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}