#[cfg(test)]
mod tests {
use crate::{Sha256Hasher, Stem, TreeKey, UnifiedBinaryTree, B256};
fn hex_to_b256(s: &str) -> B256 {
let s = s.strip_prefix("0x").unwrap_or(s);
let bytes = hex::decode(s).expect("valid hex");
B256::from_slice(&bytes)
}
const ZERO_KEY: B256 = B256::ZERO;
fn one_key() -> B256 {
hex_to_b256("0101010101010101010101010101010101010101010101010101010101010101")
}
fn two_key() -> B256 {
hex_to_b256("0202020202020202020202020202020202020202020202020202020202020202")
}
#[test]
fn test_single_entry_sha256() {
let mut tree: UnifiedBinaryTree<Sha256Hasher> = UnifiedBinaryTree::new();
tree.insert_b256(ZERO_KEY, one_key());
let root = tree.root_hash().unwrap();
let expected =
hex_to_b256("aab1060e04cb4f5dc6f697ae93156a95714debbf77d54238766adc5709282b6f");
println!("Single entry root (SHA256): {}", root);
println!("go-ethereum expected: {}", expected);
assert_eq!(tree.get_by_b256(&ZERO_KEY), Some(one_key()));
}
#[test]
fn test_two_entries_diff_first_bit_sha256() {
let mut tree: UnifiedBinaryTree<Sha256Hasher> = UnifiedBinaryTree::new();
tree.insert_b256(ZERO_KEY, one_key());
let key2 = hex_to_b256("8000000000000000000000000000000000000000000000000000000000000000");
tree.insert_b256(key2, two_key());
let root = tree.root_hash().unwrap();
let expected =
hex_to_b256("dfc69c94013a8b3c65395625a719a87534a7cfd38719251ad8c8ea7fe79f065e");
println!("Two entries root (SHA256): {}", root);
println!("go-ethereum expected: {}", expected);
assert_eq!(tree.len(), 2);
assert_eq!(tree.get_by_b256(&ZERO_KEY), Some(one_key()));
assert_eq!(tree.get_by_b256(&key2), Some(two_key()));
}
#[test]
fn test_stem_node_hash_single_value() {
use crate::{Sha256Hasher, StemNode};
let hasher = Sha256Hasher;
let stem = Stem::new([0u8; 31]);
let mut node = StemNode::new(stem);
node.set_value(0, one_key());
let hash = node.hash(&hasher);
println!("Stem node hash (single value at idx 0): {}", hash);
assert_ne!(hash, B256::ZERO);
assert_eq!(hash, node.hash(&hasher));
}
#[test]
fn test_colocated_values_sha256() {
let mut tree: UnifiedBinaryTree<Sha256Hasher> = UnifiedBinaryTree::new();
let key1 = hex_to_b256("0000000000000000000000000000000000000000000000000000000000000003");
let key2 = hex_to_b256("0000000000000000000000000000000000000000000000000000000000000004");
tree.insert_b256(key1, one_key());
tree.insert_b256(key2, two_key());
let tk1 = TreeKey::from_bytes(key1);
let tk2 = TreeKey::from_bytes(key2);
assert_eq!(tk1.stem, tk2.stem);
assert_eq!(tree.len(), 2);
let root = tree.root_hash().unwrap();
println!("Colocated values root: {}", root);
assert_ne!(root, B256::ZERO);
}
#[test]
fn test_hash_determinism_sha256() {
let mut tree1: UnifiedBinaryTree<Sha256Hasher> = UnifiedBinaryTree::new();
let mut tree2: UnifiedBinaryTree<Sha256Hasher> = UnifiedBinaryTree::new();
let key1 = hex_to_b256("0000000000000000000000000000000000000000000000000000000000000001");
let key2 = hex_to_b256("8000000000000000000000000000000000000000000000000000000000000001");
tree1.insert_b256(key1, one_key());
tree1.insert_b256(key2, two_key());
tree2.insert_b256(key2, two_key());
tree2.insert_b256(key1, one_key());
assert_eq!(tree1.root_hash().unwrap(), tree2.root_hash().unwrap());
}
#[test]
fn test_internal_node_hash_sha256() {
use crate::{Hasher, InternalNode, Node, Sha256Hasher, StemNode};
let hasher = Sha256Hasher;
let mut stem1 = StemNode::new(Stem::new([0u8; 31]));
stem1.set_value(0, one_key());
let mut bytes2 = [0u8; 31];
bytes2[0] = 0x80; let mut stem2 = StemNode::new(Stem::new(bytes2));
stem2.set_value(0, two_key());
let internal = InternalNode::new(Node::Stem(stem1.clone()), Node::Stem(stem2.clone()));
let left_hash = stem1.hash(&hasher);
let right_hash = stem2.hash(&hasher);
let internal_hash = internal.hash(&hasher);
let expected = hasher.hash_64(&left_hash, &right_hash);
assert_eq!(internal_hash, expected);
println!("Left stem hash: {}", left_hash);
println!("Right stem hash: {}", right_hash);
println!("Internal hash: {}", internal_hash);
}
}