mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 12:51:02 +00:00
Approval Checking Improvements Omnibus (#2480)
* add tracing to approval voting * notify if session info is not working * add dispute period to chain specs * propagate genesis session to parachains runtime * use `on_genesis_session` * protect against zero cores in computation * tweak voting rule to be based off of best and add logs * genesis configuration should use VRF slots only * swallow more keystore errors * add some docs * make validation-worker args non-optional and update clap * better tracing for bitfield signing and provisioner * pass amount of bits in bitfields to inclusion instead of recomputing * debug -> warn for some logs * better tracing for availability recovery * a little av-store tracing * bridge: forward availability recovery messages * add missing try_from impl * some more tracing * improve approval distribution tracing * guide: hold onto pending approval messages until NewBlocks * Hold onto pending approval messages until NewBlocks * guide: adjust comment * process all actions for one wakeup at a time * vec * fix network bridge test * replace randomness-collective-flip with Babe * remove PairNotFound
This commit is contained in:
committed by
GitHub
parent
3c4ed7b234
commit
3300b53306
@@ -238,17 +238,14 @@ impl<T: Config> Module<T> {
|
||||
/// Process a set of incoming bitfields. Return a vec of cores freed by candidates
|
||||
/// becoming available.
|
||||
pub(crate) fn process_bitfields(
|
||||
expected_bits: usize,
|
||||
signed_bitfields: SignedAvailabilityBitfields,
|
||||
core_lookup: impl Fn(CoreIndex) -> Option<ParaId>,
|
||||
) -> Result<Vec<CoreIndex>, DispatchError> {
|
||||
let validators = Validators::get();
|
||||
let session_index = shared::Module::<T>::session_index();
|
||||
let config = <configuration::Module<T>>::config();
|
||||
let parachains = <paras::Module<T>>::parachains();
|
||||
|
||||
let n_bits = parachains.len() + config.parathread_cores as usize;
|
||||
|
||||
let mut assigned_paras_record: Vec<_> = (0..n_bits)
|
||||
let mut assigned_paras_record: Vec<_> = (0..expected_bits)
|
||||
.map(|bit_index| core_lookup(CoreIndex::from(bit_index as u32)))
|
||||
.map(|core_para| core_para.map(|p| (p, PendingAvailability::<T>::get(&p))))
|
||||
.collect();
|
||||
@@ -256,7 +253,7 @@ impl<T: Config> Module<T> {
|
||||
// do sanity checks on the bitfields:
|
||||
// 1. no more than one bitfield per validator
|
||||
// 2. bitfields are ascending by validator index.
|
||||
// 3. each bitfield has exactly `n_bits`
|
||||
// 3. each bitfield has exactly `expected_bits`
|
||||
// 4. signature is valid.
|
||||
{
|
||||
let occupied_bitmask: BitVec<BitOrderLsb0, u8> = assigned_paras_record.iter()
|
||||
@@ -274,7 +271,7 @@ impl<T: Config> Module<T> {
|
||||
|
||||
for signed_bitfield in &signed_bitfields {
|
||||
ensure!(
|
||||
signed_bitfield.payload().0.len() == n_bits,
|
||||
signed_bitfield.payload().0.len() == expected_bits,
|
||||
Error::<T>::WrongBitfieldSize,
|
||||
);
|
||||
|
||||
@@ -336,7 +333,7 @@ impl<T: Config> Module<T> {
|
||||
|
||||
let threshold = availability_threshold(validators.len());
|
||||
|
||||
let mut freed_cores = Vec::with_capacity(n_bits);
|
||||
let mut freed_cores = Vec::with_capacity(expected_bits);
|
||||
for (para_id, pending_availability) in assigned_paras_record.into_iter()
|
||||
.filter_map(|x| x)
|
||||
.filter_map(|(id, p)| p.map(|p| (id, p)))
|
||||
@@ -1060,10 +1057,12 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
fn default_bitfield() -> AvailabilityBitfield {
|
||||
let n_bits = Paras::parachains().len() + Configuration::config().parathread_cores as usize;
|
||||
fn expected_bits() -> usize {
|
||||
Paras::parachains().len() + Configuration::config().parathread_cores as usize
|
||||
}
|
||||
|
||||
AvailabilityBitfield(bitvec::bitvec![BitOrderLsb0, u8; 0; n_bits])
|
||||
fn default_bitfield() -> AvailabilityBitfield {
|
||||
AvailabilityBitfield(bitvec::bitvec![BitOrderLsb0, u8; 0; expected_bits()])
|
||||
}
|
||||
|
||||
fn default_availability_votes() -> BitVec<BitOrderLsb0, u8> {
|
||||
@@ -1228,7 +1227,8 @@ mod tests {
|
||||
core if core == CoreIndex::from(0) => Some(chain_a),
|
||||
core if core == CoreIndex::from(1) => Some(chain_b),
|
||||
core if core == CoreIndex::from(2) => Some(thread_a),
|
||||
_ => panic!("Core out of bounds for 2 parachains and 1 parathread core."),
|
||||
core if core == CoreIndex::from(3) => None, // for the expected_cores() + 1 test below.
|
||||
_ => panic!("out of bounds for testing"),
|
||||
};
|
||||
|
||||
// wrong number of bits.
|
||||
@@ -1244,6 +1244,25 @@ mod tests {
|
||||
));
|
||||
|
||||
assert!(Inclusion::process_bitfields(
|
||||
expected_bits(),
|
||||
vec![signed],
|
||||
&core_lookup,
|
||||
).is_err());
|
||||
}
|
||||
|
||||
// wrong number of bits: other way around.
|
||||
{
|
||||
let bare_bitfield = default_bitfield();
|
||||
let signed = block_on(sign_bitfield(
|
||||
&keystore,
|
||||
&validators[0],
|
||||
0,
|
||||
bare_bitfield,
|
||||
&signing_context,
|
||||
));
|
||||
|
||||
assert!(Inclusion::process_bitfields(
|
||||
expected_bits() + 1,
|
||||
vec![signed],
|
||||
&core_lookup,
|
||||
).is_err());
|
||||
@@ -1261,6 +1280,7 @@ mod tests {
|
||||
));
|
||||
|
||||
assert!(Inclusion::process_bitfields(
|
||||
expected_bits(),
|
||||
vec![signed.clone(), signed],
|
||||
&core_lookup,
|
||||
).is_err());
|
||||
@@ -1286,6 +1306,7 @@ mod tests {
|
||||
));
|
||||
|
||||
assert!(Inclusion::process_bitfields(
|
||||
expected_bits(),
|
||||
vec![signed_1, signed_0],
|
||||
&core_lookup,
|
||||
).is_err());
|
||||
@@ -1304,6 +1325,7 @@ mod tests {
|
||||
));
|
||||
|
||||
assert!(Inclusion::process_bitfields(
|
||||
expected_bits(),
|
||||
vec![signed],
|
||||
&core_lookup,
|
||||
).is_err());
|
||||
@@ -1321,6 +1343,7 @@ mod tests {
|
||||
));
|
||||
|
||||
assert!(Inclusion::process_bitfields(
|
||||
expected_bits(),
|
||||
vec![signed],
|
||||
&core_lookup,
|
||||
).is_ok());
|
||||
@@ -1355,6 +1378,7 @@ mod tests {
|
||||
));
|
||||
|
||||
assert!(Inclusion::process_bitfields(
|
||||
expected_bits(),
|
||||
vec![signed],
|
||||
&core_lookup,
|
||||
).is_ok());
|
||||
@@ -1393,6 +1417,7 @@ mod tests {
|
||||
// no core is freed
|
||||
assert_eq!(
|
||||
Inclusion::process_bitfields(
|
||||
expected_bits(),
|
||||
vec![signed],
|
||||
&core_lookup,
|
||||
),
|
||||
@@ -1516,6 +1541,7 @@ mod tests {
|
||||
}).collect();
|
||||
|
||||
assert!(Inclusion::process_bitfields(
|
||||
expected_bits(),
|
||||
signed_bitfields,
|
||||
&core_lookup,
|
||||
).is_ok());
|
||||
|
||||
@@ -107,7 +107,9 @@ decl_module! {
|
||||
|
||||
// Process new availability bitfields, yielding any availability cores whose
|
||||
// work has now concluded.
|
||||
let expected_bits = <scheduler::Module<T>>::availability_cores().len();
|
||||
let freed_concluded = <inclusion::Module<T>>::process_bitfields(
|
||||
expected_bits,
|
||||
signed_bitfields,
|
||||
<scheduler::Module<T>>::core_para,
|
||||
)?;
|
||||
|
||||
@@ -229,11 +229,17 @@ impl<T: Config> Module<T> {
|
||||
validators.clone()
|
||||
};
|
||||
|
||||
BufferedSessionChanges::mutate(|v| v.push(BufferedSessionChange {
|
||||
validators,
|
||||
queued,
|
||||
session_index,
|
||||
}));
|
||||
if session_index == 0 {
|
||||
// Genesis session should be immediately enacted.
|
||||
Self::apply_new_session(0, validators, queued);
|
||||
} else {
|
||||
BufferedSessionChanges::mutate(|v| v.push(BufferedSessionChange {
|
||||
validators,
|
||||
queued,
|
||||
session_index,
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,10 +250,10 @@ impl<T: Config> sp_runtime::BoundToRuntimeAppPublic for Module<T> {
|
||||
impl<T: pallet_session::Config + Config> OneSessionHandler<T::AccountId> for Module<T> {
|
||||
type Key = ValidatorId;
|
||||
|
||||
fn on_genesis_session<'a, I: 'a>(_validators: I)
|
||||
fn on_genesis_session<'a, I: 'a>(validators: I)
|
||||
where I: Iterator<Item=(&'a T::AccountId, Self::Key)>
|
||||
{
|
||||
|
||||
<Module<T>>::on_new_session(false, 0, validators, None);
|
||||
}
|
||||
|
||||
fn on_new_session<'a, I: 'a>(changed: bool, validators: I, queued: I)
|
||||
@@ -266,7 +272,7 @@ mod tests {
|
||||
use primitives::v1::{Id as ParaId};
|
||||
use crate::mock::{
|
||||
new_test_ext,
|
||||
Initializer, System, Dmp, Paras, Configuration, MockGenesisConfig,
|
||||
Initializer, System, Dmp, Paras, Configuration, SessionInfo, MockGenesisConfig,
|
||||
};
|
||||
|
||||
use frame_support::{
|
||||
@@ -274,6 +280,24 @@ mod tests {
|
||||
traits::{OnFinalize, OnInitialize},
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn session_0_is_instantly_applied() {
|
||||
new_test_ext(Default::default()).execute_with(|| {
|
||||
Initializer::on_new_session(
|
||||
false,
|
||||
0,
|
||||
Vec::new().into_iter(),
|
||||
Some(Vec::new().into_iter()),
|
||||
);
|
||||
|
||||
let v = <BufferedSessionChanges>::get();
|
||||
assert!(v.is_empty());
|
||||
|
||||
assert_eq!(SessionInfo::earliest_stored_session(), 0);
|
||||
assert!(SessionInfo::session_info(0).is_some());
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn session_change_before_initialize_is_still_buffered_after() {
|
||||
new_test_ext(Default::default()).execute_with(|| {
|
||||
|
||||
Reference in New Issue
Block a user