Rework inherent data client side (#8526)

* Lol

* Yeah

* Moare

* adaasda

* Convert AURA to new pallet macro

* AURA: Switch to `CurrentSlot` instead of `LastTimestamp`

This switches AURA to use `CurrentSlot` instead of `LastTimestamp`.

* Add missing file

* Update frame/aura/src/migrations.rs

Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>

* Remove the runtime side provide inherent code

* Use correct weight

* Add TODO

* Remove the Inherent from AURA

* 🤦

* Remove unused stuff

* Update primitives authorship

* Fix babe inherent data provider

* Fix consensus-uncles

* Fix BABE

* Do some further changes to authorship primitives... :D

* More work

* Make it compile the happy path

* Make it async!

* Take hash

* More stuff

* Hacks

* Revert "Hacks"

This reverts commit cfffad88668cfdebf632a59c4fbfada001ef8251.

* Fix

* Make `execute_block` return the final block header

* Move Aura digest stuff

* Make it possible to disable equivocation checking

* Fix fix fix

* Some refactorings

* Comment

* Fixes fixes fixes

* More cleanups

* Some love

* Better love

* Make slot duration being exposed as `Duration` to the outside

* Some slot info love

* Add `build_aura_worker` utility function

* Copy copy copy

* Some stuff

* Start fixing pow

* Fix pow

* Remove some bounds

* More work

* Make grandpa work

* Make slots use `async_trait`

* Introduce `SharedData`

* Add test and fix bugs

* Switch to `SharedData`

* Make grandpa tests working

* More Babe work

* Make grandpa work

* Introduce `SharedData`

* Add test and fix bugs

* Switch to `SharedData`

* Make grandpa tests working

* More Babe work

* Make it async

* Fix fix

* Use `async_trait` in sc-consensus-slots

This makes the code a little bit easier to read and also expresses that
there can always only be one call at a time to `on_slot`.

* Make grandpa tests compile

* More Babe tests work

* Fix network test

* Start fixing service test

* Finish service-test

* Fix sc-consensus-aura

* Fix fix fix

* More fixes

* Make everything compile *yeah*

* Make manual-seal compile

* More fixes

* Start fixing Aura

* Fix Aura tests

* Fix Babe tests

* Make everything compile

* Move code around and switch to async_trait

* Fix Babe

* Docs docs docs

* Move to FRAME

* Fix fix fix

* Make everything compile

* Last cleanups

* Fix integration test

* Change slot usage of the timestamp

* We really need to switch to `impl-trait-for-tuples`

* Update primitives/inherents/src/lib.rs

Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>

* Update primitives/inherents/src/lib.rs

Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>

* Update primitives/inherents/src/lib.rs

Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>

* Some extra logging

* Remove dbg!

* Update primitives/consensus/common/src/import_queue/basic_queue.rs

Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>

Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>
This commit is contained in:
Bastian Köcher
2021-05-03 16:39:25 +02:00
committed by GitHub
parent ef07c3be0d
commit 2675741a09
52 changed files with 1506 additions and 1178 deletions
+87 -114
View File
@@ -77,7 +77,7 @@ pub use sp_consensus::SyncOracle;
pub use sc_consensus_slots::SlotProportion;
use std::{
collections::HashMap, sync::Arc, u64, pin::Pin, borrow::Cow, convert::TryInto,
time::{Duration, Instant},
time::Duration,
};
use sp_consensus::{ImportResult, CanAuthorWith, import_queue::BoxJustificationImport};
use sp_core::crypto::Public;
@@ -89,7 +89,7 @@ use sp_runtime::{
};
use sp_api::{ProvideRuntimeApi, NumberFor};
use parking_lot::Mutex;
use sp_inherents::{InherentDataProviders, InherentData};
use sp_inherents::{CreateInherentDataProviders, InherentDataProvider, InherentData};
use sc_telemetry::{telemetry, TelemetryHandle, CONSENSUS_TRACE, CONSENSUS_DEBUG};
use sp_consensus::{
BlockImport, Environment, Proposer, BlockCheckParams,
@@ -97,7 +97,6 @@ use sp_consensus::{
SelectChain, SlotData, import_queue::{Verifier, BasicQueue, DefaultImportQueue, CacheKeyId},
};
use sp_consensus_babe::inherents::BabeInherentData;
use sp_timestamp::TimestampInherentData;
use sc_client_api::{
backend::AuxStore, BlockchainEvents, ProvideUncles,
};
@@ -110,8 +109,8 @@ use futures::prelude::*;
use log::{debug, info, log, trace, warn};
use prometheus_endpoint::Registry;
use sc_consensus_slots::{
SlotInfo, SlotCompatible, StorageChanges, CheckedHeader, check_equivocation,
BackoffAuthoringBlocksStrategy
SlotInfo, StorageChanges, CheckedHeader, check_equivocation,
BackoffAuthoringBlocksStrategy, InherentDataProviderExt,
};
use sc_consensus_epochs::{
descendent_query, SharedEpochChanges, EpochChangesFor, Epoch as EpochT, ViableEpochDescriptor,
@@ -270,15 +269,19 @@ pub enum Error<B: BlockT> {
/// Parent block has no associated weight
#[display(fmt = "Parent block of {} has no associated weight", _0)]
ParentBlockNoAssociatedWeight(B::Hash),
/// Check inherents error
#[display(fmt = "Checking inherents failed: {}", _0)]
/// Check Inherents error
CheckInherents(String),
CheckInherents(sp_inherents::Error),
/// Unhandled check inherents error
#[display(fmt = "Checking inherents unhandled error: {}", "String::from_utf8_lossy(_0)")]
CheckInherentsUnhandled(sp_inherents::InherentIdentifier),
/// Create inherents error.
#[display(fmt = "Creating inherents failed: {}", _0)]
CreateInherents(sp_inherents::Error),
/// Client error
Client(sp_blockchain::Error),
/// Runtime Api error.
RuntimeApi(sp_api::ApiError),
/// Runtime error
Runtime(sp_inherents::Error),
/// Fork tree error
ForkTree(Box<fork_tree::Error<sp_blockchain::Error>>),
}
@@ -360,7 +363,7 @@ impl std::ops::Deref for Config {
}
/// Parameters for BABE.
pub struct BabeParams<B: BlockT, C, E, I, SO, SC, CAW, BS> {
pub struct BabeParams<B: BlockT, C, E, I, SO, SC, CAW, BS, IDP> {
/// The keystore that manages the keys of the node.
pub keystore: SyncCryptoStorePtr,
@@ -381,8 +384,8 @@ pub struct BabeParams<B: BlockT, C, E, I, SO, SC, CAW, BS> {
/// A sync oracle
pub sync_oracle: SO,
/// Providers for inherent data.
pub inherent_data_providers: InherentDataProviders,
/// Something that can create the inherent data providers.
pub create_inherent_data_providers: IDP,
/// Force authoring of blocks even if we are offline
pub force_authoring: bool,
@@ -408,21 +411,21 @@ pub struct BabeParams<B: BlockT, C, E, I, SO, SC, CAW, BS> {
}
/// Start the babe worker.
pub fn start_babe<B, C, SC, E, I, SO, CAW, BS, Error>(BabeParams {
pub fn start_babe<B, C, SC, E, I, SO, CAW, BS, Error, IDP>(BabeParams {
keystore,
client,
select_chain,
env,
block_import,
sync_oracle,
inherent_data_providers,
create_inherent_data_providers,
force_authoring,
backoff_authoring_blocks,
babe_link,
can_author_with,
block_proposal_slot_portion,
telemetry,
}: BabeParams<B, C, E, I, SO, SC, CAW, BS>) -> Result<
}: BabeParams<B, C, E, I, SO, SC, CAW, BS, IDP>) -> Result<
BabeWorker<B>,
sp_consensus::Error,
> where
@@ -440,6 +443,8 @@ pub fn start_babe<B, C, SC, E, I, SO, CAW, BS, Error>(BabeParams {
SO: SyncOracle + Send + Sync + Clone + 'static,
CAW: CanAuthorWith<B> + Send + Sync + 'static,
BS: BackoffAuthoringBlocksStrategy<NumberFor<B>> + Send + 'static,
IDP: CreateInherentDataProviders<B, ()> + Send + Sync + 'static,
IDP::InherentDataProviders: InherentDataProviderExt + Send,
{
const HANDLE_BUFFER_SIZE: usize = 1024;
@@ -461,21 +466,13 @@ pub fn start_babe<B, C, SC, E, I, SO, CAW, BS, Error>(BabeParams {
telemetry,
};
register_babe_inherent_data_provider(&inherent_data_providers, config.slot_duration())?;
sc_consensus_uncles::register_uncles_inherent_data_provider(
client.clone(),
select_chain.clone(),
&inherent_data_providers,
)?;
info!(target: "babe", "👶 Starting BABE Authorship worker");
let inner = sc_consensus_slots::start_slot_worker(
config.0.clone(),
select_chain,
worker,
sync_oracle,
inherent_data_providers,
babe_link.time_source,
create_inherent_data_providers,
can_author_with,
);
@@ -813,23 +810,22 @@ where
fn proposing_remaining_duration(
&self,
parent_head: &B::Header,
slot_info: &SlotInfo,
slot_info: &SlotInfo<B>,
) -> std::time::Duration {
let max_proposing = slot_info.duration.mul_f32(self.block_proposal_slot_portion.get());
let slot_remaining = slot_info.ends_at
.checked_duration_since(Instant::now())
.checked_duration_since(std::time::Instant::now())
.unwrap_or_default();
let slot_remaining = std::cmp::min(slot_remaining, max_proposing);
// If parent is genesis block, we don't require any lenience factor.
if parent_head.number().is_zero() {
if slot_info.chain_head.number().is_zero() {
return slot_remaining
}
let parent_slot = match find_pre_digest::<B>(parent_head) {
let parent_slot = match find_pre_digest::<B>(&slot_info.chain_head) {
Err(_) => return slot_remaining,
Ok(d) => d.slot(),
};
@@ -913,27 +909,9 @@ fn find_next_config_digest<B: BlockT>(header: &B::Header)
Ok(config_digest)
}
#[derive(Default, Clone)]
struct TimeSource(Arc<Mutex<(Option<Duration>, Vec<(Instant, u64)>)>>);
impl SlotCompatible for TimeSource {
fn extract_timestamp_and_slot(
&self,
data: &InherentData,
) -> Result<(sp_timestamp::Timestamp, Slot, std::time::Duration), sp_consensus::Error> {
trace!(target: "babe", "extract timestamp");
data.timestamp_inherent_data()
.and_then(|t| data.babe_inherent_data().map(|a| (t, a)))
.map_err(Into::into)
.map_err(sp_consensus::Error::InherentData)
.map(|(x, y)| (x, y, self.0.lock().0.take().unwrap_or_default()))
}
}
/// State that must be shared between the import queue and the authoring logic.
#[derive(Clone)]
pub struct BabeLink<Block: BlockT> {
time_source: TimeSource,
epoch_changes: SharedEpochChanges<Block, Epoch>,
config: Config,
}
@@ -951,30 +929,31 @@ impl<Block: BlockT> BabeLink<Block> {
}
/// A verifier for Babe blocks.
pub struct BabeVerifier<Block: BlockT, Client, SelectChain, CAW> {
pub struct BabeVerifier<Block: BlockT, Client, SelectChain, CAW, CIDP> {
client: Arc<Client>,
select_chain: SelectChain,
inherent_data_providers: sp_inherents::InherentDataProviders,
create_inherent_data_providers: CIDP,
config: Config,
epoch_changes: SharedEpochChanges<Block, Epoch>,
time_source: TimeSource,
can_author_with: CAW,
telemetry: Option<TelemetryHandle>,
}
impl<Block, Client, SelectChain, CAW> BabeVerifier<Block, Client, SelectChain, CAW>
impl<Block, Client, SelectChain, CAW, CIDP> BabeVerifier<Block, Client, SelectChain, CAW, CIDP>
where
Block: BlockT,
Client: AuxStore + HeaderBackend<Block> + HeaderMetadata<Block> + ProvideRuntimeApi<Block>,
Client::Api: BlockBuilderApi<Block> + BabeApi<Block>,
SelectChain: sp_consensus::SelectChain<Block>,
CAW: CanAuthorWith<Block>,
CIDP: CreateInherentDataProviders<Block, ()>,
{
fn check_inherents(
async fn check_inherents(
&self,
block: Block,
block_id: BlockId<Block>,
inherent_data: InherentData,
create_inherent_data_providers: CIDP::InherentDataProviders,
) -> Result<(), Error<Block>> {
if let Err(e) = self.can_author_with.can_author_with(&block_id) {
debug!(
@@ -993,14 +972,15 @@ where
).map_err(Error::RuntimeApi)?;
if !inherent_res.ok() {
inherent_res
.into_errors()
.try_for_each(|(i, e)| {
Err(Error::CheckInherents(self.inherent_data_providers.error_to_string(&i, &e)))
})
} else {
Ok(())
for (i, e) in inherent_res.into_errors() {
match create_inherent_data_providers.try_handle_error(&i, &e).await {
Some(res) => res.map_err(|e| Error::CheckInherents(e))?,
None => return Err(Error::CheckInherentsUnhandled(i)),
}
}
}
Ok(())
}
fn check_and_report_equivocation(
@@ -1085,8 +1065,8 @@ where
}
#[async_trait::async_trait]
impl<Block, Client, SelectChain, CAW> Verifier<Block>
for BabeVerifier<Block, Client, SelectChain, CAW>
impl<Block, Client, SelectChain, CAW, CIDP> Verifier<Block>
for BabeVerifier<Block, Client, SelectChain, CAW, CIDP>
where
Block: BlockT,
Client: HeaderMetadata<Block, Error = sp_blockchain::Error> + HeaderBackend<Block> + ProvideRuntimeApi<Block>
@@ -1094,6 +1074,8 @@ where
Client::Api: BlockBuilderApi<Block> + BabeApi<Block>,
SelectChain: sp_consensus::SelectChain<Block>,
CAW: CanAuthorWith<Block> + Send + Sync,
CIDP: CreateInherentDataProviders<Block, ()> + Send + Sync,
CIDP::InherentDataProviders: InherentDataProviderExt + Send + Sync,
{
async fn verify(
&mut self,
@@ -1111,46 +1093,51 @@ where
body,
);
debug!(target: "babe", "We have {:?} logs in this header", header.digest().logs().len());
let mut inherent_data = self
.inherent_data_providers
.create_inherent_data()
.map_err(Error::<Block>::Runtime)?;
let (_, slot_now, _) = self.time_source.extract_timestamp_and_slot(&inherent_data)
.map_err(Error::<Block>::Extraction)?;
let hash = header.hash();
let parent_hash = *header.parent_hash();
debug!(target: "babe", "We have {:?} logs in this header", header.digest().logs().len());
let create_inherent_data_providers = self
.create_inherent_data_providers
.create_inherent_data_providers(parent_hash, ())
.await
.map_err(|e| Error::<Block>::Client(sp_consensus::Error::from(e).into()))?;
let slot_now = create_inherent_data_providers.slot();
let parent_header_metadata = self.client.header_metadata(parent_hash)
.map_err(Error::<Block>::FetchParentHeader)?;
let pre_digest = find_pre_digest::<Block>(&header)?;
let epoch_changes = self.epoch_changes.shared_data();
let epoch_descriptor = epoch_changes.epoch_descriptor_for_child_of(
descendent_query(&*self.client),
&parent_hash,
parent_header_metadata.number,
pre_digest.slot(),
)
let (check_header, epoch_descriptor) = {
let epoch_changes = self.epoch_changes.shared_data();
let epoch_descriptor = epoch_changes.epoch_descriptor_for_child_of(
descendent_query(&*self.client),
&parent_hash,
parent_header_metadata.number,
pre_digest.slot(),
)
.map_err(|e| Error::<Block>::ForkTree(Box::new(e)))?
.ok_or_else(|| Error::<Block>::FetchEpoch(parent_hash))?;
let viable_epoch = epoch_changes.viable_epoch(
&epoch_descriptor,
|slot| Epoch::genesis(&self.config, slot)
).ok_or_else(|| Error::<Block>::FetchEpoch(parent_hash))?;
let viable_epoch = epoch_changes.viable_epoch(
&epoch_descriptor,
|slot| Epoch::genesis(&self.config, slot)
).ok_or_else(|| Error::<Block>::FetchEpoch(parent_hash))?;
// We add one to the current slot to allow for some small drift.
// FIXME #1019 in the future, alter this queue to allow deferring of headers
let v_params = verification::VerificationParams {
header: header.clone(),
pre_digest: Some(pre_digest),
slot_now: slot_now + 1,
epoch: viable_epoch.as_ref(),
// We add one to the current slot to allow for some small drift.
// FIXME #1019 in the future, alter this queue to allow deferring of headers
let v_params = verification::VerificationParams {
header: header.clone(),
pre_digest: Some(pre_digest),
slot_now: slot_now + 1,
epoch: viable_epoch.as_ref(),
};
(verification::check_header::<Block>(v_params)?, epoch_descriptor)
};
match verification::check_header::<Block>(v_params)? {
match check_header {
CheckedHeader::Checked(pre_header, verified_info) => {
let babe_pre_digest = verified_info.pre_digest.as_babe_pre_digest()
.expect("check_header always returns a pre-digest digest item; qed");
@@ -1173,6 +1160,8 @@ where
// to check that the internally-set timestamp in the inherents
// actually matches the slot set in the seal.
if let Some(inner_body) = body.take() {
let mut inherent_data = create_inherent_data_providers.create_inherent_data()
.map_err(Error::<Block>::CreateInherents)?;
inherent_data.babe_replace_inherent_data(slot);
let block = Block::new(pre_header.clone(), inner_body);
@@ -1180,7 +1169,8 @@ where
block.clone(),
BlockId::Hash(parent_hash),
inherent_data,
)?;
create_inherent_data_providers,
).await?;
let (_, inner_body) = block.deconstruct();
body = Some(inner_body);
@@ -1220,22 +1210,6 @@ where
}
}
/// Register the babe inherent data provider, if not registered already.
pub fn register_babe_inherent_data_provider(
inherent_data_providers: &InherentDataProviders,
slot_duration: Duration,
) -> Result<(), sp_consensus::Error> {
debug!(target: "babe", "Registering");
if !inherent_data_providers.has_provider(&sp_consensus_babe::inherents::INHERENT_IDENTIFIER) {
inherent_data_providers
.register_provider(sp_consensus_babe::inherents::InherentDataProvider::new(slot_duration))
.map_err(Into::into)
.map_err(sp_consensus::Error::InherentData)
} else {
Ok(())
}
}
/// A block-import handler for BABE.
///
/// This scans each imported block for epoch change signals. The signals are
@@ -1579,13 +1553,13 @@ pub fn block_import<Client, Block: BlockT, I>(
config: Config,
wrapped_block_import: I,
client: Arc<Client>,
) -> ClientResult<(BabeBlockImport<Block, Client, I>, BabeLink<Block>)> where
) -> ClientResult<(BabeBlockImport<Block, Client, I>, BabeLink<Block>)>
where
Client: AuxStore + HeaderBackend<Block> + HeaderMetadata<Block, Error = sp_blockchain::Error>,
{
let epoch_changes = aux_schema::load_epoch_changes::<Block, _>(&*client, &config)?;
let link = BabeLink {
epoch_changes: epoch_changes.clone(),
time_source: Default::default(),
config: config.clone(),
};
@@ -1616,13 +1590,13 @@ pub fn block_import<Client, Block: BlockT, I>(
///
/// The block import object provided must be the `BabeBlockImport` or a wrapper
/// of it, otherwise crucial import logic will be omitted.
pub fn import_queue<Block: BlockT, Client, SelectChain, Inner, CAW>(
pub fn import_queue<Block: BlockT, Client, SelectChain, Inner, CAW, CIDP>(
babe_link: BabeLink<Block>,
block_import: Inner,
justification_import: Option<BoxJustificationImport<Block>>,
client: Arc<Client>,
select_chain: SelectChain,
inherent_data_providers: InherentDataProviders,
create_inherent_data_providers: CIDP,
spawner: &impl sp_core::traits::SpawnEssentialNamed,
registry: Option<&Registry>,
can_author_with: CAW,
@@ -1636,15 +1610,14 @@ pub fn import_queue<Block: BlockT, Client, SelectChain, Inner, CAW>(
Client::Api: BlockBuilderApi<Block> + BabeApi<Block> + ApiExt<Block>,
SelectChain: sp_consensus::SelectChain<Block> + 'static,
CAW: CanAuthorWith<Block> + Send + Sync + 'static,
CIDP: CreateInherentDataProviders<Block, ()> + Send + Sync + 'static,
CIDP::InherentDataProviders: InherentDataProviderExt + Send + Sync,
{
register_babe_inherent_data_provider(&inherent_data_providers, babe_link.config.slot_duration())?;
let verifier = BabeVerifier {
select_chain,
inherent_data_providers,
create_inherent_data_providers,
config: babe_link.config,
epoch_changes: babe_link.epoch_changes,
time_source: babe_link.time_source,
can_author_with,
telemetry,
client,
+36 -9
View File
@@ -28,7 +28,10 @@ use sp_keystore::{
SyncCryptoStore,
vrf::make_transcript as transcript_from_data,
};
use sp_consensus_babe::{AuthorityPair, Slot, AllowedSlots, make_transcript, make_transcript_data};
use sp_consensus_babe::{
AuthorityPair, Slot, AllowedSlots, make_transcript, make_transcript_data,
inherents::InherentDataProvider,
};
use sc_consensus_slots::BackoffAuthoringOnFinalizedHeadLagging;
use sc_block_builder::{BlockBuilder, BlockBuilderProvider};
use sp_consensus::{
@@ -48,6 +51,7 @@ use rand_chacha::{
use sc_keystore::LocalKeystore;
use sp_application_crypto::key_types::BABE;
use futures::executor::block_on;
use sp_timestamp::InherentDataProvider as TimestampInherentDataProvider;
type Item = DigestItem<Hash>;
@@ -235,7 +239,17 @@ type TestSelectChain = substrate_test_runtime_client::LongestChain<
>;
pub struct TestVerifier {
inner: BabeVerifier<TestBlock, PeersFullClient, TestSelectChain, AlwaysCanAuthor>,
inner: BabeVerifier<
TestBlock,
PeersFullClient,
TestSelectChain,
AlwaysCanAuthor,
Box<dyn CreateInherentDataProviders<
TestBlock,
(),
InherentDataProviders = (TimestampInherentDataProvider, InherentDataProvider)
>>
>,
mutator: Mutator,
}
@@ -253,13 +267,12 @@ impl Verifier<TestBlock> for TestVerifier {
) -> Result<(BlockImportParams<TestBlock, ()>, Option<Vec<(CacheKeyId, Vec<u8>)>>), String> {
// apply post-sealing mutations (i.e. stripping seal, if desired).
(self.mutator)(&mut header, Stage::PostSeal);
self.inner.verify(dbg!(origin), header, justifications, body).await
self.inner.verify(origin, header, justifications, body).await
}
}
pub struct PeerData {
link: BabeLink<TestBlock>,
inherent_data_providers: InherentDataProviders,
block_import: Mutex<
Option<BoxBlockImport<TestBlock, TransactionFor<substrate_test_runtime_client::Backend, TestBlock>>>
>,
@@ -286,7 +299,6 @@ impl TestNetFactory for BabeTestNet {
)
{
let client = client.as_full().expect("only full clients are tested");
let inherent_data_providers = InherentDataProviders::new();
let config = Config::get_or_compute(&*client).expect("config available");
let (block_import, link) = crate::block_import(
@@ -303,7 +315,7 @@ impl TestNetFactory for BabeTestNet {
(
BlockImportAdapter::new(block_import),
None,
Some(PeerData { link, inherent_data_providers, block_import: data_block_import }),
Some(PeerData { link, block_import: data_block_import }),
)
}
@@ -329,10 +341,17 @@ impl TestNetFactory for BabeTestNet {
inner: BabeVerifier {
client: client.clone(),
select_chain: longest_chain,
inherent_data_providers: data.inherent_data_providers.clone(),
create_inherent_data_providers: Box::new(|_, _| async {
let timestamp = TimestampInherentDataProvider::from_system_time();
let slot = InherentDataProvider::from_timestamp_and_duration(
*timestamp,
Duration::from_secs(6),
);
Ok((timestamp, slot))
}),
config: data.link.config.clone(),
epoch_changes: data.link.epoch_changes.clone(),
time_source: data.link.time_source.clone(),
can_author_with: AlwaysCanAuthor,
telemetry: None,
},
@@ -440,7 +459,15 @@ fn run_one_test(
client,
env: environ,
sync_oracle: DummyOracle,
inherent_data_providers: data.inherent_data_providers.clone(),
create_inherent_data_providers: Box::new(|_, _| async {
let timestamp = TimestampInherentDataProvider::from_system_time();
let slot = InherentDataProvider::from_timestamp_and_duration(
*timestamp,
Duration::from_secs(6),
);
Ok((timestamp, slot))
}),
force_authoring: false,
backoff_authoring_blocks: Some(BackoffAuthoringOnFinalizedHeadLagging::default()),
babe_link: data.link.clone(),