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

lightningnetwork / lnd / 16883452553

11 Aug 2025 02:44PM UTC coverage: 66.909% (+0.009%) from 66.9%
16883452553

Pull #9844

github

web-flow
Merge 4e0af2f49 into f3e1f2f35
Pull Request #9844: Refactor Payment PR 3

106 of 147 new or added lines in 11 files covered. (72.11%)

61 existing lines in 19 files now uncovered.

135735 of 202866 relevant lines covered (66.91%)

21586.57 hits per line

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

87.41
/routing/router.go
1
package routing
2

3
import (
4
        "context"
5
        "errors"
6
        "fmt"
7
        "math"
8
        "math/big"
9
        "sort"
10
        "sync"
11
        "sync/atomic"
12
        "time"
13

14
        "github.com/btcsuite/btcd/btcec/v2"
15
        "github.com/btcsuite/btcd/btcutil"
16
        "github.com/davecgh/go-spew/spew"
17
        "github.com/lightningnetwork/lnd/amp"
18
        "github.com/lightningnetwork/lnd/channeldb"
19
        "github.com/lightningnetwork/lnd/clock"
20
        "github.com/lightningnetwork/lnd/fn/v2"
21
        "github.com/lightningnetwork/lnd/graph/db/models"
22
        "github.com/lightningnetwork/lnd/htlcswitch"
23
        "github.com/lightningnetwork/lnd/lntypes"
24
        "github.com/lightningnetwork/lnd/lnutils"
25
        "github.com/lightningnetwork/lnd/lnwallet"
26
        "github.com/lightningnetwork/lnd/lnwire"
27
        paymentsdb "github.com/lightningnetwork/lnd/payments/db"
28
        "github.com/lightningnetwork/lnd/record"
29
        "github.com/lightningnetwork/lnd/routing/route"
30
        "github.com/lightningnetwork/lnd/routing/shards"
31
        "github.com/lightningnetwork/lnd/tlv"
32
        "github.com/lightningnetwork/lnd/zpay32"
33
)
34

35
const (
36
        // DefaultPayAttemptTimeout is the default payment attempt timeout. The
37
        // payment attempt timeout defines the duration after which we stop
38
        // trying more routes for a payment.
39
        DefaultPayAttemptTimeout = time.Second * 60
40

41
        // MinCLTVDelta is the minimum CLTV value accepted by LND for all
42
        // timelock deltas. This includes both forwarding CLTV deltas set on
43
        // channel updates, as well as final CLTV deltas used to create BOLT 11
44
        // payment requests.
45
        //
46
        // NOTE: For payment requests, BOLT 11 stipulates that a final CLTV
47
        // delta of 9 should be used when no value is decoded. This however
48
        // leads to inflexibility in upgrading this default parameter, since it
49
        // can create inconsistencies around the assumed value between sender
50
        // and receiver. Specifically, if the receiver assumes a higher value
51
        // than the sender, the receiver will always see the received HTLCs as
52
        // invalid due to their timelock not meeting the required delta.
53
        //
54
        // We skirt this by always setting an explicit CLTV delta when creating
55
        // invoices. This allows LND nodes to freely update the minimum without
56
        // creating incompatibilities during the upgrade process. For some time
57
        // LND has used an explicit default final CLTV delta of 40 blocks for
58
        // bitcoin, though we now clamp the lower end of this
59
        // range for user-chosen deltas to 18 blocks to be conservative.
60
        MinCLTVDelta = 18
61

62
        // MaxCLTVDelta is the maximum CLTV value accepted by LND for all
63
        // timelock deltas.
64
        MaxCLTVDelta = math.MaxUint16
65
)
66

67
var (
68
        // ErrRouterShuttingDown is returned if the router is in the process of
69
        // shutting down.
70
        ErrRouterShuttingDown = fmt.Errorf("router shutting down")
71

72
        // ErrSelfIntro is a failure returned when the source node of a
73
        // route request is also the introduction node. This is not yet
74
        // supported because LND does not support blinded forwardingg.
75
        ErrSelfIntro = errors.New("introduction point as own node not " +
76
                "supported")
77

78
        // ErrHintsAndBlinded is returned if a route request has both
79
        // bolt 11 route hints and a blinded path set.
80
        ErrHintsAndBlinded = errors.New("bolt 11 route hints and blinded " +
81
                "paths are mutually exclusive")
82

83
        // ErrExpiryAndBlinded is returned if a final cltv and a blinded path
84
        // are provided, as the cltv should be provided within the blinded
85
        // path.
86
        ErrExpiryAndBlinded = errors.New("final cltv delta and blinded " +
87
                "paths are mutually exclusive")
88

89
        // ErrTargetAndBlinded is returned is a target destination and a
90
        // blinded path are both set (as the target is inferred from the
91
        // blinded path).
92
        ErrTargetAndBlinded = errors.New("target node and blinded paths " +
93
                "are mutually exclusive")
94

95
        // ErrNoTarget is returned when the target node for a route is not
96
        // provided by either a blinded route or a cleartext pubkey.
97
        ErrNoTarget = errors.New("destination not set in target or blinded " +
98
                "path")
99

100
        // ErrSkipTempErr is returned when a non-MPP is made yet the
101
        // skipTempErr flag is set.
102
        ErrSkipTempErr = errors.New("cannot skip temp error for non-MPP")
103
)
104

105
// PaymentAttemptDispatcher is used by the router to send payment attempts onto
106
// the network, and receive their results.
107
type PaymentAttemptDispatcher interface {
108
        // SendHTLC is a function that directs a link-layer switch to
109
        // forward a fully encoded payment to the first hop in the route
110
        // denoted by its public key. A non-nil error is to be returned if the
111
        // payment was unsuccessful.
112
        SendHTLC(firstHop lnwire.ShortChannelID,
113
                attemptID uint64,
114
                htlcAdd *lnwire.UpdateAddHTLC) error
115

116
        // GetAttemptResult returns the result of the payment attempt with
117
        // the given attemptID. The paymentHash should be set to the payment's
118
        // overall hash, or in case of AMP payments the payment's unique
119
        // identifier.
120
        //
121
        // The method returns a channel where the payment result will be sent
122
        // when available, or an error is encountered during forwarding. When a
123
        // result is received on the channel, the HTLC is guaranteed to no
124
        // longer be in flight.  The switch shutting down is signaled by
125
        // closing the channel. If the attemptID is unknown,
126
        // ErrPaymentIDNotFound will be returned.
127
        GetAttemptResult(attemptID uint64, paymentHash lntypes.Hash,
128
                deobfuscator htlcswitch.ErrorDecrypter) (
129
                <-chan *htlcswitch.PaymentResult, error)
130

131
        // CleanStore calls the underlying result store, telling it is safe to
132
        // delete all entries except the ones in the keepPids map. This should
133
        // be called periodically to let the switch clean up payment results
134
        // that we have handled.
135
        // NOTE: New payment attempts MUST NOT be made after the keepPids map
136
        // has been created and this method has returned.
137
        CleanStore(keepPids map[uint64]struct{}) error
138

139
        // HasAttemptResult reads the network result store to fetch the
140
        // specified attempt. Returns true if the attempt result exists.
141
        //
142
        // NOTE: This method is used and should only be used by the router to
143
        // resume payments during startup. It can be viewed as a subset of
144
        // `GetAttemptResult` in terms of its functionality, and can be removed
145
        // once we move the construction of `UpdateAddHTLC` and
146
        // `ErrorDecrypter` into `htlcswitch`.
147
        HasAttemptResult(attemptID uint64) (bool, error)
148
}
149

150
// PaymentSessionSource is an interface that defines a source for the router to
151
// retrieve new payment sessions.
152
type PaymentSessionSource interface {
153
        // NewPaymentSession creates a new payment session that will produce
154
        // routes to the given target. An optional set of routing hints can be
155
        // provided in order to populate additional edges to explore when
156
        // finding a path to the payment's destination.
157
        NewPaymentSession(p *LightningPayment,
158
                firstHopBlob fn.Option[tlv.Blob],
159
                ts fn.Option[htlcswitch.AuxTrafficShaper]) (PaymentSession,
160
                error)
161

162
        // NewPaymentSessionEmpty creates a new paymentSession instance that is
163
        // empty, and will be exhausted immediately. Used for failure reporting
164
        // to missioncontrol for resumed payment we don't want to make more
165
        // attempts for.
166
        NewPaymentSessionEmpty() PaymentSession
167
}
168

169
// MissionControlQuerier is an interface that exposes failure reporting and
170
// probability estimation.
171
type MissionControlQuerier interface {
172
        // ReportPaymentFail reports a failed payment to mission control as
173
        // input for future probability estimates. It returns a bool indicating
174
        // whether this error is a final error and no further payment attempts
175
        // need to be made.
176
        ReportPaymentFail(attemptID uint64, rt *route.Route,
177
                failureSourceIdx *int, failure lnwire.FailureMessage) (
178
                *channeldb.FailureReason, error)
179

180
        // ReportPaymentSuccess reports a successful payment to mission control
181
        // as input for future probability estimates.
182
        ReportPaymentSuccess(attemptID uint64, rt *route.Route) error
183

184
        // GetProbability is expected to return the success probability of a
185
        // payment from fromNode along edge.
186
        GetProbability(fromNode, toNode route.Vertex,
187
                amt lnwire.MilliSatoshi, capacity btcutil.Amount) float64
188
}
189

190
// FeeSchema is the set fee configuration for a Lightning Node on the network.
191
// Using the coefficients described within the schema, the required fee to
192
// forward outgoing payments can be derived.
193
type FeeSchema struct {
194
        // BaseFee is the base amount of milli-satoshis that will be chained
195
        // for ANY payment forwarded.
196
        BaseFee lnwire.MilliSatoshi
197

198
        // FeeRate is the rate that will be charged for forwarding payments.
199
        // This value should be interpreted as the numerator for a fraction
200
        // (fixed point arithmetic) whose denominator is 1 million. As a result
201
        // the effective fee rate charged per mSAT will be: (amount *
202
        // FeeRate/1,000,000).
203
        FeeRate uint32
204

205
        // InboundFee is the inbound fee schedule that applies to forwards
206
        // coming in through a channel to which this FeeSchema pertains.
207
        InboundFee fn.Option[models.InboundFee]
208
}
209

210
// ChannelPolicy holds the parameters that determine the policy we enforce
211
// when forwarding payments on a channel. These parameters are communicated
212
// to the rest of the network in ChannelUpdate messages.
213
type ChannelPolicy struct {
214
        // FeeSchema holds the fee configuration for a channel.
215
        FeeSchema
216

217
        // TimeLockDelta is the required HTLC timelock delta to be used
218
        // when forwarding payments.
219
        TimeLockDelta uint32
220

221
        // MaxHTLC is the maximum HTLC size including fees we are allowed to
222
        // forward over this channel.
223
        MaxHTLC lnwire.MilliSatoshi
224

225
        // MinHTLC is the minimum HTLC size including fees we are allowed to
226
        // forward over this channel.
227
        MinHTLC *lnwire.MilliSatoshi
228
}
229

230
// Config defines the configuration for the ChannelRouter. ALL elements within
231
// the configuration MUST be non-nil for the ChannelRouter to carry out its
232
// duties.
233
type Config struct {
234
        // SelfNode is the public key of the node that this channel router
235
        // belongs to.
236
        SelfNode route.Vertex
237

238
        // RoutingGraph is a graph source that will be used for pathfinding.
239
        RoutingGraph Graph
240

241
        // Chain is the router's source to the most up-to-date blockchain data.
242
        // All incoming advertised channels will be checked against the chain
243
        // to ensure that the channels advertised are still open.
244
        Chain lnwallet.BlockChainIO
245

246
        // Payer is an instance of a PaymentAttemptDispatcher and is used by
247
        // the router to send payment attempts onto the network, and receive
248
        // their results.
249
        Payer PaymentAttemptDispatcher
250

251
        // Control keeps track of the status of ongoing payments, ensuring we
252
        // can properly resume them across restarts.
253
        Control ControlTower
254

255
        // MissionControl is a shared memory of sorts that executions of
256
        // payment path finding use in order to remember which vertexes/edges
257
        // were pruned from prior attempts. During SendPayment execution,
258
        // errors sent by nodes are mapped into a vertex or edge to be pruned.
259
        // Each run will then take into account this set of pruned
260
        // vertexes/edges to reduce route failure and pass on graph information
261
        // gained to the next execution.
262
        MissionControl MissionControlQuerier
263

264
        // SessionSource defines a source for the router to retrieve new payment
265
        // sessions.
266
        SessionSource PaymentSessionSource
267

268
        // GetLink is a method that allows the router to query the lower link
269
        // layer to determine the up-to-date available bandwidth at a
270
        // prospective link to be traversed. If the link isn't available, then
271
        // a value of zero should be returned. Otherwise, the current up-to-
272
        // date knowledge of the available bandwidth of the link should be
273
        // returned.
274
        GetLink getLinkQuery
275

276
        // NextPaymentID is a method that guarantees to return a new, unique ID
277
        // each time it is called. This is used by the router to generate a
278
        // unique payment ID for each payment it attempts to send, such that
279
        // the switch can properly handle the HTLC.
280
        NextPaymentID func() (uint64, error)
281

282
        // PathFindingConfig defines global path finding parameters.
283
        PathFindingConfig PathFindingConfig
284

285
        // Clock is mockable time provider.
286
        Clock clock.Clock
287

288
        // ApplyChannelUpdate can be called to apply a new channel update to the
289
        // graph that we received from a payment failure.
290
        ApplyChannelUpdate func(msg *lnwire.ChannelUpdate1) bool
291

292
        // ClosedSCIDs is used by the router to fetch closed channels.
293
        //
294
        // TODO(yy): remove it once the root cause of stuck payments is found.
295
        ClosedSCIDs map[lnwire.ShortChannelID]struct{}
296

297
        // TrafficShaper is an optional traffic shaper that can be used to
298
        // control the outgoing channel of a payment.
299
        TrafficShaper fn.Option[htlcswitch.AuxTrafficShaper]
300
}
301

302
// EdgeLocator is a struct used to identify a specific edge.
303
type EdgeLocator struct {
304
        // ChannelID is the channel of this edge.
305
        ChannelID uint64
306

307
        // Direction takes the value of 0 or 1 and is identical in definition to
308
        // the channel direction flag. A value of 0 means the direction from the
309
        // lower node pubkey to the higher.
310
        Direction uint8
311
}
312

313
// String returns a human-readable version of the edgeLocator values.
314
func (e *EdgeLocator) String() string {
×
315
        return fmt.Sprintf("%v:%v", e.ChannelID, e.Direction)
×
316
}
×
317

318
// ChannelRouter is the layer 3 router within the Lightning stack. Below the
319
// ChannelRouter is the HtlcSwitch, and below that is the Bitcoin blockchain
320
// itself. The primary role of the ChannelRouter is to respond to queries for
321
// potential routes that can support a payment amount, and also general graph
322
// reachability questions. The router will prune the channel graph
323
// automatically as new blocks are discovered which spend certain known funding
324
// outpoints, thereby closing their respective channels.
325
type ChannelRouter struct {
326
        started uint32 // To be used atomically.
327
        stopped uint32 // To be used atomically.
328

329
        // cfg is a copy of the configuration struct that the ChannelRouter was
330
        // initialized with.
331
        cfg *Config
332

333
        quit chan struct{}
334
        wg   sync.WaitGroup
335
}
336

337
// New creates a new instance of the ChannelRouter with the specified
338
// configuration parameters. As part of initialization, if the router detects
339
// that the channel graph isn't fully in sync with the latest UTXO (since the
340
// channel graph is a subset of the UTXO set) set, then the router will proceed
341
// to fully sync to the latest state of the UTXO set.
342
func New(cfg Config) (*ChannelRouter, error) {
20✔
343
        return &ChannelRouter{
20✔
344
                cfg:  &cfg,
20✔
345
                quit: make(chan struct{}),
20✔
346
        }, nil
20✔
347
}
20✔
348

349
// Start launches all the goroutines the ChannelRouter requires to carry out
350
// its duties. If the router has already been started, then this method is a
351
// noop.
352
func (r *ChannelRouter) Start() error {
20✔
353
        if !atomic.CompareAndSwapUint32(&r.started, 0, 1) {
20✔
354
                return nil
×
355
        }
×
356

357
        log.Info("Channel Router starting")
20✔
358

20✔
359
        // If any payments are still in flight, we resume, to make sure their
20✔
360
        // results are properly handled.
20✔
361
        if err := r.resumePayments(); err != nil {
20✔
362
                log.Error("Failed to resume payments during startup")
×
363
        }
×
364

365
        return nil
20✔
366
}
367

368
// Stop signals the ChannelRouter to gracefully halt all routines. This method
369
// will *block* until all goroutines have excited. If the channel router has
370
// already stopped then this method will return immediately.
371
func (r *ChannelRouter) Stop() error {
20✔
372
        if !atomic.CompareAndSwapUint32(&r.stopped, 0, 1) {
20✔
373
                return nil
×
374
        }
×
375

376
        log.Info("Channel Router shutting down...")
20✔
377
        defer log.Debug("Channel Router shutdown complete")
20✔
378

20✔
379
        close(r.quit)
20✔
380
        r.wg.Wait()
20✔
381

20✔
382
        return nil
20✔
383
}
384

385
// RouteRequest contains the parameters for a pathfinding request. It may
386
// describe a request to make a regular payment or one to a blinded path
387
// (incdicated by a non-nil BlindedPayment field).
388
type RouteRequest struct {
389
        // Source is the node that the path originates from.
390
        Source route.Vertex
391

392
        // Target is the node that the path terminates at. If the route
393
        // includes a blinded path, target will be the blinded node id of the
394
        // final hop in the blinded route.
395
        Target route.Vertex
396

397
        // Amount is the Amount in millisatoshis to be delivered to the target
398
        // node.
399
        Amount lnwire.MilliSatoshi
400

401
        // TimePreference expresses the caller's time preference for
402
        // pathfinding.
403
        TimePreference float64
404

405
        // Restrictions provides a set of additional Restrictions that the
406
        // route must adhere to.
407
        Restrictions *RestrictParams
408

409
        // CustomRecords is a set of custom tlv records to include for the
410
        // final hop.
411
        CustomRecords record.CustomSet
412

413
        // RouteHints contains an additional set of edges to include in our
414
        // view of the graph. This may either be a set of hints for private
415
        // channels or a "virtual" hop hint that represents a blinded route.
416
        RouteHints RouteHints
417

418
        // FinalExpiry is the cltv delta for the final hop. If paying to a
419
        // blinded path, this value is a duplicate of the delta provided
420
        // in blinded payment.
421
        FinalExpiry uint16
422

423
        // BlindedPathSet contains a set of optional blinded paths and
424
        // parameters used to reach a target node blinded paths. This field is
425
        // mutually exclusive with the Target field.
426
        BlindedPathSet *BlindedPaymentPathSet
427
}
428

429
// RouteHints is an alias type for a set of route hints, with the source node
430
// as the map's key and the details of the hint(s) in the edge policy.
431
type RouteHints map[route.Vertex][]AdditionalEdge
432

433
// NewRouteRequest produces a new route request for a regular payment or one
434
// to a blinded route, validating that the target, routeHints and finalExpiry
435
// parameters are mutually exclusive with the blindedPayment parameter (which
436
// contains these values for blinded payments).
437
func NewRouteRequest(source route.Vertex, target *route.Vertex,
438
        amount lnwire.MilliSatoshi, timePref float64,
439
        restrictions *RestrictParams, customRecords record.CustomSet,
440
        routeHints RouteHints, blindedPathSet *BlindedPaymentPathSet,
441
        finalExpiry uint16) (*RouteRequest, error) {
19✔
442

19✔
443
        var (
19✔
444
                // Assume that we're starting off with a regular payment.
19✔
445
                requestHints  = routeHints
19✔
446
                requestExpiry = finalExpiry
19✔
447
                err           error
19✔
448
        )
19✔
449

19✔
450
        if blindedPathSet != nil {
28✔
451
                if blindedPathSet.IsIntroNode(source) {
10✔
452
                        return nil, ErrSelfIntro
1✔
453
                }
1✔
454

455
                // Check that the values for a clear path have not been set,
456
                // as this is an ambiguous signal from the caller.
457
                if routeHints != nil {
9✔
458
                        return nil, ErrHintsAndBlinded
1✔
459
                }
1✔
460

461
                if finalExpiry != 0 {
8✔
462
                        return nil, ErrExpiryAndBlinded
1✔
463
                }
1✔
464

465
                requestExpiry = blindedPathSet.FinalCLTVDelta()
6✔
466

6✔
467
                requestHints, err = blindedPathSet.ToRouteHints()
6✔
468
                if err != nil {
6✔
469
                        return nil, err
×
470
                }
×
471
        }
472

473
        requestTarget, err := getTargetNode(target, blindedPathSet)
16✔
474
        if err != nil {
17✔
475
                return nil, err
1✔
476
        }
1✔
477

478
        return &RouteRequest{
15✔
479
                Source:         source,
15✔
480
                Target:         requestTarget,
15✔
481
                Amount:         amount,
15✔
482
                TimePreference: timePref,
15✔
483
                Restrictions:   restrictions,
15✔
484
                CustomRecords:  customRecords,
15✔
485
                RouteHints:     requestHints,
15✔
486
                FinalExpiry:    requestExpiry,
15✔
487
                BlindedPathSet: blindedPathSet,
15✔
488
        }, nil
15✔
489
}
490

491
func getTargetNode(target *route.Vertex,
492
        blindedPathSet *BlindedPaymentPathSet) (route.Vertex, error) {
16✔
493

16✔
494
        var (
16✔
495
                blinded   = blindedPathSet != nil
16✔
496
                targetSet = target != nil
16✔
497
        )
16✔
498

16✔
499
        switch {
16✔
500
        case blinded && targetSet:
1✔
501
                return route.Vertex{}, ErrTargetAndBlinded
1✔
502

503
        case blinded:
5✔
504
                return route.NewVertex(blindedPathSet.TargetPubKey()), nil
5✔
505

506
        case targetSet:
13✔
507
                return *target, nil
13✔
508

509
        default:
×
510
                return route.Vertex{}, ErrNoTarget
×
511
        }
512
}
513

514
// FindRoute attempts to query the ChannelRouter for the optimum path to a
515
// particular target destination to which it is able to send `amt` after
516
// factoring in channel capacities and cumulative fees along the route.
517
func (r *ChannelRouter) FindRoute(req *RouteRequest) (*route.Route, float64,
518
        error) {
8✔
519

8✔
520
        log.Debugf("Searching for path to %v, sending %v", req.Target,
8✔
521
                req.Amount)
8✔
522

8✔
523
        // We'll attempt to obtain a set of bandwidth hints that can help us
8✔
524
        // eliminate certain routes early on in the path finding process.
8✔
525
        bandwidthHints, err := newBandwidthManager(
8✔
526
                r.cfg.RoutingGraph, r.cfg.SelfNode, r.cfg.GetLink,
8✔
527
                fn.None[tlv.Blob](), r.cfg.TrafficShaper,
8✔
528
        )
8✔
529
        if err != nil {
8✔
530
                return nil, 0, err
×
531
        }
×
532

533
        // We'll fetch the current block height, so we can properly calculate
534
        // the required HTLC time locks within the route.
535
        _, currentHeight, err := r.cfg.Chain.GetBestBlock()
8✔
536
        if err != nil {
8✔
537
                return nil, 0, err
×
538
        }
×
539

540
        // Now that we know the destination is reachable within the graph, we'll
541
        // execute our path finding algorithm.
542
        finalHtlcExpiry := currentHeight + int32(req.FinalExpiry)
8✔
543

8✔
544
        // Validate time preference.
8✔
545
        timePref := req.TimePreference
8✔
546
        if timePref < -1 || timePref > 1 {
8✔
547
                return nil, 0, errors.New("time preference out of range")
×
548
        }
×
549

550
        path, probability, err := findPath(
8✔
551
                &graphParams{
8✔
552
                        additionalEdges: req.RouteHints,
8✔
553
                        bandwidthHints:  bandwidthHints,
8✔
554
                        graph:           r.cfg.RoutingGraph,
8✔
555
                },
8✔
556
                req.Restrictions, &r.cfg.PathFindingConfig,
8✔
557
                r.cfg.SelfNode, req.Source, req.Target, req.Amount,
8✔
558
                req.TimePreference, finalHtlcExpiry,
8✔
559
        )
8✔
560
        if err != nil {
11✔
561
                return nil, 0, err
3✔
562
        }
3✔
563

564
        // Create the route with absolute time lock values.
565
        route, err := newRoute(
8✔
566
                req.Source, path, uint32(currentHeight),
8✔
567
                finalHopParams{
8✔
568
                        amt:       req.Amount,
8✔
569
                        totalAmt:  req.Amount,
8✔
570
                        cltvDelta: req.FinalExpiry,
8✔
571
                        records:   req.CustomRecords,
8✔
572
                }, req.BlindedPathSet,
8✔
573
        )
8✔
574
        if err != nil {
8✔
575
                return nil, 0, err
×
576
        }
×
577

578
        go log.Tracef("Obtained path to send %v to %x: %v",
8✔
579
                req.Amount, req.Target, lnutils.SpewLogClosure(route))
8✔
580

8✔
581
        return route, probability, nil
8✔
582
}
583

584
// probabilitySource defines the signature of a function that can be used to
585
// query the success probability of sending a given amount between the two
586
// given vertices.
587
type probabilitySource func(route.Vertex, route.Vertex, lnwire.MilliSatoshi,
588
        btcutil.Amount) float64
589

590
// BlindedPathRestrictions are a set of constraints to adhere to when
591
// choosing a set of blinded paths to this node.
592
type BlindedPathRestrictions struct {
593
        // MinDistanceFromIntroNode is the minimum number of _real_ (non-dummy)
594
        // hops to include in a blinded path. Since we post-fix dummy hops, this
595
        // is the minimum distance between our node and the introduction node
596
        // of the path. This doesn't include our node, so if the minimum is 1,
597
        // then the path will contain at minimum our node along with an
598
        // introduction node hop.
599
        MinDistanceFromIntroNode uint8
600

601
        // NumHops is the number of hops that each blinded path should consist
602
        // of. If paths are found with a number of hops less that NumHops, then
603
        // dummy hops will be padded on to the route. This value doesn't
604
        // include our node, so if the maximum is 1, then the path will contain
605
        // our node along with an introduction node hop.
606
        NumHops uint8
607

608
        // MaxNumPaths is the maximum number of blinded paths to select.
609
        MaxNumPaths uint8
610

611
        // NodeOmissionSet is a set of nodes that should not be used within any
612
        // of the blinded paths that we generate.
613
        NodeOmissionSet fn.Set[route.Vertex]
614

615
        // IncomingChainedChannels holds the chained channels list (specified
616
        // via channel id) starting from a channel which points to the receiver
617
        // node.
618
        IncomingChainedChannels []uint64
619
}
620

621
// FindBlindedPaths finds a selection of paths to the destination node that can
622
// be used in blinded payment paths.
623
func (r *ChannelRouter) FindBlindedPaths(destination route.Vertex,
624
        amt lnwire.MilliSatoshi, probabilitySrc probabilitySource,
625
        restrictions *BlindedPathRestrictions) ([]*route.Route, error) {
10✔
626

10✔
627
        // First, find a set of candidate paths given the destination node and
10✔
628
        // path length restrictions.
10✔
629
        incomingChainedChannels := restrictions.IncomingChainedChannels
10✔
630
        minDistanceFromIntroNode := restrictions.MinDistanceFromIntroNode
10✔
631
        paths, err := findBlindedPaths(
10✔
632
                r.cfg.RoutingGraph, destination, &blindedPathRestrictions{
10✔
633
                        minNumHops:              minDistanceFromIntroNode,
10✔
634
                        maxNumHops:              restrictions.NumHops,
10✔
635
                        nodeOmissionSet:         restrictions.NodeOmissionSet,
10✔
636
                        incomingChainedChannels: incomingChainedChannels,
10✔
637
                },
10✔
638
        )
10✔
639
        if err != nil {
13✔
640
                return nil, err
3✔
641
        }
3✔
642

643
        // routeWithProbability groups a route with the probability of a
644
        // payment of the given amount succeeding on that path.
645
        type routeWithProbability struct {
10✔
646
                route       *route.Route
10✔
647
                probability float64
10✔
648
        }
10✔
649

10✔
650
        // Iterate over all the candidate paths and determine the success
10✔
651
        // probability of each path given the data we have about forwards
10✔
652
        // between any two nodes on a path.
10✔
653
        routes := make([]*routeWithProbability, 0, len(paths))
10✔
654
        for _, path := range paths {
31✔
655
                if len(path) < 1 {
21✔
656
                        return nil, fmt.Errorf("a blinded path must have at " +
×
657
                                "least one hop")
×
658
                }
×
659

660
                var (
21✔
661
                        introNode = path[0].vertex
21✔
662
                        prevNode  = introNode
21✔
663
                        hops      = make(
21✔
664
                                []*route.Hop, 0, len(path)-1,
21✔
665
                        )
21✔
666
                        totalRouteProbability = float64(1)
21✔
667
                )
21✔
668

21✔
669
                // For each set of hops on the path, get the success probability
21✔
670
                // of a forward between those two vertices and use that to
21✔
671
                // update the overall route probability.
21✔
672
                for j := 1; j < len(path); j++ {
58✔
673
                        probability := probabilitySrc(
37✔
674
                                prevNode, path[j].vertex, amt,
37✔
675
                                path[j-1].edgeCapacity,
37✔
676
                        )
37✔
677

37✔
678
                        totalRouteProbability *= probability
37✔
679

37✔
680
                        hops = append(hops, &route.Hop{
37✔
681
                                PubKeyBytes: path[j].vertex,
37✔
682
                                ChannelID:   path[j-1].channelID,
37✔
683
                        })
37✔
684

37✔
685
                        prevNode = path[j].vertex
37✔
686
                }
37✔
687

688
                routeWithProbability := &routeWithProbability{
21✔
689
                        route: &route.Route{
21✔
690
                                SourcePubKey: introNode,
21✔
691
                                Hops:         hops,
21✔
692
                        },
21✔
693
                        probability: totalRouteProbability,
21✔
694
                }
21✔
695

21✔
696
                // Don't bother adding a route if its success probability less
21✔
697
                // minimum that can be assigned to any single pair.
21✔
698
                if totalRouteProbability <= DefaultMinRouteProbability {
23✔
699
                        log.Debugf("Not using route (%v) as a blinded "+
2✔
700
                                "path since it resulted in an low "+
2✔
701
                                "probability path(%.3f)",
2✔
702
                                route.ChanIDString(routeWithProbability.route),
2✔
703
                                routeWithProbability.probability)
2✔
704

2✔
705
                        continue
2✔
706
                }
707

708
                routes = append(routes, routeWithProbability)
19✔
709
        }
710

711
        // Sort the routes based on probability.
712
        sort.Slice(routes, func(i, j int) bool {
24✔
713
                return routes[i].probability > routes[j].probability
14✔
714
        })
14✔
715

716
        // Now just choose the best paths up until the maximum number of allowed
717
        // paths.
718
        bestRoutes := make([]*route.Route, 0, restrictions.MaxNumPaths)
10✔
719
        for _, route := range routes {
28✔
720
                if len(bestRoutes) >= int(restrictions.MaxNumPaths) {
19✔
721
                        break
1✔
722
                }
723

724
                bestRoutes = append(bestRoutes, route.route)
17✔
725
        }
726

727
        return bestRoutes, nil
10✔
728
}
729

730
// generateNewSessionKey generates a new ephemeral private key to be used for a
731
// payment attempt.
732
func generateNewSessionKey() (*btcec.PrivateKey, error) {
39✔
733
        // Generate a new random session key to ensure that we don't trigger
39✔
734
        // any replay.
39✔
735
        //
39✔
736
        // TODO(roasbeef): add more sources of randomness?
39✔
737
        return btcec.NewPrivateKey()
39✔
738
}
39✔
739

740
// LightningPayment describes a payment to be sent through the network to the
741
// final destination.
742
type LightningPayment struct {
743
        // Target is the node in which the payment should be routed towards.
744
        Target route.Vertex
745

746
        // Amount is the value of the payment to send through the network in
747
        // milli-satoshis.
748
        Amount lnwire.MilliSatoshi
749

750
        // FeeLimit is the maximum fee in millisatoshis that the payment should
751
        // accept when sending it through the network. The payment will fail
752
        // if there isn't a route with lower fees than this limit.
753
        FeeLimit lnwire.MilliSatoshi
754

755
        // CltvLimit is the maximum time lock that is allowed for attempts to
756
        // complete this payment.
757
        CltvLimit uint32
758

759
        // paymentHash is the r-hash value to use within the HTLC extended to
760
        // the first hop. This won't be set for AMP payments.
761
        paymentHash *lntypes.Hash
762

763
        // amp is an optional field that is set if and only if this is am AMP
764
        // payment.
765
        amp *AMPOptions
766

767
        // FinalCLTVDelta is the CTLV expiry delta to use for the _final_ hop
768
        // in the route. This means that the final hop will have a CLTV delta
769
        // of at least: currentHeight + FinalCLTVDelta.
770
        FinalCLTVDelta uint16
771

772
        // PayAttemptTimeout is a timeout value that we'll use to determine
773
        // when we should should abandon the payment attempt after consecutive
774
        // payment failure. This prevents us from attempting to send a payment
775
        // indefinitely. A zero value means the payment will never time out.
776
        //
777
        // TODO(halseth): make wallclock time to allow resume after startup.
778
        PayAttemptTimeout time.Duration
779

780
        // RouteHints represents the different routing hints that can be used to
781
        // assist a payment in reaching its destination successfully. These
782
        // hints will act as intermediate hops along the route.
783
        //
784
        // NOTE: This is optional unless required by the payment. When providing
785
        // multiple routes, ensure the hop hints within each route are chained
786
        // together and sorted in forward order in order to reach the
787
        // destination successfully. This is mutually exclusive to the
788
        // BlindedPayment field.
789
        RouteHints [][]zpay32.HopHint
790

791
        // BlindedPathSet holds the information about a set of blinded paths to
792
        // the payment recipient. This is mutually exclusive to the RouteHints
793
        // field.
794
        BlindedPathSet *BlindedPaymentPathSet
795

796
        // OutgoingChannelIDs is the list of channels that are allowed for the
797
        // first hop. If nil, any channel may be used.
798
        OutgoingChannelIDs []uint64
799

800
        // LastHop is the pubkey of the last node before the final destination
801
        // is reached. If nil, any node may be used.
802
        LastHop *route.Vertex
803

804
        // DestFeatures specifies the set of features we assume the final node
805
        // has for pathfinding. Typically, these will be taken directly from an
806
        // invoice, but they can also be manually supplied or assumed by the
807
        // sender. If a nil feature vector is provided, the router will try to
808
        // fall back to the graph in order to load a feature vector for a node
809
        // in the public graph.
810
        DestFeatures *lnwire.FeatureVector
811

812
        // PaymentAddr is the payment address specified by the receiver. This
813
        // field should be a random 32-byte nonce presented in the receiver's
814
        // invoice to prevent probing of the destination.
815
        PaymentAddr fn.Option[[32]byte]
816

817
        // PaymentRequest is an optional payment request that this payment is
818
        // attempting to complete.
819
        PaymentRequest []byte
820

821
        // DestCustomRecords are TLV records that are to be sent to the final
822
        // hop in the new onion payload format. If the destination does not
823
        // understand this new onion payload format, then the payment will
824
        // fail.
825
        DestCustomRecords record.CustomSet
826

827
        // FirstHopCustomRecords are the TLV records that are to be sent to the
828
        // first hop of this payment. These records will be transmitted via the
829
        // wire message and therefore do not affect the onion payload size.
830
        FirstHopCustomRecords lnwire.CustomRecords
831

832
        // MaxParts is the maximum number of partial payments that may be used
833
        // to complete the full amount.
834
        MaxParts uint32
835

836
        // MaxShardAmt is the largest shard that we'll attempt to split using.
837
        // If this field is set, and we need to split, rather than attempting
838
        // half of the original payment amount, we'll use this value if half
839
        // the payment amount is greater than it.
840
        //
841
        // NOTE: This field is _optional_.
842
        MaxShardAmt *lnwire.MilliSatoshi
843

844
        // TimePref is the time preference for this payment. Set to -1 to
845
        // optimize for fees only, to 1 to optimize for reliability only or a
846
        // value in between for a mix.
847
        TimePref float64
848

849
        // Metadata is additional data that is sent along with the payment to
850
        // the payee.
851
        Metadata []byte
852
}
853

854
// AMPOptions houses information that must be known in order to send an AMP
855
// payment.
856
type AMPOptions struct {
857
        SetID     [32]byte
858
        RootShare [32]byte
859
}
860

861
// SetPaymentHash sets the given hash as the payment's overall hash. This
862
// should only be used for non-AMP payments.
863
func (l *LightningPayment) SetPaymentHash(hash lntypes.Hash) error {
16✔
864
        if l.amp != nil {
16✔
865
                return fmt.Errorf("cannot set payment hash for AMP payment")
×
866
        }
×
867

868
        l.paymentHash = &hash
16✔
869
        return nil
16✔
870
}
871

872
// SetAMP sets the given AMP options for the payment.
873
func (l *LightningPayment) SetAMP(amp *AMPOptions) error {
3✔
874
        if l.paymentHash != nil {
3✔
875
                return fmt.Errorf("cannot set amp options for payment " +
×
876
                        "with payment hash")
×
877
        }
×
878

879
        l.amp = amp
3✔
880
        return nil
3✔
881
}
882

883
// Identifier returns a 32-byte slice that uniquely identifies this single
884
// payment. For non-AMP payments this will be the payment hash, for AMP
885
// payments this will be the used SetID.
886
func (l *LightningPayment) Identifier() [32]byte {
74✔
887
        if l.amp != nil {
77✔
888
                return l.amp.SetID
3✔
889
        }
3✔
890

891
        return *l.paymentHash
74✔
892
}
893

894
// SendPayment attempts to send a payment as described within the passed
895
// LightningPayment. This function is blocking and will return either: when the
896
// payment is successful, or all candidates routes have been attempted and
897
// resulted in a failed payment. If the payment succeeds, then a non-nil Route
898
// will be returned which describes the path the successful payment traversed
899
// within the network to reach the destination. Additionally, the payment
900
// preimage will also be returned.
901
func (r *ChannelRouter) SendPayment(payment *LightningPayment) ([32]byte,
902
        *route.Route, error) {
12✔
903

12✔
904
        paySession, shardTracker, err := r.PreparePayment(payment)
12✔
905
        if err != nil {
12✔
906
                return [32]byte{}, nil, err
×
907
        }
×
908

909
        log.Tracef("Dispatching SendPayment for lightning payment: %v",
12✔
910
                spewPayment(payment))
12✔
911

12✔
912
        return r.sendPayment(
12✔
913
                context.Background(), payment.FeeLimit, payment.Identifier(),
12✔
914
                payment.PayAttemptTimeout, paySession, shardTracker,
12✔
915
                payment.FirstHopCustomRecords,
12✔
916
        )
12✔
917
}
918

919
// SendPaymentAsync is the non-blocking version of SendPayment. The payment
920
// result needs to be retrieved via the control tower.
921
func (r *ChannelRouter) SendPaymentAsync(ctx context.Context,
922
        payment *LightningPayment, ps PaymentSession, st shards.ShardTracker) {
3✔
923

3✔
924
        // Since this is the first time this payment is being made, we pass nil
3✔
925
        // for the existing attempt.
3✔
926
        r.wg.Add(1)
3✔
927
        go func() {
6✔
928
                defer r.wg.Done()
3✔
929

3✔
930
                log.Tracef("Dispatching SendPayment for lightning payment: %v",
3✔
931
                        spewPayment(payment))
3✔
932

3✔
933
                _, _, err := r.sendPayment(
3✔
934
                        ctx, payment.FeeLimit, payment.Identifier(),
3✔
935
                        payment.PayAttemptTimeout, ps, st,
3✔
936
                        payment.FirstHopCustomRecords,
3✔
937
                )
3✔
938
                if err != nil {
6✔
939
                        log.Errorf("Payment %x failed: %v",
3✔
940
                                payment.Identifier(), err)
3✔
941
                }
3✔
942
        }()
943
}
944

945
// spewPayment returns a log closures that provides a spewed string
946
// representation of the passed payment.
947
func spewPayment(payment *LightningPayment) lnutils.LogClosure {
15✔
948
        return lnutils.NewLogClosure(func() string {
15✔
949
                // Make a copy of the payment with a nilled Curve
×
950
                // before spewing.
×
951
                var routeHints [][]zpay32.HopHint
×
952
                for _, routeHint := range payment.RouteHints {
×
953
                        var hopHints []zpay32.HopHint
×
954
                        for _, hopHint := range routeHint {
×
955
                                h := hopHint.Copy()
×
956
                                hopHints = append(hopHints, h)
×
957
                        }
×
958
                        routeHints = append(routeHints, hopHints)
×
959
                }
960
                p := *payment
×
961
                p.RouteHints = routeHints
×
962
                return spew.Sdump(p)
×
963
        })
964
}
965

966
// PreparePayment creates the payment session and registers the payment with the
967
// control tower.
968
func (r *ChannelRouter) PreparePayment(payment *LightningPayment) (
969
        PaymentSession, shards.ShardTracker, error) {
15✔
970

15✔
971
        // Assemble any custom data we want to send to the first hop only.
15✔
972
        var firstHopData fn.Option[tlv.Blob]
15✔
973
        if len(payment.FirstHopCustomRecords) > 0 {
18✔
974
                if err := payment.FirstHopCustomRecords.Validate(); err != nil {
3✔
975
                        return nil, nil, fmt.Errorf("invalid first hop custom "+
×
976
                                "records: %w", err)
×
977
                }
×
978

979
                firstHopBlob, err := payment.FirstHopCustomRecords.Serialize()
3✔
980
                if err != nil {
3✔
981
                        return nil, nil, fmt.Errorf("unable to serialize "+
×
982
                                "first hop custom records: %w", err)
×
983
                }
×
984

985
                firstHopData = fn.Some(firstHopBlob)
3✔
986
        }
987

988
        // Before starting the HTLC routing attempt, we'll create a fresh
989
        // payment session which will report our errors back to mission
990
        // control.
991
        paySession, err := r.cfg.SessionSource.NewPaymentSession(
15✔
992
                payment, firstHopData, r.cfg.TrafficShaper,
15✔
993
        )
15✔
994
        if err != nil {
15✔
995
                return nil, nil, err
×
996
        }
×
997

998
        // Record this payment hash with the ControlTower, ensuring it is not
999
        // already in-flight.
1000
        //
1001
        // TODO(roasbeef): store records as part of creation info?
1002
        info := &channeldb.PaymentCreationInfo{
15✔
1003
                PaymentIdentifier:     payment.Identifier(),
15✔
1004
                Value:                 payment.Amount,
15✔
1005
                CreationTime:          r.cfg.Clock.Now(),
15✔
1006
                PaymentRequest:        payment.PaymentRequest,
15✔
1007
                FirstHopCustomRecords: payment.FirstHopCustomRecords,
15✔
1008
        }
15✔
1009

15✔
1010
        // Create a new ShardTracker that we'll use during the life cycle of
15✔
1011
        // this payment.
15✔
1012
        var shardTracker shards.ShardTracker
15✔
1013
        switch {
15✔
1014
        // If this is an AMP payment, we'll use the AMP shard tracker.
1015
        case payment.amp != nil:
3✔
1016
                addr := payment.PaymentAddr.UnwrapOr([32]byte{})
3✔
1017
                shardTracker = amp.NewShardTracker(
3✔
1018
                        payment.amp.RootShare, payment.amp.SetID, addr,
3✔
1019
                        payment.Amount,
3✔
1020
                )
3✔
1021

1022
        // Otherwise we'll use the simple tracker that will map each attempt to
1023
        // the same payment hash.
1024
        default:
15✔
1025
                shardTracker = shards.NewSimpleShardTracker(
15✔
1026
                        payment.Identifier(), nil,
15✔
1027
                )
15✔
1028
        }
1029

1030
        err = r.cfg.Control.InitPayment(payment.Identifier(), info)
15✔
1031
        if err != nil {
15✔
1032
                return nil, nil, err
×
1033
        }
×
1034

1035
        return paySession, shardTracker, nil
15✔
1036
}
1037

1038
// SendToRoute sends a payment using the provided route and fails the payment
1039
// when an error is returned from the attempt.
1040
func (r *ChannelRouter) SendToRoute(htlcHash lntypes.Hash, rt *route.Route,
1041
        firstHopCustomRecords lnwire.CustomRecords) (*channeldb.HTLCAttempt,
1042
        error) {
9✔
1043

9✔
1044
        return r.sendToRoute(htlcHash, rt, false, firstHopCustomRecords)
9✔
1045
}
9✔
1046

1047
// SendToRouteSkipTempErr sends a payment using the provided route and fails
1048
// the payment ONLY when a terminal error is returned from the attempt.
1049
func (r *ChannelRouter) SendToRouteSkipTempErr(htlcHash lntypes.Hash,
1050
        rt *route.Route,
1051
        firstHopCustomRecords lnwire.CustomRecords) (*channeldb.HTLCAttempt,
1052
        error) {
4✔
1053

4✔
1054
        return r.sendToRoute(htlcHash, rt, true, firstHopCustomRecords)
4✔
1055
}
4✔
1056

1057
// sendToRoute attempts to send a payment with the given hash through the
1058
// provided route. This function is blocking and will return the attempt
1059
// information as it is stored in the database. For a successful htlc, this
1060
// information will contain the preimage. If an error occurs after the attempt
1061
// was initiated, both return values will be non-nil. If skipTempErr is true,
1062
// the payment won't be failed unless a terminal error has occurred.
1063
func (r *ChannelRouter) sendToRoute(htlcHash lntypes.Hash, rt *route.Route,
1064
        skipTempErr bool,
1065
        firstHopCustomRecords lnwire.CustomRecords) (*channeldb.HTLCAttempt,
1066
        error) {
13✔
1067

13✔
1068
        // Helper function to fail a payment. It makes sure the payment is only
13✔
1069
        // failed once so that the failure reason is not overwritten.
13✔
1070
        failPayment := func(paymentIdentifier lntypes.Hash,
13✔
1071
                reason channeldb.FailureReason) error {
21✔
1072

8✔
1073
                payment, fetchErr := r.cfg.Control.FetchPayment(
8✔
1074
                        paymentIdentifier,
8✔
1075
                )
8✔
1076
                if fetchErr != nil {
8✔
1077
                        return fetchErr
×
1078
                }
×
1079

1080
                // NOTE: We cannot rely on the payment status to be failed here
1081
                // because it can still be in-flight although the payment is
1082
                // already failed.
1083
                _, failedReason := payment.TerminalInfo()
8✔
1084
                if failedReason != nil {
12✔
1085
                        return nil
4✔
1086
                }
4✔
1087

1088
                return r.cfg.Control.FailPayment(paymentIdentifier, reason)
7✔
1089
        }
1090

1091
        log.Debugf("SendToRoute for payment %v with skipTempErr=%v",
13✔
1092
                htlcHash, skipTempErr)
13✔
1093

13✔
1094
        // Calculate amount paid to receiver.
13✔
1095
        amt := rt.ReceiverAmt()
13✔
1096

13✔
1097
        // If this is meant as an MP payment shard, we set the amount for the
13✔
1098
        // creating info to the total amount of the payment.
13✔
1099
        finalHop := rt.Hops[len(rt.Hops)-1]
13✔
1100
        mpp := finalHop.MPP
13✔
1101
        if mpp != nil {
20✔
1102
                amt = mpp.TotalMsat()
7✔
1103
        }
7✔
1104

1105
        // For non-MPP, there's no such thing as temp error as there's only one
1106
        // HTLC attempt being made. When this HTLC is failed, the payment is
1107
        // failed hence cannot be retried.
1108
        if skipTempErr && mpp == nil {
14✔
1109
                return nil, ErrSkipTempErr
1✔
1110
        }
1✔
1111

1112
        // For non-AMP payments the overall payment identifier will be the same
1113
        // hash as used for this HTLC.
1114
        paymentIdentifier := htlcHash
12✔
1115

12✔
1116
        // For AMP-payments, we'll use the setID as the unique ID for the
12✔
1117
        // overall payment.
12✔
1118
        amp := finalHop.AMP
12✔
1119
        if amp != nil {
15✔
1120
                paymentIdentifier = amp.SetID()
3✔
1121
        }
3✔
1122

1123
        // Record this payment hash with the ControlTower, ensuring it is not
1124
        // already in-flight.
1125
        info := &channeldb.PaymentCreationInfo{
12✔
1126
                PaymentIdentifier:     paymentIdentifier,
12✔
1127
                Value:                 amt,
12✔
1128
                CreationTime:          r.cfg.Clock.Now(),
12✔
1129
                PaymentRequest:        nil,
12✔
1130
                FirstHopCustomRecords: firstHopCustomRecords,
12✔
1131
        }
12✔
1132

12✔
1133
        err := r.cfg.Control.InitPayment(paymentIdentifier, info)
12✔
1134
        switch {
12✔
1135
        // If this is an MPP attempt and the hash is already registered with
1136
        // the database, we can go on to launch the shard.
1137
        case mpp != nil && errors.Is(err, paymentsdb.ErrPaymentInFlight):
3✔
NEW
1138
        case mpp != nil && errors.Is(err, paymentsdb.ErrPaymentExists):
×
1139

1140
        // Any other error is not tolerated.
1141
        case err != nil:
×
1142
                return nil, err
×
1143
        }
1144

1145
        log.Tracef("Dispatching SendToRoute for HTLC hash %v: %v", htlcHash,
12✔
1146
                lnutils.SpewLogClosure(rt))
12✔
1147

12✔
1148
        // Since the HTLC hashes and preimages are specified manually over the
12✔
1149
        // RPC for SendToRoute requests, we don't have to worry about creating
12✔
1150
        // a ShardTracker that can generate hashes for AMP payments. Instead, we
12✔
1151
        // create a simple tracker that can just return the hash for the single
12✔
1152
        // shard we'll now launch.
12✔
1153
        shardTracker := shards.NewSimpleShardTracker(htlcHash, nil)
12✔
1154

12✔
1155
        // Create a payment lifecycle using the given route with,
12✔
1156
        // - zero fee limit as we are not requesting routes.
12✔
1157
        // - nil payment session (since we already have a route).
12✔
1158
        // - no payment timeout.
12✔
1159
        // - no current block height.
12✔
1160
        p := newPaymentLifecycle(
12✔
1161
                r, 0, paymentIdentifier, nil, shardTracker, 0,
12✔
1162
                firstHopCustomRecords,
12✔
1163
        )
12✔
1164

12✔
1165
        // Allow the traffic shaper to add custom records to the outgoing HTLC
12✔
1166
        // and also adjust the amount if needed.
12✔
1167
        err = p.amendFirstHopData(rt)
12✔
1168
        if err != nil {
12✔
1169
                return nil, err
×
1170
        }
×
1171

1172
        // We found a route to try, create a new HTLC attempt to try.
1173
        //
1174
        // NOTE: we use zero `remainingAmt` here to simulate the same effect of
1175
        // setting the lastShard to be false, which is used by previous
1176
        // implementation.
1177
        attempt, err := p.registerAttempt(rt, 0)
12✔
1178
        if err != nil {
13✔
1179
                return nil, err
1✔
1180
        }
1✔
1181

1182
        // Once the attempt is created, send it to the htlcswitch. Notice that
1183
        // the `err` returned here has already been processed by
1184
        // `handleSwitchErr`, which means if there's a terminal failure, the
1185
        // payment has been failed.
1186
        result, err := p.sendAttempt(attempt)
11✔
1187
        if err != nil {
11✔
1188
                return nil, err
×
1189
        }
×
1190

1191
        // Since for SendToRoute we won't retry in case the shard fails, we'll
1192
        // mark the payment failed with the control tower immediately if the
1193
        // skipTempErr is false.
1194
        reason := channeldb.FailureReasonError
11✔
1195

11✔
1196
        // If we failed to send the HTLC, we need to further decide if we want
11✔
1197
        // to fail the payment.
11✔
1198
        if result.err != nil {
17✔
1199
                // If skipTempErr, we'll return the attempt and the temp error.
6✔
1200
                if skipTempErr {
8✔
1201
                        return result.attempt, result.err
2✔
1202
                }
2✔
1203

1204
                err := failPayment(paymentIdentifier, reason)
4✔
1205
                if err != nil {
4✔
1206
                        return nil, err
×
1207
                }
×
1208

1209
                return result.attempt, result.err
4✔
1210
        }
1211

1212
        // The attempt was successfully sent, wait for the result to be
1213
        // available.
1214
        result, err = p.collectAndHandleResult(attempt)
8✔
1215
        if err != nil {
8✔
1216
                return nil, err
×
1217
        }
×
1218

1219
        // We got a successful result.
1220
        if result.err == nil {
12✔
1221
                return result.attempt, nil
4✔
1222
        }
4✔
1223

1224
        // An error returned from collecting the result, we'll mark the payment
1225
        // as failed if we don't skip temp error.
1226
        if !skipTempErr {
14✔
1227
                err := failPayment(paymentIdentifier, reason)
7✔
1228
                if err != nil {
7✔
1229
                        return nil, err
×
1230
                }
×
1231
        }
1232

1233
        return result.attempt, result.err
7✔
1234
}
1235

1236
// sendPayment attempts to send a payment to the passed payment hash. This
1237
// function is blocking and will return either: when the payment is successful,
1238
// or all candidates routes have been attempted and resulted in a failed
1239
// payment. If the payment succeeds, then a non-nil Route will be returned
1240
// which describes the path the successful payment traversed within the network
1241
// to reach the destination. Additionally, the payment preimage will also be
1242
// returned.
1243
//
1244
// This method relies on the ControlTower's internal payment state machine to
1245
// carry out its execution. After restarts, it is safe, and assumed, that the
1246
// router will call this method for every payment still in-flight according to
1247
// the ControlTower.
1248
func (r *ChannelRouter) sendPayment(ctx context.Context,
1249
        feeLimit lnwire.MilliSatoshi, identifier lntypes.Hash,
1250
        paymentAttemptTimeout time.Duration, paySession PaymentSession,
1251
        shardTracker shards.ShardTracker,
1252
        firstHopCustomRecords lnwire.CustomRecords) ([32]byte, *route.Route,
1253
        error) {
15✔
1254

15✔
1255
        // If the user provides a timeout, we will additionally wrap the context
15✔
1256
        // in a deadline.
15✔
1257
        cancel := func() {}
30✔
1258
        if paymentAttemptTimeout > 0 {
18✔
1259
                ctx, cancel = context.WithTimeout(ctx, paymentAttemptTimeout)
3✔
1260
        }
3✔
1261

1262
        // Since resumePayment is a blocking call, we'll cancel this
1263
        // context if the payment completes before the optional
1264
        // deadline.
1265
        defer cancel()
15✔
1266

15✔
1267
        // We'll also fetch the current block height, so we can properly
15✔
1268
        // calculate the required HTLC time locks within the route.
15✔
1269
        _, currentHeight, err := r.cfg.Chain.GetBestBlock()
15✔
1270
        if err != nil {
15✔
1271
                return [32]byte{}, nil, err
×
1272
        }
×
1273

1274
        // Validate the custom records before we attempt to send the payment.
1275
        // TODO(ziggie): Move this check before registering the payment in the
1276
        // db (InitPayment).
1277
        if err := firstHopCustomRecords.Validate(); err != nil {
15✔
1278
                return [32]byte{}, nil, err
×
1279
        }
×
1280

1281
        // Now set up a paymentLifecycle struct with these params, such that we
1282
        // can resume the payment from the current state.
1283
        p := newPaymentLifecycle(
15✔
1284
                r, feeLimit, identifier, paySession, shardTracker,
15✔
1285
                currentHeight, firstHopCustomRecords,
15✔
1286
        )
15✔
1287

15✔
1288
        return p.resumePayment(ctx)
15✔
1289
}
1290

1291
// extractChannelUpdate examines the error and extracts the channel update.
1292
func (r *ChannelRouter) extractChannelUpdate(
1293
        failure lnwire.FailureMessage) *lnwire.ChannelUpdate1 {
20✔
1294

20✔
1295
        var update *lnwire.ChannelUpdate1
20✔
1296
        switch onionErr := failure.(type) {
20✔
1297
        case *lnwire.FailExpiryTooSoon:
1✔
1298
                update = &onionErr.Update
1✔
1299
        case *lnwire.FailAmountBelowMinimum:
3✔
1300
                update = &onionErr.Update
3✔
1301
        case *lnwire.FailFeeInsufficient:
10✔
1302
                update = &onionErr.Update
10✔
1303
        case *lnwire.FailIncorrectCltvExpiry:
×
1304
                update = &onionErr.Update
×
1305
        case *lnwire.FailChannelDisabled:
3✔
1306
                update = &onionErr.Update
3✔
1307
        case *lnwire.FailTemporaryChannelFailure:
8✔
1308
                update = onionErr.Update
8✔
1309
        }
1310

1311
        return update
20✔
1312
}
1313

1314
// ErrNoChannel is returned when a route cannot be built because there are no
1315
// channels that satisfy all requirements.
1316
type ErrNoChannel struct {
1317
        position int
1318
}
1319

1320
// Error returns a human-readable string describing the error.
1321
func (e ErrNoChannel) Error() string {
1✔
1322
        return fmt.Sprintf("no matching outgoing channel available for "+
1✔
1323
                "node index %v", e.position)
1✔
1324
}
1✔
1325

1326
// BuildRoute returns a fully specified route based on a list of pubkeys. If
1327
// amount is nil, the minimum routable amount is used. To force a specific
1328
// outgoing channel, use the outgoingChan parameter.
1329
func (r *ChannelRouter) BuildRoute(amt fn.Option[lnwire.MilliSatoshi],
1330
        hops []route.Vertex, outgoingChan *uint64, finalCltvDelta int32,
1331
        payAddr fn.Option[[32]byte], firstHopBlob fn.Option[[]byte]) (
1332
        *route.Route, error) {
11✔
1333

11✔
1334
        log.Tracef("BuildRoute called: hopsCount=%v, amt=%v", len(hops), amt)
11✔
1335

11✔
1336
        var outgoingChans map[uint64]struct{}
11✔
1337
        if outgoingChan != nil {
11✔
1338
                outgoingChans = map[uint64]struct{}{
×
1339
                        *outgoingChan: {},
×
1340
                }
×
1341
        }
×
1342

1343
        // We'll attempt to obtain a set of bandwidth hints that helps us select
1344
        // the best outgoing channel to use in case no outgoing channel is set.
1345
        bandwidthHints, err := newBandwidthManager(
11✔
1346
                r.cfg.RoutingGraph, r.cfg.SelfNode, r.cfg.GetLink, firstHopBlob,
11✔
1347
                r.cfg.TrafficShaper,
11✔
1348
        )
11✔
1349
        if err != nil {
11✔
1350
                return nil, err
×
1351
        }
×
1352

1353
        sourceNode := r.cfg.SelfNode
11✔
1354

11✔
1355
        // We check that each node in the route has a connection to others that
11✔
1356
        // can forward in principle.
11✔
1357
        unifiers, err := getEdgeUnifiers(
11✔
1358
                r.cfg.SelfNode, hops, outgoingChans, r.cfg.RoutingGraph,
11✔
1359
        )
11✔
1360
        if err != nil {
12✔
1361
                return nil, err
1✔
1362
        }
1✔
1363

1364
        var (
10✔
1365
                receiverAmt lnwire.MilliSatoshi
10✔
1366
                senderAmt   lnwire.MilliSatoshi
10✔
1367
                pathEdges   []*unifiedEdge
10✔
1368
        )
10✔
1369

10✔
1370
        // We determine the edges compatible with the requested amount, as well
10✔
1371
        // as the amount to send, which can be used to determine the final
10✔
1372
        // receiver amount, if a minimal amount was requested.
10✔
1373
        pathEdges, senderAmt, err = senderAmtBackwardPass(
10✔
1374
                unifiers, amt, bandwidthHints,
10✔
1375
        )
10✔
1376
        if err != nil {
12✔
1377
                return nil, err
2✔
1378
        }
2✔
1379

1380
        // For the minimal amount search, we need to do a forward pass to find a
1381
        // larger receiver amount due to possible min HTLC bumps, otherwise we
1382
        // just use the requested amount.
1383
        receiverAmt, err = fn.ElimOption(
8✔
1384
                amt,
8✔
1385
                func() fn.Result[lnwire.MilliSatoshi] {
11✔
1386
                        return fn.NewResult(
3✔
1387
                                receiverAmtForwardPass(senderAmt, pathEdges),
3✔
1388
                        )
3✔
1389
                },
3✔
1390
                fn.Ok[lnwire.MilliSatoshi],
1391
        ).Unpack()
1392
        if err != nil {
8✔
1393
                return nil, err
×
1394
        }
×
1395

1396
        // Fetch the current block height outside the routing transaction, to
1397
        // prevent the rpc call blocking the database.
1398
        _, height, err := r.cfg.Chain.GetBestBlock()
8✔
1399
        if err != nil {
8✔
1400
                return nil, err
×
1401
        }
×
1402

1403
        // Build and return the final route.
1404
        return newRoute(
8✔
1405
                sourceNode, pathEdges, uint32(height),
8✔
1406
                finalHopParams{
8✔
1407
                        amt:         receiverAmt,
8✔
1408
                        totalAmt:    receiverAmt,
8✔
1409
                        cltvDelta:   uint16(finalCltvDelta),
8✔
1410
                        records:     nil,
8✔
1411
                        paymentAddr: payAddr,
8✔
1412
                }, nil,
8✔
1413
        )
8✔
1414
}
1415

1416
// resumePayments fetches inflight payments and resumes their payment
1417
// lifecycles.
1418
func (r *ChannelRouter) resumePayments() error {
20✔
1419
        // Get all payments that are inflight.
20✔
1420
        log.Debugf("Scanning for inflight payments")
20✔
1421
        payments, err := r.cfg.Control.FetchInFlightPayments()
20✔
1422
        if err != nil {
20✔
1423
                return err
×
1424
        }
×
1425

1426
        log.Debugf("Scanning finished, found %d inflight payments",
20✔
1427
                len(payments))
20✔
1428

20✔
1429
        // Before we restart existing payments and start accepting more
20✔
1430
        // payments to be made, we clean the network result store of the
20✔
1431
        // Switch. We do this here at startup to ensure no more payments can be
20✔
1432
        // made concurrently, so we know the toKeep map will be up-to-date
20✔
1433
        // until the cleaning has finished.
20✔
1434
        toKeep := make(map[uint64]struct{})
20✔
1435
        for _, p := range payments {
23✔
1436
                for _, a := range p.HTLCs {
6✔
1437
                        toKeep[a.AttemptID] = struct{}{}
3✔
1438

3✔
1439
                        // Try to fail the attempt if the route contains a dead
3✔
1440
                        // channel.
3✔
1441
                        r.failStaleAttempt(a, p.Info.PaymentIdentifier)
3✔
1442
                }
3✔
1443
        }
1444

1445
        log.Debugf("Cleaning network result store.")
20✔
1446
        if err := r.cfg.Payer.CleanStore(toKeep); err != nil {
20✔
1447
                return err
×
1448
        }
×
1449

1450
        // launchPayment is a helper closure that handles resuming the payment.
1451
        launchPayment := func(payment *channeldb.MPPayment) {
23✔
1452
                defer r.wg.Done()
3✔
1453

3✔
1454
                // Get the hashes used for the outstanding HTLCs.
3✔
1455
                htlcs := make(map[uint64]lntypes.Hash)
3✔
1456
                for _, a := range payment.HTLCs {
6✔
1457
                        a := a
3✔
1458

3✔
1459
                        // We check whether the individual attempts have their
3✔
1460
                        // HTLC hash set, if not we'll fall back to the overall
3✔
1461
                        // payment hash.
3✔
1462
                        hash := payment.Info.PaymentIdentifier
3✔
1463
                        if a.Hash != nil {
6✔
1464
                                hash = *a.Hash
3✔
1465
                        }
3✔
1466

1467
                        htlcs[a.AttemptID] = hash
3✔
1468
                }
1469

1470
                payHash := payment.Info.PaymentIdentifier
3✔
1471

3✔
1472
                // Since we are not supporting creating more shards after a
3✔
1473
                // restart (only receiving the result of the shards already
3✔
1474
                // outstanding), we create a simple shard tracker that will map
3✔
1475
                // the attempt IDs to hashes used for the HTLCs. This will be
3✔
1476
                // enough also for AMP payments, since we only need the hashes
3✔
1477
                // for the individual HTLCs to regenerate the circuits, and we
3✔
1478
                // don't currently persist the root share necessary to
3✔
1479
                // re-derive them.
3✔
1480
                shardTracker := shards.NewSimpleShardTracker(payHash, htlcs)
3✔
1481

3✔
1482
                // We create a dummy, empty payment session such that we won't
3✔
1483
                // make another payment attempt when the result for the
3✔
1484
                // in-flight attempt is received.
3✔
1485
                paySession := r.cfg.SessionSource.NewPaymentSessionEmpty()
3✔
1486

3✔
1487
                // We pass in a non-timeout context, to indicate we don't need
3✔
1488
                // it to timeout. It will stop immediately after the existing
3✔
1489
                // attempt has finished anyway. We also set a zero fee limit,
3✔
1490
                // as no more routes should be tried.
3✔
1491
                noTimeout := time.Duration(0)
3✔
1492
                _, _, err := r.sendPayment(
3✔
1493
                        context.Background(), 0, payHash, noTimeout, paySession,
3✔
1494
                        shardTracker, payment.Info.FirstHopCustomRecords,
3✔
1495
                )
3✔
1496
                if err != nil {
6✔
1497
                        log.Errorf("Resuming payment %v failed: %v", payHash,
3✔
1498
                                err)
3✔
1499

3✔
1500
                        return
3✔
1501
                }
3✔
1502

1503
                log.Infof("Resumed payment %v completed", payHash)
3✔
1504
        }
1505

1506
        for _, payment := range payments {
23✔
1507
                log.Infof("Resuming payment %v", payment.Info.PaymentIdentifier)
3✔
1508

3✔
1509
                r.wg.Add(1)
3✔
1510
                go launchPayment(payment)
3✔
1511
        }
3✔
1512

1513
        return nil
20✔
1514
}
1515

1516
// failStaleAttempt will fail an HTLC attempt if it's using an unknown channel
1517
// in its route. It first consults the switch to see if there's already a
1518
// network result stored for this attempt. If not, it will check whether the
1519
// first hop of this attempt is using an active channel known to us. If
1520
// inactive, this attempt will be failed.
1521
//
1522
// NOTE: there's an unknown bug that caused the network result for a particular
1523
// attempt to NOT be saved, resulting a payment being stuck forever. More info:
1524
// - https://github.com/lightningnetwork/lnd/issues/8146
1525
// - https://github.com/lightningnetwork/lnd/pull/8174
1526
func (r *ChannelRouter) failStaleAttempt(a channeldb.HTLCAttempt,
1527
        payHash lntypes.Hash) {
3✔
1528

3✔
1529
        // We can only fail inflight HTLCs so we skip the settled/failed ones.
3✔
1530
        if a.Failure != nil || a.Settle != nil {
3✔
1531
                return
×
1532
        }
×
1533

1534
        // First, check if we've already had a network result for this attempt.
1535
        // If no result is found, we'll check whether the reference link is
1536
        // still known to us.
1537
        ok, err := r.cfg.Payer.HasAttemptResult(a.AttemptID)
3✔
1538
        if err != nil {
3✔
1539
                log.Errorf("Failed to fetch network result for attempt=%v",
×
1540
                        a.AttemptID)
×
1541
                return
×
1542
        }
×
1543

1544
        // There's already a network result, no need to fail it here as the
1545
        // payment lifecycle will take care of it, so we can exit early.
1546
        if ok {
3✔
1547
                log.Debugf("Already have network result for attempt=%v",
×
1548
                        a.AttemptID)
×
1549
                return
×
1550
        }
×
1551

1552
        // We now need to decide whether this attempt should be failed here.
1553
        // For very old payments, it's possible that the network results were
1554
        // never saved, causing the payments to be stuck inflight. We now check
1555
        // whether the first hop is referencing an active channel ID and, if
1556
        // not, we will fail the attempt as it has no way to be retried again.
1557
        var shouldFail bool
3✔
1558

3✔
1559
        // Validate that the attempt has hop info. If this attempt has no hop
3✔
1560
        // info it indicates an error in our db.
3✔
1561
        if len(a.Route.Hops) == 0 {
3✔
1562
                log.Errorf("Found empty hop for attempt=%v", a.AttemptID)
×
1563

×
1564
                shouldFail = true
×
1565
        } else {
3✔
1566
                // Get the short channel ID.
3✔
1567
                chanID := a.Route.Hops[0].ChannelID
3✔
1568
                scid := lnwire.NewShortChanIDFromInt(chanID)
3✔
1569

3✔
1570
                // Check whether this link is active. If so, we won't fail the
3✔
1571
                // attempt but keep waiting for its result.
3✔
1572
                _, err := r.cfg.GetLink(scid)
3✔
1573
                if err == nil {
3✔
1574
                        return
×
1575
                }
×
1576

1577
                // We should get the link not found err. If not, we will log an
1578
                // error and skip failing this attempt since an unknown error
1579
                // occurred.
1580
                if !errors.Is(err, htlcswitch.ErrChannelLinkNotFound) {
3✔
1581
                        log.Errorf("Failed to get link for attempt=%v for "+
×
1582
                                "payment=%v: %v", a.AttemptID, payHash, err)
×
1583

×
1584
                        return
×
1585
                }
×
1586

1587
                // The channel link is not active, we now check whether this
1588
                // channel is already closed. If so, we fail the HTLC attempt
1589
                // as there's no need to wait for its network result because
1590
                // there's no link. If the channel is still pending, we'll keep
1591
                // waiting for the result as we may get a contract resolution
1592
                // for this HTLC.
1593
                if _, ok := r.cfg.ClosedSCIDs[scid]; ok {
3✔
1594
                        shouldFail = true
×
1595
                }
×
1596
        }
1597

1598
        // Exit if there's no need to fail.
1599
        if !shouldFail {
6✔
1600
                return
3✔
1601
        }
3✔
1602

1603
        log.Errorf("Failing stale attempt=%v for payment=%v", a.AttemptID,
×
1604
                payHash)
×
1605

×
1606
        // Fail the attempt in db. If there's an error, there's nothing we can
×
1607
        // do here but logging it.
×
1608
        failInfo := &channeldb.HTLCFailInfo{
×
1609
                Reason:   channeldb.HTLCFailUnknown,
×
1610
                FailTime: r.cfg.Clock.Now(),
×
1611
        }
×
1612
        _, err = r.cfg.Control.FailAttempt(payHash, a.AttemptID, failInfo)
×
1613
        if err != nil {
×
1614
                log.Errorf("Fail attempt=%v got error: %v", a.AttemptID, err)
×
1615
        }
×
1616
}
1617

1618
// getEdgeUnifiers returns a list of edge unifiers for the given route.
1619
func getEdgeUnifiers(source route.Vertex, hops []route.Vertex,
1620
        outgoingChans map[uint64]struct{},
1621
        graph Graph) ([]*edgeUnifier, error) {
11✔
1622

11✔
1623
        // Allocate a list that will contain the edge unifiers for this route.
11✔
1624
        unifiers := make([]*edgeUnifier, len(hops))
11✔
1625

11✔
1626
        // Traverse hops backwards to accumulate fees in the running amounts.
11✔
1627
        for i := len(hops) - 1; i >= 0; i-- {
27✔
1628
                toNode := hops[i]
16✔
1629

16✔
1630
                var fromNode route.Vertex
16✔
1631
                if i == 0 {
25✔
1632
                        fromNode = source
9✔
1633
                } else {
19✔
1634
                        fromNode = hops[i-1]
10✔
1635
                }
10✔
1636

1637
                // Build unified policies for this hop based on the channels
1638
                // known in the graph. Inbound fees are only active if the edge
1639
                // is not the last hop.
1640
                isExitHop := i == len(hops)-1
16✔
1641
                u := newNodeEdgeUnifier(
16✔
1642
                        source, toNode, !isExitHop, outgoingChans,
16✔
1643
                )
16✔
1644

16✔
1645
                err := u.addGraphPolicies(graph)
16✔
1646
                if err != nil {
16✔
1647
                        return nil, err
×
1648
                }
×
1649

1650
                // Exit if there are no channels.
1651
                edgeUnifier, ok := u.edgeUnifiers[fromNode]
16✔
1652
                if !ok {
17✔
1653
                        log.Errorf("Cannot find policy for node %v", fromNode)
1✔
1654
                        return nil, ErrNoChannel{position: i}
1✔
1655
                }
1✔
1656

1657
                unifiers[i] = edgeUnifier
15✔
1658
        }
1659

1660
        return unifiers, nil
10✔
1661
}
1662

1663
// senderAmtBackwardPass returns a list of unified edges for the given route and
1664
// determines the amount that should be sent to fulfill min HTLC requirements.
1665
// The minimal sender amount can be searched for by using amt=None.
1666
func senderAmtBackwardPass(unifiers []*edgeUnifier,
1667
        amt fn.Option[lnwire.MilliSatoshi],
1668
        bandwidthHints bandwidthHints) ([]*unifiedEdge, lnwire.MilliSatoshi,
1669
        error) {
14✔
1670

14✔
1671
        if len(unifiers) == 0 {
15✔
1672
                return nil, 0, fmt.Errorf("no unifiers provided")
1✔
1673
        }
1✔
1674

1675
        var unifiedEdges = make([]*unifiedEdge, len(unifiers))
13✔
1676

13✔
1677
        // We traverse the route backwards and handle the last hop separately.
13✔
1678
        edgeUnifier := unifiers[len(unifiers)-1]
13✔
1679

13✔
1680
        // incomingAmt tracks the amount that is forwarded on the edges of a
13✔
1681
        // route. The last hop only forwards the amount that the receiver should
13✔
1682
        // receive, as there are no fees paid to the last node.
13✔
1683
        // For minimum amount routes, aim to deliver at least 1 msat to
13✔
1684
        // the destination. There are nodes in the wild that have a
13✔
1685
        // min_htlc channel policy of zero, which could lead to a zero
13✔
1686
        // amount payment being made.
13✔
1687
        incomingAmt := amt.UnwrapOr(1)
13✔
1688

13✔
1689
        // If using min amt, increase the amount if needed to fulfill min HTLC
13✔
1690
        // requirements.
13✔
1691
        if amt.IsNone() {
18✔
1692
                min := edgeUnifier.minAmt()
5✔
1693
                if min > incomingAmt {
10✔
1694
                        incomingAmt = min
5✔
1695
                }
5✔
1696
        }
1697

1698
        // Get an edge for the specific amount that we want to forward.
1699
        edge := edgeUnifier.getEdge(incomingAmt, bandwidthHints, 0)
13✔
1700
        if edge == nil {
14✔
1701
                log.Errorf("Cannot find policy with amt=%v "+
1✔
1702
                        "for hop %v", incomingAmt, len(unifiers)-1)
1✔
1703

1✔
1704
                return nil, 0, ErrNoChannel{position: len(unifiers) - 1}
1✔
1705
        }
1✔
1706

1707
        unifiedEdges[len(unifiers)-1] = edge
12✔
1708

12✔
1709
        // Handle the rest of the route except the last hop.
12✔
1710
        for i := len(unifiers) - 2; i >= 0; i-- {
27✔
1711
                edgeUnifier = unifiers[i]
15✔
1712

15✔
1713
                // If using min amt, increase the amount if needed to fulfill
15✔
1714
                // min HTLC requirements.
15✔
1715
                if amt.IsNone() {
21✔
1716
                        min := edgeUnifier.minAmt()
6✔
1717
                        if min > incomingAmt {
6✔
1718
                                incomingAmt = min
×
1719
                        }
×
1720
                }
1721

1722
                // A --current hop-- B --next hop: incomingAmt-- C
1723
                // The outbound fee paid to the current end node B is based on
1724
                // the amount that the next hop forwards and B's policy for that
1725
                // hop.
1726
                outboundFee := unifiedEdges[i+1].policy.ComputeFee(
15✔
1727
                        incomingAmt,
15✔
1728
                )
15✔
1729

15✔
1730
                netAmount := incomingAmt + outboundFee
15✔
1731

15✔
1732
                // We need to select an edge that can forward the requested
15✔
1733
                // amount.
15✔
1734
                edge = edgeUnifier.getEdge(
15✔
1735
                        netAmount, bandwidthHints, outboundFee,
15✔
1736
                )
15✔
1737
                if edge == nil {
16✔
1738
                        return nil, 0, ErrNoChannel{position: i}
1✔
1739
                }
1✔
1740

1741
                // The fee paid to B depends on the current hop's inbound fee
1742
                // policy and on the outbound fee for the next hop as any
1743
                // inbound fee discount is capped by the outbound fee such that
1744
                // the total fee for B can't become negative.
1745
                inboundFee := calcCappedInboundFee(edge, netAmount, outboundFee)
14✔
1746

14✔
1747
                fee := lnwire.MilliSatoshi(int64(outboundFee) + inboundFee)
14✔
1748

14✔
1749
                log.Tracef("Select channel %v at position %v",
14✔
1750
                        edge.policy.ChannelID, i)
14✔
1751

14✔
1752
                // Finally, we update the amount that needs to flow into node B
14✔
1753
                // from A, which is the next hop's forwarding amount plus the
14✔
1754
                // fee for B: A --current hop: incomingAmt-- B --next hop-- C
14✔
1755
                incomingAmt += fee
14✔
1756

14✔
1757
                unifiedEdges[i] = edge
14✔
1758
        }
1759

1760
        return unifiedEdges, incomingAmt, nil
11✔
1761
}
1762

1763
// receiverAmtForwardPass returns the amount that a receiver will receive after
1764
// deducting all fees from the sender amount.
1765
func receiverAmtForwardPass(runningAmt lnwire.MilliSatoshi,
1766
        unifiedEdges []*unifiedEdge) (lnwire.MilliSatoshi, error) {
10✔
1767

10✔
1768
        if len(unifiedEdges) == 0 {
11✔
1769
                return 0, fmt.Errorf("no edges to forward through")
1✔
1770
        }
1✔
1771

1772
        inEdge := unifiedEdges[0]
9✔
1773
        if !inEdge.amtInRange(runningAmt) {
10✔
1774
                log.Errorf("Amount %v not in range for hop index %v",
1✔
1775
                        runningAmt, 0)
1✔
1776

1✔
1777
                return 0, ErrNoChannel{position: 0}
1✔
1778
        }
1✔
1779

1780
        // Now that we arrived at the start of the route and found out the route
1781
        // total amount, we make a forward pass. Because the amount may have
1782
        // been increased in the backward pass, fees need to be recalculated and
1783
        // amount ranges re-checked.
1784
        for i := 1; i < len(unifiedEdges); i++ {
17✔
1785
                inEdge := unifiedEdges[i-1]
9✔
1786
                outEdge := unifiedEdges[i]
9✔
1787

9✔
1788
                // Decrease the amount to send while going forward.
9✔
1789
                runningAmt = outgoingFromIncoming(runningAmt, inEdge, outEdge)
9✔
1790

9✔
1791
                if !outEdge.amtInRange(runningAmt) {
9✔
1792
                        log.Errorf("Amount %v not in range for hop index %v",
×
1793
                                runningAmt, i)
×
1794

×
1795
                        return 0, ErrNoChannel{position: i}
×
1796
                }
×
1797
        }
1798

1799
        return runningAmt, nil
8✔
1800
}
1801

1802
// incomingFromOutgoing computes the incoming amount based on the outgoing
1803
// amount by adding fees to the outgoing amount, replicating the path finding
1804
// and routing process, see also CheckHtlcForward.
1805
func incomingFromOutgoing(outgoingAmt lnwire.MilliSatoshi,
1806
        incoming, outgoing *unifiedEdge) lnwire.MilliSatoshi {
31✔
1807

31✔
1808
        outgoingFee := outgoing.policy.ComputeFee(outgoingAmt)
31✔
1809

31✔
1810
        // Net amount is the amount the inbound fees are calculated with.
31✔
1811
        netAmount := outgoingAmt + outgoingFee
31✔
1812

31✔
1813
        inboundFee := incoming.inboundFees.CalcFee(netAmount)
31✔
1814

31✔
1815
        // The inbound fee is not allowed to reduce the incoming amount below
31✔
1816
        // the outgoing amount.
31✔
1817
        if int64(outgoingFee)+inboundFee < 0 {
40✔
1818
                return outgoingAmt
9✔
1819
        }
9✔
1820

1821
        return netAmount + lnwire.MilliSatoshi(inboundFee)
22✔
1822
}
1823

1824
// outgoingFromIncoming computes the outgoing amount based on the incoming
1825
// amount by subtracting fees from the incoming amount. Note that this is not
1826
// exactly the inverse of incomingFromOutgoing, because of some rounding.
1827
func outgoingFromIncoming(incomingAmt lnwire.MilliSatoshi,
1828
        incoming, outgoing *unifiedEdge) lnwire.MilliSatoshi {
40✔
1829

40✔
1830
        // Convert all quantities to big.Int to be able to hande negative
40✔
1831
        // values. The formulas to compute the outgoing amount involve terms
40✔
1832
        // with PPM*PPM*A, which can easily overflow an int64.
40✔
1833
        A := big.NewInt(int64(incomingAmt))
40✔
1834
        Ro := big.NewInt(int64(outgoing.policy.FeeProportionalMillionths))
40✔
1835
        Bo := big.NewInt(int64(outgoing.policy.FeeBaseMSat))
40✔
1836
        Ri := big.NewInt(int64(incoming.inboundFees.Rate))
40✔
1837
        Bi := big.NewInt(int64(incoming.inboundFees.Base))
40✔
1838
        PPM := big.NewInt(1_000_000)
40✔
1839

40✔
1840
        // The following discussion was contributed by user feelancer21, see
40✔
1841
        //nolint:ll
40✔
1842
        // https://github.com/feelancer21/lnd/commit/f6f05fa930985aac0d27c3f6681aada1b599162a.
40✔
1843

40✔
1844
        // The incoming amount Ai based on the outgoing amount Ao is computed by
40✔
1845
        // Ai = max(Ai(Ao), Ao), which caps the incoming amount such that the
40✔
1846
        // total node fee (Ai - Ao) is non-negative. This is commonly enforced
40✔
1847
        // by routing nodes.
40✔
1848

40✔
1849
        // The function Ai(Ao) is given by:
40✔
1850
        // Ai(Ao) = (Ao + Bo + Ro/PPM) + (Bi + (Ao + Ro/PPM + Bo)*Ri/PPM), where
40✔
1851
        // the first term is the net amount (the outgoing amount plus the
40✔
1852
        // outbound fee), and the second is the inbound fee computed based on
40✔
1853
        // the net amount.
40✔
1854

40✔
1855
        // Ai(Ao) can potentially become more negative in absolute value than
40✔
1856
        // Ao, which is why the above mentioned capping is needed. We can
40✔
1857
        // abbreviate Ai(Ao) with Ai(Ao) = m*Ao + n, where m and n are:
40✔
1858
        // m := (1 + Ro/PPM) * (1 + Ri/PPM)
40✔
1859
        // n := Bi + Bo*(1 + Ri/PPM)
40✔
1860

40✔
1861
        // If we know that m > 0, this is equivalent of Ri/PPM > -1, because Ri
40✔
1862
        // is the only factor that can become negative. A value or Ri/PPM = -1,
40✔
1863
        // means that the routing node is willing to give up on 100% of the
40✔
1864
        // net amount (based on the fee rate), which is likely to not happen in
40✔
1865
        // practice. This condition will be important for a later trick.
40✔
1866

40✔
1867
        // If we want to compute the incoming amount based on the outgoing
40✔
1868
        // amount, which is the reverse problem, we need to solve Ai =
40✔
1869
        // max(Ai(Ao), Ao) for Ao(Ai). Given an incoming amount A,
40✔
1870
        // we look for an Ao such that A = max(Ai(Ao), Ao).
40✔
1871

40✔
1872
        // The max function separates this into two cases. The case to take is
40✔
1873
        // not clear yet, because we don't know Ao, but later we see a trick
40✔
1874
        // how to determine which case is the one to take.
40✔
1875

40✔
1876
        // first case: Ai(Ao) <= Ao:
40✔
1877
        // Therefore, A = max(Ai(Ao), Ao) = Ao, we find Ao = A.
40✔
1878
        // This also leads to Ai(A) <= A by substitution into the condition.
40✔
1879

40✔
1880
        // second case: Ai(Ao) > Ao:
40✔
1881
        // Therefore, A = max(Ai(Ao), Ao) = Ai(Ao) = m*Ao + n. Solving for Ao
40✔
1882
        // gives Ao = (A - n)/m.
40✔
1883
        //
40✔
1884
        // We know
40✔
1885
        // Ai(Ao) > Ao  <=>  A = Ai(Ao) > Ao = (A - n)/m,
40✔
1886
        // so A > (A - n)/m.
40✔
1887
        //
40✔
1888
        // **Assuming m > 0**, by multiplying with m, we can transform this to
40✔
1889
        // A * m + n > A.
40✔
1890
        //
40✔
1891
        // We know Ai(A) = A*m + n, therefore Ai(A) > A.
40✔
1892
        //
40✔
1893
        // This means that if we apply the incoming amount calculation to the
40✔
1894
        // **incoming** amount, and this condition holds, then we know that we
40✔
1895
        // deal with the second case, being able to compute the outgoing amount
40✔
1896
        // based off the formula Ao = (A - n)/m, otherwise we will just return
40✔
1897
        // the incoming amount.
40✔
1898

40✔
1899
        // In case the inbound fee rate is less than -1 (-100%), we fail to
40✔
1900
        // compute the outbound amount and return the incoming amount. This also
40✔
1901
        // protects against zero division later.
40✔
1902

40✔
1903
        // We compute m in terms of big.Int to be safe from overflows and to be
40✔
1904
        // consistent with later calculations.
40✔
1905
        // m := (PPM*PPM + Ri*PPM + Ro*PPM + Ro*Ri)/(PPM*PPM)
40✔
1906

40✔
1907
        // Compute terms in (PPM*PPM + Ri*PPM + Ro*PPM + Ro*Ri).
40✔
1908
        m1 := new(big.Int).Mul(PPM, PPM)
40✔
1909
        m2 := new(big.Int).Mul(Ri, PPM)
40✔
1910
        m3 := new(big.Int).Mul(Ro, PPM)
40✔
1911
        m4 := new(big.Int).Mul(Ro, Ri)
40✔
1912

40✔
1913
        // Add up terms m1..m4.
40✔
1914
        m := big.NewInt(0)
40✔
1915
        m.Add(m, m1)
40✔
1916
        m.Add(m, m2)
40✔
1917
        m.Add(m, m3)
40✔
1918
        m.Add(m, m4)
40✔
1919

40✔
1920
        // Since we compare to 0, we can multiply by PPM*PPM to avoid the
40✔
1921
        // division.
40✔
1922
        if m.Int64() <= 0 {
42✔
1923
                return incomingAmt
2✔
1924
        }
2✔
1925

1926
        // In order to decide if the total fee is negative, we apply the fee
1927
        // to the *incoming* amount as mentioned before.
1928

1929
        // We compute the test amount in terms of big.Int to be safe from
1930
        // overflows and to be consistent later calculations.
1931
        // testAmtF := A*m + n =
1932
        // = A + Bo + Bi + (PPM*(A*Ri + A*Ro + Ro*Ri) + A*Ri*Ro)/(PPM*PPM)
1933

1934
        // Compute terms in (A*Ri + A*Ro + Ro*Ri).
1935
        t1 := new(big.Int).Mul(A, Ri)
38✔
1936
        t2 := new(big.Int).Mul(A, Ro)
38✔
1937
        t3 := new(big.Int).Mul(Ro, Ri)
38✔
1938

38✔
1939
        // Sum up terms t1-t3.
38✔
1940
        t4 := big.NewInt(0)
38✔
1941
        t4.Add(t4, t1)
38✔
1942
        t4.Add(t4, t2)
38✔
1943
        t4.Add(t4, t3)
38✔
1944

38✔
1945
        // Compute PPM*(A*Ri + A*Ro + Ro*Ri).
38✔
1946
        t6 := new(big.Int).Mul(PPM, t4)
38✔
1947

38✔
1948
        // Compute A*Ri*Ro.
38✔
1949
        t7 := new(big.Int).Mul(A, Ri)
38✔
1950
        t7.Mul(t7, Ro)
38✔
1951

38✔
1952
        // Compute (PPM*(A*Ri + A*Ro + Ro*Ri) + A*Ri*Ro)/(PPM*PPM).
38✔
1953
        num := new(big.Int).Add(t6, t7)
38✔
1954
        denom := new(big.Int).Mul(PPM, PPM)
38✔
1955
        fraction := new(big.Int).Div(num, denom)
38✔
1956

38✔
1957
        // Sum up all terms.
38✔
1958
        testAmt := big.NewInt(0)
38✔
1959
        testAmt.Add(testAmt, A)
38✔
1960
        testAmt.Add(testAmt, Bo)
38✔
1961
        testAmt.Add(testAmt, Bi)
38✔
1962
        testAmt.Add(testAmt, fraction)
38✔
1963

38✔
1964
        // Protect against negative values for the integer cast to Msat.
38✔
1965
        if testAmt.Int64() < 0 {
42✔
1966
                return incomingAmt
4✔
1967
        }
4✔
1968

1969
        // If the second case holds, we have to compute the outgoing amount.
1970
        if lnwire.MilliSatoshi(testAmt.Int64()) > incomingAmt {
62✔
1971
                // Compute the outgoing amount by integer ceiling division. This
28✔
1972
                // precision is needed because PPM*PPM*A and other terms can
28✔
1973
                // easily overflow with int64, which happens with about
28✔
1974
                // A = 10_000 sat.
28✔
1975

28✔
1976
                // out := (A - n) / m = numerator / denominator
28✔
1977
                // numerator := PPM*(PPM*(A - Bo - Bi) - Bo*Ri)
28✔
1978
                // denominator := PPM*(PPM + Ri + Ro) + Ri*Ro
28✔
1979

28✔
1980
                var numerator big.Int
28✔
1981

28✔
1982
                // Compute (A - Bo - Bi).
28✔
1983
                temp1 := new(big.Int).Sub(A, Bo)
28✔
1984
                temp2 := new(big.Int).Sub(temp1, Bi)
28✔
1985

28✔
1986
                // Compute terms in (PPM*(A - Bo - Bi) - Bo*Ri).
28✔
1987
                temp3 := new(big.Int).Mul(PPM, temp2)
28✔
1988
                temp4 := new(big.Int).Mul(Bo, Ri)
28✔
1989

28✔
1990
                // Compute PPM*(PPM*(A - Bo - Bi) - Bo*Ri)
28✔
1991
                temp5 := new(big.Int).Sub(temp3, temp4)
28✔
1992
                numerator.Mul(PPM, temp5)
28✔
1993

28✔
1994
                var denominator big.Int
28✔
1995

28✔
1996
                // Compute (PPM + Ri + Ro).
28✔
1997
                temp1 = new(big.Int).Add(PPM, Ri)
28✔
1998
                temp2 = new(big.Int).Add(temp1, Ro)
28✔
1999

28✔
2000
                // Compute PPM*(PPM + Ri + Ro) + Ri*Ro.
28✔
2001
                temp3 = new(big.Int).Mul(PPM, temp2)
28✔
2002
                temp4 = new(big.Int).Mul(Ri, Ro)
28✔
2003
                denominator.Add(temp3, temp4)
28✔
2004

28✔
2005
                // We overestimate the outgoing amount by taking the ceiling of
28✔
2006
                // the division. This means that we may round slightly up by a
28✔
2007
                // MilliSatoshi, but this helps to ensure that we don't hit min
28✔
2008
                // HTLC constrains in the context of finding the minimum amount
28✔
2009
                // of a route.
28✔
2010
                // ceil = floor((numerator + denominator - 1) / denominator)
28✔
2011
                ceil := new(big.Int).Add(&numerator, &denominator)
28✔
2012
                ceil.Sub(ceil, big.NewInt(1))
28✔
2013
                ceil.Div(ceil, &denominator)
28✔
2014

28✔
2015
                return lnwire.MilliSatoshi(ceil.Int64())
28✔
2016
        }
28✔
2017

2018
        // Otherwise the inbound fee made up for the outbound fee, which is why
2019
        // we just return the incoming amount.
2020
        return incomingAmt
6✔
2021
}
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