EPM and staking events improvement (#13035)

* EPM and staking events improvement

* Uses RawOrigin in ElectionCompute event

* Refactors new phase events to PhaseTransition event

* PhaseTransitioned and remove RawOrigin from event

* Adds helpers for epm phase transition and staking force new

* addresses review comments

* nit: removes unecessary clone

* fixes benchmarks

Co-authored-by: parity-processbot <>
This commit is contained in:
Gonçalo Pestana
2023-01-09 16:06:47 +00:00
committed by GitHub
parent b929e0282d
commit fcdd8a88ad
7 changed files with 369 additions and 124 deletions
@@ -200,7 +200,7 @@ frame_benchmarking::benchmarks! {
assert!(<MultiPhase<T>>::snapshot().is_none());
assert!(<MultiPhase<T>>::current_phase().is_off());
}: {
<MultiPhase<T>>::on_initialize_open_signed();
<MultiPhase<T>>::phase_transition(Phase::Signed);
} verify {
assert!(<MultiPhase<T>>::snapshot().is_none());
assert!(<MultiPhase<T>>::current_phase().is_signed());
@@ -210,7 +210,8 @@ frame_benchmarking::benchmarks! {
assert!(<MultiPhase<T>>::snapshot().is_none());
assert!(<MultiPhase<T>>::current_phase().is_off());
}: {
<MultiPhase<T>>::on_initialize_open_unsigned(true, 1u32.into())
let now = frame_system::Pallet::<T>::block_number();
<MultiPhase<T>>::phase_transition(Phase::Unsigned((true, now)));
} verify {
assert!(<MultiPhase<T>>::snapshot().is_none());
assert!(<MultiPhase<T>>::current_phase().is_unsigned());
@@ -318,7 +319,7 @@ frame_benchmarking::benchmarks! {
submit {
// the queue is full and the solution is only better than the worse.
<MultiPhase<T>>::create_snapshot().map_err(<&str>::from)?;
MultiPhase::<T>::on_initialize_open_signed();
<MultiPhase<T>>::phase_transition(Phase::Signed);
<Round<T>>::put(1);
let mut signed_submissions = SignedSubmissions::<T>::get();
@@ -758,7 +758,7 @@ pub mod pallet {
// NOTE: if signed-phase length is zero, second part of the if-condition fails.
match Self::create_snapshot() {
Ok(_) => {
Self::on_initialize_open_signed();
Self::phase_transition(Phase::Signed);
T::WeightInfo::on_initialize_open_signed()
},
Err(why) => {
@@ -797,7 +797,7 @@ pub mod pallet {
if need_snapshot {
match Self::create_snapshot() {
Ok(_) => {
Self::on_initialize_open_unsigned(enabled, now);
Self::phase_transition(Phase::Unsigned((enabled, now)));
T::WeightInfo::on_initialize_open_unsigned()
},
Err(why) => {
@@ -806,7 +806,7 @@ pub mod pallet {
},
}
} else {
Self::on_initialize_open_unsigned(enabled, now);
Self::phase_transition(Phase::Unsigned((enabled, now)));
T::WeightInfo::on_initialize_open_unsigned()
}
},
@@ -931,6 +931,7 @@ pub mod pallet {
<QueuedSolution<T>>::put(ready);
Self::deposit_event(Event::SolutionStored {
compute: ElectionCompute::Unsigned,
origin: None,
prev_ejected: ejected_a_solution,
});
@@ -983,6 +984,7 @@ pub mod pallet {
Self::deposit_event(Event::SolutionStored {
compute: ElectionCompute::Emergency,
origin: None,
prev_ejected: QueuedSolution::<T>::exists(),
});
@@ -1060,6 +1062,7 @@ pub mod pallet {
signed_submissions.put();
Self::deposit_event(Event::SolutionStored {
compute: ElectionCompute::Signed,
origin: Some(who),
prev_ejected: ejected_a_solution,
});
Ok(())
@@ -1102,6 +1105,7 @@ pub mod pallet {
Self::deposit_event(Event::SolutionStored {
compute: ElectionCompute::Fallback,
origin: None,
prev_ejected: QueuedSolution::<T>::exists(),
});
@@ -1115,11 +1119,16 @@ pub mod pallet {
pub enum Event<T: Config> {
/// A solution was stored with the given compute.
///
/// If the solution is signed, this means that it hasn't yet been processed. If the
/// solution is unsigned, this means that it has also been processed.
///
/// The `bool` is `true` when a previous solution was ejected to make room for this one.
SolutionStored { compute: ElectionCompute, prev_ejected: bool },
/// The `origin` indicates the origin of the solution. If `origin` is `Some(AccountId)`,
/// the stored solution was submited in the signed phase by a miner with the `AccountId`.
/// Otherwise, the solution was stored either during the unsigned phase or by
/// `T::ForceOrigin`. The `bool` is `true` when a previous solution was ejected to make
/// room for this one.
SolutionStored {
compute: ElectionCompute,
origin: Option<T::AccountId>,
prev_ejected: bool,
},
/// The election has been finalized, with the given computation and score.
ElectionFinalized { compute: ElectionCompute, score: ElectionScore },
/// An election failed.
@@ -1130,10 +1139,8 @@ pub mod pallet {
Rewarded { account: <T as frame_system::Config>::AccountId, value: BalanceOf<T> },
/// An account has been slashed for submitting an invalid signed submission.
Slashed { account: <T as frame_system::Config>::AccountId, value: BalanceOf<T> },
/// The signed phase of the given round has started.
SignedPhaseStarted { round: u32 },
/// The unsigned phase of the given round has started.
UnsignedPhaseStarted { round: u32 },
/// There was a phase transition in a given round.
PhaseTransitioned { from: Phase<T::BlockNumber>, to: Phase<T::BlockNumber>, round: u32 },
}
/// Error of the pallet that can be returned in response to dispatches.
@@ -1349,19 +1356,15 @@ impl<T: Config> Pallet<T> {
}
}
/// Logic for `<Pallet as Hooks>::on_initialize` when signed phase is being opened.
pub fn on_initialize_open_signed() {
log!(info, "Starting signed phase round {}.", Self::round());
<CurrentPhase<T>>::put(Phase::Signed);
Self::deposit_event(Event::SignedPhaseStarted { round: Self::round() });
}
/// Logic for `<Pallet as Hooks<T>>::on_initialize` when unsigned phase is being opened.
pub fn on_initialize_open_unsigned(enabled: bool, now: T::BlockNumber) {
let round = Self::round();
log!(info, "Starting unsigned phase round {} enabled {}.", round, enabled);
<CurrentPhase<T>>::put(Phase::Unsigned((enabled, now)));
Self::deposit_event(Event::UnsignedPhaseStarted { round });
/// Phase transition helper.
pub(crate) fn phase_transition(to: Phase<T::BlockNumber>) {
log!(info, "Starting phase {:?}, round {}.", to, Self::round());
Self::deposit_event(Event::PhaseTransitioned {
from: <CurrentPhase<T>>::get(),
to,
round: Self::round(),
});
<CurrentPhase<T>>::put(to);
}
/// Parts of [`create_snapshot`] that happen inside of this pallet.
@@ -1571,7 +1574,7 @@ impl<T: Config> Pallet<T> {
<Round<T>>::mutate(|r| *r += 1);
// Phase is off now.
<CurrentPhase<T>>::put(Phase::Off);
Self::phase_transition(Phase::Off);
// Kill snapshots.
Self::kill_snapshot();
@@ -1652,7 +1655,7 @@ impl<T: Config> ElectionProvider for Pallet<T> {
},
Err(why) => {
log!(error, "Entering emergency mode: {:?}", why);
<CurrentPhase<T>>::put(Phase::Emergency);
Self::phase_transition(Phase::Emergency);
Err(why)
},
}
@@ -1898,7 +1901,10 @@ mod tests {
roll_to_signed();
assert_eq!(MultiPhase::current_phase(), Phase::Signed);
assert_eq!(multi_phase_events(), vec![Event::SignedPhaseStarted { round: 1 }]);
assert_eq!(
multi_phase_events(),
vec![Event::PhaseTransitioned { from: Phase::Off, to: Phase::Signed, round: 1 }]
);
assert!(MultiPhase::snapshot().is_some());
assert_eq!(MultiPhase::round(), 1);
@@ -1912,8 +1918,12 @@ mod tests {
assert_eq!(
multi_phase_events(),
vec![
Event::SignedPhaseStarted { round: 1 },
Event::UnsignedPhaseStarted { round: 1 }
Event::PhaseTransitioned { from: Phase::Off, to: Phase::Signed, round: 1 },
Event::PhaseTransitioned {
from: Phase::Signed,
to: Phase::Unsigned((true, 25)),
round: 1
},
],
);
assert!(MultiPhase::snapshot().is_some());
@@ -1949,8 +1959,12 @@ mod tests {
assert_eq!(
multi_phase_events(),
vec![
Event::SignedPhaseStarted { round: 1 },
Event::UnsignedPhaseStarted { round: 1 },
Event::PhaseTransitioned { from: Phase::Off, to: Phase::Signed, round: 1 },
Event::PhaseTransitioned {
from: Phase::Signed,
to: Phase::Unsigned((true, 25)),
round: 1
},
Event::ElectionFinalized {
compute: ElectionCompute::Fallback,
score: ElectionScore {
@@ -1959,8 +1973,17 @@ mod tests {
sum_stake_squared: 0
}
},
Event::SignedPhaseStarted { round: 2 },
Event::UnsignedPhaseStarted { round: 2 }
Event::PhaseTransitioned {
from: Phase::Unsigned((true, 25)),
to: Phase::Off,
round: 2
},
Event::PhaseTransitioned { from: Phase::Off, to: Phase::Signed, round: 2 },
Event::PhaseTransitioned {
from: Phase::Signed,
to: Phase::Unsigned((true, 55)),
round: 2
},
]
);
})
@@ -1990,7 +2013,11 @@ mod tests {
assert_eq!(
multi_phase_events(),
vec![
Event::UnsignedPhaseStarted { round: 1 },
Event::PhaseTransitioned {
from: Phase::Off,
to: Phase::Unsigned((true, 20)),
round: 1
},
Event::ElectionFinalized {
compute: ElectionCompute::Fallback,
score: ElectionScore {
@@ -1998,7 +2025,12 @@ mod tests {
sum_stake: 0,
sum_stake_squared: 0
}
}
},
Event::PhaseTransitioned {
from: Phase::Unsigned((true, 20)),
to: Phase::Off,
round: 2
},
]
);
});
@@ -2028,7 +2060,7 @@ mod tests {
assert_eq!(
multi_phase_events(),
vec![
Event::SignedPhaseStarted { round: 1 },
Event::PhaseTransitioned { from: Phase::Off, to: Phase::Signed, round: 1 },
Event::ElectionFinalized {
compute: ElectionCompute::Fallback,
score: ElectionScore {
@@ -2036,7 +2068,8 @@ mod tests {
sum_stake: 0,
sum_stake_squared: 0
}
}
},
Event::PhaseTransitioned { from: Phase::Signed, to: Phase::Off, round: 2 },
]
)
});
@@ -2064,10 +2097,17 @@ mod tests {
assert_eq!(
multi_phase_events(),
vec![Event::ElectionFinalized {
compute: ElectionCompute::Fallback,
score: ElectionScore { minimal_stake: 0, sum_stake: 0, sum_stake_squared: 0 }
}]
vec![
Event::ElectionFinalized {
compute: ElectionCompute::Fallback,
score: ElectionScore {
minimal_stake: 0,
sum_stake: 0,
sum_stake_squared: 0
}
},
Event::PhaseTransitioned { from: Phase::Off, to: Phase::Off, round: 2 },
]
);
});
}
@@ -2079,7 +2119,10 @@ mod tests {
// Signed phase started at block 15 and will end at 25.
roll_to_signed();
assert_eq!(multi_phase_events(), vec![Event::SignedPhaseStarted { round: 1 }]);
assert_eq!(
multi_phase_events(),
vec![Event::PhaseTransitioned { from: Phase::Off, to: Phase::Signed, round: 1 }]
);
assert_eq!(MultiPhase::current_phase(), Phase::Signed);
assert_eq!(MultiPhase::round(), 1);
@@ -2090,11 +2133,12 @@ mod tests {
assert_eq!(
multi_phase_events(),
vec![
Event::SignedPhaseStarted { round: 1 },
Event::PhaseTransitioned { from: Phase::Off, to: Phase::Signed, round: 1 },
Event::ElectionFinalized {
compute: ElectionCompute::Fallback,
score: Default::default()
}
},
Event::PhaseTransitioned { from: Phase::Signed, to: Phase::Off, round: 2 },
],
);
// All storage items must be cleared.
@@ -2114,7 +2158,10 @@ mod tests {
// signed phase started at block 15 and will end at 25.
roll_to_signed();
assert_eq!(multi_phase_events(), vec![Event::SignedPhaseStarted { round: 1 }]);
assert_eq!(
multi_phase_events(),
vec![Event::PhaseTransitioned { from: Phase::Off, to: Phase::Signed, round: 1 }]
);
assert_eq!(MultiPhase::current_phase(), Phase::Signed);
assert_eq!(MultiPhase::round(), 1);
@@ -2144,12 +2191,32 @@ mod tests {
assert_eq!(
multi_phase_events(),
vec![
Event::SignedPhaseStarted { round: 1 },
Event::SolutionStored { compute: ElectionCompute::Signed, prev_ejected: false },
Event::SolutionStored { compute: ElectionCompute::Signed, prev_ejected: false },
Event::SolutionStored { compute: ElectionCompute::Signed, prev_ejected: false },
Event::SolutionStored { compute: ElectionCompute::Signed, prev_ejected: false },
Event::SolutionStored { compute: ElectionCompute::Signed, prev_ejected: false },
Event::PhaseTransitioned { from: Phase::Off, to: Phase::Signed, round: 1 },
Event::SolutionStored {
compute: ElectionCompute::Signed,
origin: Some(99),
prev_ejected: false
},
Event::SolutionStored {
compute: ElectionCompute::Signed,
origin: Some(99),
prev_ejected: false
},
Event::SolutionStored {
compute: ElectionCompute::Signed,
origin: Some(99),
prev_ejected: false
},
Event::SolutionStored {
compute: ElectionCompute::Signed,
origin: Some(99),
prev_ejected: false
},
Event::SolutionStored {
compute: ElectionCompute::Signed,
origin: Some(99),
prev_ejected: false
},
Event::Slashed { account: 99, value: 5 },
Event::Slashed { account: 99, value: 5 },
Event::Slashed { account: 99, value: 5 },
@@ -2162,7 +2229,8 @@ mod tests {
sum_stake: 0,
sum_stake_squared: 0
}
}
},
Event::PhaseTransitioned { from: Phase::Signed, to: Phase::Off, round: 2 },
]
);
})
@@ -2186,10 +2254,18 @@ mod tests {
assert_eq!(
multi_phase_events(),
vec![
Event::SignedPhaseStarted { round: 1 },
Event::SolutionStored { compute: ElectionCompute::Signed, prev_ejected: false },
Event::PhaseTransitioned { from: Phase::Off, to: Phase::Signed, round: 1 },
Event::SolutionStored {
compute: ElectionCompute::Signed,
origin: Some(99),
prev_ejected: false
},
Event::Rewarded { account: 99, value: 7 },
Event::UnsignedPhaseStarted { round: 1 },
Event::PhaseTransitioned {
from: Phase::Signed,
to: Phase::Unsigned((true, 25)),
round: 1
},
Event::ElectionFinalized {
compute: ElectionCompute::Signed,
score: ElectionScore {
@@ -2197,7 +2273,12 @@ mod tests {
sum_stake: 100,
sum_stake_squared: 5200
}
}
},
Event::PhaseTransitioned {
from: Phase::Unsigned((true, 25)),
to: Phase::Off,
round: 2
},
],
);
})
@@ -2230,10 +2311,15 @@ mod tests {
assert_eq!(
multi_phase_events(),
vec![
Event::SignedPhaseStarted { round: 1 },
Event::UnsignedPhaseStarted { round: 1 },
Event::PhaseTransitioned { from: Phase::Off, to: Phase::Signed, round: 1 },
Event::PhaseTransitioned {
from: Phase::Signed,
to: Phase::Unsigned((true, 25)),
round: 1
},
Event::SolutionStored {
compute: ElectionCompute::Unsigned,
origin: None,
prev_ejected: false
},
Event::ElectionFinalized {
@@ -2243,7 +2329,12 @@ mod tests {
sum_stake: 100,
sum_stake_squared: 5200
}
}
},
Event::PhaseTransitioned {
from: Phase::Unsigned((true, 25)),
to: Phase::Off,
round: 2
},
],
);
})
@@ -2270,8 +2361,12 @@ mod tests {
assert_eq!(
multi_phase_events(),
vec![
Event::SignedPhaseStarted { round: 1 },
Event::UnsignedPhaseStarted { round: 1 },
Event::PhaseTransitioned { from: Phase::Off, to: Phase::Signed, round: 1 },
Event::PhaseTransitioned {
from: Phase::Signed,
to: Phase::Unsigned((true, 25)),
round: 1
},
Event::ElectionFinalized {
compute: ElectionCompute::Fallback,
score: ElectionScore {
@@ -2279,7 +2374,12 @@ mod tests {
sum_stake: 0,
sum_stake_squared: 0
}
}
},
Event::PhaseTransitioned {
from: Phase::Unsigned((true, 25)),
to: Phase::Off,
round: 2
},
]
);
});
@@ -2299,9 +2399,18 @@ mod tests {
assert_eq!(
multi_phase_events(),
vec![
Event::SignedPhaseStarted { round: 1 },
Event::UnsignedPhaseStarted { round: 1 },
Event::ElectionFailed
Event::PhaseTransitioned { from: Phase::Off, to: Phase::Signed, round: 1 },
Event::PhaseTransitioned {
from: Phase::Signed,
to: Phase::Unsigned((true, 25)),
round: 1
},
Event::ElectionFailed,
Event::PhaseTransitioned {
from: Phase::Unsigned((true, 25)),
to: Phase::Emergency,
round: 1
},
]
);
})
@@ -2339,17 +2448,28 @@ mod tests {
assert_eq!(
multi_phase_events(),
vec![
Event::SignedPhaseStarted { round: 1 },
Event::UnsignedPhaseStarted { round: 1 },
Event::PhaseTransitioned { from: Phase::Off, to: Phase::Signed, round: 1 },
Event::PhaseTransitioned {
from: Phase::Signed,
to: Phase::Unsigned((true, 25)),
round: 1
},
Event::ElectionFailed,
Event::PhaseTransitioned {
from: Phase::Unsigned((true, 25)),
to: Phase::Emergency,
round: 1
},
Event::SolutionStored {
compute: ElectionCompute::Fallback,
origin: None,
prev_ejected: false
},
Event::ElectionFinalized {
compute: ElectionCompute::Fallback,
score: Default::default()
}
},
Event::PhaseTransitioned { from: Phase::Emergency, to: Phase::Off, round: 2 },
]
);
})
@@ -2375,10 +2495,17 @@ mod tests {
assert_eq!(
multi_phase_events(),
vec![Event::ElectionFinalized {
compute: ElectionCompute::Fallback,
score: ElectionScore { minimal_stake: 0, sum_stake: 0, sum_stake_squared: 0 }
}]
vec![
Event::ElectionFinalized {
compute: ElectionCompute::Fallback,
score: ElectionScore {
minimal_stake: 0,
sum_stake: 0,
sum_stake_squared: 0
}
},
Event::PhaseTransitioned { from: Phase::Off, to: Phase::Off, round: 2 },
]
);
});
}
@@ -2404,7 +2531,13 @@ mod tests {
assert_eq!(err, ElectionError::Fallback("NoFallback."));
assert_eq!(MultiPhase::current_phase(), Phase::Emergency);
assert_eq!(multi_phase_events(), vec![Event::ElectionFailed]);
assert_eq!(
multi_phase_events(),
vec![
Event::ElectionFailed,
Event::PhaseTransitioned { from: Phase::Off, to: Phase::Emergency, round: 1 }
]
);
});
}
@@ -620,8 +620,12 @@ mod tests {
assert_eq!(
multi_phase_events(),
vec![
Event::SignedPhaseStarted { round: 1 },
Event::SolutionStored { compute: ElectionCompute::Signed, prev_ejected: false }
Event::PhaseTransitioned { from: Phase::Off, to: Phase::Signed, round: 1 },
Event::SolutionStored {
compute: ElectionCompute::Signed,
origin: Some(99),
prev_ejected: false
}
]
);
})
@@ -645,8 +649,12 @@ mod tests {
assert_eq!(
multi_phase_events(),
vec![
Event::SignedPhaseStarted { round: 1 },
Event::SolutionStored { compute: ElectionCompute::Signed, prev_ejected: false },
Event::PhaseTransitioned { from: Phase::Off, to: Phase::Signed, round: 1 },
Event::SolutionStored {
compute: ElectionCompute::Signed,
origin: Some(99),
prev_ejected: false
},
Event::Rewarded { account: 99, value: 7 }
]
);
@@ -676,8 +684,12 @@ mod tests {
assert_eq!(
multi_phase_events(),
vec![
Event::SignedPhaseStarted { round: 1 },
Event::SolutionStored { compute: ElectionCompute::Signed, prev_ejected: false },
Event::PhaseTransitioned { from: Phase::Off, to: Phase::Signed, round: 1 },
Event::SolutionStored {
compute: ElectionCompute::Signed,
origin: Some(99),
prev_ejected: false
},
Event::Slashed { account: 99, value: 5 }
]
);
@@ -713,9 +725,17 @@ mod tests {
assert_eq!(
multi_phase_events(),
vec![
Event::SignedPhaseStarted { round: 1 },
Event::SolutionStored { compute: ElectionCompute::Signed, prev_ejected: false },
Event::SolutionStored { compute: ElectionCompute::Signed, prev_ejected: false },
Event::PhaseTransitioned { from: Phase::Off, to: Phase::Signed, round: 1 },
Event::SolutionStored {
compute: ElectionCompute::Signed,
origin: Some(99),
prev_ejected: false
},
Event::SolutionStored {
compute: ElectionCompute::Signed,
origin: Some(999),
prev_ejected: false
},
Event::Rewarded { account: 99, value: 7 }
]
);
@@ -788,12 +808,32 @@ mod tests {
assert_eq!(
multi_phase_events(),
vec![
Event::SignedPhaseStarted { round: 1 },
Event::SolutionStored { compute: ElectionCompute::Signed, prev_ejected: false },
Event::SolutionStored { compute: ElectionCompute::Signed, prev_ejected: false },
Event::SolutionStored { compute: ElectionCompute::Signed, prev_ejected: false },
Event::SolutionStored { compute: ElectionCompute::Signed, prev_ejected: false },
Event::SolutionStored { compute: ElectionCompute::Signed, prev_ejected: false },
Event::PhaseTransitioned { from: Phase::Off, to: Phase::Signed, round: 1 },
Event::SolutionStored {
compute: ElectionCompute::Signed,
origin: Some(99),
prev_ejected: false
},
Event::SolutionStored {
compute: ElectionCompute::Signed,
origin: Some(100),
prev_ejected: false
},
Event::SolutionStored {
compute: ElectionCompute::Signed,
origin: Some(101),
prev_ejected: false
},
Event::SolutionStored {
compute: ElectionCompute::Signed,
origin: Some(102),
prev_ejected: false
},
Event::SolutionStored {
compute: ElectionCompute::Signed,
origin: Some(103),
prev_ejected: false
},
Event::Rewarded { account: 99, value: 7 },
Event::ElectionFinalized {
compute: ElectionCompute::Signed,
@@ -856,13 +896,15 @@ mod tests {
assert_eq!(
multi_phase_events(),
vec![
Event::SignedPhaseStarted { round: 1 },
Event::PhaseTransitioned { from: Phase::Off, to: Phase::Signed, round: 1 },
Event::SolutionStored {
compute: ElectionCompute::Signed,
origin: Some(99),
prev_ejected: false
},
Event::SolutionStored {
compute: ElectionCompute::Signed,
origin: Some(99),
prev_ejected: true
}
]
@@ -1112,12 +1154,28 @@ mod tests {
assert_eq!(
multi_phase_events(),
vec![
Event::SignedPhaseStarted { round: 1 },
Event::SolutionStored { compute: ElectionCompute::Signed, prev_ejected: false },
Event::SolutionStored { compute: ElectionCompute::Signed, prev_ejected: false },
Event::SolutionStored { compute: ElectionCompute::Signed, prev_ejected: false },
Event::PhaseTransitioned { from: Phase::Off, to: Phase::Signed, round: 1 },
Event::SolutionStored {
compute: ElectionCompute::Signed,
origin: Some(100),
prev_ejected: false
},
Event::SolutionStored {
compute: ElectionCompute::Signed,
origin: Some(101),
prev_ejected: false
},
Event::SolutionStored {
compute: ElectionCompute::Signed,
origin: Some(102),
prev_ejected: false
},
Event::Rewarded { account: 100, value: 7 },
Event::UnsignedPhaseStarted { round: 1 }
Event::PhaseTransitioned {
from: Phase::Signed,
to: Phase::Unsigned((true, 25)),
round: 1
},
]
);
})
@@ -1170,10 +1228,22 @@ mod tests {
assert_eq!(
multi_phase_events(),
vec![
Event::SignedPhaseStarted { round: 1 },
Event::SolutionStored { compute: ElectionCompute::Signed, prev_ejected: false },
Event::SolutionStored { compute: ElectionCompute::Signed, prev_ejected: false },
Event::SolutionStored { compute: ElectionCompute::Signed, prev_ejected: false },
Event::PhaseTransitioned { from: Phase::Off, to: Phase::Signed, round: 1 },
Event::SolutionStored {
compute: ElectionCompute::Signed,
origin: Some(99),
prev_ejected: false
},
Event::SolutionStored {
compute: ElectionCompute::Signed,
origin: Some(999),
prev_ejected: false
},
Event::SolutionStored {
compute: ElectionCompute::Signed,
origin: Some(9999),
prev_ejected: false
},
Event::Slashed { account: 999, value: 5 },
Event::Rewarded { account: 99, value: 7 }
]
@@ -1304,8 +1374,12 @@ mod tests {
assert_eq!(
multi_phase_events(),
vec![
Event::SignedPhaseStarted { round: 1 },
Event::SolutionStored { compute: ElectionCompute::Signed, prev_ejected: false },
Event::PhaseTransitioned { from: Phase::Off, to: Phase::Signed, round: 1 },
Event::SolutionStored {
compute: ElectionCompute::Signed,
origin: Some(99),
prev_ejected: false
},
Event::Rewarded { account: 99, value: 7 }
]
);
@@ -1055,7 +1055,7 @@ mod tests {
Runtime, RuntimeCall, RuntimeOrigin, System, TestNposSolution, TrimHelpers,
UnsignedPhase,
},
CurrentPhase, Event, InvalidTransaction, Phase, QueuedSolution, TransactionSource,
Event, InvalidTransaction, Phase, QueuedSolution, TransactionSource,
TransactionValidityError,
};
use codec::Decode;
@@ -1128,7 +1128,7 @@ mod tests {
assert!(<MultiPhase as ValidateUnsigned>::pre_dispatch(&call).is_ok());
// unsigned -- but not enabled.
<CurrentPhase<Runtime>>::put(Phase::Unsigned((false, 25)));
MultiPhase::phase_transition(Phase::Unsigned((false, 25)));
assert!(MultiPhase::current_phase().is_unsigned());
assert!(matches!(
<MultiPhase as ValidateUnsigned>::validate_unsigned(
@@ -1321,10 +1321,15 @@ mod tests {
assert_eq!(
multi_phase_events(),
vec![
Event::SignedPhaseStarted { round: 1 },
Event::UnsignedPhaseStarted { round: 1 },
Event::PhaseTransitioned { from: Phase::Off, to: Phase::Signed, round: 1 },
Event::PhaseTransitioned {
from: Phase::Signed,
to: Phase::Unsigned((true, 25)),
round: 1
},
Event::SolutionStored {
compute: ElectionCompute::Unsigned,
origin: None,
prev_ejected: false
}
]
@@ -1661,7 +1666,7 @@ mod tests {
let current_block = block_plus(offchain_repeat * 2 + 2);
// force the unsigned phase to start on the current block.
CurrentPhase::<Runtime>::set(Phase::Unsigned((true, current_block)));
MultiPhase::phase_transition(Phase::Unsigned((true, current_block)));
// clear the cache and create a solution since we are on the first block of the unsigned
// phase.
@@ -1673,8 +1678,12 @@ mod tests {
assert_eq!(
multi_phase_events(),
vec![
Event::SignedPhaseStarted { round: 1 },
Event::UnsignedPhaseStarted { round: 1 },
Event::PhaseTransitioned { from: Phase::Off, to: Phase::Signed, round: 1 },
Event::PhaseTransitioned {
from: Phase::Signed,
to: Phase::Unsigned((true, 25)),
round: 1
},
Event::ElectionFinalized {
compute: ElectionCompute::Fallback,
score: ElectionScore {
@@ -1682,7 +1691,12 @@ mod tests {
sum_stake: 0,
sum_stake_squared: 0
}
}
},
Event::PhaseTransitioned {
from: Phase::Unsigned((true, 25)),
to: Phase::Unsigned((true, 37)),
round: 1
},
]
);
})
+9 -2
View File
@@ -339,7 +339,7 @@ impl<T: Config> Pallet<T> {
if maybe_new_era_validators.is_some() &&
matches!(ForceEra::<T>::get(), Forcing::ForceNew)
{
ForceEra::<T>::put(Forcing::NotForcing);
Self::set_force_era(Forcing::NotForcing);
}
maybe_new_era_validators
@@ -717,11 +717,18 @@ impl<T: Config> Pallet<T> {
}
}
/// Helper to set a new `ForceEra` mode.
pub(crate) fn set_force_era(mode: Forcing) {
log!(info, "Setting force era mode {:?}.", mode);
ForceEra::<T>::put(mode);
Self::deposit_event(Event::<T>::ForceEra { mode });
}
/// Ensures that at the end of the current session there will be a new era.
pub(crate) fn ensure_new_era() {
match ForceEra::<T>::get() {
Forcing::ForceAlways | Forcing::ForceNew => (),
_ => ForceEra::<T>::put(Forcing::ForceNew),
_ => Self::set_force_era(Forcing::ForceNew),
}
}
+5 -3
View File
@@ -714,6 +714,8 @@ pub mod pallet {
PayoutStarted { era_index: EraIndex, validator_stash: T::AccountId },
/// A validator has set their preferences.
ValidatorPrefsSet { stash: T::AccountId, prefs: ValidatorPrefs },
/// A new force era mode was set.
ForceEra { mode: Forcing },
}
#[pallet::error]
@@ -1377,7 +1379,7 @@ pub mod pallet {
#[pallet::weight(T::WeightInfo::force_no_eras())]
pub fn force_no_eras(origin: OriginFor<T>) -> DispatchResult {
ensure_root(origin)?;
ForceEra::<T>::put(Forcing::ForceNone);
Self::set_force_era(Forcing::ForceNone);
Ok(())
}
@@ -1401,7 +1403,7 @@ pub mod pallet {
#[pallet::weight(T::WeightInfo::force_new_era())]
pub fn force_new_era(origin: OriginFor<T>) -> DispatchResult {
ensure_root(origin)?;
ForceEra::<T>::put(Forcing::ForceNew);
Self::set_force_era(Forcing::ForceNew);
Ok(())
}
@@ -1452,7 +1454,7 @@ pub mod pallet {
#[pallet::weight(T::WeightInfo::force_new_era_always())]
pub fn force_new_era_always(origin: OriginFor<T>) -> DispatchResult {
ensure_root(origin)?;
ForceEra::<T>::put(Forcing::ForceAlways);
Self::set_force_era(Forcing::ForceAlways);
Ok(())
}
+21 -7
View File
@@ -899,7 +899,7 @@ fn forcing_new_era_works() {
assert_eq!(active_era(), 1);
// no era change.
ForceEra::<Test>::put(Forcing::ForceNone);
Staking::set_force_era(Forcing::ForceNone);
start_session(4);
assert_eq!(active_era(), 1);
@@ -915,7 +915,7 @@ fn forcing_new_era_works() {
// back to normal.
// this immediately starts a new session.
ForceEra::<Test>::put(Forcing::NotForcing);
Staking::set_force_era(Forcing::NotForcing);
start_session(8);
assert_eq!(active_era(), 1);
@@ -923,7 +923,7 @@ fn forcing_new_era_works() {
start_session(9);
assert_eq!(active_era(), 2);
// forceful change
ForceEra::<Test>::put(Forcing::ForceAlways);
Staking::set_force_era(Forcing::ForceAlways);
start_session(10);
assert_eq!(active_era(), 2);
@@ -935,7 +935,7 @@ fn forcing_new_era_works() {
assert_eq!(active_era(), 4);
// just one forceful change
ForceEra::<Test>::put(Forcing::ForceNew);
Staking::set_force_era(Forcing::ForceNew);
start_session(13);
assert_eq!(active_era(), 5);
assert_eq!(ForceEra::<Test>::get(), Forcing::NotForcing);
@@ -2303,7 +2303,7 @@ fn era_is_always_same_length() {
);
let session = Session::current_index();
ForceEra::<Test>::put(Forcing::ForceNew);
Staking::set_force_era(Forcing::ForceNew);
advance_session();
advance_session();
assert_eq!(current_era(), 3);
@@ -2914,7 +2914,10 @@ fn deferred_slashes_are_deferred() {
staking_events_since_last_call().as_slice(),
&[
Event::Chilled { stash: 11 },
Event::ForceEra { mode: Forcing::ForceNew },
Event::SlashReported { validator: 11, slash_era: 1, .. },
Event::StakersElected,
Event::ForceEra { mode: Forcing::NotForcing },
..,
Event::Slashed { staker: 11, amount: 100 },
Event::Slashed { staker: 101, amount: 12 }
@@ -2949,6 +2952,7 @@ fn retroactive_deferred_slashes_two_eras_before() {
staking_events_since_last_call().as_slice(),
&[
Event::Chilled { stash: 11 },
Event::ForceEra { mode: Forcing::ForceNew },
Event::SlashReported { validator: 11, slash_era: 1, .. },
..,
Event::Slashed { staker: 11, amount: 100 },
@@ -3251,6 +3255,7 @@ fn slash_kicks_validators_not_nominators_and_disables_nominator_for_kicked_valid
Event::StakersElected,
Event::EraPaid { era_index: 0, validator_payout: 11075, remainder: 33225 },
Event::Chilled { stash: 11 },
Event::ForceEra { mode: Forcing::ForceNew },
Event::SlashReported {
validator: 11,
fraction: Perbill::from_percent(10),
@@ -3318,6 +3323,7 @@ fn non_slashable_offence_doesnt_disable_validator() {
Event::StakersElected,
Event::EraPaid { era_index: 0, validator_payout: 11075, remainder: 33225 },
Event::Chilled { stash: 11 },
Event::ForceEra { mode: Forcing::ForceNew },
Event::SlashReported {
validator: 11,
fraction: Perbill::from_percent(0),
@@ -3380,6 +3386,7 @@ fn slashing_independent_of_disabling_validator() {
Event::StakersElected,
Event::EraPaid { era_index: 0, validator_payout: 11075, remainder: 33225 },
Event::Chilled { stash: 11 },
Event::ForceEra { mode: Forcing::ForceNew },
Event::SlashReported {
validator: 11,
fraction: Perbill::from_percent(0),
@@ -4662,8 +4669,15 @@ mod election_data_provider {
MinimumValidatorCount::<Test>::put(2);
run_to_block(55);
assert_eq!(Staking::next_election_prediction(System::block_number()), 55 + 25);
assert_eq!(staking_events().len(), 6);
assert_eq!(*staking_events().last().unwrap(), Event::StakersElected);
assert_eq!(staking_events().len(), 10);
assert_eq!(
*staking_events().last().unwrap(),
Event::ForceEra { mode: Forcing::NotForcing }
);
assert_eq!(
*staking_events().get(staking_events().len() - 2).unwrap(),
Event::StakersElected
);
// The new era has been planned, forcing is changed from `ForceNew` to `NotForcing`.
assert_eq!(ForceEra::<Test>::get(), Forcing::NotForcing);
})