@@ -127,6 +127,11 @@ fn test_async_commitment_signature_for_funding_signed() {
127127
128128#[ test]
129129fn 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 ) {
130135 let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
131136 let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
132137 let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
@@ -154,23 +159,33 @@ fn test_async_commitment_signature_for_commitment_signed() {
154159
155160 // Mark dst's signer as unavailable and handle src's commitment_signed: while dst won't yet have a
156161 // `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 ) ;
157163 dst. disable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, SignerOp :: SignCounterpartyCommitment ) ;
158164 dst. node . handle_commitment_signed ( & src. node . get_our_node_id ( ) , & payment_event. commitment_msg ) ;
159165 check_added_monitors ( dst, 1 ) ;
160166
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 ( ) ) ;
171178 } 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+ }
174189}
175190
176191#[ test]
@@ -272,9 +287,125 @@ fn test_async_commitment_signature_for_funding_signed_0conf() {
272287 assert_eq ! ( nodes[ 1 ] . node. list_usable_channels( ) . len( ) , 1 ) ;
273288}
274289
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+
275404#[ test]
276405fn 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 ) ;
278409}
279410
280411#[ test]
@@ -283,18 +414,18 @@ fn test_async_commitment_signature_peer_disconnect_signer_restored_before_monito
283414 // and needed to send a CS, that if our signer becomes available before the monitor
284415 // update completes, then we don't send duplicate messages upon calling `signer_unblocked`
285416 // after the monitor update completes.
286- do_test_async_commitment_signature_peer_disconnect ( 1 ) ;
417+ do_test_async_commitment_signature_peer_disconnect ( UnblockSignerAcrossDisconnectCase :: BeforeMonitorRestored ) ;
287418}
288419
289420#[ test]
290421fn test_async_commitment_signature_peer_disconnect_signer_restored_before_reestablish ( ) {
291422 // This tests that if we tried to send a commitment_signed, but our signer was blocked,
292423 // if we disconnect, reconnect, the signer becomes available, then handle channel_reestablish,
293424 // 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 ) ;
295426}
296427
297- fn do_test_async_commitment_signature_peer_disconnect ( test_case : u8 ) {
428+ fn do_test_async_commitment_signature_peer_disconnect ( test_case : UnblockSignerAcrossDisconnectCase ) {
298429 let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
299430 let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
300431 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) {
320451
321452 dst. node . handle_update_add_htlc ( & src. node . get_our_node_id ( ) , & payment_event. msgs [ 0 ] ) ;
322453
323- if test_case == 1 {
454+ if test_case == UnblockSignerAcrossDisconnectCase :: BeforeMonitorRestored {
324455 // Fail to persist the monitor update when handling the commitment_signed.
325456 chanmon_cfgs[ 1 ] . persister . set_update_ret ( ChannelMonitorUpdateStatus :: InProgress ) ;
326457 }
@@ -331,7 +462,7 @@ fn do_test_async_commitment_signature_peer_disconnect(test_case: u8) {
331462 dst. node . handle_commitment_signed ( & src. node . get_our_node_id ( ) , & payment_event. commitment_msg ) ;
332463 check_added_monitors ( dst, 1 ) ;
333464
334- if test_case != 1 {
465+ if test_case != UnblockSignerAcrossDisconnectCase :: BeforeMonitorRestored {
335466 get_event_msg ! ( dst, MessageSendEvent :: SendRevokeAndACK , src. node. get_our_node_id( ) ) ;
336467 }
337468
@@ -351,14 +482,14 @@ fn do_test_async_commitment_signature_peer_disconnect(test_case: u8) {
351482 let reestablish_2 = get_chan_reestablish_msgs ! ( dst, src) ;
352483 assert_eq ! ( reestablish_2. len( ) , 1 ) ;
353484
354- if test_case == 2 {
485+ if test_case == UnblockSignerAcrossDisconnectCase :: BeforeReestablish {
355486 // Reenable the signer before the reestablish.
356487 dst. enable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, SignerOp :: SignCounterpartyCommitment ) ;
357488 }
358489
359490 dst. node . handle_channel_reestablish ( & src. node . get_our_node_id ( ) , & reestablish_1[ 0 ] ) ;
360491
361- if test_case == 1 {
492+ if test_case == UnblockSignerAcrossDisconnectCase :: BeforeMonitorRestored {
362493 dst. enable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, SignerOp :: SignCounterpartyCommitment ) ;
363494 chanmon_cfgs[ 1 ] . persister . set_update_ret ( ChannelMonitorUpdateStatus :: Completed ) ;
364495 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) {
369500 // Expect the RAA
370501 let ( _, revoke_and_ack, commitment_signed, _) = handle_chan_reestablish_msgs ! ( dst, src) ;
371502 assert ! ( revoke_and_ack. is_some( ) ) ;
372- if test_case == 0 {
503+ if test_case == UnblockSignerAcrossDisconnectCase :: AtEnd {
373504 assert ! ( commitment_signed. is_none( ) ) ;
374505 } else {
375506 assert ! ( commitment_signed. is_some( ) ) ;
@@ -379,7 +510,7 @@ fn do_test_async_commitment_signature_peer_disconnect(test_case: u8) {
379510 dst. enable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, SignerOp :: SignCounterpartyCommitment ) ;
380511 dst. node . signer_unblocked ( Some ( ( src. node . get_our_node_id ( ) , chan_id) ) ) ;
381512
382- if test_case == 0 {
513+ if test_case == UnblockSignerAcrossDisconnectCase :: AtEnd {
383514 let ( _, _, commitment_signed, _) = handle_chan_reestablish_msgs ! ( dst, src) ;
384515 assert ! ( commitment_signed. is_some( ) ) ;
385516 } else {
0 commit comments