@@ -382,8 +382,10 @@ where
382
382
output_spender : O , change_destination_source : D , kv_store : K , logger : L ,
383
383
) -> Self {
384
384
let outputs = Vec :: new ( ) ;
385
- let sweeper_state =
386
- Mutex :: new ( SweeperState { persistent : PersistentSweeperState { outputs, best_block } } ) ;
385
+ let sweeper_state = Mutex :: new ( SweeperState {
386
+ persistent : PersistentSweeperState { outputs, best_block } ,
387
+ dirty : false ,
388
+ } ) ;
387
389
Self {
388
390
sweeper_state,
389
391
pending_sweep : AtomicBool :: new ( false ) ,
@@ -445,7 +447,7 @@ where
445
447
446
448
state_lock. persistent . outputs . push ( output_info) ;
447
449
}
448
- self . persist_state ( & * state_lock) . await . map_err ( |e| {
450
+ self . flush_state ( & mut state_lock) . await . map_err ( |e| {
449
451
log_error ! ( self . logger, "Error persisting OutputSweeper: {:?}" , e) ;
450
452
} )
451
453
}
@@ -473,7 +475,19 @@ where
473
475
return Ok ( ( ) ) ;
474
476
}
475
477
476
- let result = self . regenerate_and_broadcast_spend_if_necessary_internal ( ) . await ;
478
+ let result = {
479
+ self . regenerate_and_broadcast_spend_if_necessary_internal ( ) . await ?;
480
+
481
+ // If there is still dirty state, we need to persist it.
482
+ let mut sweeper_state = self . sweeper_state . lock ( ) . unwrap ( ) ;
483
+ if sweeper_state. dirty {
484
+ self . flush_state ( & mut sweeper_state) . await . map_err ( |e| {
485
+ log_error ! ( self . logger, "Error persisting OutputSweeper: {:?}" , e) ;
486
+ } )
487
+ } else {
488
+ Ok ( ( ) )
489
+ }
490
+ } ;
477
491
478
492
// Release the pending sweep flag again, regardless of result.
479
493
self . pending_sweep . store ( false , Ordering :: Release ) ;
@@ -567,7 +581,7 @@ where
567
581
output_info. status . broadcast ( cur_hash, cur_height, spending_tx. clone ( ) ) ;
568
582
}
569
583
570
- self . persist_state ( & sweeper_state) . await . map_err ( |e| {
584
+ self . flush_state ( & mut sweeper_state) . await . map_err ( |e| {
571
585
log_error ! ( self . logger, "Error persisting OutputSweeper: {:?}" , e) ;
572
586
} ) ?;
573
587
@@ -595,9 +609,12 @@ where
595
609
}
596
610
true
597
611
} ) ;
612
+
613
+ sweeper_state. dirty = true ;
598
614
}
599
615
600
- async fn persist_state ( & self , sweeper_state : & SweeperState ) -> Result < ( ) , io:: Error > {
616
+ /// Flushes the current state to the persistence layer and marks the state as clean.
617
+ async fn flush_state ( & self , sweeper_state : & mut SweeperState ) -> Result < ( ) , io:: Error > {
601
618
self . kv_store
602
619
. write (
603
620
OUTPUT_SWEEPER_PERSISTENCE_PRIMARY_NAMESPACE ,
@@ -617,6 +634,9 @@ where
617
634
) ;
618
635
e
619
636
} )
637
+ . map ( |_| {
638
+ sweeper_state. dirty = false ;
639
+ } )
620
640
}
621
641
622
642
fn spend_outputs (
@@ -649,13 +669,17 @@ where
649
669
}
650
670
}
651
671
}
672
+
673
+ sweeper_state. dirty = true ;
652
674
}
653
675
654
676
fn best_block_updated_internal (
655
677
& self , sweeper_state : & mut SweeperState , header : & Header , height : u32 ,
656
678
) {
657
679
sweeper_state. persistent . best_block = BestBlock :: new ( header. block_hash ( ) , height) ;
658
680
self . prune_confirmed_outputs ( sweeper_state) ;
681
+
682
+ sweeper_state. dirty = true ;
659
683
}
660
684
}
661
685
@@ -679,12 +703,8 @@ where
679
703
assert_eq ! ( state_lock. persistent. best_block. height, height - 1 ,
680
704
"Blocks must be connected in chain-order - the connected block height must be one greater than the previous height" ) ;
681
705
682
- self . transactions_confirmed_internal ( & mut * state_lock, header, txdata, height) ;
683
- self . best_block_updated_internal ( & mut * state_lock, header, height) ;
684
-
685
- // let _ = self.persist_state(&*state_lock).map_err(|e| {
686
- // log_error!(self.logger, "Error persisting OutputSweeper: {:?}", e);
687
- // });
706
+ self . transactions_confirmed_internal ( & mut state_lock, header, txdata, height) ;
707
+ self . best_block_updated_internal ( & mut state_lock, header, height) ;
688
708
}
689
709
690
710
fn block_disconnected ( & self , header : & Header , height : u32 ) {
@@ -706,9 +726,7 @@ where
706
726
}
707
727
}
708
728
709
- // self.persist_state(&*state_lock).unwrap_or_else(|e| {
710
- // log_error!(self.logger, "Error persisting OutputSweeper: {:?}", e);
711
- // });
729
+ state_lock. dirty = true ;
712
730
}
713
731
}
714
732
@@ -728,9 +746,6 @@ where
728
746
) {
729
747
let mut state_lock = self . sweeper_state . lock ( ) . unwrap ( ) ;
730
748
self . transactions_confirmed_internal ( & mut * state_lock, header, txdata, height) ;
731
- // self.persist_state(&*state_lock).unwrap_or_else(|e| {
732
- // log_error!(self.logger, "Error persisting OutputSweeper: {:?}", e);
733
- // });
734
749
}
735
750
736
751
fn transaction_unconfirmed ( & self , txid : & Txid ) {
@@ -753,18 +768,13 @@ where
753
768
. filter ( |o| o. status . confirmation_height ( ) >= Some ( unconf_height) )
754
769
. for_each ( |o| o. status . unconfirmed ( ) ) ;
755
770
756
- // self.persist_state(&*state_lock).unwrap_or_else(|e| {
757
- // log_error!(self.logger, "Error persisting OutputSweeper: {:?}", e);
758
- // });
771
+ state_lock. dirty = true ;
759
772
}
760
773
}
761
774
762
775
fn best_block_updated ( & self , header : & Header , height : u32 ) {
763
776
let mut state_lock = self . sweeper_state . lock ( ) . unwrap ( ) ;
764
- self . best_block_updated_internal ( & mut * state_lock, header, height) ;
765
- // let _ = self.persist_state(&*state_lock).map_err(|e| {
766
- // log_error!(self.logger, "Error persisting OutputSweeper: {:?}", e);
767
- // });
777
+ self . best_block_updated_internal ( & mut state_lock, header, height) ;
768
778
}
769
779
770
780
fn get_relevant_txids ( & self ) -> Vec < ( Txid , u32 , Option < BlockHash > ) > {
@@ -793,6 +803,7 @@ where
793
803
#[ derive( Debug ) ]
794
804
struct SweeperState {
795
805
persistent : PersistentSweeperState ,
806
+ dirty : bool ,
796
807
}
797
808
798
809
#[ derive( Debug , Clone ) ]
@@ -857,7 +868,7 @@ where
857
868
}
858
869
}
859
870
860
- let sweeper_state = Mutex :: new ( SweeperState { persistent : state } ) ;
871
+ let sweeper_state = Mutex :: new ( SweeperState { persistent : state, dirty : false } ) ;
861
872
Ok ( Self {
862
873
sweeper_state,
863
874
pending_sweep : AtomicBool :: new ( false ) ,
@@ -906,7 +917,7 @@ where
906
917
}
907
918
}
908
919
909
- let sweeper_state = Mutex :: new ( SweeperState { persistent : state } ) ;
920
+ let sweeper_state = Mutex :: new ( SweeperState { persistent : state, dirty : false } ) ;
910
921
Ok ( (
911
922
best_block,
912
923
OutputSweeper {
0 commit comments