Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 17 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
3 changes: 2 additions & 1 deletion runtime/common/src/xcm_sender.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ pub struct ChildParachainRouter<T, W>(PhantomData<(T, W)>);
impl<T: configuration::Config + dmp::Config, W: xcm::WrapVersion> SendXcm
for ChildParachainRouter<T, W>
{
fn send_xcm(dest: MultiLocation, msg: Xcm<()>) -> SendResult {
fn send_xcm(dest: impl Into<MultiLocation>, msg: Xcm<()>) -> SendResult {
let dest = dest.into();
match dest {
MultiLocation { parents: 0, interior: X1(Parachain(id)) } => {
// Downward message passing.
Expand Down
7 changes: 3 additions & 4 deletions runtime/parachains/src/ump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ impl<XcmExecutor: xcm::latest::ExecuteXcm<C::Call>, C: Config> UmpSink for XcmSi
) -> Result<Weight, (MessageId, Weight)> {
use parity_scale_codec::DecodeLimit;
use xcm::{
latest::{Error as XcmError, Junction, MultiLocation, Xcm},
latest::{Error as XcmError, Junction, Xcm},
VersionedXcm,
};

Expand All @@ -111,9 +111,8 @@ impl<XcmExecutor: xcm::latest::ExecuteXcm<C::Call>, C: Config> UmpSink for XcmSi
Ok(0)
},
Ok(Ok(xcm_message)) => {
let xcm_junction: Junction = Junction::Parachain(origin.into());
let xcm_location: MultiLocation = xcm_junction.into();
let outcome = XcmExecutor::execute_xcm(xcm_location, xcm_message, max_weight);
let xcm_junction = Junction::Parachain(origin.into());
let outcome = XcmExecutor::execute_xcm(xcm_junction, xcm_message, max_weight);
match outcome {
Outcome::Error(XcmError::WeightLimitReached(required)) => Err((id, required)),
outcome => {
Expand Down
2 changes: 1 addition & 1 deletion runtime/test-runtime/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pub type LocalOriginToLocation = (

pub struct DoNothingRouter;
impl SendXcm for DoNothingRouter {
fn send_xcm(_dest: MultiLocation, _msg: Xcm<()>) -> SendResult {
fn send_xcm(_dest: impl Into<MultiLocation>, _msg: Xcm<()>) -> SendResult {
Ok(())
}
}
Expand Down
14 changes: 10 additions & 4 deletions xcm/pallet-xcm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ pub mod pallet {
message: Box<VersionedXcm<()>>,
) -> DispatchResult {
let origin_location = T::SendXcmOrigin::ensure_origin(origin)?;
let interior =
let interior: Junctions =
origin_location.clone().try_into().map_err(|_| Error::<T>::InvalidOrigin)?;
let dest = MultiLocation::try_from(*dest).map_err(|()| Error::<T>::BadVersion)?;
let message: Xcm<()> = (*message).try_into().map_err(|()| Error::<T>::BadVersion)?;
Expand Down Expand Up @@ -899,10 +899,12 @@ pub mod pallet {
/// Relay an XCM `message` from a given `interior` location in this context to a given `dest`
/// location. A null `dest` is not handled.
pub fn send_xcm(
interior: Junctions,
dest: MultiLocation,
interior: impl Into<Junctions>,
dest: impl Into<MultiLocation>,
mut message: Xcm<()>,
) -> Result<(), SendError> {
let interior = interior.into();
let dest = dest.into();
if interior != Junctions::Here {
message.0.insert(0, DescendOrigin(interior))
};
Expand Down Expand Up @@ -1368,7 +1370,11 @@ where
/// this crate's `Origin::Xcm` value.
pub struct XcmPassthrough<Origin>(PhantomData<Origin>);
impl<Origin: From<crate::Origin>> ConvertOrigin<Origin> for XcmPassthrough<Origin> {
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
fn convert_origin(
origin: impl Into<MultiLocation>,
kind: OriginKind,
) -> Result<Origin, MultiLocation> {
let origin = origin.into();
match kind {
OriginKind::Xcm => Ok(crate::Origin::Xcm(origin).into()),
_ => Err(origin),
Expand Down
7 changes: 4 additions & 3 deletions xcm/pallet-xcm/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,15 +147,16 @@ pub(crate) fn take_sent_xcm() -> Vec<(MultiLocation, Xcm<()>)> {
/// Sender that never returns error, always sends
pub struct TestSendXcm;
impl SendXcm for TestSendXcm {
fn send_xcm(dest: MultiLocation, msg: Xcm<()>) -> SendResult {
SENT_XCM.with(|q| q.borrow_mut().push((dest, msg)));
fn send_xcm(dest: impl Into<MultiLocation>, msg: Xcm<()>) -> SendResult {
SENT_XCM.with(|q| q.borrow_mut().push((dest.into(), msg)));
Ok(())
}
}
/// Sender that returns error if `X8` junction and stops routing
pub struct TestSendXcmErrX8;
impl SendXcm for TestSendXcmErrX8 {
fn send_xcm(dest: MultiLocation, msg: Xcm<()>) -> SendResult {
fn send_xcm(dest: impl Into<MultiLocation>, msg: Xcm<()>) -> SendResult {
let dest = dest.into();
if dest.len() == 8 {
Err(SendError::Transport("Destination location full"))
} else {
Expand Down
12 changes: 6 additions & 6 deletions xcm/src/v1/multilocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,26 +338,26 @@ impl From<Parent> for MultiLocation {
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
pub struct ParentThen(Junctions);
impl From<ParentThen> for MultiLocation {
fn from(x: ParentThen) -> Self {
MultiLocation { parents: 1, interior: x.0 }
fn from(ParentThen(interior): ParentThen) -> Self {
MultiLocation { parents: 1, interior }
}
}

/// A unit struct which can be converted into a `MultiLocation` of the inner `parents` value.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
pub struct Ancestor(u8);
impl From<Ancestor> for MultiLocation {
fn from(x: Ancestor) -> Self {
MultiLocation { parents: x.0, interior: Junctions::Here }
fn from(Ancestor(parents): Ancestor) -> Self {
MultiLocation { parents, interior: Junctions::Here }
}
}

/// A unit struct which can be converted into a `MultiLocation` of the inner `parents` value and the inner interior.
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
pub struct AncestorThen(u8, Junctions);
impl From<AncestorThen> for MultiLocation {
fn from(x: AncestorThen) -> Self {
MultiLocation { parents: x.0, interior: x.1 }
fn from(AncestorThen(parents, interior): AncestorThen) -> Self {
MultiLocation { parents, interior }
}
}

Expand Down
32 changes: 19 additions & 13 deletions xcm/src/v1/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,12 @@ pub trait ExecuteXcm<Call> {
/// Execute some XCM `message` from `origin` using no more than `weight_limit` weight. The weight limit is
/// a basic hard-limit and the implementation may place further restrictions or requirements on weight and
/// other aspects.
fn execute_xcm(origin: MultiLocation, message: Xcm<Call>, weight_limit: Weight) -> Outcome {
fn execute_xcm(
origin: impl Into<MultiLocation>,
message: Xcm<Call>,
weight_limit: Weight,
) -> Outcome {
let origin = origin.into();
log::debug!(
target: "xcm::execute_xcm",
"origin: {:?}, message: {:?}, weight_limit: {:?}",
Expand All @@ -162,7 +167,7 @@ pub trait ExecuteXcm<Call> {
/// Some amount of `weight_credit` may be provided which, depending on the implementation, may allow
/// execution without associated payment.
fn execute_xcm_in_credit(
origin: MultiLocation,
origin: impl Into<MultiLocation>,
message: Xcm<Call>,
weight_limit: Weight,
weight_credit: Weight,
Expand All @@ -171,7 +176,7 @@ pub trait ExecuteXcm<Call> {

impl<C> ExecuteXcm<C> for () {
fn execute_xcm_in_credit(
_origin: MultiLocation,
_origin: impl Into<MultiLocation>,
_message: Xcm<C>,
_weight_limit: Weight,
_weight_credit: Weight,
Expand All @@ -195,15 +200,16 @@ impl<C> ExecuteXcm<C> for () {
/// /// A sender that only passes the message through and does nothing.
/// struct Sender1;
/// impl SendXcm for Sender1 {
/// fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> Result {
/// return Err(Error::CannotReachDestination(destination, message))
/// fn send_xcm(destination: impl Into<MultiLocation>, message: Xcm<()>) -> Result {
/// return Err(Error::CannotReachDestination(destination.into(), message))
/// }
/// }
///
/// /// A sender that accepts a message that has an X2 junction, otherwise stops the routing.
/// struct Sender2;
/// impl SendXcm for Sender2 {
/// fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> Result {
/// fn send_xcm(destination: impl Into<MultiLocation>, message: Xcm<()>) -> Result {
/// let destination = destination.into();
/// if matches!(destination.interior(), Junctions::X2(j1, j2))
/// && destination.parent_count() == 0
/// {
Expand All @@ -217,7 +223,8 @@ impl<C> ExecuteXcm<C> for () {
/// /// A sender that accepts a message from an X1 parent junction, passing through otherwise.
/// struct Sender3;
/// impl SendXcm for Sender3 {
/// fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> Result {
/// fn send_xcm(destination: impl Into<MultiLocation>, message: Xcm<()>) -> Result {
/// let destination = destination.into();
/// if matches!(destination.interior(), Junctions::Here)
/// && destination.parent_count() == 1
/// {
Expand All @@ -232,17 +239,16 @@ impl<C> ExecuteXcm<C> for () {
/// # fn main() {
/// let call: Vec<u8> = ().encode();
/// let message = Xcm::Transact { origin_type: OriginKind::Superuser, require_weight_at_most: 0, call: call.into() };
/// let destination: MultiLocation = Parent.into();
///
/// assert!(
/// // Sender2 will block this.
/// <(Sender1, Sender2, Sender3) as SendXcm>::send_xcm(destination.clone(), message.clone())
/// <(Sender1, Sender2, Sender3) as SendXcm>::send_xcm(Parent, message.clone())
/// .is_err()
/// );
///
/// assert!(
/// // Sender3 will catch this.
/// <(Sender1, Sender3) as SendXcm>::send_xcm(destination.clone(), message.clone())
/// <(Sender1, Sender3) as SendXcm>::send_xcm(Parent, message.clone())
/// .is_ok()
/// );
/// # }
Expand All @@ -253,19 +259,19 @@ pub trait SendXcm {
/// If it is not a destination which can be reached with this type but possibly could by others, then it *MUST*
/// return `CannotReachDestination`. Any other error will cause the tuple implementation to exit early without
/// trying other type fields.
fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> Result;
fn send_xcm(destination: impl Into<MultiLocation>, message: Xcm<()>) -> Result;
}

#[impl_trait_for_tuples::impl_for_tuples(30)]
impl SendXcm for Tuple {
fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> Result {
fn send_xcm(destination: impl Into<MultiLocation>, message: Xcm<()>) -> Result {
for_tuples!( #(
// we shadow `destination` and `message` in each expansion for the next one.
let (destination, message) = match Tuple::send_xcm(destination, message) {
Err(Error::CannotReachDestination(d, m)) => (d, m),
o @ _ => return o,
};
)* );
Err(Error::CannotReachDestination(destination, message))
Err(Error::CannotReachDestination(destination.into(), message))
}
}
33 changes: 19 additions & 14 deletions xcm/src/v2/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,12 @@ pub trait ExecuteXcm<Call> {
/// Execute some XCM `message` from `origin` using no more than `weight_limit` weight. The weight limit is
/// a basic hard-limit and the implementation may place further restrictions or requirements on weight and
/// other aspects.
fn execute_xcm(origin: MultiLocation, message: Xcm<Call>, weight_limit: Weight) -> Outcome {
fn execute_xcm(
origin: impl Into<MultiLocation>,
message: Xcm<Call>,
weight_limit: Weight,
) -> Outcome {
let origin = origin.into();
log::debug!(
target: "xcm::execute_xcm",
"origin: {:?}, message: {:?}, weight_limit: {:?}",
Expand All @@ -183,7 +188,7 @@ pub trait ExecuteXcm<Call> {
/// Some amount of `weight_credit` may be provided which, depending on the implementation, may allow
/// execution without associated payment.
fn execute_xcm_in_credit(
origin: MultiLocation,
origin: impl Into<MultiLocation>,
message: Xcm<Call>,
weight_limit: Weight,
weight_credit: Weight,
Expand All @@ -192,7 +197,7 @@ pub trait ExecuteXcm<Call> {

impl<C> ExecuteXcm<C> for () {
fn execute_xcm_in_credit(
_origin: MultiLocation,
_origin: impl Into<MultiLocation>,
_message: Xcm<C>,
_weight_limit: Weight,
_weight_credit: Weight,
Expand Down Expand Up @@ -241,16 +246,16 @@ pub type SendResult = result::Result<(), SendError>;
/// /// A sender that only passes the message through and does nothing.
/// struct Sender1;
/// impl SendXcm for Sender1 {
/// fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> SendResult {
/// return Err(SendError::CannotReachDestination(destination, message))
/// fn send_xcm(destination: impl Into<MultiLocation>, message: Xcm<()>) -> SendResult {
/// return Err(SendError::CannotReachDestination(destination.into(), message))
/// }
/// }
///
/// /// A sender that accepts a message that has an X2 junction, otherwise stops the routing.
/// struct Sender2;
/// impl SendXcm for Sender2 {
/// fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> SendResult {
/// if let MultiLocation { parents: 0, interior: X2(j1, j2) } = destination {
/// fn send_xcm(destination: impl Into<MultiLocation>, message: Xcm<()>) -> SendResult {
/// if let MultiLocation { parents: 0, interior: X2(j1, j2) } = destination.into() {
/// Ok(())
/// } else {
/// Err(SendError::Unroutable)
Expand All @@ -261,7 +266,8 @@ pub type SendResult = result::Result<(), SendError>;
/// /// A sender that accepts a message from a parent, passing through otherwise.
/// struct Sender3;
/// impl SendXcm for Sender3 {
/// fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> SendResult {
/// fn send_xcm(destination: impl Into<MultiLocation>, message: Xcm<()>) -> SendResult {
/// let destination = destination.into();
/// match destination {
/// MultiLocation { parents: 1, interior: Here } => Ok(()),
/// _ => Err(SendError::CannotReachDestination(destination, message)),
Expand All @@ -277,17 +283,16 @@ pub type SendResult = result::Result<(), SendError>;
/// require_weight_at_most: 0,
/// call: call.into(),
/// }]);
/// let destination = MultiLocation::parent();
///
/// assert!(
/// // Sender2 will block this.
/// <(Sender1, Sender2, Sender3) as SendXcm>::send_xcm(destination.clone(), message.clone())
/// <(Sender1, Sender2, Sender3) as SendXcm>::send_xcm(Parent, message.clone())
/// .is_err()
/// );
///
/// assert!(
/// // Sender3 will catch this.
/// <(Sender1, Sender3) as SendXcm>::send_xcm(destination.clone(), message.clone())
/// <(Sender1, Sender3) as SendXcm>::send_xcm(Parent, message.clone())
/// .is_ok()
/// );
/// # }
Expand All @@ -298,20 +303,20 @@ pub trait SendXcm {
/// If it is not a destination which can be reached with this type but possibly could by others, then it *MUST*
/// return `CannotReachDestination`. Any other error will cause the tuple implementation to exit early without
/// trying other type fields.
fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> SendResult;
fn send_xcm(destination: impl Into<MultiLocation>, message: Xcm<()>) -> SendResult;
}

#[impl_trait_for_tuples::impl_for_tuples(30)]
impl SendXcm for Tuple {
fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> SendResult {
fn send_xcm(destination: impl Into<MultiLocation>, message: Xcm<()>) -> SendResult {
for_tuples!( #(
// we shadow `destination` and `message` in each expansion for the next one.
let (destination, message) = match Tuple::send_xcm(destination, message) {
Err(SendError::CannotReachDestination(d, m)) => (d, m),
o @ _ => return o,
};
)* );
Err(SendError::CannotReachDestination(destination, message))
Err(SendError::CannotReachDestination(destination.into(), message))
}
}

Expand Down
8 changes: 4 additions & 4 deletions xcm/xcm-builder/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ pub fn sent_xcm() -> Vec<(MultiLocation, opaque::Xcm)> {
}
pub struct TestSendXcm;
impl SendXcm for TestSendXcm {
fn send_xcm(dest: MultiLocation, msg: opaque::Xcm) -> SendResult {
SENT_XCM.with(|q| q.borrow_mut().push((dest, msg)));
fn send_xcm(dest: impl Into<MultiLocation>, msg: opaque::Xcm) -> SendResult {
SENT_XCM.with(|q| q.borrow_mut().push((dest.into(), msg)));
Ok(())
}
}
Expand Down Expand Up @@ -164,11 +164,11 @@ pub fn to_account(l: MultiLocation) -> Result<u64, MultiLocation> {
pub struct TestOriginConverter;
impl ConvertOrigin<TestOrigin> for TestOriginConverter {
fn convert_origin(
origin: MultiLocation,
origin: impl Into<MultiLocation>,
kind: OriginKind,
) -> Result<TestOrigin, MultiLocation> {
use OriginKind::*;
match (kind, origin) {
match (kind, origin.into()) {
(Superuser, _) => Ok(TestOrigin::Root),
(SovereignAccount, l) => Ok(TestOrigin::Signed(to_account(l)?)),
(Native, MultiLocation { parents: 0, interior: X1(Parachain(id)) }) =>
Expand Down
Loading