mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-02-22 06:21:40 +01:00
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.
This commit is contained in:
parent
99c9440520
commit
dfe2314a2a
1 changed files with 50 additions and 19 deletions
|
@ -6,6 +6,7 @@ import (
|
|||
"github.com/btcsuite/btcd/btcec/v2"
|
||||
"github.com/btcsuite/btclog/v2"
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
graphdb "github.com/lightningnetwork/lnd/graph/db"
|
||||
"github.com/lightningnetwork/lnd/graph/db/models"
|
||||
"github.com/lightningnetwork/lnd/lnutils"
|
||||
"github.com/lightningnetwork/lnd/lnwire"
|
||||
|
@ -235,6 +236,17 @@ func newPaymentSession(p *LightningPayment, selfNode route.Vertex,
|
|||
}, nil
|
||||
}
|
||||
|
||||
// pathFindingError is a wrapper error type that is used to distinguish path
|
||||
// finding errors from other errors in path finding loop.
|
||||
type pathFindingError struct {
|
||||
error
|
||||
}
|
||||
|
||||
// Unwrap returns the underlying error.
|
||||
func (e *pathFindingError) Unwrap() error {
|
||||
return e.error
|
||||
}
|
||||
|
||||
// RequestRoute returns a route which is likely to be capable for successfully
|
||||
// routing the specified HTLC payment to the target node. Initially the first
|
||||
// set of paths returned from this method may encounter routing failure along
|
||||
|
@ -295,13 +307,8 @@ func (p *paymentSession) RequestRoute(maxAmt, feeLimit lnwire.MilliSatoshi,
|
|||
maxAmt = *p.payment.MaxShardAmt
|
||||
}
|
||||
|
||||
for {
|
||||
// Get a routing graph session.
|
||||
graph, closeGraph, err := p.graphSessFactory.NewGraphSession()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var path []*unifiedEdge
|
||||
findPath := func(graph graphdb.NodeTraverser) error {
|
||||
// We'll also obtain a set of bandwidthHints from the lower
|
||||
// layer for each of our outbound channels. This will allow the
|
||||
// path finding to skip any links that aren't active or just
|
||||
|
@ -310,19 +317,13 @@ func (p *paymentSession) RequestRoute(maxAmt, feeLimit lnwire.MilliSatoshi,
|
|||
// attempt, because concurrent payments may change balances.
|
||||
bandwidthHints, err := p.getBandwidthHints(graph)
|
||||
if err != nil {
|
||||
// Close routing graph session.
|
||||
if graphErr := closeGraph(); graphErr != nil {
|
||||
log.Errorf("could not close graph session: %v",
|
||||
graphErr)
|
||||
}
|
||||
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
p.log.Debugf("pathfinding for amt=%v", maxAmt)
|
||||
|
||||
// Find a route for the current amount.
|
||||
path, _, err := p.pathFinder(
|
||||
path, _, err = p.pathFinder(
|
||||
&graphParams{
|
||||
additionalEdges: p.additionalEdges,
|
||||
bandwidthHints: bandwidthHints,
|
||||
|
@ -332,12 +333,42 @@ func (p *paymentSession) RequestRoute(maxAmt, feeLimit lnwire.MilliSatoshi,
|
|||
p.selfNode, p.selfNode, p.payment.Target,
|
||||
maxAmt, p.payment.TimePref, finalHtlcExpiry,
|
||||
)
|
||||
|
||||
// Close routing graph session.
|
||||
if err := closeGraph(); err != nil {
|
||||
log.Errorf("could not close graph session: %v", err)
|
||||
if err != nil {
|
||||
// Wrap the error to distinguish path finding errors
|
||||
// from other errors in this closure.
|
||||
return &pathFindingError{err}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
for {
|
||||
// Get a routing graph session.
|
||||
graph, closeGraph, err := p.graphSessFactory.NewGraphSession()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = findPath(graph)
|
||||
// First, close routing graph session.
|
||||
// NOTE: this will be removed in an upcoming commit.
|
||||
if graphErr := closeGraph(); graphErr != nil {
|
||||
log.Errorf("could not close graph session: %v",
|
||||
graphErr)
|
||||
}
|
||||
// If there is an error, and it is not a path finding error, we
|
||||
// return it immediately.
|
||||
if err != nil && !lnutils.ErrorAs[*pathFindingError](err) {
|
||||
return nil, err
|
||||
} else if err != nil {
|
||||
// If the error is a path finding error, we'll unwrap it
|
||||
// to check the underlying error.
|
||||
//
|
||||
//nolint:errorlint
|
||||
err = err.(*pathFindingError).Unwrap()
|
||||
}
|
||||
|
||||
// Otherwise, we'll switch on the path finding error.
|
||||
switch {
|
||||
case err == errNoPathFound:
|
||||
// Don't split if this is a legacy payment without mpp
|
||||
|
|
Loading…
Add table
Reference in a new issue