From acb7be71cfa1d64ea09ceefdf8c1964684b7315a Mon Sep 17 00:00:00 2001 From: Emiliano <84690100+metricaez@users.noreply.github.com> Date: Tue, 15 Aug 2023 12:09:38 -0300 Subject: [PATCH] Changing XCM config for allow teleport from and to AH (#257) * update filter for allowing teleport * allow all teleporters * provisory wieght for receive_tele - must benchmark * remove CheckAccount on CurrencyAdapter * Implement trusted teleporter * cargo fmt * id does not match HOP id so blocks valid reserve * must add valid junction for native foreig asset * cargo fmt * add assetRegistry to Stout * add mockToken and comment fung trader * Hop Trader on Stout, remove reserve check * add Teleport Filter to allow only HOP * add parachain as valid junction for asset registry * clean dead code -fmt - re enable fung transactor * Change Filter approach to iter Co-authored-by: Hector Bulgarini * fix lint and duplicated code on filter * fix teleport filter, remove match prefix --------- Co-authored-by: Hector Bulgarini --- Cargo.lock | 1 + pallets/asset-registry/src/lib.rs | 4 +- runtime/stout/Cargo.toml | 1 + runtime/stout/src/lib.rs | 29 ++++++ runtime/stout/src/xcm_config.rs | 91 +++++++++++++------ .../xcm/pallet_xcm_benchmarks_fungible.rs | 3 +- runtime/trappist/src/xcm_config.rs | 53 +++++++---- 7 files changed, 133 insertions(+), 49 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index def16c9d..2bcd9a7a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11900,6 +11900,7 @@ dependencies = [ "hex-literal", "kusama-runtime-constants", "log", + "pallet-asset-registry", "pallet-asset-tx-payment", "pallet-assets", "pallet-aura", diff --git a/pallets/asset-registry/src/lib.rs b/pallets/asset-registry/src/lib.rs index dde59817..f3d12269 100644 --- a/pallets/asset-registry/src/lib.rs +++ b/pallets/asset-registry/src/lib.rs @@ -39,7 +39,7 @@ pub mod pallet { use frame_system::pallet_prelude::*; use xcm::latest::{ - Junction::{AccountId32, AccountKey20, GeneralIndex, PalletInstance}, + Junction::{AccountId32, AccountKey20, GeneralIndex, PalletInstance, Parachain}, MultiLocation, }; @@ -158,7 +158,7 @@ pub mod pallet { Some(AccountId32 { .. }) | Some(AccountKey20 { .. }) | Some(PalletInstance(_)) | - None + Some(Parachain(_)) | None ); check | diff --git a/runtime/stout/Cargo.toml b/runtime/stout/Cargo.toml index ca5fff27..a136c9df 100644 --- a/runtime/stout/Cargo.toml +++ b/runtime/stout/Cargo.toml @@ -97,6 +97,7 @@ pallet-xcm-benchmarks = { workspace = true, optional = true } # External Pallets pallet-dex = { workspace = true } pallet-dex-rpc-runtime-api = { workspace = true } +pallet-asset-registry = { workspace = true } [features] default = ["std"] diff --git a/runtime/stout/src/lib.rs b/runtime/stout/src/lib.rs index e8cccf4f..25676ecb 100644 --- a/runtime/stout/src/lib.rs +++ b/runtime/stout/src/lib.rs @@ -510,6 +510,34 @@ impl pallet_dex::Config for Runtime { type MinDeposit = ConstU128<{ UNITS }>; } +#[cfg(feature = "runtime-benchmarks")] +pub struct AssetRegistryBenchmarkHelper; +#[cfg(feature = "runtime-benchmarks")] +impl pallet_asset_registry::BenchmarkHelper + for AssetRegistryBenchmarkHelper +{ + fn get_registered_asset() -> AssetIdForTrustBackedAssets { + use sp_runtime::traits::StaticLookup; + + let root = frame_system::RawOrigin::Root.into(); + let asset_id = 1; + let caller = frame_benchmarking::whitelisted_caller(); + let caller_lookup = ::Lookup::unlookup(caller); + Assets::force_create(root, asset_id.into(), caller_lookup, true, 1) + .expect("Should have been able to force create asset"); + asset_id + } +} + +impl pallet_asset_registry::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type ReserveAssetModifierOrigin = frame_system::EnsureRoot; + type Assets = Assets; + type WeightInfo = (); + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = AssetRegistryBenchmarkHelper; +} + // Create the runtime by composing the FRAME pallets that were previously configured. construct_runtime!( pub enum Runtime where @@ -558,6 +586,7 @@ construct_runtime!( Dex: pallet_dex = 50, Spambot: cumulus_ping::{Pallet, Call, Storage, Event} = 99, + AssetRegistry: pallet_asset_registry::{Pallet, Call, Storage, Event} = 111, } ); diff --git a/runtime/stout/src/xcm_config.rs b/runtime/stout/src/xcm_config.rs index 1c2c96b7..25de23ba 100644 --- a/runtime/stout/src/xcm_config.rs +++ b/runtime/stout/src/xcm_config.rs @@ -18,8 +18,8 @@ use crate::AllPalletsWithSystem; use super::{ - AccountId, Assets, Balance, Balances, ParachainInfo, ParachainSystem, PolkadotXcm, Runtime, - RuntimeCall, RuntimeEvent, RuntimeOrigin, WeightToFee, XcmpQueue, + AccountId, AssetRegistry, Assets, Balance, Balances, ParachainInfo, ParachainSystem, + PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, WeightToFee, XcmpQueue, }; use frame_support::{ match_types, parameter_types, @@ -40,19 +40,22 @@ use xcm_executor::traits::JustTry; use pallet_xcm::{EnsureXcm, IsMajorityOfBody, XcmPassthrough}; use polkadot_parachain::primitives::Sibling; -use xcm::latest::{prelude::*, Fungibility::Fungible, MultiAsset, MultiLocation}; +use xcm::latest::{prelude::*, MultiAsset, MultiLocation}; +use xcm_primitives::{AsAssetMultiLocation, ConvertedRegisteredAssetId}; use xcm_builder::{ AccountId32Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, AsPrefixedGeneralIndex, - ConvertedConcreteId, CurrencyAdapter, EnsureXcmOrigin, FixedWeightBounds, FungiblesAdapter, - IsConcrete, MintLocation, NativeAsset, NoChecking, ParentAsSuperuser, ParentIsPreset, - RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, + ConvertedConcreteId, CurrencyAdapter, EnsureXcmOrigin, FixedRateOfFungible, FixedWeightBounds, + FungiblesAdapter, IsConcrete, MintLocation, NativeAsset, NoChecking, ParentAsSuperuser, + ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, UsingComponents, }; use xcm_executor::XcmExecutor; +use crate::constants::fee::default_fee_per_second; + parameter_types! { pub const RelayLocation: MultiLocation = MultiLocation::parent(); pub const RelayNetwork: NetworkId = NetworkId::Polkadot; @@ -67,6 +70,7 @@ parameter_types! { GlobalConsensus(NetworkId::Rococo), Parachain(ParachainInfo::parachain_id().into()), ).into(); + pub PlaceholderAccount: AccountId = PolkadotXcm::check_account(); } /// We allow root and the Relay Chain council to execute privileged collator selection operations. @@ -122,8 +126,32 @@ pub type FungiblesTransactor = FungiblesAdapter< CheckingAccount, >; +/// Means for transacting reserved fungible assets. +/// AsAssetMultiLocation uses pallet_asset_registry to convert between AssetId and MultiLocation. +pub type ReservedFungiblesTransactor = FungiblesAdapter< + // Use this fungibles implementation: + Assets, + // Use this currency when it is a registered fungible asset matching the given location or name + // Assets not found in AssetRegistry will not be used + ConvertedRegisteredAssetId< + AssetIdForTrustBackedAssets, + Balance, + AsAssetMultiLocation, + JustTry, + >, + // Convert an XCM MultiLocation into a local account id: + LocationToAccountId, + // Our chain's account ID type (we can't get away without mentioning it explicitly): + AccountId, + // We don't track any teleports of `Assets`. + NoChecking, + // We don't track any teleports of `Assets`, but a placeholder account is provided due to trait + // bounds. + PlaceholderAccount, +>; + /// Means for transacting assets on this chain. -pub type AssetTransactors = (CurrencyTransactor, FungiblesTransactor); +pub type AssetTransactors = (CurrencyTransactor, ReservedFungiblesTransactor, FungiblesTransactor); /// This is the type we use to convert an (incoming) XCM origin into a local `Origin` instance, /// ready for dispatching a transaction with Xcm's `Transact`. There is an `OriginKind` which can @@ -188,6 +216,22 @@ pub type Barrier = DenyThenTry< ), >; +parameter_types! { + pub RockmineLocation: MultiLocation = MultiLocation::new(1, X1(Parachain(1000))); + // ALWAYS ensure that the index in PalletInstance stays up-to-date with + // Rockmine's Assets pallet index + pub RockmineAssetsPalletLocation: MultiLocation = + MultiLocation::new(1, X2(Parachain(1000), PalletInstance(50))); + pub RUsdPerSecond: (xcm::v3::AssetId, u128, u128) = ( + MultiLocation::new(1, X3(Parachain(1000), PalletInstance(50), GeneralIndex(1984))).into(), + default_fee_per_second() * 10, + 0u128 + ); + /// Roc = 7 RUSD + pub RocPerSecond: (xcm::v3::AssetId, u128,u128) = (MultiLocation::parent().into(), default_fee_per_second() * 70, 0u128); + pub HopPerSecond: (xcm::v3::AssetId, u128, u128) = (MultiLocation::new(1, X1(Parachain(1836))).into(), default_fee_per_second() * 10, 0u128); +} + parameter_types! { pub StatemineLocation: MultiLocation = MultiLocation::new(1, X1(Parachain(1000))); // ALWAYS ensure that the index in PalletInstance stays up-to-date with @@ -196,30 +240,26 @@ parameter_types! { MultiLocation::new(1, X2(Parachain(1000), PalletInstance(50))); } -//- From PR https://github.com/paritytech/cumulus/pull/936 -fn matches_prefix(prefix: &MultiLocation, loc: &MultiLocation) -> bool { - prefix.parent_count() == loc.parent_count() && - loc.len() >= prefix.len() && - prefix - .interior() - .iter() - .zip(loc.interior().iter()) - .all(|(prefix_junction, junction)| prefix_junction == junction) -} pub struct ReserveAssetsFrom(PhantomData); impl> ContainsPair for ReserveAssetsFrom { - fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { + fn contains(_asset: &MultiAsset, origin: &MultiLocation) -> bool { let prefix = T::get(); log::trace!(target: "xcm::AssetsFrom", "prefix: {:?}, origin: {:?}", prefix, origin); - &prefix == origin && - match asset { - MultiAsset { id: xcm::latest::AssetId::Concrete(asset_loc), fun: Fungible(_a) } => - matches_prefix(&prefix, asset_loc), - _ => false, - } + &prefix == origin } } +pub type Traders = ( + // RUSD + FixedRateOfFungible, + // Roc + FixedRateOfFungible, + //HOP + FixedRateOfFungible, + // Everything else + UsingComponents>, +); + //-- pub type Reserves = (NativeAsset, ReserveAssetsFrom); @@ -235,8 +275,7 @@ impl xcm_executor::Config for XcmConfig { type IsTeleporter = (); // Teleporting is disabled. type Barrier = Barrier; type Weigher = FixedWeightBounds; - type Trader = - UsingComponents>; + type Trader = Traders; type ResponseHandler = PolkadotXcm; type AssetTrap = PolkadotXcm; type AssetClaims = PolkadotXcm; diff --git a/runtime/trappist/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs b/runtime/trappist/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs index 0c7b7df4..86f4ffd9 100644 --- a/runtime/trappist/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs +++ b/runtime/trappist/src/weights/xcm/pallet_xcm_benchmarks_fungible.rs @@ -103,7 +103,8 @@ impl WeightInfo { // Measured: `0` // Estimated: `0` // Minimum execution time: 500_000_000_000 picoseconds. - Weight::from_parts(500_000_000_000, 0) + // Extracted from previous implementations. TODO: Benchmark + Weight::from_parts(4_848_000, 0) } /// Storage: System Account (r:1 w:1) /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) diff --git a/runtime/trappist/src/xcm_config.rs b/runtime/trappist/src/xcm_config.rs index a2e02757..817cad60 100644 --- a/runtime/trappist/src/xcm_config.rs +++ b/runtime/trappist/src/xcm_config.rs @@ -16,8 +16,9 @@ // limitations under the License. use frame_support::{ + inherent::Vec, match_types, parameter_types, - traits::{ContainsPair, EitherOfDiverse, Everything, Get, Nothing, PalletInfoAccess}, + traits::{Contains, ContainsPair, EitherOfDiverse, Everything, Get, Nothing, PalletInfoAccess}, weights::Weight, }; use frame_system::EnsureRoot; @@ -63,6 +64,7 @@ parameter_types! { pub SelfReserve: MultiLocation = MultiLocation { parents:0, interior: Here }; pub AssetsPalletLocation: MultiLocation = PalletInstance(::index() as u8).into(); + // Be mindful with incoming teleports if you implement this pub CheckAccount: (AccountId, MintLocation) = (PolkadotXcm::check_account(), MintLocation::Local); pub PlaceholderAccount: AccountId = PolkadotXcm::check_account(); pub const ExecutiveBody: BodyId = BodyId::Executive; @@ -105,7 +107,7 @@ pub type LocalAssetTransactor = CurrencyAdapter< LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, - // For the moment we don't keep track of Teleports. + // We don't track any teleports. (), >; @@ -231,27 +233,37 @@ parameter_types! { pub RocPerSecond: (xcm::v3::AssetId, u128,u128) = (MultiLocation::parent().into(), default_fee_per_second() * 70, 0u128); } -//- From PR https://github.com/paritytech/cumulus/pull/936 -fn matches_prefix(prefix: &MultiLocation, loc: &MultiLocation) -> bool { - prefix.parent_count() == loc.parent_count() && - loc.len() >= prefix.len() && - prefix - .interior() - .iter() - .zip(loc.interior().iter()) - .all(|(prefix_junction, junction)| prefix_junction == junction) +parameter_types! { + pub const TrappistNative: MultiAssetFilter = Wild(AllOf { fun: WildFungible, id: Concrete(MultiLocation::here()) }); + pub AssetHubTrustedTeleporter: (MultiAssetFilter, MultiLocation) = (TrappistNative::get(), RockmineLocation::get()); } + pub struct ReserveAssetsFrom(PhantomData); impl> ContainsPair for ReserveAssetsFrom { fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { let prefix = T::get(); - log::trace!(target: "xcm::AssetsFrom", "prefix: {:?}, origin: {:?}", prefix, origin); - &prefix == origin && - match asset { - MultiAsset { id: xcm::latest::AssetId::Concrete(asset_loc), fun: Fungible(_a) } => - matches_prefix(&prefix, asset_loc), - _ => false, + log::trace!(target: "xcm::AssetsFrom", "prefix: {:?}, origin: {:?}, asset: {:?}", prefix, origin, asset); + &prefix == origin + } +} + +pub struct OnlyTeleportNative; +impl Contains<(MultiLocation, Vec)> for OnlyTeleportNative { + fn contains(t: &(MultiLocation, Vec)) -> bool { + t.1.iter().any(|asset| { + log::trace!(target: "xcm::OnlyTeleportNative", "Asset to be teleported: {:?}", asset); + + if let MultiAsset { id: xcm::latest::AssetId::Concrete(asset_loc), fun: Fungible(_a) } = + asset + { + match asset_loc { + MultiLocation { parents: 0, interior: Here } => true, + _ => false, + } + } else { + false } + }) } } @@ -265,6 +277,7 @@ pub type Traders = ( ); pub type Reserves = (NativeAsset, ReserveAssetsFrom); +pub type TrustedTeleporters = (xcm_builder::Case,); pub struct XcmConfig; impl xcm_executor::Config for XcmConfig { @@ -273,9 +286,8 @@ impl xcm_executor::Config for XcmConfig { type AssetTransactor = AssetTransactors; type OriginConverter = XcmOriginToTransactDispatchOrigin; type IsReserve = Reserves; - type IsTeleporter = (); + type IsTeleporter = TrustedTeleporters; type UniversalLocation = UniversalLocation; - // Teleporting is disabled. type Barrier = Barrier; type Weigher = WeightInfoBounds< crate::weights::xcm::TrappistXcmWeight, @@ -331,7 +343,8 @@ impl pallet_xcm::Config for Runtime { type ExecuteXcmOrigin = EnsureXcmOrigin; type XcmExecuteFilter = Everything; type XcmExecutor = XcmExecutor; - type XcmTeleportFilter = Nothing; + //Only teleport of HOP is allowed + type XcmTeleportFilter = OnlyTeleportNative; type XcmReserveTransferFilter = Everything; type Weigher = WeightInfoBounds< crate::weights::xcm::TrappistXcmWeight,