11//! Keyless database types and helpers for the sync example.
22//!
33//! A `keyless` database is append-only: operations are stored by location rather than by key.
4- //! It supports `Append(value)` and `Commit(metadata)` operations. For sync, the engine targets
5- //! the Merkle root over all operations, and the client reconstructs the same state by replaying
6- //! the fetched operations.
4+ //! It supports `Append(value)` and `Commit(metadata, floor )` operations. For sync, the engine
5+ //! targets the Merkle root over all operations, and the client reconstructs the same state by
6+ //! replaying the fetched operations.
77
88use crate :: { Hasher , Key , Value } ;
99use commonware_cryptography:: { Hasher as CryptoHasher , Sha256 } ;
@@ -28,7 +28,7 @@ use tracing::error;
2828pub type Database < E > = fixed:: Db < mmr:: Family , E , Value , Hasher > ;
2929
3030/// Operation type alias.
31- pub type Operation = fixed:: Operation < Value > ;
31+ pub type Operation = fixed:: Operation < mmr :: Family , Value > ;
3232
3333/// Create a database configuration for the keyless variant.
3434pub fn create_config ( context : & ( impl BufferPooler + commonware_runtime:: Metrics ) ) -> fixed:: Config {
@@ -56,11 +56,23 @@ pub fn create_config(context: &(impl BufferPooler + commonware_runtime::Metrics)
5656}
5757
5858/// Create deterministic test operations for demonstration purposes.
59- /// Generates Append operations and periodic Commit operations.
59+ ///
60+ /// Generates Append operations and periodic Commit operations, advancing the inactivity
61+ /// floor at each commit to the *previous* commit's location. This models a realistic
62+ /// application that declares older commits inactive over time (enabling pruning) while
63+ /// always keeping the most recent commit readable.
6064pub fn create_test_operations ( count : usize , seed : u64 ) -> Vec < Operation > {
6165 let mut operations = Vec :: new ( ) ;
6266 let mut hasher = <Hasher as CryptoHasher >:: new ( ) ;
6367
68+ // The DB's initial commit lands at location 0 before any of these ops are applied.
69+ // `op_count` tracks the total ops that will exist on disk (including this initial commit
70+ // and everything we push below). `prev_commit_loc` tracks the last commit's location
71+ // and is used as the next commit's floor — always <= the next commit's own location, so
72+ // the per-commit floor bound is satisfied.
73+ let mut op_count: u64 = 1 ;
74+ let mut prev_commit_loc: u64 = 0 ;
75+
6476 for i in 0 ..count {
6577 let value = {
6678 hasher. update ( & i. to_be_bytes ( ) ) ;
@@ -69,14 +81,20 @@ pub fn create_test_operations(count: usize, seed: u64) -> Vec<Operation> {
6981 } ;
7082
7183 operations. push ( Operation :: Append ( value) ) ;
84+ op_count += 1 ;
7285
7386 if ( i + 1 ) % 10 == 0 {
74- operations. push ( Operation :: Commit ( None ) ) ;
87+ operations. push ( Operation :: Commit ( None , Location :: new ( prev_commit_loc) ) ) ;
88+ prev_commit_loc = op_count;
89+ op_count += 1 ;
7590 }
7691 }
7792
78- // Always end with a commit
79- operations. push ( Operation :: Commit ( Some ( Sha256 :: fill ( 1 ) ) ) ) ;
93+ // Always end with a commit, floor set to the previous commit's location.
94+ operations. push ( Operation :: Commit (
95+ Some ( Sha256 :: fill ( 1 ) ) ,
96+ Location :: new ( prev_commit_loc) ,
97+ ) ) ;
8098 operations
8199}
82100
@@ -107,8 +125,8 @@ where
107125 Operation :: Append ( value) => {
108126 batch = batch. append ( value) ;
109127 }
110- Operation :: Commit ( metadata) => {
111- let merkleized = batch. merkleize ( self , metadata) ;
128+ Operation :: Commit ( metadata, floor ) => {
129+ let merkleized = batch. merkleize ( self , metadata, floor ) ;
112130 self . apply_batch ( merkleized) . await ?;
113131 self . commit ( ) . await ?;
114132 batch = self . new_batch ( ) ;
@@ -127,7 +145,7 @@ where
127145 }
128146
129147 async fn sync_boundary ( & self ) -> Location {
130- self . sync_boundary ( ) . await
148+ self . sync_boundary ( )
131149 }
132150
133151 async fn historical_proof (
@@ -161,7 +179,7 @@ mod tests {
161179 let ops = <KeylessDb as Syncable >:: create_test_operations ( 5 , 12345 ) ;
162180 assert_eq ! ( ops. len( ) , 6 ) ; // 5 operations + 1 commit
163181
164- if let Operation :: Commit ( Some ( _) ) = & ops[ 5 ] {
182+ if let Operation :: Commit ( Some ( _) , _ ) = & ops[ 5 ] {
165183 // ok
166184 } else {
167185 panic ! ( "last operation should be a commit with metadata" ) ;
0 commit comments