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

lightningnetwork / lnd / 13536249039

26 Feb 2025 03:42AM UTC coverage: 57.462% (-1.4%) from 58.835%
13536249039

Pull #8453

github

Roasbeef
peer: update chooseDeliveryScript to gen script if needed

In this commit, we update `chooseDeliveryScript` to generate a new
script if needed. This allows us to fold in a few other lines that
always followed this function into this expanded function.

The tests have been updated accordingly.
Pull Request #8453: [4/4] - multi: integrate new rbf coop close FSM into the existing peer flow

275 of 1318 new or added lines in 22 files covered. (20.86%)

19521 existing lines in 257 files now uncovered.

103858 of 180741 relevant lines covered (57.46%)

24750.23 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.
UNCOV
43
func ChannelGraphFromDatabase(db GraphSource) ChannelGraph {
×
UNCOV
44
        return &databaseChannelGraph{
×
UNCOV
45
                db: db,
×
UNCOV
46
        }
×
UNCOV
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