@@ -49,6 +49,7 @@ use crate::ln::features::InvoiceFeatures;
4949use  crate :: routing:: router:: { InFlightHtlcs ,  PaymentParameters ,  Route ,  RouteHop ,  RoutePath ,  RouteParameters } ; 
5050use  crate :: ln:: msgs; 
5151use  crate :: ln:: onion_utils; 
52+ use  crate :: ln:: onion_utils:: HTLCFailReason ; 
5253use  crate :: ln:: msgs:: { ChannelMessageHandler ,  DecodeError ,  LightningError ,  MAX_VALUE_MSAT } ; 
5354use  crate :: ln:: wire:: Encode ; 
5455use  crate :: chain:: keysinterface:: { Sign ,  KeysInterface ,  KeysManager ,  Recipient } ; 
@@ -276,27 +277,6 @@ impl HTLCSource {
276277	} 
277278} 
278279
279- #[ derive( Clone ) ]   // See Channel::revoke_and_ack for why, tl;dr: Rust bug 
280- pub ( super )  enum  HTLCFailReason  { 
281- 	LightningError  { 
282- 		err :  msgs:: OnionErrorPacket , 
283- 	} , 
284- 	Reason  { 
285- 		failure_code :  u16 , 
286- 		data :  Vec < u8 > , 
287- 	} 
288- } 
289- 
290- impl  HTLCFailReason  { 
291- 	pub ( super )  fn  reason ( failure_code :  u16 ,  data :  Vec < u8 > )  -> Self  { 
292- 		Self :: Reason  {  failure_code,  data } 
293- 	} 
294- 
295- 	pub ( super )  fn  from_failure_code ( failure_code :  u16 )  -> Self  { 
296- 		Self :: Reason  {  failure_code,  data :  Vec :: new ( )  } 
297- 	} 
298- } 
299- 
300280struct  ReceiveError  { 
301281	err_code :  u16 , 
302282	err_data :  Vec < u8 > , 
@@ -2062,10 +2042,13 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
20622042		// Also, ensure that, in the case of an unknown preimage for the received payment hash, our 
20632043		// payment logic has enough time to fail the HTLC backward before our onchain logic triggers a 
20642044		// channel closure (see HTLC_FAIL_BACK_BUFFER rationale). 
2065- 		if  ( hop_data. outgoing_cltv_value  as  u64 )  <= self . best_block . read ( ) . unwrap ( ) . height ( )  as  u64  + HTLC_FAIL_BACK_BUFFER  as  u64  + 1 	{ 
2045+ 		let  current_height:  u32  = self . best_block . read ( ) . unwrap ( ) . height ( ) ; 
2046+ 		if  ( hop_data. outgoing_cltv_value  as  u64 )  <= current_height as  u64  + HTLC_FAIL_BACK_BUFFER  as  u64  + 1  { 
2047+ 			let  mut  err_data = Vec :: with_capacity ( 12 ) ; 
2048+ 			err_data. extend_from_slice ( & amt_msat. to_be_bytes ( ) ) ; 
2049+ 			err_data. extend_from_slice ( & current_height. to_be_bytes ( ) ) ; 
20662050			return  Err ( ReceiveError  { 
2067- 				err_code :  17 , 
2068- 				err_data :  Vec :: new ( ) , 
2051+ 				err_code :  0x4000  | 15 ,  err_data, 
20692052				msg :  "The final CLTV expiry is too soon to handle" , 
20702053			} ) ; 
20712054		} 
@@ -2173,7 +2156,8 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
21732156					return  PendingHTLCStatus :: Fail ( HTLCFailureMsg :: Relay ( msgs:: UpdateFailHTLC  { 
21742157						channel_id:  msg. channel_id, 
21752158						htlc_id:  msg. htlc_id, 
2176- 						reason:  onion_utils:: build_first_hop_failure_packet( & shared_secret,  $err_code,  $data) , 
2159+ 						reason:  HTLCFailReason :: reason( $err_code,  $data. to_vec( ) ) 
2160+ 							. get_encrypted_failure_packet( & shared_secret,  & None ) , 
21772161					} ) ) ; 
21782162				} 
21792163			} 
@@ -2238,7 +2222,7 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
22382222			// with a short_channel_id of 0. This is important as various things later assume 
22392223			// short_channel_id is non-0 in any ::Forward. 
22402224			if  let  & PendingHTLCRouting :: Forward  {  ref  short_channel_id,  .. }  = routing { 
2241- 				if  let  Some ( ( err,  code,  chan_update) )  = loop  { 
2225+ 				if  let  Some ( ( err,  mut   code,  chan_update) )  = loop  { 
22422226					let  id_option = self . short_to_chan_info . read ( ) . unwrap ( ) . get ( & short_channel_id) . cloned ( ) ; 
22432227					let  mut  channel_state = self . channel_state . lock ( ) . unwrap ( ) ; 
22442228					let  forwarding_id_opt = match  id_option { 
@@ -2295,10 +2279,13 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
22952279						} 
22962280						chan_update_opt
22972281					}  else  { 
2298- 						if  ( msg. cltv_expiry  as  u64 )  < ( * outgoing_cltv_value)  as  u64  + MIN_CLTV_EXPIRY_DELTA  as  u64  {  // incorrect_cltv_expiry 
2282+ 						if  ( msg. cltv_expiry  as  u64 )  < ( * outgoing_cltv_value)  as  u64  + MIN_CLTV_EXPIRY_DELTA  as  u64  { 
2283+ 							// We really should set `incorrect_cltv_expiry` here but as we're not 
2284+ 							// forwarding over a real channel we can't generate a channel_update 
2285+ 							// for it. Instead we just return a generic temporary_node_failure. 
22992286							break  Some ( ( 
23002287								"Forwarding node has tampered with the intended HTLC values or origin node has an obsolete cltv_expiry_delta" , 
2301- 								0x1000  | 13 ,  None , 
2288+ 								0x2000  | 2 ,  None , 
23022289							) ) ; 
23032290						} 
23042291						None 
@@ -2344,6 +2331,12 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
23442331						( chan_update. serialized_length ( )  as  u16  + 2 ) . write ( & mut  res) . expect ( "Writes cannot fail" ) ; 
23452332						msgs:: ChannelUpdate :: TYPE . write ( & mut  res) . expect ( "Writes cannot fail" ) ; 
23462333						chan_update. write ( & mut  res) . expect ( "Writes cannot fail" ) ; 
2334+ 					}  else  if  code &  0x1000  == 0x1000  { 
2335+ 						// If we're trying to return an error that requires a `channel_update` but 
2336+ 						// we're forwarding to a phantom or intercept "channel" (i.e. cannot 
2337+ 						// generate an update), just use the generic "temporary_node_failure" 
2338+ 						// instead. 
2339+ 						code = 0x2000  | 2 ; 
23472340					} 
23482341					return_err ! ( err,  code,  & res. 0 [ ..] ) ; 
23492342				} 
@@ -4048,114 +4041,57 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
40484041				}  else  {  None  } ; 
40494042				log_trace ! ( self . logger,  "Failing outbound payment HTLC with payment_hash {}" ,  log_bytes!( payment_hash. 0 ) ) ; 
40504043
4051- 				let  path_failure = match  & onion_error { 
4052- 					& HTLCFailReason :: LightningError  {  ref  err }  => { 
4044+ 				let  path_failure = { 
40534045#[ cfg( test) ]  
4054- 						 let  ( network_update,  short_channel_id,  payment_retryable,  onion_error_code,  onion_error_data)  = onion_utils :: process_onion_failure ( & self . secp_ctx ,  & self . logger ,  & source,  err . data . clone ( ) ) ; 
4046+ 					let  ( network_update,  short_channel_id,  payment_retryable,  onion_error_code,  onion_error_data)  = onion_error . decode_onion_failure ( & self . secp_ctx ,  & self . logger ,  & source) ; 
40554047#[ cfg( not( test) ) ]  
4056- 						let  ( network_update,  short_channel_id,  payment_retryable,  _,  _)  = onion_utils:: process_onion_failure ( & self . secp_ctx ,  & self . logger ,  & source,  err. data . clone ( ) ) ; 
4057- 
4058- 						if  self . payment_is_probe ( payment_hash,  & payment_id)  { 
4059- 							if  !payment_retryable { 
4060- 								events:: Event :: ProbeSuccessful  { 
4061- 									payment_id :  * payment_id, 
4062- 									payment_hash :  payment_hash. clone ( ) , 
4063- 									path :  path. clone ( ) , 
4064- 								} 
4065- 							}  else  { 
4066- 								events:: Event :: ProbeFailed  { 
4067- 									payment_id :  * payment_id, 
4068- 									payment_hash :  payment_hash. clone ( ) , 
4069- 									path :  path. clone ( ) , 
4070- 									short_channel_id, 
4071- 								} 
4072- 							} 
4073- 						}  else  { 
4074- 							// TODO: If we decided to blame ourselves (or one of our channels) in 
4075- 							// process_onion_failure we should close that channel as it implies our 
4076- 							// next-hop is needlessly blaming us! 
4077- 							if  let  Some ( scid)  = short_channel_id { 
4078- 								retry. as_mut ( ) . map ( |r| r. payment_params . previously_failed_channels . push ( scid) ) ; 
4079- 							} 
4080- 							events:: Event :: PaymentPathFailed  { 
4081- 								payment_id :  Some ( * payment_id) , 
4082- 								payment_hash :  payment_hash. clone ( ) , 
4083- 								payment_failed_permanently :  !payment_retryable, 
4084- 								network_update, 
4085- 								all_paths_failed, 
4086- 								path :  path. clone ( ) , 
4087- 								short_channel_id, 
4088- 								retry, 
4089- 								#[ cfg( test) ]  
4090- 								error_code :  onion_error_code, 
4091- 								#[ cfg( test) ]  
4092- 								error_data :  onion_error_data
4093- 							} 
4094- 						} 
4095- 					} , 
4096- 					& HTLCFailReason :: Reason  { 
4097- #[ cfg( test) ]  
4098- 							ref  failure_code, 
4099- #[ cfg( test) ]  
4100- 							ref  data, 
4101- 							.. }  => { 
4102- 						// we get a fail_malformed_htlc from the first hop 
4103- 						// TODO: We'd like to generate a NetworkUpdate for temporary 
4104- 						// failures here, but that would be insufficient as find_route 
4105- 						// generally ignores its view of our own channels as we provide them via 
4106- 						// ChannelDetails. 
4107- 						// TODO: For non-temporary failures, we really should be closing the 
4108- 						// channel here as we apparently can't relay through them anyway. 
4109- 						let  scid = path. first ( ) . unwrap ( ) . short_channel_id ; 
4110- 						retry. as_mut ( ) . map ( |r| r. payment_params . previously_failed_channels . push ( scid) ) ; 
4111- 
4112- 						if  self . payment_is_probe ( payment_hash,  & payment_id)  { 
4113- 							events:: Event :: ProbeFailed  { 
4048+ 					let  ( network_update,  short_channel_id,  payment_retryable,  _,  _)  = onion_error. decode_onion_failure ( & self . secp_ctx ,  & self . logger ,  & source) ; 
4049+ 
4050+ 					if  self . payment_is_probe ( payment_hash,  & payment_id)  { 
4051+ 						if  !payment_retryable { 
4052+ 							events:: Event :: ProbeSuccessful  { 
41144053								payment_id :  * payment_id, 
41154054								payment_hash :  payment_hash. clone ( ) , 
41164055								path :  path. clone ( ) , 
4117- 								short_channel_id :  Some ( scid) , 
41184056							} 
41194057						}  else  { 
4120- 							events:: Event :: PaymentPathFailed  { 
4121- 								payment_id :  Some ( * payment_id) , 
4058+ 							events:: Event :: ProbeFailed  { 
4059+ 								payment_id :  * payment_id, 
41224060								payment_hash :  payment_hash. clone ( ) , 
4123- 								payment_failed_permanently :  false , 
4124- 								network_update :  None , 
4125- 								all_paths_failed, 
41264061								path :  path. clone ( ) , 
4127- 								short_channel_id :  Some ( scid) , 
4128- 								retry, 
4129- #[ cfg( test) ]  
4130- 								error_code :  Some ( * failure_code) , 
4131- #[ cfg( test) ]  
4132- 								error_data :  Some ( data. clone ( ) ) , 
4062+ 								short_channel_id, 
41334063							} 
41344064						} 
4065+ 					}  else  { 
4066+ 						// TODO: If we decided to blame ourselves (or one of our channels) in 
4067+ 						// process_onion_failure we should close that channel as it implies our 
4068+ 						// next-hop is needlessly blaming us! 
4069+ 						if  let  Some ( scid)  = short_channel_id { 
4070+ 							retry. as_mut ( ) . map ( |r| r. payment_params . previously_failed_channels . push ( scid) ) ; 
4071+ 						} 
4072+ 						events:: Event :: PaymentPathFailed  { 
4073+ 							payment_id :  Some ( * payment_id) , 
4074+ 							payment_hash :  payment_hash. clone ( ) , 
4075+ 							payment_failed_permanently :  !payment_retryable, 
4076+ 							network_update, 
4077+ 							all_paths_failed, 
4078+ 							path :  path. clone ( ) , 
4079+ 							short_channel_id, 
4080+ 							retry, 
4081+ 							#[ cfg( test) ]  
4082+ 							error_code :  onion_error_code, 
4083+ 							#[ cfg( test) ]  
4084+ 							error_data :  onion_error_data
4085+ 						} 
41354086					} 
41364087				} ; 
41374088				let  mut  pending_events = self . pending_events . lock ( ) . unwrap ( ) ; 
41384089				pending_events. push ( path_failure) ; 
41394090				if  let  Some ( ev)  = full_failure_ev {  pending_events. push ( ev) ;  } 
41404091			} , 
41414092			HTLCSource :: PreviousHopData ( HTLCPreviousHopData  {  ref  short_channel_id,  ref  htlc_id,  ref  incoming_packet_shared_secret,  ref  phantom_shared_secret,  ref  outpoint } )  => { 
4142- 				let  err_packet = match  onion_error { 
4143- 					HTLCFailReason :: Reason  {  ref  failure_code,  ref  data }  => { 
4144- 						log_trace ! ( self . logger,  "Failing HTLC with payment_hash {} backwards from us with code {}" ,  log_bytes!( payment_hash. 0 ) ,  failure_code) ; 
4145- 						if  let  Some ( phantom_ss)  = phantom_shared_secret { 
4146- 							let  phantom_packet = onion_utils:: build_failure_packet ( phantom_ss,  * failure_code,  & data[ ..] ) . encode ( ) ; 
4147- 							let  encrypted_phantom_packet = onion_utils:: encrypt_failure_packet ( phantom_ss,  & phantom_packet) ; 
4148- 							onion_utils:: encrypt_failure_packet ( incoming_packet_shared_secret,  & encrypted_phantom_packet. data [ ..] ) 
4149- 						}  else  { 
4150- 							let  packet = onion_utils:: build_failure_packet ( incoming_packet_shared_secret,  * failure_code,  & data[ ..] ) . encode ( ) ; 
4151- 							onion_utils:: encrypt_failure_packet ( incoming_packet_shared_secret,  & packet) 
4152- 						} 
4153- 					} , 
4154- 					HTLCFailReason :: LightningError  {  err }  => { 
4155- 						log_trace ! ( self . logger,  "Failing HTLC with payment_hash {} backwards with pre-built LightningError" ,  log_bytes!( payment_hash. 0 ) ) ; 
4156- 						onion_utils:: encrypt_failure_packet ( incoming_packet_shared_secret,  & err. data ) 
4157- 					} 
4158- 				} ; 
4093+ 				log_trace ! ( self . logger,  "Failing HTLC with payment_hash {} backwards from us with {:?}" ,  log_bytes!( payment_hash. 0 ) ,  onion_error) ; 
4094+ 				let  err_packet = onion_error. get_encrypted_failure_packet ( incoming_packet_shared_secret,  phantom_shared_secret) ; 
41594095
41604096				let  mut  forward_event = None ; 
41614097				let  mut  forward_htlcs = self . forward_htlcs . lock ( ) . unwrap ( ) ; 
@@ -5082,10 +5018,10 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
50825018						PendingHTLCStatus :: Forward ( PendingHTLCInfo  {  ref  incoming_shared_secret,  .. } )  => { 
50835019							let  reason = if  ( error_code &  0x1000 )  != 0  { 
50845020								let  ( real_code,  error_data)  = self . get_htlc_inbound_temp_fail_err_and_data ( error_code,  chan) ; 
5085- 								onion_utils :: build_first_hop_failure_packet ( incoming_shared_secret ,   real_code,  & error_data) 
5021+ 								HTLCFailReason :: reason ( real_code,  error_data) 
50865022							}  else  { 
5087- 								onion_utils :: build_first_hop_failure_packet ( incoming_shared_secret ,   error_code,   & [ ] ) 
5088- 							} ; 
5023+ 								HTLCFailReason :: from_failure_code ( error_code) 
5024+ 							} . get_encrypted_failure_packet ( incoming_shared_secret ,   & None ) ; 
50895025							let  msg = msgs:: UpdateFailHTLC  { 
50905026								channel_id :  msg. channel_id , 
50915027								htlc_id :  msg. htlc_id , 
@@ -5129,7 +5065,7 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
51295065				if  chan. get ( ) . get_counterparty_node_id ( )  != * counterparty_node_id { 
51305066					return  Err ( MsgHandleErrInternal :: send_err_msg_no_close ( "Got a message for a channel from the wrong node!" . to_owned ( ) ,  msg. channel_id ) ) ; 
51315067				} 
5132- 				try_chan_entry ! ( self ,  chan. get_mut( ) . update_fail_htlc( & msg,  HTLCFailReason :: LightningError   {  err :  msg . reason . clone ( )   } ) ,  chan) ; 
5068+ 				try_chan_entry ! ( self ,  chan. get_mut( ) . update_fail_htlc( & msg,  HTLCFailReason :: from_msg ( msg ) ) ,  chan) ; 
51335069			} , 
51345070			hash_map:: Entry :: Vacant ( _)  => return  Err ( MsgHandleErrInternal :: send_err_msg_no_close ( "Failed to find corresponding channel" . to_owned ( ) ,  msg. channel_id ) ) 
51355071		} 
@@ -5148,7 +5084,7 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
51485084					let  chan_err:  ChannelError  = ChannelError :: Close ( "Got update_fail_malformed_htlc with BADONION not set" . to_owned ( ) ) ; 
51495085					try_chan_entry ! ( self ,  Err ( chan_err) ,  chan) ; 
51505086				} 
5151- 				try_chan_entry ! ( self ,  chan. get_mut( ) . update_fail_malformed_htlc( & msg,  HTLCFailReason :: from_failure_code ( msg. failure_code) ) ,  chan) ; 
5087+ 				try_chan_entry ! ( self ,  chan. get_mut( ) . update_fail_malformed_htlc( & msg,  HTLCFailReason :: reason ( msg. failure_code,  msg . sha256_of_onion . to_vec ( ) ) ) ,  chan) ; 
51525088				Ok ( ( ) ) 
51535089			} , 
51545090			hash_map:: Entry :: Vacant ( _)  => return  Err ( MsgHandleErrInternal :: send_err_msg_no_close ( "Failed to find corresponding channel" . to_owned ( ) ,  msg. channel_id ) ) 
@@ -7037,16 +6973,6 @@ impl Writeable for HTLCSource {
70376973	} 
70386974} 
70396975
7040- impl_writeable_tlv_based_enum ! ( HTLCFailReason , 
7041- 	( 0 ,  LightningError )  => { 
7042- 		( 0 ,  err,  required) , 
7043- 	} , 
7044- 	( 1 ,  Reason )  => { 
7045- 		( 0 ,  failure_code,  required) , 
7046- 		( 2 ,  data,  vec_type) , 
7047- 	} , 
7048- ; ) ; 
7049- 
70506976impl_writeable_tlv_based ! ( PendingAddHTLCInfo ,  { 
70516977	( 0 ,  forward_info,  required) , 
70526978	( 1 ,  prev_user_channel_id,  ( default_value,  0 ) ) , 
0 commit comments