Skip to main content

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 current;
13pub mod immutable;
14
15/// Database type to sync.
16#[derive(Debug, Clone, Copy)]
17pub enum DatabaseType {
18    Any,
19    Current,
20    Immutable,
21}
22
23impl std::str::FromStr for DatabaseType {
24    type Err = String;
25
26    fn from_str(s: &str) -> Result<Self, Self::Err> {
27        match s.to_lowercase().as_str() {
28            "any" => Ok(Self::Any),
29            "current" => Ok(Self::Current),
30            "immutable" => Ok(Self::Immutable),
31            _ => Err(format!(
32                "Invalid database type: '{s}'. Must be 'any', 'current', or 'immutable'",
33            )),
34        }
35    }
36}
37
38impl DatabaseType {
39    pub const fn as_str(&self) -> &'static str {
40        match self {
41            Self::Any => "any",
42            Self::Current => "current",
43            Self::Immutable => "immutable",
44        }
45    }
46}
47
48/// Helper trait for databases that can be synced.
49pub trait Syncable: Sized {
50    /// The type of operations in the database.
51    type Operation: Operation + Encode + Sync + 'static;
52
53    /// Create test operations with the given count and seed.
54    /// The returned operations must end with a commit operation.
55    fn create_test_operations(count: usize, seed: u64) -> Vec<Self::Operation>;
56
57    /// Add operations to the database, ignoring any input that doesn't end with a commit
58    /// operation.
59    fn add_operations(
60        &mut self,
61        operations: Vec<Self::Operation>,
62    ) -> impl Future<Output = Result<(), qmdb::Error>>;
63
64    /// Get the database's root digest.
65    fn root(&self) -> Key;
66
67    /// Get the total number of operations in the database (including pruned operations).
68    fn size(&self) -> impl Future<Output = Location> + Send;
69
70    /// Get the inactivity floor, the location below which all operations are inactive.
71    fn inactivity_floor(&self) -> impl Future<Output = Location> + Send;
72
73    /// Get historical proof and operations.
74    fn historical_proof(
75        &self,
76        op_count: Location,
77        start_loc: Location,
78        max_ops: NonZeroU64,
79    ) -> impl Future<Output = Result<(Proof<Key>, Vec<Self::Operation>), qmdb::Error>> + Send;
80
81    /// Get the database type name for logging.
82    fn name() -> &'static str;
83}