mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-31 02:51:01 +00:00
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:
committed by
GitHub
parent
30e4a67f0c
commit
8b4f46d2df
@@ -19,12 +19,17 @@
|
||||
//! To avoid cyclic dependencies, it is important that this module is not
|
||||
//! dependent on any of the other modules.
|
||||
|
||||
use primitives::v1::SessionIndex;
|
||||
use primitives::v1::{SessionIndex, ValidatorId, ValidatorIndex};
|
||||
use frame_support::{
|
||||
decl_storage, decl_module, decl_error,
|
||||
weights::Weight,
|
||||
};
|
||||
use crate::initializer::SessionChangeNotification;
|
||||
use sp_std::vec::Vec;
|
||||
|
||||
use rand::{SeedableRng, seq::SliceRandom};
|
||||
use rand_chacha::ChaCha20Rng;
|
||||
|
||||
use crate::configuration::HostConfiguration;
|
||||
|
||||
pub trait Config: frame_system::Config { }
|
||||
|
||||
@@ -37,6 +42,12 @@ decl_storage! {
|
||||
trait Store for Module<T: Config> as ParasShared {
|
||||
/// The current session index.
|
||||
CurrentSessionIndex get(fn session_index): SessionIndex;
|
||||
/// All the validators actively participating in parachain consensus.
|
||||
/// Indices are into the broader validator set.
|
||||
ActiveValidatorIndices get(fn active_validator_indices): Vec<ValidatorIndex>;
|
||||
/// The parachain attestation keys of the validators actively participating in parachain consensus.
|
||||
/// This should be the same length as `ActiveValidatorIndices`.
|
||||
ActiveValidatorKeys get(fn active_validator_keys): Vec<ValidatorId>;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,8 +74,35 @@ impl<T: Config> Module<T> {
|
||||
/// Called by the initializer to note that a new session has started.
|
||||
///
|
||||
/// Returns the list of outgoing paras from the actions queue.
|
||||
pub(crate) fn initializer_on_new_session(notification: &SessionChangeNotification<T::BlockNumber>) {
|
||||
CurrentSessionIndex::set(notification.session_index);
|
||||
pub(crate) fn initializer_on_new_session(
|
||||
session_index: SessionIndex,
|
||||
random_seed: [u8; 32],
|
||||
new_config: &HostConfiguration<T::BlockNumber>,
|
||||
all_validators: Vec<ValidatorId>,
|
||||
) -> Vec<ValidatorId> {
|
||||
CurrentSessionIndex::set(session_index);
|
||||
let mut rng: ChaCha20Rng = SeedableRng::from_seed(random_seed);
|
||||
|
||||
let mut shuffled_indices: Vec<_> = (0..all_validators.len())
|
||||
.enumerate()
|
||||
.map(|(i, _)| ValidatorIndex(i as _))
|
||||
.collect();
|
||||
|
||||
shuffled_indices.shuffle(&mut rng);
|
||||
|
||||
if let Some(max) = new_config.max_validators {
|
||||
shuffled_indices.truncate(max as usize);
|
||||
}
|
||||
|
||||
let active_validator_keys = crate::util::take_active_subset(
|
||||
&shuffled_indices,
|
||||
&all_validators,
|
||||
);
|
||||
|
||||
ActiveValidatorIndices::set(shuffled_indices);
|
||||
ActiveValidatorKeys::set(active_validator_keys.clone());
|
||||
|
||||
active_validator_keys
|
||||
}
|
||||
|
||||
/// Return the session index that should be used for any future scheduled changes.
|
||||
@@ -76,4 +114,122 @@ impl<T: Config> Module<T> {
|
||||
pub(crate) fn set_session_index(index: SessionIndex) {
|
||||
CurrentSessionIndex::set(index);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn set_active_validators(active: Vec<ValidatorId>) {
|
||||
ActiveValidatorIndices::set(
|
||||
(0..active.len()).map(|i| ValidatorIndex(i as _)).collect()
|
||||
);
|
||||
ActiveValidatorKeys::set(active);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::configuration::HostConfiguration;
|
||||
use crate::mock::{new_test_ext, MockGenesisConfig, Shared};
|
||||
use keyring::Sr25519Keyring;
|
||||
|
||||
fn validator_pubkeys(val_ids: &[Sr25519Keyring]) -> Vec<ValidatorId> {
|
||||
val_ids.iter().map(|v| v.public().into()).collect()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sets_and_shuffles_validators() {
|
||||
let validators = vec![
|
||||
Sr25519Keyring::Alice,
|
||||
Sr25519Keyring::Bob,
|
||||
Sr25519Keyring::Charlie,
|
||||
Sr25519Keyring::Dave,
|
||||
Sr25519Keyring::Ferdie,
|
||||
];
|
||||
|
||||
let mut config = HostConfiguration::default();
|
||||
config.max_validators = None;
|
||||
|
||||
let pubkeys = validator_pubkeys(&validators);
|
||||
|
||||
new_test_ext(MockGenesisConfig::default()).execute_with(|| {
|
||||
let validators = Shared::initializer_on_new_session(
|
||||
1,
|
||||
[1; 32],
|
||||
&config,
|
||||
pubkeys,
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
validators,
|
||||
validator_pubkeys(&[
|
||||
Sr25519Keyring::Ferdie,
|
||||
Sr25519Keyring::Bob,
|
||||
Sr25519Keyring::Charlie,
|
||||
Sr25519Keyring::Dave,
|
||||
Sr25519Keyring::Alice,
|
||||
])
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
Shared::active_validator_keys(),
|
||||
validators,
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
Shared::active_validator_indices(),
|
||||
vec![
|
||||
ValidatorIndex(4),
|
||||
ValidatorIndex(1),
|
||||
ValidatorIndex(2),
|
||||
ValidatorIndex(3),
|
||||
ValidatorIndex(0),
|
||||
]
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sets_truncates_and_shuffles_validators() {
|
||||
let validators = vec![
|
||||
Sr25519Keyring::Alice,
|
||||
Sr25519Keyring::Bob,
|
||||
Sr25519Keyring::Charlie,
|
||||
Sr25519Keyring::Dave,
|
||||
Sr25519Keyring::Ferdie,
|
||||
];
|
||||
|
||||
let mut config = HostConfiguration::default();
|
||||
config.max_validators = Some(2);
|
||||
|
||||
let pubkeys = validator_pubkeys(&validators);
|
||||
|
||||
new_test_ext(MockGenesisConfig::default()).execute_with(|| {
|
||||
let validators = Shared::initializer_on_new_session(
|
||||
1,
|
||||
[1; 32],
|
||||
&config,
|
||||
pubkeys,
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
validators,
|
||||
validator_pubkeys(&[
|
||||
Sr25519Keyring::Ferdie,
|
||||
Sr25519Keyring::Bob,
|
||||
])
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
Shared::active_validator_keys(),
|
||||
validators,
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
Shared::active_validator_indices(),
|
||||
vec![
|
||||
ValidatorIndex(4),
|
||||
ValidatorIndex(1),
|
||||
]
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user