@@ -273,7 +273,28 @@ fn test_async_commitment_signature_for_funding_signed_0conf() {
273
273
}
274
274
275
275
#[ test]
276
- fn test_async_commitment_signature_for_peer_disconnect ( ) {
276
+ fn test_async_commitment_signature_peer_disconnect ( ) {
277
+ do_test_async_commitment_signature_peer_disconnect ( 0 ) ;
278
+ }
279
+
280
+ #[ test]
281
+ fn test_async_commitment_signature_peer_disconnect_signer_restored_before_monitor_completion ( ) {
282
+ // This tests that if we were pending a monitor update completion across a disconnect,
283
+ // and needed to send a CS, that if our signer becomes available before the monitor
284
+ // update completes, then we don't send duplicate messages upon calling `signer_unblocked`
285
+ // after the monitor update completes.
286
+ do_test_async_commitment_signature_peer_disconnect ( 1 ) ;
287
+ }
288
+
289
+ #[ test]
290
+ fn test_async_commitment_signature_peer_disconnect_signer_restored_before_reestablish ( ) {
291
+ // This tests that if we tried to send a commitment_signed, but our signer was blocked,
292
+ // if we disconnect, reconnect, the signer becomes available, then handle channel_reestablish,
293
+ // that we don't send duplicate messages upon calling `signer_unblocked`.
294
+ do_test_async_commitment_signature_peer_disconnect ( 2 ) ;
295
+ }
296
+
297
+ fn do_test_async_commitment_signature_peer_disconnect ( test_case : u8 ) {
277
298
let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
278
299
let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
279
300
let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
@@ -299,34 +320,72 @@ fn test_async_commitment_signature_for_peer_disconnect() {
299
320
300
321
dst. node . handle_update_add_htlc ( & src. node . get_our_node_id ( ) , & payment_event. msgs [ 0 ] ) ;
301
322
323
+ if test_case == 1 {
324
+ // Fail to persist the monitor update when handling the commitment_signed.
325
+ chanmon_cfgs[ 1 ] . persister . set_update_ret ( ChannelMonitorUpdateStatus :: InProgress ) ;
326
+ }
327
+
302
328
// Mark dst's signer as unavailable and handle src's commitment_signed: while dst won't yet have a
303
329
// `commitment_signed` of its own to offer, it should publish a `revoke_and_ack`.
304
330
dst. disable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, SignerOp :: SignCounterpartyCommitment ) ;
305
331
dst. node . handle_commitment_signed ( & src. node . get_our_node_id ( ) , & payment_event. commitment_msg ) ;
306
332
check_added_monitors ( dst, 1 ) ;
307
333
308
- get_event_msg ! ( dst, MessageSendEvent :: SendRevokeAndACK , src. node. get_our_node_id( ) ) ;
334
+ if test_case != 1 {
335
+ get_event_msg ! ( dst, MessageSendEvent :: SendRevokeAndACK , src. node. get_our_node_id( ) ) ;
336
+ }
309
337
310
338
// Now disconnect and reconnect the peers.
311
339
src. node . peer_disconnected ( & dst. node . get_our_node_id ( ) ) ;
312
340
dst. node . peer_disconnected ( & src. node . get_our_node_id ( ) ) ;
313
- let mut reconnect_args = ReconnectArgs :: new ( & nodes[ 0 ] , & nodes[ 1 ] ) ;
314
- reconnect_args. send_channel_ready = ( false , false ) ;
315
- reconnect_args. pending_raa = ( true , false ) ;
316
- reconnect_nodes ( reconnect_args) ;
341
+
342
+ // do reestablish stuff
343
+ src. node . peer_connected ( & dst. node . get_our_node_id ( ) , & msgs:: Init {
344
+ features : dst. node . init_features ( ) , networks : None , remote_network_address : None
345
+ } , true ) . unwrap ( ) ;
346
+ let reestablish_1 = get_chan_reestablish_msgs ! ( src, dst) ;
347
+ assert_eq ! ( reestablish_1. len( ) , 1 ) ;
348
+ dst. node . peer_connected ( & src. node . get_our_node_id ( ) , & msgs:: Init {
349
+ features : src. node . init_features ( ) , networks : None , remote_network_address : None
350
+ } , false ) . unwrap ( ) ;
351
+ let reestablish_2 = get_chan_reestablish_msgs ! ( dst, src) ;
352
+ assert_eq ! ( reestablish_2. len( ) , 1 ) ;
353
+
354
+ if test_case == 2 {
355
+ // Reenable the signer before the reestablish.
356
+ dst. enable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, SignerOp :: SignCounterpartyCommitment ) ;
357
+ }
358
+
359
+ dst. node . handle_channel_reestablish ( & src. node . get_our_node_id ( ) , & reestablish_1[ 0 ] ) ;
360
+
361
+ if test_case == 1 {
362
+ dst. enable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, SignerOp :: SignCounterpartyCommitment ) ;
363
+ chanmon_cfgs[ 1 ] . persister . set_update_ret ( ChannelMonitorUpdateStatus :: Completed ) ;
364
+ let ( outpoint, latest_update, _) = dst. chain_monitor . latest_monitor_update_id . lock ( ) . unwrap ( ) . get ( & chan_id) . unwrap ( ) . clone ( ) ;
365
+ dst. chain_monitor . chain_monitor . force_channel_monitor_updated ( outpoint, latest_update) ;
366
+ check_added_monitors ! ( dst, 0 ) ;
367
+ }
368
+
369
+ // Expect the RAA
370
+ let ( _, revoke_and_ack, commitment_signed, _) = handle_chan_reestablish_msgs ! ( dst, src) ;
371
+ assert ! ( revoke_and_ack. is_some( ) ) ;
372
+ if test_case == 0 {
373
+ assert ! ( commitment_signed. is_none( ) ) ;
374
+ } else {
375
+ assert ! ( commitment_signed. is_some( ) ) ;
376
+ }
317
377
318
378
// Mark dst's signer as available and retry: we now expect to see dst's `commitment_signed`.
319
379
dst. enable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, SignerOp :: SignCounterpartyCommitment ) ;
320
380
dst. node . signer_unblocked ( Some ( ( src. node . get_our_node_id ( ) , chan_id) ) ) ;
321
381
322
- {
323
- let events = dst. node . get_and_clear_pending_msg_events ( ) ;
324
- assert_eq ! ( events. len( ) , 1 , "expected one message, got {}" , events. len( ) ) ;
325
- if let MessageSendEvent :: UpdateHTLCs { ref node_id, .. } = events[ 0 ] {
326
- assert_eq ! ( node_id, & src. node. get_our_node_id( ) ) ;
327
- } else {
328
- panic ! ( "expected UpdateHTLCs message, not {:?}" , events[ 0 ] ) ;
329
- } ;
382
+ if test_case == 0 {
383
+ let ( _, _, commitment_signed, _) = handle_chan_reestablish_msgs ! ( dst, src) ;
384
+ assert ! ( commitment_signed. is_some( ) ) ;
385
+ } else {
386
+ // Make sure we don't double send the CS.
387
+ let ( _, _, commitment_signed, _) = handle_chan_reestablish_msgs ! ( dst, src) ;
388
+ assert ! ( commitment_signed. is_none( ) ) ;
330
389
}
331
390
}
332
391
0 commit comments