chainntnfs: dispatch conf/spend notifications after blocks
In this commit, we alter the different ChainNotifier implementations to dispatch confirmation and spend notifications after blocks. We do this to ensure the external consistency of our registered clients.
This commit is contained in:
parent
770e005943
commit
e402a4e146
@ -568,14 +568,19 @@ func (b *BitcoindNotifier) confDetailsManually(txid *chainhash.Hash,
|
|||||||
// transactions included this block will processed to either send notifications
|
// transactions included this block will processed to either send notifications
|
||||||
// now or after numConfirmations confs.
|
// now or after numConfirmations confs.
|
||||||
func (b *BitcoindNotifier) handleBlockConnected(block chainntnfs.BlockEpoch) error {
|
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)
|
rawBlock, err := b.chainConn.GetBlock(block.Hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to get block: %v", err)
|
return fmt.Errorf("unable to get block: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
txns := btcutil.NewBlock(rawBlock).Transactions()
|
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 {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to connect tip: %v", err)
|
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,
|
chainntnfs.Log.Infof("New block: height=%v, sha=%v", block.Height,
|
||||||
block.Hash)
|
block.Hash)
|
||||||
|
|
||||||
// We want to set the best block before dispatching notifications so
|
// Now that we've guaranteed the new block extends the txNotifier's
|
||||||
// if any subscribers make queries based on their received block epoch,
|
// current tip, we'll proceed to dispatch notifications to all of our
|
||||||
// our state is fully updated in time.
|
// 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
|
b.bestBlock = block
|
||||||
|
|
||||||
// Lastly we'll notify any subscribed clients of the block.
|
|
||||||
b.notifyBlockEpochs(block.Height, block.Hash)
|
b.notifyBlockEpochs(block.Height, block.Hash)
|
||||||
|
return b.txNotifier.NotifyHeight(uint32(block.Height))
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// notifyBlockEpochs notifies all registered block epoch clients of the newly
|
// notifyBlockEpochs notifies all registered block epoch clients of the newly
|
||||||
|
@ -622,14 +622,13 @@ func (b *BtcdNotifier) confDetailsManually(txid *chainhash.Hash, startHeight,
|
|||||||
// TODO(halseth): this is reusing the neutrino notifier implementation, unify
|
// TODO(halseth): this is reusing the neutrino notifier implementation, unify
|
||||||
// them.
|
// them.
|
||||||
func (b *BtcdNotifier) handleBlockConnected(epoch chainntnfs.BlockEpoch) error {
|
func (b *BtcdNotifier) handleBlockConnected(epoch chainntnfs.BlockEpoch) error {
|
||||||
// First process the block for our internal state. A new block has
|
// First, we'll fetch the raw block as we'll need to gather all the
|
||||||
// been connected to the main chain. Send out any N confirmation
|
// transactions to determine whether any are relevant to our registered
|
||||||
// notifications which may have been triggered by this new block.
|
// clients.
|
||||||
rawBlock, err := b.chainConn.GetBlock(epoch.Hash)
|
rawBlock, err := b.chainConn.GetBlock(epoch.Hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to get block: %v", err)
|
return fmt.Errorf("unable to get block: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
newBlock := &filteredBlock{
|
newBlock := &filteredBlock{
|
||||||
hash: *epoch.Hash,
|
hash: *epoch.Hash,
|
||||||
height: uint32(epoch.Height),
|
height: uint32(epoch.Height),
|
||||||
@ -637,6 +636,9 @@ func (b *BtcdNotifier) handleBlockConnected(epoch chainntnfs.BlockEpoch) error {
|
|||||||
connect: true,
|
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(
|
err = b.txNotifier.ConnectTip(
|
||||||
&newBlock.hash, newBlock.height, newBlock.txns,
|
&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,
|
chainntnfs.Log.Infof("New block: height=%v, sha=%v", epoch.Height,
|
||||||
epoch.Hash)
|
epoch.Hash)
|
||||||
|
|
||||||
// We want to set the best block before dispatching notifications so if
|
// Now that we've guaranteed the new block extends the txNotifier's
|
||||||
// any subscribers make queries based on their received block epoch, our
|
// current tip, we'll proceed to dispatch notifications to all of our
|
||||||
// state is fully updated in time.
|
// 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.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
|
// notifyBlockEpochs notifies all registered block epoch clients of the newly
|
||||||
|
@ -542,9 +542,8 @@ func (n *NeutrinoNotifier) historicalConfDetails(targetHash *chainhash.Hash,
|
|||||||
// transactions included this block will processed to either send notifications
|
// transactions included this block will processed to either send notifications
|
||||||
// now or after numConfirmations confs.
|
// now or after numConfirmations confs.
|
||||||
func (n *NeutrinoNotifier) handleBlockConnected(newBlock *filteredBlock) error {
|
func (n *NeutrinoNotifier) handleBlockConnected(newBlock *filteredBlock) error {
|
||||||
// First process the block for our internal state. A new block has
|
// We'll extend the txNotifier's height with the information of this new
|
||||||
// been connected to the main chain. Send out any N confirmation
|
// block, which will handle all of the notification logic for us.
|
||||||
// notifications which may have been triggered by this new block.
|
|
||||||
err := n.txNotifier.ConnectTip(
|
err := n.txNotifier.ConnectTip(
|
||||||
&newBlock.hash, newBlock.height, newBlock.txns,
|
&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,
|
chainntnfs.Log.Infof("New block: height=%v, sha=%v", newBlock.height,
|
||||||
newBlock.hash)
|
newBlock.hash)
|
||||||
|
|
||||||
// We want to set the best block before dispatching notifications
|
// Now that we've guaranteed the new block extends the txNotifier's
|
||||||
// so if any subscribers make queries based on their received
|
// current tip, we'll proceed to dispatch notifications to all of our
|
||||||
// block epoch, our state is fully updated in time.
|
// 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
|
n.bestHeight = newBlock.height
|
||||||
|
|
||||||
// With all persistent changes committed, notify any subscribed clients
|
|
||||||
// of the block.
|
|
||||||
n.notifyBlockEpochs(int32(newBlock.height), &newBlock.hash)
|
n.notifyBlockEpochs(int32(newBlock.height), &newBlock.hash)
|
||||||
|
return n.txNotifier.NotifyHeight(newBlock.height)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// getFilteredBlock is a utility to retrieve the full filtered block from a block epoch.
|
// getFilteredBlock is a utility to retrieve the full filtered block from a block epoch.
|
||||||
|
Loading…
Reference in New Issue
Block a user