@@ -22,7 +22,6 @@ import (
22
22
"github.com/lightningnetwork/lnd/input"
23
23
"github.com/lightningnetwork/lnd/lnwallet"
24
24
"github.com/lightningnetwork/lnd/lnwire"
25
- "github.com/lightningnetwork/lnd/tlv"
26
25
"github.com/stretchr/testify/require"
27
26
)
28
27
@@ -40,10 +39,58 @@ var (
40
39
)
41
40
42
41
testTimeout = time .Second
42
+
43
+ chanState = & channeldb.OpenChannel {
44
+ ChanType : channeldb .AnchorOutputsBit |
45
+ channeldb .ScidAliasChanBit | channeldb .SingleFunderBit |
46
+ channeldb .SimpleTaprootFeatureBit |
47
+ channeldb .TapscriptRootBit ,
48
+ IsInitiator : true ,
49
+ }
50
+
51
+ // sig job batch size when making more that one sig job.
52
+ numSigJobs = int32 (10 )
53
+
54
+ // Threshold for trying to cancel or quit the aux leaf signer (allow
55
+ // the signer to complete a third of the batch).
56
+ sigJobCancelThreshold = numSigJobs / 3
43
57
)
44
58
45
- // TestAuxLeafSigner tests the AuxLeafSigner implementation.
46
- func TestAuxLeafSigner (t * testing.T ) {
59
+ // RandAuxSigJob generates a basic aux signer job with random key material.
60
+ func RandAuxSigJob (t * testing.T , cancelChan chan struct {},
61
+ commitBlob lfn.Option [[]byte ], outputIdx int32 ) lnwallet.AuxSigJob {
62
+
63
+ keyDesc , _ := test .RandKeyDesc (t )
64
+ keyRing := test .RandCommitmentKeyRing (t )
65
+
66
+ return lnwallet.AuxSigJob {
67
+ SignDesc : input.SignDescriptor {
68
+ KeyDesc : keyDesc ,
69
+ },
70
+ BaseAuxJob : lnwallet.BaseAuxJob {
71
+ OutputIndex : outputIdx ,
72
+ KeyRing : keyRing ,
73
+ HTLC : lnwallet.PaymentDescriptor {
74
+ HtlcIndex : 0 ,
75
+ Amount : lnwire .NewMSatFromSatoshis (
76
+ 354 ,
77
+ ),
78
+ EntryType : lnwallet .Add ,
79
+ },
80
+ Incoming : false ,
81
+ CommitBlob : commitBlob ,
82
+ HtlcLeaf : input.AuxTapLeaf {},
83
+ },
84
+ Resp : make (chan lnwallet.AuxSigJobResp , 1 ),
85
+ Cancel : cancelChan ,
86
+ }
87
+ }
88
+
89
+ // setupAuxLeafSigner sets up an AuxLeafSigner instance and a batch of sig jobs
90
+ // to use in unit tests.
91
+ func setupAuxLeafSigner (t * testing.T , numJobs int32 ) (* AuxLeafSigner ,
92
+ chan struct {}, * wire.MsgTx , []lnwallet.AuxSigJob ) {
93
+
47
94
cfg := & LeafSignerConfig {
48
95
ChainParams : testChainParams ,
49
96
Signer : & mockVirtualSigner {},
@@ -52,30 +99,8 @@ func TestAuxLeafSigner(t *testing.T) {
52
99
signer := NewAuxLeafSigner (cfg )
53
100
require .NoError (t , signer .Start ())
54
101
55
- defer func () {
56
- require .NoError (t , signer .Stop ())
57
- }()
58
-
59
- chanState := & channeldb.OpenChannel {
60
- ChanType : channeldb .AnchorOutputsBit |
61
- channeldb .ScidAliasChanBit | channeldb .SingleFunderBit |
62
- channeldb .SimpleTaprootFeatureBit |
63
- channeldb .TapscriptRootBit ,
64
- IsInitiator : true ,
65
- }
66
102
randInputProof := randProof (t )
67
103
commitTx := & randInputProof .AnchorTx
68
- keyRing := lnwallet.CommitmentKeyRing {
69
- CommitPoint : test .RandPubKey (t ),
70
- LocalCommitKeyTweak : test .RandBytes (32 ),
71
- LocalHtlcKeyTweak : test .RandBytes (32 ),
72
- LocalHtlcKey : test .RandPubKey (t ),
73
- RemoteHtlcKey : test .RandPubKey (t ),
74
- ToLocalKey : test .RandPubKey (t ),
75
- ToRemoteKey : test .RandPubKey (t ),
76
- RevocationKey : test .RandPubKey (t ),
77
- }
78
-
79
104
outgoingHtlcs := make (map [input.HtlcIndex ][]* cmsg.AssetOutput )
80
105
outgoingHtlcs [0 ] = []* cmsg.AssetOutput {
81
106
cmsg .NewAssetOutput (
@@ -87,33 +112,28 @@ func TestAuxLeafSigner(t *testing.T) {
87
112
com := cmsg .NewCommitment (
88
113
nil , nil , outgoingHtlcs , nil , lnwallet.CommitAuxLeaves {},
89
114
)
115
+ cancelChan := make (chan struct {})
90
116
91
- randKeyDesc , _ := test .RandKeyDesc (t )
92
-
93
- jobs := []lnwallet.AuxSigJob {
94
- {
95
- SignDesc : input.SignDescriptor {
96
- KeyDesc : randKeyDesc ,
97
- },
98
- BaseAuxJob : lnwallet.BaseAuxJob {
99
- OutputIndex : 0 ,
100
- KeyRing : keyRing ,
101
- HTLC : lnwallet.PaymentDescriptor {
102
- HtlcIndex : 0 ,
103
- Amount : lnwire .NewMSatFromSatoshis (
104
- 354 ,
105
- ),
106
- EntryType : lnwallet .Add ,
107
- },
108
- Incoming : false ,
109
- CommitBlob : lfn.Some [tlv.Blob ](com .Bytes ()),
110
- HtlcLeaf : input.AuxTapLeaf {},
111
- },
112
- Resp : make (chan lnwallet.AuxSigJobResp ),
113
- Cancel : make (chan struct {}),
114
- },
117
+ // Constructing multiple jobs will allow us to assert that later jobs
118
+ // are cancelled successfully.
119
+ jobs := make ([]lnwallet.AuxSigJob , 0 , numJobs )
120
+ for idx := range numJobs {
121
+ newJob := RandAuxSigJob (
122
+ t , cancelChan , lfn .Some (com .Bytes ()), idx ,
123
+ )
124
+ jobs = append (jobs , newJob )
115
125
}
116
126
127
+ return signer , cancelChan , commitTx , jobs
128
+ }
129
+
130
+ // TestAuxLeafSigner tests the AuxLeafSigner implementation.
131
+ func TestAuxLeafSigner (t * testing.T ) {
132
+ signer , _ , commitTx , jobs := setupAuxLeafSigner (t , 1 )
133
+ defer func () {
134
+ require .NoError (t , signer .Stop ())
135
+ }()
136
+
117
137
err := signer .SubmitSecondLevelSigBatch (chanState , commitTx , jobs )
118
138
require .NoError (t , err )
119
139
@@ -131,6 +151,79 @@ func TestAuxLeafSigner(t *testing.T) {
131
151
}
132
152
}
133
153
154
+ // TestAuxLeafSignerCancel tests that the AuxLeafSigner will handle a cancel
155
+ // signal correctly, which involves skipping all remaining sig jobs.
156
+ func TestAuxLeafSignerCancel (t * testing.T ) {
157
+ // Constructing multiple jobs will allow us to assert that later jobs
158
+ // are cancelled successfully.
159
+ signer , cancelChan , commitTx , jobs := setupAuxLeafSigner (t , numSigJobs )
160
+ defer func () {
161
+ require .NoError (t , signer .Stop ())
162
+ }()
163
+
164
+ err := signer .SubmitSecondLevelSigBatch (chanState , commitTx , jobs )
165
+ require .NoError (t , err )
166
+
167
+ select {
168
+ case <- time .After (testTimeout ):
169
+ t .Fatalf ("timeout waiting for response" )
170
+ case <- jobs [sigJobCancelThreshold ].Resp :
171
+ // Send the cancel signal; jobs at the end of the batch should
172
+ // not be processed.
173
+ close (cancelChan )
174
+ }
175
+
176
+ signer .Wg .Wait ()
177
+
178
+ // Once the aux signer finishes handling the batch, the last job of the
179
+ // batch should have an empty response channel. Otherwise, the signer
180
+ // failed to skip that job after the cancel channel was closed.
181
+ select {
182
+ case <- jobs [numSigJobs - 1 ].Resp :
183
+ t .Fatalf ("Job cancellation failed" )
184
+ default :
185
+ }
186
+ }
187
+
188
+ // TestAuxLeafSignerCancelAndQuit tests that the AuxLeafSigner will handle a
189
+ // quit signal correctly, which involves ending sig job handling as soon as
190
+ // possible. This test also sends a cancel signal before the quit signal, to
191
+ // check that quits are handled correctly alongside other sent signals.
192
+ func TestAuxLeafSignerCancelAndQuit (t * testing.T ) {
193
+ // Constructing multiple jobs will allow us to assert that later jobs
194
+ // are skipped successfully after sending the quit signal.
195
+ signer , cancelChan , commitTx , jobs := setupAuxLeafSigner (t , numSigJobs )
196
+ defer func () {
197
+ require .NoError (t , signer .Stop ())
198
+ }()
199
+
200
+ err := signer .SubmitSecondLevelSigBatch (chanState , commitTx , jobs )
201
+ require .NoError (t , err )
202
+
203
+ select {
204
+ case <- time .After (testTimeout ):
205
+ t .Fatalf ("timeout waiting for response" )
206
+ case <- jobs [sigJobCancelThreshold ].Resp :
207
+ // Another component could have sent the cancel signal; we'll
208
+ // send that before the quit signal.
209
+ close (cancelChan )
210
+ time .Sleep (time .Millisecond )
211
+
212
+ // Send the quit signal; jobs at the end of the batch should not
213
+ // be processed.
214
+ require .NoError (t , signer .Stop ())
215
+ }
216
+
217
+ // Once the aux signer stops, the last job of the batch should have an
218
+ // an empty response. Otherwise, the signer failed to stop as soon as
219
+ // the quit signal was sent.
220
+ select {
221
+ case <- jobs [numSigJobs - 1 ].Resp :
222
+ t .Fatalf ("Aux signer quitting failed" )
223
+ default :
224
+ }
225
+ }
226
+
134
227
// mockVirtualSigner is a mock implementation of the VirtualSigner interface.
135
228
type mockVirtualSigner struct {
136
229
}
0 commit comments