mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-17 17:11:02 +00:00
im-online: use EstimateNextSessionRotation to get better estimates of session progress (#8242)
* frame-support: add method to estimate current session progress * im-online: use EstimateNextSessionRotation trait to delay heartbeats * node: fix im-online pallet instantiation * frame-support: fix docs * frame: fix tests * pallet-session: last block of periodic session means 100% session progress * pallet-session: add test for periodic session progress * pallet-babe: fix epoch progress and add test * frame-support: return weight with session estimates * pallet-im-online: add test for session progress logic
This commit is contained in:
@@ -34,7 +34,7 @@ use sp_application_crypto::Public;
|
||||
use sp_runtime::{
|
||||
generic::DigestItem,
|
||||
traits::{IsMember, One, SaturatedConversion, Saturating, Zero},
|
||||
ConsensusEngineId, KeyTypeId,
|
||||
ConsensusEngineId, KeyTypeId, Percent,
|
||||
};
|
||||
use sp_session::{GetSessionNumber, GetValidatorCount};
|
||||
use sp_std::prelude::*;
|
||||
@@ -780,14 +780,25 @@ impl<T: Config> frame_support::traits::EstimateNextSessionRotation<T::BlockNumbe
|
||||
T::EpochDuration::get().saturated_into()
|
||||
}
|
||||
|
||||
fn estimate_next_session_rotation(now: T::BlockNumber) -> Option<T::BlockNumber> {
|
||||
Self::next_expected_epoch_change(now)
|
||||
fn estimate_current_session_progress(_now: T::BlockNumber) -> (Option<Percent>, Weight) {
|
||||
let elapsed = CurrentSlot::get().saturating_sub(Self::current_epoch_start()) + 1;
|
||||
|
||||
(
|
||||
Some(Percent::from_rational_approximation(
|
||||
*elapsed,
|
||||
T::EpochDuration::get(),
|
||||
)),
|
||||
// Read: Current Slot, Epoch Index, Genesis Slot
|
||||
T::DbWeight::get().reads(3),
|
||||
)
|
||||
}
|
||||
|
||||
// The validity of this weight depends on the implementation of `estimate_next_session_rotation`
|
||||
fn weight(_now: T::BlockNumber) -> Weight {
|
||||
// Read: Current Slot, Epoch Index, Genesis Slot
|
||||
T::DbWeight::get().reads(3)
|
||||
fn estimate_next_session_rotation(now: T::BlockNumber) -> (Option<T::BlockNumber>, Weight) {
|
||||
(
|
||||
Self::next_expected_epoch_change(now),
|
||||
// Read: Current Slot, Epoch Index, Genesis Slot
|
||||
T::DbWeight::get().reads(3),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -260,7 +260,7 @@ impl Config for Test {
|
||||
pub fn go_to_block(n: u64, s: u64) {
|
||||
use frame_support::traits::OnFinalize;
|
||||
|
||||
System::on_finalize(System::block_number());
|
||||
Babe::on_finalize(System::block_number());
|
||||
Session::on_finalize(System::block_number());
|
||||
Staking::on_finalize(System::block_number());
|
||||
|
||||
@@ -274,14 +274,8 @@ pub fn go_to_block(n: u64, s: u64) {
|
||||
let pre_digest = make_secondary_plain_pre_digest(0, s.into());
|
||||
|
||||
System::initialize(&n, &parent_hash, &pre_digest, InitKind::Full);
|
||||
System::set_block_number(n);
|
||||
Timestamp::set_timestamp(n);
|
||||
|
||||
if s > 1 {
|
||||
CurrentSlot::put(Slot::from(s));
|
||||
}
|
||||
|
||||
System::on_initialize(n);
|
||||
Babe::on_initialize(n);
|
||||
Session::on_initialize(n);
|
||||
Staking::on_initialize(n);
|
||||
}
|
||||
|
||||
@@ -20,12 +20,12 @@
|
||||
use super::{Call, *};
|
||||
use frame_support::{
|
||||
assert_err, assert_ok,
|
||||
traits::{Currency, OnFinalize},
|
||||
traits::{Currency, EstimateNextSessionRotation, OnFinalize},
|
||||
weights::{GetDispatchInfo, Pays},
|
||||
};
|
||||
use mock::*;
|
||||
use pallet_session::ShouldEndSession;
|
||||
use sp_consensus_babe::{AllowedSlots, Slot, BabeEpochConfiguration};
|
||||
use sp_consensus_babe::{AllowedSlots, BabeEpochConfiguration, Slot};
|
||||
use sp_core::crypto::Pair;
|
||||
|
||||
const EMPTY_RANDOMNESS: [u8; 32] = [
|
||||
@@ -220,6 +220,38 @@ fn can_predict_next_epoch_change() {
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_estimate_current_epoch_progress() {
|
||||
new_test_ext(1).execute_with(|| {
|
||||
assert_eq!(<Test as Config>::EpochDuration::get(), 3);
|
||||
|
||||
// with BABE the genesis block is not part of any epoch, the first epoch starts at block #1,
|
||||
// therefore its last block should be #3
|
||||
for i in 1u64..4 {
|
||||
progress_to_block(i);
|
||||
|
||||
assert_eq!(Babe::estimate_next_session_rotation(i).0.unwrap(), 4);
|
||||
|
||||
// the last block of the epoch must have 100% progress.
|
||||
if Babe::estimate_next_session_rotation(i).0.unwrap() - 1 == i {
|
||||
assert_eq!(
|
||||
Babe::estimate_current_session_progress(i).0.unwrap(),
|
||||
Percent::from_percent(100)
|
||||
);
|
||||
} else {
|
||||
assert!(Babe::estimate_current_session_progress(i).0.unwrap() < Percent::from_percent(100));
|
||||
}
|
||||
}
|
||||
|
||||
// the first block of the new epoch counts towards the epoch progress as well
|
||||
progress_to_block(4);
|
||||
assert_eq!(
|
||||
Babe::estimate_current_session_progress(4).0.unwrap(),
|
||||
Percent::from_percent(33),
|
||||
);
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn can_enact_next_config() {
|
||||
new_test_ext(1).execute_with(|| {
|
||||
|
||||
Reference in New Issue
Block a user