1use super::{operation::Operation as BaseOperation, Config as BaseConfig, Immutable};
6use crate::{
7 journal::{
8 authenticated,
9 contiguous::variable::{self, Config as JournalConfig},
10 },
11 merkle::Family,
12 qmdb::{
13 any::{value::VariableEncoding, VariableValue},
14 operation::Key,
15 Error, ROOT_BAGGING,
16 },
17 translator::Translator,
18 Context,
19};
20use commonware_codec::Read;
21use commonware_cryptography::Hasher;
22use commonware_parallel::Strategy;
23
24pub type Operation<F, K, V> = BaseOperation<F, K, VariableEncoding<V>>;
26
27pub type Db<F, E, K, V, H, T, S> =
29 Immutable<F, E, K, VariableEncoding<V>, variable::Journal<E, Operation<F, K, V>>, H, T, S>;
30
31pub type CompactDb<F, E, K, V, H, C, S> = super::CompactDb<F, E, K, VariableEncoding<V>, H, C, S>;
33
34type Journal<F, E, K, V, H, S> =
35 authenticated::Journal<F, E, variable::Journal<E, Operation<F, K, V>>, H, S>;
36
37pub type Config<T, C, S> = BaseConfig<T, JournalConfig<C>, S>;
39
40pub type CompactConfig<C, S> = super::CompactConfig<C, S>;
42
43impl<F: Family, E: Context, K: Key, V: VariableValue, H: Hasher, T: Translator, S: Strategy>
44 Db<F, E, K, V, H, T, S>
45{
46 pub async fn init(
49 context: E,
50 cfg: Config<T, <Operation<F, K, V> as Read>::Cfg, S>,
51 ) -> Result<Self, Error<F>> {
52 let journal: Journal<F, E, K, V, H, S> = Journal::new(
53 context.child("journal"),
54 cfg.merkle_config,
55 cfg.log,
56 Operation::<F, K, V>::is_commit,
57 ROOT_BAGGING,
58 )
59 .await?;
60 Self::init_from_journal(journal, context, cfg.translator, cfg.init_cache_size).await
61 }
62}
63
64impl<
65 F: Family,
66 E: Context,
67 K: Key,
68 V: VariableValue,
69 H: Hasher,
70 C: Clone + Send + Sync + 'static,
71 S: Strategy,
72 > CompactDb<F, E, K, V, H, C, S>
73where
74 Operation<F, K, V>: Read<Cfg = C>,
75{
76 pub async fn init(context: E, cfg: CompactConfig<C, S>) -> Result<Self, Error<F>> {
78 let merkle = crate::merkle::compact::Merkle::new(cfg.strategy);
79 Self::init_from_merkle(
80 merkle,
81 context.child("witness"),
82 cfg.witness,
83 cfg.commit_codec_config,
84 )
85 .await
86 }
87}
88
89#[cfg(test)]
90mod tests {
91 use super::*;
92 use crate::{
93 journal::contiguous::variable::Config as JournalConfig,
94 merkle::{full::Config as MmrConfig, mmb, mmr},
95 qmdb::immutable::test,
96 translator::TwoCap,
97 };
98 use commonware_cryptography::{sha256::Digest, Sha256};
99 use commonware_macros::{boxed, test_traced};
100 use commonware_parallel::Sequential;
101 use commonware_runtime::{
102 buffer::paged::CacheRef, deterministic, BufferPooler, Runner as _, Supervisor as _,
103 };
104 use commonware_utils::{NZUsize, NZU16, NZU64};
105 use core::{future::Future, pin::Pin};
106 use std::num::{NonZeroU16, NonZeroUsize};
107
108 const PAGE_SIZE: NonZeroU16 = NZU16!(77);
109 const PAGE_CACHE_SIZE: NonZeroUsize = NZUsize!(9);
110
111 fn config(suffix: &str, pooler: &impl BufferPooler) -> Config<TwoCap, ((), ()), Sequential> {
112 let page_cache = CacheRef::from_pooler(pooler, PAGE_SIZE, PAGE_CACHE_SIZE);
113 super::BaseConfig {
114 merkle_config: MmrConfig {
115 journal_partition: format!("journal-{suffix}"),
116 metadata_partition: format!("metadata-{suffix}"),
117 items_per_blob: NZU64!(11),
118 write_buffer: NZUsize!(1024),
119 strategy: Sequential,
120 page_cache: page_cache.clone(),
121 },
122 log: JournalConfig {
123 partition: format!("log-{suffix}"),
124 items_per_section: NZU64!(5),
125 compression: None,
126 codec_config: ((), ()),
127 page_cache,
128 write_buffer: NZUsize!(1024),
129 },
130 translator: TwoCap,
131 init_cache_size: Some(NZUsize!(1024)),
132 }
133 }
134
135 async fn open_db<F: Family>(
136 context: deterministic::Context,
137 ) -> Db<F, deterministic::Context, Digest, Digest, Sha256, TwoCap, Sequential> {
138 let cfg = config("partition", &context);
139 Db::init(context, cfg).await.unwrap()
140 }
141
142 async fn open_compact<F: Family>(
143 context: deterministic::Context,
144 ) -> CompactDb<F, deterministic::Context, Digest, Digest, Sha256, ((), ()), Sequential> {
145 let cfg = CompactConfig {
146 strategy: Sequential,
147 witness: crate::journal::contiguous::variable::Config {
148 partition: "compact-immutable-variable-witness".into(),
149 items_per_section: NZU64!(64),
150 compression: None,
151 codec_config: (),
152 page_cache: CacheRef::from_pooler(&context, PAGE_SIZE, PAGE_CACHE_SIZE),
153 write_buffer: NZUsize!(1024),
154 },
155 commit_codec_config: ((), ()),
156 };
157 CompactDb::init(context, cfg).await.unwrap()
158 }
159
160 #[allow(clippy::type_complexity)]
161 fn open<F: Family>(
162 ctx: deterministic::Context,
163 ) -> Pin<
164 Box<
165 dyn Future<
166 Output = Db<
167 F,
168 deterministic::Context,
169 Digest,
170 Digest,
171 Sha256,
172 TwoCap,
173 Sequential,
174 >,
175 > + Send,
176 >,
177 > {
178 Box::pin(open_db::<F>(ctx))
179 }
180
181 fn is_send<T: Send>(_: T) {}
182
183 #[allow(dead_code)]
184 fn assert_db_futures_are_send(
185 db: &mut Db<
186 mmr::Family,
187 deterministic::Context,
188 Digest,
189 Digest,
190 Sha256,
191 TwoCap,
192 Sequential,
193 >,
194 key: Digest,
195 loc: crate::merkle::mmr::Location,
196 ) {
197 is_send(db.get(&key));
198 is_send(db.get_metadata());
199 is_send(db.proof(loc, NZU64!(1)));
200 is_send(db.sync());
201 is_send(db.rewind(loc));
202 }
203
204 fn small_sections_config(
205 suffix: &str,
206 pooler: &impl BufferPooler,
207 ) -> Config<TwoCap, ((), ()), Sequential> {
208 let mut cfg = config(suffix, pooler);
209 cfg.log.items_per_section = NZU64!(1);
210 cfg
211 }
212
213 async fn open_small_sections_db<F: Family>(
214 context: deterministic::Context,
215 ) -> Db<F, deterministic::Context, Digest, Digest, Sha256, TwoCap, Sequential> {
216 let cfg = small_sections_config("partition", &context);
217 Db::init(context, cfg).await.unwrap()
218 }
219
220 #[allow(clippy::type_complexity)]
221 fn open_small_sections<F: Family>(
222 ctx: deterministic::Context,
223 ) -> Pin<
224 Box<
225 dyn Future<
226 Output = Db<
227 F,
228 deterministic::Context,
229 Digest,
230 Digest,
231 Sha256,
232 TwoCap,
233 Sequential,
234 >,
235 > + Send,
236 >,
237 > {
238 Box::pin(open_small_sections_db::<F>(ctx))
239 }
240
241 #[test_traced("WARN")]
242 fn test_variable_empty() {
243 let executor = deterministic::Runner::default();
244 executor.start(|ctx| async move {
245 test::test_immutable_empty(ctx, open::<mmr::Family>).await;
246 });
247 }
248
249 #[test_traced("WARN")]
250 fn test_variable_commit_after_sync_recovery() {
251 let executor = deterministic::Runner::default();
252 executor.start(|ctx| async move {
253 test::test_immutable_commit_after_sync_recovery(ctx, open::<mmr::Family>).await;
254 });
255 }
256
257 #[test_traced("DEBUG")]
258 fn test_variable_build_basic() {
259 let executor = deterministic::Runner::default();
260 executor.start(|ctx| async move {
261 test::test_immutable_build_basic(ctx, open::<mmr::Family>).await;
262 });
263 }
264
265 #[test_traced("WARN")]
266 fn test_variable_proof_verify() {
267 let executor = deterministic::Runner::default();
268 executor.start(|ctx| async move {
269 test::test_immutable_proof_verify(ctx, open::<mmr::Family>).await;
270 });
271 }
272
273 #[test_traced("DEBUG")]
274 fn test_variable_prune() {
275 let executor = deterministic::Runner::default();
276 executor.start(|ctx| async move {
277 test::test_immutable_prune(ctx, open::<mmr::Family>).await;
278 });
279 }
280
281 #[test_traced("DEBUG")]
282 fn test_variable_batch_chain() {
283 let executor = deterministic::Runner::default();
284 executor.start(|ctx| async move {
285 test::test_immutable_batch_chain(ctx, open::<mmr::Family>).await;
286 });
287 }
288
289 #[test_traced("WARN")]
290 fn test_variable_build_and_authenticate() {
291 let executor = deterministic::Runner::default();
292 executor.start(|ctx| async move {
293 test::test_immutable_build_and_authenticate(ctx, open::<mmr::Family>).await;
294 });
295 }
296
297 #[test_traced("WARN")]
298 fn test_variable_recovery_from_failed_merkle_sync() {
299 let executor = deterministic::Runner::default();
300 executor.start(|ctx| async move {
301 test::test_immutable_recovery_from_failed_merkle_sync(ctx, open::<mmr::Family>).await;
302 });
303 }
304
305 #[test_traced("WARN")]
306 fn test_variable_recovery_from_failed_log_sync() {
307 let executor = deterministic::Runner::default();
308 executor.start(|ctx| async move {
309 test::test_immutable_recovery_from_failed_log_sync(ctx, open::<mmr::Family>).await;
310 });
311 }
312
313 #[test_traced("WARN")]
314 fn test_variable_pruning() {
315 let executor = deterministic::Runner::default();
316 executor.start(|ctx| async move {
317 test::test_immutable_pruning(ctx, open::<mmr::Family>).await;
318 });
319 }
320
321 #[test_traced("INFO")]
322 fn test_variable_prune_beyond_floor() {
323 let executor = deterministic::Runner::default();
324 executor.start(|ctx| async move {
325 test::test_immutable_prune_beyond_floor(ctx, open::<mmr::Family>).await;
326 });
327 }
328
329 #[boxed]
330 async fn assert_compact_root_compatibility<F: Family>(ctx: deterministic::Context) {
331 let mut db = open_db::<F>(ctx.child("db")).await;
332 let mut compact = open_compact::<F>(ctx.child("compact")).await;
333 assert_eq!(db.root(), compact.root());
334
335 let k1 = Sha256::fill(1u8);
336 let v1 = Sha256::fill(11u8);
337 let k2 = Sha256::fill(2u8);
338 let v2 = Sha256::fill(22u8);
339 let metadata = Sha256::fill(99u8);
340
341 let floor = db.inactivity_floor_loc();
342 let retained = db
343 .new_batch()
344 .set(k1, v1)
345 .set(k2, v2)
346 .merkleize(&db, Some(metadata), floor)
347 .await;
348 let compact_batch = compact
349 .new_batch()
350 .set(k1, v1)
351 .set(k2, v2)
352 .merkleize(&compact, Some(metadata), floor)
353 .await;
354
355 assert_eq!(retained.root(), compact_batch.root());
356
357 db.apply_batch(retained).await.unwrap();
358 compact.apply_batch(compact_batch).unwrap();
359 db.commit().await.unwrap();
360 compact.sync().await.unwrap();
361
362 assert_eq!(db.root(), compact.root());
363 assert_eq!(compact.get_metadata(), Some(metadata));
364
365 drop(compact);
366 let reopened = open_compact::<F>(ctx.child("reopen")).await;
367 assert_eq!(db.root(), reopened.root());
368 assert_eq!(reopened.get_metadata(), Some(metadata));
369
370 reopened.destroy().await.unwrap();
371 db.destroy().await.unwrap();
372 }
373
374 #[test_traced("INFO")]
375 fn test_variable_compact_root_compatibility() {
376 let executor = deterministic::Runner::default();
377 executor.start(|ctx| async move {
378 assert_compact_root_compatibility::<mmr::Family>(ctx).await;
379 });
380 }
381
382 #[test_traced("INFO")]
383 fn test_variable_compact_root_compatibility_mmb() {
384 let executor = deterministic::Runner::default();
385 executor.start(|ctx| async move {
386 assert_compact_root_compatibility::<mmb::Family>(ctx).await;
387 });
388 }
389
390 #[test_traced("INFO")]
391 fn test_variable_batch_get_read_through() {
392 let executor = deterministic::Runner::default();
393 executor.start(|ctx| async move {
394 test::test_immutable_batch_get_read_through(ctx, open::<mmr::Family>).await;
395 });
396 }
397
398 #[test_traced("INFO")]
399 fn test_variable_batch_stacked_get() {
400 let executor = deterministic::Runner::default();
401 executor.start(|ctx| async move {
402 test::test_immutable_batch_stacked_get(ctx, open::<mmr::Family>).await;
403 });
404 }
405
406 #[test_traced("INFO")]
407 fn test_variable_batch_stacked_apply() {
408 let executor = deterministic::Runner::default();
409 executor.start(|ctx| async move {
410 test::test_immutable_batch_stacked_apply(ctx, open::<mmr::Family>).await;
411 });
412 }
413
414 #[test_traced("INFO")]
415 fn test_variable_batch_speculative_root() {
416 let executor = deterministic::Runner::default();
417 executor.start(|ctx| async move {
418 test::test_immutable_batch_speculative_root(ctx, open::<mmr::Family>).await;
419 });
420 }
421
422 #[test_traced("INFO")]
423 fn test_variable_merkleized_batch_get() {
424 let executor = deterministic::Runner::default();
425 executor.start(|ctx| async move {
426 test::test_immutable_merkleized_batch_get(ctx, open::<mmr::Family>).await;
427 });
428 }
429
430 #[test_traced("INFO")]
431 fn test_variable_batch_sequential_apply() {
432 let executor = deterministic::Runner::default();
433 executor.start(|ctx| async move {
434 test::test_immutable_batch_sequential_apply(ctx, open::<mmr::Family>).await;
435 });
436 }
437
438 #[test_traced("INFO")]
439 fn test_variable_batch_many_sequential() {
440 let executor = deterministic::Runner::default();
441 executor.start(|ctx| async move {
442 test::test_immutable_batch_many_sequential(ctx, open::<mmr::Family>).await;
443 });
444 }
445
446 #[test_traced("INFO")]
447 fn test_variable_batch_empty_batch() {
448 let executor = deterministic::Runner::default();
449 executor.start(|ctx| async move {
450 test::test_immutable_batch_empty_batch(ctx, open::<mmr::Family>).await;
451 });
452 }
453
454 #[test_traced("INFO")]
455 fn test_variable_batch_chained_merkleized_get() {
456 let executor = deterministic::Runner::default();
457 executor.start(|ctx| async move {
458 test::test_immutable_batch_chained_merkleized_get(ctx, open::<mmr::Family>).await;
459 });
460 }
461
462 #[test_traced("INFO")]
463 fn test_variable_batch_large() {
464 let executor = deterministic::Runner::default();
465 executor.start(|ctx| async move {
466 test::test_immutable_batch_large(ctx, open::<mmr::Family>).await;
467 });
468 }
469
470 #[test_traced("INFO")]
471 fn test_variable_batch_chained_key_override() {
472 let executor = deterministic::Runner::default();
473 executor.start(|ctx| async move {
474 test::test_immutable_batch_chained_key_override(ctx, open::<mmr::Family>).await;
475 });
476 }
477
478 #[test_traced("INFO")]
479 fn test_variable_batch_sequential_key_override() {
480 let executor = deterministic::Runner::default();
481 executor.start(|ctx| async move {
482 test::test_immutable_batch_sequential_key_override(
483 ctx,
484 open_small_sections::<mmr::Family>,
485 )
486 .await;
487 });
488 }
489
490 #[test_traced("INFO")]
491 fn test_variable_batch_metadata() {
492 let executor = deterministic::Runner::default();
493 executor.start(|ctx| async move {
494 test::test_immutable_batch_metadata(ctx, open::<mmr::Family>).await;
495 });
496 }
497
498 #[test_traced]
499 fn test_variable_stale_batch_rejected() {
500 let executor = deterministic::Runner::default();
501 executor.start(|ctx| async move {
502 test::test_immutable_stale_batch_rejected(ctx, open::<mmr::Family>).await;
503 });
504 }
505
506 #[test_traced]
507 fn test_variable_stale_batch_chained() {
508 let executor = deterministic::Runner::default();
509 executor.start(|ctx| async move {
510 test::test_immutable_stale_batch_chained(ctx, open::<mmr::Family>).await;
511 });
512 }
513
514 #[test_traced]
515 fn test_variable_sequential_commit_parent_then_child() {
516 let executor = deterministic::Runner::default();
517 executor.start(|ctx| async move {
518 test::test_immutable_sequential_commit_parent_then_child(ctx, open::<mmr::Family>)
519 .await;
520 });
521 }
522
523 #[test_traced]
524 fn test_variable_stale_batch_child_applied_before_parent() {
525 let executor = deterministic::Runner::default();
526 executor.start(|ctx| async move {
527 test::test_immutable_stale_batch_child_applied_before_parent(ctx, open::<mmr::Family>)
528 .await;
529 });
530 }
531
532 #[test_traced]
533 fn test_variable_partial_ancestor_commit() {
534 let executor = deterministic::Runner::default();
535 executor.start(|ctx| async move {
536 test::test_immutable_partial_ancestor_commit(ctx, open::<mmr::Family>).await;
537 });
538 }
539
540 #[test_traced]
541 fn test_variable_child_root_matches_pending_and_committed() {
542 let executor = deterministic::Runner::default();
543 executor.start(|ctx| async move {
544 test::test_immutable_child_root_matches_pending_and_committed(ctx, open::<mmr::Family>)
545 .await;
546 });
547 }
548
549 #[test_traced]
550 fn test_variable_to_batch() {
551 let executor = deterministic::Runner::default();
552 executor.start(|ctx| async move {
553 test::test_immutable_to_batch(ctx, open::<mmr::Family>).await;
554 });
555 }
556
557 #[test_traced("INFO")]
558 fn test_variable_rewind_recovery() {
559 let executor = deterministic::Runner::default();
560 executor.start(|ctx| async move {
561 test::test_immutable_rewind_recovery(ctx, open::<mmr::Family>).await;
562 });
563 }
564
565 #[test_traced("INFO")]
566 fn test_variable_rewind_pruned_target_errors() {
567 let executor = deterministic::Runner::default();
568 executor.start(|ctx| async move {
569 test::test_immutable_rewind_pruned_target_errors(
570 ctx,
571 open_small_sections::<mmr::Family>,
572 )
573 .await;
574 });
575 }
576
577 #[test_traced("INFO")]
578 fn test_variable_get_many() {
579 let executor = deterministic::Runner::default();
580 executor.start(|ctx| async move {
581 test::test_immutable_get_many(ctx, open::<mmr::Family>).await;
582 });
583 }
584
585 #[test_traced("INFO")]
586 fn test_variable_get_many_unexpected_data() {
587 let executor = deterministic::Runner::default();
588 executor.start(|ctx| async move {
589 test::test_immutable_get_many_unexpected_data(ctx, open::<mmr::Family>).await;
590 });
591 }
592
593 #[test_traced("WARN")]
596 fn test_variable_empty_mmb() {
597 let executor = deterministic::Runner::default();
598 executor.start(|ctx| async move {
599 test::test_immutable_empty(ctx, open::<mmb::Family>).await;
600 });
601 }
602
603 #[test_traced("DEBUG")]
604 fn test_variable_build_basic_mmb() {
605 let executor = deterministic::Runner::default();
606 executor.start(|ctx| async move {
607 test::test_immutable_build_basic(ctx, open::<mmb::Family>).await;
608 });
609 }
610
611 #[test_traced("WARN")]
612 fn test_variable_proof_verify_mmb() {
613 let executor = deterministic::Runner::default();
614 executor.start(|ctx| async move {
615 test::test_immutable_proof_verify(ctx, open::<mmb::Family>).await;
616 });
617 }
618
619 #[test_traced("DEBUG")]
620 fn test_variable_prune_mmb() {
621 let executor = deterministic::Runner::default();
622 executor.start(|ctx| async move {
623 test::test_immutable_prune(ctx, open::<mmb::Family>).await;
624 });
625 }
626
627 #[test_traced("DEBUG")]
628 fn test_variable_batch_chain_mmb() {
629 let executor = deterministic::Runner::default();
630 executor.start(|ctx| async move {
631 test::test_immutable_batch_chain(ctx, open::<mmb::Family>).await;
632 });
633 }
634
635 #[test_traced("WARN")]
636 fn test_variable_build_and_authenticate_mmb() {
637 let executor = deterministic::Runner::default();
638 executor.start(|ctx| async move {
639 test::test_immutable_build_and_authenticate(ctx, open::<mmb::Family>).await;
640 });
641 }
642
643 #[test_traced("WARN")]
644 fn test_variable_recovery_from_failed_merkle_sync_mmb() {
645 let executor = deterministic::Runner::default();
646 executor.start(|ctx| async move {
647 test::test_immutable_recovery_from_failed_merkle_sync(ctx, open::<mmb::Family>).await;
648 });
649 }
650
651 #[test_traced("WARN")]
652 fn test_variable_recovery_from_failed_log_sync_mmb() {
653 let executor = deterministic::Runner::default();
654 executor.start(|ctx| async move {
655 test::test_immutable_recovery_from_failed_log_sync(ctx, open::<mmb::Family>).await;
656 });
657 }
658
659 #[test_traced("WARN")]
660 fn test_variable_pruning_mmb() {
661 let executor = deterministic::Runner::default();
662 executor.start(|ctx| async move {
663 test::test_immutable_pruning(ctx, open::<mmb::Family>).await;
664 });
665 }
666
667 #[test_traced("INFO")]
668 fn test_variable_prune_beyond_floor_mmb() {
669 let executor = deterministic::Runner::default();
670 executor.start(|ctx| async move {
671 test::test_immutable_prune_beyond_floor(ctx, open::<mmb::Family>).await;
672 });
673 }
674
675 #[test_traced("INFO")]
676 fn test_variable_batch_get_read_through_mmb() {
677 let executor = deterministic::Runner::default();
678 executor.start(|ctx| async move {
679 test::test_immutable_batch_get_read_through(ctx, open::<mmb::Family>).await;
680 });
681 }
682
683 #[test_traced("INFO")]
684 fn test_variable_batch_stacked_get_mmb() {
685 let executor = deterministic::Runner::default();
686 executor.start(|ctx| async move {
687 test::test_immutable_batch_stacked_get(ctx, open::<mmb::Family>).await;
688 });
689 }
690
691 #[test_traced("INFO")]
692 fn test_variable_batch_stacked_apply_mmb() {
693 let executor = deterministic::Runner::default();
694 executor.start(|ctx| async move {
695 test::test_immutable_batch_stacked_apply(ctx, open::<mmb::Family>).await;
696 });
697 }
698
699 #[test_traced("INFO")]
700 fn test_variable_batch_speculative_root_mmb() {
701 let executor = deterministic::Runner::default();
702 executor.start(|ctx| async move {
703 test::test_immutable_batch_speculative_root(ctx, open::<mmb::Family>).await;
704 });
705 }
706
707 #[test_traced("INFO")]
708 fn test_variable_merkleized_batch_get_mmb() {
709 let executor = deterministic::Runner::default();
710 executor.start(|ctx| async move {
711 test::test_immutable_merkleized_batch_get(ctx, open::<mmb::Family>).await;
712 });
713 }
714
715 #[test_traced("INFO")]
716 fn test_variable_batch_sequential_apply_mmb() {
717 let executor = deterministic::Runner::default();
718 executor.start(|ctx| async move {
719 test::test_immutable_batch_sequential_apply(ctx, open::<mmb::Family>).await;
720 });
721 }
722
723 #[test_traced("INFO")]
724 fn test_variable_batch_many_sequential_mmb() {
725 let executor = deterministic::Runner::default();
726 executor.start(|ctx| async move {
727 test::test_immutable_batch_many_sequential(ctx, open::<mmb::Family>).await;
728 });
729 }
730
731 #[test_traced("INFO")]
732 fn test_variable_batch_empty_batch_mmb() {
733 let executor = deterministic::Runner::default();
734 executor.start(|ctx| async move {
735 test::test_immutable_batch_empty_batch(ctx, open::<mmb::Family>).await;
736 });
737 }
738
739 #[test_traced("INFO")]
740 fn test_variable_batch_chained_merkleized_get_mmb() {
741 let executor = deterministic::Runner::default();
742 executor.start(|ctx| async move {
743 test::test_immutable_batch_chained_merkleized_get(ctx, open::<mmb::Family>).await;
744 });
745 }
746
747 #[test_traced("INFO")]
748 fn test_variable_batch_large_mmb() {
749 let executor = deterministic::Runner::default();
750 executor.start(|ctx| async move {
751 test::test_immutable_batch_large(ctx, open::<mmb::Family>).await;
752 });
753 }
754
755 #[test_traced("INFO")]
756 fn test_variable_batch_chained_key_override_mmb() {
757 let executor = deterministic::Runner::default();
758 executor.start(|ctx| async move {
759 test::test_immutable_batch_chained_key_override(ctx, open::<mmb::Family>).await;
760 });
761 }
762
763 #[test_traced("INFO")]
764 fn test_variable_batch_sequential_key_override_mmb() {
765 let executor = deterministic::Runner::default();
766 executor.start(|ctx| async move {
767 test::test_immutable_batch_sequential_key_override(
768 ctx,
769 open_small_sections::<mmb::Family>,
770 )
771 .await;
772 });
773 }
774
775 #[test_traced("INFO")]
776 fn test_variable_batch_metadata_mmb() {
777 let executor = deterministic::Runner::default();
778 executor.start(|ctx| async move {
779 test::test_immutable_batch_metadata(ctx, open::<mmb::Family>).await;
780 });
781 }
782
783 #[test_traced]
784 fn test_variable_stale_batch_rejected_mmb() {
785 let executor = deterministic::Runner::default();
786 executor.start(|ctx| async move {
787 test::test_immutable_stale_batch_rejected(ctx, open::<mmb::Family>).await;
788 });
789 }
790
791 #[test_traced]
792 fn test_variable_stale_batch_chained_mmb() {
793 let executor = deterministic::Runner::default();
794 executor.start(|ctx| async move {
795 test::test_immutable_stale_batch_chained(ctx, open::<mmb::Family>).await;
796 });
797 }
798
799 #[test_traced]
800 fn test_variable_sequential_commit_parent_then_child_mmb() {
801 let executor = deterministic::Runner::default();
802 executor.start(|ctx| async move {
803 test::test_immutable_sequential_commit_parent_then_child(ctx, open::<mmb::Family>)
804 .await;
805 });
806 }
807
808 #[test_traced]
809 fn test_variable_stale_batch_child_applied_before_parent_mmb() {
810 let executor = deterministic::Runner::default();
811 executor.start(|ctx| async move {
812 test::test_immutable_stale_batch_child_applied_before_parent(ctx, open::<mmb::Family>)
813 .await;
814 });
815 }
816
817 #[test_traced]
818 fn test_variable_child_root_matches_pending_and_committed_mmb() {
819 let executor = deterministic::Runner::default();
820 executor.start(|ctx| async move {
821 test::test_immutable_child_root_matches_pending_and_committed(ctx, open::<mmb::Family>)
822 .await;
823 });
824 }
825
826 #[test_traced]
827 fn test_variable_to_batch_mmb() {
828 let executor = deterministic::Runner::default();
829 executor.start(|ctx| async move {
830 test::test_immutable_to_batch(ctx, open::<mmb::Family>).await;
831 });
832 }
833
834 #[test_traced("INFO")]
835 fn test_variable_rewind_recovery_mmb() {
836 let executor = deterministic::Runner::default();
837 executor.start(|ctx| async move {
838 test::test_immutable_rewind_recovery(ctx, open::<mmb::Family>).await;
839 });
840 }
841
842 #[test_traced("INFO")]
843 fn test_variable_rewind_preserves_collision_bucket_mmb() {
844 let executor = deterministic::Runner::default();
845 executor.start(|ctx| async move {
846 test::test_immutable_rewind_preserves_collision_bucket(ctx, open::<mmb::Family>).await;
847 });
848 }
849
850 #[test_traced("INFO")]
851 fn test_variable_rewind_pruned_target_errors_mmb() {
852 let executor = deterministic::Runner::default();
853 executor.start(|ctx| async move {
854 test::test_immutable_rewind_pruned_target_errors(
855 ctx,
856 open_small_sections::<mmb::Family>,
857 )
858 .await;
859 });
860 }
861
862 #[test_traced("WARN")]
863 fn test_variable_apply_after_ancestor_dropped() {
864 let executor = deterministic::Runner::default();
865 executor.start(|ctx| async move {
866 test::test_immutable_apply_after_ancestor_dropped(ctx, open::<mmr::Family>).await;
867 });
868 }
869
870 #[test_traced("INFO")]
871 fn test_variable_inactivity_floor_tracking() {
872 let executor = deterministic::Runner::default();
873 executor.start(|ctx| async move {
874 test::test_immutable_inactivity_floor_tracking(ctx, open::<mmr::Family>).await;
875 });
876 }
877
878 #[test_traced("INFO")]
879 fn test_variable_floor_monotonicity() {
880 let executor = deterministic::Runner::default();
881 executor.start(|ctx| async move {
882 test::test_immutable_floor_monotonicity(ctx, open::<mmr::Family>).await;
883 });
884 }
885
886 #[test_traced("INFO")]
887 fn test_variable_floor_monotonicity_violation() {
888 let executor = deterministic::Runner::default();
889 executor.start(|ctx| async move {
890 test::test_immutable_floor_monotonicity_violation(ctx, open::<mmr::Family>).await;
891 });
892 }
893
894 #[test_traced("INFO")]
895 fn test_variable_floor_beyond_size() {
896 let executor = deterministic::Runner::default();
897 executor.start(|ctx| async move {
898 test::test_immutable_floor_beyond_size(ctx, open::<mmr::Family>).await;
899 });
900 }
901
902 #[test_traced("INFO")]
903 fn test_variable_chained_ancestor_floor_regression() {
904 let executor = deterministic::Runner::default();
905 executor.start(|ctx| async move {
906 test::test_immutable_chained_ancestor_floor_regression(ctx, open::<mmr::Family>).await;
907 });
908 }
909
910 #[test_traced("INFO")]
911 fn test_variable_chained_ancestor_floor_beyond_size() {
912 let executor = deterministic::Runner::default();
913 executor.start(|ctx| async move {
914 test::test_immutable_chained_ancestor_floor_beyond_size(ctx, open::<mmr::Family>).await;
915 });
916 }
917
918 #[test_traced("INFO")]
919 fn test_variable_rewind_restores_floor() {
920 let executor = deterministic::Runner::default();
921 executor.start(|ctx| async move {
922 test::test_immutable_rewind_restores_floor(ctx, open::<mmr::Family>).await;
923 });
924 }
925
926 #[test_traced("INFO")]
927 fn test_variable_inactivity_floor_tracking_mmb() {
928 let executor = deterministic::Runner::default();
929 executor.start(|ctx| async move {
930 test::test_immutable_inactivity_floor_tracking(ctx, open::<mmb::Family>).await;
931 });
932 }
933
934 #[test_traced("INFO")]
935 fn test_variable_floor_monotonicity_mmb() {
936 let executor = deterministic::Runner::default();
937 executor.start(|ctx| async move {
938 test::test_immutable_floor_monotonicity(ctx, open::<mmb::Family>).await;
939 });
940 }
941
942 #[test_traced("INFO")]
943 fn test_variable_floor_monotonicity_violation_mmb() {
944 let executor = deterministic::Runner::default();
945 executor.start(|ctx| async move {
946 test::test_immutable_floor_monotonicity_violation(ctx, open::<mmb::Family>).await;
947 });
948 }
949
950 #[test_traced("INFO")]
951 fn test_variable_floor_beyond_size_mmb() {
952 let executor = deterministic::Runner::default();
953 executor.start(|ctx| async move {
954 test::test_immutable_floor_beyond_size(ctx, open::<mmb::Family>).await;
955 });
956 }
957
958 #[test_traced("INFO")]
959 fn test_variable_chained_ancestor_floor_regression_mmb() {
960 let executor = deterministic::Runner::default();
961 executor.start(|ctx| async move {
962 test::test_immutable_chained_ancestor_floor_regression(ctx, open::<mmb::Family>).await;
963 });
964 }
965
966 #[test_traced("INFO")]
967 fn test_variable_chained_ancestor_floor_beyond_size_mmb() {
968 let executor = deterministic::Runner::default();
969 executor.start(|ctx| async move {
970 test::test_immutable_chained_ancestor_floor_beyond_size(ctx, open::<mmb::Family>).await;
971 });
972 }
973
974 #[test_traced("INFO")]
975 fn test_variable_rewind_restores_floor_mmb() {
976 let executor = deterministic::Runner::default();
977 executor.start(|ctx| async move {
978 test::test_immutable_rewind_restores_floor(ctx, open::<mmb::Family>).await;
979 });
980 }
981
982 #[test_traced("INFO")]
983 fn test_variable_single_commit_live_set() {
984 let executor = deterministic::Runner::default();
985 executor.start(|ctx| async move {
986 test::test_immutable_single_commit_live_set(ctx, open::<mmr::Family>).await;
987 });
988 }
989
990 #[test_traced("INFO")]
991 fn test_variable_single_commit_live_set_mmb() {
992 let executor = deterministic::Runner::default();
993 executor.start(|ctx| async move {
994 test::test_immutable_single_commit_live_set(ctx, open::<mmb::Family>).await;
995 });
996 }
997
998 #[test_traced("INFO")]
999 fn test_variable_rewind_after_reopen_with_floor_change() {
1000 let executor = deterministic::Runner::default();
1001 executor.start(|ctx| async move {
1002 test::test_immutable_rewind_after_reopen_with_floor_change(ctx, open::<mmr::Family>)
1003 .await;
1004 });
1005 }
1006
1007 #[test_traced("INFO")]
1008 fn test_variable_rewind_after_reopen_with_floor_change_mmb() {
1009 let executor = deterministic::Runner::default();
1010 executor.start(|ctx| async move {
1011 test::test_immutable_rewind_after_reopen_with_floor_change(ctx, open::<mmb::Family>)
1012 .await;
1013 });
1014 }
1015
1016 #[test_traced("INFO")]
1017 fn test_variable_rewind_after_reopen_partial_floor_gap() {
1018 let executor = deterministic::Runner::default();
1019 executor.start(|ctx| async move {
1020 test::test_immutable_rewind_after_reopen_partial_floor_gap(ctx, open::<mmr::Family>)
1021 .await;
1022 });
1023 }
1024
1025 #[test_traced("INFO")]
1026 fn test_variable_rewind_after_reopen_partial_floor_gap_mmb() {
1027 let executor = deterministic::Runner::default();
1028 executor.start(|ctx| async move {
1029 test::test_immutable_rewind_after_reopen_partial_floor_gap(ctx, open::<mmb::Family>)
1030 .await;
1031 });
1032 }
1033
1034 #[test_traced("INFO")]
1035 fn test_variable_rewind_after_reopen_repeated_key_gap() {
1036 let executor = deterministic::Runner::default();
1037 executor.start(|ctx| async move {
1038 test::test_immutable_rewind_after_reopen_repeated_key_gap(ctx, open::<mmb::Family>)
1039 .await;
1040 });
1041 }
1042
1043 #[test_traced("INFO")]
1044 fn test_variable_rewind_after_reopen_mixed_gap_retained() {
1045 let executor = deterministic::Runner::default();
1046 executor.start(|ctx| async move {
1047 test::test_immutable_rewind_after_reopen_mixed_gap_retained(ctx, open::<mmb::Family>)
1048 .await;
1049 });
1050 }
1051}