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; - type Origin = Origin; - type Call = Call; + type XcmRouter = XcmRouter; + type XcmTeleportFilter = Nothing; + const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; - type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; } type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; diff --git a/runtime/common/src/message_router/mock/relay_chain.rs b/runtime/common/src/message_router/mock/relay_chain.rs index 16b155d1..c1c9888e 100644 --- a/runtime/common/src/message_router/mock/relay_chain.rs +++ b/runtime/common/src/message_router/mock/relay_chain.rs @@ -45,30 +45,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! { @@ -78,15 +78,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 = (); } impl shared::Config for Runtime {} @@ -127,40 +127,41 @@ pub type Barrier = AllowUnpaidExecutionFrom; pub struct XcmConfig; impl Config for XcmConfig { - type Call = Call; - type XcmSender = XcmRouter; + type AssetClaims = (); type AssetTransactor = LocalAssetTransactor; - type OriginConverter = LocalOriginConverter; + type AssetTrap = (); + type Barrier = Barrier; + type Call = Call; type IsReserve = (); type IsTeleporter = (); type LocationInverter = LocationInverter; - type Barrier = Barrier; - type Weigher = FixedWeightBounds; - type Trader = FixedRateOfFungible; + type OriginConverter = LocalOriginConverter; type ResponseHandler = (); - type AssetTrap = (); - type AssetClaims = (); type SubscriptionService = (); + type Trader = FixedRateOfFungible; + type Weigher = FixedWeightBounds; + type XcmSender = XcmRouter; } pub type LocalOriginToLocation = SignedToAccountId32; impl pallet_xcm::Config for Runtime { + type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; + type Call = Call; type Event = Event; - type SendXcmOrigin = xcm_builder::EnsureXcmOrigin; - type XcmRouter = XcmRouter; // Anyone can execute XCM messages locally... type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin; + type LocationInverter = LocationInverter; + type Origin = Origin; + type SendXcmOrigin = xcm_builder::EnsureXcmOrigin; + type Weigher = FixedWeightBounds; type XcmExecuteFilter = Nothing; type XcmExecutor = XcmExecutor; - type XcmTeleportFilter = Everything; type XcmReserveTransferFilter = Everything; - type Weigher = FixedWeightBounds; - type LocationInverter = LocationInverter; - type Origin = Origin; - type Call = Call; + type XcmRouter = XcmRouter; + type XcmTeleportFilter = Everything; + const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; - type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; } parameter_types! { @@ -169,9 +170,9 @@ parameter_types! { impl ump::Config for Runtime { type Event = Event; - type UmpSink = ump::XcmSink, Runtime>; - type FirstMessageFactorPercent = FirstMessageFactorPercent; type ExecuteOverweightOrigin = frame_system::EnsureRoot; + type FirstMessageFactorPercent = FirstMessageFactorPercent; + type UmpSink = ump::XcmSink, Runtime>; type WeightInfo = ump::TestWeightInfo; } diff --git a/runtime/common/src/message_router/mod.rs b/runtime/common/src/message_router/mod.rs index 9f055bb8..d2326dd6 100644 --- a/runtime/common/src/message_router/mod.rs +++ b/runtime/common/src/message_router/mod.rs @@ -20,11 +20,11 @@ #[cfg(feature = "runtime-benchmarks")] mod benchmarking; -mod weights; #[cfg(test)] mod mock; #[cfg(test)] mod test; +mod weights; // --- 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 index 28faf033..a6995125 100644 --- a/runtime/common/src/message_router/test.rs +++ b/runtime/common/src/message_router/test.rs @@ -18,4 +18,4 @@ //! Unit tests for the message router. -use super::mock::*; \ No newline at end of file +use super::mock::*; From 52912a5d5eb0e628bb4c8d01245d214e265324e2 Mon Sep 17 00:00:00 2001 From: Guantong <04637@163.com> Date: Fri, 2 Sep 2022 15:36:19 +0800 Subject: [PATCH 12/37] Add descendOrigin barrier & allow moonbeam --- runtime/common/src/message_router/barriers.rs | 77 +++++++++++++++++++ runtime/common/src/message_router/mod.rs | 1 + .../src/pallets/polkadot_xcm.rs | 13 +++- 3 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 runtime/common/src/message_router/barriers.rs diff --git a/runtime/common/src/message_router/barriers.rs b/runtime/common/src/message_router/barriers.rs new file mode 100644 index 00000000..4b1df1b3 --- /dev/null +++ b/runtime/common/src/message_router/barriers.rs @@ -0,0 +1,77 @@ +// 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 . + +//! Various implementations for `ShouldExecute`. + +use frame_support::{ensure, log, traits::Contains, weights::Weight}; +use sp_std::{marker::PhantomData, result::Result}; +use xcm::latest::{ + Instruction::*, MultiLocation, WeightLimit::*, Xcm, +}; +use xcm_executor::traits::ShouldExecute; + +/// Allows execution from `origin` if it is contained in `T` (i.e. `T::Contains(origin)`) taking +/// payments into account. +/// +/// Only allows for `TeleportAsset`, `WithdrawAsset`, `ClaimAsset` and `ReserveAssetDeposit` XCMs +/// because they are the only ones that place assets in the Holding Register to pay for execution. +pub struct AllowDescendOriginPaidExecutionFrom(PhantomData); +impl> ShouldExecute for AllowDescendOriginPaidExecutionFrom { + fn should_execute( + origin: &MultiLocation, + message: &mut Xcm, + max_weight: Weight, + _weight_credit: &mut Weight, + ) -> Result<(), ()> { + log::trace!( + target: "xcm::barriers", + "AllowDescendOriginPaidExecutionFrom origin: {:?}, message: {:?}, max_weight: {:?}, weight_credit: {:?}", + origin, message, max_weight, _weight_credit, + ); + ensure!(T::contains(origin), ()); + let mut iter = message.0.iter_mut(); + let i = iter.next().ok_or(())?; + match i { + DescendOrigin(_) => (), + _ => return Err(()), + } + let i = iter.next().ok_or(())?; + match i { + ReceiveTeleportedAsset(..) + | WithdrawAsset(..) + | ReserveAssetDeposited(..) + | ClaimAsset { .. } => (), + _ => return Err(()), + } + let mut i = iter.next().ok_or(())?; + while let ClearOrigin = i { + i = iter.next().ok_or(())?; + } + match i { + BuyExecution { weight_limit: Limited(ref mut weight), .. } if *weight >= max_weight => { + *weight = max_weight; + Ok(()) + }, + BuyExecution { ref mut weight_limit, .. } if weight_limit == &Unlimited => { + *weight_limit = Limited(max_weight); + Ok(()) + }, + _ => Err(()), + } + } +} diff --git a/runtime/common/src/message_router/mod.rs b/runtime/common/src/message_router/mod.rs index d2326dd6..41f40ef4 100644 --- a/runtime/common/src/message_router/mod.rs +++ b/runtime/common/src/message_router/mod.rs @@ -18,6 +18,7 @@ //! Prototype module for message router. +pub mod barriers; #[cfg(feature = "runtime-benchmarks")] mod benchmarking; #[cfg(test)] diff --git a/runtime/pangolin-parachain/src/pallets/polkadot_xcm.rs b/runtime/pangolin-parachain/src/pallets/polkadot_xcm.rs index 149ca64d..612b6eff 100644 --- a/runtime/pangolin-parachain/src/pallets/polkadot_xcm.rs +++ b/runtime/pangolin-parachain/src/pallets/polkadot_xcm.rs @@ -14,7 +14,10 @@ use xcm_builder::*; use xcm_executor::{Config as XcmCExecutorConfig, XcmExecutor}; // --- darwinia-network --- use crate::*; -use dp_common_runtime::xcm_config::{DenyReserveTransferToRelayChain, DenyThenTry}; +use dp_common_runtime::{ + message_router::barriers::AllowDescendOriginPaidExecutionFrom, + xcm_config::{DenyReserveTransferToRelayChain, DenyThenTry}, +}; /// Converts a local signed origin into an XCM multilocation. /// Forms the basis for local origins sending/executing XCMs. @@ -48,6 +51,7 @@ pub type Barrier = DenyThenTry< ( TakeWeightCredit, AllowTopLevelPaidExecutionFrom, + AllowDescendOriginPaidExecutionFrom, // Parent and its exec plurality get free execution AllowUnpaidExecutionFrom, // Expected responses are OK. @@ -111,6 +115,13 @@ frame_support::match_types! { MultiLocation { parents: 1, interior: Here } | MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Executive, .. }) } }; + pub type AllowDescendOrigin: impl Contains = { + // MoonbeamLocation + MultiLocation { + parents: 1, + interior: X1(Parachain(1000)) + } + }; } frame_support::match_types! { pub type ParentOrSiblings: impl Contains = { From b26217e4e554668bbf8a7a4757326c22f27bc171 Mon Sep 17 00:00:00 2001 From: Guantong <04637@163.com> Date: Wed, 12 Oct 2022 13:36:46 +0800 Subject: [PATCH 13/37] Support AccountKey20Derive  Conflicts:  runtime/common/Cargo.toml --- runtime/common/Cargo.toml | 2 +- runtime/common/src/message_router/barriers.rs | 4 +- .../src/message_router/location_conversion.rs | 54 +++++++++++++++++++ runtime/common/src/message_router/mod.rs | 5 +- runtime/common/src/message_router/test.rs | 21 -------- .../src/pallets/polkadot_xcm.rs | 6 ++- 6 files changed, 62 insertions(+), 30 deletions(-) create mode 100644 runtime/common/src/message_router/location_conversion.rs delete mode 100644 runtime/common/src/message_router/test.rs diff --git a/runtime/common/Cargo.toml b/runtime/common/Cargo.toml index 72b0ec66..59ae3ffb 100644 --- a/runtime/common/Cargo.toml +++ b/runtime/common/Cargo.toml @@ -34,6 +34,7 @@ frame-system = { default-features = false, git = "https://github.c pallet-balances = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" } pallet-transaction-payment = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" } sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" } +sp-io = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" } 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 @@ -48,7 +49,6 @@ xcm-simulator = { default-features = false, git = "https://github. [dev-dependencies] pallet-timestamp = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" } -sp-io = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" } [features] default = ["std"] diff --git a/runtime/common/src/message_router/barriers.rs b/runtime/common/src/message_router/barriers.rs index 4b1df1b3..c09bf217 100644 --- a/runtime/common/src/message_router/barriers.rs +++ b/runtime/common/src/message_router/barriers.rs @@ -20,9 +20,7 @@ use frame_support::{ensure, log, traits::Contains, weights::Weight}; use sp_std::{marker::PhantomData, result::Result}; -use xcm::latest::{ - Instruction::*, MultiLocation, WeightLimit::*, Xcm, -}; +use xcm::latest::{Instruction::*, MultiLocation, WeightLimit::*, Xcm}; use xcm_executor::traits::ShouldExecute; /// Allows execution from `origin` if it is contained in `T` (i.e. `T::Contains(origin)`) taking diff --git a/runtime/common/src/message_router/location_conversion.rs b/runtime/common/src/message_router/location_conversion.rs new file mode 100644 index 00000000..90e444bb --- /dev/null +++ b/runtime/common/src/message_router/location_conversion.rs @@ -0,0 +1,54 @@ +// 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 . + +use sp_std::marker::PhantomData; +use xcm::{latest::MultiLocation, prelude::*}; +use xcm_executor::traits::Convert; + +/// The address prefix for dvm address +const ADDR_PREFIX: &[u8] = b"dvm:"; + +pub struct AccountKey20Derive(PhantomData); +impl + Into<[u8; 32]> + Clone> Convert + for AccountKey20Derive +{ + fn convert(location: MultiLocation) -> Result { + let key = match location { + MultiLocation { parents: 0, interior: X1(AccountKey20 { key, network: _ }) } => key, + MultiLocation { + parents: 1, + interior: X2(Parachain(_), AccountKey20 { key, network: _ }), + } => key, + _ => return Err(location), + }; + let mut raw_account = [0u8; 32]; + + raw_account[0..4].copy_from_slice(ADDR_PREFIX); + raw_account[11..31].copy_from_slice(&key[..]); + raw_account[31] = checksum_of(&raw_account); + Ok(raw_account.into()) + } + + fn reverse(who: AccountId) -> Result { + Ok(AccountId32 { id: who.into(), network: Any }.into()) + } +} + +fn checksum_of(account_id: &[u8; 32]) -> u8 { + account_id[1..31].iter().fold(account_id[0], |sum, &byte| sum ^ byte) +} diff --git a/runtime/common/src/message_router/mod.rs b/runtime/common/src/message_router/mod.rs index 41f40ef4..2a497dfc 100644 --- a/runtime/common/src/message_router/mod.rs +++ b/runtime/common/src/message_router/mod.rs @@ -21,10 +21,7 @@ pub mod barriers; #[cfg(feature = "runtime-benchmarks")] mod benchmarking; -#[cfg(test)] -mod mock; -#[cfg(test)] -mod test; +pub mod location_conversion; mod weights; // --- paritytech --- diff --git a/runtime/common/src/message_router/test.rs b/runtime/common/src/message_router/test.rs deleted file mode 100644 index a6995125..00000000 --- a/runtime/common/src/message_router/test.rs +++ /dev/null @@ -1,21 +0,0 @@ -// 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::*; diff --git a/runtime/pangolin-parachain/src/pallets/polkadot_xcm.rs b/runtime/pangolin-parachain/src/pallets/polkadot_xcm.rs index 612b6eff..46eb3f68 100644 --- a/runtime/pangolin-parachain/src/pallets/polkadot_xcm.rs +++ b/runtime/pangolin-parachain/src/pallets/polkadot_xcm.rs @@ -15,7 +15,9 @@ use xcm_executor::{Config as XcmCExecutorConfig, XcmExecutor}; // --- darwinia-network --- use crate::*; use dp_common_runtime::{ - message_router::barriers::AllowDescendOriginPaidExecutionFrom, + message_router::{ + barriers::AllowDescendOriginPaidExecutionFrom, location_conversion::AccountKey20Derive, + }, xcm_config::{DenyReserveTransferToRelayChain, DenyThenTry}, }; @@ -71,6 +73,8 @@ pub type LocationToAccountId = ( SiblingParachainConvertsVia, // Straight up local `AccountId32` origins just alias directly to `AccountId`. AccountId32Aliases, + // Derive AccountKey20 to AccountId32 + AccountKey20Derive, ); /// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance, From f9e61f1fe2d48dbb5c38a74d2173dcb18c9b16ad Mon Sep 17 00:00:00 2001 From: Guantong <04637@163.com> Date: Thu, 8 Sep 2022 10:24:23 +0800 Subject: [PATCH 14/37] Companion for PureStake/moonbeam#1791 --- runtime/pangolin-parachain/src/pallets/message_router.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/pangolin-parachain/src/pallets/message_router.rs b/runtime/pangolin-parachain/src/pallets/message_router.rs index bc1d24b1..1122306f 100644 --- a/runtime/pangolin-parachain/src/pallets/message_router.rs +++ b/runtime/pangolin-parachain/src/pallets/message_router.rs @@ -10,7 +10,7 @@ use dp_common_runtime::message_router::Config; frame_support::parameter_types! { pub const MoonbeamMaxInstructions: u32 = 100; - pub MoonbeamUnitWeightCost: Weight = 100_000_000; + pub MoonbeamUnitWeightCost: Weight = 200_000_000; pub SelfLocationInSibl: MultiLocation = MultiLocation::new( 1, X1(Parachain(ParachainInfo::parachain_id().into())) From c6fbfbf494096d99f26894b3917ef959a854bed4 Mon Sep 17 00:00:00 2001 From: Guantong <04637@163.com> Date: Wed, 14 Sep 2022 15:40:48 +0800 Subject: [PATCH 15/37] use default weight for bridge_messages --- runtime/pangolin-parachain/src/pallets/bridge_messages.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/runtime/pangolin-parachain/src/pallets/bridge_messages.rs b/runtime/pangolin-parachain/src/pallets/bridge_messages.rs index 86816bce..aea85582 100644 --- a/runtime/pangolin-parachain/src/pallets/bridge_messages.rs +++ b/runtime/pangolin-parachain/src/pallets/bridge_messages.rs @@ -1,7 +1,7 @@ pub use pallet_bridge_messages::Instance1 as WithPangolinMessages; // --- darwinia-network --- -use crate::{weights::pallet_bridge_messages::WeightInfo, *}; +use crate::*; use bp_messages::{source_chain::SenderOrigin, MessageNonce}; use bp_runtime::{ChainId, PANGOLIN_CHAIN_ID}; use pallet_bridge_messages::Config; @@ -52,5 +52,5 @@ impl Config for Runtime { type Parameter = bm_pangolin::PangolinParachainToPangolinParameter; type SourceHeaderChain = bm_pangolin::Pangolin; type TargetHeaderChain = bm_pangolin::Pangolin; - type WeightInfo = WeightInfo; + type WeightInfo = (); } From 1fc300576d9b46b81b3b176239d3f27efe36b75a Mon Sep 17 00:00:00 2001 From: Guantong <04637@163.com> Date: Thu, 22 Sep 2022 17:50:23 +0800 Subject: [PATCH 16/37] add comments --- runtime/common/src/message_router/mod.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/runtime/common/src/message_router/mod.rs b/runtime/common/src/message_router/mod.rs index 2a497dfc..c42b289e 100644 --- a/runtime/common/src/message_router/mod.rs +++ b/runtime/common/src/message_router/mod.rs @@ -73,6 +73,7 @@ pub mod pallet { #[pallet::error] pub enum Error { + /// Not config the target paraId's info for XCM execution. TargetXcmExecNotConfig, /// The message's weight could not be determined. UnweighableMessage, @@ -129,18 +130,20 @@ pub mod pallet { origin: OriginFor, message: Box::Call>>, ) -> DispatchResultWithPostInfo { + // MultiLocation origin used to execute xcm let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin.clone())?; let account_id = ensure_signed(origin)?; + // u8 account used in DescendOrigin instruction 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)?; - // Calculate the execution fee required to execute remote xcm - let local_asset_units_per_second = - TargetXcmExecConfig::::get(T::MoonbeamLocation::get()) - .ok_or(Error::::TargetXcmExecNotConfig)?; + /// Calculate the execution fee required for remote xcm execution + /// fee = fee_per_second * (weight/weight_per_second) + 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( account_u8.clone(), remote_xcm.clone(), From 73dd3d9107cd755df95f7362640f13b84e752242 Mon Sep 17 00:00:00 2001 From: Guantong <04637@163.com> Date: Thu, 22 Sep 2022 18:19:22 +0800 Subject: [PATCH 17/37] Add message router for crab parachain --- runtime/common/src/message_router/mod.rs | 4 +- runtime/crab-parachain/src/lib.rs | 2 + .../src/pallets/message_router.rs | 43 +++++++++++++++++++ runtime/crab-parachain/src/pallets/mod.rs | 3 ++ .../src/pallets/polkadot_xcm.rs | 19 +++++++- .../src/pallets/message_router.rs | 5 ++- .../src/pallets/polkadot_xcm.rs | 16 ++++--- 7 files changed, 80 insertions(+), 12 deletions(-) create mode 100644 runtime/crab-parachain/src/pallets/message_router.rs diff --git a/runtime/common/src/message_router/mod.rs b/runtime/common/src/message_router/mod.rs index c42b289e..97708a9c 100644 --- a/runtime/common/src/message_router/mod.rs +++ b/runtime/common/src/message_router/mod.rs @@ -140,8 +140,8 @@ pub mod pallet { let remote_xcm: Xcm<::Call> = (*message).try_into().map_err(|()| Error::::BadVersion)?; - /// Calculate the execution fee required for remote xcm execution - /// fee = fee_per_second * (weight/weight_per_second) + // Calculate the execution fee required for remote xcm execution + // fee = fee_per_second * (weight/weight_per_second) 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( diff --git a/runtime/crab-parachain/src/lib.rs b/runtime/crab-parachain/src/lib.rs index a4c85389..34e6b6ed 100644 --- a/runtime/crab-parachain/src/lib.rs +++ b/runtime/crab-parachain/src/lib.rs @@ -177,6 +177,8 @@ frame_support::construct_runtime! { CrabFeeMarket: pallet_fee_market::::{Pallet, Call, Storage, Event} = 23, FromCrabIssuing: dp_common_runtime::helixbridge::{Pallet, Call, Storage, Event} = 24, + + MessageRouter: dp_common_runtime::message_router::{Pallet, Call, Storage, Event} = 26, } } diff --git a/runtime/crab-parachain/src/pallets/message_router.rs b/runtime/crab-parachain/src/pallets/message_router.rs new file mode 100644 index 00000000..de4d5fae --- /dev/null +++ b/runtime/crab-parachain/src/pallets/message_router.rs @@ -0,0 +1,43 @@ +// --- 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; + // https://github.com/PureStake/moonbeam/blob/master/runtime/moonriver/src/xcm_config.rs#L208 + pub MoonbeamUnitWeightCost: Weight = 200_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 MoonriverLocation: MultiLocation = MultiLocation::new( + 1, + X1(Parachain(2023)) + ); +} + +impl Config for Runtime { + type AssetModifierOrigin = EnsureRoot; + type AssetTransactor = LocalAssetTransactor; + type Event = Event; + type ExecuteXcmOrigin = EnsureXcmOrigin; + type LocalAssetId = AnchoringSelfReserve; + type LocalWeigher = FixedWeightBounds; + type LocationInverter = LocationInverter; + type MoonbeamLocation = MoonriverLocation; + type MoonbeamWeigher = FixedWeightBounds; + type SelfLocationInSibl = SelfLocationInSibl; + type WeightInfo = (); + type XcmExecutor = XcmExecutor; + type XcmSender = XcmRouter; +} diff --git a/runtime/crab-parachain/src/pallets/mod.rs b/runtime/crab-parachain/src/pallets/mod.rs index a175975c..eac8f4c7 100644 --- a/runtime/crab-parachain/src/pallets/mod.rs +++ b/runtime/crab-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::*; diff --git a/runtime/crab-parachain/src/pallets/polkadot_xcm.rs b/runtime/crab-parachain/src/pallets/polkadot_xcm.rs index 149ca64d..80d516a7 100644 --- a/runtime/crab-parachain/src/pallets/polkadot_xcm.rs +++ b/runtime/crab-parachain/src/pallets/polkadot_xcm.rs @@ -14,7 +14,12 @@ use xcm_builder::*; use xcm_executor::{Config as XcmCExecutorConfig, XcmExecutor}; // --- darwinia-network --- use crate::*; -use dp_common_runtime::xcm_config::{DenyReserveTransferToRelayChain, DenyThenTry}; +use dp_common_runtime::{ + message_router::{ + barriers::AllowDescendOriginPaidExecutionFrom, location_conversion::AccountKey20Derive, + }, + xcm_config::{DenyReserveTransferToRelayChain, DenyThenTry}, +}; /// Converts a local signed origin into an XCM multilocation. /// Forms the basis for local origins sending/executing XCMs. @@ -48,6 +53,7 @@ pub type Barrier = DenyThenTry< ( TakeWeightCredit, AllowTopLevelPaidExecutionFrom, + AllowDescendOriginPaidExecutionFrom, // Parent and its exec plurality get free execution AllowUnpaidExecutionFrom, // Expected responses are OK. @@ -67,6 +73,8 @@ pub type LocationToAccountId = ( SiblingParachainConvertsVia, // Straight up local `AccountId32` origins just alias directly to `AccountId`. AccountId32Aliases, + // Derive AccountKey20 to AccountId32 + AccountKey20Derive, ); /// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance, @@ -118,6 +126,15 @@ frame_support::match_types! { MultiLocation { parents: 1, interior: X1(_) } }; } +frame_support::match_types! { + pub type AllowDescendOrigin: impl Contains = { + // Moonriver Location + MultiLocation { + parents: 1, + interior: X1(Parachain(2023)) + } + }; +} pub struct XcmConfig; impl XcmCExecutorConfig for XcmConfig { diff --git a/runtime/pangolin-parachain/src/pallets/message_router.rs b/runtime/pangolin-parachain/src/pallets/message_router.rs index 1122306f..976b81d6 100644 --- a/runtime/pangolin-parachain/src/pallets/message_router.rs +++ b/runtime/pangolin-parachain/src/pallets/message_router.rs @@ -10,6 +10,7 @@ use dp_common_runtime::message_router::Config; frame_support::parameter_types! { pub const MoonbeamMaxInstructions: u32 = 100; + // https://github.com/PureStake/moonbeam/blob/master/runtime/moonbase/src/xcm_config.rs#L214 pub MoonbeamUnitWeightCost: Weight = 200_000_000; pub SelfLocationInSibl: MultiLocation = MultiLocation::new( 1, @@ -19,7 +20,7 @@ frame_support::parameter_types! { 0, X1(PalletInstance(::index() as u8)) ); - pub MoonbeamLocation: MultiLocation = MultiLocation::new( + pub MoonbaseAlphaLocation: MultiLocation = MultiLocation::new( 1, X1(Parachain(1000)) ); @@ -33,7 +34,7 @@ impl Config for Runtime { type LocalAssetId = AnchoringSelfReserve; type LocalWeigher = FixedWeightBounds; type LocationInverter = LocationInverter; - type MoonbeamLocation = MoonbeamLocation; + type MoonbeamLocation = MoonbaseAlphaLocation; type MoonbeamWeigher = FixedWeightBounds; type SelfLocationInSibl = SelfLocationInSibl; type WeightInfo = (); diff --git a/runtime/pangolin-parachain/src/pallets/polkadot_xcm.rs b/runtime/pangolin-parachain/src/pallets/polkadot_xcm.rs index 46eb3f68..3b97394a 100644 --- a/runtime/pangolin-parachain/src/pallets/polkadot_xcm.rs +++ b/runtime/pangolin-parachain/src/pallets/polkadot_xcm.rs @@ -119,13 +119,6 @@ frame_support::match_types! { MultiLocation { parents: 1, interior: Here } | MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Executive, .. }) } }; - pub type AllowDescendOrigin: impl Contains = { - // MoonbeamLocation - MultiLocation { - parents: 1, - interior: X1(Parachain(1000)) - } - }; } frame_support::match_types! { pub type ParentOrSiblings: impl Contains = { @@ -133,6 +126,15 @@ frame_support::match_types! { MultiLocation { parents: 1, interior: X1(_) } }; } +frame_support::match_types! { + pub type AllowDescendOrigin: impl Contains = { + // MoonbaseAlpha location + MultiLocation { + parents: 1, + interior: X1(Parachain(1000)) + } + }; +} pub struct XcmConfig; impl XcmCExecutorConfig for XcmConfig { From 6592059465f786e655e237f9b779d3c49032e1ba Mon Sep 17 00:00:00 2001 From: Guantong <04637@163.com> Date: Thu, 22 Sep 2022 18:28:58 +0800 Subject: [PATCH 18/37] Add message router for darwinia parachain --- runtime/darwinia-parachain/src/lib.rs | 2 + .../src/pallets/message_router.rs | 43 +++++++++++++++++++ runtime/darwinia-parachain/src/pallets/mod.rs | 3 ++ .../src/pallets/polkadot_xcm.rs | 19 +++++++- 4 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 runtime/darwinia-parachain/src/pallets/message_router.rs diff --git a/runtime/darwinia-parachain/src/lib.rs b/runtime/darwinia-parachain/src/lib.rs index 0cc1eb82..28d7f283 100644 --- a/runtime/darwinia-parachain/src/lib.rs +++ b/runtime/darwinia-parachain/src/lib.rs @@ -161,6 +161,8 @@ frame_support::construct_runtime! { Multisig: pallet_multisig::{Pallet, Call, Storage, Event} = 17, Proxy: pallet_proxy::{Pallet, Call, Storage, Event} = 18, Sudo: pallet_sudo::{Pallet, Call, Storage, Config, Event} = 19, + + MessageRouter: dp_common_runtime::message_router::{Pallet, Call, Storage, Event} = 26, } } diff --git a/runtime/darwinia-parachain/src/pallets/message_router.rs b/runtime/darwinia-parachain/src/pallets/message_router.rs new file mode 100644 index 00000000..c1b44292 --- /dev/null +++ b/runtime/darwinia-parachain/src/pallets/message_router.rs @@ -0,0 +1,43 @@ +// --- 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; + // https://github.com/PureStake/moonbeam/blob/master/runtime/moonbeam/src/xcm_config.rs#L201 + pub MoonbeamUnitWeightCost: Weight = 200_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(2004)) + ); +} + +impl Config for Runtime { + type AssetModifierOrigin = EnsureRoot; + type AssetTransactor = LocalAssetTransactor; + type Event = Event; + type ExecuteXcmOrigin = EnsureXcmOrigin; + type LocalAssetId = AnchoringSelfReserve; + type LocalWeigher = FixedWeightBounds; + type LocationInverter = LocationInverter; + type MoonbeamLocation = MoonbeamLocation; + type MoonbeamWeigher = FixedWeightBounds; + type SelfLocationInSibl = SelfLocationInSibl; + type WeightInfo = (); + type XcmExecutor = XcmExecutor; + type XcmSender = XcmRouter; +} diff --git a/runtime/darwinia-parachain/src/pallets/mod.rs b/runtime/darwinia-parachain/src/pallets/mod.rs index 31108982..db01c8aa 100644 --- a/runtime/darwinia-parachain/src/pallets/mod.rs +++ b/runtime/darwinia-parachain/src/pallets/mod.rs @@ -54,3 +54,6 @@ pub use proxy::*; pub mod sudo; pub use sudo::*; + +pub mod message_router; +pub use message_router::*; diff --git a/runtime/darwinia-parachain/src/pallets/polkadot_xcm.rs b/runtime/darwinia-parachain/src/pallets/polkadot_xcm.rs index bda5a590..d6b53062 100644 --- a/runtime/darwinia-parachain/src/pallets/polkadot_xcm.rs +++ b/runtime/darwinia-parachain/src/pallets/polkadot_xcm.rs @@ -14,7 +14,12 @@ use xcm_builder::*; use xcm_executor::{Config as XcmCExecutorConfig, XcmExecutor}; // --- darwinia-network --- use crate::*; -use dp_common_runtime::xcm_config::{DenyReserveTransferToRelayChain, DenyThenTry}; +use dp_common_runtime::{ + message_router::{ + barriers::AllowDescendOriginPaidExecutionFrom, location_conversion::AccountKey20Derive, + }, + xcm_config::{DenyReserveTransferToRelayChain, DenyThenTry}, +}; /// Converts a local signed origin into an XCM multilocation. /// Forms the basis for local origins sending/executing XCMs. @@ -48,6 +53,7 @@ pub type Barrier = DenyThenTry< ( TakeWeightCredit, AllowTopLevelPaidExecutionFrom, + AllowDescendOriginPaidExecutionFrom, // Parent and its exec plurality get free execution AllowUnpaidExecutionFrom, // Expected responses are OK. @@ -67,6 +73,8 @@ pub type LocationToAccountId = ( SiblingParachainConvertsVia, // Straight up local `AccountId32` origins just alias directly to `AccountId`. AccountId32Aliases, + // Derive AccountKey20 to AccountId32 + AccountKey20Derive, ); /// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance, @@ -118,6 +126,15 @@ frame_support::match_types! { MultiLocation { parents: 1, interior: X1(_) } }; } +frame_support::match_types! { + pub type AllowDescendOrigin: impl Contains = { + // Moonbeam Location + MultiLocation { + parents: 1, + interior: X1(Parachain(2004)) + } + }; +} pub struct XcmConfig; impl XcmCExecutorConfig for XcmConfig { From f4bc4ce5c0ca55c2c2710d0530a423a612c6d673 Mon Sep 17 00:00:00 2001 From: Guantong <04637@163.com> Date: Thu, 22 Sep 2022 18:29:08 +0800 Subject: [PATCH 19/37] format --- runtime/common/src/message_router/mod.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/runtime/common/src/message_router/mod.rs b/runtime/common/src/message_router/mod.rs index 97708a9c..0dc6b29c 100644 --- a/runtime/common/src/message_router/mod.rs +++ b/runtime/common/src/message_router/mod.rs @@ -142,8 +142,9 @@ pub mod pallet { // Calculate the execution fee required for remote xcm execution // fee = fee_per_second * (weight/weight_per_second) - let local_asset_units_per_second = TargetXcmExecConfig::::get(T::MoonbeamLocation::get()) - .ok_or(Error::::TargetXcmExecNotConfig)?; + 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( account_u8.clone(), remote_xcm.clone(), From 1f4b3cc7e5732ab6003e327aca382f6ae9103326 Mon Sep 17 00:00:00 2001 From: Guantong <04637@163.com> Date: Thu, 22 Sep 2022 18:32:54 +0800 Subject: [PATCH 20/37] remove mock --- runtime/common/src/message_router/mock/mod.rs | 103 ------ .../src/message_router/mock/parachain.rs | 332 ------------------ .../src/message_router/mock/relay_chain.rs | 196 ----------- 3 files changed, 631 deletions(-) delete mode 100644 runtime/common/src/message_router/mock/mod.rs delete mode 100644 runtime/common/src/message_router/mock/parachain.rs delete mode 100644 runtime/common/src/message_router/mock/relay_chain.rs diff --git a/runtime/common/src/message_router/mock/mod.rs b/runtime/common/src/message_router/mock/mod.rs deleted file mode 100644 index 1756e9ef..00000000 --- a/runtime/common/src/message_router/mock/mod.rs +++ /dev/null @@ -1,103 +0,0 @@ -// 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 deleted file mode 100644 index 95840acf..00000000 --- a/runtime/common/src/message_router/mock/parachain.rs +++ /dev/null @@ -1,332 +0,0 @@ -// 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 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 Header = Header; - type Index = u64; - type Lookup = IdentityLookup; - type MaxConsumers = frame_support::traits::ConstU32<16>; - type OnKilledAccount = (); - type OnNewAccount = (); - type OnSetCode = (); - type Origin = Origin; - type PalletInfo = PalletInfo; - type SS58Prefix = (); - type SystemWeightInfo = (); - type Version = (); -} - -parameter_types! { - pub ExistentialDeposit: Balance = 1; - pub const MaxLocks: u32 = 50; - pub const MaxReserves: u32 = 50; -} - -impl pallet_balances::Config for Runtime { - type AccountStore = System; - type Balance = Balance; - type DustRemoval = (); - type Event = Event; - type ExistentialDeposit = ExistentialDeposit; - type MaxLocks = MaxLocks; - type MaxReserves = MaxReserves; - type ReserveIdentifier = [u8; 8]; - type WeightInfo = (); -} - -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 AssetClaims = (); - type AssetTransactor = LocalAssetTransactor; - type AssetTrap = (); - type Barrier = Barrier; - type Call = Call; - type IsReserve = NativeAsset; - type IsTeleporter = (); - type LocationInverter = LocationInverter; - type OriginConverter = XcmOriginToCallOrigin; - type ResponseHandler = (); - type SubscriptionService = (); - type Trader = FixedRateOfFungible; - type Weigher = FixedWeightBounds; - type XcmSender = XcmRouter; -} - -#[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 AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; - type Call = Call; - type Event = Event; - type ExecuteXcmOrigin = EnsureXcmOrigin; - type LocationInverter = LocationInverter; - type Origin = Origin; - type SendXcmOrigin = EnsureXcmOrigin; - type Weigher = FixedWeightBounds; - type XcmExecuteFilter = Everything; - type XcmExecutor = XcmExecutor; - type XcmReserveTransferFilter = Everything; - type XcmRouter = XcmRouter; - type XcmTeleportFilter = Nothing; - - const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; -} - -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 deleted file mode 100644 index c1c9888e..00000000 --- a/runtime/common/src/message_router/mock/relay_chain.rs +++ /dev/null @@ -1,196 +0,0 @@ -// 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 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 Header = Header; - type Index = u64; - type Lookup = IdentityLookup; - type MaxConsumers = frame_support::traits::ConstU32<16>; - type OnKilledAccount = (); - type OnNewAccount = (); - type OnSetCode = (); - type Origin = Origin; - type PalletInfo = PalletInfo; - type SS58Prefix = (); - type SystemWeightInfo = (); - type Version = (); -} - -parameter_types! { - pub ExistentialDeposit: Balance = 1; - pub const MaxLocks: u32 = 50; - pub const MaxReserves: u32 = 50; -} - -impl pallet_balances::Config for Runtime { - type AccountStore = System; - type Balance = Balance; - type DustRemoval = (); - type Event = Event; - type ExistentialDeposit = ExistentialDeposit; - type MaxLocks = MaxLocks; - type MaxReserves = MaxReserves; - type ReserveIdentifier = [u8; 8]; - type WeightInfo = (); -} - -impl shared::Config for Runtime {} - -impl configuration::Config for Runtime { - 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 AssetClaims = (); - type AssetTransactor = LocalAssetTransactor; - type AssetTrap = (); - type Barrier = Barrier; - type Call = Call; - type IsReserve = (); - type IsTeleporter = (); - type LocationInverter = LocationInverter; - type OriginConverter = LocalOriginConverter; - type ResponseHandler = (); - type SubscriptionService = (); - type Trader = FixedRateOfFungible; - type Weigher = FixedWeightBounds; - type XcmSender = XcmRouter; -} - -pub type LocalOriginToLocation = SignedToAccountId32; - -impl pallet_xcm::Config for Runtime { - type AdvertisedXcmVersion = pallet_xcm::CurrentXcmVersion; - type Call = Call; - type Event = Event; - // Anyone can execute XCM messages locally... - type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin; - type LocationInverter = LocationInverter; - type Origin = Origin; - type SendXcmOrigin = xcm_builder::EnsureXcmOrigin; - type Weigher = FixedWeightBounds; - type XcmExecuteFilter = Nothing; - type XcmExecutor = XcmExecutor; - type XcmReserveTransferFilter = Everything; - type XcmRouter = XcmRouter; - type XcmTeleportFilter = Everything; - - const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; -} - -parameter_types! { - pub const FirstMessageFactorPercent: u64 = 100; -} - -impl ump::Config for Runtime { - type Event = Event; - type ExecuteOverweightOrigin = frame_system::EnsureRoot; - type FirstMessageFactorPercent = FirstMessageFactorPercent; - type UmpSink = ump::XcmSink, Runtime>; - 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}, - } -); From 40fd8564691205c7d780033d02457c34d032c849 Mon Sep 17 00:00:00 2001 From: Guantong <04637@163.com> Date: Fri, 23 Sep 2022 10:58:00 +0800 Subject: [PATCH 21/37] add comment for barrier --- runtime/common/src/message_router/barriers.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/runtime/common/src/message_router/barriers.rs b/runtime/common/src/message_router/barriers.rs index c09bf217..af69d4f1 100644 --- a/runtime/common/src/message_router/barriers.rs +++ b/runtime/common/src/message_router/barriers.rs @@ -28,6 +28,8 @@ use xcm_executor::traits::ShouldExecute; /// /// Only allows for `TeleportAsset`, `WithdrawAsset`, `ClaimAsset` and `ReserveAssetDeposit` XCMs /// because they are the only ones that place assets in the Holding Register to pay for execution. +/// Copy from https://github.com/paritytech/polkadot/blob/release-v0.9.26/xcm/xcm-builder/src/barriers.rs#L53 +/// Allow `DescendOrigin` as the first instruction to specify the payment account pub struct AllowDescendOriginPaidExecutionFrom(PhantomData); impl> ShouldExecute for AllowDescendOriginPaidExecutionFrom { fn should_execute( @@ -44,6 +46,7 @@ impl> ShouldExecute for AllowDescendOriginPaidExecuti ensure!(T::contains(origin), ()); let mut iter = message.0.iter_mut(); let i = iter.next().ok_or(())?; + // Modified: Only allows `DescendOrigin` as the first instruction match i { DescendOrigin(_) => (), _ => return Err(()), From 82640a8688dca4fd9775e3f56192ad5652d1a4c3 Mon Sep 17 00:00:00 2001 From: Guantong <04637@163.com> Date: Tue, 27 Sep 2022 14:15:05 +0800 Subject: [PATCH 22/37] Allow `DescendOrigin` for Astar --- runtime/crab-parachain/src/pallets/polkadot_xcm.rs | 5 +++++ runtime/darwinia-parachain/src/pallets/polkadot_xcm.rs | 5 +++++ runtime/pangolin-parachain/src/pallets/polkadot_xcm.rs | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/runtime/crab-parachain/src/pallets/polkadot_xcm.rs b/runtime/crab-parachain/src/pallets/polkadot_xcm.rs index 80d516a7..3291b0eb 100644 --- a/runtime/crab-parachain/src/pallets/polkadot_xcm.rs +++ b/runtime/crab-parachain/src/pallets/polkadot_xcm.rs @@ -132,6 +132,11 @@ frame_support::match_types! { MultiLocation { parents: 1, interior: X1(Parachain(2023)) + } | + // Astar Shiden Location + MultiLocation { + parents: 1, + interior: X1(Parachain(2007)) } }; } diff --git a/runtime/darwinia-parachain/src/pallets/polkadot_xcm.rs b/runtime/darwinia-parachain/src/pallets/polkadot_xcm.rs index d6b53062..f6f55c9a 100644 --- a/runtime/darwinia-parachain/src/pallets/polkadot_xcm.rs +++ b/runtime/darwinia-parachain/src/pallets/polkadot_xcm.rs @@ -132,6 +132,11 @@ frame_support::match_types! { MultiLocation { parents: 1, interior: X1(Parachain(2004)) + } | + // Astar Location + MultiLocation { + parents: 1, + interior: X1(Parachain(2006)) } }; } diff --git a/runtime/pangolin-parachain/src/pallets/polkadot_xcm.rs b/runtime/pangolin-parachain/src/pallets/polkadot_xcm.rs index 3b97394a..a31e2209 100644 --- a/runtime/pangolin-parachain/src/pallets/polkadot_xcm.rs +++ b/runtime/pangolin-parachain/src/pallets/polkadot_xcm.rs @@ -132,6 +132,11 @@ frame_support::match_types! { MultiLocation { parents: 1, interior: X1(Parachain(1000)) + } | + // Astar RocstarTestnet location + MultiLocation { + parents: 1, + interior: X1(Parachain(2006)) } }; } From 0bf60b9fba4d7ccba206a9c2b6d5ccfd5d825ae7 Mon Sep 17 00:00:00 2001 From: Guantong <04637@163.com> Date: Wed, 12 Oct 2022 13:38:33 +0800 Subject: [PATCH 23/37] Support alpha bridge  Conflicts:  runtime/pangolin-parachain/src/bridges_message/pangolin.rs --- .../src/bridges_message/pangolin.rs | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/runtime/pangolin-parachain/src/bridges_message/pangolin.rs b/runtime/pangolin-parachain/src/bridges_message/pangolin.rs index 644cffc5..0d367ca1 100644 --- a/runtime/pangolin-parachain/src/bridges_message/pangolin.rs +++ b/runtime/pangolin-parachain/src/bridges_message/pangolin.rs @@ -10,8 +10,8 @@ use crate::*; use bp_messages::{source_chain::*, target_chain::*, *}; use bp_runtime::*; use bridge_runtime_common::{ - lanes::PANGOLIN_PANGOLIN_PARACHAIN_LANE, - messages::{source::*, target::*, *}, + lanes::*, + messages::{self, source::*, target::*, BalanceOf, *}, }; use dp_common_runtime::FromThisChainMessageVerifier; @@ -71,7 +71,17 @@ impl MessageBridge for WithPangolinMessageBridge { const BRIDGED_MESSAGES_PALLET_NAME: &'static str = bp_pangolin_parachain::WITH_PANGOLIN_PARACHAIN_MESSAGES_PALLET_NAME; const RELAYER_FEE_PERCENT: u32 = 10; + #[cfg(not(feature = "alpha"))] const THIS_CHAIN_ID: ChainId = PANGOLIN_PARACHAIN_CHAIN_ID; + #[cfg(feature = "alpha")] + const THIS_CHAIN_ID: ChainId = PANGOLIN_PARACHAIN_ALPHA_CHAIN_ID; + + fn bridged_balance_to_this_balance( + bridged_balance: BalanceOf, + _bridged_to_this_conversion_rate: Option, + ) -> BalanceOf { + PangolinToPangolinParachainConversionRate::get().saturating_mul_int(bridged_balance) + } } #[derive(Clone, Copy, RuntimeDebug)] @@ -88,10 +98,16 @@ impl ThisChainWithMessages for PangolinParachain { type Call = Call; type Origin = Origin; + #[cfg(not(feature = "alpha"))] fn is_message_accepted(_send_origin: &Self::Origin, lane: &LaneId) -> bool { *lane == [0, 0, 0, 0] || *lane == [0, 0, 0, 1] || *lane == PANGOLIN_PANGOLIN_PARACHAIN_LANE } + #[cfg(feature = "alpha")] + fn is_message_accepted(_send_origin: &Self::Origin, lane: &LaneId) -> bool { + *lane == [0, 0, 0, 0] || *lane == [0, 0, 0, 1] || *lane == PANGOLIN_PANGOLIN_PARACHAIN_ALPHA_LANE + } + fn maximal_pending_messages_at_outbound_lane() -> MessageNonce { MessageNonce::MAX } From f98182e2f18838bbf0f224fc0b20506e77a4dfb8 Mon Sep 17 00:00:00 2001 From: Guantong <04637@163.com> Date: Sat, 1 Oct 2022 11:48:53 +0800 Subject: [PATCH 24/37] format --- runtime/pangolin-parachain/src/bridges_message/pangolin.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/runtime/pangolin-parachain/src/bridges_message/pangolin.rs b/runtime/pangolin-parachain/src/bridges_message/pangolin.rs index 0d367ca1..be42ea0f 100644 --- a/runtime/pangolin-parachain/src/bridges_message/pangolin.rs +++ b/runtime/pangolin-parachain/src/bridges_message/pangolin.rs @@ -105,7 +105,9 @@ impl ThisChainWithMessages for PangolinParachain { #[cfg(feature = "alpha")] fn is_message_accepted(_send_origin: &Self::Origin, lane: &LaneId) -> bool { - *lane == [0, 0, 0, 0] || *lane == [0, 0, 0, 1] || *lane == PANGOLIN_PANGOLIN_PARACHAIN_ALPHA_LANE + *lane == [0, 0, 0, 0] + || *lane == [0, 0, 0, 1] + || *lane == PANGOLIN_PANGOLIN_PARACHAIN_ALPHA_LANE } fn maximal_pending_messages_at_outbound_lane() -> MessageNonce { From 2a2a530186a1d0a71be373a1a2d411deb4078a5b Mon Sep 17 00:00:00 2001 From: Guantong <04637@163.com> Date: Wed, 12 Oct 2022 13:55:18 +0800 Subject: [PATCH 25/37] Fix compile after rebase --- Cargo.lock | 5 +++++ runtime/common/Cargo.toml | 1 - .../pangolin-parachain/src/bridges_message/pangolin.rs | 9 +-------- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 49c51546..6ea0416d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2451,7 +2451,11 @@ dependencies = [ "pallet-fee-market", "pallet-timestamp", "pallet-transaction-payment", + "pallet-xcm", "parity-scale-codec 3.2.1", + "polkadot-core-primitives", + "polkadot-parachain", + "polkadot-runtime-parachains", "scale-info", "smallvec", "sp-core", @@ -2459,6 +2463,7 @@ dependencies = [ "sp-runtime", "sp-std", "xcm", + "xcm-builder", "xcm-executor", ] diff --git a/runtime/common/Cargo.toml b/runtime/common/Cargo.toml index 59ae3ffb..6c45a0ef 100644 --- a/runtime/common/Cargo.toml +++ b/runtime/common/Cargo.toml @@ -45,7 +45,6 @@ polkadot-runtime-parachains = { default-features = false, git = "https://github. 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" } diff --git a/runtime/pangolin-parachain/src/bridges_message/pangolin.rs b/runtime/pangolin-parachain/src/bridges_message/pangolin.rs index be42ea0f..00dc8069 100644 --- a/runtime/pangolin-parachain/src/bridges_message/pangolin.rs +++ b/runtime/pangolin-parachain/src/bridges_message/pangolin.rs @@ -11,7 +11,7 @@ use bp_messages::{source_chain::*, target_chain::*, *}; use bp_runtime::*; use bridge_runtime_common::{ lanes::*, - messages::{self, source::*, target::*, BalanceOf, *}, + messages::{source::*, target::*, *}, }; use dp_common_runtime::FromThisChainMessageVerifier; @@ -75,13 +75,6 @@ impl MessageBridge for WithPangolinMessageBridge { const THIS_CHAIN_ID: ChainId = PANGOLIN_PARACHAIN_CHAIN_ID; #[cfg(feature = "alpha")] const THIS_CHAIN_ID: ChainId = PANGOLIN_PARACHAIN_ALPHA_CHAIN_ID; - - fn bridged_balance_to_this_balance( - bridged_balance: BalanceOf, - _bridged_to_this_conversion_rate: Option, - ) -> BalanceOf { - PangolinToPangolinParachainConversionRate::get().saturating_mul_int(bridged_balance) - } } #[derive(Clone, Copy, RuntimeDebug)] From 5b9054f4de95e080d8508cebec40482298eb49a3 Mon Sep 17 00:00:00 2001 From: Guantong <04637@163.com> Date: Thu, 13 Oct 2022 11:37:12 +0800 Subject: [PATCH 26/37] fix pangolin parachain alpha bridge --- Cargo.lock | 54 ++++++++++++------- runtime/pangolin-parachain/Cargo.toml | 23 ++++---- .../src/bridges_message/pangolin.rs | 4 ++ 3 files changed, 51 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6ea0416d..da77b45c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -689,7 +689,7 @@ dependencies = [ [[package]] name = "bp-crab" version = "0.1.0" -source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#584bc52933ce28d4a16a442fd66227410594c178" +source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#fda68630945112553da5fafae8c21609bc86f36c" dependencies = [ "bp-darwinia-core", "bp-messages", @@ -704,7 +704,7 @@ dependencies = [ [[package]] name = "bp-crab-parachain" version = "0.1.0" -source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#584bc52933ce28d4a16a442fd66227410594c178" +source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#fda68630945112553da5fafae8c21609bc86f36c" dependencies = [ "bp-darwinia-core", "bp-messages", @@ -719,7 +719,7 @@ dependencies = [ [[package]] name = "bp-darwinia-core" version = "0.1.0" -source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#584bc52933ce28d4a16a442fd66227410594c178" +source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#fda68630945112553da5fafae8c21609bc86f36c" dependencies = [ "bp-messages", "bp-runtime", @@ -735,7 +735,7 @@ dependencies = [ [[package]] name = "bp-header-chain" version = "0.1.0" -source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#584bc52933ce28d4a16a442fd66227410594c178" +source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#fda68630945112553da5fafae8c21609bc86f36c" dependencies = [ "bp-runtime", "finality-grandpa", @@ -752,7 +752,7 @@ dependencies = [ [[package]] name = "bp-message-dispatch" version = "0.1.0" -source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#584bc52933ce28d4a16a442fd66227410594c178" +source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#fda68630945112553da5fafae8c21609bc86f36c" dependencies = [ "bp-runtime", "frame-support", @@ -765,7 +765,7 @@ dependencies = [ [[package]] name = "bp-messages" version = "0.1.0" -source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#584bc52933ce28d4a16a442fd66227410594c178" +source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#fda68630945112553da5fafae8c21609bc86f36c" dependencies = [ "bitvec 1.0.1", "bp-runtime", @@ -782,7 +782,7 @@ dependencies = [ [[package]] name = "bp-pangolin" version = "0.1.0" -source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#584bc52933ce28d4a16a442fd66227410594c178" +source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#fda68630945112553da5fafae8c21609bc86f36c" dependencies = [ "bp-darwinia-core", "bp-messages", @@ -797,7 +797,22 @@ dependencies = [ [[package]] name = "bp-pangolin-parachain" version = "0.1.0" -source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#584bc52933ce28d4a16a442fd66227410594c178" +source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#fda68630945112553da5fafae8c21609bc86f36c" +dependencies = [ + "bp-darwinia-core", + "bp-messages", + "bp-runtime", + "frame-support", + "sp-api", + "sp-runtime", + "sp-std", + "sp-version", +] + +[[package]] +name = "bp-pangolin-parachain-alpha" +version = "0.1.0" +source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#fda68630945112553da5fafae8c21609bc86f36c" dependencies = [ "bp-darwinia-core", "bp-messages", @@ -812,7 +827,7 @@ dependencies = [ [[package]] name = "bp-parachains" version = "0.1.0" -source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#584bc52933ce28d4a16a442fd66227410594c178" +source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#fda68630945112553da5fafae8c21609bc86f36c" dependencies = [ "bp-polkadot-core", "bp-runtime", @@ -826,7 +841,7 @@ dependencies = [ [[package]] name = "bp-polkadot-core" version = "0.1.0" -source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#584bc52933ce28d4a16a442fd66227410594c178" +source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#fda68630945112553da5fafae8c21609bc86f36c" dependencies = [ "bp-messages", "bp-runtime", @@ -846,7 +861,7 @@ dependencies = [ [[package]] name = "bp-runtime" version = "0.1.0" -source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#584bc52933ce28d4a16a442fd66227410594c178" +source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#fda68630945112553da5fafae8c21609bc86f36c" dependencies = [ "frame-support", "hash-db", @@ -864,7 +879,7 @@ dependencies = [ [[package]] name = "bp-test-utils" version = "0.1.0" -source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#584bc52933ce28d4a16a442fd66227410594c178" +source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#fda68630945112553da5fafae8c21609bc86f36c" dependencies = [ "bp-header-chain", "ed25519-dalek", @@ -879,7 +894,7 @@ dependencies = [ [[package]] name = "bridge-runtime-common" version = "0.1.0" -source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#584bc52933ce28d4a16a442fd66227410594c178" +source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#fda68630945112553da5fafae8c21609bc86f36c" dependencies = [ "bp-message-dispatch", "bp-messages", @@ -5648,7 +5663,7 @@ dependencies = [ [[package]] name = "pallet-bridge-dispatch" version = "0.1.0" -source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#584bc52933ce28d4a16a442fd66227410594c178" +source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#fda68630945112553da5fafae8c21609bc86f36c" dependencies = [ "bp-message-dispatch", "bp-runtime", @@ -5665,7 +5680,7 @@ dependencies = [ [[package]] name = "pallet-bridge-grandpa" version = "0.1.0" -source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#584bc52933ce28d4a16a442fd66227410594c178" +source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#fda68630945112553da5fafae8c21609bc86f36c" dependencies = [ "bp-header-chain", "bp-runtime", @@ -5688,7 +5703,7 @@ dependencies = [ [[package]] name = "pallet-bridge-messages" version = "0.1.0" -source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#584bc52933ce28d4a16a442fd66227410594c178" +source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#fda68630945112553da5fafae8c21609bc86f36c" dependencies = [ "bitvec 1.0.1", "bp-message-dispatch", @@ -5710,7 +5725,7 @@ dependencies = [ [[package]] name = "pallet-bridge-parachains" version = "0.1.0" -source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#584bc52933ce28d4a16a442fd66227410594c178" +source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#fda68630945112553da5fafae8c21609bc86f36c" dependencies = [ "bp-parachains", "bp-polkadot-core", @@ -5857,7 +5872,7 @@ dependencies = [ [[package]] name = "pallet-fee-market" version = "0.1.0" -source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#584bc52933ce28d4a16a442fd66227410594c178" +source = "git+https://github.com/darwinia-network/darwinia-messages-substrate?branch=polkadot-v0.9.27#fda68630945112553da5fafae8c21609bc86f36c" dependencies = [ "bp-messages", "bp-runtime", @@ -6457,6 +6472,7 @@ dependencies = [ "bp-messages", "bp-pangolin", "bp-pangolin-parachain", + "bp-pangolin-parachain-alpha", "bp-polkadot-core", "bp-runtime", "bridge-runtime-common", @@ -11669,7 +11685,7 @@ version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 0.1.10", "digest 0.10.5", "rand 0.8.5", "static_assertions", diff --git a/runtime/pangolin-parachain/Cargo.toml b/runtime/pangolin-parachain/Cargo.toml index 574b57ca..856fa504 100644 --- a/runtime/pangolin-parachain/Cargo.toml +++ b/runtime/pangolin-parachain/Cargo.toml @@ -31,17 +31,18 @@ parachain-info = { default-features = false, git = "https://git dc-primitives = { default-features = false, path = "../../primitives" } dp-common-runtime = { default-features = false, path = "../common" } # darwinia-messages-substrate -bp-message-dispatch = { default-features = false, git = "https://github.com/darwinia-network/darwinia-messages-substrate", branch = "polkadot-v0.9.27" } -bp-messages = { default-features = false, git = "https://github.com/darwinia-network/darwinia-messages-substrate", branch = "polkadot-v0.9.27" } -bp-pangolin = { default-features = false, git = "https://github.com/darwinia-network/darwinia-messages-substrate", branch = "polkadot-v0.9.27" } -bp-pangolin-parachain = { default-features = false, git = "https://github.com/darwinia-network/darwinia-messages-substrate", branch = "polkadot-v0.9.27" } -bp-polkadot-core = { default-features = false, git = "https://github.com/darwinia-network/darwinia-messages-substrate", branch = "polkadot-v0.9.27" } -bp-runtime = { default-features = false, git = "https://github.com/darwinia-network/darwinia-messages-substrate", branch = "polkadot-v0.9.27" } -bridge-runtime-common = { default-features = false, git = "https://github.com/darwinia-network/darwinia-messages-substrate", branch = "polkadot-v0.9.27" } -pallet-bridge-dispatch = { default-features = false, git = "https://github.com/darwinia-network/darwinia-messages-substrate", branch = "polkadot-v0.9.27" } -pallet-bridge-grandpa = { default-features = false, git = "https://github.com/darwinia-network/darwinia-messages-substrate", branch = "polkadot-v0.9.27" } -pallet-bridge-messages = { default-features = false, git = "https://github.com/darwinia-network/darwinia-messages-substrate", branch = "polkadot-v0.9.27" } -pallet-fee-market = { default-features = false, git = "https://github.com/darwinia-network/darwinia-messages-substrate", branch = "polkadot-v0.9.27" } +bp-message-dispatch = { default-features = false, git = "https://github.com/darwinia-network/darwinia-messages-substrate", branch = "polkadot-v0.9.27" } +bp-messages = { default-features = false, git = "https://github.com/darwinia-network/darwinia-messages-substrate", branch = "polkadot-v0.9.27" } +bp-pangolin = { default-features = false, git = "https://github.com/darwinia-network/darwinia-messages-substrate", branch = "polkadot-v0.9.27" } +bp-pangolin-parachain = { default-features = false, git = "https://github.com/darwinia-network/darwinia-messages-substrate", branch = "polkadot-v0.9.27" } +bp-pangolin-parachain-alpha = { default-features = false, git = "https://github.com/darwinia-network/darwinia-messages-substrate", branch = "polkadot-v0.9.27" } +bp-polkadot-core = { default-features = false, git = "https://github.com/darwinia-network/darwinia-messages-substrate", branch = "polkadot-v0.9.27" } +bp-runtime = { default-features = false, git = "https://github.com/darwinia-network/darwinia-messages-substrate", branch = "polkadot-v0.9.27" } +bridge-runtime-common = { default-features = false, git = "https://github.com/darwinia-network/darwinia-messages-substrate", branch = "polkadot-v0.9.27" } +pallet-bridge-dispatch = { default-features = false, git = "https://github.com/darwinia-network/darwinia-messages-substrate", branch = "polkadot-v0.9.27" } +pallet-bridge-grandpa = { default-features = false, git = "https://github.com/darwinia-network/darwinia-messages-substrate", branch = "polkadot-v0.9.27" } +pallet-bridge-messages = { default-features = false, git = "https://github.com/darwinia-network/darwinia-messages-substrate", branch = "polkadot-v0.9.27" } +pallet-fee-market = { default-features = false, git = "https://github.com/darwinia-network/darwinia-messages-substrate", branch = "polkadot-v0.9.27" } # polkadot pallet-xcm = { default-features = false, git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.27" } pallet-xcm-benchmarks = { optional = true, default-features = false, git = "https://github.com/paritytech/polkadot", branch = "release-v0.9.27" } diff --git a/runtime/pangolin-parachain/src/bridges_message/pangolin.rs b/runtime/pangolin-parachain/src/bridges_message/pangolin.rs index 00dc8069..92717b6a 100644 --- a/runtime/pangolin-parachain/src/bridges_message/pangolin.rs +++ b/runtime/pangolin-parachain/src/bridges_message/pangolin.rs @@ -68,8 +68,12 @@ impl MessageBridge for WithPangolinMessageBridge { type ThisChain = PangolinParachain; const BRIDGED_CHAIN_ID: ChainId = PANGOLIN_CHAIN_ID; + #[cfg(not(feature = "alpha"))] const BRIDGED_MESSAGES_PALLET_NAME: &'static str = bp_pangolin_parachain::WITH_PANGOLIN_PARACHAIN_MESSAGES_PALLET_NAME; + #[cfg(feature = "alpha")] + const BRIDGED_MESSAGES_PALLET_NAME: &'static str = + bp_pangolin_parachain_alpha::WITH_PANGOLIN_PARACHAIN_MESSAGES_PALLET_NAME; const RELAYER_FEE_PERCENT: u32 = 10; #[cfg(not(feature = "alpha"))] const THIS_CHAIN_ID: ChainId = PANGOLIN_PARACHAIN_CHAIN_ID; From e83111c577ffefd669c318097ae37e15370a825f Mon Sep 17 00:00:00 2001 From: Guantong <04637@163.com> Date: Mon, 17 Oct 2022 16:35:15 +0800 Subject: [PATCH 27/37] Adapt to multiple targets --- runtime/common/src/message_router/mod.rs | 80 +++++++++++++------- runtime/common/src/message_router/weights.rs | 6 +- 2 files changed, 54 insertions(+), 32 deletions(-) diff --git a/runtime/common/src/message_router/mod.rs b/runtime/common/src/message_router/mod.rs index 0dc6b29c..dc66893d 100644 --- a/runtime/common/src/message_router/mod.rs +++ b/runtime/common/src/message_router/mod.rs @@ -31,6 +31,12 @@ use xcm_executor::traits::WeightBounds; pub type AssetUnitsPerSecond = u128; +/// router target +#[derive(Clone, Encode, Decode, TypeInfo, PartialEq, Debug)] +pub enum Target { + Moonbeam, +} + #[frame_support::pallet] pub mod pallet { use super::*; @@ -68,7 +74,7 @@ pub mod pallet { target_location: MultiLocation, local_asset_units_per_second: AssetUnitsPerSecond, }, - RouteToMoonbeam(MultiLocation, Xcm<()>, Weight, u128), + ForwardTo(MultiLocation, Target, Xcm<()>, Weight, u128), } #[pallet::error] @@ -124,10 +130,11 @@ pub mod pallet { } #[pallet::weight( - ::WeightInfo::forward_to_moonbeam() + ::WeightInfo::forward() )] - pub fn forward_to_moonbeam( + pub fn forward( origin: OriginFor, + target: Target, message: Box::Call>>, ) -> DispatchResultWithPostInfo { // MultiLocation origin used to execute xcm @@ -137,30 +144,41 @@ pub mod pallet { let account_u8 = <[u8; 32]>::try_from(account_id.encode()) .map_err(|_| Error::::AccountIdConversionFailed)?; - let remote_xcm: Xcm<::Call> = + let mut remote_xcm: Xcm<::Call> = (*message).try_into().map_err(|()| Error::::BadVersion)?; // Calculate the execution fee required for remote xcm execution // fee = fee_per_second * (weight/weight_per_second) - 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( - account_u8.clone(), - remote_xcm.clone(), - MultiAsset { id: AssetId::from(T::LocalAssetId::get()), fun: Fungible(0) }, - )) - .map_err(|()| Error::::UnweighableMessage)?; + let local_asset_units_per_second: AssetUnitsPerSecond; + let remote_weight: Weight; + match target { + Target::Moonbeam => { + local_asset_units_per_second = + TargetXcmExecConfig::::get(T::MoonbeamLocation::get()) + .ok_or(Error::::TargetXcmExecNotConfig)?; + 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) }, + )) + .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(), - }]); + // Transfer xcm execution fee to target sovereign account + let mut local_xcm; + match target { + Target::Moonbeam => { + 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( @@ -178,18 +196,22 @@ pub mod pallet { // 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 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()) - .map_err(|_| Error::::XcmSendFailed)?; - - Self::deposit_event(Event::RouteToMoonbeam( + match target { + Target::Moonbeam => { + remote_xcm_fee_anchor_dest + .reanchor(&T::MoonbeamLocation::get(), &ancestry) + .map_err(|()| Error::::MultiLocationFull)?; + 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()) + .map_err(|_| Error::::XcmSendFailed)?; + }, + } + + Self::deposit_event(Event::ForwardTo( origin_location, + target, remote_xcm.into(), remote_weight, amount, diff --git a/runtime/common/src/message_router/weights.rs b/runtime/common/src/message_router/weights.rs index 2b8444fa..059fc4f4 100644 --- a/runtime/common/src/message_router/weights.rs +++ b/runtime/common/src/message_router/weights.rs @@ -56,7 +56,7 @@ use sp_std::marker::PhantomData; pub trait WeightInfo { fn set_target_xcm_exec_config() -> Weight; - fn forward_to_moonbeam() -> Weight; + fn forward() -> Weight; } /// Weight functions for `message_router`. @@ -74,7 +74,7 @@ impl WeightInfo for SubstrateWeightInfo { // 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 { + fn forward() -> Weight { (37_239_000 as Weight) .saturating_add(T::DbWeight::get().reads(8 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) @@ -94,7 +94,7 @@ impl WeightInfo for () { // 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 { + fn forward() -> Weight { (37_239_000 as Weight) .saturating_add(RocksDbWeight::get().reads(8 as Weight)) .saturating_add(RocksDbWeight::get().writes(1 as Weight)) From bfac62d14c9678812469f4a1cde42c556be00cb9 Mon Sep 17 00:00:00 2001 From: Guantong <04637@163.com> Date: Tue, 18 Oct 2022 11:26:21 +0800 Subject: [PATCH 28/37] add xcm fee limit --- runtime/common/src/message_router/mod.rs | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/runtime/common/src/message_router/mod.rs b/runtime/common/src/message_router/mod.rs index dc66893d..08f83ce9 100644 --- a/runtime/common/src/message_router/mod.rs +++ b/runtime/common/src/message_router/mod.rs @@ -30,6 +30,8 @@ use xcm::prelude::*; use xcm_executor::traits::WeightBounds; pub type AssetUnitsPerSecond = u128; +/// Fee type of xcm message fee, paid on this chain. +pub type XcmFee = u128; /// router target #[derive(Clone, Encode, Decode, TypeInfo, PartialEq, Debug)] @@ -74,7 +76,7 @@ pub mod pallet { target_location: MultiLocation, local_asset_units_per_second: AssetUnitsPerSecond, }, - ForwardTo(MultiLocation, Target, Xcm<()>, Weight, u128), + ForwardTo(MultiLocation, Target, Xcm<()>, Weight, XcmFee), } #[pallet::error] @@ -83,14 +85,17 @@ pub mod pallet { TargetXcmExecNotConfig, /// The message's weight could not be determined. UnweighableMessage, - /// XCM execution failed. https://github.com/paritytech/substrate/pull/10242 - XcmExecutionFailed, + /// Failed to transfer xcm fee. + FailedPayXcmFee, BadVersion, /// MultiLocation value too large to descend further. MultiLocationFull, /// Failed to send xcm. XcmSendFailed, + /// Failed to convert account id to [u8; 32]. AccountIdConversionFailed, + /// When the `xcm_fee_limit` is less than required. + TooExpensive, } /// Stores the units per second executed by the target chain for local asset(e.g. CRAB). @@ -136,6 +141,7 @@ pub mod pallet { origin: OriginFor, target: Target, message: Box::Call>>, + xcm_fee_limit: Option, ) -> DispatchResultWithPostInfo { // MultiLocation origin used to execute xcm let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin.clone())?; @@ -164,8 +170,12 @@ pub mod pallet { .map_err(|()| Error::::UnweighableMessage)?; }, } - let amount = local_asset_units_per_second.saturating_mul(remote_weight as u128) - / (WEIGHT_PER_SECOND as u128); + let amount: XcmFee = local_asset_units_per_second + .saturating_mul(remote_weight as XcmFee) + / (WEIGHT_PER_SECOND as XcmFee); + if let Some(fee_limit) = xcm_fee_limit { + ensure!(amount <= fee_limit, Error::::TooExpensive); + } let remote_xcm_fee = MultiAsset { id: AssetId::from(T::LocalAssetId::get()), fun: Fungible(amount) }; @@ -189,8 +199,8 @@ pub mod pallet { ) .ensure_complete() .map_err(|error| { - log::error!("Failed execute route message with {:?}", error); - Error::::XcmExecutionFailed + log::error!("Failed transfer xcm fee with {:?}", error); + Error::::FailedPayXcmFee })?; // Toggle the xcm_fee relative to a target context From d6c38a9b6b8e597b253a1bc91f492ca7b1d67934 Mon Sep 17 00:00:00 2001 From: Guantong <04637@163.com> Date: Tue, 18 Oct 2022 14:11:41 +0800 Subject: [PATCH 29/37] Revert "add xcm fee limit" This reverts commit bfac62d14c9678812469f4a1cde42c556be00cb9. --- runtime/common/src/message_router/mod.rs | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) diff --git a/runtime/common/src/message_router/mod.rs b/runtime/common/src/message_router/mod.rs index 08f83ce9..dc66893d 100644 --- a/runtime/common/src/message_router/mod.rs +++ b/runtime/common/src/message_router/mod.rs @@ -30,8 +30,6 @@ use xcm::prelude::*; use xcm_executor::traits::WeightBounds; pub type AssetUnitsPerSecond = u128; -/// Fee type of xcm message fee, paid on this chain. -pub type XcmFee = u128; /// router target #[derive(Clone, Encode, Decode, TypeInfo, PartialEq, Debug)] @@ -76,7 +74,7 @@ pub mod pallet { target_location: MultiLocation, local_asset_units_per_second: AssetUnitsPerSecond, }, - ForwardTo(MultiLocation, Target, Xcm<()>, Weight, XcmFee), + ForwardTo(MultiLocation, Target, Xcm<()>, Weight, u128), } #[pallet::error] @@ -85,17 +83,14 @@ pub mod pallet { TargetXcmExecNotConfig, /// The message's weight could not be determined. UnweighableMessage, - /// Failed to transfer xcm fee. - FailedPayXcmFee, + /// 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, - /// Failed to convert account id to [u8; 32]. AccountIdConversionFailed, - /// When the `xcm_fee_limit` is less than required. - TooExpensive, } /// Stores the units per second executed by the target chain for local asset(e.g. CRAB). @@ -141,7 +136,6 @@ pub mod pallet { origin: OriginFor, target: Target, message: Box::Call>>, - xcm_fee_limit: Option, ) -> DispatchResultWithPostInfo { // MultiLocation origin used to execute xcm let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin.clone())?; @@ -170,12 +164,8 @@ pub mod pallet { .map_err(|()| Error::::UnweighableMessage)?; }, } - let amount: XcmFee = local_asset_units_per_second - .saturating_mul(remote_weight as XcmFee) - / (WEIGHT_PER_SECOND as XcmFee); - if let Some(fee_limit) = xcm_fee_limit { - ensure!(amount <= fee_limit, Error::::TooExpensive); - } + 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) }; @@ -199,8 +189,8 @@ pub mod pallet { ) .ensure_complete() .map_err(|error| { - log::error!("Failed transfer xcm fee with {:?}", error); - Error::::FailedPayXcmFee + log::error!("Failed execute route message with {:?}", error); + Error::::XcmExecutionFailed })?; // Toggle the xcm_fee relative to a target context From de2543718e0be1939f28e03fc5c3e911eefeb24e Mon Sep 17 00:00:00 2001 From: Guantong <04637@163.com> Date: Tue, 18 Oct 2022 14:13:39 +0800 Subject: [PATCH 30/37] update comment --- runtime/common/src/message_router/mod.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/runtime/common/src/message_router/mod.rs b/runtime/common/src/message_router/mod.rs index dc66893d..3347e765 100644 --- a/runtime/common/src/message_router/mod.rs +++ b/runtime/common/src/message_router/mod.rs @@ -83,13 +83,14 @@ pub mod pallet { TargetXcmExecNotConfig, /// The message's weight could not be determined. UnweighableMessage, - /// XCM execution failed. https://github.com/paritytech/substrate/pull/10242 - XcmExecutionFailed, + /// Failed to transfer xcm fee. + FailedPayXcmFee, BadVersion, /// MultiLocation value too large to descend further. MultiLocationFull, /// Failed to send xcm. XcmSendFailed, + /// Failed to convert account id to [u8; 32]. AccountIdConversionFailed, } @@ -189,8 +190,8 @@ pub mod pallet { ) .ensure_complete() .map_err(|error| { - log::error!("Failed execute route message with {:?}", error); - Error::::XcmExecutionFailed + log::error!("Failed transfer xcm fee with {:?}", error); + Error::::FailedPayXcmFee })?; // Toggle the xcm_fee relative to a target context From c5b60edbd1d1d1cc4bf7c429de6551ace7e9d2de Mon Sep 17 00:00:00 2001 From: Guantong <04637@163.com> Date: Wed, 19 Oct 2022 11:01:42 +0800 Subject: [PATCH 31/37] remove useless config and sort --- runtime/common/src/message_router/mod.rs | 19 +++++++++---------- .../src/pallets/message_router.rs | 3 +-- .../src/pallets/message_router.rs | 3 +-- .../src/pallets/message_router.rs | 3 +-- 4 files changed, 12 insertions(+), 16 deletions(-) diff --git a/runtime/common/src/message_router/mod.rs b/runtime/common/src/message_router/mod.rs index 3347e765..6330d18f 100644 --- a/runtime/common/src/message_router/mod.rs +++ b/runtime/common/src/message_router/mod.rs @@ -48,22 +48,21 @@ pub mod pallet { #[pallet::config] pub trait Config: frame_system::Config { + type ConfigModifierOrigin: EnsureOrigin; type Event: From> + IsType<::Event>; - type AssetModifierOrigin: EnsureOrigin; - 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 LocalAssetId: Get; + type LocalWeigher: WeightBounds; + type LocationInverter: InvertLocation; + type MoonbeamLocation: Get; + type MoonbeamWeigher: WeightBounds; + type SelfLocationInSibl: Get; + type WeightInfo: WeightInfo; type XcmExecutor: ExecuteXcm; type XcmSender: SendXcm; - type WeightInfo: WeightInfo; } #[pallet::event] @@ -118,7 +117,7 @@ pub mod pallet { target_location: MultiLocation, local_asset_units_per_second: AssetUnitsPerSecond, ) -> DispatchResultWithPostInfo { - T::AssetModifierOrigin::ensure_origin(origin)?; + T::ConfigModifierOrigin::ensure_origin(origin)?; TargetXcmExecConfig::::insert(&target_location, &local_asset_units_per_second); diff --git a/runtime/crab-parachain/src/pallets/message_router.rs b/runtime/crab-parachain/src/pallets/message_router.rs index de4d5fae..deaed74b 100644 --- a/runtime/crab-parachain/src/pallets/message_router.rs +++ b/runtime/crab-parachain/src/pallets/message_router.rs @@ -27,8 +27,7 @@ frame_support::parameter_types! { } impl Config for Runtime { - type AssetModifierOrigin = EnsureRoot; - type AssetTransactor = LocalAssetTransactor; + type ConfigModifierOrigin = EnsureRoot; type Event = Event; type ExecuteXcmOrigin = EnsureXcmOrigin; type LocalAssetId = AnchoringSelfReserve; diff --git a/runtime/darwinia-parachain/src/pallets/message_router.rs b/runtime/darwinia-parachain/src/pallets/message_router.rs index c1b44292..37c26ab6 100644 --- a/runtime/darwinia-parachain/src/pallets/message_router.rs +++ b/runtime/darwinia-parachain/src/pallets/message_router.rs @@ -27,8 +27,7 @@ frame_support::parameter_types! { } impl Config for Runtime { - type AssetModifierOrigin = EnsureRoot; - type AssetTransactor = LocalAssetTransactor; + type ConfigModifierOrigin = EnsureRoot; type Event = Event; type ExecuteXcmOrigin = EnsureXcmOrigin; type LocalAssetId = AnchoringSelfReserve; diff --git a/runtime/pangolin-parachain/src/pallets/message_router.rs b/runtime/pangolin-parachain/src/pallets/message_router.rs index 976b81d6..0136d6d6 100644 --- a/runtime/pangolin-parachain/src/pallets/message_router.rs +++ b/runtime/pangolin-parachain/src/pallets/message_router.rs @@ -27,8 +27,7 @@ frame_support::parameter_types! { } impl Config for Runtime { - type AssetModifierOrigin = EnsureRoot; - type AssetTransactor = LocalAssetTransactor; + type ConfigModifierOrigin = EnsureRoot; type Event = Event; type ExecuteXcmOrigin = EnsureXcmOrigin; type LocalAssetId = AnchoringSelfReserve; From 4d4870958c8cf2de41890058bbc22b6612471cca Mon Sep 17 00:00:00 2001 From: Guantong <04637@163.com> Date: Wed, 19 Oct 2022 11:46:12 +0800 Subject: [PATCH 32/37] add comments --- .../src/message_router/location_conversion.rs | 3 +++ runtime/common/src/message_router/mod.rs | 22 +++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/runtime/common/src/message_router/location_conversion.rs b/runtime/common/src/message_router/location_conversion.rs index 90e444bb..7f0b58e4 100644 --- a/runtime/common/src/message_router/location_conversion.rs +++ b/runtime/common/src/message_router/location_conversion.rs @@ -23,11 +23,14 @@ use xcm_executor::traits::Convert; /// The address prefix for dvm address const ADDR_PREFIX: &[u8] = b"dvm:"; +/// Derive AccountKey20 in MultiLocation to AccountId32 +/// Refer to https://github.com/darwinia-network/darwinia-common/blob/main/frame/support/src/evm.rs#L85 pub struct AccountKey20Derive(PhantomData); impl + Into<[u8; 32]> + Clone> Convert for AccountKey20Derive { fn convert(location: MultiLocation) -> Result { + // Extract AccountKey20 from MultiLocation let key = match location { MultiLocation { parents: 0, interior: X1(AccountKey20 { key, network: _ }) } => key, MultiLocation { diff --git a/runtime/common/src/message_router/mod.rs b/runtime/common/src/message_router/mod.rs index 6330d18f..f5f048ee 100644 --- a/runtime/common/src/message_router/mod.rs +++ b/runtime/common/src/message_router/mod.rs @@ -44,21 +44,26 @@ pub mod pallet { 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 xcm_executor::traits::InvertLocation; #[pallet::config] pub trait Config: frame_system::Config { type ConfigModifierOrigin: EnsureOrigin; type Event: From> + IsType<::Event>; + /// Required origin for executing XCM messages. type ExecuteXcmOrigin: EnsureOrigin< ::Origin, Success = MultiLocation, >; type LocalAssetId: Get; + /// Used to calculate the weight required for the local execution of xcm. type LocalWeigher: WeightBounds; + /// Means of inverting a location. type LocationInverter: InvertLocation; type MoonbeamLocation: Get; + /// Used to calculate the weight required for the moonbeam execution of xcm. type MoonbeamWeigher: WeightBounds; + /// This chain location relative to sibling chain type SelfLocationInSibl: Get; type WeightInfo: WeightInfo; type XcmExecutor: ExecuteXcm; @@ -73,6 +78,8 @@ pub mod pallet { target_location: MultiLocation, local_asset_units_per_second: AssetUnitsPerSecond, }, + /// Deposited when successfully routed. + /// (send origin, route target, remote xcm, required weight, tokens used) ForwardTo(MultiLocation, Target, Xcm<()>, Weight, u128), } @@ -94,7 +101,7 @@ pub mod pallet { } /// 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. + /// This is used to know how to pay for XCM execution use local asset. /// For example: /// key: {parents: 1, Parachain(2023)}, val: 14719736222326895902025 /// represents the units per second of CRAB token on moonriver @@ -109,6 +116,7 @@ pub mod pallet { #[pallet::call] impl Pallet { + /// Update the units per second of local asset used in target chain. #[pallet::weight( ::WeightInfo::set_target_xcm_exec_config() )] @@ -129,6 +137,11 @@ pub mod pallet { Ok(().into()) } + /// Deliver received LCMP messages to other parachains. + /// 1. Calculate the fee for xcm remote execution + /// 2. Transfer xcm fee to target sovereign account + /// 3. Assemble xcm that needs to be executed remotely + /// 4. Send xcm to target chain #[pallet::weight( ::WeightInfo::forward() )] @@ -140,7 +153,7 @@ pub mod pallet { // MultiLocation origin used to execute xcm let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin.clone())?; let account_id = ensure_signed(origin)?; - // u8 account used in DescendOrigin instruction + // U8 account used in DescendOrigin instruction let account_u8 = <[u8; 32]>::try_from(account_id.encode()) .map_err(|_| Error::::AccountIdConversionFailed)?; @@ -221,7 +234,7 @@ pub mod pallet { } impl Pallet { - /// Extend xcm to pay for remote execution + /// Extend xcm for remote execution fn extend_remote_xcm( account_u8: [u8; 32], xcm: Xcm<::Call>, @@ -230,6 +243,7 @@ pub mod pallet { let mut extend_xcm = Xcm(vec![ ReserveAssetDeposited(fee.clone().into()), BuyExecution { fees: fee, weight_limit: WeightLimit::Unlimited }, + // Deposit surplus tokens back into our sovereign account SetAppendix(Xcm(vec![ RefundSurplus, DepositAsset { From 3af655e0bd12bb481486879e030eb000bd0acd87 Mon Sep 17 00:00:00 2001 From: Guantong <04637@163.com> Date: Wed, 19 Oct 2022 12:39:14 +0800 Subject: [PATCH 33/37] update comment --- 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 f5f048ee..0d40f6a3 100644 --- a/runtime/common/src/message_router/mod.rs +++ b/runtime/common/src/message_router/mod.rs @@ -101,7 +101,7 @@ pub mod pallet { } /// Stores the units per second executed by the target chain for local asset(e.g. CRAB). - /// This is used to know how to pay for XCM execution use local asset. + /// This is used to know how to pay for XCM remote execution use local asset. /// For example: /// key: {parents: 1, Parachain(2023)}, val: 14719736222326895902025 /// represents the units per second of CRAB token on moonriver From 0b765221da39d6ddfbe4ac9c673edfa796e18980 Mon Sep 17 00:00:00 2001 From: Guantong <04637@163.com> Date: Wed, 19 Oct 2022 14:25:07 +0800 Subject: [PATCH 34/37] account_u8 to raw_account --- runtime/common/src/message_router/mod.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/runtime/common/src/message_router/mod.rs b/runtime/common/src/message_router/mod.rs index 0d40f6a3..c748e741 100644 --- a/runtime/common/src/message_router/mod.rs +++ b/runtime/common/src/message_router/mod.rs @@ -154,7 +154,7 @@ pub mod pallet { let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin.clone())?; let account_id = ensure_signed(origin)?; // U8 account used in DescendOrigin instruction - let account_u8 = <[u8; 32]>::try_from(account_id.encode()) + let raw_account = <[u8; 32]>::try_from(account_id.encode()) .map_err(|_| Error::::AccountIdConversionFailed)?; let mut remote_xcm: Xcm<::Call> = @@ -170,7 +170,7 @@ pub mod pallet { TargetXcmExecConfig::::get(T::MoonbeamLocation::get()) .ok_or(Error::::TargetXcmExecNotConfig)?; remote_weight = T::MoonbeamWeigher::weight(&mut Self::extend_remote_xcm( - account_u8.clone(), + raw_account.clone(), remote_xcm.clone(), MultiAsset { id: AssetId::from(T::LocalAssetId::get()), fun: Fungible(0) }, )) @@ -215,7 +215,7 @@ pub mod pallet { .reanchor(&T::MoonbeamLocation::get(), &ancestry) .map_err(|()| Error::::MultiLocationFull)?; remote_xcm = - Self::extend_remote_xcm(account_u8, remote_xcm, remote_xcm_fee_anchor_dest); + Self::extend_remote_xcm(raw_account, remote_xcm, remote_xcm_fee_anchor_dest); // Send remote xcm to moonbeam T::XcmSender::send_xcm(T::MoonbeamLocation::get(), remote_xcm.clone().into()) .map_err(|_| Error::::XcmSendFailed)?; @@ -236,7 +236,7 @@ pub mod pallet { impl Pallet { /// Extend xcm for remote execution fn extend_remote_xcm( - account_u8: [u8; 32], + raw_account: [u8; 32], xcm: Xcm<::Call>, fee: MultiAsset, ) -> Xcm<::Call> { @@ -252,7 +252,7 @@ pub mod pallet { beneficiary: T::SelfLocationInSibl::get(), }, ])), - DescendOrigin(X1(AccountId32 { network: NetworkId::Any, id: account_u8 })), + DescendOrigin(X1(AccountId32 { network: NetworkId::Any, id: raw_account })), ]); extend_xcm.0.extend(xcm.0.into_iter()); return extend_xcm; From 63db32d88b3c9b11288c69a85bcca3b7d30d9411 Mon Sep 17 00:00:00 2001 From: Guantong <04637@163.com> Date: Thu, 20 Oct 2022 15:53:43 +0800 Subject: [PATCH 35/37] sp-io --- runtime/common/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/runtime/common/Cargo.toml b/runtime/common/Cargo.toml index 6c45a0ef..afe827c5 100644 --- a/runtime/common/Cargo.toml +++ b/runtime/common/Cargo.toml @@ -48,6 +48,7 @@ xcm-executor = { default-features = false, git = "https://github. [dev-dependencies] pallet-timestamp = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" } +sp-io = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" } [features] default = ["std"] From 630fcb6722e09d5331260a3d86d27af78a09b847 Mon Sep 17 00:00:00 2001 From: Guantong <04637@163.com> Date: Mon, 24 Oct 2022 12:30:40 +0800 Subject: [PATCH 36/37] Support astar network router --- runtime/common/src/message_router/mod.rs | 43 +++++++++++++++++-- .../src/pallets/message_router.rs | 12 +++++- .../src/pallets/message_router.rs | 12 +++++- .../src/pallets/message_router.rs | 12 +++++- 4 files changed, 70 insertions(+), 9 deletions(-) diff --git a/runtime/common/src/message_router/mod.rs b/runtime/common/src/message_router/mod.rs index c748e741..463457e3 100644 --- a/runtime/common/src/message_router/mod.rs +++ b/runtime/common/src/message_router/mod.rs @@ -35,6 +35,7 @@ pub type AssetUnitsPerSecond = u128; #[derive(Clone, Encode, Decode, TypeInfo, PartialEq, Debug)] pub enum Target { Moonbeam, + Astar, } #[frame_support::pallet] @@ -63,6 +64,9 @@ pub mod pallet { type MoonbeamLocation: Get; /// Used to calculate the weight required for the moonbeam execution of xcm. type MoonbeamWeigher: WeightBounds; + type AstarLocation: Get; + /// Used to calculate the weight required for the moonbeam execution of xcm. + type AstarWeigher: WeightBounds; /// This chain location relative to sibling chain type SelfLocationInSibl: Get; type WeightInfo: WeightInfo; @@ -176,6 +180,17 @@ pub mod pallet { )) .map_err(|()| Error::::UnweighableMessage)?; }, + Target::Astar => { + local_asset_units_per_second = + TargetXcmExecConfig::::get(T::AstarLocation::get()) + .ok_or(Error::::TargetXcmExecNotConfig)?; + remote_weight = T::AstarWeigher::weight(&mut Self::extend_remote_xcm( + raw_account.clone(), + 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); @@ -191,6 +206,12 @@ pub mod pallet { beneficiary: T::MoonbeamLocation::get(), }]); }, + Target::Astar => { + local_xcm = Xcm(vec![TransferAsset { + assets: remote_xcm_fee.clone().into(), + beneficiary: T::AstarLocation::get(), + }]); + }, } let local_weight = T::LocalWeigher::weight(&mut local_xcm) .map_err(|()| Error::::UnweighableMessage)?; @@ -214,12 +235,28 @@ pub mod pallet { remote_xcm_fee_anchor_dest .reanchor(&T::MoonbeamLocation::get(), &ancestry) .map_err(|()| Error::::MultiLocationFull)?; - remote_xcm = - Self::extend_remote_xcm(raw_account, remote_xcm, remote_xcm_fee_anchor_dest); - // Send remote xcm to moonbeam + remote_xcm = Self::extend_remote_xcm( + raw_account, + remote_xcm, + remote_xcm_fee_anchor_dest, + ); + // Send remote xcm to target T::XcmSender::send_xcm(T::MoonbeamLocation::get(), remote_xcm.clone().into()) .map_err(|_| Error::::XcmSendFailed)?; }, + Target::Astar => { + remote_xcm_fee_anchor_dest + .reanchor(&T::AstarLocation::get(), &ancestry) + .map_err(|()| Error::::MultiLocationFull)?; + remote_xcm = Self::extend_remote_xcm( + raw_account, + remote_xcm, + remote_xcm_fee_anchor_dest, + ); + // Send remote xcm to target + T::XcmSender::send_xcm(T::AstarLocation::get(), remote_xcm.clone().into()) + .map_err(|_| Error::::XcmSendFailed)?; + }, } Self::deposit_event(Event::ForwardTo( diff --git a/runtime/crab-parachain/src/pallets/message_router.rs b/runtime/crab-parachain/src/pallets/message_router.rs index deaed74b..bfa70594 100644 --- a/runtime/crab-parachain/src/pallets/message_router.rs +++ b/runtime/crab-parachain/src/pallets/message_router.rs @@ -9,9 +9,10 @@ use crate::*; use dp_common_runtime::message_router::Config; frame_support::parameter_types! { - pub const MoonbeamMaxInstructions: u32 = 100; // https://github.com/PureStake/moonbeam/blob/master/runtime/moonriver/src/xcm_config.rs#L208 pub MoonbeamUnitWeightCost: Weight = 200_000_000; + // https://github.com/AstarNetwork/Astar/blob/master/runtime/shiden/src/xcm_config.rs#L108 + pub ShidenUnitWeightCost: Weight = 1_000_000_000; pub SelfLocationInSibl: MultiLocation = MultiLocation::new( 1, X1(Parachain(ParachainInfo::parachain_id().into())) @@ -24,9 +25,15 @@ frame_support::parameter_types! { 1, X1(Parachain(2023)) ); + pub ShidenLocation: MultiLocation = MultiLocation::new( + 1, + X1(Parachain(2007)) + ); } impl Config for Runtime { + type AstarLocation = ShidenLocation; + type AstarWeigher = FixedWeightBounds; type ConfigModifierOrigin = EnsureRoot; type Event = Event; type ExecuteXcmOrigin = EnsureXcmOrigin; @@ -34,8 +41,9 @@ impl Config for Runtime { type LocalWeigher = FixedWeightBounds; type LocationInverter = LocationInverter; type MoonbeamLocation = MoonriverLocation; - type MoonbeamWeigher = FixedWeightBounds; + type MoonbeamWeigher = FixedWeightBounds; type SelfLocationInSibl = SelfLocationInSibl; + // Dont update the weights. type WeightInfo = (); type XcmExecutor = XcmExecutor; type XcmSender = XcmRouter; diff --git a/runtime/darwinia-parachain/src/pallets/message_router.rs b/runtime/darwinia-parachain/src/pallets/message_router.rs index 37c26ab6..132967dd 100644 --- a/runtime/darwinia-parachain/src/pallets/message_router.rs +++ b/runtime/darwinia-parachain/src/pallets/message_router.rs @@ -9,9 +9,10 @@ use crate::*; use dp_common_runtime::message_router::Config; frame_support::parameter_types! { - pub const MoonbeamMaxInstructions: u32 = 100; // https://github.com/PureStake/moonbeam/blob/master/runtime/moonbeam/src/xcm_config.rs#L201 pub MoonbeamUnitWeightCost: Weight = 200_000_000; + // https://github.com/AstarNetwork/Astar/blob/master/runtime/astar/src/xcm_config.rs#L108 + pub AstarUnitWeightCost: Weight = 1_000_000_000; pub SelfLocationInSibl: MultiLocation = MultiLocation::new( 1, X1(Parachain(ParachainInfo::parachain_id().into())) @@ -24,9 +25,15 @@ frame_support::parameter_types! { 1, X1(Parachain(2004)) ); + pub AstarLocation: MultiLocation = MultiLocation::new( + 1, + X1(Parachain(2006)) + ); } impl Config for Runtime { + type AstarLocation = AstarLocation; + type AstarWeigher = FixedWeightBounds; type ConfigModifierOrigin = EnsureRoot; type Event = Event; type ExecuteXcmOrigin = EnsureXcmOrigin; @@ -34,8 +41,9 @@ impl Config for Runtime { type LocalWeigher = FixedWeightBounds; type LocationInverter = LocationInverter; type MoonbeamLocation = MoonbeamLocation; - type MoonbeamWeigher = FixedWeightBounds; + type MoonbeamWeigher = FixedWeightBounds; type SelfLocationInSibl = SelfLocationInSibl; + // Dont update the weights. type WeightInfo = (); type XcmExecutor = XcmExecutor; type XcmSender = XcmRouter; diff --git a/runtime/pangolin-parachain/src/pallets/message_router.rs b/runtime/pangolin-parachain/src/pallets/message_router.rs index 0136d6d6..c5de6640 100644 --- a/runtime/pangolin-parachain/src/pallets/message_router.rs +++ b/runtime/pangolin-parachain/src/pallets/message_router.rs @@ -9,9 +9,10 @@ use crate::*; use dp_common_runtime::message_router::Config; frame_support::parameter_types! { - pub const MoonbeamMaxInstructions: u32 = 100; // https://github.com/PureStake/moonbeam/blob/master/runtime/moonbase/src/xcm_config.rs#L214 pub MoonbeamUnitWeightCost: Weight = 200_000_000; + // https://github.com/AstarNetwork/Astar/blob/master/runtime/shibuya/src/xcm_config.rs#L108 + pub RocstarUnitWeightCost: Weight = 1_000_000_000; pub SelfLocationInSibl: MultiLocation = MultiLocation::new( 1, X1(Parachain(ParachainInfo::parachain_id().into())) @@ -24,9 +25,15 @@ frame_support::parameter_types! { 1, X1(Parachain(1000)) ); + pub RocstarLocation: MultiLocation = MultiLocation::new( + 1, + X1(Parachain(2006)) + ); } impl Config for Runtime { + type AstarLocation = RocstarLocation; + type AstarWeigher = FixedWeightBounds; type ConfigModifierOrigin = EnsureRoot; type Event = Event; type ExecuteXcmOrigin = EnsureXcmOrigin; @@ -34,8 +41,9 @@ impl Config for Runtime { type LocalWeigher = FixedWeightBounds; type LocationInverter = LocationInverter; type MoonbeamLocation = MoonbaseAlphaLocation; - type MoonbeamWeigher = FixedWeightBounds; + type MoonbeamWeigher = FixedWeightBounds; type SelfLocationInSibl = SelfLocationInSibl; + // Dont update the weights. type WeightInfo = (); type XcmExecutor = XcmExecutor; type XcmSender = XcmRouter; From 434e37908d115edc30030daae5a92b8e34d51263 Mon Sep 17 00:00:00 2001 From: Guantong <04637@163.com> Date: Tue, 25 Oct 2022 16:00:07 +0800 Subject: [PATCH 37/37] dont need `reverse` of `AccountKey20Derive` --- runtime/common/src/message_router/location_conversion.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/common/src/message_router/location_conversion.rs b/runtime/common/src/message_router/location_conversion.rs index 7f0b58e4..4c9b8a06 100644 --- a/runtime/common/src/message_router/location_conversion.rs +++ b/runtime/common/src/message_router/location_conversion.rs @@ -48,7 +48,7 @@ impl + Into<[u8; 32]> + Clone> Convert Result { - Ok(AccountId32 { id: who.into(), network: Any }.into()) + Err(who) } }