commonware_storage/qmdb/current/ordered/
fixed.rs1pub use super::db::KeyValueProof;
11use crate::{
12 index::ordered::Index,
13 journal::contiguous::fixed::Journal,
14 merkle::{Graftable, Location},
15 qmdb::{
16 any::{ordered::fixed::Operation, value::FixedEncoding, FixedValue},
17 current::FixedConfig as Config,
18 Error,
19 },
20 translator::Translator,
21 Context,
22};
23use commonware_cryptography::Hasher;
24use commonware_utils::Array;
25
26pub type Db<F, E, K, V, H, T, const N: usize> = super::db::Db<
27 F,
28 E,
29 Journal<E, Operation<F, K, V>>,
30 K,
31 FixedEncoding<V>,
32 Index<T, Location<F>>,
33 H,
34 N,
35>;
36
37impl<
38 F: Graftable,
39 E: Context,
40 K: Array,
41 V: FixedValue,
42 H: Hasher,
43 T: Translator,
44 const N: usize,
45 > Db<F, E, K, V, H, T, N>
46{
47 pub async fn init(context: E, config: Config<T>) -> Result<Self, Error<F>> {
50 crate::qmdb::current::init(context, config).await
51 }
52}
53
54pub mod partitioned {
55 use super::*;
58 use crate::index::partitioned::ordered::Index;
59
60 pub type Db<F, E, K, V, H, T, const P: usize, const N: usize> =
67 crate::qmdb::current::ordered::db::Db<
68 F,
69 E,
70 Journal<E, Operation<F, K, V>>,
71 K,
72 FixedEncoding<V>,
73 Index<T, Location<F>, P>,
74 H,
75 N,
76 >;
77
78 impl<
79 F: Graftable,
80 E: Context,
81 K: Array,
82 V: FixedValue,
83 H: Hasher,
84 T: Translator,
85 const P: usize,
86 const N: usize,
87 > Db<F, E, K, V, H, T, P, N>
88 {
89 pub async fn init(context: E, config: Config<T>) -> Result<Self, Error<F>> {
92 crate::qmdb::current::init(context, config).await
93 }
94 }
95}
96
97#[cfg(test)]
98pub mod test {
99 use super::*;
100 use crate::{
101 mmr,
102 qmdb::{
103 current::{ordered::tests as shared, tests::fixed_config},
104 Error,
105 },
106 translator::OneCap,
107 };
108 use commonware_cryptography::{sha256::Digest, Sha256};
109 use commonware_macros::test_traced;
110 use commonware_runtime::{deterministic, Metrics, Runner as _};
111 use commonware_utils::{
112 bitmap::{Prunable as BitMap, Readable as _},
113 NZU64,
114 };
115
116 type CurrentTest = Db<mmr::Family, deterministic::Context, Digest, Digest, Sha256, OneCap, 32>;
118
119 async fn open_db(context: deterministic::Context, partition_prefix: String) -> CurrentTest {
121 let cfg = fixed_config::<OneCap>(&partition_prefix, &context);
122 CurrentTest::init(context, cfg).await.unwrap()
123 }
124
125 #[test_traced("DEBUG")]
126 pub fn test_current_db_verify_proof_over_bits_in_uncommitted_chunk() {
127 shared::test_verify_proof_over_bits_in_uncommitted_chunk(open_db);
128 }
129
130 #[test_traced("DEBUG")]
131 pub fn test_current_db_range_proofs() {
132 shared::test_range_proofs(open_db);
133 }
134
135 #[test_traced("DEBUG")]
138 pub fn test_range_proof_returns_error_on_pruned_chunks() {
139 let executor = deterministic::Runner::default();
140 executor.start(|context| async move {
141 let partition = "range-proofs-pruned".to_string();
142 let mut hasher = Sha256::new();
143 let mut db = open_db(context.with_label("db"), partition).await;
144
145 let chunk_bits = BitMap::<32>::CHUNK_SIZE_BITS;
146
147 let key = Sha256::fill(0x11);
150 for i in 0..chunk_bits + 10 {
151 let value = Sha256::hash(&i.to_be_bytes());
152 let merkleized = db
153 .new_batch()
154 .write(key, Some(value))
155 .merkleize(&db, None)
156 .await
157 .unwrap();
158 db.apply_batch(merkleized).await.unwrap();
159 }
160
161 let floor = db.any.inactivity_floor_loc;
163 db.prune(floor).await.unwrap();
164
165 assert!(
166 db.status.pruned_chunks() > 0,
167 "expected at least one pruned chunk"
168 );
169
170 let result = db
173 .range_proof(&mut hasher, Location::new(0), NZU64!(1))
174 .await;
175 assert!(
176 matches!(result, Err(Error::OperationPruned(_))),
177 "expected OperationPruned, got {result:?}"
178 );
179
180 db.destroy().await.unwrap();
181 });
182 }
183
184 #[test_traced("DEBUG")]
185 pub fn test_current_db_key_value_proof() {
186 shared::test_key_value_proof(open_db);
187 }
188
189 #[test_traced("WARN")]
190 pub fn test_current_db_proving_repeated_updates() {
191 shared::test_proving_repeated_updates(open_db);
192 }
193
194 #[test_traced("DEBUG")]
195 pub fn test_current_db_exclusion_proofs() {
196 shared::test_exclusion_proofs(open_db);
197 }
198}