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 ;
13+ use crate :: prelude :: * ;
1414
1515use bitcoin:: { Transaction , TxOut , TxIn , Amount } ;
1616use bitcoin:: blockdata:: locktime:: absolute:: LockTime ;
@@ -27,7 +27,59 @@ use crate::util::test_channel_signer::SignerOp;
2727use crate :: util:: logger:: Logger ;
2828
2929#[ 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 > ) {
3183 // Simulate acquiring the signature for `funding_created` asynchronously.
3284 let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
3385 let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
@@ -48,7 +100,9 @@ fn test_async_commitment_signature_for_funding_created() {
48100 // But! Let's make node[0]'s signer be unavailable: we should *not* broadcast a funding_created
49101 // message...
50102 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+ }
52106 nodes[ 0 ] . node . funding_transaction_generated ( & temporary_channel_id, & nodes[ 1 ] . node . get_our_node_id ( ) , tx. clone ( ) ) . unwrap ( ) ;
53107 check_added_monitors ( & nodes[ 0 ] , 0 ) ;
54108
@@ -62,8 +116,10 @@ fn test_async_commitment_signature_for_funding_created() {
62116 channels[ 0 ] . channel_id
63117 } ;
64118
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+ }
67123
68124 let mut funding_created_msg = get_event_msg ! ( nodes[ 0 ] , MessageSendEvent :: SendFundingCreated , nodes[ 1 ] . node. get_our_node_id( ) ) ;
69125 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() {
78134}
79135
80136#[ 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 > ) {
82143 // Simulate acquiring the signature for `funding_signed` asynchronously.
83144 let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
84145 let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
@@ -103,7 +164,9 @@ fn test_async_commitment_signature_for_funding_signed() {
103164
104165 // Now let's make node[1]'s signer be unavailable while handling the `funding_created`. It should
105166 // *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+ }
107170 nodes[ 1 ] . node . handle_funding_created ( & nodes[ 0 ] . node . get_our_node_id ( ) , & funding_created_msg) ;
108171 check_added_monitors ( & nodes[ 1 ] , 1 ) ;
109172
@@ -116,8 +179,10 @@ fn test_async_commitment_signature_for_funding_signed() {
116179 assert_eq ! ( channels. len( ) , 1 , "expected one channel, not {}" , channels. len( ) ) ;
117180 channels[ 0 ] . channel_id
118181 } ;
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+ }
121186
122187 expect_channel_pending_event ( & nodes[ 1 ] , & nodes[ 0 ] . node . get_our_node_id ( ) ) ;
123188
@@ -200,7 +265,12 @@ fn do_test_async_commitment_signature_for_commitment_signed_revoke_and_ack(enabl
200265}
201266
202267#[ 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 > ) {
204274 // Simulate acquiring the signature for `funding_signed` asynchronously for a zero-conf channel.
205275 let mut manually_accept_config = test_default_channel_config ( ) ;
206276 manually_accept_config. manually_accept_inbound_channels = true ;
@@ -243,7 +313,9 @@ fn test_async_commitment_signature_for_funding_signed_0conf() {
243313
244314 // Now let's make node[1]'s signer be unavailable while handling the `funding_created`. It should
245315 // *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+ }
247319 nodes[ 1 ] . node . handle_funding_created ( & nodes[ 0 ] . node . get_our_node_id ( ) , & funding_created_msg) ;
248320 check_added_monitors ( & nodes[ 1 ] , 1 ) ;
249321
@@ -258,8 +330,10 @@ fn test_async_commitment_signature_for_funding_signed_0conf() {
258330 } ;
259331
260332 // 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+ }
263337
264338 let ( funding_signed, channel_ready_1) = {
265339 let events = nodes[ 1 ] . node . get_and_clear_pending_msg_events ( ) ;
0 commit comments