convert (col, hash) tuples to a dedicated struct
This commit is contained in:
parent
bd0a69bcfa
commit
1102b8e4ea
5 changed files with 24 additions and 27 deletions
|
@ -3,7 +3,7 @@ use std::{fmt::Debug, hint, mem, time::Duration};
|
||||||
use criterion::{criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion};
|
use criterion::{criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion};
|
||||||
use miden_crypto::{
|
use miden_crypto::{
|
||||||
hash::rpo::RpoDigest,
|
hash::rpo::RpoDigest,
|
||||||
merkle::{NodeIndex, Smt, SmtLeaf, SMT_DEPTH},
|
merkle::{NodeIndex, Smt, SmtLeaf, SubtreeLeaf, SMT_DEPTH},
|
||||||
Felt, Word, ONE,
|
Felt, Word, ONE,
|
||||||
};
|
};
|
||||||
use rand_utils::prng_array;
|
use rand_utils::prng_array;
|
||||||
|
@ -43,11 +43,11 @@ fn smt_subtree_even(c: &mut Criterion) {
|
||||||
let leaf = SmtLeaf::new_single(*key, *value);
|
let leaf = SmtLeaf::new_single(*key, *value);
|
||||||
let col = NodeIndex::from(leaf.index()).value();
|
let col = NodeIndex::from(leaf.index()).value();
|
||||||
let hash = leaf.hash();
|
let hash = leaf.hash();
|
||||||
(col, hash)
|
SubtreeLeaf { col, hash }
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
leaves.sort();
|
leaves.sort();
|
||||||
leaves.dedup_by_key(|leaf| leaf.0);
|
leaves.dedup_by_key(|leaf| leaf.col);
|
||||||
leaves
|
leaves
|
||||||
},
|
},
|
||||||
|leaves| {
|
|leaves| {
|
||||||
|
@ -93,7 +93,7 @@ fn smt_subtree_random(c: &mut Criterion) {
|
||||||
let leaf = SmtLeaf::new_single(*key, *value);
|
let leaf = SmtLeaf::new_single(*key, *value);
|
||||||
let col = NodeIndex::from(leaf.index()).value();
|
let col = NodeIndex::from(leaf.index()).value();
|
||||||
let hash = leaf.hash();
|
let hash = leaf.hash();
|
||||||
(col, hash)
|
SubtreeLeaf { col, hash }
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
leaves.sort();
|
leaves.sort();
|
||||||
|
|
|
@ -23,7 +23,7 @@ pub use path::{MerklePath, RootPath, ValuePath};
|
||||||
mod smt;
|
mod smt;
|
||||||
pub use smt::{
|
pub use smt::{
|
||||||
LeafIndex, MutationSet, SimpleSmt, Smt, SmtLeaf, SmtLeafError, SmtProof, SmtProofError,
|
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;
|
mod mmr;
|
||||||
|
|
|
@ -6,7 +6,7 @@ use alloc::{
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
EmptySubtreeRoots, Felt, InnerNode, InnerNodeInfo, LeafIndex, MerkleError, MerklePath,
|
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;
|
mod error;
|
||||||
|
@ -251,9 +251,9 @@ impl Smt {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_subtree(
|
pub fn build_subtree(
|
||||||
leaves: Vec<(u64, RpoDigest)>,
|
leaves: Vec<SubtreeLeaf>,
|
||||||
bottom_depth: u8,
|
bottom_depth: u8,
|
||||||
) -> (BTreeMap<NodeIndex, InnerNode>, Vec<(u64, RpoDigest)>) {
|
) -> (BTreeMap<NodeIndex, InnerNode>, Vec<SubtreeLeaf>) {
|
||||||
<Self as SparseMerkleTree<SMT_DEPTH>>::build_subtree(leaves, bottom_depth)
|
<Self as SparseMerkleTree<SMT_DEPTH>>::build_subtree(leaves, bottom_depth)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
/// 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.
|
/// lower in the tree than the specified maximum depth (`DEPTH`), or if `leaves` is not sorted.
|
||||||
// FIXME: more complete docstring.
|
// FIXME: more complete docstring.
|
||||||
#[cfg_attr(not(test), allow(dead_code))]
|
|
||||||
fn build_subtree(
|
fn build_subtree(
|
||||||
mut leaves: Vec<(u64, RpoDigest)>,
|
mut leaves: Vec<SubtreeLeaf>,
|
||||||
bottom_depth: u8,
|
bottom_depth: u8,
|
||||||
) -> (BTreeMap<NodeIndex, InnerNode>, Vec<(u64, RpoDigest)>) {
|
) -> (BTreeMap<NodeIndex, InnerNode>, Vec<SubtreeLeaf>) {
|
||||||
debug_assert!(bottom_depth <= DEPTH);
|
debug_assert!(bottom_depth <= DEPTH);
|
||||||
debug_assert!(bottom_depth.is_multiple_of(&8));
|
debug_assert!(bottom_depth.is_multiple_of(&8));
|
||||||
debug_assert!(leaves.len() <= usize::pow(2, 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 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() {
|
for next_depth in (subtree_root..bottom_depth).rev() {
|
||||||
debug_assert!(next_depth <= bottom_depth);
|
debug_assert!(next_depth <= bottom_depth);
|
||||||
|
@ -379,7 +378,7 @@ pub(crate) trait SparseMerkleTree<const DEPTH: u8> {
|
||||||
// `current_depth` is the stuff we have.
|
// `current_depth` is the stuff we have.
|
||||||
let current_depth = next_depth + 1;
|
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() {
|
while let Some(first) = iter.next() {
|
||||||
// On non-continuous iterations, including the first iteration, `first_column` may
|
// 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
|
// 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 {
|
if hash != equivalent_empty_hash {
|
||||||
inner_nodes.insert(index, node);
|
inner_nodes.insert(index, node);
|
||||||
// FIXME: is it possible for this to end up not being sorted? I don't think so.
|
// 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
|
// HELPERS
|
||||||
// ================================================================================================
|
// ================================================================================================
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Default)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Default)]
|
||||||
struct SubtreeLeaf {
|
pub struct SubtreeLeaf {
|
||||||
col: u64,
|
pub col: u64,
|
||||||
hash: RpoDigest,
|
pub hash: RpoDigest,
|
||||||
}
|
|
||||||
impl SubtreeLeaf {
|
|
||||||
const fn from_tuple((col, hash): (u64, RpoDigest)) -> Self {
|
|
||||||
Self { col, hash }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TESTS
|
// TESTS
|
||||||
|
@ -587,7 +581,7 @@ mod test {
|
||||||
use super::SparseMerkleTree;
|
use super::SparseMerkleTree;
|
||||||
use crate::{
|
use crate::{
|
||||||
hash::rpo::RpoDigest,
|
hash::rpo::RpoDigest,
|
||||||
merkle::{Smt, SmtLeaf, SMT_DEPTH},
|
merkle::{smt::SubtreeLeaf, Smt, SmtLeaf, SMT_DEPTH},
|
||||||
Felt, Word, ONE,
|
Felt, Word, ONE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -606,17 +600,17 @@ mod test {
|
||||||
|
|
||||||
let control = Smt::with_entries(entries.clone()).unwrap();
|
let control = Smt::with_entries(entries.clone()).unwrap();
|
||||||
|
|
||||||
let mut leaves: Vec<(u64, RpoDigest)> = entries
|
let mut leaves: Vec<SubtreeLeaf> = entries
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(key, value)| {
|
.map(|(key, value)| {
|
||||||
let leaf = SmtLeaf::new_single(*key, *value);
|
let leaf = SmtLeaf::new_single(*key, *value);
|
||||||
let col = leaf.index().index.value();
|
let col = leaf.index().index.value();
|
||||||
let hash = leaf.hash();
|
let hash = leaf.hash();
|
||||||
(col, hash)
|
SubtreeLeaf { col, hash }
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
leaves.sort();
|
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);
|
let (first_subtree, _) = Smt::build_subtree(leaves, SMT_DEPTH);
|
||||||
assert!(!first_subtree.is_empty());
|
assert!(!first_subtree.is_empty());
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
use alloc::collections::{BTreeMap, BTreeSet};
|
use alloc::{
|
||||||
|
collections::{BTreeMap, BTreeSet},
|
||||||
|
vec::Vec,
|
||||||
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
super::ValuePath, EmptySubtreeRoots, InnerNode, InnerNodeInfo, LeafIndex, MerkleError,
|
super::ValuePath, EmptySubtreeRoots, InnerNode, InnerNodeInfo, LeafIndex, MerkleError,
|
||||||
|
|
Loading…
Add table
Reference in a new issue