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