referrerpolicy=no-referrer-when-downgrade

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