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

lightningnetwork / lnd / 12033440129

26 Nov 2024 03:03PM UTC coverage: 48.738% (-10.3%) from 58.999%
12033440129

Pull #9309

github

yyforyongyu
gomod: update `btcd` for shutdown fix
Pull Request #9309: chainntnfs: fix `TestHistoricalConfDetailsTxIndex`

97664 of 200385 relevant lines covered (48.74%)

0.52 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,
121
        *LightningChannel, error) {
×
122

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

×
380
        auxSigner := NewDefaultAuxSignerMock(t)
×
381

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

396
        obfuscator := createStateHintObfuscator(aliceChannelState)
×
397

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

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

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

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

×
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.
444
        err = initRevocationWindows(channelAlice, channelBob)
×
445
        if err != nil {
×
446
                return nil, nil, err
×
447
        }
×
448

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.
454
func initMusigNonce(chanA, chanB *LightningChannel) error {
×
455
        chanANonces, err := chanA.GenMusigNonces()
×
456
        if err != nil {
×
457
                return err
×
458
        }
×
459
        chanBNonces, err := chanB.GenMusigNonces()
×
460
        if err != nil {
×
461
                return err
×
462
        }
×
463

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

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.
477
func initRevocationWindows(chanA, chanB *LightningChannel) error {
×
478
        // If these are taproot chanenls, then we need to also simulate sending
×
479
        // either FundingLocked or ChannelReestablish by calling
×
480
        // InitRemoteMusigNonces for both sides.
×
481
        if chanA.channelState.ChanType.IsTaproot() {
×
482
                if err := initMusigNonce(chanA, chanB); err != nil {
×
483
                        return err
×
484
                }
×
485
        }
486

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

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

503
        return nil
×
504
}
505

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

515
// privkeyFromHex parses a Bitcoin private key from a hex encoded string.
516
func privkeyFromHex(keyHex string) (*btcec.PrivateKey, error) {
×
517
        bytes, err := hex.DecodeString(keyHex)
×
518
        if err != nil {
×
519
                return nil, err
×
520
        }
×
521
        key, _ := btcec.PrivKeyFromBytes(bytes)
×
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.
536
func txFromHex(txHex string) (*btcutil.Tx, error) {
×
537
        bytes, err := hex.DecodeString(txHex)
×
538
        if err != nil {
×
539
                return nil, err
×
540
        }
×
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.
549
func calcStaticFee(chanType channeldb.ChannelType, numHTLCs int) btcutil.Amount {
×
550
        const (
×
551
                htlcWeight = 172
×
552
                feePerKw   = btcutil.Amount(24/4) * 1000
×
553
        )
×
554
        htlcsWeight := htlcWeight * int64(numHTLCs)
×
555
        totalWeight := CommitWeight(chanType) + lntypes.WeightUnit(htlcsWeight)
×
556

×
557
        return feePerKw * (btcutil.Amount(totalWeight)) / 1000
×
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.
564
func ForceStateTransition(chanA, chanB *LightningChannel) error {
×
565
        aliceNewCommit, err := chanA.SignNextCommitment(ctxb)
×
566
        if err != nil {
×
567
                return err
×
568
        }
×
569
        err = chanB.ReceiveNewCommitment(aliceNewCommit.CommitSigs)
×
570
        if err != nil {
×
571
                return err
×
572
        }
×
573

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

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

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

601
        return nil
×
602
}
603

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

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

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

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

×
636
        return auxSigner
×
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