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

Allows to customize how calls are dispatched from XCM #5657

Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions runtime/kusama/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ impl xcm_executor::Config for XcmConfig {
// No bridges yet...
type MessageExporter = ();
type UniversalAliases = Nothing;
type CallDispatcher = Call;
}

parameter_types! {
Expand Down
1 change: 1 addition & 0 deletions runtime/polkadot/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ impl xcm_executor::Config for XcmConfig {
// No bridges yet...
type MessageExporter = ();
type UniversalAliases = Nothing;
type CallDispatcher = Call;
}

parameter_types! {
Expand Down
1 change: 1 addition & 0 deletions runtime/rococo/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ impl xcm_executor::Config for XcmConfig {
type FeeManager = ();
type MessageExporter = ();
type UniversalAliases = Nothing;
type CallDispatcher = Call;
}

parameter_types! {
Expand Down
1 change: 1 addition & 0 deletions runtime/test-runtime/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,4 +103,5 @@ impl xcm_executor::Config for XcmConfig {
type FeeManager = ();
type MessageExporter = ();
type UniversalAliases = Nothing;
type CallDispatcher = Call;
}
1 change: 1 addition & 0 deletions runtime/westend/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ impl xcm_executor::Config for XcmConfig {
type FeeManager = ();
type MessageExporter = ();
type UniversalAliases = Nothing;
type CallDispatcher = Call;
}

/// Type to convert an `Origin` type value into a `MultiLocation` value which represents an interior location
Expand Down
11 changes: 9 additions & 2 deletions xcm/xcm-executor/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.

use crate::traits::{
AssetExchange, AssetLock, ClaimAssets, ConvertOrigin, DropAssets, ExportXcm, FeeManager,
OnResponse, ShouldExecute, TransactAsset, VersionChangeNotifier, WeightBounds, WeightTrader,
AssetExchange, AssetLock, CallDispatcher, ClaimAssets, ConvertOrigin, DropAssets, ExportXcm,
FeeManager, OnResponse, ShouldExecute, TransactAsset, VersionChangeNotifier, WeightBounds,
WeightTrader,
};
use frame_support::{
dispatch::{Dispatchable, Parameter},
Expand Down Expand Up @@ -94,4 +95,10 @@ pub trait Config {
/// The origin locations and specific universal junctions to which they are allowed to elevate
/// themselves.
type UniversalAliases: Contains<(MultiLocation, Junction)>;

/// The call dispatcher used by XCM.
///
/// XCM will use this to dispatch any calls. When no special call dispatcher is required,
/// this can be set to the same type as `Self::Call`.
type CallDispatcher: CallDispatcher<Self::Call>;
}
27 changes: 14 additions & 13 deletions xcm/xcm-executor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#![cfg_attr(not(feature = "std"), no_std)]

use frame_support::{
dispatch::{Dispatchable, Weight},
dispatch::Weight,
ensure,
traits::{Contains, ContainsPair, Get, PalletsInfoAccess},
weights::GetDispatchInfo,
Expand All @@ -30,8 +30,8 @@ use xcm::latest::prelude::*;

pub mod traits;
use traits::{
validate_export, AssetExchange, AssetLock, ClaimAssets, ConvertOrigin, DropAssets, Enact,
ExportXcm, FeeManager, FeeReason, OnResponse, ShouldExecute, TransactAsset,
validate_export, AssetExchange, AssetLock, CallDispatcher, ClaimAssets, ConvertOrigin,
DropAssets, Enact, ExportXcm, FeeManager, FeeReason, OnResponse, ShouldExecute, TransactAsset,
VersionChangeNotifier, WeightBounds, WeightTrader,
};

Expand Down Expand Up @@ -512,16 +512,17 @@ impl<Config: config::Config> XcmExecutor<Config> {
.map_err(|_| XcmError::BadOrigin)?;
let weight = message_call.get_dispatch_info().weight;
ensure!(weight <= require_weight_at_most, XcmError::MaxWeightInvalid);
let maybe_actual_weight = match message_call.dispatch(dispatch_origin) {
Ok(post_info) => {
self.transact_status = MaybeErrorCode::Success;
post_info.actual_weight
},
Err(error_and_info) => {
self.transact_status = error_and_info.error.encode().into();
error_and_info.post_info.actual_weight
},
};
let maybe_actual_weight =
match Config::CallDispatcher::dispatch(message_call, dispatch_origin) {
Ok(post_info) => {
self.transact_status = MaybeErrorCode::Success;
post_info.actual_weight
},
Err(error_and_info) => {
self.transact_status = error_and_info.error.encode().into();
error_and_info.post_info.actual_weight
},
};
let actual_weight = maybe_actual_weight.unwrap_or(weight);
let surplus = weight.saturating_sub(actual_weight);
// We assume that the `Config::Weigher` will counts the `require_weight_at_most`
Expand Down
22 changes: 22 additions & 0 deletions xcm/xcm-executor/src/traits/conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.

use parity_scale_codec::{Decode, Encode};
use sp_runtime::{traits::Dispatchable, DispatchErrorWithPostInfo};
use sp_std::{borrow::Borrow, prelude::*, result::Result};
use xcm::latest::prelude::*;

Expand Down Expand Up @@ -203,3 +204,24 @@ impl<O> ConvertOrigin<O> for Tuple {
Err(origin)
}
}

/// Defines how a call is dispatched with given origin.
/// Allows to customize call dispatch, such as adapting the origin based on the call
/// or modifying the call.
pub trait CallDispatcher<Call: Dispatchable> {
fn dispatch(
call: Call,
origin: Call::Origin,
) -> Result<Call::PostInfo, DispatchErrorWithPostInfo<Call::PostInfo>>;
}

// We implement it for every calls so they can dispatch themselves
// (without any change).
impl<Call: Dispatchable> CallDispatcher<Call> for Call {
fn dispatch(
call: Call,
origin: Call::Origin,
) -> Result<Call::PostInfo, DispatchErrorWithPostInfo<Call::PostInfo>> {
call.dispatch(origin)
}
}
2 changes: 1 addition & 1 deletion xcm/xcm-executor/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
//! Various traits used in configuring the executor.

mod conversion;
pub use conversion::{Convert, ConvertOrigin, Decoded, Encoded, Identity, JustTry};
pub use conversion::{CallDispatcher, Convert, ConvertOrigin, Decoded, Encoded, Identity, JustTry};
mod drop_assets;
pub use drop_assets::{ClaimAssets, DropAssets};
mod asset_lock;
Expand Down