Benchmark Im Online Pallet (#5318)

* Initial benchmarking setup

* Add keystore

* validate unsigned

* Update frame/im-online/src/benchmarking.rs

Co-Authored-By: Marcio Diaz <marcio.diaz@gmail.com>

* Fix verify_unsigned benchmark

* add variable for teting the external addresss length

* Update frame/im-online/src/benchmarking.rs

Co-Authored-By: Kian Paimani <5588131+kianenigma@users.noreply.github.com>

* Update utils/frame/benchmarking-cli/src/lib.rs

Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com>

Co-authored-by: Marcio Diaz <marcio.diaz@gmail.com>
Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
Co-authored-by: Benjamin Kampmann <ben@gnunicorn.org>
Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
This commit is contained in:
Shawn Tabrizi
2020-03-20 12:42:00 +01:00
committed by GitHub
parent 7947cbf915
commit 400a62680f
9 changed files with 160 additions and 2 deletions
+2
View File
@@ -1449,6 +1449,7 @@ dependencies = [
"sc-executor",
"sc-service",
"sp-core",
"sp-externalities",
"sp-runtime",
"sp-state-machine",
"structopt",
@@ -4225,6 +4226,7 @@ dependencies = [
name = "pallet-im-online"
version = "2.0.0-alpha.4"
dependencies = [
"frame-benchmarking",
"frame-support",
"frame-system",
"pallet-authorship",
+3
View File
@@ -139,4 +139,7 @@ runtime-benchmarks = [
"pallet-identity/runtime-benchmarks",
"pallet-balances/runtime-benchmarks",
"pallet-vesting/runtime-benchmarks",
"pallet-session-benchmarking",
"pallet-staking/runtime-benchmarks",
"pallet-im-online/runtime-benchmarks",
]
+7
View File
@@ -864,6 +864,13 @@ impl_runtime_apis! {
steps,
repeat,
),
b"pallet-im-online" | b"im-online" => ImOnline::run_benchmark(
extrinsic,
lowest_range_values,
highest_range_values,
steps,
repeat,
),
b"pallet-identity" | b"identity" => Identity::run_benchmark(
extrinsic,
lowest_range_values,
+3
View File
@@ -22,6 +22,8 @@ sp-staking = { version = "2.0.0-alpha.4", default-features = false, path = "../.
frame-support = { version = "2.0.0-alpha.4", default-features = false, path = "../support" }
frame-system = { version = "2.0.0-alpha.4", default-features = false, path = "../system" }
frame-benchmarking = { version = "2.0.0-alpha.4", default-features = false, path = "../benchmarking", optional = true }
[features]
default = ["std", "pallet-session/historical"]
std = [
@@ -38,3 +40,4 @@ std = [
"frame-support/std",
"frame-system/std",
]
runtime-benchmarks = ["frame-benchmarking"]
@@ -0,0 +1,123 @@
// Copyright 2020 Parity Technologies (UK) Ltd.
// This file is part of Substrate.
// Substrate 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.
// Substrate 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 Substrate. If not, see <http://www.gnu.org/licenses/>.
//! I'm Online pallet benchmarking.
#![cfg(feature = "runtime-benchmarks")]
use super::*;
use frame_system::RawOrigin;
use frame_benchmarking::benchmarks;
use sp_core::offchain::{OpaquePeerId, OpaqueMultiaddr};
use sp_runtime::traits::{ValidateUnsigned, Zero};
use crate::Module as ImOnline;
const MAX_KEYS: u32 = 1000;
const MAX_EXTERNAL_ADDRESSES: u32 = 100;
pub fn create_heartbeat<T: Trait>(k: u32, e: u32) ->
Result<(crate::Heartbeat<T::BlockNumber>, <T::AuthorityId as RuntimeAppPublic>::Signature), &'static str>
{
let mut keys = Vec::new();
for _ in 0..k {
keys.push(T::AuthorityId::generate_pair(None));
}
Keys::<T>::put(keys.clone());
let network_state = OpaqueNetworkState {
peer_id: OpaquePeerId::default(),
external_addresses: vec![OpaqueMultiaddr::new(vec![0; 32]); e as usize],
};
let input_heartbeat = Heartbeat {
block_number: T::BlockNumber::zero(),
network_state,
session_index: 0,
authority_index: k-1,
};
let encoded_heartbeat = input_heartbeat.encode();
let authority_id = keys.get((k-1) as usize).ok_or("out of range")?;
let signature = authority_id.sign(&encoded_heartbeat).ok_or("couldn't make signature")?;
Ok((input_heartbeat, signature))
}
benchmarks! {
_{ }
heartbeat {
let k in 1 .. MAX_KEYS;
let e in 1 .. MAX_EXTERNAL_ADDRESSES;
let (input_heartbeat, signature) = create_heartbeat::<T>(k, e)?;
}: _(RawOrigin::None, input_heartbeat, signature)
validate_unsigned {
let k in 1 .. MAX_KEYS;
let e in 1 .. MAX_EXTERNAL_ADDRESSES;
let (input_heartbeat, signature) = create_heartbeat::<T>(k, e)?;
let call = Call::heartbeat(input_heartbeat, signature);
}: {
ImOnline::<T>::validate_unsigned(&call)?;
}
}
#[cfg(test)]
mod tests {
use crate::*;
use super::SelectedBenchmark;
use crate::mock::*;
use frame_support::assert_ok;
#[test]
fn test_heartbeat_benchmark() {
new_test_ext().execute_with(|| {
let k = 10;
assert_eq!(ReceivedHeartbeats::iter_prefix(0).count(), 0);
let selected_benchmark = SelectedBenchmark::heartbeat;
let c = vec![(frame_benchmarking::BenchmarkParameter::k, k)];
let closure_to_benchmark =
<SelectedBenchmark as frame_benchmarking::BenchmarkingSetup<Runtime>>::instance(
&selected_benchmark,
&c
).unwrap();
assert_ok!(closure_to_benchmark());
assert_eq!(ReceivedHeartbeats::iter_prefix(0).count(), 1);
});
}
#[test]
fn test_validate_unsigned_benchmark() {
new_test_ext().execute_with(|| {
let k = 10;
let selected_benchmark = SelectedBenchmark::validate_unsigned;
let c = vec![(frame_benchmarking::BenchmarkParameter::k, k)];
let closure_to_benchmark =
<SelectedBenchmark as frame_benchmarking::BenchmarkingSetup<Runtime>>::instance(
&selected_benchmark,
&c
).unwrap();
assert_ok!(closure_to_benchmark());
});
}
}
+1
View File
@@ -69,6 +69,7 @@
mod mock;
mod tests;
mod benchmarking;
use sp_application_crypto::RuntimeAppPublic;
use codec::{Encode, Decode};
@@ -1293,6 +1293,16 @@ impl Printable for &str {
}
}
impl Printable for bool {
fn print(&self) {
if *self {
"true".print()
} else {
"false".print()
}
}
}
#[impl_for_tuples(1, 12)]
impl Printable for Tuple {
fn print(&self) {
@@ -16,6 +16,7 @@ sc-cli = { version = "0.8.0-alpha.4", path = "../../../client/cli" }
sc-client = { version = "0.8.0-alpha.4", path = "../../../client" }
sc-client-db = { version = "0.8.0-alpha.4", path = "../../../client/db" }
sc-executor = { version = "0.8.0-alpha.4", path = "../../../client/executor" }
sp-externalities = { version = "0.8.0-alpha.4", path = "../../../primitives/externalities" }
sp-runtime = { version = "2.0.0-alpha.4", path = "../../../primitives/runtime" }
sp-state-machine = { version = "0.8.0-alpha.4", path = "../../../primitives/state-machine" }
structopt = "0.3.8"
@@ -23,7 +23,12 @@ use sc_service::{Configuration, ChainSpec};
use sc_executor::{NativeExecutor, NativeExecutionDispatch};
use codec::{Encode, Decode};
use frame_benchmarking::BenchmarkResults;
use sp_core::tasks;
use sp_core::{
tasks,
traits::KeystoreExt,
testing::KeyStore,
};
use sp_externalities::Extensions;
/// The `benchmark` command used to benchmark FRAME Pallets.
#[derive(Debug, structopt::StructOpt, Clone)]
@@ -106,6 +111,9 @@ impl BenchmarkCmd {
2, // The runtime instances cache size.
);
let mut extensions = Extensions::default();
extensions.register(KeystoreExt(KeyStore::new()));
let result = StateMachine::<_, _, NumberFor<BB>, _>::new(
&state,
None,
@@ -120,7 +128,7 @@ impl BenchmarkCmd {
self.steps.clone(),
self.repeat,
).encode(),
Default::default(),
extensions,
&sp_state_machine::backend::BackendRuntimeCode::new(&state).runtime_code()?,
tasks::executor(),
)