Skip to main content

fuel_core_storage/
transactional.rs

1//! The primitives to work with storage in transactional mode.
2
3use crate::{
4    Result as StorageResult,
5    kv_store::{
6        BatchOperations,
7        KeyValueInspect,
8        KeyValueMutate,
9        StorageColumn,
10        Value,
11        WriteOperation,
12    },
13    structured_storage::StructuredStorage,
14};
15use core::borrow::Borrow;
16
17#[cfg(feature = "alloc")]
18use alloc::{
19    boxed::Box,
20    collections::{
21        BTreeMap,
22        btree_map,
23    },
24    vec::Vec,
25};
26use fuel_vm_private::fuel_storage::StorageReadError;
27
28#[cfg(feature = "test-helpers")]
29use crate::{
30    iter::{
31        BoxedIter,
32        IterDirection,
33        IterableStore,
34    },
35    kv_store::{
36        KVItem,
37        KeyItem,
38    },
39};
40
41/// Provides an atomic view of the storage at the latest height at
42/// the moment of view instantiation. All modifications to the storage
43/// after this point will not affect the view.
44pub trait AtomicView: Send + Sync {
45    /// The type of the latest storage view.
46    type LatestView;
47
48    /// Returns current the view of the storage.
49    fn latest_view(&self) -> StorageResult<Self::LatestView>;
50}
51
52/// Provides an atomic view of the storage at the given height.
53/// The view is guaranteed to be unmodifiable for the given height.
54pub trait HistoricalView: AtomicView {
55    /// The type used by the storage to track the commitments at a specific height.
56    type Height;
57    /// The type of the storage view at `Self::Height`.
58    type ViewAtHeight;
59
60    /// Returns the latest height.
61    fn latest_height(&self) -> Option<Self::Height>;
62
63    /// Returns the view of the storage at the given `height`.
64    fn view_at(&self, height: &Self::Height) -> StorageResult<Self::ViewAtHeight>;
65}
66
67/// Storage transaction on top of the storage.
68pub type StorageTransaction<S> = StructuredStorage<InMemoryTransaction<S>>;
69
70/// In memory transaction accumulates `Changes` over the storage.
71#[derive(Default, Debug, Clone)]
72pub struct InMemoryTransaction<S> {
73    pub(crate) changes: Changes,
74    pub(crate) policy: ConflictPolicy,
75    pub(crate) storage: S,
76}
77
78impl<S> StorageTransaction<S> {
79    /// Creates a new instance of the storage transaction.
80    pub fn transaction(storage: S, policy: ConflictPolicy, changes: Changes) -> Self {
81        StructuredStorage::new(InMemoryTransaction {
82            changes,
83            policy,
84            storage,
85        })
86    }
87
88    /// Creates a new instance of the structured storage with a `ConflictPolicy`.
89    pub fn with_policy(self, policy: ConflictPolicy) -> Self {
90        StructuredStorage::new(InMemoryTransaction {
91            changes: self.inner.changes,
92            policy,
93            storage: self.inner.storage,
94        })
95    }
96
97    /// Creates a new instance of the structured storage with a `Changes`.
98    pub fn with_changes(self, changes: Changes) -> Self {
99        StructuredStorage::new(InMemoryTransaction {
100            changes,
101            policy: self.inner.policy,
102            storage: self.inner.storage,
103        })
104    }
105
106    /// Getter to the changes.
107    pub fn changes(&self) -> &Changes {
108        &self.inner.changes
109    }
110
111    /// Returns the changes to the storage.
112    pub fn into_changes(self) -> Changes {
113        self.inner.changes
114    }
115
116    /// Returns the storage and changes to it.
117    pub fn into_inner(self) -> (S, Changes) {
118        let storage = self.inner.storage;
119        let changes = self.inner.changes;
120        (storage, changes)
121    }
122
123    /// Resets the changes to the storage.
124    pub fn reset_changes(&mut self) {
125        self.inner.changes = Default::default();
126    }
127}
128
129/// The policy to resolve the conflict during committing of the changes.
130#[derive(Default, Debug, Clone, Copy, PartialEq, Eq)]
131pub enum ConflictPolicy {
132    /// The transaction will fail if there is a conflict.
133    Fail,
134    /// The transaction will overwrite the conflicting data.
135    #[default]
136    Overwrite,
137}
138
139/// The type is modifiable and may commit the changes into the storage.
140#[impl_tools::autoimpl(for<T: trait> &mut T, Box<T>)]
141pub trait Modifiable {
142    /// Commits the changes into the storage.
143    fn commit_changes(&mut self, changes: Changes) -> StorageResult<()>;
144}
145
146/// The wrapper around the `Vec<u8>` that supports `Borrow<[u8]>`.
147/// It allows the use of bytes slices to do lookups in the collections.
148#[derive(
149    Debug,
150    Clone,
151    PartialEq,
152    Eq,
153    Ord,
154    PartialOrd,
155    Hash,
156    serde::Serialize,
157    serde::Deserialize,
158)]
159pub struct ReferenceBytesKey(Vec<u8>);
160
161impl From<Vec<u8>> for ReferenceBytesKey {
162    fn from(value: Vec<u8>) -> Self {
163        ReferenceBytesKey(value)
164    }
165}
166
167impl From<ReferenceBytesKey> for Vec<u8> {
168    fn from(value: ReferenceBytesKey) -> Self {
169        value.0
170    }
171}
172
173impl Borrow<[u8]> for ReferenceBytesKey {
174    fn borrow(&self) -> &[u8] {
175        self.0.as_slice()
176    }
177}
178
179impl Borrow<Vec<u8>> for ReferenceBytesKey {
180    fn borrow(&self) -> &Vec<u8> {
181        &self.0
182    }
183}
184
185impl AsRef<[u8]> for ReferenceBytesKey {
186    fn as_ref(&self) -> &[u8] {
187        self.0.as_slice()
188    }
189}
190
191impl AsMut<[u8]> for ReferenceBytesKey {
192    fn as_mut(&mut self) -> &mut [u8] {
193        self.0.as_mut_slice()
194    }
195}
196
197impl core::ops::Deref for ReferenceBytesKey {
198    type Target = Vec<u8>;
199
200    fn deref(&self) -> &Self::Target {
201        &self.0
202    }
203}
204
205impl core::ops::DerefMut for ReferenceBytesKey {
206    fn deref_mut(&mut self) -> &mut Self::Target {
207        &mut self.0
208    }
209}
210
211#[cfg(not(feature = "std"))]
212/// The type describing the list of changes to the storage.
213pub type Changes = BTreeMap<u32, BTreeMap<ReferenceBytesKey, WriteOperation>>;
214
215#[cfg(feature = "std")]
216/// The type describing the list of changes to the storage.
217pub type Changes =
218    std::collections::HashMap<u32, BTreeMap<ReferenceBytesKey, WriteOperation>>;
219
220impl<Storage> From<StorageTransaction<Storage>> for Changes {
221    fn from(transaction: StorageTransaction<Storage>) -> Self {
222        transaction.into_changes()
223    }
224}
225
226/// The type describing the list of changes to the storage.
227pub enum StorageChanges {
228    /// A single batch of changes.
229    Changes(Changes),
230    /// A list of changes.
231    ChangesList(Vec<Changes>),
232}
233
234impl Default for StorageChanges {
235    fn default() -> Self {
236        StorageChanges::Changes(Default::default())
237    }
238}
239
240impl From<Changes> for StorageChanges {
241    fn from(value: Changes) -> Self {
242        StorageChanges::Changes(value)
243    }
244}
245
246/// The trait to convert the type into the storage transaction.
247pub trait IntoTransaction: Sized {
248    /// Converts the type into the storage transaction consuming it.
249    fn into_transaction(self) -> StorageTransaction<Self>;
250}
251
252impl<S> IntoTransaction for S
253where
254    S: KeyValueInspect,
255{
256    fn into_transaction(self) -> StorageTransaction<Self> {
257        StorageTransaction::transaction(
258            self,
259            ConflictPolicy::Overwrite,
260            Default::default(),
261        )
262    }
263}
264
265/// Creates a new instance of the storage read transaction.
266pub trait ReadTransaction {
267    /// Returns the read transaction without ability to commit the changes.
268    fn read_transaction(&self) -> StorageTransaction<&Self>;
269}
270
271impl<S> ReadTransaction for S
272where
273    S: KeyValueInspect,
274{
275    fn read_transaction(&self) -> StorageTransaction<&Self> {
276        StorageTransaction::transaction(
277            self,
278            ConflictPolicy::Overwrite,
279            Default::default(),
280        )
281    }
282}
283
284/// Creates a new instance of the storage write transaction.
285pub trait WriteTransaction {
286    /// Returns the write transaction that can commit the changes.
287    fn write_transaction(&mut self) -> StorageTransaction<&mut Self>;
288}
289
290impl<S> WriteTransaction for S {
291    fn write_transaction(&mut self) -> StorageTransaction<&mut Self> {
292        StorageTransaction::transaction(
293            self,
294            ConflictPolicy::Overwrite,
295            Default::default(),
296        )
297    }
298}
299
300impl<Storage> StorageTransaction<Storage>
301where
302    Storage: Modifiable,
303{
304    /// Commits the changes into the storage.
305    pub fn commit(mut self) -> StorageResult<Storage> {
306        let changes = core::mem::take(&mut self.inner.changes);
307        self.inner.storage.commit_changes(changes)?;
308        Ok(self.inner.storage)
309    }
310}
311
312impl<Storage> Modifiable for InMemoryTransaction<Storage> {
313    fn commit_changes(&mut self, changes: Changes) -> StorageResult<()> {
314        #[cfg(not(feature = "std"))]
315        use btree_map::Entry;
316        #[cfg(feature = "std")]
317        use std::collections::hash_map::Entry;
318
319        for (column, value) in changes.into_iter() {
320            let btree = match self.changes.entry(column) {
321                Entry::Vacant(vacant) => {
322                    vacant.insert(value);
323                    continue;
324                }
325                Entry::Occupied(occupied) => occupied.into_mut(),
326            };
327
328            for (k, v) in value {
329                match &self.policy {
330                    ConflictPolicy::Fail => {
331                        let entry = btree.entry(k);
332
333                        match entry {
334                            btree_map::Entry::Occupied(occupied) => {
335                                return Err(anyhow::anyhow!(
336                                    "Conflicting operation {v:?} for the {:?}",
337                                    occupied.key()
338                                )
339                                .into());
340                            }
341                            btree_map::Entry::Vacant(vacant) => {
342                                vacant.insert(v);
343                            }
344                        }
345                    }
346                    ConflictPolicy::Overwrite => {
347                        btree.insert(k, v);
348                    }
349                }
350            }
351        }
352        Ok(())
353    }
354}
355
356impl<Column, S> InMemoryTransaction<S>
357where
358    Column: StorageColumn,
359    S: KeyValueInspect<Column = Column>,
360{
361    fn get_from_changes(&self, key: &[u8], column: Column) -> Option<&WriteOperation> {
362        self.changes
363            .get(&column.id())
364            .and_then(|btree| btree.get(key))
365    }
366}
367
368impl<Column, S> KeyValueInspect for InMemoryTransaction<S>
369where
370    Column: StorageColumn,
371    S: KeyValueInspect<Column = Column>,
372{
373    type Column = Column;
374
375    fn exists(&self, key: &[u8], column: Self::Column) -> StorageResult<bool> {
376        if let Some(operation) = self.get_from_changes(key, column) {
377            match operation {
378                WriteOperation::Insert(_) => Ok(true),
379                WriteOperation::Remove => Ok(false),
380            }
381        } else {
382            self.storage.exists(key, column)
383        }
384    }
385
386    fn size_of_value(
387        &self,
388        key: &[u8],
389        column: Self::Column,
390    ) -> StorageResult<Option<usize>> {
391        if let Some(operation) = self.get_from_changes(key, column) {
392            match operation {
393                WriteOperation::Insert(value) => Ok(Some(value.len())),
394                WriteOperation::Remove => Ok(None),
395            }
396        } else {
397            self.storage.size_of_value(key, column)
398        }
399    }
400
401    fn get(&self, key: &[u8], column: Self::Column) -> StorageResult<Option<Value>> {
402        if let Some(operation) = self.get_from_changes(key, column) {
403            match operation {
404                WriteOperation::Insert(value) => Ok(Some(value.clone())),
405                WriteOperation::Remove => Ok(None),
406            }
407        } else {
408            self.storage.get(key, column)
409        }
410    }
411
412    fn read_exact(
413        &self,
414        key: &[u8],
415        column: Self::Column,
416        offset: usize,
417        buf: &mut [u8],
418    ) -> StorageResult<Result<usize, StorageReadError>> {
419        if let Some(operation) = self.get_from_changes(key, column) {
420            match operation {
421                WriteOperation::Insert(value) => {
422                    let buf_len = buf.len();
423
424                    let Some(data) =
425                        value.as_ref().get(offset..offset.saturating_add(buf_len))
426                    else {
427                        return Ok(Err(StorageReadError::OutOfBounds));
428                    };
429                    buf.copy_from_slice(data);
430
431                    Ok(Ok(buf_len))
432                }
433                WriteOperation::Remove => Ok(Err(StorageReadError::KeyNotFound)),
434            }
435        } else {
436            self.storage.read_exact(key, column, offset, buf)
437        }
438    }
439
440    fn read_zerofill(
441        &self,
442        key: &[u8],
443        column: Self::Column,
444        offset: usize,
445        buf: &mut [u8],
446    ) -> StorageResult<Result<usize, StorageReadError>> {
447        if let Some(operation) = self.get_from_changes(key, column) {
448            match operation {
449                WriteOperation::Insert(value) => {
450                    let bytes_len = value.as_ref().len();
451                    let buf_len = buf.len();
452
453                    let Some((_, after)) = value.as_ref().split_at_checked(offset) else {
454                        return Ok(Err(StorageReadError::OutOfBounds));
455                    };
456
457                    let (dst, rest) = buf.split_at_mut(buf_len.min(after.len()));
458                    dst.copy_from_slice(&after[..dst.len()]);
459                    rest.fill(0);
460
461                    Ok(Ok(bytes_len))
462                }
463                WriteOperation::Remove => Ok(Err(StorageReadError::KeyNotFound)),
464            }
465        } else {
466            self.storage.read_zerofill(key, column, offset, buf)
467        }
468    }
469}
470
471impl<Column, S> KeyValueMutate for InMemoryTransaction<S>
472where
473    Column: StorageColumn,
474    S: KeyValueInspect<Column = Column>,
475{
476    fn put(
477        &mut self,
478        key: &[u8],
479        column: Self::Column,
480        value: Value,
481    ) -> StorageResult<()> {
482        let k = key.to_vec().into();
483        self.changes
484            .entry(column.id())
485            .or_default()
486            .insert(k, WriteOperation::Insert(value));
487        Ok(())
488    }
489
490    fn replace(
491        &mut self,
492        key: &[u8],
493        column: Self::Column,
494        value: Value,
495    ) -> StorageResult<Option<Value>> {
496        let k = key.to_vec().into();
497        let entry = self.changes.entry(column.id()).or_default().entry(k);
498
499        match entry {
500            btree_map::Entry::Occupied(mut occupied) => {
501                let old = occupied.insert(WriteOperation::Insert(value));
502
503                match old {
504                    WriteOperation::Insert(value) => Ok(Some(value)),
505                    WriteOperation::Remove => Ok(None),
506                }
507            }
508            btree_map::Entry::Vacant(vacant) => {
509                vacant.insert(WriteOperation::Insert(value));
510                self.storage.get(key, column)
511            }
512        }
513    }
514
515    fn write(
516        &mut self,
517        key: &[u8],
518        column: Self::Column,
519        buf: &[u8],
520    ) -> StorageResult<usize> {
521        let k = key.to_vec().into();
522        self.changes
523            .entry(column.id())
524            .or_default()
525            .insert(k, WriteOperation::Insert(Value::from(buf)));
526        Ok(buf.len())
527    }
528
529    fn take(&mut self, key: &[u8], column: Self::Column) -> StorageResult<Option<Value>> {
530        let k = key.to_vec().into();
531        let entry = self.changes.entry(column.id()).or_default().entry(k);
532
533        match entry {
534            btree_map::Entry::Occupied(mut occupied) => {
535                let old = occupied.insert(WriteOperation::Remove);
536
537                match old {
538                    WriteOperation::Insert(value) => Ok(Some(value)),
539                    WriteOperation::Remove => Ok(None),
540                }
541            }
542            btree_map::Entry::Vacant(vacant) => {
543                vacant.insert(WriteOperation::Remove);
544                self.storage.get(key, column)
545            }
546        }
547    }
548
549    fn delete(&mut self, key: &[u8], column: Self::Column) -> StorageResult<()> {
550        let k = key.to_vec().into();
551        self.changes
552            .entry(column.id())
553            .or_default()
554            .insert(k, WriteOperation::Remove);
555        Ok(())
556    }
557}
558
559impl<Column, S> BatchOperations for InMemoryTransaction<S>
560where
561    Column: StorageColumn,
562    S: KeyValueInspect<Column = Column>,
563{
564    fn batch_write<I>(&mut self, column: Column, entries: I) -> StorageResult<()>
565    where
566        I: Iterator<Item = (Vec<u8>, WriteOperation)>,
567    {
568        let btree = self.changes.entry(column.id()).or_default();
569        entries.for_each(|(key, operation)| {
570            btree.insert(key.into(), operation);
571        });
572        Ok(())
573    }
574}
575
576// The `IterableStore` should only be implemented for the actual storage,
577// not the storage transaction, to maximize the performance.
578//
579// Another reason is that only actual storage with finalized updates should be
580// used to iterate over its entries to avoid inconsistent results.
581//
582// We implement `IterableStore` for `StorageTransactionInner` only to allow
583// using it in the tests and benchmarks as a type(not even implementation of it).
584#[cfg(feature = "test-helpers")]
585impl<S> IterableStore for InMemoryTransaction<S>
586where
587    S: IterableStore,
588{
589    fn iter_store(
590        &self,
591        _: Self::Column,
592        _: Option<&[u8]>,
593        _: Option<&[u8]>,
594        _: IterDirection,
595    ) -> BoxedIter<'_, KVItem> {
596        unimplemented!()
597    }
598
599    fn iter_store_keys(
600        &self,
601        _: Self::Column,
602        _: Option<&[u8]>,
603        _: Option<&[u8]>,
604        _: IterDirection,
605    ) -> BoxedIter<'_, KeyItem> {
606        unimplemented!()
607    }
608}
609
610#[cfg(feature = "test-helpers")]
611mod test {
612    use super::*;
613    use crate::structured_storage::test::InMemoryStorage;
614    #[cfg(test)]
615    use crate::{
616        StorageAsMut,
617        tables::Messages,
618    };
619
620    impl<Column> Modifiable for InMemoryStorage<Column> {
621        fn commit_changes(&mut self, changes: Changes) -> StorageResult<()> {
622            for (column, value) in changes.into_iter() {
623                for (key, value) in value {
624                    match value {
625                        WriteOperation::Insert(value) => {
626                            self.storage.insert((column, key.into()), value);
627                        }
628                        WriteOperation::Remove => {
629                            self.storage.remove(&(column, key.into()));
630                        }
631                    }
632                }
633            }
634            Ok(())
635        }
636    }
637
638    #[test]
639    fn committing_changes_modifies_underlying_storage() {
640        let mut storage = InMemoryStorage::default();
641        let mut transaction = storage.write_transaction();
642
643        let mut sub_transaction = transaction.write_transaction();
644
645        sub_transaction
646            .storage_as_mut::<Messages>()
647            .insert(&Default::default(), &Default::default())
648            .expect("Should work");
649
650        sub_transaction.commit().unwrap();
651        transaction.commit().unwrap();
652        assert_eq!(storage.storage().len(), 1);
653    }
654
655    #[test]
656    fn committing_changes_from_concurrent_independent_transactions_works() {
657        let storage = InMemoryStorage::default();
658        let mut transactions =
659            storage.into_transaction().with_policy(ConflictPolicy::Fail);
660
661        let mut sub_transaction1 = transactions.read_transaction();
662        let mut sub_transaction2 = transactions.read_transaction();
663
664        sub_transaction1
665            .storage_as_mut::<Messages>()
666            .insert(&[0u8; 32].into(), &Default::default())
667            .expect("Should work");
668        sub_transaction2
669            .storage_as_mut::<Messages>()
670            .insert(&[1u8; 32].into(), &Default::default())
671            .expect("Should work");
672
673        let changes1 = sub_transaction1.into();
674        let changes2 = sub_transaction2.into();
675        transactions.commit_changes(changes1).unwrap();
676        transactions.commit_changes(changes2).unwrap();
677    }
678
679    #[test]
680    fn committing_changes_from_concurrent_overlapping_transactions_fails() {
681        let storage = InMemoryStorage::default();
682        let mut transactions =
683            storage.into_transaction().with_policy(ConflictPolicy::Fail);
684
685        let mut sub_transaction1 = transactions.read_transaction();
686        let mut sub_transaction2 = transactions.read_transaction();
687
688        sub_transaction1
689            .storage_as_mut::<Messages>()
690            .insert(&[0u8; 32].into(), &Default::default())
691            .expect("Should work");
692        sub_transaction2
693            .storage_as_mut::<Messages>()
694            .insert(&[0u8; 32].into(), &Default::default())
695            .expect("Should work");
696
697        let changes1 = sub_transaction1.into();
698        let changes2 = sub_transaction2.into();
699        transactions.commit_changes(changes1).unwrap();
700        transactions
701            .commit_changes(changes2)
702            .expect_err("Should fails because of the modification for the same key");
703    }
704
705    #[cfg(test)]
706    mod key_value_functionality {
707        use super::*;
708        use crate::column::Column;
709
710        #[test]
711        fn read_returns_from_view_exact_size() {
712            // setup
713            let storage = InMemoryStorage::<Column>::default();
714            let mut view = storage.read_transaction();
715            let key = vec![0xA, 0xB, 0xC];
716            let value = Value::from([1, 2, 3]);
717            view.put(&key, Column::Metadata, value).unwrap();
718            // test
719            let mut buf = [0; 3];
720            let ret = view
721                .read_exact(&key, Column::Metadata, 0, &mut buf)
722                .unwrap();
723            // verify
724            assert_eq!(ret, Ok(3));
725            assert_eq!(buf, [1, 2, 3]);
726        }
727
728        #[test]
729        fn read_returns_from_view_buf_smaller() {
730            // setup
731            let storage = InMemoryStorage::<Column>::default();
732            let mut view = storage.read_transaction();
733            let key = vec![0xA, 0xB, 0xC];
734            let value = Value::from([1, 2, 3]);
735            view.put(&key, Column::Metadata, value).unwrap();
736            // test
737            let mut buf = [0; 2];
738            let ret = view
739                .read_exact(&key, Column::Metadata, 0, &mut buf)
740                .unwrap();
741            // verify
742            assert_eq!(ret, Ok(2));
743            assert_eq!(buf, [1, 2]);
744        }
745
746        #[test]
747        fn read_returns_from_view_with_offset() {
748            // setup
749            let storage = InMemoryStorage::<Column>::default();
750            let mut view = storage.read_transaction();
751            let key = vec![0xA, 0xB, 0xC];
752            let value = Value::from([1, 2, 3]);
753            view.put(&key, Column::Metadata, value).unwrap();
754            // test
755            let mut buf = [0; 2];
756            let ret = view
757                .read_exact(&key, Column::Metadata, 1, &mut buf)
758                .unwrap();
759            // verify
760            assert_eq!(ret, Ok(2));
761            assert_eq!(buf, [2, 3]);
762        }
763
764        #[test]
765        fn read_returns_from_view_buf_bigger() {
766            // setup
767            let storage = InMemoryStorage::<Column>::default();
768            let mut view = storage.read_transaction();
769            let key = vec![0xA, 0xB, 0xC];
770            let value = Value::from([1, 2, 3]);
771            view.put(&key, Column::Metadata, value).unwrap();
772            // test
773            let mut buf = [0; 4];
774            let ret = view.read_exact(&key, Column::Metadata, 0, &mut buf);
775            // verify
776            assert_eq!(ret, Ok(Err(StorageReadError::OutOfBounds)));
777        }
778
779        #[test]
780        fn read_returns_from_view_buf_bigger_because_offset() {
781            // setup
782            let storage = InMemoryStorage::<Column>::default();
783            let mut view = storage.read_transaction();
784            let key = vec![0xA, 0xB, 0xC];
785            let value = Value::from([1, 2, 3]);
786            view.put(&key, Column::Metadata, value).unwrap();
787            // test
788            let mut buf = [0; 3];
789            let ret = view.read_exact(&key, Column::Metadata, 1, &mut buf);
790            // verify
791            assert_eq!(ret, Ok(Err(StorageReadError::OutOfBounds)));
792        }
793
794        #[test]
795        fn get_returns_from_view() {
796            // setup
797            let storage = InMemoryStorage::<Column>::default();
798            let mut view = storage.read_transaction();
799            let key = vec![0xA, 0xB, 0xC];
800            let expected = Value::from([1, 2, 3]);
801            view.put(&key, Column::Metadata, expected.clone()).unwrap();
802            // test
803            let ret = view.get(&key, Column::Metadata).unwrap();
804            // verify
805            assert_eq!(ret, Some(expected))
806        }
807
808        #[test]
809        fn get_returns_from_data_store_when_key_not_in_view() {
810            // setup
811            let mut storage = InMemoryStorage::<Column>::default();
812            let mut write = storage.write_transaction();
813            let key = vec![0xA, 0xB, 0xC];
814            let expected = Value::from([1, 2, 3]);
815            write.put(&key, Column::Metadata, expected.clone()).unwrap();
816            write.commit().unwrap();
817
818            let view = storage.read_transaction();
819            // test
820            let ret = view.get(&key, Column::Metadata).unwrap();
821            // verify
822            assert_eq!(ret, Some(expected))
823        }
824
825        #[test]
826        fn get_does_not_fetch_from_datastore_if_intentionally_deleted_from_view() {
827            // setup
828            let mut storage = InMemoryStorage::<Column>::default();
829            let mut write = storage.write_transaction();
830            let key = vec![0xA, 0xB, 0xC];
831            let expected = Value::from([1, 2, 3]);
832            write.put(&key, Column::Metadata, expected.clone()).unwrap();
833            write.commit().unwrap();
834
835            let mut view = storage.read_transaction();
836            view.delete(&key, Column::Metadata).unwrap();
837            // test
838            let ret = view.get(&key, Column::Metadata).unwrap();
839            let original = storage.get(&key, Column::Metadata).unwrap();
840            // verify
841            assert_eq!(ret, None);
842            // also ensure the original value is still intact and we aren't just passing
843            // through None from the data store
844            assert_eq!(original, Some(expected))
845        }
846
847        #[test]
848        fn can_insert_value_into_view() {
849            // setup
850            let mut storage = InMemoryStorage::<Column>::default();
851            let mut write = storage.write_transaction();
852            let expected = Value::from([1, 2, 3]);
853            write
854                .put(&[0xA, 0xB, 0xC], Column::Metadata, expected.clone())
855                .unwrap();
856            // test
857            let ret = write
858                .replace(&[0xA, 0xB, 0xC], Column::Metadata, Value::from([2, 4, 6]))
859                .unwrap();
860            // verify
861            assert_eq!(ret, Some(expected))
862        }
863
864        #[test]
865        fn delete_value_from_view_returns_value() {
866            // setup
867            let mut storage = InMemoryStorage::<Column>::default();
868            let mut write = storage.write_transaction();
869            let key = vec![0xA, 0xB, 0xC];
870            let expected = Value::from([1, 2, 3]);
871            write.put(&key, Column::Metadata, expected.clone()).unwrap();
872            // test
873            let ret = write.take(&key, Column::Metadata).unwrap();
874            let get = write.get(&key, Column::Metadata).unwrap();
875            // verify
876            assert_eq!(ret, Some(expected));
877            assert_eq!(get, None)
878        }
879
880        #[test]
881        fn delete_returns_datastore_value_when_not_in_view() {
882            // setup
883            let mut storage = InMemoryStorage::<Column>::default();
884            let mut write = storage.write_transaction();
885            let key = vec![0xA, 0xB, 0xC];
886            let expected = Value::from([1, 2, 3]);
887            write.put(&key, Column::Metadata, expected.clone()).unwrap();
888            write.commit().unwrap();
889
890            let mut view = storage.read_transaction();
891            // test
892            let ret = view.take(&key, Column::Metadata).unwrap();
893            let get = view.get(&key, Column::Metadata).unwrap();
894            // verify
895            assert_eq!(ret, Some(expected));
896            assert_eq!(get, None)
897        }
898
899        #[test]
900        fn delete_does_not_return_datastore_value_when_deleted_twice() {
901            // setup
902            let mut storage = InMemoryStorage::<Column>::default();
903            let mut write = storage.write_transaction();
904            let key = vec![0xA, 0xB, 0xC];
905            let expected = Value::from([1, 2, 3]);
906            write.put(&key, Column::Metadata, expected.clone()).unwrap();
907            write.commit().unwrap();
908
909            let mut view = storage.read_transaction();
910            // test
911            let ret1 = view.take(&key, Column::Metadata).unwrap();
912            let ret2 = view.take(&key, Column::Metadata).unwrap();
913            let get = view.get(&key, Column::Metadata).unwrap();
914            // verify
915            assert_eq!(ret1, Some(expected));
916            assert_eq!(ret2, None);
917            assert_eq!(get, None)
918        }
919
920        #[test]
921        fn exists_checks_view_values() {
922            // setup
923            let mut storage = InMemoryStorage::<Column>::default();
924            let mut write = storage.write_transaction();
925            let key = vec![0xA, 0xB, 0xC];
926            let expected = Value::from([1, 2, 3]);
927            write.put(&key, Column::Metadata, expected).unwrap();
928            // test
929            let ret = write.exists(&key, Column::Metadata).unwrap();
930            // verify
931            assert!(ret)
932        }
933
934        #[test]
935        fn exists_checks_data_store_when_not_in_view() {
936            // setup
937            let mut storage = InMemoryStorage::<Column>::default();
938            let mut write = storage.write_transaction();
939            let key = vec![0xA, 0xB, 0xC];
940            let expected = Value::from([1, 2, 3]);
941            write.put(&key, Column::Metadata, expected).unwrap();
942            write.commit().unwrap();
943
944            let view = storage.read_transaction();
945            // test
946            let ret = view.exists(&key, Column::Metadata).unwrap();
947            // verify
948            assert!(ret)
949        }
950
951        #[test]
952        fn exists_does_not_check_data_store_after_intentional_removal_from_view() {
953            // setup
954            let mut storage = InMemoryStorage::<Column>::default();
955            let mut write = storage.write_transaction();
956            let key = vec![0xA, 0xB, 0xC];
957            let expected = Value::from([1, 2, 3]);
958            write.put(&key, Column::Metadata, expected).unwrap();
959            write.commit().unwrap();
960
961            let mut view = storage.read_transaction();
962            view.delete(&key, Column::Metadata).unwrap();
963            // test
964            let ret = view.exists(&key, Column::Metadata).unwrap();
965            let original = storage.exists(&key, Column::Metadata).unwrap();
966            // verify
967            assert!(!ret);
968            // also ensure the original value is still intact and we aren't just passing
969            // through None from the data store
970            assert!(original)
971        }
972
973        #[test]
974        fn commit_applies_puts() {
975            // setup
976            let mut storage = InMemoryStorage::<Column>::default();
977            let mut write = storage.write_transaction();
978            let key = vec![0xA, 0xB, 0xC];
979            let expected = Value::from([1, 2, 3]);
980            write.put(&key, Column::Metadata, expected.clone()).unwrap();
981            // test
982            write.commit().unwrap();
983            let ret = storage.get(&key, Column::Metadata).unwrap();
984            // verify
985            assert_eq!(ret, Some(expected))
986        }
987
988        #[test]
989        fn commit_applies_deletes() {
990            // setup
991            let mut storage = InMemoryStorage::<Column>::default();
992            let mut write = storage.write_transaction();
993            let key = vec![0xA, 0xB, 0xC];
994            let expected = Value::from([1, 2, 3]);
995            write.put(&key, Column::Metadata, expected).unwrap();
996            write.commit().unwrap();
997
998            let mut view = storage.write_transaction();
999            // test
1000            view.delete(&key, Column::Metadata).unwrap();
1001            view.commit().unwrap();
1002            let ret = storage.get(&key, Column::Metadata).unwrap();
1003            // verify
1004            assert_eq!(ret, None)
1005        }
1006
1007        #[test]
1008        fn can_use_unit_value() {
1009            let key = vec![0x00];
1010
1011            let mut storage = InMemoryStorage::<Column>::default();
1012            let mut write = storage.write_transaction();
1013            let expected = Value::from([]);
1014            write.put(&key, Column::Metadata, expected.clone()).unwrap();
1015
1016            assert_eq!(
1017                write.get(&key, Column::Metadata).unwrap().unwrap(),
1018                expected
1019            );
1020
1021            assert!(write.exists(&key, Column::Metadata).unwrap());
1022
1023            assert_eq!(
1024                write.take(&key, Column::Metadata).unwrap().unwrap(),
1025                expected
1026            );
1027
1028            assert!(!write.exists(&key, Column::Metadata).unwrap());
1029
1030            write.commit().unwrap();
1031
1032            assert!(!storage.exists(&key, Column::Metadata).unwrap());
1033
1034            let mut storage = InMemoryStorage::<Column>::default();
1035            let mut write = storage.write_transaction();
1036            write.put(&key, Column::Metadata, expected.clone()).unwrap();
1037            write.commit().unwrap();
1038
1039            assert_eq!(
1040                storage.get(&key, Column::Metadata).unwrap().unwrap(),
1041                expected
1042            );
1043        }
1044
1045        #[test]
1046        fn can_use_unit_key() {
1047            let key: Vec<u8> = Vec::with_capacity(0);
1048
1049            let mut storage = InMemoryStorage::<Column>::default();
1050            let mut write = storage.write_transaction();
1051            let expected = Value::from([]);
1052            write.put(&key, Column::Metadata, expected.clone()).unwrap();
1053
1054            assert_eq!(
1055                write.get(&key, Column::Metadata).unwrap().unwrap(),
1056                expected
1057            );
1058
1059            assert!(write.exists(&key, Column::Metadata).unwrap());
1060
1061            assert_eq!(
1062                write.take(&key, Column::Metadata).unwrap().unwrap(),
1063                expected
1064            );
1065
1066            assert!(!write.exists(&key, Column::Metadata).unwrap());
1067
1068            write.commit().unwrap();
1069
1070            assert!(!storage.exists(&key, Column::Metadata).unwrap());
1071
1072            let mut storage = InMemoryStorage::<Column>::default();
1073            let mut write = storage.write_transaction();
1074            write.put(&key, Column::Metadata, expected.clone()).unwrap();
1075            write.commit().unwrap();
1076
1077            assert_eq!(
1078                storage.get(&key, Column::Metadata).unwrap().unwrap(),
1079                expected
1080            );
1081        }
1082
1083        #[test]
1084        fn can_use_unit_key_and_value() {
1085            let key: Vec<u8> = Vec::with_capacity(0);
1086
1087            let mut storage = InMemoryStorage::<Column>::default();
1088            let mut write = storage.write_transaction();
1089            let expected = Value::from([]);
1090            write.put(&key, Column::Metadata, expected.clone()).unwrap();
1091
1092            assert_eq!(
1093                write.get(&key, Column::Metadata).unwrap().unwrap(),
1094                expected
1095            );
1096
1097            assert!(write.exists(&key, Column::Metadata).unwrap());
1098
1099            assert_eq!(
1100                write.take(&key, Column::Metadata).unwrap().unwrap(),
1101                expected
1102            );
1103
1104            assert!(!write.exists(&key, Column::Metadata).unwrap());
1105
1106            write.commit().unwrap();
1107
1108            assert!(!storage.exists(&key, Column::Metadata).unwrap());
1109
1110            let mut storage = InMemoryStorage::<Column>::default();
1111            let mut write = storage.write_transaction();
1112            write.put(&key, Column::Metadata, expected.clone()).unwrap();
1113            write.commit().unwrap();
1114
1115            assert_eq!(
1116                storage.get(&key, Column::Metadata).unwrap().unwrap(),
1117                expected
1118            );
1119        }
1120    }
1121}