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}