Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(xcm): add ExecuteWithOrigin instruction #6304

Open
wants to merge 4 commits into
base: xcm-v5
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -253,4 +253,7 @@ impl<Call> XcmWeightInfo<Call> for AssetHubRococoXcmWeight<Call> {
fn unpaid_execution(_: &WeightLimit, _: &Option<Location>) -> Weight {
XcmGeneric::<Runtime>::unpaid_execution()
}
fn execute_with_origin(_: &Option<InteriorLocation>, _: &Xcm<Call>) -> Weight {
XcmGeneric::<Runtime>::execute_with_origin()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -373,4 +373,11 @@ impl<T: frame_system::Config> WeightInfo<T> {
// Minimum execution time: 668_000 picoseconds.
Weight::from_parts(726_000, 0)
}
pub fn execute_with_origin() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
// Minimum execution time: 713_000 picoseconds.
Weight::from_parts(776_000, 0)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -253,4 +253,7 @@ impl<Call> XcmWeightInfo<Call> for AssetHubWestendXcmWeight<Call> {
fn unpaid_execution(_: &WeightLimit, _: &Option<Location>) -> Weight {
XcmGeneric::<Runtime>::unpaid_execution()
}
fn execute_with_origin(_: &Option<InteriorLocation>, _: &Xcm<Call>) -> Weight {
XcmGeneric::<Runtime>::execute_with_origin()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -373,4 +373,11 @@ impl<T: frame_system::Config> WeightInfo<T> {
// Minimum execution time: 638_000 picoseconds.
Weight::from_parts(708_000, 0)
}
pub fn execute_with_origin() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
// Minimum execution time: 713_000 picoseconds.
Weight::from_parts(776_000, 0)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -256,4 +256,7 @@ impl<Call> XcmWeightInfo<Call> for BridgeHubRococoXcmWeight<Call> {
fn set_asset_claimer(_location: &Location) -> Weight {
XcmGeneric::<Runtime>::set_asset_claimer()
}
fn execute_with_origin(_: &Option<InteriorLocation>, _: &Xcm<Call>) -> Weight {
XcmGeneric::<Runtime>::execute_with_origin()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -380,4 +380,11 @@ impl<T: frame_system::Config> WeightInfo<T> {
// Minimum execution time: 707_000 picoseconds.
Weight::from_parts(749_000, 0)
}
pub fn execute_with_origin() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
// Minimum execution time: 713_000 picoseconds.
Weight::from_parts(776_000, 0)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -257,4 +257,7 @@ impl<Call> XcmWeightInfo<Call> for BridgeHubWestendXcmWeight<Call> {
fn unpaid_execution(_: &WeightLimit, _: &Option<Location>) -> Weight {
XcmGeneric::<Runtime>::unpaid_execution()
}
fn execute_with_origin(_: &Option<InteriorLocation>, _: &Xcm<Call>) -> Weight {
XcmGeneric::<Runtime>::execute_with_origin()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -380,4 +380,11 @@ impl<T: frame_system::Config> WeightInfo<T> {
// Minimum execution time: 707_000 picoseconds.
Weight::from_parts(749_000, 0)
}
pub fn execute_with_origin() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
// Minimum execution time: 713_000 picoseconds.
Weight::from_parts(776_000, 0)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -254,4 +254,7 @@ impl<Call> XcmWeightInfo<Call> for CoretimeRococoXcmWeight<Call> {
fn set_asset_claimer(_location: &Location) -> Weight {
XcmGeneric::<Runtime>::set_asset_claimer()
}
fn execute_with_origin(_: &Option<InteriorLocation>, _: &Xcm<Call>) -> Weight {
XcmGeneric::<Runtime>::execute_with_origin()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -338,4 +338,11 @@ impl<T: frame_system::Config> WeightInfo<T> {
// Minimum execution time: 707_000 picoseconds.
Weight::from_parts(749_000, 0)
}
pub fn execute_with_origin() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
// Minimum execution time: 713_000 picoseconds.
Weight::from_parts(776_000, 0)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -254,4 +254,7 @@ impl<Call> XcmWeightInfo<Call> for CoretimeWestendXcmWeight<Call> {
fn unpaid_execution(_: &WeightLimit, _: &Option<Location>) -> Weight {
XcmGeneric::<Runtime>::unpaid_execution()
}
fn execute_with_origin(_: &Option<InteriorLocation>, _: &Xcm<Call>) -> Weight {
XcmGeneric::<Runtime>::execute_with_origin()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -338,4 +338,11 @@ impl<T: frame_system::Config> WeightInfo<T> {
// Minimum execution time: 707_000 picoseconds.
Weight::from_parts(749_000, 0)
}
pub fn execute_with_origin() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
// Minimum execution time: 713_000 picoseconds.
Weight::from_parts(776_000, 0)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -253,4 +253,7 @@ impl<Call> XcmWeightInfo<Call> for PeopleRococoXcmWeight<Call> {
fn set_asset_claimer(_location: &Location) -> Weight {
XcmGeneric::<Runtime>::set_asset_claimer()
}
fn execute_with_origin(_: &Option<InteriorLocation>, _: &Xcm<Call>) -> Weight {
XcmGeneric::<Runtime>::execute_with_origin()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -338,4 +338,11 @@ impl<T: frame_system::Config> WeightInfo<T> {
// Minimum execution time: 707_000 picoseconds.
Weight::from_parts(749_000, 0)
}
pub fn execute_with_origin() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
// Minimum execution time: 713_000 picoseconds.
Weight::from_parts(776_000, 0)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -253,4 +253,7 @@ impl<Call> XcmWeightInfo<Call> for PeopleWestendXcmWeight<Call> {
fn set_asset_claimer(_location: &Location) -> Weight {
XcmGeneric::<Runtime>::set_asset_claimer()
}
fn execute_with_origin(_: &Option<InteriorLocation>, _: &Xcm<Call>) -> Weight {
XcmGeneric::<Runtime>::execute_with_origin()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -338,4 +338,11 @@ impl<T: frame_system::Config> WeightInfo<T> {
// Minimum execution time: 707_000 picoseconds.
Weight::from_parts(749_000, 0)
}
pub fn execute_with_origin() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
// Minimum execution time: 713_000 picoseconds.
Weight::from_parts(776_000, 0)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -344,4 +344,11 @@ impl<T: frame_system::Config> pallet_xcm_benchmarks::generic::WeightInfo for Wei
Weight::from_parts(1_354_000, 0)
.saturating_add(Weight::from_parts(0, 0))
}
fn execute_with_origin() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
// Minimum execution time: 713_000 picoseconds.
Weight::from_parts(776_000, 0)
}
}
3 changes: 3 additions & 0 deletions polkadot/runtime/rococo/src/weights/xcm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,9 @@
fn set_asset_claimer(_location: &Location) -> Weight {
XcmGeneric::<Runtime>::set_asset_claimer()
}
fn execute_with_origin(_: &Option<InteriorLocation>, _: &Xcm<Call>) -> Weight {

Check failure on line 292 in polkadot/runtime/rococo/src/weights/xcm/mod.rs

View workflow job for this annotation

GitHub Actions / cargo-check-all-crate-macos

cannot find type `Call` in this scope
XcmGeneric::<Runtime>::execute_with_origin()

Check failure on line 293 in polkadot/runtime/rococo/src/weights/xcm/mod.rs

View workflow job for this annotation

GitHub Actions / cargo-check-all-crate-macos

no function or associated item named `execute_with_origin` found for struct `pallet_xcm_benchmarks_generic::WeightInfo` in the current scope
}
}

#[test]
Expand Down
4 changes: 4 additions & 0 deletions polkadot/runtime/westend/src/weights/xcm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
mod pallet_xcm_benchmarks_generic;

use crate::Runtime;
use crate::xcm_config::Weigher;

Check failure on line 21 in polkadot/runtime/westend/src/weights/xcm/mod.rs

View workflow job for this annotation

GitHub Actions / cargo-check-all-crate-macos

unresolved import `crate::xcm_config::Weigher`
use alloc::vec::Vec;
use frame_support::weights::Weight;
use xcm::{
Expand Down Expand Up @@ -294,6 +295,9 @@
fn unpaid_execution(_: &WeightLimit, _: &Option<Location>) -> Weight {
XcmGeneric::<Runtime>::unpaid_execution()
}
fn execute_with_origin(_: &Option<InteriorLocation>, _: &Xcm<RuntimeCall>) -> Weight {
XcmGeneric::<Runtime>::execute_with_origin()
}
}

#[test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -329,4 +329,11 @@ impl<T: frame_system::Config> WeightInfo<T> {
// Minimum execution time: 713_000 picoseconds.
Weight::from_parts(776_000, 0)
}
pub(crate) fn execute_with_origin() -> Weight {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
// Minimum execution time: 713_000 picoseconds.
Weight::from_parts(776_000, 0)
}
}
4 changes: 2 additions & 2 deletions polkadot/xcm/src/v4/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1424,8 +1424,8 @@ impl<Call: Decode + GetDispatchInfo> TryFrom<NewInstruction<Call>> for Instructi
weight_limit,
check_origin: check_origin.map(|origin| origin.try_into()).transpose()?,
},
InitiateTransfer { .. } | PayFees { .. } | SetAssetClaimer { .. } => {
log::debug!(target: "xcm::v5tov4", "`{new_instruction:?}` not supported by v4");
InitiateTransfer { .. } | PayFees { .. } | SetAssetClaimer { .. } | ExecuteWithOrigin { .. } => {
log::debug!(target: "xcm::versions::v5tov4", "`{new_instruction:?}` not supported by v4");
return Err(());
},
})
Expand Down
24 changes: 24 additions & 0 deletions polkadot/xcm/src/v5/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1110,6 +1110,28 @@ pub enum Instruction<Call> {
assets: Vec<AssetTransferFilter>,
remote_xcm: Xcm<()>,
},

/// Executes an inner set of instructions with one origin.
///
/// Parameters:
/// - `origin`: The origin that will be used during the execution of the inner `xcm`.
/// If set to `None`, it acts in the same way as `ClearOrigin` and runs the inner xcm
/// with no origin.
/// If set to `Some(o)`, it acts in the same way as `DescendOrigin(o)` and runs the
/// inner xcm with `o` as origin.
/// - `xcm`: Inner instructions that will be executed with the origin modified according
/// to `origin`.
///
/// Safety: No concerns.
///
/// Kind: *Command*
///
/// Errors:
/// - `BadOrigin`
ExecuteWithOrigin {
origin: Option<InteriorLocation>,
xcm: Xcm<Call>,
},
}

impl<Call> Xcm<Call> {
Expand Down Expand Up @@ -1190,6 +1212,7 @@ impl<Call> Instruction<Call> {
PayFees { asset } => PayFees { asset },
InitiateTransfer { destination, remote_fees, preserve_origin, assets, remote_xcm } =>
InitiateTransfer { destination, remote_fees, preserve_origin, assets, remote_xcm },
ExecuteWithOrigin { origin, xcm } => ExecuteWithOrigin { origin, xcm: xcm.into() },
}
}
}
Expand Down Expand Up @@ -1262,6 +1285,7 @@ impl<Call, W: XcmWeightInfo<Call>> GetWeight<W> for Instruction<Call> {
PayFees { asset } => W::pay_fees(asset),
InitiateTransfer { destination, remote_fees, preserve_origin, assets, remote_xcm } =>
W::initiate_transfer(destination, remote_fees, preserve_origin, assets, remote_xcm),
ExecuteWithOrigin { origin, xcm } => W::execute_with_origin(origin, xcm),
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion polkadot/xcm/xcm-builder/src/weight.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ impl<T: Get<Weight>, C: Decode + GetDispatchInfo, M> FixedWeightBounds<T, C, M>
) -> Result<Weight, ()> {
let instr_weight = match instruction {
Transact { ref mut call, .. } => call.ensure_decoded()?.get_dispatch_info().call_weight,
SetErrorHandler(xcm) | SetAppendix(xcm) => Self::weight_with_limit(xcm, instrs_limit)?,
SetErrorHandler(xcm) | SetAppendix(xcm) | ExecuteWithOrigin { xcm, .. } => Self::weight_with_limit(xcm, instrs_limit)?,
_ => Weight::zero(),
};
T::get().checked_add(&instr_weight).ok_or(())
Expand Down
52 changes: 39 additions & 13 deletions polkadot/xcm/xcm-executor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ impl<Config: config::Config> XcmAssetTransfers for XcmExecutor<Config> {
type AssetTransactor = Config::AssetTransactor;
}

#[derive(Debug)]
#[derive(Debug, PartialEq)]
pub struct ExecutorError {
pub index: u32,
pub xcm_error: XcmError,
Expand Down Expand Up @@ -1028,18 +1028,26 @@ impl<Config: config::Config> XcmExecutor<Config> {
);
Ok(())
},
DescendOrigin(who) => self
.context
.origin
.as_mut()
.ok_or(XcmError::BadOrigin)?
.append_with(who)
.map_err(|e| {
tracing::error!(target: "xcm::process_instruction::descend_origin", ?e, "Failed to append junctions");
XcmError::LocationFull
}),
ClearOrigin => {
self.context.origin = None;
DescendOrigin(who) => self.do_descend_origin(who),
ClearOrigin => self.do_clear_origin(),
ExecuteWithOrigin { origin, xcm } => {
let previous_origin = self.context.origin.clone();

// Set new temporary origin.
if let Some(who) = origin {
self.do_descend_origin(who)?;
} else {
self.do_clear_origin()?;
}
// Process instructions.
self.process(xcm).map_err(|error| {
tracing::error!(target: "xcm::execute", ?error, origin = ?self.context.origin, "ExecuteWithOrigin inner xcm failure");
self.context.origin = previous_origin.clone();
error.xcm_error
})?;
// Reset origin to previous one.
self.context.origin = previous_origin;

Ok(())
},
ReportError(response_info) => {
Expand Down Expand Up @@ -1617,6 +1625,24 @@ impl<Config: config::Config> XcmExecutor<Config> {
}
}

fn do_descend_origin(&mut self, who: InteriorLocation) -> XcmResult {
self
.context
.origin
.as_mut()
.ok_or(XcmError::BadOrigin)?
.append_with(who)
.map_err(|e| {
tracing::error!(target: "xcm::process_instruction::descend_origin", ?e, "Failed to append junctions");
XcmError::LocationFull
})
}

fn do_clear_origin(&mut self) -> XcmResult {
self.context.origin = None;
Ok(())
}

/// Deposit `to_deposit` assets to `beneficiary`, without giving up on the first (transient)
/// error, and retrying once just in case one of the subsequently deposited assets satisfy some
/// requirement.
Expand Down
Loading
Loading