-
Notifications
You must be signed in to change notification settings - Fork 373
[Feature] Add XCM benchmark weights to Statemint and Statemine #1454
Changes from 46 commits
999e8f7
26457ca
f07deed
9a179aa
009a3c5
dc1b3ef
6e06b34
c19763d
4435ac6
0fe8134
c996d6e
9845cdf
bfa6b5b
0a8abce
4086364
09b9f02
4d28efa
bf182cc
af88575
84bd7c7
1434df7
b1e472c
7574607
063fabc
0972d9d
19a991e
dc64b57
6c94d5c
5dddc60
3481ffa
3eeeea2
33e808e
2ff069f
2ebc26d
bebc96b
08cc6e9
a2475db
b901025
2f8655b
aec4b36
0a8a994
de97475
80faa1d
5dabe9e
274a576
c50d468
0fc3bf0
e6859c0
10b07ee
d239b60
2161326
3b869fe
168f0b3
59ab737
898b8bf
8cf49f1
3b4133f
571ca78
5499ef2
a09960e
247a9d9
49a3b1d
b8d6186
a12e37d
1cb21e6
0eab441
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| [package] | ||
| name = "pallet-xcm-benchmarks" | ||
| authors = ["Parity Technologies <[email protected]>"] | ||
| edition = "2021" | ||
| version = "0.9.27" | ||
ruseinov marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| description = "A pallet to benchmark XCM interactions." | ||
| homepage = "https://substrate.io" | ||
| license = "Gpl3_0" | ||
| readme = "README.md" | ||
| repository = "https://github.com/paritytech/cumulus/" | ||
|
|
||
| [package.metadata.docs.rs] | ||
| targets = ["x86_64-unknown-linux-gnu"] | ||
|
|
||
| [dependencies] | ||
| codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false } | ||
| scale-info = { version = "2.1.2", default-features = false, features = ["derive"] } | ||
| frame-support = { default-features = false, git = "https://github.com/paritytech/substrate" , branch = "master" } | ||
| frame-system = { default-features = false, git = "https://github.com/paritytech/substrate" , branch = "master" } | ||
| sp-runtime = { default-features = false, git = "https://github.com/paritytech/substrate" , branch = "master" } | ||
| sp-std = { default-features = false, git = "https://github.com/paritytech/substrate" , branch = "master" } | ||
| xcm-executor = {git = "https://github.com/paritytech/polkadot" , branch = "master", default-features = false, features = ["runtime-benchmarks"] } | ||
| frame-benchmarking = { default-features = false, git = "https://github.com/paritytech/substrate" , branch = "master" } | ||
| xcm = { git = "https://github.com/paritytech/polkadot" , branch = "master", default-features = false, features = ["runtime-benchmarks"] } | ||
|
||
| log = "0.4.17" | ||
|
|
||
| [dev-dependencies] | ||
| pallet-balances = { git = "https://github.com/paritytech/substrate" , branch = "master" } | ||
| pallet-assets = { git = "https://github.com/paritytech/substrate" , branch = "master" } | ||
| sp-core = { git = "https://github.com/paritytech/substrate" , branch = "master" } | ||
| sp-io = { git = "https://github.com/paritytech/substrate" , branch = "master" } | ||
| sp-tracing = { git = "https://github.com/paritytech/substrate" , branch = "master" } | ||
| xcm-builder = { git = "https://github.com/paritytech/polkadot", branch = "master" } | ||
| xcm = { git = "https://github.com/paritytech/polkadot" , branch = "master" } | ||
| pallet-xcm = { git = "https://github.com/paritytech/polkadot" , branch = "master" } | ||
| polkadot-runtime-common = { git = "https://github.com/paritytech/polkadot" , branch = "master" } | ||
| polkadot-primitives = { git = "https://github.com/paritytech/polkadot" , branch = "master" } | ||
|
|
||
| [features] | ||
| default = ["std"] | ||
| std = [ | ||
| "codec/std", | ||
| "frame-benchmarking/std", | ||
| "frame-support/std", | ||
| "frame-system/std", | ||
| "sp-runtime/std", | ||
| "sp-std/std" | ||
| ] | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| License: Gpl3_0 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,242 @@ | ||
| // Copyright 2022 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/>. | ||
|
|
||
| use super::*; | ||
| use crate::{account_and_location, new_executor, AssetTransactorOf, XcmCallOf}; | ||
| use frame_benchmarking::{benchmarks_instance_pallet, BenchmarkError, BenchmarkResult}; | ||
| use frame_support::{ | ||
| pallet_prelude::Get, | ||
| traits::fungible::{Inspect, Mutate}, | ||
| }; | ||
| use sp_runtime::traits::{Bounded, Zero}; | ||
| use sp_std::{prelude::*, vec}; | ||
| use xcm::latest::prelude::*; | ||
| use xcm_executor::traits::{Convert, TransactAsset}; | ||
|
|
||
| benchmarks_instance_pallet! { | ||
| where_clause { where | ||
| < | ||
| < | ||
| T::TransactAsset | ||
| as | ||
| Inspect<T::AccountId> | ||
| >::Balance | ||
| as | ||
| TryInto<u128> | ||
| >::Error: sp_std::fmt::Debug, | ||
| } | ||
|
|
||
| withdraw_asset { | ||
| let (sender_account, sender_location) = account_and_location::<T>(1); | ||
| let worst_case_holding = T::worst_case_holding(); | ||
| let asset = T::get_multi_asset(); | ||
|
|
||
| <AssetTransactorOf<T>>::deposit_asset(&asset, &sender_location).unwrap(); | ||
| // check the assets of origin. | ||
| assert!(!T::TransactAsset::balance(&sender_account).is_zero()); | ||
|
|
||
| let mut executor = new_executor::<T>(sender_location); | ||
| executor.holding = worst_case_holding.into(); | ||
| let instruction = Instruction::<XcmCallOf<T>>::WithdrawAsset(vec![asset.clone()].into()); | ||
| let xcm = Xcm(vec![instruction]); | ||
| }: { | ||
| executor.execute(xcm)?; | ||
| } verify { | ||
| // check one of the assets of origin. | ||
| assert!(T::TransactAsset::balance(&sender_account).is_zero()); | ||
| assert!(executor.holding.ensure_contains(&vec![asset].into()).is_ok()); | ||
| } | ||
|
|
||
| transfer_asset { | ||
| let (sender_account, sender_location) = account_and_location::<T>(1); | ||
| let asset = T::get_multi_asset(); | ||
| let assets: MultiAssets = vec![ asset.clone() ].into(); | ||
| // this xcm doesn't use holding | ||
|
|
||
| let dest_location = T::valid_destination()?; | ||
| let dest_account = T::AccountIdConverter::convert(dest_location.clone()).unwrap(); | ||
|
|
||
| <AssetTransactorOf<T>>::deposit_asset(&asset, &sender_location).unwrap(); | ||
| assert!(T::TransactAsset::balance(&dest_account).is_zero()); | ||
|
|
||
| let mut executor = new_executor::<T>(sender_location); | ||
| let instruction = Instruction::TransferAsset { assets, beneficiary: dest_location }; | ||
| let xcm = Xcm(vec![instruction]); | ||
| }: { | ||
| executor.execute(xcm)?; | ||
| } verify { | ||
| assert!(T::TransactAsset::balance(&sender_account).is_zero()); | ||
| assert!(!T::TransactAsset::balance(&dest_account).is_zero()); | ||
| } | ||
|
|
||
| transfer_reserve_asset { | ||
| let (sender_account, sender_location) = account_and_location::<T>(1); | ||
| let dest_location = T::valid_destination()?; | ||
| let dest_account = T::AccountIdConverter::convert(dest_location.clone()).unwrap(); | ||
|
|
||
| let asset = T::get_multi_asset(); | ||
| <AssetTransactorOf<T>>::deposit_asset(&asset, &sender_location).unwrap(); | ||
| let assets: MultiAssets = vec![ asset ].into(); | ||
| assert!(T::TransactAsset::balance(&dest_account).is_zero()); | ||
|
|
||
| let mut executor = new_executor::<T>(sender_location); | ||
| let instruction = Instruction::TransferReserveAsset { | ||
| assets, | ||
| dest: dest_location, | ||
| xcm: Xcm::new() | ||
| }; | ||
| let xcm = Xcm(vec![instruction]); | ||
| }: { | ||
| executor.execute(xcm)?; | ||
| } verify { | ||
| assert!(T::TransactAsset::balance(&sender_account).is_zero()); | ||
| assert!(!T::TransactAsset::balance(&dest_account).is_zero()); | ||
| // TODO: Check sender queue is not empty. #4426 | ||
| } | ||
|
|
||
| reserve_asset_deposited { | ||
| let (trusted_reserve, transferable_reserve_asset) = T::TrustedReserve::get() | ||
| .ok_or(BenchmarkError::Skip)?; | ||
|
|
||
| let assets: MultiAssets = vec![ transferable_reserve_asset ].into(); | ||
|
|
||
| let mut executor = new_executor::<T>(trusted_reserve); | ||
| let instruction = Instruction::ReserveAssetDeposited(assets.clone()); | ||
| let xcm = Xcm(vec![instruction]); | ||
| }: { | ||
| executor.execute(xcm).map_err(|_| { | ||
| BenchmarkError::Override( | ||
| BenchmarkResult::from_weight(T::BlockWeights::get().max_block) | ||
ruseinov marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| ) | ||
| })?; | ||
| } verify { | ||
| assert!(executor.holding.ensure_contains(&assets).is_ok()); | ||
| } | ||
|
|
||
| receive_teleported_asset { | ||
| // If there is no trusted teleporter, then we skip this benchmark. | ||
| let (trusted_teleporter, teleportable_asset) = T::TrustedTeleporter::get() | ||
| .ok_or(BenchmarkError::Skip)?; | ||
|
|
||
| if let Some(checked_account) = T::CheckedAccount::get() { | ||
| T::TransactAsset::mint_into( | ||
| &checked_account, | ||
| < | ||
| T::TransactAsset | ||
| as | ||
| Inspect<T::AccountId> | ||
| >::Balance::max_value() / 2u32.into(), | ||
| )?; | ||
| } | ||
|
|
||
| let assets: MultiAssets = vec![ teleportable_asset ].into(); | ||
|
|
||
| let mut executor = new_executor::<T>(trusted_teleporter); | ||
| let instruction = Instruction::ReceiveTeleportedAsset(assets.clone()); | ||
| let xcm = Xcm(vec![instruction]); | ||
| }: { | ||
| executor.execute(xcm).map_err(|_| { | ||
| BenchmarkError::Override( | ||
| BenchmarkResult::from_weight(T::BlockWeights::get().max_block) | ||
ruseinov marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| ) | ||
| })?; | ||
| } verify { | ||
| assert!(executor.holding.ensure_contains(&assets).is_ok()); | ||
| } | ||
|
|
||
| deposit_asset { | ||
| let asset = T::get_multi_asset(); | ||
| let mut holding = T::worst_case_holding(); | ||
|
|
||
| // Add our asset to the holding. | ||
| holding.push(asset.clone()); | ||
|
|
||
| // our dest must have no balance initially. | ||
| let dest_location = T::valid_destination()?; | ||
| let dest_account = T::AccountIdConverter::convert(dest_location.clone()).unwrap(); | ||
| assert!(T::TransactAsset::balance(&dest_account).is_zero()); | ||
|
|
||
| let mut executor = new_executor::<T>(Default::default()); | ||
| executor.holding = holding.into(); | ||
| let instruction = Instruction::<XcmCallOf<T>>::DepositAsset { | ||
| assets: asset.into(), | ||
| max_assets: 1, | ||
| beneficiary: dest_location, | ||
| }; | ||
| let xcm = Xcm(vec![instruction]); | ||
| }: { | ||
| executor.execute(xcm)?; | ||
| } verify { | ||
| // dest should have received some asset. | ||
| assert!(!T::TransactAsset::balance(&dest_account).is_zero()) | ||
| } | ||
|
|
||
| deposit_reserve_asset { | ||
| let asset = T::get_multi_asset(); | ||
| let mut holding = T::worst_case_holding(); | ||
|
|
||
| // Add our asset to the holding. | ||
| holding.push(asset.clone()); | ||
|
|
||
| // our dest must have no balance initially. | ||
| let dest_location = T::valid_destination()?; | ||
| let dest_account = T::AccountIdConverter::convert(dest_location.clone()).unwrap(); | ||
| assert!(T::TransactAsset::balance(&dest_account).is_zero()); | ||
|
|
||
| let mut executor = new_executor::<T>(Default::default()); | ||
| executor.holding = holding.into(); | ||
| let instruction = Instruction::<XcmCallOf<T>>::DepositReserveAsset { | ||
| assets: asset.into(), | ||
| max_assets: 1, | ||
| dest: dest_location, | ||
| xcm: Xcm::new(), | ||
| }; | ||
| let xcm = Xcm(vec![instruction]); | ||
| }: { | ||
| executor.execute(xcm)?; | ||
| } verify { | ||
| // dest should have received some asset. | ||
| assert!(!T::TransactAsset::balance(&dest_account).is_zero()) | ||
| } | ||
|
|
||
| initiate_teleport { | ||
| let asset = T::get_multi_asset(); | ||
| let mut holding = T::worst_case_holding(); | ||
|
|
||
| // Add our asset to the holding. | ||
| holding.push(asset.clone()); | ||
|
|
||
| let mut executor = new_executor::<T>(Default::default()); | ||
| executor.holding = holding.into(); | ||
| let instruction = Instruction::<XcmCallOf<T>>::InitiateTeleport { | ||
| assets: asset.into(), | ||
| dest: T::valid_destination()?, | ||
| xcm: Xcm::new(), | ||
| }; | ||
| let xcm = Xcm(vec![instruction]); | ||
| }: { | ||
| executor.execute(xcm)?; | ||
| } verify { | ||
| // we're good as long as there's no error, checking account is bypassed when operating on | ||
| // native assets aka Dot | ||
| } | ||
|
|
||
| impl_benchmark_test_suite!( | ||
| Pallet, | ||
| crate::fungible::mock::new_test_ext(), | ||
| crate::fungible::mock::Test | ||
| ); | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.