From b362314340ecfa67a33ece4827674755f031dd32 Mon Sep 17 00:00:00 2001 From: Tom Kirkpatrick Date: Fri, 9 Feb 2024 15:26:16 +0000 Subject: [PATCH] Include outgoing payment description in audit memo --- accounting/entries.go | 19 +++++++++++++++---- accounting/filter.go | 41 +++++++++++++++++++++++++++++++++++------ 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/accounting/entries.go b/accounting/entries.go index 3de443c..208bde2 100644 --- a/accounting/entries.go +++ b/accounting/entries.go @@ -401,11 +401,22 @@ func paymentReference(sequenceNumber uint64, preimage lntypes.Preimage) string { // paymentNote creates a note for payments from our node. // nolint: interfacer -func paymentNote(dest *route.Vertex) string { - if dest == nil { +func paymentNote(dest *route.Vertex, memo *string) string { + var notes []string + + if memo != nil && *memo != "" { + notes = append(notes, fmt.Sprintf("memo: %v", *memo)) + } + + if dest != nil { + notes = append(notes, fmt.Sprintf("destination: %v", dest)) + } + + if len(notes) == 0 { return "" } - return dest.String() + + return strings.Join(notes, "/") } // paymentEntry creates an entry for an off chain payment, including fee entries @@ -432,7 +443,7 @@ func paymentEntry(payment paymentInfo, paidToSelf bool, // Create a note for our payment. Since we have already checked that our // payment is settled, we will not have a nil preimage. - note := paymentNote(payment.destination) + note := paymentNote(payment.destination, payment.description) ref := paymentReference(payment.SequenceNumber, *payment.Preimage) // Payment values are expressed as positive values over rpc, but they diff --git a/accounting/filter.go b/accounting/filter.go index 90f48e5..f221b01 100644 --- a/accounting/filter.go +++ b/accounting/filter.go @@ -109,15 +109,16 @@ func filterInvoices(startTime, endTime time.Time, return filtered } -// paymentInfo wraps a lndclient payment struct with a destination, if it is -// available from the information we have available, and its settle time. -// Since we now allow multi-path payments, a single payment may have multiple -// htlcs resolved over a period of time. We use the most recent settle time for -// payment because payments are not considered settled until all the htlcs are -// resolved. +// paymentInfo wraps a lndclient payment struct with a destination, and +// description if available from the information we have available, and its +// settle time. Since we now allow multi-path payments, a single payment may +// have multiple htlcs resolved over a period of time. We use the most recent +// settle time for payment because payments are not considered settled until +// all the htlcs are resolved. type paymentInfo struct { lndclient.Payment destination *route.Vertex + description *string settleTime time.Time } @@ -150,9 +151,20 @@ func preProcessPayments(payments []lndclient.Payment, } } + // Try to get our payment description from our payment request + // This value may not be present for all payments, so we do not + // error if it is not. + description, err := paymentRequestDescription( + payment.PaymentRequest, decode, + ) + if err != nil && err != errNoPaymentRequest { + return nil, err + } + pmt := paymentInfo{ Payment: payment, destination: destination, + description: description, } // If the payment did not succeed, we can add it to our list @@ -229,6 +241,23 @@ func paymentRequestDestination(paymentRequest string, return &payReq.Destination, nil } +// paymentRequestDescription attempts to decode a payment address, and returns +// the description. +func paymentRequestDescription(paymentRequest string, + decode decodePaymentRequest) (*string, error) { + + if paymentRequest == "" { + return nil, errNoPaymentRequest + } + + payReq, err := decode(paymentRequest) + if err != nil { + return nil, fmt.Errorf("decode payment request failed: %w", err) + } + + return &payReq.Description, nil +} + // filterPayments filters out unsuccessful payments and those which did not // occur within the range we specify. func filterPayments(startTime, endTime time.Time,