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