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, 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 value associated with `key`
263 pub fn get_value(&self, key: &Word) -> Word {
264 <Self as SparseMerkleTree<SMT_DEPTH>>::get_value(self, key)
265 }
266
267 /// Returns an opening of the leaf associated with `key`. Conceptually, an opening is a Merkle
268 /// path to the leaf, as well as the leaf itself.
269 pub fn open(&self, key: &Word) -> SmtProof {
270 <Self as SparseMerkleTree<SMT_DEPTH>>::open(self, key)
271 }
272
273 /// Returns a boolean value indicating whether the SMT is empty.
274 pub fn is_empty(&self) -> bool {
275 debug_assert_eq!(self.leaves.is_empty(), self.root == Self::EMPTY_ROOT);
276 self.root == Self::EMPTY_ROOT
277 }
278
279 // ITERATORS
280 // --------------------------------------------------------------------------------------------
281
282 /// Returns an iterator over the leaves of this [`Smt`] in arbitrary order.
283 pub fn leaves(&self) -> impl Iterator<Item = (LeafIndex<SMT_DEPTH>, &SmtLeaf)> {
284 self.leaves
285 .iter()
286 .map(|(leaf_index, leaf)| (LeafIndex::new_max_depth(*leaf_index), leaf))
287 }
288
289 /// Returns an iterator over the key-value pairs of this [Smt] in arbitrary order.
290 pub fn entries(&self) -> impl Iterator<Item = &(Word, Word)> {
291 self.leaves().flat_map(|(_, leaf)| leaf.entries())
292 }
293
294 /// Returns an iterator over the inner nodes of this [Smt].
295 pub fn inner_nodes(&self) -> impl Iterator<Item = InnerNodeInfo> + '_ {
296 self.inner_nodes.values().map(|e| InnerNodeInfo {
297 value: e.hash(),
298 left: e.left,
299 right: e.right,
300 })
301 }
302
303 /// Returns an iterator over the [`InnerNode`] and the respective [`NodeIndex`] of the [`Smt`].
304 pub fn inner_node_indices(&self) -> impl Iterator<Item = (NodeIndex, InnerNode)> + '_ {
305 self.inner_nodes.iter().map(|(idx, inner)| (*idx, inner.clone()))
306 }
307
308 // STATE MUTATORS
309 // --------------------------------------------------------------------------------------------
310
311 /// Inserts a value at the specified key, returning the previous value associated with that key.
312 /// Recall that by definition, any key that hasn't been updated is associated with
313 /// [`Self::EMPTY_VALUE`].
314 ///
315 /// This also recomputes all hashes between the leaf (associated with the key) and the root,
316 /// updating the root itself.
317 ///
318 /// # Errors
319 /// Returns an error if inserting the key-value pair would exceed [`MAX_LEAF_ENTRIES`] (1024
320 /// entries) in the leaf.
321 pub fn insert(&mut self, key: Word, value: Word) -> Result<Word, MerkleError> {
322 <Self as SparseMerkleTree<SMT_DEPTH>>::insert(self, key, value)
323 }
324
325 /// Computes what changes are necessary to insert the specified key-value pairs into this Merkle
326 /// tree, allowing for validation before applying those changes.
327 ///
328 /// This method returns a [`MutationSet`], which contains all the information for inserting
329 /// `kv_pairs` into this Merkle tree already calculated, including the new root hash, which can
330 /// be queried with [`MutationSet::root()`]. Once a mutation set is returned,
331 /// [`Smt::apply_mutations()`] can be called in order to commit these changes to the Merkle
332 /// tree, or [`drop()`] to discard them.
333 ///
334 /// # Example
335 /// ```
336 /// # use miden_crypto::{Felt, Word};
337 /// # use miden_crypto::merkle::{Smt, EmptySubtreeRoots, SMT_DEPTH};
338 /// let mut smt = Smt::new();
339 /// let pair = (Word::default(), Word::default());
340 /// let mutations = smt.compute_mutations(vec![pair]).unwrap();
341 /// assert_eq!(mutations.root(), *EmptySubtreeRoots::entry(SMT_DEPTH, 0));
342 /// smt.apply_mutations(mutations).unwrap();
343 /// assert_eq!(smt.root(), *EmptySubtreeRoots::entry(SMT_DEPTH, 0));
344 /// ```
345 pub fn compute_mutations(
346 &self,
347 kv_pairs: impl IntoIterator<Item = (Word, Word)>,
348 ) -> Result<MutationSet<SMT_DEPTH, Word, Word>, MerkleError> {
349 #[cfg(feature = "concurrent")]
350 {
351 self.compute_mutations_concurrent(kv_pairs)
352 }
353 #[cfg(not(feature = "concurrent"))]
354 {
355 <Self as SparseMerkleTree<SMT_DEPTH>>::compute_mutations(self, kv_pairs)
356 }
357 }
358
359 /// Applies the prospective mutations computed with [`Smt::compute_mutations()`] to this tree.
360 ///
361 /// # Errors
362 /// If `mutations` was computed on a tree with a different root than this one, returns
363 /// [`MerkleError::ConflictingRoots`] with a two-item [`Vec`]. The first item is the root hash
364 /// the `mutations` were computed against, and the second item is the actual current root of
365 /// this tree.
366 pub fn apply_mutations(
367 &mut self,
368 mutations: MutationSet<SMT_DEPTH, Word, Word>,
369 ) -> Result<(), MerkleError> {
370 <Self as SparseMerkleTree<SMT_DEPTH>>::apply_mutations(self, mutations)
371 }
372
373 /// Applies the prospective mutations computed with [`Smt::compute_mutations()`] to this tree
374 /// and returns the reverse mutation set.
375 ///
376 /// Applying the reverse mutation sets to the updated tree will revert the changes.
377 ///
378 /// # Errors
379 /// If `mutations` was computed on a tree with a different root than this one, returns
380 /// [`MerkleError::ConflictingRoots`] with a two-item [`Vec`]. The first item is the root hash
381 /// the `mutations` were computed against, and the second item is the actual current root of
382 /// this tree.
383 pub fn apply_mutations_with_reversion(
384 &mut self,
385 mutations: MutationSet<SMT_DEPTH, Word, Word>,
386 ) -> Result<MutationSet<SMT_DEPTH, Word, Word>, MerkleError> {
387 <Self as SparseMerkleTree<SMT_DEPTH>>::apply_mutations_with_reversion(self, mutations)
388 }
389
390 // HELPERS
391 // --------------------------------------------------------------------------------------------
392
393 /// Inserts `value` at leaf index pointed to by `key`. `value` is guaranteed to not be the empty
394 /// value, such that this is indeed an insertion.
395 ///
396 /// # Errors
397 /// Returns an error if inserting the key-value pair would exceed [`MAX_LEAF_ENTRIES`] (1024
398 /// entries) in the leaf.
399 fn perform_insert(&mut self, key: Word, value: Word) -> Result<Option<Word>, MerkleError> {
400 debug_assert_ne!(value, Self::EMPTY_VALUE);
401
402 let leaf_index: LeafIndex<SMT_DEPTH> = Self::key_to_leaf_index(&key);
403
404 match self.leaves.get_mut(&leaf_index.value()) {
405 Some(leaf) => {
406 let prev_entries = leaf.num_entries();
407 let result = leaf.insert(key, value).map_err(|e| match e {
408 SmtLeafError::TooManyLeafEntries { actual } => {
409 MerkleError::TooManyLeafEntries { actual }
410 },
411 other => panic!("unexpected SmtLeaf::insert error: {:?}", other),
412 })?;
413 let current_entries = leaf.num_entries();
414 self.num_entries += current_entries - prev_entries;
415 Ok(result)
416 },
417 None => {
418 self.leaves.insert(leaf_index.value(), SmtLeaf::Single((key, value)));
419 self.num_entries += 1;
420 Ok(None)
421 },
422 }
423 }
424
425 /// Removes key-value pair at leaf index pointed to by `key` if it exists.
426 fn perform_remove(&mut self, key: Word) -> Option<Word> {
427 let leaf_index: LeafIndex<SMT_DEPTH> = Self::key_to_leaf_index(&key);
428
429 if let Some(leaf) = self.leaves.get_mut(&leaf_index.value()) {
430 let prev_entries = leaf.num_entries();
431 let (old_value, is_empty) = leaf.remove(key);
432 let current_entries = leaf.num_entries();
433 self.num_entries -= prev_entries - current_entries;
434 if is_empty {
435 self.leaves.remove(&leaf_index.value());
436 }
437 old_value
438 } else {
439 // there's nothing stored at the leaf; nothing to update
440 None
441 }
442 }
443}
444
445impl SparseMerkleTree<SMT_DEPTH> for Smt {
446 type Key = Word;
447 type Value = Word;
448 type Leaf = SmtLeaf;
449 type Opening = SmtProof;
450
451 const EMPTY_VALUE: Self::Value = EMPTY_WORD;
452 const EMPTY_ROOT: Word = *EmptySubtreeRoots::entry(SMT_DEPTH, 0);
453
454 fn from_raw_parts(
455 inner_nodes: InnerNodes,
456 leaves: Leaves,
457 root: Word,
458 ) -> Result<Self, MerkleError> {
459 if cfg!(debug_assertions) {
460 let root_node_hash = inner_nodes
461 .get(&NodeIndex::root())
462 .map(InnerNode::hash)
463 .unwrap_or(Self::EMPTY_ROOT);
464
465 assert_eq!(root_node_hash, root);
466 }
467 let num_entries = leaves.values().map(|leaf| leaf.num_entries()).sum();
468 Ok(Self { root, inner_nodes, leaves, num_entries })
469 }
470
471 fn root(&self) -> Word {
472 self.root
473 }
474
475 fn set_root(&mut self, root: Word) {
476 self.root = root;
477 }
478
479 fn get_inner_node(&self, index: NodeIndex) -> InnerNode {
480 self.inner_nodes
481 .get(&index)
482 .cloned()
483 .unwrap_or_else(|| EmptySubtreeRoots::get_inner_node(SMT_DEPTH, index.depth()))
484 }
485
486 fn insert_inner_node(&mut self, index: NodeIndex, inner_node: InnerNode) -> Option<InnerNode> {
487 if inner_node == EmptySubtreeRoots::get_inner_node(SMT_DEPTH, index.depth()) {
488 self.remove_inner_node(index)
489 } else {
490 self.inner_nodes.insert(index, inner_node)
491 }
492 }
493
494 fn remove_inner_node(&mut self, index: NodeIndex) -> Option<InnerNode> {
495 self.inner_nodes.remove(&index)
496 }
497
498 fn insert_value(
499 &mut self,
500 key: Self::Key,
501 value: Self::Value,
502 ) -> Result<Option<Self::Value>, MerkleError> {
503 // inserting an `EMPTY_VALUE` is equivalent to removing any value associated with `key`
504 if value != Self::EMPTY_VALUE {
505 self.perform_insert(key, value)
506 } else {
507 Ok(self.perform_remove(key))
508 }
509 }
510
511 fn get_value(&self, key: &Self::Key) -> Self::Value {
512 let leaf_pos = LeafIndex::<SMT_DEPTH>::from(*key).value();
513
514 match self.leaves.get(&leaf_pos) {
515 Some(leaf) => leaf.get_value(key).unwrap_or_default(),
516 None => EMPTY_WORD,
517 }
518 }
519
520 fn get_leaf(&self, key: &Word) -> Self::Leaf {
521 let leaf_pos = LeafIndex::<SMT_DEPTH>::from(*key).value();
522
523 match self.leaves.get(&leaf_pos) {
524 Some(leaf) => leaf.clone(),
525 None => SmtLeaf::new_empty((*key).into()),
526 }
527 }
528
529 fn hash_leaf(leaf: &Self::Leaf) -> Word {
530 leaf.hash()
531 }
532
533 fn construct_prospective_leaf(
534 &self,
535 mut existing_leaf: SmtLeaf,
536 key: &Word,
537 value: &Word,
538 ) -> Result<SmtLeaf, SmtLeafError> {
539 debug_assert_eq!(existing_leaf.index(), Self::key_to_leaf_index(key));
540
541 match existing_leaf {
542 SmtLeaf::Empty(_) => Ok(SmtLeaf::new_single(*key, *value)),
543 _ => {
544 if *value != EMPTY_WORD {
545 existing_leaf.insert(*key, *value)?;
546 } else {
547 existing_leaf.remove(*key);
548 }
549
550 Ok(existing_leaf)
551 },
552 }
553 }
554
555 fn key_to_leaf_index(key: &Word) -> LeafIndex<SMT_DEPTH> {
556 let most_significant_felt = key[3];
557 LeafIndex::new_max_depth(most_significant_felt.as_int())
558 }
559
560 fn path_and_leaf_to_opening(path: SparseMerklePath, leaf: SmtLeaf) -> SmtProof {
561 SmtProof::new_unchecked(path, leaf)
562 }
563}
564
565impl Default for Smt {
566 fn default() -> Self {
567 Self::new()
568 }
569}
570
571// CONVERSIONS
572// ================================================================================================
573
574impl From<Word> for LeafIndex<SMT_DEPTH> {
575 fn from(value: Word) -> Self {
576 // We use the most significant `Felt` of a `Word` as the leaf index.
577 Self::new_max_depth(value[3].as_int())
578 }
579}
580
581// SERIALIZATION
582// ================================================================================================
583
584impl Serializable for Smt {
585 fn write_into<W: ByteWriter>(&self, target: &mut W) {
586 // Write the number of filled leaves for this Smt
587 target.write_usize(self.entries().count());
588
589 // Write each (key, value) pair
590 for (key, value) in self.entries() {
591 target.write(key);
592 target.write(value);
593 }
594 }
595
596 fn get_size_hint(&self) -> usize {
597 let entries_count = self.entries().count();
598
599 // Each entry is the size of a digest plus a word.
600 entries_count.get_size_hint()
601 + entries_count * (Word::SERIALIZED_SIZE + EMPTY_WORD.get_size_hint())
602 }
603}
604
605impl Deserializable for Smt {
606 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
607 // Read the number of filled leaves for this Smt
608 let num_filled_leaves = source.read_usize()?;
609 let mut entries = Vec::with_capacity(num_filled_leaves);
610
611 for _ in 0..num_filled_leaves {
612 let key = source.read()?;
613 let value = source.read()?;
614 entries.push((key, value));
615 }
616
617 Self::with_entries(entries)
618 .map_err(|err| DeserializationError::InvalidValue(err.to_string()))
619 }
620}
621
622// FUZZING
623// ================================================================================================
624
625#[cfg(fuzzing)]
626impl Smt {
627 pub fn fuzz_with_entries_sequential(
628 entries: impl IntoIterator<Item = (Word, Word)>,
629 ) -> Result<Smt, MerkleError> {
630 Self::with_entries_sequential(entries)
631 }
632
633 pub fn fuzz_compute_mutations_sequential(
634 &self,
635 kv_pairs: impl IntoIterator<Item = (Word, Word)>,
636 ) -> MutationSet<SMT_DEPTH, Word, Word> {
637 <Self as SparseMerkleTree<SMT_DEPTH>>::compute_mutations(self, kv_pairs)
638 }
639}
640
641// TESTS
642// ================================================================================================
643
644#[test]
645fn test_smt_serialization_deserialization() {
646 // Smt for default types (empty map)
647 let smt_default = Smt::default();
648 let bytes = smt_default.to_bytes();
649 assert_eq!(smt_default, Smt::read_from_bytes(&bytes).unwrap());
650 assert_eq!(bytes.len(), smt_default.get_size_hint());
651
652 // Smt with values
653 let smt_leaves_2: [(Word, Word); 2] = [
654 (
655 Word::new([Felt::new(105), Felt::new(106), Felt::new(107), Felt::new(108)]),
656 [Felt::new(5_u64), Felt::new(6_u64), Felt::new(7_u64), Felt::new(8_u64)].into(),
657 ),
658 (
659 Word::new([Felt::new(101), Felt::new(102), Felt::new(103), Felt::new(104)]),
660 [Felt::new(1_u64), Felt::new(2_u64), Felt::new(3_u64), Felt::new(4_u64)].into(),
661 ),
662 ];
663 let smt = Smt::with_entries(smt_leaves_2).unwrap();
664
665 let bytes = smt.to_bytes();
666 assert_eq!(smt, Smt::read_from_bytes(&bytes).unwrap());
667 assert_eq!(bytes.len(), smt.get_size_hint());
668}
669
670#[test]
671fn smt_with_sorted_entries() {
672 // Smt with sorted values
673 let smt_leaves_2: [(Word, Word); 2] = [
674 (
675 Word::new([Felt::new(101), Felt::new(102), Felt::new(103), Felt::new(104)]),
676 [Felt::new(1_u64), Felt::new(2_u64), Felt::new(3_u64), Felt::new(4_u64)].into(),
677 ),
678 (
679 Word::new([Felt::new(105), Felt::new(106), Felt::new(107), Felt::new(108)]),
680 [Felt::new(5_u64), Felt::new(6_u64), Felt::new(7_u64), Felt::new(8_u64)].into(),
681 ),
682 ];
683
684 let smt = Smt::with_sorted_entries(smt_leaves_2).unwrap();
685 let expected_smt = Smt::with_entries(smt_leaves_2).unwrap();
686
687 assert_eq!(smt, expected_smt);
688}