staking/election: prolonged era and emergency mode for governance submission. (#8912)

* Implementation but weird initial era in tests

* Emergency mode for elections. (#8918)

* do some testing, some logging.

* some testing apparatus

* genesis election provider (#8970)

* genesis election provider

* fix historical stuff

* Fix test

* remove dbg

* Apply suggestions from code review

Co-authored-by: Zeke Mostov <32168567+emostov@users.noreply.github.com>
Co-authored-by: Peter Goodspeed-Niklaus <coriolinus@users.noreply.github.com>

* capitalize comment and name without conflict

* fix log

* Update frame/election-provider-multi-phase/src/lib.rs

* Update frame/election-provider-multi-phase/src/lib.rs

Co-authored-by: Peter Goodspeed-Niklaus <coriolinus@users.noreply.github.com>

* apply suggestion on tests

* remove testing modifications

* Apply suggestions from code review

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
Co-authored-by: Dmitry Kashitsyn <korvin@deeptown.org>

* apply suggestion

* fix master merge

Co-authored-by: kianenigma <kian@parity.io>
Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
Co-authored-by: Zeke Mostov <32168567+emostov@users.noreply.github.com>
Co-authored-by: Peter Goodspeed-Niklaus <coriolinus@users.noreply.github.com>
Co-authored-by: Dmitry Kashitsyn <korvin@deeptown.org>
This commit is contained in:
Guillaume Thiolliere
2021-06-14 16:02:45 +02:00
committed by GitHub
parent cd52b3f2bc
commit ebf5e771fc
15 changed files with 422 additions and 193 deletions
+32 -11
View File
@@ -124,10 +124,17 @@ impl<T: Config> ValidatorSetWithIdentification<T::AccountId> for Module<T> {
/// Specialization of the crate-level `SessionManager` which returns the set of full identification
/// when creating a new session.
pub trait SessionManager<ValidatorId, FullIdentification>: crate::SessionManager<ValidatorId> {
pub trait SessionManager<ValidatorId, FullIdentification>:
crate::SessionManager<ValidatorId>
{
/// If there was a validator set change, its returns the set of new validators along with their
/// full identifications.
fn new_session(new_index: SessionIndex) -> Option<Vec<(ValidatorId, FullIdentification)>>;
fn new_session_genesis(
new_index: SessionIndex,
) -> Option<Vec<(ValidatorId, FullIdentification)>> {
<Self as SessionManager<_, _>>::new_session(new_index)
}
fn start_session(start_index: SessionIndex);
fn end_session(end_index: SessionIndex);
}
@@ -136,19 +143,20 @@ pub trait SessionManager<ValidatorId, FullIdentification>: crate::SessionManager
/// sets the historical trie root of the ending session.
pub struct NoteHistoricalRoot<T, I>(sp_std::marker::PhantomData<(T, I)>);
impl<T: Config, I> crate::SessionManager<T::ValidatorId> for NoteHistoricalRoot<T, I>
where I: SessionManager<T::ValidatorId, T::FullIdentification>
{
fn new_session(new_index: SessionIndex) -> Option<Vec<T::ValidatorId>> {
impl<T: Config, I: SessionManager<T::ValidatorId, T::FullIdentification>> NoteHistoricalRoot<T, I> {
fn do_new_session(new_index: SessionIndex, is_genesis: bool) -> Option<Vec<T::ValidatorId>> {
StoredRange::mutate(|range| {
range.get_or_insert_with(|| (new_index, new_index)).1 = new_index + 1;
});
let new_validators_and_id = <I as SessionManager<_, _>>::new_session(new_index);
let new_validators = new_validators_and_id.as_ref().map(|new_validators| {
new_validators.iter().map(|(v, _id)| v.clone()).collect()
});
let new_validators_and_id = if is_genesis {
<I as SessionManager<_, _>>::new_session_genesis(new_index)
} else {
<I as SessionManager<_, _>>::new_session(new_index)
};
let new_validators_opt = new_validators_and_id
.as_ref()
.map(|new_validators| new_validators.iter().map(|(v, _id)| v.clone()).collect());
if let Some(new_validators) = new_validators_and_id {
let count = new_validators.len() as ValidatorCount;
@@ -166,7 +174,20 @@ impl<T: Config, I> crate::SessionManager<T::ValidatorId> for NoteHistoricalRoot<
}
}
new_validators
new_validators_opt
}
}
impl<T: Config, I> crate::SessionManager<T::ValidatorId> for NoteHistoricalRoot<T, I>
where
I: SessionManager<T::ValidatorId, T::FullIdentification>,
{
fn new_session(new_index: SessionIndex) -> Option<Vec<T::ValidatorId>> {
Self::do_new_session(new_index, false)
}
fn new_session_genesis(new_index: SessionIndex) -> Option<Vec<T::ValidatorId>> {
Self::do_new_session(new_index, true)
}
fn start_session(start_index: SessionIndex) {
+15 -12
View File
@@ -238,12 +238,19 @@ pub trait SessionManager<ValidatorId> {
/// `new_session(session)` is guaranteed to be called before `end_session(session-1)`. In other
/// words, a new session must always be planned before an ongoing one can be finished.
fn new_session(new_index: SessionIndex) -> Option<Vec<ValidatorId>>;
/// Same as `new_session`, but it this should only be called at genesis.
///
/// The session manager might decide to treat this in a different way. Default impl is simply
/// using [`new_session`].
fn new_session_genesis(new_index: SessionIndex) -> Option<Vec<ValidatorId>> {
Self::new_session(new_index)
}
/// End the session.
///
/// Because the session pallet can queue validator set the ending session can be lower than the
/// last new session index.
fn end_session(end_index: SessionIndex);
/// Start the session.
/// Start an already planned session.
///
/// The session start to be used for validation.
fn start_session(start_index: SessionIndex);
@@ -340,13 +347,9 @@ impl<AId> SessionHandler<AId> for Tuple {
pub struct TestSessionHandler;
impl<AId> SessionHandler<AId> for TestSessionHandler {
const KEY_TYPE_IDS: &'static [KeyTypeId] = &[sp_runtime::key_types::DUMMY];
fn on_genesis_session<Ks: OpaqueKeys>(_: &[(AId, Ks)]) {}
fn on_new_session<Ks: OpaqueKeys>(_: bool, _: &[(AId, Ks)], _: &[(AId, Ks)]) {}
fn on_before_session_ending() {}
fn on_disabled(_: usize) {}
}
@@ -451,7 +454,7 @@ decl_storage! {
}
}
let initial_validators_0 = T::SessionManager::new_session(0)
let initial_validators_0 = T::SessionManager::new_session_genesis(0)
.unwrap_or_else(|| {
frame_support::print("No initial validator provided by `SessionManager`, use \
session config keys to generate initial validator set.");
@@ -459,7 +462,7 @@ decl_storage! {
});
assert!(!initial_validators_0.is_empty(), "Empty validator set for session 0 in genesis block!");
let initial_validators_1 = T::SessionManager::new_session(1)
let initial_validators_1 = T::SessionManager::new_session_genesis(1)
.unwrap_or_else(|| initial_validators_0.clone());
assert!(!initial_validators_1.is_empty(), "Empty validator set for session 1 in genesis block!");
@@ -548,7 +551,7 @@ decl_module! {
/// Actual cost depends on the number of length of `T::Keys::key_ids()` which is fixed.
/// - DbReads: `T::ValidatorIdOf`, `NextKeys`, `origin account`
/// - DbWrites: `NextKeys`, `origin account`
/// - DbWrites per key id: `KeyOwnder`
/// - DbWrites per key id: `KeyOwner`
/// # </weight>
#[weight = T::WeightInfo::purge_keys()]
pub fn purge_keys(origin) {
@@ -573,17 +576,17 @@ decl_module! {
}
impl<T: Config> Module<T> {
/// Move on to next session. Register new validator set and session keys. Changes
/// to the validator set have a session of delay to take effect. This allows for
/// equivocation punishment after a fork.
/// Move on to next session. Register new validator set and session keys. Changes to the
/// validator set have a session of delay to take effect. This allows for equivocation
/// punishment after a fork.
pub fn rotate_session() {
let session_index = CurrentIndex::get();
log::trace!(target: "runtime::session", "rotating session {:?}", session_index);
let changed = QueuedChanged::get();
// Inform the session handlers that a session is going to end.
T::SessionHandler::on_before_session_ending();
T::SessionManager::end_session(session_index);
// Get queued session keys and validators.