@@ -326,6 +326,26 @@ impl HTLCFailReason {
326
326
}
327
327
}
328
328
}
329
+
330
+ fn decode_onion_failure < T : secp256k1:: Signing , L : Deref > ( & self , secp_ctx : & Secp256k1 < T > , logger : & L , htlc_source : & HTLCSource ) -> ( Option < crate :: routing:: gossip:: NetworkUpdate > , Option < u64 > , bool , Option < u16 > , Option < Vec < u8 > > ) where L :: Target : Logger {
331
+ match self {
332
+ HTLCFailReason :: LightningError { ref err } => {
333
+ onion_utils:: process_onion_failure ( secp_ctx, logger, & htlc_source, err. data . clone ( ) )
334
+ } ,
335
+ HTLCFailReason :: Reason { ref failure_code, ref data, .. } => {
336
+ // we get a fail_malformed_htlc from the first hop
337
+ // TODO: We'd like to generate a NetworkUpdate for temporary
338
+ // failures here, but that would be insufficient as find_route
339
+ // generally ignores its view of our own channels as we provide them via
340
+ // ChannelDetails.
341
+ // TODO: For non-temporary failures, we really should be closing the
342
+ // channel here as we apparently can't relay through them anyway.
343
+ if let & HTLCSource :: OutboundRoute { ref path, .. } = htlc_source {
344
+ ( None , Some ( path. first ( ) . unwrap ( ) . short_channel_id ) , true , Some ( * failure_code) , Some ( data. clone ( ) ) )
345
+ } else { unreachable ! ( ) ; }
346
+ }
347
+ }
348
+ }
329
349
}
330
350
331
351
struct ReceiveError {
@@ -4080,90 +4100,48 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
4080
4100
} else { None } ;
4081
4101
log_trace ! ( self . logger, "Failing outbound payment HTLC with payment_hash {}" , log_bytes!( payment_hash. 0 ) ) ;
4082
4102
4083
- let path_failure = match & onion_error {
4084
- & HTLCFailReason :: LightningError { ref err } => {
4103
+ let path_failure = {
4085
4104
#[ cfg( test) ]
4086
- 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 ( ) ) ;
4105
+ 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) ;
4087
4106
#[ cfg( not( test) ) ]
4088
- let ( network_update, short_channel_id, payment_retryable, _, _) = onion_utils:: process_onion_failure ( & self . secp_ctx , & self . logger , & source, err. data . clone ( ) ) ;
4089
-
4090
- if self . payment_is_probe ( payment_hash, & payment_id) {
4091
- if !payment_retryable {
4092
- events:: Event :: ProbeSuccessful {
4093
- payment_id : * payment_id,
4094
- payment_hash : payment_hash. clone ( ) ,
4095
- path : path. clone ( ) ,
4096
- }
4097
- } else {
4098
- events:: Event :: ProbeFailed {
4099
- payment_id : * payment_id,
4100
- payment_hash : payment_hash. clone ( ) ,
4101
- path : path. clone ( ) ,
4102
- short_channel_id,
4103
- }
4104
- }
4105
- } else {
4106
- // TODO: If we decided to blame ourselves (or one of our channels) in
4107
- // process_onion_failure we should close that channel as it implies our
4108
- // next-hop is needlessly blaming us!
4109
- if let Some ( scid) = short_channel_id {
4110
- retry. as_mut ( ) . map ( |r| r. payment_params . previously_failed_channels . push ( scid) ) ;
4111
- }
4112
- events:: Event :: PaymentPathFailed {
4113
- payment_id : Some ( * payment_id) ,
4114
- payment_hash : payment_hash. clone ( ) ,
4115
- payment_failed_permanently : !payment_retryable,
4116
- network_update,
4117
- all_paths_failed,
4118
- path : path. clone ( ) ,
4119
- short_channel_id,
4120
- retry,
4121
- #[ cfg( test) ]
4122
- error_code : onion_error_code,
4123
- #[ cfg( test) ]
4124
- error_data : onion_error_data
4125
- }
4126
- }
4127
- } ,
4128
- & HTLCFailReason :: Reason {
4129
- #[ cfg( test) ]
4130
- ref failure_code,
4131
- #[ cfg( test) ]
4132
- ref data,
4133
- .. } => {
4134
- // we get a fail_malformed_htlc from the first hop
4135
- // TODO: We'd like to generate a NetworkUpdate for temporary
4136
- // failures here, but that would be insufficient as find_route
4137
- // generally ignores its view of our own channels as we provide them via
4138
- // ChannelDetails.
4139
- // TODO: For non-temporary failures, we really should be closing the
4140
- // channel here as we apparently can't relay through them anyway.
4141
- let scid = path. first ( ) . unwrap ( ) . short_channel_id ;
4142
- retry. as_mut ( ) . map ( |r| r. payment_params . previously_failed_channels . push ( scid) ) ;
4143
-
4144
- if self . payment_is_probe ( payment_hash, & payment_id) {
4145
- events:: Event :: ProbeFailed {
4107
+ let ( network_update, short_channel_id, payment_retryable, _, _) = onion_error. decode_onion_failure ( & self . secp_ctx , & self . logger , & source) ;
4108
+
4109
+ if self . payment_is_probe ( payment_hash, & payment_id) {
4110
+ if !payment_retryable {
4111
+ events:: Event :: ProbeSuccessful {
4146
4112
payment_id : * payment_id,
4147
4113
payment_hash : payment_hash. clone ( ) ,
4148
4114
path : path. clone ( ) ,
4149
- short_channel_id : Some ( scid) ,
4150
4115
}
4151
4116
} else {
4152
- events:: Event :: PaymentPathFailed {
4153
- payment_id : Some ( * payment_id) ,
4117
+ events:: Event :: ProbeFailed {
4118
+ payment_id : * payment_id,
4154
4119
payment_hash : payment_hash. clone ( ) ,
4155
- payment_failed_permanently : false ,
4156
- network_update : None ,
4157
- all_paths_failed,
4158
4120
path : path. clone ( ) ,
4159
- short_channel_id : Some ( scid) ,
4160
- retry,
4161
- #[ cfg( test) ]
4162
- error_code : Some ( * failure_code) ,
4163
- #[ cfg( test) ]
4164
- error_data : Some ( data. clone ( ) ) ,
4121
+ short_channel_id,
4165
4122
}
4166
4123
}
4124
+ } else {
4125
+ // TODO: If we decided to blame ourselves (or one of our channels) in
4126
+ // process_onion_failure we should close that channel as it implies our
4127
+ // next-hop is needlessly blaming us!
4128
+ if let Some ( scid) = short_channel_id {
4129
+ retry. as_mut ( ) . map ( |r| r. payment_params . previously_failed_channels . push ( scid) ) ;
4130
+ }
4131
+ events:: Event :: PaymentPathFailed {
4132
+ payment_id : Some ( * payment_id) ,
4133
+ payment_hash : payment_hash. clone ( ) ,
4134
+ payment_failed_permanently : !payment_retryable,
4135
+ network_update,
4136
+ all_paths_failed,
4137
+ path : path. clone ( ) ,
4138
+ short_channel_id,
4139
+ retry,
4140
+ #[ cfg( test) ]
4141
+ error_code : onion_error_code,
4142
+ #[ cfg( test) ]
4143
+ error_data : onion_error_data
4144
+ }
4167
4145
}
4168
4146
} ;
4169
4147
let mut pending_events = self . pending_events . lock ( ) . unwrap ( ) ;
0 commit comments