plugins: lsps: move transport error to client module
What changed, and why it matters
This commit is a simple internal code cleanup in the Core Lightning LSPS plugin. It moves the definition of transport-related errors from one Rust module to another and renames one error variant from 'Other' to 'Internal'. No security vulnerability is fixed or introduced; it is purely a refactoring change.
No security action required. Treat as normal code maintenance.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch refactors the LSPS plugin’s Rust code by relocating the TransportError enum from plugins/lsps-plugin/src/proto/jsonrpc.rs to plugins/lsps-plugin/src/jsonrpc/client.rs. The variant TransportError::Other(String) is renamed to TransportError::Internal(String), and all call sites are updated accordingly. Imports are adjusted across lsps0/transport.rs, proto/jsonrpc.rs, and service.rs. The behavior of error handling remains functionally identical.
Changed components
plugins/lsps-plugin/src/jsonrpc/client.rsplugins/lsps-plugin/src/lsps0/transport.rsplugins/lsps-plugin/src/proto/jsonrpc.rsplugins/lsps-plugin/src/service.rsInspect captured patch +32 / −33
diff --git a/plugins/lsps-plugin/src/jsonrpc/client.rs b/plugins/lsps-plugin/src/jsonrpc/client.rs
index fb7f7c52..5bc27f65 100644
--- a/plugins/lsps-plugin/src/jsonrpc/client.rs
+++ b/plugins/lsps-plugin/src/jsonrpc/client.rs
@@ -1,3 +1,6 @@
+use crate::proto::jsonrpc::{
+ Error, JsonRpcRequest, JsonRpcResponse, RequestObject, ResponseObject, Result,
+};
use async_trait::async_trait;
use core::fmt::Debug;
use log::{debug, error};
@@ -6,10 +9,17 @@ use rand::TryRngCore;
use serde::{de::DeserializeOwned, Serialize};
use serde_json::Value;
use std::sync::Arc;
-
-use crate::proto::jsonrpc::{
- Error, JsonRpcRequest, JsonRpcResponse, RequestObject, ResponseObject, Result,
-};
+use thiserror::Error;
+
+/// Transport-specific errors that may occur when sending or receiving JSON-RPC
+/// messages.
+#[derive(Error, Debug)]
+pub enum TransportError {
+ #[error("Timeout")]
+ Timeout,
+ #[error("Internal error: {0}")]
+ Internal(String),
+}
/// Defines the interface for transporting JSON-RPC messages.
///
@@ -168,12 +178,11 @@ fn generate_random_id() -> String {
#[cfg(test)]
mod test_json_rpc {
+ use super::*;
+ use crate::proto::jsonrpc::RpcError;
use serde::Deserialize;
use tokio::sync::OnceCell;
- use super::*;
- use crate::proto::jsonrpc::{self, RpcError};
-
#[derive(Clone)]
struct TestTransport {
req: Arc<OnceCell<String>>,
@@ -198,7 +207,7 @@ mod test_json_rpc {
// Check for error first
if let Some(err) = &*self.err {
- return Err(Error::Transport(jsonrpc::TransportError::Other(err.into())));
+ return Err(Error::Transport(TransportError::Internal(err.into())));
}
// Then check for response
@@ -215,7 +224,7 @@ mod test_json_rpc {
// Check for error
if let Some(err) = &*self.err {
- return Err(Error::Transport(jsonrpc::TransportError::Other(err.into())));
+ return Err(Error::Transport(TransportError::Internal(err.into())));
}
Ok(())
@@ -342,7 +351,7 @@ mod test_json_rpc {
.expect_err("Expected error response");
assert!(match res {
Error::Transport(err) => {
- assert_eq!(err.to_string(), "Other error: transport error");
+ assert_eq!(err.to_string(), "Internal error: transport error");
true
}
_ => false,
diff --git a/plugins/lsps-plugin/src/lsps0/transport.rs b/plugins/lsps-plugin/src/lsps0/transport.rs
index c2b294c9..d8b2a8fb 100644
--- a/plugins/lsps-plugin/src/lsps0/transport.rs
+++ b/plugins/lsps-plugin/src/lsps0/transport.rs
@@ -1,9 +1,6 @@
use crate::{
- jsonrpc::client::Transport,
- proto::{
- jsonrpc::{Error, TransportError},
- lsps0::LSPS0_MESSAGE_TYPE,
- },
+ jsonrpc::client::{Transport, TransportError},
+ proto::{jsonrpc::Error, lsps0::LSPS0_MESSAGE_TYPE},
};
use async_trait::async_trait;
use cln_plugin::Plugin;
@@ -194,7 +191,7 @@ impl Bolt8Transport {
timeout: Option<Duration>,
) -> Result<Self, Error> {
let endpoint = cln_rpc::primitives::PublicKey::from_str(endpoint)
- .map_err(|e| TransportError::Other(e.to_string()))?;
+ .map_err(|e| TransportError::Internal(e.to_string()))?;
let timeout = timeout.unwrap_or(DEFAULT_TIMEOUT);
Ok(Self {
endpoint,
@@ -208,7 +205,7 @@ impl Bolt8Transport {
async fn connect_to_node(&self) -> Result<ClnRpc, Error> {
ClnRpc::new(&self.rpc_path)
.await
- .map_err(|e| Error::Transport(TransportError::Other(e.to_string())))
+ .map_err(|e| Error::Transport(TransportError::Internal(e.to_string())))
}
/// Sends a custom message to the destination node.
@@ -224,7 +221,7 @@ impl Bolt8Transport {
tokio::time::timeout(self.request_timeout, rx.recv())
.await
.map_err(|_| Error::Transport(TransportError::Timeout))?
- .ok_or(Error::Transport(TransportError::Other(String::from(
+ .ok_or(Error::Transport(TransportError::Internal(String::from(
"Channel unexpectedly closed",
))))
}
@@ -250,7 +247,7 @@ pub async fn send_custommsg(
.call_typed(&request)
.await
.map_err(|e| {
- Error::Transport(TransportError::Other(format!(
+ Error::Transport(TransportError::Internal(format!(
"Failed to send custom msg: {e}"
)))
})
@@ -285,7 +282,7 @@ impl Transport for Bolt8Transport {
let res = self.wait_for_response(rx).await?;
if res.message_type != LSPS0_MESSAGE_TYPE {
- return Err(Error::Transport(TransportError::Other(format!(
+ return Err(Error::Transport(TransportError::Internal(format!(
"unexpected response message type: expected {}, got {}",
LSPS0_MESSAGE_TYPE, res.message_type
))));
@@ -293,7 +290,7 @@ impl Transport for Bolt8Transport {
core::str::from_utf8(&res.payload)
.map_err(|e| {
- Error::Transport(TransportError::Other(format!(
+ Error::Transport(TransportError::Internal(format!(
"failed to decode msg payload {:?}: {}",
res.payload, e
)))
diff --git a/plugins/lsps-plugin/src/proto/jsonrpc.rs b/plugins/lsps-plugin/src/proto/jsonrpc.rs
index cc194463..5f5190df 100644
--- a/plugins/lsps-plugin/src/proto/jsonrpc.rs
+++ b/plugins/lsps-plugin/src/proto/jsonrpc.rs
@@ -3,6 +3,8 @@ use serde_json::{self, Value};
use std::fmt;
use thiserror::Error;
+use crate::jsonrpc::client::TransportError;
+
// Constants for JSON-RPC error codes.
pub const PARSE_ERROR: i64 = -32700;
pub const INVALID_REQUEST: i64 = -32600;
@@ -33,16 +35,6 @@ impl Error {
}
}
-/// Transport-specific errors that may occur when sending or receiving JSON-RPC
-/// messages.
-#[derive(Error, Debug)]
-pub enum TransportError {
- #[error("Timeout")]
- Timeout,
- #[error("Other error: {0}")]
- Other(String),
-}
-
/// Convenience type alias for Result with the JSON-RPC Error type.
pub type Result<T> = std::result::Result<T, Error>;
diff --git a/plugins/lsps-plugin/src/service.rs b/plugins/lsps-plugin/src/service.rs
index 113cb347..2500c5de 100644
--- a/plugins/lsps-plugin/src/service.rs
+++ b/plugins/lsps-plugin/src/service.rs
@@ -1,5 +1,6 @@
use anyhow::{anyhow, bail};
use async_trait::async_trait;
+use cln_lsps::jsonrpc::client::TransportError;
use cln_lsps::jsonrpc::server::JsonRpcResponseWriter;
use cln_lsps::jsonrpc::server::JsonRpcServer;
use cln_lsps::lsps0::handler::Lsps0ListProtocolsHandler;
@@ -7,7 +8,7 @@ use cln_lsps::lsps0::transport::{self, CustomMsg};
use cln_lsps::lsps2;
use cln_lsps::lsps2::cln::{HtlcAcceptedRequest, HtlcAcceptedResponse};
use cln_lsps::lsps2::handler::{ClnApiRpc, HtlcAcceptedHookHandler};
-use cln_lsps::proto::jsonrpc::{Error, JsonRpcRequest as _, Result as RpcResult, TransportError};
+use cln_lsps::proto::jsonrpc::{Error, JsonRpcRequest as _, Result as RpcResult};
use cln_lsps::proto::lsps0::{Lsps0listProtocolsRequest, LSPS0_MESSAGE_TYPE};
use cln_lsps::proto::lsps2::{Lsps2BuyRequest, Lsps2GetInfoRequest};
use cln_lsps::util::wrap_payload_with_peer_id;
@@ -187,7 +188,7 @@ impl JsonRpcResponseWriter for LspsResponseWriter {
async fn write(&mut self, payload: &[u8]) -> RpcResult<()> {
let mut client = cln_rpc::ClnRpc::new(&self.rpc_path)
.await
- .map_err(|e| Error::Transport(TransportError::Other(e.to_string())))?;
+ .map_err(|e| Error::Transport(TransportError::Internal(e.to_string())))?;
transport::send_custommsg(&mut client, payload.to_vec(), self.peer_id).await
}
}
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.