chainntnfs/neutrinonotify: update conf notifications to use pkScript

In this commit, we update the implementation of conf notifications for
neutrino to use the output script rather than the txid when matching
blocks for relevant items. The change itself is rather minor as we just
pass in the script, yet match based on the txid as normal when we go to
dispatch notifications.
This commit is contained in:
Olaoluwa Osuntokun 2018-05-30 22:07:17 -07:00
parent e93149e576
commit 21847dc691
No known key found for this signature in database
GPG Key ID: 964EA263DD637C21

@ -339,7 +339,7 @@ func (n *NeutrinoNotifier) notificationDispatcher() {
// filter so we can be notified of its // filter so we can be notified of its
// future initial confirmation. // future initial confirmation.
rescanUpdate := []neutrino.UpdateOption{ rescanUpdate := []neutrino.UpdateOption{
neutrino.AddTxIDs(*msg.TxID), neutrino.AddAddrs(addrs...),
neutrino.Rewind(currentHeight), neutrino.Rewind(currentHeight),
} }
err = n.chainView.Update(rescanUpdate...) err = n.chainView.Update(rescanUpdate...)
@ -410,9 +410,11 @@ func (n *NeutrinoNotifier) notificationDispatcher() {
} }
} }
// historicalConfDetails looks up whether a transaction is already included in a // historicalConfDetails looks up whether a transaction is already included in
// block in the active chain and, if so, returns details about the confirmation. // a block in the active chain and, if so, returns details about the
// confirmation.
func (n *NeutrinoNotifier) historicalConfDetails(targetHash *chainhash.Hash, func (n *NeutrinoNotifier) historicalConfDetails(targetHash *chainhash.Hash,
pkScript []byte,
currentHeight, heightHint uint32) (*chainntnfs.TxConfirmation, error) { currentHeight, heightHint uint32) (*chainntnfs.TxConfirmation, error) {
// Starting from the height hint, we'll walk forwards in the chain to // Starting from the height hint, we'll walk forwards in the chain to
@ -437,14 +439,15 @@ func (n *NeutrinoNotifier) historicalConfDetails(targetHash *chainhash.Hash,
// With the hash computed, we can now fetch the basic filter // With the hash computed, we can now fetch the basic filter
// for this height. // for this height.
regFilter, err := n.p2pNode.GetCFilter(blockHash, regFilter, err := n.p2pNode.GetCFilter(
wire.GCSFilterRegular) blockHash, wire.GCSFilterRegular,
)
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to retrieve regular filter for "+ return nil, fmt.Errorf("unable to retrieve regular filter for "+
"height=%v: %v", scanHeight, err) "height=%v: %v", scanHeight, err)
} }
// If the block has no transactions other than the coinbase // If the block has no transactions other than the Coinbase
// transaction, then the filter may be nil, so we'll continue // transaction, then the filter may be nil, so we'll continue
// forward int that case. // forward int that case.
if regFilter == nil { if regFilter == nil {
@ -452,9 +455,9 @@ func (n *NeutrinoNotifier) historicalConfDetails(targetHash *chainhash.Hash,
} }
// In the case that the filter exists, we'll attempt to see if // In the case that the filter exists, we'll attempt to see if
// any element in it match our target txid. // any element in it matches our target public key script.
key := builder.DeriveKey(&blockHash) key := builder.DeriveKey(&blockHash)
match, err := regFilter.Match(key, targetHash[:]) match, err := regFilter.Match(key, pkScript)
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to query filter: %v", err) return nil, fmt.Errorf("unable to query filter: %v", err)
} }
@ -504,16 +507,15 @@ func (n *NeutrinoNotifier) handleBlockConnected(newBlock *filteredBlock) error {
for i, txIn := range mtx.TxIn { for i, txIn := range mtx.TxIn {
prevOut := txIn.PreviousOutPoint prevOut := txIn.PreviousOutPoint
// If this transaction indeed does spend an output which we have a // If this transaction indeed does spend an output
// registered notification for, then create a spend summary, finally // which we have a registered notification for, then
// sending off the details to the notification subscriber. // create a spend summary, finally sending off the
// details to the notification subscriber.
clients, ok := n.spendNotifications[prevOut] clients, ok := n.spendNotifications[prevOut]
if !ok { if !ok {
continue continue
} }
// TODO(roasbeef): many integration tests expect spend to be
// notified within the mempool.
spendDetails := &chainntnfs.SpendDetail{ spendDetails := &chainntnfs.SpendDetail{
SpentOutPoint: &prevOut, SpentOutPoint: &prevOut,
SpenderTxHash: &txSha, SpenderTxHash: &txSha,
@ -523,13 +525,16 @@ func (n *NeutrinoNotifier) handleBlockConnected(newBlock *filteredBlock) error {
} }
for _, ntfn := range clients { for _, ntfn := range clients {
chainntnfs.Log.Infof("Dispatching spend notification for "+ chainntnfs.Log.Infof("Dispatching spend "+
"outpoint=%v", ntfn.targetOutpoint) "notification for outpoint=%v",
ntfn.targetOutpoint)
ntfn.spendChan <- spendDetails ntfn.spendChan <- spendDetails
// Close spendChan to ensure that any calls to Cancel will not // Close spendChan to ensure that any calls to
// block. This is safe to do since the channel is buffered, and // Cancel will not block. This is safe to do
// the message can still be read by the receiver. // since the channel is buffered, and the
// message can still be read by the receiver.
close(ntfn.spendChan) close(ntfn.spendChan)
} }
@ -537,10 +542,12 @@ func (n *NeutrinoNotifier) handleBlockConnected(newBlock *filteredBlock) error {
} }
} }
// A new block has been connected to the main chain. // A new block has been connected to the main chain. Send out any N
// Send out any N confirmation notifications which may // confirmation notifications which may have been triggered by this new
// have been triggered by this new block. // block.
n.txConfNotifier.ConnectTip(&newBlock.hash, newBlock.height, newBlock.txns) n.txConfNotifier.ConnectTip(
&newBlock.hash, newBlock.height, newBlock.txns,
)
return nil return nil
} }
@ -712,12 +719,14 @@ func (n *NeutrinoNotifier) RegisterSpendNtfn(outpoint *wire.OutPoint,
type confirmationsNotification struct { type confirmationsNotification struct {
chainntnfs.ConfNtfn chainntnfs.ConfNtfn
heightHint uint32 heightHint uint32
pkScript []byte
} }
// RegisterConfirmationsNtfn registers a notification with NeutrinoNotifier // RegisterConfirmationsNtfn registers a notification with NeutrinoNotifier
// which will be triggered once the txid reaches numConfs number of // which will be triggered once the txid reaches numConfs number of
// confirmations. // confirmations.
func (n *NeutrinoNotifier) RegisterConfirmationsNtfn(txid *chainhash.Hash, func (n *NeutrinoNotifier) RegisterConfirmationsNtfn(txid *chainhash.Hash,
pkScript []byte,
numConfs, heightHint uint32) (*chainntnfs.ConfirmationEvent, error) { numConfs, heightHint uint32) (*chainntnfs.ConfirmationEvent, error) {
ntfn := &confirmationsNotification{ ntfn := &confirmationsNotification{
@ -728,6 +737,7 @@ func (n *NeutrinoNotifier) RegisterConfirmationsNtfn(txid *chainhash.Hash,
Event: chainntnfs.NewConfirmationEvent(numConfs), Event: chainntnfs.NewConfirmationEvent(numConfs),
}, },
heightHint: heightHint, heightHint: heightHint,
pkScript: pkScript,
} }
if err := n.txConfNotifier.Register(&ntfn.ConfNtfn); err != nil { if err := n.txConfNotifier.Register(&ntfn.ConfNtfn); err != nil {