Tidy cache hash API
This commit is contained in:
parent
7b05c506df
commit
267c978abb
@ -11,16 +11,27 @@ const BYTES_PER_CHUNK: usize = 32;
|
|||||||
const HASHSIZE: usize = 32;
|
const HASHSIZE: usize = 32;
|
||||||
const MERKLE_HASH_CHUNCK: usize = 2 * BYTES_PER_CHUNK;
|
const MERKLE_HASH_CHUNCK: usize = 2 * BYTES_PER_CHUNK;
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
|
pub enum Error {
|
||||||
|
LeavesAndSubtreesIncomplete(usize),
|
||||||
|
ShouldNotProduceOffsetHandler,
|
||||||
|
NoFirstNode,
|
||||||
|
BytesAreNotEvenChunks(usize),
|
||||||
|
NoModifiedFieldForChunk(usize),
|
||||||
|
NoBytesForChunk(usize),
|
||||||
|
NoChildrenForHashing((usize, usize)),
|
||||||
|
}
|
||||||
|
|
||||||
pub trait CachedTreeHash {
|
pub trait CachedTreeHash {
|
||||||
type Item: CachedTreeHash;
|
type Item: CachedTreeHash;
|
||||||
|
|
||||||
fn build_cache_bytes(&self) -> Vec<u8>;
|
fn build_cache(&self) -> Result<TreeHashCache, Error>;
|
||||||
|
|
||||||
/// Return the number of bytes when this element is encoded as raw SSZ _without_ length
|
/// Return the number of bytes when this element is encoded as raw SSZ _without_ length
|
||||||
/// prefixes.
|
/// prefixes.
|
||||||
fn num_bytes(&self) -> usize;
|
fn num_bytes(&self) -> usize;
|
||||||
|
|
||||||
fn offset_handler(&self, initial_offset: usize) -> Option<OffsetHandler>;
|
fn offset_handler(&self, initial_offset: usize) -> Result<OffsetHandler, Error>;
|
||||||
|
|
||||||
fn num_child_nodes(&self) -> usize;
|
fn num_child_nodes(&self) -> usize;
|
||||||
|
|
||||||
@ -29,9 +40,10 @@ pub trait CachedTreeHash {
|
|||||||
other: &Self::Item,
|
other: &Self::Item,
|
||||||
cache: &mut TreeHashCache,
|
cache: &mut TreeHashCache,
|
||||||
chunk: usize,
|
chunk: usize,
|
||||||
) -> Option<usize>;
|
) -> Result<usize, Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct TreeHashCache {
|
pub struct TreeHashCache {
|
||||||
cache: Vec<u8>,
|
cache: Vec<u8>,
|
||||||
chunk_modified: Vec<bool>,
|
chunk_modified: Vec<bool>,
|
||||||
@ -44,11 +56,17 @@ impl Into<Vec<u8>> for TreeHashCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl TreeHashCache {
|
impl TreeHashCache {
|
||||||
pub fn new(mut leaves_and_subtrees: Vec<u8>, offset_handler: OffsetHandler) -> Option<Self> {
|
pub fn new<T>(item: &T) -> Result<Self, Error>
|
||||||
if leaves_and_subtrees.len() % BYTES_PER_CHUNK != 0 {
|
where
|
||||||
return None;
|
T: CachedTreeHash,
|
||||||
|
{
|
||||||
|
item.build_cache()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn from_leaves_and_subtrees(
|
||||||
|
mut leaves_and_subtrees: Vec<u8>,
|
||||||
|
offset_handler: OffsetHandler,
|
||||||
|
) -> Result<Self, Error> {
|
||||||
// Allocate enough bytes to store the internal nodes and the leaves and subtrees, then fill
|
// Allocate enough bytes to store the internal nodes and the leaves and subtrees, then fill
|
||||||
// all the to-be-built internal nodes with zeros and append the leaves and subtrees.
|
// all the to-be-built internal nodes with zeros and append the leaves and subtrees.
|
||||||
let internal_node_bytes = offset_handler.num_internal_nodes * BYTES_PER_CHUNK;
|
let internal_node_bytes = offset_handler.num_internal_nodes * BYTES_PER_CHUNK;
|
||||||
@ -56,13 +74,22 @@ impl TreeHashCache {
|
|||||||
cache.resize(internal_node_bytes, 0);
|
cache.resize(internal_node_bytes, 0);
|
||||||
cache.append(&mut leaves_and_subtrees);
|
cache.append(&mut leaves_and_subtrees);
|
||||||
|
|
||||||
|
dbg!(cache.len() / BYTES_PER_CHUNK);
|
||||||
|
|
||||||
// Concat all the leaves into one big byte array, ready for `merkleize`.
|
// Concat all the leaves into one big byte array, ready for `merkleize`.
|
||||||
let mut leaves = vec![];
|
let mut leaves = vec![];
|
||||||
for leaf_chunk in offset_handler.iter_leaf_nodes() {
|
for leaf_chunk in offset_handler.iter_leaf_nodes() {
|
||||||
let start = leaf_chunk * BYTES_PER_CHUNK;
|
let start = leaf_chunk * BYTES_PER_CHUNK;
|
||||||
let end = start + BYTES_PER_CHUNK;
|
let end = start + BYTES_PER_CHUNK;
|
||||||
|
|
||||||
leaves.extend_from_slice(cache.get(start..end)?);
|
dbg!(end);
|
||||||
|
dbg!(cache.len());
|
||||||
|
|
||||||
|
leaves.extend_from_slice(
|
||||||
|
cache
|
||||||
|
.get(start..end)
|
||||||
|
.ok_or_else(|| Error::LeavesAndSubtreesIncomplete(*leaf_chunk))?,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Merkleize the leaves, then split the leaf nodes off them. Then, replace all-zeros
|
// Merkleize the leaves, then split the leaf nodes off them. Then, replace all-zeros
|
||||||
@ -71,18 +98,18 @@ impl TreeHashCache {
|
|||||||
merkleized.split_off(internal_node_bytes);
|
merkleized.split_off(internal_node_bytes);
|
||||||
cache.splice(0..internal_node_bytes, merkleized);
|
cache.splice(0..internal_node_bytes, merkleized);
|
||||||
|
|
||||||
Some(Self {
|
Ok(Self {
|
||||||
chunk_modified: vec![false; cache.len() / BYTES_PER_CHUNK],
|
chunk_modified: vec![false; cache.len() / BYTES_PER_CHUNK],
|
||||||
cache,
|
cache,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_bytes(bytes: Vec<u8>) -> Option<Self> {
|
pub fn from_bytes(bytes: Vec<u8>) -> Result<Self, Error> {
|
||||||
if bytes.len() % BYTES_PER_CHUNK > 0 {
|
if bytes.len() % BYTES_PER_CHUNK > 0 {
|
||||||
return None;
|
return Err(Error::BytesAreNotEvenChunks(bytes.len()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(Self {
|
Ok(Self {
|
||||||
chunk_modified: vec![false; bytes.len() / BYTES_PER_CHUNK],
|
chunk_modified: vec![false; bytes.len() / BYTES_PER_CHUNK],
|
||||||
cache: bytes,
|
cache: bytes,
|
||||||
})
|
})
|
||||||
@ -121,15 +148,18 @@ impl TreeHashCache {
|
|||||||
Some(())
|
Some(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn modify_chunk(&mut self, chunk: usize, to: &[u8]) -> Option<()> {
|
pub fn modify_chunk(&mut self, chunk: usize, to: &[u8]) -> Result<(), Error> {
|
||||||
let start = chunk * BYTES_PER_CHUNK;
|
let start = chunk * BYTES_PER_CHUNK;
|
||||||
let end = start + BYTES_PER_CHUNK;
|
let end = start + BYTES_PER_CHUNK;
|
||||||
|
|
||||||
self.cache.get_mut(start..end)?.copy_from_slice(to);
|
self.cache
|
||||||
|
.get_mut(start..end)
|
||||||
|
.ok_or_else(|| Error::NoBytesForChunk(chunk))?
|
||||||
|
.copy_from_slice(to);
|
||||||
|
|
||||||
self.chunk_modified[chunk] = true;
|
self.chunk_modified[chunk] = true;
|
||||||
|
|
||||||
Some(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn chunk_equals(&mut self, chunk: usize, other: &[u8]) -> Option<bool> {
|
pub fn chunk_equals(&mut self, chunk: usize, other: &[u8]) -> Option<bool> {
|
||||||
@ -139,57 +169,30 @@ impl TreeHashCache {
|
|||||||
Some(self.cache.get(start..end)? == other)
|
Some(self.cache.get(start..end)? == other)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn changed(&self, chunk: usize) -> Option<bool> {
|
pub fn changed(&self, chunk: usize) -> Result<bool, Error> {
|
||||||
self.chunk_modified.get(chunk).cloned()
|
self.chunk_modified
|
||||||
|
.get(chunk)
|
||||||
|
.cloned()
|
||||||
|
.ok_or_else(|| Error::NoModifiedFieldForChunk(chunk))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn either_modified(&self, children: (&usize, &usize)) -> Option<bool> {
|
pub fn either_modified(&self, children: (&usize, &usize)) -> Result<bool, Error> {
|
||||||
Some(self.changed(*children.0)? | self.changed(*children.1)?)
|
Ok(self.changed(*children.0)? | self.changed(*children.1)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
pub fn hash_children(&self, children: (&usize, &usize)) -> Result<Vec<u8>, Error> {
|
||||||
pub fn children_modified(&self, parent_chunk: usize, child_offsets: &[usize]) -> Option<bool> {
|
|
||||||
let children = children(parent_chunk);
|
|
||||||
|
|
||||||
let a = *child_offsets.get(children.0)?;
|
|
||||||
let b = *child_offsets.get(children.1)?;
|
|
||||||
|
|
||||||
Some(self.changed(a)? | self.changed(b)?)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
pub fn hash_children(&self, children: (&usize, &usize)) -> Option<Vec<u8>> {
|
|
||||||
let start = children.0 * BYTES_PER_CHUNK;
|
let start = children.0 * BYTES_PER_CHUNK;
|
||||||
let end = start + BYTES_PER_CHUNK * 2;
|
let end = start + BYTES_PER_CHUNK * 2;
|
||||||
|
|
||||||
Some(hash(&self.cache.get(start..end)?))
|
let children = &self
|
||||||
}
|
.cache
|
||||||
}
|
.get(start..end)
|
||||||
|
.ok_or_else(|| Error::NoChildrenForHashing((*children.0, *children.1)))?;
|
||||||
|
|
||||||
/*
|
Ok(hash(children))
|
||||||
pub struct LocalCache {
|
|
||||||
offsets: Vec<usize>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LocalCache {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct OffsetBTree {
|
|
||||||
offsets: Vec<usize>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Vec<usize>> for OffsetBTree {
|
|
||||||
fn from(offsets: Vec<usize>) -> Self {
|
|
||||||
Self { offsets }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OffsetBTree {
|
|
||||||
fn
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
fn children(parent: usize) -> (usize, usize) {
|
fn children(parent: usize) -> (usize, usize) {
|
||||||
((2 * parent + 1), (2 * parent + 2))
|
((2 * parent + 1), (2 * parent + 2))
|
||||||
}
|
}
|
||||||
@ -206,7 +209,7 @@ pub struct OffsetHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl OffsetHandler {
|
impl OffsetHandler {
|
||||||
fn from_lengths(offset: usize, mut lengths: Vec<usize>) -> Self {
|
fn from_lengths(offset: usize, mut lengths: Vec<usize>) -> Result<Self, Error> {
|
||||||
// Extend it to the next power-of-two, if it is not already.
|
// Extend it to the next power-of-two, if it is not already.
|
||||||
let num_leaf_nodes = if lengths.len().is_power_of_two() {
|
let num_leaf_nodes = if lengths.len().is_power_of_two() {
|
||||||
lengths.len()
|
lengths.len()
|
||||||
@ -228,20 +231,23 @@ impl OffsetHandler {
|
|||||||
next_node += lengths[i];
|
next_node += lengths[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
Self {
|
Ok(Self {
|
||||||
num_internal_nodes,
|
num_internal_nodes,
|
||||||
num_leaf_nodes,
|
num_leaf_nodes,
|
||||||
offsets,
|
offsets,
|
||||||
next_node,
|
next_node,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn total_nodes(&self) -> usize {
|
pub fn total_nodes(&self) -> usize {
|
||||||
self.num_internal_nodes + self.num_leaf_nodes
|
self.num_internal_nodes + self.num_leaf_nodes
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn first_leaf_node(&self) -> Option<usize> {
|
pub fn first_leaf_node(&self) -> Result<usize, Error> {
|
||||||
self.offsets.get(self.num_internal_nodes).cloned()
|
self.offsets
|
||||||
|
.get(self.num_internal_nodes)
|
||||||
|
.cloned()
|
||||||
|
.ok_or_else(|| Error::NoFirstNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next_node(&self) -> usize {
|
pub fn next_node(&self) -> usize {
|
||||||
@ -314,6 +320,15 @@ pub fn sanitise_bytes(mut bytes: Vec<u8>) -> Vec<u8> {
|
|||||||
bytes
|
bytes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn pad_for_leaf_count(num_leaves: usize, bytes: &mut Vec<u8>) {
|
||||||
|
let required_leaves = num_leaves.next_power_of_two();
|
||||||
|
|
||||||
|
bytes.resize(
|
||||||
|
bytes.len() + (required_leaves - num_leaves) * BYTES_PER_CHUNK,
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
fn last_leaf_needs_padding(num_bytes: usize) -> bool {
|
fn last_leaf_needs_padding(num_bytes: usize) -> bool {
|
||||||
num_bytes % HASHSIZE != 0
|
num_bytes % HASHSIZE != 0
|
||||||
}
|
}
|
||||||
|
@ -4,16 +4,16 @@ use crate::{ssz_encode, Encodable};
|
|||||||
impl CachedTreeHash for u64 {
|
impl CachedTreeHash for u64 {
|
||||||
type Item = Self;
|
type Item = Self;
|
||||||
|
|
||||||
fn build_cache_bytes(&self) -> Vec<u8> {
|
fn build_cache(&self) -> Result<TreeHashCache, Error> {
|
||||||
merkleize(ssz_encode(self))
|
TreeHashCache::from_bytes(merkleize(ssz_encode(self)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn num_bytes(&self) -> usize {
|
fn num_bytes(&self) -> usize {
|
||||||
8
|
8
|
||||||
}
|
}
|
||||||
|
|
||||||
fn offset_handler(&self, _initial_offset: usize) -> Option<OffsetHandler> {
|
fn offset_handler(&self, _initial_offset: usize) -> Result<OffsetHandler, Error> {
|
||||||
None
|
Err(Error::ShouldNotProduceOffsetHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn num_child_nodes(&self) -> usize {
|
fn num_child_nodes(&self) -> usize {
|
||||||
@ -25,13 +25,13 @@ impl CachedTreeHash for u64 {
|
|||||||
other: &Self,
|
other: &Self,
|
||||||
cache: &mut TreeHashCache,
|
cache: &mut TreeHashCache,
|
||||||
chunk: usize,
|
chunk: usize,
|
||||||
) -> Option<usize> {
|
) -> Result<usize, Error> {
|
||||||
if self != other {
|
if self != other {
|
||||||
let leaf = merkleize(ssz_encode(self));
|
let leaf = merkleize(ssz_encode(self));
|
||||||
cache.modify_chunk(chunk, &leaf)?;
|
cache.modify_chunk(chunk, &leaf)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(chunk + 1)
|
Ok(chunk + 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use int_to_bytes::{int_to_bytes32, int_to_bytes8};
|
use int_to_bytes::int_to_bytes32;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Inner {
|
pub struct Inner {
|
||||||
@ -12,21 +12,19 @@ pub struct Inner {
|
|||||||
impl CachedTreeHash for Inner {
|
impl CachedTreeHash for Inner {
|
||||||
type Item = Self;
|
type Item = Self;
|
||||||
|
|
||||||
fn build_cache_bytes(&self) -> Vec<u8> {
|
fn build_cache(&self) -> Result<TreeHashCache, Error> {
|
||||||
|
let offset_handler = self.offset_handler(0)?;
|
||||||
|
|
||||||
let mut leaves_and_subtrees = vec![];
|
let mut leaves_and_subtrees = vec![];
|
||||||
|
|
||||||
leaves_and_subtrees.append(&mut self.a.build_cache_bytes());
|
leaves_and_subtrees.append(&mut self.a.build_cache()?.into());
|
||||||
leaves_and_subtrees.append(&mut self.b.build_cache_bytes());
|
leaves_and_subtrees.append(&mut self.b.build_cache()?.into());
|
||||||
leaves_and_subtrees.append(&mut self.c.build_cache_bytes());
|
leaves_and_subtrees.append(&mut self.c.build_cache()?.into());
|
||||||
leaves_and_subtrees.append(&mut self.d.build_cache_bytes());
|
leaves_and_subtrees.append(&mut self.d.build_cache()?.into());
|
||||||
|
|
||||||
// TODO: fix unwrap
|
pad_for_leaf_count(offset_handler.num_leaf_nodes, &mut leaves_and_subtrees);
|
||||||
let offset_handler = self.offset_handler(0).unwrap();
|
|
||||||
|
|
||||||
// TODO: fix unwrap
|
TreeHashCache::from_leaves_and_subtrees(leaves_and_subtrees, self.offset_handler(0)?)
|
||||||
let cache = TreeHashCache::new(leaves_and_subtrees, offset_handler).unwrap();
|
|
||||||
|
|
||||||
cache.into()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn num_bytes(&self) -> usize {
|
fn num_bytes(&self) -> usize {
|
||||||
@ -40,7 +38,7 @@ impl CachedTreeHash for Inner {
|
|||||||
bytes
|
bytes
|
||||||
}
|
}
|
||||||
|
|
||||||
fn offset_handler(&self, initial_offset: usize) -> Option<OffsetHandler> {
|
fn offset_handler(&self, initial_offset: usize) -> Result<OffsetHandler, Error> {
|
||||||
let mut offsets = vec![];
|
let mut offsets = vec![];
|
||||||
|
|
||||||
offsets.push(self.a.num_child_nodes() + 1);
|
offsets.push(self.a.num_child_nodes() + 1);
|
||||||
@ -48,7 +46,7 @@ impl CachedTreeHash for Inner {
|
|||||||
offsets.push(self.c.num_child_nodes() + 1);
|
offsets.push(self.c.num_child_nodes() + 1);
|
||||||
offsets.push(self.d.num_child_nodes() + 1);
|
offsets.push(self.d.num_child_nodes() + 1);
|
||||||
|
|
||||||
Some(OffsetHandler::from_lengths(initial_offset, offsets))
|
OffsetHandler::from_lengths(initial_offset, offsets)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn num_child_nodes(&self) -> usize {
|
fn num_child_nodes(&self) -> usize {
|
||||||
@ -68,7 +66,7 @@ impl CachedTreeHash for Inner {
|
|||||||
other: &Self,
|
other: &Self,
|
||||||
cache: &mut TreeHashCache,
|
cache: &mut TreeHashCache,
|
||||||
chunk: usize,
|
chunk: usize,
|
||||||
) -> Option<usize> {
|
) -> Result<usize, Error> {
|
||||||
let offset_handler = self.offset_handler(chunk)?;
|
let offset_handler = self.offset_handler(chunk)?;
|
||||||
|
|
||||||
// Skip past the internal nodes and update any changed leaf nodes.
|
// Skip past the internal nodes and update any changed leaf nodes.
|
||||||
@ -86,7 +84,7 @@ impl CachedTreeHash for Inner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(offset_handler.next_node())
|
Ok(offset_handler.next_node())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,20 +98,18 @@ pub struct Outer {
|
|||||||
impl CachedTreeHash for Outer {
|
impl CachedTreeHash for Outer {
|
||||||
type Item = Self;
|
type Item = Self;
|
||||||
|
|
||||||
fn build_cache_bytes(&self) -> Vec<u8> {
|
fn build_cache(&self) -> Result<TreeHashCache, Error> {
|
||||||
|
let offset_handler = self.offset_handler(0)?;
|
||||||
|
|
||||||
let mut leaves_and_subtrees = vec![];
|
let mut leaves_and_subtrees = vec![];
|
||||||
|
|
||||||
leaves_and_subtrees.append(&mut self.a.build_cache_bytes());
|
leaves_and_subtrees.append(&mut self.a.build_cache()?.into());
|
||||||
leaves_and_subtrees.append(&mut self.b.build_cache_bytes());
|
leaves_and_subtrees.append(&mut self.b.build_cache()?.into());
|
||||||
leaves_and_subtrees.append(&mut self.c.build_cache_bytes());
|
leaves_and_subtrees.append(&mut self.c.build_cache()?.into());
|
||||||
|
|
||||||
// TODO: fix unwrap
|
pad_for_leaf_count(offset_handler.num_leaf_nodes, &mut leaves_and_subtrees);
|
||||||
let offset_handler = self.offset_handler(0).unwrap();
|
|
||||||
|
|
||||||
// TODO: fix unwrap
|
TreeHashCache::from_leaves_and_subtrees(leaves_and_subtrees, self.offset_handler(0)?)
|
||||||
let cache = TreeHashCache::new(leaves_and_subtrees, offset_handler).unwrap();
|
|
||||||
|
|
||||||
cache.into()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn num_bytes(&self) -> usize {
|
fn num_bytes(&self) -> usize {
|
||||||
@ -135,14 +131,14 @@ impl CachedTreeHash for Outer {
|
|||||||
num_nodes(leaves) + children - 1
|
num_nodes(leaves) + children - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
fn offset_handler(&self, initial_offset: usize) -> Option<OffsetHandler> {
|
fn offset_handler(&self, initial_offset: usize) -> Result<OffsetHandler, Error> {
|
||||||
let mut offsets = vec![];
|
let mut offsets = vec![];
|
||||||
|
|
||||||
offsets.push(self.a.num_child_nodes() + 1);
|
offsets.push(self.a.num_child_nodes() + 1);
|
||||||
offsets.push(self.b.num_child_nodes() + 1);
|
offsets.push(self.b.num_child_nodes() + 1);
|
||||||
offsets.push(self.c.num_child_nodes() + 1);
|
offsets.push(self.c.num_child_nodes() + 1);
|
||||||
|
|
||||||
Some(OffsetHandler::from_lengths(initial_offset, offsets))
|
OffsetHandler::from_lengths(initial_offset, offsets)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cached_hash_tree_root(
|
fn cached_hash_tree_root(
|
||||||
@ -150,7 +146,7 @@ impl CachedTreeHash for Outer {
|
|||||||
other: &Self,
|
other: &Self,
|
||||||
cache: &mut TreeHashCache,
|
cache: &mut TreeHashCache,
|
||||||
chunk: usize,
|
chunk: usize,
|
||||||
) -> Option<usize> {
|
) -> Result<usize, Error> {
|
||||||
let offset_handler = self.offset_handler(chunk)?;
|
let offset_handler = self.offset_handler(chunk)?;
|
||||||
|
|
||||||
// Skip past the internal nodes and update any changed leaf nodes.
|
// Skip past the internal nodes and update any changed leaf nodes.
|
||||||
@ -167,7 +163,7 @@ impl CachedTreeHash for Outer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(offset_handler.next_node())
|
Ok(offset_handler.next_node())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,17 +195,16 @@ fn partial_modification_to_inner_struct() {
|
|||||||
..original_inner.clone()
|
..original_inner.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
// Build the initial cache.
|
|
||||||
let original_cache = original_outer.build_cache_bytes();
|
|
||||||
|
|
||||||
// Modify outer
|
// Modify outer
|
||||||
let modified_outer = Outer {
|
let modified_outer = Outer {
|
||||||
b: modified_inner.clone(),
|
b: modified_inner.clone(),
|
||||||
..original_outer.clone()
|
..original_outer.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
println!("AAAAAAAAA");
|
||||||
// Perform a differential hash
|
// Perform a differential hash
|
||||||
let mut cache_struct = TreeHashCache::from_bytes(original_cache.clone()).unwrap();
|
let mut cache_struct = TreeHashCache::new(&original_outer).unwrap();
|
||||||
|
println!("BBBBBBBBBB");
|
||||||
|
|
||||||
modified_outer
|
modified_outer
|
||||||
.cached_hash_tree_root(&original_outer, &mut cache_struct, 0)
|
.cached_hash_tree_root(&original_outer, &mut cache_struct, 0)
|
||||||
@ -220,7 +215,7 @@ fn partial_modification_to_inner_struct() {
|
|||||||
// Generate reference data.
|
// Generate reference data.
|
||||||
let mut data = vec![];
|
let mut data = vec![];
|
||||||
data.append(&mut int_to_bytes32(0));
|
data.append(&mut int_to_bytes32(0));
|
||||||
let inner_bytes = modified_inner.build_cache_bytes();
|
let inner_bytes: Vec<u8> = TreeHashCache::new(&modified_inner).unwrap().into();
|
||||||
data.append(&mut int_to_bytes32(5));
|
data.append(&mut int_to_bytes32(5));
|
||||||
|
|
||||||
let leaves = vec![
|
let leaves = vec![
|
||||||
@ -254,7 +249,7 @@ fn partial_modification_to_outer() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Build the initial cache.
|
// Build the initial cache.
|
||||||
let original_cache = original_outer.build_cache_bytes();
|
// let original_cache = original_outer.build_cache_bytes();
|
||||||
|
|
||||||
// Modify outer
|
// Modify outer
|
||||||
let modified_outer = Outer {
|
let modified_outer = Outer {
|
||||||
@ -263,7 +258,7 @@ fn partial_modification_to_outer() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Perform a differential hash
|
// Perform a differential hash
|
||||||
let mut cache_struct = TreeHashCache::from_bytes(original_cache.clone()).unwrap();
|
let mut cache_struct = TreeHashCache::new(&original_outer).unwrap();
|
||||||
|
|
||||||
modified_outer
|
modified_outer
|
||||||
.cached_hash_tree_root(&original_outer, &mut cache_struct, 0)
|
.cached_hash_tree_root(&original_outer, &mut cache_struct, 0)
|
||||||
@ -274,7 +269,7 @@ fn partial_modification_to_outer() {
|
|||||||
// Generate reference data.
|
// Generate reference data.
|
||||||
let mut data = vec![];
|
let mut data = vec![];
|
||||||
data.append(&mut int_to_bytes32(0));
|
data.append(&mut int_to_bytes32(0));
|
||||||
let inner_bytes = inner.build_cache_bytes();
|
let inner_bytes: Vec<u8> = TreeHashCache::new(&inner).unwrap().into();
|
||||||
data.append(&mut int_to_bytes32(5));
|
data.append(&mut int_to_bytes32(5));
|
||||||
|
|
||||||
let leaves = vec![
|
let leaves = vec![
|
||||||
@ -308,12 +303,12 @@ fn outer_builds() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Build the function output.
|
// Build the function output.
|
||||||
let cache = outer.build_cache_bytes();
|
let cache: Vec<u8> = TreeHashCache::new(&outer).unwrap().into();
|
||||||
|
|
||||||
// Generate reference data.
|
// Generate reference data.
|
||||||
let mut data = vec![];
|
let mut data = vec![];
|
||||||
data.append(&mut int_to_bytes32(0));
|
data.append(&mut int_to_bytes32(0));
|
||||||
let inner_bytes = inner.build_cache_bytes();
|
let inner_bytes: Vec<u8> = inner.build_cache().unwrap().into();
|
||||||
data.append(&mut int_to_bytes32(5));
|
data.append(&mut int_to_bytes32(5));
|
||||||
|
|
||||||
let leaves = vec![
|
let leaves = vec![
|
||||||
@ -427,7 +422,7 @@ fn generic_test(index: usize) {
|
|||||||
d: 4,
|
d: 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
let cache = inner.build_cache_bytes();
|
let cache: Vec<u8> = TreeHashCache::new(&inner).unwrap().into();
|
||||||
|
|
||||||
let changed_inner = match index {
|
let changed_inner = match index {
|
||||||
0 => Inner {
|
0 => Inner {
|
||||||
@ -498,7 +493,7 @@ fn inner_builds() {
|
|||||||
d: 4,
|
d: 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
let cache = inner.build_cache_bytes();
|
let cache: Vec<u8> = TreeHashCache::new(&inner).unwrap().into();
|
||||||
|
|
||||||
assert_eq!(expected, cache);
|
assert_eq!(expected, cache);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user