From 3cae603adf02015e2386017cd21dacceca36e3c0 Mon Sep 17 00:00:00 2001 From: Roman Useinov Date: Wed, 12 Apr 2023 09:34:14 +0200 Subject: [PATCH 01/21] [Feature] XCM-Emulator --- Cargo.lock | 78 +++++ Cargo.toml | 3 + xcm/xcm-emulator/Cargo.toml | 30 ++ xcm/xcm-emulator/example/Cargo.toml | 32 ++ xcm/xcm-emulator/example/src/lib.rs | 432 ++++++++++++++++++++++++ xcm/xcm-emulator/src/lib.rs | 487 ++++++++++++++++++++++++++++ xcm/xcm-emulator/yayoi/Cargo.toml | 71 ++++ xcm/xcm-emulator/yayoi/src/lib.rs | 263 +++++++++++++++ 8 files changed, 1396 insertions(+) create mode 100644 xcm/xcm-emulator/Cargo.toml create mode 100644 xcm/xcm-emulator/example/Cargo.toml create mode 100644 xcm/xcm-emulator/example/src/lib.rs create mode 100644 xcm/xcm-emulator/src/lib.rs create mode 100644 xcm/xcm-emulator/yayoi/Cargo.toml create mode 100644 xcm/xcm-emulator/yayoi/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index e20de817a01..d35cf592395 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -15195,6 +15195,56 @@ dependencies = [ "xcm-executor", ] +[[package]] +name = "xcm-emulator" +version = "0.1.0" +dependencies = [ + "cumulus-pallet-dmp-queue", + "cumulus-pallet-parachain-system", + "cumulus-pallet-xcmp-queue", + "cumulus-primitives-core", + "cumulus-primitives-parachain-inherent", + "cumulus-test-relay-sproof-builder", + "frame-support", + "frame-system", + "parachain-info", + "parity-scale-codec", + "paste", + "polkadot-primitives", + "polkadot-runtime-parachains", + "quote", + "sp-arithmetic", + "sp-io", + "sp-std", + "xcm", + "xcm-executor", +] + +[[package]] +name = "xcm-emulator-example" +version = "0.1.0" +dependencies = [ + "cumulus-pallet-xcmp-queue", + "cumulus-primitives-core", + "frame-support", + "frame-system", + "kusama-runtime", + "pallet-balances", + "pallet-xcm", + "parachain-info", + "parity-scale-codec", + "polkadot-parachain", + "polkadot-primitives", + "polkadot-runtime-parachains", + "proc-macro2", + "serde", + "sp-io", + "sp-runtime", + "xcm", + "xcm-emulator", + "yayoi", +] + [[package]] name = "xcm-executor" version = "0.9.39" @@ -15249,6 +15299,34 @@ dependencies = [ "time 0.3.17", ] +[[package]] +name = "yayoi" +version = "0.1.0" +dependencies = [ + "cumulus-pallet-dmp-queue", + "cumulus-pallet-parachain-system", + "cumulus-pallet-xcm", + "cumulus-pallet-xcmp-queue", + "cumulus-primitives-utility", + "frame-support", + "frame-system", + "pallet-balances", + "pallet-xcm", + "parachain-info", + "parity-scale-codec", + "polkadot-parachain", + "polkadot-runtime-parachains", + "scale-info", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "xcm", + "xcm-builder", + "xcm-executor", +] + [[package]] name = "zeroize" version = "1.5.7" diff --git a/Cargo.toml b/Cargo.toml index cdcf4730f72..8b8d6233fac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,6 +50,9 @@ members = [ "test/relay-validation-worker-provider", "test/runtime", "test/service", + "xcm/xcm-emulator", + "xcm/xcm-emulator/example", + "xcm/xcm-emulator/yayoi", ] [profile.release] diff --git a/xcm/xcm-emulator/Cargo.toml b/xcm/xcm-emulator/Cargo.toml new file mode 100644 index 00000000000..ff8b1e11963 --- /dev/null +++ b/xcm/xcm-emulator/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "xcm-emulator" +description = "Test kit to emulate cross-chain message passing and XCM 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" + +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-std = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-arithmetic = { 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" } +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" } + +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/example/Cargo.toml b/xcm/xcm-emulator/example/Cargo.toml new file mode 100644 index 00000000000..1db8ed3891e --- /dev/null +++ b/xcm/xcm-emulator/example/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "xcm-emulator-example" +version = "0.1.0" +license = "Apache-2.0" +authors = ["Shaun Wang "] +edition = "2021" + +[dependencies] +serde = { version = "1.0.137", optional = true } +codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false } +proc-macro2 = "1.0.40" + +frame-system = { git = "https://github.com/paritytech/substrate", branch = "master" } +frame-support = { git = "https://github.com/paritytech/substrate", branch = "master" } +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } +sp-io = { git = "https://github.com/paritytech/substrate", branch = "master" } + +cumulus-primitives-core = { path = "../../../primitives/core" } +cumulus-pallet-xcmp-queue = { path = "../../../pallets/xcmp-queue" } +parachain-info = { path = "../../../parachains/pallets/parachain-info" } + +xcm = { git = "https://github.com/paritytech/polkadot", branch = "master" } +polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "master" } +polkadot-parachain = { git = "https://github.com/paritytech/polkadot", branch = "master" } +polkadot-runtime-parachains = { git = "https://github.com/paritytech/polkadot", branch = "master" } +kusama-runtime = { git = "https://github.com/paritytech/polkadot", branch = "master" } +pallet-xcm = { git = "https://github.com/paritytech/polkadot", branch = "master" } + + +xcm-emulator = { path = ".." } +yayoi = { path = "../yayoi" } diff --git a/xcm/xcm-emulator/example/src/lib.rs b/xcm/xcm-emulator/example/src/lib.rs new file mode 100644 index 00000000000..195f13405b8 --- /dev/null +++ b/xcm/xcm-emulator/example/src/lib.rs @@ -0,0 +1,432 @@ +// 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 . + +use frame_support::{pallet_prelude::Weight, traits::GenesisBuild}; +use sp_runtime::AccountId32; + +use xcm_emulator::{decl_test_network, decl_test_parachain, decl_test_relay_chain}; + +decl_test_relay_chain! { + pub struct KusamaNet { + Runtime = kusama_runtime::Runtime, + XcmConfig = kusama_runtime::xcm_config::XcmConfig, + new_ext = kusama_ext(), + } +} + +decl_test_parachain! { + pub struct YayoiPumpkin { + Runtime = yayoi::Runtime, + RuntimeOrigin = yayoi::RuntimeOrigin, + XcmpMessageHandler = yayoi::XcmpQueue, + DmpMessageHandler = yayoi::DmpQueue, + new_ext = yayoi_ext(1), + } +} + +decl_test_parachain! { + pub struct YayoiMushroom { + Runtime = yayoi::Runtime, + RuntimeOrigin = yayoi::RuntimeOrigin, + XcmpMessageHandler = yayoi::XcmpQueue, + DmpMessageHandler = yayoi::DmpQueue, + new_ext = yayoi_ext(2), + } +} + +decl_test_parachain! { + pub struct YayoiOctopus { + Runtime = yayoi::Runtime, + RuntimeOrigin = yayoi::RuntimeOrigin, + XcmpMessageHandler = yayoi::XcmpQueue, + DmpMessageHandler = yayoi::DmpQueue, + new_ext = yayoi_ext(3), + } +} + +decl_test_network! { + pub struct Network { + relay_chain = KusamaNet, + parachains = vec![ + (1, YayoiPumpkin), + (2, YayoiMushroom), + (3, YayoiOctopus), + ], + } +} + +pub const ALICE: AccountId32 = AccountId32::new([0u8; 32]); +pub const INITIAL_BALANCE: u128 = 1_000_000_000_000; + +pub fn yayoi_ext(para_id: u32) -> sp_io::TestExternalities { + use yayoi::{Runtime, System}; + + let mut t = frame_system::GenesisConfig::default() + .build_storage::() + .unwrap(); + + let parachain_info_config = parachain_info::GenesisConfig { + parachain_id: para_id.into(), + }; + + >::assimilate_storage(¶chain_info_config, &mut t) + .unwrap(); + + pallet_balances::GenesisConfig:: { + balances: vec![(ALICE, INITIAL_BALANCE)], + } + .assimilate_storage(&mut t) + .unwrap(); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext +} + +fn default_parachains_host_configuration( +) -> polkadot_runtime_parachains::configuration::HostConfiguration { + use polkadot_primitives::v4::{MAX_CODE_SIZE, MAX_POV_SIZE}; + + polkadot_runtime_parachains::configuration::HostConfiguration { + minimum_validation_upgrade_delay: 5, + validation_upgrade_cooldown: 10u32, + validation_upgrade_delay: 10, + code_retention_period: 1200, + max_code_size: MAX_CODE_SIZE, + max_pov_size: MAX_POV_SIZE, + max_head_data_size: 32 * 1024, + group_rotation_frequency: 20, + chain_availability_period: 4, + thread_availability_period: 4, + max_upward_queue_count: 8, + max_upward_queue_size: 1024 * 1024, + max_downward_message_size: 1024, + ump_service_total_weight: Weight::from_parts(4 * 1_000_000_000, 0), + max_upward_message_size: 50 * 1024, + max_upward_message_num_per_candidate: 5, + hrmp_sender_deposit: 0, + hrmp_recipient_deposit: 0, + hrmp_channel_max_capacity: 8, + hrmp_channel_max_total_size: 8 * 1024, + hrmp_max_parachain_inbound_channels: 4, + hrmp_max_parathread_inbound_channels: 4, + hrmp_channel_max_message_size: 1024 * 1024, + hrmp_max_parachain_outbound_channels: 4, + hrmp_max_parathread_outbound_channels: 4, + hrmp_max_message_num_per_candidate: 5, + dispute_period: 6, + no_show_slots: 2, + n_delay_tranches: 25, + needed_approvals: 2, + relay_vrf_modulo_samples: 2, + zeroth_delay_tranche_width: 0, + ..Default::default() + } +} + +pub fn kusama_ext() -> sp_io::TestExternalities { + use kusama_runtime::{Runtime, System}; + + let mut t = frame_system::GenesisConfig::default() + .build_storage::() + .unwrap(); + + pallet_balances::GenesisConfig:: { + balances: vec![(ALICE, INITIAL_BALANCE)], + } + .assimilate_storage(&mut t) + .unwrap(); + + polkadot_runtime_parachains::configuration::GenesisConfig:: { + config: default_parachains_host_configuration(), + } + .assimilate_storage(&mut t) + .unwrap(); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext +} + +#[cfg(test)] +mod tests { + use super::*; + use codec::Encode; + + use cumulus_primitives_core::ParaId; + use frame_support::{assert_ok, dispatch::GetDispatchInfo, traits::Currency}; + use sp_runtime::traits::AccountIdConversion; + use xcm::{v3::prelude::*, VersionedMultiLocation, VersionedXcm}; + use xcm_emulator::TestExt; + + #[test] + fn dmp() { + Network::reset(); + + let remark = yayoi::RuntimeCall::System(frame_system::Call::::remark_with_event { + remark: "Hello from Kusama!".as_bytes().to_vec(), + }); + KusamaNet::execute_with(|| { + assert_ok!(kusama_runtime::XcmPallet::force_default_xcm_version( + kusama_runtime::RuntimeOrigin::root(), + Some(3) + )); + assert_ok!(kusama_runtime::XcmPallet::send_xcm( + Here, + Parachain(1), + Xcm(vec![Transact { + origin_kind: OriginKind::SovereignAccount, + require_weight_at_most: Weight::from_parts(INITIAL_BALANCE as u64, 1024 * 1024), + call: remark.encode().into(), + }]), + )); + }); + + YayoiPumpkin::execute_with(|| { + use yayoi::{RuntimeEvent, System}; + System::events().iter().for_each(|r| println!(">>> {:?}", r.event)); + + assert!(System::events().iter().any(|r| matches!( + r.event, + RuntimeEvent::System(frame_system::Event::Remarked { sender: _, hash: _ }) + ))); + }); + } + + #[test] + fn ump() { + Network::reset(); + + KusamaNet::execute_with(|| { + assert_ok!(kusama_runtime::XcmPallet::force_default_xcm_version( + kusama_runtime::RuntimeOrigin::root(), + Some(3) + )); + let _ = kusama_runtime::Balances::deposit_creating( + &ParaId::from(1).into_account_truncating(), + 1_000_000_000_000, + ); + }); + + let remark = + kusama_runtime::RuntimeCall::System(frame_system::Call::::remark_with_event { + remark: "Hello from Pumpkin!".as_bytes().to_vec(), + }); + YayoiPumpkin::execute_with(|| { + assert_ok!(yayoi::PolkadotXcm::force_default_xcm_version( + yayoi::RuntimeOrigin::root(), + Some(3) + )); + assert_ok!(yayoi::PolkadotXcm::send_xcm( + Here, + Parent, + Xcm(vec![ + UnpaidExecution { + weight_limit: Unlimited, + check_origin: None, + }, + Transact { + origin_kind: OriginKind::SovereignAccount, + require_weight_at_most: Weight::from_parts(INITIAL_BALANCE as u64, 1024 * 1024), + call: remark.encode().into(), + } + ]), + )); + }); + + KusamaNet::execute_with(|| { + use kusama_runtime::{RuntimeEvent, System}; + // TODO: https://github.com/paritytech/polkadot/pull/6824 or change this call to + // force_create_assets like we do in cumulus integration tests. + // assert!(System::events().iter().any(|r| matches!( + // r.event, + // RuntimeEvent::System(frame_system::Event::Remarked { sender: _, hash: _ }) + // ))); + assert!(System::events().iter().any(|r| matches!( + r.event, + RuntimeEvent::Ump(polkadot_runtime_parachains::ump::Event::ExecutedUpward( + _, + Outcome::Incomplete(_, XcmError::NoPermission) + )) + ))); + }); + } + + #[test] + fn xcmp() { + Network::reset(); + + let remark = yayoi::RuntimeCall::System(frame_system::Call::::remark_with_event { + remark: "Hello from Pumpkin!".as_bytes().to_vec(), + }); + YayoiPumpkin::execute_with(|| { + assert_ok!(yayoi::PolkadotXcm::send_xcm( + Here, + MultiLocation::new(1, X1(Parachain(2))), + Xcm(vec![Transact { + origin_kind: OriginKind::SovereignAccount, + require_weight_at_most: 20_000_000.into(), + call: remark.encode().into(), + }]), + )); + }); + + YayoiMushroom::execute_with(|| { + use yayoi::{RuntimeEvent, System}; + System::events().iter().for_each(|r| println!(">>> {:?}", r.event)); + + assert!(System::events().iter().any(|r| matches!( + r.event, + RuntimeEvent::System(frame_system::Event::Remarked { sender: _, hash: _ }) + ))); + }); + } + + #[test] + fn xcmp_through_a_parachain() { + use yayoi::{PolkadotXcm, Runtime, RuntimeCall}; + + Network::reset(); + + // The message goes through: Pumpkin --> Mushroom --> Octopus + let remark = RuntimeCall::System(frame_system::Call::::remark_with_event { + remark: "Hello from Pumpkin!".as_bytes().to_vec(), + }); + let send_xcm_to_octopus = RuntimeCall::PolkadotXcm(pallet_xcm::Call::::send { + dest: Box::new(VersionedMultiLocation::V3(MultiLocation::new(1, X1(Parachain(3))))), + message: Box::new(VersionedXcm::V3(Xcm(vec![Transact { + origin_kind: OriginKind::SovereignAccount, + require_weight_at_most: 10_000_000.into(), + call: remark.encode().into(), + }]))), + }); + assert_eq!( + send_xcm_to_octopus.get_dispatch_info().weight, + Weight::from_parts(110000010, 10000010) + ); + YayoiPumpkin::execute_with(|| { + assert_ok!(PolkadotXcm::send_xcm( + Here, + MultiLocation::new(1, X1(Parachain(2))), + Xcm(vec![Transact { + origin_kind: OriginKind::SovereignAccount, + require_weight_at_most: 110_000_010.into(), + call: send_xcm_to_octopus.encode().into(), + }]), + )); + }); + + YayoiMushroom::execute_with(|| { + use yayoi::{RuntimeEvent, System}; + System::events().iter().for_each(|r| println!(">>> {:?}", r.event)); + + assert!(System::events() + .iter() + .any(|r| matches!(r.event, RuntimeEvent::PolkadotXcm(pallet_xcm::Event::Sent(_, _, _))))); + }); + + YayoiOctopus::execute_with(|| { + use yayoi::{RuntimeEvent, System}; + // execution would fail, but good enough to check if the message is received + System::events().iter().for_each(|r| println!(">>> {:?}", r.event)); + + assert!(System::events().iter().any(|r| matches!( + r.event, + RuntimeEvent::XcmpQueue(cumulus_pallet_xcmp_queue::Event::Fail { .. }) + ))); + }); + } + + #[test] + fn deduplicate_dmp() { + Network::reset(); + KusamaNet::execute_with(|| { + assert_ok!(kusama_runtime::XcmPallet::force_default_xcm_version( + kusama_runtime::RuntimeOrigin::root(), + Some(3) + )); + }); + + kusama_send_rmrk("Kusama", 2); + parachain_receive_and_reset_events(true); + + // a different dmp message in same relay-parent-block allow execution. + kusama_send_rmrk("Polkadot", 1); + parachain_receive_and_reset_events(true); + + // same dmp message with same relay-parent-block wouldn't execution + kusama_send_rmrk("Kusama", 1); + parachain_receive_and_reset_events(false); + + // different relay-parent-block allow dmp message execution + KusamaNet::execute_with(|| kusama_runtime::System::set_block_number(2)); + + kusama_send_rmrk("Kusama", 1); + parachain_receive_and_reset_events(true); + + // reset can send same dmp message again + Network::reset(); + KusamaNet::execute_with(|| { + assert_ok!(kusama_runtime::XcmPallet::force_default_xcm_version( + kusama_runtime::RuntimeOrigin::root(), + Some(3) + )); + }); + + kusama_send_rmrk("Kusama", 1); + parachain_receive_and_reset_events(true); + } + + fn kusama_send_rmrk(msg: &str, count: u32) { + let remark = yayoi::RuntimeCall::System(frame_system::Call::::remark_with_event { + remark: msg.as_bytes().to_vec(), + }); + KusamaNet::execute_with(|| { + for _ in 0..count { + assert_ok!(kusama_runtime::XcmPallet::send_xcm( + Here, + Parachain(1), + Xcm(vec![Transact { + origin_kind: OriginKind::SovereignAccount, + require_weight_at_most: Weight::from_parts(INITIAL_BALANCE as u64, 1024 * 1024), + call: remark.encode().into(), + }]), + )); + } + }); + } + + fn parachain_receive_and_reset_events(received: bool) { + YayoiPumpkin::execute_with(|| { + use yayoi::{RuntimeEvent, System}; + System::events().iter().for_each(|r| println!(">>> {:?}", r.event)); + + if received { + assert!(System::events().iter().any(|r| matches!( + r.event, + RuntimeEvent::System(frame_system::Event::Remarked { sender: _, hash: _ }) + ))); + + System::reset_events(); + } else { + assert!(System::events().iter().all(|r| !matches!( + r.event, + RuntimeEvent::System(frame_system::Event::Remarked { sender: _, hash: _ }) + ))); + } + }); + } +} diff --git a/xcm/xcm-emulator/src/lib.rs b/xcm/xcm-emulator/src/lib.rs new file mode 100644 index 00000000000..a8bebd6fb02 --- /dev/null +++ b/xcm/xcm-emulator/src/lib.rs @@ -0,0 +1,487 @@ +// 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 codec::Encode; +pub use paste; + +pub use frame_support::{ + traits::{Get, Hooks}, + weights::Weight, +}; +pub use frame_system; +pub use sp_arithmetic::traits::Bounded; +pub use sp_io::TestExternalities; +pub use sp_std::{cell::RefCell, collections::vec_deque::VecDeque, marker::PhantomData}; + +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 parachain_info; + +pub use polkadot_primitives; +pub use polkadot_runtime_parachains::{ + dmp, + ump::{MessageId, UmpSink, XcmSink}, +}; +pub use xcm::{v3::prelude::*, VersionedXcm}; +pub use xcm_executor::XcmExecutor; + +pub trait TestExt { + fn new_ext() -> sp_io::TestExternalities; + fn reset_ext(); + fn execute_with(execute: impl FnOnce() -> R) -> R; +} + +#[macro_export] +macro_rules! decl_test_relay_chain { + ( + pub struct $name:ident { + Runtime = $runtime:path, + XcmConfig = $xcm_config:path, + new_ext = $new_ext:expr, + } + ) => { + pub struct $name; + + $crate::__impl_ext_for_relay_chain!($name, $runtime, $new_ext); + + 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<$xcm_config>, $runtime>::process_upward_message(origin, msg, max_weight) + }) + } + } + }; +} + +#[macro_export] +macro_rules! decl_test_parachain { + ( + pub struct $name:ident { + Runtime = $runtime:path, + RuntimeOrigin = $origin:path, + XcmpMessageHandler = $xcmp_message_handler:path, + DmpMessageHandler = $dmp_message_handler:path, + new_ext = $new_ext:expr, + } + ) => { + pub struct $name; + + $crate::__impl_ext_for_parachain!($name, $runtime, $origin, $new_ext); + + 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(|| { + <$xcmp_message_handler>::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(|| { + <$dmp_message_handler>::handle_dmp_messages(iter, max_weight) + }) + } + } + }; +} + +#[macro_export] +macro_rules! __impl_ext_for_relay_chain { + // entry point: generate ext name + ($name:ident, $runtime:path, $new_ext:expr) => { + $crate::paste::paste! { + $crate::__impl_ext_for_relay_chain!(@impl $name, $runtime, $new_ext, []); + } + }; + // impl + (@impl $name:ident, $runtime:path, $new_ext:expr, $ext_name:ident) => { + thread_local! { + pub static $ext_name: $crate::RefCell<$crate::TestExternalities> + = $crate::RefCell::new($new_ext); + } + + impl $crate::TestExt for $name { + fn new_ext() -> $crate::TestExternalities { + $new_ext + } + + fn reset_ext() { + $ext_name.with(|v| *v.borrow_mut() = $new_ext); + } + + fn execute_with(execute: impl FnOnce() -> R) -> R { + 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 _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; + } + _Messenger::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). + } + }) + }); + + _process_messages(); + + r + } + } + }; +} + +#[macro_export] +macro_rules! __impl_ext_for_parachain { + // entry point: generate ext name + ($name:ident, $runtime:path, $origin:path, $new_ext:expr) => { + $crate::paste::paste! { + $crate::__impl_ext_for_parachain!(@impl $name, $runtime, $origin, $new_ext, []); + } + }; + // impl + (@impl $name:ident, $runtime:path, $origin:path, $new_ext:expr, $ext_name:ident) => { + thread_local! { + pub static $ext_name: $crate::RefCell<$crate::TestExternalities> + = $crate::RefCell::new($new_ext); + } + + impl $name { + fn prepare_for_xcmp() { + $ext_name.with(|v| { + v.borrow_mut().execute_with(|| { + use $crate::{Get, Hooks}; + type ParachainSystem = $crate::cumulus_pallet_parachain_system::Pallet<$runtime>; + + let block_number = $crate::frame_system::Pallet::<$runtime>::block_number(); + let para_id = $crate::parachain_info::Pallet::<$runtime>::get(); + + let _ = ParachainSystem::set_validation_data( + <$origin>::none(), + _hrmp_channel_parachain_inherent_data(para_id.into(), 1), + ); + // set `AnnouncedHrmpMessagesPerCandidate` + ParachainSystem::on_initialize(block_number); + }) + }); + } + } + + impl $crate::TestExt for $name { + fn new_ext() -> $crate::TestExternalities { + $new_ext + } + + fn reset_ext() { + $ext_name.with(|v| *v.borrow_mut() = $new_ext); + } + + fn execute_with(execute: impl FnOnce() -> R) -> R { + use $crate::{Get, Hooks}; + type ParachainSystem = $crate::cumulus_pallet_parachain_system::Pallet<$runtime>; + + $crate::GLOBAL_RELAY.with(|v| { + *v.borrow_mut() += 1; + }); + + $ext_name.with(|v| { + v.borrow_mut().execute_with(|| { + let para_id = $crate::parachain_info::Pallet::<$runtime>::get(); + $crate::GLOBAL_RELAY.with(|v| { + let relay_block = *v.borrow(); + let _ = ParachainSystem::set_validation_data( + <$origin>::none(), + _hrmp_channel_parachain_inherent_data(para_id.into(), relay_block), + ); + }); + }) + }); + + 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 = $crate::frame_system::Pallet::<$runtime>::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 para_id = $crate::parachain_info::Pallet::<$runtime>::get(); + for msg in collation_info.upward_messages.clone() { + _Messenger::send_upward_message(para_id.into(), msg); + } + + // send horizontal messages + for msg in collation_info.horizontal_messages { + $crate::GLOBAL_RELAY.with(|v| { + let relay_block = *v.borrow(); + _Messenger::send_horizontal_messages( + msg.recipient.into(), + vec![(para_id.into(), relay_block, msg.data)].into_iter(), + ); + }); + } + + // clean messages + ParachainSystem::on_initialize(block_number); + }) + }); + + _process_messages(); + + r + } + } + }; +} + +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(VecDeque::new()); + #[allow(clippy::type_complexity)] + /// Downward messages that already processed by parachains, each message is: `(to_para_id, relay_block_number, Vec)` + pub static DMP_DONE: RefCell)>> + = RefCell::new(VecDeque::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(VecDeque::new()); + /// Upward messages, each message is: `(from_para_id, msg) + pub static UPWARD_MESSAGES: RefCell)>> = RefCell::new(VecDeque::new()); + /// Global incremental relay chain block number + pub static GLOBAL_RELAY: RefCell = RefCell::new(1); +} + +#[macro_export] +macro_rules! decl_test_network { + ( + pub struct $name:ident { + relay_chain = $relay_chain:ty, + parachains = vec![ $( ($para_id:expr, $parachain:ty), )* ], + } + ) => { + pub struct $name; + + impl $name { + pub fn reset() { + use $crate::{TestExt, VecDeque}; + + <$relay_chain>::reset_ext(); + $( <$parachain>::reset_ext(); )* + + $( <$parachain>::prepare_for_xcmp(); )* + + $crate::DOWNWARD_MESSAGES.with(|b| b.replace(VecDeque::new())); + $crate::DMP_DONE.with(|b| b.replace(VecDeque::new())); + } + } + + fn _para_ids() -> Vec { + vec![$( $para_id, )*] + } + + fn _process_messages() { + while _has_unprocessed_messages() { + _process_upward_messages(); + _process_horizontal_messages(); + _process_downward_messages(); + } + } + + fn _has_unprocessed_messages() -> bool { + $crate::DOWNWARD_MESSAGES.with(|b| !b.borrow_mut().is_empty()) + || $crate::HORIZONTAL_MESSAGES.with(|b| !b.borrow_mut().is_empty()) + || $crate::UPWARD_MESSAGES.with(|b| !b.borrow_mut().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().pop_front()) { + match to_para_id { + $( + $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().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().push_back((to_para_id, m.0, m.1))); + } + } + }, + )* + _ => unreachable!(), + } + } + } + + fn _process_horizontal_messages() { + use $crate::{XcmpMessageHandler, Bounded}; + + while let Some((to_para_id, messages)) + = $crate::HORIZONTAL_MESSAGES.with(|b| b.borrow_mut().pop_front()) { + let iter = messages.iter().map(|(p, b, m)| (*p, *b, &m[..])).collect::>().into_iter(); + match to_para_id { + $( + $para_id => { + <$parachain>::handle_xcmp_messages(iter, $crate::Weight::max_value()); + }, + )* + _ => unreachable!(), + } + } + } + + fn _process_upward_messages() { + use $crate::{UmpSink, Bounded}; + while let Some((from_para_id, msg)) = $crate::UPWARD_MESSAGES.with(|b| b.borrow_mut().pop_front()) { + let _ = <$relay_chain>::process_upward_message( + from_para_id.into(), + &msg[..], + $crate::Weight::max_value(), + ); + } + } + + pub struct _Messenger; + impl _Messenger { + fn send_downward_messages(to_para_id: u32, iter: impl Iterator)>) { + $crate::DOWNWARD_MESSAGES.with(|b| b.borrow_mut().push_back((to_para_id, iter.collect()))); + } + + fn send_horizontal_messages< + I: Iterator)>, + >(to_para_id: u32, iter: I) { + $crate::HORIZONTAL_MESSAGES.with(|b| b.borrow_mut().push_back((to_para_id, iter.collect()))); + } + + fn send_upward_message(from_para_id: u32, msg: Vec) { + $crate::UPWARD_MESSAGES.with(|b| b.borrow_mut().push_back((from_para_id, msg))); + } + } + + 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 &[ $( $para_id, )* ] { + 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(), + } + } + }; +} diff --git a/xcm/xcm-emulator/yayoi/Cargo.toml b/xcm/xcm-emulator/yayoi/Cargo.toml new file mode 100644 index 00000000000..39d370e19f1 --- /dev/null +++ b/xcm/xcm-emulator/yayoi/Cargo.toml @@ -0,0 +1,71 @@ +[package] +name = "yayoi" +description = "A simple runtime for cross-chain messages tests." +license = "Apache-2.0" +version = "0.1.0" +authors = ["Shaun Wang "] +edition = "2021" + +[dependencies] +serde = { version = "1.0.137", optional = true } +codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false } +scale-info = { version = "2.1", default-features = false, features = ["derive"] } + +sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } +sp-io = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } +sp-std = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } +sp-core = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } +pallet-balances = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } +frame-support = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } +frame-system = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } + +cumulus-pallet-dmp-queue = { path = "../../../pallets/dmp-queue", default-features = false } +cumulus-pallet-xcmp-queue = { path = "../../../pallets/xcmp-queue", default-features = false } +parachain-info = { path = "../../../parachains/pallets/parachain-info", default-features = false } +cumulus-pallet-xcm = { path = "../../../pallets/xcm", default-features = false } +cumulus-pallet-parachain-system = { path = "../../../pallets/parachain-system", default-features = false } +cumulus-primitives-utility = { path = "../../../primitives/utility", default-features = false } + +xcm = { git = "https://github.com/paritytech/polkadot", branch = "master" } +xcm-executor = { git = "https://github.com/paritytech/polkadot", branch = "master" } +polkadot-parachain = { git = "https://github.com/paritytech/polkadot", branch = "master" } +xcm-builder = { git = "https://github.com/paritytech/polkadot", branch = "master" } +pallet-xcm = { git = "https://github.com/paritytech/polkadot", branch = "master" } +polkadot-runtime-parachains = { git = "https://github.com/paritytech/polkadot", branch = "master" } + + +[features] +default = ["std"] +no_std = [] +std = [ + "serde/std", + "codec/std", + "scale-info/std", + + "sp-runtime/std", + "sp-io/std", + "sp-std/std", + "sp-core/std", + "pallet-balances/std", + "frame-support/std", + "frame-system/std", + + "cumulus-pallet-dmp-queue/std", + "cumulus-pallet-xcmp-queue/std", + "cumulus-pallet-xcm/std", + "cumulus-pallet-parachain-system/std", + "parachain-info/std", + "cumulus-primitives-utility/std", + + "xcm/std", + "xcm-executor/std", + "polkadot-parachain/std", + "xcm-builder/std", + "pallet-xcm/std", + "polkadot-runtime-parachains/std", +] + +runtime-benchmarks = [ + "pallet-xcm/runtime-benchmarks", + "xcm-builder/runtime-benchmarks", +] diff --git a/xcm/xcm-emulator/yayoi/src/lib.rs b/xcm/xcm-emulator/yayoi/src/lib.rs new file mode 100644 index 00000000000..78c1708d9ec --- /dev/null +++ b/xcm/xcm-emulator/yayoi/src/lib.rs @@ -0,0 +1,263 @@ +// 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 . + +use frame_support::{ + construct_runtime, parameter_types, + traits::{ConstU32, Everything, Nothing}, + weights::{constants::WEIGHT_REF_TIME_PER_SECOND, Weight}, +}; +use frame_system::EnsureRoot; +use pallet_xcm::XcmPassthrough; +use polkadot_parachain::primitives::Sibling; +use sp_core::H256; +use sp_runtime::{ + testing::Header, + traits::{Convert, IdentityLookup}, + AccountId32, +}; +use xcm::v3::prelude::*; +use xcm_builder::{ + AccountId32Aliases, AllowUnpaidExecutionFrom, EnsureXcmOrigin, FixedWeightBounds, + ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, + SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, +}; +use xcm_executor::{Config, XcmExecutor}; + +pub type AccountId = AccountId32; +pub type Balance = u128; +pub type Amount = i128; + +parameter_types! { + pub const BlockHashCount: u64 = 250; +} + +impl frame_system::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Hashing = ::sp_runtime::traits::BlakeTwo256; + type AccountId = AccountId; + type Lookup = IdentityLookup; + type Header = Header; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type BlockWeights = (); + type BlockLength = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type DbWeight = (); + type BaseCallFilter = Everything; + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; + type MaxConsumers = ConstU32<16>; +} + +parameter_types! { + pub ExistentialDeposit: Balance = 1; + pub const MaxLocks: u32 = 50; + pub const MaxReserves: u32 = 50; +} + +impl pallet_balances::Config for Runtime { + type MaxLocks = MaxLocks; + type Balance = Balance; + type RuntimeEvent = RuntimeEvent; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type WeightInfo = (); + type MaxReserves = MaxReserves; + type ReserveIdentifier = [u8; 8]; + type HoldIdentifier = (); + type FreezeIdentifier = (); + type MaxHolds = (); + type MaxFreezes = (); +} + +impl parachain_info::Config for Runtime {} + +parameter_types! { + pub const RelayLocation: MultiLocation = MultiLocation::parent(); + pub const RelayNetwork: NetworkId = NetworkId::Kusama; + pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); + pub UniversalLocation: InteriorMultiLocation = X2(GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into())); +} + +pub type LocationToAccountId = ( + ParentIsPreset, + SiblingParachainConvertsVia, + AccountId32Aliases, +); + +pub type XcmOriginToCallOrigin = ( + SovereignSignedViaLocation, + RelayChainAsNative, + SiblingParachainAsNative, + SignedAccountId32AsNative, + XcmPassthrough, +); + +parameter_types! { + pub const UnitWeightCost: u64 = 10; + pub const MaxInstructions: u32 = 100; + pub const MaxAssetsIntoHolding: u32 = 64; +} + +pub type LocalAssetTransactor = (); + +/// The means for routing XCM messages which are not for local execution into +/// the right message queues. +pub type XcmRouter = ( + // Two routers - use UMP to communicate with the relay chain: + cumulus_primitives_utility::ParentAsUmp, + // ..and XCMP to communicate with the sibling chains. + XcmpQueue, +); + +pub type Barrier = AllowUnpaidExecutionFrom; + +pub struct XcmConfig; +impl Config for XcmConfig { + type RuntimeCall = RuntimeCall; + type XcmSender = XcmRouter; + type AssetTransactor = LocalAssetTransactor; + type OriginConverter = XcmOriginToCallOrigin; + type IsReserve = (); + type IsTeleporter = (); + type UniversalLocation = UniversalLocation; + type Barrier = Barrier; + type Weigher = FixedWeightBounds; + type Trader = (); + type ResponseHandler = (); + type AssetTrap = (); + type AssetClaims = (); + type SubscriptionService = (); + type AssetLocker = PolkadotXcm; + type AssetExchanger = (); + type PalletInstancesInfo = (); + type MaxAssetsIntoHolding = MaxAssetsIntoHolding; + type FeeManager = (); + type MessageExporter = (); + type UniversalAliases = Nothing; + type CallDispatcher = RuntimeCall; + type SafeCallFilter = Everything; +} + +parameter_types! { + pub const ReservedXcmpWeight: Weight = Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_div(4), 0); + pub const ReservedDmpWeight: Weight = Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_div(4), 0); +} + +impl cumulus_pallet_parachain_system::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type OnSystemEvent = (); + type SelfParaId = ParachainInfo; + type DmpMessageHandler = DmpQueue; + type ReservedDmpWeight = ReservedDmpWeight; + type OutboundXcmpMessageSource = XcmpQueue; + type XcmpMessageHandler = XcmpQueue; + type ReservedXcmpWeight = ReservedXcmpWeight; + type CheckAssociatedRelayNumber = cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; +} + +impl cumulus_pallet_xcmp_queue::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type XcmExecutor = XcmExecutor; + type ChannelInfo = ParachainSystem; + type VersionWrapper = (); + type ExecuteOverweightOrigin = EnsureRoot; + type ControllerOrigin = EnsureRoot; + type ControllerOriginConverter = XcmOriginToCallOrigin; + type WeightInfo = (); + type PriceForSiblingDelivery = (); +} + +impl cumulus_pallet_dmp_queue::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type XcmExecutor = XcmExecutor; + type ExecuteOverweightOrigin = EnsureRoot; +} + +impl cumulus_pallet_xcm::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type XcmExecutor = XcmExecutor; +} + +#[cfg(feature = "runtime-benchmarks")] +parameter_types! { + pub ReachableDest: Option = Some(Parent.into()); +} + +pub type LocalOriginToLocation = SignedToAccountId32; + +impl pallet_xcm::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type SendXcmOrigin = EnsureXcmOrigin; + type XcmRouter = XcmRouter; + type ExecuteXcmOrigin = EnsureXcmOrigin; + type XcmExecuteFilter = Everything; + type XcmExecutor = XcmExecutor; + type XcmTeleportFilter = Nothing; + type XcmReserveTransferFilter = Everything; + type Weigher = FixedWeightBounds; + type UniversalLocation = UniversalLocation; + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; + type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; + type Currency = Balances; + type CurrencyMatcher = (); + type TrustedLockers = (); + type SovereignAccountOf = (); + type MaxLockers = ConstU32<8>; + type WeightInfo = pallet_xcm::TestWeightInfo; + type AdminOrigin = EnsureRoot; + #[cfg(feature = "runtime-benchmarks")] + type ReachableDest = ReachableDest; +} + +pub struct AccountIdToMultiLocation; +impl Convert for AccountIdToMultiLocation { + fn convert(account: AccountId) -> MultiLocation { + X1(Junction::AccountId32 { network: None, id: account.into() }).into() + } +} + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; + +construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system::{Pallet, Call, Storage, Config, Event}, + Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Storage, Inherent, Config, Event}, + ParachainInfo: parachain_info::{Pallet, Storage, Config}, + XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event}, + DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event}, + CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin}, + PolkadotXcm: pallet_xcm::{Pallet, Call, Event, Origin}, + } +); From 763948df394f7781a58c82009bd8b6e068aa341b Mon Sep 17 00:00:00 2001 From: command-bot <> Date: Wed, 12 Apr 2023 07:42:02 +0000 Subject: [PATCH 02/21] ".git/.scripts/commands/fmt/fmt.sh" --- xcm/xcm-emulator/example/src/lib.rs | 91 +++++++++++++++-------------- 1 file changed, 47 insertions(+), 44 deletions(-) diff --git a/xcm/xcm-emulator/example/src/lib.rs b/xcm/xcm-emulator/example/src/lib.rs index 195f13405b8..7886dc5e6fd 100644 --- a/xcm/xcm-emulator/example/src/lib.rs +++ b/xcm/xcm-emulator/example/src/lib.rs @@ -74,30 +74,29 @@ pub const INITIAL_BALANCE: u128 = 1_000_000_000_000; pub fn yayoi_ext(para_id: u32) -> sp_io::TestExternalities { use yayoi::{Runtime, System}; - let mut t = frame_system::GenesisConfig::default() - .build_storage::() - .unwrap(); - - let parachain_info_config = parachain_info::GenesisConfig { - parachain_id: para_id.into(), - }; + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); - >::assimilate_storage(¶chain_info_config, &mut t) - .unwrap(); + let parachain_info_config = parachain_info::GenesisConfig { parachain_id: para_id.into() }; - pallet_balances::GenesisConfig:: { - balances: vec![(ALICE, INITIAL_BALANCE)], - } - .assimilate_storage(&mut t) + >::assimilate_storage( + ¶chain_info_config, + &mut t, + ) .unwrap(); + pallet_balances::GenesisConfig:: { balances: vec![(ALICE, INITIAL_BALANCE)] } + .assimilate_storage(&mut t) + .unwrap(); + let mut ext = sp_io::TestExternalities::new(t); ext.execute_with(|| System::set_block_number(1)); ext } fn default_parachains_host_configuration( -) -> polkadot_runtime_parachains::configuration::HostConfiguration { +) -> polkadot_runtime_parachains::configuration::HostConfiguration< + polkadot_primitives::v4::BlockNumber, +> { use polkadot_primitives::v4::{MAX_CODE_SIZE, MAX_POV_SIZE}; polkadot_runtime_parachains::configuration::HostConfiguration { @@ -140,15 +139,11 @@ fn default_parachains_host_configuration( pub fn kusama_ext() -> sp_io::TestExternalities { use kusama_runtime::{Runtime, System}; - let mut t = frame_system::GenesisConfig::default() - .build_storage::() - .unwrap(); + let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); - pallet_balances::GenesisConfig:: { - balances: vec![(ALICE, INITIAL_BALANCE)], - } - .assimilate_storage(&mut t) - .unwrap(); + pallet_balances::GenesisConfig:: { balances: vec![(ALICE, INITIAL_BALANCE)] } + .assimilate_storage(&mut t) + .unwrap(); polkadot_runtime_parachains::configuration::GenesisConfig:: { config: default_parachains_host_configuration(), @@ -176,9 +171,10 @@ mod tests { fn dmp() { Network::reset(); - let remark = yayoi::RuntimeCall::System(frame_system::Call::::remark_with_event { - remark: "Hello from Kusama!".as_bytes().to_vec(), - }); + let remark = + yayoi::RuntimeCall::System(frame_system::Call::::remark_with_event { + remark: "Hello from Kusama!".as_bytes().to_vec(), + }); KusamaNet::execute_with(|| { assert_ok!(kusama_runtime::XcmPallet::force_default_xcm_version( kusama_runtime::RuntimeOrigin::root(), @@ -221,10 +217,11 @@ mod tests { ); }); - let remark = - kusama_runtime::RuntimeCall::System(frame_system::Call::::remark_with_event { - remark: "Hello from Pumpkin!".as_bytes().to_vec(), - }); + let remark = kusama_runtime::RuntimeCall::System(frame_system::Call::< + kusama_runtime::Runtime, + >::remark_with_event { + remark: "Hello from Pumpkin!".as_bytes().to_vec(), + }); YayoiPumpkin::execute_with(|| { assert_ok!(yayoi::PolkadotXcm::force_default_xcm_version( yayoi::RuntimeOrigin::root(), @@ -234,13 +231,13 @@ mod tests { Here, Parent, Xcm(vec![ - UnpaidExecution { - weight_limit: Unlimited, - check_origin: None, - }, + UnpaidExecution { weight_limit: Unlimited, check_origin: None }, Transact { origin_kind: OriginKind::SovereignAccount, - require_weight_at_most: Weight::from_parts(INITIAL_BALANCE as u64, 1024 * 1024), + require_weight_at_most: Weight::from_parts( + INITIAL_BALANCE as u64, + 1024 * 1024 + ), call: remark.encode().into(), } ]), @@ -269,9 +266,10 @@ mod tests { fn xcmp() { Network::reset(); - let remark = yayoi::RuntimeCall::System(frame_system::Call::::remark_with_event { - remark: "Hello from Pumpkin!".as_bytes().to_vec(), - }); + let remark = + yayoi::RuntimeCall::System(frame_system::Call::::remark_with_event { + remark: "Hello from Pumpkin!".as_bytes().to_vec(), + }); YayoiPumpkin::execute_with(|| { assert_ok!(yayoi::PolkadotXcm::send_xcm( Here, @@ -333,9 +331,10 @@ mod tests { use yayoi::{RuntimeEvent, System}; System::events().iter().for_each(|r| println!(">>> {:?}", r.event)); - assert!(System::events() - .iter() - .any(|r| matches!(r.event, RuntimeEvent::PolkadotXcm(pallet_xcm::Event::Sent(_, _, _))))); + assert!(System::events().iter().any(|r| matches!( + r.event, + RuntimeEvent::PolkadotXcm(pallet_xcm::Event::Sent(_, _, _)) + ))); }); YayoiOctopus::execute_with(|| { @@ -391,9 +390,10 @@ mod tests { } fn kusama_send_rmrk(msg: &str, count: u32) { - let remark = yayoi::RuntimeCall::System(frame_system::Call::::remark_with_event { - remark: msg.as_bytes().to_vec(), - }); + let remark = + yayoi::RuntimeCall::System(frame_system::Call::::remark_with_event { + remark: msg.as_bytes().to_vec(), + }); KusamaNet::execute_with(|| { for _ in 0..count { assert_ok!(kusama_runtime::XcmPallet::send_xcm( @@ -401,7 +401,10 @@ mod tests { Parachain(1), Xcm(vec![Transact { origin_kind: OriginKind::SovereignAccount, - require_weight_at_most: Weight::from_parts(INITIAL_BALANCE as u64, 1024 * 1024), + require_weight_at_most: Weight::from_parts( + INITIAL_BALANCE as u64, + 1024 * 1024 + ), call: remark.encode().into(), }]), )); From cf7ecabea23bd2e9cc2012e997b7c954f889ff78 Mon Sep 17 00:00:00 2001 From: Roman Useinov Date: Wed, 12 Apr 2023 11:21:41 +0200 Subject: [PATCH 03/21] rename --- Cargo.lock | 58 +++++++-------- Cargo.toml | 2 +- xcm/xcm-emulator/example/Cargo.toml | 11 ++- xcm/xcm-emulator/example/src/lib.rs | 72 +++++++++---------- .../{yayoi => test_runtime}/Cargo.toml | 4 +- .../{yayoi => test_runtime}/src/lib.rs | 0 6 files changed, 76 insertions(+), 71 deletions(-) rename xcm/xcm-emulator/{yayoi => test_runtime}/Cargo.toml (97%) rename xcm/xcm-emulator/{yayoi => test_runtime}/src/lib.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index d35cf592395..8a964b459af 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13171,6 +13171,34 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13a4ec180a2de59b57434704ccfad967f789b12737738798fa08798cd5824c16" +[[package]] +name = "test-runtime" +version = "0.1.0" +dependencies = [ + "cumulus-pallet-dmp-queue", + "cumulus-pallet-parachain-system", + "cumulus-pallet-xcm", + "cumulus-pallet-xcmp-queue", + "cumulus-primitives-utility", + "frame-support", + "frame-system", + "pallet-balances", + "pallet-xcm", + "parachain-info", + "parity-scale-codec", + "polkadot-parachain", + "polkadot-runtime-parachains", + "scale-info", + "serde", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "xcm", + "xcm-builder", + "xcm-executor", +] + [[package]] name = "test-runtime-constants" version = "0.9.39" @@ -15240,9 +15268,9 @@ dependencies = [ "serde", "sp-io", "sp-runtime", + "test-runtime", "xcm", "xcm-emulator", - "yayoi", ] [[package]] @@ -15299,34 +15327,6 @@ dependencies = [ "time 0.3.17", ] -[[package]] -name = "yayoi" -version = "0.1.0" -dependencies = [ - "cumulus-pallet-dmp-queue", - "cumulus-pallet-parachain-system", - "cumulus-pallet-xcm", - "cumulus-pallet-xcmp-queue", - "cumulus-primitives-utility", - "frame-support", - "frame-system", - "pallet-balances", - "pallet-xcm", - "parachain-info", - "parity-scale-codec", - "polkadot-parachain", - "polkadot-runtime-parachains", - "scale-info", - "serde", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", - "xcm", - "xcm-builder", - "xcm-executor", -] - [[package]] name = "zeroize" version = "1.5.7" diff --git a/Cargo.toml b/Cargo.toml index 8b8d6233fac..34e5a0e929b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,7 +52,7 @@ members = [ "test/service", "xcm/xcm-emulator", "xcm/xcm-emulator/example", - "xcm/xcm-emulator/yayoi", + "xcm/xcm-emulator/test_runtime", ] [profile.release] diff --git a/xcm/xcm-emulator/example/Cargo.toml b/xcm/xcm-emulator/example/Cargo.toml index 1db8ed3891e..9d2d75d0225 100644 --- a/xcm/xcm-emulator/example/Cargo.toml +++ b/xcm/xcm-emulator/example/Cargo.toml @@ -1,8 +1,7 @@ [package] name = "xcm-emulator-example" version = "0.1.0" -license = "Apache-2.0" -authors = ["Shaun Wang "] +authors = ["Parity Technologies "] edition = "2021" [dependencies] @@ -29,4 +28,10 @@ pallet-xcm = { git = "https://github.com/paritytech/polkadot", branch = "master" xcm-emulator = { path = ".." } -yayoi = { path = "../yayoi" } +test-runtime = { path = "../test_runtime" } + +[features] +runtime-benchmarks = [ + "kusama-runtime/runtime-benchmarks", + "test-runtime/runtime-benchmarks", +] diff --git a/xcm/xcm-emulator/example/src/lib.rs b/xcm/xcm-emulator/example/src/lib.rs index 7886dc5e6fd..b9c9912d80b 100644 --- a/xcm/xcm-emulator/example/src/lib.rs +++ b/xcm/xcm-emulator/example/src/lib.rs @@ -28,32 +28,32 @@ decl_test_relay_chain! { } decl_test_parachain! { - pub struct YayoiPumpkin { - Runtime = yayoi::Runtime, - RuntimeOrigin = yayoi::RuntimeOrigin, - XcmpMessageHandler = yayoi::XcmpQueue, - DmpMessageHandler = yayoi::DmpQueue, - new_ext = yayoi_ext(1), + pub struct ParachainA { + Runtime = test_runtime::Runtime, + RuntimeOrigin = test_runtime::RuntimeOrigin, + XcmpMessageHandler = test_runtime::XcmpQueue, + DmpMessageHandler = test_runtime::DmpQueue, + new_ext = parachain_ext(1), } } decl_test_parachain! { - pub struct YayoiMushroom { - Runtime = yayoi::Runtime, - RuntimeOrigin = yayoi::RuntimeOrigin, - XcmpMessageHandler = yayoi::XcmpQueue, - DmpMessageHandler = yayoi::DmpQueue, - new_ext = yayoi_ext(2), + pub struct ParachainB { + Runtime = test_runtime::Runtime, + RuntimeOrigin = test_runtime::RuntimeOrigin, + XcmpMessageHandler = test_runtime::XcmpQueue, + DmpMessageHandler = test_runtime::DmpQueue, + new_ext = parachain_ext(2), } } decl_test_parachain! { - pub struct YayoiOctopus { - Runtime = yayoi::Runtime, - RuntimeOrigin = yayoi::RuntimeOrigin, - XcmpMessageHandler = yayoi::XcmpQueue, - DmpMessageHandler = yayoi::DmpQueue, - new_ext = yayoi_ext(3), + pub struct ParachainC { + Runtime = test_runtime::Runtime, + RuntimeOrigin = test_runtime::RuntimeOrigin, + XcmpMessageHandler = test_runtime::XcmpQueue, + DmpMessageHandler = test_runtime::DmpQueue, + new_ext = parachain_ext(3), } } @@ -61,9 +61,9 @@ decl_test_network! { pub struct Network { relay_chain = KusamaNet, parachains = vec![ - (1, YayoiPumpkin), - (2, YayoiMushroom), - (3, YayoiOctopus), + (1, ParachainA), + (2, ParachainB), + (3, ParachainC), ], } } @@ -71,8 +71,8 @@ decl_test_network! { pub const ALICE: AccountId32 = AccountId32::new([0u8; 32]); pub const INITIAL_BALANCE: u128 = 1_000_000_000_000; -pub fn yayoi_ext(para_id: u32) -> sp_io::TestExternalities { - use yayoi::{Runtime, System}; +pub fn parachain_ext(para_id: u32) -> sp_io::TestExternalities { + use test_runtime::{Runtime, System}; let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); @@ -191,8 +191,8 @@ mod tests { )); }); - YayoiPumpkin::execute_with(|| { - use yayoi::{RuntimeEvent, System}; + ParachainA::execute_with(|| { + use test_runtime::{RuntimeEvent, System}; System::events().iter().for_each(|r| println!(">>> {:?}", r.event)); assert!(System::events().iter().any(|r| matches!( @@ -227,7 +227,7 @@ mod tests { yayoi::RuntimeOrigin::root(), Some(3) )); - assert_ok!(yayoi::PolkadotXcm::send_xcm( + assert_ok!(test_runtime::PolkadotXcm::send_xcm( Here, Parent, Xcm(vec![ @@ -282,8 +282,8 @@ mod tests { )); }); - YayoiMushroom::execute_with(|| { - use yayoi::{RuntimeEvent, System}; + ParachainB::execute_with(|| { + use test_runtime::{RuntimeEvent, System}; System::events().iter().for_each(|r| println!(">>> {:?}", r.event)); assert!(System::events().iter().any(|r| matches!( @@ -295,7 +295,7 @@ mod tests { #[test] fn xcmp_through_a_parachain() { - use yayoi::{PolkadotXcm, Runtime, RuntimeCall}; + use test_runtime::{PolkadotXcm, Runtime, RuntimeCall}; Network::reset(); @@ -315,7 +315,7 @@ mod tests { send_xcm_to_octopus.get_dispatch_info().weight, Weight::from_parts(110000010, 10000010) ); - YayoiPumpkin::execute_with(|| { + ParachainA::execute_with(|| { assert_ok!(PolkadotXcm::send_xcm( Here, MultiLocation::new(1, X1(Parachain(2))), @@ -327,8 +327,8 @@ mod tests { )); }); - YayoiMushroom::execute_with(|| { - use yayoi::{RuntimeEvent, System}; + ParachainB::execute_with(|| { + use test_runtime::{RuntimeEvent, System}; System::events().iter().for_each(|r| println!(">>> {:?}", r.event)); assert!(System::events().iter().any(|r| matches!( @@ -337,8 +337,8 @@ mod tests { ))); }); - YayoiOctopus::execute_with(|| { - use yayoi::{RuntimeEvent, System}; + ParachainC::execute_with(|| { + use test_runtime::{RuntimeEvent, System}; // execution would fail, but good enough to check if the message is received System::events().iter().for_each(|r| println!(">>> {:?}", r.event)); @@ -413,8 +413,8 @@ mod tests { } fn parachain_receive_and_reset_events(received: bool) { - YayoiPumpkin::execute_with(|| { - use yayoi::{RuntimeEvent, System}; + ParachainA::execute_with(|| { + use test_runtime::{RuntimeEvent, System}; System::events().iter().for_each(|r| println!(">>> {:?}", r.event)); if received { diff --git a/xcm/xcm-emulator/yayoi/Cargo.toml b/xcm/xcm-emulator/test_runtime/Cargo.toml similarity index 97% rename from xcm/xcm-emulator/yayoi/Cargo.toml rename to xcm/xcm-emulator/test_runtime/Cargo.toml index 39d370e19f1..ac72f6a6ce2 100644 --- a/xcm/xcm-emulator/yayoi/Cargo.toml +++ b/xcm/xcm-emulator/test_runtime/Cargo.toml @@ -1,9 +1,9 @@ [package] -name = "yayoi" +name = "test-runtime" description = "A simple runtime for cross-chain messages tests." license = "Apache-2.0" version = "0.1.0" -authors = ["Shaun Wang "] +authors = ["Parity Technologies "] edition = "2021" [dependencies] diff --git a/xcm/xcm-emulator/yayoi/src/lib.rs b/xcm/xcm-emulator/test_runtime/src/lib.rs similarity index 100% rename from xcm/xcm-emulator/yayoi/src/lib.rs rename to xcm/xcm-emulator/test_runtime/src/lib.rs From 9ed7732621ae14c97874bd8b4c932553adddaeae Mon Sep 17 00:00:00 2001 From: Roman Useinov Date: Wed, 12 Apr 2023 11:23:59 +0200 Subject: [PATCH 04/21] readme --- xcm/xcm-emulator/README.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 xcm/xcm-emulator/README.md diff --git a/xcm/xcm-emulator/README.md b/xcm/xcm-emulator/README.md new file mode 100644 index 00000000000..53fb373f113 --- /dev/null +++ b/xcm/xcm-emulator/README.md @@ -0,0 +1,5 @@ +# xcm-emulator + +xcm-emulator uses production relay chain and parachain runtime. +Users could plug in Kusama, Statemine, Polkadot and other pre-configured runtimes. +With up-to-date chain specs, it's able to verify if specific XCM messages work in live networks. From 21e24e5a80fbeb70461c353dbeff164fc981c0db Mon Sep 17 00:00:00 2001 From: Roman Useinov Date: Wed, 12 Apr 2023 12:18:32 +0200 Subject: [PATCH 05/21] more rename --- xcm/xcm-emulator/example/src/lib.rs | 31 ++++++++++++++++------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/xcm/xcm-emulator/example/src/lib.rs b/xcm/xcm-emulator/example/src/lib.rs index b9c9912d80b..36c65c645ee 100644 --- a/xcm/xcm-emulator/example/src/lib.rs +++ b/xcm/xcm-emulator/example/src/lib.rs @@ -171,10 +171,11 @@ mod tests { fn dmp() { Network::reset(); - let remark = - yayoi::RuntimeCall::System(frame_system::Call::::remark_with_event { + let remark = test_runtime::RuntimeCall::System( + frame_system::Call::::remark_with_event { remark: "Hello from Kusama!".as_bytes().to_vec(), - }); + }, + ); KusamaNet::execute_with(|| { assert_ok!(kusama_runtime::XcmPallet::force_default_xcm_version( kusama_runtime::RuntimeOrigin::root(), @@ -222,9 +223,9 @@ mod tests { >::remark_with_event { remark: "Hello from Pumpkin!".as_bytes().to_vec(), }); - YayoiPumpkin::execute_with(|| { - assert_ok!(yayoi::PolkadotXcm::force_default_xcm_version( - yayoi::RuntimeOrigin::root(), + ParachainA::execute_with(|| { + assert_ok!(test_runtime::PolkadotXcm::force_default_xcm_version( + test_runtime::RuntimeOrigin::root(), Some(3) )); assert_ok!(test_runtime::PolkadotXcm::send_xcm( @@ -266,12 +267,13 @@ mod tests { fn xcmp() { Network::reset(); - let remark = - yayoi::RuntimeCall::System(frame_system::Call::::remark_with_event { + let remark = test_runtime::RuntimeCall::System( + frame_system::Call::::remark_with_event { remark: "Hello from Pumpkin!".as_bytes().to_vec(), - }); - YayoiPumpkin::execute_with(|| { - assert_ok!(yayoi::PolkadotXcm::send_xcm( + }, + ); + ParachainA::execute_with(|| { + assert_ok!(test_runtime::PolkadotXcm::send_xcm( Here, MultiLocation::new(1, X1(Parachain(2))), Xcm(vec![Transact { @@ -390,10 +392,11 @@ mod tests { } fn kusama_send_rmrk(msg: &str, count: u32) { - let remark = - yayoi::RuntimeCall::System(frame_system::Call::::remark_with_event { + let remark = test_runtime::RuntimeCall::System( + frame_system::Call::::remark_with_event { remark: msg.as_bytes().to_vec(), - }); + }, + ); KusamaNet::execute_with(|| { for _ in 0..count { assert_ok!(kusama_runtime::XcmPallet::send_xcm( From f59a36efe4486ecc53e7e56f515b437702029a3a Mon Sep 17 00:00:00 2001 From: Roman Useinov Date: Wed, 12 Apr 2023 12:55:21 +0200 Subject: [PATCH 06/21] rename directory --- Cargo.toml | 2 +- xcm/xcm-emulator/example/Cargo.toml | 2 +- xcm/xcm-emulator/{test_runtime => test-runtime}/Cargo.toml | 0 xcm/xcm-emulator/{test_runtime => test-runtime}/src/lib.rs | 0 4 files changed, 2 insertions(+), 2 deletions(-) rename xcm/xcm-emulator/{test_runtime => test-runtime}/Cargo.toml (100%) rename xcm/xcm-emulator/{test_runtime => test-runtime}/src/lib.rs (100%) diff --git a/Cargo.toml b/Cargo.toml index 34e5a0e929b..1bc3fc0d236 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -52,7 +52,7 @@ members = [ "test/service", "xcm/xcm-emulator", "xcm/xcm-emulator/example", - "xcm/xcm-emulator/test_runtime", + "xcm/xcm-emulator/test-runtime", ] [profile.release] diff --git a/xcm/xcm-emulator/example/Cargo.toml b/xcm/xcm-emulator/example/Cargo.toml index 9d2d75d0225..5d87c2dd5cf 100644 --- a/xcm/xcm-emulator/example/Cargo.toml +++ b/xcm/xcm-emulator/example/Cargo.toml @@ -28,7 +28,7 @@ pallet-xcm = { git = "https://github.com/paritytech/polkadot", branch = "master" xcm-emulator = { path = ".." } -test-runtime = { path = "../test_runtime" } +test-runtime = { path = "../test-runtime" } [features] runtime-benchmarks = [ diff --git a/xcm/xcm-emulator/test_runtime/Cargo.toml b/xcm/xcm-emulator/test-runtime/Cargo.toml similarity index 100% rename from xcm/xcm-emulator/test_runtime/Cargo.toml rename to xcm/xcm-emulator/test-runtime/Cargo.toml diff --git a/xcm/xcm-emulator/test_runtime/src/lib.rs b/xcm/xcm-emulator/test-runtime/src/lib.rs similarity index 100% rename from xcm/xcm-emulator/test_runtime/src/lib.rs rename to xcm/xcm-emulator/test-runtime/src/lib.rs From 11b065b0a2537f539e0622a577a2ec6289dfb8e4 Mon Sep 17 00:00:00 2001 From: Roman Useinov Date: Wed, 12 Apr 2023 19:47:12 +0200 Subject: [PATCH 07/21] implement AssetTransactor --- xcm/xcm-emulator/test-runtime/src/lib.rs | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/xcm/xcm-emulator/test-runtime/src/lib.rs b/xcm/xcm-emulator/test-runtime/src/lib.rs index 78c1708d9ec..9010936892c 100644 --- a/xcm/xcm-emulator/test-runtime/src/lib.rs +++ b/xcm/xcm-emulator/test-runtime/src/lib.rs @@ -30,10 +30,12 @@ use sp_runtime::{ }; use xcm::v3::prelude::*; use xcm_builder::{ - AccountId32Aliases, AllowUnpaidExecutionFrom, EnsureXcmOrigin, FixedWeightBounds, - ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, - SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, + AccountId32Aliases, AllowUnpaidExecutionFrom, CurrencyAdapter, EnsureXcmOrigin, + FixedWeightBounds, IsConcrete, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, + SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32, + SovereignSignedViaLocation, }; + use xcm_executor::{Config, XcmExecutor}; pub type AccountId = AccountId32; @@ -120,9 +122,22 @@ parameter_types! { pub const UnitWeightCost: u64 = 10; pub const MaxInstructions: u32 = 100; pub const MaxAssetsIntoHolding: u32 = 64; + pub const RelayChain: MultiLocation = MultiLocation::parent(); } -pub type LocalAssetTransactor = (); +/// Means for transacting assets on this chain. +pub type LocalAssetTransactor = CurrencyAdapter< + // Use this currency: + Balances, + // Use this currency when it is a fungible asset matching the given location or name: + IsConcrete, + // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID: + LocationToAccountId, + // Our chain's account ID type (we can't get away without mentioning it explicitly): + AccountId, + // We don't track any teleports. + (), +>; /// The means for routing XCM messages which are not for local execution into /// the right message queues. From e7e8c1a89dcf3bdd5a43a9451f71734315eeb731 Mon Sep 17 00:00:00 2001 From: Roman Useinov Date: Thu, 13 Apr 2023 15:36:59 +0200 Subject: [PATCH 08/21] Update xcm/xcm-emulator/README.md Co-authored-by: Muharem Ismailov --- xcm/xcm-emulator/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xcm/xcm-emulator/README.md b/xcm/xcm-emulator/README.md index 53fb373f113..528a6ebe884 100644 --- a/xcm/xcm-emulator/README.md +++ b/xcm/xcm-emulator/README.md @@ -1,5 +1,5 @@ # xcm-emulator -xcm-emulator uses production relay chain and parachain runtime. +xcm-emulator uses relay chain and parachain runtimes. Users could plug in Kusama, Statemine, Polkadot and other pre-configured runtimes. With up-to-date chain specs, it's able to verify if specific XCM messages work in live networks. From 3306ff0ea086a2d2388fa6fac658590554306d28 Mon Sep 17 00:00:00 2001 From: Roman Useinov Date: Fri, 5 May 2023 12:22:54 +0200 Subject: [PATCH 09/21] address review comments (#2502) --- xcm/xcm-emulator/Cargo.toml | 2 +- xcm/xcm-emulator/README.md | 10 ++- xcm/xcm-emulator/example/src/lib.rs | 77 +++++++++++++----------- xcm/xcm-emulator/test-runtime/Cargo.toml | 2 +- 4 files changed, 52 insertions(+), 39 deletions(-) diff --git a/xcm/xcm-emulator/Cargo.toml b/xcm/xcm-emulator/Cargo.toml index ff8b1e11963..819de0199c8 100644 --- a/xcm/xcm-emulator/Cargo.toml +++ b/xcm/xcm-emulator/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "xcm-emulator" -description = "Test kit to emulate cross-chain message passing and XCM execution" +description = "Test kit to emulate XCM program execution." version = "0.1.0" authors = ["Parity Technologies "] edition = "2021" diff --git a/xcm/xcm-emulator/README.md b/xcm/xcm-emulator/README.md index 528a6ebe884..378a47d6291 100644 --- a/xcm/xcm-emulator/README.md +++ b/xcm/xcm-emulator/README.md @@ -1,5 +1,9 @@ # xcm-emulator -xcm-emulator uses relay chain and parachain runtimes. -Users could plug in Kusama, Statemine, Polkadot and other pre-configured runtimes. -With up-to-date chain specs, it's able to verify if specific XCM messages work in live networks. +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, verifying outcomes, weights and side-effects. + +## How to use + +Please refer to [example crate source-code](example/src/lib.rs) for usage examples. diff --git a/xcm/xcm-emulator/example/src/lib.rs b/xcm/xcm-emulator/example/src/lib.rs index 36c65c645ee..d1abcb9315e 100644 --- a/xcm/xcm-emulator/example/src/lib.rs +++ b/xcm/xcm-emulator/example/src/lib.rs @@ -19,14 +19,16 @@ use sp_runtime::AccountId32; use xcm_emulator::{decl_test_network, decl_test_parachain, decl_test_relay_chain}; +// Setup relay chain. decl_test_relay_chain! { - pub struct KusamaNet { + pub struct KusamaRelay { Runtime = kusama_runtime::Runtime, XcmConfig = kusama_runtime::xcm_config::XcmConfig, new_ext = kusama_ext(), } } +// Setup ParachainA. decl_test_parachain! { pub struct ParachainA { Runtime = test_runtime::Runtime, @@ -37,6 +39,7 @@ decl_test_parachain! { } } +// Setup ParachainB. decl_test_parachain! { pub struct ParachainB { Runtime = test_runtime::Runtime, @@ -47,6 +50,7 @@ decl_test_parachain! { } } +// Setup ParachainC. decl_test_parachain! { pub struct ParachainC { Runtime = test_runtime::Runtime, @@ -57,9 +61,10 @@ decl_test_parachain! { } } +// Setup a network with all the declared parachains and a relay chain. decl_test_network! { pub struct Network { - relay_chain = KusamaNet, + relay_chain = KusamaRelay, parachains = vec![ (1, ParachainA), (2, ParachainB), @@ -71,6 +76,7 @@ decl_test_network! { pub const ALICE: AccountId32 = AccountId32::new([0u8; 32]); pub const INITIAL_BALANCE: u128 = 1_000_000_000_000; +// Parachain TextExternalities setup. pub fn parachain_ext(para_id: u32) -> sp_io::TestExternalities { use test_runtime::{Runtime, System}; @@ -136,6 +142,7 @@ fn default_parachains_host_configuration( } } +// Relay chain TestExternalities setup. pub fn kusama_ext() -> sp_io::TestExternalities { use kusama_runtime::{Runtime, System}; @@ -164,7 +171,7 @@ mod tests { use cumulus_primitives_core::ParaId; use frame_support::{assert_ok, dispatch::GetDispatchInfo, traits::Currency}; use sp_runtime::traits::AccountIdConversion; - use xcm::{v3::prelude::*, VersionedMultiLocation, VersionedXcm}; + use xcm::{latest::Error::BadOrigin, v3::prelude::*, VersionedMultiLocation, VersionedXcm}; use xcm_emulator::TestExt; #[test] @@ -176,7 +183,7 @@ mod tests { remark: "Hello from Kusama!".as_bytes().to_vec(), }, ); - KusamaNet::execute_with(|| { + KusamaRelay::execute_with(|| { assert_ok!(kusama_runtime::XcmPallet::force_default_xcm_version( kusama_runtime::RuntimeOrigin::root(), Some(3) @@ -207,7 +214,7 @@ mod tests { fn ump() { Network::reset(); - KusamaNet::execute_with(|| { + KusamaRelay::execute_with(|| { assert_ok!(kusama_runtime::XcmPallet::force_default_xcm_version( kusama_runtime::RuntimeOrigin::root(), Some(3) @@ -221,7 +228,7 @@ mod tests { let remark = kusama_runtime::RuntimeCall::System(frame_system::Call::< kusama_runtime::Runtime, >::remark_with_event { - remark: "Hello from Pumpkin!".as_bytes().to_vec(), + remark: "Hello from ParachainA!".as_bytes().to_vec(), }); ParachainA::execute_with(|| { assert_ok!(test_runtime::PolkadotXcm::force_default_xcm_version( @@ -245,7 +252,7 @@ mod tests { )); }); - KusamaNet::execute_with(|| { + KusamaRelay::execute_with(|| { use kusama_runtime::{RuntimeEvent, System}; // TODO: https://github.com/paritytech/polkadot/pull/6824 or change this call to // force_create_assets like we do in cumulus integration tests. @@ -269,7 +276,7 @@ mod tests { let remark = test_runtime::RuntimeCall::System( frame_system::Call::::remark_with_event { - remark: "Hello from Pumpkin!".as_bytes().to_vec(), + remark: "Hello from ParachainA!".as_bytes().to_vec(), }, ); ParachainA::execute_with(|| { @@ -278,7 +285,7 @@ mod tests { MultiLocation::new(1, X1(Parachain(2))), Xcm(vec![Transact { origin_kind: OriginKind::SovereignAccount, - require_weight_at_most: 20_000_000.into(), + require_weight_at_most: Weight::from_parts(9_000_000, 0), call: remark.encode().into(), }]), )); @@ -301,21 +308,24 @@ mod tests { Network::reset(); - // The message goes through: Pumpkin --> Mushroom --> Octopus + // The message goes through: ParachainA --> ParachainB --> ParachainC let remark = RuntimeCall::System(frame_system::Call::::remark_with_event { - remark: "Hello from Pumpkin!".as_bytes().to_vec(), + remark: "Hello from ParachainA!".as_bytes().to_vec(), }); - let send_xcm_to_octopus = RuntimeCall::PolkadotXcm(pallet_xcm::Call::::send { + let send_xcm_to_parachain_c = RuntimeCall::PolkadotXcm(pallet_xcm::Call::::send { dest: Box::new(VersionedMultiLocation::V3(MultiLocation::new(1, X1(Parachain(3))))), message: Box::new(VersionedXcm::V3(Xcm(vec![Transact { origin_kind: OriginKind::SovereignAccount, - require_weight_at_most: 10_000_000.into(), + // The weight here does not matter, as this is going to fail with BadOrigin once it + // reaches ParachainC, as it's not going to satisfy AccountId32Aliases conversion + // rules. + require_weight_at_most: Weight::from_parts(0, 0), call: remark.encode().into(), }]))), }); assert_eq!( - send_xcm_to_octopus.get_dispatch_info().weight, - Weight::from_parts(110000010, 10000010) + send_xcm_to_parachain_c.get_dispatch_info().weight, + Weight::from_parts(100000010, 10) ); ParachainA::execute_with(|| { assert_ok!(PolkadotXcm::send_xcm( @@ -324,7 +334,7 @@ mod tests { Xcm(vec![Transact { origin_kind: OriginKind::SovereignAccount, require_weight_at_most: 110_000_010.into(), - call: send_xcm_to_octopus.encode().into(), + call: send_xcm_to_parachain_c.encode().into(), }]), )); }); @@ -341,12 +351,11 @@ mod tests { ParachainC::execute_with(|| { use test_runtime::{RuntimeEvent, System}; - // execution would fail, but good enough to check if the message is received System::events().iter().for_each(|r| println!(">>> {:?}", r.event)); assert!(System::events().iter().any(|r| matches!( r.event, - RuntimeEvent::XcmpQueue(cumulus_pallet_xcmp_queue::Event::Fail { .. }) + RuntimeEvent::XcmpQueue(cumulus_pallet_xcmp_queue::Event::Fail { error, .. }) if error == BadOrigin ))); }); } @@ -354,50 +363,50 @@ mod tests { #[test] fn deduplicate_dmp() { Network::reset(); - KusamaNet::execute_with(|| { + KusamaRelay::execute_with(|| { assert_ok!(kusama_runtime::XcmPallet::force_default_xcm_version( kusama_runtime::RuntimeOrigin::root(), Some(3) )); }); - kusama_send_rmrk("Kusama", 2); - parachain_receive_and_reset_events(true); + send_remark_with_event_to_child_parachain_a("Kusama", 2); + parachain_a_verify_remark_event_and_reset_all_events(true); // a different dmp message in same relay-parent-block allow execution. - kusama_send_rmrk("Polkadot", 1); - parachain_receive_and_reset_events(true); + send_remark_with_event_to_child_parachain_a("Polkadot", 1); + parachain_a_verify_remark_event_and_reset_all_events(true); // same dmp message with same relay-parent-block wouldn't execution - kusama_send_rmrk("Kusama", 1); - parachain_receive_and_reset_events(false); + send_remark_with_event_to_child_parachain_a("Kusama", 1); + parachain_a_verify_remark_event_and_reset_all_events(false); // different relay-parent-block allow dmp message execution - KusamaNet::execute_with(|| kusama_runtime::System::set_block_number(2)); + KusamaRelay::execute_with(|| kusama_runtime::System::set_block_number(2)); - kusama_send_rmrk("Kusama", 1); - parachain_receive_and_reset_events(true); + send_remark_with_event_to_child_parachain_a("Kusama", 1); + parachain_a_verify_remark_event_and_reset_all_events(true); // reset can send same dmp message again Network::reset(); - KusamaNet::execute_with(|| { + KusamaRelay::execute_with(|| { assert_ok!(kusama_runtime::XcmPallet::force_default_xcm_version( kusama_runtime::RuntimeOrigin::root(), Some(3) )); }); - kusama_send_rmrk("Kusama", 1); - parachain_receive_and_reset_events(true); + send_remark_with_event_to_child_parachain_a("Kusama", 1); + parachain_a_verify_remark_event_and_reset_all_events(true); } - fn kusama_send_rmrk(msg: &str, count: u32) { + fn send_remark_with_event_to_child_parachain_a(msg: &str, count: u32) { let remark = test_runtime::RuntimeCall::System( frame_system::Call::::remark_with_event { remark: msg.as_bytes().to_vec(), }, ); - KusamaNet::execute_with(|| { + KusamaRelay::execute_with(|| { for _ in 0..count { assert_ok!(kusama_runtime::XcmPallet::send_xcm( Here, @@ -415,7 +424,7 @@ mod tests { }); } - fn parachain_receive_and_reset_events(received: bool) { + fn parachain_a_verify_remark_event_and_reset_all_events(received: bool) { ParachainA::execute_with(|| { use test_runtime::{RuntimeEvent, System}; System::events().iter().for_each(|r| println!(">>> {:?}", r.event)); diff --git a/xcm/xcm-emulator/test-runtime/Cargo.toml b/xcm/xcm-emulator/test-runtime/Cargo.toml index ac72f6a6ce2..2b18d82db52 100644 --- a/xcm/xcm-emulator/test-runtime/Cargo.toml +++ b/xcm/xcm-emulator/test-runtime/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "test-runtime" -description = "A simple runtime for cross-chain messages tests." +description = "A simple runtime for cross-chain message tests." license = "Apache-2.0" version = "0.1.0" authors = ["Parity Technologies "] From 51cb75dcfcf633cd6d35f63c2f7ff36b3b5dba08 Mon Sep 17 00:00:00 2001 From: Squirrel Date: Fri, 5 May 2023 11:32:31 +0100 Subject: [PATCH 10/21] Update xcm/xcm-emulator/example/src/lib.rs Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> --- xcm/xcm-emulator/example/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xcm/xcm-emulator/example/src/lib.rs b/xcm/xcm-emulator/example/src/lib.rs index d1abcb9315e..8d3e478abcf 100644 --- a/xcm/xcm-emulator/example/src/lib.rs +++ b/xcm/xcm-emulator/example/src/lib.rs @@ -271,7 +271,7 @@ mod tests { } #[test] - fn xcmp() { + fn para_to_para() { Network::reset(); let remark = test_runtime::RuntimeCall::System( From b68c8ef6a7639a7fa8cd9e408fb171c5a71d6d48 Mon Sep 17 00:00:00 2001 From: Squirrel Date: Fri, 5 May 2023 12:42:39 +0100 Subject: [PATCH 11/21] Update xcm/xcm-emulator/README.md --- xcm/xcm-emulator/README.md | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/xcm/xcm-emulator/README.md b/xcm/xcm-emulator/README.md index 378a47d6291..ef90595a8d7 100644 --- a/xcm/xcm-emulator/README.md +++ b/xcm/xcm-emulator/README.md @@ -1,8 +1,22 @@ # 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, verifying outcomes, weights and side-effects. +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, 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 channels are mocked, using xcm-emulator tests to test +channel setup would not be appropriate. + +## 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. ## How to use From 8051e9d925f0c52cf88dd935f8214468b2ac5671 Mon Sep 17 00:00:00 2001 From: Giles Cope Date: Fri, 5 May 2023 12:51:11 +0100 Subject: [PATCH 12/21] Use 2d weights. --- xcm/xcm-emulator/example/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xcm/xcm-emulator/example/src/lib.rs b/xcm/xcm-emulator/example/src/lib.rs index 8d3e478abcf..77fdb661dbe 100644 --- a/xcm/xcm-emulator/example/src/lib.rs +++ b/xcm/xcm-emulator/example/src/lib.rs @@ -333,7 +333,7 @@ mod tests { MultiLocation::new(1, X1(Parachain(2))), Xcm(vec![Transact { origin_kind: OriginKind::SovereignAccount, - require_weight_at_most: 110_000_010.into(), + require_weight_at_most: Weight::from_parts(110_000_010, 0), call: send_xcm_to_parachain_c.encode().into(), }]), )); From c304e2a2a07f6c88b219795312f25706042bdde7 Mon Sep 17 00:00:00 2001 From: Giles Cope Date: Fri, 5 May 2023 13:16:33 +0100 Subject: [PATCH 13/21] Point out nearer the failure why it should fail --- xcm/xcm-emulator/example/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/xcm/xcm-emulator/example/src/lib.rs b/xcm/xcm-emulator/example/src/lib.rs index 77fdb661dbe..d8a2bca257f 100644 --- a/xcm/xcm-emulator/example/src/lib.rs +++ b/xcm/xcm-emulator/example/src/lib.rs @@ -349,6 +349,7 @@ mod tests { ))); }); + // ParachainC: The origin should not satisfy AccountId32Aliases conversion rules and thus fail. ParachainC::execute_with(|| { use test_runtime::{RuntimeEvent, System}; System::events().iter().for_each(|r| println!(">>> {:?}", r.event)); From 8894e33793ac84b11da011c412cd4a343ac4f594 Mon Sep 17 00:00:00 2001 From: Giles Cope Date: Fri, 5 May 2023 14:39:05 +0100 Subject: [PATCH 14/21] Move test-runtime to under examples --- Cargo.toml | 2 +- xcm/xcm-emulator/example/Cargo.toml | 2 +- .../{ => example}/test-runtime/Cargo.toml | 12 ++++++------ .../{ => example}/test-runtime/src/lib.rs | 0 4 files changed, 8 insertions(+), 8 deletions(-) rename xcm/xcm-emulator/{ => example}/test-runtime/Cargo.toml (80%) rename xcm/xcm-emulator/{ => example}/test-runtime/src/lib.rs (100%) diff --git a/Cargo.toml b/Cargo.toml index f1057060eda..e8476d04273 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -57,7 +57,7 @@ members = [ "test/service", "xcm/xcm-emulator", "xcm/xcm-emulator/example", - "xcm/xcm-emulator/test-runtime", + "xcm/xcm-emulator/example/test-runtime", ] [profile.release] diff --git a/xcm/xcm-emulator/example/Cargo.toml b/xcm/xcm-emulator/example/Cargo.toml index 5d87c2dd5cf..e5bacd89909 100644 --- a/xcm/xcm-emulator/example/Cargo.toml +++ b/xcm/xcm-emulator/example/Cargo.toml @@ -28,7 +28,7 @@ pallet-xcm = { git = "https://github.com/paritytech/polkadot", branch = "master" xcm-emulator = { path = ".." } -test-runtime = { path = "../test-runtime" } +test-runtime = { path = "test-runtime" } [features] runtime-benchmarks = [ diff --git a/xcm/xcm-emulator/test-runtime/Cargo.toml b/xcm/xcm-emulator/example/test-runtime/Cargo.toml similarity index 80% rename from xcm/xcm-emulator/test-runtime/Cargo.toml rename to xcm/xcm-emulator/example/test-runtime/Cargo.toml index 2b18d82db52..945d9e54751 100644 --- a/xcm/xcm-emulator/test-runtime/Cargo.toml +++ b/xcm/xcm-emulator/example/test-runtime/Cargo.toml @@ -19,12 +19,12 @@ pallet-balances = { git = "https://github.com/paritytech/substrate", default-fea frame-support = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } frame-system = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } -cumulus-pallet-dmp-queue = { path = "../../../pallets/dmp-queue", default-features = false } -cumulus-pallet-xcmp-queue = { path = "../../../pallets/xcmp-queue", default-features = false } -parachain-info = { path = "../../../parachains/pallets/parachain-info", default-features = false } -cumulus-pallet-xcm = { path = "../../../pallets/xcm", default-features = false } -cumulus-pallet-parachain-system = { path = "../../../pallets/parachain-system", default-features = false } -cumulus-primitives-utility = { path = "../../../primitives/utility", default-features = false } +cumulus-pallet-dmp-queue = { path = "../../../../pallets/dmp-queue", default-features = false } +cumulus-pallet-xcmp-queue = { path = "../../../../pallets/xcmp-queue", default-features = false } +parachain-info = { path = "../../../../parachains/pallets/parachain-info", default-features = false } +cumulus-pallet-xcm = { path = "../../../../pallets/xcm", default-features = false } +cumulus-pallet-parachain-system = { path = "../../../../pallets/parachain-system", default-features = false } +cumulus-primitives-utility = { path = "../../../../primitives/utility", default-features = false } xcm = { git = "https://github.com/paritytech/polkadot", branch = "master" } xcm-executor = { git = "https://github.com/paritytech/polkadot", branch = "master" } diff --git a/xcm/xcm-emulator/test-runtime/src/lib.rs b/xcm/xcm-emulator/example/test-runtime/src/lib.rs similarity index 100% rename from xcm/xcm-emulator/test-runtime/src/lib.rs rename to xcm/xcm-emulator/example/test-runtime/src/lib.rs From 304506421a6e44c885807ff4357b21579c25e424 Mon Sep 17 00:00:00 2001 From: Giles Cope Date: Fri, 5 May 2023 15:50:53 +0100 Subject: [PATCH 15/21] Walk through how to use it --- xcm/xcm-emulator/README.md | 87 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/xcm/xcm-emulator/README.md b/xcm/xcm-emulator/README.md index ef90595a8d7..a1c2418ae0b 100644 --- a/xcm/xcm-emulator/README.md +++ b/xcm/xcm-emulator/README.md @@ -20,4 +20,91 @@ repo) is the perfect tool for this. ## How to use +1. Setup a relay chain: + +```rust +decl_test_relay_chain! { + pub struct KusamaRelay { + Runtime = kusama_runtime::Runtime, + XcmConfig = kusama_runtime::xcm_config::XcmConfig, + new_ext = kusama_ext(), + } +} +``` + +2. Define some parachains: +```rust +decl_test_parachain! { + pub struct ParachainA { + Runtime = test_runtime::Runtime, + RuntimeOrigin = test_runtime::RuntimeOrigin, + XcmpMessageHandler = test_runtime::XcmpQueue, + DmpMessageHandler = test_runtime::DmpQueue, + new_ext = parachain_ext(1), + } +} +``` + +3. Setup a network with all the declared parachains and a relay chain: +```rust +decl_test_network! { + pub struct Network { + relay_chain = KusamaRelay, + parachains = vec![ + (1, ParachainA), + ], + } +} +``` + +This will wire the in-memory chains together using a mocked network. + +4. The relay chain and each parachain needs its `TestExternalities` set up. + +5. Finally write some tests: + +In the tests it's a good idea to upgrade XCM as the first thing in a test. +Here is a test that upgrades the XCM to v3 and then sends a remark: + +```rust + + #[test] + fn a_test() { + Network::reset(); + + KusamaRelay::execute_with(|| { + assert_ok!(kusama_runtime::XcmPallet::force_default_xcm_version( + kusama_runtime::RuntimeOrigin::root(), + Some(3) + )); + + assert_ok!(test_runtime::PolkadotXcm::send_xcm( + Here, + MultiLocation::new(1, X1(Parachain(2))), + Xcm(vec![Transact { + origin_kind: OriginKind::SovereignAccount, + require_weight_at_most: Weight::from_parts(9_000_000, 0), + call: test_runtime::RuntimeCall::System( + frame_system::Call::::remark_with_event { + remark: "Hello from Relay!".as_bytes().to_vec(), + }, + ).encode().into(), + }]), + )); + }); + + ParachainA::execute_with(|| { + assert_ok!(test_runtime::PolkadotXcm::force_default_xcm_version( + test_runtime::RuntimeOrigin::root(), + Some(3) + )); + + assert!(System::events().iter().any(|r| matches!( + r.event, + RuntimeEvent::System(frame_system::Event::Remarked { .. }) + ))); + }); + } +``` + Please refer to [example crate source-code](example/src/lib.rs) for usage examples. From 921310185d7c6ac455efa52510b90dde7ba02fc9 Mon Sep 17 00:00:00 2001 From: Giles Cope Date: Fri, 5 May 2023 20:49:45 +0100 Subject: [PATCH 16/21] proof needs to be non-zero --- xcm/xcm-emulator/example/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xcm/xcm-emulator/example/src/lib.rs b/xcm/xcm-emulator/example/src/lib.rs index d8a2bca257f..77c1fc1b7ca 100644 --- a/xcm/xcm-emulator/example/src/lib.rs +++ b/xcm/xcm-emulator/example/src/lib.rs @@ -333,7 +333,7 @@ mod tests { MultiLocation::new(1, X1(Parachain(2))), Xcm(vec![Transact { origin_kind: OriginKind::SovereignAccount, - require_weight_at_most: Weight::from_parts(110_000_010, 0), + require_weight_at_most: Weight::from_parts(110_000_010, 20_000), call: send_xcm_to_parachain_c.encode().into(), }]), )); From a765cd473c2bb50d4ac2636644392e80a3baae0a Mon Sep 17 00:00:00 2001 From: joe petrowski <25483142+joepetrowski@users.noreply.github.com> Date: Tue, 9 May 2023 08:03:08 +0200 Subject: [PATCH 17/21] Apply suggestions from code review --- xcm/xcm-emulator/README.md | 4 ++-- xcm/xcm-emulator/example/src/lib.rs | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/xcm/xcm-emulator/README.md b/xcm/xcm-emulator/README.md index a1c2418ae0b..297a8d575f3 100644 --- a/xcm/xcm-emulator/README.md +++ b/xcm/xcm-emulator/README.md @@ -20,7 +20,7 @@ repo) is the perfect tool for this. ## How to use -1. Setup a relay chain: +1. Set up a relay chain: ```rust decl_test_relay_chain! { @@ -45,7 +45,7 @@ decl_test_parachain! { } ``` -3. Setup a network with all the declared parachains and a relay chain: +3. Set up a network with all the declared parachains and a relay chain: ```rust decl_test_network! { pub struct Network { diff --git a/xcm/xcm-emulator/example/src/lib.rs b/xcm/xcm-emulator/example/src/lib.rs index 77c1fc1b7ca..e8626db930c 100644 --- a/xcm/xcm-emulator/example/src/lib.rs +++ b/xcm/xcm-emulator/example/src/lib.rs @@ -19,7 +19,7 @@ use sp_runtime::AccountId32; use xcm_emulator::{decl_test_network, decl_test_parachain, decl_test_relay_chain}; -// Setup relay chain. +// Set up relay chain. decl_test_relay_chain! { pub struct KusamaRelay { Runtime = kusama_runtime::Runtime, @@ -28,7 +28,7 @@ decl_test_relay_chain! { } } -// Setup ParachainA. +// Set up ParachainA. decl_test_parachain! { pub struct ParachainA { Runtime = test_runtime::Runtime, @@ -39,7 +39,7 @@ decl_test_parachain! { } } -// Setup ParachainB. +// Set up ParachainB. decl_test_parachain! { pub struct ParachainB { Runtime = test_runtime::Runtime, @@ -50,7 +50,7 @@ decl_test_parachain! { } } -// Setup ParachainC. +// Set up ParachainC. decl_test_parachain! { pub struct ParachainC { Runtime = test_runtime::Runtime, @@ -61,7 +61,7 @@ decl_test_parachain! { } } -// Setup a network with all the declared parachains and a relay chain. +// Set up a network with all the declared parachains and a relay chain. decl_test_network! { pub struct Network { relay_chain = KusamaRelay, From 9e77d16626b835d64a6004a3b4d1a82ebb00529b Mon Sep 17 00:00:00 2001 From: Squirrel Date: Tue, 9 May 2023 15:08:03 +0100 Subject: [PATCH 18/21] Update xcm/xcm-emulator/README.md Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> --- xcm/xcm-emulator/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xcm/xcm-emulator/README.md b/xcm/xcm-emulator/README.md index 297a8d575f3..384a781fab4 100644 --- a/xcm/xcm-emulator/README.md +++ b/xcm/xcm-emulator/README.md @@ -3,8 +3,8 @@ 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, verifying -outcomes, weights and side-effects. It is faster than spinning up +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 From 342babdf31733202d8c57abc91cd19b69c008e5f Mon Sep 17 00:00:00 2001 From: Ignacio Palacios Date: Thu, 18 May 2023 13:06:51 +0200 Subject: [PATCH 19/21] 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 --- Cargo.lock | 136 ++- Cargo.toml | 5 +- .../assets/statemine/0_xcm}/0_init.yml | 0 .../assets/statemine/0_xcm}/1_dmp.yml | 0 .../assets/statemine/0_xcm}/2_ump.yml | 0 .../statemine/0_xcm}/3_hrmp-open-channels.yml | 0 .../assets/statemine/0_xcm}/4_hrmp.yml | 0 .../{ => e2e/assets}/statemine/config.toml | 0 .../assets/statemint/0_xcm}/0_init.yml | 0 .../assets/statemint/0_xcm}/1_dmp.yml | 0 .../assets/statemint/0_xcm}/2_ump.yml | 0 .../statemint/0_xcm}/3_hrmp-open-channels.yml | 0 .../assets/statemint/0_xcm}/4_hrmp.yml | 0 .../{ => e2e/assets}/statemint/config.toml | 0 .../collectives_polkadot}/0_xcm/0_init.yml | 0 .../0_xcm/1_teleport.yml | 0 .../collectives_polkadot}/0_xcm/2_reserve.yml | 0 .../1_alliance/0_join_alliance_fails.yml | 0 .../1_alliance/1_init_alliance.yml | 0 .../1_alliance/2_join_alliance_fails.yml | 0 .../1_alliance/3_kick_member.yml | 0 .../collectives_polkadot}/config.toml | 0 .../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 | 49 + .../emulated/common/src/constants.rs | 672 +++++++++++ .../emulated/common/src/lib.rs | 253 +++++ xcm/xcm-emulator/Cargo.toml | 7 + xcm/xcm-emulator/README.md | 11 +- xcm/xcm-emulator/example/Cargo.toml | 37 - xcm/xcm-emulator/example/src/lib.rs | 448 -------- .../example/test-runtime/Cargo.toml | 71 -- .../example/test-runtime/src/lib.rs | 278 ----- xcm/xcm-emulator/src/lib.rs | 1004 ++++++++++++----- 38 files changed, 2052 insertions(+), 1172 deletions(-) rename parachains/integration-tests/{statemine/xcm => e2e/assets/statemine/0_xcm}/0_init.yml (100%) rename parachains/integration-tests/{statemine/xcm => e2e/assets/statemine/0_xcm}/1_dmp.yml (100%) rename parachains/integration-tests/{statemine/xcm => e2e/assets/statemine/0_xcm}/2_ump.yml (100%) rename parachains/integration-tests/{statemine/xcm => e2e/assets/statemine/0_xcm}/3_hrmp-open-channels.yml (100%) rename parachains/integration-tests/{statemine/xcm => e2e/assets/statemine/0_xcm}/4_hrmp.yml (100%) rename parachains/integration-tests/{ => e2e/assets}/statemine/config.toml (100%) rename parachains/integration-tests/{statemint/xcm => e2e/assets/statemint/0_xcm}/0_init.yml (100%) rename parachains/integration-tests/{statemint/xcm => e2e/assets/statemint/0_xcm}/1_dmp.yml (100%) rename parachains/integration-tests/{statemint/xcm => e2e/assets/statemint/0_xcm}/2_ump.yml (100%) rename parachains/integration-tests/{statemint/xcm => e2e/assets/statemint/0_xcm}/3_hrmp-open-channels.yml (100%) rename parachains/integration-tests/{statemint/xcm => e2e/assets/statemint/0_xcm}/4_hrmp.yml (100%) rename parachains/integration-tests/{ => e2e/assets}/statemint/config.toml (100%) rename parachains/integration-tests/{collectives => e2e/collectives/collectives_polkadot}/0_xcm/0_init.yml (100%) rename parachains/integration-tests/{collectives => e2e/collectives/collectives_polkadot}/0_xcm/1_teleport.yml (100%) rename parachains/integration-tests/{collectives => e2e/collectives/collectives_polkadot}/0_xcm/2_reserve.yml (100%) 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 (100%) 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 (100%) rename parachains/integration-tests/{collectives => e2e/collectives/collectives_polkadot}/config.toml (100%) 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 xcm/xcm-emulator/example/Cargo.toml delete mode 100644 xcm/xcm-emulator/example/src/lib.rs delete mode 100644 xcm/xcm-emulator/example/test-runtime/Cargo.toml delete mode 100644 xcm/xcm-emulator/example/test-runtime/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 2ee029368c9..85c7b66afad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1334,6 +1334,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" @@ -4754,6 +4763,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" @@ -13301,6 +13351,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" @@ -13732,34 +13808,6 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13a4ec180a2de59b57434704ccfad967f789b12737738798fa08798cd5824c16" -[[package]] -name = "test-runtime" -version = "0.1.0" -dependencies = [ - "cumulus-pallet-dmp-queue", - "cumulus-pallet-parachain-system", - "cumulus-pallet-xcm", - "cumulus-pallet-xcmp-queue", - "cumulus-primitives-utility", - "frame-support", - "frame-system", - "pallet-balances", - "pallet-xcm", - "parachain-info", - "parity-scale-codec", - "polkadot-parachain", - "polkadot-runtime-parachains", - "scale-info", - "serde", - "sp-core", - "sp-io", - "sp-runtime", - "sp-std", - "xcm", - "xcm-builder", - "xcm-executor", -] - [[package]] name = "test-runtime-constants" version = "0.9.41" @@ -15856,52 +15904,34 @@ dependencies = [ 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-emulator-example" -version = "0.1.0" -dependencies = [ - "cumulus-pallet-xcmp-queue", - "cumulus-primitives-core", - "frame-support", - "frame-system", - "kusama-runtime", - "pallet-balances", - "pallet-xcm", - "parachain-info", - "parity-scale-codec", - "polkadot-parachain", - "polkadot-primitives", - "polkadot-runtime-parachains", - "proc-macro2", - "serde", - "sp-io", - "sp-runtime", - "test-runtime", - "xcm", - "xcm-emulator", -] - [[package]] name = "xcm-executor" version = "0.9.41" diff --git a/Cargo.toml b/Cargo.toml index e8476d04273..6ef1df49d48 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,14 +50,14 @@ members = [ "parachains/runtimes/collectives/collectives-polkadot", "parachains/runtimes/contracts/contracts-rococo", "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", - "xcm/xcm-emulator/example", - "xcm/xcm-emulator/example/test-runtime", ] [profile.release] @@ -68,4 +68,3 @@ opt-level = 3 inherits = "release" lto = true codegen-units = 1 - diff --git a/parachains/integration-tests/statemine/xcm/0_init.yml b/parachains/integration-tests/e2e/assets/statemine/0_xcm/0_init.yml similarity index 100% rename from parachains/integration-tests/statemine/xcm/0_init.yml rename to parachains/integration-tests/e2e/assets/statemine/0_xcm/0_init.yml diff --git a/parachains/integration-tests/statemine/xcm/1_dmp.yml b/parachains/integration-tests/e2e/assets/statemine/0_xcm/1_dmp.yml similarity index 100% rename from parachains/integration-tests/statemine/xcm/1_dmp.yml rename to parachains/integration-tests/e2e/assets/statemine/0_xcm/1_dmp.yml 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 100% rename from parachains/integration-tests/statemine/xcm/2_ump.yml rename to parachains/integration-tests/e2e/assets/statemine/0_xcm/2_ump.yml diff --git a/parachains/integration-tests/statemine/xcm/3_hrmp-open-channels.yml b/parachains/integration-tests/e2e/assets/statemine/0_xcm/3_hrmp-open-channels.yml similarity index 100% rename from parachains/integration-tests/statemine/xcm/3_hrmp-open-channels.yml rename to parachains/integration-tests/e2e/assets/statemine/0_xcm/3_hrmp-open-channels.yml diff --git a/parachains/integration-tests/statemine/xcm/4_hrmp.yml b/parachains/integration-tests/e2e/assets/statemine/0_xcm/4_hrmp.yml similarity index 100% rename from parachains/integration-tests/statemine/xcm/4_hrmp.yml rename to parachains/integration-tests/e2e/assets/statemine/0_xcm/4_hrmp.yml diff --git a/parachains/integration-tests/statemine/config.toml b/parachains/integration-tests/e2e/assets/statemine/config.toml similarity index 100% rename from parachains/integration-tests/statemine/config.toml rename to parachains/integration-tests/e2e/assets/statemine/config.toml diff --git a/parachains/integration-tests/statemint/xcm/0_init.yml b/parachains/integration-tests/e2e/assets/statemint/0_xcm/0_init.yml similarity index 100% rename from parachains/integration-tests/statemint/xcm/0_init.yml rename to parachains/integration-tests/e2e/assets/statemint/0_xcm/0_init.yml diff --git a/parachains/integration-tests/statemint/xcm/1_dmp.yml b/parachains/integration-tests/e2e/assets/statemint/0_xcm/1_dmp.yml similarity index 100% rename from parachains/integration-tests/statemint/xcm/1_dmp.yml rename to parachains/integration-tests/e2e/assets/statemint/0_xcm/1_dmp.yml 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 100% rename from parachains/integration-tests/statemint/xcm/2_ump.yml rename to parachains/integration-tests/e2e/assets/statemint/0_xcm/2_ump.yml diff --git a/parachains/integration-tests/statemint/xcm/3_hrmp-open-channels.yml b/parachains/integration-tests/e2e/assets/statemint/0_xcm/3_hrmp-open-channels.yml similarity index 100% rename from parachains/integration-tests/statemint/xcm/3_hrmp-open-channels.yml rename to parachains/integration-tests/e2e/assets/statemint/0_xcm/3_hrmp-open-channels.yml diff --git a/parachains/integration-tests/statemint/xcm/4_hrmp.yml b/parachains/integration-tests/e2e/assets/statemint/0_xcm/4_hrmp.yml similarity index 100% rename from parachains/integration-tests/statemint/xcm/4_hrmp.yml rename to parachains/integration-tests/e2e/assets/statemint/0_xcm/4_hrmp.yml diff --git a/parachains/integration-tests/statemint/config.toml b/parachains/integration-tests/e2e/assets/statemint/config.toml similarity index 100% rename from parachains/integration-tests/statemint/config.toml rename to parachains/integration-tests/e2e/assets/statemint/config.toml 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 100% 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 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 100% 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 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 100% 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 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 100% 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 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 100% 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 diff --git a/parachains/integration-tests/collectives/config.toml b/parachains/integration-tests/e2e/collectives/collectives_polkadot/config.toml similarity index 100% rename from parachains/integration-tests/collectives/config.toml rename to parachains/integration-tests/e2e/collectives/collectives_polkadot/config.toml 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..8ea8c1d0f8a --- /dev/null +++ b/parachains/integration-tests/emulated/common/Cargo.toml @@ -0,0 +1,49 @@ +[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" } 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/xcm/xcm-emulator/Cargo.toml b/xcm/xcm-emulator/Cargo.toml index 819de0199c8..8da28d0283f 100644 --- a/xcm/xcm-emulator/Cargo.toml +++ b/xcm/xcm-emulator/Cargo.toml @@ -9,20 +9,27 @@ edition = "2021" 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" } diff --git a/xcm/xcm-emulator/README.md b/xcm/xcm-emulator/README.md index 384a781fab4..267258d758b 100644 --- a/xcm/xcm-emulator/README.md +++ b/xcm/xcm-emulator/README.md @@ -9,8 +9,9 @@ a zombienet and as all the chains are in one process debugging using Clion is ea ## Limitations -As the channels are mocked, using xcm-emulator tests to test -channel setup would not be appropriate. +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 @@ -20,7 +21,7 @@ repo) is the perfect tool for this. ## How to use -1. Set up a relay chain: + diff --git a/xcm/xcm-emulator/example/Cargo.toml b/xcm/xcm-emulator/example/Cargo.toml deleted file mode 100644 index e5bacd89909..00000000000 --- a/xcm/xcm-emulator/example/Cargo.toml +++ /dev/null @@ -1,37 +0,0 @@ -[package] -name = "xcm-emulator-example" -version = "0.1.0" -authors = ["Parity Technologies "] -edition = "2021" - -[dependencies] -serde = { version = "1.0.137", optional = true } -codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false } -proc-macro2 = "1.0.40" - -frame-system = { git = "https://github.com/paritytech/substrate", branch = "master" } -frame-support = { git = "https://github.com/paritytech/substrate", branch = "master" } -pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master" } -sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" } -sp-io = { git = "https://github.com/paritytech/substrate", branch = "master" } - -cumulus-primitives-core = { path = "../../../primitives/core" } -cumulus-pallet-xcmp-queue = { path = "../../../pallets/xcmp-queue" } -parachain-info = { path = "../../../parachains/pallets/parachain-info" } - -xcm = { git = "https://github.com/paritytech/polkadot", branch = "master" } -polkadot-primitives = { git = "https://github.com/paritytech/polkadot", branch = "master" } -polkadot-parachain = { git = "https://github.com/paritytech/polkadot", branch = "master" } -polkadot-runtime-parachains = { git = "https://github.com/paritytech/polkadot", branch = "master" } -kusama-runtime = { git = "https://github.com/paritytech/polkadot", branch = "master" } -pallet-xcm = { git = "https://github.com/paritytech/polkadot", branch = "master" } - - -xcm-emulator = { path = ".." } -test-runtime = { path = "test-runtime" } - -[features] -runtime-benchmarks = [ - "kusama-runtime/runtime-benchmarks", - "test-runtime/runtime-benchmarks", -] diff --git a/xcm/xcm-emulator/example/src/lib.rs b/xcm/xcm-emulator/example/src/lib.rs deleted file mode 100644 index e8626db930c..00000000000 --- a/xcm/xcm-emulator/example/src/lib.rs +++ /dev/null @@ -1,448 +0,0 @@ -// 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 . - -use frame_support::{pallet_prelude::Weight, traits::GenesisBuild}; -use sp_runtime::AccountId32; - -use xcm_emulator::{decl_test_network, decl_test_parachain, decl_test_relay_chain}; - -// Set up relay chain. -decl_test_relay_chain! { - pub struct KusamaRelay { - Runtime = kusama_runtime::Runtime, - XcmConfig = kusama_runtime::xcm_config::XcmConfig, - new_ext = kusama_ext(), - } -} - -// Set up ParachainA. -decl_test_parachain! { - pub struct ParachainA { - Runtime = test_runtime::Runtime, - RuntimeOrigin = test_runtime::RuntimeOrigin, - XcmpMessageHandler = test_runtime::XcmpQueue, - DmpMessageHandler = test_runtime::DmpQueue, - new_ext = parachain_ext(1), - } -} - -// Set up ParachainB. -decl_test_parachain! { - pub struct ParachainB { - Runtime = test_runtime::Runtime, - RuntimeOrigin = test_runtime::RuntimeOrigin, - XcmpMessageHandler = test_runtime::XcmpQueue, - DmpMessageHandler = test_runtime::DmpQueue, - new_ext = parachain_ext(2), - } -} - -// Set up ParachainC. -decl_test_parachain! { - pub struct ParachainC { - Runtime = test_runtime::Runtime, - RuntimeOrigin = test_runtime::RuntimeOrigin, - XcmpMessageHandler = test_runtime::XcmpQueue, - DmpMessageHandler = test_runtime::DmpQueue, - new_ext = parachain_ext(3), - } -} - -// Set up a network with all the declared parachains and a relay chain. -decl_test_network! { - pub struct Network { - relay_chain = KusamaRelay, - parachains = vec![ - (1, ParachainA), - (2, ParachainB), - (3, ParachainC), - ], - } -} - -pub const ALICE: AccountId32 = AccountId32::new([0u8; 32]); -pub const INITIAL_BALANCE: u128 = 1_000_000_000_000; - -// Parachain TextExternalities setup. -pub fn parachain_ext(para_id: u32) -> sp_io::TestExternalities { - use test_runtime::{Runtime, System}; - - let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); - - let parachain_info_config = parachain_info::GenesisConfig { parachain_id: para_id.into() }; - - >::assimilate_storage( - ¶chain_info_config, - &mut t, - ) - .unwrap(); - - pallet_balances::GenesisConfig:: { balances: vec![(ALICE, INITIAL_BALANCE)] } - .assimilate_storage(&mut t) - .unwrap(); - - let mut ext = sp_io::TestExternalities::new(t); - ext.execute_with(|| System::set_block_number(1)); - ext -} - -fn default_parachains_host_configuration( -) -> polkadot_runtime_parachains::configuration::HostConfiguration< - polkadot_primitives::v4::BlockNumber, -> { - use polkadot_primitives::v4::{MAX_CODE_SIZE, MAX_POV_SIZE}; - - polkadot_runtime_parachains::configuration::HostConfiguration { - minimum_validation_upgrade_delay: 5, - validation_upgrade_cooldown: 10u32, - validation_upgrade_delay: 10, - code_retention_period: 1200, - max_code_size: MAX_CODE_SIZE, - max_pov_size: MAX_POV_SIZE, - max_head_data_size: 32 * 1024, - group_rotation_frequency: 20, - chain_availability_period: 4, - thread_availability_period: 4, - max_upward_queue_count: 8, - max_upward_queue_size: 1024 * 1024, - max_downward_message_size: 1024, - ump_service_total_weight: Weight::from_parts(4 * 1_000_000_000, 0), - max_upward_message_size: 50 * 1024, - max_upward_message_num_per_candidate: 5, - hrmp_sender_deposit: 0, - hrmp_recipient_deposit: 0, - hrmp_channel_max_capacity: 8, - hrmp_channel_max_total_size: 8 * 1024, - hrmp_max_parachain_inbound_channels: 4, - hrmp_max_parathread_inbound_channels: 4, - hrmp_channel_max_message_size: 1024 * 1024, - hrmp_max_parachain_outbound_channels: 4, - hrmp_max_parathread_outbound_channels: 4, - hrmp_max_message_num_per_candidate: 5, - dispute_period: 6, - no_show_slots: 2, - n_delay_tranches: 25, - needed_approvals: 2, - relay_vrf_modulo_samples: 2, - zeroth_delay_tranche_width: 0, - ..Default::default() - } -} - -// Relay chain TestExternalities setup. -pub fn kusama_ext() -> sp_io::TestExternalities { - use kusama_runtime::{Runtime, System}; - - let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); - - pallet_balances::GenesisConfig:: { balances: vec![(ALICE, INITIAL_BALANCE)] } - .assimilate_storage(&mut t) - .unwrap(); - - polkadot_runtime_parachains::configuration::GenesisConfig:: { - config: default_parachains_host_configuration(), - } - .assimilate_storage(&mut t) - .unwrap(); - - let mut ext = sp_io::TestExternalities::new(t); - ext.execute_with(|| System::set_block_number(1)); - ext -} - -#[cfg(test)] -mod tests { - use super::*; - use codec::Encode; - - use cumulus_primitives_core::ParaId; - use frame_support::{assert_ok, dispatch::GetDispatchInfo, traits::Currency}; - use sp_runtime::traits::AccountIdConversion; - use xcm::{latest::Error::BadOrigin, v3::prelude::*, VersionedMultiLocation, VersionedXcm}; - use xcm_emulator::TestExt; - - #[test] - fn dmp() { - Network::reset(); - - let remark = test_runtime::RuntimeCall::System( - frame_system::Call::::remark_with_event { - remark: "Hello from Kusama!".as_bytes().to_vec(), - }, - ); - KusamaRelay::execute_with(|| { - assert_ok!(kusama_runtime::XcmPallet::force_default_xcm_version( - kusama_runtime::RuntimeOrigin::root(), - Some(3) - )); - assert_ok!(kusama_runtime::XcmPallet::send_xcm( - Here, - Parachain(1), - Xcm(vec![Transact { - origin_kind: OriginKind::SovereignAccount, - require_weight_at_most: Weight::from_parts(INITIAL_BALANCE as u64, 1024 * 1024), - call: remark.encode().into(), - }]), - )); - }); - - ParachainA::execute_with(|| { - use test_runtime::{RuntimeEvent, System}; - System::events().iter().for_each(|r| println!(">>> {:?}", r.event)); - - assert!(System::events().iter().any(|r| matches!( - r.event, - RuntimeEvent::System(frame_system::Event::Remarked { sender: _, hash: _ }) - ))); - }); - } - - #[test] - fn ump() { - Network::reset(); - - KusamaRelay::execute_with(|| { - assert_ok!(kusama_runtime::XcmPallet::force_default_xcm_version( - kusama_runtime::RuntimeOrigin::root(), - Some(3) - )); - let _ = kusama_runtime::Balances::deposit_creating( - &ParaId::from(1).into_account_truncating(), - 1_000_000_000_000, - ); - }); - - let remark = kusama_runtime::RuntimeCall::System(frame_system::Call::< - kusama_runtime::Runtime, - >::remark_with_event { - remark: "Hello from ParachainA!".as_bytes().to_vec(), - }); - ParachainA::execute_with(|| { - assert_ok!(test_runtime::PolkadotXcm::force_default_xcm_version( - test_runtime::RuntimeOrigin::root(), - Some(3) - )); - assert_ok!(test_runtime::PolkadotXcm::send_xcm( - Here, - Parent, - Xcm(vec![ - UnpaidExecution { weight_limit: Unlimited, check_origin: None }, - Transact { - origin_kind: OriginKind::SovereignAccount, - require_weight_at_most: Weight::from_parts( - INITIAL_BALANCE as u64, - 1024 * 1024 - ), - call: remark.encode().into(), - } - ]), - )); - }); - - KusamaRelay::execute_with(|| { - use kusama_runtime::{RuntimeEvent, System}; - // TODO: https://github.com/paritytech/polkadot/pull/6824 or change this call to - // force_create_assets like we do in cumulus integration tests. - // assert!(System::events().iter().any(|r| matches!( - // r.event, - // RuntimeEvent::System(frame_system::Event::Remarked { sender: _, hash: _ }) - // ))); - assert!(System::events().iter().any(|r| matches!( - r.event, - RuntimeEvent::Ump(polkadot_runtime_parachains::ump::Event::ExecutedUpward( - _, - Outcome::Incomplete(_, XcmError::NoPermission) - )) - ))); - }); - } - - #[test] - fn para_to_para() { - Network::reset(); - - let remark = test_runtime::RuntimeCall::System( - frame_system::Call::::remark_with_event { - remark: "Hello from ParachainA!".as_bytes().to_vec(), - }, - ); - ParachainA::execute_with(|| { - assert_ok!(test_runtime::PolkadotXcm::send_xcm( - Here, - MultiLocation::new(1, X1(Parachain(2))), - Xcm(vec![Transact { - origin_kind: OriginKind::SovereignAccount, - require_weight_at_most: Weight::from_parts(9_000_000, 0), - call: remark.encode().into(), - }]), - )); - }); - - ParachainB::execute_with(|| { - use test_runtime::{RuntimeEvent, System}; - System::events().iter().for_each(|r| println!(">>> {:?}", r.event)); - - assert!(System::events().iter().any(|r| matches!( - r.event, - RuntimeEvent::System(frame_system::Event::Remarked { sender: _, hash: _ }) - ))); - }); - } - - #[test] - fn xcmp_through_a_parachain() { - use test_runtime::{PolkadotXcm, Runtime, RuntimeCall}; - - Network::reset(); - - // The message goes through: ParachainA --> ParachainB --> ParachainC - let remark = RuntimeCall::System(frame_system::Call::::remark_with_event { - remark: "Hello from ParachainA!".as_bytes().to_vec(), - }); - let send_xcm_to_parachain_c = RuntimeCall::PolkadotXcm(pallet_xcm::Call::::send { - dest: Box::new(VersionedMultiLocation::V3(MultiLocation::new(1, X1(Parachain(3))))), - message: Box::new(VersionedXcm::V3(Xcm(vec![Transact { - origin_kind: OriginKind::SovereignAccount, - // The weight here does not matter, as this is going to fail with BadOrigin once it - // reaches ParachainC, as it's not going to satisfy AccountId32Aliases conversion - // rules. - require_weight_at_most: Weight::from_parts(0, 0), - call: remark.encode().into(), - }]))), - }); - assert_eq!( - send_xcm_to_parachain_c.get_dispatch_info().weight, - Weight::from_parts(100000010, 10) - ); - ParachainA::execute_with(|| { - assert_ok!(PolkadotXcm::send_xcm( - Here, - MultiLocation::new(1, X1(Parachain(2))), - Xcm(vec![Transact { - origin_kind: OriginKind::SovereignAccount, - require_weight_at_most: Weight::from_parts(110_000_010, 20_000), - call: send_xcm_to_parachain_c.encode().into(), - }]), - )); - }); - - ParachainB::execute_with(|| { - use test_runtime::{RuntimeEvent, System}; - System::events().iter().for_each(|r| println!(">>> {:?}", r.event)); - - assert!(System::events().iter().any(|r| matches!( - r.event, - RuntimeEvent::PolkadotXcm(pallet_xcm::Event::Sent(_, _, _)) - ))); - }); - - // ParachainC: The origin should not satisfy AccountId32Aliases conversion rules and thus fail. - ParachainC::execute_with(|| { - use test_runtime::{RuntimeEvent, System}; - System::events().iter().for_each(|r| println!(">>> {:?}", r.event)); - - assert!(System::events().iter().any(|r| matches!( - r.event, - RuntimeEvent::XcmpQueue(cumulus_pallet_xcmp_queue::Event::Fail { error, .. }) if error == BadOrigin - ))); - }); - } - - #[test] - fn deduplicate_dmp() { - Network::reset(); - KusamaRelay::execute_with(|| { - assert_ok!(kusama_runtime::XcmPallet::force_default_xcm_version( - kusama_runtime::RuntimeOrigin::root(), - Some(3) - )); - }); - - send_remark_with_event_to_child_parachain_a("Kusama", 2); - parachain_a_verify_remark_event_and_reset_all_events(true); - - // a different dmp message in same relay-parent-block allow execution. - send_remark_with_event_to_child_parachain_a("Polkadot", 1); - parachain_a_verify_remark_event_and_reset_all_events(true); - - // same dmp message with same relay-parent-block wouldn't execution - send_remark_with_event_to_child_parachain_a("Kusama", 1); - parachain_a_verify_remark_event_and_reset_all_events(false); - - // different relay-parent-block allow dmp message execution - KusamaRelay::execute_with(|| kusama_runtime::System::set_block_number(2)); - - send_remark_with_event_to_child_parachain_a("Kusama", 1); - parachain_a_verify_remark_event_and_reset_all_events(true); - - // reset can send same dmp message again - Network::reset(); - KusamaRelay::execute_with(|| { - assert_ok!(kusama_runtime::XcmPallet::force_default_xcm_version( - kusama_runtime::RuntimeOrigin::root(), - Some(3) - )); - }); - - send_remark_with_event_to_child_parachain_a("Kusama", 1); - parachain_a_verify_remark_event_and_reset_all_events(true); - } - - fn send_remark_with_event_to_child_parachain_a(msg: &str, count: u32) { - let remark = test_runtime::RuntimeCall::System( - frame_system::Call::::remark_with_event { - remark: msg.as_bytes().to_vec(), - }, - ); - KusamaRelay::execute_with(|| { - for _ in 0..count { - assert_ok!(kusama_runtime::XcmPallet::send_xcm( - Here, - Parachain(1), - Xcm(vec![Transact { - origin_kind: OriginKind::SovereignAccount, - require_weight_at_most: Weight::from_parts( - INITIAL_BALANCE as u64, - 1024 * 1024 - ), - call: remark.encode().into(), - }]), - )); - } - }); - } - - fn parachain_a_verify_remark_event_and_reset_all_events(received: bool) { - ParachainA::execute_with(|| { - use test_runtime::{RuntimeEvent, System}; - System::events().iter().for_each(|r| println!(">>> {:?}", r.event)); - - if received { - assert!(System::events().iter().any(|r| matches!( - r.event, - RuntimeEvent::System(frame_system::Event::Remarked { sender: _, hash: _ }) - ))); - - System::reset_events(); - } else { - assert!(System::events().iter().all(|r| !matches!( - r.event, - RuntimeEvent::System(frame_system::Event::Remarked { sender: _, hash: _ }) - ))); - } - }); - } -} diff --git a/xcm/xcm-emulator/example/test-runtime/Cargo.toml b/xcm/xcm-emulator/example/test-runtime/Cargo.toml deleted file mode 100644 index 945d9e54751..00000000000 --- a/xcm/xcm-emulator/example/test-runtime/Cargo.toml +++ /dev/null @@ -1,71 +0,0 @@ -[package] -name = "test-runtime" -description = "A simple runtime for cross-chain message tests." -license = "Apache-2.0" -version = "0.1.0" -authors = ["Parity Technologies "] -edition = "2021" - -[dependencies] -serde = { version = "1.0.137", optional = true } -codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false } -scale-info = { version = "2.1", default-features = false, features = ["derive"] } - -sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } -sp-io = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } -sp-std = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } -sp-core = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } -pallet-balances = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } -frame-support = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } -frame-system = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "master" } - -cumulus-pallet-dmp-queue = { path = "../../../../pallets/dmp-queue", default-features = false } -cumulus-pallet-xcmp-queue = { path = "../../../../pallets/xcmp-queue", default-features = false } -parachain-info = { path = "../../../../parachains/pallets/parachain-info", default-features = false } -cumulus-pallet-xcm = { path = "../../../../pallets/xcm", default-features = false } -cumulus-pallet-parachain-system = { path = "../../../../pallets/parachain-system", default-features = false } -cumulus-primitives-utility = { path = "../../../../primitives/utility", default-features = false } - -xcm = { git = "https://github.com/paritytech/polkadot", branch = "master" } -xcm-executor = { git = "https://github.com/paritytech/polkadot", branch = "master" } -polkadot-parachain = { git = "https://github.com/paritytech/polkadot", branch = "master" } -xcm-builder = { git = "https://github.com/paritytech/polkadot", branch = "master" } -pallet-xcm = { git = "https://github.com/paritytech/polkadot", branch = "master" } -polkadot-runtime-parachains = { git = "https://github.com/paritytech/polkadot", branch = "master" } - - -[features] -default = ["std"] -no_std = [] -std = [ - "serde/std", - "codec/std", - "scale-info/std", - - "sp-runtime/std", - "sp-io/std", - "sp-std/std", - "sp-core/std", - "pallet-balances/std", - "frame-support/std", - "frame-system/std", - - "cumulus-pallet-dmp-queue/std", - "cumulus-pallet-xcmp-queue/std", - "cumulus-pallet-xcm/std", - "cumulus-pallet-parachain-system/std", - "parachain-info/std", - "cumulus-primitives-utility/std", - - "xcm/std", - "xcm-executor/std", - "polkadot-parachain/std", - "xcm-builder/std", - "pallet-xcm/std", - "polkadot-runtime-parachains/std", -] - -runtime-benchmarks = [ - "pallet-xcm/runtime-benchmarks", - "xcm-builder/runtime-benchmarks", -] diff --git a/xcm/xcm-emulator/example/test-runtime/src/lib.rs b/xcm/xcm-emulator/example/test-runtime/src/lib.rs deleted file mode 100644 index 9010936892c..00000000000 --- a/xcm/xcm-emulator/example/test-runtime/src/lib.rs +++ /dev/null @@ -1,278 +0,0 @@ -// 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 . - -use frame_support::{ - construct_runtime, parameter_types, - traits::{ConstU32, Everything, Nothing}, - weights::{constants::WEIGHT_REF_TIME_PER_SECOND, Weight}, -}; -use frame_system::EnsureRoot; -use pallet_xcm::XcmPassthrough; -use polkadot_parachain::primitives::Sibling; -use sp_core::H256; -use sp_runtime::{ - testing::Header, - traits::{Convert, IdentityLookup}, - AccountId32, -}; -use xcm::v3::prelude::*; -use xcm_builder::{ - AccountId32Aliases, AllowUnpaidExecutionFrom, CurrencyAdapter, EnsureXcmOrigin, - FixedWeightBounds, IsConcrete, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, - SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32, - SovereignSignedViaLocation, -}; - -use xcm_executor::{Config, XcmExecutor}; - -pub type AccountId = AccountId32; -pub type Balance = u128; -pub type Amount = i128; - -parameter_types! { - pub const BlockHashCount: u64 = 250; -} - -impl frame_system::Config for Runtime { - type RuntimeOrigin = RuntimeOrigin; - type RuntimeCall = RuntimeCall; - type Index = u64; - type BlockNumber = u64; - type Hash = H256; - type Hashing = ::sp_runtime::traits::BlakeTwo256; - type AccountId = AccountId; - type Lookup = IdentityLookup; - type Header = Header; - type RuntimeEvent = RuntimeEvent; - type BlockHashCount = BlockHashCount; - type BlockWeights = (); - type BlockLength = (); - type Version = (); - type PalletInfo = PalletInfo; - type AccountData = pallet_balances::AccountData; - type OnNewAccount = (); - type OnKilledAccount = (); - type DbWeight = (); - type BaseCallFilter = Everything; - type SystemWeightInfo = (); - type SS58Prefix = (); - type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; - type MaxConsumers = ConstU32<16>; -} - -parameter_types! { - pub ExistentialDeposit: Balance = 1; - pub const MaxLocks: u32 = 50; - pub const MaxReserves: u32 = 50; -} - -impl pallet_balances::Config for Runtime { - type MaxLocks = MaxLocks; - type Balance = Balance; - type RuntimeEvent = RuntimeEvent; - type DustRemoval = (); - type ExistentialDeposit = ExistentialDeposit; - type AccountStore = System; - type WeightInfo = (); - type MaxReserves = MaxReserves; - type ReserveIdentifier = [u8; 8]; - type HoldIdentifier = (); - type FreezeIdentifier = (); - type MaxHolds = (); - type MaxFreezes = (); -} - -impl parachain_info::Config for Runtime {} - -parameter_types! { - pub const RelayLocation: MultiLocation = MultiLocation::parent(); - pub const RelayNetwork: NetworkId = NetworkId::Kusama; - pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = X2(GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into())); -} - -pub type LocationToAccountId = ( - ParentIsPreset, - SiblingParachainConvertsVia, - AccountId32Aliases, -); - -pub type XcmOriginToCallOrigin = ( - SovereignSignedViaLocation, - RelayChainAsNative, - SiblingParachainAsNative, - SignedAccountId32AsNative, - XcmPassthrough, -); - -parameter_types! { - pub const UnitWeightCost: u64 = 10; - pub const MaxInstructions: u32 = 100; - pub const MaxAssetsIntoHolding: u32 = 64; - pub const RelayChain: MultiLocation = MultiLocation::parent(); -} - -/// Means for transacting assets on this chain. -pub type LocalAssetTransactor = CurrencyAdapter< - // Use this currency: - Balances, - // Use this currency when it is a fungible asset matching the given location or name: - IsConcrete, - // Do a simple punn to convert an AccountId32 MultiLocation into a native chain account ID: - LocationToAccountId, - // Our chain's account ID type (we can't get away without mentioning it explicitly): - AccountId, - // We don't track any teleports. - (), ->; - -/// The means for routing XCM messages which are not for local execution into -/// the right message queues. -pub type XcmRouter = ( - // Two routers - use UMP to communicate with the relay chain: - cumulus_primitives_utility::ParentAsUmp, - // ..and XCMP to communicate with the sibling chains. - XcmpQueue, -); - -pub type Barrier = AllowUnpaidExecutionFrom; - -pub struct XcmConfig; -impl Config for XcmConfig { - type RuntimeCall = RuntimeCall; - type XcmSender = XcmRouter; - type AssetTransactor = LocalAssetTransactor; - type OriginConverter = XcmOriginToCallOrigin; - type IsReserve = (); - type IsTeleporter = (); - type UniversalLocation = UniversalLocation; - type Barrier = Barrier; - type Weigher = FixedWeightBounds; - type Trader = (); - type ResponseHandler = (); - type AssetTrap = (); - type AssetClaims = (); - type SubscriptionService = (); - type AssetLocker = PolkadotXcm; - type AssetExchanger = (); - type PalletInstancesInfo = (); - type MaxAssetsIntoHolding = MaxAssetsIntoHolding; - type FeeManager = (); - type MessageExporter = (); - type UniversalAliases = Nothing; - type CallDispatcher = RuntimeCall; - type SafeCallFilter = Everything; -} - -parameter_types! { - pub const ReservedXcmpWeight: Weight = Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_div(4), 0); - pub const ReservedDmpWeight: Weight = Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_div(4), 0); -} - -impl cumulus_pallet_parachain_system::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type OnSystemEvent = (); - type SelfParaId = ParachainInfo; - type DmpMessageHandler = DmpQueue; - type ReservedDmpWeight = ReservedDmpWeight; - type OutboundXcmpMessageSource = XcmpQueue; - type XcmpMessageHandler = XcmpQueue; - type ReservedXcmpWeight = ReservedXcmpWeight; - type CheckAssociatedRelayNumber = cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; -} - -impl cumulus_pallet_xcmp_queue::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type XcmExecutor = XcmExecutor; - type ChannelInfo = ParachainSystem; - type VersionWrapper = (); - type ExecuteOverweightOrigin = EnsureRoot; - type ControllerOrigin = EnsureRoot; - type ControllerOriginConverter = XcmOriginToCallOrigin; - type WeightInfo = (); - type PriceForSiblingDelivery = (); -} - -impl cumulus_pallet_dmp_queue::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type XcmExecutor = XcmExecutor; - type ExecuteOverweightOrigin = EnsureRoot; -} - -impl cumulus_pallet_xcm::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type XcmExecutor = XcmExecutor; -} - -#[cfg(feature = "runtime-benchmarks")] -parameter_types! { - pub ReachableDest: Option = Some(Parent.into()); -} - -pub type LocalOriginToLocation = SignedToAccountId32; - -impl pallet_xcm::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type SendXcmOrigin = EnsureXcmOrigin; - type XcmRouter = XcmRouter; - type ExecuteXcmOrigin = EnsureXcmOrigin; - type XcmExecuteFilter = Everything; - type XcmExecutor = XcmExecutor; - type XcmTeleportFilter = Nothing; - type XcmReserveTransferFilter = Everything; - type Weigher = FixedWeightBounds; - type UniversalLocation = UniversalLocation; - type RuntimeOrigin = RuntimeOrigin; - type RuntimeCall = RuntimeCall; - const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; - type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; - type Currency = Balances; - type CurrencyMatcher = (); - type TrustedLockers = (); - type SovereignAccountOf = (); - type MaxLockers = ConstU32<8>; - type WeightInfo = pallet_xcm::TestWeightInfo; - type AdminOrigin = EnsureRoot; - #[cfg(feature = "runtime-benchmarks")] - type ReachableDest = ReachableDest; -} - -pub struct AccountIdToMultiLocation; -impl Convert for AccountIdToMultiLocation { - fn convert(account: AccountId) -> MultiLocation { - X1(Junction::AccountId32 { network: None, id: account.into() }).into() - } -} - -type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; -type Block = frame_system::mocking::MockBlock; - -construct_runtime!( - pub enum Runtime where - Block = Block, - NodeBlock = Block, - UncheckedExtrinsic = UncheckedExtrinsic, - { - System: frame_system::{Pallet, Call, Storage, Config, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - ParachainSystem: cumulus_pallet_parachain_system::{Pallet, Call, Storage, Inherent, Config, Event}, - ParachainInfo: parachain_info::{Pallet, Storage, Config}, - XcmpQueue: cumulus_pallet_xcmp_queue::{Pallet, Call, Storage, Event}, - DmpQueue: cumulus_pallet_dmp_queue::{Pallet, Call, Storage, Event}, - CumulusXcm: cumulus_pallet_xcm::{Pallet, Event, Origin}, - PolkadotXcm: pallet_xcm::{Pallet, Call, Event, Origin}, - } -); diff --git a/xcm/xcm-emulator/src/lib.rs b/xcm/xcm-emulator/src/lib.rs index a8bebd6fb02..ad9cb2873f4 100644 --- a/xcm/xcm-emulator/src/lib.rs +++ b/xcm/xcm-emulator/src/lib.rs @@ -14,17 +14,22 @@ // 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 paste; - pub use frame_support::{ + sp_runtime::BuildStorage, traits::{Get, Hooks}, weights::Weight, }; -pub use frame_system; +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; @@ -35,91 +40,230 @@ pub use cumulus_primitives_core::{ }; 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; } -#[macro_export] -macro_rules! decl_test_relay_chain { - ( - pub struct $name:ident { - Runtime = $runtime:path, - XcmConfig = $xcm_config:path, - new_ext = $new_ext:expr, - } - ) => { - pub struct $name; +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; +} - $crate::__impl_ext_for_relay_chain!($name, $runtime, $new_ext); +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(); + } +} - 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}; +pub trait RelayChain: UmpSink { + type Runtime; + type RuntimeOrigin; + type RuntimeCall; + type RuntimeEvent; + type XcmConfig; + type SovereignAccountOf; + type System; + type Balances; +} - Self::execute_with(|| { - $crate::XcmSink::<$crate::XcmExecutor<$xcm_config>, $runtime>::process_upward_message(origin, msg, max_weight) - }) - } - } - }; +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_parachain { +macro_rules! decl_test_relay_chains { ( - pub struct $name:ident { - Runtime = $runtime:path, - RuntimeOrigin = $origin:path, - XcmpMessageHandler = $xcmp_message_handler:path, - DmpMessageHandler = $dmp_message_handler:path, - new_ext = $new_ext:expr, - } + $( + 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; - - $crate::__impl_ext_for_parachain!($name, $runtime, $origin, $new_ext); + $( + 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)::*; + } - impl $crate::XcmpMessageHandler for $name { - fn handle_xcmp_messages< - 'a, - I: Iterator, - >( - iter: I, - max_weight: $crate::Weight, - ) -> $crate::Weight { - use $crate::{TestExt, XcmpMessageHandler}; + $crate::paste::paste! { + pub trait [<$name Pallet>] { + $( + type $pallet_name; + )? + } - $name::execute_with(|| { - <$xcmp_message_handler>::handle_xcmp_messages(iter, max_weight) - }) + impl [<$name Pallet>] for $name { + $( + type $pallet_name = $pallet_path; + )? + } } - } - impl $crate::DmpMessageHandler for $name { - fn handle_dmp_messages( - iter: impl Iterator)>, + $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, - ) -> $crate::Weight { - use $crate::{DmpMessageHandler, TestExt}; + ) -> Result<$crate::Weight, ($crate::MessageId, $crate::Weight)> { + use $crate::{TestExt, UmpSink}; - $name::execute_with(|| { - <$dmp_message_handler>::handle_dmp_messages(iter, max_weight) + Self::execute_with(|| { + $crate::XcmSink::< + $crate::XcmExecutor<::XcmConfig>, + ::Runtime, + >::process_upward_message(origin, msg, max_weight) }) } } @@ -127,30 +271,44 @@ macro_rules! decl_test_parachain { } #[macro_export] -macro_rules! __impl_ext_for_relay_chain { +macro_rules! __impl_test_ext_for_relay_chain { // entry point: generate ext name - ($name:ident, $runtime:path, $new_ext:expr) => { + ($name:ident, $genesis:expr, $on_init:expr) => { $crate::paste::paste! { - $crate::__impl_ext_for_relay_chain!(@impl $name, $runtime, $new_ext, []); + $crate::__impl_test_ext_for_relay_chain!(@impl $name, $genesis, $on_init, []); } }; // impl - (@impl $name:ident, $runtime:path, $new_ext:expr, $ext_name:ident) => { + (@impl $name:ident, $genesis:expr, $on_init:expr, $ext_name:ident) => { thread_local! { pub static $ext_name: $crate::RefCell<$crate::TestExternalities> - = $crate::RefCell::new($new_ext); + = $crate::RefCell::new(<$name>::build_new_ext($genesis)); } - impl $crate::TestExt for $name { + impl TestExt for $name { + fn build_new_ext(storage: $crate::Storage) -> $crate::TestExternalities { + let mut ext = sp_io::TestExternalities::new(storage); + ext.execute_with(|| { + $on_init; + sp_tracing::try_init_simple(); + ::System::set_block_number(1); + }); + ext + } + fn new_ext() -> $crate::TestExternalities { - $new_ext + <$name>::build_new_ext($genesis) } fn reset_ext() { - $ext_name.with(|v| *v.borrow_mut() = $new_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 @@ -159,15 +317,15 @@ macro_rules! __impl_ext_for_relay_chain { use $crate::polkadot_primitives::runtime_api::runtime_decl_for_parachain_host::ParachainHostV4; //TODO: mark sent count & filter out sent msg - for para_id in _para_ids() { + for para_id in <$name>::para_ids() { // downward messages - let downward_messages = <$runtime>::dmq_contents(para_id.into()) + let downward_messages = ::Runtime::dmq_contents(para_id.into()) .into_iter() .map(|inbound| (inbound.sent_at, inbound.msg)); if downward_messages.len() == 0 { continue; } - _Messenger::send_downward_messages(para_id, downward_messages.into_iter()); + <$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). @@ -175,80 +333,227 @@ macro_rules! __impl_ext_for_relay_chain { }) }); - _process_messages(); + <$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_ext_for_parachain { +macro_rules! __impl_test_ext_for_parachain { // entry point: generate ext name - ($name:ident, $runtime:path, $origin:path, $new_ext:expr) => { + ($name:ident, $genesis:expr, $on_init:expr) => { $crate::paste::paste! { - $crate::__impl_ext_for_parachain!(@impl $name, $runtime, $origin, $new_ext, []); + $crate::__impl_test_ext_for_parachain!(@impl $name, $genesis, $on_init, []); } }; // impl - (@impl $name:ident, $runtime:path, $origin:path, $new_ext:expr, $ext_name:ident) => { + (@impl $name:ident, $genesis:expr, $on_init:expr, $ext_name:ident) => { thread_local! { pub static $ext_name: $crate::RefCell<$crate::TestExternalities> - = $crate::RefCell::new($new_ext); + = $crate::RefCell::new(<$name>::build_new_ext($genesis)); } - impl $name { - fn prepare_for_xcmp() { - $ext_name.with(|v| { - v.borrow_mut().execute_with(|| { - use $crate::{Get, Hooks}; - type ParachainSystem = $crate::cumulus_pallet_parachain_system::Pallet<$runtime>; - - let block_number = $crate::frame_system::Pallet::<$runtime>::block_number(); - let para_id = $crate::parachain_info::Pallet::<$runtime>::get(); - - let _ = ParachainSystem::set_validation_data( - <$origin>::none(), - _hrmp_channel_parachain_inherent_data(para_id.into(), 1), - ); - // set `AnnouncedHrmpMessagesPerCandidate` - ParachainSystem::on_initialize(block_number); - }) + impl TestExt for $name { + fn build_new_ext(storage: $crate::Storage) -> $crate::TestExternalities { + let mut ext = sp_io::TestExternalities::new(storage); + ext.execute_with(|| { + $on_init; + sp_tracing::try_init_simple(); + ::System::set_block_number(1); }); + ext } - } - impl $crate::TestExt for $name { fn new_ext() -> $crate::TestExternalities { - $new_ext + <$name>::build_new_ext($genesis) } fn reset_ext() { - $ext_name.with(|v| *v.borrow_mut() = $new_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}; - type ParachainSystem = $crate::cumulus_pallet_parachain_system::Pallet<$runtime>; + use $crate::{Get, Hooks, NetworkComponent}; - $crate::GLOBAL_RELAY.with(|v| { - *v.borrow_mut() += 1; - }); + // 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(|| { - let para_id = $crate::parachain_info::Pallet::<$runtime>::get(); - $crate::GLOBAL_RELAY.with(|v| { - let relay_block = *v.borrow(); - let _ = ParachainSystem::set_validation_data( - <$origin>::none(), - _hrmp_channel_parachain_inherent_data(para_id.into(), relay_block), - ); - }); + // 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 @@ -256,7 +561,7 @@ macro_rules! __impl_ext_for_parachain { v.borrow_mut().execute_with(|| { use sp_runtime::traits::Header as HeaderT; - let block_number = $crate::frame_system::Pallet::<$runtime>::block_number(); + let block_number = ::System::block_number(); let mock_header = HeaderT::new( 0, Default::default(), @@ -266,222 +571,367 @@ macro_rules! __impl_ext_for_parachain { ); // get messages - ParachainSystem::on_finalize(block_number); - let collation_info = ParachainSystem::collect_collation_info(&mock_header); + ::ParachainSystem::on_finalize(block_number); + let collation_info = ::ParachainSystem::collect_collation_info(&mock_header); // send upward messages - let para_id = $crate::parachain_info::Pallet::<$runtime>::get(); + let relay_block_number = <$name>::relay_block_number(); for msg in collation_info.upward_messages.clone() { - _Messenger::send_upward_message(para_id.into(), msg); + <$name>::send_upward_message(para_id, msg); } // send horizontal messages for msg in collation_info.horizontal_messages { - $crate::GLOBAL_RELAY.with(|v| { - let relay_block = *v.borrow(); - _Messenger::send_horizontal_messages( - msg.recipient.into(), - vec![(para_id.into(), relay_block, msg.data)].into_iter(), - ); - }); + <$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); + ::ParachainSystem::on_initialize(block_number); }) }); - _process_messages(); + <$name>::process_messages(); r } + + fn ext_wrapper(func: impl FnOnce() -> R) -> R { + $ext_name.with(|v| { + v.borrow_mut().execute_with(|| { + func() + }) + }) + } } }; } -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(VecDeque::new()); - #[allow(clippy::type_complexity)] - /// Downward messages that already processed by parachains, each message is: `(to_para_id, relay_block_number, Vec)` - pub static DMP_DONE: RefCell)>> - = RefCell::new(VecDeque::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(VecDeque::new()); - /// Upward messages, each message is: `(from_para_id, msg) - pub static UPWARD_MESSAGES: RefCell)>> = RefCell::new(VecDeque::new()); - /// Global incremental relay chain block number - pub static GLOBAL_RELAY: RefCell = RefCell::new(1); -} - #[macro_export] -macro_rules! decl_test_network { - ( - pub struct $name:ident { - relay_chain = $relay_chain:ty, - parachains = vec![ $( ($para_id:expr, $parachain:ty), )* ], +macro_rules! __impl_parachain { + ($network_name:ident, $parachain:ty) => { + impl $crate::NetworkComponent<$network_name> for $parachain { + fn network_name() -> &'static str { + stringify!($network_name) + } } - ) => { - pub struct $name; - impl $name { - pub fn reset() { - use $crate::{TestExt, VecDeque}; + impl $parachain { + pub fn para_id() -> $crate::ParaId { + Self::ext_wrapper(|| ::ParachainInfo::get()) + } - <$relay_chain>::reset_ext(); - $( <$parachain>::reset_ext(); )* + pub fn parent_location() -> $crate::MultiLocation { + (Parent).into() + } - $( <$parachain>::prepare_for_xcmp(); )* + pub fn account_id_of(seed: &str) -> $crate::AccountId { + $crate::get_account_id_from_seed::(seed) + } - $crate::DOWNWARD_MESSAGES.with(|b| b.replace(VecDeque::new())); - $crate::DMP_DONE.with(|b| b.replace(VecDeque::new())); + pub fn account_data_of(account: AccountId) -> $crate::AccountData { + Self::ext_wrapper(|| ::System::account(account).data) } - } - fn _para_ids() -> Vec { - vec![$( $para_id, )*] - } + pub fn sovereign_account_id_of(location: $crate::MultiLocation) -> $crate::AccountId { + ::LocationToAccountId::convert(location.into()).unwrap() + } - fn _process_messages() { - while _has_unprocessed_messages() { - _process_upward_messages(); - _process_horizontal_messages(); - _process_downward_messages(); + 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(), + ); + } + }); } - } - fn _has_unprocessed_messages() -> bool { - $crate::DOWNWARD_MESSAGES.with(|b| !b.borrow_mut().is_empty()) - || $crate::HORIZONTAL_MESSAGES.with(|b| !b.borrow_mut().is_empty()) - || $crate::UPWARD_MESSAGES.with(|b| !b.borrow_mut().is_empty()) + 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); + }); + } } + }; +} - fn _process_downward_messages() { - use $crate::{DmpMessageHandler, Bounded}; - use polkadot_parachain::primitives::RelayChainBlockNumber; +// 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(); )* + } + } - while let Some((to_para_id, messages)) - = $crate::DOWNWARD_MESSAGES.with(|b| b.borrow_mut().pop_front()) { - match to_para_id { - $( - $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().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().push_back((to_para_id, m.0, m.1))); + 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!(); } - }, - )* - _ => unreachable!(), + )* + } } - } - } - fn _process_horizontal_messages() { - use $crate::{XcmpMessageHandler, Bounded}; + fn _process_horizontal_messages() { + use $crate::{XcmpMessageHandler, Bounded}; - while let Some((to_para_id, messages)) - = $crate::HORIZONTAL_MESSAGES.with(|b| b.borrow_mut().pop_front()) { - let iter = messages.iter().map(|(p, b, m)| (*p, *b, &m[..])).collect::>().into_iter(); - match to_para_id { - $( - $para_id => { - <$parachain>::handle_xcmp_messages(iter, $crate::Weight::max_value()); - }, - )* - _ => unreachable!(), + 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().pop_front()) { - let _ = <$relay_chain>::process_upward_message( - from_para_id.into(), - &msg[..], - $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(), + ); + } + } - pub struct _Messenger; - impl _Messenger { - fn send_downward_messages(to_para_id: u32, iter: impl Iterator)>) { - $crate::DOWNWARD_MESSAGES.with(|b| b.borrow_mut().push_back((to_para_id, iter.collect()))); - } + 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); + } - fn send_horizontal_messages< - I: Iterator)>, - >(to_para_id: u32, iter: I) { - $crate::HORIZONTAL_MESSAGES.with(|b| b.borrow_mut().push_back((to_para_id, iter.collect()))); - } + 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, + }); + } - fn send_upward_message(from_para_id: u32, msg: Vec) { - $crate::UPWARD_MESSAGES.with(|b| b.borrow_mut().push_back((from_para_id, msg))); + 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(), + } + } } - } - 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 &[ $( $para_id, )* ] { - 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); + $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 } + }); - 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(), + 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 + } +} From 109f50ec1a93d83fbbd1cb9927f479e24ac37019 Mon Sep 17 00:00:00 2001 From: NachoPal Date: Thu, 18 May 2023 18:13:22 +0200 Subject: [PATCH 20/21] update e2e tests to xcm v3 --- .../e2e/assets/statemine/0_xcm/0_init.yml | 72 +-- .../e2e/assets/statemine/0_xcm/1_dmp.yml | 78 +-- .../e2e/assets/statemine/0_xcm/2_ump.yml | 81 +-- .../statemine/0_xcm/3_hrmp-open-channels.yml | 412 +++------------ .../e2e/assets/statemine/0_xcm/4_hrmp.yml | 497 +++++++++-------- .../e2e/assets/statemine/config.toml | 77 ++- .../e2e/assets/statemint/0_xcm/0_init.yml | 78 +-- .../e2e/assets/statemint/0_xcm/1_dmp.yml | 76 +-- .../e2e/assets/statemint/0_xcm/2_ump.yml | 80 +-- .../statemint/0_xcm/3_hrmp-open-channels.yml | 376 ++----------- .../e2e/assets/statemint/0_xcm/4_hrmp.yml | 499 ++++++++++-------- .../e2e/assets/statemint/config.toml | 78 ++- .../collectives_polkadot/0_xcm/0_init.yml | 4 +- .../collectives_polkadot/0_xcm/1_teleport.yml | 26 +- .../collectives_polkadot/0_xcm/2_reserve.yml | 10 +- .../1_alliance/1_init_alliance.yml | 19 +- .../1_alliance/3_kick_member.yml | 4 +- .../collectives_polkadot/config.toml | 8 + 18 files changed, 1063 insertions(+), 1412 deletions(-) diff --git a/parachains/integration-tests/e2e/assets/statemine/0_xcm/0_init.yml b/parachains/integration-tests/e2e/assets/statemine/0_xcm/0_init.yml index b9640517719..b770c8e569e 100644 --- a/parachains/integration-tests/e2e/assets/statemine/0_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/e2e/assets/statemine/0_xcm/1_dmp.yml b/parachains/integration-tests/e2e/assets/statemine/0_xcm/1_dmp.yml index 9b08555a251..0852a3907db 100644 --- a/parachains/integration-tests/e2e/assets/statemine/0_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,973,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,021,258,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,23 +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 - threshold: [10, 10] - value: 750,645,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/e2e/assets/statemine/0_xcm/2_ump.yml b/parachains/integration-tests/e2e/assets/statemine/0_xcm/2_ump.yml index daddf927931..46519da3fde 100644 --- a/parachains/integration-tests/e2e/assets/statemine/0_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 index 45bf89e2b05..cc1fc9da146 100644 --- 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 @@ -12,7 +12,7 @@ settings: variables: common: amount: &amount 2000000000000 - require_weight_at_most: &weight_at_most 1000000000 + 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 @@ -29,380 +29,106 @@ settings: 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 }}}} 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: sovereign_account: &ap_sovereign F7fq1jSNVTPfJmaHaXCMtatT1EZefCUsa7rRiQVNR5efcah - relay_chain_destination: &rc_dest { v1: { parents: 1, interior: { here: true }}} + relay_chain_destination: &rc_dest { v3: { 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 + - 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 + - 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 + - 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 + - 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 + - name: Open Penpal Parachain to Assets Parachain 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 + - chain: *relay_chain + signer: *rc_signer + sudo: true pallet: hrmp - call: hrmpOpenChannelRequestsList - args: [] - - asserts: - equal: + call: forceOpenHrmpChannel args: [ - $requested_channels, - [ - { - sender: *pp_id, - recipient: *ap_id - } - ] + 2000, + 1000, + 8, + 8192 ] - - - name: hrmp.hrmpAcceptOpenChannel (Assets Parachain → Penpal Parachain) + events: + - name: sudo.Sudid + attributes: + - type: Result + value: Ok + - name: hrmp.HrmpChannelForceOpened + - name: hrmp.hrmpInitOpenChannel (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 + - name: Open Assets Parachain to 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_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 + - chain: *relay_chain + signer: *rc_signer + sudo: true pallet: hrmp - call: hrmpChannels - delay: 80000 + call: forceOpenHrmpChannel args: [ - { - sender: *pp_id, - recipient: *ap_id - } + 1000, + 2000, + 8, + 8192 ] - - asserts: - equal: - args: [ - $open_channels, - *channel - ] - - - name: hrmp.hrmpInitOpenChannel (Assets Parachain → Penpal Parachain) + events: + - name: sudo.Sudid + attributes: + - type: Result + value: Ok + - name: hrmp.HrmpChannelForceOpened + - name: hrmp.forceProcessHrmpOpen (make sure all the channels are open) its: - - name: Assets Parchain sends a request to the Relay Chain to open a channel with a Penpal Parachain + - name: Make sure all the pending channels are open 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 + - chain: *relay_chain + signer: *rc_signer + sudo: true 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 + 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 index 28ef7bc803a..e47ae5a4054 100644 --- a/parachains/integration-tests/e2e/assets/statemine/0_xcm/4_hrmp.yml +++ b/parachains/integration-tests/e2e/assets/statemine/0_xcm/4_hrmp.yml @@ -1,4 +1,6 @@ --- +# 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 @@ -11,27 +13,27 @@ settings: paraId: &pp_id 2000 variables: common: - amount: &amount 1000000000000 - require_weight_at_most: &weight_at_most 1000000000 + 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 { v1: { 0, interior: { x1: { parachain: *ap_id }}}} - assets_parachain_dest_routed: &ap_dest_routed { v1: { parents: 1, interior: { x1: { parachain: *ap_id } }}} + 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 { v1: { parents: 1, interior: { x1: { parachain: *pp_id } }}} + 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: &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 }} + 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 @@ -47,48 +49,61 @@ settings: true, # isSufficient *asset_ed # minBalance ] - system_remark_with_event: + force_create_asset2: chain: *assets_parachain - pallet: system - call: remarkWithEvent - args: [ 0x0011 ] + 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: DEPENDANCY | A sufficient Asset should exist in the Assets Parachain + - 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 - { - v2: [ #message - { - Transact: { - originType: Superuser, - requireWeightAtMost: *weight_at_most, - call: $force_create_asset + - 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 - attribute: - type: XcmV2TraitsOutcome - isComplete: true - threshold: [10, 10] - value: 1,021,258,000 + ] + } + ] + 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 @@ -99,136 +114,134 @@ tests: isSome: args: [ $forced_created_asset ] - - name: DEPENDANCY | Some Assets should be minted for the sender + - 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, - *amount - ] - events: - - name: assets.Issued + - 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 - V1: { - parents: 0, - interior: { - X1: { - AccountId32: { - network: Any, - id: *pp_acc + - 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 - V1: [ - { - id: { - Concrete: { - parents: 0, - interior: { - X2: [ - { - PalletInstance: 50 - }, - { - GeneralIndex: *asset_id - } - ] + }, + { # assets + V3: [ + { + id: { + Concrete: { + parents: 0, + interior: { + X2: [ + { + PalletInstance: *assets_pallet_id + }, + { + GeneralIndex: *asset_id + } + ] + } } + }, + fun: { + Fungible: *amount_to_send } - }, - 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 + ] + }, + 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 - V1: { - parents: 0, - interior: { - X1: { - AccountId32: { - network: Any, - id: *pp_acc + - 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 - 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 + }, + { # 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( system.remarkWithEvent() ) | Penpal Parachain -> Assets Parachain + - 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: @@ -245,55 +258,82 @@ tests: - 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, + - 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 + } + } + }} + } } - }, - { - 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 + ] + } + ] + 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 @@ -303,7 +343,14 @@ tests: *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: @@ -320,37 +367,37 @@ tests: - 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: { + - 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 + } } - }, - { - Transact: { - originType: SovereignAccount, - requireWeightAtMost: *weight_at_most, - call: $system_remark_with_event - } - } - ] - } - ] - events: - - name: xcmpQueue.Fail - chain: *assets_parachain - attribute: - type: XcmV2TraitsError - value: FailedToTransactAsset + ] + } + ] + 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 index 510f3cd3b04..6aa7ee8d116 100644 --- a/parachains/integration-tests/e2e/assets/statemine/config.toml +++ b/parachains/integration-tests/e2e/assets/statemine/config.toml @@ -1,49 +1,70 @@ [relaychain] default_command = "./bin/polkadot" -default_args = [ "-lparachain=debug" ] +default_args = [ "-lparachain=debug", "-lxcm=trace" ] chain = "kusama-local" - [[relaychain.nodes]] - name = "alice" - ws_port = 9900 - validator = true + [[relaychain.nodes]] + name = "alice" + ws_port = 9900 + validator = true - [[relaychain.nodes]] - name = "bob" - validator = true + [[relaychain.nodes]] + name = "bob" + ws_port = 9901 + validator = true - [[relaychain.nodes]] - name = "charlie" - validator = true + [[relaychain.nodes]] + name = "charlie" + ws_port = 9902 + validator = true - [[relaychain.nodes]] - name = "dave" - 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" + [[parachains.collators]] + name = "collator1" + ws_port = 9910 + command = "./bin/polkadot-parachain" + args = [ "-lxcm=trace" ] - [[parachains.collators]] - name = "collator2" - command = "./bin/polkadot-parachain" + [[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" + [[parachains.collators]] + name = "collator3" + ws_port = 9920 + command = "./bin/polkadot-parachain" + args = [ "-lxcm=trace" ] - [[parachains.collators]] - name = "collator4" - command = "./bin/polkadot-parachain" + [[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/e2e/assets/statemint/0_xcm/0_init.yml b/parachains/integration-tests/e2e/assets/statemint/0_xcm/0_init.yml index b9640517719..95c77f72d0d 100644 --- a/parachains/integration-tests/e2e/assets/statemint/0_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/e2e/assets/statemint/0_xcm/1_dmp.yml b/parachains/integration-tests/e2e/assets/statemint/0_xcm/1_dmp.yml index 5f0fa349072..96a97ba728d 100644 --- a/parachains/integration-tests/e2e/assets/statemint/0_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,635,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,020,807,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,22 +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 - value: 1,000,000,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/e2e/assets/statemint/0_xcm/2_ump.yml b/parachains/integration-tests/e2e/assets/statemint/0_xcm/2_ump.yml index f51823eb3e8..d839375320b 100644 --- a/parachains/integration-tests/e2e/assets/statemint/0_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 index f83e778f1c0..a274282df30 100644 --- 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 @@ -2,17 +2,17 @@ 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: amount: &amount 2000000000000 - require_weight_at_most: &weight_at_most 1000000000 + 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 @@ -29,107 +29,20 @@ settings: 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 }}}} 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 }}} + 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 - 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 + - name: DEPENDENCY | Penpal Parachain Sovereign account in the Relay Chain needs to be funded actions: - extrinsics: - chain: *relay_chain @@ -143,7 +56,7 @@ tests: events: - name: balances.Transfer - - name: DEPENDANCY | Assets Parachain Sovereign account in the Relay Chain needs to be funded + - name: DEPENDENCY | Assets Parachain Sovereign account in the Relay Chain needs to be funded actions: - extrinsics: - chain: *relay_chain @@ -159,244 +72,61 @@ tests: 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 + - name: Open Penpal Parachain to Assets Parachain 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 + - chain: *relay_chain + signer: *rc_signer + sudo: true pallet: hrmp - call: hrmpOpenChannelRequestsList - args: [] - - asserts: - equal: + call: forceOpenHrmpChannel args: [ - $requested_channels, - [ - { - sender: *pp_id, - recipient: *ap_id - } - ] + 2000, + 1000, + 8, + 8192 ] - - - name: hrmp.hrmpAcceptOpenChannel (Assets Parachain → Penpal Parachain) + events: + - name: sudo.Sudid + attributes: + - type: Result + value: Ok + - name: hrmp.HrmpChannelForceOpened + - name: hrmp.hrmpInitOpenChannel (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 + - name: Open Assets Parachain to 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_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 + - chain: *relay_chain + signer: *rc_signer + sudo: true pallet: hrmp - call: hrmpChannels - delay: 80000 + call: forceOpenHrmpChannel args: [ - { - sender: *pp_id, - recipient: *ap_id - } + 1000, + 2000, + 8, + 8192 ] - - 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) + events: + - name: sudo.Sudid + attributes: + - type: Result + value: Ok + - name: hrmp.HrmpChannelForceOpened + - name: hrmp.forceProcessHrmpOpen (make sure all the channels are open) its: - - name: Penpal Parachain sends a response to the Relay Chain accepting the Assets Parachain's request for openning a HRMP channel + - name: Make sure all the pending channels are open 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 + - 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 index 00a3ff467bc..c36192fd5a3 100644 --- a/parachains/integration-tests/e2e/assets/statemint/0_xcm/4_hrmp.yml +++ b/parachains/integration-tests/e2e/assets/statemint/0_xcm/4_hrmp.yml @@ -2,36 +2,36 @@ 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: + mint_amount: &mint_amount 1000000000000 amount: &amount 1000000000000 - require_weight_at_most: &weight_at_most 1000000000 + 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 { v1: { 0, interior: { x1: { parachain: *ap_id }}}} - assets_parachain_dest_routed: &ap_dest_routed { v1: { parents: 1, interior: { x1: { parachain: *ap_id } }}} + 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 { v1: { parents: 1, interior: { x1: { parachain: *pp_id } }}} + 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: &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 }} + 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 @@ -47,48 +47,61 @@ settings: true, # isSufficient *asset_ed # minBalance ] - system_remark_with_event: + force_create_asset2: chain: *assets_parachain - pallet: system - call: remarkWithEvent - args: [ 0x0011 ] + 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: DEPENDANCY | A sufficient Asset should exist in the Assets Parachain + - 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 - { - v2: [ #message - { - Transact: { - originType: Superuser, - requireWeightAtMost: *weight_at_most, - call: $force_create_asset + - 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 - attribute: - type: XcmV2TraitsOutcome - isComplete: true - threshold: [10, 10] - value: 1,020,807,000 + ] + } + ] + 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 @@ -99,136 +112,134 @@ tests: isSome: args: [ $forced_created_asset ] - - name: DEPENDANCY | Some Assets should be minted for the sender + - 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, - *amount - ] - events: - - name: assets.Issued + - 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 - V1: { - parents: 0, - interior: { - X1: { - AccountId32: { - network: Any, - id: *pp_acc + - 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 - V1: [ - { - id: { - Concrete: { - parents: 0, - interior: { - X2: [ - { - PalletInstance: 50 - }, - { - GeneralIndex: *asset_id - } - ] + }, + { # assets + V3: [ + { + id: { + Concrete: { + parents: 0, + interior: { + X2: [ + { + PalletInstance: *assets_pallet_id + }, + { + GeneralIndex: *asset_id + } + ] + } } + }, + fun: { + Fungible: *amount_to_send } - }, - 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 + ] + }, + 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 - V1: { - parents: 0, - interior: { - X1: { - AccountId32: { - network: Any, - id: *pp_acc + - 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 - 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 + }, + { # 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( system.remarkWithEvent() ) | Penpal Parachain -> Assets Parachain + - 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: @@ -245,55 +256,82 @@ tests: - 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, + - 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 + } + } + }} + } } - }, - { - 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 + ] + } + ] + 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 @@ -303,7 +341,14 @@ tests: *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: @@ -320,37 +365,37 @@ tests: - 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: { + - 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 + } } - }, - { - Transact: { - originType: SovereignAccount, - requireWeightAtMost: *weight_at_most, - call: $system_remark_with_event - } - } - ] - } - ] - events: - - name: xcmpQueue.Fail - chain: *assets_parachain - attribute: - type: XcmV2TraitsError - value: FailedToTransactAsset + ] + } + ] + 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 index f989d366ef3..5b5a861eed6 100644 --- a/parachains/integration-tests/e2e/assets/statemint/config.toml +++ b/parachains/integration-tests/e2e/assets/statemint/config.toml @@ -1,49 +1,71 @@ [relaychain] default_command = "./bin/polkadot" -default_args = [ "-lparachain=debug" ] +default_args = [ "-lparachain=debug", "-lxcm=trace" ] chain = "polkadot-local" - [[relaychain.nodes]] - name = "alice" - ws_port = 9900 - validator = true + [[relaychain.nodes]] + name = "alice" + ws_port = 9800 + validator = true - [[relaychain.nodes]] - name = "bob" - validator = true + [[relaychain.nodes]] + name = "bob" + ws_port = 9801 + validator = true - [[relaychain.nodes]] - name = "charlie" - validator = true + [[relaychain.nodes]] + name = "charlie" + ws_port = 9802 + validator = true - [[relaychain.nodes]] - name = "dave" - 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 = 9910 - command = "./bin/polkadot-parachain" + [[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.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 = "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 - [[parachains.collators]] - name = "collator4" - command = "./bin/polkadot-parachain" +# [[hrmpChannels]] +# sender = 2000 +# recipient = 1000 +# maxCapacity = 8 +# maxMessageSize = 8192 diff --git a/parachains/integration-tests/e2e/collectives/collectives_polkadot/0_xcm/0_init.yml b/parachains/integration-tests/e2e/collectives/collectives_polkadot/0_xcm/0_init.yml index 48a86f9136e..4dadb9f0116 100644 --- a/parachains/integration-tests/e2e/collectives/collectives_polkadot/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/e2e/collectives/collectives_polkadot/0_xcm/1_teleport.yml b/parachains/integration-tests/e2e/collectives/collectives_polkadot/0_xcm/1_teleport.yml index 2b1a6bba8f1..e6310d05922 100644 --- a/parachains/integration-tests/e2e/collectives/collectives_polkadot/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/e2e/collectives/collectives_polkadot/0_xcm/2_reserve.yml b/parachains/integration-tests/e2e/collectives/collectives_polkadot/0_xcm/2_reserve.yml index ac42ca4a4b0..b152d71de3a 100644 --- a/parachains/integration-tests/e2e/collectives/collectives_polkadot/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/e2e/collectives/collectives_polkadot/1_alliance/1_init_alliance.yml b/parachains/integration-tests/e2e/collectives/collectives_polkadot/1_alliance/1_init_alliance.yml index 8e9adbbeb47..26bd72a7967 100644 --- a/parachains/integration-tests/e2e/collectives/collectives_polkadot/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/e2e/collectives/collectives_polkadot/1_alliance/3_kick_member.yml b/parachains/integration-tests/e2e/collectives/collectives_polkadot/1_alliance/3_kick_member.yml index 62c61787e21..aac09883375 100644 --- a/parachains/integration-tests/e2e/collectives/collectives_polkadot/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/e2e/collectives/collectives_polkadot/config.toml b/parachains/integration-tests/e2e/collectives/collectives_polkadot/config.toml index 9d138be11ba..d99e38078d0 100644 --- a/parachains/integration-tests/e2e/collectives/collectives_polkadot/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"] From 858dfc7a37172f4570a38cff1a09d6307afa2968 Mon Sep 17 00:00:00 2001 From: NachoPal Date: Fri, 19 May 2023 12:47:03 +0200 Subject: [PATCH 21/21] clippy + runtime-benchmark + clean docs --- .../emulated/common/Cargo.toml | 5 + xcm/xcm-emulator/README.md | 91 ------------------- xcm/xcm-emulator/src/lib.rs | 2 + 3 files changed, 7 insertions(+), 91 deletions(-) diff --git a/parachains/integration-tests/emulated/common/Cargo.toml b/parachains/integration-tests/emulated/common/Cargo.toml index 8ea8c1d0f8a..a13ceac2cff 100644 --- a/parachains/integration-tests/emulated/common/Cargo.toml +++ b/parachains/integration-tests/emulated/common/Cargo.toml @@ -47,3 +47,8 @@ collectives-polkadot-runtime = { path = "../../../runtimes/collectives/collectiv 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/xcm/xcm-emulator/README.md b/xcm/xcm-emulator/README.md index 267258d758b..5087ae4ac3c 100644 --- a/xcm/xcm-emulator/README.md +++ b/xcm/xcm-emulator/README.md @@ -18,94 +18,3 @@ In future it may be possible to run these XCM emulated tests as E2E tests (witho 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. - -## How to use - - diff --git a/xcm/xcm-emulator/src/lib.rs b/xcm/xcm-emulator/src/lib.rs index ad9cb2873f4..b928d5cf76e 100644 --- a/xcm/xcm-emulator/src/lib.rs +++ b/xcm/xcm-emulator/src/lib.rs @@ -289,6 +289,7 @@ macro_rules! __impl_test_ext_for_relay_chain { 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); @@ -515,6 +516,7 @@ macro_rules! __impl_test_ext_for_parachain { 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);