fast_sparse_merkle_tree/lib.rs
1//! # Fast SMT (Sparse Merkle Tree)
2//!
3//! Constructs a new `SparseMerkleTree<H, V, S>`, using TurboSHAKE128 as default hash function.
4//! You always have the freedom of using your favourite hash function by implementing `Hasher` trait.
5//! We provide two `Hasher` implementations - TurboSHAKE128 and BLAKE3. As per benchmarks, both of them stand
6//! shoulder-to-shoulder - showing impressive performance, compared to SHA256 or SHA3_256.
7//!
8//! # Examples
9//!
10//! ```
11//! use fast_sparse_merkle_tree::{
12//! turboshake_hasher::TurboShake128Hasher, default_store::DefaultStore,
13//! error::Error, MerkleProof,
14//! SparseMerkleTree, traits::Value, H256, Hash,
15//! traits::Hasher,
16//! };
17//!
18//! // Type define SMT
19//! type SMT = SparseMerkleTree<TurboShake128Hasher, Hash, Word, DefaultStore<Hash, Word, 32>, 32>;
20//!
21//! // Define SMT value
22//! #[derive(Default, Clone, PartialEq)]
23//! pub struct Word(String, H256);
24//!
25//! impl Value for Word {
26//! fn as_slice(&self) -> &[u8] {
27//! self.1.as_slice()
28//! }
29//! fn zero() -> Self {
30//! Default::default()
31//! }
32//! }
33//!
34//! fn construct_smt() {
35//! let mut tree = SMT::default();
36//!
37//! for (i, word) in "The quick brown fox jumps over the lazy dog"
38//! .split_whitespace()
39//! .enumerate()
40//! {
41//! let key: Hash = {
42//! let mut hasher = TurboShake128Hasher::default();
43//!
44//! hasher.write_bytes(&(i as u32).to_le_bytes());
45//! hasher.finish().into()
46//! };
47//!
48//! let hash: H256 = if !word.is_empty() {
49//! let mut hasher = TurboShake128Hasher::default();
50//!
51//! hasher.write_bytes(word.as_bytes());
52//! hasher.finish().into()
53//! } else {
54//! H256::zero()
55//! };
56//!
57//! let value = Word(word.to_string(), hash);
58//!
59//! // insert <key, value> pair into the tree
60//! tree.update(key, value).expect("inserting into SMT must not fail");
61//! }
62//!
63//! println!("SMT root is {:?} ", tree.root());
64//! }
65//! ```
66//!
67//! ## Installation
68//!
69//! Add this to your project's `Cargo.toml`:
70//!
71//! ```toml
72//! [dependencies]
73//! fast-sparse-merkle-tree = "=0.1.2"
74//! # or (minimal, just `turboshake` for faster hashing, no_std)
75//! fast-sparse-merkle-tree = { version = "=0.1.2", default-features = false, features = ["turboshake"] }
76//! ```
77//!
78//! For more see README in `fast-sparse-merkle-tree` repository @ <https://github.com/itzmeanjan/fast-sparse-merkle-tree>.
79
80#![cfg_attr(not(feature = "std"), no_std)]
81
82#[cfg(feature = "blake3")]
83pub mod blake3_hasher;
84
85#[cfg(feature = "turboshake")]
86pub mod turboshake_hasher;
87
88pub mod default_store;
89pub mod error;
90pub mod h256;
91pub mod internal_key;
92pub mod merge;
93pub mod merkle_proof;
94pub mod traits;
95pub mod tree;
96
97#[cfg(test)]
98mod tests;
99
100pub use h256::{H256, Hash};
101pub use internal_key::InternalKey;
102pub use merkle_proof::{CompiledMerkleProof, MerkleProof};
103pub use traits::Key;
104pub use tree::SparseMerkleTree;
105
106/// Expected path size: log2(256) * 2, used for hint vector capacity
107pub const EXPECTED_PATH_SIZE: usize = (256usize.ilog2() * 2) as usize;
108/// Height of sparse merkle tree
109pub const TREE_HEIGHT: usize = 256;
110/// Key limit size
111pub const KEY_LIMIT: usize = u32::MAX as usize;
112
113cfg_if::cfg_if! {
114 if #[cfg(feature = "std")] {
115 use std::collections;
116 use std::vec;
117 use std::string;
118 use std::vec as vec_macro;
119 } else {
120 extern crate alloc;
121 use alloc::collections;
122 use alloc::vec;
123 use alloc::string;
124 use alloc::vec as vec_macro;
125 }
126}