Metadata
Every tree returns a TreeMetadata snapshot through the MerkleTree trait. It is cheap to build
and useful for logging, dashboards, health checks, and benchmarks.
| Field | Type | Meaning |
|---|---|---|
leaf_count | usize | Logical leaves stored |
height | usize | 0 for an empty tree, 1 for a single leaf |
node_count | usize | Allocated or materialized nodes (see below) |
hash_algorithm | &'static str | H::algorithm_name(), e.g. "SHA-256" |
variant | &'static str | "BinaryMerkleTree", "SparseMerkleTree", or "MerklePatriciaTrie" |
use merkle_core::prelude::*;
use merkle_variants::BinaryMerkleTree;
use merkleforge_hash::Sha256;
fn main() -> Result<(), MerkleError> {
let tree = BinaryMerkleTree::<Sha256>::from_leaves(["a", "b", "c", "d", "e"])?;
let metadata = tree.metadata();
println!("variant: {}", metadata.variant);
println!("algorithm: {}", metadata.hash_algorithm);
println!("leaves: {}", metadata.leaf_count);
println!("height: {}", metadata.height);
println!("allocated nodes: {}", metadata.node_count);
assert_eq!(metadata.variant, "BinaryMerkleTree");
assert_eq!(metadata.hash_algorithm, "SHA-256");
assert_eq!(metadata.leaf_count, 5);
assert_eq!(metadata.height, 4); // 5 leaves pad to 8: 8 -> 4 -> 2 -> 1
assert_eq!(metadata.node_count, 15); // 8 + 4 + 2 + 1
Ok(())
}metadata() is a trait method, so bring MerkleTree into scope (the prelude does).
What node_count means per variant
- Binary: the length of the flat node array, padding included (
2 × capacity − 1). - Sparse: materialized storage entries (internal, shortcut, and batch nodes). Thanks to
shortcut and batch compression this is far smaller than 256 per leaf. Compare with
stored_node_count()andunbatched_node_count_estimate(). - Patricia: materialized trie nodes, also available as
node_count().
Serializing metadata
TreeMetadata implements Serialize, so you can log it as JSON:
use merkle_core::prelude::*;
use merkle_variants::SparseMerkleTree;
use merkleforge_hash::Blake3;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut tree = SparseMerkleTree::<Blake3>::new();
tree.insert([1_u8; 32], b"value")?;
let json = serde_json::to_string(&tree.metadata())?;
assert!(json.contains("\"variant\":\"SparseMerkleTree\""));
println!("{json}");
Ok(())
}Because its string fields are &'static str, TreeMetadata can't be deserialized from an owned
buffer. Treat it as output only.