@@ -19,10 +19,36 @@ use crate::ln::msgs::ChannelMessageHandler;
19
19
use crate :: ln:: channelmanager:: { PaymentId , RAACommitmentOrder , RecipientOnionFields } ;
20
20
use crate :: util:: test_channel_signer:: ops;
21
21
22
- const OPS : u32 = ops:: GET_PER_COMMITMENT_POINT | ops:: RELEASE_COMMITMENT_SECRET | ops:: SIGN_COUNTERPARTY_COMMITMENT ;
22
+ /// Helper to run operations with a simulated asynchronous signer.
23
+ ///
24
+ /// Disables the signer for the specified channel and then runs `do_fn`, then re-enables the signer
25
+ /// and calls `signer_unblocked`.
26
+ #[ cfg( test) ]
27
+ pub fn with_async_signer < ' a , DoFn , T > ( node : & Node , peer_id : & PublicKey , channel_id : & ChannelId , masks : & Vec < u32 > , do_fn : & ' a DoFn ) -> T
28
+ where DoFn : Fn ( ) -> T
29
+ {
30
+ let mask = masks. iter ( ) . fold ( 0 , |acc, m| ( acc | m) ) ;
31
+ eprintln ! ( "disabling {}" , ops:: string_from( mask) ) ;
32
+ node. set_channel_signer_ops_available ( peer_id, channel_id, mask, false ) ;
33
+ let res = do_fn ( ) ;
23
34
24
- #[ test]
25
- fn test_funding_created ( ) {
35
+ // Recompute the channel ID just in case the original ID was temporary.
36
+ let new_channel_id = {
37
+ let channels = node. node . list_channels ( ) ;
38
+ assert_eq ! ( channels. len( ) , 1 , "expected one channel, not {}" , channels. len( ) ) ;
39
+ channels[ 0 ] . channel_id
40
+ } ;
41
+
42
+ for mask in masks {
43
+ eprintln ! ( "enabling {} and calling signer_unblocked" , ops:: string_from( * mask) ) ;
44
+ node. set_channel_signer_ops_available ( peer_id, & new_channel_id, * mask, true ) ;
45
+ node. node . signer_unblocked ( Some ( ( * peer_id, new_channel_id) ) ) ;
46
+ }
47
+ res
48
+ }
49
+
50
+ #[ cfg( test) ]
51
+ fn do_test_funding_created ( masks : & Vec < u32 > ) {
26
52
// Simulate acquiring the signature for `funding_created` asynchronously.
27
53
let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
28
54
let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
@@ -43,22 +69,11 @@ fn test_funding_created() {
43
69
// But! Let's make node[0]'s signer be unavailable: we should *not* broadcast a funding_created
44
70
// message...
45
71
let ( temporary_channel_id, tx, _) = create_funding_transaction ( & nodes[ 0 ] , & nodes[ 1 ] . node . get_our_node_id ( ) , 100000 , 42 ) ;
46
- nodes[ 0 ] . set_channel_signer_ops_available ( & nodes[ 1 ] . node . get_our_node_id ( ) , & temporary_channel_id, OPS , false ) ;
47
- nodes[ 0 ] . node . funding_transaction_generated ( & temporary_channel_id, & nodes[ 1 ] . node . get_our_node_id ( ) , tx. clone ( ) ) . unwrap ( ) ;
48
- check_added_monitors ( & nodes[ 0 ] , 0 ) ;
49
-
50
- assert ! ( nodes[ 0 ] . node. get_and_clear_pending_msg_events( ) . is_empty( ) ) ;
51
-
52
- // Now re-enable the signer and simulate a retry. The temporary_channel_id won't work anymore so
53
- // we have to dig out the real channel ID.
54
- let chan_id = {
55
- let channels = nodes[ 0 ] . node . list_channels ( ) ;
56
- assert_eq ! ( channels. len( ) , 1 , "expected one channel, not {}" , channels. len( ) ) ;
57
- channels[ 0 ] . channel_id
58
- } ;
59
-
60
- nodes[ 0 ] . set_channel_signer_ops_available ( & nodes[ 1 ] . node . get_our_node_id ( ) , & chan_id, OPS , true ) ;
61
- nodes[ 0 ] . node . signer_unblocked ( Some ( ( nodes[ 1 ] . node . get_our_node_id ( ) , chan_id) ) ) ;
72
+ with_async_signer ( & nodes[ 0 ] , & nodes[ 1 ] . node . get_our_node_id ( ) , & temporary_channel_id, masks, & || {
73
+ nodes[ 0 ] . node . funding_transaction_generated ( & temporary_channel_id, & nodes[ 1 ] . node . get_our_node_id ( ) , tx. clone ( ) ) . unwrap ( ) ;
74
+ check_added_monitors ( & nodes[ 0 ] , 0 ) ;
75
+ assert ! ( nodes[ 0 ] . node. get_and_clear_pending_msg_events( ) . is_empty( ) ) ;
76
+ } ) ;
62
77
63
78
let mut funding_created_msg = get_event_msg ! ( nodes[ 0 ] , MessageSendEvent :: SendFundingCreated , nodes[ 1 ] . node. get_our_node_id( ) ) ;
64
79
nodes[ 1 ] . node . handle_funding_created ( & nodes[ 0 ] . node . get_our_node_id ( ) , & funding_created_msg) ;
@@ -73,7 +88,38 @@ fn test_funding_created() {
73
88
}
74
89
75
90
#[ test]
76
- fn test_for_funding_signed ( ) {
91
+ fn test_funding_created_grs ( ) {
92
+ do_test_funding_created ( & vec ! [ ops:: GET_PER_COMMITMENT_POINT , ops:: RELEASE_COMMITMENT_SECRET , ops:: SIGN_COUNTERPARTY_COMMITMENT ] ) ;
93
+ }
94
+
95
+ #[ test]
96
+ fn test_funding_created_gsr ( ) {
97
+ do_test_funding_created ( & vec ! [ ops:: GET_PER_COMMITMENT_POINT , ops:: SIGN_COUNTERPARTY_COMMITMENT , ops:: RELEASE_COMMITMENT_SECRET ] ) ;
98
+ }
99
+
100
+ #[ test]
101
+ fn test_funding_created_rsg ( ) {
102
+ do_test_funding_created ( & vec ! [ ops:: RELEASE_COMMITMENT_SECRET , ops:: SIGN_COUNTERPARTY_COMMITMENT , ops:: GET_PER_COMMITMENT_POINT ] ) ;
103
+ }
104
+
105
+ #[ test]
106
+ fn test_funding_created_rgs ( ) {
107
+ do_test_funding_created ( & vec ! [ ops:: RELEASE_COMMITMENT_SECRET , ops:: GET_PER_COMMITMENT_POINT , ops:: SIGN_COUNTERPARTY_COMMITMENT ] ) ;
108
+ }
109
+
110
+ #[ test]
111
+ fn test_funding_created_srg ( ) {
112
+ do_test_funding_created ( & vec ! [ ops:: SIGN_COUNTERPARTY_COMMITMENT , ops:: RELEASE_COMMITMENT_SECRET , ops:: GET_PER_COMMITMENT_POINT ] ) ;
113
+ }
114
+
115
+ #[ test]
116
+ fn test_funding_created_sgr ( ) {
117
+ do_test_funding_created ( & vec ! [ ops:: SIGN_COUNTERPARTY_COMMITMENT , ops:: GET_PER_COMMITMENT_POINT , ops:: RELEASE_COMMITMENT_SECRET ] ) ;
118
+ }
119
+
120
+
121
+ #[ cfg( test) ]
122
+ fn do_test_funding_signed ( masks : & Vec < u32 > ) {
77
123
// Simulate acquiring the signature for `funding_signed` asynchronously.
78
124
let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
79
125
let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
@@ -98,21 +144,11 @@ fn test_for_funding_signed() {
98
144
99
145
// Now let's make node[1]'s signer be unavailable while handling the `funding_created`. It should
100
146
// *not* broadcast a `funding_signed`...
101
- nodes[ 1 ] . set_channel_signer_ops_available ( & nodes[ 0 ] . node . get_our_node_id ( ) , & temporary_channel_id, OPS , false ) ;
102
- nodes[ 1 ] . node . handle_funding_created ( & nodes[ 0 ] . node . get_our_node_id ( ) , & funding_created_msg) ;
103
- check_added_monitors ( & nodes[ 1 ] , 1 ) ;
104
-
105
- assert ! ( nodes[ 1 ] . node. get_and_clear_pending_msg_events( ) . is_empty( ) ) ;
106
-
107
- // Now re-enable the signer and simulate a retry. The temporary_channel_id won't work anymore so
108
- // we have to dig out the real channel ID.
109
- let chan_id = {
110
- let channels = nodes[ 0 ] . node . list_channels ( ) ;
111
- assert_eq ! ( channels. len( ) , 1 , "expected one channel, not {}" , channels. len( ) ) ;
112
- channels[ 0 ] . channel_id
113
- } ;
114
- nodes[ 1 ] . set_channel_signer_ops_available ( & nodes[ 0 ] . node . get_our_node_id ( ) , & chan_id, OPS , true ) ;
115
- nodes[ 1 ] . node . signer_unblocked ( Some ( ( nodes[ 0 ] . node . get_our_node_id ( ) , chan_id) ) ) ;
147
+ with_async_signer ( & nodes[ 1 ] , & nodes[ 0 ] . node . get_our_node_id ( ) , & temporary_channel_id, masks, & || {
148
+ nodes[ 1 ] . node . handle_funding_created ( & nodes[ 0 ] . node . get_our_node_id ( ) , & funding_created_msg) ;
149
+ check_added_monitors ( & nodes[ 1 ] , 1 ) ;
150
+ assert ! ( nodes[ 1 ] . node. get_and_clear_pending_msg_events( ) . is_empty( ) ) ;
151
+ } ) ;
116
152
117
153
expect_channel_pending_event ( & nodes[ 1 ] , & nodes[ 0 ] . node . get_our_node_id ( ) ) ;
118
154
@@ -124,7 +160,38 @@ fn test_for_funding_signed() {
124
160
}
125
161
126
162
#[ test]
127
- fn test_commitment_signed ( ) {
163
+ fn test_funding_signed_grs ( ) {
164
+ do_test_funding_signed ( & vec ! [ ops:: GET_PER_COMMITMENT_POINT , ops:: RELEASE_COMMITMENT_SECRET , ops:: SIGN_COUNTERPARTY_COMMITMENT ] ) ;
165
+ }
166
+
167
+ #[ test]
168
+ fn test_funding_signed_gsr ( ) {
169
+ do_test_funding_signed ( & vec ! [ ops:: GET_PER_COMMITMENT_POINT , ops:: SIGN_COUNTERPARTY_COMMITMENT , ops:: RELEASE_COMMITMENT_SECRET ] ) ;
170
+ }
171
+
172
+ #[ test]
173
+ fn test_funding_signed_rsg ( ) {
174
+ do_test_funding_signed ( & vec ! [ ops:: RELEASE_COMMITMENT_SECRET , ops:: SIGN_COUNTERPARTY_COMMITMENT , ops:: GET_PER_COMMITMENT_POINT ] ) ;
175
+ }
176
+
177
+ #[ test]
178
+ fn test_funding_signed_rgs ( ) {
179
+ do_test_funding_signed ( & vec ! [ ops:: RELEASE_COMMITMENT_SECRET , ops:: GET_PER_COMMITMENT_POINT , ops:: SIGN_COUNTERPARTY_COMMITMENT ] ) ;
180
+ }
181
+
182
+ #[ test]
183
+ fn test_funding_signed_srg ( ) {
184
+ do_test_funding_signed ( & vec ! [ ops:: SIGN_COUNTERPARTY_COMMITMENT , ops:: RELEASE_COMMITMENT_SECRET , ops:: GET_PER_COMMITMENT_POINT ] ) ;
185
+ }
186
+
187
+ #[ test]
188
+ fn test_funding_signed_sgr ( ) {
189
+ do_test_funding_signed ( & vec ! [ ops:: SIGN_COUNTERPARTY_COMMITMENT , ops:: GET_PER_COMMITMENT_POINT , ops:: RELEASE_COMMITMENT_SECRET ] ) ;
190
+ }
191
+
192
+
193
+ #[ cfg( test) ]
194
+ fn do_test_commitment_signed ( masks : & Vec < u32 > ) {
128
195
let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
129
196
let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
130
197
let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ None , None ] ) ;
@@ -152,24 +219,48 @@ fn test_commitment_signed() {
152
219
153
220
// Mark dst's signer as unavailable and handle src's commitment_signed. If dst's signer is
154
221
// offline, it oughtn't yet respond with any updates.
155
- dst. set_channel_signer_ops_available ( & src. node . get_our_node_id ( ) , & chan_id, OPS , false ) ;
156
- dst. node . handle_commitment_signed ( & src. node . get_our_node_id ( ) , & payment_event. commitment_msg ) ;
157
- check_added_monitors ( dst, 1 ) ;
222
+ with_async_signer ( dst, & src. node . get_our_node_id ( ) , & chan_id, masks, & || {
223
+ dst. node . handle_commitment_signed ( & src. node . get_our_node_id ( ) , & payment_event. commitment_msg ) ;
224
+ check_added_monitors ( dst, 1 ) ;
225
+ assert ! ( dst. node. get_and_clear_pending_msg_events( ) . is_empty( ) ) ;
226
+ } ) ;
158
227
159
- {
160
- let events = dst. node . get_and_clear_pending_msg_events ( ) ;
161
- assert_eq ! ( events. len( ) , 0 , "expected 0 events to be generated, got {}" , events. len( ) ) ;
162
- }
228
+ get_revoke_commit_msgs ( & dst, & src. node . get_our_node_id ( ) ) ;
229
+ }
163
230
164
- // Mark dst's signer as available and retry: we now expect to see dst's `commitment_signed`.
165
- dst. set_channel_signer_ops_available ( & src. node . get_our_node_id ( ) , & chan_id, OPS , true ) ;
166
- dst. node . signer_unblocked ( Some ( ( src. node . get_our_node_id ( ) , chan_id) ) ) ;
231
+ #[ test]
232
+ fn test_commitment_signed_grs ( ) {
233
+ do_test_commitment_signed ( & vec ! [ ops:: GET_PER_COMMITMENT_POINT , ops:: RELEASE_COMMITMENT_SECRET , ops:: SIGN_COUNTERPARTY_COMMITMENT ] ) ;
234
+ }
167
235
168
- get_revoke_commit_msgs ( & dst, & src. node . get_our_node_id ( ) ) ;
236
+ #[ test]
237
+ fn test_commitment_signed_gsr ( ) {
238
+ do_test_commitment_signed ( & vec ! [ ops:: GET_PER_COMMITMENT_POINT , ops:: SIGN_COUNTERPARTY_COMMITMENT , ops:: RELEASE_COMMITMENT_SECRET ] ) ;
239
+ }
240
+
241
+ #[ test]
242
+ fn test_commitment_signed_rsg ( ) {
243
+ do_test_commitment_signed ( & vec ! [ ops:: RELEASE_COMMITMENT_SECRET , ops:: SIGN_COUNTERPARTY_COMMITMENT , ops:: GET_PER_COMMITMENT_POINT ] ) ;
169
244
}
170
245
171
246
#[ test]
172
- fn test_funding_signed_0conf ( ) {
247
+ fn test_commitment_signed_rgs ( ) {
248
+ do_test_commitment_signed ( & vec ! [ ops:: RELEASE_COMMITMENT_SECRET , ops:: GET_PER_COMMITMENT_POINT , ops:: SIGN_COUNTERPARTY_COMMITMENT ] ) ;
249
+ }
250
+
251
+ #[ test]
252
+ fn test_commitment_signed_srg ( ) {
253
+ do_test_commitment_signed ( & vec ! [ ops:: SIGN_COUNTERPARTY_COMMITMENT , ops:: RELEASE_COMMITMENT_SECRET , ops:: GET_PER_COMMITMENT_POINT ] ) ;
254
+ }
255
+
256
+ #[ test]
257
+ fn test_commitment_signed_sgr ( ) {
258
+ do_test_commitment_signed ( & vec ! [ ops:: SIGN_COUNTERPARTY_COMMITMENT , ops:: GET_PER_COMMITMENT_POINT , ops:: RELEASE_COMMITMENT_SECRET ] ) ;
259
+ }
260
+
261
+
262
+ #[ cfg( test) ]
263
+ fn do_test_funding_signed_0conf ( masks : & Vec < u32 > ) {
173
264
// Simulate acquiring the signature for `funding_signed` asynchronously for a zero-conf channel.
174
265
let mut manually_accept_config = test_default_channel_config ( ) ;
175
266
manually_accept_config. manually_accept_inbound_channels = true ;
@@ -187,7 +278,6 @@ fn test_funding_signed_0conf() {
187
278
188
279
{
189
280
let events = nodes[ 1 ] . node . get_and_clear_pending_events ( ) ;
190
- assert_eq ! ( events. len( ) , 1 , "Expected one event, got {}" , events. len( ) ) ;
191
281
match & events[ 0 ] {
192
282
Event :: OpenChannelRequest { temporary_channel_id, .. } => {
193
283
nodes[ 1 ] . node . accept_inbound_channel_from_trusted_peer_0conf (
@@ -196,6 +286,7 @@ fn test_funding_signed_0conf() {
196
286
} ,
197
287
ev => panic ! ( "Expected OpenChannelRequest, not {:?}" , ev)
198
288
}
289
+ assert_eq ! ( events. len( ) , 1 , "Expected one event, got {}" , events. len( ) ) ;
199
290
}
200
291
201
292
// nodes[0] <-- accept_channel --- nodes[1]
@@ -212,24 +303,13 @@ fn test_funding_signed_0conf() {
212
303
213
304
// Now let's make node[1]'s signer be unavailable while handling the `funding_created`. It should
214
305
// *not* broadcast a `funding_signed`...
215
- nodes[ 1 ] . set_channel_signer_ops_available ( & nodes[ 0 ] . node . get_our_node_id ( ) , & temporary_channel_id, OPS , false ) ;
216
- nodes[ 1 ] . node . handle_funding_created ( & nodes[ 0 ] . node . get_our_node_id ( ) , & funding_created_msg) ;
217
- check_added_monitors ( & nodes[ 1 ] , 1 ) ;
218
-
219
- assert ! ( nodes[ 1 ] . node. get_and_clear_pending_msg_events( ) . is_empty( ) ) ;
220
-
221
- // Now re-enable the signer and simulate a retry. The temporary_channel_id won't work anymore so
222
- // we have to dig out the real channel ID.
223
- let chan_id = {
224
- let channels = nodes[ 0 ] . node . list_channels ( ) ;
225
- assert_eq ! ( channels. len( ) , 1 , "expected one channel, not {}" , channels. len( ) ) ;
226
- channels[ 0 ] . channel_id
227
- } ;
306
+ with_async_signer ( & nodes[ 1 ] , & nodes[ 0 ] . node . get_our_node_id ( ) , & temporary_channel_id, masks, & || {
307
+ nodes[ 1 ] . node . handle_funding_created ( & nodes[ 0 ] . node . get_our_node_id ( ) , & funding_created_msg) ;
308
+ check_added_monitors ( & nodes[ 1 ] , 1 ) ;
309
+ assert ! ( nodes[ 1 ] . node. get_and_clear_pending_msg_events( ) . is_empty( ) ) ;
310
+ } ) ;
228
311
229
312
// At this point, we basically expect the channel to open like a normal zero-conf channel.
230
- nodes[ 1 ] . set_channel_signer_ops_available ( & nodes[ 0 ] . node . get_our_node_id ( ) , & chan_id, OPS , true ) ;
231
- nodes[ 1 ] . node . signer_unblocked ( Some ( ( nodes[ 0 ] . node . get_our_node_id ( ) , chan_id) ) ) ;
232
-
233
313
let ( funding_signed, channel_ready_1) = {
234
314
let events = nodes[ 1 ] . node . get_and_clear_pending_msg_events ( ) ;
235
315
let funding_signed = match & events[ 0 ] {
@@ -266,26 +346,37 @@ fn test_funding_signed_0conf() {
266
346
assert_eq ! ( nodes[ 1 ] . node. list_usable_channels( ) . len( ) , 1 ) ;
267
347
}
268
348
269
- /// Helper to run operations with a simulated asynchronous signer.
270
- ///
271
- /// Disables the signer for the specified channel and then runs `do_fn`, then re-enables the signer
272
- /// and calls `signer_unblocked`.
273
- #[ cfg( test) ]
274
- pub fn with_async_signer < ' a , DoFn , T > ( node : & Node , peer_id : & PublicKey , channel_id : & ChannelId , masks : & Vec < u32 > , do_fn : & ' a DoFn ) -> T
275
- where DoFn : Fn ( ) -> T
276
- {
277
- let mask = masks. iter ( ) . fold ( 0 , |acc, m| ( acc | m) ) ;
278
- eprintln ! ( "disabling {}" , ops:: string_from( mask) ) ;
279
- node. set_channel_signer_ops_available ( peer_id, channel_id, mask, false ) ;
280
- let res = do_fn ( ) ;
281
- for mask in masks {
282
- eprintln ! ( "enabling {} and calling signer_unblocked" , ops:: string_from( * mask) ) ;
283
- node. set_channel_signer_ops_available ( peer_id, channel_id, * mask, true ) ;
284
- node. node . signer_unblocked ( Some ( ( * peer_id, * channel_id) ) ) ;
285
- }
286
- res
349
+ #[ test]
350
+ fn test_funding_signed_0conf_grs ( ) {
351
+ do_test_funding_signed_0conf ( & vec ! [ ops:: GET_PER_COMMITMENT_POINT , ops:: RELEASE_COMMITMENT_SECRET , ops:: SIGN_COUNTERPARTY_COMMITMENT ] ) ;
352
+ }
353
+
354
+ #[ test]
355
+ fn test_funding_signed_0conf_gsr ( ) {
356
+ do_test_funding_signed_0conf ( & vec ! [ ops:: GET_PER_COMMITMENT_POINT , ops:: SIGN_COUNTERPARTY_COMMITMENT , ops:: RELEASE_COMMITMENT_SECRET ] ) ;
357
+ }
358
+
359
+ #[ test]
360
+ fn test_funding_signed_0conf_rsg ( ) {
361
+ do_test_funding_signed_0conf ( & vec ! [ ops:: RELEASE_COMMITMENT_SECRET , ops:: SIGN_COUNTERPARTY_COMMITMENT , ops:: GET_PER_COMMITMENT_POINT ] ) ;
362
+ }
363
+
364
+ #[ test]
365
+ fn test_funding_signed_0conf_rgs ( ) {
366
+ do_test_funding_signed_0conf ( & vec ! [ ops:: RELEASE_COMMITMENT_SECRET , ops:: GET_PER_COMMITMENT_POINT , ops:: SIGN_COUNTERPARTY_COMMITMENT ] ) ;
367
+ }
368
+
369
+ #[ test]
370
+ fn test_funding_signed_0conf_srg ( ) {
371
+ do_test_funding_signed_0conf ( & vec ! [ ops:: SIGN_COUNTERPARTY_COMMITMENT , ops:: RELEASE_COMMITMENT_SECRET , ops:: GET_PER_COMMITMENT_POINT ] ) ;
287
372
}
288
373
374
+ #[ test]
375
+ fn test_funding_signed_0conf_sgr ( ) {
376
+ do_test_funding_signed_0conf ( & vec ! [ ops:: SIGN_COUNTERPARTY_COMMITMENT , ops:: GET_PER_COMMITMENT_POINT , ops:: RELEASE_COMMITMENT_SECRET ] ) ;
377
+ }
378
+
379
+
289
380
#[ cfg( test) ]
290
381
fn do_test_payment ( masks : & Vec < u32 > ) {
291
382
// This runs through a one-hop payment from start to finish, simulating an asynchronous signer at
0 commit comments