Make most XCM APIs accept an Into<MultiLocation> where MultiLocation is accepted (#3627)

* Change send_xcm MultiLocation argument to be generic

* Change pallet_xcm::send_xcm MultiLocation and Junctions argument to be generic

* Change convert_origin MultiLocation argument to be generic

* Change OnResponse MultiLocation arguments to be generic

* Change UniversalWeigher MultiLocation argumente to be generic

* Change ExecuteXcm MultiLocation argument to be generic

* Remove usages of into for the MultiLocation argument in execute_xcm

* Make use of generic MultiLocation arguments in rustdocs

* Cargo fmt

* Remove unused import in tests

* Resolve conflicts

* cargo fmt

* Appease spellcheck

* impl Into<MultiLocation> in more places
This commit is contained in:
Keith Yeung
2021-09-29 16:24:49 -07:00
committed by GitHub
parent 7542a73f12
commit 819849f097
18 changed files with 179 additions and 117 deletions
+19 -14
View File
@@ -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: {:?}",
@@ -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,
@@ -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,
@@ -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)
@@ -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)),
@@ -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()
/// );
/// # }
@@ -298,12 +303,12 @@ 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) {
@@ -311,7 +316,7 @@ impl SendXcm for Tuple {
o @ _ => return o,
};
)* );
Err(SendError::CannotReachDestination(destination, message))
Err(SendError::CannotReachDestination(destination.into(), message))
}
}