encrypted_sled/
lib.rs

1//! `encrypted-sled` is an (almost) drop in replacement / wrapper around the amazing
2//! [`sled`](https://crates.io/crates/sled) embedded database. Just configure with an encryption
3//! and use normally.
4//!
5//! # Examples
6//!
7//! ```
8//! # let _ = std::fs::remove_dir_all("my_db");
9//!
10//! let cipher = {
11//!     use chacha20poly1305::{ChaCha20Poly1305, Key, Nonce};
12//!     let mut key = Key::default();
13//!     key.copy_from_slice(b"an example very very secret key.");
14//!     encrypted_sled::EncryptionCipher::<ChaCha20Poly1305, _>::new(
15//!         key,
16//!         encrypted_sled::RandNonce::new(rand::thread_rng()),
17//!         encrypted_sled::EncryptionMode::default(),
18//!     )
19//! };
20//!
21//! let db = encrypted_sled::open("my_db", cipher).unwrap();
22//!
23//! // insert and get
24//! db.insert(b"yo!", b"v1");
25//! assert_eq!(&db.get(b"yo!").unwrap().unwrap(), b"v1");
26//!
27//! // Atomic compare-and-swap.
28//! db.compare_and_swap(
29//!     b"yo!",      // key
30//!     Some(b"v1"), // old value, None for not present
31//!     Some(b"v2"), // new value, None for delete
32//! )
33//! .unwrap();
34//!
35//! // Iterates over key-value pairs, starting at the given key.
36//! let scan_key: &[u8] = b"a non-present key before yo!";
37//! let mut iter = db.range(scan_key..).unwrap();
38//! assert_eq!(&iter.next().unwrap().unwrap().0, b"yo!");
39//! assert_eq!(iter.next(), None);
40//!
41//! db.remove(b"yo!");
42//! assert_eq!(db.get(b"yo!"), Ok(None));
43//!
44//! let other_tree = db.open_tree(b"cool db facts").unwrap();
45//! other_tree.insert(
46//!     b"k1",
47//!     &b"a Db acts like a Tree due to implementing Deref<Target = Tree>"[..]
48//! ).unwrap();
49//! # let _ = std::fs::remove_dir_all("my_db");
50//! ```
51//!
52//! # Todos
53//!
54//! A few things are still not implemented:
55//!
56//! * `TransactionalTrees` (e.g. performing a transaction on multiple trees at the same time)
57//! * Database import/export
58//!
59//! A few functions don't handle encryption/decryption gracefully and therefore may cause corrupted
60//! data, so please use at your own risk! Encrypted keys will most likely break these
61//!
62//! * `update_and_fetch` and `fetch_and_update`
63//! * Merge operators
64
65#[macro_use]
66extern crate bitflags;
67
68use aead::generic_array;
69use aead::{Aead, AeadCore, AeadInPlace, Key, NewAead, Nonce};
70use core::fmt;
71use core::future::Future;
72use core::marker::PhantomData;
73use core::ops;
74use core::pin::Pin;
75use core::task::{Context, Poll};
76use core::time::Duration;
77use generic_array::typenum;
78use std::io;
79use std::path::Path;
80use std::sync::mpsc::RecvTimeoutError;
81use std::sync::{Arc, Mutex};
82use typenum::Unsigned;
83
84pub use sled::{CompareAndSwapError, Error, Event, IVec, MergeOperator, Mode};
85
86/// The top-level result type for dealing with fallible operations. The errors tend to
87/// be fail-stop, and nested results are used in cases where the outer fail-stop error can
88/// have try ? used on it, exposing the inner operation that is expected to fail under
89/// normal operation. The philosophy behind this is detailed on the sled blog.
90pub type Result<T, E = sled::Error> = std::result::Result<T, E>;
91
92bitflags! {
93/// A descriptor for which data should be encrypted/decrypted
94pub struct EncryptionMode: u32 {
95    const KEY = 0b0001;
96    const VALUE = 0b0010;
97    const TREE_NAME = 0b0100;
98}
99}
100
101impl Default for EncryptionMode {
102    fn default() -> Self {
103        EncryptionMode::VALUE
104    }
105}
106
107/// Describes a sequence of nonces, similar to an Iterator
108pub trait NonceSequence<C>
109where
110    C: AeadCore,
111{
112    /// Get the next nonce in the sequence. May return an erro if there is no more nonce
113    fn advance(&mut self) -> Result<Nonce<C>>;
114}
115
116/// A simple nonce which always increments by one
117#[derive(Debug, Clone, PartialEq, Eq, Ord, PartialOrd)]
118pub struct CountingNonce<C>
119where
120    C: AeadCore,
121{
122    nonce: Nonce<C>,
123}
124
125impl<C> CountingNonce<C>
126where
127    C: AeadCore,
128{
129    pub fn new(nonce: Nonce<C>) -> Self {
130        Self { nonce }
131    }
132}
133
134impl<C> NonceSequence<C> for CountingNonce<C>
135where
136    C: AeadCore,
137{
138    fn advance(&mut self) -> Result<Nonce<C>> {
139        let next = self.nonce.clone();
140        for byte in self.nonce.as_mut_slice().iter_mut().rev() {
141            if *byte == 0xff {
142                *byte = 0;
143            } else {
144                *byte += 1;
145                break;
146            }
147        }
148        Ok(next)
149    }
150}
151
152/// A simple nonce which randomly generates the next nonce in the sequnce
153#[cfg(feature = "rand")]
154pub struct RandNonce<R>
155where
156    R: rand::RngCore,
157{
158    rng: R,
159}
160
161#[cfg(feature = "rand")]
162impl<R> RandNonce<R>
163where
164    R: rand::RngCore,
165{
166    pub fn new(rng: R) -> Self {
167        Self { rng }
168    }
169}
170
171#[cfg(feature = "rand")]
172impl<R, C> NonceSequence<C> for RandNonce<R>
173where
174    C: AeadCore,
175    R: rand::RngCore,
176{
177    fn advance(&mut self) -> Result<Nonce<C>> {
178        use rand::Rng;
179        let mut out = Nonce::<C>::default();
180        self.rng
181            .try_fill(out.as_mut_slice())
182            .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
183        Ok(out)
184    }
185}
186
187/// Describes the [`Key`], [`NonceSequence`] and [`EncryptionMode`] used to encrypt / decrypt
188/// the data
189pub struct EncryptionCipher<C, S>
190where
191    C: AeadCore + NewAead,
192    S: NonceSequence<C>,
193{
194    cipher: PhantomData<C>,
195    key: Key<C>,
196    nonces: Arc<Mutex<S>>,
197    mode: EncryptionMode,
198}
199
200impl<C, S> EncryptionCipher<C, S>
201where
202    C: AeadCore + NewAead + AeadInPlace,
203    S: NonceSequence<C>,
204{
205    /// Create a new EncryptionCipher
206    pub fn new(key: Key<C>, nonces: S, mode: EncryptionMode) -> Self {
207        Self {
208            cipher: PhantomData,
209            key,
210            nonces: Arc::new(Mutex::new(nonces)),
211            mode,
212        }
213    }
214
215    #[inline]
216    fn applies_to(&self, mode: EncryptionMode) -> bool {
217        self.mode.contains(mode)
218    }
219
220    fn salt_and_hash(&self, data: impl AsRef<[u8]>) -> blake3::Hash {
221        let mut data = data.as_ref().to_vec();
222        data.extend(&self.key);
223        blake3::hash(&data)
224    }
225
226    fn encrypt_data(&self, data: IVec, mode: EncryptionMode, nonce: Option<IVec>) -> Result<IVec> {
227        if !self.applies_to(mode) {
228            return Ok(data);
229        }
230
231        let nonce_size = C::NonceSize::to_usize();
232        let nonce = if let Some(nonce) = nonce {
233            if nonce.len() != nonce_size {
234                return Err(Error::Io(io::Error::new(
235                    io::ErrorKind::InvalidData,
236                    format!(
237                        "invalid nonce: expected {} bytes, got {} bytes",
238                        nonce_size,
239                        nonce.len()
240                    ),
241                )));
242            }
243            let mut new_nonce = Nonce::<C>::default();
244            new_nonce.copy_from_slice(&nonce);
245            new_nonce
246        } else {
247            self.nonces
248                .lock()
249                .map_err(|_| io::Error::new(io::ErrorKind::Other, "Nonce sequence lock poisoned"))?
250                .advance()?
251        };
252        let cipher = C::new(&self.key);
253        let data = cipher
254            .encrypt(&nonce, data.as_ref())
255            .map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "failed to encrypt data"))?;
256
257        let mut out = vec![0; nonce_size + data.len()];
258        out[..nonce_size].copy_from_slice(&nonce);
259        out[nonce_size..].copy_from_slice(&data);
260        Ok(out.into())
261    }
262
263    fn extract_nonce_from_encrypted(&self, data: &IVec) -> Result<Nonce<C>> {
264        let nonce_size = C::NonceSize::to_usize();
265        if data.len() < nonce_size {
266            return Err(Error::Io(io::Error::new(
267                io::ErrorKind::InvalidData,
268                format!(
269                    "Encrypted data is too small. Expected at least {} bytes, got {} bytes",
270                    nonce_size,
271                    data.len()
272                ),
273            )));
274        }
275        let mut nonce = Nonce::<C>::default();
276        nonce.copy_from_slice(&data[..nonce_size]);
277        Ok(nonce)
278    }
279
280    fn decrypt_data(&self, data: IVec, mode: EncryptionMode) -> Result<IVec> {
281        if !self.applies_to(mode) {
282            return Ok(data);
283        }
284
285        let nonce = self.extract_nonce_from_encrypted(&data)?;
286        let cipher = C::new(&self.key);
287
288        let data = cipher
289            .decrypt(&nonce, &data[C::NonceSize::to_usize()..])
290            .map_err(|_| io::Error::new(io::ErrorKind::InvalidData, "failed to decrypt data"))?;
291        Ok(data.into())
292    }
293}
294
295impl<C, S> Clone for EncryptionCipher<C, S>
296where
297    C: AeadCore + NewAead,
298    S: NonceSequence<C>,
299{
300    fn clone(&self) -> Self {
301        Self {
302            cipher: self.cipher,
303            key: self.key.clone(),
304            nonces: self.nonces.clone(),
305            mode: self.mode,
306        }
307    }
308}
309
310impl<C, S> fmt::Debug for EncryptionCipher<C, S>
311where
312    C: AeadCore + NewAead,
313    S: NonceSequence<C>,
314{
315    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
316        f.debug_struct("EncryptionCipher")
317            .field("cipher", &core::any::type_name::<C>())
318            .field("mode", &self.mode)
319            .finish()
320    }
321}
322
323const DEFAULT_TREE_NAME: &[u8] = b"__sled__default";
324const KEY_NONCE_PREFIX: &[u8] = b"__encrypted_sled__key_nonce_";
325const TREE_NONCE_PREFIX: &[u8] = b"__encrypted_sled__tree_nonce_";
326
327fn key_nonce_key(hashed: blake3::Hash) -> [u8; KEY_NONCE_PREFIX.len() + blake3::OUT_LEN] {
328    let mut key = [0u8; KEY_NONCE_PREFIX.len() + blake3::OUT_LEN];
329    key[..KEY_NONCE_PREFIX.len()].copy_from_slice(KEY_NONCE_PREFIX);
330    key[KEY_NONCE_PREFIX.len()..].copy_from_slice(hashed.as_bytes().as_slice());
331    key
332}
333
334fn tree_nonce_key(hashed: blake3::Hash) -> [u8; TREE_NONCE_PREFIX.len() + blake3::OUT_LEN] {
335    let mut key = [0u8; TREE_NONCE_PREFIX.len() + blake3::OUT_LEN];
336    key[..TREE_NONCE_PREFIX.len()].copy_from_slice(TREE_NONCE_PREFIX);
337    key[TREE_NONCE_PREFIX.len()..].copy_from_slice(hashed.as_bytes().as_slice());
338    key
339}
340
341fn is_system_key(key: impl AsRef<[u8]>) -> bool {
342    let k = key.as_ref();
343    (k.len() == KEY_NONCE_PREFIX.len() + blake3::OUT_LEN
344        && &k[..KEY_NONCE_PREFIX.len()] == KEY_NONCE_PREFIX)
345        || (k.len() == TREE_NONCE_PREFIX.len() + blake3::OUT_LEN
346            && &k[..TREE_NONCE_PREFIX.len()] == TREE_NONCE_PREFIX)
347}
348
349type DefaultNonceFn<'a, E> = Box<dyn Fn(&IVec) -> Result<Option<IVec>, E> + 'a>;
350
351#[inline]
352fn no_nonce(_: &IVec) -> Result<Option<IVec>> {
353    Ok(None)
354}
355
356/// Encryption operations
357pub trait Encryption {
358    fn applies_to(&self, mode: EncryptionMode) -> bool;
359    fn encrypt_ivec(&self, data: IVec, mode: EncryptionMode, nonce: Option<IVec>) -> Result<IVec>;
360    fn decrypt_ivec(&self, data: IVec, mode: EncryptionMode) -> Result<IVec>;
361    fn get_nonce_from_encrypted(&self, data: &IVec) -> Result<IVec>;
362    fn salt_and_hash<D: AsRef<[u8]>>(&self, data: D) -> blake3::Hash;
363    fn applies_to_key(&self) -> bool {
364        self.applies_to(EncryptionMode::KEY)
365    }
366    fn applies_to_tree_name(&self) -> bool {
367        self.applies_to(EncryptionMode::TREE_NAME)
368    }
369    #[inline]
370    fn encrypt<T, E>(
371        &self,
372        data: T,
373        mode: EncryptionMode,
374        default_nonce_fn: DefaultNonceFn<E>,
375    ) -> Result<IVec, E>
376    where
377        T: Into<IVec>,
378        E: From<Error>,
379    {
380        let data = data.into();
381        let default_nonce = if self.applies_to(mode) {
382            default_nonce_fn(&data)?
383        } else {
384            None
385        };
386        Ok(self.encrypt_ivec(data, mode, default_nonce)?)
387    }
388    #[inline]
389    fn decrypt<T: Into<IVec>>(&self, data: T, mode: EncryptionMode) -> Result<IVec> {
390        self.decrypt_ivec(data.into(), mode)
391    }
392    #[inline]
393    fn encrypt_key<T, E>(&self, data: T, default_nonce_fn: DefaultNonceFn<E>) -> Result<IVec, E>
394    where
395        T: Into<IVec>,
396        E: From<Error>,
397    {
398        self.encrypt(data, EncryptionMode::KEY, default_nonce_fn)
399    }
400    #[inline]
401    fn decrypt_key<T: Into<IVec>>(&self, data: T) -> Result<IVec> {
402        self.decrypt(data, EncryptionMode::KEY)
403    }
404    #[inline]
405    fn encrypt_value<T: Into<IVec>>(&self, data: T) -> Result<IVec> {
406        self.encrypt(data, EncryptionMode::VALUE, Box::new(no_nonce))
407    }
408    #[inline]
409    fn decrypt_value<T: Into<IVec>>(&self, data: T) -> Result<IVec> {
410        self.decrypt(data, EncryptionMode::VALUE)
411    }
412    fn encrypt_tree_name<T, E>(
413        &self,
414        data: T,
415        default_nonce_fn: DefaultNonceFn<E>,
416    ) -> Result<IVec, E>
417    where
418        T: Into<IVec>,
419        E: From<Error>,
420    {
421        let data = data.into();
422        if data == DEFAULT_TREE_NAME {
423            return Ok(data);
424        }
425        self.encrypt(data, EncryptionMode::TREE_NAME, default_nonce_fn)
426    }
427    fn decrypt_tree_name<T: Into<IVec>>(&self, data: T) -> Result<IVec> {
428        let data = data.into();
429        if data == DEFAULT_TREE_NAME {
430            return Ok(data);
431        }
432        self.decrypt(data, EncryptionMode::TREE_NAME)
433    }
434    fn decrypt_value_result<E>(&self, res: Result<Option<IVec>, E>) -> Result<Option<IVec>, E>
435    where
436        E: From<Error>,
437    {
438        Ok(match res? {
439            None => None,
440            Some(val) => Some(self.decrypt_value(val)?),
441        })
442    }
443    fn decrypt_key_value_result(
444        &self,
445        res: Result<Option<(IVec, IVec)>>,
446    ) -> Result<Option<(IVec, IVec)>> {
447        Ok(match res? {
448            None => None,
449            Some((key, val)) => Some((self.decrypt_key(key)?, self.decrypt_value(val)?)),
450        })
451    }
452    fn decrypt_event(&self, event: Event) -> Result<Event> {
453        Ok(match event {
454            Event::Insert { key, value } => Event::Insert {
455                key: self.decrypt_key(key)?,
456                value: self.decrypt_value(value)?,
457            },
458            Event::Remove { key } => Event::Remove {
459                key: self.decrypt_key(key)?,
460            },
461        })
462    }
463}
464
465impl<T> Encryption for T
466where
467    T: ops::Deref,
468    T::Target: Encryption,
469{
470    fn encrypt_ivec(&self, data: IVec, mode: EncryptionMode, nonce: Option<IVec>) -> Result<IVec> {
471        self.deref().encrypt_ivec(data, mode, nonce)
472    }
473    fn decrypt_ivec(&self, data: IVec, mode: EncryptionMode) -> Result<IVec> {
474        self.deref().decrypt_ivec(data, mode)
475    }
476    fn applies_to(&self, mode: EncryptionMode) -> bool {
477        self.deref().applies_to(mode)
478    }
479    fn get_nonce_from_encrypted(&self, data: &IVec) -> Result<IVec> {
480        self.deref().get_nonce_from_encrypted(data)
481    }
482    fn salt_and_hash<D: AsRef<[u8]>>(&self, data: D) -> blake3::Hash {
483        self.deref().salt_and_hash(data)
484    }
485}
486
487impl<C, S> Encryption for EncryptionCipher<C, S>
488where
489    C: AeadCore + NewAead + AeadInPlace,
490    S: NonceSequence<C>,
491{
492    fn encrypt_ivec(&self, data: IVec, mode: EncryptionMode, nonce: Option<IVec>) -> Result<IVec> {
493        self.encrypt_data(data, mode, nonce)
494    }
495    fn decrypt_ivec(&self, data: IVec, mode: EncryptionMode) -> Result<IVec> {
496        self.decrypt_data(data, mode)
497    }
498    fn applies_to(&self, mode: EncryptionMode) -> bool {
499        self.applies_to(mode)
500    }
501    fn get_nonce_from_encrypted(&self, data: &IVec) -> Result<IVec> {
502        Ok(self.extract_nonce_from_encrypted(data)?.as_slice().into())
503    }
504    fn salt_and_hash<D: AsRef<[u8]>>(&self, data: D) -> blake3::Hash {
505        self.salt_and_hash(data)
506    }
507}
508
509/// A flash-sympathetic persistent lock-free B+ tree.
510#[derive(Debug, Clone)]
511pub struct Tree<E> {
512    inner: sled::Tree,
513    encryption: Arc<E>,
514}
515
516impl<E> Tree<E> {
517    pub(crate) fn new(inner: sled::Tree, encryption: Arc<E>) -> Self {
518        Self { inner, encryption }
519    }
520}
521
522/// Top-level configuration for the system.
523#[derive(Debug, Clone)]
524pub struct Db<E> {
525    inner: sled::Db,
526    tree: Tree<E>,
527    encryption: Arc<E>,
528}
529
530impl<E> Db<E> {
531    pub(crate) fn new(inner: sled::Db, encryption: Arc<E>) -> Self {
532        let tree = Tree::new(sled::Tree::clone(&inner), encryption.clone());
533        Self {
534            inner,
535            tree,
536            encryption,
537        }
538    }
539}
540
541impl<E> ops::Deref for Db<E> {
542    type Target = Tree<E>;
543    fn deref(&self) -> &Tree<E> {
544        &self.tree
545    }
546}
547
548/// The sled embedded database! Implements Deref<Target = sled::Tree> to refer to a default
549/// keyspace / namespace / bucket.
550#[derive(Debug, Clone)]
551pub struct Config<E> {
552    inner: sled::Config,
553    encryption: Arc<E>,
554}
555
556macro_rules! config_fn {
557    ($name:ident, $t:ty) => {
558        pub fn $name(self, to: $t) -> Self {
559            Self {
560                inner: self.inner.$name(to),
561                encryption: self.encryption,
562            }
563        }
564    };
565}
566
567impl<E> Config<E>
568where
569    E: Encryption,
570{
571    pub fn new(encryption: E) -> Self {
572        Self {
573            inner: sled::Config::new(),
574            encryption: Arc::new(encryption),
575        }
576    }
577    pub fn path<P: AsRef<Path>>(self, path: P) -> Self {
578        Self {
579            inner: self.inner.path(path),
580            encryption: self.encryption,
581        }
582    }
583    pub fn open(&self) -> Result<Db<E>> {
584        self.inner
585            .open()
586            .map(move |db| Db::new(db, self.encryption.clone()))
587    }
588    config_fn!(cache_capacity, u64);
589    config_fn!(mode, sled::Mode);
590    config_fn!(use_compression, bool);
591    config_fn!(compression_factor, i32);
592    config_fn!(temporary, bool);
593    config_fn!(create_new, bool);
594    config_fn!(print_profile_on_drop, bool);
595}
596
597/// A batch of updates that will be applied atomically to the Tree.
598#[derive(Debug, Clone, Default)]
599pub struct Batch {
600    events: Vec<Event>,
601}
602
603impl Batch {
604    /// Set a key to a new value
605    pub fn insert<K, V>(&mut self, key: K, value: V)
606    where
607        K: Into<IVec>,
608        V: Into<IVec>,
609    {
610        self.events.push(Event::Insert {
611            key: key.into(),
612            value: value.into(),
613        })
614    }
615    /// Remove a key
616    pub fn remove<K>(&mut self, key: K)
617    where
618        K: Into<IVec>,
619    {
620        self.events.push(Event::Remove { key: key.into() })
621    }
622}
623
624impl<E> Db<E>
625where
626    E: Encryption,
627{
628    /// Open or create a new disk-backed Tree with its own keyspace, accessible from the Db via
629    /// the provided identifier.
630    pub fn open_tree<V: AsRef<[u8]>>(&self, name: V) -> Result<Tree<E>> {
631        let encrypted_name = self
632            .encryption
633            .encrypt_tree_name(name.as_ref(), self.default_tree_nonce_fn())?;
634        let tree = self
635            .inner
636            .open_tree(&encrypted_name)
637            .map(|tree| Tree::new(tree, self.encryption.clone()))?;
638        if self.encryption.applies_to_tree_name() {
639            let nonce = self.encryption.get_nonce_from_encrypted(&encrypted_name)?;
640            self.inner
641                .insert(&tree_nonce_key(self.encryption.salt_and_hash(name)), nonce)?;
642        }
643        Ok(tree)
644    }
645    /// Remove a disk-backed collection.
646    pub fn drop_tree<V: AsRef<[u8]>>(&self, name: V) -> Result<bool> {
647        let encrypted_name = self
648            .encryption
649            .encrypt_tree_name(name.as_ref(), self.default_tree_nonce_fn())?;
650        let dropped = self.inner.drop_tree(encrypted_name)?;
651        if self.encryption.applies_to_tree_name() {
652            self.inner
653                .remove(&tree_nonce_key(self.encryption.salt_and_hash(name)))?;
654        }
655        Ok(dropped)
656    }
657    /// Returns the trees names saved in this Db.
658    pub fn tree_names(&self) -> Result<Vec<IVec>> {
659        self.inner
660            .tree_names()
661            .into_iter()
662            .map(|name| self.encryption.decrypt_tree_name(name))
663            .collect()
664    }
665    #[inline]
666    pub fn was_recovered(&self) -> bool {
667        self.inner.was_recovered()
668    }
669    #[inline]
670    pub fn generate_id(&self) -> Result<u64> {
671        self.inner.generate_id()
672    }
673    #[inline]
674    pub fn checksum(&self) -> Result<u32> {
675        self.inner.checksum()
676    }
677    #[inline]
678    pub fn size_on_disk(&self) -> Result<u64> {
679        self.inner.size_on_disk()
680    }
681    fn default_tree_nonce_fn(&self) -> DefaultNonceFn<Error> {
682        Box::new(move |data| {
683            self.inner
684                .get(&tree_nonce_key(self.encryption.salt_and_hash(data)))
685        })
686    }
687
688    // TODO implement export and import
689}
690
691/// An iterator over keys and values in a Tree.
692pub struct Iter<E> {
693    inner: sled::Iter,
694    encryption: Arc<E>,
695}
696
697impl<E> Iter<E> {
698    pub(crate) fn new(inner: sled::Iter, encryption: Arc<E>) -> Self {
699        Self { inner, encryption }
700    }
701}
702
703impl<E> Iter<E>
704where
705    E: Encryption + Send + Sync,
706{
707    pub fn keys(self) -> impl DoubleEndedIterator<Item = Result<IVec>> + Send + Sync {
708        let encryption = self.encryption;
709        self.inner
710            .filter(|res| match res {
711                Err(_) => true,
712                Ok((k, _)) => !is_system_key(k),
713            })
714            .map(move |key_res| key_res.and_then(|(key, _)| encryption.decrypt_key(key)))
715    }
716    pub fn values(self) -> impl DoubleEndedIterator<Item = Result<IVec>> + Send + Sync {
717        let encryption = self.encryption;
718        self.inner
719            .filter(|res| match res {
720                Err(_) => true,
721                Ok((k, _)) => !is_system_key(k),
722            })
723            .map(move |key_res| key_res.and_then(|(_, val)| encryption.decrypt_value(val)))
724    }
725}
726
727impl<E> Iterator for Iter<E>
728where
729    E: Encryption,
730{
731    type Item = Result<(IVec, IVec)>;
732    fn next(&mut self) -> Option<Self::Item> {
733        while let Some(res) = self.inner.next() {
734            if let Ok((k, _)) = res.as_ref() {
735                if is_system_key(k) {
736                    continue;
737                }
738            }
739            return Some(res.and_then(|(k, v)| {
740                Ok((
741                    self.encryption.decrypt_key(k)?,
742                    self.encryption.decrypt_value(v)?,
743                ))
744            }));
745        }
746        None
747    }
748}
749
750impl<E> DoubleEndedIterator for Iter<E>
751where
752    E: Encryption,
753{
754    fn next_back(&mut self) -> Option<Self::Item> {
755        while let Some(res) = self.inner.next_back() {
756            if let Ok((k, _)) = res.as_ref() {
757                if is_system_key(k) {
758                    continue;
759                }
760            }
761            return Some(res.and_then(|(k, v)| {
762                Ok((
763                    self.encryption.decrypt_key(k)?,
764                    self.encryption.decrypt_value(v)?,
765                ))
766            }));
767        }
768        None
769    }
770}
771
772/// A subscriber listening on a specified prefix
773pub struct Subscriber<E> {
774    inner: sled::Subscriber,
775    encryption: Arc<E>,
776}
777
778impl<E> Subscriber<E> {
779    pub(crate) fn new(inner: sled::Subscriber, encryption: Arc<E>) -> Self {
780        Self { inner, encryption }
781    }
782    fn pin_get_inner(self: Pin<&mut Self>) -> Pin<&mut sled::Subscriber> {
783        unsafe { self.map_unchecked_mut(|s| &mut s.inner) }
784    }
785}
786
787impl<E> Subscriber<E>
788where
789    E: Encryption,
790{
791    pub fn next_timeout(&mut self, timeout: Duration) -> Result<Result<Event>, RecvTimeoutError> {
792        self.inner
793            .next_timeout(timeout)
794            .map(|event| self.encryption.decrypt_event(event))
795    }
796}
797
798impl<E> Future for Subscriber<E>
799where
800    E: Encryption,
801{
802    type Output = Option<Result<Event>>;
803    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
804        let encryption = self.encryption.clone();
805        self.pin_get_inner()
806            .poll(cx)
807            .map(|event| event.map(|event| encryption.decrypt_event(event)))
808    }
809}
810
811impl<E> Iterator for Subscriber<E>
812where
813    E: Encryption,
814{
815    type Item = Result<Event>;
816    fn next(&mut self) -> Option<Self::Item> {
817        self.inner
818            .next()
819            .map(|event| self.encryption.decrypt_event(event))
820    }
821}
822
823impl<E> Tree<E>
824where
825    E: Encryption,
826{
827    pub fn get<K: AsRef<[u8]>>(&self, key: K) -> Result<Option<IVec>> {
828        self.encryption.decrypt_value_result(
829            self.inner.get(
830                self.encryption
831                    .encrypt_key(key.as_ref(), self.default_key_nonce_fn())?,
832            ),
833        )
834    }
835
836    // needs to be performed in a transaction because the nonce needs to be updated
837    pub fn insert<K, V>(&self, key: K, value: V) -> Result<Option<IVec>>
838    where
839        K: AsRef<[u8]>,
840        V: Into<IVec>,
841    {
842        let value = value.into();
843        match self.transaction::<_, _, core::convert::Infallible>(|db| {
844            Ok(db.insert(&key, value.clone())?)
845        }) {
846            Ok(res) => Ok(res),
847            Err(transaction::TransactionError::Abort(_)) => {
848                unreachable!("there should be no abort possible in this transaction")
849            }
850            Err(transaction::TransactionError::Storage(err)) => Err(err),
851        }
852    }
853
854    // needs to be performed in a transaction because the nonce needs to be updated
855    pub fn remove<K: AsRef<[u8]>>(&self, key: K) -> Result<Option<IVec>> {
856        match self.transaction::<_, _, core::convert::Infallible>(|db| Ok(db.remove(&key)?)) {
857            Ok(res) => Ok(res),
858            Err(transaction::TransactionError::Abort(_)) => {
859                unreachable!("there should be no abort possible in this transaction")
860            }
861            Err(transaction::TransactionError::Storage(err)) => Err(err),
862        }
863    }
864
865    // needs to be performed in a transaction because the nonces need to be updated
866    pub fn apply_batch(&self, batch: Batch) -> Result<()> {
867        match self.transaction::<_, _, core::convert::Infallible>(|db| Ok(db.apply_batch(&batch)?))
868        {
869            Ok(res) => Ok(res),
870            Err(transaction::TransactionError::Abort(_)) => {
871                unreachable!("there should be no abort possible in this transaction")
872            }
873            Err(transaction::TransactionError::Storage(err)) => Err(err),
874        }
875    }
876
877    pub fn transaction<F, A, Error>(&self, f: F) -> transaction::TransactionResult<A, Error>
878    where
879        F: Fn(
880            &transaction::TransactionalTree<E>,
881        ) -> transaction::ConflictableTransactionResult<A, Error>,
882    {
883        self.inner.transaction(|tree| {
884            f(&transaction::TransactionalTree::new(
885                tree.clone(),
886                self.encryption.clone(),
887            ))
888        })
889    }
890
891    pub fn watch_prefix<P: AsRef<[u8]>>(&self, prefix: P) -> Result<Subscriber<E>> {
892        Ok(Subscriber::new(
893            self.inner.watch_prefix(
894                self.encryption
895                    .encrypt_key(prefix.as_ref(), self.default_key_nonce_fn())?,
896            ),
897            self.encryption.clone(),
898        ))
899    }
900
901    pub fn compare_and_swap<K, OV, NV>(
902        &self,
903        key: K,
904        old: Option<OV>,
905        new: Option<NV>,
906    ) -> Result<Result<(), CompareAndSwapError>>
907    where
908        K: AsRef<[u8]>,
909        OV: AsRef<[u8]>,
910        NV: Into<IVec>,
911    {
912        self.inner
913            .compare_and_swap(
914                self.encryption
915                    .encrypt_key(key.as_ref(), self.default_key_nonce_fn())?,
916                old.map(|val| self.encryption.encrypt_value(val.as_ref()))
917                    .transpose()?,
918                new.map(|val| self.encryption.encrypt_value(val))
919                    .transpose()?,
920            )
921            .map(|res| {
922                // TODO handle encrypt / decrypt errors more elegantly but for the most part this
923                // shouldn't happen because we should have verified old and new I believe...
924                res.map_err(|cas| CompareAndSwapError {
925                    current: cas
926                        .current
927                        .map(|v| self.encryption.decrypt_value(v).unwrap_or_default()),
928                    proposed: cas
929                        .proposed
930                        .map(|v| self.encryption.decrypt_value(v).unwrap_or_default()),
931                })
932            })
933    }
934
935    pub fn update_and_fetch<K, V, F>(&self, key: K, mut f: F) -> Result<Option<IVec>>
936    where
937        K: AsRef<[u8]>,
938        F: FnMut(Option<IVec>) -> Option<V>,
939        V: Into<IVec>,
940    {
941        let new_f = move |old: Option<&[u8]>| {
942            f(old.map(|val| {
943                self.encryption
944                    .decrypt_value(val.as_ref())
945                    .unwrap_or_default()
946            }))
947            .map(|val| self.encryption.encrypt_value(val).unwrap_or_default())
948        };
949        self.encryption.decrypt_value_result(
950            self.inner.update_and_fetch(
951                self.encryption
952                    .encrypt_key(key.as_ref(), self.default_key_nonce_fn())?,
953                new_f,
954            ),
955        )
956    }
957
958    pub fn fetch_and_update<K, V, F>(&self, key: K, mut f: F) -> Result<Option<IVec>>
959    where
960        K: AsRef<[u8]>,
961        F: FnMut(Option<IVec>) -> Option<V>,
962        V: Into<IVec>,
963    {
964        let new_f = move |old: Option<&[u8]>| {
965            f(old.map(|val| {
966                self.encryption
967                    .decrypt_value(val.as_ref())
968                    .unwrap_or_default()
969            }))
970            .map(|val| self.encryption.encrypt_value(val).unwrap_or_default())
971        };
972        self.encryption.decrypt_value_result(
973            self.inner.fetch_and_update(
974                self.encryption
975                    .encrypt_key(key.as_ref(), self.default_key_nonce_fn())?,
976                new_f,
977            ),
978        )
979    }
980
981    #[inline]
982    pub fn flush(&self) -> Result<usize> {
983        self.inner.flush()
984    }
985
986    #[inline]
987    pub async fn flush_async(&self) -> Result<usize> {
988        self.inner.flush_async().await
989    }
990
991    pub fn contains_key<K: AsRef<[u8]>>(&self, key: K) -> Result<bool> {
992        self.inner.contains_key(
993            self.encryption
994                .encrypt_key(key.as_ref(), self.default_key_nonce_fn())?,
995        )
996    }
997
998    pub fn get_lt<K>(&self, key: K) -> Result<Option<(IVec, IVec)>>
999    where
1000        K: AsRef<[u8]>,
1001    {
1002        self.encryption.decrypt_key_value_result(
1003            self.inner.get_lt(
1004                self.encryption
1005                    .encrypt_key(key.as_ref(), self.default_key_nonce_fn())?,
1006            ),
1007        )
1008    }
1009
1010    pub fn get_gt<K>(&self, key: K) -> Result<Option<(IVec, IVec)>>
1011    where
1012        K: AsRef<[u8]>,
1013    {
1014        self.encryption.decrypt_key_value_result(
1015            self.inner.get_gt(
1016                self.encryption
1017                    .encrypt_key(key.as_ref(), self.default_key_nonce_fn())?,
1018            ),
1019        )
1020    }
1021
1022    pub fn first(&self) -> Result<Option<(IVec, IVec)>> {
1023        self.encryption.decrypt_key_value_result(self.inner.first())
1024    }
1025    pub fn last(&self) -> Result<Option<(IVec, IVec)>> {
1026        self.encryption.decrypt_key_value_result(self.inner.last())
1027    }
1028    pub fn pop_min(&self) -> Result<Option<(IVec, IVec)>> {
1029        self.encryption
1030            .decrypt_key_value_result(self.inner.pop_min())
1031    }
1032    pub fn pop_max(&self) -> Result<Option<(IVec, IVec)>> {
1033        self.encryption
1034            .decrypt_key_value_result(self.inner.pop_max())
1035    }
1036
1037    pub fn iter(&self) -> Iter<E> {
1038        Iter::new(self.inner.iter(), self.encryption.clone())
1039    }
1040
1041    pub fn range<K, R>(&self, range: R) -> Result<Iter<E>>
1042    where
1043        K: AsRef<[u8]>,
1044        R: ops::RangeBounds<K>,
1045    {
1046        let encrypt_bound = |bound: ops::Bound<&K>| -> Result<ops::Bound<IVec>> {
1047            Ok(match bound {
1048                ops::Bound::Unbounded => ops::Bound::Unbounded,
1049                ops::Bound::Included(x) => ops::Bound::Included(
1050                    self.encryption
1051                        .encrypt_key(x.as_ref(), self.default_key_nonce_fn())?,
1052                ),
1053                ops::Bound::Excluded(x) => ops::Bound::Excluded(
1054                    self.encryption
1055                        .encrypt_key(x.as_ref(), self.default_key_nonce_fn())?,
1056                ),
1057            })
1058        };
1059        let range = (
1060            encrypt_bound(range.start_bound())?,
1061            encrypt_bound(range.end_bound())?,
1062        );
1063        Ok(Iter::new(self.inner.range(range), self.encryption.clone()))
1064    }
1065
1066    pub fn scan_prefix<P>(&self, prefix: P) -> Result<Iter<E>>
1067    where
1068        P: AsRef<[u8]>,
1069    {
1070        Ok(Iter::new(
1071            self.inner.scan_prefix(
1072                self.encryption
1073                    .encrypt_key(prefix.as_ref(), self.default_key_nonce_fn())?,
1074            ),
1075            self.encryption.clone(),
1076        ))
1077    }
1078
1079    pub fn len(&self) -> usize {
1080        self.iter().count()
1081    }
1082
1083    #[inline]
1084    pub fn is_empty(&self) -> bool {
1085        self.inner.is_empty()
1086    }
1087
1088    #[inline]
1089    pub fn clear(&self) -> Result<()> {
1090        self.inner.clear()
1091    }
1092
1093    pub fn name(&self) -> Result<IVec> {
1094        self.encryption.decrypt_tree_name(self.inner.name())
1095    }
1096
1097    #[inline]
1098    pub fn checksum(&self) -> Result<u32> {
1099        self.inner.checksum()
1100    }
1101
1102    fn default_key_nonce_fn(&self) -> DefaultNonceFn<Error> {
1103        Box::new(move |data| {
1104            self.inner
1105                .get(&key_nonce_key(self.encryption.salt_and_hash(data)))
1106        })
1107    }
1108}
1109
1110impl<E> Tree<E>
1111where
1112    E: Encryption + 'static,
1113{
1114    pub fn merge<K, V>(&self, key: K, value: V) -> Result<Option<IVec>>
1115    where
1116        K: AsRef<[u8]>,
1117        V: AsRef<[u8]>,
1118    {
1119        self.encryption.decrypt_value_result(
1120            self.inner.merge(
1121                self.encryption
1122                    .encrypt_key(key.as_ref(), self.default_key_nonce_fn())?,
1123                self.encryption.encrypt_value(value.as_ref())?,
1124            ),
1125        )
1126    }
1127
1128    pub fn set_merge_operator(&self, merge_operator: impl sled::MergeOperator + 'static) {
1129        let encryption = self.encryption.clone();
1130        let new_operator = move |key: &[u8], old: Option<&[u8]>, merged: &[u8]| {
1131            merge_operator(
1132                &encryption.decrypt_key(key.as_ref()).unwrap_or_default(),
1133                old.map(|v| encryption.decrypt_value(v.as_ref()).unwrap_or_default())
1134                    .as_deref(),
1135                &encryption
1136                    .decrypt_value(merged.as_ref())
1137                    .unwrap_or_default(),
1138            )
1139            .map(|v| encryption.encrypt_value(v).unwrap_or_default().to_vec())
1140        };
1141        self.inner.set_merge_operator(new_operator);
1142    }
1143}
1144
1145/// Fully serializable (ACID) multi-Tree transactions
1146pub mod transaction {
1147    use super::*;
1148    pub use sled::transaction::{
1149        abort, ConflictableTransactionError, ConflictableTransactionResult, TransactionError,
1150        TransactionResult, UnabortableTransactionError,
1151    };
1152
1153    /// A transaction that will be applied atomically to the Tree.
1154    pub struct TransactionalTree<E> {
1155        inner: sled::transaction::TransactionalTree,
1156        encryption: Arc<E>,
1157    }
1158
1159    impl<E> TransactionalTree<E>
1160    where
1161        E: Encryption,
1162    {
1163        pub(crate) fn new(inner: sled::transaction::TransactionalTree, encryption: Arc<E>) -> Self {
1164            Self { inner, encryption }
1165        }
1166
1167        /// Get the value associated with a key
1168        pub fn get<K: AsRef<[u8]>>(
1169            &self,
1170            key: K,
1171        ) -> Result<Option<IVec>, UnabortableTransactionError> {
1172            self.encryption.decrypt_value_result(
1173                self.inner.get(
1174                    self.encryption
1175                        .encrypt_key(key.as_ref(), self.default_key_nonce_fn())?,
1176                ),
1177            )
1178        }
1179
1180        /// Set a key to a new value
1181        pub fn insert<K, V>(
1182            &self,
1183            key: K,
1184            value: V,
1185        ) -> Result<Option<IVec>, UnabortableTransactionError>
1186        where
1187            K: AsRef<[u8]>,
1188            V: Into<IVec>,
1189        {
1190            let encrypted_key_name = self
1191                .encryption
1192                .encrypt_key(key.as_ref(), self.default_key_nonce_fn())?;
1193            let res = self.encryption.decrypt_value_result(
1194                self.inner
1195                    .insert(&encrypted_key_name, self.encryption.encrypt_value(value)?),
1196            )?;
1197            if self.encryption.applies_to_key() {
1198                let nonce = self
1199                    .encryption
1200                    .get_nonce_from_encrypted(&encrypted_key_name)?;
1201                self.inner.insert(
1202                    key_nonce_key(self.encryption.salt_and_hash(key)).as_slice(),
1203                    nonce,
1204                )?;
1205            }
1206            Ok(res)
1207        }
1208
1209        /// Remove a key
1210        pub fn remove<K: AsRef<[u8]>>(
1211            &self,
1212            key: K,
1213        ) -> Result<Option<IVec>, UnabortableTransactionError> {
1214            let encrypted_key_name = self
1215                .encryption
1216                .encrypt_key(key.as_ref(), self.default_key_nonce_fn())?;
1217            let res = self
1218                .encryption
1219                .decrypt_value_result(self.inner.remove(encrypted_key_name))?;
1220            if self.encryption.applies_to_key() {
1221                self.inner
1222                    .remove(key_nonce_key(self.encryption.salt_and_hash(key)).as_slice())?;
1223            }
1224            Ok(res)
1225        }
1226
1227        /// Atomically apply multiple inserts and removals.
1228        pub fn apply_batch(&self, batch: &Batch) -> Result<(), UnabortableTransactionError> {
1229            for event in batch.events.iter() {
1230                match event {
1231                    Event::Insert { key, value } => {
1232                        self.insert(key, value)?;
1233                    }
1234                    Event::Remove { key } => {
1235                        self.remove(key)?;
1236                    }
1237                }
1238            }
1239            Ok(())
1240        }
1241
1242        /// Flush the database before returning from the transaction.
1243        #[inline]
1244        pub fn flush(&self) {
1245            self.inner.flush()
1246        }
1247
1248        /// Generate a monotonic ID. Not guaranteed to be contiguous or idempotent,
1249        /// can produce different values in the same transaction in case of conflicts.
1250        /// Written to disk every idgen_persist_interval operations, followed by a blocking
1251        /// flush. During recovery, we take the last recovered generated ID and add 2x the
1252        /// idgen_persist_interval to it. While persisting, if the previous persisted counter
1253        /// wasn’t synced to disk yet, we will do a blocking flush to fsync the latest counter,
1254        /// ensuring that we will never give out the same counter twice.
1255        #[inline]
1256        pub fn generate_id(&self) -> Result<u64> {
1257            self.inner.generate_id()
1258        }
1259
1260        fn default_key_nonce_fn(&self) -> DefaultNonceFn<UnabortableTransactionError> {
1261            Box::new(move |data| {
1262                self.inner
1263                    .get(&key_nonce_key(self.encryption.salt_and_hash(data)))
1264            })
1265        }
1266    }
1267}
1268
1269/// Opens a Db with a default configuration at the specified path. This will create a new
1270/// storage directory at the specified path if it does not already exist. You can use the
1271/// Db::was_recovered method to determine if your database was recovered from a previous
1272/// instance. You can use Config::create_new if you want to increase the chances that the
1273/// database will be freshly created.
1274pub fn open<P: AsRef<Path>, E: Encryption>(path: P, encryption: E) -> Result<Db<E>> {
1275    sled::open(path).map(|db| Db::new(db, Arc::new(encryption)))
1276}
1277
1278#[cfg(test)]
1279mod tests {
1280    use super::*;
1281    use chacha20poly1305::ChaCha20Poly1305;
1282
1283    type TestCipher = EncryptionCipher<ChaCha20Poly1305, CountingNonce<ChaCha20Poly1305>>;
1284    type TestDb = Db<TestCipher>;
1285
1286    const ENCRYPTION_KEY: &[u8] = b"an example very very secret key.";
1287
1288    fn test_cipher(mode: EncryptionMode) -> TestCipher {
1289        let mut key = Key::<ChaCha20Poly1305>::default();
1290        key.copy_from_slice(&ENCRYPTION_KEY);
1291        EncryptionCipher::new(
1292            key,
1293            CountingNonce::new(Nonce::<ChaCha20Poly1305>::default()),
1294            mode,
1295        )
1296    }
1297
1298    fn temp_db(mode: EncryptionMode) -> TestDb {
1299        println!("opening test db with: {:?}", mode);
1300        Config::new(test_cipher(mode))
1301            .temporary(true)
1302            .open()
1303            .unwrap()
1304    }
1305
1306    fn for_all_dbs<F>(f: F) -> Result<()>
1307    where
1308        F: Fn(TestDb) -> Result<()>,
1309    {
1310        for mode in &[
1311            EncryptionMode::empty(),
1312            EncryptionMode::KEY,
1313            EncryptionMode::VALUE,
1314            EncryptionMode::TREE_NAME,
1315            EncryptionMode::KEY | EncryptionMode::VALUE,
1316            EncryptionMode::KEY | EncryptionMode::TREE_NAME,
1317            EncryptionMode::VALUE | EncryptionMode::TREE_NAME,
1318            EncryptionMode::KEY | EncryptionMode::VALUE | EncryptionMode::TREE_NAME,
1319        ] {
1320            f(temp_db(*mode))?
1321        }
1322        Ok(())
1323    }
1324
1325    fn for_cleartext_key_dbs<F>(f: F) -> Result<()>
1326    where
1327        F: Fn(TestDb) -> Result<()>,
1328    {
1329        for mode in &[
1330            EncryptionMode::empty(),
1331            EncryptionMode::VALUE,
1332            EncryptionMode::TREE_NAME,
1333            EncryptionMode::VALUE | EncryptionMode::TREE_NAME,
1334        ] {
1335            f(temp_db(*mode))?
1336        }
1337        Ok(())
1338    }
1339
1340    fn str_res(res: Result<Option<IVec>>) -> Result<Option<String>> {
1341        res.map(|val| val.map(|val| String::from_utf8_lossy(&val).to_string()))
1342    }
1343
1344    #[test]
1345    fn insert() -> Result<()> {
1346        for_all_dbs(|db| {
1347            let tree = db.open_tree("hello").unwrap();
1348            assert!(!tree.contains_key("hello").unwrap());
1349            tree.insert("hello", "hi").unwrap();
1350            assert!(tree.contains_key("hello").unwrap());
1351            assert_eq!(Ok(Some("hi".to_string())), str_res(tree.get("hello")));
1352            tree.remove("hello").unwrap();
1353            assert!(!tree.contains_key("hello").unwrap());
1354            assert_eq!(Ok(None), str_res(tree.get("hello")));
1355            Ok(())
1356        })
1357    }
1358
1359    fn u64_to_ivec(number: u64) -> IVec {
1360        IVec::from(number.to_be_bytes().to_vec())
1361    }
1362
1363    fn increment(old: Option<IVec>) -> Option<Vec<u8>> {
1364        let number = match old {
1365            Some(bytes) => {
1366                let mut array = [0; 8];
1367                array.copy_from_slice(&bytes);
1368                let number = u64::from_be_bytes(array);
1369                number + 1
1370            }
1371            None => 0,
1372        };
1373
1374        Some(number.to_be_bytes().to_vec())
1375    }
1376
1377    #[test]
1378    fn update_and_fetch() -> Result<()> {
1379        for_cleartext_key_dbs(|db| {
1380            let zero = u64_to_ivec(0);
1381            let one = u64_to_ivec(1);
1382            let two = u64_to_ivec(2);
1383            let three = u64_to_ivec(3);
1384
1385            assert_eq!(db.update_and_fetch("counter", increment), Ok(Some(zero)));
1386            assert_eq!(db.update_and_fetch("counter", increment), Ok(Some(one)));
1387            assert_eq!(db.update_and_fetch("counter", increment), Ok(Some(two)));
1388            assert_eq!(db.update_and_fetch("counter", increment), Ok(Some(three)));
1389            Ok(())
1390        })
1391    }
1392
1393    #[test]
1394    fn fetch_and_update() -> Result<()> {
1395        for_cleartext_key_dbs(|db| {
1396            let zero = u64_to_ivec(0);
1397            let one = u64_to_ivec(1);
1398            let two = u64_to_ivec(2);
1399
1400            assert_eq!(db.fetch_and_update("counter", increment), Ok(None));
1401            assert_eq!(db.fetch_and_update("counter", increment), Ok(Some(zero)));
1402            assert_eq!(db.fetch_and_update("counter", increment), Ok(Some(one)));
1403            assert_eq!(db.fetch_and_update("counter", increment), Ok(Some(two)));
1404            Ok(())
1405        })
1406    }
1407
1408    #[test]
1409    fn merge() -> Result<()> {
1410        fn concatenate_merge(
1411            _key: &[u8],              // the key being merged
1412            old_value: Option<&[u8]>, // the previous value, if one existed
1413            merged_bytes: &[u8],      // the new bytes being merged in
1414        ) -> Option<Vec<u8>> {
1415            // set the new value, return None to delete
1416            let mut ret = old_value.map(|ov| ov.to_vec()).unwrap_or_else(|| vec![]);
1417
1418            ret.extend_from_slice(merged_bytes);
1419
1420            Some(ret)
1421        }
1422
1423        for_cleartext_key_dbs(|tree| {
1424            tree.set_merge_operator(concatenate_merge);
1425
1426            let k = b"k1";
1427
1428            tree.insert(k, vec![0]).unwrap();
1429            tree.merge(k, vec![1]).unwrap();
1430            tree.merge(k, vec![2]).unwrap();
1431            assert_eq!(tree.get(k), Ok(Some(IVec::from(vec![0, 1, 2]))));
1432
1433            // Replace previously merged data. The merge function will not be called.
1434            tree.insert(k, vec![3]).unwrap();
1435            assert_eq!(tree.get(k), Ok(Some(IVec::from(vec![3]))));
1436
1437            // Merges on non-present values will cause the merge function to be called
1438            // with `old_value == None`. If the merge function returns something (which it
1439            // does, in this case) a new value will be inserted.
1440            tree.remove(k).unwrap();
1441            tree.merge(k, vec![4]).unwrap();
1442            assert_eq!(tree.get(k), Ok(Some(IVec::from(vec![4]))));
1443            Ok(())
1444        })
1445    }
1446
1447    #[test]
1448    fn batch() -> Result<()> {
1449        for_all_dbs(|db| {
1450            let mut batch = Batch::default();
1451            batch.insert("key_a", "val_a");
1452            batch.insert("key_b", "val_b");
1453            batch.insert("key_c", "val_c");
1454            batch.remove("key_0");
1455
1456            db.apply_batch(batch)?;
1457            Ok(())
1458        })
1459    }
1460
1461    #[test]
1462    fn transaction_err() -> Result<()> {
1463        #[derive(Debug, PartialEq)]
1464        struct MyBullshitError;
1465
1466        for_all_dbs(|db| {
1467            // Use write-only transactions as a writebatch:
1468            let res = db
1469                .transaction(|tx_db| {
1470                    tx_db.insert(b"k1", b"cats")?;
1471                    tx_db.insert(b"k2", b"dogs")?;
1472                    // aborting will cause all writes to roll-back.
1473                    if true {
1474                        transaction::abort(MyBullshitError)?;
1475                    }
1476                    Ok(42)
1477                })
1478                .unwrap_err();
1479
1480            assert_eq!(res, transaction::TransactionError::Abort(MyBullshitError));
1481            assert_eq!(db.get(b"k1")?, None);
1482            assert_eq!(db.get(b"k2")?, None);
1483            Ok(())
1484        })
1485    }
1486
1487    #[test]
1488    fn iter() -> Result<()> {
1489        for_all_dbs(|db| {
1490            db.insert(&[1], vec![10])?;
1491            db.insert(&[2], vec![20])?;
1492            db.insert(&[3], vec![30])?;
1493            let mut out = db.iter().collect::<Vec<Result<(IVec, IVec)>>>();
1494            out.sort_by_key(|res| res.clone().unwrap());
1495            assert_eq!(
1496                &out,
1497                &[
1498                    Ok((IVec::from(&[1]), IVec::from(&[10]))),
1499                    Ok((IVec::from(&[2]), IVec::from(&[20]))),
1500                    Ok((IVec::from(&[3]), IVec::from(&[30])))
1501                ]
1502            );
1503            Ok(())
1504        })
1505    }
1506
1507    #[test]
1508    fn subscribe() -> Result<()> {
1509        for_all_dbs(|db| {
1510            let subscriber = db.watch_prefix(vec![])?;
1511
1512            let _ = std::thread::spawn(move || db.insert(vec![0], vec![1]));
1513
1514            for event in subscriber.take(1) {
1515                match event? {
1516                    sled::Event::Insert { key, .. } => assert_eq!(key.as_ref(), &[0]),
1517                    sled::Event::Remove { .. } => {}
1518                }
1519            }
1520            Ok(())
1521        })
1522    }
1523}