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

lightningnetwork / lnd / 12205625987

06 Dec 2024 08:23PM UTC coverage: 49.763% (-0.04%) from 49.807%
12205625987

Pull #9316

github

ziggie1984
docs: add release-notes.
Pull Request #9316: routing: fix mc blinded path behaviour.

165 of 181 new or added lines in 5 files covered. (91.16%)

238 existing lines in 28 files now uncovered.

100104 of 201163 relevant lines covered (49.76%)

2.07 hits per line

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

73.02
/chainntnfs/best_block_view.go
1
package chainntnfs
2

3
import (
4
        "errors"
5
        "fmt"
6
        "sync"
7
        "sync/atomic"
8

9
        "github.com/btcsuite/btcd/wire"
10
)
11

12
// BestBlockView is an interface that allows the querying of the most
13
// up-to-date blockchain state with low overhead. Valid implementations of this
14
// interface must track the latest chain state.
15
type BestBlockView interface {
16
        // BestHeight gets the most recent block height known to the view.
17
        BestHeight() (uint32, error)
18

19
        // BestBlockHeader gets the most recent block header known to the view.
20
        BestBlockHeader() (*wire.BlockHeader, error)
21
}
22

23
// BestBlockTracker is a tiny subsystem that tracks the blockchain tip
24
// and saves the most recent tip information in memory for querying. It is a
25
// valid implementation of BestBlockView and additionally includes
26
// methods for starting and stopping the system.
27
type BestBlockTracker struct {
28
        notifier        ChainNotifier
29
        blockNtfnStream *BlockEpochEvent
30
        current         atomic.Pointer[BlockEpoch]
31
        mu              sync.Mutex
32
        quit            chan struct{}
33
        wg              sync.WaitGroup
34
}
35

36
// This is a compile time check to ensure that BestBlockTracker implements
37
// BestBlockView.
38
var _ BestBlockView = (*BestBlockTracker)(nil)
39

40
// NewBestBlockTracker creates a new BestBlockTracker that isn't running yet.
41
// It will not provide up to date information unless it has been started. The
42
// ChainNotifier parameter must also be started prior to starting the
43
// BestBlockTracker.
44
func NewBestBlockTracker(chainNotifier ChainNotifier) *BestBlockTracker {
4✔
45
        return &BestBlockTracker{
4✔
46
                notifier:        chainNotifier,
4✔
47
                blockNtfnStream: nil,
4✔
48
                quit:            make(chan struct{}),
4✔
49
        }
4✔
50
}
4✔
51

52
// BestHeight gets the most recent block height known to the
53
// BestBlockTracker.
54
func (t *BestBlockTracker) BestHeight() (uint32, error) {
4✔
55
        epoch := t.current.Load()
4✔
56
        if epoch == nil {
4✔
57
                return 0, errors.New("best block height not yet known")
×
58
        }
×
59

60
        return uint32(epoch.Height), nil
4✔
61
}
62

63
// BestBlockHeader gets the most recent block header known to the
64
// BestBlockTracker.
UNCOV
65
func (t *BestBlockTracker) BestBlockHeader() (*wire.BlockHeader, error) {
×
UNCOV
66
        epoch := t.current.Load()
×
UNCOV
67
        if epoch == nil {
×
68
                return nil, errors.New("best block header not yet known")
×
69
        }
×
70

UNCOV
71
        return epoch.BlockHeader, nil
×
72
}
73

74
// updateLoop is a helper that subscribes to the underlying BlockEpochEvent
75
// stream and updates the internal values to match the new BlockEpochs that
76
// are discovered.
77
//
78
// MUST be run as a goroutine.
79
func (t *BestBlockTracker) updateLoop() {
4✔
80
        defer t.wg.Done()
4✔
81
        for {
8✔
82
                select {
4✔
83
                case epoch, ok := <-t.blockNtfnStream.Epochs:
4✔
84
                        if !ok {
8✔
85
                                Log.Error("dead epoch stream in " +
4✔
86
                                        "BestBlockTracker")
4✔
87

4✔
88
                                return
4✔
89
                        }
4✔
90
                        t.current.Store(epoch)
4✔
91
                case <-t.quit:
×
92
                        t.current.Store(nil)
×
93
                        return
×
94
                }
95
        }
96
}
97

98
// Start starts the BestBlockTracker. It is an error to start it if it
99
// is already started.
100
func (t *BestBlockTracker) Start() error {
4✔
101
        t.mu.Lock()
4✔
102
        defer t.mu.Unlock()
4✔
103

4✔
104
        if t.blockNtfnStream != nil {
4✔
105
                return fmt.Errorf("BestBlockTracker is already started")
×
106
        }
×
107

108
        var err error
4✔
109
        t.blockNtfnStream, err = t.notifier.RegisterBlockEpochNtfn(nil)
4✔
110
        if err != nil {
4✔
111
                return err
×
112
        }
×
113

114
        t.wg.Add(1)
4✔
115
        go t.updateLoop()
4✔
116

4✔
117
        return nil
4✔
118
}
119

120
// Stop stops the BestBlockTracker. It is an error to stop it if it has
121
// not been started or if it has already been stopped.
122
func (t *BestBlockTracker) Stop() error {
4✔
123
        t.mu.Lock()
4✔
124
        defer t.mu.Unlock()
4✔
125

4✔
126
        if t.blockNtfnStream == nil {
4✔
127
                return fmt.Errorf("BestBlockTracker is not running")
×
128
        }
×
129
        close(t.quit)
4✔
130
        t.wg.Wait()
4✔
131
        t.blockNtfnStream.Cancel()
4✔
132
        t.blockNtfnStream = nil
4✔
133

4✔
134
        return nil
4✔
135
}
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