fn process_duplicate_slots(
        duplicate_slots_receiver: &DuplicateSlotReceiver,
        gossip_duplicate_confirmed_slots: &GossipDuplicateConfirmedSlots,
        bank_forks: &RwLock<BankForks>,
        ancestors: &HashMap<Slot, HashSet<Slot>>,
        descendants: &HashMap<Slot, HashSet<Slot>>,
        progress: &mut ProgressMap,
        fork_choice: &mut HeaviestSubtreeForkChoice,
    ) {
        let duplicate_slots: Vec<Slot> = duplicate_slots_receiver.try_iter().collect();
        let (root_slot, bank_hashes) = {
            let r_bank_forks = bank_forks.read().unwrap();
            let bank_hashes: Vec<Option<Hash>> = duplicate_slots
                .iter()
                .map(|slot| r_bank_forks.get(*slot).map(|bank| bank.hash()))
                .collect();

            (r_bank_forks.root(), bank_hashes)
        };

        for (duplicate_slot, bank_hash) in duplicate_slots.into_iter().zip(bank_hashes.into_iter())
        {
            // WindowService should only send the signal once per slot
            check_slot_agrees_with_cluster(
                duplicate_slot,
                root_slot,
                bank_hash,
                gossip_duplicate_confirmed_slots,
                ancestors,
                descendants,
                progress,
                fork_choice,
                SlotStateUpdate::Duplicate,
            );
        }
    }
// Checks for and handle forks with duplicate slots.
Checks for and handle forks with duplicate slots.
Checks for and handle forks with duplicate slots .
fn process_duplicate_slots(
        duplicate_slots_receiver: &DuplicateSlotReceiver,
        gossip_duplicate_confirmed_slots: &GossipDuplicateConfirmedSlots,
        bank_forks: &RwLock<BankForks>,
        ancestors: &HashMap<Slot, HashSet<Slot>>,
        descendants: &HashMap<Slot, HashSet<Slot>>,
        progress: &mut ProgressMap,
        fork_choice: &mut HeaviestSubtreeForkChoice,
    ) {
        let duplicate_slots: Vec<Slot> = duplicate_slots_receiver.try_iter().collect();
        let (root_slot, bank_hashes) = {
            let r_bank_forks = bank_forks.read().unwrap();
            let bank_hashes: Vec<Option<Hash>> = duplicate_slots
                .iter()
                .map(|slot| r_bank_forks.get(*slot).map(|bank| bank.hash()))
                .collect();
            (r_bank_forks.root(), bank_hashes)
        };
        for (duplicate_slot, bank_hash) in duplicate_slots.into_iter().zip(bank_hashes.into_iter())
        {
            // WindowService should only send the signal once per slot
            check_slot_agrees_with_cluster(
                duplicate_slot,
                root_slot,
                bank_hash,
                gossip_duplicate_confirmed_slots,
                ancestors,
                descendants,
                progress,
                fork_choice,
                SlotStateUpdate::Duplicate,
            );
        }
    }
fn process_duplicate_slots ( duplicate_slots_receiver : & DuplicateSlotReceiver , gossip_duplicate_confirmed_slots : & GossipDuplicateConfirmedSlots , bank_forks : & RwLock < BankForks > , ancestors : & HashMap < Slot , HashSet < Slot > > , descendants : & HashMap < Slot , HashSet < Slot > > , progress : & mut ProgressMap , fork_choice : & mut HeaviestSubtreeForkChoice , ) { let duplicate_slots : Vec < Slot > = duplicate_slots_receiver . try_iter ( ) . collect ( ) ; let ( root_slot , bank_hashes ) = { let r_bank_forks = bank_forks . read ( ) . unwrap ( ) ; let bank_hashes : Vec < Option < Hash > > = duplicate_slots . iter ( ) . map ( | slot | r_bank_forks . get ( * slot ) . map ( | bank | bank . hash ( ) ) ) . collect ( ) ; ( r_bank_forks . root ( ) , bank_hashes ) } ; for ( duplicate_slot , bank_hash ) in duplicate_slots . into_iter ( ) . zip ( bank_hashes . into_iter ( ) ) { // WindowService should only send the signal once per slot check_slot_agrees_with_cluster ( duplicate_slot , root_slot , bank_hash , gossip_duplicate_confirmed_slots , ancestors , descendants , progress , fork_choice , SlotStateUpdate :: Duplicate , ) ; } }
Checks for and handle forks with duplicate slots.
Checks for and handle forks with duplicate slots .
duplicate_slots_receiver
&DuplicateSlotReceiver
gossip_duplicate_confirmed_slots
&GossipDuplicateConfirmedSlots
bank_forks
&RwLock<BankForks>
ancestors
&HashMap<Slot, HashSet<Slot>>
descendants
&HashMap<Slot, HashSet<Slot>>
progress
&mut ProgressMap
fork_choice
&mut HeaviestSubtreeForkChoice
duplicate_slots_receiver
&DuplicateSlotReceiver
gossip_duplicate_confirmed_slots
&GossipDuplicateConfirmedSlots
bank_forks
&RwLock<BankForks>
ancestors
&HashMap<Slot, HashSet<Slot>>
descendants
&HashMap<Slot, HashSet<Slot>>
progress
&mut ProgressMap
fork_choice
&mut HeaviestSubtreeForkChoice