From 399ea763ee0a5fd28c90264a8b4ab11853a2b6e4 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Wed, 26 Feb 2020 10:47:39 +0100 Subject: [PATCH] refactor old genesis_test to use simapp --- x/staking/common_test.go | 66 + x/staking/genesis_test.go | 70 +- x/staking/handler_test.go | 2925 ++++++++++++++++++------------------- 3 files changed, 1565 insertions(+), 1496 deletions(-) diff --git a/x/staking/common_test.go b/x/staking/common_test.go index 291f5ea52..871894b9b 100644 --- a/x/staking/common_test.go +++ b/x/staking/common_test.go @@ -1,11 +1,21 @@ package staking_test import ( + "bytes" + "encoding/hex" + "strconv" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/simapp" + cdc "github.com/cosmos/cosmos-sdk/simapp/codec" + abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/crypto/secp256k1" 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" ) @@ -17,6 +27,8 @@ var ( addr2 = sdk.AccAddress(priv2.PubKey().Address()) commissionRates = staking.NewCommissionRates(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()) + + PKs = createTestPubKeys(500) ) func NewTestMsgCreateValidator(address sdk.ValAddress, pubKey crypto.PubKey, amt sdk.Int) staking.MsgCreateValidator { @@ -29,3 +41,57 @@ func NewTestMsgDelegate(delAddr sdk.AccAddress, valAddr sdk.ValAddress, amt sdk. amount := sdk.NewCoin(sdk.DefaultBondDenom, amt) return staking.NewMsgDelegate(delAddr, valAddr, amount) } + +// nolint: unparam +func createTestPubKeys(numPubKeys int) []crypto.PubKey { + var publicKeys []crypto.PubKey + var buffer bytes.Buffer + + //start at 10 to avoid changing 1 to 01, 2 to 02, etc + for i := 100; i < (numPubKeys + 100); i++ { + numString := strconv.Itoa(i) + buffer.WriteString("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AF") //base pubkey string + buffer.WriteString(numString) //adding on final two digits to make pubkeys unique + publicKeys = append(publicKeys, NewPubKey(buffer.String())) + buffer.Reset() + } + return publicKeys +} + +func NewPubKey(pk string) (res crypto.PubKey) { + pkBytes, err := hex.DecodeString(pk) + if err != nil { + panic(err) + } + //res, err = crypto.PubKeyFromBytes(pkBytes) + var pkEd ed25519.PubKeyEd25519 + copy(pkEd[:], pkBytes) + return pkEd +} + +// getBaseSimappWithCustomKeeper Returns a simapp with custom StakingKeeper +// to avoid messing with the hooks. +func getBaseSimappWithCustomKeeper() (*codec.Codec, *simapp.SimApp, sdk.Context) { + app := simapp.Setup(false) + ctx := app.BaseApp.NewContext(false, abci.Header{}) + + appCodec := cdc.NewAppCodec(codec.New()) + + app.StakingKeeper = keeper.NewKeeper( + appCodec, + app.GetKey(staking.StoreKey), + app.BankKeeper, + app.SupplyKeeper, + app.GetSubspace(staking.ModuleName), + ) + + return codec.New(), app, ctx +} + +// generateAddresses generates numAddrs of normal AccAddrs and ValAddrs +func generateAddresses(app *simapp.SimApp, ctx sdk.Context, numAddrs int) ([]sdk.AccAddress, []sdk.ValAddress) { + addrDels := simapp.AddTestAddrsIncremental(app, ctx, numAddrs, sdk.NewInt(10000)) + addrVals := simapp.ConvertAddrsToValAddrs(addrDels) + + return addrDels, addrVals +} diff --git a/x/staking/genesis_test.go b/x/staking/genesis_test.go index 730e7b0fc..29a6149e4 100644 --- a/x/staking/genesis_test.go +++ b/x/staking/genesis_test.go @@ -1,27 +1,49 @@ -package staking +package staking_test import ( "fmt" "testing" "github.com/stretchr/testify/assert" + "github.com/tendermint/tendermint/crypto/ed25519" + "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/crypto/ed25519" + "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/types" + "github.com/cosmos/cosmos-sdk/x/supply" ) +func bootstrapGenesisTest(t *testing.T, power int64, numAddrs int) (*simapp.SimApp, sdk.Context, []sdk.AccAddress, []sdk.ValAddress) { + _, app, ctx := getBaseSimappWithCustomKeeper() + + addrDels, addrVals := generateAddresses(app, ctx, numAddrs) + + 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 TestInitGenesis(t *testing.T) { - ctx, accKeeper, bk, keeper, supplyKeeper := CreateTestInput(t, false, 1000) + app, ctx, addrs, _ := bootstrapGenesisTest(t, 1000, 10) valTokens := sdk.TokensFromConsensusPower(1) - params := keeper.GetParams(ctx) - validators := make([]Validator, 2) - var delegations []Delegation + params := app.StakingKeeper.GetParams(ctx) + validators := make([]types.Validator, 2) + var delegations []types.Delegation pk0, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeConsPub, PKs[0]) require.NoError(t, err) @@ -30,33 +52,33 @@ func TestInitGenesis(t *testing.T) { require.NoError(t, err) // initialize the validators - validators[0].OperatorAddress = sdk.ValAddress(Addrs[0]) + validators[0].OperatorAddress = sdk.ValAddress(addrs[0]) validators[0].ConsensusPubkey = pk0 - validators[0].Description = NewDescription("hoop", "", "", "", "") + validators[0].Description = types.NewDescription("hoop", "", "", "", "") validators[0].Status = sdk.Bonded validators[0].Tokens = valTokens validators[0].DelegatorShares = valTokens.ToDec() - validators[1].OperatorAddress = sdk.ValAddress(Addrs[1]) + validators[1].OperatorAddress = sdk.ValAddress(addrs[1]) validators[1].ConsensusPubkey = pk1 - validators[1].Description = NewDescription("bloop", "", "", "", "") + validators[1].Description = types.NewDescription("bloop", "", "", "", "") validators[1].Status = sdk.Bonded validators[1].Tokens = valTokens validators[1].DelegatorShares = valTokens.ToDec() genesisState := types.NewGenesisState(params, validators, delegations) - vals := InitGenesis(ctx, keeper, accKeeper, bk, supplyKeeper, genesisState) + vals := staking.InitGenesis(ctx, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.SupplyKeeper, genesisState) - actualGenesis := ExportGenesis(ctx, keeper) + actualGenesis := staking.ExportGenesis(ctx, app.StakingKeeper) require.Equal(t, genesisState.Params, actualGenesis.Params) require.Equal(t, genesisState.Delegations, actualGenesis.Delegations) - require.EqualValues(t, keeper.GetAllValidators(ctx), actualGenesis.Validators) + require.EqualValues(t, app.StakingKeeper.GetAllValidators(ctx), actualGenesis.Validators) // now make sure the validators are bonded and intra-tx counters are correct - resVal, found := keeper.GetValidator(ctx, sdk.ValAddress(Addrs[0])) + resVal, found := app.StakingKeeper.GetValidator(ctx, sdk.ValAddress(addrs[0])) require.True(t, found) require.Equal(t, sdk.Bonded, resVal.Status) - resVal, found = keeper.GetValidator(ctx, sdk.ValAddress(Addrs[1])) + resVal, found = app.StakingKeeper.GetValidator(ctx, sdk.ValAddress(addrs[1])) require.True(t, found) require.Equal(t, sdk.Bonded, resVal.Status) @@ -72,15 +94,15 @@ func TestInitGenesisLargeValidatorSet(t *testing.T) { size := 200 require.True(t, size > 100) - ctx, accKeeper, bk, keeper, supplyKeeper := CreateTestInput(t, false, 1000) + app, ctx, addrs, _ := bootstrapGenesisTest(t, 1000, 200) - params := keeper.GetParams(ctx) - delegations := []Delegation{} - validators := make([]Validator, size) + params := app.StakingKeeper.GetParams(ctx) + delegations := []types.Delegation{} + validators := make([]types.Validator, size) for i := range validators { - validators[i] = NewValidator(sdk.ValAddress(Addrs[i]), - PKs[i], NewDescription(fmt.Sprintf("#%d", i), "", "", "", "")) + validators[i] = types.NewValidator(sdk.ValAddress(addrs[i]), + PKs[i], types.NewDescription(fmt.Sprintf("#%d", i), "", "", "", "")) validators[i].Status = sdk.Bonded @@ -93,7 +115,7 @@ func TestInitGenesisLargeValidatorSet(t *testing.T) { } genesisState := types.NewGenesisState(params, validators, delegations) - vals := InitGenesis(ctx, keeper, accKeeper, bk, supplyKeeper, genesisState) + vals := staking.InitGenesis(ctx, app.StakingKeeper, app.AccountKeeper, app.BankKeeper, app.SupplyKeeper, genesisState) abcivals := make([]abci.ValidatorUpdate, 100) for i, val := range validators[:100] { @@ -138,9 +160,9 @@ func TestValidateGenesis(t *testing.T) { genesisState := types.DefaultGenesisState() tt.mutate(&genesisState) if tt.wantErr { - assert.Error(t, ValidateGenesis(genesisState)) + assert.Error(t, staking.ValidateGenesis(genesisState)) } else { - assert.NoError(t, ValidateGenesis(genesisState)) + assert.NoError(t, staking.ValidateGenesis(genesisState)) } }) } diff --git a/x/staking/handler_test.go b/x/staking/handler_test.go index f18dda6ac..bbbb2eaa8 100644 --- a/x/staking/handler_test.go +++ b/x/staking/handler_test.go @@ -1,1474 +1,1455 @@ package staking_test -import ( - "strings" - "testing" - "time" - - gogotypes "github.com/gogo/protobuf/types" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/crypto/secp256k1" - tmtypes "github.com/tendermint/tendermint/types" - - sdk "github.com/cosmos/cosmos-sdk/types" - . "github.com/cosmos/cosmos-sdk/x/staking" - keep "github.com/cosmos/cosmos-sdk/x/staking/keeper" - "github.com/cosmos/cosmos-sdk/x/staking/types" -) - -func TestValidatorByPowerIndex(t *testing.T) { - validatorAddr, validatorAddr3 := sdk.ValAddress(Addrs[0]), sdk.ValAddress(Addrs[1]) - - initPower := int64(1000000) - initBond := sdk.TokensFromConsensusPower(initPower) - ctx, _, _, keeper, _ := CreateTestInput(t, false, initPower) - handler := NewHandler(keeper) - - // 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 := 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) - - // verify that the by power index exists - validator, found := keeper.GetValidator(ctx, validatorAddr) - require.True(t, found) - power := GetValidatorsByPowerIndexKey(validator) - require.True(t, keep.ValidatorByPowerIndexExists(ctx, keeper, 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 = keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 1, len(updates)) - - // slash and jail the first validator - consAddr0 := sdk.ConsAddress(PKs[0].Address()) - keeper.Slash(ctx, consAddr0, 0, initPower, sdk.NewDecWithPrec(5, 1)) - keeper.Jail(ctx, consAddr0) - keeper.ApplyAndReturnValidatorSetUpdates(ctx) - - validator, found = keeper.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 - keeper.Unjail(ctx, consAddr0) - - // the old power record should have been deleted as the power changed - require.False(t, keep.ValidatorByPowerIndexExists(ctx, keeper, power)) - - // but the new power record should have been created - validator, found = keeper.GetValidator(ctx, validatorAddr) - require.True(t, found) - power2 := GetValidatorsByPowerIndexKey(validator) - require.True(t, keep.ValidatorByPowerIndexExists(ctx, keeper, power2)) - - // now the new record power index should be the same as the original record - power3 := GetValidatorsByPowerIndexKey(validator) - require.Equal(t, power2, power3) - - // unbond self-delegation - totalBond := validator.TokensFromShares(bond.GetShares()).TruncateInt() - unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, totalBond) - msgUndelegate := 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) - EndBlocker(ctx, keeper) - EndBlocker(ctx, keeper) - - // verify that by power key nolonger exists - _, found = keeper.GetValidator(ctx, validatorAddr) - require.False(t, found) - require.False(t, keep.ValidatorByPowerIndexExists(ctx, keeper, power3)) -} - -func TestDuplicatesMsgCreateValidator(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) - handler := NewHandler(keeper) - - addr1, addr2 := sdk.ValAddress(Addrs[0]), sdk.ValAddress(Addrs[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) - - keeper.ApplyAndReturnValidatorSetUpdates(ctx) - - validator, found := keeper.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, 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 := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 1, len(updates)) - - validator, found = keeper.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, Description{}, validator.Description) -} - -func TestInvalidPubKeyTypeMsgCreateValidator(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) - handler := NewHandler(keeper) - - addr := sdk.ValAddress(Addrs[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) -} +//func TestValidatorByPowerIndex(t *testing.T) { +// validatorAddr, validatorAddr3 := sdk.ValAddress(Addrs[0]), sdk.ValAddress(Addrs[1]) +// +// initPower := int64(1000000) +// initBond := sdk.TokensFromConsensusPower(initPower) +// ctx, _, _, keeper, _ := CreateTestInput(t, false, initPower) +// handler := NewHandler(keeper) +// +// // 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 := 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) +// +// // verify that the by power index exists +// validator, found := keeper.GetValidator(ctx, validatorAddr) +// require.True(t, found) +// power := GetValidatorsByPowerIndexKey(validator) +// require.True(t, keep.ValidatorByPowerIndexExists(ctx, keeper, 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 = keeper.ApplyAndReturnValidatorSetUpdates(ctx) +// require.Equal(t, 1, len(updates)) +// +// // slash and jail the first validator +// consAddr0 := sdk.ConsAddress(PKs[0].Address()) +// keeper.Slash(ctx, consAddr0, 0, initPower, sdk.NewDecWithPrec(5, 1)) +// keeper.Jail(ctx, consAddr0) +// keeper.ApplyAndReturnValidatorSetUpdates(ctx) +// +// validator, found = keeper.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 +// keeper.Unjail(ctx, consAddr0) +// +// // the old power record should have been deleted as the power changed +// require.False(t, keep.ValidatorByPowerIndexExists(ctx, keeper, power)) +// +// // but the new power record should have been created +// validator, found = keeper.GetValidator(ctx, validatorAddr) +// require.True(t, found) +// power2 := GetValidatorsByPowerIndexKey(validator) +// require.True(t, keep.ValidatorByPowerIndexExists(ctx, keeper, power2)) +// +// // now the new record power index should be the same as the original record +// power3 := GetValidatorsByPowerIndexKey(validator) +// require.Equal(t, power2, power3) +// +// // unbond self-delegation +// totalBond := validator.TokensFromShares(bond.GetShares()).TruncateInt() +// unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, totalBond) +// msgUndelegate := 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) +// EndBlocker(ctx, keeper) +// EndBlocker(ctx, keeper) +// +// // verify that by power key nolonger exists +// _, found = keeper.GetValidator(ctx, validatorAddr) +// require.False(t, found) +// require.False(t, keep.ValidatorByPowerIndexExists(ctx, keeper, power3)) +//} +// +//func TestDuplicatesMsgCreateValidator(t *testing.T) { +// ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) +// handler := NewHandler(keeper) +// +// addr1, addr2 := sdk.ValAddress(Addrs[0]), sdk.ValAddress(Addrs[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) +// +// keeper.ApplyAndReturnValidatorSetUpdates(ctx) +// +// validator, found := keeper.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, 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 := keeper.ApplyAndReturnValidatorSetUpdates(ctx) +// require.Equal(t, 1, len(updates)) +// +// validator, found = keeper.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, Description{}, validator.Description) +//} +// +//func TestInvalidPubKeyTypeMsgCreateValidator(t *testing.T) { +// ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) +// handler := NewHandler(keeper) +// +// addr := sdk.ValAddress(Addrs[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) +//}