@@ -329,7 +329,13 @@ impl Builder {
329
329
EsploraBlockchain :: from_client ( tx_sync. client ( ) . clone ( ) , BDK_CLIENT_STOP_GAP )
330
330
. with_concurrency ( BDK_CLIENT_CONCURRENCY ) ;
331
331
332
- let wallet = Arc :: new ( Wallet :: new ( blockchain, bdk_wallet, Arc :: clone ( & logger) ) ) ;
332
+ let runtime = Arc :: new ( RwLock :: new ( None ) ) ;
333
+ let wallet = Arc :: new ( Wallet :: new (
334
+ blockchain,
335
+ bdk_wallet,
336
+ Arc :: clone ( & runtime) ,
337
+ Arc :: clone ( & logger) ,
338
+ ) ) ;
333
339
334
340
let kv_store = Arc :: new ( FilesystemStore :: new ( ldk_data_dir. clone ( ) . into ( ) ) ) ;
335
341
@@ -538,10 +544,11 @@ impl Builder {
538
544
}
539
545
} ;
540
546
541
- let running = RwLock :: new ( None ) ;
547
+ let stop_running = Arc :: new ( AtomicBool :: new ( false ) ) ;
542
548
543
549
Node {
544
- running,
550
+ runtime,
551
+ stop_running,
545
552
config,
546
553
wallet,
547
554
tx_sync,
@@ -561,18 +568,12 @@ impl Builder {
561
568
}
562
569
}
563
570
564
- /// Wraps all objects that need to be preserved during the run time of [`Node`]. Will be dropped
565
- /// upon [`Node::stop()`].
566
- struct Runtime {
567
- tokio_runtime : Arc < tokio:: runtime:: Runtime > ,
568
- stop_runtime : Arc < AtomicBool > ,
569
- }
570
-
571
571
/// The main interface object of LDK Node, wrapping the necessary LDK and BDK functionalities.
572
572
///
573
573
/// Needs to be initialized and instantiated through [`Builder::build`].
574
574
pub struct Node {
575
- running : RwLock < Option < Runtime > > ,
575
+ runtime : Arc < RwLock < Option < tokio:: runtime:: Runtime > > > ,
576
+ stop_running : Arc < AtomicBool > ,
576
577
config : Arc < Config > ,
577
578
wallet : Arc < Wallet < bdk:: database:: SqliteDatabase > > ,
578
579
tx_sync : Arc < EsploraSyncClient < Arc < FilesystemLogger > > > ,
@@ -598,49 +599,15 @@ impl Node {
598
599
/// a thread-safe manner.
599
600
pub fn start ( & self ) -> Result < ( ) , Error > {
600
601
// Acquire a run lock and hold it until we're setup.
601
- let mut run_lock = self . running . write ( ) . unwrap ( ) ;
602
- if run_lock . is_some ( ) {
602
+ let mut runtime_lock = self . runtime . write ( ) . unwrap ( ) ;
603
+ if runtime_lock . is_some ( ) {
603
604
// We're already running.
604
605
return Err ( Error :: AlreadyRunning ) ;
605
606
}
606
607
607
- let runtime = self . setup_runtime ( ) ?;
608
- * run_lock = Some ( runtime) ;
609
- Ok ( ( ) )
610
- }
611
-
612
- /// Disconnects all peers, stops all running background tasks, and shuts down [`Node`].
613
- ///
614
- /// After this returns most API methods will return [`Error::NotRunning`].
615
- pub fn stop ( & self ) -> Result < ( ) , Error > {
616
- let mut run_lock = self . running . write ( ) . unwrap ( ) ;
617
- if run_lock. is_none ( ) {
618
- return Err ( Error :: NotRunning ) ;
619
- }
620
-
621
- let runtime = run_lock. as_ref ( ) . unwrap ( ) ;
622
-
623
- // Stop the runtime.
624
- runtime. stop_runtime . store ( true , Ordering :: Release ) ;
625
-
626
- // Stop disconnect peers.
627
- self . peer_manager . disconnect_all_peers ( ) ;
628
-
629
- // Drop the held runtimes.
630
- self . wallet . drop_runtime ( ) ;
608
+ let runtime = tokio:: runtime:: Builder :: new_multi_thread ( ) . enable_all ( ) . build ( ) . unwrap ( ) ;
631
609
632
- // Drop the runtime, which stops the background processor and any possibly remaining tokio threads.
633
- * run_lock = None ;
634
- Ok ( ( ) )
635
- }
636
-
637
- fn setup_runtime ( & self ) -> Result < Runtime , Error > {
638
- let tokio_runtime =
639
- Arc :: new ( tokio:: runtime:: Builder :: new_multi_thread ( ) . enable_all ( ) . build ( ) . unwrap ( ) ) ;
640
-
641
- self . wallet . set_runtime ( Arc :: clone ( & tokio_runtime) ) ;
642
-
643
- let stop_runtime = Arc :: new ( AtomicBool :: new ( false ) ) ;
610
+ let stop_running = Arc :: new ( AtomicBool :: new ( false ) ) ;
644
611
645
612
let event_handler = Arc :: new ( EventHandler :: new (
646
613
Arc :: clone ( & self . wallet ) ,
@@ -649,7 +616,7 @@ impl Node {
649
616
Arc :: clone ( & self . network_graph ) ,
650
617
Arc :: clone ( & self . keys_manager ) ,
651
618
Arc :: clone ( & self . payment_store ) ,
652
- Arc :: clone ( & tokio_runtime ) ,
619
+ Arc :: clone ( & self . runtime ) ,
653
620
Arc :: clone ( & self . logger ) ,
654
621
Arc :: clone ( & self . config ) ,
655
622
) ) ;
@@ -660,7 +627,7 @@ impl Node {
660
627
let sync_cman = Arc :: clone ( & self . channel_manager ) ;
661
628
let sync_cmon = Arc :: clone ( & self . chain_monitor ) ;
662
629
let sync_logger = Arc :: clone ( & self . logger ) ;
663
- let stop_sync = Arc :: clone ( & stop_runtime ) ;
630
+ let stop_sync = Arc :: clone ( & stop_running ) ;
664
631
665
632
std:: thread:: spawn ( move || {
666
633
tokio:: runtime:: Builder :: new_current_thread ( ) . enable_all ( ) . build ( ) . unwrap ( ) . block_on (
@@ -691,8 +658,8 @@ impl Node {
691
658
} ) ;
692
659
693
660
let sync_logger = Arc :: clone ( & self . logger ) ;
694
- let stop_sync = Arc :: clone ( & stop_runtime ) ;
695
- tokio_runtime . spawn ( async move {
661
+ let stop_sync = Arc :: clone ( & stop_running ) ;
662
+ runtime . spawn ( async move {
696
663
loop {
697
664
if stop_sync. load ( Ordering :: Acquire ) {
698
665
return ;
@@ -719,10 +686,10 @@ impl Node {
719
686
if let Some ( listening_address) = & self . config . listening_address {
720
687
// Setup networking
721
688
let peer_manager_connection_handler = Arc :: clone ( & self . peer_manager ) ;
722
- let stop_listen = Arc :: clone ( & stop_runtime ) ;
689
+ let stop_listen = Arc :: clone ( & stop_running ) ;
723
690
let listening_address = listening_address. clone ( ) ;
724
691
725
- tokio_runtime . spawn ( async move {
692
+ runtime . spawn ( async move {
726
693
let listener =
727
694
tokio:: net:: TcpListener :: bind ( listening_address) . await . expect (
728
695
"Failed to bind to listen address/port - is something else already listening on it?" ,
@@ -749,8 +716,8 @@ impl Node {
749
716
let connect_pm = Arc :: clone ( & self . peer_manager ) ;
750
717
let connect_logger = Arc :: clone ( & self . logger ) ;
751
718
let connect_peer_store = Arc :: clone ( & self . peer_store ) ;
752
- let stop_connect = Arc :: clone ( & stop_runtime ) ;
753
- tokio_runtime . spawn ( async move {
719
+ let stop_connect = Arc :: clone ( & stop_running ) ;
720
+ runtime . spawn ( async move {
754
721
let mut interval = tokio:: time:: interval ( PEER_RECONNECTION_INTERVAL ) ;
755
722
loop {
756
723
if stop_connect. load ( Ordering :: Acquire ) {
@@ -790,7 +757,7 @@ impl Node {
790
757
let background_peer_man = Arc :: clone ( & self . peer_manager ) ;
791
758
let background_logger = Arc :: clone ( & self . logger ) ;
792
759
let background_scorer = Arc :: clone ( & self . scorer ) ;
793
- let stop_background_processing = Arc :: clone ( & stop_runtime ) ;
760
+ let stop_background_processing = Arc :: clone ( & stop_running ) ;
794
761
let sleeper = move |d| {
795
762
let stop = Arc :: clone ( & stop_background_processing) ;
796
763
Box :: pin ( async move {
@@ -803,7 +770,7 @@ impl Node {
803
770
} )
804
771
} ;
805
772
806
- tokio_runtime . spawn ( async move {
773
+ runtime . spawn ( async move {
807
774
process_events_async (
808
775
background_persister,
809
776
|e| background_event_handler. handle_event ( e) ,
@@ -820,7 +787,23 @@ impl Node {
820
787
. expect ( "Failed to process events" ) ;
821
788
} ) ;
822
789
823
- Ok ( Runtime { tokio_runtime, stop_runtime } )
790
+ * runtime_lock = Some ( runtime) ;
791
+ Ok ( ( ) )
792
+ }
793
+
794
+ /// Disconnects all peers, stops all running background tasks, and shuts down [`Node`].
795
+ ///
796
+ /// After this returns most API methods will return [`Error::NotRunning`].
797
+ pub fn stop ( & self ) -> Result < ( ) , Error > {
798
+ let runtime = self . runtime . write ( ) . unwrap ( ) . take ( ) . ok_or ( Error :: NotRunning ) ?;
799
+ // Stop the runtime.
800
+ self . stop_running . store ( true , Ordering :: Release ) ;
801
+ runtime. shutdown_timeout ( Duration :: from_secs ( 10 ) ) ;
802
+
803
+ // Stop disconnect peers.
804
+ self . peer_manager . disconnect_all_peers ( ) ;
805
+
806
+ Ok ( ( ) )
824
807
}
825
808
826
809
/// Blocks until the next event is available.
@@ -870,12 +853,11 @@ impl Node {
870
853
pub fn connect_open_channel (
871
854
& self , node_pubkey_and_address : & str , channel_amount_sats : u64 , announce_channel : bool ,
872
855
) -> Result < ( ) , Error > {
873
- let runtime_lock = self . running . read ( ) . unwrap ( ) ;
874
- if runtime_lock . is_none ( ) {
856
+ let rt_lock = self . runtime . read ( ) . unwrap ( ) ;
857
+ if rt_lock . is_none ( ) {
875
858
return Err ( Error :: NotRunning ) ;
876
859
}
877
-
878
- let runtime = runtime_lock. as_ref ( ) . unwrap ( ) ;
860
+ let runtime = rt_lock. as_ref ( ) . unwrap ( ) ;
879
861
880
862
let cur_balance = self . wallet . get_balance ( ) ?;
881
863
if cur_balance. get_spendable ( ) < channel_amount_sats {
@@ -893,7 +875,7 @@ impl Node {
893
875
let con_pm = Arc :: clone ( & self . peer_manager ) ;
894
876
895
877
tokio:: task:: block_in_place ( move || {
896
- runtime. tokio_runtime . block_on ( async move {
878
+ runtime. block_on ( async move {
897
879
let res =
898
880
connect_peer_if_necessary ( con_peer_pubkey, con_peer_addr, con_pm, con_logger)
899
881
. await ;
@@ -947,10 +929,12 @@ impl Node {
947
929
///
948
930
/// Note that the wallets will be also synced regularly in the background.
949
931
pub fn sync_wallets ( & self ) -> Result < ( ) , Error > {
950
- let runtime_lock = self . running . read ( ) . unwrap ( ) ;
951
- if runtime_lock . is_none ( ) {
932
+ let rt_lock = self . runtime . read ( ) . unwrap ( ) ;
933
+ if rt_lock . is_none ( ) {
952
934
return Err ( Error :: NotRunning ) ;
953
935
}
936
+ let runtime = rt_lock. as_ref ( ) . unwrap ( ) ;
937
+
954
938
let wallet = Arc :: clone ( & self . wallet ) ;
955
939
let tx_sync = Arc :: clone ( & self . tx_sync ) ;
956
940
let sync_cman = Arc :: clone ( & self . channel_manager ) ;
@@ -961,7 +945,6 @@ impl Node {
961
945
& * sync_cmon as & ( dyn Confirm + Sync + Send ) ,
962
946
] ;
963
947
964
- let runtime = runtime_lock. as_ref ( ) . unwrap ( ) ;
965
948
tokio:: task:: block_in_place ( move || {
966
949
tokio:: runtime:: Builder :: new_current_thread ( ) . enable_all ( ) . build ( ) . unwrap ( ) . block_on (
967
950
async move {
@@ -986,7 +969,7 @@ impl Node {
986
969
987
970
let sync_logger = Arc :: clone ( & self . logger ) ;
988
971
tokio:: task:: block_in_place ( move || {
989
- runtime. tokio_runtime . block_on ( async move {
972
+ runtime. block_on ( async move {
990
973
let now = Instant :: now ( ) ;
991
974
match tx_sync. sync ( confirmables) . await {
992
975
Ok ( ( ) ) => {
@@ -1021,7 +1004,8 @@ impl Node {
1021
1004
1022
1005
/// Send a payement given an invoice.
1023
1006
pub fn send_payment ( & self , invoice : Invoice ) -> Result < PaymentHash , Error > {
1024
- if self . running . read ( ) . unwrap ( ) . is_none ( ) {
1007
+ let rt_lock = self . runtime . read ( ) . unwrap ( ) ;
1008
+ if rt_lock. is_none ( ) {
1025
1009
return Err ( Error :: NotRunning ) ;
1026
1010
}
1027
1011
@@ -1087,7 +1071,8 @@ impl Node {
1087
1071
pub fn send_payment_using_amount (
1088
1072
& self , invoice : Invoice , amount_msat : u64 ,
1089
1073
) -> Result < PaymentHash , Error > {
1090
- if self . running . read ( ) . unwrap ( ) . is_none ( ) {
1074
+ let rt_lock = self . runtime . read ( ) . unwrap ( ) ;
1075
+ if rt_lock. is_none ( ) {
1091
1076
return Err ( Error :: NotRunning ) ;
1092
1077
}
1093
1078
@@ -1175,7 +1160,8 @@ impl Node {
1175
1160
pub fn send_spontaneous_payment (
1176
1161
& self , amount_msat : u64 , node_id : & str ,
1177
1162
) -> Result < PaymentHash , Error > {
1178
- if self . running . read ( ) . unwrap ( ) . is_none ( ) {
1163
+ let rt_lock = self . runtime . read ( ) . unwrap ( ) ;
1164
+ if rt_lock. is_none ( ) {
1179
1165
return Err ( Error :: NotRunning ) ;
1180
1166
}
1181
1167
0 commit comments