From b7082d1a9d25f8173cdebabceb691f082e120a27 Mon Sep 17 00:00:00 2001 From: Roman Useinov Date: Fri, 19 May 2023 19:53:41 +0200 Subject: [PATCH] [Feature] XCM-Emulator (#2447) * [Feature] XCM-Emulator * ".git/.scripts/commands/fmt/fmt.sh" * rename * readme * more rename * rename directory * implement AssetTransactor * Update xcm/xcm-emulator/README.md Co-authored-by: Muharem Ismailov * address review comments (#2502) * Update xcm/xcm-emulator/example/src/lib.rs Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update xcm/xcm-emulator/README.md * Use 2d weights. * Point out nearer the failure why it should fail * Move test-runtime to under examples * Walk through how to use it * proof needs to be non-zero * Apply suggestions from code review * Update xcm/xcm-emulator/README.md Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Improve xcm emulator (#2593) * folder restructutre * common created * make macros repetitions * messenger traits for relay and para * default Messenger impls * messenger traits refactor * declared two networks * init network approach works * queues use HashMap but relay block number * init and reset refactor * messengers trait name changed * relay block number suboptimal * fix reset hashmap keys * genesis added * test ext added for parachains * genesis added relay chains * genesis to storage * new_ext replaced by on_init * new relay block number approach * ext_wrapper added * added types to Parachain trait * relay chain with types * restructure * para_ids working * replace para_id getter * replace para_id getter 2 * tests restructure + common variables * added sovereign and balances helpers * more helpers + tess pass * expected events macro added * added events trait method * expect_events macro improve * expect_events macro done * network traits added * reserve_transfer test added * para & relay macro inputs redefined * added collectives & BH paras * test restructure * statemine removed * nitpick * rename test folder + events logs * clean * weight threshold helper * update readme * remove cumulus-test-service dependancy * fmt * comment docs * update e2e tests to xcm v3 * clippy + runtime-benchmark + clean docs --------- Co-authored-by: command-bot <> Co-authored-by: Muharem Ismailov Co-authored-by: Squirrel Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> Co-authored-by: Ignacio Palacios --- Cargo.lock | 108 ++ Cargo.toml | 4 +- .../assets/statemine/0_xcm}/0_init.yml | 72 +- .../assets/statemine/0_xcm}/1_dmp.yml | 77 +- .../assets/statemine/0_xcm}/2_ump.yml | 81 +- .../statemine/0_xcm/3_hrmp-open-channels.yml | 134 +++ .../e2e/assets/statemine/0_xcm/4_hrmp.yml | 403 ++++++++ .../e2e/assets/statemine/config.toml | 70 ++ .../assets/statemint/0_xcm}/0_init.yml | 78 +- .../assets/statemint/0_xcm}/1_dmp.yml | 77 +- .../assets/statemint/0_xcm}/2_ump.yml | 80 +- .../statemint/0_xcm/3_hrmp-open-channels.yml | 132 +++ .../e2e/assets/statemint/0_xcm/4_hrmp.yml | 401 ++++++++ .../e2e/assets/statemint/config.toml | 71 ++ .../collectives_polkadot}/0_xcm/0_init.yml | 4 +- .../0_xcm/1_teleport.yml | 26 +- .../collectives_polkadot}/0_xcm/2_reserve.yml | 10 +- .../1_alliance/0_join_alliance_fails.yml | 0 .../1_alliance/1_init_alliance.yml | 19 +- .../1_alliance/2_join_alliance_fails.yml | 0 .../1_alliance/3_kick_member.yml | 4 +- .../collectives_polkadot}/config.toml | 8 + .../emulated/assets/statemint/Cargo.toml | 36 + .../emulated/assets/statemint/src/lib.rs | 33 + .../assets/statemint/src/tests/mod.rs | 3 + .../statemint/src/tests/reserve_transfer.rs | 63 ++ .../assets/statemint/src/tests/teleport.rs | 60 ++ .../assets/statemint/src/tests/transact.rs | 58 ++ .../emulated/common/Cargo.toml | 54 + .../emulated/common/src/constants.rs | 672 +++++++++++++ .../emulated/common/src/lib.rs | 253 +++++ .../integration-tests/statemine/config.toml | 49 - .../statemine/xcm/3_hrmp-open-channels.yml | 408 -------- .../statemine/xcm/4_hrmp.yml | 356 ------- .../integration-tests/statemint/config.toml | 49 - .../statemint/xcm/3_hrmp-open-channels.yml | 402 -------- .../statemint/xcm/4_hrmp.yml | 356 ------- xcm/xcm-emulator/Cargo.toml | 37 + xcm/xcm-emulator/README.md | 20 + xcm/xcm-emulator/src/lib.rs | 939 ++++++++++++++++++ 40 files changed, 3848 insertions(+), 1859 deletions(-) rename parachains/integration-tests/{statemint/xcm => e2e/assets/statemine/0_xcm}/0_init.yml (67%) rename parachains/integration-tests/{statemint/xcm => e2e/assets/statemine/0_xcm}/1_dmp.yml (78%) rename parachains/integration-tests/{statemine/xcm => e2e/assets/statemine/0_xcm}/2_ump.yml (71%) create mode 100644 parachains/integration-tests/e2e/assets/statemine/0_xcm/3_hrmp-open-channels.yml create mode 100644 parachains/integration-tests/e2e/assets/statemine/0_xcm/4_hrmp.yml create mode 100644 parachains/integration-tests/e2e/assets/statemine/config.toml rename parachains/integration-tests/{statemine/xcm => e2e/assets/statemint/0_xcm}/0_init.yml (66%) rename parachains/integration-tests/{statemine/xcm => e2e/assets/statemint/0_xcm}/1_dmp.yml (79%) rename parachains/integration-tests/{statemint/xcm => e2e/assets/statemint/0_xcm}/2_ump.yml (72%) create mode 100644 parachains/integration-tests/e2e/assets/statemint/0_xcm/3_hrmp-open-channels.yml create mode 100644 parachains/integration-tests/e2e/assets/statemint/0_xcm/4_hrmp.yml create mode 100644 parachains/integration-tests/e2e/assets/statemint/config.toml rename parachains/integration-tests/{collectives => e2e/collectives/collectives_polkadot}/0_xcm/0_init.yml (97%) rename parachains/integration-tests/{collectives => e2e/collectives/collectives_polkadot}/0_xcm/1_teleport.yml (96%) rename parachains/integration-tests/{collectives => e2e/collectives/collectives_polkadot}/0_xcm/2_reserve.yml (94%) rename parachains/integration-tests/{collectives => e2e/collectives/collectives_polkadot}/1_alliance/0_join_alliance_fails.yml (100%) rename parachains/integration-tests/{collectives => e2e/collectives/collectives_polkadot}/1_alliance/1_init_alliance.yml (96%) rename parachains/integration-tests/{collectives => e2e/collectives/collectives_polkadot}/1_alliance/2_join_alliance_fails.yml (100%) rename parachains/integration-tests/{collectives => e2e/collectives/collectives_polkadot}/1_alliance/3_kick_member.yml (98%) rename parachains/integration-tests/{collectives => e2e/collectives/collectives_polkadot}/config.toml (84%) create mode 100644 parachains/integration-tests/emulated/assets/statemint/Cargo.toml create mode 100644 parachains/integration-tests/emulated/assets/statemint/src/lib.rs create mode 100644 parachains/integration-tests/emulated/assets/statemint/src/tests/mod.rs create mode 100644 parachains/integration-tests/emulated/assets/statemint/src/tests/reserve_transfer.rs create mode 100644 parachains/integration-tests/emulated/assets/statemint/src/tests/teleport.rs create mode 100644 parachains/integration-tests/emulated/assets/statemint/src/tests/transact.rs create mode 100644 parachains/integration-tests/emulated/common/Cargo.toml create mode 100644 parachains/integration-tests/emulated/common/src/constants.rs create mode 100644 parachains/integration-tests/emulated/common/src/lib.rs delete mode 100644 parachains/integration-tests/statemine/config.toml delete mode 100644 parachains/integration-tests/statemine/xcm/3_hrmp-open-channels.yml delete mode 100644 parachains/integration-tests/statemine/xcm/4_hrmp.yml delete mode 100644 parachains/integration-tests/statemint/config.toml delete mode 100644 parachains/integration-tests/statemint/xcm/3_hrmp-open-channels.yml delete mode 100644 parachains/integration-tests/statemint/xcm/4_hrmp.yml create mode 100644 xcm/xcm-emulator/Cargo.toml create mode 100644 xcm/xcm-emulator/README.md create mode 100644 xcm/xcm-emulator/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 10a57137285..e395209bf46 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1347,6 +1347,15 @@ dependencies = [ "thiserror", ] +[[package]] +name = "casey" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabe85130dda9cf267715582ce6cf1ab581c8dfe3cb33f7065fee0f14e3fea14" +dependencies = [ + "syn 1.0.109", +] + [[package]] name = "cast" version = "0.3.0" @@ -4861,6 +4870,47 @@ dependencies = [ "num-traits", ] +[[package]] +name = "integration-tests-common" +version = "1.0.0" +dependencies = [ + "bridge-hub-kusama-runtime", + "bridge-hub-polkadot-runtime", + "collectives-polkadot-runtime", + "cumulus-primitives-core", + "frame-support", + "frame-system", + "kusama-runtime", + "kusama-runtime-constants", + "pallet-assets", + "pallet-balances", + "pallet-im-online", + "pallet-staking", + "pallet-xcm", + "parachain-info", + "parachains-common", + "parity-scale-codec", + "penpal-runtime", + "polkadot-core-primitives", + "polkadot-parachain", + "polkadot-primitives", + "polkadot-runtime", + "polkadot-runtime-constants", + "polkadot-runtime-parachains", + "polkadot-service", + "sc-consensus-grandpa", + "sp-authority-discovery", + "sp-consensus-babe", + "sp-core", + "sp-runtime", + "sp-weights", + "statemine-runtime", + "statemint-runtime", + "xcm", + "xcm-emulator", + "xcm-executor", +] + [[package]] name = "interceptor" version = "0.8.2" @@ -13536,6 +13586,32 @@ dependencies = [ "xcm-executor", ] +[[package]] +name = "statemint-it" +version = "1.0.0" +dependencies = [ + "frame-support", + "frame-system", + "integration-tests-common", + "pallet-assets", + "pallet-balances", + "pallet-xcm", + "parachains-common", + "parity-scale-codec", + "penpal-runtime", + "polkadot-core-primitives", + "polkadot-parachain", + "polkadot-runtime", + "polkadot-runtime-parachains", + "sp-core", + "sp-runtime", + "sp-weights", + "statemint-runtime", + "xcm", + "xcm-emulator", + "xcm-executor", +] + [[package]] name = "statemint-runtime" version = "1.0.0" @@ -16058,6 +16134,38 @@ dependencies = [ "xcm-executor", ] +[[package]] +name = "xcm-emulator" +version = "0.1.0" +dependencies = [ + "casey", + "cumulus-pallet-dmp-queue", + "cumulus-pallet-parachain-system", + "cumulus-pallet-xcmp-queue", + "cumulus-primitives-core", + "cumulus-primitives-parachain-inherent", + "cumulus-test-relay-sproof-builder", + "cumulus-test-service", + "frame-support", + "frame-system", + "log", + "pallet-balances", + "parachain-info", + "parachains-common", + "parity-scale-codec", + "paste", + "polkadot-primitives", + "polkadot-runtime-parachains", + "quote", + "sp-arithmetic", + "sp-core", + "sp-io", + "sp-std", + "sp-trie", + "xcm", + "xcm-executor", +] + [[package]] name = "xcm-executor" version = "0.9.41" diff --git a/Cargo.toml b/Cargo.toml index 42acec123a5..dcb862654e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,11 +52,14 @@ members = [ "parachains/runtimes/contracts/contracts-rococo", "parachains/runtimes/glutton/glutton-kusama", "parachains/runtimes/testing/penpal", + "parachains/integration-tests/emulated/common", + "parachains/integration-tests/emulated/assets/statemint", "test/client", "test/relay-sproof-builder", "test/relay-validation-worker-provider", "test/runtime", "test/service", + "xcm/xcm-emulator", ] [profile.release] @@ -67,4 +70,3 @@ opt-level = 3 inherits = "release" lto = true codegen-units = 1 - diff --git a/parachains/integration-tests/statemint/xcm/0_init.yml b/parachains/integration-tests/e2e/assets/statemine/0_xcm/0_init.yml similarity index 67% rename from parachains/integration-tests/statemint/xcm/0_init.yml rename to parachains/integration-tests/e2e/assets/statemine/0_xcm/0_init.yml index b9640517719..b770c8e569e 100644 --- a/parachains/integration-tests/statemint/xcm/0_init.yml +++ b/parachains/integration-tests/e2e/assets/statemine/0_xcm/0_init.yml @@ -11,12 +11,12 @@ settings: paraId: &pp_id 2000 variables: common: - xcm_verison: &xcm_version '2' - require_weight_at_most: &weight_at_most 1000000000 + xcm_version: &xcm_version '3' + require_weight_at_most: &weight_at_most {refTime: 1000000000, proofSize: 200000} chains: relay_chain: signer: &rc_signer //Alice - assets_parachain_destination: &ap_dest { v1: { 0, interior: { x1: { parachain: *ap_id }}}} + assets_parachain_destination: &ap_dest { v3: { 0, interior: { x1: { parachain: *ap_id }}}} penpal_parachain: signer: &pp_signer //Alice decodedCalls: @@ -37,7 +37,7 @@ tests: its: - name: XCM supported versions between chains actions: - - extrinsics: # Relay Chain sets supported version for Assset Parachain + - extrinsics: # Relay Chain sets supported version for Asset Parachain - chain: *relay_chain sudo: true signer: *rc_signer @@ -56,13 +56,13 @@ tests: ] events: - name: sudo.Sudid - attribute: - type: Result - value: Ok + attributes: + - type: Result + value: Ok - name: xcmPallet.SupportedVersionChanged - attribute: - type: u32 - value: *xcm_version + attributes: + - type: u32 + value: *xcm_version - extrinsics: # Relay Chain sets supported version for Penpal Parachain - chain: *relay_chain sudo: true @@ -82,14 +82,14 @@ tests: ] events: - name: sudo.Sudid - attribute: - type: Result - value: Ok + attributes: + - type: Result + value: Ok - name: xcmPallet.SupportedVersionChanged - attribute: - type: u32 - value: *xcm_version - - extrinsics: # Assset Parachain sets supported version for Relay Chain through it + attributes: + - type: u32 + value: *xcm_version + - extrinsics: # Asset Parachain sets supported version for Relay Chain through it - chain: *relay_chain signer: *rc_signer sudo: true @@ -98,10 +98,20 @@ tests: args: [ *ap_dest, # destination { - v2: [ #message + v3: [ #message + { + UnpaidExecution: { + weightLimit: { + limited: { + refTime: 2200000000, + proofSize: 200000 + } + } + } + }, { Transact: { - originType: Superuser, + originKind: Superuser, requireWeightAtMost: *weight_at_most, call: $ap_force_xcm_version } @@ -111,15 +121,15 @@ tests: ] events: - name: sudo.Sudid - attribute: - type: Result - value: Ok + attributes: + - type: Result + value: Ok - name: xcmPallet.Sent - name: polkadotXcm.SupportedVersionChanged chain: *assets_parachain - attribute: - type: u32 - value: *xcm_version + attributes: + - type: u32 + value: *xcm_version - extrinsics: # Penpal Parachain sets supported version for Relay Chain - chain: *penpal_parachain signer: *pp_signer @@ -135,10 +145,10 @@ tests: ] events: - name: sudo.Sudid - attribute: - type: Result - value: Ok + attributes: + - type: Result + value: Ok - name: polkadotXcm.SupportedVersionChanged - attribute: - type: u32 - value: *xcm_version + attributes: + - type: u32 + value: *xcm_version diff --git a/parachains/integration-tests/statemint/xcm/1_dmp.yml b/parachains/integration-tests/e2e/assets/statemine/0_xcm/1_dmp.yml similarity index 78% rename from parachains/integration-tests/statemint/xcm/1_dmp.yml rename to parachains/integration-tests/e2e/assets/statemine/0_xcm/1_dmp.yml index 5f0fa349072..0852a3907db 100644 --- a/parachains/integration-tests/statemint/xcm/1_dmp.yml +++ b/parachains/integration-tests/e2e/assets/statemine/0_xcm/1_dmp.yml @@ -10,13 +10,13 @@ settings: relay_chain: signer: &rc_signer //Alice wallet: &rc_wallet HNZata7iMYWmk5RvZRTiAsSDhV8366zq2YGb3tLH5Upf74F - assets_parachain_destination: &ap_dest { v1: { parents: 0, interior: { x1: { parachain: *ap_id }}}} + assets_parachain_destination: &ap_dest { v3: { parents: 0, interior: { x1: { parachain: *ap_id }}}} assets_parachain_account: &ap_acc '0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d' - assets_parachain_beneficiary: &ap_benf {v1: { parents: 0, interior: { x1: { accountId32: { network: { any: true }, id: *ap_acc }}}}} + assets_parachain_beneficiary: &ap_benf {v3: { parents: 0, interior: { x1: { accountId32: { id: *ap_acc }}}}} ksm: &rc_ksm { concrete: { parents: 0, interior: { here: true }}} amount: &amount 1000000000000 ksm_fungible: &rc_ksm_fungible { id: *rc_ksm, fun: { fungible: *amount }} - require_weight_at_most: &rc_weight_at_most 1000000000 + require_weight_at_most: &rc_weight_at_most {refTime: 1000000000, proofSize: 200000} assets_parachain_account: wallet: &ap_wallet HNZata7iMYWmk5RvZRTiAsSDhV8366zq2YGb3tLH5Upf74F asset_id: &asset_id 1 @@ -63,22 +63,22 @@ tests: args: [ *ap_dest, # destination *ap_benf, # beneficiary - { v1: [ *rc_ksm_fungible ] }, # assets + { v3: [ *rc_ksm_fungible ] }, 0, # feeAssetItem { unlimited: true } # weightLimit ] events: - name: xcmPallet.Attempted - attribute: - type: XcmV2TraitsOutcome - isComplete: true + attributes: + - type: XcmV3TraitsOutcome + xcmOutcome: Complete - name: dmpQueue.ExecutedDownward chain: *assets_parachain - attribute: - type: XcmV2TraitsOutcome - isComplete: true - threshold: [10, 10] - value: 1,021,635,000 + attributes: + - type: XcmV3TraitsOutcome + xcmOutcome: Complete + threshold: [10, 10] + value: {"refTime":"162,379,000","proofSize":"0"} - queries: balance_rc_sender_after: chain: *relay_chain @@ -131,10 +131,15 @@ tests: args: [ *ap_dest, # destination { - v2: [ #message + v3: [ #message + { + UnpaidExecution: { + weightLimit: Unlimited + } + }, { Transact: { - originType: Superuser, + originKind: Superuser, requireWeightAtMost: *rc_weight_at_most, call: $force_create_asset } @@ -146,11 +151,11 @@ tests: - name: xcmPallet.Sent - name: dmpQueue.ExecutedDownward chain: *assets_parachain - attribute: - type: XcmV2TraitsOutcome - isComplete: true - threshold: [10, 10] - value: 1,020,807,000 + attributes: + - type: XcmV3TraitsOutcome + xcmOutcome: Complete + threshold: [10, 10] + value: {"refTime":"1,014,103,000","proofSize":"200,000"} - queries: forced_created_asset: chain: *assets_parachain @@ -173,10 +178,15 @@ tests: args: [ *ap_dest, # destination { - v2: [ #message + v3: [ #message + { + UnpaidExecution: { + weightLimit: Unlimited + } + }, { Transact: { - originType: Native, + originKind: Native, requireWeightAtMost: *rc_weight_at_most, call: $force_create_asset } @@ -186,9 +196,9 @@ tests: ] events: - name: system.ExtrinsicFailed - attribute: - type: SpRuntimeDispatchError - value: BadOrigin + attributes: + - type: SpRuntimeDispatchError + value: BadOrigin - name: xcmPallet.limitedReserveTransferAssets before: *before_get_balances @@ -203,22 +213,23 @@ tests: args: [ *ap_dest, # destination *ap_benf, # beneficiary - { v1: [ *rc_ksm_fungible ] }, # assets + { v3: [ *rc_ksm_fungible ] }, # assets 0, # feeAssetItem { unlimited: true } # weightLimit ] events: - name: xcmPallet.Attempted - attribute: - type: XcmV2TraitsOutcome - isComplete: true - value: 1,000,000,000 + attributes: + - type: XcmV3TraitsOutcome + xcmOutcome: Complete + threshold: [10, 10] + value: {"refTime":"750,645,000","proofSize":"0"} - name: dmpQueue.ExecutedDownward chain: *assets_parachain - attribute: - type: XcmV2TraitsOutcome - isError: true - value: "WeightNotComputable" + attributes: + - type: XcmV3TraitsOutcome + xcmOutcome: Incomplete + value: [{"refTime":"1,000,000,000","proofSize":"0"},"UntrustedReserveLocation"] - queries: balance_rc_sender_after: chain: *relay_chain diff --git a/parachains/integration-tests/statemine/xcm/2_ump.yml b/parachains/integration-tests/e2e/assets/statemine/0_xcm/2_ump.yml similarity index 71% rename from parachains/integration-tests/statemine/xcm/2_ump.yml rename to parachains/integration-tests/e2e/assets/statemine/0_xcm/2_ump.yml index daddf927931..46519da3fde 100644 --- a/parachains/integration-tests/statemine/xcm/2_ump.yml +++ b/parachains/integration-tests/e2e/assets/statemine/0_xcm/2_ump.yml @@ -9,21 +9,21 @@ settings: variables: common: amount: &amount 1000000000000 - require_weight_at_most: &weight_at_most 1000000000 + require_weight_at_most: &weight_at_most {refTime: 1000000000, proofSize: 0} relay_chain: signer: &rc_signer //Alice wallet: &rc_wallet HNZata7iMYWmk5RvZRTiAsSDhV8366zq2YGb3tLH5Upf74F #Alice - assets_parachain_destination: &ap_dest { v1: { 0, interior: { x1: { parachain: *ap_id }}}} + assets_parachain_destination: &ap_dest { v3: { 0, interior: { x1: { parachain: *ap_id }}}} assets_parachain_account: &ap_acc '0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d' - assets_parachain_beneficiary: &ap_benf {v1: { parents: 0, interior: { x1: { accountId32: { network: { any: true }, id: *ap_acc }}}}} + assets_parachain_beneficiary: &ap_benf {v3: { parents: 0, interior: { x1: { accountId32: { id: *ap_acc }}}}} ksm: &rc_ksm { concrete: { 0, interior: { here: true }}} ksm_fungible: &rc_ksm_fungible { id: *rc_ksm, fun: { fungible: *amount }} assets_parachain_account: signer: &ap_signer //Alice wallet: &ap_wallet HNZata7iMYWmk5RvZRTiAsSDhV8366zq2YGb3tLH5Upf74F - relay_chain_destination: &rc_dest { v1: { parents: 1, interior: { here: true }}} + relay_chain_destination: &rc_dest { v3: { parents: 1, interior: { here: true }}} assets_parachain_account: &rc_acc '0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d' #Alice - relay_chain_beneficiary: &rc_benf {v1: { parents: 0, interior: { x1: { accountId32: { network: { any: true }, id: *rc_acc }}}}} + relay_chain_beneficiary: &rc_benf {v3: { parents: 0, interior: { x1: { accountId32: { id: *rc_acc }}}}} ksm: &ap_ksm { concrete: { parents: 1, interior: { here: true }}} ksm_fungible: &ap_ksm_fungible { id: *ap_ksm, fun: { fungible: *amount }} decodedCalls: @@ -38,7 +38,7 @@ tests: describes: - name: polkadotXcm.limitedTeleportAssets before: - - name: DEPENDANCY | Do a 'limitedTeleportAssets' from the Relay Chain to the Assets Parachain to have funds to send them back + - name: DEPENDENCY | Do a 'limitedTeleportAssets' from the Relay Chain to the Assets Parachain to have funds to send them back actions: - extrinsics: - chain: *relay_chain @@ -48,22 +48,24 @@ tests: args: [ *ap_dest, # destination *ap_benf, # beneficiary - { v1: [ *rc_ksm_fungible ] }, # assets + { v3: [ *rc_ksm_fungible ] }, # assets 0, # feeAssetItem { unlimited: true } # weightLimit ] events: - name: xcmPallet.Attempted - attribute: - type: XcmV2TraitsOutcome - isComplete: true + attributes: + - type: XcmV3TraitsOutcome + xcmOutcome: Complete + threshold: [10, 10] + value: {"refTime":"761,173,000","proofSize":"0"} - name: dmpQueue.ExecutedDownward chain: *assets_parachain - attribute: - type: XcmV2TraitsOutcome - isComplete: true - threshold: [10, 10] - value: 1,021,973,000 + attributes: + - type: XcmV3TraitsOutcome + xcmOutcome: Complete + threshold: [10, 10] + value: {"refTime":"162,379,000","proofSize":"0"} - name: Get the balances of the Assets Parachain's sender & Relay Chain's receiver actions: @@ -89,24 +91,24 @@ tests: args: [ *rc_dest, # destination *rc_benf, # beneficiary - { v1: [ *ap_ksm_fungible ] }, # assets + { v3: [ *ap_ksm_fungible ] }, # assets 0, # feeAssetItem { unlimited: true } # weightLimit ] events: - name: polkadotXcm.Attempted - attribute: - type: XcmV2TraitsOutcome - isComplete: true - threshold: [10, 10] - value: 360,315,000 + attributes: + - type: XcmV3TraitsOutcome + xcmOutcome: Complete + threshold: [10, 10] + value: {"refTime":"539,494,000","proofSize":"7,133"} - name: ump.ExecutedUpward chain: *relay_chain - attribute: - type: XcmV2TraitsOutcome - isComplete: true - threshold: [10, 10] - value: 297,578,000 + attributes: + - type: XcmV3TraitsOutcome + xcmOutcome: Complete + threshold: [10, 10] + value: {"refTime":"298,716,000","proofSize":"0"} - queries: balance_ap_sender_after: chain: *assets_parachain @@ -148,7 +150,7 @@ tests: - name: polkadotXcm.send | Native - Transact(system.remark) its: - - name: Assets Parachain SHOULD NOT be able to dipatch 'send' call + - name: Assets Parachain SHOULD NOT be able to dispatch 'send' call actions: - extrinsics: - chain: *assets_parachain @@ -158,10 +160,15 @@ tests: args: [ *rc_dest, # destination { - v2: [ #message + v3: [ #message + { + UnpaidExecution: { + weightLimit: Unlimited + } + }, { Transact: { - originType: Native, + originKind: Native, requireWeightAtMost: *weight_at_most, call: $system_remark } @@ -171,9 +178,9 @@ tests: ] events: - name: system.ExtrinsicFailed - attribute: - type: SpRuntimeDispatchError - value: BadOrigin + attributes: + - type: SpRuntimeDispatchError + value: BadOrigin - name: polkadotXcm.limitedReserveTransferAssets its: @@ -187,13 +194,13 @@ tests: args: [ *rc_dest, # destination *rc_benf, # beneficiary - { v1: [ *ap_ksm_fungible ] }, # assets + { v3: [ *ap_ksm_fungible ] }, # assets 0, # feeAssetItem { unlimited: true } # weightLimit ] events: - name: polkadotXcm.Attempted - attribute: - type: XcmV2TraitsOutcome - isError: true - value: Barrier + attributes: + - type: XcmV3TraitsOutcome + xcmOutcome: Error + value: Barrier diff --git a/parachains/integration-tests/e2e/assets/statemine/0_xcm/3_hrmp-open-channels.yml b/parachains/integration-tests/e2e/assets/statemine/0_xcm/3_hrmp-open-channels.yml new file mode 100644 index 00000000000..cc1fc9da146 --- /dev/null +++ b/parachains/integration-tests/e2e/assets/statemine/0_xcm/3_hrmp-open-channels.yml @@ -0,0 +1,134 @@ +--- +settings: + chains: + relay_chain: &relay_chain + wsPort: 9900 + assets_parachain: &assets_parachain + wsPort: 9910 + paraId: &ap_id 1000 + penpal_parachain: &penpal_parachain + wsPort: 9920 + paraId: &pp_id 2000 + variables: + common: + amount: &amount 2000000000000 + require_weight_at_most: &weight_at_most {refTime: 1000000000, proofSize: 20000} + hrmp_channels: + proposed_max_capacity: &max_capacity 8 + proposed_max_message_size: &max_message_size 8192 + channel: &channel { + maxCapacity: 8, + maxTotalSize: 8192, + maxMessageSize: 8192, + msgCount: 0, + totalSize: 0, + mqcHead: null, + senderDeposit: 0, + recipientDeposit: 0 + } + chains: + relay_chain: + signer: &rc_signer //Alice + assets_parachain_destination: &ap_dest { v3: { 0, interior: { x1: { parachain: *ap_id }}}} + assets_parachain_account: &ap_acc '0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d' + assets_parachain_beneficiary: &ap_benf {v3: { parents: 0, interior: { x1: { accountId32: { id: *ap_acc }}}}} + ksm: &rc_ksm { concrete: { 0, interior: { here: true }}} + ksm_fungible: &rc_ksm_fungible { id: *rc_ksm, fun: { fungible: *amount }} + assets_parachain_account: + sovereign_account: &ap_sovereign F7fq1jSNVTPfJmaHaXCMtatT1EZefCUsa7rRiQVNR5efcah + relay_chain_destination: &rc_dest { v3: { parents: 1, interior: { here: true }}} + penpal_parachain: + sovereign_account: &pp_sovereign F7fq1jMZkfuCuoMTyiEVAP2DMpMt18WopgBqTJznLihLNbZ + signer: &pp_signer //Alice + +tests: + - name: HRMP + beforeEach: + - name: DEPENDENCY | Penpal Parachain Sovereign account in the Relay Chain needs to be funded + actions: + - extrinsics: + - chain: *relay_chain + signer: *rc_signer + pallet: balances + call: transfer + args: [ + *pp_sovereign, # destination + *amount, # value + ] + events: + - name: balances.Transfer + + - name: DEPENDENCY | Assets Parachain Sovereign account in the Relay Chain needs to be funded + actions: + - extrinsics: + - chain: *relay_chain + signer: *rc_signer + pallet: balances + call: transfer + args: [ + *ap_sovereign, # destination + *amount, # value + ] + events: + - name: balances.Transfer + describes: + - name: hrmp.hrmpInitOpenChannel (Penpal Parachain → Assets Parachain) + its: + - name: Open Penpal Parachain to Assets Parachain + actions: + - extrinsics: + - chain: *relay_chain + signer: *rc_signer + sudo: true + pallet: hrmp + call: forceOpenHrmpChannel + args: [ + 2000, + 1000, + 8, + 8192 + ] + events: + - name: sudo.Sudid + attributes: + - type: Result + value: Ok + - name: hrmp.HrmpChannelForceOpened + - name: hrmp.hrmpInitOpenChannel (Assets Parachain → PenPal Parachain) + its: + - name: Open Assets Parachain to PenPal Parachain + actions: + - extrinsics: + - chain: *relay_chain + signer: *rc_signer + sudo: true + pallet: hrmp + call: forceOpenHrmpChannel + args: [ + 1000, + 2000, + 8, + 8192 + ] + events: + - name: sudo.Sudid + attributes: + - type: Result + value: Ok + - name: hrmp.HrmpChannelForceOpened + - name: hrmp.forceProcessHrmpOpen (make sure all the channels are open) + its: + - name: Make sure all the pending channels are open + actions: + - extrinsics: + - chain: *relay_chain + signer: *rc_signer + sudo: true + pallet: hrmp + call: forceProcessHrmpOpen + args: [ 2 ] + events: + - name: sudo.Sudid + attributes: + - type: Result + value: Ok diff --git a/parachains/integration-tests/e2e/assets/statemine/0_xcm/4_hrmp.yml b/parachains/integration-tests/e2e/assets/statemine/0_xcm/4_hrmp.yml new file mode 100644 index 00000000000..e47ae5a4054 --- /dev/null +++ b/parachains/integration-tests/e2e/assets/statemine/0_xcm/4_hrmp.yml @@ -0,0 +1,403 @@ +--- +# Note: This tests depends on the 3_hrmp-open-channels.yml for opening channels, otherwise teleports aren't going to +# work. +settings: + chains: + relay_chain: &relay_chain + wsPort: 9900 + assets_parachain: &assets_parachain + wsPort: 9910 + paraId: &ap_id 1000 + penpal_parachain: &penpal_parachain + wsPort: 9920 + paraId: &pp_id 2000 + variables: + common: + mint_amount: &mint_amount 1000000000000 + amount: &amount 100000000000 + require_weight_at_most: &weight_at_most {refTime: 1200000000, proofSize: 20000} + amount_to_send: &amount_to_send 500000000000 + chains: + relay_chain: + signer: &rc_signer //Alice + assets_parachain_destination: &ap_dest { v3: { 0, interior: { x1: { parachain: *ap_id }}}} + assets_parachain_dest_routed: &ap_dest_routed { v3: { parents: 1, interior: { x1: { parachain: *ap_id } }}} + assets_parachain_account: + signer: &ap_signer //Alice + wallet: &ap_wallet HNZata7iMYWmk5RvZRTiAsSDhV8366zq2YGb3tLH5Upf74F + asset_id: &asset_id 2 + assets_pallet_id: &assets_pallet_id 50 + asset_min_balance: &asset_ed 1000 + penpal_parachain_destination: &pp_dest { v3: { parents: 1, interior: { x1: { parachain: *pp_id } }}} + ksm: &ap_ksm { concrete: { parents: 1, interior: { here: true }}} + ksm_fungible: &ap_ksm_fungible { id: *ap_ksm, fun: { fungible: *amount }} + suff_asset: &suff_asset { concrete: { parents: 0, interior: { x2: [ { PalletInstance: *assets_pallet_id }, { GeneralIndex: *asset_id } ] }}} + suff_asset_fail: &suff_asset_fail { concrete: { parents: 0, interior: { x2: [ { PalletInstance: *assets_pallet_id }, { GeneralIndex: 3 } ] }}} + suff_asset_fungible_fail: &ap_suff_asset_fungible_fail { id: *suff_asset_fail, fun: { fungible: 200000000000 }} + penpal_parachain: + sovereign_account: &pp_sovereign_sibl FBeL7EAeUroLWXW1yfKboiqTqVfbRBcsUKd6QqVf4kGBySS + signer: &pp_signer //Alice + penpal_parachain_account: &pp_acc '0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d' + decodedCalls: + force_create_asset: + chain: *assets_parachain + pallet: assets + call: forceCreate + args: [ + *asset_id, + { Id: *ap_wallet }, # owner + true, # isSufficient + *asset_ed # minBalance + ] + force_create_asset2: + chain: *assets_parachain + pallet: assets + call: forceCreate + args: [ + *asset_id, + { Id: *ap_wallet }, # owner + true, # isSufficient + *asset_ed # minBalance + ] + +tests: + - name: HRMP + describes: + - name: polkadotXcm.limitedReserveTransferAssets (Asset) | Assets Parachain -> Penpal Parachain + before: + - name: DEPENDENCY | A sufficient Asset should exist in the Assets Parachain + actions: + - extrinsics: + - chain: *relay_chain + signer: *rc_signer + sudo: true + pallet: xcmPallet + call: send + args: [ + *ap_dest, # destination + { + v3: [ #message + { + UnpaidExecution: { + weightLimit: Unlimited + } + }, + { + SetTopic: "0x0123456789012345678901234567891201234567890123456789012345678912" + }, + { + Transact: { + originKind: Superuser, + requireWeightAtMost: *weight_at_most, + call: $force_create_asset + } + } + ] + } + ] + events: + - name: xcmPallet.Sent + - name: dmpQueue.ExecutedDownward + chain: *assets_parachain + attributes: + - type: XcmV3TraitsOutcome + xcmOutcome: Complete + threshold: [10, 10] + value: {"refTime":"1,216,703,000","proofSize":"20,000"} + - queries: + forced_created_asset: + chain: *assets_parachain + pallet: assets + call: asset + args: [ *asset_id ] + - asserts: + isSome: + args: [ $forced_created_asset ] + + - name: DEPENDENCY | Some Assets should be minted for the sender + actions: + - extrinsics: + - chain: *assets_parachain + signer: *ap_signer + pallet: assets + call: mint + args: [ + *asset_id, + *ap_wallet, + *mint_amount + ] + events: + - name: assets.Issued + + its: + - name: Assets Parachain should be able to reserve transfer an Asset to Penpal Parachain + actions: + - extrinsics: + - chain: *assets_parachain + signer: *ap_signer + pallet: polkadotXcm + call: limitedReserveTransferAssets + args: [ + *pp_dest, # destination + { # beneficiary + V3: { + parents: 0, + interior: { + X1: { + AccountId32: { + id: *pp_acc + } + } + } + } + }, + { # assets + V3: [ + { + id: { + Concrete: { + parents: 0, + interior: { + X2: [ + { + PalletInstance: *assets_pallet_id + }, + { + GeneralIndex: *asset_id + } + ] + } + } + }, + fun: { + Fungible: *amount_to_send + } + } + ] + }, + 0, # feeAssetItem + Unlimited # weightLimit + ] + events: + - name: polkadotXcm.Attempted + attributes: + - type: XcmV3TraitsOutcome + xcmOutcome: Complete + threshold: [10, 10] + value: {"refTime":"679,150,000","proofSize":"6,196"} + - name: assets.Transferred + attributes: + - type: AccountId32 + value: *pp_sovereign_sibl + - name: assets.Transferred + attributes: + - type: u128 + value: *amount_to_send + + - name: polkadotXcm.limitedReserveTransferAssets (KSM) | Assets Parachain -> Penpal Parachain + its: + - name: Assets Parachain should be able to reserve transfer KSM to Penpal Parachain + actions: + - extrinsics: + - chain: *assets_parachain + signer: *ap_signer + pallet: polkadotXcm + call: limitedReserveTransferAssets + args: [ + *pp_dest, # destination + { # beneficiary + V3: { + parents: 0, + interior: { + X1: { + AccountId32: { + id: *pp_acc + } + } + } + } + }, + { # assets + V3: [ + *ap_ksm_fungible + ] + }, + 0, # feeAssetItem + Unlimited # weightLimit + ] + events: + - name: polkadotXcm.Attempted + attributes: + - type: XcmV3TraitsOutcome + xcmOutcome: Complete + threshold: [10, 10] + value: {"refTime":"679,150,000","proofSize":"6,196"} + - name: balances.Endowed + attributes: + - type: AccountId32 + value: *pp_sovereign_sibl + - name: balances.Endowed + attributes: + - type: u128 + value: *amount + + - name: polkadotXcm.send( assets.forceCreateAsset ) | Penpal Parachain -> Assets Parachain + before: + - name: Get the asset balance of the Penpal Parachain Sovereign account in Assets Parachain + actions: + - queries: + assets_balance_pp_sovereign_before: + chain: *assets_parachain + pallet: assets + call: account + args: [ + *asset_id, + *pp_sovereign_sibl + ] + its: + - name: Penpal Parachain should be able to send XCM message paying its fee with sufficient asset in Assets Parachain + actions: + - extrinsics: + - chain: *penpal_parachain + signer: *pp_signer + sudo: true + pallet: polkadotXcm + call: send + args: [ + *ap_dest_routed, # destination + { + v3: [ #message + { + WithdrawAsset: [ + { + id: { + concrete: { + parents: 0, + interior: { + X2: [ + { PalletInstance: *assets_pallet_id }, + { GeneralIndex: *asset_id } + ] + } + } + }, + fun: { fungible: *amount }} + ] + }, + { + BuyExecution: { + fees: { id: *suff_asset, fun: { fungible: *amount }}, + weightLimit: Unlimited + } + }, + { + Transact: { + originKind: SovereignAccount, + requireWeightAtMost: *weight_at_most, + call: $force_create_asset2 + } + }, + { + RefundSurplus + }, + { + DepositAsset: { + assets: { Wild: All }, + beneficiary: { + parents: 0, + interior: { + X1: { + AccountId32: { + network: , # None + id: *pp_acc + } + } + }} + } + } + ] + } + ] + events: + - name: sudo.Sudid + attributes: + - type: Result + value: Ok + - name: polkadotXcm.Sent + - name: assets.Burned + chain: *assets_parachain + attributes: + - type: AccountId32 + value: *pp_sovereign_sibl + - name: assets.Issued + chain: *assets_parachain + attributes: + - type: u32 + value: *asset_id + - queries: + assets_balance_pp_sovereign_after: + chain: *assets_parachain + pallet: assets + call: account + args: [ + *asset_id, + *pp_sovereign_sibl + ] + forced_created_asset2: + chain: *assets_parachain + pallet: assets + call: asset + args: [ 3 ] + - asserts: + isSome: + args: [ $forced_created_asset2 ] + - name: Should reduce the assets balance of the Penpal Parachain's SovereignAccount in the Assets Parachain + actions: + - asserts: + assetsDecreased: + args: [ + { + balances: { + before: $assets_balance_pp_sovereign_before, + after: $assets_balance_pp_sovereign_after, + }, + } + ] + + - name: Penpal Parachain SHOULD NOT be able to send XCM message paying its fee with sufficient assets if not enough balance + actions: + - extrinsics: + - chain: *penpal_parachain + signer: *pp_signer + sudo: true + pallet: polkadotXcm + call: send + args: [ + *ap_dest_routed, # destination + { + v3: [ #message + { + WithdrawAsset: [*ap_suff_asset_fungible_fail] + }, + { + BuyExecution: { + fees: *ap_suff_asset_fungible_fail, + weightLimit: Unlimited + } + }, + { + Transact: { + originKind: SovereignAccount, + requireWeightAtMost: *weight_at_most, + call: $force_create_asset2 + } + } + ] + } + ] + events: + - name: xcmpQueue.Fail + chain: *assets_parachain + attributes: + - type: XcmV3TraitsError + value: FailedToTransactAsset diff --git a/parachains/integration-tests/e2e/assets/statemine/config.toml b/parachains/integration-tests/e2e/assets/statemine/config.toml new file mode 100644 index 00000000000..6aa7ee8d116 --- /dev/null +++ b/parachains/integration-tests/e2e/assets/statemine/config.toml @@ -0,0 +1,70 @@ +[relaychain] +default_command = "./bin/polkadot" +default_args = [ "-lparachain=debug", "-lxcm=trace" ] +chain = "kusama-local" + + [[relaychain.nodes]] + name = "alice" + ws_port = 9900 + validator = true + + [[relaychain.nodes]] + name = "bob" + ws_port = 9901 + validator = true + + [[relaychain.nodes]] + name = "charlie" + ws_port = 9902 + validator = true + + [[relaychain.nodes]] + name = "dave" + ws_port = 9903 + validator = true + +[[parachains]] +id = 1000 +chain = "statemine-local" +cumulus_based = true + + [[parachains.collators]] + name = "collator1" + ws_port = 9910 + command = "./bin/polkadot-parachain" + args = [ "-lxcm=trace" ] + + [[parachains.collators]] + name = "collator2" + ws_port = 9911 + command = "./bin/polkadot-parachain" + args = [ "-lxcm=trace" ] + +[[parachains]] +id = 2000 +chain = "penpal-kusama-2000" +cumulus_based = true + + [[parachains.collators]] + name = "collator3" + ws_port = 9920 + command = "./bin/polkadot-parachain" + args = [ "-lxcm=trace" ] + + [[parachains.collators]] + name = "collator4" + ws_port = 9921 + command = "./bin/polkadot-parachain" + args = [ "-lxcm=trace" ] + +# [[hrmpChannels]] +# sender = 1000 +# recipient = 2000 +# maxCapacity = 8 +# maxMessageSize = 8192 + +# [[hrmpChannels]] +# sender = 2000 +# recipient = 1000 +# maxCapacity = 8 +# maxMessageSize = 8192 diff --git a/parachains/integration-tests/statemine/xcm/0_init.yml b/parachains/integration-tests/e2e/assets/statemint/0_xcm/0_init.yml similarity index 66% rename from parachains/integration-tests/statemine/xcm/0_init.yml rename to parachains/integration-tests/e2e/assets/statemint/0_xcm/0_init.yml index b9640517719..95c77f72d0d 100644 --- a/parachains/integration-tests/statemine/xcm/0_init.yml +++ b/parachains/integration-tests/e2e/assets/statemint/0_xcm/0_init.yml @@ -2,21 +2,21 @@ settings: chains: relay_chain: &relay_chain - wsPort: 9900 + wsPort: 9800 assets_parachain: &assets_parachain - wsPort: 9910 + wsPort: 9810 paraId: &ap_id 1000 penpal_parachain: &penpal_parachain - wsPort: 9920 + wsPort: 9820 paraId: &pp_id 2000 variables: common: - xcm_verison: &xcm_version '2' - require_weight_at_most: &weight_at_most 1000000000 + xcm_version: &xcm_version '3' + require_weight_at_most: &weight_at_most {refTime: 1000000000, proofSize: 200000} chains: relay_chain: signer: &rc_signer //Alice - assets_parachain_destination: &ap_dest { v1: { 0, interior: { x1: { parachain: *ap_id }}}} + assets_parachain_destination: &ap_dest { v3: { 0, interior: { x1: { parachain: *ap_id }}}} penpal_parachain: signer: &pp_signer //Alice decodedCalls: @@ -37,7 +37,7 @@ tests: its: - name: XCM supported versions between chains actions: - - extrinsics: # Relay Chain sets supported version for Assset Parachain + - extrinsics: # Relay Chain sets supported version for Asset Parachain - chain: *relay_chain sudo: true signer: *rc_signer @@ -56,13 +56,13 @@ tests: ] events: - name: sudo.Sudid - attribute: - type: Result - value: Ok + attributes: + - type: Result + value: Ok - name: xcmPallet.SupportedVersionChanged - attribute: - type: u32 - value: *xcm_version + attributes: + - type: u32 + value: *xcm_version - extrinsics: # Relay Chain sets supported version for Penpal Parachain - chain: *relay_chain sudo: true @@ -82,14 +82,14 @@ tests: ] events: - name: sudo.Sudid - attribute: - type: Result - value: Ok + attributes: + - type: Result + value: Ok - name: xcmPallet.SupportedVersionChanged - attribute: - type: u32 - value: *xcm_version - - extrinsics: # Assset Parachain sets supported version for Relay Chain through it + attributes: + - type: u32 + value: *xcm_version + - extrinsics: # Asset Parachain sets supported version for Relay Chain through it - chain: *relay_chain signer: *rc_signer sudo: true @@ -98,10 +98,20 @@ tests: args: [ *ap_dest, # destination { - v2: [ #message + v3: [ #message + { + UnpaidExecution: { + weightLimit: { + limited: { + refTime: 3200000000, + proofSize: 200000 + } + } + } + }, { Transact: { - originType: Superuser, + originKind: Superuser, requireWeightAtMost: *weight_at_most, call: $ap_force_xcm_version } @@ -111,15 +121,15 @@ tests: ] events: - name: sudo.Sudid - attribute: - type: Result - value: Ok + attributes: + - type: Result + value: Ok - name: xcmPallet.Sent - name: polkadotXcm.SupportedVersionChanged chain: *assets_parachain - attribute: - type: u32 - value: *xcm_version + attributes: + - type: u32 + value: *xcm_version - extrinsics: # Penpal Parachain sets supported version for Relay Chain - chain: *penpal_parachain signer: *pp_signer @@ -135,10 +145,10 @@ tests: ] events: - name: sudo.Sudid - attribute: - type: Result - value: Ok + attributes: + - type: Result + value: Ok - name: polkadotXcm.SupportedVersionChanged - attribute: - type: u32 - value: *xcm_version + attributes: + - type: u32 + value: *xcm_version diff --git a/parachains/integration-tests/statemine/xcm/1_dmp.yml b/parachains/integration-tests/e2e/assets/statemint/0_xcm/1_dmp.yml similarity index 79% rename from parachains/integration-tests/statemine/xcm/1_dmp.yml rename to parachains/integration-tests/e2e/assets/statemint/0_xcm/1_dmp.yml index 9b08555a251..96a97ba728d 100644 --- a/parachains/integration-tests/statemine/xcm/1_dmp.yml +++ b/parachains/integration-tests/e2e/assets/statemint/0_xcm/1_dmp.yml @@ -2,21 +2,21 @@ settings: chains: relay_chain: &relay_chain - wsPort: 9900 + wsPort: 9800 assets_parachain: &assets_parachain - wsPort: 9910 + wsPort: 9810 paraId: &ap_id 1000 variables: relay_chain: signer: &rc_signer //Alice wallet: &rc_wallet HNZata7iMYWmk5RvZRTiAsSDhV8366zq2YGb3tLH5Upf74F - assets_parachain_destination: &ap_dest { v1: { parents: 0, interior: { x1: { parachain: *ap_id }}}} + assets_parachain_destination: &ap_dest { v3: { parents: 0, interior: { x1: { parachain: *ap_id }}}} assets_parachain_account: &ap_acc '0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d' - assets_parachain_beneficiary: &ap_benf {v1: { parents: 0, interior: { x1: { accountId32: { network: { any: true }, id: *ap_acc }}}}} + assets_parachain_beneficiary: &ap_benf {v3: { parents: 0, interior: { x1: { accountId32: { id: *ap_acc }}}}} ksm: &rc_ksm { concrete: { parents: 0, interior: { here: true }}} amount: &amount 1000000000000 ksm_fungible: &rc_ksm_fungible { id: *rc_ksm, fun: { fungible: *amount }} - require_weight_at_most: &rc_weight_at_most 1000000000 + require_weight_at_most: &rc_weight_at_most {refTime: 1000000000, proofSize: 200000} assets_parachain_account: wallet: &ap_wallet HNZata7iMYWmk5RvZRTiAsSDhV8366zq2YGb3tLH5Upf74F asset_id: &asset_id 1 @@ -63,22 +63,22 @@ tests: args: [ *ap_dest, # destination *ap_benf, # beneficiary - { v1: [ *rc_ksm_fungible ] }, # assets + { v3: [ *rc_ksm_fungible ] }, # assets 0, # feeAssetItem { unlimited: true } # weightLimit ] events: - name: xcmPallet.Attempted - attribute: - type: XcmV2TraitsOutcome - isComplete: true + attributes: + - type: XcmV3TraitsOutcome + xcmOutcome: Complete - name: dmpQueue.ExecutedDownward chain: *assets_parachain - attribute: - type: XcmV2TraitsOutcome - isComplete: true - threshold: [10, 10] - value: 1,021,973,000 + attributes: + - type: XcmV3TraitsOutcome + xcmOutcome: Complete + threshold: [10, 10] + value: {"refTime":"162,909,000","proofSize":"0"} - queries: balance_rc_sender_after: chain: *relay_chain @@ -131,7 +131,12 @@ tests: args: [ *ap_dest, # destination { - v2: [ #message + v3: [ #message + { + UnpaidExecution: { + weightLimit: Unlimited + } + }, { Transact: { originType: Superuser, @@ -146,11 +151,11 @@ tests: - name: xcmPallet.Sent - name: dmpQueue.ExecutedDownward chain: *assets_parachain - attribute: - type: XcmV2TraitsOutcome - isComplete: true - threshold: [10, 10] - value: 1,021,258,000 + attributes: + - type: XcmV3TraitsOutcome + xcmOutcome: Complete + threshold: [10, 10] + value: {"refTime":"1,015,234,000","proofSize":"200,000"} - queries: forced_created_asset: chain: *assets_parachain @@ -173,7 +178,12 @@ tests: args: [ *ap_dest, # destination { - v2: [ #message + v3: [ #message + { + UnpaidExecution: { + weightLimit: Unlimited + } + }, { Transact: { originType: Native, @@ -186,9 +196,9 @@ tests: ] events: - name: system.ExtrinsicFailed - attribute: - type: SpRuntimeDispatchError - value: BadOrigin + attributes: + - type: SpRuntimeDispatchError + value: BadOrigin - name: xcmPallet.limitedReserveTransferAssets before: *before_get_balances @@ -203,23 +213,22 @@ tests: args: [ *ap_dest, # destination *ap_benf, # beneficiary - { v1: [ *rc_ksm_fungible ] }, # assets + { v3: [ *rc_ksm_fungible ] }, # assets 0, # feeAssetItem { unlimited: true } # weightLimit ] events: - name: xcmPallet.Attempted - attribute: - type: XcmV2TraitsOutcome - isComplete: true - threshold: [10, 10] - value: 750,645,000 + attributes: + - type: XcmV3TraitsOutcome + xcmOutcome: Complete + value: {"refTime":"2,000,000,000","proofSize":"0"} - name: dmpQueue.ExecutedDownward chain: *assets_parachain - attribute: - type: XcmV2TraitsOutcome - isError: true - value: "WeightNotComputable" + attributes: + - type: XcmV3TraitsOutcome + xcmOutcome: Incomplete + value: [{"refTime":"1,000,000,000","proofSize":"0"},"UntrustedReserveLocation"] - queries: balance_rc_sender_after: chain: *relay_chain diff --git a/parachains/integration-tests/statemint/xcm/2_ump.yml b/parachains/integration-tests/e2e/assets/statemint/0_xcm/2_ump.yml similarity index 72% rename from parachains/integration-tests/statemint/xcm/2_ump.yml rename to parachains/integration-tests/e2e/assets/statemint/0_xcm/2_ump.yml index f51823eb3e8..d839375320b 100644 --- a/parachains/integration-tests/statemint/xcm/2_ump.yml +++ b/parachains/integration-tests/e2e/assets/statemint/0_xcm/2_ump.yml @@ -2,28 +2,28 @@ settings: chains: relay_chain: &relay_chain - wsPort: 9900 + wsPort: 9800 assets_parachain: &assets_parachain - wsPort: 9910 + wsPort: 9810 paraId: &ap_id 1000 variables: common: amount: &amount 1000000000000 - require_weight_at_most: &weight_at_most 1000000000 + require_weight_at_most: &weight_at_most {refTime: 1000000000, proofSize: 0} relay_chain: signer: &rc_signer //Alice wallet: &rc_wallet HNZata7iMYWmk5RvZRTiAsSDhV8366zq2YGb3tLH5Upf74F - assets_parachain_destination: &ap_dest { v1: { 0, interior: { x1: { parachain: *ap_id }}}} + assets_parachain_destination: &ap_dest { v3: { 0, interior: { x1: { parachain: *ap_id }}}} assets_parachain_account: &ap_acc '0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d' - assets_parachain_beneficiary: &ap_benf {v1: { parents: 0, interior: { x1: { accountId32: { network: { any: true }, id: *ap_acc }}}}} + assets_parachain_beneficiary: &ap_benf {v3: { parents: 0, interior: { x1: { accountId32: { id: *ap_acc }}}}} ksm: &rc_ksm { concrete: { 0, interior: { here: true }}} ksm_fungible: &rc_ksm_fungible { id: *rc_ksm, fun: { fungible: *amount }} assets_parachain_account: signer: &ap_signer //Alice wallet: &ap_wallet HNZata7iMYWmk5RvZRTiAsSDhV8366zq2YGb3tLH5Upf74F - relay_chain_destination: &rc_dest { v1: { parents: 1, interior: { here: true }}} + relay_chain_destination: &rc_dest { v3: { parents: 1, interior: { here: true }}} assets_parachain_account: &rc_acc '0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d' - relay_chain_beneficiary: &rc_benf {v1: { parents: 0, interior: { x1: { accountId32: { network: { any: true }, id: *rc_acc }}}}} + relay_chain_beneficiary: &rc_benf {v3: { parents: 0, interior: { x1: { accountId32: { id: *rc_acc }}}}} ksm: &ap_ksm { concrete: { parents: 1, interior: { here: true }}} ksm_fungible: &ap_ksm_fungible { id: *ap_ksm, fun: { fungible: *amount }} decodedCalls: @@ -38,7 +38,7 @@ tests: describes: - name: polkadotXcm.limitedTeleportAssets before: - - name: DEPENDANCY | Do a 'limitedTeleportAssets' from the Relay Chain to the Assets Parachain to have funds to send them back + - name: DEPENDENCY | Do a 'limitedTeleportAssets' from the Relay Chain to the Assets Parachain to have funds to send them back actions: - extrinsics: - chain: *relay_chain @@ -48,22 +48,23 @@ tests: args: [ *ap_dest, # destination *ap_benf, # beneficiary - { v1: [ *rc_ksm_fungible ] }, # assets + { v3: [ *rc_ksm_fungible ] }, # assets 0, # feeAssetItem { unlimited: true } # weightLimit ] events: - name: xcmPallet.Attempted - attribute: - type: XcmV2TraitsOutcome - isComplete: true + attributes: + - type: XcmV3TraitsOutcome + xcmOutcome: Complete + value: {"refTime":"3,000,000,000","proofSize":"0"} - name: dmpQueue.ExecutedDownward chain: *assets_parachain - attribute: - type: XcmV2TraitsOutcome - isComplete: true - threshold: [10, 10] - value: 1,021,635,000 + attributes: + - type: XcmV3TraitsOutcome + xcmOutcome: Complete + threshold: [10, 10] + value: {"refTime":"162,909,000","proofSize":"0"} - name: Get the balances of the Assets Parachain's sender & Relay Chain's receiver actions: @@ -90,23 +91,23 @@ tests: args: [ *rc_dest, # destination *rc_benf, # beneficiary - { v1: [ *ap_ksm_fungible ] }, # assets + { v3: [ *ap_ksm_fungible ] }, # assets 0, # feeAssetItem { unlimited: true } # weightLimit ] events: - name: polkadotXcm.Attempted - attribute: - type: XcmV2TraitsOutcome - isComplete: true - threshold: [10, 10] - value: 358,878,000 + attributes: + - type: XcmV3TraitsOutcome + xcmOutcome: Complete + threshold: [10, 10] + value: {"refTime":"533,283,000","proofSize":"7,096"} - name: ump.ExecutedUpward chain: *relay_chain - attribute: - type: XcmV2TraitsOutcome - isComplete: true - value: 4,000,000,000 + attributes: + - type: XcmV3TraitsOutcome + xcmOutcome: Complete + value: {"refTime":"4,000,000,000","proofSize":"0"} - queries: balance_ap_sender_after: chain: *assets_parachain @@ -148,7 +149,7 @@ tests: - name: polkadotXcm.send | Native - Transact(system.remark) its: - - name: Assets Parachain SHOULD NOT be able to dipatch 'send' call + - name: Assets Parachain SHOULD NOT be able to dispatch 'send' call actions: - extrinsics: - chain: *assets_parachain @@ -158,7 +159,12 @@ tests: args: [ *rc_dest, # destination { - v2: [ #message + v3: [ #message + { + UnpaidExecution: { + weightLimit: Unlimited + } + }, { Transact: { originType: Native, @@ -171,9 +177,9 @@ tests: ] events: - name: system.ExtrinsicFailed - attribute: - type: SpRuntimeDispatchError - value: BadOrigin + attributes: + - type: SpRuntimeDispatchError + value: BadOrigin - name: polkadotXcm.limitedReserveTransferAssets its: @@ -187,13 +193,13 @@ tests: args: [ *rc_dest, # destination *rc_benf, # beneficiary - { v1: [ *ap_ksm_fungible ] }, # assets + { v3: [ *ap_ksm_fungible ] }, # assets 0, # feeAssetItem { unlimited: true } # weightLimit ] events: - name: polkadotXcm.Attempted - attribute: - type: XcmV2TraitsOutcome - isError: true - value: Barrier + attributes: + - type: XcmV3TraitsOutcome + xcmOutcome: Error + value: Barrier diff --git a/parachains/integration-tests/e2e/assets/statemint/0_xcm/3_hrmp-open-channels.yml b/parachains/integration-tests/e2e/assets/statemint/0_xcm/3_hrmp-open-channels.yml new file mode 100644 index 00000000000..a274282df30 --- /dev/null +++ b/parachains/integration-tests/e2e/assets/statemint/0_xcm/3_hrmp-open-channels.yml @@ -0,0 +1,132 @@ +--- +settings: + chains: + relay_chain: &relay_chain + wsPort: 9800 + assets_parachain: &assets_parachain + wsPort: 9810 + paraId: &ap_id 1000 + penpal_parachain: &penpal_parachain + wsPort: 9820 + paraId: &pp_id 2000 + variables: + common: + amount: &amount 2000000000000 + require_weight_at_most: &weight_at_most {refTime: 1000000000, proofSize: 20000} + hrmp_channels: + proposed_max_capacity: &max_capacity 8 + proposed_max_message_size: &max_message_size 8192 + channel: &channel { + maxCapacity: 8, + maxTotalSize: 8192, + maxMessageSize: 8192, + msgCount: 0, + totalSize: 0, + mqcHead: null, + senderDeposit: 0, + recipientDeposit: 0 + } + chains: + relay_chain: + signer: &rc_signer //Alice + assets_parachain_destination: &ap_dest { v3: { 0, interior: { x1: { parachain: *ap_id }}}} + ksm: &rc_ksm { concrete: { 0, interior: { here: true }}} + ksm_fungible: &rc_ksm_fungible { id: *rc_ksm, fun: { fungible: *amount }} + assets_parachain_account: + sovereign_account: &ap_sovereign 5Ec4AhPZk8STuex8Wsi9TwDtJQxKqzPJRCH7348Xtcs9vZLJ + relay_chain_destination: &rc_dest { v3: { parents: 1, interior: { here: true }}} + penpal_parachain: + sovereign_account: &pp_sovereign F7fq1jMZkfuCuoMTyiEVAP2DMpMt18WopgBqTJznLihLNbZ + signer: &pp_signer //Alice + +tests: + - name: HRMP + beforeEach: + - name: DEPENDENCY | Penpal Parachain Sovereign account in the Relay Chain needs to be funded + actions: + - extrinsics: + - chain: *relay_chain + signer: *rc_signer + pallet: balances + call: transfer + args: [ + *pp_sovereign, # destination + *amount, # value + ] + events: + - name: balances.Transfer + + - name: DEPENDENCY | Assets Parachain Sovereign account in the Relay Chain needs to be funded + actions: + - extrinsics: + - chain: *relay_chain + signer: *rc_signer + pallet: balances + call: transfer + args: [ + *ap_sovereign, # destination + *amount, # value + ] + events: + - name: balances.Transfer + describes: + - name: hrmp.hrmpInitOpenChannel (Penpal Parachain → Assets Parachain) + its: + - name: Open Penpal Parachain to Assets Parachain + actions: + - extrinsics: + - chain: *relay_chain + signer: *rc_signer + sudo: true + pallet: hrmp + call: forceOpenHrmpChannel + args: [ + 2000, + 1000, + 8, + 8192 + ] + events: + - name: sudo.Sudid + attributes: + - type: Result + value: Ok + - name: hrmp.HrmpChannelForceOpened + - name: hrmp.hrmpInitOpenChannel (Assets Parachain → PenPal Parachain) + its: + - name: Open Assets Parachain to PenPal Parachain + actions: + - extrinsics: + - chain: *relay_chain + signer: *rc_signer + sudo: true + pallet: hrmp + call: forceOpenHrmpChannel + args: [ + 1000, + 2000, + 8, + 8192 + ] + events: + - name: sudo.Sudid + attributes: + - type: Result + value: Ok + - name: hrmp.HrmpChannelForceOpened + - name: hrmp.forceProcessHrmpOpen (make sure all the channels are open) + its: + - name: Make sure all the pending channels are open + actions: + - extrinsics: + - chain: *relay_chain + signer: *rc_signer + sudo: true + pallet: hrmp + call: forceProcessHrmpOpen + args: [ 2 ] + events: + - name: sudo.Sudid + attributes: + - type: Result + value: Ok diff --git a/parachains/integration-tests/e2e/assets/statemint/0_xcm/4_hrmp.yml b/parachains/integration-tests/e2e/assets/statemint/0_xcm/4_hrmp.yml new file mode 100644 index 00000000000..c36192fd5a3 --- /dev/null +++ b/parachains/integration-tests/e2e/assets/statemint/0_xcm/4_hrmp.yml @@ -0,0 +1,401 @@ +--- +settings: + chains: + relay_chain: &relay_chain + wsPort: 9800 + assets_parachain: &assets_parachain + wsPort: 9810 + paraId: &ap_id 1000 + penpal_parachain: &penpal_parachain + wsPort: 9820 + paraId: &pp_id 2000 + variables: + common: + mint_amount: &mint_amount 1000000000000 + amount: &amount 1000000000000 + require_weight_at_most: &weight_at_most {refTime: 1200000000, proofSize: 20000} + amount_to_send: &amount_to_send 500000000000 + chains: + relay_chain: + signer: &rc_signer //Alice + assets_parachain_destination: &ap_dest { v3: { 0, interior: { x1: { parachain: *ap_id }}}} + assets_parachain_dest_routed: &ap_dest_routed { v3: { parents: 1, interior: { x1: { parachain: *ap_id } }}} + assets_parachain_account: + signer: &ap_signer //Alice + wallet: &ap_wallet HNZata7iMYWmk5RvZRTiAsSDhV8366zq2YGb3tLH5Upf74F + asset_id: &asset_id 2 + assets_pallet_id: &assets_pallet_id 50 + asset_min_balance: &asset_ed 1000 + penpal_parachain_destination: &pp_dest { v3: { parents: 1, interior: { x1: { parachain: *pp_id } }}} + ksm: &ap_ksm { concrete: { parents: 1, interior: { here: true }}} + ksm_fungible: &ap_ksm_fungible { id: *ap_ksm, fun: { fungible: *amount }} + suff_asset: &suff_asset { concrete: { parents: 0, interior: { x2: [ { PalletInstance: *assets_pallet_id }, { GeneralIndex: *asset_id } ] }}} + suff_asset_fail: &suff_asset_fail { concrete: { parents: 0, interior: { x2: [ { PalletInstance: *assets_pallet_id }, { GeneralIndex: 3 } ] }}} + suff_asset_fungible_fail: &ap_suff_asset_fungible_fail { id: *suff_asset_fail, fun: { fungible: 200000000000 }} + penpal_parachain: + sovereign_account: &pp_sovereign_sibl 13cKp89Msu7M2PiaCuuGr1BzAsD5V3vaVbDMs3YtjMZHdGwR + signer: &pp_signer //Alice + penpal_parachain_account: &pp_acc '0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d' + decodedCalls: + force_create_asset: + chain: *assets_parachain + pallet: assets + call: forceCreate + args: [ + *asset_id, + { Id: *ap_wallet }, # owner + true, # isSufficient + *asset_ed # minBalance + ] + force_create_asset2: + chain: *assets_parachain + pallet: assets + call: forceCreate + args: [ + *asset_id, + { Id: *ap_wallet }, # owner + true, # isSufficient + *asset_ed # minBalance + ] + +tests: + - name: HRMP + describes: + - name: polkadotXcm.limitedReserveTransferAssets (Asset) | Assets Parachain -> Penpal Parachain + before: + - name: DEPENDENCY | A sufficient Asset should exist in the Assets Parachain + actions: + - extrinsics: + - chain: *relay_chain + signer: *rc_signer + sudo: true + pallet: xcmPallet + call: send + args: [ + *ap_dest, # destination + { + v3: [ #message + { + UnpaidExecution: { + weightLimit: Unlimited + } + }, + { + SetTopic: "0x0123456789012345678901234567891201234567890123456789012345678912" + }, + { + Transact: { + originKind: Superuser, + requireWeightAtMost: *weight_at_most, + call: $force_create_asset + } + } + ] + } + ] + events: + - name: xcmPallet.Sent + - name: dmpQueue.ExecutedDownward + chain: *assets_parachain + attributes: + - type: XcmV3TraitsOutcome + xcmOutcome: Complete + threshold: [10, 10] + value: {"refTime":"1,218,405,000","proofSize":"20,000"} + - queries: + forced_created_asset: + chain: *assets_parachain + pallet: assets + call: asset + args: [ *asset_id ] + - asserts: + isSome: + args: [ $forced_created_asset ] + + - name: DEPENDENCY | Some Assets should be minted for the sender + actions: + - extrinsics: + - chain: *assets_parachain + signer: *ap_signer + pallet: assets + call: mint + args: [ + *asset_id, + *ap_wallet, + *mint_amount + ] + events: + - name: assets.Issued + + its: + - name: Assets Parachain should be able to reserve transfer an Asset to Penpal Parachain + actions: + - extrinsics: + - chain: *assets_parachain + signer: *ap_signer + pallet: polkadotXcm + call: limitedReserveTransferAssets + args: [ + *pp_dest, # destination + { # beneficiary + V3: { + parents: 0, + interior: { + X1: { + AccountId32: { + id: *pp_acc + } + } + } + } + }, + { # assets + V3: [ + { + id: { + Concrete: { + parents: 0, + interior: { + X2: [ + { + PalletInstance: *assets_pallet_id + }, + { + GeneralIndex: *asset_id + } + ] + } + } + }, + fun: { + Fungible: *amount_to_send + } + } + ] + }, + 0, # feeAssetItem + Unlimited # weightLimit + ] + events: + - name: polkadotXcm.Attempted + attributes: + - type: XcmV3TraitsOutcome + xcmOutcome: Complete + threshold: [10, 10] + value: {"refTime":"673,627,000","proofSize":"6,196"} + - name: assets.Transferred + attributes: + - type: AccountId32 + value: *pp_sovereign_sibl + - name: assets.Transferred + attributes: + - type: u128 + value: *amount_to_send + + - name: polkadotXcm.limitedReserveTransferAssets (KSM) | Assets Parachain -> Penpal Parachain + its: + - name: Assets Parachain should be able to reserve transfer KSM to Penpal Parachain + actions: + - extrinsics: + - chain: *assets_parachain + signer: *ap_signer + pallet: polkadotXcm + call: limitedReserveTransferAssets + args: [ + *pp_dest, # destination + { # beneficiary + V3: { + parents: 0, + interior: { + X1: { + AccountId32: { + id: *pp_acc + } + } + } + } + }, + { # assets + V3: [ + *ap_ksm_fungible + ] + }, + 0, # feeAssetItem + Unlimited # weightLimit + ] + events: + - name: polkadotXcm.Attempted + attributes: + - type: XcmV3TraitsOutcome + xcmOutcome: Complete + threshold: [10, 10] + value: {"refTime":"673,627,000","proofSize":"6,196"} + - name: balances.Endowed + attributes: + - type: AccountId32 + value: *pp_sovereign_sibl + - name: balances.Endowed + attributes: + - type: u128 + value: *amount + + - name: polkadotXcm.send( assets.forceCreateAsset ) | Penpal Parachain -> Assets Parachain + before: + - name: Get the asset balance of the Penpal Parachain Sovereign account in Assets Parachain + actions: + - queries: + assets_balance_pp_sovereign_before: + chain: *assets_parachain + pallet: assets + call: account + args: [ + *asset_id, + *pp_sovereign_sibl + ] + its: + - name: Penpal Parachain should be able to send XCM message paying its fee with sufficient asset in Assets Parachain + actions: + - extrinsics: + - chain: *penpal_parachain + signer: *pp_signer + sudo: true + pallet: polkadotXcm + call: send + args: [ + *ap_dest_routed, # destination + { + v3: [ #message + { + WithdrawAsset: [ + { + id: { + concrete: { + parents: 0, + interior: { + X2: [ + { PalletInstance: *assets_pallet_id }, + { GeneralIndex: *asset_id } + ] + } + } + }, + fun: { fungible: *amount_to_send }} + ] + }, + { + BuyExecution: { + fees: { id: *suff_asset, fun: { fungible: *amount_to_send }}, + weightLimit: Unlimited + } + }, + { + Transact: { + originKind: SovereignAccount, + requireWeightAtMost: *weight_at_most, + call: $force_create_asset2 + } + }, + { + RefundSurplus + }, + { + DepositAsset: { + assets: { Wild: All }, + beneficiary: { + parents: 0, + interior: { + X1: { + AccountId32: { + network: , # None + id: *pp_acc + } + } + }} + } + } + ] + } + ] + events: + - name: sudo.Sudid + attributes: + - type: Result + value: Ok + - name: polkadotXcm.Sent + - name: assets.Burned + chain: *assets_parachain + attributes: + - type: AccountId32 + value: *pp_sovereign_sibl + - name: assets.Issued + chain: *assets_parachain + attributes: + - type: u32 + value: *asset_id + - queries: + assets_balance_pp_sovereign_after: + chain: *assets_parachain + pallet: assets + call: account + args: [ + *asset_id, + *pp_sovereign_sibl + ] + forced_created_asset2: + chain: *assets_parachain + pallet: assets + call: asset + args: [ 3 ] + - asserts: + isSome: + args: [ $forced_created_asset2 ] + - name: Should reduce the assets balance of the Penpal Parachain's SovereignAccount in the Assets Parachain + actions: + - asserts: + assetsDecreased: + args: [ + { + balances: { + before: $assets_balance_pp_sovereign_before, + after: $assets_balance_pp_sovereign_after, + }, + } + ] + + - name: Penpal Parachain SHOULD NOT be able to send XCM message paying its fee with sufficient assets if not enough balance + actions: + - extrinsics: + - chain: *penpal_parachain + signer: *pp_signer + sudo: true + pallet: polkadotXcm + call: send + args: [ + *ap_dest_routed, # destination + { + v3: [ #message + { + WithdrawAsset: [*ap_suff_asset_fungible_fail] + }, + { + BuyExecution: { + fees: *ap_suff_asset_fungible_fail, + weightLimit: Unlimited + } + }, + { + Transact: { + originKind: SovereignAccount, + requireWeightAtMost: *weight_at_most, + call: $force_create_asset2 + } + } + ] + } + ] + events: + - name: xcmpQueue.Fail + chain: *assets_parachain + attributes: + - type: XcmV3TraitsError + value: FailedToTransactAsset diff --git a/parachains/integration-tests/e2e/assets/statemint/config.toml b/parachains/integration-tests/e2e/assets/statemint/config.toml new file mode 100644 index 00000000000..5b5a861eed6 --- /dev/null +++ b/parachains/integration-tests/e2e/assets/statemint/config.toml @@ -0,0 +1,71 @@ +[relaychain] +default_command = "./bin/polkadot" +default_args = [ "-lparachain=debug", "-lxcm=trace" ] +chain = "polkadot-local" + + [[relaychain.nodes]] + name = "alice" + ws_port = 9800 + validator = true + + [[relaychain.nodes]] + name = "bob" + ws_port = 9801 + validator = true + + [[relaychain.nodes]] + name = "charlie" + ws_port = 9802 + validator = true + + [[relaychain.nodes]] + name = "dave" + ws_port = 9803 + validator = true + +[[parachains]] +id = 1000 +chain = "statemint-local" +cumulus_based = true + + [[parachains.collators]] + name = "collator1" + ws_port = 9810 + command = "./bin/polkadot-parachain" + args = [ "-lxcm=trace" ] + + [[parachains.collators]] + name = "collator2" + ws_port = 9811 + command = "./bin/polkadot-parachain" + args = [ "-lxcm=trace" ] + + +[[parachains]] +id = 2000 +chain = "penpal-polkadot-2000" +cumulus_based = true + + [[parachains.collators]] + name = "collator3" + ws_port = 9820 + command = "./bin/polkadot-parachain" + args = [ "-lxcm=trace" ] + + [[parachains.collators]] + name = "collator4" + ws_port = 9821 + command = "./bin/polkadot-parachain" + args = [ "-lxcm=trace" ] + +# [[hrmpChannels]] +# sender = 1000 +# recipient = 2000 +# maxCapacity = 8 +# maxMessageSize = 8192 + +# [[hrmpChannels]] +# sender = 2000 +# recipient = 1000 +# maxCapacity = 8 +# maxMessageSize = 8192 diff --git a/parachains/integration-tests/collectives/0_xcm/0_init.yml b/parachains/integration-tests/e2e/collectives/collectives_polkadot/0_xcm/0_init.yml similarity index 97% rename from parachains/integration-tests/collectives/0_xcm/0_init.yml rename to parachains/integration-tests/e2e/collectives/collectives_polkadot/0_xcm/0_init.yml index 48a86f9136e..4dadb9f0116 100644 --- a/parachains/integration-tests/collectives/0_xcm/0_init.yml +++ b/parachains/integration-tests/e2e/collectives/collectives_polkadot/0_xcm/0_init.yml @@ -67,7 +67,7 @@ tests: v3: [ # message { UnpaidExecution: { - weightLimit: { + weightLimit: { limited: { refTime: 2200000000, # 2_200_000_000 proofSize: 200000, # 200_000 @@ -79,7 +79,7 @@ tests: Transact: { originKind: Superuser, requireWeightAtMost: { - refTime: 200000000, # 200_000_000 + refTime: 200000000, # 200_000_000 proofSize: 0, }, call: $ap_force_xcm_version diff --git a/parachains/integration-tests/collectives/0_xcm/1_teleport.yml b/parachains/integration-tests/e2e/collectives/collectives_polkadot/0_xcm/1_teleport.yml similarity index 96% rename from parachains/integration-tests/collectives/0_xcm/1_teleport.yml rename to parachains/integration-tests/e2e/collectives/collectives_polkadot/0_xcm/1_teleport.yml index 2b1a6bba8f1..e6310d05922 100644 --- a/parachains/integration-tests/collectives/0_xcm/1_teleport.yml +++ b/parachains/integration-tests/e2e/collectives/collectives_polkadot/0_xcm/1_teleport.yml @@ -39,19 +39,19 @@ tests: args: [ { v3: { 0, interior: { x1: { parachain: *cp_id }}}}, # destination { v3: { parents: 0, interior: { x1: { accountId32: { id: *acc_alice_acc32 }}}}}, # beneficiary - { - v3: [ - # { + { + v3: [ + # { # # TODO use a separate Assets to pay a fee, to receive an exact amount of assets on beneficiary account. # # a call with two assets fails with an error right now. - # id: { concrete: { 0, interior: { here: true }}}, - # fun: { fungible: 1000000000000 } # 1_000_000_000_000 + # id: { concrete: { 0, interior: { here: true }}}, + # fun: { fungible: 1000000000000 } # 1_000_000_000_000 # }, - { - id: { concrete: { 0, interior: { here: true }}}, + { + id: { concrete: { 0, interior: { here: true }}}, fun: { fungible: 20000000000000 } # 20_000_000_000_000 } - ] + ] }, # assets 0, # feeAssetItem ] @@ -109,13 +109,13 @@ tests: args: [ { v3: { parents: 1, interior: { here: true }}}, # destination { v3: { parents: 0, interior: { x1: { accountId32: { id: *acc_alice_acc32 }}}}}, # beneficiary - { - v3: [ - { - id: { concrete: { parents: 1, interior: { here: true }}}, + { + v3: [ + { + id: { concrete: { parents: 1, interior: { here: true }}}, fun: { fungible: 10000000000000 } # 10_000_000_000_000 } - ] + ] }, # assets 0, # feeAssetItem ] diff --git a/parachains/integration-tests/collectives/0_xcm/2_reserve.yml b/parachains/integration-tests/e2e/collectives/collectives_polkadot/0_xcm/2_reserve.yml similarity index 94% rename from parachains/integration-tests/collectives/0_xcm/2_reserve.yml rename to parachains/integration-tests/e2e/collectives/collectives_polkadot/0_xcm/2_reserve.yml index ac42ca4a4b0..b152d71de3a 100644 --- a/parachains/integration-tests/collectives/0_xcm/2_reserve.yml +++ b/parachains/integration-tests/e2e/collectives/collectives_polkadot/0_xcm/2_reserve.yml @@ -26,13 +26,13 @@ tests: args: [ { v3: { 0, interior: { x1: { parachain: *cp_id }}}}, # destination { v3: { parents: 0, interior: { x1: { accountId32: { id: *alice_acc32 }}}}}, # beneficiary - { - v3: [ - { - id: { concrete: { 0, interior: { here: true }}}, + { + v3: [ + { + id: { concrete: { 0, interior: { here: true }}}, fun: { fungible: 20000000000000 } # 20_000_000_000_000 } - ] + ] }, # assets 0, # feeAssetItem ] diff --git a/parachains/integration-tests/collectives/1_alliance/0_join_alliance_fails.yml b/parachains/integration-tests/e2e/collectives/collectives_polkadot/1_alliance/0_join_alliance_fails.yml similarity index 100% rename from parachains/integration-tests/collectives/1_alliance/0_join_alliance_fails.yml rename to parachains/integration-tests/e2e/collectives/collectives_polkadot/1_alliance/0_join_alliance_fails.yml diff --git a/parachains/integration-tests/collectives/1_alliance/1_init_alliance.yml b/parachains/integration-tests/e2e/collectives/collectives_polkadot/1_alliance/1_init_alliance.yml similarity index 96% rename from parachains/integration-tests/collectives/1_alliance/1_init_alliance.yml rename to parachains/integration-tests/e2e/collectives/collectives_polkadot/1_alliance/1_init_alliance.yml index 8e9adbbeb47..26bd72a7967 100644 --- a/parachains/integration-tests/collectives/1_alliance/1_init_alliance.yml +++ b/parachains/integration-tests/e2e/collectives/collectives_polkadot/1_alliance/1_init_alliance.yml @@ -24,7 +24,7 @@ settings: ava_account32: &acc_ava_acc32 "0x348ef0b8776adbc09c862ddc29b1d193b9e24738e54eea3b0609c83856dc101c" mia_signer: &acc_mia_signer //Mia mia_account32: &acc_mia_acc32 "0xaebf15374cf7e758d10232514c569a7abf81cc1b8f1e81a73dbc608a0e335264" - decodedCalls: + decodedCalls: init_alliance_members: chain: *collectives_parachain pallet: alliance @@ -86,7 +86,7 @@ tests: v3: [ # message { UnpaidExecution: { - weightLimit: { + weightLimit: { limited: { refTime: 3000000000, # 3_000_000_000 proofSize: 2000000, # 2_000_000 @@ -98,7 +98,7 @@ tests: Transact: { originKind: Superuser, requireWeightAtMost: { - refTime: 1000000000, # 1_000_000_000 + refTime: 1000000000, # 1_000_000_000 proofSize: 1000000, # 1_000_000 }, call: $init_alliance_members @@ -120,7 +120,7 @@ tests: attributes: - type: XcmV3TraitsOutcome xcmOutcome: Complete - + - name: Alliance init call fails. actions: - extrinsics: @@ -135,7 +135,7 @@ tests: v3: [ # message { UnpaidExecution: { - weightLimit: { + weightLimit: { limited: { refTime: 3000000000, # 3_000_000_000 proofSize: 2000000, # 2_000_000 @@ -147,7 +147,7 @@ tests: Transact: { originKind: Superuser, requireWeightAtMost: { - refTime: 1000000000, # 1_000_000_000 + refTime: 1000000000, # 1_000_000_000 proofSize: 1000000, # 1_000_000 }, call: $init_alliance_voting_members @@ -186,7 +186,7 @@ tests: v3: [ # message { UnpaidExecution: { - weightLimit: { + weightLimit: { limited: { refTime: 5000000000, # 3_000_000_000 proofSize: 1000000, # 1_000_000 @@ -244,7 +244,7 @@ tests: v3: [ # message { UnpaidExecution: { - weightLimit: { + weightLimit: { limited: { refTime: 3000000000, # 3_000_000_000 proofSize: 2000000, # 2_000_000 @@ -256,7 +256,7 @@ tests: Transact: { originKind: Superuser, requireWeightAtMost: { - refTime: 1000000000, # 1_000_000_000 + refTime: 1000000000, # 1_000_000_000 proofSize: 1000000, # 1_000_000 }, call: $init_alliance_members @@ -278,4 +278,3 @@ tests: attributes: - type: XcmV3TraitsOutcome xcmOutcome: Complete - diff --git a/parachains/integration-tests/collectives/1_alliance/2_join_alliance_fails.yml b/parachains/integration-tests/e2e/collectives/collectives_polkadot/1_alliance/2_join_alliance_fails.yml similarity index 100% rename from parachains/integration-tests/collectives/1_alliance/2_join_alliance_fails.yml rename to parachains/integration-tests/e2e/collectives/collectives_polkadot/1_alliance/2_join_alliance_fails.yml diff --git a/parachains/integration-tests/collectives/1_alliance/3_kick_member.yml b/parachains/integration-tests/e2e/collectives/collectives_polkadot/1_alliance/3_kick_member.yml similarity index 98% rename from parachains/integration-tests/collectives/1_alliance/3_kick_member.yml rename to parachains/integration-tests/e2e/collectives/collectives_polkadot/1_alliance/3_kick_member.yml index 62c61787e21..aac09883375 100644 --- a/parachains/integration-tests/collectives/1_alliance/3_kick_member.yml +++ b/parachains/integration-tests/e2e/collectives/collectives_polkadot/1_alliance/3_kick_member.yml @@ -125,7 +125,7 @@ tests: v3: [ #message { UnpaidExecution: { - weightLimit: { + weightLimit: { limited: { refTime: 4000000000, # 4_000_000_000 proofSize: 2000000, # 2_000_000 @@ -137,7 +137,7 @@ tests: Transact: { originKind: Superuser, requireWeightAtMost: { - refTime: 2000000000, # 2_000_000_000 + refTime: 2000000000, # 2_000_000_000 proofSize: 1000000, # 1_000_000 }, call: $alliance_kick_member diff --git a/parachains/integration-tests/collectives/config.toml b/parachains/integration-tests/e2e/collectives/collectives_polkadot/config.toml similarity index 84% rename from parachains/integration-tests/collectives/config.toml rename to parachains/integration-tests/e2e/collectives/collectives_polkadot/config.toml index 9d138be11ba..d99e38078d0 100644 --- a/parachains/integration-tests/collectives/config.toml +++ b/parachains/integration-tests/e2e/collectives/collectives_polkadot/config.toml @@ -10,10 +10,17 @@ chain = "polkadot-local" [[relaychain.nodes]] name = "bob" + ws_port = 9701 validator = true [[relaychain.nodes]] name = "charlie" + ws_port = 9702 + validator = true + + [[relaychain.nodes]] + name = "dave" + ws_port = 9703 validator = true [[parachains]] @@ -29,5 +36,6 @@ cumulus_based = true [[parachains.collators]] name = "collator2" + ws_port = 9711 command = "./bin/polkadot-parachain" args = ["-lxcm=trace"] diff --git a/parachains/integration-tests/emulated/assets/statemint/Cargo.toml b/parachains/integration-tests/emulated/assets/statemint/Cargo.toml new file mode 100644 index 00000000000..8c6077b67e4 --- /dev/null +++ b/parachains/integration-tests/emulated/assets/statemint/Cargo.toml @@ -0,0 +1,36 @@ +[package] +name = "statemint-it" +version = "1.0.0" +authors = ["Parity Technologies "] +edition = "2021" +description = "Statemint parachain runtime integration tests with xcm-emulator" + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false } + +# Substrate +sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } +frame-support = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } +frame-system = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } +sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } +sp-weights = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-balances = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-assets = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } + +# Polkadot +polkadot-core-primitives = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "master" } +polkadot-parachain = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "master" } +polkadot-runtime-parachains = { git = "https://github.com/paritytech/polkadot", branch = "master" } +polkadot-runtime = { git = "https://github.com/paritytech/polkadot", branch = "master" } +xcm = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "master" } +xcm-executor = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "master" } +pallet-xcm = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "master" } + +# Cumulus +parachains-common = { path = "../../../../common" } +penpal-runtime = { path = "../../../../runtimes/testing/penpal" } +statemint-runtime = { path = "../../../../runtimes/assets/statemint" } + +# Local +xcm-emulator = { default-features = false, path = "../../../../../xcm/xcm-emulator" } +integration-tests-common = { default-features = false, path = "../../common" } diff --git a/parachains/integration-tests/emulated/assets/statemint/src/lib.rs b/parachains/integration-tests/emulated/assets/statemint/src/lib.rs new file mode 100644 index 00000000000..f7ca680a800 --- /dev/null +++ b/parachains/integration-tests/emulated/assets/statemint/src/lib.rs @@ -0,0 +1,33 @@ +pub use codec::Encode; +pub use frame_support::{ + assert_ok, instances::Instance1, pallet_prelude::Weight, traits::fungibles::Inspect, +}; +pub use integration_tests_common::{ + constants::{ + accounts::{ALICE, BOB}, + polkadot::ED as POLKADOT_ED, + PROOF_SIZE_THRESHOLD, REF_TIME_THRESHOLD, XCM_V3, + }, + AccountId, BHKusama, BHKusamaPallet, BHKusamaReceiver, BHKusamaSender, BHPolkadot, + BHPolkadotPallet, BHPolkadotReceiver, BHPolkadotSender, Collectives, CollectivesPallet, + CollectivesReceiver, CollectivesSender, Kusama, KusamaMockNet, KusamaPallet, KusamaReceiver, + KusamaSender, PenpalKusama, PenpalKusamaReceiver, PenpalKusamaSender, PenpalPolkadot, + PenpalPolkadotReceiver, PenpalPolkadotSender, Polkadot, PolkadotMockNet, PolkadotPallet, + PolkadotReceiver, PolkadotSender, Statemine, StateminePallet, StatemineReceiver, + StatemineSender, Statemint, StatemintPallet, StatemintReceiver, StatemintSender, +}; +pub use polkadot_core_primitives::InboundDownwardMessage; +pub use xcm::{ + prelude::*, + v3::{ + Error, + NetworkId::{Kusama as KusamaId, Polkadot as PolkadotId}, + }, +}; +pub use xcm_emulator::{ + assert_expected_events, bx, cumulus_pallet_dmp_queue, helpers::weight_within_threshold, + Parachain as Para, RelayChain as Relay, TestExt, +}; + +#[cfg(test)] +mod tests; diff --git a/parachains/integration-tests/emulated/assets/statemint/src/tests/mod.rs b/parachains/integration-tests/emulated/assets/statemint/src/tests/mod.rs new file mode 100644 index 00000000000..996f9fd0aae --- /dev/null +++ b/parachains/integration-tests/emulated/assets/statemint/src/tests/mod.rs @@ -0,0 +1,3 @@ +mod reserve_transfer; +mod teleport; +mod transact; diff --git a/parachains/integration-tests/emulated/assets/statemint/src/tests/reserve_transfer.rs b/parachains/integration-tests/emulated/assets/statemint/src/tests/reserve_transfer.rs new file mode 100644 index 00000000000..55d201c5608 --- /dev/null +++ b/parachains/integration-tests/emulated/assets/statemint/src/tests/reserve_transfer.rs @@ -0,0 +1,63 @@ +use crate::*; + +#[test] +fn reserve_transfer_native_asset_from_relay_to_assets() { + // Init tests variables + let amount = POLKADOT_ED * 1000; + let relay_sender_balance_before = Polkadot::account_data_of(PolkadotSender::get()).free; + let para_receiver_balance_before = Statemint::account_data_of(StatemintReceiver::get()).free; + + let origin = ::RuntimeOrigin::signed(PolkadotSender::get()); + let assets_para_destination: VersionedMultiLocation = + Polkadot::child_location_of(Statemint::para_id()).into(); + let beneficiary: VersionedMultiLocation = + AccountId32 { network: None, id: StatemintReceiver::get().into() }.into(); + let native_assets: VersionedMultiAssets = (Here, amount).into(); + let fee_asset_item = 0; + let weight_limit = WeightLimit::Unlimited; + + // Send XCM message from Relay Chain + Polkadot::execute_with(|| { + assert_ok!(::XcmPallet::limited_reserve_transfer_assets( + origin, + bx!(assets_para_destination), + bx!(beneficiary), + bx!(native_assets), + fee_asset_item, + weight_limit, + )); + + type RuntimeEvent = ::RuntimeEvent; + + assert_expected_events!( + Polkadot, + vec![ + RuntimeEvent::XcmPallet(pallet_xcm::Event::Attempted(Outcome::Complete(weight))) => { + weight: weight_within_threshold((REF_TIME_THRESHOLD, PROOF_SIZE_THRESHOLD), Weight::from_parts(2_000_000_000, 0), *weight), + }, + ] + ); + }); + + // Receive XCM message in Assets Parachain + Statemint::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + assert_expected_events!( + Statemint, + vec![ + RuntimeEvent::DmpQueue(cumulus_pallet_dmp_queue::Event::ExecutedDownward { + outcome: Outcome::Incomplete(_, Error::UntrustedReserveLocation), + .. + }) => {}, + ] + ); + }); + + // Check if balances are updated accordingly in Relay Chain and Assets Parachain + let relay_sender_balance_after = Polkadot::account_data_of(PolkadotSender::get()).free; + let para_sender_balance_after = Statemint::account_data_of(StatemintReceiver::get()).free; + + assert_eq!(relay_sender_balance_before - amount, relay_sender_balance_after); + assert_eq!(para_sender_balance_after, para_receiver_balance_before); +} diff --git a/parachains/integration-tests/emulated/assets/statemint/src/tests/teleport.rs b/parachains/integration-tests/emulated/assets/statemint/src/tests/teleport.rs new file mode 100644 index 00000000000..163db77ddfd --- /dev/null +++ b/parachains/integration-tests/emulated/assets/statemint/src/tests/teleport.rs @@ -0,0 +1,60 @@ +use crate::*; + +#[test] +fn teleport_native_assets_from_relay_to_assets_para() { + // Init tests variables + let amount = POLKADOT_ED * 1000; + let relay_sender_balance_before = Polkadot::account_data_of(PolkadotSender::get()).free; + let para_receiver_balance_before = Statemint::account_data_of(StatemintReceiver::get()).free; + + let origin = ::RuntimeOrigin::signed(PolkadotSender::get()); + let assets_para_destination: VersionedMultiLocation = + Polkadot::child_location_of(Statemint::para_id()).into(); + let beneficiary: VersionedMultiLocation = + AccountId32 { network: None, id: StatemintReceiver::get().into() }.into(); + let native_assets: VersionedMultiAssets = (Here, amount).into(); + let fee_asset_item = 0; + let weight_limit = WeightLimit::Unlimited; + + // Send XCM message from Relay Chain + Polkadot::execute_with(|| { + assert_ok!(::XcmPallet::limited_teleport_assets( + origin, + bx!(assets_para_destination), + bx!(beneficiary), + bx!(native_assets), + fee_asset_item, + weight_limit, + )); + + type RuntimeEvent = ::RuntimeEvent; + + assert_expected_events!( + Polkadot, + vec![ + RuntimeEvent::XcmPallet(pallet_xcm::Event::Attempted(Outcome::Complete { .. })) => {}, + ] + ); + }); + + // Receive XCM message in Assets Parachain + Statemint::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + assert_expected_events!( + Statemint, + vec![ + RuntimeEvent::Balances(pallet_balances::Event::Deposit { who, .. }) => { + who: *who == StatemineReceiver::get().into(), + }, + ] + ); + }); + + // Check if balances are updated accordingly in Relay Chain and Assets Parachain + let relay_sender_balance_after = Polkadot::account_data_of(PolkadotSender::get()).free; + let para_sender_balance_after = Statemint::account_data_of(StatemintReceiver::get()).free; + + assert_eq!(relay_sender_balance_before - amount, relay_sender_balance_after); + assert!(para_sender_balance_after > para_receiver_balance_before); +} diff --git a/parachains/integration-tests/emulated/assets/statemint/src/tests/transact.rs b/parachains/integration-tests/emulated/assets/statemint/src/tests/transact.rs new file mode 100644 index 00000000000..9220d914e47 --- /dev/null +++ b/parachains/integration-tests/emulated/assets/statemint/src/tests/transact.rs @@ -0,0 +1,58 @@ +use crate::*; + +#[test] +fn transact_sudo_from_relay_to_assets_para() { + // Init tests variables + // Call to be executed in Assets Parachain + const ASSET_ID: u32 = 1; + + let call = ::RuntimeCall::Assets(pallet_assets::Call::< + ::Runtime, + Instance1, + >::force_create { + id: ASSET_ID.into(), + is_sufficient: true, + min_balance: 1000, + owner: StatemintSender::get().into(), + }) + .encode() + .into(); + + // XcmPallet send arguments + let sudo_origin = ::RuntimeOrigin::root(); + let assets_para_destination: VersionedMultiLocation = + Polkadot::child_location_of(Statemint::para_id()).into(); + + let weight_limit = WeightLimit::Unlimited; + let require_weight_at_most = Weight::from_parts(1000000000, 200000); + let origin_kind = OriginKind::Superuser; + let check_origin = None; + + let xcm = VersionedXcm::from(Xcm(vec![ + UnpaidExecution { weight_limit, check_origin }, + Transact { require_weight_at_most, origin_kind, call }, + ])); + + // Send XCM message from Relay Chain + Polkadot::execute_with(|| { + assert_ok!(::XcmPallet::send( + sudo_origin, + bx!(assets_para_destination), + bx!(xcm), + )); + + type RuntimeEvent = ::RuntimeEvent; + + assert_expected_events!( + Polkadot, + vec![ + RuntimeEvent::XcmPallet(pallet_xcm::Event::Sent { .. }) => {}, + ] + ); + }); + + // Receive XCM message in Assets Parachain + Statemint::execute_with(|| { + assert!(::Assets::asset_exists(ASSET_ID)); + }); +} diff --git a/parachains/integration-tests/emulated/common/Cargo.toml b/parachains/integration-tests/emulated/common/Cargo.toml new file mode 100644 index 00000000000..a13ceac2cff --- /dev/null +++ b/parachains/integration-tests/emulated/common/Cargo.toml @@ -0,0 +1,54 @@ +[package] +name = "integration-tests-common" +version = "1.0.0" +authors = ["Parity Technologies "] +edition = "2021" +description = "Common resources for integration testing with xcm-emulator" + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false } + +# Substrate +grandpa = { package = "sc-consensus-grandpa", git = "https://github.com/paritytech/substrate", branch = "master" } +sp-authority-discovery = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } +sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } +frame-support = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } +frame-system = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } +sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } +sp-weights = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } +sp-consensus-babe = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-balances = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-assets = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-staking = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-im-online = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "master" } + +# Polkadot +polkadot-core-primitives = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "master" } +polkadot-parachain = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "master" } +polkadot-service = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "master" } +polkadot-primitives = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "master" } +polkadot-runtime-parachains = { git = "https://github.com/paritytech/polkadot", branch = "master" } +polkadot-runtime = { git = "https://github.com/paritytech/polkadot", branch = "master" } +polkadot-runtime-constants = { git = "https://github.com/paritytech/polkadot", branch = "master" } +kusama-runtime = { git = "https://github.com/paritytech/polkadot", branch = "master" } +kusama-runtime-constants = { git = "https://github.com/paritytech/polkadot", branch = "master" } +xcm = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "master" } +xcm-executor = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "master" } +pallet-xcm = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "master" } + +# Cumulus +parachains-common = { path = "../../../common" } +parachain-info = { path = "../../../pallets/parachain-info" } +cumulus-primitives-core = { path = "../../../../primitives/core" } +penpal-runtime = { path = "../../../runtimes/testing/penpal" } +statemint-runtime = { path = "../../../runtimes/assets/statemint" } +statemine-runtime = { path = "../../../runtimes/assets/statemine" } +collectives-polkadot-runtime = { path = "../../../runtimes/collectives/collectives-polkadot" } +bridge-hub-kusama-runtime = { path = "../../../runtimes/bridge-hubs/bridge-hub-kusama" } +bridge-hub-polkadot-runtime = { path = "../../../runtimes/bridge-hubs/bridge-hub-polkadot" } +xcm-emulator = { default-features = false, path = "../../../../xcm/xcm-emulator" } + +[features] +runtime-benchmarks = [ + "kusama-runtime/runtime-benchmarks", +] diff --git a/parachains/integration-tests/emulated/common/src/constants.rs b/parachains/integration-tests/emulated/common/src/constants.rs new file mode 100644 index 00000000000..b9720db4cf0 --- /dev/null +++ b/parachains/integration-tests/emulated/common/src/constants.rs @@ -0,0 +1,672 @@ +use grandpa::AuthorityId as GrandpaId; +use pallet_im_online::sr25519::AuthorityId as ImOnlineId; +pub use parachains_common::{AccountId, AuraId, Balance, BlockNumber, StatemintAuraId}; +use polkadot_primitives::{AssignmentId, ValidatorId}; +pub use polkadot_runtime_parachains::configuration::HostConfiguration; +use polkadot_service::chain_spec::get_authority_keys_from_seed_no_beefy; +use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; +use sp_consensus_babe::AuthorityId as BabeId; +use sp_core::{sr25519, storage::Storage, Pair, Public}; +use sp_runtime::{ + traits::{IdentifyAccount, Verify}, + BuildStorage, MultiSignature, Perbill, +}; +pub use xcm; + +pub const XCM_V2: u32 = 3; +pub const XCM_V3: u32 = 2; +pub const REF_TIME_THRESHOLD: u64 = 33; +pub const PROOF_SIZE_THRESHOLD: u64 = 33; + +type AccountPublic = ::Signer; + +/// Helper function to generate a crypto pair from seed +fn get_from_seed(seed: &str) -> ::Public { + TPublic::Pair::from_string(&format!("//{}", seed), None) + .expect("static values are valid; qed") + .public() +} + +/// Helper function to generate an account ID from seed. +fn get_account_id_from_seed(seed: &str) -> AccountId +where + AccountPublic: From<::Public>, +{ + AccountPublic::from(get_from_seed::(seed)).into_account() +} + +pub mod accounts { + use super::*; + pub const ALICE: &str = "Alice"; + pub const BOB: &str = "Bob"; + pub const CHARLIE: &str = "Charlie"; + pub const DAVE: &str = "Dave"; + pub const EVE: &str = "Eve"; + pub const FERDIE: &str = "Ferdei"; + pub const ALICE_STASH: &str = "Alice//stash"; + pub const BOB_STASH: &str = "Bob//stash"; + pub const CHARLIE_STASH: &str = "Charlie//stash"; + pub const DAVE_STASH: &str = "Dave//stash"; + pub const EVE_STASH: &str = "Eve//stash"; + pub const FERDIE_STASH: &str = "Ferdie//stash"; + + pub fn init_balances() -> Vec { + vec![ + get_account_id_from_seed::(ALICE), + get_account_id_from_seed::(BOB), + get_account_id_from_seed::(CHARLIE), + get_account_id_from_seed::(DAVE), + get_account_id_from_seed::(EVE), + get_account_id_from_seed::(FERDIE), + get_account_id_from_seed::(ALICE_STASH), + get_account_id_from_seed::(BOB_STASH), + get_account_id_from_seed::(CHARLIE_STASH), + get_account_id_from_seed::(DAVE_STASH), + get_account_id_from_seed::(EVE_STASH), + get_account_id_from_seed::(FERDIE_STASH), + ] + } +} + +pub mod collators { + use super::*; + + pub fn invulnerables_statemint() -> Vec<(AccountId, StatemintAuraId)> { + vec![ + ( + get_account_id_from_seed::("Alice"), + get_from_seed::("Alice"), + ), + ( + get_account_id_from_seed::("Bob"), + get_from_seed::("Bob"), + ), + ] + } + + pub fn invulnerables() -> Vec<(AccountId, AuraId)> { + vec![ + ( + get_account_id_from_seed::("Alice"), + get_from_seed::("Alice"), + ), + (get_account_id_from_seed::("Bob"), get_from_seed::("Bob")), + ] + } +} + +pub mod validators { + use super::*; + + pub fn initial_authorities() -> Vec<( + AccountId, + AccountId, + BabeId, + GrandpaId, + ImOnlineId, + ValidatorId, + AssignmentId, + AuthorityDiscoveryId, + )> { + vec![get_authority_keys_from_seed_no_beefy("Alice")] + } +} + +/// The default XCM version to set in genesis config. +const SAFE_XCM_VERSION: u32 = xcm::prelude::XCM_VERSION; +// Polkadot +pub mod polkadot { + use super::*; + pub const ED: Balance = polkadot_runtime_constants::currency::EXISTENTIAL_DEPOSIT; + const STASH: u128 = 100 * polkadot_runtime_constants::currency::UNITS; + + pub fn get_host_config() -> HostConfiguration { + HostConfiguration { + max_upward_queue_count: 10, + max_upward_queue_size: 51200, + max_upward_message_size: 51200, + max_upward_message_num_per_candidate: 10, + max_downward_message_size: 51200, + ..Default::default() + } + } + + fn session_keys( + babe: BabeId, + grandpa: GrandpaId, + im_online: ImOnlineId, + para_validator: ValidatorId, + para_assignment: AssignmentId, + authority_discovery: AuthorityDiscoveryId, + ) -> polkadot_runtime::SessionKeys { + polkadot_runtime::SessionKeys { + babe, + grandpa, + im_online, + para_validator, + para_assignment, + authority_discovery, + } + } + + pub fn genesis() -> Storage { + let genesis_config = polkadot_runtime::GenesisConfig { + system: polkadot_runtime::SystemConfig { + code: polkadot_runtime::WASM_BINARY.unwrap().to_vec(), + }, + balances: polkadot_runtime::BalancesConfig { + balances: accounts::init_balances() + .iter() + .cloned() + .map(|k| (k, ED * 4096)) + .collect(), + }, + indices: polkadot_runtime::IndicesConfig { indices: vec![] }, + session: polkadot_runtime::SessionConfig { + keys: validators::initial_authorities() + .iter() + .map(|x| { + ( + x.0.clone(), + x.0.clone(), + polkadot::session_keys( + x.2.clone(), + x.3.clone(), + x.4.clone(), + x.5.clone(), + x.6.clone(), + x.7.clone(), + ), + ) + }) + .collect::>(), + }, + staking: polkadot_runtime::StakingConfig { + validator_count: validators::initial_authorities().len() as u32, + minimum_validator_count: 1, + stakers: validators::initial_authorities() + .iter() + .map(|x| { + (x.0.clone(), x.1.clone(), STASH, polkadot_runtime::StakerStatus::Validator) + }) + .collect(), + invulnerables: validators::initial_authorities() + .iter() + .map(|x| x.0.clone()) + .collect(), + force_era: pallet_staking::Forcing::ForceNone, + slash_reward_fraction: Perbill::from_percent(10), + ..Default::default() + }, + phragmen_election: Default::default(), + democracy: Default::default(), + council: polkadot_runtime::CouncilConfig { + members: vec![], + phantom: Default::default(), + }, + technical_committee: polkadot_runtime::TechnicalCommitteeConfig { + members: vec![], + phantom: Default::default(), + }, + technical_membership: Default::default(), + babe: polkadot_runtime::BabeConfig { + authorities: Default::default(), + epoch_config: Some(polkadot_runtime::BABE_GENESIS_EPOCH_CONFIG), + }, + grandpa: Default::default(), + im_online: Default::default(), + authority_discovery: polkadot_runtime::AuthorityDiscoveryConfig { keys: vec![] }, + claims: polkadot_runtime::ClaimsConfig { claims: vec![], vesting: vec![] }, + vesting: polkadot_runtime::VestingConfig { vesting: vec![] }, + treasury: Default::default(), + hrmp: Default::default(), + configuration: polkadot_runtime::ConfigurationConfig { config: get_host_config() }, + paras: Default::default(), + xcm_pallet: Default::default(), + nomination_pools: Default::default(), + }; + + genesis_config.build_storage().unwrap() + } +} + +// Kusama +pub mod kusama { + use super::*; + pub const ED: Balance = kusama_runtime_constants::currency::EXISTENTIAL_DEPOSIT; + const STASH: u128 = 100 * kusama_runtime_constants::currency::UNITS; + + pub fn get_host_config() -> HostConfiguration { + HostConfiguration { + max_upward_queue_count: 10, + max_upward_queue_size: 51200, + max_upward_message_size: 51200, + max_upward_message_num_per_candidate: 10, + max_downward_message_size: 51200, + ..Default::default() + } + } + + fn session_keys( + babe: BabeId, + grandpa: GrandpaId, + im_online: ImOnlineId, + para_validator: ValidatorId, + para_assignment: AssignmentId, + authority_discovery: AuthorityDiscoveryId, + ) -> kusama_runtime::SessionKeys { + kusama_runtime::SessionKeys { + babe, + grandpa, + im_online, + para_validator, + para_assignment, + authority_discovery, + } + } + + pub fn genesis() -> Storage { + let genesis_config = kusama_runtime::GenesisConfig { + system: kusama_runtime::SystemConfig { + code: kusama_runtime::WASM_BINARY.unwrap().to_vec(), + }, + balances: kusama_runtime::BalancesConfig { + balances: accounts::init_balances() + .iter() + .cloned() + .map(|k| (k, ED * 4096)) + .collect(), + }, + indices: kusama_runtime::IndicesConfig { indices: vec![] }, + session: kusama_runtime::SessionConfig { + keys: validators::initial_authorities() + .iter() + .map(|x| { + ( + x.0.clone(), + x.0.clone(), + kusama::session_keys( + x.2.clone(), + x.3.clone(), + x.4.clone(), + x.5.clone(), + x.6.clone(), + x.7.clone(), + ), + ) + }) + .collect::>(), + }, + staking: kusama_runtime::StakingConfig { + minimum_validator_count: 1, + validator_count: validators::initial_authorities().len() as u32, + stakers: validators::initial_authorities() + .iter() + .map(|x| { + (x.0.clone(), x.1.clone(), STASH, kusama_runtime::StakerStatus::Validator) + }) + .collect(), + invulnerables: validators::initial_authorities() + .iter() + .map(|x| x.0.clone()) + .collect(), + force_era: pallet_staking::Forcing::NotForcing, + slash_reward_fraction: Perbill::from_percent(10), + ..Default::default() + }, + babe: kusama_runtime::BabeConfig { + authorities: Default::default(), + epoch_config: Some(kusama_runtime::BABE_GENESIS_EPOCH_CONFIG), + }, + grandpa: Default::default(), + im_online: Default::default(), + authority_discovery: kusama_runtime::AuthorityDiscoveryConfig { keys: vec![] }, + claims: kusama_runtime::ClaimsConfig { claims: vec![], vesting: vec![] }, + vesting: kusama_runtime::VestingConfig { vesting: vec![] }, + treasury: Default::default(), + hrmp: Default::default(), + configuration: kusama_runtime::ConfigurationConfig { config: get_host_config() }, + paras: Default::default(), + xcm_pallet: Default::default(), + nomination_pools: Default::default(), + nis_counterpart_balances: Default::default(), + }; + + genesis_config.build_storage().unwrap() + } +} + +// Statemint +pub mod statemint { + use super::*; + pub const PARA_ID: u32 = 1000; + pub const ED: Balance = statemint_runtime::constants::currency::EXISTENTIAL_DEPOSIT; + + pub fn genesis() -> Storage { + let genesis_config = statemint_runtime::GenesisConfig { + system: statemint_runtime::SystemConfig { + code: statemint_runtime::WASM_BINARY + .expect("WASM binary was not build, please build it!") + .to_vec(), + }, + balances: statemint_runtime::BalancesConfig { + balances: accounts::init_balances() + .iter() + .cloned() + .map(|k| (k, ED * 4096)) + .collect(), + }, + parachain_info: statemint_runtime::ParachainInfoConfig { parachain_id: PARA_ID.into() }, + collator_selection: statemint_runtime::CollatorSelectionConfig { + invulnerables: collators::invulnerables_statemint() + .iter() + .cloned() + .map(|(acc, _)| acc) + .collect(), + candidacy_bond: ED * 16, + ..Default::default() + }, + session: statemint_runtime::SessionConfig { + keys: collators::invulnerables_statemint() + .into_iter() + .map(|(acc, aura)| { + ( + acc.clone(), // account id + acc, // validator id + statemint_runtime::SessionKeys { aura }, // session keys + ) + }) + .collect(), + }, + aura: Default::default(), + aura_ext: Default::default(), + parachain_system: Default::default(), + polkadot_xcm: statemint_runtime::PolkadotXcmConfig { + safe_xcm_version: Some(SAFE_XCM_VERSION), + }, + }; + + genesis_config.build_storage().unwrap() + } +} + +// Statemint +pub mod statemine { + use super::*; + pub const PARA_ID: u32 = 1000; + pub const ED: Balance = statemine_runtime::constants::currency::EXISTENTIAL_DEPOSIT; + + pub fn genesis() -> Storage { + let genesis_config = statemine_runtime::GenesisConfig { + system: statemine_runtime::SystemConfig { + code: statemine_runtime::WASM_BINARY + .expect("WASM binary was not build, please build it!") + .to_vec(), + }, + balances: statemine_runtime::BalancesConfig { + balances: accounts::init_balances() + .iter() + .cloned() + .map(|k| (k, ED * 4096)) + .collect(), + }, + parachain_info: statemine_runtime::ParachainInfoConfig { parachain_id: PARA_ID.into() }, + collator_selection: statemine_runtime::CollatorSelectionConfig { + invulnerables: collators::invulnerables() + .iter() + .cloned() + .map(|(acc, _)| acc) + .collect(), + candidacy_bond: ED * 16, + ..Default::default() + }, + session: statemine_runtime::SessionConfig { + keys: collators::invulnerables() + .into_iter() + .map(|(acc, aura)| { + ( + acc.clone(), // account id + acc, // validator id + statemine_runtime::SessionKeys { aura }, // session keys + ) + }) + .collect(), + }, + aura: Default::default(), + aura_ext: Default::default(), + parachain_system: Default::default(), + polkadot_xcm: statemine_runtime::PolkadotXcmConfig { + safe_xcm_version: Some(SAFE_XCM_VERSION), + }, + }; + + genesis_config.build_storage().unwrap() + } +} + +// Penpal +pub mod penpal { + use super::*; + pub const PARA_ID: u32 = 2000; + pub const ED: Balance = penpal_runtime::EXISTENTIAL_DEPOSIT; + + pub fn genesis(para_id: u32) -> Storage { + let genesis_config = penpal_runtime::GenesisConfig { + system: penpal_runtime::SystemConfig { + code: penpal_runtime::WASM_BINARY + .expect("WASM binary was not build, please build it!") + .to_vec(), + }, + balances: penpal_runtime::BalancesConfig { + balances: accounts::init_balances() + .iter() + .cloned() + .map(|k| (k, ED * 4096)) + .collect(), + }, + parachain_info: penpal_runtime::ParachainInfoConfig { parachain_id: para_id.into() }, + collator_selection: penpal_runtime::CollatorSelectionConfig { + invulnerables: collators::invulnerables() + .iter() + .cloned() + .map(|(acc, _)| acc) + .collect(), + candidacy_bond: ED * 16, + ..Default::default() + }, + session: penpal_runtime::SessionConfig { + keys: collators::invulnerables() + .into_iter() + .map(|(acc, aura)| { + ( + acc.clone(), // account id + acc, // validator id + penpal_runtime::SessionKeys { aura }, // session keys + ) + }) + .collect(), + }, + aura: Default::default(), + aura_ext: Default::default(), + parachain_system: Default::default(), + polkadot_xcm: penpal_runtime::PolkadotXcmConfig { + safe_xcm_version: Some(SAFE_XCM_VERSION), + }, + sudo: penpal_runtime::SudoConfig { + key: Some(get_account_id_from_seed::("Alice")), + }, + }; + + genesis_config.build_storage().unwrap() + } +} + +// Collectives +pub mod collectives { + use super::*; + pub const PARA_ID: u32 = 1001; + pub const ED: Balance = collectives_polkadot_runtime::constants::currency::EXISTENTIAL_DEPOSIT; + + pub fn genesis() -> Storage { + let genesis_config = collectives_polkadot_runtime::GenesisConfig { + system: collectives_polkadot_runtime::SystemConfig { + code: collectives_polkadot_runtime::WASM_BINARY + .expect("WASM binary was not build, please build it!") + .to_vec(), + }, + balances: collectives_polkadot_runtime::BalancesConfig { + balances: accounts::init_balances() + .iter() + .cloned() + .map(|k| (k, ED * 4096)) + .collect(), + }, + parachain_info: collectives_polkadot_runtime::ParachainInfoConfig { + parachain_id: PARA_ID.into(), + }, + collator_selection: collectives_polkadot_runtime::CollatorSelectionConfig { + invulnerables: collators::invulnerables() + .iter() + .cloned() + .map(|(acc, _)| acc) + .collect(), + candidacy_bond: ED * 16, + ..Default::default() + }, + session: collectives_polkadot_runtime::SessionConfig { + keys: collators::invulnerables() + .into_iter() + .map(|(acc, aura)| { + ( + acc.clone(), // account id + acc, // validator id + collectives_polkadot_runtime::SessionKeys { aura }, // session keys + ) + }) + .collect(), + }, + // no need to pass anything to aura, in fact it will panic if we do. Session will take care + // of this. + aura: Default::default(), + aura_ext: Default::default(), + parachain_system: Default::default(), + polkadot_xcm: collectives_polkadot_runtime::PolkadotXcmConfig { + safe_xcm_version: Some(SAFE_XCM_VERSION), + }, + alliance: Default::default(), + alliance_motion: Default::default(), + }; + + genesis_config.build_storage().unwrap() + } +} + +pub mod bridge_hub_kusama { + use super::*; + pub const PARA_ID: u32 = 1002; + pub const ED: Balance = bridge_hub_kusama_runtime::constants::currency::EXISTENTIAL_DEPOSIT; + + pub fn genesis() -> Storage { + let genesis_config = bridge_hub_kusama_runtime::GenesisConfig { + system: bridge_hub_kusama_runtime::SystemConfig { + code: bridge_hub_kusama_runtime::WASM_BINARY + .expect("WASM binary was not build, please build it!") + .to_vec(), + }, + balances: bridge_hub_kusama_runtime::BalancesConfig { + balances: accounts::init_balances() + .iter() + .cloned() + .map(|k| (k, ED * 4096)) + .collect(), + }, + parachain_info: bridge_hub_kusama_runtime::ParachainInfoConfig { + parachain_id: PARA_ID.into(), + }, + collator_selection: bridge_hub_kusama_runtime::CollatorSelectionConfig { + invulnerables: collators::invulnerables() + .iter() + .cloned() + .map(|(acc, _)| acc) + .collect(), + candidacy_bond: ED * 16, + ..Default::default() + }, + session: bridge_hub_kusama_runtime::SessionConfig { + keys: collators::invulnerables() + .into_iter() + .map(|(acc, aura)| { + ( + acc.clone(), // account id + acc, // validator id + bridge_hub_kusama_runtime::SessionKeys { aura }, // session keys + ) + }) + .collect(), + }, + aura: Default::default(), + aura_ext: Default::default(), + parachain_system: Default::default(), + polkadot_xcm: bridge_hub_kusama_runtime::PolkadotXcmConfig { + safe_xcm_version: Some(SAFE_XCM_VERSION), + }, + }; + + genesis_config.build_storage().unwrap() + } +} + +pub mod bridge_hub_polkadot { + use super::*; + pub const PARA_ID: u32 = 1002; + pub const ED: Balance = bridge_hub_polkadot_runtime::constants::currency::EXISTENTIAL_DEPOSIT; + + pub fn genesis() -> Storage { + let genesis_config = bridge_hub_polkadot_runtime::GenesisConfig { + system: bridge_hub_polkadot_runtime::SystemConfig { + code: bridge_hub_polkadot_runtime::WASM_BINARY + .expect("WASM binary was not build, please build it!") + .to_vec(), + }, + balances: bridge_hub_polkadot_runtime::BalancesConfig { + balances: accounts::init_balances() + .iter() + .cloned() + .map(|k| (k, ED * 4096)) + .collect(), + }, + parachain_info: bridge_hub_polkadot_runtime::ParachainInfoConfig { + parachain_id: PARA_ID.into(), + }, + collator_selection: bridge_hub_polkadot_runtime::CollatorSelectionConfig { + invulnerables: collators::invulnerables() + .iter() + .cloned() + .map(|(acc, _)| acc) + .collect(), + candidacy_bond: ED * 16, + ..Default::default() + }, + session: bridge_hub_polkadot_runtime::SessionConfig { + keys: collators::invulnerables() + .into_iter() + .map(|(acc, aura)| { + ( + acc.clone(), // account id + acc, // validator id + bridge_hub_polkadot_runtime::SessionKeys { aura }, // session keys + ) + }) + .collect(), + }, + aura: Default::default(), + aura_ext: Default::default(), + parachain_system: Default::default(), + polkadot_xcm: bridge_hub_polkadot_runtime::PolkadotXcmConfig { + safe_xcm_version: Some(SAFE_XCM_VERSION), + }, + }; + + genesis_config.build_storage().unwrap() + } +} diff --git a/parachains/integration-tests/emulated/common/src/lib.rs b/parachains/integration-tests/emulated/common/src/lib.rs new file mode 100644 index 00000000000..0d0928998a0 --- /dev/null +++ b/parachains/integration-tests/emulated/common/src/lib.rs @@ -0,0 +1,253 @@ +pub mod constants; + +pub use constants::{ + accounts::{ALICE, BOB}, + bridge_hub_kusama, bridge_hub_polkadot, collectives, kusama, penpal, polkadot, statemine, + statemint, +}; +use frame_support::{parameter_types, sp_io, sp_tracing}; +pub use parachains_common::{AccountId, AuraId, Balance, BlockNumber, StatemintAuraId}; +pub use sp_core::{sr25519, storage::Storage, Get}; +use xcm::prelude::*; +use xcm_emulator::{ + decl_test_networks, decl_test_parachains, decl_test_relay_chains, Parachain, RelayChain, + TestExt, +}; +use xcm_executor::traits::Convert; + +decl_test_relay_chains! { + pub struct Polkadot { + genesis = polkadot::genesis(), + on_init = (), + runtime = { + Runtime: polkadot_runtime::Runtime, + RuntimeOrigin: polkadot_runtime::RuntimeOrigin, + RuntimeCall: polkadot_runtime::RuntimeCall, + RuntimeEvent: polkadot_runtime::RuntimeEvent, + XcmConfig: polkadot_runtime::xcm_config::XcmConfig, + SovereignAccountOf: polkadot_runtime::xcm_config::SovereignAccountOf, + System: polkadot_runtime::System, + Balances: polkadot_runtime::Balances, + }, + pallets_extra = { + XcmPallet: polkadot_runtime::XcmPallet, + } + }, + pub struct Kusama { + genesis = kusama::genesis(), + on_init = (), + runtime = { + Runtime: kusama_runtime::Runtime, + RuntimeOrigin: kusama_runtime::RuntimeOrigin, + RuntimeCall: polkadot_runtime::RuntimeCall, + RuntimeEvent: kusama_runtime::RuntimeEvent, + XcmConfig: kusama_runtime::xcm_config::XcmConfig, + SovereignAccountOf: kusama_runtime::xcm_config::SovereignAccountOf, + System: kusama_runtime::System, + Balances: kusama_runtime::Balances, + }, + pallets_extra = { + XcmPallet: kusama_runtime::XcmPallet, + } + } +} + +decl_test_parachains! { + // Polkadot + pub struct Statemint { + genesis = statemint::genesis(), + on_init = (), + runtime = { + Runtime: statemint_runtime::Runtime, + RuntimeOrigin: statemint_runtime::RuntimeOrigin, + RuntimeCall: statemint_runtime::RuntimeCall, + RuntimeEvent: statemint_runtime::RuntimeEvent, + XcmpMessageHandler: statemint_runtime::XcmpQueue, + DmpMessageHandler: statemint_runtime::DmpQueue, + LocationToAccountId: statemint_runtime::xcm_config::LocationToAccountId, + System: statemint_runtime::System, + Balances: statemint_runtime::Balances, + ParachainSystem: statemint_runtime::ParachainSystem, + ParachainInfo: statemint_runtime::ParachainInfo, + }, + pallets_extra = { + PolkadotXcm: statemint_runtime::PolkadotXcm, + Assets: statemint_runtime::Assets, + } + }, + pub struct PenpalPolkadot { + genesis = penpal::genesis(penpal::PARA_ID), + on_init = (), + runtime = { + Runtime: penpal_runtime::Runtime, + RuntimeOrigin: penpal_runtime::RuntimeOrigin, + RuntimeCall: penpal_runtime::RuntimeEvent, + RuntimeEvent: penpal_runtime::RuntimeEvent, + XcmpMessageHandler: penpal_runtime::XcmpQueue, + DmpMessageHandler: penpal_runtime::DmpQueue, + LocationToAccountId: penpal_runtime::xcm_config::LocationToAccountId, + System: penpal_runtime::System, + Balances: penpal_runtime::Balances, + ParachainSystem: penpal_runtime::ParachainSystem, + ParachainInfo: penpal_runtime::ParachainInfo, + }, + pallets_extra = { + PolkadotXcm: penpal_runtime::PolkadotXcm, + Assets: penpal_runtime::Assets, + } + }, + // Kusama + pub struct Statemine { + genesis = statemine::genesis(), + on_init = (), + runtime = { + Runtime: statemine_runtime::Runtime, + RuntimeOrigin: statemine_runtime::RuntimeOrigin, + RuntimeCall: statemine_runtime::RuntimeEvent, + RuntimeEvent: statemine_runtime::RuntimeEvent, + XcmpMessageHandler: statemine_runtime::XcmpQueue, + DmpMessageHandler: statemine_runtime::DmpQueue, + LocationToAccountId: statemine_runtime::xcm_config::LocationToAccountId, + System: statemine_runtime::System, + Balances: statemine_runtime::Balances, + ParachainSystem: statemine_runtime::ParachainSystem, + ParachainInfo: statemine_runtime::ParachainInfo, + }, + pallets_extra = { + PolkadotXcm: statemine_runtime::PolkadotXcm, + Assets: statemine_runtime::Assets, + ForeignAssets: statemine_runtime::Assets, + } + }, + pub struct PenpalKusama { + genesis = penpal::genesis(penpal::PARA_ID), + on_init = (), + runtime = { + Runtime: penpal_runtime::Runtime, + RuntimeOrigin: penpal_runtime::RuntimeOrigin, + RuntimeCall: penpal_runtime::RuntimeEvent, + RuntimeEvent: penpal_runtime::RuntimeEvent, + XcmpMessageHandler: penpal_runtime::XcmpQueue, + DmpMessageHandler: penpal_runtime::DmpQueue, + LocationToAccountId: penpal_runtime::xcm_config::LocationToAccountId, + System: penpal_runtime::System, + Balances: penpal_runtime::Balances, + ParachainSystem: penpal_runtime::ParachainSystem, + ParachainInfo: penpal_runtime::ParachainInfo, + }, + pallets_extra = { + PolkadotXcm: penpal_runtime::PolkadotXcm, + Assets: penpal_runtime::Assets, + } + }, + pub struct Collectives { + genesis = collectives::genesis(), + on_init = (), + runtime = { + Runtime: collectives_polkadot_runtime::Runtime, + RuntimeOrigin: collectives_polkadot_runtime::RuntimeOrigin, + RuntimeCall: collectives_polkadot_runtime::RuntimeEvent, + RuntimeEvent: collectives_polkadot_runtime::RuntimeEvent, + XcmpMessageHandler: collectives_polkadot_runtime::XcmpQueue, + DmpMessageHandler: collectives_polkadot_runtime::DmpQueue, + LocationToAccountId: collectives_polkadot_runtime::xcm_config::LocationToAccountId, + System: collectives_polkadot_runtime::System, + Balances: collectives_polkadot_runtime::Balances, + ParachainSystem: collectives_polkadot_runtime::ParachainSystem, + ParachainInfo: collectives_polkadot_runtime::ParachainInfo, + }, + pallets_extra = { + PolkadotXcm: collectives_polkadot_runtime::PolkadotXcm, + } + }, + pub struct BHKusama { + genesis = bridge_hub_kusama::genesis(), + on_init = (), + runtime = { + Runtime: bridge_hub_kusama_runtime::Runtime, + RuntimeOrigin: bridge_hub_kusama_runtime::RuntimeOrigin, + RuntimeCall: bridge_hub_kusama_runtime::RuntimeEvent, + RuntimeEvent: bridge_hub_kusama_runtime::RuntimeEvent, + XcmpMessageHandler: bridge_hub_kusama_runtime::XcmpQueue, + DmpMessageHandler: bridge_hub_kusama_runtime::DmpQueue, + LocationToAccountId: bridge_hub_kusama_runtime::xcm_config::LocationToAccountId, + System: bridge_hub_kusama_runtime::System, + Balances: bridge_hub_kusama_runtime::Balances, + ParachainSystem: bridge_hub_kusama_runtime::ParachainSystem, + ParachainInfo:bridge_hub_kusama_runtime::ParachainInfo, + }, + pallets_extra = { + PolkadotXcm: bridge_hub_kusama_runtime::PolkadotXcm, + } + }, + pub struct BHPolkadot { + genesis = bridge_hub_polkadot::genesis(), + on_init = (), + runtime = { + Runtime: bridge_hub_polkadot_runtime::Runtime, + RuntimeOrigin: bridge_hub_polkadot_runtime::RuntimeOrigin, + RuntimeCall: bridge_hub_polkadot_runtime::RuntimeEvent, + RuntimeEvent: bridge_hub_polkadot_runtime::RuntimeEvent, + XcmpMessageHandler: bridge_hub_polkadot_runtime::XcmpQueue, + DmpMessageHandler: bridge_hub_polkadot_runtime::DmpQueue, + LocationToAccountId: bridge_hub_polkadot_runtime::xcm_config::LocationToAccountId, + System: bridge_hub_polkadot_runtime::System, + Balances: bridge_hub_polkadot_runtime::Balances, + ParachainSystem: bridge_hub_polkadot_runtime::ParachainSystem, + ParachainInfo:bridge_hub_polkadot_runtime::ParachainInfo, + }, + pallets_extra = { + PolkadotXcm: bridge_hub_polkadot_runtime::PolkadotXcm, + } + } +} + +decl_test_networks! { + pub struct PolkadotMockNet { + relay_chain = Polkadot, + parachains = vec![ + Statemint, + PenpalPolkadot, + Collectives, + BHPolkadot, + ], + }, + pub struct KusamaMockNet { + relay_chain = Kusama, + parachains = vec![ + Statemine, + PenpalKusama, + BHKusama, + ], + } +} + +parameter_types! { + // Polkadot + pub PolkadotSender: AccountId = Polkadot::account_id_of(ALICE); + pub PolkadotReceiver: AccountId = Polkadot::account_id_of(BOB); + // Kusama + pub KusamaSender: AccountId = Kusama::account_id_of(ALICE); + pub KusamaReceiver: AccountId = Kusama::account_id_of(BOB); + // Statemint + pub StatemintSender: AccountId = Statemint::account_id_of(ALICE); + pub StatemintReceiver: AccountId = Statemint::account_id_of(BOB); + // Statemine + pub StatemineSender: AccountId = Statemine::account_id_of(ALICE); + pub StatemineReceiver: AccountId = Statemine::account_id_of(BOB); + // Penpal Polkadot + pub PenpalPolkadotSender: AccountId = PenpalPolkadot::account_id_of(ALICE); + pub PenpalPolkadotReceiver: AccountId = PenpalPolkadot::account_id_of(BOB); + // Penpal Kusama + pub PenpalKusamaSender: AccountId = PenpalKusama::account_id_of(ALICE); + pub PenpalKusamaReceiver: AccountId = PenpalKusama::account_id_of(BOB); + // Collectives + pub CollectivesSender: AccountId = Collectives::account_id_of(ALICE); + pub CollectivesReceiver: AccountId = Collectives::account_id_of(BOB); + // Bridge Hub Polkadot + pub BHPolkadotSender: AccountId = BHPolkadot::account_id_of(ALICE); + pub BHPolkadotReceiver: AccountId = BHPolkadot::account_id_of(BOB); + // Bridge Hub Kusama + pub BHKusamaSender: AccountId = BHKusama::account_id_of(ALICE); + pub BHKusamaReceiver: AccountId = BHKusama::account_id_of(BOB); +} diff --git a/parachains/integration-tests/statemine/config.toml b/parachains/integration-tests/statemine/config.toml deleted file mode 100644 index 510f3cd3b04..00000000000 --- a/parachains/integration-tests/statemine/config.toml +++ /dev/null @@ -1,49 +0,0 @@ -[relaychain] -default_command = "./bin/polkadot" -default_args = [ "-lparachain=debug" ] -chain = "kusama-local" - - [[relaychain.nodes]] - name = "alice" - ws_port = 9900 - validator = true - - [[relaychain.nodes]] - name = "bob" - validator = true - - [[relaychain.nodes]] - name = "charlie" - validator = true - - [[relaychain.nodes]] - name = "dave" - validator = true - -[[parachains]] -id = 1000 -chain = "statemine-local" -cumulus_based = true - - [[parachains.collators]] - name = "collator1" - ws_port = 9910 - command = "./bin/polkadot-parachain" - - [[parachains.collators]] - name = "collator2" - command = "./bin/polkadot-parachain" - -[[parachains]] -id = 2000 -chain = "penpal-kusama-2000" -cumulus_based = true - - [[parachains.collators]] - name = "collator3" - ws_port = 9920 - command = "./bin/polkadot-parachain" - - [[parachains.collators]] - name = "collator4" - command = "./bin/polkadot-parachain" diff --git a/parachains/integration-tests/statemine/xcm/3_hrmp-open-channels.yml b/parachains/integration-tests/statemine/xcm/3_hrmp-open-channels.yml deleted file mode 100644 index 45bf89e2b05..00000000000 --- a/parachains/integration-tests/statemine/xcm/3_hrmp-open-channels.yml +++ /dev/null @@ -1,408 +0,0 @@ ---- -settings: - chains: - relay_chain: &relay_chain - wsPort: 9900 - assets_parachain: &assets_parachain - wsPort: 9910 - paraId: &ap_id 1000 - penpal_parachain: &penpal_parachain - wsPort: 9920 - paraId: &pp_id 2000 - variables: - common: - amount: &amount 2000000000000 - require_weight_at_most: &weight_at_most 1000000000 - hrmp_channels: - proposed_max_capacity: &max_capacity 8 - proposed_max_message_size: &max_message_size 8192 - channel: &channel { - maxCapacity: 8, - maxTotalSize: 8192, - maxMessageSize: 8192, - msgCount: 0, - totalSize: 0, - mqcHead: null, - senderDeposit: 0, - recipientDeposit: 0 - } - chains: - relay_chain: - signer: &rc_signer //Alice - assets_parachain_destination: &ap_dest { v1: { 0, interior: { x1: { parachain: *ap_id }}}} - assets_parachain_account: &ap_acc '0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d' - assets_parachain_beneficiary: &ap_benf {v1: { parents: 0, interior: { x1: { accountId32: { network: { any: true }, id: *ap_acc }}}}} - ksm: &rc_ksm { concrete: { 0, interior: { here: true }}} - ksm_fungible: &rc_ksm_fungible { id: *rc_ksm, fun: { fungible: *amount }} - assets_parachain_account: - sovereign_account: &ap_sovereign F7fq1jSNVTPfJmaHaXCMtatT1EZefCUsa7rRiQVNR5efcah - relay_chain_destination: &rc_dest { v1: { parents: 1, interior: { here: true }}} - penpal_parachain: - sovereign_account: &pp_sovereign F7fq1jMZkfuCuoMTyiEVAP2DMpMt18WopgBqTJznLihLNbZ - signer: &pp_signer //Alice - decodedCalls: - init_open_channel_with_ap: - chain: *relay_chain - pallet: hrmp - call: hrmpInitOpenChannel - args: [ - *ap_id, # recipient - *max_capacity, # proposedMaxCapacity - *max_message_size # proposedMaxMessageSize - ] - init_open_channel_with_cp: - chain: *relay_chain - pallet: hrmp - call: hrmpInitOpenChannel - args: [ - *pp_id, # recipient - *max_capacity, # proposedMaxCapacity - *max_message_size # proposedMaxMessageSize - ] - accept_open_channel_with_ap: - chain: *relay_chain - pallet: hrmp - call: hrmpAcceptOpenChannel - args: [ - *ap_id, # recipient - ] - accept_init_open_request_from_cp: - chain: *relay_chain - pallet: hrmp - call: hrmpAcceptOpenChannel - args: [ - *pp_id, # sender - ] - xcm_accept_init_open_request_from_cp: - chain: *assets_parachain - pallet: polkadotXcm - call: send - args: [ - *rc_dest, # destination - { - v2: [ #message - { - WithdrawAsset: [*rc_ksm_fungible] - }, - { - BuyExecution: { - fees: *rc_ksm_fungible, - weightLimit: Unlimited - } - }, - { - Transact: { - originType: Native, - requireWeightAtMost: *weight_at_most, - call: $accept_init_open_request_from_cp - } - } - ] - } - ] - xcm_init_open_channel_with_cp: - chain: *assets_parachain - pallet: polkadotXcm - call: send - args: [ - *rc_dest, # destination - { - v2: [ #message - { - WithdrawAsset: [*rc_ksm_fungible] - }, - { - BuyExecution: { - fees: *rc_ksm_fungible, - weightLimit: Unlimited - } - }, - { - Transact: { - originType: Native, - requireWeightAtMost: *weight_at_most, - call: $init_open_channel_with_cp - } - } - ] - } - ] - -tests: - - name: HRMP - beforeEach: - - name: DEPENDANCY | Penpal Parachain Sovereign account in the Relay Chain needs to be funded - actions: - - extrinsics: - - chain: *relay_chain - signer: *rc_signer - pallet: balances - call: transfer - args: [ - *pp_sovereign, # destination - *amount, # value - ] - events: - - name: balances.Transfer - - - name: DEPENDANCY | Assets Parachain Sovereign account in the Relay Chain needs to be funded - actions: - - extrinsics: - - chain: *relay_chain - signer: *rc_signer - pallet: balances - call: transfer - args: [ - *ap_sovereign, # destination - *amount, # value - ] - events: - - name: balances.Transfer - describes: - - name: hrmp.hrmpInitOpenChannel (Penpal Parachain → Assets Parachain) - its: - - name: Penpal Parachain sends a request to the Relay Chain to open a channel with the Assets Parchain - actions: - - extrinsics: - - chain: *penpal_parachain - signer: *pp_signer - sudo: true - pallet: polkadotXcm - call: send - args: [ - *rc_dest, # destination - { - v2: [ #message - { - WithdrawAsset: [*rc_ksm_fungible] - }, - { - BuyExecution: { - fees: *rc_ksm_fungible, - weightLimit: Unlimited - } - }, - { - Transact: { - originType: Native, - requireWeightAtMost: *weight_at_most, - call: $init_open_channel_with_ap - } - } - ] - } - ] - events: - - name: sudo.Sudid - attribute: - type: Result - value: Ok - - name: polkadotXcm.Sent - - name: ump.ExecutedUpward - chain: *relay_chain - attribute: - type: XcmV2TraitsOutcome - isComplete: true - threshold: [10, 10] - value: 1,160,892,000 - - name: hrmp.OpenChannelRequested - chain: *relay_chain - - queries: - requested_channels: - chain: *relay_chain - pallet: hrmp - call: hrmpOpenChannelRequestsList - args: [] - - asserts: - equal: - args: [ - $requested_channels, - [ - { - sender: *pp_id, - recipient: *ap_id - } - ] - ] - - - name: hrmp.hrmpAcceptOpenChannel (Assets Parachain → Penpal Parachain) - its: - - name: Assets Parachain sends a response to the Relay Chain accepting the Penpal Parachain's request for openning a HRMP channel - actions: - - extrinsics: - - chain: *relay_chain - signer: *rc_signer - sudo: true - pallet: xcmPallet - call: send - args: [ - *ap_dest, # destination - { - v2: [ #message - { - Transact: { - originType: Superuser, - requireWeightAtMost: *weight_at_most, - call: $xcm_accept_init_open_request_from_cp - } - } - ] - } - ] - events: - - name: sudo.Sudid - attribute: - type: Result - value: Ok - - name: xcmPallet.Sent - - name: dmpQueue.ExecutedDownward - chain: *assets_parachain - attribute: - type: XcmV2TraitsOutcome - isComplete: true - threshold: [10, 10] - value: 1,021,258,000 - - name: polkadotXcm.Sent - chain: *assets_parachain - - name: ump.ExecutedUpward - timeout: 40000 - attribute: - type: XcmV2TraitsOutcome - isComplete: true - threshold: [10, 10] - value: 1,160,892,000 - - name: hrmp.OpenChannelAccepted - timeout: 40000 - - queries: - open_channels: - chain: *relay_chain - pallet: hrmp - call: hrmpChannels - delay: 80000 - args: [ - { - sender: *pp_id, - recipient: *ap_id - } - ] - - asserts: - equal: - args: [ - $open_channels, - *channel - ] - - - name: hrmp.hrmpInitOpenChannel (Assets Parachain → Penpal Parachain) - its: - - name: Assets Parchain sends a request to the Relay Chain to open a channel with a Penpal Parachain - actions: - - extrinsics: - - chain: *relay_chain - signer: *rc_signer - sudo: true - pallet: xcmPallet - call: send - args: [ - *ap_dest, # destination - { - v2: [ #message - { - Transact: { - originType: Superuser, - requireWeightAtMost: *weight_at_most, - call: $xcm_init_open_channel_with_cp - } - } - ] - } - ] - events: - - name: sudo.Sudid - attribute: - type: Result - value: Ok - - name: xcmPallet.Sent - - name: dmpQueue.ExecutedDownward - chain: *assets_parachain - attribute: - type: XcmV2TraitsOutcome - isComplete: true - threshold: [10, 10] - value: 1,021,258,000 - - name: polkadotXcm.Sent - chain: *assets_parachain - - name: ump.ExecutedUpward - timeout: 40000 - attribute: - type: XcmV2TraitsOutcome - isComplete: true - threshold: [10, 10] - value: 1,160,892,000 - - name: hrmp.OpenChannelRequested - timeout: 40000 - - queries: - requested_channels: - chain: *relay_chain - pallet: hrmp - call: hrmpOpenChannelRequestsList - args: [] - - asserts: - equal: - args: [ - $requested_channels, - [ - { - sender: *ap_id, - recipient: *pp_id - } - ] - ] - - - name: hrmp.hrmpAcceptOpenChannel (Penpal Parachain → Assets Parachain) - its: - - name: Penpal Parachain sends a response to the Relay Chain accepting the Assets Parachain's request for openning a HRMP channel - actions: - - extrinsics: - - chain: *penpal_parachain - signer: *pp_signer - sudo: true - pallet: polkadotXcm - call: send - args: [ - *rc_dest, # destination - { - v2: [ #message - { - WithdrawAsset: [*rc_ksm_fungible] - }, - { - BuyExecution: { - fees: *rc_ksm_fungible, - weightLimit: Unlimited - } - }, - { - Transact: { - originType: Native, - requireWeightAtMost: *weight_at_most, - call: $accept_open_channel_with_ap - } - } - ] - } - ] - events: - - name: sudo.Sudid - attribute: - type: Result - value: Ok - - name: polkadotXcm.Sent - - name: ump.ExecutedUpward - chain: *relay_chain - attribute: - type: XcmV2TraitsOutcome - isComplete: true - threshold: [10, 10] - value: 1,160,892,000 - - name: hrmp.OpenChannelAccepted - chain: *relay_chain diff --git a/parachains/integration-tests/statemine/xcm/4_hrmp.yml b/parachains/integration-tests/statemine/xcm/4_hrmp.yml deleted file mode 100644 index 28ef7bc803a..00000000000 --- a/parachains/integration-tests/statemine/xcm/4_hrmp.yml +++ /dev/null @@ -1,356 +0,0 @@ ---- -settings: - chains: - relay_chain: &relay_chain - wsPort: 9900 - assets_parachain: &assets_parachain - wsPort: 9910 - paraId: &ap_id 1000 - penpal_parachain: &penpal_parachain - wsPort: 9920 - paraId: &pp_id 2000 - variables: - common: - amount: &amount 1000000000000 - require_weight_at_most: &weight_at_most 1000000000 - amount_to_send: &amount_to_send 500000000000 - chains: - relay_chain: - signer: &rc_signer //Alice - assets_parachain_destination: &ap_dest { v1: { 0, interior: { x1: { parachain: *ap_id }}}} - assets_parachain_dest_routed: &ap_dest_routed { v1: { parents: 1, interior: { x1: { parachain: *ap_id } }}} - assets_parachain_account: - signer: &ap_signer //Alice - wallet: &ap_wallet HNZata7iMYWmk5RvZRTiAsSDhV8366zq2YGb3tLH5Upf74F - asset_id: &asset_id 2 - assets_pallet_id: &assets_pallet_id 50 - asset_min_balance: &asset_ed 1000 - penpal_parachain_destination: &pp_dest { v1: { parents: 1, interior: { x1: { parachain: *pp_id } }}} - ksm: &ap_ksm { concrete: { parents: 1, interior: { here: true }}} - ksm_fungible: &ap_ksm_fungible { id: *ap_ksm, fun: { fungible: *amount }} - suff_asset: &suff_asset { concrete: { parents: 0, interior: { x2: [ { PalletInstance: *assets_pallet_id }, { GeneralIndex: *asset_id } ] }}} - suff_asset_fail: &suff_asset_fail { concrete: { parents: 0, interior: { x2: [ { PalletInstance: *assets_pallet_id }, { GeneralIndex: 3 } ] }}} - suff_asset_fungible: &ap_suff_asset_fungible { id: *suff_asset, fun: { fungible: *weight_at_most }} - suff_asset_fungible_fail: &ap_suff_asset_fungible_fail { id: *suff_asset_fail, fun: { fungible: *weight_at_most }} - penpal_parachain: - sovereign_account: &pp_sovereign_sibl FBeL7EAeUroLWXW1yfKboiqTqVfbRBcsUKd6QqVf4kGBySS - signer: &pp_signer //Alice - penpal_parachain_account: &pp_acc '0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d' - decodedCalls: - force_create_asset: - chain: *assets_parachain - pallet: assets - call: forceCreate - args: [ - *asset_id, - { Id: *ap_wallet }, # owner - true, # isSufficient - *asset_ed # minBalance - ] - system_remark_with_event: - chain: *assets_parachain - pallet: system - call: remarkWithEvent - args: [ 0x0011 ] - -tests: - - name: HRMP - describes: - - name: polkadotXcm.limitedReserveTransferAssets (Asset) | Assets Parachain -> Penpal Parachain - before: - - name: DEPENDANCY | A sufficient Asset should exist in the Assets Parachain - actions: - - extrinsics: - - chain: *relay_chain - signer: *rc_signer - sudo: true - pallet: xcmPallet - call: send - args: [ - *ap_dest, # destination - { - v2: [ #message - { - Transact: { - originType: Superuser, - requireWeightAtMost: *weight_at_most, - call: $force_create_asset - } - } - ] - } - ] - events: - - name: xcmPallet.Sent - - name: dmpQueue.ExecutedDownward - chain: *assets_parachain - attribute: - type: XcmV2TraitsOutcome - isComplete: true - threshold: [10, 10] - value: 1,021,258,000 - - queries: - forced_created_asset: - chain: *assets_parachain - pallet: assets - call: asset - args: [ *asset_id ] - - asserts: - isSome: - args: [ $forced_created_asset ] - - - name: DEPENDANCY | Some Assets should be minted for the sender - actions: - - extrinsics: - - chain: *assets_parachain - signer: *ap_signer - pallet: assets - call: mint - args: [ - *asset_id, - *ap_wallet, - *amount - ] - events: - - name: assets.Issued - - its: - - name: Assets Parachain should be able to reserve transfer an Asset to Penpal Parachain - actions: - - extrinsics: - - chain: *assets_parachain - signer: *ap_signer - pallet: polkadotXcm - call: limitedReserveTransferAssets - args: [ - *pp_dest, # destination - { # beneficiary - V1: { - parents: 0, - interior: { - X1: { - AccountId32: { - network: Any, - id: *pp_acc - } - } - } - } - }, - { # assets - V1: [ - { - id: { - Concrete: { - parents: 0, - interior: { - X2: [ - { - PalletInstance: 50 - }, - { - GeneralIndex: *asset_id - } - ] - } - } - }, - fun: { - Fungible: *amount_to_send - } - } - ] - }, - 0, # feeAssetItem - Unlimited # weightLimit - ] - events: - - name: polkadotXcm.Attempted - attribute: - type: XcmV2TraitsOutcome - isComplete: true - threshold: [10, 10] - value: 654,608,000 - - name: assets.Transferred - attribute: - type: AccountId32 - value: *pp_sovereign_sibl - - name: assets.Transferred - attribute: - type: u128 - value: *amount_to_send - - - name: polkadotXcm.limitedReserveTransferAssets (KSM) | Assets Parachain -> Penpal Parachain - its: - - name: Assets Parachain should be able to reserve transfer KSM to Penpal Parachain - actions: - - extrinsics: - - chain: *assets_parachain - signer: *ap_signer - pallet: polkadotXcm - call: limitedReserveTransferAssets - args: [ - *pp_dest, # destination - { # beneficiary - V1: { - parents: 0, - interior: { - X1: { - AccountId32: { - network: Any, - id: *pp_acc - } - } - } - } - }, - { # assets - V1: [ - *ap_ksm_fungible - ] - }, - 0, # feeAssetItem - Unlimited # weightLimit - ] - events: - - name: polkadotXcm.Attempted - attribute: - type: XcmV2TraitsOutcome - isComplete: true - threshold: [10, 10] - value: 654,608,000 - - name: balances.Endowed - attribute: - type: AccountId32 - value: *pp_sovereign_sibl - - name: balances.Endowed - attribute: - type: u128 - value: *amount - - - name: polkadotXcm.send( system.remarkWithEvent() ) | Penpal Parachain -> Assets Parachain - before: - - name: Get the asset balance of the Penpal Parachain Sovereign account in Assets Parachain - actions: - - queries: - assets_balance_pp_sovereign_before: - chain: *assets_parachain - pallet: assets - call: account - args: [ - *asset_id, - *pp_sovereign_sibl - ] - its: - - name: Penpal Parachain should be able to send XCM message paying its fee with sufficient asset in Assets Parachain - actions: - - extrinsics: - - chain: *penpal_parachain - signer: *pp_signer - sudo: true - pallet: polkadotXcm - call: send - args: [ - *ap_dest_routed, # destination - { - v2: [ #message - { - WithdrawAsset: [*ap_suff_asset_fungible] - }, - { - BuyExecution: { - fees: *ap_suff_asset_fungible, - weightLimit: Unlimited - } - }, - { - Transact: { - originType: SovereignAccount, - requireWeightAtMost: *weight_at_most, - call: $system_remark_with_event - } - } - ] - } - ] - events: - - name: sudo.Sudid - attribute: - type: Result - value: Ok - - name: polkadotXcm.Sent - - name: assets.Burned - chain: *assets_parachain - attribute: - type: AccountId32 - value: *pp_sovereign_sibl - - name: assets.Issued - chain: *assets_parachain - attribute: - type: u32 - value: *asset_id - - name: system.Remarked - chain: *assets_parachain - attribute: - type: AccountId32 - value: *pp_sovereign_sibl - - queries: - assets_balance_pp_sovereign_after: - chain: *assets_parachain - pallet: assets - call: account - args: [ - *asset_id, - *pp_sovereign_sibl - ] - - - name: Should reduce the assets balance of the Penpal Parachain's SovereignAccount in the Assets Parachain - actions: - - asserts: - assetsDecreased: - args: [ - { - balances: { - before: $assets_balance_pp_sovereign_before, - after: $assets_balance_pp_sovereign_after, - }, - } - ] - - - name: Penpal Parachain SHOULD NOT be able to send XCM message paying its fee with sufficient assets if not enough balance - actions: - - extrinsics: - - chain: *penpal_parachain - signer: *pp_signer - sudo: true - pallet: polkadotXcm - call: send - args: [ - *ap_dest_routed, # destination - { - v2: [ #message - { - WithdrawAsset: [*ap_suff_asset_fungible_fail] - }, - { - BuyExecution: { - fees: *ap_suff_asset_fungible_fail, - weightLimit: Unlimited - } - }, - { - Transact: { - originType: SovereignAccount, - requireWeightAtMost: *weight_at_most, - call: $system_remark_with_event - } - } - ] - } - ] - events: - - name: xcmpQueue.Fail - chain: *assets_parachain - attribute: - type: XcmV2TraitsError - value: FailedToTransactAsset diff --git a/parachains/integration-tests/statemint/config.toml b/parachains/integration-tests/statemint/config.toml deleted file mode 100644 index f989d366ef3..00000000000 --- a/parachains/integration-tests/statemint/config.toml +++ /dev/null @@ -1,49 +0,0 @@ -[relaychain] -default_command = "./bin/polkadot" -default_args = [ "-lparachain=debug" ] -chain = "polkadot-local" - - [[relaychain.nodes]] - name = "alice" - ws_port = 9900 - validator = true - - [[relaychain.nodes]] - name = "bob" - validator = true - - [[relaychain.nodes]] - name = "charlie" - validator = true - - [[relaychain.nodes]] - name = "dave" - validator = true - -[[parachains]] -id = 1000 -chain = "statemint-local" -cumulus_based = true - - [[parachains.collators]] - name = "collator1" - ws_port = 9910 - command = "./bin/polkadot-parachain" - - [[parachains.collators]] - name = "collator2" - command = "./bin/polkadot-parachain" - -[[parachains]] -id = 2000 -chain = "penpal-polkadot-2000" -cumulus_based = true - - [[parachains.collators]] - name = "collator3" - ws_port = 9920 - command = "./bin/polkadot-parachain" - - [[parachains.collators]] - name = "collator4" - command = "./bin/polkadot-parachain" diff --git a/parachains/integration-tests/statemint/xcm/3_hrmp-open-channels.yml b/parachains/integration-tests/statemint/xcm/3_hrmp-open-channels.yml deleted file mode 100644 index f83e778f1c0..00000000000 --- a/parachains/integration-tests/statemint/xcm/3_hrmp-open-channels.yml +++ /dev/null @@ -1,402 +0,0 @@ ---- -settings: - chains: - relay_chain: &relay_chain - wsPort: 9900 - assets_parachain: &assets_parachain - wsPort: 9910 - paraId: &ap_id 1000 - penpal_parachain: &penpal_parachain - wsPort: 9920 - paraId: &pp_id 2000 - variables: - common: - amount: &amount 2000000000000 - require_weight_at_most: &weight_at_most 1000000000 - hrmp_channels: - proposed_max_capacity: &max_capacity 8 - proposed_max_message_size: &max_message_size 8192 - channel: &channel { - maxCapacity: 8, - maxTotalSize: 8192, - maxMessageSize: 8192, - msgCount: 0, - totalSize: 0, - mqcHead: null, - senderDeposit: 0, - recipientDeposit: 0 - } - chains: - relay_chain: - signer: &rc_signer //Alice - assets_parachain_destination: &ap_dest { v1: { 0, interior: { x1: { parachain: *ap_id }}}} - ksm: &rc_ksm { concrete: { 0, interior: { here: true }}} - ksm_fungible: &rc_ksm_fungible { id: *rc_ksm, fun: { fungible: *amount }} - assets_parachain_account: - sovereign_account: &ap_sovereign F7fq1jSNVTPfJmaHaXCMtatT1EZefCUsa7rRiQVNR5efcah - relay_chain_destination: &rc_dest { v1: { parents: 1, interior: { here: true }}} - penpal_parachain: - sovereign_account: &pp_sovereign F7fq1jMZkfuCuoMTyiEVAP2DMpMt18WopgBqTJznLihLNbZ - signer: &pp_signer //Alice - decodedCalls: - init_open_channel_with_ap: - chain: *relay_chain - pallet: hrmp - call: hrmpInitOpenChannel - args: [ - *ap_id, # recipient - *max_capacity, # proposedMaxCapacity - *max_message_size # proposedMaxMessageSize - ] - init_open_channel_with_cp: - chain: *relay_chain - pallet: hrmp - call: hrmpInitOpenChannel - args: [ - *pp_id, # recipient - *max_capacity, # proposedMaxCapacity - *max_message_size # proposedMaxMessageSize - ] - accept_open_channel_with_ap: - chain: *relay_chain - pallet: hrmp - call: hrmpAcceptOpenChannel - args: [ - *ap_id, # recipient - ] - accept_init_open_request_from_cp: - chain: *relay_chain - pallet: hrmp - call: hrmpAcceptOpenChannel - args: [ - *pp_id, # sender - ] - xcm_accept_init_open_request_from_cp: - chain: *assets_parachain - pallet: polkadotXcm - call: send - args: [ - *rc_dest, # destination - { - v2: [ #message - { - WithdrawAsset: [*rc_ksm_fungible] - }, - { - BuyExecution: { - fees: *rc_ksm_fungible, - weightLimit: Unlimited - } - }, - { - Transact: { - originType: Native, - requireWeightAtMost: *weight_at_most, - call: $accept_init_open_request_from_cp - } - } - ] - } - ] - xcm_init_open_channel_with_cp: - chain: *assets_parachain - pallet: polkadotXcm - call: send - args: [ - *rc_dest, # destination - { - v2: [ #message - { - WithdrawAsset: [*rc_ksm_fungible] - }, - { - BuyExecution: { - fees: *rc_ksm_fungible, - weightLimit: Unlimited - } - }, - { - Transact: { - originType: Native, - requireWeightAtMost: *weight_at_most, - call: $init_open_channel_with_cp - } - } - ] - } - ] - -tests: - - name: HRMP - beforeEach: - - name: DEPENDANCY | Penpal Parachain Sovereign account in the Relay Chain needs to be funded - actions: - - extrinsics: - - chain: *relay_chain - signer: *rc_signer - pallet: balances - call: transfer - args: [ - *pp_sovereign, # destination - *amount, # value - ] - events: - - name: balances.Transfer - - - name: DEPENDANCY | Assets Parachain Sovereign account in the Relay Chain needs to be funded - actions: - - extrinsics: - - chain: *relay_chain - signer: *rc_signer - pallet: balances - call: transfer - args: [ - *ap_sovereign, # destination - *amount, # value - ] - events: - - name: balances.Transfer - describes: - - name: hrmp.hrmpInitOpenChannel (Penpal Parachain → Assets Parachain) - its: - - name: Penpal Parachain sends a request to the Relay Chain to open a channel with the Assets Parchain - actions: - - extrinsics: - - chain: *penpal_parachain - signer: *pp_signer - sudo: true - pallet: polkadotXcm - call: send - args: [ - *rc_dest, # destination - { - v2: [ #message - { - WithdrawAsset: [*rc_ksm_fungible] - }, - { - BuyExecution: { - fees: *rc_ksm_fungible, - weightLimit: Unlimited - } - }, - { - Transact: { - originType: Native, - requireWeightAtMost: *weight_at_most, - call: $init_open_channel_with_ap - } - } - ] - } - ] - events: - - name: sudo.Sudid - attribute: - type: Result - value: Ok - - name: polkadotXcm.Sent - - name: ump.ExecutedUpward - chain: *relay_chain - attribute: - type: XcmV2TraitsOutcome - isComplete: true - value: 4,000,000,000 - - name: hrmp.OpenChannelRequested - chain: *relay_chain - - queries: - requested_channels: - chain: *relay_chain - pallet: hrmp - call: hrmpOpenChannelRequestsList - args: [] - - asserts: - equal: - args: [ - $requested_channels, - [ - { - sender: *pp_id, - recipient: *ap_id - } - ] - ] - - - name: hrmp.hrmpAcceptOpenChannel (Assets Parachain → Penpal Parachain) - its: - - name: Assets Parachain sends a response to the Relay Chain accepting the Penpal Parachain's request for openning a HRMP channel - actions: - - extrinsics: - - chain: *relay_chain - signer: *rc_signer - sudo: true - pallet: xcmPallet - call: send - args: [ - *ap_dest, # destination - { - v2: [ #message - { - Transact: { - originType: Superuser, - requireWeightAtMost: *weight_at_most, - call: $xcm_accept_init_open_request_from_cp - } - } - ] - } - ] - events: - - name: sudo.Sudid - attribute: - type: Result - value: Ok - - name: xcmPallet.Sent - - name: dmpQueue.ExecutedDownward - chain: *assets_parachain - attribute: - type: XcmV2TraitsOutcome - isComplete: true - threshold: [10, 10] - value: 1,020,807,000 - - name: polkadotXcm.Sent - chain: *assets_parachain - - name: ump.ExecutedUpward - timeout: 40000 - attribute: - type: XcmV2TraitsOutcome - isComplete: true - value: 4,000,000,000 - - name: hrmp.OpenChannelAccepted - timeout: 40000 - - queries: - open_channels: - chain: *relay_chain - pallet: hrmp - call: hrmpChannels - delay: 80000 - args: [ - { - sender: *pp_id, - recipient: *ap_id - } - ] - - asserts: - equal: - args: [ - $open_channels, - *channel - ] - - - name: hrmp.hrmpInitOpenChannel (Assets Parachain → Penpal Parachain) - its: - - name: Assets Parchain sends a request to the Relay Chain to open a channel with a Penpal Parachain - actions: - - extrinsics: - - chain: *relay_chain - signer: *rc_signer - sudo: true - pallet: xcmPallet - call: send - args: [ - *ap_dest, # destination - { - v2: [ #message - { - Transact: { - originType: Superuser, - requireWeightAtMost: *weight_at_most, - call: $xcm_init_open_channel_with_cp - } - } - ] - } - ] - events: - - name: sudo.Sudid - attribute: - type: Result - value: Ok - - name: xcmPallet.Sent - - name: dmpQueue.ExecutedDownward - chain: *assets_parachain - attribute: - type: XcmV2TraitsOutcome - isComplete: true - threshold: [10, 10] - value: 1,020,807,000 - - name: polkadotXcm.Sent - chain: *assets_parachain - - name: ump.ExecutedUpward - timeout: 40000 - attribute: - type: XcmV2TraitsOutcome - isComplete: true - value: 4,000,000,000 - - name: hrmp.OpenChannelRequested - timeout: 40000 - - queries: - requested_channels: - chain: *relay_chain - pallet: hrmp - call: hrmpOpenChannelRequestsList - args: [] - - asserts: - equal: - args: [ - $requested_channels, - [ - { - sender: *ap_id, - recipient: *pp_id - } - ] - ] - - - name: hrmp.hrmpAcceptOpenChannel (Penpal Parachain → Assets Parachain) - its: - - name: Penpal Parachain sends a response to the Relay Chain accepting the Assets Parachain's request for openning a HRMP channel - actions: - - extrinsics: - - chain: *penpal_parachain - signer: *pp_signer - sudo: true - pallet: polkadotXcm - call: send - args: [ - *rc_dest, # destination - { - v2: [ #message - { - WithdrawAsset: [*rc_ksm_fungible] - }, - { - BuyExecution: { - fees: *rc_ksm_fungible, - weightLimit: Unlimited - } - }, - { - Transact: { - originType: Native, - requireWeightAtMost: *weight_at_most, - call: $accept_open_channel_with_ap - } - } - ] - } - ] - events: - - name: sudo.Sudid - attribute: - type: Result - value: Ok - - name: polkadotXcm.Sent - - name: ump.ExecutedUpward - chain: *relay_chain - attribute: - type: XcmV2TraitsOutcome - isComplete: true - value: 4,000,000,000 - - name: hrmp.OpenChannelAccepted - chain: *relay_chain diff --git a/parachains/integration-tests/statemint/xcm/4_hrmp.yml b/parachains/integration-tests/statemint/xcm/4_hrmp.yml deleted file mode 100644 index 00a3ff467bc..00000000000 --- a/parachains/integration-tests/statemint/xcm/4_hrmp.yml +++ /dev/null @@ -1,356 +0,0 @@ ---- -settings: - chains: - relay_chain: &relay_chain - wsPort: 9900 - assets_parachain: &assets_parachain - wsPort: 9910 - paraId: &ap_id 1000 - penpal_parachain: &penpal_parachain - wsPort: 9920 - paraId: &pp_id 2000 - variables: - common: - amount: &amount 1000000000000 - require_weight_at_most: &weight_at_most 1000000000 - amount_to_send: &amount_to_send 500000000000 - chains: - relay_chain: - signer: &rc_signer //Alice - assets_parachain_destination: &ap_dest { v1: { 0, interior: { x1: { parachain: *ap_id }}}} - assets_parachain_dest_routed: &ap_dest_routed { v1: { parents: 1, interior: { x1: { parachain: *ap_id } }}} - assets_parachain_account: - signer: &ap_signer //Alice - wallet: &ap_wallet HNZata7iMYWmk5RvZRTiAsSDhV8366zq2YGb3tLH5Upf74F - asset_id: &asset_id 2 - assets_pallet_id: &assets_pallet_id 50 - asset_min_balance: &asset_ed 1000 - penpal_parachain_destination: &pp_dest { v1: { parents: 1, interior: { x1: { parachain: *pp_id } }}} - ksm: &ap_ksm { concrete: { parents: 1, interior: { here: true }}} - ksm_fungible: &ap_ksm_fungible { id: *ap_ksm, fun: { fungible: *amount }} - suff_asset: &suff_asset { concrete: { parents: 0, interior: { x2: [ { PalletInstance: *assets_pallet_id }, { GeneralIndex: *asset_id } ] }}} - suff_asset_fail: &suff_asset_fail { concrete: { parents: 0, interior: { x2: [ { PalletInstance: *assets_pallet_id }, { GeneralIndex: 3 } ] }}} - suff_asset_fungible: &ap_suff_asset_fungible { id: *suff_asset, fun: { fungible: *weight_at_most }} - suff_asset_fungible_fail: &ap_suff_asset_fungible_fail { id: *suff_asset_fail, fun: { fungible: *weight_at_most }} - penpal_parachain: - sovereign_account: &pp_sovereign_sibl 13cKp89Msu7M2PiaCuuGr1BzAsD5V3vaVbDMs3YtjMZHdGwR - signer: &pp_signer //Alice - penpal_parachain_account: &pp_acc '0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d' - decodedCalls: - force_create_asset: - chain: *assets_parachain - pallet: assets - call: forceCreate - args: [ - *asset_id, - { Id: *ap_wallet }, # owner - true, # isSufficient - *asset_ed # minBalance - ] - system_remark_with_event: - chain: *assets_parachain - pallet: system - call: remarkWithEvent - args: [ 0x0011 ] - -tests: - - name: HRMP - describes: - - name: polkadotXcm.limitedReserveTransferAssets (Asset) | Assets Parachain -> Penpal Parachain - before: - - name: DEPENDANCY | A sufficient Asset should exist in the Assets Parachain - actions: - - extrinsics: - - chain: *relay_chain - signer: *rc_signer - sudo: true - pallet: xcmPallet - call: send - args: [ - *ap_dest, # destination - { - v2: [ #message - { - Transact: { - originType: Superuser, - requireWeightAtMost: *weight_at_most, - call: $force_create_asset - } - } - ] - } - ] - events: - - name: xcmPallet.Sent - - name: dmpQueue.ExecutedDownward - chain: *assets_parachain - attribute: - type: XcmV2TraitsOutcome - isComplete: true - threshold: [10, 10] - value: 1,020,807,000 - - queries: - forced_created_asset: - chain: *assets_parachain - pallet: assets - call: asset - args: [ *asset_id ] - - asserts: - isSome: - args: [ $forced_created_asset ] - - - name: DEPENDANCY | Some Assets should be minted for the sender - actions: - - extrinsics: - - chain: *assets_parachain - signer: *ap_signer - pallet: assets - call: mint - args: [ - *asset_id, - *ap_wallet, - *amount - ] - events: - - name: assets.Issued - - its: - - name: Assets Parachain should be able to reserve transfer an Asset to Penpal Parachain - actions: - - extrinsics: - - chain: *assets_parachain - signer: *ap_signer - pallet: polkadotXcm - call: limitedReserveTransferAssets - args: [ - *pp_dest, # destination - { # beneficiary - V1: { - parents: 0, - interior: { - X1: { - AccountId32: { - network: Any, - id: *pp_acc - } - } - } - } - }, - { # assets - V1: [ - { - id: { - Concrete: { - parents: 0, - interior: { - X2: [ - { - PalletInstance: 50 - }, - { - GeneralIndex: *asset_id - } - ] - } - } - }, - fun: { - Fungible: *amount_to_send - } - } - ] - }, - 0, # feeAssetItem - Unlimited # weightLimit - ] - events: - - name: polkadotXcm.Attempted - attribute: - type: XcmV2TraitsOutcome - isComplete: true - threshold: [10, 10] - value: 654,404,000 - - name: assets.Transferred - attribute: - type: AccountId32 - value: *pp_sovereign_sibl - - name: assets.Transferred - attribute: - type: u128 - value: *amount_to_send - - - name: polkadotXcm.limitedReserveTransferAssets (KSM) | Assets Parachain -> Penpal Parachain - its: - - name: Assets Parachain should be able to reserve transfer KSM to Penpal Parachain - actions: - - extrinsics: - - chain: *assets_parachain - signer: *ap_signer - pallet: polkadotXcm - call: limitedReserveTransferAssets - args: [ - *pp_dest, # destination - { # beneficiary - V1: { - parents: 0, - interior: { - X1: { - AccountId32: { - network: Any, - id: *pp_acc - } - } - } - } - }, - { # assets - V1: [ - *ap_ksm_fungible - ] - }, - 0, # feeAssetItem - Unlimited # weightLimit - ] - events: - - name: polkadotXcm.Attempted - attribute: - type: XcmV2TraitsOutcome - isComplete: true - threshold: [10, 10] - value: 654,404,000 - - name: balances.Endowed - attribute: - type: AccountId32 - value: *pp_sovereign_sibl - - name: balances.Endowed - attribute: - type: u128 - value: *amount - - - name: polkadotXcm.send( system.remarkWithEvent() ) | Penpal Parachain -> Assets Parachain - before: - - name: Get the asset balance of the Penpal Parachain Sovereign account in Assets Parachain - actions: - - queries: - assets_balance_pp_sovereign_before: - chain: *assets_parachain - pallet: assets - call: account - args: [ - *asset_id, - *pp_sovereign_sibl - ] - its: - - name: Penpal Parachain should be able to send XCM message paying its fee with sufficient asset in Assets Parachain - actions: - - extrinsics: - - chain: *penpal_parachain - signer: *pp_signer - sudo: true - pallet: polkadotXcm - call: send - args: [ - *ap_dest_routed, # destination - { - v2: [ #message - { - WithdrawAsset: [*ap_suff_asset_fungible] - }, - { - BuyExecution: { - fees: *ap_suff_asset_fungible, - weightLimit: Unlimited - } - }, - { - Transact: { - originType: SovereignAccount, - requireWeightAtMost: *weight_at_most, - call: $system_remark_with_event - } - } - ] - } - ] - events: - - name: sudo.Sudid - attribute: - type: Result - value: Ok - - name: polkadotXcm.Sent - - name: assets.Burned - chain: *assets_parachain - attribute: - type: AccountId32 - value: *pp_sovereign_sibl - - name: assets.Issued - chain: *assets_parachain - attribute: - type: u32 - value: *asset_id - - name: system.Remarked - chain: *assets_parachain - attribute: - type: AccountId32 - value: *pp_sovereign_sibl - - queries: - assets_balance_pp_sovereign_after: - chain: *assets_parachain - pallet: assets - call: account - args: [ - *asset_id, - *pp_sovereign_sibl - ] - - - name: Should reduce the assets balance of the Penpal Parachain's SovereignAccount in the Assets Parachain - actions: - - asserts: - assetsDecreased: - args: [ - { - balances: { - before: $assets_balance_pp_sovereign_before, - after: $assets_balance_pp_sovereign_after, - }, - } - ] - - - name: Penpal Parachain SHOULD NOT be able to send XCM message paying its fee with sufficient assets if not enough balance - actions: - - extrinsics: - - chain: *penpal_parachain - signer: *pp_signer - sudo: true - pallet: polkadotXcm - call: send - args: [ - *ap_dest_routed, # destination - { - v2: [ #message - { - WithdrawAsset: [*ap_suff_asset_fungible_fail] - }, - { - BuyExecution: { - fees: *ap_suff_asset_fungible_fail, - weightLimit: Unlimited - } - }, - { - Transact: { - originType: SovereignAccount, - requireWeightAtMost: *weight_at_most, - call: $system_remark_with_event - } - } - ] - } - ] - events: - - name: xcmpQueue.Fail - chain: *assets_parachain - attribute: - type: XcmV2TraitsError - value: FailedToTransactAsset diff --git a/xcm/xcm-emulator/Cargo.toml b/xcm/xcm-emulator/Cargo.toml new file mode 100644 index 00000000000..8da28d0283f --- /dev/null +++ b/xcm/xcm-emulator/Cargo.toml @@ -0,0 +1,37 @@ +[package] +name = "xcm-emulator" +description = "Test kit to emulate XCM program execution." +version = "0.1.0" +authors = ["Parity Technologies "] +edition = "2021" + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.0.0" } +paste = "1.0.5" +quote = "1.0.23" +casey = "0.3.3" +log = { version = "0.4.17", default-features = false } + +frame-support = { git = "https://github.com/paritytech/substrate", branch = "master" } +frame-system = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-std = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-arithmetic = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-trie = { git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master" } + +cumulus-primitives-core = { path = "../../primitives/core"} +cumulus-pallet-xcmp-queue = { path = "../../pallets/xcmp-queue" } +cumulus-pallet-dmp-queue = { path = "../../pallets/dmp-queue" } +cumulus-pallet-parachain-system = { path = "../../pallets/parachain-system" } +cumulus-test-service = { path = "../../test/service" } +parachain-info = { path = "../../parachains/pallets/parachain-info" } +cumulus-primitives-parachain-inherent = { path = "../../primitives/parachain-inherent" } +cumulus-test-relay-sproof-builder = { path = "../../test/relay-sproof-builder" } +parachains-common = { path = "../../parachains/common" } + +xcm = { git = "https://github.com/paritytech/polkadot", branch = "master" } +xcm-executor = { git = "https://github.com/paritytech/polkadot", branch = "master" } +polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "master" } +polkadot-runtime-parachains = { git = "https://github.com/paritytech/polkadot", branch = "master" } diff --git a/xcm/xcm-emulator/README.md b/xcm/xcm-emulator/README.md new file mode 100644 index 00000000000..5087ae4ac3c --- /dev/null +++ b/xcm/xcm-emulator/README.md @@ -0,0 +1,20 @@ +# xcm-emulator + +XCM-Emulator is a tool to emulate XCM program execution using +pre-configured runtimes, including those used to run on live +networks, such as Kusama, Polkadot, Statemine et cetera. +This allows for testing cross-chain message passing and verifying +outcomes, weights, and side-effects. It is faster than spinning up +a zombienet and as all the chains are in one process debugging using Clion is easy. + +## Limitations + +As the messages do not physically go through the same messaging infrastructure +there is some code that is not being tested compared to using slower E2E tests. +In future it may be possible to run these XCM emulated tests as E2E tests (without changes). + +## Alternatives + +If you just wish to test execution of various XCM instructions +against the XCM VM then the `xcm-simulator` (in the polkadot +repo) is the perfect tool for this. diff --git a/xcm/xcm-emulator/src/lib.rs b/xcm/xcm-emulator/src/lib.rs new file mode 100644 index 00000000000..b928d5cf76e --- /dev/null +++ b/xcm/xcm-emulator/src/lib.rs @@ -0,0 +1,939 @@ +// Copyright 2023 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot 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. + +// Polkadot 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 Polkadot. If not, see . + +pub use casey::pascal; +pub use codec::Encode; +pub use frame_support::{ + sp_runtime::BuildStorage, + traits::{Get, Hooks}, + weights::Weight, +}; +pub use frame_system::AccountInfo; +pub use log; +pub use pallet_balances::AccountData; +pub use paste; +pub use sp_arithmetic::traits::Bounded; +pub use sp_core::storage::Storage; +pub use sp_io::TestExternalities; +pub use sp_std::{cell::RefCell, collections::vec_deque::VecDeque, marker::PhantomData}; +pub use sp_trie::StorageProof; + +pub use cumulus_pallet_dmp_queue; +pub use cumulus_pallet_parachain_system; +pub use cumulus_pallet_xcmp_queue; +pub use cumulus_primitives_core::{ + self, relay_chain::BlockNumber as RelayBlockNumber, DmpMessageHandler, ParaId, + PersistedValidationData, XcmpMessageHandler, +}; +pub use cumulus_primitives_parachain_inherent::ParachainInherentData; +pub use cumulus_test_relay_sproof_builder::RelayStateSproofBuilder; +pub use cumulus_test_service::get_account_id_from_seed; +pub use parachain_info; +pub use parachains_common::{AccountId, BlockNumber}; + +pub use polkadot_primitives; +pub use polkadot_runtime_parachains::{ + dmp, + ump::{MessageId, UmpSink, XcmSink}, +}; +pub use std::{collections::HashMap, thread::LocalKey}; +pub use xcm::{v3::prelude::*, VersionedXcm}; +pub use xcm_executor::XcmExecutor; + +thread_local! { + /// Downward messages, each message is: `(to_para_id, [(relay_block_number, msg)])` + #[allow(clippy::type_complexity)] + pub static DOWNWARD_MESSAGES: RefCell)>)>>> + = RefCell::new(HashMap::new()); + /// Downward messages that already processed by parachains, each message is: `(to_para_id, relay_block_number, Vec)` + #[allow(clippy::type_complexity)] + pub static DMP_DONE: RefCell)>>> + = RefCell::new(HashMap::new()); + /// Horizontal messages, each message is: `(to_para_id, [(from_para_id, relay_block_number, msg)])` + #[allow(clippy::type_complexity)] + pub static HORIZONTAL_MESSAGES: RefCell)>)>>> + = RefCell::new(HashMap::new()); + /// Upward messages, each message is: `(from_para_id, msg) + pub static UPWARD_MESSAGES: RefCell)>>> = RefCell::new(HashMap::new()); + /// Global incremental relay chain block number + pub static RELAY_BLOCK_NUMBER: RefCell> = RefCell::new(HashMap::new()); + /// Parachains Ids a the Network + pub static PARA_IDS: RefCell>> = RefCell::new(HashMap::new()); + /// Flag indicating if global variables have been initialized for a certain Network + pub static INITIALIZED: RefCell> = RefCell::new(HashMap::new()); +} + +pub trait TestExt { + fn build_new_ext(storage: Storage) -> sp_io::TestExternalities; + fn new_ext() -> sp_io::TestExternalities; + fn reset_ext(); + fn execute_with(execute: impl FnOnce() -> R) -> R; + fn ext_wrapper(func: impl FnOnce() -> R) -> R; +} + +pub trait Network { + fn _init(); + fn _para_ids() -> Vec; + fn _relay_block_number() -> u32; + fn _set_relay_block_number(block_number: u32); + fn _process_messages(); + fn _has_unprocessed_messages() -> bool; + fn _process_downward_messages(); + fn _process_horizontal_messages(); + fn _process_upward_messages(); + fn _hrmp_channel_parachain_inherent_data( + para_id: u32, + relay_parent_number: u32, + ) -> ParachainInherentData; +} + +pub trait NetworkComponent { + fn network_name() -> &'static str; + + fn init() { + N::_init(); + } + + fn relay_block_number() -> u32 { + N::_relay_block_number() + } + + fn set_relay_block_number(block_number: u32) { + N::_set_relay_block_number(block_number); + } + + fn para_ids() -> Vec { + N::_para_ids() + } + + fn send_horizontal_messages)>>( + to_para_id: u32, + iter: I, + ) { + HORIZONTAL_MESSAGES.with(|b| { + b.borrow_mut() + .get_mut(Self::network_name()) + .unwrap() + .push_back((to_para_id, iter.collect())) + }); + } + + fn send_upward_message(from_para_id: u32, msg: Vec) { + UPWARD_MESSAGES.with(|b| { + b.borrow_mut() + .get_mut(Self::network_name()) + .unwrap() + .push_back((from_para_id, msg)) + }); + } + + fn send_downward_messages( + to_para_id: u32, + iter: impl Iterator)>, + ) { + DOWNWARD_MESSAGES.with(|b| { + b.borrow_mut() + .get_mut(Self::network_name()) + .unwrap() + .push_back((to_para_id, iter.collect())) + }); + } + + fn hrmp_channel_parachain_inherent_data( + para_id: u32, + relay_parent_number: u32, + ) -> ParachainInherentData { + N::_hrmp_channel_parachain_inherent_data(para_id, relay_parent_number) + } + + fn process_messages() { + N::_process_messages(); + } +} + +pub trait RelayChain: UmpSink { + type Runtime; + type RuntimeOrigin; + type RuntimeCall; + type RuntimeEvent; + type XcmConfig; + type SovereignAccountOf; + type System; + type Balances; +} + +pub trait Parachain: XcmpMessageHandler + DmpMessageHandler { + type Runtime; + type RuntimeOrigin; + type RuntimeCall; + type RuntimeEvent; + type XcmpMessageHandler; + type DmpMessageHandler; + type LocationToAccountId; + type System; + type Balances; + type ParachainSystem; + type ParachainInfo; +} + +// Relay Chain Implementation +#[macro_export] +macro_rules! decl_test_relay_chains { + ( + $( + pub struct $name:ident { + genesis = $genesis:expr, + on_init = $on_init:expr, + runtime = { + Runtime: $($runtime:tt)::*, + RuntimeOrigin: $($runtime_origin:tt)::*, + RuntimeCall: $($runtime_call:tt)::*, + RuntimeEvent: $($runtime_event:tt)::*, + XcmConfig: $($xcm_config:tt)::*, + SovereignAccountOf: $($sovereign_acc_of:tt)::*, + System: $($system:tt)::*, + Balances: $($balances:tt)::*, + }, + pallets_extra = { + $($pallet_name:ident: $pallet_path:path,)* + } + } + ), + + + ) => { + $( + pub struct $name; + + impl RelayChain for $name { + type Runtime = $($runtime)::*; + type RuntimeOrigin = $($runtime_origin)::*; + type RuntimeCall = $($runtime_call)::*; + type RuntimeEvent = $($runtime_event)::*; + type XcmConfig = $($xcm_config)::*; + type SovereignAccountOf = $($sovereign_acc_of)::*; + type System = $($system)::*; + type Balances = $($balances)::*; + } + + $crate::paste::paste! { + pub trait [<$name Pallet>] { + $( + type $pallet_name; + )? + } + + impl [<$name Pallet>] for $name { + $( + type $pallet_name = $pallet_path; + )? + } + } + + $crate::__impl_xcm_handlers_for_relay_chain!($name); + $crate::__impl_test_ext_for_relay_chain!($name, $genesis, $on_init); + )+ + }; +} + +#[macro_export] +macro_rules! __impl_xcm_handlers_for_relay_chain { + ($name:ident) => { + impl $crate::UmpSink for $name { + fn process_upward_message( + origin: $crate::ParaId, + msg: &[u8], + max_weight: $crate::Weight, + ) -> Result<$crate::Weight, ($crate::MessageId, $crate::Weight)> { + use $crate::{TestExt, UmpSink}; + + Self::execute_with(|| { + $crate::XcmSink::< + $crate::XcmExecutor<::XcmConfig>, + ::Runtime, + >::process_upward_message(origin, msg, max_weight) + }) + } + } + }; +} + +#[macro_export] +macro_rules! __impl_test_ext_for_relay_chain { + // entry point: generate ext name + ($name:ident, $genesis:expr, $on_init:expr) => { + $crate::paste::paste! { + $crate::__impl_test_ext_for_relay_chain!(@impl $name, $genesis, $on_init, []); + } + }; + // impl + (@impl $name:ident, $genesis:expr, $on_init:expr, $ext_name:ident) => { + thread_local! { + pub static $ext_name: $crate::RefCell<$crate::TestExternalities> + = $crate::RefCell::new(<$name>::build_new_ext($genesis)); + } + + impl TestExt for $name { + fn build_new_ext(storage: $crate::Storage) -> $crate::TestExternalities { + let mut ext = sp_io::TestExternalities::new(storage); + ext.execute_with(|| { + #[allow(clippy::no_effect)] + $on_init; + sp_tracing::try_init_simple(); + ::System::set_block_number(1); + }); + ext + } + + fn new_ext() -> $crate::TestExternalities { + <$name>::build_new_ext($genesis) + } + + fn reset_ext() { + $ext_name.with(|v| *v.borrow_mut() = <$name>::build_new_ext($genesis)); + } + + fn execute_with(execute: impl FnOnce() -> R) -> R { + use $crate::{NetworkComponent}; + // Make sure the Network is initialized + <$name>::init(); + + let r = $ext_name.with(|v| v.borrow_mut().execute_with(execute)); + + // send messages if needed + $ext_name.with(|v| { + v.borrow_mut().execute_with(|| { + use $crate::polkadot_primitives::runtime_api::runtime_decl_for_parachain_host::ParachainHostV4; + + //TODO: mark sent count & filter out sent msg + for para_id in <$name>::para_ids() { + // downward messages + let downward_messages = ::Runtime::dmq_contents(para_id.into()) + .into_iter() + .map(|inbound| (inbound.sent_at, inbound.msg)); + if downward_messages.len() == 0 { + continue; + } + <$name>::send_downward_messages(para_id, downward_messages.into_iter()); + + // Note: no need to handle horizontal messages, as the + // simulator directly sends them to dest (not relayed). + } + }) + }); + + <$name>::process_messages(); + + r + } + + fn ext_wrapper(func: impl FnOnce() -> R) -> R { + $ext_name.with(|v| { + v.borrow_mut().execute_with(|| { + func() + }) + }) + } + } + }; +} + +#[macro_export] +macro_rules! __impl_relay { + ($network_name:ident, $relay_chain:ty) => { + impl $crate::NetworkComponent<$network_name> for $relay_chain { + fn network_name() -> &'static str { + stringify!($network_name) + } + } + + impl $relay_chain { + pub fn child_location_of(id: $crate::ParaId) -> MultiLocation { + (Ancestor(0), Parachain(id.into())).into() + } + + pub fn account_id_of(seed: &str) -> $crate::AccountId { + $crate::get_account_id_from_seed::(seed) + } + + pub fn account_data_of(account: AccountId) -> $crate::AccountData { + Self::ext_wrapper(|| ::System::account(account).data) + } + + pub fn sovereign_account_id_of(location: $crate::MultiLocation) -> $crate::AccountId { + ::SovereignAccountOf::convert(location.into()).unwrap() + } + + pub fn fund_accounts(accounts: Vec<(AccountId, Balance)>) { + Self::ext_wrapper(|| { + for account in accounts { + let _ = ::Balances::force_set_balance( + ::RuntimeOrigin::root(), + account.0.into(), + account.1.into(), + ); + } + }); + } + + pub fn events() -> Vec<::RuntimeEvent> { + ::System::events() + .iter() + .map(|record| record.event.clone()) + .collect() + } + } + }; +} + +// Parachain Implementation +#[macro_export] +macro_rules! decl_test_parachains { + ( + $( + pub struct $name:ident { + genesis = $genesis:expr, + on_init = $on_init:expr, + runtime = { + Runtime: $runtime:path, + RuntimeOrigin: $runtime_origin:path, + RuntimeCall: $runtime_call:path, + RuntimeEvent: $runtime_event:path, + XcmpMessageHandler: $xcmp_message_handler:path, + DmpMessageHandler: $dmp_message_handler:path, + LocationToAccountId: $location_to_account:path, + System: $system:path, + Balances: $balances_pallet:path, + ParachainSystem: $parachain_system:path, + ParachainInfo: $parachain_info:path, + }, + pallets_extra = { + $($pallet_name:ident: $pallet_path:path,)* + } + } + ), + + + ) => { + $( + pub struct $name; + + impl Parachain for $name { + type Runtime = $runtime; + type RuntimeOrigin = $runtime_origin; + type RuntimeCall = $runtime_call; + type RuntimeEvent = $runtime_event; + type XcmpMessageHandler = $xcmp_message_handler; + type DmpMessageHandler = $dmp_message_handler; + type LocationToAccountId = $location_to_account; + type System = $system; + type Balances = $balances_pallet; + type ParachainSystem = $parachain_system; + type ParachainInfo = $parachain_info; + } + + $crate::paste::paste! { + pub trait [<$name Pallet>] { + $( + type $pallet_name; + )* + } + + impl [<$name Pallet>] for $name { + $( + type $pallet_name = $pallet_path; + )* + } + } + + $crate::__impl_xcm_handlers_for_parachain!($name); + $crate::__impl_test_ext_for_parachain!($name, $genesis, $on_init); + )+ + }; +} + +#[macro_export] +macro_rules! __impl_xcm_handlers_for_parachain { + ($name:ident) => { + impl $crate::XcmpMessageHandler for $name { + fn handle_xcmp_messages< + 'a, + I: Iterator, + >( + iter: I, + max_weight: $crate::Weight, + ) -> $crate::Weight { + use $crate::{TestExt, XcmpMessageHandler}; + + $name::execute_with(|| { + ::XcmpMessageHandler::handle_xcmp_messages(iter, max_weight) + }) + } + } + + impl $crate::DmpMessageHandler for $name { + fn handle_dmp_messages( + iter: impl Iterator)>, + max_weight: $crate::Weight, + ) -> $crate::Weight { + use $crate::{DmpMessageHandler, TestExt}; + + $name::execute_with(|| { + ::DmpMessageHandler::handle_dmp_messages(iter, max_weight) + }) + } + } + }; +} + +#[macro_export] +macro_rules! __impl_test_ext_for_parachain { + // entry point: generate ext name + ($name:ident, $genesis:expr, $on_init:expr) => { + $crate::paste::paste! { + $crate::__impl_test_ext_for_parachain!(@impl $name, $genesis, $on_init, []); + } + }; + // impl + (@impl $name:ident, $genesis:expr, $on_init:expr, $ext_name:ident) => { + thread_local! { + pub static $ext_name: $crate::RefCell<$crate::TestExternalities> + = $crate::RefCell::new(<$name>::build_new_ext($genesis)); + } + + impl TestExt for $name { + fn build_new_ext(storage: $crate::Storage) -> $crate::TestExternalities { + let mut ext = sp_io::TestExternalities::new(storage); + ext.execute_with(|| { + #[allow(clippy::no_effect)] + $on_init; + sp_tracing::try_init_simple(); + ::System::set_block_number(1); + }); + ext + } + + fn new_ext() -> $crate::TestExternalities { + <$name>::build_new_ext($genesis) + } + + fn reset_ext() { + $ext_name.with(|v| *v.borrow_mut() = <$name>::build_new_ext($genesis)); + } + + fn execute_with(execute: impl FnOnce() -> R) -> R { + use $crate::{Get, Hooks, NetworkComponent}; + + // Make sure the Network is initialized + <$name>::init(); + + let mut relay_block_number = <$name>::relay_block_number(); + relay_block_number += 1; + <$name>::set_relay_block_number(relay_block_number); + + let para_id = <$name>::para_id().into(); + + $ext_name.with(|v| { + v.borrow_mut().execute_with(|| { + // Make sure it has been recorded properly + let relay_block_number = <$name>::relay_block_number(); + let _ = ::ParachainSystem::set_validation_data( + ::RuntimeOrigin::none(), + <$name>::hrmp_channel_parachain_inherent_data(para_id, relay_block_number), + ); + }) + }); + + + let r = $ext_name.with(|v| v.borrow_mut().execute_with(execute)); + + // send messages if needed + $ext_name.with(|v| { + v.borrow_mut().execute_with(|| { + use sp_runtime::traits::Header as HeaderT; + + let block_number = ::System::block_number(); + let mock_header = HeaderT::new( + 0, + Default::default(), + Default::default(), + Default::default(), + Default::default(), + ); + + // get messages + ::ParachainSystem::on_finalize(block_number); + let collation_info = ::ParachainSystem::collect_collation_info(&mock_header); + + // send upward messages + let relay_block_number = <$name>::relay_block_number(); + for msg in collation_info.upward_messages.clone() { + <$name>::send_upward_message(para_id, msg); + } + + // send horizontal messages + for msg in collation_info.horizontal_messages { + <$name>::send_horizontal_messages( + msg.recipient.into(), + vec![(para_id.into(), relay_block_number, msg.data)].into_iter(), + ); + } + + // clean messages + ::ParachainSystem::on_initialize(block_number); + }) + }); + + <$name>::process_messages(); + + r + } + + fn ext_wrapper(func: impl FnOnce() -> R) -> R { + $ext_name.with(|v| { + v.borrow_mut().execute_with(|| { + func() + }) + }) + } + } + }; +} + +#[macro_export] +macro_rules! __impl_parachain { + ($network_name:ident, $parachain:ty) => { + impl $crate::NetworkComponent<$network_name> for $parachain { + fn network_name() -> &'static str { + stringify!($network_name) + } + } + + impl $parachain { + pub fn para_id() -> $crate::ParaId { + Self::ext_wrapper(|| ::ParachainInfo::get()) + } + + pub fn parent_location() -> $crate::MultiLocation { + (Parent).into() + } + + pub fn account_id_of(seed: &str) -> $crate::AccountId { + $crate::get_account_id_from_seed::(seed) + } + + pub fn account_data_of(account: AccountId) -> $crate::AccountData { + Self::ext_wrapper(|| ::System::account(account).data) + } + + pub fn sovereign_account_id_of(location: $crate::MultiLocation) -> $crate::AccountId { + ::LocationToAccountId::convert(location.into()).unwrap() + } + + pub fn fund_accounts(accounts: Vec<(AccountId, Balance)>) { + Self::ext_wrapper(|| { + for account in accounts { + let _ = ::Balances::force_set_balance( + ::RuntimeOrigin::root(), + account.0.into(), + account.1.into(), + ); + } + }); + } + + pub fn events() -> Vec<::RuntimeEvent> { + ::System::events() + .iter() + .map(|record| record.event.clone()) + .collect() + } + + fn prepare_for_xcmp() { + use $crate::NetworkComponent; + let para_id = Self::para_id(); + + ::ext_wrapper(|| { + use $crate::{Get, Hooks}; + + let block_number = ::System::block_number(); + + let _ = ::ParachainSystem::set_validation_data( + ::RuntimeOrigin::none(), + Self::hrmp_channel_parachain_inherent_data(para_id.into(), 1), + ); + // set `AnnouncedHrmpMessagesPerCandidate` + ::ParachainSystem::on_initialize(block_number); + }); + } + } + }; +} + +// Network Implementation +#[macro_export] +macro_rules! decl_test_networks { + ( + $( + pub struct $name:ident { + relay_chain = $relay_chain:ty, + parachains = vec![ $( $parachain:ty, )* ], + } + ), + + + ) => { + $( + pub struct $name; + + impl $name { + pub fn reset() { + use $crate::{TestExt, VecDeque}; + + $crate::INITIALIZED.with(|b| b.borrow_mut().remove(stringify!($name))); + $crate::DOWNWARD_MESSAGES.with(|b| b.borrow_mut().remove(stringify!($name))); + $crate::DMP_DONE.with(|b| b.borrow_mut().remove(stringify!($name))); + $crate::UPWARD_MESSAGES.with(|b| b.borrow_mut().remove(stringify!($name))); + $crate::HORIZONTAL_MESSAGES.with(|b| b.borrow_mut().remove(stringify!($name))); + $crate::RELAY_BLOCK_NUMBER.with(|b| b.borrow_mut().remove(stringify!($name))); + + <$relay_chain>::reset_ext(); + $( <$parachain>::reset_ext(); )* + $( <$parachain>::prepare_for_xcmp(); )* + } + } + + impl $crate::Network for $name { + fn _init() { + // If Network has not been itialized yet, it gets initialized + if $crate::INITIALIZED.with(|b| b.borrow_mut().get(stringify!($name)).is_none()) { + $crate::INITIALIZED.with(|b| b.borrow_mut().insert(stringify!($name).to_string(), true)); + $crate::DOWNWARD_MESSAGES.with(|b| b.borrow_mut().insert(stringify!($name).to_string(), $crate::VecDeque::new())); + $crate::DMP_DONE.with(|b| b.borrow_mut().insert(stringify!($name).to_string(), $crate::VecDeque::new())); + $crate::UPWARD_MESSAGES.with(|b| b.borrow_mut().insert(stringify!($name).to_string(), $crate::VecDeque::new())); + $crate::HORIZONTAL_MESSAGES.with(|b| b.borrow_mut().insert(stringify!($name).to_string(), $crate::VecDeque::new())); + $crate::RELAY_BLOCK_NUMBER.with(|b| b.borrow_mut().insert(stringify!($name).to_string(), 1)); + $crate::PARA_IDS.with(|b| b.borrow_mut().insert(stringify!($name).to_string(), Self::_para_ids())); + } + } + + fn _para_ids() -> Vec { + vec![$( + <$parachain>::para_id().into(), + )*] + } + + fn _relay_block_number() -> u32 { + $crate::RELAY_BLOCK_NUMBER.with(|v| *v.clone().borrow().get(stringify!($name)).unwrap()) + } + + fn _set_relay_block_number(block_number: u32) { + $crate::RELAY_BLOCK_NUMBER.with(|v| v.borrow_mut().insert(stringify!($name).to_string(), block_number)); + } + + fn _process_messages() { + while Self::_has_unprocessed_messages() { + Self::_process_upward_messages(); + Self::_process_horizontal_messages(); + Self::_process_downward_messages(); + } + } + + fn _has_unprocessed_messages() -> bool { + $crate::DOWNWARD_MESSAGES.with(|b| !b.borrow_mut().get_mut(stringify!($name)).unwrap().is_empty()) + || $crate::HORIZONTAL_MESSAGES.with(|b| !b.borrow_mut().get_mut(stringify!($name)).unwrap().is_empty()) + || $crate::UPWARD_MESSAGES.with(|b| !b.borrow_mut().get_mut(stringify!($name)).unwrap().is_empty()) + } + + fn _process_downward_messages() { + use $crate::{DmpMessageHandler, Bounded}; + use polkadot_parachain::primitives::RelayChainBlockNumber; + + while let Some((to_para_id, messages)) + = $crate::DOWNWARD_MESSAGES.with(|b| b.borrow_mut().get_mut(stringify!($name)).unwrap().pop_front()) { + $( + if $crate::PARA_IDS.with(|b| b.borrow_mut().get_mut(stringify!($name)).unwrap().contains(&to_para_id)) { + let mut msg_dedup: Vec<(RelayChainBlockNumber, Vec)> = Vec::new(); + for m in &messages { + msg_dedup.push((m.0, m.1.clone())); + } + msg_dedup.dedup(); + + let msgs = msg_dedup.clone().into_iter().filter(|m| { + !$crate::DMP_DONE.with(|b| b.borrow_mut().get_mut(stringify!($name)).unwrap_or(&mut $crate::VecDeque::new()).contains(&(to_para_id, m.0, m.1.clone()))) + }).collect::)>>(); + if msgs.len() != 0 { + <$parachain>::handle_dmp_messages(msgs.clone().into_iter(), $crate::Weight::max_value()); + for m in msgs { + $crate::DMP_DONE.with(|b| b.borrow_mut().get_mut(stringify!($name)).unwrap().push_back((to_para_id, m.0, m.1))); + } + } + } else { + unreachable!(); + } + )* + } + } + + fn _process_horizontal_messages() { + use $crate::{XcmpMessageHandler, Bounded}; + + while let Some((to_para_id, messages)) + = $crate::HORIZONTAL_MESSAGES.with(|b| b.borrow_mut().get_mut(stringify!($name)).unwrap().pop_front()) { + let iter = messages.iter().map(|(p, b, m)| (*p, *b, &m[..])).collect::>().into_iter(); + $( + if $crate::PARA_IDS.with(|b| b.borrow_mut().get_mut(stringify!($name)).unwrap().contains(&to_para_id)) { + <$parachain>::handle_xcmp_messages(iter.clone(), $crate::Weight::max_value()); + } + )* + } + } + + fn _process_upward_messages() { + use $crate::{UmpSink, Bounded}; + while let Some((from_para_id, msg)) = $crate::UPWARD_MESSAGES.with(|b| b.borrow_mut().get_mut(stringify!($name)).unwrap().pop_front()) { + let _ = <$relay_chain>::process_upward_message( + from_para_id.into(), + &msg[..], + $crate::Weight::max_value(), + ); + } + } + + fn _hrmp_channel_parachain_inherent_data( + para_id: u32, + relay_parent_number: u32, + ) -> $crate::ParachainInherentData { + use $crate::cumulus_primitives_core::{relay_chain::HrmpChannelId, AbridgedHrmpChannel}; + + let mut sproof = $crate::RelayStateSproofBuilder::default(); + sproof.para_id = para_id.into(); + + // egress channel + let e_index = sproof.hrmp_egress_channel_index.get_or_insert_with(Vec::new); + for recipient_para_id in $crate::PARA_IDS.with(|b| b.borrow_mut().get_mut(stringify!($name)).unwrap().clone()) { + let recipient_para_id = $crate::ParaId::from(recipient_para_id); + if let Err(idx) = e_index.binary_search(&recipient_para_id) { + e_index.insert(idx, recipient_para_id); + } + + sproof + .hrmp_channels + .entry(HrmpChannelId { + sender: sproof.para_id, + recipient: recipient_para_id, + }) + .or_insert_with(|| AbridgedHrmpChannel { + max_capacity: 1024, + max_total_size: 1024 * 1024, + max_message_size: 1024 * 1024, + msg_count: 0, + total_size: 0, + mqc_head: Option::None, + }); + } + + let (relay_storage_root, proof) = sproof.into_state_root_and_proof(); + + $crate::ParachainInherentData { + validation_data: $crate::PersistedValidationData { + parent_head: Default::default(), + relay_parent_number, + relay_parent_storage_root: relay_storage_root, + max_pov_size: Default::default(), + }, + relay_chain_state: proof, + downward_messages: Default::default(), + horizontal_messages: Default::default(), + } + } + } + + $crate::__impl_relay!($name, $relay_chain); + + $( + $crate::__impl_parachain!($name, $parachain); + )* + )+ + }; +} + +#[macro_export] +macro_rules! assert_expected_events { + ( $chain:ident, vec![$( $event_pat:pat => { $($attr:ident : $condition:expr, )* }, )*] ) => { + let mut message: Vec = Vec::new(); + $( + let mut meet_conditions = true; + let mut event_message: Vec = Vec::new(); + + let event_received = <$chain>::events().iter().any(|event| { + $crate::log::debug!(target: format!("events::{}", stringify!($chain)).to_lowercase().as_str(), "{:?}", event); + + match event { + $event_pat => { + $( + if !$condition { + event_message.push(format!(" - The attribute {:?} = {:?} did not met the condition {:?}\n", stringify!($attr), $attr, stringify!($condition))); + meet_conditions &= $condition + } + )* + true + }, + _ => false + } + }); + + if event_received && !meet_conditions { + message.push(format!("\n\nEvent \x1b[31m{}\x1b[0m was received but some of its attributes did not meet the conditions:\n{}", stringify!($event_pat), event_message.concat())); + } else if !event_received { + message.push(format!("\n\nEvent \x1b[31m{}\x1b[0m was never received", stringify!($event_pat))); + } + )* + if !message.is_empty() { + panic!("{}", message.concat()) + } + } + +} + +#[macro_export] +macro_rules! bx { + ($e:expr) => { + Box::new($e) + }; +} + +pub mod helpers { + use super::Weight; + + pub fn within_threshold(threshold: u64, expected_value: u64, current_value: u64) -> bool { + let margin = (current_value * threshold) / 100; + let lower_limit = expected_value - margin; + let upper_limit = expected_value + margin; + + current_value >= lower_limit && current_value <= upper_limit + } + + pub fn weight_within_threshold( + (threshold_time, threshold_size): (u64, u64), + expected_weight: Weight, + weight: Weight, + ) -> bool { + let ref_time_within = + within_threshold(threshold_time, expected_weight.ref_time(), weight.ref_time()); + let proof_size_within = + within_threshold(threshold_size, expected_weight.proof_size(), weight.proof_size()); + + ref_time_within && proof_size_within + } +}