From 7e3738d773193ee96ea9e471fbf8ec3798fe7b13 Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Tue, 11 Jun 2019 15:11:24 +0200 Subject: [PATCH] rpcserver+channeldb: delete only failed payments if requested --- channeldb/payment_control_test.go | 61 +++++++++++++++++++++++++++---- channeldb/payments.go | 8 +++- rpcserver.go | 11 ++++-- 3 files changed, 68 insertions(+), 12 deletions(-) diff --git a/channeldb/payment_control_test.go b/channeldb/payment_control_test.go index 7949e6109..63499d711 100644 --- a/channeldb/payment_control_test.go +++ b/channeldb/payment_control_test.go @@ -388,6 +388,8 @@ func TestPaymentControlDeleteNonInFligt(t *testing.T) { }, } + var numSuccess, numInflight int + for _, p := range payments { info, attempt, preimg, err := genInfo() if err != nil { @@ -454,11 +456,15 @@ func TestPaymentControlDeleteNonInFligt(t *testing.T) { assertPaymentInfo( t, pControl, info.PaymentHash, info, nil, htlc, ) + + numSuccess++ } else { assertPaymentStatus(t, pControl, info.PaymentHash, StatusInFlight) assertPaymentInfo( t, pControl, info.PaymentHash, info, nil, htlc, ) + + numInflight++ } // If the payment is intended to have a duplicate payment, we @@ -469,27 +475,66 @@ func TestPaymentControlDeleteNonInFligt(t *testing.T) { uint64(duplicateSeqNr), preimg, ) duplicateSeqNr++ + numSuccess++ } } - // Delete payments. - if err := db.DeletePayments(); err != nil { + // Delete all failed payments. + if err := db.DeletePayments(true); err != nil { t.Fatal(err) } - // This should leave the in-flight payment. + // This should leave the succeeded and in-flight payments. dbPayments, err := db.FetchPayments() if err != nil { t.Fatal(err) } - if len(dbPayments) != 1 { - t.Fatalf("expected one payment, got %d", len(dbPayments)) + if len(dbPayments) != numSuccess+numInflight { + t.Fatalf("expected %d payments, got %d", + numSuccess+numInflight, len(dbPayments)) } - status := dbPayments[0].Status - if status != StatusInFlight { - t.Fatalf("expected in-fligth status, got %v", status) + var s, i int + for _, p := range dbPayments { + fmt.Println("fetch payment has status", p.Status) + switch p.Status { + case StatusSucceeded: + s++ + case StatusInFlight: + i++ + } + } + + if s != numSuccess { + t.Fatalf("expected %d succeeded payments , got %d", + numSuccess, s) + } + if i != numInflight { + t.Fatalf("expected %d in-flight payments, got %d", + numInflight, i) + } + + // Now delete all payments except in-flight. + if err := db.DeletePayments(false); err != nil { + t.Fatal(err) + } + + // This should leave the in-flight payment. + dbPayments, err = db.FetchPayments() + if err != nil { + t.Fatal(err) + } + + if len(dbPayments) != numInflight { + t.Fatalf("expected %d payments, got %d", numInflight, + len(dbPayments)) + } + + for _, p := range dbPayments { + if p.Status != StatusInFlight { + t.Fatalf("expected in-fligth status, got %v", p.Status) + } } // Finally, check that we only have a single index left in the payment diff --git a/channeldb/payments.go b/channeldb/payments.go index 1a42d7180..680c798c3 100644 --- a/channeldb/payments.go +++ b/channeldb/payments.go @@ -677,7 +677,7 @@ func fetchPaymentWithSequenceNumber(tx kvdb.RTx, paymentHash lntypes.Hash, } // DeletePayments deletes all completed and failed payments from the DB. -func (db *DB) DeletePayments() error { +func (db *DB) DeletePayments(failedOnly bool) error { return kvdb.Update(db, func(tx kvdb.RwTx) error { payments := tx.ReadWriteBucket(paymentsRootBucket) if payments == nil { @@ -715,6 +715,12 @@ func (db *DB) DeletePayments() error { return nil } + // If we requested to only delete failed payments, we + // can return if this one is not. + if failedOnly && paymentStatus != StatusFailed { + return nil + } + // Add the bucket to the set of buckets we can delete. deleteBuckets = append(deleteBuckets, k) diff --git a/rpcserver.go b/rpcserver.go index 9d1a0d28d..7a09f3d76 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -5710,11 +5710,16 @@ func (r *rpcServer) ListPayments(ctx context.Context, // DeleteAllPayments deletes all outgoing payments from DB. func (r *rpcServer) DeleteAllPayments(ctx context.Context, - _ *lnrpc.DeleteAllPaymentsRequest) (*lnrpc.DeleteAllPaymentsResponse, error) { + req *lnrpc.DeleteAllPaymentsRequest) ( + *lnrpc.DeleteAllPaymentsResponse, error) { - rpcsLog.Debugf("[DeleteAllPayments]") + rpcsLog.Debugf("[DeleteAllPayments] failed_payments_only=%v", + req.FailedPaymentsOnly) - if err := r.server.remoteChanDB.DeletePayments(); err != nil { + err := r.server.remoteChanDB.DeletePayments( + req.FailedPaymentsOnly, + ) + if err != nil { return nil, err }