Skip to content

graph/db: v2 model and store support#10657

Open
ellemouton wants to merge 16 commits intolightningnetwork:elle-g175-graph-db-cross-versionfrom
ellemouton:g175-graph-db-models
Open

graph/db: v2 model and store support#10657
ellemouton wants to merge 16 commits intolightningnetwork:elle-g175-graph-db-cross-versionfrom
ellemouton:g175-graph-db-models

Conversation

@ellemouton
Copy link
Copy Markdown
Collaborator

@ellemouton ellemouton commented Mar 23, 2026

Summary

Complete the graph database's v2 gossip support by adding wire conversion
helpers, versioned graph wrappers, SQL queries for v2 node traversal, and
v3-only onion address filtering.

Depends on: #10656 (graph/db: cross-version graph Store)

Part of the Gossip 1.75 epic.

Key changes

  • Node model generalization: NodeFromWireAnnouncement now accepts the
    lnwire.NodeAnnouncement interface (v1 and v2). Add NodeAnnouncement()
    for version-appropriate wire round-tripping, NodeTimestamp() for
    version-aware ordering, and ToNodeAnnouncement() for full serialization
    back to wire format including v2 address helpers.

  • Channel model helpers: ChannelAuthProofFromWireAnnouncement,
    ChannelAuthProofFromAnnounceSignatures,
    ChannelEdgeInfoFromWireAnnouncement, and
    ChannelEdgePolicyFromWireUpdate for constructing internal models from
    versioned wire messages.

  • VersionedGraph zombie wrappers: MarkEdgeZombie and MarkEdgeLive
    convenience methods that supply the gossip version from the embedded field.

  • SQL v2 node traversal: Add ListChannelsForNodeV2,
    GetV2NodesByPubKeys, ListChannelsWithPoliciesForCachePaginatedV2, and
    ListChannelsPaginatedV2 queries for version-aware node traversal.

  • V3-only onion addresses: Filter out non-v3 onion addresses for v2
    gossip, since the v2 protocol only supports v3 onion services.

Add version-aware range types for channel and node update horizon
queries. V1 gossip uses unix timestamps for ordering while v2 uses
block heights, so each range type validates that the correct bound
type is provided for the requested gossip version.

These types will be used in follow-up commits to version the
NodeUpdatesInHorizon and ChanUpdatesInHorizon Store methods.
Replace the (startTime, endTime time.Time) parameters on
NodeUpdatesInHorizon and ChanUpdatesInHorizon with
(v GossipVersion, r NodeUpdateRange/ChanUpdateRange). The range
types enforce version-correct bounds at the type level: v1 uses unix
timestamps, v2 uses block heights.

The KV store rejects non-v1 versions since it only stores v1 data.
The SQL store handles v1 queries; v2 block-height range queries are
added in the following commits.

VersionedGraph wrappers supply the version from the embedded field,
so callers only pass the range.
Add GetNodesByBlockHeightRange and GetChannelsByPolicyBlockRange
SQL queries for v2 gossip horizon lookups which use block heights
instead of unix timestamps. Hardcode version=1 in
GetNodesByLastUpdateRange and GetChannelsByPolicyLastUpdateRange
since only v1 gossip uses unix-timestamp-based ordering.

Implement the v2 gossip cases in the SQL store's
NodeUpdatesInHorizon and ChanUpdatesInHorizon using the new queries,
replacing the placeholder TODO stubs. Add extractMaxBlockHeight
helper for v2 channel pagination cursor tracking.

Also add a TestV2HorizonQueries integration test that exercises both
node and channel horizon lookups with block-height ranges on the SQL
backend.
Add a gossip version parameter to FilterKnownChanIDs on the Store
interface so that it can filter channel IDs for the correct gossip
version. The KV store rejects non-v1 versions.

Move the zombie-revival logic from ChannelGraph into VersionedGraph
so that FilterKnownChanIDs is only exposed on VersionedGraph (which
supplies the version from its embedded field). This means callers
no longer need to pass a version explicitly.
Add four new Store interface methods:

- FetchChannelEdgesByIDPreferHighest: version-agnostic channel lookup
  that returns the highest available gossip version.
- FetchChannelEdgesByOutpointPreferHighest: same but keyed by outpoint.
- GetVersionsBySCID: returns which gossip versions exist for a SCID.
- GetVersionsByOutpoint: same but keyed by outpoint.

The KV store implementations delegate to v1 since that's the only
version it supports. The SQL store implementations iterate over
versions from highest to lowest (for PreferHighest) or lowest to
highest (for GetVersions).

These will be used in follow-up commits to make ChannelGraph callers
version-agnostic.
Remove the gossip version parameter from ForEachNode and
ForEachChannel on the Store interface. Both methods now iterate
across all gossip versions, yielding each unique node/channel
exactly once. A versionsMask (uint32) is passed to the callback
where bit 0 indicates a v1 entry exists and bit 1 indicates v2.

The KV store always passes versionsMask=1 since it only stores v1
data. The SQL store collects entries across both versions, deduping
by pub key (nodes) or channel ID (channels), preferring the highest
version's data when both exist.

VersionedGraph wrappers discard the versionsMask so that existing
callers through that type don't need to change their callbacks.
…rappers

Switch FetchChannelEdgesByID and FetchChannelEdgesByOutpoint on
ChannelGraph to use the PreferHighest store variants so that callers
get the highest available gossip version without needing to specify
one.

Also add GetVersionsBySCID and GetVersionsByOutpoint convenience
wrappers on ChannelGraph that delegate to the corresponding Store
methods.
Update ForEachNodeDirectedChannel and FetchNodeFeatures on
ChannelGraph to iterate across all gossip versions (highest first)
instead of hardcoding v1. This ensures that channels announced via
v2 are preferred over v1 and that v2 features are used when
available.
@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly advances the graph database's support for gossip v2 by integrating new wire conversion utilities, enhancing versioned graph wrappers, and introducing specialized SQL queries for efficient v2 node traversal. These changes ensure better compatibility and handling of versioned gossip messages, laying crucial groundwork for the upcoming Gossip 1.75 epic.

Highlights

  • Node Model Generalization: The NodeFromWireAnnouncement function now accepts both v1 and v2 lnwire.NodeAnnouncement interfaces. New methods NodeAnnouncement(), NodeTimestamp(), and ToNodeAnnouncement() were added for version-appropriate wire round-tripping and version-aware ordering.
  • Channel Model Helpers: New helper functions ChannelAuthProofFromWireAnnouncement, ChannelAuthProofFromAnnounceSignatures, ChannelEdgeInfoFromWireAnnouncement, and ChannelEdgePolicyFromWireUpdate were introduced to construct internal models from versioned wire messages.
  • VersionedGraph Zombie Wrappers: Convenience methods MarkEdgeZombie and MarkEdgeLive were added to VersionedGraph, which automatically supply the correct gossip version from the embedded field when marking channel edges as zombie or live.
  • SQL V2 Node Traversal: New SQL queries such as ListChannelsForNodeV2, GetV2NodesByPubKeys, ListChannelsWithPoliciesForCachePaginatedV2, and ListChannelsPaginatedV2 were added to enable version-aware node traversal within the graph database.
  • V3-Only Onion Address Filtering: The system now filters out non-v3 onion addresses for v2 gossip, enforcing that the v2 protocol only supports v3 onion services.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@ellemouton ellemouton force-pushed the g175-graph-db-models branch from e610b68 to 170379c Compare March 23, 2026 16:44
@saubyk saubyk added this to v0.21 Mar 23, 2026
@saubyk saubyk moved this to In progress in v0.21 Mar 23, 2026
@saubyk saubyk removed this from v0.21 Mar 23, 2026
@saubyk saubyk added this to the v0.22.0 milestone Mar 23, 2026
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces comprehensive support for Gossip V2 within the graph database. It includes new models and conversion helpers for node announcements, channel authentication proofs, edge information, and edge policies. The database layer has been updated with new SQL queries to support versioned graph traversal, prioritizing Gossip V2 data where available. Existing code has been refactored to use new helper methods for improved abstraction and consistency across gossip versions. A review comment highlighted an inconsistency in SQL alias naming for policy fields, suggesting a change from policy_2_ to policy2_ for better consistency.

Comment on lines +1208 to +1209
cp2.message_flags AS policy_2_message_flags,
cp2.channel_flags AS policy_2_channel_flags,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The aliases for policy 2 fields (policy_2_message_flags, policy_2_channel_flags) use an underscore between 'policy' and '2'. This is inconsistent with some other queries in this file (e.g., GetChannelsByIDs uses policy2_message_flags) and also with the aliases for policy 1 in this same query (policy1_...).

For consistency, it would be better to use policy2_... for all policy 2 aliases.

This also applies to the GetChannelByOutpointPreferHighestVersionWithPolicies query on lines 1264-1265.

    cp2.message_flags AS policy2_message_flags,
    cp2.channel_flags AS policy2_channel_flags,

Update NodeFromWireAnnouncement to accept the lnwire.NodeAnnouncement
interface instead of only *NodeAnnouncement1, and return an error for
unsupported types. Add a NodeAnnouncement() method that returns the
version-appropriate wire message from a Node model.

Also add NodeTimestamp() which returns the version-appropriate
ordering timestamp (unix time for v1, block height for v2).
Add ChannelAuthProofFromWireAnnouncement and
ChannelAuthProofFromAnnounceSignatures for constructing auth proofs
from wire messages. Add ChannelEdgeInfoFromWireAnnouncement for
building a ChannelEdgeInfo from a ChannelAnnouncement interface.

Also add ChannelEdgePolicyFromWireUpdate for constructing a
ChannelEdgePolicy from a ChannelUpdate interface, and update the
KV and SQL stores to use the new ChannelEdgeInfo.ChanProofBytes()
accessor.
Add ToNodeAnnouncement which serializes a Node model back to its
version-appropriate lnwire.NodeAnnouncement wire message. This
enables round-tripping between the internal model and wire format.

Also add V2NodeAddrs/SetV2NodeAddrs helpers for extracting and
setting the typed address fields on v2 node announcements, and
comprehensive tests for node wire round-tripping.
Add MarkEdgeZombie and MarkEdgeLive convenience methods to
VersionedGraph that supply the gossip version from the embedded
field, matching the pattern used by other VersionedGraph wrappers.
Add SQL queries for version-aware node traversal used by the
sqlNodeTraverser: ListChannelsForNodeV2, GetV2NodesByPubKeys,
ListChannelsWithPoliciesForCachePaginatedV2, and
ListChannelsPaginatedV2.

Update the KV store's ForEachNodeDirectedChannel to return
ErrVersionNotSupportedForKVDB for non-v1 instead of silently
returning no results.
Filter out non-v3 onion addresses when setting v2 node addresses,
since v2 gossip only supports v3 onion addresses. Also update the
SQL store to handle v2 node address filtering during persistence
and retrieval.
@ellemouton ellemouton force-pushed the g175-graph-db-models branch from 170379c to c718ee9 Compare March 23, 2026 17:43
@ellemouton ellemouton force-pushed the elle-g175-graph-db-cross-version branch from fe7a97b to d455707 Compare March 27, 2026 09:53
@saubyk saubyk added this to lnd v0.22 Mar 30, 2026
@github-project-automation github-project-automation bot moved this to Backlog in lnd v0.22 Mar 30, 2026
@saubyk saubyk moved this from Backlog to In progress in lnd v0.22 Mar 30, 2026
@lightninglabs-deploy
Copy link
Copy Markdown
Collaborator

@ellemouton, remember to re-request review from reviewers when ready

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In progress

Development

Successfully merging this pull request may close these issues.

3 participants