commonware_storage/qmdb/current/ordered/
mod.rs1use crate::qmdb::{
12 any::{ordered::Update, ValueEncoding},
13 current::proof::OperationProof,
14 operation::Key,
15};
16use commonware_cryptography::Digest;
17
18pub mod db;
19pub mod fixed;
20#[cfg(any(test, feature = "test-traits"))]
21mod test_trait_impls;
22pub mod variable;
23
24#[cfg(test)]
25pub mod tests {
26 use crate::{
29 mmr::Location,
30 qmdb::{
31 any::traits::{DbAny, MerkleizedBatch as _, UnmerkleizedBatch as _},
32 current::BitmapPrunedBits,
33 store::{
34 tests::{TestKey, TestValue},
35 LogStore,
36 },
37 },
38 };
39 use commonware_runtime::{
40 deterministic::{self, Context},
41 Metrics as _, Runner as _,
42 };
43 use core::future::Future;
44
45 pub fn test_build_small_close_reopen<C, F, Fut>(mut open_db: F)
50 where
51 C: DbAny + BitmapPrunedBits,
52 C::Key: TestKey,
53 <C as LogStore>::Value: TestValue,
54 F: FnMut(Context, String) -> Fut,
55 Fut: Future<Output = C>,
56 {
57 let executor = deterministic::Runner::default();
58 executor.start(|context| async move {
59 let partition = "build-small".to_string();
60 let db: C = open_db(context.with_label("first"), partition.clone()).await;
61 assert_eq!(db.inactivity_floor_loc().await, Location::new(0));
62 assert_eq!(db.oldest_retained().await, 0);
63 let root0 = db.root();
64 drop(db);
65 let mut db: C = open_db(context.with_label("second"), partition.clone()).await;
66 assert!(db.get_metadata().await.unwrap().is_none());
67 assert_eq!(db.root(), root0);
68
69 let k1: C::Key = TestKey::from_seed(0);
71 let v1: <C as LogStore>::Value = TestValue::from_seed(10);
72 assert!(db.get(&k1).await.unwrap().is_none());
73 let finalized = {
74 let mut batch = db.new_batch();
75 batch.write(k1, Some(v1.clone()));
76 batch.merkleize(None).await.unwrap().finalize()
77 };
78 db.apply_batch(finalized).await.unwrap();
79 assert_eq!(db.get(&k1).await.unwrap().unwrap(), v1);
80 assert!(db.get_metadata().await.unwrap().is_none());
81 let root1 = db.root();
82 assert_ne!(root1, root0);
83
84 drop(db);
85 let mut db: C = open_db(context.with_label("third"), partition.clone()).await;
86 assert_eq!(db.root(), root1);
87
88 assert!(db.get(&k1).await.unwrap().is_some());
90
91 assert!(db.get(&k1).await.unwrap().is_some());
93 let metadata: <C as LogStore>::Value = TestValue::from_seed(1);
94 let finalized = {
95 let mut batch = db.new_batch();
96 batch.write(k1, None);
97 batch
98 .merkleize(Some(metadata.clone()))
99 .await
100 .unwrap()
101 .finalize()
102 };
103 db.apply_batch(finalized).await.unwrap();
104 assert_eq!(db.get_metadata().await.unwrap().unwrap(), metadata);
105 let root2 = db.root();
106
107 drop(db);
108 let mut db: C = open_db(context.with_label("fourth"), partition.clone()).await;
109 assert_eq!(db.get_metadata().await.unwrap().unwrap(), metadata);
110 assert_eq!(db.root(), root2);
111
112 assert!(db.get(&k1).await.unwrap().is_none());
114 let finalized = db.new_batch().merkleize(None).await.unwrap().finalize();
115 db.apply_batch(finalized).await.unwrap();
116 let root3 = db.root();
117 assert_ne!(root3, root2);
118
119 let bounds = db.bounds().await;
121 for i in 0..*bounds.end - 1 {
122 assert!(!db.get_bit(i));
123 }
124 assert!(db.get_bit(*bounds.end - 1));
125
126 let finalized = {
128 let mut batch = db.new_batch();
129 batch.write(k1, Some(v1));
130 batch.merkleize(None).await.unwrap().finalize()
131 };
132 db.apply_batch(finalized).await.unwrap();
133 assert_ne!(db.root(), root3);
134
135 db.destroy().await.unwrap();
136 });
137 }
138}
139
140#[derive(Clone, Eq, PartialEq, Debug)]
148pub enum ExclusionProof<K: Key, V: ValueEncoding, D: Digest, const N: usize> {
149 KeyValue(OperationProof<D, N>, Update<K, V>),
152
153 Commit(OperationProof<D, N>, Option<V::Value>),
158}