@@ -28,6 +28,7 @@ use crate::liquidity::{
2828use crate :: logger:: { log_error, log_info, LdkLogger , LogLevel , LogWriter , Logger } ;
2929use crate :: message_handler:: NodeCustomMessageHandler ;
3030use crate :: peer_store:: PeerStore ;
31+ use crate :: runtime:: Runtime ;
3132use crate :: tx_broadcaster:: TransactionBroadcaster ;
3233use crate :: types:: {
3334 ChainMonitor , ChannelManager , DynStore , GossipSync , Graph , KeysManager , MessageRouter ,
@@ -168,6 +169,8 @@ pub enum BuildError {
168169 InvalidAnnouncementAddresses ,
169170 /// The provided alias is invalid.
170171 InvalidNodeAlias ,
172+ /// An attempt to setup a runtime has failed.
173+ RuntimeSetupFailed ,
171174 /// We failed to read data from the [`KVStore`].
172175 ///
173176 /// [`KVStore`]: lightning::util::persist::KVStore
@@ -205,6 +208,7 @@ impl fmt::Display for BuildError {
205208 Self :: InvalidAnnouncementAddresses => {
206209 write ! ( f, "Given announcement addresses are invalid." )
207210 } ,
211+ Self :: RuntimeSetupFailed => write ! ( f, "Failed to setup a runtime." ) ,
208212 Self :: ReadFailed => write ! ( f, "Failed to read from store." ) ,
209213 Self :: WriteFailed => write ! ( f, "Failed to write to store." ) ,
210214 Self :: StoragePathAccessFailed => write ! ( f, "Failed to access the given storage path." ) ,
@@ -236,6 +240,7 @@ pub struct NodeBuilder {
236240 gossip_source_config : Option < GossipSourceConfig > ,
237241 liquidity_source_config : Option < LiquiditySourceConfig > ,
238242 log_writer_config : Option < LogWriterConfig > ,
243+ runtime_handle : Option < tokio:: runtime:: Handle > ,
239244}
240245
241246impl NodeBuilder {
@@ -252,16 +257,28 @@ impl NodeBuilder {
252257 let gossip_source_config = None ;
253258 let liquidity_source_config = None ;
254259 let log_writer_config = None ;
260+ let runtime_handle = None ;
255261 Self {
256262 config,
257263 entropy_source_config,
258264 chain_data_source_config,
259265 gossip_source_config,
260266 liquidity_source_config,
261267 log_writer_config,
268+ runtime_handle,
262269 }
263270 }
264271
272+ /// Configures the [`Node`] instance to (re-)use a specific `tokio` runtime.
273+ ///
274+ /// If not provided, the node will spawn its own runtime or reuse any outer runtime context it
275+ /// can detect.
276+ #[ cfg_attr( feature = "uniffi" , allow( dead_code) ) ]
277+ pub fn set_runtime ( & mut self , runtime_handle : tokio:: runtime:: Handle ) -> & mut Self {
278+ self . runtime_handle = Some ( runtime_handle) ;
279+ self
280+ }
281+
265282 /// Configures the [`Node`] instance to source its wallet entropy from a seed file on disk.
266283 ///
267284 /// If the given file does not exist a new random seed file will be generated and
@@ -650,6 +667,15 @@ impl NodeBuilder {
650667 ) -> Result < Node , BuildError > {
651668 let logger = setup_logger ( & self . log_writer_config , & self . config ) ?;
652669
670+ let runtime = if let Some ( handle) = self . runtime_handle . as_ref ( ) {
671+ Arc :: new ( Runtime :: with_handle ( handle. clone ( ) ) )
672+ } else {
673+ Arc :: new ( Runtime :: new ( ) . map_err ( |e| {
674+ log_error ! ( logger, "Failed to setup tokio runtime: {}" , e) ;
675+ BuildError :: RuntimeSetupFailed
676+ } ) ?)
677+ } ;
678+
653679 let seed_bytes = seed_bytes_from_config (
654680 & self . config ,
655681 self . entropy_source_config . as_ref ( ) ,
@@ -678,6 +704,7 @@ impl NodeBuilder {
678704 self . gossip_source_config . as_ref ( ) ,
679705 self . liquidity_source_config . as_ref ( ) ,
680706 seed_bytes,
707+ runtime,
681708 logger,
682709 Arc :: new ( vss_store) ,
683710 )
@@ -687,6 +714,15 @@ impl NodeBuilder {
687714 pub fn build_with_store ( & self , kv_store : Arc < DynStore > ) -> Result < Node , BuildError > {
688715 let logger = setup_logger ( & self . log_writer_config , & self . config ) ?;
689716
717+ let runtime = if let Some ( handle) = self . runtime_handle . as_ref ( ) {
718+ Arc :: new ( Runtime :: with_handle ( handle. clone ( ) ) )
719+ } else {
720+ Arc :: new ( Runtime :: new ( ) . map_err ( |e| {
721+ log_error ! ( logger, "Failed to setup tokio runtime: {}" , e) ;
722+ BuildError :: RuntimeSetupFailed
723+ } ) ?)
724+ } ;
725+
690726 let seed_bytes = seed_bytes_from_config (
691727 & self . config ,
692728 self . entropy_source_config . as_ref ( ) ,
@@ -700,6 +736,7 @@ impl NodeBuilder {
700736 self . gossip_source_config . as_ref ( ) ,
701737 self . liquidity_source_config . as_ref ( ) ,
702738 seed_bytes,
739+ runtime,
703740 logger,
704741 kv_store,
705742 )
@@ -1049,7 +1086,7 @@ fn build_with_store_internal(
10491086 config : Arc < Config > , chain_data_source_config : Option < & ChainDataSourceConfig > ,
10501087 gossip_source_config : Option < & GossipSourceConfig > ,
10511088 liquidity_source_config : Option < & LiquiditySourceConfig > , seed_bytes : [ u8 ; 64 ] ,
1052- logger : Arc < Logger > , kv_store : Arc < DynStore > ,
1089+ runtime : Arc < Runtime > , logger : Arc < Logger > , kv_store : Arc < DynStore > ,
10531090) -> Result < Node , BuildError > {
10541091 optionally_install_rustls_cryptoprovider ( ) ;
10551092
@@ -1241,8 +1278,6 @@ fn build_with_store_internal(
12411278 } ,
12421279 } ;
12431280
1244- let runtime = Arc :: new ( RwLock :: new ( None ) ) ;
1245-
12461281 // Initialize the ChainMonitor
12471282 let chain_monitor: Arc < ChainMonitor > = Arc :: new ( chainmonitor:: ChainMonitor :: new (
12481283 Some ( Arc :: clone ( & chain_source) ) ,
@@ -1637,6 +1672,8 @@ fn build_with_store_internal(
16371672 let background_tasks = Mutex :: new ( None ) ;
16381673 let cancellable_background_tasks = Mutex :: new ( None ) ;
16391674
1675+ let is_running = Arc :: new ( RwLock :: new ( false ) ) ;
1676+
16401677 Ok ( Node {
16411678 runtime,
16421679 stop_sender,
@@ -1664,6 +1701,7 @@ fn build_with_store_internal(
16641701 scorer,
16651702 peer_store,
16661703 payment_store,
1704+ is_running,
16671705 is_listening,
16681706 node_metrics,
16691707 } )
0 commit comments