commonware_sync/databases/
immutable.rs

1//! Immutable database types and helpers for the sync example.
2
3use crate::{Hasher, Key, Translator, Value};
4use commonware_cryptography::{Hasher as CryptoHasher, Sha256};
5use commonware_runtime::{Clock, Metrics, Storage};
6use commonware_storage::{
7    adb::{
8        self,
9        immutable::{self, Config},
10        operation,
11    },
12    mmr::{Location, Proof, StandardHasher as Standard},
13};
14use commonware_utils::{NZUsize, NZU64};
15use std::{future::Future, num::NonZeroU64};
16
17/// Database type alias.
18pub type Database<E> = immutable::Immutable<E, Key, Value, Hasher, Translator>;
19
20/// Operation type alias.
21pub type Operation = operation::variable::Operation<Key, Value>;
22
23/// Create a database configuration with appropriate partitioning for Immutable.
24pub fn create_config() -> Config<Translator, ()> {
25    Config {
26        mmr_journal_partition: "mmr_journal".into(),
27        mmr_metadata_partition: "mmr_metadata".into(),
28        mmr_items_per_blob: NZU64!(4096),
29        mmr_write_buffer: NZUsize!(1024),
30        log_partition: "log".into(),
31        log_items_per_section: NZU64!(512),
32        log_compression: None,
33        log_codec_config: (),
34        log_write_buffer: NZUsize!(1024),
35        translator: commonware_storage::translator::EightCap,
36        thread_pool: None,
37        buffer_pool: commonware_runtime::buffer::PoolRef::new(NZUsize!(1024), NZUsize!(10)),
38    }
39}
40
41/// Create deterministic test operations for demonstration purposes.
42/// Generates Set operations and periodic Commit operations.
43pub fn create_test_operations(count: usize, seed: u64) -> Vec<Operation> {
44    let mut operations = Vec::new();
45    let mut hasher = <Hasher as CryptoHasher>::new();
46
47    for i in 0..count {
48        let key = {
49            hasher.update(&i.to_be_bytes());
50            hasher.update(&seed.to_be_bytes());
51            hasher.finalize()
52        };
53
54        let value = {
55            hasher.update(&key);
56            hasher.update(b"value");
57            hasher.finalize()
58        };
59
60        operations.push(Operation::Set(key, value));
61
62        if (i + 1) % 10 == 0 {
63            operations.push(Operation::Commit(None));
64        }
65    }
66
67    // Always end with a commit
68    operations.push(Operation::Commit(Some(Sha256::fill(1))));
69    operations
70}
71
72impl<E> super::Syncable for Database<E>
73where
74    E: Storage + Clock + Metrics,
75{
76    type Operation = Operation;
77
78    fn create_test_operations(count: usize, seed: u64) -> Vec<Self::Operation> {
79        create_test_operations(count, seed)
80    }
81
82    async fn add_operations(
83        database: &mut Self,
84        operations: Vec<Self::Operation>,
85    ) -> Result<(), commonware_storage::adb::Error> {
86        for operation in operations {
87            match operation {
88                Operation::Set(key, value) => {
89                    database.set(key, value).await?;
90                }
91                Operation::Commit(metadata) => {
92                    database.commit(metadata).await?;
93                }
94                _ => {}
95            }
96        }
97        Ok(())
98    }
99
100    async fn commit(&mut self) -> Result<(), commonware_storage::adb::Error> {
101        self.commit(None).await
102    }
103
104    fn root(&self, hasher: &mut Standard<commonware_cryptography::Sha256>) -> Key {
105        self.root(hasher)
106    }
107
108    fn op_count(&self) -> Location {
109        self.op_count()
110    }
111
112    fn lower_bound(&self) -> Location {
113        self.oldest_retained_loc()
114            .unwrap_or(Location::new(0).unwrap())
115    }
116
117    fn historical_proof(
118        &self,
119        op_count: Location,
120        start_loc: Location,
121        max_ops: NonZeroU64,
122    ) -> impl Future<Output = Result<(Proof<Key>, Vec<Self::Operation>), adb::Error>> + Send {
123        self.historical_proof(op_count, start_loc, max_ops)
124    }
125
126    fn name() -> &'static str {
127        "immutable"
128    }
129}