Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit 832a1c0

Browse files
committed
set slot and timestamp based on relay parent, prepare for find-parent
1 parent db7f9a5 commit 832a1c0

File tree

4 files changed

+126
-52
lines changed

4 files changed

+126
-52
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

client/consensus/aura/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ tracing = "0.1.37"
1515
sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
1616
sc-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" }
1717
sc-consensus-aura = { git = "https://github.com/paritytech/substrate", branch = "master" }
18+
sc-consensus-babe = { git = "https://github.com/paritytech/substrate", branch = "master" }
1819
sc-consensus-slots = { git = "https://github.com/paritytech/substrate", branch = "master" }
1920
sc-telemetry = { git = "https://github.com/paritytech/substrate", branch = "master" }
2021
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" }

client/consensus/aura/src/unstable_reimpl.rs

Lines changed: 123 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ use cumulus_relay_chain_interface::RelayChainInterface;
3434

3535
use polkadot_node_primitives::{CollationResult, MaybeCompressedPoV};
3636
use polkadot_overseer::Handle as OverseerHandle;
37-
use polkadot_primitives::{CollatorPair, Id as ParaId};
37+
use polkadot_primitives::{Block as PBlock, CollatorPair, Header as PHeader, Id as ParaId};
3838

3939
use futures::prelude::*;
4040
use sc_client_api::{backend::AuxStore, BlockBackend, BlockOf};
@@ -58,6 +58,7 @@ use sp_runtime::{
5858
traits::{Block as BlockT, HashFor, Header as HeaderT, Member},
5959
};
6060
use sp_state_machine::StorageChanges;
61+
use sp_timestamp::Timestamp;
6162
use std::{convert::TryFrom, error::Error, fmt::Debug, hash::Hash, sync::Arc, time::Duration};
6263

6364
/// Parameters for [`run_bare_relay_driven`].
@@ -72,10 +73,57 @@ pub struct Params<BI, CIDP, Client, RClient, SO, Proposer, CS> {
7273
pub para_id: ParaId,
7374
pub overseer_handle: OverseerHandle,
7475
pub slot_duration: SlotDuration,
76+
pub relay_chain_slot_duration: SlotDuration,
7577
pub proposer: Proposer,
7678
pub collator_service: CS,
7779
}
7880

81+
/// Run async-backing-friendly Aura.
82+
pub async fn run_async_backing_driven<Block, P, BI, CIDP, Client, RClient, SO, Proposer, CS>(
83+
params: Params<BI, CIDP, Client, RClient, SO, Proposer, CS>,
84+
) where
85+
Block: BlockT,
86+
Client: ProvideRuntimeApi<Block>
87+
+ BlockOf
88+
+ AuxStore
89+
+ HeaderBackend<Block>
90+
+ BlockBackend<Block>
91+
+ Send
92+
+ Sync
93+
+ 'static,
94+
Client::Api: AuraApi<Block, P::Public> + CollectCollationInfo<Block>,
95+
RClient: RelayChainInterface,
96+
CIDP: CreateInherentDataProviders<Block, ()> + 'static,
97+
BI: BlockImport<Block> + ParachainBlockImportMarker + Send + Sync + 'static,
98+
SO: SyncOracle + Send + Sync + Clone + 'static,
99+
Proposer: ProposerInterface<Block, Transaction = BI::Transaction>,
100+
Proposer::Transaction: Sync,
101+
CS: CollatorServiceInterface<Block>,
102+
P: Pair + Send + Sync,
103+
P::Public: AppPublic + Hash + Member + Encode + Decode,
104+
P::Signature: TryFrom<Vec<u8>> + Hash + Member + Encode + Decode,
105+
{
106+
let mut proposer = params.proposer;
107+
let mut block_import = params.block_import;
108+
109+
let mut import_notifications = match params.relay_client.import_notification_stream().await {
110+
Ok(s) => s,
111+
Err(err) => {
112+
tracing::error!(
113+
target: crate::LOG_TARGET,
114+
?err,
115+
"Failed to initialize consensus: no relay chain import notification stream"
116+
);
117+
118+
return
119+
},
120+
};
121+
122+
while let Some(relay_parent_header) = import_notifications.next().await {
123+
let relay_parent = relay_parent_header.hash();
124+
}
125+
}
126+
79127
/// Run bare Aura consensus as a relay-chain-driven collator.
80128
pub async fn run_bare_relay_driven<Block, P, BI, CIDP, Client, RClient, SO, Proposer, CS>(
81129
params: Params<BI, CIDP, Client, RClient, SO, Proposer, CS>,
@@ -120,23 +168,38 @@ pub async fn run_bare_relay_driven<Block, P, BI, CIDP, Client, RClient, SO, Prop
120168
}};
121169
}
122170

171+
macro_rules! try_request {
172+
($x:expr) => {{
173+
match $x {
174+
Ok(x) => x,
175+
Err(e) => reject_with_error!(e),
176+
}
177+
}};
178+
}
179+
123180
let validation_data = request.persisted_validation_data();
124181

125-
let parent_header = match Block::Header::decode(&mut &validation_data.parent_head.0[..]) {
126-
Ok(x) => x,
127-
Err(e) => reject_with_error!(e),
128-
};
182+
let parent_header =
183+
try_request!(Block::Header::decode(&mut &validation_data.parent_head.0[..]));
129184

130185
let parent_hash = parent_header.hash();
131186

132187
if !params.collator_service.check_block_status(parent_hash, &parent_header) {
133188
continue
134189
}
135190

191+
let relay_parent_header = match params.relay_client.header(*request.relay_parent()).await {
192+
Err(e) => reject_with_error!(e),
193+
Ok(None) => continue, // sanity: would be inconsistent to get `None` here
194+
Ok(Some(h)) => h,
195+
};
196+
136197
let claim = match claim_slot::<_, _, P>(
137198
&*params.para_client,
138199
parent_hash,
200+
&relay_parent_header,
139201
params.slot_duration,
202+
params.relay_chain_slot_duration,
140203
&params.keystore,
141204
)
142205
.await
@@ -146,51 +209,45 @@ pub async fn run_bare_relay_driven<Block, P, BI, CIDP, Client, RClient, SO, Prop
146209
Err(e) => reject_with_error!(e),
147210
};
148211

149-
let (parachain_inherent_data, other_inherent_data) = match create_inherent_data(
150-
*request.relay_parent(),
151-
&validation_data,
152-
parent_hash,
153-
params.para_id,
154-
&params.relay_client,
155-
&params.create_inherent_data_providers,
156-
)
157-
.await
158-
{
159-
Ok(x) => x,
160-
Err(e) => reject_with_error!(e),
161-
};
162-
163-
let proposal = match proposer
164-
.propose(
165-
&parent_header,
166-
&parachain_inherent_data,
167-
other_inherent_data,
168-
Digest { logs: vec![claim.pre_digest] },
169-
// TODO [https://github.com/paritytech/cumulus/issues/2439]
170-
// We should call out to a pluggable interface that provides
171-
// the proposal duration.
172-
Duration::from_millis(500),
173-
// Set the block limit to 50% of the maximum PoV size.
174-
//
175-
// TODO: If we got benchmarking that includes the proof size,
176-
// we should be able to use the maximum pov size.
177-
Some((validation_data.max_pov_size / 2) as usize),
212+
let (parachain_inherent_data, other_inherent_data) = try_request!(
213+
create_inherent_data(
214+
*request.relay_parent(),
215+
&validation_data,
216+
parent_hash,
217+
params.para_id,
218+
claim.timestamp,
219+
&params.relay_client,
220+
&params.create_inherent_data_providers,
178221
)
179222
.await
180-
{
181-
Ok(p) => p,
182-
Err(e) => reject_with_error!(e),
183-
};
223+
);
224+
225+
let proposal = try_request!(
226+
proposer
227+
.propose(
228+
&parent_header,
229+
&parachain_inherent_data,
230+
other_inherent_data,
231+
Digest { logs: vec![claim.pre_digest] },
232+
// TODO [https://github.com/paritytech/cumulus/issues/2439]
233+
// We should call out to a pluggable interface that provides
234+
// the proposal duration.
235+
Duration::from_millis(500),
236+
// Set the block limit to 50% of the maximum PoV size.
237+
//
238+
// TODO: If we got benchmarking that includes the proof size,
239+
// we should be able to use the maximum pov size.
240+
Some((validation_data.max_pov_size / 2) as usize),
241+
)
242+
.await
243+
);
184244

185-
let sealed_importable = match seal::<_, _, P>(
245+
let sealed_importable = try_request!(seal::<_, _, P>(
186246
proposal.block,
187247
proposal.storage_changes,
188248
&claim.author_pub,
189249
&params.keystore,
190-
) {
191-
Ok(s) => s,
192-
Err(e) => reject_with_error!(e),
193-
};
250+
));
194251

195252
let post_hash = sealed_importable.post_hash();
196253
let block = Block::new(
@@ -202,9 +259,7 @@ pub async fn run_bare_relay_driven<Block, P, BI, CIDP, Client, RClient, SO, Prop
202259
.clone(),
203260
);
204261

205-
if let Err(e) = block_import.import_block(sealed_importable).await {
206-
reject_with_error!(e);
207-
}
262+
try_request!(block_import.import_block(sealed_importable).await);
208263

209264
let response = if let Some((collation, b)) = params.collator_service.build_collation(
210265
&parent_header,
@@ -246,12 +301,15 @@ fn slot_now(slot_duration: SlotDuration) -> Slot {
246301
struct SlotClaim<Pub> {
247302
author_pub: Pub,
248303
pre_digest: sp_runtime::DigestItem,
304+
timestamp: Timestamp,
249305
}
250306

251307
async fn claim_slot<B, C, P>(
252308
client: &C,
253309
parent_hash: B::Hash,
310+
relay_parent_header: &PHeader,
254311
slot_duration: SlotDuration,
312+
relay_chain_slot_duration: SlotDuration,
255313
keystore: &KeystorePtr,
256314
) -> Result<Option<SlotClaim<P::Public>>, Box<dyn Error>>
257315
where
@@ -265,8 +323,18 @@ where
265323
// load authorities
266324
let authorities = client.runtime_api().authorities(parent_hash).map_err(Box::new)?;
267325

268-
// Determine the current slot.
269-
let slot_now = slot_now(slot_duration);
326+
// Determine the current slot and timestamp based on the relay-parent's.
327+
let (slot_now, timestamp) =
328+
match sc_consensus_babe::find_pre_digest::<PBlock>(relay_parent_header) {
329+
Ok(babe_pre_digest) => {
330+
let t =
331+
Timestamp::new(relay_chain_slot_duration.as_millis() * *babe_pre_digest.slot());
332+
let slot = Slot::from_timestamp(t, slot_duration);
333+
334+
(slot, t)
335+
},
336+
Err(_) => return Ok(None),
337+
};
270338

271339
// Try to claim the slot locally.
272340
let author_pub = {
@@ -280,14 +348,17 @@ where
280348
// Produce the pre-digest.
281349
let pre_digest = aura_internal::pre_digest::<P>(slot_now);
282350

283-
Ok(Some(SlotClaim { author_pub, pre_digest }))
351+
Ok(Some(SlotClaim { author_pub, pre_digest, timestamp }))
284352
}
285353

354+
// This explicitly creates the inherent data for parachains, as well as overriding the
355+
// timestamp based on the slot number.
286356
async fn create_inherent_data<B: BlockT>(
287357
relay_parent: PHash,
288358
validation_data: &PersistedValidationData,
289359
parent_hash: B::Hash,
290360
para_id: ParaId,
361+
timestamp: Timestamp,
291362
relay_chain_interface: &impl RelayChainInterface,
292363
create_inherent_data_providers: &impl CreateInherentDataProviders<B, ()>,
293364
) -> Result<(ParachainInherentData, InherentData), Box<dyn Error>> {
@@ -305,14 +376,16 @@ async fn create_inherent_data<B: BlockT>(
305376
return Err(format!("Could not create paras inherent data at {:?}", relay_parent).into()),
306377
};
307378

308-
let other_inherent_data = create_inherent_data_providers
379+
let mut other_inherent_data = create_inherent_data_providers
309380
.create_inherent_data_providers(parent_hash, ())
310381
.map_err(|e| e as Box<dyn Error>)
311382
.await?
312383
.create_inherent_data()
313384
.await
314385
.map_err(Box::new)?;
315386

387+
other_inherent_data.replace_data(sp_timestamp::INHERENT_IDENTIFIER, &timestamp);
388+
316389
Ok((paras_inherent_data, other_inherent_data))
317390
}
318391

client/consensus/common/src/tests.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,7 @@ impl RelayChainInterface for Relaychain {
185185
unimplemented!("Not needed for test")
186186
}
187187

188-
async fn wait_for_block(&self, _: PHash) -> RelayChainResult<()> {
189-
}
188+
async fn wait_for_block(&self, _: PHash) -> RelayChainResult<()> {}
190189

191190
async fn new_best_notification_stream(
192191
&self,

0 commit comments

Comments
 (0)