cosmos-sdk/x/slashing/simulation/operations.go
cool-developer 372a8f194e
refactor: remove simapp from x/staking module (#13101)
## Description

Closes: #13099 



---

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

- [ ] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title
- [ ] added `!` to the type prefix if API or client breaking change
- [ ] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/main/CONTRIBUTING.md#pr-targeting))
- [ ] provided a link to the relevant issue or specification
- [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/main/docs/building-modules)
- [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/main/CONTRIBUTING.md#testing)
- [ ] added a changelog entry to `CHANGELOG.md`
- [ ] included comments for [documenting Go code](https://blog.golang.org/godoc)
- [ ] updated the relevant documentation or specification
- [ ] 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)
2022-08-31 14:50:22 +00:00

141 lines
5.1 KiB
Go

package simulation
import (
"errors"
"math/rand"
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/codec"
codectypes "github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/testutil"
simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
sdk "github.com/cosmos/cosmos-sdk/types"
simtypes "github.com/cosmos/cosmos-sdk/types/simulation"
"github.com/cosmos/cosmos-sdk/x/auth/tx"
"github.com/cosmos/cosmos-sdk/x/simulation"
"github.com/cosmos/cosmos-sdk/x/slashing/keeper"
"github.com/cosmos/cosmos-sdk/x/slashing/types"
)
// Simulation operation weights constants
//
//nolint:gosec // these are not hardcoded credentials.
const (
OpWeightMsgUnjail = "op_weight_msg_unjail"
DefaultWeightMsgUnjail = 100
)
// WeightedOperations returns all the operations from the module with their respective weights
func WeightedOperations(
appParams simtypes.AppParams, cdc codec.JSONCodec, ak types.AccountKeeper,
bk types.BankKeeper, k keeper.Keeper, sk types.StakingKeeper,
) simulation.WeightedOperations {
interfaceRegistry := codectypes.NewInterfaceRegistry()
var weightMsgUnjail int
appParams.GetOrGenerate(cdc, OpWeightMsgUnjail, &weightMsgUnjail, nil,
func(_ *rand.Rand) {
weightMsgUnjail = DefaultWeightMsgUnjail
},
)
return simulation.WeightedOperations{
simulation.NewWeightedOperation(
weightMsgUnjail,
SimulateMsgUnjail(codec.NewProtoCodec(interfaceRegistry), ak, bk, k, sk),
),
}
}
// SimulateMsgUnjail generates a MsgUnjail with random values
func SimulateMsgUnjail(cdc *codec.ProtoCodec, ak types.AccountKeeper, bk types.BankKeeper, k keeper.Keeper, sk types.StakingKeeper) simtypes.Operation {
return func(
r *rand.Rand, app *baseapp.BaseApp, ctx sdk.Context,
accs []simtypes.Account, chainID string,
) (simtypes.OperationMsg, []simtypes.FutureOperation, error) {
validator, ok := testutil.RandSliceElem(r, sk.GetAllValidators(ctx))
if !ok {
return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgUnjail, "validator is not ok"), nil, nil // skip
}
simAccount, found := simtypes.FindAccount(accs, sdk.AccAddress(validator.GetOperator()))
if !found {
return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgUnjail, "unable to find account"), nil, nil // skip
}
if !validator.IsJailed() {
// TODO: due to this condition this message is almost, if not always, skipped !
return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgUnjail, "validator is not jailed"), nil, nil
}
consAddr, err := validator.GetConsAddr()
if err != nil {
return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgUnjail, "unable to get validator consensus key"), nil, err
}
info, found := k.GetValidatorSigningInfo(ctx, consAddr)
if !found {
return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgUnjail, "unable to find validator signing info"), nil, nil // skip
}
selfDel := sk.Delegation(ctx, simAccount.Address, validator.GetOperator())
if selfDel == nil {
return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgUnjail, "self delegation is nil"), nil, nil // skip
}
account := ak.GetAccount(ctx, sdk.AccAddress(validator.GetOperator()))
spendable := bk.SpendableCoins(ctx, account.GetAddress())
fees, err := simtypes.RandomFees(r, ctx, spendable)
if err != nil {
return simtypes.NoOpMsg(types.ModuleName, types.TypeMsgUnjail, "unable to generate fees"), nil, err
}
msg := types.NewMsgUnjail(validator.GetOperator())
txGen := tx.NewTxConfig(cdc, tx.DefaultSignModes)
tx, err := simtestutil.GenSignedMockTx(
r,
txGen,
[]sdk.Msg{msg},
fees,
simtestutil.DefaultGenTxGas,
chainID,
[]uint64{account.GetAccountNumber()},
[]uint64{account.GetSequence()},
simAccount.PrivKey,
)
if err != nil {
return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to generate mock tx"), nil, err
}
_, res, err := app.SimDeliver(txGen.TxEncoder(), tx)
// result should fail if:
// - validator cannot be unjailed due to tombstone
// - validator is still in jailed period
// - self delegation too low
if info.Tombstoned ||
ctx.BlockHeader().Time.Before(info.JailedUntil) ||
validator.TokensFromShares(selfDel.GetShares()).TruncateInt().LT(validator.GetMinSelfDelegation()) {
if res != nil && err == nil {
if info.Tombstoned {
return simtypes.NewOperationMsg(msg, true, "", nil), nil, errors.New("validator should not have been unjailed if validator tombstoned")
}
if ctx.BlockHeader().Time.Before(info.JailedUntil) {
return simtypes.NewOperationMsg(msg, true, "", nil), nil, errors.New("validator unjailed while validator still in jail period")
}
if validator.TokensFromShares(selfDel.GetShares()).TruncateInt().LT(validator.GetMinSelfDelegation()) {
return simtypes.NewOperationMsg(msg, true, "", nil), nil, errors.New("validator unjailed even though self-delegation too low")
}
}
// msg failed as expected
return simtypes.NewOperationMsg(msg, false, "", nil), nil, nil
}
if err != nil {
return simtypes.NoOpMsg(types.ModuleName, msg.Type(), "unable to deliver tx"), nil, errors.New(res.Log)
}
return simtypes.NewOperationMsg(msg, true, "", nil), nil, nil
}
}