diff --git a/channeldb/invoices.go b/channeldb/invoices.go index f7912987..18f00da6 100644 --- a/channeldb/invoices.go +++ b/channeldb/invoices.go @@ -1224,9 +1224,9 @@ func (d *DB) updateInvoice(hash lntypes.Hash, invoices, settleIndex *bbolt.Bucke if !ok { return nil, fmt.Errorf("unknown htlc %v", key) } - if htlc.State == HtlcStateSettled { - return nil, fmt.Errorf("cannot cancel a " + - "settled htlc") + if htlc.State != HtlcStateAccepted { + return nil, fmt.Errorf("can only cancel " + + "accepted htlcs") } htlc.State = HtlcStateCancelled diff --git a/invoices/invoiceregistry.go b/invoices/invoiceregistry.go index 602014d4..2859e1c5 100644 --- a/invoices/invoiceregistry.go +++ b/invoices/invoiceregistry.go @@ -640,7 +640,21 @@ func (i *InvoiceRegistry) CancelInvoice(payHash lntypes.Hash) error { canceledHtlcs := make( map[channeldb.CircuitKey]*channeldb.HtlcAcceptDesc, ) - for key := range invoice.Htlcs { + for key, htlc := range invoice.Htlcs { + switch htlc.State { + + // If we get here, there shouldn't be any settled htlcs. + case channeldb.HtlcStateSettled: + return nil, errors.New("cannot cancel " + + "invoice with settled htlc(s)") + + // Don't cancel htlcs that were already cancelled, + // because it would incorrectly modify the invoice paid + // amt. + case channeldb.HtlcStateCancelled: + continue + } + canceledHtlcs[key] = nil }