From 4c2d0630687510d3529e643821eb73d253734b09 Mon Sep 17 00:00:00 2001 From: ndk Date: Thu, 21 Nov 2024 10:56:06 +0100 Subject: [PATCH 1/9] added chopsticks folder with set-up and tests --- .../chopsticks/configs/README.md | 6 + .../configs/westend-asset-hub-override.yaml | 32 +++++ .../chopsticks/configs/westend-override.yaml | 21 +++ .../chopsticks/tests/v5-tests/README.md | 18 +++ .../chopsticks/tests/v5-tests/index.ts | 124 ++++++++++++++++++ .../chopsticks/wasms/README.md | 9 ++ 6 files changed, 210 insertions(+) create mode 100644 cumulus/parachains/integration-tests/chopsticks/configs/README.md create mode 100644 cumulus/parachains/integration-tests/chopsticks/configs/westend-asset-hub-override.yaml create mode 100644 cumulus/parachains/integration-tests/chopsticks/configs/westend-override.yaml create mode 100644 cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/README.md create mode 100644 cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/index.ts create mode 100644 cumulus/parachains/integration-tests/chopsticks/wasms/README.md diff --git a/cumulus/parachains/integration-tests/chopsticks/configs/README.md b/cumulus/parachains/integration-tests/chopsticks/configs/README.md new file mode 100644 index 000000000000..12baa4ee2559 --- /dev/null +++ b/cumulus/parachains/integration-tests/chopsticks/configs/README.md @@ -0,0 +1,6 @@ +This folder serves as a reference documentation for chopstick tests and the Parity-owned ecosystems. +It provides a working set of configuration files together with the WASM BLOBs, specifically for the Westend ecosystem. +For additional resources and original Acala configuration files, including documentation, refer to the [Acala repository](https://github.com/AcalaNetwork/chopsticks/tree/master/configs) or [Papermoon chopsticks overview](https://papermoonio.github.io/polkadot-ecosystem-docs-draft/dev-tools/chopsticks/overview/#using-a-configuration-file) + +Config files, especially `wasm-override:` fields there, assume that there is a `wasms` folder within the same parent directory, and it contains pre-built WASM BLOBs of the +ecosystem under tests. diff --git a/cumulus/parachains/integration-tests/chopsticks/configs/westend-asset-hub-override.yaml b/cumulus/parachains/integration-tests/chopsticks/configs/westend-asset-hub-override.yaml new file mode 100644 index 000000000000..4b448f0864d4 --- /dev/null +++ b/cumulus/parachains/integration-tests/chopsticks/configs/westend-asset-hub-override.yaml @@ -0,0 +1,32 @@ +endpoint: wss://asset-hub-polkadot-rpc.dwellir.com +mock-signature-host: true +block: ${env.WESTEND_ASSET_HUB_BLOCK_NUMBER} +db: ./db.sqlite +runtime-log-level: 5 +wasm-override: wasms/asset_hub_westend_runtime.compact.compressed.wasm + +import-storage: + System: + Account: + - + - + - 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY # Alice + - providers: 1 + data: + free: 1000000000000000 + - + - + - 5Eg2fntQqFi3EvFWAf71G66Ecjjah26bmFzoANAeHFgj9Lia + - providers: 1 + data: + free: 1000000000000000 + - + - + - 5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty # Bob + - providers: 1 + data: + free: 1000000000000000 +# Assets: +# Account: +# - [[1984, 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY], { balance: 1000000000 }] +# - [[1984, 5Eg2fntQqFi3EvFWAf71G66Ecjjah26bmFzoANAeHFgj9Lia], { balance: 1000000000 }] diff --git a/cumulus/parachains/integration-tests/chopsticks/configs/westend-override.yaml b/cumulus/parachains/integration-tests/chopsticks/configs/westend-override.yaml new file mode 100644 index 000000000000..a8e5c58c7eca --- /dev/null +++ b/cumulus/parachains/integration-tests/chopsticks/configs/westend-override.yaml @@ -0,0 +1,21 @@ +endpoint: + - wss://westend-rpc.dwellir.com +mock-signature-host: true +block: ${env.WESTEND_BLOCK_NUMBER} +db: ./db.sqlite +runtime-log-level: 5 +wasm-override: wasms/westend_runtime.compact.compressed.wasm + +import-storage: + XcmPallet: + SafeXcmVersion: 5 + System: + Account: + - + - + - 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY + - providers: 1 + data: + free: '10000000000000000000' + ParasDisputes: + $removePrefix: ['disputes'] diff --git a/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/README.md b/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/README.md new file mode 100644 index 000000000000..7740f0b42cdf --- /dev/null +++ b/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/README.md @@ -0,0 +1,18 @@ +# v5-sac-test + +To install dependencies: + +```bash +bun add polkadot-api +# now you need to switch to another terminal window where you executed bunx command, make sure that chains are running and copy Asset Hub's port in the command below (usually the port is 8001). +bun papi add wnd_ah -w ws://localhost:8001 +bun add @polkadot-labs/hdkd +``` + +To run the test: + +```bash +bun test ./index.ts +``` + +This project was created using `bun init` in bun v1.1.34. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime. diff --git a/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/index.ts b/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/index.ts new file mode 100644 index 000000000000..6203a385c3bd --- /dev/null +++ b/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/index.ts @@ -0,0 +1,124 @@ +import { test, expect } from "bun:test"; +import { + wnd_ah, + XcmV3Junctions, + XcmV3Junction, + XcmV3MultiassetFungibility, + XcmV4Instruction, + XcmV3WeightLimit, + XcmV3MultiassetMultiAssetFilter +} from "@polkadot-api/descriptors"; +import { Binary, Enum, createClient } from "polkadot-api"; +import { getWsProvider } from "polkadot-api/ws-provider/web"; +import { withPolkadotSdkCompat } from "polkadot-api/polkadot-sdk-compat"; +import { sr25519CreateDerive } from "@polkadot-labs/hdkd"; +import { + DEV_PHRASE, + entropyToMiniSecret, + mnemonicToEntropy, +} from "@polkadot-labs/hdkd-helpers"; +import { getPolkadotSigner } from "polkadot-api/signer"; + +const WESTEND_NETWORK = Uint8Array.from([225, 67, 242, 56, 3, 172, 80, 232, 246, 248, 230, 38, 149, 209, 206, 158, 78, 29, 104, 170, 54, 193, 205, 44, 253, 21, 52, 2, 19, 243, 66, 62]); +// TODO: find a way to extract keys below from yaml config. +const BOB_KEY = "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty"; +const ALICE_KEY = "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY"; + +// Create and initialize client +const client = createClient(withPolkadotSdkCompat(getWsProvider("ws://localhost:8000"))); +const AHApi = client.getTypedApi(wnd_ah); + +// Initialize HDKD key pairs and signers +const entropy = mnemonicToEntropy(DEV_PHRASE); +const miniSecret = entropyToMiniSecret(entropy); +const derive = sr25519CreateDerive(miniSecret); + +const hdkdKeyPairAlice = derive("//Alice"); +const hdkdKeyPairBob = derive("//Bob"); + +const aliceSigner = getPolkadotSigner( + hdkdKeyPairAlice.publicKey, + "Sr25519", + hdkdKeyPairAlice.sign, +); + +const bobSigner = getPolkadotSigner( + hdkdKeyPairBob.publicKey, + "Sr25519", + hdkdKeyPairBob.sign, +); + +// Utility function for balance fetching +async function getFreeBalance(api, accountKey) { + const balance = await api.query.System.Account.getValue(accountKey); + return balance.data.free; +} + +test("Set Asset Claimer, Trap Assets, Claim Trapped Assets", async () => { + const bobBalanceBefore = await getFreeBalance(AHApi, BOB_KEY); + + // Transaction 1: Alice sets asset claimer to Bob and sends a trap transaction + const trapTx = AHApi.tx.PolkadotXcm.execute({ + message: Enum("V5", [ + Enum("SetAssetClaimer", { + location: { + parents: 0, + interior: XcmV3Junctions.X1(XcmV3Junction.AccountId32({ + network: Enum("ByGenesis", Binary.fromBytes(WESTEND_NETWORK)), + id: Binary.fromBytes(hdkdKeyPairBob.publicKey), + })) + }, + }), + XcmV4Instruction.WithdrawAsset([{ + id: { parents: 1, interior: XcmV3Junctions.Here() }, + fun: XcmV3MultiassetFungibility.Fungible(1_000_000_000_000n), + }]), + XcmV4Instruction.ClearOrigin(), + ]), + max_weight: { ref_time: 100_000_000_000n, proof_size: 300_000n }, + }); + + const trapResult = await trapTx.signAndSubmit(aliceSigner); + expect(trapResult.ok).toBeTruthy(); + + // Transaction 2: Bob claims trapped assets. + const bobClaimTx = AHApi.tx.PolkadotXcm.execute({ + message: Enum("V4", [ + XcmV4Instruction.ClaimAsset({ + assets: [{ + id: { parents: 1, interior: XcmV3Junctions.Here() }, + fun: XcmV3MultiassetFungibility.Fungible(1_000_000_000_000n), + }], + ticket: { parents: 0, interior: XcmV3Junctions.Here() }, + }), + XcmV4Instruction.BuyExecution({ + fees: { + id: { parents: 1, interior: XcmV3Junctions.Here() }, + fun: XcmV3MultiassetFungibility.Fungible(1_000_000_000n), + }, + weight_limit: XcmV3WeightLimit.Unlimited(), + }), + XcmV4Instruction.DepositAsset({ + assets: XcmV3MultiassetMultiAssetFilter.Definite([{ + fun: XcmV3MultiassetFungibility.Fungible(1_000_000_000_000n), + id: { parents: 1, interior: XcmV3Junctions.Here() }, + }]), + beneficiary: { + parents: 0, + interior: XcmV3Junctions.X1(XcmV3Junction.AccountId32({ + network: undefined, + id: Binary.fromBytes(hdkdKeyPairBob.publicKey), + })) + } + }), + ]), + max_weight: { ref_time: 100_000_000_000n, proof_size: 300_000n }, + }); + + const claimResult = await bobClaimTx.signAndSubmit(bobSigner); + expect(claimResult.ok).toBeTruthy(); + + + const bobBalanceAfter = await getFreeBalance(AHApi, BOB_KEY); + expect(bobBalanceAfter > bobBalanceBefore).toBeTruthy(); +}); diff --git a/cumulus/parachains/integration-tests/chopsticks/wasms/README.md b/cumulus/parachains/integration-tests/chopsticks/wasms/README.md new file mode 100644 index 000000000000..80d7f273ef60 --- /dev/null +++ b/cumulus/parachains/integration-tests/chopsticks/wasms/README.md @@ -0,0 +1,9 @@ +This folder contains WASM BLOBs which are supposed to be used by chopstick tests. +To populate this folder with the required files you need to: +1. BUILD relevant runtimes: usually relay and parachain(s). +- `cargo build --release -p westend-runtime ` +- `cargo build --release -p asset-hub-westend-runtime ` +2. Copy compressed wasms from target folder into the current one: +- `WBUILD_PATH=../../../../../target/release/wbuild` +- `cp $WBUILD_PATH/asset-hub-westend-runtime/asset_hub_westend_runtime.compact.compressed.wasm .` +- `cp $WBUILD_PATH/westend-runtime/westend_runtime.compact.compressed.wasm .` From 33c3a092f0d89462ae65c87fc4d66bc1e39b7215 Mon Sep 17 00:00:00 2001 From: ndk Date: Thu, 21 Nov 2024 11:01:58 +0100 Subject: [PATCH 2/9] added bridge-hub config + improved readme --- .../configs/westend-bridge-hub-override.yaml | 32 +++++++++++++++++++ .../chopsticks/tests/v5-tests/README.md | 1 + 2 files changed, 33 insertions(+) create mode 100644 cumulus/parachains/integration-tests/chopsticks/configs/westend-bridge-hub-override.yaml diff --git a/cumulus/parachains/integration-tests/chopsticks/configs/westend-bridge-hub-override.yaml b/cumulus/parachains/integration-tests/chopsticks/configs/westend-bridge-hub-override.yaml new file mode 100644 index 000000000000..a71a3a8334a3 --- /dev/null +++ b/cumulus/parachains/integration-tests/chopsticks/configs/westend-bridge-hub-override.yaml @@ -0,0 +1,32 @@ +endpoint: wss://bridge-hub-polkadot-rpc.dwellir.com +mock-signature-host: true +block: ${env.WESTEND_BRIDGE_HUB_BLOCK_NUMBER} +db: ./db.sqlite +runtime-log-level: 5 +wasm-override: wasms/bridge_hub_westend_runtime.compact.compressed.wasm + +import-storage: + System: + Account: + - + - + - 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY # Alice + - providers: 1 + data: + free: 1000000000000000 + - + - + - 5Eg2fntQqFi3EvFWAf71G66Ecjjah26bmFzoANAeHFgj9Lia + - providers: 1 + data: + free: 1000000000000000 + - + - + - 5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty # Bob + - providers: 1 + data: + free: 1000000000000000 +# Assets: +# Account: +# - [[1984, 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY], { balance: 1000000000 }] +# - [[1984, 5Eg2fntQqFi3EvFWAf71G66Ecjjah26bmFzoANAeHFgj9Lia], { balance: 1000000000 }] diff --git a/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/README.md b/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/README.md index 7740f0b42cdf..7ebf5f27e568 100644 --- a/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/README.md +++ b/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/README.md @@ -13,6 +13,7 @@ To run the test: ```bash bun test ./index.ts +# note: the test may time out during the first run. Single retry usually helps. ``` This project was created using `bun init` in bun v1.1.34. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime. From eed6aaff99412d777cd58531a78a44defe62cfda Mon Sep 17 00:00:00 2001 From: ndk Date: Thu, 21 Nov 2024 11:31:18 +0100 Subject: [PATCH 3/9] added xcm v4 initiate teleport test --- .../chopsticks/tests/v5-tests/index.ts | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/index.ts b/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/index.ts index 6203a385c3bd..17111e698fc0 100644 --- a/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/index.ts +++ b/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/index.ts @@ -6,7 +6,8 @@ import { XcmV3MultiassetFungibility, XcmV4Instruction, XcmV3WeightLimit, - XcmV3MultiassetMultiAssetFilter + XcmV3MultiassetMultiAssetFilter, + XcmV4AssetAssetFilter } from "@polkadot-api/descriptors"; import { Binary, Enum, createClient } from "polkadot-api"; import { getWsProvider } from "polkadot-api/ws-provider/web"; @@ -122,3 +123,38 @@ test("Set Asset Claimer, Trap Assets, Claim Trapped Assets", async () => { const bobBalanceAfter = await getFreeBalance(AHApi, BOB_KEY); expect(bobBalanceAfter > bobBalanceBefore).toBeTruthy(); }); + +test("Initiate Teleport XCM v4", async () => { + const WndToAH = AHApi.tx.PolkadotXcm.execute({ + message: Enum("V4", [ + XcmV4Instruction.WithdrawAsset([{ + id: { parents: 1, interior: XcmV3Junctions.Here() }, + fun: XcmV3MultiassetFungibility.Fungible(7e12), + }]), + XcmV4Instruction.SetFeesMode({ + jit_withdraw: true, + }), + XcmV4Instruction.InitiateTeleport({ + assets: XcmV4AssetAssetFilter.Wild({type: "All", value: undefined}), + dest: { + parents: 1, + interior: XcmV3Junctions.Here(), + }, + xcm: [ + XcmV4Instruction.BuyExecution({ + fees: { + id: { parents: 0, interior: XcmV3Junctions.Here() }, + fun: XcmV3MultiassetFungibility.Fungible(500_000_000_000n), + }, + weight_limit: XcmV3WeightLimit.Unlimited(), + }), + ], + }), + ]), + max_weight: { ref_time: 55791635000n, proof_size: 364593n }, + }, + ); + + const r = await WndToAH.signAndSubmit(aliceSigner); + expect(r).toBeTruthy(); +}) From 799d65cf88a5bde2da905b34f76958ad417e333c Mon Sep 17 00:00:00 2001 From: ndk Date: Mon, 25 Nov 2024 14:11:52 +0100 Subject: [PATCH 4/9] implemented teleport in xcm v5 manner --- .../chopsticks/tests/v5-tests/index.ts | 78 ++++++++++++++++++- 1 file changed, 76 insertions(+), 2 deletions(-) diff --git a/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/index.ts b/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/index.ts index 17111e698fc0..114f9b9c4c6b 100644 --- a/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/index.ts +++ b/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/index.ts @@ -125,7 +125,7 @@ test("Set Asset Claimer, Trap Assets, Claim Trapped Assets", async () => { }); test("Initiate Teleport XCM v4", async () => { - const WndToAH = AHApi.tx.PolkadotXcm.execute({ + const ahToWnd = AHApi.tx.PolkadotXcm.execute({ message: Enum("V4", [ XcmV4Instruction.WithdrawAsset([{ id: { parents: 1, interior: XcmV3Junctions.Here() }, @@ -155,6 +155,80 @@ test("Initiate Teleport XCM v4", async () => { }, ); - const r = await WndToAH.signAndSubmit(aliceSigner); + const r = await ahToWnd.signAndSubmit(aliceSigner); + expect(r).toBeTruthy(); +}) + +test("Initiate Teleport XCM v5", async () => { + + const ahToWnd = AHApi.tx.PolkadotXcm.execute({ + message: Enum('V5', [ + XcmV4Instruction.WithdrawAsset([ + { + id: { parents: 1, interior: XcmV3Junctions.Here() }, + fun: XcmV3MultiassetFungibility.Fungible(5_000_000_000_000n), + }, + + ]), + Enum('PayFees', { + asset: { + id: { + parents: 1, + interior: XcmV3Junctions.Here(), + }, + fun: XcmV3MultiassetFungibility.Fungible(2_000_000_000_000n), + } + }), + Enum('InitiateTransfer', { + destination: { + parents: 1, + interior: XcmV3Junctions.Here(), + }, + // optional field. an example of usage: + // remote_fees: Enum('Teleport', { + // type: 'Wild', + // value: { + // type: 'All', + // value: undefined, + // }, + // }), + preserve_origin: false, + assets: [Enum('Teleport', { + type: 'Wild', + value: { + type: 'All', + value: undefined, + }, + })], + remote_xcm: [ + Enum('PayFees', { + asset: { + id: { + parents: 0, + interior: XcmV3Junctions.Here(), + }, + fun: XcmV3MultiassetFungibility.Fungible(1_000_000_000_000n), + } + }), + XcmV4Instruction.DepositAsset({ + assets: XcmV3MultiassetMultiAssetFilter.Definite([{ + fun: XcmV3MultiassetFungibility.Fungible(1_000_000_000_000n), + id: { parents: 0, interior: XcmV3Junctions.Here() }, + }]), + beneficiary: { + parents: 0, + interior: XcmV3Junctions.X1(XcmV3Junction.AccountId32({ + network: undefined, + id: Binary.fromBytes(hdkdKeyPairBob.publicKey), + })), + }, + }), + ], + }), + ]), + max_weight: { ref_time: 343_504_280_000n, proof_size: 1_670_016n }, + }, + ); + const r = await ahToWnd.signAndSubmit(aliceSigner); expect(r).toBeTruthy(); }) From 5e677de972cd2888c0cd46594e9dded3427b083e Mon Sep 17 00:00:00 2001 From: ndk Date: Mon, 25 Nov 2024 15:06:53 +0100 Subject: [PATCH 5/9] added message weighing before execution for XCM v5 --- .../chopsticks/tests/v5-tests/index.ts | 117 +++++++++--------- 1 file changed, 60 insertions(+), 57 deletions(-) diff --git a/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/index.ts b/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/index.ts index 114f9b9c4c6b..628432d1f5b4 100644 --- a/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/index.ts +++ b/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/index.ts @@ -160,73 +160,76 @@ test("Initiate Teleport XCM v4", async () => { }) test("Initiate Teleport XCM v5", async () => { + const msg = Enum('V5', [ + XcmV4Instruction.WithdrawAsset([ + { + id: { parents: 1, interior: XcmV3Junctions.Here() }, + fun: XcmV3MultiassetFungibility.Fungible(5_000_000_000_000n), + }, - const ahToWnd = AHApi.tx.PolkadotXcm.execute({ - message: Enum('V5', [ - XcmV4Instruction.WithdrawAsset([ - { - id: { parents: 1, interior: XcmV3Junctions.Here() }, - fun: XcmV3MultiassetFungibility.Fungible(5_000_000_000_000n), - }, - - ]), + ]), + Enum('PayFees', { + asset: { + id: { + parents: 1, + interior: XcmV3Junctions.Here(), + }, + fun: XcmV3MultiassetFungibility.Fungible(2_000_000_000_000n), + } + }), + Enum('InitiateTransfer', { + destination: { + parents: 1, + interior: XcmV3Junctions.Here(), + }, + // optional field. an example of usage: + // remote_fees: Enum('Teleport', { + // type: 'Wild', + // value: { + // type: 'All', + // value: undefined, + // }, + // }), + preserve_origin: false, + assets: [Enum('Teleport', { + type: 'Wild', + value: { + type: 'All', + value: undefined, + }, + })], + remote_xcm: [ Enum('PayFees', { asset: { id: { - parents: 1, + parents: 0, interior: XcmV3Junctions.Here(), }, - fun: XcmV3MultiassetFungibility.Fungible(2_000_000_000_000n), + fun: XcmV3MultiassetFungibility.Fungible(1_000_000_000_000n), } }), - Enum('InitiateTransfer', { - destination: { - parents: 1, - interior: XcmV3Junctions.Here(), + XcmV4Instruction.DepositAsset({ + assets: XcmV3MultiassetMultiAssetFilter.Definite([{ + fun: XcmV3MultiassetFungibility.Fungible(1_000_000_000_000n), + id: { parents: 0, interior: XcmV3Junctions.Here() }, + }]), + beneficiary: { + parents: 0, + interior: XcmV3Junctions.X1(XcmV3Junction.AccountId32({ + network: undefined, + id: Binary.fromBytes(hdkdKeyPairBob.publicKey), + })), }, - // optional field. an example of usage: - // remote_fees: Enum('Teleport', { - // type: 'Wild', - // value: { - // type: 'All', - // value: undefined, - // }, - // }), - preserve_origin: false, - assets: [Enum('Teleport', { - type: 'Wild', - value: { - type: 'All', - value: undefined, - }, - })], - remote_xcm: [ - Enum('PayFees', { - asset: { - id: { - parents: 0, - interior: XcmV3Junctions.Here(), - }, - fun: XcmV3MultiassetFungibility.Fungible(1_000_000_000_000n), - } - }), - XcmV4Instruction.DepositAsset({ - assets: XcmV3MultiassetMultiAssetFilter.Definite([{ - fun: XcmV3MultiassetFungibility.Fungible(1_000_000_000_000n), - id: { parents: 0, interior: XcmV3Junctions.Here() }, - }]), - beneficiary: { - parents: 0, - interior: XcmV3Junctions.X1(XcmV3Junction.AccountId32({ - network: undefined, - id: Binary.fromBytes(hdkdKeyPairBob.publicKey), - })), - }, - }), - ], }), - ]), - max_weight: { ref_time: 343_504_280_000n, proof_size: 1_670_016n }, + ], + }), + ]); + + const weight = await AHApi.apis.XcmPaymentApi.query_xcm_weight(msg); + + const ahToWnd = AHApi.tx.PolkadotXcm.execute({ + message: msg, + max_weight: { ref_time: weight.value.ref_time, proof_size: weight.value.proof_size }, }, ); const r = await ahToWnd.signAndSubmit(aliceSigner); From 443fc85fc0d59903a64657d2866956613f66a34e Mon Sep 17 00:00:00 2001 From: ndk Date: Mon, 25 Nov 2024 15:41:32 +0100 Subject: [PATCH 6/9] added message weighing before execution for XCM v4 as well --- .../chopsticks/tests/v5-tests/index.ts | 154 +++++++++--------- 1 file changed, 81 insertions(+), 73 deletions(-) diff --git a/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/index.ts b/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/index.ts index 628432d1f5b4..0762659b5ee4 100644 --- a/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/index.ts +++ b/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/index.ts @@ -58,62 +58,68 @@ async function getFreeBalance(api, accountKey) { test("Set Asset Claimer, Trap Assets, Claim Trapped Assets", async () => { const bobBalanceBefore = await getFreeBalance(AHApi, BOB_KEY); + const alice_msg = Enum("V5", [ + Enum("SetAssetClaimer", { + location: { + parents: 0, + interior: XcmV3Junctions.X1(XcmV3Junction.AccountId32({ + network: Enum("ByGenesis", Binary.fromBytes(WESTEND_NETWORK)), + id: Binary.fromBytes(hdkdKeyPairBob.publicKey), + })) + }, + }), + XcmV4Instruction.WithdrawAsset([{ + id: { parents: 1, interior: XcmV3Junctions.Here() }, + fun: XcmV3MultiassetFungibility.Fungible(1_000_000_000_000n), + }]), + XcmV4Instruction.ClearOrigin(), + ]); + const alice_weight = await AHApi.apis.XcmPaymentApi.query_xcm_weight(alice_msg); + // Transaction 1: Alice sets asset claimer to Bob and sends a trap transaction const trapTx = AHApi.tx.PolkadotXcm.execute({ - message: Enum("V5", [ - Enum("SetAssetClaimer", { - location: { - parents: 0, - interior: XcmV3Junctions.X1(XcmV3Junction.AccountId32({ - network: Enum("ByGenesis", Binary.fromBytes(WESTEND_NETWORK)), - id: Binary.fromBytes(hdkdKeyPairBob.publicKey), - })) - }, - }), - XcmV4Instruction.WithdrawAsset([{ - id: { parents: 1, interior: XcmV3Junctions.Here() }, - fun: XcmV3MultiassetFungibility.Fungible(1_000_000_000_000n), - }]), - XcmV4Instruction.ClearOrigin(), - ]), - max_weight: { ref_time: 100_000_000_000n, proof_size: 300_000n }, + message: alice_msg, + max_weight: { ref_time: alice_weight.value.ref_time, proof_size: alice_weight.value.proof_size }, }); const trapResult = await trapTx.signAndSubmit(aliceSigner); expect(trapResult.ok).toBeTruthy(); + const bob_msg = Enum("V4", [ + XcmV4Instruction.ClaimAsset({ + assets: [{ + id: { parents: 1, interior: XcmV3Junctions.Here() }, + fun: XcmV3MultiassetFungibility.Fungible(1_000_000_000_000n), + }], + ticket: { parents: 0, interior: XcmV3Junctions.Here() }, + }), + XcmV4Instruction.BuyExecution({ + fees: { + id: { parents: 1, interior: XcmV3Junctions.Here() }, + fun: XcmV3MultiassetFungibility.Fungible(1_000_000_000n), + }, + weight_limit: XcmV3WeightLimit.Unlimited(), + }), + XcmV4Instruction.DepositAsset({ + assets: XcmV3MultiassetMultiAssetFilter.Definite([{ + fun: XcmV3MultiassetFungibility.Fungible(1_000_000_000_000n), + id: { parents: 1, interior: XcmV3Junctions.Here() }, + }]), + beneficiary: { + parents: 0, + interior: XcmV3Junctions.X1(XcmV3Junction.AccountId32({ + network: undefined, + id: Binary.fromBytes(hdkdKeyPairBob.publicKey), + })) + } + }), + ]); + const bob_weight = await AHApi.apis.XcmPaymentApi.query_xcm_weight(bob_msg); + // Transaction 2: Bob claims trapped assets. const bobClaimTx = AHApi.tx.PolkadotXcm.execute({ - message: Enum("V4", [ - XcmV4Instruction.ClaimAsset({ - assets: [{ - id: { parents: 1, interior: XcmV3Junctions.Here() }, - fun: XcmV3MultiassetFungibility.Fungible(1_000_000_000_000n), - }], - ticket: { parents: 0, interior: XcmV3Junctions.Here() }, - }), - XcmV4Instruction.BuyExecution({ - fees: { - id: { parents: 1, interior: XcmV3Junctions.Here() }, - fun: XcmV3MultiassetFungibility.Fungible(1_000_000_000n), - }, - weight_limit: XcmV3WeightLimit.Unlimited(), - }), - XcmV4Instruction.DepositAsset({ - assets: XcmV3MultiassetMultiAssetFilter.Definite([{ - fun: XcmV3MultiassetFungibility.Fungible(1_000_000_000_000n), - id: { parents: 1, interior: XcmV3Junctions.Here() }, - }]), - beneficiary: { - parents: 0, - interior: XcmV3Junctions.X1(XcmV3Junction.AccountId32({ - network: undefined, - id: Binary.fromBytes(hdkdKeyPairBob.publicKey), - })) - } - }), - ]), - max_weight: { ref_time: 100_000_000_000n, proof_size: 300_000n }, + message: bob_msg, + max_weight: { ref_time: bob_weight.value.ref_time, proof_size: bob_weight.value.proof_size }, }); const claimResult = await bobClaimTx.signAndSubmit(bobSigner); @@ -125,33 +131,36 @@ test("Set Asset Claimer, Trap Assets, Claim Trapped Assets", async () => { }); test("Initiate Teleport XCM v4", async () => { - const ahToWnd = AHApi.tx.PolkadotXcm.execute({ - message: Enum("V4", [ - XcmV4Instruction.WithdrawAsset([{ - id: { parents: 1, interior: XcmV3Junctions.Here() }, - fun: XcmV3MultiassetFungibility.Fungible(7e12), - }]), - XcmV4Instruction.SetFeesMode({ - jit_withdraw: true, - }), - XcmV4Instruction.InitiateTeleport({ - assets: XcmV4AssetAssetFilter.Wild({type: "All", value: undefined}), - dest: { - parents: 1, - interior: XcmV3Junctions.Here(), + const msg = Enum("V4", [ + XcmV4Instruction.WithdrawAsset([{ + id: { parents: 1, interior: XcmV3Junctions.Here() }, + fun: XcmV3MultiassetFungibility.Fungible(7e12), + }]), + XcmV4Instruction.SetFeesMode({ + jit_withdraw: true, + }), + XcmV4Instruction.InitiateTeleport({ + assets: XcmV4AssetAssetFilter.Wild({type: "All", value: undefined}), + dest: { + parents: 1, + interior: XcmV3Junctions.Here(), + }, + xcm: [ + XcmV4Instruction.BuyExecution({ + fees: { + id: { parents: 0, interior: XcmV3Junctions.Here() }, + fun: XcmV3MultiassetFungibility.Fungible(500_000_000_000n), }, - xcm: [ - XcmV4Instruction.BuyExecution({ - fees: { - id: { parents: 0, interior: XcmV3Junctions.Here() }, - fun: XcmV3MultiassetFungibility.Fungible(500_000_000_000n), - }, - weight_limit: XcmV3WeightLimit.Unlimited(), - }), - ], + weight_limit: XcmV3WeightLimit.Unlimited(), }), - ]), - max_weight: { ref_time: 55791635000n, proof_size: 364593n }, + ], + }), + ]); + const weight = await AHApi.apis.XcmPaymentApi.query_xcm_weight(msg); + + const ahToWnd = AHApi.tx.PolkadotXcm.execute({ + message: msg, + max_weight: { ref_time: weight.value.ref_time, proof_size: weight.value.proof_size }, }, ); @@ -224,7 +233,6 @@ test("Initiate Teleport XCM v5", async () => { ], }), ]); - const weight = await AHApi.apis.XcmPaymentApi.query_xcm_weight(msg); const ahToWnd = AHApi.tx.PolkadotXcm.execute({ From 274debbaaf9924e38defd7dd1c4793548d53b555 Mon Sep 17 00:00:00 2001 From: ndk Date: Tue, 26 Nov 2024 16:15:43 +0100 Subject: [PATCH 7/9] WIP: query_xcm_weight_to_asset_fee estimates wrongly --- .../chopsticks/tests/v5-tests/index.ts | 79 ++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/index.ts b/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/index.ts index 0762659b5ee4..bd19a3817d20 100644 --- a/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/index.ts +++ b/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/index.ts @@ -169,6 +169,83 @@ test("Initiate Teleport XCM v4", async () => { }) test("Initiate Teleport XCM v5", async () => { + const xcm_origin_msg = Enum('V5', [ + XcmV4Instruction.WithdrawAsset([ + { + id: { parents: 1, interior: XcmV3Junctions.Here() }, + fun: XcmV3MultiassetFungibility.Fungible(5_000_000_000_000n), + }, + + ]), + + Enum('PayFees', { + asset: { + id: { + parents: 1, + interior: XcmV3Junctions.Here(), + }, + fun: XcmV3MultiassetFungibility.Fungible(1_000_000_000_000n), + } + }), + Enum('InitiateTransfer', { + destination: { + parents: 1, + interior: XcmV3Junctions.Here(), + }, + // optional field. an example of usage: + // remote_fees: Enum('Teleport', { + // type: 'Wild', + // value: { + // type: 'All', + // value: undefined, + // }, + // }), + preserve_origin: false, + assets: [Enum('Teleport', { + type: 'Wild', + value: { + type: 'All', + value: undefined, + }, + })], + remote_xcm: [ + Enum('PayFees', { + asset: { + id: { + parents: 0, + interior: XcmV3Junctions.Here(), + }, + fun: XcmV3MultiassetFungibility.Fungible(1_000_000_000_000n), + } + }), + XcmV4Instruction.DepositAsset({ + assets: XcmV3MultiassetMultiAssetFilter.Definite([{ + fun: XcmV3MultiassetFungibility.Fungible(1_000_000_000_000n), + id: { parents: 0, interior: XcmV3Junctions.Here() }, + }]), + beneficiary: { + parents: 0, + interior: XcmV3Junctions.X1(XcmV3Junction.AccountId32({ + network: undefined, + id: Binary.fromBytes(hdkdKeyPairBob.publicKey), + })), + }, + }), + ], + }), + ]); + + const xcm_origin_weight = await AHApi.apis.XcmPaymentApi.query_xcm_weight(xcm_origin_msg); + const weight_to_asset_fee = await AHApi.apis.XcmPaymentApi.query_weight_to_asset_fee( + { ref_time: xcm_origin_weight.value.ref_time, proof_size: xcm_origin_weight.value.proof_size }, + Enum('V5', { + parents: 1, + interior: XcmV3Junctions.Here(), + }), + ); + + + const msg = Enum('V5', [ XcmV4Instruction.WithdrawAsset([ { @@ -183,7 +260,7 @@ test("Initiate Teleport XCM v5", async () => { parents: 1, interior: XcmV3Junctions.Here(), }, - fun: XcmV3MultiassetFungibility.Fungible(2_000_000_000_000n), + fun: XcmV3MultiassetFungibility.Fungible(weight_to_asset_fee.value), } }), Enum('InitiateTransfer', { From 6d11b524309067eb91b14ce183166a8e2fef383c Mon Sep 17 00:00:00 2001 From: ndk Date: Wed, 27 Nov 2024 14:34:57 +0100 Subject: [PATCH 8/9] added initiate teleport with remote fees program --- .../chopsticks/tests/v5-tests/index.ts | 67 +++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/index.ts b/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/index.ts index bd19a3817d20..aa64269786de 100644 --- a/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/index.ts +++ b/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/index.ts @@ -320,3 +320,70 @@ test("Initiate Teleport XCM v5", async () => { const r = await ahToWnd.signAndSubmit(aliceSigner); expect(r).toBeTruthy(); }) + +test("Initiate Teleport with remote fees", async () => { + const msg = Enum('V5', [ + XcmV4Instruction.WithdrawAsset([ + { + id: { parents: 1, interior: XcmV3Junctions.Here() }, + fun: XcmV3MultiassetFungibility.Fungible(5_000_000_000_000n), + }, + + ]), + Enum('PayFees', { + asset: { + id: { + parents: 1, + interior: XcmV3Junctions.Here(), + }, + fun: XcmV3MultiassetFungibility.Fungible(2_000_000_000_000n), + } + }), + Enum('InitiateTransfer', { + destination: { + parents: 1, + interior: XcmV3Junctions.Here(), + }, + // optional field. an example of usage: + remote_fees: Enum('Teleport', { + type: 'Wild', + value: { + type: 'All', + value: undefined, + }, + }), + preserve_origin: false, + assets: [Enum('Teleport', { + type: 'Wild', + value: { + type: 'All', + value: undefined, + }, + })], + remote_xcm: [ + XcmV4Instruction.DepositAsset({ + assets: XcmV3MultiassetMultiAssetFilter.Definite([{ + fun: XcmV3MultiassetFungibility.Fungible(1_000_000_000_000n), + id: { parents: 0, interior: XcmV3Junctions.Here() }, + }]), + beneficiary: { + parents: 0, + interior: XcmV3Junctions.X1(XcmV3Junction.AccountId32({ + network: undefined, + id: Binary.fromBytes(hdkdKeyPairBob.publicKey), + })), + }, + }), + ], + }), + ]); + const weight = await AHApi.apis.XcmPaymentApi.query_xcm_weight(msg); + + const ahToWnd = AHApi.tx.PolkadotXcm.execute({ + message: msg, + max_weight: { ref_time: weight.value.ref_time, proof_size: weight.value.proof_size }, + }, + ); + const r = await ahToWnd.signAndSubmit(aliceSigner); + expect(r).toBeTruthy(); +}) From 2ddb163a1dc7e5247463dc49ed7e01b936b53ab7 Mon Sep 17 00:00:00 2001 From: ndk Date: Wed, 27 Nov 2024 14:53:00 +0100 Subject: [PATCH 9/9] used wildcard instead of concrete fungible values in DepositAsset instruction --- .../integration-tests/chopsticks/tests/v5-tests/index.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/index.ts b/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/index.ts index aa64269786de..933e7d453e77 100644 --- a/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/index.ts +++ b/cumulus/parachains/integration-tests/chopsticks/tests/v5-tests/index.ts @@ -362,10 +362,10 @@ test("Initiate Teleport with remote fees", async () => { })], remote_xcm: [ XcmV4Instruction.DepositAsset({ - assets: XcmV3MultiassetMultiAssetFilter.Definite([{ - fun: XcmV3MultiassetFungibility.Fungible(1_000_000_000_000n), - id: { parents: 0, interior: XcmV3Junctions.Here() }, - }]), + assets: XcmV3MultiassetMultiAssetFilter.Wild({ + type: 'All', + value: undefined, + }), beneficiary: { parents: 0, interior: XcmV3Junctions.X1(XcmV3Junction.AccountId32({