diff --git a/channeldb/graph.go b/channeldb/graph.go index d1bb85b17..cd746adc7 100644 --- a/channeldb/graph.go +++ b/channeldb/graph.go @@ -405,9 +405,12 @@ func (c *ChannelGraph) ForEachNodeChannel(tx kvdb.RTx, node route.Vertex, dbCallback := func(tx kvdb.RTx, e *ChannelEdgeInfo, p1, p2 *ChannelEdgePolicy) error { - cachedInPolicy := NewCachedPolicy(p2) - cachedInPolicy.ToNodePubKey = toNodeCallback - cachedInPolicy.ToNodeFeatures = toNodeFeatures + var cachedInPolicy *CachedEdgePolicy + if p2 != nil { + cachedInPolicy = NewCachedPolicy(p2) + cachedInPolicy.ToNodePubKey = toNodeCallback + cachedInPolicy.ToNodeFeatures = toNodeFeatures + } directedChannel := &DirectedChannel{ ChannelID: e.ChannelID, diff --git a/channeldb/graph_cache_test.go b/channeldb/graph_cache_test.go index 09cfbf237..f8d2b9a5f 100644 --- a/channeldb/graph_cache_test.go +++ b/channeldb/graph_cache_test.go @@ -60,6 +60,8 @@ func (n *node) ForEachChannel(tx kvdb.RTx, // TestGraphCacheAddNode tests that a channel going from node A to node B can be // cached correctly, independent of the direction we add the channel as. func TestGraphCacheAddNode(t *testing.T) { + t.Parallel() + runTest := func(nodeA, nodeB route.Vertex) { t.Helper() diff --git a/channeldb/graph_test.go b/channeldb/graph_test.go index f66b57958..eb81026c1 100644 --- a/channeldb/graph_test.go +++ b/channeldb/graph_test.go @@ -3692,3 +3692,43 @@ func BenchmarkForEachChannel(b *testing.B) { require.NoError(b, err) } } + +// TestGraphCacheForEachNodeChannel tests that the ForEachNodeChannel method +// works as expected, and is able to handle nil self edges. +func TestGraphCacheForEachNodeChannel(t *testing.T) { + graph, cleanUp, err := MakeTestGraph() + defer cleanUp() + require.NoError(t, err) + + // Unset the channel graph cache to simulate the user running with the + // option turned off. + graph.graphCache = nil + + node1, err := createTestVertex(graph.db) + require.Nil(t, err) + err = graph.AddLightningNode(node1) + require.Nil(t, err) + node2, err := createTestVertex(graph.db) + require.Nil(t, err) + err = graph.AddLightningNode(node2) + require.Nil(t, err) + + // Create an edge and add it to the db. + edgeInfo, _, _ := createChannelEdge(graph.db, node1, node2) + + // Add the channel, but only insert a single edge into the graph. + require.NoError(t, graph.AddChannelEdge(edgeInfo)) + + // We should be able to accumulate the single channel added, even + // though we have a nil edge policy here. + var numChans int + err = graph.ForEachNodeChannel(nil, node1.PubKeyBytes, + func(channel *DirectedChannel) error { + + numChans++ + return nil + }) + require.NoError(t, err) + + require.Equal(t, numChans, 1) +} diff --git a/docs/release-notes/release-notes-0.14.0.md b/docs/release-notes/release-notes-0.14.0.md index df7992ced..583e31a46 100644 --- a/docs/release-notes/release-notes-0.14.0.md +++ b/docs/release-notes/release-notes-0.14.0.md @@ -595,6 +595,9 @@ messages directly. There is no routing/path finding involved. * [Don't print bucket names with special characters when compacting]( https://github.com/lightningnetwork/lnd/pull/5878) +* [Fix pathfinding crash when inbound policy is unknown]( + https://github.com/lightningnetwork/lnd/pull/5922) + ## Documentation The [code contribution guidelines have been updated to mention the new