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
|
// 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)
|
dbInvoice, err = db.SettleInvoice(payHash, amt)
|
||||||
if err != nil {
|
if err != ErrInvoiceAlreadySettled {
|
||||||
t.Fatalf("unable to settle invoice: %v", err)
|
t.Fatalf("expected ErrInvoiceAlreadySettled")
|
||||||
}
|
}
|
||||||
|
|
||||||
if dbInvoice == nil {
|
if dbInvoice == nil {
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"time"
|
"time"
|
||||||
@ -57,6 +58,10 @@ var (
|
|||||||
//
|
//
|
||||||
// settleIndexNo => invoiceKey
|
// settleIndexNo => invoiceKey
|
||||||
settleIndexBucket = []byte("invoice-settle-index")
|
settleIndexBucket = []byte("invoice-settle-index")
|
||||||
|
|
||||||
|
// ErrInvoiceAlreadySettled is returned when the invoice is already
|
||||||
|
// settled.
|
||||||
|
ErrInvoiceAlreadySettled = errors.New("invoice already settled")
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -626,21 +631,14 @@ func (d *DB) SettleInvoice(paymentHash [32]byte,
|
|||||||
return ErrInvoiceNotFound
|
return ErrInvoiceNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
invoice, err := settleInvoice(
|
settledInvoice, err = settleInvoice(
|
||||||
invoices, settleIndex, invoiceNum, amtPaid,
|
invoices, settleIndex, invoiceNum, amtPaid,
|
||||||
)
|
)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
settledInvoice = invoice
|
return err
|
||||||
return nil
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return settledInvoice, nil
|
return settledInvoice, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// InvoicesSettledSince can be used by callers to catch up any settled invoices
|
// 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
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add idempotency to duplicate settles, return here to avoid
|
|
||||||
// overwriting the previous info.
|
|
||||||
if invoice.Terms.State == ContractSettled {
|
if invoice.Terms.State == ContractSettled {
|
||||||
return &invoice, nil
|
return &invoice, ErrInvoiceAlreadySettled
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now that we know the invoice hasn't already been settled, we'll
|
// 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
|
// If this isn't a debug invoice, then we'll attempt to settle an
|
||||||
// invoice matching this rHash on disk (if one exists).
|
// invoice matching this rHash on disk (if one exists).
|
||||||
invoice, err := i.cdb.SettleInvoice(rHash, amtPaid)
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user