avoid expect, on free availability core (#3994)

* MVP fix

* bump spec version rococo

* fmt

* better var names

* remove duplicate desc

* expand comment
This commit is contained in:
Bernhard Schuster
2021-10-03 13:09:53 +02:00
committed by GitHub
parent c48b2f08ad
commit 5a1dc74a9a
2 changed files with 25 additions and 13 deletions
+24 -12
View File
@@ -240,8 +240,10 @@ impl<T: Config> Pallet<T> {
for _ in <AvailabilityBitfields<T>>::drain() {} for _ in <AvailabilityBitfields<T>>::drain() {}
} }
/// Process a set of incoming bitfields. Return a `vec` of cores freed by candidates /// Process a set of incoming bitfields.
/// becoming available. ///
/// Returns a `Vec` of `CandidateHash`es and their respective `AvailabilityCore`s that became available,
/// and cores free.
pub(crate) fn process_bitfields( pub(crate) fn process_bitfields(
expected_bits: usize, expected_bits: usize,
unchecked_bitfields: UncheckedSignedAvailabilityBitfields, unchecked_bitfields: UncheckedSignedAvailabilityBitfields,
@@ -250,10 +252,12 @@ impl<T: Config> Pallet<T> {
let validators = shared::Pallet::<T>::active_validator_keys(); let validators = shared::Pallet::<T>::active_validator_keys();
let session_index = shared::Pallet::<T>::session_index(); let session_index = shared::Pallet::<T>::session_index();
let mut assigned_paras_record: Vec<_> = (0..expected_bits) let mut assigned_paras_record = (0..expected_bits)
.map(|bit_index| core_lookup(CoreIndex::from(bit_index as u32))) .map(|bit_index| core_lookup(CoreIndex::from(bit_index as u32)))
.map(|core_para| core_para.map(|p| (p, PendingAvailability::<T>::get(&p)))) .map(|opt_para_id| {
.collect(); opt_para_id.map(|para_id| (para_id, PendingAvailability::<T>::get(&para_id)))
})
.collect::<Vec<_>>();
// do sanity checks on the bitfields: // do sanity checks on the bitfields:
// 1. no more than one bitfield per validator // 1. no more than one bitfield per validator
@@ -320,17 +324,25 @@ impl<T: Config> Pallet<T> {
for (bit_idx, _) in for (bit_idx, _) in
signed_bitfield.payload().0.iter().enumerate().filter(|(_, is_av)| **is_av) signed_bitfield.payload().0.iter().enumerate().filter(|(_, is_av)| **is_av)
{ {
let (_, pending_availability) = assigned_paras_record[bit_idx] let pending_availability = if let Some((_, pending_availability)) =
.as_mut() assigned_paras_record[bit_idx].as_mut()
.expect("validator bitfields checked not to contain bits corresponding to unoccupied cores; qed"); {
pending_availability
} else {
// For honest validators, this happens in case of unoccupied cores,
// which in turn happens in case of a disputed candidate.
// A malicious one might include arbitrary indices, but they are represented
// by `None` values and will be sorted out in the next if case.
continue
};
// defensive check - this is constructed by loading the availability bitfield record, // defensive check - this is constructed by loading the availability bitfield record,
// which is always `Some` if the core is occupied - that's why we're here. // which is always `Some` if the core is occupied - that's why we're here.
let val_idx = signed_bitfield.validator_index().0 as usize; let val_idx = signed_bitfield.validator_index().0 as usize;
if let Some(mut bit) = pending_availability if let Some(mut bit) =
.as_mut() pending_availability.as_mut().and_then(|candidate_pending_availability| {
.and_then(|r| r.availability_votes.get_mut(val_idx)) candidate_pending_availability.availability_votes.get_mut(val_idx)
{ }) {
*bit = true; *bit = true;
} else if cfg!(debug_assertions) { } else if cfg!(debug_assertions) {
ensure!(false, Error::<T>::InternalError); ensure!(false, Error::<T>::InternalError);
+1 -1
View File
@@ -105,7 +105,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("rococo"), spec_name: create_runtime_str!("rococo"),
impl_name: create_runtime_str!("parity-rococo-v1.8"), impl_name: create_runtime_str!("parity-rococo-v1.8"),
authoring_version: 0, authoring_version: 0,
spec_version: 9104, spec_version: 9105,
impl_version: 0, impl_version: 0,
#[cfg(not(feature = "disable-runtime-api"))] #[cfg(not(feature = "disable-runtime-api"))]
apis: RUNTIME_API_VERSIONS, apis: RUNTIME_API_VERSIONS,