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 ;
13
+ use crate :: prelude :: * ;
14
14
15
15
use bitcoin:: { Transaction , TxOut , TxIn , Amount } ;
16
16
use bitcoin:: blockdata:: locktime:: absolute:: LockTime ;
@@ -27,7 +27,59 @@ use crate::util::test_channel_signer::SignerOp;
27
27
use crate :: util:: logger:: Logger ;
28
28
29
29
#[ test]
30
- fn test_async_commitment_signature_for_funding_created ( ) {
30
+ fn test_open_channel ( ) {
31
+ // Simulate acquiring the commitment point for `open_channel` and `accept_channel` asynchronously.
32
+ let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
33
+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
34
+ let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
35
+ let nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
36
+
37
+ // Open an outbound channel simulating an async signer.
38
+ let channel_value_satoshis = 100000 ;
39
+ let user_channel_id = 42 ;
40
+ nodes[ 0 ] . disable_next_channel_signer_op ( SignerOp :: GetPerCommitmentPoint ) ;
41
+ 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 ( ) ;
42
+
43
+ {
44
+ let msgs = nodes[ 0 ] . node . get_and_clear_pending_msg_events ( ) ;
45
+ assert ! ( msgs. is_empty( ) , "Expected no message events; got {:?}" , msgs) ;
46
+ }
47
+
48
+ nodes[ 0 ] . enable_channel_signer_op ( & nodes[ 1 ] . node . get_our_node_id ( ) , & channel_id_0, SignerOp :: GetPerCommitmentPoint ) ;
49
+ nodes[ 0 ] . node . signer_unblocked ( None ) ;
50
+
51
+ // nodes[0] --- open_channel --> nodes[1]
52
+ let mut open_chan_msg = get_event_msg ! ( nodes[ 0 ] , MessageSendEvent :: SendOpenChannel , nodes[ 1 ] . node. get_our_node_id( ) ) ;
53
+
54
+ // Handle an inbound channel simulating an async signer.
55
+ nodes[ 1 ] . disable_next_channel_signer_op ( SignerOp :: GetPerCommitmentPoint ) ;
56
+ nodes[ 1 ] . node . handle_open_channel ( & nodes[ 0 ] . node . get_our_node_id ( ) , & open_chan_msg) ;
57
+
58
+ {
59
+ let msgs = nodes[ 1 ] . node . get_and_clear_pending_msg_events ( ) ;
60
+ assert ! ( msgs. is_empty( ) , "Expected no message events; got {:?}" , msgs) ;
61
+ }
62
+
63
+ let channel_id_1 = {
64
+ let channels = nodes[ 1 ] . node . list_channels ( ) ;
65
+ assert_eq ! ( channels. len( ) , 1 , "expected one channel, not {}" , channels. len( ) ) ;
66
+ channels[ 0 ] . channel_id
67
+ } ;
68
+
69
+ nodes[ 1 ] . enable_channel_signer_op ( & nodes[ 0 ] . node . get_our_node_id ( ) , & channel_id_1, SignerOp :: GetPerCommitmentPoint ) ;
70
+ nodes[ 1 ] . node . signer_unblocked ( None ) ;
71
+
72
+ // nodes[0] <-- accept_channel --- nodes[1]
73
+ get_event_msg ! ( nodes[ 1 ] , MessageSendEvent :: SendAcceptChannel , nodes[ 0 ] . node. get_our_node_id( ) ) ;
74
+ }
75
+
76
+ #[ test]
77
+ fn test_funding_created ( ) {
78
+ do_test_funding_created ( vec ! [ SignerOp :: SignCounterpartyCommitment , SignerOp :: GetPerCommitmentPoint ] ) ;
79
+ do_test_funding_created ( vec ! [ SignerOp :: GetPerCommitmentPoint , SignerOp :: SignCounterpartyCommitment ] ) ;
80
+ }
81
+
82
+ fn do_test_funding_created ( signer_ops : Vec < SignerOp > ) {
31
83
// Simulate acquiring the signature for `funding_created` asynchronously.
32
84
let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
33
85
let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
@@ -48,7 +100,9 @@ fn test_async_commitment_signature_for_funding_created() {
48
100
// But! Let's make node[0]'s signer be unavailable: we should *not* broadcast a funding_created
49
101
// message...
50
102
let ( temporary_channel_id, tx, _) = create_funding_transaction ( & nodes[ 0 ] , & nodes[ 1 ] . node . get_our_node_id ( ) , 100000 , 42 ) ;
51
- nodes[ 0 ] . disable_channel_signer_op ( & nodes[ 1 ] . node . get_our_node_id ( ) , & temporary_channel_id, SignerOp :: SignCounterpartyCommitment ) ;
103
+ for op in signer_ops. iter ( ) {
104
+ nodes[ 0 ] . disable_channel_signer_op ( & nodes[ 1 ] . node . get_our_node_id ( ) , & temporary_channel_id, * op) ;
105
+ }
52
106
nodes[ 0 ] . node . funding_transaction_generated ( & temporary_channel_id, & nodes[ 1 ] . node . get_our_node_id ( ) , tx. clone ( ) ) . unwrap ( ) ;
53
107
check_added_monitors ( & nodes[ 0 ] , 0 ) ;
54
108
@@ -62,8 +116,10 @@ fn test_async_commitment_signature_for_funding_created() {
62
116
channels[ 0 ] . channel_id
63
117
} ;
64
118
65
- nodes[ 0 ] . enable_channel_signer_op ( & nodes[ 1 ] . node . get_our_node_id ( ) , & chan_id, SignerOp :: SignCounterpartyCommitment ) ;
66
- nodes[ 0 ] . node . signer_unblocked ( Some ( ( nodes[ 1 ] . node . get_our_node_id ( ) , chan_id) ) ) ;
119
+ for op in signer_ops. iter ( ) {
120
+ nodes[ 0 ] . enable_channel_signer_op ( & nodes[ 1 ] . node . get_our_node_id ( ) , & chan_id, * op) ;
121
+ nodes[ 0 ] . node . signer_unblocked ( Some ( ( nodes[ 1 ] . node . get_our_node_id ( ) , chan_id) ) ) ;
122
+ }
67
123
68
124
let mut funding_created_msg = get_event_msg ! ( nodes[ 0 ] , MessageSendEvent :: SendFundingCreated , nodes[ 1 ] . node. get_our_node_id( ) ) ;
69
125
nodes[ 1 ] . node . handle_funding_created ( & nodes[ 0 ] . node . get_our_node_id ( ) , & funding_created_msg) ;
@@ -78,7 +134,12 @@ fn test_async_commitment_signature_for_funding_created() {
78
134
}
79
135
80
136
#[ test]
81
- fn test_async_commitment_signature_for_funding_signed ( ) {
137
+ fn test_funding_signed ( ) {
138
+ do_test_funding_signed ( vec ! [ SignerOp :: SignCounterpartyCommitment , SignerOp :: GetPerCommitmentPoint ] ) ;
139
+ do_test_funding_signed ( vec ! [ SignerOp :: GetPerCommitmentPoint , SignerOp :: SignCounterpartyCommitment ] ) ;
140
+ }
141
+
142
+ fn do_test_funding_signed ( signer_ops : Vec < SignerOp > ) {
82
143
// Simulate acquiring the signature for `funding_signed` asynchronously.
83
144
let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
84
145
let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
@@ -103,7 +164,9 @@ fn test_async_commitment_signature_for_funding_signed() {
103
164
104
165
// Now let's make node[1]'s signer be unavailable while handling the `funding_created`. It should
105
166
// *not* broadcast a `funding_signed`...
106
- nodes[ 1 ] . disable_channel_signer_op ( & nodes[ 0 ] . node . get_our_node_id ( ) , & temporary_channel_id, SignerOp :: SignCounterpartyCommitment ) ;
167
+ for op in signer_ops. iter ( ) {
168
+ nodes[ 1 ] . disable_channel_signer_op ( & nodes[ 0 ] . node . get_our_node_id ( ) , & temporary_channel_id, * op) ;
169
+ }
107
170
nodes[ 1 ] . node . handle_funding_created ( & nodes[ 0 ] . node . get_our_node_id ( ) , & funding_created_msg) ;
108
171
check_added_monitors ( & nodes[ 1 ] , 1 ) ;
109
172
@@ -116,8 +179,10 @@ fn test_async_commitment_signature_for_funding_signed() {
116
179
assert_eq ! ( channels. len( ) , 1 , "expected one channel, not {}" , channels. len( ) ) ;
117
180
channels[ 0 ] . channel_id
118
181
} ;
119
- nodes[ 1 ] . enable_channel_signer_op ( & nodes[ 0 ] . node . get_our_node_id ( ) , & chan_id, SignerOp :: SignCounterpartyCommitment ) ;
120
- nodes[ 1 ] . node . signer_unblocked ( Some ( ( nodes[ 0 ] . node . get_our_node_id ( ) , chan_id) ) ) ;
182
+ for op in signer_ops. iter ( ) {
183
+ nodes[ 1 ] . enable_channel_signer_op ( & nodes[ 0 ] . node . get_our_node_id ( ) , & chan_id, * op) ;
184
+ nodes[ 1 ] . node . signer_unblocked ( Some ( ( nodes[ 0 ] . node . get_our_node_id ( ) , chan_id) ) ) ;
185
+ }
121
186
122
187
expect_channel_pending_event ( & nodes[ 1 ] , & nodes[ 0 ] . node . get_our_node_id ( ) ) ;
123
188
@@ -200,7 +265,12 @@ fn do_test_async_commitment_signature_for_commitment_signed_revoke_and_ack(enabl
200
265
}
201
266
202
267
#[ test]
203
- fn test_async_commitment_signature_for_funding_signed_0conf ( ) {
268
+ fn test_funding_signed_0conf ( ) {
269
+ do_test_funding_signed_0conf ( vec ! [ SignerOp :: GetPerCommitmentPoint , SignerOp :: SignCounterpartyCommitment ] ) ;
270
+ do_test_funding_signed_0conf ( vec ! [ SignerOp :: SignCounterpartyCommitment , SignerOp :: GetPerCommitmentPoint ] ) ;
271
+ }
272
+
273
+ fn do_test_funding_signed_0conf ( signer_ops : Vec < SignerOp > ) {
204
274
// Simulate acquiring the signature for `funding_signed` asynchronously for a zero-conf channel.
205
275
let mut manually_accept_config = test_default_channel_config ( ) ;
206
276
manually_accept_config. manually_accept_inbound_channels = true ;
@@ -243,7 +313,9 @@ fn test_async_commitment_signature_for_funding_signed_0conf() {
243
313
244
314
// Now let's make node[1]'s signer be unavailable while handling the `funding_created`. It should
245
315
// *not* broadcast a `funding_signed`...
246
- nodes[ 1 ] . disable_channel_signer_op ( & nodes[ 0 ] . node . get_our_node_id ( ) , & temporary_channel_id, SignerOp :: SignCounterpartyCommitment ) ;
316
+ for op in signer_ops. iter ( ) {
317
+ nodes[ 1 ] . disable_channel_signer_op ( & nodes[ 0 ] . node . get_our_node_id ( ) , & temporary_channel_id, * op) ;
318
+ }
247
319
nodes[ 1 ] . node . handle_funding_created ( & nodes[ 0 ] . node . get_our_node_id ( ) , & funding_created_msg) ;
248
320
check_added_monitors ( & nodes[ 1 ] , 1 ) ;
249
321
@@ -258,8 +330,10 @@ fn test_async_commitment_signature_for_funding_signed_0conf() {
258
330
} ;
259
331
260
332
// At this point, we basically expect the channel to open like a normal zero-conf channel.
261
- nodes[ 1 ] . enable_channel_signer_op ( & nodes[ 0 ] . node . get_our_node_id ( ) , & chan_id, SignerOp :: SignCounterpartyCommitment ) ;
262
- nodes[ 1 ] . node . signer_unblocked ( Some ( ( nodes[ 0 ] . node . get_our_node_id ( ) , chan_id) ) ) ;
333
+ for op in signer_ops. iter ( ) {
334
+ nodes[ 1 ] . enable_channel_signer_op ( & nodes[ 0 ] . node . get_our_node_id ( ) , & chan_id, * op) ;
335
+ nodes[ 1 ] . node . signer_unblocked ( Some ( ( nodes[ 0 ] . node . get_our_node_id ( ) , chan_id) ) ) ;
336
+ }
263
337
264
338
let ( funding_signed, channel_ready_1) = {
265
339
let events = nodes[ 1 ] . node . get_and_clear_pending_msg_events ( ) ;
0 commit comments