From a78ff8ba0492311e518211fce8d699eae3c872e7 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Thu, 30 Nov 2017 22:31:18 -0800 Subject: [PATCH] routing: during path finding skip edges that are marked disabled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In this commit, we implement adherence of the disabled bit within a ChannelUpdate during path finding. If a channel is marked as disabled, then we won’t attempt to route through it. A test has been added to exercise this new check. --- routing/pathfind.go | 8 ++++- routing/pathfind_test.go | 75 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/routing/pathfind.go b/routing/pathfind.go index c75aa299..e2209d5b 100644 --- a/routing/pathfind.go +++ b/routing/pathfind.go @@ -468,7 +468,13 @@ func findPath(tx *bolt.Tx, graph *channeldb.ChannelGraph, v := NewVertex(outEdge.Node.PubKey) - // TODO(roasbeef): skip if chan disabled + // If the outgoing edge is currently disabled, then + // we'll stop here, as we shouldn't attempt to route + // through it. + edgeFlags := lnwire.ChanUpdateFlag(outEdge.Flags) + if edgeFlags&lnwire.ChanUpdateDisabled == lnwire.ChanUpdateDisabled { + return nil + } // If this Vertex or edge has been black listed, then // we'll skip exploring this edge during this diff --git a/routing/pathfind_test.go b/routing/pathfind_test.go index a94c99fa..50793dba 100644 --- a/routing/pathfind_test.go +++ b/routing/pathfind_test.go @@ -624,6 +624,81 @@ func TestPathInsufficientCapacity(t *testing.T) { } } +// TestRouteFailMinHTLC tests that if we attempt to route an HTLC which is +// smaller than the advertised minHTLC of an edge, then path finding fails. +func TestRouteFailMinHTLC(t *testing.T) { + graph, cleanUp, aliases, err := parseTestGraph(basicGraphFilePath) + defer cleanUp() + if err != nil { + t.Fatalf("unable to create graph: %v", err) + } + + sourceNode, err := graph.SourceNode() + if err != nil { + t.Fatalf("unable to fetch source node: %v", err) + } + ignoredEdges := make(map[uint64]struct{}) + ignoredVertexes := make(map[Vertex]struct{}) + + // We'll not attempt to route an HTLC of 10 SAT from roasbeef to Son + // Goku. However, the min HTLC of Son Goku is 1k SAT, as a result, this + // attempt should fail. + target := aliases["songoku"] + payAmt := lnwire.MilliSatoshi(10) + _, err = findPath(nil, graph, sourceNode, target, ignoredVertexes, + ignoredEdges, payAmt) + if !IsError(err, ErrNoPathFound) { + t.Fatalf("graph shouldn't be able to support payment: %v", err) + } +} + +// TestRouteFailDisabledEdge tests that if we attempt to route to an edge +// that's disabled, then that edge is disqualified, and the routing attempt +// will fail. +func TestRouteFailDisabledEdge(t *testing.T) { + graph, cleanUp, aliases, err := parseTestGraph(basicGraphFilePath) + defer cleanUp() + if err != nil { + t.Fatalf("unable to create graph: %v", err) + } + + sourceNode, err := graph.SourceNode() + if err != nil { + t.Fatalf("unable to fetch source node: %v", err) + } + ignoredEdges := make(map[uint64]struct{}) + ignoredVertexes := make(map[Vertex]struct{}) + + // First, we'll try to route from roasbeef -> songoku. This should + // suceed without issue, and return a single path. + target := aliases["songoku"] + payAmt := lnwire.NewMSatFromSatoshis(10000) + _, err = findPath(nil, graph, sourceNode, target, ignoredVertexes, + ignoredEdges, payAmt) + if err != nil { + t.Fatalf("unable to find path: %v", err) + } + + // First, we'll modify the edge from roasbeef -> songoku, to read that + // it's disabled. + _, gokuEdge, _, err := graph.FetchChannelEdgesByID(12345) + if err != nil { + t.Fatalf("unable to fetch goku's edge: %v", err) + } + gokuEdge.Flags = lnwire.ChanUpdateDisabled + if err := graph.UpdateEdgePolicy(gokuEdge); err != nil { + t.Fatalf("unable to update edge: %v", err) + } + + // Now, if we attempt to route throuhg that edge, we should get a + // failure as it is no longer elligble. + _, err = findPath(nil, graph, sourceNode, target, ignoredVertexes, + ignoredEdges, payAmt) + if !IsError(err, ErrNoPathFound) { + t.Fatalf("graph shouldn't be able to support payment: %v", err) + } +} + func TestPathInsufficientCapacityWithFee(t *testing.T) { t.Parallel()