mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-03-04 09:48:19 +01:00
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:
parent
b6199f27da
commit
c6c56173a8
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
|
// TODO(roasbeef): make member, add caching
|
||||||
// * add k-path
|
// * add k-path
|
||||||
func findRoute(graph *channeldb.ChannelGraph, target *btcec.PublicKey,
|
func findRoute(graph *channeldb.ChannelGraph, sourceNode *channeldb.LightningNode,
|
||||||
amt btcutil.Amount) (*Route, error) {
|
target *btcec.PublicKey, amt btcutil.Amount) (*Route, error) {
|
||||||
|
|
||||||
|
|
||||||
// First we'll initilaze an empty heap which'll help us to quickly
|
// 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
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Next we obtain the source node from the graph, and initialize it
|
// To start, we add the source of our path finding attempt to the
|
||||||
// with a distance of 0. This indicates our starting point in the graph
|
// distance map with with a distance of 0. This indicates our starting
|
||||||
// traversal.
|
// point in the graph traversal.
|
||||||
sourceNode, err := graph.SourceNode()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
sourceVertex := newVertex(sourceNode.PubKey)
|
sourceVertex := newVertex(sourceNode.PubKey)
|
||||||
distance[sourceVertex] = nodeWithDist{
|
distance[sourceVertex] = nodeWithDist{
|
||||||
dist: 0,
|
dist: 0,
|
||||||
node: sourceNode,
|
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.
|
||||||
heap.Push(&nodeHeap, distance[sourceVertex])
|
heap.Push(&nodeHeap, distance[sourceVertex])
|
||||||
|
|
||||||
|
|
|
@ -288,6 +288,11 @@ func TestBasicGraphPathFinding(t *testing.T) {
|
||||||
t.Fatalf("unable to create graph: %v", err)
|
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
|
// With the test graph loaded, we'll test some basic path finding using
|
||||||
// the pre-generated graph. Consult the testdata/basic_graph.json file
|
// the pre-generated graph. Consult the testdata/basic_graph.json file
|
||||||
// to follow along with the assumptions we'll use to test the path
|
// 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)
|
const paymentAmt = btcutil.Amount(100)
|
||||||
target := aliases["sophon"]
|
target := aliases["sophon"]
|
||||||
route, err := findRoute(graph, target, paymentAmt)
|
route, err := findRoute(graph, sourceNode, target, paymentAmt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to find route: %v", err)
|
t.Fatalf("unable to find route: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -319,8 +324,6 @@ func TestBasicGraphPathFinding(t *testing.T) {
|
||||||
route.Hops[0].Channel.Node.Alias)
|
route.Hops[0].Channel.Node.Alias)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WE shoul
|
|
||||||
|
|
||||||
// The second hop should be from goku to sophon.
|
// The second hop should be from goku to sophon.
|
||||||
if !route.Hops[1].Channel.Node.PubKey.IsEqual(aliases["sophon"]) {
|
if !route.Hops[1].Channel.Node.PubKey.IsEqual(aliases["sophon"]) {
|
||||||
t.Fatalf("second hop should be sophon, is instead: %v",
|
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
|
// exist two possible paths in the graph, but the shorter (1 hop) path
|
||||||
// should be selected.
|
// should be selected.
|
||||||
target = aliases["luoji"]
|
target = aliases["luoji"]
|
||||||
route, err = findRoute(graph, target, paymentAmt)
|
route, err = findRoute(graph, sourceNode, target, paymentAmt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to find route: %v", err)
|
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)
|
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)
|
const paymentAmt = btcutil.Amount(100)
|
||||||
|
|
||||||
// We start by confirminig that routing a payment 20 hops away is possible.
|
// We start by confirminig that routing a payment 20 hops away is possible.
|
||||||
// Alice should be able to find a valid route to ursula.
|
// Alice should be able to find a valid route to ursula.
|
||||||
target := aliases["ursula"]
|
target := aliases["ursula"]
|
||||||
route, err := findRoute(graph, target, paymentAmt)
|
route, err := findRoute(graph, sourceNode, target, paymentAmt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("path should have been found")
|
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
|
// Vincent is 21 hops away from Alice, and thus no valid route should be
|
||||||
// presented to Alice.
|
// presented to Alice.
|
||||||
target = aliases["vincent"]
|
target = aliases["vincent"]
|
||||||
route, err = findRoute(graph, target, paymentAmt)
|
route, err = findRoute(graph, sourceNode, target, paymentAmt)
|
||||||
if err == nil {
|
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)
|
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
|
// With the test graph loaded, we'll test that queries for target that
|
||||||
// are either unreachable within the graph, or unknown result in an
|
// are either unreachable within the graph, or unknown result in an
|
||||||
// error.
|
// error.
|
||||||
|
@ -407,7 +422,8 @@ func TestPathNotAvailable(t *testing.T) {
|
||||||
t.Fatalf("unable to parse pubkey: %v", err)
|
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)
|
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)
|
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
|
// Next, test that attempting to find a path in which the current
|
||||||
// channel graph cannot support due to insufficient capacity triggers
|
// channel graph cannot support due to insufficient capacity triggers
|
||||||
// an error.
|
// an error.
|
||||||
|
@ -430,7 +451,7 @@ func TestPathInsufficientCapacity(t *testing.T) {
|
||||||
target := aliases["sophon"]
|
target := aliases["sophon"]
|
||||||
|
|
||||||
const payAmt = btcutil.SatoshiPerBitcoin
|
const payAmt = btcutil.SatoshiPerBitcoin
|
||||||
_, err = findRoute(graph, target, payAmt)
|
_, err = findRoute(graph, sourceNode, target, payAmt)
|
||||||
if err != ErrNoPathFound {
|
if err != ErrNoPathFound {
|
||||||
t.Fatalf("graph shouldn't be able to support payment: %v", err)
|
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
|
// 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 {
|
if err != nil {
|
||||||
log.Errorf("Unable to find path: %v", err)
|
log.Errorf("Unable to find path: %v", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
Loading…
Add table
Reference in a new issue