@@ -155,6 +155,8 @@ pub enum BuildError {
155155 InvalidAnnouncementAddresses ,
156156 /// The provided alias is invalid.
157157 InvalidNodeAlias ,
158+ /// An attempt to setup a runtime has failed.
159+ RuntimeSetupFailed ,
158160 /// We failed to read data from the [`KVStore`].
159161 ///
160162 /// [`KVStore`]: lightning::util::persist::KVStore
@@ -192,6 +194,7 @@ impl fmt::Display for BuildError {
192194 Self :: InvalidAnnouncementAddresses => {
193195 write ! ( f, "Given announcement addresses are invalid." )
194196 } ,
197+ Self :: RuntimeSetupFailed => write ! ( f, "Failed to setup a runtime." ) ,
195198 Self :: ReadFailed => write ! ( f, "Failed to read from store." ) ,
196199 Self :: WriteFailed => write ! ( f, "Failed to write to store." ) ,
197200 Self :: StoragePathAccessFailed => write ! ( f, "Failed to access the given storage path." ) ,
@@ -223,6 +226,7 @@ pub struct NodeBuilder {
223226 gossip_source_config : Option < GossipSourceConfig > ,
224227 liquidity_source_config : Option < LiquiditySourceConfig > ,
225228 log_writer_config : Option < LogWriterConfig > ,
229+ runtime_handle : Option < tokio:: runtime:: Handle > ,
226230}
227231
228232impl NodeBuilder {
@@ -239,16 +243,27 @@ impl NodeBuilder {
239243 let gossip_source_config = None ;
240244 let liquidity_source_config = None ;
241245 let log_writer_config = None ;
246+ let runtime_handle = None ;
242247 Self {
243248 config,
244249 entropy_source_config,
245250 chain_data_source_config,
246251 gossip_source_config,
247252 liquidity_source_config,
248253 log_writer_config,
254+ runtime_handle,
249255 }
250256 }
251257
258+ /// Configures the [`Node`] instance to (re-)use a specific `tokio` runtime.
259+ ///
260+ /// If not provided, the node will spawn its own runtime or reuse any outer runtime context it
261+ /// can detect.
262+ pub fn set_runtime ( & mut self , runtime_handle : tokio:: runtime:: Handle ) -> & mut Self {
263+ self . runtime_handle = Some ( runtime_handle) ;
264+ self
265+ }
266+
252267 /// Configures the [`Node`] instance to source its wallet entropy from a seed file on disk.
253268 ///
254269 /// If the given file does not exist a new random seed file will be generated and
@@ -583,6 +598,15 @@ impl NodeBuilder {
583598 ) -> Result < Node , BuildError > {
584599 let logger = setup_logger ( & self . log_writer_config , & self . config ) ?;
585600
601+ let runtime = if let Some ( handle) = self . runtime_handle . as_ref ( ) {
602+ Arc :: new ( Runtime :: with_handle ( handle. clone ( ) ) )
603+ } else {
604+ Arc :: new ( Runtime :: new ( ) . map_err ( |e| {
605+ log_error ! ( logger, "Failed to setup tokio runtime: {}" , e) ;
606+ BuildError :: RuntimeSetupFailed
607+ } ) ?)
608+ } ;
609+
586610 let seed_bytes = seed_bytes_from_config (
587611 & self . config ,
588612 self . entropy_source_config . as_ref ( ) ,
@@ -611,6 +635,7 @@ impl NodeBuilder {
611635 self . gossip_source_config . as_ref ( ) ,
612636 self . liquidity_source_config . as_ref ( ) ,
613637 seed_bytes,
638+ runtime,
614639 logger,
615640 Arc :: new ( vss_store) ,
616641 )
@@ -620,6 +645,15 @@ impl NodeBuilder {
620645 pub fn build_with_store ( & self , kv_store : Arc < DynStore > ) -> Result < Node , BuildError > {
621646 let logger = setup_logger ( & self . log_writer_config , & self . config ) ?;
622647
648+ let runtime = if let Some ( handle) = self . runtime_handle . as_ref ( ) {
649+ Arc :: new ( Runtime :: with_handle ( handle. clone ( ) ) )
650+ } else {
651+ Arc :: new ( Runtime :: new ( ) . map_err ( |e| {
652+ log_error ! ( logger, "Failed to setup tokio runtime: {}" , e) ;
653+ BuildError :: RuntimeSetupFailed
654+ } ) ?)
655+ } ;
656+
623657 let seed_bytes = seed_bytes_from_config (
624658 & self . config ,
625659 self . entropy_source_config . as_ref ( ) ,
@@ -633,6 +667,7 @@ impl NodeBuilder {
633667 self . gossip_source_config . as_ref ( ) ,
634668 self . liquidity_source_config . as_ref ( ) ,
635669 seed_bytes,
670+ runtime,
636671 logger,
637672 kv_store,
638673 )
@@ -935,7 +970,7 @@ fn build_with_store_internal(
935970 config : Arc < Config > , chain_data_source_config : Option < & ChainDataSourceConfig > ,
936971 gossip_source_config : Option < & GossipSourceConfig > ,
937972 liquidity_source_config : Option < & LiquiditySourceConfig > , seed_bytes : [ u8 ; 64 ] ,
938- logger : Arc < Logger > , kv_store : Arc < DynStore > ,
973+ runtime : Arc < Runtime > , logger : Arc < Logger > , kv_store : Arc < DynStore > ,
939974) -> Result < Node , BuildError > {
940975 if let Err ( err) = may_announce_channel ( & config) {
941976 if config. announcement_addresses . is_some ( ) {
@@ -1102,8 +1137,6 @@ fn build_with_store_internal(
11021137 } ,
11031138 } ;
11041139
1105- let runtime = Arc :: new ( Runtime :: new ( Arc :: clone ( & logger) ) ) ;
1106-
11071140 // Initialize the ChainMonitor
11081141 let chain_monitor: Arc < ChainMonitor > = Arc :: new ( chainmonitor:: ChainMonitor :: new (
11091142 Some ( Arc :: clone ( & chain_source) ) ,
@@ -1496,6 +1529,8 @@ fn build_with_store_internal(
14961529 let ( stop_sender, _) = tokio:: sync:: watch:: channel ( ( ) ) ;
14971530 let ( event_handling_stopped_sender, _) = tokio:: sync:: watch:: channel ( ( ) ) ;
14981531
1532+ let is_running = Arc :: new ( RwLock :: new ( false ) ) ;
1533+
14991534 Ok ( Node {
15001535 runtime,
15011536 stop_sender,
@@ -1521,6 +1556,7 @@ fn build_with_store_internal(
15211556 scorer,
15221557 peer_store,
15231558 payment_store,
1559+ is_running,
15241560 is_listening,
15251561 node_metrics,
15261562 } )
0 commit comments