From acb3240d3d07b8bca427f926d7ef0787b04d1783 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Tue, 3 Feb 2026 20:13:36 +0200 Subject: [PATCH] graph/db: version fetch chan infos Add a gossip version parameter to FetchChanInfos in the Store interface and both KV/SQL implementations. Update the graph builder caller and refactor related tests. --- graph/builder.go | 2 +- graph/db/graph.go | 17 +++++++++++--- graph/db/graph_test.go | 51 ++++++++++++++++++++---------------------- graph/db/interfaces.go | 3 ++- graph/db/kv_store.go | 8 ++++++- graph/db/sql_store.go | 10 +++++++-- 6 files changed, 56 insertions(+), 35 deletions(-) diff --git a/graph/builder.go b/graph/builder.go index 69e7555dd..5100066a3 100644 --- a/graph/builder.go +++ b/graph/builder.go @@ -581,7 +581,7 @@ func (b *Builder) pruneZombieChans() error { "ids chans: %v", err) } - disabledEdges, err := b.cfg.Graph.FetchChanInfos( + disabledEdges, err := b.v1Graph.FetchChanInfos( disabledChanIDs, ) if err != nil { diff --git a/graph/db/graph.go b/graph/db/graph.go index f96328693..283f7d536 100644 --- a/graph/db/graph.go +++ b/graph/db/graph.go @@ -349,7 +349,9 @@ func (c *ChannelGraph) MarkEdgeLive(chanID uint64) error { if c.graphCache != nil { // We need to add the channel back into our graph cache, // otherwise we won't use it for path finding. - infos, err := c.db.FetchChanInfos([]uint64{chanID}) + infos, err := c.db.FetchChanInfos( + lnwire.GossipVersion1, []uint64{chanID}, + ) if err != nil { return err } @@ -710,8 +712,10 @@ func (c *ChannelGraph) FilterChannelRange(startHeight, endHeight uint32, } // FetchChanInfos returns the set of channel edges for the passed channel IDs. -func (c *ChannelGraph) FetchChanInfos(chanIDs []uint64) ([]ChannelEdge, error) { - return c.db.FetchChanInfos(chanIDs) +func (c *ChannelGraph) FetchChanInfos(v lnwire.GossipVersion, + chanIDs []uint64) ([]ChannelEdge, error) { + + return c.db.FetchChanInfos(v, chanIDs) } // FetchChannelEdgesByOutpoint attempts to lookup directed edges by funding @@ -952,6 +956,13 @@ func (c *VersionedGraph) DisabledChannelIDs() ([]uint64, error) { return c.db.DisabledChannelIDs(c.v) } +// FetchChanInfos returns the set of channel edges for the passed channel IDs. +func (c *VersionedGraph) FetchChanInfos(chanIDs []uint64) ([]ChannelEdge, + error) { + + return c.db.FetchChanInfos(c.v, chanIDs) +} + // HighestChanID returns the "highest" known channel ID in the channel graph. func (c *VersionedGraph) HighestChanID(ctx context.Context) (uint64, error) { return c.db.HighestChanID(ctx, c.v) diff --git a/graph/db/graph_test.go b/graph/db/graph_test.go index 651648936..0398031a7 100644 --- a/graph/db/graph_test.go +++ b/graph/db/graph_test.go @@ -202,6 +202,10 @@ var versionedTests = []versionedTest{ name: "highest chan id", test: testHighestChanID, }, + { + name: "fetch chan infos", + test: testFetchChanInfos, + }, } // TestVersionedDBs runs various tests against both v1 and v2 versioned @@ -3868,22 +3872,18 @@ func TestFilterChannelRange(t *testing.T) { // TestFetchChanInfos tests that we're able to properly retrieve the full set // of ChannelEdge structs for a given set of short channel ID's. -func TestFetchChanInfos(t *testing.T) { +func testFetchChanInfos(t *testing.T, v lnwire.GossipVersion) { t.Parallel() ctx := t.Context() - graph := MakeTestGraph(t) + graph := NewVersionedGraph(MakeTestGraph(t), v) // We'll first populate our graph with two nodes. All channels created // below will be made between these two nodes. - node1 := createTestVertex(t, lnwire.GossipVersion1) - if err := graph.AddNode(ctx, node1); err != nil { - t.Fatalf("unable to add node: %v", err) - } - node2 := createTestVertex(t, lnwire.GossipVersion1) - if err := graph.AddNode(ctx, node2); err != nil { - t.Fatalf("unable to add node: %v", err) - } + node1 := createTestVertex(t, v) + require.NoError(t, graph.AddNode(ctx, node1)) + node2 := createTestVertex(t, v) + require.NoError(t, graph.AddNode(ctx, node2)) // We'll make 5 test channels, ensuring we keep track of which channel // ID corresponds to a particular ChannelEdge. @@ -3894,36 +3894,35 @@ func TestFetchChanInfos(t *testing.T) { edgeQuery := make([]uint64, 0, numChans) for i := 0; i < numChans; i++ { channel, chanID := createEdge( - lnwire.GossipVersion1, uint32(i*10), 0, 0, 0, - node1, node2, + v, uint32(i*10), 0, 0, 0, node1, node2, ) - if err := graph.AddChannelEdge(ctx, channel); err != nil { - t.Fatalf("unable to create channel edge: %v", err) - } + require.NoError(t, graph.AddChannelEdge(ctx, channel)) updateTime := endTime endTime = updateTime.Add(time.Second * 10) edge1 := newEdgePolicy( - lnwire.GossipVersion1, chanID.ToUint64(), + v, chanID.ToUint64(), updateTime.Unix(), true, ) + if v == lnwire.GossipVersion1 { + edge1.ChannelFlags = 0 + } edge1.ToNode = node2.PubKeyBytes edge1.SigBytes = testSig.Serialize() - if err := graph.UpdateEdgePolicy(ctx, edge1); err != nil { - t.Fatalf("unable to update edge: %v", err) - } + require.NoError(t, graph.UpdateEdgePolicy(ctx, edge1)) edge2 := newEdgePolicy( - lnwire.GossipVersion1, chanID.ToUint64(), + v, chanID.ToUint64(), updateTime.Unix(), false, ) + if v == lnwire.GossipVersion1 { + edge2.ChannelFlags = 1 + } edge2.ToNode = node1.PubKeyBytes edge2.SigBytes = testSig.Serialize() - if err := graph.UpdateEdgePolicy(ctx, edge2); err != nil { - t.Fatalf("unable to update edge: %v", err) - } + require.NoError(t, graph.UpdateEdgePolicy(ctx, edge2)) edges = append(edges, ChannelEdge{ Info: channel, @@ -3941,11 +3940,9 @@ func TestFetchChanInfos(t *testing.T) { // Add an another edge to the query that has been marked as a zombie // edge. The query should also skip this channel. zombieChan, zombieChanID := createEdge( - lnwire.GossipVersion1, 666, 0, 0, 0, node1, node2, + v, 666, 0, 0, 0, node1, node2, ) - if err := graph.AddChannelEdge(ctx, zombieChan); err != nil { - t.Fatalf("unable to create channel edge: %v", err) - } + require.NoError(t, graph.AddChannelEdge(ctx, zombieChan)) err := graph.DeleteChannelEdges(false, true, zombieChan.ChannelID) require.NoError(t, err, "unable to delete and mark edge zombie") edgeQuery = append(edgeQuery, zombieChanID.ToUint64()) diff --git a/graph/db/interfaces.go b/graph/db/interfaces.go index 752473e77..446644077 100644 --- a/graph/db/interfaces.go +++ b/graph/db/interfaces.go @@ -282,7 +282,8 @@ type Store interface { //nolint:interfacebloat // edges that exist at the time of the query. This can be used to // respond to peer queries that are seeking to fill in gaps in their // view of the channel graph. - FetchChanInfos(chanIDs []uint64) ([]ChannelEdge, error) + FetchChanInfos(v lnwire.GossipVersion, + chanIDs []uint64) ([]ChannelEdge, error) // FetchChannelEdgesByOutpoint attempts to lookup the two directed edges // for the channel identified by the funding outpoint. If the channel diff --git a/graph/db/kv_store.go b/graph/db/kv_store.go index 2d3fdf81f..de9ff401e 100644 --- a/graph/db/kv_store.go +++ b/graph/db/kv_store.go @@ -2960,7 +2960,13 @@ func (c *KVStore) FilterChannelRange(startHeight, // skipped and the result will contain only those edges that exist at the time // of the query. This can be used to respond to peer queries that are seeking to // fill in gaps in their view of the channel graph. -func (c *KVStore) FetchChanInfos(chanIDs []uint64) ([]ChannelEdge, error) { +func (c *KVStore) FetchChanInfos(v lnwire.GossipVersion, + chanIDs []uint64) ([]ChannelEdge, error) { + + if v != lnwire.GossipVersion1 { + return nil, ErrVersionNotSupportedForKVDB + } + return c.fetchChanInfos(nil, chanIDs) } diff --git a/graph/db/sql_store.go b/graph/db/sql_store.go index 9bfb85182..2841b9666 100644 --- a/graph/db/sql_store.go +++ b/graph/db/sql_store.go @@ -2599,12 +2599,18 @@ func (s *SQLStore) IsPublicNode(v lnwire.GossipVersion, pubKey [33]byte) (bool, // fill in gaps in their view of the channel graph. // // NOTE: part of the Store interface. -func (s *SQLStore) FetchChanInfos(chanIDs []uint64) ([]ChannelEdge, error) { +func (s *SQLStore) FetchChanInfos(v lnwire.GossipVersion, + chanIDs []uint64) ([]ChannelEdge, error) { + var ( ctx = context.TODO() edges = make(map[uint64]ChannelEdge) ) err := s.db.ExecTx(ctx, sqldb.ReadTxOpt(), func(db SQLQueries) error { + if !isKnownGossipVersion(v) { + return fmt.Errorf("unsupported gossip version: %d", v) + } + // First, collect all channel rows. var channelRows []sqlc.GetChannelsBySCIDWithPoliciesRow chanCallBack := func(ctx context.Context, @@ -2615,7 +2621,7 @@ func (s *SQLStore) FetchChanInfos(chanIDs []uint64) ([]ChannelEdge, error) { } err := s.forEachChanWithPoliciesInSCIDList( - ctx, db, lnwire.GossipVersion1, chanCallBack, chanIDs, + ctx, db, v, chanCallBack, chanIDs, ) if err != nil { return err