Skip to content

Commit c6caad8

Browse files
authored
Merge pull request #3804 from martinsaposnic/issue3459
LSPS2: Add error handling events for failed client requests
2 parents 26b1934 + cea624e commit c6caad8

File tree

4 files changed

+401
-94
lines changed

4 files changed

+401
-94
lines changed

lightning-liquidity/src/lsps2/client.rs

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,9 @@ where
150150
/// but MPP can no longer be used to pay it.
151151
///
152152
/// The client agrees to paying an opening fee equal to
153-
/// `max(min_fee_msat, proportional*(payment_size_msat/1_000_000))`.
153+
/// `max(min_fee_msat, proportional * (payment_size_msat / 1_000_000))`.
154+
///
155+
/// Returns the used [`LSPSRequestId`] that was used for the buy request.
154156
///
155157
/// [`OpeningParametersReady`]: crate::lsps2::event::LSPS2ClientEvent::OpeningParametersReady
156158
/// [`InvoiceParametersReady`]: crate::lsps2::event::LSPS2ClientEvent::InvoiceParametersReady
@@ -230,8 +232,9 @@ where
230232

231233
fn handle_get_info_error(
232234
&self, request_id: LSPSRequestId, counterparty_node_id: &PublicKey,
233-
_error: LSPSResponseError,
235+
error: LSPSResponseError,
234236
) -> Result<(), LightningError> {
237+
let event_queue_notifier = self.pending_events.notifier();
235238
let outer_state_lock = self.per_peer_state.read().unwrap();
236239
match outer_state_lock.get(counterparty_node_id) {
237240
Some(inner_state_lock) => {
@@ -247,7 +250,21 @@ where
247250
});
248251
}
249252

250-
Ok(())
253+
let lightning_error = LightningError {
254+
err: format!(
255+
"Received get_info error response for request {:?}: {:?}",
256+
request_id, error
257+
),
258+
action: ErrorAction::IgnoreAndLog(Level::Error),
259+
};
260+
261+
event_queue_notifier.enqueue(LSPS2ClientEvent::GetInfoFailed {
262+
request_id,
263+
counterparty_node_id: *counterparty_node_id,
264+
error,
265+
});
266+
267+
Err(lightning_error)
251268
},
252269
None => {
253270
return Err(LightningError { err: format!("Received error response for a get_info request from an unknown counterparty ({:?})",counterparty_node_id), action: ErrorAction::IgnoreAndLog(Level::Info)});
@@ -308,8 +325,9 @@ where
308325

309326
fn handle_buy_error(
310327
&self, request_id: LSPSRequestId, counterparty_node_id: &PublicKey,
311-
_error: LSPSResponseError,
328+
error: LSPSResponseError,
312329
) -> Result<(), LightningError> {
330+
let event_queue_notifier = self.pending_events.notifier();
313331
let outer_state_lock = self.per_peer_state.read().unwrap();
314332
match outer_state_lock.get(counterparty_node_id) {
315333
Some(inner_state_lock) => {
@@ -320,7 +338,21 @@ where
320338
action: ErrorAction::IgnoreAndLog(Level::Info),
321339
})?;
322340

323-
Ok(())
341+
let lightning_error = LightningError {
342+
err: format!(
343+
"Received buy error response for request {:?}: {:?}",
344+
request_id, error
345+
),
346+
action: ErrorAction::IgnoreAndLog(Level::Error),
347+
};
348+
349+
event_queue_notifier.enqueue(LSPS2ClientEvent::BuyRequestFailed {
350+
request_id,
351+
counterparty_node_id: *counterparty_node_id,
352+
error,
353+
});
354+
355+
Err(lightning_error)
324356
},
325357
None => {
326358
return Err(LightningError { err: format!("Received error response for a buy request from an unknown counterparty ({:?})", counterparty_node_id), action: ErrorAction::IgnoreAndLog(Level::Info)});

lightning-liquidity/src/lsps2/event.rs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//! Contains bLIP-52 / LSPS2 event types
1111
1212
use super::msgs::LSPS2OpeningFeeParams;
13-
use crate::lsps0::ser::LSPSRequestId;
13+
use crate::lsps0::ser::{LSPSRequestId, LSPSResponseError};
1414
use alloc::string::String;
1515
use alloc::vec::Vec;
1616

@@ -61,6 +61,40 @@ pub enum LSPS2ClientEvent {
6161
/// The initial payment size you specified.
6262
payment_size_msat: Option<u64>,
6363
},
64+
/// A request previously issued via [`LSPS2ClientHandler::request_opening_params`]
65+
/// failed as the LSP returned an error response.
66+
///
67+
/// [`LSPS2ClientHandler::request_opening_params`]: crate::lsps2::client::LSPS2ClientHandler::request_opening_params
68+
GetInfoFailed {
69+
/// The identifier of the issued LSPS2 `get_info` request, as returned by
70+
/// [`LSPS2ClientHandler::request_opening_params`].
71+
///
72+
/// This can be used to track which request this event corresponds to.
73+
///
74+
/// [`LSPS2ClientHandler::request_opening_params`]: crate::lsps2::client::LSPS2ClientHandler::request_opening_params
75+
request_id: LSPSRequestId,
76+
/// The node id of the LSP.
77+
counterparty_node_id: PublicKey,
78+
/// The error that was returned.
79+
error: LSPSResponseError,
80+
},
81+
/// A request previously issued via [`LSPS2ClientHandler::select_opening_params`]
82+
/// failed as the LSP returned an error response.
83+
///
84+
/// [`LSPS2ClientHandler::select_opening_params`]: crate::lsps2::client::LSPS2ClientHandler::select_opening_params
85+
BuyRequestFailed {
86+
/// The identifier of the issued LSPS2 `buy` request, as returned by
87+
/// [`LSPS2ClientHandler::select_opening_params`].
88+
///
89+
/// This can be used to track which request this event corresponds to.
90+
///
91+
/// [`LSPS2ClientHandler::select_opening_params`]: crate::lsps2::client::LSPS2ClientHandler::select_opening_params
92+
request_id: LSPSRequestId,
93+
/// The node id of the LSP.
94+
counterparty_node_id: PublicKey,
95+
/// The error that was returned.
96+
error: LSPSResponseError,
97+
},
6498
}
6599

66100
/// An event which an bLIP-52 / LSPS2 server should take some action in response to.

lightning-liquidity/src/lsps2/service.rs

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1348,45 +1348,44 @@ where
13481348
&self, peer_state_lock: &mut MutexGuard<'a, PeerState>, request_id: LSPSRequestId,
13491349
counterparty_node_id: PublicKey, request: LSPS2Request,
13501350
) -> (Result<(), LightningError>, Option<LSPSMessage>) {
1351-
if self.total_pending_requests.load(Ordering::Relaxed) >= MAX_TOTAL_PENDING_REQUESTS {
1352-
let response = LSPS2Response::BuyError(LSPSResponseError {
1351+
let create_pending_request_limit_exceeded_response = |error_message: String| {
1352+
let error_details = LSPSResponseError {
13531353
code: LSPS0_CLIENT_REJECTED_ERROR_CODE,
13541354
message: "Reached maximum number of pending requests. Please try again later."
13551355
.to_string(),
13561356
data: None,
1357+
};
1358+
let response = match &request {
1359+
LSPS2Request::GetInfo(_) => LSPS2Response::GetInfoError(error_details),
1360+
LSPS2Request::Buy(_) => LSPS2Response::BuyError(error_details),
1361+
};
1362+
let msg = Some(LSPS2Message::Response(request_id.clone(), response).into());
1363+
1364+
let result = Err(LightningError {
1365+
err: error_message,
1366+
action: ErrorAction::IgnoreAndLog(Level::Debug),
13571367
});
1358-
let msg = Some(LSPS2Message::Response(request_id, response).into());
1368+
(result, msg)
1369+
};
13591370

1360-
let err = format!(
1361-
"Peer {} reached maximum number of total pending requests: {}",
1362-
counterparty_node_id, MAX_TOTAL_PENDING_REQUESTS
1371+
if self.total_pending_requests.load(Ordering::Relaxed) >= MAX_TOTAL_PENDING_REQUESTS {
1372+
let error_message = format!(
1373+
"Reached maximum number of total pending requests: {}",
1374+
MAX_TOTAL_PENDING_REQUESTS
13631375
);
1364-
let result =
1365-
Err(LightningError { err, action: ErrorAction::IgnoreAndLog(Level::Debug) });
1366-
return (result, msg);
1376+
return create_pending_request_limit_exceeded_response(error_message);
13671377
}
13681378

13691379
if peer_state_lock.pending_requests_and_channels() < MAX_PENDING_REQUESTS_PER_PEER {
13701380
peer_state_lock.pending_requests.insert(request_id, request);
13711381
self.total_pending_requests.fetch_add(1, Ordering::Relaxed);
13721382
(Ok(()), None)
13731383
} else {
1374-
let response = LSPS2Response::BuyError(LSPSResponseError {
1375-
code: LSPS0_CLIENT_REJECTED_ERROR_CODE,
1376-
message: "Reached maximum number of pending requests. Please try again later."
1377-
.to_string(),
1378-
data: None,
1379-
});
1380-
let msg = Some(LSPS2Message::Response(request_id, response).into());
1381-
1382-
let err = format!(
1384+
let error_message = format!(
13831385
"Peer {} reached maximum number of pending requests: {}",
13841386
counterparty_node_id, MAX_PENDING_REQUESTS_PER_PEER
13851387
);
1386-
let result =
1387-
Err(LightningError { err, action: ErrorAction::IgnoreAndLog(Level::Debug) });
1388-
1389-
(result, msg)
1388+
create_pending_request_limit_exceeded_response(error_message)
13901389
}
13911390
}
13921391

0 commit comments

Comments
 (0)