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