What changed, and why it matters
This commit is a routine code refactoring. It adds a 'gossip version' parameter to a function called FetchChanInfos so the graph database can handle both old (v1) and new (v2) Lightning network gossip formats consistently. It also updates callers and tests. There is no indication this fixes a security bug or introduces a vulnerability.
No security action required. Review as normal code-quality/API-consistency change.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change threads lnwire.GossipVersion through the Store.FetchChanInfos interface and both KVStore and SQLStore implementations. KVStore rejects non-v1 versions with ErrVersionNotSupportedForKVDB; SQLStore validates the version and passes it to the existing forEachChanWithPoliciesInSCIDList helper. A VersionedGraph wrapper already bound to a version is introduced as the caller in graph/builder.go, and tests are parameterized to run against both gossip versions.
Changed components
graph/db/interfaces.gograph/db/kv_store.gograph/db/sql_store.gograph/db/graph.gograph/builder.gograph/db/graph_test.goInspect captured patch +56 / −35
diff --git a/graph/builder.go b/graph/builder.go
index 69e7555..5100066 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 f963286..283f7d5 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 6516489..0398031 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 752473e..4466440 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 2d3fdf8..de9ff40 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 9bfb851..2841b96 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
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.