diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e9979d326..1c3a38ae1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,8 +41,8 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (modules) [\#5572](https://github.com/cosmos/cosmos-sdk/pull/5572) The `/bank/balances/{address}` endpoint now returns all account balances or a single balance by denom when the `denom` query parameter is present. -* (client) [\#5640](https://github.com/cosmos/cosmos-sdk/pull/5640) The rest server endpoint `/swagger-ui/` is replaced by -´/´. +* (client) [\#5640](https://github.com/cosmos/cosmos-sdk/pull/5640) The rest server endpoint `/swagger-ui/` is replaced by ´/´. +* (x/auth) [\#5702](https://github.com/cosmos/cosmos-sdk/pull/5702) The `x/auth` querier route has changed from `"acc"` to `"auth"`. ### API Breaking Changes @@ -133,6 +133,7 @@ Buffers for state serialization instead of Amino. ### Improvements +* (x/auth) [\#5702](https://github.com/cosmos/cosmos-sdk/pull/5702) Add parameter querying support for `x/auth`. * (types) [\#5581](https://github.com/cosmos/cosmos-sdk/pull/5581) Add convenience functions {,Must}Bech32ifyAddressBytes. * (staking) [\#5584](https://github.com/cosmos/cosmos-sdk/pull/5584) Add util function `ToTmValidator` that converts a `staking.Validator` type to `*tmtypes.Validator`. * (client) [\#5585](https://github.com/cosmos/cosmos-sdk/pull/5585) IBC additions: diff --git a/simapp/codec/msgs.go b/simapp/codec/msgs.go index d6390261be..2ea6c3a3a7 100644 --- a/simapp/codec/msgs.go +++ b/simapp/codec/msgs.go @@ -10,11 +10,13 @@ import ( var _ eviexported.MsgSubmitEvidence = MsgSubmitEvidence{} // NewMsgSubmitEvidence returns a new MsgSubmitEvidence. -func NewMsgSubmitEvidence(evidenceI eviexported.Evidence, s sdk.AccAddress) MsgSubmitEvidence { +func NewMsgSubmitEvidence(evidenceI eviexported.Evidence, s sdk.AccAddress) (MsgSubmitEvidence, error) { e := &Evidence{} - e.SetEvidence(evidenceI) + if err := e.SetEvidence(evidenceI); err != nil { + return MsgSubmitEvidence{}, err + } - return MsgSubmitEvidence{Evidence: e, MsgSubmitEvidenceBase: evidence.NewMsgSubmitEvidenceBase(s)} + return MsgSubmitEvidence{Evidence: e, MsgSubmitEvidenceBase: evidence.NewMsgSubmitEvidenceBase(s)}, nil } // ValidateBasic performs basic (non-state-dependant) validation on a diff --git a/x/auth/alias.go b/x/auth/alias.go index b5d5516352..6c242caf51 100644 --- a/x/auth/alias.go +++ b/x/auth/alias.go @@ -21,6 +21,7 @@ const ( DefaultSigVerifyCostED25519 = types.DefaultSigVerifyCostED25519 DefaultSigVerifyCostSecp256k1 = types.DefaultSigVerifyCostSecp256k1 QueryAccount = types.QueryAccount + QueryParams = types.QueryParams ) var ( diff --git a/x/auth/client/cli/query.go b/x/auth/client/cli/query.go index ebb5f3f508..0ef0a46e91 100644 --- a/x/auth/client/cli/query.go +++ b/x/auth/client/cli/query.go @@ -36,11 +36,45 @@ func GetQueryCmd(cdc *codec.Codec) *cobra.Command { RunE: client.ValidateCmd, } - cmd.AddCommand(GetAccountCmd(cdc)) + cmd.AddCommand( + flags.GetCommands( + GetAccountCmd(cdc), + QueryParamsCmd(cdc), + )..., + ) return cmd } +// QueryParamsCmd returns the command handler for evidence parameter querying. +func QueryParamsCmd(cdc *codec.Codec) *cobra.Command { + return &cobra.Command{ + Use: "params", + Short: "Query the current auth parameters", + Args: cobra.NoArgs, + Long: strings.TrimSpace(`Query the current auth parameters: + +$ query auth params +`), + RunE: func(cmd *cobra.Command, args []string) error { + cliCtx := context.NewCLIContext().WithCodec(cdc) + + route := fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryParams) + res, _, err := cliCtx.QueryWithData(route, nil) + if err != nil { + return err + } + + var params types.Params + if err := cdc.UnmarshalJSON(res, ¶ms); err != nil { + return fmt.Errorf("failed to unmarshal params: %w", err) + } + + return cliCtx.PrintOutput(params) + }, + } +} + // GetAccountCmd returns a query account that will display the state of the // account at a given address. func GetAccountCmd(cdc *codec.Codec) *cobra.Command { diff --git a/x/auth/client/rest/query.go b/x/auth/client/rest/query.go index 6f245e40a2..8ff7f567d0 100644 --- a/x/auth/client/rest/query.go +++ b/x/auth/client/rest/query.go @@ -138,3 +138,22 @@ func QueryTxRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc { rest.PostProcessResponseBare(w, cliCtx, output) } } + +func queryParamsHandler(cliCtx context.CLIContext) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r) + if !ok { + return + } + + route := fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryParams) + res, height, err := cliCtx.QueryWithData(route, nil) + if err != nil { + rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error()) + return + } + + cliCtx = cliCtx.WithHeight(height) + rest.PostProcessResponse(w, cliCtx, res) + } +} diff --git a/x/auth/client/rest/rest.go b/x/auth/client/rest/rest.go index 98dc813412..e69388dc41 100644 --- a/x/auth/client/rest/rest.go +++ b/x/auth/client/rest/rest.go @@ -6,11 +6,21 @@ import ( "github.com/cosmos/cosmos-sdk/client/context" ) +// REST query and parameter values +const ( + MethodGet = "GET" +) + // RegisterRoutes registers the auth module REST routes. func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, storeName string) { r.HandleFunc( "/auth/accounts/{address}", QueryAccountRequestHandlerFn(storeName, cliCtx), - ).Methods("GET") + ).Methods(MethodGet) + + r.HandleFunc( + "/auth/params", + queryParamsHandler(cliCtx), + ).Methods(MethodGet) } // RegisterTxRoutes registers all transaction routes on the provided router. diff --git a/x/auth/keeper/querier.go b/x/auth/keeper/querier.go index 28e505970b..eab5d3afca 100644 --- a/x/auth/keeper/querier.go +++ b/x/auth/keeper/querier.go @@ -10,32 +10,47 @@ import ( ) // NewQuerier creates a querier for auth REST endpoints -func NewQuerier(keeper AccountKeeper) sdk.Querier { +func NewQuerier(k AccountKeeper) sdk.Querier { return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, error) { switch path[0] { case types.QueryAccount: - return queryAccount(ctx, req, keeper) + return queryAccount(ctx, req, k) + + case types.QueryParams: + return queryParams(ctx, k) + default: return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown query path: %s", path[0]) } } } -func queryAccount(ctx sdk.Context, req abci.RequestQuery, keeper AccountKeeper) ([]byte, error) { +func queryAccount(ctx sdk.Context, req abci.RequestQuery, k AccountKeeper) ([]byte, error) { var params types.QueryAccountParams - if err := keeper.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { + if err := k.cdc.UnmarshalJSON(req.Data, ¶ms); err != nil { return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) } - account := keeper.GetAccount(ctx, params.Address) + account := k.GetAccount(ctx, params.Address) if account == nil { return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "account %s does not exist", params.Address) } - bz, err := codec.MarshalJSONIndent(keeper.cdc, account) + bz, err := codec.MarshalJSONIndent(k.cdc, account) if err != nil { return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) } return bz, nil } + +func queryParams(ctx sdk.Context, k AccountKeeper) ([]byte, error) { + params := k.GetParams(ctx) + + res, err := codec.MarshalJSONIndent(k.cdc, params) + if err != nil { + return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) + } + + return res, nil +} diff --git a/x/auth/types/account_retriever_test.go b/x/auth/types/account_retriever_test.go index 0481e00b26..99310d1170 100644 --- a/x/auth/types/account_retriever_test.go +++ b/x/auth/types/account_retriever_test.go @@ -2,6 +2,7 @@ package types_test import ( "errors" + "fmt" "testing" "github.com/golang/mock/gomock" @@ -23,19 +24,21 @@ func TestAccountRetriever(t *testing.T) { bs, err := appCodec.MarshalJSON(types.NewQueryAccountParams(addr)) require.NoError(t, err) - mockNodeQuerier.EXPECT().QueryWithData(gomock.Eq("custom/acc/account"), + route := fmt.Sprintf("custom/%s/%s", types.QuerierRoute, types.QueryAccount) + + mockNodeQuerier.EXPECT().QueryWithData(gomock.Eq(route), gomock.Eq(bs)).Return(nil, int64(0), errFoo).Times(1) _, err = accRetr.GetAccount(addr) require.Error(t, err) - mockNodeQuerier.EXPECT().QueryWithData(gomock.Eq("custom/acc/account"), + mockNodeQuerier.EXPECT().QueryWithData(gomock.Eq(route), gomock.Eq(bs)).Return(nil, int64(0), errFoo).Times(1) n, s, err := accRetr.GetAccountNumberSequence(addr) require.Error(t, err) require.Equal(t, uint64(0), n) require.Equal(t, uint64(0), s) - mockNodeQuerier.EXPECT().QueryWithData(gomock.Eq("custom/acc/account"), + mockNodeQuerier.EXPECT().QueryWithData(gomock.Eq(route), gomock.Eq(bs)).Return(nil, int64(0), errFoo).Times(1) require.Error(t, accRetr.EnsureExists(addr)) } diff --git a/x/auth/types/keys.go b/x/auth/types/keys.go index 149fe2ba51..4cb2538f25 100644 --- a/x/auth/types/keys.go +++ b/x/auth/types/keys.go @@ -14,8 +14,8 @@ const ( // FeeCollectorName the root string for the fee collector account address FeeCollectorName = "fee_collector" - // QuerierRoute is the querier route for acc - QuerierRoute = StoreKey + // QuerierRoute is the querier route for auth + QuerierRoute = ModuleName ) var ( diff --git a/x/auth/types/querier.go b/x/auth/types/querier.go index 84a80b1411..35a7e0ccf3 100644 --- a/x/auth/types/querier.go +++ b/x/auth/types/querier.go @@ -7,6 +7,7 @@ import ( // query endpoints supported by the auth Querier const ( QueryAccount = "account" + QueryParams = "params" ) // QueryAccountParams defines the params for querying accounts. diff --git a/x/evidence/handler_test.go b/x/evidence/handler_test.go index 2d766e9d8f..60e883364a 100644 --- a/x/evidence/handler_test.go +++ b/x/evidence/handler_test.go @@ -5,6 +5,7 @@ import ( "testing" "time" + "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto/ed25519" @@ -24,6 +25,12 @@ type HandlerTestSuite struct { app *simapp.SimApp } +func testMsgSubmitEvidence(r *require.Assertions, e exported.Evidence, s sdk.AccAddress) simappcodec.MsgSubmitEvidence { + msg, err := simappcodec.NewMsgSubmitEvidence(e, s) + r.NoError(err) + return msg +} + func testEquivocationHandler(k interface{}) types.Handler { return func(ctx sdk.Context, e exported.Evidence) error { if err := e.ValidateBasic(); err != nil { @@ -70,7 +77,8 @@ func (suite *HandlerTestSuite) TestMsgSubmitEvidence() { expectErr bool }{ { - simappcodec.NewMsgSubmitEvidence( + testMsgSubmitEvidence( + suite.Require(), &types.Equivocation{ Height: 11, Time: time.Now().UTC(), @@ -82,7 +90,8 @@ func (suite *HandlerTestSuite) TestMsgSubmitEvidence() { false, }, { - simappcodec.NewMsgSubmitEvidence( + testMsgSubmitEvidence( + suite.Require(), &types.Equivocation{ Height: 10, Time: time.Now().UTC(), diff --git a/x/evidence/types/msgs_test.go b/x/evidence/types/msgs_test.go index 304f49efbf..127df25357 100644 --- a/x/evidence/types/msgs_test.go +++ b/x/evidence/types/msgs_test.go @@ -6,12 +6,19 @@ import ( simappcodec "github.com/cosmos/cosmos-sdk/simapp/codec" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/evidence/exported" "github.com/cosmos/cosmos-sdk/x/evidence/types" "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto/ed25519" ) +func testMsgSubmitEvidence(t *testing.T, e exported.Evidence, s sdk.AccAddress) simappcodec.MsgSubmitEvidence { + msg, err := simappcodec.NewMsgSubmitEvidence(e, s) + require.NoError(t, err) + return msg +} + func TestMsgSubmitEvidence(t *testing.T) { pk := ed25519.GenPrivKey() submitter := sdk.AccAddress("test") @@ -27,7 +34,7 @@ func TestMsgSubmitEvidence(t *testing.T) { false, }, { - simappcodec.NewMsgSubmitEvidence(&types.Equivocation{ + testMsgSubmitEvidence(t, &types.Equivocation{ Height: 0, Power: 100, Time: time.Now().UTC(), @@ -37,7 +44,7 @@ func TestMsgSubmitEvidence(t *testing.T) { true, }, { - simappcodec.NewMsgSubmitEvidence(&types.Equivocation{ + testMsgSubmitEvidence(t, &types.Equivocation{ Height: 10, Power: 100, Time: time.Now().UTC(),