chainntfns: add new option for conf notifications to send block

In this commit, we add a new option for the existing confirmation
notification system that optionally allows the caller to specify that a
block should be included as well.

The only quirk w/ the implementation here is the neutrino backend:
usually we get filtered blocks, we so need to first fetch the block
again so we can deliver the full block to the notifier. On the notifier
end, it'll only be checking for the transactions we care about, to
sending a full block doesn't affect the correctness.

We also extend the `testBatchConfirmationNotification` test to assert
that a block is only included if the caller specifies it.
This commit is contained in:
Olaoluwa Osuntokun
2022-07-13 19:27:10 -07:00
parent fec8fd9c63
commit 08f1c2e93a
12 changed files with 224 additions and 109 deletions

View File

@@ -636,6 +636,7 @@ func (n *NeutrinoNotifier) historicalConfDetails(confRequest chainntnfs.ConfRequ
BlockHash: blockHash,
BlockHeight: scanHeight,
TxIndex: uint32(i),
Block: block.MsgBlock(),
}, nil
}
}
@@ -649,11 +650,19 @@ func (n *NeutrinoNotifier) historicalConfDetails(confRequest chainntnfs.ConfRequ
//
// NOTE: This method must be called with the bestBlockMtx lock held.
func (n *NeutrinoNotifier) handleBlockConnected(newBlock *filteredBlock) error {
// 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,
)
// We'll extend the txNotifier's height with the information of this
// new block, which will handle all of the notification logic for us.
//
// We actually need the _full_ block here as well in order to be able
// to send the full block back up to the client. The neutrino client
// itself will only dispatch a block if one of the items we're looking
// for matches, so ultimately passing it the full block will still only
// result in the items we care about being dispatched.
rawBlock, err := n.GetBlock(newBlock.hash)
if err != nil {
return fmt.Errorf("unable to get full block: %v", err)
}
err = n.txNotifier.ConnectTip(rawBlock, newBlock.height)
if err != nil {
return fmt.Errorf("unable to connect tip: %v", err)
}
@@ -899,15 +908,15 @@ func (n *NeutrinoNotifier) RegisterSpendNtfn(outpoint *wire.OutPoint,
// channel. Once it has reached all of its confirmations, a notification will be
// sent across the 'Confirmed' channel.
func (n *NeutrinoNotifier) RegisterConfirmationsNtfn(txid *chainhash.Hash,
pkScript []byte,
numConfs, heightHint uint32) (*chainntnfs.ConfirmationEvent, error) {
pkScript []byte, numConfs, heightHint uint32,
opts ...chainntnfs.NotifierOption) (*chainntnfs.ConfirmationEvent, error) {
// Register the conf notification with the TxNotifier. A non-nil value
// for `dispatch` will be returned if we are required to perform a
// manual scan for the confirmation. Otherwise the notifier will begin
// watching at tip for the transaction to confirm.
ntfn, err := n.txNotifier.RegisterConf(
txid, pkScript, numConfs, heightHint,
txid, pkScript, numConfs, heightHint, opts...,
)
if err != nil {
return nil, err