Skip to content

Commit 44e1295

Browse files
committed
ln: persist failure_reason with HTLCFailureReason
ln: persist failure_reason with HTLCFailureReason
1 parent a0131e4 commit 44e1295

File tree

1 file changed

+68
-20
lines changed

1 file changed

+68
-20
lines changed

lightning/src/ln/onion_utils.rs

Lines changed: 68 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ use crate::types::features::{ChannelFeatures, NodeFeatures};
2222
use crate::types::payment::{PaymentHash, PaymentPreimage};
2323
use crate::util::errors::{self, APIError};
2424
use crate::util::logger::Logger;
25-
use crate::util::ser::{LengthCalculatingWriter, Readable, ReadableArgs, Writeable, Writer};
25+
use crate::util::ser::{
26+
LengthCalculatingWriter, Readable, ReadableArgs, RequiredWrapper, Writeable, Writer,
27+
};
2628

2729
use bitcoin::hashes::cmp::fixed_time_eq;
2830
use bitcoin::hashes::hmac::{Hmac, HmacEngine};
@@ -1595,6 +1597,49 @@ impl Into<LocalHTLCFailureReason> for u16 {
15951597
}
15961598
}
15971599

1600+
impl_writeable_tlv_based_enum!(LocalHTLCFailureReason,
1601+
(0, TemporaryNodeFailure) => {},
1602+
(1, PermanentNodeFailure) => {},
1603+
(2, RequiredNodeFeature) => {},
1604+
(3, InvalidOnionVersion) => {},
1605+
(4, InvalidOnionHMAC) => {},
1606+
(5, InvalidOnionKey) => {},
1607+
(6, TemporaryChannelFailure) => {},
1608+
(7, PermanentChannelFailure) => {},
1609+
(8, RequiredChannelFeature) => {},
1610+
(9, UnknownNextPeer) => {},
1611+
(10, AmountBelowMinimum) => {},
1612+
(11, FeeInsufficient) => {},
1613+
(12, IncorrectCLTVExpiry) => {},
1614+
(13, CLTVExpiryTooSoon) => {},
1615+
(14, IncorrectPaymentDetails) => {},
1616+
(15, FinalIncorrectCLTVExpiry) => {},
1617+
(16, FinalIncorrectHTLCAmount) => {},
1618+
(17, ChannelDisabled) => {},
1619+
(18, CLTVExpiryTooFar) => {},
1620+
(19, InvalidOnionPayload) => {},
1621+
(20, MPPTimeout) => {},
1622+
(21, InvalidOnionBlinding) => {},
1623+
(22, InvalidTrampolineForward) => {},
1624+
(23, PaymentClaimBuffer) => {},
1625+
(24, DustLimitHolder) => {},
1626+
(25, DustLimitCounterparty) => {},
1627+
(26, FeeSpikeBuffer) => {},
1628+
(27, DroppedPending) => {},
1629+
(28, PrivateChannelForward) => {},
1630+
(29, RealSCIDForward) => {},
1631+
(30, ChannelNotReady) => {},
1632+
(31, InvalidKeysendPreimage) => {},
1633+
(32, InvalidTrampolineHop) => {},
1634+
(33, PaymentSecretRequired) => {},
1635+
(34, ForwardExpiryBuffer) => {},
1636+
(35, OutgoingCLTVTooSoon) => {},
1637+
(36, ChannelClosed) => {},
1638+
(37, UnknownFailureCode) => {
1639+
(0, code, required),
1640+
}
1641+
);
1642+
15981643
#[derive(Clone)] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
15991644
#[cfg_attr(test, derive(PartialEq))]
16001645
pub(super) struct HTLCFailReason(HTLCFailReasonRepr);
@@ -1603,14 +1648,14 @@ pub(super) struct HTLCFailReason(HTLCFailReasonRepr);
16031648
#[cfg_attr(test, derive(PartialEq))]
16041649
enum HTLCFailReasonRepr {
16051650
LightningError { err: msgs::OnionErrorPacket },
1606-
Reason { failure_code: u16, data: Vec<u8> },
1651+
Reason { data: Vec<u8>, reason: LocalHTLCFailureReason },
16071652
}
16081653

16091654
impl core::fmt::Debug for HTLCFailReason {
16101655
fn fmt(&self, f: &mut core::fmt::Formatter) -> Result<(), core::fmt::Error> {
16111656
match self.0 {
1612-
HTLCFailReasonRepr::Reason { ref failure_code, .. } => {
1613-
write!(f, "HTLC error code {}", failure_code)
1657+
HTLCFailReasonRepr::Reason { ref reason, .. } => {
1658+
write!(f, "HTLC error code {}", reason.failure_code())
16141659
},
16151660
HTLCFailReasonRepr::LightningError { .. } => {
16161661
write!(f, "pre-built LightningError")
@@ -1642,8 +1687,19 @@ impl_writeable_tlv_based_enum!(HTLCFailReasonRepr,
16421687
(_unused, err, (static_value, msgs::OnionErrorPacket { data: data.ok_or(DecodeError::InvalidValue)? })),
16431688
},
16441689
(1, Reason) => {
1645-
(0, failure_code, required),
1690+
(0, _failure_code, (legacy, u16,
1691+
|r: &HTLCFailReasonRepr| Some(r.clone()) )),
16461692
(2, data, required_vec),
1693+
// failure_code was required, and is replaced by reason so any time we do not have a
1694+
// reason available failure_code will be Some so we can require reason.
1695+
(4, reason, (default_value,
1696+
if let Some(code) = _failure_code {
1697+
let failure_reason: LocalHTLCFailureReason = code.into();
1698+
RequiredWrapper::from(failure_reason)
1699+
} else {
1700+
reason
1701+
}
1702+
)),
16471703
},
16481704
);
16491705

@@ -1715,7 +1771,7 @@ impl HTLCFailReason {
17151771
},
17161772
}
17171773

1718-
Self(HTLCFailReasonRepr::Reason { failure_code: failure_reason.failure_code(), data })
1774+
Self(HTLCFailReasonRepr::Reason { data, reason: failure_reason })
17191775
}
17201776

17211777
pub(super) fn from_failure_code(failure_reason: LocalHTLCFailureReason) -> Self {
@@ -1737,24 +1793,16 @@ impl HTLCFailReason {
17371793
&self, incoming_packet_shared_secret: &[u8; 32], secondary_shared_secret: &Option<[u8; 32]>,
17381794
) -> msgs::OnionErrorPacket {
17391795
match self.0 {
1740-
HTLCFailReasonRepr::Reason { ref failure_code, ref data } => {
1741-
let failure_code = *failure_code;
1796+
HTLCFailReasonRepr::Reason { ref data, ref reason } => {
17421797
if let Some(secondary_shared_secret) = secondary_shared_secret {
1743-
let mut packet = build_failure_packet(
1744-
secondary_shared_secret,
1745-
failure_code.into(),
1746-
&data[..],
1747-
);
1798+
let mut packet =
1799+
build_failure_packet(secondary_shared_secret, *reason, &data[..]);
17481800

17491801
crypt_failure_packet(incoming_packet_shared_secret, &mut packet);
17501802

17511803
packet
17521804
} else {
1753-
build_failure_packet(
1754-
incoming_packet_shared_secret,
1755-
failure_code.into(),
1756-
&data[..],
1757-
)
1805+
build_failure_packet(incoming_packet_shared_secret, *reason, &data[..])
17581806
}
17591807
},
17601808
HTLCFailReasonRepr::LightningError { ref err } => {
@@ -1778,7 +1826,7 @@ impl HTLCFailReason {
17781826
process_onion_failure(secp_ctx, logger, &htlc_source, err.clone())
17791827
},
17801828
#[allow(unused)]
1781-
HTLCFailReasonRepr::Reason { ref failure_code, ref data, .. } => {
1829+
HTLCFailReasonRepr::Reason { ref data, ref reason } => {
17821830
// we get a fail_malformed_htlc from the first hop
17831831
// TODO: We'd like to generate a NetworkUpdate for temporary
17841832
// failures here, but that would be insufficient as find_route
@@ -1791,7 +1839,7 @@ impl HTLCFailReason {
17911839
short_channel_id: Some(path.hops[0].short_channel_id),
17921840
failed_within_blinded_path: false,
17931841
#[cfg(any(test, feature = "_test_utils"))]
1794-
onion_error_code: Some(*failure_code),
1842+
onion_error_code: Some(reason.failure_code()),
17951843
#[cfg(any(test, feature = "_test_utils"))]
17961844
onion_error_data: Some(data.clone()),
17971845
}

0 commit comments

Comments
 (0)