mirror of
https://gitlab.com/pulsechaincom/lighthouse-pulse.git
synced 2024-12-25 04:57:17 +00:00
chore(merkle_root): move function into lib.rs
Signed-off-by: Johns Beharry <johns@peakshift.com>
This commit is contained in:
parent
5f9e93d338
commit
9fbacbf967
@ -8,6 +8,33 @@ pub fn hash(input: &[u8]) -> Vec<u8> {
|
||||
result
|
||||
}
|
||||
|
||||
/// Generate Merkle Root
|
||||
///
|
||||
/// Outputs a `Vec<u8>` byte array of the merkle root given a set of leaf node values.
|
||||
/// Expects leaf nodes to already be hashed.
|
||||
pub fn merkle_root(values: &[Vec<u8>]) -> Vec<u8> {
|
||||
let values_len = values.len();
|
||||
|
||||
// vector to store hashes
|
||||
// filled with 0 as placeholders
|
||||
let mut o: Vec<Vec<u8>> = vec![vec![0]; values_len];
|
||||
|
||||
// append values to the end
|
||||
o.append(&mut values.to_vec());
|
||||
|
||||
// traverse backwards as values are at the end
|
||||
// then fill placeholders with a hash of two leaf nodes
|
||||
for i in (0..values_len).rev() {
|
||||
let mut current_value: Vec<u8> = o[i * 2].clone();
|
||||
current_value.append(&mut o[i * 2 + 1].clone());
|
||||
|
||||
o[i] = hash(¤t_value[..]);
|
||||
}
|
||||
|
||||
// the root hash will be at index 1
|
||||
o[1].clone()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@ -25,4 +52,36 @@ mod tests {
|
||||
];
|
||||
assert_eq!(expected, output.as_slice());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_merkle_root() {
|
||||
// hash the leaf nodes
|
||||
let mut input = vec![
|
||||
hash("a".as_bytes()),
|
||||
hash("b".as_bytes()),
|
||||
hash("c".as_bytes()),
|
||||
hash("d".as_bytes()),
|
||||
];
|
||||
|
||||
// generate a merkle tree and return the root
|
||||
let output = merkle_root(&input[..]);
|
||||
|
||||
// create merkle root manually
|
||||
let mut leaf_1_2: Vec<u8> = input[0].clone(); // a
|
||||
leaf_1_2.append(&mut input[1].clone()); // b
|
||||
|
||||
let mut leaf_3_4: Vec<u8> = input[2].clone(); // c
|
||||
leaf_3_4.append(&mut input[3].clone()); // d
|
||||
|
||||
let node_1 = hash(&leaf_1_2[..]);
|
||||
let node_2 = hash(&leaf_3_4[..]);
|
||||
|
||||
let mut root: Vec<u8> = node_1.clone(); // ab
|
||||
root.append(&mut node_2.clone()); // cd
|
||||
|
||||
let expected = hash(&root[..]);
|
||||
|
||||
assert_eq!(&expected[..], output.as_slice());
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,41 +0,0 @@
|
||||
use crate::hash;
|
||||
|
||||
pub fn merkle_root(values: &[Vec<u8>]) -> Vec<u8> {
|
||||
let values_len = values.len();
|
||||
let mut o: Vec<Vec<u8>> = vec![vec![0]; values_len];
|
||||
|
||||
o.append(&mut values.to_vec());
|
||||
|
||||
for i in (0..values_len).rev() {
|
||||
let mut current_value: Vec<u8> = o[i * 2].clone();
|
||||
current_value.append(&mut o[i * 2 + 1].clone());
|
||||
|
||||
o[i] = hash(¤t_value[..]);
|
||||
}
|
||||
|
||||
o[1].clone()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_merkle_root() {
|
||||
let input = vec![
|
||||
"a".as_bytes().to_vec(),
|
||||
"b".as_bytes().to_vec(),
|
||||
"c".as_bytes().to_vec(),
|
||||
"d".as_bytes().to_vec()
|
||||
];
|
||||
|
||||
let output = merkle_root(&input[..]);
|
||||
|
||||
// merkle root of [[a],[b],[c],[d]]
|
||||
let expected = &[
|
||||
183, 91, 96, 122, 144, 174, 84, 92, 97, 156, 140, 192, 66, 221, 55, 229,
|
||||
234, 48, 118, 7, 61, 207, 39, 125, 150, 32, 94, 90, 19, 88, 122, 163,
|
||||
];
|
||||
assert_eq!(expected, output.as_slice());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user