From c6c56173a892f4bec4cb8809bf1b9dfc14653f24 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Sun, 19 Mar 2017 14:32:52 -0700 Subject: [PATCH] routing: modify findRoute to accept starting node as a paramter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit slightly modified findRoute to accept the node which should be used as the starting point in our path finding algorithm. With this change, as we move to a k-shortest paths algorithm this modification will be needed as all of our path finding attempts won’t always originate from a the same starting point. --- routing/pathfind.go | 16 ++++++---------- routing/pathfind_test.go | 39 ++++++++++++++++++++++++++++++--------- routing/router.go | 2 +- 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/routing/pathfind.go b/routing/pathfind.go index 7775e9b0..a39487b2 100644 --- a/routing/pathfind.go +++ b/routing/pathfind.go @@ -238,8 +238,8 @@ func edgeWeight(e *channeldb.ChannelEdgePolicy) float64 { // // TODO(roasbeef): make member, add caching // * add k-path -func findRoute(graph *channeldb.ChannelGraph, target *btcec.PublicKey, - amt btcutil.Amount) (*Route, error) { +func findRoute(graph *channeldb.ChannelGraph, sourceNode *channeldb.LightningNode, + target *btcec.PublicKey, amt btcutil.Amount) (*Route, error) { // First we'll initilaze an empty heap which'll help us to quickly @@ -263,20 +263,16 @@ func findRoute(graph *channeldb.ChannelGraph, target *btcec.PublicKey, return nil, err } - // Next we obtain the source node from the graph, and initialize it - // with a distance of 0. This indicates our starting point in the graph - // traversal. - sourceNode, err := graph.SourceNode() - if err != nil { - return nil, err - } + // To start, we add the source of our path finding attempt to the + // distance map with with a distance of 0. This indicates our starting + // point in the graph traversal. sourceVertex := newVertex(sourceNode.PubKey) distance[sourceVertex] = nodeWithDist{ dist: 0, node: sourceNode, } - // To start, our source node will hte the sole item within our distance + // To start, our source node will the sole item within our distance // heap. heap.Push(&nodeHeap, distance[sourceVertex]) diff --git a/routing/pathfind_test.go b/routing/pathfind_test.go index cccd6a58..0af60729 100644 --- a/routing/pathfind_test.go +++ b/routing/pathfind_test.go @@ -288,6 +288,11 @@ func TestBasicGraphPathFinding(t *testing.T) { t.Fatalf("unable to create graph: %v", err) } + sourceNode, err := graph.SourceNode() + if err != nil { + t.Fatalf("unable to fetch source node: %v", err) + } + // With the test graph loaded, we'll test some basic path finding using // the pre-generated graph. Consult the testdata/basic_graph.json file // to follow along with the assumptions we'll use to test the path @@ -295,7 +300,7 @@ func TestBasicGraphPathFinding(t *testing.T) { const paymentAmt = btcutil.Amount(100) target := aliases["sophon"] - route, err := findRoute(graph, target, paymentAmt) + route, err := findRoute(graph, sourceNode, target, paymentAmt) if err != nil { t.Fatalf("unable to find route: %v", err) } @@ -319,8 +324,6 @@ func TestBasicGraphPathFinding(t *testing.T) { route.Hops[0].Channel.Node.Alias) } - // WE shoul - // The second hop should be from goku to sophon. if !route.Hops[1].Channel.Node.PubKey.IsEqual(aliases["sophon"]) { t.Fatalf("second hop should be sophon, is instead: %v", @@ -331,7 +334,7 @@ func TestBasicGraphPathFinding(t *testing.T) { // exist two possible paths in the graph, but the shorter (1 hop) path // should be selected. target = aliases["luoji"] - route, err = findRoute(graph, target, paymentAmt) + route, err = findRoute(graph, sourceNode, target, paymentAmt) if err != nil { t.Fatalf("unable to find route: %v", err) } @@ -367,12 +370,17 @@ func TestNewRoutePathTooLong(t *testing.T) { t.Fatalf("unable to create graph: %v", err) } + sourceNode, err := graph.SourceNode() + if err != nil { + t.Fatalf("unable to fetch source node: %v", err) + } + const paymentAmt = btcutil.Amount(100) // We start by confirminig that routing a payment 20 hops away is possible. // Alice should be able to find a valid route to ursula. target := aliases["ursula"] - route, err := findRoute(graph, target, paymentAmt) + route, err := findRoute(graph, sourceNode, target, paymentAmt) if err != nil { t.Fatalf("path should have been found") } @@ -380,9 +388,11 @@ func TestNewRoutePathTooLong(t *testing.T) { // Vincent is 21 hops away from Alice, and thus no valid route should be // presented to Alice. target = aliases["vincent"] - route, err = findRoute(graph, target, paymentAmt) + route, err = findRoute(graph, sourceNode, target, paymentAmt) if err == nil { - t.Fatalf("should not have been able to find path, supposed to be "+"greater than 20 hops, found route with %v hops", len(route.Hops)) + t.Fatalf("should not have been able to find path, supposed to be "+ + "greater than 20 hops, found route with %v hops", + len(route.Hops)) } } @@ -394,6 +404,11 @@ func TestPathNotAvailable(t *testing.T) { t.Fatalf("unable to create graph: %v", err) } + sourceNode, err := graph.SourceNode() + if err != nil { + t.Fatalf("unable to fetch source node: %v", err) + } + // With the test graph loaded, we'll test that queries for target that // are either unreachable within the graph, or unknown result in an // error. @@ -407,7 +422,8 @@ func TestPathNotAvailable(t *testing.T) { t.Fatalf("unable to parse pubkey: %v", err) } - if _, err := findRoute(graph, unknownNode, 100); err != ErrNoPathFound { + _, err = findRoute(graph, sourceNode, unknownNode, 100) + if err != ErrNoPathFound { t.Fatalf("path shouldn't have been found: %v", err) } } @@ -419,6 +435,11 @@ func TestPathInsufficientCapacity(t *testing.T) { t.Fatalf("unable to create graph: %v", err) } + sourceNode, err := graph.SourceNode() + if err != nil { + t.Fatalf("unable to fetch source node: %v", err) + } + // Next, test that attempting to find a path in which the current // channel graph cannot support due to insufficient capacity triggers // an error. @@ -430,7 +451,7 @@ func TestPathInsufficientCapacity(t *testing.T) { target := aliases["sophon"] const payAmt = btcutil.SatoshiPerBitcoin - _, err = findRoute(graph, target, payAmt) + _, err = findRoute(graph, sourceNode, target, payAmt) if err != ErrNoPathFound { t.Fatalf("graph shouldn't be able to support payment: %v", err) } diff --git a/routing/router.go b/routing/router.go index 8c086cbf..4c820aed 100644 --- a/routing/router.go +++ b/routing/router.go @@ -1068,7 +1068,7 @@ func (r *ChannelRouter) FindRoute(target *btcec.PublicKey, amt btcutil.Amount) ( } // TODO(roasbeef): add k-shortest paths - route, err := findRoute(r.cfg.Graph, target, amt) + route, err := findRoute(r.cfg.Graph, r.selfNode, target, amt) if err != nil { log.Errorf("Unable to find path: %v", err) return nil, err