Skip to content

Commit 95892e3

Browse files
committed
Add FailureCode enum and ChannelManager::fail_htlc_backwards_with_reason
FailureCode is used to specify which error code and data to send to peers when failing back an HTLC. ChannelManager::fail_htlc_backwards_with_reason 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 e0a0add commit 95892e3

File tree

2 files changed

+46
-7
lines changed

2 files changed

+46
-7
lines changed

lightning/src/ln/channelmanager.rs

+41-3
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,25 @@ struct ReceiveError {
289289
msg: &'static str,
290290
}
291291

292+
/// This enum is used to specify which error data to send to peers when failing back an HTLC
293+
/// using [`ChannelManager::fail_htlc_backwards_with_reason`].
294+
///
295+
/// For more info on failure codes, see <https://github.com/lightning/bolts/blob/master/04-onion-routing.md#failure-messages>.
296+
#[derive(Clone, Copy)]
297+
pub enum FailureCode {
298+
/// We had a temporary error processing the payment. Useful if no other error codes fit
299+
/// and you want to indicate that the payer may want to retry.
300+
TemporaryNodeFailure = 0x2000 | 2,
301+
/// We have a required feature which was not in this onion. For example, you may require
302+
/// some additional metadata that was not provided with this payment.
303+
RequiredNodeFeatureMissing = 0x4000 | 0x2000 | 3,
304+
/// You may wish to use this when a `payment_preimage` is unknown, or the CLTV expiry of
305+
/// the HTLC is too close to the current block height for safe handling.
306+
/// Using this failure code in [`ChannelManager::fail_htlc_backwards_with_reason`] is
307+
/// equivalent to calling [`ChannelManager::fail_htlc_backwards`].
308+
IncorrectOrUnknownPaymentDetails = 0x4000 | 15,
309+
}
310+
292311
type ShutdownResult = (Option<(OutPoint, ChannelMonitorUpdate)>, Vec<(HTLCSource, PaymentHash, PublicKey, [u8; 32])>);
293312

294313
/// Error type returned across the peer_state mutex boundary. When an Err is generated for a
@@ -3472,21 +3491,40 @@ where
34723491
/// [`events::Event::PaymentClaimed`] events even for payments you intend to fail, especially on
34733492
/// startup during which time claims that were in-progress at shutdown may be replayed.
34743493
pub fn fail_htlc_backwards(&self, payment_hash: &PaymentHash) {
3494+
self.fail_htlc_backwards_with_reason(payment_hash, &FailureCode::IncorrectOrUnknownPaymentDetails);
3495+
}
3496+
3497+
/// This is a variant of [`ChannelManager::fail_htlc_backwards`] that allows you to specify the
3498+
/// reason for the failure.
3499+
///
3500+
/// See [`FailureCode`] for valid failure codes.
3501+
pub fn fail_htlc_backwards_with_reason(&self, payment_hash: &PaymentHash, failure_code: &FailureCode) {
34753502
let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier);
34763503

34773504
let removed_source = self.claimable_payments.lock().unwrap().claimable_htlcs.remove(payment_hash);
34783505
if let Some((_, mut sources)) = removed_source {
34793506
for htlc in sources.drain(..) {
3480-
let mut htlc_msat_height_data = htlc.value.to_be_bytes().to_vec();
3481-
htlc_msat_height_data.extend_from_slice(&self.best_block.read().unwrap().height().to_be_bytes());
3507+
let reason = self.get_htlc_fail_reason_from_failure_code(failure_code, &htlc);
34823508
let source = HTLCSource::PreviousHopData(htlc.prev_hop);
3483-
let reason = HTLCFailReason::reason(0x4000 | 15, htlc_msat_height_data);
34843509
let receiver = HTLCDestination::FailedPayment { payment_hash: *payment_hash };
34853510
self.fail_htlc_backwards_internal(&source, &payment_hash, &reason, receiver);
34863511
}
34873512
}
34883513
}
34893514

3515+
/// Gets error data to form an [`HTLCFailReason`] given a [`FailureCode`] and [`ClaimableHTLC`].
3516+
fn get_htlc_fail_reason_from_failure_code(&self, failure_code: &FailureCode, htlc: &ClaimableHTLC) -> HTLCFailReason {
3517+
match failure_code {
3518+
FailureCode::TemporaryNodeFailure => HTLCFailReason::from_failure_code(*failure_code as u16),
3519+
FailureCode::RequiredNodeFeatureMissing => HTLCFailReason::from_failure_code(*failure_code as u16),
3520+
FailureCode::IncorrectOrUnknownPaymentDetails => {
3521+
let mut htlc_msat_height_data = htlc.value.to_be_bytes().to_vec();
3522+
htlc_msat_height_data.extend_from_slice(&self.best_block.read().unwrap().height().to_be_bytes());
3523+
HTLCFailReason::reason(*failure_code as u16, htlc_msat_height_data)
3524+
}
3525+
}
3526+
}
3527+
34903528
/// Gets an HTLC onion failure code and error data for an `UPDATE` error, given the error code
34913529
/// that we want to return and a channel.
34923530
///

lightning/src/util/events.rs

+5-4
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)