1use crate::{
6 journal::{
7 authenticated,
8 contiguous::variable::{self, Config as JournalConfig},
9 },
10 merkle::Family,
11 qmdb::{
12 any::value::{VariableEncoding, VariableValue},
13 keyless::operation::Operation as BaseOperation,
14 operation::Committable,
15 Error, ROOT_BAGGING,
16 },
17 Context,
18};
19use commonware_codec::Read;
20use commonware_cryptography::Hasher;
21use commonware_parallel::Strategy;
22
23pub type Operation<F, V> = BaseOperation<F, VariableEncoding<V>>;
25
26pub type Db<F, E, V, H, S> =
28 super::Keyless<F, E, VariableEncoding<V>, variable::Journal<E, Operation<F, V>>, H, S>;
29
30pub type CompactDb<F, E, V, H, C, S> = super::CompactDb<F, E, VariableEncoding<V>, H, C, S>;
32
33type Journal<F, E, V, H, S> =
34 authenticated::Journal<F, E, variable::Journal<E, Operation<F, V>>, H, S>;
35
36pub type Config<C, S> = super::Config<JournalConfig<C>, S>;
38
39pub type CompactConfig<C, S> = super::CompactConfig<C, S>;
41
42impl<F: Family, E: Context, V: VariableValue, H: Hasher, S: Strategy> Db<F, E, V, H, S> {
43 pub async fn init(
46 context: E,
47 cfg: Config<<Operation<F, V> as Read>::Cfg, S>,
48 ) -> Result<Self, Error<F>> {
49 let journal: Journal<F, E, V, H, S> = Journal::new(
50 context.child("journal"),
51 cfg.merkle,
52 cfg.log,
53 Operation::<F, V>::is_commit,
54 ROOT_BAGGING,
55 )
56 .await?;
57 Self::init_from_journal(journal, context).await
58 }
59}
60
61impl<
62 F: Family,
63 E: Context,
64 V: VariableValue,
65 H: Hasher,
66 C: Clone + Send + Sync + 'static,
67 S: Strategy,
68 > CompactDb<F, E, V, H, C, S>
69where
70 Operation<F, V>: Read<Cfg = C>,
71{
72 pub async fn init(context: E, cfg: CompactConfig<C, S>) -> Result<Self, Error<F>> {
74 let merkle = crate::merkle::compact::Merkle::new(cfg.strategy);
75 Self::init_from_merkle(
76 merkle,
77 context.child("witness"),
78 cfg.witness,
79 cfg.commit_codec_config,
80 )
81 .await
82 }
83}
84
85#[cfg(test)]
86mod test {
87 use super::*;
88 use crate::{
89 merkle::{mmb, mmr},
90 qmdb::keyless::tests,
91 };
92 use commonware_cryptography::Sha256;
93 use commonware_macros::{boxed, test_traced};
94 use commonware_parallel::Sequential;
95 use commonware_runtime::{
96 buffer::paged::CacheRef, deterministic, BufferPooler, Runner as _, Supervisor as _,
97 };
98 use commonware_utils::{NZUsize, NZU16, NZU64};
99 use std::num::{NonZeroU16, NonZeroUsize};
100
101 const PAGE_SIZE: NonZeroU16 = NZU16!(101);
103 const PAGE_CACHE_SIZE: NonZeroUsize = NZUsize!(11);
104
105 fn db_config(
106 suffix: &str,
107 pooler: &impl BufferPooler,
108 ) -> Config<(commonware_codec::RangeCfg<usize>, ()), Sequential> {
109 let page_cache = CacheRef::from_pooler(pooler, PAGE_SIZE, PAGE_CACHE_SIZE);
110 Config {
111 merkle: crate::merkle::full::Config {
112 journal_partition: format!("journal-{suffix}"),
113 metadata_partition: format!("metadata-{suffix}"),
114 items_per_blob: NZU64!(11),
115 write_buffer: NZUsize!(1024),
116 strategy: Sequential,
117 page_cache: page_cache.clone(),
118 },
119 log: JournalConfig {
120 partition: format!("log-journal-{suffix}"),
121 items_per_section: NZU64!(7),
122 compression: None,
123 codec_config: ((0..=10000).into(), ()),
124 page_cache,
125 write_buffer: NZUsize!(1024),
126 },
127 }
128 }
129
130 type TestDb<F> = Db<F, deterministic::Context, Vec<u8>, Sha256, Sequential>;
131 type TestCompactDb<F> = CompactDb<
132 F,
133 deterministic::Context,
134 Vec<u8>,
135 Sha256,
136 (commonware_codec::RangeCfg<usize>, ()),
137 Sequential,
138 >;
139
140 async fn open_db<F: Family>(context: deterministic::Context) -> TestDb<F> {
142 open_db_with_suffix("partition", context).await
143 }
144
145 async fn open_db_with_suffix<F: Family>(
146 suffix: &str,
147 context: deterministic::Context,
148 ) -> TestDb<F> {
149 let cfg = db_config(suffix, &context);
150 TestDb::init(context, cfg).await.unwrap()
151 }
152
153 async fn open_compact<F: crate::merkle::Family>(
154 context: deterministic::Context,
155 ) -> TestCompactDb<F> {
156 let cfg = CompactConfig {
157 strategy: Sequential,
158 witness: crate::journal::contiguous::variable::Config {
159 partition: "compact-keyless-variable-witness".into(),
160 items_per_section: NZU64!(64),
161 compression: None,
162 codec_config: (),
163 page_cache: CacheRef::from_pooler(&context, PAGE_SIZE, PAGE_CACHE_SIZE),
164 write_buffer: NZUsize!(1024),
165 },
166 commit_codec_config: ((0..=10000usize).into(), ()),
167 };
168 TestCompactDb::init(context, cfg).await.unwrap()
169 }
170
171 fn reopen<F: Family>() -> tests::Reopen<TestDb<F>> {
172 Box::new(|ctx| Box::pin(open_db(ctx)))
173 }
174
175 #[test_traced("INFO")]
176 fn test_keyless_db_empty() {
177 deterministic::Runner::default().start(|ctx| async move {
178 let db = open_db::<mmr::Family>(ctx.child("db").with_attribute("index", 1)).await;
179 tests::test_keyless_db_empty(ctx, db, reopen::<mmr::Family>()).await;
180 });
181 }
182
183 #[test_traced("INFO")]
184 fn test_keyless_db_commit_after_sync_recovery() {
185 deterministic::Runner::default().start(|ctx| async move {
186 let db = open_db::<mmr::Family>(ctx.child("db").with_attribute("index", 1)).await;
187 tests::test_keyless_db_commit_after_sync_recovery(ctx, db, reopen::<mmr::Family>())
188 .await;
189 });
190 }
191
192 #[test_traced("WARN")]
193 fn test_keyless_db_build_basic() {
194 deterministic::Runner::default().start(|ctx| async move {
195 let db = open_db::<mmr::Family>(ctx.child("db").with_attribute("index", 1)).await;
196 tests::test_keyless_db_build_basic(ctx, db, reopen::<mmr::Family>()).await;
197 });
198 }
199
200 #[test_traced("WARN")]
201 fn test_keyless_db_recovery() {
202 deterministic::Runner::default().start(|ctx| async move {
203 let db = open_db::<mmr::Family>(ctx.child("db").with_attribute("index", 1)).await;
204 tests::test_keyless_db_recovery(ctx, db, reopen::<mmr::Family>()).await;
205 });
206 }
207
208 #[test_traced("WARN")]
209 fn test_keyless_db_non_empty_recovery() {
210 deterministic::Runner::default().start(|ctx| async move {
211 let db = open_db::<mmr::Family>(ctx.child("db").with_attribute("index", 1)).await;
212 tests::test_keyless_db_non_empty_recovery(ctx, db, reopen::<mmr::Family>()).await;
213 });
214 }
215
216 #[test_traced("INFO")]
217 fn test_keyless_db_proof() {
218 deterministic::Runner::default().start(|ctx| async move {
219 let db = open_db::<mmr::Family>(ctx.child("storage")).await;
220 tests::test_keyless_db_proof(db).await;
221 });
222 }
223
224 #[test_traced("INFO")]
225 fn test_keyless_db_proof_comprehensive() {
226 deterministic::Runner::default().start(|ctx| async move {
227 let db = open_db::<mmr::Family>(ctx.child("storage")).await;
228 tests::test_keyless_db_proof_comprehensive(db).await;
229 });
230 }
231
232 #[test_traced("INFO")]
233 fn test_keyless_db_proof_with_pruning() {
234 deterministic::Runner::default().start(|ctx| async move {
235 let db = open_db::<mmr::Family>(ctx.child("db").with_attribute("index", 1)).await;
236 tests::test_keyless_db_proof_with_pruning(ctx, db, reopen::<mmr::Family>()).await;
237 });
238 }
239
240 #[test_traced("INFO")]
251 fn test_keyless_historical_proof_floor_pruned() {
252 use crate::merkle::Location;
253 deterministic::Runner::default().start(|ctx| async move {
254 let mut db = open_db::<mmr::Family>(ctx.child("db")).await;
255
256 for batch_idx in 0u64..15 {
258 let mut batch = db.new_batch();
259 for j in 0..3 {
260 batch =
261 batch.append(<Vec<u8> as crate::qmdb::keyless::tests::TestValue>::make(
262 batch_idx * 10 + j,
263 ));
264 }
265 let new_commit_loc = Location::new(*db.last_commit_loc() + 1 + 3);
266 db.apply_batch(batch.merkleize(&db, None, new_commit_loc).await)
267 .await
268 .unwrap();
269 }
270
271 db.prune(Location::new(8)).await.unwrap();
274 let bounds = db.bounds();
275 assert_eq!(*bounds.start, 7);
276
277 let result = db
280 .historical_proof(Location::new(8), bounds.start, NZU64!(5))
281 .await;
282 assert!(
283 !matches!(result, Err(Error::UnexpectedData(_))),
284 "must not surface as UnexpectedData; got {result:?}",
285 );
286 assert!(
287 matches!(result, Err(Error::HistoricalFloorPruned(loc)) if loc == Location::new(8)),
288 "expected HistoricalFloorPruned(8), got {result:?}",
289 );
290
291 db.historical_proof(Location::new(9), Location::new(8), NZU64!(1))
295 .await
296 .expect("commit-boundary historical_proof should succeed");
297
298 db.destroy().await.unwrap();
299 });
300 }
301
302 #[test_traced("WARN")]
303 fn test_keyless_db_empty_db_recovery() {
304 deterministic::Runner::default().start(|ctx| async move {
305 let db = open_db::<mmr::Family>(ctx.child("db").with_attribute("index", 1)).await;
306 tests::test_keyless_db_empty_db_recovery(ctx, db, reopen::<mmr::Family>()).await;
307 });
308 }
309
310 #[test_traced("WARN")]
311 fn test_keyless_db_replay_with_trailing_appends() {
312 deterministic::Runner::default().start(|ctx| async move {
313 let db = open_db::<mmr::Family>(ctx.child("db").with_attribute("index", 1)).await;
314 tests::test_keyless_db_replay_with_trailing_appends(ctx, db, reopen::<mmr::Family>())
315 .await;
316 });
317 }
318
319 #[test_traced("INFO")]
320 fn test_keyless_db_get_out_of_bounds() {
321 deterministic::Runner::default().start(|ctx| async move {
322 let db = open_db::<mmr::Family>(ctx.child("storage")).await;
323 tests::test_keyless_db_get_out_of_bounds(db).await;
324 });
325 }
326
327 #[test_traced("INFO")]
328 fn test_keyless_db_metadata() {
329 deterministic::Runner::default().start(|ctx| async move {
330 let db = open_db::<mmr::Family>(ctx.child("db")).await;
331 tests::test_keyless_db_metadata(db).await;
332 });
333 }
334
335 #[boxed]
336 async fn assert_compact_root_compatibility<F: crate::merkle::Family>(
337 ctx: deterministic::Context,
338 ) {
339 let mut db = open_db::<F>(ctx.child("db")).await;
340 let mut compact = open_compact::<F>(ctx.child("compact")).await;
341 assert_eq!(db.root(), compact.root());
342
343 let v1 = b"hello".to_vec();
344 let v2 = b"world".to_vec();
345 let metadata = b"metadata".to_vec();
346
347 let floor = db.inactivity_floor_loc();
348 let retained = db
349 .new_batch()
350 .append(v1.clone())
351 .append(v2.clone())
352 .merkleize(&db, Some(metadata.clone()), floor)
353 .await;
354 let compact_batch = compact
355 .new_batch()
356 .append(v1)
357 .append(v2)
358 .merkleize(&compact, Some(metadata.clone()), floor)
359 .await;
360
361 assert_eq!(retained.root(), compact_batch.root());
362
363 db.apply_batch(retained).await.unwrap();
364 compact.apply_batch(compact_batch).unwrap();
365 db.commit().await.unwrap();
366 compact.sync().await.unwrap();
367
368 assert_eq!(db.root(), compact.root());
369 assert_eq!(compact.get_metadata(), Some(metadata.clone()));
370
371 drop(compact);
372 let reopened = open_compact::<F>(ctx.child("reopen")).await;
373 assert_eq!(db.root(), reopened.root());
374 assert_eq!(reopened.get_metadata(), Some(metadata));
375
376 reopened.destroy().await.unwrap();
377 db.destroy().await.unwrap();
378 }
379
380 #[test_traced("INFO")]
381 fn test_keyless_variable_compact_root_compatibility() {
382 deterministic::Runner::default().start(|ctx| async move {
383 assert_compact_root_compatibility::<mmr::Family>(ctx).await;
384 });
385 }
386
387 #[test_traced("INFO")]
388 fn test_keyless_variable_compact_root_compatibility_mmb() {
389 deterministic::Runner::default().start(|ctx| async move {
390 assert_compact_root_compatibility::<mmb::Family>(ctx).await;
391 });
392 }
393
394 #[test_traced("INFO")]
395 fn test_keyless_db_pruning() {
396 deterministic::Runner::default().start(|ctx| async move {
397 let db = open_db::<mmr::Family>(ctx.child("db")).await;
398 tests::test_keyless_db_pruning(db).await;
399 });
400 }
401
402 #[test_traced("INFO")]
403 fn test_keyless_batch_get() {
404 deterministic::Runner::default().start(|ctx| async move {
405 let db = open_db::<mmr::Family>(ctx.child("db")).await;
406 tests::test_keyless_batch_get(db).await;
407 });
408 }
409
410 #[test_traced("INFO")]
411 fn test_keyless_batch_stacked_get() {
412 deterministic::Runner::default().start(|ctx| async move {
413 let db = open_db::<mmr::Family>(ctx.child("db")).await;
414 tests::test_keyless_batch_stacked_get(db).await;
415 });
416 }
417
418 #[test_traced("INFO")]
419 fn test_keyless_batch_speculative_root() {
420 deterministic::Runner::default().start(|ctx| async move {
421 let db = open_db::<mmr::Family>(ctx.child("db")).await;
422 tests::test_keyless_batch_speculative_root(db).await;
423 });
424 }
425
426 #[test_traced("INFO")]
427 fn test_keyless_merkleized_batch_get() {
428 deterministic::Runner::default().start(|ctx| async move {
429 let db = open_db::<mmr::Family>(ctx.child("db")).await;
430 tests::test_keyless_merkleized_batch_get(db).await;
431 });
432 }
433
434 #[test_traced("INFO")]
435 fn test_keyless_get_many() {
436 deterministic::Runner::default().start(|ctx| async move {
437 let db = open_db::<mmr::Family>(ctx.child("db")).await;
438 tests::test_keyless_get_many(db).await;
439 });
440 }
441
442 #[test_traced("INFO")]
443 fn test_keyless_batch_chained() {
444 deterministic::Runner::default().start(|ctx| async move {
445 let db = open_db::<mmr::Family>(ctx.child("db")).await;
446 tests::test_keyless_batch_chained(db).await;
447 });
448 }
449
450 #[test_traced("INFO")]
451 fn test_keyless_batch_chained_apply_sequential() {
452 deterministic::Runner::default().start(|ctx| async move {
453 let db = open_db::<mmr::Family>(ctx.child("db")).await;
454 tests::test_keyless_batch_chained_apply_sequential(db).await;
455 });
456 }
457
458 #[test_traced("INFO")]
459 fn test_keyless_batch_many_sequential() {
460 deterministic::Runner::default().start(|ctx| async move {
461 let db = open_db::<mmr::Family>(ctx.child("db")).await;
462 tests::test_keyless_batch_many_sequential(db).await;
463 });
464 }
465
466 #[test_traced("INFO")]
467 fn test_keyless_batch_empty() {
468 deterministic::Runner::default().start(|ctx| async move {
469 let db = open_db::<mmr::Family>(ctx.child("db")).await;
470 tests::test_keyless_batch_empty(db).await;
471 });
472 }
473
474 #[test_traced("INFO")]
475 fn test_keyless_batch_chained_merkleized_get() {
476 deterministic::Runner::default().start(|ctx| async move {
477 let db = open_db::<mmr::Family>(ctx.child("db")).await;
478 tests::test_keyless_batch_chained_merkleized_get(db).await;
479 });
480 }
481
482 #[test_traced("INFO")]
483 fn test_keyless_batch_large() {
484 deterministic::Runner::default().start(|ctx| async move {
485 let db = open_db::<mmr::Family>(ctx.child("db")).await;
486 tests::test_keyless_batch_large(db).await;
487 });
488 }
489
490 #[test_traced]
491 fn test_keyless_stale_batch() {
492 deterministic::Runner::default().start(|ctx| async move {
493 let db = open_db::<mmr::Family>(ctx.child("db")).await;
494 tests::test_keyless_stale_batch(db).await;
495 });
496 }
497
498 #[test_traced]
499 fn test_stale_batch_chained() {
500 deterministic::Runner::default().start(|ctx| async move {
501 let db = open_db::<mmr::Family>(ctx.child("db")).await;
502 tests::test_keyless_stale_batch_chained(db).await;
503 });
504 }
505
506 #[test_traced]
507 fn test_sequential_commit_parent_then_child() {
508 deterministic::Runner::default().start(|ctx| async move {
509 let db = open_db::<mmr::Family>(ctx.child("db")).await;
510 tests::test_keyless_sequential_commit_parent_then_child(db).await;
511 });
512 }
513
514 #[test_traced]
515 fn test_stale_batch_child_applied_before_parent() {
516 deterministic::Runner::default().start(|ctx| async move {
517 let db = open_db::<mmr::Family>(ctx.child("db")).await;
518 tests::test_keyless_stale_batch_child_before_parent(db).await;
519 });
520 }
521
522 #[test_traced]
523 fn test_partial_ancestor_commit() {
524 deterministic::Runner::default().start(|ctx| async move {
525 let db = open_db::<mmr::Family>(ctx.child("db")).await;
526 tests::test_keyless_partial_ancestor_commit(db).await;
527 });
528 }
529
530 #[test_traced]
531 fn test_keyless_to_batch() {
532 deterministic::Runner::default().start(|ctx| async move {
533 let db = open_db::<mmr::Family>(ctx.child("db")).await;
534 tests::test_keyless_to_batch(db).await;
535 });
536 }
537
538 #[test_traced]
539 fn test_keyless_child_root_matches_pending_and_committed() {
540 deterministic::Runner::default().start(|ctx| async move {
541 let db = open_db::<mmr::Family>(ctx.child("db")).await;
542 tests::test_keyless_child_root_matches_pending_and_committed(db).await;
543 });
544 }
545
546 #[test_traced("INFO")]
547 fn test_keyless_rewind_recovery() {
548 deterministic::Runner::default().start(|ctx| async move {
549 let db = open_db::<mmr::Family>(ctx.child("db")).await;
550 tests::test_keyless_db_rewind_recovery(ctx, db, reopen::<mmr::Family>()).await;
551 });
552 }
553
554 #[test_traced("INFO")]
555 fn test_keyless_rewind_pruned_target_errors() {
556 deterministic::Runner::default().start(|ctx| async move {
557 let db = open_db::<mmr::Family>(ctx.child("db")).await;
558 tests::test_keyless_db_rewind_pruned_target_errors(db).await;
559 });
560 }
561
562 #[test_traced("INFO")]
565 fn test_keyless_db_empty_mmb() {
566 deterministic::Runner::default().start(|ctx| async move {
567 let db = open_db::<mmb::Family>(ctx.child("db").with_attribute("index", 1)).await;
568 tests::test_keyless_db_empty(ctx, db, reopen::<mmb::Family>()).await;
569 });
570 }
571
572 #[test_traced("WARN")]
573 fn test_keyless_db_build_basic_mmb() {
574 deterministic::Runner::default().start(|ctx| async move {
575 let db = open_db::<mmb::Family>(ctx.child("db").with_attribute("index", 1)).await;
576 tests::test_keyless_db_build_basic(ctx, db, reopen::<mmb::Family>()).await;
577 });
578 }
579
580 #[test_traced("WARN")]
581 fn test_keyless_db_recovery_mmb() {
582 deterministic::Runner::default().start(|ctx| async move {
583 let db = open_db::<mmb::Family>(ctx.child("db").with_attribute("index", 1)).await;
584 tests::test_keyless_db_recovery(ctx, db, reopen::<mmb::Family>()).await;
585 });
586 }
587
588 #[test_traced("WARN")]
589 fn test_keyless_db_non_empty_recovery_mmb() {
590 deterministic::Runner::default().start(|ctx| async move {
591 let db = open_db::<mmb::Family>(ctx.child("db").with_attribute("index", 1)).await;
592 tests::test_keyless_db_non_empty_recovery(ctx, db, reopen::<mmb::Family>()).await;
593 });
594 }
595
596 #[test_traced("INFO")]
597 fn test_keyless_db_proof_mmb() {
598 deterministic::Runner::default().start(|ctx| async move {
599 let db = open_db::<mmb::Family>(ctx.child("storage")).await;
600 tests::test_keyless_db_proof(db).await;
601 });
602 }
603
604 #[test_traced("INFO")]
605 fn test_keyless_db_proof_comprehensive_mmb() {
606 deterministic::Runner::default().start(|ctx| async move {
607 let db = open_db::<mmb::Family>(ctx.child("storage")).await;
608 tests::test_keyless_db_proof_comprehensive(db).await;
609 });
610 }
611
612 #[test_traced("INFO")]
613 fn test_keyless_db_proof_with_pruning_mmb() {
614 deterministic::Runner::default().start(|ctx| async move {
615 let db = open_db::<mmb::Family>(ctx.child("db").with_attribute("index", 1)).await;
616 tests::test_keyless_db_proof_with_pruning(ctx, db, reopen::<mmb::Family>()).await;
617 });
618 }
619
620 #[test_traced("WARN")]
621 fn test_keyless_db_empty_db_recovery_mmb() {
622 deterministic::Runner::default().start(|ctx| async move {
623 let db = open_db::<mmb::Family>(ctx.child("db").with_attribute("index", 1)).await;
624 tests::test_keyless_db_empty_db_recovery(ctx, db, reopen::<mmb::Family>()).await;
625 });
626 }
627
628 #[test_traced("WARN")]
629 fn test_keyless_db_replay_with_trailing_appends_mmb() {
630 deterministic::Runner::default().start(|ctx| async move {
631 let db = open_db::<mmb::Family>(ctx.child("db").with_attribute("index", 1)).await;
632 tests::test_keyless_db_replay_with_trailing_appends(ctx, db, reopen::<mmb::Family>())
633 .await;
634 });
635 }
636
637 #[test_traced("INFO")]
638 fn test_keyless_db_get_out_of_bounds_mmb() {
639 deterministic::Runner::default().start(|ctx| async move {
640 let db = open_db::<mmb::Family>(ctx.child("storage")).await;
641 tests::test_keyless_db_get_out_of_bounds(db).await;
642 });
643 }
644
645 #[test_traced("INFO")]
646 fn test_keyless_db_metadata_mmb() {
647 deterministic::Runner::default().start(|ctx| async move {
648 let db = open_db::<mmb::Family>(ctx.child("db")).await;
649 tests::test_keyless_db_metadata(db).await;
650 });
651 }
652
653 #[test_traced("INFO")]
654 fn test_keyless_db_pruning_mmb() {
655 deterministic::Runner::default().start(|ctx| async move {
656 let db = open_db::<mmb::Family>(ctx.child("db")).await;
657 tests::test_keyless_db_pruning(db).await;
658 });
659 }
660
661 #[test_traced("INFO")]
662 fn test_keyless_batch_get_mmb() {
663 deterministic::Runner::default().start(|ctx| async move {
664 let db = open_db::<mmb::Family>(ctx.child("db")).await;
665 tests::test_keyless_batch_get(db).await;
666 });
667 }
668
669 #[test_traced("INFO")]
670 fn test_keyless_batch_stacked_get_mmb() {
671 deterministic::Runner::default().start(|ctx| async move {
672 let db = open_db::<mmb::Family>(ctx.child("db")).await;
673 tests::test_keyless_batch_stacked_get(db).await;
674 });
675 }
676
677 #[test_traced("INFO")]
678 fn test_keyless_batch_speculative_root_mmb() {
679 deterministic::Runner::default().start(|ctx| async move {
680 let db = open_db::<mmb::Family>(ctx.child("db")).await;
681 tests::test_keyless_batch_speculative_root(db).await;
682 });
683 }
684
685 #[test_traced("INFO")]
686 fn test_keyless_merkleized_batch_get_mmb() {
687 deterministic::Runner::default().start(|ctx| async move {
688 let db = open_db::<mmb::Family>(ctx.child("db")).await;
689 tests::test_keyless_merkleized_batch_get(db).await;
690 });
691 }
692
693 #[test_traced("INFO")]
694 fn test_keyless_batch_chained_mmb() {
695 deterministic::Runner::default().start(|ctx| async move {
696 let db = open_db::<mmb::Family>(ctx.child("db")).await;
697 tests::test_keyless_batch_chained(db).await;
698 });
699 }
700
701 #[test_traced("INFO")]
702 fn test_keyless_batch_chained_apply_sequential_mmb() {
703 deterministic::Runner::default().start(|ctx| async move {
704 let db = open_db::<mmb::Family>(ctx.child("db")).await;
705 tests::test_keyless_batch_chained_apply_sequential(db).await;
706 });
707 }
708
709 #[test_traced("INFO")]
710 fn test_keyless_batch_many_sequential_mmb() {
711 deterministic::Runner::default().start(|ctx| async move {
712 let db = open_db::<mmb::Family>(ctx.child("db")).await;
713 tests::test_keyless_batch_many_sequential(db).await;
714 });
715 }
716
717 #[test_traced("INFO")]
718 fn test_keyless_batch_empty_mmb() {
719 deterministic::Runner::default().start(|ctx| async move {
720 let db = open_db::<mmb::Family>(ctx.child("db")).await;
721 tests::test_keyless_batch_empty(db).await;
722 });
723 }
724
725 #[test_traced("INFO")]
726 fn test_keyless_batch_chained_merkleized_get_mmb() {
727 deterministic::Runner::default().start(|ctx| async move {
728 let db = open_db::<mmb::Family>(ctx.child("db")).await;
729 tests::test_keyless_batch_chained_merkleized_get(db).await;
730 });
731 }
732
733 #[test_traced("INFO")]
734 fn test_keyless_batch_large_mmb() {
735 deterministic::Runner::default().start(|ctx| async move {
736 let db = open_db::<mmb::Family>(ctx.child("db")).await;
737 tests::test_keyless_batch_large(db).await;
738 });
739 }
740
741 #[test_traced]
742 fn test_keyless_stale_batch_mmb() {
743 deterministic::Runner::default().start(|ctx| async move {
744 let db = open_db::<mmb::Family>(ctx.child("db")).await;
745 tests::test_keyless_stale_batch(db).await;
746 });
747 }
748
749 #[test_traced]
750 fn test_stale_batch_chained_mmb() {
751 deterministic::Runner::default().start(|ctx| async move {
752 let db = open_db::<mmb::Family>(ctx.child("db")).await;
753 tests::test_keyless_stale_batch_chained(db).await;
754 });
755 }
756
757 #[test_traced]
758 fn test_sequential_commit_parent_then_child_mmb() {
759 deterministic::Runner::default().start(|ctx| async move {
760 let db = open_db::<mmb::Family>(ctx.child("db")).await;
761 tests::test_keyless_sequential_commit_parent_then_child(db).await;
762 });
763 }
764
765 #[test_traced]
766 fn test_stale_batch_child_applied_before_parent_mmb() {
767 deterministic::Runner::default().start(|ctx| async move {
768 let db = open_db::<mmb::Family>(ctx.child("db")).await;
769 tests::test_keyless_stale_batch_child_before_parent(db).await;
770 });
771 }
772
773 #[test_traced]
774 fn test_keyless_to_batch_mmb() {
775 deterministic::Runner::default().start(|ctx| async move {
776 let db = open_db::<mmb::Family>(ctx.child("db")).await;
777 tests::test_keyless_to_batch(db).await;
778 });
779 }
780
781 #[test_traced]
782 fn test_keyless_child_root_matches_pending_and_committed_mmb() {
783 deterministic::Runner::default().start(|ctx| async move {
784 let db = open_db::<mmb::Family>(ctx.child("db")).await;
785 tests::test_keyless_child_root_matches_pending_and_committed(db).await;
786 });
787 }
788
789 #[test_traced("INFO")]
790 fn test_keyless_rewind_recovery_mmb() {
791 deterministic::Runner::default().start(|ctx| async move {
792 let db = open_db::<mmb::Family>(ctx.child("db")).await;
793 tests::test_keyless_db_rewind_recovery(ctx, db, reopen::<mmb::Family>()).await;
794 });
795 }
796
797 #[test_traced("INFO")]
798 fn test_keyless_rewind_pruned_target_errors_mmb() {
799 deterministic::Runner::default().start(|ctx| async move {
800 let db = open_db::<mmb::Family>(ctx.child("db")).await;
801 tests::test_keyless_db_rewind_pruned_target_errors(db).await;
802 });
803 }
804
805 #[test_traced("INFO")]
806 fn test_keyless_variable_floor_tracking_mmb() {
807 deterministic::Runner::default().start(|ctx| async move {
808 let db = open_db::<mmb::Family>(ctx.child("db").with_attribute("index", 1)).await;
809 tests::test_keyless_db_floor_tracking(ctx, db, reopen::<mmb::Family>()).await;
810 });
811 }
812
813 #[test_traced("INFO")]
814 fn test_keyless_variable_floor_regression_rejected_mmb() {
815 deterministic::Runner::default().start(|ctx| async move {
816 let db = open_db::<mmb::Family>(ctx.child("db")).await;
817 tests::test_keyless_db_floor_regression_rejected(db).await;
818 });
819 }
820
821 #[test_traced("INFO")]
822 fn test_keyless_variable_floor_beyond_commit_loc_rejected_mmb() {
823 deterministic::Runner::default().start(|ctx| async move {
824 let db = open_db::<mmb::Family>(ctx.child("db")).await;
825 tests::test_keyless_db_floor_beyond_commit_loc_rejected(db).await;
826 });
827 }
828
829 #[test_traced("INFO")]
830 fn test_keyless_variable_rewind_restores_floor_mmb() {
831 deterministic::Runner::default().start(|ctx| async move {
832 let db = open_db::<mmb::Family>(ctx.child("db")).await;
833 tests::test_keyless_db_rewind_restores_floor(db).await;
834 });
835 }
836
837 #[test_traced("INFO")]
838 fn test_keyless_variable_floor_changes_root_mmb() {
839 deterministic::Runner::default().start(|ctx| async move {
840 let db_a = open_db_with_suffix::<mmb::Family>("root-a", ctx.child("a")).await;
841 let db_b = open_db_with_suffix::<mmb::Family>("root-b", ctx.child("b")).await;
842 tests::test_keyless_db_floor_changes_root(db_a, db_b).await;
843 });
844 }
845
846 #[test_traced("INFO")]
847 fn test_keyless_variable_floor_at_commit_loc_accepted_mmb() {
848 deterministic::Runner::default().start(|ctx| async move {
849 let db = open_db::<mmb::Family>(ctx.child("db")).await;
850 tests::test_keyless_db_floor_at_commit_loc_accepted(db).await;
851 });
852 }
853
854 #[test_traced("INFO")]
855 fn test_keyless_variable_rewind_after_reopen_with_floor_mmb() {
856 deterministic::Runner::default().start(|ctx| async move {
857 let db = open_db::<mmb::Family>(ctx.child("db").with_attribute("index", 1)).await;
858 tests::test_keyless_db_rewind_after_reopen_with_floor(ctx, db, reopen::<mmb::Family>())
859 .await;
860 });
861 }
862
863 #[test_traced("INFO")]
864 fn test_keyless_variable_ancestor_floor_regression_rejected_mmb() {
865 deterministic::Runner::default().start(|ctx| async move {
866 let db = open_db::<mmb::Family>(ctx.child("db")).await;
867 tests::test_keyless_db_ancestor_floor_regression_rejected(db).await;
868 });
869 }
870
871 #[test_traced("INFO")]
872 fn test_keyless_variable_ancestor_floor_beyond_commit_loc_rejected_mmb() {
873 deterministic::Runner::default().start(|ctx| async move {
874 let db = open_db::<mmb::Family>(ctx.child("db")).await;
875 tests::test_keyless_db_ancestor_floor_beyond_commit_loc_rejected(db).await;
876 });
877 }
878
879 #[test_traced("INFO")]
880 fn test_keyless_variable_chained_apply_with_valid_floors_succeeds_mmb() {
881 deterministic::Runner::default().start(|ctx| async move {
882 let db = open_db::<mmb::Family>(ctx.child("db")).await;
883 tests::test_keyless_db_chained_apply_with_valid_floors_succeeds(db).await;
884 });
885 }
886
887 #[test_traced("INFO")]
888 fn test_keyless_variable_single_commit_live_set_mmb() {
889 deterministic::Runner::default().start(|ctx| async move {
890 let db = open_db::<mmb::Family>(ctx.child("db").with_attribute("index", 1)).await;
891 tests::test_keyless_db_single_commit_live_set(ctx, db, reopen::<mmb::Family>()).await;
892 });
893 }
894
895 #[test_traced("INFO")]
896 fn test_keyless_variable_floor_tracking() {
897 deterministic::Runner::default().start(|ctx| async move {
898 let db = open_db::<mmr::Family>(ctx.child("db").with_attribute("index", 1)).await;
899 tests::test_keyless_db_floor_tracking(ctx, db, reopen::<mmr::Family>()).await;
900 });
901 }
902
903 #[test_traced("INFO")]
904 fn test_keyless_variable_floor_regression_rejected() {
905 deterministic::Runner::default().start(|ctx| async move {
906 let db = open_db::<mmr::Family>(ctx.child("db")).await;
907 tests::test_keyless_db_floor_regression_rejected(db).await;
908 });
909 }
910
911 #[test_traced("INFO")]
912 fn test_keyless_variable_floor_beyond_commit_loc_rejected() {
913 deterministic::Runner::default().start(|ctx| async move {
914 let db = open_db::<mmr::Family>(ctx.child("db")).await;
915 tests::test_keyless_db_floor_beyond_commit_loc_rejected(db).await;
916 });
917 }
918
919 #[test_traced("INFO")]
920 fn test_keyless_variable_rewind_restores_floor() {
921 deterministic::Runner::default().start(|ctx| async move {
922 let db = open_db::<mmr::Family>(ctx.child("db")).await;
923 tests::test_keyless_db_rewind_restores_floor(db).await;
924 });
925 }
926
927 #[test_traced("INFO")]
928 fn test_keyless_variable_floor_changes_root() {
929 deterministic::Runner::default().start(|ctx| async move {
930 let db_a = open_db_with_suffix::<mmr::Family>("root-a", ctx.child("a")).await;
931 let db_b = open_db_with_suffix::<mmr::Family>("root-b", ctx.child("b")).await;
932 tests::test_keyless_db_floor_changes_root(db_a, db_b).await;
933 });
934 }
935
936 #[test_traced("INFO")]
937 fn test_keyless_variable_floor_at_commit_loc_accepted() {
938 deterministic::Runner::default().start(|ctx| async move {
939 let db = open_db::<mmr::Family>(ctx.child("db")).await;
940 tests::test_keyless_db_floor_at_commit_loc_accepted(db).await;
941 });
942 }
943
944 #[test_traced("INFO")]
945 fn test_keyless_variable_rewind_after_reopen_with_floor() {
946 deterministic::Runner::default().start(|ctx| async move {
947 let db = open_db::<mmr::Family>(ctx.child("db").with_attribute("index", 1)).await;
948 tests::test_keyless_db_rewind_after_reopen_with_floor(ctx, db, reopen::<mmr::Family>())
949 .await;
950 });
951 }
952
953 #[test_traced("INFO")]
954 fn test_keyless_variable_ancestor_floor_regression_rejected() {
955 deterministic::Runner::default().start(|ctx| async move {
956 let db = open_db::<mmr::Family>(ctx.child("db")).await;
957 tests::test_keyless_db_ancestor_floor_regression_rejected(db).await;
958 });
959 }
960
961 #[test_traced("INFO")]
962 fn test_keyless_variable_ancestor_floor_beyond_commit_loc_rejected() {
963 deterministic::Runner::default().start(|ctx| async move {
964 let db = open_db::<mmr::Family>(ctx.child("db")).await;
965 tests::test_keyless_db_ancestor_floor_beyond_commit_loc_rejected(db).await;
966 });
967 }
968
969 #[test_traced("INFO")]
970 fn test_keyless_variable_chained_apply_with_valid_floors_succeeds() {
971 deterministic::Runner::default().start(|ctx| async move {
972 let db = open_db::<mmr::Family>(ctx.child("db")).await;
973 tests::test_keyless_db_chained_apply_with_valid_floors_succeeds(db).await;
974 });
975 }
976
977 #[test_traced("INFO")]
978 fn test_keyless_variable_single_commit_live_set() {
979 deterministic::Runner::default().start(|ctx| async move {
980 let db = open_db::<mmr::Family>(ctx.child("db").with_attribute("index", 1)).await;
981 tests::test_keyless_db_single_commit_live_set(ctx, db, reopen::<mmr::Family>()).await;
982 });
983 }
984
985 fn is_send<T: Send>(_: T) {}
986
987 #[allow(dead_code)]
988 fn assert_db_futures_are_send(
989 db: &mut TestDb<mmr::Family>,
990 loc: crate::merkle::Location<mmr::Family>,
991 ) {
992 is_send(db.get_metadata());
993 is_send(db.proof(loc, NZU64!(1)));
994 is_send(db.sync());
995 is_send(db.get(loc));
996 is_send(db.rewind(loc));
997 }
998}