Skip to content

Commit

Permalink
Clean up parachain ts test (#3104)
Browse files Browse the repository at this point in the history
* update bridge

* update evm

* update bridge test

* fix tests

* fix test

* stop geth container

* test it in ci

* restore
  • Loading branch information
Kailai-Wang authored Oct 1, 2024
1 parent ed8dbff commit a27f8bb
Show file tree
Hide file tree
Showing 16 changed files with 224 additions and 442 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/create-release-draft.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
Expand Down
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
1 change: 1 addition & 0 deletions local-setup/launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
2 changes: 2 additions & 0 deletions parachain/scripts/clean-network.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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"
28 changes: 6 additions & 22 deletions parachain/scripts/run-ts-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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"
2 changes: 1 addition & 1 deletion parachain/ts-tests/.env.example
Original file line number Diff line number Diff line change
@@ -1 +1 @@
NODE_ENV=<`local` or `staging` or `test` or `ci`>
NODE_ENV=<`local` or `prod` or `test` or `ci`>
5 changes: 4 additions & 1 deletion parachain/ts-tests/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@
.pnp.*

config.local.json
package-lock.json
package-lock.json

common/bob.json
common/data/
4 changes: 2 additions & 2 deletions parachain/ts-tests/common/utils/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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}`);
}
Expand Down
3 changes: 2 additions & 1 deletion parachain/ts-tests/config.ci.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
7 changes: 0 additions & 7 deletions parachain/ts-tests/config.example.json

This file was deleted.

12 changes: 12 additions & 0 deletions parachain/ts-tests/config.prod.json
Original file line number Diff line number Diff line change
@@ -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"
}
72 changes: 32 additions & 40 deletions parachain/ts-tests/integration-tests/bridge.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,92 +6,88 @@ 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(),
afterAccountData.data.free.toBn().toString()
);
});

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);
Expand All @@ -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') {
Expand All @@ -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',
Expand All @@ -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()
);
Expand All @@ -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;
Expand Down Expand Up @@ -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.<module>.<ErrorName>.is(dispatchError.asModule) guard)
// context.parachainConfig.api.errors.<module>.<ErrorName>.is(dispatchError.asModule) guard)
const decoded = context.parachainConfig.api.registry.findMetaError(
dispatchError.asModule
);
Expand All @@ -224,6 +217,5 @@ describeCrossChainTransfer('Test Cross-chain Transfer', ``, (context) => {
assert.exists('');
}
});
await sleep(39);
});
});
Loading

0 comments on commit a27f8bb

Please sign in to comment.