fuchsia_merkle/
lib.rs

1// Copyright 2018 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5//! `fuchsia_merkle` contains types and methods for building and working with merkle trees.
6
7#![deny(missing_docs)]
8
9use futures::{AsyncRead, AsyncReadExt as _};
10use std::io::{self, Read};
11
12pub use fuchsia_hash::{HASH_SIZE, Hash};
13
14/// The size of a single block of data (or hashes), in bytes.
15pub const BLOCK_SIZE: usize = 8192;
16
17mod util;
18pub use crate::util::hash_block;
19
20mod tree;
21pub use crate::tree::MerkleTree;
22
23mod builder;
24pub use crate::builder::MerkleTreeBuilder;
25
26mod writer;
27pub use crate::writer::MerkleTreeWriter;
28
29mod merkle_root_builder;
30pub use crate::merkle_root_builder::{
31    BufferedMerkleRootBuilder, LeafHashCollector, MerkleRootBuilder, NoopLeafHashCollector,
32};
33
34mod merkle_verifier;
35pub use crate::merkle_verifier::{MerkleVerifier, ReadSizedMerkleVerifier};
36
37/// Compute a merkle tree from a `&[u8]`.
38pub fn from_slice(slice: &[u8]) -> MerkleTree {
39    let mut builder = MerkleTreeBuilder::new();
40    builder.write(slice);
41    builder.finish()
42}
43
44/// Compute a merkle tree from a `std::io::Read`.
45pub fn from_read<R>(reader: &mut R) -> Result<MerkleTree, io::Error>
46where
47    R: Read,
48{
49    MerkleTree::from_reader(reader)
50}
51
52/// Compute a merkle tree from a `futures::io::AsyncRead`.
53pub async fn from_async_read<R>(reader: &mut R) -> Result<MerkleTree, io::Error>
54where
55    R: AsyncRead + Unpin,
56{
57    let mut buf = [0; BLOCK_SIZE];
58    let mut builder = MerkleTreeBuilder::new();
59
60    loop {
61        let len = reader.read(&mut buf).await?;
62        if len == 0 {
63            break;
64        }
65        builder.write(&buf[0..len]);
66    }
67
68    Ok(builder.finish())
69}
70
71#[cfg(test)]
72mod tests {
73    use super::*;
74
75    #[test]
76    fn test_from_slice() {
77        let file = b"hello world";
78        let mut builder = MerkleTreeBuilder::new();
79        builder.write(&file[..]);
80        let expected = builder.finish();
81
82        let actual = from_slice(&file[..]);
83        assert_eq!(expected, actual);
84    }
85
86    #[test]
87    fn test_from_read() {
88        let file = b"hello world";
89        let mut builder = MerkleTreeBuilder::new();
90        builder.write(&file[..]);
91        let expected = builder.finish();
92
93        let actual = from_read(&mut &file[..]).unwrap();
94        assert_eq!(expected, actual);
95    }
96
97    #[test]
98    fn test_from_async_read() {
99        futures::executor::block_on(async {
100            let file = b"hello world";
101            let mut builder = MerkleTreeBuilder::new();
102            builder.write(&file[..]);
103            let expected = builder.finish();
104
105            let actual = from_async_read(&mut &file[..]).await.unwrap();
106            assert_eq!(expected, actual);
107        })
108    }
109}