Skip to content

Commit fc07bda

Browse files
authored
runtime: make the candidate relay parent progression check more strict (#5113)
Previously, we were checking if the relay parent of a new candidate does not move backwards from the latest included on-chain candidate. This was fine prior to elastic scaling. We now need to also check that the relay parent progresses from the latest pending availability candidate, as well as check the progression within the candidate chain in the inherent data. Prospective-parachains is already doing this check but we should also add it in the runtime
1 parent 7eb946c commit fc07bda

4 files changed

Lines changed: 664 additions & 52 deletions

File tree

polkadot/runtime/parachains/src/inclusion/mod.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,8 @@ impl<T: Config> Pallet<T> {
638638
for (candidate, core) in para_candidates.iter() {
639639
let candidate_hash = candidate.candidate().hash();
640640

641+
// The previous context is None, as it's already checked during candidate
642+
// sanitization.
641643
let check_ctx = CandidateCheckContext::<T>::new(None);
642644
let relay_parent_number = check_ctx.verify_backed_candidate(
643645
&allowed_relay_parents,
@@ -717,7 +719,7 @@ impl<T: Config> Pallet<T> {
717719
})
718720
}
719721

720-
// Get the latest backed output head data of this para.
722+
// Get the latest backed output head data of this para (including pending availability).
721723
pub(crate) fn para_latest_head_data(para_id: &ParaId) -> Option<HeadData> {
722724
match PendingAvailability::<T>::get(para_id).and_then(|pending_candidates| {
723725
pending_candidates.back().map(|x| x.commitments.head_data.clone())
@@ -727,6 +729,16 @@ impl<T: Config> Pallet<T> {
727729
}
728730
}
729731

732+
// Get the relay parent number of the most recent candidate (including pending availability).
733+
pub(crate) fn para_most_recent_context(para_id: &ParaId) -> Option<BlockNumberFor<T>> {
734+
match PendingAvailability::<T>::get(para_id)
735+
.and_then(|pending_candidates| pending_candidates.back().map(|x| x.relay_parent_number))
736+
{
737+
Some(relay_parent_number) => Some(relay_parent_number),
738+
None => paras::MostRecentContext::<T>::get(para_id),
739+
}
740+
}
741+
730742
fn check_backing_votes(
731743
backed_candidate: &BackedCandidate<T::Hash>,
732744
validators: &[ValidatorId],
@@ -796,7 +808,7 @@ impl<T: Config> Pallet<T> {
796808
relay_parent_number: BlockNumberFor<T>,
797809
validation_outputs: polkadot_primitives::CandidateCommitments,
798810
) -> bool {
799-
let prev_context = paras::MostRecentContext::<T>::get(para_id);
811+
let prev_context = Self::para_most_recent_context(&para_id);
800812
let check_ctx = CandidateCheckContext::<T>::new(prev_context);
801813

802814
if check_ctx

polkadot/runtime/parachains/src/paras_inherent/mod.rs

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1243,22 +1243,27 @@ fn filter_unchained_candidates<T: inclusion::Config + paras::Config + inclusion:
12431243
candidates: &mut BTreeMap<ParaId, Vec<BackedCandidate<T::Hash>>>,
12441244
allowed_relay_parents: &AllowedRelayParentsTracker<T::Hash, BlockNumberFor<T>>,
12451245
) {
1246-
let mut para_latest_head_data: BTreeMap<ParaId, HeadData> = BTreeMap::new();
1246+
let mut para_latest_context: BTreeMap<ParaId, (HeadData, BlockNumberFor<T>)> = BTreeMap::new();
12471247
for para_id in candidates.keys() {
1248-
let latest_head_data = match inclusion::Pallet::<T>::para_latest_head_data(&para_id) {
1249-
None => {
1250-
defensive!("Latest included head data for paraid {:?} is None", para_id);
1251-
continue
1252-
},
1253-
Some(latest_head_data) => latest_head_data,
1248+
let Some(latest_head_data) = inclusion::Pallet::<T>::para_latest_head_data(&para_id) else {
1249+
defensive!("Latest included head data for paraid {:?} is None", para_id);
1250+
continue
12541251
};
1255-
para_latest_head_data.insert(*para_id, latest_head_data);
1252+
let Some(latest_relay_parent) = inclusion::Pallet::<T>::para_most_recent_context(&para_id)
1253+
else {
1254+
defensive!("Latest relay parent for paraid {:?} is None", para_id);
1255+
continue
1256+
};
1257+
para_latest_context.insert(*para_id, (latest_head_data, latest_relay_parent));
12561258
}
12571259

12581260
let mut para_visited_candidates: BTreeMap<ParaId, BTreeSet<CandidateHash>> = BTreeMap::new();
12591261

12601262
retain_candidates::<T, _, _>(candidates, |para_id, candidate| {
1261-
let Some(latest_head_data) = para_latest_head_data.get(&para_id) else { return false };
1263+
let Some((latest_head_data, latest_relay_parent)) = para_latest_context.get(&para_id)
1264+
else {
1265+
return false
1266+
};
12621267
let candidate_hash = candidate.candidate().hash();
12631268

12641269
let visited_candidates =
@@ -1277,15 +1282,23 @@ fn filter_unchained_candidates<T: inclusion::Config + paras::Config + inclusion:
12771282
visited_candidates.insert(candidate_hash);
12781283
}
12791284

1280-
let prev_context = paras::MostRecentContext::<T>::get(para_id);
1281-
let check_ctx = CandidateCheckContext::<T>::new(prev_context);
1285+
let check_ctx = CandidateCheckContext::<T>::new(Some(*latest_relay_parent));
12821286

1283-
let res = match check_ctx.verify_backed_candidate(
1287+
match check_ctx.verify_backed_candidate(
12841288
&allowed_relay_parents,
12851289
candidate.candidate(),
12861290
latest_head_data.clone(),
12871291
) {
1288-
Ok(_) => true,
1292+
Ok(relay_parent_block_number) => {
1293+
para_latest_context.insert(
1294+
para_id,
1295+
(
1296+
candidate.candidate().commitments.head_data.clone(),
1297+
relay_parent_block_number,
1298+
),
1299+
);
1300+
true
1301+
},
12891302
Err(err) => {
12901303
log::debug!(
12911304
target: LOG_TARGET,
@@ -1296,14 +1309,7 @@ fn filter_unchained_candidates<T: inclusion::Config + paras::Config + inclusion:
12961309
);
12971310
false
12981311
},
1299-
};
1300-
1301-
if res {
1302-
para_latest_head_data
1303-
.insert(para_id, candidate.candidate().commitments.head_data.clone());
13041312
}
1305-
1306-
res
13071313
});
13081314
}
13091315

0 commit comments

Comments
 (0)