commonware_storage/qmdb/current/ordered/
fixed.rs1pub use super::db::KeyValueProof;
11use crate::{
12 index::ordered::Index,
13 journal::contiguous::fixed::Journal,
14 merkle::{Graftable, Location},
15 qmdb::{
16 any::{ordered::fixed::Operation, value::FixedEncoding, FixedValue},
17 current::FixedConfig as Config,
18 Error,
19 },
20 translator::Translator,
21 Context,
22};
23use commonware_cryptography::Hasher;
24use commonware_parallel::Strategy;
25use commonware_utils::Array;
26
27pub type Db<F, E, K, V, H, T, const N: usize, S> = super::db::Db<
28 F,
29 E,
30 Journal<E, Operation<F, K, V>>,
31 K,
32 FixedEncoding<V>,
33 Index<T, Location<F>>,
34 H,
35 N,
36 S,
37>;
38
39impl<
40 F: Graftable,
41 E: Context,
42 K: Array,
43 V: FixedValue,
44 H: Hasher,
45 T: Translator,
46 const N: usize,
47 S: Strategy,
48 > Db<F, E, K, V, H, T, N, S>
49{
50 pub async fn init(context: E, config: Config<T, S>) -> Result<Self, Error<F>> {
53 crate::qmdb::current::init(context, config).await
54 }
55}
56
57pub mod partitioned {
58 use super::*;
61 use crate::index::partitioned::ordered::Index;
62
63 pub type Db<F, E, K, V, H, T, const P: usize, const N: usize, S> =
70 crate::qmdb::current::ordered::db::Db<
71 F,
72 E,
73 Journal<E, Operation<F, K, V>>,
74 K,
75 FixedEncoding<V>,
76 Index<T, Location<F>, P>,
77 H,
78 N,
79 S,
80 >;
81
82 impl<
83 F: Graftable,
84 E: Context,
85 K: Array,
86 V: FixedValue,
87 H: Hasher,
88 T: Translator,
89 const P: usize,
90 const N: usize,
91 S: Strategy,
92 > Db<F, E, K, V, H, T, P, N, S>
93 {
94 pub async fn init(context: E, config: Config<T, S>) -> Result<Self, Error<F>> {
97 crate::qmdb::current::init(context, config).await
98 }
99 }
100}
101
102#[cfg(test)]
103pub mod test {
104 use super::*;
105 use crate::{
106 mmr,
107 qmdb::{
108 current::{ordered::tests as shared, tests::fixed_config},
109 Error,
110 },
111 translator::OneCap,
112 };
113 use commonware_cryptography::{sha256::Digest, Sha256};
114 use commonware_macros::test_traced;
115 use commonware_runtime::{deterministic, Runner as _, Supervisor as _};
116 use commonware_utils::{
117 bitmap::{Prunable as BitMap, Readable as _},
118 NZU64,
119 };
120
121 type CurrentTest = Db<
123 mmr::Family,
124 deterministic::Context,
125 Digest,
126 Digest,
127 Sha256,
128 OneCap,
129 32,
130 commonware_parallel::Sequential,
131 >;
132
133 async fn open_db(context: deterministic::Context, partition_prefix: String) -> CurrentTest {
135 let cfg = fixed_config::<OneCap>(&partition_prefix, &context);
136 CurrentTest::init(context, cfg).await.unwrap()
137 }
138
139 #[test_traced("DEBUG")]
140 pub fn test_current_db_verify_proof_over_bits_in_uncommitted_chunk() {
141 shared::test_verify_proof_over_bits_in_uncommitted_chunk(open_db);
142 }
143
144 #[test_traced("DEBUG")]
145 pub fn test_current_db_range_proofs() {
146 shared::test_range_proofs(open_db);
147 }
148
149 #[test_traced("DEBUG")]
152 pub fn test_range_proof_returns_error_on_pruned_chunks() {
153 let executor = deterministic::Runner::default();
154 executor.start(|context| async move {
155 let partition = "range-proofs-pruned".to_string();
156 let hasher = crate::qmdb::hasher::<Sha256>();
157 let mut db = open_db(context.child("db"), partition).await;
158
159 let chunk_bits = BitMap::<32>::CHUNK_SIZE_BITS;
160
161 let key = Sha256::fill(0x11);
164 for i in 0..chunk_bits + 10 {
165 let value = Sha256::hash(&i.to_be_bytes());
166 let merkleized = db
167 .new_batch()
168 .write(key, Some(value))
169 .merkleize(&db, None)
170 .await
171 .unwrap();
172 db.apply_batch(merkleized).await.unwrap();
173 }
174
175 db.prune(db.sync_boundary()).await.unwrap();
177
178 assert!(
179 db.any.bitmap.pruned_chunks() > 0,
180 "expected at least one pruned chunk"
181 );
182
183 let result = db.range_proof(&hasher, Location::new(0), NZU64!(1)).await;
186 assert!(
187 matches!(result, Err(Error::OperationPruned(_))),
188 "expected OperationPruned, got {result:?}"
189 );
190
191 db.destroy().await.unwrap();
192 });
193 }
194
195 #[test_traced("DEBUG")]
196 pub fn test_current_db_key_value_proof() {
197 shared::test_key_value_proof(open_db);
198 }
199
200 #[test_traced("WARN")]
201 pub fn test_current_db_proving_repeated_updates() {
202 shared::test_proving_repeated_updates(open_db);
203 }
204
205 #[test_traced("DEBUG")]
206 pub fn test_current_db_exclusion_proofs() {
207 shared::test_exclusion_proofs(open_db);
208 }
209}