summaryrefslogtreecommitdiffstats
path: root/src/merkle/merkletree.rs
diff options
context:
space:
mode:
authorSanto Cariotti <santo@dcariotti.me>2025-06-14 16:38:00 +0000
committerSanto Cariotti <santo@dcariotti.me>2025-06-14 16:40:37 +0000
commitc470ba5f7b1a85bfd1cd96e5ec14d2f42a25ec55 (patch)
tree1a6adf9937b242650283496e24c01b42f8022777 /src/merkle/merkletree.rs
parenta7f8a76aae5335e744c743bec5e32696f0314623 (diff)
docs: add
Diffstat (limited to 'src/merkle/merkletree.rs')
-rw-r--r--src/merkle/merkletree.rs32
1 files changed, 32 insertions, 0 deletions
diff --git a/src/merkle/merkletree.rs b/src/merkle/merkletree.rs
index 812e300..fc2879a 100644
--- a/src/merkle/merkletree.rs
+++ b/src/merkle/merkletree.rs
@@ -1,13 +1,39 @@
+//! Provides the MerkleTree structure and associated methods for creating and interacting
+//! with binary Merkle trees using custom hashers.
+
use crate::{hasher::Hasher, merkle::node::Node};
+/// A binary Merkle tree implementation.
+///
+/// Merkle trees are hash-based data structures used for secure and efficient data verification.
+/// Each leaf node contains the hash of a data item, and each internal node contains the hash
+/// of the concatenation of its children's hashes.
#[derive(Debug)]
pub struct MerkleTree {
+ /// Leaf nodes at the base of the tree (may include a duplicate for even pairing).
leaves: Vec<Node>,
+ /// Height of the tree (number of levels including root).
height: usize,
+ /// Root node of the Merkle tree.
root: Node,
}
impl MerkleTree {
+ /// Creates a new `MerkleTree` from a collection of data items and a hash function.
+ ///
+ /// # Arguments
+ ///
+ /// * `hasher` - A reference to an implementation of the `Hasher` trait.
+ /// * `data` - A vector of values to be converted into leaf nodes.
+ ///
+ /// # Panics
+ ///
+ /// Panics if the `data` vector is empty.
+ ///
+ /// # Notes
+ ///
+ /// If the number of leaf nodes is odd, the last node is duplicated to ensure all internal
+ /// nodes have exactly two children.
pub fn new<T: ToString>(hasher: &dyn Hasher, data: Vec<T>) -> Self {
assert!(
!data.is_empty(),
@@ -18,6 +44,7 @@ impl MerkleTree {
.into_iter()
.map(|x| Node::new_leaf(hasher, x))
.collect();
+
if leaves.len() % 2 != 0 {
leaves.push(leaves[leaves.len() - 1].clone());
}
@@ -25,6 +52,7 @@ impl MerkleTree {
Self::build(hasher, leaves)
}
+ /// Constructs the internal nodes of the tree from the leaves upward and computes the root.
fn build(hasher: &dyn Hasher, mut nodes: Vec<Node>) -> Self {
let leaves = nodes.clone();
let mut height = 0;
@@ -48,18 +76,22 @@ impl MerkleTree {
}
}
+ /// Returns the height (number of levels) of the tree.
pub fn height(&self) -> usize {
self.height
}
+ /// Returns true if the tree has no leaves (should never happen if `new()` was used).
pub fn is_empty(&self) -> bool {
self.len() == 0
}
+ /// Returns the number of leaf nodes in the tree.
pub fn len(&self) -> usize {
self.leaves.len()
}
+ /// Returns the root node of the tree.
pub fn root(&self) -> Node {
self.root.clone()
}