diff --git a/discovery/chan_series.go b/discovery/chan_series.go index 9ba9607e9..ed64453a4 100644 --- a/discovery/chan_series.go +++ b/discovery/chan_series.go @@ -73,12 +73,12 @@ type ChannelGraphTimeSeries interface { // in-protocol channel range queries to quickly and efficiently synchronize our // channel state with all peers. type ChanSeries struct { - graph *graphdb.ChannelGraph + graph *graphdb.VersionedGraph } // NewChanSeries constructs a new ChanSeries backed by a channeldb.ChannelGraph. // The returned ChanSeries implements the ChannelGraphTimeSeries interface. -func NewChanSeries(graph *graphdb.ChannelGraph) *ChanSeries { +func NewChanSeries(graph *graphdb.VersionedGraph) *ChanSeries { return &ChanSeries{ graph: graph, } diff --git a/graph/db/graph.go b/graph/db/graph.go index 4579f1635..f96328693 100644 --- a/graph/db/graph.go +++ b/graph/db/graph.go @@ -688,8 +688,10 @@ func (c *ChannelGraph) AddEdgeProof(chanID lnwire.ShortChannelID, } // HighestChanID returns the "highest" known channel ID in the channel graph. -func (c *ChannelGraph) HighestChanID(ctx context.Context) (uint64, error) { - return c.db.HighestChanID(ctx) +func (c *ChannelGraph) HighestChanID(ctx context.Context, + v lnwire.GossipVersion) (uint64, error) { + + return c.db.HighestChanID(ctx, v) } // ChanUpdatesInHorizon returns all known channel edges with updates in the @@ -950,6 +952,11 @@ func (c *VersionedGraph) DisabledChannelIDs() ([]uint64, error) { return c.db.DisabledChannelIDs(c.v) } +// 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) +} + // ChannelID attempts to lookup the 8-byte compact channel ID. func (c *VersionedGraph) ChannelID(chanPoint *wire.OutPoint) (uint64, error) { return c.db.ChannelID(c.v, chanPoint) diff --git a/graph/db/graph_test.go b/graph/db/graph_test.go index d56c42d07..651648936 100644 --- a/graph/db/graph_test.go +++ b/graph/db/graph_test.go @@ -198,6 +198,10 @@ var versionedTests = []versionedTest{ name: "graph cache for each node channel", test: testGraphCacheForEachNodeChannel, }, + { + name: "highest chan id", + test: testHighestChanID, + }, } // TestVersionedDBs runs various tests against both v1 and v2 versioned @@ -2484,41 +2488,32 @@ func TestGraphPruning(t *testing.T) { // TestHighestChanID tests that we're able to properly retrieve the highest // known channel ID in the database. -func TestHighestChanID(t *testing.T) { +func testHighestChanID(t *testing.T, v lnwire.GossipVersion) { t.Parallel() ctx := t.Context() - graph := MakeTestGraph(t) + graph := NewVersionedGraph(MakeTestGraph(t), v) // If we don't yet have any channels in the database, then we should // get a channel ID of zero if we ask for the highest channel ID. bestID, err := graph.HighestChanID(ctx) require.NoError(t, err, "unable to get highest ID") if bestID != 0 { - t.Fatalf("best ID w/ no chan should be zero, is instead: %v", - bestID) + require.Equal(t, uint64(0), bestID) } // Next, we'll insert two channels into the database, with each channel // connecting the same two nodes. - node1 := createTestVertex(t, lnwire.GossipVersion1) - node2 := createTestVertex(t, lnwire.GossipVersion1) + node1 := createTestVertex(t, v) + node2 := createTestVertex(t, v) // The first channel with be at height 10, while the other will be at // height 100. - edge1, _ := createEdge( - lnwire.GossipVersion1, 10, 0, 0, 0, node1, node2, - ) - edge2, chanID2 := createEdge( - lnwire.GossipVersion1, 100, 0, 0, 0, node1, node2, - ) + edge1, _ := createEdge(v, 10, 0, 0, 0, node1, node2) + edge2, chanID2 := createEdge(v, 100, 0, 0, 0, node1, node2) - if err := graph.AddChannelEdge(ctx, edge1); err != nil { - t.Fatalf("unable to create channel edge: %v", err) - } - if err := graph.AddChannelEdge(ctx, edge2); err != nil { - t.Fatalf("unable to create channel edge: %v", err) - } + require.NoError(t, graph.AddChannelEdge(ctx, edge1)) + require.NoError(t, graph.AddChannelEdge(ctx, edge2)) // Now that the edges has been inserted, we'll query for the highest // known channel ID in the database. @@ -2526,25 +2521,17 @@ func TestHighestChanID(t *testing.T) { require.NoError(t, err, "unable to get highest ID") if bestID != chanID2.ToUint64() { - t.Fatalf("expected %v got %v for best chan ID: ", - chanID2.ToUint64(), bestID) + require.Equal(t, chanID2.ToUint64(), bestID) } // If we add another edge, then the current best chan ID should be // updated as well. - edge3, chanID3 := createEdge( - lnwire.GossipVersion1, 1000, 0, 0, 0, node1, node2, - ) - if err := graph.AddChannelEdge(ctx, edge3); err != nil { - t.Fatalf("unable to create channel edge: %v", err) - } + edge3, chanID3 := createEdge(v, 1000, 0, 0, 0, node1, node2) + require.NoError(t, graph.AddChannelEdge(ctx, edge3)) bestID, err = graph.HighestChanID(ctx) require.NoError(t, err, "unable to get highest ID") - if bestID != chanID3.ToUint64() { - t.Fatalf("expected %v got %v for best chan ID: ", - chanID3.ToUint64(), bestID) - } + require.Equal(t, chanID3.ToUint64(), bestID) } // TestChanUpdatesInHorizon tests the we're able to properly retrieve all known @@ -5210,6 +5197,7 @@ func BenchmarkForEachChannel(b *testing.B) { // method works as expected, and is able to handle nil self edges. func testGraphCacheForEachNodeChannel(t *testing.T, v lnwire.GossipVersion) { + t.Parallel() ctx := t.Context() diff --git a/graph/db/interfaces.go b/graph/db/interfaces.go index 9613ff62c..752473e77 100644 --- a/graph/db/interfaces.go +++ b/graph/db/interfaces.go @@ -246,7 +246,8 @@ type Store interface { //nolint:interfacebloat // graph. This represents the "newest" channel from the PoV of the // chain. This method can be used by peers to quickly determine if // they're graphs are in sync. - HighestChanID(ctx context.Context) (uint64, error) + HighestChanID(ctx context.Context, v lnwire.GossipVersion) ( + uint64, error) // ChanUpdatesInHorizon returns all the known channel edges which have // at least one edge that has an update timestamp within the specified diff --git a/graph/db/kv_store.go b/graph/db/kv_store.go index d61713ac0..2d3fdf81f 100644 --- a/graph/db/kv_store.go +++ b/graph/db/kv_store.go @@ -2056,7 +2056,13 @@ func getChanID(tx kvdb.RTx, chanPoint *wire.OutPoint) (uint64, error) { // HighestChanID returns the "highest" known channel ID in the channel graph. // This represents the "newest" channel from the PoV of the chain. This method // can be used by peers to quickly determine if they're graphs are in sync. -func (c *KVStore) HighestChanID(_ context.Context) (uint64, error) { +func (c *KVStore) HighestChanID(_ context.Context, + v lnwire.GossipVersion) (uint64, error) { + + if v != lnwire.GossipVersion1 { + return 0, ErrVersionNotSupportedForKVDB + } + var cid uint64 err := kvdb.View(c.db, func(tx kvdb.RTx) error { diff --git a/graph/db/sql_store.go b/graph/db/sql_store.go index 4c64e2e58..9bfb85182 100644 --- a/graph/db/sql_store.go +++ b/graph/db/sql_store.go @@ -786,10 +786,16 @@ func (s *SQLStore) AddChannelEdge(ctx context.Context, // can be used by peers to quickly determine if their graphs are in sync. // // NOTE: This is part of the Store interface. -func (s *SQLStore) HighestChanID(ctx context.Context) (uint64, error) { +func (s *SQLStore) HighestChanID(ctx context.Context, + v lnwire.GossipVersion) (uint64, error) { + var highestChanID uint64 err := s.db.ExecTx(ctx, sqldb.ReadTxOpt(), func(db SQLQueries) error { - chanID, err := db.HighestSCID(ctx, int16(lnwire.GossipVersion1)) + if !isKnownGossipVersion(v) { + return fmt.Errorf("unsupported gossip version: %d", v) + } + + chanID, err := db.HighestSCID(ctx, int16(v)) if errors.Is(err, sql.ErrNoRows) { return nil } else if err != nil { diff --git a/server.go b/server.go index a91d266c0..91b662463 100644 --- a/server.go +++ b/server.go @@ -1042,7 +1042,9 @@ func newServer(ctx context.Context, cfg *Config, listenAddrs []net.Addr, return nil, fmt.Errorf("can't create router: %w", err) } - chanSeries := discovery.NewChanSeries(s.graphDB) + chanSeries := discovery.NewChanSeries( + graphdb.NewVersionedGraph(s.graphDB, lnwire.GossipVersion1), + ) gossipMessageStore, err := discovery.NewMessageStore(dbs.ChanStateDB) if err != nil { return nil, err