Skip to content

Commit

Permalink
fix!: remove time.now check from authz (#10447)
Browse files Browse the repository at this point in the history
## Description

Backport v0.44.2 fix

---

### Author Checklist

*All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.*

I have...

- [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [x] added `!` to the type prefix if API or client breaking change
- [x] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting))
- [x] provided a link to the relevant issue or specification
- [x] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules)
- [x] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing)
- [ ] added a changelog entry to `CHANGELOG.md`
- [x] included comments for [documenting Go code](https://blog.golang.org/godoc)
- [x] updated the relevant documentation or specification
- [x] reviewed "Files changed" and left comments if necessary
- [ ] confirmed all CI checks have passed

### Reviewers Checklist

*All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.*

I have...

- [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] confirmed `!` in the type prefix if API or client breaking change
- [ ] confirmed all author checklist items have been addressed 
- [ ] reviewed state machine logic
- [ ] reviewed API design and naming
- [ ] reviewed documentation is accurate
- [ ] reviewed tests and test coverage
- [ ] manually tested (if applicable)
  • Loading branch information
robert-zaremba committed Feb 2, 2022
1 parent ab95455 commit 077154a
Show file tree
Hide file tree
Showing 16 changed files with 77 additions and 57 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -200,6 +200,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* [\#10868](https://github.com/cosmos/cosmos-sdk/pull/10868) Bump gov to v1beta2. Both v1beta1 and v1beta2 queries and Msgs are accepted.
* [\#11011](https://github.com/cosmos/cosmos-sdk/pull/11011) Remove burning of deposits when qourum is not reached on a governance proposal and when the deposit is not fully met.
* [\#11019](https://github.com/cosmos/cosmos-sdk/pull/11019) Add `MsgCreatePermanentLockedAccount` and CLI method for creating permanent locked account
* (x/authz) [\#10447](https://github.com/cosmos/cosmos-sdk/pull/10447) Remove time.now() check in authz `NewGrant` validation.

### Deprecated

Expand Down
14 changes: 6 additions & 8 deletions x/authz/authorization_grant.go
Expand Up @@ -9,7 +9,13 @@ import (
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)

var (
_ cdctypes.UnpackInterfacesMessage = &Grant{}
)

// NewGrant returns new Grant
// NOTE: a new grant is considered invalid if the expiration time is after the
// "current" time - you should assure that before calling this function.
func NewGrant(a Authorization, expiration time.Time) (Grant, error) {
g := Grant{
Expiration: expiration,
Expand All @@ -28,10 +34,6 @@ func NewGrant(a Authorization, expiration time.Time) (Grant, error) {
return g, nil
}

var (
_ cdctypes.UnpackInterfacesMessage = &Grant{}
)

// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
func (g Grant) UnpackInterfaces(unpacker cdctypes.AnyUnpacker) error {
var authorization Authorization
Expand All @@ -51,10 +53,6 @@ func (g Grant) GetAuthorization() Authorization {
}

func (g Grant) ValidateBasic() error {
if g.Expiration.Unix() < time.Now().Unix() {
return sdkerrors.Wrap(ErrInvalidExpirationTime, "Time can't be in the past")
}

av := g.Authorization.GetCachedValue()
a, ok := av.(Authorization)
if !ok {
Expand Down
14 changes: 14 additions & 0 deletions x/authz/authorization_grant_test.go
@@ -0,0 +1,14 @@
package authz

import (
"testing"
"time"

"github.com/stretchr/testify/require"
)

func TestNewGrant(t *testing.T) {
a := NewGenericAuthorization("some-type")
_, err := NewGrant(a, time.Unix(10, 0))
require.NoError(t, err)
}
2 changes: 1 addition & 1 deletion x/authz/client/cli/tx.go
Expand Up @@ -56,7 +56,7 @@ func NewCmdGrantAuthorization() *cobra.Command {
Use: "grant <grantee> <authorization_type=\"send\"|\"generic\"|\"delegate\"|\"unbond\"|\"redelegate\"> --from <granter>",
Short: "Grant authorization to an address",
Long: strings.TrimSpace(
fmt.Sprintf(`grant authorization to an address to execute a transaction on your behalf:
fmt.Sprintf(`create a new grant authorization to an address to execute a transaction on your behalf:
Examples:
$ %s tx %s grant cosmos1skjw.. send %s --spend-limit=1000stake --from=cosmos1skl..
Expand Down
2 changes: 1 addition & 1 deletion x/authz/client/testutil/grpc.go
Expand Up @@ -107,7 +107,7 @@ func (s *IntegrationTestSuite) TestQueryGrantsGRPC() {
false,
"",
func() {
_, err := ExecGrant(val, []string{
_, err := CreateGrant(val, []string{
grantee.String(),
"generic",
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
Expand Down
4 changes: 2 additions & 2 deletions x/authz/client/testutil/query.go
Expand Up @@ -20,7 +20,7 @@ func (s *IntegrationTestSuite) TestQueryAuthorizations() {
grantee := s.grantee[0]
twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()

_, err := ExecGrant(
_, err := CreateGrant(
val,
[]string{
grantee.String(),
Expand Down Expand Up @@ -98,7 +98,7 @@ func (s *IntegrationTestSuite) TestQueryAuthorization() {
grantee := s.grantee[0]
twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()

_, err := ExecGrant(
_, err := CreateGrant(
val,
[]string{
grantee.String(),
Expand Down
2 changes: 1 addition & 1 deletion x/authz/client/testutil/test_helpers.go
Expand Up @@ -7,7 +7,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/authz/client/cli"
)

func ExecGrant(val *network.Validator, args []string) (testutil.BufferWriter, error) {
func CreateGrant(val *network.Validator, args []string) (testutil.BufferWriter, error) {
cmd := cli.NewCmdGrantAuthorization()
clientCtx := val.ClientCtx
return clitestutil.ExecTestCLICmd(clientCtx, cmd, args)
Expand Down
37 changes: 18 additions & 19 deletions x/authz/client/testutil/tx.go
Expand Up @@ -65,7 +65,7 @@ func (s *IntegrationTestSuite) SetupSuite() {
s.msgSendExec(s.grantee[1])

// grant send authorization to grantee2
out, err := ExecGrant(val, []string{
out, err := CreateGrant(val, []string{
s.grantee[1].String(),
"send",
fmt.Sprintf("--%s=100steak", cli.FlagSpendLimit),
Expand All @@ -85,7 +85,7 @@ func (s *IntegrationTestSuite) SetupSuite() {
s.grantee[2] = s.createAccount("grantee3")

// grant send authorization to grantee3
out, err = ExecGrant(val, []string{
out, err = CreateGrant(val, []string{
s.grantee[2].String(),
"send",
fmt.Sprintf("--%s=100steak", cli.FlagSpendLimit),
Expand Down Expand Up @@ -147,8 +147,8 @@ func (s *IntegrationTestSuite) TestCLITxGrantAuthorization() {
val := s.network.Validators[0]
grantee := s.grantee[0]

twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()
pastHour := time.Now().Add(time.Minute * time.Duration(-60)).Unix()
twoHours := time.Now().Add(time.Minute * 120).Unix()
pastHour := time.Now().Add(-time.Minute * 60).Unix()

testCases := []struct {
name string
Expand Down Expand Up @@ -189,7 +189,7 @@ func (s *IntegrationTestSuite) TestCLITxGrantAuthorization() {
"send",
fmt.Sprintf("--%s=100steak", cli.FlagSpendLimit),
fmt.Sprintf("--%s=%s", flags.FlagFrom, val.Address.String()),
fmt.Sprintf("--%s=true", flags.FlagGenerateOnly),
fmt.Sprintf("--%s=true", flags.FlagBroadcastMode),
fmt.Sprintf("--%s=%d", cli.FlagExpiration, pastHour),
},
0,
Expand Down Expand Up @@ -340,15 +340,14 @@ func (s *IntegrationTestSuite) TestCLITxGrantAuthorization() {
}

for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
clientCtx := val.ClientCtx
out, err := ExecGrant(
out, err := CreateGrant(
val,
tc.args,
)
if tc.expectErr {
s.Require().Error(err)
s.Require().Error(err, out)
} else {
var txResp sdk.TxResponse
s.Require().NoError(err)
Expand All @@ -372,7 +371,7 @@ func (s *IntegrationTestSuite) TestCmdRevokeAuthorizations() {
twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()

// send-authorization
_, err := ExecGrant(
_, err := CreateGrant(
val,
[]string{
grantee.String(),
Expand All @@ -388,7 +387,7 @@ func (s *IntegrationTestSuite) TestCmdRevokeAuthorizations() {
s.Require().NoError(err)

// generic-authorization
_, err = ExecGrant(
_, err = CreateGrant(
val,
[]string{
grantee.String(),
Expand All @@ -404,7 +403,7 @@ func (s *IntegrationTestSuite) TestCmdRevokeAuthorizations() {
s.Require().NoError(err)

// generic-authorization used for amino testing
_, err = ExecGrant(
_, err = CreateGrant(
val,
[]string{
grantee.String(),
Expand Down Expand Up @@ -517,7 +516,7 @@ func (s *IntegrationTestSuite) TestExecAuthorizationWithExpiration() {
grantee := s.grantee[0]
tenSeconds := time.Now().Add(time.Second * time.Duration(10)).Unix()

_, err := ExecGrant(
_, err := CreateGrant(
val,
[]string{
grantee.String(),
Expand Down Expand Up @@ -557,7 +556,7 @@ func (s *IntegrationTestSuite) TestNewExecGenericAuthorized() {
grantee := s.grantee[0]
twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()

_, err := ExecGrant(
_, err := CreateGrant(
val,
[]string{
grantee.String(),
Expand Down Expand Up @@ -660,7 +659,7 @@ func (s *IntegrationTestSuite) TestNewExecGrantAuthorized() {
grantee1 := s.grantee[2]
twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()

_, err := ExecGrant(
_, err := CreateGrant(
val,
[]string{
grantee.String(),
Expand Down Expand Up @@ -764,7 +763,7 @@ func (s *IntegrationTestSuite) TestExecDelegateAuthorization() {
grantee := s.grantee[0]
twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()

_, err := ExecGrant(
_, err := CreateGrant(
val,
[]string{
grantee.String(),
Expand Down Expand Up @@ -856,7 +855,7 @@ func (s *IntegrationTestSuite) TestExecDelegateAuthorization() {
}

// test delegate no spend-limit
_, err = ExecGrant(
_, err = CreateGrant(
val,
[]string{
grantee.String(),
Expand Down Expand Up @@ -933,7 +932,7 @@ func (s *IntegrationTestSuite) TestExecDelegateAuthorization() {
}

// test delegating to denied validator
_, err = ExecGrant(
_, err = CreateGrant(
val,
[]string{
grantee.String(),
Expand Down Expand Up @@ -968,7 +967,7 @@ func (s *IntegrationTestSuite) TestExecUndelegateAuthorization() {
twoHours := time.Now().Add(time.Minute * time.Duration(120)).Unix()

// granting undelegate msg authorization
_, err := ExecGrant(
_, err := CreateGrant(
val,
[]string{
grantee.String(),
Expand Down Expand Up @@ -1077,7 +1076,7 @@ func (s *IntegrationTestSuite) TestExecUndelegateAuthorization() {
}

// grant undelegate authorization without limit
_, err = ExecGrant(
_, err = CreateGrant(
val,
[]string{
grantee.String(),
Expand Down
6 changes: 6 additions & 0 deletions x/authz/keeper/keeper.go
Expand Up @@ -136,6 +136,12 @@ func (k Keeper) DispatchActions(ctx sdk.Context, grantee sdk.AccAddress, msgs []
// same `sdk.Msg` type, this grant overwrites that.
func (k Keeper) SaveGrant(ctx sdk.Context, grantee, granter sdk.AccAddress, authorization authz.Authorization, expiration time.Time) error {
store := ctx.KVStore(k.storeKey)
blockTime := ctx.BlockTime()
if !expiration.After(blockTime) {
return sdkerrors.ErrInvalidRequest.Wrapf(
"expiration must be after the current block time (%v), got %v",
blockTime.Format(time.RFC3339), expiration.Format(time.RFC3339))
}

grant, err := authz.NewGrant(authorization, expiration)
if err != nil {
Expand Down
21 changes: 9 additions & 12 deletions x/authz/keeper/keeper_test.go
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/simapp"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/x/authz"
"github.com/cosmos/cosmos-sdk/x/bank/testutil"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
Expand Down Expand Up @@ -55,13 +56,12 @@ func (s *TestSuite) TestKeeper() {
s.Require().Nil(authorization)
s.Require().Equal(expiration, time.Time{})
now := s.ctx.BlockHeader().Time
s.Require().NotNil(now)

newCoins := sdk.NewCoins(sdk.NewInt64Coin("steak", 100))
s.T().Log("verify if expired authorization is rejected")
x := &banktypes.SendAuthorization{SpendLimit: newCoins}
err := app.AuthzKeeper.SaveGrant(ctx, granterAddr, granteeAddr, x, now.Add(-1*time.Hour))
s.Require().NoError(err)
s.Require().ErrorIs(err, errors.ErrInvalidRequest)
authorization, _ = app.AuthzKeeper.GetCleanAuthorization(ctx, granteeAddr, granterAddr, bankSendAuthMsgType)
s.Require().Nil(authorization)

Expand All @@ -83,7 +83,7 @@ func (s *TestSuite) TestKeeper() {

s.T().Log("verify revoke fails with wrong information")
err = app.AuthzKeeper.DeleteGrant(ctx, recipientAddr, granterAddr, bankSendAuthMsgType)
s.Require().Error(err)
s.Require().ErrorIs(err, errors.ErrNotFound)
authorization, _ = app.AuthzKeeper.GetCleanAuthorization(ctx, recipientAddr, granterAddr, bankSendAuthMsgType)
s.Require().Nil(authorization)

Expand All @@ -105,14 +105,13 @@ func (s *TestSuite) TestKeeperIter() {
authorization, expiration := app.AuthzKeeper.GetCleanAuthorization(ctx, granteeAddr, granterAddr, "Abcd")
s.Require().Nil(authorization)
s.Require().Equal(time.Time{}, expiration)
now := s.ctx.BlockHeader().Time
s.Require().NotNil(now)
now := s.ctx.BlockHeader().Time.Add(time.Second)

newCoins := sdk.NewCoins(sdk.NewInt64Coin("steak", 100))
s.T().Log("verify if expired authorization is rejected")
x := &banktypes.SendAuthorization{SpendLimit: newCoins}
err := app.AuthzKeeper.SaveGrant(ctx, granteeAddr, granterAddr, x, now.Add(-1*time.Hour))
s.Require().NoError(err)
s.Require().Error(err)
authorization, _ = app.AuthzKeeper.GetCleanAuthorization(ctx, granteeAddr, granterAddr, "abcd")
s.Require().Nil(authorization)

Expand All @@ -131,8 +130,7 @@ func (s *TestSuite) TestKeeperFees() {
granteeAddr := addrs[1]
recipientAddr := addrs[2]
s.Require().NoError(testutil.FundAccount(app.BankKeeper, s.ctx, granterAddr, sdk.NewCoins(sdk.NewInt64Coin("steak", 10000))))
now := s.ctx.BlockHeader().Time
s.Require().NotNil(now)
expiration := s.ctx.BlockHeader().Time.Add(1 * time.Second)

smallCoin := sdk.NewCoins(sdk.NewInt64Coin("steak", 20))
someCoin := sdk.NewCoins(sdk.NewInt64Coin("steak", 123))
Expand All @@ -157,7 +155,7 @@ func (s *TestSuite) TestKeeperFees() {

s.T().Log("verify dispatch executes with correct information")
// grant authorization
err = app.AuthzKeeper.SaveGrant(s.ctx, granteeAddr, granterAddr, &banktypes.SendAuthorization{SpendLimit: smallCoin}, now)
err = app.AuthzKeeper.SaveGrant(s.ctx, granteeAddr, granterAddr, &banktypes.SendAuthorization{SpendLimit: smallCoin}, expiration)
s.Require().NoError(err)
authorization, _ := app.AuthzKeeper.GetCleanAuthorization(s.ctx, granteeAddr, granterAddr, bankSendAuthMsgType)
s.Require().NotNil(authorization)
Expand Down Expand Up @@ -206,8 +204,7 @@ func (s *TestSuite) TestDispatchedEvents() {
granteeAddr := addrs[1]
recipientAddr := addrs[2]
require.NoError(testutil.FundAccount(app.BankKeeper, s.ctx, granterAddr, sdk.NewCoins(sdk.NewInt64Coin("steak", 10000))))
now := s.ctx.BlockHeader().Time
require.NotNil(now)
expiration := s.ctx.BlockHeader().Time.Add(1 * time.Second) // must be in the future

smallCoin := sdk.NewCoins(sdk.NewInt64Coin("steak", 20))
msgs := authz.NewMsgExec(granteeAddr, []sdk.Msg{
Expand All @@ -219,7 +216,7 @@ func (s *TestSuite) TestDispatchedEvents() {
})

// grant authorization
err := app.AuthzKeeper.SaveGrant(s.ctx, granteeAddr, granterAddr, &banktypes.SendAuthorization{SpendLimit: smallCoin}, now)
err := app.AuthzKeeper.SaveGrant(s.ctx, granteeAddr, granterAddr, &banktypes.SendAuthorization{SpendLimit: smallCoin}, expiration)
require.NoError(err)
authorization, _ := app.AuthzKeeper.GetCleanAuthorization(s.ctx, granteeAddr, granterAddr, bankSendAuthMsgType)
require.NotNil(authorization)
Expand Down
2 changes: 1 addition & 1 deletion x/authz/keeper/msg_server.go
Expand Up @@ -10,7 +10,7 @@ import (

var _ authz.MsgServer = Keeper{}

// GrantAuthorization implements the MsgServer.Grant method.
// GrantAuthorization implements the MsgServer.Grant method to create a new grant.
func (k Keeper) Grant(goCtx context.Context, msg *authz.MsgGrant) (*authz.MsgGrantResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
grantee, err := sdk.AccAddressFromBech32(msg.Grantee)
Expand Down
2 changes: 1 addition & 1 deletion x/authz/msgs_test.go
Expand Up @@ -80,7 +80,7 @@ func TestMsgGrantAuthorization(t *testing.T) {
{"nil granter and grantee address", nil, nil, &banktypes.SendAuthorization{SpendLimit: coinsPos}, time.Now(), false, false},
{"nil authorization", granter, grantee, nil, time.Now(), true, false},
{"valid test case", granter, grantee, &banktypes.SendAuthorization{SpendLimit: coinsPos}, time.Now().AddDate(0, 1, 0), false, true},
{"past time", granter, grantee, &banktypes.SendAuthorization{SpendLimit: coinsPos}, time.Now().AddDate(0, 0, -1), false, false},
{"past time", granter, grantee, &banktypes.SendAuthorization{SpendLimit: coinsPos}, time.Now().AddDate(0, 0, -1), true, true},
}
for i, tc := range tests {
msg, err := authz.NewMsgGrant(
Expand Down
3 changes: 2 additions & 1 deletion x/authz/simulation/decoder_test.go
Expand Up @@ -20,7 +20,8 @@ func TestDecodeStore(t *testing.T) {
cdc := simapp.MakeTestEncodingConfig().Codec
dec := simulation.NewDecodeStore(cdc)

grant, _ := authz.NewGrant(banktypes.NewSendAuthorization(sdk.NewCoins(sdk.NewInt64Coin("foo", 123))), time.Now().UTC())
grant, _ := authz.NewGrant(banktypes.NewSendAuthorization(sdk.NewCoins(sdk.NewInt64Coin("foo", 123))),
time.Now().Add(10*time.Minute).UTC())
grantBz, err := cdc.Marshal(&grant)
require.NoError(t, err)
kvPairs := kv.Pairs{
Expand Down

0 comments on commit 077154a

Please sign in to comment.