-
Notifications
You must be signed in to change notification settings - Fork 220
Expand file tree
/
Copy pathmod.rs
More file actions
105 lines (89 loc) · 3.1 KB
/
mod.rs
File metadata and controls
105 lines (89 loc) · 3.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
//! Database-specific modules for the sync example.
use crate::Key;
use commonware_codec::Encode;
use commonware_storage::{
merkle::{self, Location, Proof},
qmdb,
};
use std::{future::Future, num::NonZeroU64};
pub mod any;
pub mod current;
pub mod immutable;
pub mod keyless;
/// Database type to sync.
#[derive(Debug, Clone, Copy)]
pub enum DatabaseType {
Any,
Current,
Immutable,
Keyless,
}
impl std::str::FromStr for DatabaseType {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.to_lowercase().as_str() {
"any" => Ok(Self::Any),
"current" => Ok(Self::Current),
"immutable" => Ok(Self::Immutable),
"keyless" => Ok(Self::Keyless),
_ => Err(format!(
"Invalid database type: '{s}'. Must be 'any', 'current', 'immutable', or 'keyless'",
)),
}
}
}
impl DatabaseType {
pub const fn as_str(&self) -> &'static str {
match self {
Self::Any => "any",
Self::Current => "current",
Self::Immutable => "immutable",
Self::Keyless => "keyless",
}
}
}
/// Helper trait for databases that can be synced.
#[allow(clippy::type_complexity)]
pub trait Syncable: Sized {
/// The merkle family used by this database.
type Family: merkle::Family;
/// The type of operations in the database.
type Operation: Encode + Sync + 'static;
/// Create test operations with the given count and seed.
/// The returned operations must end with a commit operation.
fn create_test_operations(count: usize, seed: u64) -> Vec<Self::Operation>;
/// Add operations to the database, ignoring any input that doesn't end with a commit
/// operation.
fn add_operations(
&mut self,
operations: Vec<Self::Operation>,
) -> impl Future<Output = Result<(), qmdb::Error<Self::Family>>>;
/// Get the database's root digest.
fn root(&self) -> Key;
/// Get the total number of operations in the database (including pruned operations).
fn size(&self) -> impl Future<Output = Location<Self::Family>> + Send;
/// Get the most recent location from which this database can safely be synced.
///
/// Callers constructing a sync target should use this value (or any earlier retained
/// location) as the `range.start`.
fn sync_boundary(&self) -> impl Future<Output = Location<Self::Family>> + Send;
/// Get historical proof and operations.
fn historical_proof(
&self,
op_count: Location<Self::Family>,
start_loc: Location<Self::Family>,
max_ops: NonZeroU64,
) -> impl Future<
Output = Result<
(Proof<Self::Family, Key>, Vec<Self::Operation>),
qmdb::Error<Self::Family>,
>,
> + Send;
/// Get the pinned nodes for a lower operation boundary of `loc`.
fn pinned_nodes_at(
&self,
loc: Location<Self::Family>,
) -> impl Future<Output = Result<Vec<Key>, qmdb::Error<Self::Family>>> + Send;
/// Get the database type name for logging.
fn name() -> &'static str;
}