mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-03-13 11:09:23 +01:00
Merge pull request #6332 from bhandras/invoice_registry_deadlock
invoices: fix deadlock in invoice registry
This commit is contained in:
commit
d287884ff4
2 changed files with 21 additions and 10 deletions
|
@ -48,6 +48,9 @@
|
|||
validation](https://github.com/lightningnetwork/lnd/pull/6314) when calling
|
||||
`NewSigFromRawSignature`.
|
||||
|
||||
* [Fixed deadlock in invoice
|
||||
registry](https://github.com/lightningnetwork/lnd/pull/6332).
|
||||
|
||||
|
||||
## Misc
|
||||
|
||||
|
@ -183,4 +186,4 @@ gRPC performance metrics (latency to process `GetInfo`, etc)](https://github.com
|
|||
* Thebora Kompanioni
|
||||
* Torkel Rogstad
|
||||
* Vsevolod Kaganovych
|
||||
* Yong Yu
|
||||
* Yong Yu
|
||||
|
|
|
@ -939,12 +939,18 @@ func (i *InvoiceRegistry) NotifyExitHopHtlc(rHash lntypes.Hash,
|
|||
|
||||
// Execute locked notify exit hop logic.
|
||||
i.Lock()
|
||||
resolution, err := i.notifyExitHopHtlcLocked(&ctx, hodlChan)
|
||||
resolution, invoiceToExpire, err := i.notifyExitHopHtlcLocked(
|
||||
&ctx, hodlChan,
|
||||
)
|
||||
i.Unlock()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if invoiceToExpire != nil {
|
||||
i.expiryWatcher.AddInvoices(invoiceToExpire)
|
||||
}
|
||||
|
||||
switch r := resolution.(type) {
|
||||
// The htlc is held. Start a timer outside the lock if the htlc should
|
||||
// be auto-released, because otherwise a deadlock may happen with the
|
||||
|
@ -975,10 +981,11 @@ func (i *InvoiceRegistry) NotifyExitHopHtlc(rHash lntypes.Hash,
|
|||
}
|
||||
|
||||
// notifyExitHopHtlcLocked is the internal implementation of NotifyExitHopHtlc
|
||||
// that should be executed inside the registry lock.
|
||||
// that should be executed inside the registry lock. The returned invoiceExpiry
|
||||
// (if not nil) needs to be added to the expiry watcher outside of the lock.
|
||||
func (i *InvoiceRegistry) notifyExitHopHtlcLocked(
|
||||
ctx *invoiceUpdateCtx, hodlChan chan<- interface{}) (
|
||||
HtlcResolution, error) {
|
||||
HtlcResolution, invoiceExpiry, error) {
|
||||
|
||||
// We'll attempt to settle an invoice matching this rHash on disk (if
|
||||
// one exists). The callback will update the invoice state and/or htlcs.
|
||||
|
@ -1014,15 +1021,17 @@ func (i *InvoiceRegistry) notifyExitHopHtlcLocked(
|
|||
return NewFailResolution(
|
||||
ctx.circuitKey, ctx.currentHeight,
|
||||
ResultInvoiceNotFound,
|
||||
), nil
|
||||
), nil, nil
|
||||
|
||||
case nil:
|
||||
|
||||
default:
|
||||
ctx.log(err.Error())
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var invoiceToExpire invoiceExpiry
|
||||
|
||||
switch res := resolution.(type) {
|
||||
case *HtlcFailResolution:
|
||||
// Inspect latest htlc state on the invoice. If it is found,
|
||||
|
@ -1116,7 +1125,7 @@ func (i *InvoiceRegistry) notifyExitHopHtlcLocked(
|
|||
case *htlcAcceptResolution:
|
||||
invoiceHtlc, ok := invoice.Htlcs[ctx.circuitKey]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("accepted htlc: %v not"+
|
||||
return nil, nil, fmt.Errorf("accepted htlc: %v not"+
|
||||
" present on invoice: %x", ctx.circuitKey,
|
||||
ctx.hash[:])
|
||||
}
|
||||
|
@ -1145,8 +1154,7 @@ func (i *InvoiceRegistry) notifyExitHopHtlcLocked(
|
|||
// possible that we MppTimeout the htlcs, and then our relevant
|
||||
// expiry height could change.
|
||||
if res.outcome == resultAccepted {
|
||||
expiry := makeInvoiceExpiry(ctx.hash, invoice)
|
||||
i.expiryWatcher.AddInvoices(expiry)
|
||||
invoiceToExpire = makeInvoiceExpiry(ctx.hash, invoice)
|
||||
}
|
||||
|
||||
i.hodlSubscribe(hodlChan, ctx.circuitKey)
|
||||
|
@ -1169,7 +1177,7 @@ func (i *InvoiceRegistry) notifyExitHopHtlcLocked(
|
|||
i.notifyClients(ctx.hash, invoice, setID)
|
||||
}
|
||||
|
||||
return resolution, nil
|
||||
return resolution, invoiceToExpire, nil
|
||||
}
|
||||
|
||||
// SettleHodlInvoice sets the preimage of a hodl invoice.
|
||||
|
|
Loading…
Add table
Reference in a new issue