commonware_storage/qmdb/keyless/
fixed.rs1use crate::{
6 journal::{
7 authenticated,
8 contiguous::fixed::{self, Config as JournalConfig},
9 },
10 merkle::Family,
11 qmdb::{
12 any::value::{FixedEncoding, FixedValue},
13 keyless::operation::Operation as BaseOperation,
14 operation::Committable,
15 Error,
16 },
17};
18use commonware_cryptography::Hasher;
19use commonware_runtime::{Clock, Metrics, Storage};
20
21pub type Operation<V> = BaseOperation<FixedEncoding<V>>;
23
24pub type Db<F, E, V, H> =
26 super::Keyless<F, E, FixedEncoding<V>, fixed::Journal<E, Operation<V>>, H>;
27
28type Journal<F, E, V, H> = authenticated::Journal<F, E, fixed::Journal<E, Operation<V>>, H>;
29
30pub type Config = super::Config<JournalConfig>;
32
33impl<F: Family, E: Storage + Clock + Metrics, V: FixedValue, H: Hasher> Db<F, E, V, H> {
34 pub async fn init(context: E, cfg: Config) -> Result<Self, Error<F>> {
37 let journal: Journal<F, E, V, H> =
38 Journal::new(context, cfg.merkle, cfg.log, Operation::<V>::is_commit).await?;
39 Self::init_from_journal(journal).await
40 }
41}
42
43#[cfg(test)]
44mod test {
45 use super::*;
46 use crate::{
47 merkle::{mmb, mmr},
48 qmdb::keyless::tests,
49 };
50 use commonware_cryptography::Sha256;
51 use commonware_macros::test_traced;
52 use commonware_runtime::{
53 buffer::paged::CacheRef, deterministic, BufferPooler, Metrics, Runner as _,
54 };
55 use commonware_utils::{NZUsize, NZU16, NZU64};
56 use std::num::{NonZeroU16, NonZeroUsize};
57
58 const PAGE_SIZE: NonZeroU16 = NZU16!(101);
59 const PAGE_CACHE_SIZE: NonZeroUsize = NZUsize!(11);
60
61 fn db_config(suffix: &str, pooler: &impl BufferPooler) -> Config {
62 let page_cache = CacheRef::from_pooler(pooler, PAGE_SIZE, PAGE_CACHE_SIZE);
63 Config {
64 merkle: crate::merkle::journaled::Config {
65 journal_partition: format!("fixed-journal-{suffix}"),
66 metadata_partition: format!("fixed-metadata-{suffix}"),
67 items_per_blob: NZU64!(11),
68 write_buffer: NZUsize!(1024),
69 thread_pool: None,
70 page_cache: page_cache.clone(),
71 },
72 log: JournalConfig {
73 partition: format!("fixed-log-journal-{suffix}"),
74 items_per_blob: NZU64!(7),
75 page_cache,
76 write_buffer: NZUsize!(1024),
77 },
78 }
79 }
80
81 type TestDb<F> = Db<F, deterministic::Context, commonware_utils::sequence::U64, Sha256>;
82
83 async fn open_db<F: crate::merkle::Family>(context: deterministic::Context) -> TestDb<F> {
84 let cfg = db_config("partition", &context);
85 TestDb::init(context, cfg).await.unwrap()
86 }
87
88 fn reopen<F: crate::merkle::Family>() -> tests::Reopen<TestDb<F>> {
89 Box::new(|ctx| Box::pin(open_db(ctx)))
90 }
91
92 #[test_traced("INFO")]
93 fn test_keyless_fixed_empty() {
94 deterministic::Runner::default().start(|ctx| async move {
95 let db = open_db::<mmr::Family>(ctx.with_label("db1")).await;
96 tests::test_keyless_db_empty(ctx, db, reopen::<mmr::Family>()).await;
97 });
98 }
99
100 #[test_traced("WARN")]
101 fn test_keyless_fixed_build_basic() {
102 deterministic::Runner::default().start(|ctx| async move {
103 let db = open_db::<mmr::Family>(ctx.with_label("db1")).await;
104 tests::test_keyless_db_build_basic(ctx, db, reopen::<mmr::Family>()).await;
105 });
106 }
107
108 #[test_traced("WARN")]
109 fn test_keyless_fixed_recovery() {
110 deterministic::Runner::default().start(|ctx| async move {
111 let db = open_db::<mmr::Family>(ctx.with_label("db1")).await;
112 tests::test_keyless_db_recovery(ctx, db, reopen::<mmr::Family>()).await;
113 });
114 }
115
116 #[test_traced("WARN")]
117 fn test_keyless_fixed_non_empty_recovery() {
118 deterministic::Runner::default().start(|ctx| async move {
119 let db = open_db::<mmr::Family>(ctx.with_label("db1")).await;
120 tests::test_keyless_db_non_empty_recovery(ctx, db, reopen::<mmr::Family>()).await;
121 });
122 }
123
124 #[test_traced("INFO")]
125 fn test_keyless_fixed_proof() {
126 deterministic::Runner::default().start(|ctx| async move {
127 let db = open_db::<mmr::Family>(ctx.clone()).await;
128 tests::test_keyless_db_proof(db).await;
129 });
130 }
131
132 #[test_traced("INFO")]
133 fn test_keyless_fixed_proof_comprehensive() {
134 deterministic::Runner::default().start(|ctx| async move {
135 let db = open_db::<mmr::Family>(ctx.clone()).await;
136 tests::test_keyless_db_proof_comprehensive(db).await;
137 });
138 }
139
140 #[test_traced("INFO")]
141 fn test_keyless_fixed_proof_with_pruning() {
142 deterministic::Runner::default().start(|ctx| async move {
143 let db = open_db::<mmr::Family>(ctx.with_label("db1")).await;
144 tests::test_keyless_db_proof_with_pruning(ctx, db, reopen::<mmr::Family>()).await;
145 });
146 }
147
148 #[test_traced("WARN")]
149 fn test_keyless_fixed_empty_db_recovery() {
150 deterministic::Runner::default().start(|ctx| async move {
151 let db = open_db::<mmr::Family>(ctx.with_label("db1")).await;
152 tests::test_keyless_db_empty_db_recovery(ctx, db, reopen::<mmr::Family>()).await;
153 });
154 }
155
156 #[test_traced("WARN")]
157 fn test_keyless_fixed_replay_with_trailing_appends() {
158 deterministic::Runner::default().start(|ctx| async move {
159 let db = open_db::<mmr::Family>(ctx.with_label("db1")).await;
160 tests::test_keyless_db_replay_with_trailing_appends(ctx, db, reopen::<mmr::Family>())
161 .await;
162 });
163 }
164
165 #[test_traced("INFO")]
166 fn test_keyless_fixed_get_out_of_bounds() {
167 deterministic::Runner::default().start(|ctx| async move {
168 let db = open_db::<mmr::Family>(ctx.clone()).await;
169 tests::test_keyless_db_get_out_of_bounds(db).await;
170 });
171 }
172
173 #[test_traced("INFO")]
174 fn test_keyless_fixed_metadata() {
175 deterministic::Runner::default().start(|ctx| async move {
176 let db = open_db::<mmr::Family>(ctx.with_label("db")).await;
177 tests::test_keyless_db_metadata(db).await;
178 });
179 }
180
181 #[test_traced("INFO")]
182 fn test_keyless_fixed_pruning() {
183 deterministic::Runner::default().start(|ctx| async move {
184 let db = open_db::<mmr::Family>(ctx.with_label("db")).await;
185 tests::test_keyless_db_pruning(db).await;
186 });
187 }
188
189 #[test_traced("INFO")]
190 fn test_keyless_fixed_batch_get() {
191 deterministic::Runner::default().start(|ctx| async move {
192 let db = open_db::<mmr::Family>(ctx.with_label("db")).await;
193 tests::test_keyless_batch_get(db).await;
194 });
195 }
196
197 #[test_traced("INFO")]
198 fn test_keyless_fixed_batch_stacked_get() {
199 deterministic::Runner::default().start(|ctx| async move {
200 let db = open_db::<mmr::Family>(ctx.with_label("db")).await;
201 tests::test_keyless_batch_stacked_get(db).await;
202 });
203 }
204
205 #[test_traced("INFO")]
206 fn test_keyless_fixed_batch_speculative_root() {
207 deterministic::Runner::default().start(|ctx| async move {
208 let db = open_db::<mmr::Family>(ctx.with_label("db")).await;
209 tests::test_keyless_batch_speculative_root(db).await;
210 });
211 }
212
213 #[test_traced("INFO")]
214 fn test_keyless_fixed_merkleized_batch_get() {
215 deterministic::Runner::default().start(|ctx| async move {
216 let db = open_db::<mmr::Family>(ctx.with_label("db")).await;
217 tests::test_keyless_merkleized_batch_get(db).await;
218 });
219 }
220
221 #[test_traced("INFO")]
222 fn test_keyless_fixed_batch_chained() {
223 deterministic::Runner::default().start(|ctx| async move {
224 let db = open_db::<mmr::Family>(ctx.with_label("db")).await;
225 tests::test_keyless_batch_chained(db).await;
226 });
227 }
228
229 #[test_traced("INFO")]
230 fn test_keyless_fixed_batch_chained_apply_sequential() {
231 deterministic::Runner::default().start(|ctx| async move {
232 let db = open_db::<mmr::Family>(ctx.with_label("db")).await;
233 tests::test_keyless_batch_chained_apply_sequential(db).await;
234 });
235 }
236
237 #[test_traced("INFO")]
238 fn test_keyless_fixed_batch_many_sequential() {
239 deterministic::Runner::default().start(|ctx| async move {
240 let db = open_db::<mmr::Family>(ctx.with_label("db")).await;
241 tests::test_keyless_batch_many_sequential(db).await;
242 });
243 }
244
245 #[test_traced("INFO")]
246 fn test_keyless_fixed_batch_empty() {
247 deterministic::Runner::default().start(|ctx| async move {
248 let db = open_db::<mmr::Family>(ctx.with_label("db")).await;
249 tests::test_keyless_batch_empty(db).await;
250 });
251 }
252
253 #[test_traced("INFO")]
254 fn test_keyless_fixed_batch_chained_merkleized_get() {
255 deterministic::Runner::default().start(|ctx| async move {
256 let db = open_db::<mmr::Family>(ctx.with_label("db")).await;
257 tests::test_keyless_batch_chained_merkleized_get(db).await;
258 });
259 }
260
261 #[test_traced("INFO")]
262 fn test_keyless_fixed_batch_large() {
263 deterministic::Runner::default().start(|ctx| async move {
264 let db = open_db::<mmr::Family>(ctx.with_label("db")).await;
265 tests::test_keyless_batch_large(db).await;
266 });
267 }
268
269 #[test_traced]
270 fn test_keyless_fixed_stale_batch() {
271 deterministic::Runner::default().start(|ctx| async move {
272 let db = open_db::<mmr::Family>(ctx.with_label("db")).await;
273 tests::test_keyless_stale_batch(db).await;
274 });
275 }
276
277 #[test_traced]
278 fn test_keyless_fixed_stale_batch_chained() {
279 deterministic::Runner::default().start(|ctx| async move {
280 let db = open_db::<mmr::Family>(ctx.with_label("db")).await;
281 tests::test_keyless_stale_batch_chained(db).await;
282 });
283 }
284
285 #[test_traced]
286 fn test_keyless_fixed_sequential_commit_parent_then_child() {
287 deterministic::Runner::default().start(|ctx| async move {
288 let db = open_db::<mmr::Family>(ctx.with_label("db")).await;
289 tests::test_keyless_sequential_commit_parent_then_child(db).await;
290 });
291 }
292
293 #[test_traced]
294 fn test_keyless_fixed_stale_batch_child_before_parent() {
295 deterministic::Runner::default().start(|ctx| async move {
296 let db = open_db::<mmr::Family>(ctx.with_label("db")).await;
297 tests::test_keyless_stale_batch_child_before_parent(db).await;
298 });
299 }
300
301 #[test_traced]
302 fn test_keyless_fixed_to_batch() {
303 deterministic::Runner::default().start(|ctx| async move {
304 let db = open_db::<mmr::Family>(ctx.with_label("db")).await;
305 tests::test_keyless_to_batch(db).await;
306 });
307 }
308
309 #[test_traced]
310 fn test_keyless_fixed_child_root_matches_pending_and_committed() {
311 deterministic::Runner::default().start(|ctx| async move {
312 let db = open_db::<mmr::Family>(ctx.with_label("db")).await;
313 tests::test_keyless_child_root_matches_pending_and_committed(db).await;
314 });
315 }
316
317 #[test_traced("INFO")]
318 fn test_keyless_fixed_rewind_recovery() {
319 deterministic::Runner::default().start(|ctx| async move {
320 let db = open_db::<mmr::Family>(ctx.with_label("db")).await;
321 tests::test_keyless_db_rewind_recovery(ctx, db, reopen::<mmr::Family>()).await;
322 });
323 }
324
325 #[test_traced("INFO")]
326 fn test_keyless_fixed_rewind_pruned_target_errors() {
327 deterministic::Runner::default().start(|ctx| async move {
328 let db = open_db::<mmr::Family>(ctx.with_label("db")).await;
329 tests::test_keyless_db_rewind_pruned_target_errors(db).await;
330 });
331 }
332
333 #[test_traced("INFO")]
336 fn test_keyless_fixed_empty_mmb() {
337 deterministic::Runner::default().start(|ctx| async move {
338 let db = open_db::<mmb::Family>(ctx.with_label("db1")).await;
339 tests::test_keyless_db_empty(ctx, db, reopen::<mmb::Family>()).await;
340 });
341 }
342
343 #[test_traced("WARN")]
344 fn test_keyless_fixed_build_basic_mmb() {
345 deterministic::Runner::default().start(|ctx| async move {
346 let db = open_db::<mmb::Family>(ctx.with_label("db1")).await;
347 tests::test_keyless_db_build_basic(ctx, db, reopen::<mmb::Family>()).await;
348 });
349 }
350
351 #[test_traced("WARN")]
352 fn test_keyless_fixed_recovery_mmb() {
353 deterministic::Runner::default().start(|ctx| async move {
354 let db = open_db::<mmb::Family>(ctx.with_label("db1")).await;
355 tests::test_keyless_db_recovery(ctx, db, reopen::<mmb::Family>()).await;
356 });
357 }
358
359 #[test_traced("WARN")]
360 fn test_keyless_fixed_non_empty_recovery_mmb() {
361 deterministic::Runner::default().start(|ctx| async move {
362 let db = open_db::<mmb::Family>(ctx.with_label("db1")).await;
363 tests::test_keyless_db_non_empty_recovery(ctx, db, reopen::<mmb::Family>()).await;
364 });
365 }
366
367 #[test_traced("INFO")]
368 fn test_keyless_fixed_proof_mmb() {
369 deterministic::Runner::default().start(|ctx| async move {
370 let db = open_db::<mmb::Family>(ctx.clone()).await;
371 tests::test_keyless_db_proof(db).await;
372 });
373 }
374
375 #[test_traced("INFO")]
376 fn test_keyless_fixed_proof_comprehensive_mmb() {
377 deterministic::Runner::default().start(|ctx| async move {
378 let db = open_db::<mmb::Family>(ctx.clone()).await;
379 tests::test_keyless_db_proof_comprehensive(db).await;
380 });
381 }
382
383 #[test_traced("INFO")]
384 fn test_keyless_fixed_proof_with_pruning_mmb() {
385 deterministic::Runner::default().start(|ctx| async move {
386 let db = open_db::<mmb::Family>(ctx.with_label("db1")).await;
387 tests::test_keyless_db_proof_with_pruning(ctx, db, reopen::<mmb::Family>()).await;
388 });
389 }
390
391 #[test_traced("WARN")]
392 fn test_keyless_fixed_empty_db_recovery_mmb() {
393 deterministic::Runner::default().start(|ctx| async move {
394 let db = open_db::<mmb::Family>(ctx.with_label("db1")).await;
395 tests::test_keyless_db_empty_db_recovery(ctx, db, reopen::<mmb::Family>()).await;
396 });
397 }
398
399 #[test_traced("WARN")]
400 fn test_keyless_fixed_replay_with_trailing_appends_mmb() {
401 deterministic::Runner::default().start(|ctx| async move {
402 let db = open_db::<mmb::Family>(ctx.with_label("db1")).await;
403 tests::test_keyless_db_replay_with_trailing_appends(ctx, db, reopen::<mmb::Family>())
404 .await;
405 });
406 }
407
408 #[test_traced("INFO")]
409 fn test_keyless_fixed_get_out_of_bounds_mmb() {
410 deterministic::Runner::default().start(|ctx| async move {
411 let db = open_db::<mmb::Family>(ctx.clone()).await;
412 tests::test_keyless_db_get_out_of_bounds(db).await;
413 });
414 }
415
416 #[test_traced("INFO")]
417 fn test_keyless_fixed_metadata_mmb() {
418 deterministic::Runner::default().start(|ctx| async move {
419 let db = open_db::<mmb::Family>(ctx.with_label("db")).await;
420 tests::test_keyless_db_metadata(db).await;
421 });
422 }
423
424 #[test_traced("INFO")]
425 fn test_keyless_fixed_pruning_mmb() {
426 deterministic::Runner::default().start(|ctx| async move {
427 let db = open_db::<mmb::Family>(ctx.with_label("db")).await;
428 tests::test_keyless_db_pruning(db).await;
429 });
430 }
431
432 #[test_traced("INFO")]
433 fn test_keyless_fixed_batch_get_mmb() {
434 deterministic::Runner::default().start(|ctx| async move {
435 let db = open_db::<mmb::Family>(ctx.with_label("db")).await;
436 tests::test_keyless_batch_get(db).await;
437 });
438 }
439
440 #[test_traced("INFO")]
441 fn test_keyless_fixed_batch_stacked_get_mmb() {
442 deterministic::Runner::default().start(|ctx| async move {
443 let db = open_db::<mmb::Family>(ctx.with_label("db")).await;
444 tests::test_keyless_batch_stacked_get(db).await;
445 });
446 }
447
448 #[test_traced("INFO")]
449 fn test_keyless_fixed_batch_speculative_root_mmb() {
450 deterministic::Runner::default().start(|ctx| async move {
451 let db = open_db::<mmb::Family>(ctx.with_label("db")).await;
452 tests::test_keyless_batch_speculative_root(db).await;
453 });
454 }
455
456 #[test_traced("INFO")]
457 fn test_keyless_fixed_merkleized_batch_get_mmb() {
458 deterministic::Runner::default().start(|ctx| async move {
459 let db = open_db::<mmb::Family>(ctx.with_label("db")).await;
460 tests::test_keyless_merkleized_batch_get(db).await;
461 });
462 }
463
464 #[test_traced("INFO")]
465 fn test_keyless_fixed_batch_chained_mmb() {
466 deterministic::Runner::default().start(|ctx| async move {
467 let db = open_db::<mmb::Family>(ctx.with_label("db")).await;
468 tests::test_keyless_batch_chained(db).await;
469 });
470 }
471
472 #[test_traced("INFO")]
473 fn test_keyless_fixed_batch_chained_apply_sequential_mmb() {
474 deterministic::Runner::default().start(|ctx| async move {
475 let db = open_db::<mmb::Family>(ctx.with_label("db")).await;
476 tests::test_keyless_batch_chained_apply_sequential(db).await;
477 });
478 }
479
480 #[test_traced("INFO")]
481 fn test_keyless_fixed_batch_many_sequential_mmb() {
482 deterministic::Runner::default().start(|ctx| async move {
483 let db = open_db::<mmb::Family>(ctx.with_label("db")).await;
484 tests::test_keyless_batch_many_sequential(db).await;
485 });
486 }
487
488 #[test_traced("INFO")]
489 fn test_keyless_fixed_batch_empty_mmb() {
490 deterministic::Runner::default().start(|ctx| async move {
491 let db = open_db::<mmb::Family>(ctx.with_label("db")).await;
492 tests::test_keyless_batch_empty(db).await;
493 });
494 }
495
496 #[test_traced("INFO")]
497 fn test_keyless_fixed_batch_chained_merkleized_get_mmb() {
498 deterministic::Runner::default().start(|ctx| async move {
499 let db = open_db::<mmb::Family>(ctx.with_label("db")).await;
500 tests::test_keyless_batch_chained_merkleized_get(db).await;
501 });
502 }
503
504 #[test_traced("INFO")]
505 fn test_keyless_fixed_batch_large_mmb() {
506 deterministic::Runner::default().start(|ctx| async move {
507 let db = open_db::<mmb::Family>(ctx.with_label("db")).await;
508 tests::test_keyless_batch_large(db).await;
509 });
510 }
511
512 #[test_traced]
513 fn test_keyless_fixed_stale_batch_mmb() {
514 deterministic::Runner::default().start(|ctx| async move {
515 let db = open_db::<mmb::Family>(ctx.with_label("db")).await;
516 tests::test_keyless_stale_batch(db).await;
517 });
518 }
519
520 #[test_traced]
521 fn test_keyless_fixed_stale_batch_chained_mmb() {
522 deterministic::Runner::default().start(|ctx| async move {
523 let db = open_db::<mmb::Family>(ctx.with_label("db")).await;
524 tests::test_keyless_stale_batch_chained(db).await;
525 });
526 }
527
528 #[test_traced]
529 fn test_keyless_fixed_sequential_commit_parent_then_child_mmb() {
530 deterministic::Runner::default().start(|ctx| async move {
531 let db = open_db::<mmb::Family>(ctx.with_label("db")).await;
532 tests::test_keyless_sequential_commit_parent_then_child(db).await;
533 });
534 }
535
536 #[test_traced]
537 fn test_keyless_fixed_stale_batch_child_before_parent_mmb() {
538 deterministic::Runner::default().start(|ctx| async move {
539 let db = open_db::<mmb::Family>(ctx.with_label("db")).await;
540 tests::test_keyless_stale_batch_child_before_parent(db).await;
541 });
542 }
543
544 #[test_traced]
545 fn test_keyless_fixed_to_batch_mmb() {
546 deterministic::Runner::default().start(|ctx| async move {
547 let db = open_db::<mmb::Family>(ctx.with_label("db")).await;
548 tests::test_keyless_to_batch(db).await;
549 });
550 }
551
552 #[test_traced]
553 fn test_keyless_fixed_child_root_matches_pending_and_committed_mmb() {
554 deterministic::Runner::default().start(|ctx| async move {
555 let db = open_db::<mmb::Family>(ctx.with_label("db")).await;
556 tests::test_keyless_child_root_matches_pending_and_committed(db).await;
557 });
558 }
559
560 #[test_traced("INFO")]
561 fn test_keyless_fixed_rewind_recovery_mmb() {
562 deterministic::Runner::default().start(|ctx| async move {
563 let db = open_db::<mmb::Family>(ctx.with_label("db")).await;
564 tests::test_keyless_db_rewind_recovery(ctx, db, reopen::<mmb::Family>()).await;
565 });
566 }
567
568 #[test_traced("INFO")]
569 fn test_keyless_fixed_rewind_pruned_target_errors_mmb() {
570 deterministic::Runner::default().start(|ctx| async move {
571 let db = open_db::<mmb::Family>(ctx.with_label("db")).await;
572 tests::test_keyless_db_rewind_pruned_target_errors(db).await;
573 });
574 }
575}