Merge PR #5702: Add Param Querying to x/auth

This commit is contained in:
Alexander Bezobchuk 2020-02-26 10:33:56 -05:00 committed by GitHub
parent 201d1cdc34
commit 8cab43c812
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 124 additions and 22 deletions

View File

@ -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 * (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. 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 ### API Breaking Changes
@ -133,6 +133,7 @@ Buffers for state serialization instead of Amino.
### Improvements ### 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. * (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`. * (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: * (client) [\#5585](https://github.com/cosmos/cosmos-sdk/pull/5585) IBC additions:

View File

@ -10,11 +10,13 @@ import (
var _ eviexported.MsgSubmitEvidence = MsgSubmitEvidence{} var _ eviexported.MsgSubmitEvidence = MsgSubmitEvidence{}
// NewMsgSubmitEvidence returns a new 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 := &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 // ValidateBasic performs basic (non-state-dependant) validation on a

View File

@ -21,6 +21,7 @@ const (
DefaultSigVerifyCostED25519 = types.DefaultSigVerifyCostED25519 DefaultSigVerifyCostED25519 = types.DefaultSigVerifyCostED25519
DefaultSigVerifyCostSecp256k1 = types.DefaultSigVerifyCostSecp256k1 DefaultSigVerifyCostSecp256k1 = types.DefaultSigVerifyCostSecp256k1
QueryAccount = types.QueryAccount QueryAccount = types.QueryAccount
QueryParams = types.QueryParams
) )
var ( var (

View File

@ -36,11 +36,45 @@ func GetQueryCmd(cdc *codec.Codec) *cobra.Command {
RunE: client.ValidateCmd, RunE: client.ValidateCmd,
} }
cmd.AddCommand(GetAccountCmd(cdc)) cmd.AddCommand(
flags.GetCommands(
GetAccountCmd(cdc),
QueryParamsCmd(cdc),
)...,
)
return cmd 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:
$ <appcli> 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, &params); 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 // GetAccountCmd returns a query account that will display the state of the
// account at a given address. // account at a given address.
func GetAccountCmd(cdc *codec.Codec) *cobra.Command { func GetAccountCmd(cdc *codec.Codec) *cobra.Command {

View File

@ -138,3 +138,22 @@ func QueryTxRequestHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
rest.PostProcessResponseBare(w, cliCtx, output) 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)
}
}

View File

@ -6,11 +6,21 @@ import (
"github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/client/context"
) )
// REST query and parameter values
const (
MethodGet = "GET"
)
// RegisterRoutes registers the auth module REST routes. // RegisterRoutes registers the auth module REST routes.
func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, storeName string) { func RegisterRoutes(cliCtx context.CLIContext, r *mux.Router, storeName string) {
r.HandleFunc( r.HandleFunc(
"/auth/accounts/{address}", QueryAccountRequestHandlerFn(storeName, cliCtx), "/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. // RegisterTxRoutes registers all transaction routes on the provided router.

View File

@ -10,32 +10,47 @@ import (
) )
// NewQuerier creates a querier for auth REST endpoints // 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) { return func(ctx sdk.Context, path []string, req abci.RequestQuery) ([]byte, error) {
switch path[0] { switch path[0] {
case types.QueryAccount: case types.QueryAccount:
return queryAccount(ctx, req, keeper) return queryAccount(ctx, req, k)
case types.QueryParams:
return queryParams(ctx, k)
default: default:
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unknown query path: %s", path[0]) 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 var params types.QueryAccountParams
if err := keeper.cdc.UnmarshalJSON(req.Data, &params); err != nil { if err := k.cdc.UnmarshalJSON(req.Data, &params); err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error()) return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
} }
account := keeper.GetAccount(ctx, params.Address) account := k.GetAccount(ctx, params.Address)
if account == nil { if account == nil {
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownAddress, "account %s does not exist", params.Address) 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 { if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error()) return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
} }
return bz, nil 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
}

View File

@ -2,6 +2,7 @@ package types_test
import ( import (
"errors" "errors"
"fmt"
"testing" "testing"
"github.com/golang/mock/gomock" "github.com/golang/mock/gomock"
@ -23,19 +24,21 @@ func TestAccountRetriever(t *testing.T) {
bs, err := appCodec.MarshalJSON(types.NewQueryAccountParams(addr)) bs, err := appCodec.MarshalJSON(types.NewQueryAccountParams(addr))
require.NoError(t, err) 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) gomock.Eq(bs)).Return(nil, int64(0), errFoo).Times(1)
_, err = accRetr.GetAccount(addr) _, err = accRetr.GetAccount(addr)
require.Error(t, err) 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) gomock.Eq(bs)).Return(nil, int64(0), errFoo).Times(1)
n, s, err := accRetr.GetAccountNumberSequence(addr) n, s, err := accRetr.GetAccountNumberSequence(addr)
require.Error(t, err) require.Error(t, err)
require.Equal(t, uint64(0), n) require.Equal(t, uint64(0), n)
require.Equal(t, uint64(0), s) 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) gomock.Eq(bs)).Return(nil, int64(0), errFoo).Times(1)
require.Error(t, accRetr.EnsureExists(addr)) require.Error(t, accRetr.EnsureExists(addr))
} }

View File

@ -14,8 +14,8 @@ const (
// FeeCollectorName the root string for the fee collector account address // FeeCollectorName the root string for the fee collector account address
FeeCollectorName = "fee_collector" FeeCollectorName = "fee_collector"
// QuerierRoute is the querier route for acc // QuerierRoute is the querier route for auth
QuerierRoute = StoreKey QuerierRoute = ModuleName
) )
var ( var (

View File

@ -7,6 +7,7 @@ import (
// query endpoints supported by the auth Querier // query endpoints supported by the auth Querier
const ( const (
QueryAccount = "account" QueryAccount = "account"
QueryParams = "params"
) )
// QueryAccountParams defines the params for querying accounts. // QueryAccountParams defines the params for querying accounts.

View File

@ -5,6 +5,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
abci "github.com/tendermint/tendermint/abci/types" abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/crypto/ed25519"
@ -24,6 +25,12 @@ type HandlerTestSuite struct {
app *simapp.SimApp 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 { func testEquivocationHandler(k interface{}) types.Handler {
return func(ctx sdk.Context, e exported.Evidence) error { return func(ctx sdk.Context, e exported.Evidence) error {
if err := e.ValidateBasic(); err != nil { if err := e.ValidateBasic(); err != nil {
@ -70,7 +77,8 @@ func (suite *HandlerTestSuite) TestMsgSubmitEvidence() {
expectErr bool expectErr bool
}{ }{
{ {
simappcodec.NewMsgSubmitEvidence( testMsgSubmitEvidence(
suite.Require(),
&types.Equivocation{ &types.Equivocation{
Height: 11, Height: 11,
Time: time.Now().UTC(), Time: time.Now().UTC(),
@ -82,7 +90,8 @@ func (suite *HandlerTestSuite) TestMsgSubmitEvidence() {
false, false,
}, },
{ {
simappcodec.NewMsgSubmitEvidence( testMsgSubmitEvidence(
suite.Require(),
&types.Equivocation{ &types.Equivocation{
Height: 10, Height: 10,
Time: time.Now().UTC(), Time: time.Now().UTC(),

View File

@ -6,12 +6,19 @@ import (
simappcodec "github.com/cosmos/cosmos-sdk/simapp/codec" simappcodec "github.com/cosmos/cosmos-sdk/simapp/codec"
sdk "github.com/cosmos/cosmos-sdk/types" 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/cosmos/cosmos-sdk/x/evidence/types"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto/ed25519" "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) { func TestMsgSubmitEvidence(t *testing.T) {
pk := ed25519.GenPrivKey() pk := ed25519.GenPrivKey()
submitter := sdk.AccAddress("test") submitter := sdk.AccAddress("test")
@ -27,7 +34,7 @@ func TestMsgSubmitEvidence(t *testing.T) {
false, false,
}, },
{ {
simappcodec.NewMsgSubmitEvidence(&types.Equivocation{ testMsgSubmitEvidence(t, &types.Equivocation{
Height: 0, Height: 0,
Power: 100, Power: 100,
Time: time.Now().UTC(), Time: time.Now().UTC(),
@ -37,7 +44,7 @@ func TestMsgSubmitEvidence(t *testing.T) {
true, true,
}, },
{ {
simappcodec.NewMsgSubmitEvidence(&types.Equivocation{ testMsgSubmitEvidence(t, &types.Equivocation{
Height: 10, Height: 10,
Power: 100, Power: 100,
Time: time.Now().UTC(), Time: time.Now().UTC(),