Skip to content

Commit 806a95d

Browse files
committed
Add ChannelManager::fail_htlc_backwards_with_reason
This function allows a user to specify the error code and corresponding data to send to peers when failing back an HTLC. This function is mentioned in Event::PaymentClaimable docs. ChannelManager::get_htlc_fail_reason_from_failure_code was also added to assist with this function.
1 parent db76201 commit 806a95d

File tree

2 files changed

+42
-28
lines changed

2 files changed

+42
-28
lines changed

lightning/src/ln/channelmanager.rs

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3511,35 +3511,48 @@ where
35113511
for htlc in sources.drain(..) {
35123512
let source = HTLCSource::PreviousHopData(htlc.prev_hop.clone());
35133513
let receiver = HTLCDestination::FailedPayment { payment_hash: *payment_hash };
3514-
3515-
let reason = match failure_code {
3516-
FailureCode::TemporaryNodeFailure => HTLCFailReason::from_failure_code(*failure_code as u16),
3517-
FailureCode::RequiredNodeFeatureMissing => HTLCFailReason::from_failure_code(*failure_code as u16),
3518-
FailureCode::ExpiryTooSoon => {
3519-
let short_channel_id = htlc.prev_hop.short_channel_id;
3520-
let (counterparty_node_id, chan_id) = self.short_to_chan_info.read().unwrap().get(&short_channel_id).cloned().unwrap();
3521-
let per_peer_state = self.per_peer_state.read().unwrap();
3522-
let peer_state = per_peer_state.get(&counterparty_node_id).unwrap().lock().unwrap();
3523-
let chan = peer_state.channel_by_id.get(&chan_id).unwrap();
3524-
let channel_update = self.get_channel_update_for_onion(short_channel_id, chan).unwrap();
3525-
let mut channel_update_data = Vec::new();
3526-
(channel_update.serialized_length() as u16 + 2).write(&mut channel_update_data).expect("Writes cannot fail");
3527-
msgs::ChannelUpdate::TYPE.write(&mut channel_update_data).expect("Writes cannot fail");
3528-
channel_update.write(&mut channel_update_data).expect("Writes cannot fail");
3529-
HTLCFailReason::reason(*failure_code as u16, channel_update_data)
3530-
},
3531-
FailureCode::IncorrectOrUnknownPaymentDetails => {
3532-
let mut htlc_msat_height_data = htlc.value.to_be_bytes().to_vec();
3533-
htlc_msat_height_data.extend_from_slice(&self.best_block.read().unwrap().height().to_be_bytes());
3534-
HTLCFailReason::reason(*failure_code as u16, htlc_msat_height_data)
3535-
}
3536-
};
3537-
3514+
let reason = self.get_htlc_fail_reason_from_failure_code(failure_code, &htlc);
35383515
self.fail_htlc_backwards_internal(&source, &payment_hash, &reason, receiver);
35393516
}
35403517
}
35413518
}
35423519

3520+
/// Gets error data to form an [`HTLCFailReason`] given a [`FailureCode`] and [`ClaimableHTLC`].
3521+
/// If something goes wrong while finding the necessary error data, this defaults to getting
3522+
/// error data for [`FailureCode::IncorrectOrUnknownPaymentDetails`].
3523+
fn get_htlc_fail_reason_from_failure_code(&self, failure_code: &FailureCode, htlc: &ClaimableHTLC) -> HTLCFailReason {
3524+
match failure_code {
3525+
FailureCode::TemporaryNodeFailure => HTLCFailReason::from_failure_code(*failure_code as u16),
3526+
FailureCode::RequiredNodeFeatureMissing => HTLCFailReason::from_failure_code(*failure_code as u16),
3527+
FailureCode::ExpiryTooSoon => {
3528+
let short_channel_id = htlc.prev_hop.short_channel_id;
3529+
let (counterparty_node_id, chan_id) = self.short_to_chan_info.read().unwrap().get(&short_channel_id).cloned().unwrap();
3530+
let per_peer_state = self.per_peer_state.read().unwrap();
3531+
let peer_state = per_peer_state.get(&counterparty_node_id);
3532+
if peer_state.is_none() {
3533+
return self.get_htlc_fail_reason_from_failure_code(&FailureCode::IncorrectOrUnknownPaymentDetails, htlc)
3534+
}
3535+
let peer_state = peer_state.unwrap().lock().unwrap();
3536+
let chan = peer_state.channel_by_id.get(&chan_id);
3537+
if chan.is_none() {
3538+
return self.get_htlc_fail_reason_from_failure_code(&FailureCode::IncorrectOrUnknownPaymentDetails, htlc)
3539+
}
3540+
let chan = chan.unwrap();
3541+
let channel_update = self.get_channel_update_for_onion(short_channel_id, chan).unwrap();
3542+
let mut channel_update_data = Vec::new();
3543+
(channel_update.serialized_length() as u16 + 2).write(&mut channel_update_data).expect("Writes cannot fail");
3544+
msgs::ChannelUpdate::TYPE.write(&mut channel_update_data).expect("Writes cannot fail");
3545+
channel_update.write(&mut channel_update_data).expect("Writes cannot fail");
3546+
HTLCFailReason::reason(*failure_code as u16, channel_update_data)
3547+
},
3548+
FailureCode::IncorrectOrUnknownPaymentDetails => {
3549+
let mut htlc_msat_height_data = htlc.value.to_be_bytes().to_vec();
3550+
htlc_msat_height_data.extend_from_slice(&self.best_block.read().unwrap().height().to_be_bytes());
3551+
HTLCFailReason::reason(*failure_code as u16, htlc_msat_height_data)
3552+
}
3553+
}
3554+
}
3555+
35433556
/// Gets an HTLC onion failure code and error data for an `UPDATE` error, given the error code
35443557
/// that we want to return and a channel.
35453558
///

lightning/src/util/events.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -491,10 +491,10 @@ pub enum Event {
491491
/// [`ChannelManager::claim_funds`] with the preimage given in [`PaymentPurpose`].
492492
///
493493
/// Note that if the preimage is not known, you should call
494-
/// [`ChannelManager::fail_htlc_backwards`] to free up resources for this HTLC and avoid
495-
/// network congestion.
496-
/// If you fail to call either [`ChannelManager::claim_funds`] or
497-
/// [`ChannelManager::fail_htlc_backwards`] within the HTLC's timeout, the HTLC will be
494+
/// [`ChannelManager::fail_htlc_backwards`] or [`ChannelManager::fail_htlc_backwards_with_reason`]
495+
/// to free up resources for this HTLC and avoid network congestion.
496+
/// If you fail to call either [`ChannelManager::claim_funds`], [`ChannelManager::fail_htlc_backwards`],
497+
/// or [`ChannelManager::fail_htlc_backwards_with_reason`] within the HTLC's timeout, the HTLC will be
498498
/// automatically failed.
499499
///
500500
/// # Note
@@ -506,6 +506,7 @@ pub enum Event {
506506
///
507507
/// [`ChannelManager::claim_funds`]: crate::ln::channelmanager::ChannelManager::claim_funds
508508
/// [`ChannelManager::fail_htlc_backwards`]: crate::ln::channelmanager::ChannelManager::fail_htlc_backwards
509+
/// [`ChannelManager::fail_htlc_backwards_with_reason`]: crate::ln::channelmanager::ChannelManager::fail_htlc_backwards_with_reason
509510
PaymentClaimable {
510511
/// The node that will receive the payment after it has been claimed.
511512
/// This is useful to identify payments received via [phantom nodes].

0 commit comments

Comments
 (0)