mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-21 10:55:42 +00:00
Rework inherent data client side (#8526)
* Lol * Yeah * Moare * adaasda * Convert AURA to new pallet macro * AURA: Switch to `CurrentSlot` instead of `LastTimestamp` This switches AURA to use `CurrentSlot` instead of `LastTimestamp`. * Add missing file * Update frame/aura/src/migrations.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * Remove the runtime side provide inherent code * Use correct weight * Add TODO * Remove the Inherent from AURA * 🤦 * Remove unused stuff * Update primitives authorship * Fix babe inherent data provider * Fix consensus-uncles * Fix BABE * Do some further changes to authorship primitives... :D * More work * Make it compile the happy path * Make it async! * Take hash * More stuff * Hacks * Revert "Hacks" This reverts commit cfffad88668cfdebf632a59c4fbfada001ef8251. * Fix * Make `execute_block` return the final block header * Move Aura digest stuff * Make it possible to disable equivocation checking * Fix fix fix * Some refactorings * Comment * Fixes fixes fixes * More cleanups * Some love * Better love * Make slot duration being exposed as `Duration` to the outside * Some slot info love * Add `build_aura_worker` utility function * Copy copy copy * Some stuff * Start fixing pow * Fix pow * Remove some bounds * More work * Make grandpa work * Make slots use `async_trait` * Introduce `SharedData` * Add test and fix bugs * Switch to `SharedData` * Make grandpa tests working * More Babe work * Make grandpa work * Introduce `SharedData` * Add test and fix bugs * Switch to `SharedData` * Make grandpa tests working * More Babe work * Make it async * Fix fix * Use `async_trait` in sc-consensus-slots This makes the code a little bit easier to read and also expresses that there can always only be one call at a time to `on_slot`. * Make grandpa tests compile * More Babe tests work * Fix network test * Start fixing service test * Finish service-test * Fix sc-consensus-aura * Fix fix fix * More fixes * Make everything compile *yeah* * Make manual-seal compile * More fixes * Start fixing Aura * Fix Aura tests * Fix Babe tests * Make everything compile * Move code around and switch to async_trait * Fix Babe * Docs docs docs * Move to FRAME * Fix fix fix * Make everything compile * Last cleanups * Fix integration test * Change slot usage of the timestamp * We really need to switch to `impl-trait-for-tuples` * Update primitives/inherents/src/lib.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * Update primitives/inherents/src/lib.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * Update primitives/inherents/src/lib.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> * Some extra logging * Remove dbg! * Update primitives/consensus/common/src/import_queue/basic_queue.rs Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com> Co-authored-by: André Silva <123550+andresilva@users.noreply.github.com>
This commit is contained in:
@@ -20,9 +20,10 @@
|
||||
//!
|
||||
//! This is used instead of `futures_timer::Interval` because it was unreliable.
|
||||
|
||||
use super::{SlotCompatible, Slot};
|
||||
use sp_consensus::Error;
|
||||
use sp_inherents::{InherentData, InherentDataProviders};
|
||||
use super::{Slot, InherentDataProviderExt};
|
||||
use sp_consensus::{Error, SelectChain};
|
||||
use sp_inherents::{InherentData, CreateInherentDataProviders, InherentDataProvider};
|
||||
use sp_runtime::traits::{Block as BlockT, Header as HeaderT};
|
||||
|
||||
use std::time::{Duration, Instant};
|
||||
use futures_timer::Delay;
|
||||
@@ -38,19 +39,19 @@ pub fn duration_now() -> Duration {
|
||||
))
|
||||
}
|
||||
|
||||
/// Returns the duration until the next slot, based on current duration since
|
||||
pub fn time_until_next(now: Duration, slot_duration: Duration) -> Duration {
|
||||
/// Returns the duration until the next slot from now.
|
||||
pub fn time_until_next(slot_duration: Duration) -> Duration {
|
||||
let remaining_full_millis = slot_duration.as_millis()
|
||||
- (now.as_millis() % slot_duration.as_millis())
|
||||
- (duration_now().as_millis() % slot_duration.as_millis())
|
||||
- 1;
|
||||
Duration::from_millis(remaining_full_millis as u64)
|
||||
}
|
||||
|
||||
/// Information about a slot.
|
||||
pub struct SlotInfo {
|
||||
/// The slot number.
|
||||
pub struct SlotInfo<B: BlockT> {
|
||||
/// The slot number as found in the inherent data.
|
||||
pub slot: Slot,
|
||||
/// Current timestamp.
|
||||
/// Current timestamp as found in the inherent data.
|
||||
pub timestamp: sp_timestamp::Timestamp,
|
||||
/// The instant at which the slot ends.
|
||||
pub ends_at: Instant,
|
||||
@@ -58,13 +59,15 @@ pub struct SlotInfo {
|
||||
pub inherent_data: InherentData,
|
||||
/// Slot duration.
|
||||
pub duration: Duration,
|
||||
/// The chain header this slot is based on.
|
||||
pub chain_head: B::Header,
|
||||
/// Some potential block size limit for the block to be authored at this slot.
|
||||
///
|
||||
/// For more information see [`Proposer::propose`](sp_consensus::Proposer::propose).
|
||||
pub block_size_limit: Option<usize>,
|
||||
}
|
||||
|
||||
impl SlotInfo {
|
||||
impl<B: BlockT> SlotInfo<B> {
|
||||
/// Create a new [`SlotInfo`].
|
||||
///
|
||||
/// `ends_at` is calculated using `timestamp` and `duration`.
|
||||
@@ -73,6 +76,7 @@ impl SlotInfo {
|
||||
timestamp: sp_timestamp::Timestamp,
|
||||
inherent_data: InherentData,
|
||||
duration: Duration,
|
||||
chain_head: B::Header,
|
||||
block_size_limit: Option<usize>,
|
||||
) -> Self {
|
||||
Self {
|
||||
@@ -80,46 +84,55 @@ impl SlotInfo {
|
||||
timestamp,
|
||||
inherent_data,
|
||||
duration,
|
||||
chain_head,
|
||||
block_size_limit,
|
||||
ends_at: Instant::now() + time_until_next(timestamp.as_duration(), duration),
|
||||
ends_at: Instant::now() + time_until_next(duration),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A stream that returns every time there is a new slot.
|
||||
pub(crate) struct Slots<SC> {
|
||||
pub(crate) struct Slots<Block, C, IDP> {
|
||||
last_slot: Slot,
|
||||
slot_duration: Duration,
|
||||
inner_delay: Option<Delay>,
|
||||
inherent_data_providers: InherentDataProviders,
|
||||
timestamp_extractor: SC,
|
||||
create_inherent_data_providers: IDP,
|
||||
client: C,
|
||||
_phantom: std::marker::PhantomData<Block>,
|
||||
}
|
||||
|
||||
impl<SC> Slots<SC> {
|
||||
impl<Block, C, IDP> Slots<Block, C, IDP> {
|
||||
/// Create a new `Slots` stream.
|
||||
pub fn new(
|
||||
slot_duration: Duration,
|
||||
inherent_data_providers: InherentDataProviders,
|
||||
timestamp_extractor: SC,
|
||||
create_inherent_data_providers: IDP,
|
||||
client: C,
|
||||
) -> Self {
|
||||
Slots {
|
||||
last_slot: 0.into(),
|
||||
slot_duration,
|
||||
inner_delay: None,
|
||||
inherent_data_providers,
|
||||
timestamp_extractor,
|
||||
create_inherent_data_providers,
|
||||
client,
|
||||
_phantom: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<SC: SlotCompatible> Slots<SC> {
|
||||
impl<Block, C, IDP> Slots<Block, C, IDP>
|
||||
where
|
||||
Block: BlockT,
|
||||
C: SelectChain<Block>,
|
||||
IDP: CreateInherentDataProviders<Block, ()>,
|
||||
IDP::InherentDataProviders: crate::InherentDataProviderExt,
|
||||
{
|
||||
/// Returns a future that fires when the next slot starts.
|
||||
pub async fn next_slot(&mut self) -> Result<SlotInfo, Error> {
|
||||
pub async fn next_slot(&mut self) -> Result<SlotInfo<Block>, Error> {
|
||||
loop {
|
||||
self.inner_delay = match self.inner_delay.take() {
|
||||
None => {
|
||||
// schedule wait.
|
||||
let wait_dur = time_until_next(duration_now(), self.slot_duration);
|
||||
let wait_dur = time_until_next(self.slot_duration);
|
||||
Some(Delay::new(wait_dur))
|
||||
}
|
||||
Some(d) => Some(d),
|
||||
@@ -130,15 +143,39 @@ impl<SC: SlotCompatible> Slots<SC> {
|
||||
}
|
||||
// timeout has fired.
|
||||
|
||||
let inherent_data = match self.inherent_data_providers.create_inherent_data() {
|
||||
Ok(id) => id,
|
||||
Err(err) => return Err(sp_consensus::Error::InherentData(err)),
|
||||
let ends_at = Instant::now() + time_until_next(self.slot_duration);
|
||||
|
||||
let chain_head = match self.client.best_chain() {
|
||||
Ok(x) => x,
|
||||
Err(e) => {
|
||||
log::warn!(
|
||||
target: "slots",
|
||||
"Unable to author block in slot. No best block header: {:?}",
|
||||
e,
|
||||
);
|
||||
// Let's try at the next slot..
|
||||
self.inner_delay.take();
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let result = self.timestamp_extractor.extract_timestamp_and_slot(&inherent_data);
|
||||
let (timestamp, slot, offset) = result?;
|
||||
|
||||
let inherent_data_providers = self.create_inherent_data_providers
|
||||
.create_inherent_data_providers(chain_head.hash(), ())
|
||||
.await?;
|
||||
|
||||
if Instant::now() > ends_at {
|
||||
log::warn!(
|
||||
target: "slots",
|
||||
"Creating inherent data providers took more time than we had left for the slot.",
|
||||
);
|
||||
}
|
||||
|
||||
let timestamp = inherent_data_providers.timestamp();
|
||||
let slot = inherent_data_providers.slot();
|
||||
let inherent_data = inherent_data_providers.create_inherent_data()?;
|
||||
|
||||
// reschedule delay for next slot.
|
||||
let ends_in = offset +
|
||||
time_until_next(timestamp.as_duration(), self.slot_duration);
|
||||
let ends_in = time_until_next(self.slot_duration);
|
||||
self.inner_delay = Some(Delay::new(ends_in));
|
||||
|
||||
// never yield the same slot twice.
|
||||
@@ -150,6 +187,7 @@ impl<SC: SlotCompatible> Slots<SC> {
|
||||
timestamp,
|
||||
inherent_data,
|
||||
self.slot_duration,
|
||||
chain_head,
|
||||
None,
|
||||
))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user