diff --git a/node/src/chain_spec/dev.rs b/node/src/chain_spec/dev.rs index f1cef8c579..c3004b59c5 100644 --- a/node/src/chain_spec/dev.rs +++ b/node/src/chain_spec/dev.rs @@ -111,7 +111,7 @@ fn pint_testnet_genesis( code: WASM_BINARY.expect("WASM binary was not build, please build it!").to_vec(), changes_trie_config: Default::default(), }, - balances: BalancesConfig { balances: endowed_accounts.iter().cloned().map(|k| (k, 1 << 60)).collect() }, + balances: BalancesConfig { balances: endowed_accounts.iter().cloned().map(|k| (k, 1 << 12)).collect() }, committee: CommitteeConfig { council_members: council_members.clone(), ..Default::default() }, chainlink_feed: ChainlinkFeedConfig { pallet_admin: Some(root_key.clone()), feed_creators: council_members }, sudo: SudoConfig { key: root_key }, @@ -139,8 +139,8 @@ fn pint_testnet_genesis( // // this config is only for tests for now balances: vec![ - endowed_accounts.iter().cloned().map(|k| (k, 42, 1 << 60)).collect::>(), - endowed_accounts.iter().cloned().map(|k| (k, 43, 1 << 60)).collect::>(), + endowed_accounts.iter().cloned().map(|k| (k, 2, 1 << 12)).collect::>(), + endowed_accounts.iter().cloned().map(|k| (k, 3, 1 << 12)).collect::>(), ] .concat(), }, diff --git a/pallets/asset-index/src/benchmarking.rs b/pallets/asset-index/src/benchmarking.rs index 131937454e..7a1e1f6948 100644 --- a/pallets/asset-index/src/benchmarking.rs +++ b/pallets/asset-index/src/benchmarking.rs @@ -3,14 +3,13 @@ #![cfg(feature = "runtime-benchmarks")] -use frame_benchmarking::{account, benchmarks, vec}; +use frame_benchmarking::{benchmarks, vec}; use frame_support::{ assert_ok, dispatch::UnfilteredDispatchable, sp_runtime::{traits::AccountIdConversion, FixedPointNumber}, - traits::{Currency as _, EnsureOrigin, Get}, + traits::{EnsureOrigin, Get}, }; -use frame_system::RawOrigin; use orml_traits::MultiCurrency; use pallet_price_feed::{PriceFeed, PriceFeedBenchmarks}; use primitives::{traits::NavProvider, AssetAvailability}; @@ -20,18 +19,6 @@ use crate::Pallet as AssetIndex; use super::*; -const SEED: u32 = 0; - -fn whitelisted_account(name: &'static str, counter: u32) -> T::AccountId { - let acc = account(name, counter, SEED); - whitelist_acc::(&acc); - acc -} - -fn whitelist_acc(acc: &T::AccountId) { - frame_benchmarking::benchmarking::add_to_whitelist(frame_system::Account::::hashed_key_for(acc).into()); -} - benchmarks! { add_asset { let asset_id :T::AssetId = T::try_convert(2u8).unwrap(); @@ -60,22 +47,25 @@ benchmarks! { let asset_id : T::AssetId = T::try_convert(2u8).unwrap(); let units = 100_u32.into(); let tokens = 500_u32.into(); - let admin = T::AdminOrigin::successful_origin(); - let origin = whitelisted_account::("origin", 0); + let origin = T::AdminOrigin::successful_origin(); + let origin_account_id = T::AdminOrigin::ensure_origin(origin.clone()).unwrap(); let deposit_units = 1000_u32.into(); // create liquid assets assert_ok!(>::add_asset( - admin, + origin.clone(), asset_id, units, MultiLocation::Null, tokens )); + // create price feed + T::PriceFeedBenchmarks::create_feed(origin_account_id.clone(), asset_id).unwrap(); + // deposit some funds into the index from an user account - assert_ok!(T::Currency::deposit(asset_id, &origin, deposit_units)); - assert_ok!(>::deposit(RawOrigin::Signed(origin.clone()).into(), asset_id, deposit_units)); + assert_ok!(T::Currency::deposit(asset_id, &origin_account_id, deposit_units)); + assert_ok!(>::deposit(origin.clone(), asset_id, deposit_units)); // advance the block number so that the lock expires >::set_block_number( @@ -86,20 +76,19 @@ benchmarks! { // start withdraw assert_ok!(>::withdraw( - RawOrigin::Signed(origin.clone()).into(), + origin.clone(), 42_u32.into(), )); - }: _( - RawOrigin::Signed(origin.clone()) - ) verify { - assert_eq!(pallet::PendingWithdrawals::::get(&origin), None); + let call = Call::::complete_withdraw(); + }: { call.dispatch_bypass_filter(origin)? } verify { + assert_eq!(pallet::PendingWithdrawals::::get(&origin_account_id), None); } deposit { - let asset_id : T::AssetId = T::try_convert(2u8).unwrap(); + let asset_id = T::try_convert(2u8).unwrap(); let origin = T::AdminOrigin::successful_origin(); let origin_account_id = T::AdminOrigin::ensure_origin(origin.clone()).unwrap(); - let admin_deposit = 5u32; + let admin_deposit = 1_000_000u32; let units = 1_000u32.into(); assert_ok!(AssetIndex::::add_asset( @@ -110,39 +99,57 @@ benchmarks! { admin_deposit.into(), )); + let index_tokens = AssetIndex::::index_token_balance(&origin_account_id).into(); T::PriceFeedBenchmarks::create_feed(origin_account_id.clone(), asset_id).unwrap(); + assert_ok!(T::Currency::deposit(asset_id, &origin_account_id, units)); // construct call let call = Call::::deposit(asset_id, units); }: { call.dispatch_bypass_filter(origin)? } verify { let nav = AssetIndex::::nav().unwrap(); let deposit_value = T::PriceFeed::get_price(asset_id).unwrap().checked_mul_int(units.into()).unwrap(); - let received = nav.reciprocal().unwrap().saturating_mul_int(deposit_value).saturating_add(1u128); - assert_eq!(AssetIndex::::index_token_balance(&origin_account_id).into(), received + admin_deposit as u128); + let received = nav.reciprocal().unwrap().saturating_mul_int(deposit_value); + + // NOTE: + // + // the result will be 0 or 1 + // + // - 0 for tests + // - 1 for benchmarks ( transaction fee ) + assert!(AssetIndex::::index_token_balance(&origin_account_id).into() - (index_tokens + received) < 2); } - remove_asset { - let asset_id :T::AssetId = T::try_convert(2u8).unwrap(); - let origin = T::AdminOrigin::successful_origin(); - let units: u32 = 100; - let amount = 500u32.into(); - - assert_ok!(AssetIndex::::add_asset( - origin.clone(), - asset_id, - units.into(), - MultiLocation::Null, - amount, - )); - - // ensure - assert_eq!(T::IndexToken::total_balance(&Default::default()), 500u32.into()); - - // construct remove call - let call = Call::::remove_asset(asset_id, units.into(), None); - }: { call.dispatch_bypass_filter(origin.clone())? } verify { - assert_eq!(T::IndexToken::total_balance(&Default::default()), 0u32.into()); - } + // TODO: + // + // This extrinsic requires `remote-asset-manager` + // + // ---- + // + // remove_asset { + // let asset_id = T::try_convert(2u8).unwrap(); + // let units = 100_u32.into(); + // let amount = 1_000u32.into(); + // let origin = T::AdminOrigin::successful_origin(); + // let origin_account_id = T::AdminOrigin::ensure_origin(origin.clone()).unwrap(); + // let receiver = whitelisted_account::("receiver", 0); + // + // // create liquid assets + // assert_ok!(>::add_asset( + // origin.clone(), + // asset_id, + // units, + // MultiLocation::Null, + // amount + // )); + // + // // create price feed + // T::PriceFeedBenchmarks::create_feed(origin_account_id.clone(), asset_id).unwrap(); + // + // // construct call + // let call = Call::::remove_asset(asset_id, units, Some(receiver)); + // }: { call.dispatch_bypass_filter(origin.clone())? } verify { + // assert_eq!(T::IndexToken::total_balance(&origin_account_id), 0u32.into()); + // } register_asset { let asset_id :T::AssetId = T::try_convert(2u8).unwrap(); @@ -182,22 +189,25 @@ benchmarks! { let asset_id :T::AssetId = T::try_convert(2u8).unwrap(); let units = 100_u32.into(); let tokens = 500_u32.into(); - let admin = T::AdminOrigin::successful_origin(); - let origin = whitelisted_account::("origin", 0); + let origin = T::AdminOrigin::successful_origin(); + let origin_account_id = T::AdminOrigin::ensure_origin(origin.clone()).unwrap(); let deposit_units = 1_000_u32.into(); // create liquid assets assert_ok!(>::add_asset( - admin, + origin.clone(), asset_id, units, MultiLocation::Null, tokens )); + // create price feed + T::PriceFeedBenchmarks::create_feed(origin_account_id.clone(), asset_id).unwrap(); + // deposit some funds into the index from an user account - assert_ok!(T::Currency::deposit(asset_id, &origin, deposit_units)); - assert_ok!(>::deposit(RawOrigin::Signed(origin.clone()).into(), asset_id, deposit_units)); + assert_ok!(T::Currency::deposit(asset_id, &origin_account_id, deposit_units)); + assert_ok!(>::deposit(origin.clone(), asset_id, deposit_units)); // advance the block number so that the lock expires >::set_block_number( @@ -205,29 +215,31 @@ benchmarks! { + T::LockupPeriod::get() + 1_u32.into(), ); - }: _( - RawOrigin::Signed(origin.clone()), - 42_u32.into() - ) verify { - assert_eq!(pallet::PendingWithdrawals::::get(&origin).expect("pending withdrawals should be present").len(), 1); + + let call = Call::::withdraw(42_u32.into()); + }: { call.dispatch_bypass_filter(origin)? } verify { + assert_eq!(pallet::PendingWithdrawals::::get(&origin_account_id).expect("pending withdrawals should be present").len(), 1); } unlock { let asset_id :T::AssetId = T::try_convert(2u8).unwrap(); let origin = T::AdminOrigin::successful_origin(); - let depositor = whitelisted_account::("depositor", 0); + let origin_account_id = T::AdminOrigin::ensure_origin(origin.clone()).unwrap(); let amount = 500u32.into(); let units = 100u32.into(); - assert_ok!(AssetIndex::::add_asset(origin, asset_id, units, MultiLocation::Null, amount)); - assert_ok!(T::Currency::deposit(asset_id, &depositor, units)); - assert_ok!(>::deposit(RawOrigin::Signed(depositor.clone()).into(), asset_id, units)); - }: _( - RawOrigin::Signed(depositor.clone()) - ) verify { - assert_eq!(>::get(&depositor), vec![types::IndexTokenLock{ - locked: 500_u32.into(), - end_block: >::block_number() + T::LockupPeriod::get(), + // create price feed + T::PriceFeedBenchmarks::create_feed(origin_account_id.clone(), asset_id).unwrap(); + + assert_ok!(AssetIndex::::add_asset(origin.clone(), asset_id, units, MultiLocation::Null, amount)); + assert_ok!(T::Currency::deposit(asset_id, &origin_account_id, units)); + assert_ok!(>::deposit(origin.clone(), asset_id, units)); + + let call = Call::::unlock(); + }: { call.dispatch_bypass_filter(origin)? } verify { + assert_eq!(>::get(&origin_account_id), vec![types::IndexTokenLock{ + locked: >::index_token_equivalent(asset_id, units).unwrap(), + end_block: >::block_number() + T::LockupPeriod::get() - 1u32.into() }]); } } @@ -236,7 +248,7 @@ benchmarks! { mod tests { use frame_support::assert_ok; - use crate::mock::{new_test_ext, Test}; + use crate::mock::{new_test_ext, new_test_ext_from_genesis, Test}; use super::*; @@ -275,16 +287,16 @@ mod tests { }); } - #[test] - fn remove_asset() { - new_test_ext().execute_with(|| { - assert_ok!(Pallet::::test_benchmark_remove_asset()); - }); - } + // #[test] + // fn remove_asset() { + // new_test_ext().execute_with(|| { + // assert_ok!(Pallet::::test_benchmark_remove_asset()); + // }); + // } #[test] fn unlock() { - new_test_ext().execute_with(|| { + new_test_ext_from_genesis().execute_with(|| { assert_ok!(Pallet::::test_benchmark_unlock()); }); } diff --git a/pallets/asset-index/src/lib.rs b/pallets/asset-index/src/lib.rs index ce239aef45..f6553b3268 100644 --- a/pallets/asset-index/src/lib.rs +++ b/pallets/asset-index/src/lib.rs @@ -28,6 +28,11 @@ pub mod types; // this is requires as the #[pallet::event] proc macro generates code that violates this lint #[allow(clippy::unused_unit, clippy::large_enum_variant, clippy::type_complexity)] pub mod pallet { + #[cfg(feature = "runtime-benchmarks")] + use pallet_price_feed::PriceFeedBenchmarks; + #[cfg(feature = "runtime-benchmarks")] + use primitives::traits::AssetRecorderBenchmarks; + use frame_support::{ dispatch::DispatchResultWithPostInfo, pallet_prelude::*, @@ -44,8 +49,6 @@ pub mod pallet { use sp_core::U256; use xcm::v0::MultiLocation; - #[cfg(feature = "runtime-benchmarks")] - use pallet_price_feed::PriceFeedBenchmarks; use pallet_price_feed::{AssetPricePair, Price, PriceFeed}; use primitives::{ fee::{BaseFee, FeeRate}, @@ -483,7 +486,6 @@ pub mod pallet { // the amount of index token the given units of the liquid assets are worth let index_tokens = Self::index_token_equivalent(asset_id, units)?; - if index_tokens.is_zero() { return Err(Error::::InsufficientDeposit.into()); } @@ -1037,6 +1039,21 @@ pub mod pallet { } } + #[cfg(feature = "runtime-benchmarks")] + impl AssetRecorderBenchmarks for Pallet { + fn add_asset( + asset_id: T::AssetId, + units: T::Balance, + location: MultiLocation, + amount: T::Balance, + ) -> DispatchResultWithPostInfo { + let origin = T::AdminOrigin::successful_origin(); + let origin_account_id = T::AdminOrigin::ensure_origin(origin.clone()).unwrap(); + T::PriceFeedBenchmarks::create_feed(origin_account_id, asset_id)?; + Self::add_asset(T::AdminOrigin::successful_origin(), asset_id, units, location, amount) + } + } + impl MultiAssetRegistry for Pallet { fn native_asset_location(asset: &T::AssetId) -> Option { Assets::::get(asset).and_then(|availability| { @@ -1168,9 +1185,11 @@ pub mod pallet { if total_issuance.is_zero() { return Ok(Ratio::zero()); } + Assets::::iter().try_fold(Ratio::zero(), |nav, (asset, availability)| -> Result<_, DispatchError> { let value = if availability.is_liquid() { Self::net_liquid_value(asset)? } else { Self::net_saft_value(asset) }; + let proportion = Ratio::checked_from_rational(value.into(), total_issuance.into()) .ok_or(ArithmeticError::Overflow)?; Ok(nav.checked_add(&proportion).ok_or(ArithmeticError::Overflow)?) diff --git a/pallets/asset-index/src/mock.rs b/pallets/asset-index/src/mock.rs index 2a75b25e01..c4fef13003 100644 --- a/pallets/asset-index/src/mock.rs +++ b/pallets/asset-index/src/mock.rs @@ -136,6 +136,8 @@ impl orml_tokens::Config for Test { } impl pallet_saft_registry::Config for Test { + #[cfg(feature = "runtime-benchmarks")] + type AssetRecorderBenchmarks = AssetIndex; type AdminOrigin = frame_system::EnsureSignedBy; type Event = Event; type Balance = Balance; @@ -298,3 +300,13 @@ pub fn new_test_ext_with_balance(balances: Vec<(AccountId, AssetId, Balance)>) - ext } + +pub fn new_test_ext_from_genesis() -> sp_io::TestExternalities { + let ext = ExtBuilder::default().build(); + MockPriceFeed::set_prices(vec![ + (ASSET_A_ID, Price::from(ASSET_A_PRICE_MULTIPLIER)), + (ASSET_B_ID, Price::from(ASSET_B_PRICE_MULTIPLIER)), + ]); + + ext +} diff --git a/pallets/remote-asset-manager/src/mock.rs b/pallets/remote-asset-manager/src/mock.rs index 96b003072c..d6e0e3fe1b 100644 --- a/pallets/remote-asset-manager/src/mock.rs +++ b/pallets/remote-asset-manager/src/mock.rs @@ -427,6 +427,8 @@ pub mod para { } impl pallet_saft_registry::Config for Runtime { + #[cfg(feature = "runtime-benchmarks")] + type AssetRecorderBenchmarks = AssetIndex; type AdminOrigin = frame_system::EnsureSignedBy; type Event = Event; type Balance = Balance; diff --git a/pallets/saft-registry/src/benchmarking.rs b/pallets/saft-registry/src/benchmarking.rs index bc1be048c1..1e6ff0b079 100644 --- a/pallets/saft-registry/src/benchmarking.rs +++ b/pallets/saft-registry/src/benchmarking.rs @@ -5,7 +5,8 @@ use frame_benchmarking::benchmarks; use frame_support::{assert_ok, dispatch::UnfilteredDispatchable, sp_runtime::traits::Zero, traits::EnsureOrigin}; -use xcm::v0::Junction; +use primitives::traits::AssetRecorderBenchmarks; +use xcm::v0::{Junction, MultiLocation}; use crate::Pallet as SaftRegistry; @@ -15,8 +16,16 @@ const MAX_SAFT_RECORDS: u32 = 100; benchmarks! { add_saft { - let asset: T::AssetId = T::try_convert(0u8).unwrap(); + let asset: T::AssetId = T::try_convert(2u8).unwrap(); let origin = T::AdminOrigin::successful_origin(); + + assert_ok!(T::AssetRecorderBenchmarks::add_asset( + T::try_convert(3u8).unwrap(), + 100u32.into(), + MultiLocation::Null, + 1000u32.into() + )); + let call = Call::::add_saft( asset, 100u32.into(), @@ -32,8 +41,16 @@ benchmarks! { } remove_saft { - let asset: T::AssetId = T::try_convert(0u8).unwrap(); + let asset: T::AssetId = T::try_convert(2u8).unwrap(); let origin = T::AdminOrigin::successful_origin(); + + assert_ok!(T::AssetRecorderBenchmarks::add_asset( + T::try_convert(3u8).unwrap(), + 100u32.into(), + MultiLocation::Null, + 1000u32.into() + )); + assert_ok!(SaftRegistry::::add_saft(origin.clone(), asset, 100u32.into(), 20u32.into())); let call = Call::::remove_saft( asset, @@ -47,14 +64,23 @@ benchmarks! { } report_nav { - let asset: T::AssetId = T::try_convert(0u8).unwrap(); + let asset: T::AssetId = T::try_convert(2u8).unwrap(); let origin = T::AdminOrigin::successful_origin(); + + assert_ok!(T::AssetRecorderBenchmarks::add_asset( + T::try_convert(3u8).unwrap(), + 100u32.into(), + MultiLocation::Null, + 1000u32.into() + )); + assert_ok!(SaftRegistry::::add_saft( origin.clone(), asset, 100_u32.into(), 20_u32.into(), )); + let call = Call::::report_nav( asset, 0, @@ -71,8 +97,16 @@ benchmarks! { convert_to_liquid { let nav = 1337u32; let units = 1234u32; - let asset:T::AssetId = T::try_convert(0u8).unwrap(); + let asset:T::AssetId = T::try_convert(2u8).unwrap(); let origin = T::AdminOrigin::successful_origin(); + + assert_ok!(T::AssetRecorderBenchmarks::add_asset( + T::try_convert(3u8).unwrap(), + 100u32.into(), + MultiLocation::Null, + 1000u32.into() + )); + // Create saft records for i in 0 .. MAX_SAFT_RECORDS { assert_ok!(SaftRegistry::::add_saft( diff --git a/pallets/saft-registry/src/lib.rs b/pallets/saft-registry/src/lib.rs index 1e9e5b810b..e6cdb9e9f5 100644 --- a/pallets/saft-registry/src/lib.rs +++ b/pallets/saft-registry/src/lib.rs @@ -18,6 +18,9 @@ mod tests; #[allow(clippy::unused_unit)] #[allow(clippy::large_enum_variant)] pub mod pallet { + #[cfg(feature = "runtime-benchmarks")] + use primitives::traits::AssetRecorderBenchmarks; + use frame_support::{ pallet_prelude::*, sp_runtime::{ @@ -40,6 +43,8 @@ pub mod pallet { // Origin that is allowed to manage the SAFTs type AdminOrigin: EnsureOrigin::AccountId>; type AssetRecorder: AssetRecorder; + #[cfg(feature = "runtime-benchmarks")] + type AssetRecorderBenchmarks: AssetRecorderBenchmarks; type Balance: Parameter + Member + AtLeast32BitUnsigned + Default + Copy; type AssetId: Parameter + Member + Copy; type Event: From> + IsType<::Event>; diff --git a/pallets/saft-registry/src/mock.rs b/pallets/saft-registry/src/mock.rs index 7a5661439b..7412e9b97f 100644 --- a/pallets/saft-registry/src/mock.rs +++ b/pallets/saft-registry/src/mock.rs @@ -149,7 +149,7 @@ impl pallet_asset_index::Config for Test { type WeightInfo = (); } -pub const LIQUID_ASSET_ID: AssetId = 42u32; +pub const LIQUID_ASSET_ID: AssetId = 3u32; pub const SAFT_ASSET_ID: AssetId = 43u32; pub const LIQUID_ASSET_MULTIPLIER: Balance = 2; pub const SAFT_ASSET_MULTIPLIER: Balance = 3; @@ -208,6 +208,8 @@ ord_parameter_types! { } impl pallet_saft_registry::Config for Test { + #[cfg(feature = "runtime-benchmarks")] + type AssetRecorderBenchmarks = AssetIndex; type AdminOrigin = frame_system::EnsureSignedBy; type Event = Event; type Balance = Balance; diff --git a/primitives/primitives/src/traits.rs b/primitives/primitives/src/traits.rs index 7c262f2d42..bf460d620d 100644 --- a/primitives/primitives/src/traits.rs +++ b/primitives/primitives/src/traits.rs @@ -4,6 +4,9 @@ //! This contains shared traits that are used in multiple pallets to prevent //! circular dependencies +#[cfg(feature = "runtime-benchmarks")] +use frame_support::dispatch::DispatchResultWithPostInfo; + use crate::{AssetAvailability, AssetPricePair, AssetProportions, Price, Ratio}; use frame_support::{ dispatch::DispatchError, @@ -269,6 +272,16 @@ pub trait AssetRecorder { fn remove_saft(who: AccountId, id: AssetId, units: Balance, nav: Balance) -> DispatchResult; } +#[cfg(feature = "runtime-benchmarks")] +pub trait AssetRecorderBenchmarks { + fn add_asset( + asset_id: AssetId, + units: Balance, + localtion: MultiLocation, + amount: Balance, + ) -> DispatchResultWithPostInfo; +} + /// Determines the fee upon index token redemptions pub trait RedemptionFee { /// Determines the redemption fee based on how long the given amount were held in the index diff --git a/runtime/dev/src/lib.rs b/runtime/dev/src/lib.rs index d60e7f3c9a..d773ddc852 100644 --- a/runtime/dev/src/lib.rs +++ b/runtime/dev/src/lib.rs @@ -427,6 +427,8 @@ impl pallet_remote_treasury::Config for Runtime { impl pallet_saft_registry::Config for Runtime { type AdminOrigin = CommitteeOrigin; type AssetRecorder = AssetIndex; + #[cfg(feature = "runtime-benchmarks")] + type AssetRecorderBenchmarks = AssetIndex; type Balance = Balance; type AssetId = AssetId; type Event = Event; diff --git a/runtime/kusama/src/lib.rs b/runtime/kusama/src/lib.rs index 8bfbce63da..b01a75870e 100644 --- a/runtime/kusama/src/lib.rs +++ b/runtime/kusama/src/lib.rs @@ -424,6 +424,8 @@ impl pallet_remote_treasury::Config for Runtime { impl pallet_saft_registry::Config for Runtime { type AdminOrigin = CommitteeOrigin; type AssetRecorder = AssetIndex; + #[cfg(feature = "runtime-benchmarks")] + type AssetRecorderBenchmarks = AssetIndex; type Balance = Balance; type AssetId = AssetId; type Event = Event; diff --git a/runtime/polkadot/src/lib.rs b/runtime/polkadot/src/lib.rs index 300f205c9c..7fb029ac10 100644 --- a/runtime/polkadot/src/lib.rs +++ b/runtime/polkadot/src/lib.rs @@ -427,6 +427,8 @@ impl pallet_remote_treasury::Config for Runtime { impl pallet_saft_registry::Config for Runtime { type AdminOrigin = CommitteeOrigin; type AssetRecorder = AssetIndex; + #[cfg(feature = "runtime-benchmarks")] + type AssetRecorderBenchmarks = AssetIndex; type Balance = Balance; type AssetId = AssetId; type Event = Event;