From 0aec3fd23020e4cbc869022fda18a14e82e76e8d Mon Sep 17 00:00:00 2001 From: "Johan T. Halseth" Date: Tue, 11 Jun 2019 14:59:05 +0200 Subject: [PATCH] rpcserver: filter out non-suceeded payments, include payment status Earlier versions of ListPayments only included completed payments. We return to this behavior by ignore all other payments if the nonSucceeded boolean is not set in the request. --- lntest/itest/lnd_test.go | 8 +++++-- rpcserver.go | 48 ++++++++++++++++++++++++++++++++++------ 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/lntest/itest/lnd_test.go b/lntest/itest/lnd_test.go index e318df06..592e1e39 100644 --- a/lntest/itest/lnd_test.go +++ b/lntest/itest/lnd_test.go @@ -13281,7 +13281,9 @@ func testHoldInvoicePersistence(net *lntest.NetworkHarness, t *harnessTest) { // The payments should now show up in Alice's ListInvoices, with a zero // preimage, indicating they are not yet settled. err = lntest.WaitNoError(func() error { - req := &lnrpc.ListPaymentsRequest{} + req := &lnrpc.ListPaymentsRequest{ + NonSucceeded: true, + } ctxt, _ = context.WithTimeout(ctxt, defaultTimeout) paymentsResp, err := net.Alice.ListPayments(ctxt, req) if err != nil { @@ -13458,7 +13460,9 @@ func testHoldInvoicePersistence(net *lntest.NetworkHarness, t *harnessTest) { // Check that Alice's invoices to be shown as settled and failed // accordingly, and preimages matching up. - req := &lnrpc.ListPaymentsRequest{} + req := &lnrpc.ListPaymentsRequest{ + NonSucceeded: true, + } ctxt, _ = context.WithTimeout(ctxt, defaultTimeout) paymentsResp, err := net.Alice.ListPayments(ctxt, req) if err != nil { diff --git a/rpcserver.go b/rpcserver.go index 58c7af86..ec311e63 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -4131,7 +4131,7 @@ func marshallTopologyChange(topChange *routing.TopologyChange) *lnrpc.GraphTopol // ListPayments returns a list of all outgoing payments. func (r *rpcServer) ListPayments(ctx context.Context, - _ *lnrpc.ListPaymentsRequest) (*lnrpc.ListPaymentsResponse, error) { + req *lnrpc.ListPaymentsRequest) (*lnrpc.ListPaymentsResponse, error) { rpcsLog.Debugf("[ListPayments]") @@ -4140,10 +4140,15 @@ func (r *rpcServer) ListPayments(ctx context.Context, return nil, err } - paymentsResp := &lnrpc.ListPaymentsResponse{ - Payments: make([]*lnrpc.Payment, len(payments)), - } - for i, payment := range payments { + paymentsResp := &lnrpc.ListPaymentsResponse{} + for _, payment := range payments { + // To keep compatibility with the old API, we only return + // non-suceeded payments if requested. + if payment.Status != channeldb.StatusSucceeded && + !req.NonSucceeded { + continue + } + // If a payment attempt has been made we can fetch the route. // Otherwise we'll just populate the RPC response with an empty // one. @@ -4165,8 +4170,13 @@ func (r *rpcServer) ListPayments(ctx context.Context, msatValue := int64(payment.Info.Value) satValue := int64(payment.Info.Value.ToSatoshis()) + status, err := convertPaymentStatus(payment.Status) + if err != nil { + return nil, err + } + paymentHash := payment.Info.PaymentHash - paymentsResp.Payments[i] = &lnrpc.Payment{ + paymentsResp.Payments = append(paymentsResp.Payments, &lnrpc.Payment{ PaymentHash: hex.EncodeToString(paymentHash[:]), Value: satValue, ValueMsat: msatValue, @@ -4176,12 +4186,36 @@ func (r *rpcServer) ListPayments(ctx context.Context, Fee: int64(route.TotalFees().ToSatoshis()), PaymentPreimage: hex.EncodeToString(preimage[:]), PaymentRequest: string(payment.Info.PaymentRequest), - } + Status: status, + }) } return paymentsResp, nil } +// convertPaymentStatus converts a channeldb.PaymentStatus to the type expected +// by the RPC. +func convertPaymentStatus(dbStatus channeldb.PaymentStatus) ( + lnrpc.Payment_PaymentStatus, error) { + + switch dbStatus { + case channeldb.StatusUnknown: + return lnrpc.Payment_UNKNOWN, nil + + case channeldb.StatusInFlight: + return lnrpc.Payment_IN_FLIGHT, nil + + case channeldb.StatusSucceeded: + return lnrpc.Payment_SUCCEEDED, nil + + case channeldb.StatusFailed: + return lnrpc.Payment_FAILED, nil + + default: + return 0, fmt.Errorf("unhandled payment status %v", dbStatus) + } +} + // DeleteAllPayments deletes all outgoing payments from DB. func (r *rpcServer) DeleteAllPayments(ctx context.Context, _ *lnrpc.DeleteAllPaymentsRequest) (*lnrpc.DeleteAllPaymentsResponse, error) {