Add tree hash cache as field to BeaconState.

This commit is contained in:
Paul Hauner
2019-04-27 19:02:52 +10:00
parent b70ebd09ea
commit 6c9be1a73c
5 changed files with 110 additions and 14 deletions

View File

@@ -9,6 +9,7 @@ pub enum Error {
UnableToGrowMerkleTree,
UnableToShrinkMerkleTree,
TreeCannotHaveZeroNodes,
CacheNotInitialized,
ShouldNeverBePacked(TreeHashType),
BytesAreNotEvenChunks(usize),
NoModifiedFieldForChunk(usize),

View File

@@ -45,17 +45,7 @@ impl CachedTreeHasher {
where
T: CachedTreeHash<T>,
{
// Reset the per-hash counters.
self.cache.chunk_index = 0;
self.cache.schema_index = 0;
// Reset the "modified" flags for the cache.
self.cache.reset_modifications();
// Update the cache with the (maybe) changed object.
item.update_tree_hash_cache(&mut self.cache)?;
Ok(())
self.cache.update(item)
}
pub fn tree_hash_root(&self) -> Result<Vec<u8>, Error> {

View File

@@ -12,6 +12,18 @@ pub struct TreeHashCache {
pub schema_index: usize,
}
impl Default for TreeHashCache {
fn default() -> TreeHashCache {
TreeHashCache {
cache: vec![],
chunk_modified: vec![],
schemas: vec![],
chunk_index: 0,
schema_index: 0,
}
}
}
impl Into<Vec<u8>> for TreeHashCache {
fn into(self) -> Vec<u8> {
self.cache
@@ -26,6 +38,24 @@ impl TreeHashCache {
item.new_tree_hash_cache(depth)
}
pub fn update<T>(&mut self, item: &T) -> Result<(), Error>
where
T: CachedTreeHash<T>,
{
if self.is_empty() {
Err(Error::CacheNotInitialized)
} else {
// Reset the per-hash counters.
self.chunk_index = 0;
self.schema_index = 0;
// Reset the "modified" flags for the cache.
self.reset_modifications();
item.update_tree_hash_cache(self)
}
}
pub fn from_leaves_and_subtrees<T>(
item: &T,
leaves_and_subtrees: Vec<Self>,
@@ -108,6 +138,10 @@ impl TreeHashCache {
})
}
pub fn is_empty(&self) -> bool {
self.chunk_modified.is_empty()
}
pub fn get_overlay(
&self,
schema_index: usize,
@@ -210,9 +244,13 @@ impl TreeHashCache {
}
pub fn root(&self) -> Result<&[u8], Error> {
self.cache
.get(0..HASHSIZE)
.ok_or_else(|| Error::NoBytesForRoot)
if self.is_empty() {
Err(Error::CacheNotInitialized)
} else {
self.cache
.get(0..HASHSIZE)
.ok_or_else(|| Error::NoBytesForRoot)
}
}
pub fn splice(&mut self, chunk_range: Range<usize>, bytes: Vec<u8>, bools: Vec<bool>) {