From f3832b18418aa35003972214569afc5d93104e15 Mon Sep 17 00:00:00 2001 From: Alexander Popiak Date: Tue, 20 Jul 2021 15:02:23 +0200 Subject: [PATCH 1/2] add a location converter for deriving a local account id from parachain and account combination --- xcm/xcm-builder/src/lib.rs | 2 +- xcm/xcm-builder/src/location_conversion.rs | 36 ++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/xcm/xcm-builder/src/lib.rs b/xcm/xcm-builder/src/lib.rs index 534261a9998d..6dc43042c79a 100644 --- a/xcm/xcm-builder/src/lib.rs +++ b/xcm/xcm-builder/src/lib.rs @@ -28,7 +28,7 @@ mod tests; mod location_conversion; pub use location_conversion::{ Account32Hash, ParentIsDefault, ChildParachainConvertsVia, SiblingParachainConvertsVia, AccountId32Aliases, - AccountKey20Aliases, LocationInverter, + AccountKey20Aliases, LocationInverter, DerivedParachainAccountId32, }; mod origin_conversion; diff --git a/xcm/xcm-builder/src/location_conversion.rs b/xcm/xcm-builder/src/location_conversion.rs index cdf0a2bf5171..80cf0eaf8aae 100644 --- a/xcm/xcm-builder/src/location_conversion.rs +++ b/xcm/xcm-builder/src/location_conversion.rs @@ -123,6 +123,7 @@ impl< } } +/// Extracts the `AccountKey20` from the passed `location` if the network matches. pub struct AccountKey20Aliases(PhantomData<(Network, AccountId)>); impl< Network: Get, @@ -143,6 +144,41 @@ impl< } } +/// Generates a unique `AccountId` for a given parachain + account combination. +/// +/// Used for giving parachains control over some accounts on the interpreting chain. +/// +/// Note: Not reversible. +pub struct DerivedParachainAccountId32(PhantomData<(Network, AccountId)>); +impl< + Network: Get, + AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone, +> Convert for DerivedParachainAccountId32 { + fn convert(location: MultiLocation) -> Result { + use Junction::*; + use MultiLocation::*; + let id = match location { + X2(Parachain(para_id), AccountId32 { id, network }) + if network == NetworkId::Any || &network == &Network::get() => + { + (para_id, id).using_encoded(blake2_256) + }, + X2(Parachain(para_id), AccountKey20 { key, network }) + if network == NetworkId::Any || &network == &Network::get() => + { + (para_id, key).using_encoded(blake2_256) + }, + l => return Err(l), + }; + Ok(id.into()) + } + + // reverse conversion is not implemented + fn reverse(who: AccountId) -> Result { + Err(who) + } +} + /// Simple location inverter; give it this location's ancestry and it'll figure out the inverted /// location. /// From 4ba1482ef9978717bb5a57b1896577ca47d383c4 Mon Sep 17 00:00:00 2001 From: Alexander Popiak Date: Tue, 20 Jul 2021 15:02:52 +0200 Subject: [PATCH 2/2] add local acccount derivation to Kusama, Rococo and Westend --- runtime/kusama/src/lib.rs | 4 +++- runtime/rococo/src/lib.rs | 4 +++- runtime/westend/src/lib.rs | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/runtime/kusama/src/lib.rs b/runtime/kusama/src/lib.rs index fe41607dda43..aafa9647d66b 100644 --- a/runtime/kusama/src/lib.rs +++ b/runtime/kusama/src/lib.rs @@ -60,7 +60,7 @@ use xcm_builder::{ AccountId32Aliases, ChildParachainConvertsVia, SovereignSignedViaLocation, CurrencyAdapter as XcmCurrencyAdapter, ChildParachainAsNative, SignedAccountId32AsNative, ChildSystemParachainAsSuperuser, LocationInverter, IsConcrete, FixedWeightBounds, TakeWeightCredit, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, - IsChildSystemParachain, UsingComponents, BackingToPlurality, SignedToAccountId32, + IsChildSystemParachain, UsingComponents, BackingToPlurality, SignedToAccountId32, DerivedParachainAccountId32, }; use xcm_executor::XcmExecutor; use sp_arithmetic::Perquintill; @@ -1222,6 +1222,8 @@ pub type SovereignAccountOf = ( ChildParachainConvertsVia, // We can directly alias an `AccountId32` into a local account. AccountId32Aliases, + // We can generate local account ids for accounts originating on parachains. + DerivedParachainAccountId32, ); /// Our asset transactor. This is what allows us to interest with the runtime facilities from the point of diff --git a/runtime/rococo/src/lib.rs b/runtime/rococo/src/lib.rs index 04c7adc96f55..374438e9a3a0 100644 --- a/runtime/rococo/src/lib.rs +++ b/runtime/rococo/src/lib.rs @@ -94,7 +94,7 @@ use xcm_builder::{ AccountId32Aliases, ChildParachainConvertsVia, SovereignSignedViaLocation, CurrencyAdapter as XcmCurrencyAdapter, ChildParachainAsNative, SignedAccountId32AsNative, ChildSystemParachainAsSuperuser, LocationInverter, IsConcrete, FixedWeightBounds, - BackingToPlurality, SignedToAccountId32, UsingComponents, + BackingToPlurality, SignedToAccountId32, UsingComponents, DerivedParachainAccountId32, }; use constants::{time::*, currency::*, fee::*}; use frame_support::traits::InstanceFilter; @@ -608,6 +608,8 @@ parameter_types! { pub type SovereignAccountOf = ( ChildParachainConvertsVia, AccountId32Aliases, + // We can generate local account ids for accounts originating on parachains. + DerivedParachainAccountId32, ); pub type LocalAssetTransactor = diff --git a/runtime/westend/src/lib.rs b/runtime/westend/src/lib.rs index 0ee78b5d19c4..964b386d2c16 100644 --- a/runtime/westend/src/lib.rs +++ b/runtime/westend/src/lib.rs @@ -61,7 +61,7 @@ use xcm_builder::{ AccountId32Aliases, ChildParachainConvertsVia, SovereignSignedViaLocation, CurrencyAdapter as XcmCurrencyAdapter, ChildParachainAsNative, SignedAccountId32AsNative, ChildSystemParachainAsSuperuser, LocationInverter, IsConcrete, FixedWeightBounds, TakeWeightCredit, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, - IsChildSystemParachain, UsingComponents, SignedToAccountId32, + IsChildSystemParachain, UsingComponents, SignedToAccountId32, DerivedParachainAccountId32, }; use sp_runtime::{ @@ -880,6 +880,8 @@ parameter_types! { pub type LocationConverter = ( ChildParachainConvertsVia, AccountId32Aliases, + // We can generate local account ids for accounts originating on parachains. + DerivedParachainAccountId32, ); pub type LocalAssetTransactor =