Skip to content

Commit ee97643

Browse files
committed
ln: persist failure_reason with HTLCFailureReason
Update the failure reason that's persisted in HTLCFailReasonRepr to store our newly added enum, rather than the old u16. In the commits that follow, we'll add more variants create a many-to-one mapping from enum to BOLT04 code (as we're surfacing internal information that is intentionally erased by the BOLT04 codes). Without this change to persistence, we'll lose the detail that these variants contain by storing them as their erased BOLT04 code.
1 parent 6e7a575 commit ee97643

File tree

1 file changed

+45
-10
lines changed

1 file changed

+45
-10
lines changed

lightning/src/ln/onion_utils.rs

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1650,6 +1650,34 @@ impl From<u16> for LocalHTLCFailureReason {
16501650
}
16511651
}
16521652

1653+
impl_writeable_tlv_based_enum!(LocalHTLCFailureReason,
1654+
(1, TemporaryNodeFailure) => {},
1655+
(3, PermanentNodeFailure) => {},
1656+
(5, RequiredNodeFeature) => {},
1657+
(7, InvalidOnionVersion) => {},
1658+
(9, InvalidOnionHMAC) => {},
1659+
(11, InvalidOnionKey) => {},
1660+
(13, TemporaryChannelFailure) => {},
1661+
(15, PermanentChannelFailure) => {},
1662+
(17, RequiredChannelFeature) => {},
1663+
(19, UnknownNextPeer) => {},
1664+
(21, AmountBelowMinimum) => {},
1665+
(23, FeeInsufficient) => {},
1666+
(25, IncorrectCLTVExpiry) => {},
1667+
(27, CLTVExpiryTooSoon) => {},
1668+
(29, IncorrectPaymentDetails) => {},
1669+
(31, FinalIncorrectCLTVExpiry) => {},
1670+
(33, FinalIncorrectHTLCAmount) => {},
1671+
(35, ChannelDisabled) => {},
1672+
(37, CLTVExpiryTooFar) => {},
1673+
(39, InvalidOnionPayload) => {},
1674+
(41, MPPTimeout) => {},
1675+
(43, InvalidOnionBlinding) => {},
1676+
(45, UnknownFailureCode) => {
1677+
(0, code, required),
1678+
},
1679+
);
1680+
16531681
#[derive(Clone)] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
16541682
#[cfg_attr(test, derive(PartialEq))]
16551683
pub(super) struct HTLCFailReason(HTLCFailReasonRepr);
@@ -1658,7 +1686,7 @@ pub(super) struct HTLCFailReason(HTLCFailReasonRepr);
16581686
#[cfg_attr(test, derive(PartialEq))]
16591687
enum HTLCFailReasonRepr {
16601688
LightningError { err: msgs::OnionErrorPacket, hold_time: Option<u32> },
1661-
Reason { failure_code: u16, data: Vec<u8> },
1689+
Reason { data: Vec<u8>, failure_reason: LocalHTLCFailureReason },
16621690
}
16631691

16641692
impl HTLCFailReason {
@@ -1675,8 +1703,8 @@ impl HTLCFailReason {
16751703
impl core::fmt::Debug for HTLCFailReason {
16761704
fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
16771705
match self.0 {
1678-
HTLCFailReasonRepr::Reason { ref failure_code, .. } => {
1679-
write!(f, "HTLC error code {}", failure_code)
1706+
HTLCFailReasonRepr::Reason { ref failure_reason, .. } => {
1707+
write!(f, "HTLC error code {}", failure_reason.failure_code())
16801708
},
16811709
HTLCFailReasonRepr::LightningError { .. } => {
16821710
write!(f, "pre-built LightningError")
@@ -1716,8 +1744,15 @@ impl_writeable_tlv_based_enum!(HTLCFailReasonRepr,
17161744
(_unused, err, (static_value, msgs::OnionErrorPacket { data: data.ok_or(DecodeError::InvalidValue)?, attribution_data })),
17171745
},
17181746
(1, Reason) => {
1719-
(0, failure_code, required),
1747+
(0, _failure_code, (legacy, u16,
1748+
|r: &HTLCFailReasonRepr| match r {
1749+
HTLCFailReasonRepr::LightningError{ .. } => None,
1750+
HTLCFailReasonRepr::Reason{ failure_reason, .. } => Some(failure_reason.failure_code())
1751+
})),
17201752
(2, data, required_vec),
1753+
// failure_code was required, and is replaced by reason in 0.2 so any time we do not have a
1754+
// reason available failure_code will be Some and can be expressed as a reason.
1755+
(4, failure_reason, (default_value, LocalHTLCFailureReason::from(_failure_code.ok_or(DecodeError::InvalidValue)?))),
17211756
},
17221757
);
17231758

@@ -1772,7 +1807,7 @@ impl HTLCFailReason {
17721807
},
17731808
}
17741809

1775-
Self(HTLCFailReasonRepr::Reason { failure_code: failure_reason.failure_code(), data })
1810+
Self(HTLCFailReasonRepr::Reason { data, failure_reason })
17761811
}
17771812

17781813
pub(super) fn from_failure_code(failure_reason: LocalHTLCFailureReason) -> Self {
@@ -1798,15 +1833,15 @@ impl HTLCFailReason {
17981833
&self, incoming_packet_shared_secret: &[u8; 32], secondary_shared_secret: &Option<[u8; 32]>,
17991834
) -> msgs::OnionErrorPacket {
18001835
match self.0 {
1801-
HTLCFailReasonRepr::Reason { ref failure_code, ref data } => {
1836+
HTLCFailReasonRepr::Reason { ref data, ref failure_reason } => {
18021837
// Final hop always reports zero hold time.
18031838
let hold_time: u32 = 0;
18041839

18051840
if let Some(secondary_shared_secret) = secondary_shared_secret {
18061841
// Phantom hop always reports zero hold time too.
18071842
let mut packet = build_failure_packet(
18081843
secondary_shared_secret,
1809-
u16::into(*failure_code),
1844+
*failure_reason,
18101845
&data[..],
18111846
hold_time,
18121847
);
@@ -1818,7 +1853,7 @@ impl HTLCFailReason {
18181853
} else {
18191854
build_failure_packet(
18201855
incoming_packet_shared_secret,
1821-
u16::into(*failure_code),
1856+
*failure_reason,
18221857
&data[..],
18231858
hold_time,
18241859
)
@@ -1847,7 +1882,7 @@ impl HTLCFailReason {
18471882
process_onion_failure(secp_ctx, logger, &htlc_source, err.clone())
18481883
},
18491884
#[allow(unused)]
1850-
HTLCFailReasonRepr::Reason { ref failure_code, ref data, .. } => {
1885+
HTLCFailReasonRepr::Reason { ref data, ref failure_reason } => {
18511886
// we get a fail_malformed_htlc from the first hop
18521887
// TODO: We'd like to generate a NetworkUpdate for temporary
18531888
// failures here, but that would be insufficient as find_route
@@ -1861,7 +1896,7 @@ impl HTLCFailReason {
18611896
failed_within_blinded_path: false,
18621897
hold_times: Vec::new(),
18631898
#[cfg(any(test, feature = "_test_utils"))]
1864-
onion_error_code: Some(*failure_code),
1899+
onion_error_code: Some(failure_reason.failure_code()),
18651900
#[cfg(any(test, feature = "_test_utils"))]
18661901
onion_error_data: Some(data.clone()),
18671902
}

0 commit comments

Comments
 (0)