diff --git a/eth2/utils/cached_tree_hash/src/btree_overlay.rs b/eth2/utils/cached_tree_hash/src/btree_overlay.rs index 1a8fde3c1..866f5c6b7 100644 --- a/eth2/utils/cached_tree_hash/src/btree_overlay.rs +++ b/eth2/utils/cached_tree_hash/src/btree_overlay.rs @@ -4,33 +4,22 @@ use super::*; pub struct BTreeOverlay { pub offset: usize, pub depth: usize, - pub num_items: usize, pub lengths: Vec, } impl BTreeOverlay { - pub fn new(item: &T, initial_offset: usize, depth: usize) -> Result + pub fn new(item: &T, initial_offset: usize, depth: usize) -> Self where T: CachedTreeHash, { item.tree_hash_cache_overlay(initial_offset, depth) } - pub fn from_lengths( - offset: usize, - num_items: usize, - depth: usize, - lengths: Vec, - ) -> Result { - if lengths.is_empty() { - Err(Error::TreeCannotHaveZeroNodes) - } else { - Ok(Self { - offset, - num_items, - depth, - lengths, - }) + pub fn from_lengths(offset: usize, depth: usize, lengths: Vec) -> Self { + Self { + offset, + depth, + lengths, } } @@ -96,7 +85,7 @@ impl BTreeOverlay { pub fn get_leaf_node(&self, i: usize) -> Result>, Error> { if i >= self.num_nodes() - self.num_padding_leaves() { Ok(None) - } else if (i == self.num_internal_nodes()) && (self.num_items == 0) { + } else if (i == self.num_internal_nodes()) && (self.lengths.len() == 0) { // If this is the first leaf node and the overlay contains zero items, return `None` as // this node must be padding. Ok(None) @@ -177,7 +166,7 @@ mod test { use super::*; fn get_tree_a(n: usize) -> BTreeOverlay { - BTreeOverlay::from_lengths(0, n, 0, vec![1; n]).unwrap() + BTreeOverlay::from_lengths(0, 0, vec![1; n]) } #[test] @@ -215,7 +204,7 @@ mod test { let tree = get_tree_a(2); assert_eq!(tree.chunk_range(), 0..3); - let tree = BTreeOverlay::from_lengths(11, 4, 0, vec![1, 1]).unwrap(); + let tree = BTreeOverlay::from_lengths(11, 0, vec![1, 1]); assert_eq!(tree.chunk_range(), 11..14); } diff --git a/eth2/utils/cached_tree_hash/src/impls.rs b/eth2/utils/cached_tree_hash/src/impls.rs index 827b0fbe9..666461962 100644 --- a/eth2/utils/cached_tree_hash/src/impls.rs +++ b/eth2/utils/cached_tree_hash/src/impls.rs @@ -16,13 +16,8 @@ impl CachedTreeHash for u64 { 1 } - fn tree_hash_cache_overlay( - &self, - _chunk_offset: usize, - _depth: usize, - ) -> Result { - panic!("Basic should not produce overlay"); - // BTreeOverlay::from_lengths(chunk_offset, 1, depth, vec![1]) + fn tree_hash_cache_overlay(&self, _chunk_offset: usize, _depth: usize) -> BTreeOverlay { + unreachable!("Basic should not produce overlay"); } fn update_tree_hash_cache(&self, cache: &mut TreeHashCache) -> Result<(), Error> { @@ -49,13 +44,8 @@ impl CachedTreeHash for usize { 1 } - fn tree_hash_cache_overlay( - &self, - _chunk_offset: usize, - _depth: usize, - ) -> Result { - panic!("Basic should not produce overlay"); - // BTreeOverlay::from_lengths(chunk_offset, 1, depth, vec![1]) + fn tree_hash_cache_overlay(&self, _chunk_offset: usize, _depth: usize) -> BTreeOverlay { + unreachable!("Basic should not produce overlay"); } fn update_tree_hash_cache(&self, cache: &mut TreeHashCache) -> Result<(), Error> { diff --git a/eth2/utils/cached_tree_hash/src/impls/vec.rs b/eth2/utils/cached_tree_hash/src/impls/vec.rs index 14802254b..c37354404 100644 --- a/eth2/utils/cached_tree_hash/src/impls/vec.rs +++ b/eth2/utils/cached_tree_hash/src/impls/vec.rs @@ -14,17 +14,11 @@ where } fn num_tree_hash_cache_chunks(&self) -> usize { - BTreeOverlay::new(self, 0, 0) - .and_then(|o| Ok(o.num_chunks())) - .unwrap_or_else(|_| 1) - + 2 // Add two extra nodes to cater for the length. + // Add two extra nodes to cater for the node before and after to allow mixing-in length. + BTreeOverlay::new(self, 0, 0).num_chunks() + 2 } - fn tree_hash_cache_overlay( - &self, - chunk_offset: usize, - depth: usize, - ) -> Result { + fn tree_hash_cache_overlay(&self, chunk_offset: usize, depth: usize) -> BTreeOverlay { produce_overlay(self, chunk_offset, depth) } @@ -49,7 +43,7 @@ pub fn new_tree_hash_cache>( vec: &Vec, depth: usize, ) -> Result<(TreeHashCache, BTreeOverlay), Error> { - let overlay = vec.tree_hash_cache_overlay(0, depth)?; + let overlay = vec.tree_hash_cache_overlay(0, depth); let cache = match T::tree_hash_type() { TreeHashType::Basic => TreeHashCache::from_bytes( @@ -74,7 +68,7 @@ pub fn produce_overlay>( vec: &Vec, chunk_offset: usize, depth: usize, -) -> Result { +) -> BTreeOverlay { let lengths = match T::tree_hash_type() { TreeHashType::Basic => { // Ceil division. @@ -91,16 +85,11 @@ pub fn produce_overlay>( lengths.push(item.num_tree_hash_cache_chunks()) } - // Disallow zero-length as an empty list still has one all-padding node. - if lengths.is_empty() { - lengths.push(1); - } - lengths } }; - BTreeOverlay::from_lengths(chunk_offset, vec.len(), depth, lengths) + BTreeOverlay::from_lengths(chunk_offset, depth, lengths) } pub fn update_tree_hash_cache>( @@ -108,7 +97,7 @@ pub fn update_tree_hash_cache>( cache: &mut TreeHashCache, ) -> Result { let old_overlay = cache.get_overlay(cache.overlay_index, cache.chunk_index)?; - let new_overlay = BTreeOverlay::new(vec, cache.chunk_index, old_overlay.depth)?; + let new_overlay = BTreeOverlay::new(vec, cache.chunk_index, old_overlay.depth); cache.replace_overlay(cache.overlay_index, cache.chunk_index, new_overlay.clone())?; @@ -183,7 +172,7 @@ pub fn update_tree_hash_cache>( // // Viz., the list has been shortened. (Some(old), None) => { - if new_overlay.num_items == 0 { + if vec.len() == 0 { // In this case, the list has been made empty and we should make // this node padding. cache.maybe_update_chunk(new_overlay.root(), &[0; HASHSIZE])?; diff --git a/eth2/utils/cached_tree_hash/src/lib.rs b/eth2/utils/cached_tree_hash/src/lib.rs index d9f2b6a84..2cf3c38bd 100644 --- a/eth2/utils/cached_tree_hash/src/lib.rs +++ b/eth2/utils/cached_tree_hash/src/lib.rs @@ -14,11 +14,7 @@ pub use errors::Error; pub use tree_hash_cache::TreeHashCache; pub trait CachedTreeHash: TreeHash { - fn tree_hash_cache_overlay( - &self, - chunk_offset: usize, - depth: usize, - ) -> Result; + fn tree_hash_cache_overlay(&self, chunk_offset: usize, depth: usize) -> BTreeOverlay; fn num_tree_hash_cache_chunks(&self) -> usize; 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 d93278d30..2a9bae5a3 100644 --- a/eth2/utils/cached_tree_hash/src/tree_hash_cache.rs +++ b/eth2/utils/cached_tree_hash/src/tree_hash_cache.rs @@ -34,7 +34,7 @@ impl TreeHashCache { where T: CachedTreeHash, { - let overlay = BTreeOverlay::new(item, 0, depth)?; + let overlay = BTreeOverlay::new(item, 0, depth); // Note how many leaves were provided. If is not a power-of-two, we'll need to pad it out // later. diff --git a/eth2/utils/tree_hash_derive/src/lib.rs b/eth2/utils/tree_hash_derive/src/lib.rs index b6ba10e02..104cb8b32 100644 --- a/eth2/utils/tree_hash_derive/src/lib.rs +++ b/eth2/utils/tree_hash_derive/src/lib.rs @@ -55,8 +55,6 @@ pub fn subtree_derive(input: TokenStream) -> TokenStream { let idents_b = idents_a.clone(); let idents_c = idents_a.clone(); - let num_items = idents_a.len(); - let output = quote! { impl cached_tree_hash::CachedTreeHash<#name> for #name { fn new_tree_hash_cache(&self, depth: usize) -> Result { @@ -74,23 +72,21 @@ pub fn subtree_derive(input: TokenStream) -> TokenStream { } fn num_tree_hash_cache_chunks(&self) -> usize { - cached_tree_hash::BTreeOverlay::new(self, 0, 0) - .and_then(|o| Ok(o.num_chunks())) - .unwrap_or_else(|_| 1) + cached_tree_hash::BTreeOverlay::new(self, 0, 0).num_chunks() } - fn tree_hash_cache_overlay(&self, chunk_offset: usize, depth: usize) -> Result { + fn tree_hash_cache_overlay(&self, chunk_offset: usize, depth: usize) ->cached_tree_hash::BTreeOverlay { let mut lengths = vec![]; #( lengths.push(self.#idents_b.num_tree_hash_cache_chunks()); )* - cached_tree_hash::BTreeOverlay::from_lengths(chunk_offset, #num_items, depth, lengths) + cached_tree_hash::BTreeOverlay::from_lengths(chunk_offset, depth, lengths) } fn update_tree_hash_cache(&self, cache: &mut cached_tree_hash::TreeHashCache) -> Result<(), cached_tree_hash::Error> { - let overlay = cached_tree_hash::BTreeOverlay::new(self, cache.chunk_index, 0)?; + let overlay = cached_tree_hash::BTreeOverlay::new(self, cache.chunk_index, 0); // Skip the chunk index to the first leaf node of this struct. cache.chunk_index = overlay.first_leaf_node();