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 MarkValid(Slot),
42 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 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 stake_voted_at: ForkWeight,
93 stake_voted_subtree: ForkWeight,
96 height: usize,
98 best_slot: SlotHashKey,
102 deepest_slot: SlotHashKey,
106 parent: Option<SlotHashKey>,
107 children: BTreeSet<SlotHashKey>,
108 latest_invalid_ancestor: Option<Slot>,
111 is_duplicate_confirmed: bool,
113}
114
115impl ForkInfo {
116 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 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 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 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 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 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 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 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 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 pub fn add_votes<'a, 'b>(
344 &'a mut self,
345 pubkey_votes: impl Iterator<Item = impl Borrow<(Pubkey, SlotHashKey)> + 'b>,
347 epoch_stakes: &HashMap<Epoch, VersionedEpochStakes>,
348 epoch_schedule: &EpochSchedule,
349 ) -> SlotHashKey {
350 let update_operations_batch =
352 self.generate_update_operations(pubkey_votes, epoch_stakes, epoch_schedule);
353
354 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 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 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 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 purged_slots.push(cur_slot);
404 } else {
405 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 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 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 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 is_duplicate_confirmed: parent.is_none(),
482 });
483
484 if parent.is_none() {
485 return;
486 }
487
488 let parent = parent.unwrap();
489
490 self.fork_infos
492 .get_mut(&parent)
493 .unwrap()
494 .children
495 .insert(slot_hash_key);
496
497 self.propagate_new_leaf(&slot_hash_key, &parent);
500 }
501
502 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 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 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 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 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 (Ordering::Equal, Ordering::Greater, _) => return false,
557 (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 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 self.insert_aggregate_operations(&mut update_operations, *slot_hash_key);
599 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 self.process_update_operations(update_operations);
608
609 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(¤t_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 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 split_tree_root.parent = None;
632 split_tree_fork_infos.insert(*slot_hash_key, split_tree_root);
633
634 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 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 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 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 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 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 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 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 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 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(¤t_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 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 stake_voted_subtree += child_stake_voted_subtree;
896
897 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 (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 (true, _, _, _) |
918 (_, Ordering::Greater, _, _) |
920 (_, Ordering::Equal, Ordering::Greater, _) |
922 (_, 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 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 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 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 continue;
995 }
996
997 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 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 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 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 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 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 self.deepest_slot(&last_voted_slot_hash)
1185 }
1186 None => {
1187 if !tower.is_stray_last_vote() {
1188 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 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 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 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 (
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 None
1308 } else {
1309 Some(bank)
1310 }
1311 } else {
1312 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 assert!(!fork_info.is_duplicate_confirmed);
1336 let mut update_operations = UpdateOperations::default();
1337
1338 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 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 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 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 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 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 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 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 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 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 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 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 heaviest_subtree_fork_choice.set_tree_root((1, Hash::default()));
1723
1724 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 heaviest_subtree_fork_choice.set_tree_root((3, Hash::default()));
1756 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 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 heaviest_subtree_fork_choice.set_tree_root((1, Hash::default()));
1778
1779 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 heaviest_subtree_fork_choice.set_tree_root((2, Hash::default()));
1803 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 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 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 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 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 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 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 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 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 let stake = 100;
1950 let (bank, vote_pubkeys) = bank_utils::setup_bank_and_vote_pubkeys_for_tests(2, stake);
1951 let leaf6 = 6;
1952 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 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 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 assert_eq!(heaviest_subtree_fork_choice.deepest_overall_slot().0, 8);
1992
1993 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 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 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 assert_eq!(heaviest_subtree_fork_choice.best_overall_slot().0, 6);
2042
2043 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 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 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 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 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 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 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 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 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 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 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 for slot in &[0, 1] {
2181 assert_eq!(
2184 heaviest_subtree_fork_choice
2185 .stake_voted_subtree(&(*slot, Hash::default()))
2186 .unwrap(),
2187 total_stake
2188 );
2189 }
2190 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 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 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 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 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 (
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 (
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 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 let pubkey_votes: Vec<(Pubkey, SlotHashKey)> = vec![
2366 (vote_pubkeys[0], (3, Hash::default())),
2368 (vote_pubkeys[1], (5, Hash::default())),
2370 (vote_pubkeys[2], (3, Hash::default())),
2372 ];
2373
2374 let expected_update_operations: BTreeMap<(SlotHashKey, UpdateLabel), UpdateOperation> =
2375 vec![
2376 (
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 (
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 let pubkey_votes: Vec<(Pubkey, SlotHashKey)> = vec![
2423 (vote_pubkeys[0], (4, Hash::default())),
2425 (vote_pubkeys[1], (6, Hash::default())),
2427 (vote_pubkeys[2], (6, Hash::default())),
2429 ];
2430
2431 let expected_update_operations: BTreeMap<(SlotHashKey, UpdateLabel), UpdateOperation> =
2432 vec![
2433 (
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 (
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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 assert_eq!(
2841 heaviest_subtree_fork_choice.best_overall_slot(),
2842 duplicate_leaves_descended_from_4[0]
2843 );
2844 let duplicate_parent = duplicate_leaves_descended_from_4[0];
2846 let duplicate_slot = duplicate_parent.0;
2847
2848 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 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 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 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 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 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 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 let pubkey_votes: Vec<(Pubkey, SlotHashKey)> =
2961 vec![(vote_pubkeys[0], duplicate_leaves_descended_from_4[1])];
2962
2963 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 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 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 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 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 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 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 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 (vote_pubkeys[0], (16, Hash::default())),
3091 (vote_pubkeys[1], (19, Hash::default())),
3093 (vote_pubkeys[2], (10, Hash::default())),
3095 (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 tree1.merge(
3106 tree2,
3107 &(7, Hash::default()),
3108 bank.epoch_stakes_map(),
3109 bank.epoch_schedule(),
3110 );
3111
3112 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 assert_eq!(tree1.stake_voted_at(&(16, Hash::default())).unwrap(), stake);
3133 assert_eq!(tree1.stake_voted_at(&(5, Hash::default())).unwrap(), 0);
3134 assert_eq!(tree1.stake_voted_at(&(19, Hash::default())).unwrap(), stake);
3136 assert_eq!(tree1.stake_voted_at(&(3, Hash::default())).unwrap(), 0);
3137 assert_eq!(tree1.stake_voted_at(&(10, Hash::default())).unwrap(), 0);
3139 assert_eq!(tree1.stake_voted_at(&(12, Hash::default())).unwrap(), stake);
3140 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 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 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 (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 tree1.merge(
3238 tree2,
3239 &(2, Hash::default()),
3240 bank.epoch_stakes_map(),
3241 bank.epoch_schedule(),
3242 );
3243
3244 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 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 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 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 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 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 heaviest_subtree_fork_choice.set_tree_root((1, Hash::default()));
3324
3325 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 let mut slot_history = SlotHistory::default();
3347 slot_history.add(0);
3348 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 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 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 assert_eq!(
3405 heaviest_subtree_fork_choice
3406 .heaviest_slot_on_same_voted_fork(&tower)
3407 .unwrap(),
3408 (6, Hash::default())
3409 );
3410
3411 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 assert!(heaviest_subtree_fork_choice
3420 .is_candidate(&(3, Hash::default()))
3421 .unwrap());
3422
3423 assert_eq!(heaviest_subtree_fork_choice.best_overall_slot().0, 3);
3425
3426 assert_eq!(
3429 heaviest_subtree_fork_choice.heaviest_slot_on_same_voted_fork(&tower),
3430 Some((6, Hash::default()))
3431 );
3432
3433 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 assert_eq!(
3455 heaviest_subtree_fork_choice
3456 .heaviest_slot_on_same_voted_fork(&tower)
3457 .unwrap(),
3458 new_leaf7,
3459 );
3460
3461 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 assert_eq!(
3470 heaviest_subtree_fork_choice
3471 .heaviest_slot_on_same_voted_fork(&tower)
3472 .unwrap(),
3473 new_leaf7
3474 );
3475
3476 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 new_leaf7
3487 );
3488 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 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 assert_eq!(
3529 heaviest_subtree_fork_choice.deepest_overall_slot(),
3530 duplicate_leaves_descended_from_6[0],
3531 );
3532
3533 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 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 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 let new_duplicate_hash = Hash::default();
3593
3594 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 heaviest_subtree_fork_choice.mark_fork_valid_candidate(&larger_duplicate_slot.slot_hash());
3877
3878 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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}