Introduce a Slot type (#7997)

* Introduce a `Slot` type

Instead of having some type definition that only was used in half of the
code or directly using `u64`, this adds a new unit type wrapper `Slot`.
This makes it especially easy for the outside api to know what type is
expected/returned.

* Change epoch duratioC

* rename all instances of slot number to slot

* Make the constructor private

Co-authored-by: André Silva <andrerfosilva@gmail.com>
This commit is contained in:
Bastian Köcher
2021-01-28 20:44:22 +01:00
committed by GitHub
parent 6c2dd28dfb
commit b6294418f8
34 changed files with 549 additions and 445 deletions
+5
View File
@@ -6724,6 +6724,7 @@ dependencies = [
"sp-blockchain",
"sp-consensus",
"sp-consensus-aura",
"sp-consensus-slots",
"sp-core",
"sp-inherents",
"sp-io",
@@ -6776,6 +6777,7 @@ dependencies = [
"sp-blockchain",
"sp-consensus",
"sp-consensus-babe",
"sp-consensus-slots",
"sp-consensus-vrf",
"sp-core",
"sp-inherents",
@@ -6856,6 +6858,7 @@ dependencies = [
"sp-blockchain",
"sp-consensus",
"sp-consensus-babe",
"sp-consensus-slots",
"sp-core",
"sp-inherents",
"sp-keyring",
@@ -8247,6 +8250,7 @@ dependencies = [
"parity-scale-codec",
"sp-api",
"sp-application-crypto",
"sp-consensus-slots",
"sp-inherents",
"sp-runtime",
"sp-std",
@@ -8288,6 +8292,7 @@ name = "sp-consensus-slots"
version = "0.8.1"
dependencies = [
"parity-scale-codec",
"sp-arithmetic",
"sp-runtime",
]
+6 -6
View File
@@ -514,7 +514,7 @@ mod tests {
let chain_spec = crate::chain_spec::tests::integration_test_config_with_single_authority();
// For the block factory
let mut slot_num = 1u64;
let mut slot = 1u64;
// For the extrinsics factory
let bob = Arc::new(AccountKeyring::Bob.pair());
@@ -575,7 +575,7 @@ mod tests {
descendent_query(&*service.client()),
&parent_hash,
parent_number,
slot_num,
slot.into(),
).unwrap().unwrap();
let mut digest = Digest::<H256>::default();
@@ -583,9 +583,9 @@ mod tests {
// even though there's only one authority some slots might be empty,
// so we must keep trying the next slots until we can claim one.
let babe_pre_digest = loop {
inherent_data.replace_data(sp_timestamp::INHERENT_IDENTIFIER, &(slot_num * SLOT_DURATION));
inherent_data.replace_data(sp_timestamp::INHERENT_IDENTIFIER, &(slot * SLOT_DURATION));
if let Some(babe_pre_digest) = sc_consensus_babe::test_helpers::claim_slot(
slot_num,
slot.into(),
&parent_header,
&*service.client(),
keystore.clone(),
@@ -594,7 +594,7 @@ mod tests {
break babe_pre_digest;
}
slot_num += 1;
slot += 1;
};
digest.push(<DigestItem as CompatibleDigestItem>::babe_pre_digest(babe_pre_digest));
@@ -625,7 +625,7 @@ mod tests {
let item = <DigestItem as CompatibleDigestItem>::babe_seal(
signature,
);
slot_num += 1;
slot += 1;
let mut params = BlockImportParams::new(BlockOrigin::File, new_header);
params.post_digests.push(item);
+2 -2
View File
@@ -1200,7 +1200,7 @@ impl_runtime_apis! {
}
}
fn current_epoch_start() -> sp_consensus_babe::SlotNumber {
fn current_epoch_start() -> sp_consensus_babe::Slot {
Babe::current_epoch_start()
}
@@ -1213,7 +1213,7 @@ impl_runtime_apis! {
}
fn generate_key_ownership_proof(
_slot_number: sp_consensus_babe::SlotNumber,
_slot: sp_consensus_babe::Slot,
authority_id: sp_consensus_babe::AuthorityId,
) -> Option<sp_consensus_babe::OpaqueKeyOwnershipProof> {
use codec::Encode;
@@ -20,6 +20,7 @@ sc-block-builder = { version = "0.8.0", path = "../../block-builder" }
sc-client-api = { version = "2.0.0", path = "../../api" }
codec = { package = "parity-scale-codec", version = "1.3.6" }
sp-consensus = { version = "0.8.0", path = "../../../primitives/consensus/common" }
sp-consensus-slots = { version = "0.8.0", path = "../../../primitives/consensus/slots" }
derive_more = "0.99.2"
futures = "0.3.9"
futures-timer = "3.0.1"
@@ -24,6 +24,7 @@
use sp_core::Pair;
use sp_consensus_aura::AURA_ENGINE_ID;
use sp_runtime::generic::{DigestItem, OpaqueDigestItemId};
use sp_consensus_slots::Slot;
use codec::{Encode, Codec};
use std::fmt::Debug;
@@ -38,10 +39,10 @@ pub trait CompatibleDigestItem<P: Pair>: Sized {
fn as_aura_seal(&self) -> Option<Signature<P>>;
/// Construct a digest item which contains the slot number
fn aura_pre_digest(slot_num: u64) -> Self;
fn aura_pre_digest(slot: Slot) -> Self;
/// If this item is an AuRa pre-digest, return the slot number
fn as_aura_pre_digest(&self) -> Option<u64>;
fn as_aura_pre_digest(&self) -> Option<Slot>;
}
impl<P, Hash> CompatibleDigestItem<P> for DigestItem<Hash> where
@@ -57,11 +58,11 @@ impl<P, Hash> CompatibleDigestItem<P> for DigestItem<Hash> where
self.try_to(OpaqueDigestItemId::Seal(&AURA_ENGINE_ID))
}
fn aura_pre_digest(slot_num: u64) -> Self {
DigestItem::PreRuntime(AURA_ENGINE_ID, slot_num.encode())
fn aura_pre_digest(slot: Slot) -> Self {
DigestItem::PreRuntime(AURA_ENGINE_ID, slot.encode())
}
fn as_aura_pre_digest(&self) -> Option<u64> {
fn as_aura_pre_digest(&self) -> Option<Slot> {
self.try_to(OpaqueDigestItemId::PreRuntime(&AURA_ENGINE_ID))
}
}
+45 -46
View File
@@ -43,11 +43,11 @@ use prometheus_endpoint::Registry;
use codec::{Encode, Decode, Codec};
use sp_consensus::{
self, BlockImport, Environment, Proposer, CanAuthorWith, ForkChoiceStrategy, BlockImportParams,
BlockOrigin, Error as ConsensusError, SelectChain, SlotData, BlockCheckParams, ImportResult
};
use sp_consensus::import_queue::{
Verifier, BasicQueue, DefaultImportQueue, BoxJustificationImport,
BlockImport, Environment, Proposer, CanAuthorWith, ForkChoiceStrategy, BlockImportParams,
BlockOrigin, Error as ConsensusError, SelectChain, SlotData, BlockCheckParams, ImportResult,
import_queue::{
Verifier, BasicQueue, DefaultImportQueue, BoxJustificationImport,
},
};
use sc_client_api::{backend::AuxStore, BlockOf};
use sp_blockchain::{
@@ -57,10 +57,7 @@ use sp_blockchain::{
use sp_block_builder::BlockBuilder as BlockBuilderApi;
use sp_core::crypto::Public;
use sp_application_crypto::{AppKey, AppPublic};
use sp_runtime::{
generic::{BlockId, OpaqueDigestItemId},
traits::NumberFor, Justification,
};
use sp_runtime::{generic::{BlockId, OpaqueDigestItemId}, traits::NumberFor, Justification};
use sp_runtime::traits::{Block as BlockT, Header, DigestItemFor, Zero, Member};
use sp_api::ProvideRuntimeApi;
use sp_core::crypto::Pair;
@@ -75,6 +72,7 @@ use sc_consensus_slots::{
CheckedHeader, SlotInfo, SlotCompatible, StorageChanges, check_equivocation,
BackoffAuthoringBlocksStrategy,
};
use sp_consensus_slots::Slot;
use sp_api::ApiExt;
@@ -106,10 +104,10 @@ pub fn slot_duration<A, B, C>(client: &C) -> CResult<SlotDuration> where
}
/// Get slot author for given block along with authorities.
fn slot_author<P: Pair>(slot_num: u64, authorities: &[AuthorityId<P>]) -> Option<&AuthorityId<P>> {
fn slot_author<P: Pair>(slot: Slot, authorities: &[AuthorityId<P>]) -> Option<&AuthorityId<P>> {
if authorities.is_empty() { return None }
let idx = slot_num % (authorities.len() as u64);
let idx = *slot % (authorities.len() as u64);
assert!(
idx <= usize::max_value() as u64,
"It is impossible to have a vector with length beyond the address space; qed",
@@ -239,7 +237,7 @@ where
fn epoch_data(
&self,
header: &B::Header,
_slot_number: u64,
_slot: Slot,
) -> Result<Self::EpochData, sp_consensus::Error> {
authorities(self.client.as_ref(), &BlockId::Hash(header.hash()))
}
@@ -251,10 +249,10 @@ where
fn claim_slot(
&self,
_header: &B::Header,
slot_number: u64,
slot: Slot,
epoch_data: &Self::EpochData,
) -> Option<Self::Claim> {
let expected_author = slot_author::<P>(slot_number, epoch_data);
let expected_author = slot_author::<P>(slot, epoch_data);
expected_author.and_then(|p| {
if SyncCryptoStore::has_keys(
&*self.keystore,
@@ -269,11 +267,11 @@ where
fn pre_digest_data(
&self,
slot_number: u64,
slot: Slot,
_claim: &Self::Claim,
) -> Vec<sp_runtime::DigestItem<B::Hash>> {
vec![
<DigestItemFor<B> as CompatibleDigestItem<P>>::aura_pre_digest(slot_number),
<DigestItemFor<B> as CompatibleDigestItem<P>>::aura_pre_digest(slot),
]
}
@@ -323,14 +321,14 @@ where
self.force_authoring
}
fn should_backoff(&self, slot_number: u64, chain_head: &B::Header) -> bool {
fn should_backoff(&self, slot: Slot, chain_head: &B::Header) -> bool {
if let Some(ref strategy) = self.backoff_authoring_blocks {
if let Ok(chain_head_slot) = find_pre_digest::<B, P>(chain_head) {
return strategy.should_backoff(
*chain_head.number(),
chain_head_slot,
self.client.info().finalized_number,
slot_number,
slot,
self.logging_target(),
);
}
@@ -363,9 +361,10 @@ where
if let Some(slot_lenience) =
sc_consensus_slots::slot_lenience_exponential(parent_slot, slot_info)
{
debug!(target: "aura",
debug!(
target: "aura",
"No block for {} slots. Applying linear lenience of {}s",
slot_info.number.saturating_sub(parent_slot + 1),
slot_info.slot.saturating_sub(parent_slot + 1),
slot_lenience.as_secs(),
);
@@ -401,7 +400,7 @@ enum Error<B: BlockT> {
DataProvider(String),
Runtime(String),
#[display(fmt = "Slot number must increase: parent slot: {}, this slot: {}", _0, _1)]
SlotNumberMustIncrease(u64, u64),
SlotMustIncrease(Slot, Slot),
#[display(fmt = "Parent ({}) of {} unavailable. Cannot import", _0, _1)]
ParentUnavailable(B::Hash, B::Hash),
}
@@ -412,16 +411,16 @@ impl<B: BlockT> std::convert::From<Error<B>> for String {
}
}
fn find_pre_digest<B: BlockT, P: Pair>(header: &B::Header) -> Result<u64, Error<B>>
fn find_pre_digest<B: BlockT, P: Pair>(header: &B::Header) -> Result<Slot, Error<B>>
where DigestItemFor<B>: CompatibleDigestItem<P>,
P::Signature: Decode,
P::Public: Encode + Decode + PartialEq + Clone,
{
if header.number().is_zero() {
return Ok(0);
return Ok(0.into());
}
let mut pre_digest: Option<u64> = None;
let mut pre_digest: Option<Slot> = None;
for log in header.digest().logs() {
trace!(target: "aura", "Checking log {:?}", log);
match (log.as_aura_pre_digest(), pre_digest.is_some()) {
@@ -440,11 +439,11 @@ fn find_pre_digest<B: BlockT, P: Pair>(header: &B::Header) -> Result<u64, Error<
//
fn check_header<C, B: BlockT, P: Pair>(
client: &C,
slot_now: u64,
slot_now: Slot,
mut header: B::Header,
hash: B::Hash,
authorities: &[AuthorityId<P>],
) -> Result<CheckedHeader<B::Header, (u64, DigestItemFor<B>)>, Error<B>> where
) -> Result<CheckedHeader<B::Header, (Slot, DigestItemFor<B>)>, Error<B>> where
DigestItemFor<B>: CompatibleDigestItem<P>,
P::Signature: Decode,
C: sc_client_api::backend::AuxStore,
@@ -459,15 +458,15 @@ fn check_header<C, B: BlockT, P: Pair>(
aura_err(Error::HeaderBadSeal(hash))
})?;
let slot_num = find_pre_digest::<B, _>(&header)?;
let slot = find_pre_digest::<B, _>(&header)?;
if slot_num > slot_now {
if slot > slot_now {
header.digest_mut().push(seal);
Ok(CheckedHeader::Deferred(header, slot_num))
Ok(CheckedHeader::Deferred(header, slot))
} else {
// check the signature is valid under the expected authority and
// chain state.
let expected_author = match slot_author::<P>(slot_num, &authorities) {
let expected_author = match slot_author::<P>(slot, &authorities) {
None => return Err(Error::SlotAuthorNotFound),
Some(author) => author,
};
@@ -478,19 +477,19 @@ fn check_header<C, B: BlockT, P: Pair>(
if let Some(equivocation_proof) = check_equivocation(
client,
slot_now,
slot_num,
slot,
&header,
expected_author,
).map_err(Error::Client)? {
info!(
"Slot author is equivocating at slot {} with headers {:?} and {:?}",
slot_num,
slot,
equivocation_proof.first_header.hash(),
equivocation_proof.second_header.hash(),
);
}
Ok(CheckedHeader::Checked(header, (slot_num, seal)))
Ok(CheckedHeader::Checked(header, (slot, seal)))
} else {
Err(Error::BadSignature(hash))
}
@@ -614,12 +613,12 @@ impl<B: BlockT, C, P, CAW> Verifier<B> for AuraVerifier<C, P, CAW> where
&authorities[..],
).map_err(|e| e.to_string())?;
match checked_header {
CheckedHeader::Checked(pre_header, (slot_num, seal)) => {
CheckedHeader::Checked(pre_header, (slot, seal)) => {
// if the body is passed through, we need to use the runtime
// 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() {
inherent_data.aura_replace_inherent_data(slot_num);
inherent_data.aura_replace_inherent_data(slot);
let block = B::new(pre_header.clone(), inner_body);
// skip the inherents verification if the runtime API is old.
@@ -803,7 +802,7 @@ impl<Block: BlockT, C, I, P> BlockImport<Block> for AuraBlockImport<Block, C, I,
new_cache: HashMap<CacheKeyId, Vec<u8>>,
) -> Result<ImportResult, Self::Error> {
let hash = block.post_hash();
let slot_number = find_pre_digest::<Block, P>(&block.header)
let slot = find_pre_digest::<Block, P>(&block.header)
.expect("valid Aura headers must contain a predigest; \
header has been already verified; qed");
@@ -819,10 +818,10 @@ impl<Block: BlockT, C, I, P> BlockImport<Block> for AuraBlockImport<Block, C, I,
parent header has already been verified; qed");
// make sure that slot number is strictly increasing
if slot_number <= parent_slot {
if slot <= parent_slot {
return Err(
ConsensusError::ClientImport(aura_err(
Error::<Block>::SlotNumberMustIncrease(parent_slot, slot_number)
Error::<Block>::SlotMustIncrease(parent_slot, slot)
).into())
);
}
@@ -1113,13 +1112,13 @@ mod tests {
Default::default(),
Default::default()
);
assert!(worker.claim_slot(&head, 0, &authorities).is_none());
assert!(worker.claim_slot(&head, 1, &authorities).is_none());
assert!(worker.claim_slot(&head, 2, &authorities).is_none());
assert!(worker.claim_slot(&head, 3, &authorities).is_some());
assert!(worker.claim_slot(&head, 4, &authorities).is_none());
assert!(worker.claim_slot(&head, 5, &authorities).is_none());
assert!(worker.claim_slot(&head, 6, &authorities).is_none());
assert!(worker.claim_slot(&head, 7, &authorities).is_some());
assert!(worker.claim_slot(&head, 0.into(), &authorities).is_none());
assert!(worker.claim_slot(&head, 1.into(), &authorities).is_none());
assert!(worker.claim_slot(&head, 2.into(), &authorities).is_none());
assert!(worker.claim_slot(&head, 3.into(), &authorities).is_some());
assert!(worker.claim_slot(&head, 4.into(), &authorities).is_none());
assert!(worker.claim_slot(&head, 5.into(), &authorities).is_none());
assert!(worker.claim_slot(&head, 6.into(), &authorities).is_none());
assert!(worker.claim_slot(&head, 7.into(), &authorities).is_some());
}
}
@@ -35,6 +35,7 @@ sp-api = { version = "2.0.0", path = "../../../primitives/api" }
sp-block-builder = { version = "2.0.0", path = "../../../primitives/block-builder" }
sp-blockchain = { version = "2.0.0", path = "../../../primitives/blockchain" }
sp-consensus = { version = "0.8.0", path = "../../../primitives/consensus/common" }
sp-consensus-slots = { version = "0.8.0", path = "../../../primitives/consensus/slots" }
sp-consensus-vrf = { version = "0.8.0", path = "../../../primitives/consensus/vrf" }
sc-consensus-uncles = { version = "0.8.0", path = "../uncles" }
sc-consensus-slots = { version = "0.8.0", path = "../slots" }
+16 -10
View File
@@ -124,7 +124,13 @@ impl<B, C, SC> BabeApi for BabeRpcHandler<B, C, SC>
.map_err(|err| {
Error::StringError(format!("{:?}", err))
})?;
let epoch = epoch_data(&shared_epoch, &client, &babe_config, epoch_start, &select_chain)?;
let epoch = epoch_data(
&shared_epoch,
&client,
&babe_config,
*epoch_start,
&select_chain,
)?;
let (epoch_start, epoch_end) = (epoch.start_slot(), epoch.end_slot());
let mut claims: HashMap<AuthorityId, EpochAuthorship> = HashMap::new();
@@ -142,19 +148,19 @@ impl<B, C, SC> BabeApi for BabeRpcHandler<B, C, SC>
.collect::<Vec<_>>()
};
for slot_number in epoch_start..epoch_end {
for slot in *epoch_start..*epoch_end {
if let Some((claim, key)) =
authorship::claim_slot_using_keys(slot_number, &epoch, &keystore, &keys)
authorship::claim_slot_using_keys(slot.into(), &epoch, &keystore, &keys)
{
match claim {
PreDigest::Primary { .. } => {
claims.entry(key).or_default().primary.push(slot_number);
claims.entry(key).or_default().primary.push(slot);
}
PreDigest::SecondaryPlain { .. } => {
claims.entry(key).or_default().secondary.push(slot_number);
claims.entry(key).or_default().secondary.push(slot);
}
PreDigest::SecondaryVRF { .. } => {
claims.entry(key).or_default().secondary_vrf.push(slot_number);
claims.entry(key).or_default().secondary_vrf.push(slot.into());
},
};
}
@@ -167,7 +173,7 @@ impl<B, C, SC> BabeApi for BabeRpcHandler<B, C, SC>
}
}
/// Holds information about the `slot_number`'s that can be claimed by a given key.
/// Holds information about the `slot`'s that can be claimed by a given key.
#[derive(Default, Debug, Deserialize, Serialize)]
pub struct EpochAuthorship {
/// the array of primary slots that can be claimed
@@ -197,12 +203,12 @@ impl From<Error> for jsonrpc_core::Error {
}
}
/// fetches the epoch data for a given slot_number.
/// fetches the epoch data for a given slot.
fn epoch_data<B, C, SC>(
epoch_changes: &SharedEpochChanges<B, Epoch>,
client: &Arc<C>,
babe_config: &Config,
slot_number: u64,
slot: u64,
select_chain: &SC,
) -> Result<Epoch, Error>
where
@@ -215,7 +221,7 @@ fn epoch_data<B, C, SC>(
descendent_query(&**client),
&parent.hash(),
parent.number().clone(),
slot_number,
slot.into(),
|slot| Epoch::genesis(&babe_config, slot),
)
.map_err(|e| Error::Consensus(ConsensusError::ChainLookup(format!("{:?}", e))))?
@@ -20,11 +20,8 @@
use sp_application_crypto::AppKey;
use sp_consensus_babe::{
BABE_VRF_PREFIX,
AuthorityId, BabeAuthorityWeight,
SlotNumber,
make_transcript,
make_transcript_data,
BABE_VRF_PREFIX, AuthorityId, BabeAuthorityWeight, make_transcript, make_transcript_data,
Slot,
};
use sp_consensus_babe::digests::{
PreDigest, PrimaryPreDigest, SecondaryPlainPreDigest, SecondaryVRFPreDigest,
@@ -106,7 +103,7 @@ pub(super) fn check_primary_threshold(inout: &VRFInOut, threshold: u128) -> bool
/// authorities. This should always assign the slot to some authority unless the
/// authorities list is empty.
pub(super) fn secondary_slot_author(
slot_number: u64,
slot: Slot,
authorities: &[(AuthorityId, BabeAuthorityWeight)],
randomness: [u8; 32],
) -> Option<&AuthorityId> {
@@ -114,7 +111,7 @@ pub(super) fn secondary_slot_author(
return None;
}
let rand = U256::from((randomness, slot_number).using_encoded(blake2_256));
let rand = U256::from((randomness, slot).using_encoded(blake2_256));
let authorities_len = U256::from(authorities.len());
let idx = rand % authorities_len;
@@ -130,7 +127,7 @@ pub(super) fn secondary_slot_author(
/// pre-digest to use when authoring the block, or `None` if it is not our turn
/// to propose.
fn claim_secondary_slot(
slot_number: SlotNumber,
slot: Slot,
epoch: &Epoch,
keys: &[(AuthorityId, usize)],
keystore: &SyncCryptoStorePtr,
@@ -143,7 +140,7 @@ fn claim_secondary_slot(
}
let expected_author = super::authorship::secondary_slot_author(
slot_number,
slot,
authorities,
*randomness,
)?;
@@ -153,7 +150,7 @@ fn claim_secondary_slot(
let pre_digest = if author_secondary_vrf {
let transcript_data = super::authorship::make_transcript_data(
randomness,
slot_number,
slot,
*epoch_index,
);
let result = SyncCryptoStore::sr25519_vrf_sign(
@@ -164,7 +161,7 @@ fn claim_secondary_slot(
);
if let Ok(signature) = result {
Some(PreDigest::SecondaryVRF(SecondaryVRFPreDigest {
slot_number,
slot,
vrf_output: VRFOutput(signature.output),
vrf_proof: VRFProof(signature.proof),
authority_index: *authority_index as u32,
@@ -174,7 +171,7 @@ fn claim_secondary_slot(
}
} else if SyncCryptoStore::has_keys(&**keystore, &[(authority_id.to_raw_vec(), AuthorityId::ID)]) {
Some(PreDigest::SecondaryPlain(SecondaryPlainPreDigest {
slot_number,
slot,
authority_index: *authority_index as u32,
}))
} else {
@@ -195,7 +192,7 @@ fn claim_secondary_slot(
/// secondary slots enabled for the given epoch, we will fallback to trying to
/// claim a secondary slot.
pub fn claim_slot(
slot_number: SlotNumber,
slot: Slot,
epoch: &Epoch,
keystore: &SyncCryptoStorePtr,
) -> Option<(PreDigest, AuthorityId)> {
@@ -203,24 +200,24 @@ pub fn claim_slot(
.enumerate()
.map(|(index, a)| (a.0.clone(), index))
.collect::<Vec<_>>();
claim_slot_using_keys(slot_number, epoch, keystore, &authorities)
claim_slot_using_keys(slot, epoch, keystore, &authorities)
}
/// Like `claim_slot`, but allows passing an explicit set of key pairs. Useful if we intend
/// to make repeated calls for different slots using the same key pairs.
pub fn claim_slot_using_keys(
slot_number: SlotNumber,
slot: Slot,
epoch: &Epoch,
keystore: &SyncCryptoStorePtr,
keys: &[(AuthorityId, usize)],
) -> Option<(PreDigest, AuthorityId)> {
claim_primary_slot(slot_number, epoch, epoch.config.c, keystore, &keys)
claim_primary_slot(slot, epoch, epoch.config.c, keystore, &keys)
.or_else(|| {
if epoch.config.allowed_slots.is_secondary_plain_slots_allowed() ||
epoch.config.allowed_slots.is_secondary_vrf_slots_allowed()
{
claim_secondary_slot(
slot_number,
slot,
&epoch,
keys,
&keystore,
@@ -237,7 +234,7 @@ pub fn claim_slot_using_keys(
/// the VRF. If the VRF produces a value less than `threshold`, it is our turn,
/// so it returns `Some(_)`. Otherwise, it returns `None`.
fn claim_primary_slot(
slot_number: SlotNumber,
slot: Slot,
epoch: &Epoch,
c: (u64, u64),
keystore: &SyncCryptoStorePtr,
@@ -248,12 +245,12 @@ fn claim_primary_slot(
for (authority_id, authority_index) in keys {
let transcript = super::authorship::make_transcript(
randomness,
slot_number,
slot,
*epoch_index
);
let transcript_data = super::authorship::make_transcript_data(
randomness,
slot_number,
slot,
*epoch_index
);
// Compute the threshold we will use.
@@ -276,7 +273,7 @@ fn claim_primary_slot(
};
if super::authorship::check_primary_threshold(&inout, threshold) {
let pre_digest = PreDigest::Primary(PrimaryPreDigest {
slot_number,
slot,
vrf_output: VRFOutput(signature.output),
vrf_proof: VRFProof(signature.proof),
authority_index: *authority_index as u32,
@@ -314,7 +311,7 @@ mod tests {
let mut epoch = Epoch {
epoch_index: 10,
start_slot: 0,
start_slot: 0.into(),
duration: 20,
authorities: authorities.clone(),
randomness: Default::default(),
@@ -324,9 +321,9 @@ mod tests {
},
};
assert!(claim_slot(10, &epoch, &keystore).is_none());
assert!(claim_slot(10.into(), &epoch, &keystore).is_none());
epoch.authorities.push((valid_public_key.clone().into(), 10));
assert_eq!(claim_slot(10, &epoch, &keystore).unwrap().1, valid_public_key.into());
assert_eq!(claim_slot(10.into(), &epoch, &keystore).unwrap().1, valid_public_key.into());
}
}
@@ -151,7 +151,7 @@ mod test {
#[test]
fn load_decode_from_v0_epoch_changes() {
let epoch = EpochV0 {
start_slot: 0,
start_slot: 0.into(),
authorities: vec![],
randomness: [0; 32],
epoch_index: 1,
@@ -195,8 +195,8 @@ mod test {
.map(|(_, _, epoch)| epoch.clone())
.collect::<Vec<_>>() ==
vec![PersistedEpochHeader::Regular(EpochHeader {
start_slot: 0,
end_slot: 100,
start_slot: 0.into(),
end_slot: 100.into(),
})],
); // PersistedEpochHeader does not implement Debug, so we use assert! directly.
+54 -56
View File
@@ -66,10 +66,8 @@
#![forbid(unsafe_code)]
#![warn(missing_docs)]
pub use sp_consensus_babe::{
BabeApi, ConsensusLog, BABE_ENGINE_ID, SlotNumber,
BabeEpochConfiguration, BabeGenesisConfiguration,
AuthorityId, AuthorityPair, AuthoritySignature,
BabeAuthorityWeight, VRF_OUTPUT_LENGTH,
BabeApi, ConsensusLog, BABE_ENGINE_ID, BabeEpochConfiguration, BabeGenesisConfiguration,
AuthorityId, AuthorityPair, AuthoritySignature, BabeAuthorityWeight, VRF_OUTPUT_LENGTH,
digests::{
CompatibleDigestItem, NextEpochDescriptor, NextConfigDescriptor, PreDigest,
PrimaryPreDigest, SecondaryPlainPreDigest,
@@ -80,8 +78,7 @@ use std::{
collections::HashMap, sync::Arc, u64, pin::Pin, time::{Instant, Duration},
any::Any, borrow::Cow, convert::TryInto,
};
use sp_consensus::{ImportResult, CanAuthorWith};
use sp_consensus::import_queue::BoxJustificationImport;
use sp_consensus::{ImportResult, CanAuthorWith, import_queue::BoxJustificationImport};
use sp_core::crypto::Public;
use sp_application_crypto::AppKey;
use sp_keystore::{SyncCryptoStorePtr, SyncCryptoStore};
@@ -94,16 +91,14 @@ use parking_lot::Mutex;
use sp_inherents::{InherentDataProviders, InherentData};
use sc_telemetry::{telemetry, CONSENSUS_TRACE, CONSENSUS_DEBUG};
use sp_consensus::{
self, BlockImport, Environment, Proposer, BlockCheckParams,
BlockImport, Environment, Proposer, BlockCheckParams,
ForkChoiceStrategy, BlockImportParams, BlockOrigin, Error as ConsensusError,
SelectChain, SlotData,
SelectChain, SlotData, import_queue::{Verifier, BasicQueue, DefaultImportQueue, CacheKeyId},
};
use sp_consensus_babe::inherents::BabeInherentData;
use sp_timestamp::{TimestampInherentData, InherentType as TimestampInherent};
use sp_consensus::import_queue::{Verifier, BasicQueue, DefaultImportQueue, CacheKeyId};
use sc_client_api::{
backend::AuxStore,
BlockchainEvents, ProvideUncles,
backend::AuxStore, BlockchainEvents, ProvideUncles,
};
use sp_block_builder::BlockBuilder as BlockBuilderApi;
use futures::channel::mpsc::{channel, Sender, Receiver};
@@ -114,7 +109,7 @@ use log::{debug, info, log, trace, warn};
use prometheus_endpoint::Registry;
use sc_consensus_slots::{
SlotInfo, SlotCompatible, StorageChanges, CheckedHeader, check_equivocation,
BackoffAuthoringBlocksStrategy,
BackoffAuthoringBlocksStrategy
};
use sc_consensus_epochs::{
descendent_query, SharedEpochChanges, EpochChangesFor, Epoch as EpochT, ViableEpochDescriptor,
@@ -126,6 +121,7 @@ use sp_blockchain::{
use schnorrkel::SignatureError;
use codec::{Encode, Decode};
use sp_api::ApiExt;
use sp_consensus_slots::Slot;
mod verification;
mod migration;
@@ -141,9 +137,9 @@ pub struct Epoch {
/// The epoch index.
pub epoch_index: u64,
/// The starting slot of the epoch.
pub start_slot: SlotNumber,
pub start_slot: Slot,
/// The duration of this epoch.
pub duration: SlotNumber,
pub duration: u64,
/// The authorities and their weights.
pub authorities: Vec<(AuthorityId, BabeAuthorityWeight)>,
/// Randomness for this epoch.
@@ -154,7 +150,7 @@ pub struct Epoch {
impl EpochT for Epoch {
type NextEpochDescriptor = (NextEpochDescriptor, BabeEpochConfiguration);
type SlotNumber = SlotNumber;
type Slot = Slot;
fn increment(
&self,
@@ -170,11 +166,11 @@ impl EpochT for Epoch {
}
}
fn start_slot(&self) -> SlotNumber {
fn start_slot(&self) -> Slot {
self.start_slot
}
fn end_slot(&self) -> SlotNumber {
fn end_slot(&self) -> Slot {
self.start_slot + self.duration
}
}
@@ -184,11 +180,11 @@ impl Epoch {
/// the first block, so that has to be provided.
pub fn genesis(
genesis_config: &BabeGenesisConfiguration,
slot_number: SlotNumber
slot: Slot,
) -> Epoch {
Epoch {
epoch_index: 0,
start_slot: slot_number,
start_slot: slot,
duration: genesis_config.epoch_length,
authorities: genesis_config.genesis_authorities.clone(),
randomness: genesis_config.randomness,
@@ -229,7 +225,7 @@ pub enum Error<B: BlockT> {
ParentUnavailable(B::Hash, B::Hash),
/// Slot number must increase
#[display(fmt = "Slot number must increase: parent slot: {}, this slot: {}", _0, _1)]
SlotNumberMustIncrease(u64, u64),
SlotMustIncrease(Slot, Slot),
/// Header has a bad seal
#[display(fmt = "Header {:?} has a bad seal", _0)]
HeaderBadSeal(B::Hash),
@@ -262,7 +258,7 @@ pub enum Error<B: BlockT> {
FetchParentHeader(sp_blockchain::Error),
/// Expected epoch change to happen.
#[display(fmt = "Expected epoch change to happen at {:?}, s{}", _0, _1)]
ExpectedEpochChange(B::Hash, u64),
ExpectedEpochChange(B::Hash, Slot),
/// Unexpected config change.
#[display(fmt = "Unexpected config change")]
UnexpectedConfigChange,
@@ -471,7 +467,7 @@ pub fn start_babe<B, C, SC, E, I, SO, CAW, BS, Error>(BabeParams {
#[must_use]
pub struct BabeWorker<B: BlockT> {
inner: Pin<Box<dyn futures::Future<Output=()> + Send + 'static>>,
slot_notification_sinks: Arc<Mutex<Vec<Sender<(u64, ViableEpochDescriptor<B::Hash, NumberFor<B>, Epoch>)>>>>,
slot_notification_sinks: SlotNotificationSinks<B>,
}
impl<B: BlockT> BabeWorker<B> {
@@ -479,7 +475,7 @@ impl<B: BlockT> BabeWorker<B> {
/// epoch descriptor.
pub fn slot_notification_stream(
&self
) -> Receiver<(u64, ViableEpochDescriptor<B::Hash, NumberFor<B>, Epoch>)> {
) -> Receiver<(Slot, ViableEpochDescriptor<B::Hash, NumberFor<B>, Epoch>)> {
const CHANNEL_BUFFER_SIZE: usize = 1024;
let (sink, stream) = channel(CHANNEL_BUFFER_SIZE);
@@ -500,7 +496,9 @@ impl<B: BlockT> futures::Future for BabeWorker<B> {
}
/// Slot notification sinks.
type SlotNotificationSinks<B> = Arc<Mutex<Vec<Sender<(u64, ViableEpochDescriptor<<B as BlockT>::Hash, NumberFor<B>, Epoch>)>>>>;
type SlotNotificationSinks<B> = Arc<
Mutex<Vec<Sender<(Slot, ViableEpochDescriptor<<B as BlockT>::Hash, NumberFor<B>, Epoch>)>>>
>;
struct BabeSlotWorker<B: BlockT, C, E, I, SO, BS> {
client: Arc<C>,
@@ -551,13 +549,13 @@ where
fn epoch_data(
&self,
parent: &B::Header,
slot_number: u64,
slot: Slot,
) -> Result<Self::EpochData, ConsensusError> {
self.epoch_changes.lock().epoch_descriptor_for_child_of(
descendent_query(&*self.client),
&parent.hash(),
parent.number().clone(),
slot_number,
slot,
)
.map_err(|e| ConsensusError::ChainLookup(format!("{:?}", e)))?
.ok_or(sp_consensus::Error::InvalidAuthoritiesSet)
@@ -572,12 +570,12 @@ where
fn claim_slot(
&self,
_parent_header: &B::Header,
slot_number: SlotNumber,
slot: Slot,
epoch_descriptor: &ViableEpochDescriptor<B::Hash, NumberFor<B>, Epoch>,
) -> Option<Self::Claim> {
debug!(target: "babe", "Attempting to claim slot {}", slot_number);
debug!(target: "babe", "Attempting to claim slot {}", slot);
let s = authorship::claim_slot(
slot_number,
slot,
self.epoch_changes.lock().viable_epoch(
&epoch_descriptor,
|slot| Epoch::genesis(&self.config, slot)
@@ -586,7 +584,7 @@ where
);
if s.is_some() {
debug!(target: "babe", "Claimed slot {}", slot_number);
debug!(target: "babe", "Claimed slot {}", slot);
}
s
@@ -595,12 +593,12 @@ where
fn notify_slot(
&self,
_parent_header: &B::Header,
slot_number: SlotNumber,
slot: Slot,
epoch_descriptor: &ViableEpochDescriptor<B::Hash, NumberFor<B>, Epoch>,
) {
self.slot_notification_sinks.lock()
.retain_mut(|sink| {
match sink.try_send((slot_number, epoch_descriptor.clone())) {
match sink.try_send((slot, epoch_descriptor.clone())) {
Ok(()) => true,
Err(e) => {
if e.is_full() {
@@ -616,7 +614,7 @@ where
fn pre_digest_data(
&self,
_slot_number: u64,
_slot: Slot,
claim: &Self::Claim,
) -> Vec<sp_runtime::DigestItem<B::Hash>> {
vec![
@@ -673,16 +671,16 @@ where
self.force_authoring
}
fn should_backoff(&self, slot_number: u64, chain_head: &B::Header) -> bool {
fn should_backoff(&self, slot: Slot, chain_head: &B::Header) -> bool {
if let Some(ref strategy) = self.backoff_authoring_blocks {
if let Ok(chain_head_slot) = find_pre_digest::<B>(chain_head)
.map(|digest| digest.slot_number())
.map(|digest| digest.slot())
{
return strategy.should_backoff(
*chain_head.number(),
chain_head_slot,
self.client.info().finalized_number,
slot_number,
slot,
self.logging_target(),
);
}
@@ -714,7 +712,7 @@ where
let parent_slot = match find_pre_digest::<B>(parent_head) {
Err(_) => return Some(slot_remaining),
Ok(d) => d.slot_number(),
Ok(d) => d.slot(),
};
if let Some(slot_lenience) =
@@ -723,7 +721,7 @@ where
debug!(
target: "babe",
"No block for {} slots. Applying exponential lenience of {}s",
slot_info.number.saturating_sub(parent_slot + 1),
slot_info.slot.saturating_sub(parent_slot + 1),
slot_lenience.as_secs(),
);
@@ -741,7 +739,7 @@ pub fn find_pre_digest<B: BlockT>(header: &B::Header) -> Result<PreDigest, Error
// dummy one to not break any invariants in the rest of the code
if header.number().is_zero() {
return Ok(PreDigest::SecondaryPlain(SecondaryPlainPreDigest {
slot_number: 0,
slot: 0.into(),
authority_index: 0,
}));
}
@@ -803,7 +801,7 @@ impl SlotCompatible for TimeSource {
fn extract_timestamp_and_slot(
&self,
data: &InherentData,
) -> Result<(TimestampInherent, u64, std::time::Duration), sp_consensus::Error> {
) -> Result<(TimestampInherent, 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)))
@@ -888,8 +886,8 @@ where
fn check_and_report_equivocation(
&self,
slot_now: SlotNumber,
slot: SlotNumber,
slot_now: Slot,
slot: Slot,
header: &Block::Header,
author: &AuthorityId,
origin: &BlockOrigin,
@@ -1014,7 +1012,7 @@ where
descendent_query(&*self.client),
&parent_hash,
parent_header_metadata.number,
pre_digest.slot_number(),
pre_digest.slot(),
)
.map_err(|e| Error::<Block>::ForkTree(Box::new(e)))?
.ok_or_else(|| Error::<Block>::FetchEpoch(parent_hash))?;
@@ -1036,14 +1034,14 @@ where
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");
let slot_number = babe_pre_digest.slot_number();
let slot = babe_pre_digest.slot();
// the header is valid but let's check if there was something else already
// proposed at the same slot by the given author. if there was, we will
// report the equivocation to the runtime.
if let Err(err) = self.check_and_report_equivocation(
slot_now,
slot_number,
slot,
&header,
&verified_info.author,
&origin,
@@ -1055,7 +1053,7 @@ 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() {
inherent_data.babe_replace_inherent_data(slot_number);
inherent_data.babe_replace_inherent_data(slot);
let block = Block::new(pre_header.clone(), inner_body);
self.check_inherents(
@@ -1185,7 +1183,7 @@ impl<Block, Client, Inner> BlockImport<Block> for BabeBlockImport<Block, Client,
let pre_digest = find_pre_digest::<Block>(&block.header)
.expect("valid babe headers must contain a predigest; \
header has been already verified; qed");
let slot_number = pre_digest.slot_number();
let slot = pre_digest.slot();
let parent_hash = *block.header.parent_hash();
let parent_header = self.client.header(BlockId::Hash(parent_hash))
@@ -1195,15 +1193,15 @@ impl<Block, Client, Inner> BlockImport<Block> for BabeBlockImport<Block, Client,
).into()))?;
let parent_slot = find_pre_digest::<Block>(&parent_header)
.map(|d| d.slot_number())
.map(|d| d.slot())
.expect("parent is non-genesis; valid BABE headers contain a pre-digest; \
header has already been verified; qed");
// make sure that slot number is strictly increasing
if slot_number <= parent_slot {
if slot <= parent_slot {
return Err(
ConsensusError::ClientImport(babe_err(
Error::<Block>::SlotNumberMustIncrease(parent_slot, slot_number)
Error::<Block>::SlotMustIncrease(parent_slot, slot)
).into())
);
}
@@ -1256,7 +1254,7 @@ impl<Block, Client, Inner> BlockImport<Block> for BabeBlockImport<Block, Client,
(true, false, _) => {
return Err(
ConsensusError::ClientImport(
babe_err(Error::<Block>::ExpectedEpochChange(hash, slot_number)).into(),
babe_err(Error::<Block>::ExpectedEpochChange(hash, slot)).into(),
)
)
},
@@ -1301,7 +1299,7 @@ impl<Block, Client, Inner> BlockImport<Block> for BabeBlockImport<Block, Client,
"👶 New epoch {} launching at block {} (block slot {} >= start slot {}).",
viable_epoch.as_ref().epoch_index,
hash,
slot_number,
slot,
viable_epoch.as_ref().start_slot,
);
@@ -1426,7 +1424,7 @@ fn prune_finalized<Block, Client>(
find_pre_digest::<Block>(&finalized_header)
.expect("finalized header must be valid; \
valid blocks have a pre-digest; qed")
.slot_number()
.slot()
};
epoch_changes.prune_finalized(
@@ -1533,7 +1531,7 @@ pub mod test_helpers {
/// Try to claim the given slot and return a `BabePreDigest` if
/// successful.
pub fn claim_slot<B, C>(
slot_number: u64,
slot: Slot,
parent: &B::Header,
client: &C,
keystore: SyncCryptoStorePtr,
@@ -1551,12 +1549,12 @@ pub mod test_helpers {
descendent_query(client),
&parent.hash(),
parent.number().clone(),
slot_number,
slot,
|slot| Epoch::genesis(&link.config, slot),
).unwrap().unwrap();
authorship::claim_slot(
slot_number,
slot,
&epoch,
&keystore,
).map(|(digest, _)| digest)
@@ -1,9 +1,28 @@
// This file is part of Substrate.
// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use codec::{Encode, Decode};
use sc_consensus_epochs::Epoch as EpochT;
use crate::{
Epoch, SlotNumber, AuthorityId, BabeAuthorityWeight, BabeGenesisConfiguration,
Epoch, AuthorityId, BabeAuthorityWeight, BabeGenesisConfiguration,
BabeEpochConfiguration, VRF_OUTPUT_LENGTH, NextEpochDescriptor,
};
use sp_consensus_slots::Slot;
/// BABE epoch information, version 0.
#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug)]
@@ -11,9 +30,9 @@ pub struct EpochV0 {
/// The epoch index.
pub epoch_index: u64,
/// The starting slot of the epoch.
pub start_slot: SlotNumber,
pub start_slot: Slot,
/// The duration of this epoch.
pub duration: SlotNumber,
pub duration: u64,
/// The authorities and their weights.
pub authorities: Vec<(AuthorityId, BabeAuthorityWeight)>,
/// Randomness for this epoch.
@@ -22,7 +41,7 @@ pub struct EpochV0 {
impl EpochT for EpochV0 {
type NextEpochDescriptor = NextEpochDescriptor;
type SlotNumber = SlotNumber;
type Slot = Slot;
fn increment(
&self,
@@ -37,11 +56,11 @@ impl EpochT for EpochV0 {
}
}
fn start_slot(&self) -> SlotNumber {
fn start_slot(&self) -> Slot {
self.start_slot
}
fn end_slot(&self) -> SlotNumber {
fn end_slot(&self) -> Slot {
self.start_slot + self.duration
}
}
+20 -26
View File
@@ -28,13 +28,7 @@ use sp_keystore::{
SyncCryptoStore,
vrf::make_transcript as transcript_from_data,
};
use sp_consensus_babe::{
AuthorityPair,
SlotNumber,
AllowedSlots,
make_transcript,
make_transcript_data,
};
use sp_consensus_babe::{AuthorityPair, Slot, AllowedSlots, make_transcript, make_transcript_data};
use sc_consensus_slots::BackoffAuthoringOnFinalizedHeadLagging;
use sc_block_builder::{BlockBuilder, BlockBuilderProvider};
use sp_consensus::{
@@ -87,7 +81,7 @@ struct DummyProposer {
factory: DummyFactory,
parent_hash: Hash,
parent_number: u64,
parent_slot: SlotNumber,
parent_slot: Slot,
}
impl Environment<TestBlock> for DummyFactory {
@@ -101,7 +95,7 @@ impl Environment<TestBlock> for DummyFactory {
let parent_slot = crate::find_pre_digest::<TestBlock>(parent_header)
.expect("parent header has a pre-digest")
.slot_number();
.slot();
future::ready(Ok(DummyProposer {
factory: self.clone(),
@@ -137,7 +131,7 @@ impl DummyProposer {
let this_slot = crate::find_pre_digest::<TestBlock>(block.header())
.expect("baked block has valid pre-digest")
.slot_number();
.slot();
// figure out if we should add a consensus digest, since the test runtime
// doesn't.
@@ -529,7 +523,7 @@ fn can_author_block() {
let mut i = 0;
let epoch = Epoch {
start_slot: 0,
start_slot: 0.into(),
authorities: vec![(public.into(), 1)],
randomness: [0; 32],
epoch_index: 1,
@@ -550,7 +544,7 @@ fn can_author_block() {
};
// with secondary slots enabled it should never be empty
match claim_slot(i, &epoch, &keystore) {
match claim_slot(i.into(), &epoch, &keystore) {
None => i += 1,
Some(s) => debug!(target: "babe", "Authored block {:?}", s.0),
}
@@ -559,7 +553,7 @@ fn can_author_block() {
// of times.
config.allowed_slots = AllowedSlots::PrimarySlots;
loop {
match claim_slot(i, &epoch, &keystore) {
match claim_slot(i.into(), &epoch, &keystore) {
None => i += 1,
Some(s) => {
debug!(target: "babe", "Authored block {:?}", s.0);
@@ -572,15 +566,15 @@ fn can_author_block() {
// Propose and import a new BABE block on top of the given parent.
fn propose_and_import_block<Transaction>(
parent: &TestHeader,
slot_number: Option<SlotNumber>,
slot: Option<Slot>,
proposer_factory: &mut DummyFactory,
block_import: &mut BoxBlockImport<TestBlock, Transaction>,
) -> sp_core::H256 {
let mut proposer = futures::executor::block_on(proposer_factory.init(parent)).unwrap();
let slot_number = slot_number.unwrap_or_else(|| {
let slot = slot.unwrap_or_else(|| {
let parent_pre_digest = find_pre_digest::<TestBlock>(parent).unwrap();
parent_pre_digest.slot_number() + 1
parent_pre_digest.slot() + 1
});
let pre_digest = sp_runtime::generic::Digest {
@@ -588,7 +582,7 @@ fn propose_and_import_block<Transaction>(
Item::babe_pre_digest(
PreDigest::SecondaryPlain(SecondaryPlainPreDigest {
authority_index: 0,
slot_number,
slot,
}),
),
],
@@ -602,7 +596,7 @@ fn propose_and_import_block<Transaction>(
descendent_query(&*proposer_factory.client),
&parent_hash,
*parent.number(),
slot_number,
slot,
).unwrap().unwrap();
let seal = {
@@ -660,19 +654,19 @@ fn importing_block_one_sets_genesis_epoch() {
let block_hash = propose_and_import_block(
&genesis_header,
Some(999),
Some(999.into()),
&mut proposer_factory,
&mut block_import,
);
let genesis_epoch = Epoch::genesis(&data.link.config, 999);
let genesis_epoch = Epoch::genesis(&data.link.config, 999.into());
let epoch_changes = data.link.epoch_changes.lock();
let epoch_for_second_block = epoch_changes.epoch_data_for_child_of(
descendent_query(&*client),
&block_hash,
1,
1000,
1000.into(),
|slot| Epoch::genesis(&data.link.config, slot),
).unwrap().unwrap();
@@ -809,7 +803,7 @@ fn verify_slots_are_strictly_increasing() {
// we should have no issue importing this block
let b1 = propose_and_import_block(
&genesis_header,
Some(999),
Some(999.into()),
&mut proposer_factory,
&mut block_import,
);
@@ -820,7 +814,7 @@ fn verify_slots_are_strictly_increasing() {
// we will panic due to the `PanickingBlockImport` defined above.
propose_and_import_block(
&b1,
Some(999),
Some(999.into()),
&mut proposer_factory,
&mut block_import,
);
@@ -836,7 +830,7 @@ fn babe_transcript_generation_match() {
.expect("Generates authority pair");
let epoch = Epoch {
start_slot: 0,
start_slot: 0.into(),
authorities: vec![(public.into(), 1)],
randomness: [0; 32],
epoch_index: 1,
@@ -847,8 +841,8 @@ fn babe_transcript_generation_match() {
},
};
let orig_transcript = make_transcript(&epoch.randomness.clone(), 1, epoch.epoch_index);
let new_transcript = make_transcript_data(&epoch.randomness, 1, epoch.epoch_index);
let orig_transcript = make_transcript(&epoch.randomness.clone(), 1.into(), epoch.epoch_index);
let new_transcript = make_transcript_data(&epoch.randomness, 1.into(), epoch.epoch_index);
let test = |t: merlin::Transcript| -> [u8; 16] {
let mut b = [0u8; 16];
@@ -19,12 +19,13 @@
//! Verification for BABE headers.
use sp_runtime::{traits::Header, traits::DigestItemFor};
use sp_core::{Pair, Public};
use sp_consensus_babe::{make_transcript, AuthoritySignature, SlotNumber, AuthorityPair, AuthorityId};
use sp_consensus_babe::{make_transcript, AuthoritySignature, AuthorityPair, AuthorityId};
use sp_consensus_babe::digests::{
PreDigest, PrimaryPreDigest, SecondaryPlainPreDigest, SecondaryVRFPreDigest,
CompatibleDigestItem
};
use sc_consensus_slots::CheckedHeader;
use sp_consensus_slots::Slot;
use log::{debug, trace};
use super::{find_pre_digest, babe_err, Epoch, BlockT, Error};
use super::authorship::{calculate_primary_threshold, check_primary_threshold, secondary_slot_author};
@@ -38,7 +39,7 @@ pub(super) struct VerificationParams<'a, B: 'a + BlockT> {
/// work.
pub(super) pre_digest: Option<PreDigest>,
/// The slot number of the current time.
pub(super) slot_now: SlotNumber,
pub(super) slot_now: Slot,
/// Epoch descriptor of the epoch this block _should_ be under, if it's valid.
pub(super) epoch: &'a Epoch,
}
@@ -83,9 +84,9 @@ pub(super) fn check_header<B: BlockT + Sized>(
// and that's what we sign
let pre_hash = header.hash();
if pre_digest.slot_number() > slot_now {
if pre_digest.slot() > slot_now {
header.digest_mut().push(seal);
return Ok(CheckedHeader::Deferred(header, pre_digest.slot_number()));
return Ok(CheckedHeader::Deferred(header, pre_digest.slot()));
}
let author = match authorities.get(pre_digest.authority_index() as usize) {
@@ -98,7 +99,7 @@ pub(super) fn check_header<B: BlockT + Sized>(
debug!(target: "babe",
"Verifying primary block #{} at slot: {}",
header.number(),
primary.slot_number,
primary.slot,
);
check_primary_header::<B>(
@@ -113,7 +114,7 @@ pub(super) fn check_header<B: BlockT + Sized>(
debug!(target: "babe",
"Verifying secondary plain block #{} at slot: {}",
header.number(),
secondary.slot_number,
secondary.slot,
);
check_secondary_plain_header::<B>(
@@ -127,7 +128,7 @@ pub(super) fn check_header<B: BlockT + Sized>(
debug!(target: "babe",
"Verifying secondary VRF block #{} at slot: {}",
header.number(),
secondary.slot_number,
secondary.slot,
);
check_secondary_vrf_header::<B>(
@@ -173,7 +174,7 @@ fn check_primary_header<B: BlockT + Sized>(
let (inout, _) = {
let transcript = make_transcript(
&epoch.randomness,
pre_digest.slot_number,
pre_digest.slot,
epoch.epoch_index,
);
@@ -213,7 +214,7 @@ fn check_secondary_plain_header<B: BlockT>(
// check the signature is valid under the expected authority and
// chain state.
let expected_author = secondary_slot_author(
pre_digest.slot_number,
pre_digest.slot,
&epoch.authorities,
epoch.randomness,
).ok_or_else(|| Error::NoSecondaryAuthorExpected)?;
@@ -241,7 +242,7 @@ fn check_secondary_vrf_header<B: BlockT>(
// check the signature is valid under the expected authority and
// chain state.
let expected_author = secondary_slot_author(
pre_digest.slot_number,
pre_digest.slot,
&epoch.authorities,
epoch.randomness,
).ok_or_else(|| Error::NoSecondaryAuthorExpected)?;
@@ -255,7 +256,7 @@ fn check_secondary_vrf_header<B: BlockT>(
if AuthorityPair::verify(&signature, pre_hash.as_ref(), author) {
let transcript = make_transcript(
&epoch.randomness,
pre_digest.slot_number,
pre_digest.slot,
epoch.epoch_index,
);
+36 -36
View File
@@ -78,13 +78,13 @@ pub trait Epoch {
/// Descriptor for the next epoch.
type NextEpochDescriptor;
/// Type of the slot number.
type SlotNumber: Ord + Copy;
type Slot: Ord + Copy;
/// The starting slot of the epoch.
fn start_slot(&self) -> Self::SlotNumber;
fn start_slot(&self) -> Self::Slot;
/// Produce the "end slot" of the epoch. This is NOT inclusive to the epoch,
/// i.e. the slots covered by the epoch are `self.start_slot() .. self.end_slot()`.
fn end_slot(&self) -> Self::SlotNumber;
fn end_slot(&self) -> Self::Slot;
/// Increment the epoch data, using the next epoch descriptor.
fn increment(&self, descriptor: Self::NextEpochDescriptor) -> Self;
}
@@ -102,10 +102,10 @@ impl<'a, E: Epoch> From<&'a E> for EpochHeader<E> {
#[derive(Eq, PartialEq, Encode, Decode, Debug)]
pub struct EpochHeader<E: Epoch> {
/// The starting slot of the epoch.
pub start_slot: E::SlotNumber,
pub start_slot: E::Slot,
/// The end slot of the epoch. This is NOT inclusive to the epoch,
/// i.e. the slots covered by the epoch are `self.start_slot() .. self.end_slot()`.
pub end_slot: E::SlotNumber,
pub end_slot: E::Slot,
}
impl<E: Epoch> Clone for EpochHeader<E> {
@@ -215,14 +215,14 @@ impl<E, ERef> ViableEpoch<E, ERef> where
#[derive(PartialEq, Eq, Clone, Debug)]
pub enum ViableEpochDescriptor<Hash, Number, E: Epoch> {
/// The epoch is an unimported genesis, with given start slot number.
UnimportedGenesis(E::SlotNumber),
UnimportedGenesis(E::Slot),
/// The epoch is signaled and has been imported, with given identifier and header.
Signaled(EpochIdentifier<Hash, Number>, EpochHeader<E>)
}
impl<Hash, Number, E: Epoch> ViableEpochDescriptor<Hash, Number, E> {
/// Start slot of the descriptor.
pub fn start_slot(&self) -> E::SlotNumber {
pub fn start_slot(&self) -> E::Slot {
match self {
Self::UnimportedGenesis(start_slot) => *start_slot,
Self::Signaled(_, header) => header.start_slot,
@@ -339,7 +339,7 @@ impl<Hash, Number, E: Epoch> EpochChanges<Hash, Number, E> where
/// Map the epoch changes from one storing data to a different one.
pub fn map<B, F>(self, mut f: F) -> EpochChanges<Hash, Number, B> where
B: Epoch<SlotNumber=E::SlotNumber>,
B: Epoch<Slot=E::Slot>,
F: FnMut(&Hash, &Number, E) -> B,
{
EpochChanges {
@@ -394,7 +394,7 @@ impl<Hash, Number, E: Epoch> EpochChanges<Hash, Number, E> where
descendent_of_builder: D,
hash: &Hash,
number: Number,
slot: E::SlotNumber,
slot: E::Slot,
) -> Result<(), fork_tree::Error<D::Error>> {
let is_descendent_of = descendent_of_builder
.build_is_descendent_of(None);
@@ -445,11 +445,11 @@ impl<Hash, Number, E: Epoch> EpochChanges<Hash, Number, E> where
descriptor: &ViableEpochDescriptor<Hash, Number, E>,
make_genesis: G,
) -> Option<ViableEpoch<E, &E>> where
G: FnOnce(E::SlotNumber) -> E
G: FnOnce(E::Slot) -> E
{
match descriptor {
ViableEpochDescriptor::UnimportedGenesis(slot_number) => {
Some(ViableEpoch::UnimportedGenesis(make_genesis(*slot_number)))
ViableEpochDescriptor::UnimportedGenesis(slot) => {
Some(ViableEpoch::UnimportedGenesis(make_genesis(*slot)))
},
ViableEpochDescriptor::Signaled(identifier, _) => {
self.epoch(&identifier).map(ViableEpoch::Signaled)
@@ -479,11 +479,11 @@ impl<Hash, Number, E: Epoch> EpochChanges<Hash, Number, E> where
descriptor: &ViableEpochDescriptor<Hash, Number, E>,
make_genesis: G,
) -> Option<ViableEpoch<E, &mut E>> where
G: FnOnce(E::SlotNumber) -> E
G: FnOnce(E::Slot) -> E
{
match descriptor {
ViableEpochDescriptor::UnimportedGenesis(slot_number) => {
Some(ViableEpoch::UnimportedGenesis(make_genesis(*slot_number)))
ViableEpochDescriptor::UnimportedGenesis(slot) => {
Some(ViableEpoch::UnimportedGenesis(make_genesis(*slot)))
},
ViableEpochDescriptor::Signaled(identifier, _) => {
self.epoch_mut(&identifier).map(ViableEpoch::Signaled)
@@ -500,12 +500,12 @@ impl<Hash, Number, E: Epoch> EpochChanges<Hash, Number, E> where
descriptor: &ViableEpochDescriptor<Hash, Number, E>,
make_genesis: G
) -> Option<E> where
G: FnOnce(E::SlotNumber) -> E,
G: FnOnce(E::Slot) -> E,
E: Clone,
{
match descriptor {
ViableEpochDescriptor::UnimportedGenesis(slot_number) => {
Some(make_genesis(*slot_number))
ViableEpochDescriptor::UnimportedGenesis(slot) => {
Some(make_genesis(*slot))
},
ViableEpochDescriptor::Signaled(identifier, _) => {
self.epoch(&identifier).cloned()
@@ -523,17 +523,17 @@ impl<Hash, Number, E: Epoch> EpochChanges<Hash, Number, E> where
descendent_of_builder: D,
parent_hash: &Hash,
parent_number: Number,
slot_number: E::SlotNumber,
slot: E::Slot,
make_genesis: G,
) -> Result<Option<E>, fork_tree::Error<D::Error>> where
G: FnOnce(E::SlotNumber) -> E,
G: FnOnce(E::Slot) -> E,
E: Clone,
{
let descriptor = self.epoch_descriptor_for_child_of(
descendent_of_builder,
parent_hash,
parent_number,
slot_number
slot
)?;
Ok(descriptor.and_then(|des| self.epoch_data(&des, make_genesis)))
@@ -548,7 +548,7 @@ impl<Hash, Number, E: Epoch> EpochChanges<Hash, Number, E> where
descendent_of_builder: D,
parent_hash: &Hash,
parent_number: Number,
slot_number: E::SlotNumber,
slot: E::Slot,
) -> Result<Option<ViableEpochDescriptor<Hash, Number, E>>, fork_tree::Error<D::Error>> {
// find_node_where will give you the node in the fork-tree which is an ancestor
// of the `parent_hash` by default. if the last epoch was signalled at the parent_hash,
@@ -561,7 +561,7 @@ impl<Hash, Number, E: Epoch> EpochChanges<Hash, Number, E> where
if parent_number == Zero::zero() {
// need to insert the genesis epoch.
return Ok(Some(ViableEpochDescriptor::UnimportedGenesis(slot_number)))
return Ok(Some(ViableEpochDescriptor::UnimportedGenesis(slot)))
}
// We want to find the deepest node in the tree which is an ancestor
@@ -571,9 +571,9 @@ impl<Hash, Number, E: Epoch> EpochChanges<Hash, Number, E> where
// we need.
let predicate = |epoch: &PersistedEpochHeader<E>| match *epoch {
PersistedEpochHeader::Genesis(ref epoch_0, _) =>
epoch_0.start_slot <= slot_number,
epoch_0.start_slot <= slot,
PersistedEpochHeader::Regular(ref epoch_n) =>
epoch_n.start_slot <= slot_number,
epoch_n.start_slot <= slot,
};
self.inner.find_node_where(
@@ -588,7 +588,7 @@ impl<Hash, Number, E: Epoch> EpochChanges<Hash, Number, E> where
// and here we figure out which of the internal epochs
// of a genesis node to use based on their start slot.
PersistedEpochHeader::Genesis(ref epoch_0, ref epoch_1) =>
if epoch_1.start_slot <= slot_number {
if epoch_1.start_slot <= slot {
(EpochIdentifierPosition::Genesis1, epoch_1.clone())
} else {
(EpochIdentifierPosition::Genesis0, epoch_0.clone())
@@ -695,17 +695,17 @@ mod tests {
}
type Hash = [u8; 1];
type SlotNumber = u64;
type Slot = u64;
#[derive(Debug, Clone, Eq, PartialEq)]
struct Epoch {
start_slot: SlotNumber,
duration: SlotNumber,
start_slot: Slot,
duration: Slot,
}
impl EpochT for Epoch {
type NextEpochDescriptor = ();
type SlotNumber = SlotNumber;
type Slot = Slot;
fn increment(&self, _: ()) -> Self {
Epoch {
@@ -714,11 +714,11 @@ mod tests {
}
}
fn end_slot(&self) -> SlotNumber {
fn end_slot(&self) -> Slot {
self.start_slot + self.duration
}
fn start_slot(&self) -> SlotNumber {
fn start_slot(&self) -> Slot {
self.start_slot
}
}
@@ -748,8 +748,8 @@ mod tests {
).unwrap().unwrap();
match genesis_epoch {
ViableEpochDescriptor::UnimportedGenesis(slot_number) => {
assert_eq!(slot_number, 10101u64);
ViableEpochDescriptor::UnimportedGenesis(slot) => {
assert_eq!(slot, 10101u64);
},
_ => panic!("should be unimported genesis"),
};
@@ -762,8 +762,8 @@ mod tests {
).unwrap().unwrap();
match genesis_epoch_2 {
ViableEpochDescriptor::UnimportedGenesis(slot_number) => {
assert_eq!(slot_number, 10102u64);
ViableEpochDescriptor::UnimportedGenesis(slot) => {
assert_eq!(slot, 10102u64);
},
_ => panic!("should be unimported genesis"),
};
@@ -31,7 +31,8 @@ sp-consensus-babe = { path = "../../../primitives/consensus/babe", version = "0.
sc-transaction-pool = { path = "../../transaction-pool", version = "2.0.0" }
sp-blockchain = { path = "../../../primitives/blockchain", version = "2.0.0" }
sp-consensus = { package = "sp-consensus", path = "../../../primitives/consensus/common", version = "0.8.0" }
sp-consensus = { path = "../../../primitives/consensus/common", version = "0.8.0" }
sp-consensus-slots = { path = "../../../primitives/consensus/slots", version = "0.8.1" }
sp-inherents = { path = "../../../primitives/inherents", version = "2.0.0" }
sp-runtime = { path = "../../../primitives/runtime", version = "2.0.0" }
sp-core = { path = "../../../primitives/core", version = "2.0.0" }
@@ -38,6 +38,7 @@ use sp_keystore::SyncCryptoStorePtr;
use sp_api::{ProvideRuntimeApi, TransactionFor};
use sp_blockchain::{HeaderBackend, HeaderMetadata};
use sp_consensus::BlockImportParams;
use sp_consensus_slots::Slot;
use sp_consensus_babe::{
BabeApi, inherents::BabeInherentData, ConsensusLog, BABE_ENGINE_ID, AuthorityId,
digests::{PreDigest, SecondaryPlainPreDigest, NextEpochDescriptor}, BabeAuthorityWeight,
@@ -100,14 +101,14 @@ impl<B, C> BabeConsensusDataProvider<B, C>
})
}
fn epoch(&self, parent: &B::Header, slot_number: u64) -> Result<Epoch, Error> {
fn epoch(&self, parent: &B::Header, slot: Slot) -> Result<Epoch, Error> {
let epoch_changes = self.epoch_changes.lock();
let epoch_descriptor = epoch_changes
.epoch_descriptor_for_child_of(
descendent_query(&*self.client),
&parent.hash(),
parent.number().clone(),
slot_number,
slot,
)
.map_err(|e| Error::StringError(format!("failed to fetch epoch_descriptor: {}", e)))?
.ok_or_else(|| sp_consensus::Error::InvalidAuthoritiesSet)?;
@@ -135,11 +136,15 @@ impl<B, C> ConsensusDataProvider<B> for BabeConsensusDataProvider<B, C>
type Transaction = TransactionFor<C, B>;
fn create_digest(&self, parent: &B::Header, inherents: &InherentData) -> Result<DigestFor<B>, Error> {
let slot_number = inherents.babe_inherent_data()?;
let epoch = self.epoch(parent, slot_number)?;
let slot = inherents.babe_inherent_data()?;
let epoch = self.epoch(parent, slot)?;
// this is a dev node environment, we should always be able to claim a slot.
let logs = if let Some((predigest, _)) = authorship::claim_slot(slot_number, &epoch, &self.keystore) {
let logs = if let Some((predigest, _)) = authorship::claim_slot(
slot,
&epoch,
&self.keystore,
) {
vec![
<DigestItemFor<B> as CompatibleDigestItem>::babe_pre_digest(predigest),
]
@@ -147,7 +152,7 @@ impl<B, C> ConsensusDataProvider<B> for BabeConsensusDataProvider<B, C>
// well we couldn't claim a slot because this is an existing chain and we're not in the authorities.
// we need to tell BabeBlockImport that the epoch has changed, and we put ourselves in the authorities.
let predigest = PreDigest::SecondaryPlain(SecondaryPlainPreDigest {
slot_number,
slot,
authority_index: 0_u32,
});
@@ -157,7 +162,7 @@ impl<B, C> ConsensusDataProvider<B> for BabeConsensusDataProvider<B, C>
descendent_query(&*self.client),
&parent.hash(),
parent.number().clone(),
slot_number,
slot,
)
.map_err(|e| Error::StringError(format!("failed to fetch epoch_descriptor: {}", e)))?
.ok_or_else(|| sp_consensus::Error::InvalidAuthoritiesSet)?;
@@ -194,21 +199,21 @@ impl<B, C> ConsensusDataProvider<B> for BabeConsensusDataProvider<B, C>
params: &mut BlockImportParams<B, Self::Transaction>,
inherents: &InherentData
) -> Result<(), Error> {
let slot_number = inherents.babe_inherent_data()?;
let slot = inherents.babe_inherent_data()?;
let epoch_changes = self.epoch_changes.lock();
let mut epoch_descriptor = epoch_changes
.epoch_descriptor_for_child_of(
descendent_query(&*self.client),
&parent.hash(),
parent.number().clone(),
slot_number,
slot,
)
.map_err(|e| Error::StringError(format!("failed to fetch epoch_descriptor: {}", e)))?
.ok_or_else(|| sp_consensus::Error::InvalidAuthoritiesSet)?;
// drop the lock
drop(epoch_changes);
// a quick check to see if we're in the authorities
let epoch = self.epoch(parent, slot_number)?;
let epoch = self.epoch(parent, slot)?;
let (authority, _) = self.authorities.first().expect("authorities is non-emptyp; qed");
let has_authority = epoch.authorities.iter()
.find(|(id, _)| *id == *authority)
@@ -216,15 +221,15 @@ impl<B, C> ConsensusDataProvider<B> for BabeConsensusDataProvider<B, C>
if !has_authority {
log::info!(target: "manual-seal", "authority not found");
let slot_number = inherents.timestamp_inherent_data()? / self.config.slot_duration;
let slot = inherents.timestamp_inherent_data()? / 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_number,
end_slot: slot_number * self.config.epoch_length,
start_slot: slot.into(),
end_slot: (slot * self.config.epoch_length).into(),
},
)
},
@@ -263,9 +268,9 @@ impl SlotTimestampProvider {
// otherwise we'd be producing blocks for older slots.
let duration = if info.best_number != Zero::zero() {
let header = client.header(BlockId::Hash(info.best_hash))?.unwrap();
let slot_number = find_pre_digest::<B>(&header).unwrap().slot_number();
let slot = find_pre_digest::<B>(&header).unwrap().slot();
// add the slot duration so there's no collision of slots
(slot_number * slot_duration) + slot_duration
(*slot * slot_duration) + slot_duration
} else {
// this is the first block, use the correct time.
let now = SystemTime::now();
@@ -21,7 +21,7 @@
use codec::{Encode, Decode};
use sc_client_api::backend::AuxStore;
use sp_blockchain::{Result as ClientResult, Error as ClientError};
use sp_consensus_slots::EquivocationProof;
use sp_consensus_slots::{EquivocationProof, Slot};
use sp_runtime::traits::Header;
const SLOT_HEADER_MAP_KEY: &[u8] = b"slot_header_map";
@@ -52,8 +52,8 @@ fn load_decode<C, T>(backend: &C, key: &[u8]) -> ClientResult<Option<T>>
/// Note: it detects equivocations only when slot_now - slot <= MAX_SLOT_CAPACITY.
pub fn check_equivocation<C, H, P>(
backend: &C,
slot_now: u64,
slot: u64,
slot_now: Slot,
slot: Slot,
header: &H,
signer: &P,
) -> ClientResult<Option<EquivocationProof<H, P>>>
@@ -63,7 +63,7 @@ pub fn check_equivocation<C, H, P>(
P: Clone + Encode + Decode + PartialEq,
{
// We don't check equivocations for old headers out of our capacity.
if slot_now.saturating_sub(slot) > MAX_SLOT_CAPACITY {
if slot_now.saturating_sub(*slot) > Slot::from(MAX_SLOT_CAPACITY) {
return Ok(None);
}
@@ -77,7 +77,7 @@ pub fn check_equivocation<C, H, P>(
// Get first slot saved.
let slot_header_start = SLOT_HEADER_START.to_vec();
let first_saved_slot = load_decode::<_, u64>(backend, &slot_header_start[..])?
let first_saved_slot = load_decode::<_, Slot>(backend, &slot_header_start[..])?
.unwrap_or(slot);
if slot_now < first_saved_slot {
@@ -92,7 +92,7 @@ pub fn check_equivocation<C, H, P>(
// 2) with different hash
if header.hash() != prev_header.hash() {
return Ok(Some(EquivocationProof {
slot_number: slot,
slot,
offender: signer.clone(),
first_header: prev_header.clone(),
second_header: header.clone(),
@@ -109,11 +109,11 @@ pub fn check_equivocation<C, H, P>(
let mut keys_to_delete = vec![];
let mut new_first_saved_slot = first_saved_slot;
if slot_now - first_saved_slot >= PRUNING_BOUND {
if *slot_now - *first_saved_slot >= PRUNING_BOUND {
let prefix = SLOT_HEADER_MAP_KEY.to_vec();
new_first_saved_slot = slot_now.saturating_sub(MAX_SLOT_CAPACITY);
for s in first_saved_slot..new_first_saved_slot {
for s in u64::from(first_saved_slot)..new_first_saved_slot.into() {
let mut p = prefix.clone();
s.using_encoded(|s| p.extend(s));
keys_to_delete.push(p);
@@ -174,8 +174,8 @@ mod test {
assert!(
check_equivocation(
&client,
2,
2,
2.into(),
2.into(),
&header1,
&public,
).unwrap().is_none(),
@@ -184,8 +184,8 @@ mod test {
assert!(
check_equivocation(
&client,
3,
2,
3.into(),
2.into(),
&header1,
&public,
).unwrap().is_none(),
@@ -195,8 +195,8 @@ mod test {
assert!(
check_equivocation(
&client,
4,
2,
4.into(),
2.into(),
&header2,
&public,
).unwrap().is_some(),
@@ -206,8 +206,8 @@ mod test {
assert!(
check_equivocation(
&client,
5,
4,
5.into(),
4.into(),
&header3,
&public,
).unwrap().is_none(),
@@ -217,8 +217,8 @@ mod test {
assert!(
check_equivocation(
&client,
PRUNING_BOUND + 2,
MAX_SLOT_CAPACITY + 4,
(PRUNING_BOUND + 2).into(),
(MAX_SLOT_CAPACITY + 4).into(),
&header4,
&public,
).unwrap().is_none(),
@@ -228,8 +228,8 @@ mod test {
assert!(
check_equivocation(
&client,
PRUNING_BOUND + 3,
MAX_SLOT_CAPACITY + 4,
(PRUNING_BOUND + 3).into(),
(MAX_SLOT_CAPACITY + 4).into(),
&header5,
&public,
).unwrap().is_some(),
@@ -239,8 +239,8 @@ mod test {
assert!(
check_equivocation(
&client,
PRUNING_BOUND + 4,
4,
(PRUNING_BOUND + 4).into(),
4.into(),
&header6,
&public,
).unwrap().is_none(),
+64 -58
View File
@@ -41,6 +41,7 @@ use parking_lot::Mutex;
use sp_api::{ProvideRuntimeApi, ApiRef};
use sp_arithmetic::traits::BaseArithmetic;
use sp_consensus::{BlockImport, Proposer, SyncOracle, SelectChain, CanAuthorWith, SlotData, RecordProof};
use sp_consensus_slots::Slot;
use sp_inherents::{InherentData, InherentDataProviders};
use sp_runtime::{
generic::BlockId,
@@ -115,7 +116,7 @@ pub trait SimpleSlotWorker<B: BlockT> {
fn epoch_data(
&self,
header: &B::Header,
slot_number: u64,
slot: Slot,
) -> Result<Self::EpochData, sp_consensus::Error>;
/// Returns the number of authorities given the epoch data.
@@ -126,7 +127,7 @@ pub trait SimpleSlotWorker<B: BlockT> {
fn claim_slot(
&self,
header: &B::Header,
slot_number: u64,
slot: Slot,
epoch_data: &Self::EpochData,
) -> Option<Self::Claim>;
@@ -135,14 +136,14 @@ pub trait SimpleSlotWorker<B: BlockT> {
fn notify_slot(
&self,
_header: &B::Header,
_slot_number: u64,
_slot: Slot,
_epoch_data: &Self::EpochData,
) {}
/// Return the pre digest data to include in a block authored with the given claim.
fn pre_digest_data(
&self,
slot_number: u64,
slot: Slot,
claim: &Self::Claim,
) -> Vec<sp_runtime::DigestItem<B::Hash>>;
@@ -170,7 +171,7 @@ pub trait SimpleSlotWorker<B: BlockT> {
///
/// An example strategy that back offs if the finalized head is lagging too much behind the tip
/// is implemented by [`BackoffAuthoringOnFinalizedHeadLagging`].
fn should_backoff(&self, _slot_number: u64, _chain_head: &B::Header) -> bool {
fn should_backoff(&self, _slot: Slot, _chain_head: &B::Header) -> bool {
false
}
@@ -208,7 +209,7 @@ pub trait SimpleSlotWorker<B: BlockT> {
where
<Self::Proposer as Proposer<B>>::Proposal: Unpin + Send + 'static,
{
let (timestamp, slot_number) = (slot_info.timestamp, slot_info.number);
let (timestamp, slot) = (slot_info.timestamp, slot_info.slot);
let slot_remaining_duration = self.slot_remaining_duration(&slot_info);
let proposing_remaining_duration = self.proposing_remaining_duration(&chain_head, &slot_info);
@@ -218,7 +219,7 @@ pub trait SimpleSlotWorker<B: BlockT> {
debug!(
target: self.logging_target(),
"Skipping proposal slot {} since there's no time left to propose",
slot_number,
slot,
);
return Box::pin(future::ready(None));
@@ -227,7 +228,7 @@ pub trait SimpleSlotWorker<B: BlockT> {
None => Box::new(future::pending()) as Box<_>,
};
let epoch_data = match self.epoch_data(&chain_head, slot_number) {
let epoch_data = match self.epoch_data(&chain_head, slot) {
Ok(epoch_data) => epoch_data,
Err(err) => {
warn!("Unable to fetch epoch data at block {:?}: {:?}", chain_head.hash(), err);
@@ -242,7 +243,7 @@ pub trait SimpleSlotWorker<B: BlockT> {
}
};
self.notify_slot(&chain_head, slot_number, &epoch_data);
self.notify_slot(&chain_head, slot, &epoch_data);
let authorities_len = self.authorities_len(&epoch_data);
@@ -260,38 +261,43 @@ pub trait SimpleSlotWorker<B: BlockT> {
return Box::pin(future::ready(None));
}
let claim = match self.claim_slot(&chain_head, slot_number, &epoch_data) {
let claim = match self.claim_slot(&chain_head, slot, &epoch_data) {
None => return Box::pin(future::ready(None)),
Some(claim) => claim,
};
if self.should_backoff(slot_number, &chain_head) {
if self.should_backoff(slot, &chain_head) {
return Box::pin(future::ready(None));
}
debug!(
target: self.logging_target(),
"Starting authorship at slot {}; timestamp = {}",
slot_number,
slot,
timestamp,
);
telemetry!(CONSENSUS_DEBUG; "slots.starting_authorship";
"slot_num" => slot_number,
telemetry!(
CONSENSUS_DEBUG;
"slots.starting_authorship";
"slot_num" => *slot,
"timestamp" => timestamp,
);
let awaiting_proposer = self.proposer(&chain_head).map_err(move |err| {
warn!("Unable to author block in slot {:?}: {:?}", slot_number, err);
warn!("Unable to author block in slot {:?}: {:?}", slot, err);
telemetry!(CONSENSUS_WARN; "slots.unable_authoring_block";
"slot" => slot_number, "err" => ?err
telemetry!(
CONSENSUS_WARN;
"slots.unable_authoring_block";
"slot" => *slot,
"err" => ?err
);
err
});
let logs = self.pre_digest_data(slot_number, &claim);
let logs = self.pre_digest_data(slot, &claim);
// deadline our production to approx. the end of the slot
let proposing = awaiting_proposer.and_then(move |proposer| proposer.propose(
@@ -307,12 +313,14 @@ pub trait SimpleSlotWorker<B: BlockT> {
futures::future::select(proposing, proposing_remaining).map(move |v| match v {
Either::Left((b, _)) => b.map(|b| (b, claim)),
Either::Right(_) => {
info!("⌛️ Discarding proposal for slot {}; block production took too long", slot_number);
info!("⌛️ Discarding proposal for slot {}; block production took too long", slot);
// If the node was compiled with debug, tell the user to use release optimizations.
#[cfg(build_type="debug")]
info!("👉 Recompile your node in `--release` mode to mitigate this problem.");
telemetry!(CONSENSUS_INFO; "slots.discarding_proposal_took_too_long";
"slot" => slot_number,
telemetry!(
CONSENSUS_INFO;
"slots.discarding_proposal_took_too_long";
"slot" => *slot,
);
Err(sp_consensus::Error::ClientImport("Timeout in the Slots proposer".into()))
@@ -388,7 +396,7 @@ pub trait SlotCompatible {
fn extract_timestamp_and_slot(
&self,
inherent: &InherentData,
) -> Result<(u64, u64, std::time::Duration), sp_consensus::Error>;
) -> Result<(u64, Slot, std::time::Duration), sp_consensus::Error>;
}
/// Start a new slot worker.
@@ -429,12 +437,12 @@ where
return Either::Right(future::ready(Ok(())));
}
let slot_num = slot_info.number;
let slot = slot_info.slot;
let chain_head = match client.best_chain() {
Ok(x) => x,
Err(e) => {
warn!(target: "slots", "Unable to author block in slot {}. \
no best block header: {:?}", slot_num, e);
no best block header: {:?}", slot, e);
return Either::Right(future::ready(Ok(())));
}
};
@@ -444,7 +452,7 @@ where
target: "slots",
"Unable to author block in slot {},. `can_author_with` returned: {} \
Probably a node update is required!",
slot_num,
slot,
err,
);
Either::Right(future::ready(Ok(())))
@@ -465,7 +473,7 @@ where
pub enum CheckedHeader<H, S> {
/// A header which has slot in the future. this is the full header (not stripped)
/// and the slot in which it should be processed.
Deferred(H, u64),
Deferred(H, Slot),
/// A header which is fully checked, including signature. This is the pre-header
/// accompanied by the seal components.
///
@@ -473,8 +481,6 @@ pub enum CheckedHeader<H, S> {
Checked(H, S),
}
#[derive(Debug, thiserror::Error)]
#[allow(missing_docs)]
pub enum Error<T> where T: Debug {
@@ -561,7 +567,7 @@ impl<T: Clone + Send + Sync + 'static> SlotDuration<T> {
/// to parent. If the number of skipped slots is greated than 0 this method will apply
/// an exponential backoff of at most `2^7 * slot_duration`, if no slots were skipped
/// this method will return `None.`
pub fn slot_lenience_exponential(parent_slot: u64, slot_info: &SlotInfo) -> Option<Duration> {
pub fn slot_lenience_exponential(parent_slot: Slot, slot_info: &SlotInfo) -> Option<Duration> {
// never give more than 2^this times the lenience.
const BACKOFF_CAP: u64 = 7;
@@ -574,7 +580,7 @@ pub fn slot_lenience_exponential(parent_slot: u64, slot_info: &SlotInfo) -> Opti
// exponential back-off.
// in normal cases we only attempt to issue blocks up to the end of the slot.
// when the chain has been stalled for a few slots, we give more lenience.
let skipped_slots = slot_info.number.saturating_sub(parent_slot + 1);
let skipped_slots = *slot_info.slot.saturating_sub(parent_slot + 1);
if skipped_slots == 0 {
None
@@ -590,7 +596,7 @@ pub fn slot_lenience_exponential(parent_slot: u64, slot_info: &SlotInfo) -> Opti
/// to parent. If the number of skipped slots is greated than 0 this method will apply
/// a linear backoff of at most `20 * slot_duration`, if no slots were skipped
/// this method will return `None.`
pub fn slot_lenience_linear(parent_slot: u64, slot_info: &SlotInfo) -> Option<Duration> {
pub fn slot_lenience_linear(parent_slot: Slot, slot_info: &SlotInfo) -> Option<Duration> {
// never give more than 20 times more lenience.
const BACKOFF_CAP: u64 = 20;
@@ -600,7 +606,7 @@ pub fn slot_lenience_linear(parent_slot: u64, slot_info: &SlotInfo) -> Option<Du
// linear back-off.
// in normal cases we only attempt to issue blocks up to the end of the slot.
// when the chain has been stalled for a few slots, we give more lenience.
let skipped_slots = slot_info.number.saturating_sub(parent_slot + 1);
let skipped_slots = *slot_info.slot.saturating_sub(parent_slot + 1);
if skipped_slots == 0 {
None
@@ -616,9 +622,9 @@ pub trait BackoffAuthoringBlocksStrategy<N> {
fn should_backoff(
&self,
chain_head_number: N,
chain_head_slot: u64,
chain_head_slot: Slot,
finalized_number: N,
slow_now: u64,
slow_now: Slot,
logging_target: &str,
) -> bool;
}
@@ -663,9 +669,9 @@ where
fn should_backoff(
&self,
chain_head_number: N,
chain_head_slot: u64,
chain_head_slot: Slot,
finalized_number: N,
slot_now: u64,
slot_now: Slot,
logging_target: &str,
) -> bool {
// This should not happen, but we want to keep the previous behaviour if it does.
@@ -683,7 +689,7 @@ where
// If interval is nonzero we backoff if the current slot isn't far enough ahead of the chain
// head.
if slot_now <= chain_head_slot + interval {
if *slot_now <= *chain_head_slot + interval {
info!(
target: logging_target,
"Backing off claiming new slot for block authorship: finality is lagging.",
@@ -699,9 +705,9 @@ impl<N> BackoffAuthoringBlocksStrategy<N> for () {
fn should_backoff(
&self,
_chain_head_number: N,
_chain_head_slot: u64,
_chain_head_slot: Slot,
_finalized_number: N,
_slot_now: u64,
_slot_now: Slot,
_logging_target: &str,
) -> bool {
false
@@ -717,9 +723,9 @@ mod test {
const SLOT_DURATION: Duration = Duration::from_millis(6000);
fn slot(n: u64) -> super::slots::SlotInfo {
fn slot(slot: u64) -> super::slots::SlotInfo {
super::slots::SlotInfo {
number: n,
slot: slot.into(),
duration: SLOT_DURATION.as_millis() as u64,
timestamp: Default::default(),
inherent_data: Default::default(),
@@ -730,20 +736,20 @@ mod test {
#[test]
fn linear_slot_lenience() {
// if no slots are skipped there should be no lenience
assert_eq!(super::slot_lenience_linear(1, &slot(2)), None);
assert_eq!(super::slot_lenience_linear(1.into(), &slot(2)), None);
// otherwise the lenience is incremented linearly with
// the number of skipped slots.
for n in 3..=22 {
assert_eq!(
super::slot_lenience_linear(1, &slot(n)),
super::slot_lenience_linear(1.into(), &slot(n)),
Some(SLOT_DURATION * (n - 2) as u32),
);
}
// but we cap it to a maximum of 20 slots
assert_eq!(
super::slot_lenience_linear(1, &slot(23)),
super::slot_lenience_linear(1.into(), &slot(23)),
Some(SLOT_DURATION * 20),
);
}
@@ -751,24 +757,24 @@ mod test {
#[test]
fn exponential_slot_lenience() {
// if no slots are skipped there should be no lenience
assert_eq!(super::slot_lenience_exponential(1, &slot(2)), None);
assert_eq!(super::slot_lenience_exponential(1.into(), &slot(2)), None);
// otherwise the lenience is incremented exponentially every two slots
for n in 3..=17 {
assert_eq!(
super::slot_lenience_exponential(1, &slot(n)),
super::slot_lenience_exponential(1.into(), &slot(n)),
Some(SLOT_DURATION * 2u32.pow((n / 2 - 1) as u32)),
);
}
// but we cap it to a maximum of 14 slots
assert_eq!(
super::slot_lenience_exponential(1, &slot(18)),
super::slot_lenience_exponential(1.into(), &slot(18)),
Some(SLOT_DURATION * 2u32.pow(7)),
);
assert_eq!(
super::slot_lenience_exponential(1, &slot(19)),
super::slot_lenience_exponential(1.into(), &slot(19)),
Some(SLOT_DURATION * 2u32.pow(7)),
);
}
@@ -808,7 +814,7 @@ mod test {
let slot_now = 2;
let should_backoff: Vec<bool> = (slot_now..1000)
.map(|s| strategy.should_backoff(head_number, head_slot, finalized_number, s, "slots"))
.map(|s| strategy.should_backoff(head_number, head_slot.into(), finalized_number, s.into(), "slots"))
.collect();
// Should always be false, since the head isn't advancing
@@ -833,9 +839,9 @@ mod test {
.map(move |s| {
let b = strategy.should_backoff(
head_number,
head_slot,
head_slot.into(),
finalized_number,
s,
s.into(),
"slots",
);
// Chain is still advancing (by someone else)
@@ -872,7 +878,7 @@ mod test {
let max_interval = strategy.max_interval;
let should_backoff: Vec<bool> = (slot_now..200)
.map(|s| strategy.should_backoff(head_number, head_slot, finalized_number, s, "slots"))
.map(|s| strategy.should_backoff(head_number, head_slot.into(), finalized_number, s.into(), "slots"))
.collect();
// Should backoff (true) until we are `max_interval` number of slots ahead of the chain
@@ -900,9 +906,9 @@ mod test {
<dyn BackoffAuthoringBlocksStrategy<NumberFor<Block>>>::should_backoff(
&param,
head_state.head_number,
head_state.head_slot,
head_state.head_slot.into(),
finalized_number,
head_state.slot_now,
head_state.slot_now.into(),
"slots",
)
};
@@ -972,9 +978,9 @@ mod test {
<dyn BackoffAuthoringBlocksStrategy<NumberFor<Block>>>::should_backoff(
&param,
head_state.head_number,
head_state.head_slot,
head_state.head_slot.into(),
finalized_number,
head_state.slot_now,
head_state.slot_now.into(),
"slots",
)
};
@@ -1036,9 +1042,9 @@ mod test {
<dyn BackoffAuthoringBlocksStrategy<NumberFor<Block>>>::should_backoff(
&param,
head_state.head_number,
head_state.head_slot,
head_state.head_slot.into(),
finalized_number,
head_state.slot_now,
head_state.slot_now.into(),
"slots",
)
};
@@ -20,7 +20,7 @@
//!
//! This is used instead of `futures_timer::Interval` because it was unreliable.
use super::SlotCompatible;
use super::{SlotCompatible, Slot};
use sp_consensus::Error;
use futures::{prelude::*, task::Context, task::Poll};
use sp_inherents::{InherentData, InherentDataProviders};
@@ -48,7 +48,7 @@ pub fn time_until_next(now: Duration, slot_duration: u64) -> Duration {
/// Information about a slot.
pub struct SlotInfo {
/// The slot number.
pub number: u64,
pub slot: Slot,
/// Current timestamp.
pub timestamp: u64,
/// The instant at which the slot ends.
@@ -61,7 +61,7 @@ pub struct SlotInfo {
/// A stream that returns every time there is a new slot.
pub(crate) struct Slots<SC> {
last_slot: u64,
last_slot: Slot,
slot_duration: u64,
inner_delay: Option<Delay>,
inherent_data_providers: InherentDataProviders,
@@ -76,7 +76,7 @@ impl<SC> Slots<SC> {
timestamp_extractor: SC,
) -> Self {
Slots {
last_slot: 0,
last_slot: 0.into(),
slot_duration,
inner_delay: None,
inherent_data_providers,
@@ -114,7 +114,7 @@ impl<SC: SlotCompatible> Stream for Slots<SC> {
Err(err) => return Poll::Ready(Some(Err(sp_consensus::Error::InherentData(err)))),
};
let result = self.timestamp_extractor.extract_timestamp_and_slot(&inherent_data);
let (timestamp, slot_num, offset) = match result {
let (timestamp, slot, offset) = match result {
Ok(v) => v,
Err(err) => return Poll::Ready(Some(Err(err))),
};
@@ -125,11 +125,11 @@ impl<SC: SlotCompatible> Stream for Slots<SC> {
self.inner_delay = Some(Delay::new(ends_in));
// never yield the same slot twice.
if slot_num > self.last_slot {
self.last_slot = slot_num;
if slot > self.last_slot {
self.last_slot = slot;
break Poll::Ready(Some(Ok(SlotInfo {
number: slot_num,
slot,
duration: self.slot_duration,
timestamp,
ends_at,
+3 -3
View File
@@ -151,8 +151,8 @@ impl<T: Config> FindAuthor<u32> for Module<T> {
{
for (id, mut data) in digests.into_iter() {
if id == AURA_ENGINE_ID {
if let Ok(slot_num) = u64::decode(&mut data) {
let author_index = slot_num % Self::authorities().len() as u64;
if let Ok(slot) = u64::decode(&mut data) {
let author_index = slot % Self::authorities().len() as u64;
return Some(author_index as u32)
}
}
@@ -242,7 +242,7 @@ impl<T: Config> ProvideInherent for Module<T> {
let timestamp_based_slot = timestamp / Self::slot_duration();
let seal_slot = data.aura_inherent_data()?.saturated_into();
let seal_slot = u64::from(data.aura_inherent_data()?).saturated_into();
if timestamp_based_slot == seal_slot {
Ok(())
+9 -9
View File
@@ -36,7 +36,7 @@
//!
use frame_support::{debug, traits::KeyOwnerProofSystem};
use sp_consensus_babe::{EquivocationProof, SlotNumber};
use sp_consensus_babe::{EquivocationProof, Slot};
use sp_runtime::transaction_validity::{
InvalidTransaction, TransactionPriority, TransactionSource, TransactionValidity,
TransactionValidityError, ValidTransaction,
@@ -63,7 +63,7 @@ pub trait HandleEquivocation<T: Config> {
) -> Result<(), OffenceError>;
/// Returns true if all of the offenders at the given time slot have already been reported.
fn is_known_offence(offenders: &[T::KeyOwnerIdentification], time_slot: &SlotNumber) -> bool;
fn is_known_offence(offenders: &[T::KeyOwnerIdentification], time_slot: &Slot) -> bool;
/// Create and dispatch an equivocation report extrinsic.
fn submit_unsigned_equivocation_report(
@@ -83,7 +83,7 @@ impl<T: Config> HandleEquivocation<T> for () {
Ok(())
}
fn is_known_offence(_offenders: &[T::KeyOwnerIdentification], _time_slot: &SlotNumber) -> bool {
fn is_known_offence(_offenders: &[T::KeyOwnerIdentification], _time_slot: &Slot) -> bool {
true
}
@@ -136,7 +136,7 @@ where
R::report_offence(reporters, offence)
}
fn is_known_offence(offenders: &[T::KeyOwnerIdentification], time_slot: &SlotNumber) -> bool {
fn is_known_offence(offenders: &[T::KeyOwnerIdentification], time_slot: &Slot) -> bool {
R::is_known_offence(offenders, time_slot)
}
@@ -187,7 +187,7 @@ impl<T: Config> frame_support::unsigned::ValidateUnsigned for Module<T> {
// Only one equivocation report for the same offender at the same slot.
.and_provides((
equivocation_proof.offender.clone(),
equivocation_proof.slot_number,
*equivocation_proof.slot,
))
// We don't propagate this. This can never be included on a remote node.
.propagate(false)
@@ -212,7 +212,7 @@ impl<T: Config> frame_support::unsigned::ValidateUnsigned for Module<T> {
// and if so then we can discard the report.
let is_known_offence = T::HandleEquivocation::is_known_offence(
&[offender],
&equivocation_proof.slot_number,
&equivocation_proof.slot,
);
if is_known_offence {
@@ -230,8 +230,8 @@ impl<T: Config> frame_support::unsigned::ValidateUnsigned for Module<T> {
///
/// When a validator released two or more blocks at the same slot.
pub struct BabeEquivocationOffence<FullIdentification> {
/// A babe slot number in which this incident happened.
pub slot: SlotNumber,
/// A babe slot in which this incident happened.
pub slot: Slot,
/// The session index in which the incident happened.
pub session_index: SessionIndex,
/// The size of the validator set at the time of the offence.
@@ -244,7 +244,7 @@ impl<FullIdentification: Clone> Offence<FullIdentification>
for BabeEquivocationOffence<FullIdentification>
{
const ID: Kind = *b"babe:equivocatio";
type TimeSlot = SlotNumber;
type TimeSlot = Slot;
fn offenders(&self) -> Vec<FullIdentification> {
vec![self.offender.clone()]
+21 -21
View File
@@ -43,7 +43,7 @@ use sp_timestamp::OnTimestampSet;
use sp_consensus_babe::{
digests::{NextConfigDescriptor, NextEpochDescriptor, PreDigest},
inherents::{BabeInherentData, INHERENT_IDENTIFIER},
BabeAuthorityWeight, ConsensusLog, Epoch, EquivocationProof, SlotNumber, BABE_ENGINE_ID,
BabeAuthorityWeight, ConsensusLog, Epoch, EquivocationProof, Slot, BABE_ENGINE_ID,
};
use sp_consensus_vrf::schnorrkel;
use sp_inherents::{InherentData, InherentIdentifier, MakeFatalError, ProvideInherent};
@@ -66,7 +66,7 @@ pub trait Config: pallet_timestamp::Config {
/// The amount of time, in slots, that each epoch should last.
/// NOTE: Currently it is not possible to change the epoch duration after
/// the chain has started. Attempting to do so will brick block production.
type EpochDuration: Get<SlotNumber>;
type EpochDuration: Get<u64>;
/// The expected average block time at which BABE should be creating
/// blocks. Since BABE is probabilistic it is not trivial to figure out
@@ -168,10 +168,10 @@ decl_storage! {
/// The slot at which the first epoch actually started. This is 0
/// until the first block of the chain.
pub GenesisSlot get(fn genesis_slot): u64;
pub GenesisSlot get(fn genesis_slot): Slot;
/// Current slot number.
pub CurrentSlot get(fn current_slot): u64;
pub CurrentSlot get(fn current_slot): Slot;
/// The epoch randomness for the *current* epoch.
///
@@ -403,7 +403,7 @@ impl<T: Config> Module<T> {
// so we don't rotate the epoch.
now != One::one() && {
let diff = CurrentSlot::get().saturating_sub(Self::current_epoch_start());
diff >= T::EpochDuration::get()
*diff >= T::EpochDuration::get()
}
}
@@ -424,7 +424,7 @@ impl<T: Config> Module<T> {
pub fn next_expected_epoch_change(now: T::BlockNumber) -> Option<T::BlockNumber> {
let next_slot = Self::current_epoch_start().saturating_add(T::EpochDuration::get());
next_slot
.checked_sub(CurrentSlot::get())
.checked_sub(*CurrentSlot::get())
.map(|slots_remaining| {
// This is a best effort guess. Drifts in the slot/block ratio will cause errors here.
let blocks_remaining: T::BlockNumber = slots_remaining.saturated_into();
@@ -490,10 +490,10 @@ impl<T: Config> Module<T> {
}
}
// finds the start slot of the current epoch. only guaranteed to
// give correct results after `do_initialize` of the first block
// in the chain (as its result is based off of `GenesisSlot`).
pub fn current_epoch_start() -> SlotNumber {
/// Finds the start slot of the current epoch. only guaranteed to
/// give correct results after `do_initialize` of the first block
/// in the chain (as its result is based off of `GenesisSlot`).
pub fn current_epoch_start() -> Slot {
Self::epoch_start(EpochIndex::get())
}
@@ -525,7 +525,7 @@ impl<T: Config> Module<T> {
}
}
fn epoch_start(epoch_index: u64) -> SlotNumber {
fn epoch_start(epoch_index: u64) -> Slot {
// (epoch_index * epoch_duration) + genesis_slot
const PROOF: &str = "slot number is u64; it should relate in some way to wall clock time; \
@@ -535,7 +535,7 @@ impl<T: Config> Module<T> {
.checked_mul(T::EpochDuration::get())
.expect(PROOF);
epoch_start.checked_add(GenesisSlot::get()).expect(PROOF)
epoch_start.checked_add(*GenesisSlot::get()).expect(PROOF).into()
}
fn deposit_consensus<U: Encode>(new: U) {
@@ -583,9 +583,9 @@ impl<T: Config> Module<T> {
// on the first non-zero block (i.e. block #1)
// this is where the first epoch (epoch #0) actually starts.
// we need to adjust internal storage accordingly.
if GenesisSlot::get() == 0 {
GenesisSlot::put(digest.slot_number());
debug_assert_ne!(GenesisSlot::get(), 0);
if *GenesisSlot::get() == 0 {
GenesisSlot::put(digest.slot());
debug_assert_ne!(*GenesisSlot::get(), 0);
// deposit a log because this is the first block in epoch #0
// we use the same values as genesis because we haven't collected any
@@ -599,11 +599,11 @@ impl<T: Config> Module<T> {
}
// the slot number of the current block being initialized
let current_slot = digest.slot_number();
let current_slot = digest.slot();
// how many slots were skipped between current and last block
let lateness = current_slot.saturating_sub(CurrentSlot::get() + 1);
let lateness = T::BlockNumber::from(lateness as u32);
let lateness = T::BlockNumber::from(*lateness as u32);
Lateness::<T>::put(lateness);
CurrentSlot::put(current_slot);
@@ -684,7 +684,7 @@ impl<T: Config> Module<T> {
key_owner_proof: T::KeyOwnerProof,
) -> DispatchResultWithPostInfo {
let offender = equivocation_proof.offender.clone();
let slot_number = equivocation_proof.slot_number;
let slot = equivocation_proof.slot;
// validate the equivocation proof
if !sp_consensus_babe::check_equivocation_proof(equivocation_proof) {
@@ -694,7 +694,7 @@ impl<T: Config> Module<T> {
let validator_set_count = key_owner_proof.validator_count();
let session_index = key_owner_proof.session();
let epoch_index = (slot_number.saturating_sub(GenesisSlot::get()) / T::EpochDuration::get())
let epoch_index = (*slot.saturating_sub(GenesisSlot::get()) / T::EpochDuration::get())
.saturated_into::<u32>();
// check that the slot number is consistent with the session index
@@ -709,7 +709,7 @@ impl<T: Config> Module<T> {
.ok_or(Error::<T>::InvalidKeyOwnershipProof)?;
let offence = BabeEquivocationOffence {
slot: slot_number,
slot,
validator_set_count,
offender,
session_index,
@@ -837,7 +837,7 @@ impl<T: Config> ProvideInherent for Module<T> {
let timestamp_based_slot = (timestamp / Self::slot_duration()).saturated_into::<u64>();
let seal_slot = data.babe_inherent_data()?;
if timestamp_based_slot == seal_slot {
if timestamp_based_slot == *seal_slot {
Ok(())
} else {
Err(sp_inherents::Error::from("timestamp set in block doesn't match slot in seal").into())
+17 -17
View File
@@ -33,7 +33,7 @@ use frame_support::{
};
use sp_io;
use sp_core::{H256, U256, crypto::{IsWrappedBy, KeyTypeId, Pair}};
use sp_consensus_babe::{AuthorityId, AuthorityPair, SlotNumber};
use sp_consensus_babe::{AuthorityId, AuthorityPair, Slot};
use sp_consensus_vrf::schnorrkel::{VRFOutput, VRFProof};
use sp_staking::SessionIndex;
use pallet_staking::EraIndex;
@@ -255,14 +255,14 @@ pub fn go_to_block(n: u64, s: u64) {
System::parent_hash()
};
let pre_digest = make_secondary_plain_pre_digest(0, s);
let pre_digest = make_secondary_plain_pre_digest(0, s.into());
System::initialize(&n, &parent_hash, &pre_digest, InitKind::Full);
System::set_block_number(n);
Timestamp::set_timestamp(n);
if s > 1 {
CurrentSlot::put(s);
CurrentSlot::put(Slot::from(s));
}
System::on_initialize(n);
@@ -272,8 +272,8 @@ pub fn go_to_block(n: u64, s: u64) {
/// Slots will grow accordingly to blocks
pub fn progress_to_block(n: u64) {
let mut slot = Babe::current_slot() + 1;
for i in System::block_number()+1..=n {
let mut slot = u64::from(Babe::current_slot()) + 1;
for i in System::block_number() + 1 ..= n {
go_to_block(i, slot);
slot += 1;
}
@@ -294,14 +294,14 @@ pub fn start_era(era_index: EraIndex) {
pub fn make_primary_pre_digest(
authority_index: sp_consensus_babe::AuthorityIndex,
slot_number: sp_consensus_babe::SlotNumber,
slot: sp_consensus_babe::Slot,
vrf_output: VRFOutput,
vrf_proof: VRFProof,
) -> Digest {
let digest_data = sp_consensus_babe::digests::PreDigest::Primary(
sp_consensus_babe::digests::PrimaryPreDigest {
authority_index,
slot_number,
slot,
vrf_output,
vrf_proof,
}
@@ -312,12 +312,12 @@ pub fn make_primary_pre_digest(
pub fn make_secondary_plain_pre_digest(
authority_index: sp_consensus_babe::AuthorityIndex,
slot_number: sp_consensus_babe::SlotNumber,
slot: sp_consensus_babe::Slot,
) -> Digest {
let digest_data = sp_consensus_babe::digests::PreDigest::SecondaryPlain(
sp_consensus_babe::digests::SecondaryPlainPreDigest {
authority_index,
slot_number,
slot,
}
);
let log = DigestItem::PreRuntime(sp_consensus_babe::BABE_ENGINE_ID, digest_data.encode());
@@ -326,14 +326,14 @@ pub fn make_secondary_plain_pre_digest(
pub fn make_secondary_vrf_pre_digest(
authority_index: sp_consensus_babe::AuthorityIndex,
slot_number: sp_consensus_babe::SlotNumber,
slot: sp_consensus_babe::Slot,
vrf_output: VRFOutput,
vrf_proof: VRFProof,
) -> Digest {
let digest_data = sp_consensus_babe::digests::PreDigest::SecondaryVRF(
sp_consensus_babe::digests::SecondaryVRFPreDigest {
authority_index,
slot_number,
slot,
vrf_output,
vrf_proof,
}
@@ -343,11 +343,11 @@ pub fn make_secondary_vrf_pre_digest(
}
pub fn make_vrf_output(
slot_number: u64,
slot: Slot,
pair: &sp_consensus_babe::AuthorityPair
) -> (VRFOutput, VRFProof, [u8; 32]) {
let pair = sp_core::sr25519::Pair::from_ref(pair).as_ref();
let transcript = sp_consensus_babe::make_transcript(&Babe::randomness(), slot_number, 0);
let transcript = sp_consensus_babe::make_transcript(&Babe::randomness(), slot, 0);
let vrf_inout = pair.vrf_sign(transcript);
let vrf_randomness: sp_consensus_vrf::schnorrkel::Randomness = vrf_inout.0
.make_bytes::<[u8; 32]>(&sp_consensus_babe::BABE_VRF_INOUT_CONTEXT);
@@ -435,7 +435,7 @@ pub fn new_test_ext_raw_authorities(authorities: Vec<AuthorityId>) -> sp_io::Tes
pub fn generate_equivocation_proof(
offender_authority_index: u32,
offender_authority_pair: &AuthorityPair,
slot_number: SlotNumber,
slot: Slot,
) -> sp_consensus_babe::EquivocationProof<Header> {
use sp_consensus_babe::digests::CompatibleDigestItem;
@@ -444,7 +444,7 @@ pub fn generate_equivocation_proof(
let make_header = || {
let parent_hash = System::parent_hash();
let pre_digest = make_secondary_plain_pre_digest(offender_authority_index, slot_number);
let pre_digest = make_secondary_plain_pre_digest(offender_authority_index, slot);
System::initialize(&current_block, &parent_hash, &pre_digest, InitKind::Full);
System::set_block_number(current_block);
Timestamp::set_timestamp(current_block);
@@ -469,10 +469,10 @@ pub fn generate_equivocation_proof(
seal_header(&mut h2);
// restore previous runtime state
go_to_block(current_block, current_slot);
go_to_block(current_block, *current_slot);
sp_consensus_babe::EquivocationProof {
slot_number,
slot,
offender: offender_authority_pair.public(),
first_header: h1,
second_header: h2,
+15 -15
View File
@@ -25,7 +25,7 @@ use frame_support::{
};
use mock::*;
use pallet_session::ShouldEndSession;
use sp_consensus_babe::AllowedSlots;
use sp_consensus_babe::{AllowedSlots, Slot};
use sp_core::crypto::Pair;
const EMPTY_RANDOMNESS: [u8; 32] = [
@@ -62,7 +62,7 @@ fn first_block_epoch_zero_start() {
let (pairs, mut ext) = new_test_ext_with_pairs(4);
ext.execute_with(|| {
let genesis_slot = 100;
let genesis_slot = Slot::from(100);
let (vrf_output, vrf_proof, vrf_randomness) = make_vrf_output(genesis_slot, &pairs[0]);
let first_vrf = vrf_output;
@@ -73,7 +73,7 @@ fn first_block_epoch_zero_start() {
vrf_proof,
);
assert_eq!(Babe::genesis_slot(), 0);
assert_eq!(Babe::genesis_slot(), Slot::from(0));
System::initialize(
&1,
&Default::default(),
@@ -120,7 +120,7 @@ fn author_vrf_output_for_primary() {
let (pairs, mut ext) = new_test_ext_with_pairs(1);
ext.execute_with(|| {
let genesis_slot = 10;
let genesis_slot = Slot::from(10);
let (vrf_output, vrf_proof, vrf_randomness) = make_vrf_output(genesis_slot, &pairs[0]);
let primary_pre_digest = make_primary_pre_digest(0, genesis_slot, vrf_output, vrf_proof);
@@ -146,7 +146,7 @@ fn author_vrf_output_for_secondary_vrf() {
let (pairs, mut ext) = new_test_ext_with_pairs(1);
ext.execute_with(|| {
let genesis_slot = 10;
let genesis_slot = Slot::from(10);
let (vrf_output, vrf_proof, vrf_randomness) = make_vrf_output(genesis_slot, &pairs[0]);
let secondary_vrf_pre_digest = make_secondary_vrf_pre_digest(0, genesis_slot, vrf_output, vrf_proof);
@@ -170,7 +170,7 @@ fn author_vrf_output_for_secondary_vrf() {
#[test]
fn no_author_vrf_output_for_secondary_plain() {
new_test_ext(1).execute_with(|| {
let genesis_slot = 10;
let genesis_slot = Slot::from(10);
let secondary_plain_pre_digest = make_secondary_plain_pre_digest(0, genesis_slot);
System::initialize(
@@ -205,17 +205,17 @@ fn can_predict_next_epoch_change() {
assert_eq!(<Test as Config>::EpochDuration::get(), 3);
// this sets the genesis slot to 6;
go_to_block(1, 6);
assert_eq!(Babe::genesis_slot(), 6);
assert_eq!(Babe::current_slot(), 6);
assert_eq!(*Babe::genesis_slot(), 6);
assert_eq!(*Babe::current_slot(), 6);
assert_eq!(Babe::epoch_index(), 0);
progress_to_block(5);
assert_eq!(Babe::epoch_index(), 5 / 3);
assert_eq!(Babe::current_slot(), 10);
assert_eq!(*Babe::current_slot(), 10);
// next epoch change will be at
assert_eq!(Babe::current_epoch_start(), 9); // next change will be 12, 2 slots from now
assert_eq!(*Babe::current_epoch_start(), 9); // next change will be 12, 2 slots from now
assert_eq!(Babe::next_expected_epoch_change(System::block_number()), Some(5 + 2));
})
}
@@ -226,8 +226,8 @@ fn can_enact_next_config() {
assert_eq!(<Test as Config>::EpochDuration::get(), 3);
// this sets the genesis slot to 6;
go_to_block(1, 6);
assert_eq!(Babe::genesis_slot(), 6);
assert_eq!(Babe::current_slot(), 6);
assert_eq!(*Babe::genesis_slot(), 6);
assert_eq!(*Babe::current_slot(), 6);
assert_eq!(Babe::epoch_index(), 0);
go_to_block(2, 7);
@@ -269,12 +269,12 @@ fn can_fetch_current_and_next_epoch_data() {
let current_epoch = Babe::current_epoch();
assert_eq!(current_epoch.epoch_index, 3);
assert_eq!(current_epoch.start_slot, 10);
assert_eq!(*current_epoch.start_slot, 10);
assert_eq!(current_epoch.authorities.len(), 5);
let next_epoch = Babe::next_epoch();
assert_eq!(next_epoch.epoch_index, 4);
assert_eq!(next_epoch.start_slot, 13);
assert_eq!(*next_epoch.start_slot, 13);
assert_eq!(next_epoch.authorities.len(), 5);
// the on-chain randomness should always change across epochs
@@ -572,7 +572,7 @@ fn report_equivocation_invalid_equivocation_proof() {
&offending_authority_pair,
CurrentSlot::get(),
);
equivocation_proof.slot_number = 0;
equivocation_proof.slot = Slot::from(0);
assert_invalid_equivocation(equivocation_proof.clone());
// different slot numbers in headers
@@ -31,7 +31,7 @@ use frame_support::traits::{Currency, OnInitialize};
use sp_runtime::{Perbill, traits::{Convert, StaticLookup, Saturating, UniqueSaturatedInto}};
use sp_staking::offence::{ReportOffence, Offence, OffenceDetails};
use pallet_balances::{Config as BalancesConfig};
use pallet_balances::Config as BalancesConfig;
use pallet_babe::BabeEquivocationOffence;
use pallet_grandpa::{GrandpaEquivocationOffence, GrandpaTimeSlot};
use pallet_im_online::{Config as ImOnlineConfig, Module as ImOnline, UnresponsivenessOffence};
@@ -331,7 +331,7 @@ benchmarks! {
let keys = ImOnline::<T>::keys();
let offence = BabeEquivocationOffence {
slot: 0,
slot: 0u64.into(),
session_index: 0,
validator_set_count: keys.len() as u32,
offender: T::convert(offenders.pop().unwrap()),
@@ -20,6 +20,7 @@ sp-api = { version = "2.0.0", default-features = false, path = "../../api" }
sp-runtime = { version = "2.0.0", default-features = false, path = "../../runtime" }
sp-inherents = { version = "2.0.0", default-features = false, path = "../../inherents" }
sp-timestamp = { version = "2.0.0", default-features = false, path = "../../timestamp" }
sp-consensus-slots = { version = "0.8.1", default-features = false, path = "../slots" }
[features]
default = ["std"]
@@ -26,7 +26,7 @@ use sp_inherents::{InherentDataProviders, ProvideInherentData};
pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"auraslot";
/// The type of the Aura inherent.
pub type InherentType = u64;
pub type InherentType = sp_consensus_slots::Slot;
/// Auxiliary trait to extract Aura inherent data.
pub trait AuraInherentData {
@@ -87,8 +87,8 @@ impl ProvideInherentData for InherentDataProvider {
use sp_timestamp::TimestampInherentData;
let timestamp = inherent_data.timestamp_inherent_data()?;
let slot_num = timestamp / self.slot_duration;
inherent_data.put_data(INHERENT_IDENTIFIER, &slot_num)
let slot = timestamp / self.slot_duration;
inherent_data.put_data(INHERENT_IDENTIFIER, &slot)
}
fn error_to_string(&self, error: &[u8]) -> Option<String> {
@@ -19,7 +19,7 @@
use super::{
AllowedSlots, AuthorityId, AuthorityIndex, AuthoritySignature, BabeAuthorityWeight,
BabeEpochConfiguration, SlotNumber, BABE_ENGINE_ID,
BabeEpochConfiguration, Slot, BABE_ENGINE_ID,
};
use codec::{Codec, Decode, Encode};
use sp_std::vec::Vec;
@@ -32,8 +32,8 @@ use sp_consensus_vrf::schnorrkel::{Randomness, VRFOutput, VRFProof};
pub struct PrimaryPreDigest {
/// Authority index
pub authority_index: super::AuthorityIndex,
/// Slot number
pub slot_number: SlotNumber,
/// Slot
pub slot: Slot,
/// VRF output
pub vrf_output: VRFOutput,
/// VRF proof
@@ -50,8 +50,8 @@ pub struct SecondaryPlainPreDigest {
/// it makes things easier for higher-level users of the chain data to
/// be aware of the author of a secondary-slot block.
pub authority_index: super::AuthorityIndex,
/// Slot number
pub slot_number: SlotNumber,
/// Slot
pub slot: Slot,
}
/// BABE secondary deterministic slot assignment with VRF outputs.
@@ -59,8 +59,8 @@ pub struct SecondaryPlainPreDigest {
pub struct SecondaryVRFPreDigest {
/// Authority index
pub authority_index: super::AuthorityIndex,
/// Slot number
pub slot_number: SlotNumber,
/// Slot
pub slot: Slot,
/// VRF output
pub vrf_output: VRFOutput,
/// VRF proof
@@ -93,12 +93,12 @@ impl PreDigest {
}
}
/// Returns the slot number of the pre digest.
pub fn slot_number(&self) -> SlotNumber {
/// Returns the slot of the pre digest.
pub fn slot(&self) -> Slot {
match self {
PreDigest::Primary(primary) => primary.slot_number,
PreDigest::SecondaryPlain(secondary) => secondary.slot_number,
PreDigest::SecondaryVRF(secondary) => secondary.slot_number,
PreDigest::Primary(primary) => primary.slot,
PreDigest::SecondaryPlain(secondary) => secondary.slot,
PreDigest::SecondaryVRF(secondary) => secondary.slot,
}
}
@@ -31,7 +31,7 @@ use sp_std::result::Result;
pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"babeslot";
/// The type of the BABE inherent.
pub type InherentType = u64;
pub type InherentType = sp_consensus_slots::Slot;
/// Auxiliary trait to extract BABE inherent data.
pub trait BabeInherentData {
/// Get BABE inherent data.
@@ -82,8 +82,8 @@ impl ProvideInherentData for InherentDataProvider {
fn provide_inherent_data(&self, inherent_data: &mut InherentData) -> Result<(), Error> {
let timestamp = inherent_data.timestamp_inherent_data()?;
let slot_number = timestamp / self.slot_duration;
inherent_data.put_data(INHERENT_IDENTIFIER, &slot_number)
let slot = timestamp / self.slot_duration;
inherent_data.put_data(INHERENT_IDENTIFIER, &slot)
}
fn error_to_string(&self, error: &[u8]) -> Option<String> {
+15 -16
View File
@@ -76,8 +76,7 @@ pub const MEDIAN_ALGORITHM_CARDINALITY: usize = 1200; // arbitrary suggestion by
/// The index of an authority.
pub type AuthorityIndex = u32;
/// A slot number.
pub use sp_consensus_slots::SlotNumber;
pub use sp_consensus_slots::Slot;
/// 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>;
@@ -93,11 +92,11 @@ pub type BabeBlockWeight = u32;
/// Make a VRF transcript from given randomness, slot number and epoch.
pub fn make_transcript(
randomness: &Randomness,
slot_number: u64,
slot: Slot,
epoch: u64,
) -> Transcript {
let mut transcript = Transcript::new(&BABE_ENGINE_ID);
transcript.append_u64(b"slot number", slot_number);
transcript.append_u64(b"slot number", *slot);
transcript.append_u64(b"current epoch", epoch);
transcript.append_message(b"chain randomness", &randomness[..]);
transcript
@@ -107,13 +106,13 @@ pub fn make_transcript(
#[cfg(feature = "std")]
pub fn make_transcript_data(
randomness: &Randomness,
slot_number: u64,
slot: Slot,
epoch: u64,
) -> VRFTranscriptData {
VRFTranscriptData {
label: &BABE_ENGINE_ID,
items: vec![
("slot number", VRFTranscriptValue::U64(slot_number)),
("slot number", VRFTranscriptValue::U64(*slot)),
("current epoch", VRFTranscriptValue::U64(epoch)),
("chain randomness", VRFTranscriptValue::Bytes(randomness.to_vec())),
]
@@ -147,7 +146,7 @@ pub struct BabeGenesisConfigurationV1 {
pub slot_duration: u64,
/// The duration of epochs in slots.
pub epoch_length: SlotNumber,
pub epoch_length: u64,
/// A constant value that is used in the threshold calculation formula.
/// Expressed as a rational where the first member of the tuple is the
@@ -195,7 +194,7 @@ pub struct BabeGenesisConfiguration {
pub slot_duration: u64,
/// The duration of epochs in slots.
pub epoch_length: SlotNumber,
pub epoch_length: u64,
/// A constant value that is used in the threshold calculation formula.
/// Expressed as a rational where the first member of the tuple is the
@@ -303,8 +302,8 @@ where
// both headers must be targetting the same slot and it must
// be the same as the one in the proof.
if proof.slot_number != first_pre_digest.slot_number() ||
first_pre_digest.slot_number() != second_pre_digest.slot_number()
if proof.slot != first_pre_digest.slot() ||
first_pre_digest.slot() != second_pre_digest.slot()
{
return None;
}
@@ -356,9 +355,9 @@ pub struct Epoch {
/// The epoch index.
pub epoch_index: u64,
/// The starting slot of the epoch.
pub start_slot: SlotNumber,
pub start_slot: Slot,
/// The duration of this epoch.
pub duration: SlotNumber,
pub duration: u64,
/// The authorities and their weights.
pub authorities: Vec<(AuthorityId, BabeAuthorityWeight)>,
/// Randomness for this epoch.
@@ -376,8 +375,8 @@ sp_api::decl_runtime_apis! {
#[changed_in(2)]
fn configuration() -> BabeGenesisConfigurationV1;
/// Returns the slot number that started the current epoch.
fn current_epoch_start() -> SlotNumber;
/// Returns the slot that started the current epoch.
fn current_epoch_start() -> Slot;
/// Returns information regarding the current epoch.
fn current_epoch() -> Epoch;
@@ -391,14 +390,14 @@ sp_api::decl_runtime_apis! {
/// session historical module to prove that a given authority key is
/// tied to a given staking identity during a specific session. Proofs
/// of key ownership are necessary for submitting equivocation reports.
/// NOTE: even though the API takes a `slot_number` as parameter the current
/// NOTE: even though the API takes a `slot` as parameter the current
/// implementations ignores this parameter and instead relies on this
/// method being called at the correct block height, i.e. any point at
/// which the epoch for the given slot is live on-chain. Future
/// implementations will instead use indexed data through an offchain
/// worker, not requiring older states to be available.
fn generate_key_ownership_proof(
slot_number: SlotNumber,
slot: Slot,
authority_id: AuthorityId,
) -> Option<OpaqueKeyOwnershipProof>;
@@ -15,10 +15,12 @@ targets = ["x86_64-unknown-linux-gnu"]
[dependencies]
codec = { package = "parity-scale-codec", version = "1.3.6", default-features = false, features = ["derive"] }
sp-runtime = { version = "2.0.0", default-features = false, path = "../../runtime" }
sp-arithmetic = { version = "2.0.0", default-features = false, path = "../../arithmetic" }
[features]
default = ["std"]
std = [
"codec/std",
"sp-runtime/std",
"sp-arithmetic/std",
]
@@ -21,8 +21,76 @@
use codec::{Decode, Encode};
/// A slot number.
pub type SlotNumber = u64;
/// Unit type wrapper that represents a slot.
#[derive(Debug, Encode, Decode, Eq, Clone, Copy, Default, Ord)]
pub struct Slot(u64);
impl core::ops::Deref for Slot {
type Target = u64;
fn deref(&self) -> &u64 {
&self.0
}
}
impl core::ops::Add for Slot {
type Output = Self;
fn add(self, other: Self) -> Self {
Self(self.0 + other.0)
}
}
impl core::ops::Add<u64> for Slot {
type Output = Self;
fn add(self, other: u64) -> Self {
Self(self.0 + other)
}
}
impl<T: Into<u64> + Copy> core::cmp::PartialEq<T> for Slot {
fn eq(&self, eq: &T) -> bool {
self.0 == (*eq).into()
}
}
impl<T: Into<u64> + Copy> core::cmp::PartialOrd<T> for Slot {
fn partial_cmp(&self, other: &T) -> Option<core::cmp::Ordering> {
self.0.partial_cmp(&(*other).into())
}
}
impl Slot {
/// Saturating addition.
pub fn saturating_add<T: Into<u64>>(self, rhs: T) -> Self {
Self(self.0.saturating_add(rhs.into()))
}
/// Saturating subtraction.
pub fn saturating_sub<T: Into<u64>>(self, rhs: T) -> Self {
Self(self.0.saturating_sub(rhs.into()))
}
}
#[cfg(feature = "std")]
impl std::fmt::Display for Slot {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl From<u64> for Slot {
fn from(slot: u64) -> Slot {
Slot(slot)
}
}
impl From<Slot> for u64 {
fn from(slot: Slot) -> u64 {
slot.0
}
}
/// Represents an equivocation proof. An equivocation happens when a validator
/// produces more than one block on the same slot. The proof of equivocation
@@ -32,8 +100,8 @@ pub type SlotNumber = u64;
pub struct EquivocationProof<Header, Id> {
/// Returns the authority id of the equivocator.
pub offender: Id,
/// The slot number at which the equivocation happened.
pub slot_number: SlotNumber,
/// The slot at which the equivocation happened.
pub slot: Slot,
/// The first header involved in the equivocation.
pub first_header: Header,
/// The second header involved in the equivocation.
+5 -5
View File
@@ -61,7 +61,7 @@ use sp_inherents::{CheckInherentsResult, InherentData};
use cfg_if::cfg_if;
// Ensure Babe and Aura use the same crypto to simplify things a bit.
pub use sp_consensus_babe::{AuthorityId, SlotNumber, AllowedSlots};
pub use sp_consensus_babe::{AuthorityId, Slot, AllowedSlots};
pub type AuraId = sp_consensus_aura::sr25519::AuthorityId;
@@ -739,7 +739,7 @@ cfg_if! {
}
}
fn current_epoch_start() -> sp_consensus_babe::SlotNumber {
fn current_epoch_start() -> Slot {
<pallet_babe::Module<Runtime>>::current_epoch_start()
}
@@ -761,7 +761,7 @@ cfg_if! {
}
fn generate_key_ownership_proof(
_slot_number: sp_consensus_babe::SlotNumber,
_slot: sp_consensus_babe::Slot,
_authority_id: sp_consensus_babe::AuthorityId,
) -> Option<sp_consensus_babe::OpaqueKeyOwnershipProof> {
None
@@ -998,7 +998,7 @@ cfg_if! {
}
}
fn current_epoch_start() -> sp_consensus_babe::SlotNumber {
fn current_epoch_start() -> Slot {
<pallet_babe::Module<Runtime>>::current_epoch_start()
}
@@ -1020,7 +1020,7 @@ cfg_if! {
}
fn generate_key_ownership_proof(
_slot_number: sp_consensus_babe::SlotNumber,
_slot: sp_consensus_babe::Slot,
_authority_id: sp_consensus_babe::AuthorityId,
) -> Option<sp_consensus_babe::OpaqueKeyOwnershipProof> {
None