chainntnfs: make sure notification is sent to the whole set
This commit fixes a bug where the confirmation details may be missed. When the same tx is subscribed via `RegisterConfirmationsNtfn`, we will put them into the same set and notify the whole set. However, this logic is missing when performing the rescan - once the confirmation detail is found, we only notify the current subscriber. Later we will skip notifying other subscribers in `UpdateConfDetails` due to the `confSet.details != nil` check. We now fix it by immediately notify all the subscribers when the confirmation detail is found during the rescan.
This commit is contained in:
2 files changed
+30
-15
No files matched your search
@@ -258,6 +258,9 @@ type ConfirmationEvent struct {
|
|||||||
// channels.
|
// channels.
|
||||||
func NewConfirmationEvent(numConfs uint32, cancel func()) *ConfirmationEvent {
|
func NewConfirmationEvent(numConfs uint32, cancel func()) *ConfirmationEvent {
|
||||||
return &ConfirmationEvent{
|
return &ConfirmationEvent{
|
||||||
|
// We cannot rely on the subscriber to immediately read from
|
||||||
|
// the channel so we need to create a larger buffer to avoid
|
||||||
|
// blocking the notifier.
|
||||||
Confirmed: make(chan *TxConfirmation, 1),
|
Confirmed: make(chan *TxConfirmation, 1),
|
||||||
Updates: make(chan uint32, numConfs),
|
Updates: make(chan uint32, numConfs),
|
||||||
NegativeConf: make(chan int32, 1),
|
NegativeConf: make(chan int32, 1),
|
||||||
|
|||||||
+27
-15
@@ -664,8 +664,8 @@ func (n *TxNotifier) RegisterConf(txid *chainhash.Hash, pkScript []byte,
|
|||||||
// already been found, we'll attempt to deliver them immediately
|
// already been found, we'll attempt to deliver them immediately
|
||||||
// to this client.
|
// to this client.
|
||||||
Log.Debugf("Attempting to dispatch confirmation for %v on "+
|
Log.Debugf("Attempting to dispatch confirmation for %v on "+
|
||||||
"registration since rescan has finished",
|
"registration since rescan has finished, conf_id=%v",
|
||||||
ntfn.ConfRequest)
|
ntfn.ConfRequest, ntfn.ConfID)
|
||||||
|
|
||||||
// The default notification we assigned above includes the
|
// The default notification we assigned above includes the
|
||||||
// block along with the rest of the details. However not all
|
// block along with the rest of the details. However not all
|
||||||
@@ -679,9 +679,13 @@ func (n *TxNotifier) RegisterConf(txid *chainhash.Hash, pkScript []byte,
|
|||||||
confDetails = &confDetailsCopy
|
confDetails = &confDetailsCopy
|
||||||
}
|
}
|
||||||
|
|
||||||
err := n.dispatchConfDetails(ntfn, confDetails)
|
// Deliver the details to the whole conf set where this ntfn
|
||||||
if err != nil {
|
// lives in.
|
||||||
return nil, err
|
for _, subscriber := range confSet.ntfns {
|
||||||
|
err := n.dispatchConfDetails(subscriber, confDetails)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &ConfRegistration{
|
return &ConfRegistration{
|
||||||
@@ -912,10 +916,16 @@ func (n *TxNotifier) dispatchConfDetails(
|
|||||||
// If there are no conf details to dispatch or if the notification has
|
// If there are no conf details to dispatch or if the notification has
|
||||||
// already been dispatched, then we can skip dispatching to this
|
// already been dispatched, then we can skip dispatching to this
|
||||||
// client.
|
// client.
|
||||||
if details == nil || ntfn.dispatched {
|
if details == nil {
|
||||||
Log.Debugf("Skipping dispatch of conf details(%v) for "+
|
Log.Debugf("Skipped dispatching nil conf details for request "+
|
||||||
"request %v, dispatched=%v", details, ntfn.ConfRequest,
|
"%v, conf_id=%v", ntfn.ConfRequest, ntfn.ConfID)
|
||||||
ntfn.dispatched)
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if ntfn.dispatched {
|
||||||
|
Log.Debugf("Skipped dispatched conf details for request %v "+
|
||||||
|
"conf_id=%v", ntfn.ConfRequest, ntfn.ConfID)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -925,8 +935,9 @@ func (n *TxNotifier) dispatchConfDetails(
|
|||||||
// we'll dispatch a confirmation notification to the caller.
|
// we'll dispatch a confirmation notification to the caller.
|
||||||
confHeight := details.BlockHeight + ntfn.NumConfirmations - 1
|
confHeight := details.BlockHeight + ntfn.NumConfirmations - 1
|
||||||
if confHeight <= n.currentHeight {
|
if confHeight <= n.currentHeight {
|
||||||
Log.Debugf("Dispatching %v confirmation notification for %v",
|
Log.Debugf("Dispatching %v confirmation notification for "+
|
||||||
ntfn.NumConfirmations, ntfn.ConfRequest)
|
"conf_id=%v, %v", ntfn.NumConfirmations, ntfn.ConfID,
|
||||||
|
ntfn.ConfRequest)
|
||||||
|
|
||||||
// We'll send a 0 value to the Updates channel,
|
// We'll send a 0 value to the Updates channel,
|
||||||
// indicating that the transaction/output script has already
|
// indicating that the transaction/output script has already
|
||||||
@@ -944,8 +955,8 @@ func (n *TxNotifier) dispatchConfDetails(
|
|||||||
return ErrTxNotifierExiting
|
return ErrTxNotifierExiting
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.Debugf("Queueing %v confirmation notification for %v at tip ",
|
Log.Debugf("Queueing %v confirmation notification for %v at "+
|
||||||
ntfn.NumConfirmations, ntfn.ConfRequest)
|
"tip", ntfn.NumConfirmations, ntfn.ConfRequest)
|
||||||
|
|
||||||
// Otherwise, we'll keep track of the notification
|
// Otherwise, we'll keep track of the notification
|
||||||
// request by the height at which we should dispatch the
|
// request by the height at which we should dispatch the
|
||||||
@@ -1743,8 +1754,9 @@ func (n *TxNotifier) NotifyHeight(height uint32) error {
|
|||||||
for ntfn := range n.ntfnsByConfirmHeight[height] {
|
for ntfn := range n.ntfnsByConfirmHeight[height] {
|
||||||
confSet := n.confNotifications[ntfn.ConfRequest]
|
confSet := n.confNotifications[ntfn.ConfRequest]
|
||||||
|
|
||||||
Log.Debugf("Dispatching %v confirmation notification for %v",
|
Log.Debugf("Dispatching %v confirmation notification for "+
|
||||||
ntfn.NumConfirmations, ntfn.ConfRequest)
|
"conf_id=%v, %v", ntfn.NumConfirmations, ntfn.ConfID,
|
||||||
|
ntfn.ConfRequest)
|
||||||
|
|
||||||
// The default notification we assigned above includes the
|
// The default notification we assigned above includes the
|
||||||
// block along with the rest of the details. However not all
|
// block along with the rest of the details. However not all
|
||||||
|
|||||||
Reference in new issue
Block a user