forked from lightningnetwork/lnd
-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
multi: Add CalcPaymentStats to DB and RPC server
This adds a CalcPaymentStats call to the db, RPC server and dcrlncli. This allows querying the database for a report on the total number of payments tracked. An upstream lnd PR (number 5635) will include a migration that goes through every payment. While the PR has been tested upstream to not be a problem even for nodes with large numbers of payments, there is no actual way to know whether a node _would_ be a problem (due to no existing way to query the total number of payments in the DB). This PR prepares for an upstream port of an lnd version that includes the aforementioned PR by exposing the total counts of payments, which would be migrated. This will allow node operators to evaluate whether the payments should be cleared from the database before performing the migration.
- Loading branch information
Showing
9 changed files
with
1,582 additions
and
1,036 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
package channeldb | ||
|
||
import ( | ||
"github.com/decred/dcrlnd/kvdb" | ||
) | ||
|
||
// PaymentCountStats returns stats about the payments stored in the DB. | ||
type PaymentCountStats struct { | ||
Total uint64 | ||
Failed uint64 | ||
Succeeded uint64 | ||
|
||
HTLCAttempts uint64 | ||
HTLCFailed uint64 | ||
HTLCSettled uint64 | ||
|
||
OldDupePayments uint64 | ||
} | ||
|
||
// CalcPaymentStats goes through the DB, counting up the payment stats. | ||
func (d *DB) CalcPaymentStats() (*PaymentCountStats, error) { | ||
res := &PaymentCountStats{} | ||
err := kvdb.View(d, func(tx kvdb.RTx) error { | ||
paymentsBucket := tx.ReadBucket(paymentsRootBucket) | ||
if paymentsBucket == nil { | ||
return nil | ||
} | ||
|
||
// Standard payments. | ||
return paymentsBucket.ForEach(func(k, v []byte) error { | ||
payBucket := paymentsBucket.NestedReadBucket(k) | ||
if payBucket == nil { | ||
return nil | ||
} | ||
|
||
res.Total += 1 | ||
|
||
htlcsBucket := payBucket.NestedReadBucket(paymentHtlcsBucket) | ||
if htlcsBucket != nil { | ||
var inflight, settled bool | ||
err := htlcsBucket.ForEach(func(k, _ []byte) error { | ||
res.HTLCAttempts += 1 | ||
htlcBucket := htlcsBucket.NestedReadBucket(k) | ||
hasFail := htlcBucket.Get(htlcFailInfoKey) != nil | ||
hasSettle := htlcBucket.Get(htlcSettleInfoKey) != nil | ||
if hasFail { | ||
res.HTLCFailed += 1 | ||
} else if hasSettle { | ||
res.HTLCSettled += 1 | ||
settled = true | ||
} else { | ||
inflight = true | ||
} | ||
return nil | ||
}) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
hasFailureReason := payBucket.Get(paymentFailInfoKey) != nil | ||
|
||
switch { | ||
// If any of the the HTLCs did succeed and there are no HTLCs in | ||
// flight, the payment succeeded. | ||
case !inflight && settled: | ||
res.Succeeded += 1 | ||
|
||
// If we have no in-flight HTLCs, and the payment failure is set, the | ||
// payment is considered failed. | ||
case !inflight && hasFailureReason: | ||
res.Failed += 1 | ||
} | ||
|
||
} | ||
|
||
// Old duplicate payments. | ||
dupBucket := payBucket.NestedReadBucket(duplicatePaymentsBucket) | ||
if dupBucket == nil { | ||
return nil | ||
} | ||
|
||
return dupBucket.ForEach(func(k, v []byte) error { | ||
subBucket := dupBucket.NestedReadBucket(k) | ||
if subBucket == nil { | ||
return nil | ||
} | ||
res.OldDupePayments += 1 | ||
return nil | ||
}) | ||
}) | ||
}, func() {}) | ||
|
||
return res, err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package main | ||
|
||
import ( | ||
"github.com/decred/dcrlnd/lnrpc" | ||
"github.com/urfave/cli" | ||
) | ||
|
||
var calcPayStatsCommand = cli.Command{ | ||
Name: "calcpaystats", | ||
Usage: "Scans the db and generates a report on total payment counts.", | ||
ArgsUsage: "", | ||
Category: "Payments", | ||
Description: ` | ||
Goes through the DB and generates a report on total number of payments | ||
made, settled and failed. | ||
NOTE: This requires a scan through the entire set of payments in the DB, | ||
so it may be slow on nodes that have a large number of payments. | ||
`, | ||
Action: actionDecorator(calcPayStats), | ||
} | ||
|
||
func calcPayStats(ctx *cli.Context) error { | ||
ctxc := getContext() | ||
|
||
client, cleanUp := getClient(ctx) | ||
defer cleanUp() | ||
|
||
req := &lnrpc.CalcPaymentStatsRequest{} | ||
resp, err := client.CalcPaymentStats(ctxc, req) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
printRespJSON(resp) | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.