Skip to content

Commit

Permalink
cleanup test_singlethreaded_subtrees a bit
Browse files Browse the repository at this point in the history
  • Loading branch information
Qyriad committed Nov 4, 2024
1 parent df01c2c commit 07da19e
Showing 1 changed file with 44 additions and 11 deletions.
55 changes: 44 additions & 11 deletions src/merkle/smt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -616,9 +616,15 @@ impl<const DEPTH: u8, K, V> MutationSet<DEPTH, K, V> {
/// A depth-8 subtree contains 256 "columns" that can possibly be occupied.
const COLS_PER_SUBTREE: u64 = u64::pow(2, 8);

/// Helper struct for organizing the data we care about when computing Merkle subtrees.
///
/// Note that these represet "conceptual" leaves of some subtree, not necessarily
/// [`SparseMerkleTree::Leaf`].
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Default)]
pub struct SubtreeLeaf {
/// The 'value' field of [`NodeIndex`]. When computing a subtree, the depth is already known.
pub col: u64,
/// The hash of the node this `SubtreeLeaf` represents.
pub hash: RpoDigest,
}

Expand Down Expand Up @@ -692,7 +698,10 @@ mod test {
use super::{SparseMerkleTree, SubtreeLeaf};
use crate::{
hash::rpo::RpoDigest,
merkle::{smt::InnerNode, NodeIndex, Smt, SmtLeaf, SMT_DEPTH},
merkle::{
smt::{InnerNode, PairComputations},
LeafIndex, NodeIndex, Smt, SmtLeaf, SMT_DEPTH,
},
Felt, Word, ONE,
};

Expand Down Expand Up @@ -871,9 +880,11 @@ mod test {

let mut accumulated_nodes: BTreeMap<NodeIndex, InnerNode> = Default::default();

let starting_leaves = Smt::sorted_pairs_to_leaves(entries);
let PairComputations {
leaves: mut leaf_subtrees,
nodes: test_leaves,
} = Smt::sorted_pairs_to_leaves(entries);

let mut leaf_subtrees = starting_leaves.leaves;
for current_depth in (8..=SMT_DEPTH).step_by(8).rev() {
for (i, subtree) in mem::take(&mut leaf_subtrees).into_iter().enumerate() {
// Pre-assertions.
Expand Down Expand Up @@ -911,23 +922,45 @@ mod test {
assert!(!leaf_subtrees.is_empty(), "on depth {current_depth}");
}

// Make sure the true leaves match, checking length first and then each individual leaf.
let control_leaves: BTreeMap<_, _> = control.leaves().collect();
let control_leaves_len = control_leaves.len();
let test_leaves_len = test_leaves.len();
assert_eq!(test_leaves_len, control_leaves_len);
for (col, ref test_leaf) in test_leaves {
let index = LeafIndex::new_max_depth(col);
let &control_leaf = control_leaves.get(&index).unwrap();
assert_eq!(test_leaf, control_leaf);
}

// Make sure the inner nodes match, checking length first and then each individual leaf.
let control_nodes_len = control.inner_nodes().count();
let test_nodes_len = accumulated_nodes.len();
assert_eq!(test_nodes_len, control_nodes_len);
for (index, test_node) in accumulated_nodes.clone() {
let control_node = control.get_inner_node(index);
assert_eq!(test_node, control_node, "test node does not match control at {index:?}");
}

assert_eq!(leaf_subtrees.len(), 1);
let mut leaf_subtree = leaf_subtrees.pop().unwrap();
assert_eq!(leaf_subtree.len(), 1);
let root_leaf = leaf_subtree.pop().unwrap();
// After the last iteration of the above for loop, we should have the new root node actually
// in two places: one in `accumulated_nodes`, and the other as the "next leaves" return from
// `build_subtree()`. So let's check both!

let control_root = control.get_inner_node(NodeIndex::root());

// That for loop should have left us with only one leaf subtree...
let [leaf_subtree]: [_; 1] = leaf_subtrees.try_into().unwrap();
// which itself contains only one 'leaf'...
let [root_leaf]: [_; 1] = leaf_subtree.try_into().unwrap();
// which matches the expected root.
assert_eq!(control.root(), root_leaf.hash);

// Do we have a root?
// Likewise `accumulated_nodes` should contain a node at the root index...
assert!(accumulated_nodes.contains_key(&NodeIndex::root()));

// And does it match?
// and it should match our actual root.
let test_root = accumulated_nodes.get(&NodeIndex::root()).unwrap();
assert_eq!(control.root(), test_root.hash());
assert_eq!(control_root, *test_root);
// And of course the root we got from each place should match.
assert_eq!(control.root(), root_leaf.hash);
}
}

0 comments on commit 07da19e

Please sign in to comment.