Skip to main content

miden_crypto/merkle/smt/full/
mod.rs

1use alloc::{string::ToString, vec::Vec};
2
3use super::{
4    EMPTY_WORD, EmptySubtreeRoots, Felt, InnerNode, InnerNodeInfo, InnerNodes, LeafIndex,
5    MerkleError, MutationSet, NodeIndex, Rpo256, SparseMerklePath, SparseMerkleTree, Word,
6};
7
8mod error;
9pub use error::{SmtLeafError, SmtProofError};
10
11mod leaf;
12pub use leaf::SmtLeaf;
13
14mod proof;
15pub use proof::SmtProof;
16use winter_utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable};
17
18// Concurrent implementation
19#[cfg(feature = "concurrent")]
20pub(in crate::merkle::smt) mod concurrent;
21
22#[cfg(test)]
23mod tests;
24
25// CONSTANTS
26// ================================================================================================
27
28/// The depth of the sparse Merkle tree.
29///
30/// All leaves in this SMT are located at depth 64.
31pub const SMT_DEPTH: u8 = 64;
32
33/// The maximum number of entries allowed in a multiple leaf.
34pub const MAX_LEAF_ENTRIES: usize = 1024;
35
36// SMT
37// ================================================================================================
38
39type Leaves = super::Leaves<SmtLeaf>;
40
41/// Sparse Merkle tree mapping 256-bit keys to 256-bit values. Both keys and values are represented
42/// by 4 field elements.
43///
44/// All leaves sit at depth 64. The most significant element of the key is used to identify the leaf
45/// to which the key maps.
46///
47/// A leaf is either empty, or holds one or more key-value pairs. An empty leaf hashes to the empty
48/// word. Otherwise, a leaf hashes to the hash of its key-value pairs, ordered by key first, value
49/// second.
50///
51/// ```text
52/// depth
53/// T  0                  Root
54/// │  .                  /  \
55/// │  1              left   right
56/// │  .             /  \    /  \
57/// │
58/// │          .. .. .. .. .. .. .. ..
59/// │
60/// │  63
61/// │           /  \        /   \           \
62/// │  ↓       /    \      /     \           \
63/// │  64   Leaf₀  Leaf₁  Leaf₂  Leaf₃  ...  Leaf₂⁶⁴₋₂³²
64///        0x0..0 0x0..1 0x0..2 0x0..3      0xFFFFFFFF00000000
65///
66/// The digest is 256 bits, or 4 field elements:
67/// [elem₀, elem₁, elem₂, elem₃]
68///                         ↑
69///         Most significant element determines leaf
70///         index, mapping into the actual Leaf lookup
71///         table where the values are stored.
72///
73/// Zooming into a leaf, i.e. Leaf₁:
74/// ┌─────────────────────────────────────────────────┐
75/// │            Leaf₁ (index: 0x0..1)                │
76/// ├─────────────────────────────────────────────────┤
77/// │ Possible states:                                │
78/// │                                                 │
79/// │ 1. Empty leaf:                                  │
80/// │    └─ hash = EMPTY_WORD                         │
81/// │                                                 │
82/// │ 2. Single entry:                                │
83/// │    └─ (key₁, value₁)                            │
84/// │    └─ hash = H(key₁, value₁)                    │
85/// │                                                 │
86/// │ 3. Multiple entries:                            │
87/// │    └─ (key₁, value₁)                            │
88/// │    └─ (key₂, value₂)                            │
89/// │    └─ ...                                       │
90/// │    └─ hash = H(key₁, value₁, key₂, value₂, ...) │
91/// └─────────────────────────────────────────────────┘
92///
93/// Leaf states:
94/// - Empty: hashes to EMPTY_WORD
95/// - Non-empty: contains (key, value) pairs
96///              hash = H(key₁, value₁, key₂, value₂, ...)
97/// ```
98#[derive(Debug, Clone, PartialEq, Eq)]
99#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
100pub struct Smt {
101    root: Word,
102    // pub(super) for use in PartialSmt.
103    pub(super) num_entries: usize,
104    pub(super) leaves: Leaves,
105    pub(super) 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 SparseMerkleTree<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).value(),
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        // Our particular implementation of `from_raw_parts()` never returns `Err`.
225        <Self as SparseMerkleTree<SMT_DEPTH>>::from_raw_parts(inner_nodes, leaves, root).unwrap()
226    }
227
228    // PUBLIC ACCESSORS
229    // --------------------------------------------------------------------------------------------
230
231    /// Returns the depth of the tree
232    pub const fn depth(&self) -> u8 {
233        SMT_DEPTH
234    }
235
236    /// Returns the root of the tree
237    pub fn root(&self) -> Word {
238        <Self as SparseMerkleTree<SMT_DEPTH>>::root(self)
239    }
240
241    /// Returns the number of non-empty leaves in this tree.
242    ///
243    /// Note that this may return a different value from [Self::num_entries()] as a single leaf may
244    /// contain more than one key-value pair.
245    pub fn num_leaves(&self) -> usize {
246        self.leaves.len()
247    }
248
249    /// Returns the number of key-value pairs with non-default values in this tree.
250    ///
251    /// Note that this may return a different value from [Self::num_leaves()] as a single leaf may
252    /// contain more than one key-value pair.
253    pub fn num_entries(&self) -> usize {
254        self.num_entries
255    }
256
257    /// Returns the leaf to which `key` maps
258    pub fn get_leaf(&self, key: &Word) -> SmtLeaf {
259        <Self as SparseMerkleTree<SMT_DEPTH>>::get_leaf(self, key)
260    }
261
262    /// Returns the leaf corresponding to the provided `index`.
263    pub fn get_leaf_by_index(&self, index: LeafIndex<SMT_DEPTH>) -> Option<SmtLeaf> {
264        self.leaves.get(&index.position()).cloned()
265    }
266
267    /// Returns the value associated with `key`
268    pub fn get_value(&self, key: &Word) -> Word {
269        <Self as SparseMerkleTree<SMT_DEPTH>>::get_value(self, key)
270    }
271
272    /// Returns an opening of the leaf associated with `key`. Conceptually, an opening is a Merkle
273    /// path to the leaf, as well as the leaf itself.
274    pub fn open(&self, key: &Word) -> SmtProof {
275        <Self as SparseMerkleTree<SMT_DEPTH>>::open(self, key)
276    }
277
278    /// Returns a boolean value indicating whether the SMT is empty.
279    pub fn is_empty(&self) -> bool {
280        debug_assert_eq!(self.leaves.is_empty(), self.root == Self::EMPTY_ROOT);
281        self.root == Self::EMPTY_ROOT
282    }
283
284    // ITERATORS
285    // --------------------------------------------------------------------------------------------
286
287    /// Returns an iterator over the leaves of this [`Smt`] in arbitrary order.
288    pub fn leaves(&self) -> impl Iterator<Item = (LeafIndex<SMT_DEPTH>, &SmtLeaf)> {
289        self.leaves
290            .iter()
291            .map(|(leaf_index, leaf)| (LeafIndex::new_max_depth(*leaf_index), leaf))
292    }
293
294    /// Returns an iterator over the key-value pairs of this [Smt] in arbitrary order.
295    pub fn entries(&self) -> impl Iterator<Item = &(Word, Word)> {
296        self.leaves().flat_map(|(_, leaf)| leaf.entries())
297    }
298
299    /// Returns an iterator over the inner nodes of this [Smt].
300    pub fn inner_nodes(&self) -> impl Iterator<Item = InnerNodeInfo> + '_ {
301        self.inner_nodes.values().map(|e| InnerNodeInfo {
302            value: e.hash(),
303            left: e.left,
304            right: e.right,
305        })
306    }
307
308    /// Returns an iterator over the [`InnerNode`] and the respective [`NodeIndex`] of the [`Smt`].
309    pub fn inner_node_indices(&self) -> impl Iterator<Item = (NodeIndex, InnerNode)> + '_ {
310        self.inner_nodes.iter().map(|(idx, inner)| (*idx, inner.clone()))
311    }
312
313    // STATE MUTATORS
314    // --------------------------------------------------------------------------------------------
315
316    /// Inserts a value at the specified key, returning the previous value associated with that key.
317    /// Recall that by definition, any key that hasn't been updated is associated with
318    /// [`Self::EMPTY_VALUE`].
319    ///
320    /// This also recomputes all hashes between the leaf (associated with the key) and the root,
321    /// updating the root itself.
322    ///
323    /// # Errors
324    /// Returns an error if inserting the key-value pair would exceed [`MAX_LEAF_ENTRIES`] (1024
325    /// entries) in the leaf.
326    pub fn insert(&mut self, key: Word, value: Word) -> Result<Word, MerkleError> {
327        <Self as SparseMerkleTree<SMT_DEPTH>>::insert(self, key, value)
328    }
329
330    /// Computes what changes are necessary to insert the specified key-value pairs into this Merkle
331    /// tree, allowing for validation before applying those changes.
332    ///
333    /// This method returns a [`MutationSet`], which contains all the information for inserting
334    /// `kv_pairs` into this Merkle tree already calculated, including the new root hash, which can
335    /// be queried with [`MutationSet::root()`]. Once a mutation set is returned,
336    /// [`Smt::apply_mutations()`] can be called in order to commit these changes to the Merkle
337    /// tree, or [`drop()`] to discard them.
338    ///
339    /// # Example
340    /// ```
341    /// # use miden_crypto::{Felt, Word};
342    /// # use miden_crypto::merkle::{EmptySubtreeRoots, smt::{Smt, SMT_DEPTH}};
343    /// let mut smt = Smt::new();
344    /// let pair = (Word::default(), Word::default());
345    /// let mutations = smt.compute_mutations(vec![pair]).unwrap();
346    /// assert_eq!(mutations.root(), *EmptySubtreeRoots::entry(SMT_DEPTH, 0));
347    /// smt.apply_mutations(mutations).unwrap();
348    /// assert_eq!(smt.root(), *EmptySubtreeRoots::entry(SMT_DEPTH, 0));
349    /// ```
350    pub fn compute_mutations(
351        &self,
352        kv_pairs: impl IntoIterator<Item = (Word, Word)>,
353    ) -> Result<MutationSet<SMT_DEPTH, Word, Word>, MerkleError> {
354        #[cfg(feature = "concurrent")]
355        {
356            self.compute_mutations_concurrent(kv_pairs)
357        }
358        #[cfg(not(feature = "concurrent"))]
359        {
360            <Self as SparseMerkleTree<SMT_DEPTH>>::compute_mutations(self, kv_pairs)
361        }
362    }
363
364    /// Applies the prospective mutations computed with [`Smt::compute_mutations()`] to this tree.
365    ///
366    /// # Errors
367    /// If `mutations` was computed on a tree with a different root than this one, returns
368    /// [`MerkleError::ConflictingRoots`] with a two-item [`Vec`]. The first item is the root hash
369    /// the `mutations` were computed against, and the second item is the actual current root of
370    /// this tree.
371    pub fn apply_mutations(
372        &mut self,
373        mutations: MutationSet<SMT_DEPTH, Word, Word>,
374    ) -> Result<(), MerkleError> {
375        <Self as SparseMerkleTree<SMT_DEPTH>>::apply_mutations(self, mutations)
376    }
377
378    /// Applies the prospective mutations computed with [`Smt::compute_mutations()`] to this tree
379    /// and returns the reverse mutation set.
380    ///
381    /// Applying the reverse mutation sets to the updated tree will revert the changes.
382    ///
383    /// # Errors
384    /// If `mutations` was computed on a tree with a different root than this one, returns
385    /// [`MerkleError::ConflictingRoots`] with a two-item [`Vec`]. The first item is the root hash
386    /// the `mutations` were computed against, and the second item is the actual current root of
387    /// this tree.
388    pub fn apply_mutations_with_reversion(
389        &mut self,
390        mutations: MutationSet<SMT_DEPTH, Word, Word>,
391    ) -> Result<MutationSet<SMT_DEPTH, Word, Word>, MerkleError> {
392        <Self as SparseMerkleTree<SMT_DEPTH>>::apply_mutations_with_reversion(self, mutations)
393    }
394
395    // HELPERS
396    // --------------------------------------------------------------------------------------------
397
398    /// Inserts `value` at leaf index pointed to by `key`. `value` is guaranteed to not be the empty
399    /// value, such that this is indeed an insertion.
400    ///
401    /// # Errors
402    /// Returns an error if inserting the key-value pair would exceed [`MAX_LEAF_ENTRIES`] (1024
403    /// entries) in the leaf.
404    fn perform_insert(&mut self, key: Word, value: Word) -> Result<Option<Word>, MerkleError> {
405        debug_assert_ne!(value, Self::EMPTY_VALUE);
406
407        let leaf_index: LeafIndex<SMT_DEPTH> = Self::key_to_leaf_index(&key);
408
409        match self.leaves.get_mut(&leaf_index.value()) {
410            Some(leaf) => {
411                let prev_entries = leaf.num_entries();
412                let result = leaf.insert(key, value).map_err(|e| match e {
413                    SmtLeafError::TooManyLeafEntries { actual } => {
414                        MerkleError::TooManyLeafEntries { actual }
415                    },
416                    other => panic!("unexpected SmtLeaf::insert error: {:?}", other),
417                })?;
418                let current_entries = leaf.num_entries();
419                self.num_entries += current_entries - prev_entries;
420                Ok(result)
421            },
422            None => {
423                self.leaves.insert(leaf_index.value(), SmtLeaf::Single((key, value)));
424                self.num_entries += 1;
425                Ok(None)
426            },
427        }
428    }
429
430    /// Removes key-value pair at leaf index pointed to by `key` if it exists.
431    fn perform_remove(&mut self, key: Word) -> Option<Word> {
432        let leaf_index: LeafIndex<SMT_DEPTH> = Self::key_to_leaf_index(&key);
433
434        if let Some(leaf) = self.leaves.get_mut(&leaf_index.value()) {
435            let prev_entries = leaf.num_entries();
436            let (old_value, is_empty) = leaf.remove(key);
437            let current_entries = leaf.num_entries();
438            self.num_entries -= prev_entries - current_entries;
439            if is_empty {
440                self.leaves.remove(&leaf_index.value());
441            }
442            old_value
443        } else {
444            // there's nothing stored at the leaf; nothing to update
445            None
446        }
447    }
448}
449
450impl SparseMerkleTree<SMT_DEPTH> for Smt {
451    type Key = Word;
452    type Value = Word;
453    type Leaf = SmtLeaf;
454    type Opening = SmtProof;
455
456    const EMPTY_VALUE: Self::Value = EMPTY_WORD;
457    const EMPTY_ROOT: Word = *EmptySubtreeRoots::entry(SMT_DEPTH, 0);
458
459    fn from_raw_parts(
460        inner_nodes: InnerNodes,
461        leaves: Leaves,
462        root: Word,
463    ) -> Result<Self, MerkleError> {
464        if cfg!(debug_assertions) {
465            let root_node_hash = inner_nodes
466                .get(&NodeIndex::root())
467                .map(InnerNode::hash)
468                .unwrap_or(Self::EMPTY_ROOT);
469
470            assert_eq!(root_node_hash, root);
471        }
472        let num_entries = leaves.values().map(|leaf| leaf.num_entries()).sum();
473        Ok(Self { root, inner_nodes, leaves, num_entries })
474    }
475
476    fn root(&self) -> Word {
477        self.root
478    }
479
480    fn set_root(&mut self, root: Word) {
481        self.root = root;
482    }
483
484    fn get_inner_node(&self, index: NodeIndex) -> InnerNode {
485        self.inner_nodes
486            .get(&index)
487            .cloned()
488            .unwrap_or_else(|| EmptySubtreeRoots::get_inner_node(SMT_DEPTH, index.depth()))
489    }
490
491    fn insert_inner_node(&mut self, index: NodeIndex, inner_node: InnerNode) -> Option<InnerNode> {
492        if inner_node == EmptySubtreeRoots::get_inner_node(SMT_DEPTH, index.depth()) {
493            self.remove_inner_node(index)
494        } else {
495            self.inner_nodes.insert(index, inner_node)
496        }
497    }
498
499    fn remove_inner_node(&mut self, index: NodeIndex) -> Option<InnerNode> {
500        self.inner_nodes.remove(&index)
501    }
502
503    fn insert_value(
504        &mut self,
505        key: Self::Key,
506        value: Self::Value,
507    ) -> Result<Option<Self::Value>, MerkleError> {
508        // inserting an `EMPTY_VALUE` is equivalent to removing any value associated with `key`
509        if value != Self::EMPTY_VALUE {
510            self.perform_insert(key, value)
511        } else {
512            Ok(self.perform_remove(key))
513        }
514    }
515
516    fn get_value(&self, key: &Self::Key) -> Self::Value {
517        let leaf_pos = LeafIndex::<SMT_DEPTH>::from(*key).value();
518
519        match self.leaves.get(&leaf_pos) {
520            Some(leaf) => leaf.get_value(key).unwrap_or_default(),
521            None => EMPTY_WORD,
522        }
523    }
524
525    fn get_leaf(&self, key: &Word) -> Self::Leaf {
526        let leaf_pos = LeafIndex::<SMT_DEPTH>::from(*key).value();
527
528        match self.leaves.get(&leaf_pos) {
529            Some(leaf) => leaf.clone(),
530            None => SmtLeaf::new_empty((*key).into()),
531        }
532    }
533
534    fn hash_leaf(leaf: &Self::Leaf) -> Word {
535        leaf.hash()
536    }
537
538    fn construct_prospective_leaf(
539        &self,
540        mut existing_leaf: SmtLeaf,
541        key: &Word,
542        value: &Word,
543    ) -> Result<SmtLeaf, SmtLeafError> {
544        debug_assert_eq!(existing_leaf.index(), Self::key_to_leaf_index(key));
545
546        match existing_leaf {
547            SmtLeaf::Empty(_) => Ok(SmtLeaf::new_single(*key, *value)),
548            _ => {
549                if *value != EMPTY_WORD {
550                    existing_leaf.insert(*key, *value)?;
551                } else {
552                    existing_leaf.remove(*key);
553                }
554
555                Ok(existing_leaf)
556            },
557        }
558    }
559
560    fn key_to_leaf_index(key: &Word) -> LeafIndex<SMT_DEPTH> {
561        let most_significant_felt = key[3];
562        LeafIndex::new_max_depth(most_significant_felt.as_int())
563    }
564
565    fn path_and_leaf_to_opening(path: SparseMerklePath, leaf: SmtLeaf) -> SmtProof {
566        SmtProof::new_unchecked(path, leaf)
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_int())
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        let mut entries = Vec::with_capacity(num_filled_leaves);
615
616        for _ in 0..num_filled_leaves {
617            let key = source.read()?;
618            let value = source.read()?;
619            entries.push((key, value));
620        }
621
622        Self::with_entries(entries)
623            .map_err(|err| DeserializationError::InvalidValue(err.to_string()))
624    }
625}
626
627// FUZZING
628// ================================================================================================
629
630#[cfg(any(fuzzing, feature = "fuzzing"))]
631impl Smt {
632    pub fn fuzz_with_entries_sequential(
633        entries: impl IntoIterator<Item = (Word, Word)>,
634    ) -> Result<Smt, MerkleError> {
635        Self::with_entries_sequential(entries)
636    }
637
638    pub fn fuzz_compute_mutations_sequential(
639        &self,
640        kv_pairs: impl IntoIterator<Item = (Word, Word)>,
641    ) -> MutationSet<SMT_DEPTH, Word, Word> {
642        <Self as SparseMerkleTree<SMT_DEPTH>>::compute_mutations(self, kv_pairs)
643            .expect("Failed to compute mutations in fuzzing")
644    }
645}
646
647// TESTS
648// ================================================================================================
649
650#[test]
651fn test_smt_serialization_deserialization() {
652    // Smt for default types (empty map)
653    let smt_default = Smt::default();
654    let bytes = smt_default.to_bytes();
655    assert_eq!(smt_default, Smt::read_from_bytes(&bytes).unwrap());
656    assert_eq!(bytes.len(), smt_default.get_size_hint());
657
658    // Smt with values
659    let smt_leaves_2: [(Word, Word); 2] = [
660        (
661            Word::new([Felt::new(105), Felt::new(106), Felt::new(107), Felt::new(108)]),
662            [Felt::new(5_u64), Felt::new(6_u64), Felt::new(7_u64), Felt::new(8_u64)].into(),
663        ),
664        (
665            Word::new([Felt::new(101), Felt::new(102), Felt::new(103), Felt::new(104)]),
666            [Felt::new(1_u64), Felt::new(2_u64), Felt::new(3_u64), Felt::new(4_u64)].into(),
667        ),
668    ];
669    let smt = Smt::with_entries(smt_leaves_2).unwrap();
670
671    let bytes = smt.to_bytes();
672    assert_eq!(smt, Smt::read_from_bytes(&bytes).unwrap());
673    assert_eq!(bytes.len(), smt.get_size_hint());
674}
675
676#[test]
677fn smt_with_sorted_entries() {
678    // Smt with sorted values
679    let smt_leaves_2: [(Word, Word); 2] = [
680        (
681            Word::new([Felt::new(101), Felt::new(102), Felt::new(103), Felt::new(104)]),
682            [Felt::new(1_u64), Felt::new(2_u64), Felt::new(3_u64), Felt::new(4_u64)].into(),
683        ),
684        (
685            Word::new([Felt::new(105), Felt::new(106), Felt::new(107), Felt::new(108)]),
686            [Felt::new(5_u64), Felt::new(6_u64), Felt::new(7_u64), Felt::new(8_u64)].into(),
687        ),
688    ];
689
690    let smt = Smt::with_sorted_entries(smt_leaves_2).unwrap();
691    let expected_smt = Smt::with_entries(smt_leaves_2).unwrap();
692
693    assert_eq!(smt, expected_smt);
694}