lighthouse/eth2/utils/cached_tree_hash/src/resize.rs

222 lines
7.0 KiB
Rust
Raw Normal View History

2019-04-12 23:42:43 +00:00
use super::*;
/// New vec is bigger than old vec.
pub fn grow_merkle_tree(
2019-04-13 02:12:56 +00:00
old_bytes: &[u8],
old_flags: &[bool],
from_height: usize,
to_height: usize,
2019-04-13 07:21:50 +00:00
) -> Option<(Vec<u8>, Vec<bool>)> {
let to_nodes = nodes_in_tree_of_height(to_height);
2019-04-12 23:42:43 +00:00
2019-04-14 03:54:04 +00:00
let mut bytes = vec![0; to_nodes * HASHSIZE];
2019-04-13 02:12:56 +00:00
let mut flags = vec![true; to_nodes];
2019-04-12 23:42:43 +00:00
for i in 0..=from_height {
let old_byte_slice = old_bytes.get(byte_range_at_height(i))?;
let old_flag_slice = old_flags.get(node_range_at_height(i))?;
let offset = i + to_height - from_height;
let new_byte_slice = bytes.get_mut(byte_range_at_height(offset))?;
let new_flag_slice = flags.get_mut(node_range_at_height(offset))?;
2019-04-14 04:20:33 +00:00
new_byte_slice
.get_mut(0..old_byte_slice.len())?
.copy_from_slice(old_byte_slice);
new_flag_slice
.get_mut(0..old_flag_slice.len())?
.copy_from_slice(old_flag_slice);
2019-04-12 23:42:43 +00:00
}
2019-04-13 07:21:50 +00:00
Some((bytes, flags))
2019-04-13 03:02:41 +00:00
}
2019-04-14 06:31:47 +00:00
/// New vec is smaller than old vec.
pub fn shrink_merkle_tree(
2019-04-14 06:31:47 +00:00
from_bytes: &[u8],
from_flags: &[bool],
from_height: usize,
to_height: usize,
) -> Option<(Vec<u8>, Vec<bool>)> {
let to_nodes = nodes_in_tree_of_height(to_height);
2019-04-14 06:31:47 +00:00
let mut bytes = vec![0; to_nodes * HASHSIZE];
let mut flags = vec![true; to_nodes];
for i in 0..=to_height as usize {
let offset = i + from_height - to_height;
let from_byte_slice = from_bytes.get(byte_range_at_height(offset))?;
let from_flag_slice = from_flags.get(node_range_at_height(offset))?;
let to_byte_slice = bytes.get_mut(byte_range_at_height(i))?;
let to_flag_slice = flags.get_mut(node_range_at_height(i))?;
to_byte_slice.copy_from_slice(from_byte_slice.get(0..to_byte_slice.len())?);
to_flag_slice.copy_from_slice(from_flag_slice.get(0..to_flag_slice.len())?);
2019-04-14 06:31:47 +00:00
}
Some((bytes, flags))
}
pub fn nodes_in_tree_of_height(h: usize) -> usize {
2019-04-14 03:54:04 +00:00
2 * (1 << h) - 1
}
2019-04-13 02:12:56 +00:00
fn byte_range_at_height(h: usize) -> Range<usize> {
2019-04-14 03:54:04 +00:00
let node_range = node_range_at_height(h);
node_range.start * HASHSIZE..node_range.end * HASHSIZE
2019-04-13 02:12:56 +00:00
}
2019-04-13 07:21:50 +00:00
fn node_range_at_height(h: usize) -> Range<usize> {
2019-04-14 03:54:04 +00:00
first_node_at_height(h)..last_node_at_height(h) + 1
2019-04-13 07:21:50 +00:00
}
2019-04-13 02:12:56 +00:00
fn first_node_at_height(h: usize) -> usize {
(1 << h) - 1
}
fn last_node_at_height(h: usize) -> usize {
2019-04-14 03:54:04 +00:00
(1 << (h + 1)) - 2
2019-04-13 02:12:56 +00:00
}
2019-04-12 23:42:43 +00:00
#[cfg(test)]
mod test {
2019-04-13 02:12:56 +00:00
use super::*;
2019-04-12 23:42:43 +00:00
#[test]
2019-04-14 06:31:47 +00:00
fn can_grow_and_shrink_three_levels() {
let small: usize = 1;
let big: usize = 15;
let original_bytes = vec![42; small * HASHSIZE];
let original_flags = vec![false; small];
let (grown_bytes, grown_flags) = grow_merkle_tree(
2019-04-14 06:31:47 +00:00
&original_bytes,
&original_flags,
(small + 1).trailing_zeros() as usize - 1,
(big + 1).trailing_zeros() as usize - 1,
2019-04-13 07:21:50 +00:00
)
.unwrap();
let mut expected_bytes = vec![];
let mut expected_flags = vec![];
// First level
expected_bytes.append(&mut vec![0; 32]);
expected_flags.push(true);
// Second level
expected_bytes.append(&mut vec![0; 32]);
expected_bytes.append(&mut vec![0; 32]);
expected_flags.push(true);
expected_flags.push(true);
// Third level
expected_bytes.append(&mut vec![0; 32]);
expected_bytes.append(&mut vec![0; 32]);
expected_bytes.append(&mut vec![0; 32]);
expected_bytes.append(&mut vec![0; 32]);
expected_flags.push(true);
expected_flags.push(true);
expected_flags.push(true);
expected_flags.push(true);
// Fourth level
expected_bytes.append(&mut vec![42; 32]);
expected_bytes.append(&mut vec![0; 32]);
expected_bytes.append(&mut vec![0; 32]);
expected_bytes.append(&mut vec![0; 32]);
expected_bytes.append(&mut vec![0; 32]);
expected_bytes.append(&mut vec![0; 32]);
expected_bytes.append(&mut vec![0; 32]);
expected_bytes.append(&mut vec![0; 32]);
expected_flags.push(false);
expected_flags.push(true);
expected_flags.push(true);
expected_flags.push(true);
expected_flags.push(true);
expected_flags.push(true);
expected_flags.push(true);
expected_flags.push(true);
2019-04-14 06:31:47 +00:00
assert_eq!(expected_bytes, grown_bytes);
assert_eq!(expected_flags, grown_flags);
let (shrunk_bytes, shrunk_flags) = shrink_merkle_tree(
2019-04-14 06:31:47 +00:00
&grown_bytes,
&grown_flags,
(big + 1).trailing_zeros() as usize - 1,
(small + 1).trailing_zeros() as usize - 1,
)
.unwrap();
assert_eq!(original_bytes, shrunk_bytes);
assert_eq!(original_flags, shrunk_flags);
2019-04-13 07:21:50 +00:00
}
#[test]
2019-04-14 06:31:47 +00:00
fn can_grow_and_shrink_one_level() {
let small: usize = 7;
let big: usize = 15;
let original_bytes = vec![42; small * HASHSIZE];
let original_flags = vec![false; small];
let (grown_bytes, grown_flags) = grow_merkle_tree(
2019-04-14 06:31:47 +00:00
&original_bytes,
&original_flags,
(small + 1).trailing_zeros() as usize - 1,
(big + 1).trailing_zeros() as usize - 1,
2019-04-13 02:12:56 +00:00
)
.unwrap();
2019-04-13 07:21:50 +00:00
let mut expected_bytes = vec![];
let mut expected_flags = vec![];
2019-04-13 02:12:56 +00:00
// First level
2019-04-13 07:21:50 +00:00
expected_bytes.append(&mut vec![0; 32]);
expected_flags.push(true);
2019-04-13 02:12:56 +00:00
// Second level
2019-04-13 07:21:50 +00:00
expected_bytes.append(&mut vec![42; 32]);
expected_bytes.append(&mut vec![0; 32]);
expected_flags.push(false);
expected_flags.push(true);
2019-04-13 02:12:56 +00:00
// Third level
2019-04-13 07:21:50 +00:00
expected_bytes.append(&mut vec![42; 32]);
expected_bytes.append(&mut vec![42; 32]);
expected_bytes.append(&mut vec![0; 32]);
expected_bytes.append(&mut vec![0; 32]);
expected_flags.push(false);
expected_flags.push(false);
expected_flags.push(true);
expected_flags.push(true);
2019-04-13 02:12:56 +00:00
// Fourth level
2019-04-13 07:21:50 +00:00
expected_bytes.append(&mut vec![42; 32]);
expected_bytes.append(&mut vec![42; 32]);
expected_bytes.append(&mut vec![42; 32]);
expected_bytes.append(&mut vec![42; 32]);
expected_bytes.append(&mut vec![0; 32]);
expected_bytes.append(&mut vec![0; 32]);
expected_bytes.append(&mut vec![0; 32]);
expected_bytes.append(&mut vec![0; 32]);
expected_flags.push(false);
expected_flags.push(false);
expected_flags.push(false);
expected_flags.push(false);
expected_flags.push(true);
expected_flags.push(true);
expected_flags.push(true);
expected_flags.push(true);
2019-04-14 06:31:47 +00:00
assert_eq!(expected_bytes, grown_bytes);
assert_eq!(expected_flags, grown_flags);
let (shrunk_bytes, shrunk_flags) = shrink_merkle_tree(
2019-04-14 06:31:47 +00:00
&grown_bytes,
&grown_flags,
(big + 1).trailing_zeros() as usize - 1,
(small + 1).trailing_zeros() as usize - 1,
)
.unwrap();
assert_eq!(original_bytes, shrunk_bytes);
assert_eq!(original_flags, shrunk_flags);
2019-04-12 23:42:43 +00:00
}
}