commonware_sync/databases/
mod.rs

1//! Database-specific modules for the sync example.
2
3use crate::Key;
4use commonware_codec::Encode;
5use commonware_storage::{
6    mmr::{Location, Proof},
7    qmdb::{self, operation::Operation},
8};
9use std::{future::Future, num::NonZeroU64};
10
11pub mod any;
12pub mod immutable;
13
14/// Database type to sync.
15#[derive(Debug, Clone, Copy)]
16pub enum DatabaseType {
17    Any,
18    Immutable,
19}
20
21impl std::str::FromStr for DatabaseType {
22    type Err = String;
23
24    fn from_str(s: &str) -> Result<Self, Self::Err> {
25        match s.to_lowercase().as_str() {
26            "any" => Ok(Self::Any),
27            "immutable" => Ok(Self::Immutable),
28            _ => Err(format!(
29                "Invalid database type: '{s}'. Must be 'any' or 'immutable'",
30            )),
31        }
32    }
33}
34
35impl DatabaseType {
36    pub const fn as_str(&self) -> &'static str {
37        match self {
38            Self::Any => "any",
39            Self::Immutable => "immutable",
40        }
41    }
42}
43
44/// Helper trait for databases that can be synced.
45pub trait Syncable: Sized {
46    /// The type of operations in the database.
47    type Operation: Operation + Encode + Sync + 'static;
48
49    /// Create test operations with the given count and seed.
50    /// The returned operations must end with a commit operation.
51    fn create_test_operations(count: usize, seed: u64) -> Vec<Self::Operation>;
52
53    /// Add operations to the database and return the clean database, ignoring any input that
54    /// doesn't end with a commit operation (since without a commit, we can't return a clean DB).
55    fn add_operations(
56        self,
57        operations: Vec<Self::Operation>,
58    ) -> impl Future<Output = Result<Self, qmdb::Error>>;
59
60    /// Get the database's root digest.
61    fn root(&self) -> Key;
62
63    /// Get the operation count of the database.
64    fn op_count(&self) -> Location;
65
66    /// Get the lower bound for operations (inactivity floor or oldest retained location).
67    fn lower_bound(&self) -> Location;
68
69    /// Get historical proof and operations.
70    fn historical_proof(
71        &self,
72        op_count: Location,
73        start_loc: Location,
74        max_ops: NonZeroU64,
75    ) -> impl Future<Output = Result<(Proof<Key>, Vec<Self::Operation>), qmdb::Error>> + Send;
76
77    /// Get the database type name for logging.
78    fn name() -> &'static str;
79}