20399 Commits
Author SHA1 Message Date
ziggieXXX 6ea4791895 Merge pull request #10635 from ziggie1984/worktree-bw-compat-log-collection
CI / Static Checks (push) Has been cancelled
CI / Check commits (push) Has been cancelled
CI / Lint code (push) Has been cancelled
CI / Cross compilation (amd64, darwin-amd64 freebsd-amd64 linux-amd64 netbsd-amd64 openbsd-amd64 windows-amd64) (push) Has been cancelled
CI / Cross compilation (arm, darwin-arm64 freebsd-arm linux-armv6 linux-armv7 linux-arm64 windows-arm) (push) Has been cancelled
CI / Cross compilation (i386, freebsd-386 linux-386 windows-386) (push) Has been cancelled
CI / Run unit tests (unit tags="kvdb_etcd") (push) Has been cancelled
CI / Run unit tests (unit tags="kvdb_postgres") (push) Has been cancelled
CI / Run unit tests (unit tags="kvdb_sqlite") (push) Has been cancelled
CI / Run unit tests (unit tags="test_db_postgres") (push) Has been cancelled
CI / Run unit tests (unit tags="test_db_sqlite") (push) Has been cancelled
CI / Run unit tests (unit-cover) (push) Has been cancelled
CI / Run unit tests (unit-module) (push) Has been cancelled
CI / Run unit tests (unit-race tags="test_db_postgres") (push) Has been cancelled
CI / Run unit tests (unit-race tags="test_db_sqlite") (push) Has been cancelled
CI / Run unit tests (unit-race) (push) Has been cancelled
CI / Run basic itests (backend="bitcoind notxindex", bitcoind-notxindex) (push) Has been cancelled
CI / Run basic itests (backend=bitcoind cover=1, bitcoind) (push) Has been cancelled
CI / Run basic itests (backend=btcd cover=1, btcd) (push) Has been cancelled
CI / Run basic itests (backend=neutrino cover=1, neutrino) (push) Has been cancelled
CI / Run itests (backend="bitcoind rpcpolling", bitcoind-rpcpolling) (push) Has been cancelled
CI / Run itests (backend=bitcoind dbbackend=etcd, bitcoind-etcd) (push) Has been cancelled
CI / Run itests (backend=bitcoind dbbackend=postgres nativesql=true tags=test_native_sql, bitcoind-postgres-nativesql-experiment) (push) Has been cancelled
CI / Run itests (backend=bitcoind dbbackend=postgres nativesql=true, bitcoind-postgres-nativesql) (push) Has been cancelled
CI / Run itests (backend=bitcoind dbbackend=postgres, bitcoind-postgres) (push) Has been cancelled
CI / Run itests (backend=bitcoind dbbackend=sqlite nativesql=true tags=test_native_sql, bitcoind-sqlite=nativesql-experiment) (push) Has been cancelled
CI / Run itests (backend=bitcoind dbbackend=sqlite nativesql=true, bitcoind-sqlite-nativesql) (push) Has been cancelled
CI / Run itests (backend=bitcoind dbbackend=sqlite, bitcoind-sqlite) (push) Has been cancelled
CI / Run windows itest (push) Has been cancelled
CI / Run macOS itest (push) Has been cancelled
CI / Check pinned dependencies (github.com/golang/protobuf v1.5.4) (push) Has been cancelled
CI / Check pinned dependencies (google.golang.org/grpc v1.59.0) (push) Has been cancelled
CI / Check release notes updated (push) Has been cancelled
CI / Backwards compatibility test (push) Has been cancelled
CI / Cache Cleanup (push) Has been cancelled
CI / Send coverage report (push) Has been cancelled
Docker image build / Check PGP key expirations (push) Has been cancelled
Docker image build / main (push) Has been cancelled
scripts/bw-compat: fix log collection
2026-03-05 20:49:30 +01:00
ziggie 2b4dc4eace scripts/bw-compat: use docker logs for log collection
Switch collect_logs from docker cp to docker logs to reliably capture
container output. The previous approach used docker cp to copy lnd log
files from inside named volumes, which silently fails in CI — the
directory gets created and the success echo prints, but no files are
ever copied, causing upload-artifact to report "No files were found".

docker logs reads directly from Docker's captured stdout/stderr buffer,
bypassing the volume entirely, and works as long as the container exists.
2026-03-05 15:51:59 +01:00
ziggieXXX 7c38c1ea05 Merge pull request #10434 from GeorgeTsagk/extra-aux-band-check
Add `AuxHtlcValidator`
2026-03-05 11:27:07 +01:00
Olaoluwa Osuntokun cd755cda0c Merge pull request #9637 from Roasbeef/chan-type-required
feature: start to set the require bit for channel_type
2026-03-04 17:40:59 -08:00
ziggieXXX 1e433db0ee Merge pull request #10626 from ziggie1984/fix-bench-get-invoice
sqldb: fix GetInvoice call in benchmarks
2026-03-04 20:50:46 +01:00
George Tsagkarelis 8d30e7d160 peer: add test for createHtlcValidator 2026-03-04 20:19:43 +01:00
George Tsagkarelis 1edf8123e4 lnwallet: add aux test utils
We add this constructor for an AuxHtlcDescriptor that allows setting
some of the internal fields. This is useful for testing purposes for
code external to this package that may need to extensively test the
AuxHtlcView.
2026-03-04 20:19:43 +01:00
George Tsagkarelis b1701cf232 peer: set and use aux htlc validator
When instantiating the lightning channel we now pass in the created HTLC
validator. This validator simply performs a bandwidth check and errors
out if that is insufficient.
2026-03-04 20:02:07 +01:00
George Tsagkarelis 773b2c1c30 lnwallet: add and use AuxHtlcValidator to lightning channel
Previously we'd perform aux bandwidth checks during path finding. This
could lead to issues where multiple HTLCs where querying the same
bandwidth but were not accounting for each other before being added to
the commitment log. We now add a new validator function that will serve
as the last point of checks before adding the HTLC to the commitment.

During path finding HTLCs could query channel bandwidth asynchronously.
At this new call site all HTLCs that are about to be added to the
channel have been organised in sequence, so it's safe to query bandwdith
again at this point as we're getting the actual up-to-date values.

We remove the aux bandwidth check from the helper canSendHtlc, which was
called from CheckHTLCTransit and CheckHTLCForward (both are methods of
the htlcswitch).

For forwards we now fail at the link level, following the introduction
of the AuxHtlcValidator.

For payments, we now may fail either at the pathfinding level, or at the
link level. The htlcswitch may no longer fail for aux bandwidth checks.

Finally, when fetching the latest htlc view (for bandwidth checks during
pathfinding) we'd silently set the nextHeight of the view to the default
zero value. We now make sure to set it to the correct nextHeight value.
2026-03-04 20:02:06 +01:00
ziggie 6750738137 sqldb: fix GetInvoice call in benchmarks
GetInvoice was removed and replaced with GetInvoiceByHash,
GetInvoiceByAddr, etc. Update the sqlite benchmarks to use
GetInvoiceByHash instead.
2026-03-04 19:38:25 +01:00
ziggieXXX 4a3b8029cf Merge pull request #10619 from ziggie1984/increase-settling-speed
invoices/sql: fix full table scans on HTLC settlement hot path
2026-03-04 18:16:01 +01:00
ziggieXXX 8ec11635ed Merge pull request #10565 from ziggie1984/fix-sqlite-config-defaults
sqldb+lncfg: wire up unused SQLite config fields
2026-03-04 18:14:34 +01:00
ziggie d767c1e76d docs: add release-notes 2026-03-04 13:04:27 +01:00
ziggie e751d96c13 sqldb: remove unused GetInvoice query 2026-03-04 13:04:26 +01:00
ziggie 7995e87b91 invoices: use longer timeout for HTLC resolution in AMP test
Under parallel Postgres test load, the event loop must complete
sequential DB writes after SetTime fires. Using testTimeout (5s)
is too tight; switch the three blocking hodlChan selects in
testFailPartialAMPPayment to testTimeoutLong (1 minute) to
match the pattern already used elsewhere for slow backends.
2026-03-04 13:04:26 +01:00
ziggie f6f6064938 scripts: fix backwards compatibility test timing issues
The backwards compatibility test was failing intermittently due to two
related timing issues in the test setup.

The issue was that Dave's `wait_graph_sync dave 3` was hanging
for up to 60 minutes. Dave's initial gossip sync with Charlie could
complete before Charlie had forwarded the alice-bob channel
announcement, leaving Dave stuck at 2 channels until lnd's historical
syncer fired at its default interval of 1 hour. After this 1-hour idle,
some routing state had become stale, causing the subsequent payment from
alice to dave to fail with FAILURE_REASON_NO_ROUTE.

This issues is now addressed by setting `--historicalsyncinterval=10s` on
all nodes. This causes nodes to periodically re-sync the full gossip
state from their peers every 10 seconds instead of every hour. Dave
therefore picks up any missed channel announcements and routing policies
within seconds, and alice's routing graph stays up-to-date throughout
the test.

Additionally, lnd debug logs from all containers are now collected
before teardown on failure and uploaded as a CI artifact, making future
failures easier to diagnose.
2026-03-04 13:04:26 +01:00
ziggie e2dfd8f034 invoices: add TODO to change the return type of the query 2026-03-04 13:04:26 +01:00
ziggie 0ca69e6f57 invoices/sql: replace catch-all GetInvoice with indexed lookups
The GetInvoice query used an OR IS NULL pattern for each filter
parameter:

  WHERE (i.hash = $1 OR $1 IS NULL)
    AND (i.payment_addr = $2 OR $2 IS NULL)

SQLite's query planner decides on an execution plan at prepare time,
before seeing any parameter values. Because either condition can be
trivially true when its parameter is NULL, the planner conservatively
falls back to a full table scan rather than using the unique indexes on
hash and payment_addr. This caused every invoice lookup and update on
the hot path (HTLC settlement) to scan the entire invoices table.

Replace the single catch-all query with three dedicated queries, each
using a direct equality on a uniquely constrained column:

- GetInvoiceByHash:  WHERE hash = $1
- GetInvoiceByAddr:  WHERE payment_addr = $1  (new, covers AMP path)
- GetInvoiceBySetID: existing, unchanged

Update getInvoiceByRef to route to the appropriate query based on which
fields are present in the InvoiceRef. When both hash and payment address
are provided, we look up by hash and then verify the returned invoice's
payment address matches.

GetInvoice is now unused and removed from the SQLInvoiceQueries
interface.
2026-03-04 13:04:26 +01:00
ziggie 65f6d75511 sqldb: drop redundant and unused invoice indexes
Remove four indexes from the invoices table that either duplicate existing
UNIQUE constraint indexes or are never used in WHERE clauses:

- invoices_hash_idx: redundant, UNIQUE constraint on hash already creates
  an implicit index
- invoices_payment_addr_idx: redundant, UNIQUE constraint on payment_addr
  already creates an implicit index
- invoices_preimage_idx: unused, preimage is NULL on all new invoices and
  is never used as a query filter
- invoices_settled_at_idx: unused, settled_at is NULL on all pending
  invoices and is never used as a query filter (settle_index is used
  instead)

Dropping these reduces B-tree working set size, which improves page cache
utilization as the invoice table grows.
2026-03-04 13:04:26 +01:00
ziggie de06c29ae9 sqldb: add benchmark for sqlite connection number
The results suggests that the default of 2 is a good conservative
approach. The higher the connection number and the higher the
workload the performance decreases in WAL mode since readers still
need coordination (WAL index shm for example).
2026-03-03 19:23:12 +01:00
ziggieXXX 2aec8f3380 Merge pull request #10485 from ziggie1984/migration-kvdb-sql-payments-part1
payments: kv-to-sql migration (tests + wiring)
2026-03-02 10:29:46 +01:00
ziggie 89f046a129 docs: add release notes for KV-to-SQL payment migration 2026-02-27 09:25:42 +01:00
ziggie 6c28cc4d0b payments/migration1: freeze lnwire and record dependency
Also freeze the lnwire and record packages used by the migration.

Copy the minimal subset of lnwire files (16) into
payments/db/migration1/lnwire/ and all record files (6) into
payments/db/migration1/record/. Three lnwire files are trimmed to avoid
pulling in the full message-type dispatch tree — all changes are purely
subtractive and can be verified with:

  diff lnwire/message.go payments/db/migration1/lnwire/message.go
  diff lnwire/writer.go  payments/db/migration1/lnwire/writer.go
  diff lnwire/lnwire.go  payments/db/migration1/lnwire/lnwire.go

All migration1 files now import only the frozen packages, removing the
live dependency on lnwire and record so future changes to those packages
cannot affect migration correctness.
2026-02-27 09:25:21 +01:00
ziggie 00025ef3bf payments/db: normalize LegacyPayload flag in migration comparison
LegacyPayload was a hint used exclusively by the KV store to decide
how to serialize and deserialize the hop payload (legacy format vs
TLV). The SQL store does not serialize hop data at all — every hop
field is persisted natively in its own column — so this flag has no
meaning there and is never stored.

Clear LegacyPayload for all hops inside normalizePaymentForCompare so
that deep-equality checks between KV and SQL payments succeed even when
the KV source data carries LegacyPayload=true.

A dedicated test (TestMigrationLegacyPayloadNormalized) is added to
verify that a payment with LegacyPayload=true hops migrates and
compares correctly.
2026-02-26 17:38:33 +01:00
Elle 8126b424fd Merge pull request #10610 from ellemouton/graph-cleanup-todo-contexts
graph/db+refactor: surface all `context.TODO()`s
2026-02-26 16:18:31 +02:00
Yong 9bef04a67d Merge pull request #10604 from lightningnetwork/elle-payment-sql-series-new
payments: SQL backend implementation series
2026-02-26 10:52:57 +08:00
ziggie cf3610abb9 payments/db: split migration queries into dedicated SQLMigrationQueries interface 2026-02-25 18:52:34 +01:00
ziggie a2c36d1667 sqldb: add migration consistency test
Tests that all migration files follow the defined schema and that
there are not duplicates which could cause collision.
2026-02-25 18:52:34 +01:00
ziggie 932fbc33f0 graph/db/migration1: fix defer commit/rollback in test tx executor
The defer closure checked a local err variable for commit/rollback
decisions, but err remained nil after a successful BeginTx. When
txBody failed, the error was returned directly without assigning to
err, so the defer always committed instead of rolling back.

Additionally, since err was not a named return value, the defer's
Commit error assignment was silently swallowed.

Replace the error-prone defer pattern with explicit rollback on
txBody failure and a direct Commit return.
2026-02-25 18:52:34 +01:00
ziggie 9def124380 payments/db: fix silent error in duplicate payment lookup
When duplicatePaymentSequenceKey is missing from a duplicate payment
sub-bucket, the code returned the outer function's err variable which
is nil at that point. This caused corrupted duplicate entries to be
silently treated as "not found" instead of failing loudly.

Return a new dedicated ErrNoDuplicateSequenceNumber error so malformed
data is detected immediately.
2026-02-25 18:52:34 +01:00
ziggie c862e70148 mod: update new direct dependency via go mod tidy 2026-02-25 18:52:33 +01:00
ziggie 89685de16e payments/migration1: handle legacy payments with nil HTLC hash
For legacy payments, the HTLC Hash field may be nil in the bbolt
backend. Previously, the migration would fail with "HTLC attempt X
missing payment hash" when encountering such payments.

This commit fixes the migration by falling back to the parent payment
hash when the HTLC-specific hash is nil. This is consistent with how
the router handles legacy payments (see patchLegacyPaymentHash in
payment_lifecycle.go).

The validation logic is also updated to apply the same fallback when
comparing bbolt data with migrated SQL data, ensuring the comparison
succeeds.
2026-02-25 18:52:33 +01:00
ziggie f174b60b94 payments/migration1: wire KV→SQL migration in the main pkg
Hook the payments KV→SQL migration into the SQL migration config.
The migration is still only available when building with the build tag
"test_native_sql".

Moreover a tombstone protection similar to the invoice migration is added
to prevent re-runningi with the KV backend  once migration completes.
2026-02-25 18:52:33 +01:00
ziggie 4b30bed0ac payments/migration1: add external migration test
Add a developer-facing migration_external_test that allows
running the KV→SQL payments migration against a real channel.db
backend to debug migration failures on actual data. The accompanying
testdata README documents how to supply a database file and configure
the test, so users can validate their data and confirm the migration
completes successfully.

The test is skipped by default and meant for manual diagnostics.
2026-02-25 18:52:33 +01:00
ziggie f058f3329d payments/migration1: add migration test suite and helpers
Add test helpers plus sql_migration_test coverage for KV→SQL migration.
Basic migration, sequence ordering, data integrity, and feature-specific cases
(MPP/AMP, custom records, blinded routes, metadata, failure messages). Also
cover duplicate payment migration to payment_duplicates, including missing
attempt info to ensure terminal failure is recorded.

This gives broad regression coverage for the migration path and its edge-cases.
2026-02-25 18:52:33 +01:00
ziggie a9747207f6 payments/migration1: add the payments mig code
Implement the KV→SQL payment migration and add an in-migration
validation pass that deep-compares KV and SQL payment data in batches.
Duplicate payments are migrated into the payment_duplicates table,
and duplicates without attempt info or explicit resolution are marked
failed to ensure terminal state. Validation checks those rows as well.
2026-02-25 18:52:32 +01:00
ziggie fb705bb0f9 payments/migration1: freeze core payment code
Copy the core payments/db code into payments/db/migration1 and
add the required sqlc-generated types/queries from sqldb/sqlc.
This effectively freezes the migration code so it stays robust
against future query or schema changes in the main payments package.

Replace the delegation to channeldb.ReadElement/WriteElement with
self-contained, frozen implementations that only handle the exact types
required by this migration package. This removes the dependency on the
live channeldb codec so that future changes to channeldb serialization
cannot silently corrupt or break the migration.

UnknownElementType is also defined locally for the same reason.
2026-02-25 18:52:32 +01:00
ziggie 74f8f2d9e6 sqldb+payments: add payment_duplicates for legacy duplicate payments
Older LND versions could create multiple payments for the same hash.
We need to preserve those historical records during KV→SQL migration,
but they don’t fit the normal payment schema because we enforce a
unique payment hash constraint. Introduce a lean payment_duplicates
table to store only the essential fields (identifier, amount,
timestamps, settle/fail data).

This keeps the primary payment records stable and makes the migration
deterministic even when duplicate records lack attempt info. The table
is intentionally minimal and can be dropped after migration if no
duplicate payments exist.

For now there is no logic in place which allows the noderunner to
fetch duplicate payments after the migration.
2026-02-25 18:52:32 +01:00
ziggie 2596d34619 paymentsdb+sqldb: add migration related query
Add a migration specific query which allows to set the failure
reason when inserting a payment into the db.
2026-02-25 18:52:31 +01:00
ziggie e9a88267ff paymentsdb: fix duplicate interface check and down migration drop order
- Remove duplicate compile-time interface assertion for SQLStore.

- Fix the down migration to drop payment_intents before payments to
respect the foreign key dependency order. This was not a bug in the
first place bc we have the CASCADE when deleting payments.
2026-02-25 18:36:14 +01:00
ziggie 216de55dff paymentsdb: sort FetchInFlightPayments result by sequence number
The SQL implementation collects payments into a map before converting
to a slice, resulting in non-deterministic iteration order due to Go's
intentional map randomisation. Sort the result by SequenceNum to produce
a deterministic, insertion-ordered output.

Note that the current sole caller (resumePayments in router.go) processes
each payment independently, so this ordering does not affect any existing
behaviour.
2026-02-25 18:36:14 +01:00
ziggie 0c2951aa05 paymentsdb: fix SettleAttempt and FailAttempt to use caller-provided timestamps
The SQL backend introduced in this PR was ignoring the SettleTime and
FailTime fields provided in HTLCSettleInfo and HTLCFailInfo, instead
always recording time.Now() as the resolution timestamp. The KV backend
correctly serializes and deserializes these fields.

The timestamps are set by the caller using a mockable clock
(p.router.cfg.Clock.Now() in payment_lifecycle.go), so ignoring them
means the stored timestamp reflects when the DB write happened rather
than when the event occurred, breaking deterministic testing.

This commit also extends the test assertions in assertPaymentInfo to
verify that SettleTime and FailTime are correctly stored and retrieved
by the SQL backend, and updates the relevant call sites to pass explicit
timestamps so regressions are caught.
2026-02-25 18:36:14 +01:00
Elle Mouton 262e9208b9 graphdb: thread topology update context 2026-02-25 16:11:47 +02:00
Elle Mouton 0bb0d66952 graphdb: pass context to GraphSession 2026-02-25 16:11:46 +02:00
Elle Mouton 8722a96a4e graphdb: pass context to IsClosedScid 2026-02-25 16:11:46 +02:00
Elle Mouton 4dcaf1c16a graphdb: pass context to PutClosedScid 2026-02-25 16:11:46 +02:00
Elle Mouton 68c5206017 graphdb: pass context to AddEdgeProof 2026-02-25 16:11:46 +02:00
Elle Mouton 3dc2efd7f3 graphdb: pass context to DisconnectBlockAtHeight 2026-02-25 16:11:46 +02:00
Elle Mouton a31c86b0ee graphdb: pass context to PruneTip 2026-02-25 16:11:46 +02:00
Elle Mouton 9f855175d5 graphdb: pass context to ChannelView 2026-02-25 16:11:46 +02:00