miden_crypto/merkle/smt/large/storage/
mod.rs

1use alloc::{boxed::Box, vec::Vec};
2use core::{fmt, ops::Deref};
3
4use crate::{
5    Word,
6    merkle::{
7        NodeIndex, SmtLeaf,
8        smt::{InnerNode, Map, large::subtree::Subtree},
9    },
10};
11
12mod error;
13pub use error::StorageError;
14
15#[cfg(feature = "rocksdb")]
16mod rocksdb;
17#[cfg(feature = "rocksdb")]
18pub use rocksdb::{RocksDbConfig, RocksDbStorage};
19
20mod memory;
21pub use memory::MemoryStorage;
22
23mod updates;
24pub use updates::{StorageUpdateParts, StorageUpdates};
25
26/// Sparse Merkle Tree storage backend.
27///
28/// This trait outlines the fundamental operations required to persist and retrieve
29/// the components of an SMT, such as its root hash, leaves, and deeper subtrees.
30/// Implementations of this trait can provide various storage solutions, like in-memory
31/// maps or persistent databases (e.g., RocksDB).
32///
33/// All methods are expected to handle potential storage errors by returning a
34/// `Result<_, StorageError>`.
35pub trait SmtStorage: 'static + fmt::Debug + Send + Sync {
36    /// Retrieves the current root hash of the Sparse Merkle Tree.
37    /// Returns `Ok(None)` if no root has been set or an empty SMT is represented.
38    ///
39    /// # Errors
40    /// Returns `StorageError` if the storage read operation fails.
41    fn get_root(&self) -> Result<Option<Word>, StorageError>;
42
43    /// Sets or updates the root hash of the Sparse Merkle Tree.
44    ///
45    /// # Errors
46    /// Returns `StorageError` if the storage write operation fails.
47    fn set_root(&self, root: Word) -> Result<(), StorageError>;
48
49    /// Retrieves the total number of leaf nodes currently stored.
50    ///
51    /// # Errors
52    /// Returns `StorageError` if the storage read operation fails.
53    fn leaf_count(&self) -> Result<usize, StorageError>;
54
55    /// Retrieves the total number of unique key-value entries across all leaf nodes.
56    ///
57    /// # Errors
58    /// Returns `StorageError` if the storage read operation fails.
59    fn entry_count(&self) -> Result<usize, StorageError>;
60
61    /// Inserts a key-value pair into the SMT leaf at the specified logical `index`.
62    ///
63    /// - If the leaf at `index` does not exist, it may be created.
64    /// - If the `key` already exists in the leaf at `index`, its `value` is updated.
65    /// - Returns the previous `Word` value associated with the `key` at `index`, if any.
66    ///
67    /// Implementations are responsible for updating overall leaf and entry counts if necessary.
68    ///
69    /// Note: This only updates the leaf. Callers are responsible for recomputing and
70    /// persisting the corresponding inner nodes.
71    ///
72    /// # Errors
73    /// Returns `StorageError` if the storage operation fails (e.g., backend database error,
74    /// insufficient space, serialization failures).
75    fn insert_value(
76        &self,
77        index: u64,
78        key: Word,
79        value: Word,
80    ) -> Result<Option<Word>, StorageError>;
81
82    /// Removes a key-value pair from the SMT leaf at the specified logical `index`.
83    ///
84    /// - If the `key` is found in the leaf at `index`, it is removed, and the old `Word` value is
85    ///   returned.
86    /// - If the leaf at `index` does not exist, or if the `key` is not found within it, `Ok(None)`
87    ///   is returned.
88    /// - If removing the entry causes the leaf to become empty, the behavior regarding the leaf
89    ///   node itself (e.g., whether it's removed from storage) is implementation-dependent, but
90    ///   counts should be updated.
91    ///
92    /// Implementations are responsible for updating overall leaf and entry counts if necessary.
93    ///
94    /// Note: This only updates the leaf. Callers are responsible for recomputing and
95    /// persisting the corresponding inner nodes.
96    ///
97    /// # Errors
98    /// Returns `StorageError` if the storage operation fails (e.g., backend database error,
99    /// write permission issues, serialization failures).
100    fn remove_value(&self, index: u64, key: Word) -> Result<Option<Word>, StorageError>;
101
102    /// Retrieves a single SMT leaf node by its logical `index`.
103    /// Returns `Ok(None)` if no leaf exists at the given `index`.
104    fn get_leaf(&self, index: u64) -> Result<Option<SmtLeaf>, StorageError>;
105
106    /// Sets or updates multiple SMT leaf nodes in storage.
107    ///
108    /// For each entry in the `leaves` map, if a leaf at the given index already exists,
109    /// it should be overwritten with the new `SmtLeaf` data.
110    /// If it does not exist, a new leaf is stored.
111    ///
112    /// Note: This only updates the leaves. Callers are responsible for recomputing and
113    /// persisting the corresponding inner nodes.
114    ///
115    /// # Errors
116    /// Returns `StorageError` if any storage operation fails during the batch update.
117    fn set_leaves(&self, leaves: Map<u64, SmtLeaf>) -> Result<(), StorageError>;
118
119    /// Removes a single SMT leaf node entirely from storage by its logical `index`.
120    ///
121    /// Note: This only removes the leaf. Callers are responsible for recomputing and
122    /// persisting the corresponding inner nodes.
123    ///
124    /// Returns the `SmtLeaf` that was removed, or `Ok(None)` if no leaf existed at `index`.
125    /// Implementations should ensure that removing a leaf also correctly updates
126    /// the overall leaf and entry counts.
127    fn remove_leaf(&self, index: u64) -> Result<Option<SmtLeaf>, StorageError>;
128
129    /// Retrieves multiple SMT leaf nodes by their logical `indices`.
130    ///
131    /// The returned `Vec` will have the same length as the input `indices` slice.
132    /// For each `index` in the input, the corresponding element in the output `Vec`
133    /// will be `Some(SmtLeaf)` if found, or `None` if not found.
134    fn get_leaves(&self, indices: &[u64]) -> Result<Vec<Option<SmtLeaf>>, StorageError>;
135
136    /// Returns true if the storage has any leaves.
137    ///
138    /// # Errors
139    /// Returns `StorageError` if the storage read operation fails.
140    fn has_leaves(&self) -> Result<bool, StorageError>;
141
142    /// Retrieves a single SMT Subtree by its root `NodeIndex`.
143    ///
144    /// Subtrees typically represent deeper, compacted parts of the SMT.
145    /// Returns `Ok(None)` if no subtree is found for the given `index`.
146    fn get_subtree(&self, index: NodeIndex) -> Result<Option<Subtree>, StorageError>;
147
148    /// Retrieves multiple Subtrees by their root `NodeIndex` values.
149    ///
150    /// The returned `Vec` will have the same length as the input `indices` slice.
151    /// For each `index` in the input, the corresponding element in the output `Vec`
152    /// will be `Some(Subtree)` if found, or `None` if not found.
153    fn get_subtrees(&self, indices: &[NodeIndex]) -> Result<Vec<Option<Subtree>>, StorageError>;
154
155    /// Sets or updates a single SMT Subtree in storage, identified by its root `NodeIndex`.
156    ///
157    /// If a subtree with the same root `NodeIndex` already exists, it is overwritten.
158    fn set_subtree(&self, subtree: &Subtree) -> Result<(), StorageError>;
159
160    /// Sets or updates multiple SMT Subtrees in storage.
161    ///
162    /// For each `Subtree` in the `subtrees` vector, if a subtree with the same root `NodeIndex`
163    /// already exists, it is overwritten.
164    fn set_subtrees(&self, subtrees: Vec<Subtree>) -> Result<(), StorageError>;
165
166    /// Removes a single SMT Subtree from storage, identified by its root `NodeIndex`.
167    ///
168    /// Returns `Ok(())` on successful removal or if the subtree did not exist.
169    fn remove_subtree(&self, index: NodeIndex) -> Result<(), StorageError>;
170
171    /// Retrieves a single inner node from within a Subtree.
172    ///
173    /// This method is intended for accessing nodes at depths greater than the in-memory horizon.
174    /// Returns `Ok(None)` if the containing Subtree or the specific inner node is not found.
175    fn get_inner_node(&self, index: NodeIndex) -> Result<Option<InnerNode>, StorageError>;
176
177    /// Sets or updates a single inner node (non-leaf node) within a Subtree.
178    ///
179    /// - If the target Subtree does not exist, it might need to be created by the implementation.
180    /// - Returns the `InnerNode` that was previously at this `index`, if any.
181    fn set_inner_node(
182        &self,
183        index: NodeIndex,
184        node: InnerNode,
185    ) -> Result<Option<InnerNode>, StorageError>;
186
187    /// Removes a single inner node (non-leaf node) from within a Subtree.
188    ///
189    /// - If the Subtree becomes empty after removing the node, the Subtree itself might be removed
190    ///   by the storage implementation.
191    /// - Returns the `InnerNode` that was removed, if any.
192    fn remove_inner_node(&self, index: NodeIndex) -> Result<Option<InnerNode>, StorageError>;
193
194    /// Applies a batch of `StorageUpdates` atomically to the storage backend.
195    ///
196    /// This is the primary method for persisting changes to the SMT. Implementations must ensure
197    /// that all updates within the `StorageUpdates` struct (leaf changes, subtree changes,
198    /// new root hash, and count deltas) are applied as a single, indivisible operation.
199    /// If any part of the update fails, the entire transaction should be rolled back, leaving
200    /// the storage in its previous state.
201    fn apply(&self, updates: StorageUpdates) -> Result<(), StorageError>;
202
203    /// Returns an iterator over all (logical_index, SmtLeaf) pairs currently in storage.
204    ///
205    /// The order of iteration is not guaranteed unless specified by the implementation.
206    fn iter_leaves(&self) -> Result<Box<dyn Iterator<Item = (u64, SmtLeaf)> + '_>, StorageError>;
207
208    /// Returns an iterator over all `Subtree` instances currently in storage.
209    ///
210    /// The order of iteration is not guaranteed unless specified by the implementation.
211    fn iter_subtrees(&self) -> Result<Box<dyn Iterator<Item = Subtree> + '_>, StorageError>;
212
213    /// Retrieves all depth 24 hashes from storage for efficient startup reconstruction.
214    ///
215    /// Returns a vector of `(node_index_value, InnerNode)` tuples representing
216    /// the cached roots of nodes at depth 24 (the in-memory/storage boundary).
217    /// These roots enable fast reconstruction of the upper tree without loading
218    /// entire subtrees.
219    ///
220    /// The hash cache is automatically maintained by subtree operations - no manual
221    /// cache management is required.
222    fn get_depth24(&self) -> Result<Vec<(u64, Word)>, StorageError>;
223}
224
225// Blanket impl to allow any pointer to a `SmtStorage` to be used as storage.
226impl<P, T> SmtStorage for P
227where
228    P: Deref<Target = T> + fmt::Debug + Send + Sync + 'static,
229    T: SmtStorage + ?Sized,
230{
231    #[inline]
232    fn get_root(&self) -> Result<Option<Word>, StorageError> {
233        self.deref().get_root()
234    }
235    #[inline]
236    fn set_root(&self, root: Word) -> Result<(), StorageError> {
237        self.deref().set_root(root)
238    }
239    #[inline]
240    fn leaf_count(&self) -> Result<usize, StorageError> {
241        self.deref().leaf_count()
242    }
243    #[inline]
244    fn entry_count(&self) -> Result<usize, StorageError> {
245        self.deref().entry_count()
246    }
247
248    #[inline]
249    fn insert_value(
250        &self,
251        index: u64,
252        key: Word,
253        value: Word,
254    ) -> Result<Option<Word>, StorageError> {
255        self.deref().insert_value(index, key, value)
256    }
257
258    #[inline]
259    fn remove_value(&self, index: u64, key: Word) -> Result<Option<Word>, StorageError> {
260        self.deref().remove_value(index, key)
261    }
262
263    #[inline]
264    fn get_leaf(&self, index: u64) -> Result<Option<SmtLeaf>, StorageError> {
265        self.deref().get_leaf(index)
266    }
267    #[inline]
268    fn set_leaves(&self, leaves: Map<u64, SmtLeaf>) -> Result<(), StorageError> {
269        self.deref().set_leaves(leaves)
270    }
271    #[inline]
272    fn remove_leaf(&self, index: u64) -> Result<Option<SmtLeaf>, StorageError> {
273        self.deref().remove_leaf(index)
274    }
275    #[inline]
276    fn get_leaves(&self, indices: &[u64]) -> Result<Vec<Option<SmtLeaf>>, StorageError> {
277        self.deref().get_leaves(indices)
278    }
279    #[inline]
280    fn has_leaves(&self) -> Result<bool, StorageError> {
281        self.deref().has_leaves()
282    }
283
284    #[inline]
285    fn get_subtree(&self, index: NodeIndex) -> Result<Option<Subtree>, StorageError> {
286        self.deref().get_subtree(index)
287    }
288
289    #[inline]
290    fn get_subtrees(&self, indices: &[NodeIndex]) -> Result<Vec<Option<Subtree>>, StorageError> {
291        self.deref().get_subtrees(indices)
292    }
293
294    #[inline]
295    fn set_subtree(&self, subtree: &Subtree) -> Result<(), StorageError> {
296        self.deref().set_subtree(subtree)
297    }
298    #[inline]
299    fn set_subtrees(&self, subtrees: Vec<Subtree>) -> Result<(), StorageError> {
300        self.deref().set_subtrees(subtrees)
301    }
302    #[inline]
303    fn remove_subtree(&self, index: NodeIndex) -> Result<(), StorageError> {
304        self.deref().remove_subtree(index)
305    }
306
307    #[inline]
308    fn get_inner_node(&self, index: NodeIndex) -> Result<Option<InnerNode>, StorageError> {
309        self.deref().get_inner_node(index)
310    }
311
312    #[inline]
313    fn set_inner_node(
314        &self,
315        index: NodeIndex,
316        node: InnerNode,
317    ) -> Result<Option<InnerNode>, StorageError> {
318        self.deref().set_inner_node(index, node)
319    }
320
321    #[inline]
322    fn remove_inner_node(&self, index: NodeIndex) -> Result<Option<InnerNode>, StorageError> {
323        self.deref().remove_inner_node(index)
324    }
325
326    #[inline]
327    fn apply(&self, updates: StorageUpdates) -> Result<(), StorageError> {
328        self.deref().apply(updates)
329    }
330
331    #[inline]
332    fn iter_leaves(&self) -> Result<Box<dyn Iterator<Item = (u64, SmtLeaf)> + '_>, StorageError> {
333        self.deref().iter_leaves()
334    }
335
336    #[inline]
337    fn iter_subtrees(&self) -> Result<Box<dyn Iterator<Item = Subtree> + '_>, StorageError> {
338        self.deref().iter_subtrees()
339    }
340
341    #[inline]
342    fn get_depth24(&self) -> Result<Vec<(u64, Word)>, StorageError> {
343        self.deref().get_depth24()
344    }
345}