Skip to main content

commonware_storage/qmdb/current/unordered/
fixed.rs

1//! An _unordered_ variant of a [crate::qmdb::current] authenticated database optimized for
2//! fixed-size values.
3//!
4//! This variant does not maintain key ordering, so it cannot generate exclusion proofs. Use
5//! [crate::qmdb::current::ordered::fixed] if exclusion proofs are required.
6//!
7//! See [Db] for the main database type.
8
9pub use super::db::KeyValueProof;
10use crate::{
11    index::unordered::Index,
12    journal::contiguous::fixed::Journal,
13    merkle::{Graftable, Location},
14    qmdb::{
15        any::{unordered::fixed::Operation, value::FixedEncoding, FixedValue},
16        current::FixedConfig as Config,
17        Error,
18    },
19    translator::Translator,
20    Context,
21};
22use commonware_cryptography::Hasher;
23use commonware_utils::Array;
24
25/// A specialization of [super::db::Db] for unordered key spaces and fixed-size values.
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    /// Initializes a [Db] authenticated database from the given `config`. Leverages parallel
48    /// Merkleization to initialize the bitmap tree if a thread pool is provided.
49    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    //! A partitioned variant of [super] that uses a partitioned index for the snapshot.
56    //!
57    //! See [crate::qmdb::any::unordered::fixed::partitioned] for details on partitioned indices and
58    //! when to use them.
59
60    use super::*;
61    use crate::index::partitioned::unordered::Index;
62
63    /// A partitioned variant of [super::Db].
64    ///
65    /// The const generic `P` specifies the number of prefix bytes used for partitioning:
66    /// - `P = 1`: 256 partitions
67    /// - `P = 2`: 65,536 partitions
68    /// - `P = 3`: ~16 million partitions
69    pub type Db<F, E, K, V, H, T, const P: usize, const N: usize> =
70        crate::qmdb::current::unordered::db::Db<
71            F,
72            E,
73            Journal<E, Operation<F, K, V>>,
74            K,
75            FixedEncoding<V>,
76            Index<T, Location<F>, P>,
77            H,
78            N,
79        >;
80
81    impl<
82            F: Graftable,
83            E: Context,
84            K: Array,
85            V: FixedValue,
86            H: Hasher,
87            T: Translator,
88            const P: usize,
89            const N: usize,
90        > Db<F, E, K, V, H, T, P, N>
91    {
92        /// Initializes a [Db] authenticated database from the given `config`. Leverages parallel
93        /// Merkleization to initialize the bitmap Merkle tree if a thread pool is provided.
94        pub async fn init(context: E, config: Config<T>) -> Result<Self, Error<F>> {
95            crate::qmdb::current::init(context, config).await
96        }
97    }
98}
99
100#[cfg(test)]
101pub mod test {
102    use super::*;
103    use crate::{
104        mmr,
105        qmdb::current::{tests::fixed_config, unordered::tests as shared},
106        translator::TwoCap,
107    };
108    use commonware_cryptography::{sha256::Digest, Sha256};
109    use commonware_macros::test_traced;
110    use commonware_runtime::deterministic;
111
112    /// A type alias for the concrete [Db] type used in these unit tests.
113    type CurrentTest = Db<mmr::Family, deterministic::Context, Digest, Digest, Sha256, TwoCap, 32>;
114
115    /// Return a [Db] database initialized with a fixed config.
116    async fn open_db(context: deterministic::Context, partition_prefix: String) -> CurrentTest {
117        let cfg = fixed_config::<TwoCap>(&partition_prefix, &context);
118        CurrentTest::init(context, cfg).await.unwrap()
119    }
120
121    #[test_traced("DEBUG")]
122    pub fn test_current_db_verify_proof_over_bits_in_uncommitted_chunk() {
123        shared::test_verify_proof_over_bits_in_uncommitted_chunk(open_db);
124    }
125
126    #[test_traced("DEBUG")]
127    pub fn test_current_db_range_proofs() {
128        shared::test_range_proofs(open_db);
129    }
130
131    #[test_traced("DEBUG")]
132    pub fn test_current_db_key_value_proof() {
133        shared::test_key_value_proof(open_db);
134    }
135
136    #[test_traced("WARN")]
137    pub fn test_current_db_proving_repeated_updates() {
138        shared::test_proving_repeated_updates(open_db);
139    }
140}