package staking_test import ( "testing" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto/secp256k1" tmtypes "github.com/tendermint/tendermint/types" "github.com/stretchr/testify/assert" gogotypes "github.com/gogo/protobuf/types" "github.com/stretchr/testify/require" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/staking" "github.com/cosmos/cosmos-sdk/x/staking/keeper" "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/cosmos/cosmos-sdk/x/supply" ) func bootstrapHandlerGenesisTest(t *testing.T, power int64, numAddrs int, accAmount int64) (*simapp.SimApp, sdk.Context, []sdk.AccAddress, []sdk.ValAddress) { _, app, ctx := getBaseSimappWithCustomKeeper() addrDels, addrVals := generateAddresses(app, ctx, numAddrs, accAmount) amt := sdk.TokensFromConsensusPower(power) totalSupply := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), amt.MulRaw(int64(len(addrDels))))) notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) err := app.BankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), totalSupply) require.NoError(t, err) app.SupplyKeeper.SetModuleAccount(ctx, notBondedPool) app.SupplyKeeper.SetSupply(ctx, supply.NewSupply(totalSupply)) return app, ctx, addrDels, addrVals } func TestValidatorByPowerIndex(t *testing.T) { initPower := int64(1000000) initBond := sdk.TokensFromConsensusPower(initPower) app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 10, 10000000000000) validatorAddr, validatorAddr3 := valAddrs[0], valAddrs[1] handler := staking.NewHandler(app.StakingKeeper) // create validator msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, PKs[0], initBond) res, err := handler(ctx, msgCreateValidator) require.NoError(t, err) require.NotNil(t, res) // must end-block updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 1, len(updates)) // verify the self-delegation exists bond, found := app.StakingKeeper.GetDelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr) require.True(t, found) gotBond := bond.Shares.RoundInt() require.Equal(t, initBond, gotBond) // verify that the by power index exists validator, found := app.StakingKeeper.GetValidator(ctx, validatorAddr) require.True(t, found) power := staking.GetValidatorsByPowerIndexKey(validator) require.True(t, keeper.ValidatorByPowerIndexExists(ctx, app.StakingKeeper, power)) // create a second validator keep it bonded msgCreateValidator = NewTestMsgCreateValidator(validatorAddr3, PKs[2], initBond) res, err = handler(ctx, msgCreateValidator) require.NoError(t, err) require.NotNil(t, res) // must end-block updates = app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 1, len(updates)) // slash and jail the first validator consAddr0 := sdk.ConsAddress(PKs[0].Address()) app.StakingKeeper.Slash(ctx, consAddr0, 0, initPower, sdk.NewDecWithPrec(5, 1)) app.StakingKeeper.Jail(ctx, consAddr0) app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) validator, found = app.StakingKeeper.GetValidator(ctx, validatorAddr) require.True(t, found) require.Equal(t, sdk.Unbonding, validator.Status) // ensure is unbonding require.Equal(t, initBond.QuoRaw(2), validator.Tokens) // ensure tokens slashed app.StakingKeeper.Unjail(ctx, consAddr0) // the old power record should have been deleted as the power changed require.False(t, keeper.ValidatorByPowerIndexExists(ctx, app.StakingKeeper, power)) // but the new power record should have been created validator, found = app.StakingKeeper.GetValidator(ctx, validatorAddr) require.True(t, found) power2 := staking.GetValidatorsByPowerIndexKey(validator) require.True(t, keeper.ValidatorByPowerIndexExists(ctx, app.StakingKeeper, power2)) // now the new record power index should be the same as the original record power3 := staking.GetValidatorsByPowerIndexKey(validator) require.Equal(t, power2, power3) // unbond self-delegation totalBond := validator.TokensFromShares(bond.GetShares()).TruncateInt() unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, totalBond) msgUndelegate := staking.NewMsgUndelegate(sdk.AccAddress(validatorAddr), validatorAddr, unbondAmt) res, err = handler(ctx, msgUndelegate) require.NoError(t, err) require.NotNil(t, res) ts := &gogotypes.Timestamp{} types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, ts) finishTime, err := gogotypes.TimestampFromProto(ts) require.NoError(t, err) ctx = ctx.WithBlockTime(finishTime) staking.EndBlocker(ctx, app.StakingKeeper) staking.EndBlocker(ctx, app.StakingKeeper) // verify that by power key nolonger exists _, found = app.StakingKeeper.GetValidator(ctx, validatorAddr) require.False(t, found) require.False(t, keeper.ValidatorByPowerIndexExists(ctx, app.StakingKeeper, power3)) } func TestDuplicatesMsgCreateValidator(t *testing.T) { initPower := int64(1000000) app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 10, 10000000000000) handler := staking.NewHandler(app.StakingKeeper) addr1, addr2 := valAddrs[0], valAddrs[1] pk1, pk2 := PKs[0], PKs[1] valTokens := sdk.TokensFromConsensusPower(10) msgCreateValidator1 := NewTestMsgCreateValidator(addr1, pk1, valTokens) res, err := handler(ctx, msgCreateValidator1) require.NoError(t, err) require.NotNil(t, res) app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) validator, found := app.StakingKeeper.GetValidator(ctx, addr1) require.True(t, found) assert.Equal(t, sdk.Bonded, validator.Status) assert.Equal(t, addr1, validator.OperatorAddress) assert.Equal(t, pk1, validator.GetConsPubKey()) assert.Equal(t, valTokens, validator.BondedTokens()) assert.Equal(t, valTokens.ToDec(), validator.DelegatorShares) assert.Equal(t, types.Description{}, validator.Description) // two validators can't have the same operator address msgCreateValidator2 := NewTestMsgCreateValidator(addr1, pk2, valTokens) res, err = handler(ctx, msgCreateValidator2) require.Error(t, err) require.Nil(t, res) // two validators can't have the same pubkey msgCreateValidator3 := NewTestMsgCreateValidator(addr2, pk1, valTokens) res, err = handler(ctx, msgCreateValidator3) require.Error(t, err) require.Nil(t, res) // must have different pubkey and operator msgCreateValidator4 := NewTestMsgCreateValidator(addr2, pk2, valTokens) res, err = handler(ctx, msgCreateValidator4) require.NoError(t, err) require.NotNil(t, res) // must end-block updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 1, len(updates)) validator, found = app.StakingKeeper.GetValidator(ctx, addr2) require.True(t, found) assert.Equal(t, sdk.Bonded, validator.Status) assert.Equal(t, addr2, validator.OperatorAddress) assert.Equal(t, pk2, validator.GetConsPubKey()) assert.True(sdk.IntEq(t, valTokens, validator.Tokens)) assert.True(sdk.DecEq(t, valTokens.ToDec(), validator.DelegatorShares)) assert.Equal(t, types.Description{}, validator.Description) } func TestInvalidPubKeyTypeMsgCreateValidator(t *testing.T) { app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 1, 1000) handler := staking.NewHandler(app.StakingKeeper) ctx = ctx.WithConsensusParams(&abci.ConsensusParams{ Validator: &abci.ValidatorParams{PubKeyTypes: []string{tmtypes.ABCIPubKeyTypeEd25519}}, }) addr := valAddrs[0] invalidPk := secp256k1.GenPrivKey().PubKey() // invalid pukKey type should not be allowed msgCreateValidator := NewTestMsgCreateValidator(addr, invalidPk, sdk.NewInt(10)) res, err := handler(ctx, msgCreateValidator) require.Error(t, err) require.Nil(t, res) ctx = ctx.WithConsensusParams(&abci.ConsensusParams{ Validator: &abci.ValidatorParams{PubKeyTypes: []string{tmtypes.ABCIPubKeyTypeSecp256k1}}, }) res, err = handler(ctx, msgCreateValidator) require.NoError(t, err) require.NotNil(t, res) } // //func TestLegacyValidatorDelegations(t *testing.T) { // ctx, _, _, keeper, _ := CreateTestInput(t, false, int64(1000)) // handler := NewHandler(keeper) // // bondAmount := sdk.TokensFromConsensusPower(10) // valAddr := sdk.ValAddress(Addrs[0]) // valConsPubKey, valConsAddr := PKs[0], sdk.ConsAddress(PKs[0].Address()) // delAddr := Addrs[1] // // // create validator // msgCreateVal := NewTestMsgCreateValidator(valAddr, valConsPubKey, bondAmount) // res, err := handler(ctx, msgCreateVal) // require.NoError(t, err) // require.NotNil(t, res) // // // must end-block // updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) // require.Equal(t, 1, len(updates)) // // // verify the validator exists and has the correct attributes // validator, found := keeper.GetValidator(ctx, valAddr) // require.True(t, found) // require.Equal(t, sdk.Bonded, validator.Status) // require.Equal(t, bondAmount, validator.DelegatorShares.RoundInt()) // require.Equal(t, bondAmount, validator.BondedTokens()) // // // delegate tokens to the validator // msgDelegate := NewTestMsgDelegate(delAddr, valAddr, bondAmount) // res, err = handler(ctx, msgDelegate) // require.NoError(t, err) // require.NotNil(t, res) // // // verify validator bonded shares // validator, found = keeper.GetValidator(ctx, valAddr) // require.True(t, found) // require.Equal(t, bondAmount.MulRaw(2), validator.DelegatorShares.RoundInt()) // require.Equal(t, bondAmount.MulRaw(2), validator.BondedTokens()) // // // unbond validator total self-delegations (which should jail the validator) // unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, bondAmount) // msgUndelegate := NewMsgUndelegate(sdk.AccAddress(valAddr), valAddr, unbondAmt) // // res, err = handler(ctx, msgUndelegate) // require.NoError(t, err) // require.NotNil(t, res) // // ts := &gogotypes.Timestamp{} // types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, ts) // // finishTime, err := gogotypes.TimestampFromProto(ts) // require.NoError(t, err) // // ctx = ctx.WithBlockTime(finishTime) // EndBlocker(ctx, keeper) // // // verify the validator record still exists, is jailed, and has correct tokens // validator, found = keeper.GetValidator(ctx, valAddr) // require.True(t, found) // require.True(t, validator.Jailed) // require.Equal(t, bondAmount, validator.Tokens) // // // verify delegation still exists // bond, found := keeper.GetDelegation(ctx, delAddr, valAddr) // require.True(t, found) // require.Equal(t, bondAmount, bond.Shares.RoundInt()) // require.Equal(t, bondAmount, validator.DelegatorShares.RoundInt()) // // // verify the validator can still self-delegate // msgSelfDelegate := NewTestMsgDelegate(sdk.AccAddress(valAddr), valAddr, bondAmount) // res, err = handler(ctx, msgSelfDelegate) // require.NoError(t, err) // require.NotNil(t, res) // // // verify validator bonded shares // validator, found = keeper.GetValidator(ctx, valAddr) // require.True(t, found) // require.Equal(t, bondAmount.MulRaw(2), validator.DelegatorShares.RoundInt()) // require.Equal(t, bondAmount.MulRaw(2), validator.Tokens) // // // unjail the validator now that is has non-zero self-delegated shares // keeper.Unjail(ctx, valConsAddr) // // // verify the validator can now accept delegations // msgDelegate = NewTestMsgDelegate(delAddr, valAddr, bondAmount) // res, err = handler(ctx, msgDelegate) // require.NoError(t, err) // require.NotNil(t, res) // // // verify validator bonded shares // validator, found = keeper.GetValidator(ctx, valAddr) // require.True(t, found) // require.Equal(t, bondAmount.MulRaw(3), validator.DelegatorShares.RoundInt()) // require.Equal(t, bondAmount.MulRaw(3), validator.Tokens) // // // verify new delegation // bond, found = keeper.GetDelegation(ctx, delAddr, valAddr) // require.True(t, found) // require.Equal(t, bondAmount.MulRaw(2), bond.Shares.RoundInt()) // require.Equal(t, bondAmount.MulRaw(3), validator.DelegatorShares.RoundInt()) //} // //func TestIncrementsMsgDelegate(t *testing.T) { // initPower := int64(1000) // initBond := sdk.TokensFromConsensusPower(initPower) // ctx, _, bk, keeper, _ := CreateTestInput(t, false, initPower) // handler := NewHandler(keeper) // // params := keeper.GetParams(ctx) // // bondAmount := sdk.TokensFromConsensusPower(10) // validatorAddr, delegatorAddr := sdk.ValAddress(Addrs[0]), Addrs[1] // // // first create validator // msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, PKs[0], bondAmount) // res, err := handler(ctx, msgCreateValidator) // require.NoError(t, err) // require.NotNil(t, res) // // // apply TM updates // keeper.ApplyAndReturnValidatorSetUpdates(ctx) // // validator, found := keeper.GetValidator(ctx, validatorAddr) // require.True(t, found) // require.Equal(t, sdk.Bonded, validator.Status) // require.Equal(t, bondAmount, validator.DelegatorShares.RoundInt()) // require.Equal(t, bondAmount, validator.BondedTokens(), "validator: %v", validator) // // _, found = keeper.GetDelegation(ctx, delegatorAddr, validatorAddr) // require.False(t, found) // // bond, found := keeper.GetDelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr) // require.True(t, found) // require.Equal(t, bondAmount, bond.Shares.RoundInt()) // // bondedTokens := keeper.TotalBondedTokens(ctx) // require.Equal(t, bondAmount.Int64(), bondedTokens.Int64()) // // // just send the same msgbond multiple times // msgDelegate := NewTestMsgDelegate(delegatorAddr, validatorAddr, bondAmount) // // for i := int64(0); i < 5; i++ { // ctx = ctx.WithBlockHeight(i) // // res, err := handler(ctx, msgDelegate) // require.NoError(t, err) // require.NotNil(t, res) // // //Check that the accounts and the bond account have the appropriate values // validator, found := keeper.GetValidator(ctx, validatorAddr) // require.True(t, found) // bond, found := keeper.GetDelegation(ctx, delegatorAddr, validatorAddr) // require.True(t, found) // // expBond := bondAmount.MulRaw(i + 1) // expDelegatorShares := bondAmount.MulRaw(i + 2) // (1 self delegation) // expDelegatorAcc := initBond.Sub(expBond) // // gotBond := bond.Shares.RoundInt() // gotDelegatorShares := validator.DelegatorShares.RoundInt() // gotDelegatorAcc := bk.GetBalance(ctx, delegatorAddr, params.BondDenom).Amount // // require.Equal(t, expBond, gotBond, // "i: %v\nexpBond: %v\ngotBond: %v\nvalidator: %v\nbond: %v\n", // i, expBond, gotBond, validator, bond) // require.Equal(t, expDelegatorShares, gotDelegatorShares, // "i: %v\nexpDelegatorShares: %v\ngotDelegatorShares: %v\nvalidator: %v\nbond: %v\n", // i, expDelegatorShares, gotDelegatorShares, validator, bond) // require.Equal(t, expDelegatorAcc, gotDelegatorAcc, // "i: %v\nexpDelegatorAcc: %v\ngotDelegatorAcc: %v\nvalidator: %v\nbond: %v\n", // i, expDelegatorAcc, gotDelegatorAcc, validator, bond) // } //} // //func TestEditValidatorDecreaseMinSelfDelegation(t *testing.T) { // validatorAddr := sdk.ValAddress(Addrs[0]) // // initPower := int64(100) // initBond := sdk.TokensFromConsensusPower(100) // ctx, _, _, keeper, _ := CreateTestInput(t, false, initPower) // handler := NewHandler(keeper) // // // create validator // msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, PKs[0], initBond) // msgCreateValidator.MinSelfDelegation = sdk.NewInt(2) // res, err := handler(ctx, msgCreateValidator) // require.NoError(t, err) // require.NotNil(t, res) // // // must end-block // updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) // require.Equal(t, 1, len(updates)) // // // verify the self-delegation exists // bond, found := keeper.GetDelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr) // require.True(t, found) // gotBond := bond.Shares.RoundInt() // require.Equal(t, initBond, gotBond, // "initBond: %v\ngotBond: %v\nbond: %v\n", // initBond, gotBond, bond) // // newMinSelfDelegation := sdk.OneInt() // msgEditValidator := NewMsgEditValidator(validatorAddr, Description{}, nil, &newMinSelfDelegation) // res, err = handler(ctx, msgEditValidator) // require.Error(t, err) // require.Nil(t, res) //} // //func TestEditValidatorIncreaseMinSelfDelegationBeyondCurrentBond(t *testing.T) { // validatorAddr := sdk.ValAddress(Addrs[0]) // // initPower := int64(100) // initBond := sdk.TokensFromConsensusPower(100) // ctx, _, _, keeper, _ := CreateTestInput(t, false, initPower) // handler := NewHandler(keeper) // // // create validator // msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, PKs[0], initBond) // msgCreateValidator.MinSelfDelegation = sdk.NewInt(2) // res, err := handler(ctx, msgCreateValidator) // require.NoError(t, err) // require.NotNil(t, res) // // // must end-block // updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) // require.Equal(t, 1, len(updates)) // // // verify the self-delegation exists // bond, found := keeper.GetDelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr) // require.True(t, found) // gotBond := bond.Shares.RoundInt() // require.Equal(t, initBond, gotBond, // "initBond: %v\ngotBond: %v\nbond: %v\n", // initBond, gotBond, bond) // // newMinSelfDelegation := initBond.Add(sdk.OneInt()) // msgEditValidator := NewMsgEditValidator(validatorAddr, Description{}, nil, &newMinSelfDelegation) // res, err = handler(ctx, msgEditValidator) // require.Error(t, err) // require.Nil(t, res) //} // //func TestIncrementsMsgUnbond(t *testing.T) { // initPower := int64(1000) // initBond := sdk.TokensFromConsensusPower(initPower) // ctx, _, bk, keeper, _ := CreateTestInput(t, false, initPower) // handler := NewHandler(keeper) // // params := keeper.GetParams(ctx) // denom := params.BondDenom // // // create validator, delegate // validatorAddr, delegatorAddr := sdk.ValAddress(Addrs[0]), Addrs[1] // // msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, PKs[0], initBond) // res, err := handler(ctx, msgCreateValidator) // require.NoError(t, err) // require.NotNil(t, res) // // // initial balance // amt1 := bk.GetBalance(ctx, delegatorAddr, denom).Amount // // msgDelegate := NewTestMsgDelegate(delegatorAddr, validatorAddr, initBond) // res, err = handler(ctx, msgDelegate) // require.NoError(t, err) // require.NotNil(t, res) // // // balance should have been subtracted after delegation // amt2 := bk.GetBalance(ctx, delegatorAddr, denom).Amount // require.True(sdk.IntEq(t, amt1.Sub(initBond), amt2)) // // // apply TM updates // keeper.ApplyAndReturnValidatorSetUpdates(ctx) // // validator, found := keeper.GetValidator(ctx, validatorAddr) // require.True(t, found) // require.Equal(t, initBond.MulRaw(2), validator.DelegatorShares.RoundInt()) // require.Equal(t, initBond.MulRaw(2), validator.BondedTokens()) // // // just send the same msgUnbond multiple times // // TODO use decimals here // unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)) // msgUndelegate := NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt) // numUnbonds := int64(5) // // for i := int64(0); i < numUnbonds; i++ { // res, err := handler(ctx, msgUndelegate) // require.NoError(t, err) // require.NotNil(t, res) // // ts := &gogotypes.Timestamp{} // types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, ts) // // finishTime, err := gogotypes.TimestampFromProto(ts) // require.NoError(t, err) // // ctx = ctx.WithBlockTime(finishTime) // EndBlocker(ctx, keeper) // // // check that the accounts and the bond account have the appropriate values // validator, found = keeper.GetValidator(ctx, validatorAddr) // require.True(t, found) // bond, found := keeper.GetDelegation(ctx, delegatorAddr, validatorAddr) // require.True(t, found) // // expBond := initBond.Sub(unbondAmt.Amount.Mul(sdk.NewInt(i + 1))) // expDelegatorShares := initBond.MulRaw(2).Sub(unbondAmt.Amount.Mul(sdk.NewInt(i + 1))) // expDelegatorAcc := initBond.Sub(expBond) // // gotBond := bond.Shares.RoundInt() // gotDelegatorShares := validator.DelegatorShares.RoundInt() // gotDelegatorAcc := bk.GetBalance(ctx, delegatorAddr, params.BondDenom).Amount // // require.Equal(t, expBond.Int64(), gotBond.Int64(), // "i: %v\nexpBond: %v\ngotBond: %v\nvalidator: %v\nbond: %v\n", // i, expBond, gotBond, validator, bond) // require.Equal(t, expDelegatorShares.Int64(), gotDelegatorShares.Int64(), // "i: %v\nexpDelegatorShares: %v\ngotDelegatorShares: %v\nvalidator: %v\nbond: %v\n", // i, expDelegatorShares, gotDelegatorShares, validator, bond) // require.Equal(t, expDelegatorAcc.Int64(), gotDelegatorAcc.Int64(), // "i: %v\nexpDelegatorAcc: %v\ngotDelegatorAcc: %v\nvalidator: %v\nbond: %v\n", // i, expDelegatorAcc, gotDelegatorAcc, validator, bond) // } // // // these are more than we have bonded now // errorCases := []sdk.Int{ // //1<<64 - 1, // more than int64 power // //1<<63 + 1, // more than int64 power // sdk.TokensFromConsensusPower(1<<63 - 1), // sdk.TokensFromConsensusPower(1 << 31), // initBond, // } // // for _, c := range errorCases { // unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, c) // msgUndelegate := NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt) // res, err = handler(ctx, msgUndelegate) // require.Error(t, err) // require.Nil(t, res) // } // // leftBonded := initBond.Sub(unbondAmt.Amount.Mul(sdk.NewInt(numUnbonds))) // // // should be able to unbond remaining // unbondAmt = sdk.NewCoin(sdk.DefaultBondDenom, leftBonded) // msgUndelegate = NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt) // res, err = handler(ctx, msgUndelegate) // require.NoError(t, err, "msgUnbond: %v\nshares: %s\nleftBonded: %s\n", msgUndelegate, unbondAmt, leftBonded) // require.NotNil(t, res, "msgUnbond: %v\nshares: %s\nleftBonded: %s\n", msgUndelegate, unbondAmt, leftBonded) //} // //func TestMultipleMsgCreateValidator(t *testing.T) { // initPower := int64(1000) // initTokens := sdk.TokensFromConsensusPower(initPower) // ctx, _, bk, keeper, _ := CreateTestInput(t, false, initPower) // handler := NewHandler(keeper) // // params := keeper.GetParams(ctx) // blockTime := time.Now().UTC() // ctx = ctx.WithBlockTime(blockTime) // // validatorAddrs := []sdk.ValAddress{ // sdk.ValAddress(Addrs[0]), // sdk.ValAddress(Addrs[1]), // sdk.ValAddress(Addrs[2]), // } // delegatorAddrs := []sdk.AccAddress{ // Addrs[0], // Addrs[1], // Addrs[2], // } // // // bond them all // for i, validatorAddr := range validatorAddrs { // valTokens := sdk.TokensFromConsensusPower(10) // msgCreateValidatorOnBehalfOf := NewTestMsgCreateValidator(validatorAddr, PKs[i], valTokens) // // res, err := handler(ctx, msgCreateValidatorOnBehalfOf) // require.NoError(t, err) // require.NotNil(t, res) // // // verify that the account is bonded // validators := keeper.GetValidators(ctx, 100) // require.Equal(t, (i + 1), len(validators)) // // val := validators[i] // balanceExpd := initTokens.Sub(valTokens) // balanceGot := bk.GetBalance(ctx, delegatorAddrs[i], params.BondDenom).Amount // // require.Equal(t, i+1, len(validators), "expected %d validators got %d, validators: %v", i+1, len(validators), validators) // require.Equal(t, valTokens, val.DelegatorShares.RoundInt(), "expected %d shares, got %d", 10, val.DelegatorShares) // require.Equal(t, balanceExpd, balanceGot, "expected account to have %d, got %d", balanceExpd, balanceGot) // } // // EndBlocker(ctx, keeper) // // // unbond them all by removing delegation // for i, validatorAddr := range validatorAddrs { // _, found := keeper.GetValidator(ctx, validatorAddr) // require.True(t, found) // // unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(10)) // msgUndelegate := NewMsgUndelegate(delegatorAddrs[i], validatorAddr, unbondAmt) // remove delegation // res, err := handler(ctx, msgUndelegate) // require.NoError(t, err) // require.NotNil(t, res) // // ts := &gogotypes.Timestamp{} // types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, ts) // // _, err = gogotypes.TimestampFromProto(ts) // require.NoError(t, err) // // // adds validator into unbonding queue // EndBlocker(ctx, keeper) // // // removes validator from queue and set // EndBlocker(ctx.WithBlockTime(blockTime.Add(params.UnbondingTime)), keeper) // // // Check that the validator is deleted from state // validators := keeper.GetValidators(ctx, 100) // require.Equal(t, len(validatorAddrs)-(i+1), len(validators), // "expected %d validators got %d", len(validatorAddrs)-(i+1), len(validators)) // // _, found = keeper.GetValidator(ctx, validatorAddr) // require.False(t, found) // // gotBalance := bk.GetBalance(ctx, delegatorAddrs[i], params.BondDenom).Amount // require.Equal(t, initTokens, gotBalance, "expected account to have %d, got %d", initTokens, gotBalance) // } //} // //func TestMultipleMsgDelegate(t *testing.T) { // ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) // handler := NewHandler(keeper) // validatorAddr, delegatorAddrs := sdk.ValAddress(Addrs[0]), Addrs[1:] // // // first make a validator // msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, PKs[0], sdk.NewInt(10)) // res, err := handler(ctx, msgCreateValidator) // require.NoError(t, err) // require.NotNil(t, res) // // // delegate multiple parties // for _, delegatorAddr := range delegatorAddrs { // msgDelegate := NewTestMsgDelegate(delegatorAddr, validatorAddr, sdk.NewInt(10)) // res, err := handler(ctx, msgDelegate) // require.NoError(t, err) // require.NotNil(t, res) // // // check that the account is bonded // bond, found := keeper.GetDelegation(ctx, delegatorAddr, validatorAddr) // require.True(t, found) // require.NotNil(t, bond, "expected delegatee bond %d to exist", bond) // } // // // unbond them all // for _, delegatorAddr := range delegatorAddrs { // unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)) // msgUndelegate := NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt) // // res, err := handler(ctx, msgUndelegate) // require.NoError(t, err) // require.NotNil(t, res) // // ts := &gogotypes.Timestamp{} // types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, ts) // // finishTime, err := gogotypes.TimestampFromProto(ts) // require.NoError(t, err) // // ctx = ctx.WithBlockTime(finishTime) // EndBlocker(ctx, keeper) // // // check that the account is unbonded // _, found := keeper.GetDelegation(ctx, delegatorAddr, validatorAddr) // require.False(t, found) // } //} // //func TestJailValidator(t *testing.T) { // ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) // handler := NewHandler(keeper) // validatorAddr, delegatorAddr := sdk.ValAddress(Addrs[0]), Addrs[1] // // // create the validator // msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, PKs[0], sdk.NewInt(10)) // res, err := handler(ctx, msgCreateValidator) // require.NoError(t, err) // require.NotNil(t, res) // // // bond a delegator // msgDelegate := NewTestMsgDelegate(delegatorAddr, validatorAddr, sdk.NewInt(10)) // res, err = handler(ctx, msgDelegate) // require.NoError(t, err) // require.NotNil(t, res) // // // unbond the validators bond portion // unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)) // msgUndelegateValidator := NewMsgUndelegate(sdk.AccAddress(validatorAddr), validatorAddr, unbondAmt) // res, err = handler(ctx, msgUndelegateValidator) // require.NoError(t, err) // require.NotNil(t, res) // // ts := &gogotypes.Timestamp{} // types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, ts) // // finishTime, err := gogotypes.TimestampFromProto(ts) // require.NoError(t, err) // // ctx = ctx.WithBlockTime(finishTime) // EndBlocker(ctx, keeper) // // validator, found := keeper.GetValidator(ctx, validatorAddr) // require.True(t, found) // require.True(t, validator.Jailed, "%v", validator) // // // test that the delegator can still withdraw their bonds // msgUndelegateDelegator := NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt) // // res, err = handler(ctx, msgUndelegateDelegator) // require.NoError(t, err) // require.NotNil(t, res) // // ts = &gogotypes.Timestamp{} // types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, ts) // // finishTime, err = gogotypes.TimestampFromProto(ts) // require.NoError(t, err) // // ctx = ctx.WithBlockTime(finishTime) // EndBlocker(ctx, keeper) // // // verify that the pubkey can now be reused // res, err = handler(ctx, msgCreateValidator) // require.NoError(t, err) // require.NotNil(t, res) //} // //func TestValidatorQueue(t *testing.T) { // ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) // handler := NewHandler(keeper) // validatorAddr, delegatorAddr := sdk.ValAddress(Addrs[0]), Addrs[1] // // // set the unbonding time // params := keeper.GetParams(ctx) // params.UnbondingTime = 7 * time.Second // keeper.SetParams(ctx, params) // // // create the validator // valTokens := sdk.TokensFromConsensusPower(10) // msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, PKs[0], valTokens) // res, err := handler(ctx, msgCreateValidator) // require.NoError(t, err) // require.NotNil(t, res) // // // bond a delegator // delTokens := sdk.TokensFromConsensusPower(10) // msgDelegate := NewTestMsgDelegate(delegatorAddr, validatorAddr, delTokens) // res, err = handler(ctx, msgDelegate) // require.NoError(t, err) // require.NotNil(t, res) // // EndBlocker(ctx, keeper) // // // unbond the all self-delegation to put validator in unbonding state // unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, delTokens) // msgUndelegateValidator := NewMsgUndelegate(sdk.AccAddress(validatorAddr), validatorAddr, unbondAmt) // res, err = handler(ctx, msgUndelegateValidator) // require.NoError(t, err) // require.NotNil(t, res) // // ts := &gogotypes.Timestamp{} // types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, ts) // // finishTime, err := gogotypes.TimestampFromProto(ts) // require.NoError(t, err) // // ctx = ctx.WithBlockTime(finishTime) // EndBlocker(ctx, keeper) // // origHeader := ctx.BlockHeader() // // validator, found := keeper.GetValidator(ctx, validatorAddr) // require.True(t, found) // require.True(t, validator.IsUnbonding(), "%v", validator) // // // should still be unbonding at time 6 seconds later // ctx = ctx.WithBlockTime(origHeader.Time.Add(time.Second * 6)) // EndBlocker(ctx, keeper) // // validator, found = keeper.GetValidator(ctx, validatorAddr) // require.True(t, found) // require.True(t, validator.IsUnbonding(), "%v", validator) // // // should be in unbonded state at time 7 seconds later // ctx = ctx.WithBlockTime(origHeader.Time.Add(time.Second * 7)) // EndBlocker(ctx, keeper) // // validator, found = keeper.GetValidator(ctx, validatorAddr) // require.True(t, found) // require.True(t, validator.IsUnbonded(), "%v", validator) //} // //func TestUnbondingPeriod(t *testing.T) { // ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) // handler := NewHandler(keeper) // validatorAddr := sdk.ValAddress(Addrs[0]) // // // set the unbonding time // params := keeper.GetParams(ctx) // params.UnbondingTime = 7 * time.Second // keeper.SetParams(ctx, params) // // // create the validator // valTokens := sdk.TokensFromConsensusPower(10) // msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, PKs[0], valTokens) // res, err := handler(ctx, msgCreateValidator) // require.NoError(t, err) // require.NotNil(t, res) // // EndBlocker(ctx, keeper) // // // begin unbonding // unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(10)) // msgUndelegate := NewMsgUndelegate(sdk.AccAddress(validatorAddr), validatorAddr, unbondAmt) // res, err = handler(ctx, msgUndelegate) // require.NoError(t, err) // require.NotNil(t, res) // // origHeader := ctx.BlockHeader() // // _, found := keeper.GetUnbondingDelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr) // require.True(t, found, "should not have unbonded") // // // cannot complete unbonding at same time // EndBlocker(ctx, keeper) // _, found = keeper.GetUnbondingDelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr) // require.True(t, found, "should not have unbonded") // // // cannot complete unbonding at time 6 seconds later // ctx = ctx.WithBlockTime(origHeader.Time.Add(time.Second * 6)) // EndBlocker(ctx, keeper) // _, found = keeper.GetUnbondingDelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr) // require.True(t, found, "should not have unbonded") // // // can complete unbonding at time 7 seconds later // ctx = ctx.WithBlockTime(origHeader.Time.Add(time.Second * 7)) // EndBlocker(ctx, keeper) // _, found = keeper.GetUnbondingDelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr) // require.False(t, found, "should have unbonded") //} // //func TestUnbondingFromUnbondingValidator(t *testing.T) { // ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) // handler := NewHandler(keeper) // validatorAddr, delegatorAddr := sdk.ValAddress(Addrs[0]), Addrs[1] // // // create the validator // msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, PKs[0], sdk.NewInt(10)) // res, err := handler(ctx, msgCreateValidator) // require.NoError(t, err) // require.NotNil(t, res) // // // bond a delegator // msgDelegate := NewTestMsgDelegate(delegatorAddr, validatorAddr, sdk.NewInt(10)) // res, err = handler(ctx, msgDelegate) // require.NoError(t, err) // require.NotNil(t, res) // // // unbond the validators bond portion // unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)) // msgUndelegateValidator := NewMsgUndelegate(sdk.AccAddress(validatorAddr), validatorAddr, unbondAmt) // res, err = handler(ctx, msgUndelegateValidator) // require.NoError(t, err) // require.NotNil(t, res) // // // change the ctx to Block Time one second before the validator would have unbonded // ts := &gogotypes.Timestamp{} // types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, ts) // // finishTime, err := gogotypes.TimestampFromProto(ts) // require.NoError(t, err) // // ctx = ctx.WithBlockTime(finishTime.Add(time.Second * -1)) // // // unbond the delegator from the validator // msgUndelegateDelegator := NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt) // res, err = handler(ctx, msgUndelegateDelegator) // require.NoError(t, err) // require.NotNil(t, res) // // ctx = ctx.WithBlockTime(ctx.BlockHeader().Time.Add(keeper.UnbondingTime(ctx))) // // // Run the EndBlocker // EndBlocker(ctx, keeper) // // // Check to make sure that the unbonding delegation is no longer in state // // (meaning it was deleted in the above EndBlocker) // _, found := keeper.GetUnbondingDelegation(ctx, delegatorAddr, validatorAddr) // require.False(t, found, "should be removed from state") //} // //func TestRedelegationPeriod(t *testing.T) { // ctx, _, bk, keeper, _ := CreateTestInput(t, false, 1000) // handler := NewHandler(keeper) // validatorAddr, validatorAddr2 := sdk.ValAddress(Addrs[0]), sdk.ValAddress(Addrs[1]) // denom := keeper.GetParams(ctx).BondDenom // // // set the unbonding time // params := keeper.GetParams(ctx) // params.UnbondingTime = 7 * time.Second // keeper.SetParams(ctx, params) // // // create the validators // msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, PKs[0], sdk.NewInt(10)) // // // initial balance // amt1 := bk.GetBalance(ctx, sdk.AccAddress(validatorAddr), denom).Amount // // res, err := handler(ctx, msgCreateValidator) // require.NoError(t, err) // require.NotNil(t, res) // // // balance should have been subtracted after creation // amt2 := bk.GetBalance(ctx, sdk.AccAddress(validatorAddr), denom).Amount // require.Equal(t, amt1.Sub(sdk.NewInt(10)).Int64(), amt2.Int64(), "expected coins to be subtracted") // // msgCreateValidator = NewTestMsgCreateValidator(validatorAddr2, PKs[1], sdk.NewInt(10)) // res, err = handler(ctx, msgCreateValidator) // require.NoError(t, err) // require.NotNil(t, res) // // bal1 := bk.GetAllBalances(ctx, sdk.AccAddress(validatorAddr)) // // // begin redelegate // redAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)) // msgBeginRedelegate := NewMsgBeginRedelegate(sdk.AccAddress(validatorAddr), validatorAddr, validatorAddr2, redAmt) // res, err = handler(ctx, msgBeginRedelegate) // require.NoError(t, err) // require.NotNil(t, res) // // // origin account should not lose tokens as with a regular delegation // bal2 := bk.GetAllBalances(ctx, sdk.AccAddress(validatorAddr)) // require.Equal(t, bal1, bal2) // // origHeader := ctx.BlockHeader() // // // cannot complete redelegation at same time // EndBlocker(ctx, keeper) // _, found := keeper.GetRedelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr, validatorAddr2) // require.True(t, found, "should not have unbonded") // // // cannot complete redelegation at time 6 seconds later // ctx = ctx.WithBlockTime(origHeader.Time.Add(time.Second * 6)) // EndBlocker(ctx, keeper) // _, found = keeper.GetRedelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr, validatorAddr2) // require.True(t, found, "should not have unbonded") // // // can complete redelegation at time 7 seconds later // ctx = ctx.WithBlockTime(origHeader.Time.Add(time.Second * 7)) // EndBlocker(ctx, keeper) // _, found = keeper.GetRedelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr, validatorAddr2) // require.False(t, found, "should have unbonded") //} // //func TestTransitiveRedelegation(t *testing.T) { // ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) // handler := NewHandler(keeper) // // validatorAddr := sdk.ValAddress(Addrs[0]) // validatorAddr2 := sdk.ValAddress(Addrs[1]) // validatorAddr3 := sdk.ValAddress(Addrs[2]) // // blockTime := time.Now().UTC() // ctx = ctx.WithBlockTime(blockTime) // // // create the validators // msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, PKs[0], sdk.NewInt(10)) // res, err := handler(ctx, msgCreateValidator) // require.NoError(t, err) // require.NotNil(t, res) // // msgCreateValidator = NewTestMsgCreateValidator(validatorAddr2, PKs[1], sdk.NewInt(10)) // res, err = handler(ctx, msgCreateValidator) // require.NoError(t, err) // require.NotNil(t, res) // // msgCreateValidator = NewTestMsgCreateValidator(validatorAddr3, PKs[2], sdk.NewInt(10)) // res, err = handler(ctx, msgCreateValidator) // require.NoError(t, err) // require.NotNil(t, res) // // // begin redelegate // redAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)) // msgBeginRedelegate := NewMsgBeginRedelegate(sdk.AccAddress(validatorAddr), validatorAddr, validatorAddr2, redAmt) // res, err = handler(ctx, msgBeginRedelegate) // require.NoError(t, err) // require.NotNil(t, res) // // // cannot redelegation to next validator while first delegation exists // msgBeginRedelegate = NewMsgBeginRedelegate(sdk.AccAddress(validatorAddr), validatorAddr2, validatorAddr3, redAmt) // res, err = handler(ctx, msgBeginRedelegate) // require.Error(t, err) // require.Nil(t, res) // // params := keeper.GetParams(ctx) // ctx = ctx.WithBlockTime(blockTime.Add(params.UnbondingTime)) // // // complete first redelegation // EndBlocker(ctx, keeper) // // // now should be able to redelegate from the second validator to the third // res, err = handler(ctx, msgBeginRedelegate) // require.NoError(t, err) // require.NotNil(t, res) //} // //func TestMultipleRedelegationAtSameTime(t *testing.T) { // ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) // handler := NewHandler(keeper) // // valAddr := sdk.ValAddress(Addrs[0]) // valAddr2 := sdk.ValAddress(Addrs[1]) // // // set the unbonding time // params := keeper.GetParams(ctx) // params.UnbondingTime = 1 * time.Second // keeper.SetParams(ctx, params) // // // create the validators // valTokens := sdk.TokensFromConsensusPower(10) // msgCreateValidator := NewTestMsgCreateValidator(valAddr, PKs[0], valTokens) // res, err := handler(ctx, msgCreateValidator) // require.NoError(t, err) // require.NotNil(t, res) // // msgCreateValidator = NewTestMsgCreateValidator(valAddr2, PKs[1], valTokens) // res, err = handler(ctx, msgCreateValidator) // require.NoError(t, err) // require.NotNil(t, res) // // // end block to bond them // EndBlocker(ctx, keeper) // // // begin a redelegate // selfDelAddr := sdk.AccAddress(valAddr) // (the validator is it's own delegator) // redAmt := sdk.NewCoin(sdk.DefaultBondDenom, valTokens.QuoRaw(2)) // msgBeginRedelegate := NewMsgBeginRedelegate(selfDelAddr, valAddr, valAddr2, redAmt) // res, err = handler(ctx, msgBeginRedelegate) // require.NoError(t, err) // require.NotNil(t, res) // // // there should only be one entry in the redelegation object // rd, found := keeper.GetRedelegation(ctx, selfDelAddr, valAddr, valAddr2) // require.True(t, found) // require.Len(t, rd.Entries, 1) // // // start a second redelegation at this same time as the first // res, err = handler(ctx, msgBeginRedelegate) // require.NoError(t, err) // require.NotNil(t, res) // // // now there should be two entries // rd, found = keeper.GetRedelegation(ctx, selfDelAddr, valAddr, valAddr2) // require.True(t, found) // require.Len(t, rd.Entries, 2) // // // move forward in time, should complete both redelegations // ctx = ctx.WithBlockTime(ctx.BlockHeader().Time.Add(1 * time.Second)) // EndBlocker(ctx, keeper) // // rd, found = keeper.GetRedelegation(ctx, selfDelAddr, valAddr, valAddr2) // require.False(t, found) //} // //func TestMultipleRedelegationAtUniqueTimes(t *testing.T) { // ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) // handler := NewHandler(keeper) // // valAddr := sdk.ValAddress(Addrs[0]) // valAddr2 := sdk.ValAddress(Addrs[1]) // // // set the unbonding time // params := keeper.GetParams(ctx) // params.UnbondingTime = 10 * time.Second // keeper.SetParams(ctx, params) // // // create the validators // valTokens := sdk.TokensFromConsensusPower(10) // msgCreateValidator := NewTestMsgCreateValidator(valAddr, PKs[0], valTokens) // res, err := handler(ctx, msgCreateValidator) // require.NoError(t, err) // require.NotNil(t, res) // // msgCreateValidator = NewTestMsgCreateValidator(valAddr2, PKs[1], valTokens) // res, err = handler(ctx, msgCreateValidator) // require.NoError(t, err) // require.NotNil(t, res) // // // end block to bond them // EndBlocker(ctx, keeper) // // // begin a redelegate // selfDelAddr := sdk.AccAddress(valAddr) // (the validator is it's own delegator) // redAmt := sdk.NewCoin(sdk.DefaultBondDenom, valTokens.QuoRaw(2)) // msgBeginRedelegate := NewMsgBeginRedelegate(selfDelAddr, valAddr, valAddr2, redAmt) // res, err = handler(ctx, msgBeginRedelegate) // require.NoError(t, err) // require.NotNil(t, res) // // // move forward in time and start a second redelegation // ctx = ctx.WithBlockTime(ctx.BlockHeader().Time.Add(5 * time.Second)) // res, err = handler(ctx, msgBeginRedelegate) // require.NoError(t, err) // require.NotNil(t, res) // // // now there should be two entries // rd, found := keeper.GetRedelegation(ctx, selfDelAddr, valAddr, valAddr2) // require.True(t, found) // require.Len(t, rd.Entries, 2) // // // move forward in time, should complete the first redelegation, but not the second // ctx = ctx.WithBlockTime(ctx.BlockHeader().Time.Add(5 * time.Second)) // EndBlocker(ctx, keeper) // rd, found = keeper.GetRedelegation(ctx, selfDelAddr, valAddr, valAddr2) // require.True(t, found) // require.Len(t, rd.Entries, 1) // // // move forward in time, should complete the second redelegation // ctx = ctx.WithBlockTime(ctx.BlockHeader().Time.Add(5 * time.Second)) // EndBlocker(ctx, keeper) // rd, found = keeper.GetRedelegation(ctx, selfDelAddr, valAddr, valAddr2) // require.False(t, found) //} // //func TestMultipleUnbondingDelegationAtSameTime(t *testing.T) { // ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) // handler := NewHandler(keeper) // // valAddr := sdk.ValAddress(Addrs[0]) // // // set the unbonding time // params := keeper.GetParams(ctx) // params.UnbondingTime = 1 * time.Second // keeper.SetParams(ctx, params) // // // create the validator // valTokens := sdk.TokensFromConsensusPower(10) // msgCreateValidator := NewTestMsgCreateValidator(valAddr, PKs[0], valTokens) // res, err := handler(ctx, msgCreateValidator) // require.NoError(t, err) // require.NotNil(t, res) // // // end block to bond // EndBlocker(ctx, keeper) // // // begin an unbonding delegation // selfDelAddr := sdk.AccAddress(valAddr) // (the validator is it's own delegator) // unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, valTokens.QuoRaw(2)) // msgUndelegate := NewMsgUndelegate(selfDelAddr, valAddr, unbondAmt) // res, err = handler(ctx, msgUndelegate) // require.NoError(t, err) // require.NotNil(t, res) // // // there should only be one entry in the ubd object // ubd, found := keeper.GetUnbondingDelegation(ctx, selfDelAddr, valAddr) // require.True(t, found) // require.Len(t, ubd.Entries, 1) // // // start a second ubd at this same time as the first // res, err = handler(ctx, msgUndelegate) // require.NoError(t, err) // require.NotNil(t, res) // // // now there should be two entries // ubd, found = keeper.GetUnbondingDelegation(ctx, selfDelAddr, valAddr) // require.True(t, found) // require.Len(t, ubd.Entries, 2) // // // move forwaubd in time, should complete both ubds // ctx = ctx.WithBlockTime(ctx.BlockHeader().Time.Add(1 * time.Second)) // EndBlocker(ctx, keeper) // // ubd, found = keeper.GetUnbondingDelegation(ctx, selfDelAddr, valAddr) // require.False(t, found) //} // //func TestMultipleUnbondingDelegationAtUniqueTimes(t *testing.T) { // ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) // handler := NewHandler(keeper) // valAddr := sdk.ValAddress(Addrs[0]) // // // set the unbonding time // params := keeper.GetParams(ctx) // params.UnbondingTime = 10 * time.Second // keeper.SetParams(ctx, params) // // // create the validator // valTokens := sdk.TokensFromConsensusPower(10) // msgCreateValidator := NewTestMsgCreateValidator(valAddr, PKs[0], valTokens) // res, err := handler(ctx, msgCreateValidator) // require.NoError(t, err) // require.NotNil(t, res) // // // end block to bond // EndBlocker(ctx, keeper) // // // begin an unbonding delegation // selfDelAddr := sdk.AccAddress(valAddr) // (the validator is it's own delegator) // unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, valTokens.QuoRaw(2)) // msgUndelegate := NewMsgUndelegate(selfDelAddr, valAddr, unbondAmt) // res, err = handler(ctx, msgUndelegate) // require.NoError(t, err) // require.NotNil(t, res) // // // there should only be one entry in the ubd object // ubd, found := keeper.GetUnbondingDelegation(ctx, selfDelAddr, valAddr) // require.True(t, found) // require.Len(t, ubd.Entries, 1) // // // move forwaubd in time and start a second redelegation // ctx = ctx.WithBlockTime(ctx.BlockHeader().Time.Add(5 * time.Second)) // res, err = handler(ctx, msgUndelegate) // require.NoError(t, err) // require.NotNil(t, res) // // // now there should be two entries // ubd, found = keeper.GetUnbondingDelegation(ctx, selfDelAddr, valAddr) // require.True(t, found) // require.Len(t, ubd.Entries, 2) // // // move forwaubd in time, should complete the first redelegation, but not the second // ctx = ctx.WithBlockTime(ctx.BlockHeader().Time.Add(5 * time.Second)) // EndBlocker(ctx, keeper) // ubd, found = keeper.GetUnbondingDelegation(ctx, selfDelAddr, valAddr) // require.True(t, found) // require.Len(t, ubd.Entries, 1) // // // move forwaubd in time, should complete the second redelegation // ctx = ctx.WithBlockTime(ctx.BlockHeader().Time.Add(5 * time.Second)) // EndBlocker(ctx, keeper) // ubd, found = keeper.GetUnbondingDelegation(ctx, selfDelAddr, valAddr) // require.False(t, found) //} // //func TestUnbondingWhenExcessValidators(t *testing.T) { // ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) // handler := NewHandler(keeper) // // validatorAddr1 := sdk.ValAddress(Addrs[0]) // validatorAddr2 := sdk.ValAddress(Addrs[1]) // validatorAddr3 := sdk.ValAddress(Addrs[2]) // // // set the unbonding time // params := keeper.GetParams(ctx) // params.MaxValidators = 2 // keeper.SetParams(ctx, params) // // // add three validators // valTokens1 := sdk.TokensFromConsensusPower(50) // msgCreateValidator := NewTestMsgCreateValidator(validatorAddr1, PKs[0], valTokens1) // res, err := handler(ctx, msgCreateValidator) // require.NoError(t, err) // require.NotNil(t, res) // // // apply TM updates // keeper.ApplyAndReturnValidatorSetUpdates(ctx) // require.Equal(t, 1, len(keeper.GetLastValidators(ctx))) // // valTokens2 := sdk.TokensFromConsensusPower(30) // msgCreateValidator = NewTestMsgCreateValidator(validatorAddr2, PKs[1], valTokens2) // res, err = handler(ctx, msgCreateValidator) // require.NoError(t, err) // require.NotNil(t, res) // // // apply TM updates // keeper.ApplyAndReturnValidatorSetUpdates(ctx) // require.Equal(t, 2, len(keeper.GetLastValidators(ctx))) // // valTokens3 := sdk.TokensFromConsensusPower(10) // msgCreateValidator = NewTestMsgCreateValidator(validatorAddr3, PKs[2], valTokens3) // res, err = handler(ctx, msgCreateValidator) // require.NoError(t, err) // require.NotNil(t, res) // // // apply TM updates // keeper.ApplyAndReturnValidatorSetUpdates(ctx) // require.Equal(t, 2, len(keeper.GetLastValidators(ctx))) // // // unbond the validator-2 // unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, valTokens2) // msgUndelegate := NewMsgUndelegate(sdk.AccAddress(validatorAddr2), validatorAddr2, unbondAmt) // res, err = handler(ctx, msgUndelegate) // require.NoError(t, err) // require.NotNil(t, res) // // // apply TM updates // keeper.ApplyAndReturnValidatorSetUpdates(ctx) // // // because there are extra validators waiting to get in, the queued // // validator (aka. validator-1) should make it into the bonded group, thus // // the total number of validators should stay the same // vals := keeper.GetLastValidators(ctx) // require.Equal(t, 2, len(vals), "vals %v", vals) // val1, found := keeper.GetValidator(ctx, validatorAddr1) // require.True(t, found) // require.Equal(t, sdk.Bonded, val1.Status, "%v", val1) //} // //func TestBondUnbondRedelegateSlashTwice(t *testing.T) { // ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) // handler := NewHandler(keeper) // // valA, valB, del := sdk.ValAddress(Addrs[0]), sdk.ValAddress(Addrs[1]), Addrs[2] // consAddr0 := sdk.ConsAddress(PKs[0].Address()) // // valTokens := sdk.TokensFromConsensusPower(10) // msgCreateValidator := NewTestMsgCreateValidator(valA, PKs[0], valTokens) // res, err := handler(ctx, msgCreateValidator) // require.NoError(t, err) // require.NotNil(t, res) // // msgCreateValidator = NewTestMsgCreateValidator(valB, PKs[1], valTokens) // res, err = handler(ctx, msgCreateValidator) // require.NoError(t, err) // require.NotNil(t, res) // // // delegate 10 stake // msgDelegate := NewTestMsgDelegate(del, valA, valTokens) // res, err = handler(ctx, msgDelegate) // require.NoError(t, err) // require.NotNil(t, res) // // // apply Tendermint updates // updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) // require.Equal(t, 2, len(updates)) // // // a block passes // ctx = ctx.WithBlockHeight(1) // // // begin unbonding 4 stake // unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(4)) // msgUndelegate := NewMsgUndelegate(del, valA, unbondAmt) // res, err = handler(ctx, msgUndelegate) // require.NoError(t, err) // require.NotNil(t, res) // // // begin redelegate 6 stake // redAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(6)) // msgBeginRedelegate := NewMsgBeginRedelegate(del, valA, valB, redAmt) // res, err = handler(ctx, msgBeginRedelegate) // require.NoError(t, err) // require.NotNil(t, res) // // // destination delegation should have 6 shares // delegation, found := keeper.GetDelegation(ctx, del, valB) // require.True(t, found) // require.Equal(t, sdk.NewDecFromInt(redAmt.Amount), delegation.Shares) // // // must apply validator updates // updates = keeper.ApplyAndReturnValidatorSetUpdates(ctx) // require.Equal(t, 2, len(updates)) // // // slash the validator by half // keeper.Slash(ctx, consAddr0, 0, 20, sdk.NewDecWithPrec(5, 1)) // // // unbonding delegation should have been slashed by half // ubd, found := keeper.GetUnbondingDelegation(ctx, del, valA) // require.True(t, found) // require.Len(t, ubd.Entries, 1) // require.Equal(t, unbondAmt.Amount.QuoRaw(2), ubd.Entries[0].Balance) // // // redelegation should have been slashed by half // redelegation, found := keeper.GetRedelegation(ctx, del, valA, valB) // require.True(t, found) // require.Len(t, redelegation.Entries, 1) // // // destination delegation should have been slashed by half // delegation, found = keeper.GetDelegation(ctx, del, valB) // require.True(t, found) // require.Equal(t, sdk.NewDecFromInt(redAmt.Amount.QuoRaw(2)), delegation.Shares) // // // validator power should have been reduced by half // validator, found := keeper.GetValidator(ctx, valA) // require.True(t, found) // require.Equal(t, valTokens.QuoRaw(2), validator.GetBondedTokens()) // // // slash the validator for an infraction committed after the unbonding and redelegation begin // ctx = ctx.WithBlockHeight(3) // keeper.Slash(ctx, consAddr0, 2, 10, sdk.NewDecWithPrec(5, 1)) // // // unbonding delegation should be unchanged // ubd, found = keeper.GetUnbondingDelegation(ctx, del, valA) // require.True(t, found) // require.Len(t, ubd.Entries, 1) // require.Equal(t, unbondAmt.Amount.QuoRaw(2), ubd.Entries[0].Balance) // // // redelegation should be unchanged // redelegation, found = keeper.GetRedelegation(ctx, del, valA, valB) // require.True(t, found) // require.Len(t, redelegation.Entries, 1) // // // destination delegation should be unchanged // delegation, found = keeper.GetDelegation(ctx, del, valB) // require.True(t, found) // require.Equal(t, sdk.NewDecFromInt(redAmt.Amount.QuoRaw(2)), delegation.Shares) // // // end blocker // EndBlocker(ctx, keeper) // // // validator power should have been reduced to zero // // validator should be in unbonding state // validator, _ = keeper.GetValidator(ctx, valA) // require.Equal(t, validator.GetStatus(), sdk.Unbonding) //} // //func TestInvalidMsg(t *testing.T) { // k := Keeper{} // h := NewHandler(k) // // res, err := h(sdk.NewContext(nil, abci.Header{}, false, nil), sdk.NewTestMsg()) // require.Error(t, err) // require.Nil(t, res) // require.True(t, strings.Contains(err.Error(), "unrecognized staking message type")) //} // //func TestInvalidCoinDenom(t *testing.T) { // ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) // handler := NewHandler(keeper) // // valA, valB, delAddr := sdk.ValAddress(Addrs[0]), sdk.ValAddress(Addrs[1]), Addrs[2] // // valTokens := sdk.TokensFromConsensusPower(100) // invalidCoin := sdk.NewCoin("churros", valTokens) // validCoin := sdk.NewCoin(sdk.DefaultBondDenom, valTokens) // oneCoin := sdk.NewCoin(sdk.DefaultBondDenom, sdk.OneInt()) // // commission := types.NewCommissionRates(sdk.OneDec(), sdk.OneDec(), sdk.ZeroDec()) // // msgCreate := types.NewMsgCreateValidator(valA, PKs[0], invalidCoin, Description{}, commission, sdk.OneInt()) // res, err := handler(ctx, msgCreate) // require.Error(t, err) // require.Nil(t, res) // // msgCreate = types.NewMsgCreateValidator(valA, PKs[0], validCoin, Description{}, commission, sdk.OneInt()) // res, err = handler(ctx, msgCreate) // require.NoError(t, err) // require.NotNil(t, res) // // msgCreate = types.NewMsgCreateValidator(valB, PKs[1], validCoin, Description{}, commission, sdk.OneInt()) // res, err = handler(ctx, msgCreate) // require.NoError(t, err) // require.NotNil(t, res) // // msgDelegate := types.NewMsgDelegate(delAddr, valA, invalidCoin) // res, err = handler(ctx, msgDelegate) // require.Error(t, err) // require.Nil(t, res) // // msgDelegate = types.NewMsgDelegate(delAddr, valA, validCoin) // res, err = handler(ctx, msgDelegate) // require.NoError(t, err) // require.NotNil(t, res) // // msgUndelegate := types.NewMsgUndelegate(delAddr, valA, invalidCoin) // res, err = handler(ctx, msgUndelegate) // require.Error(t, err) // require.Nil(t, res) // // msgUndelegate = types.NewMsgUndelegate(delAddr, valA, oneCoin) // res, err = handler(ctx, msgUndelegate) // require.NoError(t, err) // require.NotNil(t, res) // // msgRedelegate := types.NewMsgBeginRedelegate(delAddr, valA, valB, invalidCoin) // res, err = handler(ctx, msgRedelegate) // require.Error(t, err) // require.Nil(t, res) // // msgRedelegate = types.NewMsgBeginRedelegate(delAddr, valA, valB, oneCoin) // res, err = handler(ctx, msgRedelegate) // require.NoError(t, err) // require.NotNil(t, res) //}