Unverified Commit 23f6d849 authored by asynchronous rob's avatar asynchronous rob Committed by GitHub
Browse files

Alter behavior of `max_validators_per_core` (#2143)

* guide: ensure max-per-core leads to creation of extra, semi-useless cores

* alter behavior of max_validators_per_core

* guide fixes
parent 2c6920c4
Pipeline #117994 passed with stages
in 29 minutes and 58 seconds
......@@ -175,13 +175,14 @@ Actions:
1. Set `SessionStartBlock` to current block number.
1. Clear all `Some` members of `AvailabilityCores`. Return all parathread claims to queue with retries un-incremented.
1. Set `configuration = Configuration::configuration()` (see [`HostConfiguration`](../types/runtime.md#host-configuration))
1. Resize `AvailabilityCores` to have length `Paras::parachains().len() + configuration.parathread_cores with all `None` entries.
1. Determine the number of cores & validator groups as `n_cores`. This is the maximum of
1. `Paras::parachains().len() + configuration.parathread_cores`
1. `n_validators / max_validators_per_core` if `configuration.max_validators_per_core` is `Some` and non-zero.
1. Resize `AvailabilityCores` to have length `n_cores` with all `None` entries.
1. Compute new validator groups by shuffling using a secure randomness beacon
- We need a total of `N = Paras::parachains().len() + configuration.parathread_cores` validator groups.
- First, we obtain "shuffled validators" `SV` by shuffling the validators using the `SessionChangeNotification`'s random seed.
- Then, we truncate `SV` to have at most `configuration.max_validators_per_core * N` members, if `configuration.max_validators_per_core` is `Some`.
- Note that the total number of validators `V` in `SV` may not be evenly divided by `N`.
- The groups are selected by partitioning `SV`. The first V % N groups will have (V / N) + 1 members, while the remaining groups will have (V / N) members each.
- We obtain "shuffled validators" `SV` by shuffling the validators using the `SessionChangeNotification`'s random seed.
- Note that the total number of validators `V` in `SV` may not be evenly divided by `n_cores`.
- The groups are selected by partitioning `SV`. The first V % N groups will have (V / n_cores) + 1 members, while the remaining groups will have (V / N) members each.
1. Prune the parathread queue to remove all retries beyond `configuration.parathread_retries`.
- Also prune all parathread claims corresponding to de-registered parathreads.
- all pruned claims should have their entry removed from the parathread index.
......
......@@ -173,7 +173,9 @@ decl_storage! {
/// The i'th parachain belongs to the i'th core, with the remaining cores all being
/// parathread-multiplexers.
///
/// Bounded by the number of cores: one for each parachain and parathread multiplexer.
/// Bounded by the maximum of either of these two values:
/// * The number of parachains and parathread multiplexers
/// * The number of validators divided by `configuration.max_validators_per_core`.
AvailabilityCores get(fn availability_cores): Vec<Option<CoreOccupied>>;
/// An index used to ensure that only one claim on a parathread exists in the queue or is
/// currently being handled by an occupied core.
......@@ -240,7 +242,13 @@ impl<T: Config> Module<T> {
let mut thread_queue = ParathreadQueue::get();
let n_parachains = <paras::Module<T>>::parachains().len() as u32;
let n_cores = n_parachains + config.parathread_cores;
let n_cores = core::cmp::max(
n_parachains + config.parathread_cores,
match config.max_validators_per_core {
Some(x) if x != 0 => { validators.len() as u32 / x },
_ => 0,
},
);
<SessionStartBlock<T>>::set(<frame_system::Module<T>>::block_number());
AvailabilityCores::mutate(|cores| {
......@@ -272,14 +280,6 @@ impl<T: Config> Module<T> {
shuffled_indices.shuffle(&mut rng);
// trim to max per cores. do this after shuffling.
{
if let Some(max_per_core) = config.max_validators_per_core {
let max_total = max_per_core * n_cores;
shuffled_indices.truncate(max_total as usize);
}
}
let group_base_size = shuffled_indices.len() / n_cores as usize;
let n_larger_groups = shuffled_indices.len() % n_cores as usize;
......@@ -1070,6 +1070,7 @@ mod tests {
new_test_ext(genesis_config).execute_with(|| {
let chain_a = ParaId::from(1);
let chain_b = ParaId::from(2);
let chain_c = ParaId::from(3);
// ensure that we have 5 groups by registering 2 parachains.
Paras::schedule_para_initialize(chain_a, ParaGenesisArgs {
......@@ -1082,6 +1083,11 @@ mod tests {
validation_code: Vec::new().into(),
parachain: true,
});
Paras::schedule_para_initialize(chain_c, ParaGenesisArgs {
genesis_head: Vec::new().into(),
validation_code: Vec::new().into(),
parachain: false,
});
run_to_block(1, |number| match number {
1 => Some(SessionChangeNotification {
......@@ -1102,11 +1108,10 @@ mod tests {
});
let groups = ValidatorGroups::get();
assert_eq!(groups.len(), 2);
assert_eq!(groups.len(), 7);
// Even though there are 7 validators, only 1 validator per group
// due to the max.
for i in 0..2 {
// Every validator gets its own group, even though there are 2 paras.
for i in 0..7 {
assert_eq!(groups[i].len(), 1);
}
});
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment