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