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

lightningnetwork / lnd / 13440912774

20 Feb 2025 05:14PM UTC coverage: 57.697% (-1.1%) from 58.802%
13440912774

Pull #9535

github

guggero
GitHub: remove duplicate caching

Turns out that actions/setup-go starting with @v4 also adds caching.
With that, our cache size on disk has almost doubled, leading to the
GitHub runner running out of space in certain situation.
We fix that by disabling the automated caching since we already have our
own, custom-tailored version.
Pull Request #9535: GitHub: remove duplicate caching

103519 of 179417 relevant lines covered (57.7%)

24825.3 hits per line

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

53.04
/autopilot/graph.go
1
package autopilot
2

3
import (
4
        "encoding/hex"
5
        "net"
6
        "sort"
7

8
        "github.com/btcsuite/btcd/btcec/v2"
9
        "github.com/btcsuite/btcd/btcec/v2/ecdsa"
10
        "github.com/btcsuite/btcd/btcutil"
11
        graphdb "github.com/lightningnetwork/lnd/graph/db"
12
        "github.com/lightningnetwork/lnd/graph/db/models"
13
        "github.com/lightningnetwork/lnd/lnwire"
14
        "github.com/lightningnetwork/lnd/routing/route"
15
)
16

17
var (
18
        testRBytes, _ = hex.DecodeString("8ce2bc69281ce27da07e6683571319d18e949ddfa2965fb6caa1bf0314f882d7")
19
        testSBytes, _ = hex.DecodeString("299105481d63e0f4bc2a88121167221b6700d72a0ead154c03be696a292d24ae")
20
        testRScalar   = new(btcec.ModNScalar)
21
        testSScalar   = new(btcec.ModNScalar)
22
        _             = testRScalar.SetByteSlice(testRBytes)
23
        _             = testSScalar.SetByteSlice(testSBytes)
24
        testSig       = ecdsa.NewSignature(testRScalar, testSScalar)
25

26
        chanIDCounter uint64 // To be used atomically.
27
)
28

29
// databaseChannelGraph wraps a channeldb.ChannelGraph instance with the
30
// necessary API to properly implement the autopilot.ChannelGraph interface.
31
//
32
// TODO(roasbeef): move inmpl to main package?
33
type databaseChannelGraph struct {
34
        db GraphSource
35
}
36

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

41
// ChannelGraphFromDatabase returns an instance of the autopilot.ChannelGraph
42
// backed by a GraphSource.
43
func ChannelGraphFromDatabase(db GraphSource) ChannelGraph {
×
44
        return &databaseChannelGraph{
×
45
                db: db,
×
46
        }
×
47
}
×
48

49
// type dbNode is a wrapper struct around a database transaction an
50
// channeldb.LightningNode. The wrapper method implement the autopilot.Node
51
// interface.
52
type dbNode struct {
53
        tx graphdb.NodeRTx
54
}
55

56
// A compile time assertion to ensure dbNode meets the autopilot.Node
57
// interface.
58
var _ Node = (*dbNode)(nil)
59

60
// PubKey is the identity public key of the node. This will be used to attempt
61
// to target a node for channel opening by the main autopilot agent. The key
62
// will be returned in serialized compressed format.
63
//
64
// NOTE: Part of the autopilot.Node interface.
65
func (d *dbNode) PubKey() [33]byte {
3,874✔
66
        return d.tx.Node().PubKeyBytes
3,874✔
67
}
3,874✔
68

69
// Addrs returns a slice of publicly reachable public TCP addresses that the
70
// peer is known to be listening on.
71
//
72
// NOTE: Part of the autopilot.Node interface.
73
func (d *dbNode) Addrs() []net.Addr {
×
74
        return d.tx.Node().Addresses
×
75
}
×
76

77
// ForEachChannel is a higher-order function that will be used to iterate
78
// through all edges emanating from/to the target node. For each active
79
// channel, this function should be called with the populated ChannelEdge that
80
// describes the active channel.
81
//
82
// NOTE: Part of the autopilot.Node interface.
83
func (d *dbNode) ForEachChannel(cb func(ChannelEdge) error) error {
965✔
84
        return d.tx.ForEachChannel(func(ei *models.ChannelEdgeInfo, ep,
965✔
85
                _ *models.ChannelEdgePolicy) error {
3,909✔
86

2,944✔
87
                // Skip channels for which no outgoing edge policy is available.
2,944✔
88
                //
2,944✔
89
                // TODO(joostjager): Ideally the case where channels have a nil
2,944✔
90
                // policy should be supported, as autopilot is not looking at
2,944✔
91
                // the policies. For now, it is not easily possible to get a
2,944✔
92
                // reference to the other end LightningNode object without
2,944✔
93
                // retrieving the policy.
2,944✔
94
                if ep == nil {
2,944✔
95
                        return nil
×
96
                }
×
97

98
                node, err := d.tx.FetchNode(ep.ToNode)
2,944✔
99
                if err != nil {
2,944✔
100
                        return err
×
101
                }
×
102

103
                edge := ChannelEdge{
2,944✔
104
                        ChanID:   lnwire.NewShortChanIDFromInt(ep.ChannelID),
2,944✔
105
                        Capacity: ei.Capacity,
2,944✔
106
                        Peer: &dbNode{
2,944✔
107
                                tx: node,
2,944✔
108
                        },
2,944✔
109
                }
2,944✔
110

2,944✔
111
                return cb(edge)
2,944✔
112
        })
113
}
114

115
// ForEachNode is a higher-order function that should be called once for each
116
// connected node within the channel graph. If the passed callback returns an
117
// error, then execution should be terminated.
118
//
119
// NOTE: Part of the autopilot.ChannelGraph interface.
120
func (d *databaseChannelGraph) ForEachNode(cb func(Node) error) error {
120✔
121
        return d.db.ForEachNode(func(nodeTx graphdb.NodeRTx) error {
1,090✔
122
                // We'll skip over any node that doesn't have any advertised
970✔
123
                // addresses. As we won't be able to reach them to actually
970✔
124
                // open any channels.
970✔
125
                if len(nodeTx.Node().Addresses) == 0 {
970✔
126
                        return nil
×
127
                }
×
128

129
                node := &dbNode{
970✔
130
                        tx: nodeTx,
970✔
131
                }
970✔
132
                return cb(node)
970✔
133
        })
134
}
135

136
// databaseChannelGraphCached wraps a channeldb.ChannelGraph instance with the
137
// necessary API to properly implement the autopilot.ChannelGraph interface.
138
type databaseChannelGraphCached struct {
139
        db GraphSource
140
}
141

142
// A compile time assertion to ensure databaseChannelGraphCached meets the
143
// autopilot.ChannelGraph interface.
144
var _ ChannelGraph = (*databaseChannelGraphCached)(nil)
145

146
// ChannelGraphFromCachedDatabase returns an instance of the
147
// autopilot.ChannelGraph backed by a live, open channeldb instance.
148
func ChannelGraphFromCachedDatabase(db GraphSource) ChannelGraph {
×
149
        return &databaseChannelGraphCached{
×
150
                db: db,
×
151
        }
×
152
}
×
153

154
// dbNodeCached is a wrapper struct around a database transaction for a
155
// channeldb.LightningNode. The wrapper methods implement the autopilot.Node
156
// interface.
157
type dbNodeCached struct {
158
        node     route.Vertex
159
        channels map[uint64]*graphdb.DirectedChannel
160
}
161

162
// A compile time assertion to ensure dbNodeCached meets the autopilot.Node
163
// interface.
164
var _ Node = (*dbNodeCached)(nil)
165

166
// PubKey is the identity public key of the node.
167
//
168
// NOTE: Part of the autopilot.Node interface.
169
func (nc dbNodeCached) PubKey() [33]byte {
×
170
        return nc.node
×
171
}
×
172

173
// Addrs returns a slice of publicly reachable public TCP addresses that the
174
// peer is known to be listening on.
175
//
176
// NOTE: Part of the autopilot.Node interface.
177
func (nc dbNodeCached) Addrs() []net.Addr {
×
178
        // TODO: Add addresses to be usable by autopilot.
×
179
        return []net.Addr{}
×
180
}
×
181

182
// ForEachChannel is a higher-order function that will be used to iterate
183
// through all edges emanating from/to the target node. For each active
184
// channel, this function should be called with the populated ChannelEdge that
185
// describes the active channel.
186
//
187
// NOTE: Part of the autopilot.Node interface.
188
func (nc dbNodeCached) ForEachChannel(cb func(ChannelEdge) error) error {
×
189
        for cid, channel := range nc.channels {
×
190
                edge := ChannelEdge{
×
191
                        ChanID:   lnwire.NewShortChanIDFromInt(cid),
×
192
                        Capacity: channel.Capacity,
×
193
                        Peer: dbNodeCached{
×
194
                                node: channel.OtherNode,
×
195
                        },
×
196
                }
×
197

×
198
                if err := cb(edge); err != nil {
×
199
                        return err
×
200
                }
×
201
        }
202

203
        return nil
×
204
}
205

206
// ForEachNode is a higher-order function that should be called once for each
207
// connected node within the channel graph. If the passed callback returns an
208
// error, then execution should be terminated.
209
//
210
// NOTE: Part of the autopilot.ChannelGraph interface.
211
func (dc *databaseChannelGraphCached) ForEachNode(cb func(Node) error) error {
×
212
        return dc.db.ForEachNodeCached(func(n route.Vertex,
×
213
                channels map[uint64]*graphdb.DirectedChannel) error {
×
214

×
215
                if len(channels) > 0 {
×
216
                        node := dbNodeCached{
×
217
                                node:     n,
×
218
                                channels: channels,
×
219
                        }
×
220
                        return cb(node)
×
221
                }
×
222
                return nil
×
223
        })
224
}
225

226
// memNode is a purely in-memory implementation of the autopilot.Node
227
// interface.
228
type memNode struct {
229
        pub *btcec.PublicKey
230

231
        chans []ChannelEdge
232

233
        addrs []net.Addr
234
}
235

236
// A compile time assertion to ensure memNode meets the autopilot.Node
237
// interface.
238
var _ Node = (*memNode)(nil)
239

240
// PubKey is the identity public key of the node. This will be used to attempt
241
// to target a node for channel opening by the main autopilot agent.
242
//
243
// NOTE: Part of the autopilot.Node interface.
244
func (m memNode) PubKey() [33]byte {
3,956✔
245
        var n [33]byte
3,956✔
246
        copy(n[:], m.pub.SerializeCompressed())
3,956✔
247

3,956✔
248
        return n
3,956✔
249
}
3,956✔
250

251
// Addrs returns a slice of publicly reachable public TCP addresses that the
252
// peer is known to be listening on.
253
//
254
// NOTE: Part of the autopilot.Node interface.
255
func (m memNode) Addrs() []net.Addr {
82✔
256
        return m.addrs
82✔
257
}
82✔
258

259
// ForEachChannel is a higher-order function that will be used to iterate
260
// through all edges emanating from/to the target node. For each active
261
// channel, this function should be called with the populated ChannelEdge that
262
// describes the active channel.
263
//
264
// NOTE: Part of the autopilot.Node interface.
265
func (m memNode) ForEachChannel(cb func(ChannelEdge) error) error {
965✔
266
        for _, channel := range m.chans {
3,909✔
267
                if err := cb(channel); err != nil {
2,944✔
268
                        return err
×
269
                }
×
270
        }
271

272
        return nil
965✔
273
}
274

275
// Median returns the median value in the slice of Amounts.
276
func Median(vals []btcutil.Amount) btcutil.Amount {
18✔
277
        sort.Slice(vals, func(i, j int) bool {
39✔
278
                return vals[i] < vals[j]
21✔
279
        })
21✔
280

281
        num := len(vals)
18✔
282
        switch {
18✔
283
        case num == 0:
3✔
284
                return 0
3✔
285

286
        case num%2 == 0:
8✔
287
                return (vals[num/2-1] + vals[num/2]) / 2
8✔
288

289
        default:
7✔
290
                return vals[num/2]
7✔
291
        }
292
}
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