commonware_storage/qmdb/any/
mod.rs1use crate::{
13 journal::{
14 authenticated,
15 contiguous::fixed::{Config as JConfig, Journal},
16 },
17 mmr::journaled::Config as MmrConfig,
18 qmdb::{operation::Committable, Error, Merkleized},
19 translator::Translator,
20};
21use commonware_codec::CodecFixedShared;
22use commonware_cryptography::Hasher;
23use commonware_parallel::ThreadPool;
24use commonware_runtime::{buffer::PoolRef, Clock, Metrics, Storage};
25use std::num::{NonZeroU64, NonZeroUsize};
26
27pub(crate) mod db;
28mod operation;
29#[cfg(any(test, feature = "test-traits"))]
30pub mod states;
31mod value;
32pub(crate) use value::{FixedValue, ValueEncoding, VariableValue};
33pub mod ordered;
34pub mod unordered;
35
36#[derive(Clone)]
38pub struct FixedConfig<T: Translator> {
39 pub mmr_journal_partition: String,
41
42 pub mmr_items_per_blob: NonZeroU64,
44
45 pub mmr_write_buffer: NonZeroUsize,
47
48 pub mmr_metadata_partition: String,
50
51 pub log_journal_partition: String,
53
54 pub log_items_per_blob: NonZeroU64,
56
57 pub log_write_buffer: NonZeroUsize,
59
60 pub translator: T,
62
63 pub thread_pool: Option<ThreadPool>,
65
66 pub buffer_pool: PoolRef,
68}
69
70#[derive(Clone)]
72pub struct VariableConfig<T: Translator, C> {
73 pub mmr_journal_partition: String,
75
76 pub mmr_items_per_blob: NonZeroU64,
78
79 pub mmr_write_buffer: NonZeroUsize,
81
82 pub mmr_metadata_partition: String,
84
85 pub log_partition: String,
87
88 pub log_write_buffer: NonZeroUsize,
90
91 pub log_compression: Option<u8>,
93
94 pub log_codec_config: C,
96
97 pub log_items_per_blob: NonZeroU64,
99
100 pub translator: T,
102
103 pub thread_pool: Option<ThreadPool>,
105
106 pub buffer_pool: PoolRef,
108}
109
110type AuthenticatedLog<E, O, H, S = Merkleized<H>> = authenticated::Journal<E, Journal<E, O>, H, S>;
111
112pub(crate) async fn init_fixed_authenticated_log<
115 E: Storage + Clock + Metrics,
116 O: Committable + CodecFixedShared,
117 H: Hasher,
118 T: Translator,
119>(
120 context: E,
121 cfg: FixedConfig<T>,
122) -> Result<AuthenticatedLog<E, O, H>, Error> {
123 let mmr_config = MmrConfig {
124 journal_partition: cfg.mmr_journal_partition,
125 metadata_partition: cfg.mmr_metadata_partition,
126 items_per_blob: cfg.mmr_items_per_blob,
127 write_buffer: cfg.mmr_write_buffer,
128 thread_pool: cfg.thread_pool,
129 buffer_pool: cfg.buffer_pool.clone(),
130 };
131
132 let journal_config = JConfig {
133 partition: cfg.log_journal_partition,
134 items_per_blob: cfg.log_items_per_blob,
135 write_buffer: cfg.log_write_buffer,
136 buffer_pool: cfg.buffer_pool,
137 };
138
139 let log = AuthenticatedLog::new(
140 context.with_label("log"),
141 mmr_config,
142 journal_config,
143 O::is_commit,
144 )
145 .await?;
146
147 Ok(log)
148}
149
150#[cfg(test)]
151pub(crate) mod test {
153 use super::*;
154 use crate::{
155 qmdb::any::{FixedConfig, VariableConfig},
156 translator::TwoCap,
157 };
158 use commonware_utils::{NZUsize, NZU16, NZU64};
159 use std::num::NonZeroU16;
160
161 const PAGE_SIZE: NonZeroU16 = NZU16!(101);
163 const PAGE_CACHE_SIZE: NonZeroUsize = NZUsize!(11);
164
165 pub(super) fn fixed_db_config(suffix: &str) -> FixedConfig<TwoCap> {
166 FixedConfig {
167 mmr_journal_partition: format!("journal_{suffix}"),
168 mmr_metadata_partition: format!("metadata_{suffix}"),
169 mmr_items_per_blob: NZU64!(11),
170 mmr_write_buffer: NZUsize!(1024),
171 log_journal_partition: format!("log_journal_{suffix}"),
172 log_items_per_blob: NZU64!(7),
173 log_write_buffer: NZUsize!(1024),
174 translator: TwoCap,
175 thread_pool: None,
176 buffer_pool: PoolRef::new(PAGE_SIZE, PAGE_CACHE_SIZE),
177 }
178 }
179
180 pub(super) fn variable_db_config(suffix: &str) -> VariableConfig<TwoCap, ()> {
181 VariableConfig {
182 mmr_journal_partition: format!("journal_{suffix}"),
183 mmr_metadata_partition: format!("metadata_{suffix}"),
184 mmr_items_per_blob: NZU64!(11),
185 mmr_write_buffer: NZUsize!(1024),
186 log_partition: format!("log_journal_{suffix}"),
187 log_items_per_blob: NZU64!(7),
188 log_write_buffer: NZUsize!(1024),
189 log_compression: None,
190 log_codec_config: (),
191 translator: TwoCap,
192 thread_pool: None,
193 buffer_pool: PoolRef::new(PAGE_SIZE, PAGE_CACHE_SIZE),
194 }
195 }
196
197 use crate::{
198 kv::Updatable,
199 qmdb::{
200 any::states::{CleanAny, MerkleizedNonDurableAny, MutableAny, UnmerkleizedDurableAny},
201 store::MerkleizedStore,
202 },
203 Persistable,
204 };
205 use commonware_cryptography::{sha256::Digest, Sha256};
206
207 pub(crate) async fn test_any_db_steps_not_reset<D>(db: D)
209 where
210 D: CleanAny<Key = Digest> + MerkleizedStore<Value = Digest, Digest = Digest>,
211 D::Mutable: Updatable<Key = Digest, Value = Digest, Error = crate::qmdb::Error>,
212 {
213 let mut db = db.into_mutable();
215
216 assert!(db
217 .create(Sha256::fill(1u8), Sha256::fill(2u8))
218 .await
219 .unwrap());
220 assert!(db
221 .create(Sha256::fill(3u8), Sha256::fill(4u8))
222 .await
223 .unwrap());
224 let (clean_db, _) = db.commit(None).await.unwrap();
225 let mut db = clean_db.into_mutable();
226
227 db.update(Sha256::fill(1u8), Sha256::fill(5u8))
229 .await
230 .unwrap();
231 let steps = db.steps();
232 assert_ne!(steps, 0);
233
234 let db = db.into_merkleized().await.unwrap();
236 let db = db.into_mutable();
237 assert_eq!(db.steps(), steps);
238
239 let (db, _) = db.commit(None).await.unwrap();
241 let db = db.into_merkleized().await.unwrap();
242 db.destroy().await.unwrap();
243 }
244}