Skip to content

Commit 8cf8033

Browse files
acatangiunathanwhit
authored andcommitted
sc-consensus-beefy: fix on-demand async state machine (paritytech#13599)
`futures_util::pending!()` macro only yields to the event loop once, resulting in many calls to the `OnDemandJustificationsEngine::next()` made by the tokio reactor even though the on-demand-engine is idle. Replace it with the correct `futures::future::pending::<()>()` function which forever yields to the event loop, which is what we want when the engine is idle. Signed-off-by: Adrian Catangiu <[email protected]>
1 parent 370d216 commit 8cf8033

File tree

3 files changed

+21
-14
lines changed

3 files changed

+21
-14
lines changed

client/consensus/beefy/src/communication/request_response/outgoing_requests_engine.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ impl<B: Block> OnDemandJustificationsEngine<B> {
207207
pub async fn next(&mut self) -> Option<BeefyVersionedFinalityProof<B>> {
208208
let (peer, req_info, resp) = match &mut self.state {
209209
State::Idle => {
210-
futures::pending!();
210+
futures::future::pending::<()>().await;
211211
return None
212212
},
213213
State::AwaitingResponse(peer, req_info, receiver) => {

client/consensus/beefy/src/tests.rs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -934,7 +934,7 @@ async fn on_demand_beefy_justification_sync() {
934934
let dave_index = 3;
935935

936936
// push 30 blocks
937-
let hashes = net.generate_blocks_and_sync(35, session_len, &validator_set, false).await;
937+
let mut hashes = net.generate_blocks_and_sync(30, session_len, &validator_set, false).await;
938938

939939
let fast_peers = fast_peers.into_iter().enumerate();
940940
let net = Arc::new(Mutex::new(net));
@@ -951,8 +951,16 @@ async fn on_demand_beefy_justification_sync() {
951951
// Spawn Dave, they are now way behind voting and can only catch up through on-demand justif
952952
// sync.
953953
tokio::spawn(dave_task);
954-
// give Dave a chance to spawn and init.
955-
run_for(Duration::from_millis(400), &net).await;
954+
// Dave pushes and syncs 4 more blocks just to make sure he gets included in gossip.
955+
{
956+
let mut net_guard = net.lock();
957+
let built_hashes =
958+
net_guard
959+
.peer(dave_index)
960+
.generate_blocks(4, BlockOrigin::File, |builder| builder.build().unwrap().block);
961+
hashes.extend(built_hashes);
962+
net_guard.run_until_sync().await;
963+
}
956964

957965
let (dave_best_blocks, _) =
958966
get_beefy_streams(&mut net.lock(), [(dave_index, BeefyKeyring::Dave)].into_iter());
@@ -965,7 +973,10 @@ async fn on_demand_beefy_justification_sync() {
965973
// Have the other peers do some gossip so Dave finds out about their progress.
966974
finalize_block_and_wait_for_beefy(&net, fast_peers, &[hashes[25], hashes[29]], &[25, 29]).await;
967975

968-
// Now verify Dave successfully finalized #1 (through on-demand justification request).
976+
// Kick Dave's async loop by finalizing another block.
977+
client.finalize_block(hashes[2], None).unwrap();
978+
979+
// And verify Dave successfully finalized #1 (through on-demand justification request).
969980
wait_for_best_beefy_blocks(dave_best_blocks, &net, &[1]).await;
970981

971982
// Give all tasks some cpu cycles to burn through their events queues,
@@ -978,10 +989,6 @@ async fn on_demand_beefy_justification_sync() {
978989
&[5, 10, 15, 20, 25],
979990
)
980991
.await;
981-
982-
let all_peers = all_peers.into_iter().enumerate();
983-
// Now that Dave has caught up, sanity check voting works for all of them.
984-
finalize_block_and_wait_for_beefy(&net, all_peers, &[hashes[30], hashes[34]], &[30]).await;
985992
}
986993

987994
#[tokio::test]

client/consensus/beefy/src/worker.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -887,11 +887,6 @@ where
887887
// based on the new resulting 'state'.
888888
futures::select_biased! {
889889
// Use `select_biased!` to prioritize order below.
890-
// Make sure to pump gossip engine.
891-
_ = gossip_engine => {
892-
error!(target: LOG_TARGET, "🥩 Gossip engine has terminated, closing worker.");
893-
return;
894-
},
895890
// Process finality notifications first since these drive the voter.
896891
notification = finality_notifications.next() => {
897892
if let Some(notification) = notification {
@@ -901,6 +896,11 @@ where
901896
return;
902897
}
903898
},
899+
// Make sure to pump gossip engine.
900+
_ = gossip_engine => {
901+
error!(target: LOG_TARGET, "🥩 Gossip engine has terminated, closing worker.");
902+
return;
903+
},
904904
// Process incoming justifications as these can make some in-flight votes obsolete.
905905
justif = self.on_demand_justifications.next().fuse() => {
906906
if let Some(justif) = justif {

0 commit comments

Comments
 (0)