referrerpolicy=no-referrer-when-downgrade

cumulus_client_consensus_aura/collators/slot_based/
mod.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// This file is part of Cumulus.
3// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
4
5// Cumulus is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9
10// Cumulus is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14
15// You should have received a copy of the GNU General Public License
16// along with Cumulus. If not, see <https://www.gnu.org/licenses/>.
17
18//! # Architecture Overview
19//!
20//! The block building mechanism operates through two coordinated tasks:
21//!
22//! 1. **Block Builder Task**: Orchestrates the timing and execution of parachain block production
23//! 2. **Collator Task**: Processes built blocks into collations for relay chain submission
24//!
25//! # Block Builder Task Details
26//!
27//! The block builder task manages block production timing and execution through an iterative
28//! process:
29//!
30//! 1. Awaits the next production signal from the internal timer
31//! 2. Retrieves the current best relay chain block and identifies a valid parent block (see
32//!    [find_potential_parents][cumulus_client_consensus_common::find_potential_parents] for parent
33//!    selection criteria)
34//! 3. Validates that:
35//!    - The parachain has an assigned core on the relay chain
36//!    - No block has been previously built on the target core
37//! 4. Executes block building and import operations
38//! 5. Transmits the completed block to the collator task
39//!
40//! # Block Production Timing
41//!
42//! When a block is produced is determined by the following parameters:
43//!
44//! - Parachain slot duration
45//! - Number of assigned parachain cores
46//! - Parachain runtime configuration
47//!
48//! ## Timing Examples
49//!
50//! The following table demonstrates various timing configurations and their effects. The "AURA
51//! Slot" column shows which author is responsible for the block.
52//!
53//! | Slot Duration (ms) | Cores | Production Attempts (ms) | AURA Slot  |
54//! |-------------------|--------|-------------------------|------------|
55//! | 2000              | 3      | 0, 2000, 4000, 6000    | 0, 1, 2, 3 |
56//! | 6000              | 1      | 0, 6000, 12000, 18000  | 0, 1, 2, 3 |
57//! | 6000              | 3      | 0, 2000, 4000, 6000    | 0, 0, 0, 1 |
58//! | 12000             | 1      | 0, 6000, 12000, 18000  | 0, 0, 1, 1 |
59//! | 12000             | 3      | 0, 2000, 4000, 6000    | 0, 0, 0, 0 |
60//!
61//! # Collator Task Details
62//!
63//! The collator task receives built blocks from the block builder task and performs two primary
64//! functions:
65//!
66//! 1. Block compression
67//! 2. Submission to the collation-generation subsystem
68
69use self::{block_builder_task::run_block_builder, collation_task::run_collation_task};
70pub use block_import::{SlotBasedBlockImport, SlotBasedBlockImportHandle};
71use codec::Codec;
72use consensus_common::ParachainCandidate;
73use cumulus_client_collator::service::ServiceInterface as CollatorServiceInterface;
74use cumulus_client_consensus_common::{self as consensus_common, ParachainBlockImportMarker};
75use cumulus_client_consensus_proposer::ProposerInterface;
76use cumulus_primitives_aura::AuraUnincludedSegmentApi;
77use cumulus_primitives_core::RelayParentOffsetApi;
78use cumulus_relay_chain_interface::RelayChainInterface;
79use futures::FutureExt;
80use polkadot_primitives::{
81	CollatorPair, CoreIndex, Hash as RelayHash, Id as ParaId, ValidationCodeHash,
82};
83use sc_client_api::{backend::AuxStore, BlockBackend, BlockOf, UsageProvider};
84use sc_consensus::BlockImport;
85use sc_utils::mpsc::tracing_unbounded;
86use sp_api::ProvideRuntimeApi;
87use sp_application_crypto::AppPublic;
88use sp_blockchain::HeaderBackend;
89use sp_consensus_aura::AuraApi;
90use sp_core::{crypto::Pair, traits::SpawnNamed};
91use sp_inherents::CreateInherentDataProviders;
92use sp_keystore::KeystorePtr;
93use sp_runtime::traits::{Block as BlockT, Member};
94use std::{path::PathBuf, sync::Arc, time::Duration};
95
96mod block_builder_task;
97mod block_import;
98mod collation_task;
99mod relay_chain_data_cache;
100mod slot_timer;
101
102#[cfg(test)]
103mod tests;
104
105/// Parameters for [`run`].
106pub struct Params<Block, BI, CIDP, Client, Backend, RClient, CHP, Proposer, CS, Spawner> {
107	/// Inherent data providers. Only non-consensus inherent data should be provided, i.e.
108	/// the timestamp, slot, and paras inherents should be omitted, as they are set by this
109	/// collator.
110	pub create_inherent_data_providers: CIDP,
111	/// Used to actually import blocks.
112	pub block_import: BI,
113	/// The underlying para client.
114	pub para_client: Arc<Client>,
115	/// The para client's backend, used to access the database.
116	pub para_backend: Arc<Backend>,
117	/// A handle to the relay-chain client.
118	pub relay_client: RClient,
119	/// A validation code hash provider, used to get the current validation code hash.
120	pub code_hash_provider: CHP,
121	/// The underlying keystore, which should contain Aura consensus keys.
122	pub keystore: KeystorePtr,
123	/// The collator key used to sign collations before submitting to validators.
124	pub collator_key: CollatorPair,
125	/// The para's ID.
126	pub para_id: ParaId,
127	/// The underlying block proposer this should call into.
128	pub proposer: Proposer,
129	/// The generic collator service used to plug into this consensus engine.
130	pub collator_service: CS,
131	/// The amount of time to spend authoring each block.
132	pub authoring_duration: Duration,
133	/// Whether we should reinitialize the collator config (i.e. we are transitioning to aura).
134	pub reinitialize: bool,
135	/// Offset slots by a fixed duration. This can be used to create more preferrable authoring
136	/// timings.
137	pub slot_offset: Duration,
138	/// The handle returned by [`SlotBasedBlockImport`].
139	pub block_import_handle: SlotBasedBlockImportHandle<Block>,
140	/// Spawner for spawning futures.
141	pub spawner: Spawner,
142	/// Slot duration of the relay chain
143	pub relay_chain_slot_duration: Duration,
144	/// When set, the collator will export every produced `POV` to this folder.
145	pub export_pov: Option<PathBuf>,
146	/// The maximum percentage of the maximum PoV size that the collator can use.
147	/// It will be removed once <https://github.com/paritytech/polkadot-sdk/issues/6020> is fixed.
148	pub max_pov_percentage: Option<u32>,
149}
150
151/// Run aura-based block building and collation task.
152pub fn run<Block, P, BI, CIDP, Client, Backend, RClient, CHP, Proposer, CS, Spawner>(
153	params: Params<Block, BI, CIDP, Client, Backend, RClient, CHP, Proposer, CS, Spawner>,
154) where
155	Block: BlockT,
156	Client: ProvideRuntimeApi<Block>
157		+ BlockOf
158		+ AuxStore
159		+ HeaderBackend<Block>
160		+ BlockBackend<Block>
161		+ UsageProvider<Block>
162		+ Send
163		+ Sync
164		+ 'static,
165	Client::Api:
166		AuraApi<Block, P::Public> + AuraUnincludedSegmentApi<Block> + RelayParentOffsetApi<Block>,
167	Backend: sc_client_api::Backend<Block> + 'static,
168	RClient: RelayChainInterface + Clone + 'static,
169	CIDP: CreateInherentDataProviders<Block, ()> + 'static,
170	CIDP::InherentDataProviders: Send,
171	BI: BlockImport<Block> + ParachainBlockImportMarker + Send + Sync + 'static,
172	Proposer: ProposerInterface<Block> + Send + Sync + 'static,
173	CS: CollatorServiceInterface<Block> + Send + Sync + Clone + 'static,
174	CHP: consensus_common::ValidationCodeHashProvider<Block::Hash> + Send + 'static,
175	P: Pair + 'static,
176	P::Public: AppPublic + Member + Codec,
177	P::Signature: TryFrom<Vec<u8>> + Member + Codec,
178	Spawner: SpawnNamed,
179{
180	let Params {
181		create_inherent_data_providers,
182		block_import,
183		para_client,
184		para_backend,
185		relay_client,
186		code_hash_provider,
187		keystore,
188		collator_key,
189		para_id,
190		proposer,
191		collator_service,
192		authoring_duration,
193		reinitialize,
194		slot_offset,
195		block_import_handle,
196		spawner,
197		export_pov,
198		relay_chain_slot_duration,
199		max_pov_percentage,
200	} = params;
201
202	let (tx, rx) = tracing_unbounded("mpsc_builder_to_collator", 100);
203	let collator_task_params = collation_task::Params {
204		relay_client: relay_client.clone(),
205		collator_key,
206		para_id,
207		reinitialize,
208		collator_service: collator_service.clone(),
209		collator_receiver: rx,
210		block_import_handle,
211		export_pov,
212	};
213
214	let collation_task_fut = run_collation_task::<Block, _, _>(collator_task_params);
215
216	let block_builder_params = block_builder_task::BuilderTaskParams {
217		create_inherent_data_providers,
218		block_import,
219		para_client,
220		para_backend,
221		relay_client,
222		code_hash_provider,
223		keystore,
224		para_id,
225		proposer,
226		collator_service,
227		authoring_duration,
228		collator_sender: tx,
229		relay_chain_slot_duration,
230		slot_offset,
231		max_pov_percentage,
232	};
233
234	let block_builder_fut =
235		run_block_builder::<Block, P, _, _, _, _, _, _, _, _>(block_builder_params);
236
237	spawner.spawn_blocking(
238		"slot-based-block-builder",
239		Some("slot-based-collator"),
240		block_builder_fut.boxed(),
241	);
242	spawner.spawn_blocking(
243		"slot-based-collation",
244		Some("slot-based-collator"),
245		collation_task_fut.boxed(),
246	);
247}
248
249/// Message to be sent from the block builder to the collation task.
250///
251/// Contains all data necessary to submit a collation to the relay chain.
252struct CollatorMessage<Block: BlockT> {
253	/// The hash of the relay chain block that provides the context for the parachain block.
254	pub relay_parent: RelayHash,
255	/// The header of the parent block.
256	pub parent_header: Block::Header,
257	/// The parachain block candidate.
258	pub parachain_candidate: ParachainCandidate<Block>,
259	/// The validation code hash at the parent block.
260	pub validation_code_hash: ValidationCodeHash,
261	/// Core index that this block should be submitted on
262	pub core_index: CoreIndex,
263	/// Maximum pov size. Currently needed only for exporting PoV.
264	pub max_pov_size: u32,
265}