瀏覽代碼

merge changes from council test

Gleb Urvanov 5 年之前
父節點
當前提交
fc7c7f1c1e

+ 1 - 1
package.json

@@ -6,6 +6,6 @@
 		"test": "yarn && yarn workspaces run test"
 	},
 	"workspaces": [
-		"tests"
+		"tests/network-tests"
 	]
 }

+ 0 - 0
tests/.env → tests/network-tests/.env


+ 0 - 0
tests/.prettierrc → tests/network-tests/.prettierrc


+ 0 - 0
tests/LICENSE → tests/network-tests/LICENSE


+ 1 - 1
tests/package.json → tests/network-tests/package.json

@@ -9,7 +9,7 @@
     "prettier": "prettier --write ./src"
   },
   "dependencies": {
-    "@joystream/types": "^0.6.0",
+    "@joystream/types": "^0.7.0",
     "@polkadot/api": "^0.96.1",
     "@polkadot/keyring": "^1.7.0-beta.5",
     "@types/bn.js": "^4.11.5",

+ 31 - 6
tests/src/tests/electingCouncilTest.ts → tests/network-tests/src/tests/electingCouncilTest.ts

@@ -29,9 +29,9 @@ export function councilTest(m1KeyPairs: KeyringPair[], m2KeyPairs: KeyringPair[]
   });
 
   it('Electing a council test', async () => {
+    // Setup goes here because M keypairs are generated after before() function
     sudo = keyring.addFromUri(sudoUri);
     let now = await apiWrapper.getBestBlock();
-    await apiWrapper.sudoStartAnnouncingPerion(sudo, now.addn(100));
     const applyForCouncilFee: BN = apiWrapper.estimateApplyForCouncilFee(greaterStake);
     const voteForCouncilFee: BN = apiWrapper.estimateVoteForCouncilFee(sudo.address, sudo.address, greaterStake);
     const salt: string[] = new Array();
@@ -39,14 +39,19 @@ export function councilTest(m1KeyPairs: KeyringPair[], m2KeyPairs: KeyringPair[]
       salt.push(''.concat(uuid().replace(/-/g, '')));
     });
     const revealVoteFee: BN = apiWrapper.estimateRevealVoteFee(sudo.address, salt[0]);
+
+    // Topping the balances
     await apiWrapper.transferBalanceToAccounts(sudo, m2KeyPairs, applyForCouncilFee.add(greaterStake));
     await apiWrapper.transferBalanceToAccounts(
       sudo,
       m1KeyPairs,
       voteForCouncilFee.add(revealVoteFee).add(greaterStake)
     );
+
+    // First K members stake more
+    await apiWrapper.sudoStartAnnouncingPerion(sudo, now.addn(100));
     await apiWrapper.batchApplyForCouncilElection(m2KeyPairs.slice(0, K), greaterStake);
-    m2KeyPairs.forEach(keyPair =>
+    m2KeyPairs.slice(0, K).forEach(keyPair =>
       apiWrapper.getCouncilElectionStake(keyPair.address).then(stake => {
         assert(
           stake.eq(greaterStake),
@@ -54,7 +59,19 @@ export function councilTest(m1KeyPairs: KeyringPair[], m2KeyPairs: KeyringPair[]
         );
       })
     );
+
+    // Last members stake less
     await apiWrapper.batchApplyForCouncilElection(m2KeyPairs.slice(K), lesserStake);
+    m2KeyPairs.slice(K).forEach(keyPair =>
+      apiWrapper.getCouncilElectionStake(keyPair.address).then(stake => {
+        assert(
+          stake.eq(lesserStake),
+          `${keyPair.address} not applied correctrly for council election with stake ${stake} versus expected ${lesserStake}`
+        );
+      })
+    );
+
+    // Voting
     await apiWrapper.sudoStartVotingPerion(sudo, now.addn(100));
     await apiWrapper.batchVoteForCouncilMember(
       m1KeyPairs.slice(0, K),
@@ -63,14 +80,20 @@ export function councilTest(m1KeyPairs: KeyringPair[], m2KeyPairs: KeyringPair[]
       lesserStake
     );
     await apiWrapper.batchVoteForCouncilMember(m1KeyPairs.slice(K), m2KeyPairs.slice(K), salt.slice(K), greaterStake);
+
+    // Revealing
     await apiWrapper.sudoStartRevealingPerion(sudo, now.addn(100));
     await apiWrapper.batchRevealVote(m1KeyPairs.slice(0, K), m2KeyPairs.slice(0, K), salt.slice(0, K));
     await apiWrapper.batchRevealVote(m1KeyPairs.slice(K), m2KeyPairs.slice(K), salt.slice(K));
     now = await apiWrapper.getBestBlock();
+
+    // Resolving election
+    // 3 is to ensure the revealing block is in future
     await apiWrapper.sudoStartRevealingPerion(sudo, now.addn(3));
-    // TODO get duration from chain
-    await Utils.wait(12000);
+    await Utils.wait(apiWrapper.getBlockDuration().muln(2.5).toNumber());
     const seats: Seat[] = await apiWrapper.getCouncil();
+
+    // Preparing collections to increase assertion readability
     const m2addresses: string[] = m2KeyPairs.map(keyPair => keyPair.address);
     const m1addresses: string[] = m1KeyPairs.map(keyPair => keyPair.address);
     const members: string[] = seats.map(seat => seat.member.toString());
@@ -78,8 +101,10 @@ export function councilTest(m1KeyPairs: KeyringPair[], m2KeyPairs: KeyringPair[]
       (array, seat) => array.concat(seat.backers.map(baker => baker.member.toString())),
       new Array()
     );
-    //m2addresses.forEach(address => assert(members.includes(address), `Account ${address} is not in the council`));
-    //m1addresses.forEach(address => assert(bakers.includes(address), `Account ${address} is not in the voters`));
+
+    // Assertions
+    m2addresses.forEach(address => assert(members.includes(address), `Account ${address} is not in the council`));
+    m1addresses.forEach(address => assert(bakers.includes(address), `Account ${address} is not in the voters`));
     seats.forEach(seat =>
       assert(
         Utils.getTotalStake(seat).eq(greaterStake.add(lesserStake)),

+ 0 - 0
tests/src/tests/membershipCreationTest.ts → tests/network-tests/src/tests/membershipCreationTest.ts


+ 5 - 1
tests/src/utils/apiWrapper.ts → tests/network-tests/src/utils/apiWrapper.ts

@@ -1,5 +1,5 @@
 import { ApiPromise, WsProvider } from '@polkadot/api';
-import { Option, Vec, Bytes } from '@polkadot/types';
+import { Option, Vec, Bytes, UInt } from '@polkadot/types';
 import { Codec } from '@polkadot/types/types';
 import { KeyringPair } from '@polkadot/keyring/types';
 import { UserInfo, PaidMembershipTerms } from '@joystream/types/lib/members';
@@ -229,4 +229,8 @@ export class ApiWrapper {
       })
     );
   }
+
+  public getBlockDuration(): BN {
+    return this.api.createType('Moment', this.api.consts.babe.expectedBlockTime).toBn();
+  }
 }

+ 0 - 0
tests/src/utils/config.ts → tests/network-tests/src/utils/config.ts


+ 67 - 67
tests/src/utils/sender.ts → tests/network-tests/src/utils/sender.ts

@@ -1,67 +1,67 @@
-import BN = require('bn.js');
-import { ApiPromise } from '@polkadot/api';
-import { Index } from '@polkadot/types/interfaces';
-import { SubmittableExtrinsic } from '@polkadot/api/types';
-import { KeyringPair } from '@polkadot/keyring/types';
-
-export class Sender {
-  private readonly api: ApiPromise;
-  private static nonceMap: Map<string, BN> = new Map();
-
-  constructor(api: ApiPromise) {
-    this.api = api;
-  }
-
-  private async getNonce(address: string): Promise<BN> {
-    let oncahinNonce: BN = new BN(0);
-    if (!Sender.nonceMap.get(address)) {
-      oncahinNonce = await this.api.query.system.accountNonce<Index>(address);
-    }
-    let nonce: BN | undefined = Sender.nonceMap.get(address);
-    if (!nonce) {
-      nonce = oncahinNonce;
-    }
-    const nextNonce: BN = nonce.addn(1);
-    Sender.nonceMap.set(address, nextNonce);
-    return nonce;
-  }
-
-  private clearNonce(address: string): void {
-    Sender.nonceMap.delete(address);
-  }
-
-  public async signAndSend(
-    tx: SubmittableExtrinsic<'promise'>,
-    account: KeyringPair,
-    expectFailure = false
-  ): Promise<void> {
-    return new Promise(async (resolve, reject) => {
-      const nonce: BN = await this.getNonce(account.address);
-      console.log('sending transaction from ' + account.address + ' with nonce ' + nonce);
-      const signedTx = tx.sign(account, { nonce });
-      await signedTx
-        .send(async result => {
-          if (result.status.isFinalized === true && result.events !== undefined) {
-            result.events.forEach(event => {
-              if (event.event.method === 'ExtrinsicFailed') {
-                if (expectFailure) {
-                  resolve();
-                } else {
-                  reject(new Error('Extrinsic failed unexpectedly'));
-                }
-              }
-            });
-            resolve();
-          }
-          if (result.status.isFuture) {
-            console.log('nonce ' + nonce + ' for account ' + account.address + ' is in future');
-            this.clearNonce(account.address);
-            reject(new Error('Extrinsic nonce is in future'));
-          }
-        })
-        .catch(error => {
-          reject(error);
-        });
-    });
-  }
-}
+import BN = require('bn.js');
+import { ApiPromise } from '@polkadot/api';
+import { Index } from '@polkadot/types/interfaces';
+import { SubmittableExtrinsic } from '@polkadot/api/types';
+import { KeyringPair } from '@polkadot/keyring/types';
+
+export class Sender {
+  private readonly api: ApiPromise;
+  private static nonceMap: Map<string, BN> = new Map();
+
+  constructor(api: ApiPromise) {
+    this.api = api;
+  }
+
+  private async getNonce(address: string): Promise<BN> {
+    let oncahinNonce: BN = new BN(0);
+    if (!Sender.nonceMap.get(address)) {
+      oncahinNonce = await this.api.query.system.accountNonce<Index>(address);
+    }
+    let nonce: BN | undefined = Sender.nonceMap.get(address);
+    if (!nonce) {
+      nonce = oncahinNonce;
+    }
+    const nextNonce: BN = nonce.addn(1);
+    Sender.nonceMap.set(address, nextNonce);
+    return nonce;
+  }
+
+  private clearNonce(address: string): void {
+    Sender.nonceMap.delete(address);
+  }
+
+  public async signAndSend(
+    tx: SubmittableExtrinsic<'promise'>,
+    account: KeyringPair,
+    expectFailure = false
+  ): Promise<void> {
+    return new Promise(async (resolve, reject) => {
+      const nonce: BN = await this.getNonce(account.address);
+      console.log('sending transaction from ' + account.address + ' with nonce ' + nonce);
+      const signedTx = tx.sign(account, { nonce });
+      await signedTx
+        .send(async result => {
+          if (result.status.isFinalized === true && result.events !== undefined) {
+            result.events.forEach(event => {
+              if (event.event.method === 'ExtrinsicFailed') {
+                if (expectFailure) {
+                  resolve();
+                } else {
+                  reject(new Error('Extrinsic failed unexpectedly'));
+                }
+              }
+            });
+            resolve();
+          }
+          if (result.status.isFuture) {
+            console.log('nonce ' + nonce + ' for account ' + account.address + ' is in future');
+            this.clearNonce(account.address);
+            reject(new Error('Extrinsic nonce is in future'));
+          }
+        })
+        .catch(error => {
+          reject(error);
+        });
+    });
+  }
+}

+ 0 - 0
tests/src/utils/utils.ts → tests/network-tests/src/utils/utils.ts


+ 0 - 0
tests/tsconfig.json → tests/network-tests/tsconfig.json


+ 0 - 0
tests/tslint.json → tests/network-tests/tslint.json