combine from_sized_iter and from_iter_with_depth methods
This commit is contained in:
parent
8374e07c4a
commit
5557a89538
1 changed files with 21 additions and 38 deletions
|
@ -47,9 +47,27 @@ impl SparseMerklePath {
|
|||
I: IntoIterator<IntoIter: ExactSizeIterator, Item = RpoDigest>,
|
||||
{
|
||||
let iterator = iterator.into_iter();
|
||||
// `iterator.len() as u8` will truncate, but not below `SMT_MAX_DEPTH`, which
|
||||
// `from_iter_with_depth` checks for.
|
||||
Self::from_iter_with_depth(iterator.len() as u8, iterator)
|
||||
let tree_depth = iterator.len() as u8;
|
||||
|
||||
if tree_depth > SMT_MAX_DEPTH {
|
||||
return Err(MerkleError::DepthTooBig(tree_depth as u64));
|
||||
}
|
||||
|
||||
let mut empty_nodes_mask: u64 = 0;
|
||||
let mut nodes: Vec<RpoDigest> = Default::default();
|
||||
|
||||
for (depth, node) in iter::zip(path_depth_iter(tree_depth), iterator) {
|
||||
let &equivalent_empty_node = EmptySubtreeRoots::entry(tree_depth, depth.get());
|
||||
let is_empty = node == equivalent_empty_node;
|
||||
let node = if is_empty { None } else { Some(node) };
|
||||
|
||||
match node {
|
||||
Some(node) => nodes.push(node),
|
||||
None => empty_nodes_mask |= Self::bitmask_for_depth(depth),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(SparseMerklePath { nodes, empty_nodes_mask })
|
||||
}
|
||||
|
||||
/// Returns the total depth of this path, i.e., the number of nodes this path represents.
|
||||
|
@ -114,41 +132,6 @@ impl SparseMerklePath {
|
|||
// PRIVATE HELPERS
|
||||
// ============================================================================================
|
||||
|
||||
/// Constructs a sparse Merkle path from a manually specified tree depth, and an iterator over
|
||||
/// Merkle nodes from deepest to shallowest.
|
||||
///
|
||||
/// Knowing the size is necessary to calculate the depth of the tree, which is needed to detect
|
||||
/// which nodes are empty nodes.
|
||||
///
|
||||
/// Warning: this method does not check if the iterator contained more elements.
|
||||
///
|
||||
/// # Errors
|
||||
/// Returns [MerkleError::DepthTooBig] if `tree_depth` is greater than [SMT_MAX_DEPTH].
|
||||
fn from_iter_with_depth(
|
||||
tree_depth: u8,
|
||||
iter: impl IntoIterator<Item = RpoDigest>,
|
||||
) -> Result<Self, MerkleError> {
|
||||
if tree_depth > SMT_MAX_DEPTH {
|
||||
return Err(MerkleError::DepthTooBig(tree_depth as u64));
|
||||
}
|
||||
|
||||
let mut empty_nodes_mask: u64 = 0;
|
||||
let mut nodes: Vec<RpoDigest> = Default::default();
|
||||
|
||||
for (depth, node) in iter::zip(path_depth_iter(tree_depth), iter) {
|
||||
let &equivalent_empty_node = EmptySubtreeRoots::entry(tree_depth, depth.get());
|
||||
let is_empty = node == equivalent_empty_node;
|
||||
let node = if is_empty { None } else { Some(node) };
|
||||
|
||||
match node {
|
||||
Some(node) => nodes.push(node),
|
||||
None => empty_nodes_mask |= Self::bitmask_for_depth(depth),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(SparseMerklePath { nodes, empty_nodes_mask })
|
||||
}
|
||||
|
||||
const fn bitmask_for_depth(node_depth: NonZero<u8>) -> u64 {
|
||||
// - 1 because paths do not include the root.
|
||||
1 << (node_depth.get() - 1)
|
||||
|
|
Loading…
Add table
Reference in a new issue