10
10
//! Tests for asynchronous signing. These tests verify that the channel state machine behaves
11
11
//! properly with a signer implementation that asynchronously derives signatures.
12
12
13
+ use std:: collections:: HashSet ;
14
+
13
15
use bitcoin:: { Transaction , TxOut , TxIn , Amount } ;
14
16
use bitcoin:: blockdata:: locktime:: absolute:: LockTime ;
15
17
use bitcoin:: transaction:: Version ;
16
18
17
19
use crate :: chain:: channelmonitor:: LATENCY_GRACE_PERIOD_BLOCKS ;
18
20
use crate :: chain:: ChannelMonitorUpdateStatus ;
19
21
use crate :: events:: bump_transaction:: WalletSource ;
20
- use crate :: events:: { ClosureReason , Event , MessageSendEvent , MessageSendEventsProvider , PaymentPurpose } ;
22
+ use crate :: events:: { ClosureReason , Event , MessageSendEvent , MessageSendEventsProvider } ;
21
23
use crate :: ln:: { functional_test_utils:: * , msgs} ;
22
24
use crate :: ln:: msgs:: ChannelMessageHandler ;
23
25
use crate :: ln:: channelmanager:: { PaymentId , RAACommitmentOrder , RecipientOnionFields } ;
24
26
use crate :: util:: test_channel_signer:: SignerOp ;
27
+ use crate :: util:: logger:: Logger ;
25
28
26
29
#[ test]
27
30
fn test_async_commitment_signature_for_funding_created ( ) {
@@ -127,11 +130,17 @@ fn test_async_commitment_signature_for_funding_signed() {
127
130
128
131
#[ test]
129
132
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 ) ;
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
+ }
132
141
}
133
142
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 > ) {
135
144
let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
136
145
let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
137
146
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
160
169
// Mark dst's signer as unavailable and handle src's commitment_signed: while dst won't yet have a
161
170
// `commitment_signed` of its own to offer, it should publish a `revoke_and_ack`.
162
171
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 ) ;
163
173
dst. disable_channel_signer_op ( & src. node . get_our_node_id ( ) , & chan_id, SignerOp :: SignCounterpartyCommitment ) ;
164
174
dst. node . handle_commitment_signed ( & src. node . get_our_node_id ( ) , & payment_event. commitment_msg ) ;
165
175
check_added_monitors ( dst, 1 ) ;
166
176
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) ;
170
182
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
183
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
+ }
188
199
}
189
200
}
190
201
@@ -296,12 +307,22 @@ enum UnblockSignerAcrossDisconnectCase {
296
307
297
308
#[ test]
298
309
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 ) ;
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 ) ;
302
316
}
303
317
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
+ } ;
305
326
let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
306
327
let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
307
328
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
334
355
335
356
// Mark dst's signer as unavailable and handle src's commitment_signed: while dst won't yet have a
336
357
// `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 ) ;
338
359
dst. node . handle_commitment_signed ( & src. node . get_our_node_id ( ) , & payment_event. commitment_msg ) ;
339
360
check_added_monitors ( dst, 1 ) ;
340
361
@@ -359,13 +380,13 @@ fn do_test_async_raa_peer_disconnect(test_case: UnblockSignerAcrossDisconnectCas
359
380
360
381
if test_case == UnblockSignerAcrossDisconnectCase :: BeforeReestablish {
361
382
// 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 ) ;
363
384
}
364
385
365
386
dst. node . handle_channel_reestablish ( & src. node . get_our_node_id ( ) , & reestablish_1[ 0 ] ) ;
366
387
367
388
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 ) ;
369
390
chanmon_cfgs[ 1 ] . persister . set_update_ret ( ChannelMonitorUpdateStatus :: Completed ) ;
370
391
let ( outpoint, latest_update, _) = dst. chain_monitor . latest_monitor_update_id . lock ( ) . unwrap ( ) . get ( & chan_id) . unwrap ( ) . clone ( ) ;
371
392
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
384
405
}
385
406
386
407
// 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 ) ;
388
409
dst. node . signer_unblocked ( Some ( ( src. node . get_our_node_id ( ) , chan_id) ) ) ;
389
410
390
411
if test_case == UnblockSignerAcrossDisconnectCase :: AtEnd {
0 commit comments