Skip to content

Commit a0044ba

Browse files
authored
Merge pull request #9147 from ziggie1984/introduce-sql-schema-payments
[Part 1|3] Introduce SQL Payment schema into LND
2 parents 1c2ff4a + 75b3a35 commit a0044ba

File tree

9 files changed

+738
-23
lines changed

9 files changed

+738
-23
lines changed

config_builder.go

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1225,6 +1225,26 @@ func (d *DefaultDatabaseBuilder) BuildDatabase(
12251225

12261226
return nil, nil, err
12271227
}
1228+
1229+
// Create the payments DB.
1230+
//
1231+
// NOTE: In the regular build, this will construct a kvdb
1232+
// backed payments backend. With the test_native_sql tag, it
1233+
// will build a SQL payments backend.
1234+
sqlPaymentsDB, err := d.getPaymentsStore(
1235+
baseDB, dbs.ChanStateDB.Backend,
1236+
paymentsdb.WithKeepFailedPaymentAttempts(
1237+
cfg.KeepFailedPaymentAttempts,
1238+
),
1239+
)
1240+
if err != nil {
1241+
err = fmt.Errorf("unable to get payments store: %w",
1242+
err)
1243+
1244+
return nil, nil, err
1245+
}
1246+
1247+
dbs.PaymentsDB = sqlPaymentsDB
12281248
} else {
12291249
// Check if the invoice bucket tombstone is set. If it is, we
12301250
// need to return and ask the user switch back to using the
@@ -1253,40 +1273,35 @@ func (d *DefaultDatabaseBuilder) BuildDatabase(
12531273
if err != nil {
12541274
return nil, nil, err
12551275
}
1256-
}
12571276

1258-
dbs.GraphDB, err = graphdb.NewChannelGraph(graphStore, chanGraphOpts...)
1259-
if err != nil {
1260-
cleanUp()
1277+
// Create the payments DB.
1278+
kvPaymentsDB, err := paymentsdb.NewKVStore(
1279+
dbs.ChanStateDB,
1280+
paymentsdb.WithKeepFailedPaymentAttempts(
1281+
cfg.KeepFailedPaymentAttempts,
1282+
),
1283+
)
1284+
if err != nil {
1285+
cleanUp()
12611286

1262-
err = fmt.Errorf("unable to open channel graph DB: %w", err)
1263-
d.logger.Error(err)
1287+
err = fmt.Errorf("unable to open payments DB: %w", err)
1288+
d.logger.Error(err)
12641289

1265-
return nil, nil, err
1266-
}
1290+
return nil, nil, err
1291+
}
12671292

1268-
// Mount the payments DB which is only KV for now.
1269-
//
1270-
// TODO(ziggie): Add support for SQL payments DB.
1271-
// Mount the payments DB for the KV store.
1272-
paymentsDBOptions := []paymentsdb.OptionModifier{
1273-
paymentsdb.WithKeepFailedPaymentAttempts(
1274-
cfg.KeepFailedPaymentAttempts,
1275-
),
1293+
dbs.PaymentsDB = kvPaymentsDB
12761294
}
1277-
kvPaymentsDB, err := paymentsdb.NewKVStore(
1278-
dbs.ChanStateDB,
1279-
paymentsDBOptions...,
1280-
)
1295+
1296+
dbs.GraphDB, err = graphdb.NewChannelGraph(graphStore, chanGraphOpts...)
12811297
if err != nil {
12821298
cleanUp()
12831299

1284-
err = fmt.Errorf("unable to open payments DB: %w", err)
1300+
err = fmt.Errorf("unable to open channel graph DB: %w", err)
12851301
d.logger.Error(err)
12861302

12871303
return nil, nil, err
12881304
}
1289-
dbs.PaymentsDB = kvPaymentsDB
12901305

12911306
// Wrap the watchtower client DB and make sure we clean up.
12921307
if cfg.WtClient.Active {

config_prod.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
"context"
77

88
"github.com/lightningnetwork/lnd/kvdb"
9+
paymentsdb "github.com/lightningnetwork/lnd/payments/db"
10+
"github.com/lightningnetwork/lnd/sqldb"
911
"github.com/lightningnetwork/lnd/sqldb/sqlc"
1012
)
1113

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

2527
return nil, false
2628
}
29+
30+
// getPaymentsStore returns a paymentsdb.DB backed by a paymentsdb.KVStore
31+
// implementation.
32+
func (d *DefaultDatabaseBuilder) getPaymentsStore(_ *sqldb.BaseDB,
33+
kvBackend kvdb.Backend,
34+
opts ...paymentsdb.OptionModifier) (paymentsdb.DB, error) {
35+
36+
return paymentsdb.NewKVStore(kvBackend, opts...)
37+
}

config_test_native_sql.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@ package lnd
44

55
import (
66
"context"
7+
"database/sql"
78

89
"github.com/lightningnetwork/lnd/kvdb"
10+
"github.com/lightningnetwork/lnd/lncfg"
11+
paymentsdb "github.com/lightningnetwork/lnd/payments/db"
12+
"github.com/lightningnetwork/lnd/sqldb"
913
"github.com/lightningnetwork/lnd/sqldb/sqlc"
1014
)
1115

@@ -25,3 +29,28 @@ func (d *DefaultDatabaseBuilder) getSQLMigration(_ context.Context,
2529
return nil, false
2630
}
2731
}
32+
33+
// getPaymentsStore returns a paymentsdb.DB backed by a paymentsdb.SQLStore
34+
// implementation.
35+
func (d *DefaultDatabaseBuilder) getPaymentsStore(baseDB *sqldb.BaseDB,
36+
kvBackend kvdb.Backend,
37+
opts ...paymentsdb.OptionModifier) (paymentsdb.DB, error) {
38+
39+
paymentsExecutor := sqldb.NewTransactionExecutor(
40+
baseDB, func(tx *sql.Tx) paymentsdb.SQLQueries {
41+
return baseDB.WithTx(tx)
42+
},
43+
)
44+
45+
queryConfig := d.cfg.DB.Sqlite.QueryConfig
46+
if d.cfg.DB.Backend == lncfg.PostgresBackend {
47+
queryConfig = d.cfg.DB.Postgres.QueryConfig
48+
}
49+
50+
return paymentsdb.NewSQLStore(
51+
&paymentsdb.SQLStoreConfig{
52+
QueryCfg: &queryConfig,
53+
},
54+
paymentsExecutor, opts...,
55+
)
56+
}

docs/release-notes/release-notes-0.21.0.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,17 @@
4848

4949
## Database
5050

51+
* Payment Store SQL implementation and migration project:
52+
* Introduce an [abstract payment
53+
store](https://github.com/lightningnetwork/lnd/pull/10153) interface and
54+
refacotor the payment related LND code to make it more modular.
55+
* Implement the SQL backend for the [payments
56+
database](https://github.com/lightningnetwork/lnd/pull/9147)
57+
5158
## Code Health
5259

5360
## Tooling and Documentation
5461

5562
# Contributors (Alphabetical Order)
63+
64+
* Ziggie

payments/db/sql_store.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package paymentsdb
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/lightningnetwork/lnd/sqldb"
7+
)
8+
9+
// SQLQueries is a subset of the sqlc.Querier interface that can be used to
10+
// execute queries against the SQL payments tables.
11+
type SQLQueries interface {
12+
}
13+
14+
// BatchedSQLQueries is a version of the SQLQueries that's capable
15+
// of batched database operations.
16+
type BatchedSQLQueries interface {
17+
SQLQueries
18+
sqldb.BatchedTx[SQLQueries]
19+
}
20+
21+
// SQLStore represents a storage backend.
22+
type SQLStore struct {
23+
// TODO(ziggie): Remove the KVStore once all the interface functions are
24+
// implemented.
25+
KVStore
26+
27+
cfg *SQLStoreConfig
28+
db BatchedSQLQueries
29+
30+
// keepFailedPaymentAttempts is a flag that indicates whether we should
31+
// keep failed payment attempts in the database.
32+
keepFailedPaymentAttempts bool
33+
}
34+
35+
// A compile-time constraint to ensure SQLStore implements DB.
36+
var _ DB = (*SQLStore)(nil)
37+
38+
// SQLStoreConfig holds the configuration for the SQLStore.
39+
type SQLStoreConfig struct {
40+
// QueryConfig holds configuration values for SQL queries.
41+
QueryCfg *sqldb.QueryConfig
42+
}
43+
44+
// NewSQLStore creates a new SQLStore instance given an open
45+
// BatchedSQLPaymentsQueries storage backend.
46+
func NewSQLStore(cfg *SQLStoreConfig, db BatchedSQLQueries,
47+
options ...OptionModifier) (*SQLStore, error) {
48+
49+
opts := DefaultOptions()
50+
for _, applyOption := range options {
51+
applyOption(opts)
52+
}
53+
54+
if opts.NoMigration {
55+
return nil, fmt.Errorf("the NoMigration option is not yet " +
56+
"supported for SQL stores")
57+
}
58+
59+
return &SQLStore{
60+
cfg: cfg,
61+
db: db,
62+
keepFailedPaymentAttempts: opts.KeepFailedPaymentAttempts,
63+
}, nil
64+
}
65+
66+
// A compile-time constraint to ensure SQLStore implements DB.
67+
var _ DB = (*SQLStore)(nil)

sqldb/migrations_dev.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,10 @@
22

33
package sqldb
44

5-
var migrationAdditions []MigrationConfig
5+
var migrationAdditions = []MigrationConfig{
6+
{
7+
Name: "000009_payments",
8+
Version: 11,
9+
SchemaVersion: 9,
10+
},
11+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
-- ─────────────────────────────────────────────
2+
-- Drop custom TLV record tables first (they have no dependents).
3+
-- ─────────────────────────────────────────────
4+
5+
DROP TABLE IF EXISTS payment_hop_custom_records;
6+
DROP TABLE IF EXISTS payment_attempt_first_hop_custom_records;
7+
DROP TABLE IF EXISTS payment_first_hop_custom_records;
8+
9+
-- ─────────────────────────────────────────────
10+
-- Drop per-hop payload tables before dropping the base hops table.
11+
-- ─────────────────────────────────────────────
12+
13+
DROP TABLE IF EXISTS payment_route_hop_blinded;
14+
DROP TABLE IF EXISTS payment_route_hop_amp;
15+
DROP TABLE IF EXISTS payment_route_hop_mpp;
16+
17+
-- ─────────────────────────────────────────────
18+
-- Drop route hops table and its indexes.
19+
-- ─────────────────────────────────────────────
20+
21+
DROP INDEX IF EXISTS idx_route_hops_htlc_attempt_index;
22+
DROP TABLE IF EXISTS payment_route_hops;
23+
24+
-- ─────────────────────────────────────────────
25+
-- Drop HTLC attempt resolution table and its indexes.
26+
-- ─────────────────────────────────────────────
27+
28+
DROP INDEX IF EXISTS idx_htlc_resolutions_type;
29+
DROP INDEX IF EXISTS idx_htlc_resolutions_time;
30+
DROP TABLE IF EXISTS payment_htlc_attempt_resolutions;
31+
32+
-- ─────────────────────────────────────────────
33+
-- Drop HTLC attempts table and its indexes.
34+
-- ─────────────────────────────────────────────
35+
36+
DROP INDEX IF EXISTS idx_htlc_payment_id;
37+
DROP INDEX IF EXISTS idx_htlc_attempt_index;
38+
DROP INDEX IF EXISTS idx_htlc_payment_hash;
39+
DROP INDEX IF EXISTS idx_htlc_attempt_time;
40+
DROP TABLE IF EXISTS payment_htlc_attempts;
41+
42+
-- ─────────────────────────────────────────────
43+
-- Drop payments table and its indexes.
44+
-- ─────────────────────────────────────────────
45+
46+
DROP INDEX IF EXISTS idx_payments_created_at;
47+
DROP TABLE IF EXISTS payments;
48+
49+
-- ─────────────────────────────────────────────
50+
-- Drop payment intents table and its indexes.
51+
-- ─────────────────────────────────────────────
52+
53+
DROP INDEX IF EXISTS idx_payment_intents_type;
54+
DROP TABLE IF EXISTS payment_intents;

0 commit comments

Comments
 (0)