diff --git a/lntest/itest/lnd_test.go b/lntest/itest/lnd_test.go index e318df063..592e1e390 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 58c7af860..ec311e630 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) {