|
|
- package core
-
- import (
- "fmt"
-
- ctypes "github.com/tendermint/tendermint/rpc/core/types"
- "github.com/tendermint/tendermint/state/txindex/null"
- "github.com/tendermint/tendermint/types"
- tmquery "github.com/tendermint/tmlibs/pubsub/query"
- )
-
- // Tx allows you to query the transaction results. `nil` could mean the
- // transaction is in the mempool, invalidated, or was not sent in the first
- // 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) {
-
- // if index is disabled, return error
- if _, ok := txIndexer.(*null.TxIndex); ok {
- return nil, fmt.Errorf("Transaction indexing is disabled.")
- }
-
- r, err := txIndexer.Get(hash)
- if err != nil {
- return nil, err
- }
-
- if r == nil {
- return nil, fmt.Errorf("Tx (%X) not found", hash)
- }
-
- height := r.Height
- index := int(r.Index) // XXX:overflow
-
- var proof types.TxProof
- if prove {
- block := blockStore.LoadBlock(height)
- // TODO: handle overflow
- proof = block.Data.Txs.Proof(index)
- }
-
- return &ctypes.ResultTx{
- Height: height,
- Index: uint32(index),
- TxResult: r.Result,
- Tx: r.Tx,
- Proof: proof,
- }, nil
- }
-
- // TxSearch allows you to query for multiple transactions results.
- //
- // ```shell
- // curl "localhost:46657/tx_search?query=\"account.owner='Ivan'\"&prove=true"
- // ```
- //
- // ```go
- // client := client.NewHTTP("tcp://0.0.0.0:46657", "/websocket")
- // q, err := tmquery.New("account.owner='Ivan'")
- // tx, err := client.TxSearch(q, true)
- // ```
- //
- // > The above command returns JSON structured like this:
- //
- // ```json
- // {
- // "result": [
- // {
- // "proof": {
- // "Proof": {
- // "aunts": [
- // "J3LHbizt806uKnABNLwG4l7gXCA=",
- // "iblMO/M1TnNtlAefJyNCeVhjAb0=",
- // "iVk3ryurVaEEhdeS0ohAJZ3wtB8=",
- // "5hqMkTeGqpct51ohX0lZLIdsn7Q=",
- // "afhsNxFnLlZgFDoyPpdQSe0bR8g="
- // ]
- // },
- // "Data": "mvZHHa7HhZ4aRT0xMDA=",
- // "RootHash": "F6541223AA46E428CB1070E9840D2C3DF3B6D776",
- // "Total": 32,
- // "Index": 31
- // },
- // "tx": "mvZHHa7HhZ4aRT0xMDA=",
- // "tx_result": {},
- // "index": 31,
- // "height": 12
- // }
- // ],
- // "id": "",
- // "jsonrpc": "2.0"
- // }
- // ```
- //
- // Returns transactions matching the given query.
- //
- // ### Query Parameters
- //
- // | Parameter | Type | Default | Required | Description |
- // |-----------+--------+---------+----------+-----------------------------------------------------------|
- // | query | string | "" | true | Query |
- // | prove | bool | false | false | Include proofs of the transactions 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 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 nil, err
- }
-
- results, err := txIndexer.Search(q)
- if err != nil {
- return nil, err
- }
-
- // TODO: we may want to consider putting a maximum on this length and somehow
- // informing the user that things were truncated.
- apiResults := make([]*ctypes.ResultTx, len(results))
- var proof types.TxProof
- for i, r := range results {
- height := r.Height
- index := r.Index
-
- if prove {
- block := blockStore.LoadBlock(height)
- // TODO: handle overflow
- 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
- }
|