Use `PeerState::{get_order, has_active_orders}` instead of map
What changed, and why it matters
This is a small internal code cleanup in the experimental LSPS1 (liquidity service) module. It hides a private map behind two helper methods and renames some fields for clarity. The commit message explicitly says it does not fix any bug, only improves isolation. There is no direct security fix here.
No security action required. Treat as normal code-quality refactor. Monitor future LSPS1 state-persistence rework mentioned in the commit message for functional correctness.
Security signals we found
Refactoring only: visibility changes and accessor introduction
Commit message explicitly states no bug fix: 'We don't fix this here'
No change to trust boundaries, input validation, or cryptographic operations
No advisory, CVE, or security disclosure referenced
Evidence from the diff
The patch refactors PeerState in lightning-liquidity/src/lsps1/peer_state.rs to make outbound_channels_by_order_id private and exposes get_order/has_active_orders accessors. It renames OutboundLSPS1Config to ChannelOrder and OutboundCRChannel fields, and updates service.rs and manager.rs callers accordingly. The commit message notes an existing bug in update_order_state where order state is not persisted, but explicitly states it is not fixed in this commit. No memory-safety, cryptographic, or authorization issue is addressed.
Changed components
lightning-liquidity/src/lsps1/peer_state.rslightning-liquidity/src/lsps1/service.rslightning-liquidity/src/manager.rsInspect captured patch +42 / −38
diff --git a/lightning-liquidity/src/lsps1/peer_state.rs b/lightning-liquidity/src/lsps1/peer_state.rs
index 729d682..172ace6 100644
--- a/lightning-liquidity/src/lsps1/peer_state.rs
+++ b/lightning-liquidity/src/lsps1/peer_state.rs
@@ -16,7 +16,7 @@ use crate::prelude::HashMap;
#[derive(Default)]
pub(super) struct PeerState {
- pub(super) outbound_channels_by_order_id: HashMap<LSPS1OrderId, OutboundCRChannel>,
+ outbound_channels_by_order_id: HashMap<LSPS1OrderId, OutboundCRChannel>,
pub(super) pending_requests: HashMap<LSPSRequestId, LSPS1Request>,
}
@@ -26,25 +26,32 @@ impl PeerState {
created_at: LSPSDateTime, payment_details: LSPS1PaymentInfo,
) {
let channel = OutboundCRChannel::new(order_params, created_at, payment_details);
-
self.outbound_channels_by_order_id.insert(order_id, channel);
}
+
+ pub(super) fn get_order<'a>(&'a self, order_id: &LSPS1OrderId) -> Option<&'a ChannelOrder> {
+ self.outbound_channels_by_order_id.get(order_id).map(|channel| &channel.order)
+ }
+
+ pub(super) fn has_active_orders(&self) -> bool {
+ !self.outbound_channels_by_order_id.is_empty()
+ }
}
-pub(super) struct OutboundLSPS1Config {
- pub(super) order: LSPS1OrderParams,
+pub(super) struct ChannelOrder {
+ pub(super) order_params: LSPS1OrderParams,
pub(super) created_at: LSPSDateTime,
- pub(super) payment: LSPS1PaymentInfo,
+ pub(super) payment_details: LSPS1PaymentInfo,
}
-pub(super) struct OutboundCRChannel {
- pub(super) config: OutboundLSPS1Config,
+struct OutboundCRChannel {
+ order: ChannelOrder,
}
impl OutboundCRChannel {
- pub(super) fn new(
- order: LSPS1OrderParams, created_at: LSPSDateTime, payment: LSPS1PaymentInfo,
+ fn new(
+ order_params: LSPS1OrderParams, created_at: LSPSDateTime, payment_details: LSPS1PaymentInfo,
) -> Self {
- Self { config: OutboundLSPS1Config { order, created_at, payment } }
+ Self { order: ChannelOrder { order_params, created_at, payment_details } }
}
}
diff --git a/lightning-liquidity/src/lsps1/service.rs b/lightning-liquidity/src/lsps1/service.rs
index bda7d61..0e5eacc 100644
--- a/lightning-liquidity/src/lsps1/service.rs
+++ b/lightning-liquidity/src/lsps1/service.rs
@@ -92,11 +92,11 @@ where
/// `CreateOrder` request and replied with a `CreateOrder` response containing
/// an `order_id`.
/// Pending requests that are still awaiting our response are deliberately NOT counted.
- pub(crate) fn has_active_requests(&self, counterparty_node_id: &PublicKey) -> bool {
+ pub(crate) fn has_active_orders(&self, counterparty_node_id: &PublicKey) -> bool {
let outer_state_lock = self.per_peer_state.read().unwrap();
outer_state_lock.get(counterparty_node_id).map_or(false, |inner| {
let peer_state = inner.lock().unwrap();
- !peer_state.outbound_channels_by_order_id.is_empty()
+ peer_state.has_active_orders()
})
}
@@ -270,29 +270,26 @@ where
match outer_state_lock.get(&counterparty_node_id) {
Some(inner_state_lock) => {
- let mut peer_state_lock = inner_state_lock.lock().unwrap();
-
- if let Some(outbound_channel) =
- peer_state_lock.outbound_channels_by_order_id.get_mut(&order_id)
- {
- let config = &outbound_channel.config;
-
- let response = LSPS1Response::GetOrder(LSPS1CreateOrderResponse {
- order_id,
- order: config.order.clone(),
- order_state,
- created_at: config.created_at.clone(),
- payment: config.payment.clone(),
- channel,
- });
- let msg = LSPS1Message::Response(request_id, response).into();
- message_queue_notifier.enqueue(&counterparty_node_id, msg);
- Ok(())
- } else {
- Err(APIError::APIMisuseError {
+ let peer_state_lock = inner_state_lock.lock().unwrap();
+ let order =
+ peer_state_lock.get_order(&order_id).ok_or(APIError::APIMisuseError {
err: format!("Channel with order_id {} not found", order_id.0),
- })
- }
+ })?;
+
+ // FIXME: we need to actually remember the order state (and eventually persist it)
+ // here.
+
+ let response = LSPS1Response::GetOrder(LSPS1CreateOrderResponse {
+ order_id,
+ order: order.order_params.clone(),
+ order_state,
+ created_at: order.created_at.clone(),
+ payment: order.payment_details.clone(),
+ channel,
+ });
+ let msg = LSPS1Message::Response(request_id, response).into();
+ message_queue_notifier.enqueue(&counterparty_node_id, msg);
+ Ok(())
},
None => Err(APIError::APIMisuseError {
err: format!("No existing state with counterparty {}", counterparty_node_id),
diff --git a/lightning-liquidity/src/manager.rs b/lightning-liquidity/src/manager.rs
index 45a85e7..db05d71 100644
--- a/lightning-liquidity/src/manager.rs
+++ b/lightning-liquidity/src/manager.rs
@@ -716,17 +716,17 @@ where
.as_ref()
.is_some_and(|h| h.has_active_requests(sender_node_id));
#[cfg(lsps1_service)]
- let lsps1_has_active_requests = self
+ let lsps1_has_active_orders = self
.lsps1_service_handler
.as_ref()
- .is_some_and(|h| h.has_active_requests(sender_node_id));
+ .is_some_and(|h| h.has_active_orders(sender_node_id));
#[cfg(not(lsps1_service))]
- let lsps1_has_active_requests = false;
+ let lsps1_has_active_orders = false;
lsps5_service_handler.enforce_prior_activity_or_reject(
sender_node_id,
lsps2_has_active_requests,
- lsps1_has_active_requests,
+ lsps1_has_active_orders,
req_id.clone(),
)?
}
Why this scored 11/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.