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
- use bitcoin:: key :: Secp256k1 ;
13
+ use crate :: prelude :: * ;
14
+ use bitcoin:: secp256k1 :: Secp256k1 ;
15
15
use bitcoin:: { Transaction , TxOut , TxIn , Amount } ;
16
16
use bitcoin:: locktime:: absolute:: LockTime ;
17
17
use bitcoin:: transaction:: Version ;
@@ -31,7 +31,59 @@ use crate::util::test_channel_signer::SignerOp;
31
31
use crate :: util:: logger:: Logger ;
32
32
33
33
#[ test]
34
- fn test_async_commitment_signature_for_funding_created ( ) {
34
+ fn test_open_channel ( ) {
35
+ // Simulate acquiring the commitment point for `open_channel` and `accept_channel` asynchronously.
36
+ let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
37
+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
38
+ let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
39
+ let nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
40
+
41
+ // Open an outbound channel simulating an async signer.
42
+ let channel_value_satoshis = 100000 ;
43
+ let user_channel_id = 42 ;
44
+ nodes[ 0 ] . disable_next_channel_signer_op ( SignerOp :: GetPerCommitmentPoint ) ;
45
+ let channel_id_0 = nodes[ 0 ] . node . create_channel ( nodes[ 1 ] . node . get_our_node_id ( ) , channel_value_satoshis, 10001 , user_channel_id, None , None ) . unwrap ( ) ;
46
+
47
+ {
48
+ let msgs = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
49
+ assert ! ( msgs. is_empty( ) , "Expected no message events; got {:?}" , msgs) ;
50
+ }
51
+
52
+ nodes[ 0 ] . enable_channel_signer_op ( & nodes[ 1 ] . node . get_our_node_id ( ) , & channel_id_0, SignerOp :: GetPerCommitmentPoint ) ;
53
+ nodes[ 0 ] . node . signer_unblocked ( None ) ;
54
+
55
+ // nodes[0] --- open_channel --> nodes[1]
56
+ let mut open_chan_msg = get_event_msg ! ( nodes[ 0 ] , MessageSendEvent :: SendOpenChannel , nodes[ 1 ] . node. get_our_node_id( ) ) ;
57
+
58
+ // Handle an inbound channel simulating an async signer.
59
+ nodes[ 1 ] . disable_next_channel_signer_op ( SignerOp :: GetPerCommitmentPoint ) ;
60
+ nodes[ 1 ] . node . handle_open_channel ( nodes[ 0 ] . node . get_our_node_id ( ) , & open_chan_msg) ;
61
+
62
+ {
63
+ let msgs = nodes[ 1 ] . node . get_and_clear_pending_msg_events ( ) ;
64
+ assert ! ( msgs. is_empty( ) , "Expected no message events; got {:?}" , msgs) ;
65
+ }
66
+
67
+ let channel_id_1 = {
68
+ let channels = nodes[ 1 ] . node . list_channels ( ) ;
69
+ assert_eq ! ( channels. len( ) , 1 , "expected one channel, not {}" , channels. len( ) ) ;
70
+ channels[ 0 ] . channel_id
71
+ } ;
72
+
73
+ nodes[ 1 ] . enable_channel_signer_op ( & nodes[ 0 ] . node . get_our_node_id ( ) , & channel_id_1, SignerOp :: GetPerCommitmentPoint ) ;
74
+ nodes[ 1 ] . node . signer_unblocked ( None ) ;
75
+
76
+ // nodes[0] <-- accept_channel --- nodes[1]
77
+ get_event_msg ! ( nodes[ 1 ] , MessageSendEvent :: SendAcceptChannel , nodes[ 0 ] . node. get_our_node_id( ) ) ;
78
+ }
79
+
80
+ #[ test]
81
+ fn test_funding_created ( ) {
82
+ do_test_funding_created ( vec ! [ SignerOp :: SignCounterpartyCommitment , SignerOp :: GetPerCommitmentPoint ] ) ;
83
+ do_test_funding_created ( vec ! [ SignerOp :: GetPerCommitmentPoint , SignerOp :: SignCounterpartyCommitment ] ) ;
84
+ }
85
+
86
+ fn do_test_funding_created ( signer_ops : Vec < SignerOp > ) {
35
87
// Simulate acquiring the signature for `funding_created` asynchronously.
36
88
let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
37
89
let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
@@ -52,7 +104,9 @@ fn test_async_commitment_signature_for_funding_created() {
52
104
// But! Let's make node[0]'s signer be unavailable: we should *not* broadcast a funding_created
53
105
// message...
54
106
let ( temporary_channel_id, tx, _) = create_funding_transaction ( & nodes[ 0 ] , & nodes[ 1 ] . node . get_our_node_id ( ) , 100000 , 42 ) ;
55
- nodes[ 0 ] . disable_channel_signer_op ( & nodes[ 1 ] . node . get_our_node_id ( ) , & temporary_channel_id, SignerOp :: SignCounterpartyCommitment ) ;
107
+ for op in signer_ops. iter ( ) {
108
+ nodes[ 0 ] . disable_channel_signer_op ( & nodes[ 1 ] . node . get_our_node_id ( ) , & temporary_channel_id, * op) ;
109
+ }
56
110
nodes[ 0 ] . node . funding_transaction_generated ( temporary_channel_id, nodes[ 1 ] . node . get_our_node_id ( ) , tx. clone ( ) ) . unwrap ( ) ;
57
111
check_added_monitors ( & nodes[ 0 ] , 0 ) ;
58
112
@@ -66,8 +120,10 @@ fn test_async_commitment_signature_for_funding_created() {
66
120
channels[ 0 ] . channel_id
67
121
} ;
68
122
69
- nodes[ 0 ] . enable_channel_signer_op ( & nodes[ 1 ] . node . get_our_node_id ( ) , & chan_id, SignerOp :: SignCounterpartyCommitment ) ;
70
- nodes[ 0 ] . node . signer_unblocked ( Some ( ( nodes[ 1 ] . node . get_our_node_id ( ) , chan_id) ) ) ;
123
+ for op in signer_ops. iter ( ) {
124
+ nodes[ 0 ] . enable_channel_signer_op ( & nodes[ 1 ] . node . get_our_node_id ( ) , & chan_id, * op) ;
125
+ nodes[ 0 ] . node . signer_unblocked ( Some ( ( nodes[ 1 ] . node . get_our_node_id ( ) , chan_id) ) ) ;
126
+ }
71
127
72
128
let mut funding_created_msg = get_event_msg ! ( nodes[ 0 ] , MessageSendEvent :: SendFundingCreated , nodes[ 1 ] . node. get_our_node_id( ) ) ;
73
129
nodes[ 1 ] . node . handle_funding_created ( nodes[ 0 ] . node . get_our_node_id ( ) , & funding_created_msg) ;
@@ -82,7 +138,12 @@ fn test_async_commitment_signature_for_funding_created() {
82
138
}
83
139
84
140
#[ test]
85
- fn test_async_commitment_signature_for_funding_signed ( ) {
141
+ fn test_funding_signed ( ) {
142
+ do_test_funding_signed ( vec ! [ SignerOp :: SignCounterpartyCommitment , SignerOp :: GetPerCommitmentPoint ] ) ;
143
+ do_test_funding_signed ( vec ! [ SignerOp :: GetPerCommitmentPoint , SignerOp :: SignCounterpartyCommitment ] ) ;
144
+ }
145
+
146
+ fn do_test_funding_signed ( signer_ops : Vec < SignerOp > ) {
86
147
// Simulate acquiring the signature for `funding_signed` asynchronously.
87
148
let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
88
149
let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
@@ -107,7 +168,9 @@ fn test_async_commitment_signature_for_funding_signed() {
107
168
108
169
// Now let's make node[1]'s signer be unavailable while handling the `funding_created`. It should
109
170
// *not* broadcast a `funding_signed`...
110
- nodes[ 1 ] . disable_channel_signer_op ( & nodes[ 0 ] . node . get_our_node_id ( ) , & temporary_channel_id, SignerOp :: SignCounterpartyCommitment ) ;
171
+ for op in signer_ops. iter ( ) {
172
+ nodes[ 1 ] . disable_channel_signer_op ( & nodes[ 0 ] . node . get_our_node_id ( ) , & temporary_channel_id, * op) ;
173
+ }
111
174
nodes[ 1 ] . node . handle_funding_created ( nodes[ 0 ] . node . get_our_node_id ( ) , & funding_created_msg) ;
112
175
check_added_monitors ( & nodes[ 1 ] , 1 ) ;
113
176
@@ -120,8 +183,10 @@ fn test_async_commitment_signature_for_funding_signed() {
120
183
assert_eq ! ( channels. len( ) , 1 , "expected one channel, not {}" , channels. len( ) ) ;
121
184
channels[ 0 ] . channel_id
122
185
} ;
123
- nodes[ 1 ] . enable_channel_signer_op ( & nodes[ 0 ] . node . get_our_node_id ( ) , & chan_id, SignerOp :: SignCounterpartyCommitment ) ;
124
- nodes[ 1 ] . node . signer_unblocked ( Some ( ( nodes[ 0 ] . node . get_our_node_id ( ) , chan_id) ) ) ;
186
+ for op in signer_ops. iter ( ) {
187
+ nodes[ 1 ] . enable_channel_signer_op ( & nodes[ 0 ] . node . get_our_node_id ( ) , & chan_id, * op) ;
188
+ nodes[ 1 ] . node . signer_unblocked ( Some ( ( nodes[ 0 ] . node . get_our_node_id ( ) , chan_id) ) ) ;
189
+ }
125
190
126
191
expect_channel_pending_event ( & nodes[ 1 ] , & nodes[ 0 ] . node . get_our_node_id ( ) ) ;
127
192
@@ -204,7 +269,12 @@ fn do_test_async_commitment_signature_for_commitment_signed_revoke_and_ack(enabl
204
269
}
205
270
206
271
#[ test]
207
- fn test_async_commitment_signature_for_funding_signed_0conf ( ) {
272
+ fn test_funding_signed_0conf ( ) {
273
+ do_test_funding_signed_0conf ( vec ! [ SignerOp :: GetPerCommitmentPoint , SignerOp :: SignCounterpartyCommitment ] ) ;
274
+ do_test_funding_signed_0conf ( vec ! [ SignerOp :: SignCounterpartyCommitment , SignerOp :: GetPerCommitmentPoint ] ) ;
275
+ }
276
+
277
+ fn do_test_funding_signed_0conf ( signer_ops : Vec < SignerOp > ) {
208
278
// Simulate acquiring the signature for `funding_signed` asynchronously for a zero-conf channel.
209
279
let mut manually_accept_config = test_default_channel_config ( ) ;
210
280
manually_accept_config. manually_accept_inbound_channels = true ;
@@ -247,7 +317,9 @@ fn test_async_commitment_signature_for_funding_signed_0conf() {
247
317
248
318
// Now let's make node[1]'s signer be unavailable while handling the `funding_created`. It should
249
319
// *not* broadcast a `funding_signed`...
250
- nodes[ 1 ] . disable_channel_signer_op ( & nodes[ 0 ] . node . get_our_node_id ( ) , & temporary_channel_id, SignerOp :: SignCounterpartyCommitment ) ;
320
+ for op in signer_ops. iter ( ) {
321
+ nodes[ 1 ] . disable_channel_signer_op ( & nodes[ 0 ] . node . get_our_node_id ( ) , & temporary_channel_id, * op) ;
322
+ }
251
323
nodes[ 1 ] . node . handle_funding_created ( nodes[ 0 ] . node . get_our_node_id ( ) , & funding_created_msg) ;
252
324
check_added_monitors ( & nodes[ 1 ] , 1 ) ;
253
325
@@ -262,8 +334,10 @@ fn test_async_commitment_signature_for_funding_signed_0conf() {
262
334
} ;
263
335
264
336
// At this point, we basically expect the channel to open like a normal zero-conf channel.
265
- nodes[ 1 ] . enable_channel_signer_op ( & nodes[ 0 ] . node . get_our_node_id ( ) , & chan_id, SignerOp :: SignCounterpartyCommitment ) ;
266
- nodes[ 1 ] . node . signer_unblocked ( Some ( ( nodes[ 0 ] . node . get_our_node_id ( ) , chan_id) ) ) ;
337
+ for op in signer_ops. iter ( ) {
338
+ nodes[ 1 ] . enable_channel_signer_op ( & nodes[ 0 ] . node . get_our_node_id ( ) , & chan_id, * op) ;
339
+ nodes[ 1 ] . node . signer_unblocked ( Some ( ( nodes[ 0 ] . node . get_our_node_id ( ) , chan_id) ) ) ;
340
+ }
267
341
268
342
let ( funding_signed, channel_ready_1) = {
269
343
let events = nodes[ 1 ] . node . get_and_clear_pending_msg_events ( ) ;
0 commit comments