Skip to content

Commit 0808e86

Browse files
committed
ln: use map of failure codes instead of big match
Advantages: - Do not need to repeat mappings for u16 <> LocalHTLCFailureReason - Clearer division of different types of enum variants Disadvantages: - Don't get the `match` compiler check that all variants are covered
1 parent d4306ec commit 0808e86

File tree

1 file changed

+72
-80
lines changed

1 file changed

+72
-80
lines changed

lightning/src/ln/onion_utils.rs

Lines changed: 72 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1499,43 +1499,75 @@ pub enum LocalHTLCFailureReason {
14991499
}
15001500

15011501
impl LocalHTLCFailureReason {
1502-
pub(super) fn failure_code(&self) -> u16 {
1503-
match self {
1504-
Self::TemporaryNodeFailure | Self::ForwardExpiryBuffer => NODE | 2,
1505-
Self::PermanentNodeFailure => PERM | NODE | 2,
1506-
Self::RequiredNodeFeature | Self::PaymentSecretRequired => PERM | NODE | 3,
1507-
Self::InvalidOnionVersion => BADONION | PERM | 4,
1508-
Self::InvalidOnionHMAC => BADONION | PERM | 5,
1509-
Self::InvalidOnionKey => BADONION | PERM | 6,
1510-
Self::TemporaryChannelFailure
1511-
| Self::DustLimitHolder
1512-
| Self::DustLimitCounterparty
1513-
| Self::FeeSpikeBuffer
1514-
| Self::ChannelNotReady => UPDATE | 7,
1515-
Self::PermanentChannelFailure | Self::ChannelClosed | Self::DroppedPending => PERM | 8,
1516-
Self::RequiredChannelFeature => PERM | 9,
1517-
Self::UnknownNextPeer
1518-
| Self::PrivateChannelForward
1519-
| Self::RealSCIDForward
1520-
| Self::InvalidTrampolineForward => PERM | 10,
1521-
Self::AmountBelowMinimum => UPDATE | 11,
1522-
Self::FeeInsufficient => UPDATE | 12,
1523-
Self::IncorrectCLTVExpiry => UPDATE | 13,
1524-
Self::CLTVExpiryTooSoon | Self::OutgoingCLTVTooSoon => UPDATE | 14,
1525-
Self::IncorrectPaymentDetails | Self::PaymentClaimBuffer => PERM | 15,
1526-
Self::FinalIncorrectCLTVExpiry => 18,
1527-
Self::FinalIncorrectHTLCAmount => 19,
1528-
Self::ChannelDisabled => UPDATE | 20,
1529-
Self::CLTVExpiryTooFar => 21,
1530-
Self::InvalidOnionPayload
1531-
| Self::InvalidTrampolineHop
1532-
| Self::InvalidKeysendPreimage => PERM | 22,
1533-
Self::MPPTimeout => 23,
1534-
Self::InvalidOnionBlinding => BADONION | PERM | 24,
1535-
Self::UnknownFailureCode { code } => *code,
1502+
/// Maps BOLT04 failure code variants to their underlying failure code.
1503+
const BOLT_04_CODES: &'static[(Self, u16)] = &[
1504+
(Self::TemporaryNodeFailure, NODE | 2),
1505+
(Self::PermanentNodeFailure, PERM | NODE | 2),
1506+
(Self::RequiredNodeFeature, PERM | NODE | 3),
1507+
(Self::InvalidOnionVersion, BADONION | PERM | 4),
1508+
(Self::InvalidOnionHMAC, BADONION | PERM | 5),
1509+
(Self::InvalidOnionKey, BADONION | PERM | 6),
1510+
(Self::TemporaryChannelFailure, UPDATE | 7),
1511+
(Self::PermanentChannelFailure, PERM | 8),
1512+
(Self::RequiredChannelFeature, PERM | 9),
1513+
(Self::AmountBelowMinimum, UPDATE | 11),
1514+
(Self::FeeInsufficient, UPDATE | 12),
1515+
(Self::IncorrectCLTVExpiry, UPDATE | 13),
1516+
(Self::CLTVExpiryTooSoon, UPDATE | 14),
1517+
(Self::IncorrectPaymentDetails, PERM | 15),
1518+
(Self::FinalIncorrectCLTVExpiry, 18),
1519+
(Self::FinalIncorrectHTLCAmount, 19),
1520+
(Self::ChannelDisabled, UPDATE | 20),
1521+
(Self::CLTVExpiryTooFar, 21),
1522+
(Self::InvalidOnionPayload, PERM | 22),
1523+
(Self::MPPTimeout, 23),
1524+
(Self::InvalidOnionBlinding, BADONION | PERM | 24),
1525+
];
1526+
1527+
/// Maps variants that add additional information to a BOLT04 errors to the variant that
1528+
/// represents its BOLT04 error.
1529+
const BOLT_04_MAPPING: &'static[(Self, Self)] = &[
1530+
(Self::ForwardExpiryBuffer, Self::TemporaryNodeFailure),
1531+
(Self::PaymentSecretRequired, Self::RequiredNodeFeature),
1532+
(Self::InvalidTrampolineForward, Self::UnknownNextPeer),
1533+
(Self::PaymentClaimBuffer, Self::IncorrectPaymentDetails),
1534+
(Self::DustLimitHolder, Self::TemporaryChannelFailure),
1535+
(Self::DustLimitCounterparty, Self::TemporaryChannelFailure),
1536+
(Self::FeeSpikeBuffer, Self::TemporaryChannelFailure),
1537+
(Self::ChannelNotReady, Self::TemporaryChannelFailure),
1538+
(Self::DroppedPending, Self::PermanentChannelFailure),
1539+
(Self::ChannelClosed, Self::PermanentChannelFailure),
1540+
(Self::PrivateChannelForward, Self::UnknownNextPeer),
1541+
(Self::RealSCIDForward, Self::UnknownNextPeer),
1542+
(Self::InvalidTrampolineHop, Self::InvalidOnionPayload),
1543+
(Self::InvalidKeysendPreimage, Self::InvalidOnionPayload),
1544+
(Self::OutgoingCLTVTooSoon, Self::CLTVExpiryTooSoon),
1545+
];
1546+
1547+
/// Maps a [`LocalHTLCFailureReason`] to the variant that directly represents a BOLT04 failure
1548+
/// code. If the value is already a BOLT04 code, the fuction is a no-op.
1549+
fn to_bolt_04(&self) -> Self {
1550+
if let Some(bolt04) = Self::BOLT_04_MAPPING.iter().find(|(reason, _)| reason == self).map(|(_, b04)| *b04) {
1551+
bolt04
1552+
} else {
1553+
*self
15361554
}
15371555
}
15381556

1557+
/// Returns the BOLT 04 failure code that a variant represents.
1558+
pub (super) fn failure_code(&self) -> u16 {
1559+
let bolt_04_code = self.to_bolt_04();
1560+
1561+
if let Some(code) = Self::BOLT_04_CODES.iter().find(|(reason, _)| *reason == bolt_04_code).map(|(_, code)| *code) {
1562+
return code
1563+
}
1564+
1565+
// We should have all possible BOLT04 error codes defined, so we should never hit this.
1566+
debug_assert!(false);
1567+
PERM | NODE | 2
1568+
}
1569+
1570+
15391571
pub(super) fn is_temporary(&self) -> bool {
15401572
self.failure_code() & UPDATE == UPDATE
15411573
}
@@ -1548,53 +1580,13 @@ impl LocalHTLCFailureReason {
15481580

15491581
impl Into<LocalHTLCFailureReason> for u16 {
15501582
fn into(self) -> LocalHTLCFailureReason {
1551-
if self == (NODE | 2) {
1552-
LocalHTLCFailureReason::TemporaryNodeFailure
1553-
} else if self == (PERM | NODE | 2) {
1554-
LocalHTLCFailureReason::PermanentNodeFailure
1555-
} else if self == (PERM | NODE | 3) {
1556-
LocalHTLCFailureReason::RequiredNodeFeature
1557-
} else if self == (BADONION | PERM | 4) {
1558-
LocalHTLCFailureReason::InvalidOnionVersion
1559-
} else if self == (BADONION | PERM | 5) {
1560-
LocalHTLCFailureReason::InvalidOnionHMAC
1561-
} else if self == (BADONION | PERM | 6) {
1562-
LocalHTLCFailureReason::InvalidOnionKey
1563-
} else if self == (UPDATE | 7) {
1564-
LocalHTLCFailureReason::TemporaryChannelFailure
1565-
} else if self == (PERM | 8) {
1566-
LocalHTLCFailureReason::PermanentChannelFailure
1567-
} else if self == (PERM | 9) {
1568-
LocalHTLCFailureReason::RequiredChannelFeature
1569-
} else if self == (PERM | 10) {
1570-
LocalHTLCFailureReason::UnknownNextPeer
1571-
} else if self == (UPDATE | 11) {
1572-
LocalHTLCFailureReason::AmountBelowMinimum
1573-
} else if self == (UPDATE | 12) {
1574-
LocalHTLCFailureReason::FeeInsufficient
1575-
} else if self == (UPDATE | 13) {
1576-
LocalHTLCFailureReason::IncorrectCLTVExpiry
1577-
} else if self == (UPDATE | 14) {
1578-
LocalHTLCFailureReason::CLTVExpiryTooSoon
1579-
} else if self == (PERM | 15) {
1580-
LocalHTLCFailureReason::IncorrectPaymentDetails
1581-
} else if self == 18 {
1582-
LocalHTLCFailureReason::FinalIncorrectCLTVExpiry
1583-
} else if self == 19 {
1584-
LocalHTLCFailureReason::FinalIncorrectHTLCAmount
1585-
} else if self == (UPDATE | 20) {
1586-
LocalHTLCFailureReason::ChannelDisabled
1587-
} else if self == 21 {
1588-
LocalHTLCFailureReason::CLTVExpiryTooFar
1589-
} else if self == (PERM | 22) {
1590-
LocalHTLCFailureReason::InvalidOnionPayload
1591-
} else if self == 23 {
1592-
LocalHTLCFailureReason::MPPTimeout
1593-
} else if self == (BADONION | PERM | 24) {
1594-
LocalHTLCFailureReason::InvalidOnionBlinding
1595-
} else {
1596-
LocalHTLCFailureReason::UnknownFailureCode { code: self }
1583+
// Only iterate through defined BOLT 04 failure codes because we don't get more detailed
1584+
// codes from external sources.
1585+
if let Some(reason) = LocalHTLCFailureReason::BOLT_04_CODES.iter().find(|(_, code)| *code == self).map(|(reason, _)| *reason) {
1586+
return reason
15971587
}
1588+
1589+
LocalHTLCFailureReason::UnknownFailureCode { code: self }
15981590
}
15991591
}
16001592

0 commit comments

Comments
 (0)