chainntnfs/btcd+bitcoind: use common TxConfStatus

This commit is contained in:
Johan T. Halseth committed 2018-08-24 14:46:20 +02:00
1 parent b552984fcd
commit 79b2ee7da5
2 files changed
+63 -102

No files matched your search

+31 -51
View File
@@ -28,31 +28,6 @@ const (
reorgSafetyLimit = 100 reorgSafetyLimit = 100
) )
// txConfStatus denotes the status of a transaction's lookup.
type txConfStatus uint8
const (
// txFoundMempool denotes that the transaction was found within the
// backend node's mempool.
txFoundMempool txConfStatus = iota
// txFoundIndex denotes that the transaction was found within the
// backend node's txindex.
txFoundIndex
// txFoundIndex denotes that the transaction was not found within the
// backend node's txindex.
txNotFoundIndex
// txFoundManually denotes that the transaction was found within the
// chain by scanning for it manually.
txFoundManually
// txFoundManually denotes that the transaction was not found within the
// chain by scanning for it manually.
txNotFoundManually
)
var ( var (
// ErrChainNotifierShuttingDown is used when we are trying to // ErrChainNotifierShuttingDown is used when we are trying to
// measure a spend notification when notifier is already stopped. // measure a spend notification when notifier is already stopped.
@@ -474,7 +449,7 @@ func (b *BitcoindNotifier) handleRelevantTx(tx chain.RelevantTx, bestHeight int3
// block in the active chain and, if so, returns details about the confirmation. // block in the active chain and, if so, returns details about the confirmation.
func (b *BitcoindNotifier) historicalConfDetails(txid *chainhash.Hash, func (b *BitcoindNotifier) historicalConfDetails(txid *chainhash.Hash,
heightHint, currentHeight uint32) (*chainntnfs.TxConfirmation, heightHint, currentHeight uint32) (*chainntnfs.TxConfirmation,
txConfStatus, error) { chainntnfs.TxConfStatus, error) {
// We'll first attempt to retrieve the transaction using the node's // We'll first attempt to retrieve the transaction using the node's
// txindex. // txindex.
@@ -484,13 +459,13 @@ func (b *BitcoindNotifier) historicalConfDetails(txid *chainhash.Hash,
// determine whether we should proceed with any fallback methods. // determine whether we should proceed with any fallback methods.
switch { switch {
// The transaction was found within the node's mempool. // The transaction was found within the node's mempool.
case txStatus == txFoundMempool: case txStatus == chainntnfs.TxFoundMempool:
// The transaction was found within the node's txindex. // The transaction was found within the node's txindex.
case txStatus == txFoundIndex: case txStatus == chainntnfs.TxFoundIndex:
// The transaction was not found within the node's mempool or txindex. // The transaction was not found within the node's mempool or txindex.
case err == nil && txStatus == txNotFoundIndex: case err == nil && txStatus == chainntnfs.TxNotFoundIndex:
// We failed to look up the transaction within the node's mempool or // We failed to look up the transaction within the node's mempool or
// txindex, so we'll proceed to scan the chain manually. // txindex, so we'll proceed to scan the chain manually.
@@ -508,7 +483,7 @@ func (b *BitcoindNotifier) historicalConfDetails(txid *chainhash.Hash,
// be TxFoundIndex. Otherwise TxNotFoundIndex is returned. If the tx is found // be TxFoundIndex. Otherwise TxNotFoundIndex is returned. If the tx is found
// in a block its confirmation details are also returned. // in a block its confirmation details are also returned.
func (b *BitcoindNotifier) confDetailsFromTxIndex(txid *chainhash.Hash, func (b *BitcoindNotifier) confDetailsFromTxIndex(txid *chainhash.Hash,
) (*chainntnfs.TxConfirmation, txConfStatus, error) { ) (*chainntnfs.TxConfirmation, chainntnfs.TxConfStatus, error) {
// If the transaction has some or all of its confirmations required, // If the transaction has some or all of its confirmations required,
// then we may be able to dispatch it immediately. // then we may be able to dispatch it immediately.
@@ -523,18 +498,18 @@ func (b *BitcoindNotifier) confDetailsFromTxIndex(txid *chainhash.Hash,
if ok && jsonErr.Code == btcjson.ErrRPCNoTxInfo && if ok && jsonErr.Code == btcjson.ErrRPCNoTxInfo &&
strings.Contains(jsonErr.Message, txNotFoundErr) { strings.Contains(jsonErr.Message, txNotFoundErr) {
return nil, txNotFoundIndex, nil return nil, chainntnfs.TxNotFoundIndex, nil
} }
return nil, txNotFoundIndex, fmt.Errorf("unable to query for "+ return nil, chainntnfs.TxNotFoundIndex,
"txid %v: %v", txid, err) fmt.Errorf("unable to query for txid %v: %v", txid, err)
} }
// Make sure we actually retrieved a transaction that is included in a // Make sure we actually retrieved a transaction that is included in a
// block. If not, the transaction must be unconfirmed (in the mempool), // block. If not, the transaction must be unconfirmed (in the mempool),
// and we'll return TxFoundMempool together with a nil TxConfirmation. // and we'll return TxFoundMempool together with a nil TxConfirmation.
if tx.BlockHash == "" { if tx.BlockHash == "" {
return nil, txFoundMempool, nil return nil, chainntnfs.TxFoundMempool, nil
} }
// As we need to fully populate the returned TxConfirmation struct, // As we need to fully populate the returned TxConfirmation struct,
@@ -542,16 +517,16 @@ func (b *BitcoindNotifier) confDetailsFromTxIndex(txid *chainhash.Hash,
// locate its exact index within the block. // locate its exact index within the block.
blockHash, err := chainhash.NewHashFromStr(tx.BlockHash) blockHash, err := chainhash.NewHashFromStr(tx.BlockHash)
if err != nil { if err != nil {
return nil, txNotFoundIndex, fmt.Errorf("unable to get block "+ return nil, chainntnfs.TxNotFoundIndex,
"hash %v for historical dispatch: %v", tx.BlockHash, fmt.Errorf("unable to get block hash %v for "+
err) "historical dispatch: %v", tx.BlockHash, err)
} }
block, err := b.chainConn.GetBlockVerbose(blockHash) block, err := b.chainConn.GetBlockVerbose(blockHash)
if err != nil { if err != nil {
return nil, txNotFoundIndex, fmt.Errorf("unable to get block "+ return nil, chainntnfs.TxNotFoundIndex,
"with hash %v for historical dispatch: %v", blockHash, fmt.Errorf("unable to get block with hash %v for "+
err) "historical dispatch: %v", blockHash, err)
} }
// If the block was obtained, locate the transaction's index within the // If the block was obtained, locate the transaction's index within the
@@ -564,14 +539,15 @@ func (b *BitcoindNotifier) confDetailsFromTxIndex(txid *chainhash.Hash,
BlockHeight: uint32(block.Height), BlockHeight: uint32(block.Height),
TxIndex: uint32(txIndex), TxIndex: uint32(txIndex),
} }
return details, txFoundIndex, nil return details, chainntnfs.TxFoundIndex, nil
} }
} }
// We return an error because we should have found the transaction // We return an error because we should have found the transaction
// within the block, but didn't. // within the block, but didn't.
return nil, txNotFoundIndex, fmt.Errorf("unable to locate tx %v in "+ return nil, chainntnfs.TxNotFoundIndex,
"block %v", txid, blockHash) fmt.Errorf("unable to locate tx %v in block %v", txid,
blockHash)
} }
// confDetailsManually looks up whether a transaction is already included in a // confDetailsManually looks up whether a transaction is already included in a
@@ -580,7 +556,8 @@ func (b *BitcoindNotifier) confDetailsFromTxIndex(txid *chainhash.Hash,
// height in the chain. If the transaction is found, its confirmation details // height in the chain. If the transaction is found, its confirmation details
// are returned. Otherwise, nil is returned. // are returned. Otherwise, nil is returned.
func (b *BitcoindNotifier) confDetailsManually(txid *chainhash.Hash, func (b *BitcoindNotifier) confDetailsManually(txid *chainhash.Hash,
heightHint, currentHeight uint32) (*chainntnfs.TxConfirmation, txConfStatus, error) { heightHint, currentHeight uint32) (*chainntnfs.TxConfirmation,
chainntnfs.TxConfStatus, error) {
targetTxidStr := txid.String() targetTxidStr := txid.String()
@@ -591,20 +568,23 @@ func (b *BitcoindNotifier) confDetailsManually(txid *chainhash.Hash,
// processing the next height. // processing the next height.
select { select {
case <-b.quit: case <-b.quit:
return nil, txNotFoundManually, ErrChainNotifierShuttingDown return nil, chainntnfs.TxNotFoundManually,
ErrChainNotifierShuttingDown
default: default:
} }
blockHash, err := b.chainConn.GetBlockHash(int64(height)) blockHash, err := b.chainConn.GetBlockHash(int64(height))
if err != nil { if err != nil {
return nil, txNotFoundManually, fmt.Errorf("unable to "+ return nil, chainntnfs.TxNotFoundManually,
"get hash from block with height %d", height) fmt.Errorf("unable to get hash from block "+
"with height %d", height)
} }
block, err := b.chainConn.GetBlockVerbose(blockHash) block, err := b.chainConn.GetBlockVerbose(blockHash)
if err != nil { if err != nil {
return nil, txNotFoundManually, fmt.Errorf("unable to "+ return nil, chainntnfs.TxNotFoundManually,
"get block with hash %v: %v", blockHash, err) fmt.Errorf("unable to get block with hash "+
"%v: %v", blockHash, err)
} }
for txIndex, txHash := range block.Tx { for txIndex, txHash := range block.Tx {
@@ -616,14 +596,14 @@ func (b *BitcoindNotifier) confDetailsManually(txid *chainhash.Hash,
BlockHeight: height, BlockHeight: height,
TxIndex: uint32(txIndex), TxIndex: uint32(txIndex),
} }
return details, txFoundManually, nil return details, chainntnfs.TxFoundManually, nil
} }
} }
} }
// If we reach here, then we were not able to find the transaction // If we reach here, then we were not able to find the transaction
// within a block, so we avoid returning an error. // within a block, so we avoid returning an error.
return nil, txNotFoundManually, nil return nil, chainntnfs.TxNotFoundManually, nil
} }
// handleBlockConnected applies a chain update for a new block. Any watched // handleBlockConnected applies a chain update for a new block. Any watched
+32 -51
View File
@@ -27,31 +27,6 @@ const (
reorgSafetyLimit = 100 reorgSafetyLimit = 100
) )
// txConfStatus denotes the status of a transaction's lookup.
type txConfStatus uint8
const (
// txFoundMempool denotes that the transaction was found within the
// backend node's mempool.
txFoundMempool txConfStatus = iota
// txFoundIndex denotes that the transaction was found within the
// backend node's txindex.
txFoundIndex
// txFoundIndex denotes that the transaction was not found within the
// backend node's txindex.
txNotFoundIndex
// txFoundManually denotes that the transaction was found within the
// chain by scanning for it manually.
txFoundManually
// txFoundManually denotes that the transaction was not found within the
// chain by scanning for it manually.
txNotFoundManually
)
var ( var (
// ErrChainNotifierShuttingDown is used when we are trying to // ErrChainNotifierShuttingDown is used when we are trying to
// measure a spend notification when notifier is already stopped. // measure a spend notification when notifier is already stopped.
@@ -542,7 +517,8 @@ out:
// historicalConfDetails looks up whether a transaction is already included in a // historicalConfDetails looks up whether a transaction is already included in a
// block in the active chain and, if so, returns details about the confirmation. // block in the active chain and, if so, returns details about the confirmation.
func (b *BtcdNotifier) historicalConfDetails(txid *chainhash.Hash, func (b *BtcdNotifier) historicalConfDetails(txid *chainhash.Hash,
heightHint, currentHeight uint32) (*chainntnfs.TxConfirmation, txConfStatus, error) { heightHint, currentHeight uint32) (*chainntnfs.TxConfirmation,
chainntnfs.TxConfStatus, error) {
// We'll first attempt to retrieve the transaction using the node's // We'll first attempt to retrieve the transaction using the node's
// txindex. // txindex.
@@ -552,13 +528,13 @@ func (b *BtcdNotifier) historicalConfDetails(txid *chainhash.Hash,
// determine whether we should proceed with any fallback methods. // determine whether we should proceed with any fallback methods.
switch { switch {
// The transaction was found within the node's mempool. // The transaction was found within the node's mempool.
case txStatus == txFoundMempool: case txStatus == chainntnfs.TxFoundMempool:
// The transaction was found within the node's txindex. // The transaction was found within the node's txindex.
case txStatus == txFoundIndex: case txStatus == chainntnfs.TxFoundIndex:
// The transaction was not found within the node's mempool or txindex. // The transaction was not found within the node's mempool or txindex.
case txStatus == txNotFoundIndex && err == nil: case txStatus == chainntnfs.TxNotFoundIndex && err == nil:
// We failed to look up the transaction within the node's mempool or // We failed to look up the transaction within the node's mempool or
// txindex, so we'll proceed to scan the chain manually. // txindex, so we'll proceed to scan the chain manually.
@@ -576,7 +552,7 @@ func (b *BtcdNotifier) historicalConfDetails(txid *chainhash.Hash,
// be TxFoundIndex. Otherwise TxNotFoundIndex is returned. If the tx is found // be TxFoundIndex. Otherwise TxNotFoundIndex is returned. If the tx is found
// in a block its confirmation details are also returned. // in a block its confirmation details are also returned.
func (b *BtcdNotifier) confDetailsFromTxIndex(txid *chainhash.Hash, func (b *BtcdNotifier) confDetailsFromTxIndex(txid *chainhash.Hash,
) (*chainntnfs.TxConfirmation, txConfStatus, error) { ) (*chainntnfs.TxConfirmation, chainntnfs.TxConfStatus, error) {
// If the transaction has some or all of its confirmations required, // If the transaction has some or all of its confirmations required,
// then we may be able to dispatch it immediately. // then we may be able to dispatch it immediately.
@@ -591,18 +567,18 @@ func (b *BtcdNotifier) confDetailsFromTxIndex(txid *chainhash.Hash,
if ok && jsonErr.Code == btcjson.ErrRPCNoTxInfo && if ok && jsonErr.Code == btcjson.ErrRPCNoTxInfo &&
strings.Contains(jsonErr.Message, txNotFoundErr) { strings.Contains(jsonErr.Message, txNotFoundErr) {
return nil, txNotFoundIndex, nil return nil, chainntnfs.TxNotFoundIndex, nil
} }
return nil, txNotFoundIndex, fmt.Errorf("unable to query for "+ return nil, chainntnfs.TxNotFoundIndex,
"txid %v: %v", txid, err) fmt.Errorf("unable to query for txid %v: %v", txid, err)
} }
// Make sure we actually retrieved a transaction that is included in a // Make sure we actually retrieved a transaction that is included in a
// block. If not, the transaction must be unconfirmed (in the mempool), // block. If not, the transaction must be unconfirmed (in the mempool),
// and we'll return TxFoundMempool together with a nil TxConfirmation. // and we'll return TxFoundMempool together with a nil TxConfirmation.
if tx.BlockHash == "" { if tx.BlockHash == "" {
return nil, txFoundMempool, nil return nil, chainntnfs.TxFoundMempool, nil
} }
// As we need to fully populate the returned TxConfirmation struct, // As we need to fully populate the returned TxConfirmation struct,
@@ -610,16 +586,16 @@ func (b *BtcdNotifier) confDetailsFromTxIndex(txid *chainhash.Hash,
// locate its exact index within the block. // locate its exact index within the block.
blockHash, err := chainhash.NewHashFromStr(tx.BlockHash) blockHash, err := chainhash.NewHashFromStr(tx.BlockHash)
if err != nil { if err != nil {
return nil, txNotFoundIndex, fmt.Errorf("unable to get block "+ return nil, chainntnfs.TxNotFoundIndex,
"hash %v for historical dispatch: %v", tx.BlockHash, fmt.Errorf("unable to get block hash %v for "+
err) "historical dispatch: %v", tx.BlockHash, err)
} }
block, err := b.chainConn.GetBlockVerbose(blockHash) block, err := b.chainConn.GetBlockVerbose(blockHash)
if err != nil { if err != nil {
return nil, txNotFoundIndex, fmt.Errorf("unable to get block "+ return nil, chainntnfs.TxNotFoundIndex,
"with hash %v for historical dispatch: %v", blockHash, fmt.Errorf("unable to get block with hash %v for "+
err) "historical dispatch: %v", blockHash, err)
} }
// If the block was obtained, locate the transaction's index within the // If the block was obtained, locate the transaction's index within the
@@ -632,14 +608,15 @@ func (b *BtcdNotifier) confDetailsFromTxIndex(txid *chainhash.Hash,
BlockHeight: uint32(block.Height), BlockHeight: uint32(block.Height),
TxIndex: uint32(txIndex), TxIndex: uint32(txIndex),
} }
return details, txFoundIndex, nil return details, chainntnfs.TxFoundIndex, nil
} }
} }
// We return an error because we should have found the transaction // We return an error because we should have found the transaction
// within the block, but didn't. // within the block, but didn't.
return nil, txNotFoundIndex, fmt.Errorf("unable to locate tx %v in "+ return nil, chainntnfs.TxNotFoundIndex,
"block %v", txid, blockHash) fmt.Errorf("unable to locate tx %v in block %v", txid,
blockHash)
} }
// confDetailsManually looks up whether a transaction is already included in a // confDetailsManually looks up whether a transaction is already included in a
@@ -648,7 +625,8 @@ func (b *BtcdNotifier) confDetailsFromTxIndex(txid *chainhash.Hash,
// height in the chain. If the transaction is found, its confirmation details // height in the chain. If the transaction is found, its confirmation details
// are returned. Otherwise, nil is returned. // are returned. Otherwise, nil is returned.
func (b *BtcdNotifier) confDetailsManually(txid *chainhash.Hash, heightHint, func (b *BtcdNotifier) confDetailsManually(txid *chainhash.Hash, heightHint,
currentHeight uint32) (*chainntnfs.TxConfirmation, txConfStatus, error) { currentHeight uint32) (*chainntnfs.TxConfirmation,
chainntnfs.TxConfStatus, error) {
targetTxidStr := txid.String() targetTxidStr := txid.String()
@@ -659,21 +637,24 @@ func (b *BtcdNotifier) confDetailsManually(txid *chainhash.Hash, heightHint,
// processing the next height. // processing the next height.
select { select {
case <-b.quit: case <-b.quit:
return nil, txNotFoundManually, ErrChainNotifierShuttingDown return nil, chainntnfs.TxNotFoundManually,
ErrChainNotifierShuttingDown
default: default:
} }
blockHash, err := b.chainConn.GetBlockHash(int64(height)) blockHash, err := b.chainConn.GetBlockHash(int64(height))
if err != nil { if err != nil {
return nil, txNotFoundManually, fmt.Errorf("unable to "+ return nil, chainntnfs.TxNotFoundManually,
"get hash from block with height %d", height) fmt.Errorf("unable to get hash from block "+
"with height %d", height)
} }
// TODO: fetch the neutrino filters instead. // TODO: fetch the neutrino filters instead.
block, err := b.chainConn.GetBlockVerbose(blockHash) block, err := b.chainConn.GetBlockVerbose(blockHash)
if err != nil { if err != nil {
return nil, txNotFoundManually, fmt.Errorf("unable to "+ return nil, chainntnfs.TxNotFoundManually,
"get block with hash %v: %v", blockHash, err) fmt.Errorf("unable to get block with hash "+
"%v: %v", blockHash, err)
} }
for txIndex, txHash := range block.Tx { for txIndex, txHash := range block.Tx {
@@ -685,14 +666,14 @@ func (b *BtcdNotifier) confDetailsManually(txid *chainhash.Hash, heightHint,
BlockHeight: height, BlockHeight: height,
TxIndex: uint32(txIndex), TxIndex: uint32(txIndex),
} }
return details, txFoundManually, nil return details, chainntnfs.TxFoundManually, nil
} }
} }
} }
// If we reach here, then we were not able to find the transaction // If we reach here, then we were not able to find the transaction
// within a block, so we avoid returning an error. // within a block, so we avoid returning an error.
return nil, txNotFoundManually, nil return nil, chainntnfs.TxNotFoundManually, nil
} }
// handleBlockConnected applies a chain update for a new block. Any watched // handleBlockConnected applies a chain update for a new block. Any watched