99 lines
3.5 KiB
Go
99 lines
3.5 KiB
Go
package simulation
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"time"
|
|
|
|
sdkmath "cosmossdk.io/math"
|
|
|
|
"github.com/cosmos/cosmos-sdk/testutil/simsx"
|
|
"github.com/cosmos/cosmos-sdk/x/slashing/keeper"
|
|
"github.com/cosmos/cosmos-sdk/x/slashing/types"
|
|
)
|
|
|
|
func MsgUnjailFactory(k keeper.Keeper, sk types.StakingKeeper) simsx.SimMsgFactoryX {
|
|
return simsx.NewSimMsgFactoryWithDeliveryResultHandler[*types.MsgUnjail](func(ctx context.Context, testData *simsx.ChainDataSource, reporter simsx.SimulationReporter) ([]simsx.SimAccount, *types.MsgUnjail, simsx.SimDeliveryResultHandler) {
|
|
allVals, err := sk.GetAllValidators(ctx)
|
|
if err != nil {
|
|
reporter.Skip(err.Error())
|
|
return nil, nil, nil
|
|
}
|
|
validator := simsx.OneOf(testData.Rand(), allVals)
|
|
if !validator.IsJailed() {
|
|
reporter.Skip("validator not jailed")
|
|
return nil, nil, nil
|
|
}
|
|
if validator.InvalidExRate() {
|
|
reporter.Skip("validator with invalid exchange rate")
|
|
return nil, nil, nil
|
|
}
|
|
|
|
info, err := k.GetValidatorSigningInfo(ctx, must(validator.GetConsAddr()))
|
|
if err != nil {
|
|
reporter.Skip(err.Error())
|
|
return nil, nil, nil
|
|
}
|
|
valOperBz := must(sk.ValidatorAddressCodec().StringToBytes(validator.GetOperator()))
|
|
valOper := testData.GetAccountbyAccAddr(reporter, valOperBz)
|
|
if reporter.IsSkipped() {
|
|
return nil, nil, nil
|
|
}
|
|
|
|
selfDel, err := sk.Delegation(ctx, valOper.Address, valOperBz)
|
|
if selfDel == nil || err != nil {
|
|
reporter.Skip("no self delegation")
|
|
return nil, nil, nil
|
|
}
|
|
var handler simsx.SimDeliveryResultHandler
|
|
// result should fail if:
|
|
// - validator cannot be unjailed due to tombstone
|
|
// - validator is still in jailed period
|
|
// - self delegation too low
|
|
if info.Tombstoned ||
|
|
simsx.BlockTime(ctx).Before(info.JailedUntil) ||
|
|
selfDel.GetShares().IsNil() ||
|
|
validator.TokensFromShares(selfDel.GetShares()).TruncateInt().LT(validator.GetMinSelfDelegation()) {
|
|
handler = func(err error) error {
|
|
if err == nil {
|
|
switch {
|
|
case info.Tombstoned:
|
|
return errors.New("validator should not have been unjailed if validator tombstoned")
|
|
case simsx.BlockTime(ctx).Before(info.JailedUntil):
|
|
return errors.New("validator unjailed while validator still in jail period")
|
|
case selfDel.GetShares().IsNil() || validator.TokensFromShares(selfDel.GetShares()).TruncateInt().LT(validator.GetMinSelfDelegation()):
|
|
return errors.New("validator unjailed even though self-delegation too low")
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
}
|
|
return []simsx.SimAccount{valOper}, types.NewMsgUnjail(validator.GetOperator()), handler
|
|
})
|
|
}
|
|
|
|
// MsgUpdateParamsFactory creates a gov proposal for param updates
|
|
func MsgUpdateParamsFactory() simsx.SimMsgFactoryFn[*types.MsgUpdateParams] {
|
|
return func(_ context.Context, testData *simsx.ChainDataSource, reporter simsx.SimulationReporter) ([]simsx.SimAccount, *types.MsgUpdateParams) {
|
|
r := testData.Rand()
|
|
params := types.DefaultParams()
|
|
params.DowntimeJailDuration = time.Duration(r.Timestamp().UnixNano())
|
|
params.SignedBlocksWindow = int64(r.IntInRange(1, 1000))
|
|
params.MinSignedPerWindow = sdkmath.LegacyNewDecWithPrec(int64(r.IntInRange(1, 100)), 2)
|
|
params.SlashFractionDoubleSign = sdkmath.LegacyNewDecWithPrec(int64(r.IntInRange(1, 100)), 2)
|
|
params.SlashFractionDowntime = sdkmath.LegacyNewDecWithPrec(int64(r.IntInRange(1, 100)), 2)
|
|
|
|
return nil, &types.MsgUpdateParams{
|
|
Authority: testData.ModuleAccountAddress(reporter, "gov"),
|
|
Params: params,
|
|
}
|
|
}
|
|
}
|
|
|
|
func must[T any](r T, err error) T {
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return r
|
|
}
|