//! Database-specific modules for the sync example. use crate::Key; use commonware_codec::Encode; use commonware_storage::{ mmr::{Location, Proof}, qmdb::{self, operation::Operation}, }; use std::{future::Future, num::NonZeroU64}; pub mod any; pub mod immutable; /// Database type to sync. #[derive(Debug, Clone, Copy)] pub enum DatabaseType { Any, Immutable, } impl std::str::FromStr for DatabaseType { type Err = String; fn from_str(s: &str) -> Result { match s.to_lowercase().as_str() { "any" => Ok(Self::Any), "immutable" => Ok(Self::Immutable), _ => Err(format!( "Invalid database type: '{s}'. Must be 'any' or 'immutable'", )), } } } impl DatabaseType { pub const fn as_str(&self) -> &'static str { match self { Self::Any => "any", Self::Immutable => "immutable", } } } /// Helper trait for databases that can be synced. pub trait Syncable { /// The type of operations in the database. type Operation: Operation + Encode + Sync + 'static; /// Create test operations with the given count and seed. fn create_test_operations(count: usize, seed: u64) -> Vec; /// Add operations to the database. fn add_operations( database: &mut Self, operations: Vec, ) -> impl Future>; /// Commit pending operations to the database. fn commit(&mut self) -> impl Future>; /// Get the database's root digest. fn root(&self) -> Key; /// Get the operation count of the database. fn op_count(&self) -> Location; /// Get the lower bound for operations (inactivity floor or oldest retained location). fn lower_bound(&self) -> Location; /// Get historical proof and operations. fn historical_proof( &self, op_count: Location, start_loc: Location, max_ops: NonZeroU64, ) -> impl Future, Vec), qmdb::Error>> + Send; /// Get the database type name for logging. fn name() -> &'static str; }