Skip to content

Commit

Permalink
[pallet-xcm] Adjust benchmarks (teleport_assets/reserve_transfer_asse…
Browse files Browse the repository at this point in the history
…ts) not relying on ED (#3464)

## Problem
During the bumping of the `polkadot-fellows` repository to
`polkadot-sdk@1.6.0`, I encountered a situation where the benchmarks
`teleport_assets` and `reserve_transfer_assets` in AssetHubKusama
started to fail. This issue arose due to a decreased ED balance for
AssetHubs introduced
[here](https://github.com/polkadot-fellows/runtimes/pull/158/files#diff-80668ff8e793b64f36a9a3ec512df5cbca4ad448c157a5d81abda1b15f35f1daR213),
and also because of a [missing CI
pipeline](polkadot-fellows/runtimes#197) to
check the benchmarks, which went unnoticed.

These benchmarks expect the `caller` to have enough:
1. balance to transfer (BTT)
2. balance for paying delivery (BFPD).
 
So the initial balance was calculated as `ED * 100`, which seems
reasonable:
```
const ED_MULTIPLIER: u32 = 100;
let balance = existential_deposit.saturating_mul(ED_MULTIPLIER.into());`
```
The problem arises when the price for delivery is 100 times higher than
the existential deposit. In other words, when `ED * 100` does not cover
`BTT` + `BFPD`.

I check AHR/AHW/AHK/AHP and this problem has only AssetHubKusama
```
ED: 3333333
calculated price to parent delivery:  1031666634  (from xcm logs from the benchmark)
---

3333333 * 100 - BTT(3333333) - BFPD(1031666634) = −701666667
```
which results in the error;
```
2024-02-23 09:19:42 Unable to charge fee with error Module(ModuleError { index: 31, error: [17, 0, 0, 0], message: Some("FeesNotMet") })
Error: Input("Benchmark pallet_xcm::reserve_transfer_assets failed: FeesNotMet")
     
```

## Solution

The benchmarks `teleport_assets` and `reserve_transfer_assets` were
fixed by removing `ED * 100` and replacing it with `DeliveryHelper`
logic, which calculates the (almost real) price for delivery and sets it
along with the existential deposit as the initial balance for the
account used in the benchmark.


## TODO

- [ ] patch for 1.6 -
#3466
- [ ] patch for 1.7 -
#3465
- [ ] patch for 1.8 - TODO: PR

---------

Co-authored-by: Francisco Aguirre <franciscoaguirreperez@gmail.com>
  • Loading branch information
bkontur and franciscoaguirre authored Feb 26, 2024
1 parent b9c792a commit 3d9439f
Show file tree
Hide file tree
Showing 28 changed files with 329 additions and 136 deletions.
3 changes: 1 addition & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions cumulus/pallets/parachain-system/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ sp-version = { path = "../../../substrate/primitives/version", default-features
# Polkadot
polkadot-parachain-primitives = { path = "../../../polkadot/parachain", default-features = false, features = ["wasm-api"] }
polkadot-runtime-parachains = { path = "../../../polkadot/runtime/parachains", default-features = false }
polkadot-runtime-common = { path = "../../../polkadot/runtime/common", default-features = false, optional = true }
xcm = { package = "staging-xcm", path = "../../../polkadot/xcm", default-features = false }

# Cumulus
Expand Down Expand Up @@ -79,6 +80,7 @@ std = [
"log/std",
"pallet-message-queue/std",
"polkadot-parachain-primitives/std",
"polkadot-runtime-common/std",
"polkadot-runtime-parachains/std",
"scale-info/std",
"sp-core/std",
Expand All @@ -102,6 +104,7 @@ runtime-benchmarks = [
"frame-system/runtime-benchmarks",
"pallet-message-queue/runtime-benchmarks",
"polkadot-parachain-primitives/runtime-benchmarks",
"polkadot-runtime-common/runtime-benchmarks",
"polkadot-runtime-parachains/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
]
Expand All @@ -110,6 +113,7 @@ try-runtime = [
"frame-support/try-runtime",
"frame-system/try-runtime",
"pallet-message-queue/try-runtime",
"polkadot-runtime-common?/try-runtime",
"polkadot-runtime-parachains/try-runtime",
"sp-runtime/try-runtime",
]
Expand Down
9 changes: 9 additions & 0 deletions cumulus/pallets/parachain-system/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1610,6 +1610,15 @@ impl<T: Config> UpwardMessageSender for Pallet<T> {
}
}

#[cfg(feature = "runtime-benchmarks")]
impl<T: Config> polkadot_runtime_common::xcm_sender::EnsureForParachain for Pallet<T> {
fn ensure(para_id: ParaId) {
if let ChannelStatus::Closed = Self::get_channel_status(para_id) {
Self::open_outbound_hrmp_channel_for_benchmarks_or_tests(para_id)
}
}
}

/// Something that can check the inherents of a block.
#[cfg_attr(
feature = "parameterized-consensus-hook",
Expand Down
42 changes: 27 additions & 15 deletions cumulus/parachains/runtimes/assets/asset-hub-rococo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1355,8 +1355,31 @@ impl_runtime_apis! {
Config as XcmBridgeHubRouterConfig,
};

parameter_types! {
pub ExistentialDepositAsset: Option<Asset> = Some((
TokenLocation::get(),
ExistentialDeposit::get()
).into());
pub const RandomParaId: ParaId = ParaId::new(43211234);
}

use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
impl pallet_xcm::benchmarking::Config for Runtime {
type DeliveryHelper = (
cumulus_primitives_utility::ToParentDeliveryHelper<
xcm_config::XcmConfig,
ExistentialDepositAsset,
xcm_config::PriceForParentDelivery,
>,
polkadot_runtime_common::xcm_sender::ToParachainDeliveryHelper<
xcm_config::XcmConfig,
ExistentialDepositAsset,
PriceForSiblingParachainDelivery,
RandomParaId,
ParachainSystem,
>
);

fn reachable_dest() -> Option<Location> {
Some(Parent.into())
}
Expand All @@ -1365,25 +1388,21 @@ impl_runtime_apis! {
// Relay/native token can be teleported between AH and Relay.
Some((
Asset {
fun: Fungible(EXISTENTIAL_DEPOSIT),
fun: Fungible(ExistentialDeposit::get()),
id: AssetId(Parent.into())
},
Parent.into(),
))
}

fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> {
// AH can reserve transfer native token to some random parachain.
let random_para_id = 43211234;
ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests(
random_para_id.into()
);
Some((
Asset {
fun: Fungible(EXISTENTIAL_DEPOSIT),
fun: Fungible(ExistentialDeposit::get()),
id: AssetId(Parent.into())
},
ParentThen(Parachain(random_para_id).into()).into(),
// AH can reserve transfer native token to some random parachain.
ParentThen(Parachain(RandomParaId::get().into()).into()).into(),
))
}

Expand Down Expand Up @@ -1469,13 +1488,6 @@ impl_runtime_apis! {
use xcm_config::{TokenLocation, MaxAssetsIntoHolding};
use pallet_xcm_benchmarks::asset_instance_from;

parameter_types! {
pub ExistentialDepositAsset: Option<Asset> = Some((
TokenLocation::get(),
ExistentialDeposit::get()
).into());
}

impl pallet_xcm_benchmarks::Config for Runtime {
type XcmConfig = xcm_config::XcmConfig;
type AccountIdConverter = xcm_config::LocationToAccountId;
Expand Down
42 changes: 27 additions & 15 deletions cumulus/parachains/runtimes/assets/asset-hub-westend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1427,8 +1427,31 @@ impl_runtime_apis! {
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
impl cumulus_pallet_session_benchmarking::Config for Runtime {}

parameter_types! {
pub ExistentialDepositAsset: Option<Asset> = Some((
WestendLocation::get(),
ExistentialDeposit::get()
).into());
pub const RandomParaId: ParaId = ParaId::new(43211234);
}

use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
impl pallet_xcm::benchmarking::Config for Runtime {
type DeliveryHelper = (
cumulus_primitives_utility::ToParentDeliveryHelper<
xcm_config::XcmConfig,
ExistentialDepositAsset,
xcm_config::PriceForParentDelivery,
>,
polkadot_runtime_common::xcm_sender::ToParachainDeliveryHelper<
xcm_config::XcmConfig,
ExistentialDepositAsset,
PriceForSiblingParachainDelivery,
RandomParaId,
ParachainSystem,
>
);

fn reachable_dest() -> Option<Location> {
Some(Parent.into())
}
Expand All @@ -1437,25 +1460,21 @@ impl_runtime_apis! {
// Relay/native token can be teleported between AH and Relay.
Some((
Asset {
fun: Fungible(EXISTENTIAL_DEPOSIT),
fun: Fungible(ExistentialDeposit::get()),
id: AssetId(Parent.into())
},
Parent.into(),
))
}

fn reserve_transferable_asset_and_dest() -> Option<(Asset, Location)> {
// AH can reserve transfer native token to some random parachain.
let random_para_id = 43211234;
ParachainSystem::open_outbound_hrmp_channel_for_benchmarks_or_tests(
random_para_id.into()
);
Some((
Asset {
fun: Fungible(EXISTENTIAL_DEPOSIT),
fun: Fungible(ExistentialDeposit::get()),
id: AssetId(Parent.into())
},
ParentThen(Parachain(random_para_id).into()).into(),
// AH can reserve transfer native token to some random parachain.
ParentThen(Parachain(RandomParaId::get().into()).into()).into(),
))
}

Expand Down Expand Up @@ -1546,13 +1565,6 @@ impl_runtime_apis! {
use xcm_config::{MaxAssetsIntoHolding, WestendLocation};
use pallet_xcm_benchmarks::asset_instance_from;

parameter_types! {
pub ExistentialDepositAsset: Option<Asset> = Some((
WestendLocation::get(),
ExistentialDeposit::get()
).into());
}

impl pallet_xcm_benchmarks::Config for Runtime {
type XcmConfig = xcm_config::XcmConfig;
type AccountIdConverter = xcm_config::LocationToAccountId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1109,6 +1109,12 @@ impl_runtime_apis! {

use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
impl pallet_xcm::benchmarking::Config for Runtime {
type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper<
xcm_config::XcmConfig,
ExistentialDepositAsset,
xcm_config::PriceForParentDelivery,
>;

fn reachable_dest() -> Option<Location> {
Some(Parent.into())
}
Expand All @@ -1117,7 +1123,7 @@ impl_runtime_apis! {
// Relay/native token can be teleported between BH and Relay.
Some((
Asset {
fun: Fungible(EXISTENTIAL_DEPOSIT),
fun: Fungible(ExistentialDeposit::get()),
id: AssetId(Parent.into())
},
Parent.into(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,12 @@ impl_runtime_apis! {

use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
impl pallet_xcm::benchmarking::Config for Runtime {
type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper<
xcm_config::XcmConfig,
ExistentialDepositAsset,
xcm_config::PriceForParentDelivery,
>;

fn reachable_dest() -> Option<Location> {
Some(Parent.into())
}
Expand All @@ -814,7 +820,7 @@ impl_runtime_apis! {
// Relay/native token can be teleported between BH and Relay.
Some((
Asset {
fun: Fungible(EXISTENTIAL_DEPOSIT),
fun: Fungible(ExistentialDeposit::get()),
id: AssetId(Parent.into())
},
Parent.into(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -986,8 +986,21 @@ impl_runtime_apis! {
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
impl cumulus_pallet_session_benchmarking::Config for Runtime {}

parameter_types! {
pub ExistentialDepositAsset: Option<Asset> = Some((
xcm_config::WndLocation::get(),
ExistentialDeposit::get()
).into());
}

use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
impl pallet_xcm::benchmarking::Config for Runtime {
type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper<
xcm_config::XcmConfig,
ExistentialDepositAsset,
xcm_config::PriceForParentDelivery,
>;

fn reachable_dest() -> Option<Location> {
Some(Parent.into())
}
Expand All @@ -996,7 +1009,7 @@ impl_runtime_apis! {
// Relay/native token can be teleported between Collectives and Relay.
Some((
Asset {
fun: Fungible(EXISTENTIAL_DEPOSIT),
fun: Fungible(ExistentialDeposit::get()),
id: AssetId(Parent.into())
}.into(),
Parent.into(),
Expand Down
23 changes: 20 additions & 3 deletions cumulus/parachains/runtimes/contracts/contracts-rococo/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ use frame_support::{
dispatch::DispatchClass,
genesis_builder_helper::{build_config, create_default_config},
parameter_types,
traits::{ConstBool, ConstU128, ConstU16, ConstU32, ConstU64, ConstU8},
traits::{ConstBool, ConstU16, ConstU32, ConstU64, ConstU8},
weights::{ConstantMultiplier, Weight},
PalletId,
};
Expand Down Expand Up @@ -205,14 +205,18 @@ impl pallet_authorship::Config for Runtime {
type EventHandler = (CollatorSelection,);
}

parameter_types! {
pub const ExistentialDeposit: Balance = EXISTENTIAL_DEPOSIT;
}

impl pallet_balances::Config for Runtime {
type MaxLocks = ConstU32<50>;
/// The type for recording an account's balance.
type Balance = Balance;
/// The ubiquitous event type.
type RuntimeEvent = RuntimeEvent;
type DustRemoval = ();
type ExistentialDeposit = ConstU128<EXISTENTIAL_DEPOSIT>;
type ExistentialDeposit = ExistentialDeposit;
type AccountStore = System;
type WeightInfo = pallet_balances::weights::SubstrateWeight<Runtime>;
type MaxReserves = ConstU32<50>;
Expand Down Expand Up @@ -713,9 +717,22 @@ impl_runtime_apis! {
use cumulus_pallet_session_benchmarking::Pallet as SessionBench;
impl cumulus_pallet_session_benchmarking::Config for Runtime {}

parameter_types! {
pub ExistentialDepositAsset: Option<Asset> = Some((
xcm_config::RelayLocation::get(),
ExistentialDeposit::get()
).into());
}

use xcm::latest::prelude::*;
use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
impl pallet_xcm::benchmarking::Config for Runtime {
type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper<
xcm_config::XcmConfig,
ExistentialDepositAsset,
xcm_config::PriceForParentDelivery,
>;

fn reachable_dest() -> Option<Location> {
Some(Parent.into())
}
Expand All @@ -724,7 +741,7 @@ impl_runtime_apis! {
// Relay/native token can be teleported between Contracts-System-Para and Relay.
Some((
Asset {
fun: Fungible(EXISTENTIAL_DEPOSIT),
fun: Fungible(ExistentialDeposit::get()),
id: AssetId(Parent.into())
},
Parent.into(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,12 @@ impl_runtime_apis! {

use pallet_xcm::benchmarking::Pallet as PalletXcmExtrinsicsBenchmark;
impl pallet_xcm::benchmarking::Config for Runtime {
type DeliveryHelper = cumulus_primitives_utility::ToParentDeliveryHelper<
xcm_config::XcmConfig,
ExistentialDepositAsset,
xcm_config::PriceForParentDelivery,
>;

fn reachable_dest() -> Option<Location> {
Some(Parent.into())
}
Expand All @@ -723,7 +729,7 @@ impl_runtime_apis! {
// Relay/native token can be teleported between AH and Relay.
Some((
Asset {
fun: Fungible(EXISTENTIAL_DEPOSIT),
fun: Fungible(ExistentialDeposit::get()),
id: AssetId(Parent.into())
},
Parent.into(),
Expand Down
Loading

0 comments on commit 3d9439f

Please sign in to comment.