mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 10:31:03 +00:00
Disputes runtime (#2947)
* disputes module skeleton and storage * implement dispute module initialization logic * implement disputes session change logic * provide dispute skeletons * deduplication & ancient check * fix a couple of warnings * begin provide_dispute_data impl * flesh out statement set import somewhat * move ApprovalVote to shared primitives * add a signing-payload API to explicit dispute statements * implement statement signature checking * some bitflags glue for observing changes in disputes * implement dispute vote import logic * flesh out everything except slashing * guide: tweaks * declare and use punishment trait * punish validators for inconclusive disputes * guide: tiny fix * guide: update docs * add disputes getter fn * guide: small change to spam slots handling * improve spam slots handling and fix some bugs * finish API of disputes runtime * define and deposit `RevertTo` log * begin integrating disputes into para_inherent * use precomputed slash_for/against * return candidate hash from process_bitfields * implement inclusion::collect_disputed * finish integration into rest of runtime * add Disputes to initializer * address suggestions * use pallet macro * fix typo * Update runtime/parachains/src/disputes.rs * add test: fix pruning * document specific behavior * deposit events on dispute changes * add an allow(unused) on fn disputes * add a dummy PunishValidators implementation * add disputes module to Rococo * add disputes module to westend runtime * add disputes module to test runtime * add disputes module to kusama runtime * guide: prepare for runtime API for checking frozenness * remove revert digests in favor of state variable * merge reversions * Update runtime/parachains/src/disputes.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * Update runtime/parachains/src/disputes.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * Update runtime/parachains/src/disputes.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * add byzantine_threshold and supermajority_threshold utilities to primitives * use primitive helpers * deposit revert event when freezing chain * deposit revert log when freezing chain * test revert event and log are generated when freezing * add trait to decouple disputes handling from paras inherent handling * runtime: fix compilation and setup dispute handler * disputes: add hook for filtering out dispute statements * disputes: add initializer hooks to DisputesHandler * runtime: remove disputes pallet from all runtimes * tag TODOs * don't import any dispute statements just yet... * address grumbles * fix spellcheck, hopefully * maybe now? * last spellcheck round * fix runtime tests * fix test-runtime Co-authored-by: thiolliere <gui.thiolliere@gmail.com> Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> Co-authored-by: André Silva <andrerfosilva@gmail.com>
This commit is contained in:
committed by
GitHub
parent
4636daa7ce
commit
ec98120f0e
@@ -35,8 +35,10 @@ use frame_support::{
|
||||
};
|
||||
use frame_system::ensure_none;
|
||||
use crate::{
|
||||
disputes::DisputesHandler,
|
||||
inclusion,
|
||||
scheduler::{self, FreedReason},
|
||||
shared,
|
||||
ump,
|
||||
};
|
||||
|
||||
@@ -68,6 +70,8 @@ decl_error! {
|
||||
/// The hash of the submitted parent header doesn't correspond to the saved block hash of
|
||||
/// the parent.
|
||||
InvalidParentHeader,
|
||||
/// Potentially invalid candidate.
|
||||
CandidateCouldBeInvalid,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +103,7 @@ decl_module! {
|
||||
bitfields: signed_bitfields,
|
||||
backed_candidates,
|
||||
parent_header,
|
||||
disputes: _,
|
||||
disputes,
|
||||
} = data;
|
||||
|
||||
ensure_none(origin)?;
|
||||
@@ -112,6 +116,36 @@ decl_module! {
|
||||
Error::<T>::InvalidParentHeader,
|
||||
);
|
||||
|
||||
// Handle disputes logic.
|
||||
let current_session = <shared::Module<T>>::session_index();
|
||||
let freed_disputed: Vec<(_, FreedReason)> = {
|
||||
let fresh_disputes = T::DisputesHandler::provide_multi_dispute_data(disputes)?;
|
||||
if T::DisputesHandler::is_frozen() {
|
||||
// The relay chain we are currently on is invalid. Proceed no further on parachains.
|
||||
Included::set(Some(()));
|
||||
return Ok(Some(
|
||||
MINIMAL_INCLUSION_INHERENT_WEIGHT
|
||||
).into());
|
||||
}
|
||||
|
||||
let any_current_session_disputes = fresh_disputes.iter()
|
||||
.any(|(s, _)| s == ¤t_session);
|
||||
|
||||
if any_current_session_disputes {
|
||||
let current_session_disputes: Vec<_> = fresh_disputes.iter()
|
||||
.filter(|(s, _)| s == ¤t_session)
|
||||
.map(|(_, c)| *c)
|
||||
.collect();
|
||||
|
||||
<inclusion::Module<T>>::collect_disputed(current_session_disputes)
|
||||
.into_iter()
|
||||
.map(|core| (core, FreedReason::Concluded))
|
||||
.collect()
|
||||
} else {
|
||||
Vec::new()
|
||||
}
|
||||
};
|
||||
|
||||
// Process new availability bitfields, yielding any availability cores whose
|
||||
// work has now concluded.
|
||||
let expected_bits = <scheduler::Module<T>>::availability_cores().len();
|
||||
@@ -121,6 +155,12 @@ decl_module! {
|
||||
<scheduler::Module<T>>::core_para,
|
||||
)?;
|
||||
|
||||
// Inform the disputes module of all included candidates.
|
||||
let now = <frame_system::Pallet<T>>::block_number();
|
||||
for (_, candidate_hash) in &freed_concluded {
|
||||
T::DisputesHandler::note_included(current_session, *candidate_hash, now);
|
||||
}
|
||||
|
||||
// Handle timeouts for any availability core work.
|
||||
let availability_pred = <scheduler::Module<T>>::availability_timeout_predicate();
|
||||
let freed_timeout = if let Some(pred) = availability_pred {
|
||||
@@ -130,8 +170,12 @@ decl_module! {
|
||||
};
|
||||
|
||||
// Schedule paras again, given freed cores, and reasons for freeing.
|
||||
let freed = freed_concluded.into_iter().map(|c| (c, FreedReason::Concluded))
|
||||
.chain(freed_timeout.into_iter().map(|c| (c, FreedReason::TimedOut)));
|
||||
let mut freed = freed_disputed.into_iter()
|
||||
.chain(freed_concluded.into_iter().map(|(c, _hash)| (c, FreedReason::Concluded)))
|
||||
.chain(freed_timeout.into_iter().map(|c| (c, FreedReason::TimedOut)))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
freed.sort_unstable_by_key(|pair| pair.0); // sort by core index
|
||||
|
||||
<scheduler::Module<T>>::clear();
|
||||
<scheduler::Module<T>>::schedule(
|
||||
@@ -142,6 +186,17 @@ decl_module! {
|
||||
let backed_candidates = limit_backed_candidates::<T>(backed_candidates);
|
||||
let backed_candidates_len = backed_candidates.len() as Weight;
|
||||
|
||||
// Refuse to back any candidates that are disputed or invalid.
|
||||
for candidate in &backed_candidates {
|
||||
ensure!(
|
||||
!T::DisputesHandler::could_be_invalid(
|
||||
current_session,
|
||||
candidate.candidate.hash(),
|
||||
),
|
||||
Error::<T>::CandidateCouldBeInvalid,
|
||||
);
|
||||
}
|
||||
|
||||
// Process backed candidates according to scheduled cores.
|
||||
let parent_storage_root = parent_header.state_root().clone();
|
||||
let occupied = <inclusion::Module<T>>::process_candidates(
|
||||
@@ -216,7 +271,7 @@ impl<T: Config> ProvideInherent for Module<T> {
|
||||
const INHERENT_IDENTIFIER: InherentIdentifier = PARACHAINS_INHERENT_IDENTIFIER;
|
||||
|
||||
fn create_inherent(data: &InherentData) -> Option<Self::Call> {
|
||||
let inherent_data: ParachainsInherentData<T::Header>
|
||||
let mut inherent_data: ParachainsInherentData<T::Header>
|
||||
= match data.get_data(&Self::INHERENT_IDENTIFIER)
|
||||
{
|
||||
Ok(Some(d)) => d,
|
||||
@@ -231,6 +286,9 @@ impl<T: Config> ProvideInherent for Module<T> {
|
||||
}
|
||||
};
|
||||
|
||||
// filter out any unneeded dispute statements
|
||||
T::DisputesHandler::filter_multi_dispute_data(&mut inherent_data.disputes);
|
||||
|
||||
// Sanity check: session changes can invalidate an inherent, and we _really_ don't want that to happen.
|
||||
// See github.com/paritytech/polkadot/issues/1327
|
||||
let inherent_data = match Self::enter(
|
||||
|
||||
Reference in New Issue
Block a user