Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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 {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This function is missing a comment explaining its purpose. According to the style guide, every function must be commented.

// listPaymentDuplicates is the action for the `listpaymentduplicates` command.
// It retrieves and displays duplicate payment records for a given payment hash.
func listPaymentDuplicates(ctx *cli.Context) error {
References
  1. Every function must be commented with its purpose and assumptions. Function comments must begin with the function name and should be complete sentences. (link)

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 {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This function is missing a comment explaining its purpose. According to the style guide, every function must be commented.

// listAllPaymentDuplicates is the action for the `listallpaymentduplicates`
// command. It retrieves and displays all duplicate payment records across all
// payments.
func listAllPaymentDuplicates(ctx *cli.Context) error {
References
  1. Every function must be commented with its purpose and assumptions. Function comments must begin with the function name and should be complete sentences. (link)

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
59 changes: 59 additions & 0 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 @@ -1265,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 Down
4 changes: 4 additions & 0 deletions docs/release-notes/release-notes-0.21.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@
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
Expand Down
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