From 0eb70fcd62d3280bfff4d463fceb727a75e3c45a Mon Sep 17 00:00:00 2001
From: Guantong <04637@163.com>
Date: Fri, 19 Aug 2022 10:38:52 +0800
Subject: [PATCH 01/37] init message router pallet
---
runtime/common/src/lib.rs | 1 +
runtime/common/src/message_router/mod.rs | 58 ++++++++++++++++++++++++
2 files changed, 59 insertions(+)
create mode 100644 runtime/common/src/message_router/mod.rs
diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs
index a7073754..c408196e 100644
--- a/runtime/common/src/lib.rs
+++ b/runtime/common/src/lib.rs
@@ -19,6 +19,7 @@
#![cfg_attr(not(feature = "std"), no_std)]
pub mod helixbridge;
+pub mod message_router;
pub mod remote_governance;
pub mod xcm_config;
diff --git a/runtime/common/src/message_router/mod.rs b/runtime/common/src/message_router/mod.rs
new file mode 100644
index 00000000..e47a30ad
--- /dev/null
+++ b/runtime/common/src/message_router/mod.rs
@@ -0,0 +1,58 @@
+// This file is part of Darwinia.
+//
+// Copyright (C) 2018-2022 Darwinia Network
+// SPDX-License-Identifier: GPL-3.0
+//
+// Darwinia 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.
+//
+// Darwinia 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 Darwinia. If not, see .
+
+//! Prototype module for message router.
+
+// --- paritytech ---
+use frame_support::{
+ ensure,
+ pallet_prelude::*,
+ traits::{Get, UnfilteredDispatchable},
+ weights::GetDispatchInfo,
+};
+
+#[frame_support::pallet]
+pub mod pallet {
+ use super::*;
+ use frame_system::pallet_prelude::*;
+
+ #[pallet::config]
+ pub trait Config: frame_system::Config {
+
+ }
+
+ #[pallet::event]
+ #[pallet::generate_deposit(pub(super) fn deposit_event)]
+ pub enum Event {
+
+ }
+
+ #[pallet::error]
+ pub enum Error {
+
+ }
+
+ #[pallet::pallet]
+ #[pallet::generate_store(pub(super) trait Store)]
+ pub struct Pallet(PhantomData);
+
+ #[pallet::call]
+ impl Pallet {
+
+ }
+}
\ No newline at end of file
From 71429559de4dff93312f3b1c8182b89e8d88435e Mon Sep 17 00:00:00 2001
From: Guantong <04637@163.com>
Date: Tue, 23 Aug 2022 14:42:21 +0800
Subject: [PATCH 02/37] Add xcm exec config
Conflicts:
Cargo.lock
runtime/common/Cargo.toml
---
runtime/common/src/message_router/mod.rs | 105 +++++++++++++++++++++--
1 file changed, 99 insertions(+), 6 deletions(-)
diff --git a/runtime/common/src/message_router/mod.rs b/runtime/common/src/message_router/mod.rs
index e47a30ad..c32d8c3b 100644
--- a/runtime/common/src/message_router/mod.rs
+++ b/runtime/common/src/message_router/mod.rs
@@ -22,37 +22,130 @@
use frame_support::{
ensure,
pallet_prelude::*,
- traits::{Get, UnfilteredDispatchable},
+ traits::{Currency, ExistenceRequirement, Get, WithdrawReasons},
weights::GetDispatchInfo,
};
+pub use pallet::*;
+use polkadot_parachain::primitives::Sibling;
+use xcm::{
+ prelude::*
+};
+use xcm_executor::traits::WeightBounds;
+use xcm_builder::FixedWeightBounds;
+use xcm_builder::SiblingParachainConvertsVia;
+use xcm_executor::traits::Convert;
+
+pub type AccountId = ::AccountId;
+pub type RingBalance = <::RingCurrency as Currency>>::Balance;
+pub type XcmUnitWeightCost = Weight;
+pub type AssetUnitsPerSecond = u128;
#[frame_support::pallet]
pub mod pallet {
+ use frame_support::dispatch::PostDispatchInfo;
+ use frame_support::weights::constants::WEIGHT_PER_SECOND;
use super::*;
use frame_system::pallet_prelude::*;
+ use sp_runtime::traits::Dispatchable;
#[pallet::config]
pub trait Config: frame_system::Config {
-
+ type Event: From> + IsType<::Event>;
+ type AssetModifierOrigin: EnsureOrigin;
+ type Weigher: WeightBounds;
+ type RingCurrency: Currency>;
+ type MoonbeamLocation: Get;
}
#[pallet::event]
- #[pallet::generate_deposit(pub(super) fn deposit_event)]
+ #[pallet::generate_deposit(pub (super) fn deposit_event)]
pub enum Event {
-
+ /// Changed the amount of units target chain charging per execution second for local asset
+ TargetXcmExecConfigChanged {
+ target_location: MultiLocation,
+ local_asset_units_per_second: AssetUnitsPerSecond,
+ },
}
#[pallet::error]
pub enum Error {
-
+ TargetXcmExecNotConfig,
+ WeightCalculationError,
+ InsufficientBalance,
+ AccountIdConversionFailed
}
+ /// Stores the units per second for target chain execution for local asset(e.g. CRAB).
+ /// This is used to know how to charge for XCM execution in local asset.
+ /// For example:
+ /// key: 2023, val: 14719736222326895902025
+ /// represents the units per second of CRAB token on moonriver
+ #[pallet::storage]
+ #[pallet::getter(fn target_xcm_exec_config)]
+ pub type TargetXcmExecConfig =
+ StorageMap<_, Blake2_128Concat, MultiLocation, AssetUnitsPerSecond>;
+
#[pallet::pallet]
- #[pallet::generate_store(pub(super) trait Store)]
+ #[pallet::generate_store(pub (super) trait Store)]
pub struct Pallet(PhantomData);
#[pallet::call]
impl Pallet {
+ #[pallet::weight(T::DbWeight::get().reads_writes(0, 1))]
+ pub fn set_target_xcm_exec_config(
+ origin: OriginFor,
+ target_location: MultiLocation,
+ local_asset_units_per_second: AssetUnitsPerSecond,
+ ) -> DispatchResultWithPostInfo {
+ T::AssetModifierOrigin::ensure_origin(origin)?;
+
+ TargetXcmExecConfig::::insert(&target_location,
+ &local_asset_units_per_second
+ );
+
+ Self::deposit_event(Event::TargetXcmExecConfigChanged {
+ target_location,
+ local_asset_units_per_second,
+ });
+
+ Ok(().into())
+ }
+
+ #[pallet::weight(0)]
+ pub fn forward_to_moonbeam(origin: OriginFor, mut message: Xcm)
+ -> DispatchResultWithPostInfo {
+ let user = ensure_signed(origin)?;
+
+ let local_asset_units_per_second =
+ TargetXcmExecConfig::::get(T::MoonbeamLocation::get())
+ .ok_or(Error::::TargetXcmExecNotConfig)?;
+
+ let mut amount:u128 = 0;
+ let weight = T::Weigher::weight(&mut message)
+ .map_err(|()| Error::::WeightCalculationError)?;
+
+ amount = local_asset_units_per_second.saturating_mul(weight as u128)
+ / (WEIGHT_PER_SECOND as u128);
+
+ // Make sure the user's balance is enough to transfer
+ ensure!(
+ T::RingCurrency::free_balance(&user) > amount,
+ Error::::InsufficientBalance
+ );
+
+ let sovereign_account =
+ SiblingParachainConvertsVia::::convert_ref(T::MoonbeamLocation::get())
+ .map_err(|()| Error::AccountIdConversionFailed)?;
+
+ // We need to transfer XCM execution fee from user to moonbeam sovereign account
+ T::RingCurrency::transfer(
+ &user,
+ &sovereign_account,
+ amount,
+ ExistenceRequirement::KeepAlive,
+ )?;
+ Ok(().into())
+ }
}
}
\ No newline at end of file
From cb615d33db2f54cad0c2094e32a49f266f3d7d5b Mon Sep 17 00:00:00 2001
From: Guantong <04637@163.com>
Date: Wed, 12 Oct 2022 13:31:14 +0800
Subject: [PATCH 03/37] route xcm to moonbeam
---
runtime/common/Cargo.toml | 7 +-
runtime/common/src/message_router/mod.rs | 189 ++++++++++++------
.../src/pallets/message_router.rs | 41 ++++
runtime/pangolin-parachain/src/pallets/mod.rs | 3 +
4 files changed, 180 insertions(+), 60 deletions(-)
create mode 100644 runtime/pangolin-parachain/src/pallets/message_router.rs
diff --git a/runtime/common/Cargo.toml b/runtime/common/Cargo.toml
index d2358195..57213266 100644
--- a/runtime/common/Cargo.toml
+++ b/runtime/common/Cargo.toml
@@ -37,8 +37,11 @@ sp-core = { default-features = false, git = "https://github.c
sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
# polkadot
-xcm = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.27" }
-xcm-executor = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.27" }
+pallet-xcm = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.27" }
+polkadot-parachain = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.27" }
+xcm = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.27" }
+xcm-builder = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.27" }
+xcm-executor = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.27" }
[dev-dependencies]
pallet-timestamp = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
diff --git a/runtime/common/src/message_router/mod.rs b/runtime/common/src/message_router/mod.rs
index c32d8c3b..9f61a4f5 100644
--- a/runtime/common/src/message_router/mod.rs
+++ b/runtime/common/src/message_router/mod.rs
@@ -19,42 +19,42 @@
//! Prototype module for message router.
// --- paritytech ---
-use frame_support::{
- ensure,
- pallet_prelude::*,
- traits::{Currency, ExistenceRequirement, Get, WithdrawReasons},
- weights::GetDispatchInfo,
-};
+use frame_support::{pallet_prelude::*, traits::Get};
pub use pallet::*;
-use polkadot_parachain::primitives::Sibling;
-use xcm::{
- prelude::*
-};
+use xcm::prelude::*;
use xcm_executor::traits::WeightBounds;
-use xcm_builder::FixedWeightBounds;
-use xcm_builder::SiblingParachainConvertsVia;
-use xcm_executor::traits::Convert;
-pub type AccountId = ::AccountId;
-pub type RingBalance = <::RingCurrency as Currency>>::Balance;
-pub type XcmUnitWeightCost = Weight;
pub type AssetUnitsPerSecond = u128;
+pub trait ConvertXcm {
+ fn convert(xcm: Xcm<()>) -> Option>;
+}
+
#[frame_support::pallet]
pub mod pallet {
- use frame_support::dispatch::PostDispatchInfo;
- use frame_support::weights::constants::WEIGHT_PER_SECOND;
use super::*;
+ use frame_support::{log, weights::constants::WEIGHT_PER_SECOND};
use frame_system::pallet_prelude::*;
- use sp_runtime::traits::Dispatchable;
+ use sp_std::{boxed::Box, vec};
+ use xcm_executor::traits::{InvertLocation, TransactAsset};
#[pallet::config]
pub trait Config: frame_system::Config {
type Event: From> + IsType<::Event>;
type AssetModifierOrigin: EnsureOrigin;
- type Weigher: WeightBounds;
- type RingCurrency: Currency>;
+ type MoonbeamWeigher: WeightBounds;
+ type LocalWeigher: WeightBounds;
+ type LocalAssetId: Get;
+ type LocationInverter: InvertLocation;
+ type SelfLocationInSibl: Get;
+ type AssetTransactor: TransactAsset;
type MoonbeamLocation: Get;
+ type ExecuteXcmOrigin: EnsureOrigin<
+ ::Origin,
+ Success = MultiLocation,
+ >;
+ type XcmExecutor: ExecuteXcm;
+ type XcmSender: SendXcm;
}
#[pallet::event]
@@ -65,14 +65,21 @@ pub mod pallet {
target_location: MultiLocation,
local_asset_units_per_second: AssetUnitsPerSecond,
},
+ Route(MultiLocation, Xcm<()>, Weight, u128),
}
#[pallet::error]
pub enum Error {
TargetXcmExecNotConfig,
- WeightCalculationError,
- InsufficientBalance,
- AccountIdConversionFailed
+ /// The message's weight could not be determined.
+ UnweighableMessage,
+ /// XCM execution failed. https://github.com/paritytech/substrate/pull/10242
+ XcmExecutionFailed,
+ BadVersion,
+ /// MultiLocation value too large to descend further.
+ MultiLocationFull,
+ /// Failed to send xcm.
+ XcmSendFailed,
}
/// Stores the units per second for target chain execution for local asset(e.g. CRAB).
@@ -83,7 +90,7 @@ pub mod pallet {
#[pallet::storage]
#[pallet::getter(fn target_xcm_exec_config)]
pub type TargetXcmExecConfig =
- StorageMap<_, Blake2_128Concat, MultiLocation, AssetUnitsPerSecond>;
+ StorageMap<_, Blake2_128Concat, MultiLocation, AssetUnitsPerSecond>;
#[pallet::pallet]
#[pallet::generate_store(pub (super) trait Store)]
@@ -99,9 +106,7 @@ pub mod pallet {
) -> DispatchResultWithPostInfo {
T::AssetModifierOrigin::ensure_origin(origin)?;
- TargetXcmExecConfig::::insert(&target_location,
- &local_asset_units_per_second
- );
+ TargetXcmExecConfig::::insert(&target_location, &local_asset_units_per_second);
Self::deposit_event(Event::TargetXcmExecConfigChanged {
target_location,
@@ -112,40 +117,108 @@ pub mod pallet {
}
#[pallet::weight(0)]
- pub fn forward_to_moonbeam(origin: OriginFor, mut message: Xcm)
- -> DispatchResultWithPostInfo {
- let user = ensure_signed(origin)?;
+ pub fn forward_to_moonbeam(
+ origin: OriginFor,
+ message: Box::Call>>,
+ ) -> DispatchResultWithPostInfo {
+ let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?;
+ let remote_xcm: Xcm<::Call> =
+ (*message).try_into().map_err(|()| Error::::BadVersion)?;
+ // Calculate the execution fee required to execute remote xcm
let local_asset_units_per_second =
TargetXcmExecConfig::::get(T::MoonbeamLocation::get())
- .ok_or(Error::::TargetXcmExecNotConfig)?;
-
- let mut amount:u128 = 0;
- let weight = T::Weigher::weight(&mut message)
- .map_err(|()| Error::::WeightCalculationError)?;
-
- amount = local_asset_units_per_second.saturating_mul(weight as u128)
- / (WEIGHT_PER_SECOND as u128);
-
- // Make sure the user's balance is enough to transfer
- ensure!(
- T::RingCurrency::free_balance(&user) > amount,
- Error::::InsufficientBalance
- );
-
- let sovereign_account =
- SiblingParachainConvertsVia::::convert_ref(T::MoonbeamLocation::get())
- .map_err(|()| Error::AccountIdConversionFailed)?;
-
- // We need to transfer XCM execution fee from user to moonbeam sovereign account
- T::RingCurrency::transfer(
- &user,
- &sovereign_account,
+ .ok_or(Error::::TargetXcmExecNotConfig)?;
+ let remote_weight = T::MoonbeamWeigher::weight(
+ &mut Self::extend_remote_xcm_for_weight(remote_xcm.clone()),
+ )
+ .map_err(|()| Error::::UnweighableMessage)?;
+ let amount = local_asset_units_per_second.saturating_mul(remote_weight as u128)
+ / (WEIGHT_PER_SECOND as u128);
+ let remote_xcm_fee =
+ MultiAsset { id: AssetId::from(T::LocalAssetId::get()), fun: Fungible(amount) };
+
+ // Transfer xcm execution fee to moonbeam sovereign account
+ let mut local_xcm = Xcm(vec![TransferAsset {
+ assets: remote_xcm_fee.clone().into(),
+ beneficiary: T::MoonbeamLocation::get(),
+ }]);
+ let local_weight = T::LocalWeigher::weight(&mut local_xcm)
+ .map_err(|()| Error::::UnweighableMessage)?;
+ T::XcmExecutor::execute_xcm_in_credit(
+ origin_location.clone(),
+ local_xcm,
+ local_weight,
+ local_weight,
+ )
+ .ensure_complete()
+ .map_err(|error| {
+ log::error!("Failed execute route message with {:?}", error);
+ Error::::XcmExecutionFailed
+ })?;
+
+ // Extend remote xcm to buy execution and handle error remotely
+ let ancestry = T::LocationInverter::ancestry();
+ let mut remote_xcm_fee_anchor_dest = remote_xcm_fee.clone();
+ remote_xcm_fee_anchor_dest
+ .reanchor(&T::MoonbeamLocation::get(), &ancestry)
+ .map_err(|()| Error::::MultiLocationFull)?;
+ let mut extend_remote_xcm = Xcm(vec![
+ ReserveAssetDeposited(remote_xcm_fee_anchor_dest.clone().into()),
+ BuyExecution {
+ fees: remote_xcm_fee_anchor_dest,
+ weight_limit: WeightLimit::Unlimited,
+ },
+ SetAppendix(Xcm(vec![
+ RefundSurplus,
+ DepositAsset {
+ assets: Wild(All),
+ max_assets: 1,
+ beneficiary: T::SelfLocationInSibl::get(),
+ },
+ ])),
+ ]);
+ extend_remote_xcm.0.extend(remote_xcm.0.into_iter());
+
+ // Send remote xcm to moonbeam
+ T::XcmSender::send_xcm(T::MoonbeamLocation::get(), extend_remote_xcm.clone().into())
+ .map_err(|_| Error::::XcmSendFailed)?;
+
+ Self::deposit_event(Event::Route(
+ origin_location,
+ extend_remote_xcm.into(),
+ remote_weight,
amount,
- ExistenceRequirement::KeepAlive,
- )?;
-
+ ));
Ok(().into())
}
}
-}
\ No newline at end of file
+
+ impl Pallet {
+ /// Extend xcm to make weight calculation more accurate.
+ /// These extended instructions are the instructions that will be executed remotely
+ fn extend_remote_xcm_for_weight(
+ xcm: Xcm<::Call>,
+ ) -> Xcm<::Call> {
+ let mut extend_xcm_for_weight = Xcm(vec![
+ ReserveAssetDeposited(
+ MultiAsset { id: Concrete(T::LocalAssetId::get()), fun: Fungible(0) }.into(),
+ ),
+ BuyExecution {
+ fees: MultiAsset { id: Concrete(T::LocalAssetId::get()), fun: Fungible(0) },
+ weight_limit: WeightLimit::Unlimited,
+ },
+ SetAppendix(Xcm(vec![
+ RefundSurplus,
+ DepositAsset {
+ assets: Wild(All),
+ max_assets: 1,
+ beneficiary: Default::default(),
+ },
+ ])),
+ ]);
+ extend_xcm_for_weight.0.extend(xcm.0.into_iter());
+ return extend_xcm_for_weight;
+ }
+ }
+}
diff --git a/runtime/pangolin-parachain/src/pallets/message_router.rs b/runtime/pangolin-parachain/src/pallets/message_router.rs
new file mode 100644
index 00000000..a837bc6c
--- /dev/null
+++ b/runtime/pangolin-parachain/src/pallets/message_router.rs
@@ -0,0 +1,41 @@
+// --- paritytech ---
+use frame_support::{traits::PalletInfoAccess, weights::Weight};
+use frame_system::EnsureRoot;
+use xcm::prelude::*;
+use xcm_builder::{EnsureXcmOrigin, FixedWeightBounds, LocationInverter};
+use xcm_executor::XcmExecutor;
+// --- darwinia-network ---
+use crate::*;
+use dp_common_runtime::message_router::Config;
+
+frame_support::parameter_types! {
+ pub const MoonbeamMaxInstructions: u32 = 100;
+ pub MoonbeamUnitWeightCost: Weight = 100_000_000;
+ pub SelfLocationInSibl: MultiLocation = MultiLocation::new(
+ 1,
+ X1(Parachain(ParachainInfo::parachain_id().into()))
+ );
+ pub AnchoringSelfReserve: MultiLocation = MultiLocation::new(
+ 0,
+ X1(PalletInstance(::index() as u8))
+ );
+ pub MoonbeamLocation: MultiLocation = MultiLocation::new(
+ 1,
+ X1(Parachain(1000))
+ );
+}
+
+impl Config for Runtime {
+ type Event = Event;
+ type AssetModifierOrigin = EnsureRoot;
+ type MoonbeamWeigher = FixedWeightBounds;
+ type LocalWeigher = FixedWeightBounds;
+ type LocalAssetId = AnchoringSelfReserve;
+ type LocationInverter = LocationInverter;
+ type SelfLocationInSibl = SelfLocationInSibl;
+ type AssetTransactor = LocalAssetTransactor;
+ type MoonbeamLocation = MoonbeamLocation;
+ type ExecuteXcmOrigin = EnsureXcmOrigin;
+ type XcmExecutor = XcmExecutor;
+ type XcmSender = XcmRouter;
+}
diff --git a/runtime/pangolin-parachain/src/pallets/mod.rs b/runtime/pangolin-parachain/src/pallets/mod.rs
index bd358b83..69d5aeba 100644
--- a/runtime/pangolin-parachain/src/pallets/mod.rs
+++ b/runtime/pangolin-parachain/src/pallets/mod.rs
@@ -72,3 +72,6 @@ pub use fee_market::*;
pub mod helixbridge;
pub use helixbridge::*;
+
+pub mod message_router;
+pub use message_router::*;
From b1d54dd2b679c50c3e569f236b106bcc58be4b6e Mon Sep 17 00:00:00 2001
From: Guantong <04637@163.com>
Date: Wed, 24 Aug 2022 23:49:39 +0800
Subject: [PATCH 04/37] Add message router for pangolin-parachain
---
runtime/pangolin-parachain/src/lib.rs | 2 ++
1 file changed, 2 insertions(+)
diff --git a/runtime/pangolin-parachain/src/lib.rs b/runtime/pangolin-parachain/src/lib.rs
index 0ec51038..80b5386d 100644
--- a/runtime/pangolin-parachain/src/lib.rs
+++ b/runtime/pangolin-parachain/src/lib.rs
@@ -188,6 +188,8 @@ frame_support::construct_runtime! {
PangolinFeeMarket: pallet_fee_market::::{Pallet, Call, Storage, Event} = 23,
FromPangolinIssuing: dp_common_runtime::helixbridge::{Pallet, Call, Storage, Event} = 24,
+
+ MessageRouter: dp_common_runtime::message_router::{Pallet, Call, Storage, Event} = 26,
}
}
From 6e77a49375ae9345ceaeaa766e8a87f6e81ef04a Mon Sep 17 00:00:00 2001
From: Guantong <04637@163.com>
Date: Thu, 25 Aug 2022 10:51:00 +0800
Subject: [PATCH 05/37] extend remote xcm
---
runtime/common/src/message_router/mod.rs | 53 ++++++-------------
.../src/pallets/message_router.rs | 12 ++---
2 files changed, 23 insertions(+), 42 deletions(-)
diff --git a/runtime/common/src/message_router/mod.rs b/runtime/common/src/message_router/mod.rs
index 9f61a4f5..6fd98562 100644
--- a/runtime/common/src/message_router/mod.rs
+++ b/runtime/common/src/message_router/mod.rs
@@ -129,9 +129,10 @@ pub mod pallet {
let local_asset_units_per_second =
TargetXcmExecConfig::::get(T::MoonbeamLocation::get())
.ok_or(Error::::TargetXcmExecNotConfig)?;
- let remote_weight = T::MoonbeamWeigher::weight(
- &mut Self::extend_remote_xcm_for_weight(remote_xcm.clone()),
- )
+ let remote_weight = T::MoonbeamWeigher::weight(&mut Self::extend_remote_xcm(
+ remote_xcm.clone(),
+ MultiAsset { id: AssetId::from(T::LocalAssetId::get()), fun: Fungible(0) },
+ ))
.map_err(|()| Error::::UnweighableMessage)?;
let amount = local_asset_units_per_second.saturating_mul(remote_weight as u128)
/ (WEIGHT_PER_SECOND as u128);
@@ -157,36 +158,21 @@ pub mod pallet {
Error::::XcmExecutionFailed
})?;
- // Extend remote xcm to buy execution and handle error remotely
+ // Toggle the xcm_fee relative to a target context
let ancestry = T::LocationInverter::ancestry();
let mut remote_xcm_fee_anchor_dest = remote_xcm_fee.clone();
remote_xcm_fee_anchor_dest
.reanchor(&T::MoonbeamLocation::get(), &ancestry)
.map_err(|()| Error::::MultiLocationFull)?;
- let mut extend_remote_xcm = Xcm(vec![
- ReserveAssetDeposited(remote_xcm_fee_anchor_dest.clone().into()),
- BuyExecution {
- fees: remote_xcm_fee_anchor_dest,
- weight_limit: WeightLimit::Unlimited,
- },
- SetAppendix(Xcm(vec![
- RefundSurplus,
- DepositAsset {
- assets: Wild(All),
- max_assets: 1,
- beneficiary: T::SelfLocationInSibl::get(),
- },
- ])),
- ]);
- extend_remote_xcm.0.extend(remote_xcm.0.into_iter());
+ let remote_xcm = Self::extend_remote_xcm(remote_xcm, remote_xcm_fee_anchor_dest);
// Send remote xcm to moonbeam
- T::XcmSender::send_xcm(T::MoonbeamLocation::get(), extend_remote_xcm.clone().into())
+ T::XcmSender::send_xcm(T::MoonbeamLocation::get(), remote_xcm.clone().into())
.map_err(|_| Error::::XcmSendFailed)?;
Self::deposit_event(Event::Route(
origin_location,
- extend_remote_xcm.into(),
+ remote_xcm.into(),
remote_weight,
amount,
));
@@ -195,30 +181,25 @@ pub mod pallet {
}
impl Pallet {
- /// Extend xcm to make weight calculation more accurate.
- /// These extended instructions are the instructions that will be executed remotely
- fn extend_remote_xcm_for_weight(
+ /// Extend xcm to pay for remote execution
+ fn extend_remote_xcm(
xcm: Xcm<::Call>,
+ fee: MultiAsset,
) -> Xcm<::Call> {
- let mut extend_xcm_for_weight = Xcm(vec![
- ReserveAssetDeposited(
- MultiAsset { id: Concrete(T::LocalAssetId::get()), fun: Fungible(0) }.into(),
- ),
- BuyExecution {
- fees: MultiAsset { id: Concrete(T::LocalAssetId::get()), fun: Fungible(0) },
- weight_limit: WeightLimit::Unlimited,
- },
+ let mut extend_xcm = Xcm(vec![
+ ReserveAssetDeposited(fee.clone().into()),
+ BuyExecution { fees: fee, weight_limit: WeightLimit::Unlimited },
SetAppendix(Xcm(vec![
RefundSurplus,
DepositAsset {
assets: Wild(All),
max_assets: 1,
- beneficiary: Default::default(),
+ beneficiary: T::SelfLocationInSibl::get(),
},
])),
]);
- extend_xcm_for_weight.0.extend(xcm.0.into_iter());
- return extend_xcm_for_weight;
+ extend_xcm.0.extend(xcm.0.into_iter());
+ return extend_xcm;
}
}
}
diff --git a/runtime/pangolin-parachain/src/pallets/message_router.rs b/runtime/pangolin-parachain/src/pallets/message_router.rs
index a837bc6c..db93a88c 100644
--- a/runtime/pangolin-parachain/src/pallets/message_router.rs
+++ b/runtime/pangolin-parachain/src/pallets/message_router.rs
@@ -26,16 +26,16 @@ frame_support::parameter_types! {
}
impl Config for Runtime {
- type Event = Event;
type AssetModifierOrigin = EnsureRoot;
- type MoonbeamWeigher = FixedWeightBounds;
- type LocalWeigher = FixedWeightBounds;
+ type AssetTransactor = LocalAssetTransactor;
+ type Event = Event;
+ type ExecuteXcmOrigin = EnsureXcmOrigin;
type LocalAssetId = AnchoringSelfReserve;
+ type LocalWeigher = FixedWeightBounds;
type LocationInverter = LocationInverter;
- type SelfLocationInSibl = SelfLocationInSibl;
- type AssetTransactor = LocalAssetTransactor;
type MoonbeamLocation = MoonbeamLocation;
- type ExecuteXcmOrigin = EnsureXcmOrigin;
+ type MoonbeamWeigher = FixedWeightBounds;
+ type SelfLocationInSibl = SelfLocationInSibl;
type XcmExecutor = XcmExecutor;
type XcmSender = XcmRouter;
}
From 7f8eaaeb0361d1f8ff0fae55f56937eec514fef5 Mon Sep 17 00:00:00 2001
From: Guantong <04637@163.com>
Date: Mon, 29 Aug 2022 15:22:12 +0800
Subject: [PATCH 06/37] format
---
runtime/common/src/message_router/mod.rs | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/runtime/common/src/message_router/mod.rs b/runtime/common/src/message_router/mod.rs
index 6fd98562..1b6bf5bd 100644
--- a/runtime/common/src/message_router/mod.rs
+++ b/runtime/common/src/message_router/mod.rs
@@ -26,10 +26,6 @@ use xcm_executor::traits::WeightBounds;
pub type AssetUnitsPerSecond = u128;
-pub trait ConvertXcm {
- fn convert(xcm: Xcm<()>) -> Option>;
-}
-
#[frame_support::pallet]
pub mod pallet {
use super::*;
@@ -65,7 +61,7 @@ pub mod pallet {
target_location: MultiLocation,
local_asset_units_per_second: AssetUnitsPerSecond,
},
- Route(MultiLocation, Xcm<()>, Weight, u128),
+ RouteToMoonbeam(MultiLocation, Xcm<()>, Weight, u128),
}
#[pallet::error]
@@ -82,10 +78,10 @@ pub mod pallet {
XcmSendFailed,
}
- /// Stores the units per second for target chain execution for local asset(e.g. CRAB).
+ /// Stores the units per second executed by the target chain for local asset(e.g. CRAB).
/// This is used to know how to charge for XCM execution in local asset.
/// For example:
- /// key: 2023, val: 14719736222326895902025
+ /// key: {parents: 1, Parachain(2023)}, val: 14719736222326895902025
/// represents the units per second of CRAB token on moonriver
#[pallet::storage]
#[pallet::getter(fn target_xcm_exec_config)]
@@ -170,7 +166,7 @@ pub mod pallet {
T::XcmSender::send_xcm(T::MoonbeamLocation::get(), remote_xcm.clone().into())
.map_err(|_| Error::::XcmSendFailed)?;
- Self::deposit_event(Event::Route(
+ Self::deposit_event(Event::RouteToMoonbeam(
origin_location,
remote_xcm.into(),
remote_weight,
From 28744dedfd97383979c50f8515e2d0ad7e37ed87 Mon Sep 17 00:00:00 2001
From: Guantong <04637@163.com>
Date: Tue, 30 Aug 2022 13:48:21 +0800
Subject: [PATCH 07/37] update weight for message router
---
.../common/src/message_router/benchmarking.rs | 51 +++++++++
runtime/common/src/message_router/mod.rs | 17 ++-
runtime/common/src/message_router/weights.rs | 102 ++++++++++++++++++
.../src/pallets/message_router.rs | 1 +
4 files changed, 168 insertions(+), 3 deletions(-)
create mode 100644 runtime/common/src/message_router/benchmarking.rs
create mode 100644 runtime/common/src/message_router/weights.rs
diff --git a/runtime/common/src/message_router/benchmarking.rs b/runtime/common/src/message_router/benchmarking.rs
new file mode 100644
index 00000000..20ea9eb2
--- /dev/null
+++ b/runtime/common/src/message_router/benchmarking.rs
@@ -0,0 +1,51 @@
+// This file is part of Darwinia.
+//
+// Copyright (C) 2018-2022 Darwinia Network
+// SPDX-License-Identifier: GPL-3.0
+//
+// Darwinia 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.
+//
+// Darwinia 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 Darwinia. If not, see .
+
+#![cfg(feature = "runtime-benchmarks")]
+
+// --- paritytech ---
+use frame_benchmarking::{account, benchmarks};
+use frame_support::{assert_ok, traits::Get};
+use frame_system::RawOrigin;
+use sp_std::{boxed::Box, vec};
+use xcm::{latest::prelude::*, VersionedXcm::V2};
+// --- darwinia ---
+use crate::message_router::{Call, Config, Pallet};
+use dc_primitives::COIN;
+
+benchmarks! {
+ set_target_xcm_exec_config {
+ let target_location = T::MoonbeamLocation::get();
+ let local_asset_units_per_second: u128 = 14719736222326895902025_u128;
+ }:_(RawOrigin::Root, target_location.clone(), local_asset_units_per_second)
+ verify {
+ assert_eq!(Pallet::::target_xcm_exec_config(target_location), Some(local_asset_units_per_second));
+ }
+
+ forward_to_moonbeam {
+ let target_location = T::MoonbeamLocation::get();
+ let local_asset_units_per_second: u128 = 14719736222326895902025_u128;
+ assert_ok!(Pallet::::set_target_xcm_exec_config(RawOrigin::Root.into(), target_location.clone(), local_asset_units_per_second));
+ let xcm = Xcm(vec![
+ DescendOrigin(X1(AccountKey20 {
+ network: Any,
+ key: [0u8;20].into()
+ })),
+ ]);
+ }:_(RawOrigin::Root, Box::new(V2(xcm)))
+}
diff --git a/runtime/common/src/message_router/mod.rs b/runtime/common/src/message_router/mod.rs
index 1b6bf5bd..bccd16c6 100644
--- a/runtime/common/src/message_router/mod.rs
+++ b/runtime/common/src/message_router/mod.rs
@@ -18,9 +18,12 @@
//! Prototype module for message router.
+#[cfg(feature = "runtime-benchmarks")]
+mod benchmarking;
+mod weights;
+
// --- paritytech ---
use frame_support::{pallet_prelude::*, traits::Get};
-pub use pallet::*;
use xcm::prelude::*;
use xcm_executor::traits::WeightBounds;
@@ -33,6 +36,7 @@ pub mod pallet {
use frame_system::pallet_prelude::*;
use sp_std::{boxed::Box, vec};
use xcm_executor::traits::{InvertLocation, TransactAsset};
+ use crate::message_router::weights::WeightInfo;
#[pallet::config]
pub trait Config: frame_system::Config {
@@ -51,6 +55,7 @@ pub mod pallet {
>;
type XcmExecutor: ExecuteXcm;
type XcmSender: SendXcm;
+ type WeightInfo: WeightInfo;
}
#[pallet::event]
@@ -94,7 +99,9 @@ pub mod pallet {
#[pallet::call]
impl Pallet {
- #[pallet::weight(T::DbWeight::get().reads_writes(0, 1))]
+ #[pallet::weight(
+ ::WeightInfo::set_target_xcm_exec_config()
+ )]
pub fn set_target_xcm_exec_config(
origin: OriginFor,
target_location: MultiLocation,
@@ -112,7 +119,9 @@ pub mod pallet {
Ok(().into())
}
- #[pallet::weight(0)]
+ #[pallet::weight(
+ ::WeightInfo::forward_to_moonbeam()
+ )]
pub fn forward_to_moonbeam(
origin: OriginFor,
message: Box::Call>>,
@@ -199,3 +208,5 @@ pub mod pallet {
}
}
}
+
+pub use pallet::*;
diff --git a/runtime/common/src/message_router/weights.rs b/runtime/common/src/message_router/weights.rs
new file mode 100644
index 00000000..2b8444fa
--- /dev/null
+++ b/runtime/common/src/message_router/weights.rs
@@ -0,0 +1,102 @@
+// This file is part of Darwinia.
+//
+// Copyright (C) 2018-2022 Darwinia Network
+// SPDX-License-Identifier: GPL-3.0
+//
+// Darwinia 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.
+//
+// Darwinia 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 Darwinia. If not, see .
+
+//! Autogenerated weights for `message_router`
+//!
+//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
+//! DATE: 2022-08-29, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]`
+//! HOSTNAME: `Debian`, CPU: `12th Gen Intel(R) Core(TM) i9-12900K`
+//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("pangolin-parachain-dev"), DB CACHE: 1024
+
+// Executed Command:
+// ./target/release/darwinia-parachain
+// benchmark
+// pallet
+// --chain
+// pangolin-parachain-dev
+// --execution
+// wasm
+// --wasm-execution
+// compiled
+// --pallet
+// message_router
+// --extrinsic
+// *
+// --steps
+// 50
+// --repeat
+// 20
+// --heap-pages=4096
+// --output
+// ./runtime/pangolin-parachain/src/weights/
+// --header=.maintain/lincense-header
+
+#![cfg_attr(rustfmt, rustfmt_skip)]
+#![allow(unused_parens)]
+#![allow(unused_imports)]
+
+use frame_support::{traits::Get, weights::Weight};
+use frame_support::weights::constants::RocksDbWeight;
+use sp_std::marker::PhantomData;
+
+pub trait WeightInfo {
+ fn set_target_xcm_exec_config() -> Weight;
+ fn forward_to_moonbeam() -> Weight;
+}
+
+/// Weight functions for `message_router`.
+pub struct SubstrateWeightInfo(PhantomData);
+impl WeightInfo for SubstrateWeightInfo {
+ // Storage: MessageRouter TargetXcmExecConfig (r:0 w:1)
+ fn set_target_xcm_exec_config() -> Weight {
+ (10_337_000 as Weight)
+ .saturating_add(T::DbWeight::get().writes(1 as Weight))
+ }
+ // Storage: MessageRouter TargetXcmExecConfig (r:1 w:0)
+ // Storage: ParachainInfo ParachainId (r:1 w:0)
+ // Storage: System Account (r:2 w:0)
+ // Storage: PolkadotXcm SupportedVersion (r:1 w:0)
+ // Storage: PolkadotXcm VersionDiscoveryQueue (r:1 w:1)
+ // Storage: PolkadotXcm SafeXcmVersion (r:1 w:0)
+ // Storage: ParachainSystem RelevantMessagingState (r:1 w:0)
+ fn forward_to_moonbeam() -> Weight {
+ (37_239_000 as Weight)
+ .saturating_add(T::DbWeight::get().reads(8 as Weight))
+ .saturating_add(T::DbWeight::get().writes(1 as Weight))
+ }
+}
+
+impl WeightInfo for () {
+ // Storage: MessageRouter TargetXcmExecConfig (r:0 w:1)
+ fn set_target_xcm_exec_config() -> Weight {
+ (10_337_000 as Weight)
+ .saturating_add(RocksDbWeight::get().writes(1 as Weight))
+ }
+ // Storage: MessageRouter TargetXcmExecConfig (r:1 w:0)
+ // Storage: ParachainInfo ParachainId (r:1 w:0)
+ // Storage: System Account (r:2 w:0)
+ // Storage: PolkadotXcm SupportedVersion (r:1 w:0)
+ // Storage: PolkadotXcm VersionDiscoveryQueue (r:1 w:1)
+ // Storage: PolkadotXcm SafeXcmVersion (r:1 w:0)
+ // Storage: ParachainSystem RelevantMessagingState (r:1 w:0)
+ fn forward_to_moonbeam() -> Weight {
+ (37_239_000 as Weight)
+ .saturating_add(RocksDbWeight::get().reads(8 as Weight))
+ .saturating_add(RocksDbWeight::get().writes(1 as Weight))
+ }
+}
\ No newline at end of file
diff --git a/runtime/pangolin-parachain/src/pallets/message_router.rs b/runtime/pangolin-parachain/src/pallets/message_router.rs
index db93a88c..bc1d24b1 100644
--- a/runtime/pangolin-parachain/src/pallets/message_router.rs
+++ b/runtime/pangolin-parachain/src/pallets/message_router.rs
@@ -36,6 +36,7 @@ impl Config for Runtime {
type MoonbeamLocation = MoonbeamLocation;
type MoonbeamWeigher = FixedWeightBounds;
type SelfLocationInSibl = SelfLocationInSibl;
+ type WeightInfo = ();
type XcmExecutor = XcmExecutor;
type XcmSender = XcmRouter;
}
From 52b1a497aac3b98906f9cbfe845073bd5284faad Mon Sep 17 00:00:00 2001
From: Guantong <04637@163.com>
Date: Tue, 30 Aug 2022 13:51:22 +0800
Subject: [PATCH 08/37] format
---
runtime/common/src/message_router/mod.rs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/runtime/common/src/message_router/mod.rs b/runtime/common/src/message_router/mod.rs
index bccd16c6..292dafe8 100644
--- a/runtime/common/src/message_router/mod.rs
+++ b/runtime/common/src/message_router/mod.rs
@@ -32,11 +32,11 @@ pub type AssetUnitsPerSecond = u128;
#[frame_support::pallet]
pub mod pallet {
use super::*;
+ use crate::message_router::weights::WeightInfo;
use frame_support::{log, weights::constants::WEIGHT_PER_SECOND};
use frame_system::pallet_prelude::*;
use sp_std::{boxed::Box, vec};
use xcm_executor::traits::{InvertLocation, TransactAsset};
- use crate::message_router::weights::WeightInfo;
#[pallet::config]
pub trait Config: frame_system::Config {
From 02ca1294987c9681303cdc2b35e488c0efad744b Mon Sep 17 00:00:00 2001
From: Guantong <04637@163.com>
Date: Tue, 30 Aug 2022 17:45:07 +0800
Subject: [PATCH 09/37] extend DescendOrigin for remote xcm
---
runtime/common/src/message_router/mod.rs | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/runtime/common/src/message_router/mod.rs b/runtime/common/src/message_router/mod.rs
index 292dafe8..b7704e31 100644
--- a/runtime/common/src/message_router/mod.rs
+++ b/runtime/common/src/message_router/mod.rs
@@ -81,6 +81,7 @@ pub mod pallet {
MultiLocationFull,
/// Failed to send xcm.
XcmSendFailed,
+ AccountIdConversionFailed,
}
/// Stores the units per second executed by the target chain for local asset(e.g. CRAB).
@@ -126,7 +127,11 @@ pub mod pallet {
origin: OriginFor,
message: Box::Call>>,
) -> DispatchResultWithPostInfo {
- let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?;
+ let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin.clone())?;
+ let account_id = ensure_signed(origin)?;
+ let account_u8 = <[u8; 32]>::try_from(account_id.encode())
+ .map_err(|_| Error::::AccountIdConversionFailed)?;
+
let remote_xcm: Xcm<::Call> =
(*message).try_into().map_err(|()| Error::::BadVersion)?;
@@ -135,6 +140,7 @@ pub mod pallet {
TargetXcmExecConfig::::get(T::MoonbeamLocation::get())
.ok_or(Error::::TargetXcmExecNotConfig)?;
let remote_weight = T::MoonbeamWeigher::weight(&mut Self::extend_remote_xcm(
+ account_u8.clone(),
remote_xcm.clone(),
MultiAsset { id: AssetId::from(T::LocalAssetId::get()), fun: Fungible(0) },
))
@@ -169,7 +175,8 @@ pub mod pallet {
remote_xcm_fee_anchor_dest
.reanchor(&T::MoonbeamLocation::get(), &ancestry)
.map_err(|()| Error::::MultiLocationFull)?;
- let remote_xcm = Self::extend_remote_xcm(remote_xcm, remote_xcm_fee_anchor_dest);
+ let remote_xcm =
+ Self::extend_remote_xcm(account_u8, remote_xcm, remote_xcm_fee_anchor_dest);
// Send remote xcm to moonbeam
T::XcmSender::send_xcm(T::MoonbeamLocation::get(), remote_xcm.clone().into())
@@ -188,6 +195,7 @@ pub mod pallet {
impl Pallet {
/// Extend xcm to pay for remote execution
fn extend_remote_xcm(
+ account_u8: [u8; 32],
xcm: Xcm<::Call>,
fee: MultiAsset,
) -> Xcm<::Call> {
@@ -202,6 +210,7 @@ pub mod pallet {
beneficiary: T::SelfLocationInSibl::get(),
},
])),
+ DescendOrigin(X1(AccountId32 { network: NetworkId::Any, id: account_u8 })),
]);
extend_xcm.0.extend(xcm.0.into_iter());
return extend_xcm;
From 88860204f86bc56e592ad870bf36fc9a7698981f Mon Sep 17 00:00:00 2001
From: Guantong <04637@163.com>
Date: Wed, 12 Oct 2022 13:33:02 +0800
Subject: [PATCH 10/37] Add parachain & relay chain runtime mock
Conflicts:
Cargo.lock
runtime/common/Cargo.toml
---
runtime/common/Cargo.toml | 18 +-
runtime/common/src/message_router/mock/mod.rs | 103 ++++++
.../src/message_router/mock/parachain.rs | 331 ++++++++++++++++++
.../src/message_router/mock/relay_chain.rs | 195 +++++++++++
runtime/common/src/message_router/mod.rs | 4 +
runtime/common/src/message_router/test.rs | 21 ++
6 files changed, 667 insertions(+), 5 deletions(-)
create mode 100644 runtime/common/src/message_router/mock/mod.rs
create mode 100644 runtime/common/src/message_router/mock/parachain.rs
create mode 100644 runtime/common/src/message_router/mock/relay_chain.rs
create mode 100644 runtime/common/src/message_router/test.rs
diff --git a/runtime/common/Cargo.toml b/runtime/common/Cargo.toml
index 57213266..72b0ec66 100644
--- a/runtime/common/Cargo.toml
+++ b/runtime/common/Cargo.toml
@@ -37,11 +37,14 @@ sp-core = { default-features = false, git = "https://github.c
sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
# polkadot
-pallet-xcm = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.27" }
-polkadot-parachain = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.27" }
-xcm = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.27" }
-xcm-builder = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.27" }
-xcm-executor = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.27" }
+pallet-xcm = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.27" }
+polkadot-core-primitives = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.27" }
+polkadot-parachain = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.27" }
+polkadot-runtime-parachains = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.27" }
+xcm = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.27" }
+xcm-builder = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.27" }
+xcm-executor = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.27" }
+xcm-simulator = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.27" }
[dev-dependencies]
pallet-timestamp = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
@@ -76,7 +79,12 @@ std = [
"sp-runtime/std",
"sp-std/std",
# polkadot
+ "pallet-xcm/std",
+ "polkadot-core-primitives/std",
+ "polkadot-parachain/std",
+ "polkadot-runtime-parachains/std",
"xcm/std",
+ "xcm-builder/std",
"xcm-executor/std",
]
diff --git a/runtime/common/src/message_router/mock/mod.rs b/runtime/common/src/message_router/mock/mod.rs
new file mode 100644
index 00000000..d4705694
--- /dev/null
+++ b/runtime/common/src/message_router/mock/mod.rs
@@ -0,0 +1,103 @@
+// This file is part of Darwinia.
+//
+// Copyright (C) 2018-2022 Darwinia Network
+// SPDX-License-Identifier: GPL-3.0
+//
+// Darwinia 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.
+//
+// Darwinia 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 Darwinia. If not, see .
+
+mod parachain;
+mod relay_chain;
+
+use polkadot_parachain::primitives::Id as ParaId;
+use sp_runtime::traits::AccountIdConversion;
+use xcm_simulator::{decl_test_network, decl_test_parachain, decl_test_relay_chain};
+
+pub const ALICE: sp_runtime::AccountId32 = sp_runtime::AccountId32::new([0u8; 32]);
+pub const INITIAL_BALANCE: u128 = 1_000_000_000;
+
+decl_test_parachain! {
+ pub struct ParaA {
+ Runtime = parachain::Runtime,
+ XcmpMessageHandler = parachain::MsgQueue,
+ DmpMessageHandler = parachain::MsgQueue,
+ new_ext = para_ext(1),
+ }
+}
+
+decl_test_parachain! {
+ pub struct ParaB {
+ Runtime = parachain::Runtime,
+ XcmpMessageHandler = parachain::MsgQueue,
+ DmpMessageHandler = parachain::MsgQueue,
+ new_ext = para_ext(2),
+ }
+}
+
+decl_test_relay_chain! {
+ pub struct Relay {
+ Runtime = relay_chain::Runtime,
+ XcmConfig = relay_chain::XcmConfig,
+ new_ext = relay_ext(),
+ }
+}
+
+decl_test_network! {
+ pub struct MockNet {
+ relay_chain = Relay,
+ parachains = vec![
+ (1, ParaA),
+ (2, ParaB),
+ ],
+ }
+}
+
+pub fn para_account_id(id: u32) -> relay_chain::AccountId {
+ ParaId::from(id).into_account_truncating()
+}
+
+pub fn para_ext(para_id: u32) -> sp_io::TestExternalities {
+ use parachain::{MsgQueue, Runtime, System};
+
+ let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap();
+
+ pallet_balances::GenesisConfig:: { balances: vec![(ALICE, INITIAL_BALANCE)] }
+ .assimilate_storage(&mut t)
+ .unwrap();
+
+ let mut ext = sp_io::TestExternalities::new(t);
+ ext.execute_with(|| {
+ System::set_block_number(1);
+ MsgQueue::set_para_id(para_id.into());
+ });
+ ext
+}
+
+pub fn relay_ext() -> sp_io::TestExternalities {
+ use relay_chain::{Runtime, System};
+
+ let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap();
+
+ pallet_balances::GenesisConfig:: {
+ balances: vec![(ALICE, INITIAL_BALANCE), (para_account_id(1), INITIAL_BALANCE)],
+ }
+ .assimilate_storage(&mut t)
+ .unwrap();
+
+ let mut ext = sp_io::TestExternalities::new(t);
+ ext.execute_with(|| System::set_block_number(1));
+ ext
+}
+
+pub type RelayChainPalletXcm = pallet_xcm::Pallet;
+pub type ParachainPalletXcm = pallet_xcm::Pallet;
diff --git a/runtime/common/src/message_router/mock/parachain.rs b/runtime/common/src/message_router/mock/parachain.rs
new file mode 100644
index 00000000..34551f5c
--- /dev/null
+++ b/runtime/common/src/message_router/mock/parachain.rs
@@ -0,0 +1,331 @@
+// This file is part of Darwinia.
+//
+// Copyright (C) 2018-2022 Darwinia Network
+// SPDX-License-Identifier: GPL-3.0
+//
+// Darwinia 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.
+//
+// Darwinia 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 Darwinia. If not, see .
+
+//! Parachain runtime mock.
+
+use codec::{Decode, Encode};
+use frame_support::{
+ construct_runtime, parameter_types,
+ traits::{Everything, Nothing},
+ weights::{constants::WEIGHT_PER_SECOND, Weight},
+};
+use sp_core::H256;
+use sp_runtime::{
+ testing::Header,
+ traits::{Hash, IdentityLookup},
+ AccountId32,
+};
+use sp_std::prelude::*;
+
+use pallet_xcm::XcmPassthrough;
+use polkadot_core_primitives::BlockNumber as RelayBlockNumber;
+use polkadot_parachain::primitives::{
+ DmpMessageHandler, Id as ParaId, Sibling, XcmpMessageFormat, XcmpMessageHandler,
+};
+use xcm::{latest::prelude::*, VersionedXcm};
+use xcm_builder::{
+ AccountId32Aliases, AllowUnpaidExecutionFrom, CurrencyAdapter as XcmCurrencyAdapter,
+ EnsureXcmOrigin, FixedRateOfFungible, FixedWeightBounds, IsConcrete, LocationInverter,
+ NativeAsset, ParentIsPreset, SiblingParachainConvertsVia, SignedAccountId32AsNative,
+ SignedToAccountId32, SovereignSignedViaLocation,
+};
+use xcm_executor::{Config, XcmExecutor};
+
+pub type AccountId = AccountId32;
+pub type Balance = u128;
+
+parameter_types! {
+ pub const BlockHashCount: u64 = 250;
+}
+
+impl frame_system::Config for Runtime {
+ type Origin = Origin;
+ type Call = Call;
+ type Index = u64;
+ type BlockNumber = u64;
+ type Hash = H256;
+ type Hashing = ::sp_runtime::traits::BlakeTwo256;
+ type AccountId = AccountId;
+ type Lookup = IdentityLookup;
+ type Header = Header;
+ type Event = Event;
+ type BlockHashCount = BlockHashCount;
+ type BlockWeights = ();
+ type BlockLength = ();
+ type Version = ();
+ type PalletInfo = PalletInfo;
+ type AccountData = pallet_balances::AccountData;
+ type OnNewAccount = ();
+ type OnKilledAccount = ();
+ type DbWeight = ();
+ type BaseCallFilter = Everything;
+ type SystemWeightInfo = ();
+ type SS58Prefix = ();
+ type OnSetCode = ();
+ type MaxConsumers = frame_support::traits::ConstU32<16>;
+}
+
+parameter_types! {
+ pub ExistentialDeposit: Balance = 1;
+ pub const MaxLocks: u32 = 50;
+ pub const MaxReserves: u32 = 50;
+}
+
+impl pallet_balances::Config for Runtime {
+ type MaxLocks = MaxLocks;
+ type Balance = Balance;
+ type Event = Event;
+ type DustRemoval = ();
+ type ExistentialDeposit = ExistentialDeposit;
+ type AccountStore = System;
+ type WeightInfo = ();
+ type MaxReserves = MaxReserves;
+ type ReserveIdentifier = [u8; 8];
+}
+
+parameter_types! {
+ pub const ReservedXcmpWeight: Weight = WEIGHT_PER_SECOND / 4;
+ pub const ReservedDmpWeight: Weight = WEIGHT_PER_SECOND / 4;
+}
+
+parameter_types! {
+ pub const KsmLocation: MultiLocation = MultiLocation::parent();
+ pub const RelayNetwork: NetworkId = NetworkId::Kusama;
+ pub Ancestry: MultiLocation = Parachain(MsgQueue::parachain_id().into()).into();
+}
+
+pub type LocationToAccountId = (
+ ParentIsPreset,
+ SiblingParachainConvertsVia,
+ AccountId32Aliases,
+);
+
+pub type XcmOriginToCallOrigin = (
+ SovereignSignedViaLocation,
+ SignedAccountId32AsNative,
+ XcmPassthrough,
+);
+
+parameter_types! {
+ pub const UnitWeightCost: Weight = 1;
+ pub KsmPerSecond: (AssetId, u128) = (Concrete(Parent.into()), 1);
+ pub const MaxInstructions: u32 = 100;
+}
+
+pub type LocalAssetTransactor =
+XcmCurrencyAdapter, LocationToAccountId, AccountId, ()>;
+
+pub type XcmRouter = super::ParachainXcmRouter;
+pub type Barrier = AllowUnpaidExecutionFrom;
+
+pub struct XcmConfig;
+impl Config for XcmConfig {
+ type Call = Call;
+ type XcmSender = XcmRouter;
+ type AssetTransactor = LocalAssetTransactor;
+ type OriginConverter = XcmOriginToCallOrigin;
+ type IsReserve = NativeAsset;
+ type IsTeleporter = ();
+ type LocationInverter = LocationInverter;
+ type Barrier = Barrier;
+ type Weigher = FixedWeightBounds;
+ type Trader = FixedRateOfFungible;
+ type ResponseHandler = ();
+ type AssetTrap = ();
+ type AssetClaims = ();
+ type SubscriptionService = ();
+}
+
+#[frame_support::pallet]
+pub mod mock_msg_queue {
+ use super::*;
+ use frame_support::pallet_prelude::*;
+
+ #[pallet::config]
+ pub trait Config: frame_system::Config {
+ type Event: From> + IsType<::Event>;
+ type XcmExecutor: ExecuteXcm;
+ }
+
+ #[pallet::call]
+ impl Pallet {}
+
+ #[pallet::pallet]
+ #[pallet::generate_store(pub(super) trait Store)]
+ #[pallet::without_storage_info]
+ pub struct Pallet(_);
+
+ #[pallet::storage]
+ #[pallet::getter(fn parachain_id)]
+ pub(super) type ParachainId = StorageValue<_, ParaId, ValueQuery>;
+
+ #[pallet::storage]
+ #[pallet::getter(fn received_dmp)]
+ /// A queue of received DMP messages
+ pub(super) type ReceivedDmp = StorageValue<_, Vec>, ValueQuery>;
+
+ impl Get for Pallet {
+ fn get() -> ParaId {
+ Self::parachain_id()
+ }
+ }
+
+ pub type MessageId = [u8; 32];
+
+ #[pallet::event]
+ #[pallet::generate_deposit(pub(super) fn deposit_event)]
+ pub enum Event {
+ // XCMP
+ /// Some XCM was executed OK.
+ Success(Option),
+ /// Some XCM failed.
+ Fail(Option, XcmError),
+ /// Bad XCM version used.
+ BadVersion(Option),
+ /// Bad XCM format used.
+ BadFormat(Option),
+
+ // DMP
+ /// Downward message is invalid XCM.
+ InvalidFormat(MessageId),
+ /// Downward message is unsupported version of XCM.
+ UnsupportedVersion(MessageId),
+ /// Downward message executed with the given outcome.
+ ExecutedDownward(MessageId, Outcome),
+ }
+
+ impl Pallet {
+ pub fn set_para_id(para_id: ParaId) {
+ ParachainId::::put(para_id);
+ }
+
+ fn handle_xcmp_message(
+ sender: ParaId,
+ _sent_at: RelayBlockNumber,
+ xcm: VersionedXcm,
+ max_weight: Weight,
+ ) -> Result {
+ let hash = Encode::using_encoded(&xcm, T::Hashing::hash);
+ let (result, event) = match Xcm::::try_from(xcm) {
+ Ok(xcm) => {
+ let location = (1, Parachain(sender.into()));
+ match T::XcmExecutor::execute_xcm(location, xcm, max_weight) {
+ Outcome::Error(e) => (Err(e.clone()), Event::Fail(Some(hash), e)),
+ Outcome::Complete(w) => (Ok(w), Event::Success(Some(hash))),
+ // As far as the caller is concerned, this was dispatched without error, so
+ // we just report the weight used.
+ Outcome::Incomplete(w, e) => (Ok(w), Event::Fail(Some(hash), e)),
+ }
+ },
+ Err(()) => (Err(XcmError::UnhandledXcmVersion), Event::BadVersion(Some(hash))),
+ };
+ Self::deposit_event(event);
+ result
+ }
+ }
+
+ impl XcmpMessageHandler for Pallet {
+ fn handle_xcmp_messages<'a, I: Iterator- >(
+ iter: I,
+ max_weight: Weight,
+ ) -> Weight {
+ for (sender, sent_at, data) in iter {
+ let mut data_ref = data;
+ let _ = XcmpMessageFormat::decode(&mut data_ref)
+ .expect("Simulator encodes with versioned xcm format; qed");
+
+ let mut remaining_fragments = &data_ref[..];
+ while !remaining_fragments.is_empty() {
+ if let Ok(xcm) = VersionedXcm::::decode(&mut remaining_fragments) {
+ let _ = Self::handle_xcmp_message(sender, sent_at, xcm, max_weight);
+ } else {
+ debug_assert!(false, "Invalid incoming XCMP message data");
+ }
+ }
+ }
+ max_weight
+ }
+ }
+
+ impl DmpMessageHandler for Pallet {
+ fn handle_dmp_messages(
+ iter: impl Iterator
- )>,
+ limit: Weight,
+ ) -> Weight {
+ for (_i, (_sent_at, data)) in iter.enumerate() {
+ let id = sp_io::hashing::blake2_256(&data[..]);
+ let maybe_msg =
+ VersionedXcm::::decode(&mut &data[..]).map(Xcm::::try_from);
+ match maybe_msg {
+ Err(_) => {
+ Self::deposit_event(Event::InvalidFormat(id));
+ },
+ Ok(Err(())) => {
+ Self::deposit_event(Event::UnsupportedVersion(id));
+ },
+ Ok(Ok(x)) => {
+ let outcome = T::XcmExecutor::execute_xcm(Parent, x.clone(), limit);
+ >::append(x);
+ Self::deposit_event(Event::ExecutedDownward(id, outcome));
+ },
+ }
+ }
+ limit
+ }
+ }
+}
+
+impl mock_msg_queue::Config for Runtime {
+ type Event = Event;
+ type XcmExecutor = XcmExecutor;
+}
+
+pub type LocalOriginToLocation = SignedToAccountId32;
+
+impl pallet_xcm::Config for Runtime {
+ type Event = Event;
+ type SendXcmOrigin = EnsureXcmOrigin;
+ type XcmRouter = XcmRouter;
+ type ExecuteXcmOrigin = EnsureXcmOrigin;
+ type XcmExecuteFilter = Everything;
+ type XcmExecutor = XcmExecutor;
+ type XcmTeleportFilter = Nothing;
+ type XcmReserveTransferFilter = Everything;
+ type Weigher = FixedWeightBounds;
+ type LocationInverter = LocationInverter;
+ type Origin = Origin;
+ type Call = Call;
+ const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;
+ type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion;
+}
+
+type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic;
+type Block = frame_system::mocking::MockBlock;
+
+construct_runtime!(
+ pub enum Runtime where
+ Block = Block,
+ NodeBlock = Block,
+ UncheckedExtrinsic = UncheckedExtrinsic,
+ {
+ System: frame_system::{Pallet, Call, Storage, Config, Event},
+ Balances: pallet_balances::{Pallet, Call, Storage, Config, Event},
+ MsgQueue: mock_msg_queue::{Pallet, Storage, Event},
+ PolkadotXcm: pallet_xcm::{Pallet, Call, Event, Origin},
+ }
+);
diff --git a/runtime/common/src/message_router/mock/relay_chain.rs b/runtime/common/src/message_router/mock/relay_chain.rs
new file mode 100644
index 00000000..16b155d1
--- /dev/null
+++ b/runtime/common/src/message_router/mock/relay_chain.rs
@@ -0,0 +1,195 @@
+// This file is part of Darwinia.
+//
+// Copyright (C) 2018-2022 Darwinia Network
+// SPDX-License-Identifier: GPL-3.0
+//
+// Darwinia 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.
+//
+// Darwinia 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 Darwinia. If not, see .
+
+//! Relay chain runtime mock.
+
+use frame_support::{
+ construct_runtime, parameter_types,
+ traits::{Everything, Nothing},
+ weights::Weight,
+};
+use sp_core::H256;
+use sp_runtime::{testing::Header, traits::IdentityLookup, AccountId32};
+
+use polkadot_parachain::primitives::Id as ParaId;
+use polkadot_runtime_parachains::{configuration, origin, shared, ump};
+use xcm::latest::prelude::*;
+use xcm_builder::{
+ AccountId32Aliases, AllowUnpaidExecutionFrom, ChildParachainAsNative,
+ ChildParachainConvertsVia, ChildSystemParachainAsSuperuser,
+ CurrencyAdapter as XcmCurrencyAdapter, FixedRateOfFungible, FixedWeightBounds, IsConcrete,
+ LocationInverter, SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation,
+};
+use xcm_executor::{Config, XcmExecutor};
+
+pub type AccountId = AccountId32;
+pub type Balance = u128;
+
+parameter_types! {
+ pub const BlockHashCount: u64 = 250;
+}
+
+impl frame_system::Config for Runtime {
+ type Origin = Origin;
+ type Call = Call;
+ type Index = u64;
+ type BlockNumber = u64;
+ type Hash = H256;
+ type Hashing = ::sp_runtime::traits::BlakeTwo256;
+ type AccountId = AccountId;
+ type Lookup = IdentityLookup;
+ type Header = Header;
+ type Event = Event;
+ type BlockHashCount = BlockHashCount;
+ type BlockWeights = ();
+ type BlockLength = ();
+ type Version = ();
+ type PalletInfo = PalletInfo;
+ type AccountData = pallet_balances::AccountData;
+ type OnNewAccount = ();
+ type OnKilledAccount = ();
+ type DbWeight = ();
+ type BaseCallFilter = Everything;
+ type SystemWeightInfo = ();
+ type SS58Prefix = ();
+ type OnSetCode = ();
+ type MaxConsumers = frame_support::traits::ConstU32<16>;
+}
+
+parameter_types! {
+ pub ExistentialDeposit: Balance = 1;
+ pub const MaxLocks: u32 = 50;
+ pub const MaxReserves: u32 = 50;
+}
+
+impl pallet_balances::Config for Runtime {
+ type MaxLocks = MaxLocks;
+ type Balance = Balance;
+ type Event = Event;
+ type DustRemoval = ();
+ type ExistentialDeposit = ExistentialDeposit;
+ type AccountStore = System;
+ type WeightInfo = ();
+ type MaxReserves = MaxReserves;
+ type ReserveIdentifier = [u8; 8];
+}
+
+impl shared::Config for Runtime {}
+
+impl configuration::Config for Runtime {
+ type WeightInfo = configuration::TestWeightInfo;
+}
+
+parameter_types! {
+ pub const KsmLocation: MultiLocation = Here.into();
+ pub const KusamaNetwork: NetworkId = NetworkId::Kusama;
+ pub const AnyNetwork: NetworkId = NetworkId::Any;
+ pub Ancestry: MultiLocation = Here.into();
+ pub UnitWeightCost: Weight = 1_000;
+}
+
+pub type SovereignAccountOf =
+ (ChildParachainConvertsVia, AccountId32Aliases);
+
+pub type LocalAssetTransactor =
+ XcmCurrencyAdapter, SovereignAccountOf, AccountId, ()>;
+
+type LocalOriginConverter = (
+ SovereignSignedViaLocation,
+ ChildParachainAsNative,
+ SignedAccountId32AsNative,
+ ChildSystemParachainAsSuperuser,
+);
+
+parameter_types! {
+ pub const BaseXcmWeight: Weight = 1_000;
+ pub KsmPerSecond: (AssetId, u128) = (Concrete(KsmLocation::get()), 1);
+ pub const MaxInstructions: u32 = 100;
+}
+
+pub type XcmRouter = super::RelayChainXcmRouter;
+pub type Barrier = AllowUnpaidExecutionFrom;
+
+pub struct XcmConfig;
+impl Config for XcmConfig {
+ type Call = Call;
+ type XcmSender = XcmRouter;
+ type AssetTransactor = LocalAssetTransactor;
+ type OriginConverter = LocalOriginConverter;
+ type IsReserve = ();
+ type IsTeleporter = ();
+ type LocationInverter = LocationInverter;
+ type Barrier = Barrier;
+ type Weigher = FixedWeightBounds;
+ type Trader = FixedRateOfFungible;
+ type ResponseHandler = ();
+ type AssetTrap = ();
+ type AssetClaims = ();
+ type SubscriptionService = ();
+}
+
+pub type LocalOriginToLocation = SignedToAccountId32;
+
+impl pallet_xcm::Config for Runtime {
+ type Event = Event;
+ type SendXcmOrigin = xcm_builder::EnsureXcmOrigin;
+ type XcmRouter = XcmRouter;
+ // Anyone can execute XCM messages locally...
+ type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin;
+ type XcmExecuteFilter = Nothing;
+ type XcmExecutor = XcmExecutor;
+ type XcmTeleportFilter = Everything;
+ type XcmReserveTransferFilter = Everything;
+ type Weigher = FixedWeightBounds;
+ type LocationInverter = LocationInverter;
+ type Origin = Origin;
+ type Call = Call;
+ const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100;
+ type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion;
+}
+
+parameter_types! {
+ pub const FirstMessageFactorPercent: u64 = 100;
+}
+
+impl ump::Config for Runtime {
+ type Event = Event;
+ type UmpSink = ump::XcmSink, Runtime>;
+ type FirstMessageFactorPercent = FirstMessageFactorPercent;
+ type ExecuteOverweightOrigin = frame_system::EnsureRoot;
+ type WeightInfo = ump::TestWeightInfo;
+}
+
+impl origin::Config for Runtime {}
+
+type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic;
+type Block = frame_system::mocking::MockBlock;
+
+construct_runtime!(
+ pub enum Runtime where
+ Block = Block,
+ NodeBlock = Block,
+ UncheckedExtrinsic = UncheckedExtrinsic,
+ {
+ System: frame_system::{Pallet, Call, Storage, Config, Event},
+ Balances: pallet_balances::{Pallet, Call, Storage, Config, Event},
+ ParasOrigin: origin::{Pallet, Origin},
+ ParasUmp: ump::{Pallet, Call, Storage, Event},
+ XcmPallet: pallet_xcm::{Pallet, Call, Storage, Event, Origin},
+ }
+);
diff --git a/runtime/common/src/message_router/mod.rs b/runtime/common/src/message_router/mod.rs
index b7704e31..9f055bb8 100644
--- a/runtime/common/src/message_router/mod.rs
+++ b/runtime/common/src/message_router/mod.rs
@@ -21,6 +21,10 @@
#[cfg(feature = "runtime-benchmarks")]
mod benchmarking;
mod weights;
+#[cfg(test)]
+mod mock;
+#[cfg(test)]
+mod test;
// --- paritytech ---
use frame_support::{pallet_prelude::*, traits::Get};
diff --git a/runtime/common/src/message_router/test.rs b/runtime/common/src/message_router/test.rs
new file mode 100644
index 00000000..28faf033
--- /dev/null
+++ b/runtime/common/src/message_router/test.rs
@@ -0,0 +1,21 @@
+// This file is part of Darwinia.
+//
+// Copyright (C) 2018-2022 Darwinia Network
+// SPDX-License-Identifier: GPL-3.0
+//
+// Darwinia 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.
+//
+// Darwinia 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 Darwinia. If not, see .
+
+//! Unit tests for the message router.
+
+use super::mock::*;
\ No newline at end of file
From 4b559c2d44e8908a7d65affaf5637ba6b4474e3d Mon Sep 17 00:00:00 2001
From: Guantong <04637@163.com>
Date: Thu, 1 Sep 2022 15:15:13 +0800
Subject: [PATCH 11/37] format
---
runtime/common/src/message_router/mock/mod.rs | 4 +-
.../src/message_router/mock/parachain.rs | 79 +++++++++---------
.../src/message_router/mock/relay_chain.rs | 81 ++++++++++---------
runtime/common/src/message_router/mod.rs | 2 +-
runtime/common/src/message_router/test.rs | 2 +-
5 files changed, 85 insertions(+), 83 deletions(-)
diff --git a/runtime/common/src/message_router/mock/mod.rs b/runtime/common/src/message_router/mock/mod.rs
index d4705694..1756e9ef 100644
--- a/runtime/common/src/message_router/mock/mod.rs
+++ b/runtime/common/src/message_router/mock/mod.rs
@@ -91,8 +91,8 @@ pub fn relay_ext() -> sp_io::TestExternalities {
pallet_balances::GenesisConfig:: {
balances: vec![(ALICE, INITIAL_BALANCE), (para_account_id(1), INITIAL_BALANCE)],
}
- .assimilate_storage(&mut t)
- .unwrap();
+ .assimilate_storage(&mut t)
+ .unwrap();
let mut ext = sp_io::TestExternalities::new(t);
ext.execute_with(|| System::set_block_number(1));
diff --git a/runtime/common/src/message_router/mock/parachain.rs b/runtime/common/src/message_router/mock/parachain.rs
index 34551f5c..95840acf 100644
--- a/runtime/common/src/message_router/mock/parachain.rs
+++ b/runtime/common/src/message_router/mock/parachain.rs
@@ -54,30 +54,30 @@ parameter_types! {
}
impl frame_system::Config for Runtime {
- type Origin = Origin;
- type Call = Call;
- type Index = u64;
+ type AccountData = pallet_balances::AccountData;
+ type AccountId = AccountId;
+ type BaseCallFilter = Everything;
+ type BlockHashCount = BlockHashCount;
+ type BlockLength = ();
type BlockNumber = u64;
+ type BlockWeights = ();
+ type Call = Call;
+ type DbWeight = ();
+ type Event = Event;
type Hash = H256;
type Hashing = ::sp_runtime::traits::BlakeTwo256;
- type AccountId = AccountId;
- type Lookup = IdentityLookup;
type Header = Header;
- type Event = Event;
- type BlockHashCount = BlockHashCount;
- type BlockWeights = ();
- type BlockLength = ();
- type Version = ();
- type PalletInfo = PalletInfo;
- type AccountData = pallet_balances::AccountData;
- type OnNewAccount = ();
+ type Index = u64;
+ type Lookup = IdentityLookup;
+ type MaxConsumers = frame_support::traits::ConstU32<16>;
type OnKilledAccount = ();
- type DbWeight = ();
- type BaseCallFilter = Everything;
- type SystemWeightInfo = ();
- type SS58Prefix = ();
+ type OnNewAccount = ();
type OnSetCode = ();
- type MaxConsumers = frame_support::traits::ConstU32<16>;
+ type Origin = Origin;
+ type PalletInfo = PalletInfo;
+ type SS58Prefix = ();
+ type SystemWeightInfo = ();
+ type Version = ();
}
parameter_types! {
@@ -87,15 +87,15 @@ parameter_types! {
}
impl pallet_balances::Config for Runtime {
- type MaxLocks = MaxLocks;
+ type AccountStore = System;
type Balance = Balance;
- type Event = Event;
type DustRemoval = ();
+ type Event = Event;
type ExistentialDeposit = ExistentialDeposit;
- type AccountStore = System;
- type WeightInfo = ();
+ type MaxLocks = MaxLocks;
type MaxReserves = MaxReserves;
type ReserveIdentifier = [u8; 8];
+ type WeightInfo = ();
}
parameter_types! {
@@ -128,27 +128,27 @@ parameter_types! {
}
pub type LocalAssetTransactor =
-XcmCurrencyAdapter, LocationToAccountId, AccountId, ()>;
+ XcmCurrencyAdapter, LocationToAccountId, AccountId, ()>;
pub type XcmRouter = super::ParachainXcmRouter;
pub type Barrier = AllowUnpaidExecutionFrom;
pub struct XcmConfig;
impl Config for XcmConfig {
- type Call = Call;
- type XcmSender = XcmRouter;
+ type AssetClaims = ();
type AssetTransactor = LocalAssetTransactor;
- type OriginConverter = XcmOriginToCallOrigin;
+ type AssetTrap = ();
+ type Barrier = Barrier;
+ type Call = Call;
type IsReserve = NativeAsset;
type IsTeleporter = ();
type LocationInverter = LocationInverter;
- type Barrier = Barrier;
- type Weigher = FixedWeightBounds;
- type Trader = FixedRateOfFungible;
+ type OriginConverter = XcmOriginToCallOrigin;
type ResponseHandler = ();
- type AssetTrap = ();
- type AssetClaims = ();
type SubscriptionService = ();
+ type Trader = FixedRateOfFungible;
+ type Weigher = FixedWeightBounds;
+ type XcmSender = XcmRouter;
}
#[frame_support::pallet]
@@ -298,20 +298,21 @@ impl mock_msg_queue::Config for Runtime {
pub type LocalOriginToLocation = SignedToAccountId32;
impl pallet_xcm::Config for Runtime {
+ type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion;
+ type Call = Call;
type Event = Event;
- type SendXcmOrigin = EnsureXcmOrigin;
- type XcmRouter = XcmRouter;
type ExecuteXcmOrigin = EnsureXcmOrigin;
+ type LocationInverter = LocationInverter;
+ type Origin = Origin;
+ type SendXcmOrigin = EnsureXcmOrigin;
+ type Weigher = FixedWeightBounds;
type XcmExecuteFilter = Everything;
type XcmExecutor = XcmExecutor;
- type XcmTeleportFilter = Nothing;
type XcmReserveTransferFilter = Everything;
- type Weigher = FixedWeightBounds;
- type LocationInverter = LocationInverter