Asset conversion nits (#2860)

* [asset-conv] Unused Balances type

* [asset-conv] native asset change

* Dedicated `AssetBalance` type for `pallet_assets` instances

* Improved local vs foreign asset handling + test for not allowing pool_assets in pool

* Removed `into_multiasset_id`

* Fix

* Refactor

* Fixed create_pool for benchmark with LocalAndForeignAssets (finally found it)

* ".git/.scripts/commands/fmt/fmt.sh"

* Revert

* fmt

* Migrates pools with `MultiLocation { parents: 0, interior: Here }` to `MultiLocation { parents: 1, interior: Here }`

* Allow `set_storage` for `AllowMultiAssetPools` / `LiquidityWithdrawalFee`

* Benchmarks work

* Removed comment + more defensive migration

* `T::Currency::transfer` -> `Balances::transfer_all` in migration

* Change pool_id in migration

* Update parachains/runtimes/assets/asset-hub-westend/src/lib.rs

* Bump substrate (manually)

* Bump polkadot

* Fixes from polkadot + clippy

* Fix for xcm-emulator tests (thank you Nacho)

---------

Co-authored-by: command-bot <>
Co-authored-by: Jegor Sidorenko <5252494+jsidorenko@users.noreply.github.com>
This commit is contained in:
Branislav Kontur
2023-07-21 23:53:51 +02:00
committed by GitHub
parent 849964bf18
commit 8171890f9b
25 changed files with 1060 additions and 486 deletions
@@ -28,8 +28,13 @@ pub mod constants;
mod weights;
pub mod xcm_config;
use crate::xcm_config::{TrustBackedAssetsPalletLocation, UniversalLocation};
use assets_common::local_and_foreign_assets::{LocalAndForeignAssets, MultiLocationConverter};
use crate::xcm_config::{
LocalAndForeignAssetsMultiLocationMatcher, TrustBackedAssetsPalletLocation,
};
use assets_common::{
local_and_foreign_assets::{LocalAndForeignAssets, MultiLocationConverter},
AssetIdForTrustBackedAssetsConvert,
};
use codec::{Decode, Encode, MaxEncodedLen};
use constants::{currency::*, fee::WeightToFee};
use cumulus_pallet_parachain_system::RelayNumberStrictlyIncreases;
@@ -300,9 +305,13 @@ impl pallet_asset_conversion::Config for Runtime {
type Balance = Balance;
type HigherPrecisionBalance = sp_core::U256;
type Currency = Balances;
type AssetBalance = <Self as pallet_balances::Config>::Balance;
type AssetBalance = Balance;
type AssetId = MultiLocation;
type Assets = LocalAndForeignAssets<Assets, ForeignAssets, TrustBackedAssetsPalletLocation>;
type Assets = LocalAndForeignAssets<
Assets,
AssetIdForTrustBackedAssetsConvert<TrustBackedAssetsPalletLocation>,
ForeignAssets,
>;
type PoolAssets = PoolAssets;
type PoolAssetId = u32;
type PoolSetupFee = ConstU128<0>; // Asset class deposit fees are sufficient to prevent spam
@@ -314,11 +323,12 @@ impl pallet_asset_conversion::Config for Runtime {
type MaxSwapPathLength = ConstU32<4>;
type MultiAssetId = Box<MultiLocation>;
type MultiAssetIdConverter = MultiLocationConverter<Balances, UniversalLocation>;
type MultiAssetIdConverter =
MultiLocationConverter<WestendLocation, LocalAndForeignAssetsMultiLocationMatcher>;
type MintMinLiquidity = ConstU128<100>;
type WeightInfo = ();
type WeightInfo = weights::pallet_asset_conversion::WeightInfo<Runtime>;
#[cfg(feature = "runtime-benchmarks")]
type BenchmarkHelper =
@@ -659,7 +669,11 @@ impl pallet_collator_selection::Config for Runtime {
impl pallet_asset_conversion_tx_payment::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type Fungibles = LocalAndForeignAssets<Assets, ForeignAssets, TrustBackedAssetsPalletLocation>;
type Fungibles = LocalAndForeignAssets<
Assets,
AssetIdForTrustBackedAssetsConvert<TrustBackedAssetsPalletLocation>,
ForeignAssets,
>;
type OnChargeAssetTransaction = AssetConversionAdapter<Balances, AssetConversion>;
}
@@ -835,6 +849,8 @@ pub type Migrations = (
pallet_nfts::migration::v1::MigrateToV1<Runtime>,
// unreleased
pallet_collator_selection::migration::v1::MigrateToV1<Runtime>,
// unreleased
migrations::NativeAssetParents0ToParents1Migration<Runtime>,
);
/// Executive: handles dispatch to the various modules.
@@ -1240,7 +1256,7 @@ impl_runtime_apis! {
MultiAsset { fun: Fungible(UNITS), id: Concrete(WestendLocation::get()) },
));
pub const CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None;
pub const TrustedReserve: Option<(MultiLocation, MultiAsset)> = None;
}
impl pallet_xcm_benchmarks::fungible::Config for Runtime {
@@ -1248,6 +1264,7 @@ impl_runtime_apis! {
type CheckedAccount = CheckedAccount;
type TrustedTeleporter = TrustedTeleporter;
type TrustedReserve = TrustedReserve;
fn get_multi_asset() -> MultiAsset {
MultiAsset {
@@ -1360,3 +1377,120 @@ cumulus_pallet_parachain_system::register_validate_block! {
BlockExecutor = cumulus_pallet_aura_ext::BlockExecutor::<Runtime, Executive>,
CheckInherents = CheckInherents,
}
pub mod migrations {
use super::*;
use frame_support::{
pallet_prelude::Get,
traits::{
fungibles::{Inspect, Mutate},
tokens::Preservation,
OnRuntimeUpgrade, OriginTrait,
},
};
use parachains_common::impls::AccountIdOf;
use sp_runtime::{traits::StaticLookup, Saturating};
use xcm::latest::prelude::*;
/// Temporary migration because of bug with native asset, it can be removed once applied on `AssetHubWestend`.
/// Migrates pools with `MultiLocation { parents: 0, interior: Here }` to `MultiLocation { parents: 1, interior: Here }`
pub struct NativeAssetParents0ToParents1Migration<T>(sp_std::marker::PhantomData<T>);
impl<
T: pallet_asset_conversion::Config<
MultiAssetId = Box<MultiLocation>,
AssetId = MultiLocation,
>,
> OnRuntimeUpgrade for NativeAssetParents0ToParents1Migration<T>
where
<T as pallet_asset_conversion::Config>::PoolAssetId: Into<u32>,
AccountIdOf<Runtime>: Into<[u8; 32]>,
<T as frame_system::Config>::AccountId:
Into<<<T as frame_system::Config>::RuntimeOrigin as OriginTrait>::AccountId>,
<<T as frame_system::Config>::Lookup as StaticLookup>::Source:
From<<T as frame_system::Config>::AccountId>,
sp_runtime::AccountId32: From<<T as frame_system::Config>::AccountId>,
{
fn on_runtime_upgrade() -> Weight {
let invalid_native_asset = MultiLocation { parents: 0, interior: Here };
let valid_native_asset = WestendLocation::get();
let mut reads: u64 = 1;
let mut writes: u64 = 0;
// migrate pools with invalid native asset
let pools = pallet_asset_conversion::Pools::<T>::iter().collect::<Vec<_>>();
reads.saturating_accrue(1);
for (old_pool_id, pool_info) in pools {
let old_pool_account =
pallet_asset_conversion::Pallet::<T>::get_pool_account(&old_pool_id);
reads.saturating_accrue(1);
let pool_asset_id = pool_info.lp_token.clone();
if old_pool_id.0.as_ref() != &invalid_native_asset {
// skip, if ok
continue
}
// fix new account
let new_pool_id = pallet_asset_conversion::Pallet::<T>::get_pool_id(
Box::new(valid_native_asset),
old_pool_id.1.clone(),
);
let new_pool_account =
pallet_asset_conversion::Pallet::<T>::get_pool_account(&new_pool_id);
frame_system::Pallet::<T>::inc_providers(&new_pool_account);
reads.saturating_accrue(2);
writes.saturating_accrue(1);
// move currency
let _ = Balances::transfer_all(
RuntimeOrigin::signed(sp_runtime::AccountId32::from(old_pool_account.clone())),
sp_runtime::AccountId32::from(new_pool_account.clone()).into(),
false,
);
reads.saturating_accrue(2);
writes.saturating_accrue(2);
// move LP token
let _ = T::PoolAssets::transfer(
pool_asset_id.clone(),
&old_pool_account,
&new_pool_account,
T::PoolAssets::balance(pool_asset_id.clone(), &old_pool_account),
Preservation::Expendable,
);
reads.saturating_accrue(1);
writes.saturating_accrue(2);
// change the ownership of LP token
let _ = pallet_assets::Pallet::<Runtime, PoolAssetsInstance>::transfer_ownership(
RuntimeOrigin::signed(sp_runtime::AccountId32::from(old_pool_account.clone())),
pool_asset_id.into(),
sp_runtime::AccountId32::from(new_pool_account.clone()).into(),
);
reads.saturating_accrue(1);
writes.saturating_accrue(2);
// move LocalOrForeignAssets
let _ = T::Assets::transfer(
*old_pool_id.1.as_ref(),
&old_pool_account,
&new_pool_account,
T::Assets::balance(*old_pool_id.1.as_ref(), &old_pool_account),
Preservation::Expendable,
);
reads.saturating_accrue(1);
writes.saturating_accrue(2);
// dec providers for old account
let _ = frame_system::Pallet::<T>::dec_providers(&old_pool_account);
writes.saturating_accrue(1);
// change pool key
pallet_asset_conversion::Pools::<T>::insert(new_pool_id, pool_info);
pallet_asset_conversion::Pools::<T>::remove(old_pool_id);
}
T::DbWeight::get().reads_writes(reads, writes)
}
}
}
@@ -2,6 +2,7 @@ pub mod block_weights;
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;
@@ -0,0 +1,157 @@
// Copyright Parity Technologies (UK) Ltd.
// This file is part of Cumulus.
// Cumulus 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.
// Cumulus 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 Cumulus. If not, see <http://www.gnu.org/licenses/>.
//! Autogenerated weights for `pallet_asset_conversion`
//!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev
//! DATE: 2023-07-18, STEPS: `2`, REPEAT: `1`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! WORST CASE MAP SIZE: `1000000`
//! HOSTNAME: `bkontur-ThinkPad-P14s-Gen-2i`, CPU: `11th Gen Intel(R) Core(TM) i7-1185G7 @ 3.00GHz`
//! EXECUTION: ``, WASM-EXECUTION: `Compiled`, CHAIN: `Some("asset-hub-westend-dev")`, DB CACHE: 1024
// Executed Command:
// ./target/release/polkadot-parachain
// benchmark
// pallet
// --chain=asset-hub-westend-dev
// --wasm-execution=compiled
// --pallet=pallet_asset_conversion
// --no-storage-info
// --no-median-slopes
// --no-min-squares
// --extrinsic=*
// --steps=2
// --repeat=1
// --json
// --header=./file_header.txt
// --output=./parachains/runtimes/assets/asset-hub-westend/src/weights/
#![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<T>(PhantomData<T>);
impl<T: frame_system::Config> pallet_asset_conversion::WeightInfo for WeightInfo<T> {
/// Storage: `AssetConversion::Pools` (r:1 w:1)
/// Proof: `AssetConversion::Pools` (`max_values`: None, `max_size`: Some(1224), added: 3699, mode: `MaxEncodedLen`)
/// Storage: UNKNOWN KEY `0x76a2c49709deec21d9c05f96c1f47351` (r:1 w:0)
/// Proof: UNKNOWN KEY `0x76a2c49709deec21d9c05f96c1f47351` (r:1 w:0)
/// 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: `480`
// Estimated: `6196`
// Minimum execution time: 115_870_000 picoseconds.
Weight::from_parts(115_870_000, 0)
.saturating_add(Weight::from_parts(0, 6196))
.saturating_add(T::DbWeight::get().reads(9))
.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: `1117`
// Estimated: `7404`
// Minimum execution time: 183_835_000 picoseconds.
Weight::from_parts(183_835_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: UNKNOWN KEY `0x2433d831722b1f4aeb1666953f1c0e77` (r:1 w:0)
/// Proof: UNKNOWN KEY `0x2433d831722b1f4aeb1666953f1c0e77` (r:1 w:0)
/// 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: `1106`
// Estimated: `7404`
// Minimum execution time: 166_533_000 picoseconds.
Weight::from_parts(166_533_000, 0)
.saturating_add(Weight::from_parts(0, 7404))
.saturating_add(T::DbWeight::get().reads(8))
.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() -> Weight {
// Proof Size summary in bytes:
// Measured: `1148`
// Estimated: `13818`
// Minimum execution time: 206_165_000 picoseconds.
Weight::from_parts(206_165_000, 0)
.saturating_add(Weight::from_parts(0, 13818))
.saturating_add(T::DbWeight::get().reads(8))
.saturating_add(T::DbWeight::get().writes(8))
}
/// 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() -> Weight {
// Proof Size summary in bytes:
// Measured: `1148`
// Estimated: `13818`
// Minimum execution time: 208_694_000 picoseconds.
Weight::from_parts(208_694_000, 0)
.saturating_add(Weight::from_parts(0, 13818))
.saturating_add(T::DbWeight::get().reads(8))
.saturating_add(T::DbWeight::get().writes(8))
}
}
@@ -18,9 +18,12 @@ use super::{
ParachainSystem, PolkadotXcm, PoolAssets, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin,
TrustBackedAssetsInstance, WeightToFee, XcmpQueue,
};
use crate::ForeignAssets;
use assets_common::matching::{
FromSiblingParachain, IsForeignConcreteAsset, StartsWith, StartsWithExplicitGlobalConsensus,
use crate::{AllowMultiAssetPools, ForeignAssets, LiquidityWithdrawalFee};
use assets_common::{
local_and_foreign_assets::MatchesLocalAndForeignAssetsMultiLocation,
matching::{
FromSiblingParachain, IsForeignConcreteAsset, StartsWith, StartsWithExplicitGlobalConsensus,
},
};
use frame_support::{
match_types, parameter_types,
@@ -163,6 +166,25 @@ pub type PoolFungiblesTransactor = FungiblesAdapter<
pub type AssetTransactors =
(CurrencyTransactor, FungiblesTransactor, ForeignFungiblesTransactor, PoolFungiblesTransactor);
/// Simple `MultiLocation` matcher for Local and Foreign asset `MultiLocation`.
pub struct LocalAndForeignAssetsMultiLocationMatcher;
impl MatchesLocalAndForeignAssetsMultiLocation for LocalAndForeignAssetsMultiLocationMatcher {
fn is_local(location: &MultiLocation) -> bool {
use assets_common::fungible_conversion::MatchesMultiLocation;
TrustBackedAssetsConvertedConcreteId::contains(location)
}
fn is_foreign(location: &MultiLocation) -> bool {
use assets_common::fungible_conversion::MatchesMultiLocation;
ForeignAssetsConvertedConcreteId::contains(location)
}
}
impl Contains<MultiLocation> for LocalAndForeignAssetsMultiLocationMatcher {
fn contains(location: &MultiLocation) -> bool {
Self::is_local(location) || Self::is_foreign(location)
}
}
/// 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
/// biases the kind of local `Origin` it will become.
@@ -217,6 +239,16 @@ impl Contains<RuntimeCall> for SafeCallFilter {
}
}
// Allow to change dedicated storage items (called by governance-like)
match call {
RuntimeCall::System(frame_system::Call::set_storage { items })
if items.iter().any(|(k, _)| {
k.eq(&AllowMultiAssetPools::key()) | k.eq(&LiquidityWithdrawalFee::key())
}) =>
return true,
_ => (),
};
matches!(
call,
RuntimeCall::PolkadotXcm(pallet_xcm::Call::force_xcm_version { .. }) |
@@ -540,7 +572,8 @@ pub struct BenchmarkMultiLocationConverter<SelfParaId> {
}
#[cfg(feature = "runtime-benchmarks")]
impl<SelfParaId> pallet_asset_conversion::BenchmarkHelper<MultiLocation>
impl<SelfParaId>
pallet_asset_conversion::BenchmarkHelper<MultiLocation, sp_std::boxed::Box<MultiLocation>>
for BenchmarkMultiLocationConverter<SelfParaId>
where
SelfParaId: Get<ParaId>,
@@ -555,4 +588,8 @@ where
),
}
}
fn multiasset_id(asset_id: u32) -> sp_std::boxed::Box<MultiLocation> {
sp_std::boxed::Box::new(Self::asset_id(asset_id))
}
}
@@ -28,7 +28,8 @@ use asset_hub_westend_runtime::{
AssetFeeAsExistentialDepositMultiplierFeeCharger, ForeignCreatorsSovereignAccountOf,
WestendLocation,
},
MetadataDepositBase, MetadataDepositPerByte, RuntimeCall, RuntimeEvent,
AllowMultiAssetPools, LiquidityWithdrawalFee, MetadataDepositBase, MetadataDepositPerByte,
RuntimeCall, RuntimeEvent,
};
use asset_test_utils::{CollatorSessionKeys, ExtBuilder, RuntimeHelper, XcmReceivedFrom};
use codec::{Decode, DecodeLimit, Encode};
@@ -39,7 +40,10 @@ use frame_support::{
weights::{Weight, WeightToFee as WeightToFeeT},
};
use parachains_common::{AccountId, AssetIdForTrustBackedAssets, AuraId, Balance};
use sp_runtime::traits::MaybeEquivalence;
use sp_runtime::{
traits::{CheckedAdd, CheckedSub, MaybeEquivalence},
Permill,
};
use std::convert::Into;
use xcm::{latest::prelude::*, VersionedXcm, MAX_XCM_DECODE_DEPTH};
use xcm_executor::{
@@ -652,3 +656,39 @@ fn plain_receive_teleported_asset_works() {
assert_eq!(outcome.ensure_complete(), Ok(()));
})
}
#[test]
fn change_allow_multi_asset_pools_by_governance_works() {
asset_test_utils::test_cases::change_storage_constant_by_governance_works::<
Runtime,
AllowMultiAssetPools,
bool,
>(
collator_session_keys(),
1000,
Box::new(|call| RuntimeCall::System(call).encode()),
|| (AllowMultiAssetPools::key().to_vec(), AllowMultiAssetPools::get()),
|old_value| !old_value,
)
}
#[test]
fn change_liquidity_withdrawal_fee_by_governance_works() {
asset_test_utils::test_cases::change_storage_constant_by_governance_works::<
Runtime,
LiquidityWithdrawalFee,
Permill,
>(
collator_session_keys(),
1000,
Box::new(|call| RuntimeCall::System(call).encode()),
|| (LiquidityWithdrawalFee::key().to_vec(), LiquidityWithdrawalFee::get()),
|old_value| {
if let Some(new_value) = old_value.checked_add(&Permill::from_percent(2)) {
new_value
} else {
old_value.checked_sub(&Permill::from_percent(2)).unwrap()
}
},
)
}