@@ -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