diff --git a/runtime/parachains/src/inclusion/mod.rs b/runtime/parachains/src/inclusion/mod.rs index c2baa94b9335..41d06d2272be 100644 --- a/runtime/parachains/src/inclusion/mod.rs +++ b/runtime/parachains/src/inclusion/mod.rs @@ -524,11 +524,26 @@ impl Pallet { 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; @@ -545,32 +560,6 @@ impl Pallet { ); } - { - // this should never fail because the para is registered - let persisted_validation_data = - match crate::util::make_persisted_validation_data::( - 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::::ValidationDataHashMismatch, - ); - } - ensure!( >::get(¶_id).is_none() && >::get(¶_id).is_none(), @@ -952,6 +941,10 @@ pub(crate) struct CandidateCheckContext { 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 CandidateCheckContext { pub(crate) fn new(now: T::BlockNumber, relay_parent_number: T::BlockNumber) -> Self { Self { config: >::config(), now, relay_parent_number } @@ -967,10 +960,32 @@ impl CandidateCheckContext { pub(crate) fn verify_backed_candidate( &self, parent_hash: ::Hash, + parent_storage_root: T::Hash, candidate_idx: usize, backed_candidate: &BackedCandidate<::Hash>, - ) -> Result<(), Error> { + ) -> Result, Error> { let para_id = backed_candidate.descriptor().para_id; + let now = >::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::( + 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::::ValidationDataHashMismatch, + ); + } // we require that the candidate is in the context of the parent block. ensure!( @@ -1014,7 +1029,7 @@ impl CandidateCheckContext { ); Err(err.strip_into_dispatch_err::())?; }; - Ok(()) + Ok(Ok(())) } /// Check the given outputs after candidate validation on whether it passes the acceptance diff --git a/runtime/parachains/src/paras_inherent/mod.rs b/runtime/parachains/src/paras_inherent/mod.rs index 1645f74ee804..74d58fe0feea 100644 --- a/runtime/parachains/src/paras_inherent/mod.rs +++ b/runtime/parachains/src/paras_inherent/mod.rs @@ -710,6 +710,7 @@ impl Pallet { let scheduled = >::scheduled(); let relay_parent_number = now - One::one(); + let parent_storage_root = parent_header.state_root().clone(); let check_ctx = CandidateCheckContext::::new(now, relay_parent_number); let backed_candidates = sanitize_backed_candidates::( @@ -725,7 +726,7 @@ impl Pallet { // 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) + .verify_backed_candidate(parent_hash, parent_storage_root, candidate_idx, backed_candidate) .is_err() }, &scheduled[..],