Configurable maximum validators (#2586)

* guide: max_validators

* guide: new approach

* restrict validators based on configurable max

* add some tests

* fix wasm build (Vec)

* clean up warnings

* add logging

* set validator indices in tests as well

* fix common tests

* Update runtime/parachains/src/util.rs

Co-authored-by: Andronik Ordian <write@reusable.software>

Co-authored-by: Andronik Ordian <write@reusable.software>
This commit is contained in:
Robert Habermeier
2021-03-09 12:38:55 -06:00
committed by GitHub
parent 30e4a67f0c
commit 8b4f46d2df
17 changed files with 300 additions and 83 deletions
@@ -19,7 +19,7 @@
//! Configuration can change only at session boundaries and is buffered until then.
use sp_std::prelude::*;
use primitives::v1::{Balance, ValidatorId, SessionIndex};
use primitives::v1::{Balance, SessionIndex};
use frame_support::{
decl_storage, decl_module, decl_error,
ensure,
@@ -146,6 +146,10 @@ pub struct HostConfiguration<BlockNumber> {
///
/// `None` means no maximum.
pub max_validators_per_core: Option<u32>,
/// The maximum number of valdiators to use for parachain consensus, period.
///
/// `None` means no maximum.
pub max_validators: Option<u32>,
/// The amount of sessions to keep for disputes.
pub dispute_period: SessionIndex,
/// The amount of consensus slots that must pass between submitting an assignment and
@@ -181,6 +185,7 @@ impl<BlockNumber: Default + From<u32>> Default for HostConfiguration<BlockNumber
parathread_retries: Default::default(),
scheduling_lookahead: Default::default(),
max_validators_per_core: Default::default(),
max_validators: None,
dispute_period: Default::default(),
n_delay_tranches: Default::default(),
zeroth_delay_tranche_width: Default::default(),
@@ -400,6 +405,16 @@ decl_module! {
Ok(())
}
/// Set the maximum number of validators to use in parachain consensus.
#[weight = (1_000, DispatchClass::Operational)]
pub fn set_max_validators(origin, new: Option<u32>) -> DispatchResult {
ensure_root(origin)?;
Self::update_config_member(|config| {
sp_std::mem::replace(&mut config.max_validators, new) != new
});
Ok(())
}
/// Set the dispute period, in number of sessions to keep for disputes.
#[weight = (1_000, DispatchClass::Operational)]
pub fn set_dispute_period(origin, new: SessionIndex) -> DispatchResult {
@@ -648,8 +663,6 @@ impl<T: Config> Module<T> {
/// Called by the initializer to note that a new session has started.
pub(crate) fn initializer_on_new_session(
_validators: &[ValidatorId],
_queued: &[ValidatorId],
session_index: &SessionIndex,
) {
if let Some(pending) = <Self as Store>::PendingConfig::take(session_index) {
@@ -700,12 +713,12 @@ mod tests {
assert_eq!(Configuration::config(), old_config);
assert_eq!(<Configuration as Store>::PendingConfig::get(1), None);
Configuration::initializer_on_new_session(&[], &[], &1);
Configuration::initializer_on_new_session(&1);
assert_eq!(Configuration::config(), old_config);
assert_eq!(<Configuration as Store>::PendingConfig::get(2), Some(config.clone()));
Configuration::initializer_on_new_session(&[], &[], &2);
Configuration::initializer_on_new_session(&2);
assert_eq!(Configuration::config(), config);
assert_eq!(<Configuration as Store>::PendingConfig::get(3), None);
@@ -729,6 +742,7 @@ mod tests {
thread_availability_period: 8,
scheduling_lookahead: 3,
max_validators_per_core: None,
max_validators: None,
dispute_period: 239,
no_show_slots: 240,
n_delay_tranches: 241,
@@ -795,6 +809,9 @@ mod tests {
Configuration::set_max_validators_per_core(
Origin::root(), new_config.max_validators_per_core,
).unwrap();
Configuration::set_max_validators(
Origin::root(), new_config.max_validators,
).unwrap();
Configuration::set_dispute_period(
Origin::root(), new_config.dispute_period,
).unwrap();