cleanup test_singlethreaded_subtrees a bit

This commit is contained in:
Qyriad 2024-11-04 13:38:55 -07:00
parent 5d1c6c7eb4
commit 8448e296e3

View file

@ -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. /// A depth-8 subtree contains 256 "columns" that can possibly be occupied.
const COLS_PER_SUBTREE: u64 = u64::pow(2, 8); 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)] #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Default)]
pub struct SubtreeLeaf { pub struct SubtreeLeaf {
/// The 'value' field of [`NodeIndex`]. When computing a subtree, the depth is already known.
pub col: u64, pub col: u64,
/// The hash of the node this `SubtreeLeaf` represents.
pub hash: RpoDigest, pub hash: RpoDigest,
} }
@ -692,7 +698,10 @@ mod test {
use super::{SparseMerkleTree, SubtreeLeaf}; use super::{SparseMerkleTree, SubtreeLeaf};
use crate::{ use crate::{
hash::rpo::RpoDigest, hash::rpo::RpoDigest,
merkle::{smt::InnerNode, NodeIndex, Smt, SmtLeaf, SMT_DEPTH}, merkle::{
smt::{InnerNode, PairComputations},
LeafIndex, NodeIndex, Smt, SmtLeaf, SMT_DEPTH,
},
Felt, Word, ONE, Felt, Word, ONE,
}; };
@ -871,9 +880,11 @@ mod test {
let mut accumulated_nodes: BTreeMap<NodeIndex, InnerNode> = Default::default(); 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 current_depth in (8..=SMT_DEPTH).step_by(8).rev() {
for (i, subtree) in mem::take(&mut leaf_subtrees).into_iter().enumerate() { for (i, subtree) in mem::take(&mut leaf_subtrees).into_iter().enumerate() {
// Pre-assertions. // Pre-assertions.
@ -911,23 +922,45 @@ mod test {
assert!(!leaf_subtrees.is_empty(), "on depth {current_depth}"); 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() { for (index, test_node) in accumulated_nodes.clone() {
let control_node = control.get_inner_node(index); let control_node = control.get_inner_node(index);
assert_eq!(test_node, control_node, "test node does not match control at {index:?}"); assert_eq!(test_node, control_node, "test node does not match control at {index:?}");
} }
assert_eq!(leaf_subtrees.len(), 1); // After the last iteration of the above for loop, we should have the new root node actually
let mut leaf_subtree = leaf_subtrees.pop().unwrap(); // in two places: one in `accumulated_nodes`, and the other as the "next leaves" return from
assert_eq!(leaf_subtree.len(), 1); // `build_subtree()`. So let's check both!
let root_leaf = leaf_subtree.pop().unwrap();
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); 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())); assert!(accumulated_nodes.contains_key(&NodeIndex::root()));
// and it should match our actual root.
// And does it match?
let test_root = accumulated_nodes.get(&NodeIndex::root()).unwrap(); 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); assert_eq!(control.root(), root_leaf.hash);
} }
} }