1import {IKeyringPair} from '@polkadot/types/types';2import {xxhashAsHex} from '@polkadot/util-crypto';3import {usingPlaygrounds, expect} from '../util';4import {UniqueHelper} from '../util/playgrounds/unique';56export const democracyLaunchPeriod = 35;7export const democracyVotingPeriod = 35;8export const councilMotionDuration = 35;9export const democracyEnactmentPeriod = 40;10export const democracyFastTrackVotingPeriod = 5;1112export const fellowshipRankLimit = 7;13export const fellowshipPropositionOrigin = 'FellowshipProposition';14export const fellowshipPreparePeriod = 3;15export const fellowshipConfirmPeriod = 3;16export const fellowshipMinEnactPeriod = 1;1718export const defaultEnactmentMoment = {After: 0};1920export const democracyTrackId = 10;21export const democracyTrackMinRank = 3;22const twox128 = (data: any) => xxhashAsHex(data, 128);23export interface ICounselors {24 alex: IKeyringPair;25 ildar: IKeyringPair;26 charu: IKeyringPair;27 filip: IKeyringPair;28 irina: IKeyringPair;29}30export interface ITechComms {31 greg: IKeyringPair;32 andy: IKeyringPair;33 constantine: IKeyringPair;34}3536export async function initCouncil(donor: IKeyringPair, superuser: IKeyringPair) {37 let counselors: IKeyringPair[] = [];3839 await usingPlaygrounds(async (helper) => {40 const [alex, ildar, charu, filip, irina] = await helper.arrange.createAccounts([10_000n, 10_000n, 10_000n, 10_000n, 10_000n], donor);41 const sudo = helper.getSudo();42 {43 const members = (await helper.callRpc('api.query.councilMembership.members')).toJSON() as [];44 if(members.length != 0) {45 await clearCouncil(superuser);46 }47 }48 const expectedMembers = [alex, ildar, charu, filip, irina];49 for(const member of expectedMembers) {50 await sudo.executeExtrinsic(superuser, 'api.tx.councilMembership.addMember', [member.address]);51 }52 await sudo.executeExtrinsic(superuser, 'api.tx.councilMembership.setPrime', [alex.address]);53 {54 const members = (await helper.callRpc('api.query.councilMembership.members')).toJSON();55 expect(members).to.containSubset(expectedMembers.map((x: IKeyringPair) => x.address));56 expect(members.length).to.be.equal(expectedMembers.length);57 }5859 counselors = [alex, ildar, charu, filip, irina];60 });61 return {62 alex: counselors[0],63 ildar: counselors[1],64 charu: counselors[2],65 filip: counselors[3],66 irina: counselors[4],67 };68}6970export async function clearCouncil(superuser: IKeyringPair) {71 await usingPlaygrounds(async (helper) => {72 let members = (await helper.callRpc('api.query.councilMembership.members')).toJSON();73 if(members.length) {74 const sudo = helper.getSudo();75 for(const address of members) {76 await sudo.executeExtrinsic(superuser, 'api.tx.councilMembership.removeMember', [address]);77 }78 members = (await helper.callRpc('api.query.councilMembership.members')).toJSON();79 }80 expect(members).to.be.deep.equal([]);81 });82}838485export async function initTechComm(donor: IKeyringPair, superuser: IKeyringPair) {86 let techcomms: IKeyringPair[] = [];8788 await usingPlaygrounds(async (helper) => {89 const [greg, andy, constantine] = await helper.arrange.createAccounts([10_000n, 10_000n, 10_000n], donor);90 const sudo = helper.getSudo();91 {92 const members = (await helper.callRpc('api.query.technicalCommitteeMembership.members')).toJSON() as [];93 if(members.length != 0) {94 await clearTechComm(superuser);95 }96 }97 await sudo.executeExtrinsic(superuser, 'api.tx.technicalCommitteeMembership.addMember', [greg.address]);98 await sudo.executeExtrinsic(superuser, 'api.tx.technicalCommitteeMembership.addMember', [andy.address]);99 await sudo.executeExtrinsic(superuser, 'api.tx.technicalCommitteeMembership.addMember', [constantine.address]);100 await sudo.executeExtrinsic(superuser, 'api.tx.technicalCommitteeMembership.setPrime', [greg.address]);101 {102 const members = (await helper.callRpc('api.query.technicalCommitteeMembership.members')).toJSON();103 expect(members).to.containSubset([greg.address, andy.address, constantine.address]);104 expect(members.length).to.be.equal(3);105 }106107 techcomms = [greg, andy, constantine];108 });109110 return {111 greg: techcomms[0],112 andy: techcomms[1],113 constantine: techcomms[2],114 };115}116117export async function clearTechComm(superuser: IKeyringPair) {118 await usingPlaygrounds(async (helper) => {119 let members = (await helper.callRpc('api.query.technicalCommitteeMembership.members')).toJSON();120 if(members.length) {121 const sudo = helper.getSudo();122 for(const address of members) {123 await sudo.executeExtrinsic(superuser, 'api.tx.technicalCommitteeMembership.removeMember', [address]);124 }125 members = (await helper.callRpc('api.query.technicalCommitteeMembership.members')).toJSON();126 }127 expect(members).to.be.deep.equal([]);128 });129}130131export async function initFellowship(donor: IKeyringPair, sudoer: IKeyringPair) {132 const numMembersInRank = 3;133 const memberBalance = 5000n;134 const members: IKeyringPair[][] = [];135136 await usingPlaygrounds(async (helper) => {137 const currentFellows = await helper.getApi().query.fellowshipCollective.members.keys();138139 if(currentFellows.length != 0) {140 await clearFellowship(sudoer);141 }142 for(let i = 0; i < fellowshipRankLimit; i++) {143 const rankMembers = await helper.arrange.createAccounts(144 Array(numMembersInRank).fill(memberBalance),145 donor,146 );147148 for(const member of rankMembers) {149 await helper.getSudo().fellowship.collective.addMember(sudoer, member.address);150151 for(let rank = 0; rank < i; rank++) {152 await helper.getSudo().fellowship.collective.promote(sudoer, member.address);153 }154 }155156 members.push(rankMembers);157 }158 });159160 return members;161}162163export async function clearFellowship(sudoer: IKeyringPair) {164 await usingPlaygrounds(async (helper) => {165 const fellowship = (await helper.getApi().query.fellowshipCollective.members.keys())166 .map((key) => key.args[0].toString());167 for(const member of fellowship) {168 await helper.getSudo().fellowship.collective.removeMember(sudoer, member, fellowshipRankLimit);169 }170 });171}172173export async function clearFellowshipReferenda(sudoer: IKeyringPair) {174 await usingPlaygrounds(async (helper) => {175 const proposalsCount = (await helper.getApi().query.fellowshipReferenda.referendumCount());176 for(let i = 0; i < proposalsCount.toNumber(); i++) {177 await helper.getSudo().fellowship.referenda.cancel(sudoer, i);178 }179 });180}181182export async function hardResetFellowshipReferenda(sudoer: IKeyringPair) {183 await usingPlaygrounds(async (helper) => {184 const api = helper.getApi();185 const prefix = twox128('FellowshipReferenda');186 await helper.signTransaction(sudoer, api.tx.sudo.sudo(api.tx.system.killPrefix(prefix, 100)));187 });188}189190export async function hardResetDemocracy(sudoer: IKeyringPair) {191 await usingPlaygrounds(async (helper) => {192 const api = helper.getApi();193 const prefix = twox128('Democracy');194 await helper.signTransaction(sudoer, api.tx.sudo.sudo(api.tx.system.killPrefix(prefix, 100)));195 });196}197198export async function hardResetGovScheduler(sudoer: IKeyringPair) {199 await usingPlaygrounds(async (helper) => {200 const api = helper.getApi();201 const prefix = twox128('GovScheduler');202 await helper.signTransaction(sudoer, api.tx.sudo.sudo(api.tx.system.killPrefix(prefix, 500)));203 });204}205206export async function voteUnanimouslyInFellowship(helper: UniqueHelper, fellows: IKeyringPair[][], minRank: number, referendumIndex: number) {207 for(let rank = minRank; rank < fellowshipRankLimit; rank++) {208 for(const member of fellows[rank]) {209 await helper.fellowship.collective.vote(member, referendumIndex, true);210 }211 }212}213214export function dummyProposalCall(helper: UniqueHelper) {215 return helper.constructApiCall('api.tx.system.remark', ['dummy proposal' + (new Date()).getTime()]);216}217218export function dummyProposal(helper: UniqueHelper) {219 return {220 Inline: dummyProposalCall(helper).method.toHex(),221 };222}