diff --git a/.github/workflows/create-release-draft.yml b/.github/workflows/create-release-draft.yml index 8f50ab45e7..3cee2c149d 100644 --- a/.github/workflows/create-release-draft.yml +++ b/.github/workflows/create-release-draft.yml @@ -326,6 +326,8 @@ jobs: - name: Run ts tests for ${{ matrix.chain }} timeout-minutes: 30 + env: + NODE_ENV: prod run: | make test-ts-${{ matrix.chain }} diff --git a/Makefile b/Makefile index 212db558d0..eea08e7e3b 100644 --- a/Makefile +++ b/Makefile @@ -88,15 +88,15 @@ test-cargo-all-benchmarks: .PHONY: test-ts-litentry ## Run litentry ts tests without clean-up test-ts-litentry: launch-network-litentry - @cd parachain && ./scripts/run-ts-test.sh litentry bridge evm + @cd parachain && ./scripts/run-ts-test.sh litentry .PHONY: test-ts-rococo ## Run rococo ts tests without clean-up test-ts-rococo: launch-network-rococo - @cd parachain && ./scripts/run-ts-test.sh rococo bridge evm + @cd parachain && ./scripts/run-ts-test.sh rococo .PHONY: test-ts-paseo ## Run paseo ts tests without clean-up test-ts-paseo: launch-network-paseo - @cd parachain && ./scripts/run-ts-test.sh paseo bridge evm + @cd parachain && ./scripts/run-ts-test.sh paseo # clean up .PHONY: clean-network ## Clean up the network launched by 'launch-network' diff --git a/local-setup/launch.py b/local-setup/launch.py index 686655d1f6..4d6a278c8e 100755 --- a/local-setup/launch.py +++ b/local-setup/launch.py @@ -112,6 +112,7 @@ def generate_config_local_json(parachain_dir): "parachain_ws": "ws://localhost:" + os.environ.get("CollatorWSPort", "9944"), "relaychain_ws": "ws://localhost:" + os.environ.get("AliceWSPort", "9946"), "bridge_path": "/tmp/parachain_dev/chainbridge", + "parachain_fast_runtime": "true", } config_file = "./parachain/ts-tests/config.local.json" diff --git a/parachain/scripts/clean-network.sh b/parachain/scripts/clean-network.sh index a67d4aa1c4..1fe18eecdd 100755 --- a/parachain/scripts/clean-network.sh +++ b/parachain/scripts/clean-network.sh @@ -27,6 +27,8 @@ else kill -2 $ZOMBIENET_PID fi +docker ps -q -f name=geth | xargs -r docker stop + rm -rf "$LITENTRY_PARACHAIN_DIR" echo "cleaned up" \ No newline at end of file diff --git a/parachain/scripts/run-ts-test.sh b/parachain/scripts/run-ts-test.sh index 3e904221fa..750e075c59 100755 --- a/parachain/scripts/run-ts-test.sh +++ b/parachain/scripts/run-ts-test.sh @@ -2,39 +2,23 @@ set -eo pipefail -bridge=false -evm=false - case "$1" in litentry|rococo|paseo) export PARACHAIN_TYPE=$1 ;; - *) echo "usage: ./$0 litentry [bridge] [evm]"; exit 1 ;; + *) echo "usage: ./$0 litentry|rococo|paseo"; exit 1 ;; esac -if [ "$2" = "bridge" ]; then - bridge=true -fi - -if [ "$3" = "evm" ]; then - evm=true -fi - ROOTDIR=$(git rev-parse --show-toplevel) cd "$ROOTDIR/parachain/ts-tests" LITENTRY_PARACHAIN_DIR=${LITENTRY_PARACHAIN_DIR:-"/tmp/parachain_dev"} [ -d "$LITENTRY_PARACHAIN_DIR" ] || mkdir -p "$LITENTRY_PARACHAIN_DIR" -[ -f .env ] || echo "NODE_ENV=ci" >.env +[ -f .env ] || echo "NODE_ENV=ci" > .env pnpm install pnpm run test-filter 2>&1 | tee -a "$LITENTRY_PARACHAIN_DIR/parachain_ci_test.log" -if $bridge; then - $ROOTDIR/parachain/scripts/launch-bridge.sh - pnpm run test-bridge 2>&1 | tee -a "$LITENTRY_PARACHAIN_DIR/parachain_ci_test.log" -fi +$ROOTDIR/parachain/scripts/launch-bridge.sh +pnpm run test-bridge 2>&1 | tee -a "$LITENTRY_PARACHAIN_DIR/parachain_ci_test.log" -if $evm; then - pnpm run test-evm-transfer 2>&1 | tee -a "$LITENTRY_PARACHAIN_DIR/parachain_ci_test.log" - pnpm run test-evm-contract 2>&1 | tee -a "$LITENTRY_PARACHAIN_DIR/parachain_ci_test.log" - # pnpm run test-precompile-contract 2>&1 | tee -a "$LITENTRY_PARACHAIN_DIR/parachain_ci_test.log" -fi +pnpm run test-evm-contract 2>&1 | tee -a "$LITENTRY_PARACHAIN_DIR/parachain_ci_test.log" +pnpm run test-precompile-contract 2>&1 | tee -a "$LITENTRY_PARACHAIN_DIR/parachain_ci_test.log" diff --git a/parachain/ts-tests/.env.example b/parachain/ts-tests/.env.example index 9bacc74f77..6ce004f06b 100644 --- a/parachain/ts-tests/.env.example +++ b/parachain/ts-tests/.env.example @@ -1 +1 @@ -NODE_ENV=<`local` or `staging` or `test` or `ci`> +NODE_ENV=<`local` or `prod` or `test` or `ci`> diff --git a/parachain/ts-tests/.gitignore b/parachain/ts-tests/.gitignore index 12e026367b..909f86f0c5 100644 --- a/parachain/ts-tests/.gitignore +++ b/parachain/ts-tests/.gitignore @@ -2,4 +2,7 @@ .pnp.* config.local.json -package-lock.json \ No newline at end of file +package-lock.json + +common/bob.json +common/data/ \ No newline at end of file diff --git a/parachain/ts-tests/common/utils/config.ts b/parachain/ts-tests/common/utils/config.ts index 256f9152de..6e1f6d5981 100644 --- a/parachain/ts-tests/common/utils/config.ts +++ b/parachain/ts-tests/common/utils/config.ts @@ -6,8 +6,8 @@ export function loadConfig() { case 'test': case 'ci': return require('../../config.ci.json'); - case 'staging': - return require('../../config.staging.json'); + case 'prod': + return require('../../config.prod.json'); default: throw new Error(`Invalid NODE_ENV: ${process.env.NODE_ENV}`); } diff --git a/parachain/ts-tests/config.ci.json b/parachain/ts-tests/config.ci.json index bac7c06a06..2b6b1c6d6b 100644 --- a/parachain/ts-tests/config.ci.json +++ b/parachain/ts-tests/config.ci.json @@ -7,5 +7,6 @@ "genesis_wasm_path": "/tmp/parachain_dev/genesis-wasm", "parachain_ws": "ws://127.0.0.1:9944", "relaychain_ws": "ws://127.0.0.1:9946", - "bridge_path": "/tmp/parachain_dev/chainbridge" + "bridge_path": "/tmp/parachain_dev/chainbridge", + "parachain_fast_runtime": "true" } diff --git a/parachain/ts-tests/config.example.json b/parachain/ts-tests/config.example.json deleted file mode 100644 index dd44f385a8..0000000000 --- a/parachain/ts-tests/config.example.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "eth_address": "[0x4d88dc5d528a33e4b8be579e9476715f60060582]", - "private_key": "0xe82c0c4259710bb0d6cf9f9e8d0ad73419c1278a14d375e5ca691e7618103011", - "ocw_account": "5FEYX9NES9mAJt1Xg4WebmHWywxyeGQK8G3oEBXtyfZrRePX", - "parachain_ws": "ws://localhost:9844", - "relaychain_ws": "ws://localhost:9944" -} diff --git a/parachain/ts-tests/config.prod.json b/parachain/ts-tests/config.prod.json new file mode 100644 index 0000000000..4ce2483c52 --- /dev/null +++ b/parachain/ts-tests/config.prod.json @@ -0,0 +1,12 @@ +{ + "eth_endpoint": "http://127.0.0.1:8545", + "eth_address": "[0x4d88dc5d528a33e4b8be579e9476715f60060582]", + "private_key": "0xe82c0c4259710bb0d6cf9f9e8d0ad73419c1278a14d375e5ca691e7618103011", + "ocw_account": "5FEYX9NES9mAJt1Xg4WebmHWywxyeGQK8G3oEBXtyfZrRePX", + "genesis_state_path": "/tmp/parachain_dev/genesis-state", + "genesis_wasm_path": "/tmp/parachain_dev/genesis-wasm", + "parachain_ws": "ws://127.0.0.1:9944", + "relaychain_ws": "ws://127.0.0.1:9946", + "bridge_path": "/tmp/parachain_dev/chainbridge", + "parachain_fast_runtime": "false" +} diff --git a/parachain/ts-tests/integration-tests/bridge.test.ts b/parachain/ts-tests/integration-tests/bridge.test.ts index 652fbc5a37..f7db3d4239 100644 --- a/parachain/ts-tests/integration-tests/bridge.test.ts +++ b/parachain/ts-tests/integration-tests/bridge.test.ts @@ -6,39 +6,35 @@ import { assert } from 'chai'; import { BigNumber, ethers } from 'ethers'; import { BN } from 'bn.js'; import { destResourceId } from '../common/utils/consts'; + const bn100e18 = new BN(10).pow(new BN(18)).mul(new BN(100)); -// substrate native token describeCrossChainTransfer('Test Cross-chain Transfer', ``, (context) => { - step('Transfer 100 Lit from eth to parachain', async function () { + const ferdieSubstratePubkey = '0x1cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c'; // from keyring `//Ferdie` + + step('Transfer 100 LIT from eth to parachain', async function () { let bridge = context.ethConfig.bridge.connect(context.ethConfig.wallets.bob); let erc20 = context.ethConfig.erc20.connect(context.ethConfig.wallets.bob); - // This is LIT on ETH with decimal 18 already const depositAmount = numberToHex('100,000,000,000,000,000,000'.replace(/,/g, '')); let destinationChainID = parseInt(context.parachainConfig.api.consts.chainBridge.bridgeChainId.toString()); - //FERDIE key command: polkadot key inspect //Ferdie - const destinationRecipientAddress = '0x1cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c'; - const beforeAccountData = await context.parachainConfig.api.query.system.account( context.parachainConfig.ferdie.address ); - console.log('before deposit: ', beforeAccountData.toString()); // approve await erc20.approve(context.ethConfig.erc20Handler.address, depositAmount); await sleep(6); // deposit - let data = createERCDepositData(depositAmount, 32, destinationRecipientAddress); + let data = createERCDepositData(depositAmount, 32, ferdieSubstratePubkey); await bridge.deposit(destinationChainID, destResourceId, data); await sleep(12 * 4); const afterAccountData = await context.parachainConfig.api.query.system.account( context.parachainConfig.ferdie.address ); - console.log('after deposit: ', afterAccountData.toString()); assert.equal( bn100e18.add(beforeAccountData.data.free.toBn()).toString(), @@ -46,52 +42,52 @@ describeCrossChainTransfer('Test Cross-chain Transfer', ``, (context) => { ); }); - step('Transfer 100 Lit from parachain to eth', async function () { - const receipt = context.ethConfig.wallets.charlie.address; + step('Transfer 100 LIT from parachain to eth', async function () { let erc20 = context.ethConfig.erc20.connect(context.ethConfig.wallets.bob); - const b: BigNumber = await erc20.balanceOf(receipt); + const b: BigNumber = await erc20.balanceOf(context.ethConfig.wallets.charlie.address); await signAndSend( context.parachainConfig.api.tx.bridgeTransfer.transferAssets( ethers.utils.parseUnits('100', 18).toString(), - receipt, + context.ethConfig.wallets.charlie.address, 0, destResourceId ), context.parachainConfig.bob ); await sleep(15); - // This is LIT on ETH with decimal 18 already const actual_receive = BigNumber.from('99,000,000,000,000,000,000'.replace(/,/g, '')); - assert.equal(b.add(actual_receive).toString(), (await erc20.balanceOf(receipt)).toString()); + assert.equal( + b.add(actual_receive).toString(), + (await erc20.balanceOf(context.ethConfig.wallets.charlie.address)).toString() + ); }); step('Boundary testing on ethereum: over the maximum balance', async function () { - const receipt = context.ethConfig.wallets.charlie.address; - const beforeHandleBalance: BigNumber = await context.ethConfig.erc20.balanceOf( + const beforeHandlerBalance: BigNumber = await context.ethConfig.erc20.balanceOf( context.ethConfig.erc20Handler.address ); const AssetInfo = ( await context.parachainConfig.api.query.assetsHandler.resourceToAssetInfo(destResourceId) ).toHuman() as any; - const fee = AssetInfo.fee; - const Bridge = require('../common/abi/bridge/Bridge.json'); - const inter = new ethers.utils.Interface(Bridge.abi); + const bridgeInterface = new ethers.utils.Interface(require('../common/abi/bridge/Bridge.json').abi); + await signAndSend( context.parachainConfig.api.tx.bridgeTransfer.transferAssets( - beforeHandleBalance + beforeHandlerBalance .add(BigNumber.from(100)) .add(BigNumber.from(fee.replace(/,/g, ''))) .toString(), - receipt, + context.ethConfig.wallets.charlie.address, 0, destResourceId ), context.parachainConfig.bob ); + const provider = context.ethConfig.wallets.bob.provider; const currentBlock = await provider.getBlockNumber(); await sleep(15); @@ -100,7 +96,7 @@ describeCrossChainTransfer('Test Cross-chain Transfer', ``, (context) => { for (let j = 0; j < block.transactions.length; j++) { if (block.transactions[j].to === context.ethConfig.bridge.address) { const tx = block.transactions[j]; - const decodedInput = inter.parseTransaction({ data: tx.data, value: tx.value }); + const decodedInput = bridgeInterface.parseTransaction({ data: tx.data, value: tx.value }); // The last vote proposal of threshold should failed if (decodedInput.name === 'voteProposal') { @@ -110,39 +106,40 @@ describeCrossChainTransfer('Test Cross-chain Transfer', ``, (context) => { } } } - const afterHandleBalance = await context.ethConfig.erc20.balanceOf(context.ethConfig.erc20Handler.address); + const afterHandlerBalance = await context.ethConfig.erc20.balanceOf(context.ethConfig.erc20Handler.address); assert.equal( - afterHandleBalance.toString(), - beforeHandleBalance.toString(), - 'afterHandleBalance is not equal to beforeHandleBalance' + afterHandlerBalance.toString(), + beforeHandlerBalance.toString(), + 'afterHandlerBalance is not equal to beforeHandlerBalance' ); }); step('Boundary testing on ethereum: equal to the maximum balance', async function () { - const receipt = context.ethConfig.wallets.charlie.address; const beforeHandlerBalance: BigNumber = await context.ethConfig.erc20.balanceOf( context.ethConfig.erc20Handler.address ); - const beforeReceiptBalance: BigNumber = await context.ethConfig.erc20.balanceOf(receipt); + const beforeReceiptBalance: BigNumber = await context.ethConfig.erc20.balanceOf( + context.ethConfig.wallets.charlie.address + ); const erc20 = context.ethConfig.erc20.connect(context.ethConfig.wallets.bob); const AssetInfo = ( await context.parachainConfig.api.query.assetsHandler.resourceToAssetInfo(destResourceId) ).toHuman() as any; - const fee = AssetInfo.fee; + await signAndSend( context.parachainConfig.api.tx.bridgeTransfer.transferAssets( beforeHandlerBalance.add(BigNumber.from(fee.replace(/,/g, ''))).toString(), - receipt, + context.ethConfig.wallets.charlie.address, 0, destResourceId ), context.parachainConfig.bob ); - await sleep(30); - const afterReceiptBalance: BigNumber = await erc20.balanceOf(receipt); + await sleep(15); + const afterReceiptBalance: BigNumber = await erc20.balanceOf(context.ethConfig.wallets.charlie.address); assert.equal( (await erc20.balanceOf(context.ethConfig.erc20Handler.address)).toString(), '0', @@ -158,10 +155,7 @@ describeCrossChainTransfer('Test Cross-chain Transfer', ``, (context) => { step('Boundary testing on parachain', async function () { let bridge = context.ethConfig.bridge.connect(context.ethConfig.wallets.bob); - // get context.ethConfig.wallets.bob balance - const balance = await context.ethConfig.erc20.balanceOf(context.ethConfig.wallets.bob.address); let erc20 = context.ethConfig.erc20.connect(context.ethConfig.wallets.bob); - const total_issuance = (await context.parachainConfig.api.query.balances.totalIssuance()).toBn(); const maximum_issuance = new BN( (await context.parachainConfig.api.query.assetsHandler.maximumIssuance()).toString() ); @@ -172,10 +166,9 @@ describeCrossChainTransfer('Test Cross-chain Transfer', ``, (context) => { const depositAmount = numberToHex('100,000,000,000,000,000,000'.replace(/,/g, '')); let destinationChainID = parseInt(context.parachainConfig.api.consts.chainBridge.bridgeChainId.toString()); - const destinationRecipientAddress = '0x1cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c'; await erc20.approve(context.ethConfig.erc20Handler.address, depositAmount); await sleep(2); - let data = createERCDepositData(depositAmount, 32, destinationRecipientAddress); + let data = createERCDepositData(depositAmount, 32, ferdieSubstratePubkey); await bridge.deposit(destinationChainID, destResourceId, data); let expectResult = false; @@ -204,7 +197,7 @@ describeCrossChainTransfer('Test Cross-chain Transfer', ``, (context) => { if (dispatchError.isModule) { // for module errors, we have the section indexed, lookup // (For specific known errors, we can also do a check against the - // api.errors...is(dispatchError.asModule) guard) + // context.parachainConfig.api.errors...is(dispatchError.asModule) guard) const decoded = context.parachainConfig.api.registry.findMetaError( dispatchError.asModule ); @@ -224,6 +217,5 @@ describeCrossChainTransfer('Test Cross-chain Transfer', ``, (context) => { assert.exists(''); } }); - await sleep(39); }); }); diff --git a/parachain/ts-tests/integration-tests/evm-contract.test.ts b/parachain/ts-tests/integration-tests/evm-contract.test.ts index bd565531b0..160e22d704 100644 --- a/parachain/ts-tests/integration-tests/evm-contract.test.ts +++ b/parachain/ts-tests/integration-tests/evm-contract.test.ts @@ -1,25 +1,27 @@ import { assert, expect } from 'chai'; import { step } from 'mocha-steps'; - -import { signAndSend, describeLitentry, loadConfig, sleep, sudoWrapperTC } from '../common/utils'; +import { signAndSend, describeLitentry, loadConfig, sudoWrapperTC } from '../common/utils'; +import { compiled } from '../common/utils/compile'; import { evmToAddress } from '@polkadot/util-crypto'; +import { hexToU8a, u8aToHex } from '@polkadot/util'; import { Web3 } from 'web3'; const BN = require('bn.js'); -import { compiled } from '../common/utils/compile'; +import { ethers } from 'ethers'; describeLitentry('Test EVM Module Contract', ``, (context) => { - console.log(`Test EVM Module Contract`); const config = loadConfig(); + const evmAccountRaw = { + privateKey: '0x01ab6e801c06e59ca97a14fc0a1978b27fa366fc87450e0b65459dd3515b7391', + address: '0xaaafB3972B05630fCceE866eC69CdADd9baC2771', + mappedAddress: evmToAddress('0xaaafB3972B05630fCceE866eC69CdADd9baC2771', 31), + }; + + step('Set ExtrinsicFilter mode to Test', async function () { + let extrinsic = await sudoWrapperTC(context.api, context.api.tx.extrinsicFilter.setMode('Test')); + await signAndSend(extrinsic, context.alice); + }); step('Transfer Value from Eve to EVM external account', async function () { - // In case evm is not enabled in Normal Mode, switch back to filterMode, after test. - // We do not test mode in initialization since ts-test concerns filter function too. - const filterMode = (await context.api.query.extrinsicFilter.mode()).toHuman(); - if ('Test' !== filterMode) { - let extrinsic = await sudoWrapperTC(context.api, context.api.tx.extrinsicFilter.setMode('Test')); - await signAndSend(extrinsic, context.alice); - } - let eveMappedEVMAccount = context.eve.publicKey.slice(0, 20); let eveMappedSustrateAccount = evmToAddress(eveMappedEVMAccount, 31); @@ -28,18 +30,9 @@ describeLitentry('Test EVM Module Contract', ``, (context) => { await signAndSend(tx_init, context.eve); // Get the initial balance of Eve and EVM external account - const { nonce: eveInitNonce, data: eveInitBalance } = await context.api.query.system.account( - context.eve.address - ); + const eveInitNonce = (await context.api.query.system.account(context.eve.address)).nonce; // EVM module transfer for substrate account - const evmAccountRaw = { - privateKey: '0x01ab6e801c06e59ca97a14fc0a1978b27fa366fc87450e0b65459dd3515b7391', - address: '0xaaafB3972B05630fCceE866eC69CdADd9baC2771', - mappedAddress: evmToAddress('0xaaafB3972B05630fCceE866eC69CdADd9baC2771', 31), - }; - const { nonce: evmAccountInitNonce, data: evmAccountInitBalance } = await context.api.query.system.account( - evmAccountRaw.mappedAddress - ); + const evmAccountInitBalance = (await context.api.query.system.account(evmAccountRaw.mappedAddress)).data; let value = new BN('20000000000000000000'); // 20 000 000 000 000 000 000 // 25000 is min_gas_price setup @@ -56,11 +49,8 @@ describeLitentry('Test EVM Module Contract', ``, (context) => { ); await signAndSend(tx, context.eve); - const { nonce: eveCurrentNonce, data: eveCurrentBalance } = await context.api.query.system.account( - context.eve.address - ); - const { nonce: evmAccountCurrentNonce, data: evmAccountCurrentBalance } = - await context.api.query.system.account(evmAccountRaw.mappedAddress); + const eveCurrentNonce = (await context.api.query.system.account(context.eve.address)).nonce; + const evmAccountCurrentBalance = (await context.api.query.system.account(evmAccountRaw.mappedAddress)).data; // If a substrate account using pallet_evm to trigger evm transaction, // it will bump 2 for nonce (one for substrate extrinsic, one for evm). @@ -69,49 +59,95 @@ describeLitentry('Test EVM Module Contract', ``, (context) => { expect(evmAccountCurrentBalance.free.toBigInt()).to.equal( evmAccountInitBalance.free.toBigInt() + BigInt(value) ); + }); - // In case evm is not enabled in Normal Mode, switch back to filterMode, after test. - let extrinsic = await sudoWrapperTC(context.api, context.api.tx.extrinsicFilter.setMode(filterMode)); - await signAndSend(extrinsic, context.alice); + step('Transfer some value back to Eve Mapped account from EVM external account', async function () { + // Get the initial balance of Eve and EVM external account + let eveMappedEVMAccount = context.eve.publicKey.slice(0, 20); + let eveMappedSustrateAccount = evmToAddress(eveMappedEVMAccount, 31); + const eveInitBalance = (await context.api.query.system.account(eveMappedSustrateAccount)).data; + const evmAccountInitNonce = (await context.api.query.system.account(evmAccountRaw.mappedAddress)).nonce; + + // Create Web3 instance + const web3 = new Web3(config.parachain_ws); + + let value = ethers.utils.parseUnits('0.1', 18).toString(); // 0.1 + // ExistentialDeposit = 100 000 000 000 000 000 + // Sign Tx with PK + console.log(`Tx Signing with: ${evmAccountRaw.privateKey}`); + const transferTransaction = await web3.eth.accounts.signTransaction( + { + from: evmAccountRaw.address, + to: u8aToHex(eveMappedEVMAccount), + value: value, // must be higher than ExistentialDeposit + gasPrice: 25000000000, + gas: 1000000, + }, + evmAccountRaw.privateKey + ); + console.log(`Tx Signed with: ${transferTransaction.rawTransaction}`); + const transferReceipt = await web3.eth.sendSignedTransaction(transferTransaction.rawTransaction!); + console.log(`Tx successful with hash: ${transferReceipt.transactionHash}`); + + const { nonce: eveCurrentNonce, data: eveCurrentBalance } = await context.api.query.system.account( + eveMappedSustrateAccount + ); + const { nonce: evmAccountCurrentNonce, data: evmAccountCurrentBalance } = + await context.api.query.system.account(evmAccountRaw.mappedAddress); + + console.log(`evmAccount Balance: ${evmAccountCurrentBalance}`); + + expect(evmAccountCurrentNonce.toNumber()).to.equal(evmAccountInitNonce.toNumber() + 1); + expect(eveCurrentBalance.free.toBigInt()).to.equal(eveInitBalance.free.toBigInt() + BigInt(value)); }); - step('Deploy and test contract by EVM external account', async function () { - // We want evm works in Normal Mode, switch back to filterMode, after testing. - // We do not test mode in initialization since ts-test concerns filter function too. - const filterMode = (await context.api.query.extrinsicFilter.mode()).toHuman(); - if ('Normal' !== filterMode) { - let extrinsic = await sudoWrapperTC(context.api, context.api.tx.extrinsicFilter.setMode('Normal')); - await signAndSend(extrinsic, context.alice); - } + step('Test substrate signature can not access ultra vires evm/substrate account', async function () { + // Get the initial balance of Eve and EVM external account + const eveInitNonce = (await context.api.query.system.account(context.eve.address)).nonce; + const evmAccountInitBalance = (await context.api.query.system.account(evmAccountRaw.mappedAddress)).data; - const evmAccountRaw = { - privateKey: '0x01ab6e801c06e59ca97a14fc0a1978b27fa366fc87450e0b65459dd3515b7391', - address: '0xaaafB3972B05630fCceE866eC69CdADd9baC2771', - mappedAddress: evmToAddress('0xaaafB3972B05630fCceE866eC69CdADd9baC2771', 31), - }; - const { nonce: evmAccountInitNonce, data: evmAccountInitBalance } = await context.api.query.system.account( - evmAccountRaw.mappedAddress + let eveMappedEVMAccount = context.eve.publicKey.slice(0, 20); + let value = new BN('100000000000000000'); // ExistentialDeposit = 100 000 000 000 000 000 + // Sign Tx with substrate signature, try manipulate evm account out of substrate signature's control + // 25000 is min_gas_price setup + const tx = context.api.tx.evm.call( + evmAccountRaw.address, + eveMappedEVMAccount, + '0x', + value, + 1000000, + 25000000000, + null, + null, + [] ); + await signAndSend(tx, context.eve); + + const eveCurrentNonce = (await context.api.query.system.account(context.eve.address)).nonce; + const evmAccountCurrentBalance = (await context.api.query.system.account(evmAccountRaw.mappedAddress)).data; + // Extrinsic succeed with failed origin + // So the evm transaction nonce bump will not be triggered + expect(eveCurrentNonce.toNumber()).to.equal(eveInitNonce.toNumber() + 1); + // Which means balance unchanged + expect(evmAccountCurrentBalance.free.toBigInt()).to.equal(evmAccountInitBalance.free.toBigInt()); + }); + + step('Deploy and test contract by EVM external account', async function () { // Get the bytecode and API const bytecode = compiled.evm.bytecode.object; const abi = compiled.abi; - // Create Web3 instance const web3 = new Web3(config.parachain_ws); - // Create deploy function const deploy = async (accountFrom: any) => { console.log(`Attempting to deploy from account ${accountFrom.address}`); - // Create contract instance const hello = new web3.eth.Contract(abi); - // Create constructor tx const helloTx = hello.deploy({ data: bytecode, arguments: [], }); - // Sign transacation and send const createTransaction = await web3.eth.accounts.signTransaction( { data: helloTx.encodeABI(), @@ -122,7 +158,6 @@ describeLitentry('Test EVM Module Contract', ``, (context) => { accountFrom.privateKey ); - // Send tx and wait for receipt const createReceipt = await web3.eth.sendSignedTransaction(createTransaction.rawTransaction!); console.log(`Contract deployed at address: ${createReceipt.contractAddress}`); @@ -136,13 +171,10 @@ describeLitentry('Test EVM Module Contract', ``, (context) => { // Test get message contract method const sayMessage = async (contractAddress: string): Promise => { - // 4. Create contract instance const hello = new web3.eth.Contract(abi, contractAddress); console.log(`Making a call to contract at address: ${contractAddress}`); - // 6. Call contract const data: string = await hello.methods.sayMessage().call(); - console.log(`The current message is: ${data}`); return data; @@ -156,12 +188,9 @@ describeLitentry('Test EVM Module Contract', ``, (context) => { const setMessage = async (contractAddress: string, accountFrom: any, message: string) => { console.log(`Calling the setMessage function in contract at address: ${contractAddress}`); - // Create contract instance const hello = new web3.eth.Contract(abi, contractAddress); - // Build tx const helloTx = hello.methods.setMessage(message); - // Sign Tx with PK const createTransaction = await web3.eth.accounts.signTransaction( { to: contractAddress, @@ -173,7 +202,6 @@ describeLitentry('Test EVM Module Contract', ``, (context) => { accountFrom.privateKey ); - // Send Tx and Wait for Receipt const createReceipt = await web3.eth.sendSignedTransaction(createTransaction.rawTransaction!); console.log(`Tx successful with hash: ${createReceipt.transactionHash}`); }; @@ -181,9 +209,10 @@ describeLitentry('Test EVM Module Contract', ``, (context) => { const sayMsg = await sayMessage(deployed.contractAddress!); const setResult = sayMsg === 'Goodbye World' ? 1 : 0; assert.equal(1, setResult, 'Contract modified storage query mismatch'); + }); - // In case evm is not enabled in Normal Mode, switch back to filterMode, after test. - let extrinsic = await sudoWrapperTC(context.api, context.api.tx.extrinsicFilter.setMode(filterMode)); + step('Set ExtrinsicFilter mode to Normal', async function () { + let extrinsic = await sudoWrapperTC(context.api, context.api.tx.extrinsicFilter.setMode('Normal')); await signAndSend(extrinsic, context.alice); }); }); diff --git a/parachain/ts-tests/integration-tests/evm-transfer.test.ts b/parachain/ts-tests/integration-tests/evm-transfer.test.ts deleted file mode 100644 index 9914d7ec21..0000000000 --- a/parachain/ts-tests/integration-tests/evm-transfer.test.ts +++ /dev/null @@ -1,217 +0,0 @@ -import { assert, expect } from 'chai'; -import { step } from 'mocha-steps'; - -import { signAndSend, describeLitentry, loadConfig, sudoWrapperTC } from '../common/utils'; -import { hexToU8a, u8aToHex } from '@polkadot/util'; -import { createPair, encodeAddress } from '@polkadot/keyring'; -import { evmToAddress } from '@polkadot/util-crypto'; -const BN = require('bn.js'); -import { Web3 } from 'web3'; -import { ethers } from 'ethers'; - -describeLitentry('Test EVM Module Transfer', ``, (context) => { - console.log(`Test EVM Module Transfer`); - const config = loadConfig(); - step('Transfer Value from Eve to EVM external account', async function () { - // In case evm is not enabled in Normal Mode, switch back to filterMode, after test. - // We do not test mode in initialization since ts-test concerns filter function too. - const filterMode = (await context.api.query.extrinsicFilter.mode()).toHuman(); - if ('Test' !== filterMode) { - let extrinsic = await sudoWrapperTC(context.api, context.api.tx.extrinsicFilter.setMode('Test')); - let temp = await context.api.rpc.chain.getBlock(); - console.log(`setMode await Before: ${temp.block.header.number}`); - await signAndSend(extrinsic, context.alice); - temp = await context.api.rpc.chain.getBlock(); - console.log(`setMode await end: ${temp.block.header.number}`); - } - - // EVM module transfer for substrate account - const evmAccountRaw = { - privateKey: '0x01ab6e801c06e59ca97a14fc0a1978b27fa366fc87450e0b65459dd3515b7391', - address: '0xaaafB3972B05630fCceE866eC69CdADd9baC2771', - mappedAddress: evmToAddress('0xaaafB3972B05630fCceE866eC69CdADd9baC2771', 31), - }; - console.log(`evm mapped substrate address: ${evmAccountRaw.mappedAddress}`); - const { data: evmAccountInitBalance } = await context.api.query.system.account(evmAccountRaw.mappedAddress); - - let eveMappedEVMAccount = context.eve.publicKey.slice(0, 20); - let eveMappedSustrateAccount = evmToAddress(eveMappedEVMAccount, 31); - console.log(`eve address: ${context.eve.publicKey}`); - console.log(`eveMappedEVMAccount: ${eveMappedEVMAccount}`); - - // Deposit money into substrate account's truncated EVM address's mapping substrate account - const tx_init = context.api.tx.balances.transfer(eveMappedSustrateAccount, new BN('30000000000000000000')); // 30 000 000 000 000 000 000 - await signAndSend(tx_init, context.eve); - - // Get the initial balance of Eve and EVM external account - const { nonce: eveInitNonce, data: eveInitBalance } = await context.api.query.system.account( - context.eve.address - ); - - let value = new BN('20000000000000000000'); // 20 000 000 000 000 000 000 - // 25000 is min_gas_price setup - const tx = context.api.tx.evm.call( - eveMappedEVMAccount, - evmAccountRaw.address, - '0x', - value, - 1000000, - 25000000000, - null, - null, - [] - ); - let block = await context.api.rpc.chain.getBlock(); - const blockNumber = block.block.header.number; - console.log(`evm call await before: ${block.block.header.number}`); - await signAndSend(tx, context.eve); - let temp = await context.api.rpc.chain.getBlock(); - console.log(`evm call await end: ${temp.block.header.number}`); - - const { nonce: eveCurrentNonce, data: eveCurrentBalance } = await context.api.query.system.account( - context.eve.address - ); - const { nonce: evmAccountCurrentNonce, data: evmAccountCurrentBalance } = - await context.api.query.system.account(evmAccountRaw.mappedAddress); - - // If a substrate account using pallet_evm to trigger evm transaction, - // it will bump 2 for nonce (one for substrate extrinsic, one for evm). - // +1 nonce for original substrate account, plus another 1 nonce for original substrate account's truncated evm address's mapped susbtrate account. - expect(eveCurrentNonce.toNumber()).to.equal(eveInitNonce.toNumber() + 1); - - expect(evmAccountCurrentBalance.free.toBigInt()).to.equal( - evmAccountInitBalance.free.toBigInt() + BigInt(value) - ); - - // In case evm is not enabled in Normal Mode, switch back to filterMode, after test. - let extrinsic = await sudoWrapperTC(context.api, context.api.tx.extrinsicFilter.setMode(filterMode)); - await signAndSend(extrinsic, context.alice); - }); - - step('Transfer some value back to Eve Mapped account from EVM external account', async function () { - // In case evm is not enabled in Normal Mode, switch back to filterMode, after test. - // We do not test mode in initialization since ts-test concerns filter function too. - const filterMode = (await context.api.query.extrinsicFilter.mode()).toHuman(); - if ('Test' !== filterMode) { - let extrinsic = await sudoWrapperTC(context.api, context.api.tx.extrinsicFilter.setMode('Test')); - let temp = await context.api.rpc.chain.getBlock(); - console.log(`setMode await Before: ${temp.block.header.number}`); - await signAndSend(extrinsic, context.alice); - temp = await context.api.rpc.chain.getBlock(); - console.log(`setMode await end: ${temp.block.header.number}`); - } - - // Get the initial balance of Eve and EVM external account - let eveMappedEVMAccount = context.eve.publicKey.slice(0, 20); - let eveMappedSustrateAccount = evmToAddress(eveMappedEVMAccount, 31); - const { nonce: eveInitNonce, data: eveInitBalance } = await context.api.query.system.account( - eveMappedSustrateAccount - ); - const evmAccountRaw = { - privateKey: '0x01ab6e801c06e59ca97a14fc0a1978b27fa366fc87450e0b65459dd3515b7391', - address: '0xaaafB3972B05630fCceE866eC69CdADd9baC2771', - mappedAddress: evmToAddress('0xaaafB3972B05630fCceE866eC69CdADd9baC2771', 31), - }; - const { nonce: evmAccountInitNonce, data: evmAccountInitBalance } = await context.api.query.system.account( - evmAccountRaw.mappedAddress - ); - - // Create Web3 instance - const web3 = new Web3(config.parachain_ws); - - let value = ethers.utils.parseUnits('0.1', 18).toString(); // 0.1 - // ExistentialDeposit = 100 000 000 000 000 000 - // Sign Tx with PK - console.log(`Tx Signing with: ${evmAccountRaw.privateKey}`); - const transferTransaction = await web3.eth.accounts.signTransaction( - { - from: evmAccountRaw.address, - to: u8aToHex(eveMappedEVMAccount), - value: value, // must be higher than ExistentialDeposit - gasPrice: 25000000000, - gas: 1000000, - }, - evmAccountRaw.privateKey - ); - console.log(`Tx Signed with: ${transferTransaction.rawTransaction}`); - const transferReceipt = await web3.eth.sendSignedTransaction(transferTransaction.rawTransaction!); - console.log(`Tx successful with hash: ${transferReceipt.transactionHash}`); - - const { nonce: eveCurrentNonce, data: eveCurrentBalance } = await context.api.query.system.account( - eveMappedSustrateAccount - ); - const { nonce: evmAccountCurrentNonce, data: evmAccountCurrentBalance } = - await context.api.query.system.account(evmAccountRaw.mappedAddress); - - console.log(`evmAccount Balance: ${evmAccountCurrentBalance}`); - - expect(evmAccountCurrentNonce.toNumber()).to.equal(evmAccountInitNonce.toNumber() + 1); - expect(eveCurrentBalance.free.toBigInt()).to.equal(eveInitBalance.free.toBigInt() + BigInt(value)); - - // In case evm is not enabled in Normal Mode, switch back to filterMode, after test. - let extrinsic = await sudoWrapperTC(context.api, context.api.tx.extrinsicFilter.setMode(filterMode)); - await signAndSend(extrinsic, context.alice); - }); - - step('Test substrate signature can not access ultra vires evm/substrate account', async function () { - // In case evm is not enabled in Normal Mode, switch back to filterMode, after test. - // We do not test mode in initialization since ts-test concerns filter function too. - const filterMode = (await context.api.query.extrinsicFilter.mode()).toHuman(); - if ('Test' !== filterMode) { - let extrinsic = await sudoWrapperTC(context.api, context.api.tx.extrinsicFilter.setMode('Test')); - await signAndSend(extrinsic, context.alice); - } - - // Get the initial balance of Eve and EVM external account - const { nonce: eveInitNonce, data: eveInitBalance } = await context.api.query.system.account( - context.eve.address - ); - // EVM module transfer for substrate account - const evmAccountRaw = { - privateKey: '0x01ab6e801c06e59ca97a14fc0a1978b27fa366fc87450e0b65459dd3515b7391', - address: '0xaaafB3972B05630fCceE866eC69CdADd9baC2771', - mappedAddress: evmToAddress('0xaaafB3972B05630fCceE866eC69CdADd9baC2771', 31), - }; - const { nonce: evmAccountInitNonce, data: evmAccountInitBalance } = await context.api.query.system.account( - evmAccountRaw.mappedAddress - ); - - const evmAccount = createPair( - { toSS58: encodeAddress, type: 'ethereum' }, - { publicKey: hexToU8a(evmAccountRaw.mappedAddress), secretKey: new Uint8Array([]) } - ); - - let eveMappedEVMAccount = context.eve.publicKey.slice(0, 20); - let value = new BN('100000000000000000'); // ExistentialDeposit = 100 000 000 000 000 000 - // Sign Tx with substrate signature, try manipulate evm account out of substrate signature's control - // 25000 is min_gas_price setup - const tx = context.api.tx.evm.call( - evmAccountRaw.address, - eveMappedEVMAccount, - '0x', - value, - 1000000, - 25000000000, - null, - null, - [] - ); - await signAndSend(tx, context.eve); - - const { nonce: eveCurrentNonce, data: eveCurrentBalance } = await context.api.query.system.account( - context.eve.address - ); - const { nonce: evmAccountCurrentNonce, data: evmAccountCurrentBalance } = - await context.api.query.system.account(evmAccountRaw.mappedAddress); - - // Extrinsic succeed with failed origin - // So the evm transaction nonce bump will not be triggered - expect(eveCurrentNonce.toNumber()).to.equal(eveInitNonce.toNumber() + 1); - // Which means balance unchanged - expect(evmAccountCurrentBalance.free.toBigInt()).to.equal(evmAccountInitBalance.free.toBigInt()); - - // In case evm is not enabled in Normal Mode, switch back to filterMode, after test. - let extrinsic = await sudoWrapperTC(context.api, context.api.tx.extrinsicFilter.setMode(filterMode)); - await signAndSend(extrinsic, context.alice); - }); -}); diff --git a/parachain/ts-tests/integration-tests/precompile-contract.test.ts b/parachain/ts-tests/integration-tests/precompile-contract.test.ts index 9e2aa15027..beb018a859 100644 --- a/parachain/ts-tests/integration-tests/precompile-contract.test.ts +++ b/parachain/ts-tests/integration-tests/precompile-contract.test.ts @@ -7,7 +7,6 @@ import { subscribeToEvents, sudoWrapperGC, sudoWrapperTC, - sleep, } from '../common/utils'; import precompileStakingContractAbi from '../common/abi/precompile/Staking.json'; import precompileBridgeContractAbi from '../common/abi/precompile/Bridge.json'; @@ -17,6 +16,7 @@ import { KeyringPair } from '@polkadot/keyring/types'; import { HexString } from '@polkadot/util/types'; import { ethers } from 'ethers'; import { destResourceId } from '../common/utils/consts'; + const toBigInt = (int: number) => BigInt(int) * BigInt(1e18); const bn1e18 = new BN(10).pow(new BN(18)); const bn100 = new BN(100); @@ -100,12 +100,7 @@ describeLitentry('Test Parachain Precompile Contract', ``, (context) => { null, [] ); - let block = await context.api.rpc.chain.getBlock(); - console.log(`evm call await before: ${block.block.header.number}`); await signAndSend(tx, from); - let temp = await context.api.rpc.chain.getBlock(); - console.log(`evm call await end: ${temp.block.header.number}`); - await sleep(30); }; const isPendingRequest = async () => @@ -117,7 +112,12 @@ describeLitentry('Test Parachain Precompile Contract', ``, (context) => { return collators[0]; }; - step('Address with not sufficient amount of tokens', async function () { + step('Set ExtrinsicFilter mode to Test', async function () { + let extrinsic = await sudoWrapperTC(context.api, context.api.tx.extrinsicFilter.setMode('Test')); + await signAndSend(extrinsic, context.alice); + }); + + step('Address with insufficient amount of tokens', async function () { const randomEvmWallet = ethers.Wallet.createRandom(); const delegateWithAutoCompound = precompileStakingContract.interface.encodeFunctionData( 'delegateWithAutoCompound', @@ -139,17 +139,10 @@ describeLitentry('Test Parachain Precompile Contract', ``, (context) => { expect(e).to.be.instanceof(Error); } }); + step('Test precompile bridge contract', async function () { console.time('Test precompile bridge contract'); - const filterMode = (await context.api.query.extrinsicFilter.mode()).toHuman(); - if ('Test' !== filterMode) { - let extrinsic = await sudoWrapperTC(context.api, context.api.tx.extrinsicFilter.setMode('Test')); - let temp = await context.api.rpc.chain.getBlock(); - console.log(`setMode await Before: ${temp.block.header.number}`); - await signAndSend(extrinsic, context.alice); - temp = await context.api.rpc.chain.getBlock(); - console.log(`setMode await end: ${temp.block.header.number}`); - } + const dest_address = '0xaaafb3972b05630fccee866ec69cdadd9bac2772'; // random address let balance = (await context.api.query.system.account(evmAccountRaw.mappedAddress)).data; @@ -204,23 +197,15 @@ describeLitentry('Test Parachain Precompile Contract', ``, (context) => { console.timeEnd('Test precompile bridge contract'); }); + // To see full params types for the interfaces, check notion page: https://web3builders.notion.site/Parachain-Precompile-Contract-0c34929e5f16408084446dcf3dd36006 step('Test precompile staking contract', async function () { console.time('Test precompile staking contract'); - const filterMode = (await context.api.query.extrinsicFilter.mode()).toHuman(); - if ('Test' !== filterMode) { - let extrinsic = await sudoWrapperTC(context.api, context.api.tx.extrinsicFilter.setMode('Test')); - let temp = await context.api.rpc.chain.getBlock(); - console.log(`setMode await Before: ${temp.block.header.number}`); - await signAndSend(extrinsic, context.alice); - temp = await context.api.rpc.chain.getBlock(); - console.log(`setMode await end: ${temp.block.header.number}`); - } let balance = (await context.api.query.system.account(evmAccountRaw.mappedAddress)).data; printBalance('initial balance', balance); - // top up LITs if not sufficient amount for staking or they are not reserved (require: 50 LITs minimum) + // top up LITs if insufficient amount for staking or they are not reserved (require: 50 LITs minimum) if ( parseInt(balance.free.toString()) < parseInt('60000000000000000000') && Number(balance.reserved.toString()) === 0 @@ -233,11 +218,9 @@ describeLitentry('Test Parachain Precompile Contract', ``, (context) => { printBalance('balance after transferring', balance); } - //// TESTS const autoCompoundPercent = 20; let collator = (await context.api.query.parachainStaking.candidateInfo(context.alice.address)).toHuman(); - console.log('Candidates Info:', collator); const staking_status = ( await context.api.query.parachainStaking.delegatorState(evmAccountRaw.mappedAddress) ).toHuman(); @@ -252,7 +235,6 @@ describeLitentry('Test Parachain Precompile Contract', ``, (context) => { await signAndSend(join_extrinsic, context.alice); } collator = (await context.api.query.parachainStaking.candidateInfo(context.alice.address)).toHuman(); - console.log('Candidates Info:', collator); // delegateWithAutoCompound(collator, amount, percent) const delegateWithAutoCompound = precompileStakingContract.interface.encodeFunctionData( @@ -320,68 +302,67 @@ describeLitentry('Test Parachain Precompile Contract', ``, (context) => { await executeTransaction(cancelDelegationRequest, precompileStakingContractAddress, 'cancelDelegationRequest'); expect(await isPendingRequest()).to.be.false; - // testing bond less + execution - await executeTransaction( - scheduleDelegatorBondLess, - precompileStakingContractAddress, - 'scheduleDelegatorBondLess again to test execution' - ); - expect(await isPendingRequest()).to.be.true; - - console.log('Waiting 2 blocks before execute delegation request'); - await context.api.rpc.chain.getBlock(); - await context.api.rpc.chain.getBlock(); - - // executeDelegationRequest(delegator, collator); - const executeDelegationRequest = precompileStakingContract.interface.encodeFunctionData( - 'executeDelegationRequest', - [evmAccountRaw.publicKey, collatorPublicKey] - ); - await executeTransaction( - executeDelegationRequest, - precompileStakingContractAddress, - 'executeDelegationRequest' - ); - const { data: balanceAfterBondLess } = await context.api.query.system.account(evmAccountRaw.mappedAddress); - expect(balanceAfterBondLess.reserved.toBigInt()).to.eq(balanceAfterBondMore.reserved.toBigInt() - toBigInt(5)); + // only makes sense when parachain is compiled with `fast-runtime` feature, otherwise we'll + // never make it within reasonable time + if (config.parachain_fast_runtime === 'true') { + // testing bond less + execution + await executeTransaction( + scheduleDelegatorBondLess, + precompileStakingContractAddress, + 'scheduleDelegatorBondLess again to test execution' + ); + expect(await isPendingRequest()).to.be.true; - // testing revoke delegation + execute - // scheduleRevokeDelegation(collator); - const scheduleRevokeDelegation = precompileStakingContract.interface.encodeFunctionData( - 'scheduleRevokeDelegation', - [collatorPublicKey] - ); - await executeTransaction( - scheduleRevokeDelegation, - precompileStakingContractAddress, - 'scheduleRevokeDelegation' - ); + // executeDelegationRequest(delegator, collator); + const executeDelegationRequest = precompileStakingContract.interface.encodeFunctionData( + 'executeDelegationRequest', + [evmAccountRaw.publicKey, collatorPublicKey] + ); + await executeTransaction( + executeDelegationRequest, + precompileStakingContractAddress, + 'executeDelegationRequest' + ); + const { data: balanceAfterBondLess } = await context.api.query.system.account(evmAccountRaw.mappedAddress); + expect(balanceAfterBondLess.reserved.toBigInt()).to.eq( + balanceAfterBondMore.reserved.toBigInt() - toBigInt(5) + ); - console.log('Waiting 2 blocks before execute delegation request'); - await context.api.rpc.chain.getBlock(); - await context.api.rpc.chain.getBlock(); + // testing revoke delegation + execute + // scheduleRevokeDelegation(collator); + const scheduleRevokeDelegation = precompileStakingContract.interface.encodeFunctionData( + 'scheduleRevokeDelegation', + [collatorPublicKey] + ); + await executeTransaction( + scheduleRevokeDelegation, + precompileStakingContractAddress, + 'scheduleRevokeDelegation' + ); - await executeTransaction( - executeDelegationRequest, - precompileStakingContractAddress, - 'executeDelegationRequest' - ); - const { data: balanceAfterRevoke } = await context.api.query.system.account(evmAccountRaw.mappedAddress); - expect(balanceAfterRevoke.reserved.toBigInt()).to.eq(toBigInt(0)); + await executeTransaction( + executeDelegationRequest, + precompileStakingContractAddress, + 'executeDelegationRequest' + ); + const { data: balanceAfterRevoke } = await context.api.query.system.account(evmAccountRaw.mappedAddress); + expect(balanceAfterRevoke.reserved.toBigInt()).to.eq(toBigInt(0)); + + // delegate(collator, amount); + const delegate = precompileStakingContract.interface.encodeFunctionData('delegate', [ + collatorPublicKey, + ethers.utils.parseUnits('57', 18).toString(), + ]); + await executeTransaction(delegate, precompileStakingContractAddress, 'delegate'); + const { data: balanceAfterDelegate } = await context.api.query.system.account(evmAccountRaw.mappedAddress); + expect(balanceAfterDelegate.reserved.toBigInt()).to.eq(toBigInt(57)); + } - // delegate(collator, amount); - const delegate = precompileStakingContract.interface.encodeFunctionData('delegate', [ - collatorPublicKey, - ethers.utils.parseUnits('57', 18).toString(), - ]); - await executeTransaction(delegate, precompileStakingContractAddress, 'delegate'); - const { data: balanceAfterDelegate } = await context.api.query.system.account(evmAccountRaw.mappedAddress); - expect(balanceAfterDelegate.reserved.toBigInt()).to.eq(toBigInt(57)); + console.timeEnd('Test precompile staking contract'); + }); - // In case evm is not enabled in Normal Mode, switch back to filterMode, after test. - let extrinsic = await sudoWrapperTC(context.api, context.api.tx.extrinsicFilter.setMode(filterMode)); + step('Set ExtrinsicFilter mode to Normal', async function () { + let extrinsic = await sudoWrapperTC(context.api, context.api.tx.extrinsicFilter.setMode('Normal')); await signAndSend(extrinsic, context.alice); - - console.timeEnd('Test precompile staking contract'); }); }); diff --git a/parachain/ts-tests/package.json b/parachain/ts-tests/package.json index b208002fd0..b5a92fa704 100644 --- a/parachain/ts-tests/package.json +++ b/parachain/ts-tests/package.json @@ -14,7 +14,6 @@ "setup-enclave": "pnpm exec ts-node common/setup/setup-enclave.ts", "test-filter": "pnpm exec mocha --exit --sort -r ts-node/register 'integration-tests/base-filter.test.ts'", "test-bridge": "pnpm exec mocha --exit --sort -r ts-node/register 'integration-tests/bridge.test.ts'", - "test-evm-transfer": "pnpm exec mocha --exit --sort -r ts-node/register 'integration-tests/evm-transfer.test.ts'", "test-evm-contract": "pnpm exec mocha --exit --sort -r ts-node/register 'integration-tests/evm-contract.test.ts'", "test-runtime-upgrade": "pnpm exec mocha --exit --sort -r ts-node/register 'integration-tests/runtime-upgrade.test.ts'", "test-all": "pnpm exec mocha --exit --sort -r ts-node/register 'integration-tests/**/*.test.ts'",