git.delta.rocks / unique-network / refs/commits / 95f4d2aed1c2

difftreelog

source

runtime/src/lib.rs23.0 KiBsourcehistory
1//2// This file is subject to the terms and conditions defined in3// file 'LICENSE', which is part of this source code package.4//56//! The Substrate Node Template runtime. This can be compiled with `#[no_std]`, ready for Wasm.78#![cfg_attr(not(feature = "std"), no_std)]9// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256.10#![recursion_limit = "256"]1112// Make the WASM binary available.13#[cfg(feature = "std")]14include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));1516use pallet_contracts_rpc_runtime_api::ContractExecResult;17use pallet_grandpa::fg_primitives;18use pallet_grandpa::{AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList};19use sp_api::impl_runtime_apis;20use sp_consensus_aura::sr25519::AuthorityId as AuraId;21use sp_core::{ crypto::KeyTypeId, crypto::Public, OpaqueMetadata };22use sp_runtime::{23    create_runtime_str, generic, impl_opaque_keys,24    traits::{25        Convert, ConvertInto, BlakeTwo256, Block as BlockT, IdentifyAccount, 26        IdentityLookup, NumberFor, Saturating, Verify,27    },28    transaction_validity::{TransactionSource, TransactionValidity},29    ApplyExtrinsicResult, MultiSignature,30};31use sp_std::prelude::*;32#[cfg(feature = "std")]33use sp_version::NativeVersion;34use sp_version::RuntimeVersion;3536// A few exports that help ease life for downstream crates.37pub use pallet_balances::Call as BalancesCall;38pub use pallet_contracts::Schedule as ContractsSchedule;39pub use frame_support::{40    construct_runtime,41    dispatch::DispatchResult,42    parameter_types,43    traits::{44        Currency, ExistenceRequirement, Get, KeyOwnerProofSystem, OnUnbalanced, Randomness,45        WithdrawReason, LockIdentifier,46    },47    weights::{48        constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},49        DispatchInfo, GetDispatchInfo, IdentityFee, Pays, PostDispatchInfo, Weight,50        WeightToFeePolynomial,51    },52    StorageValue,53};54#[cfg(any(feature = "std", test))]55pub use sp_runtime::BuildStorage;56use sp_runtime:: { Perbill, Permill, Percent, ModuleId };57use frame_system::{self as system, EnsureRoot };58use sp_std::{marker::PhantomData};5960pub use pallet_timestamp::Call as TimestampCall;6162/// Struct that handles the conversion of Balance -> `u64`. This is used for63/// staking's election calculation.64pub struct CurrencyToVoteHandler;6566impl CurrencyToVoteHandler {67	fn factor() -> Balance {68		(Balances::total_issuance() / u64::max_value() as Balance).max(1)69	}70}7172impl Convert<Balance, u64> for CurrencyToVoteHandler {73	fn convert(x: Balance) -> u64 {74		(x / Self::factor()) as u6475	}76}7778impl Convert<u128, Balance> for CurrencyToVoteHandler {79	fn convert(x: u128) -> Balance {80		x * Self::factor()81	}82}8384/// Re-export a nft pallet85/// TODO: Check this re-export. Is this safe and good style?86extern crate pallet_nft;87pub use pallet_nft::*;8889/// An index to a block.90pub type BlockNumber = u32;9192/// Alias to 512-bit hash when used in the context of a transaction signature on the chain.93pub type Signature = MultiSignature;9495/// Some way of identifying an account on the chain. We intentionally make it equivalent96/// to the public key of our transaction signing scheme.97pub type AccountId = <<Signature as Verify>::Signer as IdentifyAccount>::AccountId;9899/// The type for looking up accounts. We don't expect more than 4 billion of them, but you100/// never know...101pub type AccountIndex = u32;102103/// Balance of an account.104pub type Balance = u128;105106/// Index of a transaction in the chain.107pub type Index = u32;108109/// A hash of some data used by the chain.110pub type Hash = sp_core::H256;111112/// Digest item type.113pub type DigestItem = generic::DigestItem<Hash>;114115mod nft_weights;116117/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know118/// the specifics of the runtime. They can then be made to be agnostic over specific formats119/// of data like extrinsics, allowing for them to continue syncing the network through upgrades120/// to even the core data structures.121pub mod opaque {122    use super::*;123124    pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;125126    /// Opaque block header type.127    pub type Header = generic::Header<BlockNumber, BlakeTwo256>;128    /// Opaque block type.129    pub type Block = generic::Block<Header, UncheckedExtrinsic>;130    /// Opaque block identifier type.131    pub type BlockId = generic::BlockId<Block>;132133    impl_opaque_keys! {134        pub struct SessionKeys {135            pub aura: Aura,136            pub grandpa: Grandpa,137        }138    }139}140141/// This runtime version.142pub const VERSION: RuntimeVersion = RuntimeVersion {143    spec_name: create_runtime_str!("nft"),144    impl_name: create_runtime_str!("nft"),145    authoring_version: 1,146    spec_version: 2,147    impl_version: 1,148    apis: RUNTIME_API_VERSIONS,149    transaction_version: 1,150};151152pub const MILLISECS_PER_BLOCK: u64 = 6000;153154pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK;155156// These time units are defined in number of blocks.157pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber);158pub const HOURS: BlockNumber = MINUTES * 60;159pub const DAYS: BlockNumber = HOURS * 24;160161/// The version information used to identify this runtime when compiled natively.162#[cfg(feature = "std")]163pub fn native_version() -> NativeVersion {164    NativeVersion {165        runtime_version: VERSION,166        can_author_with: Default::default(),167    }168}169170/// Provides a membership set with only the configured aura users171pub struct ValiudatorsOnly<Runtime: pallet_aura::Trait>(PhantomData<Runtime>);172impl frame_support::traits::Contains<AccountId> for ValiudatorsOnly<Runtime> {173	fn contains(t: &AccountId) -> bool {174        let arr: [u8; 32] = *t.as_ref();175        let raw_key: Vec<u8> = Vec::from(arr);176177        match pallet_aura::Module::<Runtime>::authorities().iter().find(|auth| auth.to_raw_vec() == raw_key) {178            Some(_) => true,179            None => false,180        }  181	}182	fn sorted_members() -> Vec<AccountId> {183        let mut members: Vec<AccountId> = Vec::new();184        for auth in pallet_aura::Module::<Runtime>::authorities() {185            let mut arr: [u8; 32] = Default::default(); 186            let bor_arr = auth.clone().to_raw_vec();187            let slice = bor_arr.as_slice();188            arr.copy_from_slice(slice);189            members.push(AccountId::from(arr));190        }191        members  192	}193	fn count() -> usize {194        pallet_aura::Module::<Runtime>::authorities().len()195	}196}197198impl frame_support::traits::ContainsLengthBound for ValiudatorsOnly<Runtime> {199	fn min_len() -> usize {200		1201	}202	fn max_len() -> usize {203		100204	}205}206207parameter_types! {208    pub const BlockHashCount: BlockNumber = 2400;209    /// We allow for 2 seconds of compute with a 6 second average block time.210    pub const MaximumBlockWeight: Weight = 2 * WEIGHT_PER_SECOND;211    pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);212    /// Assume 10% of weight for average on_initialize calls.213    pub MaximumExtrinsicWeight: Weight = AvailableBlockRatio::get()214        .saturating_sub(Perbill::from_percent(10)) * MaximumBlockWeight::get();215    pub const MaximumBlockLength: u32 = 5 * 1024 * 1024;216    pub const Version: RuntimeVersion = VERSION;217}218219impl system::Trait for Runtime {220    /// The basic call filter to use in dispatchable.221    type BaseCallFilter = ();222    /// The identifier used to distinguish between accounts.223    type AccountId = AccountId;224    /// The aggregated dispatch type that is available for extrinsics.225    type Call = Call;226    /// The lookup mechanism to get account ID from whatever is passed in dispatchers.227    type Lookup = IdentityLookup<AccountId>;228    /// The index type for storing how many extrinsics an account has signed.229    type Index = Index;230    /// The index type for blocks.231    type BlockNumber = BlockNumber;232    /// The type for hashing blocks and tries.233    type Hash = Hash;234    /// The hashing algorithm used.235    type Hashing = BlakeTwo256;236    /// The header type.237    type Header = generic::Header<BlockNumber, BlakeTwo256>;238    /// The ubiquitous event type.239    type Event = Event;240    /// The ubiquitous origin type.241    type Origin = Origin;242    /// Maximum number of block number to block hash mappings to keep (oldest pruned first).243    type BlockHashCount = BlockHashCount;244    /// Maximum weight of each block.245    type MaximumBlockWeight = MaximumBlockWeight;246    /// The weight of database operations that the runtime can invoke.247    type DbWeight = RocksDbWeight;248    /// The weight of the overhead invoked on the block import process, independent of the249    /// extrinsics included in that block.250    type BlockExecutionWeight = BlockExecutionWeight;251    /// The base weight of any extrinsic processed by the runtime, independent of the252    /// logic of that extrinsic. (Signature verification, nonce increment, fee, etc...)253    type ExtrinsicBaseWeight = ExtrinsicBaseWeight;254    /// The maximum weight that a single extrinsic of `Normal` dispatch class can have,255    /// idependent of the logic of that extrinsics. (Roughly max block weight - average on256    /// initialize cost).257    type MaximumExtrinsicWeight = MaximumExtrinsicWeight;258    /// Maximum size of all encoded transactions (in bytes) that are allowed in one block.259    type MaximumBlockLength = MaximumBlockLength;260    /// Portion of the block weight that is available to all normal transactions.261    type AvailableBlockRatio = AvailableBlockRatio;262    /// Version of the runtime.263    type Version = Version;264 	/// This type is being generated by `construct_runtime!`.265    type PalletInfo = PalletInfo;266    /// What to do if a new account is created.267    type OnNewAccount = ();268    /// What to do if an account is fully reaped from the system.269    type OnKilledAccount = ();270    /// The data to be stored in an account.271    type AccountData = pallet_balances::AccountData<Balance>;272	/// Weight information for the extrinsics of this pallet.273	type SystemWeightInfo = ();274}275276impl pallet_aura::Trait for Runtime {277    type AuthorityId = AuraId;278}279280impl pallet_grandpa::Trait for Runtime {281	type Event = Event;282	type Call = Call;283284	type KeyOwnerProofSystem = ();285286	type KeyOwnerProof =287		<Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, GrandpaId)>>::Proof;288289	type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(290		KeyTypeId,291		GrandpaId,292	)>>::IdentificationTuple;293294	type HandleEquivocation = ();295296	type WeightInfo = ();297}298299parameter_types! {300    pub const MinimumPeriod: u64 = SLOT_DURATION / 2;301}302303impl pallet_timestamp::Trait for Runtime {304	/// A timestamp: milliseconds since the unix epoch.305	type Moment = u64;306	type OnTimestampSet = Aura;307	type MinimumPeriod = MinimumPeriod;308	type WeightInfo = ();309}310311parameter_types! {312    // pub const ExistentialDeposit: u128 = 500;313    pub const ExistentialDeposit: u128 = 0;314	pub const MaxLocks: u32 = 50;315}316317impl pallet_balances::Trait for Runtime {318	type MaxLocks = MaxLocks;319	/// The type for recording an account's balance.320	type Balance = Balance;321	/// The ubiquitous event type.322	type Event = Event;323	type DustRemoval = Treasury;324	type ExistentialDeposit = ExistentialDeposit;325	type AccountStore = System;326	type WeightInfo = ();327}328329pub const MILLICENTS: Balance = 1_000_000_000;330pub const CENTS: Balance = 1_000 * MILLICENTS;331pub const DOLLARS: Balance = 100 * CENTS;332333parameter_types! {334    pub const TombstoneDeposit: Balance = 0;335    pub const RentByteFee: Balance = 4 * MILLICENTS;336    pub const RentDepositOffset: Balance = 1000 * MILLICENTS;337    pub const SurchargeReward: Balance = 150 * MILLICENTS;338}339340impl pallet_contracts::Trait for Runtime {341	type Time = Timestamp;342	type Randomness = RandomnessCollectiveFlip;343	type Currency = Balances;344	type Event = Event;345	type DetermineContractAddress = pallet_contracts::SimpleAddressDeterminer<Runtime>;346	type TrieIdGenerator = pallet_contracts::TrieIdFromParentCounter<Runtime>;347	type RentPayment = ();348	type SignedClaimHandicap = pallet_contracts::DefaultSignedClaimHandicap;349	type TombstoneDeposit = TombstoneDeposit;350	type StorageSizeOffset = pallet_contracts::DefaultStorageSizeOffset;351	type RentByteFee = RentByteFee;352	type RentDepositOffset = RentDepositOffset;353	type SurchargeReward = SurchargeReward;354	type MaxDepth = pallet_contracts::DefaultMaxDepth;355	type MaxValueSize = pallet_contracts::DefaultMaxValueSize;356	type WeightPrice = pallet_transaction_payment::Module<Self>;357}358359parameter_types! {360	pub const TransactionByteFee: Balance = 10 * MILLICENTS;361}362363impl pallet_transaction_payment::Trait for Runtime {364    type Currency = pallet_balances::Module<Runtime>;365    type OnTransactionPayment = Treasury;366    type TransactionByteFee = TransactionByteFee;367    type WeightToFee = IdentityFee<Balance>;368    type FeeMultiplierUpdate =  ();369}370371parameter_types! {372	pub const ProposalBond: Permill = Permill::from_percent(5);373	pub const ProposalBondMinimum: Balance = 1 * DOLLARS;374	pub const SpendPeriod: BlockNumber = 5 * MINUTES;375	pub const Burn: Permill = Permill::from_percent(0);376	pub const TipCountdown: BlockNumber = 1 * DAYS;377	pub const TipFindersFee: Percent = Percent::from_percent(20);378	pub const TipReportDepositBase: Balance = 1 * DOLLARS;379	pub const DataDepositPerByte: Balance = 1 * CENTS;380	pub const BountyDepositBase: Balance = 1 * DOLLARS;381	pub const BountyDepositPayoutDelay: BlockNumber = 1 * DAYS;382	pub const TreasuryModuleId: ModuleId = ModuleId(*b"py/trsry");383	pub const BountyUpdatePeriod: BlockNumber = 14 * DAYS;384	pub const MaximumReasonLength: u32 = 16384;385	pub const BountyCuratorDeposit: Permill = Permill::from_percent(50);386	pub const BountyValueMinimum: Balance = 5 * DOLLARS;387}388389impl pallet_treasury::Trait for Runtime {390	type ModuleId = TreasuryModuleId;391	type Currency = Balances;392    type ApproveOrigin = EnsureRoot<AccountId>;393	type RejectOrigin = EnsureRoot<AccountId>;394	type Tippers = ValiudatorsOnly<Self>;395	type TipCountdown = TipCountdown;396	type TipFindersFee = TipFindersFee;397	type TipReportDepositBase = TipReportDepositBase;398	type DataDepositPerByte = DataDepositPerByte;399	type Event = Event;400	type OnSlash = ();401	type ProposalBond = ProposalBond;402	type ProposalBondMinimum = ProposalBondMinimum;403	type SpendPeriod = SpendPeriod;404	type Burn = Burn;405	type BountyDepositBase = BountyDepositBase;406	type BountyDepositPayoutDelay = BountyDepositPayoutDelay;407	type BountyUpdatePeriod = BountyUpdatePeriod;408	type BountyCuratorDeposit = BountyCuratorDeposit;409	type BountyValueMinimum = BountyValueMinimum;410	type MaximumReasonLength = MaximumReasonLength;411	type BurnDestination = ();412	type WeightInfo = ();413}414415impl pallet_sudo::Trait for Runtime {416    type Event = Event;417    type Call = Call;418}419420parameter_types! {421	pub const MinVestedTransfer: Balance = 100 * DOLLARS;422}423424impl pallet_vesting::Trait for Runtime {425	type Event = Event;426	type Currency = Balances;427	type BlockNumberToBalance = ConvertInto;428	type MinVestedTransfer = MinVestedTransfer;429	type WeightInfo = ();430}431432/// Used for the module nft in `./nft.rs`433impl pallet_nft::Trait for Runtime {434    type Event = Event;435    type WeightInfo = nft_weights::WeightInfo;436}437438construct_runtime!(439    pub enum Runtime where440        Block = Block,441        NodeBlock = opaque::Block,442        UncheckedExtrinsic = UncheckedExtrinsic443    {444        System: system::{Module, Call, Config, Storage, Event<T>},445        RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Module, Call, Storage},446        Contracts: pallet_contracts::{Module, Call, Config, Storage, Event<T>},447        Timestamp: pallet_timestamp::{Module, Call, Storage, Inherent},448        Aura: pallet_aura::{Module, Config<T>, Inherent},449        Grandpa: pallet_grandpa::{Module, Call, Storage, Config, Event},450        Balances: pallet_balances::{Module, Call, Storage, Config<T>, Event<T>},451        TransactionPayment: pallet_transaction_payment::{Module, Storage},452        Sudo: pallet_sudo::{Module, Call, Config<T>, Storage, Event<T>},453        Nft: pallet_nft::{Module, Call, Config<T>, Storage, Event<T>},454        Treasury: pallet_treasury::{Module, Call, Storage, Config, Event<T>},455        Vesting: pallet_vesting::{Module, Call, Config<T>, Storage, Event<T>},456    }457);458459/// The address format for describing accounts.460pub type Address = AccountId;461/// Block header type as expected by this runtime.462pub type Header = generic::Header<BlockNumber, BlakeTwo256>;463/// Block type as expected by this runtime.464pub type Block = generic::Block<Header, UncheckedExtrinsic>;465/// A Block signed with a Justification466pub type SignedBlock = generic::SignedBlock<Block>;467/// BlockId type as expected by this runtime.468pub type BlockId = generic::BlockId<Block>;469/// The SignedExtension to the basic transaction logic.470pub type SignedExtra = (471    system::CheckSpecVersion<Runtime>,472    system::CheckTxVersion<Runtime>,473    system::CheckGenesis<Runtime>,474    system::CheckEra<Runtime>,475    system::CheckNonce<Runtime>,476    system::CheckWeight<Runtime>,477    pallet_nft::ChargeTransactionPayment<Runtime>,478);479/// Unchecked extrinsic type as expected by this runtime.480pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;481/// Extrinsic type that has already been checked.482pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, Call, SignedExtra>;483/// Executive: handles dispatch to the various modules.484pub type Executive =485    frame_executive::Executive<Runtime, Block, system::ChainContext<Runtime>, Runtime, AllModules>;486487impl_runtime_apis! {488489    impl pallet_contracts_rpc_runtime_api::ContractsApi<Block, AccountId, Balance, BlockNumber>490    for Runtime491    {492        fn call(493            origin: AccountId,494            dest: AccountId,495            value: Balance,496            gas_limit: u64,497            input_data: Vec<u8>,498        ) -> ContractExecResult {499			let (exec_result, gas_consumed) =500				Contracts::bare_call(origin, dest.into(), value, gas_limit, input_data);501			match exec_result {502				Ok(v) => ContractExecResult::Success {503					flags: v.flags.bits(),504					data: v.data,505					gas_consumed: gas_consumed,506				},507				Err(_) => ContractExecResult::Error,508			}509        }510511        fn get_storage(512            address: AccountId,513            key: [u8; 32],514        ) -> pallet_contracts_primitives::GetStorageResult {515            Contracts::get_storage(address, key)516        }517518        fn rent_projection(519            address: AccountId,520        ) -> pallet_contracts_primitives::RentProjectionResult<BlockNumber> {521            Contracts::rent_projection(address)522        }523    }524525    impl sp_api::Core<Block> for Runtime {526        fn version() -> RuntimeVersion {527            VERSION528        }529530        fn execute_block(block: Block) {531            Executive::execute_block(block)532        }533534        fn initialize_block(header: &<Block as BlockT>::Header) {535            Executive::initialize_block(header)536        }537    }538539    impl sp_api::Metadata<Block> for Runtime {540        fn metadata() -> OpaqueMetadata {541            Runtime::metadata().into()542        }543    }544545    impl sp_block_builder::BlockBuilder<Block> for Runtime {546        fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {547            Executive::apply_extrinsic(extrinsic)548        }549550        fn finalize_block() -> <Block as BlockT>::Header {551            Executive::finalize_block()552        }553554        fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {555            data.create_extrinsics()556        }557558        fn check_inherents(559            block: Block,560            data: sp_inherents::InherentData,561        ) -> sp_inherents::CheckInherentsResult {562            data.check_extrinsics(&block)563        }564565        fn random_seed() -> <Block as BlockT>::Hash {566            RandomnessCollectiveFlip::random_seed()567        }568    }569570    impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {571        fn validate_transaction(572            source: TransactionSource,573            tx: <Block as BlockT>::Extrinsic,574        ) -> TransactionValidity {575            Executive::validate_transaction(source, tx)576        }577    }578579    impl sp_offchain::OffchainWorkerApi<Block> for Runtime {580        fn offchain_worker(header: &<Block as BlockT>::Header) {581            Executive::offchain_worker(header)582        }583    }584585    impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime {586        fn slot_duration() -> u64 {587            Aura::slot_duration()588        }589590        fn authorities() -> Vec<AuraId> {591            Aura::authorities()592        }593    }594595    impl sp_session::SessionKeys<Block> for Runtime {596        fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {597            opaque::SessionKeys::generate(seed)598        }599600        fn decode_session_keys(601            encoded: Vec<u8>,602        ) -> Option<Vec<(Vec<u8>, KeyTypeId)>> {603            opaque::SessionKeys::decode_into_raw_public_keys(&encoded)604        }605    }606607	impl fg_primitives::GrandpaApi<Block> for Runtime {608		fn grandpa_authorities() -> GrandpaAuthorityList {609			Grandpa::grandpa_authorities()610		}611612		fn submit_report_equivocation_unsigned_extrinsic(613			_equivocation_proof: fg_primitives::EquivocationProof<614				<Block as BlockT>::Hash,615				NumberFor<Block>,616			>,617			_key_owner_proof: fg_primitives::OpaqueKeyOwnershipProof,618		) -> Option<()> {619			None620		}621622		fn generate_key_ownership_proof(623			_set_id: fg_primitives::SetId,624			_authority_id: GrandpaId,625		) -> Option<fg_primitives::OpaqueKeyOwnershipProof> {626			// NOTE: this is the only implementation possible since we've627			// defined our key owner proof type as a bottom type (i.e. a type628			// with no values).629			None630		}631    }632    633	impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Index> for Runtime {634		fn account_nonce(account: AccountId) -> Index {635			System::account_nonce(account)636		}637	}638639	impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime {640		fn query_info(641			uxt: <Block as BlockT>::Extrinsic,642			len: u32,643		) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo<Balance> {644			TransactionPayment::query_info(uxt, len)645		}646	}647648    #[cfg(feature = "runtime-benchmarks")]649	impl frame_benchmarking::Benchmark<Block> for Runtime {650		fn dispatch_benchmark(651			config: frame_benchmarking::BenchmarkConfig652		) -> Result<Vec<frame_benchmarking::BenchmarkBatch>, sp_runtime::RuntimeString> {653			use frame_benchmarking::{Benchmarking, BenchmarkBatch, add_benchmark, TrackedStorageKey};654655			let whitelist: Vec<TrackedStorageKey> = vec![656				// Alice account657				hex_literal::hex!("d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d").to_vec().into(),658				// // Total Issuance659				// hex_literal::hex!("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80").to_vec().into(),660				// // Execution Phase661				// hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a").to_vec().into(),662				// // Event Count663				// hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850").to_vec().into(),664				// // System Events665				// hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7").to_vec().into(),666            ];667668			let mut batches = Vec::<BenchmarkBatch>::new();669			let params = (&config, &whitelist);670671			add_benchmark!(params, batches, pallet_nft, Nft);672673			if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) }674			Ok(batches)675		}676	}677}