Skip to main content

commonware_sync/databases/
immutable_compact.rs

1//! Compact immutable database types and helpers for compact sync demonstration.
2
3use crate::{Hasher, Key, Value};
4use commonware_parallel::Sequential;
5use commonware_runtime::{BufferPooler, Clock, Metrics, Storage};
6use commonware_storage::{
7    merkle::{
8        compact::Config as MerkleConfig,
9        mmr::{self},
10    },
11    qmdb::{
12        self,
13        immutable::fixed::{self, CompactConfig},
14        sync::compact,
15    },
16};
17use tracing::error;
18
19/// Database type alias.
20pub type Database<E> = fixed::CompactDb<mmr::Family, E, Key, Value, Hasher, Sequential>;
21
22/// Operation type alias.
23pub type Operation = fixed::Operation<mmr::Family, Key, Value>;
24
25/// Create a database configuration for the compact immutable variant.
26pub fn create_config(_context: &impl BufferPooler) -> CompactConfig<Sequential> {
27    CompactConfig {
28        merkle: MerkleConfig {
29            partition: "compact-immutable".into(),
30            strategy: Sequential,
31        },
32        commit_codec_config: (),
33    }
34}
35
36impl<E> super::ExampleDatabase for Database<E>
37where
38    E: Storage + Clock + Metrics,
39{
40    type Family = mmr::Family;
41    type Operation = Operation;
42
43    fn create_test_operations(count: usize, seed: u64, starting_loc: u64) -> Vec<Self::Operation> {
44        super::immutable::create_test_operations(count, seed, starting_loc)
45    }
46
47    async fn add_operations(
48        &mut self,
49        operations: Vec<Self::Operation>,
50    ) -> Result<(), qmdb::Error<mmr::Family>> {
51        let Some(last) = operations.last() else {
52            error!("operations must end with a commit");
53            return Ok(());
54        };
55        if !matches!(last, Operation::Commit(..)) {
56            error!("operations must end with a commit");
57            return Ok(());
58        }
59
60        let mut batch = self.new_batch();
61        for operation in operations {
62            match operation {
63                Operation::Set(key, value) => {
64                    batch = batch.set(key, value);
65                }
66                Operation::Commit(metadata, floor) => {
67                    let merkleized = batch.merkleize(self, metadata, floor);
68                    self.apply_batch(merkleized)?;
69                    self.commit().await?;
70                    batch = self.new_batch();
71                }
72            }
73        }
74        Ok(())
75    }
76
77    fn current_floor(&self) -> u64 {
78        *Self::inactivity_floor_loc(self)
79    }
80
81    fn root(&self) -> Key {
82        Self::root(self)
83    }
84
85    fn name() -> &'static str {
86        "compact immutable"
87    }
88}
89
90impl<E> super::CompactSyncable for Database<E>
91where
92    E: Storage + Clock + Metrics,
93{
94    async fn current_target(&self) -> compact::Target<Self::Family, Key> {
95        Self::current_target(self)
96    }
97}