channeldb: move idempotency up the call tree
As a preparation for subscribing to single invoices, InvoiceRegistry needs to become aware of settling a settled invoice.
This commit is contained in:
parent
2a4c93cdc4
commit
436dd41c77
@ -359,10 +359,10 @@ func TestDuplicateSettleInvoice(t *testing.T) {
|
||||
}
|
||||
|
||||
// If we try to settle the invoice again, then we should get the very
|
||||
// same invoice back.
|
||||
// same invoice back, but with an error this time.
|
||||
dbInvoice, err = db.SettleInvoice(payHash, amt)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to settle invoice: %v", err)
|
||||
if err != ErrInvoiceAlreadySettled {
|
||||
t.Fatalf("expected ErrInvoiceAlreadySettled")
|
||||
}
|
||||
|
||||
if dbInvoice == nil {
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
@ -57,6 +58,10 @@ var (
|
||||
//
|
||||
// settleIndexNo => invoiceKey
|
||||
settleIndexBucket = []byte("invoice-settle-index")
|
||||
|
||||
// ErrInvoiceAlreadySettled is returned when the invoice is already
|
||||
// settled.
|
||||
ErrInvoiceAlreadySettled = errors.New("invoice already settled")
|
||||
)
|
||||
|
||||
const (
|
||||
@ -626,21 +631,14 @@ func (d *DB) SettleInvoice(paymentHash [32]byte,
|
||||
return ErrInvoiceNotFound
|
||||
}
|
||||
|
||||
invoice, err := settleInvoice(
|
||||
settledInvoice, err = settleInvoice(
|
||||
invoices, settleIndex, invoiceNum, amtPaid,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
settledInvoice = invoice
|
||||
return nil
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return settledInvoice, nil
|
||||
return settledInvoice, err
|
||||
}
|
||||
|
||||
// InvoicesSettledSince can be used by callers to catch up any settled invoices
|
||||
@ -898,10 +896,8 @@ func settleInvoice(invoices, settleIndex *bbolt.Bucket, invoiceNum []byte,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Add idempotency to duplicate settles, return here to avoid
|
||||
// overwriting the previous info.
|
||||
if invoice.Terms.State == ContractSettled {
|
||||
return &invoice, nil
|
||||
return &invoice, ErrInvoiceAlreadySettled
|
||||
}
|
||||
|
||||
// Now that we know the invoice hasn't already been settled, we'll
|
||||
|
@ -378,6 +378,14 @@ func (i *InvoiceRegistry) SettleInvoice(rHash lntypes.Hash,
|
||||
// If this isn't a debug invoice, then we'll attempt to settle an
|
||||
// invoice matching this rHash on disk (if one exists).
|
||||
invoice, err := i.cdb.SettleInvoice(rHash, amtPaid)
|
||||
|
||||
// Implement idempotency by returning success if the invoice was already
|
||||
// settled.
|
||||
if err == channeldb.ErrInvoiceAlreadySettled {
|
||||
log.Debugf("Invoice %v already settled", rHash)
|
||||
return nil
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user