Skip to content

Commit dfe2314

Browse files
committed
routing: refactor pathfinding loop
In preparation for the next commit where we will start hiding underlying graph details such as that a graph session needs to be "closed" after pathfinding is done with it, we refactor things here so that the main pathfinding logic is done in a call-back.
1 parent 99c9440 commit dfe2314

File tree

1 file changed

+49
-18
lines changed

1 file changed

+49
-18
lines changed

routing/payment_session.go

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"github.com/btcsuite/btcd/btcec/v2"
77
"github.com/btcsuite/btclog/v2"
88
"github.com/lightningnetwork/lnd/channeldb"
9+
graphdb "github.com/lightningnetwork/lnd/graph/db"
910
"github.com/lightningnetwork/lnd/graph/db/models"
1011
"github.com/lightningnetwork/lnd/lnutils"
1112
"github.com/lightningnetwork/lnd/lnwire"
@@ -235,6 +236,17 @@ func newPaymentSession(p *LightningPayment, selfNode route.Vertex,
235236
}, nil
236237
}
237238

239+
// pathFindingError is a wrapper error type that is used to distinguish path
240+
// finding errors from other errors in path finding loop.
241+
type pathFindingError struct {
242+
error
243+
}
244+
245+
// Unwrap returns the underlying error.
246+
func (e *pathFindingError) Unwrap() error {
247+
return e.error
248+
}
249+
238250
// RequestRoute returns a route which is likely to be capable for successfully
239251
// routing the specified HTLC payment to the target node. Initially the first
240252
// set of paths returned from this method may encounter routing failure along
@@ -295,13 +307,8 @@ func (p *paymentSession) RequestRoute(maxAmt, feeLimit lnwire.MilliSatoshi,
295307
maxAmt = *p.payment.MaxShardAmt
296308
}
297309

298-
for {
299-
// Get a routing graph session.
300-
graph, closeGraph, err := p.graphSessFactory.NewGraphSession()
301-
if err != nil {
302-
return nil, err
303-
}
304-
310+
var path []*unifiedEdge
311+
findPath := func(graph graphdb.NodeTraverser) error {
305312
// We'll also obtain a set of bandwidthHints from the lower
306313
// layer for each of our outbound channels. This will allow the
307314
// path finding to skip any links that aren't active or just
@@ -310,19 +317,13 @@ func (p *paymentSession) RequestRoute(maxAmt, feeLimit lnwire.MilliSatoshi,
310317
// attempt, because concurrent payments may change balances.
311318
bandwidthHints, err := p.getBandwidthHints(graph)
312319
if err != nil {
313-
// Close routing graph session.
314-
if graphErr := closeGraph(); graphErr != nil {
315-
log.Errorf("could not close graph session: %v",
316-
graphErr)
317-
}
318-
319-
return nil, err
320+
return err
320321
}
321322

322323
p.log.Debugf("pathfinding for amt=%v", maxAmt)
323324

324325
// Find a route for the current amount.
325-
path, _, err := p.pathFinder(
326+
path, _, err = p.pathFinder(
326327
&graphParams{
327328
additionalEdges: p.additionalEdges,
328329
bandwidthHints: bandwidthHints,
@@ -332,12 +333,42 @@ func (p *paymentSession) RequestRoute(maxAmt, feeLimit lnwire.MilliSatoshi,
332333
p.selfNode, p.selfNode, p.payment.Target,
333334
maxAmt, p.payment.TimePref, finalHtlcExpiry,
334335
)
336+
if err != nil {
337+
// Wrap the error to distinguish path finding errors
338+
// from other errors in this closure.
339+
return &pathFindingError{err}
340+
}
341+
342+
return nil
343+
}
344+
345+
for {
346+
// Get a routing graph session.
347+
graph, closeGraph, err := p.graphSessFactory.NewGraphSession()
348+
if err != nil {
349+
return nil, err
350+
}
335351

336-
// Close routing graph session.
337-
if err := closeGraph(); err != nil {
338-
log.Errorf("could not close graph session: %v", err)
352+
err = findPath(graph)
353+
// First, close routing graph session.
354+
// NOTE: this will be removed in an upcoming commit.
355+
if graphErr := closeGraph(); graphErr != nil {
356+
log.Errorf("could not close graph session: %v",
357+
graphErr)
358+
}
359+
// If there is an error, and it is not a path finding error, we
360+
// return it immediately.
361+
if err != nil && !lnutils.ErrorAs[*pathFindingError](err) {
362+
return nil, err
363+
} else if err != nil {
364+
// If the error is a path finding error, we'll unwrap it
365+
// to check the underlying error.
366+
//
367+
//nolint:errorlint
368+
err = err.(*pathFindingError).Unwrap()
339369
}
340370

371+
// Otherwise, we'll switch on the path finding error.
341372
switch {
342373
case err == errNoPathFound:
343374
// Don't split if this is a legacy payment without mpp

0 commit comments

Comments
 (0)