Skip to content

Commit 6083956

Browse files
committed
ln: persist failure_reason with HTLCFailureReason
1 parent b86f82d commit 6083956

File tree

1 file changed

+60
-10
lines changed

1 file changed

+60
-10
lines changed

lightning/src/ln/onion_utils.rs

+60-10
Original file line numberDiff line numberDiff line change
@@ -1712,6 +1712,49 @@ impl Into<LocalHTLCFailureReason> for u16 {
17121712
}
17131713
}
17141714

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

17261769
impl HTLCFailReason {
@@ -1737,8 +1780,8 @@ impl HTLCFailReason {
17371780
impl core::fmt::Debug for HTLCFailReason {
17381781
fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
17391782
match self.0 {
1740-
HTLCFailReasonRepr::Reason { ref failure_code, .. } => {
1741-
write!(f, "HTLC error code {}", failure_code)
1783+
HTLCFailReasonRepr::Reason { ref reason, .. } => {
1784+
write!(f, "HTLC error code {}", reason.failure_code())
17421785
},
17431786
HTLCFailReasonRepr::LightningError { .. } => {
17441787
write!(f, "pre-built LightningError")
@@ -1778,8 +1821,15 @@ impl_writeable_tlv_based_enum!(HTLCFailReasonRepr,
17781821
(_unused, err, (static_value, msgs::OnionErrorPacket { data: data.ok_or(DecodeError::InvalidValue)?, attribution_data })),
17791822
},
17801823
(1, Reason) => {
1781-
(0, failure_code, required),
1824+
(0, _failure_code, (legacy, u16,
1825+
|r: &HTLCFailReasonRepr| match r {
1826+
HTLCFailReasonRepr::LightningError{ .. } => None,
1827+
HTLCFailReasonRepr::Reason{ reason, .. } => Some(reason.failure_code())
1828+
})),
17821829
(2, data, required_vec),
1830+
// failure_code was required, and is replaced by reason in 0.2 so any time we do not have a
1831+
// reason available failure_code will be Some and can be expressed as a reason.
1832+
(4, reason, (default_value, <u16 as Into<LocalHTLCFailureReason>>::into(_failure_code.ok_or(DecodeError::InvalidValue)?))),
17831833
},
17841834
);
17851835

@@ -1851,7 +1901,7 @@ impl HTLCFailReason {
18511901
},
18521902
}
18531903

1854-
Self(HTLCFailReasonRepr::Reason { failure_code: failure_reason.failure_code(), data })
1904+
Self(HTLCFailReasonRepr::Reason { data, reason: failure_reason })
18551905
}
18561906

18571907
pub(super) fn from_failure_code(failure_reason: LocalHTLCFailureReason) -> Self {
@@ -1877,15 +1927,15 @@ impl HTLCFailReason {
18771927
&self, incoming_packet_shared_secret: &[u8; 32], secondary_shared_secret: &Option<[u8; 32]>,
18781928
) -> msgs::OnionErrorPacket {
18791929
match self.0 {
1880-
HTLCFailReasonRepr::Reason { ref failure_code, ref data } => {
1930+
HTLCFailReasonRepr::Reason { ref reason, ref data } => {
18811931
// Final hop always reports zero hold time.
18821932
let hold_time: u32 = 0;
18831933

18841934
if let Some(secondary_shared_secret) = secondary_shared_secret {
18851935
// Phantom hop always reports zero hold time too.
18861936
let mut packet = build_failure_packet(
18871937
secondary_shared_secret,
1888-
u16::into(*failure_code),
1938+
*reason,
18891939
&data[..],
18901940
hold_time,
18911941
);
@@ -1897,7 +1947,7 @@ impl HTLCFailReason {
18971947
} else {
18981948
build_failure_packet(
18991949
incoming_packet_shared_secret,
1900-
u16::into(*failure_code),
1950+
*reason,
19011951
&data[..],
19021952
hold_time,
19031953
)
@@ -1926,7 +1976,7 @@ impl HTLCFailReason {
19261976
process_onion_failure(secp_ctx, logger, &htlc_source, err.clone())
19271977
},
19281978
#[allow(unused)]
1929-
HTLCFailReasonRepr::Reason { ref failure_code, ref data, .. } => {
1979+
HTLCFailReasonRepr::Reason { ref data, ref reason } => {
19301980
// we get a fail_malformed_htlc from the first hop
19311981
// TODO: We'd like to generate a NetworkUpdate for temporary
19321982
// failures here, but that would be insufficient as find_route
@@ -1940,7 +1990,7 @@ impl HTLCFailReason {
19401990
failed_within_blinded_path: false,
19411991
hold_times: Vec::new(),
19421992
#[cfg(any(test, feature = "_test_utils"))]
1943-
onion_error_code: Some(*failure_code),
1993+
onion_error_code: Some(reason.failure_code()),
19441994
#[cfg(any(test, feature = "_test_utils"))]
19451995
onion_error_data: Some(data.clone()),
19461996
}

0 commit comments

Comments
 (0)