routing/pathfind: set final hop features used in pathfinding
In this commit, we overwrite the final hop's features with either the destination features or those loaded from the graph fallback. This ensures that the same features used in pathfinding will be provided to route construction. In an earlier commit, we validated the final hop's transitive feature dependencies, so we also add validation to non-final nodes.
This commit is contained in:
parent
990d55d08c
commit
71e05e05bf
@ -644,6 +644,36 @@ func findPath(g *graphParams, r *RestrictParams, cfg *PathFindingConfig,
|
||||
edge.ChannelID)
|
||||
}
|
||||
|
||||
switch {
|
||||
|
||||
// If this edge takes us to the final hop, we'll set the node
|
||||
// features to those determined above. These are either taken
|
||||
// from the destination features, e.g. virtual or invoice
|
||||
// features, or loaded as a fallback from the graph. The
|
||||
// transitive dependencies were already validated above, so no
|
||||
// need to do so now.
|
||||
//
|
||||
// NOTE: This may overwrite features loaded from the graph if
|
||||
// destination features were provided. This is fine though,
|
||||
// since our route construction does not care where the features
|
||||
// are actually taken from. In the future we may wish to do
|
||||
// route construction within findPath, and avoid using
|
||||
// ChannelEdgePolicy altogether.
|
||||
case edge.Node.PubKeyBytes == target:
|
||||
edge.Node.Features = features
|
||||
|
||||
// Otherwise, this is some other intermediary node. Verify the
|
||||
// transitive feature dependencies for this node, and skip the
|
||||
// channel if they are invalid.
|
||||
default:
|
||||
err := feature.ValidateDeps(edge.Node.Features)
|
||||
if err != nil {
|
||||
log.Tracef("Node %x has invalid features",
|
||||
edge.Node.PubKeyBytes)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// All conditions are met and this new tentative distance is
|
||||
// better than the current best known distance to this node.
|
||||
// The new better distance is recorded, and also our "next hop"
|
||||
|
@ -1482,6 +1482,21 @@ func TestMissingFeatureDep(t *testing.T) {
|
||||
Features: payAddrFeatures,
|
||||
}, 0,
|
||||
),
|
||||
asymmetricTestChannel("conner", "joost", 100000,
|
||||
&testChannelPolicy{
|
||||
Expiry: 144,
|
||||
FeeRate: 400,
|
||||
MinHTLC: 1,
|
||||
MaxHTLC: 100000000,
|
||||
Features: payAddrFeatures,
|
||||
},
|
||||
&testChannelPolicy{
|
||||
Expiry: 144,
|
||||
FeeRate: 400,
|
||||
MinHTLC: 1,
|
||||
MaxHTLC: 100000000,
|
||||
}, 0,
|
||||
),
|
||||
}
|
||||
|
||||
ctx := newPathFindingTestContext(t, testChannels, "roasbeef")
|
||||
@ -1530,6 +1545,19 @@ func TestMissingFeatureDep(t *testing.T) {
|
||||
t.Fatalf("path should have been found: %v", err)
|
||||
}
|
||||
assertExpectedPath(t, ctx.testGraphInstance.aliasMap, path, "conner")
|
||||
|
||||
// Finally, try to find a route to joost through conner. The
|
||||
// destination features are set properly from the previous assertions,
|
||||
// but conner's feature vector in the graph is still broken. We expect
|
||||
// errNoPathFound and not the missing feature dep err above since
|
||||
// intermediate hops are simply skipped if they have invalid feature
|
||||
// vectors, leaving no possible route to joost.
|
||||
joost := ctx.testGraphInstance.aliasMap["joost"]
|
||||
|
||||
_, err = find(&restrictions, joost)
|
||||
if err != errNoPathFound {
|
||||
t.Fatalf("path shouldn't have been found: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// TestDestPaymentAddr asserts that we properly detect when we can send a
|
||||
|
Loading…
Reference in New Issue
Block a user