Skip to content

Commit 9f4a63a

Browse files
authored
Merge pull request #182 from LN-Zap/payment-description
Include outgoing payment description in audit memo
2 parents 7aa160c + 650327b commit 9f4a63a

File tree

5 files changed

+69
-44
lines changed

5 files changed

+69
-44
lines changed

accounting/entries.go

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -401,11 +401,18 @@ func paymentReference(sequenceNumber uint64, preimage lntypes.Preimage) string {
401401

402402
// paymentNote creates a note for payments from our node.
403403
// nolint: interfacer
404-
func paymentNote(dest *route.Vertex) string {
405-
if dest == nil {
406-
return ""
404+
func paymentNote(dest *route.Vertex, memo *string) string {
405+
var notes []string
406+
407+
if memo != nil && *memo != "" {
408+
notes = append(notes, fmt.Sprintf("memo: %v", *memo))
407409
}
408-
return dest.String()
410+
411+
if dest != nil {
412+
notes = append(notes, fmt.Sprintf("destination: %v", dest))
413+
}
414+
415+
return strings.Join(notes, "/")
409416
}
410417

411418
// paymentEntry creates an entry for an off chain payment, including fee entries
@@ -432,7 +439,7 @@ func paymentEntry(payment paymentInfo, paidToSelf bool,
432439

433440
// Create a note for our payment. Since we have already checked that our
434441
// payment is settled, we will not have a nil preimage.
435-
note := paymentNote(payment.destination)
442+
note := paymentNote(payment.destination, payment.description)
436443
ref := paymentReference(payment.SequenceNumber, *payment.Preimage)
437444

438445
// Payment values are expressed as positive values over rpc, but they

accounting/entries_test.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,6 @@ var (
8383
Tx: &wire.MsgTx{},
8484
}
8585

86-
paymentRequest = "lnbcrt10n1p0t6nmypp547evsfyrakg0nmyw59ud9cegkt99yccn5nnp4suq3ac4qyzzgevsdqqcqzpgsp54hvffpajcyddm20k3ptu53930425hpnv8m06nh5jrd6qhq53anrq9qy9qsqphhzyenspf7kfwvm3wyu04fa8cjkmvndyexlnrmh52huwa4tntppjmak703gfln76rvswmsx2cz3utsypzfx40dltesy8nj64ttgemgqtwfnj9"
87-
88-
invoiceMemo = "memo"
89-
9086
invoiceAmt = lnwire.MilliSatoshi(300)
9187

9288
invoiceOverpaidAmt = lnwire.MilliSatoshi(400)
@@ -112,7 +108,7 @@ var (
112108

113109
paymentTime = time.Unix(1590399649, 0)
114110

115-
paymentHash = "11f414479f0a0c2762492c71c58dded5dce99d56d65c3fa523f73513605bebb3"
111+
paymentHash = "0001020304050607080900010203040506070809000102030405060708090102"
116112
pmtHash, _ = lntypes.MakeHashFromStr(paymentHash)
117113

118114
paymentPreimage = "adfef20b24152accd4ed9a05257fb77203d90a8bbbe6d4069a75c5320f0538d9"
@@ -134,11 +130,13 @@ var (
134130
Fee: lnwire.MilliSatoshi(paymentFeeMsat),
135131
Htlcs: []*lnrpc.HTLCAttempt{{}},
136132
SequenceNumber: uint64(paymentIndex),
133+
PaymentRequest: paymentRequest,
137134
}
138135

139136
payInfo = paymentInfo{
140137
Payment: payment,
141138
destination: &otherPubkey,
139+
description: &invoiceMemo,
142140
settleTime: paymentTime,
143141
}
144142

@@ -758,7 +756,7 @@ func TestPaymentEntry(t *testing.T) {
758756
FiatValue: fiat.MsatToFiat(mockBTCPrice.Price, amtMsat),
759757
TxID: paymentHash,
760758
Reference: paymentRef,
761-
Note: paymentNote(&otherPubkey),
759+
Note: paymentNote(&otherPubkey, &invoiceMemo),
762760
Type: EntryTypePayment,
763761
OnChain: false,
764762
Credit: false,
@@ -773,7 +771,7 @@ func TestPaymentEntry(t *testing.T) {
773771
FiatValue: fiat.MsatToFiat(mockBTCPrice.Price, feeMsat),
774772
TxID: paymentHash,
775773
Reference: FeeReference(paymentRef),
776-
Note: paymentNote(&otherPubkey),
774+
Note: paymentNote(&otherPubkey, &invoiceMemo),
777775
Type: EntryTypeFee,
778776
OnChain: false,
779777
Credit: false,

accounting/filter.go

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -109,15 +109,16 @@ func filterInvoices(startTime, endTime time.Time,
109109
return filtered
110110
}
111111

112-
// paymentInfo wraps a lndclient payment struct with a destination, if it is
113-
// available from the information we have available, and its settle time.
114-
// Since we now allow multi-path payments, a single payment may have multiple
115-
// htlcs resolved over a period of time. We use the most recent settle time for
116-
// payment because payments are not considered settled until all the htlcs are
117-
// resolved.
112+
// paymentInfo wraps a lndclient payment struct with a destination, and
113+
// description if available from the information we have available, and its
114+
// settle time. Since we now allow multi-path payments, a single payment may
115+
// have multiple htlcs resolved over a period of time. We use the most recent
116+
// settle time for payment because payments are not considered settled until
117+
// all the htlcs are resolved.
118118
type paymentInfo struct {
119119
lndclient.Payment
120120
destination *route.Vertex
121+
description *string
121122
settleTime time.Time
122123
}
123124

@@ -135,24 +136,31 @@ func preProcessPayments(payments []lndclient.Payment,
135136
paymentList := make([]paymentInfo, len(payments))
136137

137138
for i, payment := range payments {
138-
// Try to get our payment destination from our set of htlcs.
139-
// If we cannot get it from our htlcs (which is the case for
140-
// legacy payments that did not store htlcs), we try to get it
141-
// from our payment request. This value may not be present for
142-
// all payments, so we do not error if it is not.
139+
// Attempt to obtain the payment destination and description
140+
// from our payment request. If this is not possible (which
141+
// can be the case for legacy payments that did not store
142+
// payment requests, or payments that pay directly to a
143+
// payment hash), then try to get it from our HTLCs. Note
144+
// that HTLCs may also not be available for legacy payments
145+
// that did not store HTLCs. In the event that we get a
146+
// destination from both sources, we prefer the destination
147+
// from the HTLCs.
148+
payReqDestination, description, err := paymentRequestDetails(
149+
payment.PaymentRequest, decode,
150+
)
151+
if err != nil && err != errNoPaymentRequest {
152+
return nil, err
153+
}
154+
143155
destination, err := paymentHtlcDestination(payment)
144156
if err != nil {
145-
destination, err = paymentRequestDestination(
146-
payment.PaymentRequest, decode,
147-
)
148-
if err != nil && err != errNoPaymentRequest {
149-
return nil, err
150-
}
157+
destination = payReqDestination
151158
}
152159

153160
pmt := paymentInfo{
154161
Payment: payment,
155162
destination: destination,
163+
description: description,
156164
}
157165

158166
// If the payment did not succeed, we can add it to our list
@@ -212,21 +220,23 @@ func paymentHtlcDestination(payment lndclient.Payment) (*route.Vertex, error) {
212220
return &lastHopPubkey, nil
213221
}
214222

215-
// paymentRequestDestination attempts to decode a payment address, and returns
216-
// the destination.
217-
func paymentRequestDestination(paymentRequest string,
218-
decode decodePaymentRequest) (*route.Vertex, error) {
223+
// paymentRequestDetails attempts to decode a payment address, and returns
224+
// the destination and the description.
225+
func paymentRequestDetails(paymentRequest string,
226+
decode decodePaymentRequest) (*route.Vertex, *string, error) {
219227

220228
if paymentRequest == "" {
221-
return nil, errNoPaymentRequest
229+
return nil, nil, errNoPaymentRequest
222230
}
223231

224232
payReq, err := decode(paymentRequest)
225233
if err != nil {
226-
return nil, fmt.Errorf("decode payment request failed: %w", err)
234+
return nil, nil, fmt.Errorf(
235+
"decode payment request failed: %w", err,
236+
)
227237
}
228238

229-
return &payReq.Destination, nil
239+
return &payReq.Destination, &payReq.Description, nil
230240
}
231241

232242
// filterPayments filters out unsuccessful payments and those which did not

accounting/filter_test.go

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,7 @@ func decode(toSelf bool) func(_ string) (*lndclient.PaymentRequest,
378378

379379
return &lndclient.PaymentRequest{
380380
Destination: pubkey,
381+
Description: invoiceMemo,
381382
}, nil
382383
}
383384
}
@@ -437,35 +438,39 @@ func TestPaymentHtlcDestination(t *testing.T) {
437438
}
438439
}
439440

440-
// TestPaymentRequestDestination tests getting of payment destinations from our
441+
// TestPaymentRequestDestination tests getting of payment details from our
441442
// payment request.
442-
func TestPaymentRequestDestination(t *testing.T) {
443+
func TestPaymentRequestDetails(t *testing.T) {
443444
tests := []struct {
444445
name string
445446
paymentRequest string
446447
decode decodePaymentRequest
447-
dest *route.Vertex
448+
destination *route.Vertex
449+
description *string
448450
err error
449451
}{
450452
{
451453
name: "no payment request",
452454
decode: decode(true),
453455
paymentRequest: "",
454-
dest: nil,
456+
destination: nil,
457+
description: nil,
455458
err: errNoPaymentRequest,
456459
},
457460
{
458461
name: "to self",
459462
decode: decode(true),
460463
paymentRequest: paymentRequest,
461-
dest: &ourPubKey,
464+
destination: &ourPubKey,
465+
description: &invoiceMemo,
462466
err: nil,
463467
},
464468
{
465469
name: "not to self",
466470
decode: decode(false),
467471
paymentRequest: paymentRequest,
468-
dest: &otherPubkey,
472+
destination: &otherPubkey,
473+
description: &invoiceMemo,
469474
err: nil,
470475
},
471476
}
@@ -476,11 +481,13 @@ func TestPaymentRequestDestination(t *testing.T) {
476481
t.Run(test.name, func(t *testing.T) {
477482
t.Parallel()
478483

479-
dest, err := paymentRequestDestination(
484+
destination, description, err := paymentRequestDetails(
480485
test.paymentRequest, test.decode,
481486
)
487+
482488
require.Equal(t, test.err, err)
483-
require.Equal(t, test.dest, dest)
489+
require.Equal(t, test.destination, destination)
490+
require.Equal(t, test.description, description)
484491
})
485492
}
486493
}

accounting/off_chain_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ var (
2424
paymentHash2 = "a5530c5930b9eb7ea4284bcff39da52c6bca3103fc790749eb632911edc7143b"
2525
hash2, _ = lntypes.MakeHashFromStr(paymentHash2)
2626

27+
paymentRequest = "lnbc2500u1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5xysxxatsyp3k7enxv4jsxqzpuaztrnwngzn3kdzw5hydlzf03qdgm2hdq27cqv3agm2awhz5se903vruatfhq77w3ls4evs3ch9zw97j25emudupq63nyw24cg27h2rspfj9srp"
28+
invoiceMemo = "1 cup coffee"
29+
2730
hopToUs = &lnrpc.Hop{
2831
PubKey: ourPK,
2932
}

0 commit comments

Comments
 (0)