Skip to main content

miden_crypto/merkle/smt/
mod.rs

1//! Sparse Merkle Tree (SMT) data structures.
2
3use alloc::vec::Vec;
4use core::{
5    fmt::{self, Display},
6    hash::Hash,
7};
8
9use super::{EmptySubtreeRoots, InnerNodeInfo, MerkleError, NodeIndex, SparseMerklePath};
10use crate::{
11    EMPTY_WORD, Map, Set, Word,
12    hash::poseidon2::Poseidon2,
13    utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable},
14};
15
16mod full;
17pub use full::{MAX_LEAF_ENTRIES, SMT_DEPTH, Smt, SmtLeaf, SmtLeafError, SmtProof, SmtProofError};
18
19#[cfg(feature = "concurrent")]
20mod large;
21#[cfg(feature = "internal")]
22pub use full::concurrent::{SubtreeLeaf, build_subtree_for_bench};
23#[cfg(feature = "concurrent")]
24pub use large::{
25    LargeSmt, LargeSmtError, MemoryStorage, MemoryStorageSnapshot, SmtStorage, SmtStorageReader,
26    StorageError, StorageUpdateParts, StorageUpdates, Subtree, SubtreeError, SubtreeUpdate,
27};
28#[cfg(feature = "rocksdb")]
29pub use large::{RocksDbConfig, RocksDbSnapshotStorage, RocksDbStorage};
30
31mod large_forest;
32pub use large_forest::{
33    Backend, BackendError, Config as ForestConfig,
34    DEFAULT_MAX_HISTORY_VERSIONS as FOREST_DEFAULT_MAX_HISTORY_VERSIONS, ForestOperation,
35    InMemoryBackend as ForestInMemoryBackend, LargeSmtForest, LargeSmtForestError, LineageId,
36    MIN_HISTORY_VERSIONS as FOREST_MIN_HISTORY_VERSIONS, RootInfo, SmtForestUpdateBatch,
37    SmtUpdateBatch, TreeEntry, TreeId, TreeWithRoot, VersionId,
38};
39#[cfg(feature = "persistent-forest")]
40pub use large_forest::{PersistentBackend as ForestPersistentBackend, PersistentBackendConfig};
41
42mod simple;
43pub use simple::{SimpleSmt, SimpleSmtProof};
44
45mod partial;
46pub use partial::{NodeValue, PartialSmt, UniqueNodes};
47
48mod forest;
49pub use forest::SmtForest;
50use miden_field::Felt;
51// CONSTANTS
52// ================================================================================================
53
54/// Minimum supported depth.
55pub const SMT_MIN_DEPTH: u8 = 1;
56
57/// Maximum supported depth.
58pub const SMT_MAX_DEPTH: u8 = 64;
59
60/// The felt used as a domain separator when hashing leaves in merkle trees.
61pub const LEAF_DOMAIN: Felt = Felt::new_unchecked(0x13af);
62
63// SPARSE MERKLE TREE
64// ================================================================================================
65
66type InnerNodes = Map<NodeIndex, InnerNode>;
67type Leaves<T> = Map<u64, T>;
68type NodeMutations = Map<NodeIndex, NodeMutation>;
69
70/// The read-only view of a sparse Merkle tree.
71///
72/// This trait contains all methods that require only read access to the tree, including querying
73/// values, generating proofs/openings, and computing prospective mutations. Splitting this from
74/// [`SparseMerkleTree`] allows types like `LargeSmt` to implement read-only operations with
75/// weaker generic bounds (e.g., `SmtStorageReader` instead of `SmtStorage`).
76pub(crate) trait SparseMerkleTreeReader<const DEPTH: u8> {
77    /// The type for a key
78    type Key: Clone + Ord + Eq + Hash;
79    /// The type for a value
80    type Value: Clone + PartialEq;
81    /// The type for a leaf
82    type Leaf: Clone;
83    /// The type for an opening (i.e. a "proof") of a leaf
84    type Opening;
85
86    /// The default value used to compute the hash of empty leaves
87    const EMPTY_VALUE: Self::Value;
88
89    /// The root of the empty tree with provided DEPTH
90    const EMPTY_ROOT: Word;
91
92    // PROVIDED METHODS
93    // ---------------------------------------------------------------------------------------------
94
95    /// Returns a [SparseMerklePath] to the specified key.
96    ///
97    /// Mostly this is an implementation detail of [`Self::open()`].
98    fn get_path(&self, key: &Self::Key) -> SparseMerklePath {
99        let index = NodeIndex::from(Self::key_to_leaf_index(key));
100
101        // SAFETY: this is guaranteed to have depth <= SMT_MAX_DEPTH
102        SparseMerklePath::from_sized_iter(
103            index.proof_indices().map(|index| self.get_node_hash(index)),
104        )
105        .expect("failed to convert to SparseMerklePath")
106    }
107
108    /// Get the hash of a node at an arbitrary index, including the root or leaf hashes.
109    ///
110    /// The root index simply returns [`Self::root()`]. Other hashes are retrieved by calling
111    /// [`Self::get_inner_node()`] on the parent, and returning the respective child hash.
112    fn get_node_hash(&self, index: NodeIndex) -> Word {
113        if index.is_root() {
114            return self.root();
115        }
116
117        let InnerNode { left, right } = self.get_inner_node(index.parent());
118
119        let index_is_right = index.is_position_odd();
120        if index_is_right { right } else { left }
121    }
122
123    /// Returns an opening of the leaf associated with `key`. Conceptually, an opening is a sparse
124    /// Merkle path to the leaf, as well as the leaf itself.
125    fn open(&self, key: &Self::Key) -> Self::Opening {
126        let leaf = self.get_leaf(key);
127        let merkle_path = self.get_path(key);
128
129        Self::path_and_leaf_to_opening(merkle_path, leaf)
130    }
131
132    /// Computes what changes are necessary to insert the specified key-value pairs into this Merkle
133    /// tree, allowing for validation before applying those changes.
134    ///
135    /// This method returns a [`MutationSet`], which contains all the information for inserting
136    /// `kv_pairs` into this Merkle tree already calculated, including the new root hash, which can
137    /// be queried with [`MutationSet::root()`]. Once a mutation set is returned,
138    /// [`SparseMerkleTree::apply_mutations()`] can be called in order to commit these changes to
139    /// the Merkle tree, or [`drop()`] to discard them.
140    ///
141    /// # Errors
142    /// - Returns [`MerkleError::DuplicateValuesForIndex`] if `kv_pairs` contains duplicate keys.
143    /// - If mutations would exceed [`crate::merkle::smt::MAX_LEAF_ENTRIES`] (1024 entries) in a
144    ///   leaf, returns [`MerkleError::TooManyLeafEntries`].
145    fn compute_mutations(
146        &self,
147        kv_pairs: impl IntoIterator<Item = (Self::Key, Self::Value)>,
148    ) -> Result<MutationSet<DEPTH, Self::Key, Self::Value>, MerkleError> {
149        self.compute_mutations_sequential(kv_pairs)
150    }
151
152    /// Sequential version of [`SparseMerkleTreeReader::compute_mutations()`].
153    /// This is the default implementation.
154    ///
155    /// # Errors
156    ///
157    /// - [`MerkleError::DuplicateValuesForIndex`] if `kv_pairs` contains multiple pairs with the
158    ///   same key.
159    /// - [`MerkleError::TooManyLeafEntries`] if the mutations would cause the tree to exceed
160    ///   [`crate::merkle::smt::MAX_LEAF_ENTRIES`] in a single leaf.
161    fn compute_mutations_sequential(
162        &self,
163        kv_pairs: impl IntoIterator<Item = (Self::Key, Self::Value)>,
164    ) -> Result<MutationSet<DEPTH, Self::Key, Self::Value>, MerkleError> {
165        use NodeMutation::*;
166
167        let mut new_root = self.root();
168        let mut new_pairs: Map<Self::Key, Self::Value> = Default::default();
169        let mut node_mutations: NodeMutations = NodeMutations::new();
170        let mut seen_keys: Set<Self::Key> = Set::new();
171
172        for (key, value) in kv_pairs {
173            // Reject duplicate keys.
174            if !seen_keys.insert(key.clone()) {
175                return Err(MerkleError::DuplicateValuesForIndex(
176                    Self::key_to_leaf_index(&key).position(),
177                ));
178            }
179
180            // If the old value and the new value are the same, there is nothing to update.
181            let old_value = new_pairs.get(&key).cloned().unwrap_or_else(|| self.get_value(&key));
182            if value == old_value {
183                continue;
184            }
185
186            let leaf_index = Self::key_to_leaf_index(&key);
187            let mut node_index = NodeIndex::from(leaf_index);
188
189            // We need the current leaf's hash to calculate the new leaf, but in the rare case that
190            // `kv_pairs` has multiple pairs that go into the same leaf, then those pairs are also
191            // part of the "current leaf".
192            let old_leaf = {
193                let pairs_at_index = new_pairs
194                    .iter()
195                    .filter(|&(new_key, _)| Self::key_to_leaf_index(new_key) == leaf_index);
196
197                pairs_at_index.fold(self.get_leaf(&key), |acc, (k, v)| {
198                    // Most of the time `pairs_at_index` should only contain a single entry (or
199                    // none at all), as multi-leaves should be really rare.
200                    let existing_leaf = acc;
201                    self.construct_prospective_leaf(existing_leaf, k, v)
202                        .expect("current leaf should be valid")
203                })
204            };
205
206            let new_leaf =
207                self.construct_prospective_leaf(old_leaf, &key, &value).map_err(|e| match e {
208                    SmtLeafError::TooManyLeafEntries { actual } => {
209                        MerkleError::TooManyLeafEntries { actual }
210                    },
211                    other => panic!("unexpected SmtLeaf::insert error: {:?}", other),
212                })?;
213
214            let mut new_child_hash = Self::hash_leaf(&new_leaf);
215
216            for node_depth in (0..node_index.depth()).rev() {
217                // Whether the node we're replacing is the right child or the left child.
218                let is_right = node_index.is_position_odd();
219                node_index.move_up();
220
221                let old_node = node_mutations
222                    .get(&node_index)
223                    .map(|mutation| match mutation {
224                        Addition(node) => node.clone(),
225                        Removal => EmptySubtreeRoots::get_inner_node(DEPTH, node_depth),
226                    })
227                    .unwrap_or_else(|| self.get_inner_node(node_index));
228
229                let new_node = if is_right {
230                    InnerNode {
231                        left: old_node.left,
232                        right: new_child_hash,
233                    }
234                } else {
235                    InnerNode {
236                        left: new_child_hash,
237                        right: old_node.right,
238                    }
239                };
240
241                // The next iteration will operate on this new node's hash.
242                new_child_hash = new_node.hash();
243
244                let &equivalent_empty_hash = EmptySubtreeRoots::entry(DEPTH, node_depth);
245                let is_removal = new_child_hash == equivalent_empty_hash;
246                let new_entry = if is_removal { Removal } else { Addition(new_node) };
247                node_mutations.insert(node_index, new_entry);
248            }
249
250            // Once we're at depth 0, the last node we made is the new root.
251            new_root = new_child_hash;
252            // And then we're done with this pair; on to the next one.
253            new_pairs.insert(key, value);
254        }
255
256        Ok(MutationSet {
257            old_root: self.root(),
258            new_root,
259            node_mutations,
260            new_pairs,
261        })
262    }
263
264    // REQUIRED METHODS
265    // ---------------------------------------------------------------------------------------------
266
267    /// The root of the tree
268    fn root(&self) -> Word;
269
270    /// Retrieves an inner node at the given index
271    fn get_inner_node(&self, index: NodeIndex) -> InnerNode;
272
273    /// Returns the value at the specified key. Recall that by definition, any key that hasn't been
274    /// updated is associated with [`Self::EMPTY_VALUE`].
275    fn get_value(&self, key: &Self::Key) -> Self::Value;
276
277    /// Returns the leaf at the specified index.
278    fn get_leaf(&self, key: &Self::Key) -> Self::Leaf;
279
280    /// Returns the hash of a leaf
281    fn hash_leaf(leaf: &Self::Leaf) -> Word;
282
283    /// Returns what a leaf would look like if a key-value pair were inserted into the tree, without
284    /// mutating the tree itself. The existing leaf can be empty.
285    ///
286    /// To get a prospective leaf based on the current state of the tree, use `self.get_leaf(key)`
287    /// as the argument for `existing_leaf`. The return value from this function can be chained back
288    /// into this function as the first argument to continue making prospective changes.
289    ///
290    /// # Invariants
291    /// Because this method is for a prospective key-value insertion into a specific leaf,
292    /// `existing_leaf` must have the same leaf index as `key` (as determined by
293    /// [`SparseMerkleTreeReader::key_to_leaf_index()`]), or the result will be meaningless.
294    ///
295    /// # Errors
296    /// If inserting the key-value pair would exceed
297    /// [`crate::merkle::smt::MAX_LEAF_ENTRIES`] (1024 entries) in a leaf,
298    /// returns [`SmtLeafError::TooManyLeafEntries`].
299    fn construct_prospective_leaf(
300        &self,
301        existing_leaf: Self::Leaf,
302        key: &Self::Key,
303        value: &Self::Value,
304    ) -> Result<Self::Leaf, SmtLeafError>;
305
306    /// Checks a slice of key-value pairs (assumed sorted by key) for duplicate keys.
307    ///
308    /// The input `sorted_kv_pairs` must be sorted for this function to return correct results, as
309    /// it only performs checks of adjacent elements.
310    ///
311    /// # Errors
312    ///
313    /// - [`MerkleError::DuplicateValuesForIndex`] at the first duplicate key found in
314    ///   `sorted_kv_pairs`.
315    #[cfg(feature = "concurrent")] // Currently only used in concurrent contexts
316    fn check_for_duplicate_keys(
317        sorted_kv_pairs: &[(Self::Key, Self::Value)],
318    ) -> Result<(), MerkleError> {
319        if let Some(window) = sorted_kv_pairs.windows(2).find(|w| w[0].0 == w[1].0) {
320            return Err(MerkleError::DuplicateValuesForIndex(
321                Self::key_to_leaf_index(&window[0].0).position(),
322            ));
323        }
324        Ok(())
325    }
326
327    /// Maps a key to a leaf index
328    fn key_to_leaf_index(key: &Self::Key) -> LeafIndex<DEPTH>;
329
330    /// Maps a (SparseMerklePath, Self::Leaf) to an opening.
331    ///
332    /// The length `path` is guaranteed to be equal to `DEPTH`
333    fn path_and_leaf_to_opening(path: SparseMerklePath, leaf: Self::Leaf) -> Self::Opening;
334}
335
336/// An abstract description of a sparse Merkle tree with write capabilities.
337///
338/// A sparse Merkle tree is a key-value map which also supports proving that a given value is indeed
339/// stored at a given key in the tree. It is viewed as always being fully populated. If a leaf's
340/// value was not explicitly set, then its value is the default value. Typically, the vast majority
341/// of leaves will store the default value (hence it is "sparse"), and therefore the internal
342/// representation of the tree will only keep track of the leaves that have a different value from
343/// the default.
344///
345/// All leaves sit at the same depth. The deeper the tree, the more leaves it has; but also the
346/// longer its proofs are - of exactly `log(depth)` size. A tree cannot have depth 0, since such a
347/// tree is just a single value, and is probably a programming mistake.
348///
349/// Every key maps to one leaf. If there are as many keys as there are leaves, then
350/// [Self::Leaf] should be the same type as [Self::Value], as is the case with
351/// [`SimpleSmt`]. However, if there are more keys than leaves, then [`Self::Leaf`]
352/// must accommodate all keys that map to the same leaf.
353///
354/// [SparseMerkleTree] currently doesn't support optimizations that compress Merkle proofs.
355pub(crate) trait SparseMerkleTree<const DEPTH: u8>: SparseMerkleTreeReader<DEPTH> {
356    // PROVIDED METHODS
357    // ---------------------------------------------------------------------------------------------
358
359    /// Inserts a value at the specified key, returning the previous value associated with that key.
360    /// Recall that by definition, any key that hasn't been updated is associated with
361    /// [`Self::EMPTY_VALUE`].
362    ///
363    /// This also recomputes all hashes between the leaf (associated with the key) and the root,
364    /// updating the root itself.
365    fn insert(&mut self, key: Self::Key, value: Self::Value) -> Result<Self::Value, MerkleError> {
366        let old_value = self.insert_value(key.clone(), value.clone())?.unwrap_or(Self::EMPTY_VALUE);
367
368        // if the old value and new value are the same, there is nothing to update
369        if value == old_value {
370            return Ok(value);
371        }
372
373        let leaf = self.get_leaf(&key);
374        let node_index = {
375            let leaf_index: LeafIndex<DEPTH> = Self::key_to_leaf_index(&key);
376            leaf_index.into()
377        };
378
379        self.recompute_nodes_from_index_to_root(node_index, Self::hash_leaf(&leaf));
380
381        Ok(old_value)
382    }
383
384    /// Recomputes the branch nodes (including the root) from `index` all the way to the root.
385    /// `node_hash_at_index` is the hash of the node stored at index.
386    fn recompute_nodes_from_index_to_root(
387        &mut self,
388        mut index: NodeIndex,
389        node_hash_at_index: Word,
390    ) {
391        let mut node_hash = node_hash_at_index;
392        for node_depth in (0..index.depth()).rev() {
393            let is_right = index.is_position_odd();
394            index.move_up();
395            let InnerNode { left, right } = self.get_inner_node(index);
396            let (left, right) = if is_right {
397                (left, node_hash)
398            } else {
399                (node_hash, right)
400            };
401            node_hash = Poseidon2::merge(&[left, right]);
402
403            if node_hash == *EmptySubtreeRoots::entry(DEPTH, node_depth) {
404                // If a subtree is empty, then can remove the inner node, since it's equal to the
405                // default value
406                self.remove_inner_node(index);
407            } else {
408                self.insert_inner_node(index, InnerNode { left, right });
409            }
410        }
411        self.set_root(node_hash);
412    }
413
414    /// Applies the prospective mutations computed with [`SparseMerkleTree::compute_mutations()`] to
415    /// this tree.
416    ///
417    /// # Errors
418    /// If `mutations` was computed on a tree with a different root than this one, returns
419    /// [`MerkleError::ConflictingRoots`] with a two-item [`Vec`]. The first item is the root hash
420    /// the `mutations` were computed against, and the second item is the actual current root of
421    /// this tree.
422    /// If mutations would exceed [`crate::merkle::smt::MAX_LEAF_ENTRIES`] (1024 entries) in a leaf,
423    /// returns
424    /// [`MerkleError::TooManyLeafEntries`].
425    fn apply_mutations(
426        &mut self,
427        mutations: MutationSet<DEPTH, Self::Key, Self::Value>,
428    ) -> Result<(), MerkleError>
429    where
430        Self: Sized,
431    {
432        use NodeMutation::*;
433        let MutationSet {
434            old_root,
435            node_mutations,
436            new_pairs,
437            new_root,
438        } = mutations;
439
440        // Guard against accidentally trying to apply mutations that were computed against a
441        // different tree, including a stale version of this tree.
442        if old_root != self.root() {
443            return Err(MerkleError::ConflictingRoots {
444                expected_root: self.root(),
445                actual_root: old_root,
446            });
447        }
448
449        for (index, mutation) in node_mutations {
450            match mutation {
451                Removal => {
452                    self.remove_inner_node(index);
453                },
454                Addition(node) => {
455                    self.insert_inner_node(index, node);
456                },
457            }
458        }
459
460        for (key, value) in new_pairs {
461            self.insert_value(key, value)?;
462        }
463
464        self.set_root(new_root);
465
466        Ok(())
467    }
468
469    /// Applies the prospective mutations computed with [`SparseMerkleTree::compute_mutations()`] to
470    /// this tree and returns the reverse mutation set. Applying the reverse mutation sets to the
471    /// updated tree will revert the changes.
472    ///
473    /// # Errors
474    /// If `mutations` was computed on a tree with a different root than this one, returns
475    /// [`MerkleError::ConflictingRoots`] with a two-item [`Vec`]. The first item is the root hash
476    /// the `mutations` were computed against, and the second item is the actual current root of
477    /// this tree.
478    fn apply_mutations_with_reversion(
479        &mut self,
480        mutations: MutationSet<DEPTH, Self::Key, Self::Value>,
481    ) -> Result<MutationSet<DEPTH, Self::Key, Self::Value>, MerkleError>
482    where
483        Self: Sized,
484    {
485        use NodeMutation::*;
486        let MutationSet {
487            old_root,
488            node_mutations,
489            new_pairs,
490            new_root,
491        } = mutations;
492
493        // Guard against accidentally trying to apply mutations that were computed against a
494        // different tree, including a stale version of this tree.
495        if old_root != self.root() {
496            return Err(MerkleError::ConflictingRoots {
497                expected_root: self.root(),
498                actual_root: old_root,
499            });
500        }
501
502        let mut reverse_mutations = NodeMutations::new();
503        for (index, mutation) in node_mutations {
504            match mutation {
505                Removal => {
506                    if let Some(node) = self.remove_inner_node(index) {
507                        reverse_mutations.insert(index, Addition(node));
508                    }
509                },
510                Addition(node) => {
511                    if let Some(old_node) = self.insert_inner_node(index, node) {
512                        reverse_mutations.insert(index, Addition(old_node));
513                    } else {
514                        reverse_mutations.insert(index, Removal);
515                    }
516                },
517            }
518        }
519
520        let mut reverse_pairs = Map::new();
521        for (key, value) in new_pairs {
522            match self.insert_value(key.clone(), value)? {
523                Some(old_value) => {
524                    reverse_pairs.insert(key, old_value);
525                },
526                None => {
527                    reverse_pairs.insert(key, Self::EMPTY_VALUE);
528                },
529            }
530        }
531
532        self.set_root(new_root);
533
534        Ok(MutationSet {
535            old_root: new_root,
536            node_mutations: reverse_mutations,
537            new_pairs: reverse_pairs,
538            new_root: old_root,
539        })
540    }
541
542    // REQUIRED METHODS
543    // ---------------------------------------------------------------------------------------------
544
545    /// Sets the root of the tree
546    fn set_root(&mut self, root: Word);
547
548    /// Inserts an inner node at the given index
549    fn insert_inner_node(&mut self, index: NodeIndex, inner_node: InnerNode) -> Option<InnerNode>;
550
551    /// Removes an inner node at the given index
552    fn remove_inner_node(&mut self, index: NodeIndex) -> Option<InnerNode>;
553
554    /// Inserts a leaf node, and returns the value at the key if already exists
555    fn insert_value(
556        &mut self,
557        key: Self::Key,
558        value: Self::Value,
559    ) -> Result<Option<Self::Value>, MerkleError>;
560}
561
562// INNER NODE
563// ================================================================================================
564
565/// This struct is public so functions returning it can be used in `benches/`, but is otherwise not
566/// part of the public API.
567#[doc(hidden)]
568#[derive(Debug, Default, Clone, PartialEq, Eq)]
569#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
570pub struct InnerNode {
571    pub left: Word,
572    pub right: Word,
573}
574
575impl InnerNode {
576    pub fn hash(&self) -> Word {
577        Poseidon2::merge(&[self.left, self.right])
578    }
579}
580
581// LEAF INDEX
582// ================================================================================================
583
584/// The index of a leaf, at a depth known at compile-time.
585#[derive(Debug, Default, Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
586#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
587pub struct LeafIndex<const DEPTH: u8> {
588    index: NodeIndex,
589}
590
591impl<const DEPTH: u8> LeafIndex<DEPTH> {
592    /// Creates a new `LeafIndex` with the specified value.
593    ///
594    /// # Errors
595    ///
596    /// Returns an error if the provided depth is less than the minimum supported depth.
597    pub fn new(value: u64) -> Result<Self, MerkleError> {
598        if DEPTH < SMT_MIN_DEPTH {
599            return Err(MerkleError::DepthTooSmall(DEPTH));
600        }
601
602        Ok(LeafIndex { index: NodeIndex::new(DEPTH, value)? })
603    }
604
605    /// Returns the position of this leaf index within its depth layer.
606    pub fn position(&self) -> u64 {
607        self.index.position()
608    }
609}
610
611impl LeafIndex<SMT_MAX_DEPTH> {
612    /// Creates a new `LeafIndex` at the maximum supported depth without validation.
613    pub const fn new_max_depth(value: u64) -> Self {
614        LeafIndex {
615            index: NodeIndex::new_unchecked(SMT_MAX_DEPTH, value),
616        }
617    }
618}
619
620impl<const DEPTH: u8> From<LeafIndex<DEPTH>> for NodeIndex {
621    fn from(value: LeafIndex<DEPTH>) -> Self {
622        value.index
623    }
624}
625
626impl<const DEPTH: u8> TryFrom<NodeIndex> for LeafIndex<DEPTH> {
627    type Error = MerkleError;
628
629    fn try_from(node_index: NodeIndex) -> Result<Self, Self::Error> {
630        if node_index.depth() != DEPTH {
631            return Err(MerkleError::InvalidNodeIndexDepth {
632                expected: DEPTH,
633                provided: node_index.depth(),
634            });
635        }
636
637        Self::new(node_index.position())
638    }
639}
640
641impl<const DEPTH: u8> Serializable for LeafIndex<DEPTH> {
642    fn write_into<W: ByteWriter>(&self, target: &mut W) {
643        self.index.write_into(target);
644    }
645}
646
647impl<const DEPTH: u8> Deserializable for LeafIndex<DEPTH> {
648    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
649        Ok(Self { index: source.read()? })
650    }
651}
652
653impl<const DEPTH: u8> Display for LeafIndex<DEPTH> {
654    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
655        write!(f, "DEPTH={}, position={}", DEPTH, self.position())
656    }
657}
658
659// MUTATIONS
660// ================================================================================================
661
662/// A change to an inner node of a sparse Merkle tree that hasn't yet been applied.
663/// [`MutationSet`] stores this type in relation to a [`NodeIndex`] to keep track of what changes
664/// need to occur at which node indices.
665#[derive(Debug, Clone, PartialEq, Eq)]
666pub enum NodeMutation {
667    /// Node needs to be removed.
668    Removal,
669    /// Node needs to be inserted.
670    Addition(InnerNode),
671}
672
673/// Represents a group of prospective mutations to a `SparseMerkleTree`, created by
674/// `SparseMerkleTree::compute_mutations()`, and that can be applied with
675/// `SparseMerkleTree::apply_mutations()`.
676#[derive(Debug, Clone, Default, PartialEq, Eq)]
677pub struct MutationSet<const DEPTH: u8, K: Eq + Hash, V> {
678    /// The root of the Merkle tree this MutationSet is for, recorded at the time
679    /// [`SparseMerkleTree::compute_mutations()`] was called. Exists to guard against applying
680    /// mutations to the wrong tree or applying stale mutations to a tree that has since changed.
681    old_root: Word,
682    /// The set of nodes that need to be removed or added. The "effective" node at an index is the
683    /// Merkle tree's existing node at that index, with the [`NodeMutation`] in this map at that
684    /// index overlaid, if any. Each [`NodeMutation::Addition`] corresponds to a
685    /// [`SparseMerkleTree::insert_inner_node()`] call, and each [`NodeMutation::Removal`]
686    /// corresponds to a [`SparseMerkleTree::remove_inner_node()`] call.
687    node_mutations: NodeMutations,
688    /// The set of top-level key-value pairs we're prospectively adding to the tree, including
689    /// adding empty values. The "effective" value for a key is the value in this Map, falling
690    /// back to the existing value in the Merkle tree. Each entry corresponds to a
691    /// [`SparseMerkleTree::insert_value()`] call.
692    new_pairs: Map<K, V>,
693    /// The calculated root for the Merkle tree, given these mutations. Publicly retrievable with
694    /// [`MutationSet::root()`]. Corresponds to a [`SparseMerkleTree::set_root()`]. call.
695    new_root: Word,
696}
697
698impl<const DEPTH: u8, K: Eq + Hash, V> MutationSet<DEPTH, K, V> {
699    /// Returns the SMT root that was calculated during `SparseMerkleTree::compute_mutations()`. See
700    /// that method for more information.
701    pub fn root(&self) -> Word {
702        self.new_root
703    }
704
705    /// Returns the SMT root before the mutations were applied.
706    pub fn old_root(&self) -> Word {
707        self.old_root
708    }
709
710    /// Returns the set of inner nodes that need to be removed or added.
711    pub fn node_mutations(&self) -> &NodeMutations {
712        &self.node_mutations
713    }
714
715    /// Returns the set of top-level key-value pairs that need to be added, updated or deleted
716    /// (i.e. set to `EMPTY_WORD`).
717    pub fn new_pairs(&self) -> &Map<K, V> {
718        &self.new_pairs
719    }
720
721    /// Returns `true` if the mutation set represents no changes to the tree, and `false` otherwise.
722    pub fn is_empty(&self) -> bool {
723        self.node_mutations.is_empty()
724            && self.new_pairs.is_empty()
725            && self.old_root == self.new_root
726    }
727}
728
729// SERIALIZATION
730// ================================================================================================
731
732impl Serializable for InnerNode {
733    fn write_into<W: ByteWriter>(&self, target: &mut W) {
734        target.write(self.left);
735        target.write(self.right);
736    }
737}
738
739impl Deserializable for InnerNode {
740    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
741        let left = source.read()?;
742        let right = source.read()?;
743
744        Ok(Self { left, right })
745    }
746}
747
748impl Serializable for NodeMutation {
749    fn write_into<W: ByteWriter>(&self, target: &mut W) {
750        match self {
751            NodeMutation::Removal => target.write_bool(false),
752            NodeMutation::Addition(inner_node) => {
753                target.write_bool(true);
754                inner_node.write_into(target);
755            },
756        }
757    }
758}
759
760impl Deserializable for NodeMutation {
761    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
762        if source.read_bool()? {
763            let inner_node = source.read()?;
764            return Ok(NodeMutation::Addition(inner_node));
765        }
766
767        Ok(NodeMutation::Removal)
768    }
769}
770
771impl<const DEPTH: u8, K: Serializable + Eq + Hash, V: Serializable> Serializable
772    for MutationSet<DEPTH, K, V>
773{
774    fn write_into<W: ByteWriter>(&self, target: &mut W) {
775        target.write(self.old_root);
776        target.write(self.new_root);
777
778        let inner_removals: Vec<_> = self
779            .node_mutations
780            .iter()
781            .filter(|(_, value)| matches!(value, NodeMutation::Removal))
782            .map(|(key, _)| key)
783            .collect();
784        let inner_additions: Vec<_> = self
785            .node_mutations
786            .iter()
787            .filter_map(|(key, value)| match value {
788                NodeMutation::Addition(node) => Some((key, node)),
789                _ => None,
790            })
791            .collect();
792
793        target.write(inner_removals);
794        target.write(inner_additions);
795
796        target.write_usize(self.new_pairs.len());
797        target.write_many(&self.new_pairs);
798    }
799}
800
801impl<const DEPTH: u8, K: Deserializable + Ord + Eq + Hash, V: Deserializable> Deserializable
802    for MutationSet<DEPTH, K, V>
803{
804    fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
805        let old_root = source.read()?;
806        let new_root = source.read()?;
807
808        let inner_removals: Vec<NodeIndex> = source.read()?;
809        let inner_additions: Vec<(NodeIndex, InnerNode)> = source.read()?;
810
811        let node_mutations = NodeMutations::from_iter(
812            inner_removals.into_iter().map(|index| (index, NodeMutation::Removal)).chain(
813                inner_additions
814                    .into_iter()
815                    .map(|(index, node)| (index, NodeMutation::Addition(node))),
816            ),
817        );
818
819        let num_new_pairs = source.read_usize()?;
820        let new_pairs: Map<_, _> =
821            source.read_many_iter(num_new_pairs)?.collect::<Result<_, _>>()?;
822
823        Ok(Self {
824            old_root,
825            node_mutations,
826            new_pairs,
827            new_root,
828        })
829    }
830}