Skip to content
This repository was archived by the owner on Jan 6, 2025. It is now read-only.

Commit bdae99f

Browse files
committed
Add handling around failed HTLCs and payments
1 parent 971641c commit bdae99f

File tree

1 file changed

+188
-0
lines changed

1 file changed

+188
-0
lines changed

src/lsps2/service.rs

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use crate::message_queue::MessageQueue;
1818
use crate::prelude::{HashMap, String, ToString, Vec};
1919
use crate::sync::{Arc, Mutex, RwLock};
2020

21+
use lightning::events::HTLCDestination;
2122
use lightning::ln::channelmanager::{AChannelManager, InterceptId};
2223
use lightning::ln::msgs::{ErrorAction, LightningError};
2324
use lightning::ln::{ChannelId, PaymentHash};
@@ -77,6 +78,7 @@ enum HTLCInterceptedAction {
7778
OpenChannel(OpenChannelParams),
7879
/// The forwarding of the intercepted HTLC.
7980
ForwardHTLC(ChannelId),
81+
ForwardPayment(ChannelId, FeePayment),
8082
}
8183

8284
/// The forwarding of a payment while skimming the JIT channel opening fee.
@@ -97,11 +99,22 @@ enum OutboundJITChannelState {
9799
/// opening of the channel. We are awaiting the completion of the channel establishment.
98100
PendingChannelOpen { payment_queue: Arc<Mutex<PaymentQueue>>, opening_fee_msat: u64 },
99101
/// The channel is open and a payment was forwarded while skimming the JIT channel fee.
102+
/// No further payments can be forwarded until the pending payment succeeds or fails, as we need
103+
/// to know whether the JIT channel fee needs to be skimmed from a next payment or not.
100104
PendingPaymentForward {
101105
payment_queue: Arc<Mutex<PaymentQueue>>,
102106
opening_fee_msat: u64,
103107
channel_id: ChannelId,
104108
},
109+
/// The channel is open, no payment is currently being forwarded, and the JIT channel fee still
110+
/// needs to be paid. This state can occur when the initial payment fails, e.g. due to a
111+
/// prepayment probe. We are awaiting a next payment of sufficient size to forward and skim the
112+
/// JIT channel fee.
113+
PendingPayment {
114+
payment_queue: Arc<Mutex<PaymentQueue>>,
115+
opening_fee_msat: u64,
116+
channel_id: ChannelId,
117+
},
105118
/// The channel is open and a payment was successfully forwarded while skimming the JIT channel
106119
/// fee. Any subsequent HTLCs can be forwarded without additional logic.
107120
PaymentForwarded { channel_id: ChannelId },
@@ -212,6 +225,35 @@ impl OutboundJITChannelState {
212225
};
213226
Ok((pending_payment_forward, None))
214227
},
228+
OutboundJITChannelState::PendingPayment {
229+
payment_queue,
230+
opening_fee_msat,
231+
channel_id,
232+
} => {
233+
let mut payment_queue_lock = payment_queue.lock().unwrap();
234+
payment_queue_lock.add_htlc(htlc);
235+
if let Some((_payment_hash, htlcs)) =
236+
payment_queue_lock.pop_greater_than_msat(*opening_fee_msat)
237+
{
238+
let pending_payment_forward = OutboundJITChannelState::PendingPaymentForward {
239+
payment_queue: payment_queue.clone(),
240+
opening_fee_msat: *opening_fee_msat,
241+
channel_id: *channel_id,
242+
};
243+
let forward_payment = HTLCInterceptedAction::ForwardPayment(
244+
*channel_id,
245+
FeePayment { htlcs, opening_fee_msat: *opening_fee_msat },
246+
);
247+
Ok((pending_payment_forward, Some(forward_payment)))
248+
} else {
249+
let pending_payment = OutboundJITChannelState::PendingPayment {
250+
payment_queue: payment_queue.clone(),
251+
opening_fee_msat: *opening_fee_msat,
252+
channel_id: *channel_id,
253+
};
254+
Ok((pending_payment, None))
255+
}
256+
},
215257
OutboundJITChannelState::PaymentForwarded { channel_id } => {
216258
let payment_forwarded =
217259
OutboundJITChannelState::PaymentForwarded { channel_id: *channel_id };
@@ -254,6 +296,62 @@ impl OutboundJITChannelState {
254296
}
255297
}
256298

299+
fn htlc_handling_failed(
300+
&mut self,
301+
) -> Result<(Self, Option<ForwardPaymentAction>), ChannelStateError> {
302+
match self {
303+
OutboundJITChannelState::PendingPaymentForward {
304+
payment_queue,
305+
opening_fee_msat,
306+
channel_id,
307+
} => {
308+
let mut payment_queue_lock = payment_queue.lock().unwrap();
309+
if let Some((_payment_hash, htlcs)) =
310+
payment_queue_lock.pop_greater_than_msat(*opening_fee_msat)
311+
{
312+
let pending_payment_forward = OutboundJITChannelState::PendingPaymentForward {
313+
payment_queue: payment_queue.clone(),
314+
opening_fee_msat: *opening_fee_msat,
315+
channel_id: *channel_id,
316+
};
317+
let forward_payment = ForwardPaymentAction(
318+
*channel_id,
319+
FeePayment { htlcs, opening_fee_msat: *opening_fee_msat },
320+
);
321+
Ok((pending_payment_forward, Some(forward_payment)))
322+
} else {
323+
let pending_payment = OutboundJITChannelState::PendingPayment {
324+
payment_queue: payment_queue.clone(),
325+
opening_fee_msat: *opening_fee_msat,
326+
channel_id: *channel_id,
327+
};
328+
Ok((pending_payment, None))
329+
}
330+
},
331+
OutboundJITChannelState::PendingPayment {
332+
payment_queue,
333+
opening_fee_msat,
334+
channel_id,
335+
} => {
336+
let pending_payment = OutboundJITChannelState::PendingPayment {
337+
payment_queue: payment_queue.clone(),
338+
opening_fee_msat: *opening_fee_msat,
339+
channel_id: *channel_id,
340+
};
341+
Ok((pending_payment, None))
342+
},
343+
OutboundJITChannelState::PaymentForwarded { channel_id } => {
344+
let payment_forwarded =
345+
OutboundJITChannelState::PaymentForwarded { channel_id: *channel_id };
346+
Ok((payment_forwarded, None))
347+
},
348+
state => Err(ChannelStateError(format!(
349+
"HTLC handling failed when JIT Channel was in state: {:?}",
350+
state
351+
))),
352+
}
353+
}
354+
257355
fn payment_forwarded(
258356
&mut self,
259357
) -> Result<(Self, Option<ForwardHTLCsAction>), ChannelStateError> {
@@ -308,6 +406,12 @@ impl OutboundJITChannel {
308406
Ok(action)
309407
}
310408

409+
fn htlc_handling_failed(&mut self) -> Result<Option<ForwardPaymentAction>, LightningError> {
410+
let (new_state, action) = self.state.htlc_handling_failed()?;
411+
self.state = new_state;
412+
Ok(action)
413+
}
414+
311415
fn channel_ready(
312416
&mut self, channel_id: ChannelId,
313417
) -> Result<ForwardPaymentAction, LightningError> {
@@ -571,6 +675,24 @@ where
571675
expected_outbound_amount_msat,
572676
)?;
573677
},
678+
Ok(Some(HTLCInterceptedAction::ForwardPayment(
679+
channel_id,
680+
FeePayment { opening_fee_msat, htlcs },
681+
))) => {
682+
let amounts_to_forward_msat =
683+
calculate_amount_to_forward_per_htlc(&htlcs, opening_fee_msat);
684+
685+
for (intercept_id, amount_to_forward_msat) in
686+
amounts_to_forward_msat
687+
{
688+
self.channel_manager.get_cm().forward_intercepted_htlc(
689+
intercept_id,
690+
&channel_id,
691+
*counterparty_node_id,
692+
amount_to_forward_msat,
693+
)?;
694+
}
695+
},
574696
Ok(None) => {},
575697
Err(e) => {
576698
self.channel_manager
@@ -596,6 +718,72 @@ where
596718
Ok(())
597719
}
598720

721+
/// Forward [`Event::HTLCHandlingFailed`] event parameter into this function.
722+
///
723+
/// Will attempt to forward the next payment in the queue if one is present.
724+
/// Will do nothing if the intercept scid does not match any of the ones we gave out
725+
/// or if the payment queue is empty
726+
///
727+
/// [`Event::HTLCHandlingFailed`]: lightning::events::Event::HTLCHandlingFailed
728+
pub fn htlc_handling_failed(
729+
&self, failed_next_destination: HTLCDestination,
730+
) -> Result<(), APIError> {
731+
if let HTLCDestination::NextHopChannel { channel_id, .. } = failed_next_destination {
732+
let peer_by_channel_id = self.peer_by_channel_id.read().unwrap();
733+
if let Some(counterparty_node_id) = peer_by_channel_id.get(&channel_id) {
734+
let outer_state_lock = self.per_peer_state.read().unwrap();
735+
match outer_state_lock.get(counterparty_node_id) {
736+
Some(inner_state_lock) => {
737+
let mut peer_state = inner_state_lock.lock().unwrap();
738+
if let Some(intercept_scid) =
739+
peer_state.intercept_scid_by_channel_id.get(&channel_id).copied()
740+
{
741+
if let Some(jit_channel) = peer_state
742+
.outbound_channels_by_intercept_scid
743+
.get_mut(&intercept_scid)
744+
{
745+
match jit_channel.htlc_handling_failed() {
746+
Ok(Some(ForwardPaymentAction(
747+
channel_id,
748+
FeePayment { opening_fee_msat, htlcs },
749+
))) => {
750+
let amounts_to_forward_msat =
751+
calculate_amount_to_forward_per_htlc(
752+
&htlcs,
753+
opening_fee_msat,
754+
);
755+
756+
for (intercept_id, amount_to_forward_msat) in
757+
amounts_to_forward_msat
758+
{
759+
self.channel_manager
760+
.get_cm()
761+
.forward_intercepted_htlc(
762+
intercept_id,
763+
&channel_id,
764+
*counterparty_node_id,
765+
amount_to_forward_msat,
766+
)?;
767+
}
768+
},
769+
Ok(None) => {},
770+
Err(e) => {
771+
return Err(APIError::APIMisuseError {
772+
err: format!("Unable to fail HTLC: {}.", e.err),
773+
});
774+
},
775+
}
776+
}
777+
}
778+
},
779+
None => {},
780+
}
781+
}
782+
}
783+
784+
Ok(())
785+
}
786+
599787
/// Forward [`Event::PaymentForwarded`] event parameter into this function.
600788
///
601789
/// Will register the forwarded payment as having paid the JIT channel fee, and forward any held

0 commit comments

Comments
 (0)