tendermint/rpc/core/tx.go

142 lines
3.4 KiB
Go
Raw Normal View History

package core
import (
2017-04-12 15:18:17 -07:00
"fmt"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
"github.com/tendermint/tendermint/state/txindex/null"
2017-04-12 15:55:00 -07:00
"github.com/tendermint/tendermint/types"
2017-11-28 12:12:04 -08:00
tmquery "github.com/tendermint/tmlibs/pubsub/query"
)
// Tx allows you to query the transaction results. `nil` could mean the
2017-08-16 12:18:55 -07:00
// transaction is in the mempool, invalidated, or was not sent in the first
2017-04-28 19:26:17 -07:00
// place.
//
// ```shell
// curl "localhost:46657/tx?hash=0x2B8EC32BA2579B3B8606E42C06DE2F7AFA2556EF"
// ```
//
// ```go
// client := client.NewHTTP("tcp://0.0.0.0:46657", "/websocket")
// tx, err := client.Tx([]byte("2B8EC32BA2579B3B8606E42C06DE2F7AFA2556EF"), true)
// ```
//
// > The above command returns JSON structured like this:
//
// ```json
// {
// "error": "",
// "result": {
// "proof": {
// "Proof": {
// "aunts": []
// },
// "Data": "YWJjZA==",
// "RootHash": "2B8EC32BA2579B3B8606E42C06DE2F7AFA2556EF",
// "Total": 1,
// "Index": 0
// },
// "tx": "YWJjZA==",
// "tx_result": {
// "log": "",
// "data": "",
// "code": 0
// },
// "index": 0,
// "height": 52
// },
// "id": "",
// "jsonrpc": "2.0"
// }
// ```
//
// Returns a transaction matching the given transaction hash.
//
// ### Query Parameters
//
// | Parameter | Type | Default | Required | Description |
// |-----------+--------+---------+----------+-----------------------------------------------------------|
// | hash | []byte | nil | true | The transaction hash |
// | prove | bool | false | false | Include a proof of the transaction inclusion in the block |
//
// ### Returns
//
// - `proof`: the `types.TxProof` object
// - `tx`: `[]byte` - the transaction
// - `tx_result`: the `abci.Result` object
// - `index`: `int` - index of the transaction
// - `height`: `int` - height of the block where this transaction was in
func Tx(hash []byte, prove bool) (*ctypes.ResultTx, error) {
2017-04-13 10:47:48 -07:00
// if index is disabled, return error
if _, ok := txIndexer.(*null.TxIndex); ok {
return nil, fmt.Errorf("Transaction indexing is disabled.")
2017-04-13 13:04:20 -07:00
}
r, err := txIndexer.Get(hash)
if err != nil {
return nil, err
2017-04-13 13:04:20 -07:00
}
if r == nil {
return nil, fmt.Errorf("Tx (%X) not found", hash)
2017-04-13 12:18:58 -07:00
}
height := r.Height
index := r.Index
2017-04-12 15:18:17 -07:00
2017-04-12 15:55:00 -07:00
var proof types.TxProof
if prove {
block := blockStore.LoadBlock(int(height))
proof = block.Data.Txs.Proof(int(index))
2017-04-12 15:55:00 -07:00
}
2017-04-12 15:18:17 -07:00
return &ctypes.ResultTx{
2017-04-13 13:04:20 -07:00
Height: height,
Index: index,
TxResult: r.Result,
Tx: r.Tx,
2017-04-13 13:04:20 -07:00
Proof: proof,
2017-04-12 15:18:17 -07:00
}, nil
}
2017-11-28 12:12:04 -08:00
func TxSearch(query string, prove bool) ([]*ctypes.ResultTx, error) {
// if index is disabled, return error
if _, ok := txIndexer.(*null.TxIndex); ok {
return nil, fmt.Errorf("Transaction indexing is disabled.")
}
q, err := tmquery.New(query)
if err != nil {
return []*ctypes.ResultTx{}, err
}
results, err := txIndexer.Search(q)
if err != nil {
return []*ctypes.ResultTx{}, err
}
apiResults := make([]*ctypes.ResultTx, len(results))
for i, r := range results {
height := r.Height
index := r.Index
var proof types.TxProof
if prove {
block := blockStore.LoadBlock(int(height))
proof = block.Data.Txs.Proof(int(index))
}
apiResults[i] = &ctypes.ResultTx{
Height: height,
Index: index,
TxResult: r.Result,
Tx: r.Tx,
Proof: proof,
}
}
return apiResults, nil
}