Skip to content

Commit 981af5b

Browse files
committed
ln+events: add htlc failure reason to HTLCHandlingFailed
1 parent b9017a0 commit 981af5b

File tree

3 files changed

+56
-8
lines changed

3 files changed

+56
-8
lines changed

lightning/src/events/mod.rs

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use crate::ln::channel::FUNDING_CONF_DEADLINE_BLOCKS;
2626
use crate::offers::invoice::Bolt12Invoice;
2727
use crate::offers::static_invoice::StaticInvoice;
2828
use crate::types::features::ChannelTypeFeatures;
29-
use crate::ln::msgs;
29+
use crate::ln::{msgs, LocalHTLCFailureReason};
3030
use crate::ln::types::ChannelId;
3131
use crate::types::payment::{PaymentPreimage, PaymentHash, PaymentSecret};
3232
use crate::onion_message::messenger::Responder;
@@ -525,6 +525,31 @@ impl_writeable_tlv_based_enum_upgradable!(HTLCHandlingType,
525525
},
526526
);
527527

528+
/// The reason for HTLC failures in [`Event::HTLCHandlingFailed`].
529+
#[derive(Clone, Debug, PartialEq, Eq)]
530+
pub enum HTLCHandlingFailureReason {
531+
/// The forwarded HTLC was failed back by the downstream node with an encrypted error reason.
532+
Downstream,
533+
/// The HTLC was failed locally by our node.
534+
Local {
535+
/// The reason that our node chose to fail the HTLC.
536+
reason: LocalHTLCFailureReason,
537+
},
538+
}
539+
540+
impl_writeable_tlv_based_enum!(HTLCHandlingFailureReason,
541+
(1, Downstream) => {},
542+
(3, Local) => {
543+
(0, reason, required),
544+
},
545+
);
546+
547+
impl From<LocalHTLCFailureReason> for HTLCHandlingFailureReason {
548+
fn from(value: LocalHTLCFailureReason) -> Self {
549+
HTLCHandlingFailureReason::Local { reason: value }
550+
}
551+
}
552+
528553
/// Will be used in [`Event::HTLCIntercepted`] to identify the next hop in the HTLC's path.
529554
/// Currently only used in serialization for the sake of maintaining compatibility. More variants
530555
/// will be added for general-purpose HTLC forward intercepts as well as trampoline forward
@@ -1462,6 +1487,10 @@ pub enum Event {
14621487
prev_channel_id: ChannelId,
14631488
/// The type of HTLC that was handled.
14641489
handling_type: HTLCHandlingType,
1490+
/// The reason that the HTLC failed.
1491+
///
1492+
/// This field will be `None` only for objects serialized prior to LDK 0.2.0.
1493+
handling_failure: Option<HTLCHandlingFailureReason>
14651494
},
14661495
/// Indicates that a transaction originating from LDK needs to have its fee bumped. This event
14671496
/// requires confirmed external funds to be readily available to spend.
@@ -1766,10 +1795,11 @@ impl Writeable for Event {
17661795
(8, path.blinded_tail, option),
17671796
})
17681797
},
1769-
&Event::HTLCHandlingFailed { ref prev_channel_id, ref handling_type } => {
1798+
&Event::HTLCHandlingFailed { ref prev_channel_id, ref handling_type, ref handling_failure } => {
17701799
25u8.write(writer)?;
17711800
write_tlv_fields!(writer, {
17721801
(0, prev_channel_id, required),
1802+
(1, handling_failure, option),
17731803
(2, handling_type, required),
17741804
})
17751805
},
@@ -2218,14 +2248,17 @@ impl MaybeReadable for Event {
22182248
25u8 => {
22192249
let mut f = || {
22202250
let mut prev_channel_id = ChannelId::new_zero();
2251+
let mut handling_failure = None;
22212252
let mut handling_type_opt = UpgradableRequired(None);
22222253
read_tlv_fields!(reader, {
22232254
(0, prev_channel_id, required),
2255+
(1, handling_failure, option),
22242256
(2, handling_type_opt, upgradable_required),
22252257
});
22262258
Ok(Some(Event::HTLCHandlingFailed {
22272259
prev_channel_id,
22282260
handling_type: _init_tlv_based_struct_field!(handling_type_opt, upgradable_required),
2261+
handling_failure,
22292262
}))
22302263
};
22312264
f()

lightning/src/ln/channelmanager.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5788,8 +5788,8 @@ where
57885788
&update_add_htlc, &*self.node_signer, &*self.logger, &self.secp_ctx
57895789
) {
57905790
Ok(decoded_onion) => decoded_onion,
5791-
Err((htlc_fail, _)) => {
5792-
htlc_fails.push((htlc_fail, HTLCHandlingType::InvalidOnion));
5791+
Err((htlc_fail, reason)) => {
5792+
htlc_fails.push((htlc_fail, HTLCHandlingType::InvalidOnion, reason.into()));
57935793
continue;
57945794
},
57955795
};
@@ -5817,7 +5817,7 @@ where
58175817
is_intro_node_blinded_forward, &shared_secret,
58185818
);
58195819
let handling_type = get_failed_htlc_type(outgoing_scid_opt, update_add_htlc.payment_hash);
5820-
htlc_fails.push((htlc_fail, handling_type));
5820+
htlc_fails.push((htlc_fail, handling_type, reason.into()));
58215821
continue;
58225822
},
58235823
// The incoming channel no longer exists, HTLCs should be resolved onchain instead.
@@ -5834,7 +5834,7 @@ where
58345834
is_intro_node_blinded_forward, &shared_secret,
58355835
);
58365836
let handling_type = get_failed_htlc_type(outgoing_scid_opt, update_add_htlc.payment_hash);
5837-
htlc_fails.push((htlc_fail, handling_type));
5837+
htlc_fails.push((htlc_fail, handling_type, reason.into()));
58385838
continue;
58395839
}
58405840
}
@@ -5846,8 +5846,9 @@ where
58465846
Ok(info) => htlc_forwards.push((info, update_add_htlc.htlc_id)),
58475847
Err(inbound_err) => {
58485848
let handling_type = get_failed_htlc_type(outgoing_scid_opt, update_add_htlc.payment_hash);
5849+
let htlc_failure = inbound_err.reason.into();
58495850
let htlc_fail = self.construct_pending_htlc_fail_msg(&update_add_htlc, &incoming_counterparty_node_id, shared_secret, inbound_err);
5850-
htlc_fails.push((htlc_fail, handling_type));
5851+
htlc_fails.push((htlc_fail, handling_type, htlc_failure));
58515852
},
58525853
}
58535854
}
@@ -5859,7 +5860,7 @@ where
58595860
incoming_channel_id, incoming_user_channel_id, htlc_forwards.drain(..).collect()
58605861
);
58615862
self.forward_htlcs_without_forward_event(&mut [pending_forwards]);
5862-
for (htlc_fail, handling_type) in htlc_fails.drain(..) {
5863+
for (htlc_fail, handling_type, handling_failure) in htlc_fails.drain(..) {
58635864
let failure = match htlc_fail {
58645865
HTLCFailureMsg::Relay(fail_htlc) => HTLCForwardInfo::FailHTLC {
58655866
htlc_id: fail_htlc.htlc_id,
@@ -5875,6 +5876,7 @@ where
58755876
self.pending_events.lock().unwrap().push_back((events::Event::HTLCHandlingFailed {
58765877
prev_channel_id: incoming_channel_id,
58775878
handling_type,
5879+
handling_failure: Some(handling_failure),
58785880
}, None));
58795881
}
58805882
}
@@ -7055,6 +7057,7 @@ where
70557057
pending_events.push_back((events::Event::HTLCHandlingFailed {
70567058
prev_channel_id: *channel_id,
70577059
handling_type,
7060+
handling_failure: Some(onion_error.into()),
70587061
}, None));
70597062
},
70607063
}

lightning/src/ln/onion_utils.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use super::msgs::OnionErrorPacket;
1111
use crate::blinded_path::BlindedHop;
1212
use crate::crypto::chacha20::ChaCha20;
1313
use crate::crypto::streams::ChaChaReader;
14+
use crate::events::HTLCHandlingFailureReason;
1415
use crate::ln::channel::TOTAL_BITCOIN_SUPPLY_SATOSHIS;
1516
use crate::ln::channelmanager::{HTLCSource, RecipientOnionFields};
1617
use crate::ln::msgs;
@@ -1784,6 +1785,17 @@ impl_writeable_tlv_based_enum!(LocalHTLCFailureReason,
17841785
(85, PeerOffline) => {},
17851786
);
17861787

1788+
impl From<&HTLCFailReason> for HTLCHandlingFailureReason {
1789+
fn from(value: &HTLCFailReason) -> Self {
1790+
match value.0 {
1791+
HTLCFailReasonRepr::LightningError { .. } => HTLCHandlingFailureReason::Downstream,
1792+
HTLCFailReasonRepr::Reason { failure_reason, .. } => {
1793+
HTLCHandlingFailureReason::Local { reason: failure_reason }
1794+
},
1795+
}
1796+
}
1797+
}
1798+
17871799
#[derive(Clone)] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
17881800
#[cfg_attr(test, derive(PartialEq))]
17891801
pub(super) struct HTLCFailReason(HTLCFailReasonRepr);

0 commit comments

Comments
 (0)