Skip to content

Commit 52db3a9

Browse files
committed
lsp_plugin: relax LSP feateture bit handling
Replace ensure_lsp_connected() by check_peer_lsp_status() which only returns the status of the peer (connected, has_lsp_feature). This allows us to be more tolearant about the LSP feature bit since it is only optional according to the spec. We still check for the feature but only return a warning in the logs. Signed-off-by: Peter Neuroth <[email protected]>
1 parent bd31971 commit 52db3a9

File tree

1 file changed

+46
-32
lines changed

1 file changed

+46
-32
lines changed

plugins/lsps-plugin/src/client.rs

Lines changed: 46 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)