diff --git a/Cargo.lock b/Cargo.lock
index cb4e085218e52..3de3363d19f6c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3311,6 +3311,7 @@ dependencies = [
"cumulus-relay-chain-interface",
"futures",
"parity-scale-codec",
+ "parking_lot 0.12.1",
"polkadot-node-primitives",
"polkadot-node-subsystem",
"polkadot-overseer",
@@ -14689,6 +14690,7 @@ dependencies = [
name = "sc-consensus"
version = "0.10.0-dev"
dependencies = [
+ "async-lock",
"async-trait",
"futures",
"futures-timer",
@@ -14708,6 +14710,7 @@ dependencies = [
"sp-test-primitives",
"substrate-prometheus-endpoint",
"thiserror",
+ "tokio",
]
[[package]]
diff --git a/cumulus/client/consensus/aura/Cargo.toml b/cumulus/client/consensus/aura/Cargo.toml
index 8239a498746e3..55482206c0d7f 100644
--- a/cumulus/client/consensus/aura/Cargo.toml
+++ b/cumulus/client/consensus/aura/Cargo.toml
@@ -9,6 +9,7 @@ edition.workspace = true
async-trait = "0.1.73"
codec = { package = "parity-scale-codec", version = "3.0.0", features = [ "derive" ] }
futures = "0.3.28"
+parking_lot = "0.12.1"
tracing = "0.1.37"
schnellru = "0.2.1"
diff --git a/cumulus/client/consensus/aura/src/equivocation_import_queue.rs b/cumulus/client/consensus/aura/src/equivocation_import_queue.rs
index 5cd65ed5546ba..38ceec30b57d8 100644
--- a/cumulus/client/consensus/aura/src/equivocation_import_queue.rs
+++ b/cumulus/client/consensus/aura/src/equivocation_import_queue.rs
@@ -21,11 +21,12 @@
/// should be thrown out and which ones should be kept.
use codec::Codec;
use cumulus_client_consensus_common::ParachainBlockImportMarker;
+use parking_lot::Mutex;
use schnellru::{ByLength, LruMap};
use sc_consensus::{
import_queue::{BasicQueue, Verifier as VerifierT},
- BlockImport, BlockImportParams, ForkChoiceStrategy,
+ BlockImport, BlockImportParams, ForkChoiceStrategy, SharedBlockImport,
};
use sc_consensus_aura::standalone as aura_internal;
use sc_telemetry::{telemetry, TelemetryHandle, CONSENSUS_DEBUG, CONSENSUS_TRACE};
@@ -71,7 +72,7 @@ struct Verifier
{
client: Arc,
create_inherent_data_providers: CIDP,
slot_duration: SlotDuration,
- defender: NaiveEquivocationDefender,
+ defender: Mutex,
telemetry: Option,
_phantom: std::marker::PhantomData (Block, P)>,
}
@@ -89,7 +90,7 @@ where
CIDP: CreateInherentDataProviders,
{
async fn verify(
- &mut self,
+ &self,
mut block_params: BlockImportParams,
) -> Result, String> {
// Skip checks that include execution, if being told so, or when importing only state.
@@ -132,7 +133,7 @@ where
block_params.post_hash = Some(post_hash);
// Check for and reject egregious amounts of equivocations.
- if self.defender.insert_and_check(slot) {
+ if self.defender.lock().insert_and_check(slot) {
return Err(format!(
"Rejecting block {:?} due to excessive equivocations at slot",
post_hash,
@@ -239,11 +240,11 @@ where
let verifier = Verifier:: {
client,
create_inherent_data_providers,
- defender: NaiveEquivocationDefender::default(),
+ defender: Mutex::new(NaiveEquivocationDefender::default()),
slot_duration,
telemetry,
_phantom: std::marker::PhantomData,
};
- BasicQueue::new(verifier, Box::new(block_import), None, spawner, registry)
+ BasicQueue::new(verifier, SharedBlockImport::new(block_import), None, spawner, registry)
}
diff --git a/cumulus/client/consensus/common/src/import_queue.rs b/cumulus/client/consensus/common/src/import_queue.rs
index 311a2b7ad8cfd..e815353b77bb0 100644
--- a/cumulus/client/consensus/common/src/import_queue.rs
+++ b/cumulus/client/consensus/common/src/import_queue.rs
@@ -38,6 +38,7 @@ use sp_runtime::traits::Block as BlockT;
use sc_consensus::{
block_import::{BlockImport, BlockImportParams},
import_queue::{BasicQueue, Verifier},
+ SharedBlockImport,
};
use crate::ParachainBlockImportMarker;
@@ -50,7 +51,7 @@ pub struct VerifyNothing;
#[async_trait::async_trait]
impl Verifier for VerifyNothing {
async fn verify(
- &mut self,
+ &self,
params: BlockImportParams,
) -> Result, String> {
Ok(params)
@@ -72,5 +73,5 @@ where
+ Sync
+ 'static,
{
- BasicQueue::new(VerifyNothing, Box::new(block_import), None, spawner, registry)
+ BasicQueue::new(VerifyNothing, SharedBlockImport::new(block_import), None, spawner, registry)
}
diff --git a/cumulus/client/consensus/common/src/lib.rs b/cumulus/client/consensus/common/src/lib.rs
index 08bceabb2bd4a..ea788fb219e0b 100644
--- a/cumulus/client/consensus/common/src/lib.rs
+++ b/cumulus/client/consensus/common/src/lib.rs
@@ -155,13 +155,13 @@ impl Clone for ParachainBlockImport {
impl BlockImport for ParachainBlockImport
where
Block: BlockT,
- BI: BlockImport + Send,
+ BI: BlockImport + Send + Sync,
BE: Backend,
{
type Error = BI::Error;
async fn check_block(
- &mut self,
+ &self,
block: sc_consensus::BlockCheckParams,
) -> Result {
self.inner.check_block(block).await
diff --git a/cumulus/client/consensus/relay-chain/src/import_queue.rs b/cumulus/client/consensus/relay-chain/src/import_queue.rs
index 9ee03b95904c6..16013ff2a1d2e 100644
--- a/cumulus/client/consensus/relay-chain/src/import_queue.rs
+++ b/cumulus/client/consensus/relay-chain/src/import_queue.rs
@@ -20,7 +20,7 @@ use cumulus_client_consensus_common::ParachainBlockImportMarker;
use sc_consensus::{
import_queue::{BasicQueue, Verifier as VerifierT},
- BlockImport, BlockImportParams,
+ BlockImport, BlockImportParams, SharedBlockImport,
};
use sp_api::ProvideRuntimeApi;
use sp_block_builder::BlockBuilder as BlockBuilderApi;
@@ -52,7 +52,7 @@ where
CIDP: CreateInherentDataProviders,
{
async fn verify(
- &mut self,
+ &self,
mut block_params: BlockImportParams,
) -> Result, String> {
// Skip checks that include execution, if being told so, or when importing only state.
@@ -125,5 +125,5 @@ where
{
let verifier = Verifier::new(client, create_inherent_data_providers);
- Ok(BasicQueue::new(verifier, Box::new(block_import), None, spawner, registry))
+ Ok(BasicQueue::new(verifier, SharedBlockImport::new(block_import), None, spawner, registry))
}
diff --git a/cumulus/client/pov-recovery/src/lib.rs b/cumulus/client/pov-recovery/src/lib.rs
index b050bc66799c7..130828a148dd3 100644
--- a/cumulus/client/pov-recovery/src/lib.rs
+++ b/cumulus/client/pov-recovery/src/lib.rs
@@ -453,7 +453,7 @@ where
/// Import the given `block`.
///
- /// This will also recursivley drain `waiting_for_parent` and import them as well.
+ /// This will also recursively drain `waiting_for_parent` and import them as well.
async fn import_block(&mut self, block: Block) {
let mut blocks = VecDeque::new();
diff --git a/cumulus/polkadot-parachain/src/service.rs b/cumulus/polkadot-parachain/src/service.rs
index f7b053b4b6a9d..cef6f6f32041a 100644
--- a/cumulus/polkadot-parachain/src/service.rs
+++ b/cumulus/polkadot-parachain/src/service.rs
@@ -46,7 +46,7 @@ use cumulus_client_consensus_relay_chain::Verifier as RelayChainVerifier;
use futures::lock::Mutex;
use sc_consensus::{
import_queue::{BasicQueue, Verifier as VerifierT},
- BlockImportParams, ImportQueue,
+ BlockImportParams, ImportQueue, SharedBlockImport,
};
use sc_executor::{HeapAllocStrategy, WasmExecutor, DEFAULT_HEAP_ALLOC_STRATEGY};
use sc_network::{config::FullNetworkConfiguration, NetworkBlock};
@@ -1022,7 +1022,7 @@ where
struct Verifier {
client: Arc,
- aura_verifier: BuildOnAccess>>,
+ aura_verifier: Mutex>>>,
relay_chain_verifier: Box>,
_phantom: PhantomData,
}
@@ -1035,7 +1035,7 @@ where
AuraId: Send + Sync + Codec,
{
async fn verify(
- &mut self,
+ &self,
block_import: BlockImportParams,
) -> Result, String> {
if self
@@ -1044,7 +1044,7 @@ where
.has_api::>(*block_import.header.parent_hash())
.unwrap_or(false)
{
- self.aura_verifier.get_mut().verify(block_import).await
+ self.aura_verifier.lock().await.get_mut().verify(block_import).await
} else {
self.relay_chain_verifier.verify(block_import).await
}
@@ -1104,14 +1104,14 @@ where
let verifier = Verifier {
client,
relay_chain_verifier,
- aura_verifier: BuildOnAccess::Uninitialized(Some(Box::new(aura_verifier))),
+ aura_verifier: Mutex::new(BuildOnAccess::Uninitialized(Some(Box::new(aura_verifier)))),
_phantom: PhantomData,
};
let registry = config.prometheus_registry();
let spawner = task_manager.spawn_essential_handle();
- Ok(BasicQueue::new(verifier, Box::new(block_import), None, &spawner, registry))
+ Ok(BasicQueue::new(verifier, SharedBlockImport::new(block_import), None, &spawner, registry))
}
/// Start an aura powered parachain node. Asset Hub and Collectives use this.
diff --git a/substrate/client/consensus/aura/src/import_queue.rs b/substrate/client/consensus/aura/src/import_queue.rs
index a8777ef8788cc..1239621015f96 100644
--- a/substrate/client/consensus/aura/src/import_queue.rs
+++ b/substrate/client/consensus/aura/src/import_queue.rs
@@ -29,6 +29,7 @@ use sc_client_api::{backend::AuxStore, BlockOf, UsageProvider};
use sc_consensus::{
block_import::{BlockImport, BlockImportParams, ForkChoiceStrategy},
import_queue::{BasicQueue, BoxJustificationImport, DefaultImportQueue, Verifier},
+ SharedBlockImport,
};
use sc_consensus_slots::{check_equivocation, CheckedHeader, InherentDataProviderExt};
use sc_telemetry::{telemetry, TelemetryHandle, CONSENSUS_DEBUG, CONSENSUS_TRACE};
@@ -174,7 +175,7 @@ where
CIDP::InherentDataProviders: InherentDataProviderExt + Send + Sync,
{
async fn verify(
- &mut self,
+ &self,
mut block: BlockImportParams,
) -> Result, String> {
// Skip checks that include execution, if being told so or when importing only state.
@@ -376,7 +377,13 @@ where
compatibility_mode,
});
- Ok(BasicQueue::new(verifier, Box::new(block_import), justification_import, spawner, registry))
+ Ok(BasicQueue::new(
+ verifier,
+ SharedBlockImport::new(block_import),
+ justification_import,
+ spawner,
+ registry,
+ ))
}
/// Parameters of [`build_verifier`].
diff --git a/substrate/client/consensus/babe/src/lib.rs b/substrate/client/consensus/babe/src/lib.rs
index 90b7523ec18bb..b80fe72a592c7 100644
--- a/substrate/client/consensus/babe/src/lib.rs
+++ b/substrate/client/consensus/babe/src/lib.rs
@@ -97,6 +97,7 @@ use sc_consensus::{
StateAction,
},
import_queue::{BasicQueue, BoxJustificationImport, DefaultImportQueue, Verifier},
+ SharedBlockImport,
};
use sc_consensus_epochs::{
descendent_query, Epoch as EpochT, EpochChangesFor, SharedEpochChanges, ViableEpochDescriptor,
@@ -1130,7 +1131,7 @@ where
CIDP::InherentDataProviders: InherentDataProviderExt + Send + Sync,
{
async fn verify(
- &mut self,
+ &self,
mut block: BlockImportParams,
) -> Result, String> {
trace!(
@@ -1683,7 +1684,7 @@ where
}
async fn check_block(
- &mut self,
+ &self,
block: BlockCheckParams,
) -> Result {
self.inner.check_block(block).await.map_err(Into::into)
@@ -1856,7 +1857,13 @@ where
spawner.spawn_essential("babe-worker", Some("babe"), answer_requests.boxed());
Ok((
- BasicQueue::new(verifier, Box::new(block_import), justification_import, spawner, registry),
+ BasicQueue::new(
+ verifier,
+ SharedBlockImport::new(block_import),
+ justification_import,
+ spawner,
+ registry,
+ ),
BabeWorkerHandle(worker_tx),
))
}
diff --git a/substrate/client/consensus/babe/src/tests.rs b/substrate/client/consensus/babe/src/tests.rs
index b3843f8acfa0a..0ce7209cf754e 100644
--- a/substrate/client/consensus/babe/src/tests.rs
+++ b/substrate/client/consensus/babe/src/tests.rs
@@ -22,7 +22,7 @@ use super::*;
use authorship::claim_slot;
use sc_block_builder::{BlockBuilder, BlockBuilderProvider};
use sc_client_api::{BlockchainEvents, Finalizer};
-use sc_consensus::{BoxBlockImport, BoxJustificationImport};
+use sc_consensus::{BoxJustificationImport, SharedBlockImport};
use sc_consensus_epochs::{EpochIdentifier, EpochIdentifierPosition};
use sc_consensus_slots::BackoffAuthoringOnFinalizedHeadLagging;
use sc_network_test::{Block as TestBlock, *};
@@ -138,11 +138,11 @@ thread_local! {
pub struct PanickingBlockImport(B);
#[async_trait::async_trait]
-impl> BlockImport for PanickingBlockImport
+impl BlockImport for PanickingBlockImport
where
- B: Send,
+ BI: BlockImport + Send + Sync,
{
- type Error = B::Error;
+ type Error = BI::Error;
async fn import_block(
&mut self,
@@ -152,7 +152,7 @@ where
}
async fn check_block(
- &mut self,
+ &self,
block: BlockCheckParams,
) -> Result {
Ok(self.0.check_block(block).await.expect("checking block failed"))
@@ -193,7 +193,7 @@ impl Verifier for TestVerifier {
/// new set of validators to import. If not, err with an Error-Message
/// presented to the User in the logs.
async fn verify(
- &mut self,
+ &self,
mut block: BlockImportParams,
) -> Result, String> {
// apply post-sealing mutations (i.e. stripping seal, if desired).
@@ -204,7 +204,7 @@ impl Verifier for TestVerifier {
pub struct PeerData {
link: BabeLink,
- block_import: Mutex