diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index c37fae72c..5552d1c01 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -561,31 +561,37 @@ func handleQueryCustom(app *BaseApp, path []string, req abci.RequestQuery) (res return sdk.ErrUnknownRequest(fmt.Sprintf("no custom querier found for route %s", path[1])).QueryResult() } + // when a client did not provide a query height, manually inject the latest + if req.Height == 0 { + req.Height = app.LastBlockHeight() + } + + cacheMS, err := app.cms.CacheMultiStoreWithVersion(req.Height) + if err != nil { + return sdk.ErrInternal( + fmt.Sprintf( + "failed to load state at height %d; %s (latest height: %d)", + req.Height, err, app.LastBlockHeight(), + ), + ).QueryResult() + } + // cache wrap the commit-multistore for safety ctx := sdk.NewContext( - app.cms.CacheMultiStore(), app.checkState.ctx.BlockHeader(), true, app.logger, + cacheMS, app.checkState.ctx.BlockHeader(), true, app.logger, ).WithMinGasPrices(app.minGasPrices) - if req.Height > 0 { - cacheMS, err := app.cms.CacheMultiStoreWithVersion(req.Height) - if err != nil { - return sdk.ErrInternal(fmt.Sprintf("failed to load state at height %d; %s", req.Height, err)).QueryResult() - } - - ctx = ctx.WithMultiStore(cacheMS) - } - // Passes the rest of the path as an argument to the querier. // // For example, in the path "custom/gov/proposal/test", the gov querier gets // []string{"proposal", "test"} as the path. - resBytes, err := querier(ctx, path[2:], req) - if err != nil { + resBytes, queryErr := querier(ctx, path[2:], req) + if queryErr != nil { return abci.ResponseQuery{ - Code: uint32(err.Code()), - Codespace: string(err.Codespace()), + Code: uint32(queryErr.Code()), + Codespace: string(queryErr.Codespace()), Height: req.Height, - Log: err.ABCILog(), + Log: queryErr.ABCILog(), } } diff --git a/client/context/query.go b/client/context/query.go index 2dc8ab217..87f96aece 100644 --- a/client/context/query.go +++ b/client/context/query.go @@ -81,16 +81,6 @@ func (ctx CLIContext) query(path string, key cmn.HexBytes) (res []byte, height i return res, height, err } - // When a client did not provide a query height, manually query for it so it can - // be injected downstream into responses. - if ctx.Height == 0 { - status, err := node.Status() - if err != nil { - return res, height, err - } - ctx = ctx.WithHeight(status.SyncInfo.LatestBlockHeight) - } - opts := rpcclient.ABCIQueryOptions{ Height: ctx.Height, Prove: !ctx.TrustNode, diff --git a/client/rpc/block.go b/client/rpc/block.go index b8581a32b..6e3ea231f 100644 --- a/client/rpc/block.go +++ b/client/rpc/block.go @@ -67,6 +67,7 @@ func getBlock(cliCtx context.CLIContext, height *int64) ([]byte, error) { if cliCtx.Indent { return codec.Cdc.MarshalJSONIndent(res, "", " ") } + return codec.Cdc.MarshalJSON(res) } @@ -76,10 +77,12 @@ func GetChainHeight(cliCtx context.CLIContext) (int64, error) { if err != nil { return -1, err } + status, err := node.Status() if err != nil { return -1, err } + height := status.SyncInfo.LatestBlockHeight return height, nil } @@ -104,6 +107,7 @@ func printBlock(cmd *cobra.Command, args []string) error { if err != nil { return err } + fmt.Println(string(output)) return nil } @@ -114,27 +118,32 @@ func printBlock(cmd *cobra.Command, args []string) error { func BlockRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) + height, err := strconv.ParseInt(vars["height"], 10, 64) if err != nil { rest.WriteErrorResponse(w, http.StatusBadRequest, "couldn't parse block height. Assumed format is '/block/{height}'.") return } + chainHeight, err := GetChainHeight(cliCtx) if err != nil { rest.WriteErrorResponse(w, http.StatusInternalServerError, "failed to parse chain height") return } + if height > chainHeight { rest.WriteErrorResponse(w, http.StatusNotFound, "requested block height is bigger then the chain length") return } + output, err := getBlock(cliCtx, &height) if err != nil { rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } - rest.PostProcessResponse(w, cliCtx, output) + + rest.PostProcessResponseBare(w, cliCtx, output) } } @@ -147,6 +156,6 @@ func LatestBlockRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - rest.PostProcessResponse(w, cliCtx, output) + rest.PostProcessResponseBare(w, cliCtx, output) } } diff --git a/client/rpc/status.go b/client/rpc/status.go index 1b47fea20..330d595d5 100644 --- a/client/rpc/status.go +++ b/client/rpc/status.go @@ -64,7 +64,9 @@ func printNodeStatus(_ *cobra.Command, _ []string) error { return nil } -type nodeInfoResponse struct { +// NodeInfoResponse defines a response type that contains node status and version +// information. +type NodeInfoResponse struct { p2p.DefaultNodeInfo `json:"node_info"` ApplicationVersion version.Info `json:"application_version"` @@ -79,7 +81,7 @@ func NodeInfoRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - resp := nodeInfoResponse{ + resp := NodeInfoResponse{ DefaultNodeInfo: status.NodeInfo, ApplicationVersion: version.NewInfo(), } @@ -87,7 +89,8 @@ func NodeInfoRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { } } -type syncingResponse struct { +// SyncingResponse defines a response type that contains node syncing information. +type SyncingResponse struct { Syncing bool `json:"syncing"` } @@ -100,6 +103,6 @@ func NodeSyncingRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - rest.PostProcessResponseBare(w, cliCtx, syncingResponse{Syncing: status.SyncInfo.CatchingUp}) + rest.PostProcessResponseBare(w, cliCtx, SyncingResponse{Syncing: status.SyncInfo.CatchingUp}) } } diff --git a/tests/util.go b/tests/util.go index 4ca219285..bde6a82eb 100644 --- a/tests/util.go +++ b/tests/util.go @@ -68,10 +68,10 @@ func waitForHeightTM(height int64, url string) { panic(err) } - if resBlock.Block != nil && - resBlock.Block.Height >= height { + if resBlock.Block != nil && resBlock.Block.Height >= height { return } + time.Sleep(time.Millisecond * 100) } } @@ -96,6 +96,7 @@ func StatusOK(statusCode int) bool { func waitForHeight(height int64, url string) { var res *http.Response var err error + for { // Since this is in a testing file we are accepting nolint to be passed res, err = http.Get(url) //nolint:gosec @@ -107,21 +108,20 @@ func waitForHeight(height int64, url string) { if err != nil { panic(err) } - err = res.Body.Close() - if err != nil { + + if err = res.Body.Close(); err != nil { panic(err) } var resultBlock ctypes.ResultBlock - err = cdc.UnmarshalJSON(body, &resultBlock) - if err != nil { + if err = cdc.UnmarshalJSON(body, &resultBlock); err != nil { panic(err) } - if resultBlock.Block != nil && - resultBlock.Block.Height >= height { + if resultBlock.Block != nil && resultBlock.Block.Height >= height { return } + time.Sleep(time.Millisecond * 100) } } diff --git a/types/rest/rest.go b/types/rest/rest.go index c356f07e1..bcaaba62d 100644 --- a/types/rest/rest.go +++ b/types/rest/rest.go @@ -232,6 +232,8 @@ func ParseQueryHeightOrReturnBadRequest(w http.ResponseWriter, cliCtx context.CL if height > 0 { cliCtx = cliCtx.WithHeight(height) } + } else { + cliCtx = cliCtx.WithHeight(0) } return cliCtx, true diff --git a/x/auth/client/rest/broadcast.go b/x/auth/client/rest/broadcast.go index 9aff327fb..e7609194c 100644 --- a/x/auth/client/rest/broadcast.go +++ b/x/auth/client/rest/broadcast.go @@ -48,6 +48,6 @@ func BroadcastTxRequest(cliCtx context.CLIContext) http.HandlerFunc { return } - rest.PostProcessResponse(w, cliCtx, res) + rest.PostProcessResponseBare(w, cliCtx, res) } } diff --git a/x/auth/client/rest/encode.go b/x/auth/client/rest/encode.go index c1b7f739f..e2d9f4fea 100644 --- a/x/auth/client/rest/encode.go +++ b/x/auth/client/rest/encode.go @@ -45,6 +45,6 @@ func EncodeTxRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { txBytesBase64 := base64.StdEncoding.EncodeToString(txBytes) response := EncodeResp{Tx: txBytesBase64} - rest.PostProcessResponse(w, cliCtx, response) + rest.PostProcessResponseBare(w, cliCtx, response) } } diff --git a/x/auth/client/rest/query.go b/x/auth/client/rest/query.go index daf4d34e2..d4a1a32f8 100644 --- a/x/auth/client/rest/query.go +++ b/x/auth/client/rest/query.go @@ -18,7 +18,6 @@ import ( // query accountREST Handler func QueryAccountRequestHandlerFn(storeName string, cliCtx context.CLIContext) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) bech32addr := vars["address"] @@ -85,7 +84,7 @@ func QueryTxsRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { } if len(r.Form) == 0 { - rest.PostProcessResponse(w, cliCtx, txs) + rest.PostProcessResponseBare(w, cliCtx, txs) return } @@ -101,7 +100,7 @@ func QueryTxsRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - rest.PostProcessResponse(w, cliCtx, searchResult) + rest.PostProcessResponseBare(w, cliCtx, searchResult) } } @@ -131,6 +130,6 @@ func QueryTxRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { rest.WriteErrorResponse(w, http.StatusNotFound, fmt.Sprintf("no transaction found with hash %s", hashHexStr)) } - rest.PostProcessResponse(w, cliCtx, output) + rest.PostProcessResponseBare(w, cliCtx, output) } } diff --git a/x/bank/client/rest/query.go b/x/bank/client/rest/query.go index 1341445cf..97bb16df3 100644 --- a/x/bank/client/rest/query.go +++ b/x/bank/client/rest/query.go @@ -13,7 +13,6 @@ import ( // query accountREST Handler func QueryBalancesRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") vars := mux.Vars(r) diff --git a/x/genutil/client/rest/query.go b/x/genutil/client/rest/query.go index 157384dca..4f0f318aa 100644 --- a/x/genutil/client/rest/query.go +++ b/x/genutil/client/rest/query.go @@ -37,5 +37,5 @@ func QueryGenesisTxs(cliCtx context.CLIContext, w http.ResponseWriter) { } } - rest.PostProcessResponse(w, cliCtx, genTxs) + rest.PostProcessResponseBare(w, cliCtx, genTxs) } diff --git a/x/staking/client/rest/query.go b/x/staking/client/rest/query.go index eb59ca108..e0eabd870 100644 --- a/x/staking/client/rest/query.go +++ b/x/staking/client/rest/query.go @@ -178,7 +178,7 @@ func delegatorTxsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - rest.PostProcessResponse(w, cliCtx, res) + rest.PostProcessResponseBare(w, cliCtx, res) } }