diff --git a/pallets/api/src/fungibles/benchmarking.rs b/pallets/api/src/fungibles/benchmarking.rs index d3d65b97..ced557f0 100644 --- a/pallets/api/src/fungibles/benchmarking.rs +++ b/pallets/api/src/fungibles/benchmarking.rs @@ -1,22 +1,42 @@ //! Benchmarking setup for pallet-api::fungibles +#![cfg(feature = "runtime-benchmarks")] + use super::{AccountIdOf, AssetIdOf, AssetsInstanceOf, AssetsOf, BalanceOf, Call, Config, Pallet}; +use codec::Encode; use frame_benchmarking::{account, v2::*}; use frame_support::{ assert_ok, traits::{ fungibles::{ - approvals::{Inspect as ApprovalInspect, Mutate}, - Create, Inspect, + approvals::{Inspect as ApprovalInspect, Mutate as ApprovalMutate}, + Create, Inspect, Mutate, }, Currency, }, }; use frame_system::RawOrigin; +use sp_core::crypto::FromEntropy; use sp_runtime::traits::Zero; const SEED: u32 = 1; +/// Trait describing factory functions for dispatchables' parameters. +pub trait ArgumentsFactory { + /// Factory function for an asset kind. + fn create_asset_kind(seed: u32) -> AssetKind; +} + +/// Implementation that expects the parameters implement the [`FromEntropy`] trait. +impl ArgumentsFactory for () +where + AssetKind: FromEntropy, +{ + fn create_asset_kind(seed: u32) -> AssetKind { + AssetKind::from_entropy(&mut seed.encode().as_slice()).unwrap() + } +} + // See if `generic_event` has been emitted. fn assert_has_event( generic_event: >>::RuntimeEvent, @@ -31,12 +51,53 @@ fn assert_has_event( mod benchmarks { use super::*; + // Parameter: + // - 'a': wethere `transfer` accepts native token fungible or asset. + #[benchmark] + fn transfer(a: Linear<0, 1>) -> Result<(), BenchmarkError> { + let from: AccountIdOf = account("Alice", 0, SEED); + let to: AccountIdOf = account("Bob", 0, SEED); + let min_balance = >::from(1u32); + let asset_id = AssetIdOf::::zero(); + let asset_kind = ::BenchmarkHelper::create_asset_kind(a); + let amount = >::from(u32::MAX / 2); + // Initiate the native balance for the `from` account. + T::Currency::make_free_balance_be(&from, u32::MAX.into()); + if a == 1 { + assert_ok!( as Create>>::create( + asset_id.clone(), + from.clone(), + true, + min_balance + )); + assert!( as Mutate>>::mint_into( + asset_id.clone(), + &from, + >::from(u32::MAX), + ) + .is_ok()); + }; + + #[extrinsic_call] + _(RawOrigin::Signed(from.clone()), asset_kind, to.clone(), amount); + if a == 1 { + assert_eq!( + as Inspect>>::total_balance(asset_id, &to), + >::from(u32::MAX / 2) + ); + } else { + assert_eq!(T::Currency::free_balance(&to), (u32::MAX / 2).into()); + } + Ok(()) + } + // Parameter: // - 'a': whether `approve_transfer` is required. // - 'c': whether `cancel_approval` is required. #[benchmark] fn approve(a: Linear<0, 1>, c: Linear<0, 1>) -> Result<(), BenchmarkError> { let asset_id = AssetIdOf::::zero(); + let asset_kind = ::BenchmarkHelper::create_asset_kind(SEED); let min_balance = >::from(1u32); let owner: AccountIdOf = account("Alice", 0, SEED); let spender: AccountIdOf = account("Bob", 0, SEED); @@ -49,7 +110,7 @@ mod benchmarks { true, min_balance )); - assert_ok!( as Mutate>>::approve( + assert_ok!( as ApprovalMutate>>::approve( asset_id.clone(), &owner, &spender, @@ -68,7 +129,7 @@ mod benchmarks { }; #[extrinsic_call] - _(RawOrigin::Signed(owner.clone()), asset_id.clone(), spender.clone(), approval_value); + _(RawOrigin::Signed(owner.clone()), asset_kind, spender.clone(), approval_value); assert_eq!(AssetsOf::::allowance(asset_id.clone(), &owner, &spender), approval_value); if c == 1 { diff --git a/pallets/api/src/fungibles/mod.rs b/pallets/api/src/fungibles/mod.rs index 16df4c0d..59d3ebe5 100644 --- a/pallets/api/src/fungibles/mod.rs +++ b/pallets/api/src/fungibles/mod.rs @@ -8,6 +8,9 @@ mod benchmarking; mod tests; pub mod weights; +#[cfg(feature = "runtime-benchmarks")] +pub use benchmarking::ArgumentsFactory; + use frame_support::traits::{ fungible::{Inspect as NativeInspect, Mutate as NativeMutate}, fungibles::{ @@ -112,6 +115,10 @@ pub mod pallet { /// Weight information for dispatchables in this pallet. type WeightInfo: WeightInfo; + + /// Helper type for benchmarks. + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper: ArgumentsFactory; } #[pallet::pallet]