miden_crypto/merkle/smt/full/
mod.rs1use alloc::{
2 collections::{BTreeMap, BTreeSet},
3 string::ToString,
4 vec::Vec,
5};
6
7use super::{
8 EmptySubtreeRoots, Felt, InnerNode, InnerNodeInfo, LeafIndex, MerkleError, MerklePath,
9 MutationSet, NodeIndex, Rpo256, RpoDigest, SparseMerkleTree, Word, EMPTY_WORD,
10};
11
12mod error;
13pub use error::{SmtLeafError, SmtProofError};
14
15mod leaf;
16pub use leaf::SmtLeaf;
17
18mod proof;
19pub use proof::SmtProof;
20use winter_utils::{ByteReader, ByteWriter, Deserializable, DeserializationError, Serializable};
21
22#[cfg(test)]
23mod tests;
24
25pub const SMT_DEPTH: u8 = 64;
29
30#[derive(Debug, Clone, PartialEq, Eq)]
43#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
44pub struct Smt {
45 root: RpoDigest,
46 pub(super) leaves: BTreeMap<u64, SmtLeaf>,
48 inner_nodes: BTreeMap<NodeIndex, InnerNode>,
49}
50
51impl Smt {
52 pub const EMPTY_VALUE: Word = <Self as SparseMerkleTree<SMT_DEPTH>>::EMPTY_VALUE;
56
57 pub fn new() -> Self {
64 let root = *EmptySubtreeRoots::entry(SMT_DEPTH, 0);
65
66 Self {
67 root,
68 leaves: BTreeMap::new(),
69 inner_nodes: BTreeMap::new(),
70 }
71 }
72
73 pub fn with_entries(
80 entries: impl IntoIterator<Item = (RpoDigest, Word)>,
81 ) -> Result<Self, MerkleError> {
82 let mut tree = Self::new();
84
85 let mut key_set_to_zero = BTreeSet::new();
88
89 for (key, value) in entries {
90 let old_value = tree.insert(key, value);
91
92 if old_value != EMPTY_WORD || key_set_to_zero.contains(&key) {
93 return Err(MerkleError::DuplicateValuesForIndex(
94 LeafIndex::<SMT_DEPTH>::from(key).value(),
95 ));
96 }
97
98 if value == EMPTY_WORD {
99 key_set_to_zero.insert(key);
100 };
101 }
102 Ok(tree)
103 }
104
105 pub const fn depth(&self) -> u8 {
110 SMT_DEPTH
111 }
112
113 pub fn root(&self) -> RpoDigest {
115 <Self as SparseMerkleTree<SMT_DEPTH>>::root(self)
116 }
117
118 pub fn num_leaves(&self) -> usize {
120 self.leaves.len()
121 }
122
123 pub fn get_leaf(&self, key: &RpoDigest) -> SmtLeaf {
125 <Self as SparseMerkleTree<SMT_DEPTH>>::get_leaf(self, key)
126 }
127
128 pub fn get_value(&self, key: &RpoDigest) -> Word {
130 <Self as SparseMerkleTree<SMT_DEPTH>>::get_value(self, key)
131 }
132
133 pub fn open(&self, key: &RpoDigest) -> SmtProof {
136 <Self as SparseMerkleTree<SMT_DEPTH>>::open(self, key)
137 }
138
139 pub fn is_empty(&self) -> bool {
141 debug_assert_eq!(self.leaves.is_empty(), self.root == Self::EMPTY_ROOT);
142 self.root == Self::EMPTY_ROOT
143 }
144
145 pub fn leaves(&self) -> impl Iterator<Item = (LeafIndex<SMT_DEPTH>, &SmtLeaf)> {
150 self.leaves
151 .iter()
152 .map(|(leaf_index, leaf)| (LeafIndex::new_max_depth(*leaf_index), leaf))
153 }
154
155 pub fn entries(&self) -> impl Iterator<Item = &(RpoDigest, Word)> {
157 self.leaves().flat_map(|(_, leaf)| leaf.entries())
158 }
159
160 pub fn inner_nodes(&self) -> impl Iterator<Item = InnerNodeInfo> + '_ {
162 self.inner_nodes.values().map(|e| InnerNodeInfo {
163 value: e.hash(),
164 left: e.left,
165 right: e.right,
166 })
167 }
168
169 pub fn insert(&mut self, key: RpoDigest, value: Word) -> Word {
179 <Self as SparseMerkleTree<SMT_DEPTH>>::insert(self, key, value)
180 }
181
182 pub fn compute_mutations(
203 &self,
204 kv_pairs: impl IntoIterator<Item = (RpoDigest, Word)>,
205 ) -> MutationSet<SMT_DEPTH, RpoDigest, Word> {
206 <Self as SparseMerkleTree<SMT_DEPTH>>::compute_mutations(self, kv_pairs)
207 }
208
209 pub fn apply_mutations(
217 &mut self,
218 mutations: MutationSet<SMT_DEPTH, RpoDigest, Word>,
219 ) -> Result<(), MerkleError> {
220 <Self as SparseMerkleTree<SMT_DEPTH>>::apply_mutations(self, mutations)
221 }
222
223 pub fn apply_mutations_with_reversion(
234 &mut self,
235 mutations: MutationSet<SMT_DEPTH, RpoDigest, Word>,
236 ) -> Result<MutationSet<SMT_DEPTH, RpoDigest, Word>, MerkleError> {
237 <Self as SparseMerkleTree<SMT_DEPTH>>::apply_mutations_with_reversion(self, mutations)
238 }
239
240 fn perform_insert(&mut self, key: RpoDigest, value: Word) -> Option<Word> {
246 debug_assert_ne!(value, Self::EMPTY_VALUE);
247
248 let leaf_index: LeafIndex<SMT_DEPTH> = Self::key_to_leaf_index(&key);
249
250 match self.leaves.get_mut(&leaf_index.value()) {
251 Some(leaf) => leaf.insert(key, value),
252 None => {
253 self.leaves.insert(leaf_index.value(), SmtLeaf::Single((key, value)));
254
255 None
256 },
257 }
258 }
259
260 fn perform_remove(&mut self, key: RpoDigest) -> Option<Word> {
262 let leaf_index: LeafIndex<SMT_DEPTH> = Self::key_to_leaf_index(&key);
263
264 if let Some(leaf) = self.leaves.get_mut(&leaf_index.value()) {
265 let (old_value, is_empty) = leaf.remove(key);
266 if is_empty {
267 self.leaves.remove(&leaf_index.value());
268 }
269 old_value
270 } else {
271 None
273 }
274 }
275}
276
277impl SparseMerkleTree<SMT_DEPTH> for Smt {
278 type Key = RpoDigest;
279 type Value = Word;
280 type Leaf = SmtLeaf;
281 type Opening = SmtProof;
282
283 const EMPTY_VALUE: Self::Value = EMPTY_WORD;
284 const EMPTY_ROOT: RpoDigest = *EmptySubtreeRoots::entry(SMT_DEPTH, 0);
285
286 fn root(&self) -> RpoDigest {
287 self.root
288 }
289
290 fn set_root(&mut self, root: RpoDigest) {
291 self.root = root;
292 }
293
294 fn get_inner_node(&self, index: NodeIndex) -> InnerNode {
295 self.inner_nodes
296 .get(&index)
297 .cloned()
298 .unwrap_or_else(|| EmptySubtreeRoots::get_inner_node(SMT_DEPTH, index.depth()))
299 }
300
301 fn insert_inner_node(&mut self, index: NodeIndex, inner_node: InnerNode) -> Option<InnerNode> {
302 self.inner_nodes.insert(index, inner_node)
303 }
304
305 fn remove_inner_node(&mut self, index: NodeIndex) -> Option<InnerNode> {
306 self.inner_nodes.remove(&index)
307 }
308
309 fn insert_value(&mut self, key: Self::Key, value: Self::Value) -> Option<Self::Value> {
310 if value != Self::EMPTY_VALUE {
312 self.perform_insert(key, value)
313 } else {
314 self.perform_remove(key)
315 }
316 }
317
318 fn get_value(&self, key: &Self::Key) -> Self::Value {
319 let leaf_pos = LeafIndex::<SMT_DEPTH>::from(*key).value();
320
321 match self.leaves.get(&leaf_pos) {
322 Some(leaf) => leaf.get_value(key).unwrap_or_default(),
323 None => EMPTY_WORD,
324 }
325 }
326
327 fn get_leaf(&self, key: &RpoDigest) -> Self::Leaf {
328 let leaf_pos = LeafIndex::<SMT_DEPTH>::from(*key).value();
329
330 match self.leaves.get(&leaf_pos) {
331 Some(leaf) => leaf.clone(),
332 None => SmtLeaf::new_empty(key.into()),
333 }
334 }
335
336 fn hash_leaf(leaf: &Self::Leaf) -> RpoDigest {
337 leaf.hash()
338 }
339
340 fn construct_prospective_leaf(
341 &self,
342 mut existing_leaf: SmtLeaf,
343 key: &RpoDigest,
344 value: &Word,
345 ) -> SmtLeaf {
346 debug_assert_eq!(existing_leaf.index(), Self::key_to_leaf_index(key));
347
348 match existing_leaf {
349 SmtLeaf::Empty(_) => SmtLeaf::new_single(*key, *value),
350 _ => {
351 if *value != EMPTY_WORD {
352 existing_leaf.insert(*key, *value);
353 } else {
354 existing_leaf.remove(*key);
355 }
356
357 existing_leaf
358 },
359 }
360 }
361
362 fn key_to_leaf_index(key: &RpoDigest) -> LeafIndex<SMT_DEPTH> {
363 let most_significant_felt = key[3];
364 LeafIndex::new_max_depth(most_significant_felt.as_int())
365 }
366
367 fn path_and_leaf_to_opening(path: MerklePath, leaf: SmtLeaf) -> SmtProof {
368 SmtProof::new_unchecked(path, leaf)
369 }
370}
371
372impl Default for Smt {
373 fn default() -> Self {
374 Self::new()
375 }
376}
377
378impl From<Word> for LeafIndex<SMT_DEPTH> {
382 fn from(value: Word) -> Self {
383 Self::new_max_depth(value[3].as_int())
385 }
386}
387
388impl From<RpoDigest> for LeafIndex<SMT_DEPTH> {
389 fn from(value: RpoDigest) -> Self {
390 Word::from(value).into()
391 }
392}
393
394impl From<&RpoDigest> for LeafIndex<SMT_DEPTH> {
395 fn from(value: &RpoDigest) -> Self {
396 Word::from(value).into()
397 }
398}
399
400impl Serializable for Smt {
404 fn write_into<W: ByteWriter>(&self, target: &mut W) {
405 target.write_usize(self.entries().count());
407
408 for (key, value) in self.entries() {
410 target.write(key);
411 target.write(value);
412 }
413 }
414
415 fn get_size_hint(&self) -> usize {
416 let entries_count = self.entries().count();
417
418 entries_count.get_size_hint()
420 + entries_count * (RpoDigest::SERIALIZED_SIZE + EMPTY_WORD.get_size_hint())
421 }
422}
423
424impl Deserializable for Smt {
425 fn read_from<R: ByteReader>(source: &mut R) -> Result<Self, DeserializationError> {
426 let num_filled_leaves = source.read_usize()?;
428 let mut entries = Vec::with_capacity(num_filled_leaves);
429
430 for _ in 0..num_filled_leaves {
431 let key = source.read()?;
432 let value = source.read()?;
433 entries.push((key, value));
434 }
435
436 Self::with_entries(entries)
437 .map_err(|err| DeserializationError::InvalidValue(err.to_string()))
438 }
439}
440
441#[test]
445fn test_smt_serialization_deserialization() {
446 let smt_default = Smt::default();
448 let bytes = smt_default.to_bytes();
449 assert_eq!(smt_default, Smt::read_from_bytes(&bytes).unwrap());
450 assert_eq!(bytes.len(), smt_default.get_size_hint());
451
452 let smt_leaves_2: [(RpoDigest, Word); 2] = [
454 (
455 RpoDigest::new([Felt::new(101), Felt::new(102), Felt::new(103), Felt::new(104)]),
456 [Felt::new(1_u64), Felt::new(2_u64), Felt::new(3_u64), Felt::new(4_u64)],
457 ),
458 (
459 RpoDigest::new([Felt::new(105), Felt::new(106), Felt::new(107), Felt::new(108)]),
460 [Felt::new(5_u64), Felt::new(6_u64), Felt::new(7_u64), Felt::new(8_u64)],
461 ),
462 ];
463 let smt = Smt::with_entries(smt_leaves_2).unwrap();
464
465 let bytes = smt.to_bytes();
466 assert_eq!(smt, Smt::read_from_bytes(&bytes).unwrap());
467 assert_eq!(bytes.len(), smt.get_size_hint());
468}