From ab84dcddd7d79ad73ddfee044f307fe049eb8d47 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Tue, 18 Feb 2025 10:58:32 +0100 Subject: [PATCH 1/3] feat: Filter out empty values in Smt constructor --- src/merkle/smt/full/concurrent/mod.rs | 7 ++++++- src/merkle/smt/full/concurrent/tests.rs | 10 +++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/merkle/smt/full/concurrent/mod.rs b/src/merkle/smt/full/concurrent/mod.rs index bf7e636e..c99a14b2 100644 --- a/src/merkle/smt/full/concurrent/mod.rs +++ b/src/merkle/smt/full/concurrent/mod.rs @@ -7,7 +7,10 @@ use super::{ EmptySubtreeRoots, InnerNode, InnerNodes, LeafIndex, Leaves, MerkleError, MutationSet, NodeIndex, RpoDigest, Smt, SmtLeaf, SparseMerkleTree, Word, SMT_DEPTH, }; -use crate::merkle::smt::{NodeMutation, NodeMutations, UnorderedMap}; +use crate::{ + merkle::smt::{NodeMutation, NodeMutations, UnorderedMap}, + EMPTY_WORD, +}; #[cfg(test)] mod tests; @@ -39,6 +42,8 @@ impl Smt { let mut seen_keys = BTreeSet::new(); let entries: Vec<_> = entries .into_iter() + // Filter out key-value pairs whose value is empty. + .filter(|(_key, value)| *value != EMPTY_WORD) .map(|(key, value)| { if seen_keys.insert(key) { Ok((key, value)) diff --git a/src/merkle/smt/full/concurrent/tests.rs b/src/merkle/smt/full/concurrent/tests.rs index 6d857ae4..8407c353 100644 --- a/src/merkle/smt/full/concurrent/tests.rs +++ b/src/merkle/smt/full/concurrent/tests.rs @@ -375,7 +375,15 @@ fn test_multithreaded_subtrees() { #[test] fn test_with_entries_concurrent() { const PAIR_COUNT: u64 = COLS_PER_SUBTREE * 64; - let entries = generate_entries(PAIR_COUNT); + let mut entries = generate_entries(PAIR_COUNT); + let mut rng = rand::thread_rng(); + + // Set 10% of the entries to have empty words as their values. + for _ in 0..PAIR_COUNT / 10 { + let random_index = rng.gen_range(0..PAIR_COUNT); + entries[random_index as usize].1 = EMPTY_WORD; + } + let control = Smt::with_entries_sequential(entries.clone()).unwrap(); let smt = Smt::with_entries(entries.clone()).unwrap(); assert_eq!(smt.root(), control.root()); From 857cd2ac59fc91fcf88c7c76c61a992fe1aeff01 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Tue, 18 Feb 2025 11:00:45 +0100 Subject: [PATCH 2/3] chore: Add changelog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a54f6162..14fd3a3f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - Implemented parallel leaf hashing in `Smt::process_sorted_pairs_to_leaves` (#365). - [BREAKING] Updated Winterfell dependency to v0.12 (#374). - Added debug-only duplicate column check in `build_subtree` (#378). +- Filter out empty values in concurrent version of `Smt::with_entries` to fix a panic (#383). ## 0.13.3 (2025-02-18) From 65e389fd4960c06a16cb42fc0b8540dbbe0aeca8 Mon Sep 17 00:00:00 2001 From: Philipp Gackstatter Date: Tue, 18 Feb 2025 11:10:39 +0100 Subject: [PATCH 3/3] chore: Use `Smt::EMPTY_VALUE` instead --- src/merkle/smt/full/concurrent/mod.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/merkle/smt/full/concurrent/mod.rs b/src/merkle/smt/full/concurrent/mod.rs index c99a14b2..698a8cf1 100644 --- a/src/merkle/smt/full/concurrent/mod.rs +++ b/src/merkle/smt/full/concurrent/mod.rs @@ -7,10 +7,7 @@ use super::{ EmptySubtreeRoots, InnerNode, InnerNodes, LeafIndex, Leaves, MerkleError, MutationSet, NodeIndex, RpoDigest, Smt, SmtLeaf, SparseMerkleTree, Word, SMT_DEPTH, }; -use crate::{ - merkle::smt::{NodeMutation, NodeMutations, UnorderedMap}, - EMPTY_WORD, -}; +use crate::merkle::smt::{NodeMutation, NodeMutations, UnorderedMap}; #[cfg(test)] mod tests; @@ -43,7 +40,7 @@ impl Smt { let entries: Vec<_> = entries .into_iter() // Filter out key-value pairs whose value is empty. - .filter(|(_key, value)| *value != EMPTY_WORD) + .filter(|(_key, value)| *value != Self::EMPTY_VALUE) .map(|(key, value)| { if seen_keys.insert(key) { Ok((key, value))