fix: remove time.now check from authz (#11129)

* Merge pull request from GHSA-2p6r-37p9-89p2

* test: adding authz grant tests

* fix TestCLITxGrantAuthorization/Invalid_expiration_time test case

* comment out the test

* reenable test

* master update

* update changelog and cli test

* fix keeper tests

* fix decoder test

* cleaning

* wip - tests

* fix cli test

* add a comment

* update TestMsgGrantAuthorization

* udpate changelog

* fix sims

* fix sims

* update changelog

* Update x/authz/authorization_grant.go

Co-authored-by: Robert Zaremba <robert@zaremba.ch>
Co-authored-by: Amaury <1293565+amaurym@users.noreply.github.com>
This commit is contained in:
MD Aleem 2022-02-07 20:08:45 +05:30 committed by GitHub
parent fe9a4861d3
commit 21295060ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 132 additions and 83 deletions

View File

@ -119,6 +119,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* [\#10816](https://github.com/cosmos/cosmos-sdk/pull/10816) Reuse blocked addresses from the bank module. No need to pass them to distribution.
* [\#10852](https://github.com/cosmos/cosmos-sdk/pull/10852) Move `x/gov/types` to `x/gov/types/v1beta2`.
* [\#10868](https://github.com/cosmos/cosmos-sdk/pull/10868), [\#10989](https://github.com/cosmos/cosmos-sdk/pull/10989), [\#11093](https://github.com/cosmos/cosmos-sdk/pull/11093) The Gov keeper accepts now 2 more mandatory arguments, the ServiceMsgRouter and a gov Config including the max metadata length.
* (x/authz) [\#10447](https://github.com/cosmos/cosmos-sdk/pull/10447) authz `NewGrant` takes a new argument: block time, to correctly validate expire time.
### Client Breaking Changes
* [\#11089](https://github.com/cosmos/cosmos-sdk/pull/11089]) interacting with the node through `grpc.Dial` requires clients to pass a codec refer to [doc](docs/run-node/interact-node.md).
@ -184,6 +185,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* [#9790](https://github.com/cosmos/cosmos-sdk/pull/10687) Fix behavior of `DecCoins.MulDecTruncate`.
* [\#10990](https://github.com/cosmos/cosmos-sdk/pull/10990) Fixes missing `iavl-cache-size` config parsing in `GetConfig` method.
* (crypto) [#11027] Remove dependency on Tendermint core for xsalsa20symmetric.
* (x/authz) [\#10447](https://github.com/cosmos/cosmos-sdk/pull/10447) Fix authz `NewGrant` expiration check.
### State Machine Breaking

View File

@ -9,8 +9,12 @@ import (
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
)
// NewGrant returns new Grant
func NewGrant(a Authorization, expiration time.Time) (Grant, error) {
// NewGrant returns new Grant. It returns an error if the expiration is before
// the current block time, which is passed into the `blockTime` arg.
func NewGrant(blockTime time.Time, a Authorization, expiration time.Time) (Grant, error) {
if !expiration.After(blockTime) {
return Grant{}, sdkerrors.ErrInvalidRequest.Wrapf("expiration must be after the current block time (%v), got %v", blockTime.Format(time.RFC3339), expiration.Format(time.RFC3339))
}
g := Grant{
Expiration: expiration,
}
@ -51,10 +55,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 {

View File

@ -0,0 +1,43 @@
package authz
import (
"testing"
"time"
"github.com/stretchr/testify/require"
)
// TODO: remove and use: robert/expect-error
func expecError(r *require.Assertions, expected string, received error) {
if expected == "" {
r.NoError(received)
} else {
r.Error(received)
r.Contains(received.Error(), expected)
}
}
func TestNewGrant(t *testing.T) {
a := NewGenericAuthorization("some-type")
var tcs = []struct {
title string
a Authorization
blockTime time.Time
expire time.Time
err string
}{
{"wrong expire time (1)", a, time.Unix(10, 0), time.Unix(8, 0), "expiration must be after"},
{"wrong expire time (2)", a, time.Unix(10, 0), time.Unix(10, 0), "expiration must be after"},
{"good expire time (1)", a, time.Unix(10, 0), time.Unix(10, 1), ""},
{"good expire time (2)", a, time.Unix(10, 0), time.Unix(11, 0), ""},
}
for _, tc := range tcs {
tc := tc
t.Run(tc.title, func(t *testing.T) {
_, err := NewGrant(tc.blockTime, tc.a, tc.expire)
expecError(require.New(t), tc.err, err)
})
}
}

View File

@ -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..

View File

@ -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()),

View File

@ -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(),
@ -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(),

View File

@ -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)

View File

@ -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),
@ -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),
@ -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
@ -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,
@ -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)
@ -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(),
@ -388,7 +387,7 @@ func (s *IntegrationTestSuite) TestCmdRevokeAuthorizations() {
s.Require().NoError(err)
// generic-authorization
_, err = ExecGrant(
_, err = CreateGrant(
val,
[]string{
grantee.String(),
@ -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(),
@ -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(),
@ -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(),
@ -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(),
@ -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(),
@ -856,7 +855,7 @@ func (s *IntegrationTestSuite) TestExecDelegateAuthorization() {
}
// test delegate no spend-limit
_, err = ExecGrant(
_, err = CreateGrant(
val,
[]string{
grantee.String(),
@ -933,7 +932,7 @@ func (s *IntegrationTestSuite) TestExecDelegateAuthorization() {
}
// test delegating to denied validator
_, err = ExecGrant(
_, err = CreateGrant(
val,
[]string{
grantee.String(),
@ -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(),
@ -1077,7 +1076,7 @@ func (s *IntegrationTestSuite) TestExecUndelegateAuthorization() {
}
// grant undelegate authorization without limit
_, err = ExecGrant(
_, err = CreateGrant(
val,
[]string{
grantee.String(),

View File

@ -137,7 +137,7 @@ func (k Keeper) DispatchActions(ctx sdk.Context, grantee sdk.AccAddress, msgs []
func (k Keeper) SaveGrant(ctx sdk.Context, grantee, granter sdk.AccAddress, authorization authz.Authorization, expiration time.Time) error {
store := ctx.KVStore(k.storeKey)
grant, err := authz.NewGrant(authorization, expiration)
grant, err := authz.NewGrant(ctx.BlockTime(), authorization, expiration)
if err != nil {
return err
}
@ -237,14 +237,20 @@ func (k Keeper) ExportGenesis(ctx sdk.Context) *authz.GenesisState {
// InitGenesis new authz genesis
func (k Keeper) InitGenesis(ctx sdk.Context, data *authz.GenesisState) {
for _, entry := range data.Authorization {
if entry.Expiration.Before(ctx.BlockTime()) {
continue
}
grantee, err := sdk.AccAddressFromBech32(entry.Grantee)
if err != nil {
panic(err)
}
granter, err := sdk.AccAddressFromBech32(entry.Granter)
if err != nil {
panic(err)
}
a, ok := entry.Authorization.GetCachedValue().(authz.Authorization)
if !ok {
panic("expected authorization")

View File

@ -55,13 +55,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().Error(err)
authorization, _ = app.AuthzKeeper.GetCleanAuthorization(ctx, granteeAddr, granterAddr, bankSendAuthMsgType)
s.Require().Nil(authorization)
@ -105,14 +104,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)
@ -131,8 +129,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))
@ -157,7 +154,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)
@ -206,8 +203,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{
@ -219,7 +215,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)

View File

@ -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)

View File

@ -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(

View File

@ -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())
now := time.Now().UTC()
grant, _ := authz.NewGrant(now, banktypes.NewSendAuthorization(sdk.NewCoins(sdk.NewInt64Coin("foo", 123))), now.Add(1))
grantBz, err := cdc.Marshal(&grant)
require.NoError(t, err)
kvPairs := kv.Pairs{

View File

@ -2,6 +2,7 @@ package simulation
import (
"math/rand"
"time"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
sdk "github.com/cosmos/cosmos-sdk/types"
@ -13,7 +14,7 @@ import (
)
// genGrant returns a slice of authorization grants.
func genGrant(r *rand.Rand, accounts []simtypes.Account) []authz.GrantAuthorization {
func genGrant(r *rand.Rand, accounts []simtypes.Account, genT time.Time) []authz.GrantAuthorization {
authorizations := make([]authz.GrantAuthorization, len(accounts)-1)
for i := 0; i < len(accounts)-1; i++ {
granter := accounts[i]
@ -22,6 +23,7 @@ func genGrant(r *rand.Rand, accounts []simtypes.Account) []authz.GrantAuthorizat
Granter: granter.Address.String(),
Grantee: grantee.Address.String(),
Authorization: generateRandomGrant(r),
Expiration: genT.AddDate(1, 0, 0),
}
}
@ -50,7 +52,7 @@ func RandomizedGenState(simState *module.SimulationState) {
var grants []authz.GrantAuthorization
simState.AppParams.GetOrGenerate(
simState.Cdc, "authz", &grants, simState.Rand,
func(r *rand.Rand) { grants = genGrant(r, simState.Accounts) },
func(r *rand.Rand) { grants = genGrant(r, simState.Accounts, simState.GenTimestamp) },
)
authzGrantsGenesis := authz.NewGenesisState(grants)

View File

@ -1,11 +1,8 @@
package simulation
import (
"fmt"
"math/rand"
"github.com/gogo/protobuf/proto"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/codec"
cdctypes "github.com/cosmos/cosmos-sdk/codec/types"
@ -49,8 +46,8 @@ func WeightedOperations(
var (
weightMsgGrant int
weightRevoke int
weightExec int
weightRevoke int
)
appParams.GetOrGenerate(cdc, OpWeightMsgGrant, &weightMsgGrant, nil,
@ -59,31 +56,31 @@ func WeightedOperations(
},
)
appParams.GetOrGenerate(cdc, OpWeightRevoke, &weightRevoke, nil,
func(_ *rand.Rand) {
weightRevoke = WeightRevoke
},
)
appParams.GetOrGenerate(cdc, OpWeightExec, &weightExec, nil,
func(_ *rand.Rand) {
weightExec = WeightExec
},
)
appParams.GetOrGenerate(cdc, OpWeightRevoke, &weightRevoke, nil,
func(_ *rand.Rand) {
weightRevoke = WeightRevoke
},
)
return simulation.WeightedOperations{
simulation.NewWeightedOperation(
weightMsgGrant,
SimulateMsgGrant(ak, bk, k),
),
simulation.NewWeightedOperation(
weightRevoke,
SimulateMsgRevoke(ak, bk, k),
),
simulation.NewWeightedOperation(
weightExec,
SimulateMsgExec(ak, bk, k, appCdc),
),
simulation.NewWeightedOperation(
weightRevoke,
SimulateMsgRevoke(ak, bk, k),
),
}
}
@ -236,42 +233,45 @@ func SimulateMsgExec(ak authz.AccountKeeper, bk authz.BankKeeper, k keeper.Keepe
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgRevoke, "Account not found"), nil, sdkerrors.Wrapf(sdkerrors.ErrNotFound, "granter account not found")
}
if targetGrant.Expiration.Before(ctx.BlockHeader().Time) {
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExec, "grant expired"), nil, nil
}
coins := sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(int64(simtypes.RandIntBetween(r, 100, 1000000)))))
granterspendableCoins := bk.SpendableCoins(ctx, granterAddr)
coins := simtypes.RandSubsetCoins(r, granterspendableCoins)
// Check send_enabled status of each sent coin denom
if err := bk.IsSendEnabledCoins(ctx, coins...); err != nil {
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExec, err.Error()), nil, nil
}
if targetGrant.Authorization.TypeUrl == fmt.Sprintf("/%s", proto.MessageName(&banktype.SendAuthorization{})) {
sendAuthorization := targetGrant.GetAuthorization().(*banktype.SendAuthorization)
if sendAuthorization.SpendLimit.IsAllLT(coins) {
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExec, "over spend limit"), nil, nil
}
msg := []sdk.Msg{banktype.NewMsgSend(granterAddr, granteeAddr, coins)}
sendAuth, ok := targetGrant.GetAuthorization().(*banktype.SendAuthorization)
if !ok {
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExec, "not a send authorization"), nil, nil
}
granterspendableCoins := bk.SpendableCoins(ctx, granterAddr)
if granterspendableCoins.IsAllLTE(coins) {
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExec, "insufficient funds"), nil, nil
if sendAuth.SpendLimit.IsAllLTE(coins) {
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExec, "over spend limit"), nil, nil
}
res, err := sendAuth.Accept(ctx, msg[0])
if err != nil {
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExec, err.Error()), nil, err
}
if !res.Accept {
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExec, "expired or invalid grant"), nil, nil
}
msgExec := authz.NewMsgExec(granteeAddr, msg)
granteeSpendableCoins := bk.SpendableCoins(ctx, granteeAddr)
fees, err := simtypes.RandomFees(r, ctx, granteeSpendableCoins)
if err != nil {
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExec, "fee error"), nil, err
}
msg := authz.NewMsgExec(granteeAddr, []sdk.Msg{banktype.NewMsgSend(granterAddr, granteeAddr, coins)})
txCfg := simappparams.MakeTestEncodingConfig().TxConfig
granteeAcc := ak.GetAccount(ctx, granteeAddr)
tx, err := helpers.GenTx(
txCfg,
[]sdk.Msg{&msg},
[]sdk.Msg{&msgExec},
fees,
helpers.DefaultGenTxGas,
chainID,
@ -288,10 +288,10 @@ func SimulateMsgExec(ak authz.AccountKeeper, bk authz.BankKeeper, k keeper.Keepe
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExec, err.Error()), nil, err
}
err = msg.UnpackInterfaces(cdc)
err = msgExec.UnpackInterfaces(cdc)
if err != nil {
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExec, "unmarshal error"), nil, err
}
return simtypes.NewOperationMsg(&msg, true, "success", nil), nil, nil
return simtypes.NewOperationMsg(&msgExec, true, "success", nil), nil, nil
}
}

View File

@ -43,16 +43,16 @@ func (suite *SimTestSuite) TestWeightedOperations() {
// setup 3 accounts
s := rand.NewSource(1)
r := rand.New(s)
accs := suite.getTestingAccounts(r, 3)
accs := suite.getTestingAccounts(r, 2)
expected := []struct {
weight int
opMsgRoute string
opMsgName string
}{
{simulation.WeightGrant, authz.ModuleName, simulation.TypeMsgGrant},
{simulation.WeightRevoke, authz.ModuleName, simulation.TypeMsgRevoke},
{simulation.WeightExec, authz.ModuleName, simulation.TypeMsgExec},
{simulation.WeightGrant, simulation.TypeMsgGrant, simulation.TypeMsgGrant},
{simulation.WeightExec, simulation.TypeMsgExec, simulation.TypeMsgExec},
{simulation.WeightRevoke, simulation.TypeMsgRevoke, simulation.TypeMsgRevoke},
}
for i, w := range weightedOps {