git.delta.rocks / unique-network / refs/commits / 6d1c84661df9

difftreelog

ci fix js-packages paths

Yaroslav Bolyukin2023-11-15parent: #4a84b64.patch.diff
in: master

18 files changed

modified.github/workflows/collator-selection.ymldiffbeforeafterboth
--- a/.github/workflows/collator-selection.yml
+++ b/.github/workflows/collator-selection.yml
@@ -181,7 +181,7 @@
           yarn add mochawesome
           # Wanted by both wait_for_first_block
           # export RPC_URL="${RELAY_SAPPHIRE_HTTP_URL:-${RELAY_OPAL_HTTP_URL:-${RELAY_QUARTZ_HTTP_URL:-${RELAY_UNIQUE_HTTP_URL:-}}}}"
-          ../scripts/src/generate_types/wait_for_first_block.sh
+          ../scripts/wait_for_first_block.sh
           echo "Ready to start tests"
           NOW=$(date +%s) && yarn testCollators --reporter mochawesome --reporter-options reportFilename=test-collators-${NOW}
         env:
modified.github/workflows/forkless-update-data.ymldiffbeforeafterboth
--- a/.github/workflows/forkless-update-data.yml
+++ b/.github/workflows/forkless-update-data.yml
@@ -146,19 +146,19 @@
             snippet:(import 'baedeker-library/ops/rewrites.libsonnet').rewriteNodePaths({'bin/unique':{dockerImage:'${{ steps.latest.outputs.name }}'}})
 
       - name: "Reconcile: runtime is upgraded"
-        working-directory: tests
+        working-directory: js-packages/tests
         run: |
           yarn
-          ./scripts/wait_for_first_block.sh
+          ../scripts/wait_for_first_block.sh
           echo "Executing upgrade"
-          yarn ts-node --esm src/util/authorizeEnactUpgrade.ts ${{ steps.wasms.outputs.dir }}/${{ matrix.wasm_name }}-runtime/${{ matrix.wasm_name }}_runtime.compact.compressed.wasm
+          yarn ts-node --esm util/authorizeEnactUpgrade.ts ${{ steps.wasms.outputs.dir }}/${{ matrix.wasm_name }}-runtime/${{ matrix.wasm_name }}_runtime.compact.compressed.wasm
         env:
           RPC_URL: ${{ env.RELAY_UNIQUE_HTTP_URL }}
 
       - name: Run Parallel tests after forkless upgrade
-        working-directory: tests
+        working-directory: js-packages/tests
         run: |
-          ./scripts/wait_for_first_block.sh
+          ../scripts/wait_for_first_block.sh
           echo "Ready to start tests"
           NOW=$(date +%s) && yarn testParallel --reporter mochawesome --reporter-options reportFilename=test-parallel-${NOW}
         env:
@@ -166,7 +166,7 @@
 
       - name: Run Sequential tests after forkless upgrade
         if: success() || failure()
-        working-directory: tests
+        working-directory: js-packages/tests
         run: NOW=$(date +%s) && yarn testSequential --reporter mochawesome --reporter-options reportFilename=test-sequential-${NOW}
         env:
           RPC_URL: ${{ env.RELAY_UNIQUE_HTTP_URL }}
modified.github/workflows/forkless-update-nodata.ymldiffbeforeafterboth
--- a/.github/workflows/forkless-update-nodata.yml
+++ b/.github/workflows/forkless-update-nodata.yml
@@ -161,19 +161,19 @@
             snippet:(import 'baedeker-library/ops/rewrites.libsonnet').rewriteNodePaths({'bin/unique':{dockerImage:'${{ steps.mainnet.outputs.name }}'}})
 
       - name: "Reconcile: runtime is upgraded"
-        working-directory: tests
+        working-directory: js-packages/tests
         run: |
           yarn
-          ./scripts/wait_for_first_block.sh
+          ../scripts/wait_for_first_block.sh
           echo "Executing upgrade"
-          yarn ts-node --esm src/util/authorizeEnactUpgrade.ts ${{ steps.wasms.outputs.dir }}/${{ matrix.wasm_name }}-runtime/${{ matrix.wasm_name }}_runtime.compact.compressed.wasm
+          yarn ts-node --esm util/authorizeEnactUpgrade.ts ${{ steps.wasms.outputs.dir }}/${{ matrix.wasm_name }}-runtime/${{ matrix.wasm_name }}_runtime.compact.compressed.wasm
         env:
           RPC_URL: ${{ env.RELAY_UNIQUE_HTTP_URL }}
 
       - name: Run Parallel tests after forkless upgrade
-        working-directory: tests
+        working-directory: js-packages/tests
         run: |
-          ./scripts/wait_for_first_block.sh
+          ../scripts/wait_for_first_block.sh
           echo "Ready to start tests"
           NOW=$(date +%s) && yarn testParallel --reporter mochawesome --reporter-options reportFilename=test-parallel-${NOW}
         env:
@@ -181,7 +181,7 @@
 
       - name: Run Sequential tests after forkless upgrade
         if: success() || failure()
-        working-directory: tests
+        working-directory: js-packages/tests
         run: NOW=$(date +%s) && yarn testSequential --reporter mochawesome --reporter-options reportFilename=test-sequential-${NOW}
         env:
           RPC_URL: ${{ env.RELAY_UNIQUE_HTTP_URL }}
modified.github/workflows/governance.ymldiffbeforeafterboth
--- a/.github/workflows/governance.yml
+++ b/.github/workflows/governance.yml
@@ -86,7 +86,7 @@
         run: |
           yarn install
           yarn add mochawesome
-          ../scripts/src/generate_types/wait_for_first_block.sh
+          ../scripts/wait_for_first_block.sh
           echo "Ready to start tests"
           NOW=$(date +%s) && yarn testGovernance --reporter mochawesome --reporter-options reportFilename=test-${NOW}
         env:
modified.github/workflows/make-bench.ymldiffbeforeafterboth
--- a/.github/workflows/make-bench.yml
+++ b/.github/workflows/make-bench.yml
@@ -43,16 +43,15 @@
           time make bench
 
       - name: Run node dev mode in background
-        working-directory: ./
         run: |
           ./target/release/unique-collator --dev &
 
       - name: RUN Calibrate
-        working-directory: ./tests
+        working-directory: js-packages/scripts
         run: |
-          yarn install
-          yarn ts-node --esm src/calibrate.ts
-          yarn ts-node --esm src/calibrateApply.ts
+          yarn
+          yarn ts-node --esm calibrate.ts
+          yarn ts-node --esm calibrateApply.ts
           
       - name: show git diff
         run: |
modified.github/workflows/market-test.ymldiffbeforeafterboth
--- a/.github/workflows/market-test.yml
+++ b/.github/workflows/market-test.yml
@@ -119,10 +119,10 @@
 
 # Temporary disable node readyness check. Have to dig into the script logic.
 #      - name: Wait for chain up and running
-#        working-directory: tests
+#        working-directory: js-packages/tests
 #        run: |
 #          yarn install
-#          ./scripts/wait_for_first_block.sh
+#          ../scripts/wait_for_first_block.sh
 #          echo "Ready to start tests"
 #        env:
 #          RPC_URL: http://127.0.0.1:9944/
modified.github/workflows/node-only-update.ymldiffbeforeafterboth
--- a/.github/workflows/node-only-update.yml
+++ b/.github/workflows/node-only-update.yml
@@ -170,6 +170,7 @@
         run: |
           yarn
           yarn add mochawesome
+          # TODO: Update to new script structure after mainnet will have it
           ./scripts/wait_for_first_block.sh
           echo "Ready to start tests"
           NOW=$(date +%s) && yarn testParallel --reporter mochawesome --reporter-options reportFilename=test-parallel-${NOW}
@@ -197,7 +198,7 @@
       - name: Ensure network is alive
         if: success()
         run: |
-          ./tests/scripts/wait_for_first_block.sh
+          ./js-packages/scripts/wait_for_first_block.sh
         env:
           RPC_URL: ${{ env.RELAY_UNIQUE_HTTP_URL }}
 
@@ -217,6 +218,7 @@
         run: |
           yarn install
           yarn add mochawesome
+          # TODO: Update to new script structure after mainnet will have it
           ./scripts/wait_for_first_block.sh
           echo "Ready to start tests"
           NOW=$(date +%s) && yarn testParallel --reporter mochawesome --reporter-options reportFilename=test-parallel-${NOW}
modified.github/workflows/polkadot-types.ymldiffbeforeafterboth
--- a/.github/workflows/polkadot-types.yml
+++ b/.github/workflows/polkadot-types.yml
@@ -74,13 +74,13 @@
       #   run: sudo apt install jq -y
 
       - name: Run generate_types_package script
-        working-directory: tests
+        working-directory: js-packages
         run: |
           yarn install
-          /bin/bash ./scripts/generate_types/wait_for_first_block.sh
+          ./scripts/wait_for_first_block.sh
           git config --global user.name "Unique"
           git config --global user.email github-actions@usetech.com          
-          /bin/bash ./scripts/generate_types/generate_types_package.sh --release ${{ matrix.usage }} --push
+          ./scripts/generate_types/generate_types_package.sh --release ${{ matrix.usage }} --push
         env:
           RPC_URL: http://127.0.0.1:9944/
 
modified.github/workflows/xcm.ymldiffbeforeafterboth
--- a/.github/workflows/xcm.yml
+++ b/.github/workflows/xcm.yml
@@ -327,22 +327,22 @@
           retention-days: 2
 
       - name: Yarn install
-        working-directory: tests
+        working-directory: js-packages/tests
         run: |
           yarn install
           yarn add mochawesome
 
       - name: Call HRMP initialization
-        working-directory: tests
+        working-directory: js-packages/tests
         run: |
-          yarn ts-node --esm src/util/createHrmp.ts ${{matrix.network}}
+          yarn ts-node --esm util/createHrmp.ts ${{matrix.network}}
 
       - name: Run XCM tests
         working-directory: js-packages/tests
         run: |
           # Wanted by both wait_for_first_block
           export RPC_URL="${RELAY_OPAL_HTTP_URL:-${RELAY_QUARTZ_HTTP_URL:-${RELAY_UNIQUE_HTTP_URL:-}}}"
-          ../scripts/src/generate_types/wait_for_first_block.sh
+          ../scripts/wait_for_first_block.sh
           echo "Ready to start tests"
           NOW=$(date +%s) && yarn ${{ matrix.runtest }} --reporter mochawesome --reporter-options reportFilename=test-${NOW}
 
modified.github/workflows/yarn-dev.ymldiffbeforeafterboth
--- a/.github/workflows/yarn-dev.yml
+++ b/.github/workflows/yarn-dev.yml
@@ -66,7 +66,7 @@
         run: |
           yarn install
           yarn add mochawesome
-          ../scripts/src/generate_types/wait_for_first_block.sh
+          ../scripts/wait_for_first_block.sh
           echo "Ready to start tests"
           NOW=$(date +%s) && yarn test --reporter mochawesome --reporter-options reportFilename=test-${NOW}
         env:
@@ -90,13 +90,13 @@
         working-directory: js-packages/scripts
         run: |
           yarn install
-          npx ts-node --esm ./src/benchmarks/mintFee/index.ts
+          npx ts-node --esm ./benchmarks/mintFee/index.ts
 
       - name: Run benchmark opsFee tests
         working-directory: js-packages/scripts
         run: |
           yarn install
-          npx ts-node --esm ./src/benchmarks/opsFee/index.ts
+          npx ts-node --esm ./benchmarks/opsFee/index.ts
 
       - name: Stop running containers
         if: always()                   # run this step always
modifiedMakefilediffbeforeafterboth
--- a/Makefile
+++ b/Makefile
@@ -7,25 +7,25 @@
 	@echo "  bench-unique"
 
 NATIVE_FUNGIBLE_EVM_STUBS=./pallets/balances-adapter/src/stubs
-NATIVE_FUNGIBLE_EVM_ABI=./js-packages/tests/src/eth/abi/nativeFungible.json
+NATIVE_FUNGIBLE_EVM_ABI=./js-packages/tests/eth/abi/nativeFungible.json
 
 FUNGIBLE_EVM_STUBS=./pallets/fungible/src/stubs
-FUNGIBLE_EVM_ABI=./js-packages/tests/src/eth/abi/fungible.json
+FUNGIBLE_EVM_ABI=./js-packages/tests/eth/abi/fungible.json
 
 NONFUNGIBLE_EVM_STUBS=./pallets/nonfungible/src/stubs
-NONFUNGIBLE_EVM_ABI=./js-packages/tests/src/eth/abi/nonFungible.json
+NONFUNGIBLE_EVM_ABI=./js-packages/tests/eth/abi/nonFungible.json
 
 REFUNGIBLE_EVM_STUBS=./pallets/refungible/src/stubs
-REFUNGIBLE_EVM_ABI=./js-packages/tests/src/eth/abi/reFungible.json
-REFUNGIBLE_TOKEN_EVM_ABI=./js-packages/tests/src/eth/abi/reFungibleToken.json
+REFUNGIBLE_EVM_ABI=./js-packages/tests/eth/abi/reFungible.json
+REFUNGIBLE_TOKEN_EVM_ABI=./js-packages/tests/eth/abi/reFungibleToken.json
 
 CONTRACT_HELPERS_STUBS=./pallets/evm-contract-helpers/src/stubs/
-CONTRACT_HELPERS_ABI=./js-packages/tests/src/eth/abi/contractHelpers.json
+CONTRACT_HELPERS_ABI=./js-packages/tests/eth/abi/contractHelpers.json
 
 COLLECTION_HELPER_STUBS=./pallets/unique/src/eth/stubs/
-COLLECTION_HELPER_ABI=./js-packages/tests/src/eth/abi/collectionHelpers.json
+COLLECTION_HELPER_ABI=./js-packages/tests/eth/abi/collectionHelpers.json
 
-TESTS_API=./js-packages/tests/src/eth/api/
+TESTS_API=./js-packages/tests/eth/api/
 
 .PHONY: regenerate_solidity
 regenerate_solidity: UniqueFungible.sol UniqueNFT.sol UniqueRefungible.sol UniqueRefungibleToken.sol ContractHelpers.sol CollectionHelpers.sol
modifieddoc/separate_rpc.mddiffbeforeafterboth
--- a/doc/separate_rpc.md
+++ b/doc/separate_rpc.md
@@ -77,7 +77,7 @@
     * runtime/quartz/Cargo.toml
     * runtime/unique/Cargo.toml
 
-7. Create tests/src/interfaces/ModuleName/definitions.ts and describe the necessary methods in it.
+7. Create js-packages/types/ModuleName/definitions.ts and describe the necessary methods in it.
     ```ts
     type RpcParam = {
         name: string;
@@ -105,19 +105,19 @@
         };
     ```
 
-8. Describe definitions from paragraph 7 in tests/src/interfaces/definitions.ts.
+8. Describe definitions from paragraph 7 in js-packages/types/definitions.ts.
     ```ts
     export {default as ModuleName} from './module/definitions';
     ```
 
-9. tests/src/substrate/substrate-api.ts
+9. js-packages/tests/substrate/substrate-api.ts
     * Set the RPC interface in the `defaultApiOptions` function, add an entry in the `rpc` parameter
         ```ts
         module: defs.module.rpc,
         ```
 
-10. tests/src/util/playgrounds/unique.dev.ts
+10. js-packages/playgrounds/unique.dev.ts
     * Specify RPC interface in `connect` function, add entry in `rpc` parameter
         ```ts
         module: defs.module.rpc,
-        ```
\ No newline at end of file
+        ```
modifiedjs-packages/.dockerignorediffbeforeafterboth
--- a/js-packages/.dockerignore
+++ b/js-packages/.dockerignore
@@ -1,2 +1 @@
 node_modules/
-Dockerfile-tests
deletedjs-packages/Dockerfile-testsdiffbeforeafterboth
--- a/js-packages/Dockerfile-tests
+++ /dev/null
@@ -1,38 +0,0 @@
-# ===== Integration Tests ======
-
-
-FROM ubuntu:22.04
-LABEL maintainer="UniqueNetwork.io"
-
-RUN apt -y update; apt -y upgrade; apt -y install curl
-
-
-RUN mkdir unique_parachain
-WORKDIR /unique_parachain
-
-RUN apt-get -y update && \
-      apt-get -y upgrade && \
-      apt-get -y install curl jq && \
-      curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash && \
-      export NVM_DIR="$HOME/.nvm" && \
-      [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" && \
-      nvm install v16.2.0 && \
-      nvm alias default v16.2.0 && \
-      nvm use default
-
-ENV YARN_CACHE_FOLDER ~/.yarn
-
-COPY package.json yarn.lock ./
-
-RUN export NVM_DIR="$HOME/.nvm" && \
-    [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" && \
-    npm install --global yarn && \
-    yarn add mochawesome && \
-    yarn --pure-lockfile
-
-COPY . .
-
-CMD export NVM_DIR="$HOME/.nvm" && \
-    [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" && \
-    ./scripts/wait_for_first_block.sh && \
-    NOW=$(date +%s) && yarn test --reporter mochawesome --reporter-options reportFilename=test-${NOW}
modifiedjs-packages/scripts/benchmarks/mintFee/index.tsdiffbeforeafterboth
before · js-packages/scripts/benchmarks/mintFee/index.ts
1import {usingEthPlaygrounds} from '@unique/tests/eth/util/index.js';2import {EthUniqueHelper} from '@unique/tests/eth/util/playgrounds/unique.dev.js';3import {readFile} from 'fs/promises';4import type {ICrossAccountId} from '@unique/playgrounds/types.js';5import type {IKeyringPair} from '@polkadot/types/types';6import {UniqueNFTCollection} from '@unique/playgrounds/unique.js';7import {Contract} from 'web3-eth-contract';8import {createObjectCsvWriter} from 'csv-writer';9import {convertToTokens, createCollectionForBenchmarks, PERMISSIONS, PROPERTIES} from '../utils/common.js';10import {makeNames} from '@unique/tests/util/index.js';11import type {ContractImports} from '@unique/tests/eth/util/playgrounds/types.js';1213const {dirname} = makeNames(import.meta.url);1415export const CONTRACT_IMPORT: ContractImports[] = [16  {17    fsPath: `${dirname}/../../../../tests/eth/api/CollectionHelpers.sol`,18    solPath: 'eth/api/CollectionHelpers.sol',19  },20  {21    fsPath: `${dirname}/../../../../tests/eth/api/ContractHelpers.sol`,22    solPath: 'eth/api/ContractHelpers.sol',23  },24  {25    fsPath: `${dirname}/../../../../tests/eth/api/UniqueRefungibleToken.sol`,26    solPath: 'eth/api/UniqueRefungibleToken.sol',27  },28  {29    fsPath: `${dirname}/../../../../tests/eth/api/UniqueRefungible.sol`,30    solPath: 'eth/api/UniqueRefungible.sol',31  },32  {33    fsPath: `${dirname}/../../../../tests/eth/api/UniqueNFT.sol`,34    solPath: 'eth/api/UniqueNFT.sol',35  },36];3738interface IBenchmarkResultForProp {39	propertiesNumber: number;40	substrateFee: number;41	ethFee: number;42	ethBulkFee: number;43  ethMintCrossFee: number;44	evmProxyContractFee: number;45	evmProxyContractBulkFee: number;46}4748const main = async () => {49  const benchmarks = [50    'substrateFee',51    'ethFee',52    'ethBulkFee',53    'ethMintCrossFee',54    'evmProxyContractFee',55    'evmProxyContractBulkFee',56  ];57  const headers = [58    'propertiesNumber',59    ...benchmarks,60  ];616263  const csvWriter = createObjectCsvWriter({64    path: 'properties.csv',65    header: headers,66  });6768  await usingEthPlaygrounds(async (helper, privateKey) => {69    const CONTRACT_SOURCE = (70      await readFile(`${dirname}/proxyContract.sol`)71    ).toString();7273    const donor = await privateKey('//Alice'); // Seed from account with balance on this network74    const ethSigner = await helper.eth.createAccountWithBalance(donor);7576    const contract = await helper.ethContract.deployByCode(77      ethSigner,78      'ProxyMint',79      CONTRACT_SOURCE,80      CONTRACT_IMPORT,81    );8283    const fees = await benchMintFee(helper, privateKey, contract);84    console.log('Minting without properties');85    console.table(fees);8687    const result: IBenchmarkResultForProp[] = [];88    const csvResult: IBenchmarkResultForProp[] = [];8990    for(let i = 1; i <= 20; i++) {91      const benchResult = await benchMintWithProperties(helper, privateKey, contract, {92        propertiesNumber: i,93      }) as any;9495      csvResult.push(benchResult);9697      const minFee = Math.min(...(benchmarks.map(x => benchResult[x])));98      for(const key of benchmarks) {99        const keyPercent = Math.round((benchResult[key] / minFee) * 100);100        benchResult[key] = `${benchResult[key]} (${keyPercent}%)`;101      }102103      result.push(benchResult);104    }105106    await csvWriter.writeRecords(csvResult);107108    console.log('Minting with properties');109    console.table(result, headers);110  });111};112113main()114  .then(() => process.exit(0))115  .catch((e) => {116    console.log(e);117    process.exit(1);118  });119120121122async function benchMintFee(123  helper: EthUniqueHelper,124  privateKey: (seed: string) => Promise<IKeyringPair>,125  proxyContract: Contract,126): Promise<{127	substrateFee: number;128	ethFee: number;129	evmProxyContractFee: number;130}> {131  const donor = await privateKey('//Alice');132  const substrateReceiver = await privateKey('//Bob');133  const ethSigner = await helper.eth.createAccountWithBalance(donor);134135  const nominal = helper.balance.getOneTokenNominal();136137  await helper.eth.transferBalanceFromSubstrate(138    donor,139    proxyContract.options.address,140    100n,141  );142143  const collection = (await createCollectionForBenchmarks(144    'nft',145    helper,146    privateKey,147    ethSigner,148    proxyContract.options.address,149    PERMISSIONS,150  )) as UniqueNFTCollection;151152  const substrateFee = await helper.arrange.calculcateFee(153    {Substrate: donor.address},154    () => collection.mintToken(donor, {Substrate: substrateReceiver.address}),155  );156157  const collectionEthAddress = helper.ethAddress.fromCollectionId(collection.collectionId);158  const collectionContract = await helper.ethNativeContract.collection(159    collectionEthAddress,160    'nft',161  );162163  const receiverEthAddress = helper.address.substrateToEth(substrateReceiver.address);164165  const encodedCall = collectionContract.methods166    .mint(receiverEthAddress)167    .encodeABI();168169  const ethFee = await helper.arrange.calculcateFee(170    {Substrate: donor.address},171    async () => {172      await helper.eth.sendEVM(173        donor,174        collectionContract.options.address,175        encodedCall,176        '0',177      );178    },179  );180181  const evmProxyContractFee = await helper.arrange.calculcateFee(182    {Ethereum: ethSigner},183    async () => {184      await proxyContract.methods185        .mintToSubstrate(186          helper.ethAddress.fromCollectionId(collection.collectionId),187          substrateReceiver.addressRaw,188        )189        .send({from: ethSigner});190    },191  );192193  return {194    substrateFee: convertToTokens(substrateFee, nominal),195    ethFee: convertToTokens(ethFee, nominal),196    evmProxyContractFee: convertToTokens(evmProxyContractFee, nominal),197  };198}199200async function benchMintWithProperties(201  helper: EthUniqueHelper,202  privateKey: (seed: string) => Promise<IKeyringPair>,203  proxyContract: Contract,204  setup: { propertiesNumber: number },205): Promise<IBenchmarkResultForProp> {206  const donor = await privateKey('//Alice'); // Seed from account with balance on this network207  const ethSigner = await helper.eth.createAccountWithBalance(donor);208209  const susbstrateReceiver = await privateKey('//Bob');210  const receiverEthAddress = helper.address.substrateToEth(susbstrateReceiver.address);211212  const nominal = helper.balance.getOneTokenNominal();213214  const substrateFee = await calculateFeeNftMintWithProperties(215    helper,216    privateKey,217    {Substrate: donor.address},218    ethSigner,219    proxyContract.options.address,220    async (collection) => {221      await collection.mintToken(222        donor,223        {Substrate: susbstrateReceiver.address},224        PROPERTIES.slice(0, setup.propertiesNumber).map((p) => ({key: p.key, value: Buffer.from(p.value).toString()})),225      );226    },227  );228229  const ethFee = await calculateFeeNftMintWithProperties(230    helper,231    privateKey,232    {Substrate: donor.address},233    ethSigner,234    proxyContract.options.address,235    async (collection) => {236      const evmContract = await helper.ethNativeContract.collection(237        helper.ethAddress.fromCollectionId(collection.collectionId),238        'nft',239        undefined,240        true,241      );242243      const subTokenId = await evmContract.methods.nextTokenId().call();244245      let encodedCall = evmContract.methods246        .mint(receiverEthAddress)247        .encodeABI();248249      await helper.eth.sendEVM(250        donor,251        evmContract.options.address,252        encodedCall,253        '0',254      );255256      for(const val of PROPERTIES.slice(0, setup.propertiesNumber)) {257        encodedCall = await evmContract.methods258          .setProperty(subTokenId, val.key, Buffer.from(val.value))259          .encodeABI();260261        await helper.eth.sendEVM(262          donor,263          evmContract.options.address,264          encodedCall,265          '0',266        );267      }268    },269  );270271  const ethBulkFee = await calculateFeeNftMintWithProperties(272    helper,273    privateKey,274    {Substrate: donor.address},275    ethSigner,276    proxyContract.options.address,277    async (collection) => {278      const evmContract = await helper.ethNativeContract.collection(279        helper.ethAddress.fromCollectionId(collection.collectionId),280        'nft',281      );282283      const subTokenId = await evmContract.methods.nextTokenId().call();284285      let encodedCall = evmContract.methods286        .mint(receiverEthAddress)287        .encodeABI();288289      await helper.eth.sendEVM(290        donor,291        evmContract.options.address,292        encodedCall,293        '0',294      );295296      encodedCall = await evmContract.methods297        .setProperties(298          subTokenId,299          PROPERTIES.slice(0, setup.propertiesNumber),300        )301        .encodeABI();302303      await helper.eth.sendEVM(304        donor,305        evmContract.options.address,306        encodedCall,307        '0',308      );309    },310  );311312  const ethMintCrossFee = await calculateFeeNftMintWithProperties(313    helper,314    privateKey,315    {Ethereum: ethSigner},316    ethSigner,317    proxyContract.options.address,318    async (collection) => {319      const evmContract = await helper.ethNativeContract.collection(320        helper.ethAddress.fromCollectionId(collection.collectionId),321        'nft',322      );323324      await evmContract.methods.mintCross(325        helper.ethCrossAccount.fromAddress(receiverEthAddress),326        PROPERTIES.slice(0, setup.propertiesNumber),327      )328        .send({from: ethSigner});329    },330  );331332  const proxyContractFee = await calculateFeeNftMintWithProperties(333    helper,334    privateKey,335    {Ethereum: ethSigner},336    ethSigner,337    proxyContract.options.address,338    async (collection) => {339      await proxyContract.methods340        .mintToSubstrateWithProperty(341          helper.ethAddress.fromCollectionId(collection.collectionId),342          susbstrateReceiver.addressRaw,343          PROPERTIES.slice(0, setup.propertiesNumber),344        )345        .send({from: ethSigner});346    },347  );348349  const proxyContractBulkFee = await calculateFeeNftMintWithProperties(350    helper,351    privateKey,352    {Ethereum: ethSigner},353    ethSigner,354    proxyContract.options.address,355    async (collection) => {356      await proxyContract.methods357        .mintToSubstrateBulkProperty(358          helper.ethAddress.fromCollectionId(collection.collectionId),359          susbstrateReceiver.addressRaw,360          PROPERTIES.slice(0, setup.propertiesNumber),361        )362        .send({from: ethSigner});363    },364  );365366  return {367    propertiesNumber: setup.propertiesNumber,368    substrateFee: convertToTokens(substrateFee, nominal),369    ethFee: convertToTokens(ethFee, nominal),370    ethBulkFee: convertToTokens(ethBulkFee, nominal),371    ethMintCrossFee: convertToTokens(ethMintCrossFee, nominal),372    evmProxyContractFee: convertToTokens(proxyContractFee, nominal),373    evmProxyContractBulkFee: convertToTokens(proxyContractBulkFee, nominal),374  };375}376377async function calculateFeeNftMintWithProperties(378  helper: EthUniqueHelper,379  privateKey: (seed: string) => Promise<IKeyringPair>,380  payer: ICrossAccountId,381  ethSigner: string,382  proxyContractAddress: string,383  calculatedCall: (collection: UniqueNFTCollection) => Promise<any>,384): Promise<bigint> {385  const collection = (await createCollectionForBenchmarks(386    'nft',387    helper,388    privateKey,389    ethSigner,390    proxyContractAddress,391    PERMISSIONS,392  )) as UniqueNFTCollection;393  return helper.arrange.calculcateFee(payer, async () => {394    await calculatedCall(collection);395  });396}397398399
after · js-packages/scripts/benchmarks/mintFee/index.ts
1import {usingEthPlaygrounds} from '@unique/tests/eth/util/index.js';2import {EthUniqueHelper} from '@unique/tests/eth/util/playgrounds/unique.dev.js';3import {readFile} from 'fs/promises';4import type {ICrossAccountId} from '@unique/playgrounds/types.js';5import type {IKeyringPair} from '@polkadot/types/types';6import {UniqueNFTCollection} from '@unique/playgrounds/unique.js';7import {Contract} from 'web3-eth-contract';8import {createObjectCsvWriter} from 'csv-writer';9import {convertToTokens, createCollectionForBenchmarks, PERMISSIONS, PROPERTIES} from '../utils/common.js';10import {makeNames} from '@unique/tests/util/index.js';11import type {ContractImports} from '@unique/tests/eth/util/playgrounds/types.js';1213const {dirname} = makeNames(import.meta.url);1415export const CONTRACT_IMPORT: ContractImports[] = [16  {17    fsPath: `${dirname}/../../../tests/eth/api/CollectionHelpers.sol`,18    solPath: 'eth/api/CollectionHelpers.sol',19  },20  {21    fsPath: `${dirname}/../../../tests/eth/api/ContractHelpers.sol`,22    solPath: 'eth/api/ContractHelpers.sol',23  },24  {25    fsPath: `${dirname}/../../../tests/eth/api/UniqueRefungibleToken.sol`,26    solPath: 'eth/api/UniqueRefungibleToken.sol',27  },28  {29    fsPath: `${dirname}/../../../tests/eth/api/UniqueRefungible.sol`,30    solPath: 'eth/api/UniqueRefungible.sol',31  },32  {33    fsPath: `${dirname}/../../../tests/eth/api/UniqueNFT.sol`,34    solPath: 'eth/api/UniqueNFT.sol',35  },36];3738interface IBenchmarkResultForProp {39	propertiesNumber: number;40	substrateFee: number;41	ethFee: number;42	ethBulkFee: number;43  ethMintCrossFee: number;44	evmProxyContractFee: number;45	evmProxyContractBulkFee: number;46}4748const main = async () => {49  const benchmarks = [50    'substrateFee',51    'ethFee',52    'ethBulkFee',53    'ethMintCrossFee',54    'evmProxyContractFee',55    'evmProxyContractBulkFee',56  ];57  const headers = [58    'propertiesNumber',59    ...benchmarks,60  ];616263  const csvWriter = createObjectCsvWriter({64    path: 'properties.csv',65    header: headers,66  });6768  await usingEthPlaygrounds(async (helper, privateKey) => {69    const CONTRACT_SOURCE = (70      await readFile(`${dirname}/proxyContract.sol`)71    ).toString();7273    const donor = await privateKey('//Alice'); // Seed from account with balance on this network74    const ethSigner = await helper.eth.createAccountWithBalance(donor);7576    const contract = await helper.ethContract.deployByCode(77      ethSigner,78      'ProxyMint',79      CONTRACT_SOURCE,80      CONTRACT_IMPORT,81    );8283    const fees = await benchMintFee(helper, privateKey, contract);84    console.log('Minting without properties');85    console.table(fees);8687    const result: IBenchmarkResultForProp[] = [];88    const csvResult: IBenchmarkResultForProp[] = [];8990    for(let i = 1; i <= 20; i++) {91      const benchResult = await benchMintWithProperties(helper, privateKey, contract, {92        propertiesNumber: i,93      }) as any;9495      csvResult.push(benchResult);9697      const minFee = Math.min(...(benchmarks.map(x => benchResult[x])));98      for(const key of benchmarks) {99        const keyPercent = Math.round((benchResult[key] / minFee) * 100);100        benchResult[key] = `${benchResult[key]} (${keyPercent}%)`;101      }102103      result.push(benchResult);104    }105106    await csvWriter.writeRecords(csvResult);107108    console.log('Minting with properties');109    console.table(result, headers);110  });111};112113main()114  .then(() => process.exit(0))115  .catch((e) => {116    console.log(e);117    process.exit(1);118  });119120121122async function benchMintFee(123  helper: EthUniqueHelper,124  privateKey: (seed: string) => Promise<IKeyringPair>,125  proxyContract: Contract,126): Promise<{127	substrateFee: number;128	ethFee: number;129	evmProxyContractFee: number;130}> {131  const donor = await privateKey('//Alice');132  const substrateReceiver = await privateKey('//Bob');133  const ethSigner = await helper.eth.createAccountWithBalance(donor);134135  const nominal = helper.balance.getOneTokenNominal();136137  await helper.eth.transferBalanceFromSubstrate(138    donor,139    proxyContract.options.address,140    100n,141  );142143  const collection = (await createCollectionForBenchmarks(144    'nft',145    helper,146    privateKey,147    ethSigner,148    proxyContract.options.address,149    PERMISSIONS,150  )) as UniqueNFTCollection;151152  const substrateFee = await helper.arrange.calculcateFee(153    {Substrate: donor.address},154    () => collection.mintToken(donor, {Substrate: substrateReceiver.address}),155  );156157  const collectionEthAddress = helper.ethAddress.fromCollectionId(collection.collectionId);158  const collectionContract = await helper.ethNativeContract.collection(159    collectionEthAddress,160    'nft',161  );162163  const receiverEthAddress = helper.address.substrateToEth(substrateReceiver.address);164165  const encodedCall = collectionContract.methods166    .mint(receiverEthAddress)167    .encodeABI();168169  const ethFee = await helper.arrange.calculcateFee(170    {Substrate: donor.address},171    async () => {172      await helper.eth.sendEVM(173        donor,174        collectionContract.options.address,175        encodedCall,176        '0',177      );178    },179  );180181  const evmProxyContractFee = await helper.arrange.calculcateFee(182    {Ethereum: ethSigner},183    async () => {184      await proxyContract.methods185        .mintToSubstrate(186          helper.ethAddress.fromCollectionId(collection.collectionId),187          substrateReceiver.addressRaw,188        )189        .send({from: ethSigner});190    },191  );192193  return {194    substrateFee: convertToTokens(substrateFee, nominal),195    ethFee: convertToTokens(ethFee, nominal),196    evmProxyContractFee: convertToTokens(evmProxyContractFee, nominal),197  };198}199200async function benchMintWithProperties(201  helper: EthUniqueHelper,202  privateKey: (seed: string) => Promise<IKeyringPair>,203  proxyContract: Contract,204  setup: { propertiesNumber: number },205): Promise<IBenchmarkResultForProp> {206  const donor = await privateKey('//Alice'); // Seed from account with balance on this network207  const ethSigner = await helper.eth.createAccountWithBalance(donor);208209  const susbstrateReceiver = await privateKey('//Bob');210  const receiverEthAddress = helper.address.substrateToEth(susbstrateReceiver.address);211212  const nominal = helper.balance.getOneTokenNominal();213214  const substrateFee = await calculateFeeNftMintWithProperties(215    helper,216    privateKey,217    {Substrate: donor.address},218    ethSigner,219    proxyContract.options.address,220    async (collection) => {221      await collection.mintToken(222        donor,223        {Substrate: susbstrateReceiver.address},224        PROPERTIES.slice(0, setup.propertiesNumber).map((p) => ({key: p.key, value: Buffer.from(p.value).toString()})),225      );226    },227  );228229  const ethFee = await calculateFeeNftMintWithProperties(230    helper,231    privateKey,232    {Substrate: donor.address},233    ethSigner,234    proxyContract.options.address,235    async (collection) => {236      const evmContract = await helper.ethNativeContract.collection(237        helper.ethAddress.fromCollectionId(collection.collectionId),238        'nft',239        undefined,240        true,241      );242243      const subTokenId = await evmContract.methods.nextTokenId().call();244245      let encodedCall = evmContract.methods246        .mint(receiverEthAddress)247        .encodeABI();248249      await helper.eth.sendEVM(250        donor,251        evmContract.options.address,252        encodedCall,253        '0',254      );255256      for(const val of PROPERTIES.slice(0, setup.propertiesNumber)) {257        encodedCall = await evmContract.methods258          .setProperty(subTokenId, val.key, Buffer.from(val.value))259          .encodeABI();260261        await helper.eth.sendEVM(262          donor,263          evmContract.options.address,264          encodedCall,265          '0',266        );267      }268    },269  );270271  const ethBulkFee = await calculateFeeNftMintWithProperties(272    helper,273    privateKey,274    {Substrate: donor.address},275    ethSigner,276    proxyContract.options.address,277    async (collection) => {278      const evmContract = await helper.ethNativeContract.collection(279        helper.ethAddress.fromCollectionId(collection.collectionId),280        'nft',281      );282283      const subTokenId = await evmContract.methods.nextTokenId().call();284285      let encodedCall = evmContract.methods286        .mint(receiverEthAddress)287        .encodeABI();288289      await helper.eth.sendEVM(290        donor,291        evmContract.options.address,292        encodedCall,293        '0',294      );295296      encodedCall = await evmContract.methods297        .setProperties(298          subTokenId,299          PROPERTIES.slice(0, setup.propertiesNumber),300        )301        .encodeABI();302303      await helper.eth.sendEVM(304        donor,305        evmContract.options.address,306        encodedCall,307        '0',308      );309    },310  );311312  const ethMintCrossFee = await calculateFeeNftMintWithProperties(313    helper,314    privateKey,315    {Ethereum: ethSigner},316    ethSigner,317    proxyContract.options.address,318    async (collection) => {319      const evmContract = await helper.ethNativeContract.collection(320        helper.ethAddress.fromCollectionId(collection.collectionId),321        'nft',322      );323324      await evmContract.methods.mintCross(325        helper.ethCrossAccount.fromAddress(receiverEthAddress),326        PROPERTIES.slice(0, setup.propertiesNumber),327      )328        .send({from: ethSigner});329    },330  );331332  const proxyContractFee = await calculateFeeNftMintWithProperties(333    helper,334    privateKey,335    {Ethereum: ethSigner},336    ethSigner,337    proxyContract.options.address,338    async (collection) => {339      await proxyContract.methods340        .mintToSubstrateWithProperty(341          helper.ethAddress.fromCollectionId(collection.collectionId),342          susbstrateReceiver.addressRaw,343          PROPERTIES.slice(0, setup.propertiesNumber),344        )345        .send({from: ethSigner});346    },347  );348349  const proxyContractBulkFee = await calculateFeeNftMintWithProperties(350    helper,351    privateKey,352    {Ethereum: ethSigner},353    ethSigner,354    proxyContract.options.address,355    async (collection) => {356      await proxyContract.methods357        .mintToSubstrateBulkProperty(358          helper.ethAddress.fromCollectionId(collection.collectionId),359          susbstrateReceiver.addressRaw,360          PROPERTIES.slice(0, setup.propertiesNumber),361        )362        .send({from: ethSigner});363    },364  );365366  return {367    propertiesNumber: setup.propertiesNumber,368    substrateFee: convertToTokens(substrateFee, nominal),369    ethFee: convertToTokens(ethFee, nominal),370    ethBulkFee: convertToTokens(ethBulkFee, nominal),371    ethMintCrossFee: convertToTokens(ethMintCrossFee, nominal),372    evmProxyContractFee: convertToTokens(proxyContractFee, nominal),373    evmProxyContractBulkFee: convertToTokens(proxyContractBulkFee, nominal),374  };375}376377async function calculateFeeNftMintWithProperties(378  helper: EthUniqueHelper,379  privateKey: (seed: string) => Promise<IKeyringPair>,380  payer: ICrossAccountId,381  ethSigner: string,382  proxyContractAddress: string,383  calculatedCall: (collection: UniqueNFTCollection) => Promise<any>,384): Promise<bigint> {385  const collection = (await createCollectionForBenchmarks(386    'nft',387    helper,388    privateKey,389    ethSigner,390    proxyContractAddress,391    PERMISSIONS,392  )) as UniqueNFTCollection;393  return helper.arrange.calculcateFee(payer, async () => {394    await calculatedCall(collection);395  });396}397398399
modifiedjs-packages/scripts/package.jsondiffbeforeafterboth
--- a/js-packages/scripts/package.json
+++ b/js-packages/scripts/package.json
@@ -14,10 +14,10 @@
     "tslib": "^2.6.2"
   },
   "scripts": {
-    "benchMintingFee": "ts-node src/benchmarks/mintFee/benchmark.ts",
-    "loadTransfer": "ts-node src/transfer.nload.ts",
-    "generateEnv": "ts-node --esm ./src/generateEnv.ts",
-    "propose-upgrade": "ts-node --esm ./src/proposeupgrade.ts",
-    "propose-fast-track": "ts-node --esm ./src/proposefasttrack.ts"
+    "benchMintingFee": "ts-node benchmarks/mintFee/benchmark.ts",
+    "loadTransfer": "ts-node transfer.nload.ts",
+    "generateEnv": "ts-node --esm ./generateEnv.ts",
+    "propose-upgrade": "ts-node --esm ./proposeupgrade.ts",
+    "propose-fast-track": "ts-node --esm ./proposefasttrack.ts"
   }
 }
addedjs-packages/scripts/wait_for_first_block.shdiffbeforeafterboth
--- /dev/null
+++ b/js-packages/scripts/wait_for_first_block.sh
@@ -0,0 +1,43 @@
+#!/usr/bin/env bash
+
+DIR=$(dirname "$0")
+
+. "$DIR/functions.sh"
+
+last_block_id=0
+block_id=0
+function get_block {
+	block_id_hex=$(do_rpc chain_getHeader | jq -r .result.number)
+	block_id=$((block_id_hex))
+	echo Id = $block_id
+}
+
+function had_new_block {
+	last_block_id=$block_id
+	get_block
+	if (( last_block_id != 0 && block_id > last_block_id )); then
+		return 0
+	fi
+	return 1
+}
+
+function reset_check {
+	last_block_id=0
+	block_id=0
+}
+
+while ! had_new_block; do
+	echo "Waiting for next block..."
+	sleep 12
+done
+reset_check
+
+echo "Chain is running, but lets wait for another block after a minute, to avoid startup flakiness."
+sleep 60
+
+while ! had_new_block; do
+	echo "Waiting for another block..."
+	sleep 12
+done
+
+echo "Chain is running!"
modifiedjs-packages/tests/package.jsondiffbeforeafterboth
--- a/js-packages/tests/package.json
+++ b/js-packages/tests/package.json
@@ -26,6 +26,10 @@
         "_test": "yarn setup && mocha --timeout 9999999 --loader=ts-node/esm.mjs",
         "_testParallel": "yarn setup && mocha --timeout 9999999 --parallel --loader=ts-node/esm.mjs",
         "test": "yarn _test './**/*.*test.ts'",
+        "testParallel": "yarn _testParallel './**/*.test.ts'",
+        "testSequential": "yarn _test './**/*.seqtest.ts'",
+        "testGovernance": "RUN_GOV_TESTS=1 yarn _test ./**/governance/*.*test.ts",
+        "testCollators": "RUN_COLLATOR_TESTS=1 yarn _test ./**/collator-selection/**.*test.ts --timeout 49999999",
         "load": "yarn _test './**/*.load.ts'"
     }
 }