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

lightningnetwork / lnd / 19155841408

07 Nov 2025 02:03AM UTC coverage: 66.675% (-0.04%) from 66.712%
19155841408

Pull #10352

github

web-flow
Merge e4313eba8 into 096ab65b1
Pull Request #10352: [WIP] chainrpc: return Unavailable while notifier starts

137328 of 205965 relevant lines covered (66.68%)

21333.36 hits per line

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

93.33
/autopilot/choice.go
1
package autopilot
2

3
import (
4
        "errors"
5
        "fmt"
6
        "math/rand"
7
)
8

9
// ErrNoPositive is returned from weightedChoice when there are no positive
10
// weights left to choose from.
11
var ErrNoPositive = errors.New("no positive weights left")
12

13
// weightedChoice draws a random index from the slice of weights, with a
14
// probability proportional to the weight at the given index.
15
func weightedChoice(w []float64) (int, error) {
10,508,253✔
16
        // Calculate the sum of weights.
10,508,253✔
17
        var sum float64
10,508,253✔
18
        for _, v := range w {
761,824,776✔
19
                sum += v
751,316,523✔
20
        }
751,316,523✔
21

22
        if sum <= 0 {
10,508,305✔
23
                return 0, ErrNoPositive
52✔
24
        }
52✔
25

26
        // Pick a random number in the range [0.0, 1.0) and multiply it with
27
        // the sum of weights. Then we'll iterate the weights until the number
28
        // goes below 0. This means that each index is picked with a probability
29
        // equal to their normalized score.
30
        //
31
        // Example:
32
        // Items with scores [1, 5, 2, 2]
33
        // Normalized scores [0.1, 0.5, 0.2, 0.2]
34
        // Imagine they each occupy a "range" equal to their normalized score
35
        // in [0, 1.0]:
36
        // [|-0.1-||-----0.5-----||--0.2--||--0.2--|]
37
        // The following loop is now equivalent to "hitting" the intervals.
38
        r := rand.Float64() * sum
10,508,201✔
39
        for i := range w {
394,117,942✔
40
                r -= w[i]
383,609,741✔
41
                if r <= 0 {
394,117,942✔
42
                        return i, nil
10,508,201✔
43
                }
10,508,201✔
44
        }
45

46
        return 0, fmt.Errorf("unable to make choice")
×
47
}
48

49
// chooseN picks at random min[n, len(s)] nodes if from the NodeScore map, with
50
// a probability weighted by their score.
51
func chooseN(n uint32, s map[NodeID]*NodeScore) (
52
        map[NodeID]*NodeScore, error) {
137,215✔
53

137,215✔
54
        // Keep track of the number of nodes not yet chosen, in addition to
137,215✔
55
        // their scores and NodeIDs.
137,215✔
56
        rem := len(s)
137,215✔
57
        scores := make([]float64, len(s))
137,215✔
58
        nodeIDs := make([]NodeID, len(s))
137,215✔
59
        i := 0
137,215✔
60
        for k, v := range s {
68,649,627✔
61
                scores[i] = v.Score
68,512,412✔
62
                nodeIDs[i] = k
68,512,412✔
63
                i++
68,512,412✔
64
        }
68,512,412✔
65

66
        // Pick a weighted choice from the remaining nodes as long as there are
67
        // nodes left, and we haven't already picked n.
68
        chosen := make(map[NodeID]*NodeScore)
137,215✔
69
        for len(chosen) < int(n) && rem > 0 {
645,367✔
70
                choice, err := weightedChoice(scores)
508,152✔
71
                if err == ErrNoPositive {
508,203✔
72
                        return chosen, nil
51✔
73
                } else if err != nil {
508,152✔
74
                        return nil, err
×
75
                }
×
76

77
                nID := nodeIDs[choice]
508,101✔
78

508,101✔
79
                chosen[nID] = s[nID]
508,101✔
80

508,101✔
81
                // We set the score of the chosen node to 0, so it won't be
508,101✔
82
                // picked the next iteration.
508,101✔
83
                scores[choice] = 0
508,101✔
84
        }
85

86
        return chosen, nil
137,164✔
87
}
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