Skip to content

Commit 052303a

Browse files
committed
f: Bind listeners before spawning startup tasks
Resolve and bind configured listening addresses before starting wallet sync, gossip sync, pathfinding score sync, and the remaining background loops. If listener setup now fails, startup returns while only the chain source needs cleanup, so a retry cannot leave duplicate loops behind. AI-assisted-by: OpenAI Codex
1 parent 670d952 commit 052303a

1 file changed

Lines changed: 87 additions & 84 deletions

File tree

src/lib.rs

Lines changed: 87 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,55 @@ impl Node {
355355
)
356356
})?;
357357

358+
// Bind listeners before spawning background tasks so startup errors cannot leave loops
359+
// running while the node is still marked stopped.
360+
let listeners = if let Some(listening_addresses) = &self.config.listening_addresses {
361+
let logger = Arc::clone(&self.logger);
362+
let listening_addrs = listening_addresses.clone();
363+
self.runtime.block_on(async move {
364+
let mut bind_addrs = Vec::with_capacity(listening_addrs.len());
365+
366+
for listening_addr in &listening_addrs {
367+
let resolved =
368+
tokio::net::lookup_host(listening_addr.to_string()).await.map_err(|e| {
369+
log_error!(
370+
logger,
371+
"Unable to resolve listening address: {:?}. Error details: {}",
372+
listening_addr,
373+
e,
374+
);
375+
Error::InvalidSocketAddress
376+
})?;
377+
bind_addrs.extend(resolved);
378+
}
379+
380+
let mut listeners = Vec::new();
381+
382+
// Try to bind to all addresses
383+
for addr in &bind_addrs {
384+
match tokio::net::TcpListener::bind(addr).await {
385+
Ok(listener) => {
386+
log_trace!(logger, "Listener bound to {}", addr);
387+
listeners.push(listener);
388+
},
389+
Err(e) => {
390+
log_error!(
391+
logger,
392+
"Failed to bind to {}: {} - is something else already listening?",
393+
addr,
394+
e
395+
);
396+
return Err(Error::InvalidSocketAddress);
397+
},
398+
}
399+
}
400+
401+
Ok(listeners)
402+
})?
403+
} else {
404+
Vec::new()
405+
};
406+
358407
// Spawn background task continuously syncing onchain, lightning, and fee rate cache.
359408
let stop_sync_receiver = self.stop_sender.subscribe();
360409
let chain_source = Arc::clone(&self.chain_source);
@@ -425,98 +474,52 @@ impl Node {
425474
);
426475
}
427476

428-
if let Some(listening_addresses) = &self.config.listening_addresses {
429-
// Setup networking
430-
let peer_manager_connection_handler = Arc::clone(&self.peer_manager);
431-
let listening_logger = Arc::clone(&self.logger);
432-
477+
// Setup networking
478+
let peer_manager_connection_handler = Arc::clone(&self.peer_manager);
479+
let listening_logger = Arc::clone(&self.logger);
480+
for listener in listeners {
433481
let logger = Arc::clone(&listening_logger);
434-
let listening_addrs = listening_addresses.clone();
435-
let listeners = self.runtime.block_on(async move {
436-
let mut bind_addrs = Vec::with_capacity(listening_addrs.len());
437-
438-
for listening_addr in &listening_addrs {
439-
let resolved =
440-
tokio::net::lookup_host(listening_addr.to_string()).await.map_err(|e| {
441-
log_error!(
442-
logger,
443-
"Unable to resolve listening address: {:?}. Error details: {}",
444-
listening_addr,
445-
e,
446-
);
447-
Error::InvalidSocketAddress
448-
})?;
449-
bind_addrs.extend(resolved);
450-
}
451-
452-
let mut listeners = Vec::new();
453-
454-
// Try to bind to all addresses
455-
for addr in &bind_addrs {
456-
match tokio::net::TcpListener::bind(addr).await {
457-
Ok(listener) => {
458-
log_trace!(logger, "Listener bound to {}", addr);
459-
listeners.push(listener);
460-
},
461-
Err(e) => {
462-
log_error!(
482+
let peer_mgr = Arc::clone(&peer_manager_connection_handler);
483+
let mut stop_listen = self.stop_sender.subscribe();
484+
let runtime = Arc::clone(&self.runtime);
485+
self.runtime.spawn_cancellable_background_task(async move {
486+
loop {
487+
tokio::select! {
488+
_ = stop_listen.changed() => {
489+
log_debug!(
463490
logger,
464-
"Failed to bind to {}: {} - is something else already listening?",
465-
addr,
466-
e
491+
"Stopping listening to inbound connections."
467492
);
468-
return Err(Error::InvalidSocketAddress);
469-
},
470-
}
471-
}
472-
473-
Ok(listeners)
474-
})?;
475-
476-
for listener in listeners {
477-
let logger = Arc::clone(&listening_logger);
478-
let peer_mgr = Arc::clone(&peer_manager_connection_handler);
479-
let mut stop_listen = self.stop_sender.subscribe();
480-
let runtime = Arc::clone(&self.runtime);
481-
self.runtime.spawn_cancellable_background_task(async move {
482-
loop {
483-
tokio::select! {
484-
_ = stop_listen.changed() => {
485-
log_debug!(
486-
logger,
487-
"Stopping listening to inbound connections."
488-
);
489-
break;
490-
}
491-
res = listener.accept() => {
492-
let tcp_stream = match res {
493-
Ok((tcp_stream, _)) => tcp_stream,
493+
break;
494+
}
495+
res = listener.accept() => {
496+
let tcp_stream = match res {
497+
Ok((tcp_stream, _)) => tcp_stream,
498+
Err(e) => {
499+
log_error!(logger, "Failed to accept inbound connection: {}", e);
500+
continue;
501+
},
502+
};
503+
let peer_mgr = Arc::clone(&peer_mgr);
504+
let logger = Arc::clone(&logger);
505+
runtime.spawn_cancellable_background_task(async move {
506+
let tcp_stream = match tcp_stream.into_std() {
507+
Ok(tcp_stream) => tcp_stream,
494508
Err(e) => {
495-
log_error!(logger, "Failed to accept inbound connection: {}", e);
496-
continue;
509+
log_error!(logger, "Failed to convert inbound connection: {}", e);
510+
return;
497511
},
498512
};
499-
let peer_mgr = Arc::clone(&peer_mgr);
500-
let logger = Arc::clone(&logger);
501-
runtime.spawn_cancellable_background_task(async move {
502-
let tcp_stream = match tcp_stream.into_std() {
503-
Ok(tcp_stream) => tcp_stream,
504-
Err(e) => {
505-
log_error!(logger, "Failed to convert inbound connection: {}", e);
506-
return;
507-
},
508-
};
509-
lightning_net_tokio::setup_inbound(
510-
Arc::clone(&peer_mgr),
511-
tcp_stream,
512-
)
513-
.await;
514-
});
515-
}
513+
lightning_net_tokio::setup_inbound(
514+
Arc::clone(&peer_mgr),
515+
tcp_stream,
516+
)
517+
.await;
518+
});
516519
}
517520
}
518-
});
519-
}
521+
}
522+
});
520523
}
521524

522525
// Regularly reconnect to persisted peers.

0 commit comments

Comments
 (0)