mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 01:11:10 +00:00
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:
@@ -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.
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user