@@ -17,9 +17,9 @@ use crate::sign::EntropySource;
17
17
use crate :: chain:: transaction:: OutPoint ;
18
18
use crate :: events:: { ClosureReason , Event , HTLCDestination , MessageSendEvent , MessageSendEventsProvider , PathFailure , PaymentFailureReason } ;
19
19
use crate :: ln:: channel:: EXPIRE_PREV_CONFIG_TICKS ;
20
- use crate :: ln:: channelmanager:: { BREAKDOWN_TIMEOUT , ChannelManager , MPP_TIMEOUT_TICKS , MIN_CLTV_EXPIRY_DELTA , PaymentId , PaymentSendFailure , IDEMPOTENCY_TIMEOUT_TICKS , RecentPaymentDetails , RecipientOnionFields } ;
20
+ use crate :: ln:: channelmanager:: { BREAKDOWN_TIMEOUT , ChannelManager , MPP_TIMEOUT_TICKS , MIN_CLTV_EXPIRY_DELTA , PaymentId , PaymentSendFailure , IDEMPOTENCY_TIMEOUT_TICKS , RecentPaymentDetails , RecipientOnionFields , HTLCForwardInfo , PendingHTLCRouting , PendingAddHTLCInfo } ;
21
21
use crate :: ln:: features:: InvoiceFeatures ;
22
- use crate :: ln:: msgs;
22
+ use crate :: ln:: { msgs, PaymentSecret } ;
23
23
use crate :: ln:: msgs:: ChannelMessageHandler ;
24
24
use crate :: ln:: outbound_payment:: Retry ;
25
25
use crate :: routing:: gossip:: { EffectiveCapacity , RoutingFees } ;
@@ -236,6 +236,124 @@ fn mpp_receive_timeout() {
236
236
do_mpp_receive_timeout ( false ) ;
237
237
}
238
238
239
+ #[ test]
240
+ fn test_reject_mpp_keysend_htlc ( ) {
241
+ let mut reject_mpp_keysend_cfg = test_default_channel_config ( ) ;
242
+ reject_mpp_keysend_cfg. accept_mpp_keysend = false ;
243
+
244
+ let chanmon_cfgs = create_chanmon_cfgs ( 4 ) ;
245
+ let node_cfgs = create_node_cfgs ( 4 , & chanmon_cfgs) ;
246
+ let node_chanmgrs = create_node_chanmgrs ( 4 , & node_cfgs, & [ None , None , None , Some ( reject_mpp_keysend_cfg) ] ) ;
247
+ let nodes = create_network ( 4 , & node_cfgs, & node_chanmgrs) ;
248
+ let chan_1_id = create_announced_chan_between_nodes ( & nodes, 0 , 1 ) . 0 . contents . short_channel_id ;
249
+ let chan_2_id = create_announced_chan_between_nodes ( & nodes, 0 , 2 ) . 0 . contents . short_channel_id ;
250
+ let chan_3_id = create_announced_chan_between_nodes ( & nodes, 1 , 3 ) . 0 . contents . short_channel_id ;
251
+ let ( update_a, _, chan_4_channel_id, _) = create_announced_chan_between_nodes ( & nodes, 2 , 3 ) ;
252
+ let chan_4_id = update_a. contents . short_channel_id ;
253
+ let amount = 40_000 ;
254
+ let ( mut route, payment_hash, payment_preimage, _) = get_route_and_payment_hash ! ( nodes[ 0 ] , nodes[ 3 ] , amount) ;
255
+
256
+ // Pay along nodes[1]
257
+ route. paths [ 0 ] . hops [ 0 ] . pubkey = nodes[ 1 ] . node . get_our_node_id ( ) ;
258
+ route. paths [ 0 ] . hops [ 0 ] . short_channel_id = chan_1_id;
259
+ route. paths [ 0 ] . hops [ 1 ] . short_channel_id = chan_3_id;
260
+
261
+ let payment_id_0 = PaymentId ( nodes[ 0 ] . keys_manager . backing . get_secure_random_bytes ( ) ) ;
262
+ nodes[ 0 ] . node . send_spontaneous_payment ( & route, Some ( payment_preimage) , RecipientOnionFields :: spontaneous_empty ( ) , payment_id_0) . unwrap ( ) ;
263
+ check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
264
+
265
+ let update_0 = get_htlc_update_msgs ! ( nodes[ 0 ] , nodes[ 1 ] . node. get_our_node_id( ) ) ;
266
+ let update_add_0 = update_0. update_add_htlcs [ 0 ] . clone ( ) ;
267
+ nodes[ 1 ] . node . handle_update_add_htlc ( & nodes[ 0 ] . node . get_our_node_id ( ) , & update_add_0) ;
268
+ commitment_signed_dance ! ( nodes[ 1 ] , nodes[ 0 ] , & update_0. commitment_signed, false , true ) ;
269
+ expect_pending_htlcs_forwardable ! ( nodes[ 1 ] ) ;
270
+
271
+ check_added_monitors ! ( & nodes[ 1 ] , 1 ) ;
272
+ let update_1 = get_htlc_update_msgs ! ( nodes[ 1 ] , nodes[ 3 ] . node. get_our_node_id( ) ) ;
273
+ let update_add_1 = update_1. update_add_htlcs [ 0 ] . clone ( ) ;
274
+ nodes[ 3 ] . node . handle_update_add_htlc ( & nodes[ 1 ] . node . get_our_node_id ( ) , & update_add_1) ;
275
+ commitment_signed_dance ! ( nodes[ 3 ] , nodes[ 1 ] , update_1. commitment_signed, false , true ) ;
276
+
277
+ assert ! ( nodes[ 3 ] . node. get_and_clear_pending_msg_events( ) . is_empty( ) ) ;
278
+ for ( _, pending_forwards) in nodes[ 3 ] . node . forward_htlcs . lock ( ) . unwrap ( ) . iter_mut ( ) {
279
+ for f in pending_forwards. iter_mut ( ) {
280
+ match f {
281
+ & mut HTLCForwardInfo :: AddHTLC ( PendingAddHTLCInfo { ref mut forward_info, .. } ) => {
282
+ match forward_info. routing {
283
+ PendingHTLCRouting :: ReceiveKeysend { ref mut payment_data, .. } => {
284
+ * payment_data = Some ( msgs:: FinalOnionHopData {
285
+ payment_secret : PaymentSecret ( [ 42 ; 32 ] ) ,
286
+ total_msat : amount * 2 ,
287
+ } ) ;
288
+ } ,
289
+ _ => panic ! ( "Expected PendingHTLCRouting::ReceiveKeysend" ) ,
290
+ }
291
+ } ,
292
+ _ => { } ,
293
+ }
294
+ }
295
+ }
296
+ expect_pending_htlcs_forwardable ! ( nodes[ 3 ] ) ;
297
+
298
+ // Pay along nodes[2]
299
+ route. paths [ 0 ] . hops [ 0 ] . pubkey = nodes[ 2 ] . node . get_our_node_id ( ) ;
300
+ route. paths [ 0 ] . hops [ 0 ] . short_channel_id = chan_2_id;
301
+ route. paths [ 0 ] . hops [ 1 ] . short_channel_id = chan_4_id;
302
+
303
+ let payment_id_1 = PaymentId ( nodes[ 0 ] . keys_manager . backing . get_secure_random_bytes ( ) ) ;
304
+ nodes[ 0 ] . node . send_spontaneous_payment ( & route, Some ( payment_preimage) , RecipientOnionFields :: spontaneous_empty ( ) , payment_id_1) . unwrap ( ) ;
305
+ check_added_monitors ! ( nodes[ 0 ] , 1 ) ;
306
+
307
+ let update_2 = get_htlc_update_msgs ! ( nodes[ 0 ] , nodes[ 2 ] . node. get_our_node_id( ) ) ;
308
+ let update_add_2 = update_2. update_add_htlcs [ 0 ] . clone ( ) ;
309
+ nodes[ 2 ] . node . handle_update_add_htlc ( & nodes[ 0 ] . node . get_our_node_id ( ) , & update_add_2) ;
310
+ commitment_signed_dance ! ( nodes[ 2 ] , nodes[ 0 ] , & update_2. commitment_signed, false , true ) ;
311
+ expect_pending_htlcs_forwardable ! ( nodes[ 2 ] ) ;
312
+
313
+ check_added_monitors ! ( & nodes[ 2 ] , 1 ) ;
314
+ let update_3 = get_htlc_update_msgs ! ( nodes[ 2 ] , nodes[ 3 ] . node. get_our_node_id( ) ) ;
315
+ let update_add_3 = update_3. update_add_htlcs [ 0 ] . clone ( ) ;
316
+ nodes[ 3 ] . node . handle_update_add_htlc ( & nodes[ 2 ] . node . get_our_node_id ( ) , & update_add_3) ;
317
+ commitment_signed_dance ! ( nodes[ 3 ] , nodes[ 2 ] , update_3. commitment_signed, false , true ) ;
318
+
319
+ assert ! ( nodes[ 3 ] . node. get_and_clear_pending_msg_events( ) . is_empty( ) ) ;
320
+ for ( _, pending_forwards) in nodes[ 3 ] . node . forward_htlcs . lock ( ) . unwrap ( ) . iter_mut ( ) {
321
+ for f in pending_forwards. iter_mut ( ) {
322
+ match f {
323
+ & mut HTLCForwardInfo :: AddHTLC ( PendingAddHTLCInfo { ref mut forward_info, .. } ) => {
324
+ match forward_info. routing {
325
+ PendingHTLCRouting :: ReceiveKeysend { ref mut payment_data, .. } => {
326
+ * payment_data = Some ( msgs:: FinalOnionHopData {
327
+ payment_secret : PaymentSecret ( [ 42 ; 32 ] ) ,
328
+ total_msat : amount * 2 ,
329
+ } ) ;
330
+ } ,
331
+ _ => panic ! ( "Expected PendingHTLCRouting::ReceiveKeysend" ) ,
332
+ }
333
+ } ,
334
+ _ => { } ,
335
+ }
336
+ }
337
+ }
338
+ expect_pending_htlcs_forwardable ! ( nodes[ 3 ] ) ;
339
+ check_added_monitors ! ( nodes[ 3 ] , 1 ) ;
340
+
341
+ // Fail back along nodes[2]
342
+ let update_fail_0 = get_htlc_update_msgs ! ( & nodes[ 3 ] , & nodes[ 2 ] . node. get_our_node_id( ) ) ;
343
+ nodes[ 2 ] . node . handle_update_fail_htlc ( & nodes[ 3 ] . node . get_our_node_id ( ) , & update_fail_0. update_fail_htlcs [ 0 ] ) ;
344
+ commitment_signed_dance ! ( nodes[ 2 ] , nodes[ 3 ] , update_fail_0. commitment_signed, false ) ;
345
+ expect_pending_htlcs_forwardable_and_htlc_handling_failed ! ( nodes[ 2 ] , vec![ HTLCDestination :: NextHopChannel { node_id: Some ( nodes[ 3 ] . node. get_our_node_id( ) ) , channel_id: chan_4_channel_id } ] ) ;
346
+ check_added_monitors ! ( nodes[ 2 ] , 1 ) ;
347
+
348
+ let update_fail_1 = get_htlc_update_msgs ! ( nodes[ 2 ] , nodes[ 0 ] . node. get_our_node_id( ) ) ;
349
+ nodes[ 0 ] . node . handle_update_fail_htlc ( & nodes[ 2 ] . node . get_our_node_id ( ) , & update_fail_1. update_fail_htlcs [ 0 ] ) ;
350
+ commitment_signed_dance ! ( nodes[ 0 ] , nodes[ 2 ] , update_fail_1. commitment_signed, false ) ;
351
+
352
+ expect_payment_failed_conditions ( & nodes[ 0 ] , payment_hash, true , PaymentFailedConditions :: new ( ) ) ;
353
+ expect_pending_htlcs_forwardable_and_htlc_handling_failed ! ( nodes[ 3 ] , vec![ HTLCDestination :: FailedPayment { payment_hash } ] ) ;
354
+ }
355
+
356
+
239
357
#[ test]
240
358
fn no_pending_leak_on_initial_send_failure ( ) {
241
359
// In an earlier version of our payment tracking, we'd have a retry entry even when the initial
0 commit comments