Merge pull request #6477 from Crypt-iQ/testmultihopflake
invoices: add client to map before delivering backlog notif
This commit is contained in:
2 files changed
+47
-21
No files matched your search
@@ -104,6 +104,11 @@ compact filters and block/block headers.
|
|||||||
arbitrator relying on htlcswitch to be started
|
arbitrator relying on htlcswitch to be started
|
||||||
first](https://github.com/lightningnetwork/lnd/pull/6214).
|
first](https://github.com/lightningnetwork/lnd/pull/6214).
|
||||||
|
|
||||||
|
* [Fixed an issue where invoice notifications could be missed when using the
|
||||||
|
SubscribeSingleInvoice or SubscribeNotifications rpcs.](https://github.com/lightningnetwork/lnd/pull/6477)
|
||||||
|
|
||||||
|
## Neutrino
|
||||||
|
|
||||||
* [Fixed crash in MuSig2Combine](https://github.com/lightningnetwork/lnd/pull/6502)
|
* [Fixed crash in MuSig2Combine](https://github.com/lightningnetwork/lnd/pull/6502)
|
||||||
|
|
||||||
* [Added signature length
|
* [Added signature length
|
||||||
|
|||||||
+42
-21
@@ -355,12 +355,14 @@ func (i *InvoiceRegistry) dispatchToSingleClients(event *invoiceEvent) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if atomic.LoadUint32(&client.canceled) == 1 {
|
select {
|
||||||
log.Errorf("Client(id=%v) has stopped, skipped "+
|
case <-client.backlogDelivered:
|
||||||
"notification for event(pay_hash=%v)",
|
// We won't deliver any events until the backlog has
|
||||||
client.id, payHash)
|
// went through first.
|
||||||
continue
|
case <-i.quit:
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
client.notify(event)
|
client.notify(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -416,11 +418,19 @@ func (i *InvoiceRegistry) dispatchToClients(event *invoiceEvent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case client.ntfnQueue.ChanIn() <- &invoiceEvent{
|
case <-client.backlogDelivered:
|
||||||
|
// We won't deliver any events until the backlog has
|
||||||
|
// been processed.
|
||||||
|
case <-i.quit:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err := client.notify(&invoiceEvent{
|
||||||
invoice: invoice,
|
invoice: invoice,
|
||||||
setID: event.setID,
|
setID: event.setID,
|
||||||
}:
|
})
|
||||||
case <-i.quit:
|
if err != nil {
|
||||||
|
log.Errorf("Failed dispatching to client: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1411,7 +1421,10 @@ type invoiceSubscriptionKit struct {
|
|||||||
|
|
||||||
canceled uint32 // To be used atomically.
|
canceled uint32 // To be used atomically.
|
||||||
cancelChan chan struct{}
|
cancelChan chan struct{}
|
||||||
wg sync.WaitGroup
|
|
||||||
|
// backlogDelivered is closed when the backlog events have been
|
||||||
|
// delivered.
|
||||||
|
backlogDelivered chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// InvoiceSubscription represents an intent to receive updates for newly added
|
// InvoiceSubscription represents an intent to receive updates for newly added
|
||||||
@@ -1467,13 +1480,15 @@ func (i *invoiceSubscriptionKit) Cancel() {
|
|||||||
|
|
||||||
i.ntfnQueue.Stop()
|
i.ntfnQueue.Stop()
|
||||||
close(i.cancelChan)
|
close(i.cancelChan)
|
||||||
|
|
||||||
i.wg.Wait()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *invoiceSubscriptionKit) notify(event *invoiceEvent) error {
|
func (i *invoiceSubscriptionKit) notify(event *invoiceEvent) error {
|
||||||
select {
|
select {
|
||||||
case i.ntfnQueue.ChanIn() <- event:
|
case i.ntfnQueue.ChanIn() <- event:
|
||||||
|
case <-i.cancelChan:
|
||||||
|
// This can only be triggered by delivery of non-backlog
|
||||||
|
// events.
|
||||||
|
return ErrShuttingDown
|
||||||
case <-i.quit:
|
case <-i.quit:
|
||||||
return ErrShuttingDown
|
return ErrShuttingDown
|
||||||
}
|
}
|
||||||
@@ -1498,10 +1513,14 @@ func (i *InvoiceRegistry) SubscribeNotifications(
|
|||||||
quit: i.quit,
|
quit: i.quit,
|
||||||
ntfnQueue: queue.NewConcurrentQueue(20),
|
ntfnQueue: queue.NewConcurrentQueue(20),
|
||||||
cancelChan: make(chan struct{}),
|
cancelChan: make(chan struct{}),
|
||||||
|
backlogDelivered: make(chan struct{}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
client.ntfnQueue.Start()
|
client.ntfnQueue.Start()
|
||||||
|
|
||||||
|
// This notifies other goroutines that the backlog phase is over.
|
||||||
|
defer close(client.backlogDelivered)
|
||||||
|
|
||||||
// Always increment by 1 first, and our client ID will start with 1,
|
// Always increment by 1 first, and our client ID will start with 1,
|
||||||
// not 0.
|
// not 0.
|
||||||
client.id = atomic.AddUint32(&i.nextClientID, 1)
|
client.id = atomic.AddUint32(&i.nextClientID, 1)
|
||||||
@@ -1565,6 +1584,10 @@ func (i *InvoiceRegistry) SubscribeNotifications(
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
i.Lock()
|
||||||
|
i.notificationClients[client.id] = client
|
||||||
|
i.Unlock()
|
||||||
|
|
||||||
// Query the database to see if based on the provided addIndex and
|
// Query the database to see if based on the provided addIndex and
|
||||||
// settledIndex we need to deliver any backlog notifications.
|
// settledIndex we need to deliver any backlog notifications.
|
||||||
err := i.deliverBacklogEvents(client)
|
err := i.deliverBacklogEvents(client)
|
||||||
@@ -1574,12 +1597,6 @@ func (i *InvoiceRegistry) SubscribeNotifications(
|
|||||||
|
|
||||||
log.Infof("New invoice subscription client: id=%v", client.id)
|
log.Infof("New invoice subscription client: id=%v", client.id)
|
||||||
|
|
||||||
i.Lock()
|
|
||||||
// With the backlog notifications delivered (if any), we'll add this to
|
|
||||||
// our active subscriptions.
|
|
||||||
i.notificationClients[client.id] = client
|
|
||||||
i.Unlock()
|
|
||||||
|
|
||||||
return client, nil
|
return client, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1594,11 +1611,15 @@ func (i *InvoiceRegistry) SubscribeSingleInvoice(
|
|||||||
quit: i.quit,
|
quit: i.quit,
|
||||||
ntfnQueue: queue.NewConcurrentQueue(20),
|
ntfnQueue: queue.NewConcurrentQueue(20),
|
||||||
cancelChan: make(chan struct{}),
|
cancelChan: make(chan struct{}),
|
||||||
|
backlogDelivered: make(chan struct{}),
|
||||||
},
|
},
|
||||||
invoiceRef: channeldb.InvoiceRefByHash(hash),
|
invoiceRef: channeldb.InvoiceRefByHash(hash),
|
||||||
}
|
}
|
||||||
client.ntfnQueue.Start()
|
client.ntfnQueue.Start()
|
||||||
|
|
||||||
|
// This notifies other goroutines that the backlog phase is done.
|
||||||
|
defer close(client.backlogDelivered)
|
||||||
|
|
||||||
// Always increment by 1 first, and our client ID will start with 1,
|
// Always increment by 1 first, and our client ID will start with 1,
|
||||||
// not 0.
|
// not 0.
|
||||||
client.id = atomic.AddUint32(&i.nextClientID, 1)
|
client.id = atomic.AddUint32(&i.nextClientID, 1)
|
||||||
@@ -1639,6 +1660,10 @@ func (i *InvoiceRegistry) SubscribeSingleInvoice(
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
i.Lock()
|
||||||
|
i.singleNotificationClients[client.id] = client
|
||||||
|
i.Unlock()
|
||||||
|
|
||||||
err := i.deliverSingleBacklogEvents(client)
|
err := i.deliverSingleBacklogEvents(client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -1647,10 +1672,6 @@ func (i *InvoiceRegistry) SubscribeSingleInvoice(
|
|||||||
log.Infof("New single invoice subscription client: id=%v, ref=%v",
|
log.Infof("New single invoice subscription client: id=%v, ref=%v",
|
||||||
client.id, client.invoiceRef)
|
client.id, client.invoiceRef)
|
||||||
|
|
||||||
i.Lock()
|
|
||||||
i.singleNotificationClients[client.id] = client
|
|
||||||
i.Unlock()
|
|
||||||
|
|
||||||
return client, nil
|
return client, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user