Skip to content

Commit 5a33d7b

Browse files
davxyark0f
authored andcommitted
Refactory of next_slot method (paritytech#13155)
Refactory of `next_slot` method * Prevents slot worker exit if inherent data provider creation fails * Failure is not possible anymore * Fix potential failure after warp-sync where block headers of not already downloaded blocks are used by the inherent data provider
1 parent 2c16a72 commit 5a33d7b

File tree

2 files changed

+34
-33
lines changed

2 files changed

+34
-33
lines changed

client/consensus/slots/src/lib.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -524,13 +524,7 @@ pub async fn start_slot_worker<B, C, W, SO, CIDP, Proof>(
524524
let mut slots = Slots::new(slot_duration.as_duration(), create_inherent_data_providers, client);
525525

526526
loop {
527-
let slot_info = match slots.next_slot().await {
528-
Ok(r) => r,
529-
Err(e) => {
530-
warn!(target: LOG_TARGET, "Error while polling for next slot: {}", e);
531-
return
532-
},
533-
};
527+
let slot_info = slots.next_slot().await;
534528

535529
if sync_oracle.is_major_syncing() {
536530
debug!(target: LOG_TARGET, "Skipping proposal slot due to sync.");

client/consensus/slots/src/slots.rs

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
//! This is used instead of `futures_timer::Interval` because it was unreliable.
2222
2323
use super::{InherentDataProviderExt, Slot, LOG_TARGET};
24-
use sp_consensus::{Error, SelectChain};
24+
use sp_consensus::SelectChain;
2525
use sp_inherents::{CreateInherentDataProviders, InherentDataProvider};
2626
use sp_runtime::traits::{Block as BlockT, Header as HeaderT};
2727

@@ -90,7 +90,7 @@ impl<B: BlockT> SlotInfo<B> {
9090
pub(crate) struct Slots<Block, SC, IDP> {
9191
last_slot: Slot,
9292
slot_duration: Duration,
93-
inner_delay: Option<Delay>,
93+
until_next_slot: Option<Delay>,
9494
create_inherent_data_providers: IDP,
9595
select_chain: SC,
9696
_phantom: std::marker::PhantomData<Block>,
@@ -106,7 +106,7 @@ impl<Block, SC, IDP> Slots<Block, SC, IDP> {
106106
Slots {
107107
last_slot: 0.into(),
108108
slot_duration,
109-
inner_delay: None,
109+
until_next_slot: None,
110110
create_inherent_data_providers,
111111
select_chain,
112112
_phantom: Default::default(),
@@ -122,26 +122,22 @@ where
122122
IDP::InherentDataProviders: crate::InherentDataProviderExt,
123123
{
124124
/// Returns a future that fires when the next slot starts.
125-
pub async fn next_slot(&mut self) -> Result<SlotInfo<Block>, Error> {
125+
pub async fn next_slot(&mut self) -> SlotInfo<Block> {
126126
loop {
127-
self.inner_delay = match self.inner_delay.take() {
128-
None => {
129-
// schedule wait.
127+
// Wait for slot timeout
128+
self.until_next_slot
129+
.take()
130+
.unwrap_or_else(|| {
131+
// Schedule first timeout.
130132
let wait_dur = time_until_next_slot(self.slot_duration);
131-
Some(Delay::new(wait_dur))
132-
},
133-
Some(d) => Some(d),
134-
};
135-
136-
if let Some(inner_delay) = self.inner_delay.take() {
137-
inner_delay.await;
138-
}
139-
// timeout has fired.
133+
Delay::new(wait_dur)
134+
})
135+
.await;
140136

141-
let ends_in = time_until_next_slot(self.slot_duration);
137+
// Schedule delay for next slot.
138+
let wait_dur = time_until_next_slot(self.slot_duration);
139+
self.until_next_slot = Some(Delay::new(wait_dur));
142140

143-
// reschedule delay for next slot.
144-
self.inner_delay = Some(Delay::new(ends_in));
145141
let chain_head = match self.select_chain.best_chain().await {
146142
Ok(x) => x,
147143
Err(e) => {
@@ -150,30 +146,41 @@ where
150146
"Unable to author block in slot. No best block header: {}",
151147
e,
152148
);
153-
// Let's try at the next slot..
154-
self.inner_delay.take();
149+
// Let's retry at the next slot.
155150
continue
156151
},
157152
};
158153

159-
let inherent_data_providers = self
154+
let inherent_data_providers = match self
160155
.create_inherent_data_providers
161156
.create_inherent_data_providers(chain_head.hash(), ())
162-
.await?;
157+
.await
158+
{
159+
Ok(x) => x,
160+
Err(e) => {
161+
log::warn!(
162+
target: LOG_TARGET,
163+
"Unable to author block in slot. Failure creating inherent data provider: {}",
164+
e,
165+
);
166+
// Let's retry at the next slot.
167+
continue
168+
},
169+
};
163170

164171
let slot = inherent_data_providers.slot();
165172

166-
// never yield the same slot twice.
173+
// Never yield the same slot twice.
167174
if slot > self.last_slot {
168175
self.last_slot = slot;
169176

170-
break Ok(SlotInfo::new(
177+
break SlotInfo::new(
171178
slot,
172179
Box::new(inherent_data_providers),
173180
self.slot_duration,
174181
chain_head,
175182
None,
176-
))
183+
)
177184
}
178185
}
179186
}

0 commit comments

Comments
 (0)