x/authz: simulation audit changes (#9107)
* addressing audit changes * address simulation genesis changes * address simulation operations changes * fix tests * typo * add more authorizations to operations * fix tests * fix failing simulations * WIP * WIP * testing simulations * test simulations * try fixing tests * WIP * fix error * test * Add exec authorization * WIP * WIP * fix tests * WIP * WIP * WIP * WIP * WIP * fix errors * fix test * WIP * try fix test * update tests * fix errors * add exec authorization * fix docs * fix test * fix error * try fixing simulation * fix errors * fixing simulations * fix errors * rename GenTx -> GenerateTx * Update x/authz/simulation/genesis.go Co-authored-by: Robert Zaremba <robert@zaremba.ch> * Update x/authz/simulation/genesis.go Co-authored-by: Robert Zaremba <robert@zaremba.ch> * Update x/authz/simulation/operations.go Co-authored-by: Robert Zaremba <robert@zaremba.ch> * review changes * fix tests * rename GenerateTx => GenTx * remove Authorization suffix Co-authored-by: Robert Zaremba <robert@zaremba.ch> Co-authored-by: atheeshp <59333759+atheeshp@users.noreply.github.com>
This commit is contained in:
parent
56c0595f32
commit
8cfa2c2673
|
@ -13,4 +13,5 @@ type AccountKeeper interface {
|
|||
// BankKeeper defines the expected interface needed to retrieve account balances.
|
||||
type BankKeeper interface {
|
||||
SpendableCoins(ctx sdk.Context, addr sdk.AccAddress) sdk.Coins
|
||||
IsSendEnabledCoins(ctx sdk.Context, coins ...sdk.Coin) error
|
||||
}
|
||||
|
|
|
@ -32,19 +32,19 @@ func TestDecodeStore(t *testing.T) {
|
|||
|
||||
tests := []struct {
|
||||
name string
|
||||
expectErr bool
|
||||
expectedLog string
|
||||
}{
|
||||
{"Grant", fmt.Sprintf("%v\n%v", grant, grant)},
|
||||
{"other", ""},
|
||||
{"Grant", false, fmt.Sprintf("%v\n%v", grant, grant)},
|
||||
{"other", true, ""},
|
||||
}
|
||||
|
||||
for i, tt := range tests {
|
||||
i, tt := i, tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
switch i {
|
||||
case len(tests) - 1:
|
||||
if tt.expectErr {
|
||||
require.Panics(t, func() { dec(kvPairs.Pairs[i], kvPairs.Pairs[i]) }, tt.name)
|
||||
default:
|
||||
} else {
|
||||
require.Equal(t, tt.expectedLog, dec(kvPairs.Pairs[i], kvPairs.Pairs[i]), tt.name)
|
||||
}
|
||||
})
|
||||
|
|
|
@ -1,35 +1,59 @@
|
|||
package simulation
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz"
|
||||
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
|
||||
)
|
||||
|
||||
// GenAuthorizationGrant returns an empty slice of authorization grants.
|
||||
func GenAuthorizationGrant(_ *rand.Rand, _ []simtypes.Account) []authz.GrantAuthorization {
|
||||
return []authz.GrantAuthorization{}
|
||||
// genGrant returns a slice of authorization grants.
|
||||
func genGrant(r *rand.Rand, accounts []simtypes.Account) []authz.GrantAuthorization {
|
||||
authorizations := make([]authz.GrantAuthorization, len(accounts)-1)
|
||||
for i := 0; i < len(accounts)-1; i++ {
|
||||
granter := accounts[i]
|
||||
grantee := accounts[i+1]
|
||||
authorizations[i] = authz.GrantAuthorization{
|
||||
Granter: granter.Address.String(),
|
||||
Grantee: grantee.Address.String(),
|
||||
Authorization: generateRandomGrant(r),
|
||||
}
|
||||
}
|
||||
|
||||
return authorizations
|
||||
}
|
||||
|
||||
func generateRandomGrant(r *rand.Rand) *codectypes.Any {
|
||||
authorizations := make([]*codectypes.Any, 2)
|
||||
authorizations[0] = newAnyAuthorization(banktypes.NewSendAuthorization(sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(1000)))))
|
||||
authorizations[1] = newAnyAuthorization(authz.NewGenericAuthorization(sdk.MsgTypeURL(&govtypes.MsgSubmitProposal{})))
|
||||
|
||||
return authorizations[r.Intn(len(authorizations))]
|
||||
}
|
||||
|
||||
func newAnyAuthorization(a authz.Authorization) *codectypes.Any {
|
||||
any, err := codectypes.NewAnyWithValue(a)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return any
|
||||
}
|
||||
|
||||
// RandomizedGenState generates a random GenesisState for authz.
|
||||
func RandomizedGenState(simState *module.SimulationState) {
|
||||
var grants []authz.GrantAuthorization
|
||||
|
||||
simState.AppParams.GetOrGenerate(
|
||||
simState.Cdc, "authz", &grants, simState.Rand,
|
||||
func(r *rand.Rand) { grants = GenAuthorizationGrant(r, simState.Accounts) },
|
||||
func(r *rand.Rand) { grants = genGrant(r, simState.Accounts) },
|
||||
)
|
||||
|
||||
authzGrantsGenesis := authz.NewGenesisState(grants)
|
||||
|
||||
bz, err := json.MarshalIndent(&authzGrantsGenesis, "", " ")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Printf("Selected randomly generated %s parameters:\n%s\n", authz.ModuleName, bz)
|
||||
simState.GenState[authz.ModuleName] = simState.Cdc.MustMarshalJSON(authzGrantsGenesis)
|
||||
}
|
||||
|
|
|
@ -7,8 +7,7 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
"github.com/cosmos/cosmos-sdk/types/module"
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz"
|
||||
|
@ -16,15 +15,14 @@ import (
|
|||
)
|
||||
|
||||
func TestRandomizedGenState(t *testing.T) {
|
||||
interfaceRegistry := codectypes.NewInterfaceRegistry()
|
||||
cdc := codec.NewProtoCodec(interfaceRegistry)
|
||||
app := simapp.Setup(false)
|
||||
|
||||
s := rand.NewSource(1)
|
||||
r := rand.New(s)
|
||||
|
||||
simState := module.SimulationState{
|
||||
AppParams: make(simtypes.AppParams),
|
||||
Cdc: cdc,
|
||||
Cdc: app.AppCodec(),
|
||||
Rand: r,
|
||||
NumBonded: 3,
|
||||
Accounts: simtypes.RandomAccounts(r, 3),
|
||||
|
@ -36,5 +34,5 @@ func TestRandomizedGenState(t *testing.T) {
|
|||
var authzGenesis authz.GenesisState
|
||||
simState.Cdc.MustUnmarshalJSON(simState.GenState[authz.ModuleName], &authzGenesis)
|
||||
|
||||
require.Len(t, authzGenesis.Authorization, 0)
|
||||
require.Len(t, authzGenesis.Authorization, len(simState.Accounts) - 1)
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package simulation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strings"
|
||||
|
||||
"github.com/cosmos/cosmos-sdk/baseapp"
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
|
@ -12,23 +12,34 @@ import (
|
|||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
|
||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz/keeper"
|
||||
|
||||
banktype "github.com/cosmos/cosmos-sdk/x/bank/types"
|
||||
"github.com/cosmos/cosmos-sdk/x/simulation"
|
||||
)
|
||||
|
||||
// authz message types
|
||||
var (
|
||||
TypeMsgGrantAuthorization = sdk.MsgTypeURL(&authz.MsgGrant{})
|
||||
TypeMsgRevokeAuthorization = sdk.MsgTypeURL(&authz.MsgRevoke{})
|
||||
TypeMsgExecDelegated = sdk.MsgTypeURL(&authz.MsgExec{})
|
||||
TypeMsgGrant = sdk.MsgTypeURL(&authz.MsgGrant{})
|
||||
TypeMsgRevoke = sdk.MsgTypeURL(&authz.MsgRevoke{})
|
||||
TypeMsgExec = sdk.MsgTypeURL(&authz.MsgExec{})
|
||||
)
|
||||
|
||||
// Simulation operation weights constants
|
||||
const (
|
||||
OpWeightMsgGrantAuthorization = "op_weight_msg_grant"
|
||||
OpWeightRevokeAuthorization = "op_weight_msg_revoke"
|
||||
OpWeightExecAuthorized = "op_weight_msg_execute"
|
||||
OpWeightMsgGrant = "op_weight_msg_grant"
|
||||
OpWeightRevoke = "op_weight_msg_revoke"
|
||||
OpWeightExec = "op_weight_msg_execute"
|
||||
)
|
||||
|
||||
// authz operations weights
|
||||
const (
|
||||
WeightGrant = 100
|
||||
WeightRevoke = 90
|
||||
WeightExec = 90
|
||||
)
|
||||
|
||||
// WeightedOperations returns all the operations from the module with their respective weights
|
||||
|
@ -36,91 +47,91 @@ func WeightedOperations(
|
|||
appParams simtypes.AppParams, cdc codec.JSONCodec, ak authz.AccountKeeper, bk authz.BankKeeper, k keeper.Keeper, appCdc cdctypes.AnyUnpacker, protoCdc *codec.ProtoCodec) simulation.WeightedOperations {
|
||||
|
||||
var (
|
||||
weightMsgGrantAuthorization int
|
||||
weightRevokeAuthorization int
|
||||
weightExecAuthorized int
|
||||
weightMsgGrant int
|
||||
weightRevoke int
|
||||
weightExec int
|
||||
)
|
||||
|
||||
appParams.GetOrGenerate(cdc, OpWeightMsgGrantAuthorization, &weightMsgGrantAuthorization, nil,
|
||||
appParams.GetOrGenerate(cdc, OpWeightMsgGrant, &weightMsgGrant, nil,
|
||||
func(_ *rand.Rand) {
|
||||
weightMsgGrantAuthorization = simappparams.DefaultWeightMsgDelegate
|
||||
weightMsgGrant = WeightGrant
|
||||
},
|
||||
)
|
||||
|
||||
appParams.GetOrGenerate(cdc, OpWeightRevokeAuthorization, &weightRevokeAuthorization, nil,
|
||||
appParams.GetOrGenerate(cdc, OpWeightRevoke, &weightRevoke, nil,
|
||||
func(_ *rand.Rand) {
|
||||
weightRevokeAuthorization = simappparams.DefaultWeightMsgUndelegate
|
||||
weightRevoke = WeightRevoke
|
||||
},
|
||||
)
|
||||
|
||||
appParams.GetOrGenerate(cdc, OpWeightExecAuthorized, &weightExecAuthorized, nil,
|
||||
appParams.GetOrGenerate(cdc, OpWeightExec, &weightExec, nil,
|
||||
func(_ *rand.Rand) {
|
||||
weightExecAuthorized = simappparams.DefaultWeightMsgSend
|
||||
weightExec = WeightExec
|
||||
},
|
||||
)
|
||||
|
||||
return simulation.WeightedOperations{
|
||||
simulation.NewWeightedOperation(
|
||||
weightMsgGrantAuthorization,
|
||||
SimulateMsgGrantAuthorization(ak, bk, k, protoCdc),
|
||||
weightMsgGrant,
|
||||
SimulateMsgGrant(ak, bk, k, protoCdc),
|
||||
),
|
||||
simulation.NewWeightedOperation(
|
||||
weightRevokeAuthorization,
|
||||
SimulateMsgRevokeAuthorization(ak, bk, k, protoCdc),
|
||||
weightRevoke,
|
||||
SimulateMsgRevoke(ak, bk, k, protoCdc),
|
||||
),
|
||||
simulation.NewWeightedOperation(
|
||||
weightExecAuthorized,
|
||||
SimulateMsgExecuteAuthorized(ak, bk, k, appCdc, protoCdc),
|
||||
weightExec,
|
||||
SimulateMsgExec(ak, bk, k, appCdc, protoCdc),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
// SimulateMsgGrantAuthorization generates a MsgGrantAuthorization with random values.
|
||||
// nolint: funlen
|
||||
func SimulateMsgGrantAuthorization(ak authz.AccountKeeper, bk authz.BankKeeper, _ keeper.Keeper,
|
||||
// SimulateMsgGrant generates a MsgGrant with random values.
|
||||
func SimulateMsgGrant(ak authz.AccountKeeper, bk authz.BankKeeper, _ keeper.Keeper,
|
||||
protoCdc *codec.ProtoCodec) simtypes.Operation {
|
||||
return func(
|
||||
r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string,
|
||||
) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
|
||||
granter := accs[0]
|
||||
grantee := accs[1]
|
||||
granter, _ := simtypes.RandomAcc(r, accs)
|
||||
grantee, _ := simtypes.RandomAcc(r, accs)
|
||||
|
||||
account := ak.GetAccount(ctx, granter.Address)
|
||||
if granter.Address.Equals(grantee.Address) {
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgGrant, "granter and grantee are same"), nil, nil
|
||||
}
|
||||
|
||||
spendableCoins := bk.SpendableCoins(ctx, account.GetAddress())
|
||||
granterAcc := ak.GetAccount(ctx, granter.Address)
|
||||
spendableCoins := bk.SpendableCoins(ctx, granter.Address)
|
||||
fees, err := simtypes.RandomFees(r, ctx, spendableCoins)
|
||||
if err != nil {
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgGrantAuthorization, err.Error()), nil, err
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgGrant, err.Error()), nil, err
|
||||
}
|
||||
|
||||
blockTime := ctx.BlockTime()
|
||||
spendLimit := spendableCoins.Sub(fees)
|
||||
if spendLimit == nil {
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgGrantAuthorization, "spend limit is nil"), nil, nil
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgGrant, "spend limit is nil"), nil, nil
|
||||
}
|
||||
msg, err := authz.NewMsgGrant(granter.Address, grantee.Address,
|
||||
banktype.NewSendAuthorization(spendLimit), blockTime.AddDate(1, 0, 0))
|
||||
|
||||
expiration := ctx.BlockTime().AddDate(1, 0, 0)
|
||||
msg, err := authz.NewMsgGrant(granter.Address, grantee.Address, generateRandomAuthorization(r, spendLimit), expiration)
|
||||
if err != nil {
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgGrantAuthorization, err.Error()), nil, err
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgGrant, err.Error()), nil, err
|
||||
}
|
||||
txGen := simappparams.MakeTestEncodingConfig().TxConfig
|
||||
txCfg := simappparams.MakeTestEncodingConfig().TxConfig
|
||||
tx, err := helpers.GenTx(
|
||||
txGen,
|
||||
txCfg,
|
||||
[]sdk.Msg{msg},
|
||||
fees,
|
||||
helpers.DefaultGenTxGas,
|
||||
chainID,
|
||||
[]uint64{account.GetAccountNumber()},
|
||||
[]uint64{account.GetSequence()},
|
||||
[]uint64{granterAcc.GetAccountNumber()},
|
||||
[]uint64{granterAcc.GetSequence()},
|
||||
granter.PrivKey,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgGrantAuthorization, "unable to generate mock tx"), nil, err
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgGrant, "unable to generate mock tx"), nil, err
|
||||
}
|
||||
|
||||
_, _, err = app.Deliver(txGen.TxEncoder(), tx)
|
||||
_, _, err = app.Deliver(txCfg.TxEncoder(), tx)
|
||||
if err != nil {
|
||||
return simtypes.NoOpMsg(authz.ModuleName, sdk.MsgTypeURL(msg), "unable to deliver tx"), nil, err
|
||||
}
|
||||
|
@ -128,18 +139,25 @@ func SimulateMsgGrantAuthorization(ak authz.AccountKeeper, bk authz.BankKeeper,
|
|||
}
|
||||
}
|
||||
|
||||
// SimulateMsgRevokeAuthorization generates a MsgRevokeAuthorization with random values.
|
||||
// nolint: funlen
|
||||
func SimulateMsgRevokeAuthorization(ak authz.AccountKeeper, bk authz.BankKeeper, k keeper.Keeper, protoCdc *codec.ProtoCodec) simtypes.Operation {
|
||||
func generateRandomAuthorization(r *rand.Rand, spendLimit sdk.Coins) authz.Authorization {
|
||||
authorizations := make([]authz.Authorization, 2)
|
||||
authorizations[0] = banktype.NewSendAuthorization(spendLimit)
|
||||
authorizations[1] = authz.NewGenericAuthorization(sdk.MsgTypeURL(&banktype.MsgSend{}))
|
||||
|
||||
return authorizations[r.Intn(len(authorizations))]
|
||||
}
|
||||
|
||||
// SimulateMsgRevoke generates a MsgRevoke with random values.
|
||||
func SimulateMsgRevoke(ak authz.AccountKeeper, bk authz.BankKeeper, k keeper.Keeper, protoCdc *codec.ProtoCodec) simtypes.Operation {
|
||||
return func(
|
||||
r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string,
|
||||
) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
|
||||
var granterAddr, granteeAddr sdk.AccAddress
|
||||
var grant authz.Grant
|
||||
hasGrant := false
|
||||
var targetGrant authz.Grant
|
||||
var granterAddr sdk.AccAddress
|
||||
var granteeAddr sdk.AccAddress
|
||||
k.IterateGrants(ctx, func(granter, grantee sdk.AccAddress, grant authz.Grant) bool {
|
||||
targetGrant = grant
|
||||
|
||||
k.IterateGrants(ctx, func(granter, grantee sdk.AccAddress, g authz.Grant) bool {
|
||||
grant = g
|
||||
granterAddr = granter
|
||||
granteeAddr = grantee
|
||||
hasGrant = true
|
||||
|
@ -147,51 +165,52 @@ func SimulateMsgRevokeAuthorization(ak authz.AccountKeeper, bk authz.BankKeeper,
|
|||
})
|
||||
|
||||
if !hasGrant {
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgRevokeAuthorization, "no grants"), nil, nil
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgRevoke, "no grants"), nil, nil
|
||||
}
|
||||
|
||||
granter, ok := simtypes.FindAccount(accs, granterAddr)
|
||||
granterAcc, ok := simtypes.FindAccount(accs, granterAddr)
|
||||
if !ok {
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgRevokeAuthorization, "Account not found"), nil, nil
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgRevoke, "account not found"), nil, sdkerrors.Wrapf(sdkerrors.ErrNotFound, "account not found")
|
||||
}
|
||||
account := ak.GetAccount(ctx, granter.Address)
|
||||
|
||||
spendableCoins := bk.SpendableCoins(ctx, account.GetAddress())
|
||||
spendableCoins := bk.SpendableCoins(ctx, granterAddr)
|
||||
fees, err := simtypes.RandomFees(r, ctx, spendableCoins)
|
||||
if err != nil {
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgRevokeAuthorization, "fee error"), nil, err
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgRevoke, "fee error"), nil, err
|
||||
}
|
||||
|
||||
auth := targetGrant.GetAuthorization()
|
||||
msg := authz.NewMsgRevoke(granterAddr, granteeAddr, auth.MsgTypeURL())
|
||||
txGen := simappparams.MakeTestEncodingConfig().TxConfig
|
||||
a := grant.GetAuthorization()
|
||||
msg := authz.NewMsgRevoke(granterAddr, granteeAddr, a.MsgTypeURL())
|
||||
txCfg := simappparams.MakeTestEncodingConfig().TxConfig
|
||||
account := ak.GetAccount(ctx, granterAddr)
|
||||
tx, err := helpers.GenTx(
|
||||
txGen,
|
||||
txCfg,
|
||||
[]sdk.Msg{&msg},
|
||||
fees,
|
||||
helpers.DefaultGenTxGas,
|
||||
chainID,
|
||||
[]uint64{account.GetAccountNumber()},
|
||||
[]uint64{account.GetSequence()},
|
||||
granter.PrivKey,
|
||||
granterAcc.PrivKey,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgRevokeAuthorization, err.Error()), nil, err
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgRevoke, err.Error()), nil, err
|
||||
}
|
||||
|
||||
_, _, err = app.Deliver(txGen.TxEncoder(), tx)
|
||||
return simtypes.NewOperationMsg(&msg, true, "", protoCdc), nil, err
|
||||
_, _, err = app.Deliver(txCfg.TxEncoder(), tx)
|
||||
if err != nil {
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgRevoke, "unable to deliver tx"), nil, err
|
||||
}
|
||||
|
||||
return simtypes.NewOperationMsg(&msg, true, "", protoCdc), nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
// SimulateMsgExecuteAuthorized generates a MsgExecuteAuthorized with random values.
|
||||
// nolint: funlen
|
||||
func SimulateMsgExecuteAuthorized(ak authz.AccountKeeper, bk authz.BankKeeper, k keeper.Keeper, cdc cdctypes.AnyUnpacker, protoCdc *codec.ProtoCodec) simtypes.Operation {
|
||||
// SimulateMsgExec generates a MsgExec with random values.
|
||||
func SimulateMsgExec(ak authz.AccountKeeper, bk authz.BankKeeper, k keeper.Keeper, cdc cdctypes.AnyUnpacker, protoCdc *codec.ProtoCodec) simtypes.Operation {
|
||||
return func(
|
||||
r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context, accs []simtypes.Account, chainID string,
|
||||
) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
|
||||
|
||||
hasGrant := false
|
||||
var targetGrant authz.Grant
|
||||
var granterAddr sdk.AccAddress
|
||||
|
@ -205,67 +224,73 @@ func SimulateMsgExecuteAuthorized(ak authz.AccountKeeper, bk authz.BankKeeper, k
|
|||
})
|
||||
|
||||
if !hasGrant {
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExecDelegated, "Not found"), nil, nil
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExec, "no grant found"), nil, nil
|
||||
}
|
||||
|
||||
grantee, _ := simtypes.FindAccount(accs, granteeAddr)
|
||||
granterAccount := ak.GetAccount(ctx, granterAddr)
|
||||
granteeAccount := ak.GetAccount(ctx, granteeAddr)
|
||||
grantee, ok := simtypes.FindAccount(accs, granteeAddr)
|
||||
if !ok {
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgRevoke, "Account not found"), nil, sdkerrors.Wrapf(sdkerrors.ErrNotFound, "grantee account not found")
|
||||
}
|
||||
|
||||
granterspendableCoins := bk.SpendableCoins(ctx, granterAccount.GetAddress())
|
||||
if granterspendableCoins.Empty() {
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExecDelegated, "no coins"), nil, nil
|
||||
if _, ok := simtypes.FindAccount(accs, granterAddr); !ok {
|
||||
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, TypeMsgExecDelegated, "grant expired"), nil, nil
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExec, "grant expired"), nil, nil
|
||||
}
|
||||
|
||||
granteespendableCoins := bk.SpendableCoins(ctx, granteeAccount.GetAddress())
|
||||
fees, err := simtypes.RandomFees(r, ctx, granteespendableCoins)
|
||||
coins := sdk.NewCoins(sdk.NewCoin("stake", sdk.NewInt(int64(simtypes.RandIntBetween(r, 100, 1000000)))))
|
||||
|
||||
// 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
|
||||
}
|
||||
}
|
||||
|
||||
granterspendableCoins := bk.SpendableCoins(ctx, granterAddr)
|
||||
if granterspendableCoins.IsAllLTE(coins) {
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExec, "insufficient funds"), nil, nil
|
||||
}
|
||||
|
||||
granteeSpendableCoins := bk.SpendableCoins(ctx, granteeAddr)
|
||||
fees, err := simtypes.RandomFees(r, ctx, granteeSpendableCoins)
|
||||
if err != nil {
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExecDelegated, "fee error"), nil, err
|
||||
}
|
||||
sendCoins := sdk.NewCoins(sdk.NewCoin("foo", sdk.NewInt(10)))
|
||||
|
||||
execMsg := banktype.NewMsgSend(
|
||||
granterAddr,
|
||||
granteeAddr,
|
||||
sendCoins,
|
||||
)
|
||||
|
||||
msg := authz.NewMsgExec(grantee.Address, []sdk.Msg{execMsg})
|
||||
sendGrant := targetGrant.Authorization.GetCachedValue().(*banktype.SendAuthorization)
|
||||
_, err = sendGrant.Accept(ctx, execMsg)
|
||||
if err != nil {
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExecDelegated, err.Error()), nil, nil
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExec, "fee error"), nil, err
|
||||
}
|
||||
|
||||
txGen := simappparams.MakeTestEncodingConfig().TxConfig
|
||||
msg := authz.NewMsgExec(granteeAddr, []sdk.Msg{banktype.NewMsgSend(granterAddr, granteeAddr, coins)})
|
||||
txCfg := simappparams.MakeTestEncodingConfig().TxConfig
|
||||
granteeAcc := ak.GetAccount(ctx, granteeAddr)
|
||||
|
||||
tx, err := helpers.GenTx(
|
||||
txGen,
|
||||
txCfg,
|
||||
[]sdk.Msg{&msg},
|
||||
fees,
|
||||
helpers.DefaultGenTxGas,
|
||||
chainID,
|
||||
[]uint64{granteeAccount.GetAccountNumber()},
|
||||
[]uint64{granteeAccount.GetSequence()},
|
||||
[]uint64{granteeAcc.GetAccountNumber()},
|
||||
[]uint64{granteeAcc.GetSequence()},
|
||||
grantee.PrivKey,
|
||||
)
|
||||
if err != nil {
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExec, err.Error()), nil, err
|
||||
}
|
||||
|
||||
_, _, err = app.Deliver(txCfg.TxEncoder(), tx)
|
||||
if err != nil {
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExecDelegated, err.Error()), nil, err
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExec, err.Error()), nil, err
|
||||
}
|
||||
_, _, err = app.Deliver(txGen.TxEncoder(), tx)
|
||||
|
||||
err = msg.UnpackInterfaces(cdc)
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "insufficient fee") {
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExecDelegated, "insufficient fee"), nil, nil
|
||||
}
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExecDelegated, err.Error()), nil, err
|
||||
}
|
||||
msg.UnpackInterfaces(cdc)
|
||||
if err != nil {
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExecDelegated, "unmarshal error"), nil, err
|
||||
return simtypes.NoOpMsg(authz.ModuleName, TypeMsgExec, "unmarshal error"), nil, err
|
||||
}
|
||||
return simtypes.NewOperationMsg(&msg, true, "success", protoCdc), nil, nil
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ import (
|
|||
|
||||
"github.com/cosmos/cosmos-sdk/codec"
|
||||
"github.com/cosmos/cosmos-sdk/simapp"
|
||||
simappparams "github.com/cosmos/cosmos-sdk/simapp/params"
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
|
||||
"github.com/cosmos/cosmos-sdk/x/authz"
|
||||
|
@ -54,9 +53,9 @@ func (suite *SimTestSuite) TestWeightedOperations() {
|
|||
opMsgRoute string
|
||||
opMsgName string
|
||||
}{
|
||||
{simappparams.DefaultWeightMsgDelegate, authz.ModuleName, simulation.TypeMsgGrantAuthorization},
|
||||
{simappparams.DefaultWeightMsgUndelegate, authz.ModuleName, simulation.TypeMsgRevokeAuthorization},
|
||||
{simappparams.DefaultWeightMsgSend, authz.ModuleName, simulation.TypeMsgExecDelegated},
|
||||
{simulation.WeightGrant, authz.ModuleName, simulation.TypeMsgGrant},
|
||||
{simulation.WeightRevoke, authz.ModuleName, simulation.TypeMsgRevoke},
|
||||
{simulation.WeightExec, authz.ModuleName, simulation.TypeMsgExec},
|
||||
}
|
||||
|
||||
for i, w := range weightesOps {
|
||||
|
@ -74,7 +73,7 @@ func (suite *SimTestSuite) getTestingAccounts(r *rand.Rand, n int) []simtypes.Ac
|
|||
accounts := simtypes.RandomAccounts(r, n)
|
||||
|
||||
initAmt := suite.app.StakingKeeper.TokensFromConsensusPower(suite.ctx, 200000)
|
||||
initCoins := sdk.NewCoins(sdk.NewCoin("foo", initAmt))
|
||||
initCoins := sdk.NewCoins(sdk.NewCoin("stake", initAmt))
|
||||
|
||||
// add coins to the accounts
|
||||
for _, account := range accounts {
|
||||
|
@ -86,8 +85,7 @@ func (suite *SimTestSuite) getTestingAccounts(r *rand.Rand, n int) []simtypes.Ac
|
|||
return accounts
|
||||
}
|
||||
|
||||
func (suite *SimTestSuite) TestSimulateGrantAuthorization() {
|
||||
// setup 3 accounts
|
||||
func (suite *SimTestSuite) TestSimulateGrant() {
|
||||
s := rand.NewSource(1)
|
||||
r := rand.New(s)
|
||||
accounts := suite.getTestingAccounts(r, 2)
|
||||
|
@ -106,7 +104,7 @@ func (suite *SimTestSuite) TestSimulateGrantAuthorization() {
|
|||
grantee := accounts[1]
|
||||
|
||||
// execute operation
|
||||
op := simulation.SimulateMsgGrantAuthorization(suite.app.AccountKeeper, suite.app.BankKeeper, suite.app.AuthzKeeper, suite.protoCdc)
|
||||
op := simulation.SimulateMsgGrant(suite.app.AccountKeeper, suite.app.BankKeeper, suite.app.AuthzKeeper, suite.protoCdc)
|
||||
operationMsg, futureOperations, err := op(r, suite.app.BaseApp, ctx, accounts, "")
|
||||
suite.Require().NoError(err)
|
||||
|
||||
|
@ -119,9 +117,9 @@ func (suite *SimTestSuite) TestSimulateGrantAuthorization() {
|
|||
|
||||
}
|
||||
|
||||
func (suite *SimTestSuite) TestSimulateRevokeAuthorization() {
|
||||
func (suite *SimTestSuite) TestSimulateRevoke() {
|
||||
// setup 3 accounts
|
||||
s := rand.NewSource(1)
|
||||
s := rand.NewSource(2)
|
||||
r := rand.New(s)
|
||||
accounts := suite.getTestingAccounts(r, 3)
|
||||
|
||||
|
@ -133,7 +131,7 @@ func (suite *SimTestSuite) TestSimulateRevokeAuthorization() {
|
|||
}})
|
||||
|
||||
initAmt := suite.app.StakingKeeper.TokensFromConsensusPower(suite.ctx, 200000)
|
||||
initCoins := sdk.NewCoins(sdk.NewCoin("foo", initAmt))
|
||||
initCoins := sdk.NewCoins(sdk.NewCoin("stake", initAmt))
|
||||
|
||||
granter := accounts[0]
|
||||
grantee := accounts[1]
|
||||
|
@ -143,7 +141,7 @@ func (suite *SimTestSuite) TestSimulateRevokeAuthorization() {
|
|||
suite.Require().NoError(err)
|
||||
|
||||
// execute operation
|
||||
op := simulation.SimulateMsgRevokeAuthorization(suite.app.AccountKeeper, suite.app.BankKeeper, suite.app.AuthzKeeper, suite.protoCdc)
|
||||
op := simulation.SimulateMsgRevoke(suite.app.AccountKeeper, suite.app.BankKeeper, suite.app.AuthzKeeper, suite.protoCdc)
|
||||
operationMsg, futureOperations, err := op(r, suite.app.BaseApp, suite.ctx, accounts, "")
|
||||
suite.Require().NoError(err)
|
||||
|
||||
|
@ -158,7 +156,7 @@ func (suite *SimTestSuite) TestSimulateRevokeAuthorization() {
|
|||
|
||||
}
|
||||
|
||||
func (suite *SimTestSuite) TestSimulateExecAuthorization() {
|
||||
func (suite *SimTestSuite) TestSimulateExec() {
|
||||
// setup 3 accounts
|
||||
s := rand.NewSource(1)
|
||||
r := rand.New(s)
|
||||
|
@ -168,7 +166,7 @@ func (suite *SimTestSuite) TestSimulateExecAuthorization() {
|
|||
suite.app.BeginBlock(abci.RequestBeginBlock{Header: tmproto.Header{Height: suite.app.LastBlockHeight() + 1, AppHash: suite.app.LastCommitID().Hash}})
|
||||
|
||||
initAmt := suite.app.StakingKeeper.TokensFromConsensusPower(suite.ctx, 200000)
|
||||
initCoins := sdk.NewCoins(sdk.NewCoin("foo", initAmt))
|
||||
initCoins := sdk.NewCoins(sdk.NewCoin("stake", initAmt))
|
||||
|
||||
granter := accounts[0]
|
||||
grantee := accounts[1]
|
||||
|
@ -178,7 +176,7 @@ func (suite *SimTestSuite) TestSimulateExecAuthorization() {
|
|||
suite.Require().NoError(err)
|
||||
|
||||
// execute operation
|
||||
op := simulation.SimulateMsgExecuteAuthorized(suite.app.AccountKeeper, suite.app.BankKeeper, suite.app.AuthzKeeper, suite.app.AppCodec(), suite.protoCdc)
|
||||
op := simulation.SimulateMsgExec(suite.app.AccountKeeper, suite.app.BankKeeper, suite.app.AuthzKeeper, suite.app.AppCodec(), suite.protoCdc)
|
||||
operationMsg, futureOperations, err := op(r, suite.app.BaseApp, suite.ctx, accounts, "")
|
||||
suite.Require().NoError(err)
|
||||
|
||||
|
|
Loading…
Reference in New Issue