routing: modify findRoute to accept starting node as a paramter

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.
This commit is contained in:
Olaoluwa Osuntokun 2017-03-19 14:32:52 -07:00
parent b6199f27da
commit c6c56173a8
No known key found for this signature in database
GPG Key ID: 9CC5B105D03521A2
3 changed files with 37 additions and 20 deletions

@ -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])

@ -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)
}

@ -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