From c4ccaa835a78aafcd049a524a8d717d16d445f3b Mon Sep 17 00:00:00 2001 From: muharem Date: Tue, 20 Feb 2024 11:31:02 +0800 Subject: [PATCH 01/25] pool assets instance setup --- .../asset-hubs/asset-hub-polkadot/src/lib.rs | 44 +- .../asset-hub-polkadot/src/weights/mod.rs | 1 + .../src/weights/pallet_assets_pool.rs | 530 ++++++++++++++++++ .../asset-hub-polkadot/src/xcm_config.rs | 322 ++++++----- 4 files changed, 744 insertions(+), 153 deletions(-) create mode 100644 system-parachains/asset-hubs/asset-hub-polkadot/src/weights/pallet_assets_pool.rs diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs index fa6efa5915..5ce57ae52a 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs @@ -66,7 +66,7 @@ use assets_common::{foreign_creators::ForeignCreators, matching::FromSiblingPara use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; use cumulus_primitives_core::{AggregateMessageOrigin, ParaId}; use sp_api::impl_runtime_apis; -use sp_core::{crypto::KeyTypeId, OpaqueMetadata}; +use sp_core::{crypto::KeyTypeId, ConstU128, OpaqueMetadata}; use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, ConvertInto, Verify}, @@ -87,7 +87,7 @@ use frame_support::{ parameter_types, traits::{ AsEnsureOriginWithArg, ConstBool, ConstU32, ConstU64, ConstU8, EitherOfDiverse, Equals, - InstanceFilter, TransformOrigin, + InstanceFilter, NeverEnsureOrigin, TransformOrigin, }, weights::{ConstantMultiplier, Weight}, PalletId, @@ -113,8 +113,8 @@ use system_parachains_constants::{ use xcm::latest::prelude::{AssetId, BodyId}; use xcm_config::{ DotLocation, FellowshipLocation, ForeignAssetsConvertedConcreteId, - ForeignCreatorsSovereignAccountOf, GovernanceLocation, TrustBackedAssetsConvertedConcreteId, - XcmOriginToTransactDispatchOrigin, + ForeignCreatorsSovereignAccountOf, GovernanceLocation, PoolAssetsConvertedConcreteId, + TrustBackedAssetsConvertedConcreteId, XcmOriginToTransactDispatchOrigin, }; #[cfg(any(feature = "std", test))] @@ -814,6 +814,30 @@ impl pallet_xcm_bridge_hub_router::Config for Runtime type FeeAsset = xcm_config::bridging::XcmBridgeHubRouterFeeAssetId; } +pub type PoolAssetsInstance = pallet_assets::Instance3; +impl pallet_assets::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Balance = Balance; + type RemoveItemsLimit = ConstU32<1000>; + type AssetId = u32; + type AssetIdParameter = u32; + type Currency = Balances; + type CreateOrigin = NeverEnsureOrigin; + type ForceOrigin = AssetsForceOrigin; + type AssetDeposit = ConstU128<0>; + type AssetAccountDeposit = ConstU128<0>; + type MetadataDepositBase = ConstU128<0>; + type MetadataDepositPerByte = ConstU128<0>; + type ApprovalDeposit = ExistentialDeposit; + type StringLimit = ConstU32<50>; + type Freezer = (); + type Extra = (); + type CallbackHandle = (); + type WeightInfo = weights::pallet_assets_pool::WeightInfo; + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = (); +} + // Create the runtime by composing the FRAME pallets that were previously configured. construct_runtime!( pub enum Runtime @@ -857,6 +881,7 @@ construct_runtime!( Uniques: pallet_uniques = 51, Nfts: pallet_nfts = 52, ForeignAssets: pallet_assets:: = 53, + PoolAssets: pallet_assets:: = 54, } ); @@ -906,6 +931,7 @@ mod benches { [frame_system, SystemBench::] [pallet_assets, Local] [pallet_assets, Foreign] + [pallet_assets, Pool] [pallet_balances, Balances] [pallet_message_queue, MessageQueue] [pallet_multisig, Multisig] @@ -1092,10 +1118,16 @@ impl_runtime_apis! { )?, // collect pallet_assets (ForeignAssets) convert::<_, _, _, _, ForeignAssetsConvertedConcreteId>( - ForeignAssets::account_balances(account) + ForeignAssets::account_balances(account.clone()) .iter() .filter(|(_, balance)| balance > &0) )?, + // collect pallet_assets (PoolAssets) + convert::<_, _, _, _, PoolAssetsConvertedConcreteId>( + PoolAssets::account_balances(account) + .iter() + .filter(|(_, balance)| balance > &0) + )?, // collect ... e.g. other tokens ].concat().into()) } @@ -1161,6 +1193,7 @@ impl_runtime_apis! { // `pallet_assets_local.rs / pallet_assets_foreign.rs`. type Local = pallet_assets::Pallet::; type Foreign = pallet_assets::Pallet::; + type Pool = pallet_assets::Pallet::; type ToKusama = XcmBridgeHubRouterBench; @@ -1468,6 +1501,7 @@ impl_runtime_apis! { type Local = pallet_assets::Pallet::; type Foreign = pallet_assets::Pallet::; + type Pool = pallet_assets::Pallet::; type ToKusama = XcmBridgeHubRouterBench; diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/mod.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/mod.rs index 58477b320a..e9879e088b 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/mod.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/mod.rs @@ -22,6 +22,7 @@ pub mod extrinsic_weights; pub mod frame_system; pub mod pallet_assets_foreign; pub mod pallet_assets_local; +pub mod pallet_assets_pool; pub mod pallet_balances; pub mod pallet_collator_selection; pub mod pallet_message_queue; diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/pallet_assets_pool.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/pallet_assets_pool.rs new file mode 100644 index 0000000000..922137b547 --- /dev/null +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/pallet_assets_pool.rs @@ -0,0 +1,530 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Autogenerated weights for `pallet_assets` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `ggwpez-ref-hw`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("../asset-hub-kusama-chain-spec.json")`, DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=../asset-hub-kusama-chain-spec.json +// --steps=50 +// --repeat=20 +// --pallet=pallet_assets +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --output=./asset-hub-kusama-weights +// --header=./file_header.txt + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_assets`. +pub struct WeightInfo(PhantomData); +impl pallet_assets::WeightInfo for WeightInfo { + /// Storage: `PoolAssets::Asset` (r:1 w:1) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + fn create() -> Weight { + // Proof Size summary in bytes: + // Measured: `42` + // Estimated: `3675` + // Minimum execution time: 10_327_000 picoseconds. + Weight::from_parts(10_767_000, 0) + .saturating_add(Weight::from_parts(0, 3675)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `PoolAssets::Asset` (r:1 w:1) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + fn force_create() -> Weight { + // Proof Size summary in bytes: + // Measured: `42` + // Estimated: `3675` + // Minimum execution time: 9_859_000 picoseconds. + Weight::from_parts(10_313_000, 0) + .saturating_add(Weight::from_parts(0, 3675)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `PoolAssets::Asset` (r:1 w:1) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + fn start_destroy() -> Weight { + // Proof Size summary in bytes: + // Measured: `314` + // Estimated: `3675` + // Minimum execution time: 10_349_000 picoseconds. + Weight::from_parts(10_780_000, 0) + .saturating_add(Weight::from_parts(0, 3675)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `PoolAssets::Asset` (r:1 w:1) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `PoolAssets::Account` (r:1001 w:1000) + /// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1000 w:1000) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// The range of component `c` is `[0, 1000]`. + /// The range of component `c` is `[0, 1000]`. + /// The range of component `c` is `[0, 1000]`. + fn destroy_accounts(c: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `122 + c * (208 ±0)` + // Estimated: `3675 + c * (2609 ±0)` + // Minimum execution time: 14_416_000 picoseconds. + Weight::from_parts(14_691_000, 0) + .saturating_add(Weight::from_parts(0, 3675)) + // Standard Error: 7_257 + .saturating_add(Weight::from_parts(13_166_740, 0).saturating_mul(c.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(c.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((2_u64).saturating_mul(c.into()))) + .saturating_add(Weight::from_parts(0, 2609).saturating_mul(c.into())) + } + /// Storage: `PoolAssets::Asset` (r:1 w:1) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `PoolAssets::Approvals` (r:1001 w:1000) + /// Proof: `PoolAssets::Approvals` (`max_values`: None, `max_size`: Some(148), added: 2623, mode: `MaxEncodedLen`) + /// The range of component `a` is `[0, 1000]`. + /// The range of component `a` is `[0, 1000]`. + /// The range of component `a` is `[0, 1000]`. + fn destroy_approvals(a: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `451 + a * (86 ±0)` + // Estimated: `3675 + a * (2623 ±0)` + // Minimum execution time: 14_333_000 picoseconds. + Weight::from_parts(14_651_000, 0) + .saturating_add(Weight::from_parts(0, 3675)) + // Standard Error: 4_812 + .saturating_add(Weight::from_parts(13_784_978, 0).saturating_mul(a.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(a.into()))) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(a.into()))) + .saturating_add(Weight::from_parts(0, 2623).saturating_mul(a.into())) + } + /// Storage: `PoolAssets::Asset` (r:1 w:1) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `PoolAssets::Metadata` (r:1 w:0) + /// Proof: `PoolAssets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) + fn finish_destroy() -> Weight { + // Proof Size summary in bytes: + // Measured: `280` + // Estimated: `3675` + // Minimum execution time: 11_770_000 picoseconds. + Weight::from_parts(12_178_000, 0) + .saturating_add(Weight::from_parts(0, 3675)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `PoolAssets::Asset` (r:1 w:1) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `PoolAssets::Account` (r:1 w:1) + /// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + fn mint() -> Weight { + // Proof Size summary in bytes: + // Measured: `280` + // Estimated: `3675` + // Minimum execution time: 20_274_000 picoseconds. + Weight::from_parts(21_083_000, 0) + .saturating_add(Weight::from_parts(0, 3675)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `PoolAssets::Asset` (r:1 w:1) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `PoolAssets::Account` (r:1 w:1) + /// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + fn burn() -> Weight { + // Proof Size summary in bytes: + // Measured: `388` + // Estimated: `3675` + // Minimum execution time: 26_271_000 picoseconds. + Weight::from_parts(27_277_000, 0) + .saturating_add(Weight::from_parts(0, 3675)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `PoolAssets::Asset` (r:1 w:1) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `PoolAssets::Account` (r:2 w:2) + /// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn transfer() -> Weight { + // Proof Size summary in bytes: + // Measured: `427` + // Estimated: `6208` + // Minimum execution time: 37_162_000 picoseconds. + Weight::from_parts(38_134_000, 0) + .saturating_add(Weight::from_parts(0, 6208)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: `PoolAssets::Asset` (r:1 w:1) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `PoolAssets::Account` (r:2 w:2) + /// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn transfer_keep_alive() -> Weight { + // Proof Size summary in bytes: + // Measured: `427` + // Estimated: `6208` + // Minimum execution time: 32_987_000 picoseconds. + Weight::from_parts(33_868_000, 0) + .saturating_add(Weight::from_parts(0, 6208)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: `PoolAssets::Asset` (r:1 w:1) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `PoolAssets::Account` (r:2 w:2) + /// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn force_transfer() -> Weight { + // Proof Size summary in bytes: + // Measured: `427` + // Estimated: `6208` + // Minimum execution time: 37_562_000 picoseconds. + Weight::from_parts(38_201_000, 0) + .saturating_add(Weight::from_parts(0, 6208)) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: `PoolAssets::Asset` (r:1 w:0) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `PoolAssets::Account` (r:1 w:1) + /// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + fn freeze() -> Weight { + // Proof Size summary in bytes: + // Measured: `388` + // Estimated: `3675` + // Minimum execution time: 14_035_000 picoseconds. + Weight::from_parts(14_629_000, 0) + .saturating_add(Weight::from_parts(0, 3675)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `PoolAssets::Asset` (r:1 w:0) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `PoolAssets::Account` (r:1 w:1) + /// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + fn thaw() -> Weight { + // Proof Size summary in bytes: + // Measured: `388` + // Estimated: `3675` + // Minimum execution time: 14_047_000 picoseconds. + Weight::from_parts(14_523_000, 0) + .saturating_add(Weight::from_parts(0, 3675)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `PoolAssets::Asset` (r:1 w:1) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + fn freeze_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `314` + // Estimated: `3675` + // Minimum execution time: 10_020_000 picoseconds. + Weight::from_parts(10_489_000, 0) + .saturating_add(Weight::from_parts(0, 3675)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `PoolAssets::Asset` (r:1 w:1) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + fn thaw_asset() -> Weight { + // Proof Size summary in bytes: + // Measured: `314` + // Estimated: `3675` + // Minimum execution time: 10_016_000 picoseconds. + Weight::from_parts(10_344_000, 0) + .saturating_add(Weight::from_parts(0, 3675)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `PoolAssets::Asset` (r:1 w:1) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `PoolAssets::Metadata` (r:1 w:0) + /// Proof: `PoolAssets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) + fn transfer_ownership() -> Weight { + // Proof Size summary in bytes: + // Measured: `280` + // Estimated: `3675` + // Minimum execution time: 12_335_000 picoseconds. + Weight::from_parts(12_920_000, 0) + .saturating_add(Weight::from_parts(0, 3675)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `PoolAssets::Asset` (r:1 w:1) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + fn set_team() -> Weight { + // Proof Size summary in bytes: + // Measured: `280` + // Estimated: `3675` + // Minimum execution time: 11_099_000 picoseconds. + Weight::from_parts(11_545_000, 0) + .saturating_add(Weight::from_parts(0, 3675)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `PoolAssets::Asset` (r:1 w:0) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `PoolAssets::Metadata` (r:1 w:1) + /// Proof: `PoolAssets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) + /// The range of component `n` is `[0, 50]`. + /// The range of component `s` is `[0, 50]`. + /// The range of component `n` is `[0, 50]`. + /// The range of component `s` is `[0, 50]`. + /// The range of component `n` is `[0, 50]`. + /// The range of component `s` is `[0, 50]`. + fn set_metadata(n: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `280` + // Estimated: `3675` + // Minimum execution time: 11_847_000 picoseconds. + Weight::from_parts(12_587_711, 0) + .saturating_add(Weight::from_parts(0, 3675)) + // Standard Error: 202 + .saturating_add(Weight::from_parts(2_693, 0).saturating_mul(n.into())) + // Standard Error: 202 + .saturating_add(Weight::from_parts(2_968, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `PoolAssets::Asset` (r:1 w:0) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `PoolAssets::Metadata` (r:1 w:1) + /// Proof: `PoolAssets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) + fn clear_metadata() -> Weight { + // Proof Size summary in bytes: + // Measured: `444` + // Estimated: `3675` + // Minimum execution time: 12_969_000 picoseconds. + Weight::from_parts(13_612_000, 0) + .saturating_add(Weight::from_parts(0, 3675)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `PoolAssets::Asset` (r:1 w:0) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `PoolAssets::Metadata` (r:1 w:1) + /// Proof: `PoolAssets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) + /// The range of component `n` is `[0, 50]`. + /// The range of component `s` is `[0, 50]`. + /// The range of component `n` is `[0, 50]`. + /// The range of component `s` is `[0, 50]`. + /// The range of component `n` is `[0, 50]`. + /// The range of component `s` is `[0, 50]`. + fn force_set_metadata(n: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `119` + // Estimated: `3675` + // Minimum execution time: 11_159_000 picoseconds. + Weight::from_parts(11_752_476, 0) + .saturating_add(Weight::from_parts(0, 3675)) + // Standard Error: 192 + .saturating_add(Weight::from_parts(1_592, 0).saturating_mul(n.into())) + // Standard Error: 192 + .saturating_add(Weight::from_parts(2_277, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `PoolAssets::Asset` (r:1 w:0) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `PoolAssets::Metadata` (r:1 w:1) + /// Proof: `PoolAssets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`) + fn force_clear_metadata() -> Weight { + // Proof Size summary in bytes: + // Measured: `444` + // Estimated: `3675` + // Minimum execution time: 12_375_000 picoseconds. + Weight::from_parts(13_011_000, 0) + .saturating_add(Weight::from_parts(0, 3675)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `PoolAssets::Asset` (r:1 w:1) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + fn force_asset_status() -> Weight { + // Proof Size summary in bytes: + // Measured: `280` + // Estimated: `3675` + // Minimum execution time: 10_409_000 picoseconds. + Weight::from_parts(10_977_000, 0) + .saturating_add(Weight::from_parts(0, 3675)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `PoolAssets::Asset` (r:1 w:1) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `PoolAssets::Approvals` (r:1 w:1) + /// Proof: `PoolAssets::Approvals` (`max_values`: None, `max_size`: Some(148), added: 2623, mode: `MaxEncodedLen`) + fn approve_transfer() -> Weight { + // Proof Size summary in bytes: + // Measured: `314` + // Estimated: `3675` + // Minimum execution time: 26_135_000 picoseconds. + Weight::from_parts(26_736_000, 0) + .saturating_add(Weight::from_parts(0, 3675)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `PoolAssets::Asset` (r:1 w:1) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `PoolAssets::Approvals` (r:1 w:1) + /// Proof: `PoolAssets::Approvals` (`max_values`: None, `max_size`: Some(148), added: 2623, mode: `MaxEncodedLen`) + /// Storage: `PoolAssets::Account` (r:2 w:2) + /// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn transfer_approved() -> Weight { + // Proof Size summary in bytes: + // Measured: `597` + // Estimated: `6208` + // Minimum execution time: 55_219_000 picoseconds. + Weight::from_parts(56_400_000, 0) + .saturating_add(Weight::from_parts(0, 6208)) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(5)) + } + /// Storage: `PoolAssets::Asset` (r:1 w:1) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `PoolAssets::Approvals` (r:1 w:1) + /// Proof: `PoolAssets::Approvals` (`max_values`: None, `max_size`: Some(148), added: 2623, mode: `MaxEncodedLen`) + fn cancel_approval() -> Weight { + // Proof Size summary in bytes: + // Measured: `484` + // Estimated: `3675` + // Minimum execution time: 28_475_000 picoseconds. + Weight::from_parts(29_194_000, 0) + .saturating_add(Weight::from_parts(0, 3675)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `PoolAssets::Asset` (r:1 w:1) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `PoolAssets::Approvals` (r:1 w:1) + /// Proof: `PoolAssets::Approvals` (`max_values`: None, `max_size`: Some(148), added: 2623, mode: `MaxEncodedLen`) + fn force_cancel_approval() -> Weight { + // Proof Size summary in bytes: + // Measured: `484` + // Estimated: `3675` + // Minimum execution time: 28_943_000 picoseconds. + Weight::from_parts(29_674_000, 0) + .saturating_add(Weight::from_parts(0, 3675)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `PoolAssets::Asset` (r:1 w:1) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + fn set_min_balance() -> Weight { + // Proof Size summary in bytes: + // Measured: `280` + // Estimated: `3675` + // Minimum execution time: 11_309_000 picoseconds. + Weight::from_parts(11_601_000, 0) + .saturating_add(Weight::from_parts(0, 3675)) + .saturating_add(T::DbWeight::get().reads(1)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: `PoolAssets::Account` (r:1 w:1) + /// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `PoolAssets::Asset` (r:1 w:1) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + fn touch() -> Weight { + // Proof Size summary in bytes: + // Measured: `280` + // Estimated: `3675` + // Minimum execution time: 15_731_000 picoseconds. + Weight::from_parts(16_413_000, 0) + .saturating_add(Weight::from_parts(0, 3675)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `PoolAssets::Account` (r:1 w:1) + /// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `PoolAssets::Asset` (r:1 w:1) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + fn touch_other() -> Weight { + // Proof Size summary in bytes: + // Measured: `280` + // Estimated: `3675` + // Minimum execution time: 15_119_000 picoseconds. + Weight::from_parts(15_668_000, 0) + .saturating_add(Weight::from_parts(0, 3675)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `PoolAssets::Account` (r:1 w:1) + /// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `PoolAssets::Asset` (r:1 w:1) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + fn refund() -> Weight { + // Proof Size summary in bytes: + // Measured: `406` + // Estimated: `3675` + // Minimum execution time: 14_162_000 picoseconds. + Weight::from_parts(14_911_000, 0) + .saturating_add(Weight::from_parts(0, 3675)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `PoolAssets::Account` (r:1 w:1) + /// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + /// Storage: `PoolAssets::Asset` (r:1 w:1) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + fn refund_other() -> Weight { + // Proof Size summary in bytes: + // Measured: `439` + // Estimated: `3675` + // Minimum execution time: 13_897_000 picoseconds. + Weight::from_parts(14_365_000, 0) + .saturating_add(Weight::from_parts(0, 3675)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + } + /// Storage: `PoolAssets::Asset` (r:1 w:0) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `PoolAssets::Account` (r:1 w:1) + /// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + fn block() -> Weight { + // Proof Size summary in bytes: + // Measured: `388` + // Estimated: `3675` + // Minimum execution time: 14_060_000 picoseconds. + Weight::from_parts(14_496_000, 0) + .saturating_add(Weight::from_parts(0, 3675)) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + } +} diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/xcm_config.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/xcm_config.rs index b662f16d6e..af6872b87f 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/src/xcm_config.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/xcm_config.rs @@ -15,9 +15,9 @@ use super::{ AccountId, AllPalletsWithSystem, Assets, Authorship, Balance, Balances, ForeignAssets, - ParachainInfo, ParachainSystem, PolkadotXcm, PriceForParentDelivery, Runtime, RuntimeCall, - RuntimeEvent, RuntimeOrigin, ToKusamaXcmRouter, TrustBackedAssetsInstance, WeightToFee, - XcmpQueue, + ParachainInfo, ParachainSystem, PolkadotXcm, PoolAssets, PriceForParentDelivery, Runtime, + RuntimeCall, RuntimeEvent, RuntimeOrigin, ToKusamaXcmRouter, TrustBackedAssetsInstance, + WeightToFee, XcmpQueue, }; use crate::ForeignAssetsInstance; use assets_common::matching::{FromSiblingParachain, IsForeignConcreteAsset}; @@ -66,6 +66,8 @@ parameter_types! { pub const GovernanceLocation: Location = Location::parent(); pub RelayTreasuryLocation: Location = (Parent, PalletInstance(polkadot_runtime_constants::TREASURY_PALLET_ID)).into(); pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); + pub PoolAssetsPalletLocation: Location = + PalletInstance(::index() as u8).into(); } /// Type for specifying how a `Location` can be converted into an `AccountId`. This is used @@ -151,8 +153,30 @@ pub type ForeignFungiblesTransactor = FungiblesAdapter< CheckingAccount, >; +/// `AssetId`/`Balance` converter for `PoolAssets`. +pub type PoolAssetsConvertedConcreteId = + assets_common::PoolAssetsConvertedConcreteId; + +/// Means for transacting asset conversion pool assets on this chain. +pub type PoolFungiblesTransactor = FungiblesAdapter< + // Use this fungibles implementation: + PoolAssets, + // Use this currency when it is a fungible asset matching the given location or name: + PoolAssetsConvertedConcreteId, + // 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 only want to allow teleports of known assets. We use non-zero issuance as an indication + // that this asset is known. + LocalMint>, + // The account to use for tracking teleports. + CheckingAccount, +>; + /// Means for transacting assets on this chain. -pub type AssetTransactors = (FungibleTransactor, FungiblesTransactor, ForeignFungiblesTransactor); +pub type AssetTransactors = + (FungibleTransactor, FungiblesTransactor, ForeignFungiblesTransactor, PoolFungiblesTransactor); /// 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 @@ -195,8 +219,8 @@ impl Contains for FellowshipEntities { Parachain(system_parachain::COLLECTIVES_ID), Plurality { id: BodyId::Technical, .. } ] - ) | (1, [Parachain(system_parachain::COLLECTIVES_ID), PalletInstance(64)]) | - (1, [Parachain(system_parachain::COLLECTIVES_ID), PalletInstance(65)]) + ) | (1, [Parachain(system_parachain::COLLECTIVES_ID), PalletInstance(64)]) + | (1, [Parachain(system_parachain::COLLECTIVES_ID), PalletInstance(65)]) ) } } @@ -221,7 +245,7 @@ impl Contains for SafeCallFilter { #[cfg(feature = "runtime-benchmarks")] { if matches!(call, RuntimeCall::System(frame_system::Call::remark_with_event { .. })) { - return true + return true; } } @@ -229,158 +253,160 @@ impl Contains for SafeCallFilter { match call { RuntimeCall::System(frame_system::Call::set_storage { items }) if items.iter().all(|(k, _)| { - k.eq(&bridging::XcmBridgeHubRouterBaseFee::key()) || - k.eq(&bridging::XcmBridgeHubRouterByteFee::key()) + k.eq(&bridging::XcmBridgeHubRouterBaseFee::key()) + || k.eq(&bridging::XcmBridgeHubRouterByteFee::key()) }) => - return true, + { + return true + }, _ => (), }; matches!( call, RuntimeCall::PolkadotXcm( - pallet_xcm::Call::force_xcm_version { .. } | - pallet_xcm::Call::force_default_xcm_version { .. } + pallet_xcm::Call::force_xcm_version { .. } + | pallet_xcm::Call::force_default_xcm_version { .. } ) | RuntimeCall::System( - frame_system::Call::set_heap_pages { .. } | - frame_system::Call::set_code { .. } | - frame_system::Call::set_code_without_checks { .. } | - frame_system::Call::kill_prefix { .. }, - ) | RuntimeCall::ParachainSystem(..) | - RuntimeCall::Timestamp(..) | - RuntimeCall::Balances(..) | - RuntimeCall::CollatorSelection( - pallet_collator_selection::Call::set_desired_candidates { .. } | - pallet_collator_selection::Call::set_candidacy_bond { .. } | - pallet_collator_selection::Call::register_as_candidate { .. } | - pallet_collator_selection::Call::leave_intent { .. } | - pallet_collator_selection::Call::set_invulnerables { .. } | - pallet_collator_selection::Call::add_invulnerable { .. } | - pallet_collator_selection::Call::remove_invulnerable { .. }, - ) | RuntimeCall::Session(pallet_session::Call::purge_keys { .. }) | - RuntimeCall::XcmpQueue(..) | - RuntimeCall::DmpQueue(..) | - RuntimeCall::Assets( - pallet_assets::Call::create { .. } | - pallet_assets::Call::force_create { .. } | - pallet_assets::Call::start_destroy { .. } | - pallet_assets::Call::destroy_accounts { .. } | - pallet_assets::Call::destroy_approvals { .. } | - pallet_assets::Call::finish_destroy { .. } | - pallet_assets::Call::mint { .. } | - pallet_assets::Call::burn { .. } | - pallet_assets::Call::transfer { .. } | - pallet_assets::Call::transfer_keep_alive { .. } | - pallet_assets::Call::force_transfer { .. } | - pallet_assets::Call::freeze { .. } | - pallet_assets::Call::thaw { .. } | - pallet_assets::Call::freeze_asset { .. } | - pallet_assets::Call::thaw_asset { .. } | - pallet_assets::Call::transfer_ownership { .. } | - pallet_assets::Call::set_team { .. } | - pallet_assets::Call::set_metadata { .. } | - pallet_assets::Call::clear_metadata { .. } | - pallet_assets::Call::force_set_metadata { .. } | - pallet_assets::Call::force_clear_metadata { .. } | - pallet_assets::Call::force_asset_status { .. } | - pallet_assets::Call::approve_transfer { .. } | - pallet_assets::Call::cancel_approval { .. } | - pallet_assets::Call::force_cancel_approval { .. } | - pallet_assets::Call::transfer_approved { .. } | - pallet_assets::Call::touch { .. } | - pallet_assets::Call::refund { .. }, + frame_system::Call::set_heap_pages { .. } + | frame_system::Call::set_code { .. } + | frame_system::Call::set_code_without_checks { .. } + | frame_system::Call::kill_prefix { .. }, + ) | RuntimeCall::ParachainSystem(..) + | RuntimeCall::Timestamp(..) + | RuntimeCall::Balances(..) + | RuntimeCall::CollatorSelection( + pallet_collator_selection::Call::set_desired_candidates { .. } + | pallet_collator_selection::Call::set_candidacy_bond { .. } + | pallet_collator_selection::Call::register_as_candidate { .. } + | pallet_collator_selection::Call::leave_intent { .. } + | pallet_collator_selection::Call::set_invulnerables { .. } + | pallet_collator_selection::Call::add_invulnerable { .. } + | pallet_collator_selection::Call::remove_invulnerable { .. }, + ) | RuntimeCall::Session(pallet_session::Call::purge_keys { .. }) + | RuntimeCall::XcmpQueue(..) + | RuntimeCall::DmpQueue(..) + | RuntimeCall::Assets( + pallet_assets::Call::create { .. } + | pallet_assets::Call::force_create { .. } + | pallet_assets::Call::start_destroy { .. } + | pallet_assets::Call::destroy_accounts { .. } + | pallet_assets::Call::destroy_approvals { .. } + | pallet_assets::Call::finish_destroy { .. } + | pallet_assets::Call::mint { .. } + | pallet_assets::Call::burn { .. } + | pallet_assets::Call::transfer { .. } + | pallet_assets::Call::transfer_keep_alive { .. } + | pallet_assets::Call::force_transfer { .. } + | pallet_assets::Call::freeze { .. } + | pallet_assets::Call::thaw { .. } + | pallet_assets::Call::freeze_asset { .. } + | pallet_assets::Call::thaw_asset { .. } + | pallet_assets::Call::transfer_ownership { .. } + | pallet_assets::Call::set_team { .. } + | pallet_assets::Call::set_metadata { .. } + | pallet_assets::Call::clear_metadata { .. } + | pallet_assets::Call::force_set_metadata { .. } + | pallet_assets::Call::force_clear_metadata { .. } + | pallet_assets::Call::force_asset_status { .. } + | pallet_assets::Call::approve_transfer { .. } + | pallet_assets::Call::cancel_approval { .. } + | pallet_assets::Call::force_cancel_approval { .. } + | pallet_assets::Call::transfer_approved { .. } + | pallet_assets::Call::touch { .. } + | pallet_assets::Call::refund { .. }, ) | RuntimeCall::ForeignAssets( - pallet_assets::Call::create { .. } | - pallet_assets::Call::force_create { .. } | - pallet_assets::Call::start_destroy { .. } | - pallet_assets::Call::destroy_accounts { .. } | - pallet_assets::Call::destroy_approvals { .. } | - pallet_assets::Call::finish_destroy { .. } | - pallet_assets::Call::mint { .. } | - pallet_assets::Call::burn { .. } | - pallet_assets::Call::transfer { .. } | - pallet_assets::Call::transfer_keep_alive { .. } | - pallet_assets::Call::force_transfer { .. } | - pallet_assets::Call::freeze { .. } | - pallet_assets::Call::thaw { .. } | - pallet_assets::Call::freeze_asset { .. } | - pallet_assets::Call::thaw_asset { .. } | - pallet_assets::Call::transfer_ownership { .. } | - pallet_assets::Call::set_team { .. } | - pallet_assets::Call::set_metadata { .. } | - pallet_assets::Call::clear_metadata { .. } | - pallet_assets::Call::force_set_metadata { .. } | - pallet_assets::Call::force_clear_metadata { .. } | - pallet_assets::Call::force_asset_status { .. } | - pallet_assets::Call::approve_transfer { .. } | - pallet_assets::Call::cancel_approval { .. } | - pallet_assets::Call::force_cancel_approval { .. } | - pallet_assets::Call::transfer_approved { .. } | - pallet_assets::Call::touch { .. } | - pallet_assets::Call::refund { .. }, + pallet_assets::Call::create { .. } + | pallet_assets::Call::force_create { .. } + | pallet_assets::Call::start_destroy { .. } + | pallet_assets::Call::destroy_accounts { .. } + | pallet_assets::Call::destroy_approvals { .. } + | pallet_assets::Call::finish_destroy { .. } + | pallet_assets::Call::mint { .. } + | pallet_assets::Call::burn { .. } + | pallet_assets::Call::transfer { .. } + | pallet_assets::Call::transfer_keep_alive { .. } + | pallet_assets::Call::force_transfer { .. } + | pallet_assets::Call::freeze { .. } + | pallet_assets::Call::thaw { .. } + | pallet_assets::Call::freeze_asset { .. } + | pallet_assets::Call::thaw_asset { .. } + | pallet_assets::Call::transfer_ownership { .. } + | pallet_assets::Call::set_team { .. } + | pallet_assets::Call::set_metadata { .. } + | pallet_assets::Call::clear_metadata { .. } + | pallet_assets::Call::force_set_metadata { .. } + | pallet_assets::Call::force_clear_metadata { .. } + | pallet_assets::Call::force_asset_status { .. } + | pallet_assets::Call::approve_transfer { .. } + | pallet_assets::Call::cancel_approval { .. } + | pallet_assets::Call::force_cancel_approval { .. } + | pallet_assets::Call::transfer_approved { .. } + | pallet_assets::Call::touch { .. } + | pallet_assets::Call::refund { .. }, ) | RuntimeCall::Nfts( - pallet_nfts::Call::create { .. } | - pallet_nfts::Call::force_create { .. } | - pallet_nfts::Call::destroy { .. } | - pallet_nfts::Call::mint { .. } | - pallet_nfts::Call::force_mint { .. } | - pallet_nfts::Call::burn { .. } | - pallet_nfts::Call::transfer { .. } | - pallet_nfts::Call::lock_item_transfer { .. } | - pallet_nfts::Call::unlock_item_transfer { .. } | - pallet_nfts::Call::lock_collection { .. } | - pallet_nfts::Call::transfer_ownership { .. } | - pallet_nfts::Call::set_team { .. } | - pallet_nfts::Call::force_collection_owner { .. } | - pallet_nfts::Call::force_collection_config { .. } | - pallet_nfts::Call::approve_transfer { .. } | - pallet_nfts::Call::cancel_approval { .. } | - pallet_nfts::Call::clear_all_transfer_approvals { .. } | - pallet_nfts::Call::lock_item_properties { .. } | - pallet_nfts::Call::set_attribute { .. } | - pallet_nfts::Call::force_set_attribute { .. } | - pallet_nfts::Call::clear_attribute { .. } | - pallet_nfts::Call::approve_item_attributes { .. } | - pallet_nfts::Call::cancel_item_attributes_approval { .. } | - pallet_nfts::Call::set_metadata { .. } | - pallet_nfts::Call::clear_metadata { .. } | - pallet_nfts::Call::set_collection_metadata { .. } | - pallet_nfts::Call::clear_collection_metadata { .. } | - pallet_nfts::Call::set_accept_ownership { .. } | - pallet_nfts::Call::set_collection_max_supply { .. } | - pallet_nfts::Call::update_mint_settings { .. } | - pallet_nfts::Call::set_price { .. } | - pallet_nfts::Call::buy_item { .. } | - pallet_nfts::Call::pay_tips { .. } | - pallet_nfts::Call::create_swap { .. } | - pallet_nfts::Call::cancel_swap { .. } | - pallet_nfts::Call::claim_swap { .. }, + pallet_nfts::Call::create { .. } + | pallet_nfts::Call::force_create { .. } + | pallet_nfts::Call::destroy { .. } + | pallet_nfts::Call::mint { .. } + | pallet_nfts::Call::force_mint { .. } + | pallet_nfts::Call::burn { .. } + | pallet_nfts::Call::transfer { .. } + | pallet_nfts::Call::lock_item_transfer { .. } + | pallet_nfts::Call::unlock_item_transfer { .. } + | pallet_nfts::Call::lock_collection { .. } + | pallet_nfts::Call::transfer_ownership { .. } + | pallet_nfts::Call::set_team { .. } + | pallet_nfts::Call::force_collection_owner { .. } + | pallet_nfts::Call::force_collection_config { .. } + | pallet_nfts::Call::approve_transfer { .. } + | pallet_nfts::Call::cancel_approval { .. } + | pallet_nfts::Call::clear_all_transfer_approvals { .. } + | pallet_nfts::Call::lock_item_properties { .. } + | pallet_nfts::Call::set_attribute { .. } + | pallet_nfts::Call::force_set_attribute { .. } + | pallet_nfts::Call::clear_attribute { .. } + | pallet_nfts::Call::approve_item_attributes { .. } + | pallet_nfts::Call::cancel_item_attributes_approval { .. } + | pallet_nfts::Call::set_metadata { .. } + | pallet_nfts::Call::clear_metadata { .. } + | pallet_nfts::Call::set_collection_metadata { .. } + | pallet_nfts::Call::clear_collection_metadata { .. } + | pallet_nfts::Call::set_accept_ownership { .. } + | pallet_nfts::Call::set_collection_max_supply { .. } + | pallet_nfts::Call::update_mint_settings { .. } + | pallet_nfts::Call::set_price { .. } + | pallet_nfts::Call::buy_item { .. } + | pallet_nfts::Call::pay_tips { .. } + | pallet_nfts::Call::create_swap { .. } + | pallet_nfts::Call::cancel_swap { .. } + | pallet_nfts::Call::claim_swap { .. }, ) | RuntimeCall::Uniques( - pallet_uniques::Call::create { .. } | - pallet_uniques::Call::force_create { .. } | - pallet_uniques::Call::destroy { .. } | - pallet_uniques::Call::mint { .. } | - pallet_uniques::Call::burn { .. } | - pallet_uniques::Call::transfer { .. } | - pallet_uniques::Call::freeze { .. } | - pallet_uniques::Call::thaw { .. } | - pallet_uniques::Call::freeze_collection { .. } | - pallet_uniques::Call::thaw_collection { .. } | - pallet_uniques::Call::transfer_ownership { .. } | - pallet_uniques::Call::set_team { .. } | - pallet_uniques::Call::approve_transfer { .. } | - pallet_uniques::Call::cancel_approval { .. } | - pallet_uniques::Call::force_item_status { .. } | - pallet_uniques::Call::set_attribute { .. } | - pallet_uniques::Call::clear_attribute { .. } | - pallet_uniques::Call::set_metadata { .. } | - pallet_uniques::Call::clear_metadata { .. } | - pallet_uniques::Call::set_collection_metadata { .. } | - pallet_uniques::Call::clear_collection_metadata { .. } | - pallet_uniques::Call::set_accept_ownership { .. } | - pallet_uniques::Call::set_collection_max_supply { .. } | - pallet_uniques::Call::set_price { .. } | - pallet_uniques::Call::buy_item { .. } + pallet_uniques::Call::create { .. } + | pallet_uniques::Call::force_create { .. } + | pallet_uniques::Call::destroy { .. } + | pallet_uniques::Call::mint { .. } + | pallet_uniques::Call::burn { .. } + | pallet_uniques::Call::transfer { .. } + | pallet_uniques::Call::freeze { .. } + | pallet_uniques::Call::thaw { .. } + | pallet_uniques::Call::freeze_collection { .. } + | pallet_uniques::Call::thaw_collection { .. } + | pallet_uniques::Call::transfer_ownership { .. } + | pallet_uniques::Call::set_team { .. } + | pallet_uniques::Call::approve_transfer { .. } + | pallet_uniques::Call::cancel_approval { .. } + | pallet_uniques::Call::force_item_status { .. } + | pallet_uniques::Call::set_attribute { .. } + | pallet_uniques::Call::clear_attribute { .. } + | pallet_uniques::Call::set_metadata { .. } + | pallet_uniques::Call::clear_metadata { .. } + | pallet_uniques::Call::set_collection_metadata { .. } + | pallet_uniques::Call::clear_collection_metadata { .. } + | pallet_uniques::Call::set_accept_ownership { .. } + | pallet_uniques::Call::set_collection_max_supply { .. } + | pallet_uniques::Call::set_price { .. } + | pallet_uniques::Call::buy_item { .. } ) | RuntimeCall::ToKusamaXcmRouter( pallet_xcm_bridge_hub_router::Call::report_bridge_status { .. } ) From 18f2cea3eec2c61f92f732f42236f55012957952 Mon Sep 17 00:00:00 2001 From: muharem Date: Wed, 21 Feb 2024 14:45:10 +0800 Subject: [PATCH 02/25] asset conversion setup for asset-hub-polkadot --- Cargo.lock | 2 + .../asset-hubs/asset-hub-polkadot/Cargo.toml | 9 +- .../asset-hub-polkadot/src/impls.rs | 70 ++++++++ .../asset-hubs/asset-hub-polkadot/src/lib.rs | 117 ++++++++++++- .../asset-hub-polkadot/src/weights/mod.rs | 1 + .../src/weights/pallet_asset_conversion.rs | 156 ++++++++++++++++++ .../asset-hub-polkadot/src/xcm_config.rs | 6 +- 7 files changed, 354 insertions(+), 7 deletions(-) create mode 100644 system-parachains/asset-hubs/asset-hub-polkadot/src/impls.rs create mode 100644 system-parachains/asset-hubs/asset-hub-polkadot/src/weights/pallet_asset_conversion.rs diff --git a/Cargo.lock b/Cargo.lock index 2aa42c95c7..36fe5dba17 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -612,6 +612,7 @@ dependencies = [ "hex-literal", "kusama-runtime-constants", "log", + "pallet-asset-conversion", "pallet-asset-tx-payment", "pallet-assets", "pallet-aura", @@ -639,6 +640,7 @@ dependencies = [ "polkadot-parachain-primitives", "polkadot-runtime-common", "polkadot-runtime-constants", + "primitive-types", "scale-info", "sp-api", "sp-block-builder", diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml b/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml index 2c2affff30..1551f39bdf 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml +++ b/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml @@ -30,6 +30,7 @@ frame-system = { default-features = false, version = "29.0.0" } frame-system-benchmarking = { default-features = false, optional = true, version = "29.0.0" } frame-system-rpc-runtime-api = { default-features = false, version = "27.0.0" } frame-try-runtime = { default-features = false, optional = true, version = "0.35.0" } +pallet-asset-conversion = { default-features = false, version = "11.0.0" } pallet-asset-tx-payment = { default-features = false , version = "29.0.0" } pallet-assets = { default-features = false, version = "30.0.0" } pallet-aura = { default-features = false, version = "28.0.0" } @@ -51,6 +52,7 @@ sp-block-builder = { default-features = false, version = "27.0.0" } sp-consensus-aura = { default-features = false, version = "0.33.0" } sp-core = { default-features = false, version = "29.0.0" } sp-genesis-builder = { default-features = false , version = "0.8.0" } +sp-io = { default-features = false , version = "31.0.0" } sp-inherents = { default-features = false, version = "27.0.0" } sp-offchain = { default-features = false, version = "27.0.0" } sp-runtime = { default-features = false, version = "32.0.0" } @@ -60,6 +62,8 @@ sp-storage = { default-features = false, version = "20.0.0" } sp-transaction-pool = { default-features = false, version = "27.0.0" } sp-version = { default-features = false, version = "30.0.0" } sp-weights = { default-features = false, version = "28.0.0" } +# num-traits feature needed for dex integer sq root: +primitive-types = { version = "0.12.2", default-features = false, features = ["codec", "scale-info", "num-traits"] } # Polkadot pallet-xcm = { default-features = false, version = "8.0.2" } @@ -93,7 +97,6 @@ pallet-xcm-bridge-hub-router = { default-features = false , version = "0.6.0" } hex-literal = "0.4.1" asset-test-utils = { version = "8.0.1" } parachains-runtimes-test-utils = { version = "8.0.0" } -sp-io = { version = "31.0.0" } [build-dependencies] substrate-wasm-builder = { optional = true , version = "18.0.0" } @@ -112,6 +115,7 @@ runtime-benchmarks = [ "frame-system-benchmarking/runtime-benchmarks", "frame-system/runtime-benchmarks", "hex-literal", + "pallet-asset-conversion/runtime-benchmarks", "pallet-asset-tx-payment/runtime-benchmarks", "pallet-assets/runtime-benchmarks", "pallet-balances/runtime-benchmarks", @@ -142,6 +146,7 @@ try-runtime = [ "frame-support/try-runtime", "frame-system/try-runtime", "frame-try-runtime/try-runtime", + "pallet-asset-conversion/try-runtime", "pallet-asset-tx-payment/try-runtime", "pallet-assets/try-runtime", "pallet-aura/try-runtime", @@ -187,6 +192,7 @@ std = [ "frame-try-runtime?/std", "kusama-runtime-constants/std", "log/std", + "pallet-asset-conversion/std", "pallet-asset-tx-payment/std", "pallet-assets/std", "pallet-aura/std", @@ -220,6 +226,7 @@ std = [ "sp-core/std", "sp-genesis-builder/std", "sp-inherents/std", + "sp-io/std", "sp-offchain/std", "sp-runtime/std", "sp-session/std", diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/impls.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/impls.rs new file mode 100644 index 0000000000..866dccf3f7 --- /dev/null +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/impls.rs @@ -0,0 +1,70 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::*; + +// TODO: the types in the module copied from the PR: https://github.com/paritytech/polkadot-sdk/pull/3250 +// and should be removed when changes from the PR will get released. +pub(crate) mod pool { + use super::*; + use core::marker::PhantomData; + use pallet_asset_conversion::PoolLocator; + use sp_core::Get; + use sp_runtime::traits::{TrailingZeroInput, TryConvert}; + + /// Pool locator that mandates the inclusion of the specified `FirstAsset` in every asset pair. + /// + /// The `PoolId` is represented as a tuple of `AssetKind`s with `FirstAsset` always positioned + /// as the first element. + pub struct WithFirstAsset( + PhantomData<(FirstAsset, AccountId, AssetKind, AccountIdConverter)>, + ); + impl + PoolLocator + for WithFirstAsset + where + AssetKind: Eq + Clone + Encode, + AccountId: Decode, + FirstAsset: Get, + AccountIdConverter: for<'a> TryConvert<&'a (AssetKind, AssetKind), AccountId>, + { + fn pool_id(asset1: &AssetKind, asset2: &AssetKind) -> Result<(AssetKind, AssetKind), ()> { + let first = FirstAsset::get(); + match true { + _ if asset1 == asset2 => Err(()), + _ if first == *asset1 => Ok((first, asset2.clone())), + _ if first == *asset2 => Ok((first, asset1.clone())), + _ => Err(()), + } + } + fn address(id: &(AssetKind, AssetKind)) -> Result { + AccountIdConverter::try_convert(id).map_err(|_| ()) + } + } + + /// `PoolId` to `AccountId` conversion. + pub struct AccountIdConverter(PhantomData<(Seed, PoolId)>); + impl TryConvert<&PoolId, AccountId> for AccountIdConverter + where + PoolId: Encode, + AccountId: Decode, + Seed: Get, + { + fn try_convert(id: &PoolId) -> Result { + let encoded = sp_io::hashing::blake2_256(&Encode::encode(&(Seed::get(), id))[..]); + Decode::decode(&mut TrailingZeroInput::new(encoded.as_ref())).map_err(|_| id) + } + } +} diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs index 5ce57ae52a..e420c9e1cf 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs @@ -59,10 +59,16 @@ #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); +mod impls; mod weights; pub mod xcm_config; -use assets_common::{foreign_creators::ForeignCreators, matching::FromSiblingParachain}; +use assets_common::{ + foreign_creators::ForeignCreators, + local_and_foreign_assets::{LocalFromLeft, TargetFromLeft}, + matching::FromSiblingParachain, + AssetIdForTrustBackedAssetsConvert, +}; use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases; use cumulus_primitives_core::{AggregateMessageOrigin, ParaId}; use sp_api::impl_runtime_apis; @@ -71,8 +77,9 @@ use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, ConvertInto, Verify}, transaction_validity::{TransactionSource, TransactionValidity}, - ApplyExtrinsicResult, Perbill, + ApplyExtrinsicResult, Perbill, Permill, }; +use xcm_config::TrustBackedAssetsPalletLocationV3; use sp_std::prelude::*; #[cfg(feature = "std")] @@ -86,8 +93,9 @@ use frame_support::{ genesis_builder_helper::{build_config, create_default_config}, parameter_types, traits::{ - AsEnsureOriginWithArg, ConstBool, ConstU32, ConstU64, ConstU8, EitherOfDiverse, Equals, - InstanceFilter, NeverEnsureOrigin, TransformOrigin, + fungible, fungibles, tokens::imbalance::ResolveAssetTo, AsEnsureOriginWithArg, ConstBool, + ConstU32, ConstU64, ConstU8, EitherOfDiverse, Equals, InstanceFilter, NeverEnsureOrigin, + TransformOrigin, }, weights::{ConstantMultiplier, Weight}, PalletId, @@ -112,7 +120,7 @@ use system_parachains_constants::{ }; use xcm::latest::prelude::{AssetId, BodyId}; use xcm_config::{ - DotLocation, FellowshipLocation, ForeignAssetsConvertedConcreteId, + DotLocation, DotLocationV3, FellowshipLocation, ForeignAssetsConvertedConcreteId, ForeignCreatorsSovereignAccountOf, GovernanceLocation, PoolAssetsConvertedConcreteId, TrustBackedAssetsConvertedConcreteId, XcmOriginToTransactDispatchOrigin, }; @@ -838,6 +846,66 @@ impl pallet_assets::Config for Runtime { type BenchmarkHelper = (); } +/// Union fungibles implementation for `Assets`` and `ForeignAssets`. +pub type LocalAndForeignAssets = fungibles::UnionOf< + Assets, + ForeignAssets, + LocalFromLeft< + AssetIdForTrustBackedAssetsConvert, + AssetIdForTrustBackedAssets, + xcm::v3::Location, + >, + xcm::v3::Location, + AccountId, +>; + +parameter_types! { + pub const AssetConversionPalletId: PalletId = PalletId(*b"py/ascon"); + // TODO any fee? + pub const LiquidityWithdrawalFee: Permill = Permill::from_percent(0); +} + +impl pallet_asset_conversion::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Balance = Balance; + type HigherPrecisionBalance = sp_core::U256; + type AssetKind = xcm::v3::Location; + type Assets = fungible::UnionOf< + Balances, + LocalAndForeignAssets, + TargetFromLeft, + Self::AssetKind, + Self::AccountId, + >; + type PoolId = (Self::AssetKind, Self::AssetKind); + type PoolLocator = impls::pool::WithFirstAsset< + DotLocationV3, + AccountId, + Self::AssetKind, + impls::pool::AccountIdConverter, + >; + type PoolAssetId = u32; + type PoolAssets = PoolAssets; + // TODO any fee? + type PoolSetupFee = ConstU128<0>; + type PoolSetupFeeAsset = DotLocationV3; + // TODO replace by treasury pallet account + type PoolSetupFeeTarget = ResolveAssetTo; + type LiquidityWithdrawalFee = LiquidityWithdrawalFee; + type LPFee = ConstU32<3>; + type PalletId = AssetConversionPalletId; + type MaxSwapPathLength = ConstU32<3>; + type MintMinLiquidity = ConstU128<100>; + type WeightInfo = weights::pallet_asset_conversion::WeightInfo; + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = assets_common::benchmarks::AssetPairFactory< + DotLocationV3, + parachain_info::Pallet, + xcm_config::TrustBackedAssetsPalletIndex, + Self::AssetKind, + >; +} + // Create the runtime by composing the FRAME pallets that were previously configured. construct_runtime!( pub enum Runtime @@ -882,6 +950,7 @@ construct_runtime!( Nfts: pallet_nfts = 52, ForeignAssets: pallet_assets:: = 53, PoolAssets: pallet_assets:: = 54, + AssetConversion: pallet_asset_conversion = 55, } ); @@ -932,6 +1001,7 @@ mod benches { [pallet_assets, Local] [pallet_assets, Foreign] [pallet_assets, Pool] + [pallet_asset_conversion, AssetConversion] [pallet_balances, Balances] [pallet_message_queue, MessageQueue] [pallet_multisig, Multisig] @@ -1149,6 +1219,43 @@ impl_runtime_apis! { } } + impl pallet_asset_conversion::AssetConversionApi for Runtime { + fn quote_price_exact_tokens_for_tokens( + asset1: xcm::v3::Location, + asset2: xcm::v3::Location, + amount: Balance, + include_fee: bool, + ) -> Option { + AssetConversion::quote_price_exact_tokens_for_tokens( + asset1, + asset2, + amount, + include_fee, + ) + } + + fn quote_price_tokens_for_exact_tokens( + asset1: xcm::v3::Location, + asset2: xcm::v3::Location, + amount: Balance, + include_fee: bool, + ) -> Option { + AssetConversion::quote_price_tokens_for_exact_tokens( + asset1, + asset2, + amount, + include_fee, + ) + } + + fn get_reserves( + asset1: xcm::v3::Location, + asset2: xcm::v3::Location, + ) -> Option<(Balance, Balance)> { + AssetConversion::get_reserves(asset1, asset2).ok() + } + } + #[cfg(feature = "try-runtime")] impl frame_try_runtime::TryRuntime for Runtime { fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) { diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/mod.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/mod.rs index e9879e088b..e64eef645d 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/mod.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/mod.rs @@ -20,6 +20,7 @@ pub mod cumulus_pallet_parachain_system; pub mod cumulus_pallet_xcmp_queue; pub mod extrinsic_weights; pub mod frame_system; +pub mod pallet_asset_conversion; pub mod pallet_assets_foreign; pub mod pallet_assets_local; pub mod pallet_assets_pool; diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/pallet_asset_conversion.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/pallet_asset_conversion.rs new file mode 100644 index 0000000000..97b959858f --- /dev/null +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/weights/pallet_asset_conversion.rs @@ -0,0 +1,156 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// This file is part of Polkadot. + +// Polkadot is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Polkadot is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . + +//! Autogenerated weights for `pallet_asset_conversion` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-12-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `ggwpez-ref-hw`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("../asset-hub-kusama-chain-spec.json")`, DB CACHE: 1024 + +// Executed Command: +// ./target/production/polkadot +// benchmark +// pallet +// --chain=../asset-hub-kusama-chain-spec.json +// --steps=50 +// --repeat=20 +// --pallet=pallet_asset_conversion +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --output=./asset-hub-kusama-weights +// --header=./file_header.txt + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::Weight}; +use core::marker::PhantomData; + +/// Weight functions for `pallet_asset_conversion`. +pub struct WeightInfo(PhantomData); +impl pallet_asset_conversion::WeightInfo for WeightInfo { + /// Storage: `AssetConversion::Pools` (r:1 w:1) + /// Proof: `AssetConversion::Pools` (`max_values`: None, `max_size`: Some(1224), added: 3699, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:2 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `ForeignAssets::Account` (r:1 w:1) + /// Proof: `ForeignAssets::Account` (`max_values`: None, `max_size`: Some(732), added: 3207, mode: `MaxEncodedLen`) + /// Storage: `ForeignAssets::Asset` (r:1 w:1) + /// Proof: `ForeignAssets::Asset` (`max_values`: None, `max_size`: Some(808), added: 3283, mode: `MaxEncodedLen`) + /// Storage: `AssetConversion::NextPoolAssetId` (r:1 w:1) + /// Proof: `AssetConversion::NextPoolAssetId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `PoolAssets::Asset` (r:1 w:1) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `PoolAssets::Account` (r:1 w:1) + /// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + fn create_pool() -> Weight { + // Proof Size summary in bytes: + // Measured: `499` + // Estimated: `6196` + // Minimum execution time: 74_492_000 picoseconds. + Weight::from_parts(77_141_000, 0) + .saturating_add(Weight::from_parts(0, 6196)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(7)) + } + /// Storage: `AssetConversion::Pools` (r:1 w:0) + /// Proof: `AssetConversion::Pools` (`max_values`: None, `max_size`: Some(1224), added: 3699, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `ForeignAssets::Asset` (r:1 w:1) + /// Proof: `ForeignAssets::Asset` (`max_values`: None, `max_size`: Some(808), added: 3283, mode: `MaxEncodedLen`) + /// Storage: `ForeignAssets::Account` (r:2 w:2) + /// Proof: `ForeignAssets::Account` (`max_values`: None, `max_size`: Some(732), added: 3207, mode: `MaxEncodedLen`) + /// Storage: `PoolAssets::Asset` (r:1 w:1) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `PoolAssets::Account` (r:2 w:2) + /// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + fn add_liquidity() -> Weight { + // Proof Size summary in bytes: + // Measured: `1188` + // Estimated: `7404` + // Minimum execution time: 136_659_000 picoseconds. + Weight::from_parts(138_677_000, 0) + .saturating_add(Weight::from_parts(0, 7404)) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(7)) + } + /// Storage: `AssetConversion::Pools` (r:1 w:0) + /// Proof: `AssetConversion::Pools` (`max_values`: None, `max_size`: Some(1224), added: 3699, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:1 w:1) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `ForeignAssets::Asset` (r:1 w:1) + /// Proof: `ForeignAssets::Asset` (`max_values`: None, `max_size`: Some(808), added: 3283, mode: `MaxEncodedLen`) + /// Storage: `ForeignAssets::Account` (r:2 w:2) + /// Proof: `ForeignAssets::Account` (`max_values`: None, `max_size`: Some(732), added: 3207, mode: `MaxEncodedLen`) + /// Storage: `PoolAssets::Asset` (r:1 w:1) + /// Proof: `PoolAssets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`) + /// Storage: `PoolAssets::Account` (r:1 w:1) + /// Proof: `PoolAssets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`) + fn remove_liquidity() -> Weight { + // Proof Size summary in bytes: + // Measured: `1177` + // Estimated: `7404` + // Minimum execution time: 126_575_000 picoseconds. + Weight::from_parts(128_510_000, 0) + .saturating_add(Weight::from_parts(0, 7404)) + .saturating_add(T::DbWeight::get().reads(7)) + .saturating_add(T::DbWeight::get().writes(6)) + } + /// Storage: `ForeignAssets::Asset` (r:2 w:2) + /// Proof: `ForeignAssets::Asset` (`max_values`: None, `max_size`: Some(808), added: 3283, mode: `MaxEncodedLen`) + /// Storage: `ForeignAssets::Account` (r:4 w:4) + /// Proof: `ForeignAssets::Account` (`max_values`: None, `max_size`: Some(732), added: 3207, mode: `MaxEncodedLen`) + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + fn swap_exact_tokens_for_tokens(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + n * (557 ±0)` + // Estimated: `7404 + n * (393 ±92)` + // Minimum execution time: 930_000_000 picoseconds. + Weight::from_parts(960_000_000, 0) + .saturating_add(Weight::from_parts(0, 7404)) + // Standard Error: 17_993_720 + .saturating_add(Weight::from_parts(41_959_183, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(Weight::from_parts(0, 393).saturating_mul(n.into())) + } + /// Storage: `System::Account` (r:2 w:2) + /// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`) + /// Storage: `ForeignAssets::Asset` (r:2 w:2) + /// Proof: `ForeignAssets::Asset` (`max_values`: None, `max_size`: Some(808), added: 3283, mode: `MaxEncodedLen`) + /// Storage: `ForeignAssets::Account` (r:4 w:4) + /// Proof: `ForeignAssets::Account` (`max_values`: None, `max_size`: Some(732), added: 3207, mode: `MaxEncodedLen`) + fn swap_tokens_for_exact_tokens(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0 + n * (557 ±0)` + // Estimated: `7404 + n * (393 ±92)` + // Minimum execution time: 940_000_000 picoseconds. + Weight::from_parts(956_000_000, 0) + .saturating_add(Weight::from_parts(0, 7404)) + // Standard Error: 15_746_647 + .saturating_add(Weight::from_parts(39_193_877, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(4)) + .saturating_add(Weight::from_parts(0, 393).saturating_mul(n.into())) + } +} diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/xcm_config.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/xcm_config.rs index af6872b87f..7bd3c382f9 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/src/xcm_config.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/xcm_config.rs @@ -54,13 +54,17 @@ use xcm_executor::{traits::WithOriginFilter, XcmExecutor}; parameter_types! { pub const DotLocation: Location = Location::parent(); + pub const DotLocationV3: xcm::v3::Location = xcm::v3::Location::parent(); pub const RelayNetwork: Option = Some(NetworkId::Polkadot); pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); pub UniversalLocation: InteriorLocation = [GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into())].into(); pub UniversalLocationNetworkId: NetworkId = UniversalLocation::get().global_consensus().unwrap(); + pub TrustBackedAssetsPalletIndex: u8 = ::index() as u8; pub TrustBackedAssetsPalletLocation: Location = - PalletInstance(::index() as u8).into(); + PalletInstance(TrustBackedAssetsPalletIndex::get()).into(); + pub TrustBackedAssetsPalletLocationV3: xcm::v3::Location = + xcm::v3::Junction::PalletInstance(TrustBackedAssetsPalletIndex::get()).into(); pub CheckingAccount: AccountId = PolkadotXcm::check_account(); pub FellowshipLocation: Location = Location::new(1, Parachain(system_parachain::COLLECTIVES_ID)); pub const GovernanceLocation: Location = Location::parent(); From bd93eb0647911cf5ae3ee65f103a8a23ddc60abe Mon Sep 17 00:00:00 2001 From: muharem Date: Wed, 21 Feb 2024 14:57:21 +0800 Subject: [PATCH 03/25] asset conversion tx payment setup for asset-hub-polkadot --- Cargo.lock | 2 +- .../asset-hubs/asset-hub-polkadot/Cargo.toml | 7 ++--- .../asset-hubs/asset-hub-polkadot/src/lib.rs | 28 ++++++++----------- 3 files changed, 15 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 36fe5dba17..7e01d7ea19 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -613,7 +613,7 @@ dependencies = [ "kusama-runtime-constants", "log", "pallet-asset-conversion", - "pallet-asset-tx-payment", + "pallet-asset-conversion-tx-payment", "pallet-assets", "pallet-aura", "pallet-authorship", diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml b/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml index 1551f39bdf..fc5f849abe 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml +++ b/system-parachains/asset-hubs/asset-hub-polkadot/Cargo.toml @@ -30,8 +30,8 @@ frame-system = { default-features = false, version = "29.0.0" } frame-system-benchmarking = { default-features = false, optional = true, version = "29.0.0" } frame-system-rpc-runtime-api = { default-features = false, version = "27.0.0" } frame-try-runtime = { default-features = false, optional = true, version = "0.35.0" } +pallet-asset-conversion-tx-payment = { default-features = false, version = "11.0.0" } pallet-asset-conversion = { default-features = false, version = "11.0.0" } -pallet-asset-tx-payment = { default-features = false , version = "29.0.0" } pallet-assets = { default-features = false, version = "30.0.0" } pallet-aura = { default-features = false, version = "28.0.0" } pallet-authorship = { default-features = false, version = "29.0.0" } @@ -116,7 +116,6 @@ runtime-benchmarks = [ "frame-system/runtime-benchmarks", "hex-literal", "pallet-asset-conversion/runtime-benchmarks", - "pallet-asset-tx-payment/runtime-benchmarks", "pallet-assets/runtime-benchmarks", "pallet-balances/runtime-benchmarks", "pallet-collator-selection/runtime-benchmarks", @@ -146,8 +145,8 @@ try-runtime = [ "frame-support/try-runtime", "frame-system/try-runtime", "frame-try-runtime/try-runtime", + "pallet-asset-conversion-tx-payment/try-runtime", "pallet-asset-conversion/try-runtime", - "pallet-asset-tx-payment/try-runtime", "pallet-assets/try-runtime", "pallet-aura/try-runtime", "pallet-authorship/try-runtime", @@ -192,8 +191,8 @@ std = [ "frame-try-runtime?/std", "kusama-runtime-constants/std", "log/std", + "pallet-asset-conversion-tx-payment/std", "pallet-asset-conversion/std", - "pallet-asset-tx-payment/std", "pallet-assets/std", "pallet-aura/std", "pallet-authorship/std", diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs index e420c9e1cf..9ab98e6972 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs @@ -75,7 +75,7 @@ use sp_api::impl_runtime_apis; use sp_core::{crypto::KeyTypeId, ConstU128, OpaqueMetadata}; use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, - traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, ConvertInto, Verify}, + traits::{AccountIdLookup, BlakeTwo256, Block as BlockT, Verify}, transaction_validity::{TransactionSource, TransactionValidity}, ApplyExtrinsicResult, Perbill, Permill, }; @@ -106,10 +106,8 @@ use frame_system::{ }; use pallet_nfts::PalletFeatures; use parachains_common::{ - impls::{AssetsToBlockAuthor, DealWithFees}, - message_queue::*, - AccountId, AssetHubPolkadotAuraId as AuraId, AssetIdForTrustBackedAssets, Balance, BlockNumber, - Hash, Header, Nonce, Signature, + impls::DealWithFees, message_queue::*, AccountId, AssetHubPolkadotAuraId as AuraId, + AssetIdForTrustBackedAssets, Balance, BlockNumber, Hash, Header, Nonce, Signature, }; use sp_runtime::RuntimeDebug; @@ -707,17 +705,13 @@ impl pallet_collator_selection::Config for Runtime { type WeightInfo = weights::pallet_collator_selection::WeightInfo; } -impl pallet_asset_tx_payment::Config for Runtime { +impl pallet_asset_conversion_tx_payment::Config for Runtime { type RuntimeEvent = RuntimeEvent; - type Fungibles = Assets; - type OnChargeAssetTransaction = pallet_asset_tx_payment::FungiblesAdapter< - pallet_assets::BalanceToAssetBalance< - Balances, - Runtime, - ConvertInto, - TrustBackedAssetsInstance, - >, - AssetsToBlockAuthor, + type Fungibles = LocalAndForeignAssets; + type OnChargeAssetTransaction = pallet_asset_conversion_tx_payment::AssetConversionAdapter< + Balances, + AssetConversion, + DotLocationV3, >; } @@ -920,7 +914,7 @@ construct_runtime!( // Monetary stuff. Balances: pallet_balances = 10, TransactionPayment: pallet_transaction_payment = 11, - AssetTxPayment: pallet_asset_tx_payment = 12, + AssetTxPayment: pallet_asset_conversion_tx_payment = 13, // Collator support. the order of these 5 are important and shall not change. Authorship: pallet_authorship = 20, @@ -971,7 +965,7 @@ pub type SignedExtra = ( frame_system::CheckEra, frame_system::CheckNonce, frame_system::CheckWeight, - pallet_asset_tx_payment::ChargeAssetTxPayment, + pallet_asset_conversion_tx_payment::ChargeAssetTxPayment, ); /// Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = From 4c7357d7122fcc0875606dd0dcd8f99eeaa22583 Mon Sep 17 00:00:00 2001 From: muharem Date: Wed, 21 Feb 2024 16:56:04 +0800 Subject: [PATCH 04/25] swap trader setup for polkadot and kusama asset hubs --- .../asset-hub-kusama/src/xcm_config.rs | 395 +++++++++--------- .../asset-hubs/asset-hub-polkadot/src/lib.rs | 17 +- .../asset-hub-polkadot/src/xcm_config.rs | 33 +- 3 files changed, 246 insertions(+), 199 deletions(-) diff --git a/system-parachains/asset-hubs/asset-hub-kusama/src/xcm_config.rs b/system-parachains/asset-hubs/asset-hub-kusama/src/xcm_config.rs index 96ac90bc43..0f58423baa 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/src/xcm_config.rs +++ b/system-parachains/asset-hubs/asset-hub-kusama/src/xcm_config.rs @@ -14,16 +14,22 @@ // limitations under the License. use super::{ - AccountId, AllPalletsWithSystem, Assets, Authorship, Balance, Balances, ParachainInfo, - ParachainSystem, PolkadotXcm, PoolAssets, PriceForParentDelivery, Runtime, RuntimeCall, - RuntimeEvent, RuntimeOrigin, ToPolkadotXcmRouter, TrustBackedAssetsInstance, WeightToFee, - XcmpQueue, + AccountId, AllPalletsWithSystem, AssetConversion, Assets, Authorship, Balance, Balances, + CollatorSelection, NativeAndAssets, ParachainInfo, ParachainSystem, PolkadotXcm, PoolAssets, + PriceForParentDelivery, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, ToPolkadotXcmRouter, + TrustBackedAssetsInstance, WeightToFee, XcmpQueue, }; use crate::{ForeignAssets, ForeignAssetsInstance}; -use assets_common::matching::{FromSiblingParachain, IsForeignConcreteAsset}; +use assets_common::{ + matching::{FromSiblingParachain, IsForeignConcreteAsset}, + TrustBackedAssetsAsLocation, +}; use frame_support::{ parameter_types, - traits::{ConstU32, Contains, Equals, Everything, Nothing, PalletInfoAccess}, + traits::{ + tokens::imbalance::ResolveAssetTo, ConstU32, Contains, Equals, Everything, Nothing, + PalletInfoAccess, + }, }; use frame_system::EnsureRoot; use pallet_xcm::XcmPassthrough; @@ -73,6 +79,7 @@ parameter_types! { pub const FellowshipLocation: Location = Location::parent(); pub RelayTreasuryLocation: Location = (Parent, PalletInstance(kusama_runtime_constants::TREASURY_PALLET_ID)).into(); pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); + pub StakingPot: AccountId = CollatorSelection::account_id(); } /// Type for specifying how a `Location` can be converted into an `AccountId`. This is used @@ -233,7 +240,7 @@ impl Contains for SafeCallFilter { #[cfg(feature = "runtime-benchmarks")] { if matches!(call, RuntimeCall::System(frame_system::Call::remark_with_event { .. })) { - return true + return true; } } @@ -241,199 +248,201 @@ impl Contains for SafeCallFilter { match call { RuntimeCall::System(frame_system::Call::set_storage { items }) if items.iter().all(|(k, _)| { - k.eq(&bridging::XcmBridgeHubRouterBaseFee::key()) || - k.eq(&bridging::XcmBridgeHubRouterByteFee::key()) + k.eq(&bridging::XcmBridgeHubRouterBaseFee::key()) + || k.eq(&bridging::XcmBridgeHubRouterByteFee::key()) }) => - return true, + { + return true + }, _ => (), }; matches!( call, RuntimeCall::PolkadotXcm( - pallet_xcm::Call::force_xcm_version { .. } | - pallet_xcm::Call::force_default_xcm_version { .. } + pallet_xcm::Call::force_xcm_version { .. } + | pallet_xcm::Call::force_default_xcm_version { .. } ) | RuntimeCall::System( - frame_system::Call::set_heap_pages { .. } | - frame_system::Call::set_code { .. } | - frame_system::Call::set_code_without_checks { .. } | - frame_system::Call::kill_prefix { .. }, - ) | RuntimeCall::ParachainSystem(..) | - RuntimeCall::Timestamp(..) | - RuntimeCall::Balances(..) | - RuntimeCall::CollatorSelection( - pallet_collator_selection::Call::set_desired_candidates { .. } | - pallet_collator_selection::Call::set_candidacy_bond { .. } | - pallet_collator_selection::Call::register_as_candidate { .. } | - pallet_collator_selection::Call::leave_intent { .. } | - pallet_collator_selection::Call::set_invulnerables { .. } | - pallet_collator_selection::Call::add_invulnerable { .. } | - pallet_collator_selection::Call::remove_invulnerable { .. }, - ) | RuntimeCall::Session(pallet_session::Call::purge_keys { .. }) | - RuntimeCall::XcmpQueue(..) | - RuntimeCall::DmpQueue(..) | - RuntimeCall::Assets( - pallet_assets::Call::create { .. } | - pallet_assets::Call::force_create { .. } | - pallet_assets::Call::start_destroy { .. } | - pallet_assets::Call::destroy_accounts { .. } | - pallet_assets::Call::destroy_approvals { .. } | - pallet_assets::Call::finish_destroy { .. } | - pallet_assets::Call::block { .. } | - pallet_assets::Call::mint { .. } | - pallet_assets::Call::burn { .. } | - pallet_assets::Call::transfer { .. } | - pallet_assets::Call::transfer_keep_alive { .. } | - pallet_assets::Call::force_transfer { .. } | - pallet_assets::Call::freeze { .. } | - pallet_assets::Call::thaw { .. } | - pallet_assets::Call::freeze_asset { .. } | - pallet_assets::Call::thaw_asset { .. } | - pallet_assets::Call::transfer_ownership { .. } | - pallet_assets::Call::set_team { .. } | - pallet_assets::Call::set_metadata { .. } | - pallet_assets::Call::clear_metadata { .. } | - pallet_assets::Call::force_set_metadata { .. } | - pallet_assets::Call::force_clear_metadata { .. } | - pallet_assets::Call::force_asset_status { .. } | - pallet_assets::Call::approve_transfer { .. } | - pallet_assets::Call::cancel_approval { .. } | - pallet_assets::Call::force_cancel_approval { .. } | - pallet_assets::Call::transfer_approved { .. } | - pallet_assets::Call::touch { .. } | - pallet_assets::Call::touch_other { .. } | - pallet_assets::Call::refund { .. } | - pallet_assets::Call::refund_other { .. }, + frame_system::Call::set_heap_pages { .. } + | frame_system::Call::set_code { .. } + | frame_system::Call::set_code_without_checks { .. } + | frame_system::Call::kill_prefix { .. }, + ) | RuntimeCall::ParachainSystem(..) + | RuntimeCall::Timestamp(..) + | RuntimeCall::Balances(..) + | RuntimeCall::CollatorSelection( + pallet_collator_selection::Call::set_desired_candidates { .. } + | pallet_collator_selection::Call::set_candidacy_bond { .. } + | pallet_collator_selection::Call::register_as_candidate { .. } + | pallet_collator_selection::Call::leave_intent { .. } + | pallet_collator_selection::Call::set_invulnerables { .. } + | pallet_collator_selection::Call::add_invulnerable { .. } + | pallet_collator_selection::Call::remove_invulnerable { .. }, + ) | RuntimeCall::Session(pallet_session::Call::purge_keys { .. }) + | RuntimeCall::XcmpQueue(..) + | RuntimeCall::DmpQueue(..) + | RuntimeCall::Assets( + pallet_assets::Call::create { .. } + | pallet_assets::Call::force_create { .. } + | pallet_assets::Call::start_destroy { .. } + | pallet_assets::Call::destroy_accounts { .. } + | pallet_assets::Call::destroy_approvals { .. } + | pallet_assets::Call::finish_destroy { .. } + | pallet_assets::Call::block { .. } + | pallet_assets::Call::mint { .. } + | pallet_assets::Call::burn { .. } + | pallet_assets::Call::transfer { .. } + | pallet_assets::Call::transfer_keep_alive { .. } + | pallet_assets::Call::force_transfer { .. } + | pallet_assets::Call::freeze { .. } + | pallet_assets::Call::thaw { .. } + | pallet_assets::Call::freeze_asset { .. } + | pallet_assets::Call::thaw_asset { .. } + | pallet_assets::Call::transfer_ownership { .. } + | pallet_assets::Call::set_team { .. } + | pallet_assets::Call::set_metadata { .. } + | pallet_assets::Call::clear_metadata { .. } + | pallet_assets::Call::force_set_metadata { .. } + | pallet_assets::Call::force_clear_metadata { .. } + | pallet_assets::Call::force_asset_status { .. } + | pallet_assets::Call::approve_transfer { .. } + | pallet_assets::Call::cancel_approval { .. } + | pallet_assets::Call::force_cancel_approval { .. } + | pallet_assets::Call::transfer_approved { .. } + | pallet_assets::Call::touch { .. } + | pallet_assets::Call::touch_other { .. } + | pallet_assets::Call::refund { .. } + | pallet_assets::Call::refund_other { .. }, ) | RuntimeCall::ForeignAssets( - pallet_assets::Call::create { .. } | - pallet_assets::Call::force_create { .. } | - pallet_assets::Call::start_destroy { .. } | - pallet_assets::Call::destroy_accounts { .. } | - pallet_assets::Call::destroy_approvals { .. } | - pallet_assets::Call::finish_destroy { .. } | - pallet_assets::Call::block { .. } | - pallet_assets::Call::mint { .. } | - pallet_assets::Call::burn { .. } | - pallet_assets::Call::transfer { .. } | - pallet_assets::Call::transfer_keep_alive { .. } | - pallet_assets::Call::force_transfer { .. } | - pallet_assets::Call::freeze { .. } | - pallet_assets::Call::thaw { .. } | - pallet_assets::Call::freeze_asset { .. } | - pallet_assets::Call::thaw_asset { .. } | - pallet_assets::Call::transfer_ownership { .. } | - pallet_assets::Call::set_team { .. } | - pallet_assets::Call::set_metadata { .. } | - pallet_assets::Call::clear_metadata { .. } | - pallet_assets::Call::force_set_metadata { .. } | - pallet_assets::Call::force_clear_metadata { .. } | - pallet_assets::Call::force_asset_status { .. } | - pallet_assets::Call::approve_transfer { .. } | - pallet_assets::Call::cancel_approval { .. } | - pallet_assets::Call::force_cancel_approval { .. } | - pallet_assets::Call::transfer_approved { .. } | - pallet_assets::Call::touch { .. } | - pallet_assets::Call::touch_other { .. } | - pallet_assets::Call::refund { .. } | - pallet_assets::Call::refund_other { .. }, + pallet_assets::Call::create { .. } + | pallet_assets::Call::force_create { .. } + | pallet_assets::Call::start_destroy { .. } + | pallet_assets::Call::destroy_accounts { .. } + | pallet_assets::Call::destroy_approvals { .. } + | pallet_assets::Call::finish_destroy { .. } + | pallet_assets::Call::block { .. } + | pallet_assets::Call::mint { .. } + | pallet_assets::Call::burn { .. } + | pallet_assets::Call::transfer { .. } + | pallet_assets::Call::transfer_keep_alive { .. } + | pallet_assets::Call::force_transfer { .. } + | pallet_assets::Call::freeze { .. } + | pallet_assets::Call::thaw { .. } + | pallet_assets::Call::freeze_asset { .. } + | pallet_assets::Call::thaw_asset { .. } + | pallet_assets::Call::transfer_ownership { .. } + | pallet_assets::Call::set_team { .. } + | pallet_assets::Call::set_metadata { .. } + | pallet_assets::Call::clear_metadata { .. } + | pallet_assets::Call::force_set_metadata { .. } + | pallet_assets::Call::force_clear_metadata { .. } + | pallet_assets::Call::force_asset_status { .. } + | pallet_assets::Call::approve_transfer { .. } + | pallet_assets::Call::cancel_approval { .. } + | pallet_assets::Call::force_cancel_approval { .. } + | pallet_assets::Call::transfer_approved { .. } + | pallet_assets::Call::touch { .. } + | pallet_assets::Call::touch_other { .. } + | pallet_assets::Call::refund { .. } + | pallet_assets::Call::refund_other { .. }, ) | RuntimeCall::PoolAssets( - pallet_assets::Call::force_create { .. } | - pallet_assets::Call::block { .. } | - pallet_assets::Call::burn { .. } | - pallet_assets::Call::transfer { .. } | - pallet_assets::Call::transfer_keep_alive { .. } | - pallet_assets::Call::force_transfer { .. } | - pallet_assets::Call::freeze { .. } | - pallet_assets::Call::thaw { .. } | - pallet_assets::Call::freeze_asset { .. } | - pallet_assets::Call::thaw_asset { .. } | - pallet_assets::Call::transfer_ownership { .. } | - pallet_assets::Call::set_team { .. } | - pallet_assets::Call::set_metadata { .. } | - pallet_assets::Call::clear_metadata { .. } | - pallet_assets::Call::force_set_metadata { .. } | - pallet_assets::Call::force_clear_metadata { .. } | - pallet_assets::Call::force_asset_status { .. } | - pallet_assets::Call::approve_transfer { .. } | - pallet_assets::Call::cancel_approval { .. } | - pallet_assets::Call::force_cancel_approval { .. } | - pallet_assets::Call::transfer_approved { .. } | - pallet_assets::Call::touch { .. } | - pallet_assets::Call::touch_other { .. } | - pallet_assets::Call::refund { .. } | - pallet_assets::Call::refund_other { .. }, + pallet_assets::Call::force_create { .. } + | pallet_assets::Call::block { .. } + | pallet_assets::Call::burn { .. } + | pallet_assets::Call::transfer { .. } + | pallet_assets::Call::transfer_keep_alive { .. } + | pallet_assets::Call::force_transfer { .. } + | pallet_assets::Call::freeze { .. } + | pallet_assets::Call::thaw { .. } + | pallet_assets::Call::freeze_asset { .. } + | pallet_assets::Call::thaw_asset { .. } + | pallet_assets::Call::transfer_ownership { .. } + | pallet_assets::Call::set_team { .. } + | pallet_assets::Call::set_metadata { .. } + | pallet_assets::Call::clear_metadata { .. } + | pallet_assets::Call::force_set_metadata { .. } + | pallet_assets::Call::force_clear_metadata { .. } + | pallet_assets::Call::force_asset_status { .. } + | pallet_assets::Call::approve_transfer { .. } + | pallet_assets::Call::cancel_approval { .. } + | pallet_assets::Call::force_cancel_approval { .. } + | pallet_assets::Call::transfer_approved { .. } + | pallet_assets::Call::touch { .. } + | pallet_assets::Call::touch_other { .. } + | pallet_assets::Call::refund { .. } + | pallet_assets::Call::refund_other { .. }, ) | RuntimeCall::AssetConversion( - pallet_asset_conversion::Call::create_pool { .. } | - pallet_asset_conversion::Call::add_liquidity { .. } | - pallet_asset_conversion::Call::remove_liquidity { .. } | - pallet_asset_conversion::Call::swap_tokens_for_exact_tokens { .. } | - pallet_asset_conversion::Call::swap_exact_tokens_for_tokens { .. }, + pallet_asset_conversion::Call::create_pool { .. } + | pallet_asset_conversion::Call::add_liquidity { .. } + | pallet_asset_conversion::Call::remove_liquidity { .. } + | pallet_asset_conversion::Call::swap_tokens_for_exact_tokens { .. } + | pallet_asset_conversion::Call::swap_exact_tokens_for_tokens { .. }, ) | RuntimeCall::NftFractionalization( - pallet_nft_fractionalization::Call::fractionalize { .. } | - pallet_nft_fractionalization::Call::unify { .. }, + pallet_nft_fractionalization::Call::fractionalize { .. } + | pallet_nft_fractionalization::Call::unify { .. }, ) | RuntimeCall::Nfts( - pallet_nfts::Call::create { .. } | - pallet_nfts::Call::force_create { .. } | - pallet_nfts::Call::destroy { .. } | - pallet_nfts::Call::mint { .. } | - pallet_nfts::Call::force_mint { .. } | - pallet_nfts::Call::burn { .. } | - pallet_nfts::Call::transfer { .. } | - pallet_nfts::Call::lock_item_transfer { .. } | - pallet_nfts::Call::unlock_item_transfer { .. } | - pallet_nfts::Call::lock_collection { .. } | - pallet_nfts::Call::transfer_ownership { .. } | - pallet_nfts::Call::set_team { .. } | - pallet_nfts::Call::force_collection_owner { .. } | - pallet_nfts::Call::force_collection_config { .. } | - pallet_nfts::Call::approve_transfer { .. } | - pallet_nfts::Call::cancel_approval { .. } | - pallet_nfts::Call::clear_all_transfer_approvals { .. } | - pallet_nfts::Call::lock_item_properties { .. } | - pallet_nfts::Call::set_attribute { .. } | - pallet_nfts::Call::force_set_attribute { .. } | - pallet_nfts::Call::clear_attribute { .. } | - pallet_nfts::Call::approve_item_attributes { .. } | - pallet_nfts::Call::cancel_item_attributes_approval { .. } | - pallet_nfts::Call::set_metadata { .. } | - pallet_nfts::Call::clear_metadata { .. } | - pallet_nfts::Call::set_collection_metadata { .. } | - pallet_nfts::Call::clear_collection_metadata { .. } | - pallet_nfts::Call::set_accept_ownership { .. } | - pallet_nfts::Call::set_collection_max_supply { .. } | - pallet_nfts::Call::update_mint_settings { .. } | - pallet_nfts::Call::set_price { .. } | - pallet_nfts::Call::buy_item { .. } | - pallet_nfts::Call::pay_tips { .. } | - pallet_nfts::Call::create_swap { .. } | - pallet_nfts::Call::cancel_swap { .. } | - pallet_nfts::Call::claim_swap { .. }, + pallet_nfts::Call::create { .. } + | pallet_nfts::Call::force_create { .. } + | pallet_nfts::Call::destroy { .. } + | pallet_nfts::Call::mint { .. } + | pallet_nfts::Call::force_mint { .. } + | pallet_nfts::Call::burn { .. } + | pallet_nfts::Call::transfer { .. } + | pallet_nfts::Call::lock_item_transfer { .. } + | pallet_nfts::Call::unlock_item_transfer { .. } + | pallet_nfts::Call::lock_collection { .. } + | pallet_nfts::Call::transfer_ownership { .. } + | pallet_nfts::Call::set_team { .. } + | pallet_nfts::Call::force_collection_owner { .. } + | pallet_nfts::Call::force_collection_config { .. } + | pallet_nfts::Call::approve_transfer { .. } + | pallet_nfts::Call::cancel_approval { .. } + | pallet_nfts::Call::clear_all_transfer_approvals { .. } + | pallet_nfts::Call::lock_item_properties { .. } + | pallet_nfts::Call::set_attribute { .. } + | pallet_nfts::Call::force_set_attribute { .. } + | pallet_nfts::Call::clear_attribute { .. } + | pallet_nfts::Call::approve_item_attributes { .. } + | pallet_nfts::Call::cancel_item_attributes_approval { .. } + | pallet_nfts::Call::set_metadata { .. } + | pallet_nfts::Call::clear_metadata { .. } + | pallet_nfts::Call::set_collection_metadata { .. } + | pallet_nfts::Call::clear_collection_metadata { .. } + | pallet_nfts::Call::set_accept_ownership { .. } + | pallet_nfts::Call::set_collection_max_supply { .. } + | pallet_nfts::Call::update_mint_settings { .. } + | pallet_nfts::Call::set_price { .. } + | pallet_nfts::Call::buy_item { .. } + | pallet_nfts::Call::pay_tips { .. } + | pallet_nfts::Call::create_swap { .. } + | pallet_nfts::Call::cancel_swap { .. } + | pallet_nfts::Call::claim_swap { .. }, ) | RuntimeCall::Uniques( - pallet_uniques::Call::create { .. } | - pallet_uniques::Call::force_create { .. } | - pallet_uniques::Call::destroy { .. } | - pallet_uniques::Call::mint { .. } | - pallet_uniques::Call::burn { .. } | - pallet_uniques::Call::transfer { .. } | - pallet_uniques::Call::freeze { .. } | - pallet_uniques::Call::thaw { .. } | - pallet_uniques::Call::freeze_collection { .. } | - pallet_uniques::Call::thaw_collection { .. } | - pallet_uniques::Call::transfer_ownership { .. } | - pallet_uniques::Call::set_team { .. } | - pallet_uniques::Call::approve_transfer { .. } | - pallet_uniques::Call::cancel_approval { .. } | - pallet_uniques::Call::force_item_status { .. } | - pallet_uniques::Call::set_attribute { .. } | - pallet_uniques::Call::clear_attribute { .. } | - pallet_uniques::Call::set_metadata { .. } | - pallet_uniques::Call::clear_metadata { .. } | - pallet_uniques::Call::set_collection_metadata { .. } | - pallet_uniques::Call::clear_collection_metadata { .. } | - pallet_uniques::Call::set_accept_ownership { .. } | - pallet_uniques::Call::set_collection_max_supply { .. } | - pallet_uniques::Call::set_price { .. } | - pallet_uniques::Call::buy_item { .. } + pallet_uniques::Call::create { .. } + | pallet_uniques::Call::force_create { .. } + | pallet_uniques::Call::destroy { .. } + | pallet_uniques::Call::mint { .. } + | pallet_uniques::Call::burn { .. } + | pallet_uniques::Call::transfer { .. } + | pallet_uniques::Call::freeze { .. } + | pallet_uniques::Call::thaw { .. } + | pallet_uniques::Call::freeze_collection { .. } + | pallet_uniques::Call::thaw_collection { .. } + | pallet_uniques::Call::transfer_ownership { .. } + | pallet_uniques::Call::set_team { .. } + | pallet_uniques::Call::approve_transfer { .. } + | pallet_uniques::Call::cancel_approval { .. } + | pallet_uniques::Call::force_item_status { .. } + | pallet_uniques::Call::set_attribute { .. } + | pallet_uniques::Call::clear_attribute { .. } + | pallet_uniques::Call::set_metadata { .. } + | pallet_uniques::Call::clear_metadata { .. } + | pallet_uniques::Call::set_collection_metadata { .. } + | pallet_uniques::Call::clear_collection_metadata { .. } + | pallet_uniques::Call::set_accept_ownership { .. } + | pallet_uniques::Call::set_collection_max_supply { .. } + | pallet_uniques::Call::set_price { .. } + | pallet_uniques::Call::buy_item { .. } ) | RuntimeCall::ToPolkadotXcmRouter( pallet_xcm_bridge_hub_router::Call::report_bridge_status { .. } ) @@ -525,6 +534,20 @@ impl xcm_executor::Config for XcmConfig { >; type Trader = ( UsingComponents>, + // This trader allows to pay with any assets exchangeable to DOT with + // [`AssetConversion`]. + cumulus_primitives_utility::SwapFirstAssetTrader< + KsmLocationV3, + AssetConversion, + WeightToFee, + NativeAndAssets, + ( + TrustBackedAssetsAsLocation, + ForeignAssetsConvertedConcreteId, + ), + ResolveAssetTo, + AccountId, + >, // This trader allows to pay with `is_sufficient=true` "Trust Backed" assets from dedicated // `pallet_assets` instance - `Assets`. cumulus_primitives_utility::TakeFirstAssetTrader< diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs index 9ab98e6972..11359a2a3b 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs @@ -853,6 +853,15 @@ pub type LocalAndForeignAssets = fungibles::UnionOf< AccountId, >; +/// Union fungibles implementation for [`LocalAndForeignAssets`] and `Balances`. +pub type NativeAndAssets = fungible::UnionOf< + Balances, + LocalAndForeignAssets, + TargetFromLeft, + xcm::v3::Location, + AccountId, +>; + parameter_types! { pub const AssetConversionPalletId: PalletId = PalletId(*b"py/ascon"); // TODO any fee? @@ -864,13 +873,7 @@ impl pallet_asset_conversion::Config for Runtime { type Balance = Balance; type HigherPrecisionBalance = sp_core::U256; type AssetKind = xcm::v3::Location; - type Assets = fungible::UnionOf< - Balances, - LocalAndForeignAssets, - TargetFromLeft, - Self::AssetKind, - Self::AccountId, - >; + type Assets = NativeAndAssets; type PoolId = (Self::AssetKind, Self::AssetKind); type PoolLocator = impls::pool::WithFirstAsset< DotLocationV3, diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/xcm_config.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/xcm_config.rs index 7bd3c382f9..6b1b96927f 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/src/xcm_config.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/xcm_config.rs @@ -14,16 +14,22 @@ // limitations under the License. use super::{ - AccountId, AllPalletsWithSystem, Assets, Authorship, Balance, Balances, ForeignAssets, - ParachainInfo, ParachainSystem, PolkadotXcm, PoolAssets, PriceForParentDelivery, Runtime, - RuntimeCall, RuntimeEvent, RuntimeOrigin, ToKusamaXcmRouter, TrustBackedAssetsInstance, - WeightToFee, XcmpQueue, + AccountId, AllPalletsWithSystem, AssetConversion, Assets, Authorship, Balance, Balances, + CollatorSelection, ForeignAssets, NativeAndAssets, ParachainInfo, ParachainSystem, PolkadotXcm, + PoolAssets, PriceForParentDelivery, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, + ToKusamaXcmRouter, TrustBackedAssetsInstance, WeightToFee, XcmpQueue, }; use crate::ForeignAssetsInstance; -use assets_common::matching::{FromSiblingParachain, IsForeignConcreteAsset}; +use assets_common::{ + matching::{FromSiblingParachain, IsForeignConcreteAsset}, + TrustBackedAssetsAsLocation, +}; use frame_support::{ parameter_types, - traits::{ConstU32, Contains, Equals, Everything, Nothing, PalletInfoAccess}, + traits::{ + tokens::imbalance::ResolveAssetTo, ConstU32, Contains, Equals, Everything, Nothing, + PalletInfoAccess, + }, }; use frame_system::EnsureRoot; use pallet_xcm::XcmPassthrough; @@ -72,6 +78,7 @@ parameter_types! { pub TreasuryAccount: AccountId = TREASURY_PALLET_ID.into_account_truncating(); pub PoolAssetsPalletLocation: Location = PalletInstance(::index() as u8).into(); + pub StakingPot: AccountId = CollatorSelection::account_id(); } /// Type for specifying how a `Location` can be converted into an `AccountId`. This is used @@ -505,6 +512,20 @@ impl xcm_executor::Config for XcmConfig { >; type Trader = ( UsingComponents>, + // This trader allows to pay with any assets exchangeable to DOT with + // [`AssetConversion`]. + cumulus_primitives_utility::SwapFirstAssetTrader< + DotLocationV3, + AssetConversion, + WeightToFee, + NativeAndAssets, + ( + TrustBackedAssetsAsLocation, + ForeignAssetsConvertedConcreteId, + ), + ResolveAssetTo, + AccountId, + >, // This trader allows to pay with `is_sufficient=true` "Trust Backed" assets from dedicated // `pallet_assets` instance - `Assets`. cumulus_primitives_utility::TakeFirstAssetTrader< From 2ef13fd31b8bf563afdce060a867e0b0ebb057c4 Mon Sep 17 00:00:00 2001 From: muharem Date: Mon, 26 Feb 2024 10:21:00 +0100 Subject: [PATCH 05/25] weight trader tests --- .../asset-hub-kusama/tests/weight_trader.rs | 317 ++++++++++++++++++ .../asset-hub-polkadot/tests/weight_trader.rs | 317 ++++++++++++++++++ 2 files changed, 634 insertions(+) create mode 100644 system-parachains/asset-hubs/asset-hub-kusama/tests/weight_trader.rs create mode 100644 system-parachains/asset-hubs/asset-hub-polkadot/tests/weight_trader.rs diff --git a/system-parachains/asset-hubs/asset-hub-kusama/tests/weight_trader.rs b/system-parachains/asset-hubs/asset-hub-kusama/tests/weight_trader.rs new file mode 100644 index 0000000000..c4b0d66556 --- /dev/null +++ b/system-parachains/asset-hubs/asset-hub-kusama/tests/weight_trader.rs @@ -0,0 +1,317 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Tests for `WeighTrader` type of XCM Executor. + +use asset_hub_kusama_runtime::{ + xcm_config::{ + KsmLocation, KsmLocationV3, StakingPot, TrustBackedAssetsPalletLocationV3, XcmConfig, + }, + AllPalletsWithoutSystem, AssetConversion, Assets, Balances, ForeignAssets, Runtime, + SessionKeys, +}; +use asset_test_utils::ExtBuilder; +use assets_common::AssetIdForTrustBackedAssetsConvert; +use frame_support::{ + assert_ok, + traits::{ + fungible::{Inspect, Mutate}, + fungibles::{Create, Inspect as FungiblesInspect, Mutate as FungiblesMutate}, + }, + weights::{Weight, WeightToFee as WeightToFeeT}, +}; +use parachains_common::{AccountId, AuraId}; +use sp_runtime::traits::MaybeEquivalence; +use system_parachains_constants::kusama::{currency::*, fee::WeightToFee}; +use xcm::latest::prelude::*; +use xcm_executor::traits::WeightTrader; + +const ALICE: [u8; 32] = [1u8; 32]; +const SOME_ASSET_ADMIN: [u8; 32] = [5u8; 32]; + +type RuntimeHelper = asset_test_utils::RuntimeHelper; + +#[test] +fn test_buy_and_refund_weight_with_native() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + let bob: AccountId = SOME_ASSET_ADMIN.into(); + let staking_pot = StakingPot::get(); + let native_location = KsmLocation::get(); + let initial_balance = 200 * UNITS; + + assert_ok!(Balances::mint_into(&bob, initial_balance)); + assert_ok!(Balances::mint_into(&staking_pot, initial_balance)); + + // keep initial total issuance to assert later. + let total_issuance = Balances::total_issuance(); + + // prepare input to buy weight. + let weight = Weight::from_parts(4_000_000_000, 0); + let fee = WeightToFee::weight_to_fee(&weight); + let extra_amount = 100; + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + let payment: Asset = (native_location.clone(), fee + extra_amount).into(); + + // init trader and buy weight. + let mut trader = ::Trader::new(); + let unused_asset = + trader.buy_weight(weight, payment.into(), &ctx).expect("Expected Ok"); + + // assert. + let unused_amount = + unused_asset.fungible.get(&native_location.clone().into()).map_or(0, |a| *a); + assert_eq!(unused_amount, extra_amount); + assert_eq!(Balances::total_issuance(), total_issuance); + + // prepare input to refund weight. + let refund_weight = Weight::from_parts(1_000_000_000, 0); + let refund = WeightToFee::weight_to_fee(&refund_weight); + + // refund. + let actual_refund = trader.refund_weight(refund_weight, &ctx).unwrap(); + assert_eq!(actual_refund, (native_location, refund).into()); + + // assert. + assert_eq!(Balances::balance(&staking_pot), initial_balance); + // only after `trader` is dropped we expect the fee to be resolved into the treasury + // account. + drop(trader); + assert_eq!(Balances::balance(&staking_pot), initial_balance + fee - refund); + assert_eq!(Balances::total_issuance(), total_issuance + fee - refund); + }) +} + +#[test] +fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + let bob: AccountId = SOME_ASSET_ADMIN.into(); + let staking_pot = StakingPot::get(); + let asset_1: u32 = 1; + let native_location = KsmLocationV3::get(); + let asset_1_location = AssetIdForTrustBackedAssetsConvert::< + TrustBackedAssetsPalletLocationV3, + >::convert_back(&asset_1) + .unwrap(); + // bob's initial balance for native and `asset1` assets. + let initial_balance = 200 * UNITS; + // liquidity for both arms of (native, asset1) pool. + let pool_liquidity = 100 * UNITS; + + // init asset, balances and pool. + assert_ok!(>::create(asset_1, bob.clone(), true, 10)); + + assert_ok!(Assets::mint_into(asset_1, &bob, initial_balance)); + assert_ok!(Balances::mint_into(&bob, initial_balance)); + assert_ok!(Balances::mint_into(&staking_pot, initial_balance)); + + assert_ok!(AssetConversion::create_pool( + RuntimeHelper::origin_of(bob.clone()), + Box::new(native_location), + Box::new(asset_1_location) + )); + + assert_ok!(AssetConversion::add_liquidity( + RuntimeHelper::origin_of(bob.clone()), + Box::new(native_location), + Box::new(asset_1_location), + pool_liquidity, + pool_liquidity, + 1, + 1, + bob, + )); + + // keep initial total issuance to assert later. + let asset_total_issuance = Assets::total_issuance(asset_1); + let native_total_issuance = Balances::total_issuance(); + + let asset_1_location_latest: Location = asset_1_location.try_into().unwrap(); + + // prepare input to buy weight. + let weight = Weight::from_parts(4_000_000_000, 0); + let fee = WeightToFee::weight_to_fee(&weight); + let asset_fee = + AssetConversion::get_amount_in(&fee, &pool_liquidity, &pool_liquidity).unwrap(); + let extra_amount = 100; + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + let payment: Asset = (asset_1_location_latest.clone(), asset_fee + extra_amount).into(); + + // init trader and buy weight. + let mut trader = ::Trader::new(); + let unused_asset = + trader.buy_weight(weight, payment.into(), &ctx).expect("Expected Ok"); + + // assert. + let unused_amount = unused_asset + .fungible + .get(&asset_1_location_latest.clone().into()) + .map_or(0, |a| *a); + assert_eq!(unused_amount, extra_amount); + assert_eq!(Assets::total_issuance(asset_1), asset_total_issuance + asset_fee); + + // prepare input to refund weight. + let refund_weight = Weight::from_parts(1_000_000_000, 0); + let refund = WeightToFee::weight_to_fee(&refund_weight); + let (reserve1, reserve2) = + AssetConversion::get_reserves(native_location, asset_1_location).unwrap(); + let asset_refund = + AssetConversion::get_amount_out(&refund, &reserve1, &reserve2).unwrap(); + + // refund. + let actual_refund = trader.refund_weight(refund_weight, &ctx).unwrap(); + assert_eq!(actual_refund, (asset_1_location_latest, asset_refund).into()); + + // assert. + assert_eq!(Balances::balance(&staking_pot), initial_balance); + // only after `trader` is dropped we expect the fee to be resolved into the treasury + // account. + drop(trader); + assert_eq!(Balances::balance(&staking_pot), initial_balance + fee - refund); + assert_eq!( + Assets::total_issuance(asset_1), + asset_total_issuance + asset_fee - asset_refund + ); + assert_eq!(Balances::total_issuance(), native_total_issuance); + }) +} + +#[test] +fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + let bob: AccountId = SOME_ASSET_ADMIN.into(); + let staking_pot = StakingPot::get(); + let native_location = KsmLocationV3::get(); + let foreign_location = xcm::v3::Location { + parents: 1, + interior: ( + xcm::v3::Junction::Parachain(1234), + xcm::v3::Junction::GeneralIndex(12345), + ) + .into(), + }; + // bob's initial balance for native and `asset1` assets. + let initial_balance = 200 * UNITS; + // liquidity for both arms of (native, asset1) pool. + let pool_liquidity = 100 * UNITS; + + // init asset, balances and pool. + assert_ok!(>::create( + foreign_location, + bob.clone(), + true, + 10 + )); + + assert_ok!(ForeignAssets::mint_into(foreign_location, &bob, initial_balance)); + assert_ok!(Balances::mint_into(&bob, initial_balance)); + assert_ok!(Balances::mint_into(&staking_pot, initial_balance)); + + assert_ok!(AssetConversion::create_pool( + RuntimeHelper::origin_of(bob.clone()), + Box::new(native_location), + Box::new(foreign_location) + )); + + assert_ok!(AssetConversion::add_liquidity( + RuntimeHelper::origin_of(bob.clone()), + Box::new(native_location), + Box::new(foreign_location), + pool_liquidity, + pool_liquidity, + 1, + 1, + bob, + )); + + // keep initial total issuance to assert later. + let asset_total_issuance = ForeignAssets::total_issuance(foreign_location); + let native_total_issuance = Balances::total_issuance(); + + let foreign_location_latest: Location = foreign_location.try_into().unwrap(); + + // prepare input to buy weight. + let weight = Weight::from_parts(4_000_000_000, 0); + let fee = WeightToFee::weight_to_fee(&weight); + let asset_fee = + AssetConversion::get_amount_in(&fee, &pool_liquidity, &pool_liquidity).unwrap(); + let extra_amount = 100; + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + let payment: Asset = (foreign_location_latest.clone(), asset_fee + extra_amount).into(); + + // init trader and buy weight. + let mut trader = ::Trader::new(); + let unused_asset = + trader.buy_weight(weight, payment.into(), &ctx).expect("Expected Ok"); + + // assert. + let unused_amount = unused_asset + .fungible + .get(&foreign_location_latest.clone().into()) + .map_or(0, |a| *a); + assert_eq!(unused_amount, extra_amount); + assert_eq!( + ForeignAssets::total_issuance(foreign_location), + asset_total_issuance + asset_fee + ); + + // prepare input to refund weight. + let refund_weight = Weight::from_parts(1_000_000_000, 0); + let refund = WeightToFee::weight_to_fee(&refund_weight); + let (reserve1, reserve2) = + AssetConversion::get_reserves(native_location, foreign_location).unwrap(); + let asset_refund = + AssetConversion::get_amount_out(&refund, &reserve1, &reserve2).unwrap(); + + // refund. + let actual_refund = trader.refund_weight(refund_weight, &ctx).unwrap(); + assert_eq!(actual_refund, (foreign_location_latest, asset_refund).into()); + + // assert. + assert_eq!(Balances::balance(&staking_pot), initial_balance); + // only after `trader` is dropped we expect the fee to be resolved into the treasury + // account. + drop(trader); + assert_eq!(Balances::balance(&staking_pot), initial_balance + fee - refund); + assert_eq!( + ForeignAssets::total_issuance(foreign_location), + asset_total_issuance + asset_fee - asset_refund + ); + assert_eq!(Balances::total_issuance(), native_total_issuance); + }) +} diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/tests/weight_trader.rs b/system-parachains/asset-hubs/asset-hub-polkadot/tests/weight_trader.rs new file mode 100644 index 0000000000..19a344f313 --- /dev/null +++ b/system-parachains/asset-hubs/asset-hub-polkadot/tests/weight_trader.rs @@ -0,0 +1,317 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! Tests for `WeighTrader` type of XCM Executor. + +use asset_hub_polkadot_runtime::{ + xcm_config::{ + DotLocation, DotLocationV3, StakingPot, TrustBackedAssetsPalletLocationV3, XcmConfig, + }, + AllPalletsWithoutSystem, AssetConversion, Assets, Balances, ForeignAssets, Runtime, + SessionKeys, +}; +use asset_test_utils::ExtBuilder; +use assets_common::AssetIdForTrustBackedAssetsConvert; +use frame_support::{ + assert_ok, + traits::{ + fungible::{Inspect, Mutate}, + fungibles::{Create, Inspect as FungiblesInspect, Mutate as FungiblesMutate}, + }, + weights::{Weight, WeightToFee as WeightToFeeT}, +}; +use parachains_common::{AccountId, AssetHubPolkadotAuraId as AuraId}; +use sp_runtime::traits::MaybeEquivalence; +use system_parachains_constants::polkadot::{currency::*, fee::WeightToFee}; +use xcm::latest::prelude::*; +use xcm_executor::traits::WeightTrader; + +const ALICE: [u8; 32] = [1u8; 32]; +const SOME_ASSET_ADMIN: [u8; 32] = [5u8; 32]; + +type RuntimeHelper = asset_test_utils::RuntimeHelper; + +#[test] +fn test_buy_and_refund_weight_with_native() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::ed25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + let bob: AccountId = SOME_ASSET_ADMIN.into(); + let staking_pot = StakingPot::get(); + let native_location = DotLocation::get(); + let initial_balance = 200 * UNITS; + + assert_ok!(Balances::mint_into(&bob, initial_balance)); + assert_ok!(Balances::mint_into(&staking_pot, initial_balance)); + + // keep initial total issuance to assert later. + let total_issuance = Balances::total_issuance(); + + // prepare input to buy weight. + let weight = Weight::from_parts(4_000_000_000, 0); + let fee = WeightToFee::weight_to_fee(&weight); + let extra_amount = 100; + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + let payment: Asset = (native_location.clone(), fee + extra_amount).into(); + + // init trader and buy weight. + let mut trader = ::Trader::new(); + let unused_asset = + trader.buy_weight(weight, payment.into(), &ctx).expect("Expected Ok"); + + // assert. + let unused_amount = + unused_asset.fungible.get(&native_location.clone().into()).map_or(0, |a| *a); + assert_eq!(unused_amount, extra_amount); + assert_eq!(Balances::total_issuance(), total_issuance); + + // prepare input to refund weight. + let refund_weight = Weight::from_parts(1_000_000_000, 0); + let refund = WeightToFee::weight_to_fee(&refund_weight); + + // refund. + let actual_refund = trader.refund_weight(refund_weight, &ctx).unwrap(); + assert_eq!(actual_refund, (native_location, refund).into()); + + // assert. + assert_eq!(Balances::balance(&staking_pot), initial_balance); + // only after `trader` is dropped we expect the fee to be resolved into the treasury + // account. + drop(trader); + assert_eq!(Balances::balance(&staking_pot), initial_balance + fee - refund); + assert_eq!(Balances::total_issuance(), total_issuance + fee - refund); + }) +} + +#[test] +fn test_buy_and_refund_weight_with_swap_local_asset_xcm_trader() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::ed25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + let bob: AccountId = SOME_ASSET_ADMIN.into(); + let staking_pot = StakingPot::get(); + let asset_1: u32 = 1; + let native_location = DotLocationV3::get(); + let asset_1_location = AssetIdForTrustBackedAssetsConvert::< + TrustBackedAssetsPalletLocationV3, + >::convert_back(&asset_1) + .unwrap(); + // bob's initial balance for native and `asset1` assets. + let initial_balance = 200 * UNITS; + // liquidity for both arms of (native, asset1) pool. + let pool_liquidity = 100 * UNITS; + + // init asset, balances and pool. + assert_ok!(>::create(asset_1, bob.clone(), true, 10)); + + assert_ok!(Assets::mint_into(asset_1, &bob, initial_balance)); + assert_ok!(Balances::mint_into(&bob, initial_balance)); + assert_ok!(Balances::mint_into(&staking_pot, initial_balance)); + + assert_ok!(AssetConversion::create_pool( + RuntimeHelper::origin_of(bob.clone()), + Box::new(native_location), + Box::new(asset_1_location) + )); + + assert_ok!(AssetConversion::add_liquidity( + RuntimeHelper::origin_of(bob.clone()), + Box::new(native_location), + Box::new(asset_1_location), + pool_liquidity, + pool_liquidity, + 1, + 1, + bob, + )); + + // keep initial total issuance to assert later. + let asset_total_issuance = Assets::total_issuance(asset_1); + let native_total_issuance = Balances::total_issuance(); + + let asset_1_location_latest: Location = asset_1_location.try_into().unwrap(); + + // prepare input to buy weight. + let weight = Weight::from_parts(4_000_000_000, 0); + let fee = WeightToFee::weight_to_fee(&weight); + let asset_fee = + AssetConversion::get_amount_in(&fee, &pool_liquidity, &pool_liquidity).unwrap(); + let extra_amount = 100; + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + let payment: Asset = (asset_1_location_latest.clone(), asset_fee + extra_amount).into(); + + // init trader and buy weight. + let mut trader = ::Trader::new(); + let unused_asset = + trader.buy_weight(weight, payment.into(), &ctx).expect("Expected Ok"); + + // assert. + let unused_amount = unused_asset + .fungible + .get(&asset_1_location_latest.clone().into()) + .map_or(0, |a| *a); + assert_eq!(unused_amount, extra_amount); + assert_eq!(Assets::total_issuance(asset_1), asset_total_issuance + asset_fee); + + // prepare input to refund weight. + let refund_weight = Weight::from_parts(1_000_000_000, 0); + let refund = WeightToFee::weight_to_fee(&refund_weight); + let (reserve1, reserve2) = + AssetConversion::get_reserves(native_location, asset_1_location).unwrap(); + let asset_refund = + AssetConversion::get_amount_out(&refund, &reserve1, &reserve2).unwrap(); + + // refund. + let actual_refund = trader.refund_weight(refund_weight, &ctx).unwrap(); + assert_eq!(actual_refund, (asset_1_location_latest, asset_refund).into()); + + // assert. + assert_eq!(Balances::balance(&staking_pot), initial_balance); + // only after `trader` is dropped we expect the fee to be resolved into the treasury + // account. + drop(trader); + assert_eq!(Balances::balance(&staking_pot), initial_balance + fee - refund); + assert_eq!( + Assets::total_issuance(asset_1), + asset_total_issuance + asset_fee - asset_refund + ); + assert_eq!(Balances::total_issuance(), native_total_issuance); + }) +} + +#[test] +fn test_buy_and_refund_weight_with_swap_foreign_asset_xcm_trader() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::ed25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + let bob: AccountId = SOME_ASSET_ADMIN.into(); + let staking_pot = StakingPot::get(); + let native_location = DotLocationV3::get(); + let foreign_location = xcm::v3::Location { + parents: 1, + interior: ( + xcm::v3::Junction::Parachain(1234), + xcm::v3::Junction::GeneralIndex(12345), + ) + .into(), + }; + // bob's initial balance for native and `asset1` assets. + let initial_balance = 200 * UNITS; + // liquidity for both arms of (native, asset1) pool. + let pool_liquidity = 100 * UNITS; + + // init asset, balances and pool. + assert_ok!(>::create( + foreign_location, + bob.clone(), + true, + 10 + )); + + assert_ok!(ForeignAssets::mint_into(foreign_location, &bob, initial_balance)); + assert_ok!(Balances::mint_into(&bob, initial_balance)); + assert_ok!(Balances::mint_into(&staking_pot, initial_balance)); + + assert_ok!(AssetConversion::create_pool( + RuntimeHelper::origin_of(bob.clone()), + Box::new(native_location), + Box::new(foreign_location) + )); + + assert_ok!(AssetConversion::add_liquidity( + RuntimeHelper::origin_of(bob.clone()), + Box::new(native_location), + Box::new(foreign_location), + pool_liquidity, + pool_liquidity, + 1, + 1, + bob, + )); + + // keep initial total issuance to assert later. + let asset_total_issuance = ForeignAssets::total_issuance(foreign_location); + let native_total_issuance = Balances::total_issuance(); + + let foreign_location_latest: Location = foreign_location.try_into().unwrap(); + + // prepare input to buy weight. + let weight = Weight::from_parts(4_000_000_000, 0); + let fee = WeightToFee::weight_to_fee(&weight); + let asset_fee = + AssetConversion::get_amount_in(&fee, &pool_liquidity, &pool_liquidity).unwrap(); + let extra_amount = 100; + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + let payment: Asset = (foreign_location_latest.clone(), asset_fee + extra_amount).into(); + + // init trader and buy weight. + let mut trader = ::Trader::new(); + let unused_asset = + trader.buy_weight(weight, payment.into(), &ctx).expect("Expected Ok"); + + // assert. + let unused_amount = unused_asset + .fungible + .get(&foreign_location_latest.clone().into()) + .map_or(0, |a| *a); + assert_eq!(unused_amount, extra_amount); + assert_eq!( + ForeignAssets::total_issuance(foreign_location), + asset_total_issuance + asset_fee + ); + + // prepare input to refund weight. + let refund_weight = Weight::from_parts(1_000_000_000, 0); + let refund = WeightToFee::weight_to_fee(&refund_weight); + let (reserve1, reserve2) = + AssetConversion::get_reserves(native_location, foreign_location).unwrap(); + let asset_refund = + AssetConversion::get_amount_out(&refund, &reserve1, &reserve2).unwrap(); + + // refund. + let actual_refund = trader.refund_weight(refund_weight, &ctx).unwrap(); + assert_eq!(actual_refund, (foreign_location_latest, asset_refund).into()); + + // assert. + assert_eq!(Balances::balance(&staking_pot), initial_balance); + // only after `trader` is dropped we expect the fee to be resolved into the treasury + // account. + drop(trader); + assert_eq!(Balances::balance(&staking_pot), initial_balance + fee - refund); + assert_eq!( + ForeignAssets::total_issuance(foreign_location), + asset_total_issuance + asset_fee - asset_refund + ); + assert_eq!(Balances::total_issuance(), native_total_issuance); + }) +} From 400546ec26bb70adaba66fdb59435d41b4dfea2e Mon Sep 17 00:00:00 2001 From: muharem Date: Tue, 5 Mar 2024 15:18:48 +0100 Subject: [PATCH 06/25] move weight trader tests into separate mod --- .../asset-hub-kusama/tests/tests.rs | 352 +---------------- .../asset-hub-kusama/tests/weight_trader.rs | 348 +++++++++++++++++ .../asset-hub-polkadot/tests/tests.rs | 364 +----------------- .../asset-hub-polkadot/tests/weight_trader.rs | 358 +++++++++++++++++ 4 files changed, 714 insertions(+), 708 deletions(-) diff --git a/system-parachains/asset-hubs/asset-hub-kusama/tests/tests.rs b/system-parachains/asset-hubs/asset-hub-kusama/tests/tests.rs index 602b8e23be..80a0051282 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/tests/tests.rs +++ b/system-parachains/asset-hubs/asset-hub-kusama/tests/tests.rs @@ -20,9 +20,8 @@ use asset_hub_kusama_runtime::{ xcm_config::{ bridging::{self, XcmBridgeHubRouterFeeAssetId}, - AssetFeeAsExistentialDepositMultiplierFeeCharger, CheckingAccount, - ForeignCreatorsSovereignAccountOf, KsmLocation, LocationToAccountId, TreasuryAccount, - TrustBackedAssetsPalletLocation, XcmConfig, + CheckingAccount, ForeignCreatorsSovereignAccountOf, KsmLocation, LocationToAccountId, + TreasuryAccount, TrustBackedAssetsPalletLocation, XcmConfig, }, AllPalletsWithoutSystem, AssetDeposit, Assets, Balances, ExistentialDeposit, ForeignAssets, ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, ParachainSystem, @@ -33,12 +32,7 @@ use asset_test_utils::{ test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys, ExtBuilder, }; use codec::{Decode, Encode}; -use cumulus_primitives_utility::ChargeWeightInFungibles; -use frame_support::{ - assert_noop, assert_ok, - traits::fungibles::InspectEnumerable, - weights::{Weight, WeightToFee as WeightToFeeT}, -}; +use frame_support::{assert_ok, traits::fungibles::InspectEnumerable}; use parachains_common::{AccountId, AssetIdForTrustBackedAssets, AuraId, Balance}; use parachains_runtimes_test_utils::SlotDurations; use sp_consensus_aura::SlotDuration; @@ -48,7 +42,7 @@ use system_parachains_constants::kusama::{ }; use xcm::latest::prelude::{Assets as XcmAssets, *}; use xcm_builder::V4V3LocationConverter; -use xcm_executor::traits::{ConvertLocation, JustTry, WeightTrader}; +use xcm_executor::traits::{ConvertLocation, JustTry}; const ALICE: [u8; 32] = [1u8; 32]; const SOME_ASSET_ADMIN: [u8; 32] = [5u8; 32]; @@ -94,344 +88,6 @@ fn test_ed_is_one_hundredth_of_relay() { }); } -#[test] -fn test_asset_xcm_trader() { - ExtBuilder::::default() - .with_collators(vec![AccountId::from(ALICE)]) - .with_session_keys(vec![( - AccountId::from(ALICE), - AccountId::from(ALICE), - SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, - )]) - .build() - .execute_with(|| { - // We need root origin to create a sufficient asset - let minimum_asset_balance = 3333333_u128; - let local_asset_id = 1; - assert_ok!(Assets::force_create( - RuntimeHelper::root_origin(), - local_asset_id.into(), - AccountId::from(ALICE).into(), - true, - minimum_asset_balance - )); - - // We first mint enough asset for the account to exist for assets - assert_ok!(Assets::mint( - RuntimeHelper::origin_of(AccountId::from(ALICE)), - local_asset_id.into(), - AccountId::from(ALICE).into(), - minimum_asset_balance - )); - - // get asset id as location - let asset_location = - AssetIdForTrustBackedAssetsConvertLatest::convert_back(&local_asset_id).unwrap(); - - // Set Alice as block author, who will receive fees - RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); - - // We are going to buy 4e9 weight - let bought = Weight::from_parts(4_000_000_000u64, 0); - - // Lets calculate amount needed - let asset_amount_needed = - AssetFeeAsExistentialDepositMultiplierFeeCharger::charge_weight_in_fungibles( - local_asset_id, - bought, - ) - .expect("failed to compute"); - - // Lets pay with: asset_amount_needed + asset_amount_extra - let asset_amount_extra = 100_u128; - let asset: Asset = - (asset_location.clone(), asset_amount_needed + asset_amount_extra).into(); - - let mut trader = ::Trader::new(); - let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - - // Lets buy_weight and make sure buy_weight does not return an error - let unused_assets = trader.buy_weight(bought, asset.into(), &ctx).expect("Expected Ok"); - // Check whether a correct amount of unused assets is returned - assert_ok!(unused_assets.ensure_contains(&(asset_location, asset_amount_extra).into())); - - // Drop trader - drop(trader); - - // Make sure author(Alice) has received the amount - assert_eq!( - Assets::balance(local_asset_id, AccountId::from(ALICE)), - minimum_asset_balance + asset_amount_needed - ); - - // We also need to ensure the total supply increased - assert_eq!( - Assets::total_supply(local_asset_id), - minimum_asset_balance + asset_amount_needed - ); - }); -} - -#[test] -fn test_asset_xcm_trader_with_refund() { - ExtBuilder::::default() - .with_collators(vec![AccountId::from(ALICE)]) - .with_session_keys(vec![( - AccountId::from(ALICE), - AccountId::from(ALICE), - SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, - )]) - .build() - .execute_with(|| { - // We need root origin to create a sufficient asset - // We set existential deposit to be identical to the one for Balances first - assert_ok!(Assets::force_create( - RuntimeHelper::root_origin(), - 1.into(), - AccountId::from(ALICE).into(), - true, - ExistentialDeposit::get() - )); - - // We first mint enough asset for the account to exist for assets - assert_ok!(Assets::mint( - RuntimeHelper::origin_of(AccountId::from(ALICE)), - 1.into(), - AccountId::from(ALICE).into(), - ExistentialDeposit::get() - )); - - let mut trader = ::Trader::new(); - let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - - // Set Alice as block author, who will receive fees - RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); - - // We are going to buy 4e9 weight - let bought = Weight::from_parts(4_000_000_000u64, 0); - - let asset_location = - AssetIdForTrustBackedAssetsConvertLatest::convert_back(&1).unwrap(); - - // lets calculate amount needed - let amount_bought = WeightToFee::weight_to_fee(&bought); - - let asset: Asset = (asset_location.clone(), amount_bought).into(); - - // Make sure buy_weight does not return an error - assert_ok!(trader.buy_weight(bought, asset.clone().into(), &ctx)); - - // Make sure again buy_weight does return an error - // This assert relies on the fact, that we use `TakeFirstAssetTrader` in `WeightTrader` - // tuple chain, which cannot be called twice - assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); - - // We actually use half of the weight - let weight_used = bought / 2; - - // Make sure refurnd works. - let amount_refunded = WeightToFee::weight_to_fee(&(bought - weight_used)); - - assert_eq!( - trader.refund_weight(bought - weight_used, &ctx), - Some((asset_location, amount_refunded).into()) - ); - - // Drop trader - drop(trader); - - // We only should have paid for half of the bought weight - let fees_paid = WeightToFee::weight_to_fee(&weight_used); - - assert_eq!( - Assets::balance(1, AccountId::from(ALICE)), - ExistentialDeposit::get() + fees_paid - ); - - // We also need to ensure the total supply increased - assert_eq!(Assets::total_supply(1), ExistentialDeposit::get() + fees_paid); - }); -} - -#[test] -fn test_asset_xcm_trader_refund_not_possible_since_amount_less_than_ed() { - ExtBuilder::::default() - .with_collators(vec![AccountId::from(ALICE)]) - .with_session_keys(vec![( - AccountId::from(ALICE), - AccountId::from(ALICE), - SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, - )]) - .build() - .execute_with(|| { - // We need root origin to create a sufficient asset - // We set existential deposit to be identical to the one for Balances first - assert_ok!(Assets::force_create( - RuntimeHelper::root_origin(), - 1.into(), - AccountId::from(ALICE).into(), - true, - ExistentialDeposit::get() - )); - - let mut trader = ::Trader::new(); - let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - - // Set Alice as block author, who will receive fees - RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); - - // We are going to buy small amount - let bought = Weight::from_parts(50_000_000u64, 0); - - let asset_location = - AssetIdForTrustBackedAssetsConvertLatest::convert_back(&1).unwrap(); - - let amount_bought = WeightToFee::weight_to_fee(&bought); - - assert!( - amount_bought < ExistentialDeposit::get(), - "we are testing what happens when the amount does not exceed ED" - ); - - let asset: Asset = (asset_location, amount_bought).into(); - - // Buy weight should return an error - assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); - - // not credited since the ED is higher than this value - assert_eq!(Assets::balance(1, AccountId::from(ALICE)), 0); - - // We also need to ensure the total supply did not increase - assert_eq!(Assets::total_supply(1), 0); - }); -} - -#[test] -fn test_that_buying_ed_refund_does_not_refund() { - ExtBuilder::::default() - .with_collators(vec![AccountId::from(ALICE)]) - .with_session_keys(vec![( - AccountId::from(ALICE), - AccountId::from(ALICE), - SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, - )]) - .build() - .execute_with(|| { - // We need root origin to create a sufficient asset - // We set existential deposit to be identical to the one for Balances first - assert_ok!(Assets::force_create( - RuntimeHelper::root_origin(), - 1.into(), - AccountId::from(ALICE).into(), - true, - ExistentialDeposit::get() - )); - - let mut trader = ::Trader::new(); - let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - - // Set Alice as block author, who will receive fees - RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); - - // We are gonna buy ED - let bought = Weight::from_parts(ExistentialDeposit::get().try_into().unwrap(), 0); - - let asset_location = - AssetIdForTrustBackedAssetsConvertLatest::convert_back(&1).unwrap(); - - let amount_bought = WeightToFee::weight_to_fee(&bought); - - assert!( - amount_bought < ExistentialDeposit::get(), - "we are testing what happens when the amount does not exceed ED" - ); - - // We know we will have to buy at least ED, so lets make sure first it will - // fail with a payment of less than ED - let asset: Asset = (asset_location.clone(), amount_bought).into(); - assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); - - // Now lets buy ED at least - let asset: Asset = (asset_location, ExistentialDeposit::get()).into(); - - // Buy weight should work - assert_ok!(trader.buy_weight(bought, asset.into(), &ctx)); - - // Should return None. We have a specific check making sure we dont go below ED for - // drop payment - assert_eq!(trader.refund_weight(bought, &ctx), None); - - // Drop trader - drop(trader); - - // Make sure author(Alice) has received the amount - assert_eq!(Assets::balance(1, AccountId::from(ALICE)), ExistentialDeposit::get()); - - // We also need to ensure the total supply increased - assert_eq!(Assets::total_supply(1), ExistentialDeposit::get()); - }); -} - -#[test] -fn test_asset_xcm_trader_not_possible_for_non_sufficient_assets() { - ExtBuilder::::default() - .with_collators(vec![AccountId::from(ALICE)]) - .with_session_keys(vec![( - AccountId::from(ALICE), - AccountId::from(ALICE), - SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, - )]) - .build() - .execute_with(|| { - // Create a non-sufficient asset with specific existential deposit - let minimum_asset_balance = 1_000_000_u128; - assert_ok!(Assets::force_create( - RuntimeHelper::root_origin(), - 1.into(), - AccountId::from(ALICE).into(), - false, - minimum_asset_balance - )); - - // We first mint enough asset for the account to exist for assets - assert_ok!(Assets::mint( - RuntimeHelper::origin_of(AccountId::from(ALICE)), - 1.into(), - AccountId::from(ALICE).into(), - minimum_asset_balance - )); - - let mut trader = ::Trader::new(); - let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - - // Set Alice as block author, who will receive fees - RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); - - // We are going to buy 4e9 weight - let bought = Weight::from_parts(4_000_000_000u64, 0); - - // lets calculate amount needed - let asset_amount_needed = WeightToFee::weight_to_fee(&bought); - - let asset_location = - AssetIdForTrustBackedAssetsConvertLatest::convert_back(&1).unwrap(); - - let asset: Asset = (asset_location, asset_amount_needed).into(); - - // Make sure again buy_weight does return an error - assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); - - // Drop trader - drop(trader); - - // Make sure author(Alice) has NOT received the amount - assert_eq!(Assets::balance(1, AccountId::from(ALICE)), minimum_asset_balance); - - // We also need to ensure the total supply NOT increased - assert_eq!(Assets::total_supply(1), minimum_asset_balance); - }); -} - #[test] fn test_assets_balances_api_works() { use assets_common::runtime_api::runtime_decl_for_fungibles_api::FungiblesApi; diff --git a/system-parachains/asset-hubs/asset-hub-kusama/tests/weight_trader.rs b/system-parachains/asset-hubs/asset-hub-kusama/tests/weight_trader.rs index c4b0d66556..d18e529530 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/tests/weight_trader.rs +++ b/system-parachains/asset-hubs/asset-hub-kusama/tests/weight_trader.rs @@ -32,6 +32,13 @@ use frame_support::{ }, weights::{Weight, WeightToFee as WeightToFeeT}, }; + +use asset_hub_kusama_runtime::xcm_config::AssetFeeAsExistentialDepositMultiplierFeeCharger; +use asset_hub_kusama_runtime::xcm_config::TrustBackedAssetsPalletLocation; +use asset_hub_kusama_runtime::ExistentialDeposit; +use cumulus_primitives_utility::ChargeWeightInFungibles; +use frame_support::assert_noop; + use parachains_common::{AccountId, AuraId}; use sp_runtime::traits::MaybeEquivalence; use system_parachains_constants::kusama::{currency::*, fee::WeightToFee}; @@ -43,6 +50,347 @@ const SOME_ASSET_ADMIN: [u8; 32] = [5u8; 32]; type RuntimeHelper = asset_test_utils::RuntimeHelper; +type AssetIdForTrustBackedAssetsConvertLatest = + assets_common::AssetIdForTrustBackedAssetsConvertLatest; + +#[test] +fn test_asset_xcm_trader() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // We need root origin to create a sufficient asset + let minimum_asset_balance = 3333333_u128; + let local_asset_id = 1; + assert_ok!(Assets::force_create( + RuntimeHelper::root_origin(), + local_asset_id.into(), + AccountId::from(ALICE).into(), + true, + minimum_asset_balance + )); + + // We first mint enough asset for the account to exist for assets + assert_ok!(Assets::mint( + RuntimeHelper::origin_of(AccountId::from(ALICE)), + local_asset_id.into(), + AccountId::from(ALICE).into(), + minimum_asset_balance + )); + + // get asset id as location + let asset_location = + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&local_asset_id).unwrap(); + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + // We are going to buy 4e9 weight + let bought = Weight::from_parts(4_000_000_000u64, 0); + + // Lets calculate amount needed + let asset_amount_needed = + AssetFeeAsExistentialDepositMultiplierFeeCharger::charge_weight_in_fungibles( + local_asset_id, + bought, + ) + .expect("failed to compute"); + + // Lets pay with: asset_amount_needed + asset_amount_extra + let asset_amount_extra = 100_u128; + let asset: Asset = + (asset_location.clone(), asset_amount_needed + asset_amount_extra).into(); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Lets buy_weight and make sure buy_weight does not return an error + let unused_assets = trader.buy_weight(bought, asset.into(), &ctx).expect("Expected Ok"); + // Check whether a correct amount of unused assets is returned + assert_ok!(unused_assets.ensure_contains(&(asset_location, asset_amount_extra).into())); + + // Drop trader + drop(trader); + + // Make sure author(Alice) has received the amount + assert_eq!( + Assets::balance(local_asset_id, AccountId::from(ALICE)), + minimum_asset_balance + asset_amount_needed + ); + + // We also need to ensure the total supply increased + assert_eq!( + Assets::total_supply(local_asset_id), + minimum_asset_balance + asset_amount_needed + ); + }); +} + +#[test] +fn test_asset_xcm_trader_with_refund() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // We need root origin to create a sufficient asset + // We set existential deposit to be identical to the one for Balances first + assert_ok!(Assets::force_create( + RuntimeHelper::root_origin(), + 1.into(), + AccountId::from(ALICE).into(), + true, + ExistentialDeposit::get() + )); + + // We first mint enough asset for the account to exist for assets + assert_ok!(Assets::mint( + RuntimeHelper::origin_of(AccountId::from(ALICE)), + 1.into(), + AccountId::from(ALICE).into(), + ExistentialDeposit::get() + )); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + // We are going to buy 4e9 weight + let bought = Weight::from_parts(4_000_000_000u64, 0); + + let asset_location = + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&1).unwrap(); + + // lets calculate amount needed + let amount_bought = WeightToFee::weight_to_fee(&bought); + + let asset: Asset = (asset_location.clone(), amount_bought).into(); + + // Make sure buy_weight does not return an error + assert_ok!(trader.buy_weight(bought, asset.clone().into(), &ctx)); + + // Make sure again buy_weight does return an error + // This assert relies on the fact, that we use `TakeFirstAssetTrader` in `WeightTrader` + // tuple chain, which cannot be called twice + assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); + + // We actually use half of the weight + let weight_used = bought / 2; + + // Make sure refurnd works. + let amount_refunded = WeightToFee::weight_to_fee(&(bought - weight_used)); + + assert_eq!( + trader.refund_weight(bought - weight_used, &ctx), + Some((asset_location, amount_refunded).into()) + ); + + // Drop trader + drop(trader); + + // We only should have paid for half of the bought weight + let fees_paid = WeightToFee::weight_to_fee(&weight_used); + + assert_eq!( + Assets::balance(1, AccountId::from(ALICE)), + ExistentialDeposit::get() + fees_paid + ); + + // We also need to ensure the total supply increased + assert_eq!(Assets::total_supply(1), ExistentialDeposit::get() + fees_paid); + }); +} + +#[test] +fn test_asset_xcm_trader_refund_not_possible_since_amount_less_than_ed() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // We need root origin to create a sufficient asset + // We set existential deposit to be identical to the one for Balances first + assert_ok!(Assets::force_create( + RuntimeHelper::root_origin(), + 1.into(), + AccountId::from(ALICE).into(), + true, + ExistentialDeposit::get() + )); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + // We are going to buy small amount + let bought = Weight::from_parts(50_000_000u64, 0); + + let asset_location = + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&1).unwrap(); + + let amount_bought = WeightToFee::weight_to_fee(&bought); + + assert!( + amount_bought < ExistentialDeposit::get(), + "we are testing what happens when the amount does not exceed ED" + ); + + let asset: Asset = (asset_location, amount_bought).into(); + + // Buy weight should return an error + assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); + + // not credited since the ED is higher than this value + assert_eq!(Assets::balance(1, AccountId::from(ALICE)), 0); + + // We also need to ensure the total supply did not increase + assert_eq!(Assets::total_supply(1), 0); + }); +} + +#[test] +fn test_that_buying_ed_refund_does_not_refund() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // We need root origin to create a sufficient asset + // We set existential deposit to be identical to the one for Balances first + assert_ok!(Assets::force_create( + RuntimeHelper::root_origin(), + 1.into(), + AccountId::from(ALICE).into(), + true, + ExistentialDeposit::get() + )); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + // We are gonna buy ED + let bought = Weight::from_parts(ExistentialDeposit::get().try_into().unwrap(), 0); + + let asset_location = + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&1).unwrap(); + + let amount_bought = WeightToFee::weight_to_fee(&bought); + + assert!( + amount_bought < ExistentialDeposit::get(), + "we are testing what happens when the amount does not exceed ED" + ); + + // We know we will have to buy at least ED, so lets make sure first it will + // fail with a payment of less than ED + let asset: Asset = (asset_location.clone(), amount_bought).into(); + assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); + + // Now lets buy ED at least + let asset: Asset = (asset_location, ExistentialDeposit::get()).into(); + + // Buy weight should work + assert_ok!(trader.buy_weight(bought, asset.into(), &ctx)); + + // Should return None. We have a specific check making sure we dont go below ED for + // drop payment + assert_eq!(trader.refund_weight(bought, &ctx), None); + + // Drop trader + drop(trader); + + // Make sure author(Alice) has received the amount + assert_eq!(Assets::balance(1, AccountId::from(ALICE)), ExistentialDeposit::get()); + + // We also need to ensure the total supply increased + assert_eq!(Assets::total_supply(1), ExistentialDeposit::get()); + }); +} + +#[test] +fn test_asset_xcm_trader_not_possible_for_non_sufficient_assets() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // Create a non-sufficient asset with specific existential deposit + let minimum_asset_balance = 1_000_000_u128; + assert_ok!(Assets::force_create( + RuntimeHelper::root_origin(), + 1.into(), + AccountId::from(ALICE).into(), + false, + minimum_asset_balance + )); + + // We first mint enough asset for the account to exist for assets + assert_ok!(Assets::mint( + RuntimeHelper::origin_of(AccountId::from(ALICE)), + 1.into(), + AccountId::from(ALICE).into(), + minimum_asset_balance + )); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + // We are going to buy 4e9 weight + let bought = Weight::from_parts(4_000_000_000u64, 0); + + // lets calculate amount needed + let asset_amount_needed = WeightToFee::weight_to_fee(&bought); + + let asset_location = + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&1).unwrap(); + + let asset: Asset = (asset_location, asset_amount_needed).into(); + + // Make sure again buy_weight does return an error + assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); + + // Drop trader + drop(trader); + + // Make sure author(Alice) has NOT received the amount + assert_eq!(Assets::balance(1, AccountId::from(ALICE)), minimum_asset_balance); + + // We also need to ensure the total supply NOT increased + assert_eq!(Assets::total_supply(1), minimum_asset_balance); + }); +} + #[test] fn test_buy_and_refund_weight_with_native() { ExtBuilder::::default() diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/tests/tests.rs b/system-parachains/asset-hubs/asset-hub-polkadot/tests/tests.rs index 5ffc407a30..2f40c96e98 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/tests/tests.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/tests/tests.rs @@ -20,9 +20,8 @@ use asset_hub_polkadot_runtime::{ xcm_config::{ bridging::{self, XcmBridgeHubRouterFeeAssetId}, - AssetFeeAsExistentialDepositMultiplierFeeCharger, CheckingAccount, DotLocation, - ForeignCreatorsSovereignAccountOf, LocationToAccountId, TreasuryAccount, - TrustBackedAssetsPalletLocation, XcmConfig, + CheckingAccount, DotLocation, ForeignCreatorsSovereignAccountOf, LocationToAccountId, + TreasuryAccount, TrustBackedAssetsPalletLocation, XcmConfig, }, AllPalletsWithoutSystem, AssetDeposit, Assets, Balances, ExistentialDeposit, ForeignAssets, ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, ParachainSystem, @@ -33,12 +32,7 @@ use asset_test_utils::{ test_cases_over_bridge::TestBridgingConfig, CollatorSessionKey, CollatorSessionKeys, ExtBuilder, }; use codec::{Decode, Encode}; -use cumulus_primitives_utility::ChargeWeightInFungibles; -use frame_support::{ - assert_noop, assert_ok, - traits::fungibles::InspectEnumerable, - weights::{Weight, WeightToFee as WeightToFeeT}, -}; +use frame_support::{assert_ok, traits::fungibles::InspectEnumerable}; use parachains_common::{ AccountId, AssetHubPolkadotAuraId as AuraId, AssetIdForTrustBackedAssets, Balance, }; @@ -50,7 +44,7 @@ use system_parachains_constants::{ }; use xcm::latest::prelude::{Assets as XcmAssets, *}; use xcm_builder::V4V3LocationConverter; -use xcm_executor::traits::{ConvertLocation, JustTry, WeightTrader}; +use xcm_executor::traits::{ConvertLocation, JustTry}; const ALICE: [u8; 32] = [1u8; 32]; const SOME_ASSET_ADMIN: [u8; 32] = [5u8; 32]; @@ -96,356 +90,6 @@ fn test_ed_is_one_hundredth_of_relay() { }); } -#[test] -fn test_asset_xcm_trader() { - ExtBuilder::::default() - .with_collators(vec![AccountId::from(ALICE)]) - .with_session_keys(vec![( - AccountId::from(ALICE), - AccountId::from(ALICE), - SessionKeys { aura: AuraId::from(sp_core::ed25519::Public::from_raw(ALICE)) }, - )]) - .build() - .execute_with(|| { - // We need root origin to create a sufficient asset - let minimum_asset_balance = 333333333_u128; - let local_asset_id = 1; - assert_ok!(Assets::force_create( - RuntimeHelper::root_origin(), - local_asset_id.into(), - AccountId::from(ALICE).into(), - true, - minimum_asset_balance - )); - - // We first mint enough asset for the account to exist for assets - assert_ok!(Assets::mint( - RuntimeHelper::origin_of(AccountId::from(ALICE)), - local_asset_id.into(), - AccountId::from(ALICE).into(), - minimum_asset_balance - )); - - // get asset id as location - let asset_location = - AssetIdForTrustBackedAssetsConvertLatest::convert_back(&local_asset_id).unwrap(); - - // Set Alice as block author, who will receive fees - RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); - - // We are going to buy 400e9 weight - // Because of the ED being higher in kusama's asset hub - // and not to complicate things, we use a little - // bit more of weight - let bought = Weight::from_parts(400_000_000_000u64, 0); - - // Lets calculate amount needed - let asset_amount_needed = - AssetFeeAsExistentialDepositMultiplierFeeCharger::charge_weight_in_fungibles( - local_asset_id, - bought, - ) - .expect("failed to compute"); - - // Lets pay with: asset_amount_needed + asset_amount_extra - let asset_amount_extra = 100_u128; - let asset: Asset = - (asset_location.clone(), asset_amount_needed + asset_amount_extra).into(); - - let mut trader = ::Trader::new(); - let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - - // Lets buy_weight and make sure buy_weight does not return an error - let unused_assets = trader.buy_weight(bought, asset.into(), &ctx).expect("Expected Ok"); - // Check whether a correct amount of unused assets is returned - assert_ok!(unused_assets.ensure_contains(&(asset_location, asset_amount_extra).into())); - - // Drop trader - drop(trader); - - // Make sure author(Alice) has received the amount - assert_eq!( - Assets::balance(local_asset_id, AccountId::from(ALICE)), - minimum_asset_balance + asset_amount_needed - ); - - // We also need to ensure the total supply increased - assert_eq!( - Assets::total_supply(local_asset_id), - minimum_asset_balance + asset_amount_needed - ); - }); -} - -#[test] -fn test_asset_xcm_trader_with_refund() { - ExtBuilder::::default() - .with_collators(vec![AccountId::from(ALICE)]) - .with_session_keys(vec![( - AccountId::from(ALICE), - AccountId::from(ALICE), - SessionKeys { aura: AuraId::from(sp_core::ed25519::Public::from_raw(ALICE)) }, - )]) - .build() - .execute_with(|| { - // We need root origin to create a sufficient asset - // We set existential deposit to be identical to the one for Balances first - assert_ok!(Assets::force_create( - RuntimeHelper::root_origin(), - 1.into(), - AccountId::from(ALICE).into(), - true, - ExistentialDeposit::get() - )); - - // We first mint enough asset for the account to exist for assets - assert_ok!(Assets::mint( - RuntimeHelper::origin_of(AccountId::from(ALICE)), - 1.into(), - AccountId::from(ALICE).into(), - ExistentialDeposit::get() - )); - - let mut trader = ::Trader::new(); - let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - - // Set Alice as block author, who will receive fees - RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); - - // We are going to buy 400e9 weight - // Because of the ED being higher in kusama's asset hub - // and not to complicate things, we use a little - // bit more of weight - let bought = Weight::from_parts(400_000_000_000u64, 0); - - let asset_location = - AssetIdForTrustBackedAssetsConvertLatest::convert_back(&1).unwrap(); - - // lets calculate amount needed - let amount_bought = WeightToFee::weight_to_fee(&bought); - - let asset: Asset = (asset_location.clone(), amount_bought).into(); - - // Make sure buy_weight does not return an error - assert_ok!(trader.buy_weight(bought, asset.clone().into(), &ctx)); - - // Make sure again buy_weight does return an error - // This assert relies on the fact, that we use `TakeFirstAssetTrader` in `WeightTrader` - // tuple chain, which cannot be called twice - assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); - - // We actually use half of the weight - let weight_used = bought / 2; - - // Make sure refurnd works. - let amount_refunded = WeightToFee::weight_to_fee(&(bought - weight_used)); - - assert_eq!( - trader.refund_weight(bought - weight_used, &ctx), - Some((asset_location, amount_refunded).into()) - ); - - // Drop trader - drop(trader); - - // We only should have paid for half of the bought weight - let fees_paid = WeightToFee::weight_to_fee(&weight_used); - - assert_eq!( - Assets::balance(1, AccountId::from(ALICE)), - ExistentialDeposit::get() + fees_paid - ); - - // We also need to ensure the total supply increased - assert_eq!(Assets::total_supply(1), ExistentialDeposit::get() + fees_paid); - }); -} - -#[test] -fn test_asset_xcm_trader_refund_not_possible_since_amount_less_than_ed() { - ExtBuilder::::default() - .with_collators(vec![AccountId::from(ALICE)]) - .with_session_keys(vec![( - AccountId::from(ALICE), - AccountId::from(ALICE), - SessionKeys { aura: AuraId::from(sp_core::ed25519::Public::from_raw(ALICE)) }, - )]) - .build() - .execute_with(|| { - // We need root origin to create a sufficient asset - // We set existential deposit to be identical to the one for Balances first - assert_ok!(Assets::force_create( - RuntimeHelper::root_origin(), - 1.into(), - AccountId::from(ALICE).into(), - true, - ExistentialDeposit::get() - )); - - let mut trader = ::Trader::new(); - let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - - // Set Alice as block author, who will receive fees - RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); - - // We are going to buy 50e9 weight - // Because of the ED being higher in kusama's asset hub - // and not to complicate things, we use a little - // bit more of weight - let bought = Weight::from_parts(5_000_000_000u64, 0); - - let asset_location = - AssetIdForTrustBackedAssetsConvertLatest::convert_back(&1).unwrap(); - - let amount_bought = WeightToFee::weight_to_fee(&bought); - - assert!( - amount_bought < ExistentialDeposit::get(), - "we are testing what happens when the amount does not exceed ED" - ); - - let asset: Asset = (asset_location, amount_bought).into(); - - // Buy weight should return an error - assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); - - // not credited since the ED is higher than this value - assert_eq!(Assets::balance(1, AccountId::from(ALICE)), 0); - - // We also need to ensure the total supply did not increase - assert_eq!(Assets::total_supply(1), 0); - }); -} - -#[test] -fn test_that_buying_ed_refund_does_not_refund() { - ExtBuilder::::default() - .with_collators(vec![AccountId::from(ALICE)]) - .with_session_keys(vec![( - AccountId::from(ALICE), - AccountId::from(ALICE), - SessionKeys { aura: AuraId::from(sp_core::ed25519::Public::from_raw(ALICE)) }, - )]) - .build() - .execute_with(|| { - // We need root origin to create a sufficient asset - // We set existential deposit to be identical to the one for Balances first - assert_ok!(Assets::force_create( - RuntimeHelper::root_origin(), - 1.into(), - AccountId::from(ALICE).into(), - true, - ExistentialDeposit::get() - )); - - let mut trader = ::Trader::new(); - let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - - // Set Alice as block author, who will receive fees - RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); - - // We are gonna buy ED - let bought = Weight::from_parts(ExistentialDeposit::get().try_into().unwrap(), 0); - - let asset_location = - AssetIdForTrustBackedAssetsConvertLatest::convert_back(&1).unwrap(); - - let amount_bought = WeightToFee::weight_to_fee(&bought); - - assert!( - amount_bought < ExistentialDeposit::get(), - "we are testing what happens when the amount does not exceed ED" - ); - - // We know we will have to buy at least ED, so lets make sure first it will - // fail with a payment of less than ED - let asset: Asset = (asset_location.clone(), amount_bought).into(); - assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); - - // Now lets buy ED at least - let asset: Asset = (asset_location, ExistentialDeposit::get()).into(); - - // Buy weight should work - assert_ok!(trader.buy_weight(bought, asset.into(), &ctx)); - - // Should return None. We have a specific check making sure we dont go below ED for - // drop payment - assert_eq!(trader.refund_weight(bought, &ctx), None); - - // Drop trader - drop(trader); - - // Make sure author(Alice) has received the amount - assert_eq!(Assets::balance(1, AccountId::from(ALICE)), ExistentialDeposit::get()); - - // We also need to ensure the total supply increased - assert_eq!(Assets::total_supply(1), ExistentialDeposit::get()); - }); -} - -#[test] -fn test_asset_xcm_trader_not_possible_for_non_sufficient_assets() { - ExtBuilder::::default() - .with_collators(vec![AccountId::from(ALICE)]) - .with_session_keys(vec![( - AccountId::from(ALICE), - AccountId::from(ALICE), - SessionKeys { aura: AuraId::from(sp_core::ed25519::Public::from_raw(ALICE)) }, - )]) - .build() - .execute_with(|| { - // Create a non-sufficient asset - let minimum_asset_balance = 1_000_000_u128; - assert_ok!(Assets::force_create( - RuntimeHelper::root_origin(), - 1.into(), - AccountId::from(ALICE).into(), - false, - minimum_asset_balance - )); - - // We first mint enough asset for the account to exist for assets - assert_ok!(Assets::mint( - RuntimeHelper::origin_of(AccountId::from(ALICE)), - 1.into(), - AccountId::from(ALICE).into(), - minimum_asset_balance - )); - - let mut trader = ::Trader::new(); - let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; - - // Set Alice as block author, who will receive fees - RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); - - // We are going to buy 400e9 weight - // Because of the ED being higher in kusama's asset hub - // and not to complicate things, we use a little - // bit more of weight - let bought = Weight::from_parts(400_000_000_000u64, 0); - - // lets calculate amount needed - let asset_amount_needed = WeightToFee::weight_to_fee(&bought); - - let asset_location = - AssetIdForTrustBackedAssetsConvertLatest::convert_back(&1).unwrap(); - - let asset: Asset = (asset_location, asset_amount_needed).into(); - - // Make sure again buy_weight does return an error - assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); - - // Drop trader - drop(trader); - - // Make sure author(Alice) has NOT received the amount - assert_eq!(Assets::balance(1, AccountId::from(ALICE)), minimum_asset_balance); - - // We also need to ensure the total supply NOT increased - assert_eq!(Assets::total_supply(1), minimum_asset_balance); - }); -} - #[test] fn test_assets_balances_api_works() { use assets_common::runtime_api::runtime_decl_for_fungibles_api::FungiblesApi; diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/tests/weight_trader.rs b/system-parachains/asset-hubs/asset-hub-polkadot/tests/weight_trader.rs index 19a344f313..4bbfcf64ff 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/tests/weight_trader.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/tests/weight_trader.rs @@ -15,6 +15,9 @@ //! Tests for `WeighTrader` type of XCM Executor. +use asset_hub_polkadot_runtime::xcm_config::AssetFeeAsExistentialDepositMultiplierFeeCharger; +use asset_hub_polkadot_runtime::xcm_config::TrustBackedAssetsPalletLocation; +use asset_hub_polkadot_runtime::ExistentialDeposit; use asset_hub_polkadot_runtime::{ xcm_config::{ DotLocation, DotLocationV3, StakingPot, TrustBackedAssetsPalletLocationV3, XcmConfig, @@ -24,6 +27,8 @@ use asset_hub_polkadot_runtime::{ }; use asset_test_utils::ExtBuilder; use assets_common::AssetIdForTrustBackedAssetsConvert; +use cumulus_primitives_utility::ChargeWeightInFungibles; +use frame_support::assert_noop; use frame_support::{ assert_ok, traits::{ @@ -43,6 +48,359 @@ const SOME_ASSET_ADMIN: [u8; 32] = [5u8; 32]; type RuntimeHelper = asset_test_utils::RuntimeHelper; +type AssetIdForTrustBackedAssetsConvertLatest = + assets_common::AssetIdForTrustBackedAssetsConvertLatest; + +#[test] +fn test_asset_xcm_trader() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::ed25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // We need root origin to create a sufficient asset + let minimum_asset_balance = 333333333_u128; + let local_asset_id = 1; + assert_ok!(Assets::force_create( + RuntimeHelper::root_origin(), + local_asset_id.into(), + AccountId::from(ALICE).into(), + true, + minimum_asset_balance + )); + + // We first mint enough asset for the account to exist for assets + assert_ok!(Assets::mint( + RuntimeHelper::origin_of(AccountId::from(ALICE)), + local_asset_id.into(), + AccountId::from(ALICE).into(), + minimum_asset_balance + )); + + // get asset id as location + let asset_location = + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&local_asset_id).unwrap(); + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + // We are going to buy 400e9 weight + // Because of the ED being higher in kusama's asset hub + // and not to complicate things, we use a little + // bit more of weight + let bought = Weight::from_parts(400_000_000_000u64, 0); + + // Lets calculate amount needed + let asset_amount_needed = + AssetFeeAsExistentialDepositMultiplierFeeCharger::charge_weight_in_fungibles( + local_asset_id, + bought, + ) + .expect("failed to compute"); + + // Lets pay with: asset_amount_needed + asset_amount_extra + let asset_amount_extra = 100_u128; + let asset: Asset = + (asset_location.clone(), asset_amount_needed + asset_amount_extra).into(); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Lets buy_weight and make sure buy_weight does not return an error + let unused_assets = trader.buy_weight(bought, asset.into(), &ctx).expect("Expected Ok"); + // Check whether a correct amount of unused assets is returned + assert_ok!(unused_assets.ensure_contains(&(asset_location, asset_amount_extra).into())); + + // Drop trader + drop(trader); + + // Make sure author(Alice) has received the amount + assert_eq!( + Assets::balance(local_asset_id, AccountId::from(ALICE)), + minimum_asset_balance + asset_amount_needed + ); + + // We also need to ensure the total supply increased + assert_eq!( + Assets::total_supply(local_asset_id), + minimum_asset_balance + asset_amount_needed + ); + }); +} + +#[test] +fn test_asset_xcm_trader_with_refund() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::ed25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // We need root origin to create a sufficient asset + // We set existential deposit to be identical to the one for Balances first + assert_ok!(Assets::force_create( + RuntimeHelper::root_origin(), + 1.into(), + AccountId::from(ALICE).into(), + true, + ExistentialDeposit::get() + )); + + // We first mint enough asset for the account to exist for assets + assert_ok!(Assets::mint( + RuntimeHelper::origin_of(AccountId::from(ALICE)), + 1.into(), + AccountId::from(ALICE).into(), + ExistentialDeposit::get() + )); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + // We are going to buy 400e9 weight + // Because of the ED being higher in kusama's asset hub + // and not to complicate things, we use a little + // bit more of weight + let bought = Weight::from_parts(400_000_000_000u64, 0); + + let asset_location = + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&1).unwrap(); + + // lets calculate amount needed + let amount_bought = WeightToFee::weight_to_fee(&bought); + + let asset: Asset = (asset_location.clone(), amount_bought).into(); + + // Make sure buy_weight does not return an error + assert_ok!(trader.buy_weight(bought, asset.clone().into(), &ctx)); + + // Make sure again buy_weight does return an error + // This assert relies on the fact, that we use `TakeFirstAssetTrader` in `WeightTrader` + // tuple chain, which cannot be called twice + assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); + + // We actually use half of the weight + let weight_used = bought / 2; + + // Make sure refurnd works. + let amount_refunded = WeightToFee::weight_to_fee(&(bought - weight_used)); + + assert_eq!( + trader.refund_weight(bought - weight_used, &ctx), + Some((asset_location, amount_refunded).into()) + ); + + // Drop trader + drop(trader); + + // We only should have paid for half of the bought weight + let fees_paid = WeightToFee::weight_to_fee(&weight_used); + + assert_eq!( + Assets::balance(1, AccountId::from(ALICE)), + ExistentialDeposit::get() + fees_paid + ); + + // We also need to ensure the total supply increased + assert_eq!(Assets::total_supply(1), ExistentialDeposit::get() + fees_paid); + }); +} + +#[test] +fn test_asset_xcm_trader_refund_not_possible_since_amount_less_than_ed() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::ed25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // We need root origin to create a sufficient asset + // We set existential deposit to be identical to the one for Balances first + assert_ok!(Assets::force_create( + RuntimeHelper::root_origin(), + 1.into(), + AccountId::from(ALICE).into(), + true, + ExistentialDeposit::get() + )); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + // We are going to buy 50e9 weight + // Because of the ED being higher in kusama's asset hub + // and not to complicate things, we use a little + // bit more of weight + let bought = Weight::from_parts(5_000_000_000u64, 0); + + let asset_location = + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&1).unwrap(); + + let amount_bought = WeightToFee::weight_to_fee(&bought); + + assert!( + amount_bought < ExistentialDeposit::get(), + "we are testing what happens when the amount does not exceed ED" + ); + + let asset: Asset = (asset_location, amount_bought).into(); + + // Buy weight should return an error + assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); + + // not credited since the ED is higher than this value + assert_eq!(Assets::balance(1, AccountId::from(ALICE)), 0); + + // We also need to ensure the total supply did not increase + assert_eq!(Assets::total_supply(1), 0); + }); +} + +#[test] +fn test_that_buying_ed_refund_does_not_refund() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::ed25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // We need root origin to create a sufficient asset + // We set existential deposit to be identical to the one for Balances first + assert_ok!(Assets::force_create( + RuntimeHelper::root_origin(), + 1.into(), + AccountId::from(ALICE).into(), + true, + ExistentialDeposit::get() + )); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + // We are gonna buy ED + let bought = Weight::from_parts(ExistentialDeposit::get().try_into().unwrap(), 0); + + let asset_location = + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&1).unwrap(); + + let amount_bought = WeightToFee::weight_to_fee(&bought); + + assert!( + amount_bought < ExistentialDeposit::get(), + "we are testing what happens when the amount does not exceed ED" + ); + + // We know we will have to buy at least ED, so lets make sure first it will + // fail with a payment of less than ED + let asset: Asset = (asset_location.clone(), amount_bought).into(); + assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); + + // Now lets buy ED at least + let asset: Asset = (asset_location, ExistentialDeposit::get()).into(); + + // Buy weight should work + assert_ok!(trader.buy_weight(bought, asset.into(), &ctx)); + + // Should return None. We have a specific check making sure we dont go below ED for + // drop payment + assert_eq!(trader.refund_weight(bought, &ctx), None); + + // Drop trader + drop(trader); + + // Make sure author(Alice) has received the amount + assert_eq!(Assets::balance(1, AccountId::from(ALICE)), ExistentialDeposit::get()); + + // We also need to ensure the total supply increased + assert_eq!(Assets::total_supply(1), ExistentialDeposit::get()); + }); +} + +#[test] +fn test_asset_xcm_trader_not_possible_for_non_sufficient_assets() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::ed25519::Public::from_raw(ALICE)) }, + )]) + .build() + .execute_with(|| { + // Create a non-sufficient asset + let minimum_asset_balance = 1_000_000_u128; + assert_ok!(Assets::force_create( + RuntimeHelper::root_origin(), + 1.into(), + AccountId::from(ALICE).into(), + false, + minimum_asset_balance + )); + + // We first mint enough asset for the account to exist for assets + assert_ok!(Assets::mint( + RuntimeHelper::origin_of(AccountId::from(ALICE)), + 1.into(), + AccountId::from(ALICE).into(), + minimum_asset_balance + )); + + let mut trader = ::Trader::new(); + let ctx = XcmContext { origin: None, message_id: XcmHash::default(), topic: None }; + + // Set Alice as block author, who will receive fees + RuntimeHelper::run_to_block(2, AccountId::from(ALICE)); + + // We are going to buy 400e9 weight + // Because of the ED being higher in kusama's asset hub + // and not to complicate things, we use a little + // bit more of weight + let bought = Weight::from_parts(400_000_000_000u64, 0); + + // lets calculate amount needed + let asset_amount_needed = WeightToFee::weight_to_fee(&bought); + + let asset_location = + AssetIdForTrustBackedAssetsConvertLatest::convert_back(&1).unwrap(); + + let asset: Asset = (asset_location, asset_amount_needed).into(); + + // Make sure again buy_weight does return an error + assert_noop!(trader.buy_weight(bought, asset.into(), &ctx), XcmError::TooExpensive); + + // Drop trader + drop(trader); + + // Make sure author(Alice) has NOT received the amount + assert_eq!(Assets::balance(1, AccountId::from(ALICE)), minimum_asset_balance); + + // We also need to ensure the total supply NOT increased + assert_eq!(Assets::total_supply(1), minimum_asset_balance); + }); +} + #[test] fn test_buy_and_refund_weight_with_native() { ExtBuilder::::default() From df78d6c431bd825b869b5f02dee3e47f45827ce5 Mon Sep 17 00:00:00 2001 From: muharem Date: Tue, 5 Mar 2024 15:46:47 +0100 Subject: [PATCH 07/25] bridge fees from pool test --- .../asset-hub-kusama/tests/tests.rs | 126 +++++++++++++++++- .../asset-hub-polkadot/tests/tests.rs | 124 ++++++++++++++++- 2 files changed, 242 insertions(+), 8 deletions(-) diff --git a/system-parachains/asset-hubs/asset-hub-kusama/tests/tests.rs b/system-parachains/asset-hubs/asset-hub-kusama/tests/tests.rs index 80a0051282..6219265a26 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/tests/tests.rs +++ b/system-parachains/asset-hubs/asset-hub-kusama/tests/tests.rs @@ -21,11 +21,11 @@ use asset_hub_kusama_runtime::{ xcm_config::{ bridging::{self, XcmBridgeHubRouterFeeAssetId}, CheckingAccount, ForeignCreatorsSovereignAccountOf, KsmLocation, LocationToAccountId, - TreasuryAccount, TrustBackedAssetsPalletLocation, XcmConfig, + StakingPot, TreasuryAccount, TrustBackedAssetsPalletLocation, XcmConfig, }, - AllPalletsWithoutSystem, AssetDeposit, Assets, Balances, ExistentialDeposit, ForeignAssets, - ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, ParachainSystem, - PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, SessionKeys, + AllPalletsWithoutSystem, AssetConversion, AssetDeposit, Assets, Balances, ExistentialDeposit, + ForeignAssets, ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, + ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, SessionKeys, ToPolkadotXcmRouterInstance, TrustBackedAssetsInstance, XcmpQueue, SLOT_DURATION, }; use asset_test_utils::{ @@ -37,6 +37,7 @@ use parachains_common::{AccountId, AssetIdForTrustBackedAssets, AuraId, Balance} use parachains_runtimes_test_utils::SlotDurations; use sp_consensus_aura::SlotDuration; use sp_runtime::traits::MaybeEquivalence; +use sp_std::ops::Mul; use system_parachains_constants::kusama::{ consensus::RELAY_CHAIN_SLOT_DURATION_MILLIS, fee::WeightToFee, }; @@ -71,6 +72,52 @@ fn slot_durations() -> SlotDurations { } } +fn setup_pool_for_paying_fees_with_foreign_assets( + (foreign_asset_owner, foreign_asset_id_location, foreign_asset_id_minimum_balance): ( + AccountId, + xcm::v3::Location, + Balance, + ), +) { + let existential_deposit = ExistentialDeposit::get(); + + // setup a pool to pay fees with `foreign_asset_id_location` tokens + let pool_owner: AccountId = [14u8; 32].into(); + let native_asset = xcm::v3::Location::parent(); + let pool_liquidity: Balance = + existential_deposit.max(foreign_asset_id_minimum_balance).mul(100_000); + + let _ = Balances::force_set_balance( + RuntimeOrigin::root(), + pool_owner.clone().into(), + (existential_deposit + pool_liquidity).mul(2).into(), + ); + + assert_ok!(ForeignAssets::mint( + RuntimeOrigin::signed(foreign_asset_owner), + foreign_asset_id_location.into(), + pool_owner.clone().into(), + (foreign_asset_id_minimum_balance + pool_liquidity).mul(2).into(), + )); + + assert_ok!(AssetConversion::create_pool( + RuntimeOrigin::signed(pool_owner.clone()), + Box::new(native_asset.into()), + Box::new(foreign_asset_id_location.into()) + )); + + assert_ok!(AssetConversion::add_liquidity( + RuntimeOrigin::signed(pool_owner.clone()), + Box::new(native_asset.into()), + Box::new(foreign_asset_id_location.into()), + pool_liquidity, + pool_liquidity, + 1, + 1, + pool_owner, + )); +} + #[test] fn test_ed_is_one_hundredth_of_relay() { ExtBuilder::::default() @@ -377,6 +424,77 @@ fn limited_reserve_transfer_assets_for_native_asset_to_asset_hub_polkadot_works( ) } +#[test] +fn receive_reserve_asset_deposited_dot_from_asset_hub_polkadot_fees_paid_by_pool_swap_works() { + const BLOCK_AUTHOR_ACCOUNT: [u8; 32] = [13; 32]; + let block_author_account = AccountId::from(BLOCK_AUTHOR_ACCOUNT); + let staking_pot = StakingPot::get(); + + let foreign_asset_id_location = xcm::v3::Location::new( + 2, + [xcm::v3::Junction::GlobalConsensus(xcm::v3::NetworkId::Polkadot)], + ); + let foreign_asset_id_minimum_balance = 1_000_000_000; + // sovereign account as foreign asset owner (can be whoever for this scenario) + let foreign_asset_owner = LocationToAccountId::convert_location(&Location::parent()).unwrap(); + let foreign_asset_create_params = + (foreign_asset_owner, foreign_asset_id_location, foreign_asset_id_minimum_balance); + + asset_test_utils::test_cases_over_bridge::receive_reserve_asset_deposited_from_different_consensus_works::< + Runtime, + AllPalletsWithoutSystem, + XcmConfig, + ForeignAssetsInstance, + >( + collator_session_keys().add(collator_session_key(BLOCK_AUTHOR_ACCOUNT)), + ExistentialDeposit::get(), + AccountId::from([73; 32]), + block_author_account, + // receiving DOTs + foreign_asset_create_params.clone(), + 1000000000000, + || { + // setup pool for paying fees to touch `SwapFirstAssetTrader` + setup_pool_for_paying_fees_with_foreign_assets(foreign_asset_create_params); + // staking pot account for collecting local native fees from `BuyExecution` + let _ = Balances::force_set_balance(RuntimeOrigin::root(), StakingPot::get().into(), ExistentialDeposit::get()); + // prepare bridge configuration + bridging_to_asset_hub_polkadot() + }, + ( + [PalletInstance(bp_bridge_hub_kusama::WITH_BRIDGE_KUSAMA_TO_POLKADOT_MESSAGES_PALLET_INDEX)].into(), + GlobalConsensus(Polkadot), + [Parachain(1000)].into() + ), + || { + // check staking pot for ED + assert_eq!(Balances::free_balance(&staking_pot), ExistentialDeposit::get()); + // check now foreign asset for staking pot + assert_eq!( + ForeignAssets::balance( + foreign_asset_id_location.into(), + &staking_pot + ), + 0 + ); + }, + || { + // `SwapFirstAssetTrader` - staking pot receives xcm fees in DOTs + assert!( + Balances::free_balance(&staking_pot) > ExistentialDeposit::get() + ); + // staking pot receives no foreign assets + assert_eq!( + ForeignAssets::balance( + foreign_asset_id_location.into(), + &staking_pot + ), + 0 + ); + } + ) +} + #[test] fn receive_reserve_asset_deposited_dot_from_asset_hub_polkadot_fees_paid_by_sufficient_asset_works() { diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/tests/tests.rs b/system-parachains/asset-hubs/asset-hub-polkadot/tests/tests.rs index 2f40c96e98..8848753291 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/tests/tests.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/tests/tests.rs @@ -21,11 +21,11 @@ use asset_hub_polkadot_runtime::{ xcm_config::{ bridging::{self, XcmBridgeHubRouterFeeAssetId}, CheckingAccount, DotLocation, ForeignCreatorsSovereignAccountOf, LocationToAccountId, - TreasuryAccount, TrustBackedAssetsPalletLocation, XcmConfig, + StakingPot, TreasuryAccount, TrustBackedAssetsPalletLocation, XcmConfig, }, - AllPalletsWithoutSystem, AssetDeposit, Assets, Balances, ExistentialDeposit, ForeignAssets, - ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, ParachainSystem, - PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, SessionKeys, + AllPalletsWithoutSystem, AssetConversion, AssetDeposit, Assets, Balances, ExistentialDeposit, + ForeignAssets, ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, + ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, SessionKeys, ToKusamaXcmRouterInstance, TrustBackedAssetsInstance, XcmpQueue, SLOT_DURATION, }; use asset_test_utils::{ @@ -39,6 +39,7 @@ use parachains_common::{ use parachains_runtimes_test_utils::SlotDurations; use sp_consensus_aura::SlotDuration; use sp_runtime::traits::MaybeEquivalence; +use sp_std::ops::Mul; use system_parachains_constants::{ kusama::consensus::RELAY_CHAIN_SLOT_DURATION_MILLIS, polkadot::fee::WeightToFee, }; @@ -73,6 +74,52 @@ fn slot_durations() -> SlotDurations { } } +fn setup_pool_for_paying_fees_with_foreign_assets( + (foreign_asset_owner, foreign_asset_id_location, foreign_asset_id_minimum_balance): ( + AccountId, + xcm::v3::Location, + Balance, + ), +) { + let existential_deposit = ExistentialDeposit::get(); + + // setup a pool to pay fees with `foreign_asset_id_location` tokens + let pool_owner: AccountId = [14u8; 32].into(); + let native_asset = xcm::v3::Location::parent(); + let pool_liquidity: Balance = + existential_deposit.max(foreign_asset_id_minimum_balance).mul(100_000); + + let _ = Balances::force_set_balance( + RuntimeOrigin::root(), + pool_owner.clone().into(), + (existential_deposit + pool_liquidity).mul(2).into(), + ); + + assert_ok!(ForeignAssets::mint( + RuntimeOrigin::signed(foreign_asset_owner), + foreign_asset_id_location.into(), + pool_owner.clone().into(), + (foreign_asset_id_minimum_balance + pool_liquidity).mul(2).into(), + )); + + assert_ok!(AssetConversion::create_pool( + RuntimeOrigin::signed(pool_owner.clone()), + Box::new(native_asset.into()), + Box::new(foreign_asset_id_location.into()) + )); + + assert_ok!(AssetConversion::add_liquidity( + RuntimeOrigin::signed(pool_owner.clone()), + Box::new(native_asset.into()), + Box::new(foreign_asset_id_location.into()), + pool_liquidity, + pool_liquidity, + 1, + 1, + pool_owner, + )); +} + #[test] fn test_ed_is_one_hundredth_of_relay() { ExtBuilder::::default() @@ -379,6 +426,75 @@ fn limited_reserve_transfer_assets_for_native_asset_to_asset_hub_kusama_works() ) } +#[test] +fn receive_reserve_asset_deposited_ksm_from_asset_hub_kusama_fees_paid_by_pool_swap_works() { + const BLOCK_AUTHOR_ACCOUNT: [u8; 32] = [13; 32]; + let block_author_account = AccountId::from(BLOCK_AUTHOR_ACCOUNT); + let staking_pot = StakingPot::get(); + + let foreign_asset_id_location = + xcm::v3::Location::new(2, [xcm::v3::Junction::GlobalConsensus(xcm::v3::NetworkId::Kusama)]); + let foreign_asset_id_minimum_balance = 1_000_000_000; + // sovereign account as foreign asset owner (can be whoever for this scenario) + let foreign_asset_owner = LocationToAccountId::convert_location(&Location::parent()).unwrap(); + let foreign_asset_create_params = + (foreign_asset_owner, foreign_asset_id_location, foreign_asset_id_minimum_balance); + + asset_test_utils::test_cases_over_bridge::receive_reserve_asset_deposited_from_different_consensus_works::< + Runtime, + AllPalletsWithoutSystem, + XcmConfig, + ForeignAssetsInstance, + >( + collator_session_keys().add(collator_session_key(BLOCK_AUTHOR_ACCOUNT)), + ExistentialDeposit::get(), + AccountId::from([73; 32]), + block_author_account.clone(), + // receiving KSMs + foreign_asset_create_params.clone(), + 1000000000000, + || { + // setup pool for paying fees to touch `SwapFirstAssetTrader` + setup_pool_for_paying_fees_with_foreign_assets(foreign_asset_create_params); + // staking pot account for collecting local native fees from `BuyExecution` + let _ = Balances::force_set_balance(RuntimeOrigin::root(), StakingPot::get().into(), ExistentialDeposit::get()); + // prepare bridge configuration + bridging_to_asset_hub_kusama() + }, + ( + [PalletInstance(bp_bridge_hub_polkadot::WITH_BRIDGE_POLKADOT_TO_KUSAMA_MESSAGES_PALLET_INDEX)].into(), + GlobalConsensus(Kusama), + [Parachain(1000)].into() + ), + || { + // check staking pot for ED + assert_eq!(Balances::free_balance(&staking_pot), ExistentialDeposit::get()); + // check now foreign asset for staking pot + assert_eq!( + ForeignAssets::balance( + foreign_asset_id_location.into(), + &staking_pot + ), + 0 + ); + }, + || { + // `SwapFirstAssetTrader` - staking pot receives xcm fees in KSMs + assert!( + Balances::free_balance(&staking_pot) > ExistentialDeposit::get() + ); + // staking pot receives no foreign assets + assert_eq!( + ForeignAssets::balance( + foreign_asset_id_location.into(), + &staking_pot + ), + 0 + ); + } + ) +} + #[test] fn receive_reserve_asset_deposited_ksm_from_asset_hub_kusama_fees_paid_by_sufficient_asset_works() { const BLOCK_AUTHOR_ACCOUNT: [u8; 32] = [13; 32]; From d6d682b72dd1820ba1d93b72e30ea16842cca2fa Mon Sep 17 00:00:00 2001 From: muharem Date: Tue, 5 Mar 2024 16:43:48 +0100 Subject: [PATCH 08/25] emulated swap test --- Cargo.lock | 1 + .../assets/asset-hub-polkadot/src/lib.rs | 2 + .../assets/asset-hub-polkadot/Cargo.toml | 1 + .../asset-hub-polkadot/src/tests/mod.rs | 1 + .../asset-hub-polkadot/src/tests/swap.rs | 299 ++++++++++++++++++ 5 files changed, 304 insertions(+) create mode 100644 integration-tests/emulated/tests/assets/asset-hub-polkadot/src/tests/swap.rs diff --git a/Cargo.lock b/Cargo.lock index 7e01d7ea19..8948b5c9a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -568,6 +568,7 @@ dependencies = [ "emulated-integration-tests-common", "frame-support", "integration-tests-helpers", + "pallet-asset-conversion", "pallet-assets", "pallet-balances", "pallet-message-queue", diff --git a/integration-tests/emulated/chains/parachains/assets/asset-hub-polkadot/src/lib.rs b/integration-tests/emulated/chains/parachains/assets/asset-hub-polkadot/src/lib.rs index b0f35b3a6c..4a91be0a3e 100644 --- a/integration-tests/emulated/chains/parachains/assets/asset-hub-polkadot/src/lib.rs +++ b/integration-tests/emulated/chains/parachains/assets/asset-hub-polkadot/src/lib.rs @@ -45,6 +45,8 @@ decl_test_parachains! { Balances: asset_hub_polkadot_runtime::Balances, Assets: asset_hub_polkadot_runtime::Assets, ForeignAssets: asset_hub_polkadot_runtime::ForeignAssets, + PoolAssets: asset_hub_polkadot_runtime::PoolAssets, + AssetConversion: asset_hub_polkadot_runtime::AssetConversion, } }, } diff --git a/integration-tests/emulated/tests/assets/asset-hub-polkadot/Cargo.toml b/integration-tests/emulated/tests/assets/asset-hub-polkadot/Cargo.toml index ce1a8587cf..729fd37a44 100644 --- a/integration-tests/emulated/tests/assets/asset-hub-polkadot/Cargo.toml +++ b/integration-tests/emulated/tests/assets/asset-hub-polkadot/Cargo.toml @@ -16,6 +16,7 @@ sp-runtime = { version = "32.0.0" } frame-support = { version = "29.0.0" } pallet-balances = { version = "29.0.0" } pallet-assets = { version = "30.0.0" } +pallet-asset-conversion = { version = "11.0.0" } pallet-treasury = { version = "28.0.0" } pallet-message-queue = { version = "32.0.0" } diff --git a/integration-tests/emulated/tests/assets/asset-hub-polkadot/src/tests/mod.rs b/integration-tests/emulated/tests/assets/asset-hub-polkadot/src/tests/mod.rs index 4029a58cae..a5dced4fcf 100644 --- a/integration-tests/emulated/tests/assets/asset-hub-polkadot/src/tests/mod.rs +++ b/integration-tests/emulated/tests/assets/asset-hub-polkadot/src/tests/mod.rs @@ -18,6 +18,7 @@ mod fellowship_treasury; mod reserve_transfer; mod send; mod set_xcm_versions; +mod swap; mod teleport; mod treasury; diff --git a/integration-tests/emulated/tests/assets/asset-hub-polkadot/src/tests/swap.rs b/integration-tests/emulated/tests/assets/asset-hub-polkadot/src/tests/swap.rs new file mode 100644 index 0000000000..44f8d2fd1b --- /dev/null +++ b/integration-tests/emulated/tests/assets/asset-hub-polkadot/src/tests/swap.rs @@ -0,0 +1,299 @@ +// Copyright (C) Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use crate::*; +use polkadot_system_emulated_network::penpal_emulated_chain::LocalTeleportableToAssetHub as PenpalLocalTeleportableToAssetHub; +use sp_runtime::ModuleError; +use system_parachains_constants::polkadot::currency::SYSTEM_PARA_EXISTENTIAL_DEPOSIT; + +#[test] +fn swap_locally_on_chain_using_local_assets() { + use frame_support::traits::fungible::Mutate; + + let asset_native = Box::new(asset_hub_polkadot_runtime::xcm_config::DotLocationV3::get()); + let asset_one = Box::new(v3::Location::new( + 0, + [ + v3::Junction::PalletInstance(ASSETS_PALLET_ID), + v3::Junction::GeneralIndex(ASSET_ID.into()), + ], + )); + + AssetHubPolkadot::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + assert_ok!(::Assets::create( + ::RuntimeOrigin::signed(AssetHubPolkadotSender::get()), + ASSET_ID.into(), + AssetHubPolkadotSender::get().into(), + 1000, + )); + assert!(::Assets::asset_exists(ASSET_ID)); + + assert_ok!(::Assets::mint( + ::RuntimeOrigin::signed(AssetHubPolkadotSender::get()), + ASSET_ID.into(), + AssetHubPolkadotSender::get().into(), + 3_000_000_000_000, + )); + + ::Balances::set_balance( + &AssetHubPolkadotSender::get(), + 3_000_000_000_000, + ); + + assert_ok!(::AssetConversion::create_pool( + ::RuntimeOrigin::signed(AssetHubPolkadotSender::get()), + asset_native.clone(), + asset_one.clone(), + )); + + assert_expected_events!( + AssetHubPolkadot, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::PoolCreated { .. }) => {}, + ] + ); + + assert_ok!(::AssetConversion::add_liquidity( + ::RuntimeOrigin::signed(AssetHubPolkadotSender::get()), + asset_native.clone(), + asset_one.clone(), + 1_000_000_000_000, + 2_000_000_000_000, + 0, + 0, + AssetHubPolkadotSender::get().into() + )); + + assert_expected_events!( + AssetHubPolkadot, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::LiquidityAdded {lp_token_minted, .. }) => { lp_token_minted: *lp_token_minted == 1414213562273, }, + ] + ); + + let path = vec![asset_native.clone(), asset_one.clone()]; + + assert_ok!( + ::AssetConversion::swap_exact_tokens_for_tokens( + ::RuntimeOrigin::signed(AssetHubPolkadotSender::get()), + path, + 100, + 1, + AssetHubPolkadotSender::get().into(), + true + ) + ); + + assert_expected_events!( + AssetHubPolkadot, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::SwapExecuted { amount_in, amount_out, .. }) => { + amount_in: *amount_in == 100, + amount_out: *amount_out == 199, + }, + ] + ); + + assert_ok!( + ::AssetConversion::remove_liquidity( + ::RuntimeOrigin::signed(AssetHubPolkadotSender::get()), + asset_native, + asset_one, + 1414213562273 - SYSTEM_PARA_EXISTENTIAL_DEPOSIT * 2, /* all but the 2 EDs can't be + * retrieved. */ + 0, + 0, + AssetHubPolkadotSender::get().into(), + ) + ); + }); +} + +#[test] +fn swap_locally_on_chain_using_foreign_assets() { + let asset_native = Box::new( + v3::Location::try_from(asset_hub_polkadot_runtime::xcm_config::DotLocation::get()) + .expect("conversion works"), + ); + + let ah_as_seen_by_penpal = PenpalB::sibling_location_of(AssetHubPolkadot::para_id()); + let asset_location_on_penpal = + v3::Location::try_from(PenpalLocalTeleportableToAssetHub::get()).expect("conversion works"); + let asset_id_on_penpal = match asset_location_on_penpal.last() { + Some(v3::Junction::GeneralIndex(id)) => *id as u32, + _ => unreachable!(), + }; + let asset_owner_on_penpal = PenpalBSender::get(); + let foreign_asset_at_asset_hub_polkadot = + v3::Location::new(1, [v3::Junction::Parachain(PenpalB::para_id().into())]) + .appended_with(asset_location_on_penpal) + .unwrap(); + + // 1. Create asset on penpal and, 2. Create foreign asset on asset_hub_polkadot + super::penpal_create_foreign_asset_on_asset_hub( + asset_id_on_penpal, + foreign_asset_at_asset_hub_polkadot, + ah_as_seen_by_penpal, + true, + asset_owner_on_penpal, + ASSET_MIN_BALANCE * 1_000_000, + ); + + let penpal_as_seen_by_ah = AssetHubPolkadot::sibling_location_of(PenpalB::para_id()); + let sov_penpal_on_ahk = AssetHubPolkadot::sovereign_account_id_of(penpal_as_seen_by_ah); + AssetHubPolkadot::fund_accounts(vec![ + (AssetHubPolkadotSender::get().into(), 5_000_000 * POLKADOT_ED), /* An account to swap dot + * for something else. */ + ]); + + AssetHubPolkadot::execute_with(|| { + // 3: Mint foreign asset on asset_hub_polkadot: + // + // (While it might be nice to use batch, + // currently that's disabled due to safe call filters.) + + type RuntimeEvent = ::RuntimeEvent; + // 3. Mint foreign asset (in reality this should be a teleport or some such) + assert_ok!(::ForeignAssets::mint( + ::RuntimeOrigin::signed(sov_penpal_on_ahk.clone().into()), + foreign_asset_at_asset_hub_polkadot, + sov_penpal_on_ahk.clone().into(), + 3_000_000_000_000, + )); + + assert_expected_events!( + AssetHubPolkadot, + vec![ + RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { .. }) => {}, + ] + ); + + // 4. Create pool: + assert_ok!(::AssetConversion::create_pool( + ::RuntimeOrigin::signed(AssetHubPolkadotSender::get()), + asset_native.clone(), + Box::new(foreign_asset_at_asset_hub_polkadot), + )); + + assert_expected_events!( + AssetHubPolkadot, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::PoolCreated { .. }) => {}, + ] + ); + + // 5. Add liquidity: + assert_ok!(::AssetConversion::add_liquidity( + ::RuntimeOrigin::signed(sov_penpal_on_ahk.clone()), + asset_native.clone(), + Box::new(foreign_asset_at_asset_hub_polkadot), + 1_000_000_000_000, + 2_000_000_000_000, + 0, + 0, + sov_penpal_on_ahk.clone().into() + )); + + assert_expected_events!( + AssetHubPolkadot, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::LiquidityAdded {lp_token_minted, .. }) => { + lp_token_minted: *lp_token_minted == 1414213562273, + }, + ] + ); + + // 6. Swap! + let path = vec![asset_native.clone(), Box::new(foreign_asset_at_asset_hub_polkadot)]; + + assert_ok!( + ::AssetConversion::swap_exact_tokens_for_tokens( + ::RuntimeOrigin::signed(AssetHubPolkadotSender::get()), + path, + 100000, + 1000, + AssetHubPolkadotSender::get().into(), + true + ) + ); + + assert_expected_events!( + AssetHubPolkadot, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::SwapExecuted { amount_in, amount_out, .. },) => { + amount_in: *amount_in == 100000, + amount_out: *amount_out == 199399, + }, + ] + ); + + // 7. Remove liquidity + assert_ok!( + ::AssetConversion::remove_liquidity( + ::RuntimeOrigin::signed(sov_penpal_on_ahk.clone()), + asset_native.clone(), + Box::new(foreign_asset_at_asset_hub_polkadot), + 1414213562273 - 2_000_000_000, // all but the 2 EDs can't be retrieved. + 0, + 0, + sov_penpal_on_ahk.clone().into(), + ) + ); + }); +} + +#[test] +fn cannot_create_pool_from_pool_assets() { + use frame_support::traits::fungibles::Create; + use frame_support::traits::fungibles::Mutate; + + let asset_native = asset_hub_polkadot_runtime::xcm_config::DotLocation::get() + .try_into() + .expect("conversion works"); + let asset_one = asset_hub_polkadot_runtime::xcm_config::PoolAssetsPalletLocation::get() + .appended_with(GeneralIndex(ASSET_ID.into())) + .expect("valid location") + .try_into() + .expect("conversion works"); + + AssetHubPolkadot::execute_with(|| { + assert_ok!( + <::PoolAssets as Create<_>>::create( + ASSET_ID.into(), + AssetHubPolkadotSender::get(), + false, + 1000, + ) + ); + assert!(::PoolAssets::asset_exists(ASSET_ID)); + + assert_ok!(::PoolAssets::mint_into( + ASSET_ID.into(), + &AssetHubPolkadotSender::get(), + 3_000_000_000_000, + )); + + assert_matches::assert_matches!( + ::AssetConversion::create_pool( + ::RuntimeOrigin::signed(AssetHubPolkadotSender::get()), + Box::new(asset_native), + Box::new(asset_one), + ), + Err(DispatchError::Module(ModuleError{index: _, error: _, message})) => assert_eq!(message, Some("Unknown")) + ); + }); +} From 206632c0ad5e8254888b454a8da77693d14a80db Mon Sep 17 00:00:00 2001 From: muharem Date: Tue, 5 Mar 2024 17:35:33 +0100 Subject: [PATCH 09/25] more swap tests --- .../assets/asset-hub-kusama/src/tests/swap.rs | 130 +++++++++++++++++ .../asset-hub-polkadot/src/tests/swap.rs | 137 ++++++++++++++++++ 2 files changed, 267 insertions(+) diff --git a/integration-tests/emulated/tests/assets/asset-hub-kusama/src/tests/swap.rs b/integration-tests/emulated/tests/assets/asset-hub-kusama/src/tests/swap.rs index 16e7b0d2ae..29f8d71065 100644 --- a/integration-tests/emulated/tests/assets/asset-hub-kusama/src/tests/swap.rs +++ b/integration-tests/emulated/tests/assets/asset-hub-kusama/src/tests/swap.rs @@ -287,3 +287,133 @@ fn cannot_create_pool_from_pool_assets() { ); }); } + +#[test] +fn pay_xcm_fee_with_some_asset_swapped_for_native() { + let asset_native = asset_hub_kusama_runtime::xcm_config::KsmLocationV3::get(); + let asset_one = xcm::v3::Location { + parents: 0, + interior: [ + xcm::v3::Junction::PalletInstance(ASSETS_PALLET_ID), + xcm::v3::Junction::GeneralIndex(ASSET_ID.into()), + ] + .into(), + }; + let penpal = AssetHubKusama::sovereign_account_id_of(AssetHubKusama::sibling_location_of( + PenpalA::para_id(), + )); + + AssetHubKusama::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + // set up pool with ASSET_ID <> NATIVE pair + assert_ok!(::Assets::create( + ::RuntimeOrigin::signed(AssetHubKusamaSender::get()), + ASSET_ID.into(), + AssetHubKusamaSender::get().into(), + ASSET_MIN_BALANCE, + )); + assert!(::Assets::asset_exists(ASSET_ID)); + + assert_ok!(::Assets::mint( + ::RuntimeOrigin::signed(AssetHubKusamaSender::get()), + ASSET_ID.into(), + AssetHubKusamaSender::get().into(), + 3_000_000_000_000, + )); + + assert_ok!(::AssetConversion::create_pool( + ::RuntimeOrigin::signed(AssetHubKusamaSender::get()), + Box::new(asset_native), + Box::new(asset_one), + )); + + assert_expected_events!( + AssetHubKusama, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::PoolCreated { .. }) => {}, + ] + ); + + assert_ok!(::AssetConversion::add_liquidity( + ::RuntimeOrigin::signed(AssetHubKusamaSender::get()), + Box::new(asset_native), + Box::new(asset_one), + 1_000_000_000_000, + 2_000_000_000_000, + 0, + 0, + AssetHubKusamaSender::get().into() + )); + + assert_expected_events!( + AssetHubKusama, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::LiquidityAdded {lp_token_minted, .. }) => { lp_token_minted: *lp_token_minted == 1414213562273, }, + ] + ); + + // ensure `penpal` sovereign account has no native tokens and mint some `ASSET_ID` + assert_eq!( + ::Balances::free_balance(penpal.clone()), + 0 + ); + + assert_ok!(::Assets::touch_other( + ::RuntimeOrigin::signed(AssetHubKusamaSender::get()), + ASSET_ID.into(), + penpal.clone().into(), + )); + + assert_ok!(::Assets::mint( + ::RuntimeOrigin::signed(AssetHubKusamaSender::get()), + ASSET_ID.into(), + penpal.clone().into(), + 10_000_000_000_000, + )); + }); + + PenpalA::execute_with(|| { + // send xcm transact from `penpal` account which as only `ASSET_ID` tokens on + // `AssetHubKusama` + let call = AssetHubKusama::force_create_asset_call( + ASSET_ID + 1000, + penpal.clone(), + true, + ASSET_MIN_BALANCE, + ); + + let penpal_root = ::RuntimeOrigin::root(); + let fee_amount = 4_000_000_000_000u128; + let asset_one = + ([PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())], fee_amount).into(); + let asset_hub_location = PenpalA::sibling_location_of(AssetHubKusama::para_id()).into(); + let xcm = xcm_transact_paid_execution( + call, + OriginKind::SovereignAccount, + asset_one, + penpal.clone(), + ); + + assert_ok!(::PolkadotXcm::send( + penpal_root, + bx!(asset_hub_location), + bx!(xcm), + )); + + PenpalA::assert_xcm_pallet_sent(); + }); + + AssetHubKusama::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + AssetHubKusama::assert_xcmp_queue_success(None); + assert_expected_events!( + AssetHubKusama, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::SwapCreditExecuted { .. },) => {}, + RuntimeEvent::MessageQueue(pallet_message_queue::Event::Processed { success: true,.. }) => {}, + ] + ); + }); +} diff --git a/integration-tests/emulated/tests/assets/asset-hub-polkadot/src/tests/swap.rs b/integration-tests/emulated/tests/assets/asset-hub-polkadot/src/tests/swap.rs index 44f8d2fd1b..a71f72fc6c 100644 --- a/integration-tests/emulated/tests/assets/asset-hub-polkadot/src/tests/swap.rs +++ b/integration-tests/emulated/tests/assets/asset-hub-polkadot/src/tests/swap.rs @@ -297,3 +297,140 @@ fn cannot_create_pool_from_pool_assets() { ); }); } + +#[test] +fn pay_xcm_fee_with_some_asset_swapped_for_native() { + use frame_support::traits::fungible::Mutate; + + let asset_native = asset_hub_polkadot_runtime::xcm_config::DotLocationV3::get(); + let asset_one = xcm::v3::Location { + parents: 0, + interior: [ + xcm::v3::Junction::PalletInstance(ASSETS_PALLET_ID), + xcm::v3::Junction::GeneralIndex(ASSET_ID.into()), + ] + .into(), + }; + let penpal = AssetHubPolkadot::sovereign_account_id_of(AssetHubPolkadot::sibling_location_of( + PenpalB::para_id(), + )); + + AssetHubPolkadot::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + // set up pool with ASSET_ID <> NATIVE pair + assert_ok!(::Assets::create( + ::RuntimeOrigin::signed(AssetHubPolkadotSender::get()), + ASSET_ID.into(), + AssetHubPolkadotSender::get().into(), + ASSET_MIN_BALANCE, + )); + assert!(::Assets::asset_exists(ASSET_ID)); + + assert_ok!(::Assets::mint( + ::RuntimeOrigin::signed(AssetHubPolkadotSender::get()), + ASSET_ID.into(), + AssetHubPolkadotSender::get().into(), + 3_000_000_000_000, + )); + + ::Balances::set_balance( + &AssetHubPolkadotSender::get(), + 3_000_000_000_000, + ); + + assert_ok!(::AssetConversion::create_pool( + ::RuntimeOrigin::signed(AssetHubPolkadotSender::get()), + Box::new(asset_native), + Box::new(asset_one), + )); + + assert_expected_events!( + AssetHubPolkadot, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::PoolCreated { .. }) => {}, + ] + ); + + assert_ok!(::AssetConversion::add_liquidity( + ::RuntimeOrigin::signed(AssetHubPolkadotSender::get()), + Box::new(asset_native), + Box::new(asset_one), + 1_000_000_000_000, + 2_000_000_000_000, + 0, + 0, + AssetHubPolkadotSender::get().into() + )); + + assert_expected_events!( + AssetHubPolkadot, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::LiquidityAdded {lp_token_minted, .. }) => { lp_token_minted: *lp_token_minted == 1414213562273, }, + ] + ); + + // ensure `penpal` sovereign account has no native tokens and mint some `ASSET_ID` + assert_eq!( + ::Balances::free_balance(penpal.clone()), + 0 + ); + + assert_ok!(::Assets::touch_other( + ::RuntimeOrigin::signed(AssetHubPolkadotSender::get()), + ASSET_ID.into(), + penpal.clone().into(), + )); + + assert_ok!(::Assets::mint( + ::RuntimeOrigin::signed(AssetHubPolkadotSender::get()), + ASSET_ID.into(), + penpal.clone().into(), + 10_000_000_000_000, + )); + }); + + PenpalB::execute_with(|| { + // send xcm transact from `penpal` account which as only `ASSET_ID` tokens on + // `AssetHubPolkadot` + let call = AssetHubPolkadot::force_create_asset_call( + ASSET_ID + 1000, + penpal.clone(), + true, + ASSET_MIN_BALANCE, + ); + + let penpal_root = ::RuntimeOrigin::root(); + let fee_amount = 4_000_000_000_000u128; + let asset_one = + ([PalletInstance(ASSETS_PALLET_ID), GeneralIndex(ASSET_ID.into())], fee_amount).into(); + let asset_hub_location = PenpalB::sibling_location_of(AssetHubPolkadot::para_id()).into(); + let xcm = xcm_transact_paid_execution( + call, + OriginKind::SovereignAccount, + asset_one, + penpal.clone(), + ); + + assert_ok!(::PolkadotXcm::send( + penpal_root, + bx!(asset_hub_location), + bx!(xcm), + )); + + PenpalB::assert_xcm_pallet_sent(); + }); + + AssetHubPolkadot::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + AssetHubPolkadot::assert_xcmp_queue_success(None); + assert_expected_events!( + AssetHubPolkadot, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::SwapCreditExecuted { .. },) => {}, + RuntimeEvent::MessageQueue(pallet_message_queue::Event::Processed { success: true,.. }) => {}, + ] + ); + }); +} From f3b78d181cb3251fdb760276c22ff4bbada17785 Mon Sep 17 00:00:00 2001 From: muharem Date: Tue, 5 Mar 2024 18:40:21 +0100 Subject: [PATCH 10/25] bridge asset transfer tests --- .../bridges/bridge-hub-kusama/Cargo.toml | 1 + .../bridges/bridge-hub-kusama/src/lib.rs | 8 +- .../src/tests/asset_transfers.rs | 241 +++++++++++++++++ .../bridges/bridge-hub-polkadot/Cargo.toml | 1 + .../bridges/bridge-hub-polkadot/src/lib.rs | 1 + .../src/tests/asset_transfers.rs | 242 ++++++++++++++++++ 6 files changed, 491 insertions(+), 3 deletions(-) diff --git a/integration-tests/emulated/tests/bridges/bridge-hub-kusama/Cargo.toml b/integration-tests/emulated/tests/bridges/bridge-hub-kusama/Cargo.toml index 40b168d264..6db45be9a6 100644 --- a/integration-tests/emulated/tests/bridges/bridge-hub-kusama/Cargo.toml +++ b/integration-tests/emulated/tests/bridges/bridge-hub-kusama/Cargo.toml @@ -13,6 +13,7 @@ publish = false sp-runtime = { version = "32.0.0" } frame-support = { version = "29.0.0" } pallet-balances = { version = "29.0.0" } +pallet-asset-conversion = { version = "11.0.0" } pallet-assets = { version = "30.0.0" } pallet-message-queue = { version = "32.0.0" } diff --git a/integration-tests/emulated/tests/bridges/bridge-hub-kusama/src/lib.rs b/integration-tests/emulated/tests/bridges/bridge-hub-kusama/src/lib.rs index f0a4056cb5..dfb2270f36 100644 --- a/integration-tests/emulated/tests/bridges/bridge-hub-kusama/src/lib.rs +++ b/integration-tests/emulated/tests/bridges/bridge-hub-kusama/src/lib.rs @@ -33,6 +33,7 @@ pub use bp_messages::LaneId; // Cumulus pub use emulated_integration_tests_common::{ accounts::ALICE, + accounts::BOB, impls::Inspect, xcm_emulator::{ assert_expected_events, bx, helpers::weight_within_threshold, Chain, Parachain as Para, @@ -56,9 +57,10 @@ pub use kusama_polkadot_system_emulated_network::{ AssetHubKusamaPara as AssetHubKusama, AssetHubKusamaParaReceiver as AssetHubKusamaReceiver, AssetHubKusamaParaSender as AssetHubKusamaSender, AssetHubPolkadotPara as AssetHubPolkadot, AssetHubPolkadotParaReceiver as AssetHubPolkadotReceiver, - BridgeHubKusamaPara as BridgeHubKusama, BridgeHubKusamaParaSender as BridgeHubKusamaSender, - BridgeHubPolkadotPara as BridgeHubPolkadot, KusamaRelay as Kusama, - KusamaRelayReceiver as KusamaReceiver, KusamaRelaySender as KusamaSender, + AssetHubPolkadotParaSender as AssetHubPolkadotSender, BridgeHubKusamaPara as BridgeHubKusama, + BridgeHubKusamaParaSender as BridgeHubKusamaSender, BridgeHubPolkadotPara as BridgeHubPolkadot, + KusamaRelay as Kusama, KusamaRelayReceiver as KusamaReceiver, + KusamaRelaySender as KusamaSender, }; pub use kusama_system_emulated_network::{ penpal_emulated_chain::PenpalAParaPallet as PenpalAPallet, diff --git a/integration-tests/emulated/tests/bridges/bridge-hub-kusama/src/tests/asset_transfers.rs b/integration-tests/emulated/tests/bridges/bridge-hub-kusama/src/tests/asset_transfers.rs index 49fb9aba9b..6f14cb3b1d 100644 --- a/integration-tests/emulated/tests/bridges/bridge-hub-kusama/src/tests/asset_transfers.rs +++ b/integration-tests/emulated/tests/bridges/bridge-hub-kusama/src/tests/asset_transfers.rs @@ -14,6 +14,7 @@ // limitations under the License. use crate::tests::*; +use frame_support::traits::fungible::Mutate; fn send_asset_from_asset_hub_kusama_to_asset_hub_polkadot(id: Location, amount: u128) { let destination = asset_hub_polkadot_location(); @@ -174,3 +175,243 @@ fn send_dots_from_asset_hub_kusama_to_asset_hub_polkadot() { // Reserve balance is reduced by sent amount assert_eq!(dots_in_reserve_on_ahp_after, dots_in_reserve_on_ahp_before - amount_to_send); } + +#[test] +fn send_ksms_from_asset_hub_kusama_to_asset_hub_polkadot_fee_from_pool() { + let ksm_at_asset_hub_kusama: v3::Location = v3::Parent.into(); + let ksm_at_asset_hub_polkadot = + v3::Location::new(2, [v3::Junction::GlobalConsensus(v3::NetworkId::Kusama)]); + let owner: AccountId = AssetHubPolkadot::account_id_of(ALICE); + AssetHubPolkadot::force_create_foreign_asset( + ksm_at_asset_hub_polkadot, + owner, + false, + ASSET_MIN_BALANCE, + vec![], + ); + let sov_ahp_on_ahk = AssetHubKusama::sovereign_account_of_parachain_on_other_global_consensus( + NetworkId::Polkadot, + AssetHubPolkadot::para_id(), + ); + + AssetHubPolkadot::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + // setup a pool to pay xcm fees with `ksm_at_asset_hub_polkadot` tokens + assert_ok!(::ForeignAssets::mint( + ::RuntimeOrigin::signed(AssetHubPolkadotSender::get()), + ksm_at_asset_hub_polkadot.into(), + AssetHubPolkadotSender::get().into(), + 3_000_000_000_000, + )); + + ::Balances::set_balance( + &AssetHubPolkadotSender::get(), + 3_000_000_000_000, + ); + + assert_ok!(::AssetConversion::create_pool( + ::RuntimeOrigin::signed(AssetHubPolkadotSender::get()), + Box::new(xcm::v3::Parent.into()), + Box::new(ksm_at_asset_hub_polkadot), + )); + + assert_expected_events!( + AssetHubPolkadot, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::PoolCreated { .. }) => {}, + ] + ); + + assert_ok!(::AssetConversion::add_liquidity( + ::RuntimeOrigin::signed(AssetHubPolkadotSender::get()), + Box::new(xcm::v3::Parent.into()), + Box::new(ksm_at_asset_hub_polkadot), + 1_000_000_000_000, + 2_000_000_000_000, + 1, + 1, + AssetHubPolkadotSender::get().into() + )); + + assert_expected_events!( + AssetHubPolkadot, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::LiquidityAdded {..}) => {}, + ] + ); + }); + + let ksms_in_reserve_on_ahk_before = + ::account_data_of(sov_ahp_on_ahk.clone()).free; + let sender_ksms_before = + ::account_data_of(AssetHubKusamaSender::get()).free; + let receiver_ksms_before = AssetHubPolkadot::execute_with(|| { + type Assets = ::ForeignAssets; + >::balance(ksm_at_asset_hub_polkadot, &AssetHubPolkadotReceiver::get()) + }); + + let ksm_at_asset_hub_kusama_latest: Location = ksm_at_asset_hub_kusama.try_into().unwrap(); + let amount = ASSET_HUB_KUSAMA_ED * 1_000; + send_asset_from_asset_hub_kusama_to_asset_hub_polkadot(ksm_at_asset_hub_kusama_latest, amount); + AssetHubPolkadot::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + assert_expected_events!( + AssetHubPolkadot, + vec![ + // issue KSMs on AHP + RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { asset_id, owner, .. }) => { + asset_id: *asset_id == ksm_at_asset_hub_kusama, + owner: *owner == AssetHubPolkadotReceiver::get(), + }, + // message processed successfully + RuntimeEvent::MessageQueue( + pallet_message_queue::Event::Processed { success: true, .. } + ) => {}, + ] + ); + }); + + let sender_ksms_after = + ::account_data_of(AssetHubKusamaSender::get()).free; + let receiver_ksms_after = AssetHubPolkadot::execute_with(|| { + type Assets = ::ForeignAssets; + >::balance(ksm_at_asset_hub_polkadot, &AssetHubPolkadotReceiver::get()) + }); + let ksms_in_reserve_on_ahk_after = + ::account_data_of(sov_ahp_on_ahk.clone()).free; + + // Sender's balance is reduced + assert!(sender_ksms_before > sender_ksms_after); + // Receiver's balance is increased + assert!(receiver_ksms_after > receiver_ksms_before); + // Reserve balance is reduced by sent amount + assert_eq!(ksms_in_reserve_on_ahk_after, ksms_in_reserve_on_ahk_before + amount); +} + +#[test] +fn send_dots_from_asset_hub_polkadot_to_asset_hub_kusama_fee_from_pool() { + let prefund_amount = 10_000_000_000_000u128; + let dot_at_asset_hub_kusama = + v3::Location::new(2, [v3::Junction::GlobalConsensus(v3::NetworkId::Polkadot)]); + let owner: AccountId = AssetHubPolkadot::account_id_of(BOB); + AssetHubKusama::force_create_foreign_asset( + dot_at_asset_hub_kusama, + owner.clone(), + false, + ASSET_MIN_BALANCE, + vec![(AssetHubKusamaSender::get(), prefund_amount)], + ); + + AssetHubKusama::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + // setup a pool to pay xcm fees with `dot_at_asset_hub_kusama` tokens + assert_ok!(::ForeignAssets::mint( + ::RuntimeOrigin::signed(owner.clone()), + dot_at_asset_hub_kusama.into(), + owner.clone().into(), + 3_000_000_000_000, + )); + + ::Balances::set_balance( + &owner, + 3_000_000_000_000, + ); + + assert_ok!(::AssetConversion::create_pool( + ::RuntimeOrigin::signed(owner.clone()), + Box::new(xcm::v3::Parent.into()), + Box::new(dot_at_asset_hub_kusama), + )); + + assert_expected_events!( + AssetHubKusama, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::PoolCreated { .. }) => {}, + ] + ); + + assert_ok!(::AssetConversion::add_liquidity( + ::RuntimeOrigin::signed(owner.clone()), + Box::new(xcm::v3::Parent.into()), + Box::new(dot_at_asset_hub_kusama), + 1_000_000_000_000, + 2_000_000_000_000, + 1, + 1, + owner.into() + )); + + assert_expected_events!( + AssetHubKusama, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::LiquidityAdded {..}) => {}, + ] + ); + }); + + // fund the AHK's SA on AHP with the DOT tokens held in reserve + let sov_ahk_on_ahp = AssetHubPolkadot::sovereign_account_of_parachain_on_other_global_consensus( + NetworkId::Kusama, + AssetHubKusama::para_id(), + ); + AssetHubPolkadot::fund_accounts(vec![(sov_ahk_on_ahp.clone(), prefund_amount)]); + + let dots_in_reserve_on_ahp_before = + ::account_data_of(sov_ahk_on_ahp.clone()).free; + assert_eq!(dots_in_reserve_on_ahp_before, prefund_amount); + let sender_dots_before = AssetHubKusama::execute_with(|| { + type Assets = ::ForeignAssets; + >::balance(dot_at_asset_hub_kusama, &AssetHubKusamaSender::get()) + }); + assert_eq!(sender_dots_before, prefund_amount); + let receiver_dots_before = + ::account_data_of(AssetHubPolkadotReceiver::get()).free; + + let dot_at_asset_hub_kusama_latest: Location = dot_at_asset_hub_kusama.try_into().unwrap(); + let amount_to_send = ASSET_HUB_POLKADOT_ED * 1_000; + send_asset_from_asset_hub_kusama_to_asset_hub_polkadot( + dot_at_asset_hub_kusama_latest.clone(), + amount_to_send, + ); + AssetHubPolkadot::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + assert_expected_events!( + AssetHubPolkadot, + vec![ + // DOT is withdrawn from AHK's SA on AHP + RuntimeEvent::Balances( + pallet_balances::Event::Burned { who, amount } + ) => { + who: *who == sov_ahk_on_ahp, + amount: *amount == amount_to_send, + }, + // DOTs deposited to beneficiary + RuntimeEvent::Balances(pallet_balances::Event::Minted { who, .. }) => { + who: *who == AssetHubPolkadotReceiver::get(), + }, + // message processed successfully + RuntimeEvent::MessageQueue( + pallet_message_queue::Event::Processed { success: true, .. } + ) => {}, + ] + ); + }); + + let sender_dots_after = AssetHubKusama::execute_with(|| { + type Assets = ::ForeignAssets; + >::balance(dot_at_asset_hub_kusama, &AssetHubKusamaSender::get()) + }); + let receiver_dots_after = + ::account_data_of(AssetHubPolkadotReceiver::get()).free; + let dots_in_reserve_on_ahp_after = + ::account_data_of(sov_ahk_on_ahp).free; + + // Sender's balance is reduced + assert!(sender_dots_before > sender_dots_after); + // Receiver's balance is increased + assert!(receiver_dots_after > receiver_dots_before); + // Reserve balance is reduced by sent amount + assert_eq!(dots_in_reserve_on_ahp_after, dots_in_reserve_on_ahp_before - amount_to_send); +} diff --git a/integration-tests/emulated/tests/bridges/bridge-hub-polkadot/Cargo.toml b/integration-tests/emulated/tests/bridges/bridge-hub-polkadot/Cargo.toml index c7e4151cee..3d93211300 100644 --- a/integration-tests/emulated/tests/bridges/bridge-hub-polkadot/Cargo.toml +++ b/integration-tests/emulated/tests/bridges/bridge-hub-polkadot/Cargo.toml @@ -13,6 +13,7 @@ publish = false sp-runtime = { version = "32.0.0" } frame-support = { version = "29.0.0" } pallet-balances = { version = "29.0.0" } +pallet-asset-conversion = { version = "11.0.0" } pallet-assets = { version = "30.0.0" } pallet-message-queue = { version = "32.0.0" } diff --git a/integration-tests/emulated/tests/bridges/bridge-hub-polkadot/src/lib.rs b/integration-tests/emulated/tests/bridges/bridge-hub-polkadot/src/lib.rs index 31eac92781..8ff674f9b7 100644 --- a/integration-tests/emulated/tests/bridges/bridge-hub-polkadot/src/lib.rs +++ b/integration-tests/emulated/tests/bridges/bridge-hub-polkadot/src/lib.rs @@ -33,6 +33,7 @@ pub use bp_messages::LaneId; // Cumulus pub use emulated_integration_tests_common::{ accounts::ALICE, + accounts::BOB, impls::Inspect, xcm_emulator::{ assert_expected_events, bx, helpers::weight_within_threshold, Chain, Parachain as Para, diff --git a/integration-tests/emulated/tests/bridges/bridge-hub-polkadot/src/tests/asset_transfers.rs b/integration-tests/emulated/tests/bridges/bridge-hub-polkadot/src/tests/asset_transfers.rs index 7d6e8053fa..86d2a797e0 100644 --- a/integration-tests/emulated/tests/bridges/bridge-hub-polkadot/src/tests/asset_transfers.rs +++ b/integration-tests/emulated/tests/bridges/bridge-hub-polkadot/src/tests/asset_transfers.rs @@ -12,7 +12,9 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. + use crate::tests::*; +use frame_support::traits::fungible::Mutate; fn send_asset_from_asset_hub_polkadot_to_asset_hub_kusama(id: Location, amount: u128) { let destination = asset_hub_kusama_location(); @@ -176,3 +178,243 @@ fn send_ksms_from_asset_hub_polkadot_to_asset_hub_kusama() { // Reserve balance is reduced by sent amount assert_eq!(ksms_in_reserve_on_ahk_after, ksms_in_reserve_on_ahk_before - amount_to_send); } + +#[test] +fn send_dots_from_asset_hub_polkadot_to_asset_hub_kusama_fee_from_pool() { + let dot_at_asset_hub_polkadot: v3::Location = v3::Parent.into(); + let dot_at_asset_hub_kusama = + v3::Location::new(2, [v3::Junction::GlobalConsensus(v3::NetworkId::Polkadot)]); + let owner: AccountId = AssetHubKusama::account_id_of(BOB); + AssetHubKusama::force_create_foreign_asset( + dot_at_asset_hub_kusama, + owner.clone(), + false, + ASSET_MIN_BALANCE, + vec![], + ); + let sov_ahk_on_ahp = AssetHubPolkadot::sovereign_account_of_parachain_on_other_global_consensus( + NetworkId::Kusama, + AssetHubKusama::para_id(), + ); + + AssetHubKusama::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + // setup a pool to pay xcm fees with `dot_at_asset_hub_kusama` tokens + assert_ok!(::ForeignAssets::mint( + ::RuntimeOrigin::signed(owner.clone()), + dot_at_asset_hub_kusama.into(), + owner.clone().into(), + 3_000_000_000_000, + )); + + ::Balances::set_balance(&owner, 3_000_000_000_000); + + assert_ok!(::AssetConversion::create_pool( + ::RuntimeOrigin::signed(owner.clone()), + Box::new(xcm::v3::Parent.into()), + Box::new(dot_at_asset_hub_kusama), + )); + + assert_expected_events!( + AssetHubKusama, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::PoolCreated { .. }) => {}, + ] + ); + + assert_ok!(::AssetConversion::add_liquidity( + ::RuntimeOrigin::signed(owner.clone()), + Box::new(xcm::v3::Parent.into()), + Box::new(dot_at_asset_hub_kusama), + 1_000_000_000_000, + 2_000_000_000_000, + 1, + 1, + owner.into() + )); + + assert_expected_events!( + AssetHubKusama, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::LiquidityAdded {..}) => {}, + ] + ); + }); + + let dots_in_reserve_on_ahp_before = + ::account_data_of(sov_ahk_on_ahp.clone()).free; + let sender_dots_before = + ::account_data_of(AssetHubPolkadotSender::get()).free; + let receiver_dots_before = AssetHubKusama::execute_with(|| { + type Assets = ::ForeignAssets; + >::balance(dot_at_asset_hub_kusama, &AssetHubKusamaReceiver::get()) + }); + + let dot_at_asset_hub_polkadot_latest: Location = dot_at_asset_hub_polkadot.try_into().unwrap(); + let amount = ASSET_HUB_POLKADOT_ED * 1_000; + send_asset_from_asset_hub_polkadot_to_asset_hub_kusama( + dot_at_asset_hub_polkadot_latest, + amount, + ); + AssetHubKusama::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + assert_expected_events!( + AssetHubKusama, + vec![ + // issue DOTs on AHK + RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { asset_id, owner, .. }) => { + asset_id: *asset_id == dot_at_asset_hub_kusama, + owner: *owner == AssetHubKusamaReceiver::get(), + }, + // message processed successfully + RuntimeEvent::MessageQueue( + pallet_message_queue::Event::Processed { success: true, .. } + ) => {}, + ] + ); + }); + + let sender_dots_after = + ::account_data_of(AssetHubPolkadotSender::get()).free; + let receiver_dots_after = AssetHubKusama::execute_with(|| { + type Assets = ::ForeignAssets; + >::balance(dot_at_asset_hub_kusama, &AssetHubKusamaReceiver::get()) + }); + let dots_in_reserve_on_ahp_after = + ::account_data_of(sov_ahk_on_ahp).free; + + // Sender's balance is reduced + assert!(sender_dots_before > sender_dots_after); + // Receiver's balance is increased + assert!(receiver_dots_after > receiver_dots_before); + // Reserve balance is increased by sent amount + assert_eq!(dots_in_reserve_on_ahp_after, dots_in_reserve_on_ahp_before + amount); +} + +#[test] +fn send_ksms_from_asset_hub_polkadot_to_asset_hub_kusama_fee_from_pool() { + let prefund_amount = 10_000_000_000_000u128; + let ksm_at_asset_hub_polkadot = + v3::Location::new(2, [v3::Junction::GlobalConsensus(v3::NetworkId::Kusama)]); + let owner: AccountId = AssetHubPolkadot::account_id_of(BOB); + AssetHubPolkadot::force_create_foreign_asset( + ksm_at_asset_hub_polkadot, + owner.clone(), + false, + ASSET_MIN_BALANCE, + vec![(AssetHubPolkadotSender::get(), prefund_amount)], + ); + + AssetHubPolkadot::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + // setup a pool to pay xcm fees with `ksm_at_asset_hub_polkadot` tokens + assert_ok!(::ForeignAssets::mint( + ::RuntimeOrigin::signed(owner.clone()), + ksm_at_asset_hub_polkadot.into(), + owner.clone().into(), + 3_000_000_000_000, + )); + + ::Balances::set_balance( + &owner, + 3_000_000_000_000, + ); + + assert_ok!(::AssetConversion::create_pool( + ::RuntimeOrigin::signed(owner.clone()), + Box::new(xcm::v3::Parent.into()), + Box::new(ksm_at_asset_hub_polkadot), + )); + + assert_expected_events!( + AssetHubPolkadot, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::PoolCreated { .. }) => {}, + ] + ); + + assert_ok!(::AssetConversion::add_liquidity( + ::RuntimeOrigin::signed(owner.clone()), + Box::new(xcm::v3::Parent.into()), + Box::new(ksm_at_asset_hub_polkadot), + 1_000_000_000_000, + 2_000_000_000_000, + 1, + 1, + owner.clone().into() + )); + + assert_expected_events!( + AssetHubPolkadot, + vec![ + RuntimeEvent::AssetConversion(pallet_asset_conversion::Event::LiquidityAdded {..}) => {}, + ] + ); + }); + + // fund the AHP's SA on AHK with the KSM tokens held in reserve + let sov_ahp_on_ahk = AssetHubKusama::sovereign_account_of_parachain_on_other_global_consensus( + NetworkId::Polkadot, + AssetHubPolkadot::para_id(), + ); + AssetHubKusama::fund_accounts(vec![(sov_ahp_on_ahk.clone(), prefund_amount)]); + + let ksms_in_reserve_on_ahk_before = + ::account_data_of(sov_ahp_on_ahk.clone()).free; + assert_eq!(ksms_in_reserve_on_ahk_before, prefund_amount); + let sender_ksms_before = AssetHubPolkadot::execute_with(|| { + type Assets = ::ForeignAssets; + >::balance(ksm_at_asset_hub_polkadot, &AssetHubPolkadotSender::get()) + }); + assert_eq!(sender_ksms_before, prefund_amount); + let receiver_ksms_before = + ::account_data_of(AssetHubKusamaReceiver::get()).free; + + let ksm_at_asset_hub_polkadot_latest: Location = ksm_at_asset_hub_polkadot.try_into().unwrap(); + let amount_to_send = ASSET_HUB_KUSAMA_ED * 1_000; + send_asset_from_asset_hub_polkadot_to_asset_hub_kusama( + ksm_at_asset_hub_polkadot_latest, + amount_to_send, + ); + AssetHubKusama::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + assert_expected_events!( + AssetHubKusama, + vec![ + // KSM is withdrawn from AHP's SA on AHK + RuntimeEvent::Balances( + pallet_balances::Event::Burned { who, amount } + ) => { + who: *who == sov_ahp_on_ahk, + amount: *amount == amount_to_send, + }, + // KSMs deposited to beneficiary + RuntimeEvent::Balances(pallet_balances::Event::Minted { who, .. }) => { + who: *who == AssetHubKusamaReceiver::get(), + }, + // message processed successfully + RuntimeEvent::MessageQueue( + pallet_message_queue::Event::Processed { success: true, .. } + ) => {}, + ] + ); + }); + + let sender_ksms_after = AssetHubPolkadot::execute_with(|| { + type Assets = ::ForeignAssets; + >::balance(ksm_at_asset_hub_polkadot, &AssetHubPolkadotSender::get()) + }); + let receiver_ksms_after = + ::account_data_of(AssetHubKusamaReceiver::get()).free; + let ksms_in_reserve_on_ahk_after = + ::account_data_of(sov_ahp_on_ahk.clone()).free; + + // Sender's balance is reduced + assert!(sender_ksms_before > sender_ksms_after); + // Receiver's balance is increased + assert!(receiver_ksms_after > receiver_ksms_before); + // Reserve balance is reduced by sent amount + assert_eq!(ksms_in_reserve_on_ahk_after, ksms_in_reserve_on_ahk_before - amount_to_send); +} From 20d92821f5b6bbf71ae5e8d92f55961e37751c10 Mon Sep 17 00:00:00 2001 From: muharem Date: Wed, 6 Mar 2024 10:55:59 +0100 Subject: [PATCH 11/25] rustfmt --- .../asset-hub-polkadot/src/tests/swap.rs | 9 +- .../bridges/bridge-hub-kusama/src/lib.rs | 3 +- .../src/tests/asset_transfers.rs | 5 +- .../bridges/bridge-hub-polkadot/src/lib.rs | 3 +- .../asset-hub-kusama/src/xcm_config.rs | 360 +++++++++--------- .../asset-hub-kusama/tests/weight_trader.rs | 9 +- .../asset-hub-polkadot/src/xcm_config.rs | 288 +++++++------- .../asset-hub-polkadot/tests/weight_trader.rs | 13 +- 8 files changed, 341 insertions(+), 349 deletions(-) diff --git a/integration-tests/emulated/tests/assets/asset-hub-polkadot/src/tests/swap.rs b/integration-tests/emulated/tests/assets/asset-hub-polkadot/src/tests/swap.rs index a71f72fc6c..dfd2cfba85 100644 --- a/integration-tests/emulated/tests/assets/asset-hub-polkadot/src/tests/swap.rs +++ b/integration-tests/emulated/tests/assets/asset-hub-polkadot/src/tests/swap.rs @@ -113,7 +113,8 @@ fn swap_locally_on_chain_using_local_assets() { ::RuntimeOrigin::signed(AssetHubPolkadotSender::get()), asset_native, asset_one, - 1414213562273 - SYSTEM_PARA_EXISTENTIAL_DEPOSIT * 2, /* all but the 2 EDs can't be + 1414213562273 - SYSTEM_PARA_EXISTENTIAL_DEPOSIT * 2, /* all but the 2 EDs can't + * be * retrieved. */ 0, 0, @@ -156,7 +157,8 @@ fn swap_locally_on_chain_using_foreign_assets() { let penpal_as_seen_by_ah = AssetHubPolkadot::sibling_location_of(PenpalB::para_id()); let sov_penpal_on_ahk = AssetHubPolkadot::sovereign_account_id_of(penpal_as_seen_by_ah); AssetHubPolkadot::fund_accounts(vec![ - (AssetHubPolkadotSender::get().into(), 5_000_000 * POLKADOT_ED), /* An account to swap dot + (AssetHubPolkadotSender::get().into(), 5_000_000 * POLKADOT_ED), /* An account to swap + * dot * for something else. */ ]); @@ -258,8 +260,7 @@ fn swap_locally_on_chain_using_foreign_assets() { #[test] fn cannot_create_pool_from_pool_assets() { - use frame_support::traits::fungibles::Create; - use frame_support::traits::fungibles::Mutate; + use frame_support::traits::fungibles::{Create, Mutate}; let asset_native = asset_hub_polkadot_runtime::xcm_config::DotLocation::get() .try_into() diff --git a/integration-tests/emulated/tests/bridges/bridge-hub-kusama/src/lib.rs b/integration-tests/emulated/tests/bridges/bridge-hub-kusama/src/lib.rs index dfb2270f36..101d2c2b5f 100644 --- a/integration-tests/emulated/tests/bridges/bridge-hub-kusama/src/lib.rs +++ b/integration-tests/emulated/tests/bridges/bridge-hub-kusama/src/lib.rs @@ -32,8 +32,7 @@ pub use bp_messages::LaneId; // Cumulus pub use emulated_integration_tests_common::{ - accounts::ALICE, - accounts::BOB, + accounts::{ALICE, BOB}, impls::Inspect, xcm_emulator::{ assert_expected_events, bx, helpers::weight_within_threshold, Chain, Parachain as Para, diff --git a/integration-tests/emulated/tests/bridges/bridge-hub-kusama/src/tests/asset_transfers.rs b/integration-tests/emulated/tests/bridges/bridge-hub-kusama/src/tests/asset_transfers.rs index 6f14cb3b1d..f7c57a474b 100644 --- a/integration-tests/emulated/tests/bridges/bridge-hub-kusama/src/tests/asset_transfers.rs +++ b/integration-tests/emulated/tests/bridges/bridge-hub-kusama/src/tests/asset_transfers.rs @@ -314,10 +314,7 @@ fn send_dots_from_asset_hub_polkadot_to_asset_hub_kusama_fee_from_pool() { 3_000_000_000_000, )); - ::Balances::set_balance( - &owner, - 3_000_000_000_000, - ); + ::Balances::set_balance(&owner, 3_000_000_000_000); assert_ok!(::AssetConversion::create_pool( ::RuntimeOrigin::signed(owner.clone()), diff --git a/integration-tests/emulated/tests/bridges/bridge-hub-polkadot/src/lib.rs b/integration-tests/emulated/tests/bridges/bridge-hub-polkadot/src/lib.rs index 8ff674f9b7..e82ecd4410 100644 --- a/integration-tests/emulated/tests/bridges/bridge-hub-polkadot/src/lib.rs +++ b/integration-tests/emulated/tests/bridges/bridge-hub-polkadot/src/lib.rs @@ -32,8 +32,7 @@ pub use bp_messages::LaneId; // Cumulus pub use emulated_integration_tests_common::{ - accounts::ALICE, - accounts::BOB, + accounts::{ALICE, BOB}, impls::Inspect, xcm_emulator::{ assert_expected_events, bx, helpers::weight_within_threshold, Chain, Parachain as Para, diff --git a/system-parachains/asset-hubs/asset-hub-kusama/src/xcm_config.rs b/system-parachains/asset-hubs/asset-hub-kusama/src/xcm_config.rs index 0f58423baa..2d08e288b7 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/src/xcm_config.rs +++ b/system-parachains/asset-hubs/asset-hub-kusama/src/xcm_config.rs @@ -248,201 +248,199 @@ impl Contains for SafeCallFilter { match call { RuntimeCall::System(frame_system::Call::set_storage { items }) if items.iter().all(|(k, _)| { - k.eq(&bridging::XcmBridgeHubRouterBaseFee::key()) - || k.eq(&bridging::XcmBridgeHubRouterByteFee::key()) + k.eq(&bridging::XcmBridgeHubRouterBaseFee::key()) || + k.eq(&bridging::XcmBridgeHubRouterByteFee::key()) }) => - { - return true - }, + return true, _ => (), }; matches!( call, RuntimeCall::PolkadotXcm( - pallet_xcm::Call::force_xcm_version { .. } - | pallet_xcm::Call::force_default_xcm_version { .. } + pallet_xcm::Call::force_xcm_version { .. } | + pallet_xcm::Call::force_default_xcm_version { .. } ) | RuntimeCall::System( - frame_system::Call::set_heap_pages { .. } - | frame_system::Call::set_code { .. } - | frame_system::Call::set_code_without_checks { .. } - | frame_system::Call::kill_prefix { .. }, - ) | RuntimeCall::ParachainSystem(..) - | RuntimeCall::Timestamp(..) - | RuntimeCall::Balances(..) - | RuntimeCall::CollatorSelection( - pallet_collator_selection::Call::set_desired_candidates { .. } - | pallet_collator_selection::Call::set_candidacy_bond { .. } - | pallet_collator_selection::Call::register_as_candidate { .. } - | pallet_collator_selection::Call::leave_intent { .. } - | pallet_collator_selection::Call::set_invulnerables { .. } - | pallet_collator_selection::Call::add_invulnerable { .. } - | pallet_collator_selection::Call::remove_invulnerable { .. }, - ) | RuntimeCall::Session(pallet_session::Call::purge_keys { .. }) - | RuntimeCall::XcmpQueue(..) - | RuntimeCall::DmpQueue(..) - | RuntimeCall::Assets( - pallet_assets::Call::create { .. } - | pallet_assets::Call::force_create { .. } - | pallet_assets::Call::start_destroy { .. } - | pallet_assets::Call::destroy_accounts { .. } - | pallet_assets::Call::destroy_approvals { .. } - | pallet_assets::Call::finish_destroy { .. } - | pallet_assets::Call::block { .. } - | pallet_assets::Call::mint { .. } - | pallet_assets::Call::burn { .. } - | pallet_assets::Call::transfer { .. } - | pallet_assets::Call::transfer_keep_alive { .. } - | pallet_assets::Call::force_transfer { .. } - | pallet_assets::Call::freeze { .. } - | pallet_assets::Call::thaw { .. } - | pallet_assets::Call::freeze_asset { .. } - | pallet_assets::Call::thaw_asset { .. } - | pallet_assets::Call::transfer_ownership { .. } - | pallet_assets::Call::set_team { .. } - | pallet_assets::Call::set_metadata { .. } - | pallet_assets::Call::clear_metadata { .. } - | pallet_assets::Call::force_set_metadata { .. } - | pallet_assets::Call::force_clear_metadata { .. } - | pallet_assets::Call::force_asset_status { .. } - | pallet_assets::Call::approve_transfer { .. } - | pallet_assets::Call::cancel_approval { .. } - | pallet_assets::Call::force_cancel_approval { .. } - | pallet_assets::Call::transfer_approved { .. } - | pallet_assets::Call::touch { .. } - | pallet_assets::Call::touch_other { .. } - | pallet_assets::Call::refund { .. } - | pallet_assets::Call::refund_other { .. }, + frame_system::Call::set_heap_pages { .. } | + frame_system::Call::set_code { .. } | + frame_system::Call::set_code_without_checks { .. } | + frame_system::Call::kill_prefix { .. }, + ) | RuntimeCall::ParachainSystem(..) | + RuntimeCall::Timestamp(..) | + RuntimeCall::Balances(..) | + RuntimeCall::CollatorSelection( + pallet_collator_selection::Call::set_desired_candidates { .. } | + pallet_collator_selection::Call::set_candidacy_bond { .. } | + pallet_collator_selection::Call::register_as_candidate { .. } | + pallet_collator_selection::Call::leave_intent { .. } | + pallet_collator_selection::Call::set_invulnerables { .. } | + pallet_collator_selection::Call::add_invulnerable { .. } | + pallet_collator_selection::Call::remove_invulnerable { .. }, + ) | RuntimeCall::Session(pallet_session::Call::purge_keys { .. }) | + RuntimeCall::XcmpQueue(..) | + RuntimeCall::DmpQueue(..) | + RuntimeCall::Assets( + pallet_assets::Call::create { .. } | + pallet_assets::Call::force_create { .. } | + pallet_assets::Call::start_destroy { .. } | + pallet_assets::Call::destroy_accounts { .. } | + pallet_assets::Call::destroy_approvals { .. } | + pallet_assets::Call::finish_destroy { .. } | + pallet_assets::Call::block { .. } | + pallet_assets::Call::mint { .. } | + pallet_assets::Call::burn { .. } | + pallet_assets::Call::transfer { .. } | + pallet_assets::Call::transfer_keep_alive { .. } | + pallet_assets::Call::force_transfer { .. } | + pallet_assets::Call::freeze { .. } | + pallet_assets::Call::thaw { .. } | + pallet_assets::Call::freeze_asset { .. } | + pallet_assets::Call::thaw_asset { .. } | + pallet_assets::Call::transfer_ownership { .. } | + pallet_assets::Call::set_team { .. } | + pallet_assets::Call::set_metadata { .. } | + pallet_assets::Call::clear_metadata { .. } | + pallet_assets::Call::force_set_metadata { .. } | + pallet_assets::Call::force_clear_metadata { .. } | + pallet_assets::Call::force_asset_status { .. } | + pallet_assets::Call::approve_transfer { .. } | + pallet_assets::Call::cancel_approval { .. } | + pallet_assets::Call::force_cancel_approval { .. } | + pallet_assets::Call::transfer_approved { .. } | + pallet_assets::Call::touch { .. } | + pallet_assets::Call::touch_other { .. } | + pallet_assets::Call::refund { .. } | + pallet_assets::Call::refund_other { .. }, ) | RuntimeCall::ForeignAssets( - pallet_assets::Call::create { .. } - | pallet_assets::Call::force_create { .. } - | pallet_assets::Call::start_destroy { .. } - | pallet_assets::Call::destroy_accounts { .. } - | pallet_assets::Call::destroy_approvals { .. } - | pallet_assets::Call::finish_destroy { .. } - | pallet_assets::Call::block { .. } - | pallet_assets::Call::mint { .. } - | pallet_assets::Call::burn { .. } - | pallet_assets::Call::transfer { .. } - | pallet_assets::Call::transfer_keep_alive { .. } - | pallet_assets::Call::force_transfer { .. } - | pallet_assets::Call::freeze { .. } - | pallet_assets::Call::thaw { .. } - | pallet_assets::Call::freeze_asset { .. } - | pallet_assets::Call::thaw_asset { .. } - | pallet_assets::Call::transfer_ownership { .. } - | pallet_assets::Call::set_team { .. } - | pallet_assets::Call::set_metadata { .. } - | pallet_assets::Call::clear_metadata { .. } - | pallet_assets::Call::force_set_metadata { .. } - | pallet_assets::Call::force_clear_metadata { .. } - | pallet_assets::Call::force_asset_status { .. } - | pallet_assets::Call::approve_transfer { .. } - | pallet_assets::Call::cancel_approval { .. } - | pallet_assets::Call::force_cancel_approval { .. } - | pallet_assets::Call::transfer_approved { .. } - | pallet_assets::Call::touch { .. } - | pallet_assets::Call::touch_other { .. } - | pallet_assets::Call::refund { .. } - | pallet_assets::Call::refund_other { .. }, + pallet_assets::Call::create { .. } | + pallet_assets::Call::force_create { .. } | + pallet_assets::Call::start_destroy { .. } | + pallet_assets::Call::destroy_accounts { .. } | + pallet_assets::Call::destroy_approvals { .. } | + pallet_assets::Call::finish_destroy { .. } | + pallet_assets::Call::block { .. } | + pallet_assets::Call::mint { .. } | + pallet_assets::Call::burn { .. } | + pallet_assets::Call::transfer { .. } | + pallet_assets::Call::transfer_keep_alive { .. } | + pallet_assets::Call::force_transfer { .. } | + pallet_assets::Call::freeze { .. } | + pallet_assets::Call::thaw { .. } | + pallet_assets::Call::freeze_asset { .. } | + pallet_assets::Call::thaw_asset { .. } | + pallet_assets::Call::transfer_ownership { .. } | + pallet_assets::Call::set_team { .. } | + pallet_assets::Call::set_metadata { .. } | + pallet_assets::Call::clear_metadata { .. } | + pallet_assets::Call::force_set_metadata { .. } | + pallet_assets::Call::force_clear_metadata { .. } | + pallet_assets::Call::force_asset_status { .. } | + pallet_assets::Call::approve_transfer { .. } | + pallet_assets::Call::cancel_approval { .. } | + pallet_assets::Call::force_cancel_approval { .. } | + pallet_assets::Call::transfer_approved { .. } | + pallet_assets::Call::touch { .. } | + pallet_assets::Call::touch_other { .. } | + pallet_assets::Call::refund { .. } | + pallet_assets::Call::refund_other { .. }, ) | RuntimeCall::PoolAssets( - pallet_assets::Call::force_create { .. } - | pallet_assets::Call::block { .. } - | pallet_assets::Call::burn { .. } - | pallet_assets::Call::transfer { .. } - | pallet_assets::Call::transfer_keep_alive { .. } - | pallet_assets::Call::force_transfer { .. } - | pallet_assets::Call::freeze { .. } - | pallet_assets::Call::thaw { .. } - | pallet_assets::Call::freeze_asset { .. } - | pallet_assets::Call::thaw_asset { .. } - | pallet_assets::Call::transfer_ownership { .. } - | pallet_assets::Call::set_team { .. } - | pallet_assets::Call::set_metadata { .. } - | pallet_assets::Call::clear_metadata { .. } - | pallet_assets::Call::force_set_metadata { .. } - | pallet_assets::Call::force_clear_metadata { .. } - | pallet_assets::Call::force_asset_status { .. } - | pallet_assets::Call::approve_transfer { .. } - | pallet_assets::Call::cancel_approval { .. } - | pallet_assets::Call::force_cancel_approval { .. } - | pallet_assets::Call::transfer_approved { .. } - | pallet_assets::Call::touch { .. } - | pallet_assets::Call::touch_other { .. } - | pallet_assets::Call::refund { .. } - | pallet_assets::Call::refund_other { .. }, + pallet_assets::Call::force_create { .. } | + pallet_assets::Call::block { .. } | + pallet_assets::Call::burn { .. } | + pallet_assets::Call::transfer { .. } | + pallet_assets::Call::transfer_keep_alive { .. } | + pallet_assets::Call::force_transfer { .. } | + pallet_assets::Call::freeze { .. } | + pallet_assets::Call::thaw { .. } | + pallet_assets::Call::freeze_asset { .. } | + pallet_assets::Call::thaw_asset { .. } | + pallet_assets::Call::transfer_ownership { .. } | + pallet_assets::Call::set_team { .. } | + pallet_assets::Call::set_metadata { .. } | + pallet_assets::Call::clear_metadata { .. } | + pallet_assets::Call::force_set_metadata { .. } | + pallet_assets::Call::force_clear_metadata { .. } | + pallet_assets::Call::force_asset_status { .. } | + pallet_assets::Call::approve_transfer { .. } | + pallet_assets::Call::cancel_approval { .. } | + pallet_assets::Call::force_cancel_approval { .. } | + pallet_assets::Call::transfer_approved { .. } | + pallet_assets::Call::touch { .. } | + pallet_assets::Call::touch_other { .. } | + pallet_assets::Call::refund { .. } | + pallet_assets::Call::refund_other { .. }, ) | RuntimeCall::AssetConversion( - pallet_asset_conversion::Call::create_pool { .. } - | pallet_asset_conversion::Call::add_liquidity { .. } - | pallet_asset_conversion::Call::remove_liquidity { .. } - | pallet_asset_conversion::Call::swap_tokens_for_exact_tokens { .. } - | pallet_asset_conversion::Call::swap_exact_tokens_for_tokens { .. }, + pallet_asset_conversion::Call::create_pool { .. } | + pallet_asset_conversion::Call::add_liquidity { .. } | + pallet_asset_conversion::Call::remove_liquidity { .. } | + pallet_asset_conversion::Call::swap_tokens_for_exact_tokens { .. } | + pallet_asset_conversion::Call::swap_exact_tokens_for_tokens { .. }, ) | RuntimeCall::NftFractionalization( - pallet_nft_fractionalization::Call::fractionalize { .. } - | pallet_nft_fractionalization::Call::unify { .. }, + pallet_nft_fractionalization::Call::fractionalize { .. } | + pallet_nft_fractionalization::Call::unify { .. }, ) | RuntimeCall::Nfts( - pallet_nfts::Call::create { .. } - | pallet_nfts::Call::force_create { .. } - | pallet_nfts::Call::destroy { .. } - | pallet_nfts::Call::mint { .. } - | pallet_nfts::Call::force_mint { .. } - | pallet_nfts::Call::burn { .. } - | pallet_nfts::Call::transfer { .. } - | pallet_nfts::Call::lock_item_transfer { .. } - | pallet_nfts::Call::unlock_item_transfer { .. } - | pallet_nfts::Call::lock_collection { .. } - | pallet_nfts::Call::transfer_ownership { .. } - | pallet_nfts::Call::set_team { .. } - | pallet_nfts::Call::force_collection_owner { .. } - | pallet_nfts::Call::force_collection_config { .. } - | pallet_nfts::Call::approve_transfer { .. } - | pallet_nfts::Call::cancel_approval { .. } - | pallet_nfts::Call::clear_all_transfer_approvals { .. } - | pallet_nfts::Call::lock_item_properties { .. } - | pallet_nfts::Call::set_attribute { .. } - | pallet_nfts::Call::force_set_attribute { .. } - | pallet_nfts::Call::clear_attribute { .. } - | pallet_nfts::Call::approve_item_attributes { .. } - | pallet_nfts::Call::cancel_item_attributes_approval { .. } - | pallet_nfts::Call::set_metadata { .. } - | pallet_nfts::Call::clear_metadata { .. } - | pallet_nfts::Call::set_collection_metadata { .. } - | pallet_nfts::Call::clear_collection_metadata { .. } - | pallet_nfts::Call::set_accept_ownership { .. } - | pallet_nfts::Call::set_collection_max_supply { .. } - | pallet_nfts::Call::update_mint_settings { .. } - | pallet_nfts::Call::set_price { .. } - | pallet_nfts::Call::buy_item { .. } - | pallet_nfts::Call::pay_tips { .. } - | pallet_nfts::Call::create_swap { .. } - | pallet_nfts::Call::cancel_swap { .. } - | pallet_nfts::Call::claim_swap { .. }, + pallet_nfts::Call::create { .. } | + pallet_nfts::Call::force_create { .. } | + pallet_nfts::Call::destroy { .. } | + pallet_nfts::Call::mint { .. } | + pallet_nfts::Call::force_mint { .. } | + pallet_nfts::Call::burn { .. } | + pallet_nfts::Call::transfer { .. } | + pallet_nfts::Call::lock_item_transfer { .. } | + pallet_nfts::Call::unlock_item_transfer { .. } | + pallet_nfts::Call::lock_collection { .. } | + pallet_nfts::Call::transfer_ownership { .. } | + pallet_nfts::Call::set_team { .. } | + pallet_nfts::Call::force_collection_owner { .. } | + pallet_nfts::Call::force_collection_config { .. } | + pallet_nfts::Call::approve_transfer { .. } | + pallet_nfts::Call::cancel_approval { .. } | + pallet_nfts::Call::clear_all_transfer_approvals { .. } | + pallet_nfts::Call::lock_item_properties { .. } | + pallet_nfts::Call::set_attribute { .. } | + pallet_nfts::Call::force_set_attribute { .. } | + pallet_nfts::Call::clear_attribute { .. } | + pallet_nfts::Call::approve_item_attributes { .. } | + pallet_nfts::Call::cancel_item_attributes_approval { .. } | + pallet_nfts::Call::set_metadata { .. } | + pallet_nfts::Call::clear_metadata { .. } | + pallet_nfts::Call::set_collection_metadata { .. } | + pallet_nfts::Call::clear_collection_metadata { .. } | + pallet_nfts::Call::set_accept_ownership { .. } | + pallet_nfts::Call::set_collection_max_supply { .. } | + pallet_nfts::Call::update_mint_settings { .. } | + pallet_nfts::Call::set_price { .. } | + pallet_nfts::Call::buy_item { .. } | + pallet_nfts::Call::pay_tips { .. } | + pallet_nfts::Call::create_swap { .. } | + pallet_nfts::Call::cancel_swap { .. } | + pallet_nfts::Call::claim_swap { .. }, ) | RuntimeCall::Uniques( - pallet_uniques::Call::create { .. } - | pallet_uniques::Call::force_create { .. } - | pallet_uniques::Call::destroy { .. } - | pallet_uniques::Call::mint { .. } - | pallet_uniques::Call::burn { .. } - | pallet_uniques::Call::transfer { .. } - | pallet_uniques::Call::freeze { .. } - | pallet_uniques::Call::thaw { .. } - | pallet_uniques::Call::freeze_collection { .. } - | pallet_uniques::Call::thaw_collection { .. } - | pallet_uniques::Call::transfer_ownership { .. } - | pallet_uniques::Call::set_team { .. } - | pallet_uniques::Call::approve_transfer { .. } - | pallet_uniques::Call::cancel_approval { .. } - | pallet_uniques::Call::force_item_status { .. } - | pallet_uniques::Call::set_attribute { .. } - | pallet_uniques::Call::clear_attribute { .. } - | pallet_uniques::Call::set_metadata { .. } - | pallet_uniques::Call::clear_metadata { .. } - | pallet_uniques::Call::set_collection_metadata { .. } - | pallet_uniques::Call::clear_collection_metadata { .. } - | pallet_uniques::Call::set_accept_ownership { .. } - | pallet_uniques::Call::set_collection_max_supply { .. } - | pallet_uniques::Call::set_price { .. } - | pallet_uniques::Call::buy_item { .. } + pallet_uniques::Call::create { .. } | + pallet_uniques::Call::force_create { .. } | + pallet_uniques::Call::destroy { .. } | + pallet_uniques::Call::mint { .. } | + pallet_uniques::Call::burn { .. } | + pallet_uniques::Call::transfer { .. } | + pallet_uniques::Call::freeze { .. } | + pallet_uniques::Call::thaw { .. } | + pallet_uniques::Call::freeze_collection { .. } | + pallet_uniques::Call::thaw_collection { .. } | + pallet_uniques::Call::transfer_ownership { .. } | + pallet_uniques::Call::set_team { .. } | + pallet_uniques::Call::approve_transfer { .. } | + pallet_uniques::Call::cancel_approval { .. } | + pallet_uniques::Call::force_item_status { .. } | + pallet_uniques::Call::set_attribute { .. } | + pallet_uniques::Call::clear_attribute { .. } | + pallet_uniques::Call::set_metadata { .. } | + pallet_uniques::Call::clear_metadata { .. } | + pallet_uniques::Call::set_collection_metadata { .. } | + pallet_uniques::Call::clear_collection_metadata { .. } | + pallet_uniques::Call::set_accept_ownership { .. } | + pallet_uniques::Call::set_collection_max_supply { .. } | + pallet_uniques::Call::set_price { .. } | + pallet_uniques::Call::buy_item { .. } ) | RuntimeCall::ToPolkadotXcmRouter( pallet_xcm_bridge_hub_router::Call::report_bridge_status { .. } ) diff --git a/system-parachains/asset-hubs/asset-hub-kusama/tests/weight_trader.rs b/system-parachains/asset-hubs/asset-hub-kusama/tests/weight_trader.rs index d18e529530..2bc64b545f 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/tests/weight_trader.rs +++ b/system-parachains/asset-hubs/asset-hub-kusama/tests/weight_trader.rs @@ -33,9 +33,12 @@ use frame_support::{ weights::{Weight, WeightToFee as WeightToFeeT}, }; -use asset_hub_kusama_runtime::xcm_config::AssetFeeAsExistentialDepositMultiplierFeeCharger; -use asset_hub_kusama_runtime::xcm_config::TrustBackedAssetsPalletLocation; -use asset_hub_kusama_runtime::ExistentialDeposit; +use asset_hub_kusama_runtime::{ + xcm_config::{ + AssetFeeAsExistentialDepositMultiplierFeeCharger, TrustBackedAssetsPalletLocation, + }, + ExistentialDeposit, +}; use cumulus_primitives_utility::ChargeWeightInFungibles; use frame_support::assert_noop; diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/xcm_config.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/xcm_config.rs index 6b1b96927f..c91cbde4af 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/src/xcm_config.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/xcm_config.rs @@ -230,8 +230,8 @@ impl Contains for FellowshipEntities { Parachain(system_parachain::COLLECTIVES_ID), Plurality { id: BodyId::Technical, .. } ] - ) | (1, [Parachain(system_parachain::COLLECTIVES_ID), PalletInstance(64)]) - | (1, [Parachain(system_parachain::COLLECTIVES_ID), PalletInstance(65)]) + ) | (1, [Parachain(system_parachain::COLLECTIVES_ID), PalletInstance(64)]) | + (1, [Parachain(system_parachain::COLLECTIVES_ID), PalletInstance(65)]) ) } } @@ -264,160 +264,158 @@ impl Contains for SafeCallFilter { match call { RuntimeCall::System(frame_system::Call::set_storage { items }) if items.iter().all(|(k, _)| { - k.eq(&bridging::XcmBridgeHubRouterBaseFee::key()) - || k.eq(&bridging::XcmBridgeHubRouterByteFee::key()) + k.eq(&bridging::XcmBridgeHubRouterBaseFee::key()) || + k.eq(&bridging::XcmBridgeHubRouterByteFee::key()) }) => - { - return true - }, + return true, _ => (), }; matches!( call, RuntimeCall::PolkadotXcm( - pallet_xcm::Call::force_xcm_version { .. } - | pallet_xcm::Call::force_default_xcm_version { .. } + pallet_xcm::Call::force_xcm_version { .. } | + pallet_xcm::Call::force_default_xcm_version { .. } ) | RuntimeCall::System( - frame_system::Call::set_heap_pages { .. } - | frame_system::Call::set_code { .. } - | frame_system::Call::set_code_without_checks { .. } - | frame_system::Call::kill_prefix { .. }, - ) | RuntimeCall::ParachainSystem(..) - | RuntimeCall::Timestamp(..) - | RuntimeCall::Balances(..) - | RuntimeCall::CollatorSelection( - pallet_collator_selection::Call::set_desired_candidates { .. } - | pallet_collator_selection::Call::set_candidacy_bond { .. } - | pallet_collator_selection::Call::register_as_candidate { .. } - | pallet_collator_selection::Call::leave_intent { .. } - | pallet_collator_selection::Call::set_invulnerables { .. } - | pallet_collator_selection::Call::add_invulnerable { .. } - | pallet_collator_selection::Call::remove_invulnerable { .. }, - ) | RuntimeCall::Session(pallet_session::Call::purge_keys { .. }) - | RuntimeCall::XcmpQueue(..) - | RuntimeCall::DmpQueue(..) - | RuntimeCall::Assets( - pallet_assets::Call::create { .. } - | pallet_assets::Call::force_create { .. } - | pallet_assets::Call::start_destroy { .. } - | pallet_assets::Call::destroy_accounts { .. } - | pallet_assets::Call::destroy_approvals { .. } - | pallet_assets::Call::finish_destroy { .. } - | pallet_assets::Call::mint { .. } - | pallet_assets::Call::burn { .. } - | pallet_assets::Call::transfer { .. } - | pallet_assets::Call::transfer_keep_alive { .. } - | pallet_assets::Call::force_transfer { .. } - | pallet_assets::Call::freeze { .. } - | pallet_assets::Call::thaw { .. } - | pallet_assets::Call::freeze_asset { .. } - | pallet_assets::Call::thaw_asset { .. } - | pallet_assets::Call::transfer_ownership { .. } - | pallet_assets::Call::set_team { .. } - | pallet_assets::Call::set_metadata { .. } - | pallet_assets::Call::clear_metadata { .. } - | pallet_assets::Call::force_set_metadata { .. } - | pallet_assets::Call::force_clear_metadata { .. } - | pallet_assets::Call::force_asset_status { .. } - | pallet_assets::Call::approve_transfer { .. } - | pallet_assets::Call::cancel_approval { .. } - | pallet_assets::Call::force_cancel_approval { .. } - | pallet_assets::Call::transfer_approved { .. } - | pallet_assets::Call::touch { .. } - | pallet_assets::Call::refund { .. }, + frame_system::Call::set_heap_pages { .. } | + frame_system::Call::set_code { .. } | + frame_system::Call::set_code_without_checks { .. } | + frame_system::Call::kill_prefix { .. }, + ) | RuntimeCall::ParachainSystem(..) | + RuntimeCall::Timestamp(..) | + RuntimeCall::Balances(..) | + RuntimeCall::CollatorSelection( + pallet_collator_selection::Call::set_desired_candidates { .. } | + pallet_collator_selection::Call::set_candidacy_bond { .. } | + pallet_collator_selection::Call::register_as_candidate { .. } | + pallet_collator_selection::Call::leave_intent { .. } | + pallet_collator_selection::Call::set_invulnerables { .. } | + pallet_collator_selection::Call::add_invulnerable { .. } | + pallet_collator_selection::Call::remove_invulnerable { .. }, + ) | RuntimeCall::Session(pallet_session::Call::purge_keys { .. }) | + RuntimeCall::XcmpQueue(..) | + RuntimeCall::DmpQueue(..) | + RuntimeCall::Assets( + pallet_assets::Call::create { .. } | + pallet_assets::Call::force_create { .. } | + pallet_assets::Call::start_destroy { .. } | + pallet_assets::Call::destroy_accounts { .. } | + pallet_assets::Call::destroy_approvals { .. } | + pallet_assets::Call::finish_destroy { .. } | + pallet_assets::Call::mint { .. } | + pallet_assets::Call::burn { .. } | + pallet_assets::Call::transfer { .. } | + pallet_assets::Call::transfer_keep_alive { .. } | + pallet_assets::Call::force_transfer { .. } | + pallet_assets::Call::freeze { .. } | + pallet_assets::Call::thaw { .. } | + pallet_assets::Call::freeze_asset { .. } | + pallet_assets::Call::thaw_asset { .. } | + pallet_assets::Call::transfer_ownership { .. } | + pallet_assets::Call::set_team { .. } | + pallet_assets::Call::set_metadata { .. } | + pallet_assets::Call::clear_metadata { .. } | + pallet_assets::Call::force_set_metadata { .. } | + pallet_assets::Call::force_clear_metadata { .. } | + pallet_assets::Call::force_asset_status { .. } | + pallet_assets::Call::approve_transfer { .. } | + pallet_assets::Call::cancel_approval { .. } | + pallet_assets::Call::force_cancel_approval { .. } | + pallet_assets::Call::transfer_approved { .. } | + pallet_assets::Call::touch { .. } | + pallet_assets::Call::refund { .. }, ) | RuntimeCall::ForeignAssets( - pallet_assets::Call::create { .. } - | pallet_assets::Call::force_create { .. } - | pallet_assets::Call::start_destroy { .. } - | pallet_assets::Call::destroy_accounts { .. } - | pallet_assets::Call::destroy_approvals { .. } - | pallet_assets::Call::finish_destroy { .. } - | pallet_assets::Call::mint { .. } - | pallet_assets::Call::burn { .. } - | pallet_assets::Call::transfer { .. } - | pallet_assets::Call::transfer_keep_alive { .. } - | pallet_assets::Call::force_transfer { .. } - | pallet_assets::Call::freeze { .. } - | pallet_assets::Call::thaw { .. } - | pallet_assets::Call::freeze_asset { .. } - | pallet_assets::Call::thaw_asset { .. } - | pallet_assets::Call::transfer_ownership { .. } - | pallet_assets::Call::set_team { .. } - | pallet_assets::Call::set_metadata { .. } - | pallet_assets::Call::clear_metadata { .. } - | pallet_assets::Call::force_set_metadata { .. } - | pallet_assets::Call::force_clear_metadata { .. } - | pallet_assets::Call::force_asset_status { .. } - | pallet_assets::Call::approve_transfer { .. } - | pallet_assets::Call::cancel_approval { .. } - | pallet_assets::Call::force_cancel_approval { .. } - | pallet_assets::Call::transfer_approved { .. } - | pallet_assets::Call::touch { .. } - | pallet_assets::Call::refund { .. }, + pallet_assets::Call::create { .. } | + pallet_assets::Call::force_create { .. } | + pallet_assets::Call::start_destroy { .. } | + pallet_assets::Call::destroy_accounts { .. } | + pallet_assets::Call::destroy_approvals { .. } | + pallet_assets::Call::finish_destroy { .. } | + pallet_assets::Call::mint { .. } | + pallet_assets::Call::burn { .. } | + pallet_assets::Call::transfer { .. } | + pallet_assets::Call::transfer_keep_alive { .. } | + pallet_assets::Call::force_transfer { .. } | + pallet_assets::Call::freeze { .. } | + pallet_assets::Call::thaw { .. } | + pallet_assets::Call::freeze_asset { .. } | + pallet_assets::Call::thaw_asset { .. } | + pallet_assets::Call::transfer_ownership { .. } | + pallet_assets::Call::set_team { .. } | + pallet_assets::Call::set_metadata { .. } | + pallet_assets::Call::clear_metadata { .. } | + pallet_assets::Call::force_set_metadata { .. } | + pallet_assets::Call::force_clear_metadata { .. } | + pallet_assets::Call::force_asset_status { .. } | + pallet_assets::Call::approve_transfer { .. } | + pallet_assets::Call::cancel_approval { .. } | + pallet_assets::Call::force_cancel_approval { .. } | + pallet_assets::Call::transfer_approved { .. } | + pallet_assets::Call::touch { .. } | + pallet_assets::Call::refund { .. }, ) | RuntimeCall::Nfts( - pallet_nfts::Call::create { .. } - | pallet_nfts::Call::force_create { .. } - | pallet_nfts::Call::destroy { .. } - | pallet_nfts::Call::mint { .. } - | pallet_nfts::Call::force_mint { .. } - | pallet_nfts::Call::burn { .. } - | pallet_nfts::Call::transfer { .. } - | pallet_nfts::Call::lock_item_transfer { .. } - | pallet_nfts::Call::unlock_item_transfer { .. } - | pallet_nfts::Call::lock_collection { .. } - | pallet_nfts::Call::transfer_ownership { .. } - | pallet_nfts::Call::set_team { .. } - | pallet_nfts::Call::force_collection_owner { .. } - | pallet_nfts::Call::force_collection_config { .. } - | pallet_nfts::Call::approve_transfer { .. } - | pallet_nfts::Call::cancel_approval { .. } - | pallet_nfts::Call::clear_all_transfer_approvals { .. } - | pallet_nfts::Call::lock_item_properties { .. } - | pallet_nfts::Call::set_attribute { .. } - | pallet_nfts::Call::force_set_attribute { .. } - | pallet_nfts::Call::clear_attribute { .. } - | pallet_nfts::Call::approve_item_attributes { .. } - | pallet_nfts::Call::cancel_item_attributes_approval { .. } - | pallet_nfts::Call::set_metadata { .. } - | pallet_nfts::Call::clear_metadata { .. } - | pallet_nfts::Call::set_collection_metadata { .. } - | pallet_nfts::Call::clear_collection_metadata { .. } - | pallet_nfts::Call::set_accept_ownership { .. } - | pallet_nfts::Call::set_collection_max_supply { .. } - | pallet_nfts::Call::update_mint_settings { .. } - | pallet_nfts::Call::set_price { .. } - | pallet_nfts::Call::buy_item { .. } - | pallet_nfts::Call::pay_tips { .. } - | pallet_nfts::Call::create_swap { .. } - | pallet_nfts::Call::cancel_swap { .. } - | pallet_nfts::Call::claim_swap { .. }, + pallet_nfts::Call::create { .. } | + pallet_nfts::Call::force_create { .. } | + pallet_nfts::Call::destroy { .. } | + pallet_nfts::Call::mint { .. } | + pallet_nfts::Call::force_mint { .. } | + pallet_nfts::Call::burn { .. } | + pallet_nfts::Call::transfer { .. } | + pallet_nfts::Call::lock_item_transfer { .. } | + pallet_nfts::Call::unlock_item_transfer { .. } | + pallet_nfts::Call::lock_collection { .. } | + pallet_nfts::Call::transfer_ownership { .. } | + pallet_nfts::Call::set_team { .. } | + pallet_nfts::Call::force_collection_owner { .. } | + pallet_nfts::Call::force_collection_config { .. } | + pallet_nfts::Call::approve_transfer { .. } | + pallet_nfts::Call::cancel_approval { .. } | + pallet_nfts::Call::clear_all_transfer_approvals { .. } | + pallet_nfts::Call::lock_item_properties { .. } | + pallet_nfts::Call::set_attribute { .. } | + pallet_nfts::Call::force_set_attribute { .. } | + pallet_nfts::Call::clear_attribute { .. } | + pallet_nfts::Call::approve_item_attributes { .. } | + pallet_nfts::Call::cancel_item_attributes_approval { .. } | + pallet_nfts::Call::set_metadata { .. } | + pallet_nfts::Call::clear_metadata { .. } | + pallet_nfts::Call::set_collection_metadata { .. } | + pallet_nfts::Call::clear_collection_metadata { .. } | + pallet_nfts::Call::set_accept_ownership { .. } | + pallet_nfts::Call::set_collection_max_supply { .. } | + pallet_nfts::Call::update_mint_settings { .. } | + pallet_nfts::Call::set_price { .. } | + pallet_nfts::Call::buy_item { .. } | + pallet_nfts::Call::pay_tips { .. } | + pallet_nfts::Call::create_swap { .. } | + pallet_nfts::Call::cancel_swap { .. } | + pallet_nfts::Call::claim_swap { .. }, ) | RuntimeCall::Uniques( - pallet_uniques::Call::create { .. } - | pallet_uniques::Call::force_create { .. } - | pallet_uniques::Call::destroy { .. } - | pallet_uniques::Call::mint { .. } - | pallet_uniques::Call::burn { .. } - | pallet_uniques::Call::transfer { .. } - | pallet_uniques::Call::freeze { .. } - | pallet_uniques::Call::thaw { .. } - | pallet_uniques::Call::freeze_collection { .. } - | pallet_uniques::Call::thaw_collection { .. } - | pallet_uniques::Call::transfer_ownership { .. } - | pallet_uniques::Call::set_team { .. } - | pallet_uniques::Call::approve_transfer { .. } - | pallet_uniques::Call::cancel_approval { .. } - | pallet_uniques::Call::force_item_status { .. } - | pallet_uniques::Call::set_attribute { .. } - | pallet_uniques::Call::clear_attribute { .. } - | pallet_uniques::Call::set_metadata { .. } - | pallet_uniques::Call::clear_metadata { .. } - | pallet_uniques::Call::set_collection_metadata { .. } - | pallet_uniques::Call::clear_collection_metadata { .. } - | pallet_uniques::Call::set_accept_ownership { .. } - | pallet_uniques::Call::set_collection_max_supply { .. } - | pallet_uniques::Call::set_price { .. } - | pallet_uniques::Call::buy_item { .. } + pallet_uniques::Call::create { .. } | + pallet_uniques::Call::force_create { .. } | + pallet_uniques::Call::destroy { .. } | + pallet_uniques::Call::mint { .. } | + pallet_uniques::Call::burn { .. } | + pallet_uniques::Call::transfer { .. } | + pallet_uniques::Call::freeze { .. } | + pallet_uniques::Call::thaw { .. } | + pallet_uniques::Call::freeze_collection { .. } | + pallet_uniques::Call::thaw_collection { .. } | + pallet_uniques::Call::transfer_ownership { .. } | + pallet_uniques::Call::set_team { .. } | + pallet_uniques::Call::approve_transfer { .. } | + pallet_uniques::Call::cancel_approval { .. } | + pallet_uniques::Call::force_item_status { .. } | + pallet_uniques::Call::set_attribute { .. } | + pallet_uniques::Call::clear_attribute { .. } | + pallet_uniques::Call::set_metadata { .. } | + pallet_uniques::Call::clear_metadata { .. } | + pallet_uniques::Call::set_collection_metadata { .. } | + pallet_uniques::Call::clear_collection_metadata { .. } | + pallet_uniques::Call::set_accept_ownership { .. } | + pallet_uniques::Call::set_collection_max_supply { .. } | + pallet_uniques::Call::set_price { .. } | + pallet_uniques::Call::buy_item { .. } ) | RuntimeCall::ToKusamaXcmRouter( pallet_xcm_bridge_hub_router::Call::report_bridge_status { .. } ) diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/tests/weight_trader.rs b/system-parachains/asset-hubs/asset-hub-polkadot/tests/weight_trader.rs index 4bbfcf64ff..e29fb78d63 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/tests/weight_trader.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/tests/weight_trader.rs @@ -15,22 +15,19 @@ //! Tests for `WeighTrader` type of XCM Executor. -use asset_hub_polkadot_runtime::xcm_config::AssetFeeAsExistentialDepositMultiplierFeeCharger; -use asset_hub_polkadot_runtime::xcm_config::TrustBackedAssetsPalletLocation; -use asset_hub_polkadot_runtime::ExistentialDeposit; use asset_hub_polkadot_runtime::{ xcm_config::{ - DotLocation, DotLocationV3, StakingPot, TrustBackedAssetsPalletLocationV3, XcmConfig, + AssetFeeAsExistentialDepositMultiplierFeeCharger, DotLocation, DotLocationV3, StakingPot, + TrustBackedAssetsPalletLocation, TrustBackedAssetsPalletLocationV3, XcmConfig, }, - AllPalletsWithoutSystem, AssetConversion, Assets, Balances, ForeignAssets, Runtime, - SessionKeys, + AllPalletsWithoutSystem, AssetConversion, Assets, Balances, ExistentialDeposit, ForeignAssets, + Runtime, SessionKeys, }; use asset_test_utils::ExtBuilder; use assets_common::AssetIdForTrustBackedAssetsConvert; use cumulus_primitives_utility::ChargeWeightInFungibles; -use frame_support::assert_noop; use frame_support::{ - assert_ok, + assert_noop, assert_ok, traits::{ fungible::{Inspect, Mutate}, fungibles::{Create, Inspect as FungiblesInspect, Mutate as FungiblesMutate}, From fdad8b3dc22dac5201d7845eec3689b1913ac403 Mon Sep 17 00:00:00 2001 From: muharem Date: Wed, 6 Mar 2024 11:25:12 +0100 Subject: [PATCH 12/25] cargo lock and comment fix --- Cargo.lock | 2 ++ system-parachains/asset-hubs/asset-hub-kusama/src/xcm_config.rs | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 8948b5c9a7..cb9a014f56 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1330,6 +1330,7 @@ dependencies = [ "integration-tests-helpers", "kusama-polkadot-system-emulated-network", "kusama-system-emulated-network", + "pallet-asset-conversion", "pallet-assets", "pallet-balances", "pallet-bridge-messages", @@ -1450,6 +1451,7 @@ dependencies = [ "frame-support", "integration-tests-helpers", "kusama-polkadot-system-emulated-network", + "pallet-asset-conversion", "pallet-assets", "pallet-balances", "pallet-bridge-messages", diff --git a/system-parachains/asset-hubs/asset-hub-kusama/src/xcm_config.rs b/system-parachains/asset-hubs/asset-hub-kusama/src/xcm_config.rs index 2d08e288b7..ca67e30b1d 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/src/xcm_config.rs +++ b/system-parachains/asset-hubs/asset-hub-kusama/src/xcm_config.rs @@ -532,7 +532,7 @@ impl xcm_executor::Config for XcmConfig { >; type Trader = ( UsingComponents>, - // This trader allows to pay with any assets exchangeable to DOT with + // This trader allows to pay with any assets exchangeable to KSM with // [`AssetConversion`]. cumulus_primitives_utility::SwapFirstAssetTrader< KsmLocationV3, From 55c13d634a260873a98aadf14ae4fa85fa2a91e7 Mon Sep 17 00:00:00 2001 From: muharem Date: Wed, 6 Mar 2024 11:46:53 +0100 Subject: [PATCH 13/25] clippy fix --- .../assets/asset-hub-kusama/src/tests/swap.rs | 22 ++++++++--------- .../asset-hub-polkadot/src/tests/swap.rs | 22 ++++++++--------- .../src/tests/asset_transfers.rs | 8 +++---- .../src/tests/asset_transfers.rs | 8 +++---- .../asset-hub-kusama/tests/tests.rs | 24 +++++++++---------- .../asset-hub-polkadot/tests/tests.rs | 24 +++++++++---------- 6 files changed, 54 insertions(+), 54 deletions(-) diff --git a/integration-tests/emulated/tests/assets/asset-hub-kusama/src/tests/swap.rs b/integration-tests/emulated/tests/assets/asset-hub-kusama/src/tests/swap.rs index 29f8d71065..7b4a14af89 100644 --- a/integration-tests/emulated/tests/assets/asset-hub-kusama/src/tests/swap.rs +++ b/integration-tests/emulated/tests/assets/asset-hub-kusama/src/tests/swap.rs @@ -71,7 +71,7 @@ fn swap_locally_on_chain_using_local_assets() { 2_000_000_000_000, 0, 0, - AssetHubKusamaSender::get().into() + AssetHubKusamaSender::get() )); assert_expected_events!( @@ -89,7 +89,7 @@ fn swap_locally_on_chain_using_local_assets() { path, 100, 1, - AssetHubKusamaSender::get().into(), + AssetHubKusamaSender::get(), true ) ); @@ -112,7 +112,7 @@ fn swap_locally_on_chain_using_local_assets() { * retrieved. */ 0, 0, - AssetHubKusamaSender::get().into(), + AssetHubKusamaSender::get(), )); }); } @@ -150,7 +150,7 @@ fn swap_locally_on_chain_using_foreign_assets() { let penpal_as_seen_by_ah = AssetHubKusama::sibling_location_of(PenpalA::para_id()); let sov_penpal_on_ahk = AssetHubKusama::sovereign_account_id_of(penpal_as_seen_by_ah); AssetHubKusama::fund_accounts(vec![ - (AssetHubKusamaSender::get().into(), 5_000_000 * KUSAMA_ED), /* An account to swap dot + (AssetHubKusamaSender::get(), 5_000_000 * KUSAMA_ED), /* An account to swap dot * for something else. */ ]); @@ -163,7 +163,7 @@ fn swap_locally_on_chain_using_foreign_assets() { type RuntimeEvent = ::RuntimeEvent; // 3. Mint foreign asset (in reality this should be a teleport or some such) assert_ok!(::ForeignAssets::mint( - ::RuntimeOrigin::signed(sov_penpal_on_ahk.clone().into()), + ::RuntimeOrigin::signed(sov_penpal_on_ahk.clone()), foreign_asset_at_asset_hub_kusama, sov_penpal_on_ahk.clone().into(), 3_000_000_000_000, @@ -199,7 +199,7 @@ fn swap_locally_on_chain_using_foreign_assets() { 2_000_000_000_000, 0, 0, - sov_penpal_on_ahk.clone().into() + sov_penpal_on_ahk.clone() )); assert_expected_events!( @@ -220,7 +220,7 @@ fn swap_locally_on_chain_using_foreign_assets() { path, 100000, 1000, - AssetHubKusamaSender::get().into(), + AssetHubKusamaSender::get(), true ) ); @@ -243,7 +243,7 @@ fn swap_locally_on_chain_using_foreign_assets() { 1414213562273 - 2_000_000_000, // all but the 2 EDs can't be retrieved. 0, 0, - sov_penpal_on_ahk.clone().into(), + sov_penpal_on_ahk.clone(), )); }); } @@ -264,7 +264,7 @@ fn cannot_create_pool_from_pool_assets() { assert_ok!(::PoolAssets::create( ::RuntimeOrigin::signed(pool_owner_account_id.clone()), - ASSET_ID.into(), + ASSET_ID, pool_owner_account_id.clone().into(), 1000, )); @@ -272,7 +272,7 @@ fn cannot_create_pool_from_pool_assets() { assert_ok!(::PoolAssets::mint( ::RuntimeOrigin::signed(pool_owner_account_id), - ASSET_ID.into(), + ASSET_ID, AssetHubKusamaSender::get().into(), 3_000_000_000_000, )); @@ -343,7 +343,7 @@ fn pay_xcm_fee_with_some_asset_swapped_for_native() { 2_000_000_000_000, 0, 0, - AssetHubKusamaSender::get().into() + AssetHubKusamaSender::get() )); assert_expected_events!( diff --git a/integration-tests/emulated/tests/assets/asset-hub-polkadot/src/tests/swap.rs b/integration-tests/emulated/tests/assets/asset-hub-polkadot/src/tests/swap.rs index dfd2cfba85..4ec0f01492 100644 --- a/integration-tests/emulated/tests/assets/asset-hub-polkadot/src/tests/swap.rs +++ b/integration-tests/emulated/tests/assets/asset-hub-polkadot/src/tests/swap.rs @@ -75,7 +75,7 @@ fn swap_locally_on_chain_using_local_assets() { 2_000_000_000_000, 0, 0, - AssetHubPolkadotSender::get().into() + AssetHubPolkadotSender::get() )); assert_expected_events!( @@ -93,7 +93,7 @@ fn swap_locally_on_chain_using_local_assets() { path, 100, 1, - AssetHubPolkadotSender::get().into(), + AssetHubPolkadotSender::get(), true ) ); @@ -118,7 +118,7 @@ fn swap_locally_on_chain_using_local_assets() { * retrieved. */ 0, 0, - AssetHubPolkadotSender::get().into(), + AssetHubPolkadotSender::get(), ) ); }); @@ -157,7 +157,7 @@ fn swap_locally_on_chain_using_foreign_assets() { let penpal_as_seen_by_ah = AssetHubPolkadot::sibling_location_of(PenpalB::para_id()); let sov_penpal_on_ahk = AssetHubPolkadot::sovereign_account_id_of(penpal_as_seen_by_ah); AssetHubPolkadot::fund_accounts(vec![ - (AssetHubPolkadotSender::get().into(), 5_000_000 * POLKADOT_ED), /* An account to swap + (AssetHubPolkadotSender::get(), 5_000_000 * POLKADOT_ED), /* An account to swap * dot * for something else. */ ]); @@ -171,7 +171,7 @@ fn swap_locally_on_chain_using_foreign_assets() { type RuntimeEvent = ::RuntimeEvent; // 3. Mint foreign asset (in reality this should be a teleport or some such) assert_ok!(::ForeignAssets::mint( - ::RuntimeOrigin::signed(sov_penpal_on_ahk.clone().into()), + ::RuntimeOrigin::signed(sov_penpal_on_ahk.clone()), foreign_asset_at_asset_hub_polkadot, sov_penpal_on_ahk.clone().into(), 3_000_000_000_000, @@ -207,7 +207,7 @@ fn swap_locally_on_chain_using_foreign_assets() { 2_000_000_000_000, 0, 0, - sov_penpal_on_ahk.clone().into() + sov_penpal_on_ahk.clone() )); assert_expected_events!( @@ -228,7 +228,7 @@ fn swap_locally_on_chain_using_foreign_assets() { path, 100000, 1000, - AssetHubPolkadotSender::get().into(), + AssetHubPolkadotSender::get(), true ) ); @@ -252,7 +252,7 @@ fn swap_locally_on_chain_using_foreign_assets() { 1414213562273 - 2_000_000_000, // all but the 2 EDs can't be retrieved. 0, 0, - sov_penpal_on_ahk.clone().into(), + sov_penpal_on_ahk.clone(), ) ); }); @@ -274,7 +274,7 @@ fn cannot_create_pool_from_pool_assets() { AssetHubPolkadot::execute_with(|| { assert_ok!( <::PoolAssets as Create<_>>::create( - ASSET_ID.into(), + ASSET_ID, AssetHubPolkadotSender::get(), false, 1000, @@ -283,7 +283,7 @@ fn cannot_create_pool_from_pool_assets() { assert!(::PoolAssets::asset_exists(ASSET_ID)); assert_ok!(::PoolAssets::mint_into( - ASSET_ID.into(), + ASSET_ID, &AssetHubPolkadotSender::get(), 3_000_000_000_000, )); @@ -361,7 +361,7 @@ fn pay_xcm_fee_with_some_asset_swapped_for_native() { 2_000_000_000_000, 0, 0, - AssetHubPolkadotSender::get().into() + AssetHubPolkadotSender::get() )); assert_expected_events!( diff --git a/integration-tests/emulated/tests/bridges/bridge-hub-kusama/src/tests/asset_transfers.rs b/integration-tests/emulated/tests/bridges/bridge-hub-kusama/src/tests/asset_transfers.rs index f7c57a474b..5d2ff390cb 100644 --- a/integration-tests/emulated/tests/bridges/bridge-hub-kusama/src/tests/asset_transfers.rs +++ b/integration-tests/emulated/tests/bridges/bridge-hub-kusama/src/tests/asset_transfers.rs @@ -200,7 +200,7 @@ fn send_ksms_from_asset_hub_kusama_to_asset_hub_polkadot_fee_from_pool() { // setup a pool to pay xcm fees with `ksm_at_asset_hub_polkadot` tokens assert_ok!(::ForeignAssets::mint( ::RuntimeOrigin::signed(AssetHubPolkadotSender::get()), - ksm_at_asset_hub_polkadot.into(), + ksm_at_asset_hub_polkadot, AssetHubPolkadotSender::get().into(), 3_000_000_000_000, )); @@ -231,7 +231,7 @@ fn send_ksms_from_asset_hub_kusama_to_asset_hub_polkadot_fee_from_pool() { 2_000_000_000_000, 1, 1, - AssetHubPolkadotSender::get().into() + AssetHubPolkadotSender::get() )); assert_expected_events!( @@ -309,7 +309,7 @@ fn send_dots_from_asset_hub_polkadot_to_asset_hub_kusama_fee_from_pool() { // setup a pool to pay xcm fees with `dot_at_asset_hub_kusama` tokens assert_ok!(::ForeignAssets::mint( ::RuntimeOrigin::signed(owner.clone()), - dot_at_asset_hub_kusama.into(), + dot_at_asset_hub_kusama, owner.clone().into(), 3_000_000_000_000, )); @@ -337,7 +337,7 @@ fn send_dots_from_asset_hub_polkadot_to_asset_hub_kusama_fee_from_pool() { 2_000_000_000_000, 1, 1, - owner.into() + owner )); assert_expected_events!( diff --git a/integration-tests/emulated/tests/bridges/bridge-hub-polkadot/src/tests/asset_transfers.rs b/integration-tests/emulated/tests/bridges/bridge-hub-polkadot/src/tests/asset_transfers.rs index 86d2a797e0..14a49de48c 100644 --- a/integration-tests/emulated/tests/bridges/bridge-hub-polkadot/src/tests/asset_transfers.rs +++ b/integration-tests/emulated/tests/bridges/bridge-hub-polkadot/src/tests/asset_transfers.rs @@ -203,7 +203,7 @@ fn send_dots_from_asset_hub_polkadot_to_asset_hub_kusama_fee_from_pool() { // setup a pool to pay xcm fees with `dot_at_asset_hub_kusama` tokens assert_ok!(::ForeignAssets::mint( ::RuntimeOrigin::signed(owner.clone()), - dot_at_asset_hub_kusama.into(), + dot_at_asset_hub_kusama, owner.clone().into(), 3_000_000_000_000, )); @@ -231,7 +231,7 @@ fn send_dots_from_asset_hub_polkadot_to_asset_hub_kusama_fee_from_pool() { 2_000_000_000_000, 1, 1, - owner.into() + owner )); assert_expected_events!( @@ -312,7 +312,7 @@ fn send_ksms_from_asset_hub_polkadot_to_asset_hub_kusama_fee_from_pool() { // setup a pool to pay xcm fees with `ksm_at_asset_hub_polkadot` tokens assert_ok!(::ForeignAssets::mint( ::RuntimeOrigin::signed(owner.clone()), - ksm_at_asset_hub_polkadot.into(), + ksm_at_asset_hub_polkadot, owner.clone().into(), 3_000_000_000_000, )); @@ -343,7 +343,7 @@ fn send_ksms_from_asset_hub_polkadot_to_asset_hub_kusama_fee_from_pool() { 2_000_000_000_000, 1, 1, - owner.clone().into() + owner.clone() )); assert_expected_events!( diff --git a/system-parachains/asset-hubs/asset-hub-kusama/tests/tests.rs b/system-parachains/asset-hubs/asset-hub-kusama/tests/tests.rs index 6219265a26..5daa21e606 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/tests/tests.rs +++ b/system-parachains/asset-hubs/asset-hub-kusama/tests/tests.rs @@ -90,26 +90,26 @@ fn setup_pool_for_paying_fees_with_foreign_assets( let _ = Balances::force_set_balance( RuntimeOrigin::root(), pool_owner.clone().into(), - (existential_deposit + pool_liquidity).mul(2).into(), + (existential_deposit + pool_liquidity).mul(2), ); assert_ok!(ForeignAssets::mint( RuntimeOrigin::signed(foreign_asset_owner), - foreign_asset_id_location.into(), + foreign_asset_id_location, pool_owner.clone().into(), - (foreign_asset_id_minimum_balance + pool_liquidity).mul(2).into(), + (foreign_asset_id_minimum_balance + pool_liquidity).mul(2), )); assert_ok!(AssetConversion::create_pool( RuntimeOrigin::signed(pool_owner.clone()), - Box::new(native_asset.into()), - Box::new(foreign_asset_id_location.into()) + Box::new(native_asset), + Box::new(foreign_asset_id_location) )); assert_ok!(AssetConversion::add_liquidity( RuntimeOrigin::signed(pool_owner.clone()), - Box::new(native_asset.into()), - Box::new(foreign_asset_id_location.into()), + Box::new(native_asset), + Box::new(foreign_asset_id_location), pool_liquidity, pool_liquidity, 1, @@ -377,7 +377,7 @@ asset_test_utils::include_create_and_manage_foreign_assets_for_local_consensus_p ); fn bridging_to_asset_hub_polkadot() -> TestBridgingConfig { - let _ = PolkadotXcm::force_xcm_version( + PolkadotXcm::force_xcm_version( RuntimeOrigin::root(), Box::new(bridging::to_polkadot::AssetHubPolkadot::get()), XCM_VERSION, @@ -472,7 +472,7 @@ fn receive_reserve_asset_deposited_dot_from_asset_hub_polkadot_fees_paid_by_pool // check now foreign asset for staking pot assert_eq!( ForeignAssets::balance( - foreign_asset_id_location.into(), + foreign_asset_id_location, &staking_pot ), 0 @@ -486,7 +486,7 @@ fn receive_reserve_asset_deposited_dot_from_asset_hub_polkadot_fees_paid_by_pool // staking pot receives no foreign assets assert_eq!( ForeignAssets::balance( - foreign_asset_id_location.into(), + foreign_asset_id_location, &staking_pot ), 0 @@ -535,7 +535,7 @@ fn receive_reserve_asset_deposited_dot_from_asset_hub_polkadot_fees_paid_by_suff // check block author before assert_eq!( ForeignAssets::balance( - foreign_asset_id_location.into(), + foreign_asset_id_location, &block_author_account ), 0 @@ -545,7 +545,7 @@ fn receive_reserve_asset_deposited_dot_from_asset_hub_polkadot_fees_paid_by_suff // `TakeFirstAssetTrader` puts fees to the block author assert!( ForeignAssets::balance( - foreign_asset_id_location.into(), + foreign_asset_id_location, &block_author_account ) > 0 ); diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/tests/tests.rs b/system-parachains/asset-hubs/asset-hub-polkadot/tests/tests.rs index 8848753291..867aa366f6 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/tests/tests.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/tests/tests.rs @@ -92,26 +92,26 @@ fn setup_pool_for_paying_fees_with_foreign_assets( let _ = Balances::force_set_balance( RuntimeOrigin::root(), pool_owner.clone().into(), - (existential_deposit + pool_liquidity).mul(2).into(), + (existential_deposit + pool_liquidity).mul(2), ); assert_ok!(ForeignAssets::mint( RuntimeOrigin::signed(foreign_asset_owner), - foreign_asset_id_location.into(), + foreign_asset_id_location, pool_owner.clone().into(), - (foreign_asset_id_minimum_balance + pool_liquidity).mul(2).into(), + (foreign_asset_id_minimum_balance + pool_liquidity).mul(2), )); assert_ok!(AssetConversion::create_pool( RuntimeOrigin::signed(pool_owner.clone()), - Box::new(native_asset.into()), - Box::new(foreign_asset_id_location.into()) + Box::new(native_asset), + Box::new(foreign_asset_id_location) )); assert_ok!(AssetConversion::add_liquidity( RuntimeOrigin::signed(pool_owner.clone()), - Box::new(native_asset.into()), - Box::new(foreign_asset_id_location.into()), + Box::new(native_asset), + Box::new(foreign_asset_id_location), pool_liquidity, pool_liquidity, 1, @@ -379,7 +379,7 @@ asset_test_utils::include_create_and_manage_foreign_assets_for_local_consensus_p ); fn bridging_to_asset_hub_kusama() -> TestBridgingConfig { - let _ = PolkadotXcm::force_xcm_version( + PolkadotXcm::force_xcm_version( RuntimeOrigin::root(), Box::new(bridging::to_kusama::AssetHubKusama::get()), XCM_VERSION, @@ -472,7 +472,7 @@ fn receive_reserve_asset_deposited_ksm_from_asset_hub_kusama_fees_paid_by_pool_s // check now foreign asset for staking pot assert_eq!( ForeignAssets::balance( - foreign_asset_id_location.into(), + foreign_asset_id_location, &staking_pot ), 0 @@ -486,7 +486,7 @@ fn receive_reserve_asset_deposited_ksm_from_asset_hub_kusama_fees_paid_by_pool_s // staking pot receives no foreign assets assert_eq!( ForeignAssets::balance( - foreign_asset_id_location.into(), + foreign_asset_id_location, &staking_pot ), 0 @@ -532,7 +532,7 @@ fn receive_reserve_asset_deposited_ksm_from_asset_hub_kusama_fees_paid_by_suffic // check block author before assert_eq!( ForeignAssets::balance( - foreign_asset_id_location.into(), + foreign_asset_id_location, &block_author_account ), 0 @@ -542,7 +542,7 @@ fn receive_reserve_asset_deposited_ksm_from_asset_hub_kusama_fees_paid_by_suffic // `TakeFirstAssetTrader` puts fees to the block author assert!( ForeignAssets::balance( - foreign_asset_id_location.into(), + foreign_asset_id_location, &block_author_account ) > 0 ); From 593f969056bbd9bb7c9c4888352bcbb3c249e1d6 Mon Sep 17 00:00:00 2001 From: muharem Date: Wed, 6 Mar 2024 11:54:54 +0100 Subject: [PATCH 14/25] rustfmt --- .../emulated/tests/assets/asset-hub-kusama/src/tests/swap.rs | 2 +- .../tests/assets/asset-hub-polkadot/src/tests/swap.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/integration-tests/emulated/tests/assets/asset-hub-kusama/src/tests/swap.rs b/integration-tests/emulated/tests/assets/asset-hub-kusama/src/tests/swap.rs index 7b4a14af89..e3d3fec767 100644 --- a/integration-tests/emulated/tests/assets/asset-hub-kusama/src/tests/swap.rs +++ b/integration-tests/emulated/tests/assets/asset-hub-kusama/src/tests/swap.rs @@ -151,7 +151,7 @@ fn swap_locally_on_chain_using_foreign_assets() { let sov_penpal_on_ahk = AssetHubKusama::sovereign_account_id_of(penpal_as_seen_by_ah); AssetHubKusama::fund_accounts(vec![ (AssetHubKusamaSender::get(), 5_000_000 * KUSAMA_ED), /* An account to swap dot - * for something else. */ + * for something else. */ ]); AssetHubKusama::execute_with(|| { diff --git a/integration-tests/emulated/tests/assets/asset-hub-polkadot/src/tests/swap.rs b/integration-tests/emulated/tests/assets/asset-hub-polkadot/src/tests/swap.rs index 4ec0f01492..ca8b44e118 100644 --- a/integration-tests/emulated/tests/assets/asset-hub-polkadot/src/tests/swap.rs +++ b/integration-tests/emulated/tests/assets/asset-hub-polkadot/src/tests/swap.rs @@ -158,8 +158,8 @@ fn swap_locally_on_chain_using_foreign_assets() { let sov_penpal_on_ahk = AssetHubPolkadot::sovereign_account_id_of(penpal_as_seen_by_ah); AssetHubPolkadot::fund_accounts(vec![ (AssetHubPolkadotSender::get(), 5_000_000 * POLKADOT_ED), /* An account to swap - * dot - * for something else. */ + * dot + * for something else. */ ]); AssetHubPolkadot::execute_with(|| { From 55614c3ca5f323ff2a1ae06d98db72bad10565f3 Mon Sep 17 00:00:00 2001 From: muharem Date: Wed, 6 Mar 2024 11:58:06 +0100 Subject: [PATCH 15/25] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa688224a6..f4686459a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Feature for enabling debug prints in the Polkadot and Kusama runtime ([polkadot-fellows/runtimes#85](https://github.com/polkadot-fellows/runtimes/pull/85)) - Added new "Wish for Change" track ([polkadot-fellows/runtimes#184](https://github.com/polkadot-fellows/runtimes/pull/184)) - Enable Coretime and on-demand on Kusama ([polkadot-fellows/runtimes#159](https://github.com/polkadot-fellows/runtimes/pull/159) +- Asset Conversion setup for Polkadot Asset Hub, and XCM Swap Weight Trader for both Asset Hubs ([polkadot-fellows/runtimes#218](https://github.com/polkadot-fellows/runtimes/pull/218)) ### Changed From 6144fbb11720e32369b3527d0d0ebcb8dd8e415d Mon Sep 17 00:00:00 2001 From: muharem Date: Wed, 6 Mar 2024 12:48:01 +0100 Subject: [PATCH 16/25] add TODO --- system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs index 11359a2a3b..73869a5f56 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs @@ -827,6 +827,7 @@ impl pallet_assets::Config for Runtime { type CreateOrigin = NeverEnsureOrigin; type ForceOrigin = AssetsForceOrigin; type AssetDeposit = ConstU128<0>; + // TODO any? type AssetAccountDeposit = ConstU128<0>; type MetadataDepositBase = ConstU128<0>; type MetadataDepositPerByte = ConstU128<0>; From 1397dc9cb800f9d454eda4181df19793a710ea18 Mon Sep 17 00:00:00 2001 From: muharem Date: Wed, 6 Mar 2024 14:14:57 +0100 Subject: [PATCH 17/25] resolve pool setup fee to treasury account --- system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs | 2 +- .../asset-hubs/asset-hub-kusama/tests/tests.rs | 7 +++---- system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs | 3 +-- .../asset-hubs/asset-hub-polkadot/tests/tests.rs | 7 +++---- 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs b/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs index 7be2952fd0..7268905522 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs +++ b/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs @@ -356,7 +356,7 @@ impl pallet_asset_conversion::Config for Runtime { type PoolAssets = PoolAssets; type PoolSetupFee = ConstU128<0>; // Asset class deposit fees are sufficient to prevent spam type PoolSetupFeeAsset = KsmLocationV3; - type PoolSetupFeeTarget = ResolveAssetTo; + type PoolSetupFeeTarget = ResolveAssetTo; type LiquidityWithdrawalFee = LiquidityWithdrawalFee; type LPFee = ConstU32<3>; type PalletId = AssetConversionPalletId; diff --git a/system-parachains/asset-hubs/asset-hub-kusama/tests/tests.rs b/system-parachains/asset-hubs/asset-hub-kusama/tests/tests.rs index b95ec4b613..f0a8bdd79e 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/tests/tests.rs +++ b/system-parachains/asset-hubs/asset-hub-kusama/tests/tests.rs @@ -20,10 +20,9 @@ use asset_hub_kusama_runtime::{ xcm_config::{ bridging::{self, XcmBridgeHubRouterFeeAssetId}, - AssetFeeAsExistentialDepositMultiplierFeeCharger, CheckingAccount, - ForeignCreatorsSovereignAccountOf, KsmLocation, LocationToAccountId, RelayTreasuryLocation, - RelayTreasuryPalletAccount, StakingPot, TreasuryAccount, TrustBackedAssetsPalletLocation, - XcmConfig, + CheckingAccount, ForeignCreatorsSovereignAccountOf, KsmLocation, LocationToAccountId, + RelayTreasuryLocation, RelayTreasuryPalletAccount, StakingPot, + TrustBackedAssetsPalletLocation, XcmConfig, }, AllPalletsWithoutSystem, AssetConversion, AssetDeposit, Assets, Balances, ExistentialDeposit, ForeignAssets, ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs index 73869a5f56..6515a2900c 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs @@ -887,8 +887,7 @@ impl pallet_asset_conversion::Config for Runtime { // TODO any fee? type PoolSetupFee = ConstU128<0>; type PoolSetupFeeAsset = DotLocationV3; - // TODO replace by treasury pallet account - type PoolSetupFeeTarget = ResolveAssetTo; + type PoolSetupFeeTarget = ResolveAssetTo; type LiquidityWithdrawalFee = LiquidityWithdrawalFee; type LPFee = ConstU32<3>; type PalletId = AssetConversionPalletId; diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/tests/tests.rs b/system-parachains/asset-hubs/asset-hub-polkadot/tests/tests.rs index d70fd586df..946179403c 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/tests/tests.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/tests/tests.rs @@ -20,10 +20,9 @@ use asset_hub_polkadot_runtime::{ xcm_config::{ bridging::{self, XcmBridgeHubRouterFeeAssetId}, - AssetFeeAsExistentialDepositMultiplierFeeCharger, CheckingAccount, DotLocation, - ForeignCreatorsSovereignAccountOf, LocationToAccountId, RelayTreasuryLocation, - RelayTreasuryPalletAccount, StakingPot, TreasuryAccount, TrustBackedAssetsPalletLocation, - XcmConfig, + CheckingAccount, DotLocation, ForeignCreatorsSovereignAccountOf, LocationToAccountId, + RelayTreasuryLocation, RelayTreasuryPalletAccount, StakingPot, + TrustBackedAssetsPalletLocation, XcmConfig, }, AllPalletsWithoutSystem, AssetConversion, AssetDeposit, Assets, Balances, ExistentialDeposit, ForeignAssets, ForeignAssetsInstance, MetadataDepositBase, MetadataDepositPerByte, From 47873c858b7bd4d81d314ae7c1f02e394d3367c5 Mon Sep 17 00:00:00 2001 From: Muharem Date: Mon, 11 Mar 2024 11:33:30 +0100 Subject: [PATCH 18/25] Apply suggestions from code review Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> Co-authored-by: Sergej Sakac <73715684+Szegoo@users.noreply.github.com> --- .../emulated/tests/assets/asset-hub-kusama/src/tests/swap.rs | 2 +- .../bridges/bridge-hub-kusama/src/tests/asset_transfers.rs | 2 +- .../asset-hubs/asset-hub-kusama/src/xcm_config.rs | 2 +- system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs | 1 - .../asset-hubs/asset-hub-polkadot/src/xcm_config.rs | 4 ++-- 5 files changed, 5 insertions(+), 6 deletions(-) diff --git a/integration-tests/emulated/tests/assets/asset-hub-kusama/src/tests/swap.rs b/integration-tests/emulated/tests/assets/asset-hub-kusama/src/tests/swap.rs index e3d3fec767..a7253cdc62 100644 --- a/integration-tests/emulated/tests/assets/asset-hub-kusama/src/tests/swap.rs +++ b/integration-tests/emulated/tests/assets/asset-hub-kusama/src/tests/swap.rs @@ -374,7 +374,7 @@ fn pay_xcm_fee_with_some_asset_swapped_for_native() { }); PenpalA::execute_with(|| { - // send xcm transact from `penpal` account which as only `ASSET_ID` tokens on + // send xcm transact from `penpal` account which has only `ASSET_ID` tokens on // `AssetHubKusama` let call = AssetHubKusama::force_create_asset_call( ASSET_ID + 1000, diff --git a/integration-tests/emulated/tests/bridges/bridge-hub-kusama/src/tests/asset_transfers.rs b/integration-tests/emulated/tests/bridges/bridge-hub-kusama/src/tests/asset_transfers.rs index 5d2ff390cb..e17756fccd 100644 --- a/integration-tests/emulated/tests/bridges/bridge-hub-kusama/src/tests/asset_transfers.rs +++ b/integration-tests/emulated/tests/bridges/bridge-hub-kusama/src/tests/asset_transfers.rs @@ -285,7 +285,7 @@ fn send_ksms_from_asset_hub_kusama_to_asset_hub_polkadot_fee_from_pool() { assert!(sender_ksms_before > sender_ksms_after); // Receiver's balance is increased assert!(receiver_ksms_after > receiver_ksms_before); - // Reserve balance is reduced by sent amount + // Reserve balance has increased by sent amount assert_eq!(ksms_in_reserve_on_ahk_after, ksms_in_reserve_on_ahk_before + amount); } diff --git a/system-parachains/asset-hubs/asset-hub-kusama/src/xcm_config.rs b/system-parachains/asset-hubs/asset-hub-kusama/src/xcm_config.rs index 7b7b8da632..0c0eff4b07 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/src/xcm_config.rs +++ b/system-parachains/asset-hubs/asset-hub-kusama/src/xcm_config.rs @@ -248,7 +248,7 @@ impl Contains for SafeCallFilter { #[cfg(feature = "runtime-benchmarks")] { if matches!(call, RuntimeCall::System(frame_system::Call::remark_with_event { .. })) { - return true; + return true } } diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs index 6515a2900c..aabf9df5a5 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs @@ -865,7 +865,6 @@ pub type NativeAndAssets = fungible::UnionOf< parameter_types! { pub const AssetConversionPalletId: PalletId = PalletId(*b"py/ascon"); - // TODO any fee? pub const LiquidityWithdrawalFee: Permill = Permill::from_percent(0); } diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/xcm_config.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/xcm_config.rs index 91342c3435..28cea1753c 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/src/xcm_config.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/xcm_config.rs @@ -182,7 +182,7 @@ pub type PoolFungiblesTransactor = FungiblesAdapter< PoolAssets, // Use this currency when it is a fungible asset matching the given location or name: PoolAssetsConvertedConcreteId, - // Convert an XCM MultiLocation into a local account id: + // Convert an XCM `Location` into a local account ID: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): AccountId, @@ -264,7 +264,7 @@ impl Contains for SafeCallFilter { #[cfg(feature = "runtime-benchmarks")] { if matches!(call, RuntimeCall::System(frame_system::Call::remark_with_event { .. })) { - return true; + return true } } From 2811e93f7a6c482e9377f0ba6f67236edc65affd Mon Sep 17 00:00:00 2001 From: muharem Date: Mon, 11 Mar 2024 11:54:49 +0100 Subject: [PATCH 19/25] minor review fixes --- .../bridge-hub-kusama/src/tests/asset_transfers.rs | 8 ++++---- .../bridge-hub-polkadot/src/tests/asset_transfers.rs | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/integration-tests/emulated/tests/bridges/bridge-hub-kusama/src/tests/asset_transfers.rs b/integration-tests/emulated/tests/bridges/bridge-hub-kusama/src/tests/asset_transfers.rs index e17756fccd..5c94dde5b2 100644 --- a/integration-tests/emulated/tests/bridges/bridge-hub-kusama/src/tests/asset_transfers.rs +++ b/integration-tests/emulated/tests/bridges/bridge-hub-kusama/src/tests/asset_transfers.rs @@ -212,7 +212,7 @@ fn send_ksms_from_asset_hub_kusama_to_asset_hub_polkadot_fee_from_pool() { assert_ok!(::AssetConversion::create_pool( ::RuntimeOrigin::signed(AssetHubPolkadotSender::get()), - Box::new(xcm::v3::Parent.into()), + Box::new(ksm_at_asset_hub_kusama), Box::new(ksm_at_asset_hub_polkadot), )); @@ -225,7 +225,7 @@ fn send_ksms_from_asset_hub_kusama_to_asset_hub_polkadot_fee_from_pool() { assert_ok!(::AssetConversion::add_liquidity( ::RuntimeOrigin::signed(AssetHubPolkadotSender::get()), - Box::new(xcm::v3::Parent.into()), + Box::new(ksm_at_asset_hub_kusama), Box::new(ksm_at_asset_hub_polkadot), 1_000_000_000_000, 2_000_000_000_000, @@ -282,7 +282,7 @@ fn send_ksms_from_asset_hub_kusama_to_asset_hub_polkadot_fee_from_pool() { ::account_data_of(sov_ahp_on_ahk.clone()).free; // Sender's balance is reduced - assert!(sender_ksms_before > sender_ksms_after); + assert!(sender_ksms_before >= sender_ksms_after + amount); // Receiver's balance is increased assert!(receiver_ksms_after > receiver_ksms_before); // Reserve balance has increased by sent amount @@ -406,7 +406,7 @@ fn send_dots_from_asset_hub_polkadot_to_asset_hub_kusama_fee_from_pool() { ::account_data_of(sov_ahk_on_ahp).free; // Sender's balance is reduced - assert!(sender_dots_before > sender_dots_after); + assert!(sender_dots_before >= sender_dots_after + amount_to_send); // Receiver's balance is increased assert!(receiver_dots_after > receiver_dots_before); // Reserve balance is reduced by sent amount diff --git a/integration-tests/emulated/tests/bridges/bridge-hub-polkadot/src/tests/asset_transfers.rs b/integration-tests/emulated/tests/bridges/bridge-hub-polkadot/src/tests/asset_transfers.rs index 14a49de48c..31bcaa398e 100644 --- a/integration-tests/emulated/tests/bridges/bridge-hub-polkadot/src/tests/asset_transfers.rs +++ b/integration-tests/emulated/tests/bridges/bridge-hub-polkadot/src/tests/asset_transfers.rs @@ -212,7 +212,7 @@ fn send_dots_from_asset_hub_polkadot_to_asset_hub_kusama_fee_from_pool() { assert_ok!(::AssetConversion::create_pool( ::RuntimeOrigin::signed(owner.clone()), - Box::new(xcm::v3::Parent.into()), + Box::new(dot_at_asset_hub_polkadot), Box::new(dot_at_asset_hub_kusama), )); @@ -225,7 +225,7 @@ fn send_dots_from_asset_hub_polkadot_to_asset_hub_kusama_fee_from_pool() { assert_ok!(::AssetConversion::add_liquidity( ::RuntimeOrigin::signed(owner.clone()), - Box::new(xcm::v3::Parent.into()), + Box::new(dot_at_asset_hub_polkadot), Box::new(dot_at_asset_hub_kusama), 1_000_000_000_000, 2_000_000_000_000, @@ -285,7 +285,7 @@ fn send_dots_from_asset_hub_polkadot_to_asset_hub_kusama_fee_from_pool() { ::account_data_of(sov_ahk_on_ahp).free; // Sender's balance is reduced - assert!(sender_dots_before > sender_dots_after); + assert!(sender_dots_before >= sender_dots_after + amount); // Receiver's balance is increased assert!(receiver_dots_after > receiver_dots_before); // Reserve balance is increased by sent amount @@ -412,7 +412,7 @@ fn send_ksms_from_asset_hub_polkadot_to_asset_hub_kusama_fee_from_pool() { ::account_data_of(sov_ahp_on_ahk.clone()).free; // Sender's balance is reduced - assert!(sender_ksms_before > sender_ksms_after); + assert!(sender_ksms_before >= sender_ksms_after + amount_to_send); // Receiver's balance is increased assert!(receiver_ksms_after > receiver_ksms_before); // Reserve balance is reduced by sent amount From 3b317dc18275acd7b187f3ed97cc98b7df255f45 Mon Sep 17 00:00:00 2001 From: muharem Date: Mon, 11 Mar 2024 18:24:16 +0100 Subject: [PATCH 20/25] update deposits --- system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs | 2 +- system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs b/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs index 7268905522..fb78ecf035 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs +++ b/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs @@ -308,7 +308,7 @@ impl pallet_assets::Config for Runtime { type ForceOrigin = AssetsForceOrigin; // Deposits are zero because creation/admin is limited to Asset Conversion pallet. type AssetDeposit = ConstU128<0>; - type AssetAccountDeposit = ConstU128<0>; + type AssetAccountDeposit = AssetAccountDeposit; type MetadataDepositBase = ConstU128<0>; type MetadataDepositPerByte = ConstU128<0>; type ApprovalDeposit = ExistentialDeposit; diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs index aabf9df5a5..1eaf19807b 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs @@ -827,8 +827,7 @@ impl pallet_assets::Config for Runtime { type CreateOrigin = NeverEnsureOrigin; type ForceOrigin = AssetsForceOrigin; type AssetDeposit = ConstU128<0>; - // TODO any? - type AssetAccountDeposit = ConstU128<0>; + type AssetAccountDeposit = AssetAccountDeposit; type MetadataDepositBase = ConstU128<0>; type MetadataDepositPerByte = ConstU128<0>; type ApprovalDeposit = ExistentialDeposit; @@ -866,6 +865,7 @@ pub type NativeAndAssets = fungible::UnionOf< parameter_types! { pub const AssetConversionPalletId: PalletId = PalletId(*b"py/ascon"); pub const LiquidityWithdrawalFee: Permill = Permill::from_percent(0); + pub const PoolSetupFee: Balance = system_para_deposit(1, 4); } impl pallet_asset_conversion::Config for Runtime { @@ -883,8 +883,7 @@ impl pallet_asset_conversion::Config for Runtime { >; type PoolAssetId = u32; type PoolAssets = PoolAssets; - // TODO any fee? - type PoolSetupFee = ConstU128<0>; + type PoolSetupFee = PoolSetupFee; type PoolSetupFeeAsset = DotLocationV3; type PoolSetupFeeTarget = ResolveAssetTo; type LiquidityWithdrawalFee = LiquidityWithdrawalFee; From 28d1d731d4c02e726214b4b0c86817cec93babf5 Mon Sep 17 00:00:00 2001 From: muharem Date: Wed, 13 Mar 2024 10:27:55 +0100 Subject: [PATCH 21/25] review fixes --- .../assets/asset-hub-kusama/src/tests/swap.rs | 9 ++++-- .../asset-hub-polkadot/src/tests/swap.rs | 28 +++++++++++-------- .../asset-hubs/asset-hub-kusama/src/lib.rs | 3 +- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/integration-tests/emulated/tests/assets/asset-hub-kusama/src/tests/swap.rs b/integration-tests/emulated/tests/assets/asset-hub-kusama/src/tests/swap.rs index a7253cdc62..67ab650deb 100644 --- a/integration-tests/emulated/tests/assets/asset-hub-kusama/src/tests/swap.rs +++ b/integration-tests/emulated/tests/assets/asset-hub-kusama/src/tests/swap.rs @@ -150,8 +150,9 @@ fn swap_locally_on_chain_using_foreign_assets() { let penpal_as_seen_by_ah = AssetHubKusama::sibling_location_of(PenpalA::para_id()); let sov_penpal_on_ahk = AssetHubKusama::sovereign_account_id_of(penpal_as_seen_by_ah); AssetHubKusama::fund_accounts(vec![ - (AssetHubKusamaSender::get(), 5_000_000 * KUSAMA_ED), /* An account to swap dot - * for something else. */ + (AssetHubKusamaSender::get(), 5_000_000 * ASSET_HUB_KUSAMA_ED), /* An account to swap + * dot + * for something else. */ ]); AssetHubKusama::execute_with(|| { @@ -290,7 +291,9 @@ fn cannot_create_pool_from_pool_assets() { #[test] fn pay_xcm_fee_with_some_asset_swapped_for_native() { - let asset_native = asset_hub_kusama_runtime::xcm_config::KsmLocationV3::get(); + let asset_native: xcm::v3::Location = asset_hub_kusama_runtime::xcm_config::KsmLocation::get() + .try_into() + .expect("conversion works"); let asset_one = xcm::v3::Location { parents: 0, interior: [ diff --git a/integration-tests/emulated/tests/assets/asset-hub-polkadot/src/tests/swap.rs b/integration-tests/emulated/tests/assets/asset-hub-polkadot/src/tests/swap.rs index ca8b44e118..f2901c70a6 100644 --- a/integration-tests/emulated/tests/assets/asset-hub-polkadot/src/tests/swap.rs +++ b/integration-tests/emulated/tests/assets/asset-hub-polkadot/src/tests/swap.rs @@ -22,14 +22,17 @@ use system_parachains_constants::polkadot::currency::SYSTEM_PARA_EXISTENTIAL_DEP fn swap_locally_on_chain_using_local_assets() { use frame_support::traits::fungible::Mutate; - let asset_native = Box::new(asset_hub_polkadot_runtime::xcm_config::DotLocationV3::get()); - let asset_one = Box::new(v3::Location::new( + let asset_native: xcm::v3::Location = + asset_hub_polkadot_runtime::xcm_config::DotLocation::get() + .try_into() + .expect("conversion works"); + let asset_one = v3::Location::new( 0, [ v3::Junction::PalletInstance(ASSETS_PALLET_ID), v3::Junction::GeneralIndex(ASSET_ID.into()), ], - )); + ); AssetHubPolkadot::execute_with(|| { type RuntimeEvent = ::RuntimeEvent; @@ -56,8 +59,8 @@ fn swap_locally_on_chain_using_local_assets() { assert_ok!(::AssetConversion::create_pool( ::RuntimeOrigin::signed(AssetHubPolkadotSender::get()), - asset_native.clone(), - asset_one.clone(), + bx!(asset_native.clone()), + bx!(asset_one.clone()), )); assert_expected_events!( @@ -69,8 +72,8 @@ fn swap_locally_on_chain_using_local_assets() { assert_ok!(::AssetConversion::add_liquidity( ::RuntimeOrigin::signed(AssetHubPolkadotSender::get()), - asset_native.clone(), - asset_one.clone(), + bx!(asset_native.clone()), + bx!(asset_one.clone()), 1_000_000_000_000, 2_000_000_000_000, 0, @@ -85,7 +88,7 @@ fn swap_locally_on_chain_using_local_assets() { ] ); - let path = vec![asset_native.clone(), asset_one.clone()]; + let path = vec![bx!(asset_native.clone()), bx!(asset_one.clone())]; assert_ok!( ::AssetConversion::swap_exact_tokens_for_tokens( @@ -111,8 +114,8 @@ fn swap_locally_on_chain_using_local_assets() { assert_ok!( ::AssetConversion::remove_liquidity( ::RuntimeOrigin::signed(AssetHubPolkadotSender::get()), - asset_native, - asset_one, + bx!(asset_native), + bx!(asset_one), 1414213562273 - SYSTEM_PARA_EXISTENTIAL_DEPOSIT * 2, /* all but the 2 EDs can't * be * retrieved. */ @@ -303,7 +306,10 @@ fn cannot_create_pool_from_pool_assets() { fn pay_xcm_fee_with_some_asset_swapped_for_native() { use frame_support::traits::fungible::Mutate; - let asset_native = asset_hub_polkadot_runtime::xcm_config::DotLocationV3::get(); + let asset_native: xcm::v3::Location = + asset_hub_polkadot_runtime::xcm_config::DotLocation::get() + .try_into() + .expect("conversion works"); let asset_one = xcm::v3::Location { parents: 0, interior: [ diff --git a/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs b/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs index fb78ecf035..29be2ffc3a 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs +++ b/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs @@ -288,6 +288,7 @@ impl pallet_assets::Config for Runtime { parameter_types! { pub const AssetConversionPalletId: PalletId = PalletId(*b"py/ascon"); pub const LiquidityWithdrawalFee: Permill = Permill::from_percent(0); + pub const PoolSetupFee: Balance = system_para_deposit(1, 4); } ord_parameter_types! { @@ -354,7 +355,7 @@ impl pallet_asset_conversion::Config for Runtime { pallet_asset_conversion::WithFirstAsset; type PoolAssetId = u32; type PoolAssets = PoolAssets; - type PoolSetupFee = ConstU128<0>; // Asset class deposit fees are sufficient to prevent spam + type PoolSetupFee = PoolSetupFee; type PoolSetupFeeAsset = KsmLocationV3; type PoolSetupFeeTarget = ResolveAssetTo; type LiquidityWithdrawalFee = LiquidityWithdrawalFee; From f8d3e15697f6fb3df40845ff69aa1e5fcb1093bf Mon Sep 17 00:00:00 2001 From: muharem Date: Wed, 13 Mar 2024 10:46:52 +0100 Subject: [PATCH 22/25] clippy fixes --- .../tests/assets/asset-hub-polkadot/src/tests/swap.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/integration-tests/emulated/tests/assets/asset-hub-polkadot/src/tests/swap.rs b/integration-tests/emulated/tests/assets/asset-hub-polkadot/src/tests/swap.rs index f2901c70a6..63a1fa45c7 100644 --- a/integration-tests/emulated/tests/assets/asset-hub-polkadot/src/tests/swap.rs +++ b/integration-tests/emulated/tests/assets/asset-hub-polkadot/src/tests/swap.rs @@ -59,8 +59,8 @@ fn swap_locally_on_chain_using_local_assets() { assert_ok!(::AssetConversion::create_pool( ::RuntimeOrigin::signed(AssetHubPolkadotSender::get()), - bx!(asset_native.clone()), - bx!(asset_one.clone()), + bx!(asset_native), + bx!(asset_one), )); assert_expected_events!( @@ -72,8 +72,8 @@ fn swap_locally_on_chain_using_local_assets() { assert_ok!(::AssetConversion::add_liquidity( ::RuntimeOrigin::signed(AssetHubPolkadotSender::get()), - bx!(asset_native.clone()), - bx!(asset_one.clone()), + bx!(asset_native), + bx!(asset_one), 1_000_000_000_000, 2_000_000_000_000, 0, @@ -88,7 +88,7 @@ fn swap_locally_on_chain_using_local_assets() { ] ); - let path = vec![bx!(asset_native.clone()), bx!(asset_one.clone())]; + let path = vec![bx!(asset_native), bx!(asset_one)]; assert_ok!( ::AssetConversion::swap_exact_tokens_for_tokens( From d2032c2a9dda26baa167c691f68cc5c1b1364d7d Mon Sep 17 00:00:00 2001 From: muharem Date: Wed, 13 Mar 2024 13:14:13 +0100 Subject: [PATCH 23/25] include assets storage deposit into pool setup fee --- system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs | 4 +++- system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs b/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs index 29be2ffc3a..39d135299c 100644 --- a/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs +++ b/system-parachains/asset-hubs/asset-hub-kusama/src/lib.rs @@ -288,7 +288,9 @@ impl pallet_assets::Config for Runtime { parameter_types! { pub const AssetConversionPalletId: PalletId = PalletId(*b"py/ascon"); pub const LiquidityWithdrawalFee: Permill = Permill::from_percent(0); - pub const PoolSetupFee: Balance = system_para_deposit(1, 4); + // Storage deposit for pool setup within asset conversion pallet + // and pool's lp token creation within assets pallet. + pub const PoolSetupFee: Balance = system_para_deposit(1, 4) + AssetDeposit::get(); } ord_parameter_types! { diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs index 1eaf19807b..7263b513af 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/lib.rs @@ -865,7 +865,9 @@ pub type NativeAndAssets = fungible::UnionOf< parameter_types! { pub const AssetConversionPalletId: PalletId = PalletId(*b"py/ascon"); pub const LiquidityWithdrawalFee: Permill = Permill::from_percent(0); - pub const PoolSetupFee: Balance = system_para_deposit(1, 4); + // Storage deposit for pool setup within asset conversion pallet + // and pool's lp token creation within assets pallet. + pub const PoolSetupFee: Balance = system_para_deposit(1, 4) + AssetDeposit::get(); } impl pallet_asset_conversion::Config for Runtime { From 74cb40081962be13c305801a34c397d34198fb79 Mon Sep 17 00:00:00 2001 From: muharem Date: Wed, 13 Mar 2024 17:59:13 +0100 Subject: [PATCH 24/25] add pool assets and asset conversion calls to xcm safe calls filter --- .../asset-hubs/asset-hub-polkadot/src/xcm_config.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/xcm_config.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/xcm_config.rs index 0c560fc4fc..a01d95ecca 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/src/xcm_config.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/xcm_config.rs @@ -441,7 +441,8 @@ impl Contains for SafeCallFilter { pallet_uniques::Call::buy_item { .. } ) | RuntimeCall::ToKusamaXcmRouter( pallet_xcm_bridge_hub_router::Call::report_bridge_status { .. } - ) + ) | RuntimeCall::PoolAssets(..) | + RuntimeCall::AssetConversion(..) ) } } From 9d5af6648df630116fa0121e46b0fe5fec9ff46e Mon Sep 17 00:00:00 2001 From: muharem Date: Mon, 18 Mar 2024 14:58:28 +0100 Subject: [PATCH 25/25] style fixes --- .../assets/asset-hub-kusama/src/tests/swap.rs | 2 +- .../asset-hubs/asset-hub-polkadot/src/impls.rs | 18 +++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/integration-tests/emulated/tests/assets/asset-hub-kusama/src/tests/swap.rs b/integration-tests/emulated/tests/assets/asset-hub-kusama/src/tests/swap.rs index 67ab650deb..f0fb361b81 100644 --- a/integration-tests/emulated/tests/assets/asset-hub-kusama/src/tests/swap.rs +++ b/integration-tests/emulated/tests/assets/asset-hub-kusama/src/tests/swap.rs @@ -151,7 +151,7 @@ fn swap_locally_on_chain_using_foreign_assets() { let sov_penpal_on_ahk = AssetHubKusama::sovereign_account_id_of(penpal_as_seen_by_ah); AssetHubKusama::fund_accounts(vec![ (AssetHubKusamaSender::get(), 5_000_000 * ASSET_HUB_KUSAMA_ED), /* An account to swap - * dot + * ksm * for something else. */ ]); diff --git a/system-parachains/asset-hubs/asset-hub-polkadot/src/impls.rs b/system-parachains/asset-hubs/asset-hub-polkadot/src/impls.rs index 866dccf3f7..07d682f18a 100644 --- a/system-parachains/asset-hubs/asset-hub-polkadot/src/impls.rs +++ b/system-parachains/asset-hubs/asset-hub-polkadot/src/impls.rs @@ -41,12 +41,16 @@ pub(crate) mod pool { AccountIdConverter: for<'a> TryConvert<&'a (AssetKind, AssetKind), AccountId>, { fn pool_id(asset1: &AssetKind, asset2: &AssetKind) -> Result<(AssetKind, AssetKind), ()> { + if asset1 == asset2 { + return Err(()); + } let first = FirstAsset::get(); - match true { - _ if asset1 == asset2 => Err(()), - _ if first == *asset1 => Ok((first, asset2.clone())), - _ if first == *asset2 => Ok((first, asset1.clone())), - _ => Err(()), + if first == *asset1 { + Ok((first, asset2.clone())) + } else if first == *asset2 { + Ok((first, asset1.clone())) + } else { + Err(()) } } fn address(id: &(AssetKind, AssetKind)) -> Result { @@ -63,8 +67,8 @@ pub(crate) mod pool { Seed: Get, { fn try_convert(id: &PoolId) -> Result { - let encoded = sp_io::hashing::blake2_256(&Encode::encode(&(Seed::get(), id))[..]); - Decode::decode(&mut TrailingZeroInput::new(encoded.as_ref())).map_err(|_| id) + sp_io::hashing::blake2_256(&Encode::encode(&(Seed::get(), id))[..]) + .using_encoded(|e| Decode::decode(&mut TrailingZeroInput::new(e)).map_err(|_| id)) } } }