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

lightningnetwork / lnd / 15561477203

10 Jun 2025 01:54PM UTC coverage: 58.351% (-10.1%) from 68.487%
15561477203

Pull #9356

github

web-flow
Merge 6440b25db into c6d6d4c0b
Pull Request #9356: lnrpc: add incoming/outgoing channel ids filter to forwarding history request

33 of 36 new or added lines in 2 files covered. (91.67%)

28366 existing lines in 455 files now uncovered.

97715 of 167461 relevant lines covered (58.35%)

1.81 hits per line

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

28.21
/autopilot/top_centrality.go
1
package autopilot
2

3
import (
4
        "context"
5
        "runtime"
6

7
        "github.com/btcsuite/btcd/btcutil"
8
)
9

10
// TopCentrality is a simple greedy technique to create connections to nodes
11
// with the top betweenness centrality value. This algorithm is usually
12
// referred to as TopK in the literature. The idea is that by opening channels
13
// to nodes with top betweenness centrality we also increase our own betweenness
14
// centrality (given we already have at least one channel, or create at least
15
// two new channels).
16
// A different and much better approach is instead of selecting nodes with top
17
// centrality value, we extend the graph in a loop by inserting a new non
18
// existing edge and recalculate the betweenness centrality of each node. This
19
// technique is usually referred to as "greedy" algorithm and gives better
20
// results than TopK but is considerably slower too.
21
type TopCentrality struct {
22
        centralityMetric *BetweennessCentrality
23
}
24

25
// A compile time assertion to ensure TopCentrality meets the
26
// AttachmentHeuristic interface.
27
var _ AttachmentHeuristic = (*TopCentrality)(nil)
28

29
// NewTopCentrality constructs and returns a new TopCentrality heuristic.
30
func NewTopCentrality() *TopCentrality {
3✔
31
        metric, err := NewBetweennessCentralityMetric(
3✔
32
                runtime.NumCPU(),
3✔
33
        )
3✔
34
        if err != nil {
3✔
35
                panic(err)
×
36
        }
37

38
        return &TopCentrality{
3✔
39
                centralityMetric: metric,
3✔
40
        }
3✔
41
}
42

43
// Name returns the name of the heuristic.
44
func (g *TopCentrality) Name() string {
3✔
45
        return "top_centrality"
3✔
46
}
3✔
47

48
// NodeScores will return a [0,1] normalized map of scores for the given nodes
49
// except for the ones we already have channels with. The scores will simply
50
// be the betweenness centrality values of the nodes.
51
// As our current implementation of betweenness centrality is non-incremental,
52
// NodeScores will recalculate the centrality values on every call, which is
53
// slow for large graphs.
54
func (g *TopCentrality) NodeScores(ctx context.Context, graph ChannelGraph,
55
        chans []LocalChannel, chanSize btcutil.Amount,
UNCOV
56
        nodes map[NodeID]struct{}) (map[NodeID]*NodeScore, error) {
×
UNCOV
57

×
UNCOV
58
        // Calculate betweenness centrality for the whole graph.
×
UNCOV
59
        if err := g.centralityMetric.Refresh(ctx, graph); err != nil {
×
60
                return nil, err
×
61
        }
×
62

UNCOV
63
        normalize := true
×
UNCOV
64
        centrality := g.centralityMetric.GetMetric(normalize)
×
UNCOV
65

×
UNCOV
66
        // Create a map of the existing peers for faster filtering.
×
UNCOV
67
        existingPeers := make(map[NodeID]struct{})
×
UNCOV
68
        for _, c := range chans {
×
UNCOV
69
                existingPeers[c.Node] = struct{}{}
×
UNCOV
70
        }
×
71

UNCOV
72
        result := make(map[NodeID]*NodeScore, len(nodes))
×
UNCOV
73
        for nodeID := range nodes {
×
UNCOV
74
                // Skip nodes we already have channel with.
×
UNCOV
75
                if _, ok := existingPeers[nodeID]; ok {
×
UNCOV
76
                        continue
×
77
                }
78

79
                // Skip passed nodes not in the graph. This could happen if
80
                // the graph changed before computing the centrality values as
81
                // the nodes we iterate are prefiltered by the autopilot agent.
UNCOV
82
                score, ok := centrality[nodeID]
×
UNCOV
83
                if !ok {
×
84
                        continue
×
85
                }
86

UNCOV
87
                result[nodeID] = &NodeScore{
×
UNCOV
88
                        NodeID: nodeID,
×
UNCOV
89
                        Score:  score,
×
UNCOV
90
                }
×
91
        }
92

UNCOV
93
        return result, nil
×
94
}
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