@@ -22,7 +22,9 @@ use crate::types::features::{ChannelFeatures, NodeFeatures};
22
22
use crate :: types:: payment:: { PaymentHash , PaymentPreimage } ;
23
23
use crate :: util:: errors:: { self , APIError } ;
24
24
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
+ } ;
26
28
27
29
use bitcoin:: hashes:: cmp:: fixed_time_eq;
28
30
use bitcoin:: hashes:: hmac:: { Hmac , HmacEngine } ;
@@ -1608,6 +1610,49 @@ impl Into<LocalHTLCFailureReason> for u16 {
1608
1610
}
1609
1611
}
1610
1612
1613
+ impl_writeable_tlv_based_enum ! ( LocalHTLCFailureReason ,
1614
+ ( 0 , TemporaryNodeFailure ) => { } ,
1615
+ ( 2 , PermanentNodeFailure ) => { } ,
1616
+ ( 4 , RequiredNodeFeature ) => { } ,
1617
+ ( 6 , InvalidOnionVersion ) => { } ,
1618
+ ( 8 , InvalidOnionHMAC ) => { } ,
1619
+ ( 10 , InvalidOnionKey ) => { } ,
1620
+ ( 12 , TemporaryChannelFailure ) => { } ,
1621
+ ( 14 , PermanentChannelFailure ) => { } ,
1622
+ ( 16 , RequiredChannelFeature ) => { } ,
1623
+ ( 18 , UnknownNextPeer ) => { } ,
1624
+ ( 20 , AmountBelowMinimum ) => { } ,
1625
+ ( 22 , FeeInsufficient ) => { } ,
1626
+ ( 24 , IncorrectCLTVExpiry ) => { } ,
1627
+ ( 26 , CLTVExpiryTooSoon ) => { } ,
1628
+ ( 28 , IncorrectPaymentDetails ) => { } ,
1629
+ ( 30 , FinalIncorrectCLTVExpiry ) => { } ,
1630
+ ( 32 , FinalIncorrectHTLCAmount ) => { } ,
1631
+ ( 34 , ChannelDisabled ) => { } ,
1632
+ ( 36 , CLTVExpiryTooFar ) => { } ,
1633
+ ( 38 , InvalidOnionPayload ) => { } ,
1634
+ ( 40 , MPPTimeout ) => { } ,
1635
+ ( 42 , InvalidOnionBlinding ) => { } ,
1636
+ ( 44 , InvalidTrampolineForward ) => { } ,
1637
+ ( 46 , PaymentClaimBuffer ) => { } ,
1638
+ ( 48 , DustLimitHolder ) => { } ,
1639
+ ( 50 , DustLimitCounterparty ) => { } ,
1640
+ ( 52 , FeeSpikeBuffer ) => { } ,
1641
+ ( 54 , DroppedPending ) => { } ,
1642
+ ( 56 , PrivateChannelForward ) => { } ,
1643
+ ( 58 , RealSCIDForward ) => { } ,
1644
+ ( 60 , ChannelNotReady ) => { } ,
1645
+ ( 62 , InvalidKeysendPreimage ) => { } ,
1646
+ ( 64 , InvalidTrampolinePayload ) => { } ,
1647
+ ( 66 , PaymentSecretRequired ) => { } ,
1648
+ ( 68 , ForwardExpiryBuffer ) => { } ,
1649
+ ( 70 , OutgoingCLTVTooSoon ) => { } ,
1650
+ ( 72 , ChannelClosed ) => { } ,
1651
+ ( 74 , UnknownFailureCode ) => {
1652
+ ( 0 , code, required) ,
1653
+ }
1654
+ ) ;
1655
+
1611
1656
#[ derive( Clone ) ] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
1612
1657
#[ cfg_attr( test, derive( PartialEq ) ) ]
1613
1658
pub ( super ) struct HTLCFailReason ( HTLCFailReasonRepr ) ;
@@ -1616,14 +1661,14 @@ pub(super) struct HTLCFailReason(HTLCFailReasonRepr);
1616
1661
#[ cfg_attr( test, derive( PartialEq ) ) ]
1617
1662
enum HTLCFailReasonRepr {
1618
1663
LightningError { err : msgs:: OnionErrorPacket } ,
1619
- Reason { failure_code : u16 , data : Vec < u8 > } ,
1664
+ Reason { data : Vec < u8 > , reason : LocalHTLCFailureReason } ,
1620
1665
}
1621
1666
1622
1667
impl core:: fmt:: Debug for HTLCFailReason {
1623
1668
fn fmt ( & self , f : & mut core:: fmt:: Formatter ) -> Result < ( ) , core:: fmt:: Error > {
1624
1669
match self . 0 {
1625
- HTLCFailReasonRepr :: Reason { ref failure_code , .. } => {
1626
- write ! ( f, "HTLC error code {}" , failure_code)
1670
+ HTLCFailReasonRepr :: Reason { ref reason , .. } => {
1671
+ write ! ( f, "HTLC error code {}" , reason . failure_code( ) )
1627
1672
} ,
1628
1673
HTLCFailReasonRepr :: LightningError { .. } => {
1629
1674
write ! ( f, "pre-built LightningError" )
@@ -1655,8 +1700,19 @@ impl_writeable_tlv_based_enum!(HTLCFailReasonRepr,
1655
1700
( _unused, err, ( static_value, msgs:: OnionErrorPacket { data: data. ok_or( DecodeError :: InvalidValue ) ? } ) ) ,
1656
1701
} ,
1657
1702
( 1 , Reason ) => {
1658
- ( 0 , failure_code, required) ,
1703
+ ( 0 , _failure_code, ( legacy, u16 ,
1704
+ |r: & HTLCFailReasonRepr | Some ( r. clone( ) ) ) ) ,
1659
1705
( 2 , data, required_vec) ,
1706
+ // failure_code was required, and is replaced by reason so any time we do not have a
1707
+ // reason available failure_code will be Some so we can require reason.
1708
+ ( 4 , reason, ( default_value,
1709
+ if let Some ( code) = _failure_code {
1710
+ let failure_reason: LocalHTLCFailureReason = code. into( ) ;
1711
+ RequiredWrapper :: from( failure_reason)
1712
+ } else {
1713
+ reason
1714
+ }
1715
+ ) ) ,
1660
1716
} ,
1661
1717
) ;
1662
1718
@@ -1728,7 +1784,7 @@ impl HTLCFailReason {
1728
1784
} ,
1729
1785
}
1730
1786
1731
- Self ( HTLCFailReasonRepr :: Reason { failure_code : failure_reason. failure_code ( ) , data } )
1787
+ Self ( HTLCFailReasonRepr :: Reason { data , reason : failure_reason } )
1732
1788
}
1733
1789
1734
1790
pub ( super ) fn from_failure_code ( failure_reason : LocalHTLCFailureReason ) -> Self {
@@ -1750,24 +1806,16 @@ impl HTLCFailReason {
1750
1806
& self , incoming_packet_shared_secret : & [ u8 ; 32 ] , secondary_shared_secret : & Option < [ u8 ; 32 ] > ,
1751
1807
) -> msgs:: OnionErrorPacket {
1752
1808
match self . 0 {
1753
- HTLCFailReasonRepr :: Reason { ref failure_code, ref data } => {
1754
- let failure_code = * failure_code;
1809
+ HTLCFailReasonRepr :: Reason { ref data, ref reason } => {
1755
1810
if let Some ( secondary_shared_secret) = secondary_shared_secret {
1756
- let mut packet = build_failure_packet (
1757
- secondary_shared_secret,
1758
- failure_code. into ( ) ,
1759
- & data[ ..] ,
1760
- ) ;
1811
+ let mut packet =
1812
+ build_failure_packet ( secondary_shared_secret, * reason, & data[ ..] ) ;
1761
1813
1762
1814
crypt_failure_packet ( incoming_packet_shared_secret, & mut packet) ;
1763
1815
1764
1816
packet
1765
1817
} else {
1766
- build_failure_packet (
1767
- incoming_packet_shared_secret,
1768
- failure_code. into ( ) ,
1769
- & data[ ..] ,
1770
- )
1818
+ build_failure_packet ( incoming_packet_shared_secret, * reason, & data[ ..] )
1771
1819
}
1772
1820
} ,
1773
1821
HTLCFailReasonRepr :: LightningError { ref err } => {
@@ -1791,7 +1839,7 @@ impl HTLCFailReason {
1791
1839
process_onion_failure ( secp_ctx, logger, & htlc_source, err. clone ( ) )
1792
1840
} ,
1793
1841
#[ allow( unused) ]
1794
- HTLCFailReasonRepr :: Reason { ref failure_code , ref data , .. } => {
1842
+ HTLCFailReasonRepr :: Reason { ref data , ref reason } => {
1795
1843
// we get a fail_malformed_htlc from the first hop
1796
1844
// TODO: We'd like to generate a NetworkUpdate for temporary
1797
1845
// failures here, but that would be insufficient as find_route
@@ -1804,7 +1852,7 @@ impl HTLCFailReason {
1804
1852
short_channel_id : Some ( path. hops [ 0 ] . short_channel_id ) ,
1805
1853
failed_within_blinded_path : false ,
1806
1854
#[ cfg( any( test, feature = "_test_utils" ) ) ]
1807
- onion_error_code : Some ( * failure_code) ,
1855
+ onion_error_code : Some ( reason . failure_code ( ) ) ,
1808
1856
#[ cfg( any( test, feature = "_test_utils" ) ) ]
1809
1857
onion_error_data : Some ( data. clone ( ) ) ,
1810
1858
}
0 commit comments