From 5a4644f02d75cb2c1c0f398f947dfcb3386b2693 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Thu, 22 Aug 2024 15:31:18 +0200 Subject: [PATCH] add usdc xcm transfer test --- integration-tests/README.md | 6 + .../configs/polkadot-asset-hub.yml | 20 ++ integration-tests/configs/polkadot.yml | 20 ++ integration-tests/configs/zeitgeist.yml | 26 ++- integration-tests/moonwall.config.json | 44 ++++ .../test-chopsticks-xcm.ts | 192 ++++++++++++++++++ 6 files changed, 307 insertions(+), 1 deletion(-) create mode 100644 integration-tests/configs/polkadot-asset-hub.yml create mode 100644 integration-tests/configs/polkadot.yml create mode 100644 integration-tests/tests/xcm-zeitgeist-chopsticks/test-chopsticks-xcm.ts diff --git a/integration-tests/README.md b/integration-tests/README.md index 40077fd19..4a83b9298 100644 --- a/integration-tests/README.md +++ b/integration-tests/README.md @@ -103,3 +103,9 @@ pnpm exec moonwall test chopsticks_zeitgeist_upgrade ```bash pnpm exec moonwall test chopsticks_battery_station_upgrade ``` + +#### Test XCM functionality on the live main-net fork using chopsticks: + +```bash +pnpm exec moonwall test chopsticks_zeitgeist_xcm +``` \ No newline at end of file diff --git a/integration-tests/configs/polkadot-asset-hub.yml b/integration-tests/configs/polkadot-asset-hub.yml new file mode 100644 index 000000000..57086db72 --- /dev/null +++ b/integration-tests/configs/polkadot-asset-hub.yml @@ -0,0 +1,20 @@ +endpoint: wss://polkadot-asset-hub-rpc.polkadot.io +mock-signature-host: true +block: ${env.POLKADOT_ASSET_HUB_BLOCK_NUMBER} +db: ./db.sqlite + +import-storage: + System: + Account: + - + - + - 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY + - providers: 1 + data: + free: 1000000000000000 + Assets: + Account: + - [[1984, 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY], { balance: 1000000000 }] + - [[21, 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY], { balance: 1000000000 }] + - [[1337, 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY], { balance: 1000000000 }] + Asset: [[[21], { supply: 1000000000 }]] \ No newline at end of file diff --git a/integration-tests/configs/polkadot.yml b/integration-tests/configs/polkadot.yml new file mode 100644 index 000000000..7fea0459d --- /dev/null +++ b/integration-tests/configs/polkadot.yml @@ -0,0 +1,20 @@ +endpoint: + - wss://rpc.ibp.network/polkadot + - wss://polkadot-rpc.dwellir.com +mock-signature-host: true +block: ${env.POLKADOT_BLOCK_NUMBER} +db: ./db.sqlite +runtime-log-level: 5 +# wasm-override: polkadot_runtime.compact.compressed.wasm + +import-storage: + System: + Account: + - + - + - 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY + - providers: 1 + data: + free: '10000000000000000000' + ParasDisputes: + $removePrefix: ['disputes'] # those can makes block building super slow \ No newline at end of file diff --git a/integration-tests/configs/zeitgeist.yml b/integration-tests/configs/zeitgeist.yml index fd886a6e6..7350ddd60 100644 --- a/integration-tests/configs/zeitgeist.yml +++ b/integration-tests/configs/zeitgeist.yml @@ -1,4 +1,5 @@ -endpoint: wss://main.rpc.zeitgeist.pm/ws +# endpoint: wss://main.rpc.zeitgeist.pm/ws +endpoint: wss://zeitgeist.api.onfinality.io/public-ws mock-signature-host: true db: ./tmp/ztg_db_mba.sqlite # wasm-override: zeitgeist-runtime.compact.compressed.wasm @@ -25,3 +26,26 @@ import-storage: AuthorFilter: EligibleRatio: 100 EligibleCount: 100 + # Complex working example of storage import + # AssetRegistry: + # Metadata: + # - + # - + # - ForeignAsset: 10 + # - decimals: 6 + # name: USD Coin + # symbol: USDC + # existentialDeposit: "10000" + # location: + # V3: + # parents: 1 + # interior: + # X3: [ + # Parachain: 1000, + # PalletInstance: 50, + # GeneralIndex: 1337, + # ] + # additional: + # xcm: + # feeFactor: null + # allowAsBaseAsset: false \ No newline at end of file diff --git a/integration-tests/moonwall.config.json b/integration-tests/moonwall.config.json index 55da73649..f87b5c4c2 100644 --- a/integration-tests/moonwall.config.json +++ b/integration-tests/moonwall.config.json @@ -36,6 +36,50 @@ } ] }, + { + "name": "chopsticks_zeitgeist_xcm", + "testFileDir": ["tests/xcm-zeitgeist-chopsticks"], + "runScripts": ["build-node.sh"], + "foundation": { + "type": "chopsticks", + "launchSpec": [ + { + "name": "ZeitgeistDB", + "type": "parachain", + "configPath": "./configs/zeitgeist.yml" + }, + { + "name": "AssetHubDB", + "type": "parachain", + "configPath": "./configs/polkadot-asset-hub.yml" + }, + { + "name": "PolkadotDB", + "type": "relaychain", + "configPath": "polkadot" + } + ] + }, + "envVars": ["LOG_LEVEL=debug", "VERBOSE_LOG=true"], + "buildBlockMode": "manual", + "connections": [ + { + "name": "ZeitgeistPara", + "type": "polkadotJs", + "endpoints": ["ws://127.0.0.1:8000"] + }, + { + "name": "AssetHubPara", + "type": "polkadotJs", + "endpoints": ["ws://127.0.0.1:8001"] + }, + { + "name": "PolkadotRelay", + "type": "polkadotJs", + "endpoints": ["ws://127.0.0.1:8002"] + } + ] + }, { "name": "chopsticks_zeitgeist_upgrade", "testFileDir": ["tests/rt-upgrade-zeitgeist-chopsticks"], diff --git a/integration-tests/tests/xcm-zeitgeist-chopsticks/test-chopsticks-xcm.ts b/integration-tests/tests/xcm-zeitgeist-chopsticks/test-chopsticks-xcm.ts new file mode 100644 index 000000000..34f8efe3d --- /dev/null +++ b/integration-tests/tests/xcm-zeitgeist-chopsticks/test-chopsticks-xcm.ts @@ -0,0 +1,192 @@ +// Copyright (C) Moondance Labs Ltd. +// Copyright 2022-2024 Forecasting Technologies LTD. +// +// This file is part of Zeitgeist. +// +// Zeitgeist is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the +// Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// Zeitgeist is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Zeitgeist. If not, see . + +import { + beforeAll, + describeSuite, + expect, +} from "@moonwall/cli"; +import { KeyringPair } from "@moonwall/util"; +import { ApiPromise, Keyring } from "@polkadot/api"; +import { RuntimeVersion } from "@polkadot/types/interfaces"; +import { AccountInfo, AccountData } from "@polkadot/types/interfaces"; +import WebSocket from "ws"; + +const ZEITGEIST_PARA_ID = 2092; +describeSuite({ + id: "XCM01", + title: "Chopsticks Zeitgeist XCM Tests", + foundationMethods: "zombie", + testCases: function ({ it, context, log }) { + let zeitgeistParaApi: ApiPromise; + let relayApi: ApiPromise; + let assetHubParaApi: ApiPromise; + let alice: KeyringPair; + + beforeAll(async () => { + const keyring = new Keyring({ type: "sr25519" }); + alice = keyring.addFromUri("//Alice", { name: "Alice default" }); + zeitgeistParaApi = context.polkadotJs("ZeitgeistPara"); + relayApi = context.polkadotJs("PolkadotRelay"); + assetHubParaApi = context.polkadotJs("AssetHubPara"); + + const paraZeitgeistNetwork = ( + zeitgeistParaApi.consts.system.version as unknown as RuntimeVersion + ).specName.toString(); + expect(paraZeitgeistNetwork, "Para API incorrect").to.contain( + "zeitgeist" + ); + + const relayNetwork = ( + relayApi.consts.system.version as unknown as RuntimeVersion + ).specName.toString(); + expect(relayNetwork, "Relay API incorrect").to.contain("polkadot"); + + const paraHydraDXNetwork = ( + assetHubParaApi.consts.system.version as unknown as RuntimeVersion + ).specName.toString(); + expect(paraHydraDXNetwork, "Para API incorrect").to.contain("hydradx"); + }, 120000); + + it({ + id: "T01", + title: "Send USDC from AssetHub to Zeitgeist", + test: async function () { + const assetHubBalanceBefore = ( + (await assetHubParaApi.query.system.account( + alice.address + )) as unknown as AccountInfo + ).data.free.toBigInt(); + const usdcForeignAsset = { ForeignAsset: 4 }; + const zeitgeistUSDCBalanceBefore = ( + (await zeitgeistParaApi.query.tokens.accounts( + alice.address, + usdcForeignAsset + )) as AccountData + ).free.toBigInt(); + + const amount: bigint = BigInt("100000"); + const aliceAccountId = assetHubParaApi + .createType("AccountId32", alice.address) + .toHex(); + const destination = { + V3: { + parents: 1, + interior: { + X1: [{ Parachain: ZEITGEIST_PARA_ID }], + }, + }, + }; + const beneficiary = { + V3: { + parents: 1, + interior: { + X1: [{ AccountId32: aliceAccountId }], + }, + }, + }; + const assets = { + V3: [ + { + id: { + Concrete: { + parents: 0, + interior: { + X2: [{ PalletInstance: 50 }, { GeneralIndex: 1337 }], + }, + }, + }, + fun: { Fungible: amount }, + }, + ], + }; + const feeAssetItem = 0; + + const xcmTransfer = + assetHubParaApi.tx.polkadotXcm.reserveTransferAssets( + destination, + beneficiary, + assets, + feeAssetItem + ); + + const { partialFee, weight } = await xcmTransfer.paymentInfo( + alice.address + ); + const transferFee: bigint = partialFee.toBigInt(); + + await xcmTransfer.signAndSend(alice, { nonce: -1 }); + + // RpcError: 1: Block 0x... not found, if using this `await context.createBlock({ providerName: "ReceiverPara", count: 1 });` + // Reported Bug here https://github.com/Moonsong-Labs/moonwall/issues/343 + + // use a workaround for creating a block + const newBlockPromise = new Promise((resolve, reject) => { + // ws://127.0.0.1:8001 represents the AssetHub parachain + const ws = new WebSocket("ws://127.0.0.1:8001"); + + ws.on("open", function open() { + const message = { + jsonrpc: "2.0", + id: 1, + method: "dev_newBlock", + params: [{ count: 1 }], + }; + + ws.send(JSON.stringify(message)); + }); + + ws.on("message", async function message(data) { + const dataObj = JSON.parse(data.toString()); + log("Received message:", dataObj); + resolve(dataObj.result); + }); + + ws.on("error", function error(error) { + log("Error:", error.toString()); + reject(error); + }); + }); + + await newBlockPromise; + + const assetHubBalanceAfter = ( + (await assetHubParaApi.query.system.account( + alice.address + )) as unknown as AccountInfo + ).data.free.toBigInt(); + expect( + assetHubBalanceBefore - assetHubBalanceAfter, + "Unexpected balance diff" + ).toBe(amount + transferFee); + + await context.createBlock({ + providerName: "ZeitgeistPara", + count: 1, + allowFailures: false, + }); + const zeitgeistUSDCBalanceAfter: bigint = ( + (await zeitgeistParaApi.query.tokens.accounts( + alice.address, + usdcForeignAsset + )) as AccountData + ).free.toBigInt(); + }, + }); + }, +});