diff --git a/proto/cosmos/authz/v1beta1/query.proto b/proto/cosmos/authz/v1beta1/query.proto index 62154ac19a..fcd56815a6 100644 --- a/proto/cosmos/authz/v1beta1/query.proto +++ b/proto/cosmos/authz/v1beta1/query.proto @@ -65,7 +65,7 @@ message QueryGranterGrantsResponse { cosmos.base.query.v1beta1.PageResponse pagination = 2; } -// QueryGranteeGrantsRequest is the request type for the Query/IssuedGrants RPC method. +// QueryGranteeGrantsRequest is the request type for the Query/GranteeGrants RPC method. message QueryGranteeGrantsRequest { string grantee = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; diff --git a/proto/cosmos/authz/v1beta1/tx.proto b/proto/cosmos/authz/v1beta1/tx.proto index 69277c95ee..a1abff0d6f 100644 --- a/proto/cosmos/authz/v1beta1/tx.proto +++ b/proto/cosmos/authz/v1beta1/tx.proto @@ -44,10 +44,8 @@ message MsgGrant { cosmos.authz.v1beta1.Grant grant = 3 [(gogoproto.nullable) = false, (amino.dont_omitempty) = true]; } -// MsgExecResponse defines the Msg/MsgExecResponse response type. -message MsgExecResponse { - repeated bytes results = 1; -} +// MsgGrantResponse defines the Msg/MsgGrant response type. +message MsgGrantResponse {} // MsgExec attempts to execute the provided messages using // authorizations granted to the grantee. Each message should have only @@ -63,8 +61,10 @@ message MsgExec { repeated google.protobuf.Any msgs = 2 [(cosmos_proto.accepts_interface) = "cosmos.base.v1beta1.Msg"]; } -// MsgGrantResponse defines the Msg/MsgGrant response type. -message MsgGrantResponse {} +// MsgExecResponse defines the Msg/MsgExecResponse response type. +message MsgExecResponse { + repeated bytes results = 1; +} // MsgRevoke revokes any authorization with the provided sdk.Msg type on the // granter's account with that has been granted to the grantee. diff --git a/x/authz/client/cli/query.go b/x/authz/client/cli/query.go index 4e244c348a..c8f29abde6 100644 --- a/x/authz/client/cli/query.go +++ b/x/authz/client/cli/query.go @@ -66,7 +66,7 @@ $ %s query %s grants cosmos1skjw.. cosmos1skjwj.. %s return err } msgAuthorized := "" - if len(args) >= 3 { + if len(args) == 3 { msgAuthorized = args[2] } pageReq, err := client.ReadPageRequest(cmd.Flags()) diff --git a/x/authz/client/cli/query_test.go b/x/authz/client/cli/query_test.go index 8ee965101e..51b28a04b2 100644 --- a/x/authz/client/cli/query_test.go +++ b/x/authz/client/cli/query_test.go @@ -175,6 +175,79 @@ func (s *CLITestSuite) TestQueryAuthorization() { } } +func (s *CLITestSuite) TestQueryGranteeGrants() { + val := testutil.CreateKeyringAccounts(s.T(), s.kr, 1) + + grantee := s.grantee[0] + twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix() + require := s.Require() + + _, err := authzclitestutil.CreateGrant( + s.clientCtx, + []string{ + grantee.String(), + "send", + fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit), + fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), + fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address), + fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), + fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), + fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(10))).String()), + }, + ) + s.Require().NoError(err) + + testCases := []struct { + name string + args []string + expectErr bool + expectedErr string + }{ + { + "invalid address", + []string{ + "invalid-address", + fmt.Sprintf("--%s=json", flags.FlagOutput), + }, + true, + "decoding bech32 failed", + }, + { + "valid case", + []string{ + grantee.String(), + fmt.Sprintf("--%s=json", flags.FlagOutput), + }, + false, + "", + }, + { + "valid case with pagination", + []string{ + grantee.String(), + "--limit=2", + fmt.Sprintf("--%s=json", flags.FlagOutput), + }, + false, + "", + }, + } + for _, tc := range testCases { + s.Run(tc.name, func() { + cmd := cli.GetQueryGranteeGrants(addresscodec.NewBech32Codec("cosmos")) + out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, tc.args) + if tc.expectErr { + require.Error(err) + require.Contains(out.String(), tc.expectedErr) + } else { + require.NoError(err) + var grants authz.QueryGranteeGrantsResponse + require.NoError(s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), &grants)) + } + }) + } +} + func (s *CLITestSuite) TestQueryGranterGrants() { val := testutil.CreateKeyringAccounts(s.T(), s.kr, 1) diff --git a/x/authz/client/cli/tx_test.go b/x/authz/client/cli/tx_test.go index 3124167d28..3c04f9da74 100644 --- a/x/authz/client/cli/tx_test.go +++ b/x/authz/client/cli/tx_test.go @@ -15,6 +15,7 @@ import ( sdkmath "cosmossdk.io/math" _ "cosmossdk.io/api/cosmos/authz/v1beta1" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" addresscodec "github.com/cosmos/cosmos-sdk/codec/address" @@ -229,6 +230,19 @@ func (s *CLITestSuite) TestCLITxGrantAuthorization() { true, "invalid separator index", }, + { + "Invalid spend limit", + []string{ + grantee.String(), + "send", + fmt.Sprintf("--%s=0stake", cli.FlagSpendLimit), + fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()), + fmt.Sprintf("--%s=true", flags.FlagGenerateOnly), + fmt.Sprintf("--%s=%d", cli.FlagExpiration, twoHours), + }, + true, + "spend-limit should be greater than zero", + }, { "Invalid expiration time", []string{ @@ -306,7 +320,7 @@ func (s *CLITestSuite) TestCLITxGrantAuthorization() { "invalid denom", }, { - "invalid bond denon for tx redelegate authorization", + "invalid bond denom for tx redelegate authorization", []string{ grantee.String(), "redelegate", @@ -337,6 +351,15 @@ func (s *CLITestSuite) TestCLITxGrantAuthorization() { true, "invalid decimal coin expression", }, + { + "invalid authorization type", + []string{ + grantee.String(), + "invalid authz type", + }, + true, + "invalid authorization type", + }, { "Valid tx send authorization", []string{ diff --git a/x/authz/keeper/genesis.go b/x/authz/keeper/genesis.go index 91c99ac4ba..08b84b8ed6 100644 --- a/x/authz/keeper/genesis.go +++ b/x/authz/keeper/genesis.go @@ -5,7 +5,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/authz" ) -// InitGenesis new authz genesis +// InitGenesis initializes new authz genesis func (k Keeper) InitGenesis(ctx sdk.Context, data *authz.GenesisState) { now := ctx.BlockTime() for _, entry := range data.Authorization { diff --git a/x/authz/keeper/genesis_test.go b/x/authz/keeper/genesis_test.go index 729d24e43b..eda7da5e67 100644 --- a/x/authz/keeper/genesis_test.go +++ b/x/authz/keeper/genesis_test.go @@ -83,9 +83,12 @@ func (suite *GenesisTestSuite) TestImportExportGenesis() { // TODO, recheck! // Clear keeper suite.keeper.DeleteGrant(suite.ctx, granteeAddr, granterAddr, grant.MsgTypeURL()) + newGenesis := suite.keeper.ExportGenesis(suite.ctx) + suite.Require().NotEqual(genesis, newGenesis) + suite.Require().Empty(newGenesis) suite.keeper.InitGenesis(suite.ctx, genesis) - newGenesis := suite.keeper.ExportGenesis(suite.ctx) + newGenesis = suite.keeper.ExportGenesis(suite.ctx) suite.Require().Equal(genesis, newGenesis) } diff --git a/x/authz/keeper/msg_server.go b/x/authz/keeper/msg_server.go index 8f5b0cb793..b6755a9f84 100644 --- a/x/authz/keeper/msg_server.go +++ b/x/authz/keeper/msg_server.go @@ -6,6 +6,7 @@ import ( "strings" errorsmod "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/x/authz"