Skip to content

Commit 5ccad47

Browse files
jackzampolincwgoes
authored andcommitted
Merge PR #3642: Tx Query return values
1 parent c0eec30 commit 5ccad47

File tree

5 files changed

+62
-30
lines changed

5 files changed

+62
-30
lines changed

PENDING.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
BREAKING CHANGES
44

55
* Gaia REST API
6+
* [\#3642](https://github.com/cosmos/cosmos-sdk/pull/3642) `GET /tx/{hash}` now returns `404` instead of `500` if the transaction is not found
67

78
* Gaia CLI
89

client/lcd/lcd_test.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"net/http"
88
"os"
99
"regexp"
10+
"strings"
1011
"testing"
1112
"time"
1213

@@ -503,6 +504,17 @@ func TestTxs(t *testing.T) {
503504
txs = getTransactions(t, port, fmt.Sprintf("recipient=%s", receiveAddr.String()))
504505
require.Len(t, txs, 1)
505506
require.Equal(t, resultTx.Height, txs[0].Height)
507+
508+
// query transaction that doesn't exist
509+
validTxHash := "9ADBECAAD8DACBEC3F4F535704E7CF715C765BDCEDBEF086AFEAD31BA664FB0B"
510+
res, body := getTransactionRequest(t, port, validTxHash)
511+
require.True(t, strings.Contains(body, validTxHash))
512+
require.Equal(t, http.StatusNotFound, res.StatusCode)
513+
514+
// bad query string
515+
res, body = getTransactionRequest(t, port, "badtxhash")
516+
require.True(t, strings.Contains(body, "encoding/hex"))
517+
require.Equal(t, http.StatusInternalServerError, res.StatusCode)
506518
}
507519

508520
func TestPoolParamsQuery(t *testing.T) {

client/lcd/test_helpers.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,14 +513,18 @@ func getValidatorSets(t *testing.T, port string, height int, expectFail bool) rp
513513
// GET /txs/{hash} get tx by hash
514514
func getTransaction(t *testing.T, port string, hash string) sdk.TxResponse {
515515
var tx sdk.TxResponse
516-
res, body := Request(t, port, "GET", fmt.Sprintf("/txs/%s", hash), nil)
516+
res, body := getTransactionRequest(t, port, hash)
517517
require.Equal(t, http.StatusOK, res.StatusCode, body)
518518

519519
err := cdc.UnmarshalJSON([]byte(body), &tx)
520520
require.NoError(t, err)
521521
return tx
522522
}
523523

524+
func getTransactionRequest(t *testing.T, port, hash string) (*http.Response, string) {
525+
return Request(t, port, "GET", fmt.Sprintf("/txs/%s", hash), nil)
526+
}
527+
524528
// POST /txs broadcast txs
525529

526530
// GET /txs search transactions

client/tx/query.go

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"encoding/hex"
55
"fmt"
66
"net/http"
7+
"strings"
78

89
"github.com/gorilla/mux"
910
"github.com/spf13/cobra"
@@ -26,18 +27,18 @@ func QueryTxCmd(cdc *codec.Codec) *cobra.Command {
2627
Short: "Matches this txhash over all committed blocks",
2728
Args: cobra.ExactArgs(1),
2829
RunE: func(cmd *cobra.Command, args []string) error {
29-
// find the key to look up the account
30-
hashHexStr := args[0]
31-
3230
cliCtx := context.NewCLIContext().WithCodec(cdc)
3331

34-
output, err := queryTx(cdc, cliCtx, hashHexStr)
32+
output, err := queryTx(cdc, cliCtx, args[0])
3533
if err != nil {
3634
return err
3735
}
3836

39-
fmt.Println(string(output))
40-
return nil
37+
if output.Empty() {
38+
return fmt.Errorf("No transaction found with hash %s", args[0])
39+
}
40+
41+
return cliCtx.PrintOutput(output)
4142
},
4243
}
4344

@@ -48,50 +49,46 @@ func QueryTxCmd(cdc *codec.Codec) *cobra.Command {
4849
return cmd
4950
}
5051

51-
func queryTx(cdc *codec.Codec, cliCtx context.CLIContext, hashHexStr string) ([]byte, error) {
52+
func queryTx(cdc *codec.Codec, cliCtx context.CLIContext, hashHexStr string) (out sdk.TxResponse, err error) {
5253
hash, err := hex.DecodeString(hashHexStr)
5354
if err != nil {
54-
return nil, err
55+
return out, err
5556
}
5657

5758
node, err := cliCtx.GetNode()
5859
if err != nil {
59-
return nil, err
60+
return out, err
6061
}
6162

6263
res, err := node.Tx(hash, !cliCtx.TrustNode)
6364
if err != nil {
64-
return nil, err
65+
return out, err
6566
}
6667

6768
if !cliCtx.TrustNode {
68-
err := ValidateTxResult(cliCtx, res)
69-
if err != nil {
70-
return nil, err
69+
if err = ValidateTxResult(cliCtx, res); err != nil {
70+
return out, err
7171
}
7272
}
7373

74-
info, err := formatTxResult(cdc, res)
75-
if err != nil {
76-
return nil, err
74+
if out, err = formatTxResult(cdc, res); err != nil {
75+
return out, err
7776
}
7877

79-
if cliCtx.Indent {
80-
return cdc.MarshalJSONIndent(info, "", " ")
81-
}
82-
return cdc.MarshalJSON(info)
78+
return out, nil
8379
}
8480

8581
// ValidateTxResult performs transaction verification
8682
func ValidateTxResult(cliCtx context.CLIContext, res *ctypes.ResultTx) error {
87-
check, err := cliCtx.Verify(res.Height)
88-
if err != nil {
89-
return err
90-
}
91-
92-
err = res.Proof.Validate(check.Header.DataHash)
93-
if err != nil {
94-
return err
83+
if !cliCtx.TrustNode {
84+
check, err := cliCtx.Verify(res.Height)
85+
if err != nil {
86+
return err
87+
}
88+
err = res.Proof.Validate(check.Header.DataHash)
89+
if err != nil {
90+
return err
91+
}
9592
}
9693
return nil
9794
}
@@ -118,17 +115,26 @@ func parseTx(cdc *codec.Codec, txBytes []byte) (sdk.Tx, error) {
118115

119116
// REST
120117

121-
// transaction query REST handler
118+
// QueryTxRequestHandlerFn transaction query REST handler
122119
func QueryTxRequestHandlerFn(cdc *codec.Codec, cliCtx context.CLIContext) http.HandlerFunc {
123120
return func(w http.ResponseWriter, r *http.Request) {
124121
vars := mux.Vars(r)
125122
hashHexStr := vars["hash"]
126123

127124
output, err := queryTx(cdc, cliCtx, hashHexStr)
128125
if err != nil {
126+
if strings.Contains(err.Error(), hashHexStr) {
127+
rest.WriteErrorResponse(w, http.StatusNotFound, err.Error())
128+
return
129+
}
129130
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
130131
return
131132
}
133+
134+
if output.Empty() {
135+
rest.WriteErrorResponse(w, http.StatusNotFound, fmt.Sprintf("no transaction found with hash %s", hashHexStr))
136+
}
137+
132138
rest.PostProcessResponse(w, cdc, output, cliCtx.Indent)
133139
}
134140
}

types/result.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ type TxResponse struct {
5454
Tx Tx `json:"tx,omitempty"`
5555
}
5656

57+
// NewResponseResultTx returns a TxResponse given a ResultTx from tendermint
5758
func NewResponseResultTx(res *ctypes.ResultTx, tx Tx) TxResponse {
5859
if res == nil {
5960
return TxResponse{}
@@ -73,6 +74,7 @@ func NewResponseResultTx(res *ctypes.ResultTx, tx Tx) TxResponse {
7374
}
7475
}
7576

77+
// NewResponseFormatBroadcastTxCommit returns a TxResponse given a ResultBroadcastTxCommit from tendermint
7678
func NewResponseFormatBroadcastTxCommit(res *ctypes.ResultBroadcastTxCommit) TxResponse {
7779
if res == nil {
7880
return TxResponse{}
@@ -95,8 +97,10 @@ func NewResponseFormatBroadcastTxCommit(res *ctypes.ResultBroadcastTxCommit) TxR
9597
Tags: TagsToStringTags(res.DeliverTx.Tags),
9698
Codespace: res.DeliverTx.Codespace,
9799
}
100+
98101
}
99102

103+
// NewResponseFormatBroadcastTx returns a TxResponse given a ResultBroadcastTx from tendermint
100104
func NewResponseFormatBroadcastTx(res *ctypes.ResultBroadcastTx) TxResponse {
101105
if res == nil {
102106
return TxResponse{}
@@ -156,3 +160,8 @@ func (r TxResponse) String() string {
156160

157161
return strings.TrimSpace(sb.String())
158162
}
163+
164+
// Empty returns true if the response is empty
165+
func (r TxResponse) Empty() bool {
166+
return r.TxHash == "" && r.Log == ""
167+
}

0 commit comments

Comments
 (0)