@@ -189,6 +189,10 @@ pub use types::{
189189} ;
190190pub use vss_client;
191191
192+ use crate :: config:: {
193+ LIQUIDITY_DISCOVERY_RETRY_INITIAL_DELAY , LIQUIDITY_DISCOVERY_RETRY_MAX_DELAY ,
194+ LIQUIDITY_REDISCOVERY_INTERVAL ,
195+ } ;
192196use crate :: ffi:: maybe_wrap;
193197use crate :: liquidity:: Liquidity ;
194198use crate :: scoring:: setup_background_pathfinding_scores_sync;
@@ -706,33 +710,7 @@ impl Node {
706710 let logger = Arc :: clone ( & discovery_logger) ;
707711 let ls = Arc :: clone ( & liquidity_handler) ;
708712 discovery_set. spawn ( async move {
709- if let Err ( e) = cm. connect_peer_if_necessary ( node_id, address. clone ( ) ) . await {
710- log_error ! (
711- logger,
712- "Failed to connect to LSP {} for protocol discovery: {}" ,
713- node_id,
714- e
715- ) ;
716- return ;
717- }
718- match ls. discover_lsp_protocols ( & node_id) . await {
719- Ok ( protocols) => {
720- log_info ! (
721- logger,
722- "Discovered protocols for LSP {}: {:?}" ,
723- node_id,
724- protocols
725- ) ;
726- } ,
727- Err ( e) => {
728- log_error ! (
729- logger,
730- "Failed to discover protocols for LSP {}: {:?}" ,
731- node_id,
732- e
733- ) ;
734- } ,
735- }
713+ connect_and_discover_lsp ( & cm, & ls, & logger, node_id, address) . await ;
736714 } ) ;
737715 }
738716
@@ -762,6 +740,65 @@ impl Node {
762740 }
763741 } ) ;
764742
743+ // Retry protocol discovery for any LSPs that failed the startup batch, backing off
744+ // until we reach the periodic re-discovery cadence. From then on, re-discover all
745+ // configured LSPs on a fixed interval to pick up protocols they roll out later.
746+ let mut stop_rediscovery = self . stop_sender . subscribe ( ) ;
747+ let rediscovery_ls = Arc :: clone ( & self . liquidity_source ) ;
748+ let rediscovery_logger = Arc :: clone ( & self . logger ) ;
749+ let rediscovery_cm = Arc :: clone ( & self . connection_manager ) ;
750+ self . runtime . spawn_cancellable_background_task ( async move {
751+ // Fast retries for LSPs that failed the startup discovery batch, backing off
752+ // until we reach the periodic re-discovery cadence.
753+ let mut backoff = LIQUIDITY_DISCOVERY_RETRY_INITIAL_DELAY ;
754+ while backoff < LIQUIDITY_DISCOVERY_RETRY_MAX_DELAY {
755+ tokio:: select! {
756+ _ = stop_rediscovery. changed( ) => return ,
757+ _ = tokio:: time:: sleep( backoff) => { } ,
758+ }
759+
760+ let undiscovered_lsps = rediscovery_ls. get_undiscovered_lsps ( ) ;
761+ if undiscovered_lsps. is_empty ( ) {
762+ break ;
763+ }
764+
765+ let mut discovery_set = tokio:: task:: JoinSet :: new ( ) ;
766+ for ( node_id, address) in undiscovered_lsps {
767+ let cm = Arc :: clone ( & rediscovery_cm) ;
768+ let ls = Arc :: clone ( & rediscovery_ls) ;
769+ let logger = Arc :: clone ( & rediscovery_logger) ;
770+ discovery_set. spawn ( async move {
771+ connect_and_discover_lsp ( & cm, & ls, & logger, node_id, address) . await ;
772+ } ) ;
773+ }
774+ discovery_set. join_all ( ) . await ;
775+ backoff *= 2 ;
776+ }
777+
778+ // periodically re-discover all configured LSPs to pick up newly
779+ // rolled-out protocols and recover any nodes that never completed discovery.
780+ let mut interval = tokio:: time:: interval ( LIQUIDITY_REDISCOVERY_INTERVAL ) ;
781+ interval. set_missed_tick_behavior ( tokio:: time:: MissedTickBehavior :: Skip ) ;
782+ interval. tick ( ) . await ;
783+ loop {
784+ tokio:: select! {
785+ _ = stop_rediscovery. changed( ) => return ,
786+ _ = interval. tick( ) => { } ,
787+ }
788+
789+ let mut discovery_set = tokio:: task:: JoinSet :: new ( ) ;
790+ for ( node_id, address) in rediscovery_ls. get_all_lsp_details ( ) {
791+ let cm = Arc :: clone ( & rediscovery_cm) ;
792+ let ls = Arc :: clone ( & rediscovery_ls) ;
793+ let logger = Arc :: clone ( & rediscovery_logger) ;
794+ discovery_set. spawn ( async move {
795+ connect_and_discover_lsp ( & cm, & ls, & logger, node_id, address) . await ;
796+ } ) ;
797+ }
798+ discovery_set. join_all ( ) . await ;
799+ }
800+ } ) ;
801+
765802 log_info ! ( self . logger, "Startup complete." ) ;
766803 * is_running_lock = true ;
767804 Ok ( ( ) )
@@ -2435,6 +2472,23 @@ pub(crate) fn new_channel_anchor_reserve_sats(
24352472 } )
24362473}
24372474
2475+ async fn connect_and_discover_lsp (
2476+ connection_manager : & ConnectionManager < Arc < Logger > > ,
2477+ liquidity_source : & LiquiditySource < Arc < Logger > > , logger : & Logger , node_id : PublicKey ,
2478+ address : SocketAddress ,
2479+ ) {
2480+ if let Err ( e) = connection_manager. connect_peer_if_necessary ( node_id, address) . await {
2481+ log_debug ! ( logger, "Failed to connect to LSP {} for protocol discovery: {}" , node_id, e) ;
2482+ return ;
2483+ }
2484+ match liquidity_source. discover_lsp_protocols ( & node_id) . await {
2485+ Ok ( protocols) => {
2486+ log_info ! ( logger, "Discovered protocols for LSP {}: {:?}" , node_id, protocols)
2487+ } ,
2488+ Err ( e) => log_debug ! ( logger, "Protocol discovery failed for LSP {}: {:?}" , node_id, e) ,
2489+ }
2490+ }
2491+
24382492#[ cfg( test) ]
24392493mod tests {
24402494 use lightning:: util:: ser:: { Readable , Writeable } ;
0 commit comments