lnrpc+routing: add edges and nodes restrictions to query routes
This commit allows the execution of QueryRoutes to be controlled using lists of black-listed edges and nodes. Any path returned will not pass through the edges and/or nodes on the list.
This commit is contained in:
8 files changed
+757
-595
No files matched your search
+19
-10
@@ -790,7 +790,7 @@ func findPath(g *graphParams, r *RestrictParams,
|
||||
// algorithm in a block box manner.
|
||||
func findPaths(tx *bbolt.Tx, graph *channeldb.ChannelGraph,
|
||||
source *channeldb.LightningNode, target *btcec.PublicKey,
|
||||
amt lnwire.MilliSatoshi, feeLimit lnwire.MilliSatoshi, numPaths uint32,
|
||||
amt lnwire.MilliSatoshi, restrictions *RestrictParams, numPaths uint32,
|
||||
bandwidthHints map[uint64]lnwire.MilliSatoshi) ([][]*channeldb.ChannelEdgePolicy, error) {
|
||||
|
||||
// TODO(roasbeef): modifying ordering within heap to eliminate final
|
||||
@@ -809,10 +809,7 @@ func findPaths(tx *bbolt.Tx, graph *channeldb.ChannelGraph,
|
||||
graph: graph,
|
||||
bandwidthHints: bandwidthHints,
|
||||
},
|
||||
&RestrictParams{
|
||||
FeeLimit: feeLimit,
|
||||
},
|
||||
source, target, amt,
|
||||
restrictions, source, target, amt,
|
||||
)
|
||||
if err != nil {
|
||||
log.Errorf("Unable to find path: %v", err)
|
||||
@@ -846,6 +843,13 @@ func findPaths(tx *bbolt.Tx, graph *channeldb.ChannelGraph,
|
||||
ignoredEdges := make(map[EdgeLocator]struct{})
|
||||
ignoredVertexes := make(map[Vertex]struct{})
|
||||
|
||||
for e := range restrictions.IgnoredEdges {
|
||||
ignoredEdges[e] = struct{}{}
|
||||
}
|
||||
for n := range restrictions.IgnoredNodes {
|
||||
ignoredVertexes[n] = struct{}{}
|
||||
}
|
||||
|
||||
// Our spur node is the i-th node in the prior shortest
|
||||
// path, and our root path will be all nodes in the
|
||||
// path leading up to our spurNode.
|
||||
@@ -889,17 +893,22 @@ func findPaths(tx *bbolt.Tx, graph *channeldb.ChannelGraph,
|
||||
// TODO: Fee limit passed to spur path finding isn't
|
||||
// correct, because it doesn't take into account the
|
||||
// fees already paid on the root path.
|
||||
//
|
||||
// TODO: Outgoing channel restriction isn't obeyed for
|
||||
// spur paths.
|
||||
spurRestrictions := &RestrictParams{
|
||||
IgnoredEdges: ignoredEdges,
|
||||
IgnoredNodes: ignoredVertexes,
|
||||
FeeLimit: restrictions.FeeLimit,
|
||||
}
|
||||
|
||||
spurPath, err := findPath(
|
||||
&graphParams{
|
||||
tx: tx,
|
||||
graph: graph,
|
||||
bandwidthHints: bandwidthHints,
|
||||
},
|
||||
&RestrictParams{
|
||||
IgnoredNodes: ignoredVertexes,
|
||||
IgnoredEdges: ignoredEdges,
|
||||
FeeLimit: feeLimit,
|
||||
}, spurNode, target, amt,
|
||||
spurRestrictions, spurNode, target, amt,
|
||||
)
|
||||
|
||||
// If we weren't able to find a path, we'll continue to
|
||||
|
||||
@@ -47,6 +47,12 @@ const (
|
||||
noFeeLimit = lnwire.MilliSatoshi(math.MaxUint32)
|
||||
)
|
||||
|
||||
var (
|
||||
noRestrictions = &RestrictParams{
|
||||
FeeLimit: noFeeLimit,
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
testSig = &btcec.Signature{
|
||||
R: new(big.Int),
|
||||
@@ -953,9 +959,12 @@ func TestKShortestPathFinding(t *testing.T) {
|
||||
|
||||
paymentAmt := lnwire.NewMSatFromSatoshis(100)
|
||||
target := graph.aliasMap["luoji"]
|
||||
restrictions := &RestrictParams{
|
||||
FeeLimit: noFeeLimit,
|
||||
}
|
||||
paths, err := findPaths(
|
||||
nil, graph.graph, sourceNode, target, paymentAmt, noFeeLimit, 100,
|
||||
nil,
|
||||
nil, graph.graph, sourceNode, target, paymentAmt, restrictions,
|
||||
100, nil,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to find paths between roasbeef and "+
|
||||
@@ -1706,7 +1715,7 @@ func TestPathFindSpecExample(t *testing.T) {
|
||||
// Query for a route of 4,999,999 mSAT to carol.
|
||||
carol := ctx.aliases["C"]
|
||||
const amt lnwire.MilliSatoshi = 4999999
|
||||
routes, err := ctx.router.FindRoutes(carol, amt, noFeeLimit, 100)
|
||||
routes, err := ctx.router.FindRoutes(carol, amt, noRestrictions, 100)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to find route: %v", err)
|
||||
}
|
||||
@@ -1767,7 +1776,7 @@ func TestPathFindSpecExample(t *testing.T) {
|
||||
|
||||
// We'll now request a route from A -> B -> C.
|
||||
ctx.router.routeCache = make(map[routeTuple][]*Route)
|
||||
routes, err = ctx.router.FindRoutes(carol, amt, noFeeLimit, 100)
|
||||
routes, err = ctx.router.FindRoutes(carol, amt, noRestrictions, 100)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to find routes: %v", err)
|
||||
}
|
||||
|
||||
+3
-3
@@ -1326,7 +1326,7 @@ func pathsToFeeSortedRoutes(source Vertex, paths [][]*channeldb.ChannelEdgePolic
|
||||
// route that will be ranked the highest is the one with the lowest cumulative
|
||||
// fee along the route.
|
||||
func (r *ChannelRouter) FindRoutes(target *btcec.PublicKey,
|
||||
amt, feeLimit lnwire.MilliSatoshi, numPaths uint32,
|
||||
amt lnwire.MilliSatoshi, restrictions *RestrictParams, numPaths uint32,
|
||||
finalExpiry ...uint16) ([]*Route, error) {
|
||||
|
||||
var finalCLTVDelta uint16
|
||||
@@ -1396,8 +1396,8 @@ func (r *ChannelRouter) FindRoutes(target *btcec.PublicKey,
|
||||
// we'll execute our KSP algorithm to find the k-shortest paths from
|
||||
// our source to the destination.
|
||||
shortestPaths, err := findPaths(
|
||||
tx, r.cfg.Graph, r.selfNode, target, amt, feeLimit, numPaths,
|
||||
bandwidthHints,
|
||||
tx, r.cfg.Graph, r.selfNode, target, amt, restrictions,
|
||||
numPaths, bandwidthHints,
|
||||
)
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
|
||||
@@ -184,7 +184,7 @@ func TestFindRoutesFeeSorting(t *testing.T) {
|
||||
paymentAmt := lnwire.NewMSatFromSatoshis(100)
|
||||
target := ctx.aliases["luoji"]
|
||||
routes, err := ctx.router.FindRoutes(
|
||||
target, paymentAmt, noFeeLimit, defaultNumRoutes,
|
||||
target, paymentAmt, noRestrictions, defaultNumRoutes,
|
||||
DefaultFinalCLTVDelta,
|
||||
)
|
||||
if err != nil {
|
||||
@@ -240,10 +240,12 @@ func TestFindRoutesWithFeeLimit(t *testing.T) {
|
||||
// see the first route.
|
||||
target := ctx.aliases["sophon"]
|
||||
paymentAmt := lnwire.NewMSatFromSatoshis(100)
|
||||
feeLimit := lnwire.NewMSatFromSatoshis(10)
|
||||
restrictions := &RestrictParams{
|
||||
FeeLimit: lnwire.NewMSatFromSatoshis(10),
|
||||
}
|
||||
|
||||
routes, err := ctx.router.FindRoutes(
|
||||
target, paymentAmt, feeLimit, defaultNumRoutes,
|
||||
target, paymentAmt, restrictions, defaultNumRoutes,
|
||||
DefaultFinalCLTVDelta,
|
||||
)
|
||||
if err != nil {
|
||||
@@ -254,7 +256,7 @@ func TestFindRoutesWithFeeLimit(t *testing.T) {
|
||||
t.Fatalf("expected 1 route, got %d", len(routes))
|
||||
}
|
||||
|
||||
if routes[0].TotalFees > feeLimit {
|
||||
if routes[0].TotalFees > restrictions.FeeLimit {
|
||||
t.Fatalf("route exceeded fee limit: %v", spew.Sdump(routes[0]))
|
||||
}
|
||||
|
||||
@@ -1307,7 +1309,7 @@ func TestAddEdgeUnknownVertexes(t *testing.T) {
|
||||
paymentAmt := lnwire.NewMSatFromSatoshis(100)
|
||||
targetNode := priv2.PubKey()
|
||||
routes, err := ctx.router.FindRoutes(
|
||||
targetNode, paymentAmt, noFeeLimit, defaultNumRoutes,
|
||||
targetNode, paymentAmt, noRestrictions, defaultNumRoutes,
|
||||
DefaultFinalCLTVDelta,
|
||||
)
|
||||
if err != nil {
|
||||
@@ -1352,7 +1354,7 @@ func TestAddEdgeUnknownVertexes(t *testing.T) {
|
||||
// Should still be able to find the routes, and the info should be
|
||||
// updated.
|
||||
routes, err = ctx.router.FindRoutes(
|
||||
targetNode, paymentAmt, noFeeLimit, defaultNumRoutes,
|
||||
targetNode, paymentAmt, noRestrictions, defaultNumRoutes,
|
||||
DefaultFinalCLTVDelta,
|
||||
)
|
||||
if err != nil {
|
||||
|
||||
Reference in new issue
Block a user