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

lightningnetwork / lnd / 13035292482

29 Jan 2025 03:59PM UTC coverage: 49.3% (-9.5%) from 58.777%
13035292482

Pull #9456

github

mohamedawnallah
docs: update release-notes-0.19.0.md

In this commit, we warn users about the removal
of RPCs `SendToRoute`, `SendToRouteSync`, `SendPayment`,
and `SendPaymentSync` in the next release 0.20.
Pull Request #9456: lnrpc+docs: deprecate warning `SendToRoute`, `SendToRouteSync`, `SendPayment`, and `SendPaymentSync` in Release 0.19

100634 of 204126 relevant lines covered (49.3%)

1.54 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/v2"
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 := channeldb.OpenForTesting(t, t.TempDir(), dbModifiers...)
×
247
        dbBob := channeldb.OpenForTesting(t, t.TempDir(), dbModifiers...)
×
248

×
249
        estimator := chainfee.NewStaticEstimator(6000, 0)
×
250
        feePerKw, err := estimator.EstimateFeePerKW(1)
×
251
        if err != nil {
×
252
                return nil, nil, err
×
253
        }
×
254
        commitFee := calcStaticFee(chanType, 0)
×
255
        var anchorAmt btcutil.Amount
×
256
        if chanType.HasAnchors() {
×
257
                anchorAmt += 2 * AnchorSize
×
258
        }
×
259

260
        aliceBalance := lnwire.NewMSatFromSatoshis(
×
261
                channelBal - commitFee - anchorAmt,
×
262
        )
×
263
        bobBalance := lnwire.NewMSatFromSatoshis(channelBal)
×
264

×
265
        aliceLocalCommit := channeldb.ChannelCommitment{
×
266
                CommitHeight:  0,
×
267
                LocalBalance:  aliceBalance,
×
268
                RemoteBalance: bobBalance,
×
269
                CommitFee:     commitFee,
×
270
                FeePerKw:      btcutil.Amount(feePerKw),
×
271
                CommitTx:      aliceCommitTx,
×
272
                CommitSig:     testSigBytes,
×
273
        }
×
274
        aliceRemoteCommit := channeldb.ChannelCommitment{
×
275
                CommitHeight:  0,
×
276
                LocalBalance:  aliceBalance,
×
277
                RemoteBalance: bobBalance,
×
278
                CommitFee:     commitFee,
×
279
                FeePerKw:      btcutil.Amount(feePerKw),
×
280
                CommitTx:      bobCommitTx,
×
281
                CommitSig:     testSigBytes,
×
282
        }
×
283
        bobLocalCommit := channeldb.ChannelCommitment{
×
284
                CommitHeight:  0,
×
285
                LocalBalance:  bobBalance,
×
286
                RemoteBalance: aliceBalance,
×
287
                CommitFee:     commitFee,
×
288
                FeePerKw:      btcutil.Amount(feePerKw),
×
289
                CommitTx:      bobCommitTx,
×
290
                CommitSig:     testSigBytes,
×
291
        }
×
292
        bobRemoteCommit := channeldb.ChannelCommitment{
×
293
                CommitHeight:  0,
×
294
                LocalBalance:  bobBalance,
×
295
                RemoteBalance: aliceBalance,
×
296
                CommitFee:     commitFee,
×
297
                FeePerKw:      btcutil.Amount(feePerKw),
×
298
                CommitTx:      aliceCommitTx,
×
299
                CommitSig:     testSigBytes,
×
300
        }
×
301

×
302
        var chanIDBytes [8]byte
×
303
        if _, err := io.ReadFull(rand.Reader, chanIDBytes[:]); err != nil {
×
304
                return nil, nil, err
×
305
        }
×
306

307
        shortChanID := lnwire.NewShortChanIDFromInt(
×
308
                binary.BigEndian.Uint64(chanIDBytes[:]),
×
309
        )
×
310

×
311
        aliceChannelState := &channeldb.OpenChannel{
×
312
                LocalChanCfg:            aliceCfg,
×
313
                RemoteChanCfg:           bobCfg,
×
314
                IdentityPub:             aliceKeys[0].PubKey(),
×
315
                FundingOutpoint:         *prevOut,
×
316
                ShortChannelID:          shortChanID,
×
317
                ChanType:                chanType,
×
318
                IsInitiator:             isAliceInitiator,
×
319
                Capacity:                channelCapacity,
×
320
                RemoteCurrentRevocation: bobCommitPoint,
×
321
                RevocationProducer:      alicePreimageProducer,
×
322
                RevocationStore:         shachain.NewRevocationStore(),
×
323
                LocalCommitment:         aliceLocalCommit,
×
324
                RemoteCommitment:        aliceRemoteCommit,
×
325
                Db:                      dbAlice.ChannelStateDB(),
×
326
                Packager:                channeldb.NewChannelPackager(shortChanID),
×
327
                FundingTxn:              testTx,
×
328
        }
×
329
        bobChannelState := &channeldb.OpenChannel{
×
330
                LocalChanCfg:            bobCfg,
×
331
                RemoteChanCfg:           aliceCfg,
×
332
                IdentityPub:             bobKeys[0].PubKey(),
×
333
                FundingOutpoint:         *prevOut,
×
334
                ShortChannelID:          shortChanID,
×
335
                ChanType:                chanType,
×
336
                IsInitiator:             !isAliceInitiator,
×
337
                Capacity:                channelCapacity,
×
338
                RemoteCurrentRevocation: aliceCommitPoint,
×
339
                RevocationProducer:      bobPreimageProducer,
×
340
                RevocationStore:         shachain.NewRevocationStore(),
×
341
                LocalCommitment:         bobLocalCommit,
×
342
                RemoteCommitment:        bobRemoteCommit,
×
343
                Db:                      dbBob.ChannelStateDB(),
×
344
                Packager:                channeldb.NewChannelPackager(shortChanID),
×
345
        }
×
346

×
347
        // If the channel type has a tapscript root, then we'll also specify
×
348
        // one here to apply to both the channels.
×
349
        if chanType.HasTapscriptRoot() {
×
350
                var tapscriptRoot chainhash.Hash
×
351
                _, err := io.ReadFull(rand.Reader, tapscriptRoot[:])
×
352
                if err != nil {
×
353
                        return nil, nil, err
×
354
                }
×
355

356
                someRoot := fn.Some(tapscriptRoot)
×
357

×
358
                aliceChannelState.TapscriptRoot = someRoot
×
359
                bobChannelState.TapscriptRoot = someRoot
×
360
        }
361

362
        aliceSigner := input.NewMockSigner(aliceKeys, nil)
×
363
        bobSigner := input.NewMockSigner(bobKeys, nil)
×
364

×
365
        // TODO(roasbeef): make mock version of pre-image store
×
366

×
367
        auxSigner := NewDefaultAuxSignerMock(t)
×
368

×
369
        alicePool := NewSigPool(1, aliceSigner)
×
370
        channelAlice, err := NewLightningChannel(
×
371
                aliceSigner, aliceChannelState, alicePool,
×
372
                WithLeafStore(&MockAuxLeafStore{}),
×
373
                WithAuxSigner(auxSigner),
×
374
        )
×
375
        if err != nil {
×
376
                return nil, nil, err
×
377
        }
×
378
        alicePool.Start()
×
379
        t.Cleanup(func() {
×
380
                require.NoError(t, alicePool.Stop())
×
381
        })
×
382

383
        obfuscator := createStateHintObfuscator(aliceChannelState)
×
384

×
385
        bobPool := NewSigPool(1, bobSigner)
×
386
        channelBob, err := NewLightningChannel(
×
387
                bobSigner, bobChannelState, bobPool,
×
388
                WithLeafStore(&MockAuxLeafStore{}),
×
389
                WithAuxSigner(auxSigner),
×
390
        )
×
391
        if err != nil {
×
392
                return nil, nil, err
×
393
        }
×
394
        bobPool.Start()
×
395
        t.Cleanup(func() {
×
396
                require.NoError(t, bobPool.Stop())
×
397
        })
×
398

399
        err = SetStateNumHint(
×
400
                aliceCommitTx, 0, obfuscator,
×
401
        )
×
402
        if err != nil {
×
403
                return nil, nil, err
×
404
        }
×
405
        err = SetStateNumHint(
×
406
                bobCommitTx, 0, obfuscator,
×
407
        )
×
408
        if err != nil {
×
409
                return nil, nil, err
×
410
        }
×
411

412
        addr := &net.TCPAddr{
×
413
                IP:   net.ParseIP("127.0.0.1"),
×
414
                Port: 18556,
×
415
        }
×
416
        if err := channelAlice.channelState.SyncPending(addr, 101); err != nil {
×
417
                return nil, nil, err
×
418
        }
×
419

420
        addr = &net.TCPAddr{
×
421
                IP:   net.ParseIP("127.0.0.1"),
×
422
                Port: 18555,
×
423
        }
×
424

×
425
        if err := channelBob.channelState.SyncPending(addr, 101); err != nil {
×
426
                return nil, nil, err
×
427
        }
×
428

429
        // Now that the channel are open, simulate the start of a session by
430
        // having Alice and Bob extend their revocation windows to each other.
431
        err = initRevocationWindows(channelAlice, channelBob)
×
432
        if err != nil {
×
433
                return nil, nil, err
×
434
        }
×
435

436
        return channelAlice, channelBob, nil
×
437
}
438

439
// initMusigNonce is used to manually setup musig2 nonces for a new channel,
440
// outside the normal chan-reest flow.
441
func initMusigNonce(chanA, chanB *LightningChannel) error {
×
442
        chanANonces, err := chanA.GenMusigNonces()
×
443
        if err != nil {
×
444
                return err
×
445
        }
×
446
        chanBNonces, err := chanB.GenMusigNonces()
×
447
        if err != nil {
×
448
                return err
×
449
        }
×
450

451
        if err := chanA.InitRemoteMusigNonces(chanBNonces); err != nil {
×
452
                return err
×
453
        }
×
454
        if err := chanB.InitRemoteMusigNonces(chanANonces); err != nil {
×
455
                return err
×
456
        }
×
457

458
        return nil
×
459
}
460

461
// initRevocationWindows simulates a new channel being opened within the p2p
462
// network by populating the initial revocation windows of the passed
463
// commitment state machines.
464
func initRevocationWindows(chanA, chanB *LightningChannel) error {
×
465
        // If these are taproot chanenls, then we need to also simulate sending
×
466
        // either FundingLocked or ChannelReestablish by calling
×
467
        // InitRemoteMusigNonces for both sides.
×
468
        if chanA.channelState.ChanType.IsTaproot() {
×
469
                if err := initMusigNonce(chanA, chanB); err != nil {
×
470
                        return err
×
471
                }
×
472
        }
473

474
        aliceNextRevoke, err := chanA.NextRevocationKey()
×
475
        if err != nil {
×
476
                return err
×
477
        }
×
478
        if err := chanB.InitNextRevocation(aliceNextRevoke); err != nil {
×
479
                return err
×
480
        }
×
481

482
        bobNextRevoke, err := chanB.NextRevocationKey()
×
483
        if err != nil {
×
484
                return err
×
485
        }
×
486
        if err := chanA.InitNextRevocation(bobNextRevoke); err != nil {
×
487
                return err
×
488
        }
×
489

490
        return nil
×
491
}
492

493
// pubkeyFromHex parses a Bitcoin public key from a hex encoded string.
494
func pubkeyFromHex(keyHex string) (*btcec.PublicKey, error) {
×
495
        bytes, err := hex.DecodeString(keyHex)
×
496
        if err != nil {
×
497
                return nil, err
×
498
        }
×
499
        return btcec.ParsePubKey(bytes)
×
500
}
501

502
// privkeyFromHex parses a Bitcoin private key from a hex encoded string.
503
func privkeyFromHex(keyHex string) (*btcec.PrivateKey, error) {
×
504
        bytes, err := hex.DecodeString(keyHex)
×
505
        if err != nil {
×
506
                return nil, err
×
507
        }
×
508
        key, _ := btcec.PrivKeyFromBytes(bytes)
×
509
        return key, nil
×
510

511
}
512

513
// blockFromHex parses a full Bitcoin block from a hex encoded string.
514
func blockFromHex(blockHex string) (*btcutil.Block, error) {
×
515
        bytes, err := hex.DecodeString(blockHex)
×
516
        if err != nil {
×
517
                return nil, err
×
518
        }
×
519
        return btcutil.NewBlockFromBytes(bytes)
×
520
}
521

522
// txFromHex parses a full Bitcoin transaction from a hex encoded string.
523
func txFromHex(txHex string) (*btcutil.Tx, error) {
×
524
        bytes, err := hex.DecodeString(txHex)
×
525
        if err != nil {
×
526
                return nil, err
×
527
        }
×
528
        return btcutil.NewTxFromBytes(bytes)
×
529
}
530

531
// calcStaticFee calculates appropriate fees for commitment transactions.  This
532
// function provides a simple way to allow test balance assertions to take fee
533
// calculations into account.
534
//
535
// TODO(bvu): Refactor when dynamic fee estimation is added.
536
func calcStaticFee(chanType channeldb.ChannelType, numHTLCs int) btcutil.Amount {
×
537
        const (
×
538
                htlcWeight = 172
×
539
                feePerKw   = btcutil.Amount(24/4) * 1000
×
540
        )
×
541
        htlcsWeight := htlcWeight * int64(numHTLCs)
×
542
        totalWeight := CommitWeight(chanType) + lntypes.WeightUnit(htlcsWeight)
×
543

×
544
        return feePerKw * (btcutil.Amount(totalWeight)) / 1000
×
545
}
×
546

547
// ForceStateTransition executes the necessary interaction between the two
548
// commitment state machines to transition to a new state locking in any
549
// pending updates. This method is useful when testing interactions between two
550
// live state machines.
551
func ForceStateTransition(chanA, chanB *LightningChannel) error {
×
552
        aliceNewCommit, err := chanA.SignNextCommitment(ctxb)
×
553
        if err != nil {
×
554
                return err
×
555
        }
×
556
        err = chanB.ReceiveNewCommitment(aliceNewCommit.CommitSigs)
×
557
        if err != nil {
×
558
                return err
×
559
        }
×
560

561
        bobRevocation, _, _, err := chanB.RevokeCurrentCommitment()
×
562
        if err != nil {
×
563
                return err
×
564
        }
×
565
        bobNewCommit, err := chanB.SignNextCommitment(ctxb)
×
566
        if err != nil {
×
567
                return err
×
568
        }
×
569

570
        _, _, err = chanA.ReceiveRevocation(bobRevocation)
×
571
        if err != nil {
×
572
                return err
×
573
        }
×
574
        err = chanA.ReceiveNewCommitment(bobNewCommit.CommitSigs)
×
575
        if err != nil {
×
576
                return err
×
577
        }
×
578

579
        aliceRevocation, _, _, err := chanA.RevokeCurrentCommitment()
×
580
        if err != nil {
×
581
                return err
×
582
        }
×
583
        _, _, err = chanB.ReceiveRevocation(aliceRevocation)
×
584
        if err != nil {
×
585
                return err
×
586
        }
×
587

588
        return nil
×
589
}
590

591
func NewDefaultAuxSignerMock(t *testing.T) *MockAuxSigner {
×
592
        auxSigner := NewAuxSignerMock(EmptyMockJobHandler)
×
593

×
594
        type testSigBlob struct {
×
595
                BlobInt tlv.RecordT[tlv.TlvType65634, uint16]
×
596
        }
×
597

×
598
        var sigBlobBuf bytes.Buffer
×
599
        sigBlob := testSigBlob{
×
600
                BlobInt: tlv.NewPrimitiveRecord[tlv.TlvType65634, uint16](5),
×
601
        }
×
602
        tlvStream, err := tlv.NewStream(sigBlob.BlobInt.Record())
×
603
        require.NoError(t, err, "unable to create tlv stream")
×
604
        require.NoError(t, tlvStream.Encode(&sigBlobBuf))
×
605

×
606
        auxSigner.On(
×
607
                "SubmitSecondLevelSigBatch", mock.Anything, mock.Anything,
×
608
                mock.Anything,
×
609
        ).Return(nil)
×
610
        auxSigner.On(
×
611
                "PackSigs", mock.Anything,
×
612
        ).Return(fn.Ok(fn.Some(sigBlobBuf.Bytes())))
×
613
        auxSigner.On(
×
614
                "UnpackSigs", mock.Anything,
×
615
        ).Return(fn.Ok([]fn.Option[tlv.Blob]{
×
616
                fn.Some(sigBlobBuf.Bytes()),
×
617
        }))
×
618
        auxSigner.On(
×
619
                "VerifySecondLevelSigs", mock.Anything, mock.Anything,
×
620
                mock.Anything,
×
621
        ).Return(nil)
×
622

×
623
        return auxSigner
×
624
}
×
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