Skip to content

Commit aa68ea5

Browse files
authored
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: #3282
1 parent 96ebb30 commit aa68ea5

File tree

4 files changed

+60
-2
lines changed

4 files changed

+60
-2
lines changed

cumulus/client/consensus/aura/src/collator.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ where
258258
pub struct SlotClaim<Pub> {
259259
author_pub: Pub,
260260
pre_digest: DigestItem,
261+
slot: Slot,
261262
timestamp: Timestamp,
262263
}
263264

@@ -272,7 +273,7 @@ impl<Pub> SlotClaim<Pub> {
272273
P::Public: Codec,
273274
P::Signature: Codec,
274275
{
275-
SlotClaim { author_pub, timestamp, pre_digest: aura_internal::pre_digest::<P>(slot) }
276+
SlotClaim { author_pub, timestamp, pre_digest: aura_internal::pre_digest::<P>(slot), slot }
276277
}
277278

278279
/// Get the author's public key.
@@ -285,6 +286,11 @@ impl<Pub> SlotClaim<Pub> {
285286
&self.pre_digest
286287
}
287288

289+
/// Get the slot assigned to this claim.
290+
pub fn slot(&self) -> Slot {
291+
self.slot
292+
}
293+
288294
/// Get the timestamp corresponding to the relay-chain slot this claim was
289295
/// generated against.
290296
pub fn timestamp(&self) -> Timestamp {

cumulus/client/consensus/aura/src/collators/basic.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ where
141141
collator_util::Collator::<Block, P, _, _, _, _, _>::new(params)
142142
};
143143

144+
let mut last_processed_slot = 0;
145+
144146
while let Some(request) = collation_requests.next().await {
145147
macro_rules! reject_with_error {
146148
($err:expr) => {{
@@ -192,6 +194,18 @@ where
192194
Err(e) => reject_with_error!(e),
193195
};
194196

197+
// With async backing this function will be called every relay chain block.
198+
//
199+
// Most parachains currently run with 12 seconds slots and thus, they would try to
200+
// produce multiple blocks per slot which very likely would fail on chain. Thus, we have
201+
// this "hack" to only produce on block per slot.
202+
//
203+
// With https://github.com/paritytech/polkadot-sdk/issues/3168 this implementation will be
204+
// obsolete and also the underlying issue will be fixed.
205+
if last_processed_slot >= *claim.slot() {
206+
continue
207+
}
208+
195209
let (parachain_inherent_data, other_inherent_data) = try_request!(
196210
collator
197211
.create_inherent_data(
@@ -228,6 +242,8 @@ where
228242
request.complete(None);
229243
tracing::debug!(target: crate::LOG_TARGET, "No block proposal");
230244
}
245+
246+
last_processed_slot = *claim.slot();
231247
}
232248
}
233249
}

cumulus/client/consensus/aura/src/lib.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,14 @@ use sp_core::crypto::Pair;
4242
use sp_inherents::CreateInherentDataProviders;
4343
use sp_keystore::KeystorePtr;
4444
use sp_runtime::traits::{Block as BlockT, Header as HeaderT, Member, NumberFor};
45-
use std::{convert::TryFrom, marker::PhantomData, sync::Arc};
45+
use std::{
46+
convert::TryFrom,
47+
marker::PhantomData,
48+
sync::{
49+
atomic::{AtomicU64, Ordering},
50+
Arc,
51+
},
52+
};
4653

4754
mod import_queue;
4855

@@ -61,6 +68,7 @@ pub struct AuraConsensus<B, CIDP, W> {
6168
create_inherent_data_providers: Arc<CIDP>,
6269
aura_worker: Arc<Mutex<W>>,
6370
slot_duration: SlotDuration,
71+
last_slot_processed: Arc<AtomicU64>,
6472
_phantom: PhantomData<B>,
6573
}
6674

@@ -70,6 +78,7 @@ impl<B, CIDP, W> Clone for AuraConsensus<B, CIDP, W> {
7078
create_inherent_data_providers: self.create_inherent_data_providers.clone(),
7179
aura_worker: self.aura_worker.clone(),
7280
slot_duration: self.slot_duration,
81+
last_slot_processed: self.last_slot_processed.clone(),
7382
_phantom: PhantomData,
7483
}
7584
}
@@ -156,6 +165,7 @@ where
156165
Box::new(AuraConsensus {
157166
create_inherent_data_providers: Arc::new(create_inherent_data_providers),
158167
aura_worker: Arc::new(Mutex::new(worker)),
168+
last_slot_processed: Default::default(),
159169
slot_duration,
160170
_phantom: PhantomData,
161171
})
@@ -221,6 +231,18 @@ where
221231
Some((validation_data.max_pov_size / 2) as usize),
222232
);
223233

234+
// With async backing this function will be called every relay chain block.
235+
//
236+
// Most parachains currently run with 12 seconds slots and thus, they would try to produce
237+
// multiple blocks per slot which very likely would fail on chain. Thus, we have this "hack"
238+
// to only produce on block per slot.
239+
//
240+
// With https://github.com/paritytech/polkadot-sdk/issues/3168 this implementation will be
241+
// obsolete and also the underlying issue will be fixed.
242+
if self.last_slot_processed.fetch_max(*info.slot, Ordering::Relaxed) >= *info.slot {
243+
return None
244+
}
245+
224246
let res = self.aura_worker.lock().await.on_slot(info).await?;
225247

226248
Some(ParachainCandidate { block: res.block, proof: res.storage_proof })

prdoc/pr_3308.prdoc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
title: Parachains-Aura: Only produce once per slot
2+
3+
doc:
4+
- audience: Node Dev
5+
description: |
6+
With the introduction of asynchronous backing the relay chain allows parachain to include blocks every 6 seconds.
7+
The Cumulus Aura implementations, besides the lookahead collator, are building blocks when there is a free slot for
8+
the parachain in the relay chain. Most parachains are still running with a 12s slot duration and not allowing
9+
to build multiple blocks per slot. But, the block production logic will be triggered every 6s, resulting in error
10+
logs like: "no space left for the block in the unincluded segment". This is solved by ensuring that we don't build
11+
multiple blocks per slot.
12+
13+
crates:
14+
- name: "cumulus-client-consensus-aura"

0 commit comments

Comments
 (0)