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

lightningnetwork / lnd / 11170835610

03 Oct 2024 10:41PM UTC coverage: 49.188% (-9.6%) from 58.738%
11170835610

push

github

web-flow
Merge pull request #9154 from ziggie1984/master

multi: bump btcd version.

3 of 6 new or added lines in 6 files covered. (50.0%)

26110 existing lines in 428 files now uncovered.

97359 of 197934 relevant lines covered (49.19%)

1.04 hits per line

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

79.37
/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 {
2✔
45
        return &BestBlockTracker{
2✔
46
                notifier:        chainNotifier,
2✔
47
                blockNtfnStream: nil,
2✔
48
                quit:            make(chan struct{}),
2✔
49
        }
2✔
50
}
2✔
51

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

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

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

71
        return epoch.BlockHeader, nil
2✔
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() {
2✔
80
        defer t.wg.Done()
2✔
81
        for {
4✔
82
                select {
2✔
83
                case epoch, ok := <-t.blockNtfnStream.Epochs:
2✔
84
                        if !ok {
4✔
85
                                Log.Error("dead epoch stream in " +
2✔
86
                                        "BestBlockTracker")
2✔
87

2✔
88
                                return
2✔
89
                        }
2✔
90
                        t.current.Store(epoch)
2✔
UNCOV
91
                case <-t.quit:
×
UNCOV
92
                        t.current.Store(nil)
×
UNCOV
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 {
2✔
101
        t.mu.Lock()
2✔
102
        defer t.mu.Unlock()
2✔
103

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

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

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

2✔
117
        return nil
2✔
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 {
2✔
123
        t.mu.Lock()
2✔
124
        defer t.mu.Unlock()
2✔
125

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

2✔
134
        return nil
2✔
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