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

lightningnetwork / lnd / 13035292482

29 Jan 2025 03:59PM UTC coverage: 49.3% (-9.5%) from 58.777%
13035292482

Pull #9456

github

mohamedawnallah
docs: update release-notes-0.19.0.md

In this commit, we warn users about the removal
of RPCs `SendToRoute`, `SendToRouteSync`, `SendPayment`,
and `SendPaymentSync` in the next release 0.20.
Pull Request #9456: lnrpc+docs: deprecate warning `SendToRoute`, `SendToRouteSync`, `SendPayment`, and `SendPaymentSync` in Release 0.19

100634 of 204126 relevant lines covered (49.3%)

1.54 hits per line

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

6.6
/autopilot/prefattach.go
1
package autopilot
2

3
import (
4
        prand "math/rand"
5
        "time"
6

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

11
// minMedianChanSizeFraction determines the minimum size a channel must have to
12
// count positively when calculating the scores using preferential attachment.
13
// The minimum channel size is calculated as median/minMedianChanSizeFraction,
14
// where median is the median channel size of the entire graph.
15
const minMedianChanSizeFraction = 4
16

17
// PrefAttachment is an implementation of the AttachmentHeuristic interface
18
// that implement a non-linear preferential attachment heuristic. This means
19
// that given a threshold to allocate to automatic channel establishment, the
20
// heuristic will attempt to favor connecting to nodes which already have a set
21
// amount of links, selected by sampling from a power law distribution. The
22
// attachment is non-linear in that it favors nodes with a higher in-degree but
23
// less so than regular linear preferential attachment. As a result, this
24
// creates smaller and less clusters than regular linear preferential
25
// attachment.
26
//
27
// TODO(roasbeef): BA, with k=-3
28
type PrefAttachment struct {
29
}
30

31
// NewPrefAttachment creates a new instance of a PrefAttachment heuristic.
32
func NewPrefAttachment() *PrefAttachment {
3✔
33
        prand.Seed(time.Now().Unix())
3✔
34
        return &PrefAttachment{}
3✔
35
}
3✔
36

37
// A compile time assertion to ensure PrefAttachment meets the
38
// AttachmentHeuristic interface.
39
var _ AttachmentHeuristic = (*PrefAttachment)(nil)
40

41
// NodeID is a simple type that holds an EC public key serialized in compressed
42
// format.
43
type NodeID [33]byte
44

45
// NewNodeID creates a new nodeID from a passed public key.
46
func NewNodeID(pub *btcec.PublicKey) NodeID {
×
47
        var n NodeID
×
48
        copy(n[:], pub.SerializeCompressed())
×
49
        return n
×
50
}
×
51

52
// Name returns the name of this heuristic.
53
//
54
// NOTE: This is a part of the AttachmentHeuristic interface.
55
func (p *PrefAttachment) Name() string {
3✔
56
        return "preferential"
3✔
57
}
3✔
58

59
// NodeScores is a method that given the current channel graph and current set
60
// of local channels, scores the given nodes according to the preference of
61
// opening a channel of the given size with them. The returned channel
62
// candidates maps the NodeID to a NodeScore for the node.
63
//
64
// The heuristic employed by this method is one that attempts to promote a
65
// scale-free network globally, via local attachment preferences for new nodes
66
// joining the network with an amount of available funds to be allocated to
67
// channels. Specifically, we consider the degree of each node (and the flow
68
// in/out of the node available via its open channels) and utilize the
69
// Barabási–Albert model to drive our recommended attachment heuristics. If
70
// implemented globally for each new participant, this results in a channel
71
// graph that is scale-free and follows a power law distribution with k=-3.
72
//
73
// To avoid assigning a high score to nodes with a large number of small
74
// channels, we only count channels at least as large as a given fraction of
75
// the graph's median channel size.
76
//
77
// The returned scores will be in the range [0.0, 1.0], where higher scores are
78
// given to nodes already having high connectivity in the graph.
79
//
80
// NOTE: This is a part of the AttachmentHeuristic interface.
81
func (p *PrefAttachment) NodeScores(g ChannelGraph, chans []LocalChannel,
82
        chanSize btcutil.Amount, nodes map[NodeID]struct{}) (
83
        map[NodeID]*NodeScore, error) {
×
84

×
85
        // We first run though the graph once in order to find the median
×
86
        // channel size.
×
87
        var (
×
88
                allChans  []btcutil.Amount
×
89
                seenChans = make(map[uint64]struct{})
×
90
        )
×
91
        if err := g.ForEachNode(func(n Node) error {
×
92
                err := n.ForEachChannel(func(e ChannelEdge) error {
×
93
                        if _, ok := seenChans[e.ChanID.ToUint64()]; ok {
×
94
                                return nil
×
95
                        }
×
96
                        seenChans[e.ChanID.ToUint64()] = struct{}{}
×
97
                        allChans = append(allChans, e.Capacity)
×
98
                        return nil
×
99
                })
100
                if err != nil {
×
101
                        return err
×
102
                }
×
103

104
                return nil
×
105
        }); err != nil {
×
106
                return nil, err
×
107
        }
×
108

109
        medianChanSize := Median(allChans)
×
110
        log.Tracef("Found channel median %v for preferential score heuristic",
×
111
                medianChanSize)
×
112

×
113
        // Count the number of large-ish channels for each particular node in
×
114
        // the graph.
×
115
        var maxChans int
×
116
        nodeChanNum := make(map[NodeID]int)
×
117
        if err := g.ForEachNode(func(n Node) error {
×
118
                var nodeChans int
×
119
                err := n.ForEachChannel(func(e ChannelEdge) error {
×
120
                        // Since connecting to nodes with a lot of small
×
121
                        // channels actually worsens our connectivity in the
×
122
                        // graph (we will potentially waste time trying to use
×
123
                        // these useless channels in path finding), we decrease
×
124
                        // the counter for such channels.
×
125
                        if e.Capacity < medianChanSize/minMedianChanSizeFraction {
×
126
                                nodeChans--
×
127
                                return nil
×
128
                        }
×
129

130
                        // Larger channels we count.
131
                        nodeChans++
×
132
                        return nil
×
133
                })
134
                if err != nil {
×
135
                        return err
×
136
                }
×
137

138
                // We keep track of the highest-degree node we've seen, as this
139
                // will be given the max score.
140
                if nodeChans > maxChans {
×
141
                        maxChans = nodeChans
×
142
                }
×
143

144
                // If this node is not among our nodes to score, we can return
145
                // early.
146
                nID := NodeID(n.PubKey())
×
147
                if _, ok := nodes[nID]; !ok {
×
148
                        log.Tracef("Node %x not among nodes to score, "+
×
149
                                "ignoring", nID[:])
×
150
                        return nil
×
151
                }
×
152

153
                // Otherwise we'll record the number of channels.
154
                nodeChanNum[nID] = nodeChans
×
155
                log.Tracef("Counted %v channels for node %x", nodeChans, nID[:])
×
156

×
157
                return nil
×
158
        }); err != nil {
×
159
                return nil, err
×
160
        }
×
161

162
        // If there are no channels in the graph we cannot determine any
163
        // preferences, so we return, indicating all candidates get a score of
164
        // zero.
165
        if maxChans == 0 {
×
166
                log.Tracef("No channels in the graph")
×
167
                return nil, nil
×
168
        }
×
169

170
        existingPeers := make(map[NodeID]struct{})
×
171
        for _, c := range chans {
×
172
                existingPeers[c.Node] = struct{}{}
×
173
        }
×
174

175
        // For each node in the set of nodes, count their fraction of channels
176
        // in the graph, and use that as the score.
177
        candidates := make(map[NodeID]*NodeScore)
×
178
        for nID, nodeChans := range nodeChanNum {
×
179

×
180
                // If the node is among or existing channel peers, we don't
×
181
                // need another channel.
×
182
                if _, ok := existingPeers[nID]; ok {
×
183
                        log.Tracef("Node %x among existing peers for pref "+
×
184
                                "attach heuristic, giving zero score", nID[:])
×
185
                        continue
×
186
                }
187

188
                // If the node had no large channels, we skip it, since it
189
                // would have gotten a zero score anyway.
190
                if nodeChans <= 0 {
×
191
                        log.Tracef("Skipping node %x with channel count %v",
×
192
                                nID[:], nodeChans)
×
193
                        continue
×
194
                }
195

196
                // Otherwise we score the node according to its fraction of
197
                // channels in the graph, scaled such that the highest-degree
198
                // node will be given a score of 1.0.
199
                score := float64(nodeChans) / float64(maxChans)
×
200
                log.Tracef("Giving node %x a pref attach score of %v",
×
201
                        nID[:], score)
×
202

×
203
                candidates[nID] = &NodeScore{
×
204
                        NodeID: nID,
×
205
                        Score:  score,
×
206
                }
×
207
        }
208

209
        return candidates, nil
×
210
}
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