chainntnfs/txnotifier: support reorg detection for scripts

This commit is contained in:
Wilmer Paulino 2018-12-06 21:13:50 -08:00
parent 83c8ccb3eb
commit f4f5c1ef8b
No known key found for this signature in database
GPG Key ID: 6DF57B9F9514972F

@ -1371,11 +1371,11 @@ func (n *TxNotifier) NotifyHeight(height uint32) error {
}
// DisconnectTip handles the tip of the current chain being disconnected during
// a chain reorganization. If any watched transactions or spending transactions
// for registered outpoints were included in this block, internal structures are
// updated to ensure confirmation/spend notifications are consumed (if not
// already), and reorg notifications are dispatched instead. Confirmation/spend
// notifications will be dispatched again upon block inclusion.
// a chain reorganization. If any watched requests were included in this block,
// internal structures are updated to ensure confirmation/spend notifications
// are consumed (if not already), and reorg notifications are dispatched
// instead. Confirmation/spend notifications will be dispatched again upon block
// inclusion.
func (n *TxNotifier) DisconnectTip(blockHeight uint32) error {
select {
case <-n.quit:
@ -1395,19 +1395,19 @@ func (n *TxNotifier) DisconnectTip(blockHeight uint32) error {
n.reorgDepth++
// With the block disconnected, we'll update the confirm and spend hints
// for our transactions and outpoints to reflect the new height, except
// for those that have confirmed/spent at previous heights.
// for our notification requests to reflect the new height, except for
// those that have confirmed/spent at previous heights.
n.updateHints(blockHeight)
// We'll go through all of our watched transactions and attempt to drain
// their notification channels to ensure sending notifications to the
// clients is always non-blocking.
for initialHeight, txHashes := range n.txsByInitialHeight {
// We'll go through all of our watched confirmation requests and attempt
// to drain their notification channels to ensure sending notifications
// to the clients is always non-blocking.
for initialHeight, txHashes := range n.confsByInitialHeight {
for txHash := range txHashes {
// If the transaction has been reorged out of the chain,
// we'll make sure to remove the cached confirmation
// details to prevent notifying clients with old
// information.
// If the transaction/output script has been reorged out
// of the chain, we'll make sure to remove the cached
// confirmation details to prevent notifying clients
// with old information.
confSet := n.confNotifications[txHash]
if initialHeight == blockHeight {
confSet.details = nil
@ -1424,10 +1424,11 @@ func (n *TxNotifier) DisconnectTip(blockHeight uint32) error {
default:
}
// Then, we'll check if the current transaction
// was included in the block currently being
// disconnected. If it was, we'll need to
// dispatch a reorg notification to the client.
// Then, we'll check if the current
// transaction/output script was included in the
// block currently being disconnected. If it
// was, we'll need to dispatch a reorg
// notification to the client.
if initialHeight == blockHeight {
err := n.dispatchConfReorg(
ntfn, blockHeight,
@ -1440,15 +1441,15 @@ func (n *TxNotifier) DisconnectTip(blockHeight uint32) error {
}
}
// We'll also go through our watched outpoints and attempt to drain
// We'll also go through our watched spend requests and attempt to drain
// their dispatched notifications to ensure dispatching notifications to
// clients later on is always non-blocking. We're only interested in
// outpoints whose spending transaction was included at the height being
// clients later on is always non-blocking. We're only interested in
// requests whose spending transaction was included at the height being
// disconnected.
for op := range n.opsBySpendHeight[blockHeight] {
for op := range n.spendsByHeight[blockHeight] {
// Since the spending transaction is being reorged out of the
// chain, we'll need to clear out the spending details of the
// outpoint.
// request.
spendSet := n.spendNotifications[op]
spendSet.details = nil
@ -1462,12 +1463,12 @@ func (n *TxNotifier) DisconnectTip(blockHeight uint32) error {
}
}
// Finally, we can remove the transactions that were confirmed and the
// outpoints that were spent at the height being disconnected. We'll
// still continue to track them until they have been confirmed/spent and
// are no longer under the risk of being reorged out of the chain again.
delete(n.txsByInitialHeight, blockHeight)
delete(n.opsBySpendHeight, blockHeight)
// Finally, we can remove the requests that were confirmed and/or spent
// at the height being disconnected. We'll still continue to track them
// until they have been confirmed/spent and are no longer under the risk
// of being reorged out of the chain again.
delete(n.confsByInitialHeight, blockHeight)
delete(n.spendsByHeight, blockHeight)
return nil
}
@ -1568,10 +1569,10 @@ func (n *TxNotifier) unspentOutPoints() []wire.OutPoint {
func (n *TxNotifier) dispatchConfReorg(ntfn *ConfNtfn,
heightDisconnected uint32) error {
// If the transaction's confirmation notification has yet to be
// dispatched, we'll need to clear its entry within the
// ntfnsByConfirmHeight index to prevent from notifying the client once
// the notifier reaches the confirmation height.
// If the request's confirmation notification has yet to be dispatched,
// we'll need to clear its entry within the ntfnsByConfirmHeight index
// to prevent from notifying the client once the notifier reaches the
// confirmation height.
if !ntfn.dispatched {
confHeight := heightDisconnected + ntfn.NumConfirmations - 1
ntfnSet, exists := n.ntfnsByConfirmHeight[confHeight]