1010//! Tests for asynchronous signing. These tests verify that the channel state machine behaves
1111//! properly with a signer implementation that asynchronously derives signatures.
1212
13+ use std:: collections:: HashSet ;
14+
1315use bitcoin:: { Transaction , TxOut , TxIn , Amount } ;
1416use bitcoin:: blockdata:: locktime:: absolute:: LockTime ;
1517use bitcoin:: transaction:: Version ;
1618
1719use crate :: chain:: channelmonitor:: LATENCY_GRACE_PERIOD_BLOCKS ;
1820use crate :: chain:: ChannelMonitorUpdateStatus ;
1921use crate :: events:: bump_transaction:: WalletSource ;
20- use crate :: events:: { ClosureReason , Event , MessageSendEvent , MessageSendEventsProvider , PaymentPurpose } ;
22+ use crate :: events:: { ClosureReason , Event , MessageSendEvent , MessageSendEventsProvider } ;
2123use crate :: ln:: { functional_test_utils:: * , msgs} ;
2224use crate :: ln:: msgs:: ChannelMessageHandler ;
2325use crate :: ln:: channelmanager:: { PaymentId , RAACommitmentOrder , RecipientOnionFields } ;
2426use crate :: util:: test_channel_signer:: SignerOp ;
27+ use crate :: util:: logger:: Logger ;
2528
2629#[ test]
2730fn test_async_commitment_signature_for_funding_created ( ) {
@@ -127,11 +130,17 @@ fn test_async_commitment_signature_for_funding_signed() {
127130
128131#[ test]
129132fn 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 ) ;
133+ for i in 0 ..=8 {
134+ let enable_signer_op_order = vec ! [
135+ SignerOp :: GetPerCommitmentPoint ,
136+ SignerOp :: ReleaseCommitmentSecret ,
137+ SignerOp :: SignCounterpartyCommitment ,
138+ ] . into_iter ( ) . filter ( |& op| i & ( 1 << op as u8 ) != 0 ) . collect ( ) ;
139+ do_test_async_commitment_signature_for_commitment_signed_revoke_and_ack ( enable_signer_op_order) ;
140+ }
132141}
133142
134- fn do_test_async_commitment_signature_for_commitment_signed_revoke_and_ack ( enable_sign_counterparty_commit_first : bool ) {
143+ fn do_test_async_commitment_signature_for_commitment_signed_revoke_and_ack ( enable_signer_op_order : Vec < SignerOp > ) {
135144 let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
136145 let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
137146 let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
@@ -160,31 +169,33 @@ fn do_test_async_commitment_signature_for_commitment_signed_revoke_and_ack(enabl
160169 // Mark dst's signer as unavailable and handle src's commitment_signed: while dst won't yet have a
161170 // `commitment_signed` of its own to offer, it should publish a `revoke_and_ack`.
162171 dst. disable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, SignerOp :: GetPerCommitmentPoint ) ;
172+ dst. disable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, SignerOp :: ReleaseCommitmentSecret ) ;
163173 dst. disable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, SignerOp :: SignCounterpartyCommitment ) ;
164174 dst. node . handle_commitment_signed ( & src. node . get_our_node_id ( ) , & payment_event. commitment_msg ) ;
165175 check_added_monitors ( dst, 1 ) ;
166176
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 ) ;
177+ let mut enabled_signer_ops = HashSet :: new ( ) ;
178+ log_trace ! ( dst. logger, "enable_signer_op_order={:?}" , enable_signer_op_order) ;
179+ for op in enable_signer_op_order {
180+ enabled_signer_ops. insert ( op) ;
181+ dst. enable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, op) ;
170182 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( ) ) ;
173183
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 ( ) ) ;
178- } else {
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 ( ) ) ;
184+ if enabled_signer_ops. contains ( & SignerOp :: GetPerCommitmentPoint ) && enabled_signer_ops. contains ( & SignerOp :: ReleaseCommitmentSecret ) {
185+ // We are just able to send revoke_and_ack
186+ if op == SignerOp :: GetPerCommitmentPoint || op == SignerOp :: ReleaseCommitmentSecret {
187+ get_event_msg ! ( dst, MessageSendEvent :: SendRevokeAndACK , src. node. get_our_node_id( ) ) ;
188+ }
189+ // We either just sent or previously sent revoke_and_ack
190+ // and now we are able to send commitment_signed
191+ if op == SignerOp :: SignCounterpartyCommitment {
192+ get_htlc_update_msgs ( dst, & src. node . get_our_node_id ( ) ) ;
193+ }
194+ } else {
195+ // We can't send either message until RAA is unblocked
196+ let events = dst. node . get_and_clear_pending_msg_events ( ) ;
197+ assert ! ( events. is_empty( ) , "expected no message, got {}" , events. len( ) ) ;
198+ }
188199 }
189200}
190201
@@ -296,12 +307,22 @@ enum UnblockSignerAcrossDisconnectCase {
296307
297308#[ test]
298309fn 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 ) ;
310+ do_test_async_raa_peer_disconnect ( UnblockSignerAcrossDisconnectCase :: AtEnd , true ) ;
311+ do_test_async_raa_peer_disconnect ( UnblockSignerAcrossDisconnectCase :: AtEnd , false ) ;
312+ do_test_async_raa_peer_disconnect ( UnblockSignerAcrossDisconnectCase :: BeforeMonitorRestored , true ) ;
313+ do_test_async_raa_peer_disconnect ( UnblockSignerAcrossDisconnectCase :: BeforeMonitorRestored , false ) ;
314+ do_test_async_raa_peer_disconnect ( UnblockSignerAcrossDisconnectCase :: BeforeReestablish , true ) ;
315+ do_test_async_raa_peer_disconnect ( UnblockSignerAcrossDisconnectCase :: BeforeReestablish , false ) ;
302316}
303317
304- fn do_test_async_raa_peer_disconnect ( test_case : UnblockSignerAcrossDisconnectCase ) {
318+ fn do_test_async_raa_peer_disconnect ( test_case : UnblockSignerAcrossDisconnectCase , raa_blocked_by_commit_point : bool ) {
319+ // `raa_blocked_by_commit_point` determines whether we block the RAA by blocking the
320+ // signer on `GetPerCommitmentPoint` or `ReleaseCommitmentSecret`.
321+ let block_raa_signer_op = if raa_blocked_by_commit_point {
322+ SignerOp :: GetPerCommitmentPoint
323+ } else {
324+ SignerOp :: ReleaseCommitmentSecret
325+ } ;
305326 let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
306327 let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
307328 let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
@@ -334,7 +355,7 @@ fn do_test_async_raa_peer_disconnect(test_case: UnblockSignerAcrossDisconnectCas
334355
335356 // Mark dst's signer as unavailable and handle src's commitment_signed: while dst won't yet have a
336357 // `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 ) ;
358+ dst. disable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, block_raa_signer_op ) ;
338359 dst. node . handle_commitment_signed ( & src. node . get_our_node_id ( ) , & payment_event. commitment_msg ) ;
339360 check_added_monitors ( dst, 1 ) ;
340361
@@ -359,13 +380,13 @@ fn do_test_async_raa_peer_disconnect(test_case: UnblockSignerAcrossDisconnectCas
359380
360381 if test_case == UnblockSignerAcrossDisconnectCase :: BeforeReestablish {
361382 // Reenable the signer before the reestablish.
362- dst. enable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, SignerOp :: GetPerCommitmentPoint ) ;
383+ dst. enable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, block_raa_signer_op ) ;
363384 }
364385
365386 dst. node . handle_channel_reestablish ( & src. node . get_our_node_id ( ) , & reestablish_1[ 0 ] ) ;
366387
367388 if test_case == UnblockSignerAcrossDisconnectCase :: BeforeMonitorRestored {
368- dst. enable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, SignerOp :: GetPerCommitmentPoint ) ;
389+ dst. enable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, block_raa_signer_op ) ;
369390 chanmon_cfgs[ 1 ] . persister . set_update_ret ( ChannelMonitorUpdateStatus :: Completed ) ;
370391 let ( outpoint, latest_update, _) = dst. chain_monitor . latest_monitor_update_id . lock ( ) . unwrap ( ) . get ( & chan_id) . unwrap ( ) . clone ( ) ;
371392 dst. chain_monitor . chain_monitor . force_channel_monitor_updated ( outpoint, latest_update) ;
@@ -384,7 +405,7 @@ fn do_test_async_raa_peer_disconnect(test_case: UnblockSignerAcrossDisconnectCas
384405 }
385406
386407 // 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 ) ;
408+ dst. enable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, block_raa_signer_op ) ;
388409 dst. node . signer_unblocked ( Some ( ( src. node . get_our_node_id ( ) , chan_id) ) ) ;
389410
390411 if test_case == UnblockSignerAcrossDisconnectCase :: AtEnd {
0 commit comments