mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-01 04:31:02 +00:00
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:
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user