@@ -15,7 +15,7 @@ use bitcoin::BlockHash;
15
15
use bitcoin_bech32:: WitnessProgram ;
16
16
use disk:: { INBOUND_PAYMENTS_FNAME , OUTBOUND_PAYMENTS_FNAME } ;
17
17
use lightning:: chain:: { chainmonitor, ChannelMonitorUpdateStatus } ;
18
- use lightning:: chain:: { Filter , Watch } ;
18
+ use lightning:: chain:: { BestBlock , Filter , Watch } ;
19
19
use lightning:: events:: bump_transaction:: { BumpTransactionEventHandler , Wallet } ;
20
20
use lightning:: events:: { Event , PaymentFailureReason , PaymentPurpose } ;
21
21
use lightning:: ln:: channelmanager:: { self , RecentPaymentDetails } ;
@@ -30,10 +30,14 @@ use lightning::routing::gossip;
30
30
use lightning:: routing:: gossip:: { NodeId , P2PGossipSync } ;
31
31
use lightning:: routing:: router:: DefaultRouter ;
32
32
use lightning:: routing:: scoring:: ProbabilisticScoringFeeParameters ;
33
- use lightning:: sign:: { EntropySource , InMemorySigner , KeysManager , SpendableOutputDescriptor } ;
33
+ use lightning:: sign:: { EntropySource , InMemorySigner , KeysManager } ;
34
34
use lightning:: util:: config:: UserConfig ;
35
- use lightning:: util:: persist:: { self , KVStore , MonitorUpdatingPersister } ;
35
+ use lightning:: util:: persist:: {
36
+ self , KVStore , MonitorUpdatingPersister , OUTPUT_SWEEPER_PERSISTENCE_KEY ,
37
+ OUTPUT_SWEEPER_PERSISTENCE_PRIMARY_NAMESPACE , OUTPUT_SWEEPER_PERSISTENCE_SECONDARY_NAMESPACE ,
38
+ } ;
36
39
use lightning:: util:: ser:: { Readable , ReadableArgs , Writeable , Writer } ;
40
+ use lightning:: util:: sweep as ldk_sweep;
37
41
use lightning:: { chain, impl_writeable_tlv_based, impl_writeable_tlv_based_enum} ;
38
42
use lightning_background_processor:: { process_events_async, GossipSync } ;
39
43
use lightning_block_sync:: init;
@@ -172,13 +176,23 @@ pub(crate) type BumpTxEventHandler = BumpTransactionEventHandler<
172
176
Arc < FilesystemLogger > ,
173
177
> ;
174
178
179
+ pub ( crate ) type OutputSweeper = ldk_sweep:: OutputSweeper <
180
+ Arc < BitcoindClient > ,
181
+ Arc < BitcoindClient > ,
182
+ Arc < BitcoindClient > ,
183
+ Arc < dyn Filter + Send + Sync > ,
184
+ Arc < FilesystemStore > ,
185
+ Arc < FilesystemLogger > ,
186
+ Arc < KeysManager > ,
187
+ > ;
188
+
175
189
async fn handle_ldk_events (
176
190
channel_manager : Arc < ChannelManager > , bitcoind_client : & BitcoindClient ,
177
191
network_graph : & NetworkGraph , keys_manager : & KeysManager ,
178
192
bump_tx_event_handler : & BumpTxEventHandler , peer_manager : Arc < PeerManager > ,
179
193
inbound_payments : Arc < Mutex < InboundPaymentInfoStorage > > ,
180
194
outbound_payments : Arc < Mutex < OutboundPaymentInfoStorage > > , fs_store : Arc < FilesystemStore > ,
181
- network : Network , event : Event ,
195
+ output_sweeper : Arc < OutputSweeper > , network : Network , event : Event ,
182
196
) {
183
197
match event {
184
198
Event :: FundingGenerationReady {
@@ -461,22 +475,8 @@ async fn handle_ldk_events(
461
475
forwarding_channel_manager. process_pending_htlc_forwards ( ) ;
462
476
} ) ;
463
477
} ,
464
- Event :: SpendableOutputs { outputs, channel_id : _ } => {
465
- // SpendableOutputDescriptors, of which outputs is a vec of, are critical to keep track
466
- // of! While a `StaticOutput` descriptor is just an output to a static, well-known key,
467
- // other descriptors are not currently ever regenerated for you by LDK. Once we return
468
- // from this method, the descriptor will be gone, and you may lose track of some funds.
469
- //
470
- // Here we simply persist them to disk, with a background task running which will try
471
- // to spend them regularly (possibly duplicatively/RBF'ing them). These can just be
472
- // treated as normal funds where possible - they are only spendable by us and there is
473
- // no rush to claim them.
474
- for output in outputs {
475
- let key = hex_utils:: hex_str ( & keys_manager. get_secure_random_bytes ( ) ) ;
476
- // Note that if the type here changes our read code needs to change as well.
477
- let output: SpendableOutputDescriptor = output;
478
- fs_store. write ( PENDING_SPENDABLE_OUTPUT_DIR , "" , & key, & output. encode ( ) ) . unwrap ( ) ;
479
- }
478
+ Event :: SpendableOutputs { outputs, channel_id } => {
479
+ output_sweeper. track_spendable_outputs ( outputs, channel_id, false , None ) . unwrap ( ) ;
480
480
} ,
481
481
Event :: ChannelPending { channel_id, counterparty_node_id, .. } => {
482
482
println ! (
@@ -743,14 +743,50 @@ async fn start_ldk() {
743
743
}
744
744
} ;
745
745
746
- // Step 12: Sync ChannelMonitors and ChannelManager to chain tip
746
+ // Step 12: Initialize the OutputSweeper.
747
+ let ( sweeper_best_block, output_sweeper) = match fs_store. read (
748
+ OUTPUT_SWEEPER_PERSISTENCE_PRIMARY_NAMESPACE ,
749
+ OUTPUT_SWEEPER_PERSISTENCE_SECONDARY_NAMESPACE ,
750
+ OUTPUT_SWEEPER_PERSISTENCE_KEY ,
751
+ ) {
752
+ Err ( e) if e. kind ( ) == io:: ErrorKind :: NotFound => {
753
+ let sweeper = OutputSweeper :: new (
754
+ channel_manager. current_best_block ( ) ,
755
+ broadcaster. clone ( ) ,
756
+ fee_estimator. clone ( ) ,
757
+ None ,
758
+ keys_manager. clone ( ) ,
759
+ bitcoind_client. clone ( ) ,
760
+ fs_store. clone ( ) ,
761
+ logger. clone ( ) ,
762
+ ) ;
763
+ ( channel_manager. current_best_block ( ) , sweeper)
764
+ } ,
765
+ Ok ( mut bytes) => {
766
+ let read_args = (
767
+ broadcaster. clone ( ) ,
768
+ fee_estimator. clone ( ) ,
769
+ None ,
770
+ keys_manager. clone ( ) ,
771
+ bitcoind_client. clone ( ) ,
772
+ fs_store. clone ( ) ,
773
+ logger. clone ( ) ,
774
+ ) ;
775
+ let mut reader = io:: Cursor :: new ( & mut bytes) ;
776
+ <( BestBlock , OutputSweeper ) >:: read ( & mut reader, read_args)
777
+ . expect ( "Failed to deserialize OutputSweeper" )
778
+ } ,
779
+ Err ( e) => panic ! ( "Failed to read OutputSweeper with {}" , e) ,
780
+ } ;
781
+
782
+ // Step 13: Sync ChannelMonitors, ChannelManager and OutputSweeper to chain tip
747
783
let mut chain_listener_channel_monitors = Vec :: new ( ) ;
748
784
let mut cache = UnboundedCache :: new ( ) ;
749
785
let chain_tip = if restarting_node {
750
- let mut chain_listeners = vec ! [ (
751
- channel_manager_blockhash,
752
- & channel_manager as & ( dyn chain:: Listen + Send + Sync ) ,
753
- ) ] ;
786
+ let mut chain_listeners = vec ! [
787
+ ( channel_manager_blockhash, & channel_manager as & ( dyn chain :: Listen + Send + Sync ) ) ,
788
+ ( sweeper_best_block . block_hash , & output_sweeper as & ( dyn chain:: Listen + Send + Sync ) ) ,
789
+ ] ;
754
790
755
791
for ( blockhash, channel_monitor) in channelmonitors. drain ( ..) {
756
792
let outpoint = channel_monitor. get_funding_txo ( ) . 0 ;
@@ -780,7 +816,7 @@ async fn start_ldk() {
780
816
polled_chain_tip
781
817
} ;
782
818
783
- // Step 13 : Give ChannelMonitors to ChainMonitor
819
+ // Step 14 : Give ChannelMonitors to ChainMonitor
784
820
for item in chain_listener_channel_monitors. drain ( ..) {
785
821
let channel_monitor = item. 1 . 0 ;
786
822
let funding_outpoint = item. 2 ;
@@ -790,11 +826,11 @@ async fn start_ldk() {
790
826
) ;
791
827
}
792
828
793
- // Step 14 : Optional: Initialize the P2PGossipSync
829
+ // Step 15 : Optional: Initialize the P2PGossipSync
794
830
let gossip_sync =
795
831
Arc :: new ( P2PGossipSync :: new ( Arc :: clone ( & network_graph) , None , Arc :: clone ( & logger) ) ) ;
796
832
797
- // Step 15 : Initialize the PeerManager
833
+ // Step 16 : Initialize the PeerManager
798
834
let channel_manager: Arc < ChannelManager > = Arc :: new ( channel_manager) ;
799
835
let onion_messenger: Arc < OnionMessenger > = Arc :: new ( OnionMessenger :: new (
800
836
Arc :: clone ( & keys_manager) ,
@@ -832,7 +868,7 @@ async fn start_ldk() {
832
868
gossip_sync. add_utxo_lookup ( Some ( utxo_lookup) ) ;
833
869
834
870
// ## Running LDK
835
- // Step 16 : Initialize networking
871
+ // Step 17 : Initialize networking
836
872
837
873
let peer_manager_connection_handler = peer_manager. clone ( ) ;
838
874
let listening_port = args. ldk_peer_listening_port ;
@@ -858,14 +894,17 @@ async fn start_ldk() {
858
894
}
859
895
} ) ;
860
896
861
- // Step 17: Connect and Disconnect Blocks
897
+ // Step 18: Connect and Disconnect Blocks
898
+ let output_sweeper: Arc < OutputSweeper > = Arc :: new ( output_sweeper) ;
862
899
let channel_manager_listener = channel_manager. clone ( ) ;
863
900
let chain_monitor_listener = chain_monitor. clone ( ) ;
901
+ let output_sweeper_listener = output_sweeper. clone ( ) ;
864
902
let bitcoind_block_source = bitcoind_client. clone ( ) ;
865
903
let network = args. network ;
866
904
tokio:: spawn ( async move {
867
905
let chain_poller = poll:: ChainPoller :: new ( bitcoind_block_source. as_ref ( ) , network) ;
868
- let chain_listener = ( chain_monitor_listener, channel_manager_listener) ;
906
+ let chain_listener =
907
+ ( chain_monitor_listener, & ( channel_manager_listener, output_sweeper_listener) ) ;
869
908
let mut spv_client = SpvClient :: new ( chain_tip, chain_poller, & mut cache, & chain_listener) ;
870
909
loop {
871
910
spv_client. poll_best_tip ( ) . await . unwrap ( ) ;
@@ -904,7 +943,7 @@ async fn start_ldk() {
904
943
. write ( "" , "" , OUTBOUND_PAYMENTS_FNAME , & outbound_payments. lock ( ) . unwrap ( ) . encode ( ) )
905
944
. unwrap ( ) ;
906
945
907
- // Step 18 : Handle LDK Events
946
+ // Step 19 : Handle LDK Events
908
947
let channel_manager_event_listener = Arc :: clone ( & channel_manager) ;
909
948
let bitcoind_client_event_listener = Arc :: clone ( & bitcoind_client) ;
910
949
let network_graph_event_listener = Arc :: clone ( & network_graph) ;
@@ -913,6 +952,7 @@ async fn start_ldk() {
913
952
let outbound_payments_event_listener = Arc :: clone ( & outbound_payments) ;
914
953
let fs_store_event_listener = Arc :: clone ( & fs_store) ;
915
954
let peer_manager_event_listener = Arc :: clone ( & peer_manager) ;
955
+ let output_sweeper_event_listener = Arc :: clone ( & output_sweeper) ;
916
956
let network = args. network ;
917
957
let event_handler = move |event : Event | {
918
958
let channel_manager_event_listener = Arc :: clone ( & channel_manager_event_listener) ;
@@ -924,6 +964,7 @@ async fn start_ldk() {
924
964
let outbound_payments_event_listener = Arc :: clone ( & outbound_payments_event_listener) ;
925
965
let fs_store_event_listener = Arc :: clone ( & fs_store_event_listener) ;
926
966
let peer_manager_event_listener = Arc :: clone ( & peer_manager_event_listener) ;
967
+ let output_sweeper_event_listener = Arc :: clone ( & output_sweeper_event_listener) ;
927
968
async move {
928
969
handle_ldk_events (
929
970
channel_manager_event_listener,
@@ -935,17 +976,18 @@ async fn start_ldk() {
935
976
inbound_payments_event_listener,
936
977
outbound_payments_event_listener,
937
978
fs_store_event_listener,
979
+ output_sweeper_event_listener,
938
980
network,
939
981
event,
940
982
)
941
983
. await ;
942
984
}
943
985
} ;
944
986
945
- // Step 19 : Persist ChannelManager and NetworkGraph
987
+ // Step 20 : Persist ChannelManager and NetworkGraph
946
988
let persister = Arc :: new ( FilesystemStore :: new ( ldk_data_dir. clone ( ) . into ( ) ) ) ;
947
989
948
- // Step 20 : Background Processing
990
+ // Step 21 : Background Processing
949
991
let ( bp_exit, bp_exit_check) = tokio:: sync:: watch:: channel ( ( ) ) ;
950
992
let mut background_processor = tokio:: spawn ( process_events_async (
951
993
Arc :: clone ( & persister) ,
@@ -1034,6 +1076,7 @@ async fn start_ldk() {
1034
1076
}
1035
1077
} ) ;
1036
1078
1079
+ // TODO: remove after a few months since the new `OutputSweeper` was added in LDK v0.0.123.
1037
1080
tokio:: spawn ( sweep:: periodic_sweep (
1038
1081
ldk_data_dir. clone ( ) ,
1039
1082
Arc :: clone ( & keys_manager) ,
0 commit comments