Commit Graph
100 Commits
Author SHA1 Message Date
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
ziggie a2cb753428 sqldb: rename 000009_payments to 000010_payments
The 000009 schema version slot is now taken by 000009_graph_v2_columns
which was merged ahead of the payments schema. Bump the payments schema
file number to 000010 to avoid the collision.

Moreover update the migration_dev.go file to reflect this change and
update the order of migration.
2026-02-25 08:02:27 +01:00
ziggie 2548c15167 docs: add release-notes 2026-02-25 08:02:27 +01:00
ziggie 372fbbd70b paymentsdb: add more unit tests to increase coverage
We add a couple of additional tests to increase the unit test
coverage of the sql store but also the kv store. We only create
db agnostic unit tests so both backends are tested effectively.
2026-02-25 08:02:26 +01:00
ziggie a0a22b7ff9 paymentsdb: add additional test for first hop data
We add a test which tests the retrieval of first hop data like
the first hop amount or the custom records on the route level.
2026-02-25 08:02:26 +01:00
ziggie a861ac8d46 paymentsdb: refactor test helpers 2026-02-25 08:02:26 +01:00
ziggie 995ad7e1b5 multi: move failed attempt cfg option to the router subsytem
Previously we had db and application logic mixed on the db level.
We now move the config option KeepFailedPaymentAttempts to the
ChannelRouter level and move it out of the db level.
2026-02-25 08:02:26 +01:00
ziggie 253e4fd832 routing: add TODO to also delete payments without HTLCs 2026-02-25 08:02:26 +01:00
ziggie 3ae0ccc6f5 paymentsdb: make delete payments test db agnostic
We make the TestDeleteNonInFlight and separate all the logic out
for the duplicate payment test case. The deletion of duplicate
payments is now tested in isolation only for the kv backend.
2026-02-25 08:02:26 +01:00
ziggie 9da39e5655 docs: add release-notes 2026-02-25 08:02:25 +01:00
ziggie d8d5d3f990 multi: thread context through SendPayment 2026-02-25 08:02:25 +01:00
ziggie 4cc5428087 routing: add context to reloadPayment method 2026-02-25 08:02:25 +01:00
ziggie 03d891d52d routing: add context to reloadInflightAttempts 2026-02-25 08:02:25 +01:00
ziggie 5b06854850 routing: add context to failAttempt 2026-02-25 08:02:25 +01:00
ziggie e130ccc494 routing: Thread context through failPaymentAndAttempt
A context is added to failPaymentAndAttempt and its dependant
function calls.
2026-02-25 08:02:25 +01:00
ziggie 8038dc0054 multi: thread context through payment lifecyle functions 2026-02-25 08:02:25 +01:00
ziggie dfe0c43c7d routing: Add context to requestRoute 2026-02-25 08:02:24 +01:00
ziggie 33597ad35d docs: add release notes 2026-02-25 08:02:24 +01:00
ziggie 7f2df4b088 multi: thread context through DeleteFailedAttempts 2026-02-25 08:02:24 +01:00
ziggie 635a67c94a multi: thread context through Fail payment functions 2026-02-25 08:02:24 +01:00
ziggie 446300984e multi: thread context through FailAttempt 2026-02-25 08:02:24 +01:00
ziggie 3b7fdabaec multi: thread context through SettleAttempt 2026-02-25 08:02:24 +01:00
ziggie 8bb7150dc2 multi: thread context through RegisterAttempt method 2026-02-25 08:02:24 +01:00
ziggie 60026494b1 multi: thread context through InitPayment 2026-02-25 08:02:23 +01:00
ziggie 10062ca9ac multi: thread context through FetchInflightPayments 2026-02-25 08:02:23 +01:00
ziggie 25d05be038 multi: thread context through FetchPayment 2026-02-25 08:02:19 +01:00
ziggie 563a2ac9d3 multi: thread context through DeletePayments 2026-02-25 08:02:19 +01:00
ziggie bc15d4bb50 multi: thread context through DeletePayment 2026-02-25 08:02:19 +01:00
ziggie fcb8929ea5 docs: add release-notes 2026-02-25 08:02:19 +01:00
ziggie dfacb9ec00 paymentsdb: add unit test for FetchInflightPayments method 2026-02-25 08:02:18 +01:00
ziggie e40c8df16b paymentsdb: add firstcustom records to unit tests 2026-02-25 08:02:18 +01:00
ziggie bfd59aac22 paymentsdb: add more comments 2026-02-25 08:02:18 +01:00
ziggie ea4e183c39 lnrpc: fix linter 2026-02-25 08:02:18 +01:00
ziggie f518931cf0 itest: fix list_payments accuracy edge case 2026-02-25 08:02:18 +01:00
ziggie 5f1f413596 paymentsdb: make specific kv store tests only available via build tag 2026-02-25 08:02:18 +01:00
ziggie 080fd78fb4 paymentsdb: introduce a harness interface
The design of the sql and kv db are a bit different. A harness
interface is introduced which allows us to unit most of the test
and keep the backend specific tests at a minimum.
2026-02-25 08:02:17 +01:00
ziggie 570863ca26 paymentsdb: add harness to run payment db agnostic tests
In commit adds the harness which will be used to run db agnostic
tests against the kv and sql backend. We have adopted all the
unit tests so far so that with this commit all the payment tests
not specifically put into the kv_store_test.go should all pass
for all backends.
2026-02-25 08:02:17 +01:00
ziggie 2eadbfb54d paymentsdb: fix test case before testing sql backend
We are now not supporting the LegacyPayload for the onion packet
anymore. All payments and their onion payload need to be tlv
encoded. The sql backend assumes tlv so we have to always set the
in memory presentation of a hop where the legacy parameter is still
available but deprecated to false, otherwise the hops will not be
equal and unit tests for the sql backend will fail when switched
on in the next commits.
2026-02-25 08:02:17 +01:00
ziggie de50f471e8 paymentsdb: make QueryPayments test db agnostic
We make the QueryPayments test db agnostic and also keep a small
test for querying the duplicate payments case in the kv world.
2026-02-25 08:02:17 +01:00
ziggie fdfa1430f8 paymentsdb: refactor test helpers
Since now the sql backend is more strict in using the same
session key we refactor the helper so that we can easily change
the session key for every new attempt.
2026-02-25 08:02:17 +01:00
ziggie 9ad3f2195b paymentsdb: remove kvstore from sql db implementation
Now that every method of the interface was implemented we can
remove the embedded reference we put into place for the sql store
implementation so that the interface would succeed. This is now
removed.
2026-02-25 08:02:17 +01:00
ziggie c919d25619 docs: add release-notes 2026-02-25 08:02:16 +01:00
ziggie 4e52896cc1 paymentsdb: added unit test for computePaymentStatusFromResolutions 2026-02-25 08:02:16 +01:00
ziggie 969b00e4a5 paymentsdb: implement FetchInFlightPayments for sql backend 2026-02-25 08:02:16 +01:00
ziggie 82ee78c5ef paymentsdb: use batch function when querying for resolutions 2026-02-25 08:02:16 +01:00
ziggie b02531cc85 paymentsdb: rename functions and variables
We take inspiration from the graph sql implementation and name
the variables accordingly.
2026-02-25 08:02:16 +01:00
ziggie 218a30d16e paymentsdb: add a wrapper to the fetchpayment method
We wrap the fetchPayment db call and catch the case where no errors
are found in the db, where we now return the ErrPaymentNotInitiated
error.
2026-02-25 08:02:16 +01:00
ziggie ff12082452 paymentsdb: implement DeletePayments for sql backend 2026-02-25 08:02:16 +01:00
ziggie 53a7877af0 paymentsdb: implement FailAttempt for sql backend 2026-02-25 08:02:15 +01:00
ziggie fd6796e561 multi: implement Fail method for sql backend 2026-02-25 08:02:15 +01:00
ziggie caf73c59da paymentsdb: rename paymentsBatchData
We rename this variable to paymentsDetailsData because we will
also need to batch load the core payment and intent data in
future commits and this renaming should make it clear that this
does match payment related data but not the core data which is
in the payment and in the intent table.
2026-02-25 08:02:15 +01:00
ziggie 5d328c976e paymentsdb: remove pointer receiver dependecy to make it more robust
We remove the SQLStore from most of the helper functions. This
also makes sure we do not accidentally create a new db tx but use
the provided db SQLQueries parameter.
2026-02-25 08:02:15 +01:00
ziggie 7d87c0ce2f paymentsdb: fix formatting for sql QueryPayments 2026-02-25 08:02:15 +01:00
ziggie 4c867c1b88 docs: add release-notes 2026-02-25 08:02:15 +01:00
ziggie 620dacc432 paymentsdb: implement SettleAttempt for sql backend 2026-02-25 08:02:14 +01:00
ziggie c0e55b5855 paymentsdb: verify total amount for last hop in the blinded path 2026-02-25 08:02:14 +01:00
ziggie 40c8502fd3 paymentsdb: implement RegisterAttempt for sql backend 2026-02-25 08:02:14 +01:00
ziggie d2cdd9d86f paymentsdb: add note to RegisterAttempt 2026-02-25 08:02:14 +01:00
ziggie 510f6fb532 paymentsdb: implement InitPayment for sql backend 2026-02-25 08:02:09 +01:00
ziggie 0c96a2d722 sqldb+paymentsdb: add queries to insert all relavant data
In this commit we add all queries which we will need to insert
payment related data into the db.
2026-02-25 08:02:09 +01:00
ziggie c3e25ff8ef paymentsdb: implement DeletePayment for sql backend 2026-02-25 08:02:09 +01:00
ziggie 3012eb2ca0 paymentsdb: implement DeleteFailedAttempts for sql backend 2026-02-25 08:02:09 +01:00
ziggie 6faf68c5fa paymentsdb: add query to only fetch resolution type for HTLCs 2026-02-25 08:02:08 +01:00
ziggie bdea68bebf sqldb: add queries for deleting a payment and attempts 2026-02-25 08:02:08 +01:00
ziggie 27071acb6b sqldb: Change payment_intent relationship to payment table
Previously a one(intent)-to-many(payment) relationship it is now
changed to a one-to-one relationship because a payment request
only can have 1 payment related to it. Looking into the future
with BOLT12 offers, the fetched invoice from the offer could be
stored here as well and the relationship would still hold.
2026-02-25 08:02:08 +01:00
ziggie f8241748a1 paymentsdb: enhance some godoc function descriptions 2026-02-25 08:02:08 +01:00
ziggie 4c5eaad606 docs: add release-notes 2026-02-25 08:02:08 +01:00
ziggie 8aae9ffc2c paymentsdb: implement FetchPayment for sql backend 2026-02-25 08:02:08 +01:00
ziggie e8fe45fe65 paymentsdb: implement QueryPayments for sql backend 2026-02-25 08:02:08 +01:00
ziggie eeca189b87 paymentsdb: add new internal error 2026-02-25 08:02:07 +01:00
ziggie 18e7768837 multi: add relevant queries for QueryPayments implemenation 2026-02-25 08:02:04 +01:00
ziggie e7a3096621 sqldb: add index and comment to payment tables 2026-02-25 08:01:16 +01:00
ziggie b6a05f7951 docs: add release-notes 2026-02-25 08:01:15 +01:00
ziggie 8c7b2367e5 lnd: make the payment schema migration available for testing
We allow the migration of the payment schema to be applied when
the test_native_sql is active to make sure the tables are properly
contructed.
2026-02-25 08:01:15 +01:00
ziggie dd585a821b sqldb: add payment sql tables
This does not include duplicate payments yet. They will be added
when the migration code is introduced for payments.
2026-02-25 08:01:15 +01:00
ziggie 93626822f7 lnd+paymentsdb: introduce harness for the payment sql backend
We prepare the code for the sql payment backend. However no
payment db interface method for the sql backend is implemented
yet. This will be done in the following commits. They currently
use the embedded KVStore to satify the build environment.
2026-02-25 08:01:14 +01:00
ziggie 1e5e6f27ef docs: add release notes for invoice SQL query performance improvements 2026-02-21 17:05:44 +01:00
ziggie d26bf84843 invoices/sql_store: add tests for targeted invoice query variants
Add testFetchPendingInvoicesAccepted to explicitly verify the state
filtering behaviour of FetchPendingInvoices across all four contract
states:

  ContractOpen     (state 0) – must be returned
  ContractAccepted (state 3) – must be returned
  ContractSettled  (state 1) – must be excluded
  ContractCanceled (state 2) – must be excluded

This directly exercises the `state IN (0, 3)` predicate introduced in
the FetchPendingInvoices SQL query and addresses the review request for
explicit test coverage of the new targeted query variants. The test
runs against the KV, SQLite, and Postgres backends.
2026-02-21 17:05:44 +01:00
ziggie 9becdfa8a3 sqldb/sqlc: remove deprecated FilterInvoices query
All call sites have been migrated to the targeted replacement queries
in the previous commit. Remove FilterInvoices and its associated
params struct from the SQL source and regenerate.
2026-02-21 16:58:31 +01:00
ziggie 774ebaf126 invoices/sql_store: switch to targeted queries, default timestamp bounds
Replace all four FilterInvoices call sites with the focused queries
introduced in the previous commit:

  FetchPendingInvoices   → FetchPendingInvoices
  InvoicesSettledSince   → FilterInvoicesBySettleIndex
  InvoicesAddedSince     → FilterInvoicesByAddIndex
  QueryInvoices          → FilterInvoicesForward / FilterInvoicesReverse

The first three are straight 1:1 swaps — the new params structs carry
only the fields that are actually used, and the removed fields (Reverse,
PendingOnly, unused index bounds) were always left at their zero values.

QueryInvoices is restructured more substantially. The forward/reverse
branch now selects between FilterInvoicesForward and
FilterInvoicesReverse, each of which takes a concrete id bound that is
always set:

  forward: AddIndexGet = IndexOffset + 1   (≥ 1 when IndexOffset = 0)
  reverse: AddIndexLet = IndexOffset - 1   (or MaxInt64 when offset = 0)

Timestamp parameters are changed from nullable (sql.NullTime with
OR-based SQL fallbacks) to always-on Go-side defaults, consistent with
the approach used by the payments query:

  createdAfter  → time.Unix(0, 0).UTC()          (epoch, before any invoice)
  createdBefore → time.Date(9999, 12, 31, …)     (far future, no upper cap)

This ensures the planner always sees plain range predicates on
created_at and can use the invoices_created_at_idx index.

The SQLInvoiceQueries interface is updated to expose the five new
methods and drop FilterInvoices.
2026-02-21 16:57:08 +01:00
ziggie 866efbd7fb sqldb/sqlc: add targeted invoice queries
The existing FilterInvoices query uses optional parameters via the
pattern `(col >= param OR param IS NULL)` for every filter. SQLite
cannot use indexes with this pattern because the OR prevents the query
planner from determining at plan time which rows satisfy the condition,
resulting in a full table scan regardless of the available indexes
(invoices_state_idx, invoices_settle_index_idx, and the primary-key
clustered index on id).

Additionally, the conditional ORDER BY:

  ORDER BY CASE WHEN reverse = FALSE ... THEN id ELSE NULL END ASC,
           CASE WHEN reverse = TRUE  ... THEN id ELSE NULL END DESC

prevents the planner from using the index ordering and forces an
explicit sort.

Add five focused replacements, each with a plain sargable predicate and
a direct ORDER BY so the planner can always choose an index scan:

  - FetchPendingInvoices:        WHERE state IN (0, 3)
  - FilterInvoicesBySettleIndex: WHERE settle_index >= $1
  - FilterInvoicesByAddIndex:    WHERE id >= $1
  - FilterInvoicesForward:       WHERE id >= $1 ... ORDER BY id ASC
  - FilterInvoicesReverse:       WHERE id <= $1 ... ORDER BY id DESC

FilterInvoicesForward and FilterInvoicesReverse accept non-nullable
timestamp parameters (created_after, created_before) so the planner
always sees plain range predicates on created_at. Callers supply
Go-side defaults when no date filter is needed, following the same
convention already used by the payments query.

FilterInvoices is kept in this commit so all existing call sites
continue to compile. It will be removed once all callers have been
migrated.
2026-02-21 16:09:03 +01:00
ziggie 99eceba7a5 scripts: switch verify-install.sh from curl to wget
Replace curl with wget for downloading release manifests and
signatures in verify-install.sh. wget handles redirects, retries, and
error reporting more robustly by default, which avoids silent download
failures that caused misleading "Invalid signature!" errors.

Also add error checking to all download calls so failures are reported
immediately with the URL that failed, and log which signature file and
user failed gpg verification.
2026-02-13 10:35:11 +01:00
ziggie b7c4755934 scripts: log failing signature details in verify-install
When gpg --verify fails, include the signature filename, username,
and full GPG output in the error message. Previously only a generic
"Invalid signature!" was printed, making it hard to identify which
signer's signature was invalid.
2026-02-13 10:35:11 +01:00
ziggie 5e3d608761 ci: add verify-release workflow
Add a workflow that triggers when a release is published. It runs
verify-install.sh inside the official Docker image to validate
signatures and binary hashes. If verification fails, the release
is automatically set back to draft.
2026-02-13 10:35:11 +01:00
ziggie ad8b64417f build: classify cmd/* as MEDIUM in PR severity bot
The severity bot was misclassifying CLI client code as HIGH because
filenames like cmd_walletunlocker.go matched the walletunlocker/*
auth/security keyword. Add cmd/* explicitly to the MEDIUM tier and
add a classification rule to prevent filename-based false positives.
2026-02-10 10:48:09 +01:00
ziggie c78a75f5d8 graphdb: reduce log noise from WRN to DBG 2026-01-21 20:25:08 +01:00
ziggie 04dab619cb lncfg: add deprecated no-experimental-endorsement config option
Re-adds the old no-experimental-endorsement config option as a hidden,
deprecated alias for no-experimental-accountability. This ensures
backward compatibility for users who have the old option in their
config files after the rename it.
2026-01-14 09:26:36 +01:00
ziggie 7085f4706d fn: fix printf vet check in TestSomeToOkf Go 1.24+
See also https://github.com/golang/go/issues/60529. Now we need
to use a constant.
2026-01-13 17:31:24 +01:00
ziggie e26a114cdc mod: update the minimum go version to 1.24.11
We update the minimum required go version to build the LND
exectuable to the latest minor release of go 1.24.11.
2026-01-13 16:07:38 +01:00