chainntnfs: include transaction in confirmation details

This commit is contained in:
Wilmer Paulino
2018-12-10 18:24:04 -08:00
parent 5ab30cf7ea
commit 50650d054e
6 changed files with 83 additions and 31 deletions

View File

@@ -1,6 +1,8 @@
package bitcoindnotify
import (
"bytes"
"encoding/hex"
"errors"
"fmt"
"strings"
@@ -462,7 +464,7 @@ func (b *BitcoindNotifier) confDetailsFromTxIndex(txid *chainhash.Hash,
// If the transaction has some or all of its confirmations required,
// then we may be able to dispatch it immediately.
tx, err := b.chainConn.GetRawTransactionVerbose(txid)
rawTxRes, err := b.chainConn.GetRawTransactionVerbose(txid)
if err != nil {
// If the transaction lookup was successful, but it wasn't found
// within the index itself, then we can exit early. We'll also
@@ -483,18 +485,18 @@ func (b *BitcoindNotifier) confDetailsFromTxIndex(txid *chainhash.Hash,
// Make sure we actually retrieved a transaction that is included in a
// block. If not, the transaction must be unconfirmed (in the mempool),
// and we'll return TxFoundMempool together with a nil TxConfirmation.
if tx.BlockHash == "" {
if rawTxRes.BlockHash == "" {
return nil, chainntnfs.TxFoundMempool, nil
}
// As we need to fully populate the returned TxConfirmation struct,
// grab the block in which the transaction was confirmed so we can
// locate its exact index within the block.
blockHash, err := chainhash.NewHashFromStr(tx.BlockHash)
blockHash, err := chainhash.NewHashFromStr(rawTxRes.BlockHash)
if err != nil {
return nil, chainntnfs.TxNotFoundIndex,
fmt.Errorf("unable to get block hash %v for "+
"historical dispatch: %v", tx.BlockHash, err)
"historical dispatch: %v", rawTxRes.BlockHash, err)
}
block, err := b.chainConn.GetBlockVerbose(blockHash)
@@ -506,23 +508,39 @@ func (b *BitcoindNotifier) confDetailsFromTxIndex(txid *chainhash.Hash,
// If the block was obtained, locate the transaction's index within the
// block so we can give the subscriber full confirmation details.
targetTxidStr := txid.String()
txidStr := txid.String()
for txIndex, txHash := range block.Tx {
if txHash == targetTxidStr {
details := &chainntnfs.TxConfirmation{
BlockHash: blockHash,
BlockHeight: uint32(block.Height),
TxIndex: uint32(txIndex),
}
return details, chainntnfs.TxFoundIndex, nil
if txHash != txidStr {
continue
}
// Deserialize the hex-encoded transaction to include it in the
// confirmation details.
rawTx, err := hex.DecodeString(rawTxRes.Hex)
if err != nil {
return nil, chainntnfs.TxFoundIndex,
fmt.Errorf("unable to deserialize tx %v: %v",
txHash, err)
}
var tx wire.MsgTx
if err := tx.Deserialize(bytes.NewReader(rawTx)); err != nil {
return nil, chainntnfs.TxFoundIndex,
fmt.Errorf("unable to deserialize tx %v: %v",
txHash, err)
}
return &chainntnfs.TxConfirmation{
Tx: &tx,
BlockHash: blockHash,
BlockHeight: uint32(block.Height),
TxIndex: uint32(txIndex),
}, chainntnfs.TxFoundIndex, nil
}
// We return an error because we should have found the transaction
// within the block, but didn't.
return nil, chainntnfs.TxNotFoundIndex,
fmt.Errorf("unable to locate tx %v in block %v", txid,
blockHash)
return nil, chainntnfs.TxNotFoundIndex, fmt.Errorf("unable to locate "+
"tx %v in block %v", txid, blockHash)
}
// confDetailsManually looks up whether a transaction/output script has already
@@ -568,6 +586,7 @@ func (b *BitcoindNotifier) confDetailsManually(confRequest chainntnfs.ConfReques
}
return &chainntnfs.TxConfirmation{
Tx: tx,
BlockHash: blockHash,
BlockHeight: height,
TxIndex: uint32(txIndex),