mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-19 06:31:03 +00:00
pallet-xcm: enhance reserve_transfer_assets to support remote reserves (#1672)
## Motivation `pallet-xcm` is the main user-facing interface for XCM functionality, including assets manipulation functions like `teleportAssets()` and `reserve_transfer_assets()` calls. While `teleportAsset()` works both ways, `reserve_transfer_assets()` works only for sending reserve-based assets to a remote destination and beneficiary when the reserve is the _local chain_. ## Solution This PR enhances `pallet_xcm::(limited_)reserve_withdraw_assets` to support transfers when reserves are other chains. This will allow complete, **bi-directional** reserve-based asset transfers user stories using `pallet-xcm`. Enables following scenarios: - transferring assets with local reserve (was previously supported iff asset used as fee also had local reserve - now it works in all cases), - transferring assets with reserve on destination, - transferring assets with reserve on remote/third-party chain (iff assets and fees have same remote reserve), - transferring assets with reserve different than the reserve of the asset to be used as fees - meaning can be used to transfer random asset with local/dest reserve while using DOT for fees on all involved chains, even if DOT local/dest reserve doesn't match asset reserve, - transferring assets with any type of local/dest reserve while using fees which can be teleported between involved chains. All of the above is done by pallet inner logic without the user having to specify which scenario/reserves/teleports/etc. The correct scenario and corresponding XCM programs are identified, and respectively, built automatically based on runtime configuration of trusted teleporters and trusted reserves. #### Current limitations: - while `fees` and "non-fee" `assets` CAN have different reserves (or fees CAN be teleported), the remaining "non-fee" `assets` CANNOT, among themselves, have different reserve locations (this is also implicitly enforced by `MAX_ASSETS_FOR_TRANSFER=2`, but this can be safely increased in the future). - `fees` and "non-fee" `assets` CANNOT have **different remote** reserves (this could also be supported in the future, but adds even more complexity while possibly not being worth it - we'll see what the future holds). Fixes https://github.com/paritytech/polkadot-sdk/issues/1584 Fixes https://github.com/paritytech/polkadot-sdk/issues/2055 --------- Co-authored-by: Francisco Aguirre <franciscoaguirreperez@gmail.com> Co-authored-by: Branislav Kontur <bkontur@gmail.com>
This commit is contained in:
Generated
+5
@@ -901,9 +901,11 @@ dependencies = [
|
|||||||
"pallet-asset-conversion",
|
"pallet-asset-conversion",
|
||||||
"pallet-assets",
|
"pallet-assets",
|
||||||
"pallet-balances",
|
"pallet-balances",
|
||||||
|
"pallet-message-queue",
|
||||||
"pallet-xcm",
|
"pallet-xcm",
|
||||||
"parachains-common",
|
"parachains-common",
|
||||||
"parity-scale-codec",
|
"parity-scale-codec",
|
||||||
|
"penpal-runtime",
|
||||||
"rococo-runtime",
|
"rococo-runtime",
|
||||||
"rococo-system-emulated-network",
|
"rococo-system-emulated-network",
|
||||||
"sp-runtime",
|
"sp-runtime",
|
||||||
@@ -11183,6 +11185,7 @@ dependencies = [
|
|||||||
"frame-support",
|
"frame-support",
|
||||||
"frame-system",
|
"frame-system",
|
||||||
"log",
|
"log",
|
||||||
|
"pallet-assets",
|
||||||
"pallet-balances",
|
"pallet-balances",
|
||||||
"parity-scale-codec",
|
"parity-scale-codec",
|
||||||
"polkadot-parachain-primitives",
|
"polkadot-parachain-primitives",
|
||||||
@@ -11630,6 +11633,7 @@ dependencies = [
|
|||||||
"frame-support",
|
"frame-support",
|
||||||
"parachains-common",
|
"parachains-common",
|
||||||
"penpal-runtime",
|
"penpal-runtime",
|
||||||
|
"rococo-emulated-chain",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"sp-core",
|
"sp-core",
|
||||||
"sp-runtime",
|
"sp-runtime",
|
||||||
@@ -18416,6 +18420,7 @@ dependencies = [
|
|||||||
"impl-trait-for-tuples",
|
"impl-trait-for-tuples",
|
||||||
"log",
|
"log",
|
||||||
"parity-scale-codec",
|
"parity-scale-codec",
|
||||||
|
"scale-info",
|
||||||
"sp-arithmetic",
|
"sp-arithmetic",
|
||||||
"sp-core",
|
"sp-core",
|
||||||
"sp-io",
|
"sp-io",
|
||||||
|
|||||||
@@ -150,11 +150,6 @@ pub type XcmRouter = WithUniqueTopic<(
|
|||||||
XcmpQueue,
|
XcmpQueue,
|
||||||
)>;
|
)>;
|
||||||
|
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
parameter_types! {
|
|
||||||
pub ReachableDest: Option<MultiLocation> = Some(Parent.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
impl pallet_xcm::Config for Runtime {
|
impl pallet_xcm::Config for Runtime {
|
||||||
type RuntimeEvent = RuntimeEvent;
|
type RuntimeEvent = RuntimeEvent;
|
||||||
type SendXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
|
type SendXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
|
||||||
@@ -180,8 +175,6 @@ impl pallet_xcm::Config for Runtime {
|
|||||||
type SovereignAccountOf = LocationToAccountId;
|
type SovereignAccountOf = LocationToAccountId;
|
||||||
type MaxLockers = ConstU32<8>;
|
type MaxLockers = ConstU32<8>;
|
||||||
type WeightInfo = pallet_xcm::TestWeightInfo;
|
type WeightInfo = pallet_xcm::TestWeightInfo;
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
type ReachableDest = ReachableDest;
|
|
||||||
type AdminOrigin = EnsureRoot<AccountId>;
|
type AdminOrigin = EnsureRoot<AccountId>;
|
||||||
type MaxRemoteLockConsumers = ConstU32<0>;
|
type MaxRemoteLockConsumers = ConstU32<0>;
|
||||||
type RemoteLockConsumerIdentifier = ();
|
type RemoteLockConsumerIdentifier = ();
|
||||||
|
|||||||
+3
-3
@@ -21,7 +21,7 @@ use frame_support::traits::OnInitialize;
|
|||||||
// Cumulus
|
// Cumulus
|
||||||
use emulated_integration_tests_common::{
|
use emulated_integration_tests_common::{
|
||||||
impl_accounts_helpers_for_parachain, impl_assert_events_helpers_for_parachain,
|
impl_accounts_helpers_for_parachain, impl_assert_events_helpers_for_parachain,
|
||||||
impl_assets_helpers_for_system_parachain, xcm_emulator::decl_test_parachains,
|
impl_assets_helpers_for_parachain, xcm_emulator::decl_test_parachains,
|
||||||
};
|
};
|
||||||
use rococo_emulated_chain::Rococo;
|
use rococo_emulated_chain::Rococo;
|
||||||
|
|
||||||
@@ -51,5 +51,5 @@ decl_test_parachains! {
|
|||||||
|
|
||||||
// AssetHubRococo implementation
|
// AssetHubRococo implementation
|
||||||
impl_accounts_helpers_for_parachain!(AssetHubRococo);
|
impl_accounts_helpers_for_parachain!(AssetHubRococo);
|
||||||
impl_assert_events_helpers_for_parachain!(AssetHubRococo);
|
impl_assert_events_helpers_for_parachain!(AssetHubRococo, false);
|
||||||
impl_assets_helpers_for_system_parachain!(AssetHubRococo, Rococo);
|
impl_assets_helpers_for_parachain!(AssetHubRococo, Rococo);
|
||||||
|
|||||||
+3
-3
@@ -21,7 +21,7 @@ use frame_support::traits::OnInitialize;
|
|||||||
// Cumulus
|
// Cumulus
|
||||||
use emulated_integration_tests_common::{
|
use emulated_integration_tests_common::{
|
||||||
impl_accounts_helpers_for_parachain, impl_assert_events_helpers_for_parachain,
|
impl_accounts_helpers_for_parachain, impl_assert_events_helpers_for_parachain,
|
||||||
impl_assets_helpers_for_system_parachain, xcm_emulator::decl_test_parachains,
|
impl_assets_helpers_for_parachain, xcm_emulator::decl_test_parachains,
|
||||||
};
|
};
|
||||||
use westend_emulated_chain::Westend;
|
use westend_emulated_chain::Westend;
|
||||||
|
|
||||||
@@ -51,5 +51,5 @@ decl_test_parachains! {
|
|||||||
|
|
||||||
// AssetHubWestend implementation
|
// AssetHubWestend implementation
|
||||||
impl_accounts_helpers_for_parachain!(AssetHubWestend);
|
impl_accounts_helpers_for_parachain!(AssetHubWestend);
|
||||||
impl_assert_events_helpers_for_parachain!(AssetHubWestend);
|
impl_assert_events_helpers_for_parachain!(AssetHubWestend, false);
|
||||||
impl_assets_helpers_for_system_parachain!(AssetHubWestend, Westend);
|
impl_assets_helpers_for_parachain!(AssetHubWestend, Westend);
|
||||||
|
|||||||
+3
-3
@@ -19,7 +19,7 @@ use frame_support::traits::OnInitialize;
|
|||||||
// Cumulus
|
// Cumulus
|
||||||
use emulated_integration_tests_common::{
|
use emulated_integration_tests_common::{
|
||||||
impl_accounts_helpers_for_parachain, impl_assert_events_helpers_for_parachain,
|
impl_accounts_helpers_for_parachain, impl_assert_events_helpers_for_parachain,
|
||||||
impl_assets_helpers_for_system_parachain, xcm_emulator::decl_test_parachains,
|
impl_assets_helpers_for_parachain, xcm_emulator::decl_test_parachains,
|
||||||
};
|
};
|
||||||
use wococo_emulated_chain::Wococo;
|
use wococo_emulated_chain::Wococo;
|
||||||
|
|
||||||
@@ -49,5 +49,5 @@ decl_test_parachains! {
|
|||||||
|
|
||||||
// AssetHubWococo implementation
|
// AssetHubWococo implementation
|
||||||
impl_accounts_helpers_for_parachain!(AssetHubWococo);
|
impl_accounts_helpers_for_parachain!(AssetHubWococo);
|
||||||
impl_assert_events_helpers_for_parachain!(AssetHubWococo);
|
impl_assert_events_helpers_for_parachain!(AssetHubWococo, false);
|
||||||
impl_assets_helpers_for_system_parachain!(AssetHubWococo, Wococo);
|
impl_assets_helpers_for_parachain!(AssetHubWococo, Wococo);
|
||||||
|
|||||||
+1
-1
@@ -46,4 +46,4 @@ decl_test_parachains! {
|
|||||||
|
|
||||||
// BridgeHubRococo implementation
|
// BridgeHubRococo implementation
|
||||||
impl_accounts_helpers_for_parachain!(BridgeHubRococo);
|
impl_accounts_helpers_for_parachain!(BridgeHubRococo);
|
||||||
impl_assert_events_helpers_for_parachain!(BridgeHubRococo);
|
impl_assert_events_helpers_for_parachain!(BridgeHubRococo, false);
|
||||||
|
|||||||
+1
-1
@@ -46,4 +46,4 @@ decl_test_parachains! {
|
|||||||
|
|
||||||
// BridgeHubWestend implementation
|
// BridgeHubWestend implementation
|
||||||
impl_accounts_helpers_for_parachain!(BridgeHubWestend);
|
impl_accounts_helpers_for_parachain!(BridgeHubWestend);
|
||||||
impl_assert_events_helpers_for_parachain!(BridgeHubWestend);
|
impl_assert_events_helpers_for_parachain!(BridgeHubWestend, false);
|
||||||
|
|||||||
+1
-1
@@ -44,4 +44,4 @@ decl_test_parachains! {
|
|||||||
|
|
||||||
// BridgeHubWococo implementation
|
// BridgeHubWococo implementation
|
||||||
impl_accounts_helpers_for_parachain!(BridgeHubWococo);
|
impl_accounts_helpers_for_parachain!(BridgeHubWococo);
|
||||||
impl_assert_events_helpers_for_parachain!(BridgeHubWococo);
|
impl_assert_events_helpers_for_parachain!(BridgeHubWococo, false);
|
||||||
|
|||||||
+1
@@ -22,3 +22,4 @@ parachains-common = { path = "../../../../../../../parachains/common" }
|
|||||||
cumulus-primitives-core = { path = "../../../../../../../primitives/core", default-features = false }
|
cumulus-primitives-core = { path = "../../../../../../../primitives/core", default-features = false }
|
||||||
emulated-integration-tests-common = { path = "../../../../common", default-features = false }
|
emulated-integration-tests-common = { path = "../../../../common", default-features = false }
|
||||||
penpal-runtime = { path = "../../../../../../runtimes/testing/penpal" }
|
penpal-runtime = { path = "../../../../../../runtimes/testing/penpal" }
|
||||||
|
rococo-emulated-chain = { path = "../../../relays/rococo" }
|
||||||
|
|||||||
+9
-3
@@ -21,8 +21,10 @@ use frame_support::traits::OnInitialize;
|
|||||||
|
|
||||||
// Cumulus
|
// Cumulus
|
||||||
use emulated_integration_tests_common::{
|
use emulated_integration_tests_common::{
|
||||||
impl_assert_events_helpers_for_parachain, xcm_emulator::decl_test_parachains,
|
impl_accounts_helpers_for_parachain, impl_assert_events_helpers_for_parachain,
|
||||||
|
impl_assets_helpers_for_parachain, xcm_emulator::decl_test_parachains,
|
||||||
};
|
};
|
||||||
|
use rococo_emulated_chain::Rococo;
|
||||||
|
|
||||||
// Penpal Parachain declaration
|
// Penpal Parachain declaration
|
||||||
decl_test_parachains! {
|
decl_test_parachains! {
|
||||||
@@ -40,6 +42,7 @@ decl_test_parachains! {
|
|||||||
pallets = {
|
pallets = {
|
||||||
PolkadotXcm: penpal_runtime::PolkadotXcm,
|
PolkadotXcm: penpal_runtime::PolkadotXcm,
|
||||||
Assets: penpal_runtime::Assets,
|
Assets: penpal_runtime::Assets,
|
||||||
|
Balances: penpal_runtime::Balances,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
pub struct PenpalB {
|
pub struct PenpalB {
|
||||||
@@ -56,10 +59,13 @@ decl_test_parachains! {
|
|||||||
pallets = {
|
pallets = {
|
||||||
PolkadotXcm: penpal_runtime::PolkadotXcm,
|
PolkadotXcm: penpal_runtime::PolkadotXcm,
|
||||||
Assets: penpal_runtime::Assets,
|
Assets: penpal_runtime::Assets,
|
||||||
|
Balances: penpal_runtime::Balances,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Penpal implementation
|
// Penpal implementation
|
||||||
impl_assert_events_helpers_for_parachain!(PenpalA);
|
impl_accounts_helpers_for_parachain!(PenpalA);
|
||||||
impl_assert_events_helpers_for_parachain!(PenpalB);
|
impl_assets_helpers_for_parachain!(PenpalA, Rococo);
|
||||||
|
impl_assert_events_helpers_for_parachain!(PenpalA, true);
|
||||||
|
impl_assert_events_helpers_for_parachain!(PenpalB, true);
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ decl_test_relay_chains! {
|
|||||||
on_init = (),
|
on_init = (),
|
||||||
runtime = westend_runtime,
|
runtime = westend_runtime,
|
||||||
core = {
|
core = {
|
||||||
SovereignAccountOf: westend_runtime::xcm_config::LocationConverter, //TODO: rename to SovereignAccountOf,
|
SovereignAccountOf: westend_runtime::xcm_config::LocationConverter,
|
||||||
},
|
},
|
||||||
pallets = {
|
pallets = {
|
||||||
XcmPallet: westend_runtime::XcmPallet,
|
XcmPallet: westend_runtime::XcmPallet,
|
||||||
|
|||||||
@@ -399,7 +399,7 @@ macro_rules! impl_accounts_helpers_for_parachain {
|
|||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! impl_assert_events_helpers_for_parachain {
|
macro_rules! impl_assert_events_helpers_for_parachain {
|
||||||
( $chain:ident ) => {
|
( $chain:ident, $ignore_weight:expr ) => {
|
||||||
$crate::impls::paste::paste! {
|
$crate::impls::paste::paste! {
|
||||||
type [<$chain RuntimeEvent>]<N> = <$chain<N> as $crate::impls::Chain>::RuntimeEvent;
|
type [<$chain RuntimeEvent>]<N> = <$chain<N> as $crate::impls::Chain>::RuntimeEvent;
|
||||||
|
|
||||||
@@ -412,7 +412,7 @@ macro_rules! impl_assert_events_helpers_for_parachain {
|
|||||||
[<$chain RuntimeEvent>]::<N>::PolkadotXcm(
|
[<$chain RuntimeEvent>]::<N>::PolkadotXcm(
|
||||||
$crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Complete(weight) }
|
$crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Complete(weight) }
|
||||||
) => {
|
) => {
|
||||||
weight: $crate::impls::weight_within_threshold(
|
weight: $ignore_weight || $crate::impls::weight_within_threshold(
|
||||||
($crate::impls::REF_TIME_THRESHOLD, $crate::impls::PROOF_SIZE_THRESHOLD),
|
($crate::impls::REF_TIME_THRESHOLD, $crate::impls::PROOF_SIZE_THRESHOLD),
|
||||||
expected_weight.unwrap_or(*weight),
|
expected_weight.unwrap_or(*weight),
|
||||||
*weight
|
*weight
|
||||||
@@ -434,7 +434,7 @@ macro_rules! impl_assert_events_helpers_for_parachain {
|
|||||||
[<$chain RuntimeEvent>]::<N>::PolkadotXcm(
|
[<$chain RuntimeEvent>]::<N>::PolkadotXcm(
|
||||||
$crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Incomplete(weight, error) }
|
$crate::impls::pallet_xcm::Event::Attempted { outcome: $crate::impls::Outcome::Incomplete(weight, error) }
|
||||||
) => {
|
) => {
|
||||||
weight: $crate::impls::weight_within_threshold(
|
weight: $ignore_weight || $crate::impls::weight_within_threshold(
|
||||||
($crate::impls::REF_TIME_THRESHOLD, $crate::impls::PROOF_SIZE_THRESHOLD),
|
($crate::impls::REF_TIME_THRESHOLD, $crate::impls::PROOF_SIZE_THRESHOLD),
|
||||||
expected_weight.unwrap_or(*weight),
|
expected_weight.unwrap_or(*weight),
|
||||||
*weight
|
*weight
|
||||||
@@ -490,7 +490,7 @@ macro_rules! impl_assert_events_helpers_for_parachain {
|
|||||||
[<$chain RuntimeEvent>]::<N>::MessageQueue($crate::impls::pallet_message_queue::Event::Processed {
|
[<$chain RuntimeEvent>]::<N>::MessageQueue($crate::impls::pallet_message_queue::Event::Processed {
|
||||||
success: true, weight_used: weight, ..
|
success: true, weight_used: weight, ..
|
||||||
}) => {
|
}) => {
|
||||||
weight: $crate::impls::weight_within_threshold(
|
weight: $ignore_weight || $crate::impls::weight_within_threshold(
|
||||||
($crate::impls::REF_TIME_THRESHOLD, $crate::impls::PROOF_SIZE_THRESHOLD),
|
($crate::impls::REF_TIME_THRESHOLD, $crate::impls::PROOF_SIZE_THRESHOLD),
|
||||||
expected_weight.unwrap_or(*weight),
|
expected_weight.unwrap_or(*weight),
|
||||||
*weight
|
*weight
|
||||||
@@ -510,7 +510,7 @@ macro_rules! impl_assert_events_helpers_for_parachain {
|
|||||||
[<$chain RuntimeEvent>]::<N>::MessageQueue($crate::impls::pallet_message_queue::Event::Processed {
|
[<$chain RuntimeEvent>]::<N>::MessageQueue($crate::impls::pallet_message_queue::Event::Processed {
|
||||||
success: false, weight_used: weight, ..
|
success: false, weight_used: weight, ..
|
||||||
}) => {
|
}) => {
|
||||||
weight: $crate::impls::weight_within_threshold(
|
weight: $ignore_weight || $crate::impls::weight_within_threshold(
|
||||||
($crate::impls::REF_TIME_THRESHOLD, $crate::impls::PROOF_SIZE_THRESHOLD),
|
($crate::impls::REF_TIME_THRESHOLD, $crate::impls::PROOF_SIZE_THRESHOLD),
|
||||||
expected_weight.unwrap_or(*weight),
|
expected_weight.unwrap_or(*weight),
|
||||||
*weight
|
*weight
|
||||||
@@ -541,7 +541,7 @@ macro_rules! impl_assert_events_helpers_for_parachain {
|
|||||||
vec![
|
vec![
|
||||||
[<$chain RuntimeEvent>]::<N>::MessageQueue($crate::impls::pallet_message_queue::Event::Processed { success: true, weight_used: weight, .. }
|
[<$chain RuntimeEvent>]::<N>::MessageQueue($crate::impls::pallet_message_queue::Event::Processed { success: true, weight_used: weight, .. }
|
||||||
) => {
|
) => {
|
||||||
weight: $crate::impls::weight_within_threshold(
|
weight: $ignore_weight || $crate::impls::weight_within_threshold(
|
||||||
($crate::impls::REF_TIME_THRESHOLD, $crate::impls::PROOF_SIZE_THRESHOLD),
|
($crate::impls::REF_TIME_THRESHOLD, $crate::impls::PROOF_SIZE_THRESHOLD),
|
||||||
expected_weight.unwrap_or(*weight),
|
expected_weight.unwrap_or(*weight),
|
||||||
*weight
|
*weight
|
||||||
@@ -556,7 +556,7 @@ macro_rules! impl_assert_events_helpers_for_parachain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! impl_assets_helpers_for_system_parachain {
|
macro_rules! impl_assets_helpers_for_parachain {
|
||||||
( $chain:ident, $relay_chain:ident ) => {
|
( $chain:ident, $relay_chain:ident ) => {
|
||||||
$crate::impls::paste::paste! {
|
$crate::impls::paste::paste! {
|
||||||
impl<N: $crate::impls::Network> $chain<N> {
|
impl<N: $crate::impls::Network> $chain<N> {
|
||||||
|
|||||||
+3
-1
@@ -17,6 +17,7 @@ frame-support = { path = "../../../../../../../substrate/frame/support", default
|
|||||||
pallet-balances = { path = "../../../../../../../substrate/frame/balances", default-features = false}
|
pallet-balances = { path = "../../../../../../../substrate/frame/balances", default-features = false}
|
||||||
pallet-assets = { path = "../../../../../../../substrate/frame/assets", default-features = false}
|
pallet-assets = { path = "../../../../../../../substrate/frame/assets", default-features = false}
|
||||||
pallet-asset-conversion = { path = "../../../../../../../substrate/frame/asset-conversion", default-features = false}
|
pallet-asset-conversion = { path = "../../../../../../../substrate/frame/asset-conversion", default-features = false}
|
||||||
|
pallet-message-queue = { path = "../../../../../../../substrate/frame/message-queue", default-features = false }
|
||||||
|
|
||||||
# Polkadot
|
# Polkadot
|
||||||
xcm = { package = "staging-xcm", path = "../../../../../../../polkadot/xcm", default-features = false}
|
xcm = { package = "staging-xcm", path = "../../../../../../../polkadot/xcm", default-features = false}
|
||||||
@@ -28,5 +29,6 @@ rococo-runtime = { path = "../../../../../../../polkadot/runtime/rococo" }
|
|||||||
asset-test-utils = { path = "../../../../../runtimes/assets/test-utils" }
|
asset-test-utils = { path = "../../../../../runtimes/assets/test-utils" }
|
||||||
parachains-common = { path = "../../../../../../parachains/common" }
|
parachains-common = { path = "../../../../../../parachains/common" }
|
||||||
asset-hub-rococo-runtime = { path = "../../../../../runtimes/assets/asset-hub-rococo" }
|
asset-hub-rococo-runtime = { path = "../../../../../runtimes/assets/asset-hub-rococo" }
|
||||||
emulated-integration-tests-common = { path = "../../../common", default-features = false}
|
emulated-integration-tests-common = { path = "../../../common", default-features = false }
|
||||||
|
penpal-runtime = { path = "../../../../../runtimes/testing/penpal" }
|
||||||
rococo-system-emulated-network ={ path = "../../../networks/rococo-system" }
|
rococo-system-emulated-network ={ path = "../../../networks/rococo-system" }
|
||||||
|
|||||||
+14
-11
@@ -61,18 +61,20 @@ pub const ASSET_MIN_BALANCE: u128 = 1000;
|
|||||||
pub const ASSETS_PALLET_ID: u8 = 50;
|
pub const ASSETS_PALLET_ID: u8 = 50;
|
||||||
|
|
||||||
pub type RelayToSystemParaTest = Test<Rococo, AssetHubRococo>;
|
pub type RelayToSystemParaTest = Test<Rococo, AssetHubRococo>;
|
||||||
|
pub type RelayToParaTest = Test<Rococo, PenpalA>;
|
||||||
pub type SystemParaToRelayTest = Test<AssetHubRococo, Rococo>;
|
pub type SystemParaToRelayTest = Test<AssetHubRococo, Rococo>;
|
||||||
pub type SystemParaToParaTest = Test<AssetHubRococo, PenpalA>;
|
pub type SystemParaToParaTest = Test<AssetHubRococo, PenpalA>;
|
||||||
|
pub type ParaToSystemParaTest = Test<PenpalA, AssetHubRococo>;
|
||||||
|
|
||||||
/// Returns a `TestArgs` instance to de used for the Relay Chain accross integraton tests
|
/// Returns a `TestArgs` instance to be used for the Relay Chain across integration tests
|
||||||
pub fn relay_test_args(amount: Balance) -> TestArgs {
|
pub fn relay_test_args(
|
||||||
|
dest: MultiLocation,
|
||||||
|
beneficiary_id: AccountId32,
|
||||||
|
amount: Balance,
|
||||||
|
) -> TestArgs {
|
||||||
TestArgs {
|
TestArgs {
|
||||||
dest: Rococo::child_location_of(AssetHubRococo::para_id()),
|
dest,
|
||||||
beneficiary: AccountId32Junction {
|
beneficiary: AccountId32Junction { network: None, id: beneficiary_id.into() }.into(),
|
||||||
network: None,
|
|
||||||
id: AssetHubRococoReceiver::get().into(),
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
amount,
|
amount,
|
||||||
assets: (Here, amount).into(),
|
assets: (Here, amount).into(),
|
||||||
asset_id: None,
|
asset_id: None,
|
||||||
@@ -81,13 +83,14 @@ pub fn relay_test_args(amount: Balance) -> TestArgs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a `TestArgs` instance to de used for the System Parachain accross integraton tests
|
/// Returns a `TestArgs` instance to be used by parachains across integration tests
|
||||||
pub fn system_para_test_args(
|
pub fn para_test_args(
|
||||||
dest: MultiLocation,
|
dest: MultiLocation,
|
||||||
beneficiary_id: AccountId32,
|
beneficiary_id: AccountId32,
|
||||||
amount: Balance,
|
amount: Balance,
|
||||||
assets: MultiAssets,
|
assets: MultiAssets,
|
||||||
asset_id: Option<u32>,
|
asset_id: Option<u32>,
|
||||||
|
fee_asset_item: u32,
|
||||||
) -> TestArgs {
|
) -> TestArgs {
|
||||||
TestArgs {
|
TestArgs {
|
||||||
dest,
|
dest,
|
||||||
@@ -95,7 +98,7 @@ pub fn system_para_test_args(
|
|||||||
amount,
|
amount,
|
||||||
assets,
|
assets,
|
||||||
asset_id,
|
asset_id,
|
||||||
fee_asset_item: 0,
|
fee_asset_item,
|
||||||
weight_limit: WeightLimit::Unlimited,
|
weight_limit: WeightLimit::Unlimited,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+310
-247
@@ -15,37 +15,45 @@
|
|||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use asset_hub_rococo_runtime::xcm_config::XcmConfig as AssetHubRococoXcmConfig;
|
use asset_hub_rococo_runtime::xcm_config::XcmConfig as AssetHubRococoXcmConfig;
|
||||||
|
use penpal_runtime::xcm_config::XcmConfig as PenpalRococoXcmConfig;
|
||||||
use rococo_runtime::xcm_config::XcmConfig as RococoXcmConfig;
|
use rococo_runtime::xcm_config::XcmConfig as RococoXcmConfig;
|
||||||
|
|
||||||
fn relay_origin_assertions(t: RelayToSystemParaTest) {
|
fn relay_to_para_sender_assertions(t: RelayToParaTest) {
|
||||||
type RuntimeEvent = <Rococo as Chain>::RuntimeEvent;
|
type RuntimeEvent = <Rococo as Chain>::RuntimeEvent;
|
||||||
|
|
||||||
Rococo::assert_xcm_pallet_attempted_complete(Some(Weight::from_parts(630_092_000, 6_196)));
|
Rococo::assert_xcm_pallet_attempted_complete(Some(Weight::from_parts(864_610_000, 8_799)));
|
||||||
|
|
||||||
assert_expected_events!(
|
assert_expected_events!(
|
||||||
Rococo,
|
Rococo,
|
||||||
vec![
|
vec![
|
||||||
// Amount to reserve transfer is transferred to System Parachain's Sovereign account
|
// Amount to reserve transfer is transferred to Parachain's Sovereign account
|
||||||
RuntimeEvent::Balances(pallet_balances::Event::Transfer { from, to, amount }) => {
|
RuntimeEvent::Balances(
|
||||||
|
pallet_balances::Event::Transfer { from, to, amount }
|
||||||
|
) => {
|
||||||
from: *from == t.sender.account_id,
|
from: *from == t.sender.account_id,
|
||||||
to: *to == Rococo::sovereign_account_id_of(
|
to: *to == Rococo::sovereign_account_id_of(
|
||||||
t.args.dest
|
t.args.dest
|
||||||
),
|
),
|
||||||
amount: *amount == t.args.amount,
|
amount: *amount == t.args.amount,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn system_para_dest_assertions_incomplete(_t: RelayToSystemParaTest) {
|
fn relay_to_para_receiver_assertions<Test>(_: Test) {
|
||||||
AssetHubRococo::assert_dmp_queue_incomplete(Some(Weight::from_parts(57_185_000, 3504)));
|
type RuntimeEvent = <PenpalA as Chain>::RuntimeEvent;
|
||||||
|
assert_expected_events!(
|
||||||
|
PenpalA,
|
||||||
|
vec![
|
||||||
|
RuntimeEvent::Balances(pallet_balances::Event::Deposit { .. }) => {},
|
||||||
|
RuntimeEvent::MessageQueue(
|
||||||
|
pallet_message_queue::Event::Processed { success: true, .. }
|
||||||
|
) => {},
|
||||||
|
]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn system_para_to_relay_assertions(_t: SystemParaToRelayTest) {
|
fn system_para_to_para_sender_assertions(t: SystemParaToParaTest) {
|
||||||
AssetHubRococo::assert_xcm_pallet_attempted_error(Some(XcmError::Barrier))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn system_para_to_para_assertions(t: SystemParaToParaTest) {
|
|
||||||
type RuntimeEvent = <AssetHubRococo as Chain>::RuntimeEvent;
|
type RuntimeEvent = <AssetHubRococo as Chain>::RuntimeEvent;
|
||||||
|
|
||||||
AssetHubRococo::assert_xcm_pallet_attempted_complete(Some(Weight::from_parts(
|
AssetHubRococo::assert_xcm_pallet_attempted_complete(Some(Weight::from_parts(
|
||||||
@@ -56,7 +64,7 @@ fn system_para_to_para_assertions(t: SystemParaToParaTest) {
|
|||||||
assert_expected_events!(
|
assert_expected_events!(
|
||||||
AssetHubRococo,
|
AssetHubRococo,
|
||||||
vec![
|
vec![
|
||||||
// Amount to reserve transfer is transferred to Parachain's Sovereing account
|
// Amount to reserve transfer is transferred to Parachain's Sovereign account
|
||||||
RuntimeEvent::Balances(
|
RuntimeEvent::Balances(
|
||||||
pallet_balances::Event::Transfer { from, to, amount }
|
pallet_balances::Event::Transfer { from, to, amount }
|
||||||
) => {
|
) => {
|
||||||
@@ -70,7 +78,64 @@ fn system_para_to_para_assertions(t: SystemParaToParaTest) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn system_para_to_para_assets_assertions(t: SystemParaToParaTest) {
|
fn system_para_to_para_receiver_assertions<Test>(_: Test) {
|
||||||
|
type RuntimeEvent = <PenpalA as Chain>::RuntimeEvent;
|
||||||
|
assert_expected_events!(
|
||||||
|
PenpalA,
|
||||||
|
vec![
|
||||||
|
RuntimeEvent::Balances(pallet_balances::Event::Deposit { .. }) => {},
|
||||||
|
RuntimeEvent::MessageQueue(
|
||||||
|
pallet_message_queue::Event::Processed { success: true, .. }
|
||||||
|
) => {},
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn para_to_system_para_sender_assertions(t: ParaToSystemParaTest) {
|
||||||
|
type RuntimeEvent = <PenpalA as Chain>::RuntimeEvent;
|
||||||
|
|
||||||
|
PenpalA::assert_xcm_pallet_attempted_complete(Some(Weight::from_parts(864_610_000, 8_799)));
|
||||||
|
|
||||||
|
assert_expected_events!(
|
||||||
|
PenpalA,
|
||||||
|
vec![
|
||||||
|
// Amount to reserve transfer is transferred to Parachain's Sovereign account
|
||||||
|
RuntimeEvent::Balances(
|
||||||
|
pallet_balances::Event::Withdraw { who, amount }
|
||||||
|
) => {
|
||||||
|
who: *who == t.sender.account_id,
|
||||||
|
amount: *amount == t.args.amount,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn para_to_system_para_receiver_assertions(t: ParaToSystemParaTest) {
|
||||||
|
type RuntimeEvent = <AssetHubRococo as Chain>::RuntimeEvent;
|
||||||
|
|
||||||
|
let sov_penpal_on_ahr = AssetHubRococo::sovereign_account_id_of(
|
||||||
|
AssetHubRococo::sibling_location_of(PenpalA::para_id()),
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_expected_events!(
|
||||||
|
AssetHubRococo,
|
||||||
|
vec![
|
||||||
|
// Amount to reserve transfer is transferred to Parachain's Sovereign account
|
||||||
|
RuntimeEvent::Balances(
|
||||||
|
pallet_balances::Event::Withdraw { who, amount }
|
||||||
|
) => {
|
||||||
|
who: *who == sov_penpal_on_ahr.clone().into(),
|
||||||
|
amount: *amount == t.args.amount,
|
||||||
|
},
|
||||||
|
RuntimeEvent::Balances(pallet_balances::Event::Deposit { .. }) => {},
|
||||||
|
RuntimeEvent::MessageQueue(
|
||||||
|
pallet_message_queue::Event::Processed { success: true, .. }
|
||||||
|
) => {},
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn system_para_to_para_assets_sender_assertions(t: SystemParaToParaTest) {
|
||||||
type RuntimeEvent = <AssetHubRococo as Chain>::RuntimeEvent;
|
type RuntimeEvent = <AssetHubRococo as Chain>::RuntimeEvent;
|
||||||
|
|
||||||
AssetHubRococo::assert_xcm_pallet_attempted_complete(Some(Weight::from_parts(
|
AssetHubRococo::assert_xcm_pallet_attempted_complete(Some(Weight::from_parts(
|
||||||
@@ -81,7 +146,7 @@ fn system_para_to_para_assets_assertions(t: SystemParaToParaTest) {
|
|||||||
assert_expected_events!(
|
assert_expected_events!(
|
||||||
AssetHubRococo,
|
AssetHubRococo,
|
||||||
vec![
|
vec![
|
||||||
// Amount to reserve transfer is transferred to Parachain's Sovereing account
|
// Amount to reserve transfer is transferred to Parachain's Sovereign account
|
||||||
RuntimeEvent::Assets(
|
RuntimeEvent::Assets(
|
||||||
pallet_assets::Event::Transferred { asset_id, from, to, amount }
|
pallet_assets::Event::Transferred { asset_id, from, to, amount }
|
||||||
) => {
|
) => {
|
||||||
@@ -96,7 +161,21 @@ fn system_para_to_para_assets_assertions(t: SystemParaToParaTest) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn relay_limited_reserve_transfer_assets(t: RelayToSystemParaTest) -> DispatchResult {
|
fn system_para_to_para_assets_receiver_assertions<Test>(_: Test) {
|
||||||
|
type RuntimeEvent = <PenpalA as Chain>::RuntimeEvent;
|
||||||
|
assert_expected_events!(
|
||||||
|
PenpalA,
|
||||||
|
vec![
|
||||||
|
RuntimeEvent::Balances(pallet_balances::Event::Deposit { .. }) => {},
|
||||||
|
RuntimeEvent::Assets(pallet_assets::Event::Issued { .. }) => {},
|
||||||
|
RuntimeEvent::MessageQueue(
|
||||||
|
pallet_message_queue::Event::Processed { success: true, .. }
|
||||||
|
) => {},
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn relay_to_para_limited_reserve_transfer_assets(t: RelayToParaTest) -> DispatchResult {
|
||||||
<Rococo as RococoPallet>::XcmPallet::limited_reserve_transfer_assets(
|
<Rococo as RococoPallet>::XcmPallet::limited_reserve_transfer_assets(
|
||||||
t.signed_origin,
|
t.signed_origin,
|
||||||
bx!(t.args.dest.into()),
|
bx!(t.args.dest.into()),
|
||||||
@@ -107,37 +186,6 @@ fn relay_limited_reserve_transfer_assets(t: RelayToSystemParaTest) -> DispatchRe
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn relay_reserve_transfer_assets(t: RelayToSystemParaTest) -> DispatchResult {
|
|
||||||
<Rococo as RococoPallet>::XcmPallet::reserve_transfer_assets(
|
|
||||||
t.signed_origin,
|
|
||||||
bx!(t.args.dest.into()),
|
|
||||||
bx!(t.args.beneficiary.into()),
|
|
||||||
bx!(t.args.assets.into()),
|
|
||||||
t.args.fee_asset_item,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn system_para_limited_reserve_transfer_assets(t: SystemParaToRelayTest) -> DispatchResult {
|
|
||||||
<AssetHubRococo as AssetHubRococoPallet>::PolkadotXcm::limited_reserve_transfer_assets(
|
|
||||||
t.signed_origin,
|
|
||||||
bx!(t.args.dest.into()),
|
|
||||||
bx!(t.args.beneficiary.into()),
|
|
||||||
bx!(t.args.assets.into()),
|
|
||||||
t.args.fee_asset_item,
|
|
||||||
t.args.weight_limit,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn system_para_reserve_transfer_assets(t: SystemParaToRelayTest) -> DispatchResult {
|
|
||||||
<AssetHubRococo as AssetHubRococoPallet>::PolkadotXcm::reserve_transfer_assets(
|
|
||||||
t.signed_origin,
|
|
||||||
bx!(t.args.dest.into()),
|
|
||||||
bx!(t.args.beneficiary.into()),
|
|
||||||
bx!(t.args.assets.into()),
|
|
||||||
t.args.fee_asset_item,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn system_para_to_para_limited_reserve_transfer_assets(t: SystemParaToParaTest) -> DispatchResult {
|
fn system_para_to_para_limited_reserve_transfer_assets(t: SystemParaToParaTest) -> DispatchResult {
|
||||||
<AssetHubRococo as AssetHubRococoPallet>::PolkadotXcm::limited_reserve_transfer_assets(
|
<AssetHubRococo as AssetHubRococoPallet>::PolkadotXcm::limited_reserve_transfer_assets(
|
||||||
t.signed_origin,
|
t.signed_origin,
|
||||||
@@ -149,183 +197,123 @@ fn system_para_to_para_limited_reserve_transfer_assets(t: SystemParaToParaTest)
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn system_para_to_para_reserve_transfer_assets(t: SystemParaToParaTest) -> DispatchResult {
|
fn para_to_system_para_limited_reserve_transfer_assets(t: ParaToSystemParaTest) -> DispatchResult {
|
||||||
<AssetHubRococo as AssetHubRococoPallet>::PolkadotXcm::reserve_transfer_assets(
|
<PenpalA as PenpalAPallet>::PolkadotXcm::limited_reserve_transfer_assets(
|
||||||
t.signed_origin,
|
t.signed_origin,
|
||||||
bx!(t.args.dest.into()),
|
bx!(t.args.dest.into()),
|
||||||
bx!(t.args.beneficiary.into()),
|
bx!(t.args.beneficiary.into()),
|
||||||
bx!(t.args.assets.into()),
|
bx!(t.args.assets.into()),
|
||||||
t.args.fee_asset_item,
|
t.args.fee_asset_item,
|
||||||
|
t.args.weight_limit,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Limited Reserve Transfers of native asset from Relay Chain to the System Parachain shouldn't
|
|
||||||
/// work
|
|
||||||
#[test]
|
|
||||||
fn limited_reserve_transfer_native_asset_from_relay_to_system_para_fails() {
|
|
||||||
// Init values for Relay Chain
|
|
||||||
let amount_to_send: Balance = ROCOCO_ED * 1000;
|
|
||||||
let test_args = TestContext {
|
|
||||||
sender: RococoSender::get(),
|
|
||||||
receiver: AssetHubRococoReceiver::get(),
|
|
||||||
args: relay_test_args(amount_to_send),
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut test = RelayToSystemParaTest::new(test_args);
|
|
||||||
|
|
||||||
let sender_balance_before = test.sender.balance;
|
|
||||||
let receiver_balance_before = test.receiver.balance;
|
|
||||||
|
|
||||||
test.set_assertion::<Rococo>(relay_origin_assertions);
|
|
||||||
test.set_assertion::<AssetHubRococo>(system_para_dest_assertions_incomplete);
|
|
||||||
test.set_dispatchable::<Rococo>(relay_limited_reserve_transfer_assets);
|
|
||||||
test.assert();
|
|
||||||
|
|
||||||
let delivery_fees = Rococo::execute_with(|| {
|
|
||||||
xcm_helpers::transfer_assets_delivery_fees::<
|
|
||||||
<RococoXcmConfig as xcm_executor::Config>::XcmSender,
|
|
||||||
>(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
|
|
||||||
});
|
|
||||||
|
|
||||||
let sender_balance_after = test.sender.balance;
|
|
||||||
let receiver_balance_after = test.receiver.balance;
|
|
||||||
|
|
||||||
assert_eq!(sender_balance_before - amount_to_send - delivery_fees, sender_balance_after);
|
|
||||||
assert_eq!(receiver_balance_before, receiver_balance_after);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Limited Reserve Transfers of native asset from System Parachain to Relay Chain shoudln't work
|
|
||||||
#[test]
|
|
||||||
fn limited_reserve_transfer_native_asset_from_system_para_to_relay_fails() {
|
|
||||||
// Init values for System Parachain
|
|
||||||
let destination = AssetHubRococo::parent_location();
|
|
||||||
let beneficiary_id = RococoReceiver::get();
|
|
||||||
let amount_to_send: Balance = ASSET_HUB_ROCOCO_ED * 1000;
|
|
||||||
let assets = (Parent, amount_to_send).into();
|
|
||||||
|
|
||||||
let test_args = TestContext {
|
|
||||||
sender: AssetHubRococoSender::get(),
|
|
||||||
receiver: RococoReceiver::get(),
|
|
||||||
args: system_para_test_args(destination, beneficiary_id, amount_to_send, assets, None),
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut test = SystemParaToRelayTest::new(test_args);
|
|
||||||
|
|
||||||
let sender_balance_before = test.sender.balance;
|
|
||||||
let receiver_balance_before = test.receiver.balance;
|
|
||||||
|
|
||||||
test.set_assertion::<AssetHubRococo>(system_para_to_relay_assertions);
|
|
||||||
test.set_dispatchable::<AssetHubRococo>(system_para_limited_reserve_transfer_assets);
|
|
||||||
test.assert();
|
|
||||||
|
|
||||||
let sender_balance_after = test.sender.balance;
|
|
||||||
let receiver_balance_after = test.receiver.balance;
|
|
||||||
|
|
||||||
assert_eq!(sender_balance_before, sender_balance_after);
|
|
||||||
assert_eq!(receiver_balance_before, receiver_balance_after);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reserve Transfers of native asset from Relay Chain to the System Parachain shouldn't work
|
/// Reserve Transfers of native asset from Relay Chain to the System Parachain shouldn't work
|
||||||
#[test]
|
#[test]
|
||||||
fn reserve_transfer_native_asset_from_relay_to_system_para_fails() {
|
fn reserve_transfer_native_asset_from_relay_to_system_para_fails() {
|
||||||
// Init values for Relay Chain
|
let signed_origin = <Rococo as Chain>::RuntimeOrigin::signed(RococoSender::get().into());
|
||||||
|
let destination = Rococo::child_location_of(AssetHubRococo::para_id());
|
||||||
|
let beneficiary: MultiLocation =
|
||||||
|
AccountId32Junction { network: None, id: AssetHubRococoReceiver::get().into() }.into();
|
||||||
let amount_to_send: Balance = ROCOCO_ED * 1000;
|
let amount_to_send: Balance = ROCOCO_ED * 1000;
|
||||||
let test_args = TestContext {
|
let assets: MultiAssets = (Here, amount_to_send).into();
|
||||||
sender: RococoSender::get(),
|
let fee_asset_item = 0;
|
||||||
receiver: AssetHubRococoReceiver::get(),
|
|
||||||
args: relay_test_args(amount_to_send),
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut test = RelayToSystemParaTest::new(test_args);
|
// this should fail
|
||||||
|
Rococo::execute_with(|| {
|
||||||
let sender_balance_before = test.sender.balance;
|
let result = <Rococo as RococoPallet>::XcmPallet::limited_reserve_transfer_assets(
|
||||||
let receiver_balance_before = test.receiver.balance;
|
signed_origin,
|
||||||
|
bx!(destination.into()),
|
||||||
test.set_assertion::<Rococo>(relay_origin_assertions);
|
bx!(beneficiary.into()),
|
||||||
test.set_assertion::<AssetHubRococo>(system_para_dest_assertions_incomplete);
|
bx!(assets.into()),
|
||||||
test.set_dispatchable::<Rococo>(relay_reserve_transfer_assets);
|
fee_asset_item,
|
||||||
test.assert();
|
WeightLimit::Unlimited,
|
||||||
|
);
|
||||||
let delivery_fees = Rococo::execute_with(|| {
|
assert_err!(
|
||||||
xcm_helpers::transfer_assets_delivery_fees::<
|
result,
|
||||||
<RococoXcmConfig as xcm_executor::Config>::XcmSender,
|
DispatchError::Module(sp_runtime::ModuleError {
|
||||||
>(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
|
index: 99,
|
||||||
|
error: [2, 0, 0, 0],
|
||||||
|
message: Some("Filtered")
|
||||||
|
})
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
let sender_balance_after = test.sender.balance;
|
|
||||||
let receiver_balance_after = test.receiver.balance;
|
|
||||||
|
|
||||||
assert_eq!(sender_balance_before - amount_to_send - delivery_fees, sender_balance_after);
|
|
||||||
assert_eq!(receiver_balance_before, receiver_balance_after);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reserve Transfers of native asset from System Parachain to Relay Chain shouldn't work
|
/// Reserve Transfers of native asset from System Parachain to Relay Chain shouldn't work
|
||||||
#[test]
|
#[test]
|
||||||
fn reserve_transfer_native_asset_from_system_para_to_relay_fails() {
|
fn reserve_transfer_native_asset_from_system_para_to_relay_fails() {
|
||||||
// Init values for System Parachain
|
// Init values for System Parachain
|
||||||
|
let signed_origin =
|
||||||
|
<AssetHubRococo as Chain>::RuntimeOrigin::signed(AssetHubRococoSender::get().into());
|
||||||
let destination = AssetHubRococo::parent_location();
|
let destination = AssetHubRococo::parent_location();
|
||||||
let beneficiary_id = RococoReceiver::get();
|
let beneficiary_id = RococoReceiver::get();
|
||||||
|
let beneficiary: MultiLocation =
|
||||||
|
AccountId32Junction { network: None, id: beneficiary_id.into() }.into();
|
||||||
let amount_to_send: Balance = ASSET_HUB_ROCOCO_ED * 1000;
|
let amount_to_send: Balance = ASSET_HUB_ROCOCO_ED * 1000;
|
||||||
let assets = (Parent, amount_to_send).into();
|
|
||||||
|
let assets: MultiAssets = (Parent, amount_to_send).into();
|
||||||
|
let fee_asset_item = 0;
|
||||||
|
|
||||||
|
// this should fail
|
||||||
|
AssetHubRococo::execute_with(|| {
|
||||||
|
let result =
|
||||||
|
<AssetHubRococo as AssetHubRococoPallet>::PolkadotXcm::limited_reserve_transfer_assets(
|
||||||
|
signed_origin,
|
||||||
|
bx!(destination.into()),
|
||||||
|
bx!(beneficiary.into()),
|
||||||
|
bx!(assets.into()),
|
||||||
|
fee_asset_item,
|
||||||
|
WeightLimit::Unlimited,
|
||||||
|
);
|
||||||
|
assert_err!(
|
||||||
|
result,
|
||||||
|
DispatchError::Module(sp_runtime::ModuleError {
|
||||||
|
index: 31,
|
||||||
|
error: [2, 0, 0, 0],
|
||||||
|
message: Some("Filtered")
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reserve Transfers of native asset from Relay to Parachain should work
|
||||||
|
#[test]
|
||||||
|
fn reserve_transfer_native_asset_from_relay_to_para() {
|
||||||
|
// Init values for Relay
|
||||||
|
let destination = Rococo::child_location_of(PenpalA::para_id());
|
||||||
|
let beneficiary_id = PenpalAReceiver::get();
|
||||||
|
let amount_to_send: Balance = ROCOCO_ED * 1000;
|
||||||
|
|
||||||
let test_args = TestContext {
|
let test_args = TestContext {
|
||||||
sender: AssetHubRococoSender::get(),
|
sender: RococoSender::get(),
|
||||||
receiver: RococoReceiver::get(),
|
receiver: PenpalAReceiver::get(),
|
||||||
args: system_para_test_args(destination, beneficiary_id, amount_to_send, assets, None),
|
args: relay_test_args(destination, beneficiary_id, amount_to_send),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut test = SystemParaToRelayTest::new(test_args);
|
let mut test = RelayToParaTest::new(test_args);
|
||||||
|
|
||||||
let sender_balance_before = test.sender.balance;
|
let sender_balance_before = test.sender.balance;
|
||||||
let receiver_balance_before = test.receiver.balance;
|
let receiver_balance_before = test.receiver.balance;
|
||||||
|
|
||||||
test.set_assertion::<AssetHubRococo>(system_para_to_relay_assertions);
|
test.set_assertion::<Rococo>(relay_to_para_sender_assertions);
|
||||||
test.set_dispatchable::<AssetHubRococo>(system_para_reserve_transfer_assets);
|
test.set_assertion::<PenpalA>(relay_to_para_receiver_assertions);
|
||||||
|
test.set_dispatchable::<Rococo>(relay_to_para_limited_reserve_transfer_assets);
|
||||||
test.assert();
|
test.assert();
|
||||||
|
|
||||||
|
let delivery_fees = Rococo::execute_with(|| {
|
||||||
|
xcm_helpers::transfer_assets_delivery_fees::<
|
||||||
|
<RococoXcmConfig as xcm_executor::Config>::XcmSender,
|
||||||
|
>(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
|
||||||
|
});
|
||||||
|
|
||||||
let sender_balance_after = test.sender.balance;
|
let sender_balance_after = test.sender.balance;
|
||||||
let receiver_balance_after = test.receiver.balance;
|
let receiver_balance_after = test.receiver.balance;
|
||||||
|
|
||||||
assert_eq!(sender_balance_before, sender_balance_after);
|
// Sender's balance is reduced
|
||||||
assert_eq!(receiver_balance_before, receiver_balance_after);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Limited Reserve Transfers of native asset from System Parachain to Parachain should work
|
|
||||||
#[test]
|
|
||||||
fn limited_reserve_transfer_native_asset_from_system_para_to_para() {
|
|
||||||
// Init values for System Parachain
|
|
||||||
let destination = AssetHubRococo::sibling_location_of(PenpalA::para_id());
|
|
||||||
let beneficiary_id = PenpalAReceiver::get();
|
|
||||||
let amount_to_send: Balance = ASSET_HUB_ROCOCO_ED * 1000;
|
|
||||||
let assets = (Parent, amount_to_send).into();
|
|
||||||
|
|
||||||
let test_args = TestContext {
|
|
||||||
sender: AssetHubRococoSender::get(),
|
|
||||||
receiver: PenpalAReceiver::get(),
|
|
||||||
args: system_para_test_args(destination, beneficiary_id, amount_to_send, assets, None),
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut test = SystemParaToParaTest::new(test_args);
|
|
||||||
|
|
||||||
let sender_balance_before = test.sender.balance;
|
|
||||||
|
|
||||||
test.set_assertion::<AssetHubRococo>(system_para_to_para_assertions);
|
|
||||||
// TODO: Add assertion for Penpal runtime. Right now message is failing with
|
|
||||||
// `UntrustedReserveLocation`
|
|
||||||
test.set_dispatchable::<AssetHubRococo>(system_para_to_para_limited_reserve_transfer_assets);
|
|
||||||
test.assert();
|
|
||||||
|
|
||||||
let sender_balance_after = test.sender.balance;
|
|
||||||
|
|
||||||
let delivery_fees = AssetHubRococo::execute_with(|| {
|
|
||||||
xcm_helpers::transfer_assets_delivery_fees::<
|
|
||||||
<AssetHubRococoXcmConfig as xcm_executor::Config>::XcmSender,
|
|
||||||
>(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
|
|
||||||
});
|
|
||||||
|
|
||||||
assert_eq!(sender_balance_before - amount_to_send - delivery_fees, sender_balance_after);
|
assert_eq!(sender_balance_before - amount_to_send - delivery_fees, sender_balance_after);
|
||||||
// TODO: Check receiver balance when Penpal runtime is improved to propery handle reserve
|
// Receiver's balance is increased
|
||||||
// transfers
|
assert!(receiver_balance_after > receiver_balance_before);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reserve Transfers of native asset from System Parachain to Parachain should work
|
/// Reserve Transfers of native asset from System Parachain to Parachain should work
|
||||||
@@ -340,20 +328,21 @@ fn reserve_transfer_native_asset_from_system_para_to_para() {
|
|||||||
let test_args = TestContext {
|
let test_args = TestContext {
|
||||||
sender: AssetHubRococoSender::get(),
|
sender: AssetHubRococoSender::get(),
|
||||||
receiver: PenpalAReceiver::get(),
|
receiver: PenpalAReceiver::get(),
|
||||||
args: system_para_test_args(destination, beneficiary_id, amount_to_send, assets, None),
|
args: para_test_args(destination, beneficiary_id, amount_to_send, assets, None, 0),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut test = SystemParaToParaTest::new(test_args);
|
let mut test = SystemParaToParaTest::new(test_args);
|
||||||
|
|
||||||
let sender_balance_before = test.sender.balance;
|
let sender_balance_before = test.sender.balance;
|
||||||
|
let receiver_balance_before = test.receiver.balance;
|
||||||
|
|
||||||
test.set_assertion::<AssetHubRococo>(system_para_to_para_assertions);
|
test.set_assertion::<AssetHubRococo>(system_para_to_para_sender_assertions);
|
||||||
// TODO: Add assertion for Penpal runtime. Right now message is failing with
|
test.set_assertion::<PenpalA>(system_para_to_para_receiver_assertions);
|
||||||
// `UntrustedReserveLocation`
|
test.set_dispatchable::<AssetHubRococo>(system_para_to_para_limited_reserve_transfer_assets);
|
||||||
test.set_dispatchable::<AssetHubRococo>(system_para_to_para_reserve_transfer_assets);
|
|
||||||
test.assert();
|
test.assert();
|
||||||
|
|
||||||
let sender_balance_after = test.sender.balance;
|
let sender_balance_after = test.sender.balance;
|
||||||
|
let receiver_balance_after = test.receiver.balance;
|
||||||
|
|
||||||
let delivery_fees = AssetHubRococo::execute_with(|| {
|
let delivery_fees = AssetHubRococo::execute_with(|| {
|
||||||
xcm_helpers::transfer_assets_delivery_fees::<
|
xcm_helpers::transfer_assets_delivery_fees::<
|
||||||
@@ -361,79 +350,153 @@ fn reserve_transfer_native_asset_from_system_para_to_para() {
|
|||||||
>(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
|
>(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Sender's balance is reduced
|
||||||
assert_eq!(sender_balance_before - amount_to_send - delivery_fees, sender_balance_after);
|
assert_eq!(sender_balance_before - amount_to_send - delivery_fees, sender_balance_after);
|
||||||
// TODO: Check receiver balance when Penpal runtime is improved to propery handle reserve
|
// Receiver's balance is increased
|
||||||
// transfers
|
assert!(receiver_balance_after > receiver_balance_before);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Limited Reserve Transfers of a local asset from System Parachain to Parachain should work
|
/// Reserve Transfers of native asset from Parachain to System Parachain should work
|
||||||
#[test]
|
#[test]
|
||||||
fn limited_reserve_transfer_asset_from_system_para_to_para() {
|
fn reserve_transfer_native_asset_from_para_to_system_para() {
|
||||||
// Force create asset from Relay Chain and mint assets for System Parachain's sender account
|
// Init values for Penpal Parachain
|
||||||
|
let destination = PenpalA::sibling_location_of(AssetHubRococo::para_id());
|
||||||
|
let beneficiary_id = AssetHubRococoReceiver::get();
|
||||||
|
let amount_to_send: Balance = ASSET_HUB_ROCOCO_ED * 1000;
|
||||||
|
let assets = (Parent, amount_to_send).into();
|
||||||
|
|
||||||
|
let test_args = TestContext {
|
||||||
|
sender: PenpalASender::get(),
|
||||||
|
receiver: AssetHubRococoReceiver::get(),
|
||||||
|
args: para_test_args(destination, beneficiary_id, amount_to_send, assets, None, 0),
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut test = ParaToSystemParaTest::new(test_args);
|
||||||
|
|
||||||
|
let sender_balance_before = test.sender.balance;
|
||||||
|
let receiver_balance_before = test.receiver.balance;
|
||||||
|
|
||||||
|
let penpal_location_as_seen_by_ahr = AssetHubRococo::sibling_location_of(PenpalA::para_id());
|
||||||
|
let sov_penpal_on_ahr = AssetHubRococo::sovereign_account_id_of(penpal_location_as_seen_by_ahr);
|
||||||
|
|
||||||
|
// fund the Penpal's SA on AHR with the native tokens held in reserve
|
||||||
|
AssetHubRococo::fund_accounts(vec![(sov_penpal_on_ahr.into(), amount_to_send * 2)]);
|
||||||
|
|
||||||
|
test.set_assertion::<PenpalA>(para_to_system_para_sender_assertions);
|
||||||
|
test.set_assertion::<AssetHubRococo>(para_to_system_para_receiver_assertions);
|
||||||
|
test.set_dispatchable::<PenpalA>(para_to_system_para_limited_reserve_transfer_assets);
|
||||||
|
test.assert();
|
||||||
|
|
||||||
|
let sender_balance_after = test.sender.balance;
|
||||||
|
let receiver_balance_after = test.receiver.balance;
|
||||||
|
|
||||||
|
let delivery_fees = PenpalA::execute_with(|| {
|
||||||
|
xcm_helpers::transfer_assets_delivery_fees::<
|
||||||
|
<PenpalRococoXcmConfig as xcm_executor::Config>::XcmSender,
|
||||||
|
>(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
|
||||||
|
});
|
||||||
|
|
||||||
|
// Sender's balance is reduced
|
||||||
|
assert_eq!(sender_balance_before - amount_to_send - delivery_fees, sender_balance_after);
|
||||||
|
// Receiver's balance is increased
|
||||||
|
assert!(receiver_balance_after > receiver_balance_before);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reserve Transfers of a local asset and native asset from System Parachain to Parachain should
|
||||||
|
/// work
|
||||||
|
#[test]
|
||||||
|
fn reserve_transfer_assets_from_system_para_to_para() {
|
||||||
|
// Force create asset on AssetHubRococo and PenpalA from Relay Chain
|
||||||
AssetHubRococo::force_create_and_mint_asset(
|
AssetHubRococo::force_create_and_mint_asset(
|
||||||
ASSET_ID,
|
ASSET_ID,
|
||||||
ASSET_MIN_BALANCE,
|
ASSET_MIN_BALANCE,
|
||||||
true,
|
false,
|
||||||
AssetHubRococoSender::get(),
|
AssetHubRococoSender::get(),
|
||||||
Some(Weight::from_parts(1_019_445_000, 200_000)),
|
Some(Weight::from_parts(1_019_445_000, 200_000)),
|
||||||
ASSET_MIN_BALANCE * 1000000,
|
ASSET_MIN_BALANCE * 1_000_000,
|
||||||
|
);
|
||||||
|
PenpalA::force_create_and_mint_asset(
|
||||||
|
ASSET_ID,
|
||||||
|
ASSET_MIN_BALANCE,
|
||||||
|
false,
|
||||||
|
PenpalASender::get(),
|
||||||
|
Some(Weight::from_parts(1_019_445_000, 200_000)),
|
||||||
|
0,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Init values for System Parachain
|
// Init values for System Parachain
|
||||||
let destination = AssetHubRococo::sibling_location_of(PenpalA::para_id());
|
let destination = AssetHubRococo::sibling_location_of(PenpalA::para_id());
|
||||||
let beneficiary_id = PenpalAReceiver::get();
|
let beneficiary_id = PenpalAReceiver::get();
|
||||||
let amount_to_send = ASSET_MIN_BALANCE * 1000;
|
let fee_amount_to_send = ASSET_HUB_ROCOCO_ED * 1000;
|
||||||
let assets =
|
let asset_amount_to_send = ASSET_MIN_BALANCE * 1000;
|
||||||
(X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), amount_to_send)
|
let assets: MultiAssets = vec![
|
||||||
.into();
|
(Parent, fee_amount_to_send).into(),
|
||||||
|
(X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), asset_amount_to_send)
|
||||||
|
.into(),
|
||||||
|
]
|
||||||
|
.into();
|
||||||
|
let fee_asset_index = assets
|
||||||
|
.inner()
|
||||||
|
.iter()
|
||||||
|
.position(|r| r == &(Parent, fee_amount_to_send).into())
|
||||||
|
.unwrap() as u32;
|
||||||
|
|
||||||
let system_para_test_args = TestContext {
|
let para_test_args = TestContext {
|
||||||
sender: AssetHubRococoSender::get(),
|
sender: AssetHubRococoSender::get(),
|
||||||
receiver: PenpalAReceiver::get(),
|
receiver: PenpalAReceiver::get(),
|
||||||
args: system_para_test_args(destination, beneficiary_id, amount_to_send, assets, None),
|
args: para_test_args(
|
||||||
|
destination,
|
||||||
|
beneficiary_id,
|
||||||
|
asset_amount_to_send,
|
||||||
|
assets,
|
||||||
|
None,
|
||||||
|
fee_asset_index,
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut system_para_test = SystemParaToParaTest::new(system_para_test_args);
|
let mut test = SystemParaToParaTest::new(para_test_args);
|
||||||
|
|
||||||
system_para_test.set_assertion::<AssetHubRococo>(system_para_to_para_assets_assertions);
|
// Create SA-of-Penpal-on-AHR with ED.
|
||||||
// TODO: Add assertions when Penpal is able to manage assets
|
let penpal_location = AssetHubRococo::sibling_location_of(PenpalA::para_id());
|
||||||
system_para_test
|
let sov_penpal_on_ahr = AssetHubRococo::sovereign_account_id_of(penpal_location);
|
||||||
.set_dispatchable::<AssetHubRococo>(system_para_to_para_limited_reserve_transfer_assets);
|
AssetHubRococo::fund_accounts(vec![(sov_penpal_on_ahr.into(), ROCOCO_ED)]);
|
||||||
system_para_test.assert();
|
|
||||||
}
|
let sender_balance_before = test.sender.balance;
|
||||||
|
let receiver_balance_before = test.receiver.balance;
|
||||||
/// Reserve Transfers of a local asset from System Parachain to Parachain should work
|
|
||||||
#[test]
|
let sender_assets_before = AssetHubRococo::execute_with(|| {
|
||||||
fn reserve_transfer_asset_from_system_para_to_para() {
|
type Assets = <AssetHubRococo as AssetHubRococoPallet>::Assets;
|
||||||
// Force create asset from Relay Chain and mint assets for System Parachain's sender account
|
<Assets as Inspect<_>>::balance(ASSET_ID, &AssetHubRococoSender::get())
|
||||||
AssetHubRococo::force_create_and_mint_asset(
|
});
|
||||||
ASSET_ID,
|
let receiver_assets_before = PenpalA::execute_with(|| {
|
||||||
ASSET_MIN_BALANCE,
|
type Assets = <PenpalA as PenpalAPallet>::Assets;
|
||||||
true,
|
<Assets as Inspect<_>>::balance(ASSET_ID, &PenpalAReceiver::get())
|
||||||
AssetHubRococoSender::get(),
|
});
|
||||||
Some(Weight::from_parts(1_019_445_000, 200_000)),
|
|
||||||
ASSET_MIN_BALANCE * 1000000,
|
test.set_assertion::<AssetHubRococo>(system_para_to_para_assets_sender_assertions);
|
||||||
);
|
test.set_assertion::<PenpalA>(system_para_to_para_assets_receiver_assertions);
|
||||||
|
test.set_dispatchable::<AssetHubRococo>(system_para_to_para_limited_reserve_transfer_assets);
|
||||||
// Init values for System Parachain
|
test.assert();
|
||||||
let destination = AssetHubRococo::sibling_location_of(PenpalA::para_id());
|
|
||||||
let beneficiary_id = PenpalAReceiver::get();
|
let sender_balance_after = test.sender.balance;
|
||||||
let amount_to_send = ASSET_MIN_BALANCE * 1000;
|
let receiver_balance_after = test.receiver.balance;
|
||||||
let assets =
|
|
||||||
(X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), amount_to_send)
|
// Sender's balance is reduced
|
||||||
.into();
|
assert!(sender_balance_after < sender_balance_before);
|
||||||
|
// Receiver's balance is increased
|
||||||
let system_para_test_args = TestContext {
|
assert!(receiver_balance_after > receiver_balance_before);
|
||||||
sender: AssetHubRococoSender::get(),
|
|
||||||
receiver: PenpalAReceiver::get(),
|
let sender_assets_after = AssetHubRococo::execute_with(|| {
|
||||||
args: system_para_test_args(destination, beneficiary_id, amount_to_send, assets, None),
|
type Assets = <AssetHubRococo as AssetHubRococoPallet>::Assets;
|
||||||
};
|
<Assets as Inspect<_>>::balance(ASSET_ID, &AssetHubRococoSender::get())
|
||||||
|
});
|
||||||
let mut system_para_test = SystemParaToParaTest::new(system_para_test_args);
|
let receiver_assets_after = PenpalA::execute_with(|| {
|
||||||
|
type Assets = <PenpalA as PenpalAPallet>::Assets;
|
||||||
system_para_test.set_assertion::<AssetHubRococo>(system_para_to_para_assets_assertions);
|
<Assets as Inspect<_>>::balance(ASSET_ID, &PenpalAReceiver::get())
|
||||||
// TODO: Add assertions when Penpal is able to manage assets
|
});
|
||||||
system_para_test
|
|
||||||
.set_dispatchable::<AssetHubRococo>(system_para_to_para_reserve_transfer_assets);
|
// Sender's balance is reduced
|
||||||
system_para_test.assert();
|
assert_eq!(sender_assets_before - asset_amount_to_send, sender_assets_after);
|
||||||
|
// Receiver's balance is increased
|
||||||
|
assert!(receiver_assets_after > receiver_assets_before);
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-7
@@ -51,7 +51,7 @@ fn relay_dest_assertions(t: SystemParaToRelayTest) {
|
|||||||
assert_expected_events!(
|
assert_expected_events!(
|
||||||
Rococo,
|
Rococo,
|
||||||
vec![
|
vec![
|
||||||
// Amount is witdrawn from Relay Chain's `CheckAccount`
|
// Amount is withdrawn from Relay Chain's `CheckAccount`
|
||||||
RuntimeEvent::Balances(pallet_balances::Event::Withdraw { who, amount }) => {
|
RuntimeEvent::Balances(pallet_balances::Event::Withdraw { who, amount }) => {
|
||||||
who: *who == <Rococo as RococoPallet>::XcmPallet::check_account(),
|
who: *who == <Rococo as RococoPallet>::XcmPallet::check_account(),
|
||||||
amount: *amount == t.args.amount,
|
amount: *amount == t.args.amount,
|
||||||
@@ -157,10 +157,12 @@ fn system_para_teleport_assets(t: SystemParaToRelayTest) -> DispatchResult {
|
|||||||
fn limited_teleport_native_assets_from_relay_to_system_para_works() {
|
fn limited_teleport_native_assets_from_relay_to_system_para_works() {
|
||||||
// Init values for Relay Chain
|
// Init values for Relay Chain
|
||||||
let amount_to_send: Balance = ROCOCO_ED * 1000;
|
let amount_to_send: Balance = ROCOCO_ED * 1000;
|
||||||
|
let dest = Rococo::child_location_of(AssetHubRococo::para_id());
|
||||||
|
let beneficiary_id = AssetHubRococoReceiver::get();
|
||||||
let test_args = TestContext {
|
let test_args = TestContext {
|
||||||
sender: RococoSender::get(),
|
sender: RococoSender::get(),
|
||||||
receiver: AssetHubRococoReceiver::get(),
|
receiver: AssetHubRococoReceiver::get(),
|
||||||
args: relay_test_args(amount_to_send),
|
args: relay_test_args(dest, beneficiary_id, amount_to_send),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut test = RelayToSystemParaTest::new(test_args);
|
let mut test = RelayToSystemParaTest::new(test_args);
|
||||||
@@ -204,7 +206,7 @@ fn limited_teleport_native_assets_back_from_system_para_to_relay_works() {
|
|||||||
let test_args = TestContext {
|
let test_args = TestContext {
|
||||||
sender: AssetHubRococoSender::get(),
|
sender: AssetHubRococoSender::get(),
|
||||||
receiver: RococoReceiver::get(),
|
receiver: RococoReceiver::get(),
|
||||||
args: system_para_test_args(destination, beneficiary_id, amount_to_send, assets, None),
|
args: para_test_args(destination, beneficiary_id, amount_to_send, assets, None, 0),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut test = SystemParaToRelayTest::new(test_args);
|
let mut test = SystemParaToRelayTest::new(test_args);
|
||||||
@@ -245,7 +247,7 @@ fn limited_teleport_native_assets_from_system_para_to_relay_fails() {
|
|||||||
let test_args = TestContext {
|
let test_args = TestContext {
|
||||||
sender: AssetHubRococoSender::get(),
|
sender: AssetHubRococoSender::get(),
|
||||||
receiver: RococoReceiver::get(),
|
receiver: RococoReceiver::get(),
|
||||||
args: system_para_test_args(destination, beneficiary_id, amount_to_send, assets, None),
|
args: para_test_args(destination, beneficiary_id, amount_to_send, assets, None, 0),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut test = SystemParaToRelayTest::new(test_args);
|
let mut test = SystemParaToRelayTest::new(test_args);
|
||||||
@@ -278,10 +280,12 @@ fn limited_teleport_native_assets_from_system_para_to_relay_fails() {
|
|||||||
fn teleport_native_assets_from_relay_to_system_para_works() {
|
fn teleport_native_assets_from_relay_to_system_para_works() {
|
||||||
// Init values for Relay Chain
|
// Init values for Relay Chain
|
||||||
let amount_to_send: Balance = ROCOCO_ED * 1000;
|
let amount_to_send: Balance = ROCOCO_ED * 1000;
|
||||||
|
let dest = Rococo::child_location_of(AssetHubRococo::para_id());
|
||||||
|
let beneficiary_id = AssetHubRococoReceiver::get();
|
||||||
let test_args = TestContext {
|
let test_args = TestContext {
|
||||||
sender: RococoSender::get(),
|
sender: RococoSender::get(),
|
||||||
receiver: AssetHubRococoReceiver::get(),
|
receiver: AssetHubRococoReceiver::get(),
|
||||||
args: relay_test_args(amount_to_send),
|
args: relay_test_args(dest, beneficiary_id, amount_to_send),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut test = RelayToSystemParaTest::new(test_args);
|
let mut test = RelayToSystemParaTest::new(test_args);
|
||||||
@@ -325,7 +329,7 @@ fn teleport_native_assets_back_from_system_para_to_relay_works() {
|
|||||||
let test_args = TestContext {
|
let test_args = TestContext {
|
||||||
sender: AssetHubRococoSender::get(),
|
sender: AssetHubRococoSender::get(),
|
||||||
receiver: RococoReceiver::get(),
|
receiver: RococoReceiver::get(),
|
||||||
args: system_para_test_args(destination, beneficiary_id, amount_to_send, assets, None),
|
args: para_test_args(destination, beneficiary_id, amount_to_send, assets, None, 0),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut test = SystemParaToRelayTest::new(test_args);
|
let mut test = SystemParaToRelayTest::new(test_args);
|
||||||
@@ -366,7 +370,7 @@ fn teleport_native_assets_from_system_para_to_relay_fails() {
|
|||||||
let test_args = TestContext {
|
let test_args = TestContext {
|
||||||
sender: AssetHubRococoSender::get(),
|
sender: AssetHubRococoSender::get(),
|
||||||
receiver: RococoReceiver::get(),
|
receiver: RococoReceiver::get(),
|
||||||
args: system_para_test_args(destination, beneficiary_id, amount_to_send, assets, None),
|
args: para_test_args(destination, beneficiary_id, amount_to_send, assets, None, 0),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut test = SystemParaToRelayTest::new(test_args);
|
let mut test = SystemParaToRelayTest::new(test_args);
|
||||||
|
|||||||
+2
-2
@@ -65,7 +65,7 @@ pub type RelayToSystemParaTest = Test<Westend, AssetHubWestend>;
|
|||||||
pub type SystemParaToRelayTest = Test<AssetHubWestend, Westend>;
|
pub type SystemParaToRelayTest = Test<AssetHubWestend, Westend>;
|
||||||
pub type SystemParaToParaTest = Test<AssetHubWestend, PenpalA>;
|
pub type SystemParaToParaTest = Test<AssetHubWestend, PenpalA>;
|
||||||
|
|
||||||
/// Returns a `TestArgs` instance to de used for the Relay Chain accross integraton tests
|
/// Returns a `TestArgs` instance to be used for the Relay Chain across integration tests
|
||||||
pub fn relay_test_args(amount: Balance) -> TestArgs {
|
pub fn relay_test_args(amount: Balance) -> TestArgs {
|
||||||
TestArgs {
|
TestArgs {
|
||||||
dest: Westend::child_location_of(AssetHubWestend::para_id()),
|
dest: Westend::child_location_of(AssetHubWestend::para_id()),
|
||||||
@@ -82,7 +82,7 @@ pub fn relay_test_args(amount: Balance) -> TestArgs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a `TestArgs` instance to de used for the System Parachain accross integraton tests
|
/// Returns a `TestArgs` instance to be used for the System Parachain across integration tests
|
||||||
pub fn system_para_test_args(
|
pub fn system_para_test_args(
|
||||||
dest: MultiLocation,
|
dest: MultiLocation,
|
||||||
beneficiary_id: AccountId32,
|
beneficiary_id: AccountId32,
|
||||||
|
|||||||
+74
-281
@@ -15,37 +15,8 @@
|
|||||||
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use asset_hub_westend_runtime::xcm_config::XcmConfig;
|
use asset_hub_westend_runtime::xcm_config::XcmConfig;
|
||||||
use westend_runtime::xcm_config::XcmConfig as WestendXcmConfig;
|
|
||||||
|
|
||||||
fn relay_origin_assertions(t: RelayToSystemParaTest) {
|
fn system_para_to_para_sender_assertions(t: SystemParaToParaTest) {
|
||||||
type RuntimeEvent = <Westend as Chain>::RuntimeEvent;
|
|
||||||
|
|
||||||
Westend::assert_xcm_pallet_attempted_complete(Some(Weight::from_parts(629_384_000, 6_196)));
|
|
||||||
|
|
||||||
assert_expected_events!(
|
|
||||||
Westend,
|
|
||||||
vec![
|
|
||||||
// Amount to reserve transfer is transferred to System Parachain's Sovereign account
|
|
||||||
RuntimeEvent::Balances(pallet_balances::Event::Transfer { from, to, amount }) => {
|
|
||||||
from: *from == t.sender.account_id,
|
|
||||||
to: *to == Westend::sovereign_account_id_of(
|
|
||||||
t.args.dest
|
|
||||||
),
|
|
||||||
amount: *amount == t.args.amount,
|
|
||||||
},
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn system_para_dest_assertions(_t: RelayToSystemParaTest) {
|
|
||||||
AssetHubWestend::assert_dmp_queue_incomplete(Some(Weight::from_parts(31_352_000, 1489)));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn system_para_to_relay_assertions(_t: SystemParaToRelayTest) {
|
|
||||||
AssetHubWestend::assert_xcm_pallet_attempted_error(Some(XcmError::Barrier))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn system_para_to_para_assertions(t: SystemParaToParaTest) {
|
|
||||||
type RuntimeEvent = <AssetHubWestend as Chain>::RuntimeEvent;
|
type RuntimeEvent = <AssetHubWestend as Chain>::RuntimeEvent;
|
||||||
|
|
||||||
AssetHubWestend::assert_xcm_pallet_attempted_complete(Some(Weight::from_parts(
|
AssetHubWestend::assert_xcm_pallet_attempted_complete(Some(Weight::from_parts(
|
||||||
@@ -56,7 +27,7 @@ fn system_para_to_para_assertions(t: SystemParaToParaTest) {
|
|||||||
assert_expected_events!(
|
assert_expected_events!(
|
||||||
AssetHubWestend,
|
AssetHubWestend,
|
||||||
vec![
|
vec![
|
||||||
// Amount to reserve transfer is transferred to Parachain's Sovereing account
|
// Amount to reserve transfer is transferred to Parachain's Sovereign account
|
||||||
RuntimeEvent::Balances(
|
RuntimeEvent::Balances(
|
||||||
pallet_balances::Event::Transfer { from, to, amount }
|
pallet_balances::Event::Transfer { from, to, amount }
|
||||||
) => {
|
) => {
|
||||||
@@ -70,6 +41,19 @@ fn system_para_to_para_assertions(t: SystemParaToParaTest) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn para_receiver_assertions<Test>(_: Test) {
|
||||||
|
type RuntimeEvent = <PenpalA as Chain>::RuntimeEvent;
|
||||||
|
assert_expected_events!(
|
||||||
|
PenpalA,
|
||||||
|
vec![
|
||||||
|
RuntimeEvent::Balances(pallet_balances::Event::Deposit { .. }) => {},
|
||||||
|
RuntimeEvent::MessageQueue(
|
||||||
|
pallet_message_queue::Event::Processed { success: true, .. }
|
||||||
|
) => {},
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
fn system_para_to_para_assets_assertions(t: SystemParaToParaTest) {
|
fn system_para_to_para_assets_assertions(t: SystemParaToParaTest) {
|
||||||
type RuntimeEvent = <AssetHubWestend as Chain>::RuntimeEvent;
|
type RuntimeEvent = <AssetHubWestend as Chain>::RuntimeEvent;
|
||||||
|
|
||||||
@@ -81,7 +65,7 @@ fn system_para_to_para_assets_assertions(t: SystemParaToParaTest) {
|
|||||||
assert_expected_events!(
|
assert_expected_events!(
|
||||||
AssetHubWestend,
|
AssetHubWestend,
|
||||||
vec![
|
vec![
|
||||||
// Amount to reserve transfer is transferred to Parachain's Sovereing account
|
// Amount to reserve transfer is transferred to Parachain's Sovereign account
|
||||||
RuntimeEvent::Assets(
|
RuntimeEvent::Assets(
|
||||||
pallet_assets::Event::Transferred { asset_id, from, to, amount }
|
pallet_assets::Event::Transferred { asset_id, from, to, amount }
|
||||||
) => {
|
) => {
|
||||||
@@ -96,48 +80,6 @@ fn system_para_to_para_assets_assertions(t: SystemParaToParaTest) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn relay_limited_reserve_transfer_assets(t: RelayToSystemParaTest) -> DispatchResult {
|
|
||||||
<Westend as WestendPallet>::XcmPallet::limited_reserve_transfer_assets(
|
|
||||||
t.signed_origin,
|
|
||||||
bx!(t.args.dest.into()),
|
|
||||||
bx!(t.args.beneficiary.into()),
|
|
||||||
bx!(t.args.assets.into()),
|
|
||||||
t.args.fee_asset_item,
|
|
||||||
t.args.weight_limit,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn relay_reserve_transfer_assets(t: RelayToSystemParaTest) -> DispatchResult {
|
|
||||||
<Westend as WestendPallet>::XcmPallet::reserve_transfer_assets(
|
|
||||||
t.signed_origin,
|
|
||||||
bx!(t.args.dest.into()),
|
|
||||||
bx!(t.args.beneficiary.into()),
|
|
||||||
bx!(t.args.assets.into()),
|
|
||||||
t.args.fee_asset_item,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn system_para_limited_reserve_transfer_assets(t: SystemParaToRelayTest) -> DispatchResult {
|
|
||||||
<AssetHubWestend as AssetHubWestendPallet>::PolkadotXcm::limited_reserve_transfer_assets(
|
|
||||||
t.signed_origin,
|
|
||||||
bx!(t.args.dest.into()),
|
|
||||||
bx!(t.args.beneficiary.into()),
|
|
||||||
bx!(t.args.assets.into()),
|
|
||||||
t.args.fee_asset_item,
|
|
||||||
t.args.weight_limit,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn system_para_reserve_transfer_assets(t: SystemParaToRelayTest) -> DispatchResult {
|
|
||||||
<AssetHubWestend as AssetHubWestendPallet>::PolkadotXcm::reserve_transfer_assets(
|
|
||||||
t.signed_origin,
|
|
||||||
bx!(t.args.dest.into()),
|
|
||||||
bx!(t.args.beneficiary.into()),
|
|
||||||
bx!(t.args.assets.into()),
|
|
||||||
t.args.fee_asset_item,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn system_para_to_para_limited_reserve_transfer_assets(t: SystemParaToParaTest) -> DispatchResult {
|
fn system_para_to_para_limited_reserve_transfer_assets(t: SystemParaToParaTest) -> DispatchResult {
|
||||||
<AssetHubWestend as AssetHubWestendPallet>::PolkadotXcm::limited_reserve_transfer_assets(
|
<AssetHubWestend as AssetHubWestendPallet>::PolkadotXcm::limited_reserve_transfer_assets(
|
||||||
t.signed_origin,
|
t.signed_origin,
|
||||||
@@ -149,187 +91,72 @@ fn system_para_to_para_limited_reserve_transfer_assets(t: SystemParaToParaTest)
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn system_para_to_para_reserve_transfer_assets(t: SystemParaToParaTest) -> DispatchResult {
|
|
||||||
<AssetHubWestend as AssetHubWestendPallet>::PolkadotXcm::reserve_transfer_assets(
|
|
||||||
t.signed_origin,
|
|
||||||
bx!(t.args.dest.into()),
|
|
||||||
bx!(t.args.beneficiary.into()),
|
|
||||||
bx!(t.args.assets.into()),
|
|
||||||
t.args.fee_asset_item,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Limited Reserve Transfers of native asset from Relay Chain to the System Parachain shouldn't
|
|
||||||
/// work
|
|
||||||
#[test]
|
|
||||||
fn limited_reserve_transfer_native_asset_from_relay_to_system_para_fails() {
|
|
||||||
// Init values for Relay Chain
|
|
||||||
let amount_to_send: Balance = WESTEND_ED * 1000;
|
|
||||||
let test_args = TestContext {
|
|
||||||
sender: WestendSender::get(),
|
|
||||||
receiver: AssetHubWestendReceiver::get(),
|
|
||||||
args: relay_test_args(amount_to_send),
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut test = RelayToSystemParaTest::new(test_args);
|
|
||||||
|
|
||||||
let sender_balance_before = test.sender.balance;
|
|
||||||
let receiver_balance_before = test.receiver.balance;
|
|
||||||
|
|
||||||
test.set_assertion::<Westend>(relay_origin_assertions);
|
|
||||||
test.set_assertion::<AssetHubWestend>(system_para_dest_assertions);
|
|
||||||
test.set_dispatchable::<Westend>(relay_limited_reserve_transfer_assets);
|
|
||||||
test.assert();
|
|
||||||
|
|
||||||
let delivery_fees = Westend::execute_with(|| {
|
|
||||||
xcm_helpers::transfer_assets_delivery_fees::<
|
|
||||||
<WestendXcmConfig as xcm_executor::Config>::XcmSender,
|
|
||||||
>(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
|
|
||||||
});
|
|
||||||
|
|
||||||
let sender_balance_after = test.sender.balance;
|
|
||||||
let receiver_balance_after = test.receiver.balance;
|
|
||||||
|
|
||||||
assert_eq!(sender_balance_before - amount_to_send - delivery_fees, sender_balance_after);
|
|
||||||
assert_eq!(receiver_balance_before, receiver_balance_after);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Limited Reserve Transfers of native asset from System Parachain to Relay Chain shoudln't work
|
|
||||||
#[test]
|
|
||||||
fn limited_reserve_transfer_native_asset_from_system_para_to_relay_fails() {
|
|
||||||
// Init values for System Parachain
|
|
||||||
let destination = AssetHubWestend::parent_location();
|
|
||||||
let beneficiary_id = WestendReceiver::get();
|
|
||||||
let amount_to_send: Balance = ASSET_HUB_WESTEND_ED * 1000;
|
|
||||||
let assets = (Parent, amount_to_send).into();
|
|
||||||
|
|
||||||
let test_args = TestContext {
|
|
||||||
sender: AssetHubWestendSender::get(),
|
|
||||||
receiver: WestendReceiver::get(),
|
|
||||||
args: system_para_test_args(destination, beneficiary_id, amount_to_send, assets, None),
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut test = SystemParaToRelayTest::new(test_args);
|
|
||||||
|
|
||||||
let sender_balance_before = test.sender.balance;
|
|
||||||
let receiver_balance_before = test.receiver.balance;
|
|
||||||
|
|
||||||
test.set_assertion::<AssetHubWestend>(system_para_to_relay_assertions);
|
|
||||||
test.set_dispatchable::<AssetHubWestend>(system_para_limited_reserve_transfer_assets);
|
|
||||||
test.assert();
|
|
||||||
|
|
||||||
let sender_balance_after = test.sender.balance;
|
|
||||||
let receiver_balance_after = test.receiver.balance;
|
|
||||||
|
|
||||||
assert_eq!(sender_balance_before, sender_balance_after);
|
|
||||||
assert_eq!(receiver_balance_before, receiver_balance_after);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reserve Transfers of native asset from Relay Chain to the System Parachain shouldn't work
|
/// Reserve Transfers of native asset from Relay Chain to the System Parachain shouldn't work
|
||||||
#[test]
|
#[test]
|
||||||
fn reserve_transfer_native_asset_from_relay_to_system_para_fails() {
|
fn reserve_transfer_native_asset_from_relay_to_system_para_fails() {
|
||||||
// Init values for Relay Chain
|
let signed_origin = <Westend as Chain>::RuntimeOrigin::signed(WestendSender::get().into());
|
||||||
|
let destination = Westend::child_location_of(AssetHubWestend::para_id());
|
||||||
|
let beneficiary: MultiLocation =
|
||||||
|
AccountId32Junction { network: None, id: AssetHubWestendReceiver::get().into() }.into();
|
||||||
let amount_to_send: Balance = WESTEND_ED * 1000;
|
let amount_to_send: Balance = WESTEND_ED * 1000;
|
||||||
let test_args = TestContext {
|
let assets: MultiAssets = (Here, amount_to_send).into();
|
||||||
sender: WestendSender::get(),
|
let fee_asset_item = 0;
|
||||||
receiver: AssetHubWestendReceiver::get(),
|
|
||||||
args: relay_test_args(amount_to_send),
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut test = RelayToSystemParaTest::new(test_args);
|
// this should fail
|
||||||
|
Westend::execute_with(|| {
|
||||||
let sender_balance_before = test.sender.balance;
|
let result = <Westend as WestendPallet>::XcmPallet::limited_reserve_transfer_assets(
|
||||||
let receiver_balance_before = test.receiver.balance;
|
signed_origin,
|
||||||
|
bx!(destination.into()),
|
||||||
test.set_assertion::<Westend>(relay_origin_assertions);
|
bx!(beneficiary.into()),
|
||||||
test.set_assertion::<AssetHubWestend>(system_para_dest_assertions);
|
bx!(assets.into()),
|
||||||
test.set_dispatchable::<Westend>(relay_reserve_transfer_assets);
|
fee_asset_item,
|
||||||
test.assert();
|
WeightLimit::Unlimited,
|
||||||
|
);
|
||||||
let delivery_fees = Westend::execute_with(|| {
|
assert_err!(
|
||||||
xcm_helpers::transfer_assets_delivery_fees::<
|
result,
|
||||||
<WestendXcmConfig as xcm_executor::Config>::XcmSender,
|
DispatchError::Module(sp_runtime::ModuleError {
|
||||||
>(test.args.assets.clone(), 0, test.args.weight_limit, test.args.beneficiary, test.args.dest)
|
index: 99,
|
||||||
|
error: [2, 0, 0, 0],
|
||||||
|
message: Some("Filtered")
|
||||||
|
})
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
let sender_balance_after = test.sender.balance;
|
|
||||||
let receiver_balance_after = test.receiver.balance;
|
|
||||||
|
|
||||||
assert_eq!(sender_balance_before - amount_to_send - delivery_fees, sender_balance_after);
|
|
||||||
assert_eq!(receiver_balance_before, receiver_balance_after);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reserve Transfers of native asset from System Parachain to Relay Chain shouldn't work
|
/// Reserve Transfers of native asset from System Parachain to Relay Chain shouldn't work
|
||||||
#[test]
|
#[test]
|
||||||
fn reserve_transfer_native_asset_from_system_para_to_relay_fails() {
|
fn reserve_transfer_native_asset_from_system_para_to_relay_fails() {
|
||||||
// Init values for System Parachain
|
// Init values for System Parachain
|
||||||
|
let signed_origin =
|
||||||
|
<AssetHubWestend as Chain>::RuntimeOrigin::signed(AssetHubWestendSender::get().into());
|
||||||
let destination = AssetHubWestend::parent_location();
|
let destination = AssetHubWestend::parent_location();
|
||||||
let beneficiary_id = WestendReceiver::get();
|
let beneficiary_id = WestendReceiver::get();
|
||||||
|
let beneficiary: MultiLocation =
|
||||||
|
AccountId32Junction { network: None, id: beneficiary_id.into() }.into();
|
||||||
let amount_to_send: Balance = ASSET_HUB_WESTEND_ED * 1000;
|
let amount_to_send: Balance = ASSET_HUB_WESTEND_ED * 1000;
|
||||||
let assets = (Parent, amount_to_send).into();
|
let assets: MultiAssets = (Parent, amount_to_send).into();
|
||||||
|
let fee_asset_item = 0;
|
||||||
|
|
||||||
let test_args = TestContext {
|
// this should fail
|
||||||
sender: AssetHubWestendSender::get(),
|
AssetHubWestend::execute_with(|| {
|
||||||
receiver: WestendReceiver::get(),
|
let result =
|
||||||
args: system_para_test_args(destination, beneficiary_id, amount_to_send, assets, None),
|
<AssetHubWestend as AssetHubWestendPallet>::PolkadotXcm::limited_reserve_transfer_assets(
|
||||||
};
|
signed_origin,
|
||||||
|
bx!(destination.into()),
|
||||||
let mut test = SystemParaToRelayTest::new(test_args);
|
bx!(beneficiary.into()),
|
||||||
|
bx!(assets.into()),
|
||||||
let sender_balance_before = test.sender.balance;
|
fee_asset_item,
|
||||||
let receiver_balance_before = test.receiver.balance;
|
WeightLimit::Unlimited,
|
||||||
|
);
|
||||||
test.set_assertion::<AssetHubWestend>(system_para_to_relay_assertions);
|
assert_err!(
|
||||||
test.set_dispatchable::<AssetHubWestend>(system_para_reserve_transfer_assets);
|
result,
|
||||||
test.assert();
|
DispatchError::Module(sp_runtime::ModuleError {
|
||||||
|
index: 31,
|
||||||
let sender_balance_after = test.sender.balance;
|
error: [2, 0, 0, 0],
|
||||||
let receiver_balance_after = test.receiver.balance;
|
message: Some("Filtered")
|
||||||
|
})
|
||||||
assert_eq!(sender_balance_before, sender_balance_after);
|
);
|
||||||
assert_eq!(receiver_balance_before, receiver_balance_after);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Limited Reserve Transfers of native asset from System Parachain to Parachain should work
|
|
||||||
#[test]
|
|
||||||
fn limited_reserve_transfer_native_asset_from_system_para_to_para() {
|
|
||||||
// Init values for System Parachain
|
|
||||||
let destination = AssetHubWestend::sibling_location_of(PenpalA::para_id());
|
|
||||||
let beneficiary_id = PenpalAReceiver::get();
|
|
||||||
let amount_to_send: Balance = ASSET_HUB_WESTEND_ED * 1000;
|
|
||||||
let assets = (Parent, amount_to_send).into();
|
|
||||||
|
|
||||||
let test_args = TestContext {
|
|
||||||
sender: AssetHubWestendSender::get(),
|
|
||||||
receiver: PenpalAReceiver::get(),
|
|
||||||
args: system_para_test_args(destination, beneficiary_id, amount_to_send, assets, None),
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut test = SystemParaToParaTest::new(test_args);
|
|
||||||
|
|
||||||
let sender_balance_before = test.sender.balance;
|
|
||||||
|
|
||||||
test.set_assertion::<AssetHubWestend>(system_para_to_para_assertions);
|
|
||||||
// TODO: Add assertion for Penpal runtime. Right now message is failing with
|
|
||||||
// `UntrustedReserveLocation`
|
|
||||||
test.set_dispatchable::<AssetHubWestend>(system_para_to_para_limited_reserve_transfer_assets);
|
|
||||||
test.assert();
|
|
||||||
|
|
||||||
let sender_balance_after = test.sender.balance;
|
|
||||||
|
|
||||||
let delivery_fees = AssetHubWestend::execute_with(|| {
|
|
||||||
xcm_helpers::transfer_assets_delivery_fees::<<XcmConfig as xcm_executor::Config>::XcmSender>(
|
|
||||||
test.args.assets.clone(),
|
|
||||||
0,
|
|
||||||
test.args.weight_limit,
|
|
||||||
test.args.beneficiary,
|
|
||||||
test.args.dest,
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
assert_eq!(sender_balance_before - amount_to_send - delivery_fees, sender_balance_after);
|
|
||||||
// TODO: Check receiver balance when Penpal runtime is improved to propery handle reserve
|
|
||||||
// transfers
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reserve Transfers of native asset from System Parachain to Parachain should work
|
/// Reserve Transfers of native asset from System Parachain to Parachain should work
|
||||||
@@ -350,14 +177,15 @@ fn reserve_transfer_native_asset_from_system_para_to_para() {
|
|||||||
let mut test = SystemParaToParaTest::new(test_args);
|
let mut test = SystemParaToParaTest::new(test_args);
|
||||||
|
|
||||||
let sender_balance_before = test.sender.balance;
|
let sender_balance_before = test.sender.balance;
|
||||||
|
let receiver_balance_before = test.receiver.balance;
|
||||||
|
|
||||||
test.set_assertion::<AssetHubWestend>(system_para_to_para_assertions);
|
test.set_assertion::<AssetHubWestend>(system_para_to_para_sender_assertions);
|
||||||
// TODO: Add assertion for Penpal runtime. Right now message is failing with
|
test.set_assertion::<PenpalA>(para_receiver_assertions);
|
||||||
// `UntrustedReserveLocation`
|
test.set_dispatchable::<AssetHubWestend>(system_para_to_para_limited_reserve_transfer_assets);
|
||||||
test.set_dispatchable::<AssetHubWestend>(system_para_to_para_reserve_transfer_assets);
|
|
||||||
test.assert();
|
test.assert();
|
||||||
|
|
||||||
let sender_balance_after = test.sender.balance;
|
let sender_balance_after = test.sender.balance;
|
||||||
|
let receiver_balance_after = test.receiver.balance;
|
||||||
|
|
||||||
let delivery_fees = AssetHubWestend::execute_with(|| {
|
let delivery_fees = AssetHubWestend::execute_with(|| {
|
||||||
xcm_helpers::transfer_assets_delivery_fees::<<XcmConfig as xcm_executor::Config>::XcmSender>(
|
xcm_helpers::transfer_assets_delivery_fees::<<XcmConfig as xcm_executor::Config>::XcmSender>(
|
||||||
@@ -369,45 +197,10 @@ fn reserve_transfer_native_asset_from_system_para_to_para() {
|
|||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Sender's balance is reduced
|
||||||
assert_eq!(sender_balance_before - amount_to_send - delivery_fees, sender_balance_after);
|
assert_eq!(sender_balance_before - amount_to_send - delivery_fees, sender_balance_after);
|
||||||
// TODO: Check receiver balance when Penpal runtime is improved to propery handle reserve
|
// Receiver's balance is increased
|
||||||
// transfers
|
assert!(receiver_balance_after > receiver_balance_before);
|
||||||
}
|
|
||||||
|
|
||||||
/// Limited Reserve Transfers of a local asset from System Parachain to Parachain should work
|
|
||||||
#[test]
|
|
||||||
fn limited_reserve_transfer_asset_from_system_para_to_para() {
|
|
||||||
// Force create asset from Relay Chain and mint assets for System Parachain's sender account
|
|
||||||
AssetHubWestend::force_create_and_mint_asset(
|
|
||||||
ASSET_ID,
|
|
||||||
ASSET_MIN_BALANCE,
|
|
||||||
true,
|
|
||||||
AssetHubWestendSender::get(),
|
|
||||||
Some(Weight::from_parts(1_019_445_000, 200_000)),
|
|
||||||
ASSET_MIN_BALANCE * 1000000,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Init values for System Parachain
|
|
||||||
let destination = AssetHubWestend::sibling_location_of(PenpalA::para_id());
|
|
||||||
let beneficiary_id = PenpalAReceiver::get();
|
|
||||||
let amount_to_send = ASSET_MIN_BALANCE * 1000;
|
|
||||||
let assets =
|
|
||||||
(X2(PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())), amount_to_send)
|
|
||||||
.into();
|
|
||||||
|
|
||||||
let system_para_test_args = TestContext {
|
|
||||||
sender: AssetHubWestendSender::get(),
|
|
||||||
receiver: PenpalAReceiver::get(),
|
|
||||||
args: system_para_test_args(destination, beneficiary_id, amount_to_send, assets, None),
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut system_para_test = SystemParaToParaTest::new(system_para_test_args);
|
|
||||||
|
|
||||||
system_para_test.set_assertion::<AssetHubWestend>(system_para_to_para_assets_assertions);
|
|
||||||
// TODO: Add assertions when Penpal is able to manage assets
|
|
||||||
system_para_test
|
|
||||||
.set_dispatchable::<AssetHubWestend>(system_para_to_para_limited_reserve_transfer_assets);
|
|
||||||
system_para_test.assert();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reserve Transfers of a local asset from System Parachain to Parachain should work
|
/// Reserve Transfers of a local asset from System Parachain to Parachain should work
|
||||||
@@ -442,6 +235,6 @@ fn reserve_transfer_asset_from_system_para_to_para() {
|
|||||||
system_para_test.set_assertion::<AssetHubWestend>(system_para_to_para_assets_assertions);
|
system_para_test.set_assertion::<AssetHubWestend>(system_para_to_para_assets_assertions);
|
||||||
// TODO: Add assertions when Penpal is able to manage assets
|
// TODO: Add assertions when Penpal is able to manage assets
|
||||||
system_para_test
|
system_para_test
|
||||||
.set_dispatchable::<AssetHubWestend>(system_para_to_para_reserve_transfer_assets);
|
.set_dispatchable::<AssetHubWestend>(system_para_to_para_limited_reserve_transfer_assets);
|
||||||
system_para_test.assert();
|
system_para_test.assert();
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -51,7 +51,7 @@ fn relay_dest_assertions(t: SystemParaToRelayTest) {
|
|||||||
assert_expected_events!(
|
assert_expected_events!(
|
||||||
Westend,
|
Westend,
|
||||||
vec![
|
vec![
|
||||||
// Amount is witdrawn from Relay Chain's `CheckAccount`
|
// Amount is withdrawn from Relay Chain's `CheckAccount`
|
||||||
RuntimeEvent::Balances(pallet_balances::Event::Withdraw { who, amount }) => {
|
RuntimeEvent::Balances(pallet_balances::Event::Withdraw { who, amount }) => {
|
||||||
who: *who == <Westend as WestendPallet>::XcmPallet::check_account(),
|
who: *who == <Westend as WestendPallet>::XcmPallet::check_account(),
|
||||||
amount: *amount == t.args.amount,
|
amount: *amount == t.args.amount,
|
||||||
|
|||||||
@@ -962,7 +962,7 @@ mod benches {
|
|||||||
[cumulus_pallet_xcmp_queue, XcmpQueue]
|
[cumulus_pallet_xcmp_queue, XcmpQueue]
|
||||||
[cumulus_pallet_dmp_queue, DmpQueue]
|
[cumulus_pallet_dmp_queue, DmpQueue]
|
||||||
// XCM
|
// XCM
|
||||||
[pallet_xcm, PolkadotXcm]
|
[pallet_xcm, PalletXcmExtrinsiscsBenchmark::<Runtime>]
|
||||||
// NOTE: Make sure you point to the individual modules below.
|
// NOTE: Make sure you point to the individual modules below.
|
||||||
[pallet_xcm_benchmarks::fungible, XcmBalances]
|
[pallet_xcm_benchmarks::fungible, XcmBalances]
|
||||||
[pallet_xcm_benchmarks::generic, XcmGeneric]
|
[pallet_xcm_benchmarks::generic, XcmGeneric]
|
||||||
@@ -1200,6 +1200,7 @@ impl_runtime_apis! {
|
|||||||
use frame_support::traits::StorageInfoTrait;
|
use frame_support::traits::StorageInfoTrait;
|
||||||
use frame_system_benchmarking::Pallet as SystemBench;
|
use frame_system_benchmarking::Pallet as SystemBench;
|
||||||
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
||||||
|
use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsiscsBenchmark;
|
||||||
|
|
||||||
// This is defined once again in dispatch_benchmark, because list_benchmarks!
|
// This is defined once again in dispatch_benchmark, because list_benchmarks!
|
||||||
// and add_benchmarks! are macros exported by define_benchmarks! macros and those types
|
// and add_benchmarks! are macros exported by define_benchmarks! macros and those types
|
||||||
@@ -1243,6 +1244,39 @@ impl_runtime_apis! {
|
|||||||
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
||||||
impl cumulus_pallet_session_benchmarking::Config for Runtime {}
|
impl cumulus_pallet_session_benchmarking::Config for Runtime {}
|
||||||
|
|
||||||
|
use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsiscsBenchmark;
|
||||||
|
impl pallet_xcm::benchmarking::Config for Runtime {
|
||||||
|
fn reachable_dest() -> Option<MultiLocation> {
|
||||||
|
Some(Parent.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> {
|
||||||
|
// Relay/native token can be teleported between AH and Relay.
|
||||||
|
Some((
|
||||||
|
MultiAsset {
|
||||||
|
fun: Fungible(EXISTENTIAL_DEPOSIT),
|
||||||
|
id: Concrete(Parent.into())
|
||||||
|
},
|
||||||
|
Parent.into(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> {
|
||||||
|
// AH can reserve transfer native token to some random parachain.
|
||||||
|
let random_para_id = 43211234;
|
||||||
|
ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests(
|
||||||
|
random_para_id.into()
|
||||||
|
);
|
||||||
|
Some((
|
||||||
|
MultiAsset {
|
||||||
|
fun: Fungible(EXISTENTIAL_DEPOSIT),
|
||||||
|
id: Concrete(Parent.into())
|
||||||
|
},
|
||||||
|
ParentThen(Parachain(random_para_id).into()).into(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
use xcm::latest::prelude::*;
|
use xcm::latest::prelude::*;
|
||||||
use xcm_config::{KsmLocation, MaxAssetsIntoHolding};
|
use xcm_config::{KsmLocation, MaxAssetsIntoHolding};
|
||||||
use pallet_xcm_benchmarks::asset_instance_from;
|
use pallet_xcm_benchmarks::asset_instance_from;
|
||||||
|
|||||||
@@ -552,11 +552,6 @@ pub type XcmRouter = WithUniqueTopic<(
|
|||||||
XcmpQueue,
|
XcmpQueue,
|
||||||
)>;
|
)>;
|
||||||
|
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
parameter_types! {
|
|
||||||
pub ReachableDest: Option<MultiLocation> = Some(Parent.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
impl pallet_xcm::Config for Runtime {
|
impl pallet_xcm::Config for Runtime {
|
||||||
type RuntimeEvent = RuntimeEvent;
|
type RuntimeEvent = RuntimeEvent;
|
||||||
// We want to disallow users sending (arbitrary) XCMs from this chain.
|
// We want to disallow users sending (arbitrary) XCMs from this chain.
|
||||||
@@ -586,8 +581,6 @@ impl pallet_xcm::Config for Runtime {
|
|||||||
type SovereignAccountOf = LocationToAccountId;
|
type SovereignAccountOf = LocationToAccountId;
|
||||||
type MaxLockers = ConstU32<8>;
|
type MaxLockers = ConstU32<8>;
|
||||||
type WeightInfo = crate::weights::pallet_xcm::WeightInfo<Runtime>;
|
type WeightInfo = crate::weights::pallet_xcm::WeightInfo<Runtime>;
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
type ReachableDest = ReachableDest;
|
|
||||||
type AdminOrigin = EnsureRoot<AccountId>;
|
type AdminOrigin = EnsureRoot<AccountId>;
|
||||||
type MaxRemoteLockConsumers = ConstU32<0>;
|
type MaxRemoteLockConsumers = ConstU32<0>;
|
||||||
type RemoteLockConsumerIdentifier = ();
|
type RemoteLockConsumerIdentifier = ();
|
||||||
|
|||||||
@@ -18,13 +18,14 @@
|
|||||||
//! Tests for the Statemine (Kusama Assets Hub) chain.
|
//! Tests for the Statemine (Kusama Assets Hub) chain.
|
||||||
|
|
||||||
use asset_hub_kusama_runtime::xcm_config::{
|
use asset_hub_kusama_runtime::xcm_config::{
|
||||||
AssetFeeAsExistentialDepositMultiplierFeeCharger, KsmLocation, TrustBackedAssetsPalletLocation,
|
AssetFeeAsExistentialDepositMultiplierFeeCharger, KsmLocation, LocationToAccountId,
|
||||||
|
TrustBackedAssetsPalletLocation,
|
||||||
};
|
};
|
||||||
pub use asset_hub_kusama_runtime::{
|
pub use asset_hub_kusama_runtime::{
|
||||||
xcm_config::{CheckingAccount, ForeignCreatorsSovereignAccountOf, XcmConfig},
|
xcm_config::{CheckingAccount, ForeignCreatorsSovereignAccountOf, XcmConfig},
|
||||||
AllPalletsWithoutSystem, AssetDeposit, Assets, Balances, ExistentialDeposit, ForeignAssets,
|
AllPalletsWithoutSystem, AssetDeposit, Assets, Balances, ExistentialDeposit, ForeignAssets,
|
||||||
ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, ParachainSystem, Runtime,
|
ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, ParachainSystem, Runtime,
|
||||||
RuntimeCall, RuntimeEvent, SessionKeys, System, TrustBackedAssetsInstance,
|
RuntimeCall, RuntimeEvent, SessionKeys, System, TrustBackedAssetsInstance, XcmpQueue,
|
||||||
};
|
};
|
||||||
use asset_test_utils::{CollatorSessionKeys, ExtBuilder};
|
use asset_test_utils::{CollatorSessionKeys, ExtBuilder};
|
||||||
use codec::{Decode, Encode};
|
use codec::{Decode, Encode};
|
||||||
@@ -518,12 +519,6 @@ asset_test_utils::include_teleports_for_native_asset_works!(
|
|||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
Box::new(|runtime_event_encoded: Vec<u8>| {
|
|
||||||
match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) {
|
|
||||||
Ok(RuntimeEvent::XcmpQueue(event)) => Some(event),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
1000
|
1000
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -632,3 +627,32 @@ asset_test_utils::include_create_and_manage_foreign_assets_for_local_consensus_p
|
|||||||
assert_eq!(ForeignAssets::asset_ids().collect::<Vec<_>>().len(), 1);
|
assert_eq!(ForeignAssets::asset_ids().collect::<Vec<_>>().len(), 1);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn reserve_transfer_native_asset_to_non_teleport_para_works() {
|
||||||
|
asset_test_utils::test_cases::reserve_transfer_native_asset_to_non_teleport_para_works::<
|
||||||
|
Runtime,
|
||||||
|
AllPalletsWithoutSystem,
|
||||||
|
XcmConfig,
|
||||||
|
ParachainSystem,
|
||||||
|
XcmpQueue,
|
||||||
|
LocationToAccountId,
|
||||||
|
>(
|
||||||
|
collator_session_keys(),
|
||||||
|
ExistentialDeposit::get(),
|
||||||
|
AccountId::from(ALICE),
|
||||||
|
Box::new(|runtime_event_encoded: Vec<u8>| {
|
||||||
|
match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) {
|
||||||
|
Ok(RuntimeEvent::PolkadotXcm(event)) => Some(event),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
Box::new(|runtime_event_encoded: Vec<u8>| {
|
||||||
|
match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) {
|
||||||
|
Ok(RuntimeEvent::XcmpQueue(event)) => Some(event),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
WeightLimit::Unlimited,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -868,7 +868,7 @@ mod benches {
|
|||||||
[cumulus_pallet_xcmp_queue, XcmpQueue]
|
[cumulus_pallet_xcmp_queue, XcmpQueue]
|
||||||
[cumulus_pallet_dmp_queue, DmpQueue]
|
[cumulus_pallet_dmp_queue, DmpQueue]
|
||||||
// XCM
|
// XCM
|
||||||
[pallet_xcm, PolkadotXcm]
|
[pallet_xcm, PalletXcmExtrinsiscsBenchmark::<Runtime>]
|
||||||
// NOTE: Make sure you point to the individual modules below.
|
// NOTE: Make sure you point to the individual modules below.
|
||||||
[pallet_xcm_benchmarks::fungible, XcmBalances]
|
[pallet_xcm_benchmarks::fungible, XcmBalances]
|
||||||
[pallet_xcm_benchmarks::generic, XcmGeneric]
|
[pallet_xcm_benchmarks::generic, XcmGeneric]
|
||||||
@@ -1082,6 +1082,7 @@ impl_runtime_apis! {
|
|||||||
use frame_support::traits::StorageInfoTrait;
|
use frame_support::traits::StorageInfoTrait;
|
||||||
use frame_system_benchmarking::Pallet as SystemBench;
|
use frame_system_benchmarking::Pallet as SystemBench;
|
||||||
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
||||||
|
use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsiscsBenchmark;
|
||||||
|
|
||||||
// This is defined once again in dispatch_benchmark, because list_benchmarks!
|
// This is defined once again in dispatch_benchmark, because list_benchmarks!
|
||||||
// and add_benchmarks! are macros exported by define_benchmarks! macros and those types
|
// and add_benchmarks! are macros exported by define_benchmarks! macros and those types
|
||||||
@@ -1124,6 +1125,39 @@ impl_runtime_apis! {
|
|||||||
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
||||||
impl cumulus_pallet_session_benchmarking::Config for Runtime {}
|
impl cumulus_pallet_session_benchmarking::Config for Runtime {}
|
||||||
|
|
||||||
|
use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsiscsBenchmark;
|
||||||
|
impl pallet_xcm::benchmarking::Config for Runtime {
|
||||||
|
fn reachable_dest() -> Option<MultiLocation> {
|
||||||
|
Some(Parent.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> {
|
||||||
|
// Relay/native token can be teleported between AH and Relay.
|
||||||
|
Some((
|
||||||
|
MultiAsset {
|
||||||
|
fun: Fungible(EXISTENTIAL_DEPOSIT),
|
||||||
|
id: Concrete(Parent.into())
|
||||||
|
},
|
||||||
|
Parent.into(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> {
|
||||||
|
// AH can reserve transfer native token to some random parachain.
|
||||||
|
let random_para_id = 43211234;
|
||||||
|
ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests(
|
||||||
|
random_para_id.into()
|
||||||
|
);
|
||||||
|
Some((
|
||||||
|
MultiAsset {
|
||||||
|
fun: Fungible(EXISTENTIAL_DEPOSIT),
|
||||||
|
id: Concrete(Parent.into())
|
||||||
|
},
|
||||||
|
ParentThen(Parachain(random_para_id).into()).into(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
use xcm::latest::prelude::*;
|
use xcm::latest::prelude::*;
|
||||||
use xcm_config::{DotLocation, MaxAssetsIntoHolding};
|
use xcm_config::{DotLocation, MaxAssetsIntoHolding};
|
||||||
use pallet_xcm_benchmarks::asset_instance_from;
|
use pallet_xcm_benchmarks::asset_instance_from;
|
||||||
|
|||||||
@@ -476,11 +476,6 @@ pub type XcmRouter = WithUniqueTopic<(
|
|||||||
XcmpQueue,
|
XcmpQueue,
|
||||||
)>;
|
)>;
|
||||||
|
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
parameter_types! {
|
|
||||||
pub ReachableDest: Option<MultiLocation> = Some(Parent.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
impl pallet_xcm::Config for Runtime {
|
impl pallet_xcm::Config for Runtime {
|
||||||
type RuntimeEvent = RuntimeEvent;
|
type RuntimeEvent = RuntimeEvent;
|
||||||
// We want to disallow users sending (arbitrary) XCMs from this chain.
|
// We want to disallow users sending (arbitrary) XCMs from this chain.
|
||||||
@@ -510,8 +505,6 @@ impl pallet_xcm::Config for Runtime {
|
|||||||
type SovereignAccountOf = LocationToAccountId;
|
type SovereignAccountOf = LocationToAccountId;
|
||||||
type MaxLockers = ConstU32<8>;
|
type MaxLockers = ConstU32<8>;
|
||||||
type WeightInfo = crate::weights::pallet_xcm::WeightInfo<Runtime>;
|
type WeightInfo = crate::weights::pallet_xcm::WeightInfo<Runtime>;
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
type ReachableDest = ReachableDest;
|
|
||||||
type AdminOrigin = EnsureRoot<AccountId>;
|
type AdminOrigin = EnsureRoot<AccountId>;
|
||||||
type MaxRemoteLockConsumers = ConstU32<0>;
|
type MaxRemoteLockConsumers = ConstU32<0>;
|
||||||
type RemoteLockConsumerIdentifier = ();
|
type RemoteLockConsumerIdentifier = ();
|
||||||
|
|||||||
@@ -19,12 +19,13 @@
|
|||||||
|
|
||||||
use asset_hub_polkadot_runtime::xcm_config::{
|
use asset_hub_polkadot_runtime::xcm_config::{
|
||||||
AssetFeeAsExistentialDepositMultiplierFeeCharger, CheckingAccount, DotLocation,
|
AssetFeeAsExistentialDepositMultiplierFeeCharger, CheckingAccount, DotLocation,
|
||||||
ForeignCreatorsSovereignAccountOf, TrustBackedAssetsPalletLocation, XcmConfig,
|
ForeignCreatorsSovereignAccountOf, LocationToAccountId, TrustBackedAssetsPalletLocation,
|
||||||
|
XcmConfig,
|
||||||
};
|
};
|
||||||
pub use asset_hub_polkadot_runtime::{
|
pub use asset_hub_polkadot_runtime::{
|
||||||
AllPalletsWithoutSystem, AssetDeposit, Assets, Balances, ExistentialDeposit, ForeignAssets,
|
AllPalletsWithoutSystem, AssetDeposit, Assets, Balances, ExistentialDeposit, ForeignAssets,
|
||||||
ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, ParachainSystem, Runtime,
|
ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, ParachainSystem, Runtime,
|
||||||
RuntimeCall, RuntimeEvent, SessionKeys, System, TrustBackedAssetsInstance,
|
RuntimeCall, RuntimeEvent, SessionKeys, System, TrustBackedAssetsInstance, XcmpQueue,
|
||||||
};
|
};
|
||||||
use asset_test_utils::{CollatorSessionKeys, ExtBuilder};
|
use asset_test_utils::{CollatorSessionKeys, ExtBuilder};
|
||||||
use codec::{Decode, Encode};
|
use codec::{Decode, Encode};
|
||||||
@@ -531,12 +532,6 @@ asset_test_utils::include_teleports_for_native_asset_works!(
|
|||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
Box::new(|runtime_event_encoded: Vec<u8>| {
|
|
||||||
match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) {
|
|
||||||
Ok(RuntimeEvent::XcmpQueue(event)) => Some(event),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
1000
|
1000
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -657,3 +652,32 @@ asset_test_utils::include_create_and_manage_foreign_assets_for_local_consensus_p
|
|||||||
assert_eq!(ForeignAssets::asset_ids().collect::<Vec<_>>().len(), 1);
|
assert_eq!(ForeignAssets::asset_ids().collect::<Vec<_>>().len(), 1);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn reserve_transfer_native_asset_to_non_teleport_para_works() {
|
||||||
|
asset_test_utils::test_cases::reserve_transfer_native_asset_to_non_teleport_para_works::<
|
||||||
|
Runtime,
|
||||||
|
AllPalletsWithoutSystem,
|
||||||
|
XcmConfig,
|
||||||
|
ParachainSystem,
|
||||||
|
XcmpQueue,
|
||||||
|
LocationToAccountId,
|
||||||
|
>(
|
||||||
|
collator_session_keys(),
|
||||||
|
ExistentialDeposit::get(),
|
||||||
|
AccountId::from(ALICE),
|
||||||
|
Box::new(|runtime_event_encoded: Vec<u8>| {
|
||||||
|
match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) {
|
||||||
|
Ok(RuntimeEvent::PolkadotXcm(event)) => Some(event),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
Box::new(|runtime_event_encoded: Vec<u8>| {
|
||||||
|
match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) {
|
||||||
|
Ok(RuntimeEvent::XcmpQueue(event)) => Some(event),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
WeightLimit::Unlimited,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1077,7 +1077,7 @@ mod benches {
|
|||||||
[pallet_xcm_bridge_hub_router, ToWestend]
|
[pallet_xcm_bridge_hub_router, ToWestend]
|
||||||
[pallet_xcm_bridge_hub_router, ToRococo]
|
[pallet_xcm_bridge_hub_router, ToRococo]
|
||||||
// XCM
|
// XCM
|
||||||
[pallet_xcm, PolkadotXcm]
|
[pallet_xcm, PalletXcmExtrinsiscsBenchmark::<Runtime>]
|
||||||
// NOTE: Make sure you point to the individual modules below.
|
// NOTE: Make sure you point to the individual modules below.
|
||||||
[pallet_xcm_benchmarks::fungible, XcmBalances]
|
[pallet_xcm_benchmarks::fungible, XcmBalances]
|
||||||
[pallet_xcm_benchmarks::generic, XcmGeneric]
|
[pallet_xcm_benchmarks::generic, XcmGeneric]
|
||||||
@@ -1315,6 +1315,7 @@ impl_runtime_apis! {
|
|||||||
use frame_support::traits::StorageInfoTrait;
|
use frame_support::traits::StorageInfoTrait;
|
||||||
use frame_system_benchmarking::Pallet as SystemBench;
|
use frame_system_benchmarking::Pallet as SystemBench;
|
||||||
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
||||||
|
use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsiscsBenchmark;
|
||||||
use pallet_xcm_bridge_hub_router::benchmarking::Pallet as XcmBridgeHubRouterBench;
|
use pallet_xcm_bridge_hub_router::benchmarking::Pallet as XcmBridgeHubRouterBench;
|
||||||
|
|
||||||
// This is defined once again in dispatch_benchmark, because list_benchmarks!
|
// This is defined once again in dispatch_benchmark, because list_benchmarks!
|
||||||
@@ -1368,6 +1369,39 @@ impl_runtime_apis! {
|
|||||||
Config as XcmBridgeHubRouterConfig,
|
Config as XcmBridgeHubRouterConfig,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsiscsBenchmark;
|
||||||
|
impl pallet_xcm::benchmarking::Config for Runtime {
|
||||||
|
fn reachable_dest() -> Option<MultiLocation> {
|
||||||
|
Some(Parent.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> {
|
||||||
|
// Relay/native token can be teleported between AH and Relay.
|
||||||
|
Some((
|
||||||
|
MultiAsset {
|
||||||
|
fun: Fungible(EXISTENTIAL_DEPOSIT),
|
||||||
|
id: Concrete(Parent.into())
|
||||||
|
},
|
||||||
|
Parent.into(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> {
|
||||||
|
// AH can reserve transfer native token to some random parachain.
|
||||||
|
let random_para_id = 43211234;
|
||||||
|
ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests(
|
||||||
|
random_para_id.into()
|
||||||
|
);
|
||||||
|
Some((
|
||||||
|
MultiAsset {
|
||||||
|
fun: Fungible(EXISTENTIAL_DEPOSIT),
|
||||||
|
id: Concrete(Parent.into())
|
||||||
|
},
|
||||||
|
ParentThen(Parachain(random_para_id).into()).into(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl XcmBridgeHubRouterConfig<ToWococoXcmRouterInstance> for Runtime {
|
impl XcmBridgeHubRouterConfig<ToWococoXcmRouterInstance> for Runtime {
|
||||||
fn make_congested() {
|
fn make_congested() {
|
||||||
cumulus_pallet_xcmp_queue::bridging::suspend_channel_for_benchmarks::<Runtime>(
|
cumulus_pallet_xcmp_queue::bridging::suspend_channel_for_benchmarks::<Runtime>(
|
||||||
|
|||||||
@@ -667,11 +667,6 @@ pub type XcmRouter = WithUniqueTopic<(
|
|||||||
ToRococoXcmRouter,
|
ToRococoXcmRouter,
|
||||||
)>;
|
)>;
|
||||||
|
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
parameter_types! {
|
|
||||||
pub ReachableDest: Option<MultiLocation> = Some(Parent.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
impl pallet_xcm::Config for Runtime {
|
impl pallet_xcm::Config for Runtime {
|
||||||
type RuntimeEvent = RuntimeEvent;
|
type RuntimeEvent = RuntimeEvent;
|
||||||
// We want to disallow users sending (arbitrary) XCMs from this chain.
|
// We want to disallow users sending (arbitrary) XCMs from this chain.
|
||||||
@@ -701,8 +696,6 @@ impl pallet_xcm::Config for Runtime {
|
|||||||
type SovereignAccountOf = LocationToAccountId;
|
type SovereignAccountOf = LocationToAccountId;
|
||||||
type MaxLockers = ConstU32<8>;
|
type MaxLockers = ConstU32<8>;
|
||||||
type WeightInfo = crate::weights::pallet_xcm::WeightInfo<Runtime>;
|
type WeightInfo = crate::weights::pallet_xcm::WeightInfo<Runtime>;
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
type ReachableDest = ReachableDest;
|
|
||||||
type AdminOrigin = EnsureRoot<AccountId>;
|
type AdminOrigin = EnsureRoot<AccountId>;
|
||||||
type MaxRemoteLockConsumers = ConstU32<0>;
|
type MaxRemoteLockConsumers = ConstU32<0>;
|
||||||
type RemoteLockConsumerIdentifier = ();
|
type RemoteLockConsumerIdentifier = ();
|
||||||
|
|||||||
@@ -529,12 +529,6 @@ asset_test_utils::include_teleports_for_native_asset_works!(
|
|||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
Box::new(|runtime_event_encoded: Vec<u8>| {
|
|
||||||
match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) {
|
|
||||||
Ok(RuntimeEvent::XcmpQueue(event)) => Some(event),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
1000
|
1000
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -930,6 +924,35 @@ mod asset_hub_rococo_tests {
|
|||||||
actual
|
actual
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn reserve_transfer_native_asset_to_non_teleport_para_works() {
|
||||||
|
asset_test_utils::test_cases::reserve_transfer_native_asset_to_non_teleport_para_works::<
|
||||||
|
Runtime,
|
||||||
|
AllPalletsWithoutSystem,
|
||||||
|
XcmConfig,
|
||||||
|
ParachainSystem,
|
||||||
|
XcmpQueue,
|
||||||
|
LocationToAccountId,
|
||||||
|
>(
|
||||||
|
collator_session_keys(),
|
||||||
|
ExistentialDeposit::get(),
|
||||||
|
AccountId::from(ALICE),
|
||||||
|
Box::new(|runtime_event_encoded: Vec<u8>| {
|
||||||
|
match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) {
|
||||||
|
Ok(RuntimeEvent::PolkadotXcm(event)) => Some(event),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
Box::new(|runtime_event_encoded: Vec<u8>| {
|
||||||
|
match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) {
|
||||||
|
Ok(RuntimeEvent::XcmpQueue(event)) => Some(event),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
WeightLimit::Unlimited,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mod asset_hub_wococo_tests {
|
mod asset_hub_wococo_tests {
|
||||||
|
|||||||
@@ -1013,7 +1013,7 @@ mod benches {
|
|||||||
[cumulus_pallet_dmp_queue, DmpQueue]
|
[cumulus_pallet_dmp_queue, DmpQueue]
|
||||||
[pallet_xcm_bridge_hub_router, ToRococo]
|
[pallet_xcm_bridge_hub_router, ToRococo]
|
||||||
// XCM
|
// XCM
|
||||||
[pallet_xcm, PolkadotXcm]
|
[pallet_xcm, PalletXcmExtrinsiscsBenchmark::<Runtime>]
|
||||||
// NOTE: Make sure you point to the individual modules below.
|
// NOTE: Make sure you point to the individual modules below.
|
||||||
[pallet_xcm_benchmarks::fungible, XcmBalances]
|
[pallet_xcm_benchmarks::fungible, XcmBalances]
|
||||||
[pallet_xcm_benchmarks::generic, XcmGeneric]
|
[pallet_xcm_benchmarks::generic, XcmGeneric]
|
||||||
@@ -1297,6 +1297,7 @@ impl_runtime_apis! {
|
|||||||
use frame_support::traits::StorageInfoTrait;
|
use frame_support::traits::StorageInfoTrait;
|
||||||
use frame_system_benchmarking::Pallet as SystemBench;
|
use frame_system_benchmarking::Pallet as SystemBench;
|
||||||
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
||||||
|
use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsiscsBenchmark;
|
||||||
use pallet_xcm_bridge_hub_router::benchmarking::Pallet as XcmBridgeHubRouterBench;
|
use pallet_xcm_bridge_hub_router::benchmarking::Pallet as XcmBridgeHubRouterBench;
|
||||||
|
|
||||||
// This is defined once again in dispatch_benchmark, because list_benchmarks!
|
// This is defined once again in dispatch_benchmark, because list_benchmarks!
|
||||||
@@ -1343,6 +1344,39 @@ impl_runtime_apis! {
|
|||||||
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
||||||
impl cumulus_pallet_session_benchmarking::Config for Runtime {}
|
impl cumulus_pallet_session_benchmarking::Config for Runtime {}
|
||||||
|
|
||||||
|
use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsiscsBenchmark;
|
||||||
|
impl pallet_xcm::benchmarking::Config for Runtime {
|
||||||
|
fn reachable_dest() -> Option<MultiLocation> {
|
||||||
|
Some(Parent.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> {
|
||||||
|
// Relay/native token can be teleported between AH and Relay.
|
||||||
|
Some((
|
||||||
|
MultiAsset {
|
||||||
|
fun: Fungible(EXISTENTIAL_DEPOSIT),
|
||||||
|
id: Concrete(Parent.into())
|
||||||
|
},
|
||||||
|
Parent.into(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> {
|
||||||
|
// AH can reserve transfer native token to some random parachain.
|
||||||
|
let random_para_id = 43211234;
|
||||||
|
ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests(
|
||||||
|
random_para_id.into()
|
||||||
|
);
|
||||||
|
Some((
|
||||||
|
MultiAsset {
|
||||||
|
fun: Fungible(EXISTENTIAL_DEPOSIT),
|
||||||
|
id: Concrete(Parent.into())
|
||||||
|
},
|
||||||
|
ParentThen(Parachain(random_para_id).into()).into(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
use pallet_xcm_bridge_hub_router::benchmarking::{
|
use pallet_xcm_bridge_hub_router::benchmarking::{
|
||||||
Pallet as XcmBridgeHubRouterBench,
|
Pallet as XcmBridgeHubRouterBench,
|
||||||
Config as XcmBridgeHubRouterConfig,
|
Config as XcmBridgeHubRouterConfig,
|
||||||
|
|||||||
@@ -636,11 +636,6 @@ pub type XcmRouter = WithUniqueTopic<(
|
|||||||
ToRococoXcmRouter,
|
ToRococoXcmRouter,
|
||||||
)>;
|
)>;
|
||||||
|
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
parameter_types! {
|
|
||||||
pub ReachableDest: Option<MultiLocation> = Some(Parent.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
impl pallet_xcm::Config for Runtime {
|
impl pallet_xcm::Config for Runtime {
|
||||||
type RuntimeEvent = RuntimeEvent;
|
type RuntimeEvent = RuntimeEvent;
|
||||||
type SendXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
|
type SendXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
|
||||||
@@ -666,8 +661,6 @@ impl pallet_xcm::Config for Runtime {
|
|||||||
type SovereignAccountOf = LocationToAccountId;
|
type SovereignAccountOf = LocationToAccountId;
|
||||||
type MaxLockers = ConstU32<8>;
|
type MaxLockers = ConstU32<8>;
|
||||||
type WeightInfo = crate::weights::pallet_xcm::WeightInfo<Runtime>;
|
type WeightInfo = crate::weights::pallet_xcm::WeightInfo<Runtime>;
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
type ReachableDest = ReachableDest;
|
|
||||||
type AdminOrigin = EnsureRoot<AccountId>;
|
type AdminOrigin = EnsureRoot<AccountId>;
|
||||||
type MaxRemoteLockConsumers = ConstU32<0>;
|
type MaxRemoteLockConsumers = ConstU32<0>;
|
||||||
type RemoteLockConsumerIdentifier = ();
|
type RemoteLockConsumerIdentifier = ();
|
||||||
|
|||||||
@@ -525,12 +525,6 @@ asset_test_utils::include_teleports_for_native_asset_works!(
|
|||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
Box::new(|runtime_event_encoded: Vec<u8>| {
|
|
||||||
match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) {
|
|
||||||
Ok(RuntimeEvent::XcmpQueue(event)) => Some(event),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
1000
|
1000
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -815,3 +809,32 @@ fn change_xcm_bridge_hub_router_byte_fee_by_governance_works() {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn reserve_transfer_native_asset_to_non_teleport_para_works() {
|
||||||
|
asset_test_utils::test_cases::reserve_transfer_native_asset_to_non_teleport_para_works::<
|
||||||
|
Runtime,
|
||||||
|
AllPalletsWithoutSystem,
|
||||||
|
XcmConfig,
|
||||||
|
ParachainSystem,
|
||||||
|
XcmpQueue,
|
||||||
|
LocationToAccountId,
|
||||||
|
>(
|
||||||
|
collator_session_keys(),
|
||||||
|
ExistentialDeposit::get(),
|
||||||
|
AccountId::from(ALICE),
|
||||||
|
Box::new(|runtime_event_encoded: Vec<u8>| {
|
||||||
|
match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) {
|
||||||
|
Ok(RuntimeEvent::PolkadotXcm(event)) => Some(event),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
Box::new(|runtime_event_encoded: Vec<u8>| {
|
||||||
|
match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) {
|
||||||
|
Ok(RuntimeEvent::XcmpQueue(event)) => Some(event),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
WeightLimit::Unlimited,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -27,6 +27,21 @@ use std::fmt::Debug;
|
|||||||
use xcm::latest::prelude::*;
|
use xcm::latest::prelude::*;
|
||||||
use xcm_builder::{CreateMatcher, MatchXcm};
|
use xcm_builder::{CreateMatcher, MatchXcm};
|
||||||
|
|
||||||
|
/// Given a message, a sender, and a destination, it returns the delivery fees
|
||||||
|
fn get_fungible_delivery_fees<S: SendXcm>(destination: MultiLocation, message: Xcm<()>) -> u128 {
|
||||||
|
let Ok((_, delivery_fees)) = validate_send::<S>(destination, message) else {
|
||||||
|
unreachable!("message can be sent; qed")
|
||||||
|
};
|
||||||
|
if let Some(delivery_fee) = delivery_fees.inner().first() {
|
||||||
|
let Fungible(delivery_fee_amount) = delivery_fee.fun else {
|
||||||
|
unreachable!("asset is fungible; qed");
|
||||||
|
};
|
||||||
|
delivery_fee_amount
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Helper function to verify `xcm` contains all relevant instructions expected on destination
|
/// Helper function to verify `xcm` contains all relevant instructions expected on destination
|
||||||
/// chain as part of a reserve-asset-transfer.
|
/// chain as part of a reserve-asset-transfer.
|
||||||
pub(crate) fn assert_matches_reserve_asset_deposited_instructions<RuntimeCall: Debug>(
|
pub(crate) fn assert_matches_reserve_asset_deposited_instructions<RuntimeCall: Debug>(
|
||||||
|
|||||||
@@ -16,25 +16,28 @@
|
|||||||
//! Module contains predefined test-case scenarios for `Runtime` with various assets.
|
//! Module contains predefined test-case scenarios for `Runtime` with various assets.
|
||||||
|
|
||||||
use super::xcm_helpers;
|
use super::xcm_helpers;
|
||||||
|
use crate::{assert_matches_reserve_asset_deposited_instructions, get_fungible_delivery_fees};
|
||||||
use codec::Encode;
|
use codec::Encode;
|
||||||
|
use cumulus_primitives_core::XcmpMessageSource;
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
assert_noop, assert_ok,
|
assert_noop, assert_ok,
|
||||||
traits::{
|
traits::{
|
||||||
fungible::Mutate, fungibles::InspectEnumerable, Get, OnFinalize, OnInitialize, OriginTrait,
|
fungible::Mutate, fungibles::InspectEnumerable, Currency, Get, OnFinalize, OnInitialize,
|
||||||
|
OriginTrait,
|
||||||
},
|
},
|
||||||
weights::Weight,
|
weights::Weight,
|
||||||
};
|
};
|
||||||
use frame_system::pallet_prelude::BlockNumberFor;
|
use frame_system::pallet_prelude::BlockNumberFor;
|
||||||
use parachains_common::{AccountId, Balance};
|
use parachains_common::{AccountId, Balance};
|
||||||
use parachains_runtimes_test_utils::{
|
use parachains_runtimes_test_utils::{
|
||||||
assert_metadata, assert_total, AccountIdOf, BalanceOf, CollatorSessionKeys, ExtBuilder,
|
assert_metadata, assert_total, mock_open_hrmp_channel, AccountIdOf, BalanceOf,
|
||||||
ValidatorIdOf, XcmReceivedFrom,
|
CollatorSessionKeys, ExtBuilder, ValidatorIdOf, XcmReceivedFrom,
|
||||||
};
|
};
|
||||||
use sp_runtime::{
|
use sp_runtime::{
|
||||||
traits::{MaybeEquivalence, StaticLookup, Zero},
|
traits::{MaybeEquivalence, StaticLookup, Zero},
|
||||||
DispatchError, Saturating,
|
DispatchError, Saturating,
|
||||||
};
|
};
|
||||||
use xcm::latest::prelude::*;
|
use xcm::{latest::prelude::*, VersionedMultiAssets};
|
||||||
use xcm_executor::{traits::ConvertLocation, XcmExecutor};
|
use xcm_executor::{traits::ConvertLocation, XcmExecutor};
|
||||||
|
|
||||||
type RuntimeHelper<Runtime, AllPalletsWithoutSystem = ()> =
|
type RuntimeHelper<Runtime, AllPalletsWithoutSystem = ()> =
|
||||||
@@ -43,8 +46,8 @@ type RuntimeHelper<Runtime, AllPalletsWithoutSystem = ()> =
|
|||||||
// Re-export test_case from `parachains-runtimes-test-utils`
|
// Re-export test_case from `parachains-runtimes-test-utils`
|
||||||
pub use parachains_runtimes_test_utils::test_cases::change_storage_constant_by_governance_works;
|
pub use parachains_runtimes_test_utils::test_cases::change_storage_constant_by_governance_works;
|
||||||
|
|
||||||
/// Test-case makes sure that `Runtime` can receive native asset from relay chain
|
/// Test-case makes sure that `Runtime` can receive native asset from relay chain and can teleport
|
||||||
/// and can teleport it back and to the other parachains
|
/// it back
|
||||||
pub fn teleports_for_native_asset_works<
|
pub fn teleports_for_native_asset_works<
|
||||||
Runtime,
|
Runtime,
|
||||||
AllPalletsWithoutSystem,
|
AllPalletsWithoutSystem,
|
||||||
@@ -57,9 +60,6 @@ pub fn teleports_for_native_asset_works<
|
|||||||
existential_deposit: BalanceOf<Runtime>,
|
existential_deposit: BalanceOf<Runtime>,
|
||||||
target_account: AccountIdOf<Runtime>,
|
target_account: AccountIdOf<Runtime>,
|
||||||
unwrap_pallet_xcm_event: Box<dyn Fn(Vec<u8>) -> Option<pallet_xcm::Event<Runtime>>>,
|
unwrap_pallet_xcm_event: Box<dyn Fn(Vec<u8>) -> Option<pallet_xcm::Event<Runtime>>>,
|
||||||
unwrap_xcmp_queue_event: Box<
|
|
||||||
dyn Fn(Vec<u8>) -> Option<cumulus_pallet_xcmp_queue::Event<Runtime>>,
|
|
||||||
>,
|
|
||||||
runtime_para_id: u32,
|
runtime_para_id: u32,
|
||||||
) where
|
) where
|
||||||
Runtime: frame_system::Config
|
Runtime: frame_system::Config
|
||||||
@@ -164,12 +164,13 @@ pub fn teleports_for_native_asset_works<
|
|||||||
// 2. try to teleport asset back to the relaychain
|
// 2. try to teleport asset back to the relaychain
|
||||||
{
|
{
|
||||||
let dest = MultiLocation::parent();
|
let dest = MultiLocation::parent();
|
||||||
let dest_beneficiary = MultiLocation::parent()
|
let mut dest_beneficiary = MultiLocation::parent()
|
||||||
.appended_with(AccountId32 {
|
.appended_with(AccountId32 {
|
||||||
network: None,
|
network: None,
|
||||||
id: sp_runtime::AccountId32::new([3; 32]).into(),
|
id: sp_runtime::AccountId32::new([3; 32]).into(),
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
dest_beneficiary.reanchor(&dest, XcmConfig::UniversalLocation::get()).unwrap();
|
||||||
|
|
||||||
let target_account_balance_before_teleport =
|
let target_account_balance_before_teleport =
|
||||||
<pallet_balances::Pallet<Runtime>>::free_balance(&target_account);
|
<pallet_balances::Pallet<Runtime>>::free_balance(&target_account);
|
||||||
@@ -223,65 +224,53 @@ pub fn teleports_for_native_asset_works<
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. try to teleport asset away to other parachain (1234)
|
// 3. try to teleport assets away to other parachain (2345): should not work as we don't
|
||||||
|
// trust `IsTeleporter` for `(relay-native-asset, para(2345))` pair
|
||||||
{
|
{
|
||||||
let other_para_id = 1234;
|
let other_para_id = 2345;
|
||||||
let dest = MultiLocation::new(1, X1(Parachain(other_para_id)));
|
let dest = MultiLocation::new(1, X1(Parachain(other_para_id)));
|
||||||
let dest_beneficiary = MultiLocation::new(1, X1(Parachain(other_para_id)))
|
let mut dest_beneficiary = MultiLocation::new(1, X1(Parachain(other_para_id)))
|
||||||
.appended_with(AccountId32 {
|
.appended_with(AccountId32 {
|
||||||
network: None,
|
network: None,
|
||||||
id: sp_runtime::AccountId32::new([3; 32]).into(),
|
id: sp_runtime::AccountId32::new([3; 32]).into(),
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
dest_beneficiary.reanchor(&dest, XcmConfig::UniversalLocation::get()).unwrap();
|
||||||
|
|
||||||
let target_account_balance_before_teleport =
|
let target_account_balance_before_teleport =
|
||||||
<pallet_balances::Pallet<Runtime>>::free_balance(&target_account);
|
<pallet_balances::Pallet<Runtime>>::free_balance(&target_account);
|
||||||
|
|
||||||
let native_asset_to_teleport_away = native_asset_amount_unit * 3.into();
|
let native_asset_to_teleport_away = native_asset_amount_unit * 3.into();
|
||||||
assert!(
|
assert!(
|
||||||
native_asset_to_teleport_away <
|
native_asset_to_teleport_away <
|
||||||
target_account_balance_before_teleport - existential_deposit
|
target_account_balance_before_teleport - existential_deposit
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
assert_ok!(RuntimeHelper::<Runtime>::do_teleport_assets::<HrmpChannelOpener>(
|
RuntimeHelper::<Runtime>::do_teleport_assets::<HrmpChannelOpener>(
|
||||||
RuntimeHelper::<Runtime>::origin_of(target_account.clone()),
|
RuntimeHelper::<Runtime>::origin_of(target_account.clone()),
|
||||||
dest,
|
|
||||||
dest_beneficiary,
|
|
||||||
(native_asset_id, native_asset_to_teleport_away.into()),
|
|
||||||
Some((runtime_para_id, other_para_id)),
|
|
||||||
included_head,
|
|
||||||
&alice,
|
|
||||||
));
|
|
||||||
|
|
||||||
let delivery_fees =
|
|
||||||
xcm_helpers::transfer_assets_delivery_fees::<XcmConfig::XcmSender>(
|
|
||||||
(native_asset_id, native_asset_to_teleport_away.into()).into(),
|
|
||||||
0,
|
|
||||||
Unlimited,
|
|
||||||
dest_beneficiary,
|
|
||||||
dest,
|
dest,
|
||||||
);
|
dest_beneficiary,
|
||||||
|
(native_asset_id, native_asset_to_teleport_away.into()),
|
||||||
|
Some((runtime_para_id, other_para_id)),
|
||||||
|
included_head,
|
||||||
|
&alice,
|
||||||
|
),
|
||||||
|
Err(DispatchError::Module(sp_runtime::ModuleError {
|
||||||
|
index: 31,
|
||||||
|
error: [2, 0, 0, 0,],
|
||||||
|
message: Some("Filtered",),
|
||||||
|
},),)
|
||||||
|
);
|
||||||
|
|
||||||
// check balances
|
// check balances
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
<pallet_balances::Pallet<Runtime>>::free_balance(&target_account),
|
<pallet_balances::Pallet<Runtime>>::free_balance(&target_account),
|
||||||
target_account_balance_before_teleport -
|
target_account_balance_before_teleport
|
||||||
native_asset_to_teleport_away -
|
|
||||||
delivery_fees.into()
|
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
<pallet_balances::Pallet<Runtime>>::free_balance(&CheckingAccount::get()),
|
<pallet_balances::Pallet<Runtime>>::free_balance(&CheckingAccount::get()),
|
||||||
0.into()
|
0.into()
|
||||||
);
|
);
|
||||||
|
|
||||||
// check events
|
|
||||||
RuntimeHelper::<Runtime>::assert_pallet_xcm_event_outcome(
|
|
||||||
&unwrap_pallet_xcm_event,
|
|
||||||
|outcome| {
|
|
||||||
assert_ok!(outcome.ensure_complete());
|
|
||||||
},
|
|
||||||
);
|
|
||||||
assert!(RuntimeHelper::<Runtime>::xcmp_queue_message_sent(unwrap_xcmp_queue_event)
|
|
||||||
.is_some());
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -298,7 +287,6 @@ macro_rules! include_teleports_for_native_asset_works(
|
|||||||
$collator_session_key:expr,
|
$collator_session_key:expr,
|
||||||
$existential_deposit:expr,
|
$existential_deposit:expr,
|
||||||
$unwrap_pallet_xcm_event:expr,
|
$unwrap_pallet_xcm_event:expr,
|
||||||
$unwrap_xcmp_queue_event:expr,
|
|
||||||
$runtime_para_id:expr
|
$runtime_para_id:expr
|
||||||
) => {
|
) => {
|
||||||
#[test]
|
#[test]
|
||||||
@@ -318,15 +306,14 @@ macro_rules! include_teleports_for_native_asset_works(
|
|||||||
$existential_deposit,
|
$existential_deposit,
|
||||||
target_account,
|
target_account,
|
||||||
$unwrap_pallet_xcm_event,
|
$unwrap_pallet_xcm_event,
|
||||||
$unwrap_xcmp_queue_event,
|
|
||||||
$runtime_para_id
|
$runtime_para_id
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
/// Test-case makes sure that `Runtime` can receive teleported assets from sibling parachain relay
|
/// Test-case makes sure that `Runtime` can receive teleported assets from sibling parachain, and
|
||||||
/// chain
|
/// can teleport it back
|
||||||
pub fn teleports_for_foreign_assets_works<
|
pub fn teleports_for_foreign_assets_works<
|
||||||
Runtime,
|
Runtime,
|
||||||
AllPalletsWithoutSystem,
|
AllPalletsWithoutSystem,
|
||||||
@@ -381,7 +368,7 @@ pub fn teleports_for_foreign_assets_works<
|
|||||||
<Runtime as frame_system::Config>::AccountId: From<AccountId>,
|
<Runtime as frame_system::Config>::AccountId: From<AccountId>,
|
||||||
ForeignAssetsPalletInstance: 'static,
|
ForeignAssetsPalletInstance: 'static,
|
||||||
{
|
{
|
||||||
// foreign parachain with the same consenus currency as asset
|
// foreign parachain with the same consensus currency as asset
|
||||||
let foreign_para_id = 2222;
|
let foreign_para_id = 2222;
|
||||||
let foreign_asset_id_multilocation = MultiLocation {
|
let foreign_asset_id_multilocation = MultiLocation {
|
||||||
parents: 1,
|
parents: 1,
|
||||||
@@ -473,7 +460,7 @@ pub fn teleports_for_foreign_assets_works<
|
|||||||
>(foreign_asset_id_multilocation, 0, 0);
|
>(foreign_asset_id_multilocation, 0, 0);
|
||||||
assert!(teleported_foreign_asset_amount > asset_minimum_asset_balance);
|
assert!(teleported_foreign_asset_amount > asset_minimum_asset_balance);
|
||||||
|
|
||||||
// 1. process received teleported assets from relaychain
|
// 1. process received teleported assets from sibling parachain (foreign_para_id)
|
||||||
let xcm = Xcm(vec![
|
let xcm = Xcm(vec![
|
||||||
// BuyExecution with relaychain native token
|
// BuyExecution with relaychain native token
|
||||||
WithdrawAsset(buy_execution_fee.clone().into()),
|
WithdrawAsset(buy_execution_fee.clone().into()),
|
||||||
@@ -551,12 +538,13 @@ pub fn teleports_for_foreign_assets_works<
|
|||||||
// 2. try to teleport asset back to source parachain (foreign_para_id)
|
// 2. try to teleport asset back to source parachain (foreign_para_id)
|
||||||
{
|
{
|
||||||
let dest = MultiLocation::new(1, X1(Parachain(foreign_para_id)));
|
let dest = MultiLocation::new(1, X1(Parachain(foreign_para_id)));
|
||||||
let dest_beneficiary = MultiLocation::new(1, X1(Parachain(foreign_para_id)))
|
let mut dest_beneficiary = MultiLocation::new(1, X1(Parachain(foreign_para_id)))
|
||||||
.appended_with(AccountId32 {
|
.appended_with(AccountId32 {
|
||||||
network: None,
|
network: None,
|
||||||
id: sp_runtime::AccountId32::new([3; 32]).into(),
|
id: sp_runtime::AccountId32::new([3; 32]).into(),
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
dest_beneficiary.reanchor(&dest, XcmConfig::UniversalLocation::get()).unwrap();
|
||||||
|
|
||||||
let target_account_balance_before_teleport =
|
let target_account_balance_before_teleport =
|
||||||
<pallet_assets::Pallet<Runtime, ForeignAssetsPalletInstance>>::balance(
|
<pallet_assets::Pallet<Runtime, ForeignAssetsPalletInstance>>::balance(
|
||||||
@@ -1108,7 +1096,7 @@ pub fn create_and_manage_foreign_assets_for_local_consensus_parachain_assets_wor
|
|||||||
AssetId: Clone + Copy,
|
AssetId: Clone + Copy,
|
||||||
AssetIdConverter: MaybeEquivalence<MultiLocation, AssetId>,
|
AssetIdConverter: MaybeEquivalence<MultiLocation, AssetId>,
|
||||||
{
|
{
|
||||||
// foreign parachain with the same consenus currency as asset
|
// foreign parachain with the same consensus currency as asset
|
||||||
let foreign_asset_id_multilocation =
|
let foreign_asset_id_multilocation =
|
||||||
MultiLocation { parents: 1, interior: X2(Parachain(2222), GeneralIndex(1234567)) };
|
MultiLocation { parents: 1, interior: X2(Parachain(2222), GeneralIndex(1234567)) };
|
||||||
let asset_id = AssetIdConverter::convert(&foreign_asset_id_multilocation).unwrap();
|
let asset_id = AssetIdConverter::convert(&foreign_asset_id_multilocation).unwrap();
|
||||||
@@ -1388,3 +1376,199 @@ macro_rules! include_create_and_manage_foreign_assets_for_local_consensus_parach
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// Test-case makes sure that `Runtime` can reserve-transfer asset to other parachains (where
|
||||||
|
/// teleport is not trusted)
|
||||||
|
pub fn reserve_transfer_native_asset_to_non_teleport_para_works<
|
||||||
|
Runtime,
|
||||||
|
AllPalletsWithoutSystem,
|
||||||
|
XcmConfig,
|
||||||
|
HrmpChannelOpener,
|
||||||
|
HrmpChannelSource,
|
||||||
|
LocationToAccountId,
|
||||||
|
>(
|
||||||
|
collator_session_keys: CollatorSessionKeys<Runtime>,
|
||||||
|
existential_deposit: BalanceOf<Runtime>,
|
||||||
|
alice_account: AccountIdOf<Runtime>,
|
||||||
|
unwrap_pallet_xcm_event: Box<dyn Fn(Vec<u8>) -> Option<pallet_xcm::Event<Runtime>>>,
|
||||||
|
unwrap_xcmp_queue_event: Box<
|
||||||
|
dyn Fn(Vec<u8>) -> Option<cumulus_pallet_xcmp_queue::Event<Runtime>>,
|
||||||
|
>,
|
||||||
|
weight_limit: WeightLimit,
|
||||||
|
) where
|
||||||
|
Runtime: frame_system::Config
|
||||||
|
+ pallet_balances::Config
|
||||||
|
+ pallet_session::Config
|
||||||
|
+ pallet_xcm::Config
|
||||||
|
+ parachain_info::Config
|
||||||
|
+ pallet_collator_selection::Config
|
||||||
|
+ cumulus_pallet_parachain_system::Config
|
||||||
|
+ cumulus_pallet_xcmp_queue::Config,
|
||||||
|
AllPalletsWithoutSystem:
|
||||||
|
OnInitialize<BlockNumberFor<Runtime>> + OnFinalize<BlockNumberFor<Runtime>>,
|
||||||
|
AccountIdOf<Runtime>: Into<[u8; 32]>,
|
||||||
|
ValidatorIdOf<Runtime>: From<AccountIdOf<Runtime>>,
|
||||||
|
BalanceOf<Runtime>: From<Balance>,
|
||||||
|
<Runtime as pallet_balances::Config>::Balance: From<Balance> + Into<u128>,
|
||||||
|
XcmConfig: xcm_executor::Config,
|
||||||
|
LocationToAccountId: ConvertLocation<AccountIdOf<Runtime>>,
|
||||||
|
<Runtime as frame_system::Config>::AccountId:
|
||||||
|
Into<<<Runtime as frame_system::Config>::RuntimeOrigin as OriginTrait>::AccountId>,
|
||||||
|
<<Runtime as frame_system::Config>::Lookup as StaticLookup>::Source:
|
||||||
|
From<<Runtime as frame_system::Config>::AccountId>,
|
||||||
|
<Runtime as frame_system::Config>::AccountId: From<AccountId>,
|
||||||
|
HrmpChannelOpener: frame_support::inherent::ProvideInherent<
|
||||||
|
Call = cumulus_pallet_parachain_system::Call<Runtime>,
|
||||||
|
>,
|
||||||
|
HrmpChannelSource: XcmpMessageSource,
|
||||||
|
{
|
||||||
|
let runtime_para_id = 1000;
|
||||||
|
ExtBuilder::<Runtime>::default()
|
||||||
|
.with_collators(collator_session_keys.collators())
|
||||||
|
.with_session_keys(collator_session_keys.session_keys())
|
||||||
|
.with_tracing()
|
||||||
|
.with_safe_xcm_version(3)
|
||||||
|
.with_para_id(runtime_para_id.into())
|
||||||
|
.build()
|
||||||
|
.execute_with(|| {
|
||||||
|
let mut alice = [0u8; 32];
|
||||||
|
alice[0] = 1;
|
||||||
|
let included_head = RuntimeHelper::<Runtime, AllPalletsWithoutSystem>::run_to_block(
|
||||||
|
2,
|
||||||
|
AccountId::from(alice).into(),
|
||||||
|
);
|
||||||
|
|
||||||
|
// reserve-transfer native asset with local reserve to remote parachain (2345)
|
||||||
|
|
||||||
|
let other_para_id = 2345;
|
||||||
|
let native_asset = MultiLocation::parent();
|
||||||
|
let dest = MultiLocation::new(1, X1(Parachain(other_para_id)));
|
||||||
|
let mut dest_beneficiary = MultiLocation::new(1, X1(Parachain(other_para_id)))
|
||||||
|
.appended_with(AccountId32 {
|
||||||
|
network: None,
|
||||||
|
id: sp_runtime::AccountId32::new([3; 32]).into(),
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
dest_beneficiary.reanchor(&dest, XcmConfig::UniversalLocation::get()).unwrap();
|
||||||
|
|
||||||
|
let reserve_account = LocationToAccountId::convert_location(&dest)
|
||||||
|
.expect("Sovereign account for reserves");
|
||||||
|
let balance_to_transfer = 1_000_000_000_000_u128;
|
||||||
|
|
||||||
|
// open HRMP to other parachain
|
||||||
|
mock_open_hrmp_channel::<Runtime, HrmpChannelOpener>(
|
||||||
|
runtime_para_id.into(),
|
||||||
|
other_para_id.into(),
|
||||||
|
included_head,
|
||||||
|
&alice,
|
||||||
|
);
|
||||||
|
|
||||||
|
// we calculate exact delivery fees _after_ sending the message by weighing the sent
|
||||||
|
// xcm, and this delivery fee varies for different runtimes, so just add enough buffer,
|
||||||
|
// then verify the arithmetics check out on final balance.
|
||||||
|
let delivery_fees_buffer = 40_000_000_000u128;
|
||||||
|
// drip 2xED + transfer_amount + delivery_fees_buffer to Alice account
|
||||||
|
let alice_account_init_balance = existential_deposit.saturating_mul(2.into()) +
|
||||||
|
balance_to_transfer.into() +
|
||||||
|
delivery_fees_buffer.into();
|
||||||
|
let _ = <pallet_balances::Pallet<Runtime>>::deposit_creating(
|
||||||
|
&alice_account,
|
||||||
|
alice_account_init_balance,
|
||||||
|
);
|
||||||
|
// SA of target location needs to have at least ED, otherwise making reserve fails
|
||||||
|
let _ = <pallet_balances::Pallet<Runtime>>::deposit_creating(
|
||||||
|
&reserve_account,
|
||||||
|
existential_deposit,
|
||||||
|
);
|
||||||
|
|
||||||
|
// we just check here, that user retains enough balance after withdrawal
|
||||||
|
// and also we check if `balance_to_transfer` is more than `existential_deposit`,
|
||||||
|
assert!(
|
||||||
|
(<pallet_balances::Pallet<Runtime>>::free_balance(&alice_account) -
|
||||||
|
balance_to_transfer.into()) >=
|
||||||
|
existential_deposit
|
||||||
|
);
|
||||||
|
// SA has just ED
|
||||||
|
assert_eq!(
|
||||||
|
<pallet_balances::Pallet<Runtime>>::free_balance(&reserve_account),
|
||||||
|
existential_deposit
|
||||||
|
);
|
||||||
|
|
||||||
|
// local native asset (pallet_balances)
|
||||||
|
let asset_to_transfer = MultiAsset {
|
||||||
|
fun: Fungible(balance_to_transfer.into()),
|
||||||
|
id: Concrete(native_asset),
|
||||||
|
};
|
||||||
|
|
||||||
|
// pallet_xcm call reserve transfer
|
||||||
|
assert_ok!(<pallet_xcm::Pallet<Runtime>>::limited_reserve_transfer_assets(
|
||||||
|
RuntimeHelper::<Runtime, AllPalletsWithoutSystem>::origin_of(alice_account.clone()),
|
||||||
|
Box::new(dest.into_versioned()),
|
||||||
|
Box::new(dest_beneficiary.into_versioned()),
|
||||||
|
Box::new(VersionedMultiAssets::from(MultiAssets::from(asset_to_transfer))),
|
||||||
|
0,
|
||||||
|
weight_limit,
|
||||||
|
));
|
||||||
|
|
||||||
|
// check events
|
||||||
|
// check pallet_xcm attempted
|
||||||
|
RuntimeHelper::<Runtime, AllPalletsWithoutSystem>::assert_pallet_xcm_event_outcome(
|
||||||
|
&unwrap_pallet_xcm_event,
|
||||||
|
|outcome| {
|
||||||
|
assert_ok!(outcome.ensure_complete());
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// check that xcm was sent
|
||||||
|
let xcm_sent_message_hash = <frame_system::Pallet<Runtime>>::events()
|
||||||
|
.into_iter()
|
||||||
|
.filter_map(|e| unwrap_xcmp_queue_event(e.event.encode()))
|
||||||
|
.find_map(|e| match e {
|
||||||
|
cumulus_pallet_xcmp_queue::Event::XcmpMessageSent { message_hash } =>
|
||||||
|
Some(message_hash),
|
||||||
|
_ => None,
|
||||||
|
});
|
||||||
|
|
||||||
|
// read xcm
|
||||||
|
let xcm_sent = RuntimeHelper::<HrmpChannelSource, AllPalletsWithoutSystem>::take_xcm(
|
||||||
|
other_para_id.into(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let delivery_fees = get_fungible_delivery_fees::<
|
||||||
|
<XcmConfig as xcm_executor::Config>::XcmSender,
|
||||||
|
>(dest, Xcm::try_from(xcm_sent.clone()).unwrap());
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
xcm_sent_message_hash,
|
||||||
|
Some(xcm_sent.using_encoded(sp_io::hashing::blake2_256))
|
||||||
|
);
|
||||||
|
let mut xcm_sent: Xcm<()> = xcm_sent.try_into().expect("versioned xcm");
|
||||||
|
|
||||||
|
// check sent XCM Program to other parachain
|
||||||
|
println!("reserve_transfer_native_asset_works sent xcm: {:?}", xcm_sent);
|
||||||
|
let reserve_assets_deposited = MultiAssets::from(vec![MultiAsset {
|
||||||
|
id: Concrete(MultiLocation { parents: 1, interior: Here }),
|
||||||
|
fun: Fungible(1000000000000),
|
||||||
|
}]);
|
||||||
|
|
||||||
|
assert_matches_reserve_asset_deposited_instructions(
|
||||||
|
&mut xcm_sent,
|
||||||
|
&reserve_assets_deposited,
|
||||||
|
&dest_beneficiary,
|
||||||
|
);
|
||||||
|
|
||||||
|
// check alice account decreased by balance_to_transfer ( + delivery_fees)
|
||||||
|
assert_eq!(
|
||||||
|
<pallet_balances::Pallet<Runtime>>::free_balance(&alice_account),
|
||||||
|
alice_account_init_balance - balance_to_transfer.into() - delivery_fees.into()
|
||||||
|
);
|
||||||
|
|
||||||
|
// check reserve account
|
||||||
|
// check reserve account increased by balance_to_transfer
|
||||||
|
assert_eq!(
|
||||||
|
<pallet_balances::Pallet<Runtime>>::free_balance(&reserve_account),
|
||||||
|
existential_deposit + balance_to_transfer.into()
|
||||||
|
);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
//! Module contains predefined test-case scenarios for `Runtime` with various assets transferred
|
//! Module contains predefined test-case scenarios for `Runtime` with various assets transferred
|
||||||
//! over a bridge.
|
//! over a bridge.
|
||||||
|
|
||||||
use crate::assert_matches_reserve_asset_deposited_instructions;
|
use crate::{assert_matches_reserve_asset_deposited_instructions, get_fungible_delivery_fees};
|
||||||
use codec::Encode;
|
use codec::Encode;
|
||||||
use cumulus_primitives_core::XcmpMessageSource;
|
use cumulus_primitives_core::XcmpMessageSource;
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
@@ -32,10 +32,7 @@ use parachains_runtimes_test_utils::{
|
|||||||
use sp_runtime::{traits::StaticLookup, Saturating};
|
use sp_runtime::{traits::StaticLookup, Saturating};
|
||||||
use xcm::{latest::prelude::*, VersionedMultiAssets};
|
use xcm::{latest::prelude::*, VersionedMultiAssets};
|
||||||
use xcm_builder::{CreateMatcher, MatchXcm};
|
use xcm_builder::{CreateMatcher, MatchXcm};
|
||||||
use xcm_executor::{
|
use xcm_executor::{traits::ConvertLocation, XcmExecutor};
|
||||||
traits::{ConvertLocation, TransactAsset},
|
|
||||||
XcmExecutor,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct TestBridgingConfig {
|
pub struct TestBridgingConfig {
|
||||||
pub bridged_network: NetworkId,
|
pub bridged_network: NetworkId,
|
||||||
@@ -129,8 +126,13 @@ pub fn limited_reserve_transfer_assets_for_native_asset_works<
|
|||||||
&alice,
|
&alice,
|
||||||
);
|
);
|
||||||
|
|
||||||
// drip ED to account
|
// we calculate exact delivery fees _after_ sending the message by weighing the sent
|
||||||
let alice_account_init_balance = existential_deposit + balance_to_transfer.into();
|
// xcm, and this delivery fee varies for different runtimes, so just add enough buffer,
|
||||||
|
// then verify the arithmetics check out on final balance.
|
||||||
|
let delivery_fees_buffer = 8_000_000_000_000u128;
|
||||||
|
// drip ED + transfer_amount + delivery_fees_buffer to Alice account
|
||||||
|
let alice_account_init_balance =
|
||||||
|
existential_deposit + balance_to_transfer.into() + delivery_fees_buffer.into();
|
||||||
let _ = <pallet_balances::Pallet<Runtime>>::deposit_creating(
|
let _ = <pallet_balances::Pallet<Runtime>>::deposit_creating(
|
||||||
&alice_account,
|
&alice_account,
|
||||||
alice_account_init_balance,
|
alice_account_init_balance,
|
||||||
@@ -183,56 +185,6 @@ pub fn limited_reserve_transfer_assets_for_native_asset_works<
|
|||||||
|
|
||||||
let expected_beneficiary = target_destination_account;
|
let expected_beneficiary = target_destination_account;
|
||||||
|
|
||||||
// Make sure sender has enough funds for paying delivery fees
|
|
||||||
let handling_delivery_fees = {
|
|
||||||
// Probable XCM with `ReserveAssetDeposited`.
|
|
||||||
let mut expected_reserve_asset_deposited_message = Xcm(vec![
|
|
||||||
ReserveAssetDeposited(MultiAssets::from(expected_assets.clone())),
|
|
||||||
ClearOrigin,
|
|
||||||
BuyExecution {
|
|
||||||
fees: MultiAsset {
|
|
||||||
id: Concrete(Default::default()),
|
|
||||||
fun: Fungible(balance_to_transfer),
|
|
||||||
},
|
|
||||||
weight_limit: Unlimited,
|
|
||||||
},
|
|
||||||
DepositAsset { assets: Wild(AllCounted(1)), beneficiary: expected_beneficiary },
|
|
||||||
SetTopic([
|
|
||||||
220, 188, 144, 32, 213, 83, 111, 175, 44, 210, 111, 19, 90, 165, 191, 112,
|
|
||||||
140, 247, 192, 124, 42, 17, 153, 141, 114, 34, 189, 20, 83, 69, 237, 173,
|
|
||||||
]),
|
|
||||||
]);
|
|
||||||
assert_matches_reserve_asset_deposited_instructions(
|
|
||||||
&mut expected_reserve_asset_deposited_message,
|
|
||||||
&expected_assets,
|
|
||||||
&expected_beneficiary,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Call `SendXcm::validate` to get delivery fees.
|
|
||||||
let (_, delivery_fees): (_, MultiAssets) = XcmConfig::XcmSender::validate(
|
|
||||||
&mut Some(target_location_from_different_consensus),
|
|
||||||
&mut Some(expected_reserve_asset_deposited_message),
|
|
||||||
)
|
|
||||||
.expect("validate passes");
|
|
||||||
// Drip delivery fee to Alice account.
|
|
||||||
let mut delivery_fees_added = false;
|
|
||||||
for delivery_fee in delivery_fees.inner() {
|
|
||||||
assert_ok!(<XcmConfig::AssetTransactor as TransactAsset>::deposit_asset(
|
|
||||||
&delivery_fee,
|
|
||||||
&MultiLocation {
|
|
||||||
parents: 0,
|
|
||||||
interior: X1(AccountId32 {
|
|
||||||
network: None,
|
|
||||||
id: alice_account.clone().into(),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
None,
|
|
||||||
));
|
|
||||||
delivery_fees_added = true;
|
|
||||||
}
|
|
||||||
delivery_fees_added
|
|
||||||
};
|
|
||||||
|
|
||||||
// do pallet_xcm call reserve transfer
|
// do pallet_xcm call reserve transfer
|
||||||
assert_ok!(<pallet_xcm::Pallet<Runtime>>::limited_reserve_transfer_assets(
|
assert_ok!(<pallet_xcm::Pallet<Runtime>>::limited_reserve_transfer_assets(
|
||||||
RuntimeHelper::<Runtime, AllPalletsWithoutSystem>::origin_of(alice_account.clone()),
|
RuntimeHelper::<Runtime, AllPalletsWithoutSystem>::origin_of(alice_account.clone()),
|
||||||
@@ -275,6 +227,7 @@ pub fn limited_reserve_transfer_assets_for_native_asset_works<
|
|||||||
|
|
||||||
// check sent XCM ExportMessage to BridgeHub
|
// check sent XCM ExportMessage to BridgeHub
|
||||||
|
|
||||||
|
let mut delivery_fees = 0;
|
||||||
// 1. check paid or unpaid
|
// 1. check paid or unpaid
|
||||||
if let Some(expected_fee_asset_id) = maybe_paid_export_message {
|
if let Some(expected_fee_asset_id) = maybe_paid_export_message {
|
||||||
xcm_sent
|
xcm_sent
|
||||||
@@ -315,6 +268,10 @@ pub fn limited_reserve_transfer_assets_for_native_asset_works<
|
|||||||
.split_global()
|
.split_global()
|
||||||
.expect("split works");
|
.expect("split works");
|
||||||
assert_eq!(destination, &target_location_junctions_without_global_consensus);
|
assert_eq!(destination, &target_location_junctions_without_global_consensus);
|
||||||
|
// Call `SendXcm::validate` to get delivery fees.
|
||||||
|
delivery_fees = get_fungible_delivery_fees::<
|
||||||
|
<XcmConfig as xcm_executor::Config>::XcmSender,
|
||||||
|
>(target_location_from_different_consensus, inner_xcm.clone());
|
||||||
assert_matches_reserve_asset_deposited_instructions(
|
assert_matches_reserve_asset_deposited_instructions(
|
||||||
inner_xcm,
|
inner_xcm,
|
||||||
&expected_assets,
|
&expected_assets,
|
||||||
@@ -330,8 +287,8 @@ pub fn limited_reserve_transfer_assets_for_native_asset_works<
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
<pallet_balances::Pallet<Runtime>>::free_balance(&alice_account),
|
<pallet_balances::Pallet<Runtime>>::free_balance(&alice_account),
|
||||||
alice_account_init_balance
|
alice_account_init_balance
|
||||||
.saturating_sub(existential_deposit)
|
|
||||||
.saturating_sub(balance_to_transfer.into())
|
.saturating_sub(balance_to_transfer.into())
|
||||||
|
.saturating_sub(delivery_fees.into())
|
||||||
);
|
);
|
||||||
|
|
||||||
// check reserve account increased by balance_to_transfer
|
// check reserve account increased by balance_to_transfer
|
||||||
@@ -341,14 +298,13 @@ pub fn limited_reserve_transfer_assets_for_native_asset_works<
|
|||||||
);
|
);
|
||||||
|
|
||||||
// check dedicated account increased by delivery fees (if configured)
|
// check dedicated account increased by delivery fees (if configured)
|
||||||
if handling_delivery_fees {
|
if let Some(delivery_fees_account) = delivery_fees_account {
|
||||||
if let Some(delivery_fees_account) = delivery_fees_account {
|
let delivery_fees_account_balance_after =
|
||||||
let delivery_fees_account_balance_after =
|
<pallet_balances::Pallet<Runtime>>::free_balance(&delivery_fees_account);
|
||||||
<pallet_balances::Pallet<Runtime>>::free_balance(&delivery_fees_account);
|
assert!(
|
||||||
assert!(
|
delivery_fees_account_balance_after - delivery_fees.into() >=
|
||||||
delivery_fees_account_balance_after > delivery_fees_account_balance_before
|
delivery_fees_account_balance_before
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -270,7 +270,7 @@ cd <polkadot-sdk-git-repo-dir>
|
|||||||
|
|
||||||
### Send messages - transfer asset over bridge (ROCs/WNDs)
|
### Send messages - transfer asset over bridge (ROCs/WNDs)
|
||||||
|
|
||||||
Do (asset) transfers:
|
Do reserve-backed transfers:
|
||||||
```
|
```
|
||||||
cd <polkadot-sdk-git-repo-dir>
|
cd <polkadot-sdk-git-repo-dir>
|
||||||
|
|
||||||
@@ -291,6 +291,20 @@ cd <polkadot-sdk-git-repo-dir>
|
|||||||
- AssetHubWestend (see `foreignAssets.Issued`, `xcmpQueue.Success`) https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:9010#/explorer
|
- AssetHubWestend (see `foreignAssets.Issued`, `xcmpQueue.Success`) https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:9010#/explorer
|
||||||
- BridgeHubRocococ (see `bridgeWestendMessages.MessagesDelivered`) https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:8943#/explorer
|
- BridgeHubRocococ (see `bridgeWestendMessages.MessagesDelivered`) https://polkadot.js.org/apps/?rpc=ws://127.0.0.1:8943#/explorer
|
||||||
|
|
||||||
|
Do reserve withdraw transfers: (when previous is finished)
|
||||||
|
```
|
||||||
|
cd <polkadot-sdk-git-repo-dir>
|
||||||
|
|
||||||
|
# wrappedWNDs from Rococo's Asset Hub to Westend's.
|
||||||
|
./cumulus/scripts/bridges_rococo_westend.sh withdraw-reserve-assets-from-asset-hub-rococo-local
|
||||||
|
```
|
||||||
|
```
|
||||||
|
cd <polkadot-sdk-git-repo-dir>
|
||||||
|
|
||||||
|
# wrappedROCs from Westend's Asset Hub to Rococo's.
|
||||||
|
./cumulus/scripts/bridges_rococo_westend.sh withdraw-reserve-assets-from-asset-hub-westend-local
|
||||||
|
```
|
||||||
|
|
||||||
### Claim relayer's rewards on BridgeHubRococo and BridgeHubWestend
|
### Claim relayer's rewards on BridgeHubRococo and BridgeHubWestend
|
||||||
|
|
||||||
**Accounts of BridgeHub parachains:**
|
**Accounts of BridgeHub parachains:**
|
||||||
|
|||||||
@@ -490,7 +490,7 @@ mod benches {
|
|||||||
[cumulus_pallet_xcmp_queue, XcmpQueue]
|
[cumulus_pallet_xcmp_queue, XcmpQueue]
|
||||||
[cumulus_pallet_dmp_queue, DmpQueue]
|
[cumulus_pallet_dmp_queue, DmpQueue]
|
||||||
// XCM
|
// XCM
|
||||||
[pallet_xcm, PolkadotXcm]
|
[pallet_xcm, PalletXcmExtrinsiscsBenchmark::<Runtime>]
|
||||||
// NOTE: Make sure you point to the individual modules below.
|
// NOTE: Make sure you point to the individual modules below.
|
||||||
[pallet_xcm_benchmarks::fungible, XcmBalances]
|
[pallet_xcm_benchmarks::fungible, XcmBalances]
|
||||||
[pallet_xcm_benchmarks::generic, XcmGeneric]
|
[pallet_xcm_benchmarks::generic, XcmGeneric]
|
||||||
@@ -670,6 +670,7 @@ impl_runtime_apis! {
|
|||||||
use frame_support::traits::StorageInfoTrait;
|
use frame_support::traits::StorageInfoTrait;
|
||||||
use frame_system_benchmarking::Pallet as SystemBench;
|
use frame_system_benchmarking::Pallet as SystemBench;
|
||||||
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
||||||
|
use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsiscsBenchmark;
|
||||||
|
|
||||||
// This is defined once again in dispatch_benchmark, because list_benchmarks!
|
// This is defined once again in dispatch_benchmark, because list_benchmarks!
|
||||||
// and add_benchmarks! are macros exported by define_benchmarks! macros and those types
|
// and add_benchmarks! are macros exported by define_benchmarks! macros and those types
|
||||||
@@ -705,6 +706,29 @@ impl_runtime_apis! {
|
|||||||
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
||||||
impl cumulus_pallet_session_benchmarking::Config for Runtime {}
|
impl cumulus_pallet_session_benchmarking::Config for Runtime {}
|
||||||
|
|
||||||
|
use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsiscsBenchmark;
|
||||||
|
impl pallet_xcm::benchmarking::Config for Runtime {
|
||||||
|
fn reachable_dest() -> Option<MultiLocation> {
|
||||||
|
Some(Parent.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> {
|
||||||
|
// Relay/native token can be teleported between BH and Relay.
|
||||||
|
Some((
|
||||||
|
MultiAsset {
|
||||||
|
fun: Fungible(EXISTENTIAL_DEPOSIT),
|
||||||
|
id: Concrete(Parent.into())
|
||||||
|
},
|
||||||
|
Parent.into(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> {
|
||||||
|
// Reserve transfers are disabled on BH.
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
use xcm::latest::prelude::*;
|
use xcm::latest::prelude::*;
|
||||||
use xcm_config::KsmRelayLocation;
|
use xcm_config::KsmRelayLocation;
|
||||||
|
|
||||||
|
|||||||
@@ -241,11 +241,6 @@ pub type XcmRouter = WithUniqueTopic<(
|
|||||||
XcmpQueue,
|
XcmpQueue,
|
||||||
)>;
|
)>;
|
||||||
|
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
parameter_types! {
|
|
||||||
pub ReachableDest: Option<MultiLocation> = Some(Parent.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
impl pallet_xcm::Config for Runtime {
|
impl pallet_xcm::Config for Runtime {
|
||||||
type RuntimeEvent = RuntimeEvent;
|
type RuntimeEvent = RuntimeEvent;
|
||||||
// We want to disallow users sending (arbitrary) XCMs from this chain.
|
// We want to disallow users sending (arbitrary) XCMs from this chain.
|
||||||
@@ -274,8 +269,6 @@ impl pallet_xcm::Config for Runtime {
|
|||||||
type SovereignAccountOf = LocationToAccountId;
|
type SovereignAccountOf = LocationToAccountId;
|
||||||
type MaxLockers = ConstU32<8>;
|
type MaxLockers = ConstU32<8>;
|
||||||
type WeightInfo = crate::weights::pallet_xcm::WeightInfo<Runtime>;
|
type WeightInfo = crate::weights::pallet_xcm::WeightInfo<Runtime>;
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
type ReachableDest = ReachableDest;
|
|
||||||
type AdminOrigin = EnsureRoot<AccountId>;
|
type AdminOrigin = EnsureRoot<AccountId>;
|
||||||
type MaxRemoteLockConsumers = ConstU32<0>;
|
type MaxRemoteLockConsumers = ConstU32<0>;
|
||||||
type RemoteLockConsumerIdentifier = ();
|
type RemoteLockConsumerIdentifier = ();
|
||||||
|
|||||||
@@ -47,11 +47,5 @@ bridge_hub_test_utils::test_cases::include_teleports_for_native_asset_works!(
|
|||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
Box::new(|runtime_event_encoded: Vec<u8>| {
|
|
||||||
match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) {
|
|
||||||
Ok(RuntimeEvent::XcmpQueue(event)) => Some(event),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
1002
|
1002
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -491,7 +491,7 @@ mod benches {
|
|||||||
[cumulus_pallet_xcmp_queue, XcmpQueue]
|
[cumulus_pallet_xcmp_queue, XcmpQueue]
|
||||||
[cumulus_pallet_dmp_queue, DmpQueue]
|
[cumulus_pallet_dmp_queue, DmpQueue]
|
||||||
// XCM
|
// XCM
|
||||||
[pallet_xcm, PolkadotXcm]
|
[pallet_xcm, PalletXcmExtrinsiscsBenchmark::<Runtime>]
|
||||||
// NOTE: Make sure you point to the individual modules below.
|
// NOTE: Make sure you point to the individual modules below.
|
||||||
[pallet_xcm_benchmarks::fungible, XcmBalances]
|
[pallet_xcm_benchmarks::fungible, XcmBalances]
|
||||||
[pallet_xcm_benchmarks::generic, XcmGeneric]
|
[pallet_xcm_benchmarks::generic, XcmGeneric]
|
||||||
@@ -671,6 +671,7 @@ impl_runtime_apis! {
|
|||||||
use frame_support::traits::StorageInfoTrait;
|
use frame_support::traits::StorageInfoTrait;
|
||||||
use frame_system_benchmarking::Pallet as SystemBench;
|
use frame_system_benchmarking::Pallet as SystemBench;
|
||||||
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
||||||
|
use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsiscsBenchmark;
|
||||||
|
|
||||||
// This is defined once again in dispatch_benchmark, because list_benchmarks!
|
// This is defined once again in dispatch_benchmark, because list_benchmarks!
|
||||||
// and add_benchmarks! are macros exported by define_benchmarks! macros and those types
|
// and add_benchmarks! are macros exported by define_benchmarks! macros and those types
|
||||||
@@ -706,6 +707,29 @@ impl_runtime_apis! {
|
|||||||
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
||||||
impl cumulus_pallet_session_benchmarking::Config for Runtime {}
|
impl cumulus_pallet_session_benchmarking::Config for Runtime {}
|
||||||
|
|
||||||
|
use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsiscsBenchmark;
|
||||||
|
impl pallet_xcm::benchmarking::Config for Runtime {
|
||||||
|
fn reachable_dest() -> Option<MultiLocation> {
|
||||||
|
Some(Parent.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> {
|
||||||
|
// Relay/native token can be teleported between BH and Relay.
|
||||||
|
Some((
|
||||||
|
MultiAsset {
|
||||||
|
fun: Fungible(EXISTENTIAL_DEPOSIT),
|
||||||
|
id: Concrete(Parent.into())
|
||||||
|
},
|
||||||
|
Parent.into(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> {
|
||||||
|
// Reserve transfers are disabled on BH.
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
use xcm::latest::prelude::*;
|
use xcm::latest::prelude::*;
|
||||||
use xcm_config::DotRelayLocation;
|
use xcm_config::DotRelayLocation;
|
||||||
|
|
||||||
|
|||||||
@@ -245,11 +245,6 @@ pub type XcmRouter = WithUniqueTopic<(
|
|||||||
XcmpQueue,
|
XcmpQueue,
|
||||||
)>;
|
)>;
|
||||||
|
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
parameter_types! {
|
|
||||||
pub ReachableDest: Option<MultiLocation> = Some(Parent.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
impl pallet_xcm::Config for Runtime {
|
impl pallet_xcm::Config for Runtime {
|
||||||
type RuntimeEvent = RuntimeEvent;
|
type RuntimeEvent = RuntimeEvent;
|
||||||
// We want to disallow users sending (arbitrary) XCMs from this chain.
|
// We want to disallow users sending (arbitrary) XCMs from this chain.
|
||||||
@@ -278,8 +273,6 @@ impl pallet_xcm::Config for Runtime {
|
|||||||
type SovereignAccountOf = LocationToAccountId;
|
type SovereignAccountOf = LocationToAccountId;
|
||||||
type MaxLockers = ConstU32<8>;
|
type MaxLockers = ConstU32<8>;
|
||||||
type WeightInfo = crate::weights::pallet_xcm::WeightInfo<Runtime>;
|
type WeightInfo = crate::weights::pallet_xcm::WeightInfo<Runtime>;
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
type ReachableDest = ReachableDest;
|
|
||||||
type AdminOrigin = EnsureRoot<AccountId>;
|
type AdminOrigin = EnsureRoot<AccountId>;
|
||||||
type MaxRemoteLockConsumers = ConstU32<0>;
|
type MaxRemoteLockConsumers = ConstU32<0>;
|
||||||
type RemoteLockConsumerIdentifier = ();
|
type RemoteLockConsumerIdentifier = ();
|
||||||
|
|||||||
@@ -47,11 +47,5 @@ bridge_hub_test_utils::test_cases::include_teleports_for_native_asset_works!(
|
|||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
Box::new(|runtime_event_encoded: Vec<u8>| {
|
|
||||||
match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) {
|
|
||||||
Ok(RuntimeEvent::XcmpQueue(event)) => Some(event),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
1002
|
1002
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -595,7 +595,7 @@ mod benches {
|
|||||||
[cumulus_pallet_xcmp_queue, XcmpQueue]
|
[cumulus_pallet_xcmp_queue, XcmpQueue]
|
||||||
[cumulus_pallet_dmp_queue, DmpQueue]
|
[cumulus_pallet_dmp_queue, DmpQueue]
|
||||||
// XCM
|
// XCM
|
||||||
[pallet_xcm, PolkadotXcm]
|
[pallet_xcm, PalletXcmExtrinsiscsBenchmark::<Runtime>]
|
||||||
// NOTE: Make sure you point to the individual modules below.
|
// NOTE: Make sure you point to the individual modules below.
|
||||||
[pallet_xcm_benchmarks::fungible, XcmBalances]
|
[pallet_xcm_benchmarks::fungible, XcmBalances]
|
||||||
[pallet_xcm_benchmarks::generic, XcmGeneric]
|
[pallet_xcm_benchmarks::generic, XcmGeneric]
|
||||||
@@ -933,6 +933,7 @@ impl_runtime_apis! {
|
|||||||
use frame_support::traits::StorageInfoTrait;
|
use frame_support::traits::StorageInfoTrait;
|
||||||
use frame_system_benchmarking::Pallet as SystemBench;
|
use frame_system_benchmarking::Pallet as SystemBench;
|
||||||
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
||||||
|
use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsiscsBenchmark;
|
||||||
|
|
||||||
// This is defined once again in dispatch_benchmark, because list_benchmarks!
|
// This is defined once again in dispatch_benchmark, because list_benchmarks!
|
||||||
// and add_benchmarks! are macros exported by define_benchmarks! macros and those types
|
// and add_benchmarks! are macros exported by define_benchmarks! macros and those types
|
||||||
@@ -980,6 +981,29 @@ impl_runtime_apis! {
|
|||||||
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
||||||
impl cumulus_pallet_session_benchmarking::Config for Runtime {}
|
impl cumulus_pallet_session_benchmarking::Config for Runtime {}
|
||||||
|
|
||||||
|
use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsiscsBenchmark;
|
||||||
|
impl pallet_xcm::benchmarking::Config for Runtime {
|
||||||
|
fn reachable_dest() -> Option<MultiLocation> {
|
||||||
|
Some(Parent.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> {
|
||||||
|
// Relay/native token can be teleported between BH and Relay.
|
||||||
|
Some((
|
||||||
|
MultiAsset {
|
||||||
|
fun: Fungible(EXISTENTIAL_DEPOSIT),
|
||||||
|
id: Concrete(Parent.into())
|
||||||
|
},
|
||||||
|
Parent.into(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> {
|
||||||
|
// Reserve transfers are disabled on BH.
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
use xcm::latest::prelude::*;
|
use xcm::latest::prelude::*;
|
||||||
use xcm_config::TokenLocation;
|
use xcm_config::TokenLocation;
|
||||||
|
|
||||||
|
|||||||
@@ -349,11 +349,6 @@ pub type XcmRouter = WithUniqueTopic<(
|
|||||||
XcmpQueue,
|
XcmpQueue,
|
||||||
)>;
|
)>;
|
||||||
|
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
parameter_types! {
|
|
||||||
pub ReachableDest: Option<MultiLocation> = Some(Parent.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
impl pallet_xcm::Config for Runtime {
|
impl pallet_xcm::Config for Runtime {
|
||||||
type RuntimeEvent = RuntimeEvent;
|
type RuntimeEvent = RuntimeEvent;
|
||||||
type XcmRouter = XcmRouter;
|
type XcmRouter = XcmRouter;
|
||||||
@@ -381,8 +376,6 @@ impl pallet_xcm::Config for Runtime {
|
|||||||
type SovereignAccountOf = LocationToAccountId;
|
type SovereignAccountOf = LocationToAccountId;
|
||||||
type MaxLockers = ConstU32<8>;
|
type MaxLockers = ConstU32<8>;
|
||||||
type WeightInfo = crate::weights::pallet_xcm::WeightInfo<Runtime>;
|
type WeightInfo = crate::weights::pallet_xcm::WeightInfo<Runtime>;
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
type ReachableDest = ReachableDest;
|
|
||||||
type AdminOrigin = EnsureRoot<AccountId>;
|
type AdminOrigin = EnsureRoot<AccountId>;
|
||||||
type MaxRemoteLockConsumers = ConstU32<0>;
|
type MaxRemoteLockConsumers = ConstU32<0>;
|
||||||
type RemoteLockConsumerIdentifier = ();
|
type RemoteLockConsumerIdentifier = ();
|
||||||
|
|||||||
@@ -133,12 +133,6 @@ mod bridge_hub_rococo_tests {
|
|||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
Box::new(|runtime_event_encoded: Vec<u8>| {
|
|
||||||
match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) {
|
|
||||||
Ok(RuntimeEvent::XcmpQueue(event)) => Some(event),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID
|
bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -517,12 +511,6 @@ mod bridge_hub_wococo_tests {
|
|||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
Box::new(|runtime_event_encoded: Vec<u8>| {
|
|
||||||
match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) {
|
|
||||||
Ok(RuntimeEvent::XcmpQueue(event)) => Some(event),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
bp_bridge_hub_wococo::BRIDGE_HUB_WOCOCO_PARACHAIN_ID
|
bp_bridge_hub_wococo::BRIDGE_HUB_WOCOCO_PARACHAIN_ID
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -544,7 +544,7 @@ mod benches {
|
|||||||
[pallet_collator_selection, CollatorSelection]
|
[pallet_collator_selection, CollatorSelection]
|
||||||
[cumulus_pallet_xcmp_queue, XcmpQueue]
|
[cumulus_pallet_xcmp_queue, XcmpQueue]
|
||||||
// XCM
|
// XCM
|
||||||
[pallet_xcm, PolkadotXcm]
|
[pallet_xcm, PalletXcmExtrinsiscsBenchmark::<Runtime>]
|
||||||
// NOTE: Make sure you point to the individual modules below.
|
// NOTE: Make sure you point to the individual modules below.
|
||||||
[pallet_xcm_benchmarks::fungible, XcmBalances]
|
[pallet_xcm_benchmarks::fungible, XcmBalances]
|
||||||
[pallet_xcm_benchmarks::generic, XcmGeneric]
|
[pallet_xcm_benchmarks::generic, XcmGeneric]
|
||||||
@@ -772,6 +772,7 @@ impl_runtime_apis! {
|
|||||||
use frame_support::traits::StorageInfoTrait;
|
use frame_support::traits::StorageInfoTrait;
|
||||||
use frame_system_benchmarking::Pallet as SystemBench;
|
use frame_system_benchmarking::Pallet as SystemBench;
|
||||||
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
||||||
|
use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsiscsBenchmark;
|
||||||
|
|
||||||
// This is defined once again in dispatch_benchmark, because list_benchmarks!
|
// This is defined once again in dispatch_benchmark, because list_benchmarks!
|
||||||
// and add_benchmarks! are macros exported by define_benchmarks! macros and those types
|
// and add_benchmarks! are macros exported by define_benchmarks! macros and those types
|
||||||
@@ -813,6 +814,29 @@ impl_runtime_apis! {
|
|||||||
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
||||||
impl cumulus_pallet_session_benchmarking::Config for Runtime {}
|
impl cumulus_pallet_session_benchmarking::Config for Runtime {}
|
||||||
|
|
||||||
|
use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsiscsBenchmark;
|
||||||
|
impl pallet_xcm::benchmarking::Config for Runtime {
|
||||||
|
fn reachable_dest() -> Option<MultiLocation> {
|
||||||
|
Some(Parent.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> {
|
||||||
|
// Relay/native token can be teleported between BH and Relay.
|
||||||
|
Some((
|
||||||
|
MultiAsset {
|
||||||
|
fun: Fungible(EXISTENTIAL_DEPOSIT),
|
||||||
|
id: Concrete(Parent.into())
|
||||||
|
},
|
||||||
|
Parent.into(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> {
|
||||||
|
// Reserve transfers are disabled on BH.
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
use xcm::latest::prelude::*;
|
use xcm::latest::prelude::*;
|
||||||
use xcm_config::WestendLocation;
|
use xcm_config::WestendLocation;
|
||||||
|
|
||||||
|
|||||||
@@ -284,11 +284,6 @@ pub type XcmRouter = WithUniqueTopic<(
|
|||||||
XcmpQueue,
|
XcmpQueue,
|
||||||
)>;
|
)>;
|
||||||
|
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
parameter_types! {
|
|
||||||
pub ReachableDest: Option<MultiLocation> = Some(Parent.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
impl pallet_xcm::Config for Runtime {
|
impl pallet_xcm::Config for Runtime {
|
||||||
type RuntimeEvent = RuntimeEvent;
|
type RuntimeEvent = RuntimeEvent;
|
||||||
type XcmRouter = XcmRouter;
|
type XcmRouter = XcmRouter;
|
||||||
@@ -316,8 +311,6 @@ impl pallet_xcm::Config for Runtime {
|
|||||||
type SovereignAccountOf = LocationToAccountId;
|
type SovereignAccountOf = LocationToAccountId;
|
||||||
type MaxLockers = ConstU32<8>;
|
type MaxLockers = ConstU32<8>;
|
||||||
type WeightInfo = crate::weights::pallet_xcm::WeightInfo<Runtime>;
|
type WeightInfo = crate::weights::pallet_xcm::WeightInfo<Runtime>;
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
type ReachableDest = ReachableDest;
|
|
||||||
type AdminOrigin = EnsureRoot<AccountId>;
|
type AdminOrigin = EnsureRoot<AccountId>;
|
||||||
type MaxRemoteLockConsumers = ConstU32<0>;
|
type MaxRemoteLockConsumers = ConstU32<0>;
|
||||||
type RemoteLockConsumerIdentifier = ();
|
type RemoteLockConsumerIdentifier = ();
|
||||||
|
|||||||
@@ -118,12 +118,6 @@ bridge_hub_test_utils::test_cases::include_teleports_for_native_asset_works!(
|
|||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
Box::new(|runtime_event_encoded: Vec<u8>| {
|
|
||||||
match RuntimeEvent::decode(&mut &runtime_event_encoded[..]) {
|
|
||||||
Ok(RuntimeEvent::XcmpQueue(event)) => Some(event),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID
|
bp_bridge_hub_westend::BRIDGE_HUB_WESTEND_PARACHAIN_ID
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -751,7 +751,7 @@ mod benches {
|
|||||||
[cumulus_pallet_dmp_queue, DmpQueue]
|
[cumulus_pallet_dmp_queue, DmpQueue]
|
||||||
[pallet_alliance, Alliance]
|
[pallet_alliance, Alliance]
|
||||||
[pallet_collective, AllianceMotion]
|
[pallet_collective, AllianceMotion]
|
||||||
[pallet_xcm, PolkadotXcm]
|
[pallet_xcm, PalletXcmExtrinsiscsBenchmark::<Runtime>]
|
||||||
[pallet_preimage, Preimage]
|
[pallet_preimage, Preimage]
|
||||||
[pallet_scheduler, Scheduler]
|
[pallet_scheduler, Scheduler]
|
||||||
[pallet_referenda, FellowshipReferenda]
|
[pallet_referenda, FellowshipReferenda]
|
||||||
@@ -939,6 +939,7 @@ impl_runtime_apis! {
|
|||||||
use frame_support::traits::StorageInfoTrait;
|
use frame_support::traits::StorageInfoTrait;
|
||||||
use frame_system_benchmarking::Pallet as SystemBench;
|
use frame_system_benchmarking::Pallet as SystemBench;
|
||||||
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
||||||
|
use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsiscsBenchmark;
|
||||||
|
|
||||||
let mut list = Vec::<BenchmarkList>::new();
|
let mut list = Vec::<BenchmarkList>::new();
|
||||||
list_benchmarks!(list, extra);
|
list_benchmarks!(list, extra);
|
||||||
@@ -968,6 +969,29 @@ impl_runtime_apis! {
|
|||||||
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
||||||
impl cumulus_pallet_session_benchmarking::Config for Runtime {}
|
impl cumulus_pallet_session_benchmarking::Config for Runtime {}
|
||||||
|
|
||||||
|
use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsiscsBenchmark;
|
||||||
|
impl pallet_xcm::benchmarking::Config for Runtime {
|
||||||
|
fn reachable_dest() -> Option<MultiLocation> {
|
||||||
|
Some(Parent.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> {
|
||||||
|
// Relay/native token can be teleported between Collectives and Relay.
|
||||||
|
Some((
|
||||||
|
MultiAsset {
|
||||||
|
fun: Fungible(EXISTENTIAL_DEPOSIT),
|
||||||
|
id: Concrete(Parent.into())
|
||||||
|
}.into(),
|
||||||
|
Parent.into(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> {
|
||||||
|
// Reserve transfers are disabled on Collectives.
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let whitelist: Vec<TrackedStorageKey> = vec![
|
let whitelist: Vec<TrackedStorageKey> = vec![
|
||||||
// Block Number
|
// Block Number
|
||||||
hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac").to_vec().into(),
|
hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac").to_vec().into(),
|
||||||
|
|||||||
@@ -293,11 +293,6 @@ pub type XcmRouter = WithUniqueTopic<(
|
|||||||
XcmpQueue,
|
XcmpQueue,
|
||||||
)>;
|
)>;
|
||||||
|
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
parameter_types! {
|
|
||||||
pub ReachableDest: Option<MultiLocation> = Some(Parent.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Type to convert the Fellows origin to a Plurality `MultiLocation` value.
|
/// Type to convert the Fellows origin to a Plurality `MultiLocation` value.
|
||||||
pub type FellowsToPlurality = OriginToPluralityVoice<RuntimeOrigin, Fellows, FellowsBodyId>;
|
pub type FellowsToPlurality = OriginToPluralityVoice<RuntimeOrigin, Fellows, FellowsBodyId>;
|
||||||
|
|
||||||
@@ -325,8 +320,6 @@ impl pallet_xcm::Config for Runtime {
|
|||||||
type SovereignAccountOf = LocationToAccountId;
|
type SovereignAccountOf = LocationToAccountId;
|
||||||
type MaxLockers = ConstU32<8>;
|
type MaxLockers = ConstU32<8>;
|
||||||
type WeightInfo = crate::weights::pallet_xcm::WeightInfo<Runtime>;
|
type WeightInfo = crate::weights::pallet_xcm::WeightInfo<Runtime>;
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
type ReachableDest = ReachableDest;
|
|
||||||
type AdminOrigin = EnsureRoot<AccountId>;
|
type AdminOrigin = EnsureRoot<AccountId>;
|
||||||
type MaxRemoteLockConsumers = ConstU32<0>;
|
type MaxRemoteLockConsumers = ConstU32<0>;
|
||||||
type RemoteLockConsumerIdentifier = ();
|
type RemoteLockConsumerIdentifier = ();
|
||||||
|
|||||||
@@ -433,7 +433,7 @@ mod benches {
|
|||||||
[pallet_timestamp, Timestamp]
|
[pallet_timestamp, Timestamp]
|
||||||
[pallet_collator_selection, CollatorSelection]
|
[pallet_collator_selection, CollatorSelection]
|
||||||
[pallet_contracts, Contracts]
|
[pallet_contracts, Contracts]
|
||||||
[pallet_xcm, PolkadotXcm]
|
[pallet_xcm, PalletXcmExtrinsiscsBenchmark::<Runtime>]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -678,6 +678,7 @@ impl_runtime_apis! {
|
|||||||
use frame_support::traits::StorageInfoTrait;
|
use frame_support::traits::StorageInfoTrait;
|
||||||
use frame_system_benchmarking::Pallet as SystemBench;
|
use frame_system_benchmarking::Pallet as SystemBench;
|
||||||
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
||||||
|
use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsiscsBenchmark;
|
||||||
|
|
||||||
let mut list = Vec::<BenchmarkList>::new();
|
let mut list = Vec::<BenchmarkList>::new();
|
||||||
list_benchmarks!(list, extra);
|
list_benchmarks!(list, extra);
|
||||||
@@ -707,6 +708,30 @@ impl_runtime_apis! {
|
|||||||
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
|
||||||
impl cumulus_pallet_session_benchmarking::Config for Runtime {}
|
impl cumulus_pallet_session_benchmarking::Config for Runtime {}
|
||||||
|
|
||||||
|
use xcm::latest::prelude::*;
|
||||||
|
use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsiscsBenchmark;
|
||||||
|
impl pallet_xcm::benchmarking::Config for Runtime {
|
||||||
|
fn reachable_dest() -> Option<MultiLocation> {
|
||||||
|
Some(Parent.into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> {
|
||||||
|
// Relay/native token can be teleported between Contracts-System-Para and Relay.
|
||||||
|
Some((
|
||||||
|
MultiAsset {
|
||||||
|
fun: Fungible(EXISTENTIAL_DEPOSIT),
|
||||||
|
id: Concrete(Parent.into())
|
||||||
|
},
|
||||||
|
Parent.into(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> {
|
||||||
|
// Reserve transfers are disabled on Contracts-System-Para.
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let whitelist: Vec<TrackedStorageKey> = vec![
|
let whitelist: Vec<TrackedStorageKey> = vec![
|
||||||
// Block Number
|
// Block Number
|
||||||
hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac").to_vec().into(),
|
hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac").to_vec().into(),
|
||||||
|
|||||||
@@ -227,11 +227,6 @@ pub type XcmRouter = WithUniqueTopic<(
|
|||||||
XcmpQueue,
|
XcmpQueue,
|
||||||
)>;
|
)>;
|
||||||
|
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
parameter_types! {
|
|
||||||
pub ReachableDest: Option<MultiLocation> = Some(Parent.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
impl pallet_xcm::Config for Runtime {
|
impl pallet_xcm::Config for Runtime {
|
||||||
type RuntimeEvent = RuntimeEvent;
|
type RuntimeEvent = RuntimeEvent;
|
||||||
// We want to disallow users sending (arbitrary) XCMs from this chain.
|
// We want to disallow users sending (arbitrary) XCMs from this chain.
|
||||||
@@ -258,8 +253,6 @@ impl pallet_xcm::Config for Runtime {
|
|||||||
type MaxLockers = ConstU32<8>;
|
type MaxLockers = ConstU32<8>;
|
||||||
// FIXME: Replace with benchmarked weight info
|
// FIXME: Replace with benchmarked weight info
|
||||||
type WeightInfo = pallet_xcm::TestWeightInfo;
|
type WeightInfo = pallet_xcm::TestWeightInfo;
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
type ReachableDest = ReachableDest;
|
|
||||||
type AdminOrigin = EnsureRoot<AccountId>;
|
type AdminOrigin = EnsureRoot<AccountId>;
|
||||||
type MaxRemoteLockConsumers = ConstU32<0>;
|
type MaxRemoteLockConsumers = ConstU32<0>;
|
||||||
type RemoteLockConsumerIdentifier = ();
|
type RemoteLockConsumerIdentifier = ();
|
||||||
|
|||||||
@@ -434,7 +434,7 @@ parameter_types! {
|
|||||||
// pub type AssetsForceOrigin =
|
// pub type AssetsForceOrigin =
|
||||||
// EnsureOneOf<EnsureRoot<AccountId>, EnsureXcm<IsMajorityOfBody<KsmLocation, ExecutiveBody>>>;
|
// EnsureOneOf<EnsureRoot<AccountId>, EnsureXcm<IsMajorityOfBody<KsmLocation, ExecutiveBody>>>;
|
||||||
|
|
||||||
impl pallet_assets::Config for Runtime {
|
impl pallet_assets::Config<pallet_assets::Instance1> for Runtime {
|
||||||
type RuntimeEvent = RuntimeEvent;
|
type RuntimeEvent = RuntimeEvent;
|
||||||
type Balance = Balance;
|
type Balance = Balance;
|
||||||
type AssetId = AssetId;
|
type AssetId = AssetId;
|
||||||
@@ -577,7 +577,12 @@ impl pallet_asset_tx_payment::Config for Runtime {
|
|||||||
type RuntimeEvent = RuntimeEvent;
|
type RuntimeEvent = RuntimeEvent;
|
||||||
type Fungibles = Assets;
|
type Fungibles = Assets;
|
||||||
type OnChargeAssetTransaction = pallet_asset_tx_payment::FungiblesAdapter<
|
type OnChargeAssetTransaction = pallet_asset_tx_payment::FungiblesAdapter<
|
||||||
pallet_assets::BalanceToAssetBalance<Balances, Runtime, ConvertInto>,
|
pallet_assets::BalanceToAssetBalance<
|
||||||
|
Balances,
|
||||||
|
Runtime,
|
||||||
|
ConvertInto,
|
||||||
|
pallet_assets::Instance1,
|
||||||
|
>,
|
||||||
AssetsToBlockAuthor<Runtime>,
|
AssetsToBlockAuthor<Runtime>,
|
||||||
>;
|
>;
|
||||||
}
|
}
|
||||||
@@ -619,7 +624,7 @@ construct_runtime!(
|
|||||||
MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event<T>} = 34,
|
MessageQueue: pallet_message_queue::{Pallet, Call, Storage, Event<T>} = 34,
|
||||||
|
|
||||||
// The main stage.
|
// The main stage.
|
||||||
Assets: pallet_assets::{Pallet, Call, Storage, Event<T>} = 50,
|
Assets: pallet_assets::<Instance1>::{Pallet, Call, Storage, Event<T>} = 50,
|
||||||
|
|
||||||
Sudo: pallet_sudo::{Pallet, Call, Storage, Event<T>, Config<T>} = 255,
|
Sudo: pallet_sudo::{Pallet, Call, Storage, Event<T>, Config<T>} = 255,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ use frame_support::{
|
|||||||
};
|
};
|
||||||
use frame_system::EnsureRoot;
|
use frame_system::EnsureRoot;
|
||||||
use pallet_asset_tx_payment::HandleCredit;
|
use pallet_asset_tx_payment::HandleCredit;
|
||||||
|
use pallet_assets::Instance1;
|
||||||
use pallet_xcm::XcmPassthrough;
|
use pallet_xcm::XcmPassthrough;
|
||||||
use polkadot_parachain_primitives::primitives::Sibling;
|
use polkadot_parachain_primitives::primitives::Sibling;
|
||||||
use polkadot_runtime_common::impls::ToAuthor;
|
use polkadot_runtime_common::impls::ToAuthor;
|
||||||
@@ -48,9 +49,10 @@ use xcm_builder::{
|
|||||||
AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, AsPrefixedGeneralIndex,
|
AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, AsPrefixedGeneralIndex,
|
||||||
ConvertedConcreteId, CurrencyAdapter, DenyReserveTransferToRelayChain, DenyThenTry,
|
ConvertedConcreteId, CurrencyAdapter, DenyReserveTransferToRelayChain, DenyThenTry,
|
||||||
EnsureXcmOrigin, FixedWeightBounds, FungiblesAdapter, IsConcrete, LocalMint, NativeAsset,
|
EnsureXcmOrigin, FixedWeightBounds, FungiblesAdapter, IsConcrete, LocalMint, NativeAsset,
|
||||||
ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia,
|
ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative,
|
||||||
SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,
|
SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32,
|
||||||
TrailingSetTopicAsId, UsingComponents, WithComputedOrigin, WithUniqueTopic,
|
SovereignSignedViaLocation, TakeWeightCredit, TrailingSetTopicAsId, UsingComponents,
|
||||||
|
WithComputedOrigin, WithUniqueTopic,
|
||||||
};
|
};
|
||||||
use xcm_executor::{traits::JustTry, XcmExecutor};
|
use xcm_executor::{traits::JustTry, XcmExecutor};
|
||||||
|
|
||||||
@@ -126,6 +128,9 @@ pub type XcmOriginToTransactDispatchOrigin = (
|
|||||||
// Native converter for sibling Parachains; will convert to a `SiblingPara` origin when
|
// Native converter for sibling Parachains; will convert to a `SiblingPara` origin when
|
||||||
// recognized.
|
// recognized.
|
||||||
SiblingParachainAsNative<cumulus_pallet_xcm::Origin, RuntimeOrigin>,
|
SiblingParachainAsNative<cumulus_pallet_xcm::Origin, RuntimeOrigin>,
|
||||||
|
// Superuser converter for the Relay-chain (Parent) location. This will allow it to issue a
|
||||||
|
// transaction from the Root origin.
|
||||||
|
ParentAsSuperuser<RuntimeOrigin>,
|
||||||
// Native signed account converter; this just converts an `AccountId32` origin into a normal
|
// Native signed account converter; this just converts an `AccountId32` origin into a normal
|
||||||
// `RuntimeOrigin::Signed` origin of the same 32-byte value.
|
// `RuntimeOrigin::Signed` origin of the same 32-byte value.
|
||||||
SignedAccountId32AsNative<RelayNetwork, RuntimeOrigin>,
|
SignedAccountId32AsNative<RelayNetwork, RuntimeOrigin>,
|
||||||
@@ -182,14 +187,25 @@ pub type Barrier = TrailingSetTopicAsId<
|
|||||||
/// Type alias to conveniently refer to `frame_system`'s `Config::AccountId`.
|
/// Type alias to conveniently refer to `frame_system`'s `Config::AccountId`.
|
||||||
pub type AccountIdOf<R> = <R as frame_system::Config>::AccountId;
|
pub type AccountIdOf<R> = <R as frame_system::Config>::AccountId;
|
||||||
|
|
||||||
/// Asset filter that allows all assets from a certain location.
|
/// Asset filter that allows all assets from a certain location matching asset id.
|
||||||
pub struct AssetsFrom<T>(PhantomData<T>);
|
pub struct AssetsFrom<T>(PhantomData<T>);
|
||||||
impl<T: Get<MultiLocation>> ContainsPair<MultiAsset, MultiLocation> for AssetsFrom<T> {
|
impl<T: Get<MultiLocation>> ContainsPair<MultiAsset, MultiLocation> for AssetsFrom<T> {
|
||||||
fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool {
|
fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool {
|
||||||
let loc = T::get();
|
let loc = T::get();
|
||||||
&loc == origin &&
|
&loc == origin &&
|
||||||
matches!(asset, MultiAsset { id: AssetId::Concrete(asset_loc), fun: Fungible(_a) }
|
matches!(asset, MultiAsset { id: AssetId::Concrete(asset_loc), fun: Fungible(_a) }
|
||||||
if asset_loc.match_and_split(&loc).is_some())
|
if asset_loc.starts_with(&loc))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Asset filter that allows native/relay asset if coming from a certain location.
|
||||||
|
pub struct NativeAssetFrom<T>(PhantomData<T>);
|
||||||
|
impl<T: Get<MultiLocation>> ContainsPair<MultiAsset, MultiLocation> for NativeAssetFrom<T> {
|
||||||
|
fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool {
|
||||||
|
let loc = T::get();
|
||||||
|
&loc == origin &&
|
||||||
|
matches!(asset, MultiAsset { id: AssetId::Concrete(asset_loc), fun: Fungible(_a) }
|
||||||
|
if *asset_loc == MultiLocation::from(Parent))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,56 +224,19 @@ where
|
|||||||
/// A `HandleCredit` implementation that naively transfers the fees to the block author.
|
/// A `HandleCredit` implementation that naively transfers the fees to the block author.
|
||||||
/// Will drop and burn the assets in case the transfer fails.
|
/// Will drop and burn the assets in case the transfer fails.
|
||||||
pub struct AssetsToBlockAuthor<R>(PhantomData<R>);
|
pub struct AssetsToBlockAuthor<R>(PhantomData<R>);
|
||||||
impl<R> HandleCredit<AccountIdOf<R>, pallet_assets::Pallet<R>> for AssetsToBlockAuthor<R>
|
impl<R> HandleCredit<AccountIdOf<R>, pallet_assets::Pallet<R, Instance1>> for AssetsToBlockAuthor<R>
|
||||||
where
|
where
|
||||||
R: pallet_authorship::Config + pallet_assets::Config,
|
R: pallet_authorship::Config + pallet_assets::Config<Instance1>,
|
||||||
AccountIdOf<R>: From<polkadot_primitives::AccountId> + Into<polkadot_primitives::AccountId>,
|
AccountIdOf<R>: From<polkadot_primitives::AccountId> + Into<polkadot_primitives::AccountId>,
|
||||||
{
|
{
|
||||||
fn handle_credit(credit: Credit<AccountIdOf<R>, pallet_assets::Pallet<R>>) {
|
fn handle_credit(credit: Credit<AccountIdOf<R>, pallet_assets::Pallet<R, Instance1>>) {
|
||||||
if let Some(author) = pallet_authorship::Pallet::<R>::author() {
|
if let Some(author) = pallet_authorship::Pallet::<R>::author() {
|
||||||
// In case of error: Will drop the result triggering the `OnDrop` of the imbalance.
|
// In case of error: Will drop the result triggering the `OnDrop` of the imbalance.
|
||||||
let _ = pallet_assets::Pallet::<R>::resolve(&author, credit);
|
let _ = pallet_assets::Pallet::<R, Instance1>::resolve(&author, credit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Reserve {
|
|
||||||
/// Returns assets reserve location.
|
|
||||||
fn reserve(&self) -> Option<MultiLocation>;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Takes the chain part of a MultiAsset
|
|
||||||
impl Reserve for MultiAsset {
|
|
||||||
fn reserve(&self) -> Option<MultiLocation> {
|
|
||||||
if let AssetId::Concrete(location) = self.id {
|
|
||||||
let first_interior = location.first_interior();
|
|
||||||
let parents = location.parent_count();
|
|
||||||
match (parents, first_interior) {
|
|
||||||
(0, Some(Parachain(id))) => Some(MultiLocation::new(0, X1(Parachain(*id)))),
|
|
||||||
(1, Some(Parachain(id))) => Some(MultiLocation::new(1, X1(Parachain(*id)))),
|
|
||||||
(1, _) => Some(MultiLocation::parent()),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A `FilterAssetLocation` implementation. Filters multi native assets whose
|
|
||||||
/// reserve is same with `origin`.
|
|
||||||
pub struct MultiNativeAsset;
|
|
||||||
impl ContainsPair<MultiAsset, MultiLocation> for MultiNativeAsset {
|
|
||||||
fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool {
|
|
||||||
if let Some(ref reserve) = asset.reserve() {
|
|
||||||
if reserve == origin {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
/// The location that this chain recognizes as the Relay network's Asset Hub.
|
/// The location that this chain recognizes as the Relay network's Asset Hub.
|
||||||
pub SystemAssetHubLocation: MultiLocation = MultiLocation::new(1, X1(Parachain(1000)));
|
pub SystemAssetHubLocation: MultiLocation = MultiLocation::new(1, X1(Parachain(1000)));
|
||||||
@@ -268,7 +247,8 @@ parameter_types! {
|
|||||||
pub CheckingAccount: AccountId = PolkadotXcm::check_account();
|
pub CheckingAccount: AccountId = PolkadotXcm::check_account();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Reserves = (NativeAsset, AssetsFrom<SystemAssetHubLocation>);
|
pub type Reserves =
|
||||||
|
(NativeAsset, AssetsFrom<SystemAssetHubLocation>, NativeAssetFrom<SystemAssetHubLocation>);
|
||||||
|
|
||||||
pub struct XcmConfig;
|
pub struct XcmConfig;
|
||||||
impl xcm_executor::Config for XcmConfig {
|
impl xcm_executor::Config for XcmConfig {
|
||||||
@@ -277,7 +257,8 @@ impl xcm_executor::Config for XcmConfig {
|
|||||||
// How to withdraw and deposit an asset.
|
// How to withdraw and deposit an asset.
|
||||||
type AssetTransactor = AssetTransactors;
|
type AssetTransactor = AssetTransactors;
|
||||||
type OriginConverter = XcmOriginToTransactDispatchOrigin;
|
type OriginConverter = XcmOriginToTransactDispatchOrigin;
|
||||||
type IsReserve = MultiNativeAsset; // TODO: maybe needed to be replaced by Reserves
|
type IsReserve = Reserves;
|
||||||
|
// no teleport trust established with other chains
|
||||||
type IsTeleporter = NativeAsset;
|
type IsTeleporter = NativeAsset;
|
||||||
type UniversalLocation = UniversalLocation;
|
type UniversalLocation = UniversalLocation;
|
||||||
type Barrier = Barrier;
|
type Barrier = Barrier;
|
||||||
@@ -312,11 +293,6 @@ pub type XcmRouter = WithUniqueTopic<(
|
|||||||
XcmpQueue,
|
XcmpQueue,
|
||||||
)>;
|
)>;
|
||||||
|
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
parameter_types! {
|
|
||||||
pub ReachableDest: Option<MultiLocation> = Some(Parent.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
impl pallet_xcm::Config for Runtime {
|
impl pallet_xcm::Config for Runtime {
|
||||||
type RuntimeEvent = RuntimeEvent;
|
type RuntimeEvent = RuntimeEvent;
|
||||||
type SendXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
|
type SendXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
|
||||||
@@ -342,8 +318,6 @@ impl pallet_xcm::Config for Runtime {
|
|||||||
type SovereignAccountOf = LocationToAccountId;
|
type SovereignAccountOf = LocationToAccountId;
|
||||||
type MaxLockers = ConstU32<8>;
|
type MaxLockers = ConstU32<8>;
|
||||||
type WeightInfo = pallet_xcm::TestWeightInfo;
|
type WeightInfo = pallet_xcm::TestWeightInfo;
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
type ReachableDest = ReachableDest;
|
|
||||||
type AdminOrigin = EnsureRoot<AccountId>;
|
type AdminOrigin = EnsureRoot<AccountId>;
|
||||||
type MaxRemoteLockConsumers = ConstU32<0>;
|
type MaxRemoteLockConsumers = ConstU32<0>;
|
||||||
type RemoteLockConsumerIdentifier = ();
|
type RemoteLockConsumerIdentifier = ();
|
||||||
|
|||||||
@@ -492,11 +492,6 @@ pub type XcmRouter = WithUniqueTopic<(
|
|||||||
XcmpQueue,
|
XcmpQueue,
|
||||||
)>;
|
)>;
|
||||||
|
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
parameter_types! {
|
|
||||||
pub ReachableDest: Option<MultiLocation> = Some(Parent.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
impl pallet_xcm::Config for Runtime {
|
impl pallet_xcm::Config for Runtime {
|
||||||
type RuntimeEvent = RuntimeEvent;
|
type RuntimeEvent = RuntimeEvent;
|
||||||
type SendXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
|
type SendXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
|
||||||
@@ -518,8 +513,6 @@ impl pallet_xcm::Config for Runtime {
|
|||||||
type SovereignAccountOf = LocationToAccountId;
|
type SovereignAccountOf = LocationToAccountId;
|
||||||
type MaxLockers = ConstU32<8>;
|
type MaxLockers = ConstU32<8>;
|
||||||
type WeightInfo = pallet_xcm::TestWeightInfo;
|
type WeightInfo = pallet_xcm::TestWeightInfo;
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
type ReachableDest = ReachableDest;
|
|
||||||
type AdminOrigin = EnsureRoot<AccountId>;
|
type AdminOrigin = EnsureRoot<AccountId>;
|
||||||
type MaxRemoteLockConsumers = ConstU32<0>;
|
type MaxRemoteLockConsumers = ConstU32<0>;
|
||||||
type RemoteLockConsumerIdentifier = ();
|
type RemoteLockConsumerIdentifier = ();
|
||||||
|
|||||||
@@ -301,9 +301,21 @@ case "$1" in
|
|||||||
0 \
|
0 \
|
||||||
"Unlimited"
|
"Unlimited"
|
||||||
;;
|
;;
|
||||||
|
withdraw-reserve-assets-from-asset-hub-rococo-local)
|
||||||
|
ensure_polkadot_js_api
|
||||||
|
# send back only 100000000000 wrappedWNDs to Alice account on AHW
|
||||||
|
limited_reserve_transfer_assets \
|
||||||
|
"ws://127.0.0.1:9910" \
|
||||||
|
"//Alice" \
|
||||||
|
"$(jq --null-input '{ "V3": { "parents": 2, "interior": { "X2": [ { "GlobalConsensus": "Westend" }, { "Parachain": 1000 } ] } } }')" \
|
||||||
|
"$(jq --null-input '{ "V3": { "parents": 0, "interior": { "X1": { "AccountId32": { "id": [212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125] } } } } }')" \
|
||||||
|
"$(jq --null-input '{ "V3": [ { "id": { "Concrete": { "parents": 2, "interior": { "X1": { "GlobalConsensus": "Westend" } } } }, "fun": { "Fungible": 140000000000 } } ] }')" \
|
||||||
|
0 \
|
||||||
|
"Unlimited"
|
||||||
|
;;
|
||||||
reserve-transfer-assets-from-asset-hub-westend-local)
|
reserve-transfer-assets-from-asset-hub-westend-local)
|
||||||
ensure_polkadot_js_api
|
ensure_polkadot_js_api
|
||||||
# send WOCs to Alice account on AHR
|
# send WNDs to Alice account on AHR
|
||||||
limited_reserve_transfer_assets \
|
limited_reserve_transfer_assets \
|
||||||
"ws://127.0.0.1:9010" \
|
"ws://127.0.0.1:9010" \
|
||||||
"//Alice" \
|
"//Alice" \
|
||||||
@@ -313,6 +325,18 @@ case "$1" in
|
|||||||
0 \
|
0 \
|
||||||
"Unlimited"
|
"Unlimited"
|
||||||
;;
|
;;
|
||||||
|
withdraw-reserve-assets-from-asset-hub-westend-local)
|
||||||
|
ensure_polkadot_js_api
|
||||||
|
# send back only 100000000000 wrappedROCs to Alice account on AHR
|
||||||
|
limited_reserve_transfer_assets \
|
||||||
|
"ws://127.0.0.1:9010" \
|
||||||
|
"//Alice" \
|
||||||
|
"$(jq --null-input '{ "V3": { "parents": 2, "interior": { "X2": [ { "GlobalConsensus": "Rococo" }, { "Parachain": 1000 } ] } } }')" \
|
||||||
|
"$(jq --null-input '{ "V3": { "parents": 0, "interior": { "X1": { "AccountId32": { "id": [212, 53, 147, 199, 21, 253, 211, 28, 97, 20, 26, 189, 4, 169, 159, 214, 130, 44, 133, 88, 133, 76, 205, 227, 154, 86, 132, 231, 165, 109, 162, 125] } } } } }')" \
|
||||||
|
"$(jq --null-input '{ "V3": [ { "id": { "Concrete": { "parents": 2, "interior": { "X1": { "GlobalConsensus": "Rococo" } } } }, "fun": { "Fungible": 100000000000 } } ] }')" \
|
||||||
|
0 \
|
||||||
|
"Unlimited"
|
||||||
|
;;
|
||||||
claim-rewards-bridge-hub-rococo-local)
|
claim-rewards-bridge-hub-rococo-local)
|
||||||
ensure_polkadot_js_api
|
ensure_polkadot_js_api
|
||||||
# bhwd -> [62, 68, 77, 64] -> 0x62687764
|
# bhwd -> [62, 68, 77, 64] -> 0x62687764
|
||||||
@@ -360,7 +384,9 @@ case "$1" in
|
|||||||
- init-asset-hub-westend-local
|
- init-asset-hub-westend-local
|
||||||
- init-bridge-hub-westend-local
|
- init-bridge-hub-westend-local
|
||||||
- reserve-transfer-assets-from-asset-hub-rococo-local
|
- reserve-transfer-assets-from-asset-hub-rococo-local
|
||||||
|
- withdraw-reserve-assets-from-asset-hub-rococo-local
|
||||||
- reserve-transfer-assets-from-asset-hub-westend-local
|
- reserve-transfer-assets-from-asset-hub-westend-local
|
||||||
|
- withdraw-reserve-assets-from-asset-hub-westend-local
|
||||||
- claim-rewards-bridge-hub-rococo-local
|
- claim-rewards-bridge-hub-rococo-local
|
||||||
- claim-rewards-bridge-hub-westend-local";
|
- claim-rewards-bridge-hub-westend-local";
|
||||||
exit 1
|
exit 1
|
||||||
|
|||||||
@@ -1443,9 +1443,9 @@ pub struct TestContext<T, Origin: Chain, Destination: Chain> {
|
|||||||
/// These arguments can be easily reused and shared between the assertion functions
|
/// These arguments can be easily reused and shared between the assertion functions
|
||||||
/// and dispatchable functions, which are also stored in `Test`.
|
/// and dispatchable functions, which are also stored in `Test`.
|
||||||
/// `Origin` corresponds to the chain where the XCM interaction starts with an initial execution.
|
/// `Origin` corresponds to the chain where the XCM interaction starts with an initial execution.
|
||||||
/// `Destination` corresponds to the last chain where an effect of the intial execution is expected
|
/// `Destination` corresponds to the last chain where an effect of the initial execution is expected
|
||||||
/// happen. `Hops` refer all the ordered intermediary chains an initial XCM execution can provoke
|
/// to happen. `Hops` refer to all the ordered intermediary chains an initial XCM execution can
|
||||||
/// some effect.
|
/// provoke some effect on.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Test<Origin, Destination, Hops = (), Args = TestArgs>
|
pub struct Test<Origin, Destination, Hops = (), Args = TestArgs>
|
||||||
where
|
where
|
||||||
@@ -1499,7 +1499,7 @@ where
|
|||||||
let chain_name = std::any::type_name::<Hop>();
|
let chain_name = std::any::type_name::<Hop>();
|
||||||
self.hops_assertion.insert(chain_name.to_string(), assertion);
|
self.hops_assertion.insert(chain_name.to_string(), assertion);
|
||||||
}
|
}
|
||||||
/// Stores an assertion in a particular Chain
|
/// Stores a dispatchable in a particular Chain
|
||||||
pub fn set_dispatchable<Hop>(&mut self, dispatchable: fn(Self) -> DispatchResult) {
|
pub fn set_dispatchable<Hop>(&mut self, dispatchable: fn(Self) -> DispatchResult) {
|
||||||
let chain_name = std::any::type_name::<Hop>();
|
let chain_name = std::any::type_name::<Hop>();
|
||||||
self.hops_dispatchable.insert(chain_name.to_string(), dispatchable);
|
self.hops_dispatchable.insert(chain_name.to_string(), dispatchable);
|
||||||
|
|||||||
@@ -2064,7 +2064,7 @@ impl<T: Config> Pallet<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Submits a given PVF check statement with corresponding signature as an unsigned transaction
|
/// Submits a given PVF check statement with corresponding signature as an unsigned transaction
|
||||||
/// into the memory pool. Ultimately, that disseminates the transaction accross the network.
|
/// into the memory pool. Ultimately, that disseminates the transaction across the network.
|
||||||
///
|
///
|
||||||
/// This function expects an offchain context and cannot be callable from the on-chain logic.
|
/// This function expects an offchain context and cannot be callable from the on-chain logic.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -1588,7 +1588,7 @@ mod benches {
|
|||||||
[pallet_asset_rate, AssetRate]
|
[pallet_asset_rate, AssetRate]
|
||||||
[pallet_whitelist, Whitelist]
|
[pallet_whitelist, Whitelist]
|
||||||
// XCM
|
// XCM
|
||||||
[pallet_xcm, XcmPallet]
|
[pallet_xcm, PalletXcmExtrinsiscsBenchmark::<Runtime>]
|
||||||
[pallet_xcm_benchmarks::fungible, pallet_xcm_benchmarks::fungible::Pallet::<Runtime>]
|
[pallet_xcm_benchmarks::fungible, pallet_xcm_benchmarks::fungible::Pallet::<Runtime>]
|
||||||
[pallet_xcm_benchmarks::generic, pallet_xcm_benchmarks::generic::Pallet::<Runtime>]
|
[pallet_xcm_benchmarks::generic, pallet_xcm_benchmarks::generic::Pallet::<Runtime>]
|
||||||
);
|
);
|
||||||
@@ -2064,6 +2064,8 @@ sp_api::impl_runtime_apis! {
|
|||||||
use frame_system_benchmarking::Pallet as SystemBench;
|
use frame_system_benchmarking::Pallet as SystemBench;
|
||||||
use frame_benchmarking::baseline::Pallet as Baseline;
|
use frame_benchmarking::baseline::Pallet as Baseline;
|
||||||
|
|
||||||
|
use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsiscsBenchmark;
|
||||||
|
|
||||||
let mut list = Vec::<BenchmarkList>::new();
|
let mut list = Vec::<BenchmarkList>::new();
|
||||||
list_benchmarks!(list, extra);
|
list_benchmarks!(list, extra);
|
||||||
|
|
||||||
@@ -2081,6 +2083,7 @@ sp_api::impl_runtime_apis! {
|
|||||||
use frame_benchmarking::{Benchmarking, BenchmarkBatch, BenchmarkError};
|
use frame_benchmarking::{Benchmarking, BenchmarkBatch, BenchmarkError};
|
||||||
use frame_system_benchmarking::Pallet as SystemBench;
|
use frame_system_benchmarking::Pallet as SystemBench;
|
||||||
use frame_benchmarking::baseline::Pallet as Baseline;
|
use frame_benchmarking::baseline::Pallet as Baseline;
|
||||||
|
use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsiscsBenchmark;
|
||||||
use sp_storage::TrackedStorageKey;
|
use sp_storage::TrackedStorageKey;
|
||||||
use xcm::latest::prelude::*;
|
use xcm::latest::prelude::*;
|
||||||
use xcm_config::{
|
use xcm_config::{
|
||||||
@@ -2097,6 +2100,33 @@ sp_api::impl_runtime_apis! {
|
|||||||
|
|
||||||
impl frame_system_benchmarking::Config for Runtime {}
|
impl frame_system_benchmarking::Config for Runtime {}
|
||||||
impl frame_benchmarking::baseline::Config for Runtime {}
|
impl frame_benchmarking::baseline::Config for Runtime {}
|
||||||
|
impl pallet_xcm::benchmarking::Config for Runtime {
|
||||||
|
fn reachable_dest() -> Option<MultiLocation> {
|
||||||
|
Some(crate::xcm_config::AssetHub::get())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> {
|
||||||
|
// Relay/native token can be teleported to/from AH.
|
||||||
|
Some((
|
||||||
|
MultiAsset {
|
||||||
|
fun: Fungible(EXISTENTIAL_DEPOSIT),
|
||||||
|
id: Concrete(Here.into())
|
||||||
|
},
|
||||||
|
crate::xcm_config::AssetHub::get(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> {
|
||||||
|
// Relay can reserve transfer native token to some random parachain.
|
||||||
|
Some((
|
||||||
|
MultiAsset {
|
||||||
|
fun: Fungible(EXISTENTIAL_DEPOSIT),
|
||||||
|
id: Concrete(Here.into())
|
||||||
|
},
|
||||||
|
Parachain(43211234).into(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
impl pallet_xcm_benchmarks::Config for Runtime {
|
impl pallet_xcm_benchmarks::Config for Runtime {
|
||||||
type XcmConfig = XcmConfig;
|
type XcmConfig = XcmConfig;
|
||||||
type AccountIdConverter = LocationConverter;
|
type AccountIdConverter = LocationConverter;
|
||||||
|
|||||||
@@ -211,11 +211,6 @@ parameter_types! {
|
|||||||
pub const FellowsBodyId: BodyId = BodyId::Technical;
|
pub const FellowsBodyId: BodyId = BodyId::Technical;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
parameter_types! {
|
|
||||||
pub ReachableDest: Option<MultiLocation> = Some(Parachain(ASSET_HUB_ID).into());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Type to convert an `Origin` type value into a `MultiLocation` value which represents an interior
|
/// Type to convert an `Origin` type value into a `MultiLocation` value which represents an interior
|
||||||
/// location of this chain.
|
/// location of this chain.
|
||||||
pub type LocalOriginToLocation = (
|
pub type LocalOriginToLocation = (
|
||||||
@@ -269,7 +264,5 @@ impl pallet_xcm::Config for Runtime {
|
|||||||
type MaxRemoteLockConsumers = ConstU32<0>;
|
type MaxRemoteLockConsumers = ConstU32<0>;
|
||||||
type RemoteLockConsumerIdentifier = ();
|
type RemoteLockConsumerIdentifier = ();
|
||||||
type WeightInfo = crate::weights::pallet_xcm::WeightInfo<Runtime>;
|
type WeightInfo = crate::weights::pallet_xcm::WeightInfo<Runtime>;
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
type ReachableDest = ReachableDest;
|
|
||||||
type AdminOrigin = EnsureRoot<AccountId>;
|
type AdminOrigin = EnsureRoot<AccountId>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,11 +127,6 @@ impl xcm_executor::Config for XcmConfig {
|
|||||||
type Aliasers = Nothing;
|
type Aliasers = Nothing;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
parameter_types! {
|
|
||||||
pub ReachableDest: Option<MultiLocation> = Some(xcm::latest::Junctions::Here.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
impl pallet_xcm::Config for crate::Runtime {
|
impl pallet_xcm::Config for crate::Runtime {
|
||||||
// The config types here are entirely configurable, since the only one that is sorely needed
|
// The config types here are entirely configurable, since the only one that is sorely needed
|
||||||
// is `XcmExecutor`, which will be used in unit tests located in xcm-executor.
|
// is `XcmExecutor`, which will be used in unit tests located in xcm-executor.
|
||||||
@@ -157,7 +152,5 @@ impl pallet_xcm::Config for crate::Runtime {
|
|||||||
type MaxRemoteLockConsumers = frame_support::traits::ConstU32<0>;
|
type MaxRemoteLockConsumers = frame_support::traits::ConstU32<0>;
|
||||||
type RemoteLockConsumerIdentifier = ();
|
type RemoteLockConsumerIdentifier = ();
|
||||||
type WeightInfo = pallet_xcm::TestWeightInfo;
|
type WeightInfo = pallet_xcm::TestWeightInfo;
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
type ReachableDest = ReachableDest;
|
|
||||||
type AdminOrigin = EnsureRoot<crate::AccountId>;
|
type AdminOrigin = EnsureRoot<crate::AccountId>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1626,7 +1626,7 @@ mod benches {
|
|||||||
[pallet_whitelist, Whitelist]
|
[pallet_whitelist, Whitelist]
|
||||||
[pallet_asset_rate, AssetRate]
|
[pallet_asset_rate, AssetRate]
|
||||||
// XCM
|
// XCM
|
||||||
[pallet_xcm, XcmPallet]
|
[pallet_xcm, PalletXcmExtrinsiscsBenchmark::<Runtime>]
|
||||||
// NOTE: Make sure you point to the individual modules below.
|
// NOTE: Make sure you point to the individual modules below.
|
||||||
[pallet_xcm_benchmarks::fungible, XcmBalances]
|
[pallet_xcm_benchmarks::fungible, XcmBalances]
|
||||||
[pallet_xcm_benchmarks::generic, XcmGeneric]
|
[pallet_xcm_benchmarks::generic, XcmGeneric]
|
||||||
@@ -2145,6 +2145,7 @@ sp_api::impl_runtime_apis! {
|
|||||||
use pallet_session_benchmarking::Pallet as SessionBench;
|
use pallet_session_benchmarking::Pallet as SessionBench;
|
||||||
use pallet_offences_benchmarking::Pallet as OffencesBench;
|
use pallet_offences_benchmarking::Pallet as OffencesBench;
|
||||||
use pallet_election_provider_support_benchmarking::Pallet as ElectionProviderBench;
|
use pallet_election_provider_support_benchmarking::Pallet as ElectionProviderBench;
|
||||||
|
use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsiscsBenchmark;
|
||||||
use frame_system_benchmarking::Pallet as SystemBench;
|
use frame_system_benchmarking::Pallet as SystemBench;
|
||||||
use pallet_nomination_pools_benchmarking::Pallet as NominationPoolsBench;
|
use pallet_nomination_pools_benchmarking::Pallet as NominationPoolsBench;
|
||||||
|
|
||||||
@@ -2172,12 +2173,37 @@ sp_api::impl_runtime_apis! {
|
|||||||
use pallet_session_benchmarking::Pallet as SessionBench;
|
use pallet_session_benchmarking::Pallet as SessionBench;
|
||||||
use pallet_offences_benchmarking::Pallet as OffencesBench;
|
use pallet_offences_benchmarking::Pallet as OffencesBench;
|
||||||
use pallet_election_provider_support_benchmarking::Pallet as ElectionProviderBench;
|
use pallet_election_provider_support_benchmarking::Pallet as ElectionProviderBench;
|
||||||
|
use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsiscsBenchmark;
|
||||||
use frame_system_benchmarking::Pallet as SystemBench;
|
use frame_system_benchmarking::Pallet as SystemBench;
|
||||||
use pallet_nomination_pools_benchmarking::Pallet as NominationPoolsBench;
|
use pallet_nomination_pools_benchmarking::Pallet as NominationPoolsBench;
|
||||||
|
|
||||||
impl pallet_session_benchmarking::Config for Runtime {}
|
impl pallet_session_benchmarking::Config for Runtime {}
|
||||||
impl pallet_offences_benchmarking::Config for Runtime {}
|
impl pallet_offences_benchmarking::Config for Runtime {}
|
||||||
impl pallet_election_provider_support_benchmarking::Config for Runtime {}
|
impl pallet_election_provider_support_benchmarking::Config for Runtime {}
|
||||||
|
impl pallet_xcm::benchmarking::Config for Runtime {
|
||||||
|
fn reachable_dest() -> Option<MultiLocation> {
|
||||||
|
Some(crate::xcm_config::AssetHub::get())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> {
|
||||||
|
// Relay/native token can be teleported to/from AH.
|
||||||
|
Some((
|
||||||
|
MultiAsset { fun: Fungible(EXISTENTIAL_DEPOSIT), id: Concrete(Here.into()) },
|
||||||
|
crate::xcm_config::AssetHub::get(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> {
|
||||||
|
// Relay can reserve transfer native token to some random parachain.
|
||||||
|
Some((
|
||||||
|
MultiAsset {
|
||||||
|
fun: Fungible(EXISTENTIAL_DEPOSIT),
|
||||||
|
id: Concrete(Here.into())
|
||||||
|
},
|
||||||
|
crate::Junction::Parachain(43211234).into(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
impl frame_system_benchmarking::Config for Runtime {}
|
impl frame_system_benchmarking::Config for Runtime {}
|
||||||
impl pallet_nomination_pools_benchmarking::Config for Runtime {}
|
impl pallet_nomination_pools_benchmarking::Config for Runtime {}
|
||||||
impl runtime_parachains::disputes::slashing::benchmarking::Config for Runtime {}
|
impl runtime_parachains::disputes::slashing::benchmarking::Config for Runtime {}
|
||||||
|
|||||||
@@ -119,11 +119,6 @@ parameter_types! {
|
|||||||
pub const MaxAssetsIntoHolding: u32 = 64;
|
pub const MaxAssetsIntoHolding: u32 = 64;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
parameter_types! {
|
|
||||||
pub ReachableDest: Option<MultiLocation> = Some(Parachain(ASSET_HUB_ID).into());
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type TrustedTeleporters = (
|
pub type TrustedTeleporters = (
|
||||||
xcm_builder::Case<WndForAssetHub>,
|
xcm_builder::Case<WndForAssetHub>,
|
||||||
xcm_builder::Case<WndForCollectives>,
|
xcm_builder::Case<WndForCollectives>,
|
||||||
@@ -265,7 +260,5 @@ impl pallet_xcm::Config for Runtime {
|
|||||||
type MaxRemoteLockConsumers = ConstU32<0>;
|
type MaxRemoteLockConsumers = ConstU32<0>;
|
||||||
type RemoteLockConsumerIdentifier = ();
|
type RemoteLockConsumerIdentifier = ();
|
||||||
type WeightInfo = crate::weights::pallet_xcm::WeightInfo<Runtime>;
|
type WeightInfo = crate::weights::pallet_xcm::WeightInfo<Runtime>;
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
type ReachableDest = ReachableDest;
|
|
||||||
type AdminOrigin = EnsureRoot<AccountId>;
|
type AdminOrigin = EnsureRoot<AccountId>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ scale-info = { version = "2.10.0", default-features = false, features = ["derive
|
|||||||
serde = { version = "1.0.188", optional = true, features = ["derive"] }
|
serde = { version = "1.0.188", optional = true, features = ["derive"] }
|
||||||
log = { version = "0.4.17", default-features = false }
|
log = { version = "0.4.17", default-features = false }
|
||||||
|
|
||||||
frame-benchmarking = { path = "../../../substrate/frame/benchmarking", default-features = false, optional = true }
|
|
||||||
frame-support = { path = "../../../substrate/frame/support", default-features = false}
|
frame-support = { path = "../../../substrate/frame/support", default-features = false}
|
||||||
frame-system = { path = "../../../substrate/frame/system", default-features = false}
|
frame-system = { path = "../../../substrate/frame/system", default-features = false}
|
||||||
sp-core = { path = "../../../substrate/primitives/core", default-features = false}
|
sp-core = { path = "../../../substrate/primitives/core", default-features = false}
|
||||||
@@ -25,8 +24,12 @@ xcm = { package = "staging-xcm", path = "..", default-features = false }
|
|||||||
xcm-executor = { package = "staging-xcm-executor", path = "../xcm-executor", default-features = false }
|
xcm-executor = { package = "staging-xcm-executor", path = "../xcm-executor", default-features = false }
|
||||||
xcm-builder = { package = "staging-xcm-builder", path = "../xcm-builder", default-features = false }
|
xcm-builder = { package = "staging-xcm-builder", path = "../xcm-builder", default-features = false }
|
||||||
|
|
||||||
|
# marked optional, used in benchmarking
|
||||||
|
frame-benchmarking = { path = "../../../substrate/frame/benchmarking", default-features = false, optional = true }
|
||||||
|
pallet-balances = { path = "../../../substrate/frame/balances", default-features = false, optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
pallet-balances = { path = "../../../substrate/frame/balances" }
|
pallet-assets = { path = "../../../substrate/frame/assets" }
|
||||||
polkadot-runtime-parachains = { path = "../../runtime/parachains" }
|
polkadot-runtime-parachains = { path = "../../runtime/parachains" }
|
||||||
polkadot-parachain-primitives = { path = "../../parachain" }
|
polkadot-parachain-primitives = { path = "../../parachain" }
|
||||||
|
|
||||||
@@ -39,6 +42,7 @@ std = [
|
|||||||
"frame-support/std",
|
"frame-support/std",
|
||||||
"frame-system/std",
|
"frame-system/std",
|
||||||
"log/std",
|
"log/std",
|
||||||
|
"pallet-balances/std",
|
||||||
"scale-info/std",
|
"scale-info/std",
|
||||||
"serde",
|
"serde",
|
||||||
"sp-core/std",
|
"sp-core/std",
|
||||||
@@ -53,6 +57,7 @@ runtime-benchmarks = [
|
|||||||
"frame-benchmarking/runtime-benchmarks",
|
"frame-benchmarking/runtime-benchmarks",
|
||||||
"frame-support/runtime-benchmarks",
|
"frame-support/runtime-benchmarks",
|
||||||
"frame-system/runtime-benchmarks",
|
"frame-system/runtime-benchmarks",
|
||||||
|
"pallet-assets/runtime-benchmarks",
|
||||||
"pallet-balances/runtime-benchmarks",
|
"pallet-balances/runtime-benchmarks",
|
||||||
"polkadot-parachain-primitives/runtime-benchmarks",
|
"polkadot-parachain-primitives/runtime-benchmarks",
|
||||||
"polkadot-runtime-parachains/runtime-benchmarks",
|
"polkadot-runtime-parachains/runtime-benchmarks",
|
||||||
@@ -63,6 +68,7 @@ runtime-benchmarks = [
|
|||||||
try-runtime = [
|
try-runtime = [
|
||||||
"frame-support/try-runtime",
|
"frame-support/try-runtime",
|
||||||
"frame-system/try-runtime",
|
"frame-system/try-runtime",
|
||||||
|
"pallet-assets/try-runtime",
|
||||||
"pallet-balances/try-runtime",
|
"pallet-balances/try-runtime",
|
||||||
"polkadot-runtime-parachains/try-runtime",
|
"polkadot-runtime-parachains/try-runtime",
|
||||||
"sp-runtime/try-runtime",
|
"sp-runtime/try-runtime",
|
||||||
|
|||||||
@@ -16,15 +16,56 @@
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use bounded_collections::{ConstU32, WeakBoundedVec};
|
use bounded_collections::{ConstU32, WeakBoundedVec};
|
||||||
use frame_benchmarking::{benchmarks, BenchmarkError, BenchmarkResult};
|
use frame_benchmarking::{benchmarks, whitelisted_caller, BenchmarkError, BenchmarkResult};
|
||||||
use frame_support::weights::Weight;
|
use frame_support::{traits::Currency, weights::Weight};
|
||||||
use frame_system::RawOrigin;
|
use frame_system::RawOrigin;
|
||||||
use sp_std::prelude::*;
|
use sp_std::prelude::*;
|
||||||
use xcm::{latest::prelude::*, v2};
|
use xcm::{latest::prelude::*, v2};
|
||||||
|
|
||||||
type RuntimeOrigin<T> = <T as frame_system::Config>::RuntimeOrigin;
|
type RuntimeOrigin<T> = <T as frame_system::Config>::RuntimeOrigin;
|
||||||
|
|
||||||
|
// existential deposit multiplier
|
||||||
|
const ED_MULTIPLIER: u32 = 100;
|
||||||
|
|
||||||
|
/// Pallet we're benchmarking here.
|
||||||
|
pub struct Pallet<T: Config>(crate::Pallet<T>);
|
||||||
|
|
||||||
|
/// Trait that must be implemented by runtime to be able to benchmark pallet properly.
|
||||||
|
pub trait Config: crate::Config {
|
||||||
|
/// A `MultiLocation` that can be reached via `XcmRouter`. Used only in benchmarks.
|
||||||
|
///
|
||||||
|
/// If `None`, the benchmarks that depend on a reachable destination will be skipped.
|
||||||
|
fn reachable_dest() -> Option<MultiLocation> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A `(MultiAsset, MultiLocation)` pair representing asset and the destination it can be
|
||||||
|
/// teleported to. Used only in benchmarks.
|
||||||
|
///
|
||||||
|
/// Implementation should also make sure `dest` is reachable/connected.
|
||||||
|
///
|
||||||
|
/// If `None`, the benchmarks that depend on this will be skipped.
|
||||||
|
fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A `(MultiAsset, MultiLocation)` pair representing asset and the destination it can be
|
||||||
|
/// reserve-transferred to. Used only in benchmarks.
|
||||||
|
///
|
||||||
|
/// Implementation should also make sure `dest` is reachable/connected.
|
||||||
|
///
|
||||||
|
/// If `None`, the benchmarks that depend on this will be skipped.
|
||||||
|
fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
benchmarks! {
|
benchmarks! {
|
||||||
|
where_clause {
|
||||||
|
where
|
||||||
|
T: pallet_balances::Config,
|
||||||
|
<T as pallet_balances::Config>::Balance: From<u128> + Into<u128>,
|
||||||
|
}
|
||||||
send {
|
send {
|
||||||
let send_origin =
|
let send_origin =
|
||||||
T::SendXcmOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
|
T::SendXcmOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
|
||||||
@@ -32,7 +73,7 @@ benchmarks! {
|
|||||||
return Err(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))
|
return Err(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))
|
||||||
}
|
}
|
||||||
let msg = Xcm(vec![ClearOrigin]);
|
let msg = Xcm(vec![ClearOrigin]);
|
||||||
let versioned_dest: VersionedMultiLocation = T::ReachableDest::get().ok_or(
|
let versioned_dest: VersionedMultiLocation = T::reachable_dest().ok_or(
|
||||||
BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)),
|
BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)),
|
||||||
)?
|
)?
|
||||||
.into();
|
.into();
|
||||||
@@ -40,44 +81,82 @@ benchmarks! {
|
|||||||
}: _<RuntimeOrigin<T>>(send_origin, Box::new(versioned_dest), Box::new(versioned_msg))
|
}: _<RuntimeOrigin<T>>(send_origin, Box::new(versioned_dest), Box::new(versioned_msg))
|
||||||
|
|
||||||
teleport_assets {
|
teleport_assets {
|
||||||
let asset: MultiAsset = (Here, 10).into();
|
let (asset, destination) = T::teleportable_asset_and_dest().ok_or(
|
||||||
let send_origin =
|
BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)),
|
||||||
T::ExecuteXcmOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
|
)?;
|
||||||
let origin_location = T::ExecuteXcmOrigin::try_origin(send_origin.clone())
|
|
||||||
|
let transferred_amount = match &asset.fun {
|
||||||
|
Fungible(amount) => *amount,
|
||||||
|
_ => return Err(BenchmarkError::Stop("Benchmark asset not fungible")),
|
||||||
|
}.into();
|
||||||
|
let assets: MultiAssets = asset.into();
|
||||||
|
|
||||||
|
let existential_deposit = T::ExistentialDeposit::get();
|
||||||
|
let caller = whitelisted_caller();
|
||||||
|
|
||||||
|
// Give some multiple of the existential deposit
|
||||||
|
let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into());
|
||||||
|
assert!(balance >= transferred_amount);
|
||||||
|
let _ = <pallet_balances::Pallet<T> as Currency<_>>::make_free_balance_be(&caller, balance);
|
||||||
|
// verify initial balance
|
||||||
|
assert_eq!(pallet_balances::Pallet::<T>::free_balance(&caller), balance);
|
||||||
|
|
||||||
|
let send_origin = RawOrigin::Signed(caller.clone());
|
||||||
|
let origin_location = T::ExecuteXcmOrigin::try_origin(send_origin.clone().into())
|
||||||
.map_err(|_| BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?;
|
.map_err(|_| BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?;
|
||||||
if !T::XcmTeleportFilter::contains(&(origin_location, vec![asset.clone()])) {
|
if !T::XcmTeleportFilter::contains(&(origin_location, assets.clone().into_inner())) {
|
||||||
return Err(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))
|
return Err(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))
|
||||||
}
|
}
|
||||||
|
|
||||||
let recipient = [0u8; 32];
|
let recipient = [0u8; 32];
|
||||||
let versioned_dest: VersionedMultiLocation = T::ReachableDest::get().ok_or(
|
let versioned_dest: VersionedMultiLocation = destination.into();
|
||||||
BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)),
|
|
||||||
)?
|
|
||||||
.into();
|
|
||||||
let versioned_beneficiary: VersionedMultiLocation =
|
let versioned_beneficiary: VersionedMultiLocation =
|
||||||
AccountId32 { network: None, id: recipient.into() }.into();
|
AccountId32 { network: None, id: recipient.into() }.into();
|
||||||
let versioned_assets: VersionedMultiAssets = asset.into();
|
let versioned_assets: VersionedMultiAssets = assets.into();
|
||||||
}: _<RuntimeOrigin<T>>(send_origin, Box::new(versioned_dest), Box::new(versioned_beneficiary), Box::new(versioned_assets), 0)
|
}: _<RuntimeOrigin<T>>(send_origin.into(), Box::new(versioned_dest), Box::new(versioned_beneficiary), Box::new(versioned_assets), 0)
|
||||||
|
verify {
|
||||||
|
// verify balance after transfer, decreased by transferred amount (+ maybe XCM delivery fees)
|
||||||
|
assert!(pallet_balances::Pallet::<T>::free_balance(&caller) <= balance - transferred_amount);
|
||||||
|
}
|
||||||
|
|
||||||
reserve_transfer_assets {
|
reserve_transfer_assets {
|
||||||
let asset: MultiAsset = (Here, 10).into();
|
let (asset, destination) = T::reserve_transferable_asset_and_dest().ok_or(
|
||||||
let send_origin =
|
BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)),
|
||||||
T::ExecuteXcmOrigin::try_successful_origin().map_err(|_| BenchmarkError::Weightless)?;
|
)?;
|
||||||
let origin_location = T::ExecuteXcmOrigin::try_origin(send_origin.clone())
|
|
||||||
|
let transferred_amount = match &asset.fun {
|
||||||
|
Fungible(amount) => *amount,
|
||||||
|
_ => return Err(BenchmarkError::Stop("Benchmark asset not fungible")),
|
||||||
|
}.into();
|
||||||
|
let assets: MultiAssets = asset.into();
|
||||||
|
|
||||||
|
let existential_deposit = T::ExistentialDeposit::get();
|
||||||
|
let caller = whitelisted_caller();
|
||||||
|
|
||||||
|
// Give some multiple of the existential deposit
|
||||||
|
let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into());
|
||||||
|
assert!(balance >= transferred_amount);
|
||||||
|
let _ = <pallet_balances::Pallet<T> as Currency<_>>::make_free_balance_be(&caller, balance);
|
||||||
|
// verify initial balance
|
||||||
|
assert_eq!(pallet_balances::Pallet::<T>::free_balance(&caller), balance);
|
||||||
|
|
||||||
|
let send_origin = RawOrigin::Signed(caller.clone());
|
||||||
|
let origin_location = T::ExecuteXcmOrigin::try_origin(send_origin.clone().into())
|
||||||
.map_err(|_| BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?;
|
.map_err(|_| BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))?;
|
||||||
if !T::XcmReserveTransferFilter::contains(&(origin_location, vec![asset.clone()])) {
|
if !T::XcmReserveTransferFilter::contains(&(origin_location, assets.clone().into_inner())) {
|
||||||
return Err(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))
|
return Err(BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)))
|
||||||
}
|
}
|
||||||
|
|
||||||
let recipient = [0u8; 32];
|
let recipient = [0u8; 32];
|
||||||
let versioned_dest: VersionedMultiLocation = T::ReachableDest::get().ok_or(
|
let versioned_dest: VersionedMultiLocation = destination.into();
|
||||||
BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)),
|
|
||||||
)?
|
|
||||||
.into();
|
|
||||||
let versioned_beneficiary: VersionedMultiLocation =
|
let versioned_beneficiary: VersionedMultiLocation =
|
||||||
AccountId32 { network: None, id: recipient.into() }.into();
|
AccountId32 { network: None, id: recipient.into() }.into();
|
||||||
let versioned_assets: VersionedMultiAssets = asset.into();
|
let versioned_assets: VersionedMultiAssets = assets.into();
|
||||||
}: _<RuntimeOrigin<T>>(send_origin, Box::new(versioned_dest), Box::new(versioned_beneficiary), Box::new(versioned_assets), 0)
|
}: _<RuntimeOrigin<T>>(send_origin.into(), Box::new(versioned_dest), Box::new(versioned_beneficiary), Box::new(versioned_assets), 0)
|
||||||
|
verify {
|
||||||
|
// verify balance after transfer, decreased by transferred amount (+ maybe XCM delivery fees)
|
||||||
|
assert!(pallet_balances::Pallet::<T>::free_balance(&caller) <= balance - transferred_amount);
|
||||||
|
}
|
||||||
|
|
||||||
execute {
|
execute {
|
||||||
let execute_origin =
|
let execute_origin =
|
||||||
@@ -92,7 +171,7 @@ benchmarks! {
|
|||||||
}: _<RuntimeOrigin<T>>(execute_origin, Box::new(versioned_msg), Weight::zero())
|
}: _<RuntimeOrigin<T>>(execute_origin, Box::new(versioned_msg), Weight::zero())
|
||||||
|
|
||||||
force_xcm_version {
|
force_xcm_version {
|
||||||
let loc = T::ReachableDest::get().ok_or(
|
let loc = T::reachable_dest().ok_or(
|
||||||
BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)),
|
BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)),
|
||||||
)?;
|
)?;
|
||||||
let xcm_version = 2;
|
let xcm_version = 2;
|
||||||
@@ -101,18 +180,18 @@ benchmarks! {
|
|||||||
force_default_xcm_version {}: _(RawOrigin::Root, Some(2))
|
force_default_xcm_version {}: _(RawOrigin::Root, Some(2))
|
||||||
|
|
||||||
force_subscribe_version_notify {
|
force_subscribe_version_notify {
|
||||||
let versioned_loc: VersionedMultiLocation = T::ReachableDest::get().ok_or(
|
let versioned_loc: VersionedMultiLocation = T::reachable_dest().ok_or(
|
||||||
BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)),
|
BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)),
|
||||||
)?
|
)?
|
||||||
.into();
|
.into();
|
||||||
}: _(RawOrigin::Root, Box::new(versioned_loc))
|
}: _(RawOrigin::Root, Box::new(versioned_loc))
|
||||||
|
|
||||||
force_unsubscribe_version_notify {
|
force_unsubscribe_version_notify {
|
||||||
let loc = T::ReachableDest::get().ok_or(
|
let loc = T::reachable_dest().ok_or(
|
||||||
BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)),
|
BenchmarkError::Override(BenchmarkResult::from_weight(Weight::MAX)),
|
||||||
)?;
|
)?;
|
||||||
let versioned_loc: VersionedMultiLocation = loc.into();
|
let versioned_loc: VersionedMultiLocation = loc.into();
|
||||||
let _ = Pallet::<T>::request_version_notify(loc);
|
let _ = crate::Pallet::<T>::request_version_notify(loc);
|
||||||
}: _(RawOrigin::Root, Box::new(versioned_loc))
|
}: _(RawOrigin::Root, Box::new(versioned_loc))
|
||||||
|
|
||||||
force_suspension {}: _(RawOrigin::Root, true)
|
force_suspension {}: _(RawOrigin::Root, true)
|
||||||
@@ -122,7 +201,7 @@ benchmarks! {
|
|||||||
let loc = VersionedMultiLocation::from(MultiLocation::from(Parent));
|
let loc = VersionedMultiLocation::from(MultiLocation::from(Parent));
|
||||||
SupportedVersion::<T>::insert(old_version, loc, old_version);
|
SupportedVersion::<T>::insert(old_version, loc, old_version);
|
||||||
}: {
|
}: {
|
||||||
Pallet::<T>::check_xcm_version_change(VersionMigrationStage::MigrateSupportedVersion, Weight::zero());
|
crate::Pallet::<T>::check_xcm_version_change(VersionMigrationStage::MigrateSupportedVersion, Weight::zero());
|
||||||
}
|
}
|
||||||
|
|
||||||
migrate_version_notifiers {
|
migrate_version_notifiers {
|
||||||
@@ -130,22 +209,22 @@ benchmarks! {
|
|||||||
let loc = VersionedMultiLocation::from(MultiLocation::from(Parent));
|
let loc = VersionedMultiLocation::from(MultiLocation::from(Parent));
|
||||||
VersionNotifiers::<T>::insert(old_version, loc, 0);
|
VersionNotifiers::<T>::insert(old_version, loc, 0);
|
||||||
}: {
|
}: {
|
||||||
Pallet::<T>::check_xcm_version_change(VersionMigrationStage::MigrateVersionNotifiers, Weight::zero());
|
crate::Pallet::<T>::check_xcm_version_change(VersionMigrationStage::MigrateVersionNotifiers, Weight::zero());
|
||||||
}
|
}
|
||||||
|
|
||||||
already_notified_target {
|
already_notified_target {
|
||||||
let loc = T::ReachableDest::get().ok_or(
|
let loc = T::reachable_dest().ok_or(
|
||||||
BenchmarkError::Override(BenchmarkResult::from_weight(T::DbWeight::get().reads(1))),
|
BenchmarkError::Override(BenchmarkResult::from_weight(T::DbWeight::get().reads(1))),
|
||||||
)?;
|
)?;
|
||||||
let loc = VersionedMultiLocation::from(loc);
|
let loc = VersionedMultiLocation::from(loc);
|
||||||
let current_version = T::AdvertisedXcmVersion::get();
|
let current_version = T::AdvertisedXcmVersion::get();
|
||||||
VersionNotifyTargets::<T>::insert(current_version, loc, (0, Weight::zero(), current_version));
|
VersionNotifyTargets::<T>::insert(current_version, loc, (0, Weight::zero(), current_version));
|
||||||
}: {
|
}: {
|
||||||
Pallet::<T>::check_xcm_version_change(VersionMigrationStage::NotifyCurrentTargets(None), Weight::zero());
|
crate::Pallet::<T>::check_xcm_version_change(VersionMigrationStage::NotifyCurrentTargets(None), Weight::zero());
|
||||||
}
|
}
|
||||||
|
|
||||||
notify_current_targets {
|
notify_current_targets {
|
||||||
let loc = T::ReachableDest::get().ok_or(
|
let loc = T::reachable_dest().ok_or(
|
||||||
BenchmarkError::Override(BenchmarkResult::from_weight(T::DbWeight::get().reads_writes(1, 3))),
|
BenchmarkError::Override(BenchmarkResult::from_weight(T::DbWeight::get().reads_writes(1, 3))),
|
||||||
)?;
|
)?;
|
||||||
let loc = VersionedMultiLocation::from(loc);
|
let loc = VersionedMultiLocation::from(loc);
|
||||||
@@ -153,7 +232,7 @@ benchmarks! {
|
|||||||
let old_version = current_version - 1;
|
let old_version = current_version - 1;
|
||||||
VersionNotifyTargets::<T>::insert(current_version, loc, (0, Weight::zero(), old_version));
|
VersionNotifyTargets::<T>::insert(current_version, loc, (0, Weight::zero(), old_version));
|
||||||
}: {
|
}: {
|
||||||
Pallet::<T>::check_xcm_version_change(VersionMigrationStage::NotifyCurrentTargets(None), Weight::zero());
|
crate::Pallet::<T>::check_xcm_version_change(VersionMigrationStage::NotifyCurrentTargets(None), Weight::zero());
|
||||||
}
|
}
|
||||||
|
|
||||||
notify_target_migration_fail {
|
notify_target_migration_fail {
|
||||||
@@ -167,7 +246,7 @@ benchmarks! {
|
|||||||
let current_version = T::AdvertisedXcmVersion::get();
|
let current_version = T::AdvertisedXcmVersion::get();
|
||||||
VersionNotifyTargets::<T>::insert(current_version, bad_loc, (0, Weight::zero(), current_version));
|
VersionNotifyTargets::<T>::insert(current_version, bad_loc, (0, Weight::zero(), current_version));
|
||||||
}: {
|
}: {
|
||||||
Pallet::<T>::check_xcm_version_change(VersionMigrationStage::MigrateAndNotifyOldTargets, Weight::zero());
|
crate::Pallet::<T>::check_xcm_version_change(VersionMigrationStage::MigrateAndNotifyOldTargets, Weight::zero());
|
||||||
}
|
}
|
||||||
|
|
||||||
migrate_version_notify_targets {
|
migrate_version_notify_targets {
|
||||||
@@ -176,18 +255,18 @@ benchmarks! {
|
|||||||
let loc = VersionedMultiLocation::from(MultiLocation::from(Parent));
|
let loc = VersionedMultiLocation::from(MultiLocation::from(Parent));
|
||||||
VersionNotifyTargets::<T>::insert(old_version, loc, (0, Weight::zero(), current_version));
|
VersionNotifyTargets::<T>::insert(old_version, loc, (0, Weight::zero(), current_version));
|
||||||
}: {
|
}: {
|
||||||
Pallet::<T>::check_xcm_version_change(VersionMigrationStage::MigrateAndNotifyOldTargets, Weight::zero());
|
crate::Pallet::<T>::check_xcm_version_change(VersionMigrationStage::MigrateAndNotifyOldTargets, Weight::zero());
|
||||||
}
|
}
|
||||||
|
|
||||||
migrate_and_notify_old_targets {
|
migrate_and_notify_old_targets {
|
||||||
let loc = T::ReachableDest::get().ok_or(
|
let loc = T::reachable_dest().ok_or(
|
||||||
BenchmarkError::Override(BenchmarkResult::from_weight(T::DbWeight::get().reads_writes(1, 3))),
|
BenchmarkError::Override(BenchmarkResult::from_weight(T::DbWeight::get().reads_writes(1, 3))),
|
||||||
)?;
|
)?;
|
||||||
let loc = VersionedMultiLocation::from(loc);
|
let loc = VersionedMultiLocation::from(loc);
|
||||||
let old_version = T::AdvertisedXcmVersion::get() - 1;
|
let old_version = T::AdvertisedXcmVersion::get() - 1;
|
||||||
VersionNotifyTargets::<T>::insert(old_version, loc, (0, Weight::zero(), old_version));
|
VersionNotifyTargets::<T>::insert(old_version, loc, (0, Weight::zero(), old_version));
|
||||||
}: {
|
}: {
|
||||||
Pallet::<T>::check_xcm_version_change(VersionMigrationStage::MigrateAndNotifyOldTargets, Weight::zero());
|
crate::Pallet::<T>::check_xcm_version_change(VersionMigrationStage::MigrateAndNotifyOldTargets, Weight::zero());
|
||||||
}
|
}
|
||||||
|
|
||||||
new_query {
|
new_query {
|
||||||
@@ -195,14 +274,14 @@ benchmarks! {
|
|||||||
let timeout = 1u32.into();
|
let timeout = 1u32.into();
|
||||||
let match_querier = MultiLocation::from(Here);
|
let match_querier = MultiLocation::from(Here);
|
||||||
}: {
|
}: {
|
||||||
Pallet::<T>::new_query(responder, timeout, match_querier);
|
crate::Pallet::<T>::new_query(responder, timeout, match_querier);
|
||||||
}
|
}
|
||||||
|
|
||||||
take_response {
|
take_response {
|
||||||
let responder = MultiLocation::from(Parent);
|
let responder = MultiLocation::from(Parent);
|
||||||
let timeout = 1u32.into();
|
let timeout = 1u32.into();
|
||||||
let match_querier = MultiLocation::from(Here);
|
let match_querier = MultiLocation::from(Here);
|
||||||
let query_id = Pallet::<T>::new_query(responder, timeout, match_querier);
|
let query_id = crate::Pallet::<T>::new_query(responder, timeout, match_querier);
|
||||||
let infos = (0 .. xcm::v3::MaxPalletsInfo::get()).map(|_| PalletInfo::new(
|
let infos = (0 .. xcm::v3::MaxPalletsInfo::get()).map(|_| PalletInfo::new(
|
||||||
u32::MAX,
|
u32::MAX,
|
||||||
(0..xcm::v3::MaxPalletNameLen::get()).map(|_| 97u8).collect::<Vec<_>>().try_into().unwrap(),
|
(0..xcm::v3::MaxPalletNameLen::get()).map(|_| 97u8).collect::<Vec<_>>().try_into().unwrap(),
|
||||||
@@ -211,10 +290,10 @@ benchmarks! {
|
|||||||
u32::MAX,
|
u32::MAX,
|
||||||
u32::MAX,
|
u32::MAX,
|
||||||
).unwrap()).collect::<Vec<_>>();
|
).unwrap()).collect::<Vec<_>>();
|
||||||
Pallet::<T>::expect_response(query_id, Response::PalletsInfo(infos.try_into().unwrap()));
|
crate::Pallet::<T>::expect_response(query_id, Response::PalletsInfo(infos.try_into().unwrap()));
|
||||||
|
|
||||||
}: {
|
}: {
|
||||||
<Pallet::<T> as QueryHandler>::take_response(query_id);
|
<crate::Pallet::<T> as QueryHandler>::take_response(query_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_benchmark_test_suite!(
|
impl_benchmark_test_suite!(
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
#[cfg(feature = "runtime-benchmarks")]
|
||||||
mod benchmarking;
|
pub mod benchmarking;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod mock;
|
mod mock;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -55,9 +55,9 @@ use xcm_builder::{
|
|||||||
};
|
};
|
||||||
use xcm_executor::{
|
use xcm_executor::{
|
||||||
traits::{
|
traits::{
|
||||||
CheckSuspension, ClaimAssets, ConvertLocation, ConvertOrigin, DropAssets, MatchesFungible,
|
AssetTransferError, CheckSuspension, ClaimAssets, ConvertLocation, ConvertOrigin,
|
||||||
OnResponse, Properties, QueryHandler, QueryResponseStatus, VersionChangeNotifier,
|
DropAssets, MatchesFungible, OnResponse, Properties, QueryHandler, QueryResponseStatus,
|
||||||
WeightBounds,
|
TransactAsset, TransferType, VersionChangeNotifier, WeightBounds, XcmAssetTransfers,
|
||||||
},
|
},
|
||||||
Assets,
|
Assets,
|
||||||
};
|
};
|
||||||
@@ -222,7 +222,7 @@ pub mod pallet {
|
|||||||
type XcmExecuteFilter: Contains<(MultiLocation, Xcm<<Self as Config>::RuntimeCall>)>;
|
type XcmExecuteFilter: Contains<(MultiLocation, Xcm<<Self as Config>::RuntimeCall>)>;
|
||||||
|
|
||||||
/// Something to execute an XCM message.
|
/// Something to execute an XCM message.
|
||||||
type XcmExecutor: ExecuteXcm<<Self as Config>::RuntimeCall>;
|
type XcmExecutor: ExecuteXcm<<Self as Config>::RuntimeCall> + XcmAssetTransfers;
|
||||||
|
|
||||||
/// Our XCM filter which messages to be teleported using the dedicated extrinsic must pass.
|
/// Our XCM filter which messages to be teleported using the dedicated extrinsic must pass.
|
||||||
type XcmTeleportFilter: Contains<(MultiLocation, Vec<MultiAsset>)>;
|
type XcmTeleportFilter: Contains<(MultiLocation, Vec<MultiAsset>)>;
|
||||||
@@ -275,12 +275,6 @@ pub mod pallet {
|
|||||||
|
|
||||||
/// Weight information for extrinsics in this pallet.
|
/// Weight information for extrinsics in this pallet.
|
||||||
type WeightInfo: WeightInfo;
|
type WeightInfo: WeightInfo;
|
||||||
|
|
||||||
/// A `MultiLocation` that can be reached via `XcmRouter`. Used only in benchmarks.
|
|
||||||
///
|
|
||||||
/// If `None`, the benchmarks that depend on a reachable destination will be skipped.
|
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
type ReachableDest: Get<Option<MultiLocation>>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Config> ExecuteControllerWeightInfo for Pallet<T> {
|
impl<T: Config> ExecuteControllerWeightInfo for Pallet<T> {
|
||||||
@@ -531,8 +525,8 @@ pub mod pallet {
|
|||||||
NoSubscription,
|
NoSubscription,
|
||||||
/// The location is invalid since it already has a subscription from us.
|
/// The location is invalid since it already has a subscription from us.
|
||||||
AlreadySubscribed,
|
AlreadySubscribed,
|
||||||
/// Invalid asset for the operation.
|
/// Could not check-out the assets for teleportation to the destination chain.
|
||||||
InvalidAsset,
|
CannotCheckOutTeleport,
|
||||||
/// The owner does not own (all) of the asset that they wish to do the operation on.
|
/// The owner does not own (all) of the asset that they wish to do the operation on.
|
||||||
LowBalance,
|
LowBalance,
|
||||||
/// The asset owner has too many locks on the asset.
|
/// The asset owner has too many locks on the asset.
|
||||||
@@ -545,6 +539,16 @@ pub mod pallet {
|
|||||||
LockNotFound,
|
LockNotFound,
|
||||||
/// The unlock operation cannot succeed because there are still consumers of the lock.
|
/// The unlock operation cannot succeed because there are still consumers of the lock.
|
||||||
InUse,
|
InUse,
|
||||||
|
/// Invalid non-concrete asset.
|
||||||
|
InvalidAssetNotConcrete,
|
||||||
|
/// Invalid asset, reserve chain could not be determined for it.
|
||||||
|
InvalidAssetUnknownReserve,
|
||||||
|
/// Invalid asset, do not support remote asset reserves with different fees reserves.
|
||||||
|
InvalidAssetUnsupportedReserve,
|
||||||
|
/// Too many assets with different reserve locations have been attempted for transfer.
|
||||||
|
TooManyReserves,
|
||||||
|
/// Local XCM execution of asset transfer incomplete.
|
||||||
|
LocalExecutionIncomplete,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Config> From<SendError> for Error<T> {
|
impl<T: Config> From<SendError> for Error<T> {
|
||||||
@@ -557,6 +561,15 @@ pub mod pallet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: Config> From<AssetTransferError> for Error<T> {
|
||||||
|
fn from(e: AssetTransferError) -> Self {
|
||||||
|
match e {
|
||||||
|
AssetTransferError::NotConcrete => Error::<T>::InvalidAssetNotConcrete,
|
||||||
|
AssetTransferError::UnknownReserve => Error::<T>::InvalidAssetUnknownReserve,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The status of a query.
|
/// The status of a query.
|
||||||
#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)]
|
#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug, TypeInfo)]
|
||||||
pub enum QueryStatus<BlockNumber> {
|
pub enum QueryStatus<BlockNumber> {
|
||||||
@@ -907,11 +920,7 @@ pub mod pallet {
|
|||||||
let mut message = Xcm(vec![
|
let mut message = Xcm(vec![
|
||||||
WithdrawAsset(assets),
|
WithdrawAsset(assets),
|
||||||
SetFeesMode { jit_withdraw: true },
|
SetFeesMode { jit_withdraw: true },
|
||||||
InitiateTeleport {
|
InitiateTeleport { assets: Wild(AllCounted(count)), dest, xcm: Xcm(vec![]) },
|
||||||
assets: Wild(AllCounted(count)),
|
|
||||||
dest,
|
|
||||||
xcm: Xcm(vec![]),
|
|
||||||
},
|
|
||||||
]);
|
]);
|
||||||
T::Weigher::weight(&mut message).map_or(Weight::MAX, |w| T::WeightInfo::teleport_assets().saturating_add(w))
|
T::Weigher::weight(&mut message).map_or(Weight::MAX, |w| T::WeightInfo::teleport_assets().saturating_add(w))
|
||||||
}
|
}
|
||||||
@@ -954,6 +963,8 @@ pub mod pallet {
|
|||||||
match (maybe_assets, maybe_dest) {
|
match (maybe_assets, maybe_dest) {
|
||||||
(Ok(assets), Ok(dest)) => {
|
(Ok(assets), Ok(dest)) => {
|
||||||
use sp_std::vec;
|
use sp_std::vec;
|
||||||
|
// heaviest version of locally executed XCM program: equivalent in weight to
|
||||||
|
// transfer assets to SA, reanchor them, extend XCM program, and send onward XCM
|
||||||
let mut message = Xcm(vec![
|
let mut message = Xcm(vec![
|
||||||
SetFeesMode { jit_withdraw: true },
|
SetFeesMode { jit_withdraw: true },
|
||||||
TransferReserveAsset { assets, dest, xcm: Xcm(vec![]) }
|
TransferReserveAsset { assets, dest, xcm: Xcm(vec![]) }
|
||||||
@@ -1114,6 +1125,8 @@ pub mod pallet {
|
|||||||
match (maybe_assets, maybe_dest) {
|
match (maybe_assets, maybe_dest) {
|
||||||
(Ok(assets), Ok(dest)) => {
|
(Ok(assets), Ok(dest)) => {
|
||||||
use sp_std::vec;
|
use sp_std::vec;
|
||||||
|
// heaviest version of locally executed XCM program: equivalent in weight to
|
||||||
|
// transfer assets to SA, reanchor them, extend XCM program, and send onward XCM
|
||||||
let mut message = Xcm(vec![
|
let mut message = Xcm(vec![
|
||||||
SetFeesMode { jit_withdraw: true },
|
SetFeesMode { jit_withdraw: true },
|
||||||
TransferReserveAsset { assets, dest, xcm: Xcm(vec![]) }
|
TransferReserveAsset { assets, dest, xcm: Xcm(vec![]) }
|
||||||
@@ -1273,6 +1286,33 @@ impl<T: Config> QueryHandler for Pallet<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Config> Pallet<T> {
|
impl<T: Config> Pallet<T> {
|
||||||
|
/// Validate `assets` to be reserve-transferred and return their reserve location.
|
||||||
|
fn validate_assets_and_find_reserve(
|
||||||
|
assets: &[MultiAsset],
|
||||||
|
dest: &MultiLocation,
|
||||||
|
) -> Result<TransferType, Error<T>> {
|
||||||
|
let mut reserve = None;
|
||||||
|
for asset in assets.iter() {
|
||||||
|
if let Fungible(x) = asset.fun {
|
||||||
|
// If fungible asset, ensure non-zero amount.
|
||||||
|
ensure!(!x.is_zero(), Error::<T>::Empty);
|
||||||
|
}
|
||||||
|
let transfer_type =
|
||||||
|
T::XcmExecutor::determine_for(&asset, dest).map_err(Error::<T>::from)?;
|
||||||
|
// Ensure asset is not teleportable to `dest`.
|
||||||
|
ensure!(transfer_type != TransferType::Teleport, Error::<T>::Filtered);
|
||||||
|
if let Some(reserve) = reserve.as_ref() {
|
||||||
|
// Ensure transfer for multiple assets uses same reserve location (only fee may have
|
||||||
|
// different reserve location)
|
||||||
|
ensure!(reserve == &transfer_type, Error::<T>::TooManyReserves);
|
||||||
|
} else {
|
||||||
|
// asset reserve identified
|
||||||
|
reserve = Some(transfer_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reserve.ok_or(Error::<T>::Empty)
|
||||||
|
}
|
||||||
|
|
||||||
fn do_reserve_transfer_assets(
|
fn do_reserve_transfer_assets(
|
||||||
origin: OriginFor<T>,
|
origin: OriginFor<T>,
|
||||||
dest: Box<VersionedMultiLocation>,
|
dest: Box<VersionedMultiLocation>,
|
||||||
@@ -1286,35 +1326,75 @@ impl<T: Config> Pallet<T> {
|
|||||||
let beneficiary: MultiLocation =
|
let beneficiary: MultiLocation =
|
||||||
(*beneficiary).try_into().map_err(|()| Error::<T>::BadVersion)?;
|
(*beneficiary).try_into().map_err(|()| Error::<T>::BadVersion)?;
|
||||||
let assets: MultiAssets = (*assets).try_into().map_err(|()| Error::<T>::BadVersion)?;
|
let assets: MultiAssets = (*assets).try_into().map_err(|()| Error::<T>::BadVersion)?;
|
||||||
|
log::trace!(
|
||||||
|
target: "xcm::pallet_xcm::do_reserve_transfer_assets",
|
||||||
|
"origin {:?}, dest {:?}, beneficiary {:?}, assets {:?}, fee-idx {:?}",
|
||||||
|
origin_location, dest, beneficiary, assets, fee_asset_item,
|
||||||
|
);
|
||||||
|
|
||||||
ensure!(assets.len() <= MAX_ASSETS_FOR_TRANSFER, Error::<T>::TooManyAssets);
|
ensure!(assets.len() <= MAX_ASSETS_FOR_TRANSFER, Error::<T>::TooManyAssets);
|
||||||
let value = (origin_location, assets.into_inner());
|
let value = (origin_location, assets.into_inner());
|
||||||
ensure!(T::XcmReserveTransferFilter::contains(&value), Error::<T>::Filtered);
|
ensure!(T::XcmReserveTransferFilter::contains(&value), Error::<T>::Filtered);
|
||||||
let (origin_location, assets) = value;
|
let (origin_location, mut assets) = value;
|
||||||
let context = T::UniversalLocation::get();
|
|
||||||
let fees = assets
|
if fee_asset_item as usize >= assets.len() {
|
||||||
.get(fee_asset_item as usize)
|
return Err(Error::<T>::Empty.into())
|
||||||
.ok_or(Error::<T>::Empty)?
|
}
|
||||||
.clone()
|
let fees = assets.swap_remove(fee_asset_item as usize);
|
||||||
.reanchored(&dest, context)
|
let fees_transfer_type =
|
||||||
.map_err(|_| Error::<T>::CannotReanchor)?;
|
T::XcmExecutor::determine_for(&fees, &dest).map_err(Error::<T>::from)?;
|
||||||
let max_assets = assets.len() as u32;
|
let assets_transfer_type = if assets.is_empty() {
|
||||||
let assets: MultiAssets = assets.into();
|
// Single asset to transfer (one used for fees where transfer type is determined above).
|
||||||
let xcm = Xcm(vec![
|
ensure!(fees_transfer_type != TransferType::Teleport, Error::<T>::Filtered);
|
||||||
BuyExecution { fees, weight_limit },
|
fees_transfer_type
|
||||||
DepositAsset { assets: Wild(AllCounted(max_assets)), beneficiary },
|
} else {
|
||||||
]);
|
// Find reserve for non-fee assets.
|
||||||
let mut message = Xcm(vec![
|
Self::validate_assets_and_find_reserve(&assets, &dest)?
|
||||||
SetFeesMode { jit_withdraw: true },
|
};
|
||||||
TransferReserveAsset { assets, dest, xcm },
|
|
||||||
]);
|
// local and remote XCM programs to potentially handle fees separately
|
||||||
let weight =
|
let separate_fees_instructions: Option<(Xcm<<T as Config>::RuntimeCall>, Xcm<()>)>;
|
||||||
T::Weigher::weight(&mut message).map_err(|()| Error::<T>::UnweighableMessage)?;
|
if fees_transfer_type == assets_transfer_type {
|
||||||
let hash = message.using_encoded(sp_io::hashing::blake2_256);
|
// Same reserve location (fees not teleportable), we can batch together fees and assets
|
||||||
let outcome =
|
// in same reserve-based-transfer.
|
||||||
T::XcmExecutor::execute_xcm_in_credit(origin_location, message, hash, weight, weight);
|
assets.push(fees.clone());
|
||||||
Self::deposit_event(Event::Attempted { outcome });
|
// no need for custom fees instructions, fees are batched with assets
|
||||||
Ok(())
|
separate_fees_instructions = None;
|
||||||
|
} else {
|
||||||
|
// Disallow _remote reserves_ unless assets & fees have same remote reserve (covered by
|
||||||
|
// branch above). The reason for this is that we'd need to send XCMs to separate chains
|
||||||
|
// with no guarantee of delivery order on final destination; therefore we cannot
|
||||||
|
// guarantee to have fees in place on final destination chain to pay for assets
|
||||||
|
// transfer.
|
||||||
|
ensure!(
|
||||||
|
!matches!(assets_transfer_type, TransferType::RemoteReserve(_)),
|
||||||
|
Error::<T>::InvalidAssetUnsupportedReserve
|
||||||
|
);
|
||||||
|
let fees = fees.clone();
|
||||||
|
let weight_limit = weight_limit.clone();
|
||||||
|
// build fees transfer instructions to be added to assets transfers XCM programs
|
||||||
|
separate_fees_instructions = Some(match fees_transfer_type {
|
||||||
|
TransferType::LocalReserve =>
|
||||||
|
Self::local_reserve_fees_instructions(dest, fees, weight_limit)?,
|
||||||
|
TransferType::DestinationReserve =>
|
||||||
|
Self::destination_reserve_fees_instructions(dest, fees, weight_limit)?,
|
||||||
|
TransferType::Teleport =>
|
||||||
|
Self::teleport_fees_instructions(dest, fees, weight_limit)?,
|
||||||
|
TransferType::RemoteReserve(_) =>
|
||||||
|
return Err(Error::<T>::InvalidAssetUnsupportedReserve.into()),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Self::build_and_execute_xcm_transfer_type(
|
||||||
|
origin_location,
|
||||||
|
dest,
|
||||||
|
beneficiary,
|
||||||
|
assets,
|
||||||
|
assets_transfer_type,
|
||||||
|
fees,
|
||||||
|
separate_fees_instructions,
|
||||||
|
weight_limit,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_teleport_assets(
|
fn do_teleport_assets(
|
||||||
@@ -1335,31 +1415,384 @@ impl<T: Config> Pallet<T> {
|
|||||||
let value = (origin_location, assets.into_inner());
|
let value = (origin_location, assets.into_inner());
|
||||||
ensure!(T::XcmTeleportFilter::contains(&value), Error::<T>::Filtered);
|
ensure!(T::XcmTeleportFilter::contains(&value), Error::<T>::Filtered);
|
||||||
let (origin_location, assets) = value;
|
let (origin_location, assets) = value;
|
||||||
|
for asset in assets.iter() {
|
||||||
|
let transfer_type =
|
||||||
|
T::XcmExecutor::determine_for(asset, &dest).map_err(Error::<T>::from)?;
|
||||||
|
ensure!(matches!(transfer_type, TransferType::Teleport), Error::<T>::Filtered);
|
||||||
|
}
|
||||||
|
let fees = assets.get(fee_asset_item as usize).ok_or(Error::<T>::Empty)?.clone();
|
||||||
|
|
||||||
|
Self::build_and_execute_xcm_transfer_type(
|
||||||
|
origin_location,
|
||||||
|
dest,
|
||||||
|
beneficiary,
|
||||||
|
assets,
|
||||||
|
TransferType::Teleport,
|
||||||
|
fees,
|
||||||
|
None,
|
||||||
|
weight_limit,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_and_execute_xcm_transfer_type(
|
||||||
|
origin: MultiLocation,
|
||||||
|
dest: MultiLocation,
|
||||||
|
beneficiary: MultiLocation,
|
||||||
|
assets: Vec<MultiAsset>,
|
||||||
|
transfer_type: TransferType,
|
||||||
|
fees: MultiAsset,
|
||||||
|
separate_fees_instructions: Option<(Xcm<<T as Config>::RuntimeCall>, Xcm<()>)>,
|
||||||
|
weight_limit: WeightLimit,
|
||||||
|
) -> DispatchResult {
|
||||||
|
log::trace!(
|
||||||
|
target: "xcm::pallet_xcm::build_and_execute_xcm_transfer_type",
|
||||||
|
"origin {:?}, dest {:?}, beneficiary {:?}, assets {:?}, transfer_type {:?}, \
|
||||||
|
fees {:?}, fees_xcm: {:?}, weight_limit: {:?}",
|
||||||
|
origin, dest, beneficiary, assets, transfer_type, fees, separate_fees_instructions, weight_limit,
|
||||||
|
);
|
||||||
|
let (mut local_xcm, remote_xcm) = match transfer_type {
|
||||||
|
TransferType::LocalReserve => {
|
||||||
|
let (local, remote) = Self::local_reserve_transfer_programs(
|
||||||
|
dest,
|
||||||
|
beneficiary,
|
||||||
|
assets,
|
||||||
|
fees,
|
||||||
|
separate_fees_instructions,
|
||||||
|
weight_limit,
|
||||||
|
)?;
|
||||||
|
(local, Some(remote))
|
||||||
|
},
|
||||||
|
TransferType::DestinationReserve => {
|
||||||
|
let (local, remote) = Self::destination_reserve_transfer_programs(
|
||||||
|
dest,
|
||||||
|
beneficiary,
|
||||||
|
assets,
|
||||||
|
fees,
|
||||||
|
separate_fees_instructions,
|
||||||
|
weight_limit,
|
||||||
|
)?;
|
||||||
|
(local, Some(remote))
|
||||||
|
},
|
||||||
|
TransferType::RemoteReserve(reserve) => (
|
||||||
|
Self::remote_reserve_transfer_program(
|
||||||
|
reserve,
|
||||||
|
dest,
|
||||||
|
beneficiary,
|
||||||
|
assets,
|
||||||
|
fees,
|
||||||
|
weight_limit,
|
||||||
|
)?,
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
TransferType::Teleport => (
|
||||||
|
Self::teleport_assets_program(dest, beneficiary, assets, fees, weight_limit)?,
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
};
|
||||||
|
let weight =
|
||||||
|
T::Weigher::weight(&mut local_xcm).map_err(|()| Error::<T>::UnweighableMessage)?;
|
||||||
|
let hash = local_xcm.using_encoded(sp_io::hashing::blake2_256);
|
||||||
|
let outcome =
|
||||||
|
T::XcmExecutor::execute_xcm_in_credit(origin, local_xcm, hash, weight, weight);
|
||||||
|
Self::deposit_event(Event::Attempted { outcome: outcome.clone() });
|
||||||
|
if let Some(remote_xcm) = remote_xcm {
|
||||||
|
outcome.ensure_complete().map_err(|_| Error::<T>::LocalExecutionIncomplete)?;
|
||||||
|
|
||||||
|
let (ticket, price) = validate_send::<T::XcmRouter>(dest, remote_xcm.clone())
|
||||||
|
.map_err(Error::<T>::from)?;
|
||||||
|
if origin != Here.into_location() {
|
||||||
|
Self::charge_fees(origin, price).map_err(|_| Error::<T>::FeesNotMet)?;
|
||||||
|
}
|
||||||
|
let message_id = T::XcmRouter::deliver(ticket).map_err(Error::<T>::from)?;
|
||||||
|
|
||||||
|
let e = Event::Sent { origin, destination: dest, message: remote_xcm, message_id };
|
||||||
|
Self::deposit_event(e);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn local_reserve_fees_instructions(
|
||||||
|
dest: MultiLocation,
|
||||||
|
fees: MultiAsset,
|
||||||
|
weight_limit: WeightLimit,
|
||||||
|
) -> Result<(Xcm<<T as Config>::RuntimeCall>, Xcm<()>), Error<T>> {
|
||||||
let context = T::UniversalLocation::get();
|
let context = T::UniversalLocation::get();
|
||||||
let fees = assets
|
let reanchored_fees = fees
|
||||||
.get(fee_asset_item as usize)
|
|
||||||
.ok_or(Error::<T>::Empty)?
|
|
||||||
.clone()
|
.clone()
|
||||||
.reanchored(&dest, context)
|
.reanchored(&dest, context)
|
||||||
.map_err(|_| Error::<T>::CannotReanchor)?;
|
.map_err(|_| Error::<T>::CannotReanchor)?;
|
||||||
let max_assets = assets.len() as u32;
|
|
||||||
|
let local_execute_xcm = Xcm(vec![
|
||||||
|
// move `fees` to `dest`s local sovereign account
|
||||||
|
TransferAsset { assets: fees.into(), beneficiary: dest },
|
||||||
|
]);
|
||||||
|
let xcm_on_dest = Xcm(vec![
|
||||||
|
// let (dest) chain know `fees` are in its SA on reserve
|
||||||
|
ReserveAssetDeposited(reanchored_fees.clone().into()),
|
||||||
|
// buy exec using `fees` in holding deposited in above instruction
|
||||||
|
BuyExecution { fees: reanchored_fees, weight_limit },
|
||||||
|
]);
|
||||||
|
Ok((local_execute_xcm, xcm_on_dest))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn local_reserve_transfer_programs(
|
||||||
|
dest: MultiLocation,
|
||||||
|
beneficiary: MultiLocation,
|
||||||
|
assets: Vec<MultiAsset>,
|
||||||
|
fees: MultiAsset,
|
||||||
|
separate_fees_instructions: Option<(Xcm<<T as Config>::RuntimeCall>, Xcm<()>)>,
|
||||||
|
weight_limit: WeightLimit,
|
||||||
|
) -> Result<(Xcm<<T as Config>::RuntimeCall>, Xcm<()>), Error<T>> {
|
||||||
|
// max assets is `assets` (+ potentially separately handled fee)
|
||||||
|
let max_assets =
|
||||||
|
assets.len() as u32 + separate_fees_instructions.as_ref().map(|_| 1).unwrap_or(0);
|
||||||
let assets: MultiAssets = assets.into();
|
let assets: MultiAssets = assets.into();
|
||||||
let xcm = Xcm(vec![
|
let context = T::UniversalLocation::get();
|
||||||
|
let mut reanchored_assets = assets.clone();
|
||||||
|
reanchored_assets
|
||||||
|
.reanchor(&dest, context)
|
||||||
|
.map_err(|_| Error::<T>::CannotReanchor)?;
|
||||||
|
|
||||||
|
// fees are either handled through dedicated instructions, or batched together with assets
|
||||||
|
let fees_already_handled = separate_fees_instructions.is_some();
|
||||||
|
let (fees_local_xcm, fees_remote_xcm) = separate_fees_instructions
|
||||||
|
.map(|(local, remote)| (local.into_inner(), remote.into_inner()))
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
// start off with any necessary local fees specific instructions
|
||||||
|
let mut local_execute_xcm = fees_local_xcm;
|
||||||
|
// move `assets` to `dest`s local sovereign account
|
||||||
|
local_execute_xcm.push(TransferAsset { assets, beneficiary: dest });
|
||||||
|
|
||||||
|
// on destination chain, start off with custom fee instructions
|
||||||
|
let mut xcm_on_dest = fees_remote_xcm;
|
||||||
|
// continue with rest of assets
|
||||||
|
xcm_on_dest.extend_from_slice(&[
|
||||||
|
// let (dest) chain know assets are in its SA on reserve
|
||||||
|
ReserveAssetDeposited(reanchored_assets),
|
||||||
|
// following instructions are not exec'ed on behalf of origin chain anymore
|
||||||
|
ClearOrigin,
|
||||||
|
]);
|
||||||
|
if !fees_already_handled {
|
||||||
|
// no custom fees instructions, they are batched together with `assets` transfer;
|
||||||
|
// BuyExecution happens after receiving all `assets`
|
||||||
|
let reanchored_fees =
|
||||||
|
fees.reanchored(&dest, context).map_err(|_| Error::<T>::CannotReanchor)?;
|
||||||
|
// buy execution using `fees` batched together with above `reanchored_assets`
|
||||||
|
xcm_on_dest.push(BuyExecution { fees: reanchored_fees, weight_limit });
|
||||||
|
}
|
||||||
|
// deposit all remaining assets in holding to `beneficiary` location
|
||||||
|
xcm_on_dest.push(DepositAsset { assets: Wild(AllCounted(max_assets)), beneficiary });
|
||||||
|
|
||||||
|
Ok((Xcm(local_execute_xcm), Xcm(xcm_on_dest)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn destination_reserve_fees_instructions(
|
||||||
|
dest: MultiLocation,
|
||||||
|
fees: MultiAsset,
|
||||||
|
weight_limit: WeightLimit,
|
||||||
|
) -> Result<(Xcm<<T as Config>::RuntimeCall>, Xcm<()>), Error<T>> {
|
||||||
|
let context = T::UniversalLocation::get();
|
||||||
|
let reanchored_fees = fees
|
||||||
|
.clone()
|
||||||
|
.reanchored(&dest, context)
|
||||||
|
.map_err(|_| Error::<T>::CannotReanchor)?;
|
||||||
|
let fees: MultiAssets = fees.into();
|
||||||
|
|
||||||
|
let local_execute_xcm = Xcm(vec![
|
||||||
|
// withdraw reserve-based fees (derivatives)
|
||||||
|
WithdrawAsset(fees.clone()),
|
||||||
|
// burn derivatives
|
||||||
|
BurnAsset(fees),
|
||||||
|
]);
|
||||||
|
let xcm_on_dest = Xcm(vec![
|
||||||
|
// withdraw `fees` from origin chain's sovereign account
|
||||||
|
WithdrawAsset(reanchored_fees.clone().into()),
|
||||||
|
// buy exec using `fees` in holding withdrawn in above instruction
|
||||||
|
BuyExecution { fees: reanchored_fees, weight_limit },
|
||||||
|
]);
|
||||||
|
Ok((local_execute_xcm, xcm_on_dest))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn destination_reserve_transfer_programs(
|
||||||
|
dest: MultiLocation,
|
||||||
|
beneficiary: MultiLocation,
|
||||||
|
assets: Vec<MultiAsset>,
|
||||||
|
fees: MultiAsset,
|
||||||
|
separate_fees_instructions: Option<(Xcm<<T as Config>::RuntimeCall>, Xcm<()>)>,
|
||||||
|
weight_limit: WeightLimit,
|
||||||
|
) -> Result<(Xcm<<T as Config>::RuntimeCall>, Xcm<()>), Error<T>> {
|
||||||
|
// max assets is `assets` (+ potentially separately handled fee)
|
||||||
|
let max_assets =
|
||||||
|
assets.len() as u32 + separate_fees_instructions.as_ref().map(|_| 1).unwrap_or(0);
|
||||||
|
let assets: MultiAssets = assets.into();
|
||||||
|
let context = T::UniversalLocation::get();
|
||||||
|
let mut reanchored_assets = assets.clone();
|
||||||
|
reanchored_assets
|
||||||
|
.reanchor(&dest, context)
|
||||||
|
.map_err(|_| Error::<T>::CannotReanchor)?;
|
||||||
|
|
||||||
|
// fees are either handled through dedicated instructions, or batched together with assets
|
||||||
|
let fees_already_handled = separate_fees_instructions.is_some();
|
||||||
|
let (fees_local_xcm, fees_remote_xcm) = separate_fees_instructions
|
||||||
|
.map(|(local, remote)| (local.into_inner(), remote.into_inner()))
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
// start off with any necessary local fees specific instructions
|
||||||
|
let mut local_execute_xcm = fees_local_xcm;
|
||||||
|
// continue with rest of assets
|
||||||
|
local_execute_xcm.extend_from_slice(&[
|
||||||
|
// withdraw reserve-based assets
|
||||||
|
WithdrawAsset(assets.clone()),
|
||||||
|
// burn reserve-based assets
|
||||||
|
BurnAsset(assets),
|
||||||
|
]);
|
||||||
|
|
||||||
|
// on destination chain, start off with custom fee instructions
|
||||||
|
let mut xcm_on_dest = fees_remote_xcm;
|
||||||
|
// continue with rest of assets
|
||||||
|
xcm_on_dest.extend_from_slice(&[
|
||||||
|
// withdraw `assets` from origin chain's sovereign account
|
||||||
|
WithdrawAsset(reanchored_assets),
|
||||||
|
// following instructions are not exec'ed on behalf of origin chain anymore
|
||||||
|
ClearOrigin,
|
||||||
|
]);
|
||||||
|
if !fees_already_handled {
|
||||||
|
// no custom fees instructions, they are batched together with `assets` transfer;
|
||||||
|
// BuyExecution happens after receiving all `assets`
|
||||||
|
let reanchored_fees =
|
||||||
|
fees.reanchored(&dest, context).map_err(|_| Error::<T>::CannotReanchor)?;
|
||||||
|
// buy execution using `fees` batched together with above `reanchored_assets`
|
||||||
|
xcm_on_dest.push(BuyExecution { fees: reanchored_fees, weight_limit });
|
||||||
|
}
|
||||||
|
// deposit all remaining assets in holding to `beneficiary` location
|
||||||
|
xcm_on_dest.push(DepositAsset { assets: Wild(AllCounted(max_assets)), beneficiary });
|
||||||
|
|
||||||
|
Ok((Xcm(local_execute_xcm), Xcm(xcm_on_dest)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// function assumes fees and assets have the same remote reserve
|
||||||
|
fn remote_reserve_transfer_program(
|
||||||
|
reserve: MultiLocation,
|
||||||
|
dest: MultiLocation,
|
||||||
|
beneficiary: MultiLocation,
|
||||||
|
assets: Vec<MultiAsset>,
|
||||||
|
fees: MultiAsset,
|
||||||
|
weight_limit: WeightLimit,
|
||||||
|
) -> Result<Xcm<<T as Config>::RuntimeCall>, Error<T>> {
|
||||||
|
let max_assets = assets.len() as u32;
|
||||||
|
let context = T::UniversalLocation::get();
|
||||||
|
// we spend up to half of fees for execution on reserve and other half for execution on
|
||||||
|
// destination
|
||||||
|
let (fees_half_1, fees_half_2) = Self::halve_fees(fees)?;
|
||||||
|
// identifies fee item as seen by `reserve` - to be used at reserve chain
|
||||||
|
let reserve_fees = fees_half_1
|
||||||
|
.reanchored(&reserve, context)
|
||||||
|
.map_err(|_| Error::<T>::CannotReanchor)?;
|
||||||
|
// identifies fee item as seen by `dest` - to be used at destination chain
|
||||||
|
let dest_fees =
|
||||||
|
fees_half_2.reanchored(&dest, context).map_err(|_| Error::<T>::CannotReanchor)?;
|
||||||
|
// identifies `dest` as seen by `reserve`
|
||||||
|
let dest = dest.reanchored(&reserve, context).map_err(|_| Error::<T>::CannotReanchor)?;
|
||||||
|
// xcm to be executed at dest
|
||||||
|
let xcm_on_dest = Xcm(vec![
|
||||||
|
BuyExecution { fees: dest_fees, weight_limit: weight_limit.clone() },
|
||||||
|
DepositAsset { assets: Wild(AllCounted(max_assets)), beneficiary },
|
||||||
|
]);
|
||||||
|
// xcm to be executed on reserve
|
||||||
|
let xcm_on_reserve = Xcm(vec![
|
||||||
|
BuyExecution { fees: reserve_fees, weight_limit },
|
||||||
|
DepositReserveAsset { assets: Wild(AllCounted(max_assets)), dest, xcm: xcm_on_dest },
|
||||||
|
]);
|
||||||
|
Ok(Xcm(vec![
|
||||||
|
WithdrawAsset(assets.into()),
|
||||||
|
InitiateReserveWithdraw {
|
||||||
|
assets: Wild(AllCounted(max_assets)),
|
||||||
|
reserve,
|
||||||
|
xcm: xcm_on_reserve,
|
||||||
|
},
|
||||||
|
]))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn teleport_fees_instructions(
|
||||||
|
dest: MultiLocation,
|
||||||
|
fees: MultiAsset,
|
||||||
|
weight_limit: WeightLimit,
|
||||||
|
) -> Result<(Xcm<<T as Config>::RuntimeCall>, Xcm<()>), Error<T>> {
|
||||||
|
let context = T::UniversalLocation::get();
|
||||||
|
let reanchored_fees = fees
|
||||||
|
.clone()
|
||||||
|
.reanchored(&dest, context)
|
||||||
|
.map_err(|_| Error::<T>::CannotReanchor)?;
|
||||||
|
|
||||||
|
// XcmContext irrelevant in teleports checks
|
||||||
|
let dummy_context =
|
||||||
|
XcmContext { origin: None, message_id: Default::default(), topic: None };
|
||||||
|
// We should check that the asset can actually be teleported out (for this to
|
||||||
|
// be in error, there would need to be an accounting violation by ourselves,
|
||||||
|
// so it's unlikely, but we don't want to allow that kind of bug to leak into
|
||||||
|
// a trusted chain.
|
||||||
|
<T::XcmExecutor as XcmAssetTransfers>::AssetTransactor::can_check_out(
|
||||||
|
&dest,
|
||||||
|
&fees,
|
||||||
|
&dummy_context,
|
||||||
|
)
|
||||||
|
.map_err(|_| Error::<T>::CannotCheckOutTeleport)?;
|
||||||
|
<T::XcmExecutor as XcmAssetTransfers>::AssetTransactor::check_out(
|
||||||
|
&dest,
|
||||||
|
&fees,
|
||||||
|
&dummy_context,
|
||||||
|
);
|
||||||
|
|
||||||
|
let fees: MultiAssets = fees.into();
|
||||||
|
let local_execute_xcm = Xcm(vec![
|
||||||
|
// withdraw fees
|
||||||
|
WithdrawAsset(fees.clone()),
|
||||||
|
// burn fees
|
||||||
|
BurnAsset(fees),
|
||||||
|
]);
|
||||||
|
let xcm_on_dest = Xcm(vec![
|
||||||
|
// (dest) chain receive teleported assets burned on origin chain
|
||||||
|
ReceiveTeleportedAsset(reanchored_fees.clone().into()),
|
||||||
|
// buy exec using `fees` in holding received in above instruction
|
||||||
|
BuyExecution { fees: reanchored_fees, weight_limit },
|
||||||
|
]);
|
||||||
|
Ok((local_execute_xcm, xcm_on_dest))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn teleport_assets_program(
|
||||||
|
dest: MultiLocation,
|
||||||
|
beneficiary: MultiLocation,
|
||||||
|
assets: Vec<MultiAsset>,
|
||||||
|
mut fees: MultiAsset,
|
||||||
|
weight_limit: WeightLimit,
|
||||||
|
) -> Result<Xcm<<T as Config>::RuntimeCall>, Error<T>> {
|
||||||
|
let context = T::UniversalLocation::get();
|
||||||
|
fees.reanchor(&dest, context).map_err(|_| Error::<T>::CannotReanchor)?;
|
||||||
|
let max_assets = assets.len() as u32;
|
||||||
|
let xcm_on_dest = Xcm(vec![
|
||||||
BuyExecution { fees, weight_limit },
|
BuyExecution { fees, weight_limit },
|
||||||
DepositAsset { assets: Wild(AllCounted(max_assets)), beneficiary },
|
DepositAsset { assets: Wild(AllCounted(max_assets)), beneficiary },
|
||||||
]);
|
]);
|
||||||
let mut message = Xcm(vec![
|
Ok(Xcm(vec![
|
||||||
WithdrawAsset(assets),
|
WithdrawAsset(assets.into()),
|
||||||
SetFeesMode { jit_withdraw: true },
|
SetFeesMode { jit_withdraw: true },
|
||||||
InitiateTeleport { assets: Wild(AllCounted(max_assets)), dest, xcm },
|
InitiateTeleport { assets: Wild(AllCounted(max_assets)), dest, xcm: xcm_on_dest },
|
||||||
]);
|
]))
|
||||||
let weight =
|
}
|
||||||
T::Weigher::weight(&mut message).map_err(|()| Error::<T>::UnweighableMessage)?;
|
|
||||||
let hash = message.using_encoded(sp_io::hashing::blake2_256);
|
/// Halve `fees` fungible amount.
|
||||||
let outcome =
|
pub(crate) fn halve_fees(fees: MultiAsset) -> Result<(MultiAsset, MultiAsset), Error<T>> {
|
||||||
T::XcmExecutor::execute_xcm_in_credit(origin_location, message, hash, weight, weight);
|
match fees.fun {
|
||||||
Self::deposit_event(Event::Attempted { outcome });
|
Fungible(amount) => {
|
||||||
Ok(())
|
let fee1 = amount.saturating_div(2);
|
||||||
|
let fee2 = amount.saturating_sub(fee1);
|
||||||
|
ensure!(fee1 > 0, Error::<T>::FeesNotMet);
|
||||||
|
ensure!(fee2 > 0, Error::<T>::FeesNotMet);
|
||||||
|
Ok((MultiAsset::from((fees.id, fee1)), MultiAsset::from((fees.id, fee2))))
|
||||||
|
},
|
||||||
|
NonFungible(_) => Err(Error::<T>::FeesNotMet),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Will always make progress, and will do its best not to use much more than `weight_cutoff`
|
/// Will always make progress, and will do its best not to use much more than `weight_cutoff`
|
||||||
|
|||||||
@@ -17,7 +17,9 @@
|
|||||||
use codec::Encode;
|
use codec::Encode;
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
construct_runtime, match_types, parameter_types,
|
construct_runtime, match_types, parameter_types,
|
||||||
traits::{ConstU32, Everything, EverythingBut, Nothing},
|
traits::{
|
||||||
|
AsEnsureOriginWithArg, ConstU128, ConstU32, Equals, Everything, EverythingBut, Nothing,
|
||||||
|
},
|
||||||
weights::Weight,
|
weights::Weight,
|
||||||
};
|
};
|
||||||
use frame_system::EnsureRoot;
|
use frame_system::EnsureRoot;
|
||||||
@@ -32,11 +34,15 @@ use xcm::prelude::*;
|
|||||||
use xcm_builder::{
|
use xcm_builder::{
|
||||||
AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom,
|
AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom,
|
||||||
AllowTopLevelPaidExecutionFrom, Case, ChildParachainAsNative, ChildParachainConvertsVia,
|
AllowTopLevelPaidExecutionFrom, Case, ChildParachainAsNative, ChildParachainConvertsVia,
|
||||||
ChildSystemParachainAsSuperuser, CurrencyAdapter as XcmCurrencyAdapter, FixedRateOfFungible,
|
ChildSystemParachainAsSuperuser, CurrencyAdapter as XcmCurrencyAdapter, DescribeAllTerminal,
|
||||||
FixedWeightBounds, IsConcrete, SignedAccountId32AsNative, SignedToAccountId32,
|
FixedRateOfFungible, FixedWeightBounds, FungiblesAdapter, HashedDescription, IsConcrete,
|
||||||
|
MatchedConvertedConcreteId, NoChecking, SignedAccountId32AsNative, SignedToAccountId32,
|
||||||
SovereignSignedViaLocation, TakeWeightCredit, XcmFeeManagerFromComponents, XcmFeeToAccount,
|
SovereignSignedViaLocation, TakeWeightCredit, XcmFeeManagerFromComponents, XcmFeeToAccount,
|
||||||
};
|
};
|
||||||
use xcm_executor::XcmExecutor;
|
use xcm_executor::{
|
||||||
|
traits::{Identity, JustTry},
|
||||||
|
XcmExecutor,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{self as pallet_xcm, TestWeightInfo};
|
use crate::{self as pallet_xcm, TestWeightInfo};
|
||||||
|
|
||||||
@@ -137,6 +143,7 @@ construct_runtime!(
|
|||||||
{
|
{
|
||||||
System: frame_system::{Pallet, Call, Storage, Config<T>, Event<T>},
|
System: frame_system::{Pallet, Call, Storage, Config<T>, Event<T>},
|
||||||
Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
|
Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
|
||||||
|
Assets: pallet_assets::{Pallet, Call, Storage, Config<T>, Event<T>},
|
||||||
ParasOrigin: origin::{Pallet, Origin},
|
ParasOrigin: origin::{Pallet, Origin},
|
||||||
XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event<T>, Origin, Config<T>},
|
XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event<T>, Origin, Config<T>},
|
||||||
TestNotifier: pallet_test_notifier::{Pallet, Call, Event<T>},
|
TestNotifier: pallet_test_notifier::{Pallet, Call, Event<T>},
|
||||||
@@ -179,13 +186,13 @@ impl SendXcm for TestSendXcmErrX8 {
|
|||||||
type Ticket = (MultiLocation, Xcm<()>);
|
type Ticket = (MultiLocation, Xcm<()>);
|
||||||
fn validate(
|
fn validate(
|
||||||
dest: &mut Option<MultiLocation>,
|
dest: &mut Option<MultiLocation>,
|
||||||
msg: &mut Option<Xcm<()>>,
|
_: &mut Option<Xcm<()>>,
|
||||||
) -> SendResult<(MultiLocation, Xcm<()>)> {
|
) -> SendResult<(MultiLocation, Xcm<()>)> {
|
||||||
let (dest, msg) = (dest.take().unwrap(), msg.take().unwrap());
|
if dest.as_ref().unwrap().len() == 8 {
|
||||||
if dest.len() == 8 {
|
dest.take();
|
||||||
Err(SendError::Transport("Destination location full"))
|
Err(SendError::Transport("Destination location full"))
|
||||||
} else {
|
} else {
|
||||||
Ok(((dest, msg), MultiAssets::new()))
|
Err(SendError::NotApplicable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn deliver(pair: (MultiLocation, Xcm<()>)) -> Result<XcmHash, SendError> {
|
fn deliver(pair: (MultiLocation, Xcm<()>)) -> Result<XcmHash, SendError> {
|
||||||
@@ -280,18 +287,135 @@ impl pallet_balances::Config for Test {
|
|||||||
type MaxFreezes = ConstU32<0>;
|
type MaxFreezes = ConstU32<0>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "runtime-benchmarks")]
|
||||||
|
/// Simple conversion of `u32` into an `AssetId` for use in benchmarking.
|
||||||
|
pub struct XcmBenchmarkHelper;
|
||||||
|
#[cfg(feature = "runtime-benchmarks")]
|
||||||
|
impl pallet_assets::BenchmarkHelper<MultiLocation> for XcmBenchmarkHelper {
|
||||||
|
fn create_asset_id_parameter(id: u32) -> MultiLocation {
|
||||||
|
MultiLocation { parents: 1, interior: X1(Parachain(id)) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl pallet_assets::Config for Test {
|
||||||
|
type RuntimeEvent = RuntimeEvent;
|
||||||
|
type Balance = Balance;
|
||||||
|
type AssetId = MultiLocation;
|
||||||
|
type AssetIdParameter = MultiLocation;
|
||||||
|
type Currency = Balances;
|
||||||
|
type CreateOrigin = AsEnsureOriginWithArg<frame_system::EnsureSigned<AccountId>>;
|
||||||
|
type ForceOrigin = EnsureRoot<AccountId>;
|
||||||
|
type AssetDeposit = ConstU128<1>;
|
||||||
|
type AssetAccountDeposit = ConstU128<10>;
|
||||||
|
type MetadataDepositBase = ConstU128<1>;
|
||||||
|
type MetadataDepositPerByte = ConstU128<1>;
|
||||||
|
type ApprovalDeposit = ConstU128<1>;
|
||||||
|
type StringLimit = ConstU32<50>;
|
||||||
|
type Freezer = ();
|
||||||
|
type WeightInfo = ();
|
||||||
|
type CallbackHandle = ();
|
||||||
|
type Extra = ();
|
||||||
|
type RemoveItemsLimit = ConstU32<5>;
|
||||||
|
#[cfg(feature = "runtime-benchmarks")]
|
||||||
|
type BenchmarkHelper = XcmBenchmarkHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This child parachain is a system parachain trusted to teleport native token.
|
||||||
|
pub const SOME_SYSTEM_PARA: u32 = 1001;
|
||||||
|
|
||||||
|
// This child parachain acts as trusted reserve for its assets in tests.
|
||||||
|
// USDT allowed to teleport to/from here.
|
||||||
|
pub const FOREIGN_ASSET_RESERVE_PARA_ID: u32 = 2001;
|
||||||
|
// Inner junction of reserve asset on `FOREIGN_ASSET_RESERVE_PARA_ID`.
|
||||||
|
pub const FOREIGN_ASSET_INNER_JUNCTION: Junction = GeneralIndex(1234567);
|
||||||
|
|
||||||
|
// This child parachain acts as trusted reserve for say.. USDC that can be used for fees.
|
||||||
|
pub const USDC_RESERVE_PARA_ID: u32 = 2002;
|
||||||
|
// Inner junction of reserve asset on `USDC_RESERVE_PARA_ID`.
|
||||||
|
pub const USDC_INNER_JUNCTION: Junction = PalletInstance(42);
|
||||||
|
|
||||||
|
// This child parachain is a trusted teleporter for say.. USDT (T from Teleport :)).
|
||||||
|
// We'll use USDT in tests that teleport fees.
|
||||||
|
pub const USDT_PARA_ID: u32 = 2003;
|
||||||
|
|
||||||
|
// This child parachain is not configured as trusted reserve or teleport location for any assets.
|
||||||
|
pub const OTHER_PARA_ID: u32 = 2009;
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub const RelayLocation: MultiLocation = Here.into_location();
|
pub const RelayLocation: MultiLocation = Here.into_location();
|
||||||
|
pub const NativeAsset: MultiAsset = MultiAsset {
|
||||||
|
fun: Fungible(10),
|
||||||
|
id: Concrete(Here.into_location()),
|
||||||
|
};
|
||||||
|
pub const SystemParachainLocation: MultiLocation = MultiLocation {
|
||||||
|
parents: 0,
|
||||||
|
interior: X1(Parachain(SOME_SYSTEM_PARA))
|
||||||
|
};
|
||||||
|
pub const ForeignReserveLocation: MultiLocation = MultiLocation {
|
||||||
|
parents: 0,
|
||||||
|
interior: X1(Parachain(FOREIGN_ASSET_RESERVE_PARA_ID))
|
||||||
|
};
|
||||||
|
pub const ForeignAsset: MultiAsset = MultiAsset {
|
||||||
|
fun: Fungible(10),
|
||||||
|
id: Concrete(MultiLocation {
|
||||||
|
parents: 0,
|
||||||
|
interior: X2(Parachain(FOREIGN_ASSET_RESERVE_PARA_ID), FOREIGN_ASSET_INNER_JUNCTION),
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
pub const UsdcReserveLocation: MultiLocation = MultiLocation {
|
||||||
|
parents: 0,
|
||||||
|
interior: X1(Parachain(USDC_RESERVE_PARA_ID))
|
||||||
|
};
|
||||||
|
pub const Usdc: MultiAsset = MultiAsset {
|
||||||
|
fun: Fungible(10),
|
||||||
|
id: Concrete(MultiLocation {
|
||||||
|
parents: 0,
|
||||||
|
interior: X2(Parachain(USDC_RESERVE_PARA_ID), USDC_INNER_JUNCTION),
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
pub const UsdtTeleportLocation: MultiLocation = MultiLocation {
|
||||||
|
parents: 0,
|
||||||
|
interior: X1(Parachain(USDT_PARA_ID))
|
||||||
|
};
|
||||||
|
pub const Usdt: MultiAsset = MultiAsset {
|
||||||
|
fun: Fungible(10),
|
||||||
|
id: Concrete(MultiLocation {
|
||||||
|
parents: 0,
|
||||||
|
interior: X1(Parachain(USDT_PARA_ID)),
|
||||||
|
}),
|
||||||
|
};
|
||||||
pub const AnyNetwork: Option<NetworkId> = None;
|
pub const AnyNetwork: Option<NetworkId> = None;
|
||||||
pub UniversalLocation: InteriorMultiLocation = Here;
|
pub UniversalLocation: InteriorMultiLocation = Here;
|
||||||
pub UnitWeightCost: u64 = 1_000;
|
pub UnitWeightCost: u64 = 1_000;
|
||||||
|
pub CheckingAccount: AccountId = XcmPallet::check_account();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type SovereignAccountOf =
|
pub type SovereignAccountOf = (
|
||||||
(ChildParachainConvertsVia<ParaId, AccountId>, AccountId32Aliases<AnyNetwork, AccountId>);
|
ChildParachainConvertsVia<ParaId, AccountId>,
|
||||||
|
AccountId32Aliases<AnyNetwork, AccountId>,
|
||||||
|
HashedDescription<AccountId, DescribeAllTerminal>,
|
||||||
|
);
|
||||||
|
|
||||||
pub type LocalAssetTransactor =
|
pub type ForeignAssetsConvertedConcreteId = MatchedConvertedConcreteId<
|
||||||
XcmCurrencyAdapter<Balances, IsConcrete<RelayLocation>, SovereignAccountOf, AccountId, ()>;
|
MultiLocation,
|
||||||
|
Balance,
|
||||||
|
// Excludes relay/parent chain currency
|
||||||
|
EverythingBut<(Equals<RelayLocation>,)>,
|
||||||
|
Identity,
|
||||||
|
JustTry,
|
||||||
|
>;
|
||||||
|
|
||||||
|
pub type AssetTransactors = (
|
||||||
|
XcmCurrencyAdapter<Balances, IsConcrete<RelayLocation>, SovereignAccountOf, AccountId, ()>,
|
||||||
|
FungiblesAdapter<
|
||||||
|
Assets,
|
||||||
|
ForeignAssetsConvertedConcreteId,
|
||||||
|
SovereignAccountOf,
|
||||||
|
AccountId,
|
||||||
|
NoChecking,
|
||||||
|
CheckingAccount,
|
||||||
|
>,
|
||||||
|
);
|
||||||
|
|
||||||
type LocalOriginConverter = (
|
type LocalOriginConverter = (
|
||||||
SovereignSignedViaLocation<SovereignAccountOf, RuntimeOrigin>,
|
SovereignSignedViaLocation<SovereignAccountOf, RuntimeOrigin>,
|
||||||
@@ -303,7 +427,12 @@ type LocalOriginConverter = (
|
|||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub const BaseXcmWeight: Weight = Weight::from_parts(1_000, 1_000);
|
pub const BaseXcmWeight: Weight = Weight::from_parts(1_000, 1_000);
|
||||||
pub CurrencyPerSecondPerByte: (AssetId, u128, u128) = (Concrete(RelayLocation::get()), 1, 1);
|
pub CurrencyPerSecondPerByte: (AssetId, u128, u128) = (Concrete(RelayLocation::get()), 1, 1);
|
||||||
pub TrustedAssets: (MultiAssetFilter, MultiLocation) = (All.into(), Here.into());
|
pub TrustedLocal: (MultiAssetFilter, MultiLocation) = (All.into(), Here.into());
|
||||||
|
pub TrustedSystemPara: (MultiAssetFilter, MultiLocation) = (NativeAsset::get().into(), SystemParachainLocation::get());
|
||||||
|
pub TrustedUsdt: (MultiAssetFilter, MultiLocation) = (Usdt::get().into(), UsdtTeleportLocation::get());
|
||||||
|
pub TeleportUsdtToForeign: (MultiAssetFilter, MultiLocation) = (Usdt::get().into(), ForeignReserveLocation::get());
|
||||||
|
pub TrustedForeign: (MultiAssetFilter, MultiLocation) = (ForeignAsset::get().into(), ForeignReserveLocation::get());
|
||||||
|
pub TrustedUsdc: (MultiAssetFilter, MultiLocation) = (Usdc::get().into(), UsdcReserveLocation::get());
|
||||||
pub const MaxInstructions: u32 = 100;
|
pub const MaxInstructions: u32 = 100;
|
||||||
pub const MaxAssetsIntoHolding: u32 = 64;
|
pub const MaxAssetsIntoHolding: u32 = 64;
|
||||||
pub XcmFeesTargetAccount: AccountId = AccountId::new([167u8; 32]);
|
pub XcmFeesTargetAccount: AccountId = AccountId::new([167u8; 32]);
|
||||||
@@ -323,14 +452,21 @@ pub type Barrier = (
|
|||||||
AllowSubscriptionsFrom<Everything>,
|
AllowSubscriptionsFrom<Everything>,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
pub type XcmRouter = (TestPaidForPara3000SendXcm, TestSendXcmErrX8, TestSendXcm);
|
||||||
|
|
||||||
pub struct XcmConfig;
|
pub struct XcmConfig;
|
||||||
impl xcm_executor::Config for XcmConfig {
|
impl xcm_executor::Config for XcmConfig {
|
||||||
type RuntimeCall = RuntimeCall;
|
type RuntimeCall = RuntimeCall;
|
||||||
type XcmSender = (TestPaidForPara3000SendXcm, TestSendXcm);
|
type XcmSender = XcmRouter;
|
||||||
type AssetTransactor = LocalAssetTransactor;
|
type AssetTransactor = AssetTransactors;
|
||||||
type OriginConverter = LocalOriginConverter;
|
type OriginConverter = LocalOriginConverter;
|
||||||
type IsReserve = ();
|
type IsReserve = (Case<TrustedForeign>, Case<TrustedUsdc>);
|
||||||
type IsTeleporter = Case<TrustedAssets>;
|
type IsTeleporter = (
|
||||||
|
Case<TrustedLocal>,
|
||||||
|
Case<TrustedSystemPara>,
|
||||||
|
Case<TrustedUsdt>,
|
||||||
|
Case<TeleportUsdtToForeign>,
|
||||||
|
);
|
||||||
type UniversalLocation = UniversalLocation;
|
type UniversalLocation = UniversalLocation;
|
||||||
type Barrier = Barrier;
|
type Barrier = Barrier;
|
||||||
type Weigher = FixedWeightBounds<BaseXcmWeight, RuntimeCall, MaxInstructions>;
|
type Weigher = FixedWeightBounds<BaseXcmWeight, RuntimeCall, MaxInstructions>;
|
||||||
@@ -360,15 +496,10 @@ parameter_types! {
|
|||||||
pub static AdvertisedXcmVersion: pallet_xcm::XcmVersion = 3;
|
pub static AdvertisedXcmVersion: pallet_xcm::XcmVersion = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
parameter_types! {
|
|
||||||
pub ReachableDest: Option<MultiLocation> = Some(Parachain(1000).into());
|
|
||||||
}
|
|
||||||
|
|
||||||
impl pallet_xcm::Config for Test {
|
impl pallet_xcm::Config for Test {
|
||||||
type RuntimeEvent = RuntimeEvent;
|
type RuntimeEvent = RuntimeEvent;
|
||||||
type SendXcmOrigin = xcm_builder::EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
|
type SendXcmOrigin = xcm_builder::EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
|
||||||
type XcmRouter = (TestSendXcmErrX8, TestPaidForPara3000SendXcm, TestSendXcm);
|
type XcmRouter = XcmRouter;
|
||||||
type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
|
type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
|
||||||
type XcmExecuteFilter = Everything;
|
type XcmExecuteFilter = Everything;
|
||||||
type XcmExecutor = XcmExecutor<XcmConfig>;
|
type XcmExecutor = XcmExecutor<XcmConfig>;
|
||||||
@@ -380,6 +511,7 @@ impl pallet_xcm::Config for Test {
|
|||||||
type RuntimeCall = RuntimeCall;
|
type RuntimeCall = RuntimeCall;
|
||||||
const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;
|
const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;
|
||||||
type AdvertisedXcmVersion = AdvertisedXcmVersion;
|
type AdvertisedXcmVersion = AdvertisedXcmVersion;
|
||||||
|
type AdminOrigin = EnsureRoot<AccountId>;
|
||||||
type TrustedLockers = ();
|
type TrustedLockers = ();
|
||||||
type SovereignAccountOf = AccountId32Aliases<(), AccountId32>;
|
type SovereignAccountOf = AccountId32Aliases<(), AccountId32>;
|
||||||
type Currency = Balances;
|
type Currency = Balances;
|
||||||
@@ -388,9 +520,6 @@ impl pallet_xcm::Config for Test {
|
|||||||
type MaxRemoteLockConsumers = frame_support::traits::ConstU32<0>;
|
type MaxRemoteLockConsumers = frame_support::traits::ConstU32<0>;
|
||||||
type RemoteLockConsumerIdentifier = ();
|
type RemoteLockConsumerIdentifier = ();
|
||||||
type WeightInfo = TestWeightInfo;
|
type WeightInfo = TestWeightInfo;
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
type ReachableDest = ReachableDest;
|
|
||||||
type AdminOrigin = EnsureRoot<AccountId>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl origin::Config for Test {}
|
impl origin::Config for Test {}
|
||||||
@@ -401,6 +530,24 @@ impl pallet_test_notifier::Config for Test {
|
|||||||
type RuntimeCall = RuntimeCall;
|
type RuntimeCall = RuntimeCall;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "runtime-benchmarks")]
|
||||||
|
impl super::benchmarking::Config for Test {
|
||||||
|
fn reachable_dest() -> Option<MultiLocation> {
|
||||||
|
Some(Parachain(1000).into())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn teleportable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> {
|
||||||
|
Some((NativeAsset::get(), SystemParachainLocation::get()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn reserve_transferable_asset_and_dest() -> Option<(MultiAsset, MultiLocation)> {
|
||||||
|
Some((
|
||||||
|
MultiAsset { fun: Fungible(10), id: Concrete(Here.into_location()) },
|
||||||
|
Parachain(OTHER_PARA_ID).into(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn last_event() -> RuntimeEvent {
|
pub(crate) fn last_event() -> RuntimeEvent {
|
||||||
System::events().pop().expect("RuntimeEvent expected").event
|
System::events().pop().expect("RuntimeEvent expected").event
|
||||||
}
|
}
|
||||||
@@ -416,10 +563,10 @@ pub(crate) fn buy_execution<C>(fees: impl Into<MultiAsset>) -> Instruction<C> {
|
|||||||
|
|
||||||
pub(crate) fn buy_limited_execution<C>(
|
pub(crate) fn buy_limited_execution<C>(
|
||||||
fees: impl Into<MultiAsset>,
|
fees: impl Into<MultiAsset>,
|
||||||
weight: Weight,
|
weight_limit: WeightLimit,
|
||||||
) -> Instruction<C> {
|
) -> Instruction<C> {
|
||||||
use xcm::latest::prelude::*;
|
use xcm::latest::prelude::*;
|
||||||
BuyExecution { fees: fees.into(), weight_limit: Limited(weight) }
|
BuyExecution { fees: fees.into(), weight_limit }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn new_test_ext_with_balances(
|
pub(crate) fn new_test_ext_with_balances(
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -14,6 +14,10 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#![cfg(test)]
|
||||||
|
|
||||||
|
mod assets_transfer;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
mock::*, AssetTraps, CurrentMigration, Error, LatestVersionedMultiLocation, Queries,
|
mock::*, AssetTraps, CurrentMigration, Error, LatestVersionedMultiLocation, Queries,
|
||||||
QueryStatus, VersionDiscoveryQueue, VersionMigrationStage, VersionNotifiers,
|
QueryStatus, VersionDiscoveryQueue, VersionMigrationStage, VersionNotifiers,
|
||||||
@@ -35,15 +39,15 @@ use xcm_executor::{
|
|||||||
|
|
||||||
const ALICE: AccountId = AccountId::new([0u8; 32]);
|
const ALICE: AccountId = AccountId::new([0u8; 32]);
|
||||||
const BOB: AccountId = AccountId::new([1u8; 32]);
|
const BOB: AccountId = AccountId::new([1u8; 32]);
|
||||||
const PARA_ID: u32 = 2000;
|
|
||||||
const INITIAL_BALANCE: u128 = 100;
|
const INITIAL_BALANCE: u128 = 100;
|
||||||
const SEND_AMOUNT: u128 = 10;
|
const SEND_AMOUNT: u128 = 10;
|
||||||
|
const FEE_AMOUNT: u128 = 2;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn report_outcome_notify_works() {
|
fn report_outcome_notify_works() {
|
||||||
let balances = vec![
|
let balances = vec![
|
||||||
(ALICE, INITIAL_BALANCE),
|
(ALICE, INITIAL_BALANCE),
|
||||||
(ParaId::from(PARA_ID).into_account_truncating(), INITIAL_BALANCE),
|
(ParaId::from(OTHER_PARA_ID).into_account_truncating(), INITIAL_BALANCE),
|
||||||
];
|
];
|
||||||
let sender: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into();
|
let sender: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into();
|
||||||
let mut message =
|
let mut message =
|
||||||
@@ -56,7 +60,7 @@ fn report_outcome_notify_works() {
|
|||||||
new_test_ext_with_balances(balances).execute_with(|| {
|
new_test_ext_with_balances(balances).execute_with(|| {
|
||||||
XcmPallet::report_outcome_notify(
|
XcmPallet::report_outcome_notify(
|
||||||
&mut message,
|
&mut message,
|
||||||
Parachain(PARA_ID).into_location(),
|
Parachain(OTHER_PARA_ID).into_location(),
|
||||||
notify,
|
notify,
|
||||||
100,
|
100,
|
||||||
)
|
)
|
||||||
@@ -74,8 +78,8 @@ fn report_outcome_notify_works() {
|
|||||||
);
|
);
|
||||||
let querier: MultiLocation = Here.into();
|
let querier: MultiLocation = Here.into();
|
||||||
let status = QueryStatus::Pending {
|
let status = QueryStatus::Pending {
|
||||||
responder: MultiLocation::from(Parachain(PARA_ID)).into(),
|
responder: MultiLocation::from(Parachain(OTHER_PARA_ID)).into(),
|
||||||
maybe_notify: Some((4, 2)),
|
maybe_notify: Some((5, 2)),
|
||||||
timeout: 100,
|
timeout: 100,
|
||||||
maybe_match_querier: Some(querier.into()),
|
maybe_match_querier: Some(querier.into()),
|
||||||
};
|
};
|
||||||
@@ -89,7 +93,7 @@ fn report_outcome_notify_works() {
|
|||||||
}]);
|
}]);
|
||||||
let hash = fake_message_hash(&message);
|
let hash = fake_message_hash(&message);
|
||||||
let r = XcmExecutor::<XcmConfig>::execute_xcm(
|
let r = XcmExecutor::<XcmConfig>::execute_xcm(
|
||||||
Parachain(PARA_ID),
|
Parachain(OTHER_PARA_ID),
|
||||||
message,
|
message,
|
||||||
hash,
|
hash,
|
||||||
Weight::from_parts(1_000_000_000, 1_000_000_000),
|
Weight::from_parts(1_000_000_000, 1_000_000_000),
|
||||||
@@ -99,13 +103,13 @@ fn report_outcome_notify_works() {
|
|||||||
last_events(2),
|
last_events(2),
|
||||||
vec![
|
vec![
|
||||||
RuntimeEvent::TestNotifier(pallet_test_notifier::Event::ResponseReceived(
|
RuntimeEvent::TestNotifier(pallet_test_notifier::Event::ResponseReceived(
|
||||||
Parachain(PARA_ID).into(),
|
Parachain(OTHER_PARA_ID).into(),
|
||||||
0,
|
0,
|
||||||
Response::ExecutionResult(None),
|
Response::ExecutionResult(None),
|
||||||
)),
|
)),
|
||||||
RuntimeEvent::XcmPallet(crate::Event::Notified {
|
RuntimeEvent::XcmPallet(crate::Event::Notified {
|
||||||
query_id: 0,
|
query_id: 0,
|
||||||
pallet_index: 4,
|
pallet_index: 5,
|
||||||
call_index: 2
|
call_index: 2
|
||||||
}),
|
}),
|
||||||
]
|
]
|
||||||
@@ -118,13 +122,14 @@ fn report_outcome_notify_works() {
|
|||||||
fn report_outcome_works() {
|
fn report_outcome_works() {
|
||||||
let balances = vec![
|
let balances = vec![
|
||||||
(ALICE, INITIAL_BALANCE),
|
(ALICE, INITIAL_BALANCE),
|
||||||
(ParaId::from(PARA_ID).into_account_truncating(), INITIAL_BALANCE),
|
(ParaId::from(OTHER_PARA_ID).into_account_truncating(), INITIAL_BALANCE),
|
||||||
];
|
];
|
||||||
let sender: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into();
|
let sender: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into();
|
||||||
let mut message =
|
let mut message =
|
||||||
Xcm(vec![TransferAsset { assets: (Here, SEND_AMOUNT).into(), beneficiary: sender }]);
|
Xcm(vec![TransferAsset { assets: (Here, SEND_AMOUNT).into(), beneficiary: sender }]);
|
||||||
new_test_ext_with_balances(balances).execute_with(|| {
|
new_test_ext_with_balances(balances).execute_with(|| {
|
||||||
XcmPallet::report_outcome(&mut message, Parachain(PARA_ID).into_location(), 100).unwrap();
|
XcmPallet::report_outcome(&mut message, Parachain(OTHER_PARA_ID).into_location(), 100)
|
||||||
|
.unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
message,
|
message,
|
||||||
Xcm(vec![
|
Xcm(vec![
|
||||||
@@ -138,7 +143,7 @@ fn report_outcome_works() {
|
|||||||
);
|
);
|
||||||
let querier: MultiLocation = Here.into();
|
let querier: MultiLocation = Here.into();
|
||||||
let status = QueryStatus::Pending {
|
let status = QueryStatus::Pending {
|
||||||
responder: MultiLocation::from(Parachain(PARA_ID)).into(),
|
responder: MultiLocation::from(Parachain(OTHER_PARA_ID)).into(),
|
||||||
maybe_notify: None,
|
maybe_notify: None,
|
||||||
timeout: 100,
|
timeout: 100,
|
||||||
maybe_match_querier: Some(querier.into()),
|
maybe_match_querier: Some(querier.into()),
|
||||||
@@ -153,7 +158,7 @@ fn report_outcome_works() {
|
|||||||
}]);
|
}]);
|
||||||
let hash = fake_message_hash(&message);
|
let hash = fake_message_hash(&message);
|
||||||
let r = XcmExecutor::<XcmConfig>::execute_xcm(
|
let r = XcmExecutor::<XcmConfig>::execute_xcm(
|
||||||
Parachain(PARA_ID),
|
Parachain(OTHER_PARA_ID),
|
||||||
message,
|
message,
|
||||||
hash,
|
hash,
|
||||||
Weight::from_parts(1_000_000_000, 1_000_000_000),
|
Weight::from_parts(1_000_000_000, 1_000_000_000),
|
||||||
@@ -177,7 +182,7 @@ fn report_outcome_works() {
|
|||||||
fn custom_querier_works() {
|
fn custom_querier_works() {
|
||||||
let balances = vec![
|
let balances = vec![
|
||||||
(ALICE, INITIAL_BALANCE),
|
(ALICE, INITIAL_BALANCE),
|
||||||
(ParaId::from(PARA_ID).into_account_truncating(), INITIAL_BALANCE),
|
(ParaId::from(OTHER_PARA_ID).into_account_truncating(), INITIAL_BALANCE),
|
||||||
];
|
];
|
||||||
new_test_ext_with_balances(balances).execute_with(|| {
|
new_test_ext_with_balances(balances).execute_with(|| {
|
||||||
let querier: MultiLocation =
|
let querier: MultiLocation =
|
||||||
@@ -281,7 +286,7 @@ fn custom_querier_works() {
|
|||||||
fn send_works() {
|
fn send_works() {
|
||||||
let balances = vec![
|
let balances = vec![
|
||||||
(ALICE, INITIAL_BALANCE),
|
(ALICE, INITIAL_BALANCE),
|
||||||
(ParaId::from(PARA_ID).into_account_truncating(), INITIAL_BALANCE),
|
(ParaId::from(OTHER_PARA_ID).into_account_truncating(), INITIAL_BALANCE),
|
||||||
];
|
];
|
||||||
new_test_ext_with_balances(balances).execute_with(|| {
|
new_test_ext_with_balances(balances).execute_with(|| {
|
||||||
let sender: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into();
|
let sender: MultiLocation = AccountId32 { network: None, id: ALICE.into() }.into();
|
||||||
@@ -325,7 +330,7 @@ fn send_works() {
|
|||||||
fn send_fails_when_xcm_router_blocks() {
|
fn send_fails_when_xcm_router_blocks() {
|
||||||
let balances = vec![
|
let balances = vec![
|
||||||
(ALICE, INITIAL_BALANCE),
|
(ALICE, INITIAL_BALANCE),
|
||||||
(ParaId::from(PARA_ID).into_account_truncating(), INITIAL_BALANCE),
|
(ParaId::from(OTHER_PARA_ID).into_account_truncating(), INITIAL_BALANCE),
|
||||||
];
|
];
|
||||||
new_test_ext_with_balances(balances).execute_with(|| {
|
new_test_ext_with_balances(balances).execute_with(|| {
|
||||||
let sender: MultiLocation =
|
let sender: MultiLocation =
|
||||||
@@ -346,344 +351,6 @@ fn send_fails_when_xcm_router_blocks() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Test `teleport_assets`
|
|
||||||
///
|
|
||||||
/// Asserts that the sender's balance is decreased as a result of execution of
|
|
||||||
/// local effects.
|
|
||||||
#[test]
|
|
||||||
fn teleport_assets_works() {
|
|
||||||
let balances = vec![
|
|
||||||
(ALICE, INITIAL_BALANCE),
|
|
||||||
(ParaId::from(PARA_ID).into_account_truncating(), INITIAL_BALANCE),
|
|
||||||
];
|
|
||||||
new_test_ext_with_balances(balances).execute_with(|| {
|
|
||||||
let weight = BaseXcmWeight::get() * 3;
|
|
||||||
assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE);
|
|
||||||
let dest: MultiLocation = AccountId32 { network: None, id: BOB.into() }.into();
|
|
||||||
assert_ok!(XcmPallet::teleport_assets(
|
|
||||||
RuntimeOrigin::signed(ALICE),
|
|
||||||
Box::new(RelayLocation::get().into()),
|
|
||||||
Box::new(dest.into()),
|
|
||||||
Box::new((Here, SEND_AMOUNT).into()),
|
|
||||||
0,
|
|
||||||
));
|
|
||||||
assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE - SEND_AMOUNT);
|
|
||||||
assert_eq!(
|
|
||||||
sent_xcm(),
|
|
||||||
vec![(
|
|
||||||
RelayLocation::get().into(),
|
|
||||||
Xcm(vec![
|
|
||||||
ReceiveTeleportedAsset((Here, SEND_AMOUNT).into()),
|
|
||||||
ClearOrigin,
|
|
||||||
buy_execution((Here, SEND_AMOUNT)),
|
|
||||||
DepositAsset { assets: AllCounted(1).into(), beneficiary: dest },
|
|
||||||
]),
|
|
||||||
)]
|
|
||||||
);
|
|
||||||
let versioned_sent = VersionedXcm::from(sent_xcm().into_iter().next().unwrap().1);
|
|
||||||
let _check_v2_ok: xcm::v2::Xcm<()> = versioned_sent.try_into().unwrap();
|
|
||||||
assert_eq!(
|
|
||||||
last_event(),
|
|
||||||
RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) })
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Test `limited_teleport_assets`
|
|
||||||
///
|
|
||||||
/// Asserts that the sender's balance is decreased as a result of execution of
|
|
||||||
/// local effects.
|
|
||||||
#[test]
|
|
||||||
fn limited_teleport_assets_works() {
|
|
||||||
let balances = vec![
|
|
||||||
(ALICE, INITIAL_BALANCE),
|
|
||||||
(ParaId::from(PARA_ID).into_account_truncating(), INITIAL_BALANCE),
|
|
||||||
];
|
|
||||||
new_test_ext_with_balances(balances).execute_with(|| {
|
|
||||||
let weight = BaseXcmWeight::get() * 3;
|
|
||||||
assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE);
|
|
||||||
let dest: MultiLocation = AccountId32 { network: None, id: BOB.into() }.into();
|
|
||||||
assert_ok!(XcmPallet::limited_teleport_assets(
|
|
||||||
RuntimeOrigin::signed(ALICE),
|
|
||||||
Box::new(RelayLocation::get().into()),
|
|
||||||
Box::new(dest.into()),
|
|
||||||
Box::new((Here, SEND_AMOUNT).into()),
|
|
||||||
0,
|
|
||||||
WeightLimit::Limited(Weight::from_parts(5000, 5000)),
|
|
||||||
));
|
|
||||||
assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE - SEND_AMOUNT);
|
|
||||||
assert_eq!(
|
|
||||||
sent_xcm(),
|
|
||||||
vec![(
|
|
||||||
RelayLocation::get().into(),
|
|
||||||
Xcm(vec![
|
|
||||||
ReceiveTeleportedAsset((Here, SEND_AMOUNT).into()),
|
|
||||||
ClearOrigin,
|
|
||||||
buy_limited_execution((Here, SEND_AMOUNT), Weight::from_parts(5000, 5000)),
|
|
||||||
DepositAsset { assets: AllCounted(1).into(), beneficiary: dest },
|
|
||||||
]),
|
|
||||||
)]
|
|
||||||
);
|
|
||||||
let versioned_sent = VersionedXcm::from(sent_xcm().into_iter().next().unwrap().1);
|
|
||||||
let _check_v2_ok: xcm::v2::Xcm<()> = versioned_sent.try_into().unwrap();
|
|
||||||
assert_eq!(
|
|
||||||
last_event(),
|
|
||||||
RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) })
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Test `limited_teleport_assets` with unlimited weight
|
|
||||||
///
|
|
||||||
/// Asserts that the sender's balance is decreased as a result of execution of
|
|
||||||
/// local effects.
|
|
||||||
#[test]
|
|
||||||
fn unlimited_teleport_assets_works() {
|
|
||||||
let balances = vec![
|
|
||||||
(ALICE, INITIAL_BALANCE),
|
|
||||||
(ParaId::from(PARA_ID).into_account_truncating(), INITIAL_BALANCE),
|
|
||||||
];
|
|
||||||
new_test_ext_with_balances(balances).execute_with(|| {
|
|
||||||
let weight = BaseXcmWeight::get() * 3;
|
|
||||||
assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE);
|
|
||||||
let dest: MultiLocation = AccountId32 { network: None, id: BOB.into() }.into();
|
|
||||||
assert_ok!(XcmPallet::limited_teleport_assets(
|
|
||||||
RuntimeOrigin::signed(ALICE),
|
|
||||||
Box::new(RelayLocation::get().into()),
|
|
||||||
Box::new(dest.into()),
|
|
||||||
Box::new((Here, SEND_AMOUNT).into()),
|
|
||||||
0,
|
|
||||||
WeightLimit::Unlimited,
|
|
||||||
));
|
|
||||||
assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE - SEND_AMOUNT);
|
|
||||||
assert_eq!(
|
|
||||||
sent_xcm(),
|
|
||||||
vec![(
|
|
||||||
RelayLocation::get().into(),
|
|
||||||
Xcm(vec![
|
|
||||||
ReceiveTeleportedAsset((Here, SEND_AMOUNT).into()),
|
|
||||||
ClearOrigin,
|
|
||||||
buy_execution((Here, SEND_AMOUNT)),
|
|
||||||
DepositAsset { assets: AllCounted(1).into(), beneficiary: dest },
|
|
||||||
]),
|
|
||||||
)]
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
last_event(),
|
|
||||||
RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) })
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Test `reserve_transfer_assets`
|
|
||||||
///
|
|
||||||
/// Asserts that the sender's balance is decreased and the beneficiary's balance
|
|
||||||
/// is increased. Verifies the correct message is sent and event is emitted.
|
|
||||||
#[test]
|
|
||||||
fn reserve_transfer_assets_works() {
|
|
||||||
let balances = vec![
|
|
||||||
(ALICE, INITIAL_BALANCE),
|
|
||||||
(ParaId::from(PARA_ID).into_account_truncating(), INITIAL_BALANCE),
|
|
||||||
];
|
|
||||||
new_test_ext_with_balances(balances).execute_with(|| {
|
|
||||||
let weight = BaseXcmWeight::get() * 2;
|
|
||||||
let dest: MultiLocation = Junction::AccountId32 { network: None, id: ALICE.into() }.into();
|
|
||||||
assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE);
|
|
||||||
assert_ok!(XcmPallet::reserve_transfer_assets(
|
|
||||||
RuntimeOrigin::signed(ALICE),
|
|
||||||
Box::new(Parachain(PARA_ID).into()),
|
|
||||||
Box::new(dest.into()),
|
|
||||||
Box::new((Here, SEND_AMOUNT).into()),
|
|
||||||
0,
|
|
||||||
));
|
|
||||||
// Alice spent amount
|
|
||||||
assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE - SEND_AMOUNT);
|
|
||||||
// Destination account (parachain account) has amount
|
|
||||||
let para_acc: AccountId = ParaId::from(PARA_ID).into_account_truncating();
|
|
||||||
assert_eq!(Balances::free_balance(para_acc), INITIAL_BALANCE + SEND_AMOUNT);
|
|
||||||
assert_eq!(
|
|
||||||
sent_xcm(),
|
|
||||||
vec![(
|
|
||||||
Parachain(PARA_ID).into(),
|
|
||||||
Xcm(vec![
|
|
||||||
ReserveAssetDeposited((Parent, SEND_AMOUNT).into()),
|
|
||||||
ClearOrigin,
|
|
||||||
buy_execution((Parent, SEND_AMOUNT)),
|
|
||||||
DepositAsset { assets: AllCounted(1).into(), beneficiary: dest },
|
|
||||||
]),
|
|
||||||
)]
|
|
||||||
);
|
|
||||||
let versioned_sent = VersionedXcm::from(sent_xcm().into_iter().next().unwrap().1);
|
|
||||||
let _check_v2_ok: xcm::v2::Xcm<()> = versioned_sent.try_into().unwrap();
|
|
||||||
assert_eq!(
|
|
||||||
last_event(),
|
|
||||||
RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) })
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Test `reserve_transfer_assets_with_paid_router_works`
|
|
||||||
///
|
|
||||||
/// Asserts that the sender's balance is decreased and the beneficiary's balance
|
|
||||||
/// is increased. Verifies the correct message is sent and event is emitted.
|
|
||||||
/// Verifies that XCM router fees (`SendXcm::validate` -> `MultiAssets`) are withdrawn from correct
|
|
||||||
/// user account and deposited to a correct target account (`XcmFeesTargetAccount`).
|
|
||||||
#[test]
|
|
||||||
fn reserve_transfer_assets_with_paid_router_works() {
|
|
||||||
let user_account = AccountId::from(XCM_FEES_NOT_WAIVED_USER_ACCOUNT);
|
|
||||||
let paid_para_id = Para3000::get();
|
|
||||||
let balances = vec![
|
|
||||||
(user_account.clone(), INITIAL_BALANCE),
|
|
||||||
(ParaId::from(paid_para_id).into_account_truncating(), INITIAL_BALANCE),
|
|
||||||
(XcmFeesTargetAccount::get(), INITIAL_BALANCE),
|
|
||||||
];
|
|
||||||
new_test_ext_with_balances(balances).execute_with(|| {
|
|
||||||
let xcm_router_fee_amount = Para3000PaymentAmount::get();
|
|
||||||
let weight = BaseXcmWeight::get() * 2;
|
|
||||||
let dest: MultiLocation =
|
|
||||||
Junction::AccountId32 { network: None, id: user_account.clone().into() }.into();
|
|
||||||
assert_eq!(Balances::total_balance(&user_account), INITIAL_BALANCE);
|
|
||||||
assert_ok!(XcmPallet::reserve_transfer_assets(
|
|
||||||
RuntimeOrigin::signed(user_account.clone()),
|
|
||||||
Box::new(Parachain(paid_para_id).into()),
|
|
||||||
Box::new(dest.into()),
|
|
||||||
Box::new((Here, SEND_AMOUNT).into()),
|
|
||||||
0,
|
|
||||||
));
|
|
||||||
// check event
|
|
||||||
assert_eq!(
|
|
||||||
last_event(),
|
|
||||||
RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) })
|
|
||||||
);
|
|
||||||
|
|
||||||
// XCM_FEES_NOT_WAIVED_USER_ACCOUNT spent amount
|
|
||||||
assert_eq!(
|
|
||||||
Balances::free_balance(user_account),
|
|
||||||
INITIAL_BALANCE - SEND_AMOUNT - xcm_router_fee_amount
|
|
||||||
);
|
|
||||||
// Destination account (parachain account) has amount
|
|
||||||
let para_acc: AccountId = ParaId::from(paid_para_id).into_account_truncating();
|
|
||||||
assert_eq!(Balances::free_balance(para_acc), INITIAL_BALANCE + SEND_AMOUNT);
|
|
||||||
// XcmFeesTargetAccount where should lend xcm_router_fee_amount
|
|
||||||
assert_eq!(
|
|
||||||
Balances::free_balance(XcmFeesTargetAccount::get()),
|
|
||||||
INITIAL_BALANCE + xcm_router_fee_amount
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
sent_xcm(),
|
|
||||||
vec![(
|
|
||||||
Parachain(paid_para_id).into(),
|
|
||||||
Xcm(vec![
|
|
||||||
ReserveAssetDeposited((Parent, SEND_AMOUNT).into()),
|
|
||||||
ClearOrigin,
|
|
||||||
buy_execution((Parent, SEND_AMOUNT)),
|
|
||||||
DepositAsset { assets: AllCounted(1).into(), beneficiary: dest },
|
|
||||||
]),
|
|
||||||
)]
|
|
||||||
);
|
|
||||||
let versioned_sent = VersionedXcm::from(sent_xcm().into_iter().next().unwrap().1);
|
|
||||||
let _check_v2_ok: xcm::v2::Xcm<()> = versioned_sent.try_into().unwrap();
|
|
||||||
assert_eq!(
|
|
||||||
last_event(),
|
|
||||||
RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) })
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Test `limited_reserve_transfer_assets`
|
|
||||||
///
|
|
||||||
/// Asserts that the sender's balance is decreased and the beneficiary's balance
|
|
||||||
/// is increased. Verifies the correct message is sent and event is emitted.
|
|
||||||
#[test]
|
|
||||||
fn limited_reserve_transfer_assets_works() {
|
|
||||||
let balances = vec![
|
|
||||||
(ALICE, INITIAL_BALANCE),
|
|
||||||
(ParaId::from(PARA_ID).into_account_truncating(), INITIAL_BALANCE),
|
|
||||||
];
|
|
||||||
new_test_ext_with_balances(balances).execute_with(|| {
|
|
||||||
let weight = BaseXcmWeight::get() * 2;
|
|
||||||
let dest: MultiLocation = Junction::AccountId32 { network: None, id: ALICE.into() }.into();
|
|
||||||
assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE);
|
|
||||||
assert_ok!(XcmPallet::limited_reserve_transfer_assets(
|
|
||||||
RuntimeOrigin::signed(ALICE),
|
|
||||||
Box::new(Parachain(PARA_ID).into()),
|
|
||||||
Box::new(dest.into()),
|
|
||||||
Box::new((Here, SEND_AMOUNT).into()),
|
|
||||||
0,
|
|
||||||
WeightLimit::Limited(Weight::from_parts(5000, 5000)),
|
|
||||||
));
|
|
||||||
// Alice spent amount
|
|
||||||
assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE - SEND_AMOUNT);
|
|
||||||
// Destination account (parachain account) has amount
|
|
||||||
let para_acc: AccountId = ParaId::from(PARA_ID).into_account_truncating();
|
|
||||||
assert_eq!(Balances::free_balance(para_acc), INITIAL_BALANCE + SEND_AMOUNT);
|
|
||||||
assert_eq!(
|
|
||||||
sent_xcm(),
|
|
||||||
vec![(
|
|
||||||
Parachain(PARA_ID).into(),
|
|
||||||
Xcm(vec![
|
|
||||||
ReserveAssetDeposited((Parent, SEND_AMOUNT).into()),
|
|
||||||
ClearOrigin,
|
|
||||||
buy_limited_execution((Parent, SEND_AMOUNT), Weight::from_parts(5000, 5000)),
|
|
||||||
DepositAsset { assets: AllCounted(1).into(), beneficiary: dest },
|
|
||||||
]),
|
|
||||||
)]
|
|
||||||
);
|
|
||||||
let versioned_sent = VersionedXcm::from(sent_xcm().into_iter().next().unwrap().1);
|
|
||||||
let _check_v2_ok: xcm::v2::Xcm<()> = versioned_sent.try_into().unwrap();
|
|
||||||
assert_eq!(
|
|
||||||
last_event(),
|
|
||||||
RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) })
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Test `limited_reserve_transfer_assets` with unlimited weight purchasing
|
|
||||||
///
|
|
||||||
/// Asserts that the sender's balance is decreased and the beneficiary's balance
|
|
||||||
/// is increased. Verifies the correct message is sent and event is emitted.
|
|
||||||
#[test]
|
|
||||||
fn unlimited_reserve_transfer_assets_works() {
|
|
||||||
let balances = vec![
|
|
||||||
(ALICE, INITIAL_BALANCE),
|
|
||||||
(ParaId::from(PARA_ID).into_account_truncating(), INITIAL_BALANCE),
|
|
||||||
];
|
|
||||||
new_test_ext_with_balances(balances).execute_with(|| {
|
|
||||||
let weight = BaseXcmWeight::get() * 2;
|
|
||||||
let dest: MultiLocation = Junction::AccountId32 { network: None, id: ALICE.into() }.into();
|
|
||||||
assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE);
|
|
||||||
assert_ok!(XcmPallet::limited_reserve_transfer_assets(
|
|
||||||
RuntimeOrigin::signed(ALICE),
|
|
||||||
Box::new(Parachain(PARA_ID).into()),
|
|
||||||
Box::new(dest.into()),
|
|
||||||
Box::new((Here, SEND_AMOUNT).into()),
|
|
||||||
0,
|
|
||||||
WeightLimit::Unlimited,
|
|
||||||
));
|
|
||||||
// Alice spent amount
|
|
||||||
assert_eq!(Balances::free_balance(ALICE), INITIAL_BALANCE - SEND_AMOUNT);
|
|
||||||
// Destination account (parachain account) has amount
|
|
||||||
let para_acc: AccountId = ParaId::from(PARA_ID).into_account_truncating();
|
|
||||||
assert_eq!(Balances::free_balance(para_acc), INITIAL_BALANCE + SEND_AMOUNT);
|
|
||||||
assert_eq!(
|
|
||||||
sent_xcm(),
|
|
||||||
vec![(
|
|
||||||
Parachain(PARA_ID).into(),
|
|
||||||
Xcm(vec![
|
|
||||||
ReserveAssetDeposited((Parent, SEND_AMOUNT).into()),
|
|
||||||
ClearOrigin,
|
|
||||||
buy_execution((Parent, SEND_AMOUNT)),
|
|
||||||
DepositAsset { assets: AllCounted(1).into(), beneficiary: dest },
|
|
||||||
]),
|
|
||||||
)]
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
last_event(),
|
|
||||||
RuntimeEvent::XcmPallet(crate::Event::Attempted { outcome: Outcome::Complete(weight) })
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Test local execution of XCM
|
/// Test local execution of XCM
|
||||||
///
|
///
|
||||||
/// Asserts that the sender's balance is decreased and the beneficiary's balance
|
/// Asserts that the sender's balance is decreased and the beneficiary's balance
|
||||||
@@ -692,7 +359,7 @@ fn unlimited_reserve_transfer_assets_works() {
|
|||||||
fn execute_withdraw_to_deposit_works() {
|
fn execute_withdraw_to_deposit_works() {
|
||||||
let balances = vec![
|
let balances = vec![
|
||||||
(ALICE, INITIAL_BALANCE),
|
(ALICE, INITIAL_BALANCE),
|
||||||
(ParaId::from(PARA_ID).into_account_truncating(), INITIAL_BALANCE),
|
(ParaId::from(OTHER_PARA_ID).into_account_truncating(), INITIAL_BALANCE),
|
||||||
];
|
];
|
||||||
new_test_ext_with_balances(balances).execute_with(|| {
|
new_test_ext_with_balances(balances).execute_with(|| {
|
||||||
let weight = BaseXcmWeight::get() * 3;
|
let weight = BaseXcmWeight::get() * 3;
|
||||||
@@ -444,6 +444,21 @@ impl MultiLocation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return the MultiLocation subsection identifying the chain that `self` points to.
|
||||||
|
pub fn chain_location(&self) -> MultiLocation {
|
||||||
|
let mut clone = *self;
|
||||||
|
// start popping junctions until we reach chain identifier
|
||||||
|
while let Some(j) = clone.last() {
|
||||||
|
if matches!(j, Junction::Parachain(_) | Junction::GlobalConsensus(_)) {
|
||||||
|
// return chain subsection
|
||||||
|
return clone
|
||||||
|
} else {
|
||||||
|
(clone, _) = clone.split_last_interior();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MultiLocation::new(clone.parents, Junctions::Here)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<OldMultiLocation> for MultiLocation {
|
impl TryFrom<OldMultiLocation> for MultiLocation {
|
||||||
@@ -674,6 +689,57 @@ mod tests {
|
|||||||
assert_eq!(iter.next_back(), None);
|
assert_eq!(iter.next_back(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn chain_location_works() {
|
||||||
|
// Relay-chain or parachain context pointing to local resource,
|
||||||
|
let relay_to_local = MultiLocation::new(0, (PalletInstance(42), GeneralIndex(42)));
|
||||||
|
assert_eq!(relay_to_local.chain_location(), MultiLocation::here());
|
||||||
|
|
||||||
|
// Relay-chain context pointing to child parachain,
|
||||||
|
let relay_to_child =
|
||||||
|
MultiLocation::new(0, (Parachain(42), PalletInstance(42), GeneralIndex(42)));
|
||||||
|
let expected = MultiLocation::new(0, Parachain(42));
|
||||||
|
assert_eq!(relay_to_child.chain_location(), expected);
|
||||||
|
|
||||||
|
// Relay-chain context pointing to different consensus relay,
|
||||||
|
let relay_to_remote_relay =
|
||||||
|
MultiLocation::new(1, (GlobalConsensus(Kusama), PalletInstance(42), GeneralIndex(42)));
|
||||||
|
let expected = MultiLocation::new(1, GlobalConsensus(Kusama));
|
||||||
|
assert_eq!(relay_to_remote_relay.chain_location(), expected);
|
||||||
|
|
||||||
|
// Relay-chain context pointing to different consensus parachain,
|
||||||
|
let relay_to_remote_para = MultiLocation::new(
|
||||||
|
1,
|
||||||
|
(GlobalConsensus(Kusama), Parachain(42), PalletInstance(42), GeneralIndex(42)),
|
||||||
|
);
|
||||||
|
let expected = MultiLocation::new(1, (GlobalConsensus(Kusama), Parachain(42)));
|
||||||
|
assert_eq!(relay_to_remote_para.chain_location(), expected);
|
||||||
|
|
||||||
|
// Parachain context pointing to relay chain,
|
||||||
|
let para_to_relay = MultiLocation::new(1, (PalletInstance(42), GeneralIndex(42)));
|
||||||
|
assert_eq!(para_to_relay.chain_location(), MultiLocation::parent());
|
||||||
|
|
||||||
|
// Parachain context pointing to sibling parachain,
|
||||||
|
let para_to_sibling =
|
||||||
|
MultiLocation::new(1, (Parachain(42), PalletInstance(42), GeneralIndex(42)));
|
||||||
|
let expected = MultiLocation::new(1, Parachain(42));
|
||||||
|
assert_eq!(para_to_sibling.chain_location(), expected);
|
||||||
|
|
||||||
|
// Parachain context pointing to different consensus relay,
|
||||||
|
let para_to_remote_relay =
|
||||||
|
MultiLocation::new(2, (GlobalConsensus(Kusama), PalletInstance(42), GeneralIndex(42)));
|
||||||
|
let expected = MultiLocation::new(2, GlobalConsensus(Kusama));
|
||||||
|
assert_eq!(para_to_remote_relay.chain_location(), expected);
|
||||||
|
|
||||||
|
// Parachain context pointing to different consensus parachain,
|
||||||
|
let para_to_remote_para = MultiLocation::new(
|
||||||
|
2,
|
||||||
|
(GlobalConsensus(Kusama), Parachain(42), PalletInstance(42), GeneralIndex(42)),
|
||||||
|
);
|
||||||
|
let expected = MultiLocation::new(2, (GlobalConsensus(Kusama), Parachain(42)));
|
||||||
|
assert_eq!(para_to_remote_para.chain_location(), expected);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn conversion_from_other_types_works() {
|
fn conversion_from_other_types_works() {
|
||||||
use crate::v2;
|
use crate::v2;
|
||||||
|
|||||||
@@ -81,10 +81,15 @@ impl<T: Contains<MultiLocation>> ShouldExecute for AllowTopLevelPaidExecutionFro
|
|||||||
instructions[..end]
|
instructions[..end]
|
||||||
.matcher()
|
.matcher()
|
||||||
.match_next_inst(|inst| match inst {
|
.match_next_inst(|inst| match inst {
|
||||||
ReceiveTeleportedAsset(..) | ReserveAssetDeposited(..) => Ok(()),
|
ReceiveTeleportedAsset(ref assets) |
|
||||||
WithdrawAsset(ref assets) if assets.len() <= MAX_ASSETS_FOR_BUY_EXECUTION => Ok(()),
|
ReserveAssetDeposited(ref assets) |
|
||||||
ClaimAsset { ref assets, .. } if assets.len() <= MAX_ASSETS_FOR_BUY_EXECUTION =>
|
WithdrawAsset(ref assets) |
|
||||||
Ok(()),
|
ClaimAsset { ref assets, .. } =>
|
||||||
|
if assets.len() <= MAX_ASSETS_FOR_BUY_EXECUTION {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(ProcessMessageError::BadFormat)
|
||||||
|
},
|
||||||
_ => Err(ProcessMessageError::BadFormat),
|
_ => Err(ProcessMessageError::BadFormat),
|
||||||
})?
|
})?
|
||||||
.skip_inst_while(|inst| matches!(inst, ClearOrigin))?
|
.skip_inst_while(|inst| matches!(inst, ClearOrigin))?
|
||||||
|
|||||||
@@ -246,11 +246,6 @@ type SovereignAccountOf = (
|
|||||||
HashedDescription<AccountId, DescribeFamily<DescribeAllTerminal>>,
|
HashedDescription<AccountId, DescribeFamily<DescribeAllTerminal>>,
|
||||||
);
|
);
|
||||||
|
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
parameter_types! {
|
|
||||||
pub ReachableDest: Option<MultiLocation> = Some(Parachain(1000).into());
|
|
||||||
}
|
|
||||||
|
|
||||||
impl pallet_xcm::Config for Test {
|
impl pallet_xcm::Config for Test {
|
||||||
type RuntimeEvent = RuntimeEvent;
|
type RuntimeEvent = RuntimeEvent;
|
||||||
type SendXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
|
type SendXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
|
||||||
@@ -274,8 +269,6 @@ impl pallet_xcm::Config for Test {
|
|||||||
type MaxRemoteLockConsumers = frame_support::traits::ConstU32<0>;
|
type MaxRemoteLockConsumers = frame_support::traits::ConstU32<0>;
|
||||||
type RemoteLockConsumerIdentifier = ();
|
type RemoteLockConsumerIdentifier = ();
|
||||||
type WeightInfo = pallet_xcm::TestWeightInfo;
|
type WeightInfo = pallet_xcm::TestWeightInfo;
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
type ReachableDest = ReachableDest;
|
|
||||||
type AdminOrigin = EnsureRoot<AccountId>;
|
type AdminOrigin = EnsureRoot<AccountId>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -210,11 +210,6 @@ impl xcm_executor::Config for XcmConfig {
|
|||||||
|
|
||||||
pub type LocalOriginToLocation = SignedToAccountId32<RuntimeOrigin, AccountId, KusamaNetwork>;
|
pub type LocalOriginToLocation = SignedToAccountId32<RuntimeOrigin, AccountId, KusamaNetwork>;
|
||||||
|
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
parameter_types! {
|
|
||||||
pub ReachableDest: Option<MultiLocation> = Some(Here.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
impl pallet_xcm::Config for Runtime {
|
impl pallet_xcm::Config for Runtime {
|
||||||
type RuntimeEvent = RuntimeEvent;
|
type RuntimeEvent = RuntimeEvent;
|
||||||
type UniversalLocation = UniversalLocation;
|
type UniversalLocation = UniversalLocation;
|
||||||
@@ -239,8 +234,6 @@ impl pallet_xcm::Config for Runtime {
|
|||||||
type MaxRemoteLockConsumers = frame_support::traits::ConstU32<0>;
|
type MaxRemoteLockConsumers = frame_support::traits::ConstU32<0>;
|
||||||
type RemoteLockConsumerIdentifier = ();
|
type RemoteLockConsumerIdentifier = ();
|
||||||
type WeightInfo = pallet_xcm::TestWeightInfo;
|
type WeightInfo = pallet_xcm::TestWeightInfo;
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
type ReachableDest = ReachableDest;
|
|
||||||
type AdminOrigin = EnsureRoot<AccountId>;
|
type AdminOrigin = EnsureRoot<AccountId>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ version = "1.0.0"
|
|||||||
impl-trait-for-tuples = "0.2.2"
|
impl-trait-for-tuples = "0.2.2"
|
||||||
environmental = { version = "1.1.4", default-features = false }
|
environmental = { version = "1.1.4", default-features = false }
|
||||||
parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] }
|
parity-scale-codec = { version = "3.6.1", default-features = false, features = ["derive"] }
|
||||||
|
scale-info = { version = "2.5.0", default-features = false, features = ["derive", "serde"] }
|
||||||
xcm = { package = "staging-xcm", path = "..", default-features = false }
|
xcm = { package = "staging-xcm", path = "..", default-features = false }
|
||||||
sp-std = { path = "../../../substrate/primitives/std", default-features = false }
|
sp-std = { path = "../../../substrate/primitives/std", default-features = false }
|
||||||
sp-io = { path = "../../../substrate/primitives/io", default-features = false }
|
sp-io = { path = "../../../substrate/primitives/io", default-features = false }
|
||||||
@@ -34,6 +35,7 @@ std = [
|
|||||||
"frame-support/std",
|
"frame-support/std",
|
||||||
"log/std",
|
"log/std",
|
||||||
"parity-scale-codec/std",
|
"parity-scale-codec/std",
|
||||||
|
"scale-info/std",
|
||||||
"sp-arithmetic/std",
|
"sp-arithmetic/std",
|
||||||
"sp-core/std",
|
"sp-core/std",
|
||||||
"sp-io/std",
|
"sp-io/std",
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ pub mod traits;
|
|||||||
use traits::{
|
use traits::{
|
||||||
validate_export, AssetExchange, AssetLock, CallDispatcher, ClaimAssets, ConvertOrigin,
|
validate_export, AssetExchange, AssetLock, CallDispatcher, ClaimAssets, ConvertOrigin,
|
||||||
DropAssets, Enact, ExportXcm, FeeManager, FeeReason, OnResponse, Properties, ShouldExecute,
|
DropAssets, Enact, ExportXcm, FeeManager, FeeReason, OnResponse, Properties, ShouldExecute,
|
||||||
TransactAsset, VersionChangeNotifier, WeightBounds, WeightTrader,
|
TransactAsset, VersionChangeNotifier, WeightBounds, WeightTrader, XcmAssetTransfers,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod assets;
|
mod assets;
|
||||||
@@ -254,6 +254,12 @@ impl<Config: config::Config> ExecuteXcm<Config::RuntimeCall> for XcmExecutor<Con
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<Config: config::Config> XcmAssetTransfers for XcmExecutor<Config> {
|
||||||
|
type IsReserve = Config::IsReserve;
|
||||||
|
type IsTeleporter = Config::IsTeleporter;
|
||||||
|
type AssetTransactor = Config::AssetTransactor;
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ExecutorError {
|
pub struct ExecutorError {
|
||||||
pub index: u32,
|
pub index: u32,
|
||||||
|
|||||||
@@ -0,0 +1,90 @@
|
|||||||
|
// Copyright (C) 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 crate::traits::TransactAsset;
|
||||||
|
use frame_support::traits::ContainsPair;
|
||||||
|
use scale_info::TypeInfo;
|
||||||
|
use sp_runtime::codec::{Decode, Encode};
|
||||||
|
use xcm::prelude::*;
|
||||||
|
|
||||||
|
/// Errors related to determining asset transfer support.
|
||||||
|
#[derive(Copy, Clone, Encode, Decode, Eq, PartialEq, Debug, TypeInfo)]
|
||||||
|
pub enum Error {
|
||||||
|
/// Invalid non-concrete asset.
|
||||||
|
NotConcrete,
|
||||||
|
/// Reserve chain could not be determined for assets.
|
||||||
|
UnknownReserve,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Specify which type of asset transfer is required for a particular `(asset, dest)` combination.
|
||||||
|
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||||
|
pub enum TransferType {
|
||||||
|
/// should teleport `asset` to `dest`
|
||||||
|
Teleport,
|
||||||
|
/// should reserve-transfer `asset` to `dest`, using local chain as reserve
|
||||||
|
LocalReserve,
|
||||||
|
/// should reserve-transfer `asset` to `dest`, using `dest` as reserve
|
||||||
|
DestinationReserve,
|
||||||
|
/// should reserve-transfer `asset` to `dest`, using remote chain `MultiLocation` as reserve
|
||||||
|
RemoteReserve(MultiLocation),
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A trait for identifying asset transfer type based on `IsTeleporter` and `IsReserve`
|
||||||
|
/// configurations.
|
||||||
|
pub trait XcmAssetTransfers {
|
||||||
|
/// Combinations of (Asset, Location) pairs which we trust as reserves. Meaning
|
||||||
|
/// reserve-based-transfers are to be used for assets matching this filter.
|
||||||
|
type IsReserve: ContainsPair<MultiAsset, MultiLocation>;
|
||||||
|
|
||||||
|
/// Combinations of (Asset, Location) pairs which we trust as teleporters. Meaning teleports are
|
||||||
|
/// to be used for assets matching this filter.
|
||||||
|
type IsTeleporter: ContainsPair<MultiAsset, MultiLocation>;
|
||||||
|
|
||||||
|
/// How to withdraw and deposit an asset.
|
||||||
|
type AssetTransactor: TransactAsset;
|
||||||
|
|
||||||
|
/// Determine transfer type to be used for transferring `asset` from local chain to `dest`.
|
||||||
|
fn determine_for(asset: &MultiAsset, dest: &MultiLocation) -> Result<TransferType, Error> {
|
||||||
|
if Self::IsTeleporter::contains(asset, dest) {
|
||||||
|
// we trust destination for teleporting asset
|
||||||
|
return Ok(TransferType::Teleport)
|
||||||
|
} else if Self::IsReserve::contains(asset, dest) {
|
||||||
|
// we trust destination as asset reserve location
|
||||||
|
return Ok(TransferType::DestinationReserve)
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to determine reserve location based on asset id/location
|
||||||
|
let asset_location = match asset.id {
|
||||||
|
Concrete(location) => Ok(location.chain_location()),
|
||||||
|
_ => Err(Error::NotConcrete),
|
||||||
|
}?;
|
||||||
|
if asset_location == MultiLocation::here() ||
|
||||||
|
Self::IsTeleporter::contains(asset, &asset_location)
|
||||||
|
{
|
||||||
|
// if the asset is local, then it's a local reserve
|
||||||
|
// it's also a local reserve if the asset's location is not `here` but it's a location
|
||||||
|
// where it can be teleported to `here` => local reserve
|
||||||
|
Ok(TransferType::LocalReserve)
|
||||||
|
} else if Self::IsReserve::contains(asset, &asset_location) {
|
||||||
|
// remote location that is recognized as reserve location for asset
|
||||||
|
Ok(TransferType::RemoteReserve(asset_location))
|
||||||
|
} else {
|
||||||
|
// remote location that is not configured either as teleporter or reserve => cannot
|
||||||
|
// determine asset reserve
|
||||||
|
Err(Error::UnknownReserve)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,10 +20,12 @@ mod conversion;
|
|||||||
pub use conversion::{CallDispatcher, ConvertLocation, ConvertOrigin, WithOriginFilter};
|
pub use conversion::{CallDispatcher, ConvertLocation, ConvertOrigin, WithOriginFilter};
|
||||||
mod drop_assets;
|
mod drop_assets;
|
||||||
pub use drop_assets::{ClaimAssets, DropAssets};
|
pub use drop_assets::{ClaimAssets, DropAssets};
|
||||||
mod asset_lock;
|
|
||||||
pub use asset_lock::{AssetLock, Enact, LockError};
|
|
||||||
mod asset_exchange;
|
mod asset_exchange;
|
||||||
pub use asset_exchange::AssetExchange;
|
pub use asset_exchange::AssetExchange;
|
||||||
|
mod asset_lock;
|
||||||
|
pub use asset_lock::{AssetLock, Enact, LockError};
|
||||||
|
mod asset_transfer;
|
||||||
|
pub use asset_transfer::{Error as AssetTransferError, TransferType, XcmAssetTransfers};
|
||||||
mod export;
|
mod export;
|
||||||
pub use export::{export_xcm, validate_export, ExportXcm};
|
pub use export::{export_xcm, validate_export, ExportXcm};
|
||||||
mod fee_manager;
|
mod fee_manager;
|
||||||
|
|||||||
@@ -399,11 +399,6 @@ impl mock_msg_queue::Config for Runtime {
|
|||||||
|
|
||||||
pub type LocalOriginToLocation = SignedToAccountId32<RuntimeOrigin, AccountId, RelayNetwork>;
|
pub type LocalOriginToLocation = SignedToAccountId32<RuntimeOrigin, AccountId, RelayNetwork>;
|
||||||
|
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
parameter_types! {
|
|
||||||
pub ReachableDest: Option<MultiLocation> = Some(Parent.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct TrustedLockerCase<T>(PhantomData<T>);
|
pub struct TrustedLockerCase<T>(PhantomData<T>);
|
||||||
impl<T: Get<(MultiLocation, MultiAssetFilter)>> ContainsPair<MultiLocation, MultiAsset>
|
impl<T: Get<(MultiLocation, MultiAssetFilter)>> ContainsPair<MultiLocation, MultiAsset>
|
||||||
for TrustedLockerCase<T>
|
for TrustedLockerCase<T>
|
||||||
@@ -443,8 +438,6 @@ impl pallet_xcm::Config for Runtime {
|
|||||||
type MaxRemoteLockConsumers = ConstU32<0>;
|
type MaxRemoteLockConsumers = ConstU32<0>;
|
||||||
type RemoteLockConsumerIdentifier = ();
|
type RemoteLockConsumerIdentifier = ();
|
||||||
type WeightInfo = pallet_xcm::TestWeightInfo;
|
type WeightInfo = pallet_xcm::TestWeightInfo;
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
type ReachableDest = ReachableDest;
|
|
||||||
type AdminOrigin = EnsureRoot<AccountId>;
|
type AdminOrigin = EnsureRoot<AccountId>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -199,11 +199,6 @@ impl Config for XcmConfig {
|
|||||||
|
|
||||||
pub type LocalOriginToLocation = SignedToAccountId32<RuntimeOrigin, AccountId, RelayNetwork>;
|
pub type LocalOriginToLocation = SignedToAccountId32<RuntimeOrigin, AccountId, RelayNetwork>;
|
||||||
|
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
parameter_types! {
|
|
||||||
pub ReachableDest: Option<MultiLocation> = Some(Parachain(1).into());
|
|
||||||
}
|
|
||||||
|
|
||||||
impl pallet_xcm::Config for Runtime {
|
impl pallet_xcm::Config for Runtime {
|
||||||
type RuntimeEvent = RuntimeEvent;
|
type RuntimeEvent = RuntimeEvent;
|
||||||
type SendXcmOrigin = xcm_builder::EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
|
type SendXcmOrigin = xcm_builder::EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
|
||||||
@@ -228,8 +223,6 @@ impl pallet_xcm::Config for Runtime {
|
|||||||
type MaxRemoteLockConsumers = ConstU32<0>;
|
type MaxRemoteLockConsumers = ConstU32<0>;
|
||||||
type RemoteLockConsumerIdentifier = ();
|
type RemoteLockConsumerIdentifier = ();
|
||||||
type WeightInfo = pallet_xcm::TestWeightInfo;
|
type WeightInfo = pallet_xcm::TestWeightInfo;
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
type ReachableDest = ReachableDest;
|
|
||||||
type AdminOrigin = EnsureRoot<AccountId>;
|
type AdminOrigin = EnsureRoot<AccountId>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -313,11 +313,6 @@ impl mock_msg_queue::Config for Runtime {
|
|||||||
|
|
||||||
pub type LocalOriginToLocation = SignedToAccountId32<RuntimeOrigin, AccountId, RelayNetwork>;
|
pub type LocalOriginToLocation = SignedToAccountId32<RuntimeOrigin, AccountId, RelayNetwork>;
|
||||||
|
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
parameter_types! {
|
|
||||||
pub ReachableDest: Option<MultiLocation> = Some(Parent.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
impl pallet_xcm::Config for Runtime {
|
impl pallet_xcm::Config for Runtime {
|
||||||
type RuntimeEvent = RuntimeEvent;
|
type RuntimeEvent = RuntimeEvent;
|
||||||
type SendXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
|
type SendXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
|
||||||
@@ -341,8 +336,6 @@ impl pallet_xcm::Config for Runtime {
|
|||||||
type MaxRemoteLockConsumers = frame_support::traits::ConstU32<0>;
|
type MaxRemoteLockConsumers = frame_support::traits::ConstU32<0>;
|
||||||
type RemoteLockConsumerIdentifier = ();
|
type RemoteLockConsumerIdentifier = ();
|
||||||
type WeightInfo = pallet_xcm::TestWeightInfo;
|
type WeightInfo = pallet_xcm::TestWeightInfo;
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
type ReachableDest = ReachableDest;
|
|
||||||
type AdminOrigin = EnsureRoot<AccountId>;
|
type AdminOrigin = EnsureRoot<AccountId>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -163,11 +163,6 @@ impl Config for XcmConfig {
|
|||||||
|
|
||||||
pub type LocalOriginToLocation = SignedToAccountId32<RuntimeOrigin, AccountId, ThisNetwork>;
|
pub type LocalOriginToLocation = SignedToAccountId32<RuntimeOrigin, AccountId, ThisNetwork>;
|
||||||
|
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
parameter_types! {
|
|
||||||
pub ReachableDest: Option<MultiLocation> = Some(Parachain(1).into());
|
|
||||||
}
|
|
||||||
|
|
||||||
impl pallet_xcm::Config for Runtime {
|
impl pallet_xcm::Config for Runtime {
|
||||||
type RuntimeEvent = RuntimeEvent;
|
type RuntimeEvent = RuntimeEvent;
|
||||||
type SendXcmOrigin = xcm_builder::EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
|
type SendXcmOrigin = xcm_builder::EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
|
||||||
@@ -192,8 +187,6 @@ impl pallet_xcm::Config for Runtime {
|
|||||||
type MaxRemoteLockConsumers = ConstU32<0>;
|
type MaxRemoteLockConsumers = ConstU32<0>;
|
||||||
type RemoteLockConsumerIdentifier = ();
|
type RemoteLockConsumerIdentifier = ();
|
||||||
type WeightInfo = pallet_xcm::TestWeightInfo;
|
type WeightInfo = pallet_xcm::TestWeightInfo;
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
|
||||||
type ReachableDest = ReachableDest;
|
|
||||||
type AdminOrigin = EnsureRoot<AccountId>;
|
type AdminOrigin = EnsureRoot<AccountId>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user