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