From a32f2b79da319a166535f744b9fd6e813f2198b2 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Tue, 24 Apr 2018 20:43:55 -0700 Subject: [PATCH] htlcswitch: modify the InvoiceDatabase interface to allow specifying final payment amt In this commit, we modify the InvoiceDatabase slightly to allow the link to record what the final payment about for an invoice was. It may be the case that the invoice actually had no specified value, or that the payer paid more than necessary. As a result, it's important that our on-disk records properly reflect this. To fix this issue, the SettleInvoice method now also accepts the final amount paid. Fixes #856. --- htlcswitch/interfaces.go | 2 +- htlcswitch/link.go | 12 ++++++++---- htlcswitch/link_test.go | 7 +++++++ htlcswitch/mock.go | 5 ++++- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/htlcswitch/interfaces.go b/htlcswitch/interfaces.go index 196dad4c..60c400f0 100644 --- a/htlcswitch/interfaces.go +++ b/htlcswitch/interfaces.go @@ -18,7 +18,7 @@ type InvoiceDatabase interface { // SettleInvoice attempts to mark an invoice corresponding to the // passed payment hash as fully settled. - SettleInvoice(chainhash.Hash) error + SettleInvoice(payHash chainhash.Hash, paidAmount lnwire.MilliSatoshi) error } // ChannelLink is an interface which represents the subsystem for managing the diff --git a/htlcswitch/link.go b/htlcswitch/link.go index 68261ca2..467a8a73 100644 --- a/htlcswitch/link.go +++ b/htlcswitch/link.go @@ -2298,8 +2298,9 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg, } preimage := invoice.Terms.PaymentPreimage - err = l.channel.SettleHTLC(preimage, - pd.HtlcIndex, pd.SourceRef, nil, nil) + err = l.channel.SettleHTLC( + preimage, pd.HtlcIndex, pd.SourceRef, nil, nil, + ) if err != nil { l.fail(LinkFailureError{code: ErrInternalError}, "unable to settle htlc: %v", err) @@ -2307,8 +2308,11 @@ func (l *channelLink) processRemoteAdds(fwdPkg *channeldb.FwdPkg, } // Notify the invoiceRegistry of the invoices we just - // settled with this latest commitment update. - err = l.cfg.Registry.SettleInvoice(invoiceHash) + // settled (with the amount accepted at settle time) + // with this latest commitment update. + err = l.cfg.Registry.SettleInvoice( + invoiceHash, pd.Amount, + ) if err != nil { l.fail(LinkFailureError{code: ErrInternalError}, "unable to settle invoice: %v", err) diff --git a/htlcswitch/link_test.go b/htlcswitch/link_test.go index c42c6e50..a97da231 100644 --- a/htlcswitch/link_test.go +++ b/htlcswitch/link_test.go @@ -3657,6 +3657,13 @@ func TestChannelLinkAcceptOverpay(t *testing.T) { t.Fatalf("channel bandwidth incorrect: expected %v, got %v", expectedCarolBandwidth, n.carolChannelLink.Bandwidth()) } + + // Finally, we'll ensure that the amount we paid is properly reflected + // in the stored invoice. + if invoice.AmtPaid != amount { + t.Fatalf("expected amt paid to be %v, is instead %v", amount, + invoice.AmtPaid) + } } // chanRestoreFunc is a method signature for functions that can reload both diff --git a/htlcswitch/mock.go b/htlcswitch/mock.go index e0016188..7f86c049 100644 --- a/htlcswitch/mock.go +++ b/htlcswitch/mock.go @@ -673,7 +673,9 @@ func (i *mockInvoiceRegistry) LookupInvoice(rHash chainhash.Hash) (channeldb.Inv return invoice, i.finalDelta, nil } -func (i *mockInvoiceRegistry) SettleInvoice(rhash chainhash.Hash) error { +func (i *mockInvoiceRegistry) SettleInvoice(rhash chainhash.Hash, + amt lnwire.MilliSatoshi) error { + i.Lock() defer i.Unlock() @@ -687,6 +689,7 @@ func (i *mockInvoiceRegistry) SettleInvoice(rhash chainhash.Hash) error { } invoice.Terms.Settled = true + invoice.AmtPaid = amt i.invoices[rhash] = invoice return nil