@@ -1069,11 +1069,6 @@ where
10691069 let mut is_from_final_non_blinded_node = false ;
10701070 let mut hop_hold_times: Vec < u32 > = Vec :: new ( ) ;
10711071
1072- const BADONION : u16 = 0x8000 ;
1073- const PERM : u16 = 0x4000 ;
1074- const NODE : u16 = 0x2000 ;
1075- const UPDATE : u16 = 0x1000 ;
1076-
10771072 enum ErrorHop < ' a > {
10781073 RouteHop ( & ' a RouteHop ) ,
10791074 TrampolineHop ( & ' a TrampolineHop ) ,
@@ -1451,6 +1446,188 @@ where
14511446 }
14521447}
14531448
1449+ const BADONION : u16 = 0x8000 ;
1450+ const PERM : u16 = 0x4000 ;
1451+ const NODE : u16 = 0x2000 ;
1452+ const UPDATE : u16 = 0x1000 ;
1453+
1454+ /// The reason that a HTLC was failed by the local node. These errors represent direct,
1455+ /// human-readable mappings of BOLT04 error codes.
1456+ #[ derive( Copy , Clone , Debug , Hash , PartialEq , Eq ) ]
1457+ pub enum LocalHTLCFailureReason {
1458+ /// There has been a temporary processing failure on the node which may resolve on retry.
1459+ TemporaryNodeFailure ,
1460+ /// These has been a permanent processing failure on the node which will not resolve on retry.
1461+ PermanentNodeFailure ,
1462+ /// The HTLC does not implement a feature that is required by our node.
1463+ ///
1464+ /// The sender may have outdated gossip, or a bug in its implementation.
1465+ RequiredNodeFeature ,
1466+ /// The onion version specified by the HTLC packet is unknown to our node.
1467+ InvalidOnionVersion ,
1468+ /// The integrity of the HTLC packet cannot be verified because it has an invalid HMAC.
1469+ InvalidOnionHMAC ,
1470+ /// The onion packet has an invalid ephemeral key, so the HTLC cannot be processed.
1471+ InvalidOnionKey ,
1472+ /// A temporary forwarding error has occurred which may resolve on retry.
1473+ TemporaryChannelFailure ,
1474+ /// A permanent forwarding error has occurred which will not resolve on retry.
1475+ PermanentChannelFailure ,
1476+ /// The HTLC does not implement a feature that is required by our channel for processing.
1477+ RequiredChannelFeature ,
1478+ /// The HTLC's target outgoing channel that is not known to our node.
1479+ UnknownNextPeer ,
1480+ /// The HTLC amount is below our advertised htlc_minimum_msat.
1481+ ///
1482+ /// The sender may have outdated gossip, or a bug in its implementation.
1483+ AmountBelowMinimum ,
1484+ /// The HTLC does not pay sufficient fees.
1485+ ///
1486+ /// The sender may have outdated gossip, or a bug in its implementation.
1487+ FeeInsufficient ,
1488+ /// The HTLC does not meet the cltv_expiry_delta advertised by our node, set by
1489+ /// [`ChannelConfig::cltv_expiry_delta`].
1490+ ///
1491+ /// The sender may have outdated gossip, or a bug in its implementation.
1492+ ///
1493+ /// [`ChannelConfig::cltv_expiry_delta`]: crate::util::config::ChannelConfig::cltv_expiry_delta
1494+ IncorrectCLTVExpiry ,
1495+ /// The HTLC expires too close to the current block height to be safely processed.
1496+ CLTVExpiryTooSoon ,
1497+ /// A payment was made to our node that either had incorrect payment information, or was
1498+ /// unknown to us.
1499+ IncorrectPaymentDetails ,
1500+ /// The HTLC's expiry is less than the expiry height specified by the sender.
1501+ ///
1502+ /// The forwarding node has either tampered with this value, or the sending node has an
1503+ /// old best block height.
1504+ FinalIncorrectCLTVExpiry ,
1505+ /// The HTLC's amount is less than the amount specified by the sender.
1506+ ///
1507+ /// The forwarding node has tampered with this value, or has a bug in its implementation.
1508+ FinalIncorrectHTLCAmount ,
1509+ /// The channel has been marked as disabled because the channel peer is offline.
1510+ ChannelDisabled ,
1511+ /// The HTLC expires too far in the future, so it is rejected to avoid the worst-case outcome
1512+ /// of funds being held for extended periods of time.
1513+ ///
1514+ /// Limit set by ['crate::ln::channelmanager::CLTV_FAR_FAR_AWAY`].
1515+ CLTVExpiryTooFar ,
1516+ /// The HTLC payload contained in the onion packet could not be understood by our node.
1517+ InvalidOnionPayload ,
1518+ /// The total amount for a multi-part payment did not arrive in time, so the HTLCs partially
1519+ /// paying the amount were canceled.
1520+ MPPTimeout ,
1521+ /// Our node was selected as part of a blinded path, but the packet we received was not
1522+ /// properly constructed, or had incorrect values for the blinded path.
1523+ ///
1524+ /// This may happen if the forwarding node tamperd with the HTLC or the sender or recipient
1525+ /// implementations have a bug.
1526+ InvalidOnionBlinding ,
1527+ /// UnknownFailureCode represents BOLT04 failure codes that we are not familiar with. We will
1528+ /// encounter this if:
1529+ /// - A peer sends us a new failure code that LDK has not yet been upgraded to understand.
1530+ /// - We read a deprecated failure code from disk that LDK no longer uses.
1531+ ///
1532+ /// See <https://github.com/lightning/bolts/blob/master/04-onion-routing.md#returning-errors>
1533+ /// for latest defined error codes.
1534+ UnknownFailureCode {
1535+ /// The bolt 04 failure code.
1536+ code : u16 ,
1537+ } ,
1538+ }
1539+
1540+ impl LocalHTLCFailureReason {
1541+ pub ( super ) fn failure_code ( & self ) -> u16 {
1542+ match self {
1543+ Self :: TemporaryNodeFailure => NODE | 2 ,
1544+ Self :: PermanentNodeFailure => PERM | NODE | 2 ,
1545+ Self :: RequiredNodeFeature => PERM | NODE | 3 ,
1546+ Self :: InvalidOnionVersion => BADONION | PERM | 4 ,
1547+ Self :: InvalidOnionHMAC => BADONION | PERM | 5 ,
1548+ Self :: InvalidOnionKey => BADONION | PERM | 6 ,
1549+ Self :: TemporaryChannelFailure => UPDATE | 7 ,
1550+ Self :: PermanentChannelFailure => PERM | 8 ,
1551+ Self :: RequiredChannelFeature => PERM | 9 ,
1552+ Self :: UnknownNextPeer => PERM | 10 ,
1553+ Self :: AmountBelowMinimum => UPDATE | 11 ,
1554+ Self :: FeeInsufficient => UPDATE | 12 ,
1555+ Self :: IncorrectCLTVExpiry => UPDATE | 13 ,
1556+ Self :: CLTVExpiryTooSoon => UPDATE | 14 ,
1557+ Self :: IncorrectPaymentDetails => PERM | 15 ,
1558+ Self :: FinalIncorrectCLTVExpiry => 18 ,
1559+ Self :: FinalIncorrectHTLCAmount => 19 ,
1560+ Self :: ChannelDisabled => UPDATE | 20 ,
1561+ Self :: CLTVExpiryTooFar => 21 ,
1562+ Self :: InvalidOnionPayload => PERM | 22 ,
1563+ Self :: MPPTimeout => 23 ,
1564+ Self :: InvalidOnionBlinding => BADONION | PERM | 24 ,
1565+ Self :: UnknownFailureCode { code } => * code,
1566+ }
1567+ }
1568+
1569+ pub ( super ) fn is_temporary ( & self ) -> bool {
1570+ self . failure_code ( ) & UPDATE == UPDATE
1571+ }
1572+
1573+ #[ cfg( test) ]
1574+ pub ( super ) fn is_permanent ( & self ) -> bool {
1575+ self . failure_code ( ) & PERM == PERM
1576+ }
1577+ }
1578+
1579+ impl From < u16 > for LocalHTLCFailureReason {
1580+ fn from ( value : u16 ) -> Self {
1581+ if value == ( NODE | 2 ) {
1582+ LocalHTLCFailureReason :: TemporaryNodeFailure
1583+ } else if value == ( PERM | NODE | 2 ) {
1584+ LocalHTLCFailureReason :: PermanentNodeFailure
1585+ } else if value == ( PERM | NODE | 3 ) {
1586+ LocalHTLCFailureReason :: RequiredNodeFeature
1587+ } else if value == ( BADONION | PERM | 4 ) {
1588+ LocalHTLCFailureReason :: InvalidOnionVersion
1589+ } else if value == ( BADONION | PERM | 5 ) {
1590+ LocalHTLCFailureReason :: InvalidOnionHMAC
1591+ } else if value == ( BADONION | PERM | 6 ) {
1592+ LocalHTLCFailureReason :: InvalidOnionKey
1593+ } else if value == ( UPDATE | 7 ) {
1594+ LocalHTLCFailureReason :: TemporaryChannelFailure
1595+ } else if value == ( PERM | 8 ) {
1596+ LocalHTLCFailureReason :: PermanentChannelFailure
1597+ } else if value == ( PERM | 9 ) {
1598+ LocalHTLCFailureReason :: RequiredChannelFeature
1599+ } else if value == ( PERM | 10 ) {
1600+ LocalHTLCFailureReason :: UnknownNextPeer
1601+ } else if value == ( UPDATE | 11 ) {
1602+ LocalHTLCFailureReason :: AmountBelowMinimum
1603+ } else if value == ( UPDATE | 12 ) {
1604+ LocalHTLCFailureReason :: FeeInsufficient
1605+ } else if value == ( UPDATE | 13 ) {
1606+ LocalHTLCFailureReason :: IncorrectCLTVExpiry
1607+ } else if value == ( UPDATE | 14 ) {
1608+ LocalHTLCFailureReason :: CLTVExpiryTooSoon
1609+ } else if value == ( PERM | 15 ) {
1610+ LocalHTLCFailureReason :: IncorrectPaymentDetails
1611+ } else if value == 18 {
1612+ LocalHTLCFailureReason :: FinalIncorrectCLTVExpiry
1613+ } else if value == 19 {
1614+ LocalHTLCFailureReason :: FinalIncorrectHTLCAmount
1615+ } else if value == ( UPDATE | 20 ) {
1616+ LocalHTLCFailureReason :: ChannelDisabled
1617+ } else if value == 21 {
1618+ LocalHTLCFailureReason :: CLTVExpiryTooFar
1619+ } else if value == ( PERM | 22 ) {
1620+ LocalHTLCFailureReason :: InvalidOnionPayload
1621+ } else if value == 23 {
1622+ LocalHTLCFailureReason :: MPPTimeout
1623+ } else if value == ( BADONION | PERM | 24 ) {
1624+ LocalHTLCFailureReason :: InvalidOnionBlinding
1625+ } else {
1626+ LocalHTLCFailureReason :: UnknownFailureCode { code : value }
1627+ }
1628+ }
1629+ }
1630+
14541631#[ derive( Clone ) ] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
14551632#[ cfg_attr( test, derive( PartialEq ) ) ]
14561633pub ( super ) struct HTLCFailReason ( HTLCFailReasonRepr ) ;
0 commit comments