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

lightningnetwork / lnd / 15736109134

18 Jun 2025 02:46PM UTC coverage: 58.197% (-10.1%) from 68.248%
15736109134

Pull #9752

github

web-flow
Merge d2634a68c into 31c74f20f
Pull Request #9752: routerrpc: reject payment to invoice that don't have payment secret or blinded paths

6 of 13 new or added lines in 2 files covered. (46.15%)

28331 existing lines in 455 files now uncovered.

97860 of 168153 relevant lines covered (58.2%)

1.81 hits per line

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

0.0
/htlcswitch/mock.go
1
package htlcswitch
2

3
import (
4
        "bytes"
5
        "context"
6
        "crypto/sha256"
7
        "encoding/binary"
8
        "fmt"
9
        "io"
10
        "net"
11
        "path/filepath"
12
        "sync"
13
        "sync/atomic"
14
        "testing"
15
        "time"
16

17
        "github.com/btcsuite/btcd/btcec/v2"
18
        "github.com/btcsuite/btcd/btcec/v2/ecdsa"
19
        "github.com/btcsuite/btcd/btcutil"
20
        "github.com/btcsuite/btcd/wire"
21
        "github.com/go-errors/errors"
22
        sphinx "github.com/lightningnetwork/lightning-onion"
23
        "github.com/lightningnetwork/lnd/chainntnfs"
24
        "github.com/lightningnetwork/lnd/channeldb"
25
        "github.com/lightningnetwork/lnd/clock"
26
        "github.com/lightningnetwork/lnd/contractcourt"
27
        "github.com/lightningnetwork/lnd/fn/v2"
28
        "github.com/lightningnetwork/lnd/graph/db/models"
29
        "github.com/lightningnetwork/lnd/htlcswitch/hop"
30
        "github.com/lightningnetwork/lnd/invoices"
31
        "github.com/lightningnetwork/lnd/lnpeer"
32
        "github.com/lightningnetwork/lnd/lntest/mock"
33
        "github.com/lightningnetwork/lnd/lntypes"
34
        "github.com/lightningnetwork/lnd/lnwallet/chainfee"
35
        "github.com/lightningnetwork/lnd/lnwire"
36
        "github.com/lightningnetwork/lnd/ticker"
37
        "github.com/lightningnetwork/lnd/tlv"
38
)
39

UNCOV
40
func isAlias(scid lnwire.ShortChannelID) bool {
×
UNCOV
41
        return scid.BlockHeight >= 16_000_000 && scid.BlockHeight < 16_250_000
×
UNCOV
42
}
×
43

44
type mockPreimageCache struct {
45
        sync.Mutex
46
        preimageMap map[lntypes.Hash]lntypes.Preimage
47
}
48

UNCOV
49
func newMockPreimageCache() *mockPreimageCache {
×
UNCOV
50
        return &mockPreimageCache{
×
UNCOV
51
                preimageMap: make(map[lntypes.Hash]lntypes.Preimage),
×
UNCOV
52
        }
×
UNCOV
53
}
×
54

55
func (m *mockPreimageCache) LookupPreimage(
UNCOV
56
        hash lntypes.Hash) (lntypes.Preimage, bool) {
×
UNCOV
57

×
UNCOV
58
        m.Lock()
×
UNCOV
59
        defer m.Unlock()
×
UNCOV
60

×
UNCOV
61
        p, ok := m.preimageMap[hash]
×
UNCOV
62
        return p, ok
×
UNCOV
63
}
×
64

UNCOV
65
func (m *mockPreimageCache) AddPreimages(preimages ...lntypes.Preimage) error {
×
UNCOV
66
        m.Lock()
×
UNCOV
67
        defer m.Unlock()
×
UNCOV
68

×
UNCOV
69
        for _, preimage := range preimages {
×
UNCOV
70
                m.preimageMap[preimage.Hash()] = preimage
×
UNCOV
71
        }
×
72

UNCOV
73
        return nil
×
74
}
75

76
func (m *mockPreimageCache) SubscribeUpdates(
77
        chanID lnwire.ShortChannelID, htlc *channeldb.HTLC,
78
        payload *hop.Payload,
79
        nextHopOnionBlob []byte) (*contractcourt.WitnessSubscription, error) {
×
80

×
81
        return nil, nil
×
82
}
×
83

84
// TODO(yy): replace it with chainfee.MockEstimator.
85
type mockFeeEstimator struct {
86
        byteFeeIn chan chainfee.SatPerKWeight
87
        relayFee  chan chainfee.SatPerKWeight
88

89
        quit chan struct{}
90
}
91

UNCOV
92
func newMockFeeEstimator() *mockFeeEstimator {
×
UNCOV
93
        return &mockFeeEstimator{
×
UNCOV
94
                byteFeeIn: make(chan chainfee.SatPerKWeight),
×
UNCOV
95
                relayFee:  make(chan chainfee.SatPerKWeight),
×
UNCOV
96
                quit:      make(chan struct{}),
×
UNCOV
97
        }
×
UNCOV
98
}
×
99

100
func (m *mockFeeEstimator) EstimateFeePerKW(
UNCOV
101
        numBlocks uint32) (chainfee.SatPerKWeight, error) {
×
UNCOV
102

×
UNCOV
103
        select {
×
UNCOV
104
        case feeRate := <-m.byteFeeIn:
×
UNCOV
105
                return feeRate, nil
×
106
        case <-m.quit:
×
107
                return 0, fmt.Errorf("exiting")
×
108
        }
109
}
110

UNCOV
111
func (m *mockFeeEstimator) RelayFeePerKW() chainfee.SatPerKWeight {
×
UNCOV
112
        select {
×
UNCOV
113
        case feeRate := <-m.relayFee:
×
UNCOV
114
                return feeRate
×
115
        case <-m.quit:
×
116
                return 0
×
117
        }
118
}
119

120
func (m *mockFeeEstimator) Start() error {
×
121
        return nil
×
122
}
×
UNCOV
123
func (m *mockFeeEstimator) Stop() error {
×
UNCOV
124
        close(m.quit)
×
UNCOV
125
        return nil
×
UNCOV
126
}
×
127

128
var _ chainfee.Estimator = (*mockFeeEstimator)(nil)
129

130
type mockForwardingLog struct {
131
        sync.Mutex
132

133
        events map[time.Time]channeldb.ForwardingEvent
134
}
135

UNCOV
136
func (m *mockForwardingLog) AddForwardingEvents(events []channeldb.ForwardingEvent) error {
×
UNCOV
137
        m.Lock()
×
UNCOV
138
        defer m.Unlock()
×
UNCOV
139

×
UNCOV
140
        for _, event := range events {
×
UNCOV
141
                m.events[event.Timestamp] = event
×
UNCOV
142
        }
×
143

UNCOV
144
        return nil
×
145
}
146

147
type mockServer struct {
148
        started  int32 // To be used atomically.
149
        shutdown int32 // To be used atomically.
150
        wg       sync.WaitGroup
151
        quit     chan struct{}
152

153
        t testing.TB
154

155
        name             string
156
        messages         chan lnwire.Message
157
        protocolTraceMtx sync.Mutex
158
        protocolTrace    []lnwire.Message
159

160
        id         [33]byte
161
        htlcSwitch *Switch
162

163
        registry         *mockInvoiceRegistry
164
        pCache           *mockPreimageCache
165
        interceptorFuncs []messageInterceptor
166
}
167

168
var _ lnpeer.Peer = (*mockServer)(nil)
169

UNCOV
170
func initSwitchWithDB(startingHeight uint32, db *channeldb.DB) (*Switch, error) {
×
UNCOV
171
        signAliasUpdate := func(u *lnwire.ChannelUpdate1) (*ecdsa.Signature,
×
UNCOV
172
                error) {
×
UNCOV
173

×
UNCOV
174
                return testSig, nil
×
UNCOV
175
        }
×
176

UNCOV
177
        cfg := Config{
×
UNCOV
178
                DB:                   db,
×
UNCOV
179
                FetchAllOpenChannels: db.ChannelStateDB().FetchAllOpenChannels,
×
UNCOV
180
                FetchAllChannels:     db.ChannelStateDB().FetchAllChannels,
×
UNCOV
181
                FetchClosedChannels:  db.ChannelStateDB().FetchClosedChannels,
×
UNCOV
182
                SwitchPackager:       channeldb.NewSwitchPackager(),
×
UNCOV
183
                FwdingLog: &mockForwardingLog{
×
UNCOV
184
                        events: make(map[time.Time]channeldb.ForwardingEvent),
×
UNCOV
185
                },
×
UNCOV
186
                FetchLastChannelUpdate: func(scid lnwire.ShortChannelID) (
×
UNCOV
187
                        *lnwire.ChannelUpdate1, error) {
×
UNCOV
188

×
UNCOV
189
                        return &lnwire.ChannelUpdate1{
×
UNCOV
190
                                ShortChannelID: scid,
×
UNCOV
191
                        }, nil
×
UNCOV
192
                },
×
193
                Notifier: &mock.ChainNotifier{
194
                        SpendChan: make(chan *chainntnfs.SpendDetail),
195
                        EpochChan: make(chan *chainntnfs.BlockEpoch),
196
                        ConfChan:  make(chan *chainntnfs.TxConfirmation),
197
                },
198
                FwdEventTicker: ticker.NewForce(
199
                        DefaultFwdEventInterval,
200
                ),
201
                LogEventTicker:         ticker.NewForce(DefaultLogInterval),
202
                AckEventTicker:         ticker.NewForce(DefaultAckInterval),
203
                HtlcNotifier:           &mockHTLCNotifier{},
204
                Clock:                  clock.NewDefaultClock(),
205
                MailboxDeliveryTimeout: time.Hour,
206
                MaxFeeExposure:         DefaultMaxFeeExposure,
207
                SignAliasUpdate:        signAliasUpdate,
208
                IsAlias:                isAlias,
209
        }
210

UNCOV
211
        return New(cfg, startingHeight)
×
212
}
213

214
func initSwitchWithTempDB(t testing.TB, startingHeight uint32) (*Switch,
UNCOV
215
        error) {
×
UNCOV
216

×
UNCOV
217
        tempPath := filepath.Join(t.TempDir(), "switchdb")
×
UNCOV
218
        db := channeldb.OpenForTesting(t, tempPath)
×
UNCOV
219

×
UNCOV
220
        s, err := initSwitchWithDB(startingHeight, db)
×
UNCOV
221
        if err != nil {
×
222
                return nil, err
×
223
        }
×
224

UNCOV
225
        return s, nil
×
226
}
227

228
func newMockServer(t testing.TB, name string, startingHeight uint32,
UNCOV
229
        db *channeldb.DB, defaultDelta uint32) (*mockServer, error) {
×
UNCOV
230

×
UNCOV
231
        var id [33]byte
×
UNCOV
232
        h := sha256.Sum256([]byte(name))
×
UNCOV
233
        copy(id[:], h[:])
×
UNCOV
234

×
UNCOV
235
        pCache := newMockPreimageCache()
×
UNCOV
236

×
UNCOV
237
        var (
×
UNCOV
238
                htlcSwitch *Switch
×
UNCOV
239
                err        error
×
UNCOV
240
        )
×
UNCOV
241
        if db == nil {
×
UNCOV
242
                htlcSwitch, err = initSwitchWithTempDB(t, startingHeight)
×
UNCOV
243
        } else {
×
UNCOV
244
                htlcSwitch, err = initSwitchWithDB(startingHeight, db)
×
UNCOV
245
        }
×
UNCOV
246
        if err != nil {
×
247
                return nil, err
×
248
        }
×
249

UNCOV
250
        t.Cleanup(func() { _ = htlcSwitch.Stop() })
×
251

UNCOV
252
        registry := newMockRegistry(t)
×
UNCOV
253

×
UNCOV
254
        return &mockServer{
×
UNCOV
255
                t:                t,
×
UNCOV
256
                id:               id,
×
UNCOV
257
                name:             name,
×
UNCOV
258
                messages:         make(chan lnwire.Message, 3000),
×
UNCOV
259
                quit:             make(chan struct{}),
×
UNCOV
260
                registry:         registry,
×
UNCOV
261
                htlcSwitch:       htlcSwitch,
×
UNCOV
262
                pCache:           pCache,
×
UNCOV
263
                interceptorFuncs: make([]messageInterceptor, 0),
×
UNCOV
264
        }, nil
×
265
}
266

UNCOV
267
func (s *mockServer) Start() error {
×
UNCOV
268
        if !atomic.CompareAndSwapInt32(&s.started, 0, 1) {
×
269
                return errors.New("mock server already started")
×
270
        }
×
271

UNCOV
272
        if err := s.htlcSwitch.Start(); err != nil {
×
273
                return err
×
274
        }
×
275

UNCOV
276
        s.wg.Add(1)
×
UNCOV
277
        go func() {
×
UNCOV
278
                defer s.wg.Done()
×
UNCOV
279

×
UNCOV
280
                defer func() {
×
UNCOV
281
                        s.htlcSwitch.Stop()
×
UNCOV
282
                }()
×
283

UNCOV
284
                for {
×
UNCOV
285
                        select {
×
UNCOV
286
                        case msg := <-s.messages:
×
UNCOV
287
                                s.protocolTraceMtx.Lock()
×
UNCOV
288
                                s.protocolTrace = append(s.protocolTrace, msg)
×
UNCOV
289
                                s.protocolTraceMtx.Unlock()
×
UNCOV
290

×
UNCOV
291
                                var shouldSkip bool
×
UNCOV
292

×
UNCOV
293
                                for _, interceptor := range s.interceptorFuncs {
×
UNCOV
294
                                        skip, err := interceptor(msg)
×
UNCOV
295
                                        if err != nil {
×
296
                                                s.t.Fatalf("%v: error in the "+
×
297
                                                        "interceptor: %v", s.name, err)
×
298
                                                return
×
299
                                        }
×
UNCOV
300
                                        shouldSkip = shouldSkip || skip
×
301
                                }
302

UNCOV
303
                                if shouldSkip {
×
UNCOV
304
                                        continue
×
305
                                }
306

UNCOV
307
                                if err := s.readHandler(msg); err != nil {
×
308
                                        s.t.Fatal(err)
×
309
                                        return
×
310
                                }
×
UNCOV
311
                        case <-s.quit:
×
UNCOV
312
                                return
×
313
                        }
314
                }
315
        }()
316

UNCOV
317
        return nil
×
318
}
319

320
func (s *mockServer) QuitSignal() <-chan struct{} {
×
321
        return s.quit
×
322
}
×
323

324
// mockHopIterator represents the test version of hop iterator which instead
325
// of encrypting the path in onion blob just stores the path as a list of hops.
326
type mockHopIterator struct {
327
        hops []*hop.Payload
328
}
329

UNCOV
330
func newMockHopIterator(hops ...*hop.Payload) hop.Iterator {
×
UNCOV
331
        return &mockHopIterator{hops: hops}
×
UNCOV
332
}
×
333

UNCOV
334
func (r *mockHopIterator) HopPayload() (*hop.Payload, hop.RouteRole, error) {
×
UNCOV
335
        h := r.hops[0]
×
UNCOV
336
        r.hops = r.hops[1:]
×
UNCOV
337
        return h, hop.RouteRoleCleartext, nil
×
UNCOV
338
}
×
339

340
func (r *mockHopIterator) ExtraOnionBlob() []byte {
×
341
        return nil
×
342
}
×
343

344
func (r *mockHopIterator) ExtractErrorEncrypter(
345
        extracter hop.ErrorEncrypterExtracter, _ bool) (hop.ErrorEncrypter,
UNCOV
346
        lnwire.FailCode) {
×
UNCOV
347

×
UNCOV
348
        return extracter(nil)
×
UNCOV
349
}
×
350

UNCOV
351
func (r *mockHopIterator) EncodeNextHop(w io.Writer) error {
×
UNCOV
352
        var hopLength [4]byte
×
UNCOV
353
        binary.BigEndian.PutUint32(hopLength[:], uint32(len(r.hops)))
×
UNCOV
354

×
UNCOV
355
        if _, err := w.Write(hopLength[:]); err != nil {
×
356
                return err
×
357
        }
×
358

UNCOV
359
        for _, hop := range r.hops {
×
UNCOV
360
                fwdInfo := hop.ForwardingInfo()
×
UNCOV
361
                if err := encodeFwdInfo(w, &fwdInfo); err != nil {
×
362
                        return err
×
363
                }
×
364
        }
365

UNCOV
366
        return nil
×
367
}
368

UNCOV
369
func encodeFwdInfo(w io.Writer, f *hop.ForwardingInfo) error {
×
UNCOV
370
        if err := binary.Write(w, binary.BigEndian, f.NextHop); err != nil {
×
371
                return err
×
372
        }
×
373

UNCOV
374
        if err := binary.Write(w, binary.BigEndian, f.AmountToForward); err != nil {
×
375
                return err
×
376
        }
×
377

UNCOV
378
        if err := binary.Write(w, binary.BigEndian, f.OutgoingCTLV); err != nil {
×
379
                return err
×
380
        }
×
381

UNCOV
382
        return nil
×
383
}
384

385
var _ hop.Iterator = (*mockHopIterator)(nil)
386

387
// mockObfuscator mock implementation of the failure obfuscator which only
388
// encodes the failure and do not makes any onion obfuscation.
389
type mockObfuscator struct {
390
        ogPacket *sphinx.OnionPacket
391
        failure  lnwire.FailureMessage
392
}
393

394
// NewMockObfuscator initializes a dummy mockObfuscator used for testing.
UNCOV
395
func NewMockObfuscator() hop.ErrorEncrypter {
×
UNCOV
396
        return &mockObfuscator{}
×
UNCOV
397
}
×
398

399
func (o *mockObfuscator) OnionPacket() *sphinx.OnionPacket {
×
400
        return o.ogPacket
×
401
}
×
402

UNCOV
403
func (o *mockObfuscator) Type() hop.EncrypterType {
×
UNCOV
404
        return hop.EncrypterTypeMock
×
UNCOV
405
}
×
406

UNCOV
407
func (o *mockObfuscator) Encode(w io.Writer) error {
×
UNCOV
408
        return nil
×
UNCOV
409
}
×
410

UNCOV
411
func (o *mockObfuscator) Decode(r io.Reader) error {
×
UNCOV
412
        return nil
×
UNCOV
413
}
×
414

415
func (o *mockObfuscator) Reextract(
UNCOV
416
        extracter hop.ErrorEncrypterExtracter) error {
×
UNCOV
417

×
UNCOV
418
        return nil
×
UNCOV
419
}
×
420

421
var fakeHmac = []byte("hmachmachmachmachmachmachmachmac")
422

423
func (o *mockObfuscator) EncryptFirstHop(failure lnwire.FailureMessage) (
UNCOV
424
        lnwire.OpaqueReason, error) {
×
UNCOV
425

×
UNCOV
426
        o.failure = failure
×
UNCOV
427

×
UNCOV
428
        var b bytes.Buffer
×
UNCOV
429
        b.Write(fakeHmac)
×
UNCOV
430

×
UNCOV
431
        if err := lnwire.EncodeFailure(&b, failure, 0); err != nil {
×
432
                return nil, err
×
433
        }
×
UNCOV
434
        return b.Bytes(), nil
×
435
}
436

UNCOV
437
func (o *mockObfuscator) IntermediateEncrypt(reason lnwire.OpaqueReason) lnwire.OpaqueReason {
×
UNCOV
438
        return reason
×
UNCOV
439
}
×
440

UNCOV
441
func (o *mockObfuscator) EncryptMalformedError(reason lnwire.OpaqueReason) lnwire.OpaqueReason {
×
UNCOV
442
        var b bytes.Buffer
×
UNCOV
443
        b.Write(fakeHmac)
×
UNCOV
444

×
UNCOV
445
        b.Write(reason)
×
UNCOV
446

×
UNCOV
447
        return b.Bytes()
×
UNCOV
448
}
×
449

450
// mockDeobfuscator mock implementation of the failure deobfuscator which
451
// only decodes the failure do not makes any onion obfuscation.
452
type mockDeobfuscator struct{}
453

UNCOV
454
func newMockDeobfuscator() ErrorDecrypter {
×
UNCOV
455
        return &mockDeobfuscator{}
×
UNCOV
456
}
×
457

458
func (o *mockDeobfuscator) DecryptError(reason lnwire.OpaqueReason) (
UNCOV
459
        *ForwardingError, error) {
×
UNCOV
460

×
UNCOV
461
        if !bytes.Equal(reason[:32], fakeHmac) {
×
462
                return nil, errors.New("fake decryption error")
×
463
        }
×
UNCOV
464
        reason = reason[32:]
×
UNCOV
465

×
UNCOV
466
        r := bytes.NewReader(reason)
×
UNCOV
467
        failure, err := lnwire.DecodeFailure(r, 0)
×
UNCOV
468
        if err != nil {
×
469
                return nil, err
×
470
        }
×
471

UNCOV
472
        return NewForwardingError(failure, 1), nil
×
473
}
474

475
var _ ErrorDecrypter = (*mockDeobfuscator)(nil)
476

477
// mockIteratorDecoder test version of hop iterator decoder which decodes the
478
// encoded array of hops.
479
type mockIteratorDecoder struct {
480
        mu sync.RWMutex
481

482
        responses map[[32]byte][]hop.DecodeHopIteratorResponse
483

484
        decodeFail bool
485
}
486

UNCOV
487
func newMockIteratorDecoder() *mockIteratorDecoder {
×
UNCOV
488
        return &mockIteratorDecoder{
×
UNCOV
489
                responses: make(map[[32]byte][]hop.DecodeHopIteratorResponse),
×
UNCOV
490
        }
×
UNCOV
491
}
×
492

493
func (p *mockIteratorDecoder) DecodeHopIterator(r io.Reader, rHash []byte,
UNCOV
494
        cltv uint32) (hop.Iterator, lnwire.FailCode) {
×
UNCOV
495

×
UNCOV
496
        var b [4]byte
×
UNCOV
497
        _, err := r.Read(b[:])
×
UNCOV
498
        if err != nil {
×
499
                return nil, lnwire.CodeTemporaryChannelFailure
×
500
        }
×
UNCOV
501
        hopLength := binary.BigEndian.Uint32(b[:])
×
UNCOV
502

×
UNCOV
503
        hops := make([]*hop.Payload, hopLength)
×
UNCOV
504
        for i := uint32(0); i < hopLength; i++ {
×
UNCOV
505
                var f hop.ForwardingInfo
×
UNCOV
506
                if err := decodeFwdInfo(r, &f); err != nil {
×
507
                        return nil, lnwire.CodeTemporaryChannelFailure
×
508
                }
×
509

UNCOV
510
                var nextHopBytes [8]byte
×
UNCOV
511
                binary.BigEndian.PutUint64(nextHopBytes[:], f.NextHop.ToUint64())
×
UNCOV
512

×
UNCOV
513
                hops[i] = hop.NewLegacyPayload(&sphinx.HopData{
×
UNCOV
514
                        Realm:         [1]byte{}, // hop.BitcoinNetwork
×
UNCOV
515
                        NextAddress:   nextHopBytes,
×
UNCOV
516
                        ForwardAmount: uint64(f.AmountToForward),
×
UNCOV
517
                        OutgoingCltv:  f.OutgoingCTLV,
×
UNCOV
518
                })
×
519
        }
520

UNCOV
521
        return newMockHopIterator(hops...), lnwire.CodeNone
×
522
}
523

524
func (p *mockIteratorDecoder) DecodeHopIterators(id []byte,
525
        reqs []hop.DecodeHopIteratorRequest) (
UNCOV
526
        []hop.DecodeHopIteratorResponse, error) {
×
UNCOV
527

×
UNCOV
528
        idHash := sha256.Sum256(id)
×
UNCOV
529

×
UNCOV
530
        p.mu.RLock()
×
UNCOV
531
        if resps, ok := p.responses[idHash]; ok {
×
532
                p.mu.RUnlock()
×
533
                return resps, nil
×
534
        }
×
UNCOV
535
        p.mu.RUnlock()
×
UNCOV
536

×
UNCOV
537
        batchSize := len(reqs)
×
UNCOV
538

×
UNCOV
539
        resps := make([]hop.DecodeHopIteratorResponse, 0, batchSize)
×
UNCOV
540
        for _, req := range reqs {
×
UNCOV
541
                iterator, failcode := p.DecodeHopIterator(
×
UNCOV
542
                        req.OnionReader, req.RHash, req.IncomingCltv,
×
UNCOV
543
                )
×
UNCOV
544

×
UNCOV
545
                if p.decodeFail {
×
UNCOV
546
                        failcode = lnwire.CodeTemporaryChannelFailure
×
UNCOV
547
                }
×
548

UNCOV
549
                resp := hop.DecodeHopIteratorResponse{
×
UNCOV
550
                        HopIterator: iterator,
×
UNCOV
551
                        FailCode:    failcode,
×
UNCOV
552
                }
×
UNCOV
553
                resps = append(resps, resp)
×
554
        }
555

UNCOV
556
        p.mu.Lock()
×
UNCOV
557
        p.responses[idHash] = resps
×
UNCOV
558
        p.mu.Unlock()
×
UNCOV
559

×
UNCOV
560
        return resps, nil
×
561
}
562

UNCOV
563
func decodeFwdInfo(r io.Reader, f *hop.ForwardingInfo) error {
×
UNCOV
564
        if err := binary.Read(r, binary.BigEndian, &f.NextHop); err != nil {
×
565
                return err
×
566
        }
×
567

UNCOV
568
        if err := binary.Read(r, binary.BigEndian, &f.AmountToForward); err != nil {
×
569
                return err
×
570
        }
×
571

UNCOV
572
        if err := binary.Read(r, binary.BigEndian, &f.OutgoingCTLV); err != nil {
×
573
                return err
×
574
        }
×
575

UNCOV
576
        return nil
×
577
}
578

579
// messageInterceptor is function that handles the incoming peer messages and
580
// may decide should the peer skip the message or not.
581
type messageInterceptor func(m lnwire.Message) (bool, error)
582

583
// Record is used to set the function which will be triggered when new
584
// lnwire message was received.
UNCOV
585
func (s *mockServer) intersect(f messageInterceptor) {
×
UNCOV
586
        s.interceptorFuncs = append(s.interceptorFuncs, f)
×
UNCOV
587
}
×
588

UNCOV
589
func (s *mockServer) SendMessage(sync bool, msgs ...lnwire.Message) error {
×
UNCOV
590

×
UNCOV
591
        for _, msg := range msgs {
×
UNCOV
592
                select {
×
UNCOV
593
                case s.messages <- msg:
×
UNCOV
594
                case <-s.quit:
×
UNCOV
595
                        return errors.New("server is stopped")
×
596
                }
597
        }
598

UNCOV
599
        return nil
×
600
}
601

602
func (s *mockServer) SendMessageLazy(sync bool, msgs ...lnwire.Message) error {
×
603
        panic("not implemented")
×
604
}
605

UNCOV
606
func (s *mockServer) readHandler(message lnwire.Message) error {
×
UNCOV
607
        var targetChan lnwire.ChannelID
×
UNCOV
608

×
UNCOV
609
        switch msg := message.(type) {
×
UNCOV
610
        case *lnwire.UpdateAddHTLC:
×
UNCOV
611
                targetChan = msg.ChanID
×
UNCOV
612
        case *lnwire.UpdateFulfillHTLC:
×
UNCOV
613
                targetChan = msg.ChanID
×
UNCOV
614
        case *lnwire.UpdateFailHTLC:
×
UNCOV
615
                targetChan = msg.ChanID
×
UNCOV
616
        case *lnwire.UpdateFailMalformedHTLC:
×
UNCOV
617
                targetChan = msg.ChanID
×
UNCOV
618
        case *lnwire.RevokeAndAck:
×
UNCOV
619
                targetChan = msg.ChanID
×
UNCOV
620
        case *lnwire.CommitSig:
×
UNCOV
621
                targetChan = msg.ChanID
×
UNCOV
622
        case *lnwire.ChannelReady:
×
UNCOV
623
                // Ignore
×
UNCOV
624
                return nil
×
UNCOV
625
        case *lnwire.ChannelReestablish:
×
UNCOV
626
                targetChan = msg.ChanID
×
UNCOV
627
        case *lnwire.UpdateFee:
×
UNCOV
628
                targetChan = msg.ChanID
×
UNCOV
629
        case *lnwire.Stfu:
×
UNCOV
630
                targetChan = msg.ChanID
×
631
        default:
×
632
                return fmt.Errorf("unknown message type: %T", msg)
×
633
        }
634

635
        // Dispatch the commitment update message to the proper channel link
636
        // dedicated to this channel. If the link is not found, we will discard
637
        // the message.
UNCOV
638
        link, err := s.htlcSwitch.GetLink(targetChan)
×
UNCOV
639
        if err != nil {
×
640
                return nil
×
641
        }
×
642

643
        // Create goroutine for this, in order to be able to properly stop
644
        // the server when handler stacked (server unavailable)
UNCOV
645
        link.HandleChannelUpdate(message)
×
UNCOV
646

×
UNCOV
647
        return nil
×
648
}
649

UNCOV
650
func (s *mockServer) PubKey() [33]byte {
×
UNCOV
651
        return s.id
×
UNCOV
652
}
×
653

654
func (s *mockServer) IdentityKey() *btcec.PublicKey {
×
655
        pubkey, _ := btcec.ParsePubKey(s.id[:])
×
656
        return pubkey
×
657
}
×
658

659
func (s *mockServer) Address() net.Addr {
×
660
        return nil
×
661
}
×
662

663
func (s *mockServer) AddNewChannel(channel *lnpeer.NewChannel,
664
        cancel <-chan struct{}) error {
×
665

×
666
        return nil
×
667
}
×
668

669
func (s *mockServer) AddPendingChannel(_ lnwire.ChannelID,
670
        cancel <-chan struct{}) error {
×
671

×
672
        return nil
×
673
}
×
674

675
func (s *mockServer) RemovePendingChannel(_ lnwire.ChannelID) error {
×
676
        return nil
×
677
}
×
678

679
func (s *mockServer) WipeChannel(*wire.OutPoint) {}
×
680

681
func (s *mockServer) LocalFeatures() *lnwire.FeatureVector {
×
682
        return nil
×
683
}
×
684

685
func (s *mockServer) RemoteFeatures() *lnwire.FeatureVector {
×
686
        return nil
×
687
}
×
688

UNCOV
689
func (s *mockServer) Disconnect(err error) {}
×
690

UNCOV
691
func (s *mockServer) Stop() error {
×
UNCOV
692
        if !atomic.CompareAndSwapInt32(&s.shutdown, 0, 1) {
×
UNCOV
693
                return nil
×
UNCOV
694
        }
×
695

UNCOV
696
        close(s.quit)
×
UNCOV
697
        s.wg.Wait()
×
UNCOV
698

×
UNCOV
699
        return nil
×
700
}
701

702
func (s *mockServer) String() string {
×
703
        return s.name
×
704
}
×
705

706
type mockChannelLink struct {
707
        htlcSwitch *Switch
708

709
        shortChanID lnwire.ShortChannelID
710

711
        // Only used for zero-conf channels.
712
        realScid lnwire.ShortChannelID
713

714
        aliases []lnwire.ShortChannelID
715

716
        chanID lnwire.ChannelID
717

718
        peer lnpeer.Peer
719

720
        mailBox MailBox
721

722
        packets chan *htlcPacket
723

724
        eligible bool
725

726
        unadvertised bool
727

728
        zeroConf bool
729

730
        optionFeature bool
731

732
        htlcID uint64
733

734
        checkHtlcTransitResult *LinkError
735

736
        checkHtlcForwardResult *LinkError
737

738
        failAliasUpdate func(sid lnwire.ShortChannelID,
739
                incoming bool) *lnwire.ChannelUpdate1
740

741
        confirmedZC bool
742
}
743

744
// completeCircuit is a helper method for adding the finalized payment circuit
745
// to the switch's circuit map. In testing, this should be executed after
746
// receiving an htlc from the downstream packets channel.
UNCOV
747
func (f *mockChannelLink) completeCircuit(pkt *htlcPacket) error {
×
UNCOV
748
        switch htlc := pkt.htlc.(type) {
×
UNCOV
749
        case *lnwire.UpdateAddHTLC:
×
UNCOV
750
                pkt.outgoingChanID = f.shortChanID
×
UNCOV
751
                pkt.outgoingHTLCID = f.htlcID
×
UNCOV
752
                htlc.ID = f.htlcID
×
UNCOV
753

×
UNCOV
754
                keystone := Keystone{pkt.inKey(), pkt.outKey()}
×
UNCOV
755
                err := f.htlcSwitch.circuits.OpenCircuits(keystone)
×
UNCOV
756
                if err != nil {
×
757
                        return err
×
758
                }
×
759

UNCOV
760
                f.htlcID++
×
761

UNCOV
762
        case *lnwire.UpdateFulfillHTLC, *lnwire.UpdateFailHTLC:
×
UNCOV
763
                if pkt.circuit != nil {
×
UNCOV
764
                        err := f.htlcSwitch.teardownCircuit(pkt)
×
UNCOV
765
                        if err != nil {
×
766
                                return err
×
767
                        }
×
768
                }
769
        }
770

UNCOV
771
        f.mailBox.AckPacket(pkt.inKey())
×
UNCOV
772

×
UNCOV
773
        return nil
×
774
}
775

UNCOV
776
func (f *mockChannelLink) deleteCircuit(pkt *htlcPacket) error {
×
UNCOV
777
        return f.htlcSwitch.circuits.DeleteCircuits(pkt.inKey())
×
UNCOV
778
}
×
779

780
func newMockChannelLink(htlcSwitch *Switch, chanID lnwire.ChannelID,
781
        shortChanID, realScid lnwire.ShortChannelID, peer lnpeer.Peer,
782
        eligible, unadvertised, zeroConf, optionFeature bool,
UNCOV
783
) *mockChannelLink {
×
UNCOV
784

×
UNCOV
785
        aliases := make([]lnwire.ShortChannelID, 0)
×
UNCOV
786
        var realConfirmed bool
×
UNCOV
787

×
UNCOV
788
        if zeroConf {
×
UNCOV
789
                aliases = append(aliases, shortChanID)
×
UNCOV
790
        }
×
791

UNCOV
792
        if realScid != hop.Source {
×
UNCOV
793
                realConfirmed = true
×
UNCOV
794
        }
×
795

UNCOV
796
        return &mockChannelLink{
×
UNCOV
797
                htlcSwitch:    htlcSwitch,
×
UNCOV
798
                chanID:        chanID,
×
UNCOV
799
                shortChanID:   shortChanID,
×
UNCOV
800
                realScid:      realScid,
×
UNCOV
801
                peer:          peer,
×
UNCOV
802
                eligible:      eligible,
×
UNCOV
803
                unadvertised:  unadvertised,
×
UNCOV
804
                zeroConf:      zeroConf,
×
UNCOV
805
                optionFeature: optionFeature,
×
UNCOV
806
                aliases:       aliases,
×
UNCOV
807
                confirmedZC:   realConfirmed,
×
UNCOV
808
        }
×
809
}
810

811
// addAlias is not part of any interface method.
UNCOV
812
func (f *mockChannelLink) addAlias(alias lnwire.ShortChannelID) {
×
UNCOV
813
        f.aliases = append(f.aliases, alias)
×
UNCOV
814
}
×
815

UNCOV
816
func (f *mockChannelLink) handleSwitchPacket(pkt *htlcPacket) error {
×
UNCOV
817
        f.mailBox.AddPacket(pkt)
×
UNCOV
818
        return nil
×
UNCOV
819
}
×
820

821
func (f *mockChannelLink) getDustSum(whoseCommit lntypes.ChannelParty,
UNCOV
822
        dryRunFee fn.Option[chainfee.SatPerKWeight]) lnwire.MilliSatoshi {
×
UNCOV
823

×
UNCOV
824
        return 0
×
UNCOV
825
}
×
826

UNCOV
827
func (f *mockChannelLink) getFeeRate() chainfee.SatPerKWeight {
×
UNCOV
828
        return 0
×
UNCOV
829
}
×
830

UNCOV
831
func (f *mockChannelLink) getDustClosure() dustClosure {
×
UNCOV
832
        dustLimit := btcutil.Amount(400)
×
UNCOV
833
        return dustHelper(
×
UNCOV
834
                channeldb.SingleFunderTweaklessBit, dustLimit, dustLimit,
×
UNCOV
835
        )
×
UNCOV
836
}
×
837

838
func (f *mockChannelLink) getCommitFee(remote bool) btcutil.Amount {
×
839
        return 0
×
840
}
×
841

842
func (f *mockChannelLink) HandleChannelUpdate(lnwire.Message) {
×
843
}
×
844

845
func (f *mockChannelLink) UpdateForwardingPolicy(_ models.ForwardingPolicy) {
×
846
}
×
847
func (f *mockChannelLink) CheckHtlcForward([32]byte, lnwire.MilliSatoshi,
848
        lnwire.MilliSatoshi, uint32, uint32, models.InboundFee, uint32,
UNCOV
849
        lnwire.ShortChannelID, lnwire.CustomRecords) *LinkError {
×
UNCOV
850

×
UNCOV
851
        return f.checkHtlcForwardResult
×
UNCOV
852
}
×
853

854
func (f *mockChannelLink) CheckHtlcTransit(payHash [32]byte,
855
        amt lnwire.MilliSatoshi, timeout uint32,
UNCOV
856
        heightNow uint32, _ lnwire.CustomRecords) *LinkError {
×
UNCOV
857

×
UNCOV
858
        return f.checkHtlcTransitResult
×
UNCOV
859
}
×
860

861
func (f *mockChannelLink) Stats() (
UNCOV
862
        uint64, lnwire.MilliSatoshi, lnwire.MilliSatoshi) {
×
UNCOV
863

×
UNCOV
864
        return 0, 0, 0
×
UNCOV
865
}
×
866

UNCOV
867
func (f *mockChannelLink) AttachMailBox(mailBox MailBox) {
×
UNCOV
868
        f.mailBox = mailBox
×
UNCOV
869
        f.packets = mailBox.PacketOutBox()
×
UNCOV
870
        mailBox.SetDustClosure(f.getDustClosure())
×
UNCOV
871
}
×
872

873
func (f *mockChannelLink) attachFailAliasUpdate(closure func(
UNCOV
874
        sid lnwire.ShortChannelID, incoming bool) *lnwire.ChannelUpdate1) {
×
UNCOV
875

×
UNCOV
876
        f.failAliasUpdate = closure
×
UNCOV
877
}
×
878

UNCOV
879
func (f *mockChannelLink) getAliases() []lnwire.ShortChannelID {
×
UNCOV
880
        return f.aliases
×
UNCOV
881
}
×
882

UNCOV
883
func (f *mockChannelLink) isZeroConf() bool {
×
UNCOV
884
        return f.zeroConf
×
UNCOV
885
}
×
886

UNCOV
887
func (f *mockChannelLink) negotiatedAliasFeature() bool {
×
UNCOV
888
        return f.optionFeature
×
UNCOV
889
}
×
890

UNCOV
891
func (f *mockChannelLink) confirmedScid() lnwire.ShortChannelID {
×
UNCOV
892
        return f.realScid
×
UNCOV
893
}
×
894

UNCOV
895
func (f *mockChannelLink) zeroConfConfirmed() bool {
×
UNCOV
896
        return f.confirmedZC
×
UNCOV
897
}
×
898

UNCOV
899
func (f *mockChannelLink) Start() error {
×
UNCOV
900
        f.mailBox.ResetMessages()
×
UNCOV
901
        f.mailBox.ResetPackets()
×
UNCOV
902
        return nil
×
UNCOV
903
}
×
904

UNCOV
905
func (f *mockChannelLink) ChanID() lnwire.ChannelID {
×
UNCOV
906
        return f.chanID
×
UNCOV
907
}
×
908

UNCOV
909
func (f *mockChannelLink) ShortChanID() lnwire.ShortChannelID {
×
UNCOV
910
        return f.shortChanID
×
UNCOV
911
}
×
912

913
func (f *mockChannelLink) Bandwidth() lnwire.MilliSatoshi {
×
914
        return 99999999
×
915
}
×
916

UNCOV
917
func (f *mockChannelLink) PeerPubKey() [33]byte {
×
UNCOV
918
        return f.peer.PubKey()
×
UNCOV
919
}
×
920

921
func (f *mockChannelLink) ChannelPoint() wire.OutPoint {
×
922
        return wire.OutPoint{}
×
923
}
×
924

UNCOV
925
func (f *mockChannelLink) Stop()                                        {}
×
UNCOV
926
func (f *mockChannelLink) EligibleToForward() bool                      { return f.eligible }
×
927
func (f *mockChannelLink) MayAddOutgoingHtlc(lnwire.MilliSatoshi) error { return nil }
×
928
func (f *mockChannelLink) setLiveShortChanID(sid lnwire.ShortChannelID) { f.shortChanID = sid }
×
UNCOV
929
func (f *mockChannelLink) IsUnadvertised() bool                         { return f.unadvertised }
×
UNCOV
930
func (f *mockChannelLink) UpdateShortChanID() (lnwire.ShortChannelID, error) {
×
UNCOV
931
        f.eligible = true
×
UNCOV
932
        return f.shortChanID, nil
×
UNCOV
933
}
×
934

935
func (f *mockChannelLink) EnableAdds(linkDirection LinkDirection) bool {
×
936
        // TODO(proofofkeags): Implement
×
937
        return true
×
938
}
×
939

940
func (f *mockChannelLink) DisableAdds(linkDirection LinkDirection) bool {
×
941
        // TODO(proofofkeags): Implement
×
942
        return true
×
943
}
×
944
func (f *mockChannelLink) IsFlushing(linkDirection LinkDirection) bool {
×
945
        // TODO(proofofkeags): Implement
×
946
        return false
×
947
}
×
948
func (f *mockChannelLink) OnFlushedOnce(func()) {
×
949
        // TODO(proofofkeags): Implement
×
950
}
×
951
func (f *mockChannelLink) OnCommitOnce(LinkDirection, func()) {
×
952
        // TODO(proofofkeags): Implement
×
953
}
×
954
func (f *mockChannelLink) InitStfu() <-chan fn.Result[lntypes.ChannelParty] {
×
955
        // TODO(proofofkeags): Implement
×
956
        c := make(chan fn.Result[lntypes.ChannelParty], 1)
×
957

×
958
        c <- fn.Errf[lntypes.ChannelParty]("InitStfu not implemented")
×
959

×
960
        return c
×
961
}
×
962

963
func (f *mockChannelLink) FundingCustomBlob() fn.Option[tlv.Blob] {
×
964
        return fn.None[tlv.Blob]()
×
965
}
×
966

967
func (f *mockChannelLink) CommitmentCustomBlob() fn.Option[tlv.Blob] {
×
968
        return fn.None[tlv.Blob]()
×
969
}
×
970

971
// AuxBandwidth returns the bandwidth that can be used for a channel,
972
// expressed in milli-satoshi. This might be different from the regular
973
// BTC bandwidth for custom channels. This will always return fn.None()
974
// for a regular (non-custom) channel.
975
func (f *mockChannelLink) AuxBandwidth(lnwire.MilliSatoshi,
976
        lnwire.ShortChannelID,
977
        fn.Option[tlv.Blob], AuxTrafficShaper) fn.Result[OptionalBandwidth] {
×
978

×
979
        return fn.Ok(OptionalBandwidth{})
×
980
}
×
981

982
var _ ChannelLink = (*mockChannelLink)(nil)
983

984
const testInvoiceCltvExpiry = 6
985

986
type mockInvoiceRegistry struct {
987
        settleChan chan lntypes.Hash
988

989
        registry *invoices.InvoiceRegistry
990
}
991

992
type mockChainNotifier struct {
993
        chainntnfs.ChainNotifier
994
}
995

996
// RegisterBlockEpochNtfn mocks a successful call to register block
997
// notifications.
998
func (m *mockChainNotifier) RegisterBlockEpochNtfn(*chainntnfs.BlockEpoch) (
UNCOV
999
        *chainntnfs.BlockEpochEvent, error) {
×
UNCOV
1000

×
UNCOV
1001
        return &chainntnfs.BlockEpochEvent{
×
UNCOV
1002
                Cancel: func() {},
×
1003
        }, nil
1004
}
1005

UNCOV
1006
func newMockRegistry(t testing.TB) *mockInvoiceRegistry {
×
UNCOV
1007
        cdb := channeldb.OpenForTesting(t, t.TempDir())
×
UNCOV
1008

×
UNCOV
1009
        modifierMock := &invoices.MockHtlcModifier{}
×
UNCOV
1010
        registry := invoices.NewRegistry(
×
UNCOV
1011
                cdb,
×
UNCOV
1012
                invoices.NewInvoiceExpiryWatcher(
×
UNCOV
1013
                        clock.NewDefaultClock(), 0, 0, nil,
×
UNCOV
1014
                        &mockChainNotifier{},
×
UNCOV
1015
                ),
×
UNCOV
1016
                &invoices.RegistryConfig{
×
UNCOV
1017
                        FinalCltvRejectDelta: 5,
×
UNCOV
1018
                        HtlcInterceptor:      modifierMock,
×
UNCOV
1019
                },
×
UNCOV
1020
        )
×
UNCOV
1021
        registry.Start()
×
UNCOV
1022

×
UNCOV
1023
        return &mockInvoiceRegistry{
×
UNCOV
1024
                registry: registry,
×
UNCOV
1025
        }
×
UNCOV
1026
}
×
1027

1028
func (i *mockInvoiceRegistry) LookupInvoice(ctx context.Context,
UNCOV
1029
        rHash lntypes.Hash) (invoices.Invoice, error) {
×
UNCOV
1030

×
UNCOV
1031
        return i.registry.LookupInvoice(ctx, rHash)
×
UNCOV
1032
}
×
1033

1034
func (i *mockInvoiceRegistry) SettleHodlInvoice(
UNCOV
1035
        ctx context.Context, preimage lntypes.Preimage) error {
×
UNCOV
1036

×
UNCOV
1037
        return i.registry.SettleHodlInvoice(ctx, preimage)
×
UNCOV
1038
}
×
1039

1040
func (i *mockInvoiceRegistry) NotifyExitHopHtlc(rhash lntypes.Hash,
1041
        amt lnwire.MilliSatoshi, expiry uint32, currentHeight int32,
1042
        circuitKey models.CircuitKey, hodlChan chan<- interface{},
1043
        wireCustomRecords lnwire.CustomRecords,
UNCOV
1044
        payload invoices.Payload) (invoices.HtlcResolution, error) {
×
UNCOV
1045

×
UNCOV
1046
        event, err := i.registry.NotifyExitHopHtlc(
×
UNCOV
1047
                rhash, amt, expiry, currentHeight, circuitKey,
×
UNCOV
1048
                hodlChan, wireCustomRecords, payload,
×
UNCOV
1049
        )
×
UNCOV
1050
        if err != nil {
×
1051
                return nil, err
×
1052
        }
×
UNCOV
1053
        if i.settleChan != nil {
×
UNCOV
1054
                i.settleChan <- rhash
×
UNCOV
1055
        }
×
1056

UNCOV
1057
        return event, nil
×
1058
}
1059

1060
func (i *mockInvoiceRegistry) CancelInvoice(ctx context.Context,
UNCOV
1061
        payHash lntypes.Hash) error {
×
UNCOV
1062

×
UNCOV
1063
        return i.registry.CancelInvoice(ctx, payHash)
×
UNCOV
1064
}
×
1065

1066
func (i *mockInvoiceRegistry) AddInvoice(ctx context.Context,
UNCOV
1067
        invoice invoices.Invoice, paymentHash lntypes.Hash) error {
×
UNCOV
1068

×
UNCOV
1069
        _, err := i.registry.AddInvoice(ctx, &invoice, paymentHash)
×
UNCOV
1070
        return err
×
UNCOV
1071
}
×
1072

1073
func (i *mockInvoiceRegistry) HodlUnsubscribeAll(
UNCOV
1074
        subscriber chan<- interface{}) {
×
UNCOV
1075

×
UNCOV
1076
        i.registry.HodlUnsubscribeAll(subscriber)
×
UNCOV
1077
}
×
1078

1079
var _ InvoiceDatabase = (*mockInvoiceRegistry)(nil)
1080

1081
type mockCircuitMap struct {
1082
        lookup chan *PaymentCircuit
1083
}
1084

1085
var _ CircuitMap = (*mockCircuitMap)(nil)
1086

1087
func (m *mockCircuitMap) OpenCircuits(...Keystone) error {
×
1088
        return nil
×
1089
}
×
1090

1091
func (m *mockCircuitMap) TrimOpenCircuits(chanID lnwire.ShortChannelID,
1092
        start uint64) error {
×
1093
        return nil
×
1094
}
×
1095

1096
func (m *mockCircuitMap) DeleteCircuits(inKeys ...CircuitKey) error {
×
1097
        return nil
×
1098
}
×
1099

1100
func (m *mockCircuitMap) CommitCircuits(
1101
        circuit ...*PaymentCircuit) (*CircuitFwdActions, error) {
×
1102

×
1103
        return nil, nil
×
1104
}
×
1105

1106
func (m *mockCircuitMap) CloseCircuit(outKey CircuitKey) (*PaymentCircuit,
1107
        error) {
×
1108
        return nil, nil
×
1109
}
×
1110

1111
func (m *mockCircuitMap) FailCircuit(inKey CircuitKey) (*PaymentCircuit,
1112
        error) {
×
1113
        return nil, nil
×
1114
}
×
1115

UNCOV
1116
func (m *mockCircuitMap) LookupCircuit(inKey CircuitKey) *PaymentCircuit {
×
UNCOV
1117
        return <-m.lookup
×
UNCOV
1118
}
×
1119

1120
func (m *mockCircuitMap) LookupOpenCircuit(outKey CircuitKey) *PaymentCircuit {
×
1121
        return nil
×
1122
}
×
1123

1124
func (m *mockCircuitMap) LookupByPaymentHash(hash [32]byte) []*PaymentCircuit {
×
1125
        return nil
×
1126
}
×
1127

1128
func (m *mockCircuitMap) NumPending() int {
×
1129
        return 0
×
1130
}
×
1131

1132
func (m *mockCircuitMap) NumOpen() int {
×
1133
        return 0
×
1134
}
×
1135

1136
type mockOnionErrorDecryptor struct {
1137
        sourceIdx int
1138
        message   []byte
1139
        err       error
1140
}
1141

1142
func (m *mockOnionErrorDecryptor) DecryptError(encryptedData []byte) (
UNCOV
1143
        *sphinx.DecryptedError, error) {
×
UNCOV
1144

×
UNCOV
1145
        return &sphinx.DecryptedError{
×
UNCOV
1146
                SenderIdx: m.sourceIdx,
×
UNCOV
1147
                Message:   m.message,
×
UNCOV
1148
        }, m.err
×
UNCOV
1149
}
×
1150

1151
var _ htlcNotifier = (*mockHTLCNotifier)(nil)
1152

1153
type mockHTLCNotifier struct {
1154
        htlcNotifier //nolint:unused
1155
}
1156

1157
func (h *mockHTLCNotifier) NotifyForwardingEvent(key HtlcKey, info HtlcInfo,
UNCOV
1158
        eventType HtlcEventType) {
×
UNCOV
1159

×
UNCOV
1160
}
×
1161

1162
func (h *mockHTLCNotifier) NotifyLinkFailEvent(key HtlcKey, info HtlcInfo,
1163
        eventType HtlcEventType, linkErr *LinkError,
UNCOV
1164
        incoming bool) {
×
UNCOV
1165

×
UNCOV
1166
}
×
1167

1168
func (h *mockHTLCNotifier) NotifyForwardingFailEvent(key HtlcKey,
UNCOV
1169
        eventType HtlcEventType) {
×
UNCOV
1170

×
UNCOV
1171
}
×
1172

1173
func (h *mockHTLCNotifier) NotifySettleEvent(key HtlcKey,
UNCOV
1174
        preimage lntypes.Preimage, eventType HtlcEventType) {
×
UNCOV
1175

×
UNCOV
1176
}
×
1177

1178
func (h *mockHTLCNotifier) NotifyFinalHtlcEvent(key models.CircuitKey,
UNCOV
1179
        info channeldb.FinalHtlcInfo) {
×
UNCOV
1180

×
UNCOV
1181
}
×
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