@@ -2047,3 +2047,328 @@ fn fails_paying_after_rejected_by_payee() {
2047
2047
expect_pending_htlcs_forwardable_and_htlc_handling_failed ! ( nodes[ 1 ] , [ HTLCDestination :: FailedPayment { payment_hash } ] ) ;
2048
2048
pass_failed_payment_back ( & nodes[ 0 ] , & [ & [ & nodes[ 1 ] ] ] , false , payment_hash) ;
2049
2049
}
2050
+
2051
+ #[ test]
2052
+ fn retry_multi_path_single_failed_payment ( ) {
2053
+ // Tests that we can/will retry after a single path of an MPP payment failed immediately
2054
+ let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
2055
+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
2056
+ let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None , None ] ) ;
2057
+ let nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
2058
+
2059
+ create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 1_000_000 , 0 , channelmanager:: provided_init_features ( ) , channelmanager:: provided_init_features ( ) ) ;
2060
+ create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 1_000_000 , 0 , channelmanager:: provided_init_features ( ) , channelmanager:: provided_init_features ( ) ) ;
2061
+ let chans = nodes[ 0 ] . node . list_usable_channels ( ) ;
2062
+ let mut route = Route {
2063
+ paths : vec ! [
2064
+ vec![ RouteHop {
2065
+ pubkey: nodes[ 1 ] . node. get_our_node_id( ) ,
2066
+ node_features: channelmanager:: provided_node_features( ) ,
2067
+ short_channel_id: chans[ 0 ] . short_channel_id. unwrap( ) ,
2068
+ channel_features: channelmanager:: provided_channel_features( ) ,
2069
+ fee_msat: 10_000 ,
2070
+ cltv_expiry_delta: 100 ,
2071
+ } ] ,
2072
+ vec![ RouteHop {
2073
+ pubkey: nodes[ 1 ] . node. get_our_node_id( ) ,
2074
+ node_features: channelmanager:: provided_node_features( ) ,
2075
+ short_channel_id: chans[ 1 ] . short_channel_id. unwrap( ) ,
2076
+ channel_features: channelmanager:: provided_channel_features( ) ,
2077
+ fee_msat: 100_000_001 , // Our default max-HTLC-value is 10% of the channel value, which this is one more than
2078
+ cltv_expiry_delta: 100 ,
2079
+ } ] ,
2080
+ ] ,
2081
+ payment_params : Some ( PaymentParameters :: from_node_id ( nodes[ 1 ] . node . get_our_node_id ( ) ) ) ,
2082
+ } ;
2083
+ nodes[ 0 ] . router . expect_find_route ( Ok ( route. clone ( ) ) ) ;
2084
+ // On retry, split the payment across both channels.
2085
+ route. paths [ 0 ] [ 0 ] . fee_msat = 50_000_001 ;
2086
+ route. paths [ 1 ] [ 0 ] . fee_msat = 50_000_000 ;
2087
+ nodes[ 0 ] . router . expect_find_route ( Ok ( route. clone ( ) ) ) ;
2088
+
2089
+ let amt_msat = 100_010_000 ;
2090
+ let ( _, payment_hash, _, payment_secret) = get_route_and_payment_hash ! ( & nodes[ 0 ] , nodes[ 1 ] , amt_msat) ;
2091
+ #[ cfg( feature = "std" ) ]
2092
+ let payment_expiry_secs = SystemTime :: UNIX_EPOCH . elapsed ( ) . unwrap ( ) . as_secs ( ) + 60 * 60 ;
2093
+ #[ cfg( not( feature = "std" ) ) ]
2094
+ let payment_expiry_secs = 60 * 60 ;
2095
+ let mut invoice_features = InvoiceFeatures :: empty ( ) ;
2096
+ invoice_features. set_variable_length_onion_required ( ) ;
2097
+ invoice_features. set_payment_secret_required ( ) ;
2098
+ invoice_features. set_basic_mpp_optional ( ) ;
2099
+ let payment_params = PaymentParameters :: from_node_id ( nodes[ 1 ] . node . get_our_node_id ( ) )
2100
+ . with_expiry_time ( payment_expiry_secs as u64 )
2101
+ . with_features ( invoice_features) ;
2102
+ let route_params = RouteParameters {
2103
+ payment_params,
2104
+ final_value_msat : amt_msat,
2105
+ final_cltv_expiry_delta : TEST_FINAL_CLTV ,
2106
+ } ;
2107
+
2108
+ nodes[ 0 ] . node . send_payment_with_retry ( payment_hash, & Some ( payment_secret) , PaymentId ( payment_hash. 0 ) , route_params, Retry :: Attempts ( 1 ) ) . unwrap ( ) ;
2109
+ let htlc_msgs = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
2110
+ assert_eq ! ( htlc_msgs. len( ) , 2 ) ;
2111
+ check_added_monitors ! ( nodes[ 0 ] , 2 ) ;
2112
+ }
2113
+
2114
+ #[ test]
2115
+ fn immediate_retry_on_failure ( ) {
2116
+ // Tests that we can/will retry immediately after a failure
2117
+ let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
2118
+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
2119
+ let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None , None ] ) ;
2120
+ let nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
2121
+
2122
+ create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 1_000_000 , 0 , channelmanager:: provided_init_features ( ) , channelmanager:: provided_init_features ( ) ) ;
2123
+ create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 1_000_000 , 0 , channelmanager:: provided_init_features ( ) , channelmanager:: provided_init_features ( ) ) ;
2124
+ let chans = nodes[ 0 ] . node . list_usable_channels ( ) ;
2125
+ let mut route = Route {
2126
+ paths : vec ! [
2127
+ vec![ RouteHop {
2128
+ pubkey: nodes[ 1 ] . node. get_our_node_id( ) ,
2129
+ node_features: channelmanager:: provided_node_features( ) ,
2130
+ short_channel_id: chans[ 0 ] . short_channel_id. unwrap( ) ,
2131
+ channel_features: channelmanager:: provided_channel_features( ) ,
2132
+ fee_msat: 100_000_001 , // Our default max-HTLC-value is 10% of the channel value, which this is one more than
2133
+ cltv_expiry_delta: 100 ,
2134
+ } ] ,
2135
+ ] ,
2136
+ payment_params : Some ( PaymentParameters :: from_node_id ( nodes[ 1 ] . node . get_our_node_id ( ) ) ) ,
2137
+ } ;
2138
+ nodes[ 0 ] . router . expect_find_route ( Ok ( route. clone ( ) ) ) ;
2139
+ // On retry, split the payment across both channels.
2140
+ route. paths . push ( route. paths [ 0 ] . clone ( ) ) ;
2141
+ route. paths [ 0 ] [ 0 ] . short_channel_id = chans[ 1 ] . short_channel_id . unwrap ( ) ;
2142
+ route. paths [ 0 ] [ 0 ] . fee_msat = 50_000_000 ;
2143
+ route. paths [ 1 ] [ 0 ] . fee_msat = 50_000_001 ;
2144
+ nodes[ 0 ] . router . expect_find_route ( Ok ( route. clone ( ) ) ) ;
2145
+
2146
+ let amt_msat = 100_010_000 ;
2147
+ let ( _, payment_hash, _, payment_secret) = get_route_and_payment_hash ! ( & nodes[ 0 ] , nodes[ 1 ] , amt_msat) ;
2148
+ #[ cfg( feature = "std" ) ]
2149
+ let payment_expiry_secs = SystemTime :: UNIX_EPOCH . elapsed ( ) . unwrap ( ) . as_secs ( ) + 60 * 60 ;
2150
+ #[ cfg( not( feature = "std" ) ) ]
2151
+ let payment_expiry_secs = 60 * 60 ;
2152
+ let mut invoice_features = InvoiceFeatures :: empty ( ) ;
2153
+ invoice_features. set_variable_length_onion_required ( ) ;
2154
+ invoice_features. set_payment_secret_required ( ) ;
2155
+ invoice_features. set_basic_mpp_optional ( ) ;
2156
+ let payment_params = PaymentParameters :: from_node_id ( nodes[ 1 ] . node . get_our_node_id ( ) )
2157
+ . with_expiry_time ( payment_expiry_secs as u64 )
2158
+ . with_features ( invoice_features) ;
2159
+ let route_params = RouteParameters {
2160
+ payment_params,
2161
+ final_value_msat : amt_msat,
2162
+ final_cltv_expiry_delta : TEST_FINAL_CLTV ,
2163
+ } ;
2164
+
2165
+ nodes[ 0 ] . node . send_payment_with_retry ( payment_hash, & Some ( payment_secret) , PaymentId ( payment_hash. 0 ) , route_params, Retry :: Attempts ( 1 ) ) . unwrap ( ) ;
2166
+ let htlc_msgs = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
2167
+ assert_eq ! ( htlc_msgs. len( ) , 2 ) ;
2168
+ check_added_monitors ! ( nodes[ 0 ] , 2 ) ;
2169
+ }
2170
+
2171
+ #[ test]
2172
+ fn no_extra_retries_on_back_to_back_fail ( ) {
2173
+ // In a previous release, we had a race where we may exceed the payment retry count if we
2174
+ // get two failures in a row with the second having `all_paths_failed` set.
2175
+ // Generally, when we give up trying to retry a payment, we don't know for sure what the
2176
+ // current state of the ChannelManager event queue is. Specifically, we cannot be sure that
2177
+ // there are not multiple additional `PaymentPathFailed` or even `PaymentSent` events
2178
+ // pending which we will see later. Thus, when we previously removed the retry tracking map
2179
+ // entry after a `all_paths_failed` `PaymentPathFailed` event, we may have dropped the
2180
+ // retry entry even though more events for the same payment were still pending. This led to
2181
+ // us retrying a payment again even though we'd already given up on it.
2182
+ //
2183
+ // We now have a separate event - `PaymentFailed` which indicates no HTLCs remain and which
2184
+ // is used to remove the payment retry counter entries instead. This tests for the specific
2185
+ // excess-retry case while also testing `PaymentFailed` generation.
2186
+
2187
+ let chanmon_cfgs = create_chanmon_cfgs ( 3 ) ;
2188
+ let node_cfgs = create_node_cfgs ( 3 , & chanmon_cfgs) ;
2189
+ let node_chanmgrs = create_node_chanmgrs ( 3 , & node_cfgs, & [ None , None , None ] ) ;
2190
+ let nodes = create_network ( 3 , & node_cfgs, & node_chanmgrs) ;
2191
+
2192
+ let chan_1_scid = create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , 10_000_000 , 0 , channelmanager:: provided_init_features ( ) , channelmanager:: provided_init_features ( ) ) . 0 . contents . short_channel_id ;
2193
+ let chan_2_scid = create_announced_chan_between_nodes_with_value ( & nodes, 1 , 2 , 10_000_000 , 0 , channelmanager:: provided_init_features ( ) , channelmanager:: provided_init_features ( ) ) . 0 . contents . short_channel_id ;
2194
+
2195
+ let mut route = Route {
2196
+ paths : vec ! [
2197
+ vec![ RouteHop {
2198
+ pubkey: nodes[ 1 ] . node. get_our_node_id( ) ,
2199
+ node_features: channelmanager:: provided_node_features( ) ,
2200
+ short_channel_id: chan_1_scid,
2201
+ channel_features: channelmanager:: provided_channel_features( ) ,
2202
+ fee_msat: 0 ,
2203
+ cltv_expiry_delta: 100 ,
2204
+ } , RouteHop {
2205
+ pubkey: nodes[ 2 ] . node. get_our_node_id( ) ,
2206
+ node_features: channelmanager:: provided_node_features( ) ,
2207
+ short_channel_id: chan_2_scid,
2208
+ channel_features: channelmanager:: provided_channel_features( ) ,
2209
+ fee_msat: 100_000_000 ,
2210
+ cltv_expiry_delta: 100 ,
2211
+ } ] ,
2212
+ vec![ RouteHop {
2213
+ pubkey: nodes[ 1 ] . node. get_our_node_id( ) ,
2214
+ node_features: channelmanager:: provided_node_features( ) ,
2215
+ short_channel_id: chan_1_scid,
2216
+ channel_features: channelmanager:: provided_channel_features( ) ,
2217
+ fee_msat: 0 ,
2218
+ cltv_expiry_delta: 100 ,
2219
+ } , RouteHop {
2220
+ pubkey: nodes[ 2 ] . node. get_our_node_id( ) ,
2221
+ node_features: channelmanager:: provided_node_features( ) ,
2222
+ short_channel_id: chan_2_scid,
2223
+ channel_features: channelmanager:: provided_channel_features( ) ,
2224
+ fee_msat: 100_000_000 ,
2225
+ cltv_expiry_delta: 100 ,
2226
+ } ]
2227
+ ] ,
2228
+ payment_params : Some ( PaymentParameters :: from_node_id ( nodes[ 2 ] . node . get_our_node_id ( ) ) ) ,
2229
+ } ;
2230
+ nodes[ 0 ] . router . expect_find_route ( Ok ( route. clone ( ) ) ) ;
2231
+ // On retry, we'll only be asked for one path
2232
+ route. paths . remove ( 1 ) ;
2233
+ nodes[ 0 ] . router . expect_find_route ( Ok ( route. clone ( ) ) ) ;
2234
+
2235
+ let amt_msat = 100_010_000 ;
2236
+ let ( _, payment_hash, _, payment_secret) = get_route_and_payment_hash ! ( & nodes[ 0 ] , nodes[ 1 ] , amt_msat) ;
2237
+ #[ cfg( feature = "std" ) ]
2238
+ let payment_expiry_secs = SystemTime :: UNIX_EPOCH . elapsed ( ) . unwrap ( ) . as_secs ( ) + 60 * 60 ;
2239
+ #[ cfg( not( feature = "std" ) ) ]
2240
+ let payment_expiry_secs = 60 * 60 ;
2241
+ let mut invoice_features = InvoiceFeatures :: empty ( ) ;
2242
+ invoice_features. set_variable_length_onion_required ( ) ;
2243
+ invoice_features. set_payment_secret_required ( ) ;
2244
+ invoice_features. set_basic_mpp_optional ( ) ;
2245
+ let payment_params = PaymentParameters :: from_node_id ( nodes[ 1 ] . node . get_our_node_id ( ) )
2246
+ . with_expiry_time ( payment_expiry_secs as u64 )
2247
+ . with_features ( invoice_features) ;
2248
+ let route_params = RouteParameters {
2249
+ payment_params,
2250
+ final_value_msat : amt_msat,
2251
+ final_cltv_expiry_delta : TEST_FINAL_CLTV ,
2252
+ } ;
2253
+
2254
+ nodes[ 0 ] . node . send_payment_with_retry ( payment_hash, & Some ( payment_secret) , PaymentId ( payment_hash. 0 ) , route_params, Retry :: Attempts ( 1 ) ) . unwrap ( ) ;
2255
+ let htlc_updates = SendEvent :: from_node ( & nodes[ 0 ] ) ;
2256
+ check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
2257
+ assert_eq ! ( htlc_updates. msgs. len( ) , 1 ) ;
2258
+
2259
+ nodes[ 1 ] . node . handle_update_add_htlc ( & nodes[ 0 ] . node . get_our_node_id ( ) , & htlc_updates. msgs [ 0 ] ) ;
2260
+ nodes[ 1 ] . node . handle_commitment_signed ( & nodes[ 0 ] . node . get_our_node_id ( ) , & htlc_updates. commitment_msg ) ;
2261
+ check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
2262
+ let ( bs_first_raa, bs_first_cs) = get_revoke_commit_msgs ! ( nodes[ 1 ] , nodes[ 0 ] . node. get_our_node_id( ) ) ;
2263
+
2264
+ nodes[ 0 ] . node . handle_revoke_and_ack ( & nodes[ 1 ] . node . get_our_node_id ( ) , & bs_first_raa) ;
2265
+ check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
2266
+ let second_htlc_updates = SendEvent :: from_node ( & nodes[ 0 ] ) ;
2267
+
2268
+ nodes[ 0 ] . node . handle_commitment_signed ( & nodes[ 1 ] . node . get_our_node_id ( ) , & bs_first_cs) ;
2269
+ check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
2270
+ let as_first_raa = get_event_msg ! ( nodes[ 0 ] , MessageSendEvent :: SendRevokeAndACK , nodes[ 1 ] . node. get_our_node_id( ) ) ;
2271
+
2272
+ nodes[ 1 ] . node . handle_update_add_htlc ( & nodes[ 0 ] . node . get_our_node_id ( ) , & second_htlc_updates. msgs [ 0 ] ) ;
2273
+ nodes[ 1 ] . node . handle_commitment_signed ( & nodes[ 0 ] . node . get_our_node_id ( ) , & second_htlc_updates. commitment_msg ) ;
2274
+ check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
2275
+ let bs_second_raa = get_event_msg ! ( nodes[ 1 ] , MessageSendEvent :: SendRevokeAndACK , nodes[ 0 ] . node. get_our_node_id( ) ) ;
2276
+
2277
+ nodes[ 1 ] . node . handle_revoke_and_ack ( & nodes[ 0 ] . node . get_our_node_id ( ) , & as_first_raa) ;
2278
+ check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
2279
+ let bs_fail_update = get_htlc_update_msgs ! ( nodes[ 1 ] , nodes[ 0 ] . node. get_our_node_id( ) ) ;
2280
+
2281
+ nodes[ 0 ] . node . handle_revoke_and_ack ( & nodes[ 1 ] . node . get_our_node_id ( ) , & bs_second_raa) ;
2282
+ check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
2283
+
2284
+ nodes[ 0 ] . node . handle_update_fail_htlc ( & nodes[ 1 ] . node . get_our_node_id ( ) , & bs_fail_update. update_fail_htlcs [ 0 ] ) ;
2285
+ nodes[ 0 ] . node . handle_commitment_signed ( & nodes[ 1 ] . node . get_our_node_id ( ) , & bs_fail_update. commitment_signed ) ;
2286
+ check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
2287
+ let ( as_second_raa, as_third_cs) = get_revoke_commit_msgs ! ( nodes[ 0 ] , nodes[ 1 ] . node. get_our_node_id( ) ) ;
2288
+
2289
+ nodes[ 1 ] . node . handle_revoke_and_ack ( & nodes[ 0 ] . node . get_our_node_id ( ) , & as_second_raa) ;
2290
+ check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
2291
+ let bs_second_fail_update = get_htlc_update_msgs ! ( nodes[ 1 ] , nodes[ 0 ] . node. get_our_node_id( ) ) ;
2292
+
2293
+ nodes[ 1 ] . node . handle_commitment_signed ( & nodes[ 0 ] . node . get_our_node_id ( ) , & as_third_cs) ;
2294
+ check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
2295
+ let bs_third_raa = get_event_msg ! ( nodes[ 1 ] , MessageSendEvent :: SendRevokeAndACK , nodes[ 0 ] . node. get_our_node_id( ) ) ;
2296
+
2297
+ nodes[ 0 ] . node . handle_update_fail_htlc ( & nodes[ 1 ] . node . get_our_node_id ( ) , & bs_second_fail_update. update_fail_htlcs [ 0 ] ) ;
2298
+ nodes[ 0 ] . node . handle_commitment_signed ( & nodes[ 1 ] . node . get_our_node_id ( ) , & bs_second_fail_update. commitment_signed ) ;
2299
+ check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
2300
+
2301
+ nodes[ 0 ] . node . handle_revoke_and_ack ( & nodes[ 1 ] . node . get_our_node_id ( ) , & bs_third_raa) ;
2302
+ check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
2303
+ let ( as_third_raa, as_fourth_cs) = get_revoke_commit_msgs ! ( nodes[ 0 ] , nodes[ 1 ] . node. get_our_node_id( ) ) ;
2304
+
2305
+ nodes[ 1 ] . node . handle_revoke_and_ack ( & nodes[ 0 ] . node . get_our_node_id ( ) , & as_third_raa) ;
2306
+ check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
2307
+ nodes[ 1 ] . node . handle_commitment_signed ( & nodes[ 0 ] . node . get_our_node_id ( ) , & as_fourth_cs) ;
2308
+ check_added_monitors ! ( nodes[ 1 ] , 1 ) ;
2309
+ let bs_fourth_raa = get_event_msg ! ( nodes[ 1 ] , MessageSendEvent :: SendRevokeAndACK , nodes[ 0 ] . node. get_our_node_id( ) ) ;
2310
+
2311
+ nodes[ 0 ] . node . handle_revoke_and_ack ( & nodes[ 1 ] . node . get_our_node_id ( ) , & bs_fourth_raa) ;
2312
+ check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
2313
+
2314
+ // At this point A has sent two HTLCs which both failed due to lack of fee. It now has two
2315
+ // pending `PaymentPathFailed` events, one with `all_paths_failed` unset, and the second
2316
+ // with it set. The first event will use up the only retry we are allowed, with the second
2317
+ // `PaymentPathFailed` being passed up to the user (us, in this case). Previously, we'd
2318
+ // treated this as "HTLC complete" and dropped the retry counter, causing us to retry again
2319
+ // if the final HTLC failed.
2320
+ let mut events = nodes[ 0 ] . node . get_and_clear_pending_events ( ) ;
2321
+ assert_eq ! ( events. len( ) , 4 ) ;
2322
+ match events[ 0 ] {
2323
+ Event :: PaymentPathFailed { payment_hash : ev_payment_hash, payment_failed_permanently, .. } => {
2324
+ assert_eq ! ( payment_hash, ev_payment_hash) ;
2325
+ assert_eq ! ( payment_failed_permanently, false ) ;
2326
+ } ,
2327
+ _ => panic ! ( "Unexpected event" ) ,
2328
+ }
2329
+ match events[ 1 ] {
2330
+ Event :: PendingHTLCsForwardable { .. } => { } ,
2331
+ _ => panic ! ( "Unexpected event" ) ,
2332
+ }
2333
+ match events[ 2 ] {
2334
+ Event :: PaymentPathFailed { payment_hash : ev_payment_hash, payment_failed_permanently, .. } => {
2335
+ assert_eq ! ( payment_hash, ev_payment_hash) ;
2336
+ assert_eq ! ( payment_failed_permanently, false ) ;
2337
+ } ,
2338
+ _ => panic ! ( "Unexpected event" ) ,
2339
+ }
2340
+ match events[ 3 ] {
2341
+ Event :: PendingHTLCsForwardable { .. } => { } ,
2342
+ _ => panic ! ( "Unexpected event" ) ,
2343
+ }
2344
+
2345
+ nodes[ 0 ] . node . process_pending_htlc_forwards ( ) ;
2346
+ let retry_htlc_updates = SendEvent :: from_node ( & nodes[ 0 ] ) ;
2347
+ check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
2348
+
2349
+ nodes[ 1 ] . node . handle_update_add_htlc ( & nodes[ 0 ] . node . get_our_node_id ( ) , & retry_htlc_updates. msgs [ 0 ] ) ;
2350
+ commitment_signed_dance ! ( nodes[ 1 ] , nodes[ 0 ] , & retry_htlc_updates. commitment_msg, false , true ) ;
2351
+ let bs_fail_update = get_htlc_update_msgs ! ( nodes[ 1 ] , nodes[ 0 ] . node. get_our_node_id( ) ) ;
2352
+ nodes[ 0 ] . node . handle_update_fail_htlc ( & nodes[ 1 ] . node . get_our_node_id ( ) , & bs_fail_update. update_fail_htlcs [ 0 ] ) ;
2353
+ commitment_signed_dance ! ( nodes[ 0 ] , nodes[ 1 ] , & bs_fail_update. commitment_signed, false , true ) ;
2354
+
2355
+ let mut events = nodes[ 0 ] . node . get_and_clear_pending_events ( ) ;
2356
+ assert_eq ! ( events. len( ) , 1 ) ;
2357
+ match events[ 0 ] {
2358
+ Event :: PaymentPathFailed { payment_hash : ev_payment_hash, payment_failed_permanently, .. } => {
2359
+ assert_eq ! ( payment_hash, ev_payment_hash) ;
2360
+ assert_eq ! ( payment_failed_permanently, false ) ;
2361
+ } ,
2362
+ _ => panic ! ( "Unexpected event" ) ,
2363
+ }
2364
+ nodes[ 0 ] . node . abandon_payment ( PaymentId ( payment_hash. 0 ) ) ;
2365
+ events = nodes[ 0 ] . node . get_and_clear_pending_events ( ) ;
2366
+ assert_eq ! ( events. len( ) , 1 ) ;
2367
+ match events[ 0 ] {
2368
+ Event :: PaymentFailed { payment_hash : ref ev_payment_hash, payment_id : ref ev_payment_id } => {
2369
+ assert_eq ! ( payment_hash, * ev_payment_hash) ;
2370
+ assert_eq ! ( PaymentId ( payment_hash. 0 ) , * ev_payment_id) ;
2371
+ } ,
2372
+ _ => panic ! ( "Unexpected event" ) ,
2373
+ }
2374
+ }
0 commit comments