use std::convert::TryFrom;
use blake2_rfc::blake2b::Blake2b;
pub const HASH_LENGTH: usize = 20;
pub const NULL_HASH: Hash = [0; HASH_LENGTH];
pub type Hash = [u8; HASH_LENGTH];
pub fn kv_hash(key: &[u8], value: &[u8]) -> Hash {
let mut hasher = Blake2b::new(HASH_LENGTH);
let key_length = u8::try_from(key.len())
.expect("key must be less than 256 bytes");
hasher.update(&key_length.to_be_bytes());
hasher.update(&key);
let val_length = u16::try_from(value.len())
.expect("value must be less than 65,536 bytes");
hasher.update(&val_length.to_be_bytes());
hasher.update(&value);
let res = hasher.finalize();
let mut hash: Hash = Default::default();
hash.copy_from_slice(res.as_bytes());
hash
}
pub fn node_hash(kv: &Hash, left: &Hash, right: &Hash) -> Hash {
let mut hasher = Blake2b::new(HASH_LENGTH);
hasher.update(kv);
hasher.update(left);
hasher.update(right);
let res = hasher.finalize();
let mut hash: Hash = Default::default();
hash.copy_from_slice(res.as_bytes());
hash
}