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