Add mix-in-len to cached tree hash
This commit is contained in:
		
							parent
							
								
									0632a00a48
								
							
						
					
					
						commit
						ab78a15313
					
				| @ -1,4 +1,5 @@ | ||||
| use hashing::hash; | ||||
| use int_to_bytes::int_to_bytes32; | ||||
| use std::fmt::Debug; | ||||
| use std::iter::Iterator; | ||||
| use std::ops::Range; | ||||
| @ -231,6 +232,15 @@ impl TreeHashCache { | ||||
|         Ok(hash(&child_bytes)) | ||||
|     } | ||||
| 
 | ||||
|     pub fn mix_in_length(&self, chunk: usize, length: usize) -> Result<Vec<u8>, Error> { | ||||
|         let mut bytes = Vec::with_capacity(2 * BYTES_PER_CHUNK); | ||||
| 
 | ||||
|         bytes.append(&mut self.get_chunk(chunk)?.to_vec()); | ||||
|         bytes.append(&mut int_to_bytes32(length as u64)); | ||||
| 
 | ||||
|         Ok(hash(&bytes)) | ||||
|     } | ||||
| 
 | ||||
|     pub fn into_merkle_tree(self) -> Vec<u8> { | ||||
|         self.cache | ||||
|     } | ||||
| @ -300,6 +310,10 @@ impl OffsetHandler { | ||||
|         }) | ||||
|     } | ||||
| 
 | ||||
|     pub fn root(&self) -> usize { | ||||
|         self.first_node | ||||
|     } | ||||
| 
 | ||||
|     pub fn height(&self) -> usize { | ||||
|         self.num_leaf_nodes.trailing_zeros() as usize | ||||
|     } | ||||
|  | ||||
| @ -212,6 +212,12 @@ where | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // If the root node or the length has changed, mix in the length of the list.
 | ||||
|         let root_node = offset_handler.root(); | ||||
|         if cache.changed(root_node)? | (self.len() != other.len()) { | ||||
|             cache.modify_chunk(root_node, &cache.mix_in_length(root_node, self.len())?)?; | ||||
|         } | ||||
| 
 | ||||
|         Ok(offset_handler.next_node()) | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -343,6 +343,13 @@ fn outer_builds() { | ||||
|     assert_eq!(merkle, cache); | ||||
| } | ||||
| 
 | ||||
| fn mix_in_length(root: &mut [u8], len: usize) { | ||||
|     let mut bytes = root.to_vec(); | ||||
|     bytes.append(&mut int_to_bytes32(len as u64)); | ||||
| 
 | ||||
|     root.copy_from_slice(&hash(&bytes)); | ||||
| } | ||||
| 
 | ||||
| /// Generic test that covers:
 | ||||
| ///
 | ||||
| /// 1. Produce a new cache from `original`.
 | ||||
| @ -367,7 +374,9 @@ fn test_u64_vec_modifications(original: Vec<u64>, modified: Vec<u64>) { | ||||
|         data.append(&mut int_to_bytes8(*i)); | ||||
|     } | ||||
|     let data = sanitise_bytes(data); | ||||
|     let expected = merkleize(data); | ||||
|     let mut expected = merkleize(data); | ||||
| 
 | ||||
|     mix_in_length(&mut expected[0..HASHSIZE], modified.len()); | ||||
| 
 | ||||
|     assert_eq!(expected, modified_cache); | ||||
| } | ||||
| @ -490,6 +499,8 @@ fn test_inner_vec_modifications(original: Vec<Inner>, modified: Vec<Inner>, refe | ||||
|         expected.append(&mut vec![0; HASHSIZE]); | ||||
|     } | ||||
| 
 | ||||
|     mix_in_length(&mut expected[0..HASHSIZE], modified.len()); | ||||
| 
 | ||||
|     // Compare the cached tree to the reference tree.
 | ||||
|     assert_trees_eq(&expected, &modified_cache); | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user