• 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
/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