From 60e0267b6efccf82238a09d2104baf4f216e28fa Mon Sep 17 00:00:00 2001 From: Colin Axner Date: Mon, 17 Jun 2019 15:16:40 -0700 Subject: [PATCH 01/16] add height in validator endpoint response --- x/staking/client/rest/utils.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/staking/client/rest/utils.go b/x/staking/client/rest/utils.go index 1d07c04a2e4c..6b36903b5791 100644 --- a/x/staking/client/rest/utils.go +++ b/x/staking/client/rest/utils.go @@ -128,11 +128,11 @@ func queryValidator(cliCtx context.CLIContext, endpoint string) http.HandlerFunc return } - res, _, err := cliCtx.QueryWithData(endpoint, bz) + res, height, err := cliCtx.QueryWithData(endpoint, bz) if err != nil { rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } - rest.PostProcessResponse(w, cliCtx, res) + rest.PostProcessResponse(w, cliCtx, rest.ResponseWithHeight{res, height}) } } From bb1a498e529dbe104b711ca3882df5d4eb06031f Mon Sep 17 00:00:00 2001 From: Colin Axner Date: Mon, 17 Jun 2019 15:17:22 -0700 Subject: [PATCH 02/16] generalize response with height --- types/rest/rest.go | 7 +++++++ x/auth/client/rest/query.go | 9 +-------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/types/rest/rest.go b/types/rest/rest.go index 0a87c8b96e30..6b03fab967a8 100644 --- a/types/rest/rest.go +++ b/types/rest/rest.go @@ -28,6 +28,13 @@ type GasEstimateResponse struct { GasEstimate uint64 `json:"gas_estimate"` } +// ResponseWithHeight wraps the embedded interface with the height it was queried +// at. +type ResponseWithHeight struct { + RespValue interface{} `json:"response"` + Height int64 `json:"height"` +} + // BaseReq defines a structure that can be embedded in other request structures // that all share common "base" fields. type BaseReq struct { diff --git a/x/auth/client/rest/query.go b/x/auth/client/rest/query.go index 0c54ddd508ec..f107e281aa07 100644 --- a/x/auth/client/rest/query.go +++ b/x/auth/client/rest/query.go @@ -14,13 +14,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth/types" ) -// AccountWithHeight wraps the embedded Account with the height it was queried -// at. -type AccountWithHeight struct { - types.Account `json:"account"` - Height int64 `json:"height"` -} - // query accountREST Handler func QueryAccountRequestHandlerFn( storeName string, decoder types.AccountDecoder, cliCtx context.CLIContext, @@ -60,7 +53,7 @@ func QueryAccountRequestHandlerFn( return } - rest.PostProcessResponse(w, cliCtx, AccountWithHeight{account, height}) + rest.PostProcessResponse(w, cliCtx, rest.ResponseWithHeight{account, height}) } } From 3c0faea7665e5eb8744861130d8c298de07b9dc8 Mon Sep 17 00:00:00 2001 From: Colin Axner Date: Mon, 17 Jun 2019 15:22:43 -0700 Subject: [PATCH 03/16] pending log --- .pending/improvements/sdk/4573-adds-height-in- | 1 + 1 file changed, 1 insertion(+) create mode 100644 .pending/improvements/sdk/4573-adds-height-in- diff --git a/.pending/improvements/sdk/4573-adds-height-in- b/.pending/improvements/sdk/4573-adds-height-in- new file mode 100644 index 000000000000..1bf235991ea2 --- /dev/null +++ b/.pending/improvements/sdk/4573-adds-height-in- @@ -0,0 +1 @@ +#4573 adds height in response for validator endpoints \ No newline at end of file From 975073f53f3c6e6e7fc93fe8429574596ea2e133 Mon Sep 17 00:00:00 2001 From: Colin Axner Date: Wed, 19 Jun 2019 16:44:19 -0700 Subject: [PATCH 04/16] beginning part of test for rest --- types/rest/rest.go | 38 ++++++++++++++++--------- types/rest/rest_test.go | 61 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 13 deletions(-) diff --git a/types/rest/rest.go b/types/rest/rest.go index 6b03fab967a8..3042b63bf5a5 100644 --- a/types/rest/rest.go +++ b/types/rest/rest.go @@ -3,6 +3,7 @@ package rest import ( + "encoding/json" "errors" "fmt" "io/ioutil" @@ -28,13 +29,6 @@ type GasEstimateResponse struct { GasEstimate uint64 `json:"gas_estimate"` } -// ResponseWithHeight wraps the embedded interface with the height it was queried -// at. -type ResponseWithHeight struct { - RespValue interface{} `json:"response"` - Height int64 `json:"height"` -} - // BaseReq defines a structure that can be embedded in other request structures // that all share common "base" fields. type BaseReq struct { @@ -229,7 +223,7 @@ func ParseQueryHeightOrReturnBadRequest(w http.ResponseWriter, cliCtx context.CL } // PostProcessResponse performs post processing for a REST response. -func PostProcessResponse(w http.ResponseWriter, cliCtx context.CLIContext, response interface{}) { +func PostProcessResponse(w http.ResponseWriter, cliCtx context.CLIContext, response interface{}, height int64) { var output []byte switch response.(type) { @@ -238,15 +232,33 @@ func PostProcessResponse(w http.ResponseWriter, cliCtx context.CLIContext, respo default: var err error - if cliCtx.Indent { - output, err = cliCtx.Codec.MarshalJSONIndent(response, "", " ") - } else { - output, err = cliCtx.Codec.MarshalJSON(response) - } + output, err = cliCtx.Codec.MarshalJSON(response) if err != nil { WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } + + } + + // inject the height into the json response by + // - decoding into the map + // - adding the height to the map + // - encoding using standard json library + var m map[string]interface{} + err := json.Unmarshal(output, &m) + if err != nil { + WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + } + m["height"] = height + + if cliCtx.Indent { + output, err = json.MarshalIndent(m, "", " ") + } else { + output, err = json.Marshal(m) + } + if err != nil { + WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return } w.Header().Set("Content-Type", "application/json") diff --git a/types/rest/rest_test.go b/types/rest/rest_test.go index 22d399ebd9c9..8ccd132e30bc 100644 --- a/types/rest/rest_test.go +++ b/types/rest/rest_test.go @@ -3,13 +3,19 @@ package rest import ( + // "encoding/json" + "fmt" "io" "net/http" "net/http/httptest" "testing" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/codec" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/stretchr/testify/require" + // "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/secp256k1" "github.com/cosmos/cosmos-sdk/types" ) @@ -138,6 +144,61 @@ func TestParseQueryHeight(t *testing.T) { } } +func TestProcessPostResponse(t *testing.T) { + expectedJSONWithHeight := []byte(`{"height":194423","type":"cosmos-sdk/BaseAccount","value":{"address":"cosmos1gc72g4guwg2efa03xgkx3u6ft6t39xqzelfx04","coins":[{"denom":"atom","amount":"100"},{"denom":"tree","amount":"125"}],"public_key":{"type":"tendermint/PubKeySecp256k1","value":"A0tS6HI8Goq1lXEK2+g2nT5Hq3qteBVtL0va9kn9BB++"},"account_number":"104","sequence":"32"}}`) + + // setup + var w http.ResponseWriter + + privKey := secp256k1.GenPrivKey() + pubKey := privKey.PubKey() + addr := types.AccAddress(pubKey.Address()) + coins := types.NewCoins(types.NewCoin("atom", types.NewInt(100)), types.NewCoin("tree", types.NewInt(125))) + //height := int64(194423) + accNumber := uint64(104) + sequence := uint64(32) + + acc := authtypes.NewBaseAccount(addr, coins, pubKey, accNumber, sequence) + cdc := codec.New() + authtypes.RegisterBaseAccount(cdc) + + // expected json response with zero height + expectedJSONNoHeight, err := cdc.MarshalJSON(acc) + require.Nil(t, err) + + ProcessPostResponse(w) + + /* + To test + - no height marshaled struct returns same thing + - not marhsaled no height returns expected no height + - height marshaled struct returns expected with heigh + - height no marshaled returns exected with height + - all the above with indent + + expectedOutput, err := cdc.MarshalJSONIndent(expectedMockAcc, "", " ") + require.Nil(t, err) + fmt.Printf("%s\n", expectedOutput) + fmt.Printf("%s\n", actualOutput) + // require.Equal(t, expectedOutput, actualOutput) + + // test that JSONMarshal returns equivalent output + actualOutput, err = cdc.MarshalJSON(mockAcc) + require.Nil(t, err) + m := make(map[string]interface{}) + err = json.Unmarshal(actualOutput, &m) + require.Nil(t, err) + fmt.Printf("%s\n", m) + m["height"] = height + actualOutput, err = json.MarshalIndent(m, "", " ") + fmt.Printf("%s\n", actualOutput) + var i mockAccount + err = cdc.UnmarshalJSON(actualOutput, &i) + require.Nil(t, err) + fmt.Printf("%v\n", i) + */ +} + func mustNewRequest(t *testing.T, method, url string, body io.Reader) *http.Request { req, err := http.NewRequest(method, url, body) require.NoError(t, err) From 62fcc39455173cf7c584686b479795af745092d9 Mon Sep 17 00:00:00 2001 From: Colin Axner Date: Thu, 20 Jun 2019 16:03:03 -0700 Subject: [PATCH 05/16] updated postprocessresponse to encode in height, added wip test --- types/rest/rest.go | 62 ++++++++++++++-------- types/rest/rest_test.go | 110 +++++++++++++++++++++++++--------------- 2 files changed, 109 insertions(+), 63 deletions(-) diff --git a/types/rest/rest.go b/types/rest/rest.go index 3042b63bf5a5..a19caaaf098f 100644 --- a/types/rest/rest.go +++ b/types/rest/rest.go @@ -226,40 +226,58 @@ func ParseQueryHeightOrReturnBadRequest(w http.ResponseWriter, cliCtx context.CL func PostProcessResponse(w http.ResponseWriter, cliCtx context.CLIContext, response interface{}, height int64) { var output []byte + if height < 0 { + WriteErrorResponse(w, http.StatusInternalServerError, fmt.Errorf("negative height").Error()) + return + } + switch response.(type) { case []byte: output = response.([]byte) default: var err error - output, err = cliCtx.Codec.MarshalJSON(response) + if cliCtx.Indent { + output, err = cliCtx.Codec.MarshalJSONIndent(response, "", " ") + } else { + output, err = cliCtx.Codec.MarshalJSON(response) + } + if err != nil { WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } - - } - - // inject the height into the json response by - // - decoding into the map - // - adding the height to the map - // - encoding using standard json library - var m map[string]interface{} - err := json.Unmarshal(output, &m) - if err != nil { - WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - } - m["height"] = height - - if cliCtx.Indent { - output, err = json.MarshalIndent(m, "", " ") - } else { - output, err = json.Marshal(m) } - if err != nil { - WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return + fmt.Println("before height") + if height > 0 { + fmt.Println("height") + fmt.Println(height) + // inject the height into the json response by + // - decoding into the map + // - adding the height to the map + // - encoding using standard json library + m := make(map[string]interface{}) + err := json.Unmarshal(output, &m) + if err != nil { + fmt.Println("first marshal error") + WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + m["height"] = height + fmt.Printf("%s\n", m) + if cliCtx.Indent { + output, err = json.MarshalIndent(m, "", " ") + } else { + output, err = json.Marshal(m) + } + fmt.Printf("%s\n", output) + if err != nil { + fmt.Println("second marshal error") + WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } } + fmt.Printf("%s\n", output) w.Header().Set("Content-Type", "application/json") _, _ = w.Write(output) diff --git a/types/rest/rest_test.go b/types/rest/rest_test.go index 8ccd132e30bc..214189406ea6 100644 --- a/types/rest/rest_test.go +++ b/types/rest/rest_test.go @@ -3,21 +3,23 @@ package rest import ( - // "encoding/json" "fmt" + "strconv" + // "encoding/json" "io" + "io/ioutil" "net/http" "net/http/httptest" "testing" - "github.com/cosmos/cosmos-sdk/client/context" - "github.com/cosmos/cosmos-sdk/codec" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" "github.com/stretchr/testify/require" // "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/secp256k1" + "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/types" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" ) type mockResponseWriter struct{} @@ -145,58 +147,84 @@ func TestParseQueryHeight(t *testing.T) { } func TestProcessPostResponse(t *testing.T) { - expectedJSONWithHeight := []byte(`{"height":194423","type":"cosmos-sdk/BaseAccount","value":{"address":"cosmos1gc72g4guwg2efa03xgkx3u6ft6t39xqzelfx04","coins":[{"denom":"atom","amount":"100"},{"denom":"tree","amount":"125"}],"public_key":{"type":"tendermint/PubKeySecp256k1","value":"A0tS6HI8Goq1lXEK2+g2nT5Hq3qteBVtL0va9kn9BB++"},"account_number":"104","sequence":"32"}}`) - // setup - var w http.ResponseWriter + ctx := context.NewCLIContext() + height := int64(194423) privKey := secp256k1.GenPrivKey() pubKey := privKey.PubKey() addr := types.AccAddress(pubKey.Address()) coins := types.NewCoins(types.NewCoin("atom", types.NewInt(100)), types.NewCoin("tree", types.NewInt(125))) - //height := int64(194423) accNumber := uint64(104) sequence := uint64(32) acc := authtypes.NewBaseAccount(addr, coins, pubKey, accNumber, sequence) cdc := codec.New() authtypes.RegisterBaseAccount(cdc) + ctx = ctx.WithCodec(cdc) - // expected json response with zero height - expectedJSONNoHeight, err := cdc.MarshalJSON(acc) + // setup expected json responses with zero height + jsonNoHeight, err := cdc.MarshalJSON(acc) + require.Nil(t, err) + require.NotNil(t, jsonNoHeight) + jsonIndentNoHeight, err := cdc.MarshalJSONIndent(acc, "", " ") require.Nil(t, err) + require.NotNil(t, jsonIndentNoHeight) + fmt.Println(strconv.Itoa(int(height))) + jsonWithHeight := append(append([]byte(`{"height":`), []byte(strconv.Itoa(int(height))+",")...), jsonNoHeight[1:]...) + + // check that negative height writes an error + w := httptest.NewRecorder() + PostProcessResponse(w, ctx, acc, -1) + require.Equal(t, http.StatusInternalServerError, w.Code) + + // check that zero height returns expected response + runPostProcessResponse(t, ctx, acc, jsonNoHeight, 0, false) + // chcek zero height with indent + runPostProcessResponse(t, ctx, acc, jsonIndentNoHeight, 0, true) + // check that height returns expected response + runPostProcessResponse(t, ctx, acc, jsonWithHeight, height, false) + // check height with indent + //runPostProcessResponse(t, ctx, acc, jsonIndentWithHeight, height, true) +} + +// asserts that ResponseRecorder returns the expected code and body +// runs account +func runPostProcessResponse(t *testing.T, ctx context.CLIContext, obj interface{}, + expectedBody []byte, height int64, indent bool, +) { + if indent { + ctx.Indent = indent + } + + // test using unmarshalled struct + w := httptest.NewRecorder() + PostProcessResponse(w, ctx, obj, height) + require.Equal(t, http.StatusOK, w.Code, w.Body) + resp := w.Result() + body, err := ioutil.ReadAll(resp.Body) + require.Nil(t, err) + require.Equal(t, expectedBody, body) - ProcessPostResponse(w) - - /* - To test - - no height marshaled struct returns same thing - - not marhsaled no height returns expected no height - - height marshaled struct returns expected with heigh - - height no marshaled returns exected with height - - all the above with indent - - expectedOutput, err := cdc.MarshalJSONIndent(expectedMockAcc, "", " ") - require.Nil(t, err) - fmt.Printf("%s\n", expectedOutput) - fmt.Printf("%s\n", actualOutput) - // require.Equal(t, expectedOutput, actualOutput) - - // test that JSONMarshal returns equivalent output - actualOutput, err = cdc.MarshalJSON(mockAcc) - require.Nil(t, err) - m := make(map[string]interface{}) - err = json.Unmarshal(actualOutput, &m) - require.Nil(t, err) - fmt.Printf("%s\n", m) - m["height"] = height - actualOutput, err = json.MarshalIndent(m, "", " ") - fmt.Printf("%s\n", actualOutput) - var i mockAccount - err = cdc.UnmarshalJSON(actualOutput, &i) - require.Nil(t, err) - fmt.Printf("%v\n", i) - */ + var marshalled []byte + if indent { + marshalled, err = ctx.Codec.MarshalJSONIndent(obj, "", " ") + } else { + marshalled, err = ctx.Codec.MarshalJSON(obj) + } + require.Nil(t, err) + + // test using marshalled struct, expects passed in byte slice to be written + w = httptest.NewRecorder() + PostProcessResponse(w, ctx, marshalled, height) + require.Equal(t, http.StatusOK, w.Code, w.Body) + resp = w.Result() + body, err = ioutil.ReadAll(resp.Body) + require.Nil(t, err) + fmt.Println() + fmt.Printf("%s\n", body) + fmt.Printf("%v\n", w.Body) + require.Equal(t, expectedBody, body) } func mustNewRequest(t *testing.T, method, url string, body io.Reader) *http.Request { From 8aacfa58e14dee5d9b306464cfcd8fad5f2cae15 Mon Sep 17 00:00:00 2001 From: Colin Axner Date: Fri, 21 Jun 2019 11:34:57 -0700 Subject: [PATCH 06/16] added passing postprocessresponse test --- types/rest/rest.go | 51 +++++++++++++++++-------------------- types/rest/rest_test.go | 34 ++++++++++++++----------- x/auth/client/rest/query.go | 2 +- 3 files changed, 44 insertions(+), 43 deletions(-) diff --git a/types/rest/rest.go b/types/rest/rest.go index a19caaaf098f..1f334f780866 100644 --- a/types/rest/rest.go +++ b/types/rest/rest.go @@ -223,6 +223,12 @@ func ParseQueryHeightOrReturnBadRequest(w http.ResponseWriter, cliCtx context.CL } // PostProcessResponse performs post processing for a REST response. +// If the height is greater than zero it will be injected into the body of +// the response. All responses are decoded into the map and encoded again +// using JSON standard library. This is to ensure all responses are ordered +// alphabetically rather than by their positioning within their respective +// structs. An internal server error is written to the response if the +// height is negative or an encoding/decoding error occurs. func PostProcessResponse(w http.ResponseWriter, cliCtx context.CLIContext, response interface{}, height int64) { var output []byte @@ -248,36 +254,27 @@ func PostProcessResponse(w http.ResponseWriter, cliCtx context.CLIContext, respo return } } - fmt.Println("before height") + + m := make(map[string]interface{}) + err := json.Unmarshal(output, &m) + if err != nil { + WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + if height > 0 { - fmt.Println("height") - fmt.Println(height) - // inject the height into the json response by - // - decoding into the map - // - adding the height to the map - // - encoding using standard json library - m := make(map[string]interface{}) - err := json.Unmarshal(output, &m) - if err != nil { - fmt.Println("first marshal error") - WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } m["height"] = height - fmt.Printf("%s\n", m) - if cliCtx.Indent { - output, err = json.MarshalIndent(m, "", " ") - } else { - output, err = json.Marshal(m) - } - fmt.Printf("%s\n", output) - if err != nil { - fmt.Println("second marshal error") - WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return - } } - fmt.Printf("%s\n", output) + + if cliCtx.Indent { + output, err = json.MarshalIndent(m, "", " ") + } else { + output, err = json.Marshal(m) + } + if err != nil { + WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } w.Header().Set("Content-Type", "application/json") _, _ = w.Write(output) diff --git a/types/rest/rest_test.go b/types/rest/rest_test.go index 214189406ea6..468c6bbf4a76 100644 --- a/types/rest/rest_test.go +++ b/types/rest/rest_test.go @@ -3,17 +3,15 @@ package rest import ( - "fmt" - "strconv" - // "encoding/json" + "encoding/json" "io" "io/ioutil" "net/http" "net/http/httptest" + "strconv" "testing" "github.com/stretchr/testify/require" - // "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/secp256k1" "github.com/cosmos/cosmos-sdk/client/context" @@ -170,8 +168,16 @@ func TestProcessPostResponse(t *testing.T) { jsonIndentNoHeight, err := cdc.MarshalJSONIndent(acc, "", " ") require.Nil(t, err) require.NotNil(t, jsonIndentNoHeight) - fmt.Println(strconv.Itoa(int(height))) - jsonWithHeight := append(append([]byte(`{"height":`), []byte(strconv.Itoa(int(height))+",")...), jsonNoHeight[1:]...) + + // decode into map to order alphabetically + m := make(map[string]interface{}) + err = json.Unmarshal(jsonNoHeight, &m) + require.Nil(t, err) + jsonMap, err := json.Marshal(m) + require.Nil(t, err) + jsonWithHeight := append(append([]byte(`{"height":`), []byte(strconv.Itoa(int(height))+",")...), jsonMap[1:]...) + jsonIndentMap, err := json.MarshalIndent(m, "", " ") + jsonIndentWithHeight := append(append([]byte(`{`+"\n "+`"height": `), []byte(strconv.Itoa(int(height))+",")...), jsonIndentMap[1:]...) // check that negative height writes an error w := httptest.NewRecorder() @@ -179,17 +185,18 @@ func TestProcessPostResponse(t *testing.T) { require.Equal(t, http.StatusInternalServerError, w.Code) // check that zero height returns expected response - runPostProcessResponse(t, ctx, acc, jsonNoHeight, 0, false) + runPostProcessResponse(t, ctx, acc, jsonMap, 0, false) // chcek zero height with indent - runPostProcessResponse(t, ctx, acc, jsonIndentNoHeight, 0, true) + runPostProcessResponse(t, ctx, acc, jsonIndentMap, 0, true) // check that height returns expected response runPostProcessResponse(t, ctx, acc, jsonWithHeight, height, false) // check height with indent - //runPostProcessResponse(t, ctx, acc, jsonIndentWithHeight, height, true) + runPostProcessResponse(t, ctx, acc, jsonIndentWithHeight, height, true) } // asserts that ResponseRecorder returns the expected code and body -// runs account +// runs PostProcessResponse on the objects regular interface and on +// the marshalled struct. func runPostProcessResponse(t *testing.T, ctx context.CLIContext, obj interface{}, expectedBody []byte, height int64, indent bool, ) { @@ -197,7 +204,7 @@ func runPostProcessResponse(t *testing.T, ctx context.CLIContext, obj interface{ ctx.Indent = indent } - // test using unmarshalled struct + // test using regular struct w := httptest.NewRecorder() PostProcessResponse(w, ctx, obj, height) require.Equal(t, http.StatusOK, w.Code, w.Body) @@ -214,16 +221,13 @@ func runPostProcessResponse(t *testing.T, ctx context.CLIContext, obj interface{ } require.Nil(t, err) - // test using marshalled struct, expects passed in byte slice to be written + // test using marshalled struct w = httptest.NewRecorder() PostProcessResponse(w, ctx, marshalled, height) require.Equal(t, http.StatusOK, w.Code, w.Body) resp = w.Result() body, err = ioutil.ReadAll(resp.Body) require.Nil(t, err) - fmt.Println() - fmt.Printf("%s\n", body) - fmt.Printf("%v\n", w.Body) require.Equal(t, expectedBody, body) } diff --git a/x/auth/client/rest/query.go b/x/auth/client/rest/query.go index f107e281aa07..9d0469a80bbe 100644 --- a/x/auth/client/rest/query.go +++ b/x/auth/client/rest/query.go @@ -53,7 +53,7 @@ func QueryAccountRequestHandlerFn( return } - rest.PostProcessResponse(w, cliCtx, rest.ResponseWithHeight{account, height}) + rest.PostProcessResponse(w, cliCtx, account, height) } } From 3a61eb736ec33e96947090223af02537ae97206c Mon Sep 17 00:00:00 2001 From: Colin Axner Date: Fri, 21 Jun 2019 12:16:54 -0700 Subject: [PATCH 07/16] update delegator json tag --- x/distribution/types/delegator.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/distribution/types/delegator.go b/x/distribution/types/delegator.go index 550dab1f14a2..fcbc48560a1c 100644 --- a/x/distribution/types/delegator.go +++ b/x/distribution/types/delegator.go @@ -14,7 +14,7 @@ import ( type DelegatorStartingInfo struct { PreviousPeriod uint64 `json:"previous_period"` // period at which the delegation should withdraw starting from Stake sdk.Dec `json:"stake"` // amount of staking token delegated - Height uint64 `json:"height"` // height at which delegation was created + Height uint64 `json:"creation_height"` // height at which delegation was created } // create a new DelegatorStartingInfo From cc115ef7d4e1cf1870932e9d797d218a7727a175 Mon Sep 17 00:00:00 2001 From: Colin Axner Date: Fri, 21 Jun 2019 12:23:58 -0700 Subject: [PATCH 08/16] revert indenting to two spaces --- types/rest/rest.go | 4 ++-- types/rest/rest_test.go | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/types/rest/rest.go b/types/rest/rest.go index db1c93ed5df3..e1b433a809f9 100644 --- a/types/rest/rest.go +++ b/types/rest/rest.go @@ -241,7 +241,7 @@ func PostProcessResponse(w http.ResponseWriter, cliCtx context.CLIContext, respo default: var err error if cliCtx.Indent { - output, err = cliCtx.Codec.MarshalJSONIndent(response, "", " ") + output, err = cliCtx.Codec.MarshalJSONIndent(response, "", " ") } else { output, err = cliCtx.Codec.MarshalJSON(response) } @@ -267,7 +267,7 @@ func PostProcessResponse(w http.ResponseWriter, cliCtx context.CLIContext, respo m["height"] = height if cliCtx.Indent { - output, err = json.MarshalIndent(m, "", " ") + output, err = json.MarshalIndent(m, "", " ") } else { output, err = json.Marshal(m) } diff --git a/types/rest/rest_test.go b/types/rest/rest_test.go index 430608f1c3b8..fce92e99f4aa 100644 --- a/types/rest/rest_test.go +++ b/types/rest/rest_test.go @@ -4,6 +4,7 @@ package rest import ( "encoding/json" + "fmt" "io" "io/ioutil" "net/http" @@ -165,7 +166,7 @@ func TestProcessPostResponse(t *testing.T) { jsonNoHeight, err := cdc.MarshalJSON(acc) require.Nil(t, err) require.NotNil(t, jsonNoHeight) - jsonIndentNoHeight, err := cdc.MarshalJSONIndent(acc, "", " ") + jsonIndentNoHeight, err := cdc.MarshalJSONIndent(acc, "", " ") require.Nil(t, err) require.NotNil(t, jsonIndentNoHeight) @@ -176,8 +177,8 @@ func TestProcessPostResponse(t *testing.T) { jsonMap, err := json.Marshal(m) require.Nil(t, err) jsonWithHeight := append(append([]byte(`{"height":`), []byte(strconv.Itoa(int(height))+",")...), jsonMap[1:]...) - jsonIndentMap, err := json.MarshalIndent(m, "", " ") - jsonIndentWithHeight := append(append([]byte(`{`+"\n "+`"height": `), []byte(strconv.Itoa(int(height))+",")...), jsonIndentMap[1:]...) + jsonIndentMap, err := json.MarshalIndent(m, "", " ") + jsonIndentWithHeight := append(append([]byte(`{`+"\n "+` "height": `), []byte(strconv.Itoa(int(height))+",")...), jsonIndentMap[1:]...) // check that negative height writes an error w := httptest.NewRecorder() @@ -215,7 +216,7 @@ func runPostProcessResponse(t *testing.T, ctx context.CLIContext, obj interface{ var marshalled []byte if indent { - marshalled, err = ctx.Codec.MarshalJSONIndent(obj, "", " ") + marshalled, err = ctx.Codec.MarshalJSONIndent(obj, "", " ") } else { marshalled, err = ctx.Codec.MarshalJSON(obj) } From ca2618c7119f67f502192674d2bc714bf06409fe Mon Sep 17 00:00:00 2001 From: Colin Axner Date: Fri, 21 Jun 2019 12:26:10 -0700 Subject: [PATCH 09/16] update pending log --- .pending/improvements/sdk/4573-adds-height-in- | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pending/improvements/sdk/4573-adds-height-in- b/.pending/improvements/sdk/4573-adds-height-in- index 1bf235991ea2..a0d26cad1d40 100644 --- a/.pending/improvements/sdk/4573-adds-height-in- +++ b/.pending/improvements/sdk/4573-adds-height-in- @@ -1 +1 @@ -#4573 adds height in response for validator endpoints \ No newline at end of file +#4573 Returns height in response for query endpoints. From 73c8f812ce1939fe365a48c59f1b30932722b10a Mon Sep 17 00:00:00 2001 From: Colin Axner Date: Fri, 21 Jun 2019 12:31:27 -0700 Subject: [PATCH 10/16] fix function comment --- types/rest/rest.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/types/rest/rest.go b/types/rest/rest.go index e1b433a809f9..11c8ade7acd0 100644 --- a/types/rest/rest.go +++ b/types/rest/rest.go @@ -223,14 +223,14 @@ func ParseQueryHeightOrReturnBadRequest(w http.ResponseWriter, cliCtx context.CL } // PostProcessResponse performs post processing for a REST response. -// If the height is greater than zero it will be injected into the body of -// the response.An internal server error is written to the response if the -// height is negative or an encoding/decoding error occurs. +// If the height is greater than zero it will be injected into the body +// of the response. An internal server error is written to the response +// if the height is negative or an encoding/decoding error occurs. func PostProcessResponse(w http.ResponseWriter, cliCtx context.CLIContext, response interface{}, height int64) { var output []byte if height < 0 { - WriteErrorResponse(w, http.StatusInternalServerError, fmt.Errorf("negative height").Error()) + WriteErrorResponse(w, http.StatusInternalServerError, fmt.Errorf("negative height used in query").Error()) return } From 5a845b28c9cb181c430375b210659025fd83adc3 Mon Sep 17 00:00:00 2001 From: Colin Axner Date: Fri, 21 Jun 2019 16:52:45 -0700 Subject: [PATCH 11/16] rm unused fmt import --- types/rest/rest_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/types/rest/rest_test.go b/types/rest/rest_test.go index fce92e99f4aa..f68631d3abc3 100644 --- a/types/rest/rest_test.go +++ b/types/rest/rest_test.go @@ -4,7 +4,6 @@ package rest import ( "encoding/json" - "fmt" "io" "io/ioutil" "net/http" From 1619f904502b5948ec9937388a909f548db96c4f Mon Sep 17 00:00:00 2001 From: Colin Axner Date: Mon, 24 Jun 2019 10:20:07 -0700 Subject: [PATCH 12/16] height set in ctx instead of passed in func --- client/rpc/block.go | 4 ++-- client/rpc/status.go | 2 +- client/rpc/validators.go | 4 ++-- types/rest/rest.go | 10 +++++----- types/rest/rest_test.go | 19 +++++++++++-------- x/auth/client/rest/broadcast.go | 2 +- x/auth/client/rest/encode.go | 2 +- x/auth/client/rest/query.go | 10 +++++----- x/bank/client/rest/query.go | 6 ++++-- x/distribution/client/rest/query.go | 19 +++++++++++-------- x/gov/client/rest/rest.go | 22 +++++++++++++--------- x/mint/client/rest/query.go | 9 ++++++--- x/slashing/client/rest/query.go | 9 ++++++--- x/staking/client/rest/query.go | 15 ++++++++++----- x/staking/client/rest/utils.go | 12 +++++++++--- 15 files changed, 87 insertions(+), 58 deletions(-) diff --git a/client/rpc/block.go b/client/rpc/block.go index 914333164e12..53177ec3ba6c 100644 --- a/client/rpc/block.go +++ b/client/rpc/block.go @@ -131,7 +131,7 @@ func BlockRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } - rest.PostProcessResponse(w, cliCtx, output, 0) + rest.PostProcessResponse(w, cliCtx, output) } } @@ -144,6 +144,6 @@ func LatestBlockRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - rest.PostProcessResponse(w, cliCtx, output, 0) + rest.PostProcessResponse(w, cliCtx, output) } } diff --git a/client/rpc/status.go b/client/rpc/status.go index e0fe61789fc2..88886293e5c5 100644 --- a/client/rpc/status.go +++ b/client/rpc/status.go @@ -78,7 +78,7 @@ func NodeInfoRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { } nodeInfo := status.NodeInfo - rest.PostProcessResponse(w, cliCtx, nodeInfo, 0) + rest.PostProcessResponse(w, cliCtx, nodeInfo) } } diff --git a/client/rpc/validators.go b/client/rpc/validators.go index f9302b7fdeb9..e98db0a0dd52 100644 --- a/client/rpc/validators.go +++ b/client/rpc/validators.go @@ -176,7 +176,7 @@ func ValidatorSetRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } - rest.PostProcessResponse(w, cliCtx, output, 0) + rest.PostProcessResponse(w, cliCtx, output) } } @@ -189,6 +189,6 @@ func LatestValidatorSetRequestHandlerFn(cliCtx context.CLIContext) http.HandlerF return } - rest.PostProcessResponse(w, cliCtx, output, 0) + rest.PostProcessResponse(w, cliCtx, output) } } diff --git a/types/rest/rest.go b/types/rest/rest.go index 11c8ade7acd0..3041b67796d8 100644 --- a/types/rest/rest.go +++ b/types/rest/rest.go @@ -226,11 +226,11 @@ func ParseQueryHeightOrReturnBadRequest(w http.ResponseWriter, cliCtx context.CL // If the height is greater than zero it will be injected into the body // of the response. An internal server error is written to the response // if the height is negative or an encoding/decoding error occurs. -func PostProcessResponse(w http.ResponseWriter, cliCtx context.CLIContext, response interface{}, height int64) { +func PostProcessResponse(w http.ResponseWriter, cliCtx context.CLIContext, response interface{}) { var output []byte - if height < 0 { - WriteErrorResponse(w, http.StatusInternalServerError, fmt.Errorf("negative height used in query").Error()) + if cliCtx.Height < 0 { + WriteErrorResponse(w, http.StatusInternalServerError, fmt.Errorf("negative height in response").Error()) return } @@ -256,7 +256,7 @@ func PostProcessResponse(w http.ResponseWriter, cliCtx context.CLIContext, respo // - decoding into a map // - adding the height to the map // - encoding using standard JSON library - if height > 0 { + if cliCtx.Height > 0 { m := make(map[string]interface{}) err := json.Unmarshal(output, &m) if err != nil { @@ -264,7 +264,7 @@ func PostProcessResponse(w http.ResponseWriter, cliCtx context.CLIContext, respo return } - m["height"] = height + m["height"] = cliCtx.Height if cliCtx.Indent { output, err = json.MarshalIndent(m, "", " ") diff --git a/types/rest/rest_test.go b/types/rest/rest_test.go index f68631d3abc3..28e2111e5c2a 100644 --- a/types/rest/rest_test.go +++ b/types/rest/rest_test.go @@ -181,24 +181,27 @@ func TestProcessPostResponse(t *testing.T) { // check that negative height writes an error w := httptest.NewRecorder() - PostProcessResponse(w, ctx, acc, -1) + ctx = ctx.WithHeight(-1) + PostProcessResponse(w, ctx, acc) require.Equal(t, http.StatusInternalServerError, w.Code) // check that zero height returns expected response - runPostProcessResponse(t, ctx, acc, jsonNoHeight, 0, false) + ctx = ctx.WithHeight(0) + runPostProcessResponse(t, ctx, acc, jsonNoHeight, false) // chcek zero height with indent - runPostProcessResponse(t, ctx, acc, jsonIndentNoHeight, 0, true) + runPostProcessResponse(t, ctx, acc, jsonIndentNoHeight, true) // check that height returns expected response - runPostProcessResponse(t, ctx, acc, jsonWithHeight, height, false) + ctx = ctx.WithHeight(height) + runPostProcessResponse(t, ctx, acc, jsonWithHeight, false) // check height with indent - runPostProcessResponse(t, ctx, acc, jsonIndentWithHeight, height, true) + runPostProcessResponse(t, ctx, acc, jsonIndentWithHeight, true) } // asserts that ResponseRecorder returns the expected code and body // runs PostProcessResponse on the objects regular interface and on // the marshalled struct. func runPostProcessResponse(t *testing.T, ctx context.CLIContext, obj interface{}, - expectedBody []byte, height int64, indent bool, + expectedBody []byte, indent bool, ) { if indent { ctx.Indent = indent @@ -206,7 +209,7 @@ func runPostProcessResponse(t *testing.T, ctx context.CLIContext, obj interface{ // test using regular struct w := httptest.NewRecorder() - PostProcessResponse(w, ctx, obj, height) + PostProcessResponse(w, ctx, obj) require.Equal(t, http.StatusOK, w.Code, w.Body) resp := w.Result() body, err := ioutil.ReadAll(resp.Body) @@ -223,7 +226,7 @@ func runPostProcessResponse(t *testing.T, ctx context.CLIContext, obj interface{ // test using marshalled struct w = httptest.NewRecorder() - PostProcessResponse(w, ctx, marshalled, height) + PostProcessResponse(w, ctx, marshalled) require.Equal(t, http.StatusOK, w.Code, w.Body) resp = w.Result() body, err = ioutil.ReadAll(resp.Body) diff --git a/x/auth/client/rest/broadcast.go b/x/auth/client/rest/broadcast.go index 8b0eef07ab83..0a625d4400fb 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, 0) + rest.PostProcessResponse(w, cliCtx, res) } } diff --git a/x/auth/client/rest/encode.go b/x/auth/client/rest/encode.go index e62dd9920287..36e5469029af 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, 0) + rest.PostProcessResponse(w, cliCtx, response) } } diff --git a/x/auth/client/rest/query.go b/x/auth/client/rest/query.go index 3399d3d59ce3..35e59f40d6ff 100644 --- a/x/auth/client/rest/query.go +++ b/x/auth/client/rest/query.go @@ -35,7 +35,7 @@ func QueryAccountRequestHandlerFn(storeName string, cliCtx context.CLIContext) h accGetter := types.NewAccountRetriever(cliCtx) // the query will return empty account if there is no data if err := accGetter.EnsureExists(addr); err != nil { - rest.PostProcessResponse(w, cliCtx, types.BaseAccount{}, cliCtx.Height) + rest.PostProcessResponse(w, cliCtx, types.BaseAccount{}) return } @@ -45,7 +45,7 @@ func QueryAccountRequestHandlerFn(storeName string, cliCtx context.CLIContext) h return } - rest.PostProcessResponse(w, cliCtx, account, cliCtx.Height) + rest.PostProcessResponse(w, cliCtx, account) } } @@ -72,7 +72,7 @@ func QueryTxsByTagsRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc } if len(r.Form) == 0 { - rest.PostProcessResponse(w, cliCtx, txs, cliCtx.Height) + rest.PostProcessResponse(w, cliCtx, txs) return } @@ -88,7 +88,7 @@ func QueryTxsByTagsRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc return } - rest.PostProcessResponse(w, cliCtx, searchResult, cliCtx.Height) + rest.PostProcessResponse(w, cliCtx, searchResult) } } @@ -118,6 +118,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, cliCtx.Height) + rest.PostProcessResponse(w, cliCtx, output) } } diff --git a/x/bank/client/rest/query.go b/x/bank/client/rest/query.go index 40a4659e3abb..1341445cf06d 100644 --- a/x/bank/client/rest/query.go +++ b/x/bank/client/rest/query.go @@ -43,12 +43,14 @@ func QueryBalancesRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } + cliCtx = cliCtx.WithHeight(height) + // the query will return empty if there is no data for this account if len(res) == 0 { - rest.PostProcessResponse(w, cliCtx, sdk.Coins{}, height) + rest.PostProcessResponse(w, cliCtx, sdk.Coins{}) return } - rest.PostProcessResponse(w, cliCtx, res, height) + rest.PostProcessResponse(w, cliCtx, res) } } diff --git a/x/distribution/client/rest/query.go b/x/distribution/client/rest/query.go index 8de88964b2bb..31a0feca57dc 100644 --- a/x/distribution/client/rest/query.go +++ b/x/distribution/client/rest/query.go @@ -79,7 +79,7 @@ func delegatorRewardsHandlerFn(cliCtx context.CLIContext, queryRoute string) htt return } - rest.PostProcessResponse(w, cliCtx, res, cliCtx.Height) + rest.PostProcessResponse(w, cliCtx, res) } } @@ -97,7 +97,7 @@ func delegationRewardsHandlerFn(cliCtx context.CLIContext, queryRoute string) ht return } - rest.PostProcessResponse(w, cliCtx, res, cliCtx.Height) + rest.PostProcessResponse(w, cliCtx, res) } } @@ -121,7 +121,8 @@ func delegatorWithdrawalAddrHandlerFn(cliCtx context.CLIContext, queryRoute stri return } - rest.PostProcessResponse(w, cliCtx, res, height) + cliCtx = cliCtx.WithHeight(height) + rest.PostProcessResponse(w, cliCtx, res) } } @@ -179,7 +180,7 @@ func validatorInfoHandlerFn(cliCtx context.CLIContext, queryRoute string) http.H // Prepare response res := cliCtx.Codec.MustMarshalJSON(NewValidatorDistInfo(delAddr, rewards, valCom)) - rest.PostProcessResponse(w, cliCtx, res, cliCtx.Height) + rest.PostProcessResponse(w, cliCtx, res) } } @@ -203,7 +204,7 @@ func validatorRewardsHandlerFn(cliCtx context.CLIContext, queryRoute string) htt return } - rest.PostProcessResponse(w, cliCtx, res, cliCtx.Height) + rest.PostProcessResponse(w, cliCtx, res) } } @@ -221,7 +222,7 @@ func paramsHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerF return } - rest.PostProcessResponse(w, cliCtx, params, cliCtx.Height) + rest.PostProcessResponse(w, cliCtx, params) } } @@ -244,7 +245,8 @@ func communityPoolHandler(cliCtx context.CLIContext, queryRoute string) http.Han return } - rest.PostProcessResponse(w, cliCtx, result, height) + cliCtx = cliCtx.WithHeight(height) + rest.PostProcessResponse(w, cliCtx, result) } } @@ -268,7 +270,8 @@ func outstandingRewardsHandlerFn(cliCtx context.CLIContext, queryRoute string) h return } - rest.PostProcessResponse(w, cliCtx, res, height) + cliCtx = cliCtx.WithHeight(height) + rest.PostProcessResponse(w, cliCtx, res) } } diff --git a/x/gov/client/rest/rest.go b/x/gov/client/rest/rest.go index bf76e8eb7c1a..79121d33f741 100644 --- a/x/gov/client/rest/rest.go +++ b/x/gov/client/rest/rest.go @@ -207,7 +207,8 @@ func queryParamsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - rest.PostProcessResponse(w, cliCtx, res, height) + cliCtx = cliCtx.WithHeight(height) + rest.PostProcessResponse(w, cliCtx, res) } } @@ -246,7 +247,8 @@ func queryProposalHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - rest.PostProcessResponse(w, cliCtx, res, height) + cliCtx = cliCtx.WithHeight(height) + rest.PostProcessResponse(w, cliCtx, res) } } @@ -299,7 +301,7 @@ func queryDepositsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - rest.PostProcessResponse(w, cliCtx, res, cliCtx.Height) + rest.PostProcessResponse(w, cliCtx, res) } } @@ -324,7 +326,7 @@ func queryProposerHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - rest.PostProcessResponse(w, cliCtx, res, cliCtx.Height) + rest.PostProcessResponse(w, cliCtx, res) } } @@ -406,7 +408,7 @@ func queryDepositHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { } } - rest.PostProcessResponse(w, cliCtx, res, cliCtx.Height) + rest.PostProcessResponse(w, cliCtx, res) } } @@ -488,7 +490,7 @@ func queryVoteHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { } } - rest.PostProcessResponse(w, cliCtx, res, cliCtx.Height) + rest.PostProcessResponse(w, cliCtx, res) } } @@ -548,7 +550,7 @@ func queryVotesOnProposalHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - rest.PostProcessResponse(w, cliCtx, res, cliCtx.Height) + rest.PostProcessResponse(w, cliCtx, res) } } @@ -613,7 +615,8 @@ func queryProposalsWithParameterFn(cliCtx context.CLIContext) http.HandlerFunc { return } - rest.PostProcessResponse(w, cliCtx, res, height) + cliCtx = cliCtx.WithHeight(height) + rest.PostProcessResponse(w, cliCtx, res) } } @@ -653,6 +656,7 @@ func queryTallyOnProposalHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - rest.PostProcessResponse(w, cliCtx, res, height) + cliCtx = cliCtx.WithHeight(height) + rest.PostProcessResponse(w, cliCtx, res) } } diff --git a/x/mint/client/rest/query.go b/x/mint/client/rest/query.go index 3772c4cc13ce..f6e79cc31dcc 100644 --- a/x/mint/client/rest/query.go +++ b/x/mint/client/rest/query.go @@ -43,7 +43,8 @@ func queryParamsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - rest.PostProcessResponse(w, cliCtx, res, height) + cliCtx = cliCtx.WithHeight(height) + rest.PostProcessResponse(w, cliCtx, res) } } @@ -62,7 +63,8 @@ func queryInflationHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - rest.PostProcessResponse(w, cliCtx, res, height) + cliCtx = cliCtx.WithHeight(height) + rest.PostProcessResponse(w, cliCtx, res) } } @@ -81,6 +83,7 @@ func queryAnnualProvisionsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc return } - rest.PostProcessResponse(w, cliCtx, res, height) + cliCtx = cliCtx.WithHeight(height) + rest.PostProcessResponse(w, cliCtx, res) } } diff --git a/x/slashing/client/rest/query.go b/x/slashing/client/rest/query.go index 92a19fb58dfe..30a3e6683f78 100644 --- a/x/slashing/client/rest/query.go +++ b/x/slashing/client/rest/query.go @@ -59,7 +59,8 @@ func signingInfoHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - rest.PostProcessResponse(w, cliCtx, res, height) + cliCtx = cliCtx.WithHeight(height) + rest.PostProcessResponse(w, cliCtx, res) } } @@ -91,7 +92,8 @@ func signingInfoHandlerListFn(cliCtx context.CLIContext) http.HandlerFunc { return } - rest.PostProcessResponse(w, cliCtx, res, height) + cliCtx = cliCtx.WithHeight(height) + rest.PostProcessResponse(w, cliCtx, res) } } @@ -110,6 +112,7 @@ func queryParamsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - rest.PostProcessResponse(w, cliCtx, res, height) + cliCtx = cliCtx.WithHeight(height) + rest.PostProcessResponse(w, cliCtx, res) } } diff --git a/x/staking/client/rest/query.go b/x/staking/client/rest/query.go index 45bb313a08c6..90dad6f26aa8 100644 --- a/x/staking/client/rest/query.go +++ b/x/staking/client/rest/query.go @@ -171,7 +171,7 @@ func delegatorTxsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - rest.PostProcessResponse(w, cliCtx, res, cliCtx.Height) + rest.PostProcessResponse(w, cliCtx, res) } } @@ -233,7 +233,8 @@ func redelegationsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - rest.PostProcessResponse(w, cliCtx, res, height) + cliCtx = cliCtx.WithHeight(height) + rest.PostProcessResponse(w, cliCtx, res) } } @@ -284,7 +285,9 @@ func validatorsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } - rest.PostProcessResponse(w, cliCtx, res, height) + + cliCtx = cliCtx.WithHeight(height) + rest.PostProcessResponse(w, cliCtx, res) } } @@ -317,7 +320,8 @@ func poolHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - rest.PostProcessResponse(w, cliCtx, res, height) + cliCtx = cliCtx.WithHeight(height) + rest.PostProcessResponse(w, cliCtx, res) } } @@ -335,6 +339,7 @@ func paramsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { return } - rest.PostProcessResponse(w, cliCtx, res, height) + cliCtx = cliCtx.WithHeight(height) + rest.PostProcessResponse(w, cliCtx, res) } } diff --git a/x/staking/client/rest/utils.go b/x/staking/client/rest/utils.go index 2d0b53c796db..d75d36f100df 100644 --- a/x/staking/client/rest/utils.go +++ b/x/staking/client/rest/utils.go @@ -67,7 +67,9 @@ func queryBonds(cliCtx context.CLIContext, endpoint string) http.HandlerFunc { rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } - rest.PostProcessResponse(w, cliCtx, res, height) + + cliCtx = cliCtx.WithHeight(height) + rest.PostProcessResponse(w, cliCtx, res) } } @@ -100,7 +102,9 @@ func queryDelegator(cliCtx context.CLIContext, endpoint string) http.HandlerFunc rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } - rest.PostProcessResponse(w, cliCtx, res, height) + + cliCtx = cliCtx.WithHeight(height) + rest.PostProcessResponse(w, cliCtx, res) } } @@ -133,6 +137,8 @@ func queryValidator(cliCtx context.CLIContext, endpoint string) http.HandlerFunc rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } - rest.PostProcessResponse(w, cliCtx, res, height) + + cliCtx = cliCtx.WithHeight(height) + rest.PostProcessResponse(w, cliCtx, res) } } From 2d4e65ae676899ca827eaf89da565acb2f7de68b Mon Sep 17 00:00:00 2001 From: Colin Axner Date: Tue, 25 Jun 2019 11:55:08 -0700 Subject: [PATCH 13/16] add GetAccountWithHeight --- x/auth/client/rest/query.go | 3 ++- x/auth/types/account_retriever.go | 18 +++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/x/auth/client/rest/query.go b/x/auth/client/rest/query.go index 35e59f40d6ff..a724e272df8b 100644 --- a/x/auth/client/rest/query.go +++ b/x/auth/client/rest/query.go @@ -39,12 +39,13 @@ func QueryAccountRequestHandlerFn(storeName string, cliCtx context.CLIContext) h return } - account, err := accGetter.GetAccount(addr) + account, height, err := accGetter.GetAccountWithHeight(addr) if err != nil { rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } + cliCtx = cliCtx.WithHeight(height) rest.PostProcessResponse(w, cliCtx, account) } } diff --git a/x/auth/types/account_retriever.go b/x/auth/types/account_retriever.go index 22ac0957f5f3..b9bde6a49066 100644 --- a/x/auth/types/account_retriever.go +++ b/x/auth/types/account_retriever.go @@ -28,22 +28,30 @@ func NewAccountRetriever(querier NodeQuerier) AccountRetriever { // GetAccount queries for an account given an address and a block height. An // error is returned if the query or decoding fails. func (ar AccountRetriever) GetAccount(addr sdk.AccAddress) (Account, error) { + account, _, err := ar.GetAccountWithHeight(addr) + return account, err +} + +// GetAccountWithHeight queries for an account given an address. Returns the +// height of the query with the account. An error is returned if the query +// or decoding fails. +func (ar AccountRetriever) GetAccountWithHeight(addr sdk.AccAddress) (Account, int64, error) { bs, err := ModuleCdc.MarshalJSON(NewQueryAccountParams(addr)) if err != nil { - return nil, err + return nil, 0, err } - res, _, err := ar.querier.QueryWithData(fmt.Sprintf("custom/%s/%s", QuerierRoute, QueryAccount), bs) + res, height, err := ar.querier.QueryWithData(fmt.Sprintf("custom/%s/%s", QuerierRoute, QueryAccount), bs) if err != nil { - return nil, err + return nil, 0, err } var account Account if err := ModuleCdc.UnmarshalJSON(res, &account); err != nil { - return nil, err + return nil, 0, err } - return account, nil + return account, height, nil } // EnsureExists returns an error if no account exists for the given address else nil. From 8d06eb03ec9c664fdfc25bf7b842b51f7513bade Mon Sep 17 00:00:00 2001 From: Colin Axner Date: Tue, 25 Jun 2019 12:18:41 -0700 Subject: [PATCH 14/16] fix build errors --- x/auth/client/rest/query.go | 1 - x/auth/types/account_retriever.go | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/x/auth/client/rest/query.go b/x/auth/client/rest/query.go index 9382104fd78c..a724e272df8b 100644 --- a/x/auth/client/rest/query.go +++ b/x/auth/client/rest/query.go @@ -11,7 +11,6 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/rest" "github.com/cosmos/cosmos-sdk/x/auth/client/utils" - "github.com/cosmos/cosmos-sdk/x/auth/exported" "github.com/cosmos/cosmos-sdk/x/auth/types" ) diff --git a/x/auth/types/account_retriever.go b/x/auth/types/account_retriever.go index 3827d33f90b9..90af84ec6057 100644 --- a/x/auth/types/account_retriever.go +++ b/x/auth/types/account_retriever.go @@ -36,7 +36,7 @@ func (ar AccountRetriever) GetAccount(addr sdk.AccAddress) (exported.Account, er // GetAccountWithHeight queries for an account given an address. Returns the // height of the query with the account. An error is returned if the query // or decoding fails. -func (ar AccountRetriever) GetAccountWithHeight(addr sdk.AccAddress) (Account, int64, error) { +func (ar AccountRetriever) GetAccountWithHeight(addr sdk.AccAddress) (exported.Account, int64, error) { bs, err := ModuleCdc.MarshalJSON(NewQueryAccountParams(addr)) if err != nil { return nil, 0, err From 5809c5e1b9213892222d348b558067cfa5ed567c Mon Sep 17 00:00:00 2001 From: colin axner Date: Tue, 25 Jun 2019 14:39:59 -0700 Subject: [PATCH 15/16] misspelling Co-Authored-By: Federico Kunze <31522760+fedekunze@users.noreply.github.com> --- types/rest/rest_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/rest/rest_test.go b/types/rest/rest_test.go index 28e2111e5c2a..4f209dc7bac6 100644 --- a/types/rest/rest_test.go +++ b/types/rest/rest_test.go @@ -188,7 +188,7 @@ func TestProcessPostResponse(t *testing.T) { // check that zero height returns expected response ctx = ctx.WithHeight(0) runPostProcessResponse(t, ctx, acc, jsonNoHeight, false) - // chcek zero height with indent + // check zero height with indent runPostProcessResponse(t, ctx, acc, jsonIndentNoHeight, true) // check that height returns expected response ctx = ctx.WithHeight(height) From 18cbfbd5d0b332821b168adf5e4e4e775445adc7 Mon Sep 17 00:00:00 2001 From: Colin Axner Date: Mon, 1 Jul 2019 09:36:18 -0700 Subject: [PATCH 16/16] address @alessio pr comments; remove x/auth dependency --- types/rest/rest_test.go | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/types/rest/rest_test.go b/types/rest/rest_test.go index 28e2111e5c2a..2a1a4c68ddd3 100644 --- a/types/rest/rest_test.go +++ b/types/rest/rest_test.go @@ -12,12 +12,12 @@ import ( "testing" "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/secp256k1" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/types" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" ) type mockResponseWriter struct{} @@ -145,6 +145,17 @@ func TestParseQueryHeight(t *testing.T) { } func TestProcessPostResponse(t *testing.T) { + // mock account + // PubKey field ensures amino encoding is used first since standard + // JSON encoding will panic on crypto.PubKey + type mockAccount struct { + Address types.AccAddress `json:"address"` + Coins types.Coins `json:"coins"` + PubKey crypto.PubKey `json:"public_key"` + AccountNumber uint64 `json:"account_number"` + Sequence uint64 `json:"sequence"` + } + // setup ctx := context.NewCLIContext() height := int64(194423) @@ -156,9 +167,10 @@ func TestProcessPostResponse(t *testing.T) { accNumber := uint64(104) sequence := uint64(32) - acc := authtypes.NewBaseAccount(addr, coins, pubKey, accNumber, sequence) + acc := mockAccount{addr, coins, pubKey, accNumber, sequence} cdc := codec.New() - authtypes.RegisterBaseAccount(cdc) + codec.RegisterCrypto(cdc) + cdc.RegisterConcrete(&mockAccount{}, "cosmos-sdk/mockAccount", nil) ctx = ctx.WithCodec(cdc) // setup expected json responses with zero height