channeldb/invoice: fail extra HTLC sets immeidately
This commit is contained in:
parent
70efaa5fe2
commit
8402e346f5
@ -494,6 +494,31 @@ func (i *Invoice) HTLCSet(setID *[32]byte, state HtlcState) map[CircuitKey]*Invo
|
||||
return htlcSet
|
||||
}
|
||||
|
||||
// HTLCSetCompliment returns the set of all HTLCs not belonging to setID that
|
||||
// are in the target state. Passing a nil setID will return no invoices, since
|
||||
// all MPP HTLCs are part of the same HTLC set.
|
||||
func (i *Invoice) HTLCSetCompliment(setID *[32]byte,
|
||||
state HtlcState) map[CircuitKey]*InvoiceHTLC {
|
||||
|
||||
htlcSet := make(map[CircuitKey]*InvoiceHTLC)
|
||||
for key, htlc := range i.Htlcs {
|
||||
// Only add HTLCs that are in the requested HtlcState.
|
||||
if htlc.State != state {
|
||||
continue
|
||||
}
|
||||
|
||||
// We are constructing the compliment, so filter anything that
|
||||
// matches this set id.
|
||||
if htlc.IsInHTLCSet(setID) {
|
||||
continue
|
||||
}
|
||||
|
||||
htlcSet[key] = htlc
|
||||
}
|
||||
|
||||
return htlcSet
|
||||
}
|
||||
|
||||
// HtlcState defines the states an htlc paying to an invoice can be in.
|
||||
type HtlcState uint8
|
||||
|
||||
|
@ -1063,6 +1063,23 @@ func (i *InvoiceRegistry) notifyExitHopHtlcLocked(
|
||||
i.notifyHodlSubscribers(htlcSettleResolution)
|
||||
}
|
||||
|
||||
// If concurrent payments were attempted to this invoice before
|
||||
// the current one was ultimately settled, cancel back any of
|
||||
// the HTLCs immediately. As a result of the settle, the HTLCs
|
||||
// in other HTLC sets are automatically converted to a canceled
|
||||
// state when updating the invoice.
|
||||
canceledHtlcSet := invoice.HTLCSetCompliment(
|
||||
setID, channeldb.HtlcStateCanceled,
|
||||
)
|
||||
for key, htlc := range canceledHtlcSet {
|
||||
htlcFailResolution := NewFailResolution(
|
||||
key, int32(htlc.AcceptHeight),
|
||||
ResultInvoiceAlreadySettled,
|
||||
)
|
||||
|
||||
i.notifyHodlSubscribers(htlcFailResolution)
|
||||
}
|
||||
|
||||
// If we accepted the htlc, subscribe to the hodl invoice and return
|
||||
// an accept resolution with the htlc's accept time on it.
|
||||
case *htlcAcceptResolution:
|
||||
|
@ -61,6 +61,10 @@ const (
|
||||
// invoice that is already canceled.
|
||||
ResultInvoiceAlreadyCanceled
|
||||
|
||||
// ResultInvoiceAlreadySettled is returned when trying to pay an invoice
|
||||
// that is already settled.
|
||||
ResultInvoiceAlreadySettled
|
||||
|
||||
// ResultAmountTooLow is returned when an invoice is underpaid.
|
||||
ResultAmountTooLow
|
||||
|
||||
@ -133,6 +137,9 @@ func (f FailResolutionResult) FailureString() string {
|
||||
case ResultInvoiceAlreadyCanceled:
|
||||
return "invoice already canceled"
|
||||
|
||||
case ResultInvoiceAlreadySettled:
|
||||
return "invoice alread settled"
|
||||
|
||||
case ResultAmountTooLow:
|
||||
return "amount too low"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user