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 {
|
impl CachedTreeHasher {
|
||||||
pub fn new<T>(item: &T) -> Result<Self, Error>
|
pub fn new<T>(item: &T) -> Result<Self, Error>
|
||||||
where
|
where
|
||||||
T: CachedTreeHashSubTree<T>,
|
T: CachedTreeHash<T>,
|
||||||
{
|
{
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
cache: TreeHashCache::new(item, 0)?,
|
cache: TreeHashCache::new(item, 0)?,
|
||||||
@ -28,7 +28,7 @@ impl CachedTreeHasher {
|
|||||||
|
|
||||||
pub fn update<T>(&mut self, item: &T) -> Result<(), Error>
|
pub fn update<T>(&mut self, item: &T) -> Result<(), Error>
|
||||||
where
|
where
|
||||||
T: CachedTreeHashSubTree<T>,
|
T: CachedTreeHash<T>,
|
||||||
{
|
{
|
||||||
// Reset the per-hash counters.
|
// Reset the per-hash counters.
|
||||||
self.cache.chunk_index = 0;
|
self.cache.chunk_index = 0;
|
||||||
@ -66,15 +66,7 @@ pub enum Error {
|
|||||||
NotLeafNode(usize),
|
NotLeafNode(usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait CachedTreeHash<T>: CachedTreeHashSubTree<T> + Sized {
|
pub trait CachedTreeHash<Item>: TreeHash {
|
||||||
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 {
|
|
||||||
fn tree_hash_cache_overlay(
|
fn tree_hash_cache_overlay(
|
||||||
&self,
|
&self,
|
||||||
chunk_offset: usize,
|
chunk_offset: usize,
|
||||||
|
@ -11,7 +11,7 @@ pub struct BTreeOverlay {
|
|||||||
impl BTreeOverlay {
|
impl BTreeOverlay {
|
||||||
pub fn new<T>(item: &T, initial_offset: usize, depth: usize) -> Result<Self, Error>
|
pub fn new<T>(item: &T, initial_offset: usize, depth: usize) -> Result<Self, Error>
|
||||||
where
|
where
|
||||||
T: CachedTreeHashSubTree<T>,
|
T: CachedTreeHash<T>,
|
||||||
{
|
{
|
||||||
item.tree_hash_cache_overlay(initial_offset, depth)
|
item.tree_hash_cache_overlay(initial_offset, depth)
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ use super::*;
|
|||||||
|
|
||||||
mod vec;
|
mod vec;
|
||||||
|
|
||||||
impl CachedTreeHashSubTree<u64> for u64 {
|
impl CachedTreeHash<u64> for u64 {
|
||||||
fn new_tree_hash_cache(&self, _depth: usize) -> Result<TreeHashCache, Error> {
|
fn new_tree_hash_cache(&self, _depth: usize) -> Result<TreeHashCache, Error> {
|
||||||
Ok(TreeHashCache::from_bytes(
|
Ok(TreeHashCache::from_bytes(
|
||||||
merkleize(self.to_le_bytes().to_vec()),
|
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> {
|
fn new_tree_hash_cache(&self, _depth: usize) -> Result<TreeHashCache, Error> {
|
||||||
Ok(TreeHashCache::from_bytes(
|
Ok(TreeHashCache::from_bytes(
|
||||||
merkleize(self.to_le_bytes().to_vec()),
|
merkleize(self.to_le_bytes().to_vec()),
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
impl<T> CachedTreeHashSubTree<Vec<T>> for Vec<T>
|
impl<T> CachedTreeHash<Vec<T>> for Vec<T>
|
||||||
where
|
where
|
||||||
T: CachedTreeHashSubTree<T> + TreeHash,
|
T: CachedTreeHash<T> + TreeHash,
|
||||||
{
|
{
|
||||||
fn new_tree_hash_cache(&self, depth: usize) -> Result<TreeHashCache, Error> {
|
fn new_tree_hash_cache(&self, depth: usize) -> Result<TreeHashCache, Error> {
|
||||||
let mut overlay = self.tree_hash_cache_overlay(0, depth)?;
|
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>
|
fn get_packed_leaves<T>(vec: &Vec<T>) -> Result<Vec<u8>, Error>
|
||||||
where
|
where
|
||||||
T: CachedTreeHashSubTree<T>,
|
T: CachedTreeHash<T>,
|
||||||
{
|
{
|
||||||
let num_packed_bytes = (BYTES_PER_CHUNK / T::tree_hash_packing_factor()) * vec.len();
|
let num_packed_bytes = (BYTES_PER_CHUNK / T::tree_hash_packing_factor()) * vec.len();
|
||||||
let num_leaves = num_sanitized_leaves(num_packed_bytes);
|
let num_leaves = num_sanitized_leaves(num_packed_bytes);
|
||||||
|
@ -19,7 +19,7 @@ impl Into<Vec<u8>> for TreeHashCache {
|
|||||||
impl TreeHashCache {
|
impl TreeHashCache {
|
||||||
pub fn new<T>(item: &T, depth: usize) -> Result<Self, Error>
|
pub fn new<T>(item: &T, depth: usize) -> Result<Self, Error>
|
||||||
where
|
where
|
||||||
T: CachedTreeHashSubTree<T>,
|
T: CachedTreeHash<T>,
|
||||||
{
|
{
|
||||||
item.new_tree_hash_cache(depth)
|
item.new_tree_hash_cache(depth)
|
||||||
}
|
}
|
||||||
@ -30,7 +30,7 @@ impl TreeHashCache {
|
|||||||
depth: usize,
|
depth: usize,
|
||||||
) -> Result<Self, Error>
|
) -> Result<Self, Error>
|
||||||
where
|
where
|
||||||
T: CachedTreeHashSubTree<T>,
|
T: CachedTreeHash<T>,
|
||||||
{
|
{
|
||||||
let overlay = BTreeOverlay::new(item, 0, depth)?;
|
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 HASHSIZE: usize = 32;
|
||||||
pub const MERKLE_HASH_CHUNCK: usize = 2 * BYTES_PER_CHUNK;
|
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 signed_root::SignedRoot;
|
||||||
pub use standard_tree_hash::{merkle_root, TreeHash};
|
pub use standard_tree_hash::{merkle_root, TreeHash};
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use int_to_bytes::int_to_bytes32;
|
use int_to_bytes::int_to_bytes32;
|
||||||
use tree_hash::cached_tree_hash::*;
|
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 struct NestedStruct {
|
||||||
pub a: u64,
|
pub a: u64,
|
||||||
pub b: Inner,
|
pub b: Inner,
|
||||||
@ -10,7 +10,7 @@ pub struct NestedStruct {
|
|||||||
|
|
||||||
fn test_routine<T>(original: T, modified: Vec<T>)
|
fn test_routine<T>(original: T, modified: Vec<T>)
|
||||||
where
|
where
|
||||||
T: CachedTreeHashSubTree<T>,
|
T: CachedTreeHash<T>,
|
||||||
{
|
{
|
||||||
let mut hasher = CachedTreeHasher::new(&original).unwrap();
|
let mut hasher = CachedTreeHasher::new(&original).unwrap();
|
||||||
|
|
||||||
@ -113,7 +113,7 @@ fn test_nested_list_of_u64() {
|
|||||||
test_routine(original, modified);
|
test_routine(original, modified);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, TreeHash, CachedTreeHashSubTree)]
|
#[derive(Clone, Debug, TreeHash, CachedTreeHash)]
|
||||||
pub struct StructWithVec {
|
pub struct StructWithVec {
|
||||||
pub a: u64,
|
pub a: u64,
|
||||||
pub b: Inner,
|
pub b: Inner,
|
||||||
@ -224,7 +224,7 @@ fn test_vec_of_struct_with_vec() {
|
|||||||
test_routine(original, modified);
|
test_routine(original, modified);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, TreeHash, CachedTreeHashSubTree)]
|
#[derive(Clone, Debug, TreeHash, CachedTreeHash)]
|
||||||
pub struct StructWithVecOfStructs {
|
pub struct StructWithVecOfStructs {
|
||||||
pub a: u64,
|
pub a: u64,
|
||||||
pub b: Inner,
|
pub b: Inner,
|
||||||
@ -302,7 +302,7 @@ fn test_struct_with_vec_of_structs() {
|
|||||||
test_routine(f, variants);
|
test_routine(f, variants);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, TreeHash, CachedTreeHashSubTree)]
|
#[derive(Clone, Debug, TreeHash, CachedTreeHash)]
|
||||||
pub struct Inner {
|
pub struct Inner {
|
||||||
pub a: u64,
|
pub a: u64,
|
||||||
pub b: u64,
|
pub b: u64,
|
||||||
@ -481,7 +481,7 @@ fn works_when_embedded() {
|
|||||||
assert_eq!(&merkle[0..32], &root[..]);
|
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> {
|
fn new_tree_hash_cache(&self) -> Result<TreeHashCache, Error> {
|
||||||
let tree = TreeHashCache::from_leaves_and_subtrees(
|
let tree = TreeHashCache::from_leaves_and_subtrees(
|
||||||
self,
|
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> {
|
fn new_tree_hash_cache(&self) -> Result<TreeHashCache, Error> {
|
||||||
let tree = TreeHashCache::from_leaves_and_subtrees(
|
let tree = TreeHashCache::from_leaves_and_subtrees(
|
||||||
self,
|
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> {
|
fn new_tree_hash_cache(&self) -> Result<TreeHashCache, Error> {
|
||||||
let tree = TreeHashCache::from_leaves_and_subtrees(
|
let tree = TreeHashCache::from_leaves_and_subtrees(
|
||||||
self,
|
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 ) ]")
|
.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.
|
/// 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 {
|
pub fn subtree_derive(input: TokenStream) -> TokenStream {
|
||||||
let item = parse_macro_input!(input as DeriveInput);
|
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 num_items = idents_a.len();
|
||||||
|
|
||||||
let output = quote! {
|
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> {
|
fn new_tree_hash_cache(&self, depth: usize) -> Result<tree_hash::TreeHashCache, tree_hash::Error> {
|
||||||
let tree = tree_hash::TreeHashCache::from_leaves_and_subtrees(
|
let tree = tree_hash::TreeHashCache::from_leaves_and_subtrees(
|
||||||
self,
|
self,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use tree_hash::{CachedTreeHashSubTree, SignedRoot, TreeHash};
|
use tree_hash::{CachedTreeHash, SignedRoot, TreeHash};
|
||||||
use tree_hash_derive::{CachedTreeHashSubTree, SignedRoot, TreeHash};
|
use tree_hash_derive::{CachedTreeHash, SignedRoot, TreeHash};
|
||||||
|
|
||||||
#[derive(Clone, Debug, TreeHash, CachedTreeHashSubTree)]
|
#[derive(Clone, Debug, TreeHash, CachedTreeHash)]
|
||||||
pub struct Inner {
|
pub struct Inner {
|
||||||
pub a: u64,
|
pub a: u64,
|
||||||
pub b: u64,
|
pub b: u64,
|
||||||
@ -11,7 +11,7 @@ pub struct Inner {
|
|||||||
|
|
||||||
fn test_standard_and_cached<T>(original: &T, modified: &T)
|
fn test_standard_and_cached<T>(original: &T, modified: &T)
|
||||||
where
|
where
|
||||||
T: CachedTreeHashSubTree<T>,
|
T: CachedTreeHash<T>,
|
||||||
{
|
{
|
||||||
let mut cache = original.new_tree_hash_cache().unwrap();
|
let mut cache = original.new_tree_hash_cache().unwrap();
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ fn inner_standard_vs_cached() {
|
|||||||
test_standard_and_cached(&original, &modified);
|
test_standard_and_cached(&original, &modified);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, TreeHash, CachedTreeHashSubTree)]
|
#[derive(Clone, Debug, TreeHash, CachedTreeHash)]
|
||||||
pub struct Uneven {
|
pub struct Uneven {
|
||||||
pub a: u64,
|
pub a: u64,
|
||||||
pub b: u64,
|
pub b: u64,
|
||||||
|
Loading…
Reference in New Issue
Block a user