@@ -347,7 +347,13 @@ impl Builder {
347
347
EsploraBlockchain :: from_client ( tx_sync. client ( ) . clone ( ) , BDK_CLIENT_STOP_GAP )
348
348
. with_concurrency ( BDK_CLIENT_CONCURRENCY ) ;
349
349
350
- let wallet = Arc :: new ( Wallet :: new ( blockchain, bdk_wallet, Arc :: clone ( & logger) ) ) ;
350
+ let runtime = Arc :: new ( RwLock :: new ( None ) ) ;
351
+ let wallet = Arc :: new ( Wallet :: new (
352
+ blockchain,
353
+ bdk_wallet,
354
+ Arc :: clone ( & runtime) ,
355
+ Arc :: clone ( & logger) ,
356
+ ) ) ;
351
357
352
358
let kv_store = Arc :: new ( FilesystemStore :: new ( ldk_data_dir. clone ( ) . into ( ) ) ) ;
353
359
@@ -556,10 +562,11 @@ impl Builder {
556
562
}
557
563
} ;
558
564
559
- let running = RwLock :: new ( None ) ;
565
+ let stop_running = Arc :: new ( AtomicBool :: new ( false ) ) ;
560
566
561
567
Node {
562
- running,
568
+ runtime,
569
+ stop_running,
563
570
config,
564
571
wallet,
565
572
tx_sync,
@@ -579,18 +586,12 @@ impl Builder {
579
586
}
580
587
}
581
588
582
- /// Wraps all objects that need to be preserved during the run time of [`Node`]. Will be dropped
583
- /// upon [`Node::stop()`].
584
- struct Runtime {
585
- tokio_runtime : Arc < tokio:: runtime:: Runtime > ,
586
- stop_runtime : Arc < AtomicBool > ,
587
- }
588
-
589
589
/// The main interface object of LDK Node, wrapping the necessary LDK and BDK functionalities.
590
590
///
591
591
/// Needs to be initialized and instantiated through [`Builder::build`].
592
592
pub struct Node {
593
- running : RwLock < Option < Runtime > > ,
593
+ runtime : Arc < RwLock < Option < tokio:: runtime:: Runtime > > > ,
594
+ stop_running : Arc < AtomicBool > ,
594
595
config : Arc < Config > ,
595
596
wallet : Arc < Wallet < bdk:: database:: SqliteDatabase > > ,
596
597
tx_sync : Arc < EsploraSyncClient < Arc < FilesystemLogger > > > ,
@@ -616,49 +617,15 @@ impl Node {
616
617
/// a thread-safe manner.
617
618
pub fn start ( & self ) -> Result < ( ) , Error > {
618
619
// Acquire a run lock and hold it until we're setup.
619
- let mut run_lock = self . running . write ( ) . unwrap ( ) ;
620
- if run_lock . is_some ( ) {
620
+ let mut runtime_lock = self . runtime . write ( ) . unwrap ( ) ;
621
+ if runtime_lock . is_some ( ) {
621
622
// We're already running.
622
623
return Err ( Error :: AlreadyRunning ) ;
623
624
}
624
625
625
- let runtime = self . setup_runtime ( ) ?;
626
- * run_lock = Some ( runtime) ;
627
- Ok ( ( ) )
628
- }
626
+ let runtime = tokio:: runtime:: Builder :: new_multi_thread ( ) . enable_all ( ) . build ( ) . unwrap ( ) ;
629
627
630
- /// Disconnects all peers, stops all running background tasks, and shuts down [`Node`].
631
- ///
632
- /// After this returns most API methods will return [`Error::NotRunning`].
633
- pub fn stop ( & self ) -> Result < ( ) , Error > {
634
- let mut run_lock = self . running . write ( ) . unwrap ( ) ;
635
- if run_lock. is_none ( ) {
636
- return Err ( Error :: NotRunning ) ;
637
- }
638
-
639
- let runtime = run_lock. as_ref ( ) . unwrap ( ) ;
640
-
641
- // Stop the runtime.
642
- runtime. stop_runtime . store ( true , Ordering :: Release ) ;
643
-
644
- // Stop disconnect peers.
645
- self . peer_manager . disconnect_all_peers ( ) ;
646
-
647
- // Drop the held runtimes.
648
- self . wallet . drop_runtime ( ) ;
649
-
650
- // Drop the runtime, which stops the background processor and any possibly remaining tokio threads.
651
- * run_lock = None ;
652
- Ok ( ( ) )
653
- }
654
-
655
- fn setup_runtime ( & self ) -> Result < Runtime , Error > {
656
- let tokio_runtime =
657
- Arc :: new ( tokio:: runtime:: Builder :: new_multi_thread ( ) . enable_all ( ) . build ( ) . unwrap ( ) ) ;
658
-
659
- self . wallet . set_runtime ( Arc :: clone ( & tokio_runtime) ) ;
660
-
661
- let stop_runtime = Arc :: new ( AtomicBool :: new ( false ) ) ;
628
+ let stop_running = Arc :: new ( AtomicBool :: new ( false ) ) ;
662
629
663
630
let event_handler = Arc :: new ( EventHandler :: new (
664
631
Arc :: clone ( & self . wallet ) ,
@@ -667,7 +634,7 @@ impl Node {
667
634
Arc :: clone ( & self . network_graph ) ,
668
635
Arc :: clone ( & self . keys_manager ) ,
669
636
Arc :: clone ( & self . payment_store ) ,
670
- Arc :: clone ( & tokio_runtime ) ,
637
+ Arc :: clone ( & self . runtime ) ,
671
638
Arc :: clone ( & self . logger ) ,
672
639
Arc :: clone ( & self . config ) ,
673
640
) ) ;
@@ -678,7 +645,7 @@ impl Node {
678
645
let sync_cman = Arc :: clone ( & self . channel_manager ) ;
679
646
let sync_cmon = Arc :: clone ( & self . chain_monitor ) ;
680
647
let sync_logger = Arc :: clone ( & self . logger ) ;
681
- let stop_sync = Arc :: clone ( & stop_runtime ) ;
648
+ let stop_sync = Arc :: clone ( & stop_running ) ;
682
649
683
650
std:: thread:: spawn ( move || {
684
651
tokio:: runtime:: Builder :: new_current_thread ( ) . enable_all ( ) . build ( ) . unwrap ( ) . block_on (
@@ -709,8 +676,8 @@ impl Node {
709
676
} ) ;
710
677
711
678
let sync_logger = Arc :: clone ( & self . logger ) ;
712
- let stop_sync = Arc :: clone ( & stop_runtime ) ;
713
- tokio_runtime . spawn ( async move {
679
+ let stop_sync = Arc :: clone ( & stop_running ) ;
680
+ runtime . spawn ( async move {
714
681
loop {
715
682
if stop_sync. load ( Ordering :: Acquire ) {
716
683
return ;
@@ -737,10 +704,10 @@ impl Node {
737
704
if let Some ( listening_address) = & self . config . listening_address {
738
705
// Setup networking
739
706
let peer_manager_connection_handler = Arc :: clone ( & self . peer_manager ) ;
740
- let stop_listen = Arc :: clone ( & stop_runtime ) ;
707
+ let stop_listen = Arc :: clone ( & stop_running ) ;
741
708
let listening_address = listening_address. clone ( ) ;
742
709
743
- tokio_runtime . spawn ( async move {
710
+ runtime . spawn ( async move {
744
711
let listener =
745
712
tokio:: net:: TcpListener :: bind ( listening_address) . await . expect (
746
713
"Failed to bind to listen address/port - is something else already listening on it?" ,
@@ -767,8 +734,8 @@ impl Node {
767
734
let connect_pm = Arc :: clone ( & self . peer_manager ) ;
768
735
let connect_logger = Arc :: clone ( & self . logger ) ;
769
736
let connect_peer_store = Arc :: clone ( & self . peer_store ) ;
770
- let stop_connect = Arc :: clone ( & stop_runtime ) ;
771
- tokio_runtime . spawn ( async move {
737
+ let stop_connect = Arc :: clone ( & stop_running ) ;
738
+ runtime . spawn ( async move {
772
739
let mut interval = tokio:: time:: interval ( PEER_RECONNECTION_INTERVAL ) ;
773
740
loop {
774
741
if stop_connect. load ( Ordering :: Acquire ) {
@@ -808,7 +775,7 @@ impl Node {
808
775
let background_peer_man = Arc :: clone ( & self . peer_manager ) ;
809
776
let background_logger = Arc :: clone ( & self . logger ) ;
810
777
let background_scorer = Arc :: clone ( & self . scorer ) ;
811
- let stop_background_processing = Arc :: clone ( & stop_runtime ) ;
778
+ let stop_background_processing = Arc :: clone ( & stop_running ) ;
812
779
let sleeper = move |d| {
813
780
let stop = Arc :: clone ( & stop_background_processing) ;
814
781
Box :: pin ( async move {
@@ -821,7 +788,7 @@ impl Node {
821
788
} )
822
789
} ;
823
790
824
- tokio_runtime . spawn ( async move {
791
+ runtime . spawn ( async move {
825
792
process_events_async (
826
793
background_persister,
827
794
|e| background_event_handler. handle_event ( e) ,
@@ -838,7 +805,23 @@ impl Node {
838
805
. expect ( "Failed to process events" ) ;
839
806
} ) ;
840
807
841
- Ok ( Runtime { tokio_runtime, stop_runtime } )
808
+ * runtime_lock = Some ( runtime) ;
809
+ Ok ( ( ) )
810
+ }
811
+
812
+ /// Disconnects all peers, stops all running background tasks, and shuts down [`Node`].
813
+ ///
814
+ /// After this returns most API methods will return [`Error::NotRunning`].
815
+ pub fn stop ( & self ) -> Result < ( ) , Error > {
816
+ let runtime = self . runtime . write ( ) . unwrap ( ) . take ( ) . ok_or ( Error :: NotRunning ) ?;
817
+ // Stop the runtime.
818
+ self . stop_running . store ( true , Ordering :: Release ) ;
819
+
820
+ // Stop disconnect peers.
821
+ self . peer_manager . disconnect_all_peers ( ) ;
822
+
823
+ runtime. shutdown_timeout ( Duration :: from_secs ( 10 ) ) ;
824
+ Ok ( ( ) )
842
825
}
843
826
844
827
/// Blocks until the next event is available.
@@ -888,12 +871,11 @@ impl Node {
888
871
pub fn connect (
889
872
& self , node_id : PublicKey , address : SocketAddr , permanently : bool ,
890
873
) -> Result < ( ) , Error > {
891
- let runtime_lock = self . running . read ( ) . unwrap ( ) ;
892
- if runtime_lock . is_none ( ) {
874
+ let rt_lock = self . runtime . read ( ) . unwrap ( ) ;
875
+ if rt_lock . is_none ( ) {
893
876
return Err ( Error :: NotRunning ) ;
894
877
}
895
-
896
- let runtime = runtime_lock. as_ref ( ) . unwrap ( ) ;
878
+ let runtime = rt_lock. as_ref ( ) . unwrap ( ) ;
897
879
898
880
let peer_info = PeerInfo { pubkey : node_id, address } ;
899
881
@@ -905,7 +887,7 @@ impl Node {
905
887
let con_pm = Arc :: clone ( & self . peer_manager ) ;
906
888
907
889
tokio:: task:: block_in_place ( move || {
908
- runtime. tokio_runtime . block_on ( async move {
890
+ runtime. block_on ( async move {
909
891
let res =
910
892
connect_peer_if_necessary ( con_peer_pubkey, con_peer_addr, con_pm, con_logger)
911
893
. await ;
@@ -931,8 +913,8 @@ impl Node {
931
913
/// Will also remove the peer from the peer store, i.e., after this has been called we won't
932
914
/// try to reconnect on restart.
933
915
pub fn disconnect ( & self , counterparty_node_id : & PublicKey ) -> Result < ( ) , Error > {
934
- let runtime_lock = self . running . read ( ) . unwrap ( ) ;
935
- if runtime_lock . is_none ( ) {
916
+ let rt_lock = self . runtime . read ( ) . unwrap ( ) ;
917
+ if rt_lock . is_none ( ) {
936
918
return Err ( Error :: NotRunning ) ;
937
919
}
938
920
@@ -962,12 +944,11 @@ impl Node {
962
944
& self , node_id : PublicKey , address : SocketAddr , channel_amount_sats : u64 ,
963
945
push_to_counterparty_msat : Option < u64 > , announce_channel : bool ,
964
946
) -> Result < ( ) , Error > {
965
- let runtime_lock = self . running . read ( ) . unwrap ( ) ;
966
- if runtime_lock . is_none ( ) {
947
+ let rt_lock = self . runtime . read ( ) . unwrap ( ) ;
948
+ if rt_lock . is_none ( ) {
967
949
return Err ( Error :: NotRunning ) ;
968
950
}
969
-
970
- let runtime = runtime_lock. as_ref ( ) . unwrap ( ) ;
951
+ let runtime = rt_lock. as_ref ( ) . unwrap ( ) ;
971
952
972
953
let cur_balance = self . wallet . get_balance ( ) ?;
973
954
if cur_balance. get_spendable ( ) < channel_amount_sats {
@@ -985,7 +966,7 @@ impl Node {
985
966
let con_pm = Arc :: clone ( & self . peer_manager ) ;
986
967
987
968
tokio:: task:: block_in_place ( move || {
988
- runtime. tokio_runtime . block_on ( async move {
969
+ runtime. block_on ( async move {
989
970
let res =
990
971
connect_peer_if_necessary ( con_peer_pubkey, con_peer_addr, con_pm, con_logger)
991
972
. await ;
@@ -1040,10 +1021,12 @@ impl Node {
1040
1021
///
1041
1022
/// Note that the wallets will be also synced regularly in the background.
1042
1023
pub fn sync_wallets ( & self ) -> Result < ( ) , Error > {
1043
- let runtime_lock = self . running . read ( ) . unwrap ( ) ;
1044
- if runtime_lock . is_none ( ) {
1024
+ let rt_lock = self . runtime . read ( ) . unwrap ( ) ;
1025
+ if rt_lock . is_none ( ) {
1045
1026
return Err ( Error :: NotRunning ) ;
1046
1027
}
1028
+ let runtime = rt_lock. as_ref ( ) . unwrap ( ) ;
1029
+
1047
1030
let wallet = Arc :: clone ( & self . wallet ) ;
1048
1031
let tx_sync = Arc :: clone ( & self . tx_sync ) ;
1049
1032
let sync_cman = Arc :: clone ( & self . channel_manager ) ;
@@ -1054,7 +1037,6 @@ impl Node {
1054
1037
& * sync_cmon as & ( dyn Confirm + Sync + Send ) ,
1055
1038
] ;
1056
1039
1057
- let runtime = runtime_lock. as_ref ( ) . unwrap ( ) ;
1058
1040
tokio:: task:: block_in_place ( move || {
1059
1041
tokio:: runtime:: Builder :: new_current_thread ( ) . enable_all ( ) . build ( ) . unwrap ( ) . block_on (
1060
1042
async move {
@@ -1079,7 +1061,7 @@ impl Node {
1079
1061
1080
1062
let sync_logger = Arc :: clone ( & self . logger ) ;
1081
1063
tokio:: task:: block_in_place ( move || {
1082
- runtime. tokio_runtime . block_on ( async move {
1064
+ runtime. block_on ( async move {
1083
1065
let now = Instant :: now ( ) ;
1084
1066
match tx_sync. sync ( confirmables) . await {
1085
1067
Ok ( ( ) ) => {
@@ -1114,7 +1096,8 @@ impl Node {
1114
1096
1115
1097
/// Send a payement given an invoice.
1116
1098
pub fn send_payment ( & self , invoice : & Invoice ) -> Result < PaymentHash , Error > {
1117
- if self . running . read ( ) . unwrap ( ) . is_none ( ) {
1099
+ let rt_lock = self . runtime . read ( ) . unwrap ( ) ;
1100
+ if rt_lock. is_none ( ) {
1118
1101
return Err ( Error :: NotRunning ) ;
1119
1102
}
1120
1103
@@ -1180,7 +1163,8 @@ impl Node {
1180
1163
pub fn send_payment_using_amount (
1181
1164
& self , invoice : & Invoice , amount_msat : u64 ,
1182
1165
) -> Result < PaymentHash , Error > {
1183
- if self . running . read ( ) . unwrap ( ) . is_none ( ) {
1166
+ let rt_lock = self . runtime . read ( ) . unwrap ( ) ;
1167
+ if rt_lock. is_none ( ) {
1184
1168
return Err ( Error :: NotRunning ) ;
1185
1169
}
1186
1170
@@ -1268,7 +1252,8 @@ impl Node {
1268
1252
pub fn send_spontaneous_payment (
1269
1253
& self , amount_msat : u64 , node_id : & PublicKey ,
1270
1254
) -> Result < PaymentHash , Error > {
1271
- if self . running . read ( ) . unwrap ( ) . is_none ( ) {
1255
+ let rt_lock = self . runtime . read ( ) . unwrap ( ) ;
1256
+ if rt_lock. is_none ( ) {
1272
1257
return Err ( Error :: NotRunning ) ;
1273
1258
}
1274
1259
0 commit comments