mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 12:51:02 +00:00
Improve diagnostics for the ValidationOutputs checker / inclusion (#1926)
* Improve diagnostics for acceptance criteria failures during inclusion * Initialize the runtime logger just before logging during inclusion * Formatting suggestions Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> * Missed one suggestion Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
This commit is contained in:
@@ -186,8 +186,9 @@ decl_module! {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Trait> Module<T> {
|
||||
const LOG_TARGET: &str = "parachains_runtime_inclusion";
|
||||
|
||||
impl<T: Trait> Module<T> {
|
||||
/// Block initialization logic, called by initializer.
|
||||
pub(crate) fn initializer_initialize(_now: T::BlockNumber) -> Weight { 0 }
|
||||
|
||||
@@ -400,7 +401,7 @@ impl<T: Trait> Module<T> {
|
||||
// In the meantime, we do certain sanity checks on the candidates and on the scheduled
|
||||
// list.
|
||||
'a:
|
||||
for candidate in &candidates {
|
||||
for (candidate_idx, candidate) in candidates.iter().enumerate() {
|
||||
let para_id = candidate.descriptor().para_id;
|
||||
|
||||
// we require that the candidate is in the context of the parent block.
|
||||
@@ -413,15 +414,27 @@ impl<T: Trait> Module<T> {
|
||||
Error::<T>::NotCollatorSigned,
|
||||
);
|
||||
|
||||
check_cx.check_validation_outputs(
|
||||
para_id,
|
||||
&candidate.candidate.commitments.head_data,
|
||||
&candidate.candidate.commitments.new_validation_code,
|
||||
candidate.candidate.commitments.processed_downward_messages,
|
||||
&candidate.candidate.commitments.upward_messages,
|
||||
T::BlockNumber::from(candidate.candidate.commitments.hrmp_watermark),
|
||||
&candidate.candidate.commitments.horizontal_messages,
|
||||
)?;
|
||||
if let Err(err) = check_cx
|
||||
.check_validation_outputs(
|
||||
para_id,
|
||||
&candidate.candidate.commitments.head_data,
|
||||
&candidate.candidate.commitments.new_validation_code,
|
||||
candidate.candidate.commitments.processed_downward_messages,
|
||||
&candidate.candidate.commitments.upward_messages,
|
||||
T::BlockNumber::from(candidate.candidate.commitments.hrmp_watermark),
|
||||
&candidate.candidate.commitments.horizontal_messages,
|
||||
)
|
||||
{
|
||||
frame_support::debug::RuntimeLogger::init();
|
||||
log::debug!(
|
||||
target: LOG_TARGET,
|
||||
"Validation outputs checking during inclusion of a candidate {} for parachain `{}` failed: {:?}",
|
||||
candidate_idx,
|
||||
u32::from(para_id),
|
||||
err,
|
||||
);
|
||||
Err(err.strip_into_dispatch_err::<T>())?;
|
||||
};
|
||||
|
||||
for (i, assignment) in scheduled[skip..].iter().enumerate() {
|
||||
check_assignment_in_order(assignment)?;
|
||||
@@ -542,13 +555,11 @@ impl<T: Trait> Module<T> {
|
||||
}
|
||||
|
||||
/// Run the acceptance criteria checks on the given candidate commitments.
|
||||
///
|
||||
/// Returns an 'Err` if any of the checks doesn't pass.
|
||||
pub(crate) fn check_validation_outputs(
|
||||
para_id: ParaId,
|
||||
validation_outputs: primitives::v1::ValidationOutputs,
|
||||
) -> Result<(), DispatchError> {
|
||||
CandidateCheckContext::<T>::new().check_validation_outputs(
|
||||
) -> bool {
|
||||
if let Err(err) = CandidateCheckContext::<T>::new().check_validation_outputs(
|
||||
para_id,
|
||||
&validation_outputs.head_data,
|
||||
&validation_outputs.new_validation_code,
|
||||
@@ -556,7 +567,18 @@ impl<T: Trait> Module<T> {
|
||||
&validation_outputs.upward_messages,
|
||||
T::BlockNumber::from(validation_outputs.hrmp_watermark),
|
||||
&validation_outputs.horizontal_messages,
|
||||
)
|
||||
) {
|
||||
frame_support::debug::RuntimeLogger::init();
|
||||
log::debug!(
|
||||
target: LOG_TARGET,
|
||||
"Validation outputs checking for parachain `{}` failed: {:?}",
|
||||
u32::from(para_id),
|
||||
err,
|
||||
);
|
||||
false
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
fn enact_candidate(
|
||||
@@ -692,6 +714,34 @@ const fn availability_threshold(n_validators: usize) -> usize {
|
||||
threshold
|
||||
}
|
||||
|
||||
#[derive(derive_more::From, Debug)]
|
||||
enum AcceptanceCheckErr<BlockNumber> {
|
||||
HeadDataTooLarge,
|
||||
PrematureCodeUpgrade,
|
||||
NewCodeTooLarge,
|
||||
ProcessedDownwardMessages(router::ProcessedDownwardMessagesAcceptanceErr),
|
||||
UpwardMessages(router::UpwardMessagesAcceptanceCheckErr),
|
||||
HrmpWatermark(router::HrmpWatermarkAcceptanceErr<BlockNumber>),
|
||||
OutboundHrmp(router::OutboundHrmpAcceptanceErr),
|
||||
}
|
||||
|
||||
impl<BlockNumber> AcceptanceCheckErr<BlockNumber> {
|
||||
/// Returns the same error so that it can be threaded through a needle of `DispatchError` and
|
||||
/// ultimately returned from a `Dispatchable`.
|
||||
fn strip_into_dispatch_err<T: Trait>(self) -> Error<T> {
|
||||
use AcceptanceCheckErr::*;
|
||||
match self {
|
||||
HeadDataTooLarge => Error::<T>::HeadDataTooLarge,
|
||||
PrematureCodeUpgrade => Error::<T>::PrematureCodeUpgrade,
|
||||
NewCodeTooLarge => Error::<T>::NewCodeTooLarge,
|
||||
ProcessedDownwardMessages(_) => Error::<T>::IncorrectDownwardMessageHandling,
|
||||
UpwardMessages(_) => Error::<T>::InvalidUpwardMessages,
|
||||
HrmpWatermark(_) => Error::<T>::HrmpWatermarkMishandling,
|
||||
OutboundHrmp(_) => Error::<T>::InvalidOutboundHrmp,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A collection of data required for checking a candidate.
|
||||
struct CandidateCheckContext<T: Trait> {
|
||||
config: configuration::HostConfiguration<T::BlockNumber>,
|
||||
@@ -720,10 +770,10 @@ impl<T: Trait> CandidateCheckContext<T> {
|
||||
upward_messages: &[primitives::v1::UpwardMessage],
|
||||
hrmp_watermark: T::BlockNumber,
|
||||
horizontal_messages: &[primitives::v1::OutboundHrmpMessage<ParaId>],
|
||||
) -> Result<(), DispatchError> {
|
||||
) -> Result<(), AcceptanceCheckErr<T::BlockNumber>> {
|
||||
ensure!(
|
||||
head_data.0.len() <= self.config.max_head_data_size as _,
|
||||
Error::<T>::HeadDataTooLarge
|
||||
AcceptanceCheckErr::HeadDataTooLarge,
|
||||
);
|
||||
|
||||
// if any, the code upgrade attempt is allowed.
|
||||
@@ -734,45 +784,28 @@ impl<T: Trait> CandidateCheckContext<T> {
|
||||
&& self.relay_parent_number.saturating_sub(last)
|
||||
>= self.config.validation_upgrade_frequency
|
||||
});
|
||||
ensure!(valid_upgrade_attempt, Error::<T>::PrematureCodeUpgrade);
|
||||
ensure!(
|
||||
valid_upgrade_attempt,
|
||||
AcceptanceCheckErr::PrematureCodeUpgrade,
|
||||
);
|
||||
ensure!(
|
||||
new_validation_code.0.len() <= self.config.max_code_size as _,
|
||||
Error::<T>::NewCodeTooLarge
|
||||
AcceptanceCheckErr::NewCodeTooLarge,
|
||||
);
|
||||
}
|
||||
|
||||
// check if the candidate passes the messaging acceptance criteria
|
||||
ensure!(
|
||||
<router::Module<T>>::check_processed_downward_messages(
|
||||
para_id,
|
||||
processed_downward_messages,
|
||||
),
|
||||
Error::<T>::IncorrectDownwardMessageHandling,
|
||||
);
|
||||
ensure!(
|
||||
<router::Module<T>>::check_upward_messages(
|
||||
&self.config,
|
||||
para_id,
|
||||
upward_messages,
|
||||
),
|
||||
Error::<T>::InvalidUpwardMessages,
|
||||
);
|
||||
ensure!(
|
||||
<router::Module<T>>::check_hrmp_watermark(
|
||||
para_id,
|
||||
self.relay_parent_number,
|
||||
hrmp_watermark,
|
||||
),
|
||||
Error::<T>::HrmpWatermarkMishandling,
|
||||
);
|
||||
ensure!(
|
||||
<router::Module<T>>::check_outbound_hrmp(
|
||||
&self.config,
|
||||
para_id,
|
||||
horizontal_messages,
|
||||
),
|
||||
Error::<T>::InvalidOutboundHrmp,
|
||||
);
|
||||
<router::Module<T>>::check_processed_downward_messages(
|
||||
para_id,
|
||||
processed_downward_messages,
|
||||
)?;
|
||||
<router::Module<T>>::check_upward_messages(&self.config, para_id, upward_messages)?;
|
||||
<router::Module<T>>::check_hrmp_watermark(
|
||||
para_id,
|
||||
self.relay_parent_number,
|
||||
hrmp_watermark,
|
||||
)?;
|
||||
<router::Module<T>>::check_outbound_hrmp(&self.config, para_id, horizontal_messages)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user