• 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

0.0
/pilot.go
1
package lnd
2

3
import (
4
        "errors"
5
        "fmt"
6
        "net"
7

8
        "github.com/btcsuite/btcd/btcec/v2"
9
        "github.com/btcsuite/btcd/btcutil"
10
        "github.com/btcsuite/btcd/wire"
11
        "github.com/lightningnetwork/lnd/autopilot"
12
        "github.com/lightningnetwork/lnd/chainreg"
13
        "github.com/lightningnetwork/lnd/funding"
14
        "github.com/lightningnetwork/lnd/lncfg"
15
        "github.com/lightningnetwork/lnd/lnwallet"
16
        "github.com/lightningnetwork/lnd/lnwire"
17
        "github.com/lightningnetwork/lnd/tor"
18
)
19

20
// validateAtplCfg is a helper method that makes sure the passed
21
// configuration is sane. Currently it checks that the heuristic configuration
22
// makes sense. In case the config is valid, it will return a list of
23
// WeightedHeuristics that can be combined for use with the autopilot agent.
24
func validateAtplCfg(cfg *lncfg.AutoPilot) ([]*autopilot.WeightedHeuristic,
25
        error) {
×
26

×
27
        var (
×
28
                heuristicsStr string
×
29
                sum           float64
×
30
                heuristics    []*autopilot.WeightedHeuristic
×
31
        )
×
32

×
33
        // Create a help text that we can return in case the config is not
×
34
        // correct.
×
35
        for _, a := range autopilot.AvailableHeuristics {
×
36
                heuristicsStr += fmt.Sprintf(" '%v' ", a.Name())
×
37
        }
×
38
        availStr := fmt.Sprintf("Available heuristics are: [%v]", heuristicsStr)
×
39

×
40
        // We'll go through the config and make sure all the heuristics exists,
×
41
        // and that the sum of their weights is 1.0.
×
42
        for name, weight := range cfg.Heuristic {
×
43
                a, ok := autopilot.AvailableHeuristics[name]
×
44
                if !ok {
×
45
                        // No heuristic matching this config option was found.
×
46
                        return nil, fmt.Errorf("heuristic %v not available. %v",
×
47
                                name, availStr)
×
48
                }
×
49

50
                // If this heuristic was among the registered ones, we add it
51
                // to the list we'll give to the agent, and keep track of the
52
                // sum of weights.
53
                heuristics = append(
×
54
                        heuristics,
×
55
                        &autopilot.WeightedHeuristic{
×
56
                                Weight:              weight,
×
57
                                AttachmentHeuristic: a,
×
58
                        },
×
59
                )
×
60
                sum += weight
×
61
        }
62

63
        // Check found heuristics. We must have at least one to operate.
64
        if len(heuristics) == 0 {
×
65
                return nil, fmt.Errorf("no active heuristics: %v", availStr)
×
66
        }
×
67

68
        if sum != 1.0 {
×
69
                return nil, fmt.Errorf("heuristic weights must sum to 1.0")
×
70
        }
×
71
        return heuristics, nil
×
72
}
73

74
// chanController is an implementation of the autopilot.ChannelController
75
// interface that's backed by a running lnd instance.
76
type chanController struct {
77
        server        *server
78
        private       bool
79
        minConfs      int32
80
        confTarget    uint32
81
        chanMinHtlcIn lnwire.MilliSatoshi
82
        netParams     chainreg.BitcoinNetParams
83
}
84

85
// OpenChannel opens a channel to a target peer, with a capacity of the
86
// specified amount. This function should un-block immediately after the
87
// funding transaction that marks the channel open has been broadcast.
88
func (c *chanController) OpenChannel(target *btcec.PublicKey,
89
        amt btcutil.Amount) error {
×
90

×
91
        // With the connection established, we'll now establish our connection
×
92
        // to the target peer, waiting for the first update before we exit.
×
93
        feePerKw, err := c.server.cc.FeeEstimator.EstimateFeePerKW(
×
94
                c.confTarget,
×
95
        )
×
96
        if err != nil {
×
97
                return err
×
98
        }
×
99

100
        // Construct the open channel request and send it to the server to begin
101
        // the funding workflow.
102
        req := &funding.InitFundingMsg{
×
103
                TargetPubkey:     target,
×
104
                ChainHash:        *c.netParams.GenesisHash,
×
105
                SubtractFees:     true,
×
106
                LocalFundingAmt:  amt,
×
107
                PushAmt:          0,
×
108
                MinHtlcIn:        c.chanMinHtlcIn,
×
109
                FundingFeePerKw:  feePerKw,
×
110
                Private:          c.private,
×
111
                RemoteCsvDelay:   0,
×
112
                MinConfs:         c.minConfs,
×
113
                MaxValueInFlight: 0,
×
114
        }
×
115

×
116
        updateStream, errChan := c.server.OpenChannel(req)
×
117
        select {
×
118
        case err := <-errChan:
×
119
                return err
×
120
        case <-updateStream:
×
121
                return nil
×
122
        case <-c.server.quit:
×
123
                return nil
×
124
        }
125
}
126

127
func (c *chanController) CloseChannel(chanPoint *wire.OutPoint) error {
×
128
        return nil
×
129
}
×
130

131
// A compile time assertion to ensure chanController meets the
132
// autopilot.ChannelController interface.
133
var _ autopilot.ChannelController = (*chanController)(nil)
134

135
// initAutoPilot initializes a new autopilot.ManagerCfg to manage an autopilot.
136
// Agent instance based on the passed configuration structs. The agent and all
137
// interfaces needed to drive it won't be launched before the Manager's
138
// StartAgent method is called.
139
func initAutoPilot(svr *server, cfg *lncfg.AutoPilot,
140
        minHTLCIn lnwire.MilliSatoshi, netParams chainreg.BitcoinNetParams) (
141
        *autopilot.ManagerCfg, error) {
×
142

×
143
        atplLog.Infof("Instantiating autopilot with active=%v, "+
×
144
                "max_channels=%d, allocation=%f, min_chan_size=%d, "+
×
145
                "max_chan_size=%d, private=%t, min_confs=%d, conf_target=%d",
×
146
                cfg.Active, cfg.MaxChannels, cfg.Allocation, cfg.MinChannelSize,
×
147
                cfg.MaxChannelSize, cfg.Private, cfg.MinConfs, cfg.ConfTarget)
×
148

×
149
        // Set up the constraints the autopilot heuristics must adhere to.
×
150
        atplConstraints := autopilot.NewConstraints(
×
151
                btcutil.Amount(cfg.MinChannelSize),
×
152
                btcutil.Amount(cfg.MaxChannelSize),
×
153
                uint16(cfg.MaxChannels),
×
154
                10,
×
155
                cfg.Allocation,
×
156
        )
×
157
        heuristics, err := validateAtplCfg(cfg)
×
158
        if err != nil {
×
159
                return nil, err
×
160
        }
×
161

162
        weightedAttachment, err := autopilot.NewWeightedCombAttachment(
×
163
                heuristics...,
×
164
        )
×
165
        if err != nil {
×
166
                return nil, err
×
167
        }
×
168

169
        // With the heuristic itself created, we can now populate the remainder
170
        // of the items that the autopilot agent needs to perform its duties.
171
        self := svr.identityECDH.PubKey()
×
172
        pilotCfg := autopilot.Config{
×
173
                Self:      self,
×
174
                Heuristic: weightedAttachment,
×
175
                ChanController: &chanController{
×
176
                        server:        svr,
×
177
                        private:       cfg.Private,
×
178
                        minConfs:      cfg.MinConfs,
×
179
                        confTarget:    cfg.ConfTarget,
×
180
                        chanMinHtlcIn: minHTLCIn,
×
181
                        netParams:     netParams,
×
182
                },
×
183
                WalletBalance: func() (btcutil.Amount, error) {
×
184
                        return svr.cc.Wallet.ConfirmedBalance(
×
185
                                cfg.MinConfs, lnwallet.DefaultAccountName,
×
186
                        )
×
187
                },
×
188
                Graph:       autopilot.ChannelGraphFromDatabase(svr.graphDB),
189
                Constraints: atplConstraints,
190
                ConnectToPeer: func(target *btcec.PublicKey, addrs []net.Addr) (bool, error) {
×
191
                        // First, we'll check if we're already connected to the
×
192
                        // target peer. If we are, we can exit early. Otherwise,
×
193
                        // we'll need to establish a connection.
×
194
                        if _, err := svr.FindPeer(target); err == nil {
×
195
                                return true, nil
×
196
                        }
×
197

198
                        // We can't establish a channel if no addresses were
199
                        // provided for the peer.
200
                        if len(addrs) == 0 {
×
201
                                return false, errors.New("no addresses specified")
×
202
                        }
×
203

204
                        atplLog.Tracef("Attempting to connect to %x",
×
205
                                target.SerializeCompressed())
×
206

×
207
                        lnAddr := &lnwire.NetAddress{
×
208
                                IdentityKey: target,
×
209
                                ChainNet:    netParams.Net,
×
210
                        }
×
211

×
212
                        // We'll attempt to successively connect to each of the
×
213
                        // advertised IP addresses until we've either exhausted
×
214
                        // the advertised IP addresses, or have made a
×
215
                        // connection.
×
216
                        var connected bool
×
217
                        for _, addr := range addrs {
×
218
                                switch addr.(type) {
×
219
                                case *net.TCPAddr, *tor.OnionAddr:
×
220
                                        lnAddr.Address = addr
×
221
                                default:
×
222
                                        return false, fmt.Errorf("unknown "+
×
223
                                                "address type %T", addr)
×
224
                                }
225

226
                                err := svr.ConnectToPeer(
×
227
                                        lnAddr, false, svr.cfg.ConnectionTimeout,
×
228
                                )
×
229
                                if err != nil {
×
230
                                        // If we weren't able to connect to the
×
231
                                        // peer at this address, then we'll move
×
232
                                        // onto the next.
×
233
                                        continue
×
234
                                }
235

236
                                connected = true
×
237
                                break
×
238
                        }
239

240
                        // If we weren't able to establish a connection at all,
241
                        // then we'll error out.
242
                        if !connected {
×
243
                                return false, errors.New("exhausted all " +
×
244
                                        "advertised addresses")
×
245
                        }
×
246

247
                        return false, nil
×
248
                },
249
                DisconnectPeer: svr.DisconnectPeer,
250
        }
251

252
        // Create and return the autopilot.ManagerCfg that administrates this
253
        // agent-pilot instance.
254
        return &autopilot.ManagerCfg{
×
255
                Self:     self,
×
256
                PilotCfg: &pilotCfg,
×
257
                ChannelState: func() ([]autopilot.LocalChannel, error) {
×
258
                        // We'll fetch the current state of open
×
259
                        // channels from the database to use as initial
×
260
                        // state for the auto-pilot agent.
×
261
                        activeChannels, err := svr.chanStateDB.FetchAllChannels()
×
262
                        if err != nil {
×
263
                                return nil, err
×
264
                        }
×
265
                        chanState := make([]autopilot.LocalChannel,
×
266
                                len(activeChannels))
×
267
                        for i, channel := range activeChannels {
×
268
                                localCommit := channel.LocalCommitment
×
269
                                balance := localCommit.LocalBalance.ToSatoshis()
×
270

×
271
                                chanState[i] = autopilot.LocalChannel{
×
272
                                        ChanID:  channel.ShortChanID(),
×
273
                                        Balance: balance,
×
274
                                        Node: autopilot.NewNodeID(
×
275
                                                channel.IdentityPub,
×
276
                                        ),
×
277
                                }
×
278
                        }
×
279

280
                        return chanState, nil
×
281
                },
282
                ChannelInfo: func(chanPoint wire.OutPoint) (
283
                        *autopilot.LocalChannel, error) {
×
284

×
285
                        channel, err := svr.chanStateDB.FetchChannel(chanPoint)
×
286
                        if err != nil {
×
287
                                return nil, err
×
288
                        }
×
289

290
                        localCommit := channel.LocalCommitment
×
291
                        return &autopilot.LocalChannel{
×
292
                                ChanID:  channel.ShortChanID(),
×
293
                                Balance: localCommit.LocalBalance.ToSatoshis(),
×
294
                                Node:    autopilot.NewNodeID(channel.IdentityPub),
×
295
                        }, nil
×
296
                },
297
                SubscribeTransactions: svr.cc.Wallet.SubscribeTransactions,
298
                SubscribeTopology:     svr.graphBuilder.SubscribeTopology,
299
        }, nil
300
}
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