Add a gossip version parameter to FetchChanInfos in the Store interface
and both KV/SQL implementations. Update the graph builder caller and
refactor related tests.
Add a gossip version parameter to DisabledChannelIDs in the Store
interface and both implementations. Add a new version-filtered SQL
query and update the builder caller.
Update ForEachNodeChannel to accept a gossip version parameter,
allowing callers to specify which gossip version's channels should be
iterated. This change mirrors the approach taken in ForEachChannel and
prepares the graph database for supporting multiple gossip versions
while maintaining backward compatibility.
The Store interface is updated to include the version parameter, and
both KVStore and SQLStore implementations are updated accordingly:
- KVStore validates that only GossipVersion1 is requested, returning
ErrVersionNotSupportedForKVDB for other versions.
- SQLStore passes the version through to the underlying node query,
enabling version-specific channel iteration.
The ChannelGraph wrapper is updated to accept and pass through the
version parameter. VersionedGraph gains a ForEachNodeChannel method
that automatically uses its configured gossip version, providing a
clean interface for version-specific operations.
Update all call sites to explicitly pass lnwire.GossipVersion1, except
for the local channel manager in server.go which now uses the v1Graph
directly (matching the pattern used in other parts of the codebase).
Add a new HasChannelEdge method that takes a gossip version parameter
and returns only existence and zombie status, without timestamp data.
This supports both v1 and v2 gossip protocols.
The original HasChannelEdge method is renamed to HasV1ChannelEdge to
preserve v1-specific functionality for callers that need timestamp
information. All call sites are updated accordingly.
The SQL store implementation now handles both gossip versions, using
timestamps for v1 and block heights for v2 policies, with proper
reject cache support for both versions.
Add ChanEdgePolicyFromWire to construct ChannelEdgePolicy from channel
update messages, centralizing v1/v2 field mapping.
Update call sites to use the helper:
- discovery/gossiper: handleChanUpdate
- graph/builder: ApplyChannelUpdate
- routing/router_test: ApplyChannelUpdate test helper
This consolidates update-to-policy conversion logic across versions.
Extend ChannelEdgePolicy to support v2 channel updates by adding:
- Version field to track gossip protocol version (v1 or v2).
- LastBlockHeight for v2's block-height-based timestamps.
- SecondPeer flag to indicate which peer announced the policy in v2.
- DisableFlags for v2-specific channel disable signaling.
- ExtraSignedFields map for v2 extra signed TLV data.
Add version-aware methods:
- IsNode1() determines if the policy was announced by node_1, handling
both v1 (via ChannelFlags direction bit) and v2 (via SecondPeer).
- IsDisabled() checks disable status using ChannelFlags for v1 and
DisableFlags for v2.
- String() provides version-appropriate string representations.
The new fields use zero values for v1 compatibility (Version defaults
to GossipVersion1, LastBlockHeight to 0, SecondPeer to false). This
lays the groundwork for v2 policy support; a subsequent commit will
handle reading and writing these fields from/to the database.
Make IsPublicNode version-aware by routing to the appropriate SQL
query based on gossip version. V1 and v2 have different criteria for
determining node publicity (v1 requires four signatures, v2 requires
one). Convert TestNodeIsPublic to versioned test for both protocols.
Add version-aware DeleteChannelEdges method to VersionedGraph and
update call sites in graph builder, rpcserver, and server to use
versioned graphs. This ensures channel deletion operations are
properly scoped to the correct gossip version.
HasNode currently is very v1 specific since it returns a time.Time
timestamp which is specific to V1 node announcements. However, it is
mostly only used for the "exists" return value. So here we split it up
into HasNode which just checks existence and HasV1Node which retains the
same behavaiour as before.
In this commit, we refactor the ChanUpdatesInHorizon method to return
an iterator instead of a slice. This change significantly reduces
memory usage when dealing with large result sets by allowing callers to
process items incrementally rather than loading everything into memory
at once.
Replace all usages of the "github.com/go-errors/errors" and
"github.com/pkg/errors" packages with the standard lib's "errors"
package. This ensures that error wrapping and `errors.Is` checks will
work as expected.
Remove the previously added TODOs which would extract InboundFee info
from the ExtraOpaqueData of a ChannelUpdate at the time of
ChannelEdgePolicy construction. These can now be replaced by using the
newly added InboundFee record on the ChannelUpdate message.
In this commit, we make sure to set the new field wherever appropriate.
This will be any place where the ChannelEdgePolicy is constructed other
than its disk deserialisation.
Since we have not removed all call-sites that make use of this
parameter, we can remove it. This helps hide DB-specific details from
the interface we will introduce for the graph store.
We plan to later on add an option for a remote graph source which will
be managed from the ChannelGraph. In such a set-up, a node would rely on
the remote graph source for graph updates instead of from gossip sync.
In this scenario, however, our topology subscription logic should still
notify clients of all updates and so it makes more sense to have the
logic as part of the ChannelGraph so that we can send updates we receive
from the remote graph.
The exposed AddNode, AddEdge and UpdateEdge methods of the Builder are
currently synchronous since even though they pass messages to the
network handler which spins off the handling in a goroutine, the public
methods still wait for a response from the handling before returning.
The only part that is actually done asynchronously is the topology
notifications.
We previously tried to simplify things in [this
commit](https://github.com/lightningnetwork/lnd/pull/9476/commits/d757b3bcfc77b0fbb543ef5db800e6c6b058930f)
but we soon realised that there was a reason for sending the messages to
the central/synchronous network handler first: it was to ensure
consistency for topology clients: ie, the ordering between when there is
a new topology client or if it is cancelled needs to be consistent and
handled synchronously with new network updates. So for example, if a new
update comes in right after a topology client cancels its subscription,
then it should _not_ be notified. Similariy for new subscriptions. So
this commit was reverted soon after.
We can, however, still simplify things as is done in this commit by
noting that _only topology subscriptions and notifications_ need to be
handled separately. The actual network updates do not need to. So that
is what is done here.
This refactor will make moving the topology subscription logic to a new
subsystem later on much easier.
This commit restricts the graph CRUD interface such that one can only
add a proof to a channel announcement and not update any other fields.
This pattern is better suited for SQL land too.