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}