client/beefy: fix voter initialization (#12274)

Fix corner case where voter gets a single burst of finality
notifications just when it starts.

The notification stream was consumed by "wait_for_pallet" logic,
then main loop would subscribe to finality notifications, but by that
time some notifications might've been lost.

Fix this by subscribing the main loop to notifications before waiting
for pallet to become available. Share the same stream with the main loop
so that notifications for blocks before pallet available are ignored,
while _all_ notifications after pallet available are processed.

Add regression test for this.

Signed-off-by: acatangiu <adrian@parity.io>
This commit is contained in:
Adrian Catangiu
2022-09-16 10:50:21 +03:00
committed by GitHub
parent c7e3ba09ab
commit d9a4d835d1
2 changed files with 42 additions and 7 deletions
+34
View File
@@ -811,3 +811,37 @@ fn beefy_importing_blocks() {
}));
}
}
#[test]
fn voter_initialization() {
sp_tracing::try_init_simple();
// Regression test for voter initialization where finality notifications were dropped
// after waiting for BEEFY pallet availability.
let mut runtime = Runtime::new().unwrap();
let peers = &[BeefyKeyring::Alice, BeefyKeyring::Bob];
let validator_set = ValidatorSet::new(make_beefy_ids(peers), 0).unwrap();
let session_len = 5;
// Should vote on all mandatory blocks no matter the `min_block_delta`.
let min_block_delta = 10;
let mut net = BeefyTestNet::new(2, 0);
let api = Arc::new(two_validators::TestApi {});
let beefy_peers = peers.iter().enumerate().map(|(id, key)| (id, key, api.clone())).collect();
runtime.spawn(initialize_beefy(&mut net, beefy_peers, min_block_delta));
// push 30 blocks
net.generate_blocks_and_sync(26, session_len, &validator_set, false);
let net = Arc::new(Mutex::new(net));
// Finalize multiple blocks at once to get a burst of finality notifications right from start.
// Need to finalize at least one block in each session, choose randomly.
// Expect voters to pick up all of them and BEEFY-finalize the mandatory blocks of each session.
finalize_block_and_wait_for_beefy(
&net,
peers,
&mut runtime,
&[1, 6, 10, 17, 24, 26],
&[1, 5, 10, 15, 20, 25],
);
}