From f9dd727c1ef55e9ef5d81fdf332d86197f682d08 Mon Sep 17 00:00:00 2001 From: cuteolaf Date: Tue, 7 May 2024 04:42:04 +0000 Subject: [PATCH] WIP: rococo to regionx --- e2e_tests/common.ts | 106 +++++++++++++----------- e2e_tests/xc-transfer/regionx-rococo.ts | 0 e2e_tests/xc-transfer/rococo-regionx.ts | 80 ++++++++++++++++++ zombienet_tests/0006-xc-transfer.toml | 23 +++++ zombienet_tests/0006-xc-transfer.zndsl | 11 +++ 5 files changed, 171 insertions(+), 49 deletions(-) create mode 100644 e2e_tests/xc-transfer/regionx-rococo.ts create mode 100644 e2e_tests/xc-transfer/rococo-regionx.ts create mode 100644 zombienet_tests/0006-xc-transfer.toml create mode 100644 zombienet_tests/0006-xc-transfer.zndsl diff --git a/e2e_tests/common.ts b/e2e_tests/common.ts index 04391000..4c382bae 100644 --- a/e2e_tests/common.ts +++ b/e2e_tests/common.ts @@ -2,56 +2,64 @@ import { ApiPromise } from "@polkadot/api"; import { SubmittableExtrinsic, SignerOptions } from "@polkadot/api/types"; import { KeyringPair } from "@polkadot/keyring/types"; -const RELAY_ASSET_ID = 1; - -async function submitExtrinsic(signer: KeyringPair, call: SubmittableExtrinsic<"promise">, options: Partial): Promise { - return new Promise(async (resolve, reject) => { - const unsub = await call.signAndSend(signer, options, (result) => { - console.log(`Current status is ${result.status}`); - if (result.status.isInBlock) { - console.log( - `Transaction included at blockHash ${result.status.asInBlock}` - ); - } else if (result.status.isFinalized) { - console.log( - `Transaction finalized at blockHash ${result.status.asFinalized}` - ); - unsub(); - return resolve(); - } else if (result.isError) { - console.log(`Transaction error`); - unsub(); - return reject(); - } - }); - }); +const RELAY_ASSET_ID = 1; + +async function submitExtrinsic( + signer: KeyringPair, + call: SubmittableExtrinsic<"promise">, + options: Partial +): Promise { + return new Promise(async (resolve, reject) => { + const unsub = await call.signAndSend(signer, options, (result) => { + console.log(`Current status is ${result.status}`); + if (result.status.isInBlock) { + console.log(`Transaction included at blockHash ${result.status.asInBlock}`); + } else if (result.status.isFinalized) { + console.log(`Transaction finalized at blockHash ${result.status.asFinalized}`); + unsub(); + return resolve(); + } else if (result.isError) { + console.log(`Transaction error`); + unsub(); + return reject(); + } + }); + }); +} + +async function setupRelayAsset( + api: ApiPromise, + signer: KeyringPair, + initialBalance: bigint = 10n ** 12n +) { + const assetMetadata = { + decimals: 12, + name: "ROC", + symbol: "ROC", + existentialDeposit: 10n ** 3n, + location: null, + additional: null, + }; + + const assetSetupCalls = [ + api.tx.assetRegistry.registerAsset(assetMetadata, RELAY_ASSET_ID), + api.tx.assetRate.create(RELAY_ASSET_ID, 1_000_000_000_000_000_000n), // 1 on 1 + ]; + + if (initialBalance > BigInt(0)) { + assetSetupCalls.push( + api.tx.tokens.setBalance(signer.address, RELAY_ASSET_ID, initialBalance, 0) + ); + } + + const batchCall = api.tx.utility.batch(assetSetupCalls); + const sudoCall = api.tx.sudo.sudo(batchCall); + + await submitExtrinsic(signer, sudoCall, {}); } -async function setupRelayAsset(api: ApiPromise, signer: KeyringPair) { - const assetMetadata = { - decimals: 12, - name: "ROC", - symbol: "ROC", - existentialDeposit: 10n ** 3n, - location: null, - additional: null, - }; - - const assetSetupCalls = [ - api.tx.assetRegistry.registerAsset(assetMetadata, RELAY_ASSET_ID), - api.tx.assetRate.create(RELAY_ASSET_ID, 1_000_000_000_000_000_000n), // 1 on 1 - api.tx.tokens.setBalance( - signer.address, - RELAY_ASSET_ID, - 10n ** 12n, - 0, - ), - ]; - - const batchCall = api.tx.utility.batch(assetSetupCalls); - const sudoCall = api.tx.sudo.sudo(batchCall); - - await submitExtrinsic(signer, sudoCall, {}); +async function sleep(milliseconds: number) { + return new Promise((resolve) => setTimeout(resolve, milliseconds)); } -export { submitExtrinsic, setupRelayAsset, RELAY_ASSET_ID } +export { submitExtrinsic, setupRelayAsset, sleep, RELAY_ASSET_ID }; diff --git a/e2e_tests/xc-transfer/regionx-rococo.ts b/e2e_tests/xc-transfer/regionx-rococo.ts new file mode 100644 index 00000000..e69de29b diff --git a/e2e_tests/xc-transfer/rococo-regionx.ts b/e2e_tests/xc-transfer/rococo-regionx.ts new file mode 100644 index 00000000..ce1f8628 --- /dev/null +++ b/e2e_tests/xc-transfer/rococo-regionx.ts @@ -0,0 +1,80 @@ +import { ApiPromise, WsProvider, Keyring } from "@polkadot/api"; +import { RELAY_ASSET_ID, setupRelayAsset, sleep, submitExtrinsic } from "../common"; + +import assert from "node:assert"; + +async function run(nodeName: string, networkInfo: any, _jsArgs: any) { + const { wsUri: regionXUri } = networkInfo.nodesByName[nodeName]; + const { wsUri: rococoUri } = networkInfo.nodesByName["rococo-validator01"]; + + const rococoApi = await ApiPromise.create({ provider: new WsProvider(rococoUri) }); + const regionXApi = await ApiPromise.create({ provider: new WsProvider(regionXUri) }); + + // account to submit tx + const keyring = new Keyring({ type: "sr25519" }); + const alice = keyring.addFromUri("//Alice"); + + const setXcmVersion = rococoApi.tx.xcmPallet.forceDefaultXcmVersion([3]); + await submitExtrinsic(alice, rococoApi.tx.sudo.sudo(setXcmVersion), {}); + + const BALANCE = 10n ** 12n; + + await setupRelayAsset(regionXApi, alice, BALANCE); + + const receiverKeypair = new Keyring(); + receiverKeypair.addFromAddress(alice.address); + + const { free: balanceBefore } = ( + await regionXApi.query.tokens.accounts(alice.address, RELAY_ASSET_ID) + ).toJSON() as any; + + console.log(`balanceBefore = ${balanceBefore}`); + + assert.equal(BigInt(balanceBefore), BALANCE); + + const feeAssetItem = 0; + const weightLimit = "Unlimited"; + const reserveTransfer = rococoApi.tx.xcmPallet.limitedReserveTransferAssets( + { V3: { parents: 0, interior: { X1: { Parachain: 2000 } } } }, //dest + { + V3: { + parents: 0, + interior: { + X1: { + AccountId32: { + chain: "Any", + id: receiverKeypair.pairs[0].publicKey, + }, + }, + }, + }, + }, //beneficiary + { + V3: [ + { + id: { + Concrete: { parents: 0, interior: "Here" }, + }, + fun: { + Fungible: BALANCE, + }, + }, + ], + }, //asset + feeAssetItem, + weightLimit + ); + await submitExtrinsic(alice, reserveTransfer, {}); + + await sleep(15 * 1000); + + const { free: balanceAfter } = ( + await regionXApi.query.tokens.accounts(alice.address, RELAY_ASSET_ID) + ).toJSON() as any; + + console.log(`balanceAfter = ${balanceAfter}`); + + assert.equal(BigInt(balanceAfter), BALANCE * 2n); +} + +export { run }; diff --git a/zombienet_tests/0006-xc-transfer.toml b/zombienet_tests/0006-xc-transfer.toml new file mode 100644 index 00000000..635f5419 --- /dev/null +++ b/zombienet_tests/0006-xc-transfer.toml @@ -0,0 +1,23 @@ +[settings] +timeout = 1000 + +[relaychain] +chain = "rococo-local" +command = "polkadot" + + [[relaychain.nodes]] + name = "rococo-validator01" + validator = true + + [[relaychain.nodes]] + name = "rococo-validator02" + validator = true + +[[parachains]] +id = 2000 +addToGenesis = false + + [parachains.collator] + name = "regionx-collator01" + command = "regionx-node" + args = [ "-lruntime=debug,parachain=trace" ] diff --git a/zombienet_tests/0006-xc-transfer.zndsl b/zombienet_tests/0006-xc-transfer.zndsl new file mode 100644 index 00000000..bd91a32c --- /dev/null +++ b/zombienet_tests/0006-xc-transfer.zndsl @@ -0,0 +1,11 @@ +Description: Cross chain transfer between RegionX and the relay chain +Network: ./0006-xc-transfer.toml +Creds: config + +rococo-validator01: is up +rococo-validator02: is up + +rococo-validator01: parachain 2000 is registered within 225 seconds + +regionx-collator01: js-script ../e2e_tests/build/xc-transfer/rococo-regionx.js return is 0 within 400 seconds +