@@ -11,7 +11,11 @@ use commonware_runtime::{
1111} ;
1212use commonware_storage:: {
1313 mmr,
14- qmdb:: sync:: { self , compact} ,
14+ qmdb:: {
15+ any:: sync:: Target ,
16+ current as current_qmdb,
17+ sync:: { self , compact} ,
18+ } ,
1519} ;
1620use commonware_sync:: {
1721 any, crate_version, current,
@@ -70,9 +74,9 @@ struct Config {
7074async fn target_update_task < E , Op , D > (
7175 context : E ,
7276 resolver : Resolver < Op , D > ,
73- update_tx : mpsc:: Sender < sync :: Target < mmr:: Family , D > > ,
77+ update_tx : mpsc:: Sender < Target < mmr:: Family , D > > ,
7478 interval_duration : Duration ,
75- initial_target : sync :: Target < mmr:: Family , D > ,
79+ initial_target : Target < mmr:: Family , D > ,
7680) -> Result < ( ) , Error >
7781where
7882 E : Clock ,
@@ -132,8 +136,8 @@ where
132136 E ,
133137 Config ,
134138 Resolver < Op , Key > ,
135- sync :: Target < mmr:: Family , Key > ,
136- mpsc:: Receiver < sync :: Target < mmr:: Family , Key > > ,
139+ Target < mmr:: Family , Key > ,
140+ mpsc:: Receiver < Target < mmr:: Family , Key > > ,
137141 u32 ,
138142 ) -> SyncFut ,
139143 SyncFut : Future < Output = Result < DB , Box < dyn std:: error:: Error > > > ,
@@ -188,7 +192,7 @@ where
188192 |context, config, resolver, initial_target, update_receiver, iteration| async move {
189193 let db_config = any:: create_config ( & context) ;
190194 let sync_config =
191- sync:: engine:: Config :: < any:: Database < _ > , Resolver < any:: Operation , Key > > {
195+ sync:: engine:: Config :: < any:: Database < _ > , Resolver < any:: Operation , Key > , _ > {
192196 context,
193197 db_config,
194198 fetch_batch_size : config. batch_size ,
@@ -217,44 +221,94 @@ where
217221
218222/// Repeatedly sync a Current database to the server's state.
219223///
220- /// The sync engine targets the ops root (not the canonical root). After sync completes,
221- /// the bitmap and grafted MMR are reconstructed from the synced operations.
224+ /// Uses the `current::sync::sync` wrapper. The wrapper verifies each target's `OpsRootWitness`
225+ /// before forwarding its ops root to the shared sync engine, then checks the database root for the
226+ /// target the engine finishes on.
222227async fn run_current < E > ( context : E , config : Config ) -> Result < ( ) , Box < dyn std:: error:: Error > >
223228where
224229 E : BufferPooler + Storage + Clock + Metrics + Network + Spawner ,
225230{
226- run_full_sync :: < current:: Database < _ > , current:: Operation , _ , _ , _ > (
227- context,
228- config,
229- |context, config, resolver, initial_target, update_receiver, iteration| async move {
230- let db_config = current:: create_config ( & context) ;
231- let sync_config =
232- sync:: engine:: Config :: < current:: Database < _ > , Resolver < current:: Operation , Key > > {
233- context,
234- db_config,
235- fetch_batch_size : config. batch_size ,
236- target : initial_target,
237- resolver,
238- apply_batch_size : 1024 ,
239- max_outstanding_requests : config. max_outstanding_requests ,
240- update_rx : Some ( update_receiver) ,
241- finish_rx : None ,
242- reached_target_tx : None ,
243- max_retained_roots : 8 ,
244- } ;
245- let database: current:: Database < _ > = sync:: sync ( sync_config) . await ?;
246- info ! (
247- sync_iteration = iteration,
248- canonical_root = %database. root( ) ,
249- ops_root = %database. ops_root( ) ,
250- sync_interval = ?config. sync_interval,
251- "Current sync completed successfully"
252- ) ;
253- Ok ( database)
254- } ,
255- "Current database" ,
256- )
257- . await
231+ info ! ( "starting Current database sync process" ) ;
232+ let mut iteration = 0u32 ;
233+ loop {
234+ let resolver =
235+ Resolver :: < current:: Operation , Key > :: connect ( context. child ( "resolver" ) , config. server )
236+ . await ?;
237+
238+ let initial_target = resolver. get_current_sync_target ( ) . await ?;
239+ info ! (
240+ root = %initial_target. root,
241+ ops_root = %initial_target. ops_root,
242+ range = ?initial_target. range,
243+ "received current sync target"
244+ ) ;
245+
246+ let ( update_sender, update_receiver) = mpsc:: channel ( UPDATE_CHANNEL_SIZE ) ;
247+
248+ let target_update_handle = {
249+ let resolver = resolver. clone ( ) ;
250+ let mut current_target_root = initial_target. root ;
251+ let target_update_interval = config. target_update_interval ;
252+ context
253+ . child ( "target_update" )
254+ . spawn ( move |context| async move {
255+ loop {
256+ context. sleep ( target_update_interval) . await ;
257+ match resolver. get_current_sync_target ( ) . await {
258+ Ok ( new_target) => {
259+ if current_target_root != new_target. root {
260+ let new_root = new_target. root ;
261+ match update_sender. clone ( ) . try_send ( new_target) {
262+ Ok ( ( ) ) => {
263+ info ! ( "target updated" ) ;
264+ current_target_root = new_root;
265+ }
266+ Err ( mpsc:: error:: TrySendError :: Closed ( _) ) => return Ok ( ( ) ) ,
267+ Err ( err) => {
268+ warn ! ( ?err, "failed to send target update" ) ;
269+ return Err ( Error :: TargetUpdateChannel {
270+ reason : err. to_string ( ) ,
271+ } ) ;
272+ }
273+ }
274+ }
275+ }
276+ Err ( err) => {
277+ warn ! ( ?err, "failed to get sync target from server" ) ;
278+ }
279+ }
280+ }
281+ } )
282+ } ;
283+
284+ let db_config = current:: create_config ( & context) ;
285+ let database: current:: Database < _ > = current_qmdb:: sync:: sync ( current_qmdb:: sync:: Config {
286+ context : context. child ( "sync" ) ,
287+ resolver,
288+ target : initial_target,
289+ max_outstanding_requests : config. max_outstanding_requests ,
290+ fetch_batch_size : config. batch_size ,
291+ apply_batch_size : 1024 ,
292+ db_config,
293+ update_rx : Some ( update_receiver) ,
294+ finish_rx : None ,
295+ reached_target_tx : None ,
296+ max_retained_roots : 8 ,
297+ } )
298+ . await ?;
299+
300+ target_update_handle. abort ( ) ;
301+ info ! (
302+ sync_iteration = iteration,
303+ root = %database. root( ) ,
304+ ops_root = %database. ops_root( ) ,
305+ sync_interval = ?config. sync_interval,
306+ "Current sync completed successfully"
307+ ) ;
308+ database. destroy ( ) . await ?;
309+ context. sleep ( config. sync_interval ) . await ;
310+ iteration += 1 ;
311+ }
258312}
259313
260314/// Repeatedly sync an Immutable database to the server's state.
@@ -270,6 +324,7 @@ where
270324 let sync_config = sync:: engine:: Config :: <
271325 immutable:: Database < _ > ,
272326 Resolver < immutable:: Operation , Key > ,
327+ _ ,
273328 > {
274329 context,
275330 db_config,
@@ -307,20 +362,23 @@ where
307362 config,
308363 |context, config, resolver, initial_target, update_receiver, iteration| async move {
309364 let db_config = keyless:: create_config ( & context) ;
310- let sync_config =
311- sync:: engine:: Config :: < keyless:: Database < _ > , Resolver < keyless:: Operation , Key > > {
312- context,
313- db_config,
314- fetch_batch_size : config. batch_size ,
315- target : initial_target,
316- resolver,
317- apply_batch_size : 1024 ,
318- max_outstanding_requests : config. max_outstanding_requests ,
319- update_rx : Some ( update_receiver) ,
320- finish_rx : None ,
321- reached_target_tx : None ,
322- max_retained_roots : 8 ,
323- } ;
365+ let sync_config = sync:: engine:: Config :: <
366+ keyless:: Database < _ > ,
367+ Resolver < keyless:: Operation , Key > ,
368+ _ ,
369+ > {
370+ context,
371+ db_config,
372+ fetch_batch_size : config. batch_size ,
373+ target : initial_target,
374+ resolver,
375+ apply_batch_size : 1024 ,
376+ max_outstanding_requests : config. max_outstanding_requests ,
377+ update_rx : Some ( update_receiver) ,
378+ finish_rx : None ,
379+ reached_target_tx : None ,
380+ max_retained_roots : 8 ,
381+ } ;
324382 let database: keyless:: Database < _ > = sync:: sync ( sync_config) . await ?;
325383 info ! (
326384 sync_iteration = iteration,
0 commit comments