//! Compact keyless database types and helpers for compact sync demonstration. use crate::{Hasher, Key, Value}; use commonware_parallel::Sequential; use commonware_runtime::{BufferPooler, Clock, Metrics, Storage}; use commonware_storage::{ merkle::{ compact::Config as MerkleConfig, mmr::{self}, }, qmdb::{ self, keyless::fixed::{self, CompactConfig}, sync::compact, }, }; use tracing::error; /// Database type alias. pub type Database = fixed::CompactDb; /// Operation type alias. pub type Operation = fixed::Operation; /// Create a database configuration for the compact keyless variant. pub fn create_config(_context: &impl BufferPooler) -> CompactConfig { CompactConfig { merkle: MerkleConfig { partition: "compact-keyless".into(), strategy: Sequential, }, commit_codec_config: (), } } impl super::ExampleDatabase for Database where E: Storage + Clock + Metrics, { type Family = mmr::Family; type Operation = Operation; fn create_test_operations(count: usize, seed: u64, starting_loc: u64) -> Vec { super::keyless::create_test_operations(count, seed, starting_loc) } async fn add_operations( &mut self, operations: Vec, ) -> Result<(), qmdb::Error> { let Some(last) = operations.last() else { error!("operations must end with a commit"); return Ok(()); }; if !matches!(last, Operation::Commit(..)) { error!("operations must end with a commit"); return Ok(()); } let mut batch = self.new_batch(); for operation in operations { match operation { Operation::Append(value) => { batch = batch.append(value); } Operation::Commit(metadata, floor) => { let merkleized = batch.merkleize(self, metadata, floor); self.apply_batch(merkleized)?; self.commit().await?; batch = self.new_batch(); } } } Ok(()) } fn current_floor(&self) -> u64 { *Self::last_commit_loc(self) } fn root(&self) -> Key { Self::root(self) } fn name() -> &'static str { "compact keyless" } } impl super::CompactSyncable for Database where E: Storage + Clock + Metrics, { async fn current_target(&self) -> compact::Target { Self::current_target(self) } }