Skip to content

Commit baf856e

Browse files
committed
ln+events: add htlc failure reason to HTLCHandlingFailed
1 parent b55761a commit baf856e

File tree

3 files changed

+57
-8
lines changed

3 files changed

+57
-8
lines changed

lightning/src/events/mod.rs

Lines changed: 29 additions & 2 deletions
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()

lightning/src/ln/channelmanager.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5776,8 +5776,8 @@ where
57765776
&update_add_htlc, &*self.node_signer, &*self.logger, &self.secp_ctx
57775777
) {
57785778
Ok(decoded_onion) => decoded_onion,
5779-
Err((htlc_fail, _)) => {
5780-
htlc_fails.push((htlc_fail, HTLCHandlingType::InvalidOnion));
5779+
Err((htlc_fail, reason)) => {
5780+
htlc_fails.push((htlc_fail, HTLCHandlingType::InvalidOnion, reason.into()));
57815781
continue;
57825782
},
57835783
};
@@ -5805,7 +5805,7 @@ where
58055805
is_intro_node_blinded_forward, &shared_secret,
58065806
);
58075807
let handling_type = get_failed_htlc_type(outgoing_scid_opt, update_add_htlc.payment_hash);
5808-
htlc_fails.push((htlc_fail, handling_type));
5808+
htlc_fails.push((htlc_fail, handling_type, reason.into()));
58095809
continue;
58105810
},
58115811
// The incoming channel no longer exists, HTLCs should be resolved onchain instead.
@@ -5822,7 +5822,7 @@ where
58225822
is_intro_node_blinded_forward, &shared_secret,
58235823
);
58245824
let handling_type = get_failed_htlc_type(outgoing_scid_opt, update_add_htlc.payment_hash);
5825-
htlc_fails.push((htlc_fail, handling_type));
5825+
htlc_fails.push((htlc_fail, handling_type, reason.into()));
58265826
continue;
58275827
}
58285828
}
@@ -5834,7 +5834,9 @@ where
58345834
Ok(info) => htlc_forwards.push((info, update_add_htlc.htlc_id)),
58355835
Err(inbound_err) => {
58365836
let handling_type = get_failed_htlc_type(outgoing_scid_opt, update_add_htlc.payment_hash);
5837-
htlc_fails.push((self.construct_pending_htlc_fail_msg(&update_add_htlc, &incoming_counterparty_node_id, shared_secret, inbound_err), handling_type));
5837+
let htlc_failure = inbound_err.reason.into();
5838+
htlc_fails.push((self.construct_pending_htlc_fail_msg(&update_add_htlc, &incoming_counterparty_node_id,
5839+
shared_secret, inbound_err), handling_type, htlc_failure));
58385840
},
58395841
}
58405842
}
@@ -5846,7 +5848,7 @@ where
58465848
incoming_channel_id, incoming_user_channel_id, htlc_forwards.drain(..).collect()
58475849
);
58485850
self.forward_htlcs_without_forward_event(&mut [pending_forwards]);
5849-
for (htlc_fail, handling_type) in htlc_fails.drain(..) {
5851+
for (htlc_fail, handling_type, handling_failure) in htlc_fails.drain(..) {
58505852
let failure = match htlc_fail {
58515853
HTLCFailureMsg::Relay(fail_htlc) => HTLCForwardInfo::FailHTLC {
58525854
htlc_id: fail_htlc.htlc_id,
@@ -5862,6 +5864,7 @@ where
58625864
self.pending_events.lock().unwrap().push_back((events::Event::HTLCHandlingFailed {
58635865
prev_channel_id: incoming_channel_id,
58645866
handling_type,
5867+
handling_failure: Some(handling_failure),
58655868
}, None));
58665869
}
58675870
}
@@ -7045,6 +7048,7 @@ where
70457048
pending_events.push_back((events::Event::HTLCHandlingFailed {
70467049
prev_channel_id: *channel_id,
70477050
handling_type,
7051+
handling_failure: Some(onion_error.into()),
70487052
}, None));
70497053
},
70507054
}

lightning/src/ln/onion_utils.rs

Lines changed: 18 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;
@@ -1627,6 +1628,12 @@ impl Into<LocalHTLCFailureReason> for u16 {
16271628
}
16281629
}
16291630

1631+
impl Into<HTLCHandlingFailureReason> for LocalHTLCFailureReason {
1632+
fn into(self) -> HTLCHandlingFailureReason {
1633+
HTLCHandlingFailureReason::Local { reason: self }
1634+
}
1635+
}
1636+
16301637
impl_writeable_tlv_based_enum!(LocalHTLCFailureReason,
16311638
(1, TemporaryNodeFailure) => {},
16321639
(3, PermanentNodeFailure) => {},
@@ -1891,6 +1898,17 @@ impl HTLCFailReason {
18911898
}
18921899
}
18931900

1901+
impl Into<HTLCHandlingFailureReason> for &HTLCFailReason {
1902+
fn into(self) -> HTLCHandlingFailureReason {
1903+
match self.0 {
1904+
HTLCFailReasonRepr::LightningError { .. } => HTLCHandlingFailureReason::Downstream,
1905+
HTLCFailReasonRepr::Reason { reason, .. } => {
1906+
HTLCHandlingFailureReason::Local { reason }
1907+
},
1908+
}
1909+
}
1910+
}
1911+
18941912
/// Allows `decode_next_hop` to return the next hop packet bytes for either payments or onion
18951913
/// message forwards.
18961914
pub(crate) trait NextPacketBytes: AsMut<[u8]> {

0 commit comments

Comments
 (0)