//! An immutable authenticated database with fixed-size values. //! //! For variable-size values, use [super::variable] instead. use super::{operation::Operation as BaseOperation, Config as BaseConfig, Immutable}; use crate::{ journal::{ authenticated, contiguous::fixed::{self, Config as JournalConfig}, }, merkle::Family, qmdb::{ any::{value::FixedEncoding, FixedValue}, Error, ROOT_BAGGING, }, translator::Translator, }; use commonware_cryptography::Hasher; use commonware_parallel::Strategy; use commonware_runtime::{Clock, Metrics, Storage}; use commonware_utils::Array; /// Type alias for a fixed-size operation. pub type Operation = BaseOperation>; /// Type alias for the fixed-size immutable database. pub type Db = Immutable, fixed::Journal>, H, T, S>; /// Type alias for the fixed-size compact immutable db. pub type CompactDb = super::CompactDb, H, (), S>; type Journal = authenticated::Journal>, H, S>; /// Configuration for a fixed-size immutable authenticated db. pub type Config = BaseConfig; /// Configuration for a fixed-size compact immutable db. pub type CompactConfig = super::CompactConfig<(), S>; impl< F: Family, E: Storage + Clock + Metrics, K: Array, V: FixedValue, H: Hasher, T: Translator, S: Strategy, > Db { /// Returns a [Db] initialized from `cfg`. Any uncommitted log operations will be /// discarded and the state of the db will be as of the last committed operation. pub async fn init(context: E, cfg: Config) -> Result> { let journal: Journal = Journal::new( context.child("journal"), cfg.merkle_config, cfg.log, Operation::::is_commit, ROOT_BAGGING, ) .await?; Self::init_from_journal(journal, context, cfg.translator).await } } impl CompactDb { /// Returns a [CompactDb] initialized from `cfg`. pub async fn init(context: E, cfg: CompactConfig) -> Result> { let merkle = crate::merkle::compact::Merkle::init(context, cfg.merkle).await?; Self::init_from_merkle(merkle, ()).await } } #[cfg(test)] mod tests { use super::*; use crate::{ merkle::{full::Config as MmrConfig, mmb, mmr}, qmdb::immutable::test, translator::TwoCap, }; use commonware_cryptography::{sha256::Digest, Sha256}; use commonware_macros::test_traced; use commonware_parallel::Sequential; use commonware_runtime::{ buffer::paged::CacheRef, deterministic, BufferPooler, Metrics, Runner as _, Supervisor as _, }; use commonware_utils::{NZUsize, NZU16, NZU64}; use core::{future::Future, pin::Pin}; use std::num::{NonZeroU16, NonZeroUsize}; const PAGE_SIZE: NonZeroU16 = NZU16!(77); const PAGE_CACHE_SIZE: NonZeroUsize = NZUsize!(9); fn config(suffix: &str, pooler: &impl BufferPooler) -> Config { let page_cache = CacheRef::from_pooler(pooler, PAGE_SIZE, PAGE_CACHE_SIZE); Config { merkle_config: MmrConfig { journal_partition: format!("journal-{suffix}"), metadata_partition: format!("metadata-{suffix}"), items_per_blob: NZU64!(11), write_buffer: NZUsize!(1024), strategy: Sequential, page_cache: page_cache.clone(), }, log: JournalConfig { items_per_blob: NZU64!(5), partition: format!("log-{suffix}"), page_cache, write_buffer: NZUsize!(1024), }, translator: TwoCap, } } async fn open_db( context: deterministic::Context, ) -> Db { let cfg = config("partition", &context); Db::init(context, cfg).await.unwrap() } async fn open_compact( context: deterministic::Context, ) -> CompactDb { let cfg = CompactConfig { merkle: crate::merkle::compact::Config { partition: "compact-immutable-fixed".into(), strategy: Sequential, }, commit_codec_config: (), }; CompactDb::init(context, cfg).await.unwrap() } #[test_traced("INFO")] fn test_immutable_fixed_metrics() { deterministic::Runner::default().start(|ctx| async move { let mut db = open_db::(ctx.child("db")).await; let key = Sha256::fill(1u8); let value = Sha256::fill(2u8); let floor = db.inactivity_floor_loc(); let batch = db.new_batch().set(key, value).merkleize(&db, None, floor); db.apply_batch(batch).await.unwrap(); assert_eq!(db.get(&key).await.unwrap(), Some(value)); assert_eq!(db.get_many(&[&key]).await.unwrap(), vec![Some(value)]); db.commit().await.unwrap(); db.sync().await.unwrap(); db.prune(crate::merkle::Location::new(0)).await.unwrap(); let metrics = ctx.encode(); for expected in [ "db_size 3", "db_pruning_boundary 0", "db_retained 3", "db_inactivity_floor 0", "db_last_commit 2", "db_get_calls_total 1", "db_get_many_calls_total 1", "db_keys_requested_total 2", "db_apply_batch_calls_total 1", "db_operations_applied_total 2", "db_commit_calls_total 1", "db_sync_calls_total 1", "db_prune_calls_total 1", "db_get_duration_count 1", "db_get_many_duration_count 1", "db_apply_batch_duration_count 1", "db_commit_duration_count 1", "db_sync_duration_count 1", "db_prune_duration_count 1", ] { assert!(metrics.contains(expected), "missing {expected}\n{metrics}"); } }); } #[allow(clippy::type_complexity)] fn open( ctx: deterministic::Context, ) -> Pin< Box< dyn Future< Output = Db< F, deterministic::Context, Digest, Digest, Sha256, TwoCap, Sequential, >, > + Send, >, > { Box::pin(open_db::(ctx)) } fn is_send(_: T) {} #[allow(dead_code)] fn assert_db_futures_are_send( db: &mut Db< mmr::Family, deterministic::Context, Digest, Digest, Sha256, TwoCap, Sequential, >, key: Digest, loc: crate::merkle::mmr::Location, ) { is_send(db.get(&key)); is_send(db.get_metadata()); is_send(db.proof(loc, NZU64!(1))); is_send(db.sync()); is_send(db.rewind(loc)); } fn small_sections_config( suffix: &str, pooler: &impl BufferPooler, ) -> Config { let mut cfg = config(suffix, pooler); cfg.log.items_per_blob = NZU64!(1); cfg } async fn open_small_sections_db( context: deterministic::Context, ) -> Db { let cfg = small_sections_config("partition", &context); Db::init(context, cfg).await.unwrap() } #[allow(clippy::type_complexity)] fn open_small_sections( ctx: deterministic::Context, ) -> Pin< Box< dyn Future< Output = Db< F, deterministic::Context, Digest, Digest, Sha256, TwoCap, Sequential, >, > + Send, >, > { Box::pin(open_small_sections_db::(ctx)) } #[test_traced("WARN")] fn test_fixed_empty() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_empty(ctx, open::).await; }); } #[test_traced("DEBUG")] fn test_fixed_build_basic() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_build_basic(ctx, open::).await; }); } #[test_traced("WARN")] fn test_fixed_proof_verify() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_proof_verify(ctx, open::).await; }); } #[test_traced("DEBUG")] fn test_fixed_prune() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_prune(ctx, open::).await; }); } #[test_traced("DEBUG")] fn test_fixed_batch_chain() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_batch_chain(ctx, open::).await; }); } #[test_traced("WARN")] fn test_fixed_build_and_authenticate() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_build_and_authenticate(ctx, open::).await; }); } #[test_traced("WARN")] fn test_fixed_recovery_from_failed_merkle_sync() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_recovery_from_failed_merkle_sync(ctx, open::).await; }); } #[test_traced("WARN")] fn test_fixed_recovery_from_failed_log_sync() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_recovery_from_failed_log_sync(ctx, open::).await; }); } #[test_traced("WARN")] fn test_fixed_pruning() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_pruning(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_prune_beyond_floor() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_prune_beyond_floor(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_batch_get_read_through() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_batch_get_read_through(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_batch_stacked_get() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_batch_stacked_get(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_batch_stacked_apply() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_batch_stacked_apply(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_batch_speculative_root() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_batch_speculative_root(ctx, open::).await; }); } async fn assert_compact_root_compatibility(ctx: deterministic::Context) { let mut db = open_db::(ctx.child("db")).await; let mut compact = open_compact::(ctx.child("compact")).await; assert_eq!(db.root(), compact.root()); let k1 = Sha256::fill(1u8); let v1 = Sha256::fill(11u8); let k2 = Sha256::fill(2u8); let v2 = Sha256::fill(22u8); let metadata = Sha256::fill(99u8); let floor = db.inactivity_floor_loc(); let retained = db .new_batch() .set(k1, v1) .set(k2, v2) .merkleize(&db, Some(metadata), floor); let compact_batch = compact .new_batch() .set(k1, v1) .set(k2, v2) .merkleize(&compact, Some(metadata), floor); assert_eq!(retained.root(), compact_batch.root()); db.apply_batch(retained).await.unwrap(); compact.apply_batch(compact_batch).unwrap(); db.commit().await.unwrap(); compact.commit().await.unwrap(); assert_eq!(db.root(), compact.root()); assert_eq!(compact.get_metadata(), Some(metadata)); drop(compact); let reopened = open_compact::(ctx.child("reopen")).await; assert_eq!(db.root(), reopened.root()); assert_eq!(reopened.get_metadata(), Some(metadata)); reopened.destroy().await.unwrap(); db.destroy().await.unwrap(); } #[test_traced("INFO")] fn test_fixed_compact_root_compatibility() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { assert_compact_root_compatibility::(ctx).await; }); } #[test_traced("INFO")] fn test_fixed_compact_root_compatibility_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { assert_compact_root_compatibility::(ctx).await; }); } #[test_traced("INFO")] fn test_fixed_merkleized_batch_get() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_merkleized_batch_get(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_batch_sequential_apply() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_batch_sequential_apply(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_batch_many_sequential() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_batch_many_sequential(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_batch_empty_batch() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_batch_empty_batch(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_batch_chained_merkleized_get() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_batch_chained_merkleized_get(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_batch_large() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_batch_large(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_batch_chained_key_override() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_batch_chained_key_override(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_batch_sequential_key_override() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_batch_sequential_key_override( ctx, open_small_sections::, ) .await; }); } #[test_traced("INFO")] fn test_fixed_batch_metadata() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_batch_metadata(ctx, open::).await; }); } #[test_traced] fn test_fixed_stale_batch_rejected() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_stale_batch_rejected(ctx, open::).await; }); } #[test_traced] fn test_fixed_stale_batch_chained() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_stale_batch_chained(ctx, open::).await; }); } #[test_traced] fn test_fixed_sequential_commit_parent_then_child() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_sequential_commit_parent_then_child(ctx, open::) .await; }); } #[test_traced] fn test_fixed_stale_batch_child_applied_before_parent() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_stale_batch_child_applied_before_parent(ctx, open::) .await; }); } #[test_traced] fn test_fixed_child_root_matches_pending_and_committed() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_child_root_matches_pending_and_committed(ctx, open::) .await; }); } #[test_traced] fn test_fixed_to_batch() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_to_batch(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_rewind_recovery() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_rewind_recovery(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_rewind_preserves_collision_bucket() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_rewind_preserves_collision_bucket(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_rewind_pruned_target_errors() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_rewind_pruned_target_errors( ctx, open_small_sections::, ) .await; }); } #[test_traced("INFO")] fn test_fixed_get_many() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_get_many(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_get_many_unexpected_data() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_get_many_unexpected_data(ctx, open::).await; }); } // -- MMB test wrappers -- #[test_traced("WARN")] fn test_fixed_empty_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_empty(ctx, open::).await; }); } #[test_traced("DEBUG")] fn test_fixed_build_basic_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_build_basic(ctx, open::).await; }); } #[test_traced("WARN")] fn test_fixed_proof_verify_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_proof_verify(ctx, open::).await; }); } #[test_traced("DEBUG")] fn test_fixed_prune_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_prune(ctx, open::).await; }); } #[test_traced("DEBUG")] fn test_fixed_batch_chain_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_batch_chain(ctx, open::).await; }); } #[test_traced("WARN")] fn test_fixed_build_and_authenticate_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_build_and_authenticate(ctx, open::).await; }); } #[test_traced("WARN")] fn test_fixed_recovery_from_failed_merkle_sync_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_recovery_from_failed_merkle_sync(ctx, open::).await; }); } #[test_traced("WARN")] fn test_fixed_recovery_from_failed_log_sync_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_recovery_from_failed_log_sync(ctx, open::).await; }); } #[test_traced("WARN")] fn test_fixed_pruning_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_pruning(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_prune_beyond_floor_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_prune_beyond_floor(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_batch_get_read_through_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_batch_get_read_through(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_batch_stacked_get_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_batch_stacked_get(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_batch_stacked_apply_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_batch_stacked_apply(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_batch_speculative_root_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_batch_speculative_root(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_merkleized_batch_get_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_merkleized_batch_get(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_batch_sequential_apply_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_batch_sequential_apply(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_batch_many_sequential_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_batch_many_sequential(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_batch_empty_batch_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_batch_empty_batch(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_batch_chained_merkleized_get_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_batch_chained_merkleized_get(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_batch_large_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_batch_large(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_batch_chained_key_override_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_batch_chained_key_override(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_batch_sequential_key_override_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_batch_sequential_key_override( ctx, open_small_sections::, ) .await; }); } #[test_traced("INFO")] fn test_fixed_batch_metadata_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_batch_metadata(ctx, open::).await; }); } #[test_traced] fn test_fixed_stale_batch_rejected_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_stale_batch_rejected(ctx, open::).await; }); } #[test_traced] fn test_fixed_stale_batch_chained_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_stale_batch_chained(ctx, open::).await; }); } #[test_traced] fn test_fixed_sequential_commit_parent_then_child_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_sequential_commit_parent_then_child(ctx, open::) .await; }); } #[test_traced] fn test_fixed_stale_batch_child_applied_before_parent_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_stale_batch_child_applied_before_parent(ctx, open::) .await; }); } #[test_traced] fn test_fixed_child_root_matches_pending_and_committed_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_child_root_matches_pending_and_committed(ctx, open::) .await; }); } #[test_traced] fn test_fixed_to_batch_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_to_batch(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_rewind_recovery_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_rewind_recovery(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_rewind_pruned_target_errors_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_rewind_pruned_target_errors( ctx, open_small_sections::, ) .await; }); } #[test_traced("INFO")] fn test_fixed_inactivity_floor_tracking() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_inactivity_floor_tracking(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_floor_monotonicity() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_floor_monotonicity(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_floor_monotonicity_violation() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_floor_monotonicity_violation(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_floor_beyond_size() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_floor_beyond_size(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_chained_ancestor_floor_regression() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_chained_ancestor_floor_regression(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_chained_ancestor_floor_beyond_size() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_chained_ancestor_floor_beyond_size(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_rewind_restores_floor() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_rewind_restores_floor(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_inactivity_floor_tracking_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_inactivity_floor_tracking(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_floor_monotonicity_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_floor_monotonicity(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_floor_monotonicity_violation_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_floor_monotonicity_violation(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_floor_beyond_size_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_floor_beyond_size(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_chained_ancestor_floor_regression_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_chained_ancestor_floor_regression(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_chained_ancestor_floor_beyond_size_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_chained_ancestor_floor_beyond_size(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_rewind_restores_floor_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_rewind_restores_floor(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_single_commit_live_set() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_single_commit_live_set(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_single_commit_live_set_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_single_commit_live_set(ctx, open::).await; }); } #[test_traced("INFO")] fn test_fixed_rewind_after_reopen_with_floor_change() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_rewind_after_reopen_with_floor_change(ctx, open::) .await; }); } #[test_traced("INFO")] fn test_fixed_rewind_after_reopen_with_floor_change_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_rewind_after_reopen_with_floor_change(ctx, open::) .await; }); } #[test_traced("INFO")] fn test_fixed_rewind_after_reopen_partial_floor_gap() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_rewind_after_reopen_partial_floor_gap(ctx, open::) .await; }); } #[test_traced("INFO")] fn test_fixed_rewind_after_reopen_partial_floor_gap_mmb() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_rewind_after_reopen_partial_floor_gap(ctx, open::) .await; }); } #[test_traced("INFO")] fn test_fixed_rewind_after_reopen_repeated_key_gap() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_rewind_after_reopen_repeated_key_gap(ctx, open::) .await; }); } #[test_traced("INFO")] fn test_fixed_rewind_after_reopen_mixed_gap_retained() { let executor = deterministic::Runner::default(); executor.start(|ctx| async move { test::test_immutable_rewind_after_reopen_mixed_gap_retained(ctx, open::) .await; }); } }