mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-14 05:11:09 +00:00
Fix session phase in early-exit (#453)
* Fix up session phase. * Version bump * Fix session rotation properly and add test * Update runtimes * Docs
This commit is contained in:
BIN
Binary file not shown.
Binary file not shown.
@@ -110,7 +110,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
|
|||||||
spec_name: ver_str!("polkadot"),
|
spec_name: ver_str!("polkadot"),
|
||||||
impl_name: ver_str!("parity-polkadot"),
|
impl_name: ver_str!("parity-polkadot"),
|
||||||
authoring_version: 1,
|
authoring_version: 1,
|
||||||
spec_version: 2,
|
spec_version: 100,
|
||||||
impl_version: 0,
|
impl_version: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -79,6 +79,7 @@ decl_module! {
|
|||||||
fn force_new_session(normal_rotation: bool) -> Result = 1;
|
fn force_new_session(normal_rotation: bool) -> Result = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
decl_storage! {
|
decl_storage! {
|
||||||
trait Store for Module<T: Trait>;
|
trait Store for Module<T: Trait>;
|
||||||
|
|
||||||
@@ -93,6 +94,9 @@ decl_storage! {
|
|||||||
// Percent by which the session must necessarily finish late before we early-exit the session.
|
// Percent by which the session must necessarily finish late before we early-exit the session.
|
||||||
pub BrokenPercentLate get(broken_percent_late): b"ses:broken_percent_late" => required T::Moment;
|
pub BrokenPercentLate get(broken_percent_late): b"ses:broken_percent_late" => required T::Moment;
|
||||||
|
|
||||||
|
// New session is being forced is this entry exists; in which case, the boolean value is whether
|
||||||
|
// the new session should be considered a normal rotation (rewardable) or exceptional (slashable).
|
||||||
|
pub ForcingNewSession get(forcing_new_session): b"ses:forcing_new_session" => bool;
|
||||||
// Block at which the session length last changed.
|
// Block at which the session length last changed.
|
||||||
LastLengthChange: b"ses:llc" => T::BlockNumber;
|
LastLengthChange: b"ses:llc" => T::BlockNumber;
|
||||||
// The next key for a given validator.
|
// The next key for a given validator.
|
||||||
@@ -127,8 +131,8 @@ impl<T: Trait> Module<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Forces a new session.
|
/// Forces a new session.
|
||||||
fn force_new_session(normal_rotation: bool) -> Result {
|
pub fn force_new_session(normal_rotation: bool) -> Result {
|
||||||
Self::rotate_session(normal_rotation);
|
<ForcingNewSession<T>>::put(normal_rotation);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,13 +157,16 @@ impl<T: Trait> Module<T> {
|
|||||||
let block_number = <system::Module<T>>::block_number();
|
let block_number = <system::Module<T>>::block_number();
|
||||||
let is_final_block = ((block_number - Self::last_length_change()) % Self::length()).is_zero();
|
let is_final_block = ((block_number - Self::last_length_change()) % Self::length()).is_zero();
|
||||||
let broken_validation = Self::broken_validation();
|
let broken_validation = Self::broken_validation();
|
||||||
if is_final_block || broken_validation {
|
if let Some(normal_rotation) = Self::forcing_new_session() {
|
||||||
Self::rotate_session(!broken_validation);
|
Self::rotate_session(normal_rotation, is_final_block);
|
||||||
|
<ForcingNewSession<T>>::kill();
|
||||||
|
} else if is_final_block || broken_validation {
|
||||||
|
Self::rotate_session(!broken_validation, is_final_block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Move onto next session: register the new authority set.
|
/// Move onto next session: register the new authority set.
|
||||||
pub fn rotate_session(normal_rotation: bool) {
|
pub fn rotate_session(normal_rotation: bool, is_final_block: bool) {
|
||||||
let now = <timestamp::Module<T>>::get();
|
let now = <timestamp::Module<T>>::get();
|
||||||
let time_elapsed = now.clone() - Self::current_start();
|
let time_elapsed = now.clone() - Self::current_start();
|
||||||
|
|
||||||
@@ -168,9 +175,14 @@ impl<T: Trait> Module<T> {
|
|||||||
<CurrentStart<T>>::put(now);
|
<CurrentStart<T>>::put(now);
|
||||||
|
|
||||||
// Enact era length change.
|
// Enact era length change.
|
||||||
if let Some(next_len) = <NextSessionLength<T>>::take() {
|
let len_changed = if let Some(next_len) = <NextSessionLength<T>>::take() {
|
||||||
let block_number = <system::Module<T>>::block_number();
|
|
||||||
<SessionLength<T>>::put(next_len);
|
<SessionLength<T>>::put(next_len);
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
};
|
||||||
|
if len_changed || !is_final_block {
|
||||||
|
let block_number = <system::Module<T>>::block_number();
|
||||||
<LastLengthChange<T>>::put(block_number);
|
<LastLengthChange<T>>::put(block_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,6 +366,40 @@ mod tests {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_work_with_early_exit() {
|
||||||
|
with_externalities(&mut new_test_ext(), || {
|
||||||
|
System::set_block_number(1);
|
||||||
|
assert_ok!(Session::set_length(10));
|
||||||
|
assert_eq!(Session::blocks_remaining(), 1);
|
||||||
|
Session::check_rotate_session();
|
||||||
|
|
||||||
|
System::set_block_number(2);
|
||||||
|
assert_eq!(Session::blocks_remaining(), 0);
|
||||||
|
Session::check_rotate_session();
|
||||||
|
assert_eq!(Session::length(), 10);
|
||||||
|
|
||||||
|
System::set_block_number(7);
|
||||||
|
assert_eq!(Session::current_index(), 1);
|
||||||
|
assert_eq!(Session::blocks_remaining(), 5);
|
||||||
|
assert_ok!(Session::force_new_session(false));
|
||||||
|
Session::check_rotate_session();
|
||||||
|
|
||||||
|
System::set_block_number(8);
|
||||||
|
assert_eq!(Session::current_index(), 2);
|
||||||
|
assert_eq!(Session::blocks_remaining(), 9);
|
||||||
|
Session::check_rotate_session();
|
||||||
|
|
||||||
|
System::set_block_number(17);
|
||||||
|
assert_eq!(Session::current_index(), 2);
|
||||||
|
assert_eq!(Session::blocks_remaining(), 0);
|
||||||
|
Session::check_rotate_session();
|
||||||
|
|
||||||
|
System::set_block_number(18);
|
||||||
|
assert_eq!(Session::current_index(), 3);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn session_length_change_should_work() {
|
fn session_length_change_should_work() {
|
||||||
with_externalities(&mut new_test_ext(), || {
|
with_externalities(&mut new_test_ext(), || {
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ decl_module! {
|
|||||||
fn set_sessions_per_era(new: T::BlockNumber) -> Result = 0;
|
fn set_sessions_per_era(new: T::BlockNumber) -> Result = 0;
|
||||||
fn set_bonding_duration(new: T::BlockNumber) -> Result = 1;
|
fn set_bonding_duration(new: T::BlockNumber) -> Result = 1;
|
||||||
fn set_validator_count(new: u32) -> Result = 2;
|
fn set_validator_count(new: u32) -> Result = 2;
|
||||||
fn force_new_era() -> Result = 3;
|
fn force_new_era(should_slash: bool) -> Result = 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,6 +182,9 @@ decl_storage! {
|
|||||||
// The enumeration sets.
|
// The enumeration sets.
|
||||||
pub EnumSet get(enum_set): b"sta:enum_set" => default map [ T::AccountIndex => Vec<T::AccountId> ];
|
pub EnumSet get(enum_set): b"sta:enum_set" => default map [ T::AccountIndex => Vec<T::AccountId> ];
|
||||||
|
|
||||||
|
// We are forcing a new era.
|
||||||
|
pub ForcingNewEra get(forcing_new_era): b"sta:forcing_new_era" => ();
|
||||||
|
|
||||||
// The "free" balance of a given account.
|
// The "free" balance of a given account.
|
||||||
//
|
//
|
||||||
// This is the only balance that matters in terms of most operations on tokens. It is
|
// This is the only balance that matters in terms of most operations on tokens. It is
|
||||||
@@ -403,10 +406,11 @@ impl<T: Trait> Module<T> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Force there to be a new era. This also forces a new session immediately after.
|
/// Force there to be a new era. This also forces a new session immediately after by
|
||||||
fn force_new_era() -> Result {
|
/// setting `normal_rotation` to be false. Validators will get slashed.
|
||||||
<session::Module<T>>::rotate_session(false);
|
fn force_new_era(should_slash: bool) -> Result {
|
||||||
Ok(())
|
<ForcingNewEra<T>>::put(());
|
||||||
|
<session::Module<T>>::force_new_session(!should_slash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PUBLIC MUTABLES (DANGEROUS)
|
// PUBLIC MUTABLES (DANGEROUS)
|
||||||
@@ -621,7 +625,10 @@ impl<T: Trait> Module<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((session_index - Self::last_era_length_change()) % Self::sessions_per_era()).is_zero() || !normal_rotation {
|
if <ForcingNewEra<T>>::take().is_some()
|
||||||
|
|| ((session_index - Self::last_era_length_change()) % Self::sessions_per_era()).is_zero()
|
||||||
|
|| !normal_rotation
|
||||||
|
{
|
||||||
Self::new_era();
|
Self::new_era();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
Binary file not shown.
BIN
Binary file not shown.
Reference in New Issue
Block a user