mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-15 03:21:06 +00:00
Run cargo fmt on the whole code base (#9394)
* Run cargo fmt on the whole code base * Second run * Add CI check * Fix compilation * More unnecessary braces * Handle weights * Use --all * Use correct attributes... * Fix UI tests * AHHHHHHHHH * 🤦 * Docs * Fix compilation * 🤷 * Please stop * 🤦 x 2 * More * make rustfmt.toml consistent with polkadot Co-authored-by: André Silva <andrerfosilva@gmail.com>
This commit is contained in:
@@ -25,19 +25,19 @@
|
||||
#![forbid(unsafe_code)]
|
||||
#![warn(missing_docs)]
|
||||
|
||||
mod slots;
|
||||
mod aux_schema;
|
||||
mod slots;
|
||||
|
||||
pub use aux_schema::{check_equivocation, MAX_SLOT_CAPACITY, PRUNING_BOUND};
|
||||
pub use slots::SlotInfo;
|
||||
use slots::Slots;
|
||||
pub use aux_schema::{check_equivocation, MAX_SLOT_CAPACITY, PRUNING_BOUND};
|
||||
|
||||
use std::{fmt::Debug, ops::Deref, time::Duration};
|
||||
use codec::{Decode, Encode};
|
||||
use futures::{future::Either, Future, TryFutureExt};
|
||||
use futures_timer::Delay;
|
||||
use log::{debug, error, info, warn};
|
||||
use sp_api::{ProvideRuntimeApi, ApiRef};
|
||||
use sc_telemetry::{telemetry, TelemetryHandle, CONSENSUS_DEBUG, CONSENSUS_INFO, CONSENSUS_WARN};
|
||||
use sp_api::{ApiRef, ProvideRuntimeApi};
|
||||
use sp_arithmetic::traits::BaseArithmetic;
|
||||
use sp_consensus::{
|
||||
BlockImport, CanAuthorWith, JustificationSyncLink, Proposer, SelectChain, SlotData, SyncOracle,
|
||||
@@ -46,10 +46,10 @@ use sp_consensus_slots::Slot;
|
||||
use sp_inherents::CreateInherentDataProviders;
|
||||
use sp_runtime::{
|
||||
generic::BlockId,
|
||||
traits::{Block as BlockT, Header as HeaderT, HashFor, NumberFor}
|
||||
traits::{Block as BlockT, HashFor, Header as HeaderT, NumberFor},
|
||||
};
|
||||
use sc_telemetry::{telemetry, TelemetryHandle, CONSENSUS_DEBUG, CONSENSUS_WARN, CONSENSUS_INFO};
|
||||
use sp_timestamp::Timestamp;
|
||||
use std::{fmt::Debug, ops::Deref, time::Duration};
|
||||
|
||||
/// The changes that need to applied to the storage to create the state for a block.
|
||||
///
|
||||
@@ -76,10 +76,7 @@ pub trait SlotWorker<B: BlockT, Proof> {
|
||||
///
|
||||
/// Returns a future that resolves to a [`SlotResult`] iff a block was successfully built in
|
||||
/// the slot. Otherwise `None` is returned.
|
||||
async fn on_slot(
|
||||
&mut self,
|
||||
slot_info: SlotInfo<B>,
|
||||
) -> Option<SlotResult<B, Proof>>;
|
||||
async fn on_slot(&mut self, slot_info: SlotInfo<B>) -> Option<SlotResult<B, Proof>>;
|
||||
}
|
||||
|
||||
/// A skeleton implementation for `SlotWorker` which tries to claim a slot at
|
||||
@@ -89,7 +86,8 @@ pub trait SlotWorker<B: BlockT, Proof> {
|
||||
pub trait SimpleSlotWorker<B: BlockT> {
|
||||
/// A handle to a `BlockImport`.
|
||||
type BlockImport: BlockImport<B, Transaction = <Self::Proposer as Proposer<B>>::Transaction>
|
||||
+ Send + 'static;
|
||||
+ Send
|
||||
+ 'static;
|
||||
|
||||
/// A handle to a `SyncOracle`.
|
||||
type SyncOracle: SyncOracle;
|
||||
@@ -100,7 +98,9 @@ pub trait SimpleSlotWorker<B: BlockT> {
|
||||
|
||||
/// The type of future resolving to the proposer.
|
||||
type CreateProposer: Future<Output = Result<Self::Proposer, sp_consensus::Error>>
|
||||
+ Send + Unpin + 'static;
|
||||
+ Send
|
||||
+ Unpin
|
||||
+ 'static;
|
||||
|
||||
/// The type of proposer to use to build blocks.
|
||||
type Proposer: Proposer<B> + Send;
|
||||
@@ -139,12 +139,7 @@ pub trait SimpleSlotWorker<B: BlockT> {
|
||||
|
||||
/// Notifies the given slot. Similar to `claim_slot`, but will be called no matter whether we
|
||||
/// need to author blocks or not.
|
||||
fn notify_slot(
|
||||
&self,
|
||||
_header: &B::Header,
|
||||
_slot: Slot,
|
||||
_epoch_data: &Self::EpochData,
|
||||
) {}
|
||||
fn notify_slot(&self, _header: &B::Header, _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(
|
||||
@@ -154,18 +149,24 @@ pub trait SimpleSlotWorker<B: BlockT> {
|
||||
) -> Vec<sp_runtime::DigestItem<B::Hash>>;
|
||||
|
||||
/// Returns a function which produces a `BlockImportParams`.
|
||||
fn block_import_params(&self) -> Box<
|
||||
fn block_import_params(
|
||||
&self,
|
||||
) -> Box<
|
||||
dyn Fn(
|
||||
B::Header,
|
||||
&B::Hash,
|
||||
Vec<B::Extrinsic>,
|
||||
StorageChanges<<Self::BlockImport as BlockImport<B>>::Transaction, B>,
|
||||
Self::Claim,
|
||||
Self::EpochData,
|
||||
) -> Result<
|
||||
sp_consensus::BlockImportParams<B, <Self::BlockImport as BlockImport<B>>::Transaction>,
|
||||
sp_consensus::Error
|
||||
> + Send + 'static
|
||||
B::Header,
|
||||
&B::Hash,
|
||||
Vec<B::Extrinsic>,
|
||||
StorageChanges<<Self::BlockImport as BlockImport<B>>::Transaction, B>,
|
||||
Self::Claim,
|
||||
Self::EpochData,
|
||||
) -> Result<
|
||||
sp_consensus::BlockImportParams<
|
||||
B,
|
||||
<Self::BlockImport as BlockImport<B>>::Transaction,
|
||||
>,
|
||||
sp_consensus::Error,
|
||||
> + Send
|
||||
+ 'static,
|
||||
>;
|
||||
|
||||
/// Whether to force authoring if offline.
|
||||
@@ -194,10 +195,7 @@ pub trait SimpleSlotWorker<B: BlockT> {
|
||||
fn telemetry(&self) -> Option<TelemetryHandle>;
|
||||
|
||||
/// Remaining duration for proposing.
|
||||
fn proposing_remaining_duration(
|
||||
&self,
|
||||
slot_info: &SlotInfo<B>,
|
||||
) -> Duration;
|
||||
fn proposing_remaining_duration(&self, slot_info: &SlotInfo<B>) -> Duration;
|
||||
|
||||
/// Implements [`SlotWorker::on_slot`].
|
||||
async fn on_slot(
|
||||
@@ -213,8 +211,7 @@ pub trait SimpleSlotWorker<B: BlockT> {
|
||||
let proposing_remaining = if proposing_remaining_duration == Duration::default() {
|
||||
debug!(
|
||||
target: logging_target,
|
||||
"Skipping proposal slot {} since there's no time left to propose",
|
||||
slot,
|
||||
"Skipping proposal slot {} since there's no time left to propose", slot,
|
||||
);
|
||||
|
||||
return None
|
||||
@@ -240,8 +237,8 @@ pub trait SimpleSlotWorker<B: BlockT> {
|
||||
"err" => ?err,
|
||||
);
|
||||
|
||||
return None;
|
||||
}
|
||||
return None
|
||||
},
|
||||
};
|
||||
|
||||
self.notify_slot(&slot_info.chain_head, slot, &epoch_data);
|
||||
@@ -260,13 +257,13 @@ pub trait SimpleSlotWorker<B: BlockT> {
|
||||
"authorities_len" => authorities_len,
|
||||
);
|
||||
|
||||
return None;
|
||||
return None
|
||||
}
|
||||
|
||||
let claim = self.claim_slot(&slot_info.chain_head, slot, &epoch_data)?;
|
||||
|
||||
if self.should_backoff(slot, &slot_info.chain_head) {
|
||||
return None;
|
||||
return None
|
||||
}
|
||||
|
||||
debug!(
|
||||
@@ -289,9 +286,7 @@ pub trait SimpleSlotWorker<B: BlockT> {
|
||||
Err(err) => {
|
||||
warn!(
|
||||
target: logging_target,
|
||||
"Unable to author block in slot {:?}: {:?}",
|
||||
slot,
|
||||
err,
|
||||
"Unable to author block in slot {:?}: {:?}", slot, err,
|
||||
);
|
||||
|
||||
telemetry!(
|
||||
@@ -303,7 +298,7 @@ pub trait SimpleSlotWorker<B: BlockT> {
|
||||
);
|
||||
|
||||
return None
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
let logs = self.pre_digest_data(slot, &claim);
|
||||
@@ -311,34 +306,29 @@ pub trait SimpleSlotWorker<B: BlockT> {
|
||||
// deadline our production to 98% of the total time left for proposing. As we deadline
|
||||
// the proposing below to the same total time left, the 2% margin should be enough for
|
||||
// the result to be returned.
|
||||
let proposing = proposer.propose(
|
||||
slot_info.inherent_data,
|
||||
sp_runtime::generic::Digest {
|
||||
logs,
|
||||
},
|
||||
proposing_remaining_duration.mul_f32(0.98),
|
||||
None,
|
||||
).map_err(|e| sp_consensus::Error::ClientImport(format!("{:?}", e)));
|
||||
let proposing = proposer
|
||||
.propose(
|
||||
slot_info.inherent_data,
|
||||
sp_runtime::generic::Digest { logs },
|
||||
proposing_remaining_duration.mul_f32(0.98),
|
||||
None,
|
||||
)
|
||||
.map_err(|e| sp_consensus::Error::ClientImport(format!("{:?}", e)));
|
||||
|
||||
let proposal = match futures::future::select(proposing, proposing_remaining).await {
|
||||
Either::Left((Ok(p), _)) => p,
|
||||
Either::Left((Err(err), _)) => {
|
||||
warn!(
|
||||
target: logging_target,
|
||||
"Proposing failed: {:?}",
|
||||
err,
|
||||
);
|
||||
warn!(target: logging_target, "Proposing failed: {:?}", err,);
|
||||
|
||||
return None
|
||||
},
|
||||
Either::Right(_) => {
|
||||
info!(
|
||||
target: logging_target,
|
||||
"⌛️ Discarding proposal for slot {}; block production took too long",
|
||||
slot,
|
||||
"⌛️ 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")]
|
||||
#[cfg(build_type = "debug")]
|
||||
info!(
|
||||
target: logging_target,
|
||||
"👉 Recompile your node in `--release` mode to mitigate this problem.",
|
||||
@@ -373,14 +363,10 @@ pub trait SimpleSlotWorker<B: BlockT> {
|
||||
) {
|
||||
Ok(bi) => bi,
|
||||
Err(err) => {
|
||||
warn!(
|
||||
target: logging_target,
|
||||
"Failed to create block import params: {:?}",
|
||||
err,
|
||||
);
|
||||
warn!(target: logging_target, "Failed to create block import params: {:?}", err,);
|
||||
|
||||
return None
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
info!(
|
||||
@@ -401,17 +387,14 @@ pub trait SimpleSlotWorker<B: BlockT> {
|
||||
);
|
||||
|
||||
let header = block_import_params.post_header();
|
||||
match block_import
|
||||
.import_block(block_import_params, Default::default())
|
||||
.await
|
||||
{
|
||||
match block_import.import_block(block_import_params, Default::default()).await {
|
||||
Ok(res) => {
|
||||
res.handle_justification(
|
||||
&header.hash(),
|
||||
*header.number(),
|
||||
self.justification_sync_link(),
|
||||
);
|
||||
}
|
||||
},
|
||||
Err(err) => {
|
||||
warn!(
|
||||
target: logging_target,
|
||||
@@ -425,18 +408,17 @@ pub trait SimpleSlotWorker<B: BlockT> {
|
||||
"hash" => ?parent_hash,
|
||||
"err" => ?err,
|
||||
);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
Some(SlotResult {
|
||||
block: B::new(header, body),
|
||||
storage_proof,
|
||||
})
|
||||
Some(SlotResult { block: B::new(header, body), storage_proof })
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<B: BlockT, T: SimpleSlotWorker<B> + Send> SlotWorker<B, <T::Proposer as Proposer<B>>::Proof> for T {
|
||||
impl<B: BlockT, T: SimpleSlotWorker<B> + Send> SlotWorker<B, <T::Proposer as Proposer<B>>::Proof>
|
||||
for T
|
||||
{
|
||||
async fn on_slot(
|
||||
&mut self,
|
||||
slot_info: SlotInfo<B>,
|
||||
@@ -496,8 +478,7 @@ pub async fn start_slot_worker<B, C, W, T, SO, CIDP, CAW, Proof>(
|
||||
mut sync_oracle: SO,
|
||||
create_inherent_data_providers: CIDP,
|
||||
can_author_with: CAW,
|
||||
)
|
||||
where
|
||||
) where
|
||||
B: BlockT,
|
||||
C: SelectChain<B>,
|
||||
W: SlotWorker<B, Proof>,
|
||||
@@ -509,28 +490,25 @@ where
|
||||
{
|
||||
let SlotDuration(slot_duration) = slot_duration;
|
||||
|
||||
let mut slots = Slots::new(
|
||||
slot_duration.slot_duration(),
|
||||
create_inherent_data_providers,
|
||||
client,
|
||||
);
|
||||
let mut slots =
|
||||
Slots::new(slot_duration.slot_duration(), create_inherent_data_providers, client);
|
||||
|
||||
loop {
|
||||
let slot_info = match slots.next_slot().await {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
warn!(target: "slots", "Error while polling for next slot: {:?}", e);
|
||||
return;
|
||||
}
|
||||
return
|
||||
},
|
||||
};
|
||||
|
||||
if sync_oracle.is_major_syncing() {
|
||||
debug!(target: "slots", "Skipping proposal slot due to sync.");
|
||||
continue;
|
||||
continue
|
||||
}
|
||||
|
||||
if let Err(err) = can_author_with
|
||||
.can_author_with(&BlockId::Hash(slot_info.chain_head.hash()))
|
||||
if let Err(err) =
|
||||
can_author_with.can_author_with(&BlockId::Hash(slot_info.chain_head.hash()))
|
||||
{
|
||||
warn!(
|
||||
target: "slots",
|
||||
@@ -559,7 +537,10 @@ pub enum CheckedHeader<H, S> {
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum Error<T> where T: Debug {
|
||||
pub enum Error<T>
|
||||
where
|
||||
T: Debug,
|
||||
{
|
||||
#[error("Slot duration is invalid: {0:?}")]
|
||||
SlotDurationInvalid(SlotDuration<T>),
|
||||
}
|
||||
@@ -591,25 +572,23 @@ impl<T: Clone + Send + Sync + 'static> SlotDuration<T> {
|
||||
///
|
||||
/// `slot_key` is marked as `'static`, as it should really be a
|
||||
/// compile-time constant.
|
||||
pub fn get_or_compute<B: BlockT, C, CB>(client: &C, cb: CB) -> sp_blockchain::Result<Self> where
|
||||
pub fn get_or_compute<B: BlockT, C, CB>(client: &C, cb: CB) -> sp_blockchain::Result<Self>
|
||||
where
|
||||
C: sc_client_api::backend::AuxStore + sc_client_api::UsageProvider<B>,
|
||||
C: ProvideRuntimeApi<B>,
|
||||
CB: FnOnce(ApiRef<C::Api>, &BlockId<B>) -> sp_blockchain::Result<T>,
|
||||
T: SlotData + Encode + Decode + Debug,
|
||||
{
|
||||
let slot_duration = match client.get_aux(T::SLOT_KEY)? {
|
||||
Some(v) => <T as codec::Decode>::decode(&mut &v[..])
|
||||
.map(SlotDuration)
|
||||
.map_err(|_| {
|
||||
sp_blockchain::Error::Backend({
|
||||
error!(target: "slots", "slot duration kept in invalid format");
|
||||
"slot duration kept in invalid format".to_string()
|
||||
})
|
||||
}),
|
||||
Some(v) => <T as codec::Decode>::decode(&mut &v[..]).map(SlotDuration).map_err(|_| {
|
||||
sp_blockchain::Error::Backend({
|
||||
error!(target: "slots", "slot duration kept in invalid format");
|
||||
"slot duration kept in invalid format".to_string()
|
||||
})
|
||||
}),
|
||||
None => {
|
||||
let best_hash = client.usage_info().chain.best_hash;
|
||||
let slot_duration =
|
||||
cb(client.runtime_api(), &BlockId::hash(best_hash))?;
|
||||
let slot_duration = cb(client.runtime_api(), &BlockId::hash(best_hash))?;
|
||||
|
||||
info!(
|
||||
"⏱ Loaded block-time = {:?} from block {:?}",
|
||||
@@ -621,11 +600,13 @@ impl<T: Clone + Send + Sync + 'static> SlotDuration<T> {
|
||||
.using_encoded(|s| client.insert_aux(&[(T::SLOT_KEY, &s[..])], &[]))?;
|
||||
|
||||
Ok(SlotDuration(slot_duration))
|
||||
}
|
||||
},
|
||||
}?;
|
||||
|
||||
if slot_duration.slot_duration() == Default::default() {
|
||||
return Err(sp_blockchain::Error::Application(Box::new(Error::SlotDurationInvalid(slot_duration))))
|
||||
return Err(sp_blockchain::Error::Application(Box::new(Error::SlotDurationInvalid(
|
||||
slot_duration,
|
||||
))))
|
||||
}
|
||||
|
||||
Ok(slot_duration)
|
||||
@@ -687,9 +668,7 @@ pub fn proposing_remaining_duration<Block: BlockT>(
|
||||
) -> Duration {
|
||||
use sp_runtime::traits::Zero;
|
||||
|
||||
let proposing_duration = slot_info
|
||||
.duration
|
||||
.mul_f32(block_proposal_slot_portion.get());
|
||||
let proposing_duration = slot_info.duration.mul_f32(block_proposal_slot_portion.get());
|
||||
|
||||
let slot_remaining = slot_info
|
||||
.ends_at
|
||||
@@ -700,7 +679,7 @@ pub fn proposing_remaining_duration<Block: BlockT>(
|
||||
|
||||
// If parent is genesis block, we don't require any lenience factor.
|
||||
if slot_info.chain_head.number().is_zero() {
|
||||
return proposing_duration;
|
||||
return proposing_duration
|
||||
}
|
||||
|
||||
let parent_slot = match parent_slot {
|
||||
@@ -723,9 +702,7 @@ pub fn proposing_remaining_duration<Block: BlockT>(
|
||||
if let Some(ref max_block_proposal_slot_portion) = max_block_proposal_slot_portion {
|
||||
std::cmp::min(
|
||||
lenient_proposing_duration,
|
||||
slot_info
|
||||
.duration
|
||||
.mul_f32(max_block_proposal_slot_portion.get()),
|
||||
slot_info.duration.mul_f32(max_block_proposal_slot_portion.get()),
|
||||
)
|
||||
} else {
|
||||
lenient_proposing_duration
|
||||
@@ -853,7 +830,7 @@ impl<N: BaseArithmetic> Default for BackoffAuthoringOnFinalizedHeadLagging<N> {
|
||||
|
||||
impl<N> BackoffAuthoringBlocksStrategy<N> for BackoffAuthoringOnFinalizedHeadLagging<N>
|
||||
where
|
||||
N: BaseArithmetic + Copy
|
||||
N: BaseArithmetic + Copy,
|
||||
{
|
||||
fn should_backoff(
|
||||
&self,
|
||||
@@ -865,12 +842,12 @@ where
|
||||
) -> bool {
|
||||
// This should not happen, but we want to keep the previous behaviour if it does.
|
||||
if slot_now <= chain_head_slot {
|
||||
return false;
|
||||
return false
|
||||
}
|
||||
|
||||
let unfinalized_block_length = chain_head_number - finalized_number;
|
||||
let interval = unfinalized_block_length.saturating_sub(self.unfinalized_slack)
|
||||
/ self.authoring_bias;
|
||||
let interval =
|
||||
unfinalized_block_length.saturating_sub(self.unfinalized_slack) / self.authoring_bias;
|
||||
let interval = interval.min(self.max_interval);
|
||||
|
||||
// We're doing arithmetic between block and slot numbers.
|
||||
@@ -906,9 +883,9 @@ impl<N> BackoffAuthoringBlocksStrategy<N> for () {
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use sp_api::NumberFor;
|
||||
use std::time::{Duration, Instant};
|
||||
use substrate_test_runtime_client::runtime::{Block, Header};
|
||||
use sp_api::NumberFor;
|
||||
|
||||
const SLOT_DURATION: Duration = Duration::from_millis(6000);
|
||||
|
||||
@@ -945,10 +922,7 @@ mod test {
|
||||
}
|
||||
|
||||
// but we cap it to a maximum of 20 slots
|
||||
assert_eq!(
|
||||
super::slot_lenience_linear(1u64.into(), &slot(23)),
|
||||
Some(SLOT_DURATION * 20),
|
||||
);
|
||||
assert_eq!(super::slot_lenience_linear(1u64.into(), &slot(23)), Some(SLOT_DURATION * 20),);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1041,7 +1015,15 @@ mod test {
|
||||
let slot_now = 2;
|
||||
|
||||
let should_backoff: Vec<bool> = (slot_now..1000)
|
||||
.map(|s| strategy.should_backoff(head_number, head_slot.into(), finalized_number, s.into(), "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
|
||||
@@ -1105,7 +1087,15 @@ 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.into(), finalized_number, s.into(), "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
|
||||
@@ -1123,11 +1113,7 @@ mod test {
|
||||
};
|
||||
|
||||
let finalized_number = 2;
|
||||
let mut head_state = HeadState {
|
||||
head_number: 4,
|
||||
head_slot: 10,
|
||||
slot_now: 11,
|
||||
};
|
||||
let mut head_state = HeadState { head_number: 4, head_slot: 10, slot_now: 11 };
|
||||
|
||||
let should_backoff = |head_state: &HeadState| -> bool {
|
||||
<dyn BackoffAuthoringBlocksStrategy<NumberFor<Block>>>::should_backoff(
|
||||
@@ -1155,32 +1141,27 @@ mod test {
|
||||
// Gradually start to backoff more and more frequently
|
||||
let expected = [
|
||||
false, false, false, false, false, // no effect
|
||||
true, false,
|
||||
true, false, // 1:1
|
||||
true, true, false,
|
||||
true, true, false, // 2:1
|
||||
true, true, true, false,
|
||||
true, true, true, false, // 3:1
|
||||
true, true, true, true, false,
|
||||
true, true, true, true, false, // 4:1
|
||||
true, true, true, true, true, false,
|
||||
true, true, true, true, true, false, // 5:1
|
||||
true, true, true, true, true, true, false,
|
||||
true, true, true, true, true, true, false, // 6:1
|
||||
true, true, true, true, true, true, true, false,
|
||||
true, true, true, true, true, true, true, false, // 7:1
|
||||
true, true, true, true, true, true, true, true, false,
|
||||
true, true, true, true, true, true, true, true, false, // 8:1
|
||||
true, true, true, true, true, true, true, true, true, false,
|
||||
true, true, true, true, true, true, true, true, true, false, // 9:1
|
||||
true, true, true, true, true, true, true, true, true, true, false,
|
||||
true, true, true, true, true, true, true, true, true, true, false, // 10:1
|
||||
true, true, true, true, true, true, true, true, true, true, true, false,
|
||||
true, true, true, true, true, true, true, true, true, true, true, false, // 11:1
|
||||
true, true, true, true, true, true, true, true, true, true, true, true, false,
|
||||
true, true, true, true, true, true, true, true, true, true, true, true, false, // 12:1
|
||||
true, false, true, false, // 1:1
|
||||
true, true, false, true, true, false, // 2:1
|
||||
true, true, true, false, true, true, true, false, // 3:1
|
||||
true, true, true, true, false, true, true, true, true, false, // 4:1
|
||||
true, true, true, true, true, false, true, true, true, true, true, false, // 5:1
|
||||
true, true, true, true, true, true, false, true, true, true, true, true, true,
|
||||
false, // 6:1
|
||||
true, true, true, true, true, true, true, false, true, true, true, true, true, true,
|
||||
true, false, // 7:1
|
||||
true, true, true, true, true, true, true, true, false, true, true, true, true, true,
|
||||
true, true, true, false, // 8:1
|
||||
true, true, true, true, true, true, true, true, true, false, true, true, true, true,
|
||||
true, true, true, true, true, false, // 9:1
|
||||
true, true, true, true, true, true, true, true, true, true, false, true, true, true,
|
||||
true, true, true, true, true, true, true, false, // 10:1
|
||||
true, true, true, true, true, true, true, true, true, true, true, false, true, true,
|
||||
true, true, true, true, true, true, true, true, true, false, // 11:1
|
||||
true, true, true, true, true, true, true, true, true, true, true, true, false, true,
|
||||
true, true, true, true, true, true, true, true, true, true, true, false, // 12:1
|
||||
true, true, true, true,
|
||||
];
|
||||
];
|
||||
|
||||
assert_eq!(backoff.as_slice(), &expected[..]);
|
||||
}
|
||||
@@ -1195,11 +1176,7 @@ mod test {
|
||||
|
||||
let finalized_number = 2;
|
||||
let starting_slot = 11;
|
||||
let mut head_state = HeadState {
|
||||
head_number: 4,
|
||||
head_slot: 10,
|
||||
slot_now: starting_slot,
|
||||
};
|
||||
let mut head_state = HeadState { head_number: 4, head_slot: 10, slot_now: starting_slot };
|
||||
|
||||
let should_backoff = |head_state: &HeadState| -> bool {
|
||||
<dyn BackoffAuthoringBlocksStrategy<NumberFor<Block>>>::should_backoff(
|
||||
@@ -1240,30 +1217,22 @@ mod test {
|
||||
assert_eq!(last_slot - last_two_claimed.next().unwrap(), 92);
|
||||
assert_eq!(last_slot - last_two_claimed.next().unwrap(), 92 + expected_distance);
|
||||
|
||||
let intervals: Vec<_> = slots_claimed
|
||||
.windows(2)
|
||||
.map(|x| x[1] - x[0])
|
||||
.collect();
|
||||
let intervals: Vec<_> = slots_claimed.windows(2).map(|x| x[1] - x[0]).collect();
|
||||
|
||||
// The key thing is that the distance between claimed slots is capped to `max_interval + 1`
|
||||
// assert_eq!(max_observed_interval, Some(&expected_distance));
|
||||
assert_eq!(intervals.iter().max(), Some(&expected_distance));
|
||||
|
||||
// But lets assert all distances, which we expect to grow linearly until `max_interval + 1`
|
||||
let expected_intervals: Vec<_> = (0..497)
|
||||
.map(|i| (i/2).max(1).min(expected_distance) )
|
||||
.collect();
|
||||
let expected_intervals: Vec<_> =
|
||||
(0..497).map(|i| (i / 2).max(1).min(expected_distance)).collect();
|
||||
|
||||
assert_eq!(intervals, expected_intervals);
|
||||
}
|
||||
|
||||
fn run_until_max_interval(param: BackoffAuthoringOnFinalizedHeadLagging<u64>) -> (u64, u64) {
|
||||
let finalized_number = 0;
|
||||
let mut head_state = HeadState {
|
||||
head_number: 0,
|
||||
head_slot: 0,
|
||||
slot_now: 1,
|
||||
};
|
||||
let mut head_state = HeadState { head_number: 0, head_slot: 0, slot_now: 1 };
|
||||
|
||||
let should_backoff = |head_state: &HeadState| -> bool {
|
||||
<dyn BackoffAuthoringBlocksStrategy<NumberFor<Block>>>::should_backoff(
|
||||
@@ -1277,8 +1246,8 @@ mod test {
|
||||
};
|
||||
|
||||
// Number of blocks until we reach the max interval
|
||||
let block_for_max_interval
|
||||
= param.max_interval * param.authoring_bias + param.unfinalized_slack;
|
||||
let block_for_max_interval =
|
||||
param.max_interval * param.authoring_bias + param.unfinalized_slack;
|
||||
|
||||
while head_state.head_number < block_for_max_interval {
|
||||
if should_backoff(&head_state) {
|
||||
@@ -1294,15 +1263,15 @@ mod test {
|
||||
}
|
||||
|
||||
// Denoting
|
||||
// C: unfinalized_slack
|
||||
// M: authoring_bias
|
||||
// X: max_interval
|
||||
// C: unfinalized_slack
|
||||
// M: authoring_bias
|
||||
// X: max_interval
|
||||
// then the number of slots to reach the max interval can be computed from
|
||||
// (start_slot + C) + M * sum(n, 1, X)
|
||||
// (start_slot + C) + M * sum(n, 1, X)
|
||||
// or
|
||||
// (start_slot + C) + M * X*(X+1)/2
|
||||
// (start_slot + C) + M * X*(X+1)/2
|
||||
fn expected_time_to_reach_max_interval(
|
||||
param: &BackoffAuthoringOnFinalizedHeadLagging<u64>
|
||||
param: &BackoffAuthoringOnFinalizedHeadLagging<u64>,
|
||||
) -> (u64, u64) {
|
||||
let c = param.unfinalized_slack;
|
||||
let m = param.authoring_bias;
|
||||
|
||||
Reference in New Issue
Block a user