Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Refactor check validation outputs - Backport of #4727 into v0.9.16 #4801

Merged
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 45 additions & 30 deletions runtime/parachains/src/inclusion/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -524,11 +524,26 @@ impl<T: Config> Pallet<T> {
candidates.iter().enumerate()
{
if let FullCheck::Yes = full_check {
check_ctx.verify_backed_candidate(
match check_ctx.verify_backed_candidate(
parent_hash,
parent_storage_root,
candidate_idx,
backed_candidate,
)?;
)? {
Err(FailedToCreatePVD) => {
log::debug!(
target: LOG_TARGET,
"Failed to create PVD for candidate {} on relay parent {:?}",
candidate_idx,
parent_hash,
);
// We don't want to error out here because it will
// brick the relay-chain. So we return early without
// doing anything.
return Ok(ProcessedCandidates::default())
},
Ok(rpn) => rpn,
}
}

let para_id = backed_candidate.descriptor().para_id;
Expand All @@ -545,32 +560,6 @@ impl<T: Config> Pallet<T> {
);
}

{
// this should never fail because the para is registered
let persisted_validation_data =
match crate::util::make_persisted_validation_data::<T>(
para_id,
relay_parent_number,
parent_storage_root,
) {
Some(l) => l,
None => {
// We don't want to error out here because it will
// brick the relay-chain. So we return early without
// doing anything.
return Ok(ProcessedCandidates::default())
},
};

let expected = persisted_validation_data.hash();

ensure!(
expected ==
backed_candidate.descriptor().persisted_validation_data_hash,
Error::<T>::ValidationDataHashMismatch,
);
}

ensure!(
<PendingAvailability<T>>::get(&para_id).is_none() &&
<PendingAvailabilityCommitments<T>>::get(&para_id).is_none(),
Expand Down Expand Up @@ -952,6 +941,10 @@ pub(crate) struct CandidateCheckContext<T: Config> {
relay_parent_number: T::BlockNumber,
}

/// An error indicating that creating Persisted Validation Data failed
/// while checking a candidate's validity.
pub(crate) struct FailedToCreatePVD;

impl<T: Config> CandidateCheckContext<T> {
pub(crate) fn new(now: T::BlockNumber, relay_parent_number: T::BlockNumber) -> Self {
Self { config: <configuration::Pallet<T>>::config(), now, relay_parent_number }
Expand All @@ -967,10 +960,32 @@ impl<T: Config> CandidateCheckContext<T> {
pub(crate) fn verify_backed_candidate(
&self,
parent_hash: <T as frame_system::Config>::Hash,
parent_storage_root: T::Hash,
candidate_idx: usize,
backed_candidate: &BackedCandidate<<T as frame_system::Config>::Hash>,
) -> Result<(), Error<T>> {
) -> Result<Result<(), FailedToCreatePVD>, Error<T>> {
let para_id = backed_candidate.descriptor().para_id;
let now = <frame_system::Pallet<T>>::block_number();
let relay_parent_number = now - One::one();

{
// this should never fail because the para is registered
let persisted_validation_data = match crate::util::make_persisted_validation_data::<T>(
para_id,
relay_parent_number,
parent_storage_root,
) {
Some(l) => l,
None => return Ok(Err(FailedToCreatePVD)),
};

let expected = persisted_validation_data.hash();

ensure!(
expected == backed_candidate.descriptor().persisted_validation_data_hash,
Error::<T>::ValidationDataHashMismatch,
);
}

// we require that the candidate is in the context of the parent block.
ensure!(
Expand Down Expand Up @@ -1014,7 +1029,7 @@ impl<T: Config> CandidateCheckContext<T> {
);
Err(err.strip_into_dispatch_err::<T>())?;
};
Ok(())
Ok(Ok(()))
}

/// Check the given outputs after candidate validation on whether it passes the acceptance
Expand Down
23 changes: 16 additions & 7 deletions runtime/parachains/src/paras_inherent/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,7 @@ impl<T: Config> Pallet<T> {
let scheduled = <scheduler::Pallet<T>>::scheduled();

let relay_parent_number = now - One::one();
let parent_storage_root = parent_header.state_root().clone();

let check_ctx = CandidateCheckContext::<T>::new(now, relay_parent_number);
let backed_candidates = sanitize_backed_candidates::<T, _>(
Expand All @@ -720,13 +721,21 @@ impl<T: Config> Pallet<T> {
-> bool {
// never include a concluded-invalid candidate
concluded_invalid_disputes.contains(&backed_candidate.hash()) ||
// Instead of checking the candidates with code upgrades twice
// move the checking up here and skip it in the training wheels fallback.
// That way we avoid possible duplicate checks while assuring all
// backed candidates fine to pass on.
check_ctx
.verify_backed_candidate(parent_hash, candidate_idx, backed_candidate)
.is_err()
// Instead of checking the candidates with code upgrades twice
// move the checking up here and skip it in the training wheels fallback.
// That way we avoid possible duplicate checks while assuring all
// backed candidates fine to pass on.
{
match check_ctx.verify_backed_candidate(
parent_hash,
parent_storage_root,
candidate_idx,
backed_candidate,
) {
Err(_) | Ok(Err(_)) => true,
Ok(Ok(_)) => false,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused why this doesn't match #4727, but this is what @drahnr suggested here: https://github.com/paritytech/polkadot/pull/4727/files#r793944509?

}
}
},
&scheduled[..],
);
Expand Down