@@ -49,6 +49,7 @@ use crate::ln::features::InvoiceFeatures;
49
49
use crate :: routing:: router:: { InFlightHtlcs , PaymentParameters , Route , RouteHop , RoutePath , RouteParameters } ;
50
50
use crate :: ln:: msgs;
51
51
use crate :: ln:: onion_utils;
52
+ use crate :: ln:: onion_utils:: HTLCFailReason ;
52
53
use crate :: ln:: msgs:: { ChannelMessageHandler , DecodeError , LightningError , MAX_VALUE_MSAT } ;
53
54
use crate :: ln:: wire:: Encode ;
54
55
use crate :: chain:: keysinterface:: { Sign , KeysInterface , KeysManager , Recipient } ;
@@ -276,27 +277,6 @@ impl HTLCSource {
276
277
}
277
278
}
278
279
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
-
300
280
struct ReceiveError {
301
281
err_code : u16 ,
302
282
err_data : Vec < u8 > ,
@@ -2062,10 +2042,13 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
2062
2042
// Also, ensure that, in the case of an unknown preimage for the received payment hash, our
2063
2043
// payment logic has enough time to fail the HTLC backward before our onchain logic triggers a
2064
2044
// 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 ( ) ) ;
2066
2050
return Err ( ReceiveError {
2067
- err_code : 17 ,
2068
- err_data : Vec :: new ( ) ,
2051
+ err_code : 0x4000 | 15 , err_data,
2069
2052
msg : "The final CLTV expiry is too soon to handle" ,
2070
2053
} ) ;
2071
2054
}
@@ -2173,7 +2156,8 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
2173
2156
return PendingHTLCStatus :: Fail ( HTLCFailureMsg :: Relay ( msgs:: UpdateFailHTLC {
2174
2157
channel_id: msg. channel_id,
2175
2158
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 ) ,
2177
2161
} ) ) ;
2178
2162
}
2179
2163
}
@@ -2238,7 +2222,7 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
2238
2222
// with a short_channel_id of 0. This is important as various things later assume
2239
2223
// short_channel_id is non-0 in any ::Forward.
2240
2224
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 {
2242
2226
let id_option = self . short_to_chan_info . read ( ) . unwrap ( ) . get ( & short_channel_id) . cloned ( ) ;
2243
2227
let mut channel_state = self . channel_state . lock ( ) . unwrap ( ) ;
2244
2228
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
2295
2279
}
2296
2280
chan_update_opt
2297
2281
} 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.
2299
2286
break Some ( (
2300
2287
"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 ,
2302
2289
) ) ;
2303
2290
}
2304
2291
None
@@ -2344,6 +2331,12 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
2344
2331
( chan_update. serialized_length ( ) as u16 + 2 ) . write ( & mut res) . expect ( "Writes cannot fail" ) ;
2345
2332
msgs:: ChannelUpdate :: TYPE . write ( & mut res) . expect ( "Writes cannot fail" ) ;
2346
2333
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 ;
2347
2340
}
2348
2341
return_err ! ( err, code, & res. 0 [ ..] ) ;
2349
2342
}
@@ -4048,114 +4041,57 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
4048
4041
} else { None } ;
4049
4042
log_trace ! ( self . logger, "Failing outbound payment HTLC with payment_hash {}" , log_bytes!( payment_hash. 0 ) ) ;
4050
4043
4051
- let path_failure = match & onion_error {
4052
- & HTLCFailReason :: LightningError { ref err } => {
4044
+ let path_failure = {
4053
4045
#[ 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) ;
4055
4047
#[ 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 {
4114
4053
payment_id : * payment_id,
4115
4054
payment_hash : payment_hash. clone ( ) ,
4116
4055
path : path. clone ( ) ,
4117
- short_channel_id : Some ( scid) ,
4118
4056
}
4119
4057
} else {
4120
- events:: Event :: PaymentPathFailed {
4121
- payment_id : Some ( * payment_id) ,
4058
+ events:: Event :: ProbeFailed {
4059
+ payment_id : * payment_id,
4122
4060
payment_hash : payment_hash. clone ( ) ,
4123
- payment_failed_permanently : false ,
4124
- network_update : None ,
4125
- all_paths_failed,
4126
4061
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,
4133
4063
}
4134
4064
}
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
+ }
4135
4086
}
4136
4087
} ;
4137
4088
let mut pending_events = self . pending_events . lock ( ) . unwrap ( ) ;
4138
4089
pending_events. push ( path_failure) ;
4139
4090
if let Some ( ev) = full_failure_ev { pending_events. push ( ev) ; }
4140
4091
} ,
4141
4092
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) ;
4159
4095
4160
4096
let mut forward_event = None ;
4161
4097
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
5082
5018
PendingHTLCStatus :: Forward ( PendingHTLCInfo { ref incoming_shared_secret, .. } ) => {
5083
5019
let reason = if ( error_code & 0x1000 ) != 0 {
5084
5020
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)
5086
5022
} 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 ) ;
5089
5025
let msg = msgs:: UpdateFailHTLC {
5090
5026
channel_id : msg. channel_id ,
5091
5027
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
5129
5065
if chan. get ( ) . get_counterparty_node_id ( ) != * counterparty_node_id {
5130
5066
return Err ( MsgHandleErrInternal :: send_err_msg_no_close ( "Got a message for a channel from the wrong node!" . to_owned ( ) , msg. channel_id ) ) ;
5131
5067
}
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) ;
5133
5069
} ,
5134
5070
hash_map:: Entry :: Vacant ( _) => return Err ( MsgHandleErrInternal :: send_err_msg_no_close ( "Failed to find corresponding channel" . to_owned ( ) , msg. channel_id ) )
5135
5071
}
@@ -5148,7 +5084,7 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
5148
5084
let chan_err: ChannelError = ChannelError :: Close ( "Got update_fail_malformed_htlc with BADONION not set" . to_owned ( ) ) ;
5149
5085
try_chan_entry ! ( self , Err ( chan_err) , chan) ;
5150
5086
}
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) ;
5152
5088
Ok ( ( ) )
5153
5089
} ,
5154
5090
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 {
7037
6973
}
7038
6974
}
7039
6975
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
-
7050
6976
impl_writeable_tlv_based ! ( PendingAddHTLCInfo , {
7051
6977
( 0 , forward_info, required) ,
7052
6978
( 1 , prev_user_channel_id, ( default_value, 0 ) ) ,
0 commit comments