routing/pathfind: pass ignore disable flags for local channels

To decouple our own path finding from the graph state, we don't consider
the disable bit when attempting to use local channels. Instead the
bandwidth hints will be zero for local inactive channels.

We alos modify the unit test to check that the disable flag is ignored
for local edges.
This commit is contained in:
Johan T. Halseth 2018-10-26 11:41:55 -07:00
parent 20b9d5d000
commit 0b6a19866b
No known key found for this signature in database
GPG key ID: 15BAADA29DA20D26
2 changed files with 57 additions and 13 deletions

View file

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

View file

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