mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 15:11:02 +00:00
[xcm] GlobalConsensusConvertsFor for remote relay chain (based on pevious GlobalConsensusParachainConvertsFor) (#7517)
* [xcm] `GlobalConsensusConvertsFor` for remote relay chain (based on previous GlobalConsensusParachainConvertsFor) * Typo * PR fix (constants in test) * Re-export of `GlobalConsensusConvertsFor` * assert to panic * Update xcm/src/v3/multiasset.rs Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update xcm/xcm-builder/src/location_conversion.rs Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Update xcm/xcm-builder/src/location_conversion.rs Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> * Review fixes --------- Co-authored-by: parity-processbot <> Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com>
This commit is contained in:
@@ -406,7 +406,7 @@ pub struct MultiAsset {
|
||||
/// The overall asset identity (aka *class*, in the case of a non-fungible).
|
||||
pub id: AssetId,
|
||||
/// The fungibility of the asset, which contains either the amount (in the case of a fungible
|
||||
/// asset) or the *instance ID`, the secondary asset identifier.
|
||||
/// asset) or the *instance ID*, the secondary asset identifier.
|
||||
pub fun: Fungibility,
|
||||
}
|
||||
|
||||
|
||||
@@ -33,8 +33,9 @@ pub use location_conversion::{
|
||||
Account32Hash, AccountId32Aliases, AccountKey20Aliases, AliasesIntoAccountId32,
|
||||
ChildParachainConvertsVia, DescribeAccountId32Terminal, DescribeAccountIdTerminal,
|
||||
DescribeAccountKey20Terminal, DescribeAllTerminal, DescribeFamily, DescribeLocation,
|
||||
DescribePalletTerminal, DescribeTerminus, GlobalConsensusParachainConvertsFor,
|
||||
HashedDescription, ParentIsPreset, SiblingParachainConvertsVia,
|
||||
DescribePalletTerminal, DescribeTerminus, GlobalConsensusConvertsFor,
|
||||
GlobalConsensusParachainConvertsFor, HashedDescription, ParentIsPreset,
|
||||
SiblingParachainConvertsVia,
|
||||
};
|
||||
|
||||
mod origin_conversion;
|
||||
|
||||
@@ -345,6 +345,42 @@ impl<Network: Get<Option<NetworkId>>, AccountId: From<[u8; 20]> + Into<[u8; 20]>
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts a location which is a top-level relay chain (which provides its own consensus) into a 32-byte `AccountId`.
|
||||
///
|
||||
/// This will always result in the *same account ID* being returned for the same Relay-chain, regardless of the relative security of
|
||||
/// this Relay-chain compared to the local chain.
|
||||
///
|
||||
/// Note: No distinction is made between the cases when the given `UniversalLocation` lies within
|
||||
/// the same consensus system (i.e. is itself or a parent) and when it is a foreign consensus
|
||||
/// system.
|
||||
pub struct GlobalConsensusConvertsFor<UniversalLocation, AccountId>(
|
||||
PhantomData<(UniversalLocation, AccountId)>,
|
||||
);
|
||||
impl<UniversalLocation: Get<InteriorMultiLocation>, AccountId: From<[u8; 32]> + Clone>
|
||||
ConvertLocation<AccountId> for GlobalConsensusConvertsFor<UniversalLocation, AccountId>
|
||||
{
|
||||
fn convert_location(location: &MultiLocation) -> Option<AccountId> {
|
||||
let universal_source = UniversalLocation::get();
|
||||
log::trace!(
|
||||
target: "xcm::location_conversion",
|
||||
"GlobalConsensusConvertsFor universal_source: {:?}, location: {:?}",
|
||||
universal_source, location,
|
||||
);
|
||||
let (remote_network, remote_location) =
|
||||
ensure_is_remote(universal_source, *location).ok()?;
|
||||
|
||||
match remote_location {
|
||||
Here => Some(AccountId::from(Self::from_params(&remote_network))),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<UniversalLocation, AccountId> GlobalConsensusConvertsFor<UniversalLocation, AccountId> {
|
||||
fn from_params(network: &NetworkId) -> [u8; 32] {
|
||||
(b"glblcnsnss_", network).using_encoded(blake2_256)
|
||||
}
|
||||
}
|
||||
|
||||
/// Converts a location which is a top-level parachain (i.e. a parachain held on a
|
||||
/// Relay-chain which provides its own consensus) into a 32-byte `AccountId`.
|
||||
///
|
||||
@@ -473,6 +509,105 @@ mod tests {
|
||||
assert_eq!(inverted, Err(()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn global_consensus_converts_for_works() {
|
||||
parameter_types! {
|
||||
pub UniversalLocationInNetwork1: InteriorMultiLocation = X2(GlobalConsensus(ByGenesis([1; 32])), Parachain(1234));
|
||||
pub UniversalLocationInNetwork2: InteriorMultiLocation = X2(GlobalConsensus(ByGenesis([2; 32])), Parachain(1234));
|
||||
}
|
||||
let network_1 = UniversalLocationInNetwork1::get().global_consensus().expect("NetworkId");
|
||||
let network_2 = UniversalLocationInNetwork2::get().global_consensus().expect("NetworkId");
|
||||
let network_3 = ByGenesis([3; 32]);
|
||||
let network_4 = ByGenesis([4; 32]);
|
||||
let network_5 = ByGenesis([5; 32]);
|
||||
|
||||
let test_data = vec![
|
||||
(MultiLocation::parent(), false),
|
||||
(MultiLocation::new(0, Here), false),
|
||||
(MultiLocation::new(0, X1(GlobalConsensus(network_1))), false),
|
||||
(MultiLocation::new(1, X1(GlobalConsensus(network_1))), false),
|
||||
(MultiLocation::new(2, X1(GlobalConsensus(network_1))), false),
|
||||
(MultiLocation::new(0, X1(GlobalConsensus(network_2))), false),
|
||||
(MultiLocation::new(1, X1(GlobalConsensus(network_2))), false),
|
||||
(MultiLocation::new(2, X1(GlobalConsensus(network_2))), true),
|
||||
(MultiLocation::new(0, X2(GlobalConsensus(network_2), Parachain(1000))), false),
|
||||
(MultiLocation::new(1, X2(GlobalConsensus(network_2), Parachain(1000))), false),
|
||||
(MultiLocation::new(2, X2(GlobalConsensus(network_2), Parachain(1000))), false),
|
||||
];
|
||||
|
||||
for (location, expected_result) in test_data {
|
||||
let result =
|
||||
GlobalConsensusConvertsFor::<UniversalLocationInNetwork1, [u8; 32]>::convert_location(
|
||||
&location,
|
||||
);
|
||||
match result {
|
||||
Some(account) => {
|
||||
assert_eq!(
|
||||
true, expected_result,
|
||||
"expected_result: {}, but conversion passed: {:?}, location: {:?}",
|
||||
expected_result, account, location
|
||||
);
|
||||
match &location {
|
||||
MultiLocation { interior: X1(GlobalConsensus(network)), .. } =>
|
||||
assert_eq!(
|
||||
account,
|
||||
GlobalConsensusConvertsFor::<UniversalLocationInNetwork1, [u8; 32]>::from_params(network),
|
||||
"expected_result: {}, but conversion passed: {:?}, location: {:?}", expected_result, account, location
|
||||
),
|
||||
_ => panic!("expected_result: {}, conversion passed: {:?}, but MultiLocation does not match expected pattern, location: {:?}", expected_result, account, location)
|
||||
}
|
||||
},
|
||||
None => {
|
||||
assert_eq!(
|
||||
false, expected_result,
|
||||
"expected_result: {} - but conversion failed, location: {:?}",
|
||||
expected_result, location
|
||||
);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// all success
|
||||
let res_1_gc_network_3 =
|
||||
GlobalConsensusConvertsFor::<UniversalLocationInNetwork1, [u8; 32]>::convert_location(
|
||||
&MultiLocation::new(2, X1(GlobalConsensus(network_3))),
|
||||
)
|
||||
.expect("conversion is ok");
|
||||
let res_2_gc_network_3 =
|
||||
GlobalConsensusConvertsFor::<UniversalLocationInNetwork2, [u8; 32]>::convert_location(
|
||||
&MultiLocation::new(2, X1(GlobalConsensus(network_3))),
|
||||
)
|
||||
.expect("conversion is ok");
|
||||
let res_1_gc_network_4 =
|
||||
GlobalConsensusConvertsFor::<UniversalLocationInNetwork1, [u8; 32]>::convert_location(
|
||||
&MultiLocation::new(2, X1(GlobalConsensus(network_4))),
|
||||
)
|
||||
.expect("conversion is ok");
|
||||
let res_2_gc_network_4 =
|
||||
GlobalConsensusConvertsFor::<UniversalLocationInNetwork2, [u8; 32]>::convert_location(
|
||||
&MultiLocation::new(2, X1(GlobalConsensus(network_4))),
|
||||
)
|
||||
.expect("conversion is ok");
|
||||
let res_1_gc_network_5 =
|
||||
GlobalConsensusConvertsFor::<UniversalLocationInNetwork1, [u8; 32]>::convert_location(
|
||||
&MultiLocation::new(2, X1(GlobalConsensus(network_5))),
|
||||
)
|
||||
.expect("conversion is ok");
|
||||
let res_2_gc_network_5 =
|
||||
GlobalConsensusConvertsFor::<UniversalLocationInNetwork2, [u8; 32]>::convert_location(
|
||||
&MultiLocation::new(2, X1(GlobalConsensus(network_5))),
|
||||
)
|
||||
.expect("conversion is ok");
|
||||
|
||||
assert_ne!(res_1_gc_network_3, res_1_gc_network_4);
|
||||
assert_ne!(res_1_gc_network_4, res_1_gc_network_5);
|
||||
assert_ne!(res_1_gc_network_3, res_1_gc_network_5);
|
||||
|
||||
assert_eq!(res_1_gc_network_3, res_2_gc_network_3);
|
||||
assert_eq!(res_1_gc_network_4, res_2_gc_network_4);
|
||||
assert_eq!(res_1_gc_network_5, res_2_gc_network_5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn global_consensus_parachain_converts_for_works() {
|
||||
parameter_types! {
|
||||
|
||||
Reference in New Issue
Block a user