Skip to content

Commit

Permalink
feat(x/authz): autocli tx support (#17970)
Browse files Browse the repository at this point in the history
Co-authored-by: Julien Robert <[email protected]>
Co-authored-by: Emmanuel T Odeke <[email protected]>
  • Loading branch information
3 people authored Oct 8, 2023
1 parent 9053582 commit 83622c8
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 330 deletions.
155 changes: 2 additions & 153 deletions tests/e2e/authz/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,8 @@ func (s *E2ETestSuite) TearDownSuite() {
}

var (
typeMsgSend = bank.SendAuthorization{}.MsgTypeURL()
typeMsgVote = sdk.MsgTypeURL(&govv1.MsgVote{})
typeMsgSubmitProposal = sdk.MsgTypeURL(&govv1.MsgSubmitProposal{})
typeMsgSend = bank.SendAuthorization{}.MsgTypeURL()
typeMsgVote = sdk.MsgTypeURL(&govv1.MsgVote{})
)

func execDelegate(val *network.Validator, args []string) (testutil.BufferWriter, error) {
Expand All @@ -185,156 +184,6 @@ func execDelegate(val *network.Validator, args []string) (testutil.BufferWriter,
return clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
}

func (s *E2ETestSuite) TestCmdRevokeAuthorizations() {
val := s.network.Validators[0]

grantee := s.grantee[0]
twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()

// send-authorization
_, err := authzclitestutil.CreateGrant(
val.ClientCtx,
[]string{
grantee.String(),
"send",
fmt.Sprintf("--%s=100stake", cli.FlagSpendLimit),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.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(s.cfg.BondDenom, math.NewInt(10))).String()),
},
)
s.Require().NoError(err)
s.Require().NoError(s.network.WaitForNextBlock())

// generic-authorization
_, err = authzclitestutil.CreateGrant(
val.ClientCtx,
[]string{
grantee.String(),
"generic",
fmt.Sprintf("--%s=%s", cli.FlagMsgType, typeMsgVote),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.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(s.cfg.BondDenom, math.NewInt(10))).String()),
},
)
s.Require().NoError(err)
s.Require().NoError(s.network.WaitForNextBlock())

// generic-authorization used for amino testing
_, err = authzclitestutil.CreateGrant(
val.ClientCtx,
[]string{
grantee.String(),
"generic",
fmt.Sprintf("--%s=%s", cli.FlagMsgType, typeMsgSubmitProposal),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.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(s.cfg.BondDenom, math.NewInt(10))).String()),
fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
},
)
s.Require().NoError(err)
s.Require().NoError(s.network.WaitForNextBlock())

testCases := []struct {
name string
args []string
respType proto.Message
expectedCode uint32
expectErr bool
}{
{
"invalid grantee address",
[]string{
"invalid grantee",
typeMsgSend,
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
fmt.Sprintf("--%s=true", flags.FlagGenerateOnly),
},
nil,
0,
true,
},
{
"invalid granter address",
[]string{
grantee.String(),
typeMsgSend,
fmt.Sprintf("--%s=%s", flags.FlagFrom, "granter"),
fmt.Sprintf("--%s=true", flags.FlagGenerateOnly),
},
nil,
0,
true,
},
{
"Valid tx send authorization",
[]string{
grantee.String(),
typeMsgSend,
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()),
},
&sdk.TxResponse{}, 0,
false,
},
{
"Valid tx generic authorization",
[]string{
grantee.String(),
typeMsgVote,
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()),
},
&sdk.TxResponse{}, 0,
false,
},
{
"Valid tx with amino",
[]string{
grantee.String(),
typeMsgSubmitProposal,
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin(s.cfg.BondDenom, math.NewInt(10))).String()),
fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
},
&sdk.TxResponse{}, 0,
false,
},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
cmd := cli.NewCmdRevokeAuthorization(addresscodec.NewBech32Codec("cosmos"))
clientCtx := val.ClientCtx

out, err := clitestutil.ExecTestCLICmd(clientCtx, cmd, tc.args)
if tc.expectErr {
s.Require().Error(err)
} else {
s.Require().NoError(err)
s.Require().NoError(clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String())

txResp := tc.respType.(*sdk.TxResponse)
s.Require().NoError(clitestutil.CheckTxCode(s.network, val.ClientCtx, txResp.TxHash, tc.expectedCode))
}
})
}
}

func (s *E2ETestSuite) TestExecAuthorizationWithExpiration() {
val := s.network.Validators[0]
grantee := s.grantee[0]
Expand Down
39 changes: 4 additions & 35 deletions x/authz/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,15 @@ func GetTxCmd(ac address.Codec) *cobra.Command {

AuthorizationTxCmd.AddCommand(
NewCmdGrantAuthorization(ac),
NewCmdRevokeAuthorization(ac),
NewCmdExecAuthorization(),
)

return AuthorizationTxCmd
}

// NewCmdGrantAuthorization returns a CLI command handler for creating a MsgGrant transaction.
//
// cannot give autocli support, can be CLI breaking
func NewCmdGrantAuthorization(ac address.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "grant <grantee> <authorization_type=\"send\"|\"generic\"|\"delegate\"|\"unbond\"|\"redelegate\"> --from <granter>",
Expand Down Expand Up @@ -228,41 +229,9 @@ func getExpireTime(cmd *cobra.Command) (*time.Time, error) {
return &e, nil
}

// NewCmdRevokeAuthorization returns a CLI command handler for creating a MsgRevoke transaction.
func NewCmdRevokeAuthorization(ac address.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "revoke [grantee] [msg-type-url] --from=[granter]",
Short: "revoke authorization",
Long: strings.TrimSpace(
fmt.Sprintf(`revoke authorization from a granter to a grantee:
Example:
$ %s tx %s revoke cosmos1skj.. %s --from=cosmos1skj..
`, version.AppName, authz.ModuleName, bank.SendAuthorization{}.MsgTypeURL()),
),
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}

grantee, err := ac.StringToBytes(args[0])
if err != nil {
return err
}

granter := clientCtx.GetFromAddress()
msgAuthorized := args[1]
msg := authz.NewMsgRevoke(granter, grantee, msgAuthorized)

return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), &msg)
},
}
flags.AddTxFlagsToCmd(cmd)
return cmd
}

// NewCmdExecAuthorization returns a CLI command handler for creating a MsgExec transaction.
//
// cannot give autocli support, can be CLI breaking
func NewCmdExecAuthorization() *cobra.Command {
cmd := &cobra.Command{
Use: "exec [tx-json-file] --from [grantee]",
Expand Down
142 changes: 1 addition & 141 deletions x/authz/client/cli/tx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,7 @@ import (
govv1beta1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1beta1"
)

var (
typeMsgSend = banktypes.SendAuthorization{}.MsgTypeURL()
typeMsgVote = sdk.MsgTypeURL(&govv1.MsgVote{})
typeMsgSubmitProposal = sdk.MsgTypeURL(&govv1.MsgSubmitProposal{})
)
var typeMsgVote = sdk.MsgTypeURL(&govv1.MsgVote{})

type CLITestSuite struct {
suite.Suite
Expand Down Expand Up @@ -475,142 +471,6 @@ func (s *CLITestSuite) TestCLITxGrantAuthorization() {
}
}

func (s *CLITestSuite) TestCmdRevokeAuthorizations() {
val := testutil.CreateKeyringAccounts(s.T(), s.kr, 1)

grantee := s.grantee[0]
twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()

// send-authorization
_, 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)

// generic-authorization
_, err = authzclitestutil.CreateGrant(s.clientCtx,
[]string{
grantee.String(),
"generic",
fmt.Sprintf("--%s=%s", cli.FlagMsgType, typeMsgVote),
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)

// generic-authorization used for amino testing
_, err = authzclitestutil.CreateGrant(s.clientCtx,
[]string{
grantee.String(),
"generic",
fmt.Sprintf("--%s=%s", cli.FlagMsgType, typeMsgSubmitProposal),
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()),
fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
},
)
s.Require().NoError(err)
testCases := []struct {
name string
args []string
respType proto.Message
expectErr bool
}{
{
"invalid grantee address",
[]string{
"invalid grantee",
typeMsgSend,
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
fmt.Sprintf("--%s=true", flags.FlagGenerateOnly),
},
nil,
true,
},
{
"invalid granter address",
[]string{
grantee.String(),
typeMsgSend,
fmt.Sprintf("--%s=%s", flags.FlagFrom, "granter"),
fmt.Sprintf("--%s=true", flags.FlagGenerateOnly),
},
nil,
true,
},
{
"Valid tx send authorization",
[]string{
grantee.String(),
typeMsgSend,
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(10))).String()),
},
&sdk.TxResponse{},
false,
},
{
"Valid tx generic authorization",
[]string{
grantee.String(),
typeMsgVote,
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(10))).String()),
},
&sdk.TxResponse{},
false,
},
{
"Valid tx with amino",
[]string{
grantee.String(),
typeMsgSubmitProposal,
fmt.Sprintf("--%s=%s", flags.FlagFrom, val[0].Address.String()),
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
fmt.Sprintf("--%s=%s", flags.FlagFees, sdk.NewCoins(sdk.NewCoin("stake", sdkmath.NewInt(10))).String()),
fmt.Sprintf("--%s=%s", flags.FlagSignMode, flags.SignModeLegacyAminoJSON),
},
&sdk.TxResponse{},
false,
},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
cmd := cli.NewCmdRevokeAuthorization(addresscodec.NewBech32Codec("cosmos"))

out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, tc.args)
if tc.expectErr {
s.Require().Error(err)
} else {
s.Require().NoError(err)
s.Require().NoError(s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), tc.respType), out.String())
}
})
}
}

func (s *CLITestSuite) TestExecAuthorizationWithExpiration() {
val := testutil.CreateKeyringAccounts(s.T(), s.kr, 1)

Expand Down
Loading

0 comments on commit 83622c8

Please sign in to comment.