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}