@@ -937,23 +937,54 @@ pub(crate) struct DecodedOnionFailure {
937937 pub ( crate ) onion_error_data : Option < Vec < u8 > > ,
938938}
939939
940+ pub ( super ) fn process_onion_failure < T : secp256k1:: Signing , L : Deref > (
941+ secp_ctx : & Secp256k1 < T > , logger : & L , htlc_source : & HTLCSource ,
942+ encrypted_packet : OnionErrorPacket ,
943+ ) -> DecodedOnionFailure
944+ where
945+ L :: Target : Logger ,
946+ {
947+ let ( path, primary_session_priv) = match htlc_source {
948+ HTLCSource :: OutboundRoute { ref path, ref session_priv, .. } => ( path, session_priv) ,
949+ _ => unreachable ! ( ) ,
950+ } ;
951+
952+ let ( outer_session_priv, inner_session_priv) = if path. has_trampoline_hops ( ) {
953+ // If we have Trampoline hops, the outer onion session_priv is a hash of the inner one.
954+ let session_priv_hash = Sha256 :: hash ( & primary_session_priv. secret_bytes ( ) ) . to_byte_array ( ) ;
955+ (
956+ & SecretKey :: from_slice ( & session_priv_hash[ ..] ) . expect ( "You broke SHA-256!" ) ,
957+ Some ( primary_session_priv) ,
958+ )
959+ } else {
960+ ( primary_session_priv, None )
961+ } ;
962+
963+ process_onion_failure_inner (
964+ secp_ctx,
965+ logger,
966+ htlc_source,
967+ outer_session_priv,
968+ inner_session_priv,
969+ encrypted_packet,
970+ )
971+ }
972+
940973/// Process failure we got back from upstream on a payment we sent (implying htlc_source is an
941974/// OutboundRoute).
942975#[ inline]
943- pub ( super ) fn process_onion_failure < T : secp256k1:: Signing , L : Deref > (
944- secp_ctx : & Secp256k1 < T > , logger : & L , htlc_source : & HTLCSource ,
945- mut encrypted_packet : OnionErrorPacket , outer_session_priv_override : Option < SecretKey > ,
976+ pub ( super ) fn process_onion_failure_inner < T : secp256k1:: Signing , L : Deref > (
977+ secp_ctx : & Secp256k1 < T > , logger : & L , htlc_source : & HTLCSource , outer_session_priv : & SecretKey ,
978+ inner_session_priv : Option < & SecretKey > , mut encrypted_packet : OnionErrorPacket ,
946979) -> DecodedOnionFailure
947980where
948981 L :: Target : Logger ,
949982{
950- let ( path, session_priv, first_hop_htlc_msat) = match htlc_source {
951- HTLCSource :: OutboundRoute {
952- ref path, ref session_priv, ref first_hop_htlc_msat, ..
953- } => ( path, session_priv, first_hop_htlc_msat) ,
954- _ => {
955- unreachable ! ( )
983+ let ( path, first_hop_htlc_msat) = match htlc_source {
984+ HTLCSource :: OutboundRoute { ref path, ref first_hop_htlc_msat, .. } => {
985+ ( path, first_hop_htlc_msat)
956986 } ,
987+ _ => unreachable ! ( ) ,
957988 } ;
958989
959990 // Learnings from the HTLC failure to inform future payment retries and scoring.
@@ -1002,14 +1033,6 @@ where
10021033 }
10031034 }
10041035
1005- let outer_session_priv = path. has_trampoline_hops ( ) . then ( || {
1006- // If we have Trampoline hops, the outer onion session_priv is a hash of the inner one.
1007- outer_session_priv_override. unwrap_or_else ( || {
1008- let session_priv_hash = Sha256 :: hash ( & session_priv. secret_bytes ( ) ) . to_byte_array ( ) ;
1009- SecretKey :: from_slice ( & session_priv_hash[ ..] ) . expect ( "You broke SHA-256!" )
1010- } )
1011- } ) ;
1012-
10131036 let num_blinded_hops = path. blinded_tail . as_ref ( ) . map_or ( 0 , |bt| bt. hops . len ( ) ) ;
10141037
10151038 // We are first collecting all the unblinded `RouteHop`s inside `onion_keys`. Then, if applicable,
@@ -1020,7 +1043,7 @@ where
10201043 & path. hops ,
10211044 // if we have Trampoline hops, the blinded hops are part of the inner Trampoline onion
10221045 if path. has_trampoline_hops ( ) { None } else { path. blinded_tail . as_ref ( ) } ,
1023- outer_session_priv. as_ref ( ) . unwrap_or ( session_priv ) ,
1046+ outer_session_priv,
10241047 |shared_secret, _, _, route_hop_option : Option < & RouteHop > , _| {
10251048 onion_keys. push ( ( route_hop_option. map ( |rh| ErrorHop :: RouteHop ( rh) ) , shared_secret) )
10261049 } ,
@@ -1033,7 +1056,7 @@ where
10331056 // Trampoline hops are part of the blinded tail, so this can never panic
10341057 & path. blinded_tail . as_ref ( ) . unwrap ( ) . trampoline_hops ,
10351058 path. blinded_tail . as_ref ( ) ,
1036- session_priv ,
1059+ inner_session_priv . expect ( "Trampoline hops always have an inner session priv" ) ,
10371060 |shared_secret, _, _, trampoline_hop_option : Option < & TrampolineHop > , _| {
10381061 onion_keys. push ( (
10391062 trampoline_hop_option. map ( |th| ErrorHop :: TrampolineHop ( th) ) ,
@@ -1473,7 +1496,7 @@ impl HTLCFailReason {
14731496 {
14741497 match self . 0 {
14751498 HTLCFailReasonRepr :: LightningError { ref err } => {
1476- process_onion_failure ( secp_ctx, logger, & htlc_source, err. clone ( ) , None )
1499+ process_onion_failure ( secp_ctx, logger, & htlc_source, err. clone ( ) )
14771500 } ,
14781501 #[ allow( unused) ]
14791502 HTLCFailReasonRepr :: Reason { ref failure_code, ref data, .. } => {
@@ -2401,8 +2424,7 @@ mod tests {
24012424
24022425 // Assert that the original failure can be retrieved and that all hmacs check out.
24032426 let decrypted_failure =
2404- process_onion_failure ( & ctx_full, & logger, & htlc_source, onion_error, None ) ;
2405-
2427+ process_onion_failure ( & ctx_full, & logger, & htlc_source, onion_error) ;
24062428 assert_eq ! ( decrypted_failure. onion_error_code, Some ( 0x2002 ) ) ;
24072429 }
24082430
@@ -2497,12 +2519,13 @@ mod tests {
24972519 let error_packet_hex = "f8941a320b8fde4ad7b9b920c69cbf334114737497d93059d77e591eaa78d6334d3e2aeefcb0cc83402eaaf91d07d695cd895d9cad1018abdaf7d2a49d7657b1612729db7f393f0bb62b25afaaaa326d72a9214666025385033f2ec4605dcf1507467b5726d806da180ea224a7d8631cd31b0bdd08eead8bfe14fc8c7475e17768b1321b54dd4294aecc96da391efe0ca5bd267a45ee085c85a60cf9a9ac152fa4795fff8700a3ea4f848817f5e6943e855ab2e86f6929c9e885d8b20c49b14d2512c59ed21f10bd38691110b0d82c00d9fa48a20f10c7550358724c6e8e2b966e56a0aadf458695b273768062fa7c6e60eb72d4cdc67bf525c194e4a17fdcaa0e9d80480b586bf113f14eea530b6728a1c53fe5cee092e24a90f21f4b764015e7ed5e23" ;
24982520 let error_packet =
24992521 OnionErrorPacket { data : <Vec < u8 > >:: from_hex ( error_packet_hex) . unwrap ( ) } ;
2500- let decrypted_failure = process_onion_failure (
2522+ let decrypted_failure = process_onion_failure_inner (
25012523 & secp_ctx,
25022524 & logger,
25032525 & htlc_source,
2526+ & outer_session_priv,
2527+ Some ( & trampoline_session_priv) ,
25042528 error_packet,
2505- Some ( outer_session_priv) ,
25062529 ) ;
25072530 assert_eq ! ( decrypted_failure. onion_error_code, Some ( 0x400f ) ) ;
25082531 }
@@ -2545,13 +2568,8 @@ mod tests {
25452568 & mut first_hop_error_packet,
25462569 ) ;
25472570
2548- let decrypted_failure = process_onion_failure (
2549- & secp_ctx,
2550- & logger,
2551- & htlc_source,
2552- first_hop_error_packet,
2553- None ,
2554- ) ;
2571+ let decrypted_failure =
2572+ process_onion_failure ( & secp_ctx, & logger, & htlc_source, first_hop_error_packet) ;
25552573 assert_eq ! ( decrypted_failure. onion_error_code, Some ( error_code) ) ;
25562574 } ;
25572575
@@ -2578,7 +2596,6 @@ mod tests {
25782596 & logger,
25792597 & htlc_source,
25802598 trampoline_outer_hop_error_packet,
2581- None ,
25822599 ) ;
25832600 assert_eq ! ( decrypted_failure. onion_error_code, Some ( error_code) ) ;
25842601 } ;
@@ -2611,7 +2628,6 @@ mod tests {
26112628 & logger,
26122629 & htlc_source,
26132630 trampoline_inner_hop_error_packet,
2614- None ,
26152631 ) ;
26162632 assert_eq ! ( decrypted_failure. onion_error_code, Some ( error_code) ) ;
26172633 }
@@ -2703,8 +2719,7 @@ mod tests {
27032719 payment_id : PaymentId ( [ 1 ; 32 ] ) ,
27042720 } ;
27052721
2706- let decrypted_failure =
2707- process_onion_failure ( & ctx_full, & logger, & htlc_source, packet, None ) ;
2722+ let decrypted_failure = process_onion_failure ( & ctx_full, & logger, & htlc_source, packet) ;
27082723
27092724 decrypted_failure
27102725 }
0 commit comments