snarkvm_ledger_store/helpers/traits/
nested_map.rs

1// Copyright (c) 2019-2025 Provable Inc.
2// This file is part of the snarkVM library.
3
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at:
7
8// http://www.apache.org/licenses/LICENSE-2.0
9
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16use console::network::prelude::{Deserialize, Result, Serialize};
17
18use core::hash::Hash;
19use std::borrow::Cow;
20
21/// A trait representing 'nested map'-like storage operations with read-write capabilities.
22pub trait NestedMap<
23    'a,
24    M: 'a + Copy + Clone + PartialEq + Eq + Hash + Serialize + Deserialize<'a> + Send + Sync,
25    K: 'a + Clone + PartialEq + Eq + Serialize + Deserialize<'a> + Send + Sync,
26    V: 'a + Clone + Serialize + Deserialize<'a> + Send + Sync,
27>: Clone + NestedMapRead<'a, M, K, V> + Send + Sync
28{
29    ///
30    /// Inserts the given key-value pair.
31    ///
32    fn insert(&self, map: M, key: K, value: V) -> Result<()>;
33
34    ///
35    /// Removes the given map.
36    ///
37    fn remove_map(&self, map: &M) -> Result<()>;
38
39    ///
40    /// Removes the key-value pair for the given map and key.
41    ///
42    fn remove_key(&self, map: &M, key: &K) -> Result<()>;
43
44    ///
45    /// Begins an atomic operation. Any further calls to `insert` and `remove` will be queued
46    /// without an actual write taking place until `finish_atomic` is called.
47    ///
48    fn start_atomic(&self);
49
50    ///
51    /// Checks whether an atomic operation is currently in progress. This can be done to ensure
52    /// that lower-level operations don't start or finish their individual atomic write batch
53    /// if they are already part of a larger one.
54    ///
55    fn is_atomic_in_progress(&self) -> bool;
56
57    ///
58    /// Saves the current list of pending operations, so that if `atomic_rewind` is called,
59    /// we roll back all future operations, and return to the start of this checkpoint.
60    ///
61    fn atomic_checkpoint(&self);
62
63    ///
64    /// Removes the latest atomic checkpoint.
65    ///
66    fn clear_latest_checkpoint(&self);
67
68    ///
69    /// Removes all pending operations to the last `atomic_checkpoint`
70    /// (or to `start_atomic` if no checkpoints have been created).
71    ///
72    fn atomic_rewind(&self);
73
74    ///
75    /// Aborts the current atomic operation.
76    ///
77    fn abort_atomic(&self);
78
79    ///
80    /// Finishes an atomic operation, performing all the queued writes.
81    ///
82    fn finish_atomic(&self) -> Result<()>;
83}
84
85/// A trait representing 'nested map'-like storage operations with read-only capabilities.
86pub trait NestedMapRead<
87    'a,
88    M: 'a + Copy + Clone + PartialEq + Eq + Hash + Serialize + Deserialize<'a> + Sync,
89    K: 'a + Clone + PartialEq + Eq + Serialize + Deserialize<'a> + Sync,
90    V: 'a + Clone + Serialize + Deserialize<'a> + Sync,
91>
92{
93    type PendingIterator: Iterator<Item = (Cow<'a, M>, Option<Cow<'a, K>>, Option<Cow<'a, V>>)>;
94    type Iterator: Iterator<Item = (Cow<'a, M>, Cow<'a, K>, Cow<'a, V>)>;
95    type Keys: Iterator<Item = (Cow<'a, M>, Cow<'a, K>)>;
96    type Values: Iterator<Item = Cow<'a, V>>;
97
98    ///
99    /// Returns the number of confirmed entries in the map.
100    ///
101    fn len_map_confirmed(&self, map: &M) -> Result<usize>;
102
103    ///
104    /// Checks whether there are any confirmed entries in the map.
105    ///
106    fn is_empty_map_confirmed(&self, map: &M) -> Result<bool> {
107        Ok(self.len_map_confirmed(map)? == 0)
108    }
109
110    ///
111    /// Returns `true` if the given key exists in the map.
112    ///
113    fn contains_key_confirmed(&self, map: &M, key: &K) -> Result<bool>;
114
115    ///
116    /// Returns `true` if the given key exists in the map.
117    /// This method first checks the atomic batch, and if it does not exist, then checks the confirmed.
118    ///
119    fn contains_key_speculative(&self, map: &M, key: &K) -> Result<bool>;
120
121    ///
122    /// Returns the confirmed key-value pairs for the given map, if it exists.
123    ///
124    fn get_map_confirmed(&'a self, map: &M) -> Result<Vec<(K, V)>>;
125
126    ///
127    /// Returns the speculative key-value pairs for the given map, if it exists.
128    ///
129    fn get_map_speculative(&'a self, map: &M) -> Result<Vec<(K, V)>>;
130
131    ///
132    /// Returns the value for the given key from the map, if it exists.
133    ///
134    fn get_value_confirmed(&'a self, map: &M, key: &K) -> Result<Option<Cow<'a, V>>>;
135
136    ///
137    /// Returns the current value for the given key if it is scheduled
138    /// to be inserted as part of an atomic batch.
139    ///
140    /// If the key does not exist, returns `None`.
141    /// If the key is removed in the batch, returns `Some(None)`.
142    /// If the key is inserted in the batch, returns `Some(Some(value))`.
143    ///
144    fn get_value_pending(&self, map: &M, key: &K) -> Option<Option<V>>;
145
146    ///
147    /// Returns the value for the given key from the atomic batch first, if it exists,
148    /// or return from the map, otherwise.
149    ///
150    fn get_value_speculative(&'a self, map: &M, key: &K) -> Result<Option<Cow<'a, V>>> {
151        // Return the atomic batch value, if it exists, or the map value, otherwise.
152        match self.get_value_pending(map, key) {
153            Some(Some(value)) => Ok(Some(Cow::Owned(value))),
154            Some(None) => Ok(None),
155            None => Ok(self.get_value_confirmed(map, key)?),
156        }
157    }
158
159    ///
160    /// Returns an iterator visiting each map-key-value pair in the atomic batch.
161    ///
162    fn iter_pending(&'a self) -> Self::PendingIterator;
163
164    ///
165    /// Returns an iterator visiting each confirmed map-key-value pair.
166    ///
167    fn iter_confirmed(&'a self) -> Self::Iterator;
168
169    ///
170    /// Returns an iterator over each confirmed key.
171    ///
172    fn keys_confirmed(&'a self) -> Self::Keys;
173
174    ///
175    /// Returns an iterator over each confirmed value.
176    ///
177    fn values_confirmed(&'a self) -> Self::Values;
178}