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}