miden_crypto/merkle/smt/full/mod.rs
1use alloc::{string::ToString, vec::Vec};
2
3use super::{
4 EMPTY_WORD, EmptySubtreeRoots, InnerNode, InnerNodeInfo, InnerNodes, LeafIndex, MerkleError,
5 MutationSet, NodeIndex, SparseMerklePath, SparseMerkleTree, SparseMerkleTreeReader, Word,
6};
7
8mod error;
9pub use error::{SmtLeafError, SmtProofError};
10
11mod leaf;
12pub use leaf::SmtLeaf;
13
14mod proof;
15pub use proof::SmtProof;
16
17use crate::utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable};
18
19// Concurrent implementation
20#[cfg(feature = "concurrent")]
21pub(in crate::merkle::smt) mod concurrent;
22
23#[cfg(test)]
24mod tests;
25
26// CONSTANTS
27// ================================================================================================
28
29/// The depth of the sparse Merkle tree.
30///
31/// All leaves in this SMT are located at depth 64.
32pub const SMT_DEPTH: u8 = 64;
33
34/// The maximum number of entries allowed in a multiple leaf.
35pub const MAX_LEAF_ENTRIES: usize = 1024;
36
37// SMT
38// ================================================================================================
39
40type Leaves = super::Leaves<SmtLeaf>;
41
42/// Sparse Merkle tree mapping 256-bit keys to 256-bit values. Both keys and values are represented
43/// by 4 field elements.
44///
45/// All leaves sit at depth 64. The most significant element of the key is used to identify the leaf
46/// to which the key maps.
47///
48/// A leaf is either empty, or holds one or more key-value pairs. An empty leaf hashes to the empty
49/// word. Otherwise, a leaf hashes to the hash of its key-value pairs, ordered by key first, value
50/// second.
51///
52/// ```text
53/// depth
54/// T 0 Root
55/// │ . / \
56/// │ 1 left right
57/// │ . / \ / \
58/// │
59/// │ .. .. .. .. .. .. .. ..
60/// │
61/// │ 63
62/// │ / \ / \ \
63/// │ ↓ / \ / \ \
64/// │ 64 Leaf₀ Leaf₁ Leaf₂ Leaf₃ ... Leaf₂⁶⁴₋₂³²
65/// 0x0..0 0x0..1 0x0..2 0x0..3 0xFFFFFFFF00000000
66///
67/// The digest is 256 bits, or 4 field elements:
68/// [elem₀, elem₁, elem₂, elem₃]
69/// ↑
70/// Most significant element determines leaf
71/// index, mapping into the actual Leaf lookup
72/// table where the values are stored.
73///
74/// Zooming into a leaf, i.e. Leaf₁:
75/// ┌─────────────────────────────────────────────────┐
76/// │ Leaf₁ (index: 0x0..1) │
77/// ├─────────────────────────────────────────────────┤
78/// │ Possible states: │
79/// │ │
80/// │ 1. Empty leaf: │
81/// │ └─ hash = EMPTY_WORD │
82/// │ │
83/// │ 2. Single entry: │
84/// │ └─ (key₁, value₁) │
85/// │ └─ hash = H(key₁, value₁) │
86/// │ │
87/// │ 3. Multiple entries: │
88/// │ └─ (key₁, value₁) │
89/// │ └─ (key₂, value₂) │
90/// │ └─ ... │
91/// │ └─ hash = H(key₁, value₁, key₂, value₂, ...) │
92/// └─────────────────────────────────────────────────┘
93///
94/// Leaf states:
95/// - Empty: hashes to EMPTY_WORD
96/// - Non-empty: contains (key, value) pairs
97/// hash = H(key₁, value₁, key₂, value₂, ...)
98/// ```
99#[derive(Debug, Clone, PartialEq, Eq)]
100#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
101pub struct Smt {
102 root: Word,
103 num_entries: usize,
104 leaves: Leaves,
105 inner_nodes: InnerNodes,
106}
107
108impl Smt {
109 // CONSTANTS
110 // --------------------------------------------------------------------------------------------
111 /// The default value used to compute the hash of empty leaves
112 pub const EMPTY_VALUE: Word = <Self as SparseMerkleTreeReader<SMT_DEPTH>>::EMPTY_VALUE;
113
114 // CONSTRUCTORS
115 // --------------------------------------------------------------------------------------------
116
117 /// Returns a new [Smt].
118 ///
119 /// All leaves in the returned tree are set to [Self::EMPTY_VALUE].
120 pub fn new() -> Self {
121 let root = *EmptySubtreeRoots::entry(SMT_DEPTH, 0);
122
123 Self {
124 root,
125 num_entries: 0,
126 inner_nodes: Default::default(),
127 leaves: Default::default(),
128 }
129 }
130
131 /// Returns a new [Smt] instantiated with leaves set as specified by the provided entries.
132 ///
133 /// If the `concurrent` feature is enabled, this function uses a parallel implementation to
134 /// process the entries efficiently, otherwise it defaults to the sequential implementation.
135 ///
136 /// All leaves omitted from the entries list are set to [Self::EMPTY_VALUE].
137 ///
138 /// # Errors
139 /// Returns an error if:
140 /// - the provided entries contain multiple values for the same key.
141 /// - inserting a key-value pair would exceed [`MAX_LEAF_ENTRIES`] (1024 entries) in a leaf.
142 pub fn with_entries(
143 entries: impl IntoIterator<Item = (Word, Word)>,
144 ) -> Result<Self, MerkleError> {
145 #[cfg(feature = "concurrent")]
146 {
147 Self::with_entries_concurrent(entries)
148 }
149 #[cfg(not(feature = "concurrent"))]
150 {
151 Self::with_entries_sequential(entries)
152 }
153 }
154
155 /// Similar to `with_entries` but avoids the overhead of sorting if the entries are already
156 /// sorted.
157 ///
158 /// This only applies if the "concurrent" feature is enabled. Without the feature, the behavior
159 /// is equivalent to `with_entiries`.
160 ///
161 /// # Errors
162 /// Returns an error if inserting a key-value pair would exceed [`MAX_LEAF_ENTRIES`] (1024
163 /// entries) in a leaf.
164 pub fn with_sorted_entries(
165 entries: impl IntoIterator<Item = (Word, Word)>,
166 ) -> Result<Self, MerkleError> {
167 #[cfg(feature = "concurrent")]
168 {
169 Self::with_sorted_entries_concurrent(entries)
170 }
171 #[cfg(not(feature = "concurrent"))]
172 {
173 Self::with_entries_sequential(entries)
174 }
175 }
176
177 /// Returns a new [Smt] instantiated with leaves set as specified by the provided entries.
178 ///
179 /// This sequential implementation processes entries one at a time to build the tree.
180 /// All leaves omitted from the entries list are set to [Self::EMPTY_VALUE].
181 ///
182 /// # Errors
183 /// Returns an error if:
184 /// - the provided entries contain multiple values for the same key.
185 /// - inserting a key-value pair would exceed [`MAX_LEAF_ENTRIES`] (1024 entries) in a leaf.
186 #[cfg(any(not(feature = "concurrent"), fuzzing, feature = "fuzzing", test))]
187 fn with_entries_sequential(
188 entries: impl IntoIterator<Item = (Word, Word)>,
189 ) -> Result<Self, MerkleError> {
190 use alloc::collections::BTreeSet;
191
192 // create an empty tree
193 let mut tree = Self::new();
194
195 // This being a sparse data structure, the EMPTY_WORD is not assigned to the `BTreeMap`, so
196 // entries with the empty value need additional tracking.
197 let mut key_set_to_zero = BTreeSet::new();
198
199 for (key, value) in entries {
200 let old_value = tree.insert(key, value)?;
201
202 if old_value != EMPTY_WORD || key_set_to_zero.contains(&key) {
203 return Err(MerkleError::DuplicateValuesForIndex(
204 LeafIndex::<SMT_DEPTH>::from(key).position(),
205 ));
206 }
207
208 if value == EMPTY_WORD {
209 key_set_to_zero.insert(key);
210 };
211 }
212 Ok(tree)
213 }
214
215 /// Returns a new [`Smt`] instantiated from already computed leaves and nodes.
216 ///
217 /// This function performs minimal consistency checking. It is the caller's responsibility to
218 /// ensure the passed arguments are correct and consistent with each other.
219 ///
220 /// # Panics
221 /// With debug assertions on, this function panics if `root` does not match the root node in
222 /// `inner_nodes`.
223 pub fn from_raw_parts(inner_nodes: InnerNodes, leaves: Leaves, root: Word) -> Self {
224 if cfg!(debug_assertions) {
225 let root_node_hash = inner_nodes
226 .get(&NodeIndex::root())
227 .map(InnerNode::hash)
228 .unwrap_or(Self::EMPTY_ROOT);
229
230 assert_eq!(root_node_hash, root);
231 }
232 let num_entries = leaves.values().map(SmtLeaf::num_entries).sum();
233 Self { root, inner_nodes, leaves, num_entries }
234 }
235
236 // PUBLIC ACCESSORS
237 // --------------------------------------------------------------------------------------------
238
239 /// Returns the depth of the tree
240 pub const fn depth(&self) -> u8 {
241 SMT_DEPTH
242 }
243
244 /// Returns the root of the tree
245 pub fn root(&self) -> Word {
246 <Self as SparseMerkleTreeReader<SMT_DEPTH>>::root(self)
247 }
248
249 /// Returns the number of non-empty leaves in this tree.
250 ///
251 /// Note that this may return a different value from [Self::num_entries()] as a single leaf may
252 /// contain more than one key-value pair.
253 pub fn num_leaves(&self) -> usize {
254 self.leaves.len()
255 }
256
257 /// Returns the number of key-value pairs with non-default values in this tree.
258 ///
259 /// Note that this may return a different value from [Self::num_leaves()] as a single leaf may
260 /// contain more than one key-value pair.
261 pub fn num_entries(&self) -> usize {
262 self.num_entries
263 }
264
265 /// Returns the leaf to which `key` maps
266 pub fn get_leaf(&self, key: &Word) -> SmtLeaf {
267 <Self as SparseMerkleTreeReader<SMT_DEPTH>>::get_leaf(self, key)
268 }
269
270 /// Returns the leaf corresponding to the provided `index`.
271 pub fn get_leaf_by_index(&self, index: LeafIndex<SMT_DEPTH>) -> Option<SmtLeaf> {
272 self.leaves.get(&index.position()).cloned()
273 }
274
275 /// Returns the value associated with `key`
276 pub fn get_value(&self, key: &Word) -> Word {
277 <Self as SparseMerkleTreeReader<SMT_DEPTH>>::get_value(self, key)
278 }
279
280 /// Returns an opening of the leaf associated with `key`. Conceptually, an opening is a Merkle
281 /// path to the leaf, as well as the leaf itself.
282 pub fn open(&self, key: &Word) -> SmtProof {
283 <Self as SparseMerkleTreeReader<SMT_DEPTH>>::open(self, key)
284 }
285
286 /// Returns a boolean value indicating whether the SMT is empty.
287 pub fn is_empty(&self) -> bool {
288 debug_assert_eq!(self.leaves.is_empty(), self.root == Self::EMPTY_ROOT);
289 self.root == Self::EMPTY_ROOT
290 }
291
292 // ITERATORS
293 // --------------------------------------------------------------------------------------------
294
295 /// Returns an iterator over the leaves of this [`Smt`] in arbitrary order.
296 pub fn leaves(&self) -> impl Iterator<Item = (LeafIndex<SMT_DEPTH>, &SmtLeaf)> {
297 self.leaves
298 .iter()
299 .map(|(leaf_index, leaf)| (LeafIndex::new_max_depth(*leaf_index), leaf))
300 }
301
302 /// Returns an iterator over the key-value pairs of this [Smt] in arbitrary order.
303 pub fn entries(&self) -> impl Iterator<Item = &(Word, Word)> {
304 self.leaves().flat_map(|(_, leaf)| leaf.entries())
305 }
306
307 /// Returns an iterator over the inner nodes of this [Smt].
308 pub fn inner_nodes(&self) -> impl Iterator<Item = InnerNodeInfo> + '_ {
309 self.inner_nodes.values().map(|e| InnerNodeInfo {
310 value: e.hash(),
311 left: e.left,
312 right: e.right,
313 })
314 }
315
316 /// Returns an iterator over the [`InnerNode`] and the respective [`NodeIndex`] of the [`Smt`].
317 pub fn inner_node_indices(&self) -> impl Iterator<Item = (NodeIndex, InnerNode)> + '_ {
318 self.inner_nodes.iter().map(|(idx, inner)| (*idx, inner.clone()))
319 }
320
321 // STATE MUTATORS
322 // --------------------------------------------------------------------------------------------
323
324 /// Inserts a value at the specified key, returning the previous value associated with that key.
325 /// Recall that by definition, any key that hasn't been updated is associated with
326 /// [`Self::EMPTY_VALUE`].
327 ///
328 /// This also recomputes all hashes between the leaf (associated with the key) and the root,
329 /// updating the root itself.
330 ///
331 /// # Errors
332 /// Returns an error if inserting the key-value pair would exceed [`MAX_LEAF_ENTRIES`] (1024
333 /// entries) in the leaf.
334 pub fn insert(&mut self, key: Word, value: Word) -> Result<Word, MerkleError> {
335 <Self as SparseMerkleTree<SMT_DEPTH>>::insert(self, key, value)
336 }
337
338 /// Computes what changes are necessary to insert the specified key-value pairs into this Merkle
339 /// tree, allowing for validation before applying those changes.
340 ///
341 /// This method returns a [`MutationSet`], which contains all the information for inserting
342 /// `kv_pairs` into this Merkle tree already calculated, including the new root hash, which can
343 /// be queried with [`MutationSet::root()`]. Once a mutation set is returned,
344 /// [`Smt::apply_mutations()`] can be called in order to commit these changes to the Merkle
345 /// tree, or [`drop()`] to discard them.
346 ///
347 /// # Errors
348 ///
349 /// - [`MerkleError::DuplicateValuesForIndex`] if `kv_pairs` contains the same key more than
350 /// once.
351 /// - [`MerkleError::TooManyLeafEntries`] if mutations would exceed 1024 entries in a leaf.
352 ///
353 /// # Example
354 ///
355 /// ```
356 /// # use miden_crypto::{Felt, Word};
357 /// # use miden_crypto::merkle::{EmptySubtreeRoots, smt::{Smt, SMT_DEPTH}};
358 /// let mut smt = Smt::new();
359 /// let pair = (Word::default(), Word::default());
360 /// let mutations = smt.compute_mutations(vec![pair]).unwrap();
361 /// assert_eq!(mutations.root(), *EmptySubtreeRoots::entry(SMT_DEPTH, 0));
362 /// smt.apply_mutations(mutations).unwrap();
363 /// assert_eq!(smt.root(), *EmptySubtreeRoots::entry(SMT_DEPTH, 0));
364 /// ```
365 pub fn compute_mutations(
366 &self,
367 kv_pairs: impl IntoIterator<Item = (Word, Word)>,
368 ) -> Result<MutationSet<SMT_DEPTH, Word, Word>, MerkleError> {
369 #[cfg(feature = "concurrent")]
370 {
371 self.compute_mutations_concurrent(kv_pairs)
372 }
373 #[cfg(not(feature = "concurrent"))]
374 {
375 <Self as SparseMerkleTreeReader<SMT_DEPTH>>::compute_mutations(self, kv_pairs)
376 }
377 }
378
379 /// Applies the prospective mutations computed with [`Smt::compute_mutations()`] to this tree.
380 ///
381 /// # Errors
382 /// If `mutations` was computed on a tree with a different root than this one, returns
383 /// [`MerkleError::ConflictingRoots`] with a two-item [`Vec`]. The first item is the root hash
384 /// the `mutations` were computed against, and the second item is the actual current root of
385 /// this tree.
386 pub fn apply_mutations(
387 &mut self,
388 mutations: MutationSet<SMT_DEPTH, Word, Word>,
389 ) -> Result<(), MerkleError> {
390 <Self as SparseMerkleTree<SMT_DEPTH>>::apply_mutations(self, mutations)
391 }
392
393 /// Applies the prospective mutations computed with [`Smt::compute_mutations()`] to this tree
394 /// and returns the reverse mutation set.
395 ///
396 /// Applying the reverse mutation sets to the updated tree will revert the changes.
397 ///
398 /// # Errors
399 /// If `mutations` was computed on a tree with a different root than this one, returns
400 /// [`MerkleError::ConflictingRoots`] with a two-item [`Vec`]. The first item is the root hash
401 /// the `mutations` were computed against, and the second item is the actual current root of
402 /// this tree.
403 pub fn apply_mutations_with_reversion(
404 &mut self,
405 mutations: MutationSet<SMT_DEPTH, Word, Word>,
406 ) -> Result<MutationSet<SMT_DEPTH, Word, Word>, MerkleError> {
407 <Self as SparseMerkleTree<SMT_DEPTH>>::apply_mutations_with_reversion(self, mutations)
408 }
409
410 // HELPERS
411 // --------------------------------------------------------------------------------------------
412
413 /// Inserts `value` at leaf index pointed to by `key`. `value` is guaranteed to not be the empty
414 /// value, such that this is indeed an insertion.
415 ///
416 /// # Errors
417 /// Returns an error if inserting the key-value pair would exceed [`MAX_LEAF_ENTRIES`] (1024
418 /// entries) in the leaf.
419 fn perform_insert(&mut self, key: Word, value: Word) -> Result<Option<Word>, MerkleError> {
420 debug_assert_ne!(value, Self::EMPTY_VALUE);
421
422 let leaf_index: LeafIndex<SMT_DEPTH> = Self::key_to_leaf_index(&key);
423
424 match self.leaves.get_mut(&leaf_index.position()) {
425 Some(leaf) => {
426 let prev_entries = leaf.num_entries();
427 let result = leaf.insert(key, value).map_err(|e| match e {
428 SmtLeafError::TooManyLeafEntries { actual } => {
429 MerkleError::TooManyLeafEntries { actual }
430 },
431 other => panic!("unexpected SmtLeaf::insert error: {:?}", other),
432 })?;
433 let current_entries = leaf.num_entries();
434 self.num_entries += current_entries - prev_entries;
435 Ok(result)
436 },
437 None => {
438 self.leaves.insert(leaf_index.position(), SmtLeaf::Single((key, value)));
439 self.num_entries += 1;
440 Ok(None)
441 },
442 }
443 }
444
445 /// Removes key-value pair at leaf index pointed to by `key` if it exists.
446 fn perform_remove(&mut self, key: Word) -> Option<Word> {
447 let leaf_index: LeafIndex<SMT_DEPTH> = Self::key_to_leaf_index(&key);
448
449 if let Some(leaf) = self.leaves.get_mut(&leaf_index.position()) {
450 let prev_entries = leaf.num_entries();
451 let (old_value, is_empty) = leaf.remove(key);
452 let current_entries = leaf.num_entries();
453 self.num_entries -= prev_entries - current_entries;
454 if is_empty {
455 self.leaves.remove(&leaf_index.position());
456 }
457 old_value
458 } else {
459 // there's nothing stored at the leaf; nothing to update
460 None
461 }
462 }
463}
464
465impl SparseMerkleTreeReader<SMT_DEPTH> for Smt {
466 type Key = Word;
467 type Value = Word;
468 type Leaf = SmtLeaf;
469 type Opening = SmtProof;
470
471 const EMPTY_VALUE: Self::Value = EMPTY_WORD;
472 const EMPTY_ROOT: Word = *EmptySubtreeRoots::entry(SMT_DEPTH, 0);
473
474 fn root(&self) -> Word {
475 self.root
476 }
477
478 fn get_inner_node(&self, index: NodeIndex) -> InnerNode {
479 self.inner_nodes
480 .get(&index)
481 .cloned()
482 .unwrap_or_else(|| EmptySubtreeRoots::get_inner_node(SMT_DEPTH, index.depth()))
483 }
484
485 fn get_value(&self, key: &Self::Key) -> Self::Value {
486 let leaf_pos = LeafIndex::<SMT_DEPTH>::from(*key).position();
487
488 match self.leaves.get(&leaf_pos) {
489 Some(leaf) => leaf.get_value(key).unwrap_or_default(),
490 None => EMPTY_WORD,
491 }
492 }
493
494 fn get_leaf(&self, key: &Word) -> Self::Leaf {
495 let leaf_pos = LeafIndex::<SMT_DEPTH>::from(*key).position();
496
497 match self.leaves.get(&leaf_pos) {
498 Some(leaf) => leaf.clone(),
499 None => SmtLeaf::new_empty((*key).into()),
500 }
501 }
502
503 fn hash_leaf(leaf: &Self::Leaf) -> Word {
504 leaf.hash()
505 }
506
507 fn construct_prospective_leaf(
508 &self,
509 mut existing_leaf: SmtLeaf,
510 key: &Word,
511 value: &Word,
512 ) -> Result<SmtLeaf, SmtLeafError> {
513 debug_assert_eq!(existing_leaf.index(), Self::key_to_leaf_index(key));
514
515 match existing_leaf {
516 SmtLeaf::Empty(_) => Ok(SmtLeaf::new_single(*key, *value)),
517 _ => {
518 if *value != EMPTY_WORD {
519 existing_leaf.insert(*key, *value)?;
520 } else {
521 existing_leaf.remove(*key);
522 }
523
524 Ok(existing_leaf)
525 },
526 }
527 }
528
529 fn key_to_leaf_index(key: &Word) -> LeafIndex<SMT_DEPTH> {
530 let most_significant_felt = key[3];
531 LeafIndex::new_max_depth(most_significant_felt.as_canonical_u64())
532 }
533
534 fn path_and_leaf_to_opening(path: SparseMerklePath, leaf: SmtLeaf) -> SmtProof {
535 SmtProof::new_unchecked(path, leaf)
536 }
537}
538
539impl SparseMerkleTree<SMT_DEPTH> for Smt {
540 fn set_root(&mut self, root: Word) {
541 self.root = root;
542 }
543
544 fn insert_inner_node(&mut self, index: NodeIndex, inner_node: InnerNode) -> Option<InnerNode> {
545 if inner_node == EmptySubtreeRoots::get_inner_node(SMT_DEPTH, index.depth()) {
546 self.remove_inner_node(index)
547 } else {
548 self.inner_nodes.insert(index, inner_node)
549 }
550 }
551
552 fn remove_inner_node(&mut self, index: NodeIndex) -> Option<InnerNode> {
553 self.inner_nodes.remove(&index)
554 }
555
556 fn insert_value(
557 &mut self,
558 key: Self::Key,
559 value: Self::Value,
560 ) -> Result<Option<Self::Value>, MerkleError> {
561 // inserting an `EMPTY_VALUE` is equivalent to removing any value associated with `key`
562 if value != Self::EMPTY_VALUE {
563 self.perform_insert(key, value)
564 } else {
565 Ok(self.perform_remove(key))
566 }
567 }
568}
569
570impl Default for Smt {
571 fn default() -> Self {
572 Self::new()
573 }
574}
575
576// CONVERSIONS
577// ================================================================================================
578
579impl From<Word> for LeafIndex<SMT_DEPTH> {
580 fn from(value: Word) -> Self {
581 // We use the most significant `Felt` of a `Word` as the leaf index.
582 Self::new_max_depth(value[3].as_canonical_u64())
583 }
584}
585
586// SERIALIZATION
587// ================================================================================================
588
589impl Serializable for Smt {
590 fn write_into<W: ByteWriter>(&self, target: &mut W) {
591 // Write the number of filled leaves for this Smt
592 target.write_usize(self.entries().count());
593
594 // Write each (key, value) pair
595 for (key, value) in self.entries() {
596 target.write(key);
597 target.write(value);
598 }
599 }
600
601 fn get_size_hint(&self) -> usize {
602 let entries_count = self.entries().count();
603
604 // Each entry is the size of a digest plus a word.
605 entries_count.get_size_hint()
606 + entries_count * (Word::SERIALIZED_SIZE + EMPTY_WORD.get_size_hint())
607 }
608}
609
610impl Deserializable for Smt {
611 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
612 // Read the number of filled leaves for this Smt
613 let num_filled_leaves = source.read_usize()?;
614
615 // Use read_many_iter to avoid eager allocation and respect BudgetedReader limits
616 let entries: Vec<(Word, Word)> =
617 source.read_many_iter(num_filled_leaves)?.collect::<Result<_, _>>()?;
618
619 Self::with_entries(entries)
620 .map_err(|err| DeserializationError::InvalidValue(err.to_string()))
621 }
622
623 /// Minimum serialized size: vint64 length prefix (0 entries).
624 fn min_serialized_size() -> usize {
625 1
626 }
627}
628
629// FUZZING
630// ================================================================================================
631
632#[cfg(any(fuzzing, feature = "fuzzing"))]
633impl Smt {
634 pub fn fuzz_with_entries_sequential(
635 entries: impl IntoIterator<Item = (Word, Word)>,
636 ) -> Result<Smt, MerkleError> {
637 Self::with_entries_sequential(entries)
638 }
639
640 pub fn fuzz_compute_mutations_sequential(
641 &self,
642 kv_pairs: impl IntoIterator<Item = (Word, Word)>,
643 ) -> MutationSet<SMT_DEPTH, Word, Word> {
644 <Self as SparseMerkleTreeReader<SMT_DEPTH>>::compute_mutations(self, kv_pairs)
645 .expect("Failed to compute mutations in fuzzing")
646 }
647}
648
649// TESTS
650// ================================================================================================
651
652#[cfg(test)]
653use crate::Felt;
654
655#[test]
656fn test_smt_serialization_deserialization() {
657 // Smt for default types (empty map)
658 let smt_default = Smt::default();
659 let bytes = smt_default.to_bytes();
660 assert_eq!(smt_default, Smt::read_from_bytes(&bytes).unwrap());
661 assert_eq!(bytes.len(), smt_default.get_size_hint());
662
663 // Smt with values
664 let smt_leaves_2: [(Word, Word); 2] = [
665 (
666 Word::new([
667 Felt::new_unchecked(105),
668 Felt::new_unchecked(106),
669 Felt::new_unchecked(107),
670 Felt::new_unchecked(108),
671 ]),
672 [
673 Felt::new_unchecked(5_u64),
674 Felt::new_unchecked(6_u64),
675 Felt::new_unchecked(7_u64),
676 Felt::new_unchecked(8_u64),
677 ]
678 .into(),
679 ),
680 (
681 Word::new([
682 Felt::new_unchecked(101),
683 Felt::new_unchecked(102),
684 Felt::new_unchecked(103),
685 Felt::new_unchecked(104),
686 ]),
687 [
688 Felt::new_unchecked(1_u64),
689 Felt::new_unchecked(2_u64),
690 Felt::new_unchecked(3_u64),
691 Felt::new_unchecked(4_u64),
692 ]
693 .into(),
694 ),
695 ];
696 let smt = Smt::with_entries(smt_leaves_2).unwrap();
697
698 let bytes = smt.to_bytes();
699 assert_eq!(smt, Smt::read_from_bytes(&bytes).unwrap());
700 assert_eq!(bytes.len(), smt.get_size_hint());
701}
702
703#[test]
704fn smt_with_sorted_entries() {
705 // Smt with sorted values
706 let smt_leaves_2: [(Word, Word); 2] = [
707 (
708 Word::new([
709 Felt::new_unchecked(101),
710 Felt::new_unchecked(102),
711 Felt::new_unchecked(103),
712 Felt::new_unchecked(104),
713 ]),
714 [
715 Felt::new_unchecked(1_u64),
716 Felt::new_unchecked(2_u64),
717 Felt::new_unchecked(3_u64),
718 Felt::new_unchecked(4_u64),
719 ]
720 .into(),
721 ),
722 (
723 Word::new([
724 Felt::new_unchecked(105),
725 Felt::new_unchecked(106),
726 Felt::new_unchecked(107),
727 Felt::new_unchecked(108),
728 ]),
729 [
730 Felt::new_unchecked(5_u64),
731 Felt::new_unchecked(6_u64),
732 Felt::new_unchecked(7_u64),
733 Felt::new_unchecked(8_u64),
734 ]
735 .into(),
736 ),
737 ];
738
739 let smt = Smt::with_sorted_entries(smt_leaves_2).unwrap();
740 let expected_smt = Smt::with_entries(smt_leaves_2).unwrap();
741
742 assert_eq!(smt, expected_smt);
743}