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:
parent
fe9a4861d3
commit
21295060ab
@ -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
|
||||
|
||||
|
||||
@ -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 {
|
||||
|
||||
43
x/authz/authorization_grant_test.go
Normal file
43
x/authz/authorization_grant_test.go
Normal 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)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
@ -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..
|
||||
|
||||
@ -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()),
|
||||
|
||||
@ -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(),
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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(),
|
||||
|
||||
@ -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")
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -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{
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user