@@ -273,7 +273,28 @@ fn test_async_commitment_signature_for_funding_signed_0conf() {
273273}
274274
275275#[ 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 ) {
277298 let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
278299 let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
279300 let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
@@ -299,34 +320,72 @@ fn test_async_commitment_signature_for_peer_disconnect() {
299320
300321 dst. node . handle_update_add_htlc ( & src. node . get_our_node_id ( ) , & payment_event. msgs [ 0 ] ) ;
301322
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+
302328 // Mark dst's signer as unavailable and handle src's commitment_signed: while dst won't yet have a
303329 // `commitment_signed` of its own to offer, it should publish a `revoke_and_ack`.
304330 dst. disable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, SignerOp :: SignCounterpartyCommitment ) ;
305331 dst. node . handle_commitment_signed ( & src. node . get_our_node_id ( ) , & payment_event. commitment_msg ) ;
306332 check_added_monitors ( dst, 1 ) ;
307333
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+ }
309337
310338 // Now disconnect and reconnect the peers.
311339 src. node . peer_disconnected ( & dst. node . get_our_node_id ( ) ) ;
312340 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+ }
317377
318378 // Mark dst's signer as available and retry: we now expect to see dst's `commitment_signed`.
319379 dst. enable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, SignerOp :: SignCounterpartyCommitment ) ;
320380 dst. node . signer_unblocked ( Some ( ( src. node . get_our_node_id ( ) , chan_id) ) ) ;
321381
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( ) ) ;
330389 }
331390}
332391
0 commit comments