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

lightningnetwork / lnd / 12343072627

15 Dec 2024 11:09PM UTC coverage: 57.504% (-1.1%) from 58.636%
12343072627

Pull #9315

github

yyforyongyu
contractcourt: offer outgoing htlc one block earlier before its expiry

We need to offer the outgoing htlc one block earlier to make sure when
the expiry height hits, the sweeper will not miss sweeping it in the
same block. This also means the outgoing contest resolver now only does
one thing - watch for preimage spend till height expiry-1, which can
easily be moved into the timeout resolver instead in the future.
Pull Request #9315: Implement `blockbeat`

1445 of 2007 new or added lines in 26 files covered. (72.0%)

19246 existing lines in 249 files now uncovered.

102342 of 177975 relevant lines covered (57.5%)

24772.24 hits per line

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

0.0
/autopilot/combinedattach.go
1
package autopilot
2

3
import (
4
        "fmt"
5

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

9
// WeightedHeuristic is a tuple that associates a weight to an
10
// AttachmentHeuristic. This is used to determining a node's final score when
11
// querying several heuristics for scores.
12
type WeightedHeuristic struct {
13
        // Weight is this AttachmentHeuristic's relative weight factor. It
14
        // should be between 0.0 and 1.0.
15
        Weight float64
16

17
        AttachmentHeuristic
18
}
19

20
// WeightedCombAttachment is an implementation of the AttachmentHeuristic
21
// interface that combines the scores given by several sub-heuristics into one.
22
type WeightedCombAttachment struct {
23
        heuristics []*WeightedHeuristic
24
}
25

26
// NewWeightedCombAttachment creates a new instance of a WeightedCombAttachment.
27
func NewWeightedCombAttachment(h ...*WeightedHeuristic) (
UNCOV
28
        *WeightedCombAttachment, error) {
×
UNCOV
29

×
UNCOV
30
        // The sum of weights given to the sub-heuristics must sum to exactly
×
UNCOV
31
        // 1.0.
×
UNCOV
32
        var sum float64
×
UNCOV
33
        for _, w := range h {
×
UNCOV
34
                sum += w.Weight
×
UNCOV
35
        }
×
36

UNCOV
37
        if sum != 1.0 {
×
38
                return nil, fmt.Errorf("weights MUST sum to 1.0 (was %v)", sum)
×
39
        }
×
40

UNCOV
41
        return &WeightedCombAttachment{
×
UNCOV
42
                heuristics: h,
×
UNCOV
43
        }, nil
×
44
}
45

46
// A compile time assertion to ensure WeightedCombAttachment meets the
47
// AttachmentHeuristic and ScoreSettable interfaces.
48
var _ AttachmentHeuristic = (*WeightedCombAttachment)(nil)
49
var _ ScoreSettable = (*WeightedCombAttachment)(nil)
50

51
// Name returns the name of this heuristic.
52
//
53
// NOTE: This is a part of the AttachmentHeuristic interface.
54
func (c *WeightedCombAttachment) Name() string {
×
55
        return "weightedcomb"
×
56
}
×
57

58
// NodeScores is a method that given the current channel graph, current set of
59
// local channels and funds available, scores the given nodes according to the
60
// preference of opening a channel with them. The returned channel candidates
61
// maps the NodeID to an attachment directive containing a score and a channel
62
// size.
63
//
64
// The scores is determined by querying the set of sub-heuristics, then
65
// combining these scores into a final score according to the active
66
// configuration.
67
//
68
// The returned scores will be in the range [0, 1.0], where 0 indicates no
69
// improvement in connectivity if a channel is opened to this node, while 1.0
70
// is the maximum possible improvement in connectivity.
71
//
72
// NOTE: This is a part of the AttachmentHeuristic interface.
73
func (c *WeightedCombAttachment) NodeScores(g ChannelGraph, chans []LocalChannel,
74
        chanSize btcutil.Amount, nodes map[NodeID]struct{}) (
75
        map[NodeID]*NodeScore, error) {
×
76

×
77
        // We now query each heuristic to determine the score they give to the
×
78
        // nodes for the given channel size.
×
79
        var subScores []map[NodeID]*NodeScore
×
80
        for _, h := range c.heuristics {
×
81
                log.Tracef("Getting scores from sub heuristic %v", h.Name())
×
82

×
83
                s, err := h.NodeScores(
×
84
                        g, chans, chanSize, nodes,
×
85
                )
×
86
                if err != nil {
×
87
                        return nil, fmt.Errorf("unable to get sub score: %w",
×
88
                                err)
×
89
                }
×
90

91
                subScores = append(subScores, s)
×
92
        }
93

94
        // We combine the scores given by the sub-heuristics by using the
95
        // heuristics' given weight factor.
96
        scores := make(map[NodeID]*NodeScore)
×
97
        for nID := range nodes {
×
98
                score := &NodeScore{
×
99
                        NodeID: nID,
×
100
                }
×
101

×
102
                // Each sub-heuristic should have scored the node, if not it is
×
103
                // implicitly given a zero score by that heuristic.
×
104
                for i, h := range c.heuristics {
×
105
                        sub, ok := subScores[i][nID]
×
106
                        if !ok {
×
107
                                log.Tracef("No score given to node %x by sub "+
×
108
                                        "heuristic %v", nID[:], h.Name())
×
109
                                continue
×
110
                        }
111
                        // Use the heuristic's weight factor to determine of
112
                        // how much weight we should give to this particular
113
                        // score.
114
                        subScore := h.Weight * sub.Score
×
115
                        log.Tracef("Giving node %x a sub score of %v "+
×
116
                                "(%v * %v) from sub heuristic %v", nID[:],
×
117
                                subScore, h.Weight, sub.Score, h.Name())
×
118

×
119
                        score.Score += subScore
×
120
                }
121

122
                log.Tracef("Node %x got final combined score %v", nID[:],
×
123
                        score.Score)
×
124

×
125
                switch {
×
126
                // Instead of adding a node with score 0 to the returned set,
127
                // we just skip it.
128
                case score.Score == 0:
×
129
                        continue
×
130

131
                // Sanity check the new score.
132
                case score.Score < 0 || score.Score > 1.0:
×
133
                        return nil, fmt.Errorf("invalid node score from "+
×
134
                                "combination: %v", score.Score)
×
135
                }
136

137
                scores[nID] = score
×
138
        }
139

140
        return scores, nil
×
141
}
142

143
// SetNodeScores is used to set the internal map from NodeIDs to scores. The
144
// passed scores must be in the range [0, 1.0]. The fist parameter is the name
145
// of the targeted heuristic, to allow recursively target specific
146
// sub-heuristics. The returned boolean indicates whether the targeted
147
// heuristic was found.
148
//
149
// Since this heuristic doesn't keep any internal scores, it will recursively
150
// apply the scores to its sub-heuristics.
151
//
152
// NOTE: This is a part of the ScoreSettable interface.
153
func (c *WeightedCombAttachment) SetNodeScores(targetHeuristic string,
154
        newScores map[NodeID]float64) (bool, error) {
×
155

×
156
        found := false
×
157
        for _, h := range c.heuristics {
×
158
                // It must be ScoreSettable to be available for external
×
159
                // scores.
×
160
                s, ok := h.AttachmentHeuristic.(ScoreSettable)
×
161
                if !ok {
×
162
                        continue
×
163
                }
164

165
                // Heuristic supports scoring, attempt to set them.
166
                applied, err := s.SetNodeScores(targetHeuristic, newScores)
×
167
                if err != nil {
×
168
                        return false, err
×
169
                }
×
170
                found = found || applied
×
171
        }
172

173
        return found, nil
×
174
}
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