channeldb+invoices: move hold invoice settle logic into registry
This commit is a continuation of the centralization of invoice state transition logic in the invoice registry.
This commit is contained in:
3 files changed
+37
-84
No files matched your search
@@ -692,8 +692,9 @@ func getUpdateInvoice(amt lnwire.MilliSatoshi) InvoiceUpdateCallback {
|
|||||||
}
|
}
|
||||||
|
|
||||||
update := &InvoiceUpdateDesc{
|
update := &InvoiceUpdateDesc{
|
||||||
State: ContractSettled,
|
Preimage: invoice.Terms.PaymentPreimage,
|
||||||
AmtPaid: amt,
|
State: ContractSettled,
|
||||||
|
AmtPaid: amt,
|
||||||
}
|
}
|
||||||
|
|
||||||
return update, nil
|
return update, nil
|
||||||
|
|||||||
+12
-80
@@ -284,6 +284,9 @@ type InvoiceUpdateDesc struct {
|
|||||||
|
|
||||||
// AmtPaid is the updated amount that has been paid to this invoice.
|
// AmtPaid is the updated amount that has been paid to this invoice.
|
||||||
AmtPaid lnwire.MilliSatoshi
|
AmtPaid lnwire.MilliSatoshi
|
||||||
|
|
||||||
|
// Preimage must be set to the preimage when state is settled.
|
||||||
|
Preimage lntypes.Preimage
|
||||||
}
|
}
|
||||||
|
|
||||||
// InvoiceUpdateCallback is a callback used in the db transaction to update the
|
// InvoiceUpdateCallback is a callback used in the db transaction to update the
|
||||||
@@ -740,47 +743,8 @@ func (d *DB) UpdateInvoice(paymentHash lntypes.Hash,
|
|||||||
}
|
}
|
||||||
|
|
||||||
updatedInvoice, err = updateInvoice(
|
updatedInvoice, err = updateInvoice(
|
||||||
invoices, settleIndex, invoiceNum, callback,
|
paymentHash, invoices, settleIndex, invoiceNum,
|
||||||
)
|
callback,
|
||||||
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
|
|
||||||
return updatedInvoice, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// SettleHoldInvoice sets the preimage of a hodl invoice and marks the invoice
|
|
||||||
// as settled.
|
|
||||||
func (d *DB) SettleHoldInvoice(preimage lntypes.Preimage) (*Invoice, error) {
|
|
||||||
var updatedInvoice *Invoice
|
|
||||||
hash := preimage.Hash()
|
|
||||||
err := d.Update(func(tx *bbolt.Tx) error {
|
|
||||||
invoices, err := tx.CreateBucketIfNotExists(invoiceBucket)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
invoiceIndex, err := invoices.CreateBucketIfNotExists(
|
|
||||||
invoiceIndexBucket,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
settleIndex, err := invoices.CreateBucketIfNotExists(
|
|
||||||
settleIndexBucket,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check the invoice index to see if an invoice paying to this
|
|
||||||
// hash exists within the DB.
|
|
||||||
invoiceNum := invoiceIndex.Get(hash[:])
|
|
||||||
if invoiceNum == nil {
|
|
||||||
return ErrInvoiceNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
updatedInvoice, err = settleHoldInvoice(
|
|
||||||
invoices, settleIndex, invoiceNum, preimage,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
@@ -1243,8 +1207,8 @@ func copyInvoice(src *Invoice) *Invoice {
|
|||||||
|
|
||||||
// updateInvoice fetches the invoice, obtains the update descriptor from the
|
// updateInvoice fetches the invoice, obtains the update descriptor from the
|
||||||
// callback and applies the updates in a single db transaction.
|
// callback and applies the updates in a single db transaction.
|
||||||
func updateInvoice(invoices, settleIndex *bbolt.Bucket, invoiceNum []byte,
|
func updateInvoice(hash lntypes.Hash, invoices, settleIndex *bbolt.Bucket,
|
||||||
callback InvoiceUpdateCallback) (*Invoice, error) {
|
invoiceNum []byte, callback InvoiceUpdateCallback) (*Invoice, error) {
|
||||||
|
|
||||||
invoice, err := fetchInvoice(invoiceNum, invoices)
|
invoice, err := fetchInvoice(invoiceNum, invoices)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -1272,6 +1236,11 @@ func updateInvoice(invoices, settleIndex *bbolt.Bucket, invoiceNum []byte,
|
|||||||
if preUpdateState != invoice.Terms.State &&
|
if preUpdateState != invoice.Terms.State &&
|
||||||
invoice.Terms.State == ContractSettled {
|
invoice.Terms.State == ContractSettled {
|
||||||
|
|
||||||
|
if update.Preimage.Hash() != hash {
|
||||||
|
return nil, fmt.Errorf("preimage does not match")
|
||||||
|
}
|
||||||
|
invoice.Terms.PaymentPreimage = update.Preimage
|
||||||
|
|
||||||
err := setSettleFields(settleIndex, invoiceNum, &invoice)
|
err := setSettleFields(settleIndex, invoiceNum, &invoice)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -1314,43 +1283,6 @@ func setSettleFields(settleIndex *bbolt.Bucket, invoiceNum []byte,
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func settleHoldInvoice(invoices, settleIndex *bbolt.Bucket,
|
|
||||||
invoiceNum []byte, preimage lntypes.Preimage) (*Invoice,
|
|
||||||
error) {
|
|
||||||
|
|
||||||
invoice, err := fetchInvoice(invoiceNum, invoices)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
switch invoice.Terms.State {
|
|
||||||
case ContractOpen:
|
|
||||||
return &invoice, ErrInvoiceStillOpen
|
|
||||||
case ContractCanceled:
|
|
||||||
return &invoice, ErrInvoiceAlreadyCanceled
|
|
||||||
case ContractSettled:
|
|
||||||
return &invoice, ErrInvoiceAlreadySettled
|
|
||||||
}
|
|
||||||
|
|
||||||
invoice.Terms.PaymentPreimage = preimage
|
|
||||||
|
|
||||||
err = setSettleFields(settleIndex, invoiceNum, &invoice)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var buf bytes.Buffer
|
|
||||||
if err := serializeInvoice(&buf, &invoice); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := invoices.Put(invoiceNum[:], buf.Bytes()); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &invoice, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func cancelInvoice(invoices *bbolt.Bucket, invoiceNum []byte) (
|
func cancelInvoice(invoices *bbolt.Bucket, invoiceNum []byte) (
|
||||||
*Invoice, error) {
|
*Invoice, error) {
|
||||||
|
|
||||||
|
|||||||
@@ -456,6 +456,7 @@ func (i *InvoiceRegistry) updateInvoice(invoice *channeldb.Invoice,
|
|||||||
if holdInvoice {
|
if holdInvoice {
|
||||||
update.State = channeldb.ContractAccepted
|
update.State = channeldb.ContractAccepted
|
||||||
} else {
|
} else {
|
||||||
|
update.Preimage = invoice.Terms.PaymentPreimage
|
||||||
update.State = channeldb.ContractSettled
|
update.State = channeldb.ContractSettled
|
||||||
}
|
}
|
||||||
return &update, nil
|
return &update, nil
|
||||||
@@ -587,13 +588,32 @@ func (i *InvoiceRegistry) SettleHodlInvoice(preimage lntypes.Preimage) error {
|
|||||||
i.Lock()
|
i.Lock()
|
||||||
defer i.Unlock()
|
defer i.Unlock()
|
||||||
|
|
||||||
invoice, err := i.cdb.SettleHoldInvoice(preimage)
|
updateInvoice := func(invoice *channeldb.Invoice) (
|
||||||
|
*channeldb.InvoiceUpdateDesc, error) {
|
||||||
|
|
||||||
|
switch invoice.Terms.State {
|
||||||
|
case channeldb.ContractOpen:
|
||||||
|
return nil, channeldb.ErrInvoiceStillOpen
|
||||||
|
case channeldb.ContractCanceled:
|
||||||
|
return nil, channeldb.ErrInvoiceAlreadyCanceled
|
||||||
|
case channeldb.ContractSettled:
|
||||||
|
return nil, channeldb.ErrInvoiceAlreadySettled
|
||||||
|
}
|
||||||
|
|
||||||
|
return &channeldb.InvoiceUpdateDesc{
|
||||||
|
AmtPaid: invoice.AmtPaid,
|
||||||
|
State: channeldb.ContractSettled,
|
||||||
|
Preimage: preimage,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
hash := preimage.Hash()
|
||||||
|
invoice, err := i.cdb.UpdateInvoice(hash, updateInvoice)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("SettleHodlInvoice with preimage %v: %v", preimage, err)
|
log.Errorf("SettleHodlInvoice with preimage %v: %v", preimage, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
hash := preimage.Hash()
|
|
||||||
log.Debugf("Invoice(%v): settled with preimage %v", hash,
|
log.Debugf("Invoice(%v): settled with preimage %v", hash,
|
||||||
invoice.Terms.PaymentPreimage)
|
invoice.Terms.PaymentPreimage)
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user