use sha2::{Digest, Sha256};
use crate::simple_merkle::tree::MerkleHash;
const LEAF_PREFIX: &[u8] = &[0];
const INNER_PREFIX: &[u8] = &[1];
fn leaf_hash(bytes: &[u8]) -> [u8; 32] {
let mut hasher = Sha256::new();
hasher.update(LEAF_PREFIX);
hasher.update(bytes);
hasher.finalize().into()
}
fn inner_hash(left: &[u8], right: &[u8]) -> [u8; 32] {
let mut hasher = Sha256::new();
hasher.update(INNER_PREFIX);
hasher.update(left);
hasher.update(right);
hasher.finalize().into()
}
pub struct TmSha2Hasher;
impl Default for TmSha2Hasher {
fn default() -> Self {
Self::new()
}
}
impl TmSha2Hasher {
pub fn new() -> Self {
TmSha2Hasher
}
}
impl MerkleHash for TmSha2Hasher {
type Output = [u8; 32];
const EMPTY_ROOT: Self::Output = [
227, 176, 196, 66, 152, 252, 28, 20, 154, 251, 244, 200, 153, 111, 185, 36, 39, 174, 65,
228, 100, 155, 147, 76, 164, 149, 153, 27, 120, 82, 184, 85,
];
fn hash_leaf(&self, data: &[u8]) -> Self::Output {
leaf_hash(data)
}
fn hash_nodes(&self, left: &Self::Output, right: &Self::Output) -> Self::Output {
inner_hash(left, right)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{MemDb, MerkleTree};
use tendermint::merkle::simple_hash_from_byte_vectors;
#[test]
fn test_tm_hash_matches_upstream() {
let leaves: Vec<&[u8]> = vec![b"leaf_1", b"leaf_2", b"leaf_3", b"leaf_4"];
let hasher = TmSha2Hasher {};
let mut tree: MerkleTree<MemDb<[u8; 32]>, TmSha2Hasher> = MerkleTree::with_hasher(hasher);
leaves.iter().for_each(|leaf| {
tree.push_raw_leaf(leaf);
});
let hash_from_byte_slices = simple_hash_from_byte_vectors::<Sha256>(leaves.as_slice());
assert_eq!(tree.root().as_ref(), &hash_from_byte_slices);
}
}