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_primitives_aura::AuraUnincludedSegmentApi;
76use cumulus_primitives_core::RelayParentOffsetApi;
77use cumulus_relay_chain_interface::RelayChainInterface;
78use futures::FutureExt;
79use polkadot_primitives::{
80	CollatorPair, CoreIndex, Hash as RelayHash, Id as ParaId, ValidationCodeHash,
81};
82use sc_client_api::{backend::AuxStore, BlockBackend, BlockOf, UsageProvider};
83use sc_consensus::BlockImport;
84use sc_network_types::PeerId;
85use sc_utils::mpsc::tracing_unbounded;
86use sp_api::ProvideRuntimeApi;
87use sp_application_crypto::AppPublic;
88use sp_blockchain::HeaderBackend;
89use sp_consensus::Environment;
90use sp_consensus_aura::AuraApi;
91use sp_core::{crypto::Pair, traits::SpawnEssentialNamed};
92use sp_inherents::CreateInherentDataProviders;
93use sp_keystore::KeystorePtr;
94use sp_runtime::traits::{Block as BlockT, Member};
95use std::{path::PathBuf, sync::Arc, time::Duration};
96
97mod block_builder_task;
98mod block_import;
99mod collation_task;
100mod relay_chain_data_cache;
101mod slot_timer;
102
103#[cfg(test)]
104mod tests;
105
106/// Parameters for [`run`].
107pub struct Params<Block, BI, CIDP, Client, Backend, RClient, CHP, Proposer, CS, Spawner> {
108	/// Inherent data providers. Only non-consensus inherent data should be provided, i.e.
109	/// the timestamp, slot, and paras inherents should be omitted, as they are set by this
110	/// collator.
111	pub create_inherent_data_providers: CIDP,
112	/// Used to actually import blocks.
113	pub block_import: BI,
114	/// The underlying para client.
115	pub para_client: Arc<Client>,
116	/// The para client's backend, used to access the database.
117	pub para_backend: Arc<Backend>,
118	/// A handle to the relay-chain client.
119	pub relay_client: RClient,
120	/// A validation code hash provider, used to get the current validation code hash.
121	pub code_hash_provider: CHP,
122	/// The underlying keystore, which should contain Aura consensus keys.
123	pub keystore: KeystorePtr,
124	/// The collator key used to sign collations before submitting to validators.
125	pub collator_key: CollatorPair,
126	/// The collator network peer id.
127	pub collator_peer_id: PeerId,
128	/// The para's ID.
129	pub para_id: ParaId,
130	/// The proposer for building blocks.
131	pub proposer: Proposer,
132	/// The generic collator service used to plug into this consensus engine.
133	pub collator_service: CS,
134	/// The amount of time to spend authoring each block.
135	pub authoring_duration: Duration,
136	/// Whether we should reinitialize the collator config (i.e. we are transitioning to aura).
137	pub reinitialize: bool,
138	/// Offset slots by a fixed duration. This can be used to create more preferrable authoring
139	/// timings.
140	pub slot_offset: Duration,
141	/// The handle returned by [`SlotBasedBlockImport`].
142	pub block_import_handle: SlotBasedBlockImportHandle<Block>,
143	/// Spawner for spawning futures.
144	pub spawner: Spawner,
145	/// Slot duration of the relay chain
146	pub relay_chain_slot_duration: Duration,
147	/// When set, the collator will export every produced `POV` to this folder.
148	pub export_pov: Option<PathBuf>,
149	/// The maximum percentage of the maximum PoV size that the collator can use.
150	/// It will be removed once <https://github.com/paritytech/polkadot-sdk/issues/6020> is fixed.
151	pub max_pov_percentage: Option<u32>,
152}
153
154/// Run aura-based block building and collation task.
155pub fn run<Block, P, BI, CIDP, Client, Backend, RClient, CHP, Proposer, CS, Spawner>(
156	params: Params<Block, BI, CIDP, Client, Backend, RClient, CHP, Proposer, CS, Spawner>,
157) where
158	Block: BlockT,
159	Client: ProvideRuntimeApi<Block>
160		+ BlockOf
161		+ AuxStore
162		+ HeaderBackend<Block>
163		+ BlockBackend<Block>
164		+ UsageProvider<Block>
165		+ Send
166		+ Sync
167		+ 'static,
168	Client::Api:
169		AuraApi<Block, P::Public> + AuraUnincludedSegmentApi<Block> + RelayParentOffsetApi<Block>,
170	Backend: sc_client_api::Backend<Block> + 'static,
171	RClient: RelayChainInterface + Clone + 'static,
172	CIDP: CreateInherentDataProviders<Block, ()> + 'static,
173	CIDP::InherentDataProviders: Send,
174	BI: BlockImport<Block> + ParachainBlockImportMarker + Send + Sync + 'static,
175	Proposer: Environment<Block> + Send + Sync + 'static,
176	CS: CollatorServiceInterface<Block> + Send + Sync + Clone + 'static,
177	CHP: consensus_common::ValidationCodeHashProvider<Block::Hash> + Send + 'static,
178	P: Pair + Send + Sync + 'static,
179	P::Public: AppPublic + Member + Codec,
180	P::Signature: TryFrom<Vec<u8>> + Member + Codec,
181	Spawner: SpawnEssentialNamed + Clone + 'static,
182{
183	let Params {
184		create_inherent_data_providers,
185		block_import,
186		para_client,
187		para_backend,
188		relay_client,
189		code_hash_provider,
190		keystore,
191		collator_key,
192		collator_peer_id,
193		para_id,
194		proposer,
195		collator_service,
196		authoring_duration,
197		reinitialize,
198		slot_offset,
199		block_import_handle,
200		spawner,
201		export_pov,
202		relay_chain_slot_duration,
203		max_pov_percentage,
204	} = params;
205
206	let (tx, rx) = tracing_unbounded("mpsc_builder_to_collator", 100);
207	let collator_task_params = collation_task::Params {
208		relay_client: relay_client.clone(),
209		collator_key,
210		para_id,
211		reinitialize,
212		collator_service: collator_service.clone(),
213		collator_receiver: rx,
214		block_import_handle,
215		export_pov,
216	};
217
218	let collation_task_fut = run_collation_task::<Block, _, _>(collator_task_params);
219
220	let block_builder_params = block_builder_task::BuilderTaskParams {
221		create_inherent_data_providers,
222		block_import,
223		para_client,
224		para_backend,
225		relay_client,
226		code_hash_provider,
227		keystore,
228		collator_peer_id,
229		para_id,
230		proposer,
231		collator_service,
232		authoring_duration,
233		collator_sender: tx,
234		relay_chain_slot_duration,
235		slot_offset,
236		max_pov_percentage,
237	};
238
239	let block_builder_fut =
240		run_block_builder::<Block, P, _, _, _, _, _, _, _, _>(block_builder_params);
241
242	spawner.spawn_essential_blocking(
243		"slot-based-block-builder",
244		Some("slot-based-collator"),
245		block_builder_fut.boxed(),
246	);
247	spawner.spawn_essential_blocking(
248		"slot-based-collation",
249		Some("slot-based-collator"),
250		collation_task_fut.boxed(),
251	);
252}
253
254/// Message to be sent from the block builder to the collation task.
255///
256/// Contains all data necessary to submit a collation to the relay chain.
257struct CollatorMessage<Block: BlockT> {
258	/// The hash of the relay chain block that provides the context for the parachain block.
259	pub relay_parent: RelayHash,
260	/// The header of the parent block.
261	pub parent_header: Block::Header,
262	/// The parachain block candidate.
263	pub parachain_candidate: ParachainCandidate<Block>,
264	/// The validation code hash at the parent block.
265	pub validation_code_hash: ValidationCodeHash,
266	/// Core index that this block should be submitted on
267	pub core_index: CoreIndex,
268	/// Maximum pov size. Currently needed only for exporting PoV.
269	pub max_pov_size: u32,
270}