Skip to content

Commit c6b23f0

Browse files
committed
chore: propagate changes from v0.19.x
1 parent 6f87a32 commit c6b23f0

File tree

3 files changed

+33
-3
lines changed

3 files changed

+33
-3
lines changed

miden-crypto/src/merkle/smt/forest/mod.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,13 @@ impl SmtForest {
207207
self.leaves.insert(leaf_hash, leaf);
208208
}
209209
}
210-
self.roots.insert(new_root);
210+
// Never register the empty tree root in self.roots, as it is always implicitly valid
211+
// and the empty hash nodes are pre-populated infrastructure in the SmtStore.
212+
// Adding it here would let `pop_smts` walk and destroy those nodes,
213+
// corrupting the store for all future operations.
214+
if new_root != *EmptySubtreeRoots::entry(SMT_DEPTH, 0) {
215+
self.roots.insert(new_root);
216+
}
211217

212218
Ok(new_root)
213219
}

miden-crypto/src/merkle/smt/forest/tests.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,3 +313,27 @@ fn test_removing_empty_smt_from_forest() {
313313
// Popping the empty root should be a no-op (no panic or error)
314314
forest.pop_smts(vec![empty_tree_root]);
315315
}
316+
317+
#[test]
318+
fn test_empty_root_never_removed() -> Result<(), MerkleError> {
319+
// Verify that the empty tree root is never registered in self.roots and that
320+
// popping it does not corrupt the store.
321+
let mut forest = SmtForest::new();
322+
let empty_root = *EmptySubtreeRoots::entry(SMT_DEPTH, 0);
323+
let key = Word::new([ZERO; WORD_SIZE]);
324+
let value = Word::new([ONE; WORD_SIZE]);
325+
326+
// batch_insert with no entries returns the empty root — it must not be registered
327+
let root = forest.batch_insert(empty_root, vec![])?;
328+
assert_eq!(root, empty_root);
329+
330+
// Popping the empty root would corrupt the store if it were in self.roots.
331+
forest.pop_smts(vec![empty_root]);
332+
333+
// The forest should still be fully functional
334+
let new_root = forest.insert(empty_root, key, value)?;
335+
let proof = forest.open(new_root, key)?;
336+
assert!(proof.verify_presence(&key, &value, &new_root).is_ok());
337+
338+
Ok(())
339+
}

miden-crypto/src/merkle/smt/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ mod large;
2222
pub use full::concurrent::{SubtreeLeaf, build_subtree_for_bench};
2323
#[cfg(feature = "concurrent")]
2424
pub use large::{
25-
LargeSmt, LargeSmtError, MemoryStorage, SmtStorage, StorageUpdateParts, StorageUpdates,
26-
Subtree, SubtreeError,
25+
LargeSmt, LargeSmtError, MemoryStorage, SmtStorage, StorageError, StorageUpdateParts,
26+
StorageUpdates, Subtree, SubtreeError, SubtreeUpdate,
2727
};
2828
#[cfg(feature = "rocksdb")]
2929
pub use large::{RocksDbConfig, RocksDbStorage};

0 commit comments

Comments
 (0)