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