6
6
"github.com/btcsuite/btcd/btcec/v2"
7
7
"github.com/btcsuite/btclog/v2"
8
8
"github.com/lightningnetwork/lnd/channeldb"
9
+ graphdb "github.com/lightningnetwork/lnd/graph/db"
9
10
"github.com/lightningnetwork/lnd/graph/db/models"
10
11
"github.com/lightningnetwork/lnd/lnutils"
11
12
"github.com/lightningnetwork/lnd/lnwire"
@@ -235,6 +236,17 @@ func newPaymentSession(p *LightningPayment, selfNode route.Vertex,
235
236
}, nil
236
237
}
237
238
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
+
238
250
// RequestRoute returns a route which is likely to be capable for successfully
239
251
// routing the specified HTLC payment to the target node. Initially the first
240
252
// set of paths returned from this method may encounter routing failure along
@@ -295,13 +307,8 @@ func (p *paymentSession) RequestRoute(maxAmt, feeLimit lnwire.MilliSatoshi,
295
307
maxAmt = * p .payment .MaxShardAmt
296
308
}
297
309
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 {
305
312
// We'll also obtain a set of bandwidthHints from the lower
306
313
// layer for each of our outbound channels. This will allow the
307
314
// path finding to skip any links that aren't active or just
@@ -310,19 +317,13 @@ func (p *paymentSession) RequestRoute(maxAmt, feeLimit lnwire.MilliSatoshi,
310
317
// attempt, because concurrent payments may change balances.
311
318
bandwidthHints , err := p .getBandwidthHints (graph )
312
319
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
320
321
}
321
322
322
323
p .log .Debugf ("pathfinding for amt=%v" , maxAmt )
323
324
324
325
// Find a route for the current amount.
325
- path , _ , err : = p .pathFinder (
326
+ path , _ , err = p .pathFinder (
326
327
& graphParams {
327
328
additionalEdges : p .additionalEdges ,
328
329
bandwidthHints : bandwidthHints ,
@@ -332,12 +333,42 @@ func (p *paymentSession) RequestRoute(maxAmt, feeLimit lnwire.MilliSatoshi,
332
333
p .selfNode , p .selfNode , p .payment .Target ,
333
334
maxAmt , p .payment .TimePref , finalHtlcExpiry ,
334
335
)
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
+ }
335
351
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 ()
339
369
}
340
370
371
+ // Otherwise, we'll switch on the path finding error.
341
372
switch {
342
373
case err == errNoPathFound :
343
374
// Don't split if this is a legacy payment without mpp
0 commit comments