From 6a9f7a5b614f5fd6bf04de55a6b280b5f7aaef57 Mon Sep 17 00:00:00 2001 From: Aleksandr Bezobchuk Date: Tue, 10 Mar 2020 11:02:34 -0400 Subject: [PATCH 1/7] Prep changelog --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 63826dcd00c7..2aecd8fbe178 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,8 @@ Ref: https://keepachangelog.com/en/1.0.0/ ## [Unreleased] +## [v0.37.78] - TBD + ## [v0.37.7] - 2020-02-10 ### Improvements @@ -2619,7 +2621,8 @@ BUG FIXES: -[Unreleased]: https://github.com/cosmos/cosmos-sdk/compare/v0.37.7...HEAD +[Unreleased]: https://github.com/cosmos/cosmos-sdk/compare/v0.37.8...HEAD +[v0.37.8]: https://github.com/cosmos/cosmos-sdk/releases/tag/v0.37.8 [v0.37.7]: https://github.com/cosmos/cosmos-sdk/releases/tag/v0.37.7 [v0.37.6]: https://github.com/cosmos/cosmos-sdk/releases/tag/v0.37.6 [v0.37.5]: https://github.com/cosmos/cosmos-sdk/releases/tag/v0.37.5 From 9c64b02e2069a3da785663c5566f58d02b6378de Mon Sep 17 00:00:00 2001 From: Alexander Bezobchuk Date: Thu, 9 Jan 2020 15:14:23 -0500 Subject: [PATCH 2/7] Merge PR #5499: Cleanup genesis state validation + Genutil --- CHANGELOG.md | 4 ++++ x/auth/module.go | 7 ++++--- x/bank/module.go | 8 ++++---- x/crisis/module.go | 4 +++- x/distribution/module.go | 8 ++++---- x/genutil/client/cli/validate_genesis.go | 2 +- x/genutil/genesis.go | 7 +++++-- x/genutil/module.go | 10 +++++----- x/genutil/types/genesis_state.go | 7 +++++++ x/gov/module.go | 12 ++++++------ x/mint/module.go | 8 ++++---- x/slashing/module.go | 8 ++++---- x/staking/module.go | 8 ++++---- x/supply/module.go | 8 ++++---- 14 files changed, 59 insertions(+), 42 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2aecd8fbe178..875c7a7dea49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,10 @@ Ref: https://keepachangelog.com/en/1.0.0/ ## [v0.37.78] - TBD +### Bug Fixes + +* (x/genutil) [\#5499](https://github.com/cosmos/cosmos-sdk/pull/) Ensure `DefaultGenesis` returns valid and non-nil default genesis state. + ## [v0.37.7] - 2020-02-10 ### Improvements diff --git a/x/auth/module.go b/x/auth/module.go index ef978e020082..138907ace0fc 100644 --- a/x/auth/module.go +++ b/x/auth/module.go @@ -2,6 +2,7 @@ package auth import ( "encoding/json" + "fmt" "github.com/gorilla/mux" "github.com/spf13/cobra" @@ -42,10 +43,10 @@ func (AppModuleBasic) DefaultGenesis() json.RawMessage { // module validate genesis func (AppModuleBasic) ValidateGenesis(bz json.RawMessage) error { var data types.GenesisState - err := types.ModuleCdc.UnmarshalJSON(bz, &data) - if err != nil { - return err + if err := types.ModuleCdc.UnmarshalJSON(bz, &data); err != nil { + return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) } + return types.ValidateGenesis(data) } diff --git a/x/bank/module.go b/x/bank/module.go index bd0a8d54dbc6..fd79eb2f8d13 100644 --- a/x/bank/module.go +++ b/x/bank/module.go @@ -2,10 +2,10 @@ package bank import ( "encoding/json" + "fmt" "github.com/gorilla/mux" "github.com/spf13/cobra" - abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/client/context" @@ -40,10 +40,10 @@ func (AppModuleBasic) DefaultGenesis() json.RawMessage { // module validate genesis func (AppModuleBasic) ValidateGenesis(bz json.RawMessage) error { var data GenesisState - err := ModuleCdc.UnmarshalJSON(bz, &data) - if err != nil { - return err + if err := ModuleCdc.UnmarshalJSON(bz, &data); err != nil { + return fmt.Errorf("failed to unmarshal %s genesis state: %w", ModuleName, err) } + return ValidateGenesis(data) } diff --git a/x/crisis/module.go b/x/crisis/module.go index 456e5cc7b906..5a5ed1adedb1 100644 --- a/x/crisis/module.go +++ b/x/crisis/module.go @@ -2,6 +2,7 @@ package crisis import ( "encoding/json" + "fmt" "github.com/gorilla/mux" "github.com/spf13/cobra" @@ -45,8 +46,9 @@ func (AppModuleBasic) DefaultGenesis() json.RawMessage { func (AppModuleBasic) ValidateGenesis(bz json.RawMessage) error { var data types.GenesisState if err := types.ModuleCdc.UnmarshalJSON(bz, &data); err != nil { - return err + return fmt.Errorf("failed to unmarshal %s genesis state: %w", ModuleName, err) } + return types.ValidateGenesis(data) } diff --git a/x/distribution/module.go b/x/distribution/module.go index 6fe513ad613e..51ed72fffe0d 100644 --- a/x/distribution/module.go +++ b/x/distribution/module.go @@ -2,10 +2,10 @@ package distribution import ( "encoding/json" + "fmt" "github.com/gorilla/mux" "github.com/spf13/cobra" - abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/client/context" @@ -43,10 +43,10 @@ func (AppModuleBasic) DefaultGenesis() json.RawMessage { // module validate genesis func (AppModuleBasic) ValidateGenesis(bz json.RawMessage) error { var data GenesisState - err := ModuleCdc.UnmarshalJSON(bz, &data) - if err != nil { - return err + if err := ModuleCdc.UnmarshalJSON(bz, &data); err != nil { + return fmt.Errorf("failed to unmarshal %s genesis state: %w", ModuleName, err) } + return ValidateGenesis(data) } diff --git a/x/genutil/client/cli/validate_genesis.go b/x/genutil/client/cli/validate_genesis.go index f4baa5dc9df3..6be33bdabf09 100644 --- a/x/genutil/client/cli/validate_genesis.go +++ b/x/genutil/client/cli/validate_genesis.go @@ -38,7 +38,7 @@ func ValidateGenesisCmd(ctx *server.Context, cdc *codec.Codec, mbm module.BasicM var genState map[string]json.RawMessage if err = cdc.UnmarshalJSON(genDoc.AppState, &genState); err != nil { - return fmt.Errorf("error unmarshaling genesis doc %s: %s", genesis, err.Error()) + return fmt.Errorf("error unmarshalling genesis doc %s: %s", genesis, err.Error()) } if err = mbm.ValidateGenesis(genState); err != nil { diff --git a/x/genutil/genesis.go b/x/genutil/genesis.go index c1a06a8b9aff..c8564bdc4e2d 100644 --- a/x/genutil/genesis.go +++ b/x/genutil/genesis.go @@ -9,12 +9,15 @@ import ( ) // InitGenesis - initialize accounts and deliver genesis transactions -func InitGenesis(ctx sdk.Context, cdc *codec.Codec, stakingKeeper types.StakingKeeper, - deliverTx deliverTxfn, genesisState GenesisState) []abci.ValidatorUpdate { +func InitGenesis( + ctx sdk.Context, cdc *codec.Codec, stakingKeeper types.StakingKeeper, + deliverTx deliverTxfn, genesisState GenesisState, +) []abci.ValidatorUpdate { var validators []abci.ValidatorUpdate if len(genesisState.GenTxs) > 0 { validators = DeliverGenTxs(ctx, cdc, genesisState.GenTxs, stakingKeeper, deliverTx) } + return validators } diff --git a/x/genutil/module.go b/x/genutil/module.go index f6051fccb549..a9d679f83385 100644 --- a/x/genutil/module.go +++ b/x/genutil/module.go @@ -2,10 +2,10 @@ package genutil import ( "encoding/json" + "fmt" "github.com/gorilla/mux" "github.com/spf13/cobra" - abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/client/context" @@ -33,16 +33,16 @@ func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) {} // default genesis state func (AppModuleBasic) DefaultGenesis() json.RawMessage { - return ModuleCdc.MustMarshalJSON(GenesisState{}) + return ModuleCdc.MustMarshalJSON(types.DefaultGenesisState()) } // module validate genesis func (AppModuleBasic) ValidateGenesis(bz json.RawMessage) error { var data GenesisState - err := ModuleCdc.UnmarshalJSON(bz, &data) - if err != nil { - return err + if err := ModuleCdc.UnmarshalJSON(bz, &data); err != nil { + return fmt.Errorf("failed to unmarshal %s genesis state: %w", ModuleName, err) } + return ValidateGenesis(data) } diff --git a/x/genutil/types/genesis_state.go b/x/genutil/types/genesis_state.go index e568bb42076a..1303ee82ca4b 100644 --- a/x/genutil/types/genesis_state.go +++ b/x/genutil/types/genesis_state.go @@ -25,6 +25,13 @@ func NewGenesisState(genTxs []json.RawMessage) GenesisState { } } +// DefaultGenesisState returns the genutil module's default genesis state. +func DefaultGenesisState() GenesisState { + return GenesisState{ + GenTxs: []json.RawMessage{}, + } +} + // NewGenesisStateFromStdTx creates a new GenesisState object // from auth transactions func NewGenesisStateFromStdTx(genTxs []authtypes.StdTx) GenesisState { diff --git a/x/gov/module.go b/x/gov/module.go index bd50770dc2d9..12ca1290e3a3 100644 --- a/x/gov/module.go +++ b/x/gov/module.go @@ -2,10 +2,10 @@ package gov import ( "encoding/json" + "fmt" "github.com/gorilla/mux" "github.com/spf13/cobra" - abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/client/context" @@ -39,7 +39,7 @@ var _ module.AppModuleBasic = AppModuleBasic{} // module name func (AppModuleBasic) Name() string { - return types.ModuleName + return ModuleName } // register module codec @@ -49,16 +49,16 @@ func (AppModuleBasic) RegisterCodec(cdc *codec.Codec) { // default genesis state func (AppModuleBasic) DefaultGenesis() json.RawMessage { - return types.ModuleCdc.MustMarshalJSON(DefaultGenesisState()) + return ModuleCdc.MustMarshalJSON(DefaultGenesisState()) } // module validate genesis func (AppModuleBasic) ValidateGenesis(bz json.RawMessage) error { var data GenesisState - err := types.ModuleCdc.UnmarshalJSON(bz, &data) - if err != nil { - return err + if err := ModuleCdc.UnmarshalJSON(bz, &data); err != nil { + return fmt.Errorf("failed to unmarshal %s genesis state: %w", ModuleName, err) } + return ValidateGenesis(data) } diff --git a/x/mint/module.go b/x/mint/module.go index e8e07d94efd8..f56b5415f961 100644 --- a/x/mint/module.go +++ b/x/mint/module.go @@ -2,10 +2,10 @@ package mint import ( "encoding/json" + "fmt" "github.com/gorilla/mux" "github.com/spf13/cobra" - abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/client/context" @@ -42,10 +42,10 @@ func (AppModuleBasic) DefaultGenesis() json.RawMessage { // module validate genesis func (AppModuleBasic) ValidateGenesis(bz json.RawMessage) error { var data GenesisState - err := ModuleCdc.UnmarshalJSON(bz, &data) - if err != nil { - return err + if err := ModuleCdc.UnmarshalJSON(bz, &data); err != nil { + return fmt.Errorf("failed to unmarshal %s genesis state: %w", ModuleName, err) } + return ValidateGenesis(data) } diff --git a/x/slashing/module.go b/x/slashing/module.go index 3538f96d6502..5aa922be1bd2 100644 --- a/x/slashing/module.go +++ b/x/slashing/module.go @@ -2,10 +2,10 @@ package slashing import ( "encoding/json" + "fmt" "github.com/gorilla/mux" "github.com/spf13/cobra" - abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/client/context" @@ -45,10 +45,10 @@ func (AppModuleBasic) DefaultGenesis() json.RawMessage { // module validate genesis func (AppModuleBasic) ValidateGenesis(bz json.RawMessage) error { var data GenesisState - err := ModuleCdc.UnmarshalJSON(bz, &data) - if err != nil { - return err + if err := ModuleCdc.UnmarshalJSON(bz, &data); err != nil { + return fmt.Errorf("failed to unmarshal %s genesis state: %w", types.ModuleName, err) } + return ValidateGenesis(data) } diff --git a/x/staking/module.go b/x/staking/module.go index 8dcb26c66ec6..e8b35efd4446 100644 --- a/x/staking/module.go +++ b/x/staking/module.go @@ -2,11 +2,11 @@ package staking import ( "encoding/json" + "fmt" "github.com/gorilla/mux" "github.com/spf13/cobra" flag "github.com/spf13/pflag" - abci "github.com/tendermint/tendermint/abci/types" cfg "github.com/tendermint/tendermint/config" "github.com/tendermint/tendermint/crypto" @@ -49,10 +49,10 @@ func (AppModuleBasic) DefaultGenesis() json.RawMessage { // module validate genesis func (AppModuleBasic) ValidateGenesis(bz json.RawMessage) error { var data GenesisState - err := ModuleCdc.UnmarshalJSON(bz, &data) - if err != nil { - return err + if err := ModuleCdc.UnmarshalJSON(bz, &data); err != nil { + return fmt.Errorf("failed to unmarshal %s genesis state: %w", ModuleName, err) } + return ValidateGenesis(data) } diff --git a/x/supply/module.go b/x/supply/module.go index 3a987e2fa14d..2f55536c55dd 100644 --- a/x/supply/module.go +++ b/x/supply/module.go @@ -2,10 +2,10 @@ package supply import ( "encoding/json" + "fmt" "github.com/gorilla/mux" "github.com/spf13/cobra" - abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/client/context" @@ -43,10 +43,10 @@ func (AppModuleBasic) DefaultGenesis() json.RawMessage { // module validate genesis func (AppModuleBasic) ValidateGenesis(bz json.RawMessage) error { var data GenesisState - err := ModuleCdc.UnmarshalJSON(bz, &data) - if err != nil { - return err + if err := ModuleCdc.UnmarshalJSON(bz, &data); err != nil { + return fmt.Errorf("failed to unmarshal %s genesis state: %w", ModuleName, err) } + return ValidateGenesis(data) } From 9da1fb5233cc246135ee870796b08efd27b3acec Mon Sep 17 00:00:00 2001 From: Chad Barraford Date: Mon, 10 Feb 2020 15:32:17 -0500 Subject: [PATCH 3/7] Merge PR #5497: ensure non-nil gentxs --- CHANGELOG.md | 1 + x/genutil/types/genesis_state.go | 4 ++++ x/genutil/types/genesis_state_test.go | 14 ++++++++++++++ 3 files changed, 19 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 875c7a7dea49..aa2141fae317 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Bug Fixes * (x/genutil) [\#5499](https://github.com/cosmos/cosmos-sdk/pull/) Ensure `DefaultGenesis` returns valid and non-nil default genesis state. +* (genesis) [\#5086](https://github.com/cosmos/cosmos-sdk/issues/5086) Ensure `gentxs` are always an empty array instead of `nil`. ## [v0.37.7] - 2020-02-10 diff --git a/x/genutil/types/genesis_state.go b/x/genutil/types/genesis_state.go index 1303ee82ca4b..a1c0f11b07eb 100644 --- a/x/genutil/types/genesis_state.go +++ b/x/genutil/types/genesis_state.go @@ -20,6 +20,10 @@ type GenesisState struct { // NewGenesisState creates a new GenesisState object func NewGenesisState(genTxs []json.RawMessage) GenesisState { + // Ensure genTxs is never nil, https://github.com/cosmos/cosmos-sdk/issues/5086 + if len(genTxs) == 0 { + genTxs = make([]json.RawMessage, 0) + } return GenesisState{ GenTxs: genTxs, } diff --git a/x/genutil/types/genesis_state_test.go b/x/genutil/types/genesis_state_test.go index 2c340a35e905..f6a9eee51ce1 100644 --- a/x/genutil/types/genesis_state_test.go +++ b/x/genutil/types/genesis_state_test.go @@ -1,8 +1,10 @@ package types import ( + "encoding/json" "testing" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto/ed25519" @@ -16,6 +18,18 @@ var ( pk2 = ed25519.GenPrivKey().PubKey() ) +func TestNetGenesisState(t *testing.T) { + gen := NewGenesisState(nil) + assert.NotNil(t, gen.GenTxs) // https://github.com/cosmos/cosmos-sdk/issues/5086 + + gen = NewGenesisState( + []json.RawMessage{ + []byte(`{"foo":"bar"}`), + }, + ) + assert.Equal(t, string(gen.GenTxs[0]), `{"foo":"bar"}`) +} + func TestValidateGenesisMultipleMessages(t *testing.T) { desc := stakingtypes.NewDescription("testname", "", "", "") From 88e10b3014f06a92fead4e383efe4e86a5ecccdb Mon Sep 17 00:00:00 2001 From: Alexander Bezobchuk Date: Tue, 10 Mar 2020 10:40:58 -0400 Subject: [PATCH 4/7] Merge PR #5775: Fix x/genutil ExportGenesis --- CHANGELOG.md | 1 + x/genutil/module.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa2141fae317..4752f56b72e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Bug Fixes * (x/genutil) [\#5499](https://github.com/cosmos/cosmos-sdk/pull/) Ensure `DefaultGenesis` returns valid and non-nil default genesis state. +* (x/genutil) [\#5775](https://github.com/cosmos/cosmos-sdk/pull/5775) Fix `ExportGenesis` in `x/genutil` to export default genesis state (`[]`) instead of `null`. * (genesis) [\#5086](https://github.com/cosmos/cosmos-sdk/issues/5086) Ensure `gentxs` are always an empty array instead of `nil`. ## [v0.37.7] - 2020-02-10 diff --git a/x/genutil/module.go b/x/genutil/module.go index a9d679f83385..95a8bc97efc5 100644 --- a/x/genutil/module.go +++ b/x/genutil/module.go @@ -85,5 +85,5 @@ func (am AppModule) InitGenesis(ctx sdk.Context, data json.RawMessage) []abci.Va // module export genesis func (am AppModule) ExportGenesis(ctx sdk.Context) json.RawMessage { - return nil + return am.DefaultGenesis() } From 9e1f37c8d6144225987d7d0565d2f4969f25fb12 Mon Sep 17 00:00:00 2001 From: Gerry Agbobada <10496163+gagbo@users.noreply.github.com> Date: Mon, 17 Feb 2020 10:17:34 +0100 Subject: [PATCH 5/7] Merge PR #5648: Add min-height and max-height filters to TxSearch --- CHANGELOG.md | 6 ++++++ client/lcd/swagger-ui/swagger.yaml | 10 ++++++++++ types/rest/rest.go | 6 ++++++ types/rest/rest_test.go | 3 +++ 4 files changed, 25 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4752f56b72e5..3ab6e2adef49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,12 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (x/genutil) [\#5775](https://github.com/cosmos/cosmos-sdk/pull/5775) Fix `ExportGenesis` in `x/genutil` to export default genesis state (`[]`) instead of `null`. * (genesis) [\#5086](https://github.com/cosmos/cosmos-sdk/issues/5086) Ensure `gentxs` are always an empty array instead of `nil`. +### Improvements + +* (rest) [\#5648](https://github.com/cosmos/cosmos-sdk/pull/5648) Enhance /txs usability: + * Add `tx.minheight` key to filter transaction with an inclusive minimum block height + * Add `tx.maxheight` key to filter transaction with an inclusive maximum block height + ## [v0.37.7] - 2020-02-10 ### Improvements diff --git a/client/lcd/swagger-ui/swagger.yaml b/client/lcd/swagger-ui/swagger.yaml index 6d9ebe6db48e..236cf27eecbc 100644 --- a/client/lcd/swagger-ui/swagger.yaml +++ b/client/lcd/swagger-ui/swagger.yaml @@ -268,6 +268,16 @@ paths: description: Maximum number of items per page type: integer x-example: 1 + - in: query + name: tx.minheight + type: integer + description: "transactions on blocks with height greater or equal this value" + x-example: 25 + - in: query + name: tx.maxheight + type: integer + description: "transactions on blocks with height less than or equal this value" + x-example: 800000 responses: 200: description: All txs matching the provided events diff --git a/types/rest/rest.go b/types/rest/rest.go index bcaaba62dbe6..146faaede130 100644 --- a/types/rest/rest.go +++ b/types/rest/rest.go @@ -22,6 +22,8 @@ import ( const ( DefaultPage = 1 DefaultLimit = 30 // should be consistent with tendermint/tendermint/rpc/core/pipe.go:19 + TxMinHeightKey = "tx.minheight" // Inclusive minimum height filter + TxMaxHeightKey = "tx.maxheight" // Inclusive maximum height filter ) // ResponseWithHeight defines a response object type that wraps an original @@ -337,6 +339,10 @@ func ParseHTTPArgsWithLimit(r *http.Request, defaultLimit int) (tags []string, p var tag string if key == types.TxHeightKey { tag = fmt.Sprintf("%s=%s", key, value) + } else if key == TxMinHeightKey { + tag = fmt.Sprintf("%s>=%s", types.TxHeightKey, value) + } else if key == TxMaxHeightKey { + tag = fmt.Sprintf("%s<=%s", types.TxHeightKey, value) } else { tag = fmt.Sprintf("%s='%s'", key, value) } diff --git a/types/rest/rest_test.go b/types/rest/rest_test.go index dd9d800b1a6d..bb2ddb484d4f 100644 --- a/types/rest/rest_test.go +++ b/types/rest/rest_test.go @@ -72,6 +72,8 @@ func TestParseHTTPArgs(t *testing.T) { reqE2 := mustNewRequest(t, "", "/?limit=-1", nil) req4 := mustNewRequest(t, "", "/?foo=faa", nil) + reqTxH := mustNewRequest(t, "", "/?tx.minheight=12&tx.maxheight=14", nil) + tests := []struct { name string req *http.Request @@ -90,6 +92,7 @@ func TestParseHTTPArgs(t *testing.T) { {"error limit 0", reqE2, httptest.NewRecorder(), []string{}, DefaultPage, DefaultLimit, true}, {"tags", req4, httptest.NewRecorder(), []string{"foo='faa'"}, DefaultPage, DefaultLimit, false}, + {"tags", reqTxH, httptest.NewRecorder(), []string{"tx.height>=12", "tx.height<=14"}, DefaultPage, DefaultLimit, false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { From 779f19ccffe07fe4866e6a0685c9a4f41b15f553 Mon Sep 17 00:00:00 2001 From: Alexander Bezobchuk Date: Mon, 17 Feb 2020 14:46:48 +0100 Subject: [PATCH 6/7] Merge PR #5655: Fix TestParseHTTPArgs --- types/rest/rest_test.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/types/rest/rest_test.go b/types/rest/rest_test.go index bb2ddb484d4f..29d24af27dac 100644 --- a/types/rest/rest_test.go +++ b/types/rest/rest_test.go @@ -7,6 +7,7 @@ import ( "io/ioutil" "net/http" "net/http/httptest" + "sort" "testing" "github.com/stretchr/testify/require" @@ -92,11 +93,14 @@ func TestParseHTTPArgs(t *testing.T) { {"error limit 0", reqE2, httptest.NewRecorder(), []string{}, DefaultPage, DefaultLimit, true}, {"tags", req4, httptest.NewRecorder(), []string{"foo='faa'"}, DefaultPage, DefaultLimit, false}, - {"tags", reqTxH, httptest.NewRecorder(), []string{"tx.height>=12", "tx.height<=14"}, DefaultPage, DefaultLimit, false}, + {"tags", reqTxH, httptest.NewRecorder(), []string{"tx.height<=14", "tx.height>=12"}, DefaultPage, DefaultLimit, false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { tags, page, limit, err := ParseHTTPArgs(tt.req) + + sort.Strings(tags) + if tt.err { require.NotNil(t, err) } else { From 0e8143204614019b1f41a6af4f6959c2dfe0d849 Mon Sep 17 00:00:00 2001 From: Alexander Bezobchuk Date: Fri, 10 Jan 2020 16:10:37 -0500 Subject: [PATCH 7/7] Merge PR #5508: Fix and Return Height in x/distribution REST Handlers --- CHANGELOG.md | 1 + x/distribution/client/cli/query.go | 28 +++++-- x/distribution/client/common/common.go | 32 +++----- x/distribution/client/common/common_test.go | 2 +- x/distribution/client/rest/query.go | 82 ++++++++++++--------- 5 files changed, 85 insertions(+), 60 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ab6e2adef49..98b76f80898d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Bug Fixes +* (rest) [\#5508](https://github.com/cosmos/cosmos-sdk/pull/5508) Fix `x/distribution` endpoints to properly return height in the response. * (x/genutil) [\#5499](https://github.com/cosmos/cosmos-sdk/pull/) Ensure `DefaultGenesis` returns valid and non-nil default genesis state. * (x/genutil) [\#5775](https://github.com/cosmos/cosmos-sdk/pull/5775) Fix `ExportGenesis` in `x/genutil` to export default genesis state (`[]`) instead of `null`. * (genesis) [\#5086](https://github.com/cosmos/cosmos-sdk/issues/5086) Ensure `gentxs` are always an empty array instead of `nil`. diff --git a/x/distribution/client/cli/query.go b/x/distribution/client/cli/query.go index 36d12e57fb1d..f3f4d324a5fc 100644 --- a/x/distribution/client/cli/query.go +++ b/x/distribution/client/cli/query.go @@ -208,26 +208,44 @@ $ %s query distr rewards cosmos1gghjut3ccd8ay0zduzj64hwre2fxs9ld75ru9p cosmosval RunE: func(cmd *cobra.Command, args []string) error { cliCtx := context.NewCLIContext().WithCodec(cdc) + // query for rewards from a particular delegation if len(args) == 2 { - // query for rewards from a particular delegation - resp, err := common.QueryDelegationRewards(cliCtx, queryRoute, args[0], args[1]) + resp, _, err := common.QueryDelegationRewards(cliCtx, queryRoute, args[0], args[1]) if err != nil { return err } var result sdk.DecCoins - cdc.MustUnmarshalJSON(resp, &result) + if err = cdc.UnmarshalJSON(resp, &result); err != nil { + return fmt.Errorf("failed to unmarshal response: %w", err) + } + return cliCtx.PrintOutput(result) } + delegatorAddr, err := sdk.AccAddressFromBech32(args[0]) + if err != nil { + return err + } + + params := types.NewQueryDelegatorParams(delegatorAddr) + bz, err := cdc.MarshalJSON(params) + if err != nil { + return fmt.Errorf("failed to marshal params: %w", err) + } + // query for delegator total rewards - resp, err := common.QueryDelegatorTotalRewards(cliCtx, queryRoute, args[0]) + route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryDelegatorTotalRewards) + res, _, err := cliCtx.QueryWithData(route, bz) if err != nil { return err } var result types.QueryDelegatorTotalRewardsResponse - cdc.MustUnmarshalJSON(resp, &result) + if err = cdc.UnmarshalJSON(res, &result); err != nil { + return fmt.Errorf("failed to unmarshal response: %w", err) + } + return cliCtx.PrintOutput(result) }, } diff --git a/x/distribution/client/common/common.go b/x/distribution/client/common/common.go index 077933f0375c..3bd95cb70a38 100644 --- a/x/distribution/client/common/common.go +++ b/x/distribution/client/common/common.go @@ -40,37 +40,27 @@ func QueryParams(cliCtx context.CLIContext, queryRoute string) (PrettyParams, er ), nil } -// QueryDelegatorTotalRewards queries delegator total rewards. -func QueryDelegatorTotalRewards(cliCtx context.CLIContext, queryRoute, delAddr string) ([]byte, error) { +// QueryDelegationRewards queries a delegation rewards between a delegator and a +// validator. +func QueryDelegationRewards(cliCtx context.CLIContext, queryRoute, delAddr, valAddr string) ([]byte, int64, error) { delegatorAddr, err := sdk.AccAddressFromBech32(delAddr) if err != nil { - return nil, err + return nil, 0, err } - res, _, err := cliCtx.QueryWithData( - fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryDelegatorTotalRewards), - cliCtx.Codec.MustMarshalJSON(types.NewQueryDelegatorParams(delegatorAddr)), - ) - return res, err -} - -// QueryDelegationRewards queries a delegation rewards. -func QueryDelegationRewards(cliCtx context.CLIContext, queryRoute, delAddr, valAddr string) ([]byte, error) { - delegatorAddr, err := sdk.AccAddressFromBech32(delAddr) + validatorAddr, err := sdk.ValAddressFromBech32(valAddr) if err != nil { - return nil, err + return nil, 0, err } - validatorAddr, err := sdk.ValAddressFromBech32(valAddr) + params := types.NewQueryDelegationRewardsParams(delegatorAddr, validatorAddr) + bz, err := cliCtx.Codec.MarshalJSON(params) if err != nil { - return nil, err + return nil, 0, fmt.Errorf("failed to marshal params: %w", err) } - res, _, err := cliCtx.QueryWithData( - fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryDelegationRewards), - cliCtx.Codec.MustMarshalJSON(types.NewQueryDelegationRewardsParams(delegatorAddr, validatorAddr)), - ) - return res, err + route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryDelegationRewards) + return cliCtx.QueryWithData(route, bz) } // QueryDelegatorValidators returns delegator's list of validators diff --git a/x/distribution/client/common/common_test.go b/x/distribution/client/common/common_test.go index 1e21861112d2..d10ff87c88dc 100644 --- a/x/distribution/client/common/common_test.go +++ b/x/distribution/client/common/common_test.go @@ -29,7 +29,7 @@ func TestQueryDelegationRewardsAddrValidation(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - _, err := QueryDelegationRewards(ctx, "", tt.args.delAddr, tt.args.valAddr) + _, _, err := QueryDelegationRewards(ctx, "", tt.args.delAddr, tt.args.valAddr) require.True(t, err != nil, tt.wantErr) }) } diff --git a/x/distribution/client/rest/query.go b/x/distribution/client/rest/query.go index 15b5c7fe07c7..266aa3c222c1 100644 --- a/x/distribution/client/rest/query.go +++ b/x/distribution/client/rest/query.go @@ -73,12 +73,26 @@ func delegatorRewardsHandlerFn(cliCtx context.CLIContext, queryRoute string) htt return } - // query for rewards from a particular delegator - res, ok := checkResponseQueryDelegatorTotalRewards(w, cliCtx, queryRoute, mux.Vars(r)["delegatorAddr"]) + delegatorAddr, ok := checkDelegatorAddressVar(w, r) if !ok { return } + params := types.NewQueryDelegatorParams(delegatorAddr) + bz, err := cliCtx.Codec.MarshalJSON(params) + if err != nil { + rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("failed to marshal params: %s", err)) + return + } + + route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryDelegatorTotalRewards) + res, height, err := cliCtx.QueryWithData(route, bz) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + cliCtx = cliCtx.WithHeight(height) rest.PostProcessResponse(w, cliCtx, res) } } @@ -91,12 +105,16 @@ func delegationRewardsHandlerFn(cliCtx context.CLIContext, queryRoute string) ht return } + delAddr := mux.Vars(r)["delegatorAddr"] + valAddr := mux.Vars(r)["validatorAddr"] + // query for rewards from a particular delegation - res, ok := checkResponseQueryDelegationRewards(w, cliCtx, queryRoute, mux.Vars(r)["delegatorAddr"], mux.Vars(r)["validatorAddr"]) + res, height, ok := checkResponseQueryDelegationRewards(w, cliCtx, queryRoute, delAddr, valAddr) if !ok { return } + cliCtx = cliCtx.WithHeight(height) rest.PostProcessResponse(w, cliCtx, res) } } @@ -147,8 +165,7 @@ func NewValidatorDistInfo(operatorAddr sdk.AccAddress, rewards sdk.DecCoins, // HTTP request handler to query validator's distribution information func validatorInfoHandlerFn(cliCtx context.CLIContext, queryRoute string) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - valAddr := mux.Vars(r)["validatorAddr"] - validatorAddr, ok := checkValidatorAddressVar(w, r) + valAddr, ok := checkValidatorAddressVar(w, r) if !ok { return } @@ -159,28 +176,39 @@ func validatorInfoHandlerFn(cliCtx context.CLIContext, queryRoute string) http.H } // query commission - commissionRes, err := common.QueryValidatorCommission(cliCtx, queryRoute, validatorAddr) + bz, err := common.QueryValidatorCommission(cliCtx, queryRoute, valAddr) if err != nil { rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) return } - var valCom types.ValidatorAccumulatedCommission - cliCtx.Codec.MustUnmarshalJSON(commissionRes, &valCom) + var commission types.ValidatorAccumulatedCommission + if err := cliCtx.Codec.UnmarshalJSON(bz, &commission); err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } // self bond rewards - delAddr := sdk.AccAddress(validatorAddr) - rewardsRes, ok := checkResponseQueryDelegationRewards(w, cliCtx, queryRoute, delAddr.String(), valAddr) + delAddr := sdk.AccAddress(valAddr) + bz, height, ok := checkResponseQueryDelegationRewards(w, cliCtx, queryRoute, delAddr.String(), valAddr.String()) if !ok { return } var rewards sdk.DecCoins - cliCtx.Codec.MustUnmarshalJSON(rewardsRes, &rewards) + if err := cliCtx.Codec.UnmarshalJSON(bz, &rewards); err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } - // Prepare response - res := cliCtx.Codec.MustMarshalJSON(NewValidatorDistInfo(delAddr, rewards, valCom)) - rest.PostProcessResponse(w, cliCtx, res) + bz, err = cliCtx.Codec.MarshalJSON(NewValidatorDistInfo(delAddr, rewards, commission)) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + cliCtx = cliCtx.WithHeight(height) + rest.PostProcessResponse(w, cliCtx, bz) } } @@ -199,12 +227,13 @@ func validatorRewardsHandlerFn(cliCtx context.CLIContext, queryRoute string) htt } delAddr := sdk.AccAddress(validatorAddr).String() - res, ok := checkResponseQueryDelegationRewards(w, cliCtx, queryRoute, delAddr, valAddr) + bz, height, ok := checkResponseQueryDelegationRewards(w, cliCtx, queryRoute, delAddr, valAddr) if !ok { return } - rest.PostProcessResponse(w, cliCtx, res) + cliCtx = cliCtx.WithHeight(height) + rest.PostProcessResponse(w, cliCtx, bz) } } @@ -275,28 +304,15 @@ func outstandingRewardsHandlerFn(cliCtx context.CLIContext, queryRoute string) h } } -func checkResponseQueryDelegatorTotalRewards( - w http.ResponseWriter, cliCtx context.CLIContext, queryRoute, delAddr string, -) (res []byte, ok bool) { - - res, err := common.QueryDelegatorTotalRewards(cliCtx, queryRoute, delAddr) - if err != nil { - rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return nil, false - } - - return res, true -} - func checkResponseQueryDelegationRewards( w http.ResponseWriter, cliCtx context.CLIContext, queryRoute, delAddr, valAddr string, -) (res []byte, ok bool) { +) (res []byte, height int64, ok bool) { - res, err := common.QueryDelegationRewards(cliCtx, queryRoute, delAddr, valAddr) + res, height, err := common.QueryDelegationRewards(cliCtx, queryRoute, delAddr, valAddr) if err != nil { rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) - return nil, false + return nil, 0, false } - return res, true + return res, height, true }