diff --git a/routing/pathfind.go b/routing/pathfind.go index fa9778ae..a1910292 100644 --- a/routing/pathfind.go +++ b/routing/pathfind.go @@ -462,7 +462,11 @@ type graphParams struct { // bandwidthHints is an optional map from channels to bandwidths that // can be populated if the caller has a better estimate of the current - // channel bandwidth than what is found in the graph. + // channel bandwidth than what is found in the graph. If set, it will + // override the capacities and disabled flags found in the graph for + // local channels when doing path finding. In particular, it should be + // set to the current available sending bandwidth for active local + // channels, and 0 for inactive channels. bandwidthHints map[uint64]lnwire.MilliSatoshi } @@ -585,10 +589,15 @@ func findPath(g *graphParams, r *restrictParams, fromVertex := Vertex(fromNode.PubKeyBytes) - // If the edge is currently disabled, then we'll stop here, as - // we shouldn't attempt to route through it. + // If this is not a local channel and it is disabled, we will + // skip it. + // TODO(halseth): also ignore disable flags for non-local + // channels if bandwidth hint is set? + isSourceChan := fromVertex == sourceVertex edgeFlags := lnwire.ChanUpdateFlag(edge.Flags) - if edgeFlags&lnwire.ChanUpdateDisabled != 0 { + isDisabled := edgeFlags&lnwire.ChanUpdateDisabled != 0 + + if !isSourceChan && isDisabled { return } diff --git a/routing/pathfind_test.go b/routing/pathfind_test.go index c535a4ee..0948e0fa 100644 --- a/routing/pathfind_test.go +++ b/routing/pathfind_test.go @@ -1451,7 +1451,9 @@ func TestRouteFailMinHTLC(t *testing.T) { // 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. +// will fail. We also test that this is true only for non-local edges, as we'll +// ignore the disable flags, with the assumption that the correct bandwidth is +// found among the bandwidth hints. func TestRouteFailDisabledEdge(t *testing.T) { t.Parallel() @@ -1487,19 +1489,52 @@ func TestRouteFailDisabledEdge(t *testing.T) { t.Fatalf("unable to find path: %v", err) } - // First, we'll modify the edge from roasbeef -> phamnuwen, to read that - // it's disabled. - _, _, phamnuwenEdge, err := graph.graph.FetchChannelEdgesByID(999991) + // Disable the edge roasbeef->phamnuwen. This should not impact the + // path finding, as we don't consider the disable flag for local + // channels (and roasbeef is the source). + roasToPham := uint64(999991) + _, e1, e2, err := graph.graph.FetchChannelEdgesByID(roasToPham) if err != nil { - t.Fatalf("unable to fetch goku's edge: %v", err) + t.Fatalf("unable to fetch edge: %v", err) } - phamnuwenEdge.Flags = lnwire.ChanUpdateDisabled | lnwire.ChanUpdateDirection - if err := graph.graph.UpdateEdgePolicy(phamnuwenEdge); err != nil { + e1.Flags |= lnwire.ChanUpdateDisabled + if err := graph.graph.UpdateEdgePolicy(e1); err != nil { + t.Fatalf("unable to update edge: %v", err) + } + e2.Flags |= lnwire.ChanUpdateDisabled + if err := graph.graph.UpdateEdgePolicy(e2); err != nil { t.Fatalf("unable to update edge: %v", err) } - // Now, if we attempt to route through that edge, we should get a - // failure as it is no longer eligible. + _, err = findPath( + &graphParams{ + graph: graph.graph, + }, + &restrictParams{ + ignoredNodes: ignoredVertexes, + ignoredEdges: ignoredEdges, + feeLimit: noFeeLimit, + }, + sourceNode, target, payAmt, + ) + if err != nil { + t.Fatalf("unable to find path: %v", err) + } + + // Now, we'll modify the edge from phamnuwen -> sophon, to read that + // it's disabled. + phamToSophon := uint64(99999) + _, e, _, err := graph.graph.FetchChannelEdgesByID(phamToSophon) + if err != nil { + t.Fatalf("unable to fetch edge: %v", err) + } + e.Flags |= lnwire.ChanUpdateDisabled + if err := graph.graph.UpdateEdgePolicy(e); err != nil { + t.Fatalf("unable to update edge: %v", err) + } + + // If we attempt to route through that edge, we should get a failure as + // it is no longer eligible. _, err = findPath( &graphParams{ graph: graph.graph,