From d88fa01162dc345bfe42bce03d3837bd962f20b4 Mon Sep 17 00:00:00 2001 From: Elle Mouton Date: Wed, 19 Nov 2025 18:28:20 +0200 Subject: [PATCH] graph/db: add version parameter to FetchChannelEdgesByID/Outpoint Make channel edge fetching version-aware by adding gossip version parameter to FetchChannelEdgesByID and FetchChannelEdgesByOutpoint. Add corresponding methods to VersionedGraph. V2 policy building is marked as TODO. --- graph/db/graph.go | 25 ++++++++++++++++++++++-- graph/db/interfaces.go | 4 ++-- graph/db/kv_store.go | 16 ++++++++++++---- graph/db/sql_store.go | 43 +++++++++++++++++++++++++++++++++++------- 4 files changed, 73 insertions(+), 15 deletions(-) diff --git a/graph/db/graph.go b/graph/db/graph.go index 6c4b0a150..0f4dda661 100644 --- a/graph/db/graph.go +++ b/graph/db/graph.go @@ -711,7 +711,9 @@ func (c *ChannelGraph) FetchChannelEdgesByOutpoint(op *wire.OutPoint) ( *models.ChannelEdgeInfo, *models.ChannelEdgePolicy, *models.ChannelEdgePolicy, error) { - return c.db.FetchChannelEdgesByOutpoint(op) + return c.db.FetchChannelEdgesByOutpoint( + lnwire.GossipVersion1, op, + ) } // FetchChannelEdgesByID attempts to lookup directed edges by channel ID. @@ -719,7 +721,9 @@ func (c *ChannelGraph) FetchChannelEdgesByID(chanID uint64) ( *models.ChannelEdgeInfo, *models.ChannelEdgePolicy, *models.ChannelEdgePolicy, error) { - return c.db.FetchChannelEdgesByID(chanID) + return c.db.FetchChannelEdgesByID( + lnwire.GossipVersion1, chanID, + ) } // ChannelView returns the verifiable edge information for each active channel. @@ -785,6 +789,23 @@ func (c *VersionedGraph) FetchNode(ctx context.Context, return c.db.FetchNode(ctx, c.v, nodePub) } +// FetchChannelEdgesByID attempts to lookup directed edges by channel ID. +func (c *VersionedGraph) FetchChannelEdgesByID(chanID uint64) ( + *models.ChannelEdgeInfo, *models.ChannelEdgePolicy, + *models.ChannelEdgePolicy, error) { + + return c.db.FetchChannelEdgesByID(c.v, chanID) +} + +// FetchChannelEdgesByOutpoint attempts to lookup directed edges by funding +// outpoint. +func (c *VersionedGraph) FetchChannelEdgesByOutpoint(op *wire.OutPoint) ( + *models.ChannelEdgeInfo, *models.ChannelEdgePolicy, + *models.ChannelEdgePolicy, error) { + + return c.db.FetchChannelEdgesByOutpoint(c.v, op) +} + // AddrsForNode returns all known addresses for the target node public key. func (c *VersionedGraph) AddrsForNode(ctx context.Context, nodePub *btcec.PublicKey) (bool, []net.Addr, error) { diff --git a/graph/db/interfaces.go b/graph/db/interfaces.go index 5658fa5c7..c6848132e 100644 --- a/graph/db/interfaces.go +++ b/graph/db/interfaces.go @@ -276,7 +276,7 @@ type Store interface { //nolint:interfacebloat // houses the general information for the channel itself is returned as // well as two structs that contain the routing policies for the channel // in either direction. - FetchChannelEdgesByOutpoint(op *wire.OutPoint) ( + FetchChannelEdgesByOutpoint(v lnwire.GossipVersion, op *wire.OutPoint) ( *models.ChannelEdgeInfo, *models.ChannelEdgePolicy, *models.ChannelEdgePolicy, error) @@ -291,7 +291,7 @@ type Store interface { //nolint:interfacebloat // zombie within the database. In this case, the ChannelEdgePolicy's // will be nil, and the ChannelEdgeInfo will only include the public // keys of each node. - FetchChannelEdgesByID(chanID uint64) ( + FetchChannelEdgesByID(v lnwire.GossipVersion, chanID uint64) ( *models.ChannelEdgeInfo, *models.ChannelEdgePolicy, *models.ChannelEdgePolicy, error) diff --git a/graph/db/kv_store.go b/graph/db/kv_store.go index b3442bde6..0887ff0d8 100644 --- a/graph/db/kv_store.go +++ b/graph/db/kv_store.go @@ -3811,8 +3811,8 @@ func computeEdgePolicyKeys(info *models.ChannelEdgeInfo) ([]byte, []byte) { // found, then ErrEdgeNotFound is returned. A struct which houses the general // information for the channel itself is returned as well as two structs that // contain the routing policies for the channel in either direction. -func (c *KVStore) FetchChannelEdgesByOutpoint(op *wire.OutPoint) ( - *models.ChannelEdgeInfo, *models.ChannelEdgePolicy, +func (c *KVStore) FetchChannelEdgesByOutpoint(v lnwire.GossipVersion, + op *wire.OutPoint) (*models.ChannelEdgeInfo, *models.ChannelEdgePolicy, *models.ChannelEdgePolicy, error) { var ( @@ -3821,6 +3821,10 @@ func (c *KVStore) FetchChannelEdgesByOutpoint(op *wire.OutPoint) ( policy2 *models.ChannelEdgePolicy ) + if v != lnwire.GossipVersion1 { + return nil, nil, nil, ErrVersionNotSupportedForKVDB + } + err := kvdb.View(c.db, func(tx kvdb.RTx) error { // First, grab the node bucket. This will be used to populate // the Node pointers in each edge read from disk. @@ -3897,10 +3901,14 @@ func (c *KVStore) FetchChannelEdgesByOutpoint(op *wire.OutPoint) ( // ErrZombieEdge an be returned if the edge is currently marked as a zombie // within the database. In this case, the ChannelEdgePolicy's will be nil, and // the ChannelEdgeInfo will only include the public keys of each node. -func (c *KVStore) FetchChannelEdgesByID(chanID uint64) ( - *models.ChannelEdgeInfo, *models.ChannelEdgePolicy, +func (c *KVStore) FetchChannelEdgesByID(v lnwire.GossipVersion, + chanID uint64) (*models.ChannelEdgeInfo, *models.ChannelEdgePolicy, *models.ChannelEdgePolicy, error) { + if v != lnwire.GossipVersion1 { + return nil, nil, nil, ErrVersionNotSupportedForKVDB + } + var ( edgeInfo *models.ChannelEdgeInfo policy1 *models.ChannelEdgePolicy diff --git a/graph/db/sql_store.go b/graph/db/sql_store.go index 2f0b1c56f..7cebedeef 100644 --- a/graph/db/sql_store.go +++ b/graph/db/sql_store.go @@ -2008,8 +2008,8 @@ func (s *SQLStore) DeleteChannelEdges(v lnwire.GossipVersion, // the ChannelEdgeInfo will only include the public keys of each node. // // NOTE: part of the Store interface. -func (s *SQLStore) FetchChannelEdgesByID(chanID uint64) ( - *models.ChannelEdgeInfo, *models.ChannelEdgePolicy, +func (s *SQLStore) FetchChannelEdgesByID(v lnwire.GossipVersion, + chanID uint64) (*models.ChannelEdgeInfo, *models.ChannelEdgePolicy, *models.ChannelEdgePolicy, error) { var ( @@ -2018,11 +2018,18 @@ func (s *SQLStore) FetchChannelEdgesByID(chanID uint64) ( policy1, policy2 *models.ChannelEdgePolicy chanIDB = channelIDToBytes(chanID) ) + + if !isKnownGossipVersion(v) { + return nil, nil, nil, fmt.Errorf( + "unsupported gossip version: %d", v, + ) + } + err := s.db.ExecTx(ctx, sqldb.ReadTxOpt(), func(db SQLQueries) error { row, err := db.GetChannelBySCIDWithPolicies( ctx, sqlc.GetChannelBySCIDWithPoliciesParams{ Scid: chanIDB, - Version: int16(lnwire.GossipVersion1), + Version: int16(v), }, ) if errors.Is(err, sql.ErrNoRows) { @@ -2031,7 +2038,7 @@ func (s *SQLStore) FetchChannelEdgesByID(chanID uint64) ( zombie, err := db.GetZombieChannel( ctx, sqlc.GetZombieChannelParams{ Scid: chanIDB, - Version: int16(lnwire.GossipVersion1), + Version: int16(v), }, ) if errors.Is(err, sql.ErrNoRows) { @@ -2118,8 +2125,8 @@ func (s *SQLStore) FetchChannelEdgesByID(chanID uint64) ( // contain the routing policies for the channel in either direction. // // NOTE: part of the Store interface. -func (s *SQLStore) FetchChannelEdgesByOutpoint(op *wire.OutPoint) ( - *models.ChannelEdgeInfo, *models.ChannelEdgePolicy, +func (s *SQLStore) FetchChannelEdgesByOutpoint(v lnwire.GossipVersion, + op *wire.OutPoint) (*models.ChannelEdgeInfo, *models.ChannelEdgePolicy, *models.ChannelEdgePolicy, error) { var ( @@ -2127,11 +2134,18 @@ func (s *SQLStore) FetchChannelEdgesByOutpoint(op *wire.OutPoint) ( edge *models.ChannelEdgeInfo policy1, policy2 *models.ChannelEdgePolicy ) + + if !isKnownGossipVersion(v) { + return nil, nil, nil, fmt.Errorf( + "unsupported gossip version: %d", v, + ) + } + err := s.db.ExecTx(ctx, sqldb.ReadTxOpt(), func(db SQLQueries) error { row, err := db.GetChannelByOutpointWithPolicies( ctx, sqlc.GetChannelByOutpointWithPoliciesParams{ Outpoint: op.String(), - Version: int16(lnwire.GossipVersion1), + Version: int16(v), }, ) if errors.Is(err, sql.ErrNoRows) { @@ -4662,6 +4676,21 @@ func getAndBuildChanPolicies(ctx context.Context, cfg *sqldb.QueryConfig, return nil, nil, nil } + // TODO(elle): update to support v2 policies. + if dbPol1 != nil && + lnwire.GossipVersion(dbPol1.Version) != lnwire.GossipVersion1 { + + return nil, nil, fmt.Errorf("unsupported policy1 version: %d", + dbPol1.Version) + } + + if dbPol2 != nil && + lnwire.GossipVersion(dbPol2.Version) != lnwire.GossipVersion1 { + + return nil, nil, fmt.Errorf("unsupported policy2 version: %d", + dbPol2.Version) + } + var policyIDs = make([]int64, 0, 2) if dbPol1 != nil { policyIDs = append(policyIDs, dbPol1.ID)