pub fn crypto_hash_lazy_tree(t: &LazyTree<'_>) -> crypto::HashTree {
    use crypto::HashTree;

    fn go(t: &LazyTree<'_>) -> HashTree {
        match t {
            LazyTree::Blob(b) => {
                let mut h = Hasher::for_domain("ic-hashtree-leaf");
                h.update(b);
                HashTree::Leaf {
                    digest: h.finalize(),
                }
            }
            LazyTree::LazyBlob(f) => {
                let b = f();
                let mut h = Hasher::for_domain("ic-hashtree-leaf");
                h.update(&b);
                HashTree::Leaf {
                    digest: h.finalize(),
                }
            }
            LazyTree::LazyFork(f) => {
                let mut children = VecDeque::new();
                for label in f.labels() {
                    let child = go(&f.edge(&label).expect("missing fork tree"));
                    let mut h = Hasher::for_domain("ic-hashtree-labeled");
                    h.update(label.as_bytes());
                    h.update(child.digest().as_bytes());
                    children.push_back(HashTree::Node {
                        digest: h.finalize(),
                        label,
                        hash_tree: Box::new(child),
                    });
                }

                if children.is_empty() {
                    return HashTree::Leaf { digest: EMPTY_HASH };
                }

                let mut next = VecDeque::new();
                loop {
                    while let Some(l) = children.pop_front() {
                        if let Some(r) = children.pop_front() {
                            let mut h = Hasher::for_domain("ic-hashtree-fork");
                            h.update(l.digest().as_bytes());
                            h.update(r.digest().as_bytes());
                            next.push_back(HashTree::Fork {
                                digest: h.finalize(),
                                left_tree: Box::new(l),
                                right_tree: Box::new(r),
                            });
                        } else {
                            next.push_back(l);
                        }
                    }

                    if next.len() == 1 {
                        return next.pop_front().unwrap();
                    }
                    std::mem::swap(&mut children, &mut next);
                }
            }
        }
    }
    go(t)
}
/// Constructs a hash tree corresponding to the specified lazy tree.
/// This function is only used for benchmarks.
Constructs a hash tree corresponding to the specified lazy tree.
This function is only used for benchmarks.
Constructs a hash tree corresponding to the specified lazy tree . This function is only used for benchmarks .
pub fn crypto_hash_lazy_tree(t: &LazyTree<'_>) -> crypto::HashTree {
    use crypto::HashTree;
    fn go(t: &LazyTree<'_>) -> HashTree {
        match t {
            LazyTree::Blob(b) => {
                let mut h = Hasher::for_domain("ic-hashtree-leaf");
                h.update(b);
                HashTree::Leaf {
                    digest: h.finalize(),
                }
            }
            LazyTree::LazyBlob(f) => {
                let b = f();
                let mut h = Hasher::for_domain("ic-hashtree-leaf");
                h.update(&b);
                HashTree::Leaf {
                    digest: h.finalize(),
                }
            }
            LazyTree::LazyFork(f) => {
                let mut children = VecDeque::new();
                for label in f.labels() {
                    let child = go(&f.edge(&label).expect("missing fork tree"));
                    let mut h = Hasher::for_domain("ic-hashtree-labeled");
                    h.update(label.as_bytes());
                    h.update(child.digest().as_bytes());
                    children.push_back(HashTree::Node {
                        digest: h.finalize(),
                        label,
                        hash_tree: Box::new(child),
                    });
                }
                if children.is_empty() {
                    return HashTree::Leaf { digest: EMPTY_HASH };
                }
                let mut next = VecDeque::new();
                loop {
                    while let Some(l) = children.pop_front() {
                        if let Some(r) = children.pop_front() {
                            let mut h = Hasher::for_domain("ic-hashtree-fork");
                            h.update(l.digest().as_bytes());
                            h.update(r.digest().as_bytes());
                            next.push_back(HashTree::Fork {
                                digest: h.finalize(),
                                left_tree: Box::new(l),
                                right_tree: Box::new(r),
                            });
                        } else {
                            next.push_back(l);
                        }
                    }
                    if next.len() == 1 {
                        return next.pop_front().unwrap();
                    }
                    std::mem::swap(&mut children, &mut next);
                }
            }
        }
    }
    go(t)
}
pub fn crypto_hash_lazy_tree ( t : & LazyTree < ' _ > ) -> crypto :: HashTree { use crypto :: HashTree ; fn go ( t : & LazyTree < ' _ > ) -> HashTree { match t { LazyTree :: Blob ( b ) => { let mut h = Hasher :: for_domain ( " " ) ; h . update ( b ) ; HashTree :: Leaf { digest : h . finalize ( ) , } } LazyTree :: LazyBlob ( f ) => { let b = f ( ) ; let mut h = Hasher :: for_domain ( " " ) ; h . update ( & b ) ; HashTree :: Leaf { digest : h . finalize ( ) , } } LazyTree :: LazyFork ( f ) => { let mut children = VecDeque :: new ( ) ; for label in f . labels ( ) { let child = go ( & f . edge ( & label ) . expect ( " " ) ) ; let mut h = Hasher :: for_domain ( " " ) ; h . update ( label . as_bytes ( ) ) ; h . update ( child . digest ( ) . as_bytes ( ) ) ; children . push_back ( HashTree :: Node { digest : h . finalize ( ) , label , hash_tree : Box :: new ( child ) , } ) ; } if children . is_empty ( ) { return HashTree :: Leaf { digest : EMPTY_HASH } ; } let mut next = VecDeque :: new ( ) ; loop { while let Some ( l ) = children . pop_front ( ) { if let Some ( r ) = children . pop_front ( ) { let mut h = Hasher :: for_domain ( " " ) ; h . update ( l . digest ( ) . as_bytes ( ) ) ; h . update ( r . digest ( ) . as_bytes ( ) ) ; next . push_back ( HashTree :: Fork { digest : h . finalize ( ) , left_tree : Box :: new ( l ) , right_tree : Box :: new ( r ) , } ) ; } else { next . push_back ( l ) ; } } if next . len ( ) == 1 { return next . pop_front ( ) . unwrap ( ) ; } std :: mem :: swap ( & mut children , & mut next ) ; } } } } go ( t ) }
Constructs a hash tree corresponding to the specified lazy tree.
Constructs a hash tree corresponding to the specified lazy tree .
t
&LazyTree<'_>
t
&LazyTree<'_>