From 59aa955576e963942c60e3ae8f8316444b66cafb Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Wed, 1 Dec 2021 19:52:18 -0400 Subject: [PATCH] XCM Benchmarks for Generic Instructions (#3940) * initial stuff * quick fixes * move to individual tests * dont need these * Update benchmarking.rs * add to westend * make benchmarks execute * fix compile * add post_execute * ClaimAsset benchmark working * subscribe and unsubscribe benchmarks * benchmark for initiate reserve withdraw * cargo run --quiet --release --features=runtime-benchmarks -- benchmark --chain=westend-dev --steps=50 --repeat=20 --pallet=pallet_xcm_benchmarks::generic --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --header=./file_header.txt --template=./xcm/pallet-xcm-benchmarks/template.hbs --output=./runtime/westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs * fix spell check * cargo run --quiet --release --features=runtime-benchmarks -- benchmark --chain=westend-dev --steps=50 --repeat=20 --pallet=pallet_xcm_benchmarks::generic --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --header=./file_header.txt --template=./xcm/pallet-xcm-benchmarks/template.hbs --output=./runtime/westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs * update worst case for query_holding * cargo run --quiet --release --features=runtime-benchmarks -- benchmark --chain=westend-dev --steps=50 --repeat=20 --pallet=pallet_xcm_benchmarks::generic --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --header=./file_header.txt --template=./xcm/pallet-xcm-benchmarks/template.hbs --output=./runtime/westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs * move verification logic below * introduce worst case holding to initiate reserve withdraw * cargo run --quiet --release --features=runtime-benchmarks -- benchmark --chain=westend-dev --steps=50 --repeat=20 --pallet=pallet_xcm_benchmarks::generic --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --header=./file_header.txt --template=./xcm/pallet-xcm-benchmarks/template.hbs --output=./runtime/westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs * feedback * cargo run --quiet --release --features=runtime-benchmarks -- benchmark --chain=westend-dev --steps=50 --repeat=20 --pallet=pallet_xcm_benchmarks::generic --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --header=./file_header.txt --template=./xcm/pallet-xcm-benchmarks/template.hbs --output=./runtime/westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs * Revert "cargo run --quiet --release --features=runtime-benchmarks -- benchmark --chain=westend-dev --steps=50 --repeat=20 --pallet=pallet_xcm_benchmarks::generic --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --header=./file_header.txt --template=./xcm/pallet-xcm-benchmarks/template.hbs --output=./runtime/westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs" This reverts commit 277903944be620dc57d83b9bcf3b462d2fb73ab5. * fix benchmark template * cargo run --quiet --release --features=runtime-benchmarks -- benchmark --chain=westend-dev --steps=50 --repeat=20 --pallet=pallet_xcm_benchmarks::generic --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --header=./file_header.txt --template=./xcm/pallet-xcm-benchmarks/template.hbs --output=./runtime/westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs * use response::version * cargo run --quiet --release --features=runtime-benchmarks -- benchmark --chain=westend-dev --steps=50 --repeat=20 --pallet=pallet_xcm_benchmarks::generic --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --header=./file_header.txt --template=./xcm/pallet-xcm-benchmarks/template.hbs --output=./runtime/westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs * refactor worst case holding * cargo run --quiet --release --features=runtime-benchmarks -- benchmark --chain=westend-dev --steps=50 --repeat=20 --pallet=pallet_xcm_benchmarks::generic --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --header=./file_header.txt --template=./xcm/pallet-xcm-benchmarks/template.hbs --output=./runtime/westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs * fmt * one more todo needs to be labeled * change option to result with benchmark error * fmt and fix import Co-authored-by: Parity Bot --- bridges/bin/rialto/runtime/src/lib.rs | 1 - runtime/polkadot/src/lib.rs | 1 - runtime/rococo/src/lib.rs | 1 - runtime/westend/src/lib.rs | 39 ++- runtime/westend/src/weights/xcm/mod.rs | 33 +- .../xcm/pallet_xcm_benchmarks_generic.rs | 185 ++++++---- .../src/fungible/benchmarking.rs | 26 +- .../src/fungible/mock.rs | 6 +- .../src/generic/benchmarking.rs | 318 ++++++++++++++++++ xcm/pallet-xcm-benchmarks/src/generic/mock.rs | 171 ++++++++++ xcm/pallet-xcm-benchmarks/src/generic/mod.rs | 39 +++ xcm/pallet-xcm-benchmarks/src/lib.rs | 20 +- xcm/pallet-xcm-benchmarks/template.hbs | 30 +- xcm/src/v2/traits.rs | 1 - 14 files changed, 747 insertions(+), 124 deletions(-) create mode 100644 xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs create mode 100644 xcm/pallet-xcm-benchmarks/src/generic/mock.rs create mode 100644 xcm/pallet-xcm-benchmarks/src/generic/mod.rs diff --git a/bridges/bin/rialto/runtime/src/lib.rs b/bridges/bin/rialto/runtime/src/lib.rs index 3285a90e1e13..601a513f0f9c 100644 --- a/bridges/bin/rialto/runtime/src/lib.rs +++ b/bridges/bin/rialto/runtime/src/lib.rs @@ -1096,7 +1096,6 @@ impl_runtime_apis! { ); add_benchmark!(params, batches, pallet_bridge_grandpa, BridgeMillauGrandpa); - if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } Ok(batches) } } diff --git a/runtime/polkadot/src/lib.rs b/runtime/polkadot/src/lib.rs index 88a79f045eb1..d5334503e79c 100644 --- a/runtime/polkadot/src/lib.rs +++ b/runtime/polkadot/src/lib.rs @@ -2034,7 +2034,6 @@ sp_api::impl_runtime_apis! { add_benchmark!(params, batches, pallet_utility, Utility); add_benchmark!(params, batches, pallet_vesting, Vesting); - if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } Ok(batches) } } diff --git a/runtime/rococo/src/lib.rs b/runtime/rococo/src/lib.rs index acb0ee20dc49..a5bfc793b0bc 100644 --- a/runtime/rococo/src/lib.rs +++ b/runtime/rococo/src/lib.rs @@ -1676,7 +1676,6 @@ sp_api::impl_runtime_apis! { add_benchmark!(params, batches, runtime_parachains::paras_inherent, ParaInherent); add_benchmark!(params, batches, runtime_parachains::paras, Paras); - if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } Ok(batches) } } diff --git a/runtime/westend/src/lib.rs b/runtime/westend/src/lib.rs index a5cae34ca5a3..f564712feb69 100644 --- a/runtime/westend/src/lib.rs +++ b/runtime/westend/src/lib.rs @@ -1497,6 +1497,7 @@ sp_api::impl_runtime_apis! { use frame_system_benchmarking::Pallet as SystemBench; type XcmBalances = pallet_xcm_benchmarks::fungible::Pallet::; + type XcmGeneric = pallet_xcm_benchmarks::generic::Pallet::; let mut list = Vec::::new(); @@ -1533,6 +1534,7 @@ sp_api::impl_runtime_apis! { // XCM Benchmarks // NOTE: Make sure you point to the individual modules below. list_benchmark!(list, extra, pallet_xcm_benchmarks::fungible, XcmBalances); + list_benchmark!(list, extra, pallet_xcm_benchmarks::generic, XcmGeneric); let storage_info = AllPalletsWithSystem::storage_info(); @@ -1545,7 +1547,7 @@ sp_api::impl_runtime_apis! { Vec, sp_runtime::RuntimeString, > { - use frame_benchmarking::{Benchmarking, BenchmarkBatch, add_benchmark, TrackedStorageKey}; + use frame_benchmarking::{Benchmarking, BenchmarkBatch, add_benchmark, TrackedStorageKey, BenchmarkError}; // Trying to add benchmarks directly to some pallets caused cyclic dependency issues. // To get around that, we separated the benchmarks into its own crate. use pallet_session_benchmarking::Pallet as SessionBench; @@ -1561,9 +1563,16 @@ sp_api::impl_runtime_apis! { impl pallet_xcm_benchmarks::Config for Runtime { type XcmConfig = XcmConfig; type AccountIdConverter = LocationConverter; - fn valid_destination() -> Result { + fn valid_destination() -> Result { Ok(Westmint::get()) } + fn worst_case_holding() -> MultiAssets { + // Westend only knows about WND. + vec![MultiAsset{ + id: Concrete(WndLocation::get()), + fun: Fungible(1_000_000 * UNITS), + }].into() + } } parameter_types! { @@ -1587,7 +1596,31 @@ sp_api::impl_runtime_apis! { } } + impl pallet_xcm_benchmarks::generic::Config for Runtime { + type Call = Call; + + fn worst_case_response() -> (u64, Response) { + (0u64, Response::Version(Default::default())) + } + + fn transact_origin() -> Result { + Ok(Westmint::get()) + } + + fn subscribe_origin() -> Result { + Ok(Westmint::get()) + } + + fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + let origin = Westmint::get(); + let assets: MultiAssets = (Concrete(WndLocation::get()), 1_000 * UNITS).into(); + let ticket = MultiLocation { parents: 0, interior: Here }; + Ok((origin, ticket, assets)) + } + } + type XcmBalances = pallet_xcm_benchmarks::fungible::Pallet::; + type XcmGeneric = pallet_xcm_benchmarks::generic::Pallet::; let whitelist: Vec = vec![ // Block Number @@ -1646,8 +1679,8 @@ sp_api::impl_runtime_apis! { // XCM Benchmarks // NOTE: Make sure you point to the individual modules below. add_benchmark!(params, batches, pallet_xcm_benchmarks::fungible, XcmBalances); + add_benchmark!(params, batches, pallet_xcm_benchmarks::generic, XcmGeneric); - if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) } Ok(batches) } } diff --git a/runtime/westend/src/weights/xcm/mod.rs b/runtime/westend/src/weights/xcm/mod.rs index 70c5731a7853..78fb9b739ede 100644 --- a/runtime/westend/src/weights/xcm/mod.rs +++ b/runtime/westend/src/weights/xcm/mod.rs @@ -69,14 +69,15 @@ impl XcmWeightInfo for WestendXcmWeight { fn withdraw_asset(assets: &MultiAssets) -> Weight { assets.weigh_multi_assets(XcmBalancesWeight::::withdraw_asset()) } - fn reserve_asset_deposited(assets: &MultiAssets) -> Weight { - assets.weigh_multi_assets(XcmGeneric::::reserve_asset_deposited()) + fn reserve_asset_deposited(_assets: &MultiAssets) -> Weight { + // Westend does not support reserve asset deposits. + Weight::MAX } fn receive_teleported_asset(assets: &MultiAssets) -> Weight { assets.weigh_multi_assets(XcmBalancesWeight::::receive_teleported_asset()) } - fn query_response(_query_id: &u64, _response: &Response, max_weight: &u64) -> Weight { - *max_weight + fn query_response(_query_id: &u64, _response: &Response, _max_weight: &u64) -> Weight { + XcmGeneric::::query_response() } fn transfer_asset(assets: &MultiAssets, _dest: &MultiLocation) -> Weight { assets.weigh_multi_assets(XcmBalancesWeight::::transfer_asset()) @@ -100,19 +101,22 @@ impl XcmWeightInfo for WestendXcmWeight { _max_message_size: &u32, _max_capacity: &u32, ) -> Weight { - XcmGeneric::::hrmp_new_channel_open_request() + // XCM Executor does not currently support HRMP channel operations + Weight::MAX } fn hrmp_channel_accepted(_recipient: &u32) -> Weight { - XcmGeneric::::hrmp_channel_accepted() + // XCM Executor does not currently support HRMP channel operations + Weight::MAX } fn hrmp_channel_closing(_initiator: &u32, _sender: &u32, _recipient: &u32) -> Weight { - XcmGeneric::::hrmp_channel_closing() + // XCM Executor does not currently support HRMP channel operations + Weight::MAX } fn clear_origin() -> Weight { XcmGeneric::::clear_origin() } - fn descend_origin(who: &InteriorMultiLocation) -> Weight { - XcmGeneric::::descend_origin(who) + fn descend_origin(_who: &InteriorMultiLocation) -> Weight { + XcmGeneric::::descend_origin() } fn report_error( _query_id: &QueryId, @@ -121,9 +125,6 @@ impl XcmWeightInfo for WestendXcmWeight { ) -> Weight { XcmGeneric::::report_error() } - fn relayed_from(_who: &Junctions, _message: &Box>) -> Weight { - XcmGeneric::::relayed_from() - } fn deposit_asset( assets: &MultiAssetFilter, @@ -180,11 +181,11 @@ impl XcmWeightInfo for WestendXcmWeight { fn clear_error() -> Weight { XcmGeneric::::clear_error() } - fn claim_asset(assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { - XcmGeneric::::claim_asset(assets) + fn claim_asset(_assets: &MultiAssets, _ticket: &MultiLocation) -> Weight { + XcmGeneric::::claim_asset() } - fn trap(code: &u64) -> Weight { - XcmGeneric::::trap(code) + fn trap(_code: &u64) -> Weight { + XcmGeneric::::trap() } fn subscribe_version(_query_id: &QueryId, _max_response_weight: &u64) -> Weight { XcmGeneric::::subscribe_version() diff --git a/runtime/westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs b/runtime/westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs index 5c8626f0b22a..d87cb6d37861 100644 --- a/runtime/westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs +++ b/runtime/westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs @@ -1,73 +1,132 @@ -// this whole file is temp, and will be replaced in the future TODO +// Copyright 2017-2021 Parity Technologies (UK) Ltd. +// This file is part of Polkadot. -use frame_support::dispatch::Weight; +// 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. -pub struct WeightInfo(sp_std::marker::PhantomData); -impl WeightInfo { - pub fn query_holding() -> Weight { - 1_000_000_000 - } - pub fn buy_execution() -> Weight { - 1_000_000_000 - } - pub fn transact() -> Weight { - 1_000_000_000 - } - pub fn reserve_asset_deposited() -> Weight { - 1_000_000_000 - } - pub fn hrmp_new_channel_open_request() -> Weight { - 1_000_000_000 - } - pub fn hrmp_channel_accepted() -> Weight { - 1_000_000_000 - } - pub fn hrmp_channel_closing() -> Weight { - 1_000_000_000 - } - pub fn relayed_from() -> Weight { - 1_000_000_000 - } - pub fn refund_surplus() -> Weight { - 1_000_000_000 - } - pub fn set_error_handler() -> Weight { - 1_000_000_000 - } - pub fn set_appendix() -> Weight { - 1_000_000_000 - } - pub fn clear_error() -> Weight { - 1_000_000_000 - } - pub fn claim_asset(_assets: &crate::MultiAssets) -> Weight { - 1_000_000_000 - } - pub fn trap(_code: &u64) -> Weight { - 1_000_000_000 - } +// 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. - pub fn subscribe_version() -> Weight { - 1_000_000_000 - } +// You should have received a copy of the GNU General Public License +// along with Polkadot. If not, see . - pub fn unsubscribe_version() -> Weight { - 1_000_000_000 - } +//! Autogenerated weights for `pallet_xcm_benchmarks::generic` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2021-12-01, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("westend-dev"), DB CACHE: 128 - pub fn clear_origin() -> Weight { - 1_000_000_000 - } +// Executed Command: +// target/release/polkadot +// benchmark +// --chain=westend-dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_xcm_benchmarks::generic +// --extrinsic=* +// --execution=wasm +// --wasm-execution=compiled +// --heap-pages=4096 +// --header=./file_header.txt +// --template=./xcm/pallet-xcm-benchmarks/template.hbs +// --output=./runtime/westend/src/weights/xcm/pallet_xcm_benchmarks_generic.rs - pub fn descend_origin(_who: &crate::InteriorMultiLocation) -> Weight { - 1_000_000_000 - } +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] - pub fn initiate_reserve_withdraw() -> Weight { - 1_000_000_000 - } +use frame_support::{traits::Get, weights::Weight}; +use sp_std::marker::PhantomData; - pub fn report_error() -> Weight { - 1_000_000_000 +/// Weights for `pallet_xcm_benchmarks::generic`. +pub struct WeightInfo(PhantomData); +impl WeightInfo { + // Storage: XcmPallet SupportedVersion (r:1 w:0) + // Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1) + // Storage: XcmPallet SafeXcmVersion (r:1 w:0) + // Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + // Storage: Dmp DownwardMessageQueues (r:1 w:1) + pub(crate) fn query_holding() -> Weight { + (39_278_000 as Weight) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + pub(crate) fn buy_execution() -> Weight { + (5_922_000 as Weight) + } + // Storage: XcmPallet Queries (r:1 w:0) + pub(crate) fn query_response() -> Weight { + (20_625_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + } + pub(crate) fn transact() -> Weight { + (22_198_000 as Weight) + } + pub(crate) fn refund_surplus() -> Weight { + (6_122_000 as Weight) + } + pub(crate) fn set_error_handler() -> Weight { + (5_758_000 as Weight) + } + pub(crate) fn set_appendix() -> Weight { + (5_764_000 as Weight) + } + pub(crate) fn clear_error() -> Weight { + (5_679_000 as Weight) + } + pub(crate) fn descend_origin() -> Weight { + (7_206_000 as Weight) + } + pub(crate) fn clear_origin() -> Weight { + (5_738_000 as Weight) + } + // Storage: XcmPallet SupportedVersion (r:1 w:0) + // Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1) + // Storage: XcmPallet SafeXcmVersion (r:1 w:0) + // Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + // Storage: Dmp DownwardMessageQueues (r:1 w:1) + pub(crate) fn report_error() -> Weight { + (31_512_000 as Weight) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) + } + // Storage: XcmPallet AssetTraps (r:1 w:1) + pub(crate) fn claim_asset() -> Weight { + (13_594_000 as Weight) + .saturating_add(T::DbWeight::get().reads(1 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + pub(crate) fn trap() -> Weight { + (5_745_000 as Weight) + } + // Storage: XcmPallet VersionNotifyTargets (r:1 w:1) + // Storage: XcmPallet SupportedVersion (r:1 w:0) + // Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1) + // Storage: XcmPallet SafeXcmVersion (r:1 w:0) + // Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + // Storage: Dmp DownwardMessageQueues (r:1 w:1) + pub(crate) fn subscribe_version() -> Weight { + (38_138_000 as Weight) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 as Weight)) + } + // Storage: XcmPallet VersionNotifyTargets (r:0 w:1) + pub(crate) fn unsubscribe_version() -> Weight { + (9_127_000 as Weight) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) + } + // Storage: XcmPallet SupportedVersion (r:1 w:0) + // Storage: XcmPallet VersionDiscoveryQueue (r:1 w:1) + // Storage: XcmPallet SafeXcmVersion (r:1 w:0) + // Storage: Dmp DownwardMessageQueueHeads (r:1 w:1) + // Storage: Dmp DownwardMessageQueues (r:1 w:1) + pub(crate) fn initiate_reserve_withdraw() -> Weight { + (41_443_000 as Weight) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) } } diff --git a/xcm/pallet-xcm-benchmarks/src/fungible/benchmarking.rs b/xcm/pallet-xcm-benchmarks/src/fungible/benchmarking.rs index 9e2083704254..8a987cf84d4e 100644 --- a/xcm/pallet-xcm-benchmarks/src/fungible/benchmarking.rs +++ b/xcm/pallet-xcm-benchmarks/src/fungible/benchmarking.rs @@ -15,7 +15,7 @@ // along with Polkadot. If not, see . use super::*; -use crate::{account_and_location, new_executor, worst_case_holding, AssetTransactorOf, XcmCallOf}; +use crate::{account_and_location, new_executor, AssetTransactorOf, XcmCallOf}; use frame_benchmarking::{benchmarks_instance_pallet, BenchmarkError, BenchmarkResult}; use frame_support::{ pallet_prelude::Get, @@ -41,7 +41,7 @@ benchmarks_instance_pallet! { withdraw_asset { let (sender_account, sender_location) = account_and_location::(1); - let worst_case_holding = worst_case_holding(); + let worst_case_holding = T::worst_case_holding(); let asset = T::get_multi_asset(); >::deposit_asset(&asset, &sender_location).unwrap(); @@ -49,7 +49,7 @@ benchmarks_instance_pallet! { assert!(!T::TransactAsset::balance(&sender_account).is_zero()); let mut executor = new_executor::(sender_location); - executor.holding = worst_case_holding; + executor.holding = worst_case_holding.into(); let instruction = Instruction::>::WithdrawAsset(vec![asset.clone()].into()); let xcm = Xcm(vec![instruction]); }: { @@ -104,7 +104,7 @@ benchmarks_instance_pallet! { } verify { assert!(T::TransactAsset::balance(&sender_account).is_zero()); assert!(!T::TransactAsset::balance(&dest_account).is_zero()); - // TODO: Check sender queue is not empty. + // TODO: Check sender queue is not empty. #4426 } receive_teleported_asset { @@ -140,10 +140,10 @@ benchmarks_instance_pallet! { deposit_asset { let asset = T::get_multi_asset(); - let mut holding = worst_case_holding(); + let mut holding = T::worst_case_holding(); // Add our asset to the holding. - holding.subsume(asset.clone()); + holding.push(asset.clone()); // our dest must have no balance initially. let dest_location = T::valid_destination()?; @@ -151,7 +151,7 @@ benchmarks_instance_pallet! { assert!(T::TransactAsset::balance(&dest_account).is_zero()); let mut executor = new_executor::(Default::default()); - executor.holding = holding; + executor.holding = holding.into(); let instruction = Instruction::>::DepositAsset { assets: asset.into(), max_assets: 1, @@ -167,10 +167,10 @@ benchmarks_instance_pallet! { deposit_reserve_asset { let asset = T::get_multi_asset(); - let mut holding = worst_case_holding(); + let mut holding = T::worst_case_holding(); // Add our asset to the holding. - holding.subsume(asset.clone()); + holding.push(asset.clone()); // our dest must have no balance initially. let dest_location = T::valid_destination()?; @@ -178,7 +178,7 @@ benchmarks_instance_pallet! { assert!(T::TransactAsset::balance(&dest_account).is_zero()); let mut executor = new_executor::(Default::default()); - executor.holding = holding; + executor.holding = holding.into(); let instruction = Instruction::>::DepositReserveAsset { assets: asset.into(), max_assets: 1, @@ -195,16 +195,16 @@ benchmarks_instance_pallet! { initiate_teleport { let asset = T::get_multi_asset(); - let mut holding = worst_case_holding(); + let mut holding = T::worst_case_holding(); // Add our asset to the holding. - holding.subsume(asset.clone()); + holding.push(asset.clone()); // Checked account starts at zero assert!(T::CheckedAccount::get().map_or(true, |c| T::TransactAsset::balance(&c).is_zero())); let mut executor = new_executor::(Default::default()); - executor.holding = holding; + executor.holding = holding.into(); let instruction = Instruction::>::InitiateTeleport { assets: asset.into(), dest: T::valid_destination()?, diff --git a/xcm/pallet-xcm-benchmarks/src/fungible/mock.rs b/xcm/pallet-xcm-benchmarks/src/fungible/mock.rs index fb5f3059561b..5153c7f54a08 100644 --- a/xcm/pallet-xcm-benchmarks/src/fungible/mock.rs +++ b/xcm/pallet-xcm-benchmarks/src/fungible/mock.rs @@ -17,6 +17,7 @@ //! A mock runtime for XCM benchmarking. use crate::{fungible as xcm_balances_benchmark, mock::*}; +use frame_benchmarking::BenchmarkError; use frame_support::{parameter_types, traits::Everything}; use sp_core::H256; use sp_runtime::{ @@ -145,12 +146,15 @@ impl xcm_executor::Config for XcmConfig { impl crate::Config for Test { type XcmConfig = XcmConfig; type AccountIdConverter = AccountIdConverter; - fn valid_destination() -> Result { + fn valid_destination() -> Result { let valid_destination: MultiLocation = X1(AccountId32 { network: NetworkId::Any, id: [0u8; 32] }).into(); Ok(valid_destination) } + fn worst_case_holding() -> MultiAssets { + crate::mock_worst_case_holding() + } } pub type TrustedTeleporters = (xcm_builder::Case,); diff --git a/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs b/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs new file mode 100644 index 000000000000..62d0df265c42 --- /dev/null +++ b/xcm/pallet-xcm-benchmarks/src/generic/benchmarking.rs @@ -0,0 +1,318 @@ +// Copyright 2021 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 . + +use super::*; +use crate::{new_executor, XcmCallOf}; +use codec::Encode; +use frame_benchmarking::{benchmarks, BenchmarkError}; +use frame_support::dispatch::GetDispatchInfo; +use sp_std::vec; +use xcm::{ + latest::{prelude::*, MultiAssets}, + DoubleEncoded, +}; + +benchmarks! { + query_holding { + let holding = T::worst_case_holding(); + + let mut executor = new_executor::(Default::default()); + executor.holding = holding.clone().into(); + + let instruction = Instruction::>::QueryHolding { + query_id: Default::default(), + dest: T::valid_destination()?, + // Worst case is looking through all holdings for every asset explicitly. + assets: Definite(holding), + max_response_weight: u64::MAX, + }; + + let xcm = Xcm(vec![instruction]); + + } : { + executor.execute(xcm)?; + } verify { + // The completion of execution above is enough to validate this is completed. + } + + // This benchmark does not use any additional orders or instructions. This should be managed + // by the `deep` and `shallow` implementation. + buy_execution { + let holding = T::worst_case_holding().into(); + + let mut executor = new_executor::(Default::default()); + executor.holding = holding; + + let fee_asset = Concrete(Here.into()); + + let instruction = Instruction::>::BuyExecution { + fees: (fee_asset, 100_000_000).into(), // should be something inside of holding + weight_limit: WeightLimit::Unlimited, + }; + + let xcm = Xcm(vec![instruction]); + } : { + executor.execute(xcm)?; + } verify { + + } + + // Worst case scenario for this benchmark is a large number of assets to + // filter through the reserve. + reserve_asset_deposited { + const MAX_ASSETS: u32 = 100; // TODO when executor has a built in limit, use it here. #4426 + let mut executor = new_executor::(Default::default()); + let assets = (0..MAX_ASSETS).map(|i| MultiAsset { + id: Abstract(i.encode()), + fun: Fungible(i as u128), + + }).collect::>(); + let multiassets: MultiAssets = assets.into(); + + let instruction = Instruction::ReserveAssetDeposited(multiassets.clone()); + let xcm = Xcm(vec![instruction]); + }: { + executor.execute(xcm).map_err(|_| BenchmarkError::Skip)?; + } verify { + assert_eq!(executor.holding, multiassets.into()); + } + + query_response { + let mut executor = new_executor::(Default::default()); + let (query_id, response) = T::worst_case_response(); + let max_weight = u64::MAX; + let instruction = Instruction::QueryResponse { query_id, response, max_weight }; + let xcm = Xcm(vec![instruction]); + }: { + executor.execute(xcm)?; + } verify { + // The assert above is enough to show this XCM succeeded + } + + // We don't care about the call itself, since that is accounted for in the weight parameter + // and included in the final weight calculation. So this is just the overhead of submitting + // a noop call. + transact { + let origin = T::transact_origin()?; + let mut executor = new_executor::(origin); + let noop_call: ::Call = frame_system::Call::remark_with_event { + remark: Default::default() + }.into(); + let double_encoded_noop_call: DoubleEncoded<_> = noop_call.encode().into(); + + let instruction = Instruction::Transact { + origin_type: OriginKind::SovereignAccount, + require_weight_at_most: noop_call.get_dispatch_info().weight, + call: double_encoded_noop_call, + }; + let xcm = Xcm(vec![instruction]); + + let num_events = frame_system::Pallet::::events().len(); + }: { + executor.execute(xcm)?; + } verify { + // TODO make better assertion? #4426 + let num_events2 = frame_system::Pallet::::events().len(); + assert_eq!(num_events + 1, num_events2); + } + + refund_surplus { + let holding = T::worst_case_holding().into(); + let mut executor = new_executor::(Default::default()); + executor.holding = holding; + executor.total_surplus = 1337; + executor.total_refunded = 0; + + let instruction = Instruction::>::RefundSurplus; + let xcm = Xcm(vec![instruction]); + } : { + let result = executor.execute(xcm)?; + } verify { + assert_eq!(executor.total_surplus, 1337); + assert_eq!(executor.total_refunded, 1337); + } + + set_error_handler { + let mut executor = new_executor::(Default::default()); + let instruction = Instruction::>::SetErrorHandler(Xcm(vec![])); + let xcm = Xcm(vec![instruction]); + } : { + executor.execute(xcm)?; + } verify { + assert_eq!(executor.error_handler, Xcm(vec![])); + } + + set_appendix { + let mut executor = new_executor::(Default::default()); + let appendix = Xcm(vec![]); + let instruction = Instruction::>::SetAppendix(appendix); + let xcm = Xcm(vec![instruction]); + } : { + executor.execute(xcm)?; + } verify { + assert_eq!(executor.appendix, Xcm(vec![])); + } + + clear_error { + let mut executor = new_executor::(Default::default()); + executor.error = Some((5u32, XcmError::Overflow)); + let instruction = Instruction::>::ClearError; + let xcm = Xcm(vec![instruction]); + } : { + executor.execute(xcm)?; + } verify { + assert!(executor.error.is_none()) + } + + descend_origin { + let mut executor = new_executor::(Default::default()); + let who = X2(OnlyChild, OnlyChild); + let instruction = Instruction::DescendOrigin(who.clone()); + let xcm = Xcm(vec![instruction]); + } : { + executor.execute(xcm)?; + } verify { + assert_eq!( + executor.origin, + Some(MultiLocation { + parents: 0, + interior: who, + }), + ); + } + + clear_origin { + let mut executor = new_executor::(Default::default()); + let instruction = Instruction::ClearOrigin; + let xcm = Xcm(vec![instruction]); + } : { + executor.execute(xcm)?; + } verify { + assert_eq!(executor.origin, None); + } + + report_error { + let mut executor = new_executor::(Default::default()); + executor.error = Some((0u32, XcmError::Unimplemented)); + let query_id = Default::default(); + let dest = T::valid_destination().map_err(|_| BenchmarkError::Skip)?; + let max_response_weight = Default::default(); + + let instruction = Instruction::ReportError { query_id, dest, max_response_weight }; + let xcm = Xcm(vec![instruction]); + }: { + executor.execute(xcm)?; + } verify { + // the execution succeeding is all we need to verify this xcm was successful + } + + claim_asset { + use xcm_executor::traits::DropAssets; + + let (origin, ticket, assets) = T::claimable_asset()?; + + // We place some items into the asset trap to claim. + ::AssetTrap::drop_assets( + &origin, + assets.clone().into(), + ); + + // Assets should be in the trap now. + + let mut executor = new_executor::(origin); + let instruction = Instruction::ClaimAsset { assets: assets.clone(), ticket }; + let xcm = Xcm(vec![instruction]); + } :{ + executor.execute(xcm)?; + } verify { + assert!(executor.holding.ensure_contains(&assets).is_ok()); + } + + trap { + let mut executor = new_executor::(Default::default()); + let instruction = Instruction::Trap(10); + let xcm = Xcm(vec![instruction]); + // In order to access result in the verification below, it needs to be defined here. + let mut _result = Ok(()); + } : { + _result = executor.execute(xcm); + } verify { + match _result { + Err(error) if error.xcm_error == XcmError::Trap(10) => { + // This is the success condition + }, + _ => Err("xcm trap did not return the expected error")? + }; + } + + subscribe_version { + use xcm_executor::traits::VersionChangeNotifier; + let origin = T::subscribe_origin()?; + let query_id = Default::default(); + let max_response_weight = Default::default(); + let mut executor = new_executor::(origin.clone()); + let instruction = Instruction::SubscribeVersion { query_id, max_response_weight }; + let xcm = Xcm(vec![instruction]); + } : { + executor.execute(xcm)?; + } verify { + assert!(::SubscriptionService::is_subscribed(&origin)); + } + + unsubscribe_version { + use xcm_executor::traits::VersionChangeNotifier; + // First we need to subscribe to notifications. + let origin = T::transact_origin()?; + let query_id = Default::default(); + let max_response_weight = Default::default(); + ::SubscriptionService::start( + &origin, + query_id, + max_response_weight + ).map_err(|_| "Could not start subscription")?; + assert!(::SubscriptionService::is_subscribed(&origin)); + + let mut executor = new_executor::(origin.clone()); + let instruction = Instruction::UnsubscribeVersion; + let xcm = Xcm(vec![instruction]); + } : { + executor.execute(xcm)?; + } verify { + assert!(!::SubscriptionService::is_subscribed(&origin)); + } + + initiate_reserve_withdraw { + let holding = T::worst_case_holding(); + let assets_filter = MultiAssetFilter::Definite(holding.clone()); + let reserve = T::valid_destination().map_err(|_| BenchmarkError::Skip)?; + let mut executor = new_executor::(Default::default()); + executor.holding = holding.into(); + let instruction = Instruction::InitiateReserveWithdraw { assets: assets_filter, reserve, xcm: Xcm(vec![]) }; + let xcm = Xcm(vec![instruction]); + }:{ + executor.execute(xcm)?; + } verify { + // The execute completing successfully is as good as we can check. + // TODO: Potentially add new trait to XcmSender to detect a queued outgoing message. #4426 + } + + impl_benchmark_test_suite!( + Pallet, + crate::generic::mock::new_test_ext(), + crate::generic::mock::Test + ); + +} diff --git a/xcm/pallet-xcm-benchmarks/src/generic/mock.rs b/xcm/pallet-xcm-benchmarks/src/generic/mock.rs new file mode 100644 index 000000000000..cad5b916e13f --- /dev/null +++ b/xcm/pallet-xcm-benchmarks/src/generic/mock.rs @@ -0,0 +1,171 @@ +// Copyright 2021 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 . + +//! A mock runtime for XCM benchmarking. + +use crate::{generic, mock::*, *}; +use frame_support::{ + parameter_types, + traits::{Everything, OriginTrait}, +}; +use sp_core::H256; +use sp_runtime::{ + testing::Header, + traits::{BlakeTwo256, IdentityLookup}, + BuildStorage, +}; +use xcm_builder::{ + test_utils::{Assets, TestAssetTrap, TestSubscriptionService}, + AllowUnpaidExecutionFrom, +}; +use xcm_executor::traits::ConvertOrigin; + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; + +frame_support::construct_runtime!( + pub enum Test where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system::{Pallet, Call, Config, Storage, Event}, + XcmGenericBenchmarks: generic::{Pallet}, + } +); + +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub BlockWeights: frame_system::limits::BlockWeights = + frame_system::limits::BlockWeights::simple_max(1024); +} + +impl frame_system::Config for Test { + type BaseCallFilter = Everything; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type Origin = Origin; + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Call = Call; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type Event = Event; + type BlockHashCount = BlockHashCount; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); +} + +/// The benchmarks in this pallet should never need an asset transactor to begin with. +pub struct NoAssetTransactor; +impl xcm_executor::traits::TransactAsset for NoAssetTransactor { + fn deposit_asset(_: &MultiAsset, _: &MultiLocation) -> Result<(), XcmError> { + unreachable!(); + } + + fn withdraw_asset(_: &MultiAsset, _: &MultiLocation) -> Result { + unreachable!(); + } +} + +parameter_types! { + pub const MaxInstructions: u32 = 100; +} + +pub struct XcmConfig; +impl xcm_executor::Config for XcmConfig { + type Call = Call; + type XcmSender = DevNull; + type AssetTransactor = NoAssetTransactor; + type OriginConverter = AlwaysSignedByDefault; + type IsReserve = AllAssetLocationsPass; + type IsTeleporter = (); + type LocationInverter = xcm_builder::LocationInverter; + type Barrier = AllowUnpaidExecutionFrom; + type Weigher = xcm_builder::FixedWeightBounds; + type Trader = xcm_builder::FixedRateOfFungible; + type ResponseHandler = DevNull; + type AssetTrap = TestAssetTrap; + type AssetClaims = TestAssetTrap; + type SubscriptionService = TestSubscriptionService; +} + +impl crate::Config for Test { + type XcmConfig = XcmConfig; + type AccountIdConverter = AccountIdConverter; + fn valid_destination() -> Result { + let valid_destination: MultiLocation = + Junction::AccountId32 { network: NetworkId::Any, id: [0u8; 32] }.into(); + + Ok(valid_destination) + } + fn worst_case_holding() -> MultiAssets { + crate::mock_worst_case_holding() + } +} + +impl generic::Config for Test { + type Call = Call; + + fn worst_case_response() -> (u64, Response) { + let assets: MultiAssets = (Concrete(Here.into()), 100).into(); + (0, Response::Assets(assets)) + } + + fn transact_origin() -> Result { + Ok(Default::default()) + } + + fn subscribe_origin() -> Result { + Ok(Default::default()) + } + + fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError> { + let assets: MultiAssets = (Concrete(Here.into()), 100).into(); + let ticket = MultiLocation { parents: 0, interior: X1(GeneralIndex(0)) }; + Ok((Default::default(), ticket, assets)) + } +} + +pub fn new_test_ext() -> sp_io::TestExternalities { + let t = GenesisConfig { ..Default::default() }.build_storage().unwrap(); + sp_tracing::try_init_simple(); + t.into() +} + +pub struct AlwaysSignedByDefault(core::marker::PhantomData); +impl ConvertOrigin for AlwaysSignedByDefault +where + Origin: OriginTrait, + ::AccountId: Default, +{ + fn convert_origin( + _origin: impl Into, + _kind: OriginKind, + ) -> Result { + Ok(Origin::signed(Default::default())) + } +} diff --git a/xcm/pallet-xcm-benchmarks/src/generic/mod.rs b/xcm/pallet-xcm-benchmarks/src/generic/mod.rs new file mode 100644 index 000000000000..270eaf896e7e --- /dev/null +++ b/xcm/pallet-xcm-benchmarks/src/generic/mod.rs @@ -0,0 +1,39 @@ +pub use pallet::*; + +pub mod benchmarking; +#[cfg(test)] +mod mock; + +#[frame_support::pallet] +pub mod pallet { + use frame_benchmarking::BenchmarkError; + use frame_support::{dispatch::Dispatchable, pallet_prelude::Encode, weights::GetDispatchInfo}; + use xcm::latest::{MultiAssets, MultiLocation, Response}; + + #[pallet::config] + pub trait Config: frame_system::Config + crate::Config { + type Call: Dispatchable + + GetDispatchInfo + + From> + + Encode; + + /// The response which causes the most runtime weight. + fn worst_case_response() -> (u64, Response); + + /// The `MultiLocation` used for successful transaction XCMs. + /// + /// If set to `None`, benchmarks which rely on a `transact_origin` will be skipped. + fn transact_origin() -> Result; + + /// A valid `MultiLocation` we can successfully subscribe to. + /// + /// If set to `None`, benchmarks which rely on a `subscribe_origin` will be skipped. + fn subscribe_origin() -> Result; + + /// Return an origin, ticket, and assets that can be trapped and claimed. + fn claimable_asset() -> Result<(MultiLocation, MultiLocation, MultiAssets), BenchmarkError>; + } + + #[pallet::pallet] + pub struct Pallet(_); +} diff --git a/xcm/pallet-xcm-benchmarks/src/lib.rs b/xcm/pallet-xcm-benchmarks/src/lib.rs index cfbb3a478f67..8492dac5a622 100644 --- a/xcm/pallet-xcm-benchmarks/src/lib.rs +++ b/xcm/pallet-xcm-benchmarks/src/lib.rs @@ -19,12 +19,13 @@ #![cfg_attr(not(feature = "std"), no_std)] use codec::Encode; -use frame_benchmarking::account; +use frame_benchmarking::{account, BenchmarkError}; use sp_std::prelude::*; use xcm::latest::prelude::*; -use xcm_executor::{traits::Convert, Assets}; +use xcm_executor::traits::Convert; pub mod fungible; +pub mod generic; #[cfg(test)] mod mock; @@ -42,7 +43,10 @@ pub trait Config: frame_system::Config { /// Does any necessary setup to create a valid destination for XCM messages. /// Returns that destination's multi-location to be used in benchmarks. - fn valid_destination() -> Result; + fn valid_destination() -> Result; + + /// Worst case scenario for a holding account in this runtime. + fn worst_case_holding() -> MultiAssets; } const SEED: u32 = 0; @@ -56,12 +60,10 @@ pub type AssetTransactorOf = <::XcmConfig as xcm_executor::Confi /// The call type of executor's config. Should eventually resolve to the same overarching call type. pub type XcmCallOf = <::XcmConfig as xcm_executor::Config>::Call; -/// The worst case number of assets in the holding. -const HOLDING_FUNGIBLES: u32 = 99; -const HOLDING_NON_FUNGIBLES: u32 = 99; - -pub fn worst_case_holding() -> Assets { - let fungibles_amount: u128 = 100; // TODO probably update +pub fn mock_worst_case_holding() -> MultiAssets { + const HOLDING_FUNGIBLES: u32 = 99; + const HOLDING_NON_FUNGIBLES: u32 = 99; + let fungibles_amount: u128 = 100; (0..HOLDING_FUNGIBLES) .map(|i| { MultiAsset { diff --git a/xcm/pallet-xcm-benchmarks/template.hbs b/xcm/pallet-xcm-benchmarks/template.hbs index 357fa7456aa0..89880e9f7061 100644 --- a/xcm/pallet-xcm-benchmarks/template.hbs +++ b/xcm/pallet-xcm-benchmarks/template.hbs @@ -21,7 +21,7 @@ //! EXECUTION: {{cmd.execution}}, WASM-EXECUTION: {{cmd.wasm_execution}}, CHAIN: {{cmd.chain}}, DB CACHE: {{cmd.db_cache}} // Executed Command: -{{#each args as |arg|~}} +{{#each args as |arg|}} // {{arg}} {{/each}} @@ -35,32 +35,32 @@ use sp_std::marker::PhantomData; /// Weights for `{{pallet}}`. pub struct WeightInfo(PhantomData); impl WeightInfo { - {{~#each benchmarks as |benchmark|}} - {{~#each benchmark.comments as |comment|}} + {{#each benchmarks as |benchmark|}} + {{#each benchmark.comments as |comment|}} // {{comment}} - {{~/each}} + {{/each}} pub(crate) fn {{benchmark.name~}} ( {{~#each benchmark.components as |c| ~}} {{~#if (not c.is_used)}}_{{/if}}{{c.name}}: u32, {{/each~}} ) -> Weight { ({{underscore benchmark.base_weight}} as Weight) - {{~#each benchmark.component_weight as |cw|}} + {{#each benchmark.component_weight as |cw|}} // Standard Error: {{underscore cw.error}} .saturating_add(({{underscore cw.slope}} as Weight).saturating_mul({{cw.name}} as Weight)) - {{~/each}} - {{~#if (ne benchmark.base_reads "0")}} + {{/each}} + {{#if (ne benchmark.base_reads "0")}} .saturating_add(T::DbWeight::get().reads({{benchmark.base_reads}} as Weight)) - {{~/if}} - {{~#each benchmark.component_reads as |cr|}} + {{/if}} + {{#each benchmark.component_reads as |cr|}} .saturating_add(T::DbWeight::get().reads(({{cr.slope}} as Weight).saturating_mul({{cr.name}} as Weight))) - {{~/each}} - {{~#if (ne benchmark.base_writes "0")}} + {{/each}} + {{#if (ne benchmark.base_writes "0")}} .saturating_add(T::DbWeight::get().writes({{benchmark.base_writes}} as Weight)) - {{~/if}} - {{~#each benchmark.component_writes as |cw|}} + {{/if}} + {{#each benchmark.component_writes as |cw|}} .saturating_add(T::DbWeight::get().writes(({{cw.slope}} as Weight).saturating_mul({{cw.name}} as Weight))) - {{~/each}} + {{/each}} } - {{~/each}} + {{/each}} } diff --git a/xcm/src/v2/traits.rs b/xcm/src/v2/traits.rs index 12ffd0e8538f..8264039dcac5 100644 --- a/xcm/src/v2/traits.rs +++ b/xcm/src/v2/traits.rs @@ -344,7 +344,6 @@ pub trait XcmWeightInfo { fn clear_origin() -> Weight; fn descend_origin(who: &InteriorMultiLocation) -> Weight; fn report_error(query_id: &QueryId, dest: &MultiLocation, max_response_weight: &u64) -> Weight; - fn relayed_from(who: &Junctions, message: &alloc::boxed::Box>) -> Weight; fn deposit_asset( assets: &MultiAssetFilter, max_assets: &u32,