style: Migrate to stable-only rustfmt configuration
- Remove nightly-only features from .rustfmt.toml and vendor/ss58-registry/rustfmt.toml - Removed features: imports_granularity, wrap_comments, comment_width, reorder_impl_items, spaces_around_ranges, binop_separator, match_arm_blocks, trailing_semicolon, trailing_comma - Format all 898 affected files with stable rustfmt - Ensures long-term reliability without nightly toolchain dependency
This commit is contained in:
@@ -551,7 +551,10 @@ async fn construct_and_distribute_receipt(
|
||||
// As such, honest collators never produce an uncompressed PoV which starts with
|
||||
// a compression magic number, which would lead validators to reject the collation.
|
||||
if encoded_size > validation_data.max_pov_size as usize {
|
||||
return Err(Error::POVSizeExceeded(encoded_size, validation_data.max_pov_size as usize));
|
||||
return Err(Error::POVSizeExceeded(
|
||||
encoded_size,
|
||||
validation_data.max_pov_size as usize,
|
||||
));
|
||||
}
|
||||
|
||||
pov
|
||||
|
||||
@@ -519,7 +519,7 @@ fn validator_index_for_msg(
|
||||
) {
|
||||
match msg {
|
||||
pezkuwi_node_network_protocol::ValidationProtocols::V3(ref message) => match message {
|
||||
pezkuwi_node_network_protocol::v3::ApprovalDistributionMessage::Assignments(msgs) =>
|
||||
pezkuwi_node_network_protocol::v3::ApprovalDistributionMessage::Assignments(msgs) => {
|
||||
if let Ok(validator) = msgs.iter().map(|(msg, _)| msg.validator).all_equal_value() {
|
||||
(Some((validator, msg)), None)
|
||||
} else {
|
||||
@@ -537,8 +537,9 @@ fn validator_index_for_msg(
|
||||
})
|
||||
.collect_vec();
|
||||
(None, Some(split))
|
||||
},
|
||||
pezkuwi_node_network_protocol::v3::ApprovalDistributionMessage::Approvals(msgs) =>
|
||||
}
|
||||
},
|
||||
pezkuwi_node_network_protocol::v3::ApprovalDistributionMessage::Approvals(msgs) => {
|
||||
if let Ok(validator) = msgs.iter().map(|msg| msg.validator).all_equal_value() {
|
||||
(Some((validator, msg)), None)
|
||||
} else {
|
||||
@@ -556,7 +557,8 @@ fn validator_index_for_msg(
|
||||
})
|
||||
.collect_vec();
|
||||
(None, Some(split))
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -733,8 +735,9 @@ impl<T: Send + Sync + 'static + Debug> overseer::SubsystemSender<T> for ToWorker
|
||||
{
|
||||
match P::priority() {
|
||||
pezkuwi_overseer::PriorityLevel::Normal => self.send_message(msg),
|
||||
pezkuwi_overseer::PriorityLevel::High =>
|
||||
async { self.send_unbounded_message(msg) }.boxed(),
|
||||
pezkuwi_overseer::PriorityLevel::High => {
|
||||
async { self.send_unbounded_message(msg) }.boxed()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -821,10 +824,12 @@ impl<S: SubsystemSender<ApprovalVotingParallelMessage>>
|
||||
) -> Result<(), metered::TrySendError<ApprovalDistributionMessage>> {
|
||||
self.0.try_send_message(msg.into()).map_err(|err| match err {
|
||||
// Safe to unwrap because it was built from the same type.
|
||||
metered::TrySendError::Closed(msg) =>
|
||||
metered::TrySendError::Closed(msg.try_into().unwrap()),
|
||||
metered::TrySendError::Full(msg) =>
|
||||
metered::TrySendError::Full(msg.try_into().unwrap()),
|
||||
metered::TrySendError::Closed(msg) => {
|
||||
metered::TrySendError::Closed(msg.try_into().unwrap())
|
||||
},
|
||||
metered::TrySendError::Full(msg) => {
|
||||
metered::TrySendError::Full(msg.try_into().unwrap())
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -869,10 +874,12 @@ impl<S: SubsystemSender<ApprovalVotingParallelMessage>>
|
||||
) -> Result<(), metered::TrySendError<ApprovalDistributionMessage>> {
|
||||
self.0.try_send_message_with_priority::<P>(msg.into()).map_err(|err| match err {
|
||||
// Safe to unwrap because it was built from the same type.
|
||||
metered::TrySendError::Closed(msg) =>
|
||||
metered::TrySendError::Closed(msg.try_into().unwrap()),
|
||||
metered::TrySendError::Full(msg) =>
|
||||
metered::TrySendError::Full(msg.try_into().unwrap()),
|
||||
metered::TrySendError::Closed(msg) => {
|
||||
metered::TrySendError::Closed(msg.try_into().unwrap())
|
||||
},
|
||||
metered::TrySendError::Full(msg) => {
|
||||
metered::TrySendError::Full(msg.try_into().unwrap())
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,8 +93,9 @@ impl Check {
|
||||
pub fn is_approved(&self, max_assignment_tick: Tick) -> bool {
|
||||
match *self {
|
||||
Check::Unapproved => false,
|
||||
Check::Approved(_, last_assignment_tick) =>
|
||||
last_assignment_tick.map_or(true, |t| t <= max_assignment_tick),
|
||||
Check::Approved(_, last_assignment_tick) => {
|
||||
last_assignment_tick.map_or(true, |t| t <= max_assignment_tick)
|
||||
},
|
||||
Check::ApprovedOneThird => true,
|
||||
}
|
||||
}
|
||||
@@ -304,8 +305,8 @@ impl State {
|
||||
// validators.
|
||||
// If there are a lot then we've got bigger problems and no need to make this
|
||||
// array unnecessarily large.
|
||||
if self.no_show_validators.len() + no_show_validators.len() <
|
||||
MAX_RECORDED_NO_SHOW_VALIDATORS_PER_CANDIDATE
|
||||
if self.no_show_validators.len() + no_show_validators.len()
|
||||
< MAX_RECORDED_NO_SHOW_VALIDATORS_PER_CANDIDATE
|
||||
{
|
||||
self.no_show_validators.extend(no_show_validators);
|
||||
}
|
||||
|
||||
@@ -409,8 +409,9 @@ fn canonicalize_works() {
|
||||
.is_none());
|
||||
continue;
|
||||
},
|
||||
Some(i) =>
|
||||
(load_block_entry_v2(store.as_ref(), &TEST_CONFIG, &hash).unwrap().unwrap(), i),
|
||||
Some(i) => {
|
||||
(load_block_entry_v2(store.as_ref(), &TEST_CONFIG, &hash).unwrap().unwrap(), i)
|
||||
},
|
||||
};
|
||||
|
||||
assert_eq!(entry.candidates.len(), with_candidates.len());
|
||||
|
||||
@@ -415,8 +415,9 @@ fn canonicalize_works() {
|
||||
.is_none());
|
||||
continue;
|
||||
},
|
||||
Some(i) =>
|
||||
(load_block_entry(store.as_ref(), &TEST_CONFIG, &hash).unwrap().unwrap(), i),
|
||||
Some(i) => {
|
||||
(load_block_entry(store.as_ref(), &TEST_CONFIG, &hash).unwrap().unwrap(), i)
|
||||
},
|
||||
};
|
||||
|
||||
assert_eq!(entry.candidates.len(), with_candidates.len());
|
||||
|
||||
@@ -132,10 +132,10 @@ impl<'a, B: 'a + Backend> OverlayedBackend<'a, B> {
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.block_entries.is_empty() &&
|
||||
self.candidate_entries.is_empty() &&
|
||||
self.blocks_at_height.is_empty() &&
|
||||
self.stored_block_range == BlockRangeStatus::NotModified
|
||||
self.block_entries.is_empty()
|
||||
&& self.candidate_entries.is_empty()
|
||||
&& self.blocks_at_height.is_empty()
|
||||
&& self.stored_block_range == BlockRangeStatus::NotModified
|
||||
}
|
||||
|
||||
pub fn load_all_blocks(&self) -> SubsystemResult<Vec<Hash>> {
|
||||
|
||||
@@ -241,9 +241,9 @@ pub fn compute_assignments(
|
||||
leaving_cores: impl IntoIterator<Item = (CandidateHash, CoreIndex, GroupIndex)> + Clone,
|
||||
enable_v2_assignments: bool,
|
||||
) -> HashMap<CoreIndex, OurAssignment> {
|
||||
if config.n_cores == 0 ||
|
||||
config.assignment_keys.is_empty() ||
|
||||
config.validator_groups.is_empty()
|
||||
if config.n_cores == 0
|
||||
|| config.assignment_keys.is_empty()
|
||||
|| config.validator_groups.is_empty()
|
||||
{
|
||||
gum::trace!(
|
||||
target: LOG_TARGET,
|
||||
@@ -262,8 +262,9 @@ pub fn compute_assignments(
|
||||
Ok(Some(pair)) => Some((ValidatorIndex(i as _), pair)),
|
||||
Ok(None) => None,
|
||||
Err(pezsc_keystore::Error::Unavailable) => None,
|
||||
Err(pezsc_keystore::Error::Io(e)) if e.kind() == std::io::ErrorKind::NotFound =>
|
||||
None,
|
||||
Err(pezsc_keystore::Error::Io(e)) if e.kind() == std::io::ErrorKind::NotFound => {
|
||||
None
|
||||
},
|
||||
Err(e) => {
|
||||
gum::warn!(target: LOG_TARGET, "Encountered keystore error: {:?}", e);
|
||||
None
|
||||
@@ -504,13 +505,14 @@ fn compute_relay_vrf_delay_assignments(
|
||||
let _ = e.insert(our_assignment);
|
||||
true
|
||||
},
|
||||
Entry::Occupied(mut e) =>
|
||||
Entry::Occupied(mut e) => {
|
||||
if e.get().tranche() > our_assignment.tranche() {
|
||||
e.insert(our_assignment);
|
||||
true
|
||||
} else {
|
||||
false
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
if used {
|
||||
@@ -556,8 +558,8 @@ pub(crate) fn check_assignment_cert(
|
||||
.map_err(|_| InvalidAssignment(Reason::InvalidAssignmentKey))?;
|
||||
|
||||
// Check that we have all backing groups for claimed cores.
|
||||
if claimed_core_indices.count_ones() == 0 ||
|
||||
claimed_core_indices.count_ones() != backing_groups.len()
|
||||
if claimed_core_indices.count_ones() == 0
|
||||
|| claimed_core_indices.count_ones() != backing_groups.len()
|
||||
{
|
||||
return Err(InvalidAssignment(Reason::InvalidArguments));
|
||||
}
|
||||
@@ -1070,8 +1072,8 @@ mod tests {
|
||||
fn check_rejects_modulo_core_wrong() {
|
||||
check_mutated_assignments(200, 100, 25, |m| {
|
||||
match m.cert.kind.clone() {
|
||||
AssignmentCertKindV2::RelayVRFModulo { .. } |
|
||||
AssignmentCertKindV2::RelayVRFModuloCompact { .. } => {
|
||||
AssignmentCertKindV2::RelayVRFModulo { .. }
|
||||
| AssignmentCertKindV2::RelayVRFModuloCompact { .. } => {
|
||||
m.cores = CoreIndex((m.cores.first_one().unwrap() + 1) as u32 % 100).into();
|
||||
|
||||
Some(false)
|
||||
|
||||
@@ -135,15 +135,17 @@ async fn imported_block_info<Sender: SubsystemSender<RuntimeApiMessage>>(
|
||||
let events: Vec<CandidateEvent> = match c_rx.await {
|
||||
Ok(Ok(events)) => events,
|
||||
Ok(Err(error)) => return Err(ImportedBlockInfoError::RuntimeError(error)),
|
||||
Err(error) =>
|
||||
return Err(ImportedBlockInfoError::FutureCancelled("CandidateEvents", error)),
|
||||
Err(error) => {
|
||||
return Err(ImportedBlockInfoError::FutureCancelled("CandidateEvents", error))
|
||||
},
|
||||
};
|
||||
|
||||
events
|
||||
.into_iter()
|
||||
.filter_map(|e| match e {
|
||||
CandidateEvent::CandidateIncluded(receipt, _, core, group) =>
|
||||
Some((receipt.hash(), receipt, core, group)),
|
||||
CandidateEvent::CandidateIncluded(receipt, _, core, group) => {
|
||||
Some((receipt.hash(), receipt, core, group))
|
||||
},
|
||||
_ => None,
|
||||
})
|
||||
.collect()
|
||||
@@ -163,8 +165,9 @@ async fn imported_block_info<Sender: SubsystemSender<RuntimeApiMessage>>(
|
||||
let session_index = match s_rx.await {
|
||||
Ok(Ok(s)) => s,
|
||||
Ok(Err(error)) => return Err(ImportedBlockInfoError::RuntimeError(error)),
|
||||
Err(error) =>
|
||||
return Err(ImportedBlockInfoError::FutureCancelled("SessionIndexForChild", error)),
|
||||
Err(error) => {
|
||||
return Err(ImportedBlockInfoError::FutureCancelled("SessionIndexForChild", error))
|
||||
},
|
||||
};
|
||||
|
||||
// We can't determine if the block is finalized or not - try processing it
|
||||
@@ -214,8 +217,9 @@ async fn imported_block_info<Sender: SubsystemSender<RuntimeApiMessage>>(
|
||||
match s_rx.await {
|
||||
Ok(Ok(s)) => s,
|
||||
Ok(Err(error)) => return Err(ImportedBlockInfoError::RuntimeError(error)),
|
||||
Err(error) =>
|
||||
return Err(ImportedBlockInfoError::FutureCancelled("CurrentBabeEpoch", error)),
|
||||
Err(error) => {
|
||||
return Err(ImportedBlockInfoError::FutureCancelled("CurrentBabeEpoch", error))
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -941,8 +941,8 @@ impl NoShowStats {
|
||||
// Print the no-show stats if NO_SHOW_DUMP_FREQUENCY blocks have passed since the last
|
||||
// print.
|
||||
fn maybe_print(&mut self, current_block_number: BlockNumber) {
|
||||
if self.last_dumped_block_number > current_block_number ||
|
||||
current_block_number - self.last_dumped_block_number < NO_SHOW_DUMP_FREQUENCY
|
||||
if self.last_dumped_block_number > current_block_number
|
||||
|| current_block_number - self.last_dumped_block_number < NO_SHOW_DUMP_FREQUENCY
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1763,10 +1763,12 @@ fn get_core_indices_on_startup(
|
||||
) -> CoreBitfield {
|
||||
match &assignment {
|
||||
AssignmentCertKindV2::RelayVRFModuloCompact { core_bitfield } => core_bitfield.clone(),
|
||||
AssignmentCertKindV2::RelayVRFModulo { sample: _ } =>
|
||||
CoreBitfield::try_from(vec![block_entry_core_index]).expect("Not an empty vec; qed"),
|
||||
AssignmentCertKindV2::RelayVRFDelay { core_index } =>
|
||||
CoreBitfield::try_from(vec![*core_index]).expect("Not an empty vec; qed"),
|
||||
AssignmentCertKindV2::RelayVRFModulo { sample: _ } => {
|
||||
CoreBitfield::try_from(vec![block_entry_core_index]).expect("Not an empty vec; qed")
|
||||
},
|
||||
AssignmentCertKindV2::RelayVRFDelay { core_index } => {
|
||||
CoreBitfield::try_from(vec![*core_index]).expect("Not an empty vec; qed")
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1779,8 +1781,9 @@ fn get_assignment_core_indices(
|
||||
block_entry: &BlockEntry,
|
||||
) -> Option<CoreBitfield> {
|
||||
match &assignment {
|
||||
AssignmentCertKindV2::RelayVRFModuloCompact { core_bitfield } =>
|
||||
Some(core_bitfield.clone()),
|
||||
AssignmentCertKindV2::RelayVRFModuloCompact { core_bitfield } => {
|
||||
Some(core_bitfield.clone())
|
||||
},
|
||||
AssignmentCertKindV2::RelayVRFModulo { sample: _ } => block_entry
|
||||
.candidates()
|
||||
.iter()
|
||||
@@ -1788,8 +1791,9 @@ fn get_assignment_core_indices(
|
||||
.map(|(core_index, _candidate_hash)| {
|
||||
CoreBitfield::try_from(vec![*core_index]).expect("Not an empty vec; qed")
|
||||
}),
|
||||
AssignmentCertKindV2::RelayVRFDelay { core_index } =>
|
||||
Some(CoreBitfield::try_from(vec![*core_index]).expect("Not an empty vec; qed")),
|
||||
AssignmentCertKindV2::RelayVRFDelay { core_index } => {
|
||||
Some(CoreBitfield::try_from(vec![*core_index]).expect("Not an empty vec; qed"))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2701,13 +2705,14 @@ where
|
||||
|
||||
let block_entry = match db.load_block_entry(&assignment.block_hash)? {
|
||||
Some(b) => b,
|
||||
None =>
|
||||
None => {
|
||||
return Ok((
|
||||
AssignmentCheckResult::Bad(AssignmentCheckError::UnknownBlock(
|
||||
assignment.block_hash,
|
||||
)),
|
||||
Vec::new(),
|
||||
)),
|
||||
))
|
||||
},
|
||||
};
|
||||
|
||||
let session_info = match get_session_info_by_index(
|
||||
@@ -2719,13 +2724,14 @@ where
|
||||
.await
|
||||
{
|
||||
Some(s) => s,
|
||||
None =>
|
||||
None => {
|
||||
return Ok((
|
||||
AssignmentCheckResult::Bad(AssignmentCheckError::UnknownSessionIndex(
|
||||
block_entry.session(),
|
||||
)),
|
||||
Vec::new(),
|
||||
)),
|
||||
))
|
||||
},
|
||||
};
|
||||
|
||||
let n_cores = session_info.n_cores as usize;
|
||||
@@ -2756,25 +2762,27 @@ where
|
||||
let (claimed_core_index, assigned_candidate_hash) =
|
||||
match block_entry.candidate(candidate_index) {
|
||||
Some((c, h)) => (*c, *h),
|
||||
None =>
|
||||
None => {
|
||||
return Ok((
|
||||
AssignmentCheckResult::Bad(AssignmentCheckError::InvalidCandidateIndex(
|
||||
candidate_index as _,
|
||||
)),
|
||||
Vec::new(),
|
||||
)), // no candidate at core.
|
||||
))
|
||||
}, // no candidate at core.
|
||||
};
|
||||
|
||||
let mut candidate_entry = match db.load_candidate_entry(&assigned_candidate_hash)? {
|
||||
Some(c) => c,
|
||||
None =>
|
||||
None => {
|
||||
return Ok((
|
||||
AssignmentCheckResult::Bad(AssignmentCheckError::InvalidCandidate(
|
||||
candidate_index as _,
|
||||
assigned_candidate_hash,
|
||||
)),
|
||||
Vec::new(),
|
||||
)), // no candidate at core.
|
||||
))
|
||||
}, // no candidate at core.
|
||||
};
|
||||
|
||||
if candidate_entry.approval_entry_mut(&assignment.block_hash).is_none() {
|
||||
@@ -2811,26 +2819,28 @@ where
|
||||
{
|
||||
let mut candidate_entry = match db.load_candidate_entry(&assigned_candidate_hash)? {
|
||||
Some(c) => c,
|
||||
None =>
|
||||
None => {
|
||||
return Ok((
|
||||
AssignmentCheckResult::Bad(AssignmentCheckError::InvalidCandidate(
|
||||
candidate_index as _,
|
||||
*assigned_candidate_hash,
|
||||
)),
|
||||
Vec::new(),
|
||||
)),
|
||||
))
|
||||
},
|
||||
};
|
||||
|
||||
let approval_entry = match candidate_entry.approval_entry_mut(&assignment.block_hash) {
|
||||
Some(a) => a,
|
||||
None =>
|
||||
None => {
|
||||
return Ok((
|
||||
AssignmentCheckResult::Bad(AssignmentCheckError::Internal(
|
||||
assignment.block_hash,
|
||||
*assigned_candidate_hash,
|
||||
)),
|
||||
Vec::new(),
|
||||
)),
|
||||
))
|
||||
},
|
||||
};
|
||||
|
||||
let is_duplicate_for_candidate = approval_entry.is_assigned(assignment.validator);
|
||||
@@ -3024,8 +3034,8 @@ enum ApprovalStateTransition {
|
||||
impl ApprovalStateTransition {
|
||||
fn validator_index(&self) -> Option<ValidatorIndex> {
|
||||
match *self {
|
||||
ApprovalStateTransition::RemoteApproval(v) |
|
||||
ApprovalStateTransition::LocalApproval(v) => Some(v),
|
||||
ApprovalStateTransition::RemoteApproval(v)
|
||||
| ApprovalStateTransition::LocalApproval(v) => Some(v),
|
||||
ApprovalStateTransition::WakeupProcessed => None,
|
||||
}
|
||||
}
|
||||
@@ -3210,9 +3220,9 @@ where
|
||||
.as_ref()
|
||||
.map(|validator_index| fork_approval_entry.is_assigned(*validator_index))
|
||||
.unwrap_or_default();
|
||||
if wakeups.wakeup_for(*fork_block_hash, candidate_hash).is_none() &&
|
||||
!fork_approval_entry.is_approved() &&
|
||||
assigned_on_fork_block
|
||||
if wakeups.wakeup_for(*fork_block_hash, candidate_hash).is_none()
|
||||
&& !fork_approval_entry.is_approved()
|
||||
&& assigned_on_fork_block
|
||||
{
|
||||
let fork_block_entry = db.load_block_entry(fork_block_hash);
|
||||
if let Ok(Some(fork_block_entry)) = fork_block_entry {
|
||||
@@ -3275,8 +3285,8 @@ fn should_trigger_assignment(
|
||||
RequiredTranches::Pending { maximum_broadcast, clock_drift, .. } => {
|
||||
let drifted_tranche_now =
|
||||
tranche_now.saturating_sub(clock_drift as DelayTranche);
|
||||
assignment.tranche() <= maximum_broadcast &&
|
||||
assignment.tranche() <= drifted_tranche_now
|
||||
assignment.tranche() <= maximum_broadcast
|
||||
&& assignment.tranche() <= drifted_tranche_now
|
||||
},
|
||||
RequiredTranches::Exact { .. } => {
|
||||
// indicates that no new assignments are needed at the moment.
|
||||
|
||||
@@ -642,8 +642,8 @@ impl BlockEntry {
|
||||
.map(|val| val.sign_no_later_than_tick);
|
||||
|
||||
if let Some(sign_no_later_than_tick) = sign_no_later_than_tick {
|
||||
if sign_no_later_than_tick <= tick_now ||
|
||||
self.num_candidates_pending_signature() >= max_approval_coalesce_count as usize
|
||||
if sign_no_later_than_tick <= tick_now
|
||||
|| self.num_candidates_pending_signature() >= max_approval_coalesce_count as usize
|
||||
{
|
||||
(
|
||||
self.candidate_indices_pending_signature().and_then(|candidate_indices| {
|
||||
|
||||
@@ -5722,8 +5722,8 @@ fn test_gathering_assignments_statements() {
|
||||
CandidateHash(Hash::repeat_byte(i as u8)),
|
||||
);
|
||||
assert!(
|
||||
state.per_block_assignments_gathering_times.len() <=
|
||||
MAX_BLOCKS_WITH_ASSIGNMENT_TIMESTAMPS as usize
|
||||
state.per_block_assignments_gathering_times.len()
|
||||
<= MAX_BLOCKS_WITH_ASSIGNMENT_TIMESTAMPS as usize
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
|
||||
@@ -1263,8 +1263,8 @@ async fn has_all_chunks(
|
||||
expect_present: bool,
|
||||
) -> bool {
|
||||
for i in 0..n_validators {
|
||||
if query_chunk(virtual_overseer, candidate_hash, ValidatorIndex(i)).await.is_some() !=
|
||||
expect_present
|
||||
if query_chunk(virtual_overseer, candidate_hash, ValidatorIndex(i)).await.is_some()
|
||||
!= expect_present
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -831,7 +831,7 @@ async fn validate_and_make_available(
|
||||
|
||||
let pov = match pov {
|
||||
PoVData::Ready(pov) => pov,
|
||||
PoVData::FetchFromValidator { from_validator, candidate_hash, pov_hash } =>
|
||||
PoVData::FetchFromValidator { from_validator, candidate_hash, pov_hash } => {
|
||||
match request_pov(
|
||||
&mut sender,
|
||||
relay_parent,
|
||||
@@ -854,7 +854,8 @@ async fn validate_and_make_available(
|
||||
},
|
||||
Err(err) => return Err(err),
|
||||
Ok(pov) => pov,
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
let v = {
|
||||
@@ -945,10 +946,12 @@ async fn handle_communication<Context>(
|
||||
CandidateBackingMessage::Statement(relay_parent, statement) => {
|
||||
handle_statement_message(ctx, state, relay_parent, statement, metrics).await?;
|
||||
},
|
||||
CandidateBackingMessage::GetBackableCandidates(requested_candidates, tx) =>
|
||||
handle_get_backable_candidates_message(state, requested_candidates, tx, metrics)?,
|
||||
CandidateBackingMessage::CanSecond(request, tx) =>
|
||||
handle_can_second_request(ctx, state, request, tx).await,
|
||||
CandidateBackingMessage::GetBackableCandidates(requested_candidates, tx) => {
|
||||
handle_get_backable_candidates_message(state, requested_candidates, tx, metrics)?
|
||||
},
|
||||
CandidateBackingMessage::CanSecond(request, tx) => {
|
||||
handle_can_second_request(ctx, state, request, tx).await
|
||||
},
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -51,8 +51,9 @@ struct TestLeaf {
|
||||
|
||||
fn table_statement_to_primitive(statement: TableStatement) -> Statement {
|
||||
match statement {
|
||||
TableStatement::Seconded(committed_candidate_receipt) =>
|
||||
Statement::Seconded(committed_candidate_receipt),
|
||||
TableStatement::Seconded(committed_candidate_receipt) => {
|
||||
Statement::Seconded(committed_candidate_receipt)
|
||||
},
|
||||
TableStatement::Valid(candidate_hash) => Statement::Valid(candidate_hash),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -421,8 +421,9 @@ async fn handle_active_leaves_update<Sender>(
|
||||
|
||||
if let Some(activated) = update.activated {
|
||||
let maybe_new_session_index = match (prepare_state.session_index, maybe_session_index) {
|
||||
(Some(existing_index), Some(new_index)) =>
|
||||
(new_index > existing_index).then_some(new_index),
|
||||
(Some(existing_index), Some(new_index)) => {
|
||||
(new_index > existing_index).then_some(new_index)
|
||||
},
|
||||
(None, Some(new_index)) => Some(new_index),
|
||||
_ => None,
|
||||
};
|
||||
@@ -837,12 +838,13 @@ where
|
||||
|
||||
match validation_backend.precheck_pvf(pvf).await {
|
||||
Ok(_) => PreCheckOutcome::Valid,
|
||||
Err(prepare_err) =>
|
||||
Err(prepare_err) => {
|
||||
if prepare_err.is_deterministic() {
|
||||
PreCheckOutcome::Invalid
|
||||
} else {
|
||||
PreCheckOutcome::Failed
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -875,10 +877,11 @@ async fn validate_candidate_exhaustive(
|
||||
|
||||
// We only check the session index for backing.
|
||||
match (exec_kind, candidate_receipt.descriptor.session_index()) {
|
||||
(PvfExecKind::Backing(_) | PvfExecKind::BackingSystemParas(_), Some(session_index)) =>
|
||||
(PvfExecKind::Backing(_) | PvfExecKind::BackingSystemParas(_), Some(session_index)) => {
|
||||
if session_index != expected_session_index {
|
||||
return Ok(ValidationResult::Invalid(InvalidCandidate::InvalidSessionIndex));
|
||||
},
|
||||
}
|
||||
},
|
||||
(_, _) => {},
|
||||
};
|
||||
|
||||
@@ -918,7 +921,7 @@ async fn validate_candidate_exhaustive(
|
||||
)
|
||||
.await
|
||||
},
|
||||
PvfExecKind::Approval | PvfExecKind::Dispute =>
|
||||
PvfExecKind::Approval | PvfExecKind::Dispute => {
|
||||
validation_backend
|
||||
.validate_candidate_with_retry(
|
||||
validation_code.0,
|
||||
@@ -931,7 +934,8 @@ async fn validate_candidate_exhaustive(
|
||||
exec_kind,
|
||||
validation_code_bomb_limit,
|
||||
)
|
||||
.await,
|
||||
.await
|
||||
},
|
||||
};
|
||||
|
||||
if let Err(ref error) = result {
|
||||
@@ -949,27 +953,35 @@ async fn validate_candidate_exhaustive(
|
||||
);
|
||||
Err(ValidationFailed(e.to_string()))
|
||||
},
|
||||
Err(ValidationError::Invalid(WasmInvalidCandidate::HardTimeout)) =>
|
||||
Ok(ValidationResult::Invalid(InvalidCandidate::Timeout)),
|
||||
Err(ValidationError::Invalid(WasmInvalidCandidate::WorkerReportedInvalid(e))) =>
|
||||
Ok(ValidationResult::Invalid(InvalidCandidate::ExecutionError(e))),
|
||||
Err(ValidationError::Invalid(WasmInvalidCandidate::PoVDecompressionFailure)) =>
|
||||
Ok(ValidationResult::Invalid(InvalidCandidate::PoVDecompressionFailure)),
|
||||
Err(ValidationError::PossiblyInvalid(PossiblyInvalidError::AmbiguousWorkerDeath)) =>
|
||||
Err(ValidationError::Invalid(WasmInvalidCandidate::HardTimeout)) => {
|
||||
Ok(ValidationResult::Invalid(InvalidCandidate::Timeout))
|
||||
},
|
||||
Err(ValidationError::Invalid(WasmInvalidCandidate::WorkerReportedInvalid(e))) => {
|
||||
Ok(ValidationResult::Invalid(InvalidCandidate::ExecutionError(e)))
|
||||
},
|
||||
Err(ValidationError::Invalid(WasmInvalidCandidate::PoVDecompressionFailure)) => {
|
||||
Ok(ValidationResult::Invalid(InvalidCandidate::PoVDecompressionFailure))
|
||||
},
|
||||
Err(ValidationError::PossiblyInvalid(PossiblyInvalidError::AmbiguousWorkerDeath)) => {
|
||||
Ok(ValidationResult::Invalid(InvalidCandidate::ExecutionError(
|
||||
"ambiguous worker death".to_string(),
|
||||
))),
|
||||
Err(ValidationError::PossiblyInvalid(PossiblyInvalidError::JobError(err))) =>
|
||||
Ok(ValidationResult::Invalid(InvalidCandidate::ExecutionError(err))),
|
||||
Err(ValidationError::PossiblyInvalid(PossiblyInvalidError::RuntimeConstruction(err))) =>
|
||||
Ok(ValidationResult::Invalid(InvalidCandidate::ExecutionError(err))),
|
||||
Err(ValidationError::PossiblyInvalid(err @ PossiblyInvalidError::CorruptedArtifact)) =>
|
||||
Ok(ValidationResult::Invalid(InvalidCandidate::ExecutionError(err.to_string()))),
|
||||
)))
|
||||
},
|
||||
Err(ValidationError::PossiblyInvalid(PossiblyInvalidError::JobError(err))) => {
|
||||
Ok(ValidationResult::Invalid(InvalidCandidate::ExecutionError(err)))
|
||||
},
|
||||
Err(ValidationError::PossiblyInvalid(PossiblyInvalidError::RuntimeConstruction(err))) => {
|
||||
Ok(ValidationResult::Invalid(InvalidCandidate::ExecutionError(err)))
|
||||
},
|
||||
Err(ValidationError::PossiblyInvalid(err @ PossiblyInvalidError::CorruptedArtifact)) => {
|
||||
Ok(ValidationResult::Invalid(InvalidCandidate::ExecutionError(err.to_string())))
|
||||
},
|
||||
|
||||
Err(ValidationError::PossiblyInvalid(PossiblyInvalidError::AmbiguousJobDeath(err))) =>
|
||||
Err(ValidationError::PossiblyInvalid(PossiblyInvalidError::AmbiguousJobDeath(err))) => {
|
||||
Ok(ValidationResult::Invalid(InvalidCandidate::ExecutionError(format!(
|
||||
"ambiguous job death: {err}"
|
||||
)))),
|
||||
))))
|
||||
},
|
||||
Err(ValidationError::Preparation(e)) => {
|
||||
gum::warn!(
|
||||
target: LOG_TARGET,
|
||||
@@ -1005,8 +1017,8 @@ async fn validate_candidate_exhaustive(
|
||||
},
|
||||
};
|
||||
|
||||
if candidate_receipt.commitments_hash !=
|
||||
committed_candidate_receipt.commitments.hash()
|
||||
if candidate_receipt.commitments_hash
|
||||
!= committed_candidate_receipt.commitments.hash()
|
||||
{
|
||||
gum::info!(
|
||||
target: LOG_TARGET,
|
||||
@@ -1158,8 +1170,8 @@ trait ValidationBackend {
|
||||
let mut retry_immediately = false;
|
||||
match validation_result {
|
||||
Err(ValidationError::PossiblyInvalid(
|
||||
PossiblyInvalidError::AmbiguousWorkerDeath |
|
||||
PossiblyInvalidError::AmbiguousJobDeath(_),
|
||||
PossiblyInvalidError::AmbiguousWorkerDeath
|
||||
| PossiblyInvalidError::AmbiguousJobDeath(_),
|
||||
)) => break_if_no_retries_left!(num_death_retries_left),
|
||||
|
||||
Err(ValidationError::PossiblyInvalid(PossiblyInvalidError::JobError(_))) => {
|
||||
@@ -1171,8 +1183,8 @@ trait ValidationBackend {
|
||||
},
|
||||
|
||||
Err(ValidationError::PossiblyInvalid(
|
||||
PossiblyInvalidError::RuntimeConstruction(_) |
|
||||
PossiblyInvalidError::CorruptedArtifact,
|
||||
PossiblyInvalidError::RuntimeConstruction(_)
|
||||
| PossiblyInvalidError::CorruptedArtifact,
|
||||
)) => {
|
||||
break_if_no_retries_left!(num_execution_error_retries_left);
|
||||
self.precheck_pvf(pvf.clone()).await?;
|
||||
@@ -1183,11 +1195,11 @@ trait ValidationBackend {
|
||||
retry_immediately = true;
|
||||
},
|
||||
|
||||
Ok(_) |
|
||||
Err(
|
||||
ValidationError::Invalid(_) |
|
||||
ValidationError::Preparation(_) |
|
||||
ValidationError::ExecutionDeadline,
|
||||
Ok(_)
|
||||
| Err(
|
||||
ValidationError::Invalid(_)
|
||||
| ValidationError::Preparation(_)
|
||||
| ValidationError::ExecutionDeadline,
|
||||
) => break,
|
||||
}
|
||||
|
||||
|
||||
@@ -290,7 +290,7 @@ impl Backend for DbBackend {
|
||||
block_entry.encode(),
|
||||
);
|
||||
},
|
||||
BackendWriteOp::WriteBlocksByNumber(block_number, v) =>
|
||||
BackendWriteOp::WriteBlocksByNumber(block_number, v) => {
|
||||
if v.is_empty() {
|
||||
tx.delete(self.config.col_data, &block_height_key(block_number));
|
||||
} else {
|
||||
@@ -299,7 +299,8 @@ impl Backend for DbBackend {
|
||||
&block_height_key(block_number),
|
||||
v.encode(),
|
||||
);
|
||||
},
|
||||
}
|
||||
},
|
||||
BackendWriteOp::WriteViableLeaves(leaves) => {
|
||||
let leaves: LeafEntrySet = leaves.into();
|
||||
if leaves.inner.is_empty() {
|
||||
|
||||
@@ -224,10 +224,11 @@ fn propagate_viability_update(
|
||||
// finalized block is implicitly the viable leaf.
|
||||
continue;
|
||||
},
|
||||
Some(entry) =>
|
||||
Some(entry) => {
|
||||
if entry.children.len() == pivot_count {
|
||||
viable_leaves.insert(entry.leaf_entry());
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -86,9 +86,9 @@ impl<'a, B: 'a + Backend> OverlayedBackend<'a, B> {
|
||||
|
||||
/// Returns true if the are no write operations to perform.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.earliest_session.is_none() &&
|
||||
self.recent_disputes.is_none() &&
|
||||
self.candidate_votes.is_empty()
|
||||
self.earliest_session.is_none()
|
||||
&& self.recent_disputes.is_none()
|
||||
&& self.candidate_votes.is_empty()
|
||||
}
|
||||
|
||||
/// Load the earliest session, if any.
|
||||
|
||||
@@ -81,8 +81,9 @@ impl<'a> CandidateEnvironment<'a> {
|
||||
.get_session_info_by_index(ctx.sender(), relay_parent, session_index)
|
||||
.await
|
||||
{
|
||||
Ok(extended_session_info) =>
|
||||
(&extended_session_info.session_info, &extended_session_info.executor_params),
|
||||
Ok(extended_session_info) => {
|
||||
(&extended_session_info.session_info, &extended_session_info.executor_params)
|
||||
},
|
||||
Err(_) => return None,
|
||||
};
|
||||
|
||||
@@ -553,8 +554,8 @@ impl ImportResult {
|
||||
/// Whether or not the invalid vote count for the dispute went beyond the byzantine threshold
|
||||
/// after the last import
|
||||
pub fn has_fresh_byzantine_threshold_against(&self) -> bool {
|
||||
!self.old_state().byzantine_threshold_against &&
|
||||
self.new_state().byzantine_threshold_against
|
||||
!self.old_state().byzantine_threshold_against
|
||||
&& self.new_state().byzantine_threshold_against
|
||||
}
|
||||
|
||||
/// Modify this `ImportResult`s, by importing additional approval votes.
|
||||
|
||||
@@ -279,8 +279,9 @@ impl Initialized {
|
||||
self.scraper.process_finalized_block(&n);
|
||||
default_confirm
|
||||
},
|
||||
FromOrchestra::Communication { msg } =>
|
||||
self.handle_incoming(ctx, &mut overlay_db, msg, clock.now()).await?,
|
||||
FromOrchestra::Communication { msg } => {
|
||||
self.handle_incoming(ctx, &mut overlay_db, msg, clock.now()).await?
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -948,8 +949,9 @@ impl Initialized {
|
||||
let candidate_hash = candidate_receipt.hash();
|
||||
let votes_in_db = overlay_db.load_candidate_votes(session, &candidate_hash)?;
|
||||
let relay_parent = match &candidate_receipt {
|
||||
MaybeCandidateReceipt::Provides(candidate_receipt) =>
|
||||
candidate_receipt.descriptor().relay_parent(),
|
||||
MaybeCandidateReceipt::Provides(candidate_receipt) => {
|
||||
candidate_receipt.descriptor().relay_parent()
|
||||
},
|
||||
MaybeCandidateReceipt::AssumeBackingVotePresent(candidate_hash) => match &votes_in_db {
|
||||
Some(votes) => votes.candidate_receipt.descriptor().relay_parent(),
|
||||
None => {
|
||||
@@ -1006,7 +1008,7 @@ impl Initialized {
|
||||
// not have a `CandidateReceipt` available.
|
||||
let old_state = match votes_in_db.map(CandidateVotes::from) {
|
||||
Some(votes) => CandidateVoteState::new(votes, &env, now),
|
||||
None =>
|
||||
None => {
|
||||
if let MaybeCandidateReceipt::Provides(candidate_receipt) = candidate_receipt {
|
||||
CandidateVoteState::new_from_receipt(candidate_receipt)
|
||||
} else {
|
||||
@@ -1017,7 +1019,8 @@ impl Initialized {
|
||||
"Cannot import votes, without `CandidateReceipt` available!"
|
||||
);
|
||||
return Ok(ImportStatementsResult::InvalidImport);
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
gum::trace!(target: LOG_TARGET, ?candidate_hash, ?session, "Loaded votes");
|
||||
@@ -1026,8 +1029,8 @@ impl Initialized {
|
||||
let own_statements = statements
|
||||
.iter()
|
||||
.filter(|(statement, validator_index)| {
|
||||
controlled_indices.contains(validator_index) &&
|
||||
*statement.candidate_hash() == candidate_hash
|
||||
controlled_indices.contains(validator_index)
|
||||
&& *statement.candidate_hash() == candidate_hash
|
||||
})
|
||||
.cloned()
|
||||
.collect::<Vec<_>>();
|
||||
@@ -1039,8 +1042,8 @@ impl Initialized {
|
||||
//
|
||||
// See guide: We import on fresh disputes to maximize likelihood of fetching votes for
|
||||
// dead forks and once concluded to maximize time for approval votes to trickle in.
|
||||
if intermediate_result.is_freshly_disputed() ||
|
||||
intermediate_result.is_freshly_concluded()
|
||||
if intermediate_result.is_freshly_disputed()
|
||||
|| intermediate_result.is_freshly_concluded()
|
||||
{
|
||||
gum::trace!(
|
||||
target: LOG_TARGET,
|
||||
@@ -1587,8 +1590,8 @@ impl Initialized {
|
||||
continue;
|
||||
};
|
||||
// Check if all invalid voters (raising parties) are disabled
|
||||
if !votes.invalid.is_empty() &&
|
||||
votes.invalid.iter().all(|(_, validator_index, _)| {
|
||||
if !votes.invalid.is_empty()
|
||||
&& votes.invalid.iter().all(|(_, validator_index, _)| {
|
||||
self.offchain_disabled_validators.is_disabled(session, *validator_index)
|
||||
}) {
|
||||
disputes_to_remove.push((*dispute_session, *candidate_hash));
|
||||
@@ -1833,9 +1836,9 @@ impl OffchainDisabledValidators {
|
||||
self.per_session
|
||||
.get(&session_index)
|
||||
.map(|session_disputes| {
|
||||
session_disputes.backers_for_invalid.peek(&validator_index).is_some() ||
|
||||
session_disputes.for_invalid.peek(&validator_index).is_some() ||
|
||||
session_disputes.against_valid.peek(&validator_index).is_some()
|
||||
session_disputes.backers_for_invalid.peek(&validator_index).is_some()
|
||||
|| session_disputes.for_invalid.peek(&validator_index).is_some()
|
||||
|| session_disputes.against_valid.peek(&validator_index).is_some()
|
||||
})
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
@@ -171,10 +171,10 @@ impl PartialEq for ParticipationRequest {
|
||||
executor_params,
|
||||
request_timer: _,
|
||||
} = self;
|
||||
candidate_receipt == other.candidate_receipt() &&
|
||||
candidate_hash == other.candidate_hash() &&
|
||||
*session == other.session() &&
|
||||
executor_params.hash() == other.executor_params.hash()
|
||||
candidate_receipt == other.candidate_receipt()
|
||||
&& candidate_hash == other.candidate_hash()
|
||||
&& *session == other.session()
|
||||
&& executor_params.hash() == other.executor_params.hash()
|
||||
}
|
||||
}
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -256,8 +256,8 @@ fn reqs_get_queued_when_out_of_capacity() {
|
||||
let mut recover_available_data_msg_count = 0;
|
||||
let mut block_number_msg_count = 0;
|
||||
|
||||
while recover_available_data_msg_count < MAX_PARALLEL_PARTICIPATIONS + 1 ||
|
||||
block_number_msg_count < 1
|
||||
while recover_available_data_msg_count < MAX_PARALLEL_PARTICIPATIONS + 1
|
||||
|| block_number_msg_count < 1
|
||||
{
|
||||
match ctx_handle.recv().await {
|
||||
AllMessages::AvailabilityRecovery(
|
||||
|
||||
@@ -427,9 +427,9 @@ impl ChainScraper {
|
||||
for (block_number, hash) in block_numbers.zip(&hashes) {
|
||||
// Return if we either met target/cached block or
|
||||
// hit the size limit for the returned ancestry of head.
|
||||
if self.last_observed_blocks.get(hash).is_some() ||
|
||||
block_number <= target_ancestor ||
|
||||
ancestors.len() >= Self::ANCESTRY_SIZE_LIMIT as usize
|
||||
if self.last_observed_blocks.get(hash).is_some()
|
||||
|| block_number <= target_ancestor
|
||||
|| ancestors.len() >= Self::ANCESTRY_SIZE_LIMIT as usize
|
||||
{
|
||||
return Ok(ancestors);
|
||||
}
|
||||
|
||||
@@ -427,8 +427,8 @@ fn scraper_requests_candidates_of_non_finalized_ancestors() {
|
||||
&mut virtual_overseer,
|
||||
&chain,
|
||||
finalized_block_number,
|
||||
BLOCKS_TO_SKIP -
|
||||
(finalized_block_number - DISPUTE_CANDIDATE_LIFETIME_AFTER_FINALIZATION) as usize, /* Expect the provider not to go past finalized block. */
|
||||
BLOCKS_TO_SKIP
|
||||
- (finalized_block_number - DISPUTE_CANDIDATE_LIFETIME_AFTER_FINALIZATION) as usize, /* Expect the provider not to go past finalized block. */
|
||||
get_backed_and_included_candidate_events,
|
||||
);
|
||||
join(process_active_leaves_update(ctx.sender(), &mut ordering, next_update), overseer_fut)
|
||||
@@ -532,8 +532,8 @@ fn scraper_handles_backed_but_not_included_candidate() {
|
||||
// Bump the finalized block outside `BACKED_CANDIDATE_LIFETIME_AFTER_FINALIZATION`.
|
||||
// The candidate should be removed.
|
||||
assert!(
|
||||
finalized_block_number <
|
||||
TEST_TARGET_BLOCK_NUMBER + DISPUTE_CANDIDATE_LIFETIME_AFTER_FINALIZATION
|
||||
finalized_block_number
|
||||
< TEST_TARGET_BLOCK_NUMBER + DISPUTE_CANDIDATE_LIFETIME_AFTER_FINALIZATION
|
||||
);
|
||||
finalized_block_number +=
|
||||
TEST_TARGET_BLOCK_NUMBER + DISPUTE_CANDIDATE_LIFETIME_AFTER_FINALIZATION;
|
||||
@@ -583,8 +583,8 @@ fn scraper_handles_the_same_candidate_included_in_two_different_block_heights()
|
||||
// Finalize blocks to enforce pruning of scraped events.
|
||||
// The magic candidate was added twice, so it shouldn't be removed if we finalize two more
|
||||
// blocks.
|
||||
finalized_block_number = test_targets.first().expect("there are two block nums") +
|
||||
DISPUTE_CANDIDATE_LIFETIME_AFTER_FINALIZATION;
|
||||
finalized_block_number = test_targets.first().expect("there are two block nums")
|
||||
+ DISPUTE_CANDIDATE_LIFETIME_AFTER_FINALIZATION;
|
||||
process_finalized_block(&mut scraper, &finalized_block_number);
|
||||
|
||||
let magic_candidate = make_candidate_receipt(get_magic_candidate_hash());
|
||||
|
||||
@@ -123,8 +123,9 @@ async fn generate_opposing_votes_pair(
|
||||
valid_vote_type: VoteType,
|
||||
) -> (SignedDisputeStatement, SignedDisputeStatement) {
|
||||
let valid_vote = match valid_vote_type {
|
||||
VoteType::Backing =>
|
||||
test_state.issue_backing_statement_with_index(valid_voter_idx, candidate_hash, session),
|
||||
VoteType::Backing => {
|
||||
test_state.issue_backing_statement_with_index(valid_voter_idx, candidate_hash, session)
|
||||
},
|
||||
VoteType::Explicit => test_state.issue_explicit_statement_with_index(
|
||||
valid_voter_idx,
|
||||
candidate_hash,
|
||||
|
||||
@@ -768,8 +768,8 @@ impl FragmentChain {
|
||||
|
||||
/// Return whether this candidate is backed in this chain or the unconnected storage.
|
||||
pub fn is_candidate_backed(&self, hash: &CandidateHash) -> bool {
|
||||
self.best_chain.candidates.contains(hash) ||
|
||||
matches!(
|
||||
self.best_chain.candidates.contains(hash)
|
||||
|| matches!(
|
||||
self.unconnected.by_candidate_hash.get(hash),
|
||||
Some(candidate) if candidate.state == CandidateState::Backed
|
||||
)
|
||||
|
||||
@@ -156,10 +156,12 @@ async fn run_iteration<Context>(
|
||||
},
|
||||
FromOrchestra::Signal(OverseerSignal::BlockFinalized(..)) => {},
|
||||
FromOrchestra::Communication { msg } => match msg {
|
||||
ProspectiveTeyrchainsMessage::IntroduceSecondedCandidate(request, tx) =>
|
||||
handle_introduce_seconded_candidate(view, request, tx, metrics).await,
|
||||
ProspectiveTeyrchainsMessage::CandidateBacked(para, candidate_hash) =>
|
||||
handle_candidate_backed(view, para, candidate_hash, metrics).await,
|
||||
ProspectiveTeyrchainsMessage::IntroduceSecondedCandidate(request, tx) => {
|
||||
handle_introduce_seconded_candidate(view, request, tx, metrics).await
|
||||
},
|
||||
ProspectiveTeyrchainsMessage::CandidateBacked(para, candidate_hash) => {
|
||||
handle_candidate_backed(view, para, candidate_hash, metrics).await
|
||||
},
|
||||
ProspectiveTeyrchainsMessage::GetBackableCandidates(
|
||||
relay_parent,
|
||||
para,
|
||||
@@ -167,12 +169,15 @@ async fn run_iteration<Context>(
|
||||
ancestors,
|
||||
tx,
|
||||
) => answer_get_backable_candidates(&view, relay_parent, para, count, ancestors, tx),
|
||||
ProspectiveTeyrchainsMessage::GetHypotheticalMembership(request, tx) =>
|
||||
answer_hypothetical_membership_request(&view, request, tx, metrics),
|
||||
ProspectiveTeyrchainsMessage::GetMinimumRelayParents(relay_parent, tx) =>
|
||||
answer_minimum_relay_parents_request(&view, relay_parent, tx),
|
||||
ProspectiveTeyrchainsMessage::GetProspectiveValidationData(request, tx) =>
|
||||
answer_prospective_validation_data_request(&view, request, tx),
|
||||
ProspectiveTeyrchainsMessage::GetHypotheticalMembership(request, tx) => {
|
||||
answer_hypothetical_membership_request(&view, request, tx, metrics)
|
||||
},
|
||||
ProspectiveTeyrchainsMessage::GetMinimumRelayParents(relay_parent, tx) => {
|
||||
answer_minimum_relay_parents_request(&view, relay_parent, tx)
|
||||
},
|
||||
ProspectiveTeyrchainsMessage::GetProspectiveValidationData(request, tx) => {
|
||||
answer_prospective_validation_data_request(&view, request, tx)
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,9 +343,9 @@ async fn handle_leaf_activation(
|
||||
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
|
||||
parent,
|
||||
RuntimeApiRequest::BackingConstraints(p_id, tx),
|
||||
)) if parent == *hash &&
|
||||
test_state.runtime_api_version >=
|
||||
RuntimeApiRequest::CONSTRAINTS_RUNTIME_REQUIREMENT =>
|
||||
)) if parent == *hash
|
||||
&& test_state.runtime_api_version
|
||||
>= RuntimeApiRequest::CONSTRAINTS_RUNTIME_REQUIREMENT =>
|
||||
{
|
||||
let PerParaData { min_relay_parent, head_data, pending_availability: _ } =
|
||||
leaf.para_data(p_id);
|
||||
@@ -362,9 +362,9 @@ async fn handle_leaf_activation(
|
||||
AllMessages::RuntimeApi(RuntimeApiMessage::Request(
|
||||
parent,
|
||||
RuntimeApiRequest::BackingConstraints(_p_id, tx),
|
||||
)) if parent == *hash &&
|
||||
test_state.runtime_api_version <
|
||||
RuntimeApiRequest::CONSTRAINTS_RUNTIME_REQUIREMENT =>
|
||||
)) if parent == *hash
|
||||
&& test_state.runtime_api_version
|
||||
< RuntimeApiRequest::CONSTRAINTS_RUNTIME_REQUIREMENT =>
|
||||
{
|
||||
tx.send(Err(RUNTIME_API_NOT_SUPPORTED)).unwrap();
|
||||
None
|
||||
|
||||
@@ -332,8 +332,8 @@ fn concluded_onchain(onchain_state: &DisputeState) -> bool {
|
||||
// Check if there are enough onchain votes for or against to conclude the dispute
|
||||
let supermajority = supermajority_threshold(onchain_state.validators_for.len());
|
||||
|
||||
onchain_state.validators_for.count_ones() >= supermajority ||
|
||||
onchain_state.validators_against.count_ones() >= supermajority
|
||||
onchain_state.validators_for.count_ones() >= supermajority
|
||||
|| onchain_state.validators_against.count_ones() >= supermajority
|
||||
}
|
||||
|
||||
fn partition_recent_disputes(
|
||||
@@ -347,7 +347,7 @@ fn partition_recent_disputes(
|
||||
let key = (session_index, candidate_hash);
|
||||
if dispute_is_inactive(&dispute_state, time_now) {
|
||||
match onchain.get(&key) {
|
||||
Some(onchain_state) =>
|
||||
Some(onchain_state) => {
|
||||
if concluded_onchain(onchain_state) {
|
||||
partitioned
|
||||
.inactive_concluded_onchain
|
||||
@@ -356,16 +356,19 @@ fn partition_recent_disputes(
|
||||
partitioned
|
||||
.inactive_unconcluded_onchain
|
||||
.push((session_index, candidate_hash));
|
||||
},
|
||||
}
|
||||
},
|
||||
None => partitioned.inactive_unknown_onchain.push((session_index, candidate_hash)),
|
||||
}
|
||||
} else {
|
||||
match onchain.get(&(session_index, candidate_hash)) {
|
||||
Some(d) => match concluded_onchain(d) {
|
||||
true =>
|
||||
partitioned.active_concluded_onchain.push((session_index, candidate_hash)),
|
||||
false =>
|
||||
partitioned.active_unconcluded_onchain.push((session_index, candidate_hash)),
|
||||
true => {
|
||||
partitioned.active_concluded_onchain.push((session_index, candidate_hash))
|
||||
},
|
||||
false => {
|
||||
partitioned.active_unconcluded_onchain.push((session_index, candidate_hash))
|
||||
},
|
||||
},
|
||||
None => partitioned.active_unknown_onchain.push((session_index, candidate_hash)),
|
||||
}
|
||||
@@ -389,8 +392,8 @@ fn is_vote_worth_to_keep(
|
||||
// punished when misbehaving.
|
||||
if let Some(kind) = valid_kind {
|
||||
match kind {
|
||||
ValidDisputeStatementKind::BackingValid(_) |
|
||||
ValidDisputeStatementKind::BackingSeconded(_) => return true,
|
||||
ValidDisputeStatementKind::BackingValid(_)
|
||||
| ValidDisputeStatementKind::BackingSeconded(_) => return true,
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
@@ -491,10 +494,12 @@ where
|
||||
.map_err(|_| GetOnchainDisputesError::Channel)
|
||||
.and_then(|res| {
|
||||
res.map_err(|e| match e {
|
||||
RuntimeApiError::Execution { .. } =>
|
||||
GetOnchainDisputesError::Execution(e, relay_parent),
|
||||
RuntimeApiError::NotSupported { .. } =>
|
||||
GetOnchainDisputesError::NotSupported(e, relay_parent),
|
||||
RuntimeApiError::Execution { .. } => {
|
||||
GetOnchainDisputesError::Execution(e, relay_parent)
|
||||
},
|
||||
RuntimeApiError::NotSupported { .. } => {
|
||||
GetOnchainDisputesError::NotSupported(e, relay_parent)
|
||||
},
|
||||
})
|
||||
})
|
||||
.map(|v| v.into_iter().map(|e| ((e.0, e.1), e.2)).collect())
|
||||
|
||||
@@ -666,8 +666,8 @@ fn many_batches() {
|
||||
let vote_count = result.iter().map(|d| d.statements.len()).fold(0, |acc, v| acc + v);
|
||||
|
||||
assert!(
|
||||
MAX_DISPUTE_VOTES_FORWARDED_TO_RUNTIME - VALIDATOR_COUNT <= vote_count &&
|
||||
vote_count <= MAX_DISPUTE_VOTES_FORWARDED_TO_RUNTIME,
|
||||
MAX_DISPUTE_VOTES_FORWARDED_TO_RUNTIME - VALIDATOR_COUNT <= vote_count
|
||||
&& vote_count <= MAX_DISPUTE_VOTES_FORWARDED_TO_RUNTIME,
|
||||
"vote_count: {}",
|
||||
vote_count
|
||||
);
|
||||
@@ -720,8 +720,8 @@ fn votes_above_limit() {
|
||||
let vote_count = result.iter().map(|d| d.statements.len()).fold(0, |acc, v| acc + v);
|
||||
|
||||
assert!(
|
||||
MAX_DISPUTE_VOTES_FORWARDED_TO_RUNTIME - VALIDATOR_COUNT <= vote_count &&
|
||||
vote_count <= MAX_DISPUTE_VOTES_FORWARDED_TO_RUNTIME,
|
||||
MAX_DISPUTE_VOTES_FORWARDED_TO_RUNTIME - VALIDATOR_COUNT <= vote_count
|
||||
&& vote_count <= MAX_DISPUTE_VOTES_FORWARDED_TO_RUNTIME,
|
||||
"vote_count: {}",
|
||||
vote_count
|
||||
);
|
||||
|
||||
@@ -396,8 +396,9 @@ fn note_provisionable_data(
|
||||
provisionable_data: ProvisionableData,
|
||||
) {
|
||||
match provisionable_data {
|
||||
ProvisionableData::Bitfield(_, signed_bitfield) =>
|
||||
per_relay_parent.signed_bitfields.push(signed_bitfield),
|
||||
ProvisionableData::Bitfield(_, signed_bitfield) => {
|
||||
per_relay_parent.signed_bitfields.push(signed_bitfield)
|
||||
},
|
||||
// We choose not to punish these forms of misbehavior for the time being.
|
||||
// Risks from misbehavior are sufficiently mitigated at the protocol level
|
||||
// via reputation changes. Punitive actions here may become desirable
|
||||
|
||||
@@ -572,8 +572,9 @@ mod select_candidates {
|
||||
_parent_hash,
|
||||
PersistedValidationDataReq(_para_id, _assumption, tx),
|
||||
)) => tx.send(Ok(Some(Default::default()))).unwrap(),
|
||||
AllMessages::RuntimeApi(Request(_parent_hash, AvailabilityCores(tx))) =>
|
||||
tx.send(Ok(mock_availability_cores.clone())).unwrap(),
|
||||
AllMessages::RuntimeApi(Request(_parent_hash, AvailabilityCores(tx))) => {
|
||||
tx.send(Ok(mock_availability_cores.clone())).unwrap()
|
||||
},
|
||||
AllMessages::CandidateBacking(CandidateBackingMessage::GetBackableCandidates(
|
||||
hashes,
|
||||
sender,
|
||||
|
||||
@@ -380,14 +380,15 @@ async fn examine_activation(
|
||||
};
|
||||
|
||||
let new_session_index = match runtime_api::session_index_for_child(sender, leaf_hash).await {
|
||||
Ok(session_index) =>
|
||||
Ok(session_index) => {
|
||||
if state.latest_session.map_or(true, |l| l < session_index) {
|
||||
let signing_credentials =
|
||||
check_signing_credentials(sender, keystore, leaf_hash).await;
|
||||
Some((session_index, signing_credentials))
|
||||
} else {
|
||||
None
|
||||
},
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
gum::warn!(
|
||||
target: LOG_TARGET,
|
||||
|
||||
@@ -110,17 +110,17 @@ impl PrepareError {
|
||||
pub fn is_deterministic(&self) -> bool {
|
||||
use PrepareError::*;
|
||||
match self {
|
||||
Prevalidation(_) |
|
||||
Preparation(_) |
|
||||
JobError(_) |
|
||||
OutOfMemory |
|
||||
CouldNotDecompressCodeBlob(_) => true,
|
||||
IoErr(_) |
|
||||
JobDied { .. } |
|
||||
CreateTmpFile(_) |
|
||||
RenameTmpFile { .. } |
|
||||
ClearWorkerDir(_) |
|
||||
Kernel(_) => false,
|
||||
Prevalidation(_)
|
||||
| Preparation(_)
|
||||
| JobError(_)
|
||||
| OutOfMemory
|
||||
| CouldNotDecompressCodeBlob(_) => true,
|
||||
IoErr(_)
|
||||
| JobDied { .. }
|
||||
| CreateTmpFile(_)
|
||||
| RenameTmpFile { .. }
|
||||
| ClearWorkerDir(_)
|
||||
| Kernel(_) => false,
|
||||
// Can occur due to issues with the PVF, but also due to factors like local load.
|
||||
TimedOut => false,
|
||||
// Can occur due to issues with the PVF, but also due to local errors.
|
||||
|
||||
@@ -160,16 +160,17 @@ pub fn params_to_wasmtime_semantics(par: &ExecutorParams) -> (Semantics, Determi
|
||||
|
||||
for p in par.iter() {
|
||||
match p {
|
||||
ExecutorParam::MaxMemoryPages(max_pages) =>
|
||||
ExecutorParam::MaxMemoryPages(max_pages) => {
|
||||
sem.heap_alloc_strategy = HeapAllocStrategy::Dynamic {
|
||||
maximum_pages: Some((*max_pages).saturating_add(DEFAULT_HEAP_PAGES_ESTIMATE)),
|
||||
},
|
||||
}
|
||||
},
|
||||
ExecutorParam::StackLogicalMax(slm) => stack_limit.logical_max = *slm,
|
||||
ExecutorParam::StackNativeMax(snm) => stack_limit.native_stack_max = *snm,
|
||||
ExecutorParam::WasmExtBulkMemory => sem.wasm_bulk_memory = true,
|
||||
ExecutorParam::PrecheckingMaxMemory(_) |
|
||||
ExecutorParam::PvfPrepTimeout(_, _) |
|
||||
ExecutorParam::PvfExecTimeout(_, _) => (), /* Not used here */
|
||||
ExecutorParam::PrecheckingMaxMemory(_)
|
||||
| ExecutorParam::PvfPrepTimeout(_, _)
|
||||
| ExecutorParam::PvfExecTimeout(_, _) => (), /* Not used here */
|
||||
}
|
||||
}
|
||||
sem.deterministic_stack_limit = Some(stack_limit.clone());
|
||||
|
||||
@@ -133,8 +133,8 @@ impl fmt::Debug for PvfPrepData {
|
||||
|
||||
impl PartialEq for PvfPrepData {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.code_hash == other.code_hash &&
|
||||
self.executor_params.hash() == other.executor_params.hash()
|
||||
self.code_hash == other.code_hash
|
||||
&& self.executor_params.hash() == other.executor_params.hash()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -562,8 +562,8 @@ fn recv_worker_handshake(stream: &mut UnixStream) -> io::Result<WorkerHandshake>
|
||||
///
|
||||
/// Returns a `Duration` representing the total CPU time.
|
||||
pub fn get_total_cpu_usage(rusage: Usage) -> Duration {
|
||||
let micros = (((rusage.user_time().tv_sec() + rusage.system_time().tv_sec()) * 1_000_000) +
|
||||
(rusage.system_time().tv_usec() + rusage.user_time().tv_usec()) as i64) as u64;
|
||||
let micros = (((rusage.user_time().tv_sec() + rusage.system_time().tv_sec()) * 1_000_000)
|
||||
+ (rusage.system_time().tv_usec() + rusage.user_time().tv_usec()) as i64) as u64;
|
||||
|
||||
return Duration::from_micros(micros);
|
||||
}
|
||||
|
||||
@@ -121,11 +121,12 @@ fn try_restrict(worker_info: &WorkerInfo) -> Result<()> {
|
||||
worker_dir_path_c.as_ptr(),
|
||||
worker_dir_path_c.as_ptr(),
|
||||
ptr::null(), // ignored when MS_BIND is used
|
||||
libc::MS_BIND |
|
||||
libc::MS_REC | libc::MS_NOEXEC |
|
||||
libc::MS_NODEV | libc::MS_NOSUID |
|
||||
libc::MS_NOATIME |
|
||||
additional_flags,
|
||||
libc::MS_BIND
|
||||
| libc::MS_REC | libc::MS_NOEXEC
|
||||
| libc::MS_NODEV
|
||||
| libc::MS_NOSUID
|
||||
| libc::MS_NOATIME
|
||||
| additional_flags,
|
||||
ptr::null(), // ignored when MS_BIND is used
|
||||
) < 0
|
||||
{
|
||||
|
||||
@@ -82,12 +82,12 @@ fn clone_flags(have_unshare_newuser: bool) -> CloneFlags {
|
||||
// SIGCHLD flag is used to inform clone that the parent process is
|
||||
// expecting a child termination signal, without this flag `waitpid` function
|
||||
// return `ECHILD` error.
|
||||
maybe_clone_newuser |
|
||||
CloneFlags::CLONE_NEWCGROUP |
|
||||
CloneFlags::CLONE_NEWIPC |
|
||||
CloneFlags::CLONE_NEWNET |
|
||||
CloneFlags::CLONE_NEWNS |
|
||||
CloneFlags::CLONE_NEWPID |
|
||||
CloneFlags::CLONE_NEWUTS |
|
||||
CloneFlags::from_bits_retain(libc::SIGCHLD)
|
||||
maybe_clone_newuser
|
||||
| CloneFlags::CLONE_NEWCGROUP
|
||||
| CloneFlags::CLONE_NEWIPC
|
||||
| CloneFlags::CLONE_NEWNET
|
||||
| CloneFlags::CLONE_NEWNS
|
||||
| CloneFlags::CLONE_NEWPID
|
||||
| CloneFlags::CLONE_NEWUTS
|
||||
| CloneFlags::from_bits_retain(libc::SIGCHLD)
|
||||
}
|
||||
|
||||
@@ -319,18 +319,20 @@ fn validate_using_artifact(
|
||||
// [`executor_interface::prepare`].
|
||||
execute_artifact(compiled_artifact_blob, executor_params, params)
|
||||
} {
|
||||
Err(ExecuteError::RuntimeConstruction(wasmerr)) =>
|
||||
return JobResponse::runtime_construction("execute", &wasmerr.to_string()),
|
||||
Err(ExecuteError::RuntimeConstruction(wasmerr)) => {
|
||||
return JobResponse::runtime_construction("execute", &wasmerr.to_string())
|
||||
},
|
||||
Err(err) => return JobResponse::format_invalid("execute", &err.to_string()),
|
||||
Ok(d) => d,
|
||||
};
|
||||
|
||||
let result_descriptor = match ValidationResult::decode(&mut &descriptor_bytes[..]) {
|
||||
Err(err) =>
|
||||
Err(err) => {
|
||||
return JobResponse::format_invalid(
|
||||
"validation result decoding failed",
|
||||
&err.to_string(),
|
||||
),
|
||||
)
|
||||
},
|
||||
Ok(r) => r,
|
||||
};
|
||||
|
||||
@@ -383,8 +385,9 @@ fn handle_clone(
|
||||
pov_size,
|
||||
execution_timeout,
|
||||
),
|
||||
Err(security::clone::Error::Clone(errno)) =>
|
||||
Ok(Err(internal_error_from_errno("clone", errno))),
|
||||
Err(security::clone::Error::Clone(errno)) => {
|
||||
Ok(Err(internal_error_from_errno("clone", errno)))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -243,8 +243,8 @@ impl Artifacts {
|
||||
let Some(file_name) = path.file_name().and_then(|f| f.to_str()) else { continue };
|
||||
if path.is_dir() && file_name.starts_with(WORKER_DIR_PREFIX) {
|
||||
let _ = fs::remove_dir_all(path);
|
||||
} else if path.extension().map_or(false, |ext| ext == ARTIFACT_EXTENSION) ||
|
||||
file_name.starts_with(ARTIFACT_OLD_PREFIX)
|
||||
} else if path.extension().map_or(false, |ext| ext == ARTIFACT_EXTENSION)
|
||||
|| file_name.starts_with(ARTIFACT_OLD_PREFIX)
|
||||
{
|
||||
let _ = fs::remove_file(path);
|
||||
}
|
||||
|
||||
@@ -524,14 +524,16 @@ async fn handle_job_finish(
|
||||
)
|
||||
},
|
||||
|
||||
Err(WorkerInterfaceError::InternalError(err)) |
|
||||
Err(WorkerInterfaceError::WorkerError(WorkerError::InternalError(err))) =>
|
||||
(None, Err(ValidationError::Internal(err)), None, None, None),
|
||||
Err(WorkerInterfaceError::InternalError(err))
|
||||
| Err(WorkerInterfaceError::WorkerError(WorkerError::InternalError(err))) => {
|
||||
(None, Err(ValidationError::Internal(err)), None, None, None)
|
||||
},
|
||||
// Either the worker or the job timed out. Kill the worker in either case. Treated as
|
||||
// definitely-invalid, because if we timed out, there's no time left for a retry.
|
||||
Err(WorkerInterfaceError::HardTimeout) |
|
||||
Err(WorkerInterfaceError::WorkerError(WorkerError::JobTimedOut)) =>
|
||||
(None, Err(ValidationError::Invalid(InvalidCandidate::HardTimeout)), None, None, None),
|
||||
Err(WorkerInterfaceError::HardTimeout)
|
||||
| Err(WorkerInterfaceError::WorkerError(WorkerError::JobTimedOut)) => {
|
||||
(None, Err(ValidationError::Invalid(InvalidCandidate::HardTimeout)), None, None, None)
|
||||
},
|
||||
// "Maybe invalid" errors (will retry).
|
||||
Err(WorkerInterfaceError::CommunicationErr(_err)) => (
|
||||
None,
|
||||
|
||||
@@ -533,10 +533,12 @@ async fn handle_to_host(
|
||||
handle_execute_pvf(artifacts, prepare_queue, execute_queue, awaiting_prepare, inputs)
|
||||
.await?;
|
||||
},
|
||||
ToHost::HeadsUp { active_pvfs } =>
|
||||
handle_heads_up(artifacts, prepare_queue, active_pvfs).await?,
|
||||
ToHost::UpdateActiveLeaves { update, ancestors } =>
|
||||
handle_update_active_leaves(execute_queue, update, ancestors).await?,
|
||||
ToHost::HeadsUp { active_pvfs } => {
|
||||
handle_heads_up(artifacts, prepare_queue, active_pvfs).await?
|
||||
},
|
||||
ToHost::UpdateActiveLeaves { update, ancestors } => {
|
||||
handle_update_active_leaves(execute_queue, update, ancestors).await?
|
||||
},
|
||||
#[cfg(feature = "test-utils")]
|
||||
ToHost::ReplaceArtifactChecksum { checksum, new_checksum } => {
|
||||
artifacts.replace_artifact_checksum(checksum, new_checksum);
|
||||
@@ -567,8 +569,9 @@ async fn handle_precheck_pvf(
|
||||
*last_time_needed = SystemTime::now();
|
||||
let _ = result_sender.send(Ok(()));
|
||||
},
|
||||
ArtifactState::Preparing { waiting_for_response, num_failures: _ } =>
|
||||
waiting_for_response.push(result_sender),
|
||||
ArtifactState::Preparing { waiting_for_response, num_failures: _ } => {
|
||||
waiting_for_response.push(result_sender)
|
||||
},
|
||||
ArtifactState::FailedToProcess { error, .. } => {
|
||||
// Do not retry an artifact that previously failed preparation.
|
||||
let _ = result_sender.send(PrecheckResult::Err(error.clone()));
|
||||
@@ -887,8 +890,9 @@ async fn handle_prepare_done(
|
||||
}
|
||||
|
||||
*state = match result {
|
||||
Ok(PrepareSuccess { checksum, path, size, .. }) =>
|
||||
ArtifactState::Prepared { checksum, path, last_time_needed: SystemTime::now(), size },
|
||||
Ok(PrepareSuccess { checksum, path, size, .. }) => {
|
||||
ArtifactState::Prepared { checksum, path, last_time_needed: SystemTime::now(), size }
|
||||
},
|
||||
Err(error) => {
|
||||
let last_time_failed = SystemTime::now();
|
||||
let num_failures = *num_failures + 1;
|
||||
@@ -1033,8 +1037,8 @@ fn can_retry_prepare_after_failure(
|
||||
|
||||
// Retry if the retry cooldown has elapsed and if we have already retried less than
|
||||
// `NUM_PREPARE_RETRIES` times. IO errors may resolve themselves.
|
||||
SystemTime::now() >= last_time_failed + PREPARE_FAILURE_COOLDOWN &&
|
||||
num_failures <= NUM_PREPARE_RETRIES
|
||||
SystemTime::now() >= last_time_failed + PREPARE_FAILURE_COOLDOWN
|
||||
&& num_failures <= NUM_PREPARE_RETRIES
|
||||
}
|
||||
|
||||
/// A stream that yields a pulse continuously at a given interval.
|
||||
|
||||
@@ -330,8 +330,9 @@ fn handle_mux(
|
||||
// If we receive an outcome that the worker is unreachable or that an error occurred on
|
||||
// the worker, we attempt to kill the worker process.
|
||||
match outcome {
|
||||
Outcome::Concluded { worker: idle, result } =>
|
||||
handle_concluded_no_rip(from_pool, spawned, worker, idle, result),
|
||||
Outcome::Concluded { worker: idle, result } => {
|
||||
handle_concluded_no_rip(from_pool, spawned, worker, idle, result)
|
||||
},
|
||||
// Return `Concluded`, but do not kill the worker since the error was on the host
|
||||
// side.
|
||||
Outcome::CreateTmpFileErr { worker: idle, err } => handle_concluded_no_rip(
|
||||
|
||||
@@ -271,8 +271,9 @@ async fn handle_from_pool(queue: &mut Queue, from_pool: pool::FromPool) -> Resul
|
||||
use pool::FromPool;
|
||||
match from_pool {
|
||||
FromPool::Spawned(worker) => handle_worker_spawned(queue, worker).await?,
|
||||
FromPool::Concluded { worker, rip, result } =>
|
||||
handle_worker_concluded(queue, worker, rip, result).await?,
|
||||
FromPool::Concluded { worker, rip, result } => {
|
||||
handle_worker_concluded(queue, worker, rip, result).await?
|
||||
},
|
||||
FromPool::Rip(worker) => handle_worker_rip(queue, worker).await?,
|
||||
}
|
||||
Ok(())
|
||||
|
||||
@@ -157,7 +157,7 @@ pub async fn start_work(
|
||||
|
||||
match result {
|
||||
// Received bytes from worker within the time limit.
|
||||
Ok(Ok(prepare_worker_result)) =>
|
||||
Ok(Ok(prepare_worker_result)) => {
|
||||
handle_response(
|
||||
metrics,
|
||||
IdleWorker { stream, pid, worker_dir },
|
||||
@@ -167,7 +167,8 @@ pub async fn start_work(
|
||||
&cache_path,
|
||||
preparation_timeout,
|
||||
)
|
||||
.await,
|
||||
.await
|
||||
},
|
||||
Ok(Err(err)) => {
|
||||
// Communication error within the time limit.
|
||||
gum::warn!(
|
||||
|
||||
@@ -105,8 +105,8 @@ impl FullSecurityStatus {
|
||||
}
|
||||
|
||||
fn all_errs_allowed(&self) -> bool {
|
||||
!self.partial.secure_validator_mode ||
|
||||
self.errs.iter().all(|err| err.is_allowed_in_secure_mode(&self.partial))
|
||||
!self.partial.secure_validator_mode
|
||||
|| self.errs.iter().all(|err| err.is_allowed_in_secure_mode(&self.partial))
|
||||
}
|
||||
|
||||
fn errs_string(&self) -> String {
|
||||
@@ -141,8 +141,9 @@ impl SecureModeError {
|
||||
match self {
|
||||
// Landlock is present on relatively recent Linuxes. This is optional if the unshare
|
||||
// capability is present, providing FS sandboxing a different way.
|
||||
CannotEnableLandlock { .. } =>
|
||||
security_status.can_unshare_user_namespace_and_change_root,
|
||||
CannotEnableLandlock { .. } => {
|
||||
security_status.can_unshare_user_namespace_and_change_root
|
||||
},
|
||||
// seccomp should be present on all modern Linuxes unless it's been disabled.
|
||||
CannotEnableSeccomp(_) => false,
|
||||
// Should always be present on modern Linuxes. If not, Landlock also provides FS
|
||||
|
||||
@@ -97,17 +97,21 @@ where
|
||||
use RequestResult::*;
|
||||
|
||||
match result {
|
||||
Authorities(relay_parent, authorities) =>
|
||||
self.requests_cache.cache_authorities(relay_parent, authorities),
|
||||
Validators(relay_parent, validators) =>
|
||||
self.requests_cache.cache_validators(relay_parent, validators),
|
||||
Authorities(relay_parent, authorities) => {
|
||||
self.requests_cache.cache_authorities(relay_parent, authorities)
|
||||
},
|
||||
Validators(relay_parent, validators) => {
|
||||
self.requests_cache.cache_validators(relay_parent, validators)
|
||||
},
|
||||
MinimumBackingVotes(session_index, minimum_backing_votes) => self
|
||||
.requests_cache
|
||||
.cache_minimum_backing_votes(session_index, minimum_backing_votes),
|
||||
ValidatorGroups(relay_parent, groups) =>
|
||||
self.requests_cache.cache_validator_groups(relay_parent, groups),
|
||||
AvailabilityCores(relay_parent, cores) =>
|
||||
self.requests_cache.cache_availability_cores(relay_parent, cores),
|
||||
ValidatorGroups(relay_parent, groups) => {
|
||||
self.requests_cache.cache_validator_groups(relay_parent, groups)
|
||||
},
|
||||
AvailabilityCores(relay_parent, cores) => {
|
||||
self.requests_cache.cache_availability_cores(relay_parent, cores)
|
||||
},
|
||||
PersistedValidationData(relay_parent, para_id, assumption, data) => self
|
||||
.requests_cache
|
||||
.cache_persisted_validation_data((relay_parent, para_id, assumption), data),
|
||||
@@ -123,66 +127,82 @@ where
|
||||
CheckValidationOutputs(relay_parent, para_id, commitments, b) => self
|
||||
.requests_cache
|
||||
.cache_check_validation_outputs((relay_parent, para_id, commitments), b),
|
||||
SessionIndexForChild(relay_parent, session_index) =>
|
||||
self.requests_cache.cache_session_index_for_child(relay_parent, session_index),
|
||||
SessionIndexForChild(relay_parent, session_index) => {
|
||||
self.requests_cache.cache_session_index_for_child(relay_parent, session_index)
|
||||
},
|
||||
ValidationCode(relay_parent, para_id, assumption, code) => self
|
||||
.requests_cache
|
||||
.cache_validation_code((relay_parent, para_id, assumption), code),
|
||||
ValidationCodeByHash(_relay_parent, validation_code_hash, code) =>
|
||||
self.requests_cache.cache_validation_code_by_hash(validation_code_hash, code),
|
||||
ValidationCodeByHash(_relay_parent, validation_code_hash, code) => {
|
||||
self.requests_cache.cache_validation_code_by_hash(validation_code_hash, code)
|
||||
},
|
||||
CandidatePendingAvailability(relay_parent, para_id, candidate) => self
|
||||
.requests_cache
|
||||
.cache_candidate_pending_availability((relay_parent, para_id), candidate),
|
||||
CandidatesPendingAvailability(relay_parent, para_id, candidates) => self
|
||||
.requests_cache
|
||||
.cache_candidates_pending_availability((relay_parent, para_id), candidates),
|
||||
CandidateEvents(relay_parent, events) =>
|
||||
self.requests_cache.cache_candidate_events(relay_parent, events),
|
||||
SessionExecutorParams(_relay_parent, session_index, index) =>
|
||||
self.requests_cache.cache_session_executor_params(session_index, index),
|
||||
SessionInfo(_relay_parent, session_index, info) =>
|
||||
CandidateEvents(relay_parent, events) => {
|
||||
self.requests_cache.cache_candidate_events(relay_parent, events)
|
||||
},
|
||||
SessionExecutorParams(_relay_parent, session_index, index) => {
|
||||
self.requests_cache.cache_session_executor_params(session_index, index)
|
||||
},
|
||||
SessionInfo(_relay_parent, session_index, info) => {
|
||||
if let Some(info) = info {
|
||||
self.requests_cache.cache_session_info(session_index, info);
|
||||
},
|
||||
DmqContents(relay_parent, para_id, messages) =>
|
||||
self.requests_cache.cache_dmq_contents((relay_parent, para_id), messages),
|
||||
}
|
||||
},
|
||||
DmqContents(relay_parent, para_id, messages) => {
|
||||
self.requests_cache.cache_dmq_contents((relay_parent, para_id), messages)
|
||||
},
|
||||
InboundHrmpChannelsContents(relay_parent, para_id, contents) => self
|
||||
.requests_cache
|
||||
.cache_inbound_hrmp_channel_contents((relay_parent, para_id), contents),
|
||||
CurrentBabeEpoch(relay_parent, epoch) =>
|
||||
self.requests_cache.cache_current_babe_epoch(relay_parent, epoch),
|
||||
FetchOnChainVotes(relay_parent, scraped) =>
|
||||
self.requests_cache.cache_on_chain_votes(relay_parent, scraped),
|
||||
PvfsRequirePrecheck(relay_parent, pvfs) =>
|
||||
self.requests_cache.cache_pvfs_require_precheck(relay_parent, pvfs),
|
||||
CurrentBabeEpoch(relay_parent, epoch) => {
|
||||
self.requests_cache.cache_current_babe_epoch(relay_parent, epoch)
|
||||
},
|
||||
FetchOnChainVotes(relay_parent, scraped) => {
|
||||
self.requests_cache.cache_on_chain_votes(relay_parent, scraped)
|
||||
},
|
||||
PvfsRequirePrecheck(relay_parent, pvfs) => {
|
||||
self.requests_cache.cache_pvfs_require_precheck(relay_parent, pvfs)
|
||||
},
|
||||
SubmitPvfCheckStatement(()) => {},
|
||||
ValidationCodeHash(relay_parent, para_id, assumption, hash) => self
|
||||
.requests_cache
|
||||
.cache_validation_code_hash((relay_parent, para_id, assumption), hash),
|
||||
Version(relay_parent, version) =>
|
||||
self.requests_cache.cache_version(relay_parent, version),
|
||||
Disputes(relay_parent, disputes) =>
|
||||
self.requests_cache.cache_disputes(relay_parent, disputes),
|
||||
UnappliedSlashes(relay_parent, unapplied_slashes) =>
|
||||
self.requests_cache.cache_unapplied_slashes(relay_parent, unapplied_slashes),
|
||||
Version(relay_parent, version) => {
|
||||
self.requests_cache.cache_version(relay_parent, version)
|
||||
},
|
||||
Disputes(relay_parent, disputes) => {
|
||||
self.requests_cache.cache_disputes(relay_parent, disputes)
|
||||
},
|
||||
UnappliedSlashes(relay_parent, unapplied_slashes) => {
|
||||
self.requests_cache.cache_unapplied_slashes(relay_parent, unapplied_slashes)
|
||||
},
|
||||
UnappliedSlashesV2(relay_parent, unapplied_slashes_v2) => self
|
||||
.requests_cache
|
||||
.cache_unapplied_slashes_v2(relay_parent, unapplied_slashes_v2),
|
||||
KeyOwnershipProof(relay_parent, validator_id, key_ownership_proof) => self
|
||||
.requests_cache
|
||||
.cache_key_ownership_proof((relay_parent, validator_id), key_ownership_proof),
|
||||
ApprovalVotingParams(_relay_parent, session_index, params) =>
|
||||
self.requests_cache.cache_approval_voting_params(session_index, params),
|
||||
ApprovalVotingParams(_relay_parent, session_index, params) => {
|
||||
self.requests_cache.cache_approval_voting_params(session_index, params)
|
||||
},
|
||||
SubmitReportDisputeLost(_) => {},
|
||||
DisabledValidators(relay_parent, disabled_validators) =>
|
||||
self.requests_cache.cache_disabled_validators(relay_parent, disabled_validators),
|
||||
DisabledValidators(relay_parent, disabled_validators) => {
|
||||
self.requests_cache.cache_disabled_validators(relay_parent, disabled_validators)
|
||||
},
|
||||
ParaBackingState(relay_parent, para_id, constraints) => self
|
||||
.requests_cache
|
||||
.cache_para_backing_state((relay_parent, para_id), constraints),
|
||||
AsyncBackingParams(relay_parent, params) =>
|
||||
self.requests_cache.cache_async_backing_params(relay_parent, params),
|
||||
NodeFeatures(session_index, params) =>
|
||||
self.requests_cache.cache_node_features(session_index, params),
|
||||
AsyncBackingParams(relay_parent, params) => {
|
||||
self.requests_cache.cache_async_backing_params(relay_parent, params)
|
||||
},
|
||||
NodeFeatures(session_index, params) => {
|
||||
self.requests_cache.cache_node_features(session_index, params)
|
||||
},
|
||||
ClaimQueue(relay_parent, sender) => {
|
||||
self.requests_cache.cache_claim_queue(relay_parent, sender);
|
||||
},
|
||||
@@ -192,8 +212,9 @@ where
|
||||
SchedulingLookahead(session_index, scheduling_lookahead) => self
|
||||
.requests_cache
|
||||
.cache_scheduling_lookahead(session_index, scheduling_lookahead),
|
||||
ValidationCodeBombLimit(session_index, limit) =>
|
||||
self.requests_cache.cache_validation_code_bomb_limit(session_index, limit),
|
||||
ValidationCodeBombLimit(session_index, limit) => {
|
||||
self.requests_cache.cache_validation_code_bomb_limit(session_index, limit)
|
||||
},
|
||||
ParaIds(session_index, para_ids) => {
|
||||
self.requests_cache.cache_para_ids(session_index, para_ids);
|
||||
},
|
||||
@@ -227,19 +248,24 @@ where
|
||||
}
|
||||
|
||||
match request {
|
||||
Request::Version(sender) =>
|
||||
query!(version(), sender).map(|sender| Request::Version(sender)),
|
||||
Request::Authorities(sender) =>
|
||||
query!(authorities(), sender).map(|sender| Request::Authorities(sender)),
|
||||
Request::Validators(sender) =>
|
||||
query!(validators(), sender).map(|sender| Request::Validators(sender)),
|
||||
Request::ValidatorGroups(sender) =>
|
||||
query!(validator_groups(), sender).map(|sender| Request::ValidatorGroups(sender)),
|
||||
Request::Version(sender) => {
|
||||
query!(version(), sender).map(|sender| Request::Version(sender))
|
||||
},
|
||||
Request::Authorities(sender) => {
|
||||
query!(authorities(), sender).map(|sender| Request::Authorities(sender))
|
||||
},
|
||||
Request::Validators(sender) => {
|
||||
query!(validators(), sender).map(|sender| Request::Validators(sender))
|
||||
},
|
||||
Request::ValidatorGroups(sender) => {
|
||||
query!(validator_groups(), sender).map(|sender| Request::ValidatorGroups(sender))
|
||||
},
|
||||
Request::AvailabilityCores(sender) => query!(availability_cores(), sender)
|
||||
.map(|sender| Request::AvailabilityCores(sender)),
|
||||
Request::PersistedValidationData(para, assumption, sender) =>
|
||||
Request::PersistedValidationData(para, assumption, sender) => {
|
||||
query!(persisted_validation_data(para, assumption), sender)
|
||||
.map(|sender| Request::PersistedValidationData(para, assumption, sender)),
|
||||
.map(|sender| Request::PersistedValidationData(para, assumption, sender))
|
||||
},
|
||||
Request::AssumedValidationData(
|
||||
para,
|
||||
expected_persisted_validation_data_hash,
|
||||
@@ -255,25 +281,31 @@ where
|
||||
sender,
|
||||
)
|
||||
}),
|
||||
Request::CheckValidationOutputs(para, commitments, sender) =>
|
||||
Request::CheckValidationOutputs(para, commitments, sender) => {
|
||||
query!(check_validation_outputs(para, commitments), sender)
|
||||
.map(|sender| Request::CheckValidationOutputs(para, commitments, sender)),
|
||||
.map(|sender| Request::CheckValidationOutputs(para, commitments, sender))
|
||||
},
|
||||
Request::SessionIndexForChild(sender) => query!(session_index_for_child(), sender)
|
||||
.map(|sender| Request::SessionIndexForChild(sender)),
|
||||
Request::ValidationCode(para, assumption, sender) =>
|
||||
Request::ValidationCode(para, assumption, sender) => {
|
||||
query!(validation_code(para, assumption), sender)
|
||||
.map(|sender| Request::ValidationCode(para, assumption, sender)),
|
||||
Request::ValidationCodeByHash(validation_code_hash, sender) =>
|
||||
.map(|sender| Request::ValidationCode(para, assumption, sender))
|
||||
},
|
||||
Request::ValidationCodeByHash(validation_code_hash, sender) => {
|
||||
query!(validation_code_by_hash(validation_code_hash), sender)
|
||||
.map(|sender| Request::ValidationCodeByHash(validation_code_hash, sender)),
|
||||
Request::CandidatePendingAvailability(para, sender) =>
|
||||
.map(|sender| Request::ValidationCodeByHash(validation_code_hash, sender))
|
||||
},
|
||||
Request::CandidatePendingAvailability(para, sender) => {
|
||||
query!(candidate_pending_availability(para), sender)
|
||||
.map(|sender| Request::CandidatePendingAvailability(para, sender)),
|
||||
Request::CandidatesPendingAvailability(para, sender) =>
|
||||
.map(|sender| Request::CandidatePendingAvailability(para, sender))
|
||||
},
|
||||
Request::CandidatesPendingAvailability(para, sender) => {
|
||||
query!(candidates_pending_availability(para), sender)
|
||||
.map(|sender| Request::CandidatesPendingAvailability(para, sender)),
|
||||
Request::CandidateEvents(sender) =>
|
||||
query!(candidate_events(), sender).map(|sender| Request::CandidateEvents(sender)),
|
||||
.map(|sender| Request::CandidatesPendingAvailability(para, sender))
|
||||
},
|
||||
Request::CandidateEvents(sender) => {
|
||||
query!(candidate_events(), sender).map(|sender| Request::CandidateEvents(sender))
|
||||
},
|
||||
Request::SessionExecutorParams(session_index, sender) => {
|
||||
if let Some(executor_params) =
|
||||
self.requests_cache.session_executor_params(session_index)
|
||||
@@ -294,42 +326,52 @@ where
|
||||
Some(Request::SessionInfo(index, sender))
|
||||
}
|
||||
},
|
||||
Request::DmqContents(id, sender) =>
|
||||
query!(dmq_contents(id), sender).map(|sender| Request::DmqContents(id, sender)),
|
||||
Request::InboundHrmpChannelsContents(id, sender) =>
|
||||
Request::DmqContents(id, sender) => {
|
||||
query!(dmq_contents(id), sender).map(|sender| Request::DmqContents(id, sender))
|
||||
},
|
||||
Request::InboundHrmpChannelsContents(id, sender) => {
|
||||
query!(inbound_hrmp_channels_contents(id), sender)
|
||||
.map(|sender| Request::InboundHrmpChannelsContents(id, sender)),
|
||||
Request::CurrentBabeEpoch(sender) =>
|
||||
query!(current_babe_epoch(), sender).map(|sender| Request::CurrentBabeEpoch(sender)),
|
||||
Request::FetchOnChainVotes(sender) =>
|
||||
query!(on_chain_votes(), sender).map(|sender| Request::FetchOnChainVotes(sender)),
|
||||
.map(|sender| Request::InboundHrmpChannelsContents(id, sender))
|
||||
},
|
||||
Request::CurrentBabeEpoch(sender) => {
|
||||
query!(current_babe_epoch(), sender).map(|sender| Request::CurrentBabeEpoch(sender))
|
||||
},
|
||||
Request::FetchOnChainVotes(sender) => {
|
||||
query!(on_chain_votes(), sender).map(|sender| Request::FetchOnChainVotes(sender))
|
||||
},
|
||||
Request::PvfsRequirePrecheck(sender) => query!(pvfs_require_precheck(), sender)
|
||||
.map(|sender| Request::PvfsRequirePrecheck(sender)),
|
||||
request @ Request::SubmitPvfCheckStatement(_, _, _) => {
|
||||
// This request is side-effecting and thus cannot be cached.
|
||||
Some(request)
|
||||
},
|
||||
Request::ValidationCodeHash(para, assumption, sender) =>
|
||||
Request::ValidationCodeHash(para, assumption, sender) => {
|
||||
query!(validation_code_hash(para, assumption), sender)
|
||||
.map(|sender| Request::ValidationCodeHash(para, assumption, sender)),
|
||||
Request::Disputes(sender) =>
|
||||
query!(disputes(), sender).map(|sender| Request::Disputes(sender)),
|
||||
Request::UnappliedSlashes(sender) =>
|
||||
query!(unapplied_slashes(), sender).map(|sender| Request::UnappliedSlashes(sender)),
|
||||
.map(|sender| Request::ValidationCodeHash(para, assumption, sender))
|
||||
},
|
||||
Request::Disputes(sender) => {
|
||||
query!(disputes(), sender).map(|sender| Request::Disputes(sender))
|
||||
},
|
||||
Request::UnappliedSlashes(sender) => {
|
||||
query!(unapplied_slashes(), sender).map(|sender| Request::UnappliedSlashes(sender))
|
||||
},
|
||||
Request::UnappliedSlashesV2(sender) => query!(unapplied_slashes_v2(), sender)
|
||||
.map(|sender| Request::UnappliedSlashesV2(sender)),
|
||||
Request::KeyOwnershipProof(validator_id, sender) =>
|
||||
Request::KeyOwnershipProof(validator_id, sender) => {
|
||||
query!(key_ownership_proof(validator_id), sender)
|
||||
.map(|sender| Request::KeyOwnershipProof(validator_id, sender)),
|
||||
Request::SubmitReportDisputeLost(dispute_proof, key_ownership_proof, sender) =>
|
||||
.map(|sender| Request::KeyOwnershipProof(validator_id, sender))
|
||||
},
|
||||
Request::SubmitReportDisputeLost(dispute_proof, key_ownership_proof, sender) => {
|
||||
query!(submit_report_dispute_lost(dispute_proof, key_ownership_proof), sender).map(
|
||||
|sender| {
|
||||
Request::SubmitReportDisputeLost(dispute_proof, key_ownership_proof, sender)
|
||||
},
|
||||
),
|
||||
Request::ApprovalVotingParams(session_index, sender) =>
|
||||
)
|
||||
},
|
||||
Request::ApprovalVotingParams(session_index, sender) => {
|
||||
query!(approval_voting_params(session_index), sender)
|
||||
.map(|sender| Request::ApprovalVotingParams(session_index, sender)),
|
||||
.map(|sender| Request::ApprovalVotingParams(session_index, sender))
|
||||
},
|
||||
Request::DisabledValidators(sender) => query!(disabled_validators(), sender)
|
||||
.map(|sender| Request::DisabledValidators(sender)),
|
||||
Request::ParaBackingState(para, sender) => query!(para_backing_state(para), sender)
|
||||
@@ -354,8 +396,9 @@ where
|
||||
Some(Request::NodeFeatures(index, sender))
|
||||
}
|
||||
},
|
||||
Request::ClaimQueue(sender) =>
|
||||
query!(claim_queue(), sender).map(|sender| Request::ClaimQueue(sender)),
|
||||
Request::ClaimQueue(sender) => {
|
||||
query!(claim_queue(), sender).map(|sender| Request::ClaimQueue(sender))
|
||||
},
|
||||
Request::BackingConstraints(para, sender) => query!(backing_constraints(para), sender)
|
||||
.map(|sender| Request::BackingConstraints(para, sender)),
|
||||
Request::SchedulingLookahead(index, sender) => {
|
||||
|
||||
@@ -67,8 +67,9 @@ impl FakeCandidateValidation {
|
||||
use FakeCandidateValidation::*;
|
||||
|
||||
match *self {
|
||||
BackingInvalid | BackingAndApprovalInvalid | BackingValid | BackingAndApprovalValid =>
|
||||
true,
|
||||
BackingInvalid | BackingAndApprovalInvalid | BackingValid | BackingAndApprovalValid => {
|
||||
true
|
||||
},
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@@ -77,10 +78,10 @@ impl FakeCandidateValidation {
|
||||
use FakeCandidateValidation::*;
|
||||
|
||||
match *self {
|
||||
ApprovalInvalid |
|
||||
BackingAndApprovalInvalid |
|
||||
ApprovalValid |
|
||||
BackingAndApprovalValid => true,
|
||||
ApprovalInvalid
|
||||
| BackingAndApprovalInvalid
|
||||
| ApprovalValid
|
||||
| BackingAndApprovalValid => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@@ -126,20 +127,23 @@ pub enum FakeCandidateValidationError {
|
||||
impl Into<InvalidCandidate> for FakeCandidateValidationError {
|
||||
fn into(self) -> InvalidCandidate {
|
||||
match self {
|
||||
FakeCandidateValidationError::ExecutionError =>
|
||||
InvalidCandidate::ExecutionError("Malus".into()),
|
||||
FakeCandidateValidationError::ExecutionError => {
|
||||
InvalidCandidate::ExecutionError("Malus".into())
|
||||
},
|
||||
FakeCandidateValidationError::InvalidOutputs => InvalidCandidate::InvalidOutputs,
|
||||
FakeCandidateValidationError::Timeout => InvalidCandidate::Timeout,
|
||||
FakeCandidateValidationError::ParamsTooLarge => InvalidCandidate::ParamsTooLarge(666),
|
||||
FakeCandidateValidationError::CodeTooLarge => InvalidCandidate::CodeTooLarge(666),
|
||||
FakeCandidateValidationError::POVDecompressionFailure =>
|
||||
InvalidCandidate::PoVDecompressionFailure,
|
||||
FakeCandidateValidationError::POVDecompressionFailure => {
|
||||
InvalidCandidate::PoVDecompressionFailure
|
||||
},
|
||||
FakeCandidateValidationError::BadReturn => InvalidCandidate::BadReturn,
|
||||
FakeCandidateValidationError::BadParent => InvalidCandidate::BadParent,
|
||||
FakeCandidateValidationError::POVHashMismatch => InvalidCandidate::PoVHashMismatch,
|
||||
FakeCandidateValidationError::BadSignature => InvalidCandidate::BadSignature,
|
||||
FakeCandidateValidationError::ParaHeadHashMismatch =>
|
||||
InvalidCandidate::ParaHeadHashMismatch,
|
||||
FakeCandidateValidationError::ParaHeadHashMismatch => {
|
||||
InvalidCandidate::ParaHeadHashMismatch
|
||||
},
|
||||
FakeCandidateValidationError::CodeHashMismatch => InvalidCandidate::CodeHashMismatch,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,8 +148,9 @@ where
|
||||
matches!(event, CandidateEvent::CandidateIncluded(_, _, _, _))
|
||||
});
|
||||
let candidate = match event {
|
||||
Some(CandidateEvent::CandidateIncluded(candidate, _, _, _)) =>
|
||||
candidate,
|
||||
Some(CandidateEvent::CandidateIncluded(candidate, _, _, _)) => {
|
||||
candidate
|
||||
},
|
||||
_ => {
|
||||
gum::error!(
|
||||
target: MALUS,
|
||||
|
||||
@@ -184,12 +184,15 @@ impl RuntimeMetricsProvider {
|
||||
// Parse end execute the update operation.
|
||||
fn parse_metric_update(&self, update: RuntimeMetricUpdate) {
|
||||
match update.op {
|
||||
RuntimeMetricOp::IncrementCounterVec(value, ref labels) =>
|
||||
self.inc_counter_vec_by(update.metric_name(), value, labels),
|
||||
RuntimeMetricOp::IncrementCounter(value) =>
|
||||
self.inc_counter_by(update.metric_name(), value),
|
||||
RuntimeMetricOp::ObserveHistogram(value) =>
|
||||
self.observe_histogram(update.metric_name(), value),
|
||||
RuntimeMetricOp::IncrementCounterVec(value, ref labels) => {
|
||||
self.inc_counter_vec_by(update.metric_name(), value, labels)
|
||||
},
|
||||
RuntimeMetricOp::IncrementCounter(value) => {
|
||||
self.inc_counter_by(update.metric_name(), value)
|
||||
},
|
||||
RuntimeMetricOp::ObserveHistogram(value) => {
|
||||
self.observe_histogram(update.metric_name(), value)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -419,8 +419,8 @@ impl Knowledge {
|
||||
// we need to share the same `MessageSubject` with the followup approval candidate index.
|
||||
if kind == MessageKind::Assignment && success && message.1.count_ones() > 1 {
|
||||
for candidate_index in message.1.iter_ones() {
|
||||
success = success &&
|
||||
self.insert(
|
||||
success = success
|
||||
&& self.insert(
|
||||
MessageSubject(
|
||||
message.0,
|
||||
vec![candidate_index as u32].try_into().expect("Non-empty vec; qed"),
|
||||
@@ -1300,8 +1300,8 @@ impl State {
|
||||
|
||||
let age = max_age.saturating_sub(min_age);
|
||||
|
||||
aggression_config.should_trigger_aggression(age) &&
|
||||
topology.map(|topology| topology.is_validator(&peer)).unwrap_or(false)
|
||||
aggression_config.should_trigger_aggression(age)
|
||||
&& topology.map(|topology| topology.is_validator(&peer)).unwrap_or(false)
|
||||
}
|
||||
|
||||
async fn import_and_circulate_assignment<A, N, RA, R>(
|
||||
@@ -2282,11 +2282,11 @@ impl State {
|
||||
})
|
||||
.unwrap_or(true);
|
||||
|
||||
if resend == Resend::Yes &&
|
||||
config.resend_unfinalized_period.as_ref().map_or(false, |p| {
|
||||
block_age > 0 &&
|
||||
block_age % p == 0 && diff_from_min_age == 0 &&
|
||||
can_resend_at_this_age
|
||||
if resend == Resend::Yes
|
||||
&& config.resend_unfinalized_period.as_ref().map_or(false, |p| {
|
||||
block_age > 0
|
||||
&& block_age % p == 0 && diff_from_min_age == 0
|
||||
&& can_resend_at_this_age
|
||||
}) {
|
||||
// Retry sending to all peers.
|
||||
for (_, knowledge) in block_entry.known_by.iter_mut() {
|
||||
@@ -2372,8 +2372,9 @@ impl State {
|
||||
// We assume `candidate_bitfield` length for the core bitfield and we just check
|
||||
// against `MAX_BITFIELD_SIZE` later.
|
||||
AssignmentCertKindV2::RelayVRFModulo { .. } => candidate_bitfield.len(),
|
||||
AssignmentCertKindV2::RelayVRFModuloCompact { core_bitfield } =>
|
||||
core_bitfield.len(),
|
||||
AssignmentCertKindV2::RelayVRFModuloCompact { core_bitfield } => {
|
||||
core_bitfield.len()
|
||||
},
|
||||
};
|
||||
|
||||
let candidate_bitfield_bits = candidate_bitfield.len();
|
||||
@@ -2411,8 +2412,8 @@ impl State {
|
||||
let mut sanitized_approvals = Vec::new();
|
||||
for approval in approval.into_iter() {
|
||||
let has_no_approved_candidates = approval.candidate_indices.first_one().is_none();
|
||||
if approval.candidate_indices.len() as usize > MAX_BITFIELD_SIZE ||
|
||||
has_no_approved_candidates
|
||||
if approval.candidate_indices.len() as usize > MAX_BITFIELD_SIZE
|
||||
|| has_no_approved_candidates
|
||||
{
|
||||
// Punish the peer for the invalid message.
|
||||
modify_reputation(
|
||||
@@ -2687,7 +2688,7 @@ impl ApprovalDistribution {
|
||||
session_info_provider: &mut RuntimeInfo,
|
||||
) -> bool {
|
||||
match message {
|
||||
FromOrchestra::Communication { msg } =>
|
||||
FromOrchestra::Communication { msg } => {
|
||||
Self::handle_incoming(
|
||||
approval_voting_sender,
|
||||
network_sender,
|
||||
@@ -2700,7 +2701,8 @@ impl ApprovalDistribution {
|
||||
self.clock.as_ref(),
|
||||
session_info_provider,
|
||||
)
|
||||
.await,
|
||||
.await
|
||||
},
|
||||
FromOrchestra::Signal(OverseerSignal::ActiveLeaves(_update)) => {
|
||||
gum::trace!(target: LOG_TARGET, "active leaves signal (ignored)");
|
||||
// the relay chain blocks relevant to the approval subsystems
|
||||
@@ -2849,9 +2851,9 @@ const fn ensure_size_not_zero(size: usize) -> usize {
|
||||
/// assignments we send in a single message to peers. Exceeding `MAX_NOTIFICATION_SIZE` will violate
|
||||
/// the protocol configuration.
|
||||
pub const MAX_ASSIGNMENT_BATCH_SIZE: usize = ensure_size_not_zero(
|
||||
MAX_NOTIFICATION_SIZE as usize /
|
||||
std::mem::size_of::<(IndirectAssignmentCertV2, CandidateIndex)>() /
|
||||
3,
|
||||
MAX_NOTIFICATION_SIZE as usize
|
||||
/ std::mem::size_of::<(IndirectAssignmentCertV2, CandidateIndex)>()
|
||||
/ 3,
|
||||
);
|
||||
|
||||
/// The maximum amount of approvals per batch is 33% of maximum allowed by protocol.
|
||||
|
||||
@@ -106,17 +106,17 @@ pub fn log_error(
|
||||
Ok(()) => Ok(()),
|
||||
Err(jfyi) => {
|
||||
match jfyi {
|
||||
JfyiError::UnexpectedPoV |
|
||||
JfyiError::InvalidValidatorIndex |
|
||||
JfyiError::NoSuchCachedSession { .. } |
|
||||
JfyiError::QueryAvailableDataResponseChannel(_) |
|
||||
JfyiError::QueryChunkResponseChannel(_) |
|
||||
JfyiError::FailedNodeFeatures(_) |
|
||||
JfyiError::ErasureCoding(_) => gum::warn!(target: LOG_TARGET, error = %jfyi, ctx),
|
||||
JfyiError::FetchPoV(_) |
|
||||
JfyiError::SendResponse |
|
||||
JfyiError::NoSuchPoV |
|
||||
JfyiError::Runtime(_) => {
|
||||
JfyiError::UnexpectedPoV
|
||||
| JfyiError::InvalidValidatorIndex
|
||||
| JfyiError::NoSuchCachedSession { .. }
|
||||
| JfyiError::QueryAvailableDataResponseChannel(_)
|
||||
| JfyiError::QueryChunkResponseChannel(_)
|
||||
| JfyiError::FailedNodeFeatures(_)
|
||||
| JfyiError::ErasureCoding(_) => gum::warn!(target: LOG_TARGET, error = %jfyi, ctx),
|
||||
JfyiError::FetchPoV(_)
|
||||
| JfyiError::SendResponse
|
||||
| JfyiError::NoSuchPoV
|
||||
| JfyiError::Runtime(_) => {
|
||||
gum::warn_if_frequent!(freq: warn_freq, max_rate: gum::Times::PerHour(100), target: LOG_TARGET, error = ?jfyi, ctx)
|
||||
},
|
||||
}
|
||||
|
||||
@@ -143,8 +143,9 @@ impl AvailabilityDistributionSubsystem {
|
||||
|
||||
// Handle task messages sending:
|
||||
let message = match action {
|
||||
Either::Left(subsystem_msg) =>
|
||||
subsystem_msg.map_err(|e| FatalError::IncomingMessageChannel(e))?,
|
||||
Either::Left(subsystem_msg) => {
|
||||
subsystem_msg.map_err(|e| FatalError::IncomingMessageChannel(e))?
|
||||
},
|
||||
Either::Right(from_task) => {
|
||||
let from_task = from_task.ok_or(FatalError::RequesterExhausted)?;
|
||||
ctx.send_message(from_task).await;
|
||||
|
||||
@@ -369,7 +369,7 @@ impl RunningTask {
|
||||
|
||||
match response_recv.await {
|
||||
Ok((bytes, protocol)) => match protocol {
|
||||
_ if protocol == self.req_v2_protocol_name =>
|
||||
_ if protocol == self.req_v2_protocol_name => {
|
||||
match v2::ChunkFetchingResponse::decode(&mut &bytes[..]) {
|
||||
Ok(chunk_response) => Ok(Option::<ErasureChunk>::from(chunk_response)),
|
||||
Err(e) => {
|
||||
@@ -386,8 +386,9 @@ impl RunningTask {
|
||||
);
|
||||
Err(TaskError::PeerError)
|
||||
},
|
||||
},
|
||||
_ if protocol == self.req_v1_protocol_name =>
|
||||
}
|
||||
},
|
||||
_ if protocol == self.req_v1_protocol_name => {
|
||||
match v1::ChunkFetchingResponse::decode(&mut &bytes[..]) {
|
||||
Ok(chunk_response) => Ok(Option::<ChunkResponse>::from(chunk_response)
|
||||
.map(|c| c.recombine_into_chunk(&self.request.into()))),
|
||||
@@ -405,7 +406,8 @@ impl RunningTask {
|
||||
);
|
||||
Err(TaskError::PeerError)
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
gum::warn!(
|
||||
target: LOG_TARGET,
|
||||
|
||||
@@ -296,15 +296,15 @@ impl TestRun {
|
||||
self.chunk_responses.get(&req.peer).ok_or(network::RequestFailure::Refused);
|
||||
|
||||
if let Ok((resp, protocol)) = response {
|
||||
let chunk = if protocol ==
|
||||
&self.req_protocol_names.get_name(Protocol::ChunkFetchingV1)
|
||||
let chunk = if protocol
|
||||
== &self.req_protocol_names.get_name(Protocol::ChunkFetchingV1)
|
||||
{
|
||||
Into::<Option<v1::ChunkResponse>>::into(
|
||||
v1::ChunkFetchingResponse::decode(&mut &resp[..]).unwrap(),
|
||||
)
|
||||
.map(|c| c.chunk)
|
||||
} else if protocol ==
|
||||
&self.req_protocol_names.get_name(Protocol::ChunkFetchingV2)
|
||||
} else if protocol
|
||||
== &self.req_protocol_names.get_name(Protocol::ChunkFetchingV2)
|
||||
{
|
||||
Into::<Option<ErasureChunk>>::into(
|
||||
v2::ChunkFetchingResponse::decode(&mut &resp[..]).unwrap(),
|
||||
|
||||
@@ -94,8 +94,8 @@ fn check_basic(#[case] node_features: NodeFeatures, #[case] chunk_resp_protocol:
|
||||
let state =
|
||||
TestState::new(node_features.clone(), req_protocol_names.clone(), chunk_resp_protocol);
|
||||
|
||||
if node_features == node_features_with_mapping_enabled() &&
|
||||
chunk_resp_protocol == Protocol::ChunkFetchingV1
|
||||
if node_features == node_features_with_mapping_enabled()
|
||||
&& chunk_resp_protocol == Protocol::ChunkFetchingV1
|
||||
{
|
||||
// For this specific case, chunk fetching is not possible, because the ValidatorIndex is not
|
||||
// equal to the ChunkIndex and the peer does not send back the actual ChunkIndex.
|
||||
@@ -128,8 +128,8 @@ fn check_fetch_tries_all(
|
||||
v.push(None);
|
||||
}
|
||||
|
||||
if node_features == node_features_with_mapping_enabled() &&
|
||||
chunk_resp_protocol == Protocol::ChunkFetchingV1
|
||||
if node_features == node_features_with_mapping_enabled()
|
||||
&& chunk_resp_protocol == Protocol::ChunkFetchingV1
|
||||
{
|
||||
// For this specific case, chunk fetching is not possible, because the ValidatorIndex is not
|
||||
// equal to the ChunkIndex and the peer does not send back the actual ChunkIndex.
|
||||
@@ -186,8 +186,8 @@ fn check_fetch_retry(#[case] node_features: NodeFeatures, #[case] chunk_resp_pro
|
||||
v.push(None);
|
||||
}
|
||||
|
||||
if node_features == node_features_with_mapping_enabled() &&
|
||||
chunk_resp_protocol == Protocol::ChunkFetchingV1
|
||||
if node_features == node_features_with_mapping_enabled()
|
||||
&& chunk_resp_protocol == Protocol::ChunkFetchingV1
|
||||
{
|
||||
// For this specific case, chunk fetching is not possible, because the ValidatorIndex is not
|
||||
// equal to the ChunkIndex and the peer does not send back the actual ChunkIndex.
|
||||
|
||||
@@ -418,8 +418,8 @@ async fn handle_recover<Context>(
|
||||
let mut small_pov_size = true;
|
||||
|
||||
match recovery_strategy_kind {
|
||||
RecoveryStrategyKind::BackersFirstIfSizeLower(fetch_chunks_threshold) |
|
||||
RecoveryStrategyKind::BackersFirstIfSizeLowerThenSystematicChunks(
|
||||
RecoveryStrategyKind::BackersFirstIfSizeLower(fetch_chunks_threshold)
|
||||
| RecoveryStrategyKind::BackersFirstIfSizeLowerThenSystematicChunks(
|
||||
fetch_chunks_threshold,
|
||||
) => {
|
||||
// Get our own chunk size to get an estimate of the PoV size.
|
||||
@@ -448,16 +448,17 @@ async fn handle_recover<Context>(
|
||||
};
|
||||
|
||||
match (&recovery_strategy_kind, small_pov_size) {
|
||||
(RecoveryStrategyKind::BackersFirstAlways, _) |
|
||||
(RecoveryStrategyKind::BackersFirstIfSizeLower(_), true) |
|
||||
(
|
||||
(RecoveryStrategyKind::BackersFirstAlways, _)
|
||||
| (RecoveryStrategyKind::BackersFirstIfSizeLower(_), true)
|
||||
| (
|
||||
RecoveryStrategyKind::BackersFirstIfSizeLowerThenSystematicChunks(_),
|
||||
true,
|
||||
) |
|
||||
(RecoveryStrategyKind::BackersThenSystematicChunks, _) =>
|
||||
)
|
||||
| (RecoveryStrategyKind::BackersThenSystematicChunks, _) => {
|
||||
recovery_strategies.push_back(Box::new(FetchFull::new(
|
||||
FetchFullParams { validators: backing_validators.to_vec() },
|
||||
))),
|
||||
)))
|
||||
},
|
||||
_ => {},
|
||||
};
|
||||
|
||||
@@ -479,9 +480,9 @@ async fn handle_recover<Context>(
|
||||
if let Some(core_index) = maybe_core_index {
|
||||
if matches!(
|
||||
recovery_strategy_kind,
|
||||
RecoveryStrategyKind::BackersThenSystematicChunks |
|
||||
RecoveryStrategyKind::SystematicChunks |
|
||||
RecoveryStrategyKind::BackersFirstIfSizeLowerThenSystematicChunks(_)
|
||||
RecoveryStrategyKind::BackersThenSystematicChunks
|
||||
| RecoveryStrategyKind::SystematicChunks
|
||||
| RecoveryStrategyKind::BackersFirstIfSizeLowerThenSystematicChunks(_)
|
||||
) && chunk_mapping_enabled
|
||||
{
|
||||
let chunk_indices =
|
||||
@@ -507,8 +508,8 @@ async fn handle_recover<Context>(
|
||||
.into_iter()
|
||||
.filter(|(c_index, _)| {
|
||||
usize::try_from(c_index.0)
|
||||
.expect("usize is at least u32 bytes on all modern targets.") <
|
||||
systematic_threshold
|
||||
.expect("usize is at least u32 bytes on all modern targets.")
|
||||
< systematic_threshold
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
||||
@@ -158,7 +158,7 @@ where
|
||||
let res = current_strategy.run(&mut self.state, &mut self.sender, &self.params).await;
|
||||
|
||||
match res {
|
||||
Err(RecoveryError::Unavailable) =>
|
||||
Err(RecoveryError::Unavailable) => {
|
||||
if self.strategies.front().is_some() {
|
||||
gum::debug!(
|
||||
target: LOG_TARGET,
|
||||
@@ -167,11 +167,13 @@ where
|
||||
display_name
|
||||
);
|
||||
continue;
|
||||
},
|
||||
}
|
||||
},
|
||||
Err(err) => {
|
||||
match &err {
|
||||
RecoveryError::Invalid =>
|
||||
self.params.metrics.on_recovery_invalid(strategy_type),
|
||||
RecoveryError::Invalid => {
|
||||
self.params.metrics.on_recovery_invalid(strategy_type)
|
||||
},
|
||||
_ => self.params.metrics.on_recovery_failed(strategy_type),
|
||||
}
|
||||
return Err(err);
|
||||
|
||||
@@ -191,8 +191,8 @@ impl<Sender: overseer::AvailabilityRecoverySenderTrait> RecoveryStrategy<Sender>
|
||||
// No need to query the validators that have the chunks we already received or that we know
|
||||
// don't have the data from previous strategies.
|
||||
self.validators.retain(|v_index| {
|
||||
!state.received_chunks.values().any(|c| v_index == &c.validator_index) &&
|
||||
state.can_retry_request(
|
||||
!state.received_chunks.values().any(|c| v_index == &c.validator_index)
|
||||
&& state.can_retry_request(
|
||||
&(common_params.validator_authority_keys[v_index.0 as usize].clone(), *v_index),
|
||||
REGULAR_CHUNKS_REQ_RETRY_LIMIT,
|
||||
)
|
||||
@@ -279,8 +279,8 @@ impl<Sender: overseer::AvailabilityRecoverySenderTrait> RecoveryStrategy<Sender>
|
||||
in_flight_reqs,
|
||||
chunk_count,
|
||||
_systematic_chunk_count| {
|
||||
chunk_count >= common_params.threshold ||
|
||||
Self::is_unavailable(
|
||||
chunk_count >= common_params.threshold
|
||||
|| Self::is_unavailable(
|
||||
unrequested_validators,
|
||||
in_flight_reqs,
|
||||
chunk_count,
|
||||
|
||||
@@ -113,8 +113,9 @@ impl<Sender: overseer::AvailabilityRecoverySenderTrait> RecoveryStrategy<Sender>
|
||||
|
||||
reencode_rx.await.map_err(|_| RecoveryError::ChannelClosed)?
|
||||
},
|
||||
PostRecoveryCheck::PovHash =>
|
||||
(data.pov.hash() == common_params.pov_hash).then_some(data),
|
||||
PostRecoveryCheck::PovHash => {
|
||||
(data.pov.hash() == common_params.pov_hash).then_some(data)
|
||||
},
|
||||
};
|
||||
|
||||
match maybe_data {
|
||||
@@ -150,8 +151,9 @@ impl<Sender: overseer::AvailabilityRecoverySenderTrait> RecoveryStrategy<Sender>
|
||||
Err(e) => {
|
||||
match &e {
|
||||
RequestError::Canceled(_) => common_params.metrics.on_full_request_error(),
|
||||
RequestError::InvalidResponse(_) =>
|
||||
common_params.metrics.on_full_request_invalid(),
|
||||
RequestError::InvalidResponse(_) => {
|
||||
common_params.metrics.on_full_request_invalid()
|
||||
},
|
||||
RequestError::NetworkError(req_failure) => {
|
||||
if let RequestFailure::Network(OutboundFailure::Timeout) = req_failure {
|
||||
common_params.metrics.on_full_request_timeout();
|
||||
|
||||
@@ -385,10 +385,12 @@ impl State {
|
||||
Ok((bytes, protocol)) => {
|
||||
if v2_protocol_name == protocol {
|
||||
match req_res::v2::ChunkFetchingResponse::decode(&mut &bytes[..]) {
|
||||
Ok(req_res::v2::ChunkFetchingResponse::Chunk(chunk)) =>
|
||||
Ok((Some(chunk.into()), protocol)),
|
||||
Ok(req_res::v2::ChunkFetchingResponse::NoSuchChunk) =>
|
||||
Ok((None, protocol)),
|
||||
Ok(req_res::v2::ChunkFetchingResponse::Chunk(chunk)) => {
|
||||
Ok((Some(chunk.into()), protocol))
|
||||
},
|
||||
Ok(req_res::v2::ChunkFetchingResponse::NoSuchChunk) => {
|
||||
Ok((None, protocol))
|
||||
},
|
||||
Err(e) => Err(RequestError::InvalidResponse(e)),
|
||||
}
|
||||
} else if v1_protocol_name == protocol {
|
||||
@@ -413,8 +415,9 @@ impl State {
|
||||
Some(chunk.recombine_into_chunk(&raw_request_v1)),
|
||||
protocol,
|
||||
)),
|
||||
Ok(req_res::v1::ChunkFetchingResponse::NoSuchChunk) =>
|
||||
Ok((None, protocol)),
|
||||
Ok(req_res::v1::ChunkFetchingResponse::NoSuchChunk) => {
|
||||
Ok((None, protocol))
|
||||
},
|
||||
Err(e) => Err(RequestError::InvalidResponse(e)),
|
||||
}
|
||||
} else {
|
||||
@@ -485,10 +488,12 @@ impl State {
|
||||
match request_result {
|
||||
Ok((maybe_chunk, protocol)) => {
|
||||
match protocol {
|
||||
name if name == params.req_v1_protocol_name =>
|
||||
params.metrics.on_chunk_response_v1(),
|
||||
name if name == params.req_v2_protocol_name =>
|
||||
params.metrics.on_chunk_response_v2(),
|
||||
name if name == params.req_v1_protocol_name => {
|
||||
params.metrics.on_chunk_response_v1()
|
||||
},
|
||||
name if name == params.req_v2_protocol_name => {
|
||||
params.metrics.on_chunk_response_v2()
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
|
||||
|
||||
@@ -104,8 +104,8 @@ impl FetchSystematicChunks {
|
||||
let chunks = state
|
||||
.received_chunks
|
||||
.range(
|
||||
ChunkIndex(0)..
|
||||
ChunkIndex(
|
||||
ChunkIndex(0)
|
||||
..ChunkIndex(
|
||||
u32::try_from(self.threshold)
|
||||
.expect("validator count should not exceed u32"),
|
||||
),
|
||||
@@ -180,8 +180,8 @@ impl<Sender: overseer::AvailabilityRecoverySenderTrait> RecoveryStrategy<Sender>
|
||||
for (_, our_c_index) in &local_chunk_indices {
|
||||
// If we are among the systematic validators but hold an invalid chunk, we cannot
|
||||
// perform the systematic recovery. Fall through to the next strategy.
|
||||
if self.validators.iter().any(|(c_index, _)| c_index == our_c_index) &&
|
||||
!state.received_chunks.contains_key(our_c_index)
|
||||
if self.validators.iter().any(|(c_index, _)| c_index == our_c_index)
|
||||
&& !state.received_chunks.contains_key(our_c_index)
|
||||
{
|
||||
gum::debug!(
|
||||
target: LOG_TARGET,
|
||||
@@ -201,8 +201,8 @@ impl<Sender: overseer::AvailabilityRecoverySenderTrait> RecoveryStrategy<Sender>
|
||||
// No need to query the validators that have the chunks we already received or that we know
|
||||
// don't have the data from previous strategies.
|
||||
self.validators.retain(|(c_index, v_index)| {
|
||||
!state.received_chunks.contains_key(c_index) &&
|
||||
state.can_retry_request(
|
||||
!state.received_chunks.contains_key(c_index)
|
||||
&& state.can_retry_request(
|
||||
&(common_params.validator_authority_keys[v_index.0 as usize].clone(), *v_index),
|
||||
SYSTEMATIC_CHUNKS_REQ_RETRY_LIMIT,
|
||||
)
|
||||
|
||||
@@ -2499,8 +2499,8 @@ fn systematic_chunks_are_not_requested_again_in_regular_recovery() {
|
||||
&mut virtual_overseer,
|
||||
1,
|
||||
|i| {
|
||||
if (test_state.chunks.get(i).unwrap().index.0 as usize) <
|
||||
test_state.systematic_threshold()
|
||||
if (test_state.chunks.get(i).unwrap().index.0 as usize)
|
||||
< test_state.systematic_threshold()
|
||||
{
|
||||
panic!("Already requested")
|
||||
} else {
|
||||
|
||||
@@ -90,11 +90,12 @@ impl BitfieldGossipMessage {
|
||||
recipient_version: ProtocolVersion,
|
||||
) -> net_protocol::BitfieldDistributionMessage {
|
||||
match ValidationVersion::try_from(recipient_version).ok() {
|
||||
Some(ValidationVersion::V3) =>
|
||||
Some(ValidationVersion::V3) => {
|
||||
ValidationProtocols::V3(protocol_v3::BitfieldDistributionMessage::Bitfield(
|
||||
self.relay_parent,
|
||||
self.signed_availability.into(),
|
||||
)),
|
||||
))
|
||||
},
|
||||
None => {
|
||||
gum::warn!(
|
||||
target: LOG_TARGET,
|
||||
@@ -187,8 +188,9 @@ impl PerRelayParentData {
|
||||
self.message_sent_to_peer
|
||||
.get(peer)
|
||||
.map(|pubkeys| !pubkeys.contains(signed_by))
|
||||
.unwrap_or(true) &&
|
||||
self.message_received_from_peer
|
||||
.unwrap_or(true)
|
||||
&& self
|
||||
.message_received_from_peer
|
||||
.get(peer)
|
||||
.map(|pubkeys| !pubkeys.contains(signed_by))
|
||||
.unwrap_or(true)
|
||||
@@ -729,8 +731,9 @@ async fn handle_network_msg<Context>(
|
||||
gum::trace!(target: LOG_TARGET, ?new_view, "Our view change");
|
||||
handle_our_view_change(state, new_view);
|
||||
},
|
||||
NetworkBridgeEvent::PeerMessage(remote, message) =>
|
||||
process_incoming_peer_message(ctx, state, metrics, remote, message, rng).await,
|
||||
NetworkBridgeEvent::PeerMessage(remote, message) => {
|
||||
process_incoming_peer_message(ctx, state, metrics, remote, message, rng).await
|
||||
},
|
||||
NetworkBridgeEvent::UpdatedAuthorityIds(peer_id, authority_ids) => {
|
||||
state
|
||||
.topologies
|
||||
@@ -794,8 +797,8 @@ async fn handle_peer_view_change<Context>(
|
||||
let topology = state.topologies.get_current_topology().local_grid_neighbors();
|
||||
let is_gossip_peer = topology.route_to_peer(RequiredRouting::GridXY, &origin);
|
||||
|
||||
let lucky = is_gossip_peer ||
|
||||
util::gen_ratio_rng(
|
||||
let lucky = is_gossip_peer
|
||||
|| util::gen_ratio_rng(
|
||||
util::MIN_GOSSIP_PEERS.saturating_sub(topology.len()),
|
||||
util::MIN_GOSSIP_PEERS,
|
||||
rng,
|
||||
@@ -904,8 +907,9 @@ async fn query_basics<Context>(
|
||||
.await;
|
||||
|
||||
match (validators_rx.await?, session_rx.await?) {
|
||||
(Ok(validators), Ok(session_index)) =>
|
||||
Ok(Some((validators, SigningContext { parent_hash: relay_parent, session_index }))),
|
||||
(Ok(validators), Ok(session_index)) => {
|
||||
Ok(Some((validators, SigningContext { parent_hash: relay_parent, session_index })))
|
||||
},
|
||||
(Err(err), _) | (_, Err(err)) => {
|
||||
gum::warn!(
|
||||
target: LOG_TARGET,
|
||||
|
||||
@@ -1024,8 +1024,8 @@ fn handle_peer_messages<RawMessage: Decode, OutMessage: From<RawMessage>>(
|
||||
|
||||
outgoing_events.push(match message {
|
||||
WireMessage::ViewUpdate(new_view) => {
|
||||
if new_view.len() > MAX_VIEW_HEADS ||
|
||||
new_view.finalized_number < peer_data.view.finalized_number
|
||||
if new_view.len() > MAX_VIEW_HEADS
|
||||
|| new_view.finalized_number < peer_data.view.finalized_number
|
||||
{
|
||||
reports.push(MALFORMED_VIEW_COST);
|
||||
continue;
|
||||
@@ -1040,8 +1040,9 @@ fn handle_peer_messages<RawMessage: Decode, OutMessage: From<RawMessage>>(
|
||||
NetworkBridgeEvent::PeerViewChange(peer, peer_data.view.clone())
|
||||
}
|
||||
},
|
||||
WireMessage::ProtocolMessage(message) =>
|
||||
NetworkBridgeEvent::PeerMessage(peer, message.into()),
|
||||
WireMessage::ProtocolMessage(message) => {
|
||||
NetworkBridgeEvent::PeerMessage(peer, message.into())
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1123,9 +1124,9 @@ async fn dispatch_validation_events_to_all<I>(
|
||||
// NetworkBridgeEvent::OurViewChange(..) must also be here,
|
||||
// but it is sent via an unbounded channel.
|
||||
// See https://github.com/pezkuwichain/pezkuwi-sdk/issues/108
|
||||
NetworkBridgeEvent::PeerConnected(..) |
|
||||
NetworkBridgeEvent::PeerDisconnected(..) |
|
||||
NetworkBridgeEvent::PeerViewChange(..)
|
||||
NetworkBridgeEvent::PeerConnected(..)
|
||||
| NetworkBridgeEvent::PeerDisconnected(..)
|
||||
| NetworkBridgeEvent::PeerViewChange(..)
|
||||
);
|
||||
let message = $message::from(event);
|
||||
if has_high_priority {
|
||||
|
||||
@@ -488,8 +488,8 @@ async fn await_peer_connections(
|
||||
loop {
|
||||
{
|
||||
let shared = shared.0.lock();
|
||||
if shared.validation_peers.len() == num_validation_peers &&
|
||||
shared.collation_peers.len() == num_collation_peers
|
||||
if shared.validation_peers.len() == num_validation_peers
|
||||
&& shared.collation_peers.len() == num_collation_peers
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -1516,13 +1516,16 @@ fn network_protocol_versioning_view_update() {
|
||||
|
||||
for &(peer_id, peer_set, version) in &peers {
|
||||
let wire_msg = match (version.into(), peer_set) {
|
||||
(1, PeerSet::Collation) =>
|
||||
WireMessage::<protocol_v1::CollationProtocol>::ViewUpdate(view.clone()).encode(),
|
||||
(2, PeerSet::Collation) =>
|
||||
WireMessage::<protocol_v2::CollationProtocol>::ViewUpdate(view.clone()).encode(),
|
||||
(3, PeerSet::Validation) =>
|
||||
(1, PeerSet::Collation) => {
|
||||
WireMessage::<protocol_v1::CollationProtocol>::ViewUpdate(view.clone()).encode()
|
||||
},
|
||||
(2, PeerSet::Collation) => {
|
||||
WireMessage::<protocol_v2::CollationProtocol>::ViewUpdate(view.clone()).encode()
|
||||
},
|
||||
(3, PeerSet::Validation) => {
|
||||
WireMessage::<protocol_v3::ValidationProtocol>::ViewUpdate(view.clone())
|
||||
.encode(),
|
||||
.encode()
|
||||
},
|
||||
_ => unreachable!(),
|
||||
};
|
||||
assert_network_actions_contains(
|
||||
|
||||
@@ -288,8 +288,9 @@ where
|
||||
metrics.on_message("chunk_fetching_v1")
|
||||
}
|
||||
},
|
||||
Requests::AvailableDataFetchingV1(_) =>
|
||||
metrics.on_message("available_data_fetching_v1"),
|
||||
Requests::AvailableDataFetchingV1(_) => {
|
||||
metrics.on_message("available_data_fetching_v1")
|
||||
},
|
||||
Requests::CollationFetchingV1(_) => metrics.on_message("collation_fetching_v1"),
|
||||
Requests::CollationFetchingV2(_) => metrics.on_message("collation_fetching_v2"),
|
||||
Requests::PoVFetchingV1(_) => metrics.on_message("pov_fetching_v1"),
|
||||
|
||||
@@ -1052,8 +1052,8 @@ async fn handle_incoming_peer_message<Context>(
|
||||
))
|
||||
.await;
|
||||
},
|
||||
CollationProtocols::V1(V1::AdvertiseCollation(_)) |
|
||||
CollationProtocols::V2(V2::AdvertiseCollation { .. }) => {
|
||||
CollationProtocols::V1(V1::AdvertiseCollation(_))
|
||||
| CollationProtocols::V2(V2::AdvertiseCollation { .. }) => {
|
||||
gum::trace!(
|
||||
target: LOG_TARGET,
|
||||
?origin,
|
||||
@@ -1174,8 +1174,9 @@ async fn handle_incoming_request<Context>(
|
||||
};
|
||||
|
||||
let collation_with_core = match &req {
|
||||
VersionedCollationRequest::V2(req) =>
|
||||
per_relay_parent.collations.get_mut(&req.payload.candidate_hash),
|
||||
VersionedCollationRequest::V2(req) => {
|
||||
per_relay_parent.collations.get_mut(&req.payload.candidate_hash)
|
||||
},
|
||||
};
|
||||
let (receipt, pov, parent_head_data) =
|
||||
if let Some(collation_with_core) = collation_with_core {
|
||||
@@ -1634,7 +1635,7 @@ fn process_out_of_view_collation(
|
||||
let candidate_hash = collation.receipt.hash();
|
||||
|
||||
match collation.status {
|
||||
CollationStatus::Created =>
|
||||
CollationStatus::Created => {
|
||||
if is_same_session {
|
||||
gum::warn!(
|
||||
target: LOG_TARGET,
|
||||
@@ -1649,7 +1650,8 @@ fn process_out_of_view_collation(
|
||||
pov_hash = ?collation.pov.hash(),
|
||||
"Collation wasn't advertised because it was built on a relay chain block that is now part of an old session.",
|
||||
)
|
||||
},
|
||||
}
|
||||
},
|
||||
CollationStatus::Advertised => gum::debug!(
|
||||
target: LOG_TARGET,
|
||||
?candidate_hash,
|
||||
|
||||
@@ -548,8 +548,9 @@ fn decode_collation_response(bytes: &[u8]) -> (CandidateReceipt, PoV) {
|
||||
CollationFetchingResponse::Collation(_, _) => {
|
||||
panic!("Expected to always receive CollationWithParentHeadData")
|
||||
},
|
||||
CollationFetchingResponse::CollationWithParentHeadData { receipt, pov, .. } =>
|
||||
(receipt, pov),
|
||||
CollationFetchingResponse::CollationWithParentHeadData { receipt, pov, .. } => {
|
||||
(receipt, pov)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -151,14 +151,16 @@ impl<Context> CollatorProtocolSubsystem {
|
||||
.boxed()
|
||||
},
|
||||
#[cfg(feature = "experimental-collator-protocol")]
|
||||
ProtocolSide::ValidatorExperimental { keystore, metrics } =>
|
||||
ProtocolSide::ValidatorExperimental { keystore, metrics } => {
|
||||
validator_side_experimental::run(ctx, keystore, metrics)
|
||||
.map_err(|e| SubsystemError::with_origin("collator-protocol", e))
|
||||
.boxed(),
|
||||
ProtocolSide::Collator { peer_id, collator_pair, request_receiver_v2, metrics } =>
|
||||
.boxed()
|
||||
},
|
||||
ProtocolSide::Collator { peer_id, collator_pair, request_receiver_v2, metrics } => {
|
||||
collator_side::run(ctx, peer_id, collator_pair, request_receiver_v2, metrics)
|
||||
.map_err(|e| SubsystemError::with_origin("collator-protocol", e))
|
||||
.boxed(),
|
||||
.boxed()
|
||||
},
|
||||
ProtocolSide::None => return DummySubsystem.start(ctx),
|
||||
};
|
||||
|
||||
|
||||
@@ -98,13 +98,13 @@ impl SecondingError {
|
||||
use SecondingError::*;
|
||||
matches!(
|
||||
self,
|
||||
PersistedValidationDataMismatch |
|
||||
CandidateHashMismatch |
|
||||
RelayParentMismatch |
|
||||
ParentHeadDataMismatch |
|
||||
InvalidCoreIndex(_, _) |
|
||||
InvalidSessionIndex(_, _) |
|
||||
InvalidReceiptVersion(_)
|
||||
PersistedValidationDataMismatch
|
||||
| CandidateHashMismatch
|
||||
| RelayParentMismatch
|
||||
| ParentHeadDataMismatch
|
||||
| InvalidCoreIndex(_, _)
|
||||
| InvalidSessionIndex(_, _)
|
||||
| InvalidReceiptVersion(_)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -335,8 +335,9 @@ impl PeerData {
|
||||
fn is_inactive(&self, policy: &crate::CollatorEvictionPolicy) -> bool {
|
||||
match self.state {
|
||||
PeerState::Connected(connected_at) => connected_at.elapsed() >= policy.undeclared,
|
||||
PeerState::Collating(ref state) =>
|
||||
state.last_active.elapsed() >= policy.inactive_collator,
|
||||
PeerState::Collating(ref state) => {
|
||||
state.last_active.elapsed() >= policy.inactive_collator
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -540,8 +541,8 @@ impl State {
|
||||
acc + blocked_collations
|
||||
.iter()
|
||||
.filter(|pc| {
|
||||
pc.candidate_receipt.descriptor.para_id() == *para_id &&
|
||||
pc.candidate_receipt.descriptor.relay_parent() == *relay_parent
|
||||
pc.candidate_receipt.descriptor.para_id() == *para_id
|
||||
&& pc.candidate_receipt.descriptor.relay_parent() == *relay_parent
|
||||
})
|
||||
.count()
|
||||
});
|
||||
@@ -747,14 +748,16 @@ async fn notify_collation_seconded(
|
||||
) {
|
||||
let statement = statement.into();
|
||||
let wire_message = match version {
|
||||
CollationVersion::V1 =>
|
||||
CollationVersion::V1 => {
|
||||
CollationProtocols::V1(protocol_v1::CollationProtocol::CollatorProtocol(
|
||||
protocol_v1::CollatorProtocolMessage::CollationSeconded(relay_parent, statement),
|
||||
)),
|
||||
CollationVersion::V2 =>
|
||||
))
|
||||
},
|
||||
CollationVersion::V2 => {
|
||||
CollationProtocols::V2(protocol_v2::CollationProtocol::CollatorProtocol(
|
||||
protocol_v2::CollatorProtocolMessage::CollationSeconded(relay_parent, statement),
|
||||
)),
|
||||
))
|
||||
},
|
||||
};
|
||||
sender
|
||||
.send_message(NetworkBridgeTxMessage::SendCollationMessage(vec![peer_id], wire_message))
|
||||
@@ -879,8 +882,8 @@ async fn process_incoming_peer_message<Context>(
|
||||
use protocol_v2::CollatorProtocolMessage as V2;
|
||||
|
||||
match msg {
|
||||
CollationProtocols::V1(V1::Declare(collator_id, para_id, signature)) |
|
||||
CollationProtocols::V2(V2::Declare(collator_id, para_id, signature)) => {
|
||||
CollationProtocols::V1(V1::Declare(collator_id, para_id, signature))
|
||||
| CollationProtocols::V2(V2::Declare(collator_id, para_id, signature)) => {
|
||||
if collator_peer_id(&state.peer_data, &collator_id).is_some() {
|
||||
modify_reputation(
|
||||
&mut state.reputation,
|
||||
@@ -1022,8 +1025,8 @@ async fn process_incoming_peer_message<Context>(
|
||||
}
|
||||
}
|
||||
},
|
||||
CollationProtocols::V1(V1::CollationSeconded(..)) |
|
||||
CollationProtocols::V2(V2::CollationSeconded(..)) => {
|
||||
CollationProtocols::V1(V1::CollationSeconded(..))
|
||||
| CollationProtocols::V2(V2::CollationSeconded(..)) => {
|
||||
gum::warn!(
|
||||
target: LOG_TARGET,
|
||||
peer_id = ?origin,
|
||||
@@ -1053,9 +1056,9 @@ fn hold_off_asset_hub_collation_if_needed(
|
||||
let peer_is_invulnerable = state.ah_invulnerables.contains(&peer_id);
|
||||
let invulnerables_set_is_empty = state.ah_invulnerables.is_empty();
|
||||
|
||||
if maybe_para_id != Some(ASSET_HUB_PARA_ID) ||
|
||||
peer_is_invulnerable ||
|
||||
invulnerables_set_is_empty
|
||||
if maybe_para_id != Some(ASSET_HUB_PARA_ID)
|
||||
|| peer_is_invulnerable
|
||||
|| invulnerables_set_is_empty
|
||||
{
|
||||
gum::trace!(
|
||||
target: LOG_TARGET,
|
||||
@@ -1269,8 +1272,8 @@ fn ensure_seconding_limit_is_respected(
|
||||
for path in paths {
|
||||
let mut cq_state = ClaimQueueState::new();
|
||||
for ancestor in &path {
|
||||
let seconded_and_pending = state.seconded_and_pending_for_para(&ancestor, ¶_id) +
|
||||
state.in_waiting_queue_for_para(relay_parent, ¶_id);
|
||||
let seconded_and_pending = state.seconded_and_pending_for_para(&ancestor, ¶_id)
|
||||
+ state.in_waiting_queue_for_para(relay_parent, ¶_id);
|
||||
cq_state.add_leaf(
|
||||
&ancestor,
|
||||
&state
|
||||
@@ -1847,9 +1850,11 @@ async fn process_msg<Context>(
|
||||
let candidate_hash = fetched_collation.candidate_hash;
|
||||
let id = match state.fetched_candidates.entry(fetched_collation) {
|
||||
Entry::Occupied(entry)
|
||||
if entry.get().pending_collation.commitments_hash ==
|
||||
Some(candidate_receipt.commitments_hash) =>
|
||||
entry.remove().collator_id,
|
||||
if entry.get().pending_collation.commitments_hash
|
||||
== Some(candidate_receipt.commitments_hash) =>
|
||||
{
|
||||
entry.remove().collator_id
|
||||
},
|
||||
Entry::Occupied(_) => {
|
||||
gum::error!(
|
||||
target: LOG_TARGET,
|
||||
@@ -2400,10 +2405,10 @@ async fn handle_collation_fetch_response(
|
||||
Err(None)
|
||||
},
|
||||
Ok(
|
||||
request_v1::CollationFetchingResponse::Collation(receipt, _) |
|
||||
request_v2::CollationFetchingResponse::Collation(receipt, _) |
|
||||
request_v1::CollationFetchingResponse::CollationWithParentHeadData { receipt, .. } |
|
||||
request_v2::CollationFetchingResponse::CollationWithParentHeadData { receipt, .. },
|
||||
request_v1::CollationFetchingResponse::Collation(receipt, _)
|
||||
| request_v2::CollationFetchingResponse::Collation(receipt, _)
|
||||
| request_v1::CollationFetchingResponse::CollationWithParentHeadData { receipt, .. }
|
||||
| request_v2::CollationFetchingResponse::CollationWithParentHeadData { receipt, .. },
|
||||
) if receipt.descriptor().para_id() != pending_collation.para_id => {
|
||||
gum::debug!(
|
||||
target: LOG_TARGET,
|
||||
@@ -2550,8 +2555,8 @@ fn get_next_collation_to_fetch(
|
||||
// to replace it.
|
||||
if let Some((collator_id, maybe_candidate_hash)) = rp_state.collations.fetching_from.as_ref() {
|
||||
// If a candidate hash was saved previously, `finished_one` must include this too.
|
||||
if collator_id != &finished_one.0 &&
|
||||
maybe_candidate_hash.map_or(true, |hash| Some(&hash) != finished_one.1.as_ref())
|
||||
if collator_id != &finished_one.0
|
||||
&& maybe_candidate_hash.map_or(true, |hash| Some(&hash) != finished_one.1.as_ref())
|
||||
{
|
||||
gum::trace!(
|
||||
target: LOG_TARGET,
|
||||
|
||||
@@ -416,18 +416,20 @@ async fn connect_and_declare_collator(
|
||||
.await;
|
||||
|
||||
let wire_message = match version {
|
||||
CollationVersion::V1 =>
|
||||
CollationVersion::V1 => {
|
||||
CollationProtocols::V1(protocol_v1::CollatorProtocolMessage::Declare(
|
||||
collator.public(),
|
||||
para_id,
|
||||
collator.sign(&protocol_v1::declare_signature_payload(&peer)),
|
||||
)),
|
||||
CollationVersion::V2 =>
|
||||
))
|
||||
},
|
||||
CollationVersion::V2 => {
|
||||
CollationProtocols::V2(protocol_v2::CollatorProtocolMessage::Declare(
|
||||
collator.public(),
|
||||
para_id,
|
||||
collator.sign(&protocol_v1::declare_signature_payload(&peer)),
|
||||
)),
|
||||
))
|
||||
},
|
||||
};
|
||||
|
||||
overseer_send(
|
||||
@@ -448,12 +450,13 @@ async fn advertise_collation(
|
||||
candidate: Option<(CandidateHash, Hash)>, // Candidate hash + parent head data hash.
|
||||
) {
|
||||
let wire_message = match candidate {
|
||||
Some((candidate_hash, parent_head_data_hash)) =>
|
||||
Some((candidate_hash, parent_head_data_hash)) => {
|
||||
CollationProtocols::V2(protocol_v2::CollatorProtocolMessage::AdvertiseCollation {
|
||||
relay_parent,
|
||||
candidate_hash,
|
||||
parent_head_data_hash,
|
||||
}),
|
||||
})
|
||||
},
|
||||
None => CollationProtocols::V1(protocol_v1::CollatorProtocolMessage::AdvertiseCollation(
|
||||
relay_parent,
|
||||
)),
|
||||
|
||||
+30
-20
@@ -104,12 +104,13 @@ impl ConnectedPeers {
|
||||
outcome = outcome.combine(res);
|
||||
}
|
||||
},
|
||||
PeerState::Connected =>
|
||||
PeerState::Connected => {
|
||||
for (para_id, per_para) in self.per_para.iter_mut() {
|
||||
let past_reputation = reputation_query_fn(peer_id, *para_id).await;
|
||||
let res = per_para.try_accept(peer_id, past_reputation);
|
||||
outcome = outcome.combine(res);
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
match outcome {
|
||||
@@ -567,12 +568,15 @@ mod tests {
|
||||
let rep_query_fn = |peer_id, para_id| async move {
|
||||
match (peer_id, para_id) {
|
||||
(peer_id, para_id) if peer_id == first_peer => Score::new(10).unwrap(),
|
||||
(peer_id, para_id) if peer_id == second_peer && para_id == para_1 =>
|
||||
Score::new(20).unwrap(),
|
||||
(peer_id, para_id) if peer_id == third_peer && para_id == para_2 =>
|
||||
Score::new(20).unwrap(),
|
||||
(peer_id, para_id) if peer_id == new_peer && para_id == para_1 =>
|
||||
Score::new(5).unwrap(),
|
||||
(peer_id, para_id) if peer_id == second_peer && para_id == para_1 => {
|
||||
Score::new(20).unwrap()
|
||||
},
|
||||
(peer_id, para_id) if peer_id == third_peer && para_id == para_2 => {
|
||||
Score::new(20).unwrap()
|
||||
},
|
||||
(peer_id, para_id) if peer_id == new_peer && para_id == para_1 => {
|
||||
Score::new(5).unwrap()
|
||||
},
|
||||
|
||||
(_, _) => Score::default(),
|
||||
}
|
||||
@@ -714,12 +718,15 @@ mod tests {
|
||||
let rep_query_fn = |peer_id, para_id| async move {
|
||||
match (peer_id, para_id) {
|
||||
(peer_id, para_id) if peer_id == first_peer => Score::new(10).unwrap(),
|
||||
(peer_id, para_id) if peer_id == second_peer && para_id == para_1 =>
|
||||
Score::new(20).unwrap(),
|
||||
(peer_id, para_id) if peer_id == third_peer && para_id == para_2 =>
|
||||
Score::new(20).unwrap(),
|
||||
(peer_id, para_id) if peer_id == fourth_peer && para_id == para_2 =>
|
||||
Score::new(15).unwrap(),
|
||||
(peer_id, para_id) if peer_id == second_peer && para_id == para_1 => {
|
||||
Score::new(20).unwrap()
|
||||
},
|
||||
(peer_id, para_id) if peer_id == third_peer && para_id == para_2 => {
|
||||
Score::new(20).unwrap()
|
||||
},
|
||||
(peer_id, para_id) if peer_id == fourth_peer && para_id == para_2 => {
|
||||
Score::new(15).unwrap()
|
||||
},
|
||||
(peer_id, para_id) if peer_id == new_peer => Score::new(30).unwrap(),
|
||||
|
||||
(_, _) => Score::default(),
|
||||
@@ -863,12 +870,15 @@ mod tests {
|
||||
let rep_query_fn = |peer_id, para_id| async move {
|
||||
match (peer_id, para_id) {
|
||||
(peer_id, para_id) if peer_id == first_peer => Score::new(10).unwrap(),
|
||||
(peer_id, para_id) if peer_id == second_peer && para_id == para_1 =>
|
||||
Score::new(5).unwrap(),
|
||||
(peer_id, para_id) if peer_id == third_peer && para_id == para_2 =>
|
||||
Score::new(5).unwrap(),
|
||||
(peer_id, para_id) if peer_id == new_peer && para_id == para_1 =>
|
||||
Score::new(8).unwrap(),
|
||||
(peer_id, para_id) if peer_id == second_peer && para_id == para_1 => {
|
||||
Score::new(5).unwrap()
|
||||
},
|
||||
(peer_id, para_id) if peer_id == third_peer && para_id == para_2 => {
|
||||
Score::new(5).unwrap()
|
||||
},
|
||||
(peer_id, para_id) if peer_id == new_peer && para_id == para_1 => {
|
||||
Score::new(8).unwrap()
|
||||
},
|
||||
|
||||
(_, _) => Score::default(),
|
||||
}
|
||||
|
||||
@@ -210,8 +210,9 @@ where
|
||||
Err(f) => Err(f),
|
||||
}
|
||||
},
|
||||
FromOrchestra::Communication { msg } =>
|
||||
self.handle_subsystem_message(&mut ctx, msg).await,
|
||||
FromOrchestra::Communication { msg } => {
|
||||
self.handle_subsystem_message(&mut ctx, msg).await
|
||||
},
|
||||
};
|
||||
log_error(result, "on FromOrchestra")?;
|
||||
},
|
||||
@@ -254,8 +255,9 @@ where
|
||||
msg: DisputeDistributionMessage,
|
||||
) -> Result<()> {
|
||||
match msg {
|
||||
DisputeDistributionMessage::SendDispute(dispute_msg) =>
|
||||
self.disputes_sender.start_sender(ctx, &mut self.runtime, dispute_msg).await?,
|
||||
DisputeDistributionMessage::SendDispute(dispute_msg) => {
|
||||
self.disputes_sender.start_sender(ctx, &mut self.runtime, dispute_msg).await?
|
||||
},
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -177,8 +177,8 @@ impl Batch {
|
||||
/// This function is supposed to be called at instants given at construction and as returned as
|
||||
/// part of `TickResult`.
|
||||
pub(super) fn tick(mut self, now: Instant) -> TickResult {
|
||||
if self.votes_batched_since_last_tick >= MIN_KEEP_BATCH_ALIVE_VOTES &&
|
||||
now < self.best_before
|
||||
if self.votes_batched_since_last_tick >= MIN_KEEP_BATCH_ALIVE_VOTES
|
||||
&& now < self.best_before
|
||||
{
|
||||
// Still good:
|
||||
let next_tick = self.calculate_next_tick(now);
|
||||
|
||||
@@ -315,8 +315,9 @@ async fn wait_response_task<M: 'static + Send + Sync>(
|
||||
let result = pending_response.await;
|
||||
let msg = match result {
|
||||
Err(err) => TaskFinish { candidate_hash, receiver, result: TaskResult::Failed(err) },
|
||||
Ok(DisputeResponse::Confirmed) =>
|
||||
TaskFinish { candidate_hash, receiver, result: TaskResult::Succeeded },
|
||||
Ok(DisputeResponse::Confirmed) => {
|
||||
TaskFinish { candidate_hash, receiver, result: TaskResult::Succeeded }
|
||||
},
|
||||
};
|
||||
if let Err(err) = tx.send_message(msg).await {
|
||||
gum::debug!(
|
||||
|
||||
@@ -210,7 +210,7 @@ where
|
||||
gum::debug!(target: LOG_TARGET, error = ?e);
|
||||
}
|
||||
},
|
||||
FromOrchestra::Signal(OverseerSignal::BlockFinalized(_hash, _number)) =>
|
||||
FromOrchestra::Signal(OverseerSignal::BlockFinalized(_hash, _number)) => {
|
||||
if let Some(session_index) = self.last_session_index {
|
||||
if let Err(e) = self
|
||||
.build_topology_for_last_finalized_if_needed(
|
||||
@@ -225,7 +225,8 @@ where
|
||||
e
|
||||
);
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
FromOrchestra::Signal(OverseerSignal::Conclude) => return self,
|
||||
}
|
||||
}
|
||||
@@ -394,8 +395,8 @@ where
|
||||
.await
|
||||
.await??;
|
||||
|
||||
if finalized_session_index < self.min_known_session &&
|
||||
Some(finalized_session_index) != self.finalized_needed_session
|
||||
if finalized_session_index < self.min_known_session
|
||||
&& Some(finalized_session_index) != self.finalized_needed_session
|
||||
{
|
||||
gum::debug!(
|
||||
target: LOG_TARGET,
|
||||
|
||||
@@ -586,12 +586,12 @@ impl RequiredRouting {
|
||||
match (self, other) {
|
||||
(RequiredRouting::All, _) | (_, RequiredRouting::All) => RequiredRouting::All,
|
||||
(RequiredRouting::GridXY, _) | (_, RequiredRouting::GridXY) => RequiredRouting::GridXY,
|
||||
(RequiredRouting::GridX, RequiredRouting::GridY) |
|
||||
(RequiredRouting::GridY, RequiredRouting::GridX) => RequiredRouting::GridXY,
|
||||
(RequiredRouting::GridX, RequiredRouting::GridY)
|
||||
| (RequiredRouting::GridY, RequiredRouting::GridX) => RequiredRouting::GridXY,
|
||||
(RequiredRouting::GridX, RequiredRouting::GridX) => RequiredRouting::GridX,
|
||||
(RequiredRouting::GridY, RequiredRouting::GridY) => RequiredRouting::GridY,
|
||||
(RequiredRouting::None, RequiredRouting::PendingTopology) |
|
||||
(RequiredRouting::PendingTopology, RequiredRouting::None) => RequiredRouting::PendingTopology,
|
||||
(RequiredRouting::None, RequiredRouting::PendingTopology)
|
||||
| (RequiredRouting::PendingTopology, RequiredRouting::None) => RequiredRouting::PendingTopology,
|
||||
(RequiredRouting::None, _) | (RequiredRouting::PendingTopology, _) => other,
|
||||
(_, RequiredRouting::None) | (_, RequiredRouting::PendingTopology) => self,
|
||||
}
|
||||
|
||||
@@ -346,8 +346,9 @@ macro_rules! impl_versioned_validation_try_from {
|
||||
fn try_from(x: &'a $from) -> Result<$out, Self::Error> {
|
||||
#[allow(unreachable_patterns)] // when there is only one variant
|
||||
match x {
|
||||
ValidationProtocols::V3($v3_pat) =>
|
||||
Ok(ValidationProtocols::V3($v3_out.clone())),
|
||||
ValidationProtocols::V3($v3_pat) => {
|
||||
Ok(ValidationProtocols::V3($v3_out.clone()))
|
||||
},
|
||||
_ => Err(crate::WrongVariant),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,20 +168,22 @@ impl PeerSet {
|
||||
// Unfortunately, labels must be static strings, so we must manually cover them
|
||||
// for all protocol versions here.
|
||||
match self {
|
||||
PeerSet::Validation =>
|
||||
PeerSet::Validation => {
|
||||
if version == ValidationVersion::V3.into() {
|
||||
Some("validation/3")
|
||||
} else {
|
||||
None
|
||||
},
|
||||
PeerSet::Collation =>
|
||||
}
|
||||
},
|
||||
PeerSet::Collation => {
|
||||
if version == CollationVersion::V1.into() {
|
||||
Some("collation/1")
|
||||
} else if version == CollationVersion::V2.into() {
|
||||
Some("collation/2")
|
||||
} else {
|
||||
None
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -320,7 +322,7 @@ impl PeerSetProtocolNames {
|
||||
let mut names = HashMap::new();
|
||||
for protocol in PeerSet::iter() {
|
||||
match protocol {
|
||||
PeerSet::Validation =>
|
||||
PeerSet::Validation => {
|
||||
for version in ValidationVersion::iter() {
|
||||
Self::register_main_protocol(
|
||||
&mut protocols,
|
||||
@@ -330,7 +332,8 @@ impl PeerSetProtocolNames {
|
||||
&genesis_hash,
|
||||
fork_id,
|
||||
);
|
||||
},
|
||||
}
|
||||
},
|
||||
PeerSet::Collation => {
|
||||
for version in CollationVersion::iter() {
|
||||
Self::register_main_protocol(
|
||||
@@ -566,7 +569,7 @@ mod tests {
|
||||
|
||||
for protocol in PeerSet::iter() {
|
||||
match protocol {
|
||||
PeerSet::Validation =>
|
||||
PeerSet::Validation => {
|
||||
for version in ValidationVersion::iter() {
|
||||
assert_eq!(
|
||||
protocol_names.get_name(protocol, version.into()),
|
||||
@@ -577,8 +580,9 @@ mod tests {
|
||||
version.into(),
|
||||
),
|
||||
);
|
||||
},
|
||||
PeerSet::Collation =>
|
||||
}
|
||||
},
|
||||
PeerSet::Collation => {
|
||||
for version in CollationVersion::iter() {
|
||||
assert_eq!(
|
||||
protocol_names.get_name(protocol, version.into()),
|
||||
@@ -589,7 +593,8 @@ mod tests {
|
||||
version.into(),
|
||||
),
|
||||
);
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -598,18 +603,20 @@ mod tests {
|
||||
fn all_protocol_versions_have_labels() {
|
||||
for protocol in PeerSet::iter() {
|
||||
match protocol {
|
||||
PeerSet::Validation =>
|
||||
PeerSet::Validation => {
|
||||
for version in ValidationVersion::iter() {
|
||||
protocol
|
||||
.get_protocol_label(version.into())
|
||||
.expect("All validation protocol versions must have a label.");
|
||||
},
|
||||
PeerSet::Collation =>
|
||||
}
|
||||
},
|
||||
PeerSet::Collation => {
|
||||
for version in CollationVersion::iter() {
|
||||
protocol
|
||||
.get_protocol_label(version.into())
|
||||
.expect("All collation protocol versions must have a label.");
|
||||
},
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,10 +74,10 @@ impl UnifiedReputationChange {
|
||||
/// Whether the reputation change is for good behavior.
|
||||
pub const fn is_benefit(&self) -> bool {
|
||||
match self {
|
||||
Self::BenefitMajorFirst(_) |
|
||||
Self::BenefitMajor(_) |
|
||||
Self::BenefitMinorFirst(_) |
|
||||
Self::BenefitMinor(_) => true,
|
||||
Self::BenefitMajorFirst(_)
|
||||
| Self::BenefitMajor(_)
|
||||
| Self::BenefitMinorFirst(_)
|
||||
| Self::BenefitMinor(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,8 +281,8 @@ impl Protocol {
|
||||
// wasting precious time.
|
||||
let available_bandwidth = 7 * MIN_BANDWIDTH_BYTES / 10;
|
||||
let size = u64::saturating_sub(
|
||||
ATTESTED_CANDIDATE_TIMEOUT.as_millis() as u64 * available_bandwidth /
|
||||
(1000 * MAX_CODE_SIZE as u64),
|
||||
ATTESTED_CANDIDATE_TIMEOUT.as_millis() as u64 * available_bandwidth
|
||||
/ (1000 * MAX_CODE_SIZE as u64),
|
||||
MAX_PARALLEL_ATTESTED_CANDIDATE_REQUESTS as u64,
|
||||
);
|
||||
debug_assert!(
|
||||
|
||||
@@ -91,9 +91,9 @@ impl RequestError {
|
||||
/// Whether the error represents some kind of timeout condition.
|
||||
pub fn is_timed_out(&self) -> bool {
|
||||
match self {
|
||||
Self::Canceled(_) |
|
||||
Self::NetworkError(network::RequestFailure::Obsolete) |
|
||||
Self::NetworkError(network::RequestFailure::Network(
|
||||
Self::Canceled(_)
|
||||
| Self::NetworkError(network::RequestFailure::Obsolete)
|
||||
| Self::NetworkError(network::RequestFailure::Network(
|
||||
network::OutboundFailure::Timeout,
|
||||
)) => true,
|
||||
_ => false,
|
||||
|
||||
@@ -185,9 +185,9 @@ impl Candidates {
|
||||
let mut reckoning = PostConfirmationReckoning::default();
|
||||
|
||||
for (leaf_hash, x) in u.unconfirmed_importable_under {
|
||||
if x.relay_parent == relay_parent &&
|
||||
x.parent_hash == parent_hash &&
|
||||
x.para_id == para_id
|
||||
if x.relay_parent == relay_parent
|
||||
&& x.parent_hash == parent_hash
|
||||
&& x.para_id == para_id
|
||||
{
|
||||
new_confirmed.importable_under.insert(leaf_hash);
|
||||
}
|
||||
@@ -296,8 +296,9 @@ impl Candidates {
|
||||
) {
|
||||
for (c_hash, candidate) in i {
|
||||
match candidate {
|
||||
CandidateState::Unconfirmed(u) =>
|
||||
u.extend_hypotheticals(*c_hash, v, maybe_required_parent),
|
||||
CandidateState::Unconfirmed(u) => {
|
||||
u.extend_hypotheticals(*c_hash, v, maybe_required_parent)
|
||||
},
|
||||
CandidateState::Confirmed(c) => v.push(c.to_hypothetical(*c_hash)),
|
||||
}
|
||||
}
|
||||
@@ -335,7 +336,7 @@ impl Candidates {
|
||||
}
|
||||
};
|
||||
self.candidates.retain(|c_hash, state| match state {
|
||||
CandidateState::Confirmed(ref mut c) =>
|
||||
CandidateState::Confirmed(ref mut c) => {
|
||||
if !relay_parent_live(&c.relay_parent()) {
|
||||
remove_parent_claims(*c_hash, c.parent_head_data_hash(), c.para_id());
|
||||
false
|
||||
@@ -344,7 +345,8 @@ impl Candidates {
|
||||
c.importable_under.remove(leaf_hash);
|
||||
}
|
||||
true
|
||||
},
|
||||
}
|
||||
},
|
||||
CandidateState::Unconfirmed(ref mut c) => {
|
||||
c.on_deactivate_leaves(
|
||||
leaves,
|
||||
@@ -393,9 +395,9 @@ impl CandidateClaims {
|
||||
parent_hash: Hash,
|
||||
para_id: ParaId,
|
||||
) -> bool {
|
||||
self.relay_parent == relay_parent &&
|
||||
self.group_index == group_index &&
|
||||
self.parent_hash_and_id.map_or(true, |p| p == (parent_hash, para_id))
|
||||
self.relay_parent == relay_parent
|
||||
&& self.group_index == group_index
|
||||
&& self.parent_hash_and_id.map_or(true, |p| p == (parent_hash, para_id))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -320,16 +320,16 @@ impl ClusterTracker {
|
||||
) -> bool {
|
||||
// we sent, they sent, or they signed and we received from someone else.
|
||||
|
||||
self.we_sent_seconded(validator, candidate_hash) ||
|
||||
self.they_sent_seconded(validator, candidate_hash) ||
|
||||
self.validator_seconded(validator, candidate_hash)
|
||||
self.we_sent_seconded(validator, candidate_hash)
|
||||
|| self.they_sent_seconded(validator, candidate_hash)
|
||||
|| self.validator_seconded(validator, candidate_hash)
|
||||
}
|
||||
|
||||
/// Whether a validator can request a candidate from us.
|
||||
pub fn can_request(&self, target: ValidatorIndex, candidate_hash: CandidateHash) -> bool {
|
||||
self.validators.contains(&target) &&
|
||||
self.we_sent_seconded(target, candidate_hash) &&
|
||||
!self.they_sent_seconded(target, candidate_hash)
|
||||
self.validators.contains(&target)
|
||||
&& self.we_sent_seconded(target, candidate_hash)
|
||||
&& !self.they_sent_seconded(target, candidate_hash)
|
||||
}
|
||||
|
||||
/// Returns a Vec of pending statements to be sent to a particular validator
|
||||
|
||||
@@ -283,11 +283,13 @@ impl GridTracker {
|
||||
// * They are in the sending set for the group AND we have sent them a manifest AND
|
||||
// the received manifest is partial.
|
||||
ManifestKind::Full => receiving_from,
|
||||
ManifestKind::Acknowledgement =>
|
||||
sending_to &&
|
||||
self.confirmed_backed
|
||||
ManifestKind::Acknowledgement => {
|
||||
sending_to
|
||||
&& self
|
||||
.confirmed_backed
|
||||
.get(&candidate_hash)
|
||||
.map_or(false, |c| c.has_sent_manifest_to(sender)),
|
||||
.map_or(false, |c| c.has_sent_manifest_to(sender))
|
||||
},
|
||||
};
|
||||
|
||||
if !manifest_allowed {
|
||||
@@ -1083,10 +1085,10 @@ impl KnownBackedCandidate {
|
||||
.filter(|k| k.local_knowledge.is_some())
|
||||
.and_then(|k| k.remote_knowledge.as_ref())
|
||||
.map(|remote| StatementFilter {
|
||||
seconded_in_group: full_local.seconded_in_group.clone() &
|
||||
!remote.seconded_in_group.clone(),
|
||||
validated_in_group: full_local.validated_in_group.clone() &
|
||||
!remote.validated_in_group.clone(),
|
||||
seconded_in_group: full_local.seconded_in_group.clone()
|
||||
& !remote.seconded_in_group.clone(),
|
||||
validated_in_group: full_local.validated_in_group.clone()
|
||||
& !remote.validated_in_group.clone(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -494,7 +494,7 @@ pub(crate) async fn handle_network_update<Context>(
|
||||
NetworkBridgeEvent::PeerMessage(peer_id, message) => match message {
|
||||
net_protocol::StatementDistributionMessage::V3(
|
||||
protocol_v3::StatementDistributionMessage::Statement(relay_parent, statement),
|
||||
) =>
|
||||
) => {
|
||||
handle_incoming_statement(
|
||||
ctx,
|
||||
state,
|
||||
@@ -504,18 +504,21 @@ pub(crate) async fn handle_network_update<Context>(
|
||||
reputation,
|
||||
metrics,
|
||||
)
|
||||
.await,
|
||||
.await
|
||||
},
|
||||
net_protocol::StatementDistributionMessage::V3(
|
||||
protocol_v3::StatementDistributionMessage::BackedCandidateManifest(inner),
|
||||
) => handle_incoming_manifest(ctx, state, peer_id, inner, reputation, metrics).await,
|
||||
net_protocol::StatementDistributionMessage::V3(
|
||||
protocol_v3::StatementDistributionMessage::BackedCandidateKnown(inner),
|
||||
) =>
|
||||
) => {
|
||||
handle_incoming_acknowledgement(ctx, state, peer_id, inner, reputation, metrics)
|
||||
.await,
|
||||
.await
|
||||
},
|
||||
},
|
||||
NetworkBridgeEvent::PeerViewChange(peer_id, view) => {
|
||||
handle_peer_view_update(ctx, state, peer_id, view, metrics).await
|
||||
},
|
||||
NetworkBridgeEvent::PeerViewChange(peer_id, view) =>
|
||||
handle_peer_view_update(ctx, state, peer_id, view, metrics).await,
|
||||
NetworkBridgeEvent::OurViewChange(_view) => {
|
||||
// handled by `handle_activated_leaf`
|
||||
},
|
||||
@@ -1161,10 +1164,12 @@ pub(crate) async fn share_local_statement<Context>(
|
||||
// Two possibilities: either the statement is `Seconded` or we already
|
||||
// have the candidate. Sanity: check the para-id is valid.
|
||||
let expected = match statement.payload() {
|
||||
FullStatementWithPVD::Seconded(ref c, _) =>
|
||||
Some((c.descriptor.para_id(), c.descriptor.relay_parent())),
|
||||
FullStatementWithPVD::Valid(hash) =>
|
||||
state.candidates.get_confirmed(&hash).map(|c| (c.para_id(), c.relay_parent())),
|
||||
FullStatementWithPVD::Seconded(ref c, _) => {
|
||||
Some((c.descriptor.para_id(), c.descriptor.relay_parent()))
|
||||
},
|
||||
FullStatementWithPVD::Valid(hash) => {
|
||||
state.candidates.get_confirmed(&hash).map(|c| (c.para_id(), c.relay_parent()))
|
||||
},
|
||||
};
|
||||
|
||||
let is_seconded = match statement.payload() {
|
||||
@@ -1183,8 +1188,8 @@ pub(crate) async fn share_local_statement<Context>(
|
||||
|
||||
let seconding_limit = local_assignments.len();
|
||||
|
||||
if is_seconded &&
|
||||
per_relay_parent.statement_store.seconded_count(&local_index) >= seconding_limit
|
||||
if is_seconded
|
||||
&& per_relay_parent.statement_store.seconded_count(&local_index) >= seconding_limit
|
||||
{
|
||||
gum::warn!(
|
||||
target: LOG_TARGET,
|
||||
@@ -1789,8 +1794,9 @@ fn handle_cluster_statement(
|
||||
Ok(ClusterAccept::Ok) => true,
|
||||
Ok(ClusterAccept::WithPrejudice) => false,
|
||||
Err(ClusterRejectIncoming::ExcessiveSeconded) => return Err(COST_EXCESSIVE_SECONDED),
|
||||
Err(ClusterRejectIncoming::CandidateUnknown | ClusterRejectIncoming::Duplicate) =>
|
||||
return Err(COST_UNEXPECTED_STATEMENT_CLUSTER_REJECTED),
|
||||
Err(ClusterRejectIncoming::CandidateUnknown | ClusterRejectIncoming::Duplicate) => {
|
||||
return Err(COST_UNEXPECTED_STATEMENT_CLUSTER_REJECTED)
|
||||
},
|
||||
Err(ClusterRejectIncoming::NotInGroup) => {
|
||||
// sanity: shouldn't be possible; we already filtered this
|
||||
// out above.
|
||||
@@ -1989,12 +1995,13 @@ async fn provide_candidate_to_grid<Context>(
|
||||
for (v, action) in actions {
|
||||
let p = match connected_validator_peer(authorities, per_session, v) {
|
||||
None => continue,
|
||||
Some(p) =>
|
||||
Some(p) => {
|
||||
if peers.get(&p).map_or(false, |d| d.knows_relay_parent(&relay_parent)) {
|
||||
(p, peers.get(&p).expect("Qed, was checked above").protocol_version.into())
|
||||
} else {
|
||||
continue;
|
||||
},
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
match action {
|
||||
@@ -2940,8 +2947,9 @@ pub(crate) async fn receive_response(response_manager: &mut ResponseManager) ->
|
||||
/// this API must call `dispatch_requests`.
|
||||
pub(crate) async fn next_retry(request_manager: &mut RequestManager) {
|
||||
match request_manager.next_retry_time() {
|
||||
Some(instant) =>
|
||||
futures_timer::Delay::new(instant.saturating_duration_since(Instant::now())).await,
|
||||
Some(instant) => {
|
||||
futures_timer::Delay::new(instant.saturating_duration_since(Instant::now())).await
|
||||
},
|
||||
None => futures::future::pending().await,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -583,12 +583,13 @@ impl UnhandledResponse {
|
||||
// it could also happen in the case that we had a request in-flight
|
||||
// and the request entry was garbage-collected on outdated relay parent.
|
||||
let entry = match manager.requests.get_mut(&identifier) {
|
||||
None =>
|
||||
None => {
|
||||
return ResponseValidationOutput {
|
||||
requested_peer,
|
||||
reputation_changes: Vec::new(),
|
||||
request_status: CandidateRequestStatus::Outdated,
|
||||
},
|
||||
}
|
||||
},
|
||||
Some(e) => e,
|
||||
};
|
||||
|
||||
@@ -710,8 +711,8 @@ fn validate_complete_response(
|
||||
return invalid_candidate_output(COST_INVALID_RESPONSE);
|
||||
}
|
||||
|
||||
if response.candidate_receipt.descriptor.persisted_validation_data_hash() !=
|
||||
response.persisted_validation_data.hash()
|
||||
if response.candidate_receipt.descriptor.persisted_validation_data_hash()
|
||||
!= response.persisted_validation_data.hash()
|
||||
{
|
||||
return invalid_candidate_output(COST_INVALID_RESPONSE);
|
||||
}
|
||||
@@ -730,8 +731,8 @@ fn validate_complete_response(
|
||||
let candidate_hash = response.candidate_receipt.hash();
|
||||
|
||||
// V2 descriptors are invalid if not enabled by runtime.
|
||||
if !allow_v2_descriptors &&
|
||||
response.candidate_receipt.descriptor.version() == CandidateDescriptorVersion::V2
|
||||
if !allow_v2_descriptors
|
||||
&& response.candidate_receipt.descriptor.version() == CandidateDescriptorVersion::V2
|
||||
{
|
||||
gum::debug!(
|
||||
target: LOG_TARGET,
|
||||
@@ -794,8 +795,8 @@ fn validate_complete_response(
|
||||
};
|
||||
|
||||
// ensure statement is on the correct candidate hash.
|
||||
if unchecked_statement.unchecked_payload().candidate_hash() !=
|
||||
&identifier.candidate_hash
|
||||
if unchecked_statement.unchecked_payload().candidate_hash()
|
||||
!= &identifier.candidate_hash
|
||||
{
|
||||
rep_changes.push((requested_peer, COST_UNREQUESTED_RESPONSE_STATEMENT));
|
||||
continue;
|
||||
|
||||
@@ -914,7 +914,7 @@ fn next_group_index(
|
||||
group_size: usize,
|
||||
) -> GroupIndex {
|
||||
let next_group = group_index.0 + 1;
|
||||
let num_groups =
|
||||
validator_count / group_size + if !validator_count.is_multiple_of(group_size) { 1 } else { 0 };
|
||||
let num_groups = validator_count / group_size
|
||||
+ if !validator_count.is_multiple_of(group_size) { 1 } else { 0 };
|
||||
GroupIndex::from(next_group % num_groups as u32)
|
||||
}
|
||||
|
||||
@@ -698,7 +698,7 @@ where
|
||||
#[cfg(any(target_os = "linux", feature = "jemalloc-allocator"))]
|
||||
let collect_memory_stats: Box<dyn Fn(&OverseerMetrics) + Send> =
|
||||
match memory_stats::MemoryAllocationTracker::new() {
|
||||
Ok(memory_stats) =>
|
||||
Ok(memory_stats) => {
|
||||
Box::new(move |metrics: &OverseerMetrics| match memory_stats.snapshot() {
|
||||
Ok(memory_stats_snapshot) => {
|
||||
gum::trace!(
|
||||
@@ -711,7 +711,8 @@ where
|
||||
Err(e) => {
|
||||
gum::debug!(target: LOG_TARGET, "Failed to obtain memory stats: {:?}", e)
|
||||
},
|
||||
}),
|
||||
})
|
||||
},
|
||||
Err(_) => {
|
||||
gum::debug!(
|
||||
target: LOG_TARGET,
|
||||
|
||||
@@ -447,8 +447,8 @@ fn overseer_start_stop_works() {
|
||||
complete => break,
|
||||
}
|
||||
|
||||
if ss5_results.len() == expected_heartbeats.len() &&
|
||||
ss6_results.len() == expected_heartbeats.len()
|
||||
if ss5_results.len() == expected_heartbeats.len()
|
||||
&& ss6_results.len() == expected_heartbeats.len()
|
||||
{
|
||||
handle.stop().await;
|
||||
}
|
||||
@@ -551,8 +551,8 @@ fn overseer_finalize_works() {
|
||||
complete => break,
|
||||
}
|
||||
|
||||
if ss5_results.len() == expected_heartbeats.len() &&
|
||||
ss6_results.len() == expected_heartbeats.len()
|
||||
if ss5_results.len() == expected_heartbeats.len()
|
||||
&& ss6_results.len() == expected_heartbeats.len()
|
||||
{
|
||||
handle.stop().await;
|
||||
}
|
||||
@@ -654,8 +654,8 @@ fn overseer_finalize_leaf_preserves_it() {
|
||||
complete => break,
|
||||
}
|
||||
|
||||
if ss5_results.len() == expected_heartbeats.len() &&
|
||||
ss6_results.len() == expected_heartbeats.len()
|
||||
if ss5_results.len() == expected_heartbeats.len()
|
||||
&& ss6_results.len() == expected_heartbeats.len()
|
||||
{
|
||||
handle.stop().await;
|
||||
}
|
||||
|
||||
@@ -412,10 +412,12 @@ pub mod v2 {
|
||||
fn from(cert: super::v1::AssignmentCert) -> Self {
|
||||
Self {
|
||||
kind: match cert.kind {
|
||||
super::v1::AssignmentCertKind::RelayVRFDelay { core_index } =>
|
||||
AssignmentCertKindV2::RelayVRFDelay { core_index },
|
||||
super::v1::AssignmentCertKind::RelayVRFModulo { sample } =>
|
||||
AssignmentCertKindV2::RelayVRFModulo { sample },
|
||||
super::v1::AssignmentCertKind::RelayVRFDelay { core_index } => {
|
||||
AssignmentCertKindV2::RelayVRFDelay { core_index }
|
||||
},
|
||||
super::v1::AssignmentCertKind::RelayVRFModulo { sample } => {
|
||||
AssignmentCertKindV2::RelayVRFModulo { sample }
|
||||
},
|
||||
},
|
||||
vrf: cert.vrf,
|
||||
}
|
||||
@@ -434,10 +436,12 @@ pub mod v2 {
|
||||
fn try_from(cert: AssignmentCertV2) -> Result<Self, AssignmentConversionError> {
|
||||
Ok(Self {
|
||||
kind: match cert.kind {
|
||||
AssignmentCertKindV2::RelayVRFDelay { core_index } =>
|
||||
super::v1::AssignmentCertKind::RelayVRFDelay { core_index },
|
||||
AssignmentCertKindV2::RelayVRFModulo { sample } =>
|
||||
super::v1::AssignmentCertKind::RelayVRFModulo { sample },
|
||||
AssignmentCertKindV2::RelayVRFDelay { core_index } => {
|
||||
super::v1::AssignmentCertKind::RelayVRFDelay { core_index }
|
||||
},
|
||||
AssignmentCertKindV2::RelayVRFModulo { sample } => {
|
||||
super::v1::AssignmentCertKind::RelayVRFModulo { sample }
|
||||
},
|
||||
// Not supported
|
||||
_ => return Err(AssignmentConversionError::CertificateNotSupported),
|
||||
},
|
||||
|
||||
@@ -113,11 +113,11 @@ impl ValidCandidateVotes {
|
||||
true
|
||||
},
|
||||
Bentry::Occupied(mut occupied) => match occupied.get().0 {
|
||||
ValidDisputeStatementKind::BackingValid(_) |
|
||||
ValidDisputeStatementKind::BackingSeconded(_) => false,
|
||||
ValidDisputeStatementKind::Explicit |
|
||||
ValidDisputeStatementKind::ApprovalChecking |
|
||||
ValidDisputeStatementKind::ApprovalCheckingMultipleCandidates(_) => {
|
||||
ValidDisputeStatementKind::BackingValid(_)
|
||||
| ValidDisputeStatementKind::BackingSeconded(_) => false,
|
||||
ValidDisputeStatementKind::Explicit
|
||||
| ValidDisputeStatementKind::ApprovalChecking
|
||||
| ValidDisputeStatementKind::ApprovalCheckingMultipleCandidates(_) => {
|
||||
occupied.insert((kind.clone(), sig));
|
||||
kind != occupied.get().0
|
||||
},
|
||||
|
||||
@@ -67,9 +67,9 @@ impl DisputeStatus {
|
||||
/// Check whether the dispute is not a spam dispute.
|
||||
pub fn is_confirmed_concluded(&self) -> bool {
|
||||
match self {
|
||||
&DisputeStatus::Confirmed |
|
||||
&DisputeStatus::ConcludedFor(_) |
|
||||
DisputeStatus::ConcludedAgainst(_) => true,
|
||||
&DisputeStatus::Confirmed
|
||||
| &DisputeStatus::ConcludedFor(_)
|
||||
| DisputeStatus::ConcludedAgainst(_) => true,
|
||||
&DisputeStatus::Active => false,
|
||||
}
|
||||
}
|
||||
@@ -103,21 +103,24 @@ impl DisputeStatus {
|
||||
/// candidate. This may be a no-op if the status was already concluded.
|
||||
pub fn conclude_against(self, now: Timestamp) -> DisputeStatus {
|
||||
match self {
|
||||
DisputeStatus::Active | DisputeStatus::Confirmed =>
|
||||
DisputeStatus::ConcludedAgainst(now),
|
||||
DisputeStatus::ConcludedFor(at) =>
|
||||
DisputeStatus::ConcludedAgainst(std::cmp::min(at, now)),
|
||||
DisputeStatus::ConcludedAgainst(at) =>
|
||||
DisputeStatus::ConcludedAgainst(std::cmp::min(at, now)),
|
||||
DisputeStatus::Active | DisputeStatus::Confirmed => {
|
||||
DisputeStatus::ConcludedAgainst(now)
|
||||
},
|
||||
DisputeStatus::ConcludedFor(at) => {
|
||||
DisputeStatus::ConcludedAgainst(std::cmp::min(at, now))
|
||||
},
|
||||
DisputeStatus::ConcludedAgainst(at) => {
|
||||
DisputeStatus::ConcludedAgainst(std::cmp::min(at, now))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether the disputed candidate is possibly invalid.
|
||||
pub fn is_possibly_invalid(&self) -> bool {
|
||||
match self {
|
||||
DisputeStatus::Active |
|
||||
DisputeStatus::Confirmed |
|
||||
DisputeStatus::ConcludedAgainst(_) => true,
|
||||
DisputeStatus::Active
|
||||
| DisputeStatus::Confirmed
|
||||
| DisputeStatus::ConcludedAgainst(_) => true,
|
||||
DisputeStatus::ConcludedFor(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,8 +231,8 @@ where
|
||||
let force_authoring = config.force_authoring;
|
||||
let disable_grandpa = config.disable_grandpa;
|
||||
let name = config.network.node_name.clone();
|
||||
let backoff_authoring_blocks = if !force_authoring_backoff &&
|
||||
(config.chain_spec.is_pezkuwi() || config.chain_spec.is_kusama())
|
||||
let backoff_authoring_blocks = if !force_authoring_backoff
|
||||
&& (config.chain_spec.is_pezkuwi() || config.chain_spec.is_kusama())
|
||||
{
|
||||
// the block authoring backoff is disabled by default on production networks
|
||||
None
|
||||
@@ -240,9 +240,9 @@ where
|
||||
let mut backoff =
|
||||
pezsc_consensus_slots::BackoffAuthoringOnFinalizedHeadLagging::default();
|
||||
|
||||
if config.chain_spec.is_pezkuwichain() ||
|
||||
config.chain_spec.is_versi() ||
|
||||
config.chain_spec.is_dev()
|
||||
if config.chain_spec.is_pezkuwichain()
|
||||
|| config.chain_spec.is_versi()
|
||||
|| config.chain_spec.is_dev()
|
||||
{
|
||||
// on testnets that are in flux (like pezkuwichain or versi), finality has stalled
|
||||
// sometimes due to operational issues and it's annoying to slow down block
|
||||
@@ -316,8 +316,8 @@ where
|
||||
//
|
||||
// Collators and teyrchain full nodes require the collator and validator networking to send
|
||||
// collations and to be able to recover PoVs.
|
||||
let notification_services = if role.is_authority() ||
|
||||
is_teyrchain_node.is_running_alongside_teyrchain_node()
|
||||
let notification_services = if role.is_authority()
|
||||
|| is_teyrchain_node.is_running_alongside_teyrchain_node()
|
||||
{
|
||||
use pezkuwi_network_bridge::{peer_sets_info, IsAuthority};
|
||||
let is_authority = if role.is_authority() { IsAuthority::Yes } else { IsAuthority::No };
|
||||
|
||||
@@ -450,10 +450,12 @@ pub fn build_full<OverseerGenerator: OverseerGen>(
|
||||
});
|
||||
|
||||
match config.network.network_backend {
|
||||
pezsc_network::config::NetworkBackendType::Libp2p =>
|
||||
new_full::<_, pezsc_network::NetworkWorker<Block, Hash>>(config, params),
|
||||
pezsc_network::config::NetworkBackendType::Litep2p =>
|
||||
new_full::<_, pezsc_network::Litep2pNetworkBackend>(config, params),
|
||||
pezsc_network::config::NetworkBackendType::Libp2p => {
|
||||
new_full::<_, pezsc_network::NetworkWorker<Block, Hash>>(config, params)
|
||||
},
|
||||
pezsc_network::config::NetworkBackendType::Litep2p => {
|
||||
new_full::<_, pezsc_network::Litep2pNetworkBackend>(config, params)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -295,10 +295,11 @@ where
|
||||
.collation_generation(DummySubsystem)
|
||||
.collator_protocol({
|
||||
let side = match is_teyrchain_node {
|
||||
IsTeyrchainNode::Collator(_) | IsTeyrchainNode::FullNode =>
|
||||
IsTeyrchainNode::Collator(_) | IsTeyrchainNode::FullNode => {
|
||||
return Err(Error::Overseer(SubsystemError::Context(
|
||||
"build validator overseer for teyrchain node".to_owned(),
|
||||
))),
|
||||
)))
|
||||
},
|
||||
IsTeyrchainNode::No => ProtocolSide::Validator {
|
||||
keystore: keystore.clone(),
|
||||
eviction_policy: Default::default(),
|
||||
@@ -466,10 +467,11 @@ where
|
||||
.collation_generation(CollationGenerationSubsystem::new(Metrics::register(registry)?))
|
||||
.collator_protocol({
|
||||
let side = match is_teyrchain_node {
|
||||
IsTeyrchainNode::No =>
|
||||
IsTeyrchainNode::No => {
|
||||
return Err(Error::Overseer(SubsystemError::Context(
|
||||
"build teyrchain node overseer for validator".to_owned(),
|
||||
))),
|
||||
)))
|
||||
},
|
||||
IsTeyrchainNode::Collator(collator_pair) => ProtocolSide::Collator {
|
||||
peer_id: network_service.local_peer_id(),
|
||||
collator_pair,
|
||||
|
||||
@@ -251,8 +251,9 @@ where
|
||||
fn block_header(&self, hash: Hash) -> Result<PezkuwiHeader, ConsensusError> {
|
||||
match HeaderProvider::header(self.backend.header_provider(), hash) {
|
||||
Ok(Some(header)) => Ok(header),
|
||||
Ok(None) =>
|
||||
Err(ConsensusError::ChainLookup(format!("Missing header with hash {:?}", hash,))),
|
||||
Ok(None) => {
|
||||
Err(ConsensusError::ChainLookup(format!("Missing header with hash {:?}", hash,)))
|
||||
},
|
||||
Err(e) => Err(ConsensusError::ChainLookup(format!(
|
||||
"Lookup failed for header with hash {:?}: {:?}",
|
||||
hash, e,
|
||||
@@ -263,8 +264,9 @@ where
|
||||
fn block_number(&self, hash: Hash) -> Result<BlockNumber, ConsensusError> {
|
||||
match HeaderProvider::number(self.backend.header_provider(), hash) {
|
||||
Ok(Some(number)) => Ok(number),
|
||||
Ok(None) =>
|
||||
Err(ConsensusError::ChainLookup(format!("Missing number with hash {:?}", hash,))),
|
||||
Ok(None) => {
|
||||
Err(ConsensusError::ChainLookup(format!("Missing number with hash {:?}", hash,)))
|
||||
},
|
||||
Err(e) => Err(ConsensusError::ChainLookup(format!(
|
||||
"Lookup failed for number with hash {:?}: {:?}",
|
||||
hash, e,
|
||||
@@ -490,8 +492,9 @@ where
|
||||
{
|
||||
// No approved ancestors means target hash is maximal vote.
|
||||
None => (target_hash, target_number, Vec::new()),
|
||||
Some(HighestApprovedAncestorBlock { number, hash, descriptions }) =>
|
||||
(hash, number, descriptions),
|
||||
Some(HighestApprovedAncestorBlock { number, hash, descriptions }) => {
|
||||
(hash, number, descriptions)
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
@@ -523,8 +526,8 @@ where
|
||||
|
||||
let (lag, subchain_head) = {
|
||||
// Prevent sending flawed data to the dispute-coordinator.
|
||||
if Some(subchain_block_descriptions.len() as _) !=
|
||||
subchain_number.checked_sub(target_number)
|
||||
if Some(subchain_block_descriptions.len() as _)
|
||||
!= subchain_number.checked_sub(target_number)
|
||||
{
|
||||
gum::error!(
|
||||
LOG_TARGET,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user