@@ -1627,6 +1627,34 @@ impl From<u16> for LocalHTLCFailureReason {
16271627	} 
16281628} 
16291629
1630+ impl_writeable_tlv_based_enum ! ( LocalHTLCFailureReason , 
1631+ 	( 1 ,  TemporaryNodeFailure )  => { } , 
1632+ 	( 3 ,  PermanentNodeFailure )  => { } , 
1633+ 	( 5 ,  RequiredNodeFeature )  => { } , 
1634+ 	( 7 ,  InvalidOnionVersion )  => { } , 
1635+ 	( 9 ,  InvalidOnionHMAC )  => { } , 
1636+ 	( 11 ,  InvalidOnionKey )  => { } , 
1637+ 	( 13 ,  TemporaryChannelFailure )  => { } , 
1638+ 	( 15 ,  PermanentChannelFailure )  => { } , 
1639+ 	( 17 ,  RequiredChannelFeature )  => { } , 
1640+ 	( 19 ,  UnknownNextPeer )  => { } , 
1641+ 	( 21 ,  AmountBelowMinimum )  => { } , 
1642+ 	( 23 ,  FeeInsufficient )  => { } , 
1643+ 	( 25 ,  IncorrectCLTVExpiry )  => { } , 
1644+ 	( 27 ,  CLTVExpiryTooSoon )  => { } , 
1645+ 	( 29 ,  IncorrectPaymentDetails )  => { } , 
1646+ 	( 31 ,  FinalIncorrectCLTVExpiry )  => { } , 
1647+ 	( 33 ,  FinalIncorrectHTLCAmount )  => { } , 
1648+ 	( 35 ,  ChannelDisabled )  => { } , 
1649+ 	( 37 ,  CLTVExpiryTooFar )  => { } , 
1650+ 	( 39 ,  InvalidOnionPayload )  => { } , 
1651+ 	( 41 ,  MPPTimeout )  => { } , 
1652+ 	( 43 ,  InvalidOnionBlinding )  => { } , 
1653+ 	( 45 ,  UnknownFailureCode )  => { 
1654+ 		( 0 ,  code,  required) , 
1655+ 	} , 
1656+ ) ; 
1657+ 
16301658#[ derive( Clone ) ]   // See Channel::revoke_and_ack for why, tl;dr: Rust bug 
16311659#[ cfg_attr( test,  derive( PartialEq ) ) ]  
16321660pub ( super )  struct  HTLCFailReason ( HTLCFailReasonRepr ) ; 
@@ -1635,7 +1663,7 @@ pub(super) struct HTLCFailReason(HTLCFailReasonRepr);
16351663#[ cfg_attr( test,  derive( PartialEq ) ) ]  
16361664enum  HTLCFailReasonRepr  { 
16371665	LightningError  {  err :  msgs:: OnionErrorPacket ,  hold_time :  Option < u32 >  } , 
1638- 	Reason  {  failure_code :   u16 ,   data :  Vec < u8 >  } , 
1666+ 	Reason  {  data :  Vec < u8 > ,   failure_reason :   LocalHTLCFailureReason  } , 
16391667} 
16401668
16411669impl  HTLCFailReason  { 
@@ -1652,8 +1680,13 @@ impl HTLCFailReason {
16521680impl  core:: fmt:: Debug  for  HTLCFailReason  { 
16531681	fn  fmt ( & self ,  f :  & mut  core:: fmt:: Formatter )  -> Result < ( ) ,  core:: fmt:: Error >  { 
16541682		match  self . 0  { 
1655- 			HTLCFailReasonRepr :: Reason  {  ref  failure_code,  .. }  => { 
1656- 				write ! ( f,  "HTLC error code {}" ,  failure_code) 
1683+ 			HTLCFailReasonRepr :: Reason  {  ref  failure_reason,  .. }  => { 
1684+ 				write ! ( 
1685+ 					f, 
1686+ 					"HTLC failure {:?} error code {}" , 
1687+ 					failure_reason, 
1688+ 					failure_reason. failure_code( ) 
1689+ 				) 
16571690			} , 
16581691			HTLCFailReasonRepr :: LightningError  {  .. }  => { 
16591692				write ! ( f,  "pre-built LightningError" ) 
@@ -1693,7 +1726,14 @@ impl_writeable_tlv_based_enum!(HTLCFailReasonRepr,
16931726		( _unused,  err,  ( static_value,  msgs:: OnionErrorPacket  {  data:  data. ok_or( DecodeError :: InvalidValue ) ?,  attribution_data } ) ) , 
16941727	} , 
16951728	( 1 ,  Reason )  => { 
1696- 		( 0 ,  failure_code,  required) , 
1729+ 		( 0 ,  _failure_code,  ( legacy,  u16 , 
1730+ 			|r:  & HTLCFailReasonRepr | match  r { 
1731+ 				HTLCFailReasonRepr :: LightningError {  .. }  => None , 
1732+ 				HTLCFailReasonRepr :: Reason {  failure_reason,  .. }  => Some ( failure_reason. failure_code( ) ) 
1733+ 			} ) ) , 
1734+ 		// failure_code was required, and is replaced by reason in 0.2 so any time we do not have a 
1735+ 		// reason available failure_code will be Some and can be expressed as a reason. 
1736+ 		( 1 ,  failure_reason,  ( default_value,  LocalHTLCFailureReason :: from( _failure_code. ok_or( DecodeError :: InvalidValue ) ?) ) ) , 
16971737		( 2 ,  data,  required_vec) , 
16981738	} , 
16991739) ; 
@@ -1749,7 +1789,7 @@ impl HTLCFailReason {
17491789			} , 
17501790		} 
17511791
1752- 		Self ( HTLCFailReasonRepr :: Reason  {  failure_code :  failure_reason . failure_code ( ) ,  data  } ) 
1792+ 		Self ( HTLCFailReasonRepr :: Reason  {  data ,  failure_reason  } ) 
17531793	} 
17541794
17551795	pub ( super )  fn  from_failure_code ( failure_reason :  LocalHTLCFailureReason )  -> Self  { 
@@ -1775,15 +1815,15 @@ impl HTLCFailReason {
17751815		& self ,  incoming_packet_shared_secret :  & [ u8 ;  32 ] ,  secondary_shared_secret :  & Option < [ u8 ;  32 ] > , 
17761816	)  -> msgs:: OnionErrorPacket  { 
17771817		match  self . 0  { 
1778- 			HTLCFailReasonRepr :: Reason  {  ref  failure_code ,  ref  data  }  => { 
1818+ 			HTLCFailReasonRepr :: Reason  {  ref  data ,  ref  failure_reason  }  => { 
17791819				// Final hop always reports zero hold time. 
17801820				let  hold_time:  u32  = 0 ; 
17811821
17821822				if  let  Some ( secondary_shared_secret)  = secondary_shared_secret { 
17831823					// Phantom hop always reports zero hold time too. 
17841824					let  mut  packet = build_failure_packet ( 
17851825						secondary_shared_secret, 
1786- 						u16 :: into ( * failure_code ) , 
1826+ 						* failure_reason , 
17871827						& data[ ..] , 
17881828						hold_time, 
17891829					) ; 
@@ -1795,7 +1835,7 @@ impl HTLCFailReason {
17951835				}  else  { 
17961836					build_failure_packet ( 
17971837						incoming_packet_shared_secret, 
1798- 						u16 :: into ( * failure_code ) , 
1838+ 						* failure_reason , 
17991839						& data[ ..] , 
18001840						hold_time, 
18011841					) 
@@ -1824,7 +1864,7 @@ impl HTLCFailReason {
18241864				process_onion_failure ( secp_ctx,  logger,  & htlc_source,  err. clone ( ) ) 
18251865			} , 
18261866			#[ allow( unused) ]  
1827- 			HTLCFailReasonRepr :: Reason  {  ref  failure_code ,  ref  data ,  ..  }  => { 
1867+ 			HTLCFailReasonRepr :: Reason  {  ref  data ,  ref  failure_reason  }  => { 
18281868				// we get a fail_malformed_htlc from the first hop 
18291869				// TODO: We'd like to generate a NetworkUpdate for temporary 
18301870				// failures here, but that would be insufficient as find_route 
@@ -1838,7 +1878,7 @@ impl HTLCFailReason {
18381878						failed_within_blinded_path :  false , 
18391879						hold_times :  Vec :: new ( ) , 
18401880						#[ cfg( any( test,  feature = "_test_utils" ) ) ]  
1841- 						onion_error_code :  Some ( * failure_code) , 
1881+ 						onion_error_code :  Some ( failure_reason . failure_code ( ) ) , 
18421882						#[ cfg( any( test,  feature = "_test_utils" ) ) ]  
18431883						onion_error_data :  Some ( data. clone ( ) ) , 
18441884					} 
0 commit comments