Commit Graph
394 Commits
Author SHA1 Message Date
Abdullahi Yunus 86cde4b93f graphdb: add benchmark for isPublicNode query
In this commit we add a benchmark to test the performance of
IsPublicNode query.
2025-12-23 21:04:36 +01:00
ziggie 2d25bce1bf graphdb: fix potential sql tx exhaustion
We should avoid taking the lock of a mutex inside transaction.
Currently we also take this lock in other places and there is a
chance that in case the application lock aquires the lock but
all transactions are already blocked waiting for the mutex to
unlock, we end up in a deadlock.
2025-12-09 11:51:46 +01:00
Elle bc670fab82 Merge pull request #10396 from ziggie1984/enhance-lsp-heuritic
Enhance Lsp Heuristic when probing a payment
2025-12-09 10:43:43 +02:00
Elle Mouton 9f715555c4 graph/db: fix race in DisconnectBlockAtHeight cache access
The DisconnectBlockAtHeight method was modifying the rejectCache and
chanCache without holding the cacheMu lock. This caused races with
other operations that properly held the lock, such as AddChannelEdge
which modifies the caches in its OnCommit callback while the batch
scheduler holds cacheMu.

Fix by acquiring cacheMu before removing channels from the caches.
2025-12-08 11:56:36 +02:00
Elle Mouton 31b3e7424d graph/db/models: fix race conditions in ChannelEdgeInfo
Both NodeKey1 and NodeKey2 methods had the same race condition as the
Node.PubKey method, where concurrent calls could race to write to the
cached fields.

Remove the caching for the same reasons: parsing overhead is minimal
and doesn't justify the complexity and race risk.
2025-12-08 11:56:36 +02:00
Elle Mouton 9906e61774 graph/db/models: fix race condition in Node.PubKey
The PubKey method had a race condition where concurrent calls could
all pass the nil check and race to write to the cached pubKey field.
This is a classic check-then-act race.

Remove the caching entirely to fix the race. The overhead of parsing
a public key is minimal and doesn't justify the added complexity and
race risk of caching.
2025-12-08 11:56:35 +02:00
Elle Mouton c04aa655b9 graph/db: fix SetSourceNode race with lenient upsert
This commit fixes a race condition where multiple goroutines call
SetSourceNode concurrently during startup, causing sql.ErrNoRows
errors. The race occurs when multiple code paths (setSelfNode,
createNewHiddenService, RPC updates) read the same old timestamp,
independently increment it to the same new value (T+1), and race to
write.

The fix uses the new UpsertSourceNode SQL query (without strict
timestamp constraint) instead of UpsertNode. This allows
last-write-wins semantics for our own node, ensuring all parameter
changes persist even when timestamps collide.

Refactored sql_store.go for reusability:
- upsertNodeAncillaryData: common logic for features/addresses/extras
- populateNodeParams: common parameter building with callback pattern
- buildNodeUpsertParams: builds params for strict UpsertNode
- buildSourceNodeUpsertParams: builds params for lenient UpsertSourceNode
- upsertSourceNode: new function using lenient query

Updated TestSetSourceNodeSameTimestamp to verify that concurrent
updates with the same timestamp now succeed and parameter changes
persist.

Fixes the itest error:
"unable to upsert source node: upserting node(...): sql: no rows in
result set"
2025-12-03 13:08:31 +02:00
Elle Mouton 41615f74a5 graph/db: add test for SetSourceNode same timestamp behavior
This commit adds TestSetSourceNodeSameTimestamp to demonstrate the
current behavior when SetSourceNode is called with the same last update
timestamp. The test reveals a difference between the SQL and bbolt
implementations:

- SQL store returns sql.ErrNoRows when attempting to update with the
  same timestamp, as the upsert query's UPDATE clause requires the new
  timestamp to be strictly greater than the existing one
- bbolt store silently ignores stale updates and returns no error

This behavior is important to document because our own node
announcements may change quickly with the same timestamp, unlike
announcements from other nodes where same timestamp typically means
identical parameters.
2025-12-03 13:08:30 +02:00
ziggie 06886e71b2 graph/db: fix HasNode comment
The comment was incorrectly referring to HasLightningNode but the
function is named HasNode. Update the comment to match the actual
function name.
2025-11-29 01:04:25 +01:00
ziggie 5225b9bbbc graph: add regression test for the fixed behaviour 2025-11-19 16:09:33 +01:00
ziggie 575766c5f4 graph: fix graph cache population for channels with both policies disabled
Fix a bug where channels with both policies disabled were not added to
the graph cache during startup. When a policy update later re-enabled
one of the directions, the update would succeed in the database but fail
to update the graph cache (since the channel structure was never added),
preventing the channel from being used for routing.
2025-11-19 10:12:08 +01:00
Elle Mouton 352b4d620a graph/db: freeze sql migration queries 2025-11-12 22:54:06 +08:00
Elle Mouton 125325f625 multi: freeze graph SQL migration logic
Copy over all the code that the graph SQL migration needs to a
separate folder. This will let us advance the main graph SQL CRUD code
without worrying about changing the sql migration code. It will also let
us change the SQL queries without changing the migration. In this
commit, only the migration logic is "frozen" but in an upcoming commit,
the sqlc queries & models will be frozen too.
2025-11-12 22:54:05 +08:00
Elle Mouton 07d0f0842c graph/db: remove TestPopulateViaMigration
This tests was a temporary helper to let devs test the graph SQL
migration before it was plugged in to LND. But that migration has now
shipped and so we can remove this.
2025-11-12 22:54:05 +08:00
Elle Mouton 33c3809e4b graph/db: remove outdated comment 2025-11-12 22:54:05 +08:00
Elle Mouton 855e579c3f graph: remove DB interface 2025-11-12 22:54:05 +08:00
Elle Mouton edc021f711 graph/db: simplify auth proof and edge info
Remove various unused fields and methods.
2025-11-12 22:54:05 +08:00
Elle Mouton 80e70096cb multi: add models.Node V1 constructor
Add a version field to models.Node and a V1 constructor for it.
2025-11-12 22:54:05 +08:00
Elle Mouton 8f205e2d1c multi: remove HaveNodeAnnouncement field from Node
Remove the 2 sources of truth here. If we have a signature for the
node, then we have the announcement.
2025-11-12 22:54:04 +08:00
Elle Mouton a394938dfd models: simplify models.Node
Simplify the struct by removing un-used methods and outdated comments.
2025-11-12 22:54:04 +08:00
Elle Mouton b57714b00c graph/db: use lnwire.GossipVersion instead of ProtocolVersion 2025-11-12 22:54:03 +08:00
Elle Mouton eb67757a07 graph/db: gracefully handle duplicate channel policy announcements 2025-10-06 11:37:39 +02:00
Elle Mouton abb9654856 graph/db: gracefully handle duplicate node announcements
It can happen that we are handling 2 of the same node announcements in
the same batch transaction. In that case, our `UpsertNode` conflict
assertion may fail. We need to handle this gracefully.
2025-10-06 11:28:33 +02:00
Elle Mouton 14cf937419 graph: fix log formatting 2025-10-06 10:59:39 +02:00
Elle Mouton b8abe130a5 multi: rename lnwire.NodeAnnouncement
In preparation for adding a NodeAnnouncement2 struct along with a
NodeAnnouncement interface, this commit renames the existing
NodeAnnouncment struct to NodeAnnouncement1.
2025-10-01 13:13:32 +02:00
Olaoluwa Osuntokun f3a8fd842d graph+discovery: update graph/db gossip backlog interfaces to use iter.Seq2
This lets us emit a rich error if things fail when first creating the
iterator, or if any of the yield attempts fail.
2025-09-26 17:01:11 -07:00
Olaoluwa Osuntokun 32528afa0a graph/db: add tests for iterator implementations 2025-09-26 16:58:41 -07:00
Olaoluwa Osuntokun 31ab2ae4b6 sqldb: implement iterator support for ChanUpdatesInHorizon
In this commit, we update the SQL store implementation to support the
new iterator-based API for ChanUpdatesInHorizon. This includes adding
SQL query pagination support and helper functions for efficient batch
processing.

The SQL implementation uses cursor-based pagination with configurable
batch sizes, allowing efficient iteration over large result sets without
loading everything into memory. The query is optimized to use indexes
effectively and minimize database round trips.

New SQL query GetChannelsByPolicyLastUpdateRange is updated to support:
- Cursor-based pagination using (max_update_time, id) compound cursor
- Configurable batch sizes via MaxResults parameter
- Efficient batch caching with updateChanCacheBatch helper
2025-09-26 16:58:11 -07:00
Olaoluwa Osuntokun c69971c20b sqldb: implement iterator support for NodeUpdatesInHorizon
In this commit, we update the SQL store implementation to support the
new iterator-based API for NodeUpdatesInHorizon. This includes adding a
new SQL query that supports efficient pagination through result sets.

The SQL implementation uses cursor-based pagination with configurable
batch sizes, allowing efficient iteration over large result sets without
loading everything into memory. The query is optimized to use indexes
effectively and minimize database round trips.

New SQL query GetNodesByLastUpdateRange is updated to support:
  * Cursor-based pagination using (last_update, pub_key) compound cursor
  * Optional filtering for public nodes only
  * Configurable batch sizes via MaxResults parameter
2025-09-26 16:57:41 -07:00
Olaoluwa Osuntokun 069888b51a graph/db: convert ChanUpdatesInHorizon to use iterators
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.
2025-09-26 16:57:11 -07:00
Olaoluwa Osuntokun 1d6d54e5db graph/db: convert NodeUpdatesInHorizon to use iterators
In this commit, we refactor the NodeUpdatesInHorizon 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.

The new implementation uses Go 1.23's iter.Seq type to provide a
standard iterator interface. The method now supports configurable batch
sizes through functional options, allowing fine-tuned control over
memory usage and performance characteristics.

Rather than reading all the entries from disk into memory (before this
commit, we did consult the cache for most entries, skipping the disk
hits), we now expose a chunked iterator instead.

We also make the process of filtering out public nodes first class. This
saves many newly created db transactions later.
2025-09-26 16:56:41 -07:00
Olaoluwa Osuntokun f8ce00b84a graph/db: add options infrastructure for iterator configuration
In this commit, we introduce a new options pattern for configuring
iterator behavior in the graph database. This includes configuration
for batch sizes when iterating over channel and node updates, as well
as an option to filter for public nodes only.

The new functional options pattern allows callers to customize iterator
behavior without breaking existing APIs. Default batch sizes are set to
1000 entries for both channel and node updates, which provides a good
balance between memory usage and performance.
2025-09-26 16:56:20 -07:00
Elle Mouton f2fa0a4da6 graph/db: fix type name 2025-09-04 17:10:44 +02:00
Yong e46c676894 Merge pull request #10162 from ellemouton/graphMigUnwrapDNSAddrs
graph/db: unwrap dns addresses from opaque ones during migration
2025-09-04 22:29:49 +08:00
Elle d9647f8b79 Merge pull request #10193 from ellemouton/fixSQLStrHelper
sqldb: fix SQLStr helper
2025-09-04 12:07:25 +02:00
Elle Mouton 40b279687f sqldb: add SQLStrValid helper
The SQL* helpers are meant to always set the `Valid` field of the
sql.Null* type to true. Otherwise they cannot be used to set a valid,
empty field. However, we dont want to break the behaviour of the
existing SQLStr helper and so this commit adds a new helper with the
desired functionality.
2025-09-03 15:46:11 +02:00
Elle Mouton 6e98b336f6 graph/db+channeldb: rename test helper 2025-09-03 10:14:35 +02:00
Elle Mouton 330f697937 graph: rename HasLightningNode
to HasNode
2025-09-03 10:14:35 +02:00
Elle Mouton 7a1b548e07 graph/db: rename DeleteLightningNode
to DeleteNode
2025-09-03 10:14:35 +02:00
Elle Mouton cd3bd05810 multi: rename FetchLightningNode
to FetchNode
2025-09-03 10:14:35 +02:00
Elle Mouton 060219780b multi: rename AddLightningNode methods
to AddNode
2025-09-03 10:14:35 +02:00
Elle Mouton c663a557c4 multi: rename models.LightningNode to models.Node 2025-09-03 10:14:35 +02:00
Elle Mouton a74f0b133a graph/db: expand test comment with build tag info 2025-09-03 10:11:49 +02:00
Elle Mouton af380c9eb1 graph/db: extract DNS addresses during SQL migration
In this commit, we take advantage of the graph SQL migration and use it
to also extract DNS addresses from the opaque address type. We use
opaque addresses to store addresses that we dont understand yet. We
recently added logic for DNS addresses and so we may have persisted node
announcements that have DNS addresses but we would currently have them
stored under the opaque address type. So we use this migration to see if
we can extract such addresses.

A few decisions were made here:
1) If multiple DNS addressees are extracted, this is ok and we continue
   to migrate the node even though this is actually invalid at a
   protocol level. We will currently check (at a higher level) that a node
   announcement only has 1 DNS address in it before we broadcast it though.
2) If an invalid DNS address is encountered (so we hit the DNS type
   descriptor but then the rest of the DNS address payload is invalid
   and cannot be parsed into the expected hostname:port, then we skip
   migrating the node completely.
2025-09-03 09:13:42 +02:00
Elle Mouton 6ef80db746 graph/db+chanbackup: dns add encoding/decoding for persistence 2025-09-03 01:11:35 +00:00
Elle Mouton 4bd2bbca27 graph/db: update test opaque addr to be valid
The first byte of an opaque addr must be one that we dont understand
yet. We do this update in preparation for doing an on-the-fly parse of
persisted opaque addrs to see if they contain addrs that we now support.
For this to work, the first byte cant be 0x01 since this maps to a known
address.
2025-09-03 01:11:35 +00:00
Yong 84b2c20ea0 Merge pull request #10167 from starius/go124
multi: bump Go to 1.24.6
2025-09-01 20:03:54 +08:00
Elle Mouton ce1df9da34 graph/db: let the rapid migration test also tests idempotency 2025-09-01 08:08:00 +02:00
Elle Mouton f2ed5564ef graph/db+sqldb: improve performance of chan update sql migration
This commit simplifies insertChanEdgePolicyMig. Much of the logic can be
removed given that this method is only used in the context of the graph
SQL migration.

This should improve the performance of the migration quite a lot since
it removes the extra GetChannelAndNodesBySCID call.
2025-09-01 08:07:57 +02:00
Elle Mouton 22bf88e900 graph/db+sqldb: make policy migration idempotent
Finally, we make the channel-policy part of the SQL migration idempotent
by adding a migration-only policy insert query which will not error out
if the policy already exists and does not have a timestamp that is newer
than the existing records timestamp. To keep the commit simple, a
insertChanEdgePolicyMig function is added which is basically identical
to the updateChanEdgePolicy function except for the fact that it uses
the newly added query. In the next commit, it will be simplified even
more.
2025-09-01 08:06:12 +02:00