github.com/cosmos/cosmos-sdk@v0.50.10/x/staking/testutil/helpers.go (about) 1 package testutil 2 3 import ( 4 "context" 5 "testing" 6 "time" 7 8 "github.com/stretchr/testify/require" 9 10 "cosmossdk.io/math" 11 12 cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" 13 sdk "github.com/cosmos/cosmos-sdk/types" 14 "github.com/cosmos/cosmos-sdk/x/staking/keeper" 15 stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types" 16 ) 17 18 // Helper is a structure which wraps the staking message server 19 // and provides methods useful in tests 20 type Helper struct { 21 t *testing.T 22 msgSrvr stakingtypes.MsgServer 23 k *keeper.Keeper 24 25 Ctx sdk.Context 26 Commission stakingtypes.CommissionRates 27 // Coin Denomination 28 Denom string 29 } 30 31 // NewHelper creates a new instance of Helper. 32 func NewHelper(t *testing.T, ctx sdk.Context, k *keeper.Keeper) *Helper { 33 return &Helper{t, keeper.NewMsgServerImpl(k), k, ctx, ZeroCommission(), sdk.DefaultBondDenom} 34 } 35 36 // CreateValidator calls staking module `MsgServer/CreateValidator` to create a new validator 37 func (sh *Helper) CreateValidator(addr sdk.ValAddress, pk cryptotypes.PubKey, stakeAmount math.Int, ok bool) { 38 coin := sdk.NewCoin(sh.Denom, stakeAmount) 39 sh.createValidator(addr, pk, coin, ok) 40 } 41 42 // CreateValidatorWithValPower calls staking module `MsgServer/CreateValidator` to create a new validator with zero 43 // commission 44 func (sh *Helper) CreateValidatorWithValPower(addr sdk.ValAddress, pk cryptotypes.PubKey, valPower int64, ok bool) math.Int { 45 amount := sh.k.TokensFromConsensusPower(sh.Ctx, valPower) 46 coin := sdk.NewCoin(sh.Denom, amount) 47 sh.createValidator(addr, pk, coin, ok) 48 return amount 49 } 50 51 // CreateValidatorMsg returns a message used to create validator in this service. 52 func (sh *Helper) CreateValidatorMsg(addr sdk.ValAddress, pk cryptotypes.PubKey, stakeAmount math.Int) *stakingtypes.MsgCreateValidator { 53 coin := sdk.NewCoin(sh.Denom, stakeAmount) 54 msg, err := stakingtypes.NewMsgCreateValidator(addr.String(), pk, coin, stakingtypes.Description{}, sh.Commission, math.OneInt()) 55 require.NoError(sh.t, err) 56 return msg 57 } 58 59 // CreateValidatorWithMsg calls staking module `MsgServer/CreateValidator` 60 func (sh *Helper) CreateValidatorWithMsg(ctx context.Context, msg *stakingtypes.MsgCreateValidator) (*stakingtypes.MsgCreateValidatorResponse, error) { 61 return sh.msgSrvr.CreateValidator(ctx, msg) 62 } 63 64 func (sh *Helper) createValidator(addr sdk.ValAddress, pk cryptotypes.PubKey, coin sdk.Coin, ok bool) { 65 msg, err := stakingtypes.NewMsgCreateValidator(addr.String(), pk, coin, stakingtypes.Description{Moniker: "TestValidator"}, sh.Commission, math.OneInt()) 66 require.NoError(sh.t, err) 67 res, err := sh.msgSrvr.CreateValidator(sh.Ctx, msg) 68 if ok { 69 require.NoError(sh.t, err) 70 require.NotNil(sh.t, res) 71 } else { 72 require.Error(sh.t, err) 73 require.Nil(sh.t, res) 74 } 75 } 76 77 // Delegate calls staking module staking module `MsgServer/Delegate` to delegate stake for a validator 78 func (sh *Helper) Delegate(delegator sdk.AccAddress, val sdk.ValAddress, amount math.Int) { 79 coin := sdk.NewCoin(sh.Denom, amount) 80 msg := stakingtypes.NewMsgDelegate(delegator.String(), val.String(), coin) 81 res, err := sh.msgSrvr.Delegate(sh.Ctx, msg) 82 require.NoError(sh.t, err) 83 require.NotNil(sh.t, res) 84 } 85 86 // DelegateWithPower calls staking module `MsgServer/Delegate` to delegate stake for a validator 87 func (sh *Helper) DelegateWithPower(delegator sdk.AccAddress, val sdk.ValAddress, power int64) { 88 coin := sdk.NewCoin(sh.Denom, sh.k.TokensFromConsensusPower(sh.Ctx, power)) 89 msg := stakingtypes.NewMsgDelegate(delegator.String(), val.String(), coin) 90 res, err := sh.msgSrvr.Delegate(sh.Ctx, msg) 91 require.NoError(sh.t, err) 92 require.NotNil(sh.t, res) 93 } 94 95 // Undelegate calls staking module `MsgServer/Undelegate` to unbound some stake from a validator. 96 func (sh *Helper) Undelegate(delegator sdk.AccAddress, val sdk.ValAddress, amount math.Int, ok bool) { 97 unbondAmt := sdk.NewCoin(sh.Denom, amount) 98 msg := stakingtypes.NewMsgUndelegate(delegator.String(), val.String(), unbondAmt) 99 res, err := sh.msgSrvr.Undelegate(sh.Ctx, msg) 100 if ok { 101 require.NoError(sh.t, err) 102 require.NotNil(sh.t, res) 103 } else { 104 require.Error(sh.t, err) 105 require.Nil(sh.t, res) 106 } 107 } 108 109 // CheckValidator asserts that a validor exists and has a given status (if status!="") 110 // and if has a right jailed flag. 111 func (sh *Helper) CheckValidator(addr sdk.ValAddress, status stakingtypes.BondStatus, jailed bool) stakingtypes.Validator { 112 v, err := sh.k.GetValidator(sh.Ctx, addr) 113 require.NoError(sh.t, err) 114 require.Equal(sh.t, jailed, v.Jailed, "wrong Jalied status") 115 if status >= 0 { 116 require.Equal(sh.t, status, v.Status) 117 } 118 return v 119 } 120 121 // CheckDelegator asserts that a delegator exists 122 func (sh *Helper) CheckDelegator(delegator sdk.AccAddress, val sdk.ValAddress, found bool) { 123 _, ok := sh.k.GetDelegation(sh.Ctx, delegator, val) 124 require.Equal(sh.t, ok, found) 125 } 126 127 // TurnBlock calls EndBlocker and updates the block time 128 func (sh *Helper) TurnBlock(newTime time.Time) sdk.Context { 129 sh.Ctx = sh.Ctx.WithBlockTime(newTime) 130 _, err := sh.k.EndBlocker(sh.Ctx) 131 require.NoError(sh.t, err) 132 return sh.Ctx 133 } 134 135 // TurnBlockTimeDiff calls EndBlocker and updates the block time by adding the 136 // duration to the current block time 137 func (sh *Helper) TurnBlockTimeDiff(diff time.Duration) sdk.Context { 138 sh.Ctx = sh.Ctx.WithBlockTime(sh.Ctx.BlockHeader().Time.Add(diff)) 139 _, err := sh.k.EndBlocker(sh.Ctx) 140 require.NoError(sh.t, err) 141 return sh.Ctx 142 } 143 144 // ZeroCommission constructs a commission rates with all zeros. 145 func ZeroCommission() stakingtypes.CommissionRates { 146 return stakingtypes.NewCommissionRates(math.LegacyZeroDec(), math.LegacyZeroDec(), math.LegacyZeroDec()) 147 }