commonware_storage/qmdb/store/
mod.rs1use crate::{
10 mmr::{Location, Proof},
11 qmdb::Error,
12};
13use commonware_codec::CodecShared;
14use commonware_cryptography::Digest;
15use core::future::Future;
16use std::num::NonZeroU64;
17
18pub mod db;
19
20pub trait LogStore: Send + Sync {
22 type Value: CodecShared + Clone;
23
24 fn bounds(&self) -> impl Future<Output = std::ops::Range<Location>> + Send;
27
28 fn size(&self) -> impl Future<Output = Location> + Send {
30 async { self.bounds().await.end }
31 }
32
33 fn get_metadata(&self) -> impl Future<Output = Result<Option<Self::Value>, Error>> + Send;
35}
36
37pub trait PrunableStore: LogStore {
39 fn prune(&mut self, loc: Location) -> impl Future<Output = Result<(), Error>> + Send;
41
42 fn inactivity_floor_loc(&self) -> impl Future<Output = Location> + Send;
45}
46
47pub trait MerkleizedStore: LogStore {
49 type Digest: Digest;
51
52 type Operation;
54
55 fn root(&self) -> Self::Digest;
57
58 #[allow(clippy::type_complexity)]
70 fn proof(
71 &self,
72 start_loc: Location,
73 max_ops: NonZeroU64,
74 ) -> impl Future<Output = Result<(Proof<Self::Digest>, Vec<Self::Operation>), Error>> + Send
75 {
76 async move {
77 self.historical_proof(self.bounds().await.end, start_loc, max_ops)
78 .await
79 }
80 }
81
82 #[allow(clippy::type_complexity)]
96 fn historical_proof(
97 &self,
98 historical_size: Location,
99 start_loc: Location,
100 max_ops: NonZeroU64,
101 ) -> impl Future<Output = Result<(Proof<Self::Digest>, Vec<Self::Operation>), Error>> + Send;
102}
103
104#[cfg(test)]
105pub(crate) mod tests {
106 use super::{LogStore, MerkleizedStore, PrunableStore};
107 use crate::mmr::Location;
108 use commonware_codec::Codec;
109 use commonware_cryptography::{sha256, Hasher};
110 use commonware_utils::{Array, NZU64};
111 use core::fmt::Debug;
112
113 pub fn assert_send<T: Send>(_: T) {}
114
115 #[allow(dead_code)]
116 pub fn assert_log_store<T: LogStore>(db: &T) {
117 assert_send(db.get_metadata());
118 }
119
120 #[allow(dead_code)]
121 pub fn assert_prunable_store<T: PrunableStore>(db: &mut T, loc: Location) {
122 assert_send(db.prune(loc));
123 }
124
125 #[allow(dead_code)]
126 pub fn assert_merkleized_store<T: MerkleizedStore>(db: &T, loc: Location) {
127 assert_send(db.proof(loc, NZU64!(1)));
128 }
129
130 pub trait TestKey: Array + Copy + Send + Sync {
131 fn from_seed(seed: u64) -> Self;
132 }
133
134 pub trait TestValue: Codec + Eq + PartialEq + Debug + Send + Sync {
135 fn from_seed(seed: u64) -> Self;
136 }
137
138 impl TestKey for sha256::Digest {
139 fn from_seed(seed: u64) -> Self {
140 commonware_cryptography::Sha256::hash(&seed.to_be_bytes())
141 }
142 }
143
144 impl<D: TestKey> TestValue for D {
145 fn from_seed(seed: u64) -> Self {
146 D::from_seed(seed)
147 }
148 }
149
150 impl TestValue for Vec<u8> {
151 fn from_seed(seed: u64) -> Self {
152 vec![seed as u8; 32]
153 }
154 }
155}