From 4b8954314417b562f5e99f1b014e707137b693cb Mon Sep 17 00:00:00 2001 From: "ron.yang" Date: Tue, 13 Jul 2021 10:03:30 +0800 Subject: [PATCH 1/2] Xcm test framework --- Cargo.lock | 8 + xcm-support/Cargo.toml | 21 +- xcm-support/src/lib.rs | 16 +- xcm-support/src/mock.rs | 467 +++++++++++++++++++++++++++++++++++++-- xcm-support/src/tests.rs | 139 ++++++++++++ 5 files changed, 622 insertions(+), 29 deletions(-) create mode 100644 xcm-support/src/tests.rs diff --git a/Cargo.lock b/Cargo.lock index b984e532fc..cfb3751645 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5822,6 +5822,7 @@ dependencies = [ "frame-support", "frame-system", "parity-scale-codec", + "serde", "sp-runtime", "sp-std", "xcm", @@ -11730,16 +11731,23 @@ name = "xcm-support" version = "0.8.0" dependencies = [ "cumulus-pallet-dmp-queue", + "cumulus-pallet-parachain-system", + "cumulus-pallet-xcm", "cumulus-pallet-xcmp-queue", "cumulus-primitives-core", "frame-support", "frame-system", "node-primitives", "orml-traits", + "pallet-balances", + "pallet-xcm", + "parachain-info", "parity-scale-codec", "paste", "polkadot-parachain", "polkadot-runtime-parachains", + "sp-core", + "sp-io", "sp-runtime", "sp-std", "xcm", diff --git a/xcm-support/Cargo.toml b/xcm-support/Cargo.toml index 9a422a0948..f4ec09bc62 100644 --- a/xcm-support/Cargo.toml +++ b/xcm-support/Cargo.toml @@ -12,17 +12,26 @@ sp-std = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.8", default-features = false } frame-system = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.8", default-features = false } frame-support = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.8", default-features = false } -polkadot-parachain = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "release-v0.9.8" } xcm = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.8", default-features = false } xcm-builder = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "release-v0.9.8" } xcm-executor = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.8", default-features = false } cumulus-primitives-core = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.8", default-features = false } -cumulus-pallet-xcmp-queue = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.8", default-features = false } -cumulus-pallet-dmp-queue = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.8", default-features = false } -polkadot-runtime-parachains = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.8", default-features = false } orml-traits = { version = "0.4.1-dev", default-features = false } node-primitives = { default-features = false, path = "../node/primitives" } +[dev-dependencies] +sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.8"} +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.8"} +pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.8"} +cumulus-pallet-parachain-system = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.8"} +cumulus-pallet-xcmp-queue = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.8" } +cumulus-pallet-dmp-queue = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.8" } +cumulus-pallet-xcm = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.8" } +parachain-info = { git = "https://github.com/paritytech/cumulus", branch = "polkadot-v0.9.8" } +pallet-xcm = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.8" } +polkadot-parachain = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.8" } +polkadot-runtime-parachains = { git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.8" } + [features] default = ["std"] std = [ @@ -31,14 +40,10 @@ std = [ "sp-runtime/std", "frame-system/std", "frame-support/std", - "polkadot-parachain/std", "xcm/std", "xcm-builder/std", "xcm-executor/std", "orml-traits/std", "node-primitives/std", "cumulus-primitives-core/std", - "cumulus-pallet-xcmp-queue/std", - "cumulus-pallet-dmp-queue/std", - "polkadot-runtime-parachains/std", ] diff --git a/xcm-support/src/lib.rs b/xcm-support/src/lib.rs index ee3ef917c0..7cb89d6fcb 100644 --- a/xcm-support/src/lib.rs +++ b/xcm-support/src/lib.rs @@ -26,17 +26,18 @@ #![cfg_attr(not(feature = "std"), no_std)] -#[cfg(test)] -mod mock; - use codec::FullCodec; +pub use cumulus_primitives_core::{self, ParaId}; +pub use frame_support::{traits::Get, weights::Weight}; +pub use paste; use sp_runtime::traits::{Convert, MaybeSerializeDeserialize, SaturatedConversion}; +pub use sp_std::{cell::RefCell, marker::PhantomData}; use sp_std::{ cmp::{Eq, PartialEq}, fmt::Debug, - marker::PhantomData, prelude::*, }; +pub use xcm::{v0::prelude::*, VersionedXcm}; use xcm::{ v0::{ Error as XcmError, Junction, MultiAsset, MultiLocation, OriginKind, Result as XcmResult, @@ -45,9 +46,16 @@ use xcm::{ DoubleEncoded, }; use xcm_executor::traits::{Convert as xcmConvert, MatchesFungible, TransactAsset}; +pub use xcm_executor::XcmExecutor; mod traits; pub use traits::{BifrostXcmExecutor, HandleDmpMessage, HandleUmpMessage, HandleXcmpMessage}; +#[cfg(test)] +mod mock; + +#[cfg(test)] +mod tests; + /// Asset transaction errors. enum Error { /// Failed to match fungible. diff --git a/xcm-support/src/mock.rs b/xcm-support/src/mock.rs index 830ae0a0e9..8657cd3f2f 100644 --- a/xcm-support/src/mock.rs +++ b/xcm-support/src/mock.rs @@ -20,11 +20,12 @@ pub use codec::Encode; pub use cumulus_pallet_dmp_queue; pub use cumulus_pallet_xcmp_queue; pub use cumulus_primitives_core::{self, ParaId}; -use frame_support::sp_io; +use frame_support::{sp_io, traits::GenesisBuild}; pub use frame_support::{traits::Get, weights::Weight}; pub use paste; pub use polkadot_runtime_parachains::{dmp, ump}; pub use sp_io::TestExternalities; +use sp_runtime::AccountId32; use sp_std::vec::Vec; pub use sp_std::{cell::RefCell, marker::PhantomData}; pub use xcm::{v0::prelude::*, VersionedXcm}; @@ -73,13 +74,12 @@ macro_rules! decl_test_relay_chain { impl $crate::HandleUmpMessage for $name { fn handle_ump_message(from: $crate::ParaId, msg: &[u8], max_weight: $crate::Weight) { - use $crate::ump::UmpSink; - use $crate::TestExt; + use ump::UmpSink; Self::execute_with(|| { - let _ = $crate::ump::XcmSink::<$crate::XcmExecutor<$xcm_config>, $runtime>::process_upward_message( - from, msg, max_weight, - ); + let _ = ump::XcmSink::<$crate::XcmExecutor<$xcm_config>, $runtime>::process_upward_message( + from, msg, max_weight, + ); }); } } @@ -105,10 +105,10 @@ macro_rules! decl_test_parachain { msg: &[u8], max_weight: $crate::Weight, ) { - use $crate::{cumulus_primitives_core::XcmpMessageHandler, TestExt}; + use cumulus_primitives_core::XcmpMessageHandler; $name::execute_with(|| { - $crate::cumulus_pallet_xcmp_queue::Pallet::<$runtime>::handle_xcmp_messages( + cumulus_pallet_xcmp_queue::Pallet::<$runtime>::handle_xcmp_messages( vec![(from, at_relay_block, msg)].into_iter(), max_weight, ); @@ -118,10 +118,10 @@ macro_rules! decl_test_parachain { impl $crate::HandleDmpMessage for $name { fn handle_dmp_message(at_relay_block: u32, msg: Vec, max_weight: $crate::Weight) { - use $crate::{cumulus_primitives_core::DmpMessageHandler, TestExt}; + use cumulus_primitives_core::DmpMessageHandler; $name::execute_with(|| { - $crate::cumulus_pallet_dmp_queue::Pallet::<$runtime>::handle_dmp_messages( + cumulus_pallet_dmp_queue::Pallet::<$runtime>::handle_dmp_messages( vec![(at_relay_block, msg)].into_iter(), max_weight, ); @@ -142,12 +142,12 @@ macro_rules! __impl_ext { // impl (@impl $name:ident, $new_ext:expr, $ext_name:ident) => { thread_local! { - pub static $ext_name: $crate::RefCell<$crate::TestExternalities> + pub static $ext_name: $crate::RefCell = $crate::RefCell::new($new_ext); } - impl $crate::TestExt for $name { - fn new_ext() -> $crate::TestExternalities { + impl TestExt for $name { + fn new_ext() -> TestExternalities { $new_ext } @@ -174,7 +174,6 @@ macro_rules! decl_test_network { impl $name { pub fn reset() { - use $crate::TestExt; <$relay_chain>::reset_ext(); $( <$parachain>::reset_ext(); )* @@ -190,14 +189,14 @@ macro_rules! decl_test_network { match destination { $crate::X1($crate::Parent) => { - let encoded = $crate::encode_xcm(message, $crate::MessageKind::Ump); + let encoded = encode_xcm(message, MessageKind::Ump); <$relay_chain>::handle_ump_message(T::get(), &encoded[..], $crate::Weight::max_value()); // TODO: update max weight Ok(()) }, $( $crate::X2($crate::Parent, $crate::Parachain(id)) if id == $para_id => { - let encoded = $crate::encode_xcm(message, $crate::MessageKind::Xcmp); + let encoded = encode_xcm(message, MessageKind::Xcmp); // TODO: update max weight; update `at_relay_block` <$parachain>::handle_xcmp_message(T::get(), 1, &encoded[..], $crate::Weight::max_value()); Ok(()) @@ -217,7 +216,7 @@ macro_rules! decl_test_network { match destination { $( $crate::X1($crate::Parachain(id)) if id == $para_id => { - let encoded = $crate::encode_xcm(message, $crate::MessageKind::Dmp); + let encoded = encode_xcm(message, MessageKind::Dmp); // TODO: update max weight; update `at_relay_block` <$parachain>::handle_dmp_message(1, encoded, $crate::Weight::max_value()); Ok(()) @@ -229,3 +228,437 @@ macro_rules! decl_test_network { } }; } + +pub const ALICE: AccountId32 = AccountId32::new([0u8; 32]); + +decl_test_parachain! { + pub struct ParaA { + Runtime = para::Runtime, + new_ext = para_ext(1), + } +} + +decl_test_parachain! { + pub struct ParaB { + Runtime = para::Runtime, + new_ext = para_ext(2), + } +} + +decl_test_relay_chain! { + pub struct Relay { + Runtime = relay::Runtime, + XcmConfig = relay::XcmConfig, + new_ext = relay_ext(), + } +} + +decl_test_network! { + pub struct MockNet { + relay_chain = Relay, + parachains = vec![ + (1, ParaA), + (2, ParaB), + ], + } +} + +pub const INITIAL_BALANCE: u128 = 1_000_000_000; + +pub fn para_ext(para_id: u32) -> sp_io::TestExternalities { + use para::{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 +} + +pub fn relay_ext() -> sp_io::TestExternalities { + use relay::{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(); + + let mut ext = sp_io::TestExternalities::new(t); + ext.execute_with(|| System::set_block_number(1)); + ext +} + +pub type RelayChainPalletXcm = pallet_xcm::Pallet; +pub type ParachainPalletXcm = pallet_xcm::Pallet; + +pub mod para { + use frame_support::{ + construct_runtime, parameter_types, + traits::All, + weights::{constants::WEIGHT_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::IdentityLookup, AccountId32}; + pub use xcm::v0::{ + Junction::{Parachain, Parent}, + MultiAsset, + MultiLocation::{self, X1, X2, X3}, + NetworkId, Xcm, + }; + pub use xcm_builder::{ + AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, + CurrencyAdapter as XcmCurrencyAdapter, EnsureXcmOrigin, FixedRateOfConcreteFungible, + FixedWeightBounds, IsConcrete, LocationInverter, NativeAsset, ParentAsSuperuser, + ParentIsDefault, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, + SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, + TakeWeightCredit, + }; + use xcm_executor::{Config, XcmExecutor}; + + pub type AccountId = AccountId32; + pub type Balance = u128; + + parameter_types! { + pub const BlockHashCount: u64 = 250; + } + + impl frame_system::Config for Runtime { + type AccountData = pallet_balances::AccountData; + type AccountId = AccountId; + type BaseCallFilter = (); + type BlockHashCount = BlockHashCount; + type BlockLength = (); + type BlockNumber = u64; + type BlockWeights = (); + type Call = Call; + type DbWeight = (); + type Event = Event; + type Hash = H256; + type Hashing = ::sp_runtime::traits::BlakeTwo256; + type Header = Header; + type Index = u64; + type Lookup = IdentityLookup; + type OnKilledAccount = (); + type OnNewAccount = (); + type OnSetCode = cumulus_pallet_parachain_system::ParachainSetCode; + type Origin = Origin; + type PalletInfo = PalletInfo; + type SS58Prefix = (); + type SystemWeightInfo = (); + type Version = (); + } + + parameter_types! { + pub ExistentialDeposit: Balance = 1; + pub const MaxLocks: u32 = 50; + pub const MaxReserves: u32 = 50; + } + + impl pallet_balances::Config for Runtime { + type AccountStore = System; + type Balance = Balance; + type DustRemoval = (); + type Event = Event; + type ExistentialDeposit = ExistentialDeposit; + type MaxLocks = MaxLocks; + type MaxReserves = MaxReserves; + type ReserveIdentifier = [u8; 8]; + type WeightInfo = (); + } + + parameter_types! { + pub const ReservedXcmpWeight: Weight = WEIGHT_PER_SECOND / 4; + pub const ReservedDmpWeight: Weight = WEIGHT_PER_SECOND / 4; + } + + impl cumulus_pallet_parachain_system::Config for Runtime { + type DmpMessageHandler = DmpQueue; + type Event = Event; + type OnValidationData = (); + type OutboundXcmpMessageSource = XcmpQueue; + type ReservedDmpWeight = ReservedDmpWeight; + type ReservedXcmpWeight = ReservedXcmpWeight; + type SelfParaId = ParachainInfo; + type XcmpMessageHandler = XcmpQueue; + } + + impl parachain_info::Config for Runtime {} + + parameter_types! { + pub const KsmLocation: MultiLocation = MultiLocation::X1(Parent); + pub const RelayNetwork: NetworkId = NetworkId::Kusama; + pub RelayChainOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into(); + pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into(); + } + + pub type LocationToAccountId = ( + ParentIsDefault, + SiblingParachainConvertsVia, + AccountId32Aliases, + ); + + pub type XcmOriginToCallOrigin = ( + SovereignSignedViaLocation, + RelayChainAsNative, + SiblingParachainAsNative, + SignedAccountId32AsNative, + XcmPassthrough, + ); + + parameter_types! { + pub const UnitWeightCost: Weight = 1; + pub KsmPerSecond: (MultiLocation, u128) = (X1(Parent), 1); + } + + pub type LocalAssetTransactor = + XcmCurrencyAdapter, LocationToAccountId, AccountId, ()>; + + pub type XcmRouter = crate::mock::ParachainXcmRouter; + pub type Barrier = AllowUnpaidExecutionFrom>; + + pub struct XcmConfig; + impl Config for XcmConfig { + type AssetTransactor = LocalAssetTransactor; + type Barrier = Barrier; + type Call = Call; + type IsReserve = NativeAsset; + type IsTeleporter = (); + type LocationInverter = LocationInverter; + type OriginConverter = XcmOriginToCallOrigin; + type ResponseHandler = (); + type Trader = FixedRateOfConcreteFungible; + type Weigher = FixedWeightBounds; + type XcmSender = XcmRouter; + } + + impl cumulus_pallet_xcmp_queue::Config for Runtime { + type ChannelInfo = ParachainSystem; + type Event = Event; + type XcmExecutor = XcmExecutor; + } + + impl cumulus_pallet_dmp_queue::Config for Runtime { + type Event = Event; + type ExecuteOverweightOrigin = EnsureRoot; + type XcmExecutor = XcmExecutor; + } + + impl cumulus_pallet_xcm::Config for Runtime { + type Event = Event; + type XcmExecutor = XcmExecutor; + } + + pub type LocalOriginToLocation = SignedToAccountId32; + + impl pallet_xcm::Config for Runtime { + type Event = Event; + type ExecuteXcmOrigin = EnsureXcmOrigin; + type SendXcmOrigin = EnsureXcmOrigin; + type Weigher = FixedWeightBounds; + type XcmExecuteFilter = All<(MultiLocation, Xcm)>; + type XcmExecutor = XcmExecutor; + type XcmReserveTransferFilter = All<(MultiLocation, Vec)>; + type XcmRouter = XcmRouter; + type XcmTeleportFilter = (); + } + + 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, Config, Storage, Inherent, 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}, + } + ); +} + +pub mod relay { + use cumulus_primitives_core::ParaId; + use frame_support::{construct_runtime, parameter_types, traits::All, weights::Weight}; + use polkadot_runtime_parachains::{configuration, origin, shared, ump}; + use sp_core::H256; + use sp_runtime::{testing::Header, traits::IdentityLookup, AccountId32}; + use xcm::v0::{MultiAsset, MultiLocation, NetworkId}; + use xcm_builder::{ + AccountId32Aliases, AllowUnpaidExecutionFrom, ChildParachainAsNative, + ChildParachainConvertsVia, ChildSystemParachainAsSuperuser, + CurrencyAdapter as XcmCurrencyAdapter, FixedRateOfConcreteFungible, FixedWeightBounds, + IsConcrete, LocationInverter, SignedAccountId32AsNative, SignedToAccountId32, + SovereignSignedViaLocation, + }; + use xcm_executor::{Config, XcmExecutor}; + + pub type AccountId = AccountId32; + pub type Balance = u128; + + parameter_types! { + pub const BlockHashCount: u64 = 250; + } + + impl frame_system::Config for Runtime { + type AccountData = pallet_balances::AccountData; + type AccountId = AccountId; + type BaseCallFilter = (); + type BlockHashCount = BlockHashCount; + type BlockLength = (); + type BlockNumber = u64; + type BlockWeights = (); + type Call = Call; + type DbWeight = (); + type Event = Event; + type Hash = H256; + type Hashing = ::sp_runtime::traits::BlakeTwo256; + type Header = Header; + type Index = u64; + type Lookup = IdentityLookup; + type OnKilledAccount = (); + type OnNewAccount = (); + type OnSetCode = (); + type Origin = Origin; + type PalletInfo = PalletInfo; + type SS58Prefix = (); + type SystemWeightInfo = (); + type Version = (); + } + + parameter_types! { + pub ExistentialDeposit: Balance = 1; + pub const MaxLocks: u32 = 50; + pub const MaxReserves: u32 = 50; + } + + impl pallet_balances::Config for Runtime { + type AccountStore = System; + type Balance = Balance; + type DustRemoval = (); + type Event = Event; + type ExistentialDeposit = ExistentialDeposit; + type MaxLocks = MaxLocks; + type MaxReserves = MaxReserves; + type ReserveIdentifier = [u8; 8]; + type WeightInfo = (); + } + + impl shared::Config for Runtime {} + + impl configuration::Config for Runtime {} + + parameter_types! { + pub const KsmLocation: MultiLocation = MultiLocation::Null; + pub const KusamaNetwork: NetworkId = NetworkId::Kusama; + pub const AnyNetwork: NetworkId = NetworkId::Any; + pub Ancestry: MultiLocation = MultiLocation::Null; + pub UnitWeightCost: Weight = 1_000; + } + + pub type SovereignAccountOf = ( + ChildParachainConvertsVia, + AccountId32Aliases, + ); + + pub type LocalAssetTransactor = + XcmCurrencyAdapter, SovereignAccountOf, AccountId, ()>; + + type LocalOriginConverter = ( + SovereignSignedViaLocation, + ChildParachainAsNative, + SignedAccountId32AsNative, + ChildSystemParachainAsSuperuser, + ); + + parameter_types! { + pub const BaseXcmWeight: Weight = 1_000; + pub KsmPerSecond: (MultiLocation, u128) = (KsmLocation::get(), 1); + } + + pub type XcmRouter = crate::mock::RelayChainXcmRouter; + pub type Barrier = AllowUnpaidExecutionFrom>; + + pub struct XcmConfig; + impl Config for XcmConfig { + type AssetTransactor = LocalAssetTransactor; + type Barrier = Barrier; + type Call = Call; + type IsReserve = (); + type IsTeleporter = (); + type LocationInverter = LocationInverter; + type OriginConverter = LocalOriginConverter; + type ResponseHandler = (); + type Trader = FixedRateOfConcreteFungible; + type Weigher = FixedWeightBounds; + type XcmSender = XcmRouter; + } + + pub type LocalOriginToLocation = SignedToAccountId32; + + impl pallet_xcm::Config for Runtime { + type Event = Event; + // Anyone can execute XCM messages locally... + type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin; + type SendXcmOrigin = xcm_builder::EnsureXcmOrigin; + type Weigher = FixedWeightBounds; + type XcmExecuteFilter = (); + type XcmExecutor = XcmExecutor; + type XcmReserveTransferFilter = All<(MultiLocation, Vec)>; + type XcmRouter = XcmRouter; + type XcmTeleportFilter = All<(MultiLocation, Vec)>; + } + + parameter_types! { + pub const FirstMessageFactorPercent: u64 = 100; + } + + impl ump::Config for Runtime { + type Event = Event; + type FirstMessageFactorPercent = FirstMessageFactorPercent; + type UmpSink = ump::XcmSink, Runtime>; + } + + impl origin::Config for Runtime {} + + 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}, + ParasOrigin: origin::{Pallet, Origin}, + ParasUmp: ump::{Pallet, Call, Storage, Event}, + XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event}, + } + ); +} diff --git a/xcm-support/src/tests.rs b/xcm-support/src/tests.rs new file mode 100644 index 0000000000..bb329fc986 --- /dev/null +++ b/xcm-support/src/tests.rs @@ -0,0 +1,139 @@ +// This file is part of Bifrost. + +// Copyright (C) 2019-2021 Liebi Technologies (UK) Ltd. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program 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. + +// This program 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 this program. If not, see . + +#[cfg(test)] +mod tests { + use codec::Encode; + use frame_support::assert_ok; + use xcm::v0::{ + Junction::{self, Parachain, Parent}, + MultiAsset::*, + MultiLocation::*, + NetworkId, OriginKind, + Xcm::*, + }; + + use crate::mock::*; + + fn print_events(context: &str) { + println!("------ {:?} events ------", context); + frame_system::Pallet::::events().iter().for_each(|r| { + println!("{:?}", r.event); + }); + } + + #[test] + fn reserve_transfer() { + MockNet::reset(); + + Relay::execute_with(|| { + assert_ok!(RelayChainPalletXcm::reserve_transfer_assets( + relay::Origin::signed(ALICE), + X1(Parachain(1)), + X1(Junction::AccountId32 { network: NetworkId::Any, id: ALICE.into() }), + vec![ConcreteFungible { id: Null, amount: 123 }], + 123, + )); + }); + + ParaA::execute_with(|| { + // free execution, full amount received + assert_eq!( + pallet_balances::Pallet::::free_balance(&ALICE), + INITIAL_BALANCE + 123 + ); + + print_events::("ParaA"); + }); + } + + #[test] + fn dmp() { + MockNet::reset(); + + let remark = + para::Call::System(frame_system::Call::::remark_with_event(vec![ + 1, 2, 3, + ])); + Relay::execute_with(|| { + assert_ok!(RelayChainPalletXcm::send_xcm( + Null, + X1(Parachain(1)), + Transact { + origin_type: OriginKind::SovereignAccount, + require_weight_at_most: INITIAL_BALANCE as u64, + call: remark.encode().into(), + }, + )); + }); + + ParaA::execute_with(|| { + print_events::("ParaA"); + }); + } + + #[test] + fn ump() { + MockNet::reset(); + + let remark = + relay::Call::System(frame_system::Call::::remark_with_event(vec![ + 1, 2, 3, + ])); + ParaA::execute_with(|| { + assert_ok!(ParachainPalletXcm::send_xcm( + Null, + X1(Parent), + Transact { + origin_type: OriginKind::SovereignAccount, + require_weight_at_most: INITIAL_BALANCE as u64, + call: remark.encode().into(), + }, + )); + }); + + Relay::execute_with(|| { + print_events::("RelayChain"); + }); + } + + #[test] + fn xcmp() { + MockNet::reset(); + + let remark = + para::Call::System(frame_system::Call::::remark_with_event(vec![ + 1, 2, 3, + ])); + ParaA::execute_with(|| { + assert_ok!(ParachainPalletXcm::send_xcm( + Null, + X2(Parent, Parachain(2)), + Transact { + origin_type: OriginKind::SovereignAccount, + require_weight_at_most: INITIAL_BALANCE as u64, + call: remark.encode().into(), + }, + )); + }); + + ParaB::execute_with(|| { + print_events::("ParaB"); + }); + } +} From 9a4c24954d12ac0f7010ae91421ae163ccaa848d Mon Sep 17 00:00:00 2001 From: "ron.yang" Date: Tue, 13 Jul 2021 11:05:24 +0800 Subject: [PATCH 2/2] fix --- xcm-support/src/mock.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/xcm-support/src/mock.rs b/xcm-support/src/mock.rs index 8657cd3f2f..3f01638e7d 100644 --- a/xcm-support/src/mock.rs +++ b/xcm-support/src/mock.rs @@ -75,11 +75,8 @@ macro_rules! decl_test_relay_chain { impl $crate::HandleUmpMessage for $name { fn handle_ump_message(from: $crate::ParaId, msg: &[u8], max_weight: $crate::Weight) { use ump::UmpSink; - Self::execute_with(|| { - let _ = ump::XcmSink::<$crate::XcmExecutor<$xcm_config>, $runtime>::process_upward_message( - from, msg, max_weight, - ); + let _ = ump::XcmSink::<$crate::XcmExecutor<$xcm_config>, $runtime>::process_upward_message(from, msg, max_weight); }); } }