@@ -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 if let Err ( err) = may_announce_channel ( & config) {
10551092 if config. announcement_addresses . is_some ( ) {
@@ -1239,8 +1276,6 @@ fn build_with_store_internal(
12391276 } ,
12401277 } ;
12411278
1242- let runtime = Arc :: new ( RwLock :: new ( None ) ) ;
1243-
12441279 // Initialize the ChainMonitor
12451280 let chain_monitor: Arc < ChainMonitor > = Arc :: new ( chainmonitor:: ChainMonitor :: new (
12461281 Some ( Arc :: clone ( & chain_source) ) ,
@@ -1633,6 +1668,8 @@ fn build_with_store_internal(
16331668 let ( stop_sender, _) = tokio:: sync:: watch:: channel ( ( ) ) ;
16341669 let background_processor_task = Mutex :: new ( None ) ;
16351670
1671+ let is_running = Arc :: new ( RwLock :: new ( false ) ) ;
1672+
16361673 Ok ( Node {
16371674 runtime,
16381675 stop_sender,
@@ -1658,6 +1695,7 @@ fn build_with_store_internal(
16581695 scorer,
16591696 peer_store,
16601697 payment_store,
1698+ is_running,
16611699 is_listening,
16621700 node_metrics,
16631701 } )
0 commit comments