1- use anyhow:: { anyhow, Context } ;
1+ use anyhow:: { anyhow, bail , Context } ;
22use chrono:: { Duration , Utc } ;
33use cln_lsps:: jsonrpc:: client:: JsonRpcClient ;
44use cln_lsps:: lsps0:: primitives:: Msat ;
@@ -112,9 +112,19 @@ async fn on_lsps_lsps2_getinfo(
112112 let rpc_path = Path :: new ( & dir) . join ( & p. configuration ( ) . rpc_file ) ;
113113 let mut cln_client = cln_rpc:: ClnRpc :: new ( rpc_path. clone ( ) ) . await ?;
114114
115- // Fail early: Check that we are connected to the peer and that it has the
116- // LSP feature bit set.
117- ensure_lsp_connected ( & mut cln_client, & req. lsp_id ) . await ?;
115+ let lsp_status = check_peer_lsp_status ( & mut cln_client, & req. lsp_id ) . await ?;
116+
117+ // Fail early: Check that we are connected to the peer.
118+ if !lsp_status. connected {
119+ bail ! ( "Not connected to peer {}" , & req. lsp_id) ;
120+ } ;
121+
122+ // From Blip52: LSPs MAY set the features bit numbered 729
123+ // (option_supports_lsps)...
124+ // We only log that it is not set but don't fail.
125+ if !lsp_status. has_lsp_feature {
126+ debug ! ( "Peer {} doesn't have the LSP feature bit set." , & req. lsp_id) ;
127+ }
118128
119129 // Create Transport and Client
120130 let transport = Bolt8Transport :: new (
@@ -153,9 +163,19 @@ async fn on_lsps_lsps2_buy(
153163 let rpc_path = Path :: new ( & dir) . join ( & p. configuration ( ) . rpc_file ) ;
154164 let mut cln_client = cln_rpc:: ClnRpc :: new ( rpc_path. clone ( ) ) . await ?;
155165
156- // Fail early: Check that we are connected to the peer and that it has the
157- // LSP feature bit set.
158- ensure_lsp_connected ( & mut cln_client, & req. lsp_id ) . await ?;
166+ let lsp_status = check_peer_lsp_status ( & mut cln_client, & req. lsp_id ) . await ?;
167+
168+ // Fail early: Check that we are connected to the peer.
169+ if !lsp_status. connected {
170+ bail ! ( "Not connected to peer {}" , & req. lsp_id) ;
171+ } ;
172+
173+ // From Blip52: LSPs MAY set the features bit numbered 729
174+ // (option_supports_lsps)...
175+ // We only log that it is not set but don't fail.
176+ if !lsp_status. has_lsp_feature {
177+ debug ! ( "Peer {} doesn't have the LSP feature bit set." , & req. lsp_id) ;
178+ }
159179
160180 // Create Transport and Client
161181 let transport = Bolt8Transport :: new (
@@ -542,10 +562,19 @@ async fn on_lsps_listprotocols(
542562 let mut cln_client = cln_rpc:: ClnRpc :: new ( rpc_path. clone ( ) ) . await ?;
543563
544564 let req: Request = serde_json:: from_value ( v) . context ( "Failed to parse request JSON" ) ?;
565+ let lsp_status = check_peer_lsp_status ( & mut cln_client, & req. lsp_id ) . await ?;
566+
567+ // Fail early: Check that we are connected to the peer.
568+ if !lsp_status. connected {
569+ bail ! ( "Not connected to peer {}" , & req. lsp_id) ;
570+ } ;
545571
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 ?;
572+ // From Blip52: LSPs MAY set the features bit numbered 729
573+ // (option_supports_lsps)...
574+ // We only log that it is not set but don't fail.
575+ if !lsp_status. has_lsp_feature {
576+ debug ! ( "Peer {} doesn't have the LSP feature bit set." , & req. lsp_id) ;
577+ }
549578
550579 // Create the transport first and handle potential errors
551580 let transport = Bolt8Transport :: new (
@@ -563,48 +592,53 @@ async fn on_lsps_listprotocols(
563592 let res: lsps0:: model:: Lsps0listProtocolsResponse = client
564593 . call_typed ( request)
565594 . await
566- . context ( "lsps0.list_protocols call failed" ) ?;
595+ . map_err ( |e| anyhow ! ( "lsps0.list_protocols call failed: {}" , e ) ) ?;
567596
568597 debug ! ( "Received lsps0.list_protocols response: {:?}" , res) ;
569598 Ok ( serde_json:: to_value ( res) ?)
570599}
571600
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 > {
601+ struct PeerLspStatus {
602+ connected : bool ,
603+ has_lsp_feature : bool ,
604+ }
605+
606+ /// Returns the `PeerLspStatus`, containing information about the connectivity
607+ /// and the LSP feature bit.
608+ async fn check_peer_lsp_status (
609+ cln_client : & mut ClnRpc ,
610+ peer_id : & str ,
611+ ) -> Result < PeerLspStatus , anyhow:: Error > {
575612 let res = cln_client
576613 . call_typed ( & ListpeersRequest {
577- id : Some ( PublicKey :: from_str ( lsp_id ) ?) ,
614+ id : Some ( PublicKey :: from_str ( peer_id ) ?) ,
578615 level : None ,
579616 } )
580617 . await ?;
581618
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- }
619+ let peer = match res. peers . first ( ) {
620+ None => {
621+ return Ok ( PeerLspStatus {
622+ connected : false ,
623+ has_lsp_feature : false ,
598624 } )
599- } )
600- . ok_or_else ( || {
601- anyhow ! (
602- "peer is not an lsp, feature bit {} is missing" ,
603- LSP_FEATURE_BIT ,
604- )
605- } ) ?;
625+ }
626+ Some ( p) => p,
627+ } ;
628+
629+ let connected = peer. connected ;
630+ let has_lsp_feature = if let Some ( f_str) = & peer. features {
631+ let feature_bits = hex:: decode ( f_str)
632+ . map_err ( |e| anyhow ! ( "Invalid feature bits hex for peer {peer_id}, {f_str}: {e}" ) ) ?;
633+ util:: is_feature_bit_set_reversed ( & feature_bits, LSP_FEATURE_BIT )
634+ } else {
635+ false
636+ } ;
606637
607- Ok ( ( ) )
638+ Ok ( PeerLspStatus {
639+ connected,
640+ has_lsp_feature,
641+ } )
608642}
609643
610644#[ derive( Debug , Clone , PartialEq , Serialize , Deserialize ) ]
0 commit comments