@@ -1962,11 +1962,8 @@ fn test_trampoline_inbound_payment_decoding() {
1962
1962
} ;
1963
1963
}
1964
1964
1965
- #[ test]
1966
1965
#[ cfg( trampoline) ]
1967
- fn test_successful_trampoline_single_hop_receive ( ) {
1968
- // Simulate a payment of A (0) -> B (1) -> C(Trampoline (blinded intro)) (2)
1969
-
1966
+ fn do_test_trampoline_single_hop_receive ( success : bool ) {
1970
1967
const TOTAL_NODE_COUNT : usize = 3 ;
1971
1968
let secp_ctx = Secp256k1 :: new ( ) ;
1972
1969
@@ -1982,6 +1979,7 @@ fn test_successful_trampoline_single_hop_receive() {
1982
1979
connect_blocks ( & nodes[ i] , ( TOTAL_NODE_COUNT as u32 ) * CHAN_CONFIRM_DEPTH + 1 - nodes[ i] . best_block_info ( ) . 1 ) ;
1983
1980
}
1984
1981
1982
+ let alice_node_id = nodes[ 0 ] . node ( ) . get_our_node_id ( ) ;
1985
1983
let bob_node_id = nodes[ 1 ] . node ( ) . get_our_node_id ( ) ;
1986
1984
let carol_node_id = nodes[ 2 ] . node ( ) . get_our_node_id ( ) ;
1987
1985
@@ -1990,129 +1988,51 @@ fn test_successful_trampoline_single_hop_receive() {
1990
1988
1991
1989
let amt_msat = 1000 ;
1992
1990
let ( payment_preimage, payment_hash, payment_secret) = get_payment_preimage_hash ( & nodes[ 2 ] , Some ( amt_msat) , None ) ;
1993
- let payee_tlvs = UnauthenticatedReceiveTlvs {
1994
- payment_secret,
1995
- payment_constraints : PaymentConstraints {
1996
- max_cltv_expiry : u32:: max_value ( ) ,
1997
- htlc_minimum_msat : amt_msat,
1998
- } ,
1999
- payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext { } ) ,
2000
- } ;
2001
-
2002
- let nonce = Nonce ( [ 42u8 ; 16 ] ) ;
2003
- let expanded_key = nodes[ 2 ] . keys_manager . get_inbound_payment_key ( ) ;
2004
- let payee_tlvs = payee_tlvs. authenticate ( nonce, & expanded_key) ;
2005
- let carol_unblinded_tlvs = payee_tlvs. encode ( ) ;
2006
1991
2007
- let path = [ ( carol_node_id, WithoutLength ( & carol_unblinded_tlvs) ) ] ;
2008
1992
let carol_alice_trampoline_session_priv = secret_from_hex ( "a0f4b8d7b6c2d0ffdfaf718f76e9decaef4d9fb38a8c4addb95c4007cc3eee03" ) ;
2009
1993
let carol_blinding_point = PublicKey :: from_secret_key ( & secp_ctx, & carol_alice_trampoline_session_priv) ;
2010
- let carol_blinded_hops = blinded_path:: utils:: construct_blinded_hops (
2011
- & secp_ctx, path. into_iter ( ) , & carol_alice_trampoline_session_priv
2012
- ) . unwrap ( ) ;
2013
-
2014
- let route = Route {
2015
- paths : vec ! [ Path {
2016
- hops: vec![
2017
- // Bob
2018
- RouteHop {
2019
- pubkey: bob_node_id,
2020
- node_features: NodeFeatures :: empty( ) ,
2021
- short_channel_id: alice_bob_scid,
2022
- channel_features: ChannelFeatures :: empty( ) ,
2023
- fee_msat: 1000 ,
2024
- cltv_expiry_delta: 48 ,
2025
- maybe_announced_channel: false ,
2026
- } ,
2027
-
2028
- // Carol
2029
- RouteHop {
2030
- pubkey: carol_node_id,
2031
- node_features: NodeFeatures :: empty( ) ,
2032
- short_channel_id: bob_carol_scid,
2033
- channel_features: ChannelFeatures :: empty( ) ,
2034
- fee_msat: 0 ,
2035
- cltv_expiry_delta: 48 ,
2036
- maybe_announced_channel: false ,
2037
- }
2038
- ] ,
2039
- blinded_tail: Some ( BlindedTail {
2040
- trampoline_hops: vec![
2041
- // Carol
2042
- TrampolineHop {
2043
- pubkey: carol_node_id,
2044
- node_features: Features :: empty( ) ,
2045
- fee_msat: amt_msat,
2046
- cltv_expiry_delta: 24 ,
2047
- } ,
2048
- ] ,
2049
- hops: carol_blinded_hops,
2050
- blinding_point: carol_blinding_point,
2051
- excess_final_cltv_expiry_delta: 39 ,
2052
- final_value_msat: amt_msat,
2053
- } )
2054
- } ] ,
2055
- route_params : None ,
2056
- } ;
2057
-
2058
- nodes[ 0 ] . node . send_payment_with_route ( route, payment_hash, RecipientOnionFields :: spontaneous_empty ( ) , PaymentId ( payment_hash. 0 ) ) . unwrap ( ) ;
2059
-
2060
- check_added_monitors ! ( & nodes[ 0 ] , 1 ) ;
2061
- pass_along_route ( & nodes[ 0 ] , & [ & [ & nodes[ 1 ] , & nodes[ 2 ] ] ] , amt_msat, payment_hash, payment_secret) ;
2062
- claim_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] , & nodes[ 2 ] ] , payment_preimage) ;
2063
- }
2064
-
2065
- #[ test]
2066
- #[ cfg( trampoline) ]
2067
- fn test_trampoline_blinded_decoding_failure ( ) {
2068
- // Simulate a payment failure of A (0) -> B (1) -> C(Trampoline (blinded forward)) (2)
2069
-
2070
- const TOTAL_NODE_COUNT : usize = 3 ;
2071
- let secp_ctx = Secp256k1 :: new ( ) ;
2072
-
2073
- let chanmon_cfgs = create_chanmon_cfgs ( TOTAL_NODE_COUNT ) ;
2074
- let node_cfgs = create_node_cfgs ( TOTAL_NODE_COUNT , & chanmon_cfgs) ;
2075
- let node_chanmgrs = create_node_chanmgrs ( TOTAL_NODE_COUNT , & node_cfgs, & vec ! [ None ; TOTAL_NODE_COUNT ] ) ;
2076
- let mut nodes = create_network ( TOTAL_NODE_COUNT , & node_cfgs, & node_chanmgrs) ;
2077
-
2078
- let ( _, _, chan_id_alice_bob, _) = create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 1_000_000 , 0 ) ;
2079
- let ( _, _, chan_id_bob_carol, _) = create_announced_chan_between_nodes_with_value ( & nodes, 1 , 2 , 1_000_000 , 0 ) ;
2080
-
2081
- for i in 0 ..TOTAL_NODE_COUNT { // connect all nodes' blocks
2082
- connect_blocks ( & nodes[ i] , ( TOTAL_NODE_COUNT as u32 ) * CHAN_CONFIRM_DEPTH + 1 - nodes[ i] . best_block_info ( ) . 1 ) ;
2083
- }
1994
+ let carol_blinded_hops = if success {
1995
+ let payee_tlvs = UnauthenticatedReceiveTlvs {
1996
+ payment_secret,
1997
+ payment_constraints : PaymentConstraints {
1998
+ max_cltv_expiry : u32:: max_value ( ) ,
1999
+ htlc_minimum_msat : amt_msat,
2000
+ } ,
2001
+ payment_context : PaymentContext :: Bolt12Refund ( Bolt12RefundContext { } ) ,
2002
+ } ;
2084
2003
2085
- let alice_node_id = nodes[ 0 ] . node ( ) . get_our_node_id ( ) ;
2086
- let bob_node_id = nodes[ 1 ] . node ( ) . get_our_node_id ( ) ;
2087
- let carol_node_id = nodes[ 2 ] . node ( ) . get_our_node_id ( ) ;
2004
+ let nonce = Nonce ( [ 42u8 ; 16 ] ) ;
2005
+ let expanded_key = nodes[ 2 ] . keys_manager . get_inbound_payment_key ( ) ;
2006
+ let payee_tlvs = payee_tlvs. authenticate ( nonce, & expanded_key) ;
2007
+ let carol_unblinded_tlvs = payee_tlvs. encode ( ) ;
2088
2008
2089
- let alice_bob_scid = nodes[ 0 ] . node ( ) . list_channels ( ) . iter ( ) . find ( |c| c. channel_id == chan_id_alice_bob) . unwrap ( ) . short_channel_id . unwrap ( ) ;
2090
- let bob_carol_scid = nodes[ 1 ] . node ( ) . list_channels ( ) . iter ( ) . find ( |c| c. channel_id == chan_id_bob_carol) . unwrap ( ) . short_channel_id . unwrap ( ) ;
2009
+ let path = [ ( carol_node_id, WithoutLength ( & carol_unblinded_tlvs) ) ] ;
2010
+ blinded_path:: utils:: construct_blinded_hops (
2011
+ & secp_ctx, path. into_iter ( ) , & carol_alice_trampoline_session_priv
2012
+ ) . unwrap ( )
2013
+ } else {
2014
+ let payee_tlvs = blinded_path:: payment:: TrampolineForwardTlvs {
2015
+ next_trampoline : alice_node_id,
2016
+ payment_constraints : PaymentConstraints {
2017
+ max_cltv_expiry : u32:: max_value ( ) ,
2018
+ htlc_minimum_msat : amt_msat,
2019
+ } ,
2020
+ features : BlindedHopFeatures :: empty ( ) ,
2021
+ payment_relay : PaymentRelay {
2022
+ cltv_expiry_delta : 0 ,
2023
+ fee_proportional_millionths : 0 ,
2024
+ fee_base_msat : 0 ,
2025
+ } ,
2026
+ next_blinding_override : None ,
2027
+ } ;
2091
2028
2092
- let amt_msat = 1000 ;
2093
- let ( payment_preimage, payment_hash, _) = get_payment_preimage_hash ( & nodes[ 2 ] , Some ( amt_msat) , None ) ;
2094
- let payee_tlvs = blinded_path:: payment:: TrampolineForwardTlvs {
2095
- next_trampoline : alice_node_id,
2096
- payment_constraints : PaymentConstraints {
2097
- max_cltv_expiry : u32:: max_value ( ) ,
2098
- htlc_minimum_msat : amt_msat,
2099
- } ,
2100
- features : BlindedHopFeatures :: empty ( ) ,
2101
- payment_relay : PaymentRelay {
2102
- cltv_expiry_delta : 0 ,
2103
- fee_proportional_millionths : 0 ,
2104
- fee_base_msat : 0 ,
2105
- } ,
2106
- next_blinding_override : None ,
2029
+ let carol_unblinded_tlvs = payee_tlvs. encode ( ) ;
2030
+ let path = [ ( carol_node_id, WithoutLength ( & carol_unblinded_tlvs) ) ] ;
2031
+ blinded_path:: utils:: construct_blinded_hops (
2032
+ & secp_ctx, path. into_iter ( ) , & carol_alice_trampoline_session_priv
2033
+ ) . unwrap ( )
2107
2034
} ;
2108
2035
2109
- let carol_unblinded_tlvs = payee_tlvs. encode ( ) ;
2110
- let path = [ ( carol_node_id, WithoutLength ( & carol_unblinded_tlvs) ) ] ;
2111
- let carol_alice_trampoline_session_priv = secret_from_hex ( "a0f4b8d7b6c2d0ffdfaf718f76e9decaef4d9fb38a8c4addb95c4007cc3eee03" ) ;
2112
- let carol_blinding_point = PublicKey :: from_secret_key ( & secp_ctx, & carol_alice_trampoline_session_priv) ;
2113
- let carol_blinded_hops = blinded_path:: utils:: construct_blinded_hops (
2114
- & secp_ctx, path. into_iter ( ) , & carol_alice_trampoline_session_priv
2115
- ) . unwrap ( ) ;
2116
2036
2117
2037
let route = Route {
2118
2038
paths : vec ! [ Path {
@@ -2160,71 +2080,87 @@ fn test_trampoline_blinded_decoding_failure() {
2160
2080
2161
2081
nodes[ 0 ] . node . send_payment_with_route ( route. clone ( ) , payment_hash, RecipientOnionFields :: spontaneous_empty ( ) , PaymentId ( payment_hash. 0 ) ) . unwrap ( ) ;
2162
2082
2163
- let replacement_onion = {
2164
- // create a substitute onion where the last Trampoline hop is a forward
2165
- let trampoline_secret_key = secret_from_hex ( "0134928f7b7ca6769080d70f16be84c812c741f545b49a34db47ce338a205799" ) ;
2166
- let prng_seed = secret_from_hex ( "fe02b4b9054302a3ddf4e1e9f7c411d644aebbd295218ab009dca94435f775a9" ) ;
2167
- let recipient_onion_fields = RecipientOnionFields :: spontaneous_empty ( ) ;
2083
+ if success {
2084
+ check_added_monitors ! ( & nodes[ 0 ] , 1 ) ;
2085
+ pass_along_route ( & nodes[ 0 ] , & [ & [ & nodes[ 1 ] , & nodes[ 2 ] ] ] , amt_msat, payment_hash, payment_secret) ;
2086
+ claim_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] , & nodes[ 2 ] ] , payment_preimage) ;
2087
+ } else {
2088
+ let replacement_onion = {
2089
+ // create a substitute onion where the last Trampoline hop is a forward
2090
+ let trampoline_secret_key = secret_from_hex ( "0134928f7b7ca6769080d70f16be84c812c741f545b49a34db47ce338a205799" ) ;
2091
+ let prng_seed = secret_from_hex ( "fe02b4b9054302a3ddf4e1e9f7c411d644aebbd295218ab009dca94435f775a9" ) ;
2092
+ let recipient_onion_fields = RecipientOnionFields :: spontaneous_empty ( ) ;
2168
2093
2169
- let mut blinded_tail = route. paths [ 0 ] . blinded_tail . clone ( ) . unwrap ( ) ;
2094
+ let mut blinded_tail = route. paths [ 0 ] . blinded_tail . clone ( ) . unwrap ( ) ;
2170
2095
2171
- // append some dummy blinded hop so the intro hop looks like a forward
2172
- blinded_tail. hops . push ( BlindedHop {
2173
- blinded_node_id : alice_node_id,
2174
- encrypted_payload : vec ! [ ] ,
2175
- } ) ;
2096
+ // append some dummy blinded hop so the intro hop looks like a forward
2097
+ blinded_tail. hops . push ( BlindedHop {
2098
+ blinded_node_id : alice_node_id,
2099
+ encrypted_payload : vec ! [ ] ,
2100
+ } ) ;
2176
2101
2177
- let ( mut trampoline_payloads, outer_total_msat, outer_starting_htlc_offset) = onion_utils:: build_trampoline_onion_payloads ( & blinded_tail, amt_msat, & recipient_onion_fields, 32 , & None ) . unwrap ( ) ;
2102
+ let ( mut trampoline_payloads, outer_total_msat, outer_starting_htlc_offset) = onion_utils:: build_trampoline_onion_payloads ( & blinded_tail, amt_msat, & recipient_onion_fields, 32 , & None ) . unwrap ( ) ;
2178
2103
2179
- // pop the last dummy hop
2180
- trampoline_payloads. pop ( ) ;
2104
+ // pop the last dummy hop
2105
+ trampoline_payloads. pop ( ) ;
2181
2106
2182
- let trampoline_onion_keys = onion_utils:: construct_trampoline_onion_keys ( & secp_ctx, & route. paths [ 0 ] . blinded_tail . as_ref ( ) . unwrap ( ) , & trampoline_secret_key) . unwrap ( ) ;
2183
- let trampoline_packet = onion_utils:: construct_trampoline_onion_packet (
2184
- trampoline_payloads,
2185
- trampoline_onion_keys,
2186
- prng_seed. secret_bytes ( ) ,
2187
- & payment_hash,
2188
- None ,
2189
- ) . unwrap ( ) ;
2107
+ let trampoline_onion_keys = onion_utils:: construct_trampoline_onion_keys ( & secp_ctx, & route. paths [ 0 ] . blinded_tail . as_ref ( ) . unwrap ( ) , & trampoline_secret_key) . unwrap ( ) ;
2108
+ let trampoline_packet = onion_utils:: construct_trampoline_onion_packet (
2109
+ trampoline_payloads,
2110
+ trampoline_onion_keys,
2111
+ prng_seed. secret_bytes ( ) ,
2112
+ & payment_hash,
2113
+ None ,
2114
+ ) . unwrap ( ) ;
2190
2115
2191
- let outer_session_priv = secret_from_hex ( "e52c20461ed7acd46c4e7b591a37610519179482887bd73bf3b94617f8f03677" ) ;
2116
+ let outer_session_priv = secret_from_hex ( "e52c20461ed7acd46c4e7b591a37610519179482887bd73bf3b94617f8f03677" ) ;
2192
2117
2193
- let ( outer_payloads, _, _) = onion_utils:: build_onion_payloads ( & route. paths [ 0 ] , outer_total_msat, & recipient_onion_fields, outer_starting_htlc_offset, & None , None , Some ( trampoline_packet) ) . unwrap ( ) ;
2194
- let outer_onion_keys = onion_utils:: construct_onion_keys ( & secp_ctx, & route. clone ( ) . paths [ 0 ] , & outer_session_priv) . unwrap ( ) ;
2195
- let outer_packet = onion_utils:: construct_onion_packet (
2196
- outer_payloads,
2197
- outer_onion_keys,
2198
- prng_seed. secret_bytes ( ) ,
2199
- & payment_hash,
2200
- ) . unwrap ( ) ;
2118
+ let ( outer_payloads, _, _) = onion_utils:: build_onion_payloads ( & route. paths [ 0 ] , outer_total_msat, & recipient_onion_fields, outer_starting_htlc_offset, & None , None , Some ( trampoline_packet) ) . unwrap ( ) ;
2119
+ let outer_onion_keys = onion_utils:: construct_onion_keys ( & secp_ctx, & route. clone ( ) . paths [ 0 ] , & outer_session_priv) . unwrap ( ) ;
2120
+ let outer_packet = onion_utils:: construct_onion_packet (
2121
+ outer_payloads,
2122
+ outer_onion_keys,
2123
+ prng_seed. secret_bytes ( ) ,
2124
+ & payment_hash,
2125
+ ) . unwrap ( ) ;
2201
2126
2202
- outer_packet
2203
- } ;
2127
+ outer_packet
2128
+ } ;
2204
2129
2205
- check_added_monitors ! ( & nodes[ 0 ] , 1 ) ;
2130
+ check_added_monitors ! ( & nodes[ 0 ] , 1 ) ;
2206
2131
2207
- // Check that we've queued the HTLCs of the async keysend payment.
2208
- let mut events = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
2209
- assert_eq ! ( events. len( ) , 1 ) ;
2210
- let mut first_message_event = remove_first_msg_event_to_node ( & nodes[ 1 ] . node . get_our_node_id ( ) , & mut events) ;
2211
- let mut update_message = match first_message_event {
2212
- MessageSendEvent :: UpdateHTLCs { ref mut updates, .. } => {
2213
- assert_eq ! ( updates. update_add_htlcs. len( ) , 1 ) ;
2214
- updates. update_add_htlcs . get_mut ( 0 )
2215
- } ,
2216
- _ => panic ! ( )
2217
- } ;
2218
- update_message. map ( |msg| {
2219
- msg. onion_routing_packet = replacement_onion. clone ( ) ;
2220
- } ) ;
2221
-
2222
- let route: & [ & Node ] = & [ & nodes[ 1 ] , & nodes[ 2 ] ] ;
2223
- let args = PassAlongPathArgs :: new ( & nodes[ 0 ] , route, amt_msat, payment_hash, first_message_event)
2224
- . with_payment_preimage ( payment_preimage)
2225
- . without_claimable_event ( )
2226
- . expect_failure ( HTLCDestination :: InvalidOnion ) ;
2227
- do_pass_along_path ( args) ;
2132
+ // Check that we've queued the HTLCs of the async keysend payment.
2133
+ let mut events = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
2134
+ assert_eq ! ( events. len( ) , 1 ) ;
2135
+ let mut first_message_event = remove_first_msg_event_to_node ( & nodes[ 1 ] . node . get_our_node_id ( ) , & mut events) ;
2136
+ let mut update_message = match first_message_event {
2137
+ MessageSendEvent :: UpdateHTLCs { ref mut updates, .. } => {
2138
+ assert_eq ! ( updates. update_add_htlcs. len( ) , 1 ) ;
2139
+ updates. update_add_htlcs . get_mut ( 0 )
2140
+ } ,
2141
+ _ => panic ! ( )
2142
+ } ;
2143
+ update_message. map ( |msg| {
2144
+ msg. onion_routing_packet = replacement_onion. clone ( ) ;
2145
+ } ) ;
2146
+
2147
+ let route: & [ & Node ] = & [ & nodes[ 1 ] , & nodes[ 2 ] ] ;
2148
+ let args = PassAlongPathArgs :: new ( & nodes[ 0 ] , route, amt_msat, payment_hash, first_message_event)
2149
+ . with_payment_preimage ( payment_preimage)
2150
+ . without_claimable_event ( )
2151
+ . expect_failure ( HTLCDestination :: InvalidOnion ) ;
2152
+ do_pass_along_path ( args) ;
2228
2153
2229
- fail_blinded_htlc_backwards ( payment_hash, 1 , & [ & nodes[ 0 ] , & nodes[ 1 ] , & nodes[ 2 ] ] , false ) ;
2154
+ fail_blinded_htlc_backwards ( payment_hash, 1 , & [ & nodes[ 0 ] , & nodes[ 1 ] , & nodes[ 2 ] ] , false ) ;
2155
+ }
2156
+ }
2157
+
2158
+ #[ test]
2159
+ #[ cfg( trampoline) ]
2160
+ fn test_trampoline_single_hop_receive ( ) {
2161
+ // Simulate a payment of A (0) -> B (1) -> C(Trampoline (blinded intro)) (2)
2162
+ do_test_trampoline_single_hop_receive ( true ) ;
2163
+
2164
+ // Simulate a payment failure of A (0) -> B (1) -> C(Trampoline (blinded forward)) (2)
2165
+ do_test_trampoline_single_hop_receive ( false ) ;
2230
2166
}
0 commit comments