Skip to content

Commit 3540fc4

Browse files
alindimaMorganamilo
authored andcommitted
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 f690350 commit 3540fc4

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
@@ -639,6 +639,8 @@ impl<T: Config> Pallet<T> {
639639
for (candidate, core) in para_candidates.iter() {
640640
let candidate_hash = candidate.candidate().hash();
641641

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

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

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

803815
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)