From f320ed918b6bb5537e280fcb8dd14bf807d26478 Mon Sep 17 00:00:00 2001 From: Gabriel Facco de Arruda Date: Tue, 4 Jul 2023 13:46:13 -0400 Subject: [PATCH 1/3] Introduce Tinkernet multisig XCM configs to Kintsugi --- Cargo.lock | 15 +++++++++++ parachain/runtime/kintsugi/Cargo.toml | 5 +++- parachain/runtime/kintsugi/src/xcm_config.rs | 26 ++++++++++++++------ 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 668eb23d6b..d17df52c88 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4379,6 +4379,20 @@ dependencies = [ "xcm-executor", ] +[[package]] +name = "invarch-xcm-builder" +version = "0.1.0" +source = "git+https://github.com/InvArch/InvArch-XCM-Builder?branch=polkadot-v0.9.40#65c59b740a44fc4e947b586ac654e6a5d96ce28e" +dependencies = [ + "frame-support", + "log", + "parity-scale-codec", + "sp-core", + "sp-io", + "xcm", + "xcm-executor", +] + [[package]] name = "io-lifetimes" version = "1.0.10" @@ -4699,6 +4713,7 @@ dependencies = [ "hex", "hex-literal 0.3.4", "interbtc-primitives", + "invarch-xcm-builder", "issue", "issue-rpc-runtime-api", "loans", diff --git a/parachain/runtime/kintsugi/Cargo.toml b/parachain/runtime/kintsugi/Cargo.toml index 8836064a91..0213ef310d 100644 --- a/parachain/runtime/kintsugi/Cargo.toml +++ b/parachain/runtime/kintsugi/Cargo.toml @@ -132,6 +132,9 @@ orml-xcm-support = { git = "https://github.com/open-web3-stack/open-runtime-modu orml-unknown-tokens = { git = "https://github.com/open-web3-stack/open-runtime-module-library", rev = "dc39cfddefb10ef0de23655e2c3dcdab66a19404", default-features = false } orml-asset-registry= { git = "https://github.com/open-web3-stack/open-runtime-module-library", rev = "dc39cfddefb10ef0de23655e2c3dcdab66a19404", default-features = false } +# InvArch Tinkernet Multisig dependencies +invarch-xcm-builder = { git = "https://github.com/InvArch/InvArch-XCM-Builder", branch = "polkadot-v0.9.40", default-features = false } + [dev-dependencies] hex = '0.4.2' mocktopus = "0.8.0" @@ -372,4 +375,4 @@ try-runtime = [ "orml-unknown-tokens/try-runtime", "multi-transaction-payment/try-runtime", ] -vesting-any = [] \ No newline at end of file +vesting-any = [] diff --git a/parachain/runtime/kintsugi/src/xcm_config.rs b/parachain/runtime/kintsugi/src/xcm_config.rs index fd7bde6efa..20c91cb329 100644 --- a/parachain/runtime/kintsugi/src/xcm_config.rs +++ b/parachain/runtime/kintsugi/src/xcm_config.rs @@ -18,7 +18,7 @@ use xcm_builder::{ AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, EnsureXcmOrigin, FixedRateOfFungible, FixedWeightBounds, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32, - SovereignSignedViaLocation, TakeRevenue, TakeWeightCredit, + SovereignSignedViaLocation, TakeRevenue, TakeWeightCredit, WithComputedOrigin, }; use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; use CurrencyId::ForeignAsset; @@ -37,6 +37,8 @@ type LocationToAccountId = ( SiblingParachainConvertsVia, // Straight up local `AccountId32` origins just alias directly to `AccountId`. AccountId32Aliases, + // Mapping Tinkernet multisig to the correctly derived AccountId. + invarch_xcm_builder::TinkernetMultisigAsAccountId, ); /// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance, @@ -56,16 +58,26 @@ pub type XcmOriginToTransactDispatchOrigin = ( // Native signed account converter; this just converts an `AccountId32` origin into a normal // `Origin::Signed` origin of the same 32-byte value. SignedAccountId32AsNative, + // Derives signed AccountId origins for Tinkernet multisigs. + invarch_xcm_builder::DeriveOriginFromTinkernetMultisig, // Xcm origins can be represented natively under the Xcm pallet's Xcm origin. XcmPassthrough, ); -pub type Barrier = Transactless<( - TakeWeightCredit, - AllowTopLevelPaidExecutionFrom, - AllowKnownQueryResponses, - AllowSubscriptionsFrom, -)>; // required for others to keep track of our xcm version +pub type Barrier = ( + Transactless<( + TakeWeightCredit, + AllowTopLevelPaidExecutionFrom, + AllowKnownQueryResponses, + AllowSubscriptionsFrom, + )>, // required for others to keep track of our xcm version + // XCM barrier that allows Tinkernet Multisigs to transact if paying for execution. + WithComputedOrigin< + AllowTopLevelPaidExecutionFrom, + UniversalLocation, + ConstU32<8>, + >, +); parameter_types! { // One XCM operation is 200_000_000 weight, cross-chain transfer ~= 2x of transfer. From 896f2e944d5b155b4a36f496857d664dce228a42 Mon Sep 17 00:00:00 2001 From: Gabriel Facco de Arruda Date: Fri, 28 Jul 2023 11:14:06 -0700 Subject: [PATCH 2/3] refactor: Declaring Tinkernet XCM configs directly in Kintsugi runtime --- Cargo.lock | 15 --- parachain/runtime/kintsugi/src/xcm_config.rs | 106 +++++++++++++++++-- 2 files changed, 97 insertions(+), 24 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 19ae2a8fbf..44f1949205 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5046,20 +5046,6 @@ dependencies = [ "xcm-executor", ] -[[package]] -name = "invarch-xcm-builder" -version = "0.1.0" -source = "git+https://github.com/InvArch/InvArch-XCM-Builder?branch=polkadot-v0.9.40#65c59b740a44fc4e947b586ac654e6a5d96ce28e" -dependencies = [ - "frame-support", - "log", - "parity-scale-codec", - "sp-core", - "sp-io", - "xcm", - "xcm-executor", -] - [[package]] name = "io-lifetimes" version = "1.0.11" @@ -5403,7 +5389,6 @@ dependencies = [ "hex", "hex-literal 0.3.4", "interbtc-primitives", - "invarch-xcm-builder", "issue", "issue-rpc-runtime-api", "loans", diff --git a/parachain/runtime/kintsugi/src/xcm_config.rs b/parachain/runtime/kintsugi/src/xcm_config.rs index 898d94360c..7c08f01771 100644 --- a/parachain/runtime/kintsugi/src/xcm_config.rs +++ b/parachain/runtime/kintsugi/src/xcm_config.rs @@ -3,7 +3,7 @@ use codec::{Decode, Encode}; use cumulus_primitives_core::ParaId; use frame_support::{ parameter_types, - traits::{Everything, Get, Nothing}, + traits::{Everything, Get, Nothing, OriginTrait}, }; use orml_asset_registry::{AssetRegistryTrader, FixedRateAssetRegistryTrader}; use orml_traits::{ @@ -13,6 +13,10 @@ use orml_xcm_support::{DepositToAlternative, IsNativeConcrete, MultiCurrencyAdap use pallet_xcm::XcmPassthrough; use polkadot_parachain::primitives::Sibling; use runtime_common::Transactless; +use sp_core::H256; +use sp_io::hashing::blake2_256; +use sp_runtime::traits::TrailingZeroInput; +use sp_std::{borrow::Borrow, marker::PhantomData}; use xcm::latest::{prelude::*, Weight}; use xcm_builder::{ AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, @@ -20,7 +24,10 @@ use xcm_builder::{ SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeRevenue, TakeWeightCredit, WithComputedOrigin, }; -use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; +use xcm_executor::{ + traits::{Convert as XcmConvert, ConvertOrigin, WithOriginFilter}, + XcmExecutor, +}; use CurrencyId::ForeignAsset; parameter_types! { pub const ParentLocation: MultiLocation = MultiLocation::parent(); @@ -38,7 +45,7 @@ type LocationToAccountId = ( // Straight up local `AccountId32` origins just alias directly to `AccountId`. AccountId32Aliases, // Mapping Tinkernet multisig to the correctly derived AccountId. - invarch_xcm_builder::TinkernetMultisigAsAccountId, + TinkernetMultisigAsAccountId, ); /// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance, @@ -59,7 +66,7 @@ pub type XcmOriginToTransactDispatchOrigin = ( // `Origin::Signed` origin of the same 32-byte value. SignedAccountId32AsNative, // Derives signed AccountId origins for Tinkernet multisigs. - invarch_xcm_builder::DeriveOriginFromTinkernetMultisig, + TinkernetMultisigAsNativeOrigin, // Xcm origins can be represented natively under the Xcm pallet's Xcm origin. XcmPassthrough, ); @@ -72,11 +79,7 @@ pub type Barrier = ( AllowSubscriptionsFrom, )>, // required for others to keep track of our xcm version // XCM barrier that allows Tinkernet Multisigs to transact if paying for execution. - WithComputedOrigin< - AllowTopLevelPaidExecutionFrom, - UniversalLocation, - ConstU32<8>, - >, + WithComputedOrigin, UniversalLocation, ConstU32<8>>, ); parameter_types! { @@ -442,6 +445,91 @@ impl orml_xtokens::Config for Runtime { type UniversalLocation = UniversalLocation; } +/// Tinkernet Multisig Multilocation for XCM barriers. +pub struct TinkernetMultisigMultiLocation; +impl Contains for TinkernetMultisigMultiLocation { + fn contains(t: &MultiLocation) -> bool { + matches!( + t, + MultiLocation { + parents: _, + interior: Junctions::X3( + Junction::Parachain(2125), + Junction::PalletInstance(71), + Junction::GeneralIndex(_) + ) + } + ) + } +} + +/// Constant derivation function for Tinkernet Multisigs. +/// Uses the Tinkernet genesis hash as a salt. +pub fn derive_tinkernet_multisig(id: u128) -> Result { + 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(PhantomData); +impl XcmConvert for TinkernetMultisigAsAccountId { + fn convert_ref(location: impl Borrow) -> Result { + match location.borrow() { + MultiLocation { + parents: 1, + interior: + X3( + Parachain(2125), + PalletInstance(71), + // Index from which the multisig account is derived. + GeneralIndex(id), + ), + } => derive_tinkernet_multisig(*id), + _ => Err(()), + } + } +} + +/// Convert a Tinkernet Multisig `MultiLocation` value into a `Signed` origin. +pub struct TinkernetMultisigAsNativeOrigin(PhantomData); +impl ConvertOrigin for TinkernetMultisigAsNativeOrigin +where + RuntimeOrigin::AccountId: Decode, +{ + fn convert_origin(origin: impl Into, kind: OriginKind) -> Result { + let origin = origin.into(); + match (kind, origin) { + ( + OriginKind::Native, + MultiLocation { + parents: 1, + interior: + X3( + Junction::Parachain(2125), + Junction::PalletInstance(71), + // Index from which the multisig account is derived. + Junction::GeneralIndex(id), + ), + }, + ) => Ok(RuntimeOrigin::signed( + derive_tinkernet_multisig(id).map_err(|_| origin)?, + )), + (_, origin) => Err(origin), + } + } +} + #[cfg(feature = "runtime-benchmarks")] use benchmark_impls::*; From a2328f7a0713a9eec20901c2d1ce780fb8c185d4 Mon Sep 17 00:00:00 2001 From: Gabriel Facco de Arruda Date: Fri, 28 Jul 2023 11:17:47 -0700 Subject: [PATCH 3/3] refactor: Fix parents to 1 in TinkernetMultisigMultilocation --- parachain/runtime/kintsugi/src/xcm_config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parachain/runtime/kintsugi/src/xcm_config.rs b/parachain/runtime/kintsugi/src/xcm_config.rs index 7c08f01771..df861934ca 100644 --- a/parachain/runtime/kintsugi/src/xcm_config.rs +++ b/parachain/runtime/kintsugi/src/xcm_config.rs @@ -452,7 +452,7 @@ impl Contains for TinkernetMultisigMultiLocation { matches!( t, MultiLocation { - parents: _, + parents: 1, interior: Junctions::X3( Junction::Parachain(2125), Junction::PalletInstance(71),