Skip to content

Commit 30b1c3f

Browse files
committed
ln+events: add htlc failure reason to HTLCHandlingFailed
1 parent 8456a83 commit 30b1c3f

File tree

3 files changed

+57
-8
lines changed

3 files changed

+57
-8
lines changed

Diff for: lightning/src/events/mod.rs

+29-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use crate::chain::transaction;
2424
use crate::ln::channelmanager::{InterceptId, PaymentId, RecipientOnionFields};
2525
use crate::ln::channel::FUNDING_CONF_DEADLINE_BLOCKS;
2626
use crate::types::features::ChannelTypeFeatures;
27-
use crate::ln::msgs;
27+
use crate::ln::{msgs, LocalHTLCFailureReason};
2828
use crate::ln::types::ChannelId;
2929
use crate::types::payment::{PaymentPreimage, PaymentHash, PaymentSecret};
3030
use crate::offers::invoice::Bolt12Invoice;
@@ -524,6 +524,25 @@ impl_writeable_tlv_based_enum_upgradable!(HTLCHandlingType,
524524
},
525525
);
526526

527+
/// The reason for HTLC failures in [`Event::HTLCHandlingFailed`].
528+
#[derive(Clone, Debug, PartialEq, Eq)]
529+
pub enum HTLCHandlingFailureReason {
530+
/// The forwarded HTLC was failed back by the downstream node with an encrypted error reason.
531+
Downstream,
532+
/// The HTLC was failed locally by our node.
533+
Local {
534+
/// The reason that our node chose to fail the HTLC.
535+
reason: LocalHTLCFailureReason,
536+
},
537+
}
538+
539+
impl_writeable_tlv_based_enum!(HTLCHandlingFailureReason,
540+
(1, Downstream) => {},
541+
(3, Local) => {
542+
(0, reason, required),
543+
},
544+
);
545+
527546
/// Will be used in [`Event::HTLCIntercepted`] to identify the next hop in the HTLC's path.
528547
/// Currently only used in serialization for the sake of maintaining compatibility. More variants
529548
/// will be added for general-purpose HTLC forward intercepts as well as trampoline forward
@@ -1449,6 +1468,10 @@ pub enum Event {
14491468
prev_channel_id: ChannelId,
14501469
/// The type of HTLC that was handled.
14511470
handling_type: HTLCHandlingType,
1471+
/// The reason that the HTLC failed.
1472+
///
1473+
/// This field will be `None` only for objects serialized prior to LDK 0.2.0.
1474+
handling_failure: Option<HTLCHandlingFailureReason>
14521475
},
14531476
/// Indicates that a transaction originating from LDK needs to have its fee bumped. This event
14541477
/// requires confirmed external funds to be readily available to spend.
@@ -1752,10 +1775,11 @@ impl Writeable for Event {
17521775
(8, path.blinded_tail, option),
17531776
})
17541777
},
1755-
&Event::HTLCHandlingFailed { ref prev_channel_id, ref handling_type } => {
1778+
&Event::HTLCHandlingFailed { ref prev_channel_id, ref handling_type, ref handling_failure } => {
17561779
25u8.write(writer)?;
17571780
write_tlv_fields!(writer, {
17581781
(0, prev_channel_id, required),
1782+
(1, handling_failure, option),
17591783
(2, handling_type, required),
17601784
})
17611785
},
@@ -2201,14 +2225,17 @@ impl MaybeReadable for Event {
22012225
25u8 => {
22022226
let mut f = || {
22032227
let mut prev_channel_id = ChannelId::new_zero();
2228+
let mut handling_failure = None;
22042229
let mut handling_type_opt = UpgradableRequired(None);
22052230
read_tlv_fields!(reader, {
22062231
(0, prev_channel_id, required),
2232+
(1, handling_failure, option),
22072233
(2, handling_type_opt, upgradable_required),
22082234
});
22092235
Ok(Some(Event::HTLCHandlingFailed {
22102236
prev_channel_id,
22112237
handling_type: _init_tlv_based_struct_field!(handling_type_opt, upgradable_required),
2238+
handling_failure,
22122239
}))
22132240
};
22142241
f()

Diff for: lightning/src/ln/channelmanager.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -5784,8 +5784,8 @@ where
57845784
&update_add_htlc, &*self.node_signer, &*self.logger, &self.secp_ctx
57855785
) {
57865786
Ok(decoded_onion) => decoded_onion,
5787-
Err((htlc_fail, _)) => {
5788-
htlc_fails.push((htlc_fail, HTLCHandlingType::InvalidOnion));
5787+
Err((htlc_fail, reason)) => {
5788+
htlc_fails.push((htlc_fail, HTLCHandlingType::InvalidOnion, reason.into()));
57895789
continue;
57905790
},
57915791
};
@@ -5813,7 +5813,7 @@ where
58135813
is_intro_node_blinded_forward, &shared_secret,
58145814
);
58155815
let handling_type = get_failed_htlc_type(outgoing_scid_opt, update_add_htlc.payment_hash);
5816-
htlc_fails.push((htlc_fail, handling_type));
5816+
htlc_fails.push((htlc_fail, handling_type, reason.into()));
58175817
continue;
58185818
},
58195819
// The incoming channel no longer exists, HTLCs should be resolved onchain instead.
@@ -5830,7 +5830,7 @@ where
58305830
is_intro_node_blinded_forward, &shared_secret,
58315831
);
58325832
let handling_type = get_failed_htlc_type(outgoing_scid_opt, update_add_htlc.payment_hash);
5833-
htlc_fails.push((htlc_fail, handling_type));
5833+
htlc_fails.push((htlc_fail, handling_type, reason.into()));
58345834
continue;
58355835
}
58365836
}
@@ -5842,7 +5842,9 @@ where
58425842
Ok(info) => htlc_forwards.push((info, update_add_htlc.htlc_id)),
58435843
Err(inbound_err) => {
58445844
let handling_type = get_failed_htlc_type(outgoing_scid_opt, update_add_htlc.payment_hash);
5845-
htlc_fails.push((self.construct_pending_htlc_fail_msg(&update_add_htlc, &incoming_counterparty_node_id, shared_secret, inbound_err), handling_type));
5845+
let htlc_failure = inbound_err.reason.into();
5846+
htlc_fails.push((self.construct_pending_htlc_fail_msg(&update_add_htlc, &incoming_counterparty_node_id,
5847+
shared_secret, inbound_err), handling_type, htlc_failure));
58465848
},
58475849
}
58485850
}
@@ -5854,7 +5856,7 @@ where
58545856
incoming_channel_id, incoming_user_channel_id, htlc_forwards.drain(..).collect()
58555857
);
58565858
self.forward_htlcs_without_forward_event(&mut [pending_forwards]);
5857-
for (htlc_fail, handling_type) in htlc_fails.drain(..) {
5859+
for (htlc_fail, handling_type, handling_failure) in htlc_fails.drain(..) {
58585860
let failure = match htlc_fail {
58595861
HTLCFailureMsg::Relay(fail_htlc) => HTLCForwardInfo::FailHTLC {
58605862
htlc_id: fail_htlc.htlc_id,
@@ -5870,6 +5872,7 @@ where
58705872
self.pending_events.lock().unwrap().push_back((events::Event::HTLCHandlingFailed {
58715873
prev_channel_id: incoming_channel_id,
58725874
handling_type,
5875+
handling_failure: Some(handling_failure),
58735876
}, None));
58745877
}
58755878
}
@@ -7053,6 +7056,7 @@ where
70537056
pending_events.push_back((events::Event::HTLCHandlingFailed {
70547057
prev_channel_id: *channel_id,
70557058
handling_type,
7059+
handling_failure: Some(onion_error.into()),
70567060
}, None));
70577061
},
70587062
}

Diff for: lightning/src/ln/onion_utils.rs

+18
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;
@@ -1728,6 +1729,12 @@ impl Into<LocalHTLCFailureReason> for u16 {
17281729
}
17291730
}
17301731

1732+
impl Into<HTLCHandlingFailureReason> for LocalHTLCFailureReason {
1733+
fn into(self) -> HTLCHandlingFailureReason {
1734+
HTLCHandlingFailureReason::Local { reason: self }
1735+
}
1736+
}
1737+
17311738
impl_writeable_tlv_based_enum!(LocalHTLCFailureReason,
17321739
(1, TemporaryNodeFailure) => {},
17331740
(3, PermanentNodeFailure) => {},
@@ -2032,6 +2039,17 @@ impl HTLCFailReason {
20322039
}
20332040
}
20342041

2042+
impl Into<HTLCHandlingFailureReason> for &HTLCFailReason {
2043+
fn into(self) -> HTLCHandlingFailureReason {
2044+
match self.0 {
2045+
HTLCFailReasonRepr::LightningError { .. } => HTLCHandlingFailureReason::Downstream,
2046+
HTLCFailReasonRepr::Reason { reason, .. } => {
2047+
HTLCHandlingFailureReason::Local { reason }
2048+
},
2049+
}
2050+
}
2051+
}
2052+
20352053
/// Allows `decode_next_hop` to return the next hop packet bytes for either payments or onion
20362054
/// message forwards.
20372055
pub(crate) trait NextPacketBytes: AsMut<[u8]> {

0 commit comments

Comments
 (0)