solana_core/consensus/
tree_diff.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
use std::{collections::HashSet, hash::Hash};

pub trait TreeDiff<'a> {
    type TreeKey: 'a + Hash + PartialEq + Eq + Copy;
    type ChildIter: Iterator<Item = &'a Self::TreeKey>;

    fn children(&self, key: &Self::TreeKey) -> Option<Self::ChildIter>;

    fn contains_slot(&self, slot: &Self::TreeKey) -> bool;

    // Find all nodes reachable from `root1`, excluding subtree at `root2`
    fn subtree_diff(&self, root1: Self::TreeKey, root2: Self::TreeKey) -> HashSet<Self::TreeKey> {
        if !self.contains_slot(&root1) {
            return HashSet::new();
        }
        let mut pending_keys = vec![root1];
        let mut reachable_set = HashSet::new();
        while let Some(current_key) = pending_keys.pop() {
            if current_key == root2 {
                continue;
            }
            for child in self
                .children(&current_key)
                .expect("slot was discovered earlier, must exist")
            {
                pending_keys.push(*child);
            }
            reachable_set.insert(current_key);
        }

        reachable_set
    }
}