• 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
/peer/test_utils.go
1
package peer
2

3
import (
4
        "bytes"
5
        crand "crypto/rand"
6
        "encoding/binary"
7
        "io"
8
        "math/rand"
9
        "net"
10
        "sync/atomic"
11
        "testing"
12
        "time"
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/chainntnfs"
19
        "github.com/lightningnetwork/lnd/channeldb"
20
        "github.com/lightningnetwork/lnd/channelnotifier"
21
        "github.com/lightningnetwork/lnd/fn"
22
        "github.com/lightningnetwork/lnd/htlcswitch"
23
        "github.com/lightningnetwork/lnd/input"
24
        "github.com/lightningnetwork/lnd/keychain"
25
        "github.com/lightningnetwork/lnd/lntest/channels"
26
        "github.com/lightningnetwork/lnd/lntest/mock"
27
        "github.com/lightningnetwork/lnd/lnwallet"
28
        "github.com/lightningnetwork/lnd/lnwallet/chainfee"
29
        "github.com/lightningnetwork/lnd/lnwire"
30
        "github.com/lightningnetwork/lnd/netann"
31
        "github.com/lightningnetwork/lnd/pool"
32
        "github.com/lightningnetwork/lnd/queue"
33
        "github.com/lightningnetwork/lnd/shachain"
34
        "github.com/stretchr/testify/require"
35
)
36

37
const (
38
        broadcastHeight = 100
39

40
        // timeout is a timeout value to use for tests which need to wait for
41
        // a return value on a channel.
42
        timeout = time.Second * 5
43

44
        // testCltvRejectDelta is the minimum delta between expiry and current
45
        // height below which htlcs are rejected.
46
        testCltvRejectDelta = 13
47
)
48

49
var (
50
        testKeyLoc = keychain.KeyLocator{Family: keychain.KeyFamilyNodeKey}
51
)
52

53
// noUpdate is a function which can be used as a parameter in
54
// createTestPeerWithChannel to call the setup code with no custom values on
55
// the channels set up.
56
var noUpdate = func(a, b *channeldb.OpenChannel) {}
×
57

58
type peerTestCtx struct {
59
        peer          *Brontide
60
        channel       *lnwallet.LightningChannel
61
        notifier      *mock.ChainNotifier
62
        publishTx     <-chan *wire.MsgTx
63
        mockSwitch    *mockMessageSwitch
64
        db            *channeldb.DB
65
        privKey       *btcec.PrivateKey
66
        mockConn      *mockMessageConn
67
        customChan    chan *customMsg
68
        chanStatusMgr *netann.ChanStatusManager
69
}
70

71
// createTestPeerWithChannel creates a channel between two nodes, and returns a
72
// peer for one of the nodes, together with the channel seen from both nodes.
73
// It takes an updateChan function which can be used to modify the default
74
// values on the channel states for each peer.
75
func createTestPeerWithChannel(t *testing.T, updateChan func(a,
76
        b *channeldb.OpenChannel)) (*peerTestCtx, error) {
×
77

×
78
        params := createTestPeer(t)
×
79

×
80
        var (
×
81
                publishTx     = params.publishTx
×
82
                mockSwitch    = params.mockSwitch
×
83
                alicePeer     = params.peer
×
84
                notifier      = params.notifier
×
85
                aliceKeyPriv  = params.privKey
×
86
                dbAlice       = params.db
×
87
                chanStatusMgr = params.chanStatusMgr
×
88
        )
×
89

×
90
        err := chanStatusMgr.Start()
×
91
        require.NoError(t, err)
×
92
        t.Cleanup(func() {
×
93
                require.NoError(t, chanStatusMgr.Stop())
×
94
        })
×
95

96
        aliceKeyPub := alicePeer.IdentityKey()
×
97
        estimator := alicePeer.cfg.FeeEstimator
×
98

×
99
        channelCapacity := btcutil.Amount(10 * 1e8)
×
100
        channelBal := channelCapacity / 2
×
101
        aliceDustLimit := btcutil.Amount(200)
×
102
        bobDustLimit := btcutil.Amount(1300)
×
103
        csvTimeoutAlice := uint32(5)
×
104
        csvTimeoutBob := uint32(4)
×
105
        isAliceInitiator := true
×
106

×
107
        prevOut := &wire.OutPoint{
×
108
                Hash:  channels.TestHdSeed,
×
109
                Index: 0,
×
110
        }
×
111
        fundingTxIn := wire.NewTxIn(prevOut, nil, nil)
×
112

×
113
        bobKeyPriv, bobKeyPub := btcec.PrivKeyFromBytes(
×
114
                channels.BobsPrivKey,
×
115
        )
×
116

×
117
        aliceCfg := channeldb.ChannelConfig{
×
118
                ChannelStateBounds: channeldb.ChannelStateBounds{
×
119
                        MaxPendingAmount: lnwire.MilliSatoshi(rand.Int63()),
×
120
                        ChanReserve:      btcutil.Amount(rand.Int63()),
×
121
                        MinHTLC:          lnwire.MilliSatoshi(rand.Int63()),
×
122
                        MaxAcceptedHtlcs: uint16(rand.Int31()),
×
123
                },
×
124
                CommitmentParams: channeldb.CommitmentParams{
×
125
                        DustLimit: aliceDustLimit,
×
126
                        CsvDelay:  uint16(csvTimeoutAlice),
×
127
                },
×
128
                MultiSigKey: keychain.KeyDescriptor{
×
129
                        PubKey: aliceKeyPub,
×
130
                },
×
131
                RevocationBasePoint: keychain.KeyDescriptor{
×
132
                        PubKey: aliceKeyPub,
×
133
                },
×
134
                PaymentBasePoint: keychain.KeyDescriptor{
×
135
                        PubKey: aliceKeyPub,
×
136
                },
×
137
                DelayBasePoint: keychain.KeyDescriptor{
×
138
                        PubKey: aliceKeyPub,
×
139
                },
×
140
                HtlcBasePoint: keychain.KeyDescriptor{
×
141
                        PubKey: aliceKeyPub,
×
142
                },
×
143
        }
×
144
        bobCfg := channeldb.ChannelConfig{
×
145
                ChannelStateBounds: channeldb.ChannelStateBounds{
×
146
                        MaxPendingAmount: lnwire.MilliSatoshi(rand.Int63()),
×
147
                        ChanReserve:      btcutil.Amount(rand.Int63()),
×
148
                        MinHTLC:          lnwire.MilliSatoshi(rand.Int63()),
×
149
                        MaxAcceptedHtlcs: uint16(rand.Int31()),
×
150
                },
×
151
                CommitmentParams: channeldb.CommitmentParams{
×
152
                        DustLimit: bobDustLimit,
×
153
                        CsvDelay:  uint16(csvTimeoutBob),
×
154
                },
×
155
                MultiSigKey: keychain.KeyDescriptor{
×
156
                        PubKey: bobKeyPub,
×
157
                },
×
158
                RevocationBasePoint: keychain.KeyDescriptor{
×
159
                        PubKey: bobKeyPub,
×
160
                },
×
161
                PaymentBasePoint: keychain.KeyDescriptor{
×
162
                        PubKey: bobKeyPub,
×
163
                },
×
164
                DelayBasePoint: keychain.KeyDescriptor{
×
165
                        PubKey: bobKeyPub,
×
166
                },
×
167
                HtlcBasePoint: keychain.KeyDescriptor{
×
168
                        PubKey: bobKeyPub,
×
169
                },
×
170
        }
×
171

×
172
        bobRoot, err := chainhash.NewHash(bobKeyPriv.Serialize())
×
173
        if err != nil {
×
174
                return nil, err
×
175
        }
×
176
        bobPreimageProducer := shachain.NewRevocationProducer(*bobRoot)
×
177
        bobFirstRevoke, err := bobPreimageProducer.AtIndex(0)
×
178
        if err != nil {
×
179
                return nil, err
×
180
        }
×
181
        bobCommitPoint := input.ComputeCommitmentPoint(bobFirstRevoke[:])
×
182

×
183
        aliceRoot, err := chainhash.NewHash(aliceKeyPriv.Serialize())
×
184
        if err != nil {
×
185
                return nil, err
×
186
        }
×
187
        alicePreimageProducer := shachain.NewRevocationProducer(*aliceRoot)
×
188
        aliceFirstRevoke, err := alicePreimageProducer.AtIndex(0)
×
189
        if err != nil {
×
190
                return nil, err
×
191
        }
×
192
        aliceCommitPoint := input.ComputeCommitmentPoint(aliceFirstRevoke[:])
×
193

×
194
        aliceCommitTx, bobCommitTx, err := lnwallet.CreateCommitmentTxns(
×
195
                channelBal, channelBal, &aliceCfg, &bobCfg, aliceCommitPoint,
×
196
                bobCommitPoint, *fundingTxIn, channeldb.SingleFunderTweaklessBit,
×
197
                isAliceInitiator, 0,
×
198
        )
×
199
        if err != nil {
×
200
                return nil, err
×
201
        }
×
202

203
        dbBob, err := channeldb.Open(t.TempDir())
×
204
        if err != nil {
×
205
                return nil, err
×
206
        }
×
207
        t.Cleanup(func() {
×
208
                require.NoError(t, dbBob.Close())
×
209
        })
×
210

211
        feePerKw, err := estimator.EstimateFeePerKW(1)
×
212
        if err != nil {
×
213
                return nil, err
×
214
        }
×
215

216
        // TODO(roasbeef): need to factor in commit fee?
217
        aliceCommit := channeldb.ChannelCommitment{
×
218
                CommitHeight:  0,
×
219
                LocalBalance:  lnwire.NewMSatFromSatoshis(channelBal),
×
220
                RemoteBalance: lnwire.NewMSatFromSatoshis(channelBal),
×
221
                FeePerKw:      btcutil.Amount(feePerKw),
×
222
                CommitFee:     feePerKw.FeeForWeight(input.CommitWeight),
×
223
                CommitTx:      aliceCommitTx,
×
224
                CommitSig:     bytes.Repeat([]byte{1}, 71),
×
225
        }
×
226
        bobCommit := channeldb.ChannelCommitment{
×
227
                CommitHeight:  0,
×
228
                LocalBalance:  lnwire.NewMSatFromSatoshis(channelBal),
×
229
                RemoteBalance: lnwire.NewMSatFromSatoshis(channelBal),
×
230
                FeePerKw:      btcutil.Amount(feePerKw),
×
231
                CommitFee:     feePerKw.FeeForWeight(input.CommitWeight),
×
232
                CommitTx:      bobCommitTx,
×
233
                CommitSig:     bytes.Repeat([]byte{1}, 71),
×
234
        }
×
235

×
236
        var chanIDBytes [8]byte
×
237
        if _, err := io.ReadFull(crand.Reader, chanIDBytes[:]); err != nil {
×
238
                return nil, err
×
239
        }
×
240

241
        shortChanID := lnwire.NewShortChanIDFromInt(
×
242
                binary.BigEndian.Uint64(chanIDBytes[:]),
×
243
        )
×
244

×
245
        aliceChannelState := &channeldb.OpenChannel{
×
246
                LocalChanCfg:            aliceCfg,
×
247
                RemoteChanCfg:           bobCfg,
×
248
                IdentityPub:             aliceKeyPub,
×
249
                FundingOutpoint:         *prevOut,
×
250
                ShortChannelID:          shortChanID,
×
251
                ChanType:                channeldb.SingleFunderTweaklessBit,
×
252
                IsInitiator:             isAliceInitiator,
×
253
                Capacity:                channelCapacity,
×
254
                RemoteCurrentRevocation: bobCommitPoint,
×
255
                RevocationProducer:      alicePreimageProducer,
×
256
                RevocationStore:         shachain.NewRevocationStore(),
×
257
                LocalCommitment:         aliceCommit,
×
258
                RemoteCommitment:        aliceCommit,
×
259
                Db:                      dbAlice.ChannelStateDB(),
×
260
                Packager:                channeldb.NewChannelPackager(shortChanID),
×
261
                FundingTxn:              channels.TestFundingTx,
×
262
        }
×
263
        bobChannelState := &channeldb.OpenChannel{
×
264
                LocalChanCfg:            bobCfg,
×
265
                RemoteChanCfg:           aliceCfg,
×
266
                IdentityPub:             bobKeyPub,
×
267
                FundingOutpoint:         *prevOut,
×
268
                ChanType:                channeldb.SingleFunderTweaklessBit,
×
269
                IsInitiator:             !isAliceInitiator,
×
270
                Capacity:                channelCapacity,
×
271
                RemoteCurrentRevocation: aliceCommitPoint,
×
272
                RevocationProducer:      bobPreimageProducer,
×
273
                RevocationStore:         shachain.NewRevocationStore(),
×
274
                LocalCommitment:         bobCommit,
×
275
                RemoteCommitment:        bobCommit,
×
276
                Db:                      dbBob.ChannelStateDB(),
×
277
                Packager:                channeldb.NewChannelPackager(shortChanID),
×
278
        }
×
279

×
280
        // Set custom values on the channel states.
×
281
        updateChan(aliceChannelState, bobChannelState)
×
282

×
283
        aliceAddr := alicePeer.cfg.Addr.Address
×
284
        if err := aliceChannelState.SyncPending(aliceAddr, 0); err != nil {
×
285
                return nil, err
×
286
        }
×
287

288
        bobAddr := &net.TCPAddr{
×
289
                IP:   net.ParseIP("127.0.0.1"),
×
290
                Port: 18556,
×
291
        }
×
292

×
293
        if err := bobChannelState.SyncPending(bobAddr, 0); err != nil {
×
294
                return nil, err
×
295
        }
×
296

297
        aliceSigner := input.NewMockSigner(
×
298
                []*btcec.PrivateKey{aliceKeyPriv}, nil,
×
299
        )
×
300
        bobSigner := input.NewMockSigner(
×
301
                []*btcec.PrivateKey{bobKeyPriv}, nil,
×
302
        )
×
303

×
304
        alicePool := lnwallet.NewSigPool(1, aliceSigner)
×
305
        channelAlice, err := lnwallet.NewLightningChannel(
×
306
                aliceSigner, aliceChannelState, alicePool,
×
307
                lnwallet.WithLeafStore(&lnwallet.MockAuxLeafStore{}),
×
308
                lnwallet.WithAuxSigner(lnwallet.NewAuxSignerMock(
×
309
                        lnwallet.EmptyMockJobHandler,
×
310
                )),
×
311
        )
×
312
        if err != nil {
×
313
                return nil, err
×
314
        }
×
315
        _ = alicePool.Start()
×
316
        t.Cleanup(func() {
×
317
                require.NoError(t, alicePool.Stop())
×
318
        })
×
319

320
        bobPool := lnwallet.NewSigPool(1, bobSigner)
×
321
        channelBob, err := lnwallet.NewLightningChannel(
×
322
                bobSigner, bobChannelState, bobPool,
×
323
                lnwallet.WithLeafStore(&lnwallet.MockAuxLeafStore{}),
×
324
                lnwallet.WithAuxSigner(lnwallet.NewAuxSignerMock(
×
325
                        lnwallet.EmptyMockJobHandler,
×
326
                )),
×
327
        )
×
328
        if err != nil {
×
329
                return nil, err
×
330
        }
×
331
        _ = bobPool.Start()
×
332
        t.Cleanup(func() {
×
333
                require.NoError(t, bobPool.Stop())
×
334
        })
×
335

336
        alicePeer.remoteFeatures = lnwire.NewFeatureVector(
×
337
                nil, lnwire.Features,
×
338
        )
×
339

×
340
        chanID := lnwire.NewChanIDFromOutPoint(channelAlice.ChannelPoint())
×
341
        alicePeer.activeChannels.Store(chanID, channelAlice)
×
342

×
343
        alicePeer.wg.Add(1)
×
344
        go alicePeer.channelManager()
×
345

×
346
        return &peerTestCtx{
×
347
                peer:       alicePeer,
×
348
                channel:    channelBob,
×
349
                notifier:   notifier,
×
350
                publishTx:  publishTx,
×
351
                mockSwitch: mockSwitch,
×
352
                mockConn:   params.mockConn,
×
353
        }, nil
×
354
}
355

356
// mockMessageSwitch is a mock implementation of the messageSwitch interface
357
// used for testing without relying on a *htlcswitch.Switch in unit tests.
358
type mockMessageSwitch struct {
359
        links []htlcswitch.ChannelUpdateHandler
360
}
361

362
// BestHeight currently returns a dummy value.
363
func (m *mockMessageSwitch) BestHeight() uint32 {
×
364
        return 0
×
365
}
×
366

367
// CircuitModifier currently returns a dummy value.
368
func (m *mockMessageSwitch) CircuitModifier() htlcswitch.CircuitModifier {
×
369
        return nil
×
370
}
×
371

372
// RemoveLink currently does nothing.
373
func (m *mockMessageSwitch) RemoveLink(cid lnwire.ChannelID) {}
×
374

375
// CreateAndAddLink currently returns a dummy value.
376
func (m *mockMessageSwitch) CreateAndAddLink(cfg htlcswitch.ChannelLinkConfig,
377
        lnChan *lnwallet.LightningChannel) error {
×
378

×
379
        return nil
×
380
}
×
381

382
// GetLinksByInterface returns the active links.
383
func (m *mockMessageSwitch) GetLinksByInterface(pub [33]byte) (
384
        []htlcswitch.ChannelUpdateHandler, error) {
×
385

×
386
        return m.links, nil
×
387
}
×
388

389
// mockUpdateHandler is a mock implementation of the ChannelUpdateHandler
390
// interface. It is used in mockMessageSwitch's GetLinksByInterface method.
391
type mockUpdateHandler struct {
392
        cid                  lnwire.ChannelID
393
        isOutgoingAddBlocked atomic.Bool
394
        isIncomingAddBlocked atomic.Bool
395
}
396

397
// newMockUpdateHandler creates a new mockUpdateHandler.
398
func newMockUpdateHandler(cid lnwire.ChannelID) *mockUpdateHandler {
×
399
        return &mockUpdateHandler{
×
400
                cid: cid,
×
401
        }
×
402
}
×
403

404
// HandleChannelUpdate currently does nothing.
405
func (m *mockUpdateHandler) HandleChannelUpdate(msg lnwire.Message) {}
×
406

407
// ChanID returns the mockUpdateHandler's cid.
408
func (m *mockUpdateHandler) ChanID() lnwire.ChannelID { return m.cid }
×
409

410
// Bandwidth currently returns a dummy value.
411
func (m *mockUpdateHandler) Bandwidth() lnwire.MilliSatoshi { return 0 }
×
412

413
// EligibleToForward currently returns a dummy value.
414
func (m *mockUpdateHandler) EligibleToForward() bool { return false }
×
415

416
// MayAddOutgoingHtlc currently returns nil.
417
func (m *mockUpdateHandler) MayAddOutgoingHtlc(lnwire.MilliSatoshi) error { return nil }
×
418

419
type mockMessageConn struct {
420
        t *testing.T
421

422
        // MessageConn embeds our interface so that the mock does not need to
423
        // implement every function. The mock will panic if an unspecified function
424
        // is called.
425
        MessageConn
426

427
        // writtenMessages is a channel that our mock pushes written messages into.
428
        writtenMessages chan []byte
429

430
        readMessages   chan []byte
431
        curReadMessage []byte
432

433
        // writeRaceDetectingCounter is incremented on any function call
434
        // associated with writing to the connection. The race detector will
435
        // trigger on this counter if a data race exists.
436
        writeRaceDetectingCounter int
437

438
        // readRaceDetectingCounter is incremented on any function call
439
        // associated with reading from the connection. The race detector will
440
        // trigger on this counter if a data race exists.
441
        readRaceDetectingCounter int
442
}
443

444
func (m *mockUpdateHandler) EnableAdds(dir htlcswitch.LinkDirection) bool {
×
445
        if dir == htlcswitch.Outgoing {
×
446
                return m.isOutgoingAddBlocked.Swap(false)
×
447
        }
×
448

449
        return m.isIncomingAddBlocked.Swap(false)
×
450
}
451

452
func (m *mockUpdateHandler) DisableAdds(dir htlcswitch.LinkDirection) bool {
×
453
        if dir == htlcswitch.Outgoing {
×
454
                return !m.isOutgoingAddBlocked.Swap(true)
×
455
        }
×
456

457
        return !m.isIncomingAddBlocked.Swap(true)
×
458
}
459

460
func (m *mockUpdateHandler) IsFlushing(dir htlcswitch.LinkDirection) bool {
×
461
        switch dir {
×
462
        case htlcswitch.Outgoing:
×
463
                return m.isOutgoingAddBlocked.Load()
×
464
        case htlcswitch.Incoming:
×
465
                return m.isIncomingAddBlocked.Load()
×
466
        }
467

468
        return false
×
469
}
470

471
func (m *mockUpdateHandler) OnFlushedOnce(hook func()) {
×
472
        hook()
×
473
}
×
474
func (m *mockUpdateHandler) OnCommitOnce(
475
        _ htlcswitch.LinkDirection, hook func(),
476
) {
×
477

×
478
        hook()
×
479
}
×
480

481
func newMockConn(t *testing.T, expectedMessages int) *mockMessageConn {
×
482
        return &mockMessageConn{
×
483
                t:               t,
×
484
                writtenMessages: make(chan []byte, expectedMessages),
×
485
                readMessages:    make(chan []byte, 1),
×
486
        }
×
487
}
×
488

489
// SetWriteDeadline mocks setting write deadline for our conn.
490
func (m *mockMessageConn) SetWriteDeadline(time.Time) error {
×
491
        m.writeRaceDetectingCounter++
×
492
        return nil
×
493
}
×
494

495
// Flush mocks a message conn flush.
496
func (m *mockMessageConn) Flush() (int, error) {
×
497
        m.writeRaceDetectingCounter++
×
498
        return 0, nil
×
499
}
×
500

501
// WriteMessage mocks sending of a message on our connection. It will push
502
// the bytes sent into the mock's writtenMessages channel.
503
func (m *mockMessageConn) WriteMessage(msg []byte) error {
×
504
        m.writeRaceDetectingCounter++
×
505

×
506
        msgCopy := make([]byte, len(msg))
×
507
        copy(msgCopy, msg)
×
508

×
509
        select {
×
510
        case m.writtenMessages <- msgCopy:
×
511
        case <-time.After(timeout):
×
512
                m.t.Fatalf("timeout sending message: %v", msgCopy)
×
513
        }
514

515
        return nil
×
516
}
517

518
// assertWrite asserts that our mock as had WriteMessage called with the byte
519
// slice we expect.
520
func (m *mockMessageConn) assertWrite(expected []byte) {
×
521
        select {
×
522
        case actual := <-m.writtenMessages:
×
523
                require.Equal(m.t, expected, actual)
×
524

525
        case <-time.After(timeout):
×
526
                m.t.Fatalf("timeout waiting for write: %v", expected)
×
527
        }
528
}
529

530
func (m *mockMessageConn) SetReadDeadline(t time.Time) error {
×
531
        m.readRaceDetectingCounter++
×
532
        return nil
×
533
}
×
534

535
func (m *mockMessageConn) ReadNextHeader() (uint32, error) {
×
536
        m.readRaceDetectingCounter++
×
537
        m.curReadMessage = <-m.readMessages
×
538
        return uint32(len(m.curReadMessage)), nil
×
539
}
×
540

541
func (m *mockMessageConn) ReadNextBody(buf []byte) ([]byte, error) {
×
542
        m.readRaceDetectingCounter++
×
543
        return m.curReadMessage, nil
×
544
}
×
545

546
func (m *mockMessageConn) RemoteAddr() net.Addr {
×
547
        return nil
×
548
}
×
549

550
func (m *mockMessageConn) LocalAddr() net.Addr {
×
551
        return nil
×
552
}
×
553

554
func (m *mockMessageConn) Close() error {
×
555
        return nil
×
556
}
×
557

558
// createTestPeer creates a new peer for testing and returns a context struct
559
// containing necessary handles and mock objects for conducting tests on peer
560
// functionalities.
561
func createTestPeer(t *testing.T) *peerTestCtx {
×
562
        nodeKeyLocator := keychain.KeyLocator{
×
563
                Family: keychain.KeyFamilyNodeKey,
×
564
        }
×
565

×
566
        aliceKeyPriv, aliceKeyPub := btcec.PrivKeyFromBytes(
×
567
                channels.AlicesPrivKey,
×
568
        )
×
569

×
570
        aliceKeySigner := keychain.NewPrivKeyMessageSigner(
×
571
                aliceKeyPriv, nodeKeyLocator,
×
572
        )
×
573

×
574
        aliceAddr := &net.TCPAddr{
×
575
                IP:   net.ParseIP("127.0.0.1"),
×
576
                Port: 18555,
×
577
        }
×
578
        cfgAddr := &lnwire.NetAddress{
×
579
                IdentityKey: aliceKeyPub,
×
580
                Address:     aliceAddr,
×
581
                ChainNet:    wire.SimNet,
×
582
        }
×
583

×
584
        errBuffer, err := queue.NewCircularBuffer(ErrorBufferSize)
×
585
        require.NoError(t, err)
×
586

×
587
        chainIO := &mock.ChainIO{
×
588
                BestHeight: broadcastHeight,
×
589
        }
×
590

×
591
        publishTx := make(chan *wire.MsgTx)
×
592
        wallet := &lnwallet.LightningWallet{
×
593
                WalletController: &mock.WalletController{
×
594
                        RootKey:               aliceKeyPriv,
×
595
                        PublishedTransactions: publishTx,
×
596
                },
×
597
        }
×
598

×
599
        const chanActiveTimeout = time.Minute
×
600

×
601
        dbAlice, err := channeldb.Open(t.TempDir())
×
602
        require.NoError(t, err)
×
603
        t.Cleanup(func() {
×
604
                require.NoError(t, dbAlice.Close())
×
605
        })
×
606

607
        nodeSignerAlice := netann.NewNodeSigner(aliceKeySigner)
×
608

×
609
        chanStatusMgr, err := netann.NewChanStatusManager(&netann.
×
610
                ChanStatusConfig{
×
611
                ChanStatusSampleInterval: 30 * time.Second,
×
612
                ChanEnableTimeout:        chanActiveTimeout,
×
613
                ChanDisableTimeout:       2 * time.Minute,
×
614
                DB:                       dbAlice.ChannelStateDB(),
×
615
                Graph:                    dbAlice.ChannelGraph(),
×
616
                MessageSigner:            nodeSignerAlice,
×
617
                OurPubKey:                aliceKeyPub,
×
618
                OurKeyLoc:                testKeyLoc,
×
619
                IsChannelActive: func(lnwire.ChannelID) bool {
×
620
                        return true
×
621
                },
×
622
                ApplyChannelUpdate: func(*lnwire.ChannelUpdate1,
623
                        *wire.OutPoint, bool) error {
×
624

×
625
                        return nil
×
626
                },
×
627
        })
628
        require.NoError(t, err)
×
629

×
630
        interceptableSwitchNotifier := &mock.ChainNotifier{
×
631
                EpochChan: make(chan *chainntnfs.BlockEpoch, 1),
×
632
        }
×
633
        interceptableSwitchNotifier.EpochChan <- &chainntnfs.BlockEpoch{
×
634
                Height: 1,
×
635
        }
×
636

×
637
        interceptableSwitch, err := htlcswitch.NewInterceptableSwitch(
×
638
                &htlcswitch.InterceptableSwitchConfig{
×
639
                        CltvRejectDelta:    testCltvRejectDelta,
×
640
                        CltvInterceptDelta: testCltvRejectDelta + 3,
×
641
                        Notifier:           interceptableSwitchNotifier,
×
642
                },
×
643
        )
×
644
        require.NoError(t, err)
×
645

×
646
        // TODO(yy): create interface for lnwallet.LightningChannel so we can
×
647
        // easily mock it without the following setups.
×
648
        notifier := &mock.ChainNotifier{
×
649
                SpendChan: make(chan *chainntnfs.SpendDetail),
×
650
                EpochChan: make(chan *chainntnfs.BlockEpoch),
×
651
                ConfChan:  make(chan *chainntnfs.TxConfirmation),
×
652
        }
×
653

×
654
        mockSwitch := &mockMessageSwitch{}
×
655

×
656
        // TODO(yy): change ChannelNotifier to be an interface.
×
657
        channelNotifier := channelnotifier.New(dbAlice.ChannelStateDB())
×
658
        require.NoError(t, channelNotifier.Start())
×
659
        t.Cleanup(func() {
×
660
                require.NoError(t, channelNotifier.Stop(),
×
661
                        "stop channel notifier failed")
×
662
        })
×
663

664
        writeBufferPool := pool.NewWriteBuffer(
×
665
                pool.DefaultWriteBufferGCInterval,
×
666
                pool.DefaultWriteBufferExpiryInterval,
×
667
        )
×
668

×
669
        writePool := pool.NewWrite(
×
670
                writeBufferPool, 1, timeout,
×
671
        )
×
672
        require.NoError(t, writePool.Start())
×
673

×
674
        readBufferPool := pool.NewReadBuffer(
×
675
                pool.DefaultReadBufferGCInterval,
×
676
                pool.DefaultReadBufferExpiryInterval,
×
677
        )
×
678

×
679
        readPool := pool.NewRead(
×
680
                readBufferPool, 1, timeout,
×
681
        )
×
682
        require.NoError(t, readPool.Start())
×
683

×
684
        mockConn := newMockConn(t, 1)
×
685

×
686
        receivedCustomChan := make(chan *customMsg)
×
687

×
688
        var pubKey [33]byte
×
689
        copy(pubKey[:], aliceKeyPub.SerializeCompressed())
×
690

×
691
        estimator := chainfee.NewStaticEstimator(12500, 0)
×
692

×
693
        cfg := &Config{
×
694
                Addr:              cfgAddr,
×
695
                PubKeyBytes:       pubKey,
×
696
                ErrorBuffer:       errBuffer,
×
697
                ChainIO:           chainIO,
×
698
                Switch:            mockSwitch,
×
699
                ChanActiveTimeout: chanActiveTimeout,
×
700
                InterceptSwitch:   interceptableSwitch,
×
701
                ChannelDB:         dbAlice.ChannelStateDB(),
×
702
                FeeEstimator:      estimator,
×
703
                Wallet:            wallet,
×
704
                ChainNotifier:     notifier,
×
705
                ChanStatusMgr:     chanStatusMgr,
×
706
                Features: lnwire.NewFeatureVector(
×
707
                        nil, lnwire.Features,
×
708
                ),
×
709
                DisconnectPeer: func(b *btcec.PublicKey) error {
×
710
                        return nil
×
711
                },
×
712
                ChannelNotifier:               channelNotifier,
713
                PrunePersistentPeerConnection: func([33]byte) {},
×
714
                LegacyFeatures:                lnwire.EmptyFeatureVector(),
715
                WritePool:                     writePool,
716
                ReadPool:                      readPool,
717
                Conn:                          mockConn,
718
                HandleCustomMessage: func(
719
                        peer [33]byte, msg *lnwire.Custom) error {
×
720

×
721
                        receivedCustomChan <- &customMsg{
×
722
                                peer: peer,
×
723
                                msg:  *msg,
×
724
                        }
×
725

×
726
                        return nil
×
727
                },
×
728
                PongBuf: make([]byte, lnwire.MaxPongBytes),
729
                FetchLastChanUpdate: func(chanID lnwire.ShortChannelID,
730
                ) (*lnwire.ChannelUpdate1, error) {
×
731

×
732
                        return &lnwire.ChannelUpdate1{}, nil
×
733
                },
×
734
        }
735

736
        alicePeer := NewBrontide(*cfg)
×
737

×
738
        return &peerTestCtx{
×
739
                publishTx:     publishTx,
×
740
                mockSwitch:    mockSwitch,
×
741
                peer:          alicePeer,
×
742
                notifier:      notifier,
×
743
                db:            dbAlice,
×
744
                privKey:       aliceKeyPriv,
×
745
                mockConn:      mockConn,
×
746
                customChan:    receivedCustomChan,
×
747
                chanStatusMgr: chanStatusMgr,
×
748
        }
×
749
}
750

751
// startPeer invokes the `Start` method on the specified peer and handles any
752
// initial startup messages for testing.
753
func startPeer(t *testing.T, mockConn *mockMessageConn,
754
        peer *Brontide) <-chan struct{} {
×
755

×
756
        // Start the peer in a goroutine so that we can handle and test for
×
757
        // startup messages. Successfully sending and receiving init message,
×
758
        // indicates a successful startup.
×
759
        done := make(chan struct{})
×
760
        go func() {
×
761
                require.NoError(t, peer.Start())
×
762
                close(done)
×
763
        }()
×
764

765
        // Receive the init message that should be the first message received on
766
        // startup.
767
        rawMsg, err := fn.RecvOrTimeout[[]byte](
×
768
                mockConn.writtenMessages, timeout,
×
769
        )
×
770
        require.NoError(t, err)
×
771

×
772
        msgReader := bytes.NewReader(rawMsg)
×
773
        nextMsg, err := lnwire.ReadMessage(msgReader, 0)
×
774
        require.NoError(t, err)
×
775

×
776
        _, ok := nextMsg.(*lnwire.Init)
×
777
        require.True(t, ok)
×
778

×
779
        // Write the reply for the init message to complete the startup.
×
780
        initReplyMsg := lnwire.NewInitMessage(
×
781
                lnwire.NewRawFeatureVector(
×
782
                        lnwire.DataLossProtectRequired,
×
783
                        lnwire.GossipQueriesOptional,
×
784
                ),
×
785
                lnwire.NewRawFeatureVector(),
×
786
        )
×
787

×
788
        var b bytes.Buffer
×
789
        _, err = lnwire.WriteMessage(&b, initReplyMsg, 0)
×
790
        require.NoError(t, err)
×
791

×
792
        ok = fn.SendOrQuit[[]byte, struct{}](
×
793
                mockConn.readMessages, b.Bytes(), make(chan struct{}),
×
794
        )
×
795
        require.True(t, ok)
×
796

×
797
        return done
×
798
}
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