@@ -1712,6 +1712,49 @@ impl Into<LocalHTLCFailureReason> for u16 {
17121712 }
17131713}
17141714
1715+ impl_writeable_tlv_based_enum ! ( LocalHTLCFailureReason ,
1716+ ( 1 , TemporaryNodeFailure ) => { } ,
1717+ ( 3 , PermanentNodeFailure ) => { } ,
1718+ ( 5 , RequiredNodeFeature ) => { } ,
1719+ ( 7 , InvalidOnionVersion ) => { } ,
1720+ ( 9 , InvalidOnionHMAC ) => { } ,
1721+ ( 11 , InvalidOnionKey ) => { } ,
1722+ ( 13 , TemporaryChannelFailure ) => { } ,
1723+ ( 15 , PermanentChannelFailure ) => { } ,
1724+ ( 17 , RequiredChannelFeature ) => { } ,
1725+ ( 19 , UnknownNextPeer ) => { } ,
1726+ ( 21 , AmountBelowMinimum ) => { } ,
1727+ ( 23 , FeeInsufficient ) => { } ,
1728+ ( 25 , IncorrectCLTVExpiry ) => { } ,
1729+ ( 27 , CLTVExpiryTooSoon ) => { } ,
1730+ ( 29 , IncorrectPaymentDetails ) => { } ,
1731+ ( 31 , FinalIncorrectCLTVExpiry ) => { } ,
1732+ ( 33 , FinalIncorrectHTLCAmount ) => { } ,
1733+ ( 35 , ChannelDisabled ) => { } ,
1734+ ( 37 , CLTVExpiryTooFar ) => { } ,
1735+ ( 39 , InvalidOnionPayload ) => { } ,
1736+ ( 41 , MPPTimeout ) => { } ,
1737+ ( 43 , InvalidOnionBlinding ) => { } ,
1738+ ( 45 , InvalidTrampolineForward ) => { } ,
1739+ ( 47 , PaymentClaimBuffer ) => { } ,
1740+ ( 49 , DustLimitHolder ) => { } ,
1741+ ( 51 , DustLimitCounterparty ) => { } ,
1742+ ( 53 , FeeSpikeBuffer ) => { } ,
1743+ ( 55 , OnChainTimeout ) => { } ,
1744+ ( 57 , PrivateChannelForward ) => { } ,
1745+ ( 59 , RealSCIDForward ) => { } ,
1746+ ( 61 , ChannelNotReady ) => { } ,
1747+ ( 63 , InvalidKeysendPreimage ) => { } ,
1748+ ( 65 , InvalidTrampolinePayload ) => { } ,
1749+ ( 67 , PaymentSecretRequired ) => { } ,
1750+ ( 69 , ForwardExpiryBuffer ) => { } ,
1751+ ( 71 , OutgoingCLTVTooSoon ) => { } ,
1752+ ( 73 , ChannelClosed ) => { } ,
1753+ ( 75 , UnknownFailureCode ) => {
1754+ ( 0 , code, required) ,
1755+ }
1756+ ) ;
1757+
17151758#[ derive( Clone ) ] // See Channel::revoke_and_ack for why, tl;dr: Rust bug
17161759#[ cfg_attr( test, derive( PartialEq ) ) ]
17171760pub ( super ) struct HTLCFailReason ( HTLCFailReasonRepr ) ;
@@ -1720,7 +1763,7 @@ pub(super) struct HTLCFailReason(HTLCFailReasonRepr);
17201763#[ cfg_attr( test, derive( PartialEq ) ) ]
17211764enum HTLCFailReasonRepr {
17221765 LightningError { err : msgs:: OnionErrorPacket , hold_time : Option < u32 > } ,
1723- Reason { failure_code : u16 , data : Vec < u8 > } ,
1766+ Reason { data : Vec < u8 > , reason : LocalHTLCFailureReason } ,
17241767}
17251768
17261769impl HTLCFailReason {
@@ -1737,8 +1780,8 @@ impl HTLCFailReason {
17371780impl core:: fmt:: Debug for HTLCFailReason {
17381781 fn fmt ( & self , f : & mut core:: fmt:: Formatter ) -> Result < ( ) , core:: fmt:: Error > {
17391782 match self . 0 {
1740- HTLCFailReasonRepr :: Reason { ref failure_code , .. } => {
1741- write ! ( f, "HTLC error code {}" , failure_code)
1783+ HTLCFailReasonRepr :: Reason { ref reason , .. } => {
1784+ write ! ( f, "HTLC error code {}" , reason . failure_code( ) )
17421785 } ,
17431786 HTLCFailReasonRepr :: LightningError { .. } => {
17441787 write ! ( f, "pre-built LightningError" )
@@ -1778,8 +1821,15 @@ impl_writeable_tlv_based_enum!(HTLCFailReasonRepr,
17781821 ( _unused, err, ( static_value, msgs:: OnionErrorPacket { data: data. ok_or( DecodeError :: InvalidValue ) ?, attribution_data } ) ) ,
17791822 } ,
17801823 ( 1 , Reason ) => {
1781- ( 0 , failure_code, required) ,
1824+ ( 0 , _failure_code, ( legacy, u16 ,
1825+ |r: & HTLCFailReasonRepr | match r {
1826+ HTLCFailReasonRepr :: LightningError { .. } => None ,
1827+ HTLCFailReasonRepr :: Reason { reason, .. } => Some ( reason. failure_code( ) )
1828+ } ) ) ,
17821829 ( 2 , data, required_vec) ,
1830+ // failure_code was required, and is replaced by reason in 0.2 so any time we do not have a
1831+ // reason available failure_code will be Some and can be expressed as a reason.
1832+ ( 4 , reason, ( default_value, <u16 as Into <LocalHTLCFailureReason >>:: into( _failure_code. ok_or( DecodeError :: InvalidValue ) ?) ) ) ,
17831833 } ,
17841834) ;
17851835
@@ -1851,7 +1901,7 @@ impl HTLCFailReason {
18511901 } ,
18521902 }
18531903
1854- Self ( HTLCFailReasonRepr :: Reason { failure_code : failure_reason. failure_code ( ) , data } )
1904+ Self ( HTLCFailReasonRepr :: Reason { data , reason : failure_reason } )
18551905 }
18561906
18571907 pub ( super ) fn from_failure_code ( failure_reason : LocalHTLCFailureReason ) -> Self {
@@ -1877,15 +1927,15 @@ impl HTLCFailReason {
18771927 & self , incoming_packet_shared_secret : & [ u8 ; 32 ] , secondary_shared_secret : & Option < [ u8 ; 32 ] > ,
18781928 ) -> msgs:: OnionErrorPacket {
18791929 match self . 0 {
1880- HTLCFailReasonRepr :: Reason { ref failure_code , ref data } => {
1930+ HTLCFailReasonRepr :: Reason { ref reason , ref data } => {
18811931 // Final hop always reports zero hold time.
18821932 let hold_time: u32 = 0 ;
18831933
18841934 if let Some ( secondary_shared_secret) = secondary_shared_secret {
18851935 // Phantom hop always reports zero hold time too.
18861936 let mut packet = build_failure_packet (
18871937 secondary_shared_secret,
1888- u16 :: into ( * failure_code ) ,
1938+ * reason ,
18891939 & data[ ..] ,
18901940 hold_time,
18911941 ) ;
@@ -1897,7 +1947,7 @@ impl HTLCFailReason {
18971947 } else {
18981948 build_failure_packet (
18991949 incoming_packet_shared_secret,
1900- u16 :: into ( * failure_code ) ,
1950+ * reason ,
19011951 & data[ ..] ,
19021952 hold_time,
19031953 )
@@ -1926,7 +1976,7 @@ impl HTLCFailReason {
19261976 process_onion_failure ( secp_ctx, logger, & htlc_source, err. clone ( ) )
19271977 } ,
19281978 #[ allow( unused) ]
1929- HTLCFailReasonRepr :: Reason { ref failure_code , ref data , .. } => {
1979+ HTLCFailReasonRepr :: Reason { ref data , ref reason } => {
19301980 // we get a fail_malformed_htlc from the first hop
19311981 // TODO: We'd like to generate a NetworkUpdate for temporary
19321982 // failures here, but that would be insufficient as find_route
@@ -1940,7 +1990,7 @@ impl HTLCFailReason {
19401990 failed_within_blinded_path : false ,
19411991 hold_times : Vec :: new ( ) ,
19421992 #[ cfg( any( test, feature = "_test_utils" ) ) ]
1943- onion_error_code : Some ( * failure_code) ,
1993+ onion_error_code : Some ( reason . failure_code ( ) ) ,
19441994 #[ cfg( any( test, feature = "_test_utils" ) ) ]
19451995 onion_error_data : Some ( data. clone ( ) ) ,
19461996 }
0 commit comments