Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

add integration tests to xcm-builder #3537

Merged
37 commits merged into from
Aug 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
5018eb5
add integration tests to xcm-builder
apopiak Jul 31, 2021
29b7b04
add an integration test for reserve_transfer_assets
apopiak Jul 31, 2021
ee9b9c7
add query holding and teleport tests
apopiak Jul 31, 2021
7a09753
formatting
apopiak Jul 31, 2021
d1539f6
add to barrier doc comments and fix doc tests warnings
apopiak Jul 31, 2021
d9ebc77
use more realistic barrier for integration tests
apopiak Jul 31, 2021
ec426b9
improve imports
apopiak Jul 31, 2021
32b67ca
adjust base xcm weight and existential deposit to be in line with Kusama
apopiak Jul 31, 2021
7881628
remove AnyNetwork
apopiak Aug 1, 2021
5e8507f
add more comments and remove unnecessary code
apopiak Aug 1, 2021
cea48f9
Merge branch 'apopiak/xcm-integration-tests' of github.com:paritytech…
apopiak Aug 1, 2021
24b79ec
move mock into separate file
apopiak Aug 1, 2021
4aba2d6
reduce imports
apopiak Aug 1, 2021
114ef4e
update cargo.lock
apopiak Aug 1, 2021
97fb7a8
remove reserve transfer test from xcm builder integration tests
apopiak Aug 3, 2021
21a7e74
reword barrier doc comment
apopiak Aug 3, 2021
aababe1
elaborate on QueryHolding test scenario
apopiak Aug 3, 2021
2b63830
add an integration test for reserve based transfers from parachain to…
apopiak Aug 3, 2021
eed0fbc
add teleport tests
apopiak Aug 3, 2021
dc2a1bf
fix failing teleport filter tests
apopiak Aug 3, 2021
5dd3744
Update xcm/xcm-builder/src/integration_tests.rs
apopiak Aug 10, 2021
3b63468
Update xcm/xcm-builder/src/integration_tests.rs
apopiak Aug 10, 2021
26e7f53
Update xcm/xcm-builder/src/integration_tests.rs
apopiak Aug 10, 2021
4bd50a7
Move integration tests to tests/ directory
KiChjang Aug 14, 2021
75d0971
Merge remote-tracking branch 'origin/master' into apopiak/xcm-integra…
KiChjang Aug 14, 2021
f8a4847
Fix merge
KiChjang Aug 14, 2021
e3605c5
Replace All wildcard with a concrete seed amount
KiChjang Aug 14, 2021
4266a94
Rename SEED_AMOUNT to REGISTER_AMOUNT
KiChjang Aug 14, 2021
412ce69
Fix compilation error
KiChjang Aug 14, 2021
72975eb
Check for teleport destination first before checking out assets
KiChjang Aug 14, 2021
0d17e0a
Fix unit test
KiChjang Aug 14, 2021
304fd94
Do not run tests in integration mock
KiChjang Aug 14, 2021
ab81960
Add a permissive assets filter for teleportation
KiChjang Aug 14, 2021
2fba6af
Remove check for teleport location in InitiateTeleport XCM
KiChjang Aug 16, 2021
fd51b75
Remove defunct test
KiChjang Aug 17, 2021
1f15e4b
Apply suggestions from code review
apopiak Aug 17, 2021
dcd947b
Reword comment
apopiak Aug 17, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions xcm/pallet-xcm/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use xcm::{
opaque::latest::{Error as XcmError, MultiAsset, Result as XcmResult, SendXcm, Xcm},
};
use xcm_builder::{
AccountId32Aliases, AllowTopLevelPaidExecutionFrom, ChildParachainAsNative,
AccountId32Aliases, AllowTopLevelPaidExecutionFrom, Case, ChildParachainAsNative,
ChildParachainConvertsVia, ChildSystemParachainAsSuperuser,
CurrencyAdapter as XcmCurrencyAdapter, FixedRateOfFungible, FixedWeightBounds, IsConcrete,
LocationInverter, SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation,
Expand Down Expand Up @@ -151,6 +151,7 @@ type LocalOriginConverter = (
parameter_types! {
pub const BaseXcmWeight: Weight = 1_000;
pub CurrencyPerSecond: (AssetId, u128) = (Concrete(RelayLocation::get()), 1);
pub TrustedAssets: (MultiAssetFilter, MultiLocation) = (All.into(), Here.into());
}

pub type Barrier = (TakeWeightCredit, AllowTopLevelPaidExecutionFrom<Everything>);
Expand All @@ -162,7 +163,7 @@ impl xcm_executor::Config for XcmConfig {
type AssetTransactor = LocalAssetTransactor;
type OriginConverter = LocalOriginConverter;
type IsReserve = ();
type IsTeleporter = ();
type IsTeleporter = Case<TrustedAssets>;
type LocationInverter = LocationInverter<Ancestry>;
type Barrier = Barrier;
type Weigher = FixedWeightBounds<BaseXcmWeight, Call>;
Expand Down
5 changes: 5 additions & 0 deletions xcm/xcm-builder/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ pallet-transaction-payment = { git = "https://github.com/paritytech/substrate",
# Polkadot dependencies
polkadot-parachain = { path = "../../parachain", default-features = false }

[dev-dependencies]
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master" }
pallet-xcm = { path = "../pallet-xcm" }
polkadot-runtime-parachains = { path = "../../runtime/parachains" }
[features]
default = ["std"]
runtime-benchmarks = []
Expand Down
7 changes: 7 additions & 0 deletions xcm/xcm-builder/src/barriers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ use xcm::latest::{Junction, Junctions, MultiLocation, Order, Xcm};
use xcm_executor::traits::{OnResponse, ShouldExecute};

/// Execution barrier that just takes `shallow_weight` from `weight_credit`.
///
/// Useful to allow XCM execution by local chain users via extrinsics.
/// E.g. `pallet_xcm::reserve_asset_transfer` to transfer a reserve asset
apopiak marked this conversation as resolved.
Show resolved Hide resolved
/// out of the local chain to another one.
pub struct TakeWeightCredit;
impl ShouldExecute for TakeWeightCredit {
fn should_execute<Call>(
Expand All @@ -39,6 +43,9 @@ impl ShouldExecute for TakeWeightCredit {

/// Allows execution from `origin` if it is contained in `T` (i.e. `T::Contains(origin)`) taking payments into
/// account.
///
/// Only allows for `TeleportAsset`, `WithdrawAsset` and `ReserveAssetDeposit` XCMs because they are the only ones
/// that place assets in the Holding Register to pay for execution.
pub struct AllowTopLevelPaidExecutionFrom<T>(PhantomData<T>);
impl<T: Contains<MultiLocation>> ShouldExecute for AllowTopLevelPaidExecutionFrom<T> {
fn should_execute<Call>(
Expand Down
4 changes: 2 additions & 2 deletions xcm/xcm-builder/src/currency_adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ impl From<Error> for XcmError {
///
/// /// Our relay chain's location.
/// parameter_types! {
/// RelayChain: MultiLocation = Parent.into();
/// CheckingAccount: AccountId = Default::default();
/// pub RelayChain: MultiLocation = Parent.into();
/// pub CheckingAccount: AccountId = Default::default();
/// }
///
/// /// Some items that implement `Convert<MultiLocation, AccountId>`. Can be more, but for now we just assume we accept
Expand Down
4 changes: 2 additions & 2 deletions xcm/xcm-builder/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ thread_local! {
pub fn assets(who: u64) -> Vec<MultiAsset> {
ASSETS.with(|a| a.borrow().get(&who).map_or(vec![], |a| a.clone().into()))
}
pub fn add_asset(who: u64, what: MultiAsset) {
ASSETS.with(|a| a.borrow_mut().entry(who).or_insert(Assets::new()).subsume(what));
pub fn add_asset<AssetArg: Into<MultiAsset>>(who: u64, what: AssetArg) {
ASSETS.with(|a| a.borrow_mut().entry(who).or_insert(Assets::new()).subsume(what.into()));
}

pub struct TestAssetTransactor;
Expand Down
6 changes: 3 additions & 3 deletions xcm/xcm-builder/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ fn transfer_should_work() {
// we'll let them have message execution for free.
AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]);
// Child parachain #1 owns 1000 tokens held by us in reserve.
add_asset(1001, (Here, 1000).into());
add_asset(1001, (Here, 1000));
// They want to transfer 100 of them to their sibling parachain #2
let r = XcmExecutor::<TestConfig>::execute_xcm(
Parachain(1).into(),
Expand All @@ -247,7 +247,7 @@ fn transfer_should_work() {
fn reserve_transfer_should_work() {
AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]);
// Child parachain #1 owns 1000 tokens held by us in reserve.
add_asset(1001, (Here, 1000).into());
add_asset(1001, (Here, 1000));
// The remote account owned by gav.
let three: MultiLocation = X1(AccountIndex64 { index: 3, network: Any }).into();

Expand Down Expand Up @@ -334,7 +334,7 @@ fn transacting_should_refund_weight() {
fn paid_transacting_should_refund_payment_for_unused_weight() {
let one: MultiLocation = X1(AccountIndex64 { index: 1, network: Any }).into();
AllowPaidFrom::set(vec![one.clone()]);
add_asset(1, (Parent, 100).into());
add_asset(1, (Parent, 100));
WeightPrice::set((Parent.into(), 1_000_000_000_000));

let origin = one.clone();
Expand Down
211 changes: 211 additions & 0 deletions xcm/xcm-builder/tests/mock/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
// Copyright 2021 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 <http://www.gnu.org/licenses/>.

use frame_support::{construct_runtime, parameter_types, traits::Everything, weights::Weight};
use sp_core::H256;
use sp_runtime::{testing::Header, traits::IdentityLookup, AccountId32};
use sp_std::cell::RefCell;

use polkadot_parachain::primitives::Id as ParaId;
use polkadot_runtime_parachains::{configuration, origin, shared};
use xcm::latest::{opaque, prelude::*};
use xcm_executor::XcmExecutor;

use xcm_builder::{
AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom,
ChildParachainAsNative, ChildParachainConvertsVia, ChildSystemParachainAsSuperuser,
CurrencyAdapter as XcmCurrencyAdapter, FixedRateOfFungible, FixedWeightBounds,
IsChildSystemParachain, IsConcrete, LocationInverter, SignedAccountId32AsNative,
SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,
};

pub type AccountId = AccountId32;
pub type Balance = u128;

thread_local! {
pub static SENT_XCM: RefCell<Vec<(MultiLocation, opaque::Xcm)>> = RefCell::new(Vec::new());
}
pub fn sent_xcm() -> Vec<(MultiLocation, opaque::Xcm)> {
SENT_XCM.with(|q| (*q.borrow()).clone())
}
pub struct TestSendXcm;
impl SendXcm for TestSendXcm {
fn send_xcm(dest: MultiLocation, msg: opaque::Xcm) -> XcmResult {
SENT_XCM.with(|q| q.borrow_mut().push((dest, msg)));
Ok(())
}
}

// copied from kusama constants
pub const UNITS: Balance = 1_000_000_000_000;
pub const CENTS: Balance = UNITS / 30_000;

parameter_types! {
pub const BlockHashCount: u64 = 250;
}

impl frame_system::Config for Runtime {
type Origin = Origin;
type Call = Call;
type Index = u64;
type BlockNumber = u64;
type Hash = H256;
type Hashing = ::sp_runtime::traits::BlakeTwo256;
type AccountId = AccountId;
type Lookup = IdentityLookup<Self::AccountId>;
type Header = Header;
type Event = Event;
type BlockHashCount = BlockHashCount;
type BlockWeights = ();
type BlockLength = ();
type Version = ();
type PalletInfo = PalletInfo;
type AccountData = pallet_balances::AccountData<Balance>;
type OnNewAccount = ();
type OnKilledAccount = ();
type DbWeight = ();
type BaseCallFilter = Everything;
type SystemWeightInfo = ();
type SS58Prefix = ();
type OnSetCode = ();
}

parameter_types! {
pub ExistentialDeposit: Balance = 1 * CENTS;
pub const MaxLocks: u32 = 50;
pub const MaxReserves: u32 = 50;
}

impl pallet_balances::Config for Runtime {
type MaxLocks = MaxLocks;
type Balance = Balance;
type Event = Event;
type DustRemoval = ();
type ExistentialDeposit = ExistentialDeposit;
type AccountStore = System;
type WeightInfo = ();
type MaxReserves = MaxReserves;
type ReserveIdentifier = [u8; 8];
}

impl shared::Config for Runtime {}

impl configuration::Config for Runtime {}

// aims to closely emulate the Kusama XcmConfig
parameter_types! {
pub const KsmLocation: MultiLocation = MultiLocation::here();
pub const KusamaNetwork: NetworkId = NetworkId::Kusama;
pub Ancestry: MultiLocation = Here.into();
pub CheckAccount: AccountId = XcmPallet::check_account();
}

pub type SovereignAccountOf =
(ChildParachainConvertsVia<ParaId, AccountId>, AccountId32Aliases<KusamaNetwork, AccountId>);

pub type LocalAssetTransactor = XcmCurrencyAdapter<
Balances,
IsConcrete<KsmLocation>,
SovereignAccountOf,
AccountId,
CheckAccount,
>;

type LocalOriginConverter = (
SovereignSignedViaLocation<SovereignAccountOf, Origin>,
ChildParachainAsNative<origin::Origin, Origin>,
SignedAccountId32AsNative<KusamaNetwork, Origin>,
ChildSystemParachainAsSuperuser<ParaId, Origin>,
);

parameter_types! {
pub const BaseXcmWeight: Weight = 1_000_000_000;
pub KsmPerSecond: (AssetId, u128) = (KsmLocation::get().into(), 1);
}

pub type Barrier = (
TakeWeightCredit,
AllowTopLevelPaidExecutionFrom<Everything>,
// Unused/Untested
AllowUnpaidExecutionFrom<IsChildSystemParachain<ParaId>>,
);

parameter_types! {
pub const KusamaForStatemint: (MultiAssetFilter, MultiLocation) =
(MultiAssetFilter::Wild(WildMultiAsset::AllOf { id: Concrete(MultiLocation::here()), fun: WildFungible }), X1(Parachain(1000)).into());
}
pub type TrustedTeleporters = (xcm_builder::Case<KusamaForStatemint>,);

pub struct XcmConfig;
impl xcm_executor::Config for XcmConfig {
type Call = Call;
type XcmSender = TestSendXcm;
type AssetTransactor = LocalAssetTransactor;
type OriginConverter = LocalOriginConverter;
type IsReserve = ();
type IsTeleporter = TrustedTeleporters;
type LocationInverter = LocationInverter<Ancestry>;
type Barrier = Barrier;
type Weigher = FixedWeightBounds<BaseXcmWeight, Call>;
type Trader = FixedRateOfFungible<KsmPerSecond, ()>;
type ResponseHandler = ();
}

pub type LocalOriginToLocation = SignedToAccountId32<Origin, AccountId, KusamaNetwork>;

impl pallet_xcm::Config for Runtime {
type Event = Event;
type LocationInverter = LocationInverter<Ancestry>;
type SendXcmOrigin = xcm_builder::EnsureXcmOrigin<Origin, LocalOriginToLocation>;
type XcmRouter = TestSendXcm;
// Anyone can execute XCM messages locally...
type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin<Origin, LocalOriginToLocation>;
type XcmExecuteFilter = ();
type XcmExecutor = XcmExecutor<XcmConfig>;
type XcmTeleportFilter = Everything;
type XcmReserveTransferFilter = Everything;
type Weigher = FixedWeightBounds<BaseXcmWeight, Call>;
}

impl origin::Config for Runtime {}

type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Runtime>;
type Block = frame_system::mocking::MockBlock<Runtime>;

construct_runtime!(
pub enum Runtime where
Block = Block,
NodeBlock = Block,
UncheckedExtrinsic = UncheckedExtrinsic,
{
System: frame_system::{Pallet, Call, Storage, Config, Event<T>},
Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
ParasOrigin: origin::{Pallet, Origin},
XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event<T>},
}
);

pub fn kusama_like_with_balances(balances: Vec<(AccountId, Balance)>) -> sp_io::TestExternalities {
let mut t = frame_system::GenesisConfig::default().build_storage::<Runtime>().unwrap();

pallet_balances::GenesisConfig::<Runtime> { balances }
.assimilate_storage(&mut t)
.unwrap();

let mut ext = sp_io::TestExternalities::new(t);
ext.execute_with(|| System::set_block_number(1));
ext
}
Loading