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