@@ -1227,24 +1227,46 @@ func findBlindedPaths(g Graph, target route.Vertex,
1227
1227
}
1228
1228
1229
1229
var (
1230
- // The target node is always the last hop in the path.
1231
- incomingPath = []blindedHop {{vertex : target }}
1232
- whiteListedNodes = map [route.Vertex ]bool {target : true }
1230
+ // The target node is always the last hop in the path, and so
1231
+ // we add it to the incoming path from the get-go. Any additions
1232
+ // to the slice should be prepended.
1233
+ incomingPath = []blindedHop {{
1234
+ vertex : target ,
1235
+ }}
1236
+
1237
+ // supportsRouteBlinding is a list of nodes that we can assume
1238
+ // support route blinding without needing to rely on the feature
1239
+ // bits announced in their node announcement. Since we are
1240
+ // finding a path to the target node, we can assume it supports
1241
+ // route blinding.
1242
+ supportsRouteBlinding = map [route.Vertex ]bool {
1243
+ target : true ,
1244
+ }
1245
+
1233
1246
visited = make (map [route.Vertex ]bool )
1234
- errChanFound = errors .New ("found incoming channel" )
1235
1247
nextTarget = target
1248
+ haveIncomingPath = len (restrictions .incomingChainedChannels ) > 0
1249
+
1250
+ // errChanFound is an error variable we return from the DB
1251
+ // iteration call below when we have found the channel we are
1252
+ // looking for. This lets us exit the iteration early.
1253
+ errChanFound = errors .New ("found incoming channel" )
1236
1254
)
1237
1255
for _ , chanID := range restrictions .incomingChainedChannels {
1256
+ // Mark that we have visited this node so that we don't revisit
1257
+ // it later on when we call "processNodeForBlindedPath".
1238
1258
visited [nextTarget ] = true
1239
1259
1240
1260
err := g .ForEachNodeDirectedChannel (nextTarget ,
1241
1261
func (channel * graphdb.DirectedChannel ) error {
1242
- // Not the right channel, continue to the node's
1243
- // other channels.
1262
+ // This is not the right channel, continue to
1263
+ // the node's other channels.
1244
1264
if channel .ChannelID != chanID {
1245
1265
return nil
1246
1266
}
1247
1267
1268
+ // We found the channel in question. Prepend it
1269
+ // to the incoming path.
1248
1270
incomingPath = append ([]blindedHop {
1249
1271
{
1250
1272
vertex : channel .OtherNode ,
@@ -1259,39 +1281,37 @@ func findBlindedPaths(g Graph, target route.Vertex,
1259
1281
return errChanFound
1260
1282
},
1261
1283
)
1262
- if err == nil {
1284
+ // We expect errChanFound to be returned if the channel in
1285
+ // question was found.
1286
+ if ! errors .Is (err , errChanFound ) && err != nil {
1287
+ return nil , err
1288
+ } else if err == nil {
1263
1289
return nil , fmt .Errorf ("incoming channel %d is not " +
1264
1290
"seen as owned by node %v" , chanID , nextTarget )
1265
1291
}
1266
- if ! errors .Is (err , errChanFound ) {
1267
- return nil , err
1268
- }
1269
1292
1270
1293
// Check that the user didn't accidentally add a channel that
1271
- // is owned by a node in the node omission set
1294
+ // is owned by a node in the node omission set.
1272
1295
if restrictions .nodeOmissionSet .Contains (nextTarget ) {
1273
1296
return nil , fmt .Errorf ("node %v cannot simultaneously " +
1274
1297
"be included in the omission set and in the " +
1275
1298
"partially specified path" , nextTarget )
1276
1299
}
1277
1300
1278
- if whiteListedNodes [nextTarget ] {
1301
+ // Check that we have not already visited the next target node
1302
+ // since this would mean a circular incoming path.
1303
+ if visited [nextTarget ] {
1279
1304
return nil , fmt .Errorf ("a circular route cannot be " +
1280
1305
"specified for the incoming blinded path" )
1281
1306
}
1282
- whiteListedNodes [nextTarget ] = true
1307
+
1308
+ supportsRouteBlinding [nextTarget ] = true
1283
1309
}
1284
1310
1285
- // If the node is not the destination node, then it is required that the
1286
- // node advertise the route blinding feature-bit in order for it to be
1287
- // chosen as a node on the blinded path.
1288
- // We skip checking the target node, as accepting blinded payments
1289
- // (via invoice) doesn't imply support for routing them (via node
1290
- // announcement).
1291
- // We skip checking incomingChainedChannels nodes, as we might not yet
1292
- // have an updated node announcement for them.
1293
- supportsRouteBlinding := func (node route.Vertex ) (bool , error ) {
1294
- if whiteListedNodes [node ] {
1311
+ // A helper closure which checks if the node in question has advertised
1312
+ // that it supports route blinding.
1313
+ nodeSupportsRouteBlinding := func (node route.Vertex ) (bool , error ) {
1314
+ if supportsRouteBlinding [node ] {
1295
1315
return true , nil
1296
1316
}
1297
1317
@@ -1308,8 +1328,12 @@ func findBlindedPaths(g Graph, target route.Vertex,
1308
1328
// conditions such as: The maxHops number being reached or reaching
1309
1329
// a node that doesn't have any other edges - in that final case, the
1310
1330
// whole path should be ignored.
1331
+ //
1332
+ // NOTE: any paths returned will end at the "nextTarget" node meaning
1333
+ // that if we have a fixed list of incoming chained channels, then this
1334
+ // fixed list must be appended to any of the returned paths.
1311
1335
paths , _ , err := processNodeForBlindedPath (
1312
- g , nextTarget , supportsRouteBlinding , visited , restrictions ,
1336
+ g , nextTarget , nodeSupportsRouteBlinding , visited , restrictions ,
1313
1337
)
1314
1338
if err != nil {
1315
1339
return nil , err
@@ -1319,8 +1343,7 @@ func findBlindedPaths(g Graph, target route.Vertex,
1319
1343
1320
1344
// When there is no path to add, but incomingChainedChannels can be
1321
1345
// used.
1322
- lenChainedChannels := int8 (len (restrictions .incomingChainedChannels ))
1323
- if len (paths ) == 0 && lenChainedChannels > 0 {
1346
+ if len (paths ) == 0 && haveIncomingPath {
1324
1347
orderedPaths = [][]blindedHop {incomingPath }
1325
1348
} else {
1326
1349
// Reverse each path so that the order is correct (from
@@ -1337,7 +1360,7 @@ func findBlindedPaths(g Graph, target route.Vertex,
1337
1360
1338
1361
// Handle the special case that allows a blinded path with the
1339
1362
// introduction node as the destination node.
1340
- if restrictions .minNumHops == 0 && lenChainedChannels == 0 {
1363
+ if restrictions .minNumHops == 0 && ! haveIncomingPath {
1341
1364
singleHopPath := [][]blindedHop {{{vertex : target }}}
1342
1365
1343
1366
//nolint:makezero
0 commit comments