Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions benchmarking/xcm-weight-template.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
{{header}}
//! Autogenerated weights for `{{pallet}}`
//!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION {{version}}
//! DATE: {{date}}, STEPS: `{{cmd.steps}}`, REPEAT: `{{cmd.repeat}}`, LOW RANGE: `{{cmd.lowest_range_values}}`, HIGH RANGE: `{{cmd.highest_range_values}}`
//! WORST CASE MAP SIZE: `{{cmd.worst_case_map_values}}`
//! HOSTNAME: `{{hostname}}`, CPU: `{{cpuname}}`
//! WASM-EXECUTION: {{cmd.wasm_execution}}, CHAIN: {{cmd.chain}}, DB CACHE: {{cmd.db_cache}}

// Executed Command:
{{#each args as |arg|}}
// {{arg}}
{{/each}}

#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(unused_parens)]
#![allow(unused_imports)]

use frame_support::{traits::Get, weights::Weight};
use core::marker::PhantomData;

/// Weight functions for `{{pallet}}`.
pub struct WeightInfo<T>(PhantomData<T>);
impl<T: frame_system::Config> WeightInfo<T> {
{{#each benchmarks as |benchmark|}}
{{#each benchmark.comments as |comment|}}
/// {{comment}}
{{/each}}
{{#each benchmark.component_ranges as |range|}}
/// The range of component `{{range.name}}` is `[{{range.min}}, {{range.max}}]`.
{{/each}}
pub(crate) fn {{benchmark.name~}}
(
{{~#each benchmark.components as |c| ~}}
{{~#if (not c.is_used)}}_{{/if}}{{c.name}}: u32, {{/each~}}
) -> Weight {
// Proof Size summary in bytes:
// Measured: `{{benchmark.base_recorded_proof_size}}{{#each benchmark.component_recorded_proof_size as |cp|}} + {{cp.name}} * ({{cp.slope}} ±{{underscore cp.error}}){{/each}}`
// Estimated: `{{benchmark.base_calculated_proof_size}}{{#each benchmark.component_calculated_proof_size as |cp|}} + {{cp.name}} * ({{cp.slope}} ±{{underscore cp.error}}){{/each}}`
// Minimum execution time: {{underscore benchmark.min_execution_time}}_000 picoseconds.
Weight::from_parts({{underscore benchmark.base_weight}}, {{benchmark.base_calculated_proof_size}})
{{#each benchmark.component_weight as |cw|}}
// Standard Error: {{underscore cw.error}}
.saturating_add(Weight::from_parts({{underscore cw.slope}}, 0).saturating_mul({{cw.name}}.into()))
{{/each}}
{{#if (ne benchmark.base_reads "0")}}
.saturating_add(T::DbWeight::get().reads({{benchmark.base_reads}}))
{{/if}}
{{#each benchmark.component_reads as |cr|}}
.saturating_add(T::DbWeight::get().reads(({{cr.slope}}_u64).saturating_mul({{cr.name}}.into())))
{{/each}}
{{#if (ne benchmark.base_writes "0")}}
.saturating_add(T::DbWeight::get().writes({{benchmark.base_writes}}))
{{/if}}
{{#each benchmark.component_writes as |cw|}}
.saturating_add(T::DbWeight::get().writes(({{cw.slope}}_u64).saturating_mul({{cw.name}}.into())))
{{/each}}
{{#each benchmark.component_calculated_proof_size as |cp|}}
.saturating_add(Weight::from_parts(0, {{cp.slope}}).saturating_mul({{cp.name}}.into()))
{{/each}}
}
{{/each}}
}
21 changes: 21 additions & 0 deletions pallets/moonbeam-foreign-assets/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,16 @@ pub mod pallet {
AssetsByLocation::<T>::insert(&asset_location, (asset_id, AssetStatus::Active));
AssetsById::<T>::insert(&asset_id, asset_location);
}

#[cfg(feature = "runtime-benchmarks")]
pub fn create_asset_contract(
asset_id: AssetId,
decimals: u8,
symbol: &str,
name: &str,
) -> Result<H160, Error<T>> {
EvmCaller::<T>::erc20_create(asset_id, decimals, symbol, name)
}
}

#[pallet::call]
Expand Down Expand Up @@ -771,6 +781,17 @@ pub mod pallet {

Ok(what.clone().into())
}

#[cfg(feature = "runtime-benchmarks")]
fn can_check_out(_dest: &Location, _what: &Asset, _context: &XcmContext) -> XcmResult {
// Needed for the benchmarks to work
Ok(())
}

#[cfg(feature = "runtime-benchmarks")]
fn check_out(_dest: &Location, _what: &Asset, _context: &XcmContext) {
// Needed for benchmarks to work
}
}

impl<T: Config> sp_runtime::traits::MaybeEquivalence<Location, AssetId> for Pallet<T> {
Expand Down
43 changes: 19 additions & 24 deletions pallets/xcm-weight-trader/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -408,11 +408,11 @@ impl<T: crate::Config> WeightTrader for Trader<T> {
}
}

fn refund_weight(&mut self, actual_weight: Weight, context: &XcmContext) -> Option<Asset> {
fn refund_weight(&mut self, weight_to_refund: Weight, context: &XcmContext) -> Option<Asset> {
log::trace!(
target: "xcm-weight-trader",
"refund_weight weight: {:?}, context: {:?}, available weight: {:?}, asset: {:?}",
actual_weight,
weight_to_refund,
context,
self.0,
self.1
Expand All @@ -422,32 +422,27 @@ impl<T: crate::Config> WeightTrader for Trader<T> {
id: XcmAssetId(location),
}) = self.1.take()
{
if actual_weight == self.0 {
self.1 = Some(Asset {
fun: Fungibility::Fungible(initial_amount),
id: XcmAssetId(location),
});
None
} else {
let weight = actual_weight.min(self.0);
let amount: u128 =
Self::compute_amount_to_charge(&weight, &location).unwrap_or(u128::MAX);
let final_amount = amount.min(initial_amount);
let amount_to_refund = initial_amount.saturating_sub(final_amount);
self.0 -= weight;
self.1 = Some(Asset {
fun: Fungibility::Fungible(final_amount),
id: XcmAssetId(location.clone()),
});
log::trace!(
target: "xcm-weight-trader",
"refund_weight amount to refund: {:?}",
amount_to_refund
);
let weight_to_refund = weight_to_refund.min(self.0);
let amount_to_refund: u128 =
Self::compute_amount_to_charge(&weight_to_refund, &location).unwrap_or(u128::MAX);
let final_amount = initial_amount.saturating_sub(amount_to_refund);
self.0 -= weight_to_refund;
self.1 = Some(Asset {
fun: Fungibility::Fungible(final_amount),
id: XcmAssetId(location.clone()),
});
log::trace!(
target: "xcm-weight-trader",
"refund_weight amount to refund: {:?}",
amount_to_refund
);
if amount_to_refund > 0 {
Some(Asset {
fun: Fungibility::Fungible(amount_to_refund),
id: XcmAssetId(location),
})
} else {
None
}
} else {
None
Expand Down
22 changes: 11 additions & 11 deletions pallets/xcm-weight-trader/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,10 @@ fn test_trader_native_asset() {
let actual_weight = weight_to_buy;
assert_eq!(
trader.refund_weight(actual_weight, &dummy_xcm_context),
None
Some(Asset {
id: XcmAssetId(Location::here()),
fun: Fungibility::Fungible(10_000),
}),
);

// Should not be able to buy weight again with the same trader
Expand All @@ -443,9 +446,9 @@ fn test_trader_native_asset() {
Err(XcmError::NotWithdrawable)
);

// Fees asset should be deposited into XcmFeesAccount
// XcmFeesAccount should have zero balance
drop(trader);
assert_eq!(Balances::free_balance(&xcm_fees_account()), 10_000);
assert_eq!(Balances::free_balance(&xcm_fees_account()), 0);

// Should be able to buy weight with more native asset (and get back unused amount)
let mut trader = Trader::<Test>::new();
Expand All @@ -471,17 +474,14 @@ fn test_trader_native_asset() {
assert_eq!(
trader.refund_weight(actual_weight, &dummy_xcm_context),
Some(Asset {
fun: Fungibility::Fungible(2_000),
fun: Fungibility::Fungible(8_000),
id: XcmAssetId(Location::here()),
})
);

// Fees asset should be deposited again into XcmFeesAccount (2 times cost minus one refund)
// Fees asset should be deposited again into XcmFeesAccount
drop(trader);
assert_eq!(
Balances::free_balance(&xcm_fees_account()),
(2 * 10_000) - 2_000
);
assert_eq!(Balances::free_balance(&xcm_fees_account()), 2_000);
})
}

Expand Down Expand Up @@ -526,7 +526,7 @@ fn test_trader_parent_asset() {
assert_eq!(
trader.refund_weight(actual_weight, &dummy_xcm_context),
Some(Asset {
fun: Fungibility::Fungible(4_000_000_000_000),
fun: Fungibility::Fungible(16_000_000_000_000),
id: XcmAssetId(Location::parent()),
})
);
Expand All @@ -535,7 +535,7 @@ fn test_trader_parent_asset() {
drop(trader);
assert_eq!(
get_parent_asset_deposited(),
Some((xcm_fees_account(), 20_000_000_000_000 - 4_000_000_000_000))
Some((xcm_fees_account(), 20_000_000_000_000 - 16_000_000_000_000))
);

// Should not be able to buy weight if the asset is not a first position
Expand Down
109 changes: 96 additions & 13 deletions runtime/common/src/apis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,33 @@ macro_rules! impl_runtime_apis_plus_common {
}
}

/// AccountId Converter used for benchmarks.
///
/// * AccountId32 Junction is being used in pallet_xcm_benchmarks
/// * Parent is used as valid destination location for benchmarking.
#[cfg(feature = "runtime-benchmarks")]
pub struct BenchAccountIdConverter<AccountId>(sp_std::marker::PhantomData<AccountId>);

#[cfg(feature = "runtime-benchmarks")]
impl<AccountId: From<[u8; 20]> + Into<[u8; 20]> + Clone> xcm_executor::traits::ConvertLocation<AccountId>
for BenchAccountIdConverter<AccountId>
{
fn convert_location(location: &xcm::latest::prelude::Location) -> Option<AccountId> {
match location.unpack() {
(0, [xcm::latest::prelude::AccountId32 { id, network: None }]) => {
// take the first 20 bytes of the id and convert to fixed-size array
let mut id20: [u8; 20] = [0u8; 20];
id20.copy_from_slice(&id[..20]);
Some(id20.into())
},
(1, []) => {
Some([1u8; 20].into())
},
_ => return None,
}
}
}

impl_runtime_apis! {
$($custom)*

Expand Down Expand Up @@ -805,11 +832,13 @@ macro_rules! impl_runtime_apis_plus_common {
use cumulus_primitives_core::ParaId;

use xcm::latest::prelude::{
GeneralIndex, Junction, Junctions, Location, Response, NetworkId, AssetId,
Assets as XcmAssets, Fungible, Asset, ParentThen, Parachain, Parent, WeightLimit
GeneralIndex, Junction, Junctions, Location, Response, NetworkId, AssetId, Here,
Assets as XcmAssets, Fungible, Asset, ParentThen, Parachain, Parent, WeightLimit,
AccountId32,
};
use xcm_config::SelfReserve;
use xcm_config::{SelfReserve, MaxAssetsIntoHolding};
use frame_benchmarking::BenchmarkError;
use xcm_executor::traits::ConvertLocation;

use frame_system_benchmarking::Pallet as SystemBench;
// Needed to run `set_code` and `apply_authorized_upgrade` frame_system benchmarks
Expand Down Expand Up @@ -938,16 +967,15 @@ macro_rules! impl_runtime_apis_plus_common {

impl pallet_xcm_benchmarks::Config for Runtime {
type XcmConfig = xcm_config::XcmExecutorConfig;
type AccountIdConverter = xcm_config::LocationToAccountId;
type AccountIdConverter = BenchAccountIdConverter<AccountId>;
type DeliveryHelper = ();
fn valid_destination() -> Result<Location, BenchmarkError> {
Ok(Location::parent())
}
fn worst_case_holding(_depositable_count: u32) -> XcmAssets {
// 100 fungibles
const HOLDING_FUNGIBLES: u32 = 100;
let fungibles_amount: u128 = 100;
let assets = (0..HOLDING_FUNGIBLES).map(|i| {
const HOLDING_FUNGIBLES: u32 = MaxAssetsIntoHolding::get();
let fungibles_amount: u128 = 1_000 * ExistentialDeposit::get();
let assets = (1..=HOLDING_FUNGIBLES).map(|i| {
let location: Location = GeneralIndex(i as u128).into();
Asset {
id: AssetId(location),
Expand Down Expand Up @@ -977,14 +1005,65 @@ macro_rules! impl_runtime_apis_plus_common {
);
XcmWeightTrader::set_asset_price(
location.clone(),
1u128.pow(18)
10u128.pow(18)
);
}
}
assets.into()
}
}

parameter_types! {
// Native token location
pub const TokenLocation: Location = Here.into_location();
pub TrustedTeleporter: Option<(Location, Asset)> = None;
pub CheckedAccount: Option<(AccountId, xcm_builder::MintLocation)> = None;
pub TrustedReserve: Option<(Location, Asset)> = Some(
(
Location::parent(),
Asset::from((
Location::parent(),
1000000000000 as u128
))
)
);
}

impl pallet_xcm_benchmarks::fungible::Config for Runtime {
type TransactAsset = Balances;

type CheckedAccount = CheckedAccount;
type TrustedTeleporter = TrustedTeleporter;
type TrustedReserve = TrustedReserve;

fn get_asset() -> Asset {
// We put more than ED here for being able to keep accounts alive when transferring
// and paying the delivery fees.
let location: Location = GeneralIndex(1).into();
let asset_id = 1u128;
let decimals = 18u8;
let asset = Asset {
id: AssetId(location.clone()),
fun: Fungible(100 * ExistentialDeposit::get()),
};
EvmForeignAssets::set_asset(
location.clone(),
asset_id,
);
XcmWeightTrader::set_asset_price(
location.clone(),
10u128.pow(decimals as u32)
);
EvmForeignAssets::create_asset_contract(
asset_id,
decimals,
"TKN",
"Token",
).unwrap();
asset
}
}

impl pallet_xcm_benchmarks::generic::Config for Runtime {
type RuntimeCall = RuntimeCall;
type TransactAsset = Balances;
Expand Down Expand Up @@ -1028,7 +1107,14 @@ macro_rules! impl_runtime_apis_plus_common {
}

fn worst_case_for_trader() -> Result<(Asset, WeightLimit), BenchmarkError> {
Err(BenchmarkError::Skip)
let location: Location = GeneralIndex(1).into();
Ok((
Asset {
id: AssetId(Location::parent()),
fun: Fungible(1_000_000_000_000_000 as u128)
},
WeightLimit::Limited(Weight::from_parts(5000, 5000)),
))
}

fn unlockable_asset()
Expand Down Expand Up @@ -1105,9 +1191,6 @@ macro_rules! impl_runtime_apis_plus_common {

add_benchmarks!(params, batches);

if batches.is_empty() {
return Err("Benchmark not found for this pallet.".into());
}
Ok(batches)
}
}
Expand Down
2 changes: 2 additions & 0 deletions runtime/moonbase/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1630,6 +1630,8 @@ mod benches {
[pallet_xcm_weight_trader, XcmWeightTrader]
[pallet_collective, TreasuryCouncilCollective]
[pallet_collective, OpenTechCommitteeCollective]
[pallet_xcm_benchmarks::fungible, pallet_xcm_benchmarks::fungible::Pallet<Runtime>]
[pallet_xcm_benchmarks::generic, pallet_xcm_benchmarks::generic::Pallet<Runtime>]
);
}

Expand Down
Loading
Loading