Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit ac641cd

Browse files
Fix Election when ForceNone V1 (#6166)
* Clean * Better doc * Better better doc * Again better doc * Fix indemt * Update frame/staking/src/lib.rs * Update frame/staking/src/lib.rs * Better test Co-authored-by: Gavin Wood <gavin@parity.io>
1 parent d7058c8 commit ac641cd

File tree

2 files changed

+102
-15
lines changed

2 files changed

+102
-15
lines changed

frame/staking/src/lib.rs

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,7 +1288,7 @@ decl_module! {
12881288
// either current session final based on the plan, or we're forcing.
12891289
(Self::is_current_session_final() || Self::will_era_be_forced())
12901290
{
1291-
if let Some(next_session_change) = T::NextNewSession::estimate_next_new_session(now){
1291+
if let Some(next_session_change) = T::NextNewSession::estimate_next_new_session(now) {
12921292
if let Some(remaining) = next_session_change.checked_sub(&now) {
12931293
if remaining <= T::ElectionLookahead::get() && !remaining.is_zero() {
12941294
// create snapshot.
@@ -2569,16 +2569,19 @@ impl<T: Trait> Module<T> {
25692569
Forcing::ForceAlways => (),
25702570
Forcing::NotForcing if era_length >= T::SessionsPerEra::get() => (),
25712571
_ => {
2572-
// not forcing, not a new era either. If final, set the flag.
2573-
if era_length + 1 >= T::SessionsPerEra::get() {
2572+
// Either `ForceNone`, or `NotForcing && era_length < T::SessionsPerEra::get()`.
2573+
if era_length + 1 == T::SessionsPerEra::get() {
25742574
IsCurrentSessionFinal::put(true);
2575+
} else if era_length >= T::SessionsPerEra::get() {
2576+
// Should only happen when we are ready to trigger an era but we have ForceNone,
2577+
// otherwise previous arm would short circuit.
2578+
Self::close_election_window();
25752579
}
25762580
return None
25772581
},
25782582
}
25792583

25802584
// new era.
2581-
IsCurrentSessionFinal::put(false);
25822585
Self::new_era(session_index)
25832586
} else {
25842587
// Set initial era
@@ -2912,6 +2915,17 @@ impl<T: Trait> Module<T> {
29122915
maybe_new_validators
29132916
}
29142917

2918+
2919+
/// Remove all the storage items associated with the election.
2920+
fn close_election_window() {
2921+
// Close window.
2922+
<EraElectionStatus<T>>::put(ElectionStatus::Closed);
2923+
// Kill snapshots.
2924+
Self::kill_stakers_snapshot();
2925+
// Don't track final session.
2926+
IsCurrentSessionFinal::put(false);
2927+
}
2928+
29152929
/// Select the new validator set at the end of the era.
29162930
///
29172931
/// Runs [`try_do_phragmen`] and updates the following storage items:
@@ -2933,11 +2947,8 @@ impl<T: Trait> Module<T> {
29332947
exposures,
29342948
compute,
29352949
}) = Self::try_do_phragmen() {
2936-
// We have chosen the new validator set. Submission is no longer allowed.
2937-
<EraElectionStatus<T>>::put(ElectionStatus::Closed);
2938-
2939-
// kill the snapshots.
2940-
Self::kill_stakers_snapshot();
2950+
// Totally close the election round and data.
2951+
Self::close_election_window();
29412952

29422953
// Populate Stakers and write slot stake.
29432954
let mut total_stake: BalanceOf<T> = Zero::zero();

frame/staking/src/tests.rs

Lines changed: 82 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2859,7 +2859,7 @@ mod offchain_phragmen {
28592859
}
28602860

28612861
#[test]
2862-
fn offchain_election_flag_is_triggered() {
2862+
fn offchain_window_is_triggered() {
28632863
ExtBuilder::default()
28642864
.session_per_era(5)
28652865
.session_length(10)
@@ -2919,28 +2919,104 @@ mod offchain_phragmen {
29192919
}
29202920

29212921
#[test]
2922-
fn offchain_election_flag_is_triggered_when_forcing() {
2922+
fn offchain_window_is_triggered_when_forcing() {
29232923
ExtBuilder::default()
29242924
.session_per_era(5)
29252925
.session_length(10)
29262926
.election_lookahead(3)
29272927
.build()
29282928
.execute_with(|| {
2929-
run_to_block(7);
2930-
assert_session_era!(0, 0);
2931-
29322929
run_to_block(12);
29332930
ForceEra::put(Forcing::ForceNew);
29342931
run_to_block(13);
29352932
assert_eq!(Staking::era_election_status(), ElectionStatus::Closed);
29362933

29372934
run_to_block(17); // instead of 47
29382935
assert_eq!(Staking::era_election_status(), ElectionStatus::Open(17));
2936+
2937+
run_to_block(20);
2938+
assert_eq!(Staking::era_election_status(), ElectionStatus::Closed);
2939+
})
2940+
}
2941+
2942+
#[test]
2943+
fn offchain_window_is_triggered_when_force_always() {
2944+
ExtBuilder::default()
2945+
.session_per_era(5)
2946+
.session_length(10)
2947+
.election_lookahead(3)
2948+
.build()
2949+
.execute_with(|| {
2950+
2951+
ForceEra::put(Forcing::ForceAlways);
2952+
run_to_block(16);
2953+
assert_eq!(Staking::era_election_status(), ElectionStatus::Closed);
2954+
2955+
run_to_block(17); // instead of 37
2956+
assert_eq!(Staking::era_election_status(), ElectionStatus::Open(17));
2957+
2958+
run_to_block(20);
2959+
assert_eq!(Staking::era_election_status(), ElectionStatus::Closed);
2960+
2961+
run_to_block(26);
2962+
assert_eq!(Staking::era_election_status(), ElectionStatus::Closed);
2963+
2964+
run_to_block(27); // next one again
2965+
assert_eq!(Staking::era_election_status(), ElectionStatus::Open(27));
2966+
})
2967+
}
2968+
2969+
#[test]
2970+
fn offchain_window_closes_when_forcenone() {
2971+
ExtBuilder::default()
2972+
.session_per_era(5)
2973+
.session_length(10)
2974+
.election_lookahead(3)
2975+
.build()
2976+
.execute_with(|| {
2977+
ForceEra::put(Forcing::ForceNone);
2978+
2979+
run_to_block(36);
2980+
assert_session_era!(3, 0);
2981+
assert_eq!(Staking::era_election_status(), ElectionStatus::Closed);
2982+
2983+
// opens
2984+
run_to_block(37);
2985+
assert_eq!(Staking::era_election_status(), ElectionStatus::Open(37));
2986+
assert!(Staking::is_current_session_final());
2987+
assert!(Staking::snapshot_validators().is_some());
2988+
2989+
// closes normally
2990+
run_to_block(40);
2991+
assert_eq!(Staking::era_election_status(), ElectionStatus::Closed);
2992+
assert!(!Staking::is_current_session_final());
2993+
assert!(Staking::snapshot_validators().is_none());
2994+
assert_session_era!(4, 0);
2995+
2996+
run_to_block(47);
2997+
assert_eq!(Staking::era_election_status(), ElectionStatus::Closed);
2998+
assert_session_era!(4, 0);
2999+
3000+
run_to_block(57);
3001+
assert_eq!(Staking::era_election_status(), ElectionStatus::Closed);
3002+
assert_session_era!(5, 0);
3003+
3004+
run_to_block(67);
3005+
assert_eq!(Staking::era_election_status(), ElectionStatus::Closed);
3006+
3007+
// Will not open again as scheduled
3008+
run_to_block(87);
3009+
assert_eq!(Staking::era_election_status(), ElectionStatus::Closed);
3010+
assert_session_era!(8, 0);
3011+
3012+
run_to_block(90);
3013+
assert_eq!(Staking::era_election_status(), ElectionStatus::Closed);
3014+
assert_session_era!(9, 0);
29393015
})
29403016
}
29413017

29423018
#[test]
2943-
fn election_on_chain_fallback_works() {
3019+
fn offchain_window_on_chain_fallback_works() {
29443020
ExtBuilder::default().build_and_execute(|| {
29453021
start_session(1);
29463022
start_session(2);

0 commit comments

Comments
 (0)