Skip to content

Commit 9327940

Browse files
committed
routing: add pathfinding test
We add a test where we add duplicate hops in a route and verify that the pathfinding engine can handle this edge case.
1 parent 3cec72a commit 9327940

File tree

1 file changed

+104
-0
lines changed

1 file changed

+104
-0
lines changed

routing/pathfind_test.go

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,9 @@ func TestPathFinding(t *testing.T) {
765765
}, {
766766
name: "path finding with additional edges",
767767
fn: runPathFindingWithAdditionalEdges,
768+
}, {
769+
name: "path finding with duplicate blinded hop",
770+
fn: runPathFindingWithBlindedPathDuplicateHop,
768771
}, {
769772
name: "path finding with redundant additional edges",
770773
fn: runPathFindingWithRedundantAdditionalEdges,
@@ -1265,6 +1268,107 @@ func runPathFindingWithAdditionalEdges(t *testing.T, useCache bool) {
12651268
assertExpectedPath(t, graph.aliasMap, path, "songoku", "doge")
12661269
}
12671270

1271+
// runPathFindingWithBlindedPathDuplicateHop tests that in case a blinded path
1272+
// has duplicate hops that the path finding algorithm does not fail or behave
1273+
// incorrectly. This can happen because the creator of the blinded path can
1274+
// specify the same hop multiple times and this will only be detected at the
1275+
// forwarding nodes, so it is important that we can handle this case.
1276+
func runPathFindingWithBlindedPathDuplicateHop(t *testing.T, useCache bool) {
1277+
graph, err := parseTestGraph(t, useCache, basicGraphFilePath)
1278+
require.NoError(t, err, "unable to create graph")
1279+
1280+
sourceNode, err := graph.graph.SourceNode()
1281+
require.NoError(t, err, "unable to fetch source node")
1282+
1283+
paymentAmt := lnwire.NewMSatFromSatoshis(100)
1284+
1285+
songokuPubKeyBytes := graph.aliasMap["songoku"]
1286+
songokuPubKey, err := btcec.ParsePubKey(songokuPubKeyBytes[:])
1287+
require.NoError(t, err, "unable to parse public key from bytes")
1288+
1289+
_, pkb1 := btcec.PrivKeyFromBytes([]byte{2})
1290+
_, pkb2 := btcec.PrivKeyFromBytes([]byte{3})
1291+
_, blindedPoint := btcec.PrivKeyFromBytes([]byte{5})
1292+
1293+
sizeEncryptedData := 100
1294+
cipherText := bytes.Repeat(
1295+
[]byte{1}, sizeEncryptedData,
1296+
)
1297+
1298+
vb1 := route.NewVertex(pkb1)
1299+
vb2 := route.NewVertex(pkb2)
1300+
1301+
// Payments to blinded paths always pay to the NUMS target key.
1302+
dummyTarget := route.NewVertex(&BlindedPathNUMSKey)
1303+
1304+
graph.aliasMap["pkb1"] = vb1
1305+
graph.aliasMap["pkb2"] = vb2
1306+
graph.aliasMap["dummyTarget"] = dummyTarget
1307+
1308+
// Create a blinded payment with duplicate hops and make sure the
1309+
// path finding algorithm can cope with that. We add blinded hop 2
1310+
// 3 times. The path finding algorithm should create a path with a
1311+
// single hop to pkb2 (the first entry).
1312+
blindedPayment := &BlindedPayment{
1313+
BlindedPath: &sphinx.BlindedPath{
1314+
IntroductionPoint: songokuPubKey,
1315+
BlindingPoint: blindedPoint,
1316+
BlindedHops: []*sphinx.BlindedHopInfo{
1317+
{
1318+
CipherText: cipherText,
1319+
},
1320+
{
1321+
BlindedNodePub: pkb2,
1322+
CipherText: cipherText,
1323+
},
1324+
{
1325+
BlindedNodePub: pkb1,
1326+
CipherText: cipherText,
1327+
},
1328+
{
1329+
BlindedNodePub: pkb2,
1330+
CipherText: cipherText,
1331+
},
1332+
{
1333+
BlindedNodePub: &BlindedPathNUMSKey,
1334+
CipherText: cipherText,
1335+
},
1336+
{
1337+
BlindedNodePub: pkb2,
1338+
CipherText: cipherText,
1339+
},
1340+
},
1341+
},
1342+
HtlcMinimum: 1,
1343+
HtlcMaximum: 100_000_000,
1344+
CltvExpiryDelta: 140,
1345+
}
1346+
1347+
blindedPath, err := blindedPayment.toRouteHints()
1348+
require.NoError(t, err)
1349+
1350+
find := func(r *RestrictParams) (
1351+
[]*unifiedEdge, error) {
1352+
1353+
return dbFindPath(
1354+
graph.graph, blindedPath, &mockBandwidthHints{},
1355+
r, testPathFindingConfig,
1356+
sourceNode.PubKeyBytes, dummyTarget, paymentAmt,
1357+
0, 0,
1358+
)
1359+
}
1360+
1361+
// We should now be able to find a path however not the chained path
1362+
// of the blinded hops.
1363+
path, err := find(noRestrictions)
1364+
require.NoError(t, err, "unable to create route to blinded path")
1365+
1366+
// The path should represent the following hops:
1367+
// source node -> songoku -> pkb2 -> dummyTarget
1368+
assertExpectedPath(t, graph.aliasMap, path, "songoku", "pkb2",
1369+
"dummyTarget")
1370+
}
1371+
12681372
// runPathFindingWithRedundantAdditionalEdges asserts that we are able to find
12691373
// paths to nodes ignoring additional edges that are already known by self node.
12701374
func runPathFindingWithRedundantAdditionalEdges(t *testing.T, useCache bool) {

0 commit comments

Comments
 (0)