82 lines
2.1 KiB
Go
Raw Normal View History

package core
import (
2017-04-12 18:18:17 -04:00
"fmt"
2017-04-13 13:47:48 -04:00
abci "github.com/tendermint/abci/types"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
2017-04-13 16:04:20 -04:00
"github.com/tendermint/tendermint/state/tx/indexer"
2017-04-12 18:55:00 -04:00
"github.com/tendermint/tendermint/types"
)
2017-04-13 13:47:48 -04:00
func Tx(hash []byte, height, index int, prove bool) (*ctypes.ResultTx, error) {
2017-04-13 16:04:20 -04:00
// if index is disabled, we need a height
_, indexerDisabled := txIndexer.(*indexer.Null)
if indexerDisabled && height == 0 {
return nil, fmt.Errorf("TxIndexer is disabled. Please specify a height to search for the tx by hash or index")
}
// hash and index must not be passed together
if len(hash) > 0 && index != 0 {
return nil, fmt.Errorf("Invalid args. Only one of hash and index may be provided")
}
// results
var txResult abci.ResponseDeliverTx
var tx types.Tx
// if indexer is enabled and we have a hash,
// fetch the tx result and set the height and index
if !indexerDisabled && len(hash) > 0 {
2017-04-13 13:47:48 -04:00
r, err := txIndexer.Tx(hash)
if err != nil {
return nil, err
}
if r == nil {
return &ctypes.ResultTx{}, fmt.Errorf("Tx (%X) not found", hash)
}
2017-04-12 18:18:17 -04:00
2017-04-13 13:47:48 -04:00
height = int(r.Height) // XXX
index = int(r.Index)
2017-04-13 16:04:20 -04:00
txResult = r.DeliverTx
2017-04-12 18:18:17 -04:00
}
2017-04-13 16:04:20 -04:00
// height must be valid
2017-04-13 15:18:58 -04:00
if height <= 0 || height > blockStore.Height() {
return nil, fmt.Errorf("Invalid height (%d) for blockStore at height %d", height, blockStore.Height())
}
2017-04-13 13:47:48 -04:00
block := blockStore.LoadBlock(height)
2017-04-13 16:04:20 -04:00
// index must be valid
2017-04-13 15:18:58 -04:00
if index < 0 || index >= len(block.Data.Txs) {
2017-04-13 13:47:48 -04:00
return nil, fmt.Errorf("Index (%d) is out of range for block (%d) with %d txs", index, height, len(block.Data.Txs))
}
2017-04-13 16:04:20 -04:00
// if indexer is disabled and we have a hash,
// search for it in the list of txs
if indexerDisabled && len(hash) > 0 {
index = block.Data.Txs.IndexByHash(hash)
if index < 0 {
return nil, fmt.Errorf("Tx hash %X not found in block %d", hash, height)
}
}
tx = block.Data.Txs[index]
2017-04-12 18:18:17 -04:00
2017-04-12 18:55:00 -04:00
var proof types.TxProof
if prove {
2017-04-13 13:47:48 -04:00
proof = block.Data.Txs.Proof(index)
2017-04-12 18:55:00 -04:00
}
2017-04-12 18:18:17 -04:00
return &ctypes.ResultTx{
2017-04-13 16:04:20 -04:00
Height: height,
Index: index,
TxResult: txResult,
Tx: tx,
Proof: proof,
2017-04-12 18:18:17 -04:00
}, nil
}