• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lightningnetwork / lnd / 12026968820

26 Nov 2024 08:48AM UTC coverage: 49.896% (-9.1%) from 58.999%
12026968820

Pull #9303

github

yyforyongyu
lnwallet: add debug logs
Pull Request #9303: htlcswitch+routing: handle nil pointer dereference properly

20 of 23 new or added lines in 4 files covered. (86.96%)

25375 existing lines in 428 files now uncovered.

99993 of 200404 relevant lines covered (49.9%)

2.07 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/lnwallet/test_utils.go
1
package lnwallet
2

3
import (
4
        "bytes"
5
        "context"
6
        "crypto/rand"
7
        "encoding/binary"
8
        "encoding/hex"
9
        "io"
10
        prand "math/rand"
11
        "net"
12
        "testing"
13

14
        "github.com/btcsuite/btcd/btcec/v2"
15
        "github.com/btcsuite/btcd/btcutil"
16
        "github.com/btcsuite/btcd/chaincfg/chainhash"
17
        "github.com/btcsuite/btcd/wire"
18
        "github.com/lightningnetwork/lnd/channeldb"
19
        "github.com/lightningnetwork/lnd/fn"
20
        "github.com/lightningnetwork/lnd/input"
21
        "github.com/lightningnetwork/lnd/keychain"
22
        "github.com/lightningnetwork/lnd/lntypes"
23
        "github.com/lightningnetwork/lnd/lnwallet/chainfee"
24
        "github.com/lightningnetwork/lnd/lnwire"
25
        "github.com/lightningnetwork/lnd/shachain"
26
        "github.com/lightningnetwork/lnd/tlv"
27
        "github.com/stretchr/testify/mock"
28
        "github.com/stretchr/testify/require"
29
)
30

31
var (
32
        // For simplicity a single priv key controls all of our test outputs.
33
        testWalletPrivKey = []byte{
34
                0x2b, 0xd8, 0x06, 0xc9, 0x7f, 0x0e, 0x00, 0xaf,
35
                0x1a, 0x1f, 0xc3, 0x32, 0x8f, 0xa7, 0x63, 0xa9,
36
                0x26, 0x97, 0x23, 0xc8, 0xdb, 0x8f, 0xac, 0x4f,
37
                0x93, 0xaf, 0x71, 0xdb, 0x18, 0x6d, 0x6e, 0x90,
38
        }
39

40
        // We're alice :)
41
        bobsPrivKey = []byte{
42
                0x81, 0xb6, 0x37, 0xd8, 0xfc, 0xd2, 0xc6, 0xda,
43
                0x63, 0x59, 0xe6, 0x96, 0x31, 0x13, 0xa1, 0x17,
44
                0xd, 0xe7, 0x95, 0xe4, 0xb7, 0x25, 0xb8, 0x4d,
45
                0x1e, 0xb, 0x4c, 0xfd, 0x9e, 0xc5, 0x8c, 0xe9,
46
        }
47

48
        // Use a hard-coded HD seed.
49
        testHdSeed = chainhash.Hash{
50
                0xb7, 0x94, 0x38, 0x5f, 0x2d, 0x1e, 0xf7, 0xab,
51
                0x4d, 0x92, 0x73, 0xd1, 0x90, 0x63, 0x81, 0xb4,
52
                0x4f, 0x2f, 0x6f, 0x25, 0x88, 0xa3, 0xef, 0xb9,
53
                0x6a, 0x49, 0x18, 0x83, 0x31, 0x98, 0x47, 0x53,
54
        }
55

56
        // A serializable txn for testing funding txn.
57
        testTx = &wire.MsgTx{
58
                Version: 1,
59
                TxIn: []*wire.TxIn{
60
                        {
61
                                PreviousOutPoint: wire.OutPoint{
62
                                        Hash:  chainhash.Hash{},
63
                                        Index: 0xffffffff,
64
                                },
65
                                SignatureScript: []byte{0x04, 0x31, 0xdc, 0x00, 0x1b, 0x01, 0x62},
66
                                Sequence:        0xffffffff,
67
                        },
68
                },
69
                TxOut: []*wire.TxOut{
70
                        {
71
                                Value: 5000000000,
72
                                PkScript: []byte{
73
                                        0x41, // OP_DATA_65
74
                                        0x04, 0xd6, 0x4b, 0xdf, 0xd0, 0x9e, 0xb1, 0xc5,
75
                                        0xfe, 0x29, 0x5a, 0xbd, 0xeb, 0x1d, 0xca, 0x42,
76
                                        0x81, 0xbe, 0x98, 0x8e, 0x2d, 0xa0, 0xb6, 0xc1,
77
                                        0xc6, 0xa5, 0x9d, 0xc2, 0x26, 0xc2, 0x86, 0x24,
78
                                        0xe1, 0x81, 0x75, 0xe8, 0x51, 0xc9, 0x6b, 0x97,
79
                                        0x3d, 0x81, 0xb0, 0x1c, 0xc3, 0x1f, 0x04, 0x78,
80
                                        0x34, 0xbc, 0x06, 0xd6, 0xd6, 0xed, 0xf6, 0x20,
81
                                        0xd1, 0x84, 0x24, 0x1a, 0x6a, 0xed, 0x8b, 0x63,
82
                                        0xa6, // 65-byte signature
83
                                        0xac, // OP_CHECKSIG
84
                                },
85
                        },
86
                },
87
                LockTime: 5,
88
        }
89

90
        // A valid, DER-encoded signature (taken from btcec unit tests).
91
        testSigBytes = []byte{
92
                0x30, 0x44, 0x02, 0x20, 0x4e, 0x45, 0xe1, 0x69,
93
                0x32, 0xb8, 0xaf, 0x51, 0x49, 0x61, 0xa1, 0xd3,
94
                0xa1, 0xa2, 0x5f, 0xdf, 0x3f, 0x4f, 0x77, 0x32,
95
                0xe9, 0xd6, 0x24, 0xc6, 0xc6, 0x15, 0x48, 0xab,
96
                0x5f, 0xb8, 0xcd, 0x41, 0x02, 0x20, 0x18, 0x15,
97
                0x22, 0xec, 0x8e, 0xca, 0x07, 0xde, 0x48, 0x60,
98
                0xa4, 0xac, 0xdd, 0x12, 0x90, 0x9d, 0x83, 0x1c,
99
                0xc5, 0x6c, 0xbb, 0xac, 0x46, 0x22, 0x08, 0x22,
100
                0x21, 0xa8, 0x76, 0x8d, 0x1d, 0x09,
101
        }
102

103
        aliceDustLimit = btcutil.Amount(200)
104
        bobDustLimit   = btcutil.Amount(1300)
105

106
        testChannelCapacity float64 = 10
107

108
        // ctxb is a context that will never be cancelled, that is used in
109
        // place of a real quit context.
110
        ctxb = context.Background()
111
)
112

113
// CreateTestChannels creates to fully populated channels to be used within
114
// testing fixtures. The channels will be returned as if the funding process
115
// has just completed.  The channel itself is funded with 10 BTC, with 5 BTC
116
// allocated to each side. Within the channel, Alice is the initiator. If
117
// tweaklessCommits is true, then the commits within the channels will use the
118
// new format, otherwise the legacy format.
119
func CreateTestChannels(t *testing.T, chanType channeldb.ChannelType,
120
        dbModifiers ...channeldb.OptionModifier) (*LightningChannel,
UNCOV
121
        *LightningChannel, error) {
×
UNCOV
122

×
UNCOV
123
        channelCapacity, err := btcutil.NewAmount(testChannelCapacity)
×
UNCOV
124
        if err != nil {
×
125
                return nil, nil, err
×
126
        }
×
127

UNCOV
128
        channelBal := channelCapacity / 2
×
UNCOV
129
        csvTimeoutAlice := uint32(5)
×
UNCOV
130
        csvTimeoutBob := uint32(4)
×
UNCOV
131
        isAliceInitiator := true
×
UNCOV
132

×
UNCOV
133
        prevOut := &wire.OutPoint{
×
UNCOV
134
                Hash:  chainhash.Hash(testHdSeed),
×
UNCOV
135
                Index: prand.Uint32(),
×
UNCOV
136
        }
×
UNCOV
137
        fundingTxIn := wire.NewTxIn(prevOut, nil, nil)
×
UNCOV
138

×
UNCOV
139
        // For each party, we'll create a distinct set of keys in order to
×
UNCOV
140
        // emulate the typical set up with live channels.
×
UNCOV
141
        var (
×
UNCOV
142
                aliceKeys []*btcec.PrivateKey
×
UNCOV
143
                bobKeys   []*btcec.PrivateKey
×
UNCOV
144
        )
×
UNCOV
145
        for i := 0; i < 5; i++ {
×
UNCOV
146
                key := make([]byte, len(testWalletPrivKey))
×
UNCOV
147
                copy(key[:], testWalletPrivKey[:])
×
UNCOV
148
                key[0] ^= byte(i + 1)
×
UNCOV
149

×
UNCOV
150
                aliceKey, _ := btcec.PrivKeyFromBytes(key)
×
UNCOV
151
                aliceKeys = append(aliceKeys, aliceKey)
×
UNCOV
152

×
UNCOV
153
                key = make([]byte, len(bobsPrivKey))
×
UNCOV
154
                copy(key[:], bobsPrivKey)
×
UNCOV
155
                key[0] ^= byte(i + 1)
×
UNCOV
156

×
UNCOV
157
                bobKey, _ := btcec.PrivKeyFromBytes(key)
×
UNCOV
158
                bobKeys = append(bobKeys, bobKey)
×
UNCOV
159
        }
×
160

UNCOV
161
        aliceCfg := channeldb.ChannelConfig{
×
UNCOV
162
                ChannelStateBounds: channeldb.ChannelStateBounds{
×
UNCOV
163
                        MaxPendingAmount: lnwire.NewMSatFromSatoshis(channelCapacity),
×
UNCOV
164
                        ChanReserve:      channelCapacity / 100,
×
UNCOV
165
                        MinHTLC:          0,
×
UNCOV
166
                        MaxAcceptedHtlcs: input.MaxHTLCNumber / 2,
×
UNCOV
167
                },
×
UNCOV
168
                CommitmentParams: channeldb.CommitmentParams{
×
UNCOV
169
                        DustLimit: aliceDustLimit,
×
UNCOV
170
                        CsvDelay:  uint16(csvTimeoutAlice),
×
UNCOV
171
                },
×
UNCOV
172
                MultiSigKey: keychain.KeyDescriptor{
×
UNCOV
173
                        PubKey: aliceKeys[0].PubKey(),
×
UNCOV
174
                },
×
UNCOV
175
                RevocationBasePoint: keychain.KeyDescriptor{
×
UNCOV
176
                        PubKey: aliceKeys[1].PubKey(),
×
UNCOV
177
                },
×
UNCOV
178
                PaymentBasePoint: keychain.KeyDescriptor{
×
UNCOV
179
                        PubKey: aliceKeys[2].PubKey(),
×
UNCOV
180
                },
×
UNCOV
181
                DelayBasePoint: keychain.KeyDescriptor{
×
UNCOV
182
                        PubKey: aliceKeys[3].PubKey(),
×
UNCOV
183
                },
×
UNCOV
184
                HtlcBasePoint: keychain.KeyDescriptor{
×
UNCOV
185
                        PubKey: aliceKeys[4].PubKey(),
×
UNCOV
186
                },
×
UNCOV
187
        }
×
UNCOV
188
        bobCfg := channeldb.ChannelConfig{
×
UNCOV
189
                ChannelStateBounds: channeldb.ChannelStateBounds{
×
UNCOV
190
                        MaxPendingAmount: lnwire.NewMSatFromSatoshis(channelCapacity),
×
UNCOV
191
                        ChanReserve:      channelCapacity / 100,
×
UNCOV
192
                        MinHTLC:          0,
×
UNCOV
193
                        MaxAcceptedHtlcs: input.MaxHTLCNumber / 2,
×
UNCOV
194
                },
×
UNCOV
195
                CommitmentParams: channeldb.CommitmentParams{
×
UNCOV
196
                        DustLimit: bobDustLimit,
×
UNCOV
197
                        CsvDelay:  uint16(csvTimeoutBob),
×
UNCOV
198
                },
×
UNCOV
199
                MultiSigKey: keychain.KeyDescriptor{
×
UNCOV
200
                        PubKey: bobKeys[0].PubKey(),
×
UNCOV
201
                },
×
UNCOV
202
                RevocationBasePoint: keychain.KeyDescriptor{
×
UNCOV
203
                        PubKey: bobKeys[1].PubKey(),
×
UNCOV
204
                },
×
UNCOV
205
                PaymentBasePoint: keychain.KeyDescriptor{
×
UNCOV
206
                        PubKey: bobKeys[2].PubKey(),
×
UNCOV
207
                },
×
UNCOV
208
                DelayBasePoint: keychain.KeyDescriptor{
×
UNCOV
209
                        PubKey: bobKeys[3].PubKey(),
×
UNCOV
210
                },
×
UNCOV
211
                HtlcBasePoint: keychain.KeyDescriptor{
×
UNCOV
212
                        PubKey: bobKeys[4].PubKey(),
×
UNCOV
213
                },
×
UNCOV
214
        }
×
UNCOV
215

×
UNCOV
216
        bobRoot, err := chainhash.NewHash(bobKeys[0].Serialize())
×
UNCOV
217
        if err != nil {
×
218
                return nil, nil, err
×
219
        }
×
UNCOV
220
        bobPreimageProducer := shachain.NewRevocationProducer(*bobRoot)
×
UNCOV
221
        bobFirstRevoke, err := bobPreimageProducer.AtIndex(0)
×
UNCOV
222
        if err != nil {
×
223
                return nil, nil, err
×
224
        }
×
UNCOV
225
        bobCommitPoint := input.ComputeCommitmentPoint(bobFirstRevoke[:])
×
UNCOV
226

×
UNCOV
227
        aliceRoot, err := chainhash.NewHash(aliceKeys[0].Serialize())
×
UNCOV
228
        if err != nil {
×
229
                return nil, nil, err
×
230
        }
×
UNCOV
231
        alicePreimageProducer := shachain.NewRevocationProducer(*aliceRoot)
×
UNCOV
232
        aliceFirstRevoke, err := alicePreimageProducer.AtIndex(0)
×
UNCOV
233
        if err != nil {
×
234
                return nil, nil, err
×
235
        }
×
UNCOV
236
        aliceCommitPoint := input.ComputeCommitmentPoint(aliceFirstRevoke[:])
×
UNCOV
237

×
UNCOV
238
        aliceCommitTx, bobCommitTx, err := CreateCommitmentTxns(
×
UNCOV
239
                channelBal, channelBal, &aliceCfg, &bobCfg, aliceCommitPoint,
×
UNCOV
240
                bobCommitPoint, *fundingTxIn, chanType, isAliceInitiator, 0,
×
UNCOV
241
        )
×
UNCOV
242
        if err != nil {
×
243
                return nil, nil, err
×
244
        }
×
245

UNCOV
246
        dbAlice, err := channeldb.Open(t.TempDir(), dbModifiers...)
×
UNCOV
247
        if err != nil {
×
248
                return nil, nil, err
×
249
        }
×
UNCOV
250
        t.Cleanup(func() {
×
UNCOV
251
                require.NoError(t, dbAlice.Close())
×
UNCOV
252
        })
×
253

UNCOV
254
        dbBob, err := channeldb.Open(t.TempDir(), dbModifiers...)
×
UNCOV
255
        if err != nil {
×
256
                return nil, nil, err
×
257
        }
×
UNCOV
258
        t.Cleanup(func() {
×
UNCOV
259
                require.NoError(t, dbBob.Close())
×
UNCOV
260
        })
×
261

UNCOV
262
        estimator := chainfee.NewStaticEstimator(6000, 0)
×
UNCOV
263
        feePerKw, err := estimator.EstimateFeePerKW(1)
×
UNCOV
264
        if err != nil {
×
265
                return nil, nil, err
×
266
        }
×
UNCOV
267
        commitFee := calcStaticFee(chanType, 0)
×
UNCOV
268
        var anchorAmt btcutil.Amount
×
UNCOV
269
        if chanType.HasAnchors() {
×
UNCOV
270
                anchorAmt += 2 * AnchorSize
×
UNCOV
271
        }
×
272

UNCOV
273
        aliceBalance := lnwire.NewMSatFromSatoshis(
×
UNCOV
274
                channelBal - commitFee - anchorAmt,
×
UNCOV
275
        )
×
UNCOV
276
        bobBalance := lnwire.NewMSatFromSatoshis(channelBal)
×
UNCOV
277

×
UNCOV
278
        aliceLocalCommit := channeldb.ChannelCommitment{
×
UNCOV
279
                CommitHeight:  0,
×
UNCOV
280
                LocalBalance:  aliceBalance,
×
UNCOV
281
                RemoteBalance: bobBalance,
×
UNCOV
282
                CommitFee:     commitFee,
×
UNCOV
283
                FeePerKw:      btcutil.Amount(feePerKw),
×
UNCOV
284
                CommitTx:      aliceCommitTx,
×
UNCOV
285
                CommitSig:     testSigBytes,
×
UNCOV
286
        }
×
UNCOV
287
        aliceRemoteCommit := channeldb.ChannelCommitment{
×
UNCOV
288
                CommitHeight:  0,
×
UNCOV
289
                LocalBalance:  aliceBalance,
×
UNCOV
290
                RemoteBalance: bobBalance,
×
UNCOV
291
                CommitFee:     commitFee,
×
UNCOV
292
                FeePerKw:      btcutil.Amount(feePerKw),
×
UNCOV
293
                CommitTx:      bobCommitTx,
×
UNCOV
294
                CommitSig:     testSigBytes,
×
UNCOV
295
        }
×
UNCOV
296
        bobLocalCommit := channeldb.ChannelCommitment{
×
UNCOV
297
                CommitHeight:  0,
×
UNCOV
298
                LocalBalance:  bobBalance,
×
UNCOV
299
                RemoteBalance: aliceBalance,
×
UNCOV
300
                CommitFee:     commitFee,
×
UNCOV
301
                FeePerKw:      btcutil.Amount(feePerKw),
×
UNCOV
302
                CommitTx:      bobCommitTx,
×
UNCOV
303
                CommitSig:     testSigBytes,
×
UNCOV
304
        }
×
UNCOV
305
        bobRemoteCommit := channeldb.ChannelCommitment{
×
UNCOV
306
                CommitHeight:  0,
×
UNCOV
307
                LocalBalance:  bobBalance,
×
UNCOV
308
                RemoteBalance: aliceBalance,
×
UNCOV
309
                CommitFee:     commitFee,
×
UNCOV
310
                FeePerKw:      btcutil.Amount(feePerKw),
×
UNCOV
311
                CommitTx:      aliceCommitTx,
×
UNCOV
312
                CommitSig:     testSigBytes,
×
UNCOV
313
        }
×
UNCOV
314

×
UNCOV
315
        var chanIDBytes [8]byte
×
UNCOV
316
        if _, err := io.ReadFull(rand.Reader, chanIDBytes[:]); err != nil {
×
317
                return nil, nil, err
×
318
        }
×
319

UNCOV
320
        shortChanID := lnwire.NewShortChanIDFromInt(
×
UNCOV
321
                binary.BigEndian.Uint64(chanIDBytes[:]),
×
UNCOV
322
        )
×
UNCOV
323

×
UNCOV
324
        aliceChannelState := &channeldb.OpenChannel{
×
UNCOV
325
                LocalChanCfg:            aliceCfg,
×
UNCOV
326
                RemoteChanCfg:           bobCfg,
×
UNCOV
327
                IdentityPub:             aliceKeys[0].PubKey(),
×
UNCOV
328
                FundingOutpoint:         *prevOut,
×
UNCOV
329
                ShortChannelID:          shortChanID,
×
UNCOV
330
                ChanType:                chanType,
×
UNCOV
331
                IsInitiator:             isAliceInitiator,
×
UNCOV
332
                Capacity:                channelCapacity,
×
UNCOV
333
                RemoteCurrentRevocation: bobCommitPoint,
×
UNCOV
334
                RevocationProducer:      alicePreimageProducer,
×
UNCOV
335
                RevocationStore:         shachain.NewRevocationStore(),
×
UNCOV
336
                LocalCommitment:         aliceLocalCommit,
×
UNCOV
337
                RemoteCommitment:        aliceRemoteCommit,
×
UNCOV
338
                Db:                      dbAlice.ChannelStateDB(),
×
UNCOV
339
                Packager:                channeldb.NewChannelPackager(shortChanID),
×
UNCOV
340
                FundingTxn:              testTx,
×
UNCOV
341
        }
×
UNCOV
342
        bobChannelState := &channeldb.OpenChannel{
×
UNCOV
343
                LocalChanCfg:            bobCfg,
×
UNCOV
344
                RemoteChanCfg:           aliceCfg,
×
UNCOV
345
                IdentityPub:             bobKeys[0].PubKey(),
×
UNCOV
346
                FundingOutpoint:         *prevOut,
×
UNCOV
347
                ShortChannelID:          shortChanID,
×
UNCOV
348
                ChanType:                chanType,
×
UNCOV
349
                IsInitiator:             !isAliceInitiator,
×
UNCOV
350
                Capacity:                channelCapacity,
×
UNCOV
351
                RemoteCurrentRevocation: aliceCommitPoint,
×
UNCOV
352
                RevocationProducer:      bobPreimageProducer,
×
UNCOV
353
                RevocationStore:         shachain.NewRevocationStore(),
×
UNCOV
354
                LocalCommitment:         bobLocalCommit,
×
UNCOV
355
                RemoteCommitment:        bobRemoteCommit,
×
UNCOV
356
                Db:                      dbBob.ChannelStateDB(),
×
UNCOV
357
                Packager:                channeldb.NewChannelPackager(shortChanID),
×
UNCOV
358
        }
×
UNCOV
359

×
UNCOV
360
        // If the channel type has a tapscript root, then we'll also specify
×
UNCOV
361
        // one here to apply to both the channels.
×
UNCOV
362
        if chanType.HasTapscriptRoot() {
×
UNCOV
363
                var tapscriptRoot chainhash.Hash
×
UNCOV
364
                _, err := io.ReadFull(rand.Reader, tapscriptRoot[:])
×
UNCOV
365
                if err != nil {
×
366
                        return nil, nil, err
×
367
                }
×
368

UNCOV
369
                someRoot := fn.Some(tapscriptRoot)
×
UNCOV
370

×
UNCOV
371
                aliceChannelState.TapscriptRoot = someRoot
×
UNCOV
372
                bobChannelState.TapscriptRoot = someRoot
×
373
        }
374

UNCOV
375
        aliceSigner := input.NewMockSigner(aliceKeys, nil)
×
UNCOV
376
        bobSigner := input.NewMockSigner(bobKeys, nil)
×
UNCOV
377

×
UNCOV
378
        // TODO(roasbeef): make mock version of pre-image store
×
UNCOV
379

×
UNCOV
380
        auxSigner := NewDefaultAuxSignerMock(t)
×
UNCOV
381

×
UNCOV
382
        alicePool := NewSigPool(1, aliceSigner)
×
UNCOV
383
        channelAlice, err := NewLightningChannel(
×
UNCOV
384
                aliceSigner, aliceChannelState, alicePool,
×
UNCOV
385
                WithLeafStore(&MockAuxLeafStore{}),
×
UNCOV
386
                WithAuxSigner(auxSigner),
×
UNCOV
387
        )
×
UNCOV
388
        if err != nil {
×
389
                return nil, nil, err
×
390
        }
×
UNCOV
391
        alicePool.Start()
×
UNCOV
392
        t.Cleanup(func() {
×
UNCOV
393
                require.NoError(t, alicePool.Stop())
×
UNCOV
394
        })
×
395

UNCOV
396
        obfuscator := createStateHintObfuscator(aliceChannelState)
×
UNCOV
397

×
UNCOV
398
        bobPool := NewSigPool(1, bobSigner)
×
UNCOV
399
        channelBob, err := NewLightningChannel(
×
UNCOV
400
                bobSigner, bobChannelState, bobPool,
×
UNCOV
401
                WithLeafStore(&MockAuxLeafStore{}),
×
UNCOV
402
                WithAuxSigner(auxSigner),
×
UNCOV
403
        )
×
UNCOV
404
        if err != nil {
×
405
                return nil, nil, err
×
406
        }
×
UNCOV
407
        bobPool.Start()
×
UNCOV
408
        t.Cleanup(func() {
×
UNCOV
409
                require.NoError(t, bobPool.Stop())
×
UNCOV
410
        })
×
411

UNCOV
412
        err = SetStateNumHint(
×
UNCOV
413
                aliceCommitTx, 0, obfuscator,
×
UNCOV
414
        )
×
UNCOV
415
        if err != nil {
×
416
                return nil, nil, err
×
417
        }
×
UNCOV
418
        err = SetStateNumHint(
×
UNCOV
419
                bobCommitTx, 0, obfuscator,
×
UNCOV
420
        )
×
UNCOV
421
        if err != nil {
×
422
                return nil, nil, err
×
423
        }
×
424

UNCOV
425
        addr := &net.TCPAddr{
×
UNCOV
426
                IP:   net.ParseIP("127.0.0.1"),
×
UNCOV
427
                Port: 18556,
×
UNCOV
428
        }
×
UNCOV
429
        if err := channelAlice.channelState.SyncPending(addr, 101); err != nil {
×
430
                return nil, nil, err
×
431
        }
×
432

UNCOV
433
        addr = &net.TCPAddr{
×
UNCOV
434
                IP:   net.ParseIP("127.0.0.1"),
×
UNCOV
435
                Port: 18555,
×
UNCOV
436
        }
×
UNCOV
437

×
UNCOV
438
        if err := channelBob.channelState.SyncPending(addr, 101); err != nil {
×
439
                return nil, nil, err
×
440
        }
×
441

442
        // Now that the channel are open, simulate the start of a session by
443
        // having Alice and Bob extend their revocation windows to each other.
UNCOV
444
        err = initRevocationWindows(channelAlice, channelBob)
×
UNCOV
445
        if err != nil {
×
446
                return nil, nil, err
×
447
        }
×
448

UNCOV
449
        return channelAlice, channelBob, nil
×
450
}
451

452
// initMusigNonce is used to manually setup musig2 nonces for a new channel,
453
// outside the normal chan-reest flow.
UNCOV
454
func initMusigNonce(chanA, chanB *LightningChannel) error {
×
UNCOV
455
        chanANonces, err := chanA.GenMusigNonces()
×
UNCOV
456
        if err != nil {
×
457
                return err
×
458
        }
×
UNCOV
459
        chanBNonces, err := chanB.GenMusigNonces()
×
UNCOV
460
        if err != nil {
×
461
                return err
×
462
        }
×
463

UNCOV
464
        if err := chanA.InitRemoteMusigNonces(chanBNonces); err != nil {
×
465
                return err
×
466
        }
×
UNCOV
467
        if err := chanB.InitRemoteMusigNonces(chanANonces); err != nil {
×
468
                return err
×
469
        }
×
470

UNCOV
471
        return nil
×
472
}
473

474
// initRevocationWindows simulates a new channel being opened within the p2p
475
// network by populating the initial revocation windows of the passed
476
// commitment state machines.
UNCOV
477
func initRevocationWindows(chanA, chanB *LightningChannel) error {
×
UNCOV
478
        // If these are taproot chanenls, then we need to also simulate sending
×
UNCOV
479
        // either FundingLocked or ChannelReestablish by calling
×
UNCOV
480
        // InitRemoteMusigNonces for both sides.
×
UNCOV
481
        if chanA.channelState.ChanType.IsTaproot() {
×
UNCOV
482
                if err := initMusigNonce(chanA, chanB); err != nil {
×
483
                        return err
×
484
                }
×
485
        }
486

UNCOV
487
        aliceNextRevoke, err := chanA.NextRevocationKey()
×
UNCOV
488
        if err != nil {
×
489
                return err
×
490
        }
×
UNCOV
491
        if err := chanB.InitNextRevocation(aliceNextRevoke); err != nil {
×
492
                return err
×
493
        }
×
494

UNCOV
495
        bobNextRevoke, err := chanB.NextRevocationKey()
×
UNCOV
496
        if err != nil {
×
497
                return err
×
498
        }
×
UNCOV
499
        if err := chanA.InitNextRevocation(bobNextRevoke); err != nil {
×
500
                return err
×
501
        }
×
502

UNCOV
503
        return nil
×
504
}
505

506
// pubkeyFromHex parses a Bitcoin public key from a hex encoded string.
UNCOV
507
func pubkeyFromHex(keyHex string) (*btcec.PublicKey, error) {
×
UNCOV
508
        bytes, err := hex.DecodeString(keyHex)
×
UNCOV
509
        if err != nil {
×
510
                return nil, err
×
511
        }
×
UNCOV
512
        return btcec.ParsePubKey(bytes)
×
513
}
514

515
// privkeyFromHex parses a Bitcoin private key from a hex encoded string.
UNCOV
516
func privkeyFromHex(keyHex string) (*btcec.PrivateKey, error) {
×
UNCOV
517
        bytes, err := hex.DecodeString(keyHex)
×
UNCOV
518
        if err != nil {
×
519
                return nil, err
×
520
        }
×
UNCOV
521
        key, _ := btcec.PrivKeyFromBytes(bytes)
×
UNCOV
522
        return key, nil
×
523

524
}
525

526
// blockFromHex parses a full Bitcoin block from a hex encoded string.
527
func blockFromHex(blockHex string) (*btcutil.Block, error) {
×
528
        bytes, err := hex.DecodeString(blockHex)
×
529
        if err != nil {
×
530
                return nil, err
×
531
        }
×
532
        return btcutil.NewBlockFromBytes(bytes)
×
533
}
534

535
// txFromHex parses a full Bitcoin transaction from a hex encoded string.
UNCOV
536
func txFromHex(txHex string) (*btcutil.Tx, error) {
×
UNCOV
537
        bytes, err := hex.DecodeString(txHex)
×
UNCOV
538
        if err != nil {
×
539
                return nil, err
×
540
        }
×
UNCOV
541
        return btcutil.NewTxFromBytes(bytes)
×
542
}
543

544
// calcStaticFee calculates appropriate fees for commitment transactions.  This
545
// function provides a simple way to allow test balance assertions to take fee
546
// calculations into account.
547
//
548
// TODO(bvu): Refactor when dynamic fee estimation is added.
UNCOV
549
func calcStaticFee(chanType channeldb.ChannelType, numHTLCs int) btcutil.Amount {
×
UNCOV
550
        const (
×
UNCOV
551
                htlcWeight = 172
×
UNCOV
552
                feePerKw   = btcutil.Amount(24/4) * 1000
×
UNCOV
553
        )
×
UNCOV
554
        htlcsWeight := htlcWeight * int64(numHTLCs)
×
UNCOV
555
        totalWeight := CommitWeight(chanType) + lntypes.WeightUnit(htlcsWeight)
×
UNCOV
556

×
UNCOV
557
        return feePerKw * (btcutil.Amount(totalWeight)) / 1000
×
UNCOV
558
}
×
559

560
// ForceStateTransition executes the necessary interaction between the two
561
// commitment state machines to transition to a new state locking in any
562
// pending updates. This method is useful when testing interactions between two
563
// live state machines.
UNCOV
564
func ForceStateTransition(chanA, chanB *LightningChannel) error {
×
UNCOV
565
        aliceNewCommit, err := chanA.SignNextCommitment(ctxb)
×
UNCOV
566
        if err != nil {
×
567
                return err
×
568
        }
×
UNCOV
569
        err = chanB.ReceiveNewCommitment(aliceNewCommit.CommitSigs)
×
UNCOV
570
        if err != nil {
×
571
                return err
×
572
        }
×
573

UNCOV
574
        bobRevocation, _, _, err := chanB.RevokeCurrentCommitment()
×
UNCOV
575
        if err != nil {
×
576
                return err
×
577
        }
×
UNCOV
578
        bobNewCommit, err := chanB.SignNextCommitment(ctxb)
×
UNCOV
579
        if err != nil {
×
580
                return err
×
581
        }
×
582

UNCOV
583
        _, _, err = chanA.ReceiveRevocation(bobRevocation)
×
UNCOV
584
        if err != nil {
×
585
                return err
×
586
        }
×
UNCOV
587
        err = chanA.ReceiveNewCommitment(bobNewCommit.CommitSigs)
×
UNCOV
588
        if err != nil {
×
589
                return err
×
590
        }
×
591

UNCOV
592
        aliceRevocation, _, _, err := chanA.RevokeCurrentCommitment()
×
UNCOV
593
        if err != nil {
×
594
                return err
×
595
        }
×
UNCOV
596
        _, _, err = chanB.ReceiveRevocation(aliceRevocation)
×
UNCOV
597
        if err != nil {
×
598
                return err
×
599
        }
×
600

UNCOV
601
        return nil
×
602
}
603

UNCOV
604
func NewDefaultAuxSignerMock(t *testing.T) *MockAuxSigner {
×
UNCOV
605
        auxSigner := NewAuxSignerMock(EmptyMockJobHandler)
×
UNCOV
606

×
UNCOV
607
        type testSigBlob struct {
×
UNCOV
608
                BlobInt tlv.RecordT[tlv.TlvType65634, uint16]
×
UNCOV
609
        }
×
UNCOV
610

×
UNCOV
611
        var sigBlobBuf bytes.Buffer
×
UNCOV
612
        sigBlob := testSigBlob{
×
UNCOV
613
                BlobInt: tlv.NewPrimitiveRecord[tlv.TlvType65634, uint16](5),
×
UNCOV
614
        }
×
UNCOV
615
        tlvStream, err := tlv.NewStream(sigBlob.BlobInt.Record())
×
UNCOV
616
        require.NoError(t, err, "unable to create tlv stream")
×
UNCOV
617
        require.NoError(t, tlvStream.Encode(&sigBlobBuf))
×
UNCOV
618

×
UNCOV
619
        auxSigner.On(
×
UNCOV
620
                "SubmitSecondLevelSigBatch", mock.Anything, mock.Anything,
×
UNCOV
621
                mock.Anything,
×
UNCOV
622
        ).Return(nil)
×
UNCOV
623
        auxSigner.On(
×
UNCOV
624
                "PackSigs", mock.Anything,
×
UNCOV
625
        ).Return(fn.Ok(fn.Some(sigBlobBuf.Bytes())))
×
UNCOV
626
        auxSigner.On(
×
UNCOV
627
                "UnpackSigs", mock.Anything,
×
UNCOV
628
        ).Return(fn.Ok([]fn.Option[tlv.Blob]{
×
UNCOV
629
                fn.Some(sigBlobBuf.Bytes()),
×
UNCOV
630
        }))
×
UNCOV
631
        auxSigner.On(
×
UNCOV
632
                "VerifySecondLevelSigs", mock.Anything, mock.Anything,
×
UNCOV
633
                mock.Anything,
×
UNCOV
634
        ).Return(nil)
×
UNCOV
635

×
UNCOV
636
        return auxSigner
×
UNCOV
637
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc