Skip to main content

commonware_storage/qmdb/current/ordered/
variable.rs

1//! An _ordered_ variant of a [crate::qmdb::current] authenticated database for variable-size values
2//!
3//! This variant maintains the lexicographic-next active key for each active key, enabling exclusion
4//! proofs (proving a key is currently inactive). Use [crate::qmdb::current::unordered::variable] if
5//! exclusion proofs are not needed.
6//!
7//! See [Db] for the main database type and [super::ExclusionProof] for proving key inactivity.
8
9pub use super::db::KeyValueProof;
10use crate::{
11    index::ordered::Index,
12    journal::contiguous::variable::Journal,
13    merkle::{Graftable, Location},
14    qmdb::{
15        any::{ordered::variable::Operation, value::VariableEncoding, VariableValue},
16        current::VariableConfig as Config,
17        operation::Key,
18        Error,
19    },
20    translator::Translator,
21    Context,
22};
23use commonware_codec::{Codec, Read};
24use commonware_cryptography::Hasher;
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    VariableEncoding<V>,
32    Index<T, Location<F>>,
33    H,
34    N,
35>;
36
37impl<
38        F: Graftable,
39        E: Context,
40        K: Key,
41        V: VariableValue,
42        H: Hasher,
43        T: Translator,
44        const N: usize,
45    > Db<F, E, K, V, H, T, N>
46where
47    Operation<F, K, V>: Codec,
48{
49    /// Initializes a [Db] from the given `config`. Leverages parallel Merkleization to initialize
50    /// the bitmap Merkle tree if a thread pool is provided.
51    pub async fn init(
52        context: E,
53        config: Config<T, <Operation<F, K, V> as Read>::Cfg>,
54    ) -> Result<Self, Error<F>> {
55        crate::qmdb::current::init(context, config).await
56    }
57}
58
59pub mod partitioned {
60    //! A variant of [super] that uses a partitioned index for the snapshot.
61
62    use super::*;
63    use crate::index::partitioned::ordered::Index;
64
65    /// A partitioned variant of [super::Db].
66    ///
67    /// The const generic `P` specifies the number of prefix bytes used for partitioning:
68    /// - `P = 1`: 256 partitions
69    /// - `P = 2`: 65,536 partitions
70    /// - `P = 3`: ~16 million partitions
71    pub type Db<F, E, K, V, H, T, const P: usize, const N: usize> =
72        crate::qmdb::current::ordered::db::Db<
73            F,
74            E,
75            Journal<E, Operation<F, K, V>>,
76            K,
77            VariableEncoding<V>,
78            Index<T, Location<F>, P>,
79            H,
80            N,
81        >;
82
83    impl<
84            F: Graftable,
85            E: Context,
86            K: Key,
87            V: VariableValue,
88            H: Hasher,
89            T: Translator,
90            const P: usize,
91            const N: usize,
92        > Db<F, E, K, V, H, T, P, N>
93    where
94        Operation<F, K, V>: Codec,
95    {
96        /// Initializes a [Db] from the given `config`. Leverages parallel Merkleization to initialize
97        /// the bitmap Merkle tree if a thread pool is provided.
98        pub async fn init(
99            context: E,
100            config: Config<T, <Operation<F, K, V> as Read>::Cfg>,
101        ) -> Result<Self, Error<F>> {
102            crate::qmdb::current::init(context, config).await
103        }
104    }
105}
106
107#[cfg(test)]
108mod test {
109    use crate::{
110        mmr,
111        qmdb::current::{ordered::tests as shared, tests::variable_config},
112        translator::OneCap,
113    };
114    use commonware_cryptography::{sha256::Digest, Sha256};
115    use commonware_macros::test_traced;
116    use commonware_runtime::deterministic;
117
118    /// A type alias for the concrete [Db] type used in these unit tests.
119    type CurrentTest =
120        super::Db<mmr::Family, deterministic::Context, Digest, Digest, Sha256, OneCap, 32>;
121
122    /// Return a [Db] database initialized with a variable config.
123    async fn open_db(context: deterministic::Context, partition_prefix: String) -> CurrentTest {
124        let cfg = variable_config::<OneCap>(&partition_prefix, &context);
125        CurrentTest::init(context, cfg).await.unwrap()
126    }
127
128    #[test_traced("DEBUG")]
129    pub fn test_current_db_verify_proof_over_bits_in_uncommitted_chunk() {
130        shared::test_verify_proof_over_bits_in_uncommitted_chunk(open_db);
131    }
132
133    #[test_traced("DEBUG")]
134    pub fn test_current_db_range_proofs() {
135        shared::test_range_proofs(open_db);
136    }
137
138    #[test_traced("DEBUG")]
139    pub fn test_current_db_key_value_proof() {
140        shared::test_key_value_proof(open_db);
141    }
142
143    #[test_traced("WARN")]
144    pub fn test_current_db_proving_repeated_updates() {
145        shared::test_proving_repeated_updates(open_db);
146    }
147
148    #[test_traced("DEBUG")]
149    pub fn test_current_db_exclusion_proofs() {
150        shared::test_exclusion_proofs(open_db);
151    }
152}