Skip to content

Commit

Permalink
Add pruning to bechmarks & update weights. (#918)
Browse files Browse the repository at this point in the history
* Insert headers in benchmarks.

* Fix benchmarks.

* Lower number of headers.

* Avoid hardcoding numbers.

* Update weights.

* cargo fmt --all

* Remove todo.

* Fix test.

* Address review comments.

* Fix borrowed value.
  • Loading branch information
tomusdrw committed Apr 22, 2021
1 parent a30c51d commit c2d56b2
Show file tree
Hide file tree
Showing 6 changed files with 159 additions and 106 deletions.
30 changes: 22 additions & 8 deletions bin/rialto/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -409,16 +409,30 @@ impl pallet_session::Config for Runtime {
}

parameter_types! {
// This is a pretty unscientific cap.
//
// Note that once this is hit the pallet will essentially throttle incoming requests down to one
// call per block.
/// This is a pretty unscientific cap.
///
/// Note that once this is hit the pallet will essentially throttle incoming requests down to one
/// call per block.
pub const MaxRequests: u32 = 50;
}

#[cfg(feature = "runtime-benchmarks")]
parameter_types! {
/// Number of headers to keep in benchmarks.
///
/// In benchmarks we always populate with full number of `HeadersToKeep` to make sure that
/// pruning is taken into account.
///
/// Note: This is lower than regular value, to speed up benchmarking setup.
pub const HeadersToKeep: u32 = 1024;
}

// Number of headers to keep.
//
// Assuming the worst case of every header being finalized, we will keep headers at least for a
// week.
#[cfg(not(feature = "runtime-benchmarks"))]
parameter_types! {
/// Number of headers to keep.
///
/// Assuming the worst case of every header being finalized, we will keep headers at least for a
/// week.
pub const HeadersToKeep: u32 = 7 * bp_rialto::DAYS as u32;
}

Expand Down
29 changes: 19 additions & 10 deletions modules/grandpa/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,10 @@ use bp_test_utils::{
TEST_GRANDPA_ROUND, TEST_GRANDPA_SET_ID,
};
use frame_benchmarking::{benchmarks_instance_pallet, whitelisted_caller};
use frame_support::traits::Get;
use frame_system::RawOrigin;
use sp_finality_grandpa::AuthorityId;
use sp_runtime::traits::{One, Zero};
use sp_runtime::traits::Zero;
use sp_std::{vec, vec::Vec};

// The maximum number of vote ancestries to include in a justification.
Expand All @@ -66,6 +67,14 @@ const MAX_VOTE_ANCESTRIES: u32 = 1000;
// number of validators.
const MAX_VALIDATOR_SET_SIZE: u32 = 1024;

/// Returns number of first header to be imported.
///
/// Since we boostrap the pallet with `HeadersToKeep` already imported headers,
/// this function computes the next expected header number to import.
fn header_number<T: Config<I>, I: 'static, N: From<u32>>() -> N {
(T::HeadersToKeep::get() + 1).into()
}

benchmarks_instance_pallet! {
// This is the "gold standard" benchmark for this extrinsic, and it's what should be used to
// annotate the weight in the pallet.
Expand All @@ -90,9 +99,9 @@ benchmarks_instance_pallet! {
is_halted: false,
};

initialize_bridge::<T, I>(init_data);
let header: BridgedHeader<T, I> = bp_test_utils::test_header(One::one());
bootstrap_bridge::<T, I>(init_data);

let header: BridgedHeader<T, I> = bp_test_utils::test_header(header_number::<T, I, _>());
let params = JustificationGeneratorParams {
header: header.clone(),
round: TEST_GRANDPA_ROUND,
Expand All @@ -106,7 +115,7 @@ benchmarks_instance_pallet! {

}: _(RawOrigin::Signed(caller), header, justification)
verify {
let header: BridgedHeader<T, I> = bp_test_utils::test_header(One::one());
let header: BridgedHeader<T, I> = bp_test_utils::test_header(header_number::<T, I, _>());
let expected_hash = header.hash();

assert_eq!(<BestFinalized<T, I>>::get(), expected_hash);
Expand All @@ -127,8 +136,8 @@ benchmarks_instance_pallet! {
is_halted: false,
};

initialize_bridge::<T, I>(init_data);
let header: BridgedHeader<T, I> = bp_test_utils::test_header(One::one());
bootstrap_bridge::<T, I>(init_data);
let header: BridgedHeader<T, I> = bp_test_utils::test_header(header_number::<T, I, _>());

let params = JustificationGeneratorParams {
header: header.clone(),
Expand All @@ -143,7 +152,7 @@ benchmarks_instance_pallet! {

}: submit_finality_proof(RawOrigin::Signed(caller), header, justification)
verify {
let header: BridgedHeader<T, I> = bp_test_utils::test_header(One::one());
let header: BridgedHeader<T, I> = bp_test_utils::test_header(header_number::<T, I, _>());
let expected_hash = header.hash();

assert_eq!(<BestFinalized<T, I>>::get(), expected_hash);
Expand All @@ -170,8 +179,8 @@ benchmarks_instance_pallet! {
is_halted: false,
};

initialize_bridge::<T, I>(init_data);
let header: BridgedHeader<T, I> = bp_test_utils::test_header(One::one());
bootstrap_bridge::<T, I>(init_data);
let header: BridgedHeader<T, I> = bp_test_utils::test_header(header_number::<T, I, _>());

let params = JustificationGeneratorParams {
header: header.clone(),
Expand All @@ -186,7 +195,7 @@ benchmarks_instance_pallet! {

}: submit_finality_proof(RawOrigin::Signed(caller), header, justification)
verify {
let header: BridgedHeader<T, I> = bp_test_utils::test_header(One::one());
let header: BridgedHeader<T, I> = bp_test_utils::test_header(header_number::<T, I, _>());
let expected_hash = header.hash();

assert_eq!(<BestFinalized<T, I>>::get(), expected_hash);
Expand Down
60 changes: 45 additions & 15 deletions modules/grandpa/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,20 +158,8 @@ pub mod pallet {
verify_justification::<T, I>(&justification, hash, *number, authority_set)?;

let _enacted = try_enact_authority_change::<T, I>(&finality_target, set_id)?;
let index = <ImportedHashesPointer<T, I>>::get();
let pruning = <ImportedHashes<T, I>>::try_get(index);
<BestFinalized<T, I>>::put(hash);
<ImportedHeaders<T, I>>::insert(hash, finality_target);
<ImportedHashes<T, I>>::insert(index, hash);
<RequestCount<T, I>>::mutate(|count| *count += 1);

// Update ring buffer pointer and remove old header.
<ImportedHashesPointer<T, I>>::put((index + 1) % T::HeadersToKeep::get());
if let Ok(hash) = pruning {
log::debug!(target: "runtime::bridge-grandpa", "Pruning old header: {:?}.", hash);
<ImportedHeaders<T, I>>::remove(hash);
}

insert_header::<T, I>(finality_target, hash);
log::info!(target: "runtime::bridge-grandpa", "Succesfully imported finalized header with hash {:?}!", hash);

Ok(().into())
Expand Down Expand Up @@ -427,6 +415,25 @@ pub mod pallet {
)
}

/// Import a previously verified header to the storage.
///
/// Note this function solely takes care of updating the storage and pruning old entries,
/// but does not verify the validaty of such import.
pub(crate) fn insert_header<T: Config<I>, I: 'static>(header: BridgedHeader<T, I>, hash: BridgedBlockHash<T, I>) {
let index = <ImportedHashesPointer<T, I>>::get();
let pruning = <ImportedHashes<T, I>>::try_get(index);
<BestFinalized<T, I>>::put(hash);
<ImportedHeaders<T, I>>::insert(hash, header);
<ImportedHashes<T, I>>::insert(index, hash);

// Update ring buffer pointer and remove old header.
<ImportedHashesPointer<T, I>>::put((index + 1) % T::HeadersToKeep::get());
if let Ok(hash) = pruning {
log::debug!(target: "runtime::bridge-grandpa", "Pruning old header: {:?}.", hash);
<ImportedHeaders<T, I>>::remove(hash);
}
}

/// Since this writes to storage with no real checks this should only be used in functions that
/// were called by a trusted origin.
pub(crate) fn initialize_bridge<T: Config<I>, I: 'static>(
Expand All @@ -441,15 +448,38 @@ pub mod pallet {

let initial_hash = header.hash();
<InitialHash<T, I>>::put(initial_hash);
<BestFinalized<T, I>>::put(initial_hash);
<ImportedHeaders<T, I>>::insert(initial_hash, header);
<ImportedHashesPointer<T, I>>::put(0);
insert_header::<T, I>(header, initial_hash);

let authority_set = bp_header_chain::AuthoritySet::new(authority_list, set_id);
<CurrentAuthoritySet<T, I>>::put(authority_set);

<IsHalted<T, I>>::put(is_halted);
}

#[cfg(feature = "runtime-benchmarks")]
pub(crate) fn bootstrap_bridge<T: Config<I>, I: 'static>(
init_params: super::InitializationData<BridgedHeader<T, I>>,
) {
let start_number = *init_params.header.number();
let end_number = start_number + T::HeadersToKeep::get().into();
initialize_bridge::<T, I>(init_params);

let mut number = start_number;
while number < end_number {
number = number + sp_runtime::traits::One::one();
let header = <BridgedHeader<T, I>>::new(
number,
Default::default(),
Default::default(),
Default::default(),
Default::default(),
);
let hash = header.hash();
insert_header::<T, I>(header, hash);
}
}

/// Ensure that the origin is either root, or `PalletOwner`.
fn ensure_owner_or_root<T: Config<I>, I: 'static>(origin: T::Origin) -> Result<(), BadOrigin> {
match origin.into() {
Expand Down
50 changes: 25 additions & 25 deletions modules/grandpa/src/weights.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
//! Autogenerated weights for pallet_bridge_grandpa
//!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 3.0.0
//! DATE: 2021-04-14, STEPS: [50, ], REPEAT: 20
//! DATE: 2021-04-21, STEPS: [50, ], REPEAT: 20
//! LOW RANGE: [], HIGH RANGE: []
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled
//! CHAIN: Some("dev"), DB CACHE: 128
Expand Down Expand Up @@ -60,29 +60,29 @@ pub struct RialtoWeight<T>(PhantomData<T>);
impl<T: frame_system::Config> WeightInfo for RialtoWeight<T> {
fn submit_finality_proof(v: u32, p: u32) -> Weight {
(0 as Weight)
.saturating_add((837_084_000 as Weight).saturating_mul(v as Weight))
.saturating_add((874_929_000 as Weight).saturating_mul(p as Weight))
.saturating_add((756_462_000 as Weight).saturating_mul(v as Weight))
.saturating_add((791_236_000 as Weight).saturating_mul(p as Weight))
.saturating_add(T::DbWeight::get().reads(7 as Weight))
.saturating_add(T::DbWeight::get().writes(5 as Weight))
.saturating_add(T::DbWeight::get().writes(6 as Weight))
}
fn submit_finality_proof_on_single_fork(v: u32) -> Weight {
(276_463_000 as Weight)
.saturating_add((14_149_000 as Weight).saturating_mul(v as Weight))
(280_121_000 as Weight)
.saturating_add((14_098_000 as Weight).saturating_mul(v as Weight))
.saturating_add(T::DbWeight::get().reads(7 as Weight))
.saturating_add(T::DbWeight::get().writes(5 as Weight))
.saturating_add(T::DbWeight::get().writes(6 as Weight))
}
fn submit_finality_proof_on_many_forks(p: u32) -> Weight {
(10_676_019_000 as Weight)
.saturating_add((97_598_000 as Weight).saturating_mul(p as Weight))
(10_370_940_000 as Weight)
.saturating_add((96_902_000 as Weight).saturating_mul(p as Weight))
.saturating_add(T::DbWeight::get().reads(7 as Weight))
.saturating_add(T::DbWeight::get().writes(5 as Weight))
.saturating_add(T::DbWeight::get().writes(6 as Weight))
}
fn find_scheduled_change(n: u32) -> Weight {
(618_000 as Weight).saturating_add((8_000 as Weight).saturating_mul(n as Weight))
(479_000 as Weight).saturating_add((11_000 as Weight).saturating_mul(n as Weight))
}
fn read_write_authority_sets(n: u32) -> Weight {
(8_582_000 as Weight)
.saturating_add((234_000 as Weight).saturating_mul(n as Weight))
(8_030_000 as Weight)
.saturating_add((232_000 as Weight).saturating_mul(n as Weight))
.saturating_add(T::DbWeight::get().reads(1 as Weight))
.saturating_add(T::DbWeight::get().writes(1 as Weight))
}
Expand All @@ -92,29 +92,29 @@ impl<T: frame_system::Config> WeightInfo for RialtoWeight<T> {
impl WeightInfo for () {
fn submit_finality_proof(v: u32, p: u32) -> Weight {
(0 as Weight)
.saturating_add((837_084_000 as Weight).saturating_mul(v as Weight))
.saturating_add((874_929_000 as Weight).saturating_mul(p as Weight))
.saturating_add((756_462_000 as Weight).saturating_mul(v as Weight))
.saturating_add((791_236_000 as Weight).saturating_mul(p as Weight))
.saturating_add(RocksDbWeight::get().reads(7 as Weight))
.saturating_add(RocksDbWeight::get().writes(5 as Weight))
.saturating_add(RocksDbWeight::get().writes(6 as Weight))
}
fn submit_finality_proof_on_single_fork(v: u32) -> Weight {
(276_463_000 as Weight)
.saturating_add((14_149_000 as Weight).saturating_mul(v as Weight))
(280_121_000 as Weight)
.saturating_add((14_098_000 as Weight).saturating_mul(v as Weight))
.saturating_add(RocksDbWeight::get().reads(7 as Weight))
.saturating_add(RocksDbWeight::get().writes(5 as Weight))
.saturating_add(RocksDbWeight::get().writes(6 as Weight))
}
fn submit_finality_proof_on_many_forks(p: u32) -> Weight {
(10_676_019_000 as Weight)
.saturating_add((97_598_000 as Weight).saturating_mul(p as Weight))
(10_370_940_000 as Weight)
.saturating_add((96_902_000 as Weight).saturating_mul(p as Weight))
.saturating_add(RocksDbWeight::get().reads(7 as Weight))
.saturating_add(RocksDbWeight::get().writes(5 as Weight))
.saturating_add(RocksDbWeight::get().writes(6 as Weight))
}
fn find_scheduled_change(n: u32) -> Weight {
(618_000 as Weight).saturating_add((8_000 as Weight).saturating_mul(n as Weight))
(479_000 as Weight).saturating_add((11_000 as Weight).saturating_mul(n as Weight))
}
fn read_write_authority_sets(n: u32) -> Weight {
(8_582_000 as Weight)
.saturating_add((234_000 as Weight).saturating_mul(n as Weight))
(8_030_000 as Weight)
.saturating_add((232_000 as Weight).saturating_mul(n as Weight))
.saturating_add(RocksDbWeight::get().reads(1 as Weight))
.saturating_add(RocksDbWeight::get().writes(1 as Weight))
}
Expand Down

0 comments on commit c2d56b2

Please sign in to comment.