convert (col, hash) tuples to a dedicated struct

This commit is contained in:
Qyriad 2024-10-28 14:57:36 -06:00
parent d23cce314e
commit d0098e1eb4
5 changed files with 24 additions and 27 deletions

View file

@ -3,7 +3,7 @@ use std::{fmt::Debug, hint, mem, time::Duration};
use criterion::{criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion};
use miden_crypto::{
hash::rpo::RpoDigest,
merkle::{NodeIndex, Smt, SmtLeaf, SMT_DEPTH},
merkle::{NodeIndex, Smt, SmtLeaf, SubtreeLeaf, SMT_DEPTH},
Felt, Word, ONE,
};
use rand_utils::prng_array;
@ -43,11 +43,11 @@ fn smt_subtree_even(c: &mut Criterion) {
let leaf = SmtLeaf::new_single(*key, *value);
let col = NodeIndex::from(leaf.index()).value();
let hash = leaf.hash();
(col, hash)
SubtreeLeaf { col, hash }
})
.collect();
leaves.sort();
leaves.dedup_by_key(|leaf| leaf.0);
leaves.dedup_by_key(|leaf| leaf.col);
leaves
},
|leaves| {
@ -93,7 +93,7 @@ fn smt_subtree_random(c: &mut Criterion) {
let leaf = SmtLeaf::new_single(*key, *value);
let col = NodeIndex::from(leaf.index()).value();
let hash = leaf.hash();
(col, hash)
SubtreeLeaf { col, hash }
})
.collect();
leaves.sort();

View file

@ -23,7 +23,7 @@ pub use path::{MerklePath, RootPath, ValuePath};
mod smt;
pub use smt::{
LeafIndex, MutationSet, SimpleSmt, Smt, SmtLeaf, SmtLeafError, SmtProof, SmtProofError,
SMT_DEPTH, SMT_MAX_DEPTH, SMT_MIN_DEPTH,
SubtreeLeaf, SMT_DEPTH, SMT_MAX_DEPTH, SMT_MIN_DEPTH,
};
mod mmr;

View file

@ -6,7 +6,7 @@ use alloc::{
use super::{
EmptySubtreeRoots, Felt, InnerNode, InnerNodeInfo, LeafIndex, MerkleError, MerklePath,
MutationSet, NodeIndex, Rpo256, RpoDigest, SparseMerkleTree, Word, EMPTY_WORD,
MutationSet, NodeIndex, Rpo256, RpoDigest, SparseMerkleTree, SubtreeLeaf, Word, EMPTY_WORD,
};
mod error;
@ -251,9 +251,9 @@ impl Smt {
}
pub fn build_subtree(
leaves: Vec<(u64, RpoDigest)>,
leaves: Vec<SubtreeLeaf>,
bottom_depth: u8,
) -> (BTreeMap<NodeIndex, InnerNode>, Vec<(u64, RpoDigest)>) {
) -> (BTreeMap<NodeIndex, InnerNode>, Vec<SubtreeLeaf>) {
<Self as SparseMerkleTree<SMT_DEPTH>>::build_subtree(leaves, bottom_depth)
}
}

View file

@ -357,11 +357,10 @@ pub(crate) trait SparseMerkleTree<const DEPTH: u8> {
/// more entries than can fit in a depth-8 subtree (more than 256), if `bottom_depth` is
/// lower in the tree than the specified maximum depth (`DEPTH`), or if `leaves` is not sorted.
// FIXME: more complete docstring.
#[cfg_attr(not(test), allow(dead_code))]
fn build_subtree(
mut leaves: Vec<(u64, RpoDigest)>,
mut leaves: Vec<SubtreeLeaf>,
bottom_depth: u8,
) -> (BTreeMap<NodeIndex, InnerNode>, Vec<(u64, RpoDigest)>) {
) -> (BTreeMap<NodeIndex, InnerNode>, Vec<SubtreeLeaf>) {
debug_assert!(bottom_depth <= DEPTH);
debug_assert!(bottom_depth.is_multiple_of(&8));
debug_assert!(leaves.len() <= usize::pow(2, 8));
@ -370,7 +369,7 @@ pub(crate) trait SparseMerkleTree<const DEPTH: u8> {
let mut inner_nodes: BTreeMap<NodeIndex, InnerNode> = Default::default();
let mut next_leaves: Vec<(u64, RpoDigest)> = Vec::with_capacity(leaves.len() / 2);
let mut next_leaves: Vec<SubtreeLeaf> = Vec::with_capacity(leaves.len() / 2);
for next_depth in (subtree_root..bottom_depth).rev() {
debug_assert!(next_depth <= bottom_depth);
@ -379,7 +378,7 @@ pub(crate) trait SparseMerkleTree<const DEPTH: u8> {
// `current_depth` is the stuff we have.
let current_depth = next_depth + 1;
let mut iter = leaves.drain(..).map(SubtreeLeaf::from_tuple).peekable();
let mut iter = leaves.drain(..).peekable();
while let Some(first) = iter.next() {
// On non-continuous iterations, including the first iteration, `first_column` may
// be a left or right node. On subsequent continuous iterations, we will always call
@ -432,7 +431,7 @@ pub(crate) trait SparseMerkleTree<const DEPTH: u8> {
if hash != equivalent_empty_hash {
inner_nodes.insert(index, node);
// FIXME: is it possible for this to end up not being sorted? I don't think so.
next_leaves.push((index.value(), hash));
next_leaves.push(SubtreeLeaf { col: index.value(), hash });
}
}
@ -568,14 +567,9 @@ impl<const DEPTH: u8, K, V> MutationSet<DEPTH, K, V> {
// HELPERS
// ================================================================================================
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Default)]
struct SubtreeLeaf {
col: u64,
hash: RpoDigest,
}
impl SubtreeLeaf {
const fn from_tuple((col, hash): (u64, RpoDigest)) -> Self {
Self { col, hash }
}
pub struct SubtreeLeaf {
pub col: u64,
pub hash: RpoDigest,
}
// TESTS
@ -587,7 +581,7 @@ mod test {
use super::SparseMerkleTree;
use crate::{
hash::rpo::RpoDigest,
merkle::{Smt, SmtLeaf, SMT_DEPTH},
merkle::{smt::SubtreeLeaf, Smt, SmtLeaf, SMT_DEPTH},
Felt, Word, ONE,
};
@ -606,17 +600,17 @@ mod test {
let control = Smt::with_entries(entries.clone()).unwrap();
let mut leaves: Vec<(u64, RpoDigest)> = entries
let mut leaves: Vec<SubtreeLeaf> = entries
.iter()
.map(|(key, value)| {
let leaf = SmtLeaf::new_single(*key, *value);
let col = leaf.index().index.value();
let hash = leaf.hash();
(col, hash)
SubtreeLeaf { col, hash }
})
.collect();
leaves.sort();
leaves.dedup_by_key(|leaf| leaf.0);
leaves.dedup_by_key(|leaf| leaf.col);
let (first_subtree, _) = Smt::build_subtree(leaves, SMT_DEPTH);
assert!(!first_subtree.is_empty());

View file

@ -1,4 +1,7 @@
use alloc::collections::{BTreeMap, BTreeSet};
use alloc::{
collections::{BTreeMap, BTreeSet},
vec::Vec,
};
use super::{
super::ValuePath, EmptySubtreeRoots, InnerNode, InnerNodeInfo, LeafIndex, MerkleError,