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

lightningnetwork / lnd / 13566028875

27 Feb 2025 12:09PM UTC coverage: 49.396% (-9.4%) from 58.748%
13566028875

Pull #9555

github

ellemouton
graph/db: populate the graph cache in Start instead of during construction

In this commit, we move the graph cache population logic out of the
ChannelGraph constructor and into its Start method instead.
Pull Request #9555: graph: extract cache from CRUD [6]

34 of 54 new or added lines in 4 files covered. (62.96%)

27464 existing lines in 436 files now uncovered.

101095 of 204664 relevant lines covered (49.4%)

1.54 hits per line

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

0.0
/chainntnfs/neutrinonotify/neutrino_dev.go
1
//go:build dev
2
// +build dev
3

4
package neutrinonotify
5

6
import (
7
        "fmt"
8
        "time"
9

10
        "github.com/btcsuite/btcd/chaincfg/chainhash"
11
        "github.com/btcsuite/btcd/rpcclient"
12
        "github.com/lightninglabs/neutrino"
13
        "github.com/lightningnetwork/lnd/chainntnfs"
14
)
15

16
// UnsafeStart starts the notifier with a specified best height and optional
17
// best hash. Its bestHeight, txNotifier and neutrino node are initialized with
18
// bestHeight. The parameter generateBlocks is necessary for the bitcoind
19
// notifier to ensure we drain all notifications up to syncHeight, since if they
20
// are generated ahead of UnsafeStart the chainConn may start up with an
21
// outdated best block and miss sending ntfns. Used for testing.
22
func (n *NeutrinoNotifier) UnsafeStart(bestHeight int32,
23
        bestHash *chainhash.Hash, syncHeight int32,
UNCOV
24
        generateBlocks func() error) error {
×
UNCOV
25

×
UNCOV
26
        // We'll obtain the latest block height of the p2p node. We'll
×
UNCOV
27
        // start the auto-rescan from this point. Once a caller actually wishes
×
UNCOV
28
        // to register a chain view, the rescan state will be rewound
×
UNCOV
29
        // accordingly.
×
UNCOV
30
        startingPoint, err := n.p2pNode.BestBlock()
×
UNCOV
31
        if err != nil {
×
32
                return err
×
33
        }
×
34

35
        // Next, we'll create our set of rescan options. Currently it's
36
        // required that a user MUST set an addr/outpoint/txid when creating a
37
        // rescan. To get around this, we'll add a "zero" outpoint, that won't
38
        // actually be matched.
UNCOV
39
        var zeroInput neutrino.InputWithScript
×
UNCOV
40
        rescanOptions := []neutrino.RescanOption{
×
UNCOV
41
                neutrino.StartBlock(startingPoint),
×
UNCOV
42
                neutrino.QuitChan(n.quit),
×
UNCOV
43
                neutrino.NotificationHandlers(
×
UNCOV
44
                        rpcclient.NotificationHandlers{
×
UNCOV
45
                                OnFilteredBlockConnected:    n.onFilteredBlockConnected,
×
UNCOV
46
                                OnFilteredBlockDisconnected: n.onFilteredBlockDisconnected,
×
UNCOV
47
                        },
×
UNCOV
48
                ),
×
UNCOV
49
                neutrino.WatchInputs(zeroInput),
×
UNCOV
50
        }
×
UNCOV
51

×
UNCOV
52
        n.txNotifier = chainntnfs.NewTxNotifier(
×
UNCOV
53
                uint32(bestHeight), chainntnfs.ReorgSafetyLimit,
×
UNCOV
54
                n.confirmHintCache, n.spendHintCache,
×
UNCOV
55
        )
×
UNCOV
56

×
UNCOV
57
        // Finally, we'll create our rescan struct, start it, and launch all
×
UNCOV
58
        // the goroutines we need to operate this ChainNotifier instance.
×
UNCOV
59
        n.chainView = neutrino.NewRescan(
×
UNCOV
60
                &neutrino.RescanChainSource{
×
UNCOV
61
                        ChainService: n.p2pNode,
×
UNCOV
62
                },
×
UNCOV
63
                rescanOptions...,
×
UNCOV
64
        )
×
UNCOV
65
        n.rescanErr = n.chainView.Start()
×
UNCOV
66

×
UNCOV
67
        n.txUpdates.Start()
×
UNCOV
68

×
UNCOV
69
        if generateBlocks != nil {
×
UNCOV
70
                // Ensure no block notifications are pending when we start the
×
UNCOV
71
                // notification dispatcher goroutine.
×
UNCOV
72

×
UNCOV
73
                // First generate the blocks, then drain the notifications
×
UNCOV
74
                // for the generated blocks.
×
UNCOV
75
                if err := generateBlocks(); err != nil {
×
76
                        return err
×
77
                }
×
78

UNCOV
79
                timeout := time.After(60 * time.Second)
×
UNCOV
80
        loop:
×
UNCOV
81
                for {
×
UNCOV
82
                        select {
×
UNCOV
83
                        case ntfn := <-n.chainUpdates:
×
UNCOV
84
                                lastReceivedNtfn := ntfn
×
UNCOV
85
                                if lastReceivedNtfn.height >= uint32(syncHeight) {
×
UNCOV
86
                                        break loop
×
87
                                }
88
                        case <-timeout:
×
89
                                return fmt.Errorf("unable to catch up to height %d",
×
90
                                        syncHeight)
×
91
                        }
92
                }
93
        }
94

95
        // Run notificationDispatcher after setting the notifier's best height
96
        // to avoid a race condition.
UNCOV
97
        n.bestBlock.Hash = bestHash
×
UNCOV
98
        n.bestBlock.Height = bestHeight
×
UNCOV
99

×
UNCOV
100
        n.wg.Add(1)
×
UNCOV
101
        go n.notificationDispatcher()
×
UNCOV
102

×
UNCOV
103
        return nil
×
104
}
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