XCM docs and tests (#2948)

* WIP

* add tests and docs for DoubleEncoded

* reformat parent_count

* add test for match_and_split

* fix append_with docs and add tests

* move Parachain enum variant to tuple

* Fix stuff

* add to append test

* simplify match

* formatting

* format and extend doc comments (including examples)

* fix typo

* add some doc comments

* add test for location inverter

* Add more tests/docs

* Fix build

* matches fungibles

* currency adapter.

* add more tests for location inverter

* extract max length magic number into constant

* adapters.

* Apply suggestions from code review

* Final touches.

* Repot and fixes

* Remove last todo

* Apply suggestions from code review

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

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

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

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

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

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

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

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

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

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

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

* Update xcm/xcm-executor/src/traits/conversion.rs

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

* Update xcm/xcm-executor/src/traits/conversion.rs

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

* Update xcm/xcm-executor/src/traits/transact_asset.rs

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

* Update xcm/xcm-executor/src/traits/should_execute.rs

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

Co-authored-by: kianenigma <kian@parity.io>
Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com>
This commit is contained in:
Alexander Popiak
2021-06-03 04:01:25 +02:00
committed by GitHub
parent 512b366280
commit a28d4a5c5d
22 changed files with 715 additions and 200 deletions
+9
View File
@@ -14,12 +14,15 @@
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Various implementations for `ShouldExecute`.
use sp_std::{result::Result, marker::PhantomData};
use xcm::v0::{Xcm, Order, MultiLocation, Junction};
use frame_support::{ensure, traits::Contains, weights::Weight};
use xcm_executor::traits::{OnResponse, ShouldExecute};
use polkadot_parachain::primitives::IsSystem;
/// Execution barrier that just takes `shallow_weight` from `weight_credit`.
pub struct TakeWeightCredit;
impl ShouldExecute for TakeWeightCredit {
fn should_execute<Call>(
@@ -34,6 +37,8 @@ impl ShouldExecute for TakeWeightCredit {
}
}
/// Allows execution from `origin` if it is contained in `T` (i.e. `T::Contains(origin)`) taking payments into
/// account.
pub struct AllowTopLevelPaidExecutionFrom<T>(PhantomData<T>);
impl<T: Contains<MultiLocation>> ShouldExecute for AllowTopLevelPaidExecutionFrom<T> {
fn should_execute<Call>(
@@ -59,6 +64,8 @@ impl<T: Contains<MultiLocation>> ShouldExecute for AllowTopLevelPaidExecutionFro
}
}
/// Allows execution from any origin that is contained in `T` (i.e. `T::Contains(origin)`) without any payments.
/// Use only for executions from trusted origin groups.
pub struct AllowUnpaidExecutionFrom<T>(PhantomData<T>);
impl<T: Contains<MultiLocation>> ShouldExecute for AllowUnpaidExecutionFrom<T> {
fn should_execute<Call>(
@@ -73,6 +80,7 @@ impl<T: Contains<MultiLocation>> ShouldExecute for AllowUnpaidExecutionFrom<T> {
}
}
/// Allows a message only if it is from a system-level child parachain.
pub struct IsChildSystemParachain<ParaId>(PhantomData<ParaId>);
impl<
ParaId: IsSystem + From<u32>,
@@ -82,6 +90,7 @@ impl<
}
}
/// Allows only messages if the generic `ResponseHandler` expects them via `expecting_response`.
pub struct AllowKnownQueryResponses<ResponseHandler>(PhantomData<ResponseHandler>);
impl<ResponseHandler: OnResponse> ShouldExecute for AllowKnownQueryResponses<ResponseHandler> {
fn should_execute<Call>(
@@ -14,6 +14,8 @@
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Adapters to work with `frame_support::traits::Currency` through XCM.
use sp_std::{result, convert::TryInto, marker::PhantomData};
use xcm::v0::{Error as XcmError, Result, MultiAsset, MultiLocation};
use sp_runtime::traits::{SaturatedConversion, CheckedSub};
@@ -33,16 +35,51 @@ enum Error {
impl From<Error> for XcmError {
fn from(e: Error) -> Self {
use XcmError::FailedToTransactAsset;
match e {
Error::AssetNotFound => XcmError::FailedToTransactAsset("AssetNotFound"),
Error::AccountIdConversionFailed =>
XcmError::FailedToTransactAsset("AccountIdConversionFailed"),
Error::AmountToBalanceConversionFailed =>
XcmError::FailedToTransactAsset("AmountToBalanceConversionFailed"),
Error::AssetNotFound => FailedToTransactAsset("AssetNotFound"),
Error::AccountIdConversionFailed => FailedToTransactAsset("AccountIdConversionFailed"),
Error::AmountToBalanceConversionFailed => FailedToTransactAsset("AmountToBalanceConversionFailed"),
}
}
}
/// Simple adapter to use a currency as asset transactor. This type can be used as `type AssetTransactor` in
/// `xcm::Config`.
///
/// # Example
/// ```
/// use frame_support::parameter_types;
/// use xcm::v0::{MultiLocation, Junction};
/// use xcm_builder::{ParentIsDefault, CurrencyAdapter, IsConcrete};
///
/// /// Our chain's account id.
/// type AccountId = sp_runtime::AccountId32;
///
/// /// Our relay chain's location.
/// parameter_types! {
/// RelayChain: MultiLocation = MultiLocation::X1(Junction::Parent);
/// CheckingAccount: AccountId = Default::default();
/// }
///
/// /// Some items that implement `Convert<MultiLocation, AccountId>`. Can be more, but for now we just assume we accept
/// /// messages from the parent (relay chain).
/// pub type LocationConvertor = (ParentIsDefault<RelayChain>);
///
/// /// Final currency adapter. This can be used in `xcm::Config` to specify how asset related transactions happen.
/// pub type AssetTransactor = CurrencyAdapter<
/// // Use this balance type:
/// u128,
/// // The matcher: use the currency when the asset is a concrete asset in our relay chain.
/// IsConcrete<RelayChain>,
/// // The local convertor: default account of the parent relay chain.
/// LocationConvertor,
/// // Our chain's account ID type.
/// AccountId,
/// // The checking account. Can be any deterministic inaccessible account.
/// CheckingAccount,
/// >;
/// ```
pub struct CurrencyAdapter<Currency, Matcher, AccountIdConverter, AccountId, CheckedAccount>(
PhantomData<(Currency, Matcher, AccountIdConverter, AccountId, CheckedAccount)>
);
@@ -14,11 +14,14 @@
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Various implementations of `FilterAssetLocation`.
use sp_std::marker::PhantomData;
use xcm::v0::{MultiAsset, MultiLocation};
use frame_support::traits::Get;
use xcm_executor::traits::FilterAssetLocation;
/// Accepts an asset IFF it is a native asset.
pub struct NativeAsset;
impl FilterAssetLocation for NativeAsset {
fn filter_asset_location(asset: &MultiAsset, origin: &MultiLocation) -> bool {
@@ -26,6 +29,7 @@ impl FilterAssetLocation for NativeAsset {
}
}
/// Accepts an asset if it is contained in the given `T`'s `Get` impl.
pub struct Case<T>(PhantomData<T>);
impl<T: Get<(MultiAsset, MultiLocation)>> FilterAssetLocation for Case<T> {
fn filter_asset_location(asset: &MultiAsset, origin: &MultiLocation) -> bool {
@@ -14,40 +14,16 @@
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Adapters to work with `frame_support::traits::tokens::fungibles` through XCM.
use sp_std::{prelude::*, result, marker::PhantomData, borrow::Borrow};
use xcm::v0::{Error as XcmError, Result, MultiAsset, MultiLocation, Junction};
use frame_support::traits::{Get, tokens::fungibles, Contains};
use xcm_executor::traits::{TransactAsset, Convert};
use xcm_executor::traits::{TransactAsset, Convert, MatchesFungibles, Error as MatchError};
/// Asset transaction errors.
pub enum Error {
/// Asset not found.
AssetNotFound,
/// `MultiLocation` to `AccountId` conversion failed.
AccountIdConversionFailed,
/// `u128` amount to currency `Balance` conversion failed.
AmountToBalanceConversionFailed,
/// `MultiLocation` to `AssetId` conversion failed.
AssetIdConversionFailed,
}
impl From<Error> for XcmError {
fn from(e: Error) -> Self {
match e {
Error::AssetNotFound => XcmError::FailedToTransactAsset("AssetNotFound"),
Error::AccountIdConversionFailed =>
XcmError::FailedToTransactAsset("AccountIdConversionFailed"),
Error::AmountToBalanceConversionFailed =>
XcmError::FailedToTransactAsset("AmountToBalanceConversionFailed"),
Error::AssetIdConversionFailed =>
XcmError::FailedToTransactAsset("AssetIdConversionFailed"),
}
}
}
/// Converter struct implementing `AssetIdConversion` converting a numeric asset ID (must be TryFrom/TryInto<u128>)
/// into a `GeneralIndex` junction, prefixed by some `MultiLocation` value. The `MultiLocation` value will
/// typically be a `PalletInstance` junction.
/// Converter struct implementing `AssetIdConversion` converting a numeric asset ID (must be TryFrom/TryInto<u128>) into
/// a `GeneralIndex` junction, prefixed by some `MultiLocation` value. The `MultiLocation` value will typically be a
/// `PalletInstance` junction.
pub struct AsPrefixedGeneralIndex<Prefix, AssetId, ConvertAssetId>(PhantomData<(Prefix, AssetId, ConvertAssetId)>);
impl<
Prefix: Get<MultiLocation>,
@@ -73,23 +49,6 @@ impl<
}
}
pub trait MatchesFungibles<AssetId, Balance> {
fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), Error>;
}
#[impl_trait_for_tuples::impl_for_tuples(30)]
impl<
AssetId: Clone,
Balance: Clone,
> MatchesFungibles<AssetId, Balance> for Tuple {
fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), Error> {
for_tuples!( #(
match Tuple::matches_fungibles(a) { o @ Ok(_) => return o, _ => () }
)* );
Err(Error::AssetNotFound)
}
}
pub struct ConvertedConcreteAssetId<AssetId, Balance, ConvertAssetId, ConvertBalance>(
PhantomData<(AssetId, Balance, ConvertAssetId, ConvertBalance)>
);
@@ -101,13 +60,13 @@ impl<
> MatchesFungibles<AssetId, Balance> for
ConvertedConcreteAssetId<AssetId, Balance, ConvertAssetId, ConvertBalance>
{
fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), Error> {
fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), MatchError> {
let (id, amount) = match a {
MultiAsset::ConcreteFungible { id, amount } => (id, amount),
_ => return Err(Error::AssetNotFound),
_ => return Err(MatchError::AssetNotFound),
};
let what = ConvertAssetId::convert_ref(id).map_err(|_| Error::AssetIdConversionFailed)?;
let amount = ConvertBalance::convert_ref(amount).map_err(|_| Error::AmountToBalanceConversionFailed)?;
let what = ConvertAssetId::convert_ref(id).map_err(|_| MatchError::AssetIdConversionFailed)?;
let amount = ConvertBalance::convert_ref(amount).map_err(|_| MatchError::AmountToBalanceConversionFailed)?;
Ok((what, amount))
}
}
@@ -123,13 +82,13 @@ impl<
> MatchesFungibles<AssetId, Balance> for
ConvertedAbstractAssetId<AssetId, Balance, ConvertAssetId, ConvertBalance>
{
fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), Error> {
fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), MatchError> {
let (id, amount) = match a {
MultiAsset::AbstractFungible { id, amount } => (id, amount),
_ => return Err(Error::AssetNotFound),
_ => return Err(MatchError::AssetNotFound),
};
let what = ConvertAssetId::convert_ref(id).map_err(|_| Error::AssetIdConversionFailed)?;
let amount = ConvertBalance::convert_ref(amount).map_err(|_| Error::AmountToBalanceConversionFailed)?;
let what = ConvertAssetId::convert_ref(id).map_err(|_| MatchError::AssetIdConversionFailed)?;
let amount = ConvertBalance::convert_ref(amount).map_err(|_| MatchError::AmountToBalanceConversionFailed)?;
Ok((what, amount))
}
}
@@ -151,9 +110,9 @@ impl<
// Check we handle this asset.
let (asset_id, amount) = Matcher::matches_fungibles(what)?;
let source = AccountIdConverter::convert_ref(from)
.map_err(|()| Error::AccountIdConversionFailed)?;
.map_err(|()| MatchError::AccountIdConversionFailed)?;
let dest = AccountIdConverter::convert_ref(to)
.map_err(|()| Error::AccountIdConversionFailed)?;
.map_err(|()| MatchError::AccountIdConversionFailed)?;
Assets::transfer(asset_id, &source, &dest, amount, true)
.map_err(|e| XcmError::FailedToTransactAsset(e.into()))?;
Ok(what.clone().into())
@@ -208,7 +167,7 @@ impl<
// Check we handle this asset.
let (asset_id, amount) = Matcher::matches_fungibles(what)?;
let who = AccountIdConverter::convert_ref(who)
.map_err(|()| Error::AccountIdConversionFailed)?;
.map_err(|()| MatchError::AccountIdConversionFailed)?;
Assets::mint_into(asset_id, &who, amount)
.map_err(|e| XcmError::FailedToTransactAsset(e.into()))
}
@@ -220,7 +179,7 @@ impl<
// Check we handle this asset.
let (asset_id, amount) = Matcher::matches_fungibles(what)?;
let who = AccountIdConverter::convert_ref(who)
.map_err(|()| Error::AccountIdConversionFailed)?;
.map_err(|()| MatchError::AccountIdConversionFailed)?;
Assets::burn_from(asset_id, &who, amount)
.map_err(|e| XcmError::FailedToTransactAsset(e.into()))?;
Ok(what.clone().into())
+4
View File
@@ -14,6 +14,10 @@
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! # XCM-Builder
//!
//! Types and helpers for *building* XCM configuration.
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(test)]
@@ -23,7 +23,6 @@ use xcm::v0::{MultiLocation, NetworkId, Junction};
use xcm_executor::traits::{InvertLocation, Convert};
pub struct Account32Hash<Network, AccountId>(PhantomData<(Network, AccountId)>);
impl<
Network: Get<NetworkId>,
AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone,
@@ -37,6 +36,8 @@ impl<
}
}
/// A [`MultiLocation`] consisting of a single `Parent` [`Junction`] will be converted to the
/// default value of `AccountId` (e.g. all zeros for `AccountId32`).
pub struct ParentIsDefault<AccountId>(PhantomData<AccountId>);
impl<
AccountId: Default + Eq + Clone,
@@ -81,7 +82,6 @@ impl<
}
pub struct SiblingParachainConvertsVia<ParaId, AccountId>(PhantomData<(ParaId, AccountId)>);
impl<
ParaId: From<u32> + Into<u32> + AccountIdConversion<AccountId>,
AccountId: Clone,
@@ -103,6 +103,7 @@ impl<
}
}
/// Extracts the `AccountId32` from the passed `location` if the network matches.
pub struct AccountId32Aliases<Network, AccountId>(PhantomData<(Network, AccountId)>);
impl<
Network: Get<NetworkId>,
@@ -142,7 +143,40 @@ impl<
}
}
/// Simple location inverter; give it this location's ancestry and it'll figure out the inverted location.
/// Simple location inverter; give it this location's ancestry and it'll figure out the inverted
/// location.
///
/// # Example
/// ## Network Topology
/// ```txt
/// v Source
/// Relay -> Para 1 -> Account20
/// -> Para 2 -> Account32
/// ^ Target
/// ```
/// ```rust
/// # use frame_support::parameter_types;
/// # use xcm::v0::{MultiLocation::{self, *}, Junction::*, NetworkId::Any};
/// # use xcm_builder::LocationInverter;
/// # use xcm_executor::traits::InvertLocation;
/// # fn main() {
/// parameter_types!{
/// pub Ancestry: MultiLocation = X2(
/// Parachain(1),
/// AccountKey20 { network: Any, key: Default::default() },
/// );
/// }
///
/// let input = X4(Parent, Parent, Parachain(2), AccountId32 { network: Any, id: Default::default() });
/// let inverted = LocationInverter::<Ancestry>::invert_location(&input);
/// assert_eq!(inverted, X4(
/// Parent,
/// Parent,
/// Parachain(1),
/// AccountKey20 { network: Any, key: Default::default() },
/// ));
/// # }
/// ```
pub struct LocationInverter<Ancestry>(PhantomData<Ancestry>);
impl<Ancestry: Get<MultiLocation>> InvertLocation for LocationInverter<Ancestry> {
fn invert_location(location: &MultiLocation) -> MultiLocation {
@@ -160,3 +194,72 @@ impl<Ancestry: Get<MultiLocation>> InvertLocation for LocationInverter<Ancestry>
result
}
}
#[cfg(test)]
mod tests {
use super::*;
use frame_support::parameter_types;
use xcm::v0::{MultiLocation::*, Junction::*, NetworkId::Any};
fn account20() -> Junction {
AccountKey20 { network: Any, key: Default::default() }
}
fn account32() -> Junction {
AccountId32 { network: Any, id: Default::default() }
}
// Network Topology
// v Source
// Relay -> Para 1 -> SmartContract -> Account
// -> Para 2 -> Account
// ^ Target
//
// Inputs and outputs written as file paths:
//
// input location (source to target): ../../../para_2/account32_default
// ancestry (root to source): para_1/account20_default/account20_default
// =>
// output (target to source): ../../para_1/account20_default/account20_default
#[test]
fn inverter_works_in_tree() {
parameter_types!{
pub Ancestry: MultiLocation = X3(Parachain(1), account20(), account20());
}
let input = X5(Parent, Parent, Parent, Parachain(2), account32());
let inverted = LocationInverter::<Ancestry>::invert_location(&input);
assert_eq!(inverted, X5(Parent, Parent, Parachain(1), account20(), account20()));
}
// Network Topology
// v Source
// Relay -> Para 1 -> SmartContract -> Account
// ^ Target
#[test]
fn inverter_uses_ancestry_as_inverted_location() {
parameter_types!{
pub Ancestry: MultiLocation = X2(account20(), account20());
}
let input = X2(Parent, Parent);
let inverted = LocationInverter::<Ancestry>::invert_location(&input);
assert_eq!(inverted, X2(account20(), account20()));
}
// Network Topology
// v Source
// Relay -> Para 1 -> CollectivePallet -> Plurality
// ^ Target
#[test]
fn inverter_uses_only_child_on_missing_ancestry() {
parameter_types!{
pub Ancestry: MultiLocation = X1(PalletInstance(5));
}
let input = X2(Parent, Parent);
let inverted = LocationInverter::<Ancestry>::invert_location(&input);
assert_eq!(inverted, X2(PalletInstance(5), OnlyChild));
}
}
@@ -14,12 +14,35 @@
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Various implementations for the `MatchesFungible` trait.
use sp_std::{marker::PhantomData, convert::TryFrom};
use sp_runtime::traits::CheckedConversion;
use xcm::v0::{MultiAsset, MultiLocation};
use frame_support::traits::Get;
use xcm_executor::traits::MatchesFungible;
/// Converts a `MultiAsset` into balance `B` if it is a concrete fungible with an id equal to that
/// given by `T`'s `Get`.
///
/// # Example
///
/// ```
/// use xcm::v0::{MultiAsset, MultiLocation, Junction};
/// use xcm_builder::IsConcrete;
/// use xcm_executor::traits::MatchesFungible;
///
/// frame_support::parameter_types! {
/// pub TargetLocation: MultiLocation = MultiLocation::X1(Junction::Parent);
/// }
///
/// # fn main() {
/// let id = MultiLocation::X1(Junction::Parent);
/// let asset = MultiAsset::ConcreteFungible { id, amount: 999u128 };
/// // match `asset` if it is a concrete asset in `TargetLocation`.
/// assert_eq!(<IsConcrete<TargetLocation> as MatchesFungible<u128>>::matches_fungible(&asset), Some(999));
/// # }
/// ```
pub struct IsConcrete<T>(PhantomData<T>);
impl<T: Get<MultiLocation>, B: TryFrom<u128>> MatchesFungible<B> for IsConcrete<T> {
fn matches_fungible(a: &MultiAsset) -> Option<B> {
@@ -30,6 +53,26 @@ impl<T: Get<MultiLocation>, B: TryFrom<u128>> MatchesFungible<B> for IsConcrete<
}
}
}
/// Same as [`IsConcrete`] but for a fungible with abstract location.
///
/// # Example
///
/// ```
/// use xcm::v0::{MultiAsset};
/// use xcm_builder::IsAbstract;
/// use xcm_executor::traits::MatchesFungible;
///
/// frame_support::parameter_types! {
/// pub TargetLocation: &'static [u8] = &[7u8];
/// }
///
/// # fn main() {
/// let asset = MultiAsset::AbstractFungible { id: vec![7u8], amount: 999u128 };
/// // match `asset` if it is a concrete asset in `TargetLocation`.
/// assert_eq!(<IsAbstract<TargetLocation> as MatchesFungible<u128>>::matches_fungible(&asset), Some(999));
/// # }
/// ```
pub struct IsAbstract<T>(PhantomData<T>);
impl<T: Get<&'static [u8]>, B: TryFrom<u128>> MatchesFungible<B> for IsAbstract<T> {
fn matches_fungible(a: &MultiAsset) -> Option<B> {
+13 -8
View File
@@ -36,8 +36,17 @@ pub use crate::{
FixedRateOfConcreteFungible, AllowKnownQueryResponses, LocationInverter,
};
pub enum TestOrigin { Root, Relay, Signed(u64), Parachain(u32) }
pub enum TestOrigin {
Root,
Relay,
Signed(u64),
Parachain(u32),
}
/// A dummy call.
///
/// Each item contains the amount of weight that it *wants* to consume as the first item, and the actual amount (if
/// different from the former) in the second option.
#[derive(Debug, Encode, Decode, Eq, PartialEq, Clone, Copy)]
pub enum TestCall {
OnlyRoot(Weight, Option<Weight>),
@@ -60,17 +69,13 @@ impl Dispatchable for TestCall {
=> maybe_actual,
};
if match (&origin, &self) {
(TestOrigin::Parachain(i), TestCall::OnlyParachain(_, _, Some(j)))
=> i == j,
(TestOrigin::Signed(i), TestCall::OnlySigned(_, _, Some(j)))
=> i == j,
(TestOrigin::Parachain(i), TestCall::OnlyParachain(_, _, Some(j))) => i == j,
(TestOrigin::Signed(i), TestCall::OnlySigned(_, _, Some(j))) => i == j,
(TestOrigin::Root, TestCall::OnlyRoot(..))
| (TestOrigin::Parachain(_), TestCall::OnlyParachain(_, _, None))
| (TestOrigin::Signed(_), TestCall::OnlySigned(_, _, None))
| (_, TestCall::Any(..))
=> true,
_ => false,
} {
Ok(post_info)
@@ -151,7 +156,7 @@ pub fn to_account(l: MultiLocation) -> Result<u64, MultiLocation> {
X1(Parachain(id)) => 1000 + id as u64,
// Self at 3000
Null => 3000,
// Parent at 3000
// Parent at 3001
X1(Parent) => 3001,
l => return Err(l),
})
@@ -14,6 +14,8 @@
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Various implementations for `ConvertOrigin`.
use sp_std::{marker::PhantomData, convert::TryInto};
use xcm::v0::{MultiLocation, OriginKind, NetworkId, Junction, BodyId, BodyPart};
use xcm_executor::traits::{Convert, ConvertOrigin};
@@ -21,8 +23,7 @@ use frame_support::traits::{EnsureOrigin, Get, OriginTrait, GetBacking};
use frame_system::RawOrigin as SystemRawOrigin;
use polkadot_parachain::primitives::IsSystem;
/// Sovereign accounts use the system's `Signed` origin with an account ID derived from the
/// `LocationConverter`.
/// Sovereign accounts use the system's `Signed` origin with an account ID derived from the `LocationConverter`.
pub struct SovereignSignedViaLocation<LocationConverter, Origin>(
PhantomData<(LocationConverter, Origin)>
);