瀏覽代碼

Constantinople proposals covered with network tests

Gleb Urvanov 4 年之前
父節點
當前提交
239c80cb23

+ 1 - 2
scripts/run-test-chain.sh

@@ -1,5 +1,4 @@
 #!/bin/bash
-cargo build --release -p joystream-node
 cargo run --release -p joystream-node build-spec --chain dev > chainspec.json
 sed -i 's/"setValidatorCountProposalGracePeriod":.*/"setValidatorCountProposalGracePeriod": 0,/' chainspec.json
 sed -i 's/"runtimeUpgradeProposalGracePeriod":.*/"runtimeUpgradeProposalGracePeriod": 0,/' ./chainspec.json
@@ -11,4 +10,4 @@ sed -i 's/"spendingProposalGracePeriod":.*/"spendingProposalGracePeriod": 0,/' c
 sed -i 's/"evictStorageProviderProposalGracePeriod":.*/"evictStorageProviderProposalGracePeriod": 0,/' chainspec.json
 sed -i 's/"setStorageRoleParametersProposalGracePeriod":.*/"setStorageRoleParametersProposalGracePeriod": 0/' chainspec.json
 yes | cargo run --release -p joystream-node -- purge-chain --dev
-cargo run --release -p joystream-node -- --dev
+cargo run --release -p joystream-node -- --chain=chainspec.json --alice --validator

+ 2 - 2
tests/network-tests/.env

@@ -7,9 +7,9 @@ MEMBERSHIP_CREATION_N = 2
 # ID of the membership paid terms used in membership creation test.
 MEMBERSHIP_PAID_TERMS = 0
 # Council stake amount for first K accounts in council election test.
-COUNCIL_STAKE_GREATER_AMOUNT = 1500
+COUNCIL_STAKE_GREATER_AMOUNT = 3000
 # Council stake amount for first the rest participants in council election test.
-COUNCIL_STAKE_LESSER_AMOUNT = 1000
+COUNCIL_STAKE_LESSER_AMOUNT = 2000
 # Number of members with greater stake in council election test.
 COUNCIL_ELECTION_K = 2
 # Balance to spend using spending proposal

+ 138 - 0
tests/network-tests/src/tests/constantinople/proposals/electionParametersProposalTest.ts

@@ -0,0 +1,138 @@
+import { initConfig } from '../../../utils/config';
+import { Keyring, WsProvider } from '@polkadot/api';
+import { KeyringPair } from '@polkadot/keyring/types';
+import { membershipTest } from '../membershipCreationTest';
+import { councilTest } from '../electingCouncilTest';
+import { registerJoystreamTypes } from '@joystream/types';
+import { ApiWrapper } from '../../../utils/apiWrapper';
+import { v4 as uuid } from 'uuid';
+import BN = require('bn.js');
+import { assert } from 'chai';
+
+describe('Election parameters proposal network tests', () => {
+  initConfig();
+  const keyring = new Keyring({ type: 'sr25519' });
+  const nodeUrl: string = process.env.NODE_URL!;
+  const sudoUri: string = process.env.SUDO_ACCOUNT_URI!;
+  const defaultTimeout: number = 180000;
+
+  const m1KeyPairs: KeyringPair[] = new Array();
+  const m2KeyPairs: KeyringPair[] = new Array();
+
+  let apiWrapper: ApiWrapper;
+  let sudo: KeyringPair;
+
+  before(async function () {
+    this.timeout(defaultTimeout);
+    registerJoystreamTypes();
+    const provider = new WsProvider(nodeUrl);
+    apiWrapper = await ApiWrapper.create(provider);
+  });
+
+  membershipTest(m1KeyPairs);
+  membershipTest(m2KeyPairs);
+  councilTest(m1KeyPairs, m2KeyPairs);
+
+  it('Election parameters proposal test', async () => {
+    // Setup
+    sudo = keyring.addFromUri(sudoUri);
+    const proposalTitle: string = 'Testing proposal ' + uuid().substring(0, 8);
+    const description: string = 'Testing validator count proposal ' + uuid().substring(0, 8);
+    const runtimeVoteFee: BN = apiWrapper.estimateVoteForProposalFee();
+    await apiWrapper.transferBalanceToAccounts(sudo, m2KeyPairs, runtimeVoteFee);
+    const announcingPeriod: BN = await apiWrapper.getAnnouncingPeriod();
+    const votingPeriod: BN = await apiWrapper.getVotingPeriod();
+    const revealingPeriod: BN = await apiWrapper.getRevealingPeriod();
+    const councilSize: BN = await apiWrapper.getCouncilSize();
+    const candidacyLimit: BN = await apiWrapper.getCandidacyLimit();
+    const newTermDuration: BN = await apiWrapper.getNewTermDuration();
+    const minCouncilStake: BN = await apiWrapper.getMinCouncilStake();
+    const minVotingStake: BN = await apiWrapper.getMinVotingStake();
+
+    // Proposal stake calculation
+    const proposalStake: BN = new BN(200000);
+    const proposalFee: BN = apiWrapper.estimateProposeElectionParametersFee(
+      description,
+      description,
+      proposalStake,
+      announcingPeriod,
+      votingPeriod,
+      revealingPeriod,
+      councilSize,
+      candidacyLimit,
+      newTermDuration,
+      minCouncilStake,
+      minVotingStake
+    );
+    await apiWrapper.transferBalance(sudo, m1KeyPairs[0].address, proposalFee.add(proposalStake));
+
+    // Proposal creation
+    const proposalPromise = apiWrapper.expectProposalCreated();
+    await apiWrapper.proposeElectionParameters(
+      m1KeyPairs[0],
+      proposalTitle,
+      description,
+      proposalStake,
+      announcingPeriod,
+      votingPeriod,
+      revealingPeriod,
+      councilSize.addn(1),
+      candidacyLimit.addn(1),
+      newTermDuration.addn(1),
+      minCouncilStake.addn(1),
+      minVotingStake.addn(1)
+    );
+    const proposalNumber = await proposalPromise;
+
+    // Approving the proposal
+    const proposalExecutionPromise = apiWrapper.expectProposalFinalized();
+    await apiWrapper.batchApproveProposal(m2KeyPairs, proposalNumber);
+    await proposalExecutionPromise;
+
+    // Assertions
+    const newAnnouncingPeriod: BN = await apiWrapper.getAnnouncingPeriod();
+    const newVotingPeriod: BN = await apiWrapper.getVotingPeriod();
+    const newRevealingPeriod: BN = await apiWrapper.getRevealingPeriod();
+    const newCouncilSize: BN = await apiWrapper.getCouncilSize();
+    const newCandidacyLimit: BN = await apiWrapper.getCandidacyLimit();
+    const newNewTermDuration: BN = await apiWrapper.getNewTermDuration();
+    const newMinCouncilStake: BN = await apiWrapper.getMinCouncilStake();
+    const newMinVotingStake: BN = await apiWrapper.getMinVotingStake();
+    assert(
+      announcingPeriod.eq(newAnnouncingPeriod),
+      `Announcing period has unexpected value ${newAnnouncingPeriod}, expected ${announcingPeriod}`
+    );
+    assert(
+      votingPeriod.eq(newVotingPeriod),
+      `Voting period has unexpected value ${newVotingPeriod}, expected ${votingPeriod}`
+    );
+    assert(
+      revealingPeriod.eq(newRevealingPeriod),
+      `Revealing has unexpected value ${newRevealingPeriod}, expected ${revealingPeriod}`
+    );
+    assert(
+      councilSize.addn(1).eq(newCouncilSize),
+      `Council size has unexpected value ${newCouncilSize}, expected ${councilSize.addn(1)}`
+    );
+    assert(
+      candidacyLimit.addn(1).eq(newCandidacyLimit),
+      `Candidacy limit has unexpected value ${newCandidacyLimit}, expected ${candidacyLimit.addn(1)}`
+    );
+    assert(
+      newTermDuration.addn(1).eq(newNewTermDuration),
+      `New term duration has unexpected value ${newNewTermDuration}, expected ${newTermDuration.addn(1)}`
+    );
+    assert(
+      minCouncilStake.addn(1).eq(newMinCouncilStake),
+      `Min council stake has unexpected value ${newMinCouncilStake}, expected ${minCouncilStake.addn(1)}`
+    );
+    assert(
+      minVotingStake.addn(1).eq(newMinVotingStake),
+      `Min voting stake has unexpected value ${newMinVotingStake}, expected ${minVotingStake.addn(1)}`
+    );
+  }).timeout(defaultTimeout);
+
+  after(() => {
+    apiWrapper.close();
+  });
+});

+ 2 - 2
tests/network-tests/src/tests/constantinople/proposals/evictStoraveProviderTest.ts

@@ -10,7 +10,7 @@ import BN = require('bn.js');
 import { assert } from 'chai';
 import { Utils } from '../../../utils/utils';
 
-describe.skip('Evict storage provider proposal network tests', () => {
+describe('Evict storage provider proposal network tests', () => {
   initConfig();
   const keyring = new Keyring({ type: 'sr25519' });
   const nodeUrl: string = process.env.NODE_URL!;
@@ -47,7 +47,7 @@ describe.skip('Evict storage provider proposal network tests', () => {
     assert(await apiWrapper.isStorageProvider(sudo.address), `Account ${sudo.address} is not storage provider`);
 
     // Proposal stake calculation
-    const proposalStake: BN = await apiWrapper.getRequiredProposalStake(1, 1000);
+    const proposalStake: BN = new BN(25000);
     const proposalFee: BN = apiWrapper.estimateProposeEvictStorageProviderFee(
       description,
       description,

+ 2 - 2
tests/network-tests/src/tests/constantinople/proposals/setLeadProposalTest.ts

@@ -9,7 +9,7 @@ import { v4 as uuid } from 'uuid';
 import BN = require('bn.js');
 import { assert } from 'chai';
 
-describe.skip('Lead proposal network tests', () => {
+describe('Lead proposal network tests', () => {
   initConfig();
   const keyring = new Keyring({ type: 'sr25519' });
   const nodeUrl: string = process.env.NODE_URL!;
@@ -42,7 +42,7 @@ describe.skip('Lead proposal network tests', () => {
     await apiWrapper.transferBalanceToAccounts(sudo, m2KeyPairs, runtimeVoteFee);
 
     // Proposal stake calculation
-    const proposalStake: BN = await apiWrapper.getRequiredProposalStake(25, 10000);
+    const proposalStake: BN = new BN(50000);
     const proposalFee: BN = apiWrapper.estimateProposeLeadFee(description, description, proposalStake, sudo.address);
     await apiWrapper.transferBalance(sudo, m1KeyPairs[0].address, proposalFee.add(proposalStake));
 

+ 2 - 2
tests/network-tests/src/tests/constantinople/proposals/spendingProposalTest.ts

@@ -9,7 +9,7 @@ import { v4 as uuid } from 'uuid';
 import BN = require('bn.js');
 import { assert } from 'chai';
 
-describe.skip('Spending proposal network tests', () => {
+describe('Spending proposal network tests', () => {
   initConfig();
   const keyring = new Keyring({ type: 'sr25519' });
   const nodeUrl: string = process.env.NODE_URL!;
@@ -42,7 +42,7 @@ describe.skip('Spending proposal network tests', () => {
     const runtimeVoteFee: BN = apiWrapper.estimateVoteForProposalFee();
 
     // Topping the balances
-    const proposalStake: BN = await apiWrapper.getRequiredProposalStake(25, 10000);
+    const proposalStake: BN = new BN(25000);
     const runtimeProposalFee: BN = apiWrapper.estimateProposeSpendingFee(
       description,
       description,

+ 2 - 0
tests/network-tests/src/tests/constantinople/proposals/storageRoleParametersProposalTest.ts

@@ -86,6 +86,8 @@ describe('Storage role parameters proposal network tests', () => {
     const proposalExecutionPromise = apiWrapper.expectProposalFinalized();
     await apiWrapper.batchApproveProposal(m2KeyPairs, proposalNumber);
     await proposalExecutionPromise;
+
+    // Assertions
     const newRoleParameters: RoleParameters = await apiWrapper.getStorageRoleParameters();
     assert(
       roleParameters.min_stake.toBn().addn(1).eq(newRoleParameters.min_stake.toBn()),

+ 2 - 2
tests/network-tests/src/tests/constantinople/proposals/textProposalTest.ts

@@ -8,7 +8,7 @@ import { ApiWrapper } from '../../../utils/apiWrapper';
 import { v4 as uuid } from 'uuid';
 import BN = require('bn.js');
 
-describe.skip('Text proposal network tests', () => {
+describe('Text proposal network tests', () => {
   initConfig();
   const keyring = new Keyring({ type: 'sr25519' });
   const nodeUrl: string = process.env.NODE_URL!;
@@ -42,7 +42,7 @@ describe.skip('Text proposal network tests', () => {
     await apiWrapper.transferBalanceToAccounts(sudo, m2KeyPairs, runtimeVoteFee);
 
     // Proposal stake calculation
-    const proposalStake: BN = await apiWrapper.getRequiredProposalStake(25, 10000);
+    const proposalStake: BN = new BN(25000);
     const runtimeProposalFee: BN = apiWrapper.estimateProposeTextFee(
       proposalStake,
       description,

+ 2 - 2
tests/network-tests/src/tests/constantinople/proposals/updateRuntimeTest.ts

@@ -9,7 +9,7 @@ import { ApiWrapper } from '../../../utils/apiWrapper';
 import { v4 as uuid } from 'uuid';
 import BN = require('bn.js');
 
-describe.skip('Runtime upgrade networt tests', () => {
+describe('Runtime upgrade networt tests', () => {
   initConfig();
   const keyring = new Keyring({ type: 'sr25519' });
   const nodeUrl: string = process.env.NODE_URL!;
@@ -41,7 +41,7 @@ describe.skip('Runtime upgrade networt tests', () => {
     const runtimeVoteFee: BN = apiWrapper.estimateVoteForProposalFee();
 
     // Topping the balances
-    const proposalStake: BN = await apiWrapper.getRequiredProposalStake(1, 100);
+    const proposalStake: BN = new BN(1000000);
     const runtimeProposalFee: BN = apiWrapper.estimateProposeRuntimeUpgradeFee(
       proposalStake,
       description,

+ 2 - 2
tests/network-tests/src/tests/constantinople/proposals/validatorCountProposal.ts

@@ -9,7 +9,7 @@ import { v4 as uuid } from 'uuid';
 import BN = require('bn.js');
 import { assert } from 'chai';
 
-describe.skip('Validator count proposal network tests', () => {
+describe('Validator count proposal network tests', () => {
   initConfig();
   const keyring = new Keyring({ type: 'sr25519' });
   const nodeUrl: string = process.env.NODE_URL!;
@@ -43,7 +43,7 @@ describe.skip('Validator count proposal network tests', () => {
     await apiWrapper.transferBalanceToAccounts(sudo, m2KeyPairs, runtimeVoteFee);
 
     // Proposal stake calculation
-    const proposalStake: BN = await apiWrapper.getRequiredProposalStake(25, 10000);
+    const proposalStake: BN = new BN(100000);
     const proposalFee: BN = apiWrapper.estimateProposeValidatorCountFee(description, description, proposalStake);
     await apiWrapper.transferBalance(sudo, m1KeyPairs[0].address, proposalFee.add(proposalStake));
     const validatorCount: BN = await apiWrapper.getValidatorCount();

+ 2 - 2
tests/network-tests/src/tests/constantinople/proposals/workingGroupMintCapacityProposalTest.ts

@@ -9,7 +9,7 @@ import { v4 as uuid } from 'uuid';
 import BN = require('bn.js');
 import { assert } from 'chai';
 
-describe.skip('Working group mint capacity proposal network tests', () => {
+describe('Working group mint capacity proposal network tests', () => {
   initConfig();
   const keyring = new Keyring({ type: 'sr25519' });
   const nodeUrl: string = process.env.NODE_URL!;
@@ -43,7 +43,7 @@ describe.skip('Working group mint capacity proposal network tests', () => {
     const initialMintingCapacity: BN = await apiWrapper.getWorkingGroupMintCapacity();
 
     // Topping the balances
-    const proposalStake: BN = await apiWrapper.getRequiredProposalStake(25, 10000);
+    const proposalStake: BN = new BN(50000);
     const runtimeProposalFee: BN = apiWrapper.estimateProposeWorkingGroupMintCapacityFee(
       description,
       description,

+ 133 - 42
tests/network-tests/src/utils/apiWrapper.ts

@@ -7,7 +7,7 @@ import { Mint, MintId } from '@joystream/types/lib/mint';
 import { Lead, LeadId } from '@joystream/types/lib/content-working-group';
 import { RoleParameters } from '@joystream/types/lib/roles';
 import { Seat } from '@joystream/types';
-import { Balance, EventRecord, AccountId } from '@polkadot/types/interfaces';
+import { Balance, EventRecord, AccountId, BlockNumber, BalanceOf } from '@polkadot/types/interfaces';
 import BN = require('bn.js');
 import { SubmittableExtrinsic } from '@polkadot/api/types';
 import { Sender } from './sender';
@@ -64,11 +64,12 @@ export class ApiWrapper {
     return this.getPaidMembershipTerms(paidTermsId).then(terms => terms.unwrap().fee.toBn());
   }
 
-  public async transferBalanceToAccounts(from: KeyringPair, to: KeyringPair[], amount: BN): Promise<void> {
-    for (let i = 0; i < to.length; i++) {
-      await this.transferBalance(from, to[i].address, amount);
-    }
-    return;
+  public async transferBalanceToAccounts(from: KeyringPair, to: KeyringPair[], amount: BN): Promise<void[]> {
+    return Promise.all(
+      to.map(async keyPair => {
+        await this.transferBalance(from, keyPair.address, amount);
+      })
+    );
   }
 
   private getBaseTxFee(): BN {
@@ -157,29 +158,56 @@ export class ApiWrapper {
     title: string,
     description: string,
     stake: BN,
-    min_stake: BN,
-    min_actors: BN,
-    max_actors: BN,
+    minStake: BN,
+    minActors: BN,
+    maxActors: BN,
     reward: BN,
-    reward_period: BN,
-    bonding_period: BN,
-    unbonding_period: BN,
-    min_service_period: BN,
-    startup_grace_period: BN,
-    entry_request_fee: BN
+    rewardPeriod: BN,
+    bondingPeriod: BN,
+    unbondingPeriod: BN,
+    minServicePeriod: BN,
+    startupGracePeriod: BN,
+    entryRequestFee: BN
   ): BN {
     return this.estimateTxFee(
       this.api.tx.proposalsCodex.createSetStorageRoleParametersProposal(stake, title, description, stake, [
-        min_stake,
-        min_actors,
-        max_actors,
+        minStake,
+        minActors,
+        maxActors,
         reward,
-        reward_period,
-        bonding_period,
-        unbonding_period,
-        min_service_period,
-        startup_grace_period,
-        entry_request_fee,
+        rewardPeriod,
+        bondingPeriod,
+        unbondingPeriod,
+        minServicePeriod,
+        startupGracePeriod,
+        entryRequestFee,
+      ])
+    );
+  }
+
+  public estimateProposeElectionParametersFee(
+    title: string,
+    description: string,
+    stake: BN,
+    announcingPeriod: BN,
+    votingPeriod: BN,
+    revealingPeriod: BN,
+    councilSize: BN,
+    candidacyLimit: BN,
+    newTermDuration: BN,
+    minCouncilStake: BN,
+    minVotingStake: BN
+  ): BN {
+    return this.estimateTxFee(
+      this.api.tx.proposalsCodex.createSetElectionParametersProposal(stake, title, description, stake, [
+        announcingPeriod,
+        votingPeriod,
+        revealingPeriod,
+        councilSize,
+        candidacyLimit,
+        newTermDuration,
+        minCouncilStake,
+        minVotingStake,
       ])
     );
   }
@@ -414,30 +442,61 @@ export class ApiWrapper {
     title: string,
     description: string,
     stake: BN,
-    min_stake: BN,
-    min_actors: BN,
-    max_actors: BN,
+    minStake: BN,
+    minActors: BN,
+    maxActors: BN,
     reward: BN,
-    reward_period: BN,
-    bonding_period: BN,
-    unbonding_period: BN,
-    min_service_period: BN,
-    startup_grace_period: BN,
-    entry_request_fee: BN
+    rewardPeriod: BN,
+    bondingPeriod: BN,
+    unbondingPeriod: BN,
+    minServicePeriod: BN,
+    startupGracePeriod: BN,
+    entryRequestFee: BN
   ): Promise<void> {
     const memberId: BN = (await this.getMemberIds(account.address))[0].toBn();
     return this.sender.signAndSend(
       this.api.tx.proposalsCodex.createSetStorageRoleParametersProposal(memberId, title, description, stake, [
-        min_stake,
-        min_actors,
-        max_actors,
+        minStake,
+        minActors,
+        maxActors,
         reward,
-        reward_period,
-        bonding_period,
-        unbonding_period,
-        min_service_period,
-        startup_grace_period,
-        entry_request_fee,
+        rewardPeriod,
+        bondingPeriod,
+        unbondingPeriod,
+        minServicePeriod,
+        startupGracePeriod,
+        entryRequestFee,
+      ]),
+      account,
+      false
+    );
+  }
+
+  public async proposeElectionParameters(
+    account: KeyringPair,
+    title: string,
+    description: string,
+    stake: BN,
+    announcingPeriod: BN,
+    votingPeriod: BN,
+    revealingPeriod: BN,
+    councilSize: BN,
+    candidacyLimit: BN,
+    newTermDuration: BN,
+    minCouncilStake: BN,
+    minVotingStake: BN
+  ): Promise<void> {
+    const memberId: BN = (await this.getMemberIds(account.address))[0].toBn();
+    return this.sender.signAndSend(
+      this.api.tx.proposalsCodex.createSetElectionParametersProposal(memberId, title, description, stake, [
+        announcingPeriod,
+        votingPeriod,
+        revealingPeriod,
+        councilSize,
+        candidacyLimit,
+        newTermDuration,
+        minCouncilStake,
+        minVotingStake,
       ]),
       account,
       false
@@ -550,4 +609,36 @@ export class ApiWrapper {
   public async getStorageRoleParameters(): Promise<RoleParameters> {
     return (await this.api.query.actors.parameters<Option<RoleParameters>>('StorageProvider')).unwrap();
   }
+
+  public async getAnnouncingPeriod(): Promise<BN> {
+    return await this.api.query.councilElection.announcingPeriod<BlockNumber>();
+  }
+
+  public async getVotingPeriod(): Promise<BN> {
+    return await this.api.query.councilElection.votingPeriod<BlockNumber>();
+  }
+
+  public async getRevealingPeriod(): Promise<BN> {
+    return await this.api.query.councilElection.revealingPeriod<BlockNumber>();
+  }
+
+  public async getCouncilSize(): Promise<BN> {
+    return await this.api.query.councilElection.councilSize<u32>();
+  }
+
+  public async getCandidacyLimit(): Promise<BN> {
+    return await this.api.query.councilElection.candidacyLimit<u32>();
+  }
+
+  public async getNewTermDuration(): Promise<BN> {
+    return await this.api.query.councilElection.newTermDuration<BlockNumber>();
+  }
+
+  public async getMinCouncilStake(): Promise<BN> {
+    return await this.api.query.councilElection.minCouncilStake<BalanceOf>();
+  }
+
+  public async getMinVotingStake(): Promise<BN> {
+    return await this.api.query.councilElection.minVotingStake<BalanceOf>();
+  }
 }