diff --git a/rpc-test/tests/rpc.rs b/rpc-test/tests/rpc.rs index 72c8488e7a8325..89df239f6791e6 100644 --- a/rpc-test/tests/rpc.rs +++ b/rpc-test/tests/rpc.rs @@ -195,17 +195,23 @@ fn test_rpc_slot_updates() { // Verify that updates are received in order for an upcoming slot let verify_slot = first_update.slot() + 2; - let mut expected_update_index = 0; let expected_updates = vec![ "CreatedBank", - "Completed", "Frozen", "OptimisticConfirmation", + "Root", // TODO: debug why root signal is sent twice. "Root", ]; + let mut expected_updates = expected_updates.into_iter().peekable(); + // SlotUpdate::Completed is sent asynchronous to banking-stage and replay + // when shreds are inserted into blockstore. When the leader generates + // blocks, replay may freeze the bank before shreds are all inserted into + // blockstore; and so SlotUpdate::Completed may be received _after_ + // SlotUpdate::Frozen. + let mut slot_update_completed = false; let test_start = Instant::now(); - loop { + while expected_updates.peek().is_some() || !slot_update_completed { assert!(test_start.elapsed() < Duration::from_secs(30)); let update = update_receiver .recv_timeout(Duration::from_secs(2)) @@ -213,17 +219,16 @@ fn test_rpc_slot_updates() { if update.slot() == verify_slot { let update_name = match update { SlotUpdate::CreatedBank { .. } => "CreatedBank", - SlotUpdate::Completed { .. } => "Completed", + SlotUpdate::Completed { .. } => { + slot_update_completed = true; + continue; + } SlotUpdate::Frozen { .. } => "Frozen", SlotUpdate::OptimisticConfirmation { .. } => "OptimisticConfirmation", SlotUpdate::Root { .. } => "Root", _ => continue, }; - assert_eq!(update_name, expected_updates[expected_update_index]); - expected_update_index += 1; - if expected_update_index == expected_updates.len() { - break; - } + assert_eq!(Some(update_name), expected_updates.next()); } } }