diff --git a/chainntnfs/bitcoindnotify/bitcoind.go b/chainntnfs/bitcoindnotify/bitcoind.go index f4f518210..8c2352138 100644 --- a/chainntnfs/bitcoindnotify/bitcoind.go +++ b/chainntnfs/bitcoindnotify/bitcoind.go @@ -568,14 +568,19 @@ func (b *BitcoindNotifier) confDetailsManually(txid *chainhash.Hash, // transactions included this block will processed to either send notifications // now or after numConfirmations confs. func (b *BitcoindNotifier) handleBlockConnected(block chainntnfs.BlockEpoch) error { + // First, we'll fetch the raw block as we'll need to gather all the + // transactions to determine whether any are relevant to our registered + // clients. rawBlock, err := b.chainConn.GetBlock(block.Hash) if err != nil { return fmt.Errorf("unable to get block: %v", err) } - txns := btcutil.NewBlock(rawBlock).Transactions() - err = b.txNotifier.ConnectTip( - block.Hash, uint32(block.Height), txns) + + // We'll then extend the txNotifier's height with the information of + // this new block, which will handle all of the notification logic for + // us. + err = b.txNotifier.ConnectTip(block.Hash, uint32(block.Height), txns) if err != nil { return fmt.Errorf("unable to connect tip: %v", err) } @@ -583,15 +588,15 @@ func (b *BitcoindNotifier) handleBlockConnected(block chainntnfs.BlockEpoch) err chainntnfs.Log.Infof("New block: height=%v, sha=%v", block.Height, block.Hash) - // We want to set the best block before dispatching notifications so - // if any subscribers make queries based on their received block epoch, - // our state is fully updated in time. + // Now that we've guaranteed the new block extends the txNotifier's + // current tip, we'll proceed to dispatch notifications to all of our + // registered clients whom have had notifications fulfilled. Before + // doing so, we'll make sure update our in memory state in order to + // satisfy any client requests based upon the new block. b.bestBlock = block - // Lastly we'll notify any subscribed clients of the block. b.notifyBlockEpochs(block.Height, block.Hash) - - return nil + return b.txNotifier.NotifyHeight(uint32(block.Height)) } // notifyBlockEpochs notifies all registered block epoch clients of the newly diff --git a/chainntnfs/btcdnotify/btcd.go b/chainntnfs/btcdnotify/btcd.go index c7eecfbcb..bb5e55a43 100644 --- a/chainntnfs/btcdnotify/btcd.go +++ b/chainntnfs/btcdnotify/btcd.go @@ -622,14 +622,13 @@ func (b *BtcdNotifier) confDetailsManually(txid *chainhash.Hash, startHeight, // TODO(halseth): this is reusing the neutrino notifier implementation, unify // them. func (b *BtcdNotifier) handleBlockConnected(epoch chainntnfs.BlockEpoch) error { - // First process the block for our internal state. A new block has - // been connected to the main chain. Send out any N confirmation - // notifications which may have been triggered by this new block. + // First, we'll fetch the raw block as we'll need to gather all the + // transactions to determine whether any are relevant to our registered + // clients. rawBlock, err := b.chainConn.GetBlock(epoch.Hash) if err != nil { return fmt.Errorf("unable to get block: %v", err) } - newBlock := &filteredBlock{ hash: *epoch.Hash, height: uint32(epoch.Height), @@ -637,6 +636,9 @@ func (b *BtcdNotifier) handleBlockConnected(epoch chainntnfs.BlockEpoch) error { connect: true, } + // We'll then extend the txNotifier's height with the information of + // this new block, which will handle all of the notification logic for + // us. err = b.txNotifier.ConnectTip( &newBlock.hash, newBlock.height, newBlock.txns, ) @@ -647,13 +649,15 @@ func (b *BtcdNotifier) handleBlockConnected(epoch chainntnfs.BlockEpoch) error { chainntnfs.Log.Infof("New block: height=%v, sha=%v", epoch.Height, epoch.Hash) - // We want to set the best block before dispatching notifications so if - // any subscribers make queries based on their received block epoch, our - // state is fully updated in time. + // Now that we've guaranteed the new block extends the txNotifier's + // current tip, we'll proceed to dispatch notifications to all of our + // registered clients whom have had notifications fulfilled. Before + // doing so, we'll make sure update our in memory state in order to + // satisfy any client requests based upon the new block. b.bestBlock = epoch - b.notifyBlockEpochs(int32(newBlock.height), &newBlock.hash) - return nil + b.notifyBlockEpochs(epoch.Height, epoch.Hash) + return b.txNotifier.NotifyHeight(uint32(epoch.Height)) } // notifyBlockEpochs notifies all registered block epoch clients of the newly diff --git a/chainntnfs/neutrinonotify/neutrino.go b/chainntnfs/neutrinonotify/neutrino.go index f0d4da2e6..34b8285f8 100644 --- a/chainntnfs/neutrinonotify/neutrino.go +++ b/chainntnfs/neutrinonotify/neutrino.go @@ -542,9 +542,8 @@ func (n *NeutrinoNotifier) historicalConfDetails(targetHash *chainhash.Hash, // transactions included this block will processed to either send notifications // now or after numConfirmations confs. func (n *NeutrinoNotifier) handleBlockConnected(newBlock *filteredBlock) error { - // First process the block for our internal state. A new block has - // been connected to the main chain. Send out any N confirmation - // notifications which may have been triggered by this new block. + // We'll extend the txNotifier's height with the information of this new + // block, which will handle all of the notification logic for us. err := n.txNotifier.ConnectTip( &newBlock.hash, newBlock.height, newBlock.txns, ) @@ -555,16 +554,15 @@ func (n *NeutrinoNotifier) handleBlockConnected(newBlock *filteredBlock) error { chainntnfs.Log.Infof("New block: height=%v, sha=%v", newBlock.height, newBlock.hash) - // We want to set the best block before dispatching notifications - // so if any subscribers make queries based on their received - // block epoch, our state is fully updated in time. + // Now that we've guaranteed the new block extends the txNotifier's + // current tip, we'll proceed to dispatch notifications to all of our + // registered clients whom have had notifications fulfilled. Before + // doing so, we'll make sure update our in memory state in order to + // satisfy any client requests based upon the new block. n.bestHeight = newBlock.height - // With all persistent changes committed, notify any subscribed clients - // of the block. n.notifyBlockEpochs(int32(newBlock.height), &newBlock.hash) - - return nil + return n.txNotifier.NotifyHeight(newBlock.height) } // getFilteredBlock is a utility to retrieve the full filtered block from a block epoch.