solana_core/consensus/
heaviest_subtree_fork_choice.rs

1#[cfg(test)]
2use trees::{Tree, TreeWalk};
3use {
4    crate::consensus::{
5        fork_choice::ForkChoice,
6        latest_validator_votes_for_frozen_banks::LatestValidatorVotesForFrozenBanks,
7        progress_map::ProgressMap, tree_diff::TreeDiff, Tower,
8    },
9    solana_clock::{Epoch, Slot},
10    solana_epoch_schedule::EpochSchedule,
11    solana_hash::Hash,
12    solana_measure::measure::Measure,
13    solana_pubkey::Pubkey,
14    solana_runtime::{bank::Bank, bank_forks::BankForks, epoch_stakes::VersionedEpochStakes},
15    std::{
16        borrow::Borrow,
17        cmp::Ordering,
18        collections::{
19            btree_set::Iter, hash_map::Entry, BTreeMap, BTreeSet, HashMap, HashSet, VecDeque,
20        },
21        sync::{Arc, RwLock},
22        time::Instant,
23    },
24};
25
26pub type ForkWeight = u64;
27pub type SlotHashKey = (Slot, Hash);
28type UpdateOperations = BTreeMap<(SlotHashKey, UpdateLabel), UpdateOperation>;
29
30const MAX_ROOT_PRINT_SECONDS: u64 = 30;
31
32#[derive(PartialEq, Eq, Clone, Debug, PartialOrd, Ord)]
33enum UpdateLabel {
34    Aggregate,
35    Add,
36
37    // Notify a fork in the tree that a particular slot in that fork is now
38    // marked as valid. If there are multiple MarkValid operations for
39    // a single node, should apply the one with the smaller slot first (hence
40    // why the actual slot is included here).
41    MarkValid(Slot),
42    // Notify a fork in the tree that a particular slot in that fork is now
43    // marked as invalid. If there are multiple MarkInvalid operations for
44    // a single node, should apply the one with the smaller slot first (hence
45    // why the actual slot is included here).
46    MarkInvalid(Slot),
47    Subtract,
48}
49
50pub trait GetSlotHash {
51    fn slot_hash(&self) -> SlotHashKey;
52}
53
54impl GetSlotHash for SlotHashKey {
55    fn slot_hash(&self) -> SlotHashKey {
56        *self
57    }
58}
59
60impl GetSlotHash for Slot {
61    fn slot_hash(&self) -> SlotHashKey {
62        (*self, Hash::default())
63    }
64}
65
66#[derive(PartialEq, Eq, Clone, Debug)]
67enum UpdateOperation {
68    Add(u64),
69    MarkValid(Slot),
70    // Notify a fork in the tree that a particular slot in that fork is now
71    // marked as invalid.
72    MarkInvalid(Slot),
73    Subtract(u64),
74    Aggregate,
75}
76
77impl UpdateOperation {
78    fn update_stake(&mut self, new_stake: u64) {
79        match self {
80            Self::Aggregate => panic!("Should not get here"),
81            Self::Add(stake) => *stake += new_stake,
82            Self::MarkValid(_slot) => panic!("Should not get here"),
83            Self::MarkInvalid(_slot) => panic!("Should not get here"),
84            Self::Subtract(stake) => *stake += new_stake,
85        }
86    }
87}
88
89#[derive(Clone, Debug)]
90struct ForkInfo {
91    // Amount of stake that has voted for exactly this slot
92    stake_voted_at: ForkWeight,
93    // Amount of stake that has voted for this slot and the subtree
94    // rooted at this slot
95    stake_voted_subtree: ForkWeight,
96    // Tree height for the subtree rooted at this slot
97    height: usize,
98    // Best slot in the subtree rooted at this slot, does not
99    // have to be a direct child in `children`. This is the slot whose subtree
100    // is the heaviest.
101    best_slot: SlotHashKey,
102    // Deepest slot in the subtree rooted at this slot. This is the slot
103    // with the greatest tree height. This metric does not discriminate invalid
104    // forks, unlike `best_slot`
105    deepest_slot: SlotHashKey,
106    parent: Option<SlotHashKey>,
107    children: BTreeSet<SlotHashKey>,
108    // The latest ancestor of this node that has been marked invalid. If the slot
109    // itself is a duplicate, this is set to the slot itself.
110    latest_invalid_ancestor: Option<Slot>,
111    // Set to true if this slot or a child node was duplicate confirmed.
112    is_duplicate_confirmed: bool,
113}
114
115impl ForkInfo {
116    /// Returns if this node has been explicitly marked as a duplicate
117    /// slot
118    fn is_unconfirmed_duplicate(&self, my_slot: Slot) -> bool {
119        self.latest_invalid_ancestor
120            .map(|ancestor| ancestor == my_slot)
121            .unwrap_or(false)
122    }
123
124    /// Returns if the fork rooted at this node is included in fork choice
125    fn is_candidate(&self) -> bool {
126        self.latest_invalid_ancestor.is_none()
127    }
128
129    fn is_duplicate_confirmed(&self) -> bool {
130        self.is_duplicate_confirmed
131    }
132
133    fn set_duplicate_confirmed(&mut self) {
134        self.is_duplicate_confirmed = true;
135        self.latest_invalid_ancestor = None;
136    }
137
138    fn update_with_newly_valid_ancestor(
139        &mut self,
140        my_key: &SlotHashKey,
141        newly_valid_ancestor: Slot,
142    ) {
143        if let Some(latest_invalid_ancestor) = self.latest_invalid_ancestor {
144            if latest_invalid_ancestor <= newly_valid_ancestor {
145                info!(
146                    "Fork choice for {my_key:?} clearing latest invalid ancestor \
147                     {latest_invalid_ancestor:?} because {newly_valid_ancestor:?} was duplicate \
148                     confirmed"
149                );
150                self.latest_invalid_ancestor = None;
151            }
152        }
153    }
154
155    fn update_with_newly_invalid_ancestor(
156        &mut self,
157        my_key: &SlotHashKey,
158        newly_invalid_ancestor: Slot,
159    ) {
160        // Should not be marking a duplicate confirmed slot as invalid
161        assert!(!self.is_duplicate_confirmed);
162        if self
163            .latest_invalid_ancestor
164            .map(|latest_invalid_ancestor| newly_invalid_ancestor > latest_invalid_ancestor)
165            .unwrap_or(true)
166        {
167            info!(
168                "Fork choice for {:?} setting latest invalid ancestor from {:?} to {}",
169                my_key, self.latest_invalid_ancestor, newly_invalid_ancestor
170            );
171            self.latest_invalid_ancestor = Some(newly_invalid_ancestor);
172        }
173    }
174}
175
176#[cfg(test)]
177impl PartialEq for ForkInfo {
178    // Basic fork structure equality
179    fn eq(&self, other: &Self) -> bool {
180        self.parent == other.parent && self.children == other.children
181    }
182}
183
184#[derive(Debug, Clone)]
185pub struct HeaviestSubtreeForkChoice {
186    fork_infos: HashMap<SlotHashKey, ForkInfo>,
187    latest_votes: HashMap<Pubkey, SlotHashKey>,
188    tree_root: SlotHashKey,
189    last_root_time: Instant,
190}
191
192#[cfg(test)]
193impl PartialEq for HeaviestSubtreeForkChoice {
194    // Basic fork structure equality
195    fn eq(&self, other: &Self) -> bool {
196        self.fork_infos == other.fork_infos && self.tree_root == other.tree_root
197    }
198}
199
200#[cfg(test)]
201impl PartialOrd for HeaviestSubtreeForkChoice {
202    // Sort by root
203    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
204        Some(self.tree_root.cmp(&other.tree_root))
205    }
206}
207
208#[cfg(test)]
209impl Eq for HeaviestSubtreeForkChoice {}
210#[cfg(test)]
211impl Ord for HeaviestSubtreeForkChoice {
212    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
213        self.tree_root.cmp(&other.tree_root)
214    }
215}
216
217impl HeaviestSubtreeForkChoice {
218    pub fn new(tree_root: SlotHashKey) -> Self {
219        let mut heaviest_subtree_fork_choice = Self {
220            tree_root,
221            // Doesn't implement default because `root` must
222            // exist in all the fields
223            fork_infos: HashMap::new(),
224            latest_votes: HashMap::new(),
225            last_root_time: Instant::now(),
226        };
227        heaviest_subtree_fork_choice.add_new_leaf_slot(tree_root, None);
228        heaviest_subtree_fork_choice
229    }
230
231    // Given a root and a list of `frozen_banks` sorted smallest to greatest by slot,
232    // return a new HeaviestSubtreeForkChoice
233    pub fn new_from_frozen_banks(root: SlotHashKey, frozen_banks: &[Arc<Bank>]) -> Self {
234        let mut heaviest_subtree_fork_choice = HeaviestSubtreeForkChoice::new(root);
235        let mut prev_slot = root.0;
236        for bank in frozen_banks.iter() {
237            assert!(bank.is_frozen());
238            if bank.slot() > root.0 {
239                // Make sure the list is sorted
240                assert!(bank.slot() > prev_slot);
241                prev_slot = bank.slot();
242                let bank_hash = bank.hash();
243                assert_ne!(bank_hash, Hash::default());
244                let parent_bank_hash = bank.parent_hash();
245                assert_ne!(parent_bank_hash, Hash::default());
246                heaviest_subtree_fork_choice.add_new_leaf_slot(
247                    (bank.slot(), bank_hash),
248                    Some((bank.parent_slot(), parent_bank_hash)),
249                );
250            }
251        }
252
253        heaviest_subtree_fork_choice
254    }
255
256    pub fn new_from_bank_forks(bank_forks: Arc<RwLock<BankForks>>) -> Self {
257        let (frozen_banks, root_bank) = {
258            let bank_forks = bank_forks.read().unwrap();
259            let mut frozen_banks: Vec<_> = bank_forks
260                .frozen_banks()
261                .map(|(_slot, bank)| bank)
262                .collect();
263            frozen_banks.sort_by_key(|bank| bank.slot());
264            let root_bank = bank_forks.root_bank();
265
266            (frozen_banks, root_bank)
267        };
268
269        Self::new_from_frozen_banks((root_bank.slot(), root_bank.hash()), &frozen_banks)
270    }
271
272    #[cfg(test)]
273    pub fn new_from_tree<T: GetSlotHash>(forks: Tree<T>) -> Self {
274        let root = forks.root().data().slot_hash();
275        let mut walk = TreeWalk::from(forks);
276        let mut heaviest_subtree_fork_choice = HeaviestSubtreeForkChoice::new(root);
277        while let Some(visit) = walk.get() {
278            let slot_hash = visit.node().data().slot_hash();
279            if heaviest_subtree_fork_choice
280                .fork_infos
281                .contains_key(&slot_hash)
282            {
283                walk.forward();
284                continue;
285            }
286            let parent_slot_hash = walk.get_parent().map(|n| n.data().slot_hash());
287            heaviest_subtree_fork_choice.add_new_leaf_slot(slot_hash, parent_slot_hash);
288            walk.forward();
289        }
290
291        heaviest_subtree_fork_choice
292    }
293
294    pub fn contains_block(&self, key: &SlotHashKey) -> bool {
295        self.fork_infos.contains_key(key)
296    }
297
298    pub fn best_slot(&self, key: &SlotHashKey) -> Option<SlotHashKey> {
299        self.fork_infos
300            .get(key)
301            .map(|fork_info| fork_info.best_slot)
302    }
303
304    pub fn deepest_slot(&self, key: &SlotHashKey) -> Option<SlotHashKey> {
305        self.fork_infos
306            .get(key)
307            .map(|fork_info| fork_info.deepest_slot)
308    }
309
310    pub fn best_overall_slot(&self) -> SlotHashKey {
311        self.best_slot(&self.tree_root).unwrap()
312    }
313
314    pub fn deepest_overall_slot(&self) -> SlotHashKey {
315        self.deepest_slot(&self.tree_root).unwrap()
316    }
317
318    pub fn stake_voted_subtree(&self, key: &SlotHashKey) -> Option<u64> {
319        self.fork_infos
320            .get(key)
321            .map(|fork_info| fork_info.stake_voted_subtree)
322    }
323
324    pub fn height(&self, key: &SlotHashKey) -> Option<usize> {
325        self.fork_infos.get(key).map(|fork_info| fork_info.height)
326    }
327
328    pub fn tree_root(&self) -> SlotHashKey {
329        self.tree_root
330    }
331
332    pub fn max_by_weight(&self, slot1: SlotHashKey, slot2: SlotHashKey) -> std::cmp::Ordering {
333        let weight1 = self.stake_voted_subtree(&slot1).unwrap();
334        let weight2 = self.stake_voted_subtree(&slot2).unwrap();
335        if weight1 == weight2 {
336            slot1.cmp(&slot2).reverse()
337        } else {
338            weight1.cmp(&weight2)
339        }
340    }
341
342    // Add new votes, returns the best slot
343    pub fn add_votes<'a, 'b>(
344        &'a mut self,
345        // newly updated votes on a fork
346        pubkey_votes: impl Iterator<Item = impl Borrow<(Pubkey, SlotHashKey)> + 'b>,
347        epoch_stakes: &HashMap<Epoch, VersionedEpochStakes>,
348        epoch_schedule: &EpochSchedule,
349    ) -> SlotHashKey {
350        // Generate the set of updates
351        let update_operations_batch =
352            self.generate_update_operations(pubkey_votes, epoch_stakes, epoch_schedule);
353
354        // Finalize all updates
355        self.process_update_operations(update_operations_batch);
356        self.best_overall_slot()
357    }
358
359    pub fn is_empty(&self) -> bool {
360        self.fork_infos.is_empty()
361    }
362
363    pub fn set_tree_root(&mut self, new_root: SlotHashKey) {
364        // Remove everything reachable from `self.tree_root` but not `new_root`,
365        // as those are now unrooted.
366        let remove_set = (&*self).subtree_diff(self.tree_root, new_root);
367        for node_key in remove_set {
368            self.fork_infos
369                .remove(&node_key)
370                .expect("Slots reachable from old root must exist in tree");
371        }
372        let root_fork_info = self.fork_infos.get_mut(&new_root);
373
374        root_fork_info
375            .unwrap_or_else(|| panic!("New root: {new_root:?}, didn't exist in fork choice"))
376            .parent = None;
377        self.tree_root = new_root;
378        self.last_root_time = Instant::now();
379    }
380
381    /// Purges all slots < `new_root` and prunes subtrees with slots > `new_root` not descending from `new_root`.
382    /// Also if the resulting tree is non-empty, updates `self.tree_root` to `new_root`
383    /// Returns (purged slots, pruned subtrees)
384    pub fn purge_prune(&mut self, new_root: SlotHashKey) -> (Vec<SlotHashKey>, Vec<Self>) {
385        let mut pruned_subtrees = vec![];
386        let mut purged_slots = vec![];
387        let mut tree_root = None;
388        // Find the subtrees to prune
389        let mut to_visit = vec![self.tree_root];
390        while let Some(cur_slot) = to_visit.pop() {
391            if cur_slot == new_root {
392                tree_root = Some(new_root);
393                continue;
394            }
395            if cur_slot < new_root {
396                for child in (&*self)
397                    .children(&cur_slot)
398                    .expect("slot was discovered earlier, must exist")
399                {
400                    to_visit.push(*child);
401                }
402                // Purge this slot since it's < `new_root`
403                purged_slots.push(cur_slot);
404            } else {
405                // The start of a pruned subtree. Split it out and stop traversing this subtree.
406                pruned_subtrees.push(self.split_off(&cur_slot));
407            }
408        }
409
410        for slot in purged_slots.iter() {
411            self.fork_infos
412                .remove(slot)
413                .expect("Slots reachable from old root must exist in tree");
414        }
415        if let Some(tree_root) = tree_root {
416            self.fork_infos
417                .get_mut(&tree_root)
418                .expect("New tree_root must exist in fork_infos")
419                .parent = None;
420            self.tree_root = tree_root;
421            self.last_root_time = Instant::now();
422        }
423        (purged_slots, pruned_subtrees)
424    }
425
426    pub fn add_root_parent(&mut self, root_parent: SlotHashKey) {
427        assert!(root_parent.0 < self.tree_root.0);
428        assert!(!self.fork_infos.contains_key(&root_parent));
429        let root_info = self
430            .fork_infos
431            .get_mut(&self.tree_root)
432            .expect("entry for root must exist");
433        root_info.parent = Some(root_parent);
434        let root_parent_info = ForkInfo {
435            stake_voted_at: 0,
436            stake_voted_subtree: root_info.stake_voted_subtree,
437            height: root_info.height + 1,
438            // The `best_slot` and `deepest_slot` do not change
439            best_slot: root_info.best_slot,
440            deepest_slot: root_info.deepest_slot,
441            children: BTreeSet::from([self.tree_root]),
442            parent: None,
443            latest_invalid_ancestor: None,
444            is_duplicate_confirmed: root_info.is_duplicate_confirmed,
445        };
446        self.fork_infos.insert(root_parent, root_parent_info);
447        self.tree_root = root_parent;
448    }
449
450    pub fn maybe_print_state(&mut self) {
451        if self.last_root_time.elapsed().as_secs() > MAX_ROOT_PRINT_SECONDS {
452            self.print_state();
453            self.last_root_time = Instant::now();
454        }
455    }
456
457    pub fn add_new_leaf_slot(&mut self, slot_hash_key: SlotHashKey, parent: Option<SlotHashKey>) {
458        if self.fork_infos.contains_key(&slot_hash_key) {
459            // Can potentially happen if we repair the same version of the duplicate slot, after
460            // dumping the original version
461            return;
462        }
463
464        let parent_latest_invalid_ancestor =
465            parent.and_then(|parent| self.latest_invalid_ancestor(&parent));
466        self.fork_infos
467            .entry(slot_hash_key)
468            .and_modify(|fork_info| fork_info.parent = parent)
469            .or_insert(ForkInfo {
470                stake_voted_at: 0,
471                stake_voted_subtree: 0,
472                height: 1,
473                // The `best_slot` and `deepest_slot` of a leaf is itself
474                best_slot: slot_hash_key,
475                deepest_slot: slot_hash_key,
476                children: BTreeSet::new(),
477                parent,
478                latest_invalid_ancestor: parent_latest_invalid_ancestor,
479                // If the parent is none, then this is the root, which implies this must
480                // have reached the duplicate confirmed threshold
481                is_duplicate_confirmed: parent.is_none(),
482            });
483
484        if parent.is_none() {
485            return;
486        }
487
488        let parent = parent.unwrap();
489
490        // Parent must already exist by time child is being added
491        self.fork_infos
492            .get_mut(&parent)
493            .unwrap()
494            .children
495            .insert(slot_hash_key);
496
497        // Propagate leaf up the tree to any ancestors who considered the previous leaf
498        // the `best_slot`, as well as any deepest slot info
499        self.propagate_new_leaf(&slot_hash_key, &parent);
500    }
501
502    // Returns true if the given `maybe_best_child` is the heaviest among the children
503    // of the parent. Breaks ties by slot # (lower is heavier).
504    fn is_best_child(&self, maybe_best_child: &SlotHashKey) -> bool {
505        let maybe_best_child_weight = self.stake_voted_subtree(maybe_best_child).unwrap();
506        let parent = self.parent(maybe_best_child);
507        // If there's no parent, this must be the root
508        if parent.is_none() {
509            return true;
510        }
511        for child in self.children(&parent.unwrap()).unwrap() {
512            let child_weight = self
513                .stake_voted_subtree(child)
514                .expect("child must exist in `self.fork_infos`");
515
516            // Don't count children currently marked as invalid
517            if !self.is_candidate(child).expect("child must exist in tree") {
518                continue;
519            }
520
521            if child_weight > maybe_best_child_weight
522                || (maybe_best_child_weight == child_weight && *child < *maybe_best_child)
523            {
524                return false;
525            }
526        }
527
528        true
529    }
530
531    // Returns true if the given `maybe_deepest_child` is the deepest among the children
532    // of the parent. Breaks ties by stake, then slot # (lower is heavier).
533    fn is_deepest_child(&self, maybe_deepest_child: &SlotHashKey) -> bool {
534        let maybe_deepest_child_weight = self.stake_voted_subtree(maybe_deepest_child).unwrap();
535        let maybe_deepest_child_height = self.height(maybe_deepest_child).unwrap();
536        let parent = self.parent(maybe_deepest_child);
537        // If there's no parent, this must be the root
538        if parent.is_none() {
539            return true;
540        }
541        for child in self.children(&parent.unwrap()).unwrap() {
542            let child_height = self
543                .height(child)
544                .expect("child must exist in `self.fork_infos`");
545            let child_weight = self
546                .stake_voted_subtree(child)
547                .expect("child must exist in `self.fork_infos`");
548
549            match (
550                child_height.cmp(&maybe_deepest_child_height),
551                child_weight.cmp(&maybe_deepest_child_weight),
552                child.cmp(maybe_deepest_child),
553            ) {
554                (Ordering::Greater, _, _) => return false,
555                // Tiebreak by stake
556                (Ordering::Equal, Ordering::Greater, _) => return false,
557                // Tiebreak by slot #
558                (Ordering::Equal, Ordering::Equal, Ordering::Less) => return false,
559                _ => (),
560            }
561        }
562
563        true
564    }
565
566    pub fn all_slots_stake_voted_subtree(&self) -> impl Iterator<Item = (&SlotHashKey, u64)> {
567        self.fork_infos
568            .iter()
569            .map(|(slot_hash, fork_info)| (slot_hash, fork_info.stake_voted_subtree))
570    }
571
572    pub fn slots_iter(&self) -> impl Iterator<Item = Slot> + '_ {
573        self.fork_infos.iter().map(|((slot, _), _)| slot).copied()
574    }
575
576    /// Split off the node at `slot_hash_key` and propagate the stake subtraction up to the root of the
577    /// tree.
578    ///
579    /// Assumes that `slot_hash_key` is not the `tree_root`
580    /// Returns the subtree originating from `slot_hash_key`
581    pub fn split_off(&mut self, slot_hash_key: &SlotHashKey) -> Self {
582        assert_ne!(self.tree_root, *slot_hash_key);
583        let (mut split_tree_root, parent) = {
584            let node_to_split_at = self
585                .fork_infos
586                .get_mut(slot_hash_key)
587                .expect("Slot hash key must exist in tree");
588            (
589                node_to_split_at.clone(),
590                node_to_split_at
591                    .parent
592                    .expect("Split node is not tree root"),
593            )
594        };
595
596        let mut update_operations: UpdateOperations = BTreeMap::new();
597        // Insert aggregate operations up to the root
598        self.insert_aggregate_operations(&mut update_operations, *slot_hash_key);
599        // Remove child link so that this slot cannot be chosen as best or deepest
600        assert!(self
601            .fork_infos
602            .get_mut(&parent)
603            .expect("Parent must exist in fork_infos")
604            .children
605            .remove(slot_hash_key));
606        // Aggregate
607        self.process_update_operations(update_operations);
608
609        // Remove node + all children and add to new tree
610        let mut split_tree_fork_infos = HashMap::new();
611        let mut to_visit = vec![*slot_hash_key];
612        while let Some(current_node) = to_visit.pop() {
613            let current_fork_info = self
614                .fork_infos
615                .remove(&current_node)
616                .expect("Node must exist in tree");
617
618            to_visit.extend(current_fork_info.children.iter());
619            split_tree_fork_infos.insert(current_node, current_fork_info);
620        }
621
622        // Remove link from parent
623        let parent_fork_info = self
624            .fork_infos
625            .get_mut(&split_tree_root.parent.expect("Cannot split off from root"))
626            .expect("Parent must exist in fork infos");
627        parent_fork_info.children.remove(slot_hash_key);
628
629        // Update the root of the new tree with the proper info, now that we have finished
630        // aggregating
631        split_tree_root.parent = None;
632        split_tree_fork_infos.insert(*slot_hash_key, split_tree_root);
633
634        // Split off the relevant votes to the new tree
635        let mut split_tree_latest_votes = self.latest_votes.clone();
636        split_tree_latest_votes.retain(|_, node| split_tree_fork_infos.contains_key(node));
637        self.latest_votes
638            .retain(|_, node| self.fork_infos.contains_key(node));
639
640        // Create a new tree from the split
641        HeaviestSubtreeForkChoice {
642            tree_root: *slot_hash_key,
643            fork_infos: split_tree_fork_infos,
644            latest_votes: split_tree_latest_votes,
645            last_root_time: Instant::now(),
646        }
647    }
648
649    #[cfg(test)]
650    pub fn ancestors(&self, start_slot_hash_key: SlotHashKey) -> Vec<SlotHashKey> {
651        AncestorIterator::new(start_slot_hash_key, &self.fork_infos).collect()
652    }
653
654    pub fn merge(
655        &mut self,
656        other: HeaviestSubtreeForkChoice,
657        merge_leaf: &SlotHashKey,
658        epoch_stakes: &HashMap<Epoch, VersionedEpochStakes>,
659        epoch_schedule: &EpochSchedule,
660    ) {
661        assert!(self.fork_infos.contains_key(merge_leaf));
662
663        // Add all the nodes from `other` into our tree
664        let mut other_slots_nodes: Vec<_> = other
665            .fork_infos
666            .iter()
667            .map(|(slot_hash_key, fork_info)| {
668                (slot_hash_key, fork_info.parent.unwrap_or(*merge_leaf))
669            })
670            .collect();
671
672        other_slots_nodes.sort_by_key(|(slot_hash_key, _)| *slot_hash_key);
673        for (slot_hash_key, parent) in other_slots_nodes {
674            self.add_new_leaf_slot(*slot_hash_key, Some(parent));
675        }
676
677        // Add all votes, the outdated ones should be filtered out by
678        // self.add_votes()
679        self.add_votes(other.latest_votes.into_iter(), epoch_stakes, epoch_schedule);
680    }
681
682    pub fn stake_voted_at(&self, slot: &SlotHashKey) -> Option<u64> {
683        self.fork_infos
684            .get(slot)
685            .map(|fork_info| fork_info.stake_voted_at)
686    }
687
688    pub fn latest_invalid_ancestor(&self, slot_hash_key: &SlotHashKey) -> Option<Slot> {
689        self.fork_infos
690            .get(slot_hash_key)
691            .map(|fork_info| fork_info.latest_invalid_ancestor)
692            .unwrap_or(None)
693    }
694
695    pub fn is_duplicate_confirmed(&self, slot_hash_key: &SlotHashKey) -> Option<bool> {
696        self.fork_infos
697            .get(slot_hash_key)
698            .map(|fork_info| fork_info.is_duplicate_confirmed())
699    }
700
701    /// Returns if the exact node with the specified key has been explicitly marked as a duplicate
702    /// slot (doesn't count ancestors being marked as duplicate).
703    pub fn is_unconfirmed_duplicate(&self, slot_hash_key: &SlotHashKey) -> Option<bool> {
704        self.fork_infos
705            .get(slot_hash_key)
706            .map(|fork_info| fork_info.is_unconfirmed_duplicate(slot_hash_key.0))
707    }
708
709    /// Returns false if the node or any of its ancestors have been marked as duplicate
710    pub fn is_candidate(&self, slot_hash_key: &SlotHashKey) -> Option<bool> {
711        self.fork_infos
712            .get(slot_hash_key)
713            .map(|fork_info| fork_info.is_candidate())
714    }
715
716    /// Returns if a node with slot `maybe_ancestor_slot` is an ancestor of the node with
717    /// key `node_key`
718    pub fn is_strict_ancestor(
719        &self,
720        maybe_ancestor_key: &SlotHashKey,
721        node_key: &SlotHashKey,
722    ) -> bool {
723        if maybe_ancestor_key == node_key {
724            return false;
725        }
726
727        if maybe_ancestor_key.0 > node_key.0 {
728            return false;
729        }
730
731        let mut ancestor_iterator = self.ancestor_iterator(*node_key);
732        ancestor_iterator.any(|(ancestor_slot, ancestor_hash)| {
733            ancestor_slot == maybe_ancestor_key.0 && ancestor_hash == maybe_ancestor_key.1
734        })
735    }
736
737    /// To be called when `slot_hash_key` has been added to `self.fork_infos`, before any
738    /// aggregate update operations have taken place.
739    ///
740    /// Will propagate update `best_slot` and `deepest_slot` to ancestors.
741    fn propagate_new_leaf(
742        &mut self,
743        slot_hash_key: &SlotHashKey,
744        parent_slot_hash_key: &SlotHashKey,
745    ) {
746        let parent_best_slot_hash_key = self
747            .best_slot(parent_slot_hash_key)
748            .expect("parent must exist in self.fork_infos after its child leaf was created");
749        // If this new leaf is the direct parent's best child, then propagate it up the tree
750        if self.is_best_child(slot_hash_key) {
751            let mut ancestor = Some(*parent_slot_hash_key);
752            loop {
753                if ancestor.is_none() {
754                    break;
755                }
756                let ancestor_fork_info = self.fork_infos.get_mut(&ancestor.unwrap()).unwrap();
757                if ancestor_fork_info.best_slot == parent_best_slot_hash_key {
758                    ancestor_fork_info.best_slot = *slot_hash_key;
759                } else {
760                    break;
761                }
762                ancestor = ancestor_fork_info.parent;
763            }
764        }
765        // Propagate the deepest slot up the tree
766        let mut ancestor = Some(*parent_slot_hash_key);
767        let mut current_child = *slot_hash_key;
768        let mut current_height = 1;
769        loop {
770            if ancestor.is_none() {
771                break;
772            }
773            if !self.is_deepest_child(&current_child) {
774                break;
775            }
776            let ancestor_fork_info = self.fork_infos.get_mut(&ancestor.unwrap()).unwrap();
777            ancestor_fork_info.deepest_slot = *slot_hash_key;
778            ancestor_fork_info.height = current_height + 1;
779            current_child = ancestor.unwrap();
780            current_height = ancestor_fork_info.height;
781            ancestor = ancestor_fork_info.parent;
782        }
783    }
784
785    fn insert_aggregate_operations(
786        &self,
787        update_operations: &mut BTreeMap<(SlotHashKey, UpdateLabel), UpdateOperation>,
788        slot_hash_key: SlotHashKey,
789    ) {
790        self.do_insert_aggregate_operations_across_ancestors(
791            update_operations,
792            None,
793            slot_hash_key,
794        );
795    }
796
797    #[allow(clippy::map_entry)]
798    fn do_insert_aggregate_operations_across_ancestors(
799        &self,
800        update_operations: &mut BTreeMap<(SlotHashKey, UpdateLabel), UpdateOperation>,
801        modify_fork_validity: Option<UpdateOperation>,
802        slot_hash_key: SlotHashKey,
803    ) {
804        for parent_slot_hash_key in self.ancestor_iterator(slot_hash_key) {
805            if !self.do_insert_aggregate_operation(
806                update_operations,
807                &modify_fork_validity,
808                parent_slot_hash_key,
809            ) {
810                // If this parent was already inserted, we assume all the other parents have also
811                // already been inserted. This is to prevent iterating over the parents multiple times
812                // when we are aggregating leaves that have a lot of shared ancestors
813                break;
814            }
815        }
816    }
817
818    #[allow(clippy::map_entry)]
819    fn do_insert_aggregate_operation(
820        &self,
821        update_operations: &mut BTreeMap<(SlotHashKey, UpdateLabel), UpdateOperation>,
822        modify_fork_validity: &Option<UpdateOperation>,
823        slot_hash_key: SlotHashKey,
824    ) -> bool {
825        let aggregate_label = (slot_hash_key, UpdateLabel::Aggregate);
826        if update_operations.contains_key(&aggregate_label) {
827            false
828        } else {
829            if let Some(mark_fork_validity) = modify_fork_validity {
830                match mark_fork_validity {
831                    UpdateOperation::MarkValid(slot) => {
832                        update_operations.insert(
833                            (slot_hash_key, UpdateLabel::MarkValid(*slot)),
834                            UpdateOperation::MarkValid(*slot),
835                        );
836                    }
837                    UpdateOperation::MarkInvalid(slot) => {
838                        update_operations.insert(
839                            (slot_hash_key, UpdateLabel::MarkInvalid(*slot)),
840                            UpdateOperation::MarkInvalid(*slot),
841                        );
842                    }
843                    _ => (),
844                }
845            }
846            update_operations.insert(aggregate_label, UpdateOperation::Aggregate);
847            true
848        }
849    }
850
851    fn ancestor_iterator(&self, start_slot_hash_key: SlotHashKey) -> AncestorIterator {
852        AncestorIterator::new(start_slot_hash_key, &self.fork_infos)
853    }
854
855    fn aggregate_slot(&mut self, slot_hash_key: SlotHashKey) {
856        let mut stake_voted_subtree;
857        let mut deepest_child_height = 0;
858        let mut best_slot_hash_key = slot_hash_key;
859        let mut deepest_slot_hash_key = slot_hash_key;
860        let mut is_duplicate_confirmed = false;
861        if let Some(fork_info) = self.fork_infos.get(&slot_hash_key) {
862            stake_voted_subtree = fork_info.stake_voted_at;
863            let mut best_child_stake_voted_subtree = 0;
864            let mut best_child_slot_key = slot_hash_key;
865            let mut deepest_child_stake_voted_subtree = 0;
866            let mut deepest_child_slot_key = slot_hash_key;
867            for child_key in &fork_info.children {
868                let child_fork_info = self
869                    .fork_infos
870                    .get(child_key)
871                    .expect("Child must exist in fork_info map");
872                let child_stake_voted_subtree = child_fork_info.stake_voted_subtree;
873                let child_height = child_fork_info.height;
874                is_duplicate_confirmed |= child_fork_info.is_duplicate_confirmed;
875
876                // Child forks that are not candidates still contribute to the weight
877                // of the subtree rooted at `slot_hash_key`. For instance:
878                /*
879                    Build fork structure:
880                          slot 0
881                            |
882                          slot 1
883                          /    \
884                    slot 2     |
885                        |     slot 3 (34%)
886                slot 4 (66%)
887
888                    If slot 4 is a duplicate slot, so no longer qualifies as a candidate until
889                    the slot is confirmed, the weight of votes on slot 4 should still count towards
890                    slot 2, otherwise we might pick slot 3 as the heaviest fork to build blocks on
891                    instead of slot 2.
892                */
893
894                // See comment above for why this check is outside of the `is_candidate` check.
895                stake_voted_subtree += child_stake_voted_subtree;
896
897                // Note: If there's no valid children, then the best slot should default to the
898                // input `slot` itself.
899                if child_fork_info.is_candidate()
900                    && (best_child_slot_key == slot_hash_key ||
901                    child_stake_voted_subtree > best_child_stake_voted_subtree ||
902                // tiebreaker by slot height, prioritize earlier slot
903                (child_stake_voted_subtree == best_child_stake_voted_subtree && child_key < &best_child_slot_key))
904                {
905                    best_child_stake_voted_subtree = child_stake_voted_subtree;
906                    best_child_slot_key = *child_key;
907                    best_slot_hash_key = child_fork_info.best_slot;
908                }
909
910                match (
911                    deepest_child_slot_key == slot_hash_key,
912                    child_height.cmp(&deepest_child_height),
913                    child_stake_voted_subtree.cmp(&deepest_child_stake_voted_subtree),
914                    child_key.cmp(&deepest_child_slot_key)
915                ) {
916                    // First child
917                    (true, _, _, _) |
918                    // or deeper child
919                    (_, Ordering::Greater, _, _) |
920                    // or tie break by stake weight
921                    (_, Ordering::Equal, Ordering::Greater, _) |
922                    // or tie break by slot #
923                    (_, Ordering::Equal, Ordering::Equal, Ordering::Less) => {
924                        deepest_child_height = child_height;
925                        deepest_child_stake_voted_subtree = child_stake_voted_subtree;
926                        deepest_child_slot_key = *child_key;
927                        deepest_slot_hash_key = child_fork_info.deepest_slot;
928                    },
929                    _ => ()
930                }
931            }
932        } else {
933            return;
934        }
935
936        let fork_info = self.fork_infos.get_mut(&slot_hash_key).unwrap();
937        if is_duplicate_confirmed {
938            if !fork_info.is_duplicate_confirmed {
939                info!("Fork choice setting {slot_hash_key:?} to duplicate confirmed");
940            }
941            fork_info.set_duplicate_confirmed();
942        }
943        fork_info.stake_voted_subtree = stake_voted_subtree;
944        fork_info.height = deepest_child_height + 1;
945        fork_info.best_slot = best_slot_hash_key;
946        fork_info.deepest_slot = deepest_slot_hash_key;
947    }
948
949    /// Mark that `valid_slot` on the fork starting at `fork_to_modify` has been marked
950    /// valid. Note we don't need the hash for `valid_slot` because slot number uniquely
951    /// identifies a node on a single fork.
952    fn mark_fork_valid(&mut self, fork_to_modify_key: SlotHashKey, valid_slot: Slot) {
953        if let Some(fork_info_to_modify) = self.fork_infos.get_mut(&fork_to_modify_key) {
954            fork_info_to_modify.update_with_newly_valid_ancestor(&fork_to_modify_key, valid_slot);
955            if fork_to_modify_key.0 == valid_slot {
956                fork_info_to_modify.is_duplicate_confirmed = true;
957            }
958        }
959    }
960
961    /// Mark that `invalid_slot` on the fork starting at `fork_to_modify` has been marked
962    /// invalid. Note we don't need the hash for `invalid_slot` because slot number uniquely
963    /// identifies a node on a single fork.
964    fn mark_fork_invalid(&mut self, fork_to_modify_key: SlotHashKey, invalid_slot: Slot) {
965        if let Some(fork_info_to_modify) = self.fork_infos.get_mut(&fork_to_modify_key) {
966            fork_info_to_modify
967                .update_with_newly_invalid_ancestor(&fork_to_modify_key, invalid_slot);
968        }
969    }
970
971    fn generate_update_operations<'a, 'b>(
972        &'a mut self,
973        pubkey_votes: impl Iterator<Item = impl Borrow<(Pubkey, SlotHashKey)> + 'b>,
974        epoch_stakes: &HashMap<Epoch, VersionedEpochStakes>,
975        epoch_schedule: &EpochSchedule,
976    ) -> UpdateOperations {
977        let mut update_operations: BTreeMap<(SlotHashKey, UpdateLabel), UpdateOperation> =
978            BTreeMap::new();
979        let mut observed_pubkeys: HashMap<Pubkey, Slot> = HashMap::new();
980        // Sort the `pubkey_votes` in a BTreeMap by the slot voted
981        for pubkey_vote in pubkey_votes {
982            let (pubkey, new_vote_slot_hash) = pubkey_vote.borrow();
983            let (new_vote_slot, new_vote_hash) = *new_vote_slot_hash;
984            if new_vote_slot < self.tree_root.0 {
985                // If the new vote is less than the root we can ignore it. This is because there
986                // are two cases. Either:
987                // 1) The validator's latest vote was bigger than the new vote, so we can ignore it
988                // 2) The validator's latest vote was less than the new vote, then the validator's latest
989                // vote was also less than root. This means either every node in the current tree has the
990                // validators stake counted toward it (if the latest vote was an ancestor of the current root),
991                // OR every node doesn't have this validator's vote counting toward it (if the latest vote
992                // was not an ancestor of the current root). Thus this validator is essentially a no-op
993                // and won't affect fork choice.
994                continue;
995            }
996
997            // A pubkey cannot appear in pubkey votes more than once.
998            match observed_pubkeys.entry(*pubkey) {
999                Entry::Occupied(_occupied_entry) => {
1000                    panic!("Should not get multiple votes for same pubkey in the same batch");
1001                }
1002                Entry::Vacant(vacant_entry) => {
1003                    vacant_entry.insert(new_vote_slot);
1004                    false
1005                }
1006            };
1007
1008            let mut pubkey_latest_vote = self.latest_votes.get_mut(pubkey);
1009
1010            // Filter out any votes or slots < any slot this pubkey has
1011            // already voted for, we only care about the latest votes.
1012            //
1013            // If the new vote is for the same slot, but a different, smaller hash,
1014            // then allow processing to continue as this is a duplicate version
1015            // of the same slot.
1016            match pubkey_latest_vote.as_mut() {
1017                Some((pubkey_latest_vote_slot, pubkey_latest_vote_hash))
1018                    if (new_vote_slot < *pubkey_latest_vote_slot)
1019                        || (new_vote_slot == *pubkey_latest_vote_slot
1020                            && &new_vote_hash >= pubkey_latest_vote_hash) =>
1021                {
1022                    continue;
1023                }
1024
1025                _ => {
1026                    // We either:
1027                    // 1) don't have a vote yet for this pubkey,
1028                    // 2) or the new vote slot is bigger than the old vote slot
1029                    // 3) or the new vote slot == old_vote slot, but for a smaller bank hash.
1030                    // In all above cases, we need to remove this pubkey stake from the previous fork
1031                    // of the previous vote
1032
1033                    if let Some((old_latest_vote_slot, old_latest_vote_hash)) =
1034                        self.latest_votes.insert(*pubkey, *new_vote_slot_hash)
1035                    {
1036                        assert!(if new_vote_slot == old_latest_vote_slot {
1037                            warn!(
1038                                "Got a duplicate vote for validator: {pubkey}, slot_hash: \
1039                                 {new_vote_slot_hash:?}",
1040                            );
1041                            // If the slots are equal, then the new
1042                            // vote must be for a smaller hash
1043                            new_vote_hash < old_latest_vote_hash
1044                        } else {
1045                            new_vote_slot > old_latest_vote_slot
1046                        });
1047
1048                        let epoch = epoch_schedule.get_epoch(old_latest_vote_slot);
1049                        let stake_update = epoch_stakes
1050                            .get(&epoch)
1051                            .map(|epoch_stakes| epoch_stakes.vote_account_stake(pubkey))
1052                            .unwrap_or(0);
1053
1054                        if stake_update > 0 {
1055                            update_operations
1056                                .entry((
1057                                    (old_latest_vote_slot, old_latest_vote_hash),
1058                                    UpdateLabel::Subtract,
1059                                ))
1060                                .and_modify(|update| update.update_stake(stake_update))
1061                                .or_insert(UpdateOperation::Subtract(stake_update));
1062                            self.insert_aggregate_operations(
1063                                &mut update_operations,
1064                                (old_latest_vote_slot, old_latest_vote_hash),
1065                            );
1066                        }
1067                    }
1068                }
1069            }
1070
1071            // Add this pubkey stake to new fork
1072            let epoch = epoch_schedule.get_epoch(new_vote_slot_hash.0);
1073            let stake_update = epoch_stakes
1074                .get(&epoch)
1075                .map(|epoch_stakes| epoch_stakes.vote_account_stake(pubkey))
1076                .unwrap_or(0);
1077
1078            update_operations
1079                .entry((*new_vote_slot_hash, UpdateLabel::Add))
1080                .and_modify(|update| update.update_stake(stake_update))
1081                .or_insert(UpdateOperation::Add(stake_update));
1082            self.insert_aggregate_operations(&mut update_operations, *new_vote_slot_hash);
1083        }
1084
1085        update_operations
1086    }
1087
1088    fn process_update_operations(&mut self, update_operations: UpdateOperations) {
1089        // Iterate through the update operations from greatest to smallest slot
1090        for ((slot_hash_key, _), operation) in update_operations.into_iter().rev() {
1091            match operation {
1092                UpdateOperation::MarkValid(valid_slot) => {
1093                    self.mark_fork_valid(slot_hash_key, valid_slot)
1094                }
1095                UpdateOperation::MarkInvalid(invalid_slot) => {
1096                    self.mark_fork_invalid(slot_hash_key, invalid_slot)
1097                }
1098                UpdateOperation::Aggregate => self.aggregate_slot(slot_hash_key),
1099                UpdateOperation::Add(stake) => self.add_slot_stake(&slot_hash_key, stake),
1100                UpdateOperation::Subtract(stake) => self.subtract_slot_stake(&slot_hash_key, stake),
1101            }
1102        }
1103    }
1104
1105    fn add_slot_stake(&mut self, slot_hash_key: &SlotHashKey, stake: u64) {
1106        if let Some(fork_info) = self.fork_infos.get_mut(slot_hash_key) {
1107            fork_info.stake_voted_at += stake;
1108            fork_info.stake_voted_subtree += stake;
1109        }
1110    }
1111
1112    fn subtract_slot_stake(&mut self, slot_hash_key: &SlotHashKey, stake: u64) {
1113        if let Some(fork_info) = self.fork_infos.get_mut(slot_hash_key) {
1114            fork_info.stake_voted_at -= stake;
1115            fork_info.stake_voted_subtree -= stake;
1116        }
1117    }
1118
1119    fn parent(&self, slot_hash_key: &SlotHashKey) -> Option<SlotHashKey> {
1120        self.fork_infos
1121            .get(slot_hash_key)
1122            .map(|fork_info| fork_info.parent)
1123            .unwrap_or(None)
1124    }
1125
1126    fn print_state(&self) {
1127        let best_slot_hash_key = self.best_overall_slot();
1128        let mut best_path: VecDeque<_> = self.ancestor_iterator(best_slot_hash_key).collect();
1129        best_path.push_front(best_slot_hash_key);
1130        info!(
1131            "Latest known votes by vote pubkey: {:#?}, best path: {:?}",
1132            self.latest_votes,
1133            best_path.iter().rev().collect::<Vec<&SlotHashKey>>()
1134        );
1135    }
1136
1137    fn heaviest_slot_on_same_voted_fork(&self, tower: &Tower) -> Option<SlotHashKey> {
1138        tower
1139            .last_voted_slot_hash()
1140            .and_then(|last_voted_slot_hash| {
1141                match self.is_candidate(&last_voted_slot_hash) {
1142                    Some(true) => self.best_slot(&last_voted_slot_hash),
1143                    Some(false) => {
1144                        // In this case our last voted fork has been marked invalid because
1145                        // it contains a duplicate block. It is critical that we continue to
1146                        // build on it as long as there exists at least 1 non duplicate fork.
1147                        // This is because there is a chance that this fork is actually duplicate
1148                        // confirmed but not observed because there is no block containing the
1149                        // required votes.
1150                        //
1151                        // Scenario 1:
1152                        // Slot 0 - Slot 1 (90%)
1153                        //        |
1154                        //        - Slot 1'
1155                        //        |
1156                        //        - Slot 2 (10%)
1157                        //
1158                        // Imagine that 90% of validators voted for Slot 1, but because of the existence
1159                        // of Slot 1', Slot 1 is marked as invalid in fork choice. It is impossible to reach
1160                        // the required switch threshold for these validators to switch off of Slot 1 to Slot 2.
1161                        // In this case it is important for someone to build a Slot 3 off of Slot 1 that contains
1162                        // the votes for Slot 1. At this point they will see that the fork off of Slot 1 is duplicate
1163                        // confirmed, and the rest of the network can repair Slot 1, and mark it is a valid candidate
1164                        // allowing fork choice to converge.
1165                        //
1166                        // This will only occur after Slot 2 has been created, in order to resolve the following
1167                        // scenario:
1168                        //
1169                        // Scenario 2:
1170                        // Slot 0 - Slot 1 (30%)
1171                        //        |
1172                        //        - Slot 1' (30%)
1173                        //
1174                        // In this scenario only 60% of the network has voted before the duplicate proof for Slot 1 and 1'
1175                        // was viewed. Neither version of the slot will reach the duplicate confirmed threshold, so it is
1176                        // critical that a new fork Slot 2 from Slot 0 is created to allow the validators on Slot 1 and
1177                        // Slot 1' to switch. Since the `best_slot` is an ancestor of the last vote (Slot 0 is ancestor of last
1178                        // vote Slot 1 or Slot 1'), we will trigger `SwitchForkDecision::FailedSwitchDuplicateRollback`, which
1179                        // will create an alternate fork off of Slot 0. Once this alternate fork is created, the `best_slot`
1180                        // will be Slot 2, at which point we will be in Scenario 1 and continue building off of Slot 1 or Slot 1'.
1181                        //
1182                        // For more details see the case for
1183                        // `SwitchForkDecision::FailedSwitchDuplicateRollback` in `ReplayStage::select_vote_and_reset_forks`.
1184                        self.deepest_slot(&last_voted_slot_hash)
1185                    }
1186                    None => {
1187                        if !tower.is_stray_last_vote() {
1188                            // Unless last vote is stray and stale, self.is_candidate(last_voted_slot_hash) must return
1189                            // Some(_), justifying to panic! here.
1190                            // Also, adjust_lockouts_after_replay() correctly makes last_voted_slot None,
1191                            // if all saved votes are ancestors of replayed_root_slot. So this code shouldn't be
1192                            // touched in that case as well.
1193                            // In other words, except being stray, all other slots have been voted on while this
1194                            // validator has been running, so we must be able to fetch best_slots for all of
1195                            // them.
1196                            panic!(
1197                                "a bank at last_voted_slot({last_voted_slot_hash:?}) is a frozen \
1198                                 bank so must have been added to heaviest_subtree_fork_choice at \
1199                                 time of freezing",
1200                            )
1201                        } else {
1202                            // fork_infos doesn't have corresponding data for the stale stray last vote,
1203                            // meaning some inconsistency between saved tower and ledger.
1204                            // (newer snapshot, or only a saved tower is moved over to new setup?)
1205                            None
1206                        }
1207                    }
1208                }
1209            })
1210    }
1211
1212    #[cfg(test)]
1213    fn set_stake_voted_at(&mut self, slot_hash_key: SlotHashKey, stake_voted_at: u64) {
1214        self.fork_infos
1215            .get_mut(&slot_hash_key)
1216            .unwrap()
1217            .stake_voted_at = stake_voted_at;
1218    }
1219
1220    #[cfg(test)]
1221    fn is_leaf(&self, slot_hash_key: SlotHashKey) -> bool {
1222        self.fork_infos
1223            .get(&slot_hash_key)
1224            .unwrap()
1225            .children
1226            .is_empty()
1227    }
1228}
1229
1230impl<'a> TreeDiff<'a> for &'a HeaviestSubtreeForkChoice {
1231    type TreeKey = SlotHashKey;
1232    type ChildIter = Iter<'a, SlotHashKey>;
1233
1234    fn contains_slot(&self, slot_hash_key: &SlotHashKey) -> bool {
1235        self.fork_infos.contains_key(slot_hash_key)
1236    }
1237
1238    fn children(&self, slot_hash_key: &SlotHashKey) -> Option<Self::ChildIter> {
1239        self.fork_infos
1240            .get(slot_hash_key)
1241            .map(|fork_info| fork_info.children.iter())
1242    }
1243}
1244
1245impl ForkChoice for HeaviestSubtreeForkChoice {
1246    type ForkChoiceKey = SlotHashKey;
1247    fn compute_bank_stats(
1248        &mut self,
1249        bank: &Bank,
1250        _tower: &Tower,
1251        latest_validator_votes_for_frozen_banks: &mut LatestValidatorVotesForFrozenBanks,
1252    ) {
1253        let mut start = Measure::start("compute_bank_stats_time");
1254        // Update `heaviest_subtree_fork_choice` to find the best fork to build on
1255        let root = self.tree_root.0;
1256        let new_votes = latest_validator_votes_for_frozen_banks.take_votes_dirty_set(root);
1257        let (best_overall_slot, best_overall_hash) = self.add_votes(
1258            new_votes.into_iter(),
1259            bank.epoch_stakes_map(),
1260            bank.epoch_schedule(),
1261        );
1262        start.stop();
1263
1264        datapoint_info!(
1265            "compute_bank_stats-best_slot",
1266            ("computed_slot", bank.slot(), i64),
1267            ("overall_best_slot", best_overall_slot, i64),
1268            ("overall_best_hash", best_overall_hash.to_string(), String),
1269            ("elapsed", start.as_us(), i64),
1270        );
1271    }
1272
1273    // Returns:
1274    // 1) The heaviest overall bank
1275    // 2) The heaviest bank on the same fork as the last vote (doesn't require a
1276    // switching proof to vote for)
1277    fn select_forks(
1278        &self,
1279        _frozen_banks: &[Arc<Bank>],
1280        tower: &Tower,
1281        _progress: &ProgressMap,
1282        _ancestors: &HashMap<u64, HashSet<u64>>,
1283        bank_forks: &RwLock<BankForks>,
1284    ) -> (Arc<Bank>, Option<Arc<Bank>>) {
1285        let r_bank_forks = bank_forks.read().unwrap();
1286
1287        // BankForks should only contain one valid version of this slot
1288        (
1289            r_bank_forks
1290                .get_with_checked_hash(self.best_overall_slot())
1291                .unwrap(),
1292            self.heaviest_slot_on_same_voted_fork(tower)
1293                .and_then(|slot_hash| {
1294                    #[allow(clippy::manual_filter)]
1295                    if let Some(bank) = r_bank_forks.get(slot_hash.0) {
1296                        if bank.hash() != slot_hash.1 {
1297                            // It is possible that our last vote was for an invalid fork
1298                            // and we have repaired and replayed the correct version of the fork.
1299                            // In this case the hash for the heaviest bank on our voted fork
1300                            // will no longer be matching what we have replayed.
1301                            //
1302                            // Because we have dumped and repaired a new version, it is impossible
1303                            // for our last voted fork to become duplicate confirmed as the state
1304                            // machine will never dump and repair a block that has not been observed
1305                            // as duplicate confirmed. Therefore it is safe to never build on this
1306                            // invalid fork.
1307                            None
1308                        } else {
1309                            Some(bank)
1310                        }
1311                    } else {
1312                        // It is possible that our last vote was for an invalid fork
1313                        // and we are in the middle of dumping and repairing such fork.
1314                        // In that case, the `heaviest_slot_on_same_voted_fork` has a chance to
1315                        // be for a slot that we currently do not have in our bank forks, so we
1316                        // return None.
1317                        //
1318                        // We are guaranteed that we will eventually repair a duplicate confirmed version
1319                        // of this slot because the state machine will never dump a slot unless it has
1320                        // observed a duplicate confirmed version of the slot.
1321                        //
1322                        // Therefore there is no chance that our last voted fork will ever become
1323                        // duplicate confirmed, so it is safe to never build on it.
1324                        None
1325                    }
1326                }),
1327        )
1328    }
1329
1330    fn mark_fork_invalid_candidate(&mut self, invalid_slot_hash_key: &SlotHashKey) {
1331        info!("marking fork starting at: {invalid_slot_hash_key:?} invalid candidate");
1332        let fork_info = self.fork_infos.get_mut(invalid_slot_hash_key);
1333        if let Some(fork_info) = fork_info {
1334            // Should not be marking duplicate confirmed blocks as invalid candidates
1335            assert!(!fork_info.is_duplicate_confirmed);
1336            let mut update_operations = UpdateOperations::default();
1337
1338            // Notify all the children of this node that a parent was marked as invalid
1339            for child_hash_key in
1340                (&*self).subtree_diff(*invalid_slot_hash_key, SlotHashKey::default())
1341            {
1342                self.do_insert_aggregate_operation(
1343                    &mut update_operations,
1344                    &Some(UpdateOperation::MarkInvalid(invalid_slot_hash_key.0)),
1345                    child_hash_key,
1346                );
1347            }
1348
1349            // Aggregate across all ancestors to find the new best slots excluding this fork
1350            self.insert_aggregate_operations(&mut update_operations, *invalid_slot_hash_key);
1351            self.process_update_operations(update_operations);
1352        }
1353    }
1354
1355    fn mark_fork_valid_candidate(&mut self, valid_slot_hash_key: &SlotHashKey) -> Vec<SlotHashKey> {
1356        info!("marking fork starting at: {valid_slot_hash_key:?} valid candidate");
1357        let mut newly_duplicate_confirmed_ancestors = vec![];
1358
1359        for ancestor_key in std::iter::once(*valid_slot_hash_key)
1360            .chain(self.ancestor_iterator(*valid_slot_hash_key))
1361        {
1362            if !self.is_duplicate_confirmed(&ancestor_key).unwrap() {
1363                newly_duplicate_confirmed_ancestors.push(ancestor_key);
1364            }
1365        }
1366
1367        let mut update_operations = UpdateOperations::default();
1368        // Notify all the children of this node that a parent was marked as valid
1369        for child_hash_key in (&*self).subtree_diff(*valid_slot_hash_key, SlotHashKey::default()) {
1370            self.do_insert_aggregate_operation(
1371                &mut update_operations,
1372                &Some(UpdateOperation::MarkValid(valid_slot_hash_key.0)),
1373                child_hash_key,
1374            );
1375        }
1376
1377        // Aggregate across all ancestors to find the new best slots including this fork
1378        self.insert_aggregate_operations(&mut update_operations, *valid_slot_hash_key);
1379        self.process_update_operations(update_operations);
1380        newly_duplicate_confirmed_ancestors
1381    }
1382}
1383
1384struct AncestorIterator<'a> {
1385    current_slot_hash_key: SlotHashKey,
1386    fork_infos: &'a HashMap<SlotHashKey, ForkInfo>,
1387}
1388
1389impl<'a> AncestorIterator<'a> {
1390    fn new(
1391        start_slot_hash_key: SlotHashKey,
1392        fork_infos: &'a HashMap<SlotHashKey, ForkInfo>,
1393    ) -> Self {
1394        Self {
1395            current_slot_hash_key: start_slot_hash_key,
1396            fork_infos,
1397        }
1398    }
1399}
1400
1401impl Iterator for AncestorIterator<'_> {
1402    type Item = SlotHashKey;
1403    fn next(&mut self) -> Option<Self::Item> {
1404        let parent_slot_hash_key = self
1405            .fork_infos
1406            .get(&self.current_slot_hash_key)
1407            .map(|fork_info| fork_info.parent)
1408            .unwrap_or(None);
1409
1410        parent_slot_hash_key
1411            .map(|parent_slot_hash_key| {
1412                self.current_slot_hash_key = parent_slot_hash_key;
1413                Some(self.current_slot_hash_key)
1414            })
1415            .unwrap_or(None)
1416    }
1417}
1418
1419#[cfg(test)]
1420mod test {
1421    use {
1422        super::*,
1423        crate::vote_simulator::VoteSimulator,
1424        itertools::Itertools,
1425        solana_hash::Hash,
1426        solana_runtime::{bank::Bank, bank_utils},
1427        solana_slot_history::SlotHistory,
1428        std::{collections::HashSet, ops::Range},
1429        trees::tr,
1430    };
1431
1432    #[test]
1433    fn test_max_by_weight() {
1434        /*
1435            Build fork structure:
1436                 slot 0
1437                   |
1438                 slot 4
1439                   |
1440                 slot 5
1441        */
1442        let forks = tr(0) / (tr(4) / (tr(5)));
1443        let mut heaviest_subtree_fork_choice = HeaviestSubtreeForkChoice::new_from_tree(forks);
1444
1445        let stake = 100;
1446        let (bank, vote_pubkeys) = bank_utils::setup_bank_and_vote_pubkeys_for_tests(1, stake);
1447        heaviest_subtree_fork_choice.add_votes(
1448            [(vote_pubkeys[0], (4, Hash::default()))].iter(),
1449            bank.epoch_stakes_map(),
1450            bank.epoch_schedule(),
1451        );
1452
1453        assert_eq!(
1454            heaviest_subtree_fork_choice.max_by_weight((4, Hash::default()), (5, Hash::default())),
1455            std::cmp::Ordering::Greater
1456        );
1457        assert_eq!(
1458            heaviest_subtree_fork_choice.max_by_weight((4, Hash::default()), (0, Hash::default())),
1459            std::cmp::Ordering::Less
1460        );
1461    }
1462
1463    #[test]
1464    fn test_add_root_parent() {
1465        /*
1466            Build fork structure:
1467                 slot 3
1468                   |
1469                 slot 4
1470                   |
1471                 slot 5
1472        */
1473        let forks = tr(3) / (tr(4) / (tr(5)));
1474        let stake = 100;
1475        let (bank, vote_pubkeys) = bank_utils::setup_bank_and_vote_pubkeys_for_tests(1, stake);
1476        let mut heaviest_subtree_fork_choice = HeaviestSubtreeForkChoice::new_from_tree(forks);
1477        heaviest_subtree_fork_choice.add_votes(
1478            [(vote_pubkeys[0], (5, Hash::default()))].iter(),
1479            bank.epoch_stakes_map(),
1480            bank.epoch_schedule(),
1481        );
1482        heaviest_subtree_fork_choice.add_root_parent((2, Hash::default()));
1483        assert_eq!(
1484            heaviest_subtree_fork_choice
1485                .parent(&(3, Hash::default()))
1486                .unwrap(),
1487            (2, Hash::default())
1488        );
1489        assert_eq!(
1490            heaviest_subtree_fork_choice
1491                .stake_voted_subtree(&(3, Hash::default()))
1492                .unwrap(),
1493            stake
1494        );
1495        assert_eq!(
1496            heaviest_subtree_fork_choice
1497                .stake_voted_at(&(2, Hash::default()))
1498                .unwrap(),
1499            0
1500        );
1501        assert_eq!(
1502            (&heaviest_subtree_fork_choice)
1503                .children(&(2, Hash::default()))
1504                .unwrap()
1505                .collect_vec(),
1506            vec![&(3, Hash::default())]
1507        );
1508        assert_eq!(
1509            heaviest_subtree_fork_choice
1510                .best_slot(&(2, Hash::default()))
1511                .unwrap()
1512                .0,
1513            5
1514        );
1515        assert_eq!(
1516            heaviest_subtree_fork_choice
1517                .deepest_slot(&(2, Hash::default()))
1518                .unwrap()
1519                .0,
1520            5
1521        );
1522
1523        assert!(heaviest_subtree_fork_choice
1524            .parent(&(2, Hash::default()))
1525            .is_none());
1526    }
1527
1528    #[test]
1529    fn test_ancestor_iterator() {
1530        let mut heaviest_subtree_fork_choice = setup_forks();
1531        let parents: Vec<_> = heaviest_subtree_fork_choice
1532            .ancestor_iterator((6, Hash::default()))
1533            .collect();
1534        assert_eq!(
1535            parents,
1536            vec![5, 3, 1, 0]
1537                .into_iter()
1538                .map(|s| (s, Hash::default()))
1539                .collect::<Vec<_>>()
1540        );
1541        let parents: Vec<_> = heaviest_subtree_fork_choice
1542            .ancestor_iterator((4, Hash::default()))
1543            .collect();
1544        assert_eq!(
1545            parents,
1546            vec![2, 1, 0]
1547                .into_iter()
1548                .map(|s| (s, Hash::default()))
1549                .collect::<Vec<_>>()
1550        );
1551        let parents: Vec<_> = heaviest_subtree_fork_choice
1552            .ancestor_iterator((1, Hash::default()))
1553            .collect();
1554        assert_eq!(
1555            parents,
1556            vec![0]
1557                .into_iter()
1558                .map(|s| (s, Hash::default()))
1559                .collect::<Vec<_>>()
1560        );
1561        assert!(heaviest_subtree_fork_choice
1562            .ancestor_iterator((0, Hash::default()))
1563            .next()
1564            .is_none());
1565
1566        // Set a root, everything but slots 2, 4 should be removed
1567        heaviest_subtree_fork_choice.set_tree_root((2, Hash::default()));
1568        let parents: Vec<_> = heaviest_subtree_fork_choice
1569            .ancestor_iterator((4, Hash::default()))
1570            .collect();
1571        assert_eq!(
1572            parents,
1573            vec![2]
1574                .into_iter()
1575                .map(|s| (s, Hash::default()))
1576                .collect::<Vec<_>>()
1577        );
1578    }
1579
1580    #[test]
1581    fn test_new_from_frozen_banks() {
1582        /*
1583            Build fork structure:
1584                 slot 0
1585                   |
1586                 slot 1
1587                 /    \
1588            slot 2    |
1589               |    slot 3
1590            slot 4
1591        */
1592        let forks = tr(0) / (tr(1) / (tr(2) / (tr(4))) / (tr(3)));
1593        let mut vote_simulator = VoteSimulator::new(1);
1594        vote_simulator.fill_bank_forks(forks, &HashMap::new(), true);
1595        let bank_forks = vote_simulator.bank_forks;
1596        let mut frozen_banks: Vec<_> = bank_forks
1597            .read()
1598            .unwrap()
1599            .frozen_banks()
1600            .map(|(_slot, bank)| bank)
1601            .collect();
1602        frozen_banks.sort_by_key(|bank| bank.slot());
1603
1604        let root_bank = bank_forks.read().unwrap().root_bank();
1605        let root = root_bank.slot();
1606        let root_hash = root_bank.hash();
1607        let heaviest_subtree_fork_choice =
1608            HeaviestSubtreeForkChoice::new_from_frozen_banks((root, root_hash), &frozen_banks);
1609
1610        let bank0_hash = bank_forks.read().unwrap().get(0).unwrap().hash();
1611        assert!(heaviest_subtree_fork_choice
1612            .parent(&(0, bank0_hash))
1613            .is_none());
1614
1615        let bank1_hash = bank_forks.read().unwrap().get(1).unwrap().hash();
1616        assert_eq!(
1617            (&heaviest_subtree_fork_choice)
1618                .children(&(0, bank0_hash))
1619                .unwrap()
1620                .collect_vec(),
1621            &[&(1, bank1_hash)]
1622        );
1623
1624        assert_eq!(
1625            heaviest_subtree_fork_choice.parent(&(1, bank1_hash)),
1626            Some((0, bank0_hash))
1627        );
1628        let bank2_hash = bank_forks.read().unwrap().get(2).unwrap().hash();
1629        let bank3_hash = bank_forks.read().unwrap().get(3).unwrap().hash();
1630        assert_eq!(
1631            (&heaviest_subtree_fork_choice)
1632                .children(&(1, bank1_hash))
1633                .unwrap()
1634                .collect_vec(),
1635            &[&(2, bank2_hash), &(3, bank3_hash)]
1636        );
1637        assert_eq!(
1638            heaviest_subtree_fork_choice.parent(&(2, bank2_hash)),
1639            Some((1, bank1_hash))
1640        );
1641        let bank4_hash = bank_forks.read().unwrap().get(4).unwrap().hash();
1642        assert_eq!(
1643            (&heaviest_subtree_fork_choice)
1644                .children(&(2, bank2_hash))
1645                .unwrap()
1646                .collect_vec(),
1647            &[&(4, bank4_hash)]
1648        );
1649        // Check parent and children of invalid hash don't exist
1650        let invalid_hash = Hash::new_unique();
1651        assert!((&heaviest_subtree_fork_choice)
1652            .children(&(2, invalid_hash))
1653            .is_none());
1654        assert!(heaviest_subtree_fork_choice
1655            .parent(&(2, invalid_hash))
1656            .is_none());
1657
1658        assert_eq!(
1659            heaviest_subtree_fork_choice.parent(&(3, bank3_hash)),
1660            Some((1, bank1_hash))
1661        );
1662        assert!((&heaviest_subtree_fork_choice)
1663            .children(&(3, bank3_hash))
1664            .unwrap()
1665            .collect_vec()
1666            .is_empty());
1667        assert_eq!(
1668            heaviest_subtree_fork_choice.parent(&(4, bank4_hash)),
1669            Some((2, bank2_hash))
1670        );
1671        assert!((&heaviest_subtree_fork_choice)
1672            .children(&(4, bank4_hash))
1673            .unwrap()
1674            .collect_vec()
1675            .is_empty());
1676    }
1677
1678    #[test]
1679    fn test_set_root() {
1680        let mut heaviest_subtree_fork_choice = setup_forks();
1681
1682        // Set root to 1, should only purge 0
1683        heaviest_subtree_fork_choice.set_tree_root((1, Hash::default()));
1684        for i in 0..=6 {
1685            let exists = i != 0;
1686            assert_eq!(
1687                heaviest_subtree_fork_choice
1688                    .fork_infos
1689                    .contains_key(&(i, Hash::default())),
1690                exists
1691            );
1692        }
1693
1694        // Set root to 5, should purge everything except 5, 6
1695        heaviest_subtree_fork_choice.set_tree_root((5, Hash::default()));
1696        for i in 0..=6 {
1697            let exists = i == 5 || i == 6;
1698            assert_eq!(
1699                heaviest_subtree_fork_choice
1700                    .fork_infos
1701                    .contains_key(&(i, Hash::default())),
1702                exists
1703            );
1704        }
1705    }
1706
1707    #[test]
1708    fn test_set_root_and_add_votes() {
1709        let mut heaviest_subtree_fork_choice = setup_forks();
1710        let stake = 100;
1711        let (bank, vote_pubkeys) = bank_utils::setup_bank_and_vote_pubkeys_for_tests(1, stake);
1712
1713        // Vote for slot 2
1714        heaviest_subtree_fork_choice.add_votes(
1715            [(vote_pubkeys[0], (2, Hash::default()))].iter(),
1716            bank.epoch_stakes_map(),
1717            bank.epoch_schedule(),
1718        );
1719        assert_eq!(heaviest_subtree_fork_choice.best_overall_slot().0, 4);
1720
1721        // Set a root
1722        heaviest_subtree_fork_choice.set_tree_root((1, Hash::default()));
1723
1724        // Vote again for slot 3 on a different fork than the last vote,
1725        // verify this fork is now the best fork
1726        heaviest_subtree_fork_choice.add_votes(
1727            [(vote_pubkeys[0], (3, Hash::default()))].iter(),
1728            bank.epoch_stakes_map(),
1729            bank.epoch_schedule(),
1730        );
1731
1732        assert_eq!(heaviest_subtree_fork_choice.best_overall_slot().0, 6);
1733        assert_eq!(
1734            heaviest_subtree_fork_choice
1735                .stake_voted_at(&(1, Hash::default()))
1736                .unwrap(),
1737            0
1738        );
1739        assert_eq!(
1740            heaviest_subtree_fork_choice
1741                .stake_voted_at(&(3, Hash::default()))
1742                .unwrap(),
1743            stake
1744        );
1745        for slot in &[1, 3] {
1746            assert_eq!(
1747                heaviest_subtree_fork_choice
1748                    .stake_voted_subtree(&(*slot, Hash::default()))
1749                    .unwrap(),
1750                stake
1751            );
1752        }
1753
1754        // Set a root at last vote
1755        heaviest_subtree_fork_choice.set_tree_root((3, Hash::default()));
1756        // Check new leaf 7 is still propagated properly
1757        heaviest_subtree_fork_choice
1758            .add_new_leaf_slot((7, Hash::default()), Some((6, Hash::default())));
1759        assert_eq!(heaviest_subtree_fork_choice.best_overall_slot().0, 7);
1760    }
1761
1762    #[test]
1763    fn test_set_root_and_add_outdated_votes() {
1764        let mut heaviest_subtree_fork_choice = setup_forks();
1765        let stake = 100;
1766        let (bank, vote_pubkeys) = bank_utils::setup_bank_and_vote_pubkeys_for_tests(1, stake);
1767
1768        // Vote for slot 0
1769        heaviest_subtree_fork_choice.add_votes(
1770            [(vote_pubkeys[0], (0, Hash::default()))].iter(),
1771            bank.epoch_stakes_map(),
1772            bank.epoch_schedule(),
1773        );
1774
1775        // Set root to 1, should purge 0 from the tree, but
1776        // there's still an outstanding vote for slot 0 in `pubkey_votes`.
1777        heaviest_subtree_fork_choice.set_tree_root((1, Hash::default()));
1778
1779        // Vote again for slot 3, verify everything is ok
1780        heaviest_subtree_fork_choice.add_votes(
1781            [(vote_pubkeys[0], (3, Hash::default()))].iter(),
1782            bank.epoch_stakes_map(),
1783            bank.epoch_schedule(),
1784        );
1785        assert_eq!(
1786            heaviest_subtree_fork_choice
1787                .stake_voted_at(&(3, Hash::default()))
1788                .unwrap(),
1789            stake
1790        );
1791        for slot in &[1, 3] {
1792            assert_eq!(
1793                heaviest_subtree_fork_choice
1794                    .stake_voted_subtree(&(*slot, Hash::default()))
1795                    .unwrap(),
1796                stake
1797            );
1798        }
1799        assert_eq!(heaviest_subtree_fork_choice.best_overall_slot().0, 6);
1800
1801        // Set root again on different fork than the last vote
1802        heaviest_subtree_fork_choice.set_tree_root((2, Hash::default()));
1803        // Smaller vote than last vote 3 should be ignored
1804        heaviest_subtree_fork_choice.add_votes(
1805            [(vote_pubkeys[0], (2, Hash::default()))].iter(),
1806            bank.epoch_stakes_map(),
1807            bank.epoch_schedule(),
1808        );
1809        assert_eq!(
1810            heaviest_subtree_fork_choice
1811                .stake_voted_at(&(2, Hash::default()))
1812                .unwrap(),
1813            0
1814        );
1815        assert_eq!(
1816            heaviest_subtree_fork_choice
1817                .stake_voted_subtree(&(2, Hash::default()))
1818                .unwrap(),
1819            0
1820        );
1821        assert_eq!(heaviest_subtree_fork_choice.best_overall_slot().0, 4);
1822
1823        // New larger vote than last vote 3 should be processed
1824        heaviest_subtree_fork_choice.add_votes(
1825            [(vote_pubkeys[0], (4, Hash::default()))].iter(),
1826            bank.epoch_stakes_map(),
1827            bank.epoch_schedule(),
1828        );
1829        assert_eq!(
1830            heaviest_subtree_fork_choice
1831                .stake_voted_at(&(2, Hash::default()))
1832                .unwrap(),
1833            0
1834        );
1835        assert_eq!(
1836            heaviest_subtree_fork_choice
1837                .stake_voted_at(&(4, Hash::default()))
1838                .unwrap(),
1839            stake
1840        );
1841        assert_eq!(
1842            heaviest_subtree_fork_choice
1843                .stake_voted_subtree(&(2, Hash::default()))
1844                .unwrap(),
1845            stake
1846        );
1847        assert_eq!(
1848            heaviest_subtree_fork_choice
1849                .stake_voted_subtree(&(4, Hash::default()))
1850                .unwrap(),
1851            stake
1852        );
1853        assert_eq!(heaviest_subtree_fork_choice.best_overall_slot().0, 4);
1854    }
1855
1856    #[test]
1857    fn test_best_overall_slot() {
1858        let heaviest_subtree_fork_choice = setup_forks();
1859        // Best overall path is 0 -> 1 -> 2 -> 4, so best leaf
1860        // should be 4
1861        assert_eq!(heaviest_subtree_fork_choice.best_overall_slot().0, 4);
1862    }
1863
1864    #[test]
1865    fn test_add_new_leaf_duplicate() {
1866        let (
1867            mut heaviest_subtree_fork_choice,
1868            duplicate_leaves_descended_from_4,
1869            duplicate_leaves_descended_from_5,
1870            _,
1871        ) = setup_duplicate_forks();
1872
1873        // Add a child to one of the duplicates
1874        let duplicate_parent = duplicate_leaves_descended_from_4[0];
1875        let child = (11, Hash::new_unique());
1876        heaviest_subtree_fork_choice.add_new_leaf_slot(child, Some(duplicate_parent));
1877        assert_eq!(
1878            (&heaviest_subtree_fork_choice)
1879                .children(&duplicate_parent)
1880                .unwrap()
1881                .collect_vec(),
1882            &[&child]
1883        );
1884        assert_eq!(heaviest_subtree_fork_choice.best_overall_slot(), child);
1885
1886        // All the other duplicates should have no children
1887        for duplicate_leaf in duplicate_leaves_descended_from_5
1888            .iter()
1889            .chain(std::iter::once(&duplicate_leaves_descended_from_4[1]))
1890        {
1891            assert!((&heaviest_subtree_fork_choice)
1892                .children(duplicate_leaf)
1893                .unwrap()
1894                .collect_vec()
1895                .is_empty(),);
1896        }
1897
1898        // Re-adding same duplicate slot should not overwrite existing one
1899        heaviest_subtree_fork_choice
1900            .add_new_leaf_slot(duplicate_parent, Some((4, Hash::default())));
1901        assert_eq!(
1902            (&heaviest_subtree_fork_choice)
1903                .children(&duplicate_parent)
1904                .unwrap()
1905                .collect_vec(),
1906            &[&child]
1907        );
1908        assert_eq!(heaviest_subtree_fork_choice.best_overall_slot(), child);
1909    }
1910
1911    #[test]
1912    fn test_propagate_new_leaf() {
1913        let mut heaviest_subtree_fork_choice = setup_forks();
1914
1915        // Add a leaf 10, it should be the best and deepest choice
1916        heaviest_subtree_fork_choice
1917            .add_new_leaf_slot((10, Hash::default()), Some((4, Hash::default())));
1918        let ancestors = heaviest_subtree_fork_choice
1919            .ancestor_iterator((10, Hash::default()))
1920            .chain(std::iter::once((10, Hash::default())));
1921        for a in ancestors {
1922            assert_eq!(heaviest_subtree_fork_choice.best_slot(&a).unwrap().0, 10);
1923            assert_eq!(heaviest_subtree_fork_choice.deepest_slot(&a).unwrap().0, 10);
1924        }
1925
1926        // Add a smaller leaf 9, it should be the best and deepest choice
1927        heaviest_subtree_fork_choice
1928            .add_new_leaf_slot((9, Hash::default()), Some((4, Hash::default())));
1929        let ancestors = heaviest_subtree_fork_choice
1930            .ancestor_iterator((9, Hash::default()))
1931            .chain(std::iter::once((9, Hash::default())));
1932        for a in ancestors {
1933            assert_eq!(heaviest_subtree_fork_choice.best_slot(&a).unwrap().0, 9);
1934            assert_eq!(heaviest_subtree_fork_choice.deepest_slot(&a).unwrap().0, 9);
1935        }
1936
1937        // Add a higher leaf 11, should not change the best or deepest choice
1938        heaviest_subtree_fork_choice
1939            .add_new_leaf_slot((11, Hash::default()), Some((4, Hash::default())));
1940        let ancestors = heaviest_subtree_fork_choice
1941            .ancestor_iterator((11, Hash::default()))
1942            .chain(std::iter::once((9, Hash::default())));
1943        for a in ancestors {
1944            assert_eq!(heaviest_subtree_fork_choice.best_slot(&a).unwrap().0, 9);
1945            assert_eq!(heaviest_subtree_fork_choice.deepest_slot(&a).unwrap().0, 9);
1946        }
1947
1948        // Add a vote for the other branch at slot 3.
1949        let stake = 100;
1950        let (bank, vote_pubkeys) = bank_utils::setup_bank_and_vote_pubkeys_for_tests(2, stake);
1951        let leaf6 = 6;
1952        // Leaf slot 9 stops being the `best_slot` at slot 1 because there
1953        // are now votes for the branch at slot 3
1954        heaviest_subtree_fork_choice.add_votes(
1955            [(vote_pubkeys[0], (leaf6, Hash::default()))].iter(),
1956            bank.epoch_stakes_map(),
1957            bank.epoch_schedule(),
1958        );
1959
1960        // Because slot 1 now sees the child branch at slot 3 has non-zero
1961        // weight, adding smaller leaf slot 8 in the other child branch at slot 2
1962        // should not propagate past slot 1
1963        // Similarly, both forks have the same tree height so we should tie break by
1964        // stake weight choosing 6 as the deepest slot when possible.
1965        heaviest_subtree_fork_choice
1966            .add_new_leaf_slot((8, Hash::default()), Some((4, Hash::default())));
1967        let ancestors = heaviest_subtree_fork_choice
1968            .ancestor_iterator((8, Hash::default()))
1969            .chain(std::iter::once((8, Hash::default())));
1970        for a in ancestors {
1971            let best_slot = if a.0 > 1 { 8 } else { leaf6 };
1972            assert_eq!(
1973                heaviest_subtree_fork_choice.best_slot(&a).unwrap().0,
1974                best_slot
1975            );
1976            assert_eq!(
1977                heaviest_subtree_fork_choice.deepest_slot(&a).unwrap().0,
1978                best_slot
1979            );
1980        }
1981
1982        // Add vote for slot 8, should now be the best slot (has same weight
1983        // as fork containing slot 6, but slot 2 is smaller than slot 3).
1984        heaviest_subtree_fork_choice.add_votes(
1985            [(vote_pubkeys[1], (8, Hash::default()))].iter(),
1986            bank.epoch_stakes_map(),
1987            bank.epoch_schedule(),
1988        );
1989        assert_eq!(heaviest_subtree_fork_choice.best_overall_slot().0, 8);
1990        // Deepest overall is now 8 as well
1991        assert_eq!(heaviest_subtree_fork_choice.deepest_overall_slot().0, 8);
1992
1993        // Because slot 4 now sees the child leaf 8 has non-zero
1994        // weight, adding smaller leaf slots should not propagate past slot 4
1995        // Similarly by tiebreak, 8 should be the deepest slot
1996        heaviest_subtree_fork_choice
1997            .add_new_leaf_slot((7, Hash::default()), Some((4, Hash::default())));
1998        let ancestors = heaviest_subtree_fork_choice
1999            .ancestor_iterator((7, Hash::default()))
2000            .chain(std::iter::once((8, Hash::default())));
2001        for a in ancestors {
2002            assert_eq!(heaviest_subtree_fork_choice.best_slot(&a).unwrap().0, 8);
2003            assert_eq!(heaviest_subtree_fork_choice.deepest_slot(&a).unwrap().0, 8);
2004        }
2005
2006        // All the leaves should think they are their own best and deepest choice
2007        for leaf in [8, 9, 10, 11].iter() {
2008            assert_eq!(
2009                heaviest_subtree_fork_choice
2010                    .best_slot(&(*leaf, Hash::default()))
2011                    .unwrap()
2012                    .0,
2013                *leaf
2014            );
2015            assert_eq!(
2016                heaviest_subtree_fork_choice
2017                    .deepest_slot(&(*leaf, Hash::default()))
2018                    .unwrap()
2019                    .0,
2020                *leaf
2021            );
2022        }
2023    }
2024
2025    #[test]
2026    fn test_propagate_new_leaf_2() {
2027        /*
2028            Build fork structure:
2029                 slot 0
2030                   |
2031                 slot 4
2032                   |
2033                 slot 6
2034        */
2035        let forks = tr(0) / (tr(4) / (tr(6)));
2036        let mut heaviest_subtree_fork_choice = HeaviestSubtreeForkChoice::new_from_tree(forks);
2037        let stake = 100;
2038        let (bank, vote_pubkeys) = bank_utils::setup_bank_and_vote_pubkeys_for_tests(1, stake);
2039
2040        // slot 6 should be the best because it's the only leaf
2041        assert_eq!(heaviest_subtree_fork_choice.best_overall_slot().0, 6);
2042
2043        // Add a leaf slot 5. Even though 5 is less than the best leaf 6,
2044        // it's not less than it's sibling slot 4, so the best overall
2045        // leaf should remain unchanged
2046        heaviest_subtree_fork_choice
2047            .add_new_leaf_slot((5, Hash::default()), Some((0, Hash::default())));
2048        assert_eq!(heaviest_subtree_fork_choice.best_overall_slot().0, 6);
2049
2050        // Add a leaf slot 2 on a different fork than leaf 6. Slot 2 should
2051        // be the new best because it's for a lesser slot
2052        heaviest_subtree_fork_choice
2053            .add_new_leaf_slot((2, Hash::default()), Some((0, Hash::default())));
2054        assert_eq!(heaviest_subtree_fork_choice.best_overall_slot().0, 2);
2055
2056        // Add a vote for slot 4, so leaf 6 should be the best again
2057        heaviest_subtree_fork_choice.add_votes(
2058            [(vote_pubkeys[0], (4, Hash::default()))].iter(),
2059            bank.epoch_stakes_map(),
2060            bank.epoch_schedule(),
2061        );
2062        assert_eq!(heaviest_subtree_fork_choice.best_overall_slot().0, 6);
2063
2064        // Adding a slot 1 that is less than the current best leaf 6 should not change the best
2065        // slot because the fork slot 5 is on has a higher weight
2066        heaviest_subtree_fork_choice
2067            .add_new_leaf_slot((1, Hash::default()), Some((0, Hash::default())));
2068        assert_eq!(heaviest_subtree_fork_choice.best_overall_slot().0, 6);
2069    }
2070
2071    #[test]
2072    fn test_aggregate_slot() {
2073        let mut heaviest_subtree_fork_choice = setup_forks();
2074
2075        // No weights are present, weights should be zero
2076        heaviest_subtree_fork_choice.aggregate_slot((1, Hash::default()));
2077        assert_eq!(
2078            heaviest_subtree_fork_choice
2079                .stake_voted_at(&(1, Hash::default()))
2080                .unwrap(),
2081            0
2082        );
2083        assert_eq!(
2084            heaviest_subtree_fork_choice
2085                .stake_voted_subtree(&(1, Hash::default()))
2086                .unwrap(),
2087            0
2088        );
2089        // The best leaf when weights are equal should prioritize the lower leaf
2090        assert_eq!(
2091            heaviest_subtree_fork_choice
2092                .best_slot(&(1, Hash::default()))
2093                .unwrap()
2094                .0,
2095            4
2096        );
2097        assert_eq!(
2098            heaviest_subtree_fork_choice
2099                .best_slot(&(2, Hash::default()))
2100                .unwrap()
2101                .0,
2102            4
2103        );
2104        assert_eq!(
2105            heaviest_subtree_fork_choice
2106                .best_slot(&(3, Hash::default()))
2107                .unwrap()
2108                .0,
2109            6
2110        );
2111        // The deepest leaf only tiebreaks by slot # when tree heights are equal
2112        assert_eq!(
2113            heaviest_subtree_fork_choice
2114                .deepest_slot(&(1, Hash::default()))
2115                .unwrap()
2116                .0,
2117            6
2118        );
2119        assert_eq!(
2120            heaviest_subtree_fork_choice
2121                .deepest_slot(&(2, Hash::default()))
2122                .unwrap()
2123                .0,
2124            4
2125        );
2126        assert_eq!(
2127            heaviest_subtree_fork_choice
2128                .deepest_slot(&(3, Hash::default()))
2129                .unwrap()
2130                .0,
2131            6
2132        );
2133
2134        // Update the weights that have voted *exactly* at each slot, the
2135        // branch containing slots {5, 6} has weight 11, so should be heavier
2136        // than the branch containing slots {2, 4}
2137        let mut total_stake = 0;
2138        let staked_voted_slots: HashSet<_> = vec![2, 4, 5, 6].into_iter().collect();
2139        for slot in &staked_voted_slots {
2140            heaviest_subtree_fork_choice.set_stake_voted_at((*slot, Hash::default()), *slot);
2141            total_stake += *slot;
2142        }
2143
2144        // Aggregate up each of the two forks (order matters, has to be
2145        // reverse order for each fork, and aggregating a slot multiple times
2146        // is fine)
2147        let slots_to_aggregate: Vec<_> = std::iter::once((6, Hash::default()))
2148            .chain(heaviest_subtree_fork_choice.ancestor_iterator((6, Hash::default())))
2149            .chain(std::iter::once((4, Hash::default())))
2150            .chain(heaviest_subtree_fork_choice.ancestor_iterator((4, Hash::default())))
2151            .collect();
2152
2153        for slot_hash in slots_to_aggregate {
2154            heaviest_subtree_fork_choice.aggregate_slot(slot_hash);
2155        }
2156
2157        // The best path is now 0 -> 1 -> 3 -> 5 -> 6, so leaf 6
2158        // should be the best choice
2159        // It is still the deepest choice
2160        assert_eq!(heaviest_subtree_fork_choice.best_overall_slot().0, 6);
2161        assert_eq!(heaviest_subtree_fork_choice.deepest_overall_slot().0, 6);
2162
2163        // Verify `stake_voted_at`
2164        for slot in 0..=6 {
2165            let expected_stake = if staked_voted_slots.contains(&slot) {
2166                slot
2167            } else {
2168                0
2169            };
2170
2171            assert_eq!(
2172                heaviest_subtree_fork_choice
2173                    .stake_voted_at(&(slot, Hash::default()))
2174                    .unwrap(),
2175                expected_stake
2176            );
2177        }
2178
2179        // Verify `stake_voted_subtree` for common fork
2180        for slot in &[0, 1] {
2181            // Subtree stake is sum of the `stake_voted_at` across
2182            // all slots in the subtree
2183            assert_eq!(
2184                heaviest_subtree_fork_choice
2185                    .stake_voted_subtree(&(*slot, Hash::default()))
2186                    .unwrap(),
2187                total_stake
2188            );
2189        }
2190        // Verify `stake_voted_subtree` for fork 1
2191        let mut total_expected_stake = 0;
2192        for slot in &[4, 2] {
2193            total_expected_stake += heaviest_subtree_fork_choice
2194                .stake_voted_at(&(*slot, Hash::default()))
2195                .unwrap();
2196            assert_eq!(
2197                heaviest_subtree_fork_choice
2198                    .stake_voted_subtree(&(*slot, Hash::default()))
2199                    .unwrap(),
2200                total_expected_stake
2201            );
2202        }
2203        // Verify `stake_voted_subtree` for fork 2
2204        total_expected_stake = 0;
2205        for slot in &[6, 5, 3] {
2206            total_expected_stake += heaviest_subtree_fork_choice
2207                .stake_voted_at(&(*slot, Hash::default()))
2208                .unwrap();
2209            assert_eq!(
2210                heaviest_subtree_fork_choice
2211                    .stake_voted_subtree(&(*slot, Hash::default()))
2212                    .unwrap(),
2213                total_expected_stake
2214            );
2215        }
2216    }
2217
2218    #[test]
2219    fn test_process_update_operations() {
2220        let mut heaviest_subtree_fork_choice = setup_forks();
2221        let stake = 100;
2222        let (bank, vote_pubkeys) = bank_utils::setup_bank_and_vote_pubkeys_for_tests(3, stake);
2223
2224        let pubkey_votes: Vec<(Pubkey, SlotHashKey)> = vec![
2225            (vote_pubkeys[0], (3, Hash::default())),
2226            (vote_pubkeys[1], (2, Hash::default())),
2227            (vote_pubkeys[2], (1, Hash::default())),
2228        ];
2229        let expected_best_slot =
2230            |slot, heaviest_subtree_fork_choice: &HeaviestSubtreeForkChoice| -> Slot {
2231                if !heaviest_subtree_fork_choice.is_leaf((slot, Hash::default())) {
2232                    // Both branches have equal weight, so should pick the lesser leaf
2233                    if heaviest_subtree_fork_choice
2234                        .ancestor_iterator((4, Hash::default()))
2235                        .collect::<HashSet<SlotHashKey>>()
2236                        .contains(&(slot, Hash::default()))
2237                    {
2238                        4
2239                    } else {
2240                        6
2241                    }
2242                } else {
2243                    slot
2244                }
2245            };
2246
2247        let expected_deepest_slot =
2248            |slot, _heaviest_subtree_fork_choice: &HeaviestSubtreeForkChoice| -> Slot {
2249                if [2, 4].contains(&slot) {
2250                    4
2251                } else {
2252                    6
2253                }
2254            };
2255
2256        check_process_update_correctness(
2257            &mut heaviest_subtree_fork_choice,
2258            &pubkey_votes,
2259            0..7,
2260            &bank,
2261            stake,
2262            expected_best_slot,
2263            expected_deepest_slot,
2264        );
2265
2266        // Everyone makes newer votes
2267        let pubkey_votes: Vec<(Pubkey, SlotHashKey)> = vec![
2268            (vote_pubkeys[0], (4, Hash::default())),
2269            (vote_pubkeys[1], (3, Hash::default())),
2270            (vote_pubkeys[2], (3, Hash::default())),
2271        ];
2272
2273        let expected_best_slot =
2274            |slot, heaviest_subtree_fork_choice: &HeaviestSubtreeForkChoice| -> Slot {
2275                if !heaviest_subtree_fork_choice.is_leaf((slot, Hash::default())) {
2276                    // The branch with leaf 6 now has two votes, so should pick that one
2277                    if heaviest_subtree_fork_choice
2278                        .ancestor_iterator((6, Hash::default()))
2279                        .collect::<HashSet<SlotHashKey>>()
2280                        .contains(&(slot, Hash::default()))
2281                    {
2282                        6
2283                    } else {
2284                        4
2285                    }
2286                } else {
2287                    slot
2288                }
2289            };
2290
2291        check_process_update_correctness(
2292            &mut heaviest_subtree_fork_choice,
2293            &pubkey_votes,
2294            0..7,
2295            &bank,
2296            stake,
2297            expected_best_slot,
2298            expected_deepest_slot,
2299        );
2300    }
2301
2302    #[test]
2303    fn test_generate_update_operations() {
2304        let mut heaviest_subtree_fork_choice = setup_forks();
2305        let stake = 100;
2306        let (bank, vote_pubkeys) = bank_utils::setup_bank_and_vote_pubkeys_for_tests(3, stake);
2307        let pubkey_votes: Vec<(Pubkey, SlotHashKey)> = vec![
2308            (vote_pubkeys[0], (3, Hash::default())),
2309            (vote_pubkeys[1], (4, Hash::default())),
2310            (vote_pubkeys[2], (1, Hash::default())),
2311        ];
2312
2313        let expected_update_operations: UpdateOperations = vec![
2314            // Add/remove from new/old forks
2315            (
2316                ((1, Hash::default()), UpdateLabel::Add),
2317                UpdateOperation::Add(stake),
2318            ),
2319            (
2320                ((3, Hash::default()), UpdateLabel::Add),
2321                UpdateOperation::Add(stake),
2322            ),
2323            (
2324                ((4, Hash::default()), UpdateLabel::Add),
2325                UpdateOperation::Add(stake),
2326            ),
2327            // Aggregate all ancestors of changed slots
2328            (
2329                ((0, Hash::default()), UpdateLabel::Aggregate),
2330                UpdateOperation::Aggregate,
2331            ),
2332            (
2333                ((1, Hash::default()), UpdateLabel::Aggregate),
2334                UpdateOperation::Aggregate,
2335            ),
2336            (
2337                ((2, Hash::default()), UpdateLabel::Aggregate),
2338                UpdateOperation::Aggregate,
2339            ),
2340        ]
2341        .into_iter()
2342        .collect();
2343
2344        let generated_update_operations = heaviest_subtree_fork_choice.generate_update_operations(
2345            pubkey_votes.iter(),
2346            bank.epoch_stakes_map(),
2347            bank.epoch_schedule(),
2348        );
2349        assert_eq!(expected_update_operations, generated_update_operations);
2350
2351        // Everyone makes older/same votes, should be ignored
2352        let pubkey_votes: Vec<(Pubkey, SlotHashKey)> = vec![
2353            (vote_pubkeys[0], (3, Hash::default())),
2354            (vote_pubkeys[1], (2, Hash::default())),
2355            (vote_pubkeys[2], (1, Hash::default())),
2356        ];
2357        let generated_update_operations = heaviest_subtree_fork_choice.generate_update_operations(
2358            pubkey_votes.iter(),
2359            bank.epoch_stakes_map(),
2360            bank.epoch_schedule(),
2361        );
2362        assert!(generated_update_operations.is_empty());
2363
2364        // Some people make newer votes
2365        let pubkey_votes: Vec<(Pubkey, SlotHashKey)> = vec![
2366            // old, ignored
2367            (vote_pubkeys[0], (3, Hash::default())),
2368            // new, switched forks
2369            (vote_pubkeys[1], (5, Hash::default())),
2370            // new, same fork
2371            (vote_pubkeys[2], (3, Hash::default())),
2372        ];
2373
2374        let expected_update_operations: BTreeMap<(SlotHashKey, UpdateLabel), UpdateOperation> =
2375            vec![
2376                // Add/remove to/from new/old forks
2377                (
2378                    ((3, Hash::default()), UpdateLabel::Add),
2379                    UpdateOperation::Add(stake),
2380                ),
2381                (
2382                    ((5, Hash::default()), UpdateLabel::Add),
2383                    UpdateOperation::Add(stake),
2384                ),
2385                (
2386                    ((1, Hash::default()), UpdateLabel::Subtract),
2387                    UpdateOperation::Subtract(stake),
2388                ),
2389                (
2390                    ((4, Hash::default()), UpdateLabel::Subtract),
2391                    UpdateOperation::Subtract(stake),
2392                ),
2393                // Aggregate all ancestors of changed slots
2394                (
2395                    ((0, Hash::default()), UpdateLabel::Aggregate),
2396                    UpdateOperation::Aggregate,
2397                ),
2398                (
2399                    ((1, Hash::default()), UpdateLabel::Aggregate),
2400                    UpdateOperation::Aggregate,
2401                ),
2402                (
2403                    ((2, Hash::default()), UpdateLabel::Aggregate),
2404                    UpdateOperation::Aggregate,
2405                ),
2406                (
2407                    ((3, Hash::default()), UpdateLabel::Aggregate),
2408                    UpdateOperation::Aggregate,
2409                ),
2410            ]
2411            .into_iter()
2412            .collect();
2413
2414        let generated_update_operations = heaviest_subtree_fork_choice.generate_update_operations(
2415            pubkey_votes.iter(),
2416            bank.epoch_stakes_map(),
2417            bank.epoch_schedule(),
2418        );
2419        assert_eq!(expected_update_operations, generated_update_operations);
2420
2421        // People make new votes
2422        let pubkey_votes: Vec<(Pubkey, SlotHashKey)> = vec![
2423            // new, switch forks
2424            (vote_pubkeys[0], (4, Hash::default())),
2425            // new, same fork
2426            (vote_pubkeys[1], (6, Hash::default())),
2427            // new, same fork
2428            (vote_pubkeys[2], (6, Hash::default())),
2429        ];
2430
2431        let expected_update_operations: BTreeMap<(SlotHashKey, UpdateLabel), UpdateOperation> =
2432            vec![
2433                // Add/remove from new/old forks
2434                (
2435                    ((4, Hash::default()), UpdateLabel::Add),
2436                    UpdateOperation::Add(stake),
2437                ),
2438                (
2439                    ((6, Hash::default()), UpdateLabel::Add),
2440                    UpdateOperation::Add(2 * stake),
2441                ),
2442                (
2443                    ((3, Hash::default()), UpdateLabel::Subtract),
2444                    UpdateOperation::Subtract(2 * stake),
2445                ),
2446                (
2447                    ((5, Hash::default()), UpdateLabel::Subtract),
2448                    UpdateOperation::Subtract(stake),
2449                ),
2450                // Aggregate all ancestors of changed slots
2451                (
2452                    ((0, Hash::default()), UpdateLabel::Aggregate),
2453                    UpdateOperation::Aggregate,
2454                ),
2455                (
2456                    ((1, Hash::default()), UpdateLabel::Aggregate),
2457                    UpdateOperation::Aggregate,
2458                ),
2459                (
2460                    ((2, Hash::default()), UpdateLabel::Aggregate),
2461                    UpdateOperation::Aggregate,
2462                ),
2463                (
2464                    ((3, Hash::default()), UpdateLabel::Aggregate),
2465                    UpdateOperation::Aggregate,
2466                ),
2467                (
2468                    ((5, Hash::default()), UpdateLabel::Aggregate),
2469                    UpdateOperation::Aggregate,
2470                ),
2471            ]
2472            .into_iter()
2473            .collect();
2474
2475        let generated_update_operations = heaviest_subtree_fork_choice.generate_update_operations(
2476            pubkey_votes.iter(),
2477            bank.epoch_stakes_map(),
2478            bank.epoch_schedule(),
2479        );
2480        assert_eq!(expected_update_operations, generated_update_operations);
2481    }
2482
2483    #[test]
2484    fn test_add_votes() {
2485        let mut heaviest_subtree_fork_choice = setup_forks();
2486        let stake = 100;
2487        let (bank, vote_pubkeys) = bank_utils::setup_bank_and_vote_pubkeys_for_tests(3, stake);
2488
2489        let pubkey_votes: Vec<(Pubkey, SlotHashKey)> = vec![
2490            (vote_pubkeys[0], (3, Hash::default())),
2491            (vote_pubkeys[1], (2, Hash::default())),
2492            (vote_pubkeys[2], (1, Hash::default())),
2493        ];
2494        assert_eq!(
2495            heaviest_subtree_fork_choice
2496                .add_votes(
2497                    pubkey_votes.iter(),
2498                    bank.epoch_stakes_map(),
2499                    bank.epoch_schedule()
2500                )
2501                .0,
2502            4
2503        );
2504
2505        assert_eq!(heaviest_subtree_fork_choice.best_overall_slot().0, 4)
2506    }
2507
2508    #[test]
2509    fn test_add_votes_duplicate_tie() {
2510        let (
2511            mut heaviest_subtree_fork_choice,
2512            duplicate_leaves_descended_from_4,
2513            _,
2514            duplicate_leaves_descended_from_6,
2515        ) = setup_duplicate_forks();
2516        let stake = 10;
2517        let num_validators = 2;
2518        let (bank, vote_pubkeys) =
2519            bank_utils::setup_bank_and_vote_pubkeys_for_tests(num_validators, stake);
2520
2521        let pubkey_votes: Vec<(Pubkey, SlotHashKey)> = vec![
2522            (vote_pubkeys[0], duplicate_leaves_descended_from_4[0]),
2523            (vote_pubkeys[1], duplicate_leaves_descended_from_4[1]),
2524        ];
2525
2526        // duplicate_leaves_descended_from_4 are sorted, and fork choice will pick the smaller
2527        // one in the event of a tie
2528        let expected_best_slot_hash = duplicate_leaves_descended_from_4[0];
2529        assert_eq!(
2530            heaviest_subtree_fork_choice.add_votes(
2531                pubkey_votes.iter(),
2532                bank.epoch_stakes_map(),
2533                bank.epoch_schedule()
2534            ),
2535            expected_best_slot_hash
2536        );
2537        assert_eq!(
2538            heaviest_subtree_fork_choice.best_overall_slot(),
2539            expected_best_slot_hash
2540        );
2541
2542        // we tie break the duplicate_leaves_descended_from_6 and pick the smaller one
2543        // for deepest
2544        let expected_deepest_slot_hash = duplicate_leaves_descended_from_6[0];
2545        assert_eq!(
2546            heaviest_subtree_fork_choice
2547                .deepest_slot(&(3, Hash::default()))
2548                .unwrap(),
2549            expected_deepest_slot_hash
2550        );
2551        assert_eq!(
2552            heaviest_subtree_fork_choice.deepest_overall_slot(),
2553            expected_deepest_slot_hash
2554        );
2555
2556        // Adding the same vote again will not do anything
2557        let pubkey_votes: Vec<(Pubkey, SlotHashKey)> =
2558            vec![(vote_pubkeys[1], duplicate_leaves_descended_from_4[1])];
2559        assert_eq!(
2560            heaviest_subtree_fork_choice.add_votes(
2561                pubkey_votes.iter(),
2562                bank.epoch_stakes_map(),
2563                bank.epoch_schedule()
2564            ),
2565            expected_best_slot_hash
2566        );
2567
2568        assert_eq!(
2569            heaviest_subtree_fork_choice
2570                .stake_voted_subtree(&duplicate_leaves_descended_from_4[1])
2571                .unwrap(),
2572            stake
2573        );
2574        assert_eq!(
2575            heaviest_subtree_fork_choice
2576                .stake_voted_at(&duplicate_leaves_descended_from_4[1])
2577                .unwrap(),
2578            stake
2579        );
2580        assert_eq!(
2581            heaviest_subtree_fork_choice.deepest_overall_slot(),
2582            expected_deepest_slot_hash
2583        );
2584
2585        // All common ancestors should have subtree voted stake == 2 * stake, but direct
2586        // voted stake == 0
2587        let expected_ancestors_stake = 2 * stake;
2588        for ancestor in
2589            heaviest_subtree_fork_choice.ancestor_iterator(duplicate_leaves_descended_from_4[1])
2590        {
2591            assert_eq!(
2592                heaviest_subtree_fork_choice
2593                    .stake_voted_subtree(&ancestor)
2594                    .unwrap(),
2595                expected_ancestors_stake
2596            );
2597            assert_eq!(
2598                heaviest_subtree_fork_choice
2599                    .stake_voted_at(&ancestor)
2600                    .unwrap(),
2601                0,
2602            );
2603        }
2604    }
2605
2606    #[test]
2607    fn test_add_votes_duplicate_greater_hash_ignored() {
2608        let (
2609            mut heaviest_subtree_fork_choice,
2610            duplicate_leaves_descended_from_4,
2611            _,
2612            duplicate_leaves_descended_from_6,
2613        ) = setup_duplicate_forks();
2614        let stake = 10;
2615        let num_validators = 2;
2616        let (bank, vote_pubkeys) =
2617            bank_utils::setup_bank_and_vote_pubkeys_for_tests(num_validators, stake);
2618
2619        let pubkey_votes: Vec<(Pubkey, SlotHashKey)> = vec![
2620            (vote_pubkeys[0], duplicate_leaves_descended_from_4[0]),
2621            (vote_pubkeys[1], duplicate_leaves_descended_from_4[1]),
2622        ];
2623
2624        // duplicate_leaves_descended_from_4 are sorted, and fork choice will pick the smaller
2625        // one in the event of a tie
2626        let expected_best_slot_hash = duplicate_leaves_descended_from_4[0];
2627        assert_eq!(
2628            heaviest_subtree_fork_choice.add_votes(
2629                pubkey_votes.iter(),
2630                bank.epoch_stakes_map(),
2631                bank.epoch_schedule()
2632            ),
2633            expected_best_slot_hash
2634        );
2635        // we tie break the duplicate_leaves_descended_from_6 and pick the smaller one
2636        // for deepest
2637        let expected_deepest_slot_hash = duplicate_leaves_descended_from_6[0];
2638        assert_eq!(
2639            heaviest_subtree_fork_choice.deepest_overall_slot(),
2640            expected_deepest_slot_hash
2641        );
2642        // Adding a duplicate vote for a validator, for another a greater bank hash,
2643        // should be ignored as we prioritize the smaller bank hash. Thus nothing
2644        // should change.
2645        let pubkey_votes: Vec<(Pubkey, SlotHashKey)> =
2646            vec![(vote_pubkeys[0], duplicate_leaves_descended_from_4[1])];
2647        assert_eq!(
2648            heaviest_subtree_fork_choice.add_votes(
2649                pubkey_votes.iter(),
2650                bank.epoch_stakes_map(),
2651                bank.epoch_schedule()
2652            ),
2653            expected_best_slot_hash
2654        );
2655        assert_eq!(
2656            heaviest_subtree_fork_choice.deepest_overall_slot(),
2657            expected_deepest_slot_hash
2658        );
2659
2660        // Still only has one validator voting on it
2661        assert_eq!(
2662            heaviest_subtree_fork_choice
2663                .stake_voted_subtree(&duplicate_leaves_descended_from_4[1])
2664                .unwrap(),
2665            stake
2666        );
2667        assert_eq!(
2668            heaviest_subtree_fork_choice
2669                .stake_voted_at(&duplicate_leaves_descended_from_4[1])
2670                .unwrap(),
2671            stake
2672        );
2673        // All common ancestors should have subtree voted stake == 2 * stake, but direct
2674        // voted stake == 0
2675        let expected_ancestors_stake = 2 * stake;
2676        for ancestor in
2677            heaviest_subtree_fork_choice.ancestor_iterator(duplicate_leaves_descended_from_4[1])
2678        {
2679            assert_eq!(
2680                heaviest_subtree_fork_choice
2681                    .stake_voted_subtree(&ancestor)
2682                    .unwrap(),
2683                expected_ancestors_stake
2684            );
2685            assert_eq!(
2686                heaviest_subtree_fork_choice
2687                    .stake_voted_at(&ancestor)
2688                    .unwrap(),
2689                0,
2690            );
2691        }
2692    }
2693
2694    #[test]
2695    fn test_add_votes_duplicate_smaller_hash_prioritized() {
2696        let (
2697            mut heaviest_subtree_fork_choice,
2698            duplicate_leaves_descended_from_4,
2699            _,
2700            duplicate_leaves_descended_from_6,
2701        ) = setup_duplicate_forks();
2702        let stake = 10;
2703        let num_validators = 2;
2704        let (bank, vote_pubkeys) =
2705            bank_utils::setup_bank_and_vote_pubkeys_for_tests(num_validators, stake);
2706
2707        // Both voters voted on duplicate_leaves_descended_from_4[1], so thats the heaviest
2708        // branch
2709        let pubkey_votes: Vec<(Pubkey, SlotHashKey)> = vec![
2710            (vote_pubkeys[0], duplicate_leaves_descended_from_4[1]),
2711            (vote_pubkeys[1], duplicate_leaves_descended_from_4[1]),
2712        ];
2713
2714        let expected_best_slot_hash = duplicate_leaves_descended_from_4[1];
2715        assert_eq!(
2716            heaviest_subtree_fork_choice.add_votes(
2717                pubkey_votes.iter(),
2718                bank.epoch_stakes_map(),
2719                bank.epoch_schedule()
2720            ),
2721            expected_best_slot_hash
2722        );
2723        let expected_deepest_slot_hash = duplicate_leaves_descended_from_6[0];
2724        assert_eq!(
2725            heaviest_subtree_fork_choice.deepest_overall_slot(),
2726            expected_deepest_slot_hash
2727        );
2728
2729        // BEFORE, both validators voting on this leaf
2730        assert_eq!(
2731            heaviest_subtree_fork_choice
2732                .stake_voted_subtree(&duplicate_leaves_descended_from_4[1])
2733                .unwrap(),
2734            2 * stake,
2735        );
2736        assert_eq!(
2737            heaviest_subtree_fork_choice
2738                .stake_voted_at(&duplicate_leaves_descended_from_4[1])
2739                .unwrap(),
2740            2 * stake,
2741        );
2742
2743        // Adding a duplicate vote for a validator, for another a smaller bank hash,
2744        // should be proritized and replace the vote for the greater bank hash.
2745        // Now because both duplicate nodes are tied, the best leaf is the smaller one.
2746        let pubkey_votes: Vec<(Pubkey, SlotHashKey)> =
2747            vec![(vote_pubkeys[0], duplicate_leaves_descended_from_4[0])];
2748        let expected_best_slot_hash = duplicate_leaves_descended_from_4[0];
2749        assert_eq!(
2750            heaviest_subtree_fork_choice.add_votes(
2751                pubkey_votes.iter(),
2752                bank.epoch_stakes_map(),
2753                bank.epoch_schedule()
2754            ),
2755            expected_best_slot_hash
2756        );
2757
2758        // AFTER, only one of the validators is voting on this leaf
2759        assert_eq!(
2760            heaviest_subtree_fork_choice
2761                .stake_voted_subtree(&duplicate_leaves_descended_from_4[1])
2762                .unwrap(),
2763            stake,
2764        );
2765        assert_eq!(
2766            heaviest_subtree_fork_choice
2767                .stake_voted_at(&duplicate_leaves_descended_from_4[1])
2768                .unwrap(),
2769            stake,
2770        );
2771        assert_eq!(
2772            heaviest_subtree_fork_choice.deepest_overall_slot(),
2773            expected_deepest_slot_hash
2774        );
2775
2776        // The other leaf now has one of the votes
2777        assert_eq!(
2778            heaviest_subtree_fork_choice
2779                .stake_voted_subtree(&duplicate_leaves_descended_from_4[0])
2780                .unwrap(),
2781            stake,
2782        );
2783        assert_eq!(
2784            heaviest_subtree_fork_choice
2785                .stake_voted_at(&duplicate_leaves_descended_from_4[0])
2786                .unwrap(),
2787            stake,
2788        );
2789
2790        // All common ancestors should have subtree voted stake == 2 * stake, but direct
2791        // voted stake == 0
2792        let expected_ancestors_stake = 2 * stake;
2793        for ancestor in
2794            heaviest_subtree_fork_choice.ancestor_iterator(duplicate_leaves_descended_from_4[0])
2795        {
2796            assert_eq!(
2797                heaviest_subtree_fork_choice
2798                    .stake_voted_subtree(&ancestor)
2799                    .unwrap(),
2800                expected_ancestors_stake
2801            );
2802            assert_eq!(
2803                heaviest_subtree_fork_choice
2804                    .stake_voted_at(&ancestor)
2805                    .unwrap(),
2806                0,
2807            );
2808        }
2809    }
2810
2811    #[test]
2812    fn test_add_votes_duplicate_then_outdated() {
2813        let (mut heaviest_subtree_fork_choice, duplicate_leaves_descended_from_4, _, _) =
2814            setup_duplicate_forks();
2815        let stake = 10;
2816        let num_validators = 3;
2817        let (bank, vote_pubkeys) =
2818            bank_utils::setup_bank_and_vote_pubkeys_for_tests(num_validators, stake);
2819
2820        let pubkey_votes: Vec<(Pubkey, SlotHashKey)> = vec![
2821            (vote_pubkeys[0], duplicate_leaves_descended_from_4[0]),
2822            (vote_pubkeys[1], duplicate_leaves_descended_from_4[1]),
2823        ];
2824
2825        // duplicate_leaves_descended_from_4 are sorted, and fork choice will pick the smaller
2826        // one in the event of a tie
2827        let expected_best_slot_hash = duplicate_leaves_descended_from_4[0];
2828        assert_eq!(
2829            heaviest_subtree_fork_choice.add_votes(
2830                pubkey_votes.iter(),
2831                bank.epoch_stakes_map(),
2832                bank.epoch_schedule()
2833            ),
2834            expected_best_slot_hash
2835        );
2836
2837        // Create two children for slots greater than the duplicate slot,
2838        // 1) descended from the current best slot (which also happens to be a duplicate slot)
2839        // 2) another descended from a non-duplicate slot.
2840        assert_eq!(
2841            heaviest_subtree_fork_choice.best_overall_slot(),
2842            duplicate_leaves_descended_from_4[0]
2843        );
2844        // Create new child with heaviest duplicate parent
2845        let duplicate_parent = duplicate_leaves_descended_from_4[0];
2846        let duplicate_slot = duplicate_parent.0;
2847
2848        // Create new child with non-duplicate parent
2849        let nonduplicate_parent = (2, Hash::default());
2850        let higher_child_with_duplicate_parent = (duplicate_slot + 1, Hash::new_unique());
2851        let higher_child_with_nonduplicate_parent = (duplicate_slot + 2, Hash::new_unique());
2852        heaviest_subtree_fork_choice
2853            .add_new_leaf_slot(higher_child_with_duplicate_parent, Some(duplicate_parent));
2854        heaviest_subtree_fork_choice.add_new_leaf_slot(
2855            higher_child_with_nonduplicate_parent,
2856            Some(nonduplicate_parent),
2857        );
2858
2859        // vote_pubkeys[0] and vote_pubkeys[1] should both have their latest votes
2860        // erased after a vote for a higher parent
2861        let pubkey_votes: Vec<(Pubkey, SlotHashKey)> = vec![
2862            (vote_pubkeys[0], higher_child_with_duplicate_parent),
2863            (vote_pubkeys[1], higher_child_with_nonduplicate_parent),
2864            (vote_pubkeys[2], higher_child_with_nonduplicate_parent),
2865        ];
2866        let expected_best_slot_hash = higher_child_with_nonduplicate_parent;
2867        assert_eq!(
2868            heaviest_subtree_fork_choice.add_votes(
2869                pubkey_votes.iter(),
2870                bank.epoch_stakes_map(),
2871                bank.epoch_schedule()
2872            ),
2873            expected_best_slot_hash
2874        );
2875
2876        // All the stake directly voting on the duplicates have been outdated
2877        for (i, duplicate_leaf) in duplicate_leaves_descended_from_4.iter().enumerate() {
2878            assert_eq!(
2879                heaviest_subtree_fork_choice
2880                    .stake_voted_at(duplicate_leaf)
2881                    .unwrap(),
2882                0,
2883            );
2884
2885            if i == 0 {
2886                // The subtree stake of the first duplicate however, has one vote still
2887                // because it's the parent of the `higher_child_with_duplicate_parent`,
2888                // which has one vote
2889                assert_eq!(
2890                    heaviest_subtree_fork_choice
2891                        .stake_voted_subtree(duplicate_leaf)
2892                        .unwrap(),
2893                    stake,
2894                );
2895            } else {
2896                assert_eq!(
2897                    heaviest_subtree_fork_choice
2898                        .stake_voted_subtree(duplicate_leaf)
2899                        .unwrap(),
2900                    0,
2901                );
2902            }
2903        }
2904
2905        // Node 4 has subtree voted stake == stake since it only has one voter on it
2906        let node4 = (4, Hash::default());
2907        assert_eq!(
2908            heaviest_subtree_fork_choice
2909                .stake_voted_subtree(&node4)
2910                .unwrap(),
2911            stake,
2912        );
2913        assert_eq!(
2914            heaviest_subtree_fork_choice.stake_voted_at(&node4).unwrap(),
2915            0,
2916        );
2917
2918        // All ancestors of 4 should have subtree voted stake == num_validators * stake,
2919        // but direct voted stake == 0
2920        let expected_ancestors_stake = num_validators as u64 * stake;
2921        for ancestor in heaviest_subtree_fork_choice.ancestor_iterator(node4) {
2922            assert_eq!(
2923                heaviest_subtree_fork_choice
2924                    .stake_voted_subtree(&ancestor)
2925                    .unwrap(),
2926                expected_ancestors_stake
2927            );
2928            assert_eq!(
2929                heaviest_subtree_fork_choice
2930                    .stake_voted_at(&ancestor)
2931                    .unwrap(),
2932                0,
2933            );
2934        }
2935    }
2936
2937    #[test]
2938    fn test_add_votes_duplicate_zero_stake() {
2939        let (mut heaviest_subtree_fork_choice, duplicate_leaves_descended_from_4, _, _): (
2940            HeaviestSubtreeForkChoice,
2941            Vec<SlotHashKey>,
2942            Vec<SlotHashKey>,
2943            Vec<SlotHashKey>,
2944        ) = setup_duplicate_forks();
2945
2946        let stake = 0;
2947        let num_validators = 2;
2948        let (bank, vote_pubkeys) =
2949            bank_utils::setup_bank_and_vote_pubkeys_for_tests(num_validators, stake);
2950
2951        // Make new vote with vote_pubkeys[0] for a higher slot
2952        // Create new child with heaviest duplicate parent
2953        let duplicate_parent = duplicate_leaves_descended_from_4[0];
2954        let duplicate_slot = duplicate_parent.0;
2955        let higher_child_with_duplicate_parent = (duplicate_slot + 1, Hash::new_unique());
2956        heaviest_subtree_fork_choice
2957            .add_new_leaf_slot(higher_child_with_duplicate_parent, Some(duplicate_parent));
2958
2959        // Vote for pubkey 0 on one of the duplicate slots
2960        let pubkey_votes: Vec<(Pubkey, SlotHashKey)> =
2961            vec![(vote_pubkeys[0], duplicate_leaves_descended_from_4[1])];
2962
2963        // Stake is zero, so because duplicate_leaves_descended_from_4[0] and
2964        // duplicate_leaves_descended_from_4[1] are tied, the child of the smaller
2965        // node duplicate_leaves_descended_from_4[0] is the one that is picked
2966        let expected_best_slot_hash = higher_child_with_duplicate_parent;
2967        assert_eq!(
2968            heaviest_subtree_fork_choice.add_votes(
2969                pubkey_votes.iter(),
2970                bank.epoch_stakes_map(),
2971                bank.epoch_schedule()
2972            ),
2973            expected_best_slot_hash
2974        );
2975        assert_eq!(
2976            *heaviest_subtree_fork_choice
2977                .latest_votes
2978                .get(&vote_pubkeys[0])
2979                .unwrap(),
2980            duplicate_leaves_descended_from_4[1]
2981        );
2982
2983        // Now add a vote for a higher slot, and ensure the latest votes
2984        // for this pubkey were updated
2985        let pubkey_votes: Vec<(Pubkey, SlotHashKey)> =
2986            vec![(vote_pubkeys[0], higher_child_with_duplicate_parent)];
2987
2988        assert_eq!(
2989            heaviest_subtree_fork_choice.add_votes(
2990                pubkey_votes.iter(),
2991                bank.epoch_stakes_map(),
2992                bank.epoch_schedule()
2993            ),
2994            expected_best_slot_hash
2995        );
2996        assert_eq!(
2997            *heaviest_subtree_fork_choice
2998                .latest_votes
2999                .get(&vote_pubkeys[0])
3000                .unwrap(),
3001            higher_child_with_duplicate_parent
3002        );
3003    }
3004
3005    #[test]
3006    fn test_is_best_child() {
3007        /*
3008            Build fork structure:
3009                 slot 0
3010                   |
3011                 slot 4
3012                /      \
3013          slot 10     slot 9
3014        */
3015        let forks = tr(0) / (tr(4) / (tr(9)) / (tr(10)));
3016        let mut heaviest_subtree_fork_choice = HeaviestSubtreeForkChoice::new_from_tree(forks);
3017        assert!(heaviest_subtree_fork_choice.is_best_child(&(0, Hash::default())));
3018        assert!(heaviest_subtree_fork_choice.is_best_child(&(4, Hash::default())));
3019
3020        // 9 is better than 10
3021        assert!(heaviest_subtree_fork_choice.is_best_child(&(9, Hash::default())));
3022        assert!(!heaviest_subtree_fork_choice.is_best_child(&(10, Hash::default())));
3023
3024        // Add new leaf 8, which is better than 9, as both have weight 0
3025        heaviest_subtree_fork_choice
3026            .add_new_leaf_slot((8, Hash::default()), Some((4, Hash::default())));
3027        assert!(heaviest_subtree_fork_choice.is_best_child(&(8, Hash::default())));
3028        assert!(!heaviest_subtree_fork_choice.is_best_child(&(9, Hash::default())));
3029        assert!(!heaviest_subtree_fork_choice.is_best_child(&(10, Hash::default())));
3030
3031        // Add vote for 9, it's the best again
3032        let (bank, vote_pubkeys) = bank_utils::setup_bank_and_vote_pubkeys_for_tests(3, 100);
3033        heaviest_subtree_fork_choice.add_votes(
3034            [(vote_pubkeys[0], (9, Hash::default()))].iter(),
3035            bank.epoch_stakes_map(),
3036            bank.epoch_schedule(),
3037        );
3038        assert!(heaviest_subtree_fork_choice.is_best_child(&(9, Hash::default())));
3039        assert!(!heaviest_subtree_fork_choice.is_best_child(&(8, Hash::default())));
3040        assert!(!heaviest_subtree_fork_choice.is_best_child(&(10, Hash::default())));
3041    }
3042
3043    #[test]
3044    fn test_merge() {
3045        let stake = 100;
3046        let (bank, vote_pubkeys) = bank_utils::setup_bank_and_vote_pubkeys_for_tests(4, stake);
3047        /*
3048            Build fork structure:
3049                 slot 0
3050                   |
3051                 slot 3
3052                 /    \
3053            slot 5    |
3054               |    slot 9
3055            slot 7    |
3056                    slot 11
3057                      |
3058                    slot 12 (vote pubkey 2)
3059        */
3060        let forks = tr(0) / (tr(3) / (tr(5) / (tr(7))) / (tr(9) / (tr(11) / (tr(12)))));
3061        let mut tree1 = HeaviestSubtreeForkChoice::new_from_tree(forks);
3062        let pubkey_votes: Vec<(Pubkey, SlotHashKey)> = vec![
3063            (vote_pubkeys[0], (5, Hash::default())),
3064            (vote_pubkeys[1], (3, Hash::default())),
3065            (vote_pubkeys[2], (12, Hash::default())),
3066        ];
3067        tree1.add_votes(
3068            pubkey_votes.iter(),
3069            bank.epoch_stakes_map(),
3070            bank.epoch_schedule(),
3071        );
3072
3073        /*
3074                    Build fork structure:
3075                          slot 10
3076                             |
3077                          slot 15
3078                         /       \
3079        (vote pubkey 0) slot 16   |
3080                       |       slot 18
3081                    slot 17       |
3082                               slot 19 (vote pubkey 1)
3083                                  |
3084                               slot 20 (vote pubkey 3)
3085        */
3086        let forks = tr(10) / (tr(15) / (tr(16) / (tr(17))) / (tr(18) / (tr(19) / (tr(20)))));
3087        let mut tree2 = HeaviestSubtreeForkChoice::new_from_tree(forks);
3088        let pubkey_votes: Vec<(Pubkey, SlotHashKey)> = vec![
3089            // more than tree 1
3090            (vote_pubkeys[0], (16, Hash::default())),
3091            // more than tree1
3092            (vote_pubkeys[1], (19, Hash::default())),
3093            // less than tree1
3094            (vote_pubkeys[2], (10, Hash::default())),
3095            // Add a pubkey that only voted on this tree
3096            (vote_pubkeys[3], (20, Hash::default())),
3097        ];
3098        tree2.add_votes(
3099            pubkey_votes.iter(),
3100            bank.epoch_stakes_map(),
3101            bank.epoch_schedule(),
3102        );
3103
3104        // Merge tree2 at leaf 7 of tree1
3105        tree1.merge(
3106            tree2,
3107            &(7, Hash::default()),
3108            bank.epoch_stakes_map(),
3109            bank.epoch_schedule(),
3110        );
3111
3112        // Check ancestry information is correct
3113        let ancestors: Vec<_> = tree1.ancestor_iterator((20, Hash::default())).collect();
3114        assert_eq!(
3115            ancestors,
3116            vec![19, 18, 15, 10, 7, 5, 3, 0]
3117                .into_iter()
3118                .map(|s| (s, Hash::default()))
3119                .collect::<Vec<_>>()
3120        );
3121        let ancestors: Vec<_> = tree1.ancestor_iterator((17, Hash::default())).collect();
3122        assert_eq!(
3123            ancestors,
3124            vec![16, 15, 10, 7, 5, 3, 0]
3125                .into_iter()
3126                .map(|s| (s, Hash::default()))
3127                .collect::<Vec<_>>()
3128        );
3129
3130        // Check correctness of votes
3131        // Pubkey 0
3132        assert_eq!(tree1.stake_voted_at(&(16, Hash::default())).unwrap(), stake);
3133        assert_eq!(tree1.stake_voted_at(&(5, Hash::default())).unwrap(), 0);
3134        // Pubkey 1
3135        assert_eq!(tree1.stake_voted_at(&(19, Hash::default())).unwrap(), stake);
3136        assert_eq!(tree1.stake_voted_at(&(3, Hash::default())).unwrap(), 0);
3137        // Pubkey 2
3138        assert_eq!(tree1.stake_voted_at(&(10, Hash::default())).unwrap(), 0);
3139        assert_eq!(tree1.stake_voted_at(&(12, Hash::default())).unwrap(), stake);
3140        // Pubkey 3
3141        assert_eq!(tree1.stake_voted_at(&(20, Hash::default())).unwrap(), stake);
3142
3143        for slot in &[0, 3] {
3144            assert_eq!(
3145                tree1
3146                    .stake_voted_subtree(&(*slot, Hash::default()))
3147                    .unwrap(),
3148                4 * stake
3149            );
3150        }
3151        for slot in &[5, 7, 10, 15] {
3152            assert_eq!(
3153                tree1
3154                    .stake_voted_subtree(&(*slot, Hash::default()))
3155                    .unwrap(),
3156                3 * stake
3157            );
3158        }
3159        for slot in &[18, 19] {
3160            assert_eq!(
3161                tree1
3162                    .stake_voted_subtree(&(*slot, Hash::default()))
3163                    .unwrap(),
3164                2 * stake
3165            );
3166        }
3167        for slot in &[9, 11, 12, 16, 20] {
3168            assert_eq!(
3169                tree1
3170                    .stake_voted_subtree(&(*slot, Hash::default()))
3171                    .unwrap(),
3172                stake
3173            );
3174        }
3175        {
3176            let slot = &17;
3177            assert_eq!(
3178                tree1
3179                    .stake_voted_subtree(&(*slot, Hash::default()))
3180                    .unwrap(),
3181                0
3182            );
3183        }
3184
3185        assert_eq!(tree1.best_overall_slot().0, 20);
3186    }
3187
3188    #[test]
3189    fn test_merge_duplicate() {
3190        let stake = 100;
3191        let (bank, vote_pubkeys) = bank_utils::setup_bank_and_vote_pubkeys_for_tests(2, stake);
3192        let mut slot_5_duplicate_hashes = std::iter::repeat_with(|| (5, Hash::new_unique()))
3193            .take(2)
3194            .collect::<Vec<_>>();
3195        slot_5_duplicate_hashes.sort();
3196
3197        /*
3198            Build fork structure:
3199                 slot 0
3200                /     \
3201           slot 2     slot 5 (bigger hash)
3202        */
3203        let forks =
3204            tr((0, Hash::default())) / tr((2, Hash::default())) / tr(slot_5_duplicate_hashes[1]);
3205        let mut tree1 = HeaviestSubtreeForkChoice::new_from_tree(forks);
3206        let pubkey_votes: Vec<(Pubkey, SlotHashKey)> = vec![
3207            (vote_pubkeys[0], (2, Hash::default())),
3208            (vote_pubkeys[1], slot_5_duplicate_hashes[1]),
3209        ];
3210        tree1.add_votes(
3211            pubkey_votes.iter(),
3212            bank.epoch_stakes_map(),
3213            bank.epoch_schedule(),
3214        );
3215
3216        /*
3217                    Build fork structure:
3218                          slot 3
3219                             |
3220                          slot 5 (smaller hash, prioritized over previous version)
3221        */
3222        let forks = tr((3, Hash::default())) / tr(slot_5_duplicate_hashes[0]);
3223        let mut tree2 = HeaviestSubtreeForkChoice::new_from_tree(forks);
3224        let pubkey_votes: Vec<(Pubkey, SlotHashKey)> = vec![
3225            (vote_pubkeys[0], (3, Hash::default())),
3226            // Pubkey 1 voted on another version of slot 5
3227            (vote_pubkeys[1], slot_5_duplicate_hashes[0]),
3228        ];
3229
3230        tree2.add_votes(
3231            pubkey_votes.iter(),
3232            bank.epoch_stakes_map(),
3233            bank.epoch_schedule(),
3234        );
3235
3236        // Merge tree2 at leaf 2 of tree1
3237        tree1.merge(
3238            tree2,
3239            &(2, Hash::default()),
3240            bank.epoch_stakes_map(),
3241            bank.epoch_schedule(),
3242        );
3243
3244        // Pubkey 1 voted on both versions of slot 5, but should prioritize the one in
3245        // the merged branch because it's for a smaller hash
3246        assert_eq!(
3247            tree1.stake_voted_at(&slot_5_duplicate_hashes[1]).unwrap(),
3248            0
3249        );
3250        assert_eq!(
3251            tree1.stake_voted_at(&slot_5_duplicate_hashes[0]).unwrap(),
3252            stake
3253        );
3254        assert_eq!(tree1.best_overall_slot(), slot_5_duplicate_hashes[0]);
3255
3256        // Check the ancestors are correct
3257        let ancestors: Vec<_> = tree1
3258            .ancestor_iterator(slot_5_duplicate_hashes[1])
3259            .collect();
3260        assert_eq!(ancestors, vec![(0, Hash::default())]);
3261        let ancestors: Vec<_> = tree1
3262            .ancestor_iterator(slot_5_duplicate_hashes[0])
3263            .collect();
3264        assert_eq!(
3265            ancestors,
3266            vec![
3267                (3, Hash::default()),
3268                (2, Hash::default()),
3269                (0, Hash::default())
3270            ]
3271        );
3272    }
3273
3274    #[test]
3275    fn test_subtree_diff() {
3276        let mut heaviest_subtree_fork_choice = setup_forks();
3277
3278        // Diff of same root is empty, no matter root, intermediate node, or leaf
3279        assert!((&heaviest_subtree_fork_choice)
3280            .subtree_diff((0, Hash::default()), (0, Hash::default()))
3281            .is_empty());
3282        assert!((&heaviest_subtree_fork_choice)
3283            .subtree_diff((5, Hash::default()), (5, Hash::default()))
3284            .is_empty());
3285        assert!((&heaviest_subtree_fork_choice)
3286            .subtree_diff((6, Hash::default()), (6, Hash::default()))
3287            .is_empty());
3288
3289        // The set reachable from slot 3, excluding subtree 1, is just everything
3290        // in slot 3 since subtree 1 is an ancestor
3291        assert_eq!(
3292            (&heaviest_subtree_fork_choice)
3293                .subtree_diff((3, Hash::default()), (1, Hash::default())),
3294            vec![3, 5, 6]
3295                .into_iter()
3296                .map(|s| (s, Hash::default()))
3297                .collect::<HashSet<_>>()
3298        );
3299
3300        // The set reachable from slot 1, excluding subtree 3, is just 1 and
3301        // the subtree at 2
3302        assert_eq!(
3303            (&heaviest_subtree_fork_choice)
3304                .subtree_diff((1, Hash::default()), (3, Hash::default())),
3305            vec![1, 2, 4]
3306                .into_iter()
3307                .map(|s| (s, Hash::default()))
3308                .collect::<HashSet<_>>()
3309        );
3310
3311        // The set reachable from slot 1, excluding leaf 6, is just everything
3312        // except leaf 6
3313        assert_eq!(
3314            (&heaviest_subtree_fork_choice)
3315                .subtree_diff((0, Hash::default()), (6, Hash::default())),
3316            vec![0, 1, 3, 5, 2, 4]
3317                .into_iter()
3318                .map(|s| (s, Hash::default()))
3319                .collect::<HashSet<_>>()
3320        );
3321
3322        // Set root at 1
3323        heaviest_subtree_fork_choice.set_tree_root((1, Hash::default()));
3324
3325        // Zero no longer exists, set reachable from 0 is empty
3326        assert!((&heaviest_subtree_fork_choice)
3327            .subtree_diff((0, Hash::default()), (6, Hash::default()))
3328            .is_empty());
3329    }
3330
3331    #[test]
3332    fn test_stray_restored_slot() {
3333        let forks = tr(0) / (tr(1) / tr(2));
3334        let heaviest_subtree_fork_choice = HeaviestSubtreeForkChoice::new_from_tree(forks);
3335
3336        let mut tower = Tower::new_for_tests(10, 0.9);
3337        tower.record_vote(1, Hash::default());
3338
3339        assert!(!tower.is_stray_last_vote());
3340        assert_eq!(
3341            heaviest_subtree_fork_choice.heaviest_slot_on_same_voted_fork(&tower),
3342            Some((2, Hash::default()))
3343        );
3344
3345        // Make slot 1 (existing in bank_forks) a restored stray slot
3346        let mut slot_history = SlotHistory::default();
3347        slot_history.add(0);
3348        // Work around TooOldSlotHistory
3349        slot_history.add(999);
3350        tower = tower
3351            .adjust_lockouts_after_replay(0, &slot_history)
3352            .unwrap();
3353
3354        assert!(tower.is_stray_last_vote());
3355        assert_eq!(
3356            heaviest_subtree_fork_choice.heaviest_slot_on_same_voted_fork(&tower),
3357            Some((2, Hash::default()))
3358        );
3359
3360        // Make slot 3 (NOT existing in bank_forks) a restored stray slot
3361        tower.record_vote(3, Hash::default());
3362        tower = tower
3363            .adjust_lockouts_after_replay(0, &slot_history)
3364            .unwrap();
3365
3366        assert!(tower.is_stray_last_vote());
3367        assert_eq!(
3368            heaviest_subtree_fork_choice.heaviest_slot_on_same_voted_fork(&tower),
3369            None
3370        );
3371    }
3372
3373    #[test]
3374    fn test_mark_valid_invalid_forks() {
3375        let mut heaviest_subtree_fork_choice = setup_forks();
3376        let stake = 100;
3377        let (bank, vote_pubkeys) = bank_utils::setup_bank_and_vote_pubkeys_for_tests(3, stake);
3378
3379        let pubkey_votes: Vec<(Pubkey, SlotHashKey)> = vec![
3380            (vote_pubkeys[0], (6, Hash::default())),
3381            (vote_pubkeys[1], (6, Hash::default())),
3382            (vote_pubkeys[2], (2, Hash::default())),
3383        ];
3384        let expected_best_slot = 6;
3385        assert_eq!(
3386            heaviest_subtree_fork_choice.add_votes(
3387                pubkey_votes.iter(),
3388                bank.epoch_stakes_map(),
3389                bank.epoch_schedule()
3390            ),
3391            (expected_best_slot, Hash::default()),
3392        );
3393        assert_eq!(
3394            heaviest_subtree_fork_choice.deepest_overall_slot(),
3395            (expected_best_slot, Hash::default()),
3396        );
3397
3398        // Simulate a vote on slot 5
3399        let last_voted_slot_hash = (5, Hash::default());
3400        let mut tower = Tower::new_for_tests(10, 0.9);
3401        tower.record_vote(last_voted_slot_hash.0, last_voted_slot_hash.1);
3402
3403        // The heaviest_slot_on_same_voted_fork() should be 6, descended from 5.
3404        assert_eq!(
3405            heaviest_subtree_fork_choice
3406                .heaviest_slot_on_same_voted_fork(&tower)
3407                .unwrap(),
3408            (6, Hash::default())
3409        );
3410
3411        // Mark slot 5 as invalid
3412        let invalid_candidate = last_voted_slot_hash;
3413        heaviest_subtree_fork_choice.mark_fork_invalid_candidate(&invalid_candidate);
3414        assert!(!heaviest_subtree_fork_choice
3415            .is_candidate(&invalid_candidate)
3416            .unwrap());
3417
3418        // The ancestor 3 is still a candidate
3419        assert!(heaviest_subtree_fork_choice
3420            .is_candidate(&(3, Hash::default()))
3421            .unwrap());
3422
3423        // The best fork should be its ancestor 3, not the other fork at 4.
3424        assert_eq!(heaviest_subtree_fork_choice.best_overall_slot().0, 3);
3425
3426        // After marking the last vote in the tower as invalid, `heaviest_slot_on_same_voted_fork()`
3427        // should instead use the deepest slot metric, which is still 6
3428        assert_eq!(
3429            heaviest_subtree_fork_choice.heaviest_slot_on_same_voted_fork(&tower),
3430            Some((6, Hash::default()))
3431        );
3432
3433        // Adding another descendant to the invalid candidate won't
3434        // update the best slot, even if it contains votes
3435        let new_leaf7 = (7, Hash::default());
3436        heaviest_subtree_fork_choice.add_new_leaf_slot(new_leaf7, Some((6, Hash::default())));
3437        let invalid_slot_ancestor = 3;
3438        assert_eq!(
3439            heaviest_subtree_fork_choice.best_overall_slot().0,
3440            invalid_slot_ancestor
3441        );
3442        let pubkey_votes: Vec<(Pubkey, SlotHashKey)> = vec![(vote_pubkeys[0], new_leaf7)];
3443        assert_eq!(
3444            heaviest_subtree_fork_choice.add_votes(
3445                pubkey_votes.iter(),
3446                bank.epoch_stakes_map(),
3447                bank.epoch_schedule()
3448            ),
3449            (invalid_slot_ancestor, Hash::default()),
3450        );
3451
3452        // However this should update the `heaviest_slot_on_same_voted_fork` since we use
3453        // deepest metric for invalid forks
3454        assert_eq!(
3455            heaviest_subtree_fork_choice
3456                .heaviest_slot_on_same_voted_fork(&tower)
3457                .unwrap(),
3458            new_leaf7,
3459        );
3460
3461        // Adding a descendant to the ancestor of the invalid candidate *should* update
3462        // the best slot though, since the ancestor is on the heaviest fork
3463        let new_leaf8 = (8, Hash::default());
3464        heaviest_subtree_fork_choice
3465            .add_new_leaf_slot(new_leaf8, Some((invalid_slot_ancestor, Hash::default())));
3466        assert_eq!(heaviest_subtree_fork_choice.best_overall_slot(), new_leaf8,);
3467        // Should not update the `heaviest_slot_on_same_voted_fork` because the new leaf
3468        // is not descended from the last vote
3469        assert_eq!(
3470            heaviest_subtree_fork_choice
3471                .heaviest_slot_on_same_voted_fork(&tower)
3472                .unwrap(),
3473            new_leaf7
3474        );
3475
3476        // If we mark slot a descendant of `invalid_candidate` as valid, then that
3477        // should also mark `invalid_candidate` as valid, and the best slot should
3478        // be the leaf of the heaviest fork, `new_leaf_slot`.
3479        heaviest_subtree_fork_choice.mark_fork_valid_candidate(&invalid_candidate);
3480        assert!(heaviest_subtree_fork_choice
3481            .is_candidate(&invalid_candidate)
3482            .unwrap());
3483        assert_eq!(
3484            heaviest_subtree_fork_choice.best_overall_slot(),
3485            // Should pick the smaller slot of the two new equally weighted leaves
3486            new_leaf7
3487        );
3488        // Should update the `heaviest_slot_on_same_voted_fork` as well
3489        assert_eq!(
3490            heaviest_subtree_fork_choice
3491                .heaviest_slot_on_same_voted_fork(&tower)
3492                .unwrap(),
3493            new_leaf7
3494        );
3495    }
3496
3497    fn setup_mark_invalid_forks_duplicate_tests() -> (
3498        HeaviestSubtreeForkChoice,
3499        Vec<SlotHashKey>,
3500        SlotHashKey,
3501        Bank,
3502        Vec<Pubkey>,
3503    ) {
3504        let (
3505            mut heaviest_subtree_fork_choice,
3506            duplicate_leaves_descended_from_4,
3507            duplicate_leaves_descended_from_5,
3508            duplicate_leaves_descended_from_6,
3509        ) = setup_duplicate_forks();
3510        let stake = 100;
3511        let (bank, vote_pubkeys) = bank_utils::setup_bank_and_vote_pubkeys_for_tests(3, stake);
3512
3513        let pubkey_votes: Vec<(Pubkey, SlotHashKey)> = vec![
3514            (vote_pubkeys[0], duplicate_leaves_descended_from_4[0]),
3515            (vote_pubkeys[1], duplicate_leaves_descended_from_5[0]),
3516        ];
3517
3518        // The best slot should be the smallest leaf descended from 4
3519        assert_eq!(
3520            heaviest_subtree_fork_choice.add_votes(
3521                pubkey_votes.iter(),
3522                bank.epoch_stakes_map(),
3523                bank.epoch_schedule(),
3524            ),
3525            duplicate_leaves_descended_from_4[0]
3526        );
3527        // Deepest slot should be the smallest leaf descended from 6
3528        assert_eq!(
3529            heaviest_subtree_fork_choice.deepest_overall_slot(),
3530            duplicate_leaves_descended_from_6[0],
3531        );
3532
3533        // If we mark slot 4 as invalid, the ancestor 2 should be the heaviest, not
3534        // the other branch at slot 5
3535        let invalid_candidate = (4, Hash::default());
3536        heaviest_subtree_fork_choice.mark_fork_invalid_candidate(&invalid_candidate);
3537        assert_eq!(
3538            heaviest_subtree_fork_choice.best_overall_slot(),
3539            (2, Hash::default())
3540        );
3541        // Samallest duplicate from 6 should still be deepest
3542        assert_eq!(
3543            heaviest_subtree_fork_choice.deepest_overall_slot(),
3544            duplicate_leaves_descended_from_6[0],
3545        );
3546        (
3547            heaviest_subtree_fork_choice,
3548            duplicate_leaves_descended_from_4,
3549            invalid_candidate,
3550            bank,
3551            vote_pubkeys,
3552        )
3553    }
3554
3555    #[test]
3556    fn test_mark_invalid_then_valid_duplicate() {
3557        let (
3558            mut heaviest_subtree_fork_choice,
3559            duplicate_leaves_descended_from_4,
3560            invalid_candidate,
3561            ..,
3562        ) = setup_mark_invalid_forks_duplicate_tests();
3563
3564        // Marking candidate as valid again will choose the heaviest leaf of
3565        // the newly valid branch
3566        let duplicate_slot = duplicate_leaves_descended_from_4[0].0;
3567        let duplicate_descendant = (duplicate_slot + 1, Hash::new_unique());
3568        heaviest_subtree_fork_choice.add_new_leaf_slot(
3569            duplicate_descendant,
3570            Some(duplicate_leaves_descended_from_4[0]),
3571        );
3572        heaviest_subtree_fork_choice.mark_fork_valid_candidate(&invalid_candidate);
3573        assert_eq!(
3574            heaviest_subtree_fork_choice.best_overall_slot(),
3575            duplicate_descendant
3576        );
3577    }
3578
3579    #[test]
3580    fn test_mark_invalid_then_add_new_heavier_duplicate_slot() {
3581        let (
3582            mut heaviest_subtree_fork_choice,
3583            duplicate_leaves_descended_from_4,
3584            _invalid_candidate,
3585            bank,
3586            vote_pubkeys,
3587        ) = setup_mark_invalid_forks_duplicate_tests();
3588
3589        // If we add a new version of the duplicate slot that is not descended from the invalid
3590        // candidate and votes for that duplicate slot, the new duplicate slot should be picked
3591        // once it has more weight
3592        let new_duplicate_hash = Hash::default();
3593
3594        // The hash has to be smaller in order for the votes to be counted
3595        assert!(new_duplicate_hash < duplicate_leaves_descended_from_4[0].1);
3596        let duplicate_slot = duplicate_leaves_descended_from_4[0].0;
3597        let new_duplicate = (duplicate_slot, new_duplicate_hash);
3598        heaviest_subtree_fork_choice.add_new_leaf_slot(new_duplicate, Some((3, Hash::default())));
3599
3600        let pubkey_votes: Vec<(Pubkey, SlotHashKey)> = vec![
3601            (vote_pubkeys[0], new_duplicate),
3602            (vote_pubkeys[1], new_duplicate),
3603        ];
3604
3605        heaviest_subtree_fork_choice.add_votes(
3606            pubkey_votes.iter(),
3607            bank.epoch_stakes_map(),
3608            bank.epoch_schedule(),
3609        );
3610
3611        assert_eq!(
3612            heaviest_subtree_fork_choice.best_overall_slot(),
3613            new_duplicate
3614        );
3615    }
3616
3617    #[test]
3618    fn test_mark_valid_then_descendant_invalid() {
3619        let forks = tr(0) / (tr(1) / (tr(2) / (tr(3) / (tr(4) / (tr(5) / tr(6))))));
3620        let mut heaviest_subtree_fork_choice = HeaviestSubtreeForkChoice::new_from_tree(forks);
3621        let duplicate_confirmed_slot: Slot = 1;
3622        let duplicate_confirmed_key = duplicate_confirmed_slot.slot_hash();
3623        heaviest_subtree_fork_choice.mark_fork_valid_candidate(&duplicate_confirmed_key);
3624
3625        for slot_hash_key in heaviest_subtree_fork_choice.fork_infos.keys() {
3626            let slot = slot_hash_key.0;
3627            if slot <= duplicate_confirmed_slot {
3628                assert!(heaviest_subtree_fork_choice
3629                    .is_duplicate_confirmed(slot_hash_key)
3630                    .unwrap());
3631            } else {
3632                assert!(!heaviest_subtree_fork_choice
3633                    .is_duplicate_confirmed(slot_hash_key)
3634                    .unwrap());
3635            }
3636            assert!(heaviest_subtree_fork_choice
3637                .latest_invalid_ancestor(slot_hash_key)
3638                .is_none());
3639        }
3640
3641        // Mark a later descendant invalid
3642        let invalid_descendant_slot = 5;
3643        let invalid_descendant_key = invalid_descendant_slot.slot_hash();
3644        heaviest_subtree_fork_choice.mark_fork_invalid_candidate(&invalid_descendant_key);
3645        for slot_hash_key in heaviest_subtree_fork_choice.fork_infos.keys() {
3646            let slot = slot_hash_key.0;
3647            if slot <= duplicate_confirmed_slot {
3648                // All ancestors of the duplicate confirmed slot should:
3649                // 1) Be duplicate confirmed
3650                // 2) Have no invalid ancestors
3651                assert!(heaviest_subtree_fork_choice
3652                    .is_duplicate_confirmed(slot_hash_key)
3653                    .unwrap());
3654                assert!(heaviest_subtree_fork_choice
3655                    .latest_invalid_ancestor(slot_hash_key)
3656                    .is_none());
3657            } else if slot >= invalid_descendant_slot {
3658                // Anything descended from the invalid slot should:
3659                // 1) Not be duplicate confirmed
3660                // 2) Should have an invalid ancestor == `invalid_descendant_slot`
3661                assert!(!heaviest_subtree_fork_choice
3662                    .is_duplicate_confirmed(slot_hash_key)
3663                    .unwrap());
3664                assert_eq!(
3665                    heaviest_subtree_fork_choice
3666                        .latest_invalid_ancestor(slot_hash_key)
3667                        .unwrap(),
3668                    invalid_descendant_slot
3669                );
3670            } else {
3671                // Anything in between the duplicate confirmed slot and the invalid slot should:
3672                // 1) Not be duplicate confirmed
3673                // 2) Should not have an invalid ancestor
3674                assert!(!heaviest_subtree_fork_choice
3675                    .is_duplicate_confirmed(slot_hash_key)
3676                    .unwrap());
3677                assert!(heaviest_subtree_fork_choice
3678                    .latest_invalid_ancestor(slot_hash_key)
3679                    .is_none());
3680            }
3681        }
3682
3683        // Mark later descendant `d` duplicate confirmed where `duplicate_confirmed_slot < d < invalid_descendant_slot`.
3684        let later_duplicate_confirmed_slot = 4;
3685        assert!(
3686            later_duplicate_confirmed_slot > duplicate_confirmed_slot
3687                && later_duplicate_confirmed_slot < invalid_descendant_slot
3688        );
3689        let later_duplicate_confirmed_key = later_duplicate_confirmed_slot.slot_hash();
3690        heaviest_subtree_fork_choice.mark_fork_valid_candidate(&later_duplicate_confirmed_key);
3691
3692        for slot_hash_key in heaviest_subtree_fork_choice.fork_infos.keys() {
3693            let slot = slot_hash_key.0;
3694            if slot <= later_duplicate_confirmed_slot {
3695                // All ancestors of the later_duplicate_confirmed_slot should:
3696                // 1) Be duplicate confirmed
3697                // 2) Have no invalid ancestors
3698                assert!(heaviest_subtree_fork_choice
3699                    .is_duplicate_confirmed(slot_hash_key)
3700                    .unwrap());
3701                assert!(heaviest_subtree_fork_choice
3702                    .latest_invalid_ancestor(slot_hash_key)
3703                    .is_none());
3704            } else if slot >= invalid_descendant_slot {
3705                // Anything descended from the invalid slot should:
3706                // 1) Not be duplicate confirmed
3707                // 2) Should have an invalid ancestor == `invalid_descendant_slot`
3708                assert!(!heaviest_subtree_fork_choice
3709                    .is_duplicate_confirmed(slot_hash_key)
3710                    .unwrap());
3711                assert_eq!(
3712                    heaviest_subtree_fork_choice
3713                        .latest_invalid_ancestor(slot_hash_key)
3714                        .unwrap(),
3715                    invalid_descendant_slot
3716                );
3717            } else {
3718                // Anything in between the duplicate confirmed slot and the invalid slot should:
3719                // 1) Not be duplicate confirmed
3720                // 2) Should not have an invalid ancestor
3721                assert!(!heaviest_subtree_fork_choice
3722                    .is_duplicate_confirmed(slot_hash_key)
3723                    .unwrap());
3724                assert!(heaviest_subtree_fork_choice
3725                    .latest_invalid_ancestor(slot_hash_key)
3726                    .is_none());
3727            }
3728        }
3729
3730        // Mark all slots duplicate confirmed
3731        let last_duplicate_confirmed_slot = 6;
3732        let last_duplicate_confirmed_key = last_duplicate_confirmed_slot.slot_hash();
3733        heaviest_subtree_fork_choice.mark_fork_valid_candidate(&last_duplicate_confirmed_key);
3734        for slot_hash_key in heaviest_subtree_fork_choice.fork_infos.keys() {
3735            assert!(heaviest_subtree_fork_choice
3736                .is_duplicate_confirmed(slot_hash_key)
3737                .unwrap());
3738            assert!(heaviest_subtree_fork_choice
3739                .latest_invalid_ancestor(slot_hash_key)
3740                .is_none());
3741        }
3742    }
3743
3744    #[test]
3745    #[should_panic]
3746    fn test_mark_valid_then_ancestor_invalid() {
3747        let forks = tr(0) / (tr(1) / (tr(2) / (tr(3) / (tr(4) / (tr(5) / tr(6))))));
3748        let mut heaviest_subtree_fork_choice = HeaviestSubtreeForkChoice::new_from_tree(forks);
3749        let duplicate_confirmed_slot: Slot = 4;
3750        let duplicate_confirmed_key = duplicate_confirmed_slot.slot_hash();
3751        heaviest_subtree_fork_choice.mark_fork_valid_candidate(&duplicate_confirmed_key);
3752
3753        // Now mark an ancestor of this fork invalid, should panic since this ancestor
3754        // was duplicate confirmed by its descendant 4 already
3755        heaviest_subtree_fork_choice.mark_fork_invalid_candidate(&3.slot_hash());
3756    }
3757
3758    fn setup_set_unconfirmed_and_confirmed_duplicate_slot_tests(
3759        smaller_duplicate_slot: Slot,
3760        larger_duplicate_slot: Slot,
3761    ) -> HeaviestSubtreeForkChoice {
3762        // Create simple fork 0 -> 1 -> 2 -> 3 -> 4 -> 5
3763        let forks = tr(0) / (tr(1) / (tr(2) / (tr(3) / (tr(4) / tr(5)))));
3764        let mut heaviest_subtree_fork_choice = HeaviestSubtreeForkChoice::new_from_tree(forks);
3765
3766        // Mark the slots as unconfirmed duplicates
3767        heaviest_subtree_fork_choice
3768            .mark_fork_invalid_candidate(&smaller_duplicate_slot.slot_hash());
3769        heaviest_subtree_fork_choice
3770            .mark_fork_invalid_candidate(&larger_duplicate_slot.slot_hash());
3771
3772        // Correctness checks
3773        for slot_hash_key in heaviest_subtree_fork_choice.fork_infos.keys() {
3774            let slot = slot_hash_key.0;
3775            if slot < smaller_duplicate_slot {
3776                assert!(heaviest_subtree_fork_choice
3777                    .latest_invalid_ancestor(slot_hash_key)
3778                    .is_none());
3779            } else if slot < larger_duplicate_slot {
3780                assert_eq!(
3781                    heaviest_subtree_fork_choice
3782                        .latest_invalid_ancestor(slot_hash_key)
3783                        .unwrap(),
3784                    smaller_duplicate_slot
3785                );
3786            } else {
3787                assert_eq!(
3788                    heaviest_subtree_fork_choice
3789                        .latest_invalid_ancestor(slot_hash_key)
3790                        .unwrap(),
3791                    larger_duplicate_slot
3792                );
3793            }
3794        }
3795
3796        heaviest_subtree_fork_choice
3797    }
3798
3799    #[test]
3800    fn test_set_unconfirmed_duplicate_confirm_smaller_slot_first() {
3801        let smaller_duplicate_slot = 1;
3802        let larger_duplicate_slot = 4;
3803        let mut heaviest_subtree_fork_choice =
3804            setup_set_unconfirmed_and_confirmed_duplicate_slot_tests(
3805                smaller_duplicate_slot,
3806                larger_duplicate_slot,
3807            );
3808
3809        // Mark the smaller duplicate slot as confirmed
3810        heaviest_subtree_fork_choice.mark_fork_valid_candidate(&smaller_duplicate_slot.slot_hash());
3811        for slot_hash_key in heaviest_subtree_fork_choice.fork_infos.keys() {
3812            let slot = slot_hash_key.0;
3813            if slot < larger_duplicate_slot {
3814                // Only slots <= smaller_duplicate_slot have been duplicate confirmed
3815                if slot <= smaller_duplicate_slot {
3816                    assert!(heaviest_subtree_fork_choice
3817                        .is_duplicate_confirmed(slot_hash_key)
3818                        .unwrap());
3819                } else {
3820                    assert!(!heaviest_subtree_fork_choice
3821                        .is_duplicate_confirmed(slot_hash_key)
3822                        .unwrap());
3823                }
3824                // The unconfirmed duplicate flag has been cleared on the smaller
3825                // descendants because their most recent duplicate ancestor has
3826                // been confirmed
3827                assert!(heaviest_subtree_fork_choice
3828                    .latest_invalid_ancestor(slot_hash_key)
3829                    .is_none());
3830            } else {
3831                assert!(!heaviest_subtree_fork_choice
3832                    .is_duplicate_confirmed(slot_hash_key)
3833                    .unwrap(),);
3834                // The unconfirmed duplicate flag has not been cleared on the smaller
3835                // descendants because their most recent duplicate ancestor,
3836                // `larger_duplicate_slot` has  not yet been confirmed
3837                assert_eq!(
3838                    heaviest_subtree_fork_choice
3839                        .latest_invalid_ancestor(slot_hash_key)
3840                        .unwrap(),
3841                    larger_duplicate_slot
3842                );
3843            }
3844        }
3845
3846        // Mark the larger duplicate slot as confirmed, all slots should no longer
3847        // have any unconfirmed duplicate ancestors, and should be marked as duplicate confirmed
3848        heaviest_subtree_fork_choice.mark_fork_valid_candidate(&larger_duplicate_slot.slot_hash());
3849        for slot_hash_key in heaviest_subtree_fork_choice.fork_infos.keys() {
3850            let slot = slot_hash_key.0;
3851            // All slots <= the latest duplicate confirmed slot are ancestors of
3852            // that slot, so they should all be marked duplicate confirmed
3853            assert_eq!(
3854                heaviest_subtree_fork_choice
3855                    .is_duplicate_confirmed(slot_hash_key)
3856                    .unwrap(),
3857                slot <= larger_duplicate_slot
3858            );
3859            assert!(heaviest_subtree_fork_choice
3860                .latest_invalid_ancestor(slot_hash_key)
3861                .is_none());
3862        }
3863    }
3864
3865    #[test]
3866    fn test_set_unconfirmed_duplicate_confirm_larger_slot_first() {
3867        let smaller_duplicate_slot = 1;
3868        let larger_duplicate_slot = 4;
3869        let mut heaviest_subtree_fork_choice =
3870            setup_set_unconfirmed_and_confirmed_duplicate_slot_tests(
3871                smaller_duplicate_slot,
3872                larger_duplicate_slot,
3873            );
3874
3875        // Mark the larger duplicate slot as confirmed
3876        heaviest_subtree_fork_choice.mark_fork_valid_candidate(&larger_duplicate_slot.slot_hash());
3877
3878        // All slots should no longer have any unconfirmed duplicate ancestors
3879        heaviest_subtree_fork_choice.mark_fork_valid_candidate(&smaller_duplicate_slot.slot_hash());
3880        for slot_hash_key in heaviest_subtree_fork_choice.fork_infos.keys() {
3881            let slot = slot_hash_key.0;
3882            // All slots <= the latest duplicate confirmed slot are ancestors of
3883            // that slot, so they should all be marked duplicate confirmed
3884            assert_eq!(
3885                heaviest_subtree_fork_choice
3886                    .is_duplicate_confirmed(slot_hash_key)
3887                    .unwrap(),
3888                slot <= larger_duplicate_slot
3889            );
3890            assert!(heaviest_subtree_fork_choice
3891                .latest_invalid_ancestor(slot_hash_key)
3892                .is_none());
3893        }
3894    }
3895
3896    #[test]
3897    fn test_split_off_simple() {
3898        let mut heaviest_subtree_fork_choice = setup_forks();
3899        let stake = 100;
3900        let (bank, vote_pubkeys) = bank_utils::setup_bank_and_vote_pubkeys_for_tests(4, stake);
3901
3902        let pubkey_votes: Vec<(Pubkey, SlotHashKey)> = vec![
3903            (vote_pubkeys[0], (3, Hash::default())),
3904            (vote_pubkeys[1], (2, Hash::default())),
3905            (vote_pubkeys[2], (6, Hash::default())),
3906            (vote_pubkeys[3], (4, Hash::default())),
3907        ];
3908
3909        heaviest_subtree_fork_choice.add_votes(
3910            pubkey_votes.iter(),
3911            bank.epoch_stakes_map(),
3912            bank.epoch_schedule(),
3913        );
3914        let tree = heaviest_subtree_fork_choice.split_off(&(5, Hash::default()));
3915
3916        assert_eq!(
3917            3 * stake,
3918            heaviest_subtree_fork_choice
3919                .stake_voted_subtree(&(0, Hash::default()))
3920                .unwrap()
3921        );
3922        assert_eq!(
3923            2 * stake,
3924            heaviest_subtree_fork_choice
3925                .stake_voted_subtree(&(2, Hash::default()))
3926                .unwrap()
3927        );
3928        assert_eq!(
3929            stake,
3930            heaviest_subtree_fork_choice
3931                .stake_voted_subtree(&(3, Hash::default()))
3932                .unwrap()
3933        );
3934        assert_eq!(
3935            None,
3936            heaviest_subtree_fork_choice.stake_voted_subtree(&(5, Hash::default()))
3937        );
3938        assert_eq!(
3939            None,
3940            heaviest_subtree_fork_choice.stake_voted_subtree(&(6, Hash::default()))
3941        );
3942        assert_eq!(
3943            stake,
3944            tree.stake_voted_subtree(&(5, Hash::default())).unwrap()
3945        );
3946        assert_eq!(
3947            stake,
3948            tree.stake_voted_subtree(&(6, Hash::default())).unwrap()
3949        );
3950
3951        assert!(tree
3952            .fork_infos
3953            .get(&tree.tree_root)
3954            .unwrap()
3955            .parent
3956            .is_none());
3957    }
3958
3959    #[test]
3960    fn test_split_off_unvoted() {
3961        let mut heaviest_subtree_fork_choice = setup_forks();
3962        let stake = 100;
3963        let (bank, vote_pubkeys) = bank_utils::setup_bank_and_vote_pubkeys_for_tests(4, stake);
3964
3965        let pubkey_votes: Vec<(Pubkey, SlotHashKey)> = vec![
3966            (vote_pubkeys[0], (3, Hash::default())),
3967            (vote_pubkeys[1], (5, Hash::default())),
3968            (vote_pubkeys[2], (6, Hash::default())),
3969            (vote_pubkeys[3], (1, Hash::default())),
3970        ];
3971
3972        heaviest_subtree_fork_choice.add_votes(
3973            pubkey_votes.iter(),
3974            bank.epoch_stakes_map(),
3975            bank.epoch_schedule(),
3976        );
3977        let tree = heaviest_subtree_fork_choice.split_off(&(2, Hash::default()));
3978
3979        assert_eq!(
3980            4 * stake,
3981            heaviest_subtree_fork_choice
3982                .stake_voted_subtree(&(0, Hash::default()))
3983                .unwrap()
3984        );
3985        assert_eq!(
3986            3 * stake,
3987            heaviest_subtree_fork_choice
3988                .stake_voted_subtree(&(3, Hash::default()))
3989                .unwrap()
3990        );
3991        assert_eq!(
3992            None,
3993            heaviest_subtree_fork_choice.stake_voted_subtree(&(2, Hash::default()))
3994        );
3995        assert_eq!(
3996            None,
3997            heaviest_subtree_fork_choice.stake_voted_subtree(&(4, Hash::default()))
3998        );
3999        assert_eq!(0, tree.stake_voted_subtree(&(2, Hash::default())).unwrap());
4000        assert_eq!(0, tree.stake_voted_subtree(&(4, Hash::default())).unwrap());
4001    }
4002
4003    #[test]
4004    fn test_split_off_on_best_path() {
4005        let mut heaviest_subtree_fork_choice = setup_forks();
4006        let stake = 100;
4007        let (bank, vote_pubkeys) = bank_utils::setup_bank_and_vote_pubkeys_for_tests(4, stake);
4008
4009        let pubkey_votes: Vec<(Pubkey, SlotHashKey)> = vec![
4010            (vote_pubkeys[0], (2, Hash::default())),
4011            (vote_pubkeys[1], (3, Hash::default())),
4012            (vote_pubkeys[2], (5, Hash::default())),
4013            (vote_pubkeys[3], (6, Hash::default())),
4014        ];
4015
4016        heaviest_subtree_fork_choice.add_votes(
4017            pubkey_votes.iter(),
4018            bank.epoch_stakes_map(),
4019            bank.epoch_schedule(),
4020        );
4021
4022        assert_eq!(6, heaviest_subtree_fork_choice.best_overall_slot().0);
4023
4024        let tree = heaviest_subtree_fork_choice.split_off(&(6, Hash::default()));
4025        assert_eq!(5, heaviest_subtree_fork_choice.best_overall_slot().0);
4026        assert_eq!(6, tree.best_overall_slot().0);
4027
4028        let tree = heaviest_subtree_fork_choice.split_off(&(3, Hash::default()));
4029        assert_eq!(4, heaviest_subtree_fork_choice.best_overall_slot().0);
4030        assert_eq!(5, tree.best_overall_slot().0);
4031
4032        let tree = heaviest_subtree_fork_choice.split_off(&(1, Hash::default()));
4033        assert_eq!(0, heaviest_subtree_fork_choice.best_overall_slot().0);
4034        assert_eq!(4, tree.best_overall_slot().0);
4035    }
4036
4037    #[test]
4038    fn test_split_off_on_deepest_path() {
4039        let mut heaviest_subtree_fork_choice = setup_forks();
4040
4041        assert_eq!(6, heaviest_subtree_fork_choice.deepest_overall_slot().0);
4042
4043        let tree = heaviest_subtree_fork_choice.split_off(&(6, Hash::default()));
4044        assert_eq!(4, heaviest_subtree_fork_choice.deepest_overall_slot().0);
4045        assert_eq!(6, tree.deepest_overall_slot().0);
4046
4047        let tree = heaviest_subtree_fork_choice.split_off(&(3, Hash::default()));
4048        assert_eq!(4, heaviest_subtree_fork_choice.deepest_overall_slot().0);
4049        assert_eq!(5, tree.deepest_overall_slot().0);
4050
4051        let tree = heaviest_subtree_fork_choice.split_off(&(1, Hash::default()));
4052        assert_eq!(0, heaviest_subtree_fork_choice.deepest_overall_slot().0);
4053        assert_eq!(4, tree.deepest_overall_slot().0);
4054    }
4055
4056    #[test]
4057    fn test_split_off_on_deepest_path_complicated() {
4058        let mut heaviest_subtree_fork_choice = setup_complicated_forks();
4059        assert_eq!(23, heaviest_subtree_fork_choice.deepest_overall_slot().0);
4060        assert_eq!(
4061            9,
4062            heaviest_subtree_fork_choice
4063                .height(&(0, Hash::default()))
4064                .unwrap()
4065        );
4066        assert_eq!(
4067            3,
4068            heaviest_subtree_fork_choice
4069                .height(&(9, Hash::default()))
4070                .unwrap()
4071        );
4072        assert_eq!(
4073            7,
4074            heaviest_subtree_fork_choice
4075                .height(&(12, Hash::default()))
4076                .unwrap()
4077        );
4078
4079        // Take out the 13 branch, 34 should now be deepest
4080        let tree = heaviest_subtree_fork_choice.split_off(&(13, Hash::default()));
4081        assert_eq!(34, heaviest_subtree_fork_choice.deepest_overall_slot().0);
4082        assert_eq!(
4083            5,
4084            heaviest_subtree_fork_choice
4085                .height(&(0, Hash::default()))
4086                .unwrap()
4087        );
4088        assert_eq!(
4089            3,
4090            heaviest_subtree_fork_choice
4091                .height(&(9, Hash::default()))
4092                .unwrap()
4093        );
4094        assert_eq!(
4095            1,
4096            heaviest_subtree_fork_choice
4097                .height(&(12, Hash::default()))
4098                .unwrap()
4099        );
4100
4101        // New tree should have updated heights but still think 23 is the heaviest
4102        assert_eq!(23, tree.deepest_overall_slot().0);
4103        assert_eq!(6, tree.height(&(13, Hash::default())).unwrap());
4104        assert_eq!(2, tree.height(&(18, Hash::default())).unwrap());
4105        assert_eq!(1, tree.height(&(25, Hash::default())).unwrap());
4106    }
4107
4108    #[test]
4109    fn test_split_off_with_dups() {
4110        let (
4111            mut heaviest_subtree_fork_choice,
4112            duplicate_leaves_descended_from_4,
4113            duplicate_leaves_descended_from_5,
4114            duplicate_leaves_descended_from_6,
4115        ) = setup_duplicate_forks();
4116
4117        let stake = 10;
4118        let num_validators = 3;
4119        let (bank, vote_pubkeys) =
4120            bank_utils::setup_bank_and_vote_pubkeys_for_tests(num_validators, stake);
4121
4122        let pubkey_votes: Vec<(Pubkey, SlotHashKey)> = vec![
4123            (vote_pubkeys[0], duplicate_leaves_descended_from_4[0]),
4124            (vote_pubkeys[1], duplicate_leaves_descended_from_4[1]),
4125            (vote_pubkeys[2], duplicate_leaves_descended_from_5[0]),
4126        ];
4127
4128        // duplicate_leaves_descended_from_4 are sorted, and fork choice will pick the smaller
4129        // one in the event of a tie
4130        let expected_best_slot_hash = duplicate_leaves_descended_from_4[0];
4131        assert_eq!(
4132            heaviest_subtree_fork_choice.add_votes(
4133                pubkey_votes.iter(),
4134                bank.epoch_stakes_map(),
4135                bank.epoch_schedule()
4136            ),
4137            expected_best_slot_hash
4138        );
4139
4140        assert_eq!(
4141            heaviest_subtree_fork_choice.best_overall_slot(),
4142            expected_best_slot_hash
4143        );
4144        let expected_deepest_slot_hash = duplicate_leaves_descended_from_6[0];
4145        assert_eq!(
4146            heaviest_subtree_fork_choice.deepest_overall_slot(),
4147            expected_deepest_slot_hash
4148        );
4149        let tree = heaviest_subtree_fork_choice.split_off(&expected_best_slot_hash);
4150
4151        assert_eq!(
4152            heaviest_subtree_fork_choice.best_overall_slot(),
4153            duplicate_leaves_descended_from_4[1]
4154        );
4155        assert_eq!(
4156            heaviest_subtree_fork_choice.deepest_overall_slot(),
4157            expected_deepest_slot_hash
4158        );
4159        assert_eq!(tree.best_overall_slot(), expected_best_slot_hash);
4160        assert_eq!(tree.deepest_overall_slot(), expected_best_slot_hash);
4161    }
4162
4163    #[test]
4164    fn test_split_off_subtree_with_dups() {
4165        let (
4166            mut heaviest_subtree_fork_choice,
4167            duplicate_leaves_descended_from_4,
4168            duplicate_leaves_descended_from_5,
4169            duplicate_leaves_descended_from_6,
4170        ) = setup_duplicate_forks();
4171
4172        let stake = 10;
4173        let num_validators = 3;
4174        let (bank, vote_pubkeys) =
4175            bank_utils::setup_bank_and_vote_pubkeys_for_tests(num_validators, stake);
4176
4177        let pubkey_votes: Vec<(Pubkey, SlotHashKey)> = vec![
4178            (vote_pubkeys[0], duplicate_leaves_descended_from_4[0]),
4179            (vote_pubkeys[1], duplicate_leaves_descended_from_4[1]),
4180            (vote_pubkeys[2], duplicate_leaves_descended_from_5[0]),
4181        ];
4182
4183        // duplicate_leaves_descended_from_4 are sorted, and fork choice will pick the smaller
4184        // one in the event of a tie
4185        let expected_best_slot_hash = duplicate_leaves_descended_from_4[0];
4186        assert_eq!(
4187            heaviest_subtree_fork_choice.add_votes(
4188                pubkey_votes.iter(),
4189                bank.epoch_stakes_map(),
4190                bank.epoch_schedule()
4191            ),
4192            expected_best_slot_hash
4193        );
4194
4195        assert_eq!(
4196            heaviest_subtree_fork_choice.best_overall_slot(),
4197            expected_best_slot_hash
4198        );
4199        let expected_deepest_slot_hash = duplicate_leaves_descended_from_6[0];
4200        assert_eq!(
4201            heaviest_subtree_fork_choice.deepest_overall_slot(),
4202            expected_deepest_slot_hash
4203        );
4204
4205        let tree = heaviest_subtree_fork_choice.split_off(&(2, Hash::default()));
4206
4207        assert_eq!(
4208            heaviest_subtree_fork_choice.best_overall_slot(),
4209            duplicate_leaves_descended_from_5[0]
4210        );
4211        assert_eq!(
4212            heaviest_subtree_fork_choice.deepest_overall_slot(),
4213            expected_deepest_slot_hash
4214        );
4215
4216        assert_eq!(tree.best_overall_slot(), expected_best_slot_hash);
4217        assert_eq!(tree.deepest_overall_slot(), expected_best_slot_hash,);
4218    }
4219
4220    #[test]
4221    fn test_split_off_complicated() {
4222        let mut heaviest_subtree_fork_choice = setup_complicated_forks();
4223
4224        let split_and_check =
4225            |tree: &mut HeaviestSubtreeForkChoice, node: Slot, nodes_to_check: Vec<Slot>| {
4226                for &n in nodes_to_check.iter() {
4227                    assert!(tree.contains_block(&(n, Hash::default())));
4228                }
4229                let split_tree = tree.split_off(&(node, Hash::default()));
4230                for &n in nodes_to_check.iter() {
4231                    assert!(!tree.contains_block(&(n, Hash::default())));
4232                    assert!(split_tree.contains_block(&(n, Hash::default())));
4233                }
4234            };
4235
4236        split_and_check(
4237            &mut heaviest_subtree_fork_choice,
4238            14,
4239            vec![14, 15, 16, 22, 23, 17, 21, 18, 19, 20, 24, 25],
4240        );
4241        split_and_check(&mut heaviest_subtree_fork_choice, 12, vec![12, 13]);
4242        split_and_check(
4243            &mut heaviest_subtree_fork_choice,
4244            2,
4245            vec![2, 7, 8, 9, 33, 34, 10, 31, 32],
4246        );
4247        split_and_check(&mut heaviest_subtree_fork_choice, 1, vec![1, 5, 6]);
4248    }
4249
4250    #[test]
4251    fn test_purge_prune() {
4252        let mut heaviest_subtree_fork_choice = setup_forks();
4253        assert_eq!(heaviest_subtree_fork_choice.tree_root().0, 0);
4254
4255        // Same root, no-op
4256        let (purged, pruned) = heaviest_subtree_fork_choice.purge_prune((0, Hash::default()));
4257        assert!(purged.is_empty());
4258        assert!(pruned.is_empty());
4259        assert_eq!(heaviest_subtree_fork_choice.tree_root().0, 0);
4260
4261        // Root update, purge no prune
4262        let (mut purged, pruned) = heaviest_subtree_fork_choice.purge_prune((1, Hash::default()));
4263        purged.sort();
4264        assert_eq!(purged, vec![(0, Hash::default())]);
4265        assert!(pruned.is_empty());
4266        assert_eq!(heaviest_subtree_fork_choice.tree_root().0, 1);
4267
4268        // Root update, purge, prune
4269        let (mut purged, pruned) = heaviest_subtree_fork_choice.purge_prune((3, Hash::default()));
4270        purged.sort();
4271        assert_eq!(purged, vec![(1, Hash::default()), (2, Hash::default())]);
4272        assert_eq!(
4273            pruned,
4274            vec![HeaviestSubtreeForkChoice::new_from_tree(tr(4))]
4275        );
4276        assert_eq!(heaviest_subtree_fork_choice.tree_root().0, 3);
4277
4278        // Root doesn't exist (same fork structure w/o 3)
4279        let forks = tr(0) / (tr(1) / (tr(2) / (tr(4))) / (tr(5) / (tr(6))));
4280        heaviest_subtree_fork_choice = HeaviestSubtreeForkChoice::new_from_tree(forks);
4281        let (mut purged, mut pruned) =
4282            heaviest_subtree_fork_choice.purge_prune((3, Hash::default()));
4283        purged.sort();
4284        pruned.sort();
4285        assert_eq!(
4286            purged,
4287            vec![
4288                (0, Hash::default()),
4289                (1, Hash::default()),
4290                (2, Hash::default())
4291            ]
4292        );
4293        assert_eq!(
4294            pruned,
4295            vec![
4296                HeaviestSubtreeForkChoice::new_from_tree(tr(4)),
4297                HeaviestSubtreeForkChoice::new_from_tree(tr(5) / tr(6))
4298            ]
4299        );
4300        assert!(heaviest_subtree_fork_choice.fork_infos.is_empty());
4301    }
4302
4303    #[test]
4304    fn test_purge_prune_complicated() {
4305        let mut heaviest_subtree_fork_choice = setup_complicated_forks();
4306        assert_eq!(heaviest_subtree_fork_choice.tree_root().0, 0);
4307
4308        let expected_pruned = [
4309            tr(5),
4310            tr(6),
4311            tr(7),
4312            tr(8),
4313            tr(9) / (tr(33) / tr(34)),
4314            tr(10),
4315            tr(31) / tr(32),
4316        ];
4317        let expected_purged = [0, 1, 2];
4318        let expected_tree = heaviest_subtree_fork_choice
4319            .clone()
4320            .split_off(&(3, Hash::default()));
4321        let (mut purged, mut pruned) =
4322            heaviest_subtree_fork_choice.purge_prune((3, Hash::default()));
4323        purged.sort();
4324        pruned.sort();
4325        assert_eq!(
4326            purged,
4327            expected_purged
4328                .into_iter()
4329                .map(|s| (s, Hash::default()))
4330                .collect_vec()
4331        );
4332        assert_eq!(
4333            pruned,
4334            expected_pruned
4335                .into_iter()
4336                .map(HeaviestSubtreeForkChoice::new_from_tree)
4337                .collect_vec()
4338        );
4339        assert_eq!(heaviest_subtree_fork_choice, expected_tree);
4340
4341        let expected_pruned = [
4342            tr(17) / tr(21),
4343            tr(18) / tr(19) / tr(20),
4344            tr(24),
4345            tr(25),
4346            tr(26),
4347        ];
4348        let expected_purged = [3, 11, 12, 13, 14, 15];
4349        let expected_tree = heaviest_subtree_fork_choice
4350            .clone()
4351            .split_off(&(16, Hash::default()));
4352        let (mut purged, mut pruned) =
4353            heaviest_subtree_fork_choice.purge_prune((16, Hash::default()));
4354        purged.sort();
4355        pruned.sort();
4356        assert_eq!(
4357            purged,
4358            expected_purged
4359                .into_iter()
4360                .map(|s| (s, Hash::default()))
4361                .collect_vec()
4362        );
4363        assert_eq!(
4364            pruned,
4365            expected_pruned
4366                .into_iter()
4367                .map(HeaviestSubtreeForkChoice::new_from_tree)
4368                .collect_vec()
4369        );
4370        assert_eq!(heaviest_subtree_fork_choice, expected_tree);
4371    }
4372
4373    fn setup_forks() -> HeaviestSubtreeForkChoice {
4374        /*
4375            Build fork structure:
4376                 slot 0
4377                   |
4378                 slot 1
4379                 /    \
4380            slot 2    |
4381               |    slot 3
4382            slot 4    |
4383                    slot 5
4384                      |
4385                    slot 6
4386        */
4387        let forks = tr(0) / (tr(1) / (tr(2) / (tr(4))) / (tr(3) / (tr(5) / (tr(6)))));
4388        HeaviestSubtreeForkChoice::new_from_tree(forks)
4389    }
4390
4391    fn setup_complicated_forks() -> HeaviestSubtreeForkChoice {
4392        /*
4393            Build a complicated fork structure:
4394
4395                slot 0
4396                ├── slot 1
4397                │   ├── slot 5
4398                │   └── slot 6
4399                ├── slot 2
4400                │   ├── slot 7
4401                │   ├── slot 8
4402                │   ├── slot 9
4403                │   │   └── slot 33
4404                │   │       └── slot 34
4405                │   ├── slot 10
4406                │   └── slot 31
4407                │       └── slot 32
4408                └── slot 3
4409                    ├── slot 11
4410                    ├── slot 12
4411                    │   └── slot 13
4412                    │       └── slot 14
4413                    │           ├── slot 15
4414                    │           │   ├── slot 16
4415                    │           │   │   └── slot 22
4416                    │           │   │       └── slot 23
4417                    │           │   ├── slot 17
4418                    │           │   │   └── slot 21
4419                    │           │   ├── slot 18
4420                    │           │   │   ├── slot 19
4421                    │           │   │   └── slot 20
4422                    │           │   └── slot 24
4423                    │           └── slot 25
4424                    └── slot 26
4425
4426        */
4427        let tree_12 = tr(12)
4428            / (tr(13)
4429                / (tr(14)
4430                    / (tr(15)
4431                        / (tr(16) / (tr(22) / tr(23)))
4432                        / (tr(17) / tr(21))
4433                        / (tr(18) / tr(19) / tr(20))
4434                        / tr(24))
4435                    / tr(25)));
4436        let forks = tr(0)
4437            / (tr(1) / tr(5) / tr(6))
4438            / (tr(2) / tr(7) / tr(8) / (tr(9) / (tr(33) / tr(34))) / tr(10) / (tr(31) / tr(32)))
4439            / (tr(3) / tr(11) / tree_12 / tr(26));
4440        HeaviestSubtreeForkChoice::new_from_tree(forks)
4441    }
4442
4443    fn setup_duplicate_forks() -> (
4444        HeaviestSubtreeForkChoice,
4445        Vec<SlotHashKey>,
4446        Vec<SlotHashKey>,
4447        Vec<SlotHashKey>,
4448    ) {
4449        /*
4450                Build fork structure:
4451                     slot 0
4452                       |
4453                     slot 1
4454                     /       \
4455                slot 2        |
4456                   |          slot 3
4457                slot 4               \
4458                /    \                slot 5
4459        slot 10      slot 10        /     |     \
4460                             slot 6   slot 10   slot 10
4461                            /      \
4462                       slot 10   slot 10
4463            */
4464
4465        let mut heaviest_subtree_fork_choice = setup_forks();
4466        let duplicate_slot = 10;
4467        let mut duplicate_leaves_descended_from_4 =
4468            std::iter::repeat_with(|| (duplicate_slot, Hash::new_unique()))
4469                .take(2)
4470                .collect::<Vec<_>>();
4471        let mut duplicate_leaves_descended_from_5 =
4472            std::iter::repeat_with(|| (duplicate_slot, Hash::new_unique()))
4473                .take(2)
4474                .collect::<Vec<_>>();
4475        let mut duplicate_leaves_descended_from_6 =
4476            std::iter::repeat_with(|| (duplicate_slot, Hash::new_unique()))
4477                .take(2)
4478                .collect::<Vec<_>>();
4479        duplicate_leaves_descended_from_4.sort();
4480        duplicate_leaves_descended_from_5.sort();
4481        duplicate_leaves_descended_from_6.sort();
4482
4483        // Add versions of leaf 10, some with different ancestors, some with the same
4484        // ancestors
4485        for duplicate_leaf in &duplicate_leaves_descended_from_4 {
4486            heaviest_subtree_fork_choice
4487                .add_new_leaf_slot(*duplicate_leaf, Some((4, Hash::default())));
4488        }
4489        for duplicate_leaf in &duplicate_leaves_descended_from_5 {
4490            heaviest_subtree_fork_choice
4491                .add_new_leaf_slot(*duplicate_leaf, Some((5, Hash::default())));
4492        }
4493        for duplicate_leaf in &duplicate_leaves_descended_from_6 {
4494            heaviest_subtree_fork_choice
4495                .add_new_leaf_slot(*duplicate_leaf, Some((6, Hash::default())));
4496        }
4497
4498        let mut dup_children = (&heaviest_subtree_fork_choice)
4499            .children(&(4, Hash::default()))
4500            .unwrap()
4501            .copied()
4502            .collect_vec();
4503        dup_children.sort();
4504        assert_eq!(dup_children, duplicate_leaves_descended_from_4);
4505        let mut dup_children: Vec<_> = (&heaviest_subtree_fork_choice)
4506            .children(&(5, Hash::default()))
4507            .unwrap()
4508            .copied()
4509            .filter(|(slot, _)| *slot == duplicate_slot)
4510            .collect();
4511        dup_children.sort();
4512        assert_eq!(dup_children, duplicate_leaves_descended_from_5);
4513        let mut dup_children: Vec<_> = (&heaviest_subtree_fork_choice)
4514            .children(&(6, Hash::default()))
4515            .unwrap()
4516            .copied()
4517            .filter(|(slot, _)| *slot == duplicate_slot)
4518            .collect();
4519        dup_children.sort();
4520        assert_eq!(dup_children, duplicate_leaves_descended_from_6);
4521
4522        (
4523            heaviest_subtree_fork_choice,
4524            duplicate_leaves_descended_from_4,
4525            duplicate_leaves_descended_from_5,
4526            duplicate_leaves_descended_from_6,
4527        )
4528    }
4529
4530    fn check_process_update_correctness<F, G>(
4531        heaviest_subtree_fork_choice: &mut HeaviestSubtreeForkChoice,
4532        pubkey_votes: &[(Pubkey, SlotHashKey)],
4533        slots_range: Range<Slot>,
4534        bank: &Bank,
4535        stake: u64,
4536        mut expected_best_slot: F,
4537        mut expected_deepest_slot: G,
4538    ) where
4539        F: FnMut(Slot, &HeaviestSubtreeForkChoice) -> Slot,
4540        G: FnMut(Slot, &HeaviestSubtreeForkChoice) -> Slot,
4541    {
4542        let unique_votes: HashSet<Slot> = pubkey_votes.iter().map(|(_, (slot, _))| *slot).collect();
4543        let vote_ancestors: HashMap<Slot, HashSet<SlotHashKey>> = unique_votes
4544            .iter()
4545            .map(|v| {
4546                (
4547                    *v,
4548                    heaviest_subtree_fork_choice
4549                        .ancestor_iterator((*v, Hash::default()))
4550                        .collect(),
4551                )
4552            })
4553            .collect();
4554        let mut vote_count: HashMap<Slot, usize> = HashMap::new();
4555        for (_, vote) in pubkey_votes {
4556            vote_count
4557                .entry(vote.0)
4558                .and_modify(|c| *c += 1)
4559                .or_insert(1);
4560        }
4561
4562        // Maps a slot to the number of descendants of that slot
4563        // that have been voted on
4564        let num_voted_descendants: HashMap<Slot, usize> = slots_range
4565            .clone()
4566            .map(|slot| {
4567                let num_voted_descendants = vote_ancestors
4568                    .iter()
4569                    .map(|(vote_slot, ancestors)| {
4570                        (ancestors.contains(&(slot, Hash::default())) || *vote_slot == slot)
4571                            as usize
4572                            * vote_count.get(vote_slot).unwrap()
4573                    })
4574                    .sum();
4575                (slot, num_voted_descendants)
4576            })
4577            .collect();
4578
4579        let update_operations_batch = heaviest_subtree_fork_choice.generate_update_operations(
4580            pubkey_votes.iter(),
4581            bank.epoch_stakes_map(),
4582            bank.epoch_schedule(),
4583        );
4584
4585        heaviest_subtree_fork_choice.process_update_operations(update_operations_batch);
4586        for slot in slots_range {
4587            let expected_stake_voted_at =
4588                vote_count.get(&slot).cloned().unwrap_or(0) as u64 * stake;
4589            let expected_stake_voted_subtree =
4590                *num_voted_descendants.get(&slot).unwrap() as u64 * stake;
4591            assert_eq!(
4592                expected_stake_voted_at,
4593                heaviest_subtree_fork_choice
4594                    .stake_voted_at(&(slot, Hash::default()))
4595                    .unwrap()
4596            );
4597            assert_eq!(
4598                expected_stake_voted_subtree,
4599                heaviest_subtree_fork_choice
4600                    .stake_voted_subtree(&(slot, Hash::default()))
4601                    .unwrap()
4602            );
4603            assert_eq!(
4604                expected_best_slot(slot, heaviest_subtree_fork_choice),
4605                heaviest_subtree_fork_choice
4606                    .best_slot(&(slot, Hash::default()))
4607                    .unwrap()
4608                    .0
4609            );
4610            assert_eq!(
4611                expected_deepest_slot(slot, heaviest_subtree_fork_choice),
4612                heaviest_subtree_fork_choice
4613                    .deepest_slot(&(slot, Hash::default()))
4614                    .unwrap()
4615                    .0
4616            );
4617        }
4618    }
4619}