oasis_core_runtime/storage/mkvs/
mod.rs1use std::{
3 iter,
4 ops::{Deref, DerefMut},
5};
6
7use anyhow::{Error, Result};
8
9use crate::common::{crypto::hash::Hash, namespace::Namespace};
10
11use self::sync::Proof;
12
13#[macro_use]
14mod tree;
15mod cache;
16#[cfg(test)]
17pub mod interop;
18pub mod marshal;
19pub mod sync;
20#[cfg(test)]
21mod tests;
22
23pub use tree::{Depth, Key, NodeBox, NodePointer, NodePtrRef, OverlayTree, Root, RootType, Tree};
24
25#[derive(Copy, Clone, Debug, Eq, PartialEq)]
27pub enum LogEntryKind {
28 Insert,
29 Delete,
30}
31
32#[derive(Clone, Debug, Default, Eq, PartialEq, Hash, cbor::Encode, cbor::Decode)]
34#[cbor(as_array)]
35pub struct LogEntry {
36 pub key: Vec<u8>,
38 pub value: Option<Vec<u8>>,
40}
41
42impl LogEntry {
43 pub fn new(key: &[u8], value: &[u8]) -> Self {
44 Self {
45 key: key.to_owned(),
46 value: Some(value.to_owned()),
47 }
48 }
49
50 pub fn kind(&self) -> LogEntryKind {
51 match self.value {
52 Some(_) => LogEntryKind::Insert,
53 None => LogEntryKind::Delete,
54 }
55 }
56}
57
58pub type WriteLog = Vec<LogEntry>;
62
63#[derive(Clone, Debug, Default, Eq, PartialEq, PartialOrd, Ord, cbor::Encode, cbor::Decode)]
65#[cbor(transparent)]
66pub struct Prefix(Vec<u8>);
67
68impl AsRef<[u8]> for Prefix {
69 fn as_ref(&self) -> &[u8] {
70 &self.0
71 }
72}
73
74impl Deref for Prefix {
75 type Target = Vec<u8>;
76
77 fn deref(&self) -> &Self::Target {
78 &self.0
79 }
80}
81
82impl DerefMut for Prefix {
83 fn deref_mut(&mut self) -> &mut Self::Target {
84 &mut self.0
85 }
86}
87
88impl From<Prefix> for Vec<u8> {
89 fn from(val: Prefix) -> Self {
90 val.0
91 }
92}
93
94impl From<Vec<u8>> for Prefix {
95 fn from(v: Vec<u8>) -> Prefix {
96 Prefix(v)
97 }
98}
99
100pub trait MKVS {
102 fn get(&self, key: &[u8]) -> Option<Vec<u8>>;
104
105 fn get_proof(&self, key: &[u8]) -> Option<Proof>;
107
108 fn cache_contains_key(&self, key: &[u8]) -> bool;
114
115 fn insert(&mut self, key: &[u8], value: &[u8]) -> Option<Vec<u8>>;
124
125 fn remove(&mut self, key: &[u8]) -> Option<Vec<u8>>;
128
129 fn prefetch_prefixes(&self, prefixes: &[Prefix], limit: u16);
131
132 fn iter(&self) -> Box<dyn Iterator + '_>;
134
135 fn commit(&mut self, namespace: Namespace, version: u64) -> Result<(WriteLog, Hash)>;
137}
138
139pub trait FallibleMKVS {
141 fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>>;
143
144 fn get_proof(&self, key: &[u8]) -> Result<Option<Proof>>;
146
147 fn cache_contains_key(&self, key: &[u8]) -> bool;
153
154 fn insert(&mut self, key: &[u8], value: &[u8]) -> Result<Option<Vec<u8>>>;
163
164 fn remove(&mut self, key: &[u8]) -> Result<Option<Vec<u8>>>;
167
168 fn prefetch_prefixes(&self, prefixes: &[Prefix], limit: u16) -> Result<()>;
170
171 fn iter(&self) -> Box<dyn Iterator + '_>;
173
174 fn commit(&mut self, namespace: Namespace, version: u64) -> Result<Hash>;
176}
177
178pub trait ImmutableMKVS {
180 fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>>;
182
183 fn get_proof(&self, key: &[u8]) -> Result<Option<Proof>>;
185
186 fn prefetch_prefixes(&self, prefixes: &[Prefix], limit: u16) -> Result<()>;
188
189 fn iter(&self) -> Box<dyn Iterator + '_>;
191}
192
193impl<T> ImmutableMKVS for T
194where
195 T: FallibleMKVS,
196{
197 fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>> {
198 T::get(self, key)
199 }
200
201 fn get_proof(&self, key: &[u8]) -> Result<Option<Proof>> {
202 T::get_proof(self, key)
203 }
204
205 fn prefetch_prefixes(&self, prefixes: &[Prefix], limit: u16) -> Result<()> {
206 T::prefetch_prefixes(self, prefixes, limit)
207 }
208
209 fn iter(&self) -> Box<dyn Iterator + '_> {
210 T::iter(self)
211 }
212}
213
214pub trait Iterator: iter::Iterator<Item = (Vec<u8>, Vec<u8>)> {
216 fn set_prefetch(&mut self, prefetch: usize);
218
219 fn is_valid(&self) -> bool;
221
222 fn error(&self) -> &Option<Error>;
224
225 fn rewind(&mut self);
227
228 fn seek(&mut self, key: &[u8]);
230
231 fn get_key(&self) -> &Option<Key>;
233
234 fn get_value(&self) -> &Option<Vec<u8>>;
236
237 fn next(&mut self);
239}
240
241impl<T: MKVS + ?Sized> MKVS for &mut T {
242 fn get(&self, key: &[u8]) -> Option<Vec<u8>> {
243 T::get(self, key)
244 }
245
246 fn get_proof(&self, key: &[u8]) -> Option<Proof> {
247 T::get_proof(self, key)
248 }
249
250 fn cache_contains_key(&self, key: &[u8]) -> bool {
251 T::cache_contains_key(self, key)
252 }
253
254 fn insert(&mut self, key: &[u8], value: &[u8]) -> Option<Vec<u8>> {
255 T::insert(self, key, value)
256 }
257
258 fn remove(&mut self, key: &[u8]) -> Option<Vec<u8>> {
259 T::remove(self, key)
260 }
261
262 fn prefetch_prefixes(&self, prefixes: &[Prefix], limit: u16) {
263 T::prefetch_prefixes(self, prefixes, limit)
264 }
265
266 fn iter(&self) -> Box<dyn Iterator + '_> {
267 T::iter(self)
268 }
269
270 fn commit(&mut self, namespace: Namespace, version: u64) -> Result<(WriteLog, Hash)> {
271 T::commit(self, namespace, version)
272 }
273}
274
275impl<T: FallibleMKVS + ?Sized> FallibleMKVS for &mut T {
276 fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>> {
277 T::get(self, key)
278 }
279
280 fn get_proof(&self, key: &[u8]) -> Result<Option<Proof>> {
281 T::get_proof(self, key)
282 }
283
284 fn cache_contains_key(&self, key: &[u8]) -> bool {
285 T::cache_contains_key(self, key)
286 }
287
288 fn insert(&mut self, key: &[u8], value: &[u8]) -> Result<Option<Vec<u8>>> {
289 T::insert(self, key, value)
290 }
291
292 fn remove(&mut self, key: &[u8]) -> Result<Option<Vec<u8>>> {
293 T::remove(self, key)
294 }
295
296 fn prefetch_prefixes(&self, prefixes: &[Prefix], limit: u16) -> Result<()> {
297 T::prefetch_prefixes(self, prefixes, limit)
298 }
299
300 fn iter(&self) -> Box<dyn Iterator + '_> {
301 T::iter(self)
302 }
303
304 fn commit(&mut self, namespace: Namespace, version: u64) -> Result<Hash> {
305 T::commit(self, namespace, version)
306 }
307}
308
309#[cfg(test)]
310mod _tests {
311 use super::*;
312
313 #[test]
314 fn test_write_log_serialization() {
315 let write_log = vec![LogEntry {
316 key: b"foo".to_vec(),
317 value: Some(b"bar".to_vec()),
318 }];
319
320 let raw = cbor::to_vec(write_log.clone());
321 let deserialized: WriteLog = cbor::from_slice(&raw).unwrap();
322
323 assert_eq!(write_log, deserialized);
324 }
325}