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