Use async_trait in sc-consensus-slots (#8461)

* 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`.

* slots: remove mutex around BlockImport in SlotWorker

Co-authored-by: André Silva <andrerfosilva@gmail.com>
This commit is contained in:
Bastian Köcher
2021-03-27 22:40:28 +01:00
committed by GitHub
parent ff5765eac3
commit 49e79967c8
6 changed files with 179 additions and 155 deletions
+12 -21
View File
@@ -22,10 +22,9 @@
use super::{SlotCompatible, Slot};
use sp_consensus::Error;
use futures::{prelude::*, task::Context, task::Poll};
use sp_inherents::{InherentData, InherentDataProviders};
use std::{pin::Pin, time::{Duration, Instant}};
use std::time::{Duration, Instant};
use futures_timer::Delay;
/// Returns current duration since unix epoch.
@@ -107,57 +106,49 @@ impl<SC> Slots<SC> {
}
}
impl<SC: SlotCompatible> Stream for Slots<SC> {
type Item = Result<SlotInfo, Error>;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
impl<SC: SlotCompatible> Slots<SC> {
/// Returns a future that fires when the next slot starts.
pub async fn next_slot(&mut self) -> Result<SlotInfo, Error> {
loop {
let slot_duration = self.slot_duration;
self.inner_delay = match self.inner_delay.take() {
None => {
// schedule wait.
let wait_dur = time_until_next(duration_now(), slot_duration);
let wait_dur = time_until_next(duration_now(), self.slot_duration);
Some(Delay::new(wait_dur))
}
Some(d) => Some(d),
};
if let Some(ref mut inner_delay) = self.inner_delay {
match Future::poll(Pin::new(inner_delay), cx) {
Poll::Pending => return Poll::Pending,
Poll::Ready(()) => {}
}
if let Some(inner_delay) = self.inner_delay.take() {
inner_delay.await;
}
// timeout has fired.
let inherent_data = match self.inherent_data_providers.create_inherent_data() {
Ok(id) => id,
Err(err) => return Poll::Ready(Some(Err(sp_consensus::Error::InherentData(err)))),
Err(err) => return Err(sp_consensus::Error::InherentData(err)),
};
let result = self.timestamp_extractor.extract_timestamp_and_slot(&inherent_data);
let (timestamp, slot, offset) = match result {
Ok(v) => v,
Err(err) => return Poll::Ready(Some(Err(err))),
Err(err) => return Err(err),
};
// reschedule delay for next slot.
let ends_in = offset +
time_until_next(timestamp.as_duration(), slot_duration);
time_until_next(timestamp.as_duration(), self.slot_duration);
self.inner_delay = Some(Delay::new(ends_in));
// never yield the same slot twice.
if slot > self.last_slot {
self.last_slot = slot;
break Poll::Ready(Some(Ok(SlotInfo::new(
break Ok(SlotInfo::new(
slot,
timestamp,
inherent_data,
self.slot_duration,
))))
))
}
}
}
}
impl<SC> Unpin for Slots<SC> {}