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  }