referrerpolicy=no-referrer-when-downgrade

cumulus_client_consensus_relay_chain/
import_queue.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
18use std::{marker::PhantomData, sync::Arc};
19
20use cumulus_client_consensus_common::ParachainBlockImportMarker;
21
22use sc_consensus::{
23	import_queue::{BasicQueue, Verifier as VerifierT},
24	BlockImport, BlockImportParams,
25};
26use sp_api::ProvideRuntimeApi;
27use sp_block_builder::BlockBuilder as BlockBuilderApi;
28use sp_blockchain::Result as ClientResult;
29use sp_consensus::error::Error as ConsensusError;
30use sp_inherents::CreateInherentDataProviders;
31use sp_runtime::traits::{Block as BlockT, Header as HeaderT};
32
33/// A verifier that just checks the inherents.
34pub struct Verifier<Client, Block, CIDP> {
35	client: Arc<Client>,
36	create_inherent_data_providers: CIDP,
37	_marker: PhantomData<Block>,
38}
39
40impl<Client, Block, CIDP> Verifier<Client, Block, CIDP> {
41	/// Create a new instance.
42	pub fn new(client: Arc<Client>, create_inherent_data_providers: CIDP) -> Self {
43		Self { client, create_inherent_data_providers, _marker: PhantomData }
44	}
45}
46
47#[async_trait::async_trait]
48impl<Client, Block, CIDP> VerifierT<Block> for Verifier<Client, Block, CIDP>
49where
50	Block: BlockT,
51	Client: ProvideRuntimeApi<Block> + Send + Sync,
52	<Client as ProvideRuntimeApi<Block>>::Api: BlockBuilderApi<Block>,
53	CIDP: CreateInherentDataProviders<Block, ()>,
54{
55	async fn verify(
56		&self,
57		mut block_params: BlockImportParams<Block>,
58	) -> Result<BlockImportParams<Block>, String> {
59		block_params.fork_choice = Some(sc_consensus::ForkChoiceStrategy::Custom(
60			block_params.origin == sp_consensus::BlockOrigin::NetworkInitialSync,
61		));
62
63		// Skip checks that include execution, if being told so, or when importing only state.
64		//
65		// This is done for example when gap syncing and it is expected that the block after the gap
66		// was checked/chosen properly, e.g. by warp syncing to this block using a finality proof.
67		if block_params.state_action.skip_execution_checks() || block_params.with_state() {
68			return Ok(block_params)
69		}
70
71		if let Some(inner_body) = block_params.body.take() {
72			let inherent_data_providers = self
73				.create_inherent_data_providers
74				.create_inherent_data_providers(*block_params.header.parent_hash(), ())
75				.await
76				.map_err(|e| e.to_string())?;
77
78			let block = Block::new(block_params.header.clone(), inner_body);
79			sp_block_builder::check_inherents(
80				self.client.clone(),
81				*block.header().parent_hash(),
82				block.clone(),
83				&inherent_data_providers,
84			)
85			.await
86			.map_err(|e| format!("Error checking block inherents {:?}", e))?;
87
88			let (_, inner_body) = block.deconstruct();
89			block_params.body = Some(inner_body);
90		}
91
92		block_params.post_hash = Some(block_params.header.hash());
93		Ok(block_params)
94	}
95}
96
97/// Start an import queue for a Cumulus collator that does not uses any special authoring logic.
98pub fn import_queue<Client, Block: BlockT, I, CIDP>(
99	client: Arc<Client>,
100	block_import: I,
101	create_inherent_data_providers: CIDP,
102	spawner: &impl sp_core::traits::SpawnEssentialNamed,
103	registry: Option<&prometheus_endpoint::Registry>,
104) -> ClientResult<BasicQueue<Block>>
105where
106	I: BlockImport<Block, Error = ConsensusError>
107		+ ParachainBlockImportMarker
108		+ Send
109		+ Sync
110		+ 'static,
111	Client: ProvideRuntimeApi<Block> + Send + Sync + 'static,
112	<Client as ProvideRuntimeApi<Block>>::Api: BlockBuilderApi<Block>,
113	CIDP: CreateInherentDataProviders<Block, ()> + 'static,
114{
115	let verifier = Verifier::new(client, create_inherent_data_providers);
116
117	Ok(BasicQueue::new(verifier, Box::new(block_import), None, spawner, registry))
118}