@@ -525,12 +525,12 @@ impl AncestorHashesService {
525525 for update in ancestor_hashes_replay_update_receiver. try_iter ( ) {
526526 let slot = update. slot ( ) ;
527527 if slot <= root_slot || ancestor_hashes_request_statuses. contains_key ( & slot) {
528- return ;
528+ continue ;
529529 }
530530 match update {
531531 AncestorHashesReplayUpdate :: Dead ( dead_slot) => {
532532 if repairable_dead_slot_pool. contains ( & dead_slot) {
533- return ;
533+ continue ;
534534 } else if popular_pruned_slot_pool. contains ( & dead_slot) {
535535 // If `dead_slot` is also part of a popular pruned fork, this implies that the slot has
536536 // become `EpochSlotsFrozen` as 52% had to have frozen some version of this slot in order
@@ -2253,4 +2253,43 @@ mod test {
22532253 assert ! ( repairable_dead_slot_pool. is_empty( ) ) ;
22542254 assert ! ( popular_pruned_slot_pool. contains( & request_slot) ) ;
22552255 }
2256+
2257+ #[ test]
2258+ fn test_process_replay_updates_continue_after_skipped_update ( ) {
2259+ let ( sender, receiver) = unbounded ( ) ;
2260+ let ancestor_hashes_request_statuses = DashMap :: new ( ) ;
2261+ let mut dead_slot_pool = HashSet :: new ( ) ;
2262+ let mut repairable_dead_slot_pool = HashSet :: new ( ) ;
2263+ let mut popular_pruned_slot_pool = HashSet :: new ( ) ;
2264+
2265+ let root_slot: Slot = 15 ;
2266+ let skipped_slot = root_slot; // should be skipped due to slot <= root
2267+ let actionable_slot = root_slot + 2 ; // should be processed
2268+
2269+ sender
2270+ . send ( AncestorHashesReplayUpdate :: Dead ( skipped_slot) )
2271+ . unwrap ( ) ;
2272+ sender
2273+ . send ( AncestorHashesReplayUpdate :: DeadDuplicateConfirmed (
2274+ actionable_slot,
2275+ ) )
2276+ . unwrap ( ) ;
2277+
2278+ // Run processing; previously, an early return would have aborted after the first
2279+ // (skipped) update and ignored the actionable second update in the same batch.
2280+ AncestorHashesService :: process_replay_updates (
2281+ & receiver,
2282+ & ancestor_hashes_request_statuses,
2283+ & mut dead_slot_pool,
2284+ & mut repairable_dead_slot_pool,
2285+ & mut popular_pruned_slot_pool,
2286+ root_slot,
2287+ ) ;
2288+
2289+ // The skipped update should not pollute pools
2290+ assert ! ( !dead_slot_pool. contains( & skipped_slot) ) ;
2291+
2292+ // The actionable update must have been processed in the same call
2293+ assert ! ( repairable_dead_slot_pool. contains( & actionable_slot) ) ;
2294+ }
22562295}
0 commit comments