XCM: Remove & replace XCM Convert trait (#7329)

* Introduce an extensible location-to-hash-account

* Convert becomes RevFallRefConvert

* Use ConvertLocation trait

* Remove Convert usage

* Builds

* Fix warnings

* Remove unused types

* Bump lock

* No need for aliasing

* Remove unused

* Deprecate legacy conversion

* Fixes

* Fixes

* Update Cargo.toml

Co-authored-by: Muharem Ismailov <ismailov.m.h@gmail.com>

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

Co-authored-by: Liam Aharon <liam.aharon@hotmail.com>

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

Co-authored-by: Liam Aharon <liam.aharon@hotmail.com>

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

Co-authored-by: Liam Aharon <liam.aharon@hotmail.com>

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

Co-authored-by: Liam Aharon <liam.aharon@hotmail.com>

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

Co-authored-by: Liam Aharon <liam.aharon@hotmail.com>

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

Co-authored-by: Liam Aharon <liam.aharon@hotmail.com>

---------

Co-authored-by: Muharem Ismailov <ismailov.m.h@gmail.com>
Co-authored-by: Liam Aharon <liam.aharon@hotmail.com>
This commit is contained in:
Gavin Wood
2023-06-05 12:00:53 +01:00
committed by GitHub
parent 429b1e4de7
commit c8f9b1b7a0
16 changed files with 588 additions and 609 deletions
+183 -184
View File
File diff suppressed because it is too large Load Diff
@@ -24,7 +24,7 @@ use frame_support::{
use sp_runtime::traits::{Bounded, Zero};
use sp_std::{prelude::*, vec};
use xcm::latest::prelude::*;
use xcm_executor::traits::{Convert, TransactAsset};
use xcm_executor::traits::{ConvertLocation, TransactAsset};
benchmarks_instance_pallet! {
where_clause { where
@@ -75,7 +75,7 @@ benchmarks_instance_pallet! {
// this xcm doesn't use holding
let dest_location = T::valid_destination()?;
let dest_account = T::AccountIdConverter::convert(dest_location.clone()).unwrap();
let dest_account = T::AccountIdConverter::convert_location(&dest_location).unwrap();
<AssetTransactorOf<T>>::deposit_asset(
&asset,
@@ -101,7 +101,7 @@ benchmarks_instance_pallet! {
transfer_reserve_asset {
let (sender_account, sender_location) = account_and_location::<T>(1);
let dest_location = T::valid_destination()?;
let dest_account = T::AccountIdConverter::convert(dest_location.clone()).unwrap();
let dest_account = T::AccountIdConverter::convert_location(&dest_location).unwrap();
let asset = T::get_multi_asset();
<AssetTransactorOf<T>>::deposit_asset(
@@ -171,7 +171,7 @@ benchmarks_instance_pallet! {
// our dest must have no balance initially.
let dest_location = T::valid_destination()?;
let dest_account = T::AccountIdConverter::convert(dest_location.clone()).unwrap();
let dest_account = T::AccountIdConverter::convert_location(&dest_location).unwrap();
assert!(T::TransactAsset::balance(&dest_account).is_zero());
let mut executor = new_executor::<T>(Default::default());
@@ -197,7 +197,7 @@ benchmarks_instance_pallet! {
// our dest must have no balance initially.
let dest_location = T::valid_destination()?;
let dest_account = T::AccountIdConverter::convert(dest_location.clone()).unwrap();
let dest_account = T::AccountIdConverter::convert_location(&dest_location).unwrap();
assert!(T::TransactAsset::balance(&dest_account).is_zero());
let mut executor = new_executor::<T>(Default::default());
@@ -22,7 +22,7 @@ use codec::Encode;
use frame_benchmarking::{account, BenchmarkError};
use sp_std::prelude::*;
use xcm::latest::prelude::*;
use xcm_executor::{traits::Convert, Config as XcmConfig};
use xcm_executor::{traits::ConvertLocation, Config as XcmConfig};
pub mod fungible;
pub mod generic;
@@ -39,7 +39,7 @@ pub trait Config: frame_system::Config {
type XcmConfig: XcmConfig;
/// A converter between a multi-location to a sovereign account.
type AccountIdConverter: Convert<MultiLocation, Self::AccountId>;
type AccountIdConverter: ConvertLocation<Self::AccountId>;
/// Does any necessary setup to create a valid destination for XCM messages.
/// Returns that destination's multi-location to be used in benchmarks.
@@ -104,7 +104,7 @@ fn account_id_junction<T: frame_system::Config>(index: u32) -> Junction {
pub fn account_and_location<T: Config>(index: u32) -> (T::AccountId, MultiLocation) {
let location: MultiLocation = account_id_junction::<T>(index).into();
let account = T::AccountIdConverter::convert(location.clone()).unwrap();
let account = T::AccountIdConverter::convert_location(&location).unwrap();
(account, location)
}
@@ -47,18 +47,14 @@ impl xcm_executor::traits::OnResponse for DevNull {
}
pub struct AccountIdConverter;
impl xcm_executor::traits::Convert<MultiLocation, u64> for AccountIdConverter {
fn convert(ml: MultiLocation) -> Result<u64, MultiLocation> {
impl xcm_executor::traits::ConvertLocation<u64> for AccountIdConverter {
fn convert_location(ml: &MultiLocation) -> Option<u64> {
match ml {
MultiLocation { parents: 0, interior: X1(Junction::AccountId32 { id, .. }) } =>
Ok(<u64 as codec::Decode>::decode(&mut &*id.to_vec()).unwrap()),
_ => Err(ml),
Some(<u64 as codec::Decode>::decode(&mut &*id.to_vec()).unwrap()),
_ => None,
}
}
fn reverse(acc: u64) -> Result<MultiLocation, u64> {
Err(acc)
}
}
parameter_types! {
+8 -8
View File
@@ -40,7 +40,7 @@ use sp_runtime::{
};
use sp_std::{boxed::Box, marker::PhantomData, prelude::*, result::Result, vec};
use xcm::{latest::QueryResponseInfo, prelude::*};
use xcm_executor::traits::{Convert, ConvertOrigin, Properties};
use xcm_executor::traits::{ConvertOrigin, Properties};
use frame_support::{
dispatch::{Dispatchable, GetDispatchInfo},
@@ -52,8 +52,8 @@ use frame_system::pallet_prelude::*;
pub use pallet::*;
use xcm_executor::{
traits::{
CheckSuspension, ClaimAssets, DropAssets, MatchesFungible, OnResponse, QueryHandler,
QueryResponseStatus, VersionChangeNotifier, WeightBounds,
CheckSuspension, ClaimAssets, ConvertLocation, DropAssets, MatchesFungible, OnResponse,
QueryHandler, QueryResponseStatus, VersionChangeNotifier, WeightBounds,
},
Assets,
};
@@ -247,7 +247,7 @@ pub mod pallet {
type TrustedLockers: ContainsPair<MultiLocation, MultiAsset>;
/// How to get an `AccountId` value from a `MultiLocation`, useful for handling asset locks.
type SovereignAccountOf: Convert<MultiLocation, Self::AccountId>;
type SovereignAccountOf: ConvertLocation<Self::AccountId>;
/// The maximum number of local XCM locks that a single account may have.
type MaxLockers: Get<u32>;
@@ -1750,7 +1750,7 @@ impl<T: Config> xcm_executor::traits::AssetLock for Pallet<T> {
owner: MultiLocation,
) -> Result<LockTicket<T>, xcm_executor::traits::LockError> {
use xcm_executor::traits::LockError::*;
let sovereign_account = T::SovereignAccountOf::convert_ref(&owner).map_err(|_| BadOwner)?;
let sovereign_account = T::SovereignAccountOf::convert_location(&owner).ok_or(BadOwner)?;
let amount = T::CurrencyMatcher::matches_fungible(&asset).ok_or(UnknownAsset)?;
ensure!(T::Currency::free_balance(&sovereign_account) >= amount, AssetNotOwned);
let locks = LockedFungibles::<T>::get(&sovereign_account).unwrap_or_default();
@@ -1765,7 +1765,7 @@ impl<T: Config> xcm_executor::traits::AssetLock for Pallet<T> {
owner: MultiLocation,
) -> Result<UnlockTicket<T>, xcm_executor::traits::LockError> {
use xcm_executor::traits::LockError::*;
let sovereign_account = T::SovereignAccountOf::convert_ref(&owner).map_err(|_| BadOwner)?;
let sovereign_account = T::SovereignAccountOf::convert_location(&owner).ok_or(BadOwner)?;
let amount = T::CurrencyMatcher::matches_fungible(&asset).ok_or(UnknownAsset)?;
ensure!(T::Currency::free_balance(&sovereign_account) >= amount, AssetNotOwned);
let locks = LockedFungibles::<T>::get(&sovereign_account).unwrap_or_default();
@@ -1787,7 +1787,7 @@ impl<T: Config> xcm_executor::traits::AssetLock for Pallet<T> {
NonFungible(_) => return Err(Unimplemented),
};
owner.remove_network_id();
let account = T::SovereignAccountOf::convert_ref(&owner).map_err(|_| BadOwner)?;
let account = T::SovereignAccountOf::convert_location(&owner).ok_or(BadOwner)?;
let locker = locker.into();
let owner = owner.into();
let id: VersionedAssetId = asset.id.into();
@@ -1815,7 +1815,7 @@ impl<T: Config> xcm_executor::traits::AssetLock for Pallet<T> {
NonFungible(_) => return Err(Unimplemented),
};
owner.remove_network_id();
let sovereign_account = T::SovereignAccountOf::convert_ref(&owner).map_err(|_| BadOwner)?;
let sovereign_account = T::SovereignAccountOf::convert_location(&owner).ok_or(BadOwner)?;
let locker = locker.into();
let owner = owner.into();
let id: VersionedAssetId = asset.id.into();
@@ -17,9 +17,10 @@
//! Adapters to work with `frame_support::traits::tokens::fungibles` through XCM.
use frame_support::traits::{Contains, Get};
use sp_std::{borrow::Borrow, marker::PhantomData, prelude::*, result};
use sp_runtime::traits::MaybeEquivalence;
use sp_std::{marker::PhantomData, prelude::*, result};
use xcm::latest::prelude::*;
use xcm_executor::traits::{Convert, Error as MatchError, MatchesFungibles, MatchesNonFungibles};
use xcm_executor::traits::{Error as MatchError, MatchesFungibles, MatchesNonFungibles};
/// 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
@@ -27,12 +28,15 @@ use xcm_executor::traits::{Convert, Error as MatchError, MatchesFungibles, Match
pub struct AsPrefixedGeneralIndex<Prefix, AssetId, ConvertAssetId>(
PhantomData<(Prefix, AssetId, ConvertAssetId)>,
);
impl<Prefix: Get<MultiLocation>, AssetId: Clone, ConvertAssetId: Convert<u128, AssetId>>
Convert<MultiLocation, AssetId> for AsPrefixedGeneralIndex<Prefix, AssetId, ConvertAssetId>
impl<
Prefix: Get<MultiLocation>,
AssetId: Clone,
ConvertAssetId: MaybeEquivalence<u128, AssetId>,
> MaybeEquivalence<MultiLocation, AssetId>
for AsPrefixedGeneralIndex<Prefix, AssetId, ConvertAssetId>
{
fn convert_ref(id: impl Borrow<MultiLocation>) -> result::Result<AssetId, ()> {
fn convert(id: &MultiLocation) -> Option<AssetId> {
let prefix = Prefix::get();
let id = id.borrow();
if prefix.parent_count() != id.parent_count() ||
prefix
.interior()
@@ -40,18 +44,18 @@ impl<Prefix: Get<MultiLocation>, AssetId: Clone, ConvertAssetId: Convert<u128, A
.enumerate()
.any(|(index, junction)| id.interior().at(index) != Some(junction))
{
return Err(())
return None
}
match id.interior().at(prefix.interior().len()) {
Some(Junction::GeneralIndex(id)) => ConvertAssetId::convert_ref(id),
_ => Err(()),
Some(Junction::GeneralIndex(id)) => ConvertAssetId::convert(id),
_ => None,
}
}
fn reverse_ref(what: impl Borrow<AssetId>) -> result::Result<MultiLocation, ()> {
fn convert_back(what: &AssetId) -> Option<MultiLocation> {
let mut location = Prefix::get();
let id = ConvertAssetId::reverse_ref(what)?;
location.push_interior(Junction::GeneralIndex(id)).map_err(|_| ())?;
Ok(location)
let id = ConvertAssetId::convert_back(what)?;
location.push_interior(Junction::GeneralIndex(id)).ok()?;
Some(location)
}
}
@@ -61,8 +65,8 @@ pub struct ConvertedConcreteId<AssetId, Balance, ConvertAssetId, ConvertOther>(
impl<
AssetId: Clone,
Balance: Clone,
ConvertAssetId: Convert<MultiLocation, AssetId>,
ConvertBalance: Convert<u128, Balance>,
ConvertAssetId: MaybeEquivalence<MultiLocation, AssetId>,
ConvertBalance: MaybeEquivalence<u128, Balance>,
> MatchesFungibles<AssetId, Balance>
for ConvertedConcreteId<AssetId, Balance, ConvertAssetId, ConvertBalance>
{
@@ -71,18 +75,17 @@ impl<
(Fungible(ref amount), Concrete(ref id)) => (amount, id),
_ => return Err(MatchError::AssetNotHandled),
};
let what =
ConvertAssetId::convert_ref(id).map_err(|_| MatchError::AssetIdConversionFailed)?;
let amount = ConvertBalance::convert_ref(amount)
.map_err(|_| MatchError::AmountToBalanceConversionFailed)?;
let what = ConvertAssetId::convert(id).ok_or(MatchError::AssetIdConversionFailed)?;
let amount =
ConvertBalance::convert(amount).ok_or(MatchError::AmountToBalanceConversionFailed)?;
Ok((what, amount))
}
}
impl<
ClassId: Clone,
InstanceId: Clone,
ConvertClassId: Convert<MultiLocation, ClassId>,
ConvertInstanceId: Convert<AssetInstance, InstanceId>,
ConvertClassId: MaybeEquivalence<MultiLocation, ClassId>,
ConvertInstanceId: MaybeEquivalence<AssetInstance, InstanceId>,
> MatchesNonFungibles<ClassId, InstanceId>
for ConvertedConcreteId<ClassId, InstanceId, ConvertClassId, ConvertInstanceId>
{
@@ -91,10 +94,9 @@ impl<
(NonFungible(ref instance), Concrete(ref class)) => (instance, class),
_ => return Err(MatchError::AssetNotHandled),
};
let what =
ConvertClassId::convert_ref(class).map_err(|_| MatchError::AssetIdConversionFailed)?;
let instance = ConvertInstanceId::convert_ref(instance)
.map_err(|_| MatchError::InstanceConversionFailed)?;
let what = ConvertClassId::convert(class).ok_or(MatchError::AssetIdConversionFailed)?;
let instance =
ConvertInstanceId::convert(instance).ok_or(MatchError::InstanceConversionFailed)?;
Ok((what, instance))
}
}
@@ -105,8 +107,8 @@ pub struct ConvertedAbstractId<AssetId, Balance, ConvertAssetId, ConvertOther>(
impl<
AssetId: Clone,
Balance: Clone,
ConvertAssetId: Convert<[u8; 32], AssetId>,
ConvertBalance: Convert<u128, Balance>,
ConvertAssetId: MaybeEquivalence<[u8; 32], AssetId>,
ConvertBalance: MaybeEquivalence<u128, Balance>,
> MatchesFungibles<AssetId, Balance>
for ConvertedAbstractId<AssetId, Balance, ConvertAssetId, ConvertBalance>
{
@@ -115,18 +117,17 @@ impl<
(Fungible(ref amount), Abstract(ref id)) => (amount, id),
_ => return Err(MatchError::AssetNotHandled),
};
let what =
ConvertAssetId::convert_ref(id).map_err(|_| MatchError::AssetIdConversionFailed)?;
let amount = ConvertBalance::convert_ref(amount)
.map_err(|_| MatchError::AmountToBalanceConversionFailed)?;
let what = ConvertAssetId::convert(id).ok_or(MatchError::AssetIdConversionFailed)?;
let amount =
ConvertBalance::convert(amount).ok_or(MatchError::AmountToBalanceConversionFailed)?;
Ok((what, amount))
}
}
impl<
ClassId: Clone,
InstanceId: Clone,
ConvertClassId: Convert<[u8; 32], ClassId>,
ConvertInstanceId: Convert<AssetInstance, InstanceId>,
ConvertClassId: MaybeEquivalence<[u8; 32], ClassId>,
ConvertInstanceId: MaybeEquivalence<AssetInstance, InstanceId>,
> MatchesNonFungibles<ClassId, InstanceId>
for ConvertedAbstractId<ClassId, InstanceId, ConvertClassId, ConvertInstanceId>
{
@@ -135,10 +136,9 @@ impl<
(NonFungible(ref instance), Abstract(ref class)) => (instance, class),
_ => return Err(MatchError::AssetNotHandled),
};
let what =
ConvertClassId::convert_ref(class).map_err(|_| MatchError::AssetIdConversionFailed)?;
let instance = ConvertInstanceId::convert_ref(instance)
.map_err(|_| MatchError::InstanceConversionFailed)?;
let what = ConvertClassId::convert(class).ok_or(MatchError::AssetIdConversionFailed)?;
let instance =
ConvertInstanceId::convert(instance).ok_or(MatchError::InstanceConversionFailed)?;
Ok((what, instance))
}
}
@@ -155,8 +155,8 @@ impl<
AssetId: Clone,
Balance: Clone,
MatchAssetId: Contains<MultiLocation>,
ConvertAssetId: Convert<MultiLocation, AssetId>,
ConvertBalance: Convert<u128, Balance>,
ConvertAssetId: MaybeEquivalence<MultiLocation, AssetId>,
ConvertBalance: MaybeEquivalence<u128, Balance>,
> MatchesFungibles<AssetId, Balance>
for MatchedConvertedConcreteId<AssetId, Balance, MatchAssetId, ConvertAssetId, ConvertBalance>
{
@@ -165,10 +165,9 @@ impl<
(Fungible(ref amount), Concrete(ref id)) if MatchAssetId::contains(id) => (amount, id),
_ => return Err(MatchError::AssetNotHandled),
};
let what =
ConvertAssetId::convert_ref(id).map_err(|_| MatchError::AssetIdConversionFailed)?;
let amount = ConvertBalance::convert_ref(amount)
.map_err(|_| MatchError::AmountToBalanceConversionFailed)?;
let what = ConvertAssetId::convert(id).ok_or(MatchError::AssetIdConversionFailed)?;
let amount =
ConvertBalance::convert(amount).ok_or(MatchError::AmountToBalanceConversionFailed)?;
Ok((what, amount))
}
}
@@ -176,8 +175,8 @@ impl<
ClassId: Clone,
InstanceId: Clone,
MatchClassId: Contains<MultiLocation>,
ConvertClassId: Convert<MultiLocation, ClassId>,
ConvertInstanceId: Convert<AssetInstance, InstanceId>,
ConvertClassId: MaybeEquivalence<MultiLocation, ClassId>,
ConvertInstanceId: MaybeEquivalence<AssetInstance, InstanceId>,
> MatchesNonFungibles<ClassId, InstanceId>
for MatchedConvertedConcreteId<ClassId, InstanceId, MatchClassId, ConvertClassId, ConvertInstanceId>
{
@@ -187,10 +186,9 @@ impl<
(instance, class),
_ => return Err(MatchError::AssetNotHandled),
};
let what =
ConvertClassId::convert_ref(class).map_err(|_| MatchError::AssetIdConversionFailed)?;
let instance = ConvertInstanceId::convert_ref(instance)
.map_err(|_| MatchError::InstanceConversionFailed)?;
let what = ConvertClassId::convert(class).ok_or(MatchError::AssetIdConversionFailed)?;
let instance =
ConvertInstanceId::convert(instance).ok_or(MatchError::InstanceConversionFailed)?;
Ok((what, instance))
}
}
@@ -286,13 +284,13 @@ mod tests {
// ConvertedConcreteId cfg
struct ClassInstanceIdConverter;
impl Convert<AssetInstance, ClassInstanceId> for ClassInstanceIdConverter {
fn convert_ref(value: impl Borrow<AssetInstance>) -> Result<ClassInstanceId, ()> {
value.borrow().clone().try_into().map_err(|_| ())
impl MaybeEquivalence<AssetInstance, ClassInstanceId> for ClassInstanceIdConverter {
fn convert(value: &AssetInstance) -> Option<ClassInstanceId> {
value.clone().try_into().ok()
}
fn reverse_ref(value: impl Borrow<ClassInstanceId>) -> Result<AssetInstance, ()> {
Ok(AssetInstance::from(value.borrow().clone()))
fn convert_back(value: &ClassInstanceId) -> Option<AssetInstance> {
Some(AssetInstance::from(value.clone()))
}
}
@@ -22,7 +22,7 @@ use sp_runtime::traits::CheckedSub;
use sp_std::{marker::PhantomData, result};
use xcm::latest::{Error as XcmError, MultiAsset, MultiLocation, Result, XcmContext};
use xcm_executor::{
traits::{Convert, MatchesFungible, TransactAsset},
traits::{ConvertLocation, MatchesFungible, TransactAsset},
Assets,
};
@@ -64,7 +64,7 @@ impl From<Error> for XcmError {
/// pub CheckingAccount: AccountId = PalletId(*b"checking").into_account_truncating();
/// }
///
/// /// Some items that implement `Convert<MultiLocation, AccountId>`. Can be more, but for now we just assume we accept
/// /// Some items that implement `ConvertLocation<AccountId>`. Can be more, but for now we just assume we accept
/// /// messages from the parent (relay chain).
/// pub type LocationConverter = (ParentIsPreset<AccountId>);
///
@@ -92,7 +92,7 @@ pub struct CurrencyAdapter<Currency, Matcher, AccountIdConverter, AccountId, Che
impl<
Currency: frame_support::traits::Currency<AccountId>,
Matcher: MatchesFungible<Currency::Balance>,
AccountIdConverter: Convert<MultiLocation, AccountId>,
AccountIdConverter: ConvertLocation<AccountId>,
AccountId: Clone, // can't get away without it since Currency is generic over it.
CheckedAccount: Get<Option<(AccountId, MintLocation)>>,
> CurrencyAdapter<Currency, Matcher, AccountIdConverter, AccountId, CheckedAccount>
@@ -133,7 +133,7 @@ impl<
impl<
Currency: frame_support::traits::Currency<AccountId>,
Matcher: MatchesFungible<Currency::Balance>,
AccountIdConverter: Convert<MultiLocation, AccountId>,
AccountIdConverter: ConvertLocation<AccountId>,
AccountId: Clone, // can't get away without it since Currency is generic over it.
CheckedAccount: Get<Option<(AccountId, MintLocation)>>,
> TransactAsset
@@ -196,7 +196,7 @@ impl<
// Check we handle this asset.
let amount = Matcher::matches_fungible(&what).ok_or(Error::AssetNotHandled)?;
let who =
AccountIdConverter::convert_ref(who).map_err(|()| Error::AccountIdConversionFailed)?;
AccountIdConverter::convert_location(who).ok_or(Error::AccountIdConversionFailed)?;
let _imbalance = Currency::deposit_creating(&who, amount);
Ok(())
}
@@ -210,7 +210,7 @@ impl<
// Check we handle this asset.
let amount = Matcher::matches_fungible(what).ok_or(Error::AssetNotHandled)?;
let who =
AccountIdConverter::convert_ref(who).map_err(|()| Error::AccountIdConversionFailed)?;
AccountIdConverter::convert_location(who).ok_or(Error::AccountIdConversionFailed)?;
Currency::withdraw(&who, amount, WithdrawReasons::TRANSFER, AllowDeath)
.map_err(|e| XcmError::FailedToTransactAsset(e.into()))?;
Ok(what.clone().into())
@@ -225,9 +225,9 @@ impl<
log::trace!(target: "xcm::currency_adapter", "internal_transfer_asset asset: {:?}, from: {:?}, to: {:?}", asset, from, to);
let amount = Matcher::matches_fungible(asset).ok_or(Error::AssetNotHandled)?;
let from =
AccountIdConverter::convert_ref(from).map_err(|()| Error::AccountIdConversionFailed)?;
AccountIdConverter::convert_location(from).ok_or(Error::AccountIdConversionFailed)?;
let to =
AccountIdConverter::convert_ref(to).map_err(|()| Error::AccountIdConversionFailed)?;
AccountIdConverter::convert_location(to).ok_or(Error::AccountIdConversionFailed)?;
Currency::transfer(&from, &to, amount, AllowDeath)
.map_err(|e| XcmError::FailedToTransactAsset(e.into()))?;
Ok(asset.clone().into())
@@ -24,7 +24,7 @@ use frame_support::traits::{
};
use sp_std::{marker::PhantomData, prelude::*, result};
use xcm::latest::prelude::*;
use xcm_executor::traits::{Convert, Error as MatchError, MatchesFungibles, TransactAsset};
use xcm_executor::traits::{ConvertLocation, Error as MatchError, MatchesFungibles, TransactAsset};
/// `TransactAsset` implementation to convert a `fungibles` implementation to become usable in XCM.
pub struct FungiblesTransferAdapter<Assets, Matcher, AccountIdConverter, AccountId>(
@@ -33,7 +33,7 @@ pub struct FungiblesTransferAdapter<Assets, Matcher, AccountIdConverter, Account
impl<
Assets: fungibles::Mutate<AccountId>,
Matcher: MatchesFungibles<Assets::AssetId, Assets::Balance>,
AccountIdConverter: Convert<MultiLocation, AccountId>,
AccountIdConverter: ConvertLocation<AccountId>,
AccountId: Clone, // can't get away without it since Currency is generic over it.
> TransactAsset for FungiblesTransferAdapter<Assets, Matcher, AccountIdConverter, AccountId>
{
@@ -50,10 +50,10 @@ impl<
);
// Check we handle this asset.
let (asset_id, amount) = Matcher::matches_fungibles(what)?;
let source = AccountIdConverter::convert_ref(from)
.map_err(|()| MatchError::AccountIdConversionFailed)?;
let dest = AccountIdConverter::convert_ref(to)
.map_err(|()| MatchError::AccountIdConversionFailed)?;
let source = AccountIdConverter::convert_location(from)
.ok_or(MatchError::AccountIdConversionFailed)?;
let dest = AccountIdConverter::convert_location(to)
.ok_or(MatchError::AccountIdConversionFailed)?;
Assets::transfer(asset_id, &source, &dest, amount, Preserve)
.map_err(|e| XcmError::FailedToTransactAsset(e.into()))?;
Ok(what.clone().into())
@@ -149,7 +149,7 @@ pub struct FungiblesMutateAdapter<
impl<
Assets: fungibles::Mutate<AccountId>,
Matcher: MatchesFungibles<Assets::AssetId, Assets::Balance>,
AccountIdConverter: Convert<MultiLocation, AccountId>,
AccountIdConverter: ConvertLocation<AccountId>,
AccountId: Clone, // can't get away without it since Currency is generic over it.
CheckAsset: AssetChecking<Assets::AssetId>,
CheckingAccount: Get<AccountId>,
@@ -184,7 +184,7 @@ impl<
impl<
Assets: fungibles::Mutate<AccountId>,
Matcher: MatchesFungibles<Assets::AssetId, Assets::Balance>,
AccountIdConverter: Convert<MultiLocation, AccountId>,
AccountIdConverter: ConvertLocation<AccountId>,
AccountId: Clone, // can't get away without it since Currency is generic over it.
CheckAsset: AssetChecking<Assets::AssetId>,
CheckingAccount: Get<AccountId>,
@@ -282,8 +282,8 @@ impl<
);
// Check we handle this asset.
let (asset_id, amount) = Matcher::matches_fungibles(what)?;
let who = AccountIdConverter::convert_ref(who)
.map_err(|()| MatchError::AccountIdConversionFailed)?;
let who = AccountIdConverter::convert_location(who)
.ok_or(MatchError::AccountIdConversionFailed)?;
Assets::mint_into(asset_id, &who, amount)
.map_err(|e| XcmError::FailedToTransactAsset(e.into()))?;
Ok(())
@@ -301,8 +301,8 @@ impl<
);
// Check we handle this asset.
let (asset_id, amount) = Matcher::matches_fungibles(what)?;
let who = AccountIdConverter::convert_ref(who)
.map_err(|()| MatchError::AccountIdConversionFailed)?;
let who = AccountIdConverter::convert_location(who)
.ok_or(MatchError::AccountIdConversionFailed)?;
Assets::burn_from(asset_id, &who, amount, Exact, Polite)
.map_err(|e| XcmError::FailedToTransactAsset(e.into()))?;
Ok(what.clone().into())
@@ -320,7 +320,7 @@ pub struct FungiblesAdapter<
impl<
Assets: fungibles::Mutate<AccountId>,
Matcher: MatchesFungibles<Assets::AssetId, Assets::Balance>,
AccountIdConverter: Convert<MultiLocation, AccountId>,
AccountIdConverter: ConvertLocation<AccountId>,
AccountId: Clone, // can't get away without it since Currency is generic over it.
CheckAsset: AssetChecking<Assets::AssetId>,
CheckingAccount: Get<AccountId>,
+6 -2
View File
@@ -27,10 +27,14 @@ mod tests;
pub mod test_utils;
mod location_conversion;
#[allow(deprecated)]
pub use location_conversion::ForeignChainAliasAccount;
pub use location_conversion::{
Account32Hash, AccountId32Aliases, AccountKey20Aliases, AliasesIntoAccountId32,
ChildParachainConvertsVia, GlobalConsensusParachainConvertsFor, ParentIsPreset,
SiblingParachainConvertsVia,
ChildParachainConvertsVia, DescribeAccountId32Terminal, DescribeAccountIdTerminal,
DescribeAccountKey20Terminal, DescribeAllTerminal, DescribeFamily, DescribeLocation,
DescribePalletTerminal, DescribeTerminus, GlobalConsensusParachainConvertsFor,
HashedDescription, ParentIsPreset, SiblingParachainConvertsVia,
};
mod origin_conversion;
@@ -16,12 +16,155 @@
use crate::universal_exports::ensure_is_remote;
use frame_support::traits::Get;
use parity_scale_codec::{Decode, Encode};
use parity_scale_codec::{Compact, Decode, Encode};
use sp_io::hashing::blake2_256;
use sp_runtime::traits::{AccountIdConversion, TrailingZeroInput};
use sp_std::{borrow::Borrow, marker::PhantomData};
use sp_runtime::traits::{AccountIdConversion, Convert, TrailingZeroInput};
use sp_std::{marker::PhantomData, prelude::*};
use xcm::latest::prelude::*;
use xcm_executor::traits::Convert;
use xcm_executor::traits::ConvertLocation;
/// Means of converting a location into a stable and unique descriptive identifier.
pub trait DescribeLocation {
/// Create a description of the given `location` if possible. No two locations should have the
/// same descriptor.
fn describe_location(location: &MultiLocation) -> Option<Vec<u8>>;
}
#[impl_trait_for_tuples::impl_for_tuples(30)]
impl DescribeLocation for Tuple {
fn describe_location(l: &MultiLocation) -> Option<Vec<u8>> {
for_tuples!( #(
match Tuple::describe_location(l) {
Some(result) => return Some(result),
None => {},
}
)* );
None
}
}
pub struct DescribeTerminus;
impl DescribeLocation for DescribeTerminus {
fn describe_location(l: &MultiLocation) -> Option<Vec<u8>> {
match (l.parents, &l.interior) {
(0, Here) => Some(Vec::new()),
_ => return None,
}
}
}
pub struct DescribePalletTerminal;
impl DescribeLocation for DescribePalletTerminal {
fn describe_location(l: &MultiLocation) -> Option<Vec<u8>> {
match (l.parents, &l.interior) {
(0, X1(PalletInstance(i))) =>
Some((b"Pallet", Compact::<u32>::from(*i as u32)).encode()),
_ => return None,
}
}
}
pub struct DescribeAccountId32Terminal;
impl DescribeLocation for DescribeAccountId32Terminal {
fn describe_location(l: &MultiLocation) -> Option<Vec<u8>> {
match (l.parents, &l.interior) {
(0, X1(AccountId32 { id, .. })) => Some((b"AccountId32", id).encode()),
_ => return None,
}
}
}
pub struct DescribeAccountKey20Terminal;
impl DescribeLocation for DescribeAccountKey20Terminal {
fn describe_location(l: &MultiLocation) -> Option<Vec<u8>> {
match (l.parents, &l.interior) {
(0, X1(AccountKey20 { key, .. })) => Some((b"AccountKey20", key).encode()),
_ => return None,
}
}
}
pub type DescribeAccountIdTerminal = (DescribeAccountId32Terminal, DescribeAccountKey20Terminal);
pub type DescribeAllTerminal = (
DescribeTerminus,
DescribePalletTerminal,
DescribeAccountId32Terminal,
DescribeAccountKey20Terminal,
);
pub struct DescribeFamily<DescribeInterior>(PhantomData<DescribeInterior>);
impl<Suffix: DescribeLocation> DescribeLocation for DescribeFamily<Suffix> {
fn describe_location(l: &MultiLocation) -> Option<Vec<u8>> {
match (l.parents, l.interior.first()) {
(0, Some(Parachain(index))) => {
let tail = l.interior.split_first().0;
let interior = Suffix::describe_location(&tail.into())?;
Some((b"ChildChain", Compact::<u32>::from(*index), interior).encode())
},
(1, Some(Parachain(index))) => {
let tail = l.interior.split_first().0;
let interior = Suffix::describe_location(&tail.into())?;
Some((b"SiblingChain", Compact::<u32>::from(*index), interior).encode())
},
(1, _) => {
let tail = l.interior.into();
let interior = Suffix::describe_location(&tail)?;
Some((b"ParentChain", interior).encode())
},
_ => return None,
}
}
}
pub struct HashedDescription<AccountId, Describe>(PhantomData<(AccountId, Describe)>);
impl<AccountId: From<[u8; 32]> + Clone, Describe: DescribeLocation> ConvertLocation<AccountId>
for HashedDescription<AccountId, Describe>
{
fn convert_location(value: &MultiLocation) -> Option<AccountId> {
Some(blake2_256(&Describe::describe_location(value)?).into())
}
}
/// This is a describer for legacy support of the `ForeignChainAliasAccount` preimage. New chains
/// are recommended to use the more extensible `HashedDescription` type.
pub struct LegacyDescribeForeignChainAccount;
impl DescribeLocation for LegacyDescribeForeignChainAccount {
fn describe_location(location: &MultiLocation) -> Option<Vec<u8>> {
Some(match location {
// Used on the relay chain for sending paras that use 32 byte accounts
MultiLocation {
parents: 0,
interior: X2(Parachain(para_id), AccountId32 { id, .. }),
} => LegacyDescribeForeignChainAccount::from_para_32(para_id, id, 0),
// Used on the relay chain for sending paras that use 20 byte accounts
MultiLocation {
parents: 0,
interior: X2(Parachain(para_id), AccountKey20 { key, .. }),
} => LegacyDescribeForeignChainAccount::from_para_20(para_id, key, 0),
// Used on para-chain for sending paras that use 32 byte accounts
MultiLocation {
parents: 1,
interior: X2(Parachain(para_id), AccountId32 { id, .. }),
} => LegacyDescribeForeignChainAccount::from_para_32(para_id, id, 1),
// Used on para-chain for sending paras that use 20 byte accounts
MultiLocation {
parents: 1,
interior: X2(Parachain(para_id), AccountKey20 { key, .. }),
} => LegacyDescribeForeignChainAccount::from_para_20(para_id, key, 1),
// Used on para-chain for sending from the relay chain
MultiLocation { parents: 1, interior: X1(AccountId32 { id, .. }) } =>
LegacyDescribeForeignChainAccount::from_relay_32(id, 1),
// No other conversions provided
_ => return None,
})
}
}
/// Prefix for generating alias account for accounts coming
/// from chains that use 32 byte long representations.
@@ -35,6 +178,39 @@ pub const FOREIGN_CHAIN_PREFIX_PARA_20: [u8; 37] = *b"ForeignChainAliasAccountPr
/// from the relay chain using 32 byte long representations.
pub const FOREIGN_CHAIN_PREFIX_RELAY: [u8; 36] = *b"ForeignChainAliasAccountPrefix_Relay";
impl LegacyDescribeForeignChainAccount {
fn from_para_32(para_id: &u32, id: &[u8; 32], parents: u8) -> Vec<u8> {
(FOREIGN_CHAIN_PREFIX_PARA_32, para_id, id, parents).encode()
}
fn from_para_20(para_id: &u32, id: &[u8; 20], parents: u8) -> Vec<u8> {
(FOREIGN_CHAIN_PREFIX_PARA_20, para_id, id, parents).encode()
}
fn from_relay_32(id: &[u8; 32], parents: u8) -> Vec<u8> {
(FOREIGN_CHAIN_PREFIX_RELAY, id, parents).encode()
}
}
/// This is deprecated in favour of the more modular `HashedDescription` converter. If
/// your chain has previously used this, then you can retain backwards compatibility using
/// `HashedDescription` and a tuple with `LegacyDescribeForeignChainAccount` as the first
/// element. For example:
///
/// ```nocompile
/// pub type LocationToAccount = HashedDescription<
/// // Legacy conversion - MUST BE FIRST!
/// LegacyDescribeForeignChainAccount,
/// // Other conversions
/// DescribeTerminus,
/// DescribePalletTerminal,
/// >;
/// ```
///
/// This type is equivalent to the above but without any other conversions.
///
/// ### Old documentation
///
/// This converter will for a given `AccountId32`/`AccountKey20`
/// always generate the same "remote" account for a specific
/// sending chain.
@@ -68,145 +244,58 @@ pub const FOREIGN_CHAIN_PREFIX_RELAY: [u8; 36] = *b"ForeignChainAliasAccountPref
///
/// Note that the alias accounts have overlaps but never on the same
/// chain when the sender comes from different chains.
pub struct ForeignChainAliasAccount<AccountId>(PhantomData<AccountId>);
impl<AccountId: From<[u8; 32]> + Clone> Convert<MultiLocation, AccountId>
for ForeignChainAliasAccount<AccountId>
{
fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
let entropy = match location.borrow() {
// Used on the relay chain for sending paras that use 32 byte accounts
MultiLocation {
parents: 0,
interior: X2(Parachain(para_id), AccountId32 { id, .. }),
} => ForeignChainAliasAccount::<AccountId>::from_para_32(para_id, id, 0),
// Used on the relay chain for sending paras that use 20 byte accounts
MultiLocation {
parents: 0,
interior: X2(Parachain(para_id), AccountKey20 { key, .. }),
} => ForeignChainAliasAccount::<AccountId>::from_para_20(para_id, key, 0),
// Used on para-chain for sending paras that use 32 byte accounts
MultiLocation {
parents: 1,
interior: X2(Parachain(para_id), AccountId32 { id, .. }),
} => ForeignChainAliasAccount::<AccountId>::from_para_32(para_id, id, 1),
// Used on para-chain for sending paras that use 20 byte accounts
MultiLocation {
parents: 1,
interior: X2(Parachain(para_id), AccountKey20 { key, .. }),
} => ForeignChainAliasAccount::<AccountId>::from_para_20(para_id, key, 1),
// Used on para-chain for sending from the relay chain
MultiLocation { parents: 1, interior: X1(AccountId32 { id, .. }) } =>
ForeignChainAliasAccount::<AccountId>::from_relay_32(id, 1),
// No other conversions provided
_ => return Err(()),
};
Ok(entropy.into())
}
fn reverse_ref(_: impl Borrow<AccountId>) -> Result<MultiLocation, ()> {
Err(())
}
}
impl<AccountId> ForeignChainAliasAccount<AccountId> {
fn from_para_32(para_id: &u32, id: &[u8; 32], parents: u8) -> [u8; 32] {
(FOREIGN_CHAIN_PREFIX_PARA_32, para_id, id, parents).using_encoded(blake2_256)
}
fn from_para_20(para_id: &u32, id: &[u8; 20], parents: u8) -> [u8; 32] {
(FOREIGN_CHAIN_PREFIX_PARA_20, para_id, id, parents).using_encoded(blake2_256)
}
fn from_relay_32(id: &[u8; 32], parents: u8) -> [u8; 32] {
(FOREIGN_CHAIN_PREFIX_RELAY, id, parents).using_encoded(blake2_256)
}
}
#[deprecated = "Use `HashedDescription<AccountId, LegacyDescribeForeignChainAccount>` instead"]
pub type ForeignChainAliasAccount<AccountId> =
HashedDescription<AccountId, LegacyDescribeForeignChainAccount>;
pub struct Account32Hash<Network, AccountId>(PhantomData<(Network, AccountId)>);
impl<Network: Get<Option<NetworkId>>, AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone>
Convert<MultiLocation, AccountId> for Account32Hash<Network, AccountId>
ConvertLocation<AccountId> for Account32Hash<Network, AccountId>
{
fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
Ok(("multiloc", location.borrow()).using_encoded(blake2_256).into())
}
fn reverse_ref(_: impl Borrow<AccountId>) -> Result<MultiLocation, ()> {
Err(())
fn convert_location(location: &MultiLocation) -> Option<AccountId> {
Some(("multiloc", location).using_encoded(blake2_256).into())
}
}
/// A [`MultiLocation`] consisting of a single `Parent` [`Junction`] will be converted to the
/// parent `AccountId`.
pub struct ParentIsPreset<AccountId>(PhantomData<AccountId>);
impl<AccountId: Decode + Eq + Clone> Convert<MultiLocation, AccountId>
for ParentIsPreset<AccountId>
{
fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
if location.borrow().contains_parents_only(1) {
Ok(b"Parent"
.using_encoded(|b| AccountId::decode(&mut TrailingZeroInput::new(b)))
.expect("infinite length input; no invalid inputs for type; qed"))
impl<AccountId: Decode + Eq + Clone> ConvertLocation<AccountId> for ParentIsPreset<AccountId> {
fn convert_location(location: &MultiLocation) -> Option<AccountId> {
if location.contains_parents_only(1) {
Some(
b"Parent"
.using_encoded(|b| AccountId::decode(&mut TrailingZeroInput::new(b)))
.expect("infinite length input; no invalid inputs for type; qed"),
)
} else {
Err(())
}
}
fn reverse_ref(who: impl Borrow<AccountId>) -> Result<MultiLocation, ()> {
let parent_account = b"Parent"
.using_encoded(|b| AccountId::decode(&mut TrailingZeroInput::new(b)))
.expect("infinite length input; no invalid inputs for type; qed");
if who.borrow() == &parent_account {
Ok(Parent.into())
} else {
Err(())
None
}
}
}
pub struct ChildParachainConvertsVia<ParaId, AccountId>(PhantomData<(ParaId, AccountId)>);
impl<ParaId: From<u32> + Into<u32> + AccountIdConversion<AccountId>, AccountId: Clone>
Convert<MultiLocation, AccountId> for ChildParachainConvertsVia<ParaId, AccountId>
ConvertLocation<AccountId> for ChildParachainConvertsVia<ParaId, AccountId>
{
fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
match location.borrow() {
fn convert_location(location: &MultiLocation) -> Option<AccountId> {
match location {
MultiLocation { parents: 0, interior: X1(Parachain(id)) } =>
Ok(ParaId::from(*id).into_account_truncating()),
_ => Err(()),
}
}
fn reverse_ref(who: impl Borrow<AccountId>) -> Result<MultiLocation, ()> {
if let Some(id) = ParaId::try_from_account(who.borrow()) {
Ok(Parachain(id.into()).into())
} else {
Err(())
Some(ParaId::from(*id).into_account_truncating()),
_ => None,
}
}
}
pub struct SiblingParachainConvertsVia<ParaId, AccountId>(PhantomData<(ParaId, AccountId)>);
impl<ParaId: From<u32> + Into<u32> + AccountIdConversion<AccountId>, AccountId: Clone>
Convert<MultiLocation, AccountId> for SiblingParachainConvertsVia<ParaId, AccountId>
ConvertLocation<AccountId> for SiblingParachainConvertsVia<ParaId, AccountId>
{
fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
match location.borrow() {
fn convert_location(location: &MultiLocation) -> Option<AccountId> {
match location {
MultiLocation { parents: 1, interior: X1(Parachain(id)) } =>
Ok(ParaId::from(*id).into_account_truncating()),
_ => Err(()),
}
}
fn reverse_ref(who: impl Borrow<AccountId>) -> Result<MultiLocation, ()> {
if let Some(id) = ParaId::try_from_account(who.borrow()) {
Ok(MultiLocation::new(1, X1(Parachain(id.into()))))
} else {
Err(())
Some(ParaId::from(*id).into_account_truncating()),
_ => None,
}
}
}
@@ -214,21 +303,17 @@ impl<ParaId: From<u32> + Into<u32> + AccountIdConversion<AccountId>, AccountId:
/// Extracts the `AccountId32` from the passed `location` if the network matches.
pub struct AccountId32Aliases<Network, AccountId>(PhantomData<(Network, AccountId)>);
impl<Network: Get<Option<NetworkId>>, AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone>
Convert<MultiLocation, AccountId> for AccountId32Aliases<Network, AccountId>
ConvertLocation<AccountId> for AccountId32Aliases<Network, AccountId>
{
fn convert(location: MultiLocation) -> Result<AccountId, MultiLocation> {
let id = match location {
fn convert_location(location: &MultiLocation) -> Option<AccountId> {
let id = match *location {
MultiLocation { parents: 0, interior: X1(AccountId32 { id, network: None }) } => id,
MultiLocation { parents: 0, interior: X1(AccountId32 { id, network }) }
if network == Network::get() =>
id,
_ => return Err(location),
_ => return None,
};
Ok(id.into())
}
fn reverse(who: AccountId) -> Result<MultiLocation, AccountId> {
Ok(AccountId32 { id: who.into(), network: Network::get() }.into())
Some(id.into())
}
}
@@ -237,8 +322,7 @@ impl<Network: Get<Option<NetworkId>>, AccountId: From<[u8; 32]> + Into<[u8; 32]>
/// network (provided by `Network`) and the `AccountId`'s `[u8; 32]` datum for the `id`.
pub struct AliasesIntoAccountId32<Network, AccountId>(PhantomData<(Network, AccountId)>);
impl<'a, Network: Get<Option<NetworkId>>, AccountId: Clone + Into<[u8; 32]> + Clone>
sp_runtime::traits::Convert<&'a AccountId, MultiLocation>
for AliasesIntoAccountId32<Network, AccountId>
Convert<&'a AccountId, MultiLocation> for AliasesIntoAccountId32<Network, AccountId>
{
fn convert(who: &AccountId) -> MultiLocation {
AccountId32 { network: Network::get(), id: who.clone().into() }.into()
@@ -247,22 +331,17 @@ impl<'a, Network: Get<Option<NetworkId>>, AccountId: Clone + Into<[u8; 32]> + Cl
pub struct AccountKey20Aliases<Network, AccountId>(PhantomData<(Network, AccountId)>);
impl<Network: Get<Option<NetworkId>>, AccountId: From<[u8; 20]> + Into<[u8; 20]> + Clone>
Convert<MultiLocation, AccountId> for AccountKey20Aliases<Network, AccountId>
ConvertLocation<AccountId> for AccountKey20Aliases<Network, AccountId>
{
fn convert(location: MultiLocation) -> Result<AccountId, MultiLocation> {
let key = match location {
fn convert_location(location: &MultiLocation) -> Option<AccountId> {
let key = match *location {
MultiLocation { parents: 0, interior: X1(AccountKey20 { key, network: None }) } => key,
MultiLocation { parents: 0, interior: X1(AccountKey20 { key, network }) }
if network == Network::get() =>
key,
_ => return Err(location),
_ => return None,
};
Ok(key.into())
}
fn reverse(who: AccountId) -> Result<MultiLocation, AccountId> {
let j = AccountKey20 { key: who.into(), network: Network::get() };
Ok(j.into())
Some(key.into())
}
}
@@ -285,31 +364,24 @@ pub struct GlobalConsensusParachainConvertsFor<UniversalLocation, AccountId>(
PhantomData<(UniversalLocation, AccountId)>,
);
impl<UniversalLocation: Get<InteriorMultiLocation>, AccountId: From<[u8; 32]> + Clone>
Convert<MultiLocation, AccountId>
for GlobalConsensusParachainConvertsFor<UniversalLocation, AccountId>
ConvertLocation<AccountId> for GlobalConsensusParachainConvertsFor<UniversalLocation, AccountId>
{
fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
fn convert_location(location: &MultiLocation) -> Option<AccountId> {
let universal_source = UniversalLocation::get();
log::trace!(
target: "xcm::location_conversion",
"GlobalConsensusParachainConvertsFor universal_source: {:?}, location: {:?}",
universal_source, location.borrow(),
universal_source, location,
);
let devolved = ensure_is_remote(universal_source, *location.borrow()).map_err(|_| ())?;
let devolved = ensure_is_remote(universal_source, *location).ok()?;
let (remote_network, remote_location) = devolved;
match remote_location {
X1(Parachain(remote_network_para_id)) =>
Ok(AccountId::from(Self::from_params(&remote_network, &remote_network_para_id))),
_ => Err(()),
Some(AccountId::from(Self::from_params(&remote_network, &remote_network_para_id))),
_ => None,
}
}
fn reverse_ref(_: impl Borrow<AccountId>) -> Result<MultiLocation, ()> {
// if this is ever be needed, we could implement some kind of guessing, if we have
// configuration for supported networkId+paraId
Err(())
}
}
impl<UniversalLocation, AccountId>
GlobalConsensusParachainConvertsFor<UniversalLocation, AccountId>
@@ -323,6 +395,9 @@ impl<UniversalLocation, AccountId>
mod tests {
use super::*;
pub type ForeignChainAliasAccount<AccountId> =
HashedDescription<AccountId, LegacyDescribeForeignChainAccount>;
use frame_support::parameter_types;
use xcm::latest::Junction;
@@ -441,11 +516,11 @@ mod tests {
for (location, expected_result) in test_data {
let result =
GlobalConsensusParachainConvertsFor::<UniversalLocation, [u8; 32]>::convert_ref(
GlobalConsensusParachainConvertsFor::<UniversalLocation, [u8; 32]>::convert_location(
&location,
);
match result {
Ok(account) => {
Some(account) => {
assert_eq!(
true, expected_result,
"expected_result: {}, but conversion passed: {:?}, location: {:?}",
@@ -465,7 +540,7 @@ mod tests {
)
}
},
Err(_) => {
None => {
assert_eq!(
false, expected_result,
"expected_result: {} - but conversion failed, location: {:?}",
@@ -477,23 +552,23 @@ mod tests {
// all success
let res_gc_a_p1000 =
GlobalConsensusParachainConvertsFor::<UniversalLocation, [u8; 32]>::convert_ref(
MultiLocation::new(2, X2(GlobalConsensus(ByGenesis([3; 32])), Parachain(1000))),
GlobalConsensusParachainConvertsFor::<UniversalLocation, [u8; 32]>::convert_location(
&MultiLocation::new(2, X2(GlobalConsensus(ByGenesis([3; 32])), Parachain(1000))),
)
.expect("conversion is ok");
let res_gc_a_p1001 =
GlobalConsensusParachainConvertsFor::<UniversalLocation, [u8; 32]>::convert_ref(
MultiLocation::new(2, X2(GlobalConsensus(ByGenesis([3; 32])), Parachain(1001))),
GlobalConsensusParachainConvertsFor::<UniversalLocation, [u8; 32]>::convert_location(
&MultiLocation::new(2, X2(GlobalConsensus(ByGenesis([3; 32])), Parachain(1001))),
)
.expect("conversion is ok");
let res_gc_b_p1000 =
GlobalConsensusParachainConvertsFor::<UniversalLocation, [u8; 32]>::convert_ref(
MultiLocation::new(2, X2(GlobalConsensus(ByGenesis([4; 32])), Parachain(1000))),
GlobalConsensusParachainConvertsFor::<UniversalLocation, [u8; 32]>::convert_location(
&MultiLocation::new(2, X2(GlobalConsensus(ByGenesis([4; 32])), Parachain(1000))),
)
.expect("conversion is ok");
let res_gc_b_p1001 =
GlobalConsensusParachainConvertsFor::<UniversalLocation, [u8; 32]>::convert_ref(
MultiLocation::new(2, X2(GlobalConsensus(ByGenesis([4; 32])), Parachain(1001))),
GlobalConsensusParachainConvertsFor::<UniversalLocation, [u8; 32]>::convert_location(
&MultiLocation::new(2, X2(GlobalConsensus(ByGenesis([4; 32])), Parachain(1001))),
)
.expect("conversion is ok");
assert_ne!(res_gc_a_p1000, res_gc_a_p1001);
@@ -510,7 +585,7 @@ mod tests {
parents: 1,
interior: X2(Parachain(1), AccountId32 { network: None, id: [0u8; 32] }),
};
let rem_1 = ForeignChainAliasAccount::<[u8; 32]>::convert(mul).unwrap();
let rem_1 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap();
assert_eq!(
[
@@ -528,13 +603,13 @@ mod tests {
),
};
assert_eq!(ForeignChainAliasAccount::<[u8; 32]>::convert(mul).unwrap(), rem_1);
assert_eq!(ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(), rem_1);
let mul = MultiLocation {
parents: 1,
interior: X2(Parachain(2), AccountId32 { network: None, id: [0u8; 32] }),
};
let rem_2 = ForeignChainAliasAccount::<[u8; 32]>::convert(mul).unwrap();
let rem_2 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap();
assert_eq!(
[
@@ -553,7 +628,7 @@ mod tests {
parents: 1,
interior: X2(Parachain(1), AccountKey20 { network: None, key: [0u8; 20] }),
};
let rem_1 = ForeignChainAliasAccount::<[u8; 32]>::convert(mul).unwrap();
let rem_1 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap();
assert_eq!(
[
@@ -571,13 +646,13 @@ mod tests {
),
};
assert_eq!(ForeignChainAliasAccount::<[u8; 32]>::convert(mul).unwrap(), rem_1);
assert_eq!(ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(), rem_1);
let mul = MultiLocation {
parents: 1,
interior: X2(Parachain(2), AccountKey20 { network: None, key: [0u8; 20] }),
};
let rem_2 = ForeignChainAliasAccount::<[u8; 32]>::convert(mul).unwrap();
let rem_2 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap();
assert_eq!(
[
@@ -596,7 +671,7 @@ mod tests {
parents: 1,
interior: X1(AccountId32 { network: None, id: [0u8; 32] }),
};
let rem_1 = ForeignChainAliasAccount::<[u8; 32]>::convert(mul).unwrap();
let rem_1 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap();
assert_eq!(
[
@@ -611,13 +686,13 @@ mod tests {
interior: X1(AccountId32 { network: Some(NetworkId::Polkadot), id: [0u8; 32] }),
};
assert_eq!(ForeignChainAliasAccount::<[u8; 32]>::convert(mul).unwrap(), rem_1);
assert_eq!(ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(), rem_1);
let mul = MultiLocation {
parents: 1,
interior: X1(AccountId32 { network: None, id: [1u8; 32] }),
};
let rem_2 = ForeignChainAliasAccount::<[u8; 32]>::convert(mul).unwrap();
let rem_2 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap();
assert_eq!(
[
@@ -636,7 +711,7 @@ mod tests {
parents: 0,
interior: X2(Parachain(1), AccountKey20 { network: None, key: [0u8; 20] }),
};
let rem_1 = ForeignChainAliasAccount::<[u8; 32]>::convert(mul).unwrap();
let rem_1 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap();
assert_eq!(
[
@@ -650,7 +725,7 @@ mod tests {
parents: 0,
interior: X2(Parachain(2), AccountKey20 { network: None, key: [0u8; 20] }),
};
let rem_2 = ForeignChainAliasAccount::<[u8; 32]>::convert(mul).unwrap();
let rem_2 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap();
assert_eq!(
[
@@ -669,7 +744,7 @@ mod tests {
parents: 0,
interior: X2(Parachain(1), AccountId32 { network: None, id: [0u8; 32] }),
};
let rem_1 = ForeignChainAliasAccount::<[u8; 32]>::convert(mul).unwrap();
let rem_1 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap();
assert_eq!(
[
@@ -687,13 +762,13 @@ mod tests {
),
};
assert_eq!(ForeignChainAliasAccount::<[u8; 32]>::convert(mul).unwrap(), rem_1);
assert_eq!(ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap(), rem_1);
let mul = MultiLocation {
parents: 0,
interior: X2(Parachain(2), AccountId32 { network: None, id: [0u8; 32] }),
};
let rem_2 = ForeignChainAliasAccount::<[u8; 32]>::convert(mul).unwrap();
let rem_2 = ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).unwrap();
assert_eq!(
[
@@ -712,6 +787,6 @@ mod tests {
parents: 1,
interior: X1(AccountKey20 { network: None, key: [0u8; 20] }),
};
assert!(ForeignChainAliasAccount::<[u8; 32]>::convert(mul).is_err());
assert!(ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).is_none());
}
}
@@ -23,7 +23,9 @@ use frame_support::{
};
use sp_std::{marker::PhantomData, prelude::*, result};
use xcm::latest::prelude::*;
use xcm_executor::traits::{Convert, Error as MatchError, MatchesNonFungibles, TransactAsset};
use xcm_executor::traits::{
ConvertLocation, Error as MatchError, MatchesNonFungibles, TransactAsset,
};
const LOG_TARGET: &str = "xcm::nonfungibles_adapter";
@@ -33,7 +35,7 @@ pub struct NonFungiblesTransferAdapter<Assets, Matcher, AccountIdConverter, Acco
impl<
Assets: nonfungibles::Transfer<AccountId>,
Matcher: MatchesNonFungibles<Assets::CollectionId, Assets::ItemId>,
AccountIdConverter: Convert<MultiLocation, AccountId>,
AccountIdConverter: ConvertLocation<AccountId>,
AccountId: Clone, // can't get away without it since Currency is generic over it.
> TransactAsset for NonFungiblesTransferAdapter<Assets, Matcher, AccountIdConverter, AccountId>
{
@@ -53,8 +55,8 @@ impl<
);
// Check we handle this asset.
let (class, instance) = Matcher::matches_nonfungibles(what)?;
let destination = AccountIdConverter::convert_ref(to)
.map_err(|()| MatchError::AccountIdConversionFailed)?;
let destination = AccountIdConverter::convert_location(to)
.ok_or(MatchError::AccountIdConversionFailed)?;
Assets::transfer(&class, &instance, &destination)
.map_err(|e| XcmError::FailedToTransactAsset(e.into()))?;
Ok(what.clone().into())
@@ -73,7 +75,7 @@ pub struct NonFungiblesMutateAdapter<
impl<
Assets: nonfungibles::Mutate<AccountId>,
Matcher: MatchesNonFungibles<Assets::CollectionId, Assets::ItemId>,
AccountIdConverter: Convert<MultiLocation, AccountId>,
AccountIdConverter: ConvertLocation<AccountId>,
AccountId: Clone + Eq, // can't get away without it since Currency is generic over it.
CheckAsset: AssetChecking<Assets::CollectionId>,
CheckingAccount: Get<Option<AccountId>>,
@@ -115,7 +117,7 @@ impl<
impl<
Assets: nonfungibles::Mutate<AccountId>,
Matcher: MatchesNonFungibles<Assets::CollectionId, Assets::ItemId>,
AccountIdConverter: Convert<MultiLocation, AccountId>,
AccountIdConverter: ConvertLocation<AccountId>,
AccountId: Clone + Eq, // can't get away without it since Currency is generic over it.
CheckAsset: AssetChecking<Assets::CollectionId>,
CheckingAccount: Get<Option<AccountId>>,
@@ -215,8 +217,8 @@ impl<
);
// Check we handle this asset.
let (class, instance) = Matcher::matches_nonfungibles(what)?;
let who = AccountIdConverter::convert_ref(who)
.map_err(|()| MatchError::AccountIdConversionFailed)?;
let who = AccountIdConverter::convert_location(who)
.ok_or(MatchError::AccountIdConversionFailed)?;
Assets::mint_into(&class, &instance, &who)
.map_err(|e| XcmError::FailedToTransactAsset(e.into()))
}
@@ -234,8 +236,8 @@ impl<
maybe_context,
);
// Check we handle this asset.
let who = AccountIdConverter::convert_ref(who)
.map_err(|()| MatchError::AccountIdConversionFailed)?;
let who = AccountIdConverter::convert_location(who)
.ok_or(MatchError::AccountIdConversionFailed)?;
let (class, instance) = Matcher::matches_nonfungibles(what)?;
Assets::burn(&class, &instance, Some(&who))
.map_err(|e| XcmError::FailedToTransactAsset(e.into()))?;
@@ -254,7 +256,7 @@ pub struct NonFungiblesAdapter<
impl<
Assets: nonfungibles::Mutate<AccountId> + nonfungibles::Transfer<AccountId>,
Matcher: MatchesNonFungibles<Assets::CollectionId, Assets::ItemId>,
AccountIdConverter: Convert<MultiLocation, AccountId>,
AccountIdConverter: ConvertLocation<AccountId>,
AccountId: Clone + Eq, // can't get away without it since Currency is generic over it.
CheckAsset: AssetChecking<Assets::CollectionId>,
CheckingAccount: Get<Option<AccountId>>,
@@ -19,18 +19,17 @@
use frame_support::traits::{EnsureOrigin, Get, GetBacking, OriginTrait};
use frame_system::RawOrigin as SystemRawOrigin;
use polkadot_parachain::primitives::IsSystem;
use sp_runtime::traits::TryConvert;
use sp_std::marker::PhantomData;
use xcm::latest::{BodyId, BodyPart, Junction, Junctions::*, MultiLocation, NetworkId, OriginKind};
use xcm_executor::traits::{Convert, ConvertOrigin};
use xcm_executor::traits::{ConvertLocation, ConvertOrigin};
/// Sovereign accounts use the system's `Signed` origin with an account ID derived from the `LocationConverter`.
pub struct SovereignSignedViaLocation<LocationConverter, RuntimeOrigin>(
PhantomData<(LocationConverter, RuntimeOrigin)>,
);
impl<
LocationConverter: Convert<MultiLocation, RuntimeOrigin::AccountId>,
RuntimeOrigin: OriginTrait,
> ConvertOrigin<RuntimeOrigin> for SovereignSignedViaLocation<LocationConverter, RuntimeOrigin>
impl<LocationConverter: ConvertLocation<RuntimeOrigin::AccountId>, RuntimeOrigin: OriginTrait>
ConvertOrigin<RuntimeOrigin> for SovereignSignedViaLocation<LocationConverter, RuntimeOrigin>
where
RuntimeOrigin::AccountId: Clone,
{
@@ -45,7 +44,7 @@ where
origin, kind,
);
if let OriginKind::SovereignAccount = kind {
let location = LocationConverter::convert(origin)?;
let location = LocationConverter::convert_location(&origin).ok_or(origin)?;
Ok(RuntimeOrigin::signed(location).into())
} else {
Err(origin)
@@ -244,14 +243,14 @@ where
/// `EnsureOrigin` barrier to convert from dispatch origin to XCM origin, if one exists.
pub struct EnsureXcmOrigin<RuntimeOrigin, Conversion>(PhantomData<(RuntimeOrigin, Conversion)>);
impl<RuntimeOrigin: OriginTrait + Clone, Conversion: Convert<RuntimeOrigin, MultiLocation>>
impl<RuntimeOrigin: OriginTrait + Clone, Conversion: TryConvert<RuntimeOrigin, MultiLocation>>
EnsureOrigin<RuntimeOrigin> for EnsureXcmOrigin<RuntimeOrigin, Conversion>
where
RuntimeOrigin::PalletsOrigin: PartialEq,
{
type Success = MultiLocation;
fn try_origin(o: RuntimeOrigin) -> Result<Self::Success, RuntimeOrigin> {
let o = match Conversion::convert(o) {
let o = match Conversion::try_convert(o) {
Ok(location) => return Ok(location),
Err(o) => o,
};
@@ -281,12 +280,13 @@ impl<
RuntimeOrigin: OriginTrait + Clone,
AccountId: Into<[u8; 32]>,
Network: Get<Option<NetworkId>>,
> Convert<RuntimeOrigin, MultiLocation> for SignedToAccountId32<RuntimeOrigin, AccountId, Network>
> TryConvert<RuntimeOrigin, MultiLocation>
for SignedToAccountId32<RuntimeOrigin, AccountId, Network>
where
RuntimeOrigin::PalletsOrigin: From<SystemRawOrigin<AccountId>>
+ TryInto<SystemRawOrigin<AccountId>, Error = RuntimeOrigin::PalletsOrigin>,
{
fn convert(o: RuntimeOrigin) -> Result<MultiLocation, RuntimeOrigin> {
fn try_convert(o: RuntimeOrigin) -> Result<MultiLocation, RuntimeOrigin> {
o.try_with_caller(|caller| match caller.try_into() {
Ok(SystemRawOrigin::Signed(who)) =>
Ok(Junction::AccountId32 { network: Network::get(), id: who.into() }.into()),
@@ -305,12 +305,12 @@ pub struct BackingToPlurality<RuntimeOrigin, COrigin, Body>(
PhantomData<(RuntimeOrigin, COrigin, Body)>,
);
impl<RuntimeOrigin: OriginTrait + Clone, COrigin: GetBacking, Body: Get<BodyId>>
Convert<RuntimeOrigin, MultiLocation> for BackingToPlurality<RuntimeOrigin, COrigin, Body>
TryConvert<RuntimeOrigin, MultiLocation> for BackingToPlurality<RuntimeOrigin, COrigin, Body>
where
RuntimeOrigin::PalletsOrigin:
From<COrigin> + TryInto<COrigin, Error = RuntimeOrigin::PalletsOrigin>,
{
fn convert(o: RuntimeOrigin) -> Result<MultiLocation, RuntimeOrigin> {
fn try_convert(o: RuntimeOrigin) -> Result<MultiLocation, RuntimeOrigin> {
o.try_with_caller(|caller| match caller.try_into() {
Ok(co) => match co.get_backing() {
Some(backing) => Ok(Junction::Plurality {
@@ -331,10 +331,10 @@ pub struct OriginToPluralityVoice<RuntimeOrigin, EnsureBodyOrigin, Body>(
PhantomData<(RuntimeOrigin, EnsureBodyOrigin, Body)>,
);
impl<RuntimeOrigin: Clone, EnsureBodyOrigin: EnsureOrigin<RuntimeOrigin>, Body: Get<BodyId>>
Convert<RuntimeOrigin, MultiLocation>
TryConvert<RuntimeOrigin, MultiLocation>
for OriginToPluralityVoice<RuntimeOrigin, EnsureBodyOrigin, Body>
{
fn convert(o: RuntimeOrigin) -> Result<MultiLocation, RuntimeOrigin> {
fn try_convert(o: RuntimeOrigin) -> Result<MultiLocation, RuntimeOrigin> {
match EnsureBodyOrigin::try_origin(o) {
Ok(_) => Ok(Junction::Plurality { id: Body::get(), part: BodyPart::Voice }.into()),
Err(o) => Err(o),
@@ -15,122 +15,26 @@
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
use frame_support::traits::{Contains, OriginTrait};
use parity_scale_codec::{Decode, Encode};
use sp_runtime::{traits::Dispatchable, DispatchErrorWithPostInfo};
use sp_std::{borrow::Borrow, marker::PhantomData, prelude::*, result::Result};
use sp_std::{marker::PhantomData, result::Result};
use xcm::latest::prelude::*;
/// Generic third-party conversion trait. Use this when you don't want to force the user to use default
/// implementations of `From` and `Into` for the types you wish to convert between.
///
/// One of `convert`/`convert_ref` and `reverse`/`reverse_ref` MUST be implemented. If possible, implement
/// `convert_ref`, since this will never result in a clone. Use `convert` when you definitely need to consume
/// the source value.
///
/// Can be amalgamated into tuples. If any of the tuple elements converts into `Ok(_)` it short circuits. Otherwise returns
/// the `Err(_)` of the last failing conversion (or `Err(())` for ref conversions).
pub trait Convert<A: Clone, B: Clone> {
/// Convert from `value` (of type `A`) into an equivalent value of type `B`, `Err` if not possible.
fn convert(value: A) -> Result<B, A> {
Self::convert_ref(&value).map_err(|_| value)
}
fn convert_ref(value: impl Borrow<A>) -> Result<B, ()> {
Self::convert(value.borrow().clone()).map_err(|_| ())
}
/// Convert from `value` (of type `B`) into an equivalent value of type `A`, `Err` if not possible.
fn reverse(value: B) -> Result<A, B> {
Self::reverse_ref(&value).map_err(|_| value)
}
fn reverse_ref(value: impl Borrow<B>) -> Result<A, ()> {
Self::reverse(value.borrow().clone()).map_err(|_| ())
}
/// Means of converting a location into an account identifier.
pub trait ConvertLocation<AccountId> {
/// Convert the `location` into `Some` account ID, or `None` if not possible.
fn convert_location(location: &MultiLocation) -> Option<AccountId>;
}
#[impl_trait_for_tuples::impl_for_tuples(30)]
impl<A: Clone, B: Clone> Convert<A, B> for Tuple {
fn convert(value: A) -> Result<B, A> {
impl<AccountId> ConvertLocation<AccountId> for Tuple {
fn convert_location(l: &MultiLocation) -> Option<AccountId> {
for_tuples!( #(
let value = match Tuple::convert(value) {
Ok(result) => return Ok(result),
Err(v) => v,
};
)* );
Err(value)
}
fn reverse(value: B) -> Result<A, B> {
for_tuples!( #(
let value = match Tuple::reverse(value) {
Ok(result) => return Ok(result),
Err(v) => v,
};
)* );
Err(value)
}
fn convert_ref(value: impl Borrow<A>) -> Result<B, ()> {
let value = value.borrow();
for_tuples!( #(
match Tuple::convert_ref(value) {
Ok(result) => return Ok(result),
Err(_) => (),
match Tuple::convert_location(l) {
Some(result) => return Some(result),
None => {},
}
)* );
Err(())
}
fn reverse_ref(value: impl Borrow<B>) -> Result<A, ()> {
let value = value.borrow();
for_tuples!( #(
match Tuple::reverse_ref(value.clone()) {
Ok(result) => return Ok(result),
Err(_) => (),
}
)* );
Err(())
}
}
/// Simple pass-through which implements `BytesConversion` while not doing any conversion.
pub struct Identity;
impl<T: Clone> Convert<T, T> for Identity {
fn convert(value: T) -> Result<T, T> {
Ok(value)
}
fn reverse(value: T) -> Result<T, T> {
Ok(value)
}
}
/// Implementation of `Convert` trait using `TryFrom`.
pub struct JustTry;
impl<Source: TryFrom<Dest> + Clone, Dest: TryFrom<Source> + Clone> Convert<Source, Dest>
for JustTry
{
fn convert(value: Source) -> Result<Dest, Source> {
Dest::try_from(value.clone()).map_err(|_| value)
}
fn reverse(value: Dest) -> Result<Source, Dest> {
Source::try_from(value.clone()).map_err(|_| value)
}
}
/// Implementation of `Convert<_, Vec<u8>>` using the parity scale codec.
pub struct Encoded;
impl<T: Clone + Encode + Decode> Convert<T, Vec<u8>> for Encoded {
fn convert_ref(value: impl Borrow<T>) -> Result<Vec<u8>, ()> {
Ok(value.borrow().encode())
}
fn reverse_ref(bytes: impl Borrow<Vec<u8>>) -> Result<T, ()> {
T::decode(&mut &bytes.borrow()[..]).map_err(|_| ())
}
}
/// Implementation of `Convert<Vec<u8>, _>` using the parity scale codec.
pub struct Decoded;
impl<T: Clone + Encode + Decode> Convert<Vec<u8>, T> for Decoded {
fn convert_ref(bytes: impl Borrow<Vec<u8>>) -> Result<T, ()> {
T::decode(&mut &bytes.borrow()[..]).map_err(|_| ())
}
fn reverse_ref(value: impl Borrow<T>) -> Result<Vec<u8>, ()> {
Ok(value.borrow().encode())
None
}
}
+9 -8
View File
@@ -17,9 +17,7 @@
//! Various traits used in configuring the executor.
mod conversion;
pub use conversion::{
CallDispatcher, Convert, ConvertOrigin, Decoded, Encoded, Identity, JustTry, WithOriginFilter,
};
pub use conversion::{CallDispatcher, ConvertLocation, ConvertOrigin, WithOriginFilter};
mod drop_assets;
pub use drop_assets::{ClaimAssets, DropAssets};
mod asset_lock;
@@ -44,14 +42,17 @@ pub use should_execute::{CheckSuspension, Properties, ShouldExecute};
mod transact_asset;
pub use transact_asset::TransactAsset;
mod weight;
#[deprecated = "Use `sp_runtime::traits::` instead"]
pub use sp_runtime::traits::{Identity, TryConvertInto as JustTry};
pub use weight::{WeightBounds, WeightTrader};
pub mod prelude {
pub use super::{
export_xcm, validate_export, AssetExchange, AssetLock, ClaimAssets, Convert, ConvertOrigin,
Decoded, DropAssets, Enact, Encoded, Error, ExportXcm, FeeManager, FeeReason, Identity,
JustTry, LockError, MatchesFungible, MatchesFungibles, MatchesNonFungible,
MatchesNonFungibles, OnResponse, ShouldExecute, TransactAsset, VersionChangeNotifier,
WeightBounds, WeightTrader, WithOriginFilter,
export_xcm, validate_export, AssetExchange, AssetLock, ClaimAssets, ConvertOrigin,
DropAssets, Enact, Error, ExportXcm, FeeManager, FeeReason, LockError, MatchesFungible,
MatchesFungibles, MatchesNonFungible, MatchesNonFungibles, OnResponse, ShouldExecute,
TransactAsset, VersionChangeNotifier, WeightBounds, WeightTrader, WithOriginFilter,
};
#[allow(deprecated)]
pub use super::{Identity, JustTry};
}
@@ -19,7 +19,7 @@ mod relay_chain;
use frame_support::sp_tracing;
use xcm::prelude::*;
use xcm_executor::traits::Convert;
use xcm_executor::traits::ConvertLocation;
use xcm_simulator::{decl_test_network, decl_test_parachain, decl_test_relay_chain, TestExt};
pub const ALICE: sp_runtime::AccountId32 = sp_runtime::AccountId32::new([0u8; 32]);
@@ -67,27 +67,27 @@ decl_test_network! {
pub fn parent_account_id() -> parachain::AccountId {
let location = (Parent,);
parachain::LocationToAccountId::convert(location.into()).unwrap()
parachain::LocationToAccountId::convert_location(&location.into()).unwrap()
}
pub fn child_account_id(para: u32) -> relay_chain::AccountId {
let location = (Parachain(para),);
relay_chain::LocationToAccountId::convert(location.into()).unwrap()
relay_chain::LocationToAccountId::convert_location(&location.into()).unwrap()
}
pub fn child_account_account_id(para: u32, who: sp_runtime::AccountId32) -> relay_chain::AccountId {
let location = (Parachain(para), AccountId32 { network: None, id: who.into() });
relay_chain::LocationToAccountId::convert(location.into()).unwrap()
relay_chain::LocationToAccountId::convert_location(&location.into()).unwrap()
}
pub fn sibling_account_account_id(para: u32, who: sp_runtime::AccountId32) -> parachain::AccountId {
let location = (Parent, Parachain(para), AccountId32 { network: None, id: who.into() });
parachain::LocationToAccountId::convert(location.into()).unwrap()
parachain::LocationToAccountId::convert_location(&location.into()).unwrap()
}
pub fn parent_account_account_id(who: sp_runtime::AccountId32) -> parachain::AccountId {
let location = (Parent, AccountId32 { network: None, id: who.into() });
parachain::LocationToAccountId::convert(location.into()).unwrap()
parachain::LocationToAccountId::convert_location(&location.into()).unwrap()
}
pub fn para_ext(para_id: u32) -> sp_io::TestExternalities {
@@ -47,7 +47,7 @@ use xcm_builder::{
SovereignSignedViaLocation,
};
use xcm_executor::{
traits::{Convert, JustTry},
traits::{ConvertLocation, JustTry},
Config, XcmExecutor,
};
@@ -160,7 +160,7 @@ impl EnsureOriginWithArg<RuntimeOrigin, MultiLocation> for ForeignCreators {
if !a.starts_with(&origin_location) {
return Err(o)
}
SovereignAccountOf::convert(origin_location).map_err(|_| o)
SovereignAccountOf::convert_location(&origin_location).ok_or(o)
}
#[cfg(feature = "runtime-benchmarks")]