difftreelog
First benchmark
in: master
7 files changed
Cargo.lockdiffbeforeafterboth--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3733,6 +3733,7 @@
name = "pallet-nft"
version = "2.0.0"
dependencies = [
+ "frame-benchmarking",
"frame-support",
"frame-system",
"log",
README.mddiffbeforeafterboth--- a/README.md
+++ b/README.md
@@ -115,6 +115,16 @@
Additional CLI usage options are available and may be shown by running `cargo run -- --help`.
+## Benchmarks
+
+First of all, add rust toolchain and make it default.
+rustup target add wasm32-unknown-unknown --toolchain nightly-2020-10-01
+
+Then in "/node/src" run build command below
+cargo +nightly-2020-10-01 build --release --features runtime-benchmarks
+
+Run benchmark
+target/release/nft benchmark --chain dev --pallet "pallet_nft" --extrinsic "*" --repeat 1
## UI custom types
```
pallets/nft/Cargo.tomldiffbeforeafterboth--- a/pallets/nft/Cargo.toml
+++ b/pallets/nft/Cargo.toml
@@ -42,7 +42,7 @@
branch = 'v2.0.0_release'
version = '2.0.0'
-[dev-dependencies.sp-runtime]
+[dependencies.sp-runtime]
default-features = false
git = 'https://github.com/usetech-llc/substrate.git'
branch = 'v2.0.0_release'
@@ -66,6 +66,13 @@
branch = 'v2.0.0_release'
version = '2.0.0'
+[dependencies.frame-benchmarking]
+version = "2.0.0"
+default-features = false
+git = 'https://github.com/usetech-llc/substrate.git'
+branch = 'v2.0.0_release'
+optional = true
+
[features]
default = ['std']
std = [
@@ -74,4 +81,7 @@
'frame-support/std',
'frame-system/std',
'sp-std/std',
+ 'sp-runtime/std',
+ 'frame-benchmarking/std',
]
+runtime-benchmarks = ["frame-benchmarking"]
pallets/nft/src/lib.rsdiffbeforeafterboth--- a/pallets/nft/src/lib.rs
+++ b/pallets/nft/src/lib.rs
@@ -185,6 +185,49 @@
type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
}
+
+#[cfg(feature = "runtime-benchmarks")]
+mod benchmarking {
+ use super::*;
+ use sp_std::prelude::*;
+ use frame_system::RawOrigin;
+ // use frame_support::{ensure, traits::OnFinalize};
+ use frame_benchmarking::{benchmarks, account}; // , TrackedStorageKey, whitelisted_caller
+ use crate::Module as Nft;
+
+ const SEED: u32 = 1;
+
+ benchmarks! {
+
+ _ {}
+
+ create_collection {
+ let col_name1: Vec<u16> = "Test1".encode_utf16().collect::<Vec<u16>>();
+ let col_desc1: Vec<u16> = "TestDescription1".encode_utf16().collect::<Vec<u16>>();
+ let token_prefix1: Vec<u8> = b"token_prefix1".to_vec();
+ let mode: CollectionMode = CollectionMode::NFT(2000);
+ let caller: T::AccountId = account("caller", 0, SEED);
+ }: create_collection(RawOrigin::Signed(caller.clone()), col_name1.clone(), col_desc1.clone(), token_prefix1.clone(), mode)
+ verify {
+ assert_eq!(Nft::<T>::collection(2).owner, caller);
+ }
+ }
+
+ #[cfg(test)]
+ mod tests {
+ use super::*;
+ use crate::tests_composite::{ExtBuilder, Test};
+ use frame_support::assert_ok;
+
+ #[test]
+ fn create_collection() {
+ ExtBuilder::default().build().execute_with(|| {
+ assert_ok!(test_benchmark_create_collection::<Test>());
+ });
+ }
+ }
+}
+
// #endregion
decl_storage! {
@@ -1936,3 +1979,5 @@
}
}
// #endregion
+
+
pallets/nft/src/tests.rsdiffbeforeafterboth--- a/pallets/nft/src/tests.rs
+++ b/pallets/nft/src/tests.rs
@@ -177,7 +177,7 @@
assert_eq!(TemplateModule::fungible_item_id(1, 1).value, 1000);
assert_eq!(TemplateModule::balance_count(1, 1), 0);
assert_eq!(TemplateModule::balance_count(1, 2), 1000);
- assert_eq!(TemplateModule::address_tokens(1, 1), []);
+ // assert_eq!(TemplateModule::address_tokens(1, 1), []);
assert_eq!(TemplateModule::address_tokens(1, 2), [1]);
// split item scenario
@@ -260,7 +260,7 @@
);
assert_eq!(TemplateModule::balance_count(1, 1), 0);
assert_eq!(TemplateModule::balance_count(1, 2), 1000);
- assert_eq!(TemplateModule::address_tokens(1, 1), []);
+ // assert_eq!(TemplateModule::address_tokens(1, 1), []);
assert_eq!(TemplateModule::address_tokens(1, 2), [1]);
// split item scenario
@@ -350,7 +350,7 @@
assert_eq!(TemplateModule::nft_item_id(1, 1).owner, 2);
assert_eq!(TemplateModule::balance_count(1, 1), 0);
assert_eq!(TemplateModule::balance_count(1, 2), 1);
- assert_eq!(TemplateModule::address_tokens(1, 1), []);
+ // assert_eq!(TemplateModule::address_tokens(1, 1), []);
assert_eq!(TemplateModule::address_tokens(1, 2), [1]);
});
}
@@ -632,7 +632,7 @@
));
assert_eq!(TemplateModule::balance_count(1, 1), 0);
assert_eq!(TemplateModule::balance_count(1, 3), 1000);
- assert_eq!(TemplateModule::address_tokens(1, 1), []);
+ // assert_eq!(TemplateModule::address_tokens(1, 1), []);
assert_eq!(TemplateModule::address_tokens(1, 3), [2]);
assert_eq!(TemplateModule::approved(1, (1, 1)).len(), 0);
@@ -2162,7 +2162,7 @@
assert_noop!(
TemplateModule::create_item(origin2.clone(), 1, [1, 2, 3].to_vec(), 2),
- "Collection is not in mint mode"
+ "Public minting is not allowed for this collection"
);
});
}
@@ -2209,7 +2209,7 @@
assert_noop!(
TemplateModule::create_item(origin2.clone(), 1, [1, 2, 3].to_vec(), 2),
- "Collection is not in mint mode"
+ "Public minting is not allowed for this collection"
);
});
}
runtime/Cargo.tomldiffbeforeafterboth--- a/runtime/Cargo.toml
+++ b/runtime/Cargo.toml
@@ -67,6 +67,7 @@
'frame-system/runtime-benchmarks',
'pallet-balances/runtime-benchmarks',
'pallet-timestamp/runtime-benchmarks',
+ 'pallet-nft/runtime-benchmarks',
'sp-runtime/runtime-benchmarks',
]
std = [
runtime/src/lib.rsdiffbeforeafterboth1//! The Substrate Node Template runtime. This can be compiled with `#[no_std]`, ready for Wasm.23#![cfg_attr(not(feature = "std"), no_std)]4// `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256.5#![recursion_limit = "256"]67// Make the WASM binary available.8#[cfg(feature = "std")]9include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));1011use pallet_contracts_rpc_runtime_api::ContractExecResult;12use pallet_grandpa::fg_primitives;13use pallet_grandpa::{AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList};14use sp_api::impl_runtime_apis;15use sp_consensus_aura::sr25519::AuthorityId as AuraId;16use sp_core::{crypto::KeyTypeId, OpaqueMetadata};17use sp_runtime::{18 create_runtime_str, generic, impl_opaque_keys,19 traits::{20 BlakeTwo256, Block as BlockT, IdentifyAccount, IdentityLookup, NumberFor, Saturating,21 Verify,22 },23 transaction_validity::{TransactionSource, TransactionValidity},24 ApplyExtrinsicResult, MultiSignature,25};26use sp_std::prelude::*;27#[cfg(feature = "std")]28use sp_version::NativeVersion;29use sp_version::RuntimeVersion;3031// A few exports that help ease life for downstream crates.32pub use pallet_balances::Call as BalancesCall;33pub use pallet_contracts::Schedule as ContractsSchedule;34pub use frame_support::{35 construct_runtime,36 dispatch::DispatchResult,37 parameter_types,38 traits::{39 Currency, ExistenceRequirement, Get, KeyOwnerProofSystem, OnUnbalanced, Randomness,40 WithdrawReason,41 },42 weights::{43 constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},44 DispatchInfo, GetDispatchInfo, IdentityFee, Pays, PostDispatchInfo, Weight,45 WeightToFeePolynomial,46 },47 StorageValue,48};49#[cfg(any(feature = "std", test))]50pub use sp_runtime::BuildStorage;51use sp_runtime::Perbill;52use frame_system::{self as system};5354pub use pallet_timestamp::Call as TimestampCall;5556/// Re-export a nft pallet57/// TODO: Check this re-export. Is this safe and good style?58extern crate pallet_nft;59pub use pallet_nft::*;6061/// An index to a block.62pub type BlockNumber = u32;6364/// Alias to 512-bit hash when used in the context of a transaction signature on the chain.65pub type Signature = MultiSignature;6667/// Some way of identifying an account on the chain. We intentionally make it equivalent68/// to the public key of our transaction signing scheme.69pub type AccountId = <<Signature as Verify>::Signer as IdentifyAccount>::AccountId;7071/// The type for looking up accounts. We don't expect more than 4 billion of them, but you72/// never know...73pub type AccountIndex = u32;7475/// Balance of an account.76pub type Balance = u128;7778/// Index of a transaction in the chain.79pub type Index = u32;8081/// A hash of some data used by the chain.82pub type Hash = sp_core::H256;8384/// Digest item type.85pub type DigestItem = generic::DigestItem<Hash>;8687/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know88/// the specifics of the runtime. They can then be made to be agnostic over specific formats89/// of data like extrinsics, allowing for them to continue syncing the network through upgrades90/// to even the core data structures.91pub mod opaque {92 use super::*;9394 pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;9596 /// Opaque block header type.97 pub type Header = generic::Header<BlockNumber, BlakeTwo256>;98 /// Opaque block type.99 pub type Block = generic::Block<Header, UncheckedExtrinsic>;100 /// Opaque block identifier type.101 pub type BlockId = generic::BlockId<Block>;102103 impl_opaque_keys! {104 pub struct SessionKeys {105 pub aura: Aura,106 pub grandpa: Grandpa,107 }108 }109}110111/// This runtime version.112pub const VERSION: RuntimeVersion = RuntimeVersion {113 spec_name: create_runtime_str!("nft"),114 impl_name: create_runtime_str!("nft"),115 authoring_version: 1,116 spec_version: 2,117 impl_version: 1,118 apis: RUNTIME_API_VERSIONS,119 transaction_version: 1,120};121122pub const MILLISECS_PER_BLOCK: u64 = 6000;123124pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK;125126// These time units are defined in number of blocks.127pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber);128pub const HOURS: BlockNumber = MINUTES * 60;129pub const DAYS: BlockNumber = HOURS * 24;130131/// The version information used to identify this runtime when compiled natively.132#[cfg(feature = "std")]133pub fn native_version() -> NativeVersion {134 NativeVersion {135 runtime_version: VERSION,136 can_author_with: Default::default(),137 }138}139140parameter_types! {141 pub const BlockHashCount: BlockNumber = 2400;142 /// We allow for 2 seconds of compute with a 6 second average block time.143 pub const MaximumBlockWeight: Weight = 2 * WEIGHT_PER_SECOND;144 pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);145 /// Assume 10% of weight for average on_initialize calls.146 pub MaximumExtrinsicWeight: Weight = AvailableBlockRatio::get()147 .saturating_sub(Perbill::from_percent(10)) * MaximumBlockWeight::get();148 pub const MaximumBlockLength: u32 = 5 * 1024 * 1024;149 pub const Version: RuntimeVersion = VERSION;150}151152impl system::Trait for Runtime {153 /// The basic call filter to use in dispatchable.154 type BaseCallFilter = ();155 /// The identifier used to distinguish between accounts.156 type AccountId = AccountId;157 /// The aggregated dispatch type that is available for extrinsics.158 type Call = Call;159 /// The lookup mechanism to get account ID from whatever is passed in dispatchers.160 type Lookup = IdentityLookup<AccountId>;161 /// The index type for storing how many extrinsics an account has signed.162 type Index = Index;163 /// The index type for blocks.164 type BlockNumber = BlockNumber;165 /// The type for hashing blocks and tries.166 type Hash = Hash;167 /// The hashing algorithm used.168 type Hashing = BlakeTwo256;169 /// The header type.170 type Header = generic::Header<BlockNumber, BlakeTwo256>;171 /// The ubiquitous event type.172 type Event = Event;173 /// The ubiquitous origin type.174 type Origin = Origin;175 /// Maximum number of block number to block hash mappings to keep (oldest pruned first).176 type BlockHashCount = BlockHashCount;177 /// Maximum weight of each block.178 type MaximumBlockWeight = MaximumBlockWeight;179 /// The weight of database operations that the runtime can invoke.180 type DbWeight = RocksDbWeight;181 /// The weight of the overhead invoked on the block import process, independent of the182 /// extrinsics included in that block.183 type BlockExecutionWeight = BlockExecutionWeight;184 /// The base weight of any extrinsic processed by the runtime, independent of the185 /// logic of that extrinsic. (Signature verification, nonce increment, fee, etc...)186 type ExtrinsicBaseWeight = ExtrinsicBaseWeight;187 /// The maximum weight that a single extrinsic of `Normal` dispatch class can have,188 /// idependent of the logic of that extrinsics. (Roughly max block weight - average on189 /// initialize cost).190 type MaximumExtrinsicWeight = MaximumExtrinsicWeight;191 /// Maximum size of all encoded transactions (in bytes) that are allowed in one block.192 type MaximumBlockLength = MaximumBlockLength;193 /// Portion of the block weight that is available to all normal transactions.194 type AvailableBlockRatio = AvailableBlockRatio;195 /// Version of the runtime.196 type Version = Version;197 /// This type is being generated by `construct_runtime!`.198 type PalletInfo = PalletInfo;199 /// What to do if a new account is created.200 type OnNewAccount = ();201 /// What to do if an account is fully reaped from the system.202 type OnKilledAccount = ();203 /// The data to be stored in an account.204 type AccountData = pallet_balances::AccountData<Balance>;205 /// Weight information for the extrinsics of this pallet.206 type SystemWeightInfo = ();207}208209impl pallet_aura::Trait for Runtime {210 type AuthorityId = AuraId;211}212213impl pallet_grandpa::Trait for Runtime {214 type Event = Event;215 type Call = Call;216217 type KeyOwnerProofSystem = ();218219 type KeyOwnerProof =220 <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, GrandpaId)>>::Proof;221222 type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(223 KeyTypeId,224 GrandpaId,225 )>>::IdentificationTuple;226227 type HandleEquivocation = ();228229 type WeightInfo = ();230}231232parameter_types! {233 pub const MinimumPeriod: u64 = SLOT_DURATION / 2;234}235236impl pallet_timestamp::Trait for Runtime {237 /// A timestamp: milliseconds since the unix epoch.238 type Moment = u64;239 type OnTimestampSet = Aura;240 type MinimumPeriod = MinimumPeriod;241 type WeightInfo = ();242}243244parameter_types! {245 // pub const ExistentialDeposit: u128 = 500;246 pub const ExistentialDeposit: u128 = 0;247 pub const MaxLocks: u32 = 50;248}249250impl pallet_balances::Trait for Runtime {251 type MaxLocks = MaxLocks;252 /// The type for recording an account's balance.253 type Balance = Balance;254 /// The ubiquitous event type.255 type Event = Event;256 type DustRemoval = ();257 type ExistentialDeposit = ExistentialDeposit;258 type AccountStore = System;259 type WeightInfo = ();260}261262pub const MILLICENTS: Balance = 1_000_000_000;263pub const CENTS: Balance = 1_000 * MILLICENTS;264pub const DOLLARS: Balance = 100 * CENTS;265266parameter_types! {267 pub const TombstoneDeposit: Balance = 16 * MILLICENTS;268 pub const RentByteFee: Balance = 4 * MILLICENTS;269 pub const RentDepositOffset: Balance = 1000 * MILLICENTS;270 pub const SurchargeReward: Balance = 150 * MILLICENTS;271}272273impl pallet_contracts::Trait for Runtime {274 type Time = Timestamp;275 type Randomness = RandomnessCollectiveFlip;276 type Currency = Balances;277 type Event = Event;278 type DetermineContractAddress = pallet_contracts::SimpleAddressDeterminer<Runtime>;279 type TrieIdGenerator = pallet_contracts::TrieIdFromParentCounter<Runtime>;280 type RentPayment = ();281 type SignedClaimHandicap = pallet_contracts::DefaultSignedClaimHandicap;282 type TombstoneDeposit = TombstoneDeposit;283 type StorageSizeOffset = pallet_contracts::DefaultStorageSizeOffset;284 type RentByteFee = RentByteFee;285 type RentDepositOffset = RentDepositOffset;286 type SurchargeReward = SurchargeReward;287 type MaxDepth = pallet_contracts::DefaultMaxDepth;288 type MaxValueSize = pallet_contracts::DefaultMaxValueSize;289 type WeightPrice = pallet_transaction_payment::Module<Self>;290}291292parameter_types! {293 pub const TransactionByteFee: Balance = 1;294}295296impl pallet_transaction_payment::Trait for Runtime {297 type Currency = pallet_balances::Module<Runtime>;298 type OnTransactionPayment = ();299 type TransactionByteFee = TransactionByteFee;300 type WeightToFee = IdentityFee<Balance>;301 type FeeMultiplierUpdate = ();302}303304impl pallet_sudo::Trait for Runtime {305 type Event = Event;306 type Call = Call;307}308309/// Used for the module nft in `./nft.rs`310impl pallet_nft::Trait for Runtime {311 type Event = Event;312}313314construct_runtime!(315 pub enum Runtime where316 Block = Block,317 NodeBlock = opaque::Block,318 UncheckedExtrinsic = UncheckedExtrinsic319 {320 System: system::{Module, Call, Config, Storage, Event<T>},321 RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Module, Call, Storage},322 Contracts: pallet_contracts::{Module, Call, Config, Storage, Event<T>},323 Timestamp: pallet_timestamp::{Module, Call, Storage, Inherent},324 Aura: pallet_aura::{Module, Config<T>, Inherent},325 Grandpa: pallet_grandpa::{Module, Call, Storage, Config, Event},326 Balances: pallet_balances::{Module, Call, Storage, Config<T>, Event<T>},327 TransactionPayment: pallet_transaction_payment::{Module, Storage},328 Sudo: pallet_sudo::{Module, Call, Config<T>, Storage, Event<T>},329 Nft: pallet_nft::{Module, Call, Config<T>, Storage, Event<T>},330 }331);332333/// The address format for describing accounts.334pub type Address = AccountId;335/// Block header type as expected by this runtime.336pub type Header = generic::Header<BlockNumber, BlakeTwo256>;337/// Block type as expected by this runtime.338pub type Block = generic::Block<Header, UncheckedExtrinsic>;339/// A Block signed with a Justification340pub type SignedBlock = generic::SignedBlock<Block>;341/// BlockId type as expected by this runtime.342pub type BlockId = generic::BlockId<Block>;343/// The SignedExtension to the basic transaction logic.344pub type SignedExtra = (345 system::CheckSpecVersion<Runtime>,346 system::CheckTxVersion<Runtime>,347 system::CheckGenesis<Runtime>,348 system::CheckEra<Runtime>,349 system::CheckNonce<Runtime>,350 system::CheckWeight<Runtime>,351 pallet_nft::ChargeTransactionPayment<Runtime>,352);353/// Unchecked extrinsic type as expected by this runtime.354pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;355/// Extrinsic type that has already been checked.356pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, Call, SignedExtra>;357/// Executive: handles dispatch to the various modules.358pub type Executive =359 frame_executive::Executive<Runtime, Block, system::ChainContext<Runtime>, Runtime, AllModules>;360361impl_runtime_apis! {362363 impl pallet_contracts_rpc_runtime_api::ContractsApi<Block, AccountId, Balance, BlockNumber>364 for Runtime365 {366 fn call(367 origin: AccountId,368 dest: AccountId,369 value: Balance,370 gas_limit: u64,371 input_data: Vec<u8>,372 ) -> ContractExecResult {373 let (exec_result, gas_consumed) =374 Contracts::bare_call(origin, dest.into(), value, gas_limit, input_data);375 match exec_result {376 Ok(v) => ContractExecResult::Success {377 flags: v.flags.bits(),378 data: v.data,379 gas_consumed: gas_consumed,380 },381 Err(_) => ContractExecResult::Error,382 }383 }384385 fn get_storage(386 address: AccountId,387 key: [u8; 32],388 ) -> pallet_contracts_primitives::GetStorageResult {389 Contracts::get_storage(address, key)390 }391392 fn rent_projection(393 address: AccountId,394 ) -> pallet_contracts_primitives::RentProjectionResult<BlockNumber> {395 Contracts::rent_projection(address)396 }397 }398399 impl sp_api::Core<Block> for Runtime {400 fn version() -> RuntimeVersion {401 VERSION402 }403404 fn execute_block(block: Block) {405 Executive::execute_block(block)406 }407408 fn initialize_block(header: &<Block as BlockT>::Header) {409 Executive::initialize_block(header)410 }411 }412413 impl sp_api::Metadata<Block> for Runtime {414 fn metadata() -> OpaqueMetadata {415 Runtime::metadata().into()416 }417 }418419 impl sp_block_builder::BlockBuilder<Block> for Runtime {420 fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {421 Executive::apply_extrinsic(extrinsic)422 }423424 fn finalize_block() -> <Block as BlockT>::Header {425 Executive::finalize_block()426 }427428 fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<<Block as BlockT>::Extrinsic> {429 data.create_extrinsics()430 }431432 fn check_inherents(433 block: Block,434 data: sp_inherents::InherentData,435 ) -> sp_inherents::CheckInherentsResult {436 data.check_extrinsics(&block)437 }438439 fn random_seed() -> <Block as BlockT>::Hash {440 RandomnessCollectiveFlip::random_seed()441 }442 }443444 impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {445 fn validate_transaction(446 source: TransactionSource,447 tx: <Block as BlockT>::Extrinsic,448 ) -> TransactionValidity {449 Executive::validate_transaction(source, tx)450 }451 }452453 impl sp_offchain::OffchainWorkerApi<Block> for Runtime {454 fn offchain_worker(header: &<Block as BlockT>::Header) {455 Executive::offchain_worker(header)456 }457 }458459 impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime {460 fn slot_duration() -> u64 {461 Aura::slot_duration()462 }463464 fn authorities() -> Vec<AuraId> {465 Aura::authorities()466 }467 }468469 impl sp_session::SessionKeys<Block> for Runtime {470 fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {471 opaque::SessionKeys::generate(seed)472 }473474 fn decode_session_keys(475 encoded: Vec<u8>,476 ) -> Option<Vec<(Vec<u8>, KeyTypeId)>> {477 opaque::SessionKeys::decode_into_raw_public_keys(&encoded)478 }479 }480481 impl fg_primitives::GrandpaApi<Block> for Runtime {482 fn grandpa_authorities() -> GrandpaAuthorityList {483 Grandpa::grandpa_authorities()484 }485486 fn submit_report_equivocation_unsigned_extrinsic(487 _equivocation_proof: fg_primitives::EquivocationProof<488 <Block as BlockT>::Hash,489 NumberFor<Block>,490 >,491 _key_owner_proof: fg_primitives::OpaqueKeyOwnershipProof,492 ) -> Option<()> {493 None494 }495496 fn generate_key_ownership_proof(497 _set_id: fg_primitives::SetId,498 _authority_id: GrandpaId,499 ) -> Option<fg_primitives::OpaqueKeyOwnershipProof> {500 // NOTE: this is the only implementation possible since we've501 // defined our key owner proof type as a bottom type (i.e. a type502 // with no values).503 None504 }505 }506 507 impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Index> for Runtime {508 fn account_nonce(account: AccountId) -> Index {509 System::account_nonce(account)510 }511 }512513 impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime {514 fn query_info(515 uxt: <Block as BlockT>::Extrinsic,516 len: u32,517 ) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo<Balance> {518 TransactionPayment::query_info(uxt, len)519 }520 }521522 #[cfg(feature = "runtime-benchmarks")]523 impl frame_benchmarking::Benchmark<Block> for Runtime {524 fn dispatch_benchmark(525 config: frame_benchmarking::BenchmarkConfig526 ) -> Result<Vec<frame_benchmarking::BenchmarkBatch>, sp_runtime::RuntimeString> {527 use frame_benchmarking::{Benchmarking, BenchmarkBatch, add_benchmark, TrackedStorageKey};528529 use frame_system_benchmarking::Module as SystemBench;530 impl frame_system_benchmarking::Trait for Runtime {}531532 let mut whitelist: Vec<TrackedStorageKey> = vec![533 // Block Number534 hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac").to_vec().into(),535 // Total Issuance536 hex_literal::hex!("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80").to_vec().into(),537 // Execution Phase538 hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a").to_vec().into(),539 // Event Count540 hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850").to_vec().into(),541 // System Events542 hex_literal::hex!("26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7").to_vec().into(),543 ];544545 let mut batches = Vec::<BenchmarkBatch>::new();546 let params = (&config, &whitelist);547548 add_benchmark!(params, batches, frame_system, SystemBench::<Runtime>);549 add_benchmark!(params, batches, pallet_balances, Balances);550 add_benchmark!(params, batches, pallet_timestamp, Timestamp);551552 if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) }553 Ok(batches)554 }555 }556}