@@ -127,6 +127,11 @@ fn test_async_commitment_signature_for_funding_signed() {
127
127
128
128
#[ test]
129
129
fn test_async_commitment_signature_for_commitment_signed ( ) {
130
+ do_test_async_commitment_signature_for_commitment_signed_revoke_and_ack ( true ) ;
131
+ do_test_async_commitment_signature_for_commitment_signed_revoke_and_ack ( false ) ;
132
+ }
133
+
134
+ fn do_test_async_commitment_signature_for_commitment_signed_revoke_and_ack ( enable_sign_counterparty_commit_first : bool ) {
130
135
let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
131
136
let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
132
137
let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
@@ -154,23 +159,33 @@ fn test_async_commitment_signature_for_commitment_signed() {
154
159
155
160
// Mark dst's signer as unavailable and handle src's commitment_signed: while dst won't yet have a
156
161
// `commitment_signed` of its own to offer, it should publish a `revoke_and_ack`.
162
+ dst. disable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, SignerOp :: GetPerCommitmentPoint ) ;
157
163
dst. disable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, SignerOp :: SignCounterpartyCommitment ) ;
158
164
dst. node . handle_commitment_signed ( & src. node . get_our_node_id ( ) , & payment_event. commitment_msg ) ;
159
165
check_added_monitors ( dst, 1 ) ;
160
166
161
- get_event_msg ! ( dst, MessageSendEvent :: SendRevokeAndACK , src. node. get_our_node_id( ) ) ;
162
-
163
- // Mark dst's signer as available and retry: we now expect to see dst's `commitment_signed`.
164
- dst. enable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, SignerOp :: SignCounterpartyCommitment ) ;
165
- dst. node . signer_unblocked ( Some ( ( src. node . get_our_node_id ( ) , chan_id) ) ) ;
166
-
167
- let events = dst. node . get_and_clear_pending_msg_events ( ) ;
168
- assert_eq ! ( events. len( ) , 1 , "expected one message, got {}" , events. len( ) ) ;
169
- if let MessageSendEvent :: UpdateHTLCs { ref node_id, .. } = events[ 0 ] {
170
- assert_eq ! ( node_id, & src. node. get_our_node_id( ) ) ;
167
+ if enable_sign_counterparty_commit_first {
168
+ // Unblock CS -> no messages should be sent, since we must send RAA first.
169
+ dst. enable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, SignerOp :: SignCounterpartyCommitment ) ;
170
+ dst. node . signer_unblocked ( Some ( ( src. node . get_our_node_id ( ) , chan_id) ) ) ;
171
+ let events = dst. node . get_and_clear_pending_msg_events ( ) ;
172
+ assert ! ( events. is_empty( ) , "expected no message, got {}" , events. len( ) ) ;
173
+
174
+ // Unblock revoke_and_ack -> we should send both RAA + CS.
175
+ dst. enable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, SignerOp :: GetPerCommitmentPoint ) ;
176
+ dst. node . signer_unblocked ( Some ( ( src. node . get_our_node_id ( ) , chan_id) ) ) ;
177
+ get_revoke_commit_msgs ( & dst, & src. node . get_our_node_id ( ) ) ;
171
178
} else {
172
- panic ! ( "expected UpdateHTLCs message, not {:?}" , events[ 0 ] ) ;
173
- } ;
179
+ // Unblock revoke_and_ack -> we should send just RAA.
180
+ dst. enable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, SignerOp :: GetPerCommitmentPoint ) ;
181
+ dst. node . signer_unblocked ( Some ( ( src. node . get_our_node_id ( ) , chan_id) ) ) ;
182
+ get_event_msg ! ( dst, MessageSendEvent :: SendRevokeAndACK , src. node. get_our_node_id( ) ) ;
183
+
184
+ // Unblock commitment signed -> we should send CS.
185
+ dst. enable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, SignerOp :: SignCounterpartyCommitment ) ;
186
+ dst. node . signer_unblocked ( Some ( ( src. node . get_our_node_id ( ) , chan_id) ) ) ;
187
+ get_htlc_update_msgs ( dst, & src. node . get_our_node_id ( ) ) ;
188
+ }
174
189
}
175
190
176
191
#[ test]
@@ -272,9 +287,125 @@ fn test_async_commitment_signature_for_funding_signed_0conf() {
272
287
assert_eq ! ( nodes[ 1 ] . node. list_usable_channels( ) . len( ) , 1 ) ;
273
288
}
274
289
290
+ #[ derive( PartialEq ) ]
291
+ enum UnblockSignerAcrossDisconnectCase {
292
+ AtEnd ,
293
+ BeforeMonitorRestored ,
294
+ BeforeReestablish ,
295
+ }
296
+
297
+ #[ test]
298
+ fn test_async_raa_peer_disconnect ( ) {
299
+ do_test_async_raa_peer_disconnect ( UnblockSignerAcrossDisconnectCase :: AtEnd ) ;
300
+ do_test_async_raa_peer_disconnect ( UnblockSignerAcrossDisconnectCase :: BeforeMonitorRestored ) ;
301
+ do_test_async_raa_peer_disconnect ( UnblockSignerAcrossDisconnectCase :: BeforeReestablish ) ;
302
+ }
303
+
304
+ fn do_test_async_raa_peer_disconnect ( test_case : UnblockSignerAcrossDisconnectCase ) {
305
+ let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
306
+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
307
+ let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
308
+ let nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
309
+ let ( _, _, chan_id, _) = create_announced_chan_between_nodes ( & nodes, 0 , 1 ) ;
310
+
311
+ // Send a payment.
312
+ let src = & nodes[ 0 ] ;
313
+ let dst = & nodes[ 1 ] ;
314
+ let ( route, our_payment_hash, _our_payment_preimage, our_payment_secret) = get_route_and_payment_hash ! ( src, dst, 8000000 ) ;
315
+ src. node . send_payment_with_route ( & route, our_payment_hash,
316
+ RecipientOnionFields :: secret_only ( our_payment_secret) , PaymentId ( our_payment_hash. 0 ) ) . unwrap ( ) ;
317
+ check_added_monitors ! ( src, 1 ) ;
318
+
319
+ // Pass the payment along the route.
320
+ let payment_event = {
321
+ let mut events = src. node . get_and_clear_pending_msg_events ( ) ;
322
+ assert_eq ! ( events. len( ) , 1 ) ;
323
+ SendEvent :: from_event ( events. remove ( 0 ) )
324
+ } ;
325
+ assert_eq ! ( payment_event. node_id, dst. node. get_our_node_id( ) ) ;
326
+ assert_eq ! ( payment_event. msgs. len( ) , 1 ) ;
327
+
328
+ dst. node . handle_update_add_htlc ( & src. node . get_our_node_id ( ) , & payment_event. msgs [ 0 ] ) ;
329
+
330
+ if test_case == UnblockSignerAcrossDisconnectCase :: BeforeMonitorRestored {
331
+ // Fail to persist the monitor update when handling the commitment_signed.
332
+ chanmon_cfgs[ 1 ] . persister . set_update_ret ( ChannelMonitorUpdateStatus :: InProgress ) ;
333
+ }
334
+
335
+ // Mark dst's signer as unavailable and handle src's commitment_signed: while dst won't yet have a
336
+ // `commitment_signed` of its own to offer, it should publish a `revoke_and_ack`.
337
+ dst. disable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, SignerOp :: GetPerCommitmentPoint ) ;
338
+ dst. node . handle_commitment_signed ( & src. node . get_our_node_id ( ) , & payment_event. commitment_msg ) ;
339
+ check_added_monitors ( dst, 1 ) ;
340
+
341
+ let events = dst. node . get_and_clear_pending_msg_events ( ) ;
342
+ assert ! ( events. is_empty( ) , "expected no message, got {}" , events. len( ) ) ;
343
+
344
+ // Now disconnect and reconnect the peers.
345
+ src. node . peer_disconnected ( & dst. node . get_our_node_id ( ) ) ;
346
+ dst. node . peer_disconnected ( & src. node . get_our_node_id ( ) ) ;
347
+
348
+ // do reestablish stuff
349
+ src. node . peer_connected ( & dst. node . get_our_node_id ( ) , & msgs:: Init {
350
+ features : dst. node . init_features ( ) , networks : None , remote_network_address : None
351
+ } , true ) . unwrap ( ) ;
352
+ let reestablish_1 = get_chan_reestablish_msgs ! ( src, dst) ;
353
+ assert_eq ! ( reestablish_1. len( ) , 1 ) ;
354
+ dst. node . peer_connected ( & src. node . get_our_node_id ( ) , & msgs:: Init {
355
+ features : src. node . init_features ( ) , networks : None , remote_network_address : None
356
+ } , false ) . unwrap ( ) ;
357
+ let reestablish_2 = get_chan_reestablish_msgs ! ( dst, src) ;
358
+ assert_eq ! ( reestablish_2. len( ) , 1 ) ;
359
+
360
+ if test_case == UnblockSignerAcrossDisconnectCase :: BeforeReestablish {
361
+ // Reenable the signer before the reestablish.
362
+ dst. enable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, SignerOp :: GetPerCommitmentPoint ) ;
363
+ }
364
+
365
+ dst. node . handle_channel_reestablish ( & src. node . get_our_node_id ( ) , & reestablish_1[ 0 ] ) ;
366
+
367
+ if test_case == UnblockSignerAcrossDisconnectCase :: BeforeMonitorRestored {
368
+ dst. enable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, SignerOp :: GetPerCommitmentPoint ) ;
369
+ chanmon_cfgs[ 1 ] . persister . set_update_ret ( ChannelMonitorUpdateStatus :: Completed ) ;
370
+ let ( outpoint, latest_update, _) = dst. chain_monitor . latest_monitor_update_id . lock ( ) . unwrap ( ) . get ( & chan_id) . unwrap ( ) . clone ( ) ;
371
+ dst. chain_monitor . chain_monitor . force_channel_monitor_updated ( outpoint, latest_update) ;
372
+ check_added_monitors ! ( dst, 0 ) ;
373
+ }
374
+
375
+ // Expect the RAA
376
+ let ( _, revoke_and_ack, commitment_signed, resend_order) = handle_chan_reestablish_msgs ! ( dst, src) ;
377
+ if test_case == UnblockSignerAcrossDisconnectCase :: AtEnd {
378
+ assert ! ( revoke_and_ack. is_none( ) ) ;
379
+ assert ! ( commitment_signed. is_none( ) ) ;
380
+ } else {
381
+ assert ! ( revoke_and_ack. is_some( ) ) ;
382
+ assert ! ( commitment_signed. is_some( ) ) ;
383
+ assert ! ( resend_order == RAACommitmentOrder :: RevokeAndACKFirst ) ;
384
+ }
385
+
386
+ // Mark dst's signer as available and retry: we now expect to see dst's RAA + CS.
387
+ dst. enable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, SignerOp :: GetPerCommitmentPoint ) ;
388
+ dst. node . signer_unblocked ( Some ( ( src. node . get_our_node_id ( ) , chan_id) ) ) ;
389
+
390
+ if test_case == UnblockSignerAcrossDisconnectCase :: AtEnd {
391
+ let ( _, revoke_and_ack, commitment_signed, resend_order) = handle_chan_reestablish_msgs ! ( dst, src) ;
392
+ assert ! ( revoke_and_ack. is_some( ) ) ;
393
+ assert ! ( commitment_signed. is_some( ) ) ;
394
+ assert ! ( resend_order == RAACommitmentOrder :: RevokeAndACKFirst ) ;
395
+ } else {
396
+ // Make sure we don't double send the RAA.
397
+ let ( _, revoke_and_ack, commitment_signed, _) = handle_chan_reestablish_msgs ! ( dst, src) ;
398
+ assert ! ( revoke_and_ack. is_none( ) ) ;
399
+ assert ! ( commitment_signed. is_none( ) ) ;
400
+ }
401
+ }
402
+
403
+
275
404
#[ test]
276
405
fn test_async_commitment_signature_peer_disconnect ( ) {
277
- do_test_async_commitment_signature_peer_disconnect ( 0 ) ;
406
+ // This tests that if our signer is blocked and gets unblocked
407
+ // after a peer disconnect + channel reestablish, we'll send the right messages.
408
+ do_test_async_commitment_signature_peer_disconnect ( UnblockSignerAcrossDisconnectCase :: AtEnd ) ;
278
409
}
279
410
280
411
#[ test]
@@ -283,18 +414,18 @@ fn test_async_commitment_signature_peer_disconnect_signer_restored_before_monito
283
414
// and needed to send a CS, that if our signer becomes available before the monitor
284
415
// update completes, then we don't send duplicate messages upon calling `signer_unblocked`
285
416
// after the monitor update completes.
286
- do_test_async_commitment_signature_peer_disconnect ( 1 ) ;
417
+ do_test_async_commitment_signature_peer_disconnect ( UnblockSignerAcrossDisconnectCase :: BeforeMonitorRestored ) ;
287
418
}
288
419
289
420
#[ test]
290
421
fn test_async_commitment_signature_peer_disconnect_signer_restored_before_reestablish ( ) {
291
422
// This tests that if we tried to send a commitment_signed, but our signer was blocked,
292
423
// if we disconnect, reconnect, the signer becomes available, then handle channel_reestablish,
293
424
// that we don't send duplicate messages upon calling `signer_unblocked`.
294
- do_test_async_commitment_signature_peer_disconnect ( 2 ) ;
425
+ do_test_async_commitment_signature_peer_disconnect ( UnblockSignerAcrossDisconnectCase :: BeforeReestablish ) ;
295
426
}
296
427
297
- fn do_test_async_commitment_signature_peer_disconnect ( test_case : u8 ) {
428
+ fn do_test_async_commitment_signature_peer_disconnect ( test_case : UnblockSignerAcrossDisconnectCase ) {
298
429
let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
299
430
let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
300
431
let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
@@ -320,7 +451,7 @@ fn do_test_async_commitment_signature_peer_disconnect(test_case: u8) {
320
451
321
452
dst. node . handle_update_add_htlc ( & src. node . get_our_node_id ( ) , & payment_event. msgs [ 0 ] ) ;
322
453
323
- if test_case == 1 {
454
+ if test_case == UnblockSignerAcrossDisconnectCase :: BeforeMonitorRestored {
324
455
// Fail to persist the monitor update when handling the commitment_signed.
325
456
chanmon_cfgs[ 1 ] . persister . set_update_ret ( ChannelMonitorUpdateStatus :: InProgress ) ;
326
457
}
@@ -331,7 +462,7 @@ fn do_test_async_commitment_signature_peer_disconnect(test_case: u8) {
331
462
dst. node . handle_commitment_signed ( & src. node . get_our_node_id ( ) , & payment_event. commitment_msg ) ;
332
463
check_added_monitors ( dst, 1 ) ;
333
464
334
- if test_case != 1 {
465
+ if test_case != UnblockSignerAcrossDisconnectCase :: BeforeMonitorRestored {
335
466
get_event_msg ! ( dst, MessageSendEvent :: SendRevokeAndACK , src. node. get_our_node_id( ) ) ;
336
467
}
337
468
@@ -351,14 +482,14 @@ fn do_test_async_commitment_signature_peer_disconnect(test_case: u8) {
351
482
let reestablish_2 = get_chan_reestablish_msgs ! ( dst, src) ;
352
483
assert_eq ! ( reestablish_2. len( ) , 1 ) ;
353
484
354
- if test_case == 2 {
485
+ if test_case == UnblockSignerAcrossDisconnectCase :: BeforeReestablish {
355
486
// Reenable the signer before the reestablish.
356
487
dst. enable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, SignerOp :: SignCounterpartyCommitment ) ;
357
488
}
358
489
359
490
dst. node . handle_channel_reestablish ( & src. node . get_our_node_id ( ) , & reestablish_1[ 0 ] ) ;
360
491
361
- if test_case == 1 {
492
+ if test_case == UnblockSignerAcrossDisconnectCase :: BeforeMonitorRestored {
362
493
dst. enable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, SignerOp :: SignCounterpartyCommitment ) ;
363
494
chanmon_cfgs[ 1 ] . persister . set_update_ret ( ChannelMonitorUpdateStatus :: Completed ) ;
364
495
let ( outpoint, latest_update, _) = dst. chain_monitor . latest_monitor_update_id . lock ( ) . unwrap ( ) . get ( & chan_id) . unwrap ( ) . clone ( ) ;
@@ -369,7 +500,7 @@ fn do_test_async_commitment_signature_peer_disconnect(test_case: u8) {
369
500
// Expect the RAA
370
501
let ( _, revoke_and_ack, commitment_signed, _) = handle_chan_reestablish_msgs ! ( dst, src) ;
371
502
assert ! ( revoke_and_ack. is_some( ) ) ;
372
- if test_case == 0 {
503
+ if test_case == UnblockSignerAcrossDisconnectCase :: AtEnd {
373
504
assert ! ( commitment_signed. is_none( ) ) ;
374
505
} else {
375
506
assert ! ( commitment_signed. is_some( ) ) ;
@@ -379,7 +510,7 @@ fn do_test_async_commitment_signature_peer_disconnect(test_case: u8) {
379
510
dst. enable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, SignerOp :: SignCounterpartyCommitment ) ;
380
511
dst. node . signer_unblocked ( Some ( ( src. node . get_our_node_id ( ) , chan_id) ) ) ;
381
512
382
- if test_case == 0 {
513
+ if test_case == UnblockSignerAcrossDisconnectCase :: AtEnd {
383
514
let ( _, _, commitment_signed, _) = handle_chan_reestablish_msgs ! ( dst, src) ;
384
515
assert ! ( commitment_signed. is_some( ) ) ;
385
516
} else {
0 commit comments