diff --git a/eth2/utils/cached_tree_hash/src/btree_overlay.rs b/eth2/utils/cached_tree_hash/src/btree_overlay.rs index 7d08210fbd..4b3c6cc277 100644 --- a/eth2/utils/cached_tree_hash/src/btree_overlay.rs +++ b/eth2/utils/cached_tree_hash/src/btree_overlay.rs @@ -149,7 +149,6 @@ impl BTreeOverlay { chunks.append(&mut self.leaf_node_chunks()); (0..self.num_internal_nodes()) - .into_iter() .map(|parent| { let children = children(parent); (chunks[parent], (chunks[children.0], chunks[children.1])) diff --git a/eth2/utils/cached_tree_hash/src/impls/vec.rs b/eth2/utils/cached_tree_hash/src/impls/vec.rs index 00a1ef9d92..b04884636d 100644 --- a/eth2/utils/cached_tree_hash/src/impls/vec.rs +++ b/eth2/utils/cached_tree_hash/src/impls/vec.rs @@ -65,7 +65,7 @@ pub fn new_tree_hash_cache( Ok((cache, schema)) } -pub fn produce_schema(vec: &Vec, depth: usize) -> BTreeSchema { +pub fn produce_schema(vec: &[T], depth: usize) -> BTreeSchema { let lengths = match T::tree_hash_type() { TreeHashType::Basic => { // Ceil division. @@ -89,6 +89,7 @@ pub fn produce_schema(vec: &Vec, depth: usize) -> BTreeSch BTreeSchema::from_lengths(depth, lengths) } +#[allow(clippy::range_plus_one)] // Minor readability lint requiring structural changes; not worth it. pub fn update_tree_hash_cache( vec: &Vec, cache: &mut TreeHashCache, @@ -294,7 +295,7 @@ where // } -fn get_packed_leaves(vec: &Vec) -> Result, Error> +fn get_packed_leaves(vec: &[T]) -> Result, Error> where T: CachedTreeHash, { diff --git a/eth2/utils/cached_tree_hash/src/tree_hash_cache.rs b/eth2/utils/cached_tree_hash/src/tree_hash_cache.rs index c6b3833c81..283a98974c 100644 --- a/eth2/utils/cached_tree_hash/src/tree_hash_cache.rs +++ b/eth2/utils/cached_tree_hash/src/tree_hash_cache.rs @@ -168,46 +168,53 @@ impl TreeHashCache { ) -> Result { let old_overlay = self.get_overlay(schema_index, chunk_index)?; // If the merkle tree required to represent the new list is of a different size to the one - // required for the previous list, then update our cache. + // required for the previous list, then update the internal nodes. // - // This grows/shrinks the bytes to accomodate the new tree, preserving as much of the tree + // Leaf nodes are not touched, they should be updated externally to this function. + // + // This grows/shrinks the bytes to accommodate the new tree, preserving as much of the tree // as possible. - if new_overlay.num_leaf_nodes() != old_overlay.num_leaf_nodes() { + if new_overlay.num_internal_nodes() != old_overlay.num_internal_nodes() { // Get slices of the existing tree from the cache. let (old_bytes, old_flags) = self .slices(old_overlay.internal_chunk_range()) .ok_or_else(|| Error::UnableToObtainSlices)?; let (new_bytes, new_flags) = if new_overlay.num_internal_nodes() == 0 { + // The new tree has zero internal nodes, simply return empty lists. (vec![], vec![]) } else if old_overlay.num_internal_nodes() == 0 { + // The old tree has zero nodes and the new tree has some nodes. Create new nodes to + // suit. let nodes = resize::nodes_in_tree_of_height(new_overlay.height() - 1); (vec![0; nodes * HASHSIZE], vec![true; nodes]) + } else if new_overlay.num_internal_nodes() > old_overlay.num_internal_nodes() { + // The new tree is bigger than the old tree. + // + // Grow the internal nodes, preserving any existing nodes. + resize::grow_merkle_tree( + old_bytes, + old_flags, + old_overlay.height() - 1, + new_overlay.height() - 1, + ) + .ok_or_else(|| Error::UnableToGrowMerkleTree)? } else { - if new_overlay.num_leaf_nodes() > old_overlay.num_leaf_nodes() { - resize::grow_merkle_tree( - old_bytes, - old_flags, - old_overlay.height() - 1, - new_overlay.height() - 1, - ) - .ok_or_else(|| Error::UnableToGrowMerkleTree)? - } else { - resize::shrink_merkle_tree( - old_bytes, - old_flags, - old_overlay.height() - 1, - new_overlay.height() - 1, - ) - .ok_or_else(|| Error::UnableToShrinkMerkleTree)? - } + // The new tree is smaller than the old tree. + // + // Shrink the internal nodes, preserving any existing nodes. + resize::shrink_merkle_tree( + old_bytes, + old_flags, + old_overlay.height() - 1, + new_overlay.height() - 1, + ) + .ok_or_else(|| Error::UnableToShrinkMerkleTree)? }; - assert_eq!(old_overlay.num_internal_nodes(), old_flags.len()); - assert_eq!(new_overlay.num_internal_nodes(), new_flags.len()); - - // Splice the resized created elements over the existing elements. + // Splice the resized created elements over the existing elements, effectively updating + // the number of stored internal nodes for this tree. self.splice(old_overlay.internal_chunk_range(), new_bytes, new_flags); } diff --git a/eth2/utils/tree_hash/src/impls.rs b/eth2/utils/tree_hash/src/impls.rs index e8485dc2ff..56eb7dbf49 100644 --- a/eth2/utils/tree_hash/src/impls.rs +++ b/eth2/utils/tree_hash/src/impls.rs @@ -19,6 +19,7 @@ macro_rules! impl_for_bitsize { HASHSIZE / ($bit_size / 8) } + #[allow(clippy::cast_lossless)] fn tree_hash_root(&self) -> Vec { int_to_bytes32(*self as u64) }