mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 15:51:12 +00:00
consensus-slots: cleanup SlotDuration config (#10878)
* consensus-slots: cleanup the SlotDuration config * fix tests * address review comments
This commit is contained in:
Generated
+2
@@ -9627,6 +9627,8 @@ dependencies = [
|
||||
"serde",
|
||||
"sp-arithmetic",
|
||||
"sp-runtime",
|
||||
"sp-std",
|
||||
"sp-timestamp",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
@@ -8,7 +8,6 @@ use sc_finality_grandpa::SharedVoterState;
|
||||
use sc_keystore::LocalKeystore;
|
||||
use sc_service::{error::Error as ServiceError, Configuration, TaskManager};
|
||||
use sc_telemetry::{Telemetry, TelemetryWorker};
|
||||
use sp_consensus::SlotData;
|
||||
use sp_consensus_aura::sr25519::AuthorityPair as AuraPair;
|
||||
use std::{sync::Arc, time::Duration};
|
||||
|
||||
@@ -111,7 +110,7 @@ pub fn new_partial(
|
||||
telemetry.as_ref().map(|x| x.handle()),
|
||||
)?;
|
||||
|
||||
let slot_duration = sc_consensus_aura::slot_duration(&*client)?.slot_duration();
|
||||
let slot_duration = sc_consensus_aura::slot_duration(&*client)?;
|
||||
|
||||
let import_queue =
|
||||
sc_consensus_aura::import_queue::<AuraPair, _, _, _, _, _, _>(ImportQueueParams {
|
||||
@@ -122,7 +121,7 @@ pub fn new_partial(
|
||||
let timestamp = sp_timestamp::InherentDataProvider::from_system_time();
|
||||
|
||||
let slot =
|
||||
sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_duration(
|
||||
sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration(
|
||||
*timestamp,
|
||||
slot_duration,
|
||||
);
|
||||
@@ -260,7 +259,6 @@ pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError>
|
||||
sp_consensus::CanAuthorWithNativeVersion::new(client.executor().clone());
|
||||
|
||||
let slot_duration = sc_consensus_aura::slot_duration(&*client)?;
|
||||
let raw_slot_duration = slot_duration.slot_duration();
|
||||
|
||||
let aura = sc_consensus_aura::start_aura::<AuraPair, _, _, _, _, _, _, _, _, _, _, _>(
|
||||
StartAuraParams {
|
||||
@@ -273,9 +271,9 @@ pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError>
|
||||
let timestamp = sp_timestamp::InherentDataProvider::from_system_time();
|
||||
|
||||
let slot =
|
||||
sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_duration(
|
||||
sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration(
|
||||
*timestamp,
|
||||
raw_slot_duration,
|
||||
slot_duration,
|
||||
);
|
||||
|
||||
Ok((timestamp, slot))
|
||||
|
||||
@@ -212,7 +212,7 @@ pub fn new_partial(
|
||||
let timestamp = sp_timestamp::InherentDataProvider::from_system_time();
|
||||
|
||||
let slot =
|
||||
sp_consensus_babe::inherents::InherentDataProvider::from_timestamp_and_duration(
|
||||
sp_consensus_babe::inherents::InherentDataProvider::from_timestamp_and_slot_duration(
|
||||
*timestamp,
|
||||
slot_duration,
|
||||
);
|
||||
@@ -419,7 +419,7 @@ pub fn new_full_base(
|
||||
let timestamp = sp_timestamp::InherentDataProvider::from_system_time();
|
||||
|
||||
let slot =
|
||||
sp_consensus_babe::inherents::InherentDataProvider::from_timestamp_and_duration(
|
||||
sp_consensus_babe::inherents::InherentDataProvider::from_timestamp_and_slot_duration(
|
||||
*timestamp,
|
||||
slot_duration,
|
||||
);
|
||||
@@ -650,7 +650,10 @@ mod tests {
|
||||
.epoch_changes()
|
||||
.shared_data()
|
||||
.epoch_data(&epoch_descriptor, |slot| {
|
||||
sc_consensus_babe::Epoch::genesis(&babe_link.config(), slot)
|
||||
sc_consensus_babe::Epoch::genesis(
|
||||
babe_link.config().genesis_config(),
|
||||
slot,
|
||||
)
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
|
||||
@@ -77,14 +77,11 @@ pub use sp_consensus::SyncOracle;
|
||||
pub use sp_consensus_aura::{
|
||||
digests::CompatibleDigestItem,
|
||||
inherents::{InherentDataProvider, InherentType as AuraInherent, INHERENT_IDENTIFIER},
|
||||
AuraApi, ConsensusLog, AURA_ENGINE_ID,
|
||||
AuraApi, ConsensusLog, SlotDuration, AURA_ENGINE_ID,
|
||||
};
|
||||
|
||||
type AuthorityId<P> = <P as Pair>::Public;
|
||||
|
||||
/// Slot duration type for Aura.
|
||||
pub type SlotDuration = sc_consensus_slots::SlotDuration<sp_consensus_aura::SlotDuration>;
|
||||
|
||||
/// Get the slot duration for Aura.
|
||||
pub fn slot_duration<A, B, C>(client: &C) -> CResult<SlotDuration>
|
||||
where
|
||||
@@ -94,9 +91,7 @@ where
|
||||
C::Api: AuraApi<B, A>,
|
||||
{
|
||||
let best_block_id = BlockId::Hash(client.usage_info().chain.best_hash);
|
||||
let slot_duration = client.runtime_api().slot_duration(&best_block_id)?;
|
||||
|
||||
Ok(SlotDuration::new(slot_duration))
|
||||
client.runtime_api().slot_duration(&best_block_id).map_err(|err| err.into())
|
||||
}
|
||||
|
||||
/// Get slot author for given block along with authorities.
|
||||
@@ -574,7 +569,7 @@ mod tests {
|
||||
use sc_network_test::{Block as TestBlock, *};
|
||||
use sp_application_crypto::key_types::AURA;
|
||||
use sp_consensus::{
|
||||
AlwaysCanAuthor, DisableProofRecording, NoNetwork as DummyOracle, Proposal, SlotData,
|
||||
AlwaysCanAuthor, DisableProofRecording, NoNetwork as DummyOracle, Proposal,
|
||||
};
|
||||
use sp_consensus_aura::sr25519::AuthorityPair;
|
||||
use sp_inherents::InherentData;
|
||||
@@ -672,14 +667,14 @@ mod tests {
|
||||
let client = client.as_client();
|
||||
let slot_duration = slot_duration(&*client).expect("slot duration available");
|
||||
|
||||
assert_eq!(slot_duration.slot_duration().as_millis() as u64, SLOT_DURATION);
|
||||
assert_eq!(slot_duration.as_millis() as u64, SLOT_DURATION);
|
||||
import_queue::AuraVerifier::new(
|
||||
client,
|
||||
Box::new(|_, _| async {
|
||||
let timestamp = TimestampInherentDataProvider::from_system_time();
|
||||
let slot = InherentDataProvider::from_timestamp_and_duration(
|
||||
let slot = InherentDataProvider::from_timestamp_and_slot_duration(
|
||||
*timestamp,
|
||||
Duration::from_secs(6),
|
||||
SlotDuration::from_millis(6000),
|
||||
);
|
||||
|
||||
Ok((timestamp, slot))
|
||||
@@ -762,9 +757,9 @@ mod tests {
|
||||
justification_sync_link: (),
|
||||
create_inherent_data_providers: |_, _| async {
|
||||
let timestamp = TimestampInherentDataProvider::from_system_time();
|
||||
let slot = InherentDataProvider::from_timestamp_and_duration(
|
||||
let slot = InherentDataProvider::from_timestamp_and_slot_duration(
|
||||
*timestamp,
|
||||
Duration::from_secs(6),
|
||||
SlotDuration::from_millis(6000),
|
||||
);
|
||||
|
||||
Ok((timestamp, slot))
|
||||
|
||||
@@ -207,7 +207,7 @@ where
|
||||
&parent.hash(),
|
||||
parent.number().clone(),
|
||||
slot.into(),
|
||||
|slot| Epoch::genesis(&babe_config, slot),
|
||||
|slot| Epoch::genesis(babe_config.genesis_config(), slot),
|
||||
)
|
||||
.map_err(|e| Error::Consensus(ConsensusError::ChainLookup(e.to_string())))?
|
||||
.ok_or(Error::Consensus(ConsensusError::InvalidAuthoritiesSet))
|
||||
|
||||
@@ -66,9 +66,7 @@
|
||||
#![forbid(unsafe_code)]
|
||||
#![warn(missing_docs)]
|
||||
|
||||
use std::{
|
||||
borrow::Cow, collections::HashMap, convert::TryInto, pin::Pin, sync::Arc, time::Duration, u64,
|
||||
};
|
||||
use std::{borrow::Cow, collections::HashMap, convert::TryInto, pin::Pin, sync::Arc, u64};
|
||||
|
||||
use codec::{Decode, Encode};
|
||||
use futures::{
|
||||
@@ -106,10 +104,10 @@ use sp_block_builder::BlockBuilder as BlockBuilderApi;
|
||||
use sp_blockchain::{Error as ClientError, HeaderBackend, HeaderMetadata, Result as ClientResult};
|
||||
use sp_consensus::{
|
||||
BlockOrigin, CacheKeyId, CanAuthorWith, Environment, Error as ConsensusError, Proposer,
|
||||
SelectChain, SlotData,
|
||||
SelectChain,
|
||||
};
|
||||
use sp_consensus_babe::inherents::BabeInherentData;
|
||||
use sp_consensus_slots::Slot;
|
||||
use sp_consensus_slots::{Slot, SlotDuration};
|
||||
use sp_core::{crypto::ByteArray, ExecutionContext};
|
||||
use sp_inherents::{CreateInherentDataProviders, InherentData, InherentDataProvider};
|
||||
use sp_keystore::{SyncCryptoStore, SyncCryptoStorePtr};
|
||||
@@ -328,17 +326,15 @@ pub struct BabeIntermediate<B: BlockT> {
|
||||
/// Intermediate key for Babe engine.
|
||||
pub static INTERMEDIATE_KEY: &[u8] = b"babe1";
|
||||
|
||||
/// A slot duration.
|
||||
///
|
||||
/// Create with [`Self::get`].
|
||||
// FIXME: Once Rust has higher-kinded types, the duplication between this
|
||||
// and `super::babe::Config` can be eliminated.
|
||||
// https://github.com/paritytech/substrate/issues/2434
|
||||
/// Configuration for BABE used for defining block verification parameters as
|
||||
/// well as authoring (e.g. the slot duration).
|
||||
#[derive(Clone)]
|
||||
pub struct Config(sc_consensus_slots::SlotDuration<BabeGenesisConfiguration>);
|
||||
pub struct Config {
|
||||
genesis_config: BabeGenesisConfiguration,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
/// Fetch the config from the runtime.
|
||||
/// Create a new config by reading the genesis configuration from the runtime.
|
||||
pub fn get<B: BlockT, C>(client: &C) -> ClientResult<Self>
|
||||
where
|
||||
C: AuxStore + ProvideRuntimeApi<B> + UsageProvider<B>,
|
||||
@@ -355,7 +351,7 @@ impl Config {
|
||||
|
||||
let version = runtime_api.api_version::<dyn BabeApi<B>>(&best_block_id)?;
|
||||
|
||||
let slot_duration = if version == Some(1) {
|
||||
let genesis_config = if version == Some(1) {
|
||||
#[allow(deprecated)]
|
||||
{
|
||||
runtime_api.configuration_before_version_2(&best_block_id)?.into()
|
||||
@@ -368,20 +364,17 @@ impl Config {
|
||||
))
|
||||
};
|
||||
|
||||
Ok(Self(sc_consensus_slots::SlotDuration::new(slot_duration)))
|
||||
Ok(Config { genesis_config })
|
||||
}
|
||||
|
||||
/// Get the inner slot duration
|
||||
pub fn slot_duration(&self) -> Duration {
|
||||
self.0.slot_duration()
|
||||
/// Get the genesis configuration.
|
||||
pub fn genesis_config(&self) -> &BabeGenesisConfiguration {
|
||||
&self.genesis_config
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for Config {
|
||||
type Target = BabeGenesisConfiguration;
|
||||
|
||||
fn deref(&self) -> &BabeGenesisConfiguration {
|
||||
&*self.0
|
||||
/// Get the slot duration defined in the genesis configuration.
|
||||
pub fn slot_duration(&self) -> SlotDuration {
|
||||
SlotDuration::from_millis(self.genesis_config.slot_duration)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -488,7 +481,6 @@ where
|
||||
{
|
||||
const HANDLE_BUFFER_SIZE: usize = 1024;
|
||||
|
||||
let config = babe_link.config;
|
||||
let slot_notification_sinks = Arc::new(Mutex::new(Vec::new()));
|
||||
|
||||
let worker = BabeSlotWorker {
|
||||
@@ -502,7 +494,7 @@ where
|
||||
keystore,
|
||||
epoch_changes: babe_link.epoch_changes.clone(),
|
||||
slot_notification_sinks: slot_notification_sinks.clone(),
|
||||
config: config.clone(),
|
||||
config: babe_link.config.clone(),
|
||||
block_proposal_slot_portion,
|
||||
max_block_proposal_slot_portion,
|
||||
telemetry,
|
||||
@@ -510,7 +502,7 @@ where
|
||||
|
||||
info!(target: "babe", "👶 Starting BABE Authorship worker");
|
||||
let inner = sc_consensus_slots::start_slot_worker(
|
||||
config.0.clone(),
|
||||
babe_link.config.slot_duration(),
|
||||
select_chain,
|
||||
worker,
|
||||
sync_oracle,
|
||||
@@ -521,7 +513,8 @@ where
|
||||
let (worker_tx, worker_rx) = channel(HANDLE_BUFFER_SIZE);
|
||||
|
||||
let answer_requests =
|
||||
answer_requests(worker_rx, config.0, client, babe_link.epoch_changes.clone());
|
||||
answer_requests(worker_rx, babe_link.config, client, babe_link.epoch_changes.clone());
|
||||
|
||||
Ok(BabeWorker {
|
||||
inner: Box::pin(future::join(inner, answer_requests).map(|_| ())),
|
||||
slot_notification_sinks,
|
||||
@@ -531,7 +524,7 @@ where
|
||||
|
||||
async fn answer_requests<B: BlockT, C>(
|
||||
mut request_rx: Receiver<BabeRequest<B>>,
|
||||
genesis_config: sc_consensus_slots::SlotDuration<BabeGenesisConfiguration>,
|
||||
config: Config,
|
||||
client: Arc<C>,
|
||||
epoch_changes: SharedEpochChanges<B, Epoch>,
|
||||
) where
|
||||
@@ -561,7 +554,7 @@ async fn answer_requests<B: BlockT, C>(
|
||||
|
||||
let viable_epoch = epoch_changes
|
||||
.viable_epoch(&epoch_descriptor, |slot| {
|
||||
Epoch::genesis(&genesis_config, slot)
|
||||
Epoch::genesis(&config.genesis_config, slot)
|
||||
})
|
||||
.ok_or_else(|| Error::<B>::FetchEpoch(parent_hash))?;
|
||||
|
||||
@@ -720,7 +713,9 @@ where
|
||||
fn authorities_len(&self, epoch_descriptor: &Self::EpochData) -> Option<usize> {
|
||||
self.epoch_changes
|
||||
.shared_data()
|
||||
.viable_epoch(&epoch_descriptor, |slot| Epoch::genesis(&self.config, slot))
|
||||
.viable_epoch(&epoch_descriptor, |slot| {
|
||||
Epoch::genesis(&self.config.genesis_config, slot)
|
||||
})
|
||||
.map(|epoch| epoch.as_ref().authorities.len())
|
||||
}
|
||||
|
||||
@@ -735,7 +730,9 @@ where
|
||||
slot,
|
||||
self.epoch_changes
|
||||
.shared_data()
|
||||
.viable_epoch(&epoch_descriptor, |slot| Epoch::genesis(&self.config, slot))?
|
||||
.viable_epoch(&epoch_descriptor, |slot| {
|
||||
Epoch::genesis(&self.config.genesis_config, slot)
|
||||
})?
|
||||
.as_ref(),
|
||||
&self.keystore,
|
||||
);
|
||||
@@ -1165,7 +1162,9 @@ where
|
||||
.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))
|
||||
.viable_epoch(&epoch_descriptor, |slot| {
|
||||
Epoch::genesis(&self.config.genesis_config, slot)
|
||||
})
|
||||
.ok_or_else(|| Error::<Block>::FetchEpoch(parent_hash))?;
|
||||
|
||||
// We add one to the current slot to allow for some small drift.
|
||||
@@ -1498,7 +1497,9 @@ where
|
||||
old_epoch_changes = Some((*epoch_changes).clone());
|
||||
|
||||
let viable_epoch = epoch_changes
|
||||
.viable_epoch(&epoch_descriptor, |slot| Epoch::genesis(&self.config, slot))
|
||||
.viable_epoch(&epoch_descriptor, |slot| {
|
||||
Epoch::genesis(&self.config.genesis_config, slot)
|
||||
})
|
||||
.ok_or_else(|| {
|
||||
ConsensusError::ClientImport(Error::<Block>::FetchEpoch(parent_hash).into())
|
||||
})?;
|
||||
@@ -1684,7 +1685,8 @@ pub fn block_import<Client, Block: BlockT, I>(
|
||||
where
|
||||
Client: AuxStore + HeaderBackend<Block> + HeaderMetadata<Block, Error = sp_blockchain::Error>,
|
||||
{
|
||||
let epoch_changes = aux_schema::load_epoch_changes::<Block, _>(&*client, &config)?;
|
||||
let epoch_changes =
|
||||
aux_schema::load_epoch_changes::<Block, _>(&*client, &config.genesis_config)?;
|
||||
let link = BabeLink { epoch_changes: epoch_changes.clone(), config: config.clone() };
|
||||
|
||||
// NOTE: this isn't entirely necessary, but since we didn't use to prune the
|
||||
|
||||
@@ -143,7 +143,7 @@ impl DummyProposer {
|
||||
&self.parent_hash,
|
||||
self.parent_number,
|
||||
this_slot,
|
||||
|slot| Epoch::genesis(&self.factory.config, slot),
|
||||
|slot| Epoch::genesis(self.factory.config.genesis_config(), slot),
|
||||
)
|
||||
.expect("client has data to find epoch")
|
||||
.expect("can compute epoch for baked block");
|
||||
@@ -336,9 +336,9 @@ impl TestNetFactory for BabeTestNet {
|
||||
select_chain: longest_chain,
|
||||
create_inherent_data_providers: Box::new(|_, _| async {
|
||||
let timestamp = TimestampInherentDataProvider::from_system_time();
|
||||
let slot = InherentDataProvider::from_timestamp_and_duration(
|
||||
let slot = InherentDataProvider::from_timestamp_and_slot_duration(
|
||||
*timestamp,
|
||||
Duration::from_secs(6),
|
||||
SlotDuration::from_millis(6000),
|
||||
);
|
||||
|
||||
Ok((timestamp, slot))
|
||||
@@ -449,9 +449,9 @@ fn run_one_test(mutator: impl Fn(&mut TestHeader, Stage) + Send + Sync + 'static
|
||||
sync_oracle: DummyOracle,
|
||||
create_inherent_data_providers: Box::new(|_, _| async {
|
||||
let timestamp = TimestampInherentDataProvider::from_system_time();
|
||||
let slot = InherentDataProvider::from_timestamp_and_duration(
|
||||
let slot = InherentDataProvider::from_timestamp_and_slot_duration(
|
||||
*timestamp,
|
||||
Duration::from_secs(6),
|
||||
SlotDuration::from_millis(6000),
|
||||
);
|
||||
|
||||
Ok((timestamp, slot))
|
||||
@@ -699,12 +699,12 @@ fn importing_block_one_sets_genesis_epoch() {
|
||||
&mut block_import,
|
||||
);
|
||||
|
||||
let genesis_epoch = Epoch::genesis(&data.link.config, 999.into());
|
||||
let genesis_epoch = Epoch::genesis(data.link.config.genesis_config(), 999.into());
|
||||
|
||||
let epoch_changes = data.link.epoch_changes.shared_data();
|
||||
let epoch_for_second_block = epoch_changes
|
||||
.epoch_data_for_child_of(descendent_query(&*client), &block_hash, 1, 1000.into(), |slot| {
|
||||
Epoch::genesis(&data.link.config, slot)
|
||||
Epoch::genesis(data.link.config.genesis_config(), slot)
|
||||
})
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
||||
@@ -22,13 +22,12 @@
|
||||
use crate::{ConsensusDataProvider, Error};
|
||||
use sc_client_api::{AuxStore, UsageProvider};
|
||||
use sc_consensus::BlockImportParams;
|
||||
use sc_consensus_aura::slot_duration;
|
||||
use sp_api::{ProvideRuntimeApi, TransactionFor};
|
||||
use sp_blockchain::{HeaderBackend, HeaderMetadata};
|
||||
use sp_consensus_aura::{
|
||||
digests::CompatibleDigestItem,
|
||||
sr25519::{AuthorityId, AuthoritySignature},
|
||||
AuraApi,
|
||||
AuraApi, Slot, SlotDuration,
|
||||
};
|
||||
use sp_inherents::InherentData;
|
||||
use sp_runtime::{traits::Block as BlockT, Digest, DigestItem};
|
||||
@@ -37,8 +36,8 @@ use std::{marker::PhantomData, sync::Arc};
|
||||
|
||||
/// Consensus data provider for Aura.
|
||||
pub struct AuraConsensusDataProvider<B, C> {
|
||||
// slot duration in milliseconds
|
||||
slot_duration: u64,
|
||||
// slot duration
|
||||
slot_duration: SlotDuration,
|
||||
// phantom data for required generics
|
||||
_phantom: PhantomData<(B, C)>,
|
||||
}
|
||||
@@ -52,8 +51,8 @@ where
|
||||
/// Creates a new instance of the [`AuraConsensusDataProvider`], requires that `client`
|
||||
/// implements [`sp_consensus_aura::AuraApi`]
|
||||
pub fn new(client: Arc<C>) -> Self {
|
||||
let slot_duration =
|
||||
(*slot_duration(&*client).expect("slot_duration is always present; qed.")).get();
|
||||
let slot_duration = sc_consensus_aura::slot_duration(&*client)
|
||||
.expect("slot_duration is always present; qed.");
|
||||
|
||||
Self { slot_duration, _phantom: PhantomData }
|
||||
}
|
||||
@@ -76,13 +75,15 @@ where
|
||||
_parent: &B::Header,
|
||||
inherents: &InherentData,
|
||||
) -> Result<Digest, Error> {
|
||||
let time_stamp =
|
||||
*inherents.timestamp_inherent_data()?.expect("Timestamp is always present; qed");
|
||||
let timestamp =
|
||||
inherents.timestamp_inherent_data()?.expect("Timestamp is always present; qed");
|
||||
|
||||
// we always calculate the new slot number based on the current time-stamp and the slot
|
||||
// duration.
|
||||
let digest_item = <DigestItem as CompatibleDigestItem<AuthoritySignature>>::aura_pre_digest(
|
||||
(time_stamp / self.slot_duration).into(),
|
||||
Slot::from_timestamp(timestamp, self.slot_duration),
|
||||
);
|
||||
|
||||
Ok(Digest { logs: vec![digest_item] })
|
||||
}
|
||||
|
||||
|
||||
@@ -169,7 +169,9 @@ where
|
||||
.ok_or_else(|| sp_consensus::Error::InvalidAuthoritiesSet)?;
|
||||
|
||||
let epoch = epoch_changes
|
||||
.viable_epoch(&epoch_descriptor, |slot| Epoch::genesis(&self.config, slot))
|
||||
.viable_epoch(&epoch_descriptor, |slot| {
|
||||
Epoch::genesis(self.config.genesis_config(), slot)
|
||||
})
|
||||
.ok_or_else(|| {
|
||||
log::info!(target: "babe", "create_digest: no viable_epoch :(");
|
||||
sp_consensus::Error::InvalidAuthoritiesSet
|
||||
@@ -283,15 +285,17 @@ where
|
||||
let timestamp = inherents
|
||||
.timestamp_inherent_data()?
|
||||
.ok_or_else(|| Error::StringError("No timestamp inherent data".into()))?;
|
||||
let slot = *timestamp / self.config.slot_duration;
|
||||
|
||||
let slot = Slot::from_timestamp(timestamp, self.config.slot_duration());
|
||||
|
||||
// manually hard code epoch descriptor
|
||||
epoch_descriptor = match epoch_descriptor {
|
||||
ViableEpochDescriptor::Signaled(identifier, _header) =>
|
||||
ViableEpochDescriptor::Signaled(
|
||||
identifier,
|
||||
EpochHeader {
|
||||
start_slot: slot.into(),
|
||||
end_slot: (slot * self.config.epoch_length).into(),
|
||||
start_slot: slot,
|
||||
end_slot: (*slot * self.config.genesis_config().epoch_length).into(),
|
||||
},
|
||||
),
|
||||
_ => unreachable!(
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
|
||||
use crate::Error;
|
||||
use sc_client_api::{AuxStore, UsageProvider};
|
||||
use sc_consensus_aura::slot_duration;
|
||||
use sc_consensus_babe::Config;
|
||||
use sp_api::ProvideRuntimeApi;
|
||||
use sp_blockchain::HeaderBackend;
|
||||
use sp_consensus_aura::{
|
||||
@@ -30,6 +28,7 @@ use sp_consensus_aura::{
|
||||
AuraApi,
|
||||
};
|
||||
use sp_consensus_babe::BabeApi;
|
||||
use sp_consensus_slots::{Slot, SlotDuration};
|
||||
use sp_inherents::{InherentData, InherentDataProvider, InherentIdentifier};
|
||||
use sp_runtime::{
|
||||
generic::BlockId,
|
||||
@@ -53,7 +52,7 @@ pub struct SlotTimestampProvider {
|
||||
// holds the unix millisecnd timestamp for the most recent block
|
||||
unix_millis: atomic::AtomicU64,
|
||||
// configured slot_duration in the runtime
|
||||
slot_duration: u64,
|
||||
slot_duration: SlotDuration,
|
||||
}
|
||||
|
||||
impl SlotTimestampProvider {
|
||||
@@ -64,7 +63,7 @@ impl SlotTimestampProvider {
|
||||
C: AuxStore + HeaderBackend<B> + ProvideRuntimeApi<B> + UsageProvider<B>,
|
||||
C::Api: BabeApi<B>,
|
||||
{
|
||||
let slot_duration = Config::get(&*client)?.slot_duration;
|
||||
let slot_duration = sc_consensus_babe::Config::get(&*client)?.slot_duration();
|
||||
|
||||
let time = Self::with_header(&client, slot_duration, |header| {
|
||||
let slot_number = *sc_consensus_babe::find_pre_digest::<B>(&header)
|
||||
@@ -83,7 +82,7 @@ impl SlotTimestampProvider {
|
||||
C: AuxStore + HeaderBackend<B> + ProvideRuntimeApi<B> + UsageProvider<B>,
|
||||
C::Api: AuraApi<B, AuthorityId>,
|
||||
{
|
||||
let slot_duration = (*slot_duration(&*client)?).get();
|
||||
let slot_duration = sc_consensus_aura::slot_duration(&*client)?;
|
||||
|
||||
let time = Self::with_header(&client, slot_duration, |header| {
|
||||
let slot_number = *sc_consensus_aura::find_pre_digest::<B, AuthoritySignature>(&header)
|
||||
@@ -94,7 +93,11 @@ impl SlotTimestampProvider {
|
||||
Ok(Self { unix_millis: atomic::AtomicU64::new(time), slot_duration })
|
||||
}
|
||||
|
||||
fn with_header<F, C, B>(client: &Arc<C>, slot_duration: u64, func: F) -> Result<u64, Error>
|
||||
fn with_header<F, C, B>(
|
||||
client: &Arc<C>,
|
||||
slot_duration: SlotDuration,
|
||||
func: F,
|
||||
) -> Result<u64, Error>
|
||||
where
|
||||
B: BlockT,
|
||||
C: AuxStore + HeaderBackend<B> + UsageProvider<B>,
|
||||
@@ -110,7 +113,7 @@ impl SlotTimestampProvider {
|
||||
.ok_or_else(|| "best header not found in the db!".to_string())?;
|
||||
let slot = func(header)?;
|
||||
// add the slot duration so there's no collision of slots
|
||||
(slot * slot_duration) + slot_duration
|
||||
(slot * slot_duration.as_millis() as u64) + slot_duration.as_millis() as u64
|
||||
} else {
|
||||
// this is the first block, use the correct time.
|
||||
let now = SystemTime::now();
|
||||
@@ -123,8 +126,11 @@ impl SlotTimestampProvider {
|
||||
}
|
||||
|
||||
/// Get the current slot number
|
||||
pub fn slot(&self) -> u64 {
|
||||
self.unix_millis.load(atomic::Ordering::SeqCst) / self.slot_duration
|
||||
pub fn slot(&self) -> Slot {
|
||||
Slot::from_timestamp(
|
||||
self.unix_millis.load(atomic::Ordering::SeqCst).into(),
|
||||
self.slot_duration,
|
||||
)
|
||||
}
|
||||
|
||||
/// Gets the current time stamp.
|
||||
@@ -140,8 +146,10 @@ impl InherentDataProvider for SlotTimestampProvider {
|
||||
inherent_data: &mut InherentData,
|
||||
) -> Result<(), sp_inherents::Error> {
|
||||
// we update the time here.
|
||||
let new_time: InherentType =
|
||||
self.unix_millis.fetch_add(self.slot_duration, atomic::Ordering::SeqCst).into();
|
||||
let new_time: InherentType = self
|
||||
.unix_millis
|
||||
.fetch_add(self.slot_duration.as_millis() as u64, atomic::Ordering::SeqCst)
|
||||
.into();
|
||||
inherent_data.put_data(INHERENT_IDENTIFIER, &new_time)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -32,15 +32,14 @@ pub use aux_schema::{check_equivocation, MAX_SLOT_CAPACITY, PRUNING_BOUND};
|
||||
pub use slots::SlotInfo;
|
||||
use slots::Slots;
|
||||
|
||||
use codec::{Decode, Encode};
|
||||
use futures::{future::Either, Future, TryFutureExt};
|
||||
use futures_timer::Delay;
|
||||
use log::{debug, error, info, warn};
|
||||
use log::{debug, info, warn};
|
||||
use sc_consensus::{BlockImport, JustificationSyncLink};
|
||||
use sc_telemetry::{telemetry, TelemetryHandle, CONSENSUS_DEBUG, CONSENSUS_INFO, CONSENSUS_WARN};
|
||||
use sp_arithmetic::traits::BaseArithmetic;
|
||||
use sp_consensus::{CanAuthorWith, Proposer, SelectChain, SlotData, SyncOracle};
|
||||
use sp_consensus_slots::Slot;
|
||||
use sp_consensus::{CanAuthorWith, Proposer, SelectChain, SyncOracle};
|
||||
use sp_consensus_slots::{Slot, SlotDuration};
|
||||
use sp_inherents::CreateInherentDataProviders;
|
||||
use sp_runtime::{
|
||||
generic::BlockId,
|
||||
@@ -459,8 +458,8 @@ impl_inherent_data_provider_ext_tuple!(T, S, A, B, C, D, E, F, G, H, I, J);
|
||||
///
|
||||
/// Every time a new slot is triggered, `worker.on_slot` is called and the future it returns is
|
||||
/// polled until completion, unless we are major syncing.
|
||||
pub async fn start_slot_worker<B, C, W, T, SO, CIDP, CAW, Proof>(
|
||||
slot_duration: SlotDuration<T>,
|
||||
pub async fn start_slot_worker<B, C, W, SO, CIDP, CAW, Proof>(
|
||||
slot_duration: SlotDuration,
|
||||
client: C,
|
||||
mut worker: W,
|
||||
mut sync_oracle: SO,
|
||||
@@ -471,15 +470,11 @@ pub async fn start_slot_worker<B, C, W, T, SO, CIDP, CAW, Proof>(
|
||||
C: SelectChain<B>,
|
||||
W: SlotWorker<B, Proof>,
|
||||
SO: SyncOracle + Send,
|
||||
T: SlotData + Clone,
|
||||
CIDP: CreateInherentDataProviders<B, ()> + Send,
|
||||
CIDP::InherentDataProviders: InherentDataProviderExt + Send,
|
||||
CAW: CanAuthorWith<B> + Send,
|
||||
{
|
||||
let SlotDuration(slot_duration) = slot_duration;
|
||||
|
||||
let mut slots =
|
||||
Slots::new(slot_duration.slot_duration(), create_inherent_data_providers, client);
|
||||
let mut slots = Slots::new(slot_duration.as_duration(), create_inherent_data_providers, client);
|
||||
|
||||
loop {
|
||||
let slot_info = match slots.next_slot().await {
|
||||
@@ -523,45 +518,6 @@ pub enum CheckedHeader<H, S> {
|
||||
Checked(H, S),
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum Error<T>
|
||||
where
|
||||
T: Debug,
|
||||
{
|
||||
#[error("Slot duration is invalid: {0:?}")]
|
||||
SlotDurationInvalid(SlotDuration<T>),
|
||||
}
|
||||
|
||||
/// A slot duration. Create with [`Self::new`].
|
||||
#[derive(Clone, Copy, Debug, Encode, Decode, Hash, PartialOrd, Ord, PartialEq, Eq)]
|
||||
pub struct SlotDuration<T>(T);
|
||||
|
||||
impl<T> Deref for SlotDuration<T> {
|
||||
type Target = T;
|
||||
fn deref(&self) -> &T {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: SlotData> SlotData for SlotDuration<T> {
|
||||
fn slot_duration(&self) -> std::time::Duration {
|
||||
self.0.slot_duration()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone + Send + Sync + 'static> SlotDuration<T> {
|
||||
/// Create a new instance of `Self`.
|
||||
pub fn new(val: T) -> Self {
|
||||
Self(val)
|
||||
}
|
||||
|
||||
/// Returns slot data value.
|
||||
pub fn get(&self) -> T {
|
||||
self.0.clone()
|
||||
}
|
||||
}
|
||||
|
||||
/// A unit type wrapper to express the proportion of a slot.
|
||||
pub struct SlotProportion(f32);
|
||||
|
||||
|
||||
@@ -58,12 +58,11 @@ impl InherentDataProvider {
|
||||
|
||||
/// Creates the inherent data provider by calculating the slot from the given
|
||||
/// `timestamp` and `duration`.
|
||||
pub fn from_timestamp_and_duration(
|
||||
pub fn from_timestamp_and_slot_duration(
|
||||
timestamp: sp_timestamp::Timestamp,
|
||||
duration: std::time::Duration,
|
||||
slot_duration: sp_consensus_slots::SlotDuration,
|
||||
) -> Self {
|
||||
let slot =
|
||||
InherentType::from((timestamp.as_duration().as_millis() / duration.as_millis()) as u64);
|
||||
let slot = InherentType::from_timestamp(timestamp, slot_duration);
|
||||
|
||||
Self { slot }
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ pub mod ed25519 {
|
||||
pub type AuthorityId = app_ed25519::Public;
|
||||
}
|
||||
|
||||
pub use sp_consensus_slots::Slot;
|
||||
pub use sp_consensus_slots::{Slot, SlotDuration};
|
||||
|
||||
/// The `ConsensusEngineId` of AuRa.
|
||||
pub const AURA_ENGINE_ID: ConsensusEngineId = [b'a', b'u', b'r', b'a'];
|
||||
@@ -93,28 +93,3 @@ sp_api::decl_runtime_apis! {
|
||||
fn authorities() -> Vec<AuthorityId>;
|
||||
}
|
||||
}
|
||||
|
||||
/// Aura slot duration.
|
||||
///
|
||||
/// Internally stored as milliseconds.
|
||||
#[derive(sp_runtime::RuntimeDebug, Encode, Decode, PartialEq, Clone, Copy)]
|
||||
pub struct SlotDuration(u64);
|
||||
|
||||
impl SlotDuration {
|
||||
/// Initialize from the given milliseconds.
|
||||
pub fn from_millis(val: u64) -> Self {
|
||||
Self(val)
|
||||
}
|
||||
|
||||
/// Returns the slot duration in milli seconds.
|
||||
pub fn get(&self) -> u64 {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl sp_consensus::SlotData for SlotDuration {
|
||||
fn slot_duration(&self) -> std::time::Duration {
|
||||
std::time::Duration::from_millis(self.0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
//! Inherents for BABE
|
||||
|
||||
use sp_inherents::{Error, InherentData, InherentIdentifier};
|
||||
|
||||
use sp_std::result::Result;
|
||||
|
||||
/// The BABE inherent identifier.
|
||||
@@ -60,12 +59,11 @@ impl InherentDataProvider {
|
||||
|
||||
/// Creates the inherent data provider by calculating the slot from the given
|
||||
/// `timestamp` and `duration`.
|
||||
pub fn from_timestamp_and_duration(
|
||||
pub fn from_timestamp_and_slot_duration(
|
||||
timestamp: sp_timestamp::Timestamp,
|
||||
duration: std::time::Duration,
|
||||
slot_duration: sp_consensus_slots::SlotDuration,
|
||||
) -> Self {
|
||||
let slot =
|
||||
InherentType::from((timestamp.as_duration().as_millis() / duration.as_millis()) as u64);
|
||||
let slot = InherentType::from_timestamp(timestamp, slot_duration);
|
||||
|
||||
Self { slot }
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ pub const MEDIAN_ALGORITHM_CARDINALITY: usize = 1200; // arbitrary suggestion by
|
||||
/// The index of an authority.
|
||||
pub type AuthorityIndex = u32;
|
||||
|
||||
pub use sp_consensus_slots::Slot;
|
||||
pub use sp_consensus_slots::{Slot, SlotDuration};
|
||||
|
||||
/// An equivocation proof for multiple block authorships on the same slot (i.e. double vote).
|
||||
pub type EquivocationProof<H> = sp_consensus_slots::EquivocationProof<H, AuthorityId>;
|
||||
@@ -237,13 +237,6 @@ impl AllowedSlots {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl sp_consensus::SlotData for BabeGenesisConfiguration {
|
||||
fn slot_duration(&self) -> std::time::Duration {
|
||||
std::time::Duration::from_millis(self.slot_duration)
|
||||
}
|
||||
}
|
||||
|
||||
/// Configuration data used by the BABE consensus engine.
|
||||
#[derive(Clone, PartialEq, Eq, Encode, Decode, RuntimeDebug, MaxEncodedLen, TypeInfo)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
||||
|
||||
@@ -327,9 +327,3 @@ impl<Block: BlockT> CanAuthorWith<Block> for NeverCanAuthor {
|
||||
Err("Authoring is always disabled.".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
/// A type from which a slot duration can be obtained.
|
||||
pub trait SlotData {
|
||||
/// Gets the slot duration.
|
||||
fn slot_duration(&self) -> sp_std::time::Duration;
|
||||
}
|
||||
|
||||
@@ -16,8 +16,10 @@ targets = ["x86_64-unknown-linux-gnu"]
|
||||
codec = { package = "parity-scale-codec", version = "2.2.0", default-features = false, features = ["derive", "max-encoded-len"] }
|
||||
scale-info = { version = "1.0", default-features = false, features = ["derive"] }
|
||||
serde = { version = "1.0", features = ["derive"], optional = true }
|
||||
sp-runtime = { version = "5.0.0", default-features = false, path = "../../runtime" }
|
||||
sp-arithmetic = { version = "4.0.0", default-features = false, path = "../../arithmetic" }
|
||||
sp-runtime = { version = "5.0.0", default-features = false, path = "../../runtime" }
|
||||
sp-std = { version = "4.0.0", default-features = false, path = "../../std" }
|
||||
sp-timestamp = { version = "4.0.0-dev", default-features = false, path = "../../timestamp" }
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
@@ -25,6 +27,8 @@ std = [
|
||||
"codec/std",
|
||||
"scale-info/std",
|
||||
"serde",
|
||||
"sp-runtime/std",
|
||||
"sp-arithmetic/std",
|
||||
"sp-runtime/std",
|
||||
"sp-std/std",
|
||||
"sp-timestamp/std",
|
||||
]
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
use codec::{Decode, Encode, MaxEncodedLen};
|
||||
use scale_info::TypeInfo;
|
||||
use sp_timestamp::Timestamp;
|
||||
|
||||
/// Unit type wrapper that represents a slot.
|
||||
#[derive(Debug, Encode, MaxEncodedLen, Decode, Eq, Clone, Copy, Default, Ord, TypeInfo)]
|
||||
@@ -64,6 +65,11 @@ impl<T: Into<u64> + Copy> core::cmp::PartialOrd<T> for Slot {
|
||||
}
|
||||
|
||||
impl Slot {
|
||||
/// Create a new slot by calculating it from the given timestamp and slot duration.
|
||||
pub const fn from_timestamp(timestamp: Timestamp, slot_duration: SlotDuration) -> Self {
|
||||
Slot(timestamp.as_millis() / slot_duration.as_millis())
|
||||
}
|
||||
|
||||
/// Saturating addition.
|
||||
pub fn saturating_add<T: Into<u64>>(self, rhs: T) -> Self {
|
||||
Self(self.0.saturating_add(rhs.into()))
|
||||
@@ -94,6 +100,32 @@ impl From<Slot> for u64 {
|
||||
}
|
||||
}
|
||||
|
||||
/// A slot duration defined in milliseconds.
|
||||
#[derive(Clone, Copy, Debug, Encode, Decode, Hash, PartialOrd, Ord, PartialEq, Eq, TypeInfo)]
|
||||
pub struct SlotDuration(u64);
|
||||
|
||||
impl SlotDuration {
|
||||
/// Initialize from the given milliseconds.
|
||||
pub const fn from_millis(millis: u64) -> Self {
|
||||
Self(millis)
|
||||
}
|
||||
}
|
||||
|
||||
impl SlotDuration {
|
||||
/// Returns `self` as a `u64` representing the duration in milliseconds.
|
||||
pub const fn as_millis(&self) -> u64 {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl SlotDuration {
|
||||
/// Returns `self` as [`sp_std::time::Duration`].
|
||||
pub const fn as_duration(&self) -> sp_std::time::Duration {
|
||||
sp_std::time::Duration::from_millis(self.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents an equivocation proof. An equivocation happens when a validator
|
||||
/// produces more than one block on the same slot. The proof of equivocation
|
||||
/// are the given distinct headers that were signed by the validator and which
|
||||
|
||||
@@ -42,10 +42,16 @@ impl Timestamp {
|
||||
}
|
||||
|
||||
/// Returns `self` as [`Duration`].
|
||||
pub fn as_duration(self) -> Duration {
|
||||
pub const fn as_duration(self) -> Duration {
|
||||
Duration::from_millis(self.0)
|
||||
}
|
||||
|
||||
/// Returns `self` as a `u64` representing the elapsed time since the UNIX_EPOCH in
|
||||
/// milliseconds.
|
||||
pub const fn as_millis(&self) -> u64 {
|
||||
self.0
|
||||
}
|
||||
|
||||
/// Checked subtraction that returns `None` on an underflow.
|
||||
pub fn checked_sub(self, other: Self) -> Option<Self> {
|
||||
self.0.checked_sub(other.0).map(Self)
|
||||
|
||||
Reference in New Issue
Block a user