Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
452ea71
lnd+paymentsdb: introduce harness for the payment sql backend
ziggie1984 Sep 29, 2025
644f8f0
sqldb: add payment sql tables
ziggie1984 Sep 29, 2025
6c2a263
lnd: make the payment schema migration available for testing
ziggie1984 Sep 29, 2025
31c374f
docs: add release-notes
ziggie1984 Oct 12, 2025
aedfddd
sqldb: add index and comment to payment tables
ziggie1984 Oct 15, 2025
e803b11
multi: add relevant queries for QueryPayments implemenation
ziggie1984 Oct 12, 2025
208ef7d
paymentsdb: add new internal error
ziggie1984 Oct 12, 2025
9e07820
paymentsdb: implement QueryPayments for sql backend
ziggie1984 Oct 12, 2025
dfaf109
paymentsdb: implement FetchPayment for sql backend
ziggie1984 Oct 15, 2025
9fb5a8f
docs: add release-notes
ziggie1984 Oct 12, 2025
86243fd
paymentsdb: enhance some godoc function descriptions
ziggie1984 Nov 11, 2025
6a1eb35
sqldb: Change payment_intent relationship to payment table
ziggie1984 Nov 11, 2025
c47191e
sqldb: add queries for deleting a payment and attempts
ziggie1984 Oct 15, 2025
706c95c
paymentsdb: add query to only fetch resolution type for HTLCs
ziggie1984 Nov 13, 2025
7f6f987
paymentsdb: implement DeleteFailedAttempts for sql backend
ziggie1984 Oct 15, 2025
c60b62f
paymentsdb: implement DeletePayment for sql backend
ziggie1984 Oct 15, 2025
164a325
sqldb+paymentsdb: add queries to insert all relavant data
ziggie1984 Oct 15, 2025
2014049
paymentsdb: implement InitPayment for sql backend
ziggie1984 Oct 15, 2025
061a357
paymentsdb: add note to RegisterAttempt
ziggie1984 Nov 13, 2025
2efa975
paymentsdb: implement RegisterAttempt for sql backend
ziggie1984 Oct 15, 2025
de67e95
paymentsdb: verify total amount for last hop in the blinded path
ziggie1984 Nov 11, 2025
0dd69fa
paymentsdb: implement SettleAttempt for sql backend
ziggie1984 Oct 15, 2025
af54d39
docs: add release-notes
ziggie1984 Oct 15, 2025
d0a2741
paymentsdb: fix formatting for sql QueryPayments
ziggie1984 Nov 20, 2025
9afae14
paymentsdb: remove pointer receiver dependecy to make it more robust
ziggie1984 Nov 20, 2025
f108689
paymentsdb: rename paymentsBatchData
ziggie1984 Nov 20, 2025
7c02a30
multi: implement Fail method for sql backend
ziggie1984 Oct 15, 2025
a0b480f
paymentsdb: implement FailAttempt for sql backend
ziggie1984 Oct 15, 2025
06dbe95
paymentsdb: implement DeletePayments for sql backend
ziggie1984 Oct 15, 2025
b04c118
paymentsdb: add a wrapper to the fetchpayment method
ziggie1984 Nov 13, 2025
44483b0
paymentsdb: rename functions and variables
ziggie1984 Nov 20, 2025
9764885
paymentsdb: use batch function when querying for resolutions
ziggie1984 Nov 20, 2025
a2c77fc
paymentsdb: implement FetchInFlightPayments for sql backend
ziggie1984 Oct 15, 2025
8b4cca7
paymentsdb: added unit test for computePaymentStatusFromResolutions
ziggie1984 Nov 21, 2025
17e23fa
docs: add release-notes
ziggie1984 Nov 13, 2025
7d9d424
paymentsdb: remove kvstore from sql db implementation
ziggie1984 Oct 15, 2025
709a1ad
paymentsdb: refactor test helpers
ziggie1984 Oct 15, 2025
06dc82f
paymentsdb: make QueryPayments test db agnostic
ziggie1984 Oct 15, 2025
cf249a9
paymentsdb: fix test case before testing sql backend
ziggie1984 Oct 15, 2025
ce11259
paymentsdb: add harness to run payment db agnostic tests
ziggie1984 Oct 15, 2025
535f1e9
paymentsdb: introduce a harness interface
ziggie1984 Nov 14, 2025
13bd9e9
paymentsdb: make specific kv store tests only available via build tag
ziggie1984 Nov 14, 2025
e4053f6
itest: fix list_payments accuracy edge case
ziggie1984 Oct 15, 2025
d398308
lnrpc: fix linter
ziggie1984 Oct 16, 2025
bbc2068
paymentsdb: add more comments
ziggie1984 Oct 17, 2025
63d024c
paymentsdb: add firstcustom records to unit tests
ziggie1984 Oct 17, 2025
276c831
paymentsdb: add unit test for FetchInflightPayments method
ziggie1984 Nov 24, 2025
006be9b
docs: add release-notes
ziggie1984 Oct 16, 2025
98992af
multi: thread context through DeletePayment
ziggie1984 Oct 20, 2025
2ad437f
multi: thread context through DeletePayments
ziggie1984 Oct 20, 2025
1833fce
multi: thread context through FetchPayment
ziggie1984 Oct 20, 2025
8e32ffc
multi: thread context through FetchInflightPayments
ziggie1984 Oct 20, 2025
ff63feb
multi: thread context through InitPayment
ziggie1984 Oct 20, 2025
a4a8ddc
multi: thread context through RegisterAttempt method
ziggie1984 Nov 11, 2025
d779506
multi: thread context through SettleAttempt
ziggie1984 Oct 21, 2025
bf5f9a2
multi: thread context through FailAttempt
ziggie1984 Oct 21, 2025
f18546a
multi: thread context through Fail payment functions
ziggie1984 Oct 21, 2025
d6015bb
multi: thread context through DeleteFailedAttempts
ziggie1984 Oct 21, 2025
d266bc4
docs: add release notes
ziggie1984 Oct 21, 2025
09c640e
routing: Add context to requestRoute
ziggie1984 Oct 21, 2025
9ea8bbe
multi: thread context through payment lifecyle functions
ziggie1984 Oct 21, 2025
3301488
routing: Thread context through failPaymentAndAttempt
ziggie1984 Oct 21, 2025
8072ec9
routing: add context to failAttempt
ziggie1984 Oct 21, 2025
1259c32
routing: add context to reloadInflightAttempts
ziggie1984 Oct 21, 2025
dcf2fb6
routing: add context to reloadPayment method
ziggie1984 Oct 21, 2025
2d1ce51
multi: thread context through SendPayment
ziggie1984 Nov 17, 2025
13a1d3a
docs: add release-notes
ziggie1984 Oct 21, 2025
bf41d73
paymentsdb: make delete payments test db agnostic
ziggie1984 Nov 15, 2025
9b892fc
routing: add TODO to also delete payments without HTLCs
ziggie1984 Nov 16, 2025
e5079a8
multi: move failed attempt cfg option to the router subsytem
ziggie1984 Nov 18, 2025
bb1ee80
paymentsdb: refactor test helpers
ziggie1984 Nov 21, 2025
3467fae
paymentsdb: add additional test for first hop data
ziggie1984 Nov 24, 2025
840a7f9
paymentsdb: add more unit tests to increase coverage
ziggie1984 Nov 24, 2025
8c106c7
docs: add release-notes
ziggie1984 Nov 24, 2025
d5d49a1
paymentsdb+sqldb: add migration related query
ziggie1984 Jan 10, 2026
c78d0e9
sqldb+payments: add payment_duplicates for legacy duplicate payments
ziggie1984 Jan 10, 2026
eee2004
payments/migration1: copy core payment helpers and sqlc types
ziggie1984 Jan 10, 2026
fb174f2
payments/migration1: migrate payments and validate including duplicates
ziggie1984 Jan 10, 2026
e5a421b
payments/migration1: add sql_migration_test suite and helpers
ziggie1984 Jan 10, 2026
26cd720
payments/migration1: add external migration test and README
ziggie1984 Jan 10, 2026
579dfdf
payments/migration1: wire KV→SQL migration and add tombstone guard
ziggie1984 Jan 10, 2026
5e24738
docs: add release-notes
ziggie1984 Jan 10, 2026
83a9946
mod: update new direct dependency via go mod tidy
ziggie1984 Jan 10, 2026
3a0b724
git: add sqlite db files to the gitignore file
ziggie1984 Jan 11, 2026
572db06
paymentsdb: add sql duplicate payment fetchers
ziggie1984 Jan 11, 2026
950e213
paymentsdb: test duplicate payment fetch APIs
ziggie1984 Jan 11, 2026
f44ef04
lnrpc: add duplicate payment list RPCs
ziggie1984 Jan 11, 2026
2d2cd8a
lncli: add hidden commands for duplicate payments
ziggie1984 Jan 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ mobile/*_generated.go
*.hex
*.db
*.bin
*.sqlite
*.sqlite-shm
*.sqlite-wal

vendor
*.idea
Expand Down
65 changes: 65 additions & 0 deletions cmd/commands/cmd_payments.go
Original file line number Diff line number Diff line change
Expand Up @@ -1525,6 +1525,71 @@
return nil
}

var listPaymentDuplicatesCommand = cli.Command{
Name: "listpaymentduplicates",
Category: "Payments",
Usage: "List duplicate payments for a given payment hash.",
Hidden: true,
Flags: []cli.Flag{
cli.StringFlag{
Name: "payment_hash",
Usage: "hex-encoded payment hash to query",
},
},
Action: actionDecorator(listPaymentDuplicates),
}

func listPaymentDuplicates(ctx *cli.Context) error {
if !ctx.IsSet("payment_hash") {
return fmt.Errorf("payment_hash is required")
}

hashBytes, err := hex.DecodeString(ctx.String("payment_hash"))
if err != nil {
return fmt.Errorf("error decoding payment_hash: %w", err)
}

ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()

req := &lnrpc.ListPaymentDuplicatesRequest{
PaymentHash: hashBytes,
}

resp, err := client.ListPaymentDuplicates(ctxc, req)
if err != nil {
return err
}

printRespJSON(resp)
return nil

Check failure on line 1566 in cmd/commands/cmd_payments.go

View workflow job for this annotation

GitHub Actions / Lint code

return with no blank line before (nlreturn)
}

var listAllPaymentDuplicatesCommand = cli.Command{
Name: "listallpaymentduplicates",
Category: "Payments",
Usage: "List duplicate payments across all payments.",
Hidden: true,
Action: actionDecorator(listAllPaymentDuplicates),
}

func listAllPaymentDuplicates(ctx *cli.Context) error {
ctxc := getContext()
client, cleanUp := getClient(ctx)
defer cleanUp()

req := &lnrpc.ListAllPaymentDuplicatesRequest{}

resp, err := client.ListAllPaymentDuplicates(ctxc, req)
if err != nil {
return err
}

printRespJSON(resp)
return nil

Check failure on line 1590 in cmd/commands/cmd_payments.go

View workflow job for this annotation

GitHub Actions / Lint code

return with no blank line before (nlreturn)
}

var forwardingHistoryCommand = cli.Command{
Name: "fwdinghistory",
Category: "Payments",
Expand Down
2 changes: 2 additions & 0 deletions cmd/commands/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,8 @@ func Main() {
ListChannelsCommand,
closedChannelsCommand,
listPaymentsCommand,
listPaymentDuplicatesCommand,
listAllPaymentDuplicatesCommand,
describeGraphCommand,
getNodeMetricsCommand,
getChanInfoCommand,
Expand Down
112 changes: 90 additions & 22 deletions config_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ import (
"github.com/lightningnetwork/lnd/macaroons"
"github.com/lightningnetwork/lnd/msgmux"
paymentsdb "github.com/lightningnetwork/lnd/payments/db"
paymentsmig1 "github.com/lightningnetwork/lnd/payments/db/migration1"
paymentsmig1sqlc "github.com/lightningnetwork/lnd/payments/db/migration1/sqlc"
"github.com/lightningnetwork/lnd/rpcperms"
"github.com/lightningnetwork/lnd/signal"
"github.com/lightningnetwork/lnd/sqldb"
Expand All @@ -76,6 +78,10 @@ const (
// graphMigration is the version number for the graph migration
// that migrates the KV graph to the native SQL schema.
graphMigration = 10

// paymentMigration is the version number for the payments migration
// that migrates KV payments to the native SQL schema.
paymentMigration = 12
)

// GrpcRegistrar is an interface that must be satisfied by an external subserver
Expand Down Expand Up @@ -1153,6 +1159,32 @@ func (d *DefaultDatabaseBuilder) BuildDatabase(
return nil
}

paymentMig := func(tx *sqlc.Queries) error {
var err error
err = paymentsmig1.MigratePaymentsKVToSQL(
ctx,
dbs.ChanStateDB.Backend,
paymentsmig1sqlc.New(tx.GetTx()),
&paymentsmig1.SQLStoreConfig{
QueryCfg: queryCfg,
},
)
if err != nil {
return fmt.Errorf("failed to migrate "+
"payments to SQL: %w", err)
}

// Set the payments bucket tombstone to
// indicate that the migration has been
// completed.
d.logger.Debugf("Setting payments bucket " +
"tombstone")

return paymentsdb.SetPaymentsBucketTombstone(
dbs.ChanStateDB.Backend,
)
}

// Make sure we attach the custom migration function to
// the correct migration version.
for i := 0; i < len(migrations); i++ {
Expand All @@ -1162,11 +1194,17 @@ func (d *DefaultDatabaseBuilder) BuildDatabase(
migrations[i].MigrationFn = invoiceMig

continue

case graphMigration:
migrations[i].MigrationFn = graphMig

continue

case paymentMigration:
migrations[i].MigrationFn = paymentMig

continue

default:
}

Expand Down Expand Up @@ -1228,6 +1266,23 @@ func (d *DefaultDatabaseBuilder) BuildDatabase(

return nil, nil, err
}

// Create the payments DB.
//
// NOTE: In the regular build, this will construct a kvdb
// backed payments backend. With the test_native_sql tag, it
// will build a SQL payments backend.
sqlPaymentsDB, err := d.getPaymentsStore(
baseDB, dbs.ChanStateDB.Backend,
)
if err != nil {
err = fmt.Errorf("unable to get payments store: %w",
err)

return nil, nil, err
}

dbs.PaymentsDB = sqlPaymentsDB
} else {
// Check if the invoice bucket tombstone is set. If it is, we
// need to return and ask the user switch back to using the
Expand All @@ -1248,6 +1303,27 @@ func (d *DefaultDatabaseBuilder) BuildDatabase(
return nil, nil, err
}

// Check if the payments bucket tombstone is set. If it is, we
// need to return and ask the user switch back to using the
// native SQL store.
ripPayments, err := paymentsdb.GetPaymentsBucketTombstone(
dbs.ChanStateDB.Backend,
)
if err != nil {
err = fmt.Errorf("unable to check payments bucket "+
"tombstone: %w", err)
d.logger.Error(err)

return nil, nil, err
}
if ripPayments {
err = fmt.Errorf("payments bucket tombstoned, please " +
"switch back to native SQL")
d.logger.Error(err)

return nil, nil, err
}

dbs.InvoiceDB = dbs.ChanStateDB

graphStore, err = graphdb.NewKVStore(
Expand All @@ -1256,40 +1332,32 @@ func (d *DefaultDatabaseBuilder) BuildDatabase(
if err != nil {
return nil, nil, err
}
}

dbs.GraphDB, err = graphdb.NewChannelGraph(graphStore, chanGraphOpts...)
if err != nil {
cleanUp()
// Create the payments DB.
kvPaymentsDB, err := paymentsdb.NewKVStore(
dbs.ChanStateDB,
)
if err != nil {
cleanUp()

err = fmt.Errorf("unable to open channel graph DB: %w", err)
d.logger.Error(err)
err = fmt.Errorf("unable to open payments DB: %w", err)
d.logger.Error(err)

return nil, nil, err
}
return nil, nil, err
}

// Mount the payments DB which is only KV for now.
//
// TODO(ziggie): Add support for SQL payments DB.
// Mount the payments DB for the KV store.
paymentsDBOptions := []paymentsdb.OptionModifier{
paymentsdb.WithKeepFailedPaymentAttempts(
cfg.KeepFailedPaymentAttempts,
),
dbs.PaymentsDB = kvPaymentsDB
}
kvPaymentsDB, err := paymentsdb.NewKVStore(
dbs.ChanStateDB,
paymentsDBOptions...,
)

dbs.GraphDB, err = graphdb.NewChannelGraph(graphStore, chanGraphOpts...)
if err != nil {
cleanUp()

err = fmt.Errorf("unable to open payments DB: %w", err)
err = fmt.Errorf("unable to open channel graph DB: %w", err)
d.logger.Error(err)

return nil, nil, err
}
dbs.PaymentsDB = kvPaymentsDB

// Wrap the watchtower client DB and make sure we clean up.
if cfg.WtClient.Active {
Expand Down
11 changes: 11 additions & 0 deletions config_prod.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"context"

"github.com/lightningnetwork/lnd/kvdb"
paymentsdb "github.com/lightningnetwork/lnd/payments/db"
"github.com/lightningnetwork/lnd/sqldb"
"github.com/lightningnetwork/lnd/sqldb/sqlc"
)

Expand All @@ -24,3 +26,12 @@ func (d *DefaultDatabaseBuilder) getSQLMigration(ctx context.Context,

return nil, false
}

// getPaymentsStore returns a paymentsdb.DB backed by a paymentsdb.KVStore
// implementation.
func (d *DefaultDatabaseBuilder) getPaymentsStore(_ *sqldb.BaseDB,
kvBackend kvdb.Backend,
opts ...paymentsdb.OptionModifier) (paymentsdb.DB, error) {

return paymentsdb.NewKVStore(kvBackend, opts...)
}
29 changes: 29 additions & 0 deletions config_test_native_sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ package lnd

import (
"context"
"database/sql"

"github.com/lightningnetwork/lnd/kvdb"
"github.com/lightningnetwork/lnd/lncfg"
paymentsdb "github.com/lightningnetwork/lnd/payments/db"
"github.com/lightningnetwork/lnd/sqldb"
"github.com/lightningnetwork/lnd/sqldb/sqlc"
)

Expand All @@ -25,3 +29,28 @@ func (d *DefaultDatabaseBuilder) getSQLMigration(_ context.Context,
return nil, false
}
}

// getPaymentsStore returns a paymentsdb.DB backed by a paymentsdb.SQLStore
// implementation.
func (d *DefaultDatabaseBuilder) getPaymentsStore(baseDB *sqldb.BaseDB,
kvBackend kvdb.Backend,
opts ...paymentsdb.OptionModifier) (paymentsdb.DB, error) {

paymentsExecutor := sqldb.NewTransactionExecutor(
baseDB, func(tx *sql.Tx) paymentsdb.SQLQueries {
return baseDB.WithTx(tx)
},
)

queryConfig := d.cfg.DB.Sqlite.QueryConfig
if d.cfg.DB.Backend == lncfg.PostgresBackend {
queryConfig = d.cfg.DB.Postgres.QueryConfig
}

return paymentsdb.NewSQLStore(
&paymentsdb.SQLStoreConfig{
QueryCfg: &queryConfig,
},
paymentsExecutor, opts...,
)
}
28 changes: 28 additions & 0 deletions docs/release-notes/release-notes-0.21.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,32 @@
code](https://github.com/lightningnetwork/lnd/pull/10338) to prevent the
need for maintenance as the sqlc code evolves.

* Payment Store SQL implementation and migration project:
* Introduce an [abstract payment
store](https://github.com/lightningnetwork/lnd/pull/10153) interface and
refacotor the payment related LND code to make it more modular.
* Implement the SQL backend for the [payments
database](https://github.com/lightningnetwork/lnd/pull/9147)
* Implement query methods (QueryPayments,FetchPayment) for the [payments db
SQL Backend](https://github.com/lightningnetwork/lnd/pull/10287)
* Implement insert methods for the [payments db
SQL Backend](https://github.com/lightningnetwork/lnd/pull/10291)
* Implement third(final) Part of SQL backend [payment
functions](https://github.com/lightningnetwork/lnd/pull/10368)
* Finalize SQL payments implementation [enabling unit and itests
for SQL backend](https://github.com/lightningnetwork/lnd/pull/10292)
* [Thread context through payment
db functions Part 1](https://github.com/lightningnetwork/lnd/pull/10307)
* [Thread context through payment
db functions Part 2](https://github.com/lightningnetwork/lnd/pull/10308)
* [Finalize SQL implementation for
payments db](https://github.com/lightningnetwork/lnd/pull/10373)
* [Add the KV-to-SQL payment
migration](https://github.com/lightningnetwork/lnd/pull/10485) with
comprehensive tests and build tag "test_native_sql" gated wiring into the
payment flow.


## Code Health

## Tooling and Documentation
Expand All @@ -146,7 +172,9 @@
* Boris Nagaev
* Elle Mouton
* Erick Cestari
* Gijs van Dam
* hieblmi
* Mohamed Awnallah
* Nishant Bansal
* Pins
* Ziggie
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ require (
github.com/opencontainers/runc v1.1.14 // indirect
github.com/ory/dockertest/v3 v3.10.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/pmezard/go-difflib v1.0.0
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.26.0 // indirect
github.com/prometheus/procfs v0.6.0 // indirect
Expand Down
Loading
Loading