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

lightningnetwork / lnd / 11216766535

07 Oct 2024 01:37PM UTC coverage: 57.817% (-1.0%) from 58.817%
11216766535

Pull #9148

github

ProofOfKeags
lnwire: remove kickoff feerate from propose/commit
Pull Request #9148: DynComms [2/n]: lnwire: add authenticated wire messages for Dyn*

571 of 879 new or added lines in 16 files covered. (64.96%)

23253 existing lines in 251 files now uncovered.

99022 of 171268 relevant lines covered (57.82%)

38420.67 hits per line

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

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

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

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

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

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

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

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

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

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

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

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

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