Skip to content

Commit

Permalink
#305 Fixing unexpectedly high weights for XCM pallet (#322)
Browse files Browse the repository at this point in the history
  • Loading branch information
KitHat authored Oct 8, 2024
1 parent 6953c33 commit 7d38311
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 16 deletions.
108 changes: 102 additions & 6 deletions evm-template/runtime/src/apis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,7 @@ impl_runtime_apis! {
).into());
/// The base fee for the message delivery fees. Kusama is based for the reference.
pub const ToParentBaseDeliveryFee: u128 = CENTS.saturating_mul(3);
pub const InitialTransferAssetAmount: u128 = 4001070000100;
}
pub type PriceForParentDelivery = polkadot_runtime_common::xcm_sender::ExponentialPrice<
FeeAssetId,
Expand All @@ -486,7 +487,7 @@ impl_runtime_apis! {
ParachainSystem,
>;
use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
use xcm::latest::prelude::{Asset, AssetId, Assets as AssetList, Fungible, Location, Parachain, Parent, ParentThen};
use xcm::latest::prelude::{Asset, AssetId, Assets as AssetList, Fungible, Location, Parachain, Parent, ParentThen, PalletInstance, GeneralIndex};
impl pallet_xcm::benchmarking::Config for Runtime {
type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper<
xcm_config::XcmConfig,
Expand All @@ -503,18 +504,113 @@ impl_runtime_apis! {
}

fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> {
use frame_support::traits::PalletInfoAccess;
use xcm_primitives::AssetTypeGetter;
use frame_system::RawOrigin;

// set up fee asset
let fee_location = RelayLocation::get();
let who: AccountId = frame_benchmarking::whitelisted_caller();

let Some(location_v3) = xcm::v3::Location::try_from(fee_location.clone()).ok() else {
return None;
};
let asset_type = AssetType::Xcm(location_v3);

let local_asset_id: crate::types::AssetId = asset_type.clone().into();
let manager_id = AssetManager::account_id();
let _ = Assets::force_create(RuntimeOrigin::root(), local_asset_id.clone().into(), sp_runtime::MultiAddress::Id(manager_id.clone()), true, 1);
let _ = Assets::mint(
RawOrigin::Signed(manager_id.clone()).into(),
local_asset_id.into(),
sp_runtime::MultiAddress::Id(who),
InitialTransferAssetAmount::get(),
);
AssetManager::set_asset_type_asset_id(asset_type.clone(), local_asset_id.into());

// open a mock parachain channel
ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests(
RandomParaId::get().into()
);

// set up transfer asset
let initial_asset_amount: u128 = InitialTransferAssetAmount::get();
let (asset_id, _, _) = pallet_assets::benchmarking::create_default_minted_asset::<
Runtime,
()
>(true, initial_asset_amount);

let asset_id_u128: u128 = asset_id.into();
let self_reserve = Location {
parents: 0,
interior: [
PalletInstance(<Assets as PalletInfoAccess>::index() as u8), GeneralIndex(asset_id_u128)
].into()
};

let Some(location_v3) = xcm::v3::Location::try_from(self_reserve.clone()).ok() else {
return None;
};
let asset_type = AssetType::Xcm(location_v3);
AssetManager::set_asset_type_asset_id(asset_type.clone(), asset_id_u128);

let asset = Asset {
fun: Fungible(ExistentialDeposit::get()),
id: AssetId(self_reserve.into())
}.into();
Some((
Asset {
fun: Fungible(ExistentialDeposit::get()),
id: AssetId(Parent.into())
}.into(),
asset,
ParentThen(Parachain(RandomParaId::get().into()).into()).into(),
))
}

fn set_up_complex_asset_transfer(
) -> Option<(AssetList, u32, Location, Box<dyn FnOnce()>)> {
None
use frame_support::traits::PalletInfoAccess;
use xcm_primitives::AssetTypeGetter;
// set up local asset
let initial_asset_amount: u128 = 1000000011;

let (asset_id, _, _) = pallet_assets::benchmarking::create_default_minted_asset::<
Runtime,
()
>(true, initial_asset_amount);

let asset_id_u128: u128 = asset_id.into();

let self_reserve = Location {
parents:0,
interior: [
PalletInstance(<Assets as PalletInfoAccess>::index() as u8), GeneralIndex(asset_id_u128)
].into()
};

let Some(location_v3) = xcm::v3::Location::try_from(self_reserve.clone()).ok() else {
return None;
};
let asset_type = AssetType::Xcm(location_v3);
AssetManager::set_asset_type_asset_id(asset_type.clone(), asset_id_u128);

let destination: xcm::v4::Location = Parent.into();

// set up fee asset
let fee_amount: u128 = <Runtime as pallet_balances::Config>::ExistentialDeposit::get();
let asset_amount: u128 = 10;
let fee_asset: Asset = (self_reserve.clone(), fee_amount).into();
let transfer_asset: Asset = (self_reserve.clone(), asset_amount).into();

let assets: cumulus_primitives_core::Assets = vec![fee_asset.clone(), transfer_asset].into();
let fee_index: u32 = 0;

let who = frame_benchmarking::whitelisted_caller();

let verify: Box<dyn FnOnce()> = Box::new(move || {
// verify balance after transfer, decreased by
// transferred amount (and delivery fees)
assert!(Assets::balance(asset_id_u128, &who) <= initial_asset_amount - fee_amount);
});

Some((assets, fee_index, destination, verify))
}

fn get_asset() -> Asset {
Expand Down
6 changes: 4 additions & 2 deletions evm-template/runtime/src/configs/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,11 +297,13 @@ impl pallet_xcm::Config for Runtime {
type Weigher = FixedWeightBounds<UnitWeightCost, RuntimeCall, MaxInstructions>;
/// Rerun benchmarks if you are making changes to runtime configuration.
type WeightInfo = weights::pallet_xcm::WeightInfo<Runtime>;
#[cfg(feature = "runtime-benchmarks")]
type XcmExecuteFilter = Everything;
#[cfg(not(feature = "runtime-benchmarks"))]
type XcmExecuteFilter = Nothing;
// ^ Disable dispatchable execute on the XCM pallet.
// Needs to be `Everything` for local testing.
type XcmExecutor = XcmExecutor<XcmConfig>;
type XcmReserveTransferFilter = Nothing;
type XcmReserveTransferFilter = Everything;
type XcmRouter = XcmRouter;
type XcmTeleportFilter = Nothing;

Expand Down
70 changes: 66 additions & 4 deletions generic-template/runtime/src/apis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ impl_runtime_apis! {
ParachainSystem,
>;
use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
use xcm::latest::prelude::{Asset, AssetId, Assets as AssetList, Fungible, Location, Parachain, Parent, ParentThen};
use xcm::latest::prelude::{Asset, AssetId, Assets as AssetList, Fungible, Location, Parachain, Parent, ParentThen, PalletInstance, GeneralIndex};
impl pallet_xcm::benchmarking::Config for Runtime {
type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper<
xcm_config::XcmConfig,
Expand All @@ -278,23 +278,85 @@ impl_runtime_apis! {
}

fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> {
use frame_support::traits::PalletInfoAccess;
ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests(
RandomParaId::get().into()
);
let balance = 3001070000000;
let who = frame_benchmarking::whitelisted_caller();
let _ =
<Balances as frame_support::traits::Currency<_>>::make_free_balance_be(&who, balance);

let asset_amount: u128 = 10u128;
let initial_asset_amount: u128 = asset_amount * 10;

let (asset_id, _, _) = pallet_assets::benchmarking::create_default_minted_asset::<
Runtime,
()
>(true, initial_asset_amount);

let asset_id_u32: u32 = asset_id.into();

let location = Location {parents: 0, interior: (PalletInstance(<Assets as PalletInfoAccess>::index() as u8), GeneralIndex(asset_id_u32 as u128)).into()};
Some((
Asset {
fun: Fungible(ExistentialDeposit::get()),
id: AssetId(Parent.into())
id: AssetId(location.into())
}.into(),
ParentThen(Parachain(RandomParaId::get().into()).into()).into(),
))
}

fn set_up_complex_asset_transfer(
) -> Option<(AssetList, u32, Location, Box<dyn FnOnce()>)> {
None
use frame_support::traits::PalletInfoAccess;
// set up local asset
let asset_amount: u128 = 10u128;
let initial_asset_amount: u128 = 1000000011;
let (asset_id, _, _) = pallet_assets::benchmarking::create_default_minted_asset::<
Runtime,
()
>(true, initial_asset_amount);
let asset_id_u32: u32 = asset_id.into();

let self_reserve = Location {
parents:0,
interior: [
PalletInstance(<Assets as PalletInfoAccess>::index() as u8), GeneralIndex(asset_id_u32 as u128)
].into()
};

let destination: xcm::v4::Location = Parent.into();

let fee_amount: u128 = <Runtime as pallet_balances::Config>::ExistentialDeposit::get();
let fee_asset: Asset = (self_reserve.clone(), fee_amount).into();

// Give some multiple of transferred amount
let balance = fee_amount * 1000;
let who = frame_benchmarking::whitelisted_caller();
let _ =
<Balances as frame_support::traits::Currency<_>>::make_free_balance_be(&who, balance);

// verify initial balance
assert_eq!(Balances::free_balance(&who), balance);
let transfer_asset: Asset = (self_reserve.clone(), asset_amount).into();

let assets: cumulus_primitives_core::Assets = vec![fee_asset.clone(), transfer_asset].into();
let fee_index: u32 = 0;

let verify: Box<dyn FnOnce()> = Box::new(move || {
// verify balance after transfer, decreased by
// transferred amount (and delivery fees)
assert!(Assets::balance(asset_id_u32, &who) <= initial_asset_amount - fee_amount);
});

Some((assets, fee_index, destination, verify))
}

fn get_asset() -> Asset {
use frame_support::traits::PalletInfoAccess;
Asset {
id: AssetId(Location::parent()),
id: AssetId((Location {parents: 0, interior: (PalletInstance(<Assets as PalletInfoAccess>::index() as u8), GeneralIndex(1)).into()}).into()),
fun: Fungible(ExistentialDeposit::get()),
}
}
Expand Down
4 changes: 2 additions & 2 deletions generic-template/runtime/src/configs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,8 +323,8 @@ impl pallet_assets::Config for Runtime {
type ApprovalDeposit = ApprovalDeposit;
type AssetAccountDeposit = AssetAccountDeposit;
type AssetDeposit = AssetDeposit;
type AssetId = u32;
type AssetIdParameter = parity_scale_codec::Compact<u32>;
type AssetId = crate::types::AssetId;
type AssetIdParameter = parity_scale_codec::Compact<crate::types::AssetId>;
type Balance = Balance;
#[cfg(feature = "runtime-benchmarks")]
type BenchmarkHelper = ();
Expand Down
6 changes: 4 additions & 2 deletions generic-template/runtime/src/configs/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,11 +223,13 @@ impl pallet_xcm::Config for Runtime {
type Weigher = FixedWeightBounds<UnitWeightCost, RuntimeCall, MaxInstructions>;
/// Rerun benchmarks if you are making changes to runtime configuration.
type WeightInfo = weights::pallet_xcm::WeightInfo<Runtime>;
#[cfg(feature = "runtime-benchmarks")]
type XcmExecuteFilter = Everything;
#[cfg(not(feature = "runtime-benchmarks"))]
type XcmExecuteFilter = Nothing;
// ^ Disable dispatchable execute on the XCM pallet.
// Needs to be `Everything` for local testing.
type XcmExecutor = XcmExecutor<XcmConfig>;
type XcmReserveTransferFilter = Nothing;
type XcmReserveTransferFilter = Everything;
type XcmRouter = XcmRouter;
type XcmTeleportFilter = Nothing;

Expand Down
3 changes: 3 additions & 0 deletions generic-template/runtime/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ pub type AccountId = <<Signature as Verify>::Signer as IdentifyAccount>::Account
/// Balance of an account.
pub type Balance = u128;

/// Identifier of an asset
pub type AssetId = u32;

/// Index of a transaction in the chain.
pub type Nonce = u32;

Expand Down

0 comments on commit 7d38311

Please sign in to comment.