@@ -542,10 +542,19 @@ async fn on_lsps_listprotocols(
542542    let  mut  cln_client = cln_rpc:: ClnRpc :: new ( rpc_path. clone ( ) ) . await ?; 
543543
544544    let  req:  Request  = serde_json:: from_value ( v) . context ( "Failed to parse request JSON" ) ?; 
545+     let  lsp_status = check_peer_lsp_status ( & mut  cln_client,  & req. lsp_id ) . await ?; 
545546
546-     // Fail early: Check that we are connected to the peer and that it has the 
547-     // LSP feature bit set. 
548-     ensure_lsp_connected ( & mut  cln_client,  & req. lsp_id ) . await ?; 
547+     // Fail early: Check that we are connected to the peer. 
548+     if  !lsp_status. connected  { 
549+         bail ! ( "Not connected to peer {}" ,  & req. lsp_id) ; 
550+     } ; 
551+ 
552+     // From Blip52: LSPs MAY set the features bit numbered 729 
553+     // (option_supports_lsps)... 
554+     // We only log that it is not set but don't fail. 
555+     if  !lsp_status. has_lsp_feature  { 
556+         debug ! ( "Peer {} doesn't have the LSP feature bit set." ,  & req. lsp_id) ; 
557+     } 
549558
550559    // Create the transport first and handle potential errors 
551560    let  transport = Bolt8Transport :: new ( 
@@ -563,48 +572,53 @@ async fn on_lsps_listprotocols(
563572    let  res:  lsps0:: model:: Lsps0listProtocolsResponse  = client
564573        . call_typed ( request) 
565574        . await 
566-         . context ( "lsps0.list_protocols call failed"  ) ?; 
575+         . map_err ( |e|  anyhow ! ( "lsps0.list_protocols call failed: {}"  ,  e ) ) ?; 
567576
568577    debug ! ( "Received lsps0.list_protocols response: {:?}" ,  res) ; 
569578    Ok ( serde_json:: to_value ( res) ?) 
570579} 
571580
572- /// Checks that the node is connected to the peer and that it has the LSP 
573- /// feature bit set. 
574- async  fn  ensure_lsp_connected ( cln_client :  & mut  ClnRpc ,  lsp_id :  & str )  -> Result < ( ) ,  anyhow:: Error >  { 
581+ struct  PeerLspStatus  { 
582+     connected :  bool , 
583+     has_lsp_feature :  bool , 
584+ } 
585+ 
586+ /// Returns the `PeerLspStatus`, containing information about the connectivity 
587+ /// and the LSP feature bit. 
588+ async  fn  check_peer_lsp_status ( 
589+     cln_client :  & mut  ClnRpc , 
590+     peer_id :  & str , 
591+ )  -> Result < PeerLspStatus ,  anyhow:: Error >  { 
575592    let  res = cln_client
576593        . call_typed ( & ListpeersRequest  { 
577-             id :  Some ( PublicKey :: from_str ( lsp_id ) ?) , 
594+             id :  Some ( PublicKey :: from_str ( peer_id ) ?) , 
578595            level :  None , 
579596        } ) 
580597        . await ?; 
581598
582-     // unwrap in next line is safe as we checked that an item exists before. 
583-     if  res. peers . is_empty ( )  || !res. peers . first ( ) . unwrap ( ) . connected  { 
584-         debug ! ( "Node isn't connected to lsp {lsp_id}" ) ; 
585-         return  Err ( anyhow ! ( "not connected to lsp" ) ) ; 
586-     } 
587- 
588-     res. peers 
589-         . first ( ) 
590-         . filter ( |peer| { 
591-             // Check that feature bit is set 
592-             peer. features . as_deref ( ) . map_or ( false ,  |f_str| { 
593-                 if  let  Some ( feature_bits)  = hex:: decode ( f_str) . ok ( )  { 
594-                     util:: is_feature_bit_set_reversed ( & feature_bits,  LSP_FEATURE_BIT ) 
595-                 }  else  { 
596-                     false 
597-                 } 
599+     let  peer = match  res. peers . first ( )  { 
600+         None  => { 
601+             return  Ok ( PeerLspStatus  { 
602+                 connected :  false , 
603+                 has_lsp_feature :  false , 
598604            } ) 
599-         } ) 
600-         . ok_or_else ( || { 
601-             anyhow ! ( 
602-                 "peer is not an lsp, feature bit {} is missing" , 
603-                 LSP_FEATURE_BIT , 
604-             ) 
605-         } ) ?; 
605+         } 
606+         Some ( p)  => p, 
607+     } ; 
608+ 
609+     let  connected = peer. connected ; 
610+     let  has_lsp_feature = if  let  Some ( f_str)  = & peer. features  { 
611+         let  feature_bits = hex:: decode ( f_str) 
612+             . map_err ( |e| anyhow ! ( "Invalid feature bits hex for peer {peer_id}, {f_str}: {e}" ) ) ?; 
613+         util:: is_feature_bit_set_reversed ( & feature_bits,  LSP_FEATURE_BIT ) 
614+     }  else  { 
615+         false 
616+     } ; 
606617
607-     Ok ( ( ) ) 
618+     Ok ( PeerLspStatus  { 
619+         connected, 
620+         has_lsp_feature, 
621+     } ) 
608622} 
609623
610624#[ derive( Debug ,  Clone ,  PartialEq ,  Serialize ,  Deserialize ) ]  
0 commit comments