Parachains-Aura: Only produce once per slot (#3308)

Given how the block production is driven for Parachains right now, with
the enabling of async backing we would produce two blocks per slot.
Until we have a proper collator implementation, the "hack" is to prevent
the production of multiple blocks per slot.


Closes: https://github.com/paritytech/polkadot-sdk/issues/3282
This commit is contained in:
Bastian Köcher
2024-02-13 21:07:51 +01:00
committed by GitHub
parent 96ebb305ed
commit aa68ea58f3
4 changed files with 60 additions and 2 deletions
+23 -1
View File
@@ -42,7 +42,14 @@ use sp_core::crypto::Pair;
use sp_inherents::CreateInherentDataProviders;
use sp_keystore::KeystorePtr;
use sp_runtime::traits::{Block as BlockT, Header as HeaderT, Member, NumberFor};
use std::{convert::TryFrom, marker::PhantomData, sync::Arc};
use std::{
convert::TryFrom,
marker::PhantomData,
sync::{
atomic::{AtomicU64, Ordering},
Arc,
},
};
mod import_queue;
@@ -61,6 +68,7 @@ pub struct AuraConsensus<B, CIDP, W> {
create_inherent_data_providers: Arc<CIDP>,
aura_worker: Arc<Mutex<W>>,
slot_duration: SlotDuration,
last_slot_processed: Arc<AtomicU64>,
_phantom: PhantomData<B>,
}
@@ -70,6 +78,7 @@ impl<B, CIDP, W> Clone for AuraConsensus<B, CIDP, W> {
create_inherent_data_providers: self.create_inherent_data_providers.clone(),
aura_worker: self.aura_worker.clone(),
slot_duration: self.slot_duration,
last_slot_processed: self.last_slot_processed.clone(),
_phantom: PhantomData,
}
}
@@ -156,6 +165,7 @@ where
Box::new(AuraConsensus {
create_inherent_data_providers: Arc::new(create_inherent_data_providers),
aura_worker: Arc::new(Mutex::new(worker)),
last_slot_processed: Default::default(),
slot_duration,
_phantom: PhantomData,
})
@@ -221,6 +231,18 @@ where
Some((validation_data.max_pov_size / 2) as usize),
);
// With async backing this function will be called every relay chain block.
//
// Most parachains currently run with 12 seconds slots and thus, they would try to produce
// multiple blocks per slot which very likely would fail on chain. Thus, we have this "hack"
// to only produce on block per slot.
//
// With https://github.com/paritytech/polkadot-sdk/issues/3168 this implementation will be
// obsolete and also the underlying issue will be fixed.
if self.last_slot_processed.fetch_max(*info.slot, Ordering::Relaxed) >= *info.slot {
return None
}
let res = self.aura_worker.lock().await.on_slot(info).await?;
Some(ParachainCandidate { block: res.block, proof: res.storage_proof })