Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
Introduce Tinkernet multisig XCM configs to Kusama/Rococo through xcm…
Browse files Browse the repository at this point in the history
…-builder (#7165)

* Introduce Tinkernet multisig XCM configs

* fmt fix

* overflow handling, comments, clippy fixes

* Adding Tinkernet XCM configs to xcm-builder

* switching spaces to tab

* remove derivation.rs in favor of location_conversion.rs

* replace hardcoded literals with constants

* autoformat

* Fix for the unit test

* replacing expect with an error and renaming constants

* Resolving clippy warning

---------

Co-authored-by: parity-processbot <>
  • Loading branch information
arrudagates committed Jun 28, 2023
1 parent 56adf08 commit 52595c8
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 8 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 7 additions & 2 deletions runtime/kusama/src/xcm_config.rs
Expand Up @@ -41,8 +41,9 @@ use xcm_builder::{
ChildParachainConvertsVia, ChildSystemParachainAsSuperuser,
CurrencyAdapter as XcmCurrencyAdapter, FixedWeightBounds, IsChildSystemParachain, IsConcrete,
MintLocation, OriginToPluralityVoice, SignedAccountId32AsNative, SignedToAccountId32,
SovereignSignedViaLocation, TakeWeightCredit, TrailingSetTopicAsId, UsingComponents,
WeightInfoBounds, WithComputedOrigin, WithUniqueTopic,
SovereignSignedViaLocation, TakeWeightCredit, TinkernetMultisigAsAccountId,
TinkernetMultisigAsNative, TrailingSetTopicAsId, UsingComponents, WeightInfoBounds,
WithComputedOrigin, WithUniqueTopic,
};
use xcm_executor::traits::WithOriginFilter;

Expand Down Expand Up @@ -70,6 +71,8 @@ pub type SovereignAccountOf = (
ChildParachainConvertsVia<ParaId, AccountId>,
// We can directly alias an `AccountId32` into a local account.
AccountId32Aliases<ThisNetwork, AccountId>,
// We can derive a local account from a Tinkernet XCMultisig MultiLocation.
TinkernetMultisigAsAccountId<AccountId>,
);

/// Our asset transactor. This is what allows us to interest with the runtime facilities from the point of
Expand Down Expand Up @@ -99,6 +102,8 @@ type LocalOriginConverter = (
SignedAccountId32AsNative<ThisNetwork, RuntimeOrigin>,
// A system child parachain, expressed as a Superuser, converts to the `Root` origin.
ChildSystemParachainAsSuperuser<ParaId, RuntimeOrigin>,
// Converts a Tinkernet XCMultisig MultiLocation into a `Signed` origin.
TinkernetMultisigAsNative<RuntimeOrigin>,
);

parameter_types! {
Expand Down
14 changes: 10 additions & 4 deletions runtime/rococo/src/xcm_config.rs
Expand Up @@ -40,8 +40,8 @@ use xcm_builder::{
ChildParachainAsNative, ChildParachainConvertsVia, ChildSystemParachainAsSuperuser,
CurrencyAdapter as XcmCurrencyAdapter, FixedWeightBounds, IsChildSystemParachain, IsConcrete,
MintLocation, SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation,
TakeWeightCredit, TrailingSetTopicAsId, UsingComponents, WeightInfoBounds, WithComputedOrigin,
WithUniqueTopic,
TakeWeightCredit, TinkernetMultisigAsAccountId, TinkernetMultisigAsNative,
TrailingSetTopicAsId, UsingComponents, WeightInfoBounds, WithComputedOrigin, WithUniqueTopic,
};
use xcm_executor::{traits::WithOriginFilter, XcmExecutor};

Expand All @@ -53,8 +53,12 @@ parameter_types! {
pub LocalCheckAccount: (AccountId, MintLocation) = (CheckAccount::get(), MintLocation::Local);
}

pub type LocationConverter =
(ChildParachainConvertsVia<ParaId, AccountId>, AccountId32Aliases<ThisNetwork, AccountId>);
pub type LocationConverter = (
ChildParachainConvertsVia<ParaId, AccountId>,
AccountId32Aliases<ThisNetwork, AccountId>,
// We can derive a local account from a Tinkernet XCMultisig MultiLocation.
TinkernetMultisigAsAccountId<AccountId>,
);

/// Our asset transactor. This is what allows us to interest with the runtime facilities from the point of
/// view of XCM-only concepts like `MultiLocation` and `MultiAsset`.
Expand Down Expand Up @@ -83,6 +87,8 @@ type LocalOriginConverter = (
SignedAccountId32AsNative<ThisNetwork, RuntimeOrigin>,
// A system child parachain, expressed as a Superuser, converts to the `Root` origin.
ChildSystemParachainAsSuperuser<ParaId, RuntimeOrigin>,
// Converts a Tinkernet XCMultisig MultiLocation into a `Signed` origin.
TinkernetMultisigAsNative<RuntimeOrigin>,
);

parameter_types! {
Expand Down
2 changes: 2 additions & 0 deletions xcm/xcm-builder/Cargo.toml
Expand Up @@ -15,6 +15,7 @@ sp-std = { git = "https://github.com/paritytech/substrate", branch = "master", d
sp-arithmetic = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
sp-io = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
sp-weights = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
frame-system = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
Expand Down Expand Up @@ -49,6 +50,7 @@ std = [
"sp-arithmetic/std",
"sp-io/std",
"sp-runtime/std",
"sp-core/std",
"sp-weights/std",
"frame-support/std",
"frame-system/std",
Expand Down
4 changes: 2 additions & 2 deletions xcm/xcm-builder/src/lib.rs
Expand Up @@ -34,15 +34,15 @@ pub use location_conversion::{
ChildParachainConvertsVia, DescribeAccountId32Terminal, DescribeAccountIdTerminal,
DescribeAccountKey20Terminal, DescribeAllTerminal, DescribeFamily, DescribeLocation,
DescribePalletTerminal, DescribeTerminus, GlobalConsensusParachainConvertsFor,
HashedDescription, ParentIsPreset, SiblingParachainConvertsVia,
HashedDescription, ParentIsPreset, SiblingParachainConvertsVia, TinkernetMultisigAsAccountId,
};

mod origin_conversion;
pub use origin_conversion::{
BackingToPlurality, ChildParachainAsNative, ChildSystemParachainAsSuperuser, EnsureXcmOrigin,
OriginToPluralityVoice, ParentAsSuperuser, RelayChainAsNative, SiblingParachainAsNative,
SiblingSystemParachainAsSuperuser, SignedAccountId32AsNative, SignedAccountKey20AsNative,
SignedToAccountId32, SovereignSignedViaLocation,
SignedToAccountId32, SovereignSignedViaLocation, TinkernetMultisigAsNative,
};

mod asset_conversion;
Expand Down
67 changes: 67 additions & 0 deletions xcm/xcm-builder/src/location_conversion.rs
Expand Up @@ -17,6 +17,7 @@
use crate::universal_exports::ensure_is_remote;
use frame_support::traits::Get;
use parity_scale_codec::{Compact, Decode, Encode};
use sp_core::H256;
use sp_io::hashing::blake2_256;
use sp_runtime::traits::{AccountIdConversion, Convert, TrailingZeroInput};
use sp_std::{marker::PhantomData, prelude::*};
Expand Down Expand Up @@ -345,6 +346,52 @@ impl<Network: Get<Option<NetworkId>>, AccountId: From<[u8; 20]> + Into<[u8; 20]>
}
}

/// Tinkernet ParaId used when matching Multisig MultiLocations.
pub const KUSAMA_TINKERNET_PARA_ID: u32 = 2125;

/// Tinkernet Multisig pallet instance used when matching Multisig MultiLocations.
pub const KUSAMA_TINKERNET_MULTISIG_PALLET: u8 = 71;

/// Constant derivation function for Tinkernet Multisigs.
/// Uses the Tinkernet genesis hash as a salt.
pub fn derive_tinkernet_multisig<AccountId: Decode>(id: u128) -> Result<AccountId, ()> {
AccountId::decode(&mut TrailingZeroInput::new(
&(
// The constant salt used to derive Tinkernet Multisigs, this is Tinkernet's genesis hash.
H256([
212, 46, 150, 6, 169, 149, 223, 228, 51, 220, 121, 85, 220, 42, 112, 244, 149, 243,
80, 243, 115, 218, 162, 0, 9, 138, 232, 68, 55, 129, 106, 210,
]),
// The actual multisig integer id.
u32::try_from(id).map_err(|_| ())?,
)
.using_encoded(blake2_256),
))
.map_err(|_| ())
}

/// Convert a Tinkernet Multisig `MultiLocation` value into a local `AccountId`.
pub struct TinkernetMultisigAsAccountId<AccountId>(PhantomData<AccountId>);
impl<AccountId: Decode + Clone> ConvertLocation<AccountId>
for TinkernetMultisigAsAccountId<AccountId>
{
fn convert_location(location: &MultiLocation) -> Option<AccountId> {
match location {
MultiLocation {
parents: _,
interior:
X3(
Parachain(KUSAMA_TINKERNET_PARA_ID),
PalletInstance(KUSAMA_TINKERNET_MULTISIG_PALLET),
// Index from which the multisig account is derived.
GeneralIndex(id),
),
} => derive_tinkernet_multisig(*id).ok(),
_ => None,
}
}
}

/// 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`.
///
Expand Down Expand Up @@ -789,4 +836,24 @@ mod tests {
};
assert!(ForeignChainAliasAccount::<[u8; 32]>::convert_location(&mul).is_none());
}

#[test]
fn remote_tinkernet_multisig_convert_to_account() {
let mul = MultiLocation {
parents: 0,
interior: X3(
Parachain(KUSAMA_TINKERNET_PARA_ID),
PalletInstance(KUSAMA_TINKERNET_MULTISIG_PALLET),
GeneralIndex(0),
),
};

assert_eq!(
[
97, 160, 244, 60, 133, 145, 170, 26, 202, 108, 203, 156, 114, 116, 175, 30, 156,
195, 43, 101, 243, 51, 193, 162, 152, 188, 30, 165, 244, 81, 70, 90
],
TinkernetMultisigAsAccountId::<[u8; 32]>::convert_location(&mul).unwrap()
);
}
}
35 changes: 35 additions & 0 deletions xcm/xcm-builder/src/origin_conversion.rs
Expand Up @@ -16,8 +16,12 @@

//! Various implementations for `ConvertOrigin`.

use crate::location_conversion::{
derive_tinkernet_multisig, KUSAMA_TINKERNET_MULTISIG_PALLET, KUSAMA_TINKERNET_PARA_ID,
};
use frame_support::traits::{EnsureOrigin, Get, GetBacking, OriginTrait};
use frame_system::RawOrigin as SystemRawOrigin;
use parity_scale_codec::Decode;
use polkadot_parachain::primitives::IsSystem;
use sp_runtime::traits::TryConvert;
use sp_std::marker::PhantomData;
Expand Down Expand Up @@ -241,6 +245,37 @@ where
}
}

/// Convert a Tinkernet Multisig `MultiLocation` value into a `Signed` origin.
pub struct TinkernetMultisigAsNative<RuntimeOrigin>(PhantomData<RuntimeOrigin>);
impl<RuntimeOrigin: OriginTrait> ConvertOrigin<RuntimeOrigin>
for TinkernetMultisigAsNative<RuntimeOrigin>
where
RuntimeOrigin::AccountId: Decode,
{
fn convert_origin(
origin: impl Into<MultiLocation>,
kind: OriginKind,
) -> Result<RuntimeOrigin, MultiLocation> {
let origin = origin.into();
match (kind, origin) {
(
OriginKind::Native,
MultiLocation {
parents: _,
interior:
X3(
Junction::Parachain(KUSAMA_TINKERNET_PARA_ID),
Junction::PalletInstance(KUSAMA_TINKERNET_MULTISIG_PALLET),
// Index from which the multisig account is derived.
Junction::GeneralIndex(id),
),
},
) => Ok(RuntimeOrigin::signed(derive_tinkernet_multisig(id).map_err(|_| origin)?)),
(_, origin) => Err(origin),
}
}
}

/// `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: TryConvert<RuntimeOrigin, MultiLocation>>
Expand Down

0 comments on commit 52595c8

Please sign in to comment.