Rename CachedTreeHash trait, add readme
				
					
				
			This commit is contained in:
		
							parent
							
								
									7563755b15
								
							
						
					
					
						commit
						cab5e59a6f
					
				
							
								
								
									
										76
									
								
								eth2/utils/tree_hash/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								eth2/utils/tree_hash/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,76 @@ | ||||
| # Tree hashing | ||||
| 
 | ||||
| Provides both cached and non-cached tree hashing methods. | ||||
| 
 | ||||
| ## Standard Tree Hash | ||||
| 
 | ||||
| ```rust | ||||
| use tree_hash_derive::TreeHash; | ||||
| 
 | ||||
| #[derive(TreeHash)] | ||||
| struct Foo { | ||||
| 	a: u64, | ||||
| 	b: Vec<u64>, | ||||
| } | ||||
| 
 | ||||
| fn main() { | ||||
| 	let foo = Foo { | ||||
| 		a: 42, | ||||
| 		b: vec![1, 2, 3] | ||||
| 	} | ||||
| 
 | ||||
| 	println!("root: {}", foo.tree_hash_root()); | ||||
| } | ||||
| ``` | ||||
| 
 | ||||
| ## Cached Tree Hash | ||||
| 
 | ||||
| 
 | ||||
| ```rust | ||||
| use tree_hash_derive::{TreeHash, CachedTreeHash}; | ||||
| 
 | ||||
| #[derive(TreeHash, CachedTreeHash)] | ||||
| struct Foo { | ||||
| 	a: u64, | ||||
| 	b: Vec<u64>, | ||||
| } | ||||
| 
 | ||||
| #[derive(TreeHash, CachedTreeHash)] | ||||
| struct Bar { | ||||
| 	a: Vec<Foo>, | ||||
| 	b: u64, | ||||
| } | ||||
| 
 | ||||
| fn main() { | ||||
| 	let bar = Bar { | ||||
| 		a: vec![ | ||||
| 			Foo { | ||||
| 				a: 42, | ||||
| 				b: vec![1, 2, 3] | ||||
| 			} | ||||
| 		], | ||||
| 		b: 42 | ||||
| 	}; | ||||
| 
 | ||||
| 	let modified_bar = Bar { | ||||
| 		a: vec![ | ||||
| 			Foo { | ||||
| 				a: 100, | ||||
| 				b: vec![1, 2, 3, 4, 5, 6] | ||||
| 			} | ||||
| 			Foo { | ||||
| 				a: 42, | ||||
| 				b: vec![] | ||||
| 			} | ||||
| 		], | ||||
| 		b: 99 | ||||
| 	}; | ||||
| 
 | ||||
| 
 | ||||
|     let mut hasher = CachedTreeHasher::new(&bar).unwrap(); | ||||
| 	hasher.update(&modified_bar); | ||||
| 
 | ||||
| 	// Assert that the cached tree hash matches a standard tree hash. | ||||
| 	assert_eq!(hasher.tree_hash_root(), modified_bar.tree_hash_root()); | ||||
| } | ||||
| ``` | ||||
| @ -19,7 +19,7 @@ pub struct CachedTreeHasher { | ||||
| impl CachedTreeHasher { | ||||
|     pub fn new<T>(item: &T) -> Result<Self, Error> | ||||
|     where | ||||
|         T: CachedTreeHashSubTree<T>, | ||||
|         T: CachedTreeHash<T>, | ||||
|     { | ||||
|         Ok(Self { | ||||
|             cache: TreeHashCache::new(item, 0)?, | ||||
| @ -28,7 +28,7 @@ impl CachedTreeHasher { | ||||
| 
 | ||||
|     pub fn update<T>(&mut self, item: &T) -> Result<(), Error> | ||||
|     where | ||||
|         T: CachedTreeHashSubTree<T>, | ||||
|         T: CachedTreeHash<T>, | ||||
|     { | ||||
|         // Reset the per-hash counters.
 | ||||
|         self.cache.chunk_index = 0; | ||||
| @ -66,15 +66,7 @@ pub enum Error { | ||||
|     NotLeafNode(usize), | ||||
| } | ||||
| 
 | ||||
| pub trait CachedTreeHash<T>: CachedTreeHashSubTree<T> + Sized { | ||||
|     fn update_internal_tree_hash_cache(self, old: T) -> Result<(Self, Self), Error>; | ||||
| 
 | ||||
|     fn cached_tree_hash_root(&self) -> Option<Vec<u8>>; | ||||
| 
 | ||||
|     fn clone_without_tree_hash_cache(&self) -> Self; | ||||
| } | ||||
| 
 | ||||
| pub trait CachedTreeHashSubTree<Item>: TreeHash { | ||||
| pub trait CachedTreeHash<Item>: TreeHash { | ||||
|     fn tree_hash_cache_overlay( | ||||
|         &self, | ||||
|         chunk_offset: usize, | ||||
|  | ||||
| @ -11,7 +11,7 @@ pub struct BTreeOverlay { | ||||
| impl BTreeOverlay { | ||||
|     pub fn new<T>(item: &T, initial_offset: usize, depth: usize) -> Result<Self, Error> | ||||
|     where | ||||
|         T: CachedTreeHashSubTree<T>, | ||||
|         T: CachedTreeHash<T>, | ||||
|     { | ||||
|         item.tree_hash_cache_overlay(initial_offset, depth) | ||||
|     } | ||||
|  | ||||
| @ -2,7 +2,7 @@ use super::*; | ||||
| 
 | ||||
| mod vec; | ||||
| 
 | ||||
| impl CachedTreeHashSubTree<u64> for u64 { | ||||
| impl CachedTreeHash<u64> for u64 { | ||||
|     fn new_tree_hash_cache(&self, _depth: usize) -> Result<TreeHashCache, Error> { | ||||
|         Ok(TreeHashCache::from_bytes( | ||||
|             merkleize(self.to_le_bytes().to_vec()), | ||||
| @ -35,7 +35,7 @@ impl CachedTreeHashSubTree<u64> for u64 { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl CachedTreeHashSubTree<usize> for usize { | ||||
| impl CachedTreeHash<usize> for usize { | ||||
|     fn new_tree_hash_cache(&self, _depth: usize) -> Result<TreeHashCache, Error> { | ||||
|         Ok(TreeHashCache::from_bytes( | ||||
|             merkleize(self.to_le_bytes().to_vec()), | ||||
|  | ||||
| @ -1,8 +1,8 @@ | ||||
| use super::*; | ||||
| 
 | ||||
| impl<T> CachedTreeHashSubTree<Vec<T>> for Vec<T> | ||||
| impl<T> CachedTreeHash<Vec<T>> for Vec<T> | ||||
| where | ||||
|     T: CachedTreeHashSubTree<T> + TreeHash, | ||||
|     T: CachedTreeHash<T> + TreeHash, | ||||
| { | ||||
|     fn new_tree_hash_cache(&self, depth: usize) -> Result<TreeHashCache, Error> { | ||||
|         let mut overlay = self.tree_hash_cache_overlay(0, depth)?; | ||||
| @ -186,7 +186,7 @@ where | ||||
| 
 | ||||
| fn get_packed_leaves<T>(vec: &Vec<T>) -> Result<Vec<u8>, Error> | ||||
| where | ||||
|     T: CachedTreeHashSubTree<T>, | ||||
|     T: CachedTreeHash<T>, | ||||
| { | ||||
|     let num_packed_bytes = (BYTES_PER_CHUNK / T::tree_hash_packing_factor()) * vec.len(); | ||||
|     let num_leaves = num_sanitized_leaves(num_packed_bytes); | ||||
|  | ||||
| @ -19,7 +19,7 @@ impl Into<Vec<u8>> for TreeHashCache { | ||||
| impl TreeHashCache { | ||||
|     pub fn new<T>(item: &T, depth: usize) -> Result<Self, Error> | ||||
|     where | ||||
|         T: CachedTreeHashSubTree<T>, | ||||
|         T: CachedTreeHash<T>, | ||||
|     { | ||||
|         item.new_tree_hash_cache(depth) | ||||
|     } | ||||
| @ -30,7 +30,7 @@ impl TreeHashCache { | ||||
|         depth: usize, | ||||
|     ) -> Result<Self, Error> | ||||
|     where | ||||
|         T: CachedTreeHashSubTree<T>, | ||||
|         T: CachedTreeHash<T>, | ||||
|     { | ||||
|         let overlay = BTreeOverlay::new(item, 0, depth)?; | ||||
| 
 | ||||
|  | ||||
| @ -6,7 +6,7 @@ pub const BYTES_PER_CHUNK: usize = 32; | ||||
| pub const HASHSIZE: usize = 32; | ||||
| pub const MERKLE_HASH_CHUNCK: usize = 2 * BYTES_PER_CHUNK; | ||||
| 
 | ||||
| pub use cached_tree_hash::{BTreeOverlay, CachedTreeHashSubTree, Error, TreeHashCache}; | ||||
| pub use cached_tree_hash::{BTreeOverlay, CachedTreeHash, Error, TreeHashCache}; | ||||
| pub use signed_root::SignedRoot; | ||||
| pub use standard_tree_hash::{merkle_root, TreeHash}; | ||||
| 
 | ||||
|  | ||||
| @ -1,8 +1,8 @@ | ||||
| use int_to_bytes::int_to_bytes32; | ||||
| use tree_hash::cached_tree_hash::*; | ||||
| use tree_hash_derive::{CachedTreeHashSubTree, TreeHash}; | ||||
| use tree_hash_derive::{CachedTreeHash, TreeHash}; | ||||
| 
 | ||||
| #[derive(Clone, Debug, TreeHash, CachedTreeHashSubTree)] | ||||
| #[derive(Clone, Debug, TreeHash, CachedTreeHash)] | ||||
| pub struct NestedStruct { | ||||
|     pub a: u64, | ||||
|     pub b: Inner, | ||||
| @ -10,7 +10,7 @@ pub struct NestedStruct { | ||||
| 
 | ||||
| fn test_routine<T>(original: T, modified: Vec<T>) | ||||
| where | ||||
|     T: CachedTreeHashSubTree<T>, | ||||
|     T: CachedTreeHash<T>, | ||||
| { | ||||
|     let mut hasher = CachedTreeHasher::new(&original).unwrap(); | ||||
| 
 | ||||
| @ -113,7 +113,7 @@ fn test_nested_list_of_u64() { | ||||
|     test_routine(original, modified); | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, Debug, TreeHash, CachedTreeHashSubTree)] | ||||
| #[derive(Clone, Debug, TreeHash, CachedTreeHash)] | ||||
| pub struct StructWithVec { | ||||
|     pub a: u64, | ||||
|     pub b: Inner, | ||||
| @ -224,7 +224,7 @@ fn test_vec_of_struct_with_vec() { | ||||
|     test_routine(original, modified); | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, Debug, TreeHash, CachedTreeHashSubTree)] | ||||
| #[derive(Clone, Debug, TreeHash, CachedTreeHash)] | ||||
| pub struct StructWithVecOfStructs { | ||||
|     pub a: u64, | ||||
|     pub b: Inner, | ||||
| @ -302,7 +302,7 @@ fn test_struct_with_vec_of_structs() { | ||||
|     test_routine(f, variants); | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, Debug, TreeHash, CachedTreeHashSubTree)] | ||||
| #[derive(Clone, Debug, TreeHash, CachedTreeHash)] | ||||
| pub struct Inner { | ||||
|     pub a: u64, | ||||
|     pub b: u64, | ||||
| @ -481,7 +481,7 @@ fn works_when_embedded() { | ||||
|     assert_eq!(&merkle[0..32], &root[..]); | ||||
| } | ||||
| 
 | ||||
| impl CachedTreeHashSubTree<InternalCache> for InternalCache { | ||||
| impl CachedTreeHash<InternalCache> for InternalCache { | ||||
|     fn new_tree_hash_cache(&self) -> Result<TreeHashCache, Error> { | ||||
|         let tree = TreeHashCache::from_leaves_and_subtrees( | ||||
|             self, | ||||
| @ -562,7 +562,7 @@ impl TreeHash for Inner { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl CachedTreeHashSubTree<Inner> for Inner { | ||||
| impl CachedTreeHash<Inner> for Inner { | ||||
|     fn new_tree_hash_cache(&self) -> Result<TreeHashCache, Error> { | ||||
|         let tree = TreeHashCache::from_leaves_and_subtrees( | ||||
|             self, | ||||
| @ -646,7 +646,7 @@ impl TreeHash for Outer { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl CachedTreeHashSubTree<Outer> for Outer { | ||||
| impl CachedTreeHash<Outer> for Outer { | ||||
|     fn new_tree_hash_cache(&self) -> Result<TreeHashCache, Error> { | ||||
|         let tree = TreeHashCache::from_leaves_and_subtrees( | ||||
|             self, | ||||
|  | ||||
| @ -37,10 +37,10 @@ fn should_skip_hashing(field: &syn::Field) -> bool { | ||||
|         .any(|attr| attr.into_token_stream().to_string() == "# [ tree_hash ( skip_hashing ) ]") | ||||
| } | ||||
| 
 | ||||
| /// Implements `tree_hash::CachedTreeHashSubTree` for some `struct`.
 | ||||
| /// Implements `tree_hash::CachedTreeHash` for some `struct`.
 | ||||
| ///
 | ||||
| /// Fields are hashed in the order they are defined.
 | ||||
| #[proc_macro_derive(CachedTreeHashSubTree, attributes(tree_hash))] | ||||
| #[proc_macro_derive(CachedTreeHash, attributes(tree_hash))] | ||||
| pub fn subtree_derive(input: TokenStream) -> TokenStream { | ||||
|     let item = parse_macro_input!(input as DeriveInput); | ||||
| 
 | ||||
| @ -58,7 +58,7 @@ pub fn subtree_derive(input: TokenStream) -> TokenStream { | ||||
|     let num_items = idents_a.len(); | ||||
| 
 | ||||
|     let output = quote! { | ||||
|         impl tree_hash::CachedTreeHashSubTree<#name> for #name { | ||||
|         impl tree_hash::CachedTreeHash<#name> for #name { | ||||
|             fn new_tree_hash_cache(&self, depth: usize) -> Result<tree_hash::TreeHashCache, tree_hash::Error> { | ||||
|                 let tree = tree_hash::TreeHashCache::from_leaves_and_subtrees( | ||||
|                     self, | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| use tree_hash::{CachedTreeHashSubTree, SignedRoot, TreeHash}; | ||||
| use tree_hash_derive::{CachedTreeHashSubTree, SignedRoot, TreeHash}; | ||||
| use tree_hash::{CachedTreeHash, SignedRoot, TreeHash}; | ||||
| use tree_hash_derive::{CachedTreeHash, SignedRoot, TreeHash}; | ||||
| 
 | ||||
| #[derive(Clone, Debug, TreeHash, CachedTreeHashSubTree)] | ||||
| #[derive(Clone, Debug, TreeHash, CachedTreeHash)] | ||||
| pub struct Inner { | ||||
|     pub a: u64, | ||||
|     pub b: u64, | ||||
| @ -11,7 +11,7 @@ pub struct Inner { | ||||
| 
 | ||||
| fn test_standard_and_cached<T>(original: &T, modified: &T) | ||||
| where | ||||
|     T: CachedTreeHashSubTree<T>, | ||||
|     T: CachedTreeHash<T>, | ||||
| { | ||||
|     let mut cache = original.new_tree_hash_cache().unwrap(); | ||||
| 
 | ||||
| @ -44,7 +44,7 @@ fn inner_standard_vs_cached() { | ||||
|     test_standard_and_cached(&original, &modified); | ||||
| } | ||||
| 
 | ||||
| #[derive(Clone, Debug, TreeHash, CachedTreeHashSubTree)] | ||||
| #[derive(Clone, Debug, TreeHash, CachedTreeHash)] | ||||
| pub struct Uneven { | ||||
|     pub a: u64, | ||||
|     pub b: u64, | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user