@@ -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,9 +447,11 @@ where
445
447
446
448
state_lock. persistent . outputs . push ( output_info) ;
447
449
}
448
- self . persist_state ( & state_lock. persistent ) . map_err ( |e| {
449
- log_error ! ( self . logger, "Error persisting OutputSweeper: {:?}" , e) ;
450
- } )
450
+ self . persist_state ( & state_lock. persistent ) . inspect ( |_| state_lock. dirty = false ) . map_err (
451
+ |e| {
452
+ log_error ! ( self . logger, "Error persisting OutputSweeper: {:?}" , e) ;
453
+ } ,
454
+ )
451
455
}
452
456
453
457
/// Returns a list of the currently tracked spendable outputs.
@@ -504,12 +508,21 @@ where
504
508
505
509
// See if there is anything to sweep before requesting a change address.
506
510
{
507
- let sweeper_state = self . sweeper_state . lock ( ) . unwrap ( ) ;
511
+ let mut sweeper_state = self . sweeper_state . lock ( ) . unwrap ( ) ;
508
512
509
513
let cur_height = sweeper_state. persistent . best_block . height ;
510
514
let has_respends =
511
515
sweeper_state. persistent . outputs . iter ( ) . any ( |o| filter_fn ( o, cur_height) ) ;
512
516
if !has_respends {
517
+ // If there is nothing to sweep, we still persist the state if it is dirty.
518
+ if sweeper_state. dirty {
519
+ self . persist_state ( & sweeper_state. persistent )
520
+ . inspect ( |_| sweeper_state. dirty = false )
521
+ . map_err ( |e| {
522
+ log_error ! ( self . logger, "Error persisting OutputSweeper: {:?}" , e) ;
523
+ } ) ?;
524
+ }
525
+
513
526
return Ok ( ( ) ) ;
514
527
}
515
528
}
@@ -534,7 +547,8 @@ where
534
547
. collect ( ) ;
535
548
536
549
if respend_descriptors. is_empty ( ) {
537
- // It could be that a tx confirmed and there is now nothing to sweep anymore.
550
+ // It could be that a tx confirmed and there is now nothing to sweep anymore. If there is dirty state,
551
+ // we'll persist it in the next cycle.
538
552
return Ok ( ( ) ) ;
539
553
}
540
554
@@ -567,9 +581,11 @@ where
567
581
output_info. status . broadcast ( cur_hash, cur_height, spending_tx. clone ( ) ) ;
568
582
}
569
583
570
- self . persist_state ( & sweeper_state. persistent ) . map_err ( |e| {
571
- log_error ! ( self . logger, "Error persisting OutputSweeper: {:?}" , e) ;
572
- } ) ?;
584
+ self . persist_state ( & sweeper_state. persistent )
585
+ . inspect ( |_| sweeper_state. dirty = false )
586
+ . map_err ( |e| {
587
+ log_error ! ( self . logger, "Error persisting OutputSweeper: {:?}" , e) ;
588
+ } ) ?;
573
589
574
590
self . broadcaster . broadcast_transactions ( & [ & spending_tx] ) ;
575
591
}
@@ -595,6 +611,8 @@ where
595
611
}
596
612
true
597
613
} ) ;
614
+
615
+ sweeper_state. dirty = true ;
598
616
}
599
617
600
618
fn persist_state ( & self , sweeper_state : & PersistentSweeperState ) -> Result < ( ) , io:: Error > {
@@ -648,13 +666,17 @@ where
648
666
}
649
667
}
650
668
}
669
+
670
+ sweeper_state. dirty = true ;
651
671
}
652
672
653
673
fn best_block_updated_internal (
654
674
& self , sweeper_state : & mut SweeperState , header : & Header , height : u32 ,
655
675
) {
656
676
sweeper_state. persistent . best_block = BestBlock :: new ( header. block_hash ( ) , height) ;
657
677
self . prune_confirmed_outputs ( sweeper_state) ;
678
+
679
+ sweeper_state. dirty = true ;
658
680
}
659
681
}
660
682
@@ -678,12 +700,8 @@ where
678
700
assert_eq ! ( state_lock. persistent. best_block. height, height - 1 ,
679
701
"Blocks must be connected in chain-order - the connected block height must be one greater than the previous height" ) ;
680
702
681
- self . transactions_confirmed_internal ( & mut * state_lock, header, txdata, height) ;
682
- self . best_block_updated_internal ( & mut * state_lock, header, height) ;
683
-
684
- let _ = self . persist_state ( & state_lock. persistent ) . map_err ( |e| {
685
- log_error ! ( self . logger, "Error persisting OutputSweeper: {:?}" , e) ;
686
- } ) ;
703
+ self . transactions_confirmed_internal ( & mut state_lock, header, txdata, height) ;
704
+ self . best_block_updated_internal ( & mut state_lock, header, height) ;
687
705
}
688
706
689
707
fn block_disconnected ( & self , header : & Header , height : u32 ) {
@@ -705,9 +723,7 @@ where
705
723
}
706
724
}
707
725
708
- self . persist_state ( & state_lock. persistent ) . unwrap_or_else ( |e| {
709
- log_error ! ( self . logger, "Error persisting OutputSweeper: {:?}" , e) ;
710
- } ) ;
726
+ state_lock. dirty = true ;
711
727
}
712
728
}
713
729
@@ -727,9 +743,6 @@ where
727
743
) {
728
744
let mut state_lock = self . sweeper_state . lock ( ) . unwrap ( ) ;
729
745
self . transactions_confirmed_internal ( & mut * state_lock, header, txdata, height) ;
730
- self . persist_state ( & state_lock. persistent ) . unwrap_or_else ( |e| {
731
- log_error ! ( self . logger, "Error persisting OutputSweeper: {:?}" , e) ;
732
- } ) ;
733
746
}
734
747
735
748
fn transaction_unconfirmed ( & self , txid : & Txid ) {
@@ -752,18 +765,13 @@ where
752
765
. filter ( |o| o. status . confirmation_height ( ) >= Some ( unconf_height) )
753
766
. for_each ( |o| o. status . unconfirmed ( ) ) ;
754
767
755
- self . persist_state ( & state_lock. persistent ) . unwrap_or_else ( |e| {
756
- log_error ! ( self . logger, "Error persisting OutputSweeper: {:?}" , e) ;
757
- } ) ;
768
+ state_lock. dirty = true ;
758
769
}
759
770
}
760
771
761
772
fn best_block_updated ( & self , header : & Header , height : u32 ) {
762
773
let mut state_lock = self . sweeper_state . lock ( ) . unwrap ( ) ;
763
- self . best_block_updated_internal ( & mut * state_lock, header, height) ;
764
- let _ = self . persist_state ( & state_lock. persistent ) . map_err ( |e| {
765
- log_error ! ( self . logger, "Error persisting OutputSweeper: {:?}" , e) ;
766
- } ) ;
774
+ self . best_block_updated_internal ( & mut state_lock, header, height) ;
767
775
}
768
776
769
777
fn get_relevant_txids ( & self ) -> Vec < ( Txid , u32 , Option < BlockHash > ) > {
@@ -792,6 +800,7 @@ where
792
800
#[ derive( Debug ) ]
793
801
struct SweeperState {
794
802
persistent : PersistentSweeperState ,
803
+ dirty : bool ,
795
804
}
796
805
797
806
#[ derive( Debug , Clone ) ]
@@ -856,7 +865,7 @@ where
856
865
}
857
866
}
858
867
859
- let sweeper_state = Mutex :: new ( SweeperState { persistent : state } ) ;
868
+ let sweeper_state = Mutex :: new ( SweeperState { persistent : state, dirty : false } ) ;
860
869
Ok ( Self {
861
870
sweeper_state,
862
871
pending_sweep : AtomicBool :: new ( false ) ,
@@ -905,7 +914,7 @@ where
905
914
}
906
915
}
907
916
908
- let sweeper_state = Mutex :: new ( SweeperState { persistent : state } ) ;
917
+ let sweeper_state = Mutex :: new ( SweeperState { persistent : state, dirty : false } ) ;
909
918
Ok ( (
910
919
best_block,
911
920
OutputSweeper {
0 commit comments