github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/x/staking/handler_test.go (about)

     1  package staking
     2  
     3  import (
     4  	"strings"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  	"github.com/stretchr/testify/require"
    10  
    11  	abci "github.com/fibonacci-chain/fbc/libs/tendermint/abci/types"
    12  	"github.com/fibonacci-chain/fbc/libs/tendermint/crypto/secp256k1"
    13  	tmtypes "github.com/fibonacci-chain/fbc/libs/tendermint/types"
    14  
    15  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    16  	keep "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/staking/keeper"
    17  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/staking/types"
    18  )
    19  
    20  func TestValidatorByPowerIndex(t *testing.T) {
    21  	validatorAddr, validatorAddr3 := sdk.ValAddress(keep.Addrs[0]), sdk.ValAddress(keep.Addrs[1])
    22  
    23  	initPower := int64(1000000)
    24  	initBond := sdk.TokensFromConsensusPower(initPower)
    25  	ctx, _, keeper, _ := keep.CreateTestInput(t, false, initPower)
    26  
    27  	// create validator
    28  	msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], initBond)
    29  	res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
    30  	require.NoError(t, err)
    31  	require.NotNil(t, res)
    32  
    33  	// must end-block
    34  	updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx)
    35  	require.Equal(t, 1, len(updates))
    36  
    37  	// verify the self-delegation exists
    38  	bond, found := keeper.GetDelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr)
    39  	require.True(t, found)
    40  	gotBond := bond.Shares.RoundInt()
    41  	require.Equal(t, initBond, gotBond)
    42  
    43  	// verify that the by power index exists
    44  	validator, found := keeper.GetValidator(ctx, validatorAddr)
    45  	require.True(t, found)
    46  	power := GetValidatorsByPowerIndexKey(validator)
    47  	require.True(t, keep.ValidatorByPowerIndexExists(ctx, keeper, power))
    48  
    49  	// create a second validator keep it bonded
    50  	msgCreateValidator = NewTestMsgCreateValidator(validatorAddr3, keep.PKs[2], initBond)
    51  	res, err = handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
    52  	require.NoError(t, err)
    53  	require.NotNil(t, res)
    54  
    55  	// must end-block
    56  	updates = keeper.ApplyAndReturnValidatorSetUpdates(ctx)
    57  	require.Equal(t, 1, len(updates))
    58  
    59  	// slash and jail the first validator
    60  	consAddr0 := sdk.ConsAddress(keep.PKs[0].Address())
    61  	keeper.Slash(ctx, consAddr0, 0, initPower, sdk.NewDecWithPrec(5, 1))
    62  	keeper.Jail(ctx, consAddr0)
    63  	keeper.ApplyAndReturnValidatorSetUpdates(ctx)
    64  
    65  	validator, found = keeper.GetValidator(ctx, validatorAddr)
    66  	require.True(t, found)
    67  	require.Equal(t, sdk.Unbonding, validator.Status)      // ensure is unbonding
    68  	require.Equal(t, initBond.QuoRaw(2), validator.Tokens) // ensure tokens slashed
    69  	keeper.Unjail(ctx, consAddr0)
    70  
    71  	// the old power record should have been deleted as the power changed
    72  	require.False(t, keep.ValidatorByPowerIndexExists(ctx, keeper, power))
    73  
    74  	// but the new power record should have been created
    75  	validator, found = keeper.GetValidator(ctx, validatorAddr)
    76  	require.True(t, found)
    77  	power2 := GetValidatorsByPowerIndexKey(validator)
    78  	require.True(t, keep.ValidatorByPowerIndexExists(ctx, keeper, power2))
    79  
    80  	// now the new record power index should be the same as the original record
    81  	power3 := GetValidatorsByPowerIndexKey(validator)
    82  	require.Equal(t, power2, power3)
    83  
    84  	// unbond self-delegation
    85  	totalBond := validator.TokensFromShares(bond.GetShares()).TruncateInt()
    86  	unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, totalBond)
    87  	msgUndelegate := NewMsgUndelegate(sdk.AccAddress(validatorAddr), validatorAddr, unbondAmt)
    88  
    89  	res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper)
    90  	require.NoError(t, err)
    91  	require.NotNil(t, res)
    92  
    93  	var finishTime time.Time
    94  	types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, &finishTime)
    95  
    96  	ctx.SetBlockTime(finishTime)
    97  	EndBlocker(ctx, keeper)
    98  	EndBlocker(ctx, keeper)
    99  
   100  	// verify that by power key nolonger exists
   101  	_, found = keeper.GetValidator(ctx, validatorAddr)
   102  	require.False(t, found)
   103  	require.False(t, keep.ValidatorByPowerIndexExists(ctx, keeper, power3))
   104  }
   105  
   106  func TestDuplicatesMsgCreateValidator(t *testing.T) {
   107  	ctx, _, keeper, _ := keep.CreateTestInput(t, false, 1000)
   108  
   109  	addr1, addr2 := sdk.ValAddress(keep.Addrs[0]), sdk.ValAddress(keep.Addrs[1])
   110  	pk1, pk2 := keep.PKs[0], keep.PKs[1]
   111  
   112  	valTokens := sdk.TokensFromConsensusPower(10)
   113  	msgCreateValidator1 := NewTestMsgCreateValidator(addr1, pk1, valTokens)
   114  	res, err := handleMsgCreateValidator(ctx, msgCreateValidator1, keeper)
   115  	require.NoError(t, err)
   116  	require.NotNil(t, res)
   117  
   118  	keeper.ApplyAndReturnValidatorSetUpdates(ctx)
   119  
   120  	validator, found := keeper.GetValidator(ctx, addr1)
   121  	require.True(t, found)
   122  	assert.Equal(t, sdk.Bonded, validator.Status)
   123  	assert.Equal(t, addr1, validator.OperatorAddress)
   124  	assert.Equal(t, pk1, validator.ConsPubKey)
   125  	assert.Equal(t, valTokens, validator.BondedTokens())
   126  	assert.Equal(t, valTokens.ToDec(), validator.DelegatorShares)
   127  	assert.Equal(t, Description{}, validator.Description)
   128  
   129  	// two validators can't have the same operator address
   130  	msgCreateValidator2 := NewTestMsgCreateValidator(addr1, pk2, valTokens)
   131  	res, err = handleMsgCreateValidator(ctx, msgCreateValidator2, keeper)
   132  	require.Error(t, err)
   133  	require.Nil(t, res)
   134  
   135  	// two validators can't have the same pubkey
   136  	msgCreateValidator3 := NewTestMsgCreateValidator(addr2, pk1, valTokens)
   137  	res, err = handleMsgCreateValidator(ctx, msgCreateValidator3, keeper)
   138  	require.Error(t, err)
   139  	require.Nil(t, res)
   140  
   141  	// must have different pubkey and operator
   142  	msgCreateValidator4 := NewTestMsgCreateValidator(addr2, pk2, valTokens)
   143  	res, err = handleMsgCreateValidator(ctx, msgCreateValidator4, keeper)
   144  	require.NoError(t, err)
   145  	require.NotNil(t, res)
   146  
   147  	// must end-block
   148  	updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx)
   149  	require.Equal(t, 1, len(updates))
   150  
   151  	validator, found = keeper.GetValidator(ctx, addr2)
   152  
   153  	require.True(t, found)
   154  	assert.Equal(t, sdk.Bonded, validator.Status)
   155  	assert.Equal(t, addr2, validator.OperatorAddress)
   156  	assert.Equal(t, pk2, validator.ConsPubKey)
   157  	assert.True(sdk.IntEq(t, valTokens, validator.Tokens))
   158  	assert.True(sdk.DecEq(t, valTokens.ToDec(), validator.DelegatorShares))
   159  	assert.Equal(t, Description{}, validator.Description)
   160  }
   161  
   162  func TestInvalidPubKeyTypeMsgCreateValidator(t *testing.T) {
   163  	ctx, _, keeper, _ := keep.CreateTestInput(t, false, 1000)
   164  
   165  	addr := sdk.ValAddress(keep.Addrs[0])
   166  	invalidPk := secp256k1.GenPrivKey().PubKey()
   167  
   168  	// invalid pukKey type should not be allowed
   169  	msgCreateValidator := NewTestMsgCreateValidator(addr, invalidPk, sdk.NewInt(10))
   170  	res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
   171  	require.Error(t, err)
   172  	require.Nil(t, res)
   173  
   174  	ctx.SetConsensusParams(&abci.ConsensusParams{
   175  		Validator: &abci.ValidatorParams{PubKeyTypes: []string{tmtypes.ABCIPubKeyTypeSecp256k1}},
   176  	})
   177  
   178  	res, err = handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
   179  	require.NoError(t, err)
   180  	require.NotNil(t, res)
   181  }
   182  
   183  func TestLegacyValidatorDelegations(t *testing.T) {
   184  	ctx, _, keeper, _ := keep.CreateTestInput(t, false, int64(1000))
   185  
   186  	bondAmount := sdk.TokensFromConsensusPower(10)
   187  	valAddr := sdk.ValAddress(keep.Addrs[0])
   188  	valConsPubKey, valConsAddr := keep.PKs[0], sdk.ConsAddress(keep.PKs[0].Address())
   189  	delAddr := keep.Addrs[1]
   190  
   191  	// create validator
   192  	msgCreateVal := NewTestMsgCreateValidator(valAddr, valConsPubKey, bondAmount)
   193  	res, err := handleMsgCreateValidator(ctx, msgCreateVal, keeper)
   194  	require.NoError(t, err)
   195  	require.NotNil(t, res)
   196  
   197  	// must end-block
   198  	updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx)
   199  	require.Equal(t, 1, len(updates))
   200  
   201  	// verify the validator exists and has the correct attributes
   202  	validator, found := keeper.GetValidator(ctx, valAddr)
   203  	require.True(t, found)
   204  	require.Equal(t, sdk.Bonded, validator.Status)
   205  	require.Equal(t, bondAmount, validator.DelegatorShares.RoundInt())
   206  	require.Equal(t, bondAmount, validator.BondedTokens())
   207  
   208  	// delegate tokens to the validator
   209  	msgDelegate := NewTestMsgDelegate(delAddr, valAddr, bondAmount)
   210  	res, err = handleMsgDelegate(ctx, msgDelegate, keeper)
   211  	require.NoError(t, err)
   212  	require.NotNil(t, res)
   213  
   214  	// verify validator bonded shares
   215  	validator, found = keeper.GetValidator(ctx, valAddr)
   216  	require.True(t, found)
   217  	require.Equal(t, bondAmount.MulRaw(2), validator.DelegatorShares.RoundInt())
   218  	require.Equal(t, bondAmount.MulRaw(2), validator.BondedTokens())
   219  
   220  	// unbond validator total self-delegations (which should jail the validator)
   221  	unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, bondAmount)
   222  	msgUndelegate := NewMsgUndelegate(sdk.AccAddress(valAddr), valAddr, unbondAmt)
   223  
   224  	res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper)
   225  	require.NoError(t, err)
   226  	require.NotNil(t, res)
   227  
   228  	var finishTime time.Time
   229  	types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, &finishTime)
   230  	ctx.SetBlockTime(finishTime)
   231  	EndBlocker(ctx, keeper)
   232  
   233  	// verify the validator record still exists, is jailed, and has correct tokens
   234  	validator, found = keeper.GetValidator(ctx, valAddr)
   235  	require.True(t, found)
   236  	require.True(t, validator.Jailed)
   237  	require.Equal(t, bondAmount, validator.Tokens)
   238  
   239  	// verify delegation still exists
   240  	bond, found := keeper.GetDelegation(ctx, delAddr, valAddr)
   241  	require.True(t, found)
   242  	require.Equal(t, bondAmount, bond.Shares.RoundInt())
   243  	require.Equal(t, bondAmount, validator.DelegatorShares.RoundInt())
   244  
   245  	// verify the validator can still self-delegate
   246  	msgSelfDelegate := NewTestMsgDelegate(sdk.AccAddress(valAddr), valAddr, bondAmount)
   247  	res, err = handleMsgDelegate(ctx, msgSelfDelegate, keeper)
   248  	require.NoError(t, err)
   249  	require.NotNil(t, res)
   250  
   251  	// verify validator bonded shares
   252  	validator, found = keeper.GetValidator(ctx, valAddr)
   253  	require.True(t, found)
   254  	require.Equal(t, bondAmount.MulRaw(2), validator.DelegatorShares.RoundInt())
   255  	require.Equal(t, bondAmount.MulRaw(2), validator.Tokens)
   256  
   257  	// unjail the validator now that is has non-zero self-delegated shares
   258  	keeper.Unjail(ctx, valConsAddr)
   259  
   260  	// verify the validator can now accept delegations
   261  	msgDelegate = NewTestMsgDelegate(delAddr, valAddr, bondAmount)
   262  	res, err = handleMsgDelegate(ctx, msgDelegate, keeper)
   263  	require.NoError(t, err)
   264  	require.NotNil(t, res)
   265  
   266  	// verify validator bonded shares
   267  	validator, found = keeper.GetValidator(ctx, valAddr)
   268  	require.True(t, found)
   269  	require.Equal(t, bondAmount.MulRaw(3), validator.DelegatorShares.RoundInt())
   270  	require.Equal(t, bondAmount.MulRaw(3), validator.Tokens)
   271  
   272  	// verify new delegation
   273  	bond, found = keeper.GetDelegation(ctx, delAddr, valAddr)
   274  	require.True(t, found)
   275  	require.Equal(t, bondAmount.MulRaw(2), bond.Shares.RoundInt())
   276  	require.Equal(t, bondAmount.MulRaw(3), validator.DelegatorShares.RoundInt())
   277  }
   278  
   279  func TestIncrementsMsgDelegate(t *testing.T) {
   280  	initPower := int64(1000)
   281  	initBond := sdk.TokensFromConsensusPower(initPower)
   282  	ctx, accMapper, keeper, _ := keep.CreateTestInput(t, false, initPower)
   283  	params := keeper.GetParams(ctx)
   284  
   285  	bondAmount := sdk.TokensFromConsensusPower(10)
   286  	validatorAddr, delegatorAddr := sdk.ValAddress(keep.Addrs[0]), keep.Addrs[1]
   287  
   288  	// first create validator
   289  	msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], bondAmount)
   290  	res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
   291  	require.NoError(t, err)
   292  	require.NotNil(t, res)
   293  
   294  	// apply TM updates
   295  	keeper.ApplyAndReturnValidatorSetUpdates(ctx)
   296  
   297  	validator, found := keeper.GetValidator(ctx, validatorAddr)
   298  	require.True(t, found)
   299  	require.Equal(t, sdk.Bonded, validator.Status)
   300  	require.Equal(t, bondAmount, validator.DelegatorShares.RoundInt())
   301  	require.Equal(t, bondAmount, validator.BondedTokens(), "validator: %v", validator)
   302  
   303  	_, found = keeper.GetDelegation(ctx, delegatorAddr, validatorAddr)
   304  	require.False(t, found)
   305  
   306  	bond, found := keeper.GetDelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr)
   307  	require.True(t, found)
   308  	require.Equal(t, bondAmount, bond.Shares.RoundInt())
   309  
   310  	bondedTokens := keeper.TotalBondedTokens(ctx)
   311  	require.Equal(t, bondAmount.ToDec().Int, bondedTokens.Int)
   312  
   313  	// just send the same msgbond multiple times
   314  	msgDelegate := NewTestMsgDelegate(delegatorAddr, validatorAddr, bondAmount)
   315  
   316  	for i := int64(0); i < 5; i++ {
   317  		ctx.SetBlockHeight(i)
   318  
   319  		res, err := handleMsgDelegate(ctx, msgDelegate, keeper)
   320  		require.NoError(t, err)
   321  		require.NotNil(t, res)
   322  
   323  		//Check that the accounts and the bond account have the appropriate values
   324  		validator, found := keeper.GetValidator(ctx, validatorAddr)
   325  		require.True(t, found)
   326  		bond, found := keeper.GetDelegation(ctx, delegatorAddr, validatorAddr)
   327  		require.True(t, found)
   328  
   329  		expBond := bondAmount.MulRaw(i + 1)
   330  		expDelegatorShares := bondAmount.MulRaw(i + 2) // (1 self delegation)
   331  		expDelegatorAcc := initBond.Sub(expBond)
   332  
   333  		gotBond := bond.Shares.RoundInt()
   334  		gotDelegatorShares := validator.DelegatorShares.RoundInt()
   335  		gotDelegatorAcc := accMapper.GetAccount(ctx, delegatorAddr).GetCoins().AmountOf(params.BondDenom)
   336  
   337  		require.Equal(t, expBond, gotBond,
   338  			"i: %v\nexpBond: %v\ngotBond: %v\nvalidator: %v\nbond: %v\n",
   339  			i, expBond, gotBond, validator, bond)
   340  		require.Equal(t, expDelegatorShares, gotDelegatorShares,
   341  			"i: %v\nexpDelegatorShares: %v\ngotDelegatorShares: %v\nvalidator: %v\nbond: %v\n",
   342  			i, expDelegatorShares, gotDelegatorShares, validator, bond)
   343  		require.Equal(t, expDelegatorAcc.ToDec().Int, gotDelegatorAcc.Int,
   344  			"i: %v\nexpDelegatorAcc: %v\ngotDelegatorAcc: %v\nvalidator: %v\nbond: %v\n",
   345  			i, expDelegatorAcc, gotDelegatorAcc, validator, bond)
   346  	}
   347  }
   348  
   349  func TestEditValidatorDecreaseMinSelfDelegation(t *testing.T) {
   350  	validatorAddr := sdk.ValAddress(keep.Addrs[0])
   351  
   352  	initPower := int64(100)
   353  	initBond := sdk.TokensFromConsensusPower(100)
   354  	ctx, _, keeper, _ := keep.CreateTestInput(t, false, initPower)
   355  
   356  	// create validator
   357  	msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], initBond)
   358  	msgCreateValidator.MinSelfDelegation = sdk.NewInt(2)
   359  	res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
   360  	require.NoError(t, err)
   361  	require.NotNil(t, res)
   362  
   363  	// must end-block
   364  	updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx)
   365  	require.Equal(t, 1, len(updates))
   366  
   367  	// verify the self-delegation exists
   368  	bond, found := keeper.GetDelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr)
   369  	require.True(t, found)
   370  	gotBond := bond.Shares.RoundInt()
   371  	require.Equal(t, initBond, gotBond,
   372  		"initBond: %v\ngotBond: %v\nbond: %v\n",
   373  		initBond, gotBond, bond)
   374  
   375  	newMinSelfDelegation := sdk.OneInt()
   376  	msgEditValidator := NewMsgEditValidator(validatorAddr, Description{}, nil, &newMinSelfDelegation)
   377  	res, err = handleMsgEditValidator(ctx, msgEditValidator, keeper)
   378  	require.Error(t, err)
   379  	require.Nil(t, res)
   380  }
   381  
   382  func TestEditValidatorIncreaseMinSelfDelegationBeyondCurrentBond(t *testing.T) {
   383  	validatorAddr := sdk.ValAddress(keep.Addrs[0])
   384  
   385  	initPower := int64(100)
   386  	initBond := sdk.TokensFromConsensusPower(100)
   387  	ctx, _, keeper, _ := keep.CreateTestInput(t, false, initPower)
   388  
   389  	// create validator
   390  	msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], initBond)
   391  	msgCreateValidator.MinSelfDelegation = sdk.NewInt(2)
   392  	res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
   393  	require.NoError(t, err)
   394  	require.NotNil(t, res)
   395  
   396  	// must end-block
   397  	updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx)
   398  	require.Equal(t, 1, len(updates))
   399  
   400  	// verify the self-delegation exists
   401  	bond, found := keeper.GetDelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr)
   402  	require.True(t, found)
   403  	gotBond := bond.Shares.RoundInt()
   404  	require.Equal(t, initBond, gotBond,
   405  		"initBond: %v\ngotBond: %v\nbond: %v\n",
   406  		initBond, gotBond, bond)
   407  
   408  	newMinSelfDelegation := initBond.Add(sdk.OneInt())
   409  	msgEditValidator := NewMsgEditValidator(validatorAddr, Description{}, nil, &newMinSelfDelegation)
   410  	res, err = handleMsgEditValidator(ctx, msgEditValidator, keeper)
   411  	require.Error(t, err)
   412  	require.Nil(t, res)
   413  }
   414  
   415  func TestIncrementsMsgUnbond(t *testing.T) {
   416  	initPower := int64(1000)
   417  	initBond := sdk.TokensFromConsensusPower(initPower)
   418  	ctx, accMapper, keeper, _ := keep.CreateTestInput(t, false, initPower)
   419  
   420  	params := keeper.GetParams(ctx)
   421  	denom := params.BondDenom
   422  
   423  	// create validator, delegate
   424  	validatorAddr, delegatorAddr := sdk.ValAddress(keep.Addrs[0]), keep.Addrs[1]
   425  
   426  	msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], initBond)
   427  	res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
   428  	require.NoError(t, err)
   429  	require.NotNil(t, res)
   430  
   431  	// initial balance
   432  	amt1 := accMapper.GetAccount(ctx, delegatorAddr).GetCoins().AmountOf(denom)
   433  
   434  	msgDelegate := NewTestMsgDelegate(delegatorAddr, validatorAddr, initBond)
   435  	res, err = handleMsgDelegate(ctx, msgDelegate, keeper)
   436  	require.NoError(t, err)
   437  	require.NotNil(t, res)
   438  
   439  	// balance should have been subtracted after delegation
   440  	amt2 := accMapper.GetAccount(ctx, delegatorAddr).GetCoins().AmountOf(denom)
   441  	require.True(sdk.DecEq(t, amt1.Sub(sdk.NewDecFromInt(initBond)), amt2))
   442  
   443  	// apply TM updates
   444  	keeper.ApplyAndReturnValidatorSetUpdates(ctx)
   445  
   446  	validator, found := keeper.GetValidator(ctx, validatorAddr)
   447  	require.True(t, found)
   448  	require.Equal(t, initBond.MulRaw(2), validator.DelegatorShares.RoundInt())
   449  	require.Equal(t, initBond.MulRaw(2), validator.BondedTokens())
   450  
   451  	// just send the same msgUnbond multiple times
   452  	// TODO use decimals here
   453  	unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10))
   454  	msgUndelegate := NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt)
   455  	numUnbonds := int64(5)
   456  
   457  	for i := int64(0); i < numUnbonds; i++ {
   458  		res, err := handleMsgUndelegate(ctx, msgUndelegate, keeper)
   459  		require.NoError(t, err)
   460  		require.NotNil(t, res)
   461  
   462  		var finishTime time.Time
   463  		types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, &finishTime)
   464  
   465  		ctx.SetBlockTime(finishTime)
   466  		EndBlocker(ctx, keeper)
   467  
   468  		// check that the accounts and the bond account have the appropriate values
   469  		validator, found = keeper.GetValidator(ctx, validatorAddr)
   470  		require.True(t, found)
   471  		bond, found := keeper.GetDelegation(ctx, delegatorAddr, validatorAddr)
   472  		require.True(t, found)
   473  
   474  		expBond := sdk.NewDecFromInt(initBond).Sub(unbondAmt.Amount.Mul(sdk.NewDec(i + 1)))
   475  		expDelegatorShares := sdk.NewDecFromInt(initBond.MulRaw(2)).Sub(unbondAmt.Amount.Mul(sdk.NewDec(i + 1)))
   476  		expDelegatorAcc := sdk.NewDecFromInt(initBond).Sub(expBond)
   477  
   478  		gotBond := bond.Shares.RoundInt()
   479  		gotDelegatorShares := validator.DelegatorShares.RoundInt()
   480  		gotDelegatorAcc := accMapper.GetAccount(ctx, delegatorAddr).GetCoins().AmountOf(params.BondDenom)
   481  
   482  		require.Equal(t, expBond.Int, gotBond.ToDec().Int,
   483  			"i: %v\nexpBond: %v\ngotBond: %v\nvalidator: %v\nbond: %v\n",
   484  			i, expBond, gotBond, validator, bond)
   485  		require.Equal(t, expDelegatorShares.Int, gotDelegatorShares.ToDec().Int,
   486  			"i: %v\nexpDelegatorShares: %v\ngotDelegatorShares: %v\nvalidator: %v\nbond: %v\n",
   487  			i, expDelegatorShares, gotDelegatorShares, validator, bond)
   488  		require.Equal(t, expDelegatorAcc.Int64(), gotDelegatorAcc.Int64(),
   489  			"i: %v\nexpDelegatorAcc: %v\ngotDelegatorAcc: %v\nvalidator: %v\nbond: %v\n",
   490  			i, expDelegatorAcc, gotDelegatorAcc, validator, bond)
   491  	}
   492  
   493  	// these are more than we have bonded now
   494  	errorCases := []sdk.Int{
   495  		//1<<64 - 1, // more than int64 power
   496  		//1<<63 + 1, // more than int64 power
   497  		sdk.TokensFromConsensusPower(1<<63 - 1),
   498  		sdk.TokensFromConsensusPower(1 << 31),
   499  		initBond,
   500  	}
   501  
   502  	for _, c := range errorCases {
   503  		unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, c)
   504  		msgUndelegate := NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt)
   505  		res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper)
   506  		require.Error(t, err)
   507  		require.Nil(t, res)
   508  	}
   509  
   510  	leftBonded := sdk.NewDecFromInt(initBond).Sub(unbondAmt.Amount.Mul(sdk.NewDec(numUnbonds)))
   511  
   512  	// should be able to unbond remaining
   513  	unbondAmt = sdk.NewCoin(sdk.DefaultBondDenom, leftBonded)
   514  	msgUndelegate = NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt)
   515  	res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper)
   516  	require.NoError(t, err, "msgUnbond: %v\nshares: %s\nleftBonded: %s\n", msgUndelegate, unbondAmt, leftBonded)
   517  	require.NotNil(t, res, "msgUnbond: %v\nshares: %s\nleftBonded: %s\n", msgUndelegate, unbondAmt, leftBonded)
   518  }
   519  
   520  func TestMultipleMsgCreateValidator(t *testing.T) {
   521  	initPower := int64(1000)
   522  	initTokens := sdk.TokensFromConsensusPower(initPower)
   523  	ctx, accMapper, keeper, _ := keep.CreateTestInput(t, false, initPower)
   524  
   525  	params := keeper.GetParams(ctx)
   526  	blockTime := time.Now().UTC()
   527  	ctx.SetBlockTime(blockTime)
   528  
   529  	validatorAddrs := []sdk.ValAddress{
   530  		sdk.ValAddress(keep.Addrs[0]),
   531  		sdk.ValAddress(keep.Addrs[1]),
   532  		sdk.ValAddress(keep.Addrs[2]),
   533  	}
   534  	delegatorAddrs := []sdk.AccAddress{
   535  		keep.Addrs[0],
   536  		keep.Addrs[1],
   537  		keep.Addrs[2],
   538  	}
   539  
   540  	// bond them all
   541  	for i, validatorAddr := range validatorAddrs {
   542  		valTokens := sdk.TokensFromConsensusPower(10)
   543  		msgCreateValidatorOnBehalfOf := NewTestMsgCreateValidator(validatorAddr, keep.PKs[i], valTokens)
   544  
   545  		res, err := handleMsgCreateValidator(ctx, msgCreateValidatorOnBehalfOf, keeper)
   546  		require.NoError(t, err)
   547  		require.NotNil(t, res)
   548  
   549  		// verify that the account is bonded
   550  		validators := keeper.GetValidators(ctx, 100)
   551  		require.Equal(t, (i + 1), len(validators))
   552  
   553  		val := validators[i]
   554  		balanceExpd := initTokens.Sub(valTokens)
   555  		balanceGot := accMapper.GetAccount(ctx, delegatorAddrs[i]).GetCoins().AmountOf(params.BondDenom)
   556  
   557  		require.Equal(t, i+1, len(validators), "expected %d validators got %d, validators: %v", i+1, len(validators), validators)
   558  		require.Equal(t, valTokens, val.DelegatorShares.RoundInt(), "expected %d shares, got %d", 10, val.DelegatorShares)
   559  		require.Equal(t, balanceExpd.ToDec().Int, balanceGot.Int, "expected account to have %d, got %d", balanceExpd, balanceGot)
   560  	}
   561  
   562  	EndBlocker(ctx, keeper)
   563  
   564  	// unbond them all by removing delegation
   565  	for i, validatorAddr := range validatorAddrs {
   566  		_, found := keeper.GetValidator(ctx, validatorAddr)
   567  		require.True(t, found)
   568  
   569  		unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(10))
   570  		msgUndelegate := NewMsgUndelegate(delegatorAddrs[i], validatorAddr, unbondAmt) // remove delegation
   571  		res, err := handleMsgUndelegate(ctx, msgUndelegate, keeper)
   572  		require.NoError(t, err)
   573  		require.NotNil(t, res)
   574  
   575  		var finishTime time.Time
   576  		types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, &finishTime)
   577  
   578  		// adds validator into unbonding queue
   579  		EndBlocker(ctx, keeper)
   580  
   581  		// removes validator from queue and set
   582  		EndBlocker(ctx.WithBlockTime(blockTime.Add(params.UnbondingTime)), keeper)
   583  
   584  		// Check that the validator is deleted from state
   585  		validators := keeper.GetValidators(ctx, 100)
   586  		require.Equal(t, len(validatorAddrs)-(i+1), len(validators),
   587  			"expected %d validators got %d", len(validatorAddrs)-(i+1), len(validators))
   588  
   589  		_, found = keeper.GetValidator(ctx, validatorAddr)
   590  		require.False(t, found)
   591  
   592  		gotBalance := accMapper.GetAccount(ctx, delegatorAddrs[i]).GetCoins().AmountOf(params.BondDenom)
   593  		require.Equal(t, initTokens.ToDec().Int, gotBalance.Int, "expected account to have %d, got %d", initTokens, gotBalance)
   594  	}
   595  }
   596  
   597  func TestMultipleMsgDelegate(t *testing.T) {
   598  	ctx, _, keeper, _ := keep.CreateTestInput(t, false, 1000)
   599  	validatorAddr, delegatorAddrs := sdk.ValAddress(keep.Addrs[0]), keep.Addrs[1:]
   600  
   601  	// first make a validator
   602  	msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], sdk.NewInt(10))
   603  	res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
   604  	require.NoError(t, err)
   605  	require.NotNil(t, res)
   606  
   607  	// delegate multiple parties
   608  	for _, delegatorAddr := range delegatorAddrs {
   609  		msgDelegate := NewTestMsgDelegate(delegatorAddr, validatorAddr, sdk.NewInt(10))
   610  		res, err := handleMsgDelegate(ctx, msgDelegate, keeper)
   611  		require.NoError(t, err)
   612  		require.NotNil(t, res)
   613  
   614  		// check that the account is bonded
   615  		bond, found := keeper.GetDelegation(ctx, delegatorAddr, validatorAddr)
   616  		require.True(t, found)
   617  		require.NotNil(t, bond, "expected delegatee bond %d to exist", bond)
   618  	}
   619  
   620  	// unbond them all
   621  	for _, delegatorAddr := range delegatorAddrs {
   622  		unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10))
   623  		msgUndelegate := NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt)
   624  
   625  		res, err := handleMsgUndelegate(ctx, msgUndelegate, keeper)
   626  		require.NoError(t, err)
   627  		require.NotNil(t, res)
   628  
   629  		var finishTime time.Time
   630  		types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, &finishTime)
   631  
   632  		ctx.SetBlockTime(finishTime)
   633  		EndBlocker(ctx, keeper)
   634  
   635  		// check that the account is unbonded
   636  		_, found := keeper.GetDelegation(ctx, delegatorAddr, validatorAddr)
   637  		require.False(t, found)
   638  	}
   639  }
   640  
   641  func TestJailValidator(t *testing.T) {
   642  	ctx, _, keeper, _ := keep.CreateTestInput(t, false, 1000)
   643  	validatorAddr, delegatorAddr := sdk.ValAddress(keep.Addrs[0]), keep.Addrs[1]
   644  
   645  	// create the validator
   646  	msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], sdk.NewInt(10))
   647  	res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
   648  	require.NoError(t, err)
   649  	require.NotNil(t, res)
   650  
   651  	// bond a delegator
   652  	msgDelegate := NewTestMsgDelegate(delegatorAddr, validatorAddr, sdk.NewInt(10))
   653  	res, err = handleMsgDelegate(ctx, msgDelegate, keeper)
   654  	require.NoError(t, err)
   655  	require.NotNil(t, res)
   656  
   657  	// unbond the validators bond portion
   658  	unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10))
   659  	msgUndelegateValidator := NewMsgUndelegate(sdk.AccAddress(validatorAddr), validatorAddr, unbondAmt)
   660  	res, err = handleMsgUndelegate(ctx, msgUndelegateValidator, keeper)
   661  	require.NoError(t, err)
   662  	require.NotNil(t, res)
   663  
   664  	var finishTime time.Time
   665  	types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, &finishTime)
   666  
   667  	ctx.SetBlockTime(finishTime)
   668  	EndBlocker(ctx, keeper)
   669  
   670  	validator, found := keeper.GetValidator(ctx, validatorAddr)
   671  	require.True(t, found)
   672  	require.True(t, validator.Jailed, "%v", validator)
   673  
   674  	// test that the delegator can still withdraw their bonds
   675  	msgUndelegateDelegator := NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt)
   676  
   677  	res, err = handleMsgUndelegate(ctx, msgUndelegateDelegator, keeper)
   678  	require.NoError(t, err)
   679  	require.NotNil(t, res)
   680  	types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, &finishTime)
   681  
   682  	ctx.SetBlockTime(finishTime)
   683  	EndBlocker(ctx, keeper)
   684  
   685  	// verify that the pubkey can now be reused
   686  	res, err = handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
   687  	require.NoError(t, err)
   688  	require.NotNil(t, res)
   689  }
   690  
   691  func TestValidatorQueue(t *testing.T) {
   692  	ctx, _, keeper, _ := keep.CreateTestInput(t, false, 1000)
   693  	validatorAddr, delegatorAddr := sdk.ValAddress(keep.Addrs[0]), keep.Addrs[1]
   694  
   695  	// set the unbonding time
   696  	params := keeper.GetParams(ctx)
   697  	params.UnbondingTime = 7 * time.Second
   698  	keeper.SetParams(ctx, params)
   699  
   700  	// create the validator
   701  	valTokens := sdk.TokensFromConsensusPower(10)
   702  	msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], valTokens)
   703  	res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
   704  	require.NoError(t, err)
   705  	require.NotNil(t, res)
   706  
   707  	// bond a delegator
   708  	delTokens := sdk.TokensFromConsensusPower(10)
   709  	msgDelegate := NewTestMsgDelegate(delegatorAddr, validatorAddr, delTokens)
   710  	res, err = handleMsgDelegate(ctx, msgDelegate, keeper)
   711  	require.NoError(t, err)
   712  	require.NotNil(t, res)
   713  
   714  	EndBlocker(ctx, keeper)
   715  
   716  	// unbond the all self-delegation to put validator in unbonding state
   717  	unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, delTokens)
   718  	msgUndelegateValidator := NewMsgUndelegate(sdk.AccAddress(validatorAddr), validatorAddr, unbondAmt)
   719  	res, err = handleMsgUndelegate(ctx, msgUndelegateValidator, keeper)
   720  	require.NoError(t, err)
   721  	require.NotNil(t, res)
   722  
   723  	var finishTime time.Time
   724  	types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, &finishTime)
   725  
   726  	ctx.SetBlockTime(finishTime)
   727  	EndBlocker(ctx, keeper)
   728  
   729  	origHeader := ctx.BlockHeader()
   730  
   731  	validator, found := keeper.GetValidator(ctx, validatorAddr)
   732  	require.True(t, found)
   733  	require.True(t, validator.IsUnbonding(), "%v", validator)
   734  
   735  	// should still be unbonding at time 6 seconds later
   736  	ctx.SetBlockTime(origHeader.Time.Add(time.Second * 6))
   737  	EndBlocker(ctx, keeper)
   738  
   739  	validator, found = keeper.GetValidator(ctx, validatorAddr)
   740  	require.True(t, found)
   741  	require.True(t, validator.IsUnbonding(), "%v", validator)
   742  
   743  	// should be in unbonded state at time 7 seconds later
   744  	ctx.SetBlockTime(origHeader.Time.Add(time.Second * 7))
   745  	EndBlocker(ctx, keeper)
   746  
   747  	validator, found = keeper.GetValidator(ctx, validatorAddr)
   748  	require.True(t, found)
   749  	require.True(t, validator.IsUnbonded(), "%v", validator)
   750  }
   751  
   752  func TestUnbondingPeriod(t *testing.T) {
   753  	ctx, _, keeper, _ := keep.CreateTestInput(t, false, 1000)
   754  	validatorAddr := sdk.ValAddress(keep.Addrs[0])
   755  
   756  	// set the unbonding time
   757  	params := keeper.GetParams(ctx)
   758  	params.UnbondingTime = 7 * time.Second
   759  	keeper.SetParams(ctx, params)
   760  
   761  	// create the validator
   762  	valTokens := sdk.TokensFromConsensusPower(10)
   763  	msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], valTokens)
   764  	res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
   765  	require.NoError(t, err)
   766  	require.NotNil(t, res)
   767  
   768  	EndBlocker(ctx, keeper)
   769  
   770  	// begin unbonding
   771  	unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(10))
   772  	msgUndelegate := NewMsgUndelegate(sdk.AccAddress(validatorAddr), validatorAddr, unbondAmt)
   773  	res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper)
   774  	require.NoError(t, err)
   775  	require.NotNil(t, res)
   776  
   777  	origHeader := ctx.BlockHeader()
   778  
   779  	_, found := keeper.GetUnbondingDelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr)
   780  	require.True(t, found, "should not have unbonded")
   781  
   782  	// cannot complete unbonding at same time
   783  	EndBlocker(ctx, keeper)
   784  	_, found = keeper.GetUnbondingDelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr)
   785  	require.True(t, found, "should not have unbonded")
   786  
   787  	// cannot complete unbonding at time 6 seconds later
   788  	ctx.SetBlockTime(origHeader.Time.Add(time.Second * 6))
   789  	EndBlocker(ctx, keeper)
   790  	_, found = keeper.GetUnbondingDelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr)
   791  	require.True(t, found, "should not have unbonded")
   792  
   793  	// can complete unbonding at time 7 seconds later
   794  	ctx.SetBlockTime(origHeader.Time.Add(time.Second * 7))
   795  	EndBlocker(ctx, keeper)
   796  	_, found = keeper.GetUnbondingDelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr)
   797  	require.False(t, found, "should have unbonded")
   798  }
   799  
   800  func TestUnbondingFromUnbondingValidator(t *testing.T) {
   801  	ctx, _, keeper, _ := keep.CreateTestInput(t, false, 1000)
   802  	validatorAddr, delegatorAddr := sdk.ValAddress(keep.Addrs[0]), keep.Addrs[1]
   803  
   804  	// create the validator
   805  	msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], sdk.NewInt(10))
   806  	res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
   807  	require.NoError(t, err)
   808  	require.NotNil(t, res)
   809  
   810  	// bond a delegator
   811  	msgDelegate := NewTestMsgDelegate(delegatorAddr, validatorAddr, sdk.NewInt(10))
   812  	res, err = handleMsgDelegate(ctx, msgDelegate, keeper)
   813  	require.NoError(t, err)
   814  	require.NotNil(t, res)
   815  
   816  	// unbond the validators bond portion
   817  	unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10))
   818  	msgUndelegateValidator := NewMsgUndelegate(sdk.AccAddress(validatorAddr), validatorAddr, unbondAmt)
   819  	res, err = handleMsgUndelegate(ctx, msgUndelegateValidator, keeper)
   820  	require.NoError(t, err)
   821  	require.NotNil(t, res)
   822  
   823  	// change the ctx to Block Time one second before the validator would have unbonded
   824  	var finishTime time.Time
   825  	types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, &finishTime)
   826  	ctx.SetBlockTime(finishTime.Add(time.Second * -1))
   827  
   828  	// unbond the delegator from the validator
   829  	msgUndelegateDelegator := NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt)
   830  	res, err = handleMsgUndelegate(ctx, msgUndelegateDelegator, keeper)
   831  	require.NoError(t, err)
   832  	require.NotNil(t, res)
   833  
   834  	ctx.SetBlockTime(ctx.BlockHeader().Time.Add(keeper.UnbondingTime(ctx)))
   835  
   836  	// Run the EndBlocker
   837  	EndBlocker(ctx, keeper)
   838  
   839  	// Check to make sure that the unbonding delegation is no longer in state
   840  	// (meaning it was deleted in the above EndBlocker)
   841  	_, found := keeper.GetUnbondingDelegation(ctx, delegatorAddr, validatorAddr)
   842  	require.False(t, found, "should be removed from state")
   843  }
   844  
   845  func TestRedelegationPeriod(t *testing.T) {
   846  	ctx, AccMapper, keeper, _ := keep.CreateTestInput(t, false, 1000)
   847  	validatorAddr, validatorAddr2 := sdk.ValAddress(keep.Addrs[0]), sdk.ValAddress(keep.Addrs[1])
   848  	denom := keeper.GetParams(ctx).BondDenom
   849  
   850  	// set the unbonding time
   851  	params := keeper.GetParams(ctx)
   852  	params.UnbondingTime = 7 * time.Second
   853  	keeper.SetParams(ctx, params)
   854  
   855  	// create the validators
   856  	msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], sdk.NewInt(10))
   857  
   858  	// initial balance
   859  	amt1 := AccMapper.GetAccount(ctx, sdk.AccAddress(validatorAddr)).GetCoins().AmountOf(denom)
   860  
   861  	res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
   862  	require.NoError(t, err)
   863  	require.NotNil(t, res)
   864  
   865  	// balance should have been subtracted after creation
   866  	amt2 := AccMapper.GetAccount(ctx, sdk.AccAddress(validatorAddr)).GetCoins().AmountOf(denom)
   867  	require.Equal(t, amt1.Sub(sdk.NewDec(10)).Int64(), amt2.Int64(), "expected coins to be subtracted")
   868  
   869  	msgCreateValidator = NewTestMsgCreateValidator(validatorAddr2, keep.PKs[1], sdk.NewInt(10))
   870  	res, err = handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
   871  	require.NoError(t, err)
   872  	require.NotNil(t, res)
   873  
   874  	bal1 := AccMapper.GetAccount(ctx, sdk.AccAddress(validatorAddr)).GetCoins()
   875  
   876  	// begin redelegate
   877  	redAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10))
   878  	msgBeginRedelegate := NewMsgBeginRedelegate(sdk.AccAddress(validatorAddr), validatorAddr, validatorAddr2, redAmt)
   879  	res, err = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper)
   880  	require.NoError(t, err)
   881  	require.NotNil(t, res)
   882  
   883  	// origin account should not lose tokens as with a regular delegation
   884  	bal2 := AccMapper.GetAccount(ctx, sdk.AccAddress(validatorAddr)).GetCoins()
   885  	require.Equal(t, bal1, bal2)
   886  
   887  	origHeader := ctx.BlockHeader()
   888  
   889  	// cannot complete redelegation at same time
   890  	EndBlocker(ctx, keeper)
   891  	_, found := keeper.GetRedelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr, validatorAddr2)
   892  	require.True(t, found, "should not have unbonded")
   893  
   894  	// cannot complete redelegation at time 6 seconds later
   895  	ctx.SetBlockTime(origHeader.Time.Add(time.Second * 6))
   896  	EndBlocker(ctx, keeper)
   897  	_, found = keeper.GetRedelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr, validatorAddr2)
   898  	require.True(t, found, "should not have unbonded")
   899  
   900  	// can complete redelegation at time 7 seconds later
   901  	ctx.SetBlockTime(origHeader.Time.Add(time.Second * 7))
   902  	EndBlocker(ctx, keeper)
   903  	_, found = keeper.GetRedelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr, validatorAddr2)
   904  	require.False(t, found, "should have unbonded")
   905  }
   906  
   907  func TestTransitiveRedelegation(t *testing.T) {
   908  	ctx, _, keeper, _ := keep.CreateTestInput(t, false, 1000)
   909  	validatorAddr := sdk.ValAddress(keep.Addrs[0])
   910  	validatorAddr2 := sdk.ValAddress(keep.Addrs[1])
   911  	validatorAddr3 := sdk.ValAddress(keep.Addrs[2])
   912  
   913  	blockTime := time.Now().UTC()
   914  	ctx.SetBlockTime(blockTime)
   915  
   916  	// create the validators
   917  	msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], sdk.NewInt(10))
   918  	res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
   919  	require.NoError(t, err)
   920  	require.NotNil(t, res)
   921  
   922  	msgCreateValidator = NewTestMsgCreateValidator(validatorAddr2, keep.PKs[1], sdk.NewInt(10))
   923  	res, err = handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
   924  	require.NoError(t, err)
   925  	require.NotNil(t, res)
   926  
   927  	msgCreateValidator = NewTestMsgCreateValidator(validatorAddr3, keep.PKs[2], sdk.NewInt(10))
   928  	res, err = handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
   929  	require.NoError(t, err)
   930  	require.NotNil(t, res)
   931  
   932  	// begin redelegate
   933  	redAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10))
   934  	msgBeginRedelegate := NewMsgBeginRedelegate(sdk.AccAddress(validatorAddr), validatorAddr, validatorAddr2, redAmt)
   935  	res, err = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper)
   936  	require.NoError(t, err)
   937  	require.NotNil(t, res)
   938  
   939  	// cannot redelegation to next validator while first delegation exists
   940  	msgBeginRedelegate = NewMsgBeginRedelegate(sdk.AccAddress(validatorAddr), validatorAddr2, validatorAddr3, redAmt)
   941  	res, err = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper)
   942  	require.Error(t, err)
   943  	require.Nil(t, res)
   944  
   945  	params := keeper.GetParams(ctx)
   946  	ctx.SetBlockTime(blockTime.Add(params.UnbondingTime))
   947  
   948  	// complete first redelegation
   949  	EndBlocker(ctx, keeper)
   950  
   951  	// now should be able to redelegate from the second validator to the third
   952  	res, err = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper)
   953  	require.NoError(t, err)
   954  	require.NotNil(t, res)
   955  }
   956  
   957  func TestMultipleRedelegationAtSameTime(t *testing.T) {
   958  	ctx, _, keeper, _ := keep.CreateTestInput(t, false, 1000)
   959  	valAddr := sdk.ValAddress(keep.Addrs[0])
   960  	valAddr2 := sdk.ValAddress(keep.Addrs[1])
   961  
   962  	// set the unbonding time
   963  	params := keeper.GetParams(ctx)
   964  	params.UnbondingTime = 1 * time.Second
   965  	keeper.SetParams(ctx, params)
   966  
   967  	// create the validators
   968  	valTokens := sdk.TokensFromConsensusPower(10)
   969  	msgCreateValidator := NewTestMsgCreateValidator(valAddr, keep.PKs[0], valTokens)
   970  	res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
   971  	require.NoError(t, err)
   972  	require.NotNil(t, res)
   973  
   974  	msgCreateValidator = NewTestMsgCreateValidator(valAddr2, keep.PKs[1], valTokens)
   975  	res, err = handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
   976  	require.NoError(t, err)
   977  	require.NotNil(t, res)
   978  
   979  	// end block to bond them
   980  	EndBlocker(ctx, keeper)
   981  
   982  	// begin a redelegate
   983  	selfDelAddr := sdk.AccAddress(valAddr) // (the validator is it's own delegator)
   984  	redAmt := sdk.NewCoin(sdk.DefaultBondDenom, valTokens.QuoRaw(2))
   985  	msgBeginRedelegate := NewMsgBeginRedelegate(selfDelAddr, valAddr, valAddr2, redAmt)
   986  	res, err = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper)
   987  	require.NoError(t, err)
   988  	require.NotNil(t, res)
   989  
   990  	// there should only be one entry in the redelegation object
   991  	rd, found := keeper.GetRedelegation(ctx, selfDelAddr, valAddr, valAddr2)
   992  	require.True(t, found)
   993  	require.Len(t, rd.Entries, 1)
   994  
   995  	// start a second redelegation at this same time as the first
   996  	res, err = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper)
   997  	require.NoError(t, err)
   998  	require.NotNil(t, res)
   999  
  1000  	// now there should be two entries
  1001  	rd, found = keeper.GetRedelegation(ctx, selfDelAddr, valAddr, valAddr2)
  1002  	require.True(t, found)
  1003  	require.Len(t, rd.Entries, 2)
  1004  
  1005  	// move forward in time, should complete both redelegations
  1006  	ctx.SetBlockTime(ctx.BlockHeader().Time.Add(1 * time.Second))
  1007  	EndBlocker(ctx, keeper)
  1008  
  1009  	rd, found = keeper.GetRedelegation(ctx, selfDelAddr, valAddr, valAddr2)
  1010  	require.False(t, found)
  1011  }
  1012  
  1013  func TestMultipleRedelegationAtUniqueTimes(t *testing.T) {
  1014  	ctx, _, keeper, _ := keep.CreateTestInput(t, false, 1000)
  1015  	valAddr := sdk.ValAddress(keep.Addrs[0])
  1016  	valAddr2 := sdk.ValAddress(keep.Addrs[1])
  1017  
  1018  	// set the unbonding time
  1019  	params := keeper.GetParams(ctx)
  1020  	params.UnbondingTime = 10 * time.Second
  1021  	keeper.SetParams(ctx, params)
  1022  
  1023  	// create the validators
  1024  	valTokens := sdk.TokensFromConsensusPower(10)
  1025  	msgCreateValidator := NewTestMsgCreateValidator(valAddr, keep.PKs[0], valTokens)
  1026  	res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
  1027  	require.NoError(t, err)
  1028  	require.NotNil(t, res)
  1029  
  1030  	msgCreateValidator = NewTestMsgCreateValidator(valAddr2, keep.PKs[1], valTokens)
  1031  	res, err = handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
  1032  	require.NoError(t, err)
  1033  	require.NotNil(t, res)
  1034  
  1035  	// end block to bond them
  1036  	EndBlocker(ctx, keeper)
  1037  
  1038  	// begin a redelegate
  1039  	selfDelAddr := sdk.AccAddress(valAddr) // (the validator is it's own delegator)
  1040  	redAmt := sdk.NewCoin(sdk.DefaultBondDenom, valTokens.QuoRaw(2))
  1041  	msgBeginRedelegate := NewMsgBeginRedelegate(selfDelAddr, valAddr, valAddr2, redAmt)
  1042  	res, err = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper)
  1043  	require.NoError(t, err)
  1044  	require.NotNil(t, res)
  1045  
  1046  	// move forward in time and start a second redelegation
  1047  	ctx.SetBlockTime(ctx.BlockHeader().Time.Add(5 * time.Second))
  1048  	res, err = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper)
  1049  	require.NoError(t, err)
  1050  	require.NotNil(t, res)
  1051  
  1052  	// now there should be two entries
  1053  	rd, found := keeper.GetRedelegation(ctx, selfDelAddr, valAddr, valAddr2)
  1054  	require.True(t, found)
  1055  	require.Len(t, rd.Entries, 2)
  1056  
  1057  	// move forward in time, should complete the first redelegation, but not the second
  1058  	ctx.SetBlockTime(ctx.BlockHeader().Time.Add(5 * time.Second))
  1059  	EndBlocker(ctx, keeper)
  1060  	rd, found = keeper.GetRedelegation(ctx, selfDelAddr, valAddr, valAddr2)
  1061  	require.True(t, found)
  1062  	require.Len(t, rd.Entries, 1)
  1063  
  1064  	// move forward in time, should complete the second redelegation
  1065  	ctx.SetBlockTime(ctx.BlockHeader().Time.Add(5 * time.Second))
  1066  	EndBlocker(ctx, keeper)
  1067  	rd, found = keeper.GetRedelegation(ctx, selfDelAddr, valAddr, valAddr2)
  1068  	require.False(t, found)
  1069  }
  1070  
  1071  func TestMultipleUnbondingDelegationAtSameTime(t *testing.T) {
  1072  	ctx, _, keeper, _ := keep.CreateTestInput(t, false, 1000)
  1073  	valAddr := sdk.ValAddress(keep.Addrs[0])
  1074  
  1075  	// set the unbonding time
  1076  	params := keeper.GetParams(ctx)
  1077  	params.UnbondingTime = 1 * time.Second
  1078  	keeper.SetParams(ctx, params)
  1079  
  1080  	// create the validator
  1081  	valTokens := sdk.TokensFromConsensusPower(10)
  1082  	msgCreateValidator := NewTestMsgCreateValidator(valAddr, keep.PKs[0], valTokens)
  1083  	res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
  1084  	require.NoError(t, err)
  1085  	require.NotNil(t, res)
  1086  
  1087  	// end block to bond
  1088  	EndBlocker(ctx, keeper)
  1089  
  1090  	// begin an unbonding delegation
  1091  	selfDelAddr := sdk.AccAddress(valAddr) // (the validator is it's own delegator)
  1092  	unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, valTokens.QuoRaw(2))
  1093  	msgUndelegate := NewMsgUndelegate(selfDelAddr, valAddr, unbondAmt)
  1094  	res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper)
  1095  	require.NoError(t, err)
  1096  	require.NotNil(t, res)
  1097  
  1098  	// there should only be one entry in the ubd object
  1099  	ubd, found := keeper.GetUnbondingDelegation(ctx, selfDelAddr, valAddr)
  1100  	require.True(t, found)
  1101  	require.Len(t, ubd.Entries, 1)
  1102  
  1103  	// start a second ubd at this same time as the first
  1104  	res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper)
  1105  	require.NoError(t, err)
  1106  	require.NotNil(t, res)
  1107  
  1108  	// now there should be two entries
  1109  	ubd, found = keeper.GetUnbondingDelegation(ctx, selfDelAddr, valAddr)
  1110  	require.True(t, found)
  1111  	require.Len(t, ubd.Entries, 2)
  1112  
  1113  	// move forwaubd in time, should complete both ubds
  1114  	ctx.SetBlockTime(ctx.BlockHeader().Time.Add(1 * time.Second))
  1115  	EndBlocker(ctx, keeper)
  1116  
  1117  	ubd, found = keeper.GetUnbondingDelegation(ctx, selfDelAddr, valAddr)
  1118  	require.False(t, found)
  1119  }
  1120  
  1121  func TestMultipleUnbondingDelegationAtUniqueTimes(t *testing.T) {
  1122  	ctx, _, keeper, _ := keep.CreateTestInput(t, false, 1000)
  1123  	valAddr := sdk.ValAddress(keep.Addrs[0])
  1124  
  1125  	// set the unbonding time
  1126  	params := keeper.GetParams(ctx)
  1127  	params.UnbondingTime = 10 * time.Second
  1128  	keeper.SetParams(ctx, params)
  1129  
  1130  	// create the validator
  1131  	valTokens := sdk.TokensFromConsensusPower(10)
  1132  	msgCreateValidator := NewTestMsgCreateValidator(valAddr, keep.PKs[0], valTokens)
  1133  	res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
  1134  	require.NoError(t, err)
  1135  	require.NotNil(t, res)
  1136  
  1137  	// end block to bond
  1138  	EndBlocker(ctx, keeper)
  1139  
  1140  	// begin an unbonding delegation
  1141  	selfDelAddr := sdk.AccAddress(valAddr) // (the validator is it's own delegator)
  1142  	unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, valTokens.QuoRaw(2))
  1143  	msgUndelegate := NewMsgUndelegate(selfDelAddr, valAddr, unbondAmt)
  1144  	res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper)
  1145  	require.NoError(t, err)
  1146  	require.NotNil(t, res)
  1147  
  1148  	// there should only be one entry in the ubd object
  1149  	ubd, found := keeper.GetUnbondingDelegation(ctx, selfDelAddr, valAddr)
  1150  	require.True(t, found)
  1151  	require.Len(t, ubd.Entries, 1)
  1152  
  1153  	// move forwaubd in time and start a second redelegation
  1154  	ctx.SetBlockTime(ctx.BlockHeader().Time.Add(5 * time.Second))
  1155  	res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper)
  1156  	require.NoError(t, err)
  1157  	require.NotNil(t, res)
  1158  
  1159  	// now there should be two entries
  1160  	ubd, found = keeper.GetUnbondingDelegation(ctx, selfDelAddr, valAddr)
  1161  	require.True(t, found)
  1162  	require.Len(t, ubd.Entries, 2)
  1163  
  1164  	// move forwaubd in time, should complete the first redelegation, but not the second
  1165  	ctx.SetBlockTime(ctx.BlockHeader().Time.Add(5 * time.Second))
  1166  	EndBlocker(ctx, keeper)
  1167  	ubd, found = keeper.GetUnbondingDelegation(ctx, selfDelAddr, valAddr)
  1168  	require.True(t, found)
  1169  	require.Len(t, ubd.Entries, 1)
  1170  
  1171  	// move forwaubd in time, should complete the second redelegation
  1172  	ctx.SetBlockTime(ctx.BlockHeader().Time.Add(5 * time.Second))
  1173  	EndBlocker(ctx, keeper)
  1174  	ubd, found = keeper.GetUnbondingDelegation(ctx, selfDelAddr, valAddr)
  1175  	require.False(t, found)
  1176  }
  1177  
  1178  func TestUnbondingWhenExcessValidators(t *testing.T) {
  1179  	ctx, _, keeper, _ := keep.CreateTestInput(t, false, 1000)
  1180  	validatorAddr1 := sdk.ValAddress(keep.Addrs[0])
  1181  	validatorAddr2 := sdk.ValAddress(keep.Addrs[1])
  1182  	validatorAddr3 := sdk.ValAddress(keep.Addrs[2])
  1183  
  1184  	// set the unbonding time
  1185  	params := keeper.GetParams(ctx)
  1186  	params.MaxValidators = 2
  1187  	keeper.SetParams(ctx, params)
  1188  
  1189  	// add three validators
  1190  	valTokens1 := sdk.TokensFromConsensusPower(50)
  1191  	msgCreateValidator := NewTestMsgCreateValidator(validatorAddr1, keep.PKs[0], valTokens1)
  1192  	res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
  1193  	require.NoError(t, err)
  1194  	require.NotNil(t, res)
  1195  
  1196  	// apply TM updates
  1197  	keeper.ApplyAndReturnValidatorSetUpdates(ctx)
  1198  	require.Equal(t, 1, len(keeper.GetLastValidators(ctx)))
  1199  
  1200  	valTokens2 := sdk.TokensFromConsensusPower(30)
  1201  	msgCreateValidator = NewTestMsgCreateValidator(validatorAddr2, keep.PKs[1], valTokens2)
  1202  	res, err = handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
  1203  	require.NoError(t, err)
  1204  	require.NotNil(t, res)
  1205  
  1206  	// apply TM updates
  1207  	keeper.ApplyAndReturnValidatorSetUpdates(ctx)
  1208  	require.Equal(t, 2, len(keeper.GetLastValidators(ctx)))
  1209  
  1210  	valTokens3 := sdk.TokensFromConsensusPower(10)
  1211  	msgCreateValidator = NewTestMsgCreateValidator(validatorAddr3, keep.PKs[2], valTokens3)
  1212  	res, err = handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
  1213  	require.NoError(t, err)
  1214  	require.NotNil(t, res)
  1215  
  1216  	// apply TM updates
  1217  	keeper.ApplyAndReturnValidatorSetUpdates(ctx)
  1218  	require.Equal(t, 2, len(keeper.GetLastValidators(ctx)))
  1219  
  1220  	// unbond the validator-2
  1221  	unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, valTokens2)
  1222  	msgUndelegate := NewMsgUndelegate(sdk.AccAddress(validatorAddr2), validatorAddr2, unbondAmt)
  1223  	res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper)
  1224  	require.NoError(t, err)
  1225  	require.NotNil(t, res)
  1226  
  1227  	// apply TM updates
  1228  	keeper.ApplyAndReturnValidatorSetUpdates(ctx)
  1229  
  1230  	// because there are extra validators waiting to get in, the queued
  1231  	// validator (aka. validator-1) should make it into the bonded group, thus
  1232  	// the total number of validators should stay the same
  1233  	vals := keeper.GetLastValidators(ctx)
  1234  	require.Equal(t, 2, len(vals), "vals %v", vals)
  1235  	val1, found := keeper.GetValidator(ctx, validatorAddr1)
  1236  	require.True(t, found)
  1237  	require.Equal(t, sdk.Bonded, val1.Status, "%v", val1)
  1238  }
  1239  
  1240  func TestBondUnbondRedelegateSlashTwice(t *testing.T) {
  1241  	ctx, _, keeper, _ := keep.CreateTestInput(t, false, 1000)
  1242  	valA, valB, del := sdk.ValAddress(keep.Addrs[0]), sdk.ValAddress(keep.Addrs[1]), keep.Addrs[2]
  1243  	consAddr0 := sdk.ConsAddress(keep.PKs[0].Address())
  1244  
  1245  	valTokens := sdk.TokensFromConsensusPower(10)
  1246  	msgCreateValidator := NewTestMsgCreateValidator(valA, keep.PKs[0], valTokens)
  1247  	res, err := handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
  1248  	require.NoError(t, err)
  1249  	require.NotNil(t, res)
  1250  
  1251  	msgCreateValidator = NewTestMsgCreateValidator(valB, keep.PKs[1], valTokens)
  1252  	res, err = handleMsgCreateValidator(ctx, msgCreateValidator, keeper)
  1253  	require.NoError(t, err)
  1254  	require.NotNil(t, res)
  1255  
  1256  	// delegate 10 stake
  1257  	msgDelegate := NewTestMsgDelegate(del, valA, valTokens)
  1258  	res, err = handleMsgDelegate(ctx, msgDelegate, keeper)
  1259  	require.NoError(t, err)
  1260  	require.NotNil(t, res)
  1261  
  1262  	// apply Tendermint updates
  1263  	updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx)
  1264  	require.Equal(t, 2, len(updates))
  1265  
  1266  	// a block passes
  1267  	ctx.SetBlockHeight(1)
  1268  
  1269  	// begin unbonding 4 stake
  1270  	unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(4))
  1271  	msgUndelegate := NewMsgUndelegate(del, valA, unbondAmt)
  1272  	res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper)
  1273  	require.NoError(t, err)
  1274  	require.NotNil(t, res)
  1275  
  1276  	// begin redelegate 6 stake
  1277  	redAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(6))
  1278  	msgBeginRedelegate := NewMsgBeginRedelegate(del, valA, valB, redAmt)
  1279  	res, err = handleMsgBeginRedelegate(ctx, msgBeginRedelegate, keeper)
  1280  	require.NoError(t, err)
  1281  	require.NotNil(t, res)
  1282  
  1283  	// destination delegation should have 6 shares
  1284  	delegation, found := keeper.GetDelegation(ctx, del, valB)
  1285  	require.True(t, found)
  1286  	require.Equal(t, redAmt.Amount, delegation.Shares)
  1287  
  1288  	// must apply validator updates
  1289  	updates = keeper.ApplyAndReturnValidatorSetUpdates(ctx)
  1290  	require.Equal(t, 2, len(updates))
  1291  
  1292  	// slash the validator by half
  1293  	keeper.Slash(ctx, consAddr0, 0, 20, sdk.NewDecWithPrec(5, 1))
  1294  
  1295  	// unbonding delegation should have been slashed by half
  1296  	ubd, found := keeper.GetUnbondingDelegation(ctx, del, valA)
  1297  	require.True(t, found)
  1298  	require.Len(t, ubd.Entries, 1)
  1299  	require.Equal(t, unbondAmt.Amount.QuoInt64(2).Int, ubd.Entries[0].Balance.ToDec().Int)
  1300  
  1301  	// redelegation should have been slashed by half
  1302  	redelegation, found := keeper.GetRedelegation(ctx, del, valA, valB)
  1303  	require.True(t, found)
  1304  	require.Len(t, redelegation.Entries, 1)
  1305  
  1306  	// destination delegation should have been slashed by half
  1307  	delegation, found = keeper.GetDelegation(ctx, del, valB)
  1308  	require.True(t, found)
  1309  	require.Equal(t, redAmt.Amount.QuoInt64(2), delegation.Shares)
  1310  
  1311  	// validator power should have been reduced by half
  1312  	validator, found := keeper.GetValidator(ctx, valA)
  1313  	require.True(t, found)
  1314  	require.Equal(t, valTokens.QuoRaw(2), validator.GetBondedTokens())
  1315  
  1316  	// slash the validator for an infraction committed after the unbonding and redelegation begin
  1317  	ctx.SetBlockHeight(3)
  1318  	keeper.Slash(ctx, consAddr0, 2, 10, sdk.NewDecWithPrec(5, 1))
  1319  
  1320  	// unbonding delegation should be unchanged
  1321  	ubd, found = keeper.GetUnbondingDelegation(ctx, del, valA)
  1322  	require.True(t, found)
  1323  	require.Len(t, ubd.Entries, 1)
  1324  	require.Equal(t, unbondAmt.Amount.QuoInt64(2).Int, ubd.Entries[0].Balance.ToDec().Int)
  1325  
  1326  	// redelegation should be unchanged
  1327  	redelegation, found = keeper.GetRedelegation(ctx, del, valA, valB)
  1328  	require.True(t, found)
  1329  	require.Len(t, redelegation.Entries, 1)
  1330  
  1331  	// destination delegation should be unchanged
  1332  	delegation, found = keeper.GetDelegation(ctx, del, valB)
  1333  	require.True(t, found)
  1334  	require.Equal(t, redAmt.Amount.QuoInt64(2), delegation.Shares)
  1335  
  1336  	// end blocker
  1337  	EndBlocker(ctx, keeper)
  1338  
  1339  	// validator power should have been reduced to zero
  1340  	// validator should be in unbonding state
  1341  	validator, _ = keeper.GetValidator(ctx, valA)
  1342  	require.Equal(t, validator.GetStatus(), sdk.Unbonding)
  1343  }
  1344  
  1345  func TestInvalidMsg(t *testing.T) {
  1346  	k := keep.Keeper{}
  1347  	h := NewHandler(k)
  1348  
  1349  	res, err := h(sdk.NewContext(nil, abci.Header{}, false, nil), sdk.NewTestMsg())
  1350  	require.Error(t, err)
  1351  	require.Nil(t, res)
  1352  	require.True(t, strings.Contains(err.Error(), "unrecognized staking message type"))
  1353  }
  1354  
  1355  func TestInvalidCoinDenom(t *testing.T) {
  1356  	ctx, _, keeper, _ := keep.CreateTestInput(t, false, 1000)
  1357  	valA, valB, delAddr := sdk.ValAddress(keep.Addrs[0]), sdk.ValAddress(keep.Addrs[1]), keep.Addrs[2]
  1358  
  1359  	valTokens := sdk.TokensFromConsensusPower(100)
  1360  	invalidCoin := sdk.NewCoin("churros", valTokens)
  1361  	validCoin := sdk.NewCoin(sdk.DefaultBondDenom, valTokens)
  1362  	oneCoin := sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneInt())
  1363  
  1364  	commission := types.NewCommissionRates(sdk.OneDec(), sdk.OneDec(), sdk.ZeroDec())
  1365  
  1366  	msgCreate := types.NewMsgCreateValidator(valA, keep.PKs[0], invalidCoin, Description{}, commission, sdk.OneInt())
  1367  	res, err := handleMsgCreateValidator(ctx, msgCreate, keeper)
  1368  	require.Error(t, err)
  1369  	require.Nil(t, res)
  1370  
  1371  	msgCreate = types.NewMsgCreateValidator(valA, keep.PKs[0], validCoin, Description{}, commission, sdk.OneInt())
  1372  	res, err = handleMsgCreateValidator(ctx, msgCreate, keeper)
  1373  	require.NoError(t, err)
  1374  	require.NotNil(t, res)
  1375  
  1376  	msgCreate = types.NewMsgCreateValidator(valB, keep.PKs[1], validCoin, Description{}, commission, sdk.OneInt())
  1377  	res, err = handleMsgCreateValidator(ctx, msgCreate, keeper)
  1378  	require.NoError(t, err)
  1379  	require.NotNil(t, res)
  1380  
  1381  	msgDelegate := types.NewMsgDelegate(delAddr, valA, invalidCoin)
  1382  	res, err = handleMsgDelegate(ctx, msgDelegate, keeper)
  1383  	require.Error(t, err)
  1384  	require.Nil(t, res)
  1385  
  1386  	msgDelegate = types.NewMsgDelegate(delAddr, valA, validCoin)
  1387  	res, err = handleMsgDelegate(ctx, msgDelegate, keeper)
  1388  	require.NoError(t, err)
  1389  	require.NotNil(t, res)
  1390  
  1391  	msgUndelegate := types.NewMsgUndelegate(delAddr, valA, invalidCoin)
  1392  	res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper)
  1393  	require.Error(t, err)
  1394  	require.Nil(t, res)
  1395  
  1396  	msgUndelegate = types.NewMsgUndelegate(delAddr, valA, oneCoin)
  1397  	res, err = handleMsgUndelegate(ctx, msgUndelegate, keeper)
  1398  	require.NoError(t, err)
  1399  	require.NotNil(t, res)
  1400  
  1401  	msgRedelegate := types.NewMsgBeginRedelegate(delAddr, valA, valB, invalidCoin)
  1402  	res, err = handleMsgBeginRedelegate(ctx, msgRedelegate, keeper)
  1403  	require.Error(t, err)
  1404  	require.Nil(t, res)
  1405  
  1406  	msgRedelegate = types.NewMsgBeginRedelegate(delAddr, valA, valB, oneCoin)
  1407  	res, err = handleMsgBeginRedelegate(ctx, msgRedelegate, keeper)
  1408  	require.NoError(t, err)
  1409  	require.NotNil(t, res)
  1410  }