mirror of
https://gitlab.com/pulsechaincom/lighthouse-pulse.git
synced 2024-12-25 21:17:17 +00:00
Add failing test for grow merkle tree
This commit is contained in:
parent
1ce1fce03c
commit
e038bd18b5
@ -16,6 +16,8 @@ pub enum Error {
|
|||||||
ShouldNotProduceOffsetHandler,
|
ShouldNotProduceOffsetHandler,
|
||||||
NoFirstNode,
|
NoFirstNode,
|
||||||
NoBytesForRoot,
|
NoBytesForRoot,
|
||||||
|
UnableToObtainSlices,
|
||||||
|
UnableToGrowMerkleTree,
|
||||||
BytesAreNotEvenChunks(usize),
|
BytesAreNotEvenChunks(usize),
|
||||||
NoModifiedFieldForChunk(usize),
|
NoModifiedFieldForChunk(usize),
|
||||||
NoBytesForChunk(usize),
|
NoBytesForChunk(usize),
|
||||||
@ -74,6 +76,13 @@ impl TreeHashCache {
|
|||||||
item.build_tree_hash_cache()
|
item.build_tree_hash_cache()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn from_elems(cache: Vec<u8>, chunk_modified: Vec<bool>) -> Self {
|
||||||
|
Self {
|
||||||
|
cache,
|
||||||
|
chunk_modified,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn from_leaves_and_subtrees<T>(
|
pub fn from_leaves_and_subtrees<T>(
|
||||||
item: &T,
|
item: &T,
|
||||||
leaves_and_subtrees: Vec<Self>,
|
leaves_and_subtrees: Vec<Self>,
|
||||||
@ -149,7 +158,7 @@ impl TreeHashCache {
|
|||||||
// Update the `chunk_modified` vec, marking all spliced-in nodes as changed.
|
// Update the `chunk_modified` vec, marking all spliced-in nodes as changed.
|
||||||
self.chunk_modified.splice(chunk_range.clone(), bools);
|
self.chunk_modified.splice(chunk_range.clone(), bools);
|
||||||
self.cache
|
self.cache
|
||||||
.splice(node_range_to_byte_range(chunk_range), bytes);
|
.splice(node_range_to_byte_range(&chunk_range), bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn maybe_update_chunk(&mut self, chunk: usize, to: &[u8]) -> Result<(), Error> {
|
pub fn maybe_update_chunk(&mut self, chunk: usize, to: &[u8]) -> Result<(), Error> {
|
||||||
@ -167,6 +176,13 @@ impl TreeHashCache {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn slices(&self, chunk_range: Range<usize>) -> Option<(&[u8], &[bool])> {
|
||||||
|
Some((
|
||||||
|
self.cache.get(node_range_to_byte_range(&chunk_range))?,
|
||||||
|
self.chunk_modified.get(chunk_range)?,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn modify_chunk(&mut self, chunk: usize, to: &[u8]) -> Result<(), Error> {
|
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;
|
||||||
@ -231,7 +247,7 @@ fn num_nodes(num_leaves: usize) -> usize {
|
|||||||
2 * num_leaves - 1
|
2 * num_leaves - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
fn node_range_to_byte_range(node_range: Range<usize>) -> Range<usize> {
|
fn node_range_to_byte_range(node_range: &Range<usize>) -> Range<usize> {
|
||||||
node_range.start * HASHSIZE..node_range.end * HASHSIZE
|
node_range.start * HASHSIZE..node_range.end * HASHSIZE
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,6 +297,10 @@ impl OffsetHandler {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn node_range(&self) -> Result<Range<usize>, Error> {
|
||||||
|
Ok(*self.offsets.first().ok_or_else(|| Error::NoFirstNode)?..self.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
|
||||||
}
|
}
|
||||||
|
@ -113,9 +113,27 @@ where
|
|||||||
) -> Result<usize, Error> {
|
) -> Result<usize, Error> {
|
||||||
let offset_handler = OffsetHandler::new(self, chunk)?;
|
let offset_handler = OffsetHandler::new(self, chunk)?;
|
||||||
|
|
||||||
if other.len().next_power_of_two() > self.len().next_power_of_two() {
|
if self.len().next_power_of_two() > other.len().next_power_of_two() {
|
||||||
//
|
// Get slices of the exsiting tree from the cache.
|
||||||
} else if other.len().next_power_of_two() < self.len().next_power_of_two() {
|
let (old_bytes, old_flags) = cache
|
||||||
|
.slices(offset_handler.node_range()?)
|
||||||
|
.ok_or_else(|| Error::UnableToObtainSlices)?;
|
||||||
|
|
||||||
|
// From the existing slices build new, expanded Vecs.
|
||||||
|
let (new_bytes, new_flags) = grow_merkle_cache(
|
||||||
|
old_bytes,
|
||||||
|
old_flags,
|
||||||
|
other.len().next_power_of_two().leading_zeros() as usize,
|
||||||
|
self.len().next_power_of_two().leading_zeros() as usize,
|
||||||
|
).ok_or_else(|| Error::UnableToGrowMerkleTree)?;
|
||||||
|
|
||||||
|
// Create a `TreeHashCache` from the raw elements.
|
||||||
|
let expanded_cache = TreeHashCache::from_elems(new_bytes, new_flags);
|
||||||
|
|
||||||
|
// Splice the newly created `TreeHashCache` over the existing, smaller elements.
|
||||||
|
cache.splice(offset_handler.node_range()?, expanded_cache);
|
||||||
|
//
|
||||||
|
} else if self.len().next_power_of_two() < other.len().next_power_of_two() {
|
||||||
panic!("shrinking below power of two is not implemented")
|
panic!("shrinking below power of two is not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,7 +408,6 @@ fn extended_u64_vec_len_within_pow_2_boundary() {
|
|||||||
test_u64_vec_modifications(original_vec, modified_vec);
|
test_u64_vec_modifications(original_vec, modified_vec);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
#[test]
|
#[test]
|
||||||
fn extended_u64_vec_len_outside_pow_2_boundary() {
|
fn extended_u64_vec_len_outside_pow_2_boundary() {
|
||||||
let original_vec: Vec<u64> = (0..2_u64.pow(5)).collect();
|
let original_vec: Vec<u64> = (0..2_u64.pow(5)).collect();
|
||||||
@ -417,7 +416,6 @@ fn extended_u64_vec_len_outside_pow_2_boundary() {
|
|||||||
|
|
||||||
test_u64_vec_modifications(original_vec, modified_vec);
|
test_u64_vec_modifications(original_vec, modified_vec);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn large_vec_of_u64_builds() {
|
fn large_vec_of_u64_builds() {
|
||||||
|
Loading…
Reference in New Issue
Block a user