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