Add XCM Origin and converter (#2896)

* Add XCM Origin and converter

* IsMajority filter can be location-prefixed

* Update xcm/pallet-xcm/src/lib.rs

Co-authored-by: Alexander Popiak <alexander.popiak@parity.io>

* Update xcm/src/v0/multi_location.rs

Co-authored-by: Alexander Popiak <alexander.popiak@parity.io>

* Introduce UsingComponents to allow reuse of fee payment in XCM

* Use Drop rather than finalize

* Add errors for weight.

* Apply suggestions from code review

Co-authored-by: Alexander Popiak <alexander.popiak@parity.io>

* Fixes

* Update xcm/xcm-builder/src/weight.rs

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>

* Various XCM fixes and improvements

* Fixes

* Update xcm/xcm-builder/src/weight.rs

Co-authored-by: Alexander Popiak <alexander.popiak@parity.io>

* Update xcm/xcm-builder/src/weight.rs

Co-authored-by: Alexander Popiak <alexander.popiak@parity.io>

* Update xcm/xcm-builder/src/weight.rs

Co-authored-by: Alexander Popiak <alexander.popiak@parity.io>

* Fixes

Co-authored-by: Alexander Popiak <alexander.popiak@parity.io>
Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
This commit is contained in:
Gavin Wood
2021-04-27 14:33:40 +02:00
committed by GitHub
parent 8e0963e533
commit 9194219586
13 changed files with 357 additions and 218 deletions
+23 -5
View File
@@ -20,7 +20,8 @@
use sp_std::{marker::PhantomData, convert::TryInto, boxed::Box};
use codec::{Encode, Decode};
use xcm::v0::{BodyId, MultiLocation::{self, X1}, Junction::Plurality};
use xcm::v0::{BodyId, OriginKind, MultiLocation, Junction::Plurality};
use xcm_executor::traits::ConvertOrigin;
use sp_runtime::{RuntimeDebug, traits::BadOrigin};
use frame_support::traits::{EnsureOrigin, OriginTrait, Filter, Get};
@@ -62,6 +63,7 @@ pub mod pallet {
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
Attempted(xcm::v0::Outcome),
Sent(MultiLocation, MultiLocation, Xcm<()>),
}
#[pallet::error]
@@ -78,11 +80,12 @@ pub mod pallet {
#[pallet::weight(1_000)]
fn send(origin: OriginFor<T>, dest: MultiLocation, message: Xcm<()>) -> DispatchResult {
let origin_location = T::SendXcmOrigin::ensure_origin(origin)?;
Self::send_xcm(origin_location, dest, message)
Self::send_xcm(origin_location.clone(), dest.clone(), message.clone())
.map_err(|e| match e {
XcmError::CannotReachDestination(..) => Error::<T>::Unreachable,
_ => Error::<T>::SendFailure,
})?;
Self::deposit_event(Event::Sent(origin_location, dest, message));
Ok(())
}
@@ -149,10 +152,11 @@ pub fn ensure_xcm<OuterOrigin>(o: OuterOrigin) -> Result<MultiLocation, BadOrigi
/// plurality.
///
/// May reasonably be used with `EnsureXcm`.
pub struct IsMajorityOfBody<Body>(PhantomData<Body>);
impl<Body: Get<BodyId>> Filter<MultiLocation> for IsMajorityOfBody<Body> {
pub struct IsMajorityOfBody<Prefix, Body>(PhantomData<(Prefix, Body)>);
impl<Prefix: Get<MultiLocation>, Body: Get<BodyId>> Filter<MultiLocation> for IsMajorityOfBody<Prefix, Body> {
fn filter(l: &MultiLocation) -> bool {
matches!(l, X1(Plurality { id, part }) if id == &Body::get() && part.is_majority())
let maybe_suffix = l.match_and_split(&Prefix::get());
matches!(maybe_suffix, Some(Plurality { id, part }) if id == &Body::get() && part.is_majority())
}
}
@@ -180,3 +184,17 @@ impl<O: OriginTrait + From<Origin>, F: Filter<MultiLocation>> EnsureOrigin<O> fo
O::from(Origin::Xcm(MultiLocation::Null))
}
}
/// A simple passthrough where we reuse the `MultiLocation`-typed XCM origin as the inner value of
/// 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> {
match (kind, origin) {
(OriginKind::Xcm, l) => Ok(crate::Origin::Xcm(l).into()),
(_, origin) => Err(origin),
}
}
}