pub fn missing_trie_keys<K, V, T, S, E>(
    _correlation_id: CorrelationId,
    txn: &T,
    store: &S,
    mut trie_keys_to_visit: Vec<Digest>,
) -> Result<Vec<Digest>, E>
where
    K: ToBytes + FromBytes + Eq + std::fmt::Debug,
    V: ToBytes + FromBytes + std::fmt::Debug,
    T: Readable<Handle = S::Handle>,
    S: TrieStore<K, V>,
    S::Error: From<T::Error>,
    E: From<S::Error> + From<bytesrepr::Error>,
{
    let mut missing_descendants = Vec::new();
    let mut visited = HashSet::new();
    while let Some(trie_key) = trie_keys_to_visit.pop() {
        if !visited.insert(trie_key) {
            continue;
        }
        let maybe_retrieved_trie: Option<Trie<K, V>> = store.get(txn, &trie_key)?;
        if let Some(trie_value) = &maybe_retrieved_trie {
            let hash_of_trie_value = {
                let node_bytes = trie_value.to_bytes()?;
                Digest::hash(&node_bytes)
            };
            if trie_key != hash_of_trie_value {
                warn!(
                    "Trie key {:?} has corrupted value {:?} (hash of value is {:?}); \
                     adding to list of missing nodes",
                    trie_key, trie_value, hash_of_trie_value
                );
                missing_descendants.push(trie_key);
                continue;
            }
        }
        match maybe_retrieved_trie {
            // If we can't find the trie_key; it is missing and we'll return it
            None => {
                missing_descendants.push(trie_key);
            }
            // If we could retrieve the node and it is a leaf, the search can move on
            Some(Trie::Leaf { .. }) => (),
            // If we hit a pointer block, queue up all of the nodes it points to
            Some(Trie::Node { pointer_block }) => {
                for (_, pointer) in pointer_block.as_indexed_pointers() {
                    match pointer {
                        Pointer::LeafPointer(descendant_leaf_trie_key) => {
                            trie_keys_to_visit.push(descendant_leaf_trie_key)
                        }
                        Pointer::NodePointer(descendant_node_trie_key) => {
                            trie_keys_to_visit.push(descendant_node_trie_key)
                        }
                    }
                }
            }
            // If we hit an extension block, add its pointer to the queue
            Some(Trie::Extension { pointer, .. }) => trie_keys_to_visit.push(pointer.into_hash()),
        }
    }
    Ok(missing_descendants)
}
/// Given a root hash, find any try keys that are descendant from it that are:
/// 1. referenced but not present in the database
/// 2. referenced and present but whose values' hashes do not equal their keys (ie, corrupted)
// TODO: We only need to check one trie key at a time
Given a root hash, find any try keys that are descendant from it that are:
1. referenced but not present in the database
2. referenced and present but whose values' hashes do not equal their keys
TODO: We only need to check one trie key at a time
Given a root hash find any try keys that are descendant from it that are : 1 . referenced but not present in the database 2 . referenced and present but whose values ' hashes do not equal their keys TODO : We only need to check one trie key at a time
pub fn missing_trie_keys<K, V, T, S, E>(
    _correlation_id: CorrelationId,
    txn: &T,
    store: &S,
    mut trie_keys_to_visit: Vec<Digest>,
) -> Result<Vec<Digest>, E>
where
    K: ToBytes + FromBytes + Eq + std::fmt::Debug,
    V: ToBytes + FromBytes + std::fmt::Debug,
    T: Readable<Handle = S::Handle>,
    S: TrieStore<K, V>,
    S::Error: From<T::Error>,
    E: From<S::Error> + From<bytesrepr::Error>,
{
    let mut missing_descendants = Vec::new();
    let mut visited = HashSet::new();
    while let Some(trie_key) = trie_keys_to_visit.pop() {
        if !visited.insert(trie_key) {
            continue;
        }
        let maybe_retrieved_trie: Option<Trie<K, V>> = store.get(txn, &trie_key)?;
        if let Some(trie_value) = &maybe_retrieved_trie {
            let hash_of_trie_value = {
                let node_bytes = trie_value.to_bytes()?;
                Digest::hash(&node_bytes)
            };
            if trie_key != hash_of_trie_value {
                warn!(
                    "Trie key {:?} has corrupted value {:?} (hash of value is {:?}); \
                     adding to list of missing nodes",
                    trie_key, trie_value, hash_of_trie_value
                );
                missing_descendants.push(trie_key);
                continue;
            }
        }
        match maybe_retrieved_trie {
            // If we can't find the trie_key; it is missing and we'll return it
            None => {
                missing_descendants.push(trie_key);
            }
            // If we could retrieve the node and it is a leaf, the search can move on
            Some(Trie::Leaf { .. }) => (),
            // If we hit a pointer block, queue up all of the nodes it points to
            Some(Trie::Node { pointer_block }) => {
                for (_, pointer) in pointer_block.as_indexed_pointers() {
                    match pointer {
                        Pointer::LeafPointer(descendant_leaf_trie_key) => {
                            trie_keys_to_visit.push(descendant_leaf_trie_key)
                        }
                        Pointer::NodePointer(descendant_node_trie_key) => {
                            trie_keys_to_visit.push(descendant_node_trie_key)
                        }
                    }
                }
            }
            // If we hit an extension block, add its pointer to the queue
            Some(Trie::Extension { pointer, .. }) => trie_keys_to_visit.push(pointer.into_hash()),
        }
    }
    Ok(missing_descendants)
}
pub fn missing_trie_keys < K , V , T , S , E > ( _correlation_id : CorrelationId , txn : & T , store : & S , mut trie_keys_to_visit : Vec < Digest > , ) -> Result < Vec < Digest > , E > where K : ToBytes + FromBytes + Eq + std :: fmt :: Debug , V : ToBytes + FromBytes + std :: fmt :: Debug , T : Readable < Handle = S :: Handle > , S : TrieStore < K , V > , S :: Error : From < T :: Error > , E : From < S :: Error > + From < bytesrepr :: Error > , { let mut missing_descendants = Vec :: new ( ) ; let mut visited = HashSet :: new ( ) ; while let Some ( trie_key ) = trie_keys_to_visit . pop ( ) { if ! visited . insert ( trie_key ) { continue ; } let maybe_retrieved_trie : Option < Trie < K , V > > = store . get ( txn , & trie_key ) ? ; if let Some ( trie_value ) = & maybe_retrieved_trie { let hash_of_trie_value = { let node_bytes = trie_value . to_bytes ( ) ? ; Digest :: hash ( & node_bytes ) } ; if trie_key != hash_of_trie_value { warn ! ( " \
 " trie_key trie_value hash_of_trie_value ) ; missing_descendants . push ( trie_key ) ; continue ; } } match maybe_retrieved_trie { // If we can't find the trie_key; it is missing and we'll return it None => { missing_descendants . push ( trie_key ) ; } // If we could retrieve the node and it is a leaf, the search can move on Some ( Trie :: Leaf { .. } ) => ( ) , // If we hit a pointer block, queue up all of the nodes it points to Some ( Trie :: Node { pointer_block } ) => { for ( _ , pointer ) in pointer_block . as_indexed_pointers ( ) { match pointer { Pointer :: LeafPointer ( descendant_leaf_trie_key ) => { trie_keys_to_visit . push ( descendant_leaf_trie_key ) } Pointer :: NodePointer ( descendant_node_trie_key ) => { trie_keys_to_visit . push ( descendant_node_trie_key ) } } } } // If we hit an extension block, add its pointer to the queue Some ( Trie :: Extension { pointer , .. } ) => trie_keys_to_visit . push ( pointer . into_hash ( ) ) , } } Ok ( missing_descendants ) }
Given a root hash, find any try keys that are descendant from it that are:
1. referenced but not present in the database
2. referenced and present but whose values' hashes do not equal their keys (ie, corrupted)
TODO: We only need to check one trie key at a time
Given a root hash find any try keys that are descendant from it that are : 1 . referenced but not present in the database 2 . referenced and present but whose values ' hashes do not equal their keys ( ie corrupted ) TODO : We only need to check one trie key at a time
_correlation_id
CorrelationId
txn
&T
store
&S
trie_keys_to_visit
Vec<Digest>
_correlation_id
CorrelationId
txn
&T
store
&S
trie_keys_to_visit
Vec<Digest>