diff --git a/graph/db/graph_test.go b/graph/db/graph_test.go index 026fedbdc..6984517e0 100644 --- a/graph/db/graph_test.go +++ b/graph/db/graph_test.go @@ -1861,7 +1861,7 @@ func TestGraphPruning(t *testing.T) { func TestHighestChanID(t *testing.T) { t.Parallel() - graph := MakeTestGraph(t) + graph := MakeTestGraphNew(t) // 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. diff --git a/graph/db/sql_store.go b/graph/db/sql_store.go index 83749c81c..1d296d2d2 100644 --- a/graph/db/sql_store.go +++ b/graph/db/sql_store.go @@ -75,6 +75,7 @@ type SQLQueries interface { */ CreateChannel(ctx context.Context, arg sqlc.CreateChannelParams) (int64, error) GetChannelBySCID(ctx context.Context, arg sqlc.GetChannelBySCIDParams) (sqlc.Channel, error) + HighestSCID(ctx context.Context, version int16) ([]byte, error) CreateChannelExtraType(ctx context.Context, arg sqlc.CreateChannelExtraTypeParams) error InsertChannelFeature(ctx context.Context, arg sqlc.InsertChannelFeatureParams) error @@ -512,6 +513,35 @@ func (s *SQLStore) AddChannelEdge(edge *models.ChannelEdgeInfo, return s.chanScheduler.Execute(ctx, r) } +// 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 their graphs are in sync. +// +// NOTE: This is part of the V1Store interface. +func (s *SQLStore) HighestChanID() (uint64, error) { + ctx := context.TODO() + + var highestChanID uint64 + err := s.db.ExecTx(ctx, sqldb.ReadTxOpt(), func(db SQLQueries) error { + chanID, err := db.HighestSCID(ctx, int16(ProtocolV1)) + if errors.Is(err, sql.ErrNoRows) { + return nil + } else if err != nil { + return fmt.Errorf("unable to fetch highest chan ID: %w", + err) + } + + highestChanID = byteOrder.Uint64(chanID) + + return nil + }, sqldb.NoOpReset) + if err != nil { + return 0, fmt.Errorf("unable to fetch highest chan ID: %w", err) + } + + return highestChanID, nil +} + // getNodeByPubKey attempts to look up a target node by its public key. func getNodeByPubKey(ctx context.Context, db SQLQueries, pubKey route.Vertex) (int64, *models.LightningNode, error) { diff --git a/sqldb/sqlc/graph.sql.go b/sqldb/sqlc/graph.sql.go index ec730818f..0823132a3 100644 --- a/sqldb/sqlc/graph.sql.go +++ b/sqldb/sqlc/graph.sql.go @@ -429,6 +429,21 @@ func (q *Queries) GetSourceNodesByVersion(ctx context.Context, version int16) ([ return items, nil } +const highestSCID = `-- name: HighestSCID :one +SELECT scid +FROM channels +WHERE version = $1 +ORDER BY scid DESC +LIMIT 1 +` + +func (q *Queries) HighestSCID(ctx context.Context, version int16) ([]byte, error) { + row := q.db.QueryRowContext(ctx, highestSCID, version) + var scid []byte + err := row.Scan(&scid) + return scid, err +} + const insertChannelFeature = `-- name: InsertChannelFeature :exec /* ───────────────────────────────────────────── channel_features table queries diff --git a/sqldb/sqlc/querier.go b/sqldb/sqlc/querier.go index e3482d524..b905dd4c8 100644 --- a/sqldb/sqlc/querier.go +++ b/sqldb/sqlc/querier.go @@ -46,6 +46,7 @@ type Querier interface { GetNodeFeaturesByPubKey(ctx context.Context, arg GetNodeFeaturesByPubKeyParams) ([]int32, error) GetNodesByLastUpdateRange(ctx context.Context, arg GetNodesByLastUpdateRangeParams) ([]Node, error) GetSourceNodesByVersion(ctx context.Context, version int16) ([]GetSourceNodesByVersionRow, error) + HighestSCID(ctx context.Context, version int16) ([]byte, error) InsertAMPSubInvoice(ctx context.Context, arg InsertAMPSubInvoiceParams) error InsertAMPSubInvoiceHTLC(ctx context.Context, arg InsertAMPSubInvoiceHTLCParams) error InsertChannelFeature(ctx context.Context, arg InsertChannelFeatureParams) error diff --git a/sqldb/sqlc/queries/graph.sql b/sqldb/sqlc/queries/graph.sql index b66aaaa75..dd96ac2f1 100644 --- a/sqldb/sqlc/queries/graph.sql +++ b/sqldb/sqlc/queries/graph.sql @@ -153,6 +153,13 @@ RETURNING id; SELECT * FROM channels WHERE scid = $1 AND version = $2; +-- name: HighestSCID :one +SELECT scid +FROM channels +WHERE version = $1 +ORDER BY scid DESC +LIMIT 1; + /* ───────────────────────────────────────────── channel_features table queries ─────────────────────────────────────────────