diff --git a/tendermint/src/merkle.rs b/tendermint/src/merkle.rs index f0b28efff..f34f0cc5f 100644 --- a/tendermint/src/merkle.rs +++ b/tendermint/src/merkle.rs @@ -8,16 +8,23 @@ pub const HASH_SIZE: usize = 32; /// Hash is the output of the cryptographic digest function pub type Hash = [u8; HASH_SIZE]; -/// Compute a simple Merkle root from the arbitrary sized byte slices -pub fn simple_hash_from_byte_slices(byte_slices: &[&[u8]]) -> Hash { +/// Compute a simple Merkle root from vectors of arbitrary byte vectors. +/// The leaves of the tree are the bytes of the given byte vectors in +/// the given order. +pub fn simple_hash_from_byte_vectors(byte_vecs: Vec>) -> Hash { + simple_hash_from_byte_slices_inner(byte_vecs.as_slice()) +} + +// recurse into subtrees +fn simple_hash_from_byte_slices_inner(byte_slices: &[Vec]) -> Hash { let length = byte_slices.len(); match length { 0 => [0; HASH_SIZE], - 1 => leaf_hash(byte_slices[0]), + 1 => leaf_hash(byte_slices[0].as_slice()), _ => { let k = get_split_point(length); - let left = simple_hash_from_byte_slices(&byte_slices[..k]); - let right = simple_hash_from_byte_slices(&byte_slices[k..]); + let left = simple_hash_from_byte_slices_inner(&byte_slices[..k]); + let right = simple_hash_from_byte_slices_inner(&byte_slices[k..]); inner_hash(&left, &right) } } @@ -90,8 +97,9 @@ mod tests { let empty_leaf_root_hex = "6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d"; let empty_leaf_root = &hex::decode(empty_leaf_root_hex).unwrap(); - let empty_tree: &[&[u8]] = &[&[]]; - let root = simple_hash_from_byte_slices(empty_tree); + let empty_tree: Vec> = vec![vec![]; 1]; + + let root = simple_hash_from_byte_vectors(empty_tree); assert_eq!(empty_leaf_root, &root); } @@ -101,8 +109,9 @@ mod tests { let leaf_string = "L123456"; let leaf_root = &hex::decode(leaf_root_hex).unwrap(); - let leaf_tree: &[&[u8]] = &[leaf_string.as_bytes()]; - let root = simple_hash_from_byte_slices(leaf_tree); + let leaf_tree: Vec> = vec![leaf_string.as_bytes().to_vec(); 1]; + + let root = simple_hash_from_byte_vectors(leaf_tree); assert_eq!(leaf_root, &root); } diff --git a/tendermint/src/validator.rs b/tendermint/src/validator.rs index f7c2dc8e5..f936de8a9 100644 --- a/tendermint/src/validator.rs +++ b/tendermint/src/validator.rs @@ -21,18 +21,12 @@ impl Set { /// Compute the Merkle root of the validator set pub fn hash(self) -> merkle::Hash { - // We need to get from Vec to &[&[u8]] so we can call simple_hash_from_byte_slices. - // This looks like: Vec -> Vec> -> Vec<&[u8]> -> &[&[u8]] - // Can we simplify this? - // Perhaps simple_hash_from_byteslices should take Vec> directly ? let validator_bytes: Vec> = self .validators .into_iter() .map(|x| x.hash_bytes()) .collect(); - let validator_byteslices: Vec<&[u8]> = - (&validator_bytes).iter().map(|x| x.as_slice()).collect(); - merkle::simple_hash_from_byte_slices(validator_byteslices.as_slice()) + merkle::simple_hash_from_byte_vectors(validator_bytes) } }