@@ -326,6 +326,26 @@ impl HTLCFailReason {
326326 }
327327 }
328328 }
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+ }
329349}
330350
331351struct ReceiveError {
@@ -4080,90 +4100,48 @@ impl<M: Deref, T: Deref, K: Deref, F: Deref, L: Deref> ChannelManager<M, T, K, F
40804100 } else { None } ;
40814101 log_trace ! ( self . logger, "Failing outbound payment HTLC with payment_hash {}" , log_bytes!( payment_hash. 0 ) ) ;
40824102
4083- let path_failure = match & onion_error {
4084- & HTLCFailReason :: LightningError { ref err } => {
4103+ let path_failure = {
40854104#[ 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) ;
40874106#[ 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 {
41464112 payment_id : * payment_id,
41474113 payment_hash : payment_hash. clone ( ) ,
41484114 path : path. clone ( ) ,
4149- short_channel_id : Some ( scid) ,
41504115 }
41514116 } else {
4152- events:: Event :: PaymentPathFailed {
4153- payment_id : Some ( * payment_id) ,
4117+ events:: Event :: ProbeFailed {
4118+ payment_id : * payment_id,
41544119 payment_hash : payment_hash. clone ( ) ,
4155- payment_failed_permanently : false ,
4156- network_update : None ,
4157- all_paths_failed,
41584120 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,
41654122 }
41664123 }
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+ }
41674145 }
41684146 } ;
41694147 let mut pending_events = self . pending_events . lock ( ) . unwrap ( ) ;
0 commit comments