polkadot_node_subsystem_types/
messages.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// This file is part of Polkadot.
3
4// Polkadot is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Polkadot is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
16
17//! Message types for the overseer and subsystems.
18//!
19//! These messages are intended to define the protocol by which different subsystems communicate
20//! with each other and signals that they receive from an overseer to coordinate their work.
21//! This is intended for use with the `polkadot-overseer` crate.
22//!
23//! Subsystems' APIs are defined separately from their implementation, leading to easier mocking.
24
25use futures::channel::oneshot;
26use sc_network::{Multiaddr, ReputationChange};
27use thiserror::Error;
28
29pub use sc_network::IfDisconnected;
30
31use polkadot_node_network_protocol::{
32	self as net_protocol, peer_set::PeerSet, request_response::Requests, PeerId,
33};
34use polkadot_node_primitives::{
35	approval::{
36		v1::{BlockApprovalMeta, DelayTranche},
37		v2::{CandidateBitfield, IndirectAssignmentCertV2, IndirectSignedApprovalVoteV2},
38	},
39	AvailableData, BabeEpoch, BlockWeight, CandidateVotes, CollationGenerationConfig,
40	CollationSecondedSignal, DisputeMessage, DisputeStatus, ErasureChunk, PoV,
41	SignedDisputeStatement, SignedFullStatement, SignedFullStatementWithPVD, SubmitCollationParams,
42	ValidationResult,
43};
44use polkadot_primitives::{
45	async_backing, slashing, ApprovalVotingParams, AuthorityDiscoveryId, BackedCandidate,
46	BlockNumber, CandidateCommitments, CandidateEvent, CandidateHash, CandidateIndex,
47	CandidateReceipt, CollatorId, CommittedCandidateReceipt, CoreIndex, CoreState, DisputeState,
48	ExecutorParams, GroupIndex, GroupRotationInfo, Hash, HeadData, Header as BlockHeader,
49	Id as ParaId, InboundDownwardMessage, InboundHrmpMessage, MultiDisputeStatementSet,
50	NodeFeatures, OccupiedCoreAssumption, PersistedValidationData, PvfCheckStatement, PvfExecKind,
51	SessionIndex, SessionInfo, SignedAvailabilityBitfield, SignedAvailabilityBitfields,
52	ValidationCode, ValidationCodeHash, ValidatorId, ValidatorIndex, ValidatorSignature,
53};
54use polkadot_statement_table::v2::Misbehavior;
55use std::{
56	collections::{BTreeMap, HashMap, HashSet, VecDeque},
57	sync::Arc,
58};
59
60/// Network events as transmitted to other subsystems, wrapped in their message types.
61pub mod network_bridge_event;
62pub use network_bridge_event::NetworkBridgeEvent;
63
64/// A request to the candidate backing subsystem to check whether
65/// we can second this candidate.
66#[derive(Debug, Copy, Clone)]
67pub struct CanSecondRequest {
68	/// Para id of the candidate.
69	pub candidate_para_id: ParaId,
70	/// The relay-parent of the candidate.
71	pub candidate_relay_parent: Hash,
72	/// Hash of the candidate.
73	pub candidate_hash: CandidateHash,
74	/// Parent head data hash.
75	pub parent_head_data_hash: Hash,
76}
77
78/// Messages received by the Candidate Backing subsystem.
79#[derive(Debug)]
80pub enum CandidateBackingMessage {
81	/// Requests a set of backable candidates attested by the subsystem.
82	///
83	/// The order of candidates of the same para must be preserved in the response.
84	/// If a backed candidate of a para cannot be retrieved, the response should not contain any
85	/// candidates of the same para that follow it in the input vector. In other words, assuming
86	/// candidates are supplied in dependency order, we must ensure that this dependency order is
87	/// preserved.
88	GetBackableCandidates(
89		HashMap<ParaId, Vec<(CandidateHash, Hash)>>,
90		oneshot::Sender<HashMap<ParaId, Vec<BackedCandidate>>>,
91	),
92	/// Request the subsystem to check whether it's allowed to second given candidate.
93	/// The rule is to only fetch collations that can either be directly chained to any
94	/// FragmentChain in the view or there is at least one FragmentChain where this candidate is a
95	/// potentially unconnected candidate (we predict that it may become connected to a
96	/// FragmentChain in the future).
97	///
98	/// Always responds with `false` if async backing is disabled for candidate's relay
99	/// parent.
100	CanSecond(CanSecondRequest, oneshot::Sender<bool>),
101	/// Note that the Candidate Backing subsystem should second the given candidate in the context
102	/// of the given relay-parent (ref. by hash). This candidate must be validated.
103	Second(Hash, CandidateReceipt, PersistedValidationData, PoV),
104	/// Note a validator's statement about a particular candidate in the context of the given
105	/// relay-parent. Disagreements about validity must be escalated to a broader check by the
106	/// Disputes Subsystem, though that escalation is deferred until the approval voting stage to
107	/// guarantee availability. Agreements are simply tallied until a quorum is reached.
108	Statement(Hash, SignedFullStatementWithPVD),
109}
110
111/// Blanket error for validation failing for internal reasons.
112#[derive(Debug, Error)]
113#[error("Validation failed with {0:?}")]
114pub struct ValidationFailed(pub String);
115
116/// The outcome of the candidate-validation's PVF pre-check request.
117#[derive(Debug, PartialEq)]
118pub enum PreCheckOutcome {
119	/// The PVF has been compiled successfully within the given constraints.
120	Valid,
121	/// The PVF could not be compiled. This variant is used when the candidate-validation subsystem
122	/// can be sure that the PVF is invalid. To give a couple of examples: a PVF that cannot be
123	/// decompressed or that does not represent a structurally valid WebAssembly file.
124	Invalid,
125	/// This variant is used when the PVF cannot be compiled but for other reasons that are not
126	/// included into [`PreCheckOutcome::Invalid`]. This variant can indicate that the PVF in
127	/// question is invalid, however it is not necessary that PVF that received this judgement
128	/// is invalid.
129	///
130	/// For example, if during compilation the preparation worker was killed we cannot be sure why
131	/// it happened: because the PVF was malicious made the worker to use too much memory or its
132	/// because the host machine is under severe memory pressure and it decided to kill the worker.
133	Failed,
134}
135
136/// Messages received by the Validation subsystem.
137///
138/// ## Validation Requests
139///
140/// Validation requests made to the subsystem should return an error only on internal error.
141/// Otherwise, they should return either `Ok(ValidationResult::Valid(_))`
142/// or `Ok(ValidationResult::Invalid)`.
143#[derive(Debug)]
144pub enum CandidateValidationMessage {
145	/// Validate a candidate with provided parameters using relay-chain state.
146	///
147	/// This will implicitly attempt to gather the `PersistedValidationData` and `ValidationCode`
148	/// from the runtime API of the chain, based on the `relay_parent`
149	/// of the `CandidateReceipt`.
150	///
151	/// This will also perform checking of validation outputs against the acceptance criteria.
152	///
153	/// If there is no state available which can provide this data or the core for
154	/// the para is not free at the relay-parent, an error is returned.
155	ValidateFromChainState {
156		/// The candidate receipt
157		candidate_receipt: CandidateReceipt,
158		/// The proof-of-validity
159		pov: Arc<PoV>,
160		/// Session's executor parameters
161		executor_params: ExecutorParams,
162		/// Execution kind, used for timeouts and retries (backing/approvals)
163		exec_kind: PvfExecKind,
164		/// The sending side of the response channel
165		response_sender: oneshot::Sender<Result<ValidationResult, ValidationFailed>>,
166	},
167	/// Validate a candidate with provided, exhaustive parameters for validation.
168	///
169	/// Explicitly provide the `PersistedValidationData` and `ValidationCode` so this can do full
170	/// validation without needing to access the state of the relay-chain.
171	///
172	/// This request doesn't involve acceptance criteria checking, therefore only useful for the
173	/// cases where the validity of the candidate is established. This is the case for the typical
174	/// use-case: secondary checkers would use this request relying on the full prior checks
175	/// performed by the relay-chain.
176	ValidateFromExhaustive {
177		/// Persisted validation data
178		validation_data: PersistedValidationData,
179		/// Validation code
180		validation_code: ValidationCode,
181		/// The candidate receipt
182		candidate_receipt: CandidateReceipt,
183		/// The proof-of-validity
184		pov: Arc<PoV>,
185		/// Session's executor parameters
186		executor_params: ExecutorParams,
187		/// Execution kind, used for timeouts and retries (backing/approvals)
188		exec_kind: PvfExecKind,
189		/// The sending side of the response channel
190		response_sender: oneshot::Sender<Result<ValidationResult, ValidationFailed>>,
191	},
192	/// Try to compile the given validation code and send back
193	/// the outcome.
194	///
195	/// The validation code is specified by the hash and will be queried from the runtime API at
196	/// the given relay-parent.
197	PreCheck {
198		/// Relay-parent
199		relay_parent: Hash,
200		/// Validation code hash
201		validation_code_hash: ValidationCodeHash,
202		/// The sending side of the response channel
203		response_sender: oneshot::Sender<PreCheckOutcome>,
204	},
205}
206
207/// Messages received by the Collator Protocol subsystem.
208#[derive(Debug, derive_more::From)]
209pub enum CollatorProtocolMessage {
210	/// Signal to the collator protocol that it should connect to validators with the expectation
211	/// of collating on the given para. This is only expected to be called once, early on, if at
212	/// all, and only by the Collation Generation subsystem. As such, it will overwrite the value
213	/// of the previous signal.
214	///
215	/// This should be sent before any `DistributeCollation` message.
216	CollateOn(ParaId),
217	/// Provide a collation to distribute to validators with an optional result sender.
218	DistributeCollation {
219		/// The receipt of the candidate.
220		candidate_receipt: CandidateReceipt,
221		/// The hash of the parent head-data.
222		/// Here to avoid computing the hash of the parent head data twice.
223		parent_head_data_hash: Hash,
224		/// Proof of validity.
225		pov: PoV,
226		/// This parent head-data is needed for elastic scaling.
227		parent_head_data: HeadData,
228		/// The result sender should be informed when at least one parachain validator seconded the
229		/// collation. It is also completely okay to just drop the sender.
230		result_sender: Option<oneshot::Sender<CollationSecondedSignal>>,
231		/// The core index where the candidate should be backed.
232		core_index: CoreIndex,
233	},
234	/// Report a collator as having provided an invalid collation. This should lead to disconnect
235	/// and blacklist of the collator.
236	ReportCollator(CollatorId),
237	/// Get a network bridge update.
238	#[from]
239	NetworkBridgeUpdate(NetworkBridgeEvent<net_protocol::CollatorProtocolMessage>),
240	/// We recommended a particular candidate to be seconded, but it was invalid; penalize the
241	/// collator.
242	///
243	/// The hash is the relay parent.
244	Invalid(Hash, CandidateReceipt),
245	/// The candidate we recommended to be seconded was validated successfully.
246	///
247	/// The hash is the relay parent.
248	Seconded(Hash, SignedFullStatement),
249}
250
251impl Default for CollatorProtocolMessage {
252	fn default() -> Self {
253		Self::CollateOn(Default::default())
254	}
255}
256
257/// Messages received by the dispute coordinator subsystem.
258///
259/// NOTE: Any response oneshots might get cancelled if the `DisputeCoordinator` was not yet
260/// properly initialized for some reason.
261#[derive(Debug)]
262pub enum DisputeCoordinatorMessage {
263	/// Import statements by validators about a candidate.
264	///
265	/// The subsystem will silently discard ancient statements or sets of only dispute-specific
266	/// statements for candidates that are previously unknown to the subsystem. The former is
267	/// simply because ancient data is not relevant and the latter is as a DoS prevention
268	/// mechanism. Both backing and approval statements already undergo anti-DoS procedures in
269	/// their respective subsystems, but statements cast specifically for disputes are not
270	/// necessarily relevant to any candidate the system is already aware of and thus present a DoS
271	/// vector. Our expectation is that nodes will notify each other of disputes over the network
272	/// by providing (at least) 2 conflicting statements, of which one is either a backing or
273	/// validation statement.
274	///
275	/// This does not do any checking of the message signature.
276	ImportStatements {
277		/// The candidate receipt itself.
278		candidate_receipt: CandidateReceipt,
279		/// The session the candidate appears in.
280		session: SessionIndex,
281		/// Statements, with signatures checked, by validators participating in disputes.
282		///
283		/// The validator index passed alongside each statement should correspond to the index
284		/// of the validator in the set.
285		statements: Vec<(SignedDisputeStatement, ValidatorIndex)>,
286		/// Inform the requester once we finished importing (if a sender was provided).
287		///
288		/// This is:
289		/// - we discarded the votes because
290		/// 		- they were ancient or otherwise invalid (result: `InvalidImport`)
291		/// 		- or we were not able to recover availability for an unknown candidate (result:
292		///		`InvalidImport`)
293		/// 		- or were known already (in that case the result will still be `ValidImport`)
294		/// - or we recorded them because (`ValidImport`)
295		/// 		- we cast our own vote already on that dispute
296		/// 		- or we have approval votes on that candidate
297		/// 		- or other explicit votes on that candidate already recorded
298		/// 		- or recovered availability for the candidate
299		/// 		- or the imported statements are backing/approval votes, which are always accepted.
300		pending_confirmation: Option<oneshot::Sender<ImportStatementsResult>>,
301	},
302	/// Fetch a list of all recent disputes the coordinator is aware of.
303	/// These are disputes which have occurred any time in recent sessions,
304	/// and which may have already concluded.
305	RecentDisputes(oneshot::Sender<Vec<(SessionIndex, CandidateHash, DisputeStatus)>>),
306	/// Fetch a list of all active disputes that the coordinator is aware of.
307	/// These disputes are either not yet concluded or recently concluded.
308	ActiveDisputes(oneshot::Sender<Vec<(SessionIndex, CandidateHash, DisputeStatus)>>),
309	/// Get candidate votes for a candidate.
310	QueryCandidateVotes(
311		Vec<(SessionIndex, CandidateHash)>,
312		oneshot::Sender<Vec<(SessionIndex, CandidateHash, CandidateVotes)>>,
313	),
314	/// Sign and issue local dispute votes. A value of `true` indicates validity, and `false`
315	/// invalidity.
316	IssueLocalStatement(SessionIndex, CandidateHash, CandidateReceipt, bool),
317	/// Determine the highest undisputed block within the given chain, based on where candidates
318	/// were included. If even the base block should not be finalized due to a dispute,
319	/// then `None` should be returned on the channel.
320	///
321	/// The block descriptions begin counting upwards from the block after the given `base_number`.
322	/// The `base_number` is typically the number of the last finalized block but may be slightly
323	/// higher. This block is inevitably going to be finalized so it is not accounted for by this
324	/// function.
325	DetermineUndisputedChain {
326		/// The lowest possible block to vote on.
327		base: (BlockNumber, Hash),
328		/// Descriptions of all the blocks counting upwards from the block after the base number
329		block_descriptions: Vec<BlockDescription>,
330		/// The block to vote on, might be base in case there is no better.
331		tx: oneshot::Sender<(BlockNumber, Hash)>,
332	},
333}
334
335/// The result of `DisputeCoordinatorMessage::ImportStatements`.
336#[derive(Copy, Clone, Debug, PartialEq, Eq)]
337pub enum ImportStatementsResult {
338	/// Import was invalid (candidate was not available)  and the sending peer should get banned.
339	InvalidImport,
340	/// Import was valid and can be confirmed to peer.
341	ValidImport,
342}
343
344/// Messages going to the dispute distribution subsystem.
345#[derive(Debug)]
346pub enum DisputeDistributionMessage {
347	/// Tell dispute distribution to distribute an explicit dispute statement to
348	/// validators.
349	SendDispute(DisputeMessage),
350}
351
352/// Messages received from other subsystems.
353#[derive(Debug)]
354pub enum NetworkBridgeRxMessage {
355	/// Inform the distribution subsystems about the new
356	/// gossip network topology formed.
357	///
358	/// The only reason to have this here, is the availability of the
359	/// authority discovery service, otherwise, the `GossipSupport`
360	/// subsystem would make more sense.
361	NewGossipTopology {
362		/// The session info this gossip topology is concerned with.
363		session: SessionIndex,
364		/// Our validator index in the session, if any.
365		local_index: Option<ValidatorIndex>,
366		/// The canonical shuffling of validators for the session.
367		canonical_shuffling: Vec<(AuthorityDiscoveryId, ValidatorIndex)>,
368		/// The reverse mapping of `canonical_shuffling`: from validator index
369		/// to the index in `canonical_shuffling`
370		shuffled_indices: Vec<usize>,
371	},
372	/// Inform the distribution subsystems about `AuthorityDiscoveryId` key rotations.
373	UpdatedAuthorityIds {
374		/// The `PeerId` of the peer that updated its `AuthorityDiscoveryId`s.
375		peer_id: PeerId,
376		/// The updated authority discovery keys of the peer.
377		authority_ids: HashSet<AuthorityDiscoveryId>,
378	},
379}
380
381/// Type of peer reporting
382#[derive(Debug)]
383pub enum ReportPeerMessage {
384	/// Single peer report about malicious actions which should be sent right away
385	Single(PeerId, ReputationChange),
386	/// Delayed report for other actions.
387	Batch(HashMap<PeerId, i32>),
388}
389
390/// Messages received from other subsystems by the network bridge subsystem.
391#[derive(Debug)]
392pub enum NetworkBridgeTxMessage {
393	/// Report a peer for their actions.
394	ReportPeer(ReportPeerMessage),
395
396	/// Disconnect a peer from the given peer-set without affecting their reputation.
397	DisconnectPeer(PeerId, PeerSet),
398
399	/// Send a message to one or more peers on the validation peer-set.
400	SendValidationMessage(Vec<PeerId>, net_protocol::VersionedValidationProtocol),
401
402	/// Send a message to one or more peers on the collation peer-set.
403	SendCollationMessage(Vec<PeerId>, net_protocol::VersionedCollationProtocol),
404
405	/// Send a batch of validation messages.
406	///
407	/// NOTE: Messages will be processed in order (at least statement distribution relies on this).
408	SendValidationMessages(Vec<(Vec<PeerId>, net_protocol::VersionedValidationProtocol)>),
409
410	/// Send a batch of collation messages.
411	///
412	/// NOTE: Messages will be processed in order.
413	SendCollationMessages(Vec<(Vec<PeerId>, net_protocol::VersionedCollationProtocol)>),
414
415	/// Send requests via substrate request/response.
416	/// Second parameter, tells what to do if we are not yet connected to the peer.
417	SendRequests(Vec<Requests>, IfDisconnected),
418
419	/// Connect to peers who represent the given `validator_ids`.
420	///
421	/// Also ask the network to stay connected to these peers at least
422	/// until a new request is issued.
423	///
424	/// Because it overrides the previous request, it must be ensured
425	/// that `validator_ids` include all peers the subsystems
426	/// are interested in (per `PeerSet`).
427	///
428	/// A caller can learn about validator connections by listening to the
429	/// `PeerConnected` events from the network bridge.
430	ConnectToValidators {
431		/// Ids of the validators to connect to.
432		validator_ids: Vec<AuthorityDiscoveryId>,
433		/// The underlying protocol to use for this request.
434		peer_set: PeerSet,
435		/// Sends back the number of `AuthorityDiscoveryId`s which
436		/// authority discovery has failed to resolve.
437		failed: oneshot::Sender<usize>,
438	},
439	/// Alternative to `ConnectToValidators` in case you already know the `Multiaddrs` you want to
440	/// be connected to.
441	ConnectToResolvedValidators {
442		/// Each entry corresponds to the addresses of an already resolved validator.
443		validator_addrs: Vec<HashSet<Multiaddr>>,
444		/// The peer set we want the connection on.
445		peer_set: PeerSet,
446	},
447
448	/// Extends the known validators set with new peers we already know the `Multiaddrs`, this is
449	/// usually needed for validators that change their address mid-session. It is usually called
450	/// after a ConnectToResolvedValidators at the beginning of the session.
451	AddToResolvedValidators {
452		/// Each entry corresponds to the addresses of an already resolved validator.
453		validator_addrs: Vec<HashSet<Multiaddr>>,
454		/// The peer set we want the connection on.
455		peer_set: PeerSet,
456	},
457}
458
459/// Availability Distribution Message.
460#[derive(Debug)]
461pub enum AvailabilityDistributionMessage {
462	/// Instruct availability distribution to fetch a remote PoV.
463	///
464	/// NOTE: The result of this fetch is not yet locally validated and could be bogus.
465	FetchPoV {
466		/// The relay parent giving the necessary context.
467		relay_parent: Hash,
468		/// Validator to fetch the PoV from.
469		from_validator: ValidatorIndex,
470		/// The id of the parachain that produced this PoV.
471		/// This field is only used to provide more context when logging errors
472		/// from the `AvailabilityDistribution` subsystem.
473		para_id: ParaId,
474		/// Candidate hash to fetch the PoV for.
475		candidate_hash: CandidateHash,
476		/// Expected hash of the PoV, a PoV not matching this hash will be rejected.
477		pov_hash: Hash,
478		/// Sender for getting back the result of this fetch.
479		///
480		/// The sender will be canceled if the fetching failed for some reason.
481		tx: oneshot::Sender<PoV>,
482	},
483}
484
485/// Availability Recovery Message.
486#[derive(Debug, derive_more::From)]
487pub enum AvailabilityRecoveryMessage {
488	/// Recover available data from validators on the network.
489	RecoverAvailableData(
490		CandidateReceipt,
491		SessionIndex,
492		Option<GroupIndex>, // Optional backing group to request from first.
493		Option<CoreIndex>,  /* A `CoreIndex` needs to be specified for the recovery process to
494		                     * prefer systematic chunk recovery. */
495		oneshot::Sender<Result<AvailableData, crate::errors::RecoveryError>>,
496	),
497}
498
499/// Bitfield distribution message.
500#[derive(Debug, derive_more::From)]
501pub enum BitfieldDistributionMessage {
502	/// Distribute a bitfield via gossip to other validators.
503	DistributeBitfield(Hash, SignedAvailabilityBitfield),
504
505	/// Event from the network bridge.
506	#[from]
507	NetworkBridgeUpdate(NetworkBridgeEvent<net_protocol::BitfieldDistributionMessage>),
508}
509
510/// Availability store subsystem message.
511#[derive(Debug)]
512pub enum AvailabilityStoreMessage {
513	/// Query a `AvailableData` from the AV store.
514	QueryAvailableData(CandidateHash, oneshot::Sender<Option<AvailableData>>),
515
516	/// Query whether a `AvailableData` exists within the AV Store.
517	///
518	/// This is useful in cases when existence
519	/// matters, but we don't want to necessarily pass around multiple
520	/// megabytes of data to get a single bit of information.
521	QueryDataAvailability(CandidateHash, oneshot::Sender<bool>),
522
523	/// Query an `ErasureChunk` from the AV store by the candidate hash and validator index.
524	QueryChunk(CandidateHash, ValidatorIndex, oneshot::Sender<Option<ErasureChunk>>),
525
526	/// Get the size of an `ErasureChunk` from the AV store by the candidate hash.
527	QueryChunkSize(CandidateHash, oneshot::Sender<Option<usize>>),
528
529	/// Query all chunks that we have for the given candidate hash.
530	QueryAllChunks(CandidateHash, oneshot::Sender<Vec<(ValidatorIndex, ErasureChunk)>>),
531
532	/// Query whether an `ErasureChunk` exists within the AV Store.
533	///
534	/// This is useful in cases like bitfield signing, when existence
535	/// matters, but we don't want to necessarily pass around large
536	/// quantities of data to get a single bit of information.
537	QueryChunkAvailability(CandidateHash, ValidatorIndex, oneshot::Sender<bool>),
538
539	/// Store an `ErasureChunk` in the AV store.
540	///
541	/// Return `Ok(())` if the store operation succeeded, `Err(())` if it failed.
542	StoreChunk {
543		/// A hash of the candidate this chunk belongs to.
544		candidate_hash: CandidateHash,
545		/// Validator index. May not be equal to the chunk index.
546		validator_index: ValidatorIndex,
547		/// The chunk itself.
548		chunk: ErasureChunk,
549		/// Sending side of the channel to send result to.
550		tx: oneshot::Sender<Result<(), ()>>,
551	},
552
553	/// Computes and checks the erasure root of `AvailableData` before storing all of its chunks in
554	/// the AV store.
555	///
556	/// Return `Ok(())` if the store operation succeeded, `Err(StoreAvailableData)` if it failed.
557	StoreAvailableData {
558		/// A hash of the candidate this `available_data` belongs to.
559		candidate_hash: CandidateHash,
560		/// The number of validators in the session.
561		n_validators: u32,
562		/// The `AvailableData` itself.
563		available_data: AvailableData,
564		/// Erasure root we expect to get after chunking.
565		expected_erasure_root: Hash,
566		/// Core index where the candidate was backed.
567		core_index: CoreIndex,
568		/// Node features at the candidate relay parent. Used for computing the validator->chunk
569		/// mapping.
570		node_features: NodeFeatures,
571		/// Sending side of the channel to send result to.
572		tx: oneshot::Sender<Result<(), StoreAvailableDataError>>,
573	},
574}
575
576/// The error result type of a [`AvailabilityStoreMessage::StoreAvailableData`] request.
577#[derive(Error, Debug, Clone, PartialEq, Eq)]
578#[allow(missing_docs)]
579pub enum StoreAvailableDataError {
580	#[error("The computed erasure root did not match expected one")]
581	InvalidErasureRoot,
582}
583
584/// A response channel for the result of a chain API request.
585pub type ChainApiResponseChannel<T> = oneshot::Sender<Result<T, crate::errors::ChainApiError>>;
586
587/// Chain API request subsystem message.
588#[derive(Debug)]
589pub enum ChainApiMessage {
590	/// Request the block number by hash.
591	/// Returns `None` if a block with the given hash is not present in the db.
592	BlockNumber(Hash, ChainApiResponseChannel<Option<BlockNumber>>),
593	/// Request the block header by hash.
594	/// Returns `None` if a block with the given hash is not present in the db.
595	BlockHeader(Hash, ChainApiResponseChannel<Option<BlockHeader>>),
596	/// Get the cumulative weight of the given block, by hash.
597	/// If the block or weight is unknown, this returns `None`.
598	///
599	/// Note: this is the weight within the low-level fork-choice rule,
600	/// not the high-level one implemented in the chain-selection subsystem.
601	///
602	/// Weight is used for comparing blocks in a fork-choice rule.
603	BlockWeight(Hash, ChainApiResponseChannel<Option<BlockWeight>>),
604	/// Request the finalized block hash by number.
605	/// Returns `None` if a block with the given number is not present in the db.
606	/// Note: the caller must ensure the block is finalized.
607	FinalizedBlockHash(BlockNumber, ChainApiResponseChannel<Option<Hash>>),
608	/// Request the last finalized block number.
609	/// This request always succeeds.
610	FinalizedBlockNumber(ChainApiResponseChannel<BlockNumber>),
611	/// Request the `k` ancestor block hashes of a block with the given hash.
612	/// The response channel may return a `Vec` of size up to `k`
613	/// filled with ancestors hashes with the following order:
614	/// `parent`, `grandparent`, ... up to the hash of genesis block
615	/// with number 0, including it.
616	Ancestors {
617		/// The hash of the block in question.
618		hash: Hash,
619		/// The number of ancestors to request.
620		k: usize,
621		/// The response channel.
622		response_channel: ChainApiResponseChannel<Vec<Hash>>,
623	},
624}
625
626/// Chain selection subsystem messages
627#[derive(Debug)]
628pub enum ChainSelectionMessage {
629	/// Signal to the chain selection subsystem that a specific block has been approved.
630	Approved(Hash),
631	/// Request the leaves in descending order by score.
632	Leaves(oneshot::Sender<Vec<Hash>>),
633	/// Request the best leaf containing the given block in its ancestry. Return `None` if
634	/// there is no such leaf.
635	BestLeafContaining(Hash, oneshot::Sender<Option<Hash>>),
636	/// The passed blocks must be marked as reverted, and their children must be marked
637	/// as non-viable.
638	RevertBlocks(Vec<(BlockNumber, Hash)>),
639}
640
641/// A sender for the result of a runtime API request.
642pub type RuntimeApiSender<T> = oneshot::Sender<Result<T, crate::errors::RuntimeApiError>>;
643
644/// A request to the Runtime API subsystem.
645#[derive(Debug)]
646pub enum RuntimeApiRequest {
647	/// Get the version of the runtime API, if any.
648	Version(RuntimeApiSender<u32>),
649	/// Get the next, current and some previous authority discovery set deduplicated.
650	Authorities(RuntimeApiSender<Vec<AuthorityDiscoveryId>>),
651	/// Get the current validator set.
652	Validators(RuntimeApiSender<Vec<ValidatorId>>),
653	/// Get the validator groups and group rotation info.
654	ValidatorGroups(RuntimeApiSender<(Vec<Vec<ValidatorIndex>>, GroupRotationInfo)>),
655	/// Get information on all availability cores.
656	AvailabilityCores(RuntimeApiSender<Vec<CoreState>>),
657	/// Get the persisted validation data for a particular para, taking the given
658	/// `OccupiedCoreAssumption`, which will inform on how the validation data should be computed
659	/// if the para currently occupies a core.
660	PersistedValidationData(
661		ParaId,
662		OccupiedCoreAssumption,
663		RuntimeApiSender<Option<PersistedValidationData>>,
664	),
665	/// Get the persisted validation data for a particular para along with the current validation
666	/// code hash, matching the data hash against an expected one.
667	AssumedValidationData(
668		ParaId,
669		Hash,
670		RuntimeApiSender<Option<(PersistedValidationData, ValidationCodeHash)>>,
671	),
672	/// Sends back `true` if the validation outputs pass all acceptance criteria checks.
673	CheckValidationOutputs(
674		ParaId,
675		polkadot_primitives::CandidateCommitments,
676		RuntimeApiSender<bool>,
677	),
678	/// Get the session index that a child of the block will have.
679	SessionIndexForChild(RuntimeApiSender<SessionIndex>),
680	/// Get the validation code for a para, taking the given `OccupiedCoreAssumption`, which
681	/// will inform on how the validation data should be computed if the para currently
682	/// occupies a core.
683	ValidationCode(ParaId, OccupiedCoreAssumption, RuntimeApiSender<Option<ValidationCode>>),
684	/// Get validation code by its hash, either past, current or future code can be returned, as
685	/// long as state is still available.
686	ValidationCodeByHash(ValidationCodeHash, RuntimeApiSender<Option<ValidationCode>>),
687	/// Get the candidate pending availability for a particular parachain by parachain / core
688	/// index
689	CandidatePendingAvailability(ParaId, RuntimeApiSender<Option<CommittedCandidateReceipt>>),
690	/// Get all events concerning candidates (backing, inclusion, time-out) in the parent of
691	/// the block in whose state this request is executed.
692	CandidateEvents(RuntimeApiSender<Vec<CandidateEvent>>),
693	/// Get the execution environment parameter set by session index
694	SessionExecutorParams(SessionIndex, RuntimeApiSender<Option<ExecutorParams>>),
695	/// Get the session info for the given session, if stored.
696	SessionInfo(SessionIndex, RuntimeApiSender<Option<SessionInfo>>),
697	/// Get all the pending inbound messages in the downward message queue for a para.
698	DmqContents(ParaId, RuntimeApiSender<Vec<InboundDownwardMessage<BlockNumber>>>),
699	/// Get the contents of all channels addressed to the given recipient. Channels that have no
700	/// messages in them are also included.
701	InboundHrmpChannelsContents(
702		ParaId,
703		RuntimeApiSender<BTreeMap<ParaId, Vec<InboundHrmpMessage<BlockNumber>>>>,
704	),
705	/// Get information about the BABE epoch the block was included in.
706	CurrentBabeEpoch(RuntimeApiSender<BabeEpoch>),
707	/// Get all disputes in relation to a relay parent.
708	FetchOnChainVotes(RuntimeApiSender<Option<polkadot_primitives::ScrapedOnChainVotes>>),
709	/// Submits a PVF pre-checking statement into the transaction pool.
710	SubmitPvfCheckStatement(PvfCheckStatement, ValidatorSignature, RuntimeApiSender<()>),
711	/// Returns code hashes of PVFs that require pre-checking by validators in the active set.
712	PvfsRequirePrecheck(RuntimeApiSender<Vec<ValidationCodeHash>>),
713	/// Get the validation code used by the specified para, taking the given
714	/// `OccupiedCoreAssumption`, which will inform on how the validation data should be computed
715	/// if the para currently occupies a core.
716	ValidationCodeHash(
717		ParaId,
718		OccupiedCoreAssumption,
719		RuntimeApiSender<Option<ValidationCodeHash>>,
720	),
721	/// Returns all on-chain disputes at given block number. Available in `v3`.
722	Disputes(RuntimeApiSender<Vec<(SessionIndex, CandidateHash, DisputeState<BlockNumber>)>>),
723	/// Returns a list of validators that lost a past session dispute and need to be slashed.
724	/// `V5`
725	UnappliedSlashes(
726		RuntimeApiSender<Vec<(SessionIndex, CandidateHash, slashing::PendingSlashes)>>,
727	),
728	/// Returns a merkle proof of a validator session key.
729	/// `V5`
730	KeyOwnershipProof(ValidatorId, RuntimeApiSender<Option<slashing::OpaqueKeyOwnershipProof>>),
731	/// Submits an unsigned extrinsic to slash validator who lost a past session dispute.
732	/// `V5`
733	SubmitReportDisputeLost(
734		slashing::DisputeProof,
735		slashing::OpaqueKeyOwnershipProof,
736		RuntimeApiSender<Option<()>>,
737	),
738	/// Get the minimum required backing votes.
739	MinimumBackingVotes(SessionIndex, RuntimeApiSender<u32>),
740	/// Returns all disabled validators at a given block height.
741	DisabledValidators(RuntimeApiSender<Vec<ValidatorIndex>>),
742	/// Get the backing state of the given para.
743	ParaBackingState(ParaId, RuntimeApiSender<Option<async_backing::BackingState>>),
744	/// Get candidate's acceptance limitations for asynchronous backing for a relay parent.
745	///
746	/// If it's not supported by the Runtime, the async backing is said to be disabled.
747	AsyncBackingParams(RuntimeApiSender<async_backing::AsyncBackingParams>),
748	/// Get the node features.
749	NodeFeatures(SessionIndex, RuntimeApiSender<NodeFeatures>),
750	/// Approval voting params
751	/// `V10`
752	ApprovalVotingParams(SessionIndex, RuntimeApiSender<ApprovalVotingParams>),
753	/// Fetch the `ClaimQueue` from scheduler pallet
754	/// `V11`
755	ClaimQueue(RuntimeApiSender<BTreeMap<CoreIndex, VecDeque<ParaId>>>),
756	/// Get the candidates pending availability for a particular parachain
757	/// `V11`
758	CandidatesPendingAvailability(ParaId, RuntimeApiSender<Vec<CommittedCandidateReceipt>>),
759}
760
761impl RuntimeApiRequest {
762	/// Runtime version requirements for each message
763
764	/// `Disputes`
765	pub const DISPUTES_RUNTIME_REQUIREMENT: u32 = 3;
766
767	/// `ExecutorParams`
768	pub const EXECUTOR_PARAMS_RUNTIME_REQUIREMENT: u32 = 4;
769
770	/// `UnappliedSlashes`
771	pub const UNAPPLIED_SLASHES_RUNTIME_REQUIREMENT: u32 = 5;
772
773	/// `KeyOwnershipProof`
774	pub const KEY_OWNERSHIP_PROOF_RUNTIME_REQUIREMENT: u32 = 5;
775
776	/// `SubmitReportDisputeLost`
777	pub const SUBMIT_REPORT_DISPUTE_LOST_RUNTIME_REQUIREMENT: u32 = 5;
778
779	/// `MinimumBackingVotes`
780	pub const MINIMUM_BACKING_VOTES_RUNTIME_REQUIREMENT: u32 = 6;
781
782	/// Minimum version to enable asynchronous backing: `AsyncBackingParams` and `ParaBackingState`.
783	pub const ASYNC_BACKING_STATE_RUNTIME_REQUIREMENT: u32 = 7;
784
785	/// `DisabledValidators`
786	pub const DISABLED_VALIDATORS_RUNTIME_REQUIREMENT: u32 = 8;
787
788	/// `Node features`
789	pub const NODE_FEATURES_RUNTIME_REQUIREMENT: u32 = 9;
790
791	/// `approval_voting_params`
792	pub const APPROVAL_VOTING_PARAMS_REQUIREMENT: u32 = 10;
793
794	/// `ClaimQueue`
795	pub const CLAIM_QUEUE_RUNTIME_REQUIREMENT: u32 = 11;
796
797	/// `candidates_pending_availability`
798	pub const CANDIDATES_PENDING_AVAILABILITY_RUNTIME_REQUIREMENT: u32 = 11;
799}
800
801/// A message to the Runtime API subsystem.
802#[derive(Debug)]
803pub enum RuntimeApiMessage {
804	/// Make a request of the runtime API against the post-state of the given relay-parent.
805	Request(Hash, RuntimeApiRequest),
806}
807
808/// Statement distribution message.
809#[derive(Debug, derive_more::From)]
810pub enum StatementDistributionMessage {
811	/// We have originated a signed statement in the context of
812	/// given relay-parent hash and it should be distributed to other validators.
813	Share(Hash, SignedFullStatementWithPVD),
814	/// The candidate received enough validity votes from the backing group.
815	///
816	/// If the candidate is backed as a result of a local statement, this message MUST
817	/// be preceded by a `Share` message for that statement. This ensures that Statement
818	/// Distribution is always aware of full candidates prior to receiving the `Backed`
819	/// notification, even when the group size is 1 and the candidate is seconded locally.
820	Backed(CandidateHash),
821	/// Event from the network bridge.
822	#[from]
823	NetworkBridgeUpdate(NetworkBridgeEvent<net_protocol::StatementDistributionMessage>),
824}
825
826/// This data becomes intrinsics or extrinsics which should be included in a future relay chain
827/// block.
828// It needs to be clonable because multiple potential block authors can request copies.
829#[derive(Debug, Clone)]
830pub enum ProvisionableData {
831	/// This bitfield indicates the availability of various candidate blocks.
832	Bitfield(Hash, SignedAvailabilityBitfield),
833	/// The Candidate Backing subsystem believes that this candidate is valid, pending
834	/// availability.
835	BackedCandidate(CandidateReceipt),
836	/// Misbehavior reports are self-contained proofs of validator misbehavior.
837	MisbehaviorReport(Hash, ValidatorIndex, Misbehavior),
838	/// Disputes trigger a broad dispute resolution process.
839	Dispute(Hash, ValidatorSignature),
840}
841
842/// Inherent data returned by the provisioner
843#[derive(Debug, Clone)]
844pub struct ProvisionerInherentData {
845	/// Signed bitfields.
846	pub bitfields: SignedAvailabilityBitfields,
847	/// Backed candidates.
848	pub backed_candidates: Vec<BackedCandidate>,
849	/// Dispute statement sets.
850	pub disputes: MultiDisputeStatementSet,
851}
852
853/// Message to the Provisioner.
854///
855/// In all cases, the Hash is that of the relay parent.
856#[derive(Debug)]
857pub enum ProvisionerMessage {
858	/// This message allows external subsystems to request the set of bitfields and backed
859	/// candidates associated with a particular potential block hash.
860	///
861	/// This is expected to be used by a proposer, to inject that information into the
862	/// `InherentData` where it can be assembled into the `ParaInherent`.
863	RequestInherentData(Hash, oneshot::Sender<ProvisionerInherentData>),
864	/// This data should become part of a relay chain block
865	ProvisionableData(Hash, ProvisionableData),
866}
867
868/// Message to the Collation Generation subsystem.
869#[derive(Debug)]
870pub enum CollationGenerationMessage {
871	/// Initialize the collation generation subsystem.
872	Initialize(CollationGenerationConfig),
873	/// Reinitialize the collation generation subsystem, overriding the existing config.
874	Reinitialize(CollationGenerationConfig),
875	/// Submit a collation to the subsystem. This will package it into a signed
876	/// [`CommittedCandidateReceipt`] and distribute along the network to validators.
877	///
878	/// If sent before `Initialize`, this will be ignored.
879	SubmitCollation(SubmitCollationParams),
880}
881
882/// The result type of [`ApprovalVotingMessage::ImportAssignment`] request.
883#[derive(Debug, Clone, PartialEq, Eq)]
884pub enum AssignmentCheckResult {
885	/// The vote was accepted and should be propagated onwards.
886	Accepted,
887	/// The vote was valid but duplicate and should not be propagated onwards.
888	AcceptedDuplicate,
889	/// The vote was valid but too far in the future to accept right now.
890	TooFarInFuture,
891	/// The vote was bad and should be ignored, reporting the peer who propagated it.
892	Bad(AssignmentCheckError),
893}
894
895/// The error result type of [`ApprovalVotingMessage::ImportAssignment`] request.
896#[derive(Error, Debug, Clone, PartialEq, Eq)]
897#[allow(missing_docs)]
898pub enum AssignmentCheckError {
899	#[error("Unknown block: {0:?}")]
900	UnknownBlock(Hash),
901	#[error("Unknown session index: {0}")]
902	UnknownSessionIndex(SessionIndex),
903	#[error("Invalid candidate index: {0}")]
904	InvalidCandidateIndex(CandidateIndex),
905	#[error("Invalid candidate {0}: {1:?}")]
906	InvalidCandidate(CandidateIndex, CandidateHash),
907	#[error("Invalid cert: {0:?}, reason: {1}")]
908	InvalidCert(ValidatorIndex, String),
909	#[error("Internal state mismatch: {0:?}, {1:?}")]
910	Internal(Hash, CandidateHash),
911	#[error("Oversized candidate or core bitfield >= {0}")]
912	InvalidBitfield(usize),
913}
914
915/// The result type of [`ApprovalVotingMessage::ImportApproval`] request.
916#[derive(Debug, Clone, PartialEq, Eq)]
917pub enum ApprovalCheckResult {
918	/// The vote was accepted and should be propagated onwards.
919	Accepted,
920	/// The vote was bad and should be ignored, reporting the peer who propagated it.
921	Bad(ApprovalCheckError),
922}
923
924/// The error result type of [`ApprovalVotingMessage::ImportApproval`] request.
925#[derive(Error, Debug, Clone, PartialEq, Eq)]
926#[allow(missing_docs)]
927pub enum ApprovalCheckError {
928	#[error("Unknown block: {0:?}")]
929	UnknownBlock(Hash),
930	#[error("Unknown session index: {0}")]
931	UnknownSessionIndex(SessionIndex),
932	#[error("Invalid candidate index: {0}")]
933	InvalidCandidateIndex(CandidateIndex),
934	#[error("Invalid validator index: {0:?}")]
935	InvalidValidatorIndex(ValidatorIndex),
936	#[error("Invalid candidate {0}: {1:?}")]
937	InvalidCandidate(CandidateIndex, CandidateHash),
938	#[error("Invalid signature: {0:?}")]
939	InvalidSignature(ValidatorIndex),
940	#[error("No assignment for {0:?}")]
941	NoAssignment(ValidatorIndex),
942	#[error("Internal state mismatch: {0:?}, {1:?}")]
943	Internal(Hash, CandidateHash),
944}
945
946/// Describes a relay-chain block by the para-chain candidates
947/// it includes.
948#[derive(Clone, Debug)]
949pub struct BlockDescription {
950	/// The relay-chain block hash.
951	pub block_hash: Hash,
952	/// The session index of this block.
953	pub session: SessionIndex,
954	/// The set of para-chain candidates.
955	pub candidates: Vec<CandidateHash>,
956}
957
958/// Message to the approval voting parallel subsystem running both approval-distribution and
959/// approval-voting logic in parallel. This is a combination of all the messages ApprovalVoting and
960/// ApprovalDistribution subsystems can receive.
961///
962/// The reason this exists is, so that we can keep both modes of running in the same polkadot
963/// binary, based on the value of `--approval-voting-parallel-enabled`, we decide if we run with two
964/// different subsystems for approval-distribution and approval-voting or run the approval-voting
965/// parallel which has several parallel workers for the approval-distribution and a worker for
966/// approval-voting.
967///
968/// This is meant to be a temporary state until we can safely remove running the two subsystems
969/// individually.
970#[derive(Debug, derive_more::From)]
971pub enum ApprovalVotingParallelMessage {
972	/// Gets mapped into `ApprovalVotingMessage::ApprovedAncestor`
973	ApprovedAncestor(Hash, BlockNumber, oneshot::Sender<Option<HighestApprovedAncestorBlock>>),
974
975	/// Gets mapped into `ApprovalVotingMessage::GetApprovalSignaturesForCandidate`
976	GetApprovalSignaturesForCandidate(
977		CandidateHash,
978		oneshot::Sender<HashMap<ValidatorIndex, (Vec<CandidateHash>, ValidatorSignature)>>,
979	),
980	/// Gets mapped into `ApprovalDistributionMessage::NewBlocks`
981	NewBlocks(Vec<BlockApprovalMeta>),
982	/// Gets mapped into `ApprovalDistributionMessage::DistributeAssignment`
983	DistributeAssignment(IndirectAssignmentCertV2, CandidateBitfield),
984	/// Gets mapped into `ApprovalDistributionMessage::DistributeApproval`
985	DistributeApproval(IndirectSignedApprovalVoteV2),
986	/// An update from the network bridge, gets mapped into
987	/// `ApprovalDistributionMessage::NetworkBridgeUpdate`
988	#[from]
989	NetworkBridgeUpdate(NetworkBridgeEvent<net_protocol::ApprovalDistributionMessage>),
990
991	/// Gets mapped into `ApprovalDistributionMessage::GetApprovalSignatures`
992	GetApprovalSignatures(
993		HashSet<(Hash, CandidateIndex)>,
994		oneshot::Sender<HashMap<ValidatorIndex, (Hash, Vec<CandidateIndex>, ValidatorSignature)>>,
995	),
996	/// Gets mapped into `ApprovalDistributionMessage::ApprovalCheckingLagUpdate`
997	ApprovalCheckingLagUpdate(BlockNumber),
998}
999
1000impl TryFrom<ApprovalVotingParallelMessage> for ApprovalVotingMessage {
1001	type Error = ();
1002
1003	fn try_from(msg: ApprovalVotingParallelMessage) -> Result<Self, Self::Error> {
1004		match msg {
1005			ApprovalVotingParallelMessage::ApprovedAncestor(hash, number, tx) =>
1006				Ok(ApprovalVotingMessage::ApprovedAncestor(hash, number, tx)),
1007			ApprovalVotingParallelMessage::GetApprovalSignaturesForCandidate(candidate, tx) =>
1008				Ok(ApprovalVotingMessage::GetApprovalSignaturesForCandidate(candidate, tx)),
1009			_ => Err(()),
1010		}
1011	}
1012}
1013
1014impl TryFrom<ApprovalVotingParallelMessage> for ApprovalDistributionMessage {
1015	type Error = ();
1016
1017	fn try_from(msg: ApprovalVotingParallelMessage) -> Result<Self, Self::Error> {
1018		match msg {
1019			ApprovalVotingParallelMessage::NewBlocks(blocks) =>
1020				Ok(ApprovalDistributionMessage::NewBlocks(blocks)),
1021			ApprovalVotingParallelMessage::DistributeAssignment(assignment, claimed_cores) =>
1022				Ok(ApprovalDistributionMessage::DistributeAssignment(assignment, claimed_cores)),
1023			ApprovalVotingParallelMessage::DistributeApproval(vote) =>
1024				Ok(ApprovalDistributionMessage::DistributeApproval(vote)),
1025			ApprovalVotingParallelMessage::NetworkBridgeUpdate(msg) =>
1026				Ok(ApprovalDistributionMessage::NetworkBridgeUpdate(msg)),
1027			ApprovalVotingParallelMessage::GetApprovalSignatures(candidate_indicies, tx) =>
1028				Ok(ApprovalDistributionMessage::GetApprovalSignatures(candidate_indicies, tx)),
1029			ApprovalVotingParallelMessage::ApprovalCheckingLagUpdate(lag) =>
1030				Ok(ApprovalDistributionMessage::ApprovalCheckingLagUpdate(lag)),
1031			_ => Err(()),
1032		}
1033	}
1034}
1035
1036impl From<ApprovalDistributionMessage> for ApprovalVotingParallelMessage {
1037	fn from(msg: ApprovalDistributionMessage) -> Self {
1038		match msg {
1039			ApprovalDistributionMessage::NewBlocks(blocks) =>
1040				ApprovalVotingParallelMessage::NewBlocks(blocks),
1041			ApprovalDistributionMessage::DistributeAssignment(cert, bitfield) =>
1042				ApprovalVotingParallelMessage::DistributeAssignment(cert, bitfield),
1043			ApprovalDistributionMessage::DistributeApproval(vote) =>
1044				ApprovalVotingParallelMessage::DistributeApproval(vote),
1045			ApprovalDistributionMessage::NetworkBridgeUpdate(msg) =>
1046				ApprovalVotingParallelMessage::NetworkBridgeUpdate(msg),
1047			ApprovalDistributionMessage::GetApprovalSignatures(candidate_indicies, tx) =>
1048				ApprovalVotingParallelMessage::GetApprovalSignatures(candidate_indicies, tx),
1049			ApprovalDistributionMessage::ApprovalCheckingLagUpdate(lag) =>
1050				ApprovalVotingParallelMessage::ApprovalCheckingLagUpdate(lag),
1051		}
1052	}
1053}
1054
1055/// Response type to `ApprovalVotingMessage::ApprovedAncestor`.
1056#[derive(Clone, Debug)]
1057pub struct HighestApprovedAncestorBlock {
1058	/// The block hash of the highest viable ancestor.
1059	pub hash: Hash,
1060	/// The block number of the highest viable ancestor.
1061	pub number: BlockNumber,
1062	/// Block descriptions in the direct path between the
1063	/// initially provided hash and the highest viable ancestor.
1064	/// Primarily for use with `DetermineUndisputedChain`.
1065	/// Must be sorted from lowest to highest block number.
1066	pub descriptions: Vec<BlockDescription>,
1067}
1068
1069/// A checked indirect assignment, the crypto for the cert has been validated
1070/// and the `candidate_bitfield` is correctly claimed at `delay_tranche`.
1071#[derive(Debug)]
1072pub struct CheckedIndirectAssignment {
1073	assignment: IndirectAssignmentCertV2,
1074	candidate_indices: CandidateBitfield,
1075	tranche: DelayTranche,
1076}
1077
1078impl CheckedIndirectAssignment {
1079	/// Builds a checked assignment from an assignment that was checked to be valid for the
1080	/// `claimed_candidate_indices` at the give tranche
1081	pub fn from_checked(
1082		assignment: IndirectAssignmentCertV2,
1083		claimed_candidate_indices: CandidateBitfield,
1084		tranche: DelayTranche,
1085	) -> Self {
1086		Self { assignment, candidate_indices: claimed_candidate_indices, tranche }
1087	}
1088
1089	/// Returns the indirect assignment.
1090	pub fn assignment(&self) -> &IndirectAssignmentCertV2 {
1091		&self.assignment
1092	}
1093
1094	/// Returns the candidate bitfield claimed by the assignment.
1095	pub fn candidate_indices(&self) -> &CandidateBitfield {
1096		&self.candidate_indices
1097	}
1098
1099	/// Returns the tranche this assignment is claimed at.
1100	pub fn tranche(&self) -> DelayTranche {
1101		self.tranche
1102	}
1103}
1104
1105/// A checked indirect signed approval vote.
1106///
1107/// The crypto for the vote has been validated and the signature can be trusted as being valid and
1108/// to correspond to the `validator_index` inside the structure.
1109#[derive(Debug, derive_more::Deref, derive_more::Into)]
1110pub struct CheckedIndirectSignedApprovalVote(IndirectSignedApprovalVoteV2);
1111
1112impl CheckedIndirectSignedApprovalVote {
1113	/// Builds a checked vote from a vote that was checked to be valid and correctly signed.
1114	pub fn from_checked(vote: IndirectSignedApprovalVoteV2) -> Self {
1115		Self(vote)
1116	}
1117}
1118
1119/// Message to the Approval Voting subsystem.
1120#[derive(Debug)]
1121pub enum ApprovalVotingMessage {
1122	/// Import an assignment into the approval-voting database.
1123	///
1124	/// Should not be sent unless the block hash is known and the VRF assignment checks out.
1125	ImportAssignment(CheckedIndirectAssignment, Option<oneshot::Sender<AssignmentCheckResult>>),
1126	/// Import an approval vote into approval-voting database
1127	///
1128	/// Should not be sent unless the block hash within the indirect vote is known, vote is
1129	/// correctly signed and we had a previous assignment for the candidate.
1130	ImportApproval(CheckedIndirectSignedApprovalVote, Option<oneshot::Sender<ApprovalCheckResult>>),
1131	/// Returns the highest possible ancestor hash of the provided block hash which is
1132	/// acceptable to vote on finality for.
1133	/// The `BlockNumber` provided is the number of the block's ancestor which is the
1134	/// earliest possible vote.
1135	///
1136	/// It can also return the same block hash, if that is acceptable to vote upon.
1137	/// Return `None` if the input hash is unrecognized.
1138	ApprovedAncestor(Hash, BlockNumber, oneshot::Sender<Option<HighestApprovedAncestorBlock>>),
1139
1140	/// Retrieve all available approval signatures for a candidate from approval-voting.
1141	///
1142	/// This message involves a linear search for candidates on each relay chain fork and also
1143	/// requires calling into `approval-distribution`: Calls should be infrequent and bounded.
1144	GetApprovalSignaturesForCandidate(
1145		CandidateHash,
1146		oneshot::Sender<HashMap<ValidatorIndex, (Vec<CandidateHash>, ValidatorSignature)>>,
1147	),
1148}
1149
1150/// Message to the Approval Distribution subsystem.
1151#[derive(Debug, derive_more::From)]
1152pub enum ApprovalDistributionMessage {
1153	/// Notify the `ApprovalDistribution` subsystem about new blocks
1154	/// and the candidates contained within them.
1155	NewBlocks(Vec<BlockApprovalMeta>),
1156	/// Distribute an assignment cert from the local validator. The cert is assumed
1157	/// to be valid, relevant, and for the given relay-parent and validator index.
1158	DistributeAssignment(IndirectAssignmentCertV2, CandidateBitfield),
1159	/// Distribute an approval vote for the local validator. The approval vote is assumed to be
1160	/// valid, relevant, and the corresponding approval already issued.
1161	/// If not, the subsystem is free to drop the message.
1162	DistributeApproval(IndirectSignedApprovalVoteV2),
1163	/// An update from the network bridge.
1164	#[from]
1165	NetworkBridgeUpdate(NetworkBridgeEvent<net_protocol::ApprovalDistributionMessage>),
1166
1167	/// Get all approval signatures for all chains a candidate appeared in.
1168	GetApprovalSignatures(
1169		HashSet<(Hash, CandidateIndex)>,
1170		oneshot::Sender<HashMap<ValidatorIndex, (Hash, Vec<CandidateIndex>, ValidatorSignature)>>,
1171	),
1172	/// Approval checking lag update measured in blocks.
1173	ApprovalCheckingLagUpdate(BlockNumber),
1174}
1175
1176/// Message to the Gossip Support subsystem.
1177#[derive(Debug, derive_more::From)]
1178pub enum GossipSupportMessage {
1179	/// Dummy constructor, so we can receive networking events.
1180	#[from]
1181	NetworkBridgeUpdate(NetworkBridgeEvent<net_protocol::GossipSupportNetworkMessage>),
1182}
1183
1184/// Request introduction of a seconded candidate into the prospective parachains subsystem.
1185#[derive(Debug, PartialEq, Eq, Clone)]
1186pub struct IntroduceSecondedCandidateRequest {
1187	/// The para-id of the candidate.
1188	pub candidate_para: ParaId,
1189	/// The candidate receipt itself.
1190	pub candidate_receipt: CommittedCandidateReceipt,
1191	/// The persisted validation data of the candidate.
1192	pub persisted_validation_data: PersistedValidationData,
1193}
1194
1195/// A hypothetical candidate to be evaluated for potential/actual membership
1196/// in the prospective parachains subsystem.
1197///
1198/// Hypothetical candidates are either complete or incomplete.
1199/// Complete candidates have already had their (potentially heavy)
1200/// candidate receipt fetched, while incomplete candidates are simply
1201/// claims about properties that a fetched candidate would have.
1202///
1203/// Complete candidates can be evaluated more strictly than incomplete candidates.
1204#[derive(Debug, PartialEq, Eq, Clone)]
1205pub enum HypotheticalCandidate {
1206	/// A complete candidate.
1207	Complete {
1208		/// The hash of the candidate.
1209		candidate_hash: CandidateHash,
1210		/// The receipt of the candidate.
1211		receipt: Arc<CommittedCandidateReceipt>,
1212		/// The persisted validation data of the candidate.
1213		persisted_validation_data: PersistedValidationData,
1214	},
1215	/// An incomplete candidate.
1216	Incomplete {
1217		/// The claimed hash of the candidate.
1218		candidate_hash: CandidateHash,
1219		/// The claimed para-ID of the candidate.
1220		candidate_para: ParaId,
1221		/// The claimed head-data hash of the candidate.
1222		parent_head_data_hash: Hash,
1223		/// The claimed relay parent of the candidate.
1224		candidate_relay_parent: Hash,
1225	},
1226}
1227
1228impl HypotheticalCandidate {
1229	/// Get the `CandidateHash` of the hypothetical candidate.
1230	pub fn candidate_hash(&self) -> CandidateHash {
1231		match *self {
1232			HypotheticalCandidate::Complete { candidate_hash, .. } => candidate_hash,
1233			HypotheticalCandidate::Incomplete { candidate_hash, .. } => candidate_hash,
1234		}
1235	}
1236
1237	/// Get the `ParaId` of the hypothetical candidate.
1238	pub fn candidate_para(&self) -> ParaId {
1239		match *self {
1240			HypotheticalCandidate::Complete { ref receipt, .. } => receipt.descriptor().para_id,
1241			HypotheticalCandidate::Incomplete { candidate_para, .. } => candidate_para,
1242		}
1243	}
1244
1245	/// Get parent head data hash of the hypothetical candidate.
1246	pub fn parent_head_data_hash(&self) -> Hash {
1247		match *self {
1248			HypotheticalCandidate::Complete { ref persisted_validation_data, .. } =>
1249				persisted_validation_data.parent_head.hash(),
1250			HypotheticalCandidate::Incomplete { parent_head_data_hash, .. } =>
1251				parent_head_data_hash,
1252		}
1253	}
1254
1255	/// Get candidate's relay parent.
1256	pub fn relay_parent(&self) -> Hash {
1257		match *self {
1258			HypotheticalCandidate::Complete { ref receipt, .. } =>
1259				receipt.descriptor().relay_parent,
1260			HypotheticalCandidate::Incomplete { candidate_relay_parent, .. } =>
1261				candidate_relay_parent,
1262		}
1263	}
1264
1265	/// Get the output head data hash, if the candidate is complete.
1266	pub fn output_head_data_hash(&self) -> Option<Hash> {
1267		match *self {
1268			HypotheticalCandidate::Complete { ref receipt, .. } =>
1269				Some(receipt.descriptor.para_head),
1270			HypotheticalCandidate::Incomplete { .. } => None,
1271		}
1272	}
1273
1274	/// Get the candidate commitments, if the candidate is complete.
1275	pub fn commitments(&self) -> Option<&CandidateCommitments> {
1276		match *self {
1277			HypotheticalCandidate::Complete { ref receipt, .. } => Some(&receipt.commitments),
1278			HypotheticalCandidate::Incomplete { .. } => None,
1279		}
1280	}
1281
1282	/// Get the persisted validation data, if the candidate is complete.
1283	pub fn persisted_validation_data(&self) -> Option<&PersistedValidationData> {
1284		match *self {
1285			HypotheticalCandidate::Complete { ref persisted_validation_data, .. } =>
1286				Some(persisted_validation_data),
1287			HypotheticalCandidate::Incomplete { .. } => None,
1288		}
1289	}
1290
1291	/// Get the validation code hash, if the candidate is complete.
1292	pub fn validation_code_hash(&self) -> Option<&ValidationCodeHash> {
1293		match *self {
1294			HypotheticalCandidate::Complete { ref receipt, .. } =>
1295				Some(&receipt.descriptor.validation_code_hash),
1296			HypotheticalCandidate::Incomplete { .. } => None,
1297		}
1298	}
1299}
1300
1301/// Request specifying which candidates are either already included
1302/// or might become included in fragment chain under a given active leaf (or any active leaf if
1303/// `fragment_chain_relay_parent` is `None`).
1304#[derive(Debug, PartialEq, Eq, Clone)]
1305pub struct HypotheticalMembershipRequest {
1306	/// Candidates, in arbitrary order, which should be checked for
1307	/// hypothetical/actual membership in fragment chains.
1308	pub candidates: Vec<HypotheticalCandidate>,
1309	/// Either a specific fragment chain to check, otherwise all.
1310	pub fragment_chain_relay_parent: Option<Hash>,
1311}
1312
1313/// A request for the persisted validation data stored in the prospective
1314/// parachains subsystem.
1315#[derive(Debug)]
1316pub struct ProspectiveValidationDataRequest {
1317	/// The para-id of the candidate.
1318	pub para_id: ParaId,
1319	/// The relay-parent of the candidate.
1320	pub candidate_relay_parent: Hash,
1321	/// The parent head-data.
1322	pub parent_head_data: ParentHeadData,
1323}
1324
1325/// The parent head-data hash with optional data itself.
1326#[derive(Debug, Clone)]
1327pub enum ParentHeadData {
1328	/// Parent head-data hash.
1329	OnlyHash(Hash),
1330	/// Parent head-data along with its hash.
1331	WithData {
1332		/// This will be provided for collations with elastic scaling enabled.
1333		head_data: HeadData,
1334		/// Parent head-data hash.
1335		hash: Hash,
1336	},
1337}
1338
1339impl ParentHeadData {
1340	/// Return the hash of the parent head-data.
1341	pub fn hash(&self) -> Hash {
1342		match self {
1343			ParentHeadData::OnlyHash(hash) => *hash,
1344			ParentHeadData::WithData { hash, .. } => *hash,
1345		}
1346	}
1347}
1348
1349/// Indicates the relay-parents whose fragment chain a candidate
1350/// is present in or can be added in (right now or in the future).
1351pub type HypotheticalMembership = Vec<Hash>;
1352
1353/// A collection of ancestor candidates of a parachain.
1354pub type Ancestors = HashSet<CandidateHash>;
1355
1356/// Messages sent to the Prospective Parachains subsystem.
1357#[derive(Debug)]
1358pub enum ProspectiveParachainsMessage {
1359	/// Inform the Prospective Parachains Subsystem of a new seconded candidate.
1360	///
1361	/// The response sender returns false if the candidate was rejected by prospective parachains,
1362	/// true otherwise (if it was accepted or already present)
1363	IntroduceSecondedCandidate(IntroduceSecondedCandidateRequest, oneshot::Sender<bool>),
1364	/// Inform the Prospective Parachains Subsystem that a previously introduced candidate
1365	/// has been backed. This requires that the candidate was successfully introduced in
1366	/// the past.
1367	CandidateBacked(ParaId, CandidateHash),
1368	/// Try getting N backable candidate hashes along with their relay parents for the given
1369	/// parachain, under the given relay-parent hash, which is a descendant of the given ancestors.
1370	/// Timed out ancestors should not be included in the collection.
1371	/// N should represent the number of scheduled cores of this ParaId.
1372	/// A timed out ancestor frees the cores of all of its descendants, so if there's a hole in the
1373	/// supplied ancestor path, we'll get candidates that backfill those timed out slots first. It
1374	/// may also return less/no candidates, if there aren't enough backable candidates recorded.
1375	GetBackableCandidates(
1376		Hash,
1377		ParaId,
1378		u32,
1379		Ancestors,
1380		oneshot::Sender<Vec<(CandidateHash, Hash)>>,
1381	),
1382	/// Get the hypothetical or actual membership of candidates with the given properties
1383	/// under the specified active leave's fragment chain.
1384	///
1385	/// For each candidate, we return a vector of leaves where the candidate is present or could be
1386	/// added. "Could be added" either means that the candidate can be added to the chain right now
1387	/// or could be added in the future (we may not have its ancestors yet).
1388	/// Note that even if we think it could be added in the future, we may find out that it was
1389	/// invalid, as time passes.
1390	/// If an active leaf is not in the vector, it means that there's no
1391	/// chance this candidate will become valid under that leaf in the future.
1392	///
1393	/// If `fragment_chain_relay_parent` in the request is `Some()`, the return vector can only
1394	/// contain this relay parent (or none).
1395	GetHypotheticalMembership(
1396		HypotheticalMembershipRequest,
1397		oneshot::Sender<Vec<(HypotheticalCandidate, HypotheticalMembership)>>,
1398	),
1399	/// Get the minimum accepted relay-parent number for each para in the fragment chain
1400	/// for the given relay-chain block hash.
1401	///
1402	/// That is, if the block hash is known and is an active leaf, this returns the
1403	/// minimum relay-parent block number in the same branch of the relay chain which
1404	/// is accepted in the fragment chain for each para-id.
1405	///
1406	/// If the block hash is not an active leaf, this will return an empty vector.
1407	///
1408	/// Para-IDs which are omitted from this list can be assumed to have no
1409	/// valid candidate relay-parents under the given relay-chain block hash.
1410	///
1411	/// Para-IDs are returned in no particular order.
1412	GetMinimumRelayParents(Hash, oneshot::Sender<Vec<(ParaId, BlockNumber)>>),
1413	/// Get the validation data of some prospective candidate. The candidate doesn't need
1414	/// to be part of any fragment chain, but this only succeeds if the parent head-data and
1415	/// relay-parent are part of the `CandidateStorage` (meaning that it's a candidate which is
1416	/// part of some fragment chain or which prospective-parachains predicted will become part of
1417	/// some fragment chain).
1418	GetProspectiveValidationData(
1419		ProspectiveValidationDataRequest,
1420		oneshot::Sender<Option<PersistedValidationData>>,
1421	),
1422}