diff --git a/Cargo.lock b/Cargo.lock index 00cca29359..6800652949 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -629,6 +629,7 @@ dependencies = [ name = "astar-xcm-benchmarks" version = "0.1.0" dependencies = [ + "astar-primitives", "frame-benchmarking", "frame-support", "frame-system", @@ -637,12 +638,14 @@ dependencies = [ "pallet-balances", "pallet-xcm", "parity-scale-codec", + "paste", "scale-info", "serde", "sp-core", "sp-io", "sp-runtime", "sp-std", + "sp-tracing", "xcm", "xcm-builder", "xcm-executor", diff --git a/pallets/astar-xcm-benchmarks/Cargo.toml b/pallets/astar-xcm-benchmarks/Cargo.toml index 0c78bc52f8..d97e16ae90 100644 --- a/pallets/astar-xcm-benchmarks/Cargo.toml +++ b/pallets/astar-xcm-benchmarks/Cargo.toml @@ -13,11 +13,12 @@ serde = { workspace = true, optional = true } # Substrate frame-support = { workspace = true, default-features = false } frame-system = { workspace = true } -parity-scale-codec = { workspace = true, features = ["derive"] } -scale-info = { workspace = true, features = ["derive"] } +parity-scale-codec = { workspace = true } +scale-info = { workspace = true } sp-std = { workspace = true } # Polkadot / XCM +astar-primitives = { workspace = true } sp-io = { workspace = true } sp-runtime = { workspace = true } xcm = { workspace = true } @@ -31,7 +32,9 @@ frame-benchmarking = { workspace = true } pallet-assets = { workspace = true } pallet-balances = { workspace = true } pallet-xcm = { workspace = true } +paste = { workspace = true } sp-core = { workspace = true } +sp-tracing = { workspace = true } [features] default = ["std"] @@ -46,12 +49,23 @@ std = [ "xcm/std", "sp-io/std", "sp-runtime/std", + "sp-core/std", + "astar-primitives/std", + "scale-info/std", + "astar-primitives/std", + "pallet-balances/std", + "pallet-assets/std", ] runtime-benchmarks = [ "xcm-builder/runtime-benchmarks", "xcm-executor/runtime-benchmarks", + "pallet-xcm/runtime-benchmarks", "frame-benchmarking/runtime-benchmarks", "frame-system/runtime-benchmarks", "frame-support/runtime-benchmarks", + "astar-primitives/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", ] + +try-runtime = ["frame-support/try-runtime"] diff --git a/pallets/astar-xcm-benchmarks/src/fungible/assets/mock.rs b/pallets/astar-xcm-benchmarks/src/fungible/assets/mock.rs index 6a09dafc24..5feec89f7d 100644 --- a/pallets/astar-xcm-benchmarks/src/fungible/assets/mock.rs +++ b/pallets/astar-xcm-benchmarks/src/fungible/assets/mock.rs @@ -23,25 +23,36 @@ use crate::{fungible::assets as xcm_assets_benchmark, mock::*}; use frame_benchmarking::BenchmarkError; use frame_support::{ parameter_types, - traits::{ConstU32, Everything, Nothing}, + traits::{AsEnsureOriginWithArg, ConstU32, Everything, Nothing}, weights::Weight, }; +use frame_system::{EnsureRoot, EnsureSigned}; +use parity_scale_codec::Compact; use sp_core::H256; -use sp_runtime::traits::{BlakeTwo256, IdentityLookup}; +use sp_runtime::{ + testing::Header, + traits::{BlakeTwo256, IdentityLookup}, +}; +use sp_std::borrow::Borrow; use xcm::latest::prelude::*; -use xcm_builder::{AllowUnpaidExecutionFrom, ConvertedConcreteId, IsConcrete, MintLocation}; -use xcm_executor::traits::JustTry; +use xcm_builder::{AllowUnpaidExecutionFrom, ConvertedConcreteId, MintLocation}; +use xcm_executor::traits::{Convert, JustTry}; type Block = frame_system::mocking::MockBlock; +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; // For testing the pallet, we construct a mock runtime. frame_support::construct_runtime!( - pub enum Test + pub struct Test + where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - XcmAssetsBenchmark: xcm_assets_benchmark::{Pallet}, - Assets : pallet_balances::{Pallet, Call, Storage, Config, Event}, + System: frame_system, + Balances: pallet_balances, + XcmAssetsBenchmark: xcm_assets_benchmark, + Assets: pallet_assets, } ); @@ -56,13 +67,14 @@ impl frame_system::Config for Test { type BlockLength = (); type DbWeight = (); type RuntimeOrigin = RuntimeOrigin; - type Nonce = u64; type Hash = H256; + type Index = u64; + type Header = Header; + type BlockNumber = u64; type RuntimeCall = RuntimeCall; type Hashing = BlakeTwo256; type AccountId = u64; type Lookup = IdentityLookup; - type Block = Block; type RuntimeEvent = RuntimeEvent; type BlockHashCount = BlockHashCount; type Version = (); @@ -90,10 +102,10 @@ impl pallet_balances::Config for Test { type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; type WeightInfo = (); - type RuntimeHoldReason = RuntimeHoldReason; type FreezeIdentifier = (); type MaxHolds = ConstU32<0>; type MaxFreezes = ConstU32<0>; + type HoldIdentifier = (); } parameter_types! { @@ -103,7 +115,7 @@ parameter_types! { pub const MetadataDepositBase: u64 = 10 * ExistentialDeposit::get(); pub const MetadataDepositPerByte: u64 = 1 * ExistentialDeposit::get(); pub const AssetAccountDeposit: u64 = 1 * ExistentialDeposit::get(); - const AssetsStringLimit: u32 = 50; + pub const AssetsStringLimit: u32 = 50; } @@ -112,8 +124,8 @@ impl pallet_assets::Config for Test { type Balance = u64; type AssetId = u64; type Currency = Balances; - type CreateOrigin = AsEnsureOriginWithArg>; - type ForceOrigin = EnsureRoot; + type CreateOrigin = AsEnsureOriginWithArg>; + type ForceOrigin = EnsureRoot; type AssetDeposit = AssetDeposit; type MetadataDepositBase = MetadataDepositBase; type MetadataDepositPerByte = MetadataDepositPerByte; @@ -130,6 +142,9 @@ impl pallet_assets::Config for Test { type BenchmarkHelper = (); } +parameter_types! { + pub const DummyCheckingAccount : u64 = 0; +} // Use fungible transactor as the asset transactor. pub type AssetTransactor = xcm_builder::FungiblesAdapter< Assets, @@ -137,14 +152,14 @@ pub type AssetTransactor = xcm_builder::FungiblesAdapter< AccountIdConverter, u64, xcm_builder::NoChecking, - 0, + DummyCheckingAccount, >; pub struct AssetLocationIdConverter; impl Convert for AssetLocationIdConverter { fn convert_ref(location: impl Borrow) -> Result { if let X1(GeneralIndex(i)) = location.borrow().clone().interior { - Ok(i.into()) + Ok(>::try_into(i).map_err(|_| ())?) } else { Err(()) } @@ -187,7 +202,6 @@ impl xcm_executor::Config for XcmConfig { type UniversalAliases = Nothing; type CallDispatcher = RuntimeCall; type SafeCallFilter = Everything; - type Aliasers = Nothing; } impl crate::Config for Test { diff --git a/pallets/astar-xcm-benchmarks/src/fungible/balances/mock.rs b/pallets/astar-xcm-benchmarks/src/fungible/balances/mock.rs index 0bd3e943b4..347ebc2eb0 100644 --- a/pallets/astar-xcm-benchmarks/src/fungible/balances/mock.rs +++ b/pallets/astar-xcm-benchmarks/src/fungible/balances/mock.rs @@ -19,7 +19,7 @@ // Copyright (C) Parity Technologies (UK) Ltd. //! A mock runtime for XCM benchmarking. -use crate::{fungible as xcm_balances_benchmark, mock::*}; +use crate::{fungible::balances as xcm_balances_benchmark, mock::*}; use frame_benchmarking::BenchmarkError; use frame_support::{ parameter_types, @@ -27,19 +27,27 @@ use frame_support::{ weights::Weight, }; use sp_core::H256; -use sp_runtime::traits::{BlakeTwo256, IdentityLookup}; +use sp_runtime::{ + testing::Header, + traits::{BlakeTwo256, IdentityLookup}, +}; use xcm::latest::prelude::*; use xcm_builder::{AllowUnpaidExecutionFrom, MintLocation}; type Block = frame_system::mocking::MockBlock; +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; // For testing the pallet, we construct a mock runtime. frame_support::construct_runtime!( - pub enum Test + pub struct Test + where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, - XcmBalancesBenchmark: xcm_balances_benchmark::{Pallet}, + System: frame_system, + Balances: pallet_balances, + XcmBalancesBenchmark: xcm_balances_benchmark, } ); @@ -54,13 +62,14 @@ impl frame_system::Config for Test { type BlockLength = (); type DbWeight = (); type RuntimeOrigin = RuntimeOrigin; - type Nonce = u64; type Hash = H256; + type Index = u64; + type Header = Header; + type BlockNumber = u64; type RuntimeCall = RuntimeCall; type Hashing = BlakeTwo256; type AccountId = u64; type Lookup = IdentityLookup; - type Block = Block; type RuntimeEvent = RuntimeEvent; type BlockHashCount = BlockHashCount; type Version = (); @@ -88,10 +97,10 @@ impl pallet_balances::Config for Test { type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; type WeightInfo = (); - type RuntimeHoldReason = RuntimeHoldReason; type FreezeIdentifier = (); type MaxHolds = ConstU32<0>; type MaxFreezes = ConstU32<0>; + type HoldIdentifier = (); } parameter_types! { @@ -155,7 +164,6 @@ impl xcm_executor::Config for XcmConfig { type UniversalAliases = Nothing; type CallDispatcher = RuntimeCall; type SafeCallFilter = Everything; - type Aliasers = Nothing; } impl crate::Config for Test { diff --git a/pallets/astar-xcm-benchmarks/src/fungible/benchmarking.rs b/pallets/astar-xcm-benchmarks/src/fungible/benchmarking.rs deleted file mode 100644 index a8b8a8cd55..0000000000 --- a/pallets/astar-xcm-benchmarks/src/fungible/benchmarking.rs +++ /dev/null @@ -1,253 +0,0 @@ -// This file is part of Astar. - -// Copyright (C) 2019-2023 Stake Technologies Pte.Ltd. -// SPDX-License-Identifier: GPL-3.0-or-later - -// Astar 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. - -// Astar 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 Astar. If not, see . - -// Copyright (C) Parity Technologies (UK) Ltd. -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 - >::Balance - as - TryInto - >::Error: sp_std::fmt::Debug, - } - - withdraw_asset { - let (sender_account, sender_location) = account_and_location::(1); - let worst_case_holding = T::worst_case_holding(0); - let asset = T::get_multi_asset(); - - >::deposit_asset( - &asset, - &sender_location, - &XcmContext { - origin: Some(sender_location.clone()), - message_hash: [0; 32], - topic: None, - }, - ).unwrap(); - // check the assets of origin. - assert!(!T::TransactAsset::balance(&sender_account).is_zero()); - - let mut executor = new_executor::(sender_location); - executor.set_holding(worst_case_holding.into()); - let instruction = Instruction::>::WithdrawAsset(vec![asset.clone()].into()); - let xcm = Xcm(vec![instruction]); - }: { - executor.bench_process(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::(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(); - - >::deposit_asset( - &asset, - &sender_location, - &XcmContext { - origin: Some(sender_location.clone()), - message_hash: [0; 32], - topic: None, - }, - ).unwrap(); - assert!(T::TransactAsset::balance(&dest_account).is_zero()); - - let mut executor = new_executor::(sender_location); - let instruction = Instruction::TransferAsset { assets, beneficiary: dest_location }; - let xcm = Xcm(vec![instruction]); - }: { - executor.bench_process(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::(1); - let dest_location = T::valid_destination()?; - let dest_account = T::AccountIdConverter::convert(dest_location.clone()).unwrap(); - - let asset = T::get_multi_asset(); - >::deposit_asset( - &asset, - &sender_location, - &XcmContext { - origin: Some(sender_location.clone()), - message_hash: [0; 32], - topic: None, - }, - ).unwrap(); - let assets: MultiAssets = vec![ asset ].into(); - assert!(T::TransactAsset::balance(&dest_account).is_zero()); - - let mut executor = new_executor::(sender_location); - let instruction = Instruction::TransferReserveAsset { - assets, - dest: dest_location, - xcm: Xcm::new() - }; - let xcm = Xcm(vec![instruction]); - }: { - executor.bench_process(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 - } - - 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 - >::Balance::max_value() / 2u32.into(), - )?; - } - - let assets: MultiAssets = vec![ teleportable_asset ].into(); - - let mut executor = new_executor::(trusted_teleporter); - let instruction = Instruction::ReceiveTeleportedAsset(assets.clone()); - let xcm = Xcm(vec![instruction]); - }: { - executor.bench_process(xcm).map_err(|_| { - BenchmarkError::Override( - BenchmarkResult::from_weight(T::BlockWeights::get().max_block) - ) - })?; - } verify { - assert!(executor.holding().ensure_contains(&assets).is_ok()); - } - - deposit_asset { - let asset = T::get_multi_asset(); - let mut holding = T::worst_case_holding(1); - - // 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::(Default::default()); - executor.set_holding(holding.into()); - let instruction = Instruction::>::DepositAsset { - assets: asset.into(), - beneficiary: dest_location, - }; - let xcm = Xcm(vec![instruction]); - }: { - executor.bench_process(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(1); - - // 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::(Default::default()); - executor.set_holding(holding.into()); - let instruction = Instruction::>::DepositReserveAsset { - assets: asset.into(), - dest: dest_location, - xcm: Xcm::new(), - }; - let xcm = Xcm(vec![instruction]); - }: { - executor.bench_process(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(0); - - // Add our asset to the holding. - 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.set_holding(holding.into()); - let instruction = Instruction::>::InitiateTeleport { - assets: asset.into(), - dest: T::valid_destination()?, - xcm: Xcm::new(), - }; - let xcm = Xcm(vec![instruction]); - }: { - executor.bench_process(xcm)?; - } verify { - if let Some((checked_account, _)) = T::CheckedAccount::get() { - // teleport checked account should have received some asset. - assert!(!T::TransactAsset::balance(&checked_account).is_zero()); - } - } - - impl_benchmark_test_suite!( - Pallet, - crate::fungible::mock::new_test_ext(), - crate::fungible::mock::Test - ); -} diff --git a/pallets/astar-xcm-benchmarks/src/generic/mock.rs b/pallets/astar-xcm-benchmarks/src/generic/mock.rs index 6edce1f896..aa73c969cc 100644 --- a/pallets/astar-xcm-benchmarks/src/generic/mock.rs +++ b/pallets/astar-xcm-benchmarks/src/generic/mock.rs @@ -20,30 +20,38 @@ //! A mock runtime for XCM benchmarking. use crate::{generic, mock::*, *}; -use codec::Decode; use frame_support::{ match_types, parameter_types, traits::{Everything, OriginTrait}, weights::Weight, }; +use parity_scale_codec::Decode; use sp_core::H256; -use sp_runtime::traits::{BlakeTwo256, IdentityLookup, TrailingZeroInput}; +use sp_runtime::{ + testing::Header, + traits::{BlakeTwo256, IdentityLookup, TrailingZeroInput}, +}; use xcm_builder::{ test_utils::{ Assets, TestAssetExchanger, TestAssetLocker, TestAssetTrap, TestSubscriptionService, TestUniversalAliases, }, - AliasForeignAccountId32, AllowUnpaidExecutionFrom, + AllowUnpaidExecutionFrom, }; use xcm_executor::traits::ConvertOrigin; -type Block = frame_system::mocking::MockBlock; +type Block = frame_system::mocking::MockBlock; +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; frame_support::construct_runtime!( - pub enum Test + pub struct TestRuntime + where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - XcmGenericBenchmarks: generic::{Pallet}, + System: frame_system, + XcmGenericBenchmarks: generic, } ); @@ -53,19 +61,17 @@ parameter_types! { frame_system::limits::BlockWeights::simple_max(Weight::from_parts(1024, u64::MAX)); } -impl frame_system::Config for Test { +impl frame_system::Config for TestRuntime { type BaseCallFilter = Everything; type BlockWeights = (); type BlockLength = (); type DbWeight = (); type RuntimeOrigin = RuntimeOrigin; - type Nonce = u64; type Hash = H256; type RuntimeCall = RuntimeCall; type Hashing = BlakeTwo256; type AccountId = u64; type Lookup = IdentityLookup; - type Block = Block; type RuntimeEvent = RuntimeEvent; type BlockHashCount = BlockHashCount; type Version = (); @@ -77,6 +83,9 @@ impl frame_system::Config for Test { type SS58Prefix = (); type OnSetCode = (); type MaxConsumers = frame_support::traits::ConstU32<16>; + type Index = u64; + type Header = Header; + type BlockNumber = u64; } /// The benchmarks in this pallet should never need an asset transactor to begin with. @@ -106,7 +115,6 @@ match_types! { }; } -type Aliasers = AliasForeignAccountId32; pub struct XcmConfig; impl xcm_executor::Config for XcmConfig { type RuntimeCall = RuntimeCall; @@ -133,10 +141,9 @@ impl xcm_executor::Config for XcmConfig { type UniversalAliases = TestUniversalAliases; type CallDispatcher = RuntimeCall; type SafeCallFilter = Everything; - type Aliasers = Aliasers; } -impl crate::Config for Test { +impl crate::Config for TestRuntime { type XcmConfig = XcmConfig; type AccountIdConverter = AccountIdConverter; fn valid_destination() -> Result { @@ -156,7 +163,7 @@ impl crate::Config for Test { } } -impl generic::Config for Test { +impl generic::Config for TestRuntime { type RuntimeCall = RuntimeCall; fn worst_case_response() -> (u64, Response) { @@ -203,23 +210,6 @@ impl generic::Config for Test { // No MessageExporter in tests Err(BenchmarkError::Skip) } - - fn alias_origin() -> Result<(MultiLocation, MultiLocation), BenchmarkError> { - let origin: MultiLocation = ( - Parachain(1), - AccountId32 { - network: None, - id: [0; 32], - }, - ) - .into(); - let target: MultiLocation = AccountId32 { - network: None, - id: [0; 32], - } - .into(); - Ok((origin, target)) - } } #[cfg(feature = "runtime-benchmarks")] diff --git a/pallets/astar-xcm-benchmarks/src/mock.rs b/pallets/astar-xcm-benchmarks/src/mock.rs index 45170bfc6d..3f783859df 100644 --- a/pallets/astar-xcm-benchmarks/src/mock.rs +++ b/pallets/astar-xcm-benchmarks/src/mock.rs @@ -50,16 +50,19 @@ impl xcm_executor::traits::OnResponse for DevNull { } pub struct AccountIdConverter; -impl xcm_executor::traits::ConvertLocation for AccountIdConverter { - fn convert_location(ml: &MultiLocation) -> Option { +impl xcm_executor::traits::Convert for AccountIdConverter { + fn convert(ml: MultiLocation) -> Result { match ml { MultiLocation { parents: 0, interior: X1(Junction::AccountId32 { id, .. }), - } => Some(::decode(&mut &*id.to_vec()).unwrap()), - _ => None, + } => Ok(::decode(&mut &*id.to_vec()).unwrap()), + _ => Err(ml), } } + fn reverse(acc: u64) -> Result { + Err(acc) + } } parameter_types! {