mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-18 23:25:40 +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:
@@ -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(
|
||||
¶m,
|
||||
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(
|
||||
¶m,
|
||||
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(
|
||||
¶m,
|
||||
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",
|
||||
)
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user