/// Materializes the provided lazy tree and builds its hash tree that can be
/// used to produce witnesses.
Materializes the provided lazy tree and builds its hash tree that can be
used to produce witnesses.
Materializes the provided lazy tree and builds its hash tree that can be used to produce witnesses .
pub fn hash_lazy_tree(t: &LazyTree<'_>) -> HashTree {
    fn go(t: &LazyTree<'_>, ht: &mut HashTree, parent: NodeId) -> NodeId {
        match t {
            LazyTree::Blob(b) => {
                let mut h = Hasher::for_domain("ic-hashtree-leaf");
                h.update(b);
                ht.new_leaf(h.finalize())
            }
            LazyTree::LazyBlob(f) => {
                let b = f();
                let mut h = Hasher::for_domain("ic-hashtree-leaf");
                h.update(&b);
                ht.new_leaf(h.finalize())
            }
            LazyTree::LazyFork(f) => {
                let range = ht.preallocate_nodes(f.labels(), parent);
                let mut nodes = VecDeque::new();
                for i in range {
                    let child = go(
                        &f.edge(&ht.node_labels[i]).expect("missing fork tree"),
                        ht,
                        NodeId::node(i),
                    );
                    let mut h = Hasher::for_domain("ic-hashtree-labeled");
                    h.update(ht.node_labels[i].as_bytes());
                    h.update(ht.digest(child).as_bytes());
                    ht.node_digests[i] = h.finalize();
                    ht.node_children[i] = child;
                    nodes.push_back(NodeId::node(i));
                }
                if nodes.is_empty() {
                    return NodeId::empty();
                }
                let mut next = VecDeque::new();
                loop {
                    while let Some(l) = nodes.pop_front() {
                        if let Some(r) = nodes.pop_front() {
                            let mut h = Hasher::for_domain("ic-hashtree-fork");
                            h.update(ht.digest(l).as_bytes());
                            h.update(ht.digest(r).as_bytes());
                            next.push_back(ht.new_fork(h.finalize(), l, r));
                        } else {
                            next.push_back(l);
                        }
                    }
                    if next.len() == 1 {
                        return next.pop_front().unwrap();
                    }
                    std::mem::swap(&mut nodes, &mut next);
                }
            }
        }
    }
    let mut ht = HashTree::default();
    ht.root = go(t, &mut ht, NodeId::empty());
    ht.check_invariants();
    ht
}
pub fn hash_lazy_tree ( t : & LazyTree < ' _ > ) -> HashTree { fn go ( t : & LazyTree < ' _ > , ht : & mut HashTree , parent : NodeId ) -> NodeId { match t { LazyTree :: Blob ( b ) => { let mut h = Hasher :: for_domain ( " " ) ; h . update ( b ) ; ht . new_leaf ( h . finalize ( ) ) } LazyTree :: LazyBlob ( f ) => { let b = f ( ) ; let mut h = Hasher :: for_domain ( " " ) ; h . update ( & b ) ; ht . new_leaf ( h . finalize ( ) ) } LazyTree :: LazyFork ( f ) => { let range = ht . preallocate_nodes ( f . labels ( ) , parent ) ; let mut nodes = VecDeque :: new ( ) ; for i in range { let child = go ( & f . edge ( & ht . node_labels [ i ] ) . expect ( " " ) , ht , NodeId :: node ( i ) , ) ; let mut h = Hasher :: for_domain ( " " ) ; h . update ( ht . node_labels [ i ] . as_bytes ( ) ) ; h . update ( ht . digest ( child ) . as_bytes ( ) ) ; ht . node_digests [ i ] = h . finalize ( ) ; ht . node_children [ i ] = child ; nodes . push_back ( NodeId :: node ( i ) ) ; } if nodes . is_empty ( ) { return NodeId :: empty ( ) ; } let mut next = VecDeque :: new ( ) ; loop { while let Some ( l ) = nodes . pop_front ( ) { if let Some ( r ) = nodes . pop_front ( ) { let mut h = Hasher :: for_domain ( " " ) ; h . update ( ht . digest ( l ) . as_bytes ( ) ) ; h . update ( ht . digest ( r ) . as_bytes ( ) ) ; next . push_back ( ht . new_fork ( h . finalize ( ) , l , r ) ) ; } else { next . push_back ( l ) ; } } if next . len ( ) == 1 { return next . pop_front ( ) . unwrap ( ) ; } std :: mem :: swap ( & mut nodes , & mut next ) ; } } } } let mut ht = HashTree :: default ( ) ; ht . root = go ( t , & mut ht , NodeId :: empty ( ) ) ; ht . check_invariants ( ) ; ht }
Materializes the provided lazy tree and builds its hash tree that can be
used to produce witnesses.
Materializes the provided lazy tree and builds its hash tree that can be used to produce witnesses .
t
&LazyTree<'_>