Skip to content

Commit 21c9858

Browse files
committed
ln: persist failure_reason with HTLCFailureReason
1 parent 5587169 commit 21c9858

File tree

1 file changed

+65
-11
lines changed

1 file changed

+65
-11
lines changed

lightning/src/ln/onion_utils.rs

Lines changed: 65 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use crate::types::payment::{PaymentHash, PaymentPreimage};
2323
use crate::util::errors::{self, APIError};
2424
use crate::util::logger::Logger;
2525
use crate::util::ser::{
26-
LengthCalculatingWriter, Readable, ReadableArgs, VecWriter, Writeable, Writer,
26+
LengthCalculatingWriter, Readable, ReadableArgs, RequiredWrapper, VecWriter, Writeable, Writer
2727
};
2828

2929
use bitcoin::hashes::cmp::fixed_time_eq;
@@ -1711,6 +1711,49 @@ impl Into<LocalHTLCFailureReason> for u16 {
17111711
}
17121712
}
17131713

1714+
impl_writeable_tlv_based_enum!(LocalHTLCFailureReason,
1715+
(1, TemporaryNodeFailure) => {},
1716+
(3, PermanentNodeFailure) => {},
1717+
(5, RequiredNodeFeature) => {},
1718+
(7, InvalidOnionVersion) => {},
1719+
(9, InvalidOnionHMAC) => {},
1720+
(11, InvalidOnionKey) => {},
1721+
(13, TemporaryChannelFailure) => {},
1722+
(15, PermanentChannelFailure) => {},
1723+
(17, RequiredChannelFeature) => {},
1724+
(19, UnknownNextPeer) => {},
1725+
(21, AmountBelowMinimum) => {},
1726+
(23, FeeInsufficient) => {},
1727+
(25, IncorrectCLTVExpiry) => {},
1728+
(27, CLTVExpiryTooSoon) => {},
1729+
(29, IncorrectPaymentDetails) => {},
1730+
(31, FinalIncorrectCLTVExpiry) => {},
1731+
(33, FinalIncorrectHTLCAmount) => {},
1732+
(35, ChannelDisabled) => {},
1733+
(37, CLTVExpiryTooFar) => {},
1734+
(39, InvalidOnionPayload) => {},
1735+
(41, MPPTimeout) => {},
1736+
(43, InvalidOnionBlinding) => {},
1737+
(45, InvalidTrampolineForward) => {},
1738+
(47, PaymentClaimBuffer) => {},
1739+
(49, DustLimitHolder) => {},
1740+
(51, DustLimitCounterparty) => {},
1741+
(53, FeeSpikeBuffer) => {},
1742+
(55, DroppedPending) => {},
1743+
(57, PrivateChannelForward) => {},
1744+
(59, RealSCIDForward) => {},
1745+
(61, ChannelNotReady) => {},
1746+
(63, InvalidKeysendPreimage) => {},
1747+
(65, InvalidTrampolinePayload) => {},
1748+
(67, PaymentSecretRequired) => {},
1749+
(69, ForwardExpiryBuffer) => {},
1750+
(71, OutgoingCLTVTooSoon) => {},
1751+
(73, ChannelClosed) => {},
1752+
(75, UnknownFailureCode) => {
1753+
(0, code, required),
1754+
}
1755+
);
1756+
17141757
#[derive(Clone)] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
17151758
#[cfg_attr(test, derive(PartialEq))]
17161759
pub(super) struct HTLCFailReason(HTLCFailReasonRepr);
@@ -1719,7 +1762,7 @@ pub(super) struct HTLCFailReason(HTLCFailReasonRepr);
17191762
#[cfg_attr(test, derive(PartialEq))]
17201763
enum HTLCFailReasonRepr {
17211764
LightningError { err: msgs::OnionErrorPacket, hold_time: Option<u32> },
1722-
Reason { failure_code: u16, data: Vec<u8> },
1765+
Reason { data: Vec<u8>, reason: LocalHTLCFailureReason },
17231766
}
17241767

17251768
impl HTLCFailReason {
@@ -1736,8 +1779,8 @@ impl HTLCFailReason {
17361779
impl core::fmt::Debug for HTLCFailReason {
17371780
fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
17381781
match self.0 {
1739-
HTLCFailReasonRepr::Reason { ref failure_code, .. } => {
1740-
write!(f, "HTLC error code {}", failure_code)
1782+
HTLCFailReasonRepr::Reason { ref reason, .. } => {
1783+
write!(f, "HTLC error code {}", reason.failure_code())
17411784
},
17421785
HTLCFailReasonRepr::LightningError { .. } => {
17431786
write!(f, "pre-built LightningError")
@@ -1777,8 +1820,19 @@ impl_writeable_tlv_based_enum!(HTLCFailReasonRepr,
17771820
(_unused, err, (static_value, msgs::OnionErrorPacket { data: data.ok_or(DecodeError::InvalidValue)?, attribution_data })),
17781821
},
17791822
(1, Reason) => {
1780-
(0, failure_code, required),
1823+
(0, _failure_code, (legacy, u16,
1824+
|r: &HTLCFailReasonRepr| Some(r.clone()) )),
17811825
(2, data, required_vec),
1826+
// failure_code was required, and is replaced by reason so any time we do not have a
1827+
// reason available failure_code will be Some so we can require reason.
1828+
(4, reason, (default_value,
1829+
if let Some(code) = _failure_code {
1830+
let failure_reason: LocalHTLCFailureReason = code.into();
1831+
RequiredWrapper::from(failure_reason)
1832+
} else {
1833+
reason
1834+
}
1835+
)),
17821836
},
17831837
);
17841838

@@ -1850,7 +1904,7 @@ impl HTLCFailReason {
18501904
},
18511905
}
18521906

1853-
Self(HTLCFailReasonRepr::Reason { failure_code: failure_reason.failure_code(), data })
1907+
Self(HTLCFailReasonRepr::Reason { data, reason: failure_reason })
18541908
}
18551909

18561910
pub(super) fn from_failure_code(failure_reason: LocalHTLCFailureReason) -> Self {
@@ -1876,15 +1930,15 @@ impl HTLCFailReason {
18761930
&self, incoming_packet_shared_secret: &[u8; 32], secondary_shared_secret: &Option<[u8; 32]>,
18771931
) -> msgs::OnionErrorPacket {
18781932
match self.0 {
1879-
HTLCFailReasonRepr::Reason { ref failure_code, ref data } => {
1933+
HTLCFailReasonRepr::Reason { ref reason, ref data } => {
18801934
// Final hop always reports zero hold time.
18811935
let hold_time: u32 = 0;
18821936

18831937
if let Some(secondary_shared_secret) = secondary_shared_secret {
18841938
// Phantom hop always reports zero hold time too.
18851939
let mut packet = build_failure_packet(
18861940
secondary_shared_secret,
1887-
u16::into(*failure_code),
1941+
*reason,
18881942
&data[..],
18891943
hold_time,
18901944
);
@@ -1896,7 +1950,7 @@ impl HTLCFailReason {
18961950
} else {
18971951
build_failure_packet(
18981952
incoming_packet_shared_secret,
1899-
u16::into(*failure_code),
1953+
*reason,
19001954
&data[..],
19011955
hold_time,
19021956
)
@@ -1925,7 +1979,7 @@ impl HTLCFailReason {
19251979
process_onion_failure(secp_ctx, logger, &htlc_source, err.clone())
19261980
},
19271981
#[allow(unused)]
1928-
HTLCFailReasonRepr::Reason { ref failure_code, ref data, .. } => {
1982+
HTLCFailReasonRepr::Reason { ref data, ref reason } => {
19291983
// we get a fail_malformed_htlc from the first hop
19301984
// TODO: We'd like to generate a NetworkUpdate for temporary
19311985
// failures here, but that would be insufficient as find_route
@@ -1939,7 +1993,7 @@ impl HTLCFailReason {
19391993
failed_within_blinded_path: false,
19401994
hold_times: Vec::new(),
19411995
#[cfg(any(test, feature = "_test_utils"))]
1942-
onion_error_code: Some(*failure_code),
1996+
onion_error_code: Some(reason.failure_code()),
19431997
#[cfg(any(test, feature = "_test_utils"))]
19441998
onion_error_data: Some(data.clone()),
19451999
}

0 commit comments

Comments
 (0)