chainntnfs: refactor common registration code within RegisterConfirmationsNtfn
This commit is contained in:
parent
0a5080c144
commit
5089311ca1
@ -39,7 +39,6 @@ type chainUpdate struct {
|
|||||||
// chain client. Multiple concurrent clients are supported. All notifications
|
// chain client. Multiple concurrent clients are supported. All notifications
|
||||||
// are achieved via non-blocking sends on client channels.
|
// are achieved via non-blocking sends on client channels.
|
||||||
type BitcoindNotifier struct {
|
type BitcoindNotifier struct {
|
||||||
confClientCounter uint64 // To be used atomically.
|
|
||||||
spendClientCounter uint64 // To be used atomically.
|
spendClientCounter uint64 // To be used atomically.
|
||||||
epochClientCounter uint64 // To be used atomically.
|
epochClientCounter uint64 // To be used atomically.
|
||||||
|
|
||||||
@ -827,41 +826,23 @@ func (b *BitcoindNotifier) RegisterConfirmationsNtfn(txid *chainhash.Hash,
|
|||||||
pkScript []byte,
|
pkScript []byte,
|
||||||
numConfs, heightHint uint32) (*chainntnfs.ConfirmationEvent, error) {
|
numConfs, heightHint uint32) (*chainntnfs.ConfirmationEvent, error) {
|
||||||
|
|
||||||
// Construct a notification request for the transaction and send it to
|
|
||||||
// the main event loop.
|
|
||||||
confID := atomic.AddUint64(&b.confClientCounter, 1)
|
|
||||||
confRequest, err := chainntnfs.NewConfRequest(txid, pkScript)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
ntfn := &chainntnfs.ConfNtfn{
|
|
||||||
ConfID: confID,
|
|
||||||
ConfRequest: confRequest,
|
|
||||||
NumConfirmations: numConfs,
|
|
||||||
Event: chainntnfs.NewConfirmationEvent(numConfs, func() {
|
|
||||||
b.txNotifier.CancelConf(confRequest, confID)
|
|
||||||
}),
|
|
||||||
HeightHint: heightHint,
|
|
||||||
}
|
|
||||||
|
|
||||||
chainntnfs.Log.Infof("New confirmation subscription: %v, num_confs=%v",
|
|
||||||
confRequest, numConfs)
|
|
||||||
|
|
||||||
// Register the conf notification with the TxNotifier. A non-nil value
|
// Register the conf notification with the TxNotifier. A non-nil value
|
||||||
// for `dispatch` will be returned if we are required to perform a
|
// for `dispatch` will be returned if we are required to perform a
|
||||||
// manual scan for the confirmation. Otherwise the notifier will begin
|
// manual scan for the confirmation. Otherwise the notifier will begin
|
||||||
// watching at tip for the transaction to confirm.
|
// watching at tip for the transaction to confirm.
|
||||||
dispatch, _, err := b.txNotifier.RegisterConf(ntfn)
|
ntfn, err := b.txNotifier.RegisterConf(
|
||||||
|
txid, pkScript, numConfs, heightHint,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if dispatch == nil {
|
if ntfn.HistoricalDispatch == nil {
|
||||||
return ntfn.Event, nil
|
return ntfn.Event, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case b.notificationRegistry <- dispatch:
|
case b.notificationRegistry <- ntfn.HistoricalDispatch:
|
||||||
return ntfn.Event, nil
|
return ntfn.Event, nil
|
||||||
case <-b.quit:
|
case <-b.quit:
|
||||||
return nil, chainntnfs.ErrChainNotifierShuttingDown
|
return nil, chainntnfs.ErrChainNotifierShuttingDown
|
||||||
|
@ -50,7 +50,6 @@ type txUpdate struct {
|
|||||||
// notifications. Multiple concurrent clients are supported. All notifications
|
// notifications. Multiple concurrent clients are supported. All notifications
|
||||||
// are achieved via non-blocking sends on client channels.
|
// are achieved via non-blocking sends on client channels.
|
||||||
type BtcdNotifier struct {
|
type BtcdNotifier struct {
|
||||||
confClientCounter uint64 // To be used aotmically.
|
|
||||||
spendClientCounter uint64 // To be used atomically.
|
spendClientCounter uint64 // To be used atomically.
|
||||||
epochClientCounter uint64 // To be used atomically.
|
epochClientCounter uint64 // To be used atomically.
|
||||||
|
|
||||||
@ -851,41 +850,23 @@ func (b *BtcdNotifier) RegisterConfirmationsNtfn(txid *chainhash.Hash,
|
|||||||
pkScript []byte,
|
pkScript []byte,
|
||||||
numConfs, heightHint uint32) (*chainntnfs.ConfirmationEvent, error) {
|
numConfs, heightHint uint32) (*chainntnfs.ConfirmationEvent, error) {
|
||||||
|
|
||||||
// Construct a notification request for the transaction and send it to
|
|
||||||
// the main event loop.
|
|
||||||
confID := atomic.AddUint64(&b.confClientCounter, 1)
|
|
||||||
confRequest, err := chainntnfs.NewConfRequest(txid, pkScript)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
ntfn := &chainntnfs.ConfNtfn{
|
|
||||||
ConfID: confID,
|
|
||||||
ConfRequest: confRequest,
|
|
||||||
NumConfirmations: numConfs,
|
|
||||||
Event: chainntnfs.NewConfirmationEvent(numConfs, func() {
|
|
||||||
b.txNotifier.CancelConf(confRequest, confID)
|
|
||||||
}),
|
|
||||||
HeightHint: heightHint,
|
|
||||||
}
|
|
||||||
|
|
||||||
chainntnfs.Log.Infof("New confirmation subscription: %v, num_confs=%v ",
|
|
||||||
confRequest, numConfs)
|
|
||||||
|
|
||||||
// Register the conf notification with the TxNotifier. A non-nil value
|
// Register the conf notification with the TxNotifier. A non-nil value
|
||||||
// for `dispatch` will be returned if we are required to perform a
|
// for `dispatch` will be returned if we are required to perform a
|
||||||
// manual scan for the confirmation. Otherwise the notifier will begin
|
// manual scan for the confirmation. Otherwise the notifier will begin
|
||||||
// watching at tip for the transaction to confirm.
|
// watching at tip for the transaction to confirm.
|
||||||
dispatch, _, err := b.txNotifier.RegisterConf(ntfn)
|
ntfn, err := b.txNotifier.RegisterConf(
|
||||||
|
txid, pkScript, numConfs, heightHint,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if dispatch == nil {
|
if ntfn.HistoricalDispatch == nil {
|
||||||
return ntfn.Event, nil
|
return ntfn.Event, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case b.notificationRegistry <- dispatch:
|
case b.notificationRegistry <- ntfn.HistoricalDispatch:
|
||||||
return ntfn.Event, nil
|
return ntfn.Event, nil
|
||||||
case <-b.quit:
|
case <-b.quit:
|
||||||
return nil, chainntnfs.ErrChainNotifierShuttingDown
|
return nil, chainntnfs.ErrChainNotifierShuttingDown
|
||||||
|
@ -37,7 +37,6 @@ const (
|
|||||||
// TODO(roasbeef): heavily consolidate with NeutrinoNotifier code
|
// TODO(roasbeef): heavily consolidate with NeutrinoNotifier code
|
||||||
// * maybe combine into single package?
|
// * maybe combine into single package?
|
||||||
type NeutrinoNotifier struct {
|
type NeutrinoNotifier struct {
|
||||||
confClientCounter uint64 // To be used atomically.
|
|
||||||
spendClientCounter uint64 // To be used atomically.
|
spendClientCounter uint64 // To be used atomically.
|
||||||
epochClientCounter uint64 // To be used atomically.
|
epochClientCounter uint64 // To be used atomically.
|
||||||
|
|
||||||
@ -820,31 +819,13 @@ func (n *NeutrinoNotifier) RegisterConfirmationsNtfn(txid *chainhash.Hash,
|
|||||||
pkScript []byte,
|
pkScript []byte,
|
||||||
numConfs, heightHint uint32) (*chainntnfs.ConfirmationEvent, error) {
|
numConfs, heightHint uint32) (*chainntnfs.ConfirmationEvent, error) {
|
||||||
|
|
||||||
// Construct a notification request for the transaction and send it to
|
|
||||||
// the main event loop.
|
|
||||||
confID := atomic.AddUint64(&n.confClientCounter, 1)
|
|
||||||
confRequest, err := chainntnfs.NewConfRequest(txid, pkScript)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
ntfn := &chainntnfs.ConfNtfn{
|
|
||||||
ConfID: confID,
|
|
||||||
ConfRequest: confRequest,
|
|
||||||
NumConfirmations: numConfs,
|
|
||||||
Event: chainntnfs.NewConfirmationEvent(numConfs, func() {
|
|
||||||
n.txNotifier.CancelConf(confRequest, confID)
|
|
||||||
}),
|
|
||||||
HeightHint: heightHint,
|
|
||||||
}
|
|
||||||
|
|
||||||
chainntnfs.Log.Infof("New confirmation subscription: %v, num_confs=%v",
|
|
||||||
confRequest, numConfs)
|
|
||||||
|
|
||||||
// Register the conf notification with the TxNotifier. A non-nil value
|
// Register the conf notification with the TxNotifier. A non-nil value
|
||||||
// for `dispatch` will be returned if we are required to perform a
|
// for `dispatch` will be returned if we are required to perform a
|
||||||
// manual scan for the confirmation. Otherwise the notifier will begin
|
// manual scan for the confirmation. Otherwise the notifier will begin
|
||||||
// watching at tip for the transaction to confirm.
|
// watching at tip for the transaction to confirm.
|
||||||
dispatch, txNotifierTip, err := n.txNotifier.RegisterConf(ntfn)
|
ntfn, err := n.txNotifier.RegisterConf(
|
||||||
|
txid, pkScript, numConfs, heightHint,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -859,9 +840,7 @@ func (n *NeutrinoNotifier) RegisterConfirmationsNtfn(txid *chainhash.Hash,
|
|||||||
// type so we can instruct neutrino to match if the transaction
|
// type so we can instruct neutrino to match if the transaction
|
||||||
// containing the script is found in a block.
|
// containing the script is found in a block.
|
||||||
params := n.p2pNode.ChainParams()
|
params := n.p2pNode.ChainParams()
|
||||||
_, addrs, _, err := txscript.ExtractPkScriptAddrs(
|
_, addrs, _, err := txscript.ExtractPkScriptAddrs(pkScript, ¶ms)
|
||||||
confRequest.PkScript.Script(), ¶ms,
|
|
||||||
)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to extract script: %v", err)
|
return nil, fmt.Errorf("unable to extract script: %v", err)
|
||||||
}
|
}
|
||||||
@ -873,7 +852,7 @@ func (n *NeutrinoNotifier) RegisterConfirmationsNtfn(txid *chainhash.Hash,
|
|||||||
case n.notificationRegistry <- &rescanFilterUpdate{
|
case n.notificationRegistry <- &rescanFilterUpdate{
|
||||||
updateOptions: []neutrino.UpdateOption{
|
updateOptions: []neutrino.UpdateOption{
|
||||||
neutrino.AddAddrs(addrs...),
|
neutrino.AddAddrs(addrs...),
|
||||||
neutrino.Rewind(txNotifierTip),
|
neutrino.Rewind(ntfn.Height),
|
||||||
neutrino.DisableDisconnectedNtfns(true),
|
neutrino.DisableDisconnectedNtfns(true),
|
||||||
},
|
},
|
||||||
errChan: errChan,
|
errChan: errChan,
|
||||||
@ -893,14 +872,14 @@ func (n *NeutrinoNotifier) RegisterConfirmationsNtfn(txid *chainhash.Hash,
|
|||||||
|
|
||||||
// If a historical rescan was not requested by the txNotifier, then we
|
// If a historical rescan was not requested by the txNotifier, then we
|
||||||
// can return to the caller.
|
// can return to the caller.
|
||||||
if dispatch == nil {
|
if ntfn.HistoricalDispatch == nil {
|
||||||
return ntfn.Event, nil
|
return ntfn.Event, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, with the filter updated, we can dispatch the historical
|
// Finally, with the filter updated, we can dispatch the historical
|
||||||
// rescan to ensure we can detect if the event happened in the past.
|
// rescan to ensure we can detect if the event happened in the past.
|
||||||
select {
|
select {
|
||||||
case n.notificationRegistry <- dispatch:
|
case n.notificationRegistry <- ntfn.HistoricalDispatch:
|
||||||
case <-n.quit:
|
case <-n.quit:
|
||||||
return nil, chainntnfs.ErrChainNotifierShuttingDown
|
return nil, chainntnfs.ErrChainNotifierShuttingDown
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
"github.com/btcsuite/btcd/chaincfg/chainhash"
|
||||||
"github.com/btcsuite/btcd/txscript"
|
"github.com/btcsuite/btcd/txscript"
|
||||||
@ -255,6 +256,25 @@ type HistoricalConfDispatch struct {
|
|||||||
EndHeight uint32
|
EndHeight uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ConfRegistration encompasses all of the information required for callers to
|
||||||
|
// retrieve details about a confirmation event.
|
||||||
|
type ConfRegistration struct {
|
||||||
|
// Event contains references to the channels that the notifications are
|
||||||
|
// to be sent over.
|
||||||
|
Event *ConfirmationEvent
|
||||||
|
|
||||||
|
// HistoricalDispatch, if non-nil, signals to the client who registered
|
||||||
|
// the notification that they are responsible for attempting to manually
|
||||||
|
// rescan blocks for the txid/output script between the start and end
|
||||||
|
// heights.
|
||||||
|
HistoricalDispatch *HistoricalConfDispatch
|
||||||
|
|
||||||
|
// Height is the height of the TxNotifier at the time the confirmation
|
||||||
|
// notification was registered. This can be used so that backends can
|
||||||
|
// request to be notified of confirmations from this point forwards.
|
||||||
|
Height uint32
|
||||||
|
}
|
||||||
|
|
||||||
// SpendRequest encapsulates a request for a spend notification of either an
|
// SpendRequest encapsulates a request for a spend notification of either an
|
||||||
// outpoint or output script.
|
// outpoint or output script.
|
||||||
type SpendRequest struct {
|
type SpendRequest struct {
|
||||||
@ -401,6 +421,8 @@ type HistoricalSpendDispatch struct {
|
|||||||
// The TxNotifier will watch the blockchain as new blocks come in, in order to
|
// The TxNotifier will watch the blockchain as new blocks come in, in order to
|
||||||
// satisfy its client requests.
|
// satisfy its client requests.
|
||||||
type TxNotifier struct {
|
type TxNotifier struct {
|
||||||
|
confClientCounter uint64 // To be used atomically.
|
||||||
|
|
||||||
// currentHeight is the height of the tracked blockchain. It is used to
|
// currentHeight is the height of the tracked blockchain. It is used to
|
||||||
// determine the number of confirmations a tx has and ensure blocks are
|
// determine the number of confirmations a tx has and ensure blocks are
|
||||||
// connected and disconnected in order.
|
// connected and disconnected in order.
|
||||||
@ -484,34 +506,60 @@ func NewTxNotifier(startHeight uint32, reorgSafetyLimit uint32,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// newConfNtfn validates all of the parameters required to successfully create
|
||||||
|
// and register a confirmation notification.
|
||||||
|
func (n *TxNotifier) newConfNtfn(txid *chainhash.Hash,
|
||||||
|
pkScript []byte, numConfs, heightHint uint32) (*ConfNtfn, error) {
|
||||||
|
|
||||||
|
confRequest, err := NewConfRequest(txid, pkScript)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enforce that we will not dispatch confirmations beyond the reorg
|
||||||
|
// safety limit.
|
||||||
|
if numConfs > n.reorgSafetyLimit {
|
||||||
|
return nil, ErrTxMaxConfs
|
||||||
|
}
|
||||||
|
|
||||||
|
confID := atomic.AddUint64(&n.confClientCounter, 1)
|
||||||
|
return &ConfNtfn{
|
||||||
|
ConfID: confID,
|
||||||
|
ConfRequest: confRequest,
|
||||||
|
NumConfirmations: numConfs,
|
||||||
|
Event: NewConfirmationEvent(numConfs, func() {
|
||||||
|
n.CancelConf(confRequest, confID)
|
||||||
|
}),
|
||||||
|
HeightHint: heightHint,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// RegisterConf handles a new confirmation notification request. The client will
|
// RegisterConf handles a new confirmation notification request. The client will
|
||||||
// be notified when the transaction/output script gets a sufficient number of
|
// be notified when the transaction/output script gets a sufficient number of
|
||||||
// confirmations in the blockchain. The registration succeeds if no error is
|
// confirmations in the blockchain.
|
||||||
// returned. If the returned HistoricalConfDispatch is non-nil, the caller is
|
|
||||||
// responsible for attempting to manually rescan blocks for the txid/output
|
|
||||||
// script between the start and end heights. The notifier's current height is
|
|
||||||
// also returned so that backends can request to be notified of confirmations
|
|
||||||
// from this point forwards.
|
|
||||||
//
|
//
|
||||||
// NOTE: If the transaction/output script has already been included in a block
|
// NOTE: If the transaction/output script has already been included in a block
|
||||||
// on the chain, the confirmation details must be provided with the
|
// on the chain, the confirmation details must be provided with the
|
||||||
// UpdateConfDetails method, otherwise we will wait for the transaction/output
|
// UpdateConfDetails method, otherwise we will wait for the transaction/output
|
||||||
// script to confirm even though it already has.
|
// script to confirm even though it already has.
|
||||||
func (n *TxNotifier) RegisterConf(ntfn *ConfNtfn) (*HistoricalConfDispatch,
|
func (n *TxNotifier) RegisterConf(txid *chainhash.Hash, pkScript []byte,
|
||||||
uint32, error) {
|
numConfs, heightHint uint32) (*ConfRegistration, error) {
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-n.quit:
|
case <-n.quit:
|
||||||
return nil, 0, ErrTxNotifierExiting
|
return nil, ErrTxNotifierExiting
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enforce that we will not dispatch confirmations beyond the reorg
|
// We'll start by performing a series of validation checks.
|
||||||
// safety limit.
|
ntfn, err := n.newConfNtfn(txid, pkScript, numConfs, heightHint)
|
||||||
if ntfn.NumConfirmations > n.reorgSafetyLimit {
|
if err != nil {
|
||||||
return nil, 0, ErrTxMaxConfs
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Log.Infof("New confirmation subscription: %v, num_confs=%v ",
|
||||||
|
ntfn.ConfRequest, numConfs)
|
||||||
|
|
||||||
// Before proceeding to register the notification, we'll query our
|
// Before proceeding to register the notification, we'll query our
|
||||||
// height hint cache to determine whether a better one exists.
|
// height hint cache to determine whether a better one exists.
|
||||||
//
|
//
|
||||||
@ -557,9 +605,16 @@ func (n *TxNotifier) RegisterConf(ntfn *ConfNtfn) (*HistoricalConfDispatch,
|
|||||||
"registration since rescan has finished",
|
"registration since rescan has finished",
|
||||||
ntfn.ConfRequest)
|
ntfn.ConfRequest)
|
||||||
|
|
||||||
return nil, n.currentHeight, n.dispatchConfDetails(
|
err := n.dispatchConfDetails(ntfn, confSet.details)
|
||||||
ntfn, confSet.details,
|
if err != nil {
|
||||||
)
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &ConfRegistration{
|
||||||
|
Event: ntfn.Event,
|
||||||
|
HistoricalDispatch: nil,
|
||||||
|
Height: n.currentHeight,
|
||||||
|
}, nil
|
||||||
|
|
||||||
// A rescan is already in progress, return here to prevent dispatching
|
// A rescan is already in progress, return here to prevent dispatching
|
||||||
// another. When the rescan returns, this notification's details will be
|
// another. When the rescan returns, this notification's details will be
|
||||||
@ -568,7 +623,11 @@ func (n *TxNotifier) RegisterConf(ntfn *ConfNtfn) (*HistoricalConfDispatch,
|
|||||||
Log.Debugf("Waiting for pending rescan to finish before "+
|
Log.Debugf("Waiting for pending rescan to finish before "+
|
||||||
"notifying %v at tip", ntfn.ConfRequest)
|
"notifying %v at tip", ntfn.ConfRequest)
|
||||||
|
|
||||||
return nil, n.currentHeight, nil
|
return &ConfRegistration{
|
||||||
|
Event: ntfn.Event,
|
||||||
|
HistoricalDispatch: nil,
|
||||||
|
Height: n.currentHeight,
|
||||||
|
}, nil
|
||||||
|
|
||||||
// If no rescan has been dispatched, attempt to do so now.
|
// If no rescan has been dispatched, attempt to do so now.
|
||||||
case rescanNotStarted:
|
case rescanNotStarted:
|
||||||
@ -587,7 +646,11 @@ func (n *TxNotifier) RegisterConf(ntfn *ConfNtfn) (*HistoricalConfDispatch,
|
|||||||
// notifier to start delivering messages for this set
|
// notifier to start delivering messages for this set
|
||||||
// immediately.
|
// immediately.
|
||||||
confSet.rescanStatus = rescanComplete
|
confSet.rescanStatus = rescanComplete
|
||||||
return nil, n.currentHeight, nil
|
return &ConfRegistration{
|
||||||
|
Event: ntfn.Event,
|
||||||
|
HistoricalDispatch: nil,
|
||||||
|
Height: n.currentHeight,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.Debugf("Dispatching historical confirmation rescan for %v",
|
Log.Debugf("Dispatching historical confirmation rescan for %v",
|
||||||
@ -607,7 +670,11 @@ func (n *TxNotifier) RegisterConf(ntfn *ConfNtfn) (*HistoricalConfDispatch,
|
|||||||
// registrations don't also attempt a dispatch.
|
// registrations don't also attempt a dispatch.
|
||||||
confSet.rescanStatus = rescanPending
|
confSet.rescanStatus = rescanPending
|
||||||
|
|
||||||
return dispatch, n.currentHeight, nil
|
return &ConfRegistration{
|
||||||
|
Event: ntfn.Event,
|
||||||
|
HistoricalDispatch: dispatch,
|
||||||
|
Height: n.currentHeight,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CancelConf cancels an existing request for a spend notification of an
|
// CancelConf cancels an existing request for a spend notification of an
|
||||||
|
@ -136,22 +136,17 @@ func TestTxNotifierMaxConfs(t *testing.T) {
|
|||||||
|
|
||||||
// Registering one confirmation above the maximum should fail with
|
// Registering one confirmation above the maximum should fail with
|
||||||
// ErrTxMaxConfs.
|
// ErrTxMaxConfs.
|
||||||
ntfn := &chainntnfs.ConfNtfn{
|
_, err := n.RegisterConf(
|
||||||
ConfRequest: chainntnfs.ConfRequest{
|
&chainntnfs.ZeroHash, testRawScript, chainntnfs.MaxNumConfs+1, 1,
|
||||||
TxID: chainntnfs.ZeroHash,
|
)
|
||||||
PkScript: testScript,
|
if err != chainntnfs.ErrTxMaxConfs {
|
||||||
},
|
|
||||||
NumConfirmations: chainntnfs.MaxNumConfs + 1,
|
|
||||||
Event: chainntnfs.NewConfirmationEvent(
|
|
||||||
chainntnfs.MaxNumConfs, nil,
|
|
||||||
),
|
|
||||||
}
|
|
||||||
if _, _, err := n.RegisterConf(ntfn); err != chainntnfs.ErrTxMaxConfs {
|
|
||||||
t.Fatalf("expected chainntnfs.ErrTxMaxConfs, got %v", err)
|
t.Fatalf("expected chainntnfs.ErrTxMaxConfs, got %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ntfn.NumConfirmations--
|
_, err = n.RegisterConf(
|
||||||
if _, _, err := n.RegisterConf(ntfn); err != nil {
|
&chainntnfs.ZeroHash, testRawScript, chainntnfs.MaxNumConfs, 1,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
t.Fatalf("unable to register conf ntfn: %v", err)
|
t.Fatalf("unable to register conf ntfn: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -176,29 +171,17 @@ func TestTxNotifierFutureConfDispatch(t *testing.T) {
|
|||||||
// notifications.
|
// notifications.
|
||||||
tx1 := wire.MsgTx{Version: 1}
|
tx1 := wire.MsgTx{Version: 1}
|
||||||
tx1.AddTxOut(&wire.TxOut{PkScript: testRawScript})
|
tx1.AddTxOut(&wire.TxOut{PkScript: testRawScript})
|
||||||
ntfn1 := chainntnfs.ConfNtfn{
|
tx1Hash := tx1.TxHash()
|
||||||
ConfRequest: chainntnfs.ConfRequest{
|
ntfn1, err := n.RegisterConf(&tx1Hash, testRawScript, tx1NumConfs, 1)
|
||||||
TxID: tx1.TxHash(),
|
if err != nil {
|
||||||
PkScript: testScript,
|
|
||||||
},
|
|
||||||
NumConfirmations: tx1NumConfs,
|
|
||||||
Event: chainntnfs.NewConfirmationEvent(tx1NumConfs, nil),
|
|
||||||
}
|
|
||||||
if _, _, err := n.RegisterConf(&ntfn1); err != nil {
|
|
||||||
t.Fatalf("unable to register ntfn: %v", err)
|
t.Fatalf("unable to register ntfn: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
tx2 := wire.MsgTx{Version: 2}
|
tx2 := wire.MsgTx{Version: 2}
|
||||||
tx2.AddTxOut(&wire.TxOut{PkScript: testRawScript})
|
tx2.AddTxOut(&wire.TxOut{PkScript: testRawScript})
|
||||||
ntfn2 := chainntnfs.ConfNtfn{
|
tx2Hash := tx2.TxHash()
|
||||||
ConfRequest: chainntnfs.ConfRequest{
|
ntfn2, err := n.RegisterConf(&tx2Hash, testRawScript, tx2NumConfs, 1)
|
||||||
TxID: tx2.TxHash(),
|
if err != nil {
|
||||||
PkScript: testScript,
|
|
||||||
},
|
|
||||||
NumConfirmations: tx2NumConfs,
|
|
||||||
Event: chainntnfs.NewConfirmationEvent(tx2NumConfs, nil),
|
|
||||||
}
|
|
||||||
if _, _, err := n.RegisterConf(&ntfn2); err != nil {
|
|
||||||
t.Fatalf("unable to register ntfn: %v", err)
|
t.Fatalf("unable to register ntfn: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,7 +209,7 @@ func TestTxNotifierFutureConfDispatch(t *testing.T) {
|
|||||||
Transactions: []*wire.MsgTx{&tx1, &tx2},
|
Transactions: []*wire.MsgTx{&tx1, &tx2},
|
||||||
})
|
})
|
||||||
|
|
||||||
err := n.ConnectTip(block1.Hash(), 11, block1.Transactions())
|
err = n.ConnectTip(block1.Hash(), 11, block1.Transactions())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to connect block: %v", err)
|
t.Fatalf("Failed to connect block: %v", err)
|
||||||
}
|
}
|
||||||
@ -361,24 +344,14 @@ func TestTxNotifierHistoricalConfDispatch(t *testing.T) {
|
|||||||
// Create the test transactions at a height before the TxNotifier's
|
// Create the test transactions at a height before the TxNotifier's
|
||||||
// starting height so that they are confirmed once registering them.
|
// starting height so that they are confirmed once registering them.
|
||||||
tx1Hash := tx1.TxHash()
|
tx1Hash := tx1.TxHash()
|
||||||
ntfn1 := chainntnfs.ConfNtfn{
|
ntfn1, err := n.RegisterConf(&tx1Hash, testRawScript, tx1NumConfs, 1)
|
||||||
ConfID: 0,
|
if err != nil {
|
||||||
ConfRequest: chainntnfs.ConfRequest{TxID: tx1Hash},
|
|
||||||
NumConfirmations: tx1NumConfs,
|
|
||||||
Event: chainntnfs.NewConfirmationEvent(tx1NumConfs, nil),
|
|
||||||
}
|
|
||||||
if _, _, err := n.RegisterConf(&ntfn1); err != nil {
|
|
||||||
t.Fatalf("unable to register ntfn: %v", err)
|
t.Fatalf("unable to register ntfn: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
tx2Hash := tx2.TxHash()
|
tx2Hash := tx2.TxHash()
|
||||||
ntfn2 := chainntnfs.ConfNtfn{
|
ntfn2, err := n.RegisterConf(&tx2Hash, testRawScript, tx2NumConfs, 1)
|
||||||
ConfID: 1,
|
if err != nil {
|
||||||
ConfRequest: chainntnfs.ConfRequest{TxID: tx2Hash},
|
|
||||||
NumConfirmations: tx2NumConfs,
|
|
||||||
Event: chainntnfs.NewConfirmationEvent(tx2NumConfs, nil),
|
|
||||||
}
|
|
||||||
if _, _, err := n.RegisterConf(&ntfn2); err != nil {
|
|
||||||
t.Fatalf("unable to register ntfn: %v", err)
|
t.Fatalf("unable to register ntfn: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -390,7 +363,7 @@ func TestTxNotifierHistoricalConfDispatch(t *testing.T) {
|
|||||||
TxIndex: 1,
|
TxIndex: 1,
|
||||||
Tx: &tx1,
|
Tx: &tx1,
|
||||||
}
|
}
|
||||||
err := n.UpdateConfDetails(ntfn1.ConfRequest, &txConf1)
|
err = n.UpdateConfDetails(ntfn1.HistoricalDispatch.ConfRequest, &txConf1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to update conf details: %v", err)
|
t.Fatalf("unable to update conf details: %v", err)
|
||||||
}
|
}
|
||||||
@ -424,7 +397,7 @@ func TestTxNotifierHistoricalConfDispatch(t *testing.T) {
|
|||||||
TxIndex: 2,
|
TxIndex: 2,
|
||||||
Tx: &tx2,
|
Tx: &tx2,
|
||||||
}
|
}
|
||||||
err = n.UpdateConfDetails(ntfn2.ConfRequest, &txConf2)
|
err = n.UpdateConfDetails(ntfn2.HistoricalDispatch.ConfRequest, &txConf2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to update conf details: %v", err)
|
t.Fatalf("unable to update conf details: %v", err)
|
||||||
}
|
}
|
||||||
@ -693,34 +666,22 @@ func TestTxNotifierMultipleHistoricalConfRescans(t *testing.T) {
|
|||||||
// The first registration for a transaction in the notifier should
|
// The first registration for a transaction in the notifier should
|
||||||
// request a historical confirmation rescan as it does not have a
|
// request a historical confirmation rescan as it does not have a
|
||||||
// historical view of the chain.
|
// historical view of the chain.
|
||||||
confNtfn1 := &chainntnfs.ConfNtfn{
|
ntfn1, err := n.RegisterConf(&chainntnfs.ZeroHash, testRawScript, 1, 1)
|
||||||
ConfID: 0,
|
|
||||||
// TODO(wilmer): set pkScript.
|
|
||||||
ConfRequest: chainntnfs.ConfRequest{TxID: chainntnfs.ZeroHash},
|
|
||||||
Event: chainntnfs.NewConfirmationEvent(1, nil),
|
|
||||||
}
|
|
||||||
historicalConfDispatch1, _, err := n.RegisterConf(confNtfn1)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to register spend ntfn: %v", err)
|
t.Fatalf("unable to register spend ntfn: %v", err)
|
||||||
}
|
}
|
||||||
if historicalConfDispatch1 == nil {
|
if ntfn1.HistoricalDispatch == nil {
|
||||||
t.Fatal("expected to receive historical dispatch request")
|
t.Fatal("expected to receive historical dispatch request")
|
||||||
}
|
}
|
||||||
|
|
||||||
// We'll register another confirmation notification for the same
|
// We'll register another confirmation notification for the same
|
||||||
// transaction. This should not request a historical confirmation rescan
|
// transaction. This should not request a historical confirmation rescan
|
||||||
// since the first one is still pending.
|
// since the first one is still pending.
|
||||||
confNtfn2 := &chainntnfs.ConfNtfn{
|
ntfn2, err := n.RegisterConf(&chainntnfs.ZeroHash, testRawScript, 1, 1)
|
||||||
ConfID: 1,
|
|
||||||
// TODO(wilmer): set pkScript.
|
|
||||||
ConfRequest: chainntnfs.ConfRequest{TxID: chainntnfs.ZeroHash},
|
|
||||||
Event: chainntnfs.NewConfirmationEvent(1, nil),
|
|
||||||
}
|
|
||||||
historicalConfDispatch2, _, err := n.RegisterConf(confNtfn2)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to register spend ntfn: %v", err)
|
t.Fatalf("unable to register spend ntfn: %v", err)
|
||||||
}
|
}
|
||||||
if historicalConfDispatch2 != nil {
|
if ntfn2.HistoricalDispatch != nil {
|
||||||
t.Fatal("received unexpected historical rescan request")
|
t.Fatal("received unexpected historical rescan request")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -731,21 +692,16 @@ func TestTxNotifierMultipleHistoricalConfRescans(t *testing.T) {
|
|||||||
confDetails := &chainntnfs.TxConfirmation{
|
confDetails := &chainntnfs.TxConfirmation{
|
||||||
BlockHeight: startingHeight - 1,
|
BlockHeight: startingHeight - 1,
|
||||||
}
|
}
|
||||||
err = n.UpdateConfDetails(confNtfn2.ConfRequest, confDetails)
|
err = n.UpdateConfDetails(ntfn1.HistoricalDispatch.ConfRequest, confDetails)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to update conf details: %v", err)
|
t.Fatalf("unable to update conf details: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
confNtfn3 := &chainntnfs.ConfNtfn{
|
ntfn3, err := n.RegisterConf(&chainntnfs.ZeroHash, testRawScript, 1, 1)
|
||||||
ConfID: 2,
|
|
||||||
ConfRequest: chainntnfs.ConfRequest{TxID: chainntnfs.ZeroHash},
|
|
||||||
Event: chainntnfs.NewConfirmationEvent(1, nil),
|
|
||||||
}
|
|
||||||
historicalConfDispatch3, _, err := n.RegisterConf(confNtfn3)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to register spend ntfn: %v", err)
|
t.Fatalf("unable to register spend ntfn: %v", err)
|
||||||
}
|
}
|
||||||
if historicalConfDispatch3 != nil {
|
if ntfn3.HistoricalDispatch != nil {
|
||||||
t.Fatal("received unexpected historical rescan request")
|
t.Fatal("received unexpected historical rescan request")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -848,23 +804,16 @@ func TestTxNotifierMultipleHistoricalNtfns(t *testing.T) {
|
|||||||
|
|
||||||
var txid chainhash.Hash
|
var txid chainhash.Hash
|
||||||
copy(txid[:], bytes.Repeat([]byte{0x01}, 32))
|
copy(txid[:], bytes.Repeat([]byte{0x01}, 32))
|
||||||
confRequest := chainntnfs.ConfRequest{
|
|
||||||
// TODO(wilmer): set pkScript.
|
|
||||||
TxID: txid,
|
|
||||||
}
|
|
||||||
|
|
||||||
// We'll start off by registered 5 clients for a confirmation
|
// We'll start off by registered 5 clients for a confirmation
|
||||||
// notification on the same transaction.
|
// notification on the same transaction.
|
||||||
confNtfns := make([]*chainntnfs.ConfNtfn, numNtfns)
|
confNtfns := make([]*chainntnfs.ConfRegistration, numNtfns)
|
||||||
for i := uint64(0); i < numNtfns; i++ {
|
for i := uint64(0); i < numNtfns; i++ {
|
||||||
confNtfns[i] = &chainntnfs.ConfNtfn{
|
ntfn, err := n.RegisterConf(&txid, testRawScript, 1, 1)
|
||||||
ConfID: i,
|
if err != nil {
|
||||||
ConfRequest: confRequest,
|
|
||||||
Event: chainntnfs.NewConfirmationEvent(1, nil),
|
|
||||||
}
|
|
||||||
if _, _, err := n.RegisterConf(confNtfns[i]); err != nil {
|
|
||||||
t.Fatalf("unable to register conf ntfn #%d: %v", i, err)
|
t.Fatalf("unable to register conf ntfn #%d: %v", i, err)
|
||||||
}
|
}
|
||||||
|
confNtfns[i] = ntfn
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure none of them have received the confirmation details.
|
// Ensure none of them have received the confirmation details.
|
||||||
@ -884,7 +833,9 @@ func TestTxNotifierMultipleHistoricalNtfns(t *testing.T) {
|
|||||||
BlockHeight: startingHeight - 1,
|
BlockHeight: startingHeight - 1,
|
||||||
Tx: wire.NewMsgTx(1),
|
Tx: wire.NewMsgTx(1),
|
||||||
}
|
}
|
||||||
err := n.UpdateConfDetails(confNtfns[0].ConfRequest, expectedConfDetails)
|
err := n.UpdateConfDetails(
|
||||||
|
confNtfns[0].HistoricalDispatch.ConfRequest, expectedConfDetails,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to update conf details: %v", err)
|
t.Fatalf("unable to update conf details: %v", err)
|
||||||
}
|
}
|
||||||
@ -905,16 +856,11 @@ func TestTxNotifierMultipleHistoricalNtfns(t *testing.T) {
|
|||||||
// we'll register another client for the same transaction. We should not
|
// we'll register another client for the same transaction. We should not
|
||||||
// see a historical rescan request and the confirmation notification
|
// see a historical rescan request and the confirmation notification
|
||||||
// should come through immediately.
|
// should come through immediately.
|
||||||
extraConfNtfn := &chainntnfs.ConfNtfn{
|
extraConfNtfn, err := n.RegisterConf(&txid, testRawScript, 1, 1)
|
||||||
ConfID: numNtfns + 1,
|
|
||||||
ConfRequest: confRequest,
|
|
||||||
Event: chainntnfs.NewConfirmationEvent(1, nil),
|
|
||||||
}
|
|
||||||
historicalConfRescan, _, err := n.RegisterConf(extraConfNtfn)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to register conf ntfn: %v", err)
|
t.Fatalf("unable to register conf ntfn: %v", err)
|
||||||
}
|
}
|
||||||
if historicalConfRescan != nil {
|
if extraConfNtfn.HistoricalDispatch != nil {
|
||||||
t.Fatal("received unexpected historical rescan request")
|
t.Fatal("received unexpected historical rescan request")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1016,31 +962,17 @@ func TestTxNotifierCancelConf(t *testing.T) {
|
|||||||
// canceled.
|
// canceled.
|
||||||
tx1 := wire.NewMsgTx(1)
|
tx1 := wire.NewMsgTx(1)
|
||||||
tx1.AddTxOut(&wire.TxOut{PkScript: testRawScript})
|
tx1.AddTxOut(&wire.TxOut{PkScript: testRawScript})
|
||||||
ntfn1 := &chainntnfs.ConfNtfn{
|
tx1Hash := tx1.TxHash()
|
||||||
ConfID: 1,
|
ntfn1, err := n.RegisterConf(&tx1Hash, testRawScript, 1, 1)
|
||||||
ConfRequest: chainntnfs.ConfRequest{
|
if err != nil {
|
||||||
TxID: tx1.TxHash(),
|
|
||||||
PkScript: testScript,
|
|
||||||
},
|
|
||||||
NumConfirmations: 1,
|
|
||||||
Event: chainntnfs.NewConfirmationEvent(1, nil),
|
|
||||||
}
|
|
||||||
if _, _, err := n.RegisterConf(ntfn1); err != nil {
|
|
||||||
t.Fatalf("unable to register spend ntfn: %v", err)
|
t.Fatalf("unable to register spend ntfn: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
tx2 := wire.NewMsgTx(2)
|
tx2 := wire.NewMsgTx(2)
|
||||||
tx2.AddTxOut(&wire.TxOut{PkScript: testRawScript})
|
tx2.AddTxOut(&wire.TxOut{PkScript: testRawScript})
|
||||||
ntfn2 := &chainntnfs.ConfNtfn{
|
tx2Hash := tx2.TxHash()
|
||||||
ConfID: 2,
|
ntfn2, err := n.RegisterConf(&tx2Hash, testRawScript, 1, 1)
|
||||||
ConfRequest: chainntnfs.ConfRequest{
|
if err != nil {
|
||||||
TxID: tx2.TxHash(),
|
|
||||||
PkScript: testScript,
|
|
||||||
},
|
|
||||||
NumConfirmations: 1,
|
|
||||||
Event: chainntnfs.NewConfirmationEvent(1, nil),
|
|
||||||
}
|
|
||||||
if _, _, err := n.RegisterConf(ntfn2); err != nil {
|
|
||||||
t.Fatalf("unable to register spend ntfn: %v", err)
|
t.Fatalf("unable to register spend ntfn: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1057,9 +989,9 @@ func TestTxNotifierCancelConf(t *testing.T) {
|
|||||||
|
|
||||||
// Before extending the notifier's tip with the block above, we'll
|
// Before extending the notifier's tip with the block above, we'll
|
||||||
// cancel the second request.
|
// cancel the second request.
|
||||||
n.CancelConf(ntfn2.ConfRequest, ntfn2.ConfID)
|
n.CancelConf(ntfn2.HistoricalDispatch.ConfRequest, 2)
|
||||||
|
|
||||||
err := n.ConnectTip(block.Hash(), startingHeight+1, block.Transactions())
|
err = n.ConnectTip(block.Hash(), startingHeight+1, block.Transactions())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to connect block: %v", err)
|
t.Fatalf("unable to connect block: %v", err)
|
||||||
}
|
}
|
||||||
@ -1200,60 +1132,42 @@ func TestTxNotifierConfReorg(t *testing.T) {
|
|||||||
// Tx 1 will be confirmed in block 9 and requires 2 confs.
|
// Tx 1 will be confirmed in block 9 and requires 2 confs.
|
||||||
tx1 := wire.MsgTx{Version: 1}
|
tx1 := wire.MsgTx{Version: 1}
|
||||||
tx1.AddTxOut(&wire.TxOut{PkScript: testRawScript})
|
tx1.AddTxOut(&wire.TxOut{PkScript: testRawScript})
|
||||||
ntfn1 := chainntnfs.ConfNtfn{
|
tx1Hash := tx1.TxHash()
|
||||||
ConfID: 1,
|
ntfn1, err := n.RegisterConf(&tx1Hash, testRawScript, tx1NumConfs, 1)
|
||||||
ConfRequest: chainntnfs.ConfRequest{
|
if err != nil {
|
||||||
TxID: tx1.TxHash(),
|
|
||||||
PkScript: testScript,
|
|
||||||
},
|
|
||||||
NumConfirmations: tx1NumConfs,
|
|
||||||
Event: chainntnfs.NewConfirmationEvent(tx1NumConfs, nil),
|
|
||||||
}
|
|
||||||
if _, _, err := n.RegisterConf(&ntfn1); err != nil {
|
|
||||||
t.Fatalf("unable to register ntfn: %v", err)
|
t.Fatalf("unable to register ntfn: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := n.UpdateConfDetails(ntfn1.ConfRequest, nil); err != nil {
|
err = n.UpdateConfDetails(ntfn1.HistoricalDispatch.ConfRequest, nil)
|
||||||
|
if err != nil {
|
||||||
t.Fatalf("unable to deliver conf details: %v", err)
|
t.Fatalf("unable to deliver conf details: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tx 2 will be confirmed in block 10 and requires 1 conf.
|
// Tx 2 will be confirmed in block 10 and requires 1 conf.
|
||||||
tx2 := wire.MsgTx{Version: 2}
|
tx2 := wire.MsgTx{Version: 2}
|
||||||
tx2.AddTxOut(&wire.TxOut{PkScript: testRawScript})
|
tx2.AddTxOut(&wire.TxOut{PkScript: testRawScript})
|
||||||
ntfn2 := chainntnfs.ConfNtfn{
|
tx2Hash := tx2.TxHash()
|
||||||
ConfID: 2,
|
ntfn2, err := n.RegisterConf(&tx2Hash, testRawScript, tx2NumConfs, 1)
|
||||||
ConfRequest: chainntnfs.ConfRequest{
|
if err != nil {
|
||||||
TxID: tx2.TxHash(),
|
|
||||||
PkScript: testScript,
|
|
||||||
},
|
|
||||||
NumConfirmations: tx2NumConfs,
|
|
||||||
Event: chainntnfs.NewConfirmationEvent(tx2NumConfs, nil),
|
|
||||||
}
|
|
||||||
if _, _, err := n.RegisterConf(&ntfn2); err != nil {
|
|
||||||
t.Fatalf("unable to register ntfn: %v", err)
|
t.Fatalf("unable to register ntfn: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := n.UpdateConfDetails(ntfn2.ConfRequest, nil); err != nil {
|
err = n.UpdateConfDetails(ntfn2.HistoricalDispatch.ConfRequest, nil)
|
||||||
|
if err != nil {
|
||||||
t.Fatalf("unable to deliver conf details: %v", err)
|
t.Fatalf("unable to deliver conf details: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tx 3 will be confirmed in block 10 and requires 2 confs.
|
// Tx 3 will be confirmed in block 10 and requires 2 confs.
|
||||||
tx3 := wire.MsgTx{Version: 3}
|
tx3 := wire.MsgTx{Version: 3}
|
||||||
tx3.AddTxOut(&wire.TxOut{PkScript: testRawScript})
|
tx3.AddTxOut(&wire.TxOut{PkScript: testRawScript})
|
||||||
ntfn3 := chainntnfs.ConfNtfn{
|
tx3Hash := tx3.TxHash()
|
||||||
ConfID: 3,
|
ntfn3, err := n.RegisterConf(&tx3Hash, testRawScript, tx3NumConfs, 1)
|
||||||
ConfRequest: chainntnfs.ConfRequest{
|
if err != nil {
|
||||||
TxID: tx3.TxHash(),
|
|
||||||
PkScript: testScript,
|
|
||||||
},
|
|
||||||
NumConfirmations: tx3NumConfs,
|
|
||||||
Event: chainntnfs.NewConfirmationEvent(tx3NumConfs, nil),
|
|
||||||
}
|
|
||||||
if _, _, err := n.RegisterConf(&ntfn3); err != nil {
|
|
||||||
t.Fatalf("unable to register ntfn: %v", err)
|
t.Fatalf("unable to register ntfn: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := n.UpdateConfDetails(ntfn3.ConfRequest, nil); err != nil {
|
err = n.UpdateConfDetails(ntfn3.HistoricalDispatch.ConfRequest, nil)
|
||||||
|
if err != nil {
|
||||||
t.Fatalf("unable to deliver conf details: %v", err)
|
t.Fatalf("unable to deliver conf details: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1397,7 +1311,7 @@ func TestTxNotifierConfReorg(t *testing.T) {
|
|||||||
})
|
})
|
||||||
block4 := btcutil.NewBlock(&wire.MsgBlock{})
|
block4 := btcutil.NewBlock(&wire.MsgBlock{})
|
||||||
|
|
||||||
err := n.ConnectTip(block3.Hash(), 12, block3.Transactions())
|
err = n.ConnectTip(block3.Hash(), 12, block3.Transactions())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to connect block: %v", err)
|
t.Fatalf("Failed to connect block: %v", err)
|
||||||
}
|
}
|
||||||
@ -1726,45 +1640,30 @@ func TestTxNotifierConfirmHintCache(t *testing.T) {
|
|||||||
// Create two test transactions and register them for notifications.
|
// Create two test transactions and register them for notifications.
|
||||||
tx1 := wire.MsgTx{Version: 1}
|
tx1 := wire.MsgTx{Version: 1}
|
||||||
tx1.AddTxOut(&wire.TxOut{PkScript: testRawScript})
|
tx1.AddTxOut(&wire.TxOut{PkScript: testRawScript})
|
||||||
ntfn1 := &chainntnfs.ConfNtfn{
|
tx1Hash := tx1.TxHash()
|
||||||
ConfID: 1,
|
ntfn1, err := n.RegisterConf(&tx1Hash, testRawScript, 1, 1)
|
||||||
ConfRequest: chainntnfs.ConfRequest{
|
if err != nil {
|
||||||
TxID: tx1.TxHash(),
|
t.Fatalf("unable to register tx1: %v", err)
|
||||||
PkScript: testScript,
|
|
||||||
},
|
|
||||||
NumConfirmations: 1,
|
|
||||||
Event: chainntnfs.NewConfirmationEvent(1, nil),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tx2 := wire.MsgTx{Version: 2}
|
tx2 := wire.MsgTx{Version: 2}
|
||||||
tx2.AddTxOut(&wire.TxOut{PkScript: testRawScript})
|
tx2.AddTxOut(&wire.TxOut{PkScript: testRawScript})
|
||||||
ntfn2 := &chainntnfs.ConfNtfn{
|
tx2Hash := tx2.TxHash()
|
||||||
ConfID: 2,
|
ntfn2, err := n.RegisterConf(&tx2Hash, testRawScript, 2, 1)
|
||||||
ConfRequest: chainntnfs.ConfRequest{
|
if err != nil {
|
||||||
TxID: tx2.TxHash(),
|
|
||||||
PkScript: testScript,
|
|
||||||
},
|
|
||||||
NumConfirmations: 2,
|
|
||||||
Event: chainntnfs.NewConfirmationEvent(2, nil),
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, _, err := n.RegisterConf(ntfn1); err != nil {
|
|
||||||
t.Fatalf("unable to register tx1: %v", err)
|
|
||||||
}
|
|
||||||
if _, _, err := n.RegisterConf(ntfn2); err != nil {
|
|
||||||
t.Fatalf("unable to register tx2: %v", err)
|
t.Fatalf("unable to register tx2: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Both transactions should not have a height hint set, as RegisterConf
|
// Both transactions should not have a height hint set, as RegisterConf
|
||||||
// should not alter the cache state.
|
// should not alter the cache state.
|
||||||
_, err := hintCache.QueryConfirmHint(ntfn1.ConfRequest)
|
_, err = hintCache.QueryConfirmHint(ntfn1.HistoricalDispatch.ConfRequest)
|
||||||
if err != chainntnfs.ErrConfirmHintNotFound {
|
if err != chainntnfs.ErrConfirmHintNotFound {
|
||||||
t.Fatalf("unexpected error when querying for height hint "+
|
t.Fatalf("unexpected error when querying for height hint "+
|
||||||
"want: %v, got %v",
|
"want: %v, got %v",
|
||||||
chainntnfs.ErrConfirmHintNotFound, err)
|
chainntnfs.ErrConfirmHintNotFound, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = hintCache.QueryConfirmHint(ntfn2.ConfRequest)
|
_, err = hintCache.QueryConfirmHint(ntfn2.HistoricalDispatch.ConfRequest)
|
||||||
if err != chainntnfs.ErrConfirmHintNotFound {
|
if err != chainntnfs.ErrConfirmHintNotFound {
|
||||||
t.Fatalf("unexpected error when querying for height hint "+
|
t.Fatalf("unexpected error when querying for height hint "+
|
||||||
"want: %v, got %v",
|
"want: %v, got %v",
|
||||||
@ -1790,14 +1689,14 @@ func TestTxNotifierConfirmHintCache(t *testing.T) {
|
|||||||
// the height hints should remain unchanged. This simulates blocks
|
// the height hints should remain unchanged. This simulates blocks
|
||||||
// confirming while the historical dispatch is processing the
|
// confirming while the historical dispatch is processing the
|
||||||
// registration.
|
// registration.
|
||||||
hint, err := hintCache.QueryConfirmHint(ntfn1.ConfRequest)
|
hint, err := hintCache.QueryConfirmHint(ntfn1.HistoricalDispatch.ConfRequest)
|
||||||
if err != chainntnfs.ErrConfirmHintNotFound {
|
if err != chainntnfs.ErrConfirmHintNotFound {
|
||||||
t.Fatalf("unexpected error when querying for height hint "+
|
t.Fatalf("unexpected error when querying for height hint "+
|
||||||
"want: %v, got %v",
|
"want: %v, got %v",
|
||||||
chainntnfs.ErrConfirmHintNotFound, err)
|
chainntnfs.ErrConfirmHintNotFound, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
hint, err = hintCache.QueryConfirmHint(ntfn2.ConfRequest)
|
hint, err = hintCache.QueryConfirmHint(ntfn2.HistoricalDispatch.ConfRequest)
|
||||||
if err != chainntnfs.ErrConfirmHintNotFound {
|
if err != chainntnfs.ErrConfirmHintNotFound {
|
||||||
t.Fatalf("unexpected error when querying for height hint "+
|
t.Fatalf("unexpected error when querying for height hint "+
|
||||||
"want: %v, got %v",
|
"want: %v, got %v",
|
||||||
@ -1806,10 +1705,12 @@ func TestTxNotifierConfirmHintCache(t *testing.T) {
|
|||||||
|
|
||||||
// Now, update the conf details reporting that the neither txn was found
|
// Now, update the conf details reporting that the neither txn was found
|
||||||
// in the historical dispatch.
|
// in the historical dispatch.
|
||||||
if err := n.UpdateConfDetails(ntfn1.ConfRequest, nil); err != nil {
|
err = n.UpdateConfDetails(ntfn1.HistoricalDispatch.ConfRequest, nil)
|
||||||
|
if err != nil {
|
||||||
t.Fatalf("unable to update conf details: %v", err)
|
t.Fatalf("unable to update conf details: %v", err)
|
||||||
}
|
}
|
||||||
if err := n.UpdateConfDetails(ntfn2.ConfRequest, nil); err != nil {
|
err = n.UpdateConfDetails(ntfn2.HistoricalDispatch.ConfRequest, nil)
|
||||||
|
if err != nil {
|
||||||
t.Fatalf("unable to update conf details: %v", err)
|
t.Fatalf("unable to update conf details: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1830,7 +1731,7 @@ func TestTxNotifierConfirmHintCache(t *testing.T) {
|
|||||||
// Now that both notifications are waiting at tip for confirmations,
|
// Now that both notifications are waiting at tip for confirmations,
|
||||||
// they should have their height hints updated to the latest block
|
// they should have their height hints updated to the latest block
|
||||||
// height.
|
// height.
|
||||||
hint, err = hintCache.QueryConfirmHint(ntfn1.ConfRequest)
|
hint, err = hintCache.QueryConfirmHint(ntfn1.HistoricalDispatch.ConfRequest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to query for hint: %v", err)
|
t.Fatalf("unable to query for hint: %v", err)
|
||||||
}
|
}
|
||||||
@ -1839,7 +1740,7 @@ func TestTxNotifierConfirmHintCache(t *testing.T) {
|
|||||||
tx1Height, hint)
|
tx1Height, hint)
|
||||||
}
|
}
|
||||||
|
|
||||||
hint, err = hintCache.QueryConfirmHint(ntfn2.ConfRequest)
|
hint, err = hintCache.QueryConfirmHint(ntfn2.HistoricalDispatch.ConfRequest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to query for hint: %v", err)
|
t.Fatalf("unable to query for hint: %v", err)
|
||||||
}
|
}
|
||||||
@ -1863,7 +1764,7 @@ func TestTxNotifierConfirmHintCache(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The height hint for the first transaction should remain the same.
|
// The height hint for the first transaction should remain the same.
|
||||||
hint, err = hintCache.QueryConfirmHint(ntfn1.ConfRequest)
|
hint, err = hintCache.QueryConfirmHint(ntfn1.HistoricalDispatch.ConfRequest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to query for hint: %v", err)
|
t.Fatalf("unable to query for hint: %v", err)
|
||||||
}
|
}
|
||||||
@ -1874,7 +1775,7 @@ func TestTxNotifierConfirmHintCache(t *testing.T) {
|
|||||||
|
|
||||||
// The height hint for the second transaction should now be updated to
|
// The height hint for the second transaction should now be updated to
|
||||||
// reflect its confirmation.
|
// reflect its confirmation.
|
||||||
hint, err = hintCache.QueryConfirmHint(ntfn2.ConfRequest)
|
hint, err = hintCache.QueryConfirmHint(ntfn2.HistoricalDispatch.ConfRequest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to query for hint: %v", err)
|
t.Fatalf("unable to query for hint: %v", err)
|
||||||
}
|
}
|
||||||
@ -1891,7 +1792,7 @@ func TestTxNotifierConfirmHintCache(t *testing.T) {
|
|||||||
|
|
||||||
// This should update the second transaction's height hint within the
|
// This should update the second transaction's height hint within the
|
||||||
// cache to the previous height.
|
// cache to the previous height.
|
||||||
hint, err = hintCache.QueryConfirmHint(ntfn2.ConfRequest)
|
hint, err = hintCache.QueryConfirmHint(ntfn2.HistoricalDispatch.ConfRequest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to query for hint: %v", err)
|
t.Fatalf("unable to query for hint: %v", err)
|
||||||
}
|
}
|
||||||
@ -1902,7 +1803,7 @@ func TestTxNotifierConfirmHintCache(t *testing.T) {
|
|||||||
|
|
||||||
// The first transaction's height hint should remain at the original
|
// The first transaction's height hint should remain at the original
|
||||||
// confirmation height.
|
// confirmation height.
|
||||||
hint, err = hintCache.QueryConfirmHint(ntfn2.ConfRequest)
|
hint, err = hintCache.QueryConfirmHint(ntfn2.HistoricalDispatch.ConfRequest)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to query for hint: %v", err)
|
t.Fatalf("unable to query for hint: %v", err)
|
||||||
}
|
}
|
||||||
@ -2122,16 +2023,8 @@ func TestTxNotifierNtfnDone(t *testing.T) {
|
|||||||
|
|
||||||
// We'll start by creating two notification requests: one confirmation
|
// We'll start by creating two notification requests: one confirmation
|
||||||
// and one spend.
|
// and one spend.
|
||||||
confNtfn := &chainntnfs.ConfNtfn{
|
confNtfn, err := n.RegisterConf(&chainntnfs.ZeroHash, testRawScript, 1, 1)
|
||||||
ConfID: 1,
|
if err != nil {
|
||||||
ConfRequest: chainntnfs.ConfRequest{
|
|
||||||
TxID: chainntnfs.ZeroHash,
|
|
||||||
PkScript: testScript,
|
|
||||||
},
|
|
||||||
NumConfirmations: 1,
|
|
||||||
Event: chainntnfs.NewConfirmationEvent(1, nil),
|
|
||||||
}
|
|
||||||
if _, _, err := n.RegisterConf(confNtfn); err != nil {
|
|
||||||
t.Fatalf("unable to register conf ntfn: %v", err)
|
t.Fatalf("unable to register conf ntfn: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2160,7 +2053,7 @@ func TestTxNotifierNtfnDone(t *testing.T) {
|
|||||||
Transactions: []*wire.MsgTx{tx, spendTx},
|
Transactions: []*wire.MsgTx{tx, spendTx},
|
||||||
})
|
})
|
||||||
|
|
||||||
err := n.ConnectTip(block.Hash(), 11, block.Transactions())
|
err = n.ConnectTip(block.Hash(), 11, block.Transactions())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unable to connect block: %v", err)
|
t.Fatalf("unable to connect block: %v", err)
|
||||||
}
|
}
|
||||||
@ -2268,13 +2161,8 @@ func TestTxNotifierTearDown(t *testing.T) {
|
|||||||
|
|
||||||
// To begin the test, we'll register for a confirmation and spend
|
// To begin the test, we'll register for a confirmation and spend
|
||||||
// notification.
|
// notification.
|
||||||
confNtfn := &chainntnfs.ConfNtfn{
|
confNtfn, err := n.RegisterConf(&chainntnfs.ZeroHash, testRawScript, 1, 1)
|
||||||
ConfID: 1,
|
if err != nil {
|
||||||
ConfRequest: chainntnfs.ConfRequest{TxID: chainntnfs.ZeroHash},
|
|
||||||
NumConfirmations: 1,
|
|
||||||
Event: chainntnfs.NewConfirmationEvent(1, nil),
|
|
||||||
}
|
|
||||||
if _, _, err := n.RegisterConf(confNtfn); err != nil {
|
|
||||||
t.Fatalf("unable to register conf ntfn: %v", err)
|
t.Fatalf("unable to register conf ntfn: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2320,7 +2208,8 @@ func TestTxNotifierTearDown(t *testing.T) {
|
|||||||
|
|
||||||
// Now that the notifier is torn down, we should no longer be able to
|
// Now that the notifier is torn down, we should no longer be able to
|
||||||
// register notification requests.
|
// register notification requests.
|
||||||
if _, _, err := n.RegisterConf(confNtfn); err == nil {
|
_, err = n.RegisterConf(&chainntnfs.ZeroHash, testRawScript, 1, 1)
|
||||||
|
if err == nil {
|
||||||
t.Fatal("expected confirmation registration to fail")
|
t.Fatal("expected confirmation registration to fail")
|
||||||
}
|
}
|
||||||
if _, _, err := n.RegisterSpend(spendNtfn); err == nil {
|
if _, _, err := n.RegisterSpend(spendNtfn); err == nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user