From f912618b8a68efce3240ea2051627b50e2a9aadb Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Tue, 18 Feb 2020 13:42:53 +0100 Subject: [PATCH 01/90] use simapp into keeper --- x/staking/keeper/keeper_test.go | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/x/staking/keeper/keeper_test.go b/x/staking/keeper/keeper_test.go index dbde12e7b1a9..8b59555e6554 100644 --- a/x/staking/keeper/keeper_test.go +++ b/x/staking/keeper/keeper_test.go @@ -1,24 +1,28 @@ -package keeper +package keeper_test import ( "testing" "github.com/stretchr/testify/require" + "github.com/cosmos/cosmos-sdk/simapp" "github.com/cosmos/cosmos-sdk/x/staking/types" + abci "github.com/tendermint/tendermint/abci/types" ) func TestParams(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 0) + app := simapp.Setup(false) + ctx := app.BaseApp.NewContext(false, abci.Header{}) + expParams := types.DefaultParams() //check that the empty keeper loads the default - resParams := keeper.GetParams(ctx) + resParams := app.StakingKeeper.GetParams(ctx) require.True(t, expParams.Equal(resParams)) //modify a params, save, and retrieve expParams.MaxValidators = 777 - keeper.SetParams(ctx, expParams) - resParams = keeper.GetParams(ctx) + app.StakingKeeper.SetParams(ctx, expParams) + resParams = app.StakingKeeper.GetParams(ctx) require.True(t, expParams.Equal(resParams)) } From 918949cf231978da0926015dccfbb04db403471f Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Tue, 18 Feb 2020 14:00:59 +0100 Subject: [PATCH 02/90] refactor TestHistoricalInfo to use simapp --- x/staking/keeper/common_refactor_test.go | 97 ++++++++++++++ x/staking/keeper/historical_info_test.go | 155 ++++++++++++----------- 2 files changed, 176 insertions(+), 76 deletions(-) create mode 100644 x/staking/keeper/common_refactor_test.go diff --git a/x/staking/keeper/common_refactor_test.go b/x/staking/keeper/common_refactor_test.go new file mode 100644 index 000000000000..33a4f0c1ab50 --- /dev/null +++ b/x/staking/keeper/common_refactor_test.go @@ -0,0 +1,97 @@ +package keeper_test + +import ( + "bytes" + "encoding/hex" + "strconv" + + "github.com/tendermint/tendermint/crypto/ed25519" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/tendermint/tendermint/crypto" +) + +var ( + Addrs = createTestAddrs(500) + PKs = createTestPubKeys(500) + + addrDels = []sdk.AccAddress{ + Addrs[0], + Addrs[1], + } + addrVals = []sdk.ValAddress{ + sdk.ValAddress(Addrs[2]), + sdk.ValAddress(Addrs[3]), + sdk.ValAddress(Addrs[4]), + sdk.ValAddress(Addrs[5]), + sdk.ValAddress(Addrs[6]), + } +) + +func createTestAddrs(numAddrs int) []sdk.AccAddress { + var addresses []sdk.AccAddress + var buffer bytes.Buffer + + // start at 100 so we can make up to 999 test addresses with valid test addresses + for i := 100; i < (numAddrs + 100); i++ { + numString := strconv.Itoa(i) + buffer.WriteString("A58856F0FD53BF058B4909A21AEC019107BA6") //base address string + + buffer.WriteString(numString) //adding on final two digits to make addresses unique + res, _ := sdk.AccAddressFromHex(buffer.String()) + bech := res.String() + addresses = append(addresses, CreateTestAddr(buffer.String(), bech)) + buffer.Reset() + } + return addresses +} + +// 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 +} + +// for incode address generation +func CreateTestAddr(addr string, bech string) sdk.AccAddress { + + res, err := sdk.AccAddressFromHex(addr) + if err != nil { + panic(err) + } + bechexpected := res.String() + if bech != bechexpected { + panic("Bech encoding doesn't match reference") + } + + bechres, err := sdk.AccAddressFromBech32(bech) + if err != nil { + panic(err) + } + if !bytes.Equal(bechres, res) { + panic("Bech decode and hex decode don't match") + } + + return res +} diff --git a/x/staking/keeper/historical_info_test.go b/x/staking/keeper/historical_info_test.go index db372bce2cae..50250116ef0b 100644 --- a/x/staking/keeper/historical_info_test.go +++ b/x/staking/keeper/historical_info_test.go @@ -1,10 +1,11 @@ -package keeper +package keeper_test import ( "sort" "testing" - sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/simapp" + "github.com/cosmos/cosmos-sdk/x/staking/types" "github.com/stretchr/testify/require" @@ -12,7 +13,9 @@ import ( ) func TestHistoricalInfo(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 10) + app := simapp.Setup(false) + ctx := app.BaseApp.NewContext(false, abci.Header{}) + validators := make([]types.Validator, len(addrVals)) for i, valAddr := range addrVals { @@ -21,86 +24,86 @@ func TestHistoricalInfo(t *testing.T) { hi := types.NewHistoricalInfo(ctx.BlockHeader(), validators) - keeper.SetHistoricalInfo(ctx, 2, hi) + app.StakingKeeper.SetHistoricalInfo(ctx, 2, hi) - recv, found := keeper.GetHistoricalInfo(ctx, 2) + recv, found := app.StakingKeeper.GetHistoricalInfo(ctx, 2) require.True(t, found, "HistoricalInfo not found after set") require.Equal(t, hi, recv, "HistoricalInfo not equal") require.True(t, sort.IsSorted(types.Validators(recv.Valset)), "HistoricalInfo validators is not sorted") - keeper.DeleteHistoricalInfo(ctx, 2) + app.StakingKeeper.DeleteHistoricalInfo(ctx, 2) - recv, found = keeper.GetHistoricalInfo(ctx, 2) + recv, found = app.StakingKeeper.GetHistoricalInfo(ctx, 2) require.False(t, found, "HistoricalInfo found after delete") require.Equal(t, types.HistoricalInfo{}, recv, "HistoricalInfo is not empty") } -func TestTrackHistoricalInfo(t *testing.T) { - ctx, _, _, k, _ := CreateTestInput(t, false, 10) - - // set historical entries in params to 5 - params := types.DefaultParams() - params.HistoricalEntries = 5 - k.SetParams(ctx, params) - - // set historical info at 5, 4 which should be pruned - // and check that it has been stored - h4 := abci.Header{ - ChainID: "HelloChain", - Height: 4, - } - h5 := abci.Header{ - ChainID: "HelloChain", - Height: 5, - } - valSet := []types.Validator{ - types.NewValidator(sdk.ValAddress(Addrs[0]), PKs[0], types.Description{}), - types.NewValidator(sdk.ValAddress(Addrs[1]), PKs[1], types.Description{}), - } - hi4 := types.NewHistoricalInfo(h4, valSet) - hi5 := types.NewHistoricalInfo(h5, valSet) - k.SetHistoricalInfo(ctx, 4, hi4) - k.SetHistoricalInfo(ctx, 5, hi5) - recv, found := k.GetHistoricalInfo(ctx, 4) - require.True(t, found) - require.Equal(t, hi4, recv) - recv, found = k.GetHistoricalInfo(ctx, 5) - require.True(t, found) - require.Equal(t, hi5, recv) - - // Set last validators in keeper - val1 := types.NewValidator(sdk.ValAddress(Addrs[2]), PKs[2], types.Description{}) - k.SetValidator(ctx, val1) - k.SetLastValidatorPower(ctx, val1.OperatorAddress, 10) - val2 := types.NewValidator(sdk.ValAddress(Addrs[3]), PKs[3], types.Description{}) - vals := []types.Validator{val1, val2} - sort.Sort(types.Validators(vals)) - k.SetValidator(ctx, val2) - k.SetLastValidatorPower(ctx, val2.OperatorAddress, 8) - - // Set Header for BeginBlock context - header := abci.Header{ - ChainID: "HelloChain", - Height: 10, - } - ctx = ctx.WithBlockHeader(header) - - k.TrackHistoricalInfo(ctx) - - // Check HistoricalInfo at height 10 is persisted - expected := types.HistoricalInfo{ - Header: header, - Valset: vals, - } - recv, found = k.GetHistoricalInfo(ctx, 10) - require.True(t, found, "GetHistoricalInfo failed after BeginBlock") - require.Equal(t, expected, recv, "GetHistoricalInfo returned eunexpected result") - - // Check HistoricalInfo at height 5, 4 is pruned - recv, found = k.GetHistoricalInfo(ctx, 4) - require.False(t, found, "GetHistoricalInfo did not prune earlier height") - require.Equal(t, types.HistoricalInfo{}, recv, "GetHistoricalInfo at height 4 is not empty after prune") - recv, found = k.GetHistoricalInfo(ctx, 5) - require.False(t, found, "GetHistoricalInfo did not prune first prune height") - require.Equal(t, types.HistoricalInfo{}, recv, "GetHistoricalInfo at height 5 is not empty after prune") -} +//func TestTrackHistoricalInfo(t *testing.T) { +// ctx, _, _, k, _ := CreateTestInput(t, false, 10) +// +// // set historical entries in params to 5 +// params := types.DefaultParams() +// params.HistoricalEntries = 5 +// k.SetParams(ctx, params) +// +// // set historical info at 5, 4 which should be pruned +// // and check that it has been stored +// h4 := abci.Header{ +// ChainID: "HelloChain", +// Height: 4, +// } +// h5 := abci.Header{ +// ChainID: "HelloChain", +// Height: 5, +// } +// valSet := []types.Validator{ +// types.NewValidator(sdk.ValAddress(Addrs[0]), PKs[0], types.Description{}), +// types.NewValidator(sdk.ValAddress(Addrs[1]), PKs[1], types.Description{}), +// } +// hi4 := types.NewHistoricalInfo(h4, valSet) +// hi5 := types.NewHistoricalInfo(h5, valSet) +// k.SetHistoricalInfo(ctx, 4, hi4) +// k.SetHistoricalInfo(ctx, 5, hi5) +// recv, found := k.GetHistoricalInfo(ctx, 4) +// require.True(t, found) +// require.Equal(t, hi4, recv) +// recv, found = k.GetHistoricalInfo(ctx, 5) +// require.True(t, found) +// require.Equal(t, hi5, recv) +// +// // Set last validators in keeper +// val1 := types.NewValidator(sdk.ValAddress(Addrs[2]), PKs[2], types.Description{}) +// k.SetValidator(ctx, val1) +// k.SetLastValidatorPower(ctx, val1.OperatorAddress, 10) +// val2 := types.NewValidator(sdk.ValAddress(Addrs[3]), PKs[3], types.Description{}) +// vals := []types.Validator{val1, val2} +// sort.Sort(types.Validators(vals)) +// k.SetValidator(ctx, val2) +// k.SetLastValidatorPower(ctx, val2.OperatorAddress, 8) +// +// // Set Header for BeginBlock context +// header := abci.Header{ +// ChainID: "HelloChain", +// Height: 10, +// } +// ctx = ctx.WithBlockHeader(header) +// +// k.TrackHistoricalInfo(ctx) +// +// // Check HistoricalInfo at height 10 is persisted +// expected := types.HistoricalInfo{ +// Header: header, +// Valset: vals, +// } +// recv, found = k.GetHistoricalInfo(ctx, 10) +// require.True(t, found, "GetHistoricalInfo failed after BeginBlock") +// require.Equal(t, expected, recv, "GetHistoricalInfo returned eunexpected result") +// +// // Check HistoricalInfo at height 5, 4 is pruned +// recv, found = k.GetHistoricalInfo(ctx, 4) +// require.False(t, found, "GetHistoricalInfo did not prune earlier height") +// require.Equal(t, types.HistoricalInfo{}, recv, "GetHistoricalInfo at height 4 is not empty after prune") +// recv, found = k.GetHistoricalInfo(ctx, 5) +// require.False(t, found, "GetHistoricalInfo did not prune first prune height") +// require.Equal(t, types.HistoricalInfo{}, recv, "GetHistoricalInfo at height 5 is not empty after prune") +//} From 6025132720efad5d442bb7d86bbd972ac42b0870 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Tue, 18 Feb 2020 14:03:06 +0100 Subject: [PATCH 03/90] refactor historical info test --- x/staking/keeper/historical_info_test.go | 141 ++++++++++++----------- 1 file changed, 72 insertions(+), 69 deletions(-) diff --git a/x/staking/keeper/historical_info_test.go b/x/staking/keeper/historical_info_test.go index 50250116ef0b..73cc64de0f4e 100644 --- a/x/staking/keeper/historical_info_test.go +++ b/x/staking/keeper/historical_info_test.go @@ -4,6 +4,8 @@ import ( "sort" "testing" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/simapp" "github.com/cosmos/cosmos-sdk/x/staking/types" @@ -38,72 +40,73 @@ func TestHistoricalInfo(t *testing.T) { require.Equal(t, types.HistoricalInfo{}, recv, "HistoricalInfo is not empty") } -//func TestTrackHistoricalInfo(t *testing.T) { -// ctx, _, _, k, _ := CreateTestInput(t, false, 10) -// -// // set historical entries in params to 5 -// params := types.DefaultParams() -// params.HistoricalEntries = 5 -// k.SetParams(ctx, params) -// -// // set historical info at 5, 4 which should be pruned -// // and check that it has been stored -// h4 := abci.Header{ -// ChainID: "HelloChain", -// Height: 4, -// } -// h5 := abci.Header{ -// ChainID: "HelloChain", -// Height: 5, -// } -// valSet := []types.Validator{ -// types.NewValidator(sdk.ValAddress(Addrs[0]), PKs[0], types.Description{}), -// types.NewValidator(sdk.ValAddress(Addrs[1]), PKs[1], types.Description{}), -// } -// hi4 := types.NewHistoricalInfo(h4, valSet) -// hi5 := types.NewHistoricalInfo(h5, valSet) -// k.SetHistoricalInfo(ctx, 4, hi4) -// k.SetHistoricalInfo(ctx, 5, hi5) -// recv, found := k.GetHistoricalInfo(ctx, 4) -// require.True(t, found) -// require.Equal(t, hi4, recv) -// recv, found = k.GetHistoricalInfo(ctx, 5) -// require.True(t, found) -// require.Equal(t, hi5, recv) -// -// // Set last validators in keeper -// val1 := types.NewValidator(sdk.ValAddress(Addrs[2]), PKs[2], types.Description{}) -// k.SetValidator(ctx, val1) -// k.SetLastValidatorPower(ctx, val1.OperatorAddress, 10) -// val2 := types.NewValidator(sdk.ValAddress(Addrs[3]), PKs[3], types.Description{}) -// vals := []types.Validator{val1, val2} -// sort.Sort(types.Validators(vals)) -// k.SetValidator(ctx, val2) -// k.SetLastValidatorPower(ctx, val2.OperatorAddress, 8) -// -// // Set Header for BeginBlock context -// header := abci.Header{ -// ChainID: "HelloChain", -// Height: 10, -// } -// ctx = ctx.WithBlockHeader(header) -// -// k.TrackHistoricalInfo(ctx) -// -// // Check HistoricalInfo at height 10 is persisted -// expected := types.HistoricalInfo{ -// Header: header, -// Valset: vals, -// } -// recv, found = k.GetHistoricalInfo(ctx, 10) -// require.True(t, found, "GetHistoricalInfo failed after BeginBlock") -// require.Equal(t, expected, recv, "GetHistoricalInfo returned eunexpected result") -// -// // Check HistoricalInfo at height 5, 4 is pruned -// recv, found = k.GetHistoricalInfo(ctx, 4) -// require.False(t, found, "GetHistoricalInfo did not prune earlier height") -// require.Equal(t, types.HistoricalInfo{}, recv, "GetHistoricalInfo at height 4 is not empty after prune") -// recv, found = k.GetHistoricalInfo(ctx, 5) -// require.False(t, found, "GetHistoricalInfo did not prune first prune height") -// require.Equal(t, types.HistoricalInfo{}, recv, "GetHistoricalInfo at height 5 is not empty after prune") -//} +func TestTrackHistoricalInfo(t *testing.T) { + app := simapp.Setup(false) + ctx := app.BaseApp.NewContext(false, abci.Header{}) + + // set historical entries in params to 5 + params := types.DefaultParams() + params.HistoricalEntries = 5 + app.StakingKeeper.SetParams(ctx, params) + + // set historical info at 5, 4 which should be pruned + // and check that it has been stored + h4 := abci.Header{ + ChainID: "HelloChain", + Height: 4, + } + h5 := abci.Header{ + ChainID: "HelloChain", + Height: 5, + } + valSet := []types.Validator{ + types.NewValidator(sdk.ValAddress(Addrs[0]), PKs[0], types.Description{}), + types.NewValidator(sdk.ValAddress(Addrs[1]), PKs[1], types.Description{}), + } + hi4 := types.NewHistoricalInfo(h4, valSet) + hi5 := types.NewHistoricalInfo(h5, valSet) + app.StakingKeeper.SetHistoricalInfo(ctx, 4, hi4) + app.StakingKeeper.SetHistoricalInfo(ctx, 5, hi5) + recv, found := app.StakingKeeper.GetHistoricalInfo(ctx, 4) + require.True(t, found) + require.Equal(t, hi4, recv) + recv, found = app.StakingKeeper.GetHistoricalInfo(ctx, 5) + require.True(t, found) + require.Equal(t, hi5, recv) + + // Set last validators in keeper + val1 := types.NewValidator(sdk.ValAddress(Addrs[2]), PKs[2], types.Description{}) + app.StakingKeeper.SetValidator(ctx, val1) + app.StakingKeeper.SetLastValidatorPower(ctx, val1.OperatorAddress, 10) + val2 := types.NewValidator(sdk.ValAddress(Addrs[3]), PKs[3], types.Description{}) + vals := []types.Validator{val1, val2} + sort.Sort(types.Validators(vals)) + app.StakingKeeper.SetValidator(ctx, val2) + app.StakingKeeper.SetLastValidatorPower(ctx, val2.OperatorAddress, 8) + + // Set Header for BeginBlock context + header := abci.Header{ + ChainID: "HelloChain", + Height: 10, + } + ctx = ctx.WithBlockHeader(header) + + app.StakingKeeper.TrackHistoricalInfo(ctx) + + // Check HistoricalInfo at height 10 is persisted + expected := types.HistoricalInfo{ + Header: header, + Valset: vals, + } + recv, found = app.StakingKeeper.GetHistoricalInfo(ctx, 10) + require.True(t, found, "GetHistoricalInfo failed after BeginBlock") + require.Equal(t, expected, recv, "GetHistoricalInfo returned eunexpected result") + + // Check HistoricalInfo at height 5, 4 is pruned + recv, found = app.StakingKeeper.GetHistoricalInfo(ctx, 4) + require.False(t, found, "GetHistoricalInfo did not prune earlier height") + require.Equal(t, types.HistoricalInfo{}, recv, "GetHistoricalInfo at height 4 is not empty after prune") + recv, found = app.StakingKeeper.GetHistoricalInfo(ctx, 5) + require.False(t, found, "GetHistoricalInfo did not prune first prune height") + require.Equal(t, types.HistoricalInfo{}, recv, "GetHistoricalInfo at height 5 is not empty after prune") +} From c84c5922e4acb199bd7c69bd7d6af7c5bcc96af6 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Tue, 18 Feb 2020 16:44:23 +0100 Subject: [PATCH 04/90] temporal commit on querier test, it passes --- x/staking/keeper/common_refactor_test.go | 2 +- x/staking/keeper/querier_test.go | 889 ++++++++++++----------- 2 files changed, 451 insertions(+), 440 deletions(-) diff --git a/x/staking/keeper/common_refactor_test.go b/x/staking/keeper/common_refactor_test.go index 33a4f0c1ab50..8b43af1739f2 100644 --- a/x/staking/keeper/common_refactor_test.go +++ b/x/staking/keeper/common_refactor_test.go @@ -5,10 +5,10 @@ import ( "encoding/hex" "strconv" + "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/tendermint/tendermint/crypto" ) var ( diff --git a/x/staking/keeper/querier_test.go b/x/staking/keeper/querier_test.go index 2bbd468ae075..202290762ba5 100644 --- a/x/staking/keeper/querier_test.go +++ b/x/staking/keeper/querier_test.go @@ -1,4 +1,4 @@ -package keeper +package keeper_test import ( "fmt" @@ -8,7 +8,9 @@ import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/codec" + "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" ) @@ -20,15 +22,17 @@ var ( func TestNewQuerier(t *testing.T) { cdc := codec.New() - ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) + app := simapp.Setup(false) + ctx := app.BaseApp.NewContext(false, abci.Header{}) + // Create Validators amts := []sdk.Int{sdk.NewInt(9), sdk.NewInt(8)} var validators [2]types.Validator for i, amt := range amts { validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) validators[i], _ = validators[i].AddTokensFromDel(amt) - keeper.SetValidator(ctx, validators[i]) - keeper.SetValidatorByPowerIndex(ctx, validators[i]) + app.StakingKeeper.SetValidator(ctx, validators[i]) + app.StakingKeeper.SetValidatorByPowerIndex(ctx, validators[i]) } header := abci.Header{ @@ -36,14 +40,14 @@ func TestNewQuerier(t *testing.T) { Height: 5, } hi := types.NewHistoricalInfo(header, validators[:]) - keeper.SetHistoricalInfo(ctx, 5, hi) + app.StakingKeeper.SetHistoricalInfo(ctx, 5, hi) query := abci.RequestQuery{ Path: "", Data: []byte{}, } - querier := NewQuerier(keeper) + querier := staking.NewQuerier(app.StakingKeeper) bz, err := querier(ctx, []string{"other"}, query) require.Error(t, err) @@ -107,32 +111,37 @@ func TestNewQuerier(t *testing.T) { func TestQueryParametersPool(t *testing.T) { cdc := codec.New() - ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) + app := simapp.Setup(false) + ctx := app.BaseApp.NewContext(false, abci.Header{}) + querier := staking.NewQuerier(app.StakingKeeper) + bondDenom := sdk.DefaultBondDenom - res, err := queryParameters(ctx, keeper) + res, err := querier(ctx, []string{staking.QueryParameters}, abci.RequestQuery{}) require.NoError(t, err) var params types.Params errRes := cdc.UnmarshalJSON(res, ¶ms) require.NoError(t, errRes) - require.Equal(t, keeper.GetParams(ctx), params) + require.Equal(t, app.StakingKeeper.GetParams(ctx), params) - res, err = queryPool(ctx, keeper) + res, err = querier(ctx, []string{staking.QueryPool}, abci.RequestQuery{}) require.NoError(t, err) var pool types.Pool - bondedPool := keeper.GetBondedPool(ctx) - notBondedPool := keeper.GetNotBondedPool(ctx) + bondedPool := app.StakingKeeper.GetBondedPool(ctx) + notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) require.NoError(t, cdc.UnmarshalJSON(res, &pool)) - require.Equal(t, keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount, pool.NotBondedTokens) - require.Equal(t, keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount, pool.BondedTokens) + require.Equal(t, app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount, pool.NotBondedTokens) + require.Equal(t, app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount, pool.BondedTokens) } func TestQueryValidators(t *testing.T) { cdc := codec.New() - ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000) - params := keeper.GetParams(ctx) + app := simapp.Setup(false) + ctx := app.BaseApp.NewContext(false, abci.Header{}) + params := app.StakingKeeper.GetParams(ctx) + querier := staking.NewQuerier(app.StakingKeeper) // Create Validators amts := []sdk.Int{sdk.NewInt(9), sdk.NewInt(8), sdk.NewInt(7)} @@ -144,12 +153,12 @@ func TestQueryValidators(t *testing.T) { validators[i] = validators[i].UpdateStatus(status[i]) } - keeper.SetValidator(ctx, validators[0]) - keeper.SetValidator(ctx, validators[1]) - keeper.SetValidator(ctx, validators[2]) + app.StakingKeeper.SetValidator(ctx, validators[0]) + app.StakingKeeper.SetValidator(ctx, validators[1]) + app.StakingKeeper.SetValidator(ctx, validators[2]) // Query Validators - queriedValidators := keeper.GetValidators(ctx, params.MaxValidators) + queriedValidators := app.StakingKeeper.GetValidators(ctx, params.MaxValidators) for i, s := range status { queryValsParams := types.NewQueryValidatorsParams(1, int(params.MaxValidators), s.String()) @@ -161,7 +170,7 @@ func TestQueryValidators(t *testing.T) { Data: bz, } - res, err := queryValidators(ctx, req, keeper) + res, err := querier(ctx, []string{types.QueryValidators}, req) require.NoError(t, err) var validatorsResp []types.Validator @@ -182,7 +191,7 @@ func TestQueryValidators(t *testing.T) { Path: "/custom/staking/validator", Data: bz, } - res, err := queryValidator(ctx, query, keeper) + res, err := querier(ctx, []string{types.QueryValidator}, query) require.NoError(t, err) var validator types.Validator @@ -192,420 +201,422 @@ func TestQueryValidators(t *testing.T) { require.Equal(t, queriedValidators[0], validator) } -func TestQueryDelegation(t *testing.T) { - cdc := codec.New() - ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000) - params := keeper.GetParams(ctx) - - // Create Validators and Delegation - val1 := types.NewValidator(addrVal1, pk1, types.Description{}) - keeper.SetValidator(ctx, val1) - keeper.SetValidatorByPowerIndex(ctx, val1) - - val2 := types.NewValidator(addrVal2, pk2, types.Description{}) - keeper.SetValidator(ctx, val2) - keeper.SetValidatorByPowerIndex(ctx, val2) - - delTokens := sdk.TokensFromConsensusPower(20) - keeper.Delegate(ctx, addrAcc2, delTokens, sdk.Unbonded, val1, true) - - // apply TM updates - keeper.ApplyAndReturnValidatorSetUpdates(ctx) - - // Query Delegator bonded validators - queryParams := types.NewQueryDelegatorParams(addrAcc2) - bz, errRes := cdc.MarshalJSON(queryParams) - require.NoError(t, errRes) - - query := abci.RequestQuery{ - Path: "/custom/staking/delegatorValidators", - Data: bz, - } - - delValidators := keeper.GetDelegatorValidators(ctx, addrAcc2, params.MaxValidators) - - res, err := queryDelegatorValidators(ctx, query, keeper) - require.NoError(t, err) - - var validatorsResp []types.Validator - errRes = cdc.UnmarshalJSON(res, &validatorsResp) - require.NoError(t, errRes) - - require.Equal(t, len(delValidators), len(validatorsResp)) - require.ElementsMatch(t, delValidators, validatorsResp) - - // error unknown request - query.Data = bz[:len(bz)-1] - - _, err = queryDelegatorValidators(ctx, query, keeper) - require.Error(t, err) - - // Query bonded validator - queryBondParams := types.NewQueryBondsParams(addrAcc2, addrVal1) - bz, errRes = cdc.MarshalJSON(queryBondParams) - require.NoError(t, errRes) - - query = abci.RequestQuery{ - Path: "/custom/staking/delegatorValidator", - Data: bz, - } - - res, err = queryDelegatorValidator(ctx, query, keeper) - require.NoError(t, err) - - var validator types.Validator - errRes = cdc.UnmarshalJSON(res, &validator) - require.NoError(t, errRes) - - require.Equal(t, delValidators[0], validator) - - // error unknown request - query.Data = bz[:len(bz)-1] - - _, err = queryDelegatorValidator(ctx, query, keeper) - require.Error(t, err) - - // Query delegation - - query = abci.RequestQuery{ - Path: "/custom/staking/delegation", - Data: bz, - } - - delegation, found := keeper.GetDelegation(ctx, addrAcc2, addrVal1) - require.True(t, found) - - res, err = queryDelegation(ctx, query, keeper) - require.NoError(t, err) - - var delegationRes types.DelegationResponse - errRes = cdc.UnmarshalJSON(res, &delegationRes) - require.NoError(t, errRes) - - require.Equal(t, delegation.ValidatorAddress, delegationRes.ValidatorAddress) - require.Equal(t, delegation.DelegatorAddress, delegationRes.DelegatorAddress) - require.Equal(t, sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), delegationRes.Balance) - - // Query Delegator Delegations - query = abci.RequestQuery{ - Path: "/custom/staking/delegatorDelegations", - Data: bz, - } - - res, err = queryDelegatorDelegations(ctx, query, keeper) - require.NoError(t, err) - - var delegatorDelegations types.DelegationResponses - errRes = cdc.UnmarshalJSON(res, &delegatorDelegations) - require.NoError(t, errRes) - require.Len(t, delegatorDelegations, 1) - require.Equal(t, delegation.ValidatorAddress, delegatorDelegations[0].ValidatorAddress) - require.Equal(t, delegation.DelegatorAddress, delegatorDelegations[0].DelegatorAddress) - require.Equal(t, sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), delegatorDelegations[0].Balance) - - // error unknown request - query.Data = bz[:len(bz)-1] - - _, err = queryDelegation(ctx, query, keeper) - require.Error(t, err) - - // Query validator delegations - - bz, errRes = cdc.MarshalJSON(types.NewQueryValidatorParams(addrVal1)) - require.NoError(t, errRes) - - query = abci.RequestQuery{ - Path: "custom/staking/validatorDelegations", - Data: bz, - } - - res, err = queryValidatorDelegations(ctx, query, keeper) - require.NoError(t, err) - - var delegationsRes types.DelegationResponses - errRes = cdc.UnmarshalJSON(res, &delegationsRes) - require.NoError(t, errRes) - require.Len(t, delegatorDelegations, 1) - require.Equal(t, delegation.ValidatorAddress, delegationsRes[0].ValidatorAddress) - require.Equal(t, delegation.DelegatorAddress, delegationsRes[0].DelegatorAddress) - require.Equal(t, sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), delegationsRes[0].Balance) - - // Query unbonging delegation - unbondingTokens := sdk.TokensFromConsensusPower(10) - _, err = keeper.Undelegate(ctx, addrAcc2, val1.OperatorAddress, unbondingTokens.ToDec()) - require.NoError(t, err) - - queryBondParams = types.NewQueryBondsParams(addrAcc2, addrVal1) - bz, errRes = cdc.MarshalJSON(queryBondParams) - require.NoError(t, errRes) - - query = abci.RequestQuery{ - Path: "/custom/staking/unbondingDelegation", - Data: bz, - } - - unbond, found := keeper.GetUnbondingDelegation(ctx, addrAcc2, addrVal1) - require.True(t, found) - - res, err = queryUnbondingDelegation(ctx, query, keeper) - require.NoError(t, err) - - var unbondRes types.UnbondingDelegation - errRes = cdc.UnmarshalJSON(res, &unbondRes) - require.NoError(t, errRes) - - require.Equal(t, unbond, unbondRes) - - // error unknown request - query.Data = bz[:len(bz)-1] - - _, err = queryUnbondingDelegation(ctx, query, keeper) - require.Error(t, err) - - // Query Delegator Delegations - - query = abci.RequestQuery{ - Path: "/custom/staking/delegatorUnbondingDelegations", - Data: bz, - } - - res, err = queryDelegatorUnbondingDelegations(ctx, query, keeper) - require.NoError(t, err) - - var delegatorUbds []types.UnbondingDelegation - errRes = cdc.UnmarshalJSON(res, &delegatorUbds) - require.NoError(t, errRes) - require.Equal(t, unbond, delegatorUbds[0]) - - // error unknown request - query.Data = bz[:len(bz)-1] - - _, err = queryDelegatorUnbondingDelegations(ctx, query, keeper) - require.Error(t, err) - - // Query redelegation - redelegationTokens := sdk.TokensFromConsensusPower(10) - _, err = keeper.BeginRedelegation(ctx, addrAcc2, val1.OperatorAddress, - val2.OperatorAddress, redelegationTokens.ToDec()) - require.NoError(t, err) - redel, found := keeper.GetRedelegation(ctx, addrAcc2, val1.OperatorAddress, val2.OperatorAddress) - require.True(t, found) - - bz, errRes = cdc.MarshalJSON(types.NewQueryRedelegationParams(addrAcc2, val1.OperatorAddress, val2.OperatorAddress)) - require.NoError(t, errRes) - - query = abci.RequestQuery{ - Path: "/custom/staking/redelegations", - Data: bz, - } - - res, err = queryRedelegations(ctx, query, keeper) - require.NoError(t, err) - - var redelRes types.RedelegationResponses - errRes = cdc.UnmarshalJSON(res, &redelRes) - require.NoError(t, errRes) - require.Len(t, redelRes, 1) - require.Equal(t, redel.DelegatorAddress, redelRes[0].DelegatorAddress) - require.Equal(t, redel.ValidatorSrcAddress, redelRes[0].ValidatorSrcAddress) - require.Equal(t, redel.ValidatorDstAddress, redelRes[0].ValidatorDstAddress) - require.Len(t, redel.Entries, len(redelRes[0].Entries)) -} - -func TestQueryRedelegations(t *testing.T) { - cdc := codec.New() - ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000) - - // Create Validators and Delegation - val1 := types.NewValidator(addrVal1, pk1, types.Description{}) - val2 := types.NewValidator(addrVal2, pk2, types.Description{}) - keeper.SetValidator(ctx, val1) - keeper.SetValidator(ctx, val2) - - delAmount := sdk.TokensFromConsensusPower(100) - keeper.Delegate(ctx, addrAcc2, delAmount, sdk.Unbonded, val1, true) - _ = keeper.ApplyAndReturnValidatorSetUpdates(ctx) - - rdAmount := sdk.TokensFromConsensusPower(20) - keeper.BeginRedelegation(ctx, addrAcc2, val1.GetOperator(), val2.GetOperator(), rdAmount.ToDec()) - keeper.ApplyAndReturnValidatorSetUpdates(ctx) - - redel, found := keeper.GetRedelegation(ctx, addrAcc2, val1.OperatorAddress, val2.OperatorAddress) - require.True(t, found) - - // delegator redelegations - queryDelegatorParams := types.NewQueryDelegatorParams(addrAcc2) - bz, errRes := cdc.MarshalJSON(queryDelegatorParams) - require.NoError(t, errRes) - - query := abci.RequestQuery{ - Path: "/custom/staking/redelegations", - Data: bz, - } - - res, err := queryRedelegations(ctx, query, keeper) - require.NoError(t, err) - - var redelRes types.RedelegationResponses - errRes = cdc.UnmarshalJSON(res, &redelRes) - require.NoError(t, errRes) - require.Len(t, redelRes, 1) - require.Equal(t, redel.DelegatorAddress, redelRes[0].DelegatorAddress) - require.Equal(t, redel.ValidatorSrcAddress, redelRes[0].ValidatorSrcAddress) - require.Equal(t, redel.ValidatorDstAddress, redelRes[0].ValidatorDstAddress) - require.Len(t, redel.Entries, len(redelRes[0].Entries)) - - // validator redelegations - queryValidatorParams := types.NewQueryValidatorParams(val1.GetOperator()) - bz, errRes = cdc.MarshalJSON(queryValidatorParams) - require.NoError(t, errRes) - - query = abci.RequestQuery{ - Path: "/custom/staking/redelegations", - Data: bz, - } - - res, err = queryRedelegations(ctx, query, keeper) - require.NoError(t, err) - - errRes = cdc.UnmarshalJSON(res, &redelRes) - require.NoError(t, errRes) - require.Len(t, redelRes, 1) - require.Equal(t, redel.DelegatorAddress, redelRes[0].DelegatorAddress) - require.Equal(t, redel.ValidatorSrcAddress, redelRes[0].ValidatorSrcAddress) - require.Equal(t, redel.ValidatorDstAddress, redelRes[0].ValidatorDstAddress) - require.Len(t, redel.Entries, len(redelRes[0].Entries)) -} - -func TestQueryUnbondingDelegation(t *testing.T) { - cdc := codec.New() - ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000) - - // Create Validators and Delegation - val1 := types.NewValidator(addrVal1, pk1, types.Description{}) - keeper.SetValidator(ctx, val1) - - // delegate - delAmount := sdk.TokensFromConsensusPower(100) - _, err := keeper.Delegate(ctx, addrAcc1, delAmount, sdk.Unbonded, val1, true) - require.NoError(t, err) - _ = keeper.ApplyAndReturnValidatorSetUpdates(ctx) - - // undelegate - undelAmount := sdk.TokensFromConsensusPower(20) - _, err = keeper.Undelegate(ctx, addrAcc1, val1.GetOperator(), undelAmount.ToDec()) - require.NoError(t, err) - keeper.ApplyAndReturnValidatorSetUpdates(ctx) - - _, found := keeper.GetUnbondingDelegation(ctx, addrAcc1, val1.OperatorAddress) - require.True(t, found) - - // - // found: query unbonding delegation by delegator and validator - // - queryValidatorParams := types.NewQueryBondsParams(addrAcc1, val1.GetOperator()) - bz, errRes := cdc.MarshalJSON(queryValidatorParams) - require.NoError(t, errRes) - query := abci.RequestQuery{ - Path: "/custom/staking/unbondingDelegation", - Data: bz, - } - res, err := queryUnbondingDelegation(ctx, query, keeper) - require.NoError(t, err) - require.NotNil(t, res) - var ubDel types.UnbondingDelegation - require.NoError(t, cdc.UnmarshalJSON(res, &ubDel)) - require.Equal(t, addrAcc1, ubDel.DelegatorAddress) - require.Equal(t, val1.OperatorAddress, ubDel.ValidatorAddress) - require.Equal(t, 1, len(ubDel.Entries)) - - // - // not found: query unbonding delegation by delegator and validator - // - queryValidatorParams = types.NewQueryBondsParams(addrAcc2, val1.GetOperator()) - bz, errRes = cdc.MarshalJSON(queryValidatorParams) - require.NoError(t, errRes) - query = abci.RequestQuery{ - Path: "/custom/staking/unbondingDelegation", - Data: bz, - } - _, err = queryUnbondingDelegation(ctx, query, keeper) - require.Error(t, err) - - // - // found: query unbonding delegation by delegator and validator - // - queryDelegatorParams := types.NewQueryDelegatorParams(addrAcc1) - bz, errRes = cdc.MarshalJSON(queryDelegatorParams) - require.NoError(t, errRes) - query = abci.RequestQuery{ - Path: "/custom/staking/delegatorUnbondingDelegations", - Data: bz, - } - res, err = queryDelegatorUnbondingDelegations(ctx, query, keeper) - require.NoError(t, err) - require.NotNil(t, res) - var ubDels []types.UnbondingDelegation - require.NoError(t, cdc.UnmarshalJSON(res, &ubDels)) - require.Equal(t, 1, len(ubDels)) - require.Equal(t, addrAcc1, ubDels[0].DelegatorAddress) - require.Equal(t, val1.OperatorAddress, ubDels[0].ValidatorAddress) - - // - // not found: query unbonding delegation by delegator and validator - // - queryDelegatorParams = types.NewQueryDelegatorParams(addrAcc2) - bz, errRes = cdc.MarshalJSON(queryDelegatorParams) - require.NoError(t, errRes) - query = abci.RequestQuery{ - Path: "/custom/staking/delegatorUnbondingDelegations", - Data: bz, - } - res, err = queryDelegatorUnbondingDelegations(ctx, query, keeper) - require.NoError(t, err) - require.NotNil(t, res) - require.NoError(t, cdc.UnmarshalJSON(res, &ubDels)) - require.Equal(t, 0, len(ubDels)) -} - -func TestQueryHistoricalInfo(t *testing.T) { - cdc := codec.New() - ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000) - - // Create Validators and Delegation - val1 := types.NewValidator(addrVal1, pk1, types.Description{}) - val2 := types.NewValidator(addrVal2, pk2, types.Description{}) - vals := []types.Validator{val1, val2} - keeper.SetValidator(ctx, val1) - keeper.SetValidator(ctx, val2) - - header := abci.Header{ - ChainID: "HelloChain", - Height: 5, - } - hi := types.NewHistoricalInfo(header, vals) - keeper.SetHistoricalInfo(ctx, 5, hi) - - queryHistoricalParams := types.NewQueryHistoricalInfoParams(4) - bz, errRes := cdc.MarshalJSON(queryHistoricalParams) - require.NoError(t, errRes) - query := abci.RequestQuery{ - Path: "/custom/staking/historicalInfo", - Data: bz, - } - res, err := queryHistoricalInfo(ctx, query, keeper) - require.Error(t, err, "Invalid query passed") - require.Nil(t, res, "Invalid query returned non-nil result") - - queryHistoricalParams = types.NewQueryHistoricalInfoParams(5) - bz, errRes = cdc.MarshalJSON(queryHistoricalParams) - require.NoError(t, errRes) - query.Data = bz - res, err = queryHistoricalInfo(ctx, query, keeper) - require.NoError(t, err, "Valid query passed") - require.NotNil(t, res, "Valid query returned nil result") - - var recv types.HistoricalInfo - require.NoError(t, cdc.UnmarshalJSON(res, &recv)) - require.Equal(t, hi, recv, "HistoricalInfo query returned wrong result") -} +//func TestQueryDelegation(t *testing.T) { +// cdc := codec.New() +// app := simapp.Setup(false) +// ctx := app.BaseApp.NewContext(false, abci.Header{}) +// params := app.StakingKeeper.GetParams(ctx) +// querier := staking.NewQuerier(app.StakingKeeper) +// +// // Create Validators and Delegation +// val1 := types.NewValidator(addrVal1, pk1, types.Description{}) +// app.StakingKeeper.SetValidator(ctx, val1) +// app.StakingKeeper.SetValidatorByPowerIndex(ctx, val1) +// +// val2 := types.NewValidator(addrVal2, pk2, types.Description{}) +// app.StakingKeeper.SetValidator(ctx, val2) +// app.StakingKeeper.SetValidatorByPowerIndex(ctx, val2) +// +// delTokens := sdk.TokensFromConsensusPower(20) +// app.StakingKeeper.Delegate(ctx, addrAcc2, delTokens, sdk.Unbonded, val1, true) +// +// // apply TM updates +// app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) +// +// // Query Delegator bonded validators +// queryParams := types.NewQueryDelegatorParams(addrAcc2) +// bz, errRes := cdc.MarshalJSON(queryParams) +// require.NoError(t, errRes) +// +// query := abci.RequestQuery{ +// Path: "/custom/staking/delegatorValidators", +// Data: bz, +// } +// +// delValidators := app.StakingKeeper.GetDelegatorValidators(ctx, addrAcc2, params.MaxValidators) +// +// res, err := querier(ctx, []string{types.QueryDelegatorValidators}, query) +// require.NoError(t, err) +// +// var validatorsResp []types.Validator +// errRes = cdc.UnmarshalJSON(res, &validatorsResp) +// require.NoError(t, errRes) +// +// require.Equal(t, len(delValidators), len(validatorsResp)) +// require.ElementsMatch(t, delValidators, validatorsResp) +// +// // error unknown request +// query.Data = bz[:len(bz)-1] +// +// res, err = querier(ctx, []string{types.QueryDelegatorValidators}, query) +// require.Error(t, err) +// +// // Query bonded validator +// queryBondParams := types.NewQueryBondsParams(addrAcc2, addrVal1) +// bz, errRes = cdc.MarshalJSON(queryBondParams) +// require.NoError(t, errRes) +// +// query = abci.RequestQuery{ +// Path: "/custom/staking/delegatorValidator", +// Data: bz, +// } +// +// res, err = querier(ctx, []string{types.QueryDelegatorValidator}, query) +// require.NoError(t, err) +// +// var validator types.Validator +// errRes = cdc.UnmarshalJSON(res, &validator) +// require.NoError(t, errRes) +// +// require.Equal(t, delValidators[0], validator) +// +// // error unknown request +// query.Data = bz[:len(bz)-1] +// +// res, err = querier(ctx, []string{types.QueryDelegatorValidator}, query) +// require.Error(t, err) +// +// // Query delegation +// +// query = abci.RequestQuery{ +// Path: "/custom/staking/delegation", +// Data: bz, +// } +// +// delegation, found := app.StakingKeeper.GetDelegation(ctx, addrAcc2, addrVal1) +// require.True(t, found) +// +// res, err = querier(ctx, []string{types.QueryDelegation}, query) +// require.NoError(t, err) +// +// var delegationRes types.DelegationResponse +// errRes = cdc.UnmarshalJSON(res, &delegationRes) +// require.NoError(t, errRes) +// +// require.Equal(t, delegation.ValidatorAddress, delegationRes.ValidatorAddress) +// require.Equal(t, delegation.DelegatorAddress, delegationRes.DelegatorAddress) +// require.Equal(t, sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), delegationRes.Balance) +// +// // Query Delegator Delegations +// query = abci.RequestQuery{ +// Path: "/custom/staking/delegatorDelegations", +// Data: bz, +// } +// +// res, err = querier(ctx, []string{types.QueryDelegatorDelegations}, query) +// require.NoError(t, err) +// +// var delegatorDelegations types.DelegationResponses +// errRes = cdc.UnmarshalJSON(res, &delegatorDelegations) +// require.NoError(t, errRes) +// require.Len(t, delegatorDelegations, 1) +// require.Equal(t, delegation.ValidatorAddress, delegatorDelegations[0].ValidatorAddress) +// require.Equal(t, delegation.DelegatorAddress, delegatorDelegations[0].DelegatorAddress) +// require.Equal(t, sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), delegatorDelegations[0].Balance) +// +// // error unknown request +// query.Data = bz[:len(bz)-1] +// +// res, err = querier(ctx, []string{types.QueryDelegation}, query) +// require.Error(t, err) +// +// // Query validator delegations +// +// bz, errRes = cdc.MarshalJSON(types.NewQueryValidatorParams(addrVal1)) +// require.NoError(t, errRes) +// +// query = abci.RequestQuery{ +// Path: "custom/staking/validatorDelegations", +// Data: bz, +// } +// +// res, err = querier(ctx, []string{types.QueryValidatorDelegations}, query) +// require.NoError(t, err) +// +// var delegationsRes types.DelegationResponses +// errRes = cdc.UnmarshalJSON(res, &delegationsRes) +// require.NoError(t, errRes) +// require.Len(t, delegatorDelegations, 1) +// require.Equal(t, delegation.ValidatorAddress, delegationsRes[0].ValidatorAddress) +// require.Equal(t, delegation.DelegatorAddress, delegationsRes[0].DelegatorAddress) +// require.Equal(t, sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), delegationsRes[0].Balance) +// +// // Query unbonging delegation +// unbondingTokens := sdk.TokensFromConsensusPower(10) +// _, err = app.StakingKeeper.Undelegate(ctx, addrAcc2, val1.OperatorAddress, unbondingTokens.ToDec()) +// require.NoError(t, err) +// +// queryBondParams = types.NewQueryBondsParams(addrAcc2, addrVal1) +// bz, errRes = cdc.MarshalJSON(queryBondParams) +// require.NoError(t, errRes) +// +// query = abci.RequestQuery{ +// Path: "/custom/staking/unbondingDelegation", +// Data: bz, +// } +// +// unbond, found := app.StakingKeeper.GetUnbondingDelegation(ctx, addrAcc2, addrVal1) +// require.True(t, found) +// +// res, err = querier(ctx, []string{types.QueryUnbondingDelegation}, query) +// require.NoError(t, err) +// +// var unbondRes types.UnbondingDelegation +// errRes = cdc.UnmarshalJSON(res, &unbondRes) +// require.NoError(t, errRes) +// +// require.Equal(t, unbond, unbondRes) +// +// // error unknown request +// query.Data = bz[:len(bz)-1] +// +// _, err = querier(ctx, []string{types.QueryUnbondingDelegation}, query) +// require.Error(t, err) +// +// // Query Delegator Delegations +// +// query = abci.RequestQuery{ +// Path: "/custom/staking/delegatorUnbondingDelegations", +// Data: bz, +// } +// +// res, err = querier(ctx, []string{types.QueryDelegatorUnbondingDelegations}, query) +// require.NoError(t, err) +// +// var delegatorUbds []types.UnbondingDelegation +// errRes = cdc.UnmarshalJSON(res, &delegatorUbds) +// require.NoError(t, errRes) +// require.Equal(t, unbond, delegatorUbds[0]) +// +// // error unknown request +// query.Data = bz[:len(bz)-1] +// +// _, err = querier(ctx, []string{types.QueryDelegatorUnbondingDelegations}, query) +// require.Error(t, err) +// +// // Query redelegation +// redelegationTokens := sdk.TokensFromConsensusPower(10) +// _, err = app.StakingKeeper.BeginRedelegation(ctx, addrAcc2, val1.OperatorAddress, +// val2.OperatorAddress, redelegationTokens.ToDec()) +// require.NoError(t, err) +// redel, found := app.StakingKeeper.GetRedelegation(ctx, addrAcc2, val1.OperatorAddress, val2.OperatorAddress) +// require.True(t, found) +// +// bz, errRes = cdc.MarshalJSON(types.NewQueryRedelegationParams(addrAcc2, val1.OperatorAddress, val2.OperatorAddress)) +// require.NoError(t, errRes) +// +// query = abci.RequestQuery{ +// Path: "/custom/staking/redelegations", +// Data: bz, +// } +// +// res, err = querier(ctx, []string{types.QueryRedelegations}, query) +// require.NoError(t, err) +// +// var redelRes types.RedelegationResponses +// errRes = cdc.UnmarshalJSON(res, &redelRes) +// require.NoError(t, errRes) +// require.Len(t, redelRes, 1) +// require.Equal(t, redel.DelegatorAddress, redelRes[0].DelegatorAddress) +// require.Equal(t, redel.ValidatorSrcAddress, redelRes[0].ValidatorSrcAddress) +// require.Equal(t, redel.ValidatorDstAddress, redelRes[0].ValidatorDstAddress) +// require.Len(t, redel.Entries, len(redelRes[0].Entries)) +//} +// +//func TestQueryRedelegations(t *testing.T) { +// cdc := codec.New() +// ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000) +// +// // Create Validators and Delegation +// val1 := types.NewValidator(addrVal1, pk1, types.Description{}) +// val2 := types.NewValidator(addrVal2, pk2, types.Description{}) +// keeper.SetValidator(ctx, val1) +// keeper.SetValidator(ctx, val2) +// +// delAmount := sdk.TokensFromConsensusPower(100) +// keeper.Delegate(ctx, addrAcc2, delAmount, sdk.Unbonded, val1, true) +// _ = keeper.ApplyAndReturnValidatorSetUpdates(ctx) +// +// rdAmount := sdk.TokensFromConsensusPower(20) +// keeper.BeginRedelegation(ctx, addrAcc2, val1.GetOperator(), val2.GetOperator(), rdAmount.ToDec()) +// keeper.ApplyAndReturnValidatorSetUpdates(ctx) +// +// redel, found := keeper.GetRedelegation(ctx, addrAcc2, val1.OperatorAddress, val2.OperatorAddress) +// require.True(t, found) +// +// // delegator redelegations +// queryDelegatorParams := types.NewQueryDelegatorParams(addrAcc2) +// bz, errRes := cdc.MarshalJSON(queryDelegatorParams) +// require.NoError(t, errRes) +// +// query := abci.RequestQuery{ +// Path: "/custom/staking/redelegations", +// Data: bz, +// } +// +// res, err := queryRedelegations(ctx, query, keeper) +// require.NoError(t, err) +// +// var redelRes types.RedelegationResponses +// errRes = cdc.UnmarshalJSON(res, &redelRes) +// require.NoError(t, errRes) +// require.Len(t, redelRes, 1) +// require.Equal(t, redel.DelegatorAddress, redelRes[0].DelegatorAddress) +// require.Equal(t, redel.ValidatorSrcAddress, redelRes[0].ValidatorSrcAddress) +// require.Equal(t, redel.ValidatorDstAddress, redelRes[0].ValidatorDstAddress) +// require.Len(t, redel.Entries, len(redelRes[0].Entries)) +// +// // validator redelegations +// queryValidatorParams := types.NewQueryValidatorParams(val1.GetOperator()) +// bz, errRes = cdc.MarshalJSON(queryValidatorParams) +// require.NoError(t, errRes) +// +// query = abci.RequestQuery{ +// Path: "/custom/staking/redelegations", +// Data: bz, +// } +// +// res, err = queryRedelegations(ctx, query, keeper) +// require.NoError(t, err) +// +// errRes = cdc.UnmarshalJSON(res, &redelRes) +// require.NoError(t, errRes) +// require.Len(t, redelRes, 1) +// require.Equal(t, redel.DelegatorAddress, redelRes[0].DelegatorAddress) +// require.Equal(t, redel.ValidatorSrcAddress, redelRes[0].ValidatorSrcAddress) +// require.Equal(t, redel.ValidatorDstAddress, redelRes[0].ValidatorDstAddress) +// require.Len(t, redel.Entries, len(redelRes[0].Entries)) +//} +// +//func TestQueryUnbondingDelegation(t *testing.T) { +// cdc := codec.New() +// ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000) +// +// // Create Validators and Delegation +// val1 := types.NewValidator(addrVal1, pk1, types.Description{}) +// keeper.SetValidator(ctx, val1) +// +// // delegate +// delAmount := sdk.TokensFromConsensusPower(100) +// _, err := keeper.Delegate(ctx, addrAcc1, delAmount, sdk.Unbonded, val1, true) +// require.NoError(t, err) +// _ = keeper.ApplyAndReturnValidatorSetUpdates(ctx) +// +// // undelegate +// undelAmount := sdk.TokensFromConsensusPower(20) +// _, err = keeper.Undelegate(ctx, addrAcc1, val1.GetOperator(), undelAmount.ToDec()) +// require.NoError(t, err) +// keeper.ApplyAndReturnValidatorSetUpdates(ctx) +// +// _, found := keeper.GetUnbondingDelegation(ctx, addrAcc1, val1.OperatorAddress) +// require.True(t, found) +// +// // +// // found: query unbonding delegation by delegator and validator +// // +// queryValidatorParams := types.NewQueryBondsParams(addrAcc1, val1.GetOperator()) +// bz, errRes := cdc.MarshalJSON(queryValidatorParams) +// require.NoError(t, errRes) +// query := abci.RequestQuery{ +// Path: "/custom/staking/unbondingDelegation", +// Data: bz, +// } +// res, err := queryUnbondingDelegation(ctx, query, keeper) +// require.NoError(t, err) +// require.NotNil(t, res) +// var ubDel types.UnbondingDelegation +// require.NoError(t, cdc.UnmarshalJSON(res, &ubDel)) +// require.Equal(t, addrAcc1, ubDel.DelegatorAddress) +// require.Equal(t, val1.OperatorAddress, ubDel.ValidatorAddress) +// require.Equal(t, 1, len(ubDel.Entries)) +// +// // +// // not found: query unbonding delegation by delegator and validator +// // +// queryValidatorParams = types.NewQueryBondsParams(addrAcc2, val1.GetOperator()) +// bz, errRes = cdc.MarshalJSON(queryValidatorParams) +// require.NoError(t, errRes) +// query = abci.RequestQuery{ +// Path: "/custom/staking/unbondingDelegation", +// Data: bz, +// } +// _, err = queryUnbondingDelegation(ctx, query, keeper) +// require.Error(t, err) +// +// // +// // found: query unbonding delegation by delegator and validator +// // +// queryDelegatorParams := types.NewQueryDelegatorParams(addrAcc1) +// bz, errRes = cdc.MarshalJSON(queryDelegatorParams) +// require.NoError(t, errRes) +// query = abci.RequestQuery{ +// Path: "/custom/staking/delegatorUnbondingDelegations", +// Data: bz, +// } +// res, err = queryDelegatorUnbondingDelegations(ctx, query, keeper) +// require.NoError(t, err) +// require.NotNil(t, res) +// var ubDels []types.UnbondingDelegation +// require.NoError(t, cdc.UnmarshalJSON(res, &ubDels)) +// require.Equal(t, 1, len(ubDels)) +// require.Equal(t, addrAcc1, ubDels[0].DelegatorAddress) +// require.Equal(t, val1.OperatorAddress, ubDels[0].ValidatorAddress) +// +// // +// // not found: query unbonding delegation by delegator and validator +// // +// queryDelegatorParams = types.NewQueryDelegatorParams(addrAcc2) +// bz, errRes = cdc.MarshalJSON(queryDelegatorParams) +// require.NoError(t, errRes) +// query = abci.RequestQuery{ +// Path: "/custom/staking/delegatorUnbondingDelegations", +// Data: bz, +// } +// res, err = queryDelegatorUnbondingDelegations(ctx, query, keeper) +// require.NoError(t, err) +// require.NotNil(t, res) +// require.NoError(t, cdc.UnmarshalJSON(res, &ubDels)) +// require.Equal(t, 0, len(ubDels)) +//} +// +//func TestQueryHistoricalInfo(t *testing.T) { +// cdc := codec.New() +// ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000) +// +// // Create Validators and Delegation +// val1 := types.NewValidator(addrVal1, pk1, types.Description{}) +// val2 := types.NewValidator(addrVal2, pk2, types.Description{}) +// vals := []types.Validator{val1, val2} +// keeper.SetValidator(ctx, val1) +// keeper.SetValidator(ctx, val2) +// +// header := abci.Header{ +// ChainID: "HelloChain", +// Height: 5, +// } +// hi := types.NewHistoricalInfo(header, vals) +// keeper.SetHistoricalInfo(ctx, 5, hi) +// +// queryHistoricalParams := types.NewQueryHistoricalInfoParams(4) +// bz, errRes := cdc.MarshalJSON(queryHistoricalParams) +// require.NoError(t, errRes) +// query := abci.RequestQuery{ +// Path: "/custom/staking/historicalInfo", +// Data: bz, +// } +// res, err := queryHistoricalInfo(ctx, query, keeper) +// require.Error(t, err, "Invalid query passed") +// require.Nil(t, res, "Invalid query returned non-nil result") +// +// queryHistoricalParams = types.NewQueryHistoricalInfoParams(5) +// bz, errRes = cdc.MarshalJSON(queryHistoricalParams) +// require.NoError(t, errRes) +// query.Data = bz +// res, err = queryHistoricalInfo(ctx, query, keeper) +// require.NoError(t, err, "Valid query passed") +// require.NotNil(t, res, "Valid query returned nil result") +// +// var recv types.HistoricalInfo +// require.NoError(t, cdc.UnmarshalJSON(res, &recv)) +// require.Equal(t, hi, recv, "HistoricalInfo query returned wrong result") +//} From 7f8d0e60476323ef755dac2db2cdcb0b71effaab Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Tue, 18 Feb 2020 19:10:53 +0100 Subject: [PATCH 05/90] commit end of day refactoring --- x/staking/keeper/old_querier_test.go | 436 +++++++++++++++++++++++++++ x/staking/keeper/querier_test.go | 17 +- 2 files changed, 445 insertions(+), 8 deletions(-) create mode 100644 x/staking/keeper/old_querier_test.go diff --git a/x/staking/keeper/old_querier_test.go b/x/staking/keeper/old_querier_test.go new file mode 100644 index 000000000000..3203755cc6ab --- /dev/null +++ b/x/staking/keeper/old_querier_test.go @@ -0,0 +1,436 @@ +package keeper + +import ( + "testing" + + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/stretchr/testify/require" +) + +var ( + addrAcc1, addrAcc2 = Addrs[0], Addrs[1] + addrVal1, addrVal2 = sdk.ValAddress(Addrs[0]), sdk.ValAddress(Addrs[1]) + pk1, pk2 = PKs[0], PKs[1] +) + +func TestQueryDelegation(t *testing.T) { + cdc := codec.New() + ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000) + params := keeper.GetParams(ctx) + + // Create Validators and Delegation + val1 := types.NewValidator(addrVal1, pk1, types.Description{}) + keeper.SetValidator(ctx, val1) + keeper.SetValidatorByPowerIndex(ctx, val1) + + val2 := types.NewValidator(addrVal2, pk2, types.Description{}) + keeper.SetValidator(ctx, val2) + keeper.SetValidatorByPowerIndex(ctx, val2) + + delTokens := sdk.TokensFromConsensusPower(20) + keeper.Delegate(ctx, addrAcc2, delTokens, sdk.Unbonded, val1, true) + + // apply TM updates + keeper.ApplyAndReturnValidatorSetUpdates(ctx) + + // Query Delegator bonded validators + queryParams := types.NewQueryDelegatorParams(addrAcc2) + bz, errRes := cdc.MarshalJSON(queryParams) + require.NoError(t, errRes) + + query := abci.RequestQuery{ + Path: "/custom/staking/delegatorValidators", + Data: bz, + } + + delValidators := keeper.GetDelegatorValidators(ctx, addrAcc2, params.MaxValidators) + + res, err := queryDelegatorValidators(ctx, query, keeper) + require.NoError(t, err) + + var validatorsResp []types.Validator + errRes = cdc.UnmarshalJSON(res, &validatorsResp) + require.NoError(t, errRes) + + require.Equal(t, len(delValidators), len(validatorsResp)) + require.ElementsMatch(t, delValidators, validatorsResp) + + // error unknown request + query.Data = bz[:len(bz)-1] + + _, err = queryDelegatorValidators(ctx, query, keeper) + require.Error(t, err) + + // Query bonded validator + queryBondParams := types.NewQueryBondsParams(addrAcc2, addrVal1) + bz, errRes = cdc.MarshalJSON(queryBondParams) + require.NoError(t, errRes) + + query = abci.RequestQuery{ + Path: "/custom/staking/delegatorValidator", + Data: bz, + } + + res, err = queryDelegatorValidator(ctx, query, keeper) + require.NoError(t, err) + + var validator types.Validator + errRes = cdc.UnmarshalJSON(res, &validator) + require.NoError(t, errRes) + + require.Equal(t, delValidators[0], validator) + + // error unknown request + query.Data = bz[:len(bz)-1] + + _, err = queryDelegatorValidator(ctx, query, keeper) + require.Error(t, err) + + // Query delegation + + query = abci.RequestQuery{ + Path: "/custom/staking/delegation", + Data: bz, + } + + delegation, found := keeper.GetDelegation(ctx, addrAcc2, addrVal1) + require.True(t, found) + + res, err = queryDelegation(ctx, query, keeper) + require.NoError(t, err) + + var delegationRes types.DelegationResponse + errRes = cdc.UnmarshalJSON(res, &delegationRes) + require.NoError(t, errRes) + + require.Equal(t, delegation.ValidatorAddress, delegationRes.ValidatorAddress) + require.Equal(t, delegation.DelegatorAddress, delegationRes.DelegatorAddress) + require.Equal(t, sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), delegationRes.Balance) + + // Query Delegator Delegations + query = abci.RequestQuery{ + Path: "/custom/staking/delegatorDelegations", + Data: bz, + } + + res, err = queryDelegatorDelegations(ctx, query, keeper) + require.NoError(t, err) + + var delegatorDelegations types.DelegationResponses + errRes = cdc.UnmarshalJSON(res, &delegatorDelegations) + require.NoError(t, errRes) + require.Len(t, delegatorDelegations, 1) + require.Equal(t, delegation.ValidatorAddress, delegatorDelegations[0].ValidatorAddress) + require.Equal(t, delegation.DelegatorAddress, delegatorDelegations[0].DelegatorAddress) + require.Equal(t, sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), delegatorDelegations[0].Balance) + + // error unknown request + query.Data = bz[:len(bz)-1] + + _, err = queryDelegation(ctx, query, keeper) + require.Error(t, err) + + // Query validator delegations + + bz, errRes = cdc.MarshalJSON(types.NewQueryValidatorParams(addrVal1)) + require.NoError(t, errRes) + + query = abci.RequestQuery{ + Path: "custom/staking/validatorDelegations", + Data: bz, + } + + res, err = queryValidatorDelegations(ctx, query, keeper) + require.NoError(t, err) + + var delegationsRes types.DelegationResponses + errRes = cdc.UnmarshalJSON(res, &delegationsRes) + require.NoError(t, errRes) + require.Len(t, delegatorDelegations, 1) + require.Equal(t, delegation.ValidatorAddress, delegationsRes[0].ValidatorAddress) + require.Equal(t, delegation.DelegatorAddress, delegationsRes[0].DelegatorAddress) + require.Equal(t, sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), delegationsRes[0].Balance) + + // Query unbonging delegation + unbondingTokens := sdk.TokensFromConsensusPower(10) + _, err = keeper.Undelegate(ctx, addrAcc2, val1.OperatorAddress, unbondingTokens.ToDec()) + require.NoError(t, err) + + queryBondParams = types.NewQueryBondsParams(addrAcc2, addrVal1) + bz, errRes = cdc.MarshalJSON(queryBondParams) + require.NoError(t, errRes) + + query = abci.RequestQuery{ + Path: "/custom/staking/unbondingDelegation", + Data: bz, + } + + unbond, found := keeper.GetUnbondingDelegation(ctx, addrAcc2, addrVal1) + require.True(t, found) + + res, err = queryUnbondingDelegation(ctx, query, keeper) + require.NoError(t, err) + + var unbondRes types.UnbondingDelegation + errRes = cdc.UnmarshalJSON(res, &unbondRes) + require.NoError(t, errRes) + + require.Equal(t, unbond, unbondRes) + + // error unknown request + query.Data = bz[:len(bz)-1] + + _, err = queryUnbondingDelegation(ctx, query, keeper) + require.Error(t, err) + + // Query Delegator Delegations + + query = abci.RequestQuery{ + Path: "/custom/staking/delegatorUnbondingDelegations", + Data: bz, + } + + res, err = queryDelegatorUnbondingDelegations(ctx, query, keeper) + require.NoError(t, err) + + var delegatorUbds []types.UnbondingDelegation + errRes = cdc.UnmarshalJSON(res, &delegatorUbds) + require.NoError(t, errRes) + require.Equal(t, unbond, delegatorUbds[0]) + + // error unknown request + query.Data = bz[:len(bz)-1] + + _, err = queryDelegatorUnbondingDelegations(ctx, query, keeper) + require.Error(t, err) + + // Query redelegation + redelegationTokens := sdk.TokensFromConsensusPower(10) + _, err = keeper.BeginRedelegation(ctx, addrAcc2, val1.OperatorAddress, + val2.OperatorAddress, redelegationTokens.ToDec()) + require.NoError(t, err) + redel, found := keeper.GetRedelegation(ctx, addrAcc2, val1.OperatorAddress, val2.OperatorAddress) + require.True(t, found) + + bz, errRes = cdc.MarshalJSON(types.NewQueryRedelegationParams(addrAcc2, val1.OperatorAddress, val2.OperatorAddress)) + require.NoError(t, errRes) + + query = abci.RequestQuery{ + Path: "/custom/staking/redelegations", + Data: bz, + } + + res, err = queryRedelegations(ctx, query, keeper) + require.NoError(t, err) + + var redelRes types.RedelegationResponses + errRes = cdc.UnmarshalJSON(res, &redelRes) + require.NoError(t, errRes) + require.Len(t, redelRes, 1) + require.Equal(t, redel.DelegatorAddress, redelRes[0].DelegatorAddress) + require.Equal(t, redel.ValidatorSrcAddress, redelRes[0].ValidatorSrcAddress) + require.Equal(t, redel.ValidatorDstAddress, redelRes[0].ValidatorDstAddress) + require.Len(t, redel.Entries, len(redelRes[0].Entries)) +} + +func TestQueryRedelegations(t *testing.T) { + cdc := codec.New() + ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000) + + // Create Validators and Delegation + val1 := types.NewValidator(addrVal1, pk1, types.Description{}) + val2 := types.NewValidator(addrVal2, pk2, types.Description{}) + keeper.SetValidator(ctx, val1) + keeper.SetValidator(ctx, val2) + + delAmount := sdk.TokensFromConsensusPower(100) + keeper.Delegate(ctx, addrAcc2, delAmount, sdk.Unbonded, val1, true) + _ = keeper.ApplyAndReturnValidatorSetUpdates(ctx) + + rdAmount := sdk.TokensFromConsensusPower(20) + keeper.BeginRedelegation(ctx, addrAcc2, val1.GetOperator(), val2.GetOperator(), rdAmount.ToDec()) + keeper.ApplyAndReturnValidatorSetUpdates(ctx) + + redel, found := keeper.GetRedelegation(ctx, addrAcc2, val1.OperatorAddress, val2.OperatorAddress) + require.True(t, found) + + // delegator redelegations + queryDelegatorParams := types.NewQueryDelegatorParams(addrAcc2) + bz, errRes := cdc.MarshalJSON(queryDelegatorParams) + require.NoError(t, errRes) + + query := abci.RequestQuery{ + Path: "/custom/staking/redelegations", + Data: bz, + } + + res, err := queryRedelegations(ctx, query, keeper) + require.NoError(t, err) + + var redelRes types.RedelegationResponses + errRes = cdc.UnmarshalJSON(res, &redelRes) + require.NoError(t, errRes) + require.Len(t, redelRes, 1) + require.Equal(t, redel.DelegatorAddress, redelRes[0].DelegatorAddress) + require.Equal(t, redel.ValidatorSrcAddress, redelRes[0].ValidatorSrcAddress) + require.Equal(t, redel.ValidatorDstAddress, redelRes[0].ValidatorDstAddress) + require.Len(t, redel.Entries, len(redelRes[0].Entries)) + + // validator redelegations + queryValidatorParams := types.NewQueryValidatorParams(val1.GetOperator()) + bz, errRes = cdc.MarshalJSON(queryValidatorParams) + require.NoError(t, errRes) + + query = abci.RequestQuery{ + Path: "/custom/staking/redelegations", + Data: bz, + } + + res, err = queryRedelegations(ctx, query, keeper) + require.NoError(t, err) + + errRes = cdc.UnmarshalJSON(res, &redelRes) + require.NoError(t, errRes) + require.Len(t, redelRes, 1) + require.Equal(t, redel.DelegatorAddress, redelRes[0].DelegatorAddress) + require.Equal(t, redel.ValidatorSrcAddress, redelRes[0].ValidatorSrcAddress) + require.Equal(t, redel.ValidatorDstAddress, redelRes[0].ValidatorDstAddress) + require.Len(t, redel.Entries, len(redelRes[0].Entries)) +} + +func TestQueryUnbondingDelegation(t *testing.T) { + cdc := codec.New() + ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000) + + // Create Validators and Delegation + val1 := types.NewValidator(addrVal1, pk1, types.Description{}) + keeper.SetValidator(ctx, val1) + + // delegate + delAmount := sdk.TokensFromConsensusPower(100) + _, err := keeper.Delegate(ctx, addrAcc1, delAmount, sdk.Unbonded, val1, true) + require.NoError(t, err) + _ = keeper.ApplyAndReturnValidatorSetUpdates(ctx) + + // undelegate + undelAmount := sdk.TokensFromConsensusPower(20) + _, err = keeper.Undelegate(ctx, addrAcc1, val1.GetOperator(), undelAmount.ToDec()) + require.NoError(t, err) + keeper.ApplyAndReturnValidatorSetUpdates(ctx) + + _, found := keeper.GetUnbondingDelegation(ctx, addrAcc1, val1.OperatorAddress) + require.True(t, found) + + // + // found: query unbonding delegation by delegator and validator + // + queryValidatorParams := types.NewQueryBondsParams(addrAcc1, val1.GetOperator()) + bz, errRes := cdc.MarshalJSON(queryValidatorParams) + require.NoError(t, errRes) + query := abci.RequestQuery{ + Path: "/custom/staking/unbondingDelegation", + Data: bz, + } + res, err := queryUnbondingDelegation(ctx, query, keeper) + require.NoError(t, err) + require.NotNil(t, res) + var ubDel types.UnbondingDelegation + require.NoError(t, cdc.UnmarshalJSON(res, &ubDel)) + require.Equal(t, addrAcc1, ubDel.DelegatorAddress) + require.Equal(t, val1.OperatorAddress, ubDel.ValidatorAddress) + require.Equal(t, 1, len(ubDel.Entries)) + + // + // not found: query unbonding delegation by delegator and validator + // + queryValidatorParams = types.NewQueryBondsParams(addrAcc2, val1.GetOperator()) + bz, errRes = cdc.MarshalJSON(queryValidatorParams) + require.NoError(t, errRes) + query = abci.RequestQuery{ + Path: "/custom/staking/unbondingDelegation", + Data: bz, + } + _, err = queryUnbondingDelegation(ctx, query, keeper) + require.Error(t, err) + + // + // found: query unbonding delegation by delegator and validator + // + queryDelegatorParams := types.NewQueryDelegatorParams(addrAcc1) + bz, errRes = cdc.MarshalJSON(queryDelegatorParams) + require.NoError(t, errRes) + query = abci.RequestQuery{ + Path: "/custom/staking/delegatorUnbondingDelegations", + Data: bz, + } + res, err = queryDelegatorUnbondingDelegations(ctx, query, keeper) + require.NoError(t, err) + require.NotNil(t, res) + var ubDels []types.UnbondingDelegation + require.NoError(t, cdc.UnmarshalJSON(res, &ubDels)) + require.Equal(t, 1, len(ubDels)) + require.Equal(t, addrAcc1, ubDels[0].DelegatorAddress) + require.Equal(t, val1.OperatorAddress, ubDels[0].ValidatorAddress) + + // + // not found: query unbonding delegation by delegator and validator + // + queryDelegatorParams = types.NewQueryDelegatorParams(addrAcc2) + bz, errRes = cdc.MarshalJSON(queryDelegatorParams) + require.NoError(t, errRes) + query = abci.RequestQuery{ + Path: "/custom/staking/delegatorUnbondingDelegations", + Data: bz, + } + res, err = queryDelegatorUnbondingDelegations(ctx, query, keeper) + require.NoError(t, err) + require.NotNil(t, res) + require.NoError(t, cdc.UnmarshalJSON(res, &ubDels)) + require.Equal(t, 0, len(ubDels)) +} + +func TestQueryHistoricalInfo(t *testing.T) { + cdc := codec.New() + ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000) + + // Create Validators and Delegation + val1 := types.NewValidator(addrVal1, pk1, types.Description{}) + val2 := types.NewValidator(addrVal2, pk2, types.Description{}) + vals := []types.Validator{val1, val2} + keeper.SetValidator(ctx, val1) + keeper.SetValidator(ctx, val2) + + header := abci.Header{ + ChainID: "HelloChain", + Height: 5, + } + hi := types.NewHistoricalInfo(header, vals) + keeper.SetHistoricalInfo(ctx, 5, hi) + + queryHistoricalParams := types.NewQueryHistoricalInfoParams(4) + bz, errRes := cdc.MarshalJSON(queryHistoricalParams) + require.NoError(t, errRes) + query := abci.RequestQuery{ + Path: "/custom/staking/historicalInfo", + Data: bz, + } + res, err := queryHistoricalInfo(ctx, query, keeper) + require.Error(t, err, "Invalid query passed") + require.Nil(t, res, "Invalid query returned non-nil result") + + queryHistoricalParams = types.NewQueryHistoricalInfoParams(5) + bz, errRes = cdc.MarshalJSON(queryHistoricalParams) + require.NoError(t, errRes) + query.Data = bz + res, err = queryHistoricalInfo(ctx, query, keeper) + require.NoError(t, err, "Valid query passed") + require.NotNil(t, res, "Valid query returned nil result") + + var recv types.HistoricalInfo + require.NoError(t, cdc.UnmarshalJSON(res, &recv)) + require.Equal(t, hi, recv, "HistoricalInfo query returned wrong result") +} diff --git a/x/staking/keeper/querier_test.go b/x/staking/keeper/querier_test.go index 202290762ba5..50bb8b34d03f 100644 --- a/x/staking/keeper/querier_test.go +++ b/x/staking/keeper/querier_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/stretchr/testify/require" + abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/codec" @@ -14,22 +15,19 @@ import ( "github.com/cosmos/cosmos-sdk/x/staking/types" ) -var ( - addrAcc1, addrAcc2 = Addrs[0], Addrs[1] - addrVal1, addrVal2 = sdk.ValAddress(Addrs[0]), sdk.ValAddress(Addrs[1]) - pk1, pk2 = PKs[0], PKs[1] -) - func TestNewQuerier(t *testing.T) { cdc := codec.New() app := simapp.Setup(false) ctx := app.BaseApp.NewContext(false, abci.Header{}) + addrs := simapp.AddTestAddrs(app, ctx, 500, sdk.NewInt(10000)) + _, addrAcc2 := addrs[0], addrs[1] + addrVal1, _ := sdk.ValAddress(addrs[0]), sdk.ValAddress(addrs[1]) // Create Validators amts := []sdk.Int{sdk.NewInt(9), sdk.NewInt(8)} var validators [2]types.Validator for i, amt := range amts { - validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) + validators[i] = types.NewValidator(sdk.ValAddress(addrs[i]), PKs[i], types.Description{}) validators[i], _ = validators[i].AddTokensFromDel(amt) app.StakingKeeper.SetValidator(ctx, validators[i]) app.StakingKeeper.SetValidatorByPowerIndex(ctx, validators[i]) @@ -143,12 +141,15 @@ func TestQueryValidators(t *testing.T) { params := app.StakingKeeper.GetParams(ctx) querier := staking.NewQuerier(app.StakingKeeper) + addrs := simapp.AddTestAddrs(app, ctx, 500, sdk.NewInt(10000)) + addrVal1, _ := sdk.ValAddress(addrs[0]), sdk.ValAddress(addrs[1]) + // Create Validators amts := []sdk.Int{sdk.NewInt(9), sdk.NewInt(8), sdk.NewInt(7)} status := []sdk.BondStatus{sdk.Bonded, sdk.Unbonded, sdk.Unbonding} var validators [3]types.Validator for i, amt := range amts { - validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) + validators[i] = types.NewValidator(sdk.ValAddress(addrs[i]), PKs[i], types.Description{}) validators[i], _ = validators[i].AddTokensFromDel(amt) validators[i] = validators[i].UpdateStatus(status[i]) } From cdcbecb2f4da1eb142c6762444830336881b6faf Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Wed, 19 Feb 2020 10:53:43 +0100 Subject: [PATCH 06/90] rename and temp commit --- .../{test_common.go => old_test_common.go} | 0 x/staking/keeper/querier_test.go | 421 +++++++++--------- ...n_refactor_test.go => test_common_test.go} | 3 +- 3 files changed, 214 insertions(+), 210 deletions(-) rename x/staking/keeper/{test_common.go => old_test_common.go} (100%) rename x/staking/keeper/{common_refactor_test.go => test_common_test.go} (99%) diff --git a/x/staking/keeper/test_common.go b/x/staking/keeper/old_test_common.go similarity index 100% rename from x/staking/keeper/test_common.go rename to x/staking/keeper/old_test_common.go diff --git a/x/staking/keeper/querier_test.go b/x/staking/keeper/querier_test.go index 50bb8b34d03f..4f348a429a77 100644 --- a/x/staking/keeper/querier_test.go +++ b/x/staking/keeper/querier_test.go @@ -202,215 +202,218 @@ func TestQueryValidators(t *testing.T) { require.Equal(t, queriedValidators[0], validator) } -//func TestQueryDelegation(t *testing.T) { -// cdc := codec.New() -// app := simapp.Setup(false) -// ctx := app.BaseApp.NewContext(false, abci.Header{}) -// params := app.StakingKeeper.GetParams(ctx) -// querier := staking.NewQuerier(app.StakingKeeper) -// -// // Create Validators and Delegation -// val1 := types.NewValidator(addrVal1, pk1, types.Description{}) -// app.StakingKeeper.SetValidator(ctx, val1) -// app.StakingKeeper.SetValidatorByPowerIndex(ctx, val1) -// -// val2 := types.NewValidator(addrVal2, pk2, types.Description{}) -// app.StakingKeeper.SetValidator(ctx, val2) -// app.StakingKeeper.SetValidatorByPowerIndex(ctx, val2) -// -// delTokens := sdk.TokensFromConsensusPower(20) -// app.StakingKeeper.Delegate(ctx, addrAcc2, delTokens, sdk.Unbonded, val1, true) -// -// // apply TM updates -// app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) -// -// // Query Delegator bonded validators -// queryParams := types.NewQueryDelegatorParams(addrAcc2) -// bz, errRes := cdc.MarshalJSON(queryParams) -// require.NoError(t, errRes) -// -// query := abci.RequestQuery{ -// Path: "/custom/staking/delegatorValidators", -// Data: bz, -// } -// -// delValidators := app.StakingKeeper.GetDelegatorValidators(ctx, addrAcc2, params.MaxValidators) -// -// res, err := querier(ctx, []string{types.QueryDelegatorValidators}, query) -// require.NoError(t, err) -// -// var validatorsResp []types.Validator -// errRes = cdc.UnmarshalJSON(res, &validatorsResp) -// require.NoError(t, errRes) -// -// require.Equal(t, len(delValidators), len(validatorsResp)) -// require.ElementsMatch(t, delValidators, validatorsResp) -// -// // error unknown request -// query.Data = bz[:len(bz)-1] -// -// res, err = querier(ctx, []string{types.QueryDelegatorValidators}, query) -// require.Error(t, err) -// -// // Query bonded validator -// queryBondParams := types.NewQueryBondsParams(addrAcc2, addrVal1) -// bz, errRes = cdc.MarshalJSON(queryBondParams) -// require.NoError(t, errRes) -// -// query = abci.RequestQuery{ -// Path: "/custom/staking/delegatorValidator", -// Data: bz, -// } -// -// res, err = querier(ctx, []string{types.QueryDelegatorValidator}, query) -// require.NoError(t, err) -// -// var validator types.Validator -// errRes = cdc.UnmarshalJSON(res, &validator) -// require.NoError(t, errRes) -// -// require.Equal(t, delValidators[0], validator) -// -// // error unknown request -// query.Data = bz[:len(bz)-1] -// -// res, err = querier(ctx, []string{types.QueryDelegatorValidator}, query) -// require.Error(t, err) -// -// // Query delegation -// -// query = abci.RequestQuery{ -// Path: "/custom/staking/delegation", -// Data: bz, -// } -// -// delegation, found := app.StakingKeeper.GetDelegation(ctx, addrAcc2, addrVal1) -// require.True(t, found) -// -// res, err = querier(ctx, []string{types.QueryDelegation}, query) -// require.NoError(t, err) -// -// var delegationRes types.DelegationResponse -// errRes = cdc.UnmarshalJSON(res, &delegationRes) -// require.NoError(t, errRes) -// -// require.Equal(t, delegation.ValidatorAddress, delegationRes.ValidatorAddress) -// require.Equal(t, delegation.DelegatorAddress, delegationRes.DelegatorAddress) -// require.Equal(t, sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), delegationRes.Balance) -// -// // Query Delegator Delegations -// query = abci.RequestQuery{ -// Path: "/custom/staking/delegatorDelegations", -// Data: bz, -// } -// -// res, err = querier(ctx, []string{types.QueryDelegatorDelegations}, query) -// require.NoError(t, err) -// -// var delegatorDelegations types.DelegationResponses -// errRes = cdc.UnmarshalJSON(res, &delegatorDelegations) -// require.NoError(t, errRes) -// require.Len(t, delegatorDelegations, 1) -// require.Equal(t, delegation.ValidatorAddress, delegatorDelegations[0].ValidatorAddress) -// require.Equal(t, delegation.DelegatorAddress, delegatorDelegations[0].DelegatorAddress) -// require.Equal(t, sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), delegatorDelegations[0].Balance) -// -// // error unknown request -// query.Data = bz[:len(bz)-1] -// -// res, err = querier(ctx, []string{types.QueryDelegation}, query) -// require.Error(t, err) -// -// // Query validator delegations -// -// bz, errRes = cdc.MarshalJSON(types.NewQueryValidatorParams(addrVal1)) -// require.NoError(t, errRes) -// -// query = abci.RequestQuery{ -// Path: "custom/staking/validatorDelegations", -// Data: bz, -// } -// -// res, err = querier(ctx, []string{types.QueryValidatorDelegations}, query) -// require.NoError(t, err) -// -// var delegationsRes types.DelegationResponses -// errRes = cdc.UnmarshalJSON(res, &delegationsRes) -// require.NoError(t, errRes) -// require.Len(t, delegatorDelegations, 1) -// require.Equal(t, delegation.ValidatorAddress, delegationsRes[0].ValidatorAddress) -// require.Equal(t, delegation.DelegatorAddress, delegationsRes[0].DelegatorAddress) -// require.Equal(t, sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), delegationsRes[0].Balance) -// -// // Query unbonging delegation -// unbondingTokens := sdk.TokensFromConsensusPower(10) -// _, err = app.StakingKeeper.Undelegate(ctx, addrAcc2, val1.OperatorAddress, unbondingTokens.ToDec()) -// require.NoError(t, err) -// -// queryBondParams = types.NewQueryBondsParams(addrAcc2, addrVal1) -// bz, errRes = cdc.MarshalJSON(queryBondParams) -// require.NoError(t, errRes) -// -// query = abci.RequestQuery{ -// Path: "/custom/staking/unbondingDelegation", -// Data: bz, -// } -// -// unbond, found := app.StakingKeeper.GetUnbondingDelegation(ctx, addrAcc2, addrVal1) -// require.True(t, found) -// -// res, err = querier(ctx, []string{types.QueryUnbondingDelegation}, query) -// require.NoError(t, err) -// -// var unbondRes types.UnbondingDelegation -// errRes = cdc.UnmarshalJSON(res, &unbondRes) -// require.NoError(t, errRes) -// -// require.Equal(t, unbond, unbondRes) -// -// // error unknown request -// query.Data = bz[:len(bz)-1] -// -// _, err = querier(ctx, []string{types.QueryUnbondingDelegation}, query) -// require.Error(t, err) -// -// // Query Delegator Delegations -// -// query = abci.RequestQuery{ -// Path: "/custom/staking/delegatorUnbondingDelegations", -// Data: bz, -// } -// -// res, err = querier(ctx, []string{types.QueryDelegatorUnbondingDelegations}, query) -// require.NoError(t, err) -// -// var delegatorUbds []types.UnbondingDelegation -// errRes = cdc.UnmarshalJSON(res, &delegatorUbds) -// require.NoError(t, errRes) -// require.Equal(t, unbond, delegatorUbds[0]) -// -// // error unknown request -// query.Data = bz[:len(bz)-1] -// -// _, err = querier(ctx, []string{types.QueryDelegatorUnbondingDelegations}, query) -// require.Error(t, err) -// -// // Query redelegation -// redelegationTokens := sdk.TokensFromConsensusPower(10) -// _, err = app.StakingKeeper.BeginRedelegation(ctx, addrAcc2, val1.OperatorAddress, -// val2.OperatorAddress, redelegationTokens.ToDec()) -// require.NoError(t, err) -// redel, found := app.StakingKeeper.GetRedelegation(ctx, addrAcc2, val1.OperatorAddress, val2.OperatorAddress) -// require.True(t, found) -// -// bz, errRes = cdc.MarshalJSON(types.NewQueryRedelegationParams(addrAcc2, val1.OperatorAddress, val2.OperatorAddress)) -// require.NoError(t, errRes) -// -// query = abci.RequestQuery{ -// Path: "/custom/staking/redelegations", -// Data: bz, -// } -// +func TestQueryDelegation(t *testing.T) { + cdc := codec.New() + app := simapp.Setup(false) + ctx := app.BaseApp.NewContext(false, abci.Header{}) + params := app.StakingKeeper.GetParams(ctx) + querier := staking.NewQuerier(app.StakingKeeper) + + addrs := simapp.AddTestAddrs(app, ctx, 500, sdk.NewInt(10000)) + + + // Create Validators and Delegation + val1 := types.NewValidator(addrVal1, pk1, types.Description{}) + app.StakingKeeper.SetValidator(ctx, val1) + app.StakingKeeper.SetValidatorByPowerIndex(ctx, val1) + + val2 := types.NewValidator(addrVal2, pk2, types.Description{}) + app.StakingKeeper.SetValidator(ctx, val2) + app.StakingKeeper.SetValidatorByPowerIndex(ctx, val2) + + delTokens := sdk.TokensFromConsensusPower(20) + app.StakingKeeper.Delegate(ctx, addrAcc2, delTokens, sdk.Unbonded, val1, true) + + // apply TM updates + app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + + // Query Delegator bonded validators + queryParams := types.NewQueryDelegatorParams(addrAcc2) + bz, errRes := cdc.MarshalJSON(queryParams) + require.NoError(t, errRes) + + query := abci.RequestQuery{ + Path: "/custom/staking/delegatorValidators", + Data: bz, + } + + delValidators := app.StakingKeeper.GetDelegatorValidators(ctx, addrAcc2, params.MaxValidators) + + res, err := querier(ctx, []string{types.QueryDelegatorValidators}, query) + require.NoError(t, err) + + var validatorsResp []types.Validator + errRes = cdc.UnmarshalJSON(res, &validatorsResp) + require.NoError(t, errRes) + + require.Equal(t, len(delValidators), len(validatorsResp)) + require.ElementsMatch(t, delValidators, validatorsResp) + + // error unknown request + query.Data = bz[:len(bz)-1] + + res, err = querier(ctx, []string{types.QueryDelegatorValidators}, query) + require.Error(t, err) + + // Query bonded validator + queryBondParams := types.NewQueryBondsParams(addrAcc2, addrVal1) + bz, errRes = cdc.MarshalJSON(queryBondParams) + require.NoError(t, errRes) + + query = abci.RequestQuery{ + Path: "/custom/staking/delegatorValidator", + Data: bz, + } + + res, err = querier(ctx, []string{types.QueryDelegatorValidator}, query) + require.NoError(t, err) + + var validator types.Validator + errRes = cdc.UnmarshalJSON(res, &validator) + require.NoError(t, errRes) + + require.Equal(t, delValidators[0], validator) + + // error unknown request + query.Data = bz[:len(bz)-1] + + res, err = querier(ctx, []string{types.QueryDelegatorValidator}, query) + require.Error(t, err) + + // Query delegation + + query = abci.RequestQuery{ + Path: "/custom/staking/delegation", + Data: bz, + } + + delegation, found := app.StakingKeeper.GetDelegation(ctx, addrAcc2, addrVal1) + require.True(t, found) + + res, err = querier(ctx, []string{types.QueryDelegation}, query) + require.NoError(t, err) + + var delegationRes types.DelegationResponse + errRes = cdc.UnmarshalJSON(res, &delegationRes) + require.NoError(t, errRes) + + require.Equal(t, delegation.ValidatorAddress, delegationRes.ValidatorAddress) + require.Equal(t, delegation.DelegatorAddress, delegationRes.DelegatorAddress) + require.Equal(t, sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), delegationRes.Balance) + + // Query Delegator Delegations + query = abci.RequestQuery{ + Path: "/custom/staking/delegatorDelegations", + Data: bz, + } + + res, err = querier(ctx, []string{types.QueryDelegatorDelegations}, query) + require.NoError(t, err) + + var delegatorDelegations types.DelegationResponses + errRes = cdc.UnmarshalJSON(res, &delegatorDelegations) + require.NoError(t, errRes) + require.Len(t, delegatorDelegations, 1) + require.Equal(t, delegation.ValidatorAddress, delegatorDelegations[0].ValidatorAddress) + require.Equal(t, delegation.DelegatorAddress, delegatorDelegations[0].DelegatorAddress) + require.Equal(t, sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), delegatorDelegations[0].Balance) + + // error unknown request + query.Data = bz[:len(bz)-1] + + res, err = querier(ctx, []string{types.QueryDelegation}, query) + require.Error(t, err) + + // Query validator delegations + + bz, errRes = cdc.MarshalJSON(types.NewQueryValidatorParams(addrVal1)) + require.NoError(t, errRes) + + query = abci.RequestQuery{ + Path: "custom/staking/validatorDelegations", + Data: bz, + } + + res, err = querier(ctx, []string{types.QueryValidatorDelegations}, query) + require.NoError(t, err) + + var delegationsRes types.DelegationResponses + errRes = cdc.UnmarshalJSON(res, &delegationsRes) + require.NoError(t, errRes) + require.Len(t, delegatorDelegations, 1) + require.Equal(t, delegation.ValidatorAddress, delegationsRes[0].ValidatorAddress) + require.Equal(t, delegation.DelegatorAddress, delegationsRes[0].DelegatorAddress) + require.Equal(t, sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), delegationsRes[0].Balance) + + // Query unbonging delegation + unbondingTokens := sdk.TokensFromConsensusPower(10) + _, err = app.StakingKeeper.Undelegate(ctx, addrAcc2, val1.OperatorAddress, unbondingTokens.ToDec()) + require.NoError(t, err) + + queryBondParams = types.NewQueryBondsParams(addrAcc2, addrVal1) + bz, errRes = cdc.MarshalJSON(queryBondParams) + require.NoError(t, errRes) + + query = abci.RequestQuery{ + Path: "/custom/staking/unbondingDelegation", + Data: bz, + } + + unbond, found := app.StakingKeeper.GetUnbondingDelegation(ctx, addrAcc2, addrVal1) + require.True(t, found) + + res, err = querier(ctx, []string{types.QueryUnbondingDelegation}, query) + require.NoError(t, err) + + var unbondRes types.UnbondingDelegation + errRes = cdc.UnmarshalJSON(res, &unbondRes) + require.NoError(t, errRes) + + require.Equal(t, unbond, unbondRes) + + // error unknown request + query.Data = bz[:len(bz)-1] + + _, err = querier(ctx, []string{types.QueryUnbondingDelegation}, query) + require.Error(t, err) + + // Query Delegator Delegations + + query = abci.RequestQuery{ + Path: "/custom/staking/delegatorUnbondingDelegations", + Data: bz, + } + + res, err = querier(ctx, []string{types.QueryDelegatorUnbondingDelegations}, query) + require.NoError(t, err) + + var delegatorUbds []types.UnbondingDelegation + errRes = cdc.UnmarshalJSON(res, &delegatorUbds) + require.NoError(t, errRes) + require.Equal(t, unbond, delegatorUbds[0]) + + // error unknown request + query.Data = bz[:len(bz)-1] + + _, err = querier(ctx, []string{types.QueryDelegatorUnbondingDelegations}, query) + require.Error(t, err) + + // Query redelegation + redelegationTokens := sdk.TokensFromConsensusPower(10) + _, err = app.StakingKeeper.BeginRedelegation(ctx, addrAcc2, val1.OperatorAddress, + val2.OperatorAddress, redelegationTokens.ToDec()) + require.NoError(t, err) + redel, found := app.StakingKeeper.GetRedelegation(ctx, addrAcc2, val1.OperatorAddress, val2.OperatorAddress) + require.True(t, found) + + bz, errRes = cdc.MarshalJSON(types.NewQueryRedelegationParams(addrAcc2, val1.OperatorAddress, val2.OperatorAddress)) + require.NoError(t, errRes) + + query = abci.RequestQuery{ + Path: "/custom/staking/redelegations", + Data: bz, + } + // res, err = querier(ctx, []string{types.QueryRedelegations}, query) // require.NoError(t, err) // diff --git a/x/staking/keeper/common_refactor_test.go b/x/staking/keeper/test_common_test.go similarity index 99% rename from x/staking/keeper/common_refactor_test.go rename to x/staking/keeper/test_common_test.go index 8b43af1739f2..936c028148d2 100644 --- a/x/staking/keeper/common_refactor_test.go +++ b/x/staking/keeper/test_common_test.go @@ -59,6 +59,7 @@ func createTestPubKeys(numPubKeys int) []crypto.PubKey { publicKeys = append(publicKeys, NewPubKey(buffer.String())) buffer.Reset() } + return publicKeys } @@ -75,11 +76,11 @@ func NewPubKey(pk string) (res crypto.PubKey) { // for incode address generation func CreateTestAddr(addr string, bech string) sdk.AccAddress { - res, err := sdk.AccAddressFromHex(addr) if err != nil { panic(err) } + bechexpected := res.String() if bech != bechexpected { panic("Bech encoding doesn't match reference") From 0d24d2b2cbc6c8e7183b7152271c1705739091b8 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Thu, 20 Feb 2020 16:09:25 +0100 Subject: [PATCH 07/90] fix test query validators --- simapp/test_helpers.go | 30 +++++++++++++ x/staking/keeper/old_test_common.go | 3 +- x/staking/keeper/querier_test.go | 68 ++++++++++++++++------------- 3 files changed, 69 insertions(+), 32 deletions(-) diff --git a/simapp/test_helpers.go b/simapp/test_helpers.go index abc87ed635cc..31b4db3b80cd 100644 --- a/simapp/test_helpers.go +++ b/simapp/test_helpers.go @@ -1,6 +1,9 @@ package simapp import ( + "bytes" + "encoding/hex" + "strconv" "testing" "github.com/stretchr/testify/require" @@ -187,3 +190,30 @@ func incrementAllSequenceNumbers(initSeqNums []uint64) { initSeqNums[i]++ } } + +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 +} diff --git a/x/staking/keeper/old_test_common.go b/x/staking/keeper/old_test_common.go index 005cfbfb1ffa..8e4cd6b9aac7 100644 --- a/x/staking/keeper/old_test_common.go +++ b/x/staking/keeper/old_test_common.go @@ -83,9 +83,10 @@ func CreateTestInput(t *testing.T, isCheckTx bool, initPower int64) (sdk.Context keyAcc := sdk.NewKVStoreKey(auth.StoreKey) bankKey := sdk.NewKVStoreKey(bank.StoreKey) keyParams := sdk.NewKVStoreKey(params.StoreKey) - tkeyParams := sdk.NewTransientStoreKey(params.TStoreKey) keySupply := sdk.NewKVStoreKey(supply.StoreKey) + tkeyParams := sdk.NewTransientStoreKey(params.TStoreKey) + db := dbm.NewMemDB() ms := store.NewCommitMultiStore(db) ms.MountStoreWithDB(keyStaking, sdk.StoreTypeIAVL, db) diff --git a/x/staking/keeper/querier_test.go b/x/staking/keeper/querier_test.go index 4f348a429a77..333b3b28e655 100644 --- a/x/staking/keeper/querier_test.go +++ b/x/staking/keeper/querier_test.go @@ -141,8 +141,7 @@ func TestQueryValidators(t *testing.T) { params := app.StakingKeeper.GetParams(ctx) querier := staking.NewQuerier(app.StakingKeeper) - addrs := simapp.AddTestAddrs(app, ctx, 500, sdk.NewInt(10000)) - addrVal1, _ := sdk.ValAddress(addrs[0]), sdk.ValAddress(addrs[1]) + addrs := simapp.AddTestAddrs(app, ctx, 500, sdk.TokensFromConsensusPower(10000)) // Create Validators amts := []sdk.Int{sdk.NewInt(9), sdk.NewInt(8), sdk.NewInt(7)} @@ -160,6 +159,7 @@ func TestQueryValidators(t *testing.T) { // Query Validators queriedValidators := app.StakingKeeper.GetValidators(ctx, params.MaxValidators) + require.Len(t, queriedValidators, 3) for i, s := range status { queryValsParams := types.NewQueryValidatorsParams(1, int(params.MaxValidators), s.String()) @@ -180,26 +180,27 @@ func TestQueryValidators(t *testing.T) { require.Equal(t, 1, len(validatorsResp)) require.ElementsMatch(t, validators[i].OperatorAddress, validatorsResp[0].OperatorAddress) - } // Query each validator - queryParams := types.NewQueryValidatorParams(addrVal1) - bz, err := cdc.MarshalJSON(queryParams) - require.NoError(t, err) + for _, validator := range validators { + queryParams := types.NewQueryValidatorParams(validator.OperatorAddress) + bz, err := cdc.MarshalJSON(queryParams) + require.NoError(t, err) - query := abci.RequestQuery{ - Path: "/custom/staking/validator", - Data: bz, - } - res, err := querier(ctx, []string{types.QueryValidator}, query) - require.NoError(t, err) + query := abci.RequestQuery{ + Path: "/custom/staking/validator", + Data: bz, + } + res, err := querier(ctx, []string{types.QueryValidator}, query) + require.NoError(t, err) - var validator types.Validator - err = cdc.UnmarshalJSON(res, &validator) - require.NoError(t, err) + var queriedValidator types.Validator + err = cdc.UnmarshalJSON(res, &queriedValidator) + require.NoError(t, err) - require.Equal(t, queriedValidators[0], validator) + require.Equal(t, validator, queriedValidator) + } } func TestQueryDelegation(t *testing.T) { @@ -209,8 +210,12 @@ func TestQueryDelegation(t *testing.T) { params := app.StakingKeeper.GetParams(ctx) querier := staking.NewQuerier(app.StakingKeeper) - addrs := simapp.AddTestAddrs(app, ctx, 500, sdk.NewInt(10000)) + addrs := simapp.AddTestAddrs(app, ctx, 500, sdk.TokensFromConsensusPower(10000)) + addrAcc1, addrAcc2 := addrs[0], addrs[1] + addrVal1, addrVal2 := sdk.ValAddress(addrAcc1), sdk.ValAddress(addrAcc2) + pubKeys := simapp.CreateTestPubKeys(2) + pk1, pk2 := pubKeys[0], pubKeys[1] // Create Validators and Delegation val1 := types.NewValidator(addrVal1, pk1, types.Description{}) @@ -222,7 +227,8 @@ func TestQueryDelegation(t *testing.T) { app.StakingKeeper.SetValidatorByPowerIndex(ctx, val2) delTokens := sdk.TokensFromConsensusPower(20) - app.StakingKeeper.Delegate(ctx, addrAcc2, delTokens, sdk.Unbonded, val1, true) + _, err := app.StakingKeeper.Delegate(ctx, addrAcc2, delTokens, sdk.Unbonded, val1, true) + require.NoError(t, err) // apply TM updates app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) @@ -414,19 +420,19 @@ func TestQueryDelegation(t *testing.T) { Data: bz, } -// res, err = querier(ctx, []string{types.QueryRedelegations}, query) -// require.NoError(t, err) -// -// var redelRes types.RedelegationResponses -// errRes = cdc.UnmarshalJSON(res, &redelRes) -// require.NoError(t, errRes) -// require.Len(t, redelRes, 1) -// require.Equal(t, redel.DelegatorAddress, redelRes[0].DelegatorAddress) -// require.Equal(t, redel.ValidatorSrcAddress, redelRes[0].ValidatorSrcAddress) -// require.Equal(t, redel.ValidatorDstAddress, redelRes[0].ValidatorDstAddress) -// require.Len(t, redel.Entries, len(redelRes[0].Entries)) -//} -// + res, err = querier(ctx, []string{types.QueryRedelegations}, query) + require.NoError(t, err) + + var redelRes types.RedelegationResponses + errRes = cdc.UnmarshalJSON(res, &redelRes) + require.NoError(t, errRes) + require.Len(t, redelRes, 1) + require.Equal(t, redel.DelegatorAddress, redelRes[0].DelegatorAddress) + require.Equal(t, redel.ValidatorSrcAddress, redelRes[0].ValidatorSrcAddress) + require.Equal(t, redel.ValidatorDstAddress, redelRes[0].ValidatorDstAddress) + require.Len(t, redel.Entries, len(redelRes[0].Entries)) +} + //func TestQueryRedelegations(t *testing.T) { // cdc := codec.New() // ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000) From 29987a095b83c2952a74987953b8f4e305bf3537 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Thu, 20 Feb 2020 17:30:13 +0100 Subject: [PATCH 08/90] make TestQueryDelegations pass with simapp :D --- x/staking/keeper/querier_test.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/x/staking/keeper/querier_test.go b/x/staking/keeper/querier_test.go index 333b3b28e655..0289bb102cf3 100644 --- a/x/staking/keeper/querier_test.go +++ b/x/staking/keeper/querier_test.go @@ -4,6 +4,8 @@ import ( "fmt" "testing" + "github.com/cosmos/cosmos-sdk/x/distribution" + "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" @@ -203,14 +205,14 @@ func TestQueryValidators(t *testing.T) { } } -func TestQueryDelegation(t *testing.T) { +func TestQueryDelegations(t *testing.T) { cdc := codec.New() app := simapp.Setup(false) ctx := app.BaseApp.NewContext(false, abci.Header{}) params := app.StakingKeeper.GetParams(ctx) querier := staking.NewQuerier(app.StakingKeeper) - addrs := simapp.AddTestAddrs(app, ctx, 500, sdk.TokensFromConsensusPower(10000)) + addrs := simapp.AddTestAddrs(app, ctx, 2, sdk.TokensFromConsensusPower(10000)) addrAcc1, addrAcc2 := addrs[0], addrs[1] addrVal1, addrVal2 := sdk.ValAddress(addrAcc1), sdk.ValAddress(addrAcc2) @@ -221,6 +223,8 @@ func TestQueryDelegation(t *testing.T) { val1 := types.NewValidator(addrVal1, pk1, types.Description{}) app.StakingKeeper.SetValidator(ctx, val1) app.StakingKeeper.SetValidatorByPowerIndex(ctx, val1) + app.DistrKeeper.SetValidatorHistoricalRewards(ctx, addrVal1, 18446744073709551615, distribution.ValidatorHistoricalRewards{ReferenceCount: 1}) + app.DistrKeeper.SetValidatorHistoricalRewards(ctx, addrVal2, 18446744073709551615, distribution.ValidatorHistoricalRewards{ReferenceCount: 1}) val2 := types.NewValidator(addrVal2, pk2, types.Description{}) app.StakingKeeper.SetValidator(ctx, val2) @@ -351,7 +355,7 @@ func TestQueryDelegation(t *testing.T) { require.Equal(t, delegation.DelegatorAddress, delegationsRes[0].DelegatorAddress) require.Equal(t, sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), delegationsRes[0].Balance) - // Query unbonging delegation + // Query unbonding delegation unbondingTokens := sdk.TokensFromConsensusPower(10) _, err = app.StakingKeeper.Undelegate(ctx, addrAcc2, val1.OperatorAddress, unbondingTokens.ToDec()) require.NoError(t, err) From 06c144805d71001a7bffc3aea1ae02c028e54c1c Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Thu, 20 Feb 2020 17:30:45 +0100 Subject: [PATCH 09/90] rename function --- x/staking/keeper/querier_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/staking/keeper/querier_test.go b/x/staking/keeper/querier_test.go index 0289bb102cf3..948529173198 100644 --- a/x/staking/keeper/querier_test.go +++ b/x/staking/keeper/querier_test.go @@ -205,7 +205,7 @@ func TestQueryValidators(t *testing.T) { } } -func TestQueryDelegations(t *testing.T) { +func TestQueryDelegation(t *testing.T) { cdc := codec.New() app := simapp.Setup(false) ctx := app.BaseApp.NewContext(false, abci.Header{}) From 32a27afbd5fc26eeccfe1af5986b452321e7b3a3 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Thu, 20 Feb 2020 17:58:17 +0100 Subject: [PATCH 10/90] make TestQueryRedelegations pass with simapp --- x/staking/keeper/old_querier_test.go | 285 --------------------------- x/staking/keeper/querier_test.go | 143 +++++++------- 2 files changed, 75 insertions(+), 353 deletions(-) diff --git a/x/staking/keeper/old_querier_test.go b/x/staking/keeper/old_querier_test.go index 3203755cc6ab..15074cfa6563 100644 --- a/x/staking/keeper/old_querier_test.go +++ b/x/staking/keeper/old_querier_test.go @@ -17,291 +17,6 @@ var ( pk1, pk2 = PKs[0], PKs[1] ) -func TestQueryDelegation(t *testing.T) { - cdc := codec.New() - ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000) - params := keeper.GetParams(ctx) - - // Create Validators and Delegation - val1 := types.NewValidator(addrVal1, pk1, types.Description{}) - keeper.SetValidator(ctx, val1) - keeper.SetValidatorByPowerIndex(ctx, val1) - - val2 := types.NewValidator(addrVal2, pk2, types.Description{}) - keeper.SetValidator(ctx, val2) - keeper.SetValidatorByPowerIndex(ctx, val2) - - delTokens := sdk.TokensFromConsensusPower(20) - keeper.Delegate(ctx, addrAcc2, delTokens, sdk.Unbonded, val1, true) - - // apply TM updates - keeper.ApplyAndReturnValidatorSetUpdates(ctx) - - // Query Delegator bonded validators - queryParams := types.NewQueryDelegatorParams(addrAcc2) - bz, errRes := cdc.MarshalJSON(queryParams) - require.NoError(t, errRes) - - query := abci.RequestQuery{ - Path: "/custom/staking/delegatorValidators", - Data: bz, - } - - delValidators := keeper.GetDelegatorValidators(ctx, addrAcc2, params.MaxValidators) - - res, err := queryDelegatorValidators(ctx, query, keeper) - require.NoError(t, err) - - var validatorsResp []types.Validator - errRes = cdc.UnmarshalJSON(res, &validatorsResp) - require.NoError(t, errRes) - - require.Equal(t, len(delValidators), len(validatorsResp)) - require.ElementsMatch(t, delValidators, validatorsResp) - - // error unknown request - query.Data = bz[:len(bz)-1] - - _, err = queryDelegatorValidators(ctx, query, keeper) - require.Error(t, err) - - // Query bonded validator - queryBondParams := types.NewQueryBondsParams(addrAcc2, addrVal1) - bz, errRes = cdc.MarshalJSON(queryBondParams) - require.NoError(t, errRes) - - query = abci.RequestQuery{ - Path: "/custom/staking/delegatorValidator", - Data: bz, - } - - res, err = queryDelegatorValidator(ctx, query, keeper) - require.NoError(t, err) - - var validator types.Validator - errRes = cdc.UnmarshalJSON(res, &validator) - require.NoError(t, errRes) - - require.Equal(t, delValidators[0], validator) - - // error unknown request - query.Data = bz[:len(bz)-1] - - _, err = queryDelegatorValidator(ctx, query, keeper) - require.Error(t, err) - - // Query delegation - - query = abci.RequestQuery{ - Path: "/custom/staking/delegation", - Data: bz, - } - - delegation, found := keeper.GetDelegation(ctx, addrAcc2, addrVal1) - require.True(t, found) - - res, err = queryDelegation(ctx, query, keeper) - require.NoError(t, err) - - var delegationRes types.DelegationResponse - errRes = cdc.UnmarshalJSON(res, &delegationRes) - require.NoError(t, errRes) - - require.Equal(t, delegation.ValidatorAddress, delegationRes.ValidatorAddress) - require.Equal(t, delegation.DelegatorAddress, delegationRes.DelegatorAddress) - require.Equal(t, sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), delegationRes.Balance) - - // Query Delegator Delegations - query = abci.RequestQuery{ - Path: "/custom/staking/delegatorDelegations", - Data: bz, - } - - res, err = queryDelegatorDelegations(ctx, query, keeper) - require.NoError(t, err) - - var delegatorDelegations types.DelegationResponses - errRes = cdc.UnmarshalJSON(res, &delegatorDelegations) - require.NoError(t, errRes) - require.Len(t, delegatorDelegations, 1) - require.Equal(t, delegation.ValidatorAddress, delegatorDelegations[0].ValidatorAddress) - require.Equal(t, delegation.DelegatorAddress, delegatorDelegations[0].DelegatorAddress) - require.Equal(t, sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), delegatorDelegations[0].Balance) - - // error unknown request - query.Data = bz[:len(bz)-1] - - _, err = queryDelegation(ctx, query, keeper) - require.Error(t, err) - - // Query validator delegations - - bz, errRes = cdc.MarshalJSON(types.NewQueryValidatorParams(addrVal1)) - require.NoError(t, errRes) - - query = abci.RequestQuery{ - Path: "custom/staking/validatorDelegations", - Data: bz, - } - - res, err = queryValidatorDelegations(ctx, query, keeper) - require.NoError(t, err) - - var delegationsRes types.DelegationResponses - errRes = cdc.UnmarshalJSON(res, &delegationsRes) - require.NoError(t, errRes) - require.Len(t, delegatorDelegations, 1) - require.Equal(t, delegation.ValidatorAddress, delegationsRes[0].ValidatorAddress) - require.Equal(t, delegation.DelegatorAddress, delegationsRes[0].DelegatorAddress) - require.Equal(t, sdk.NewCoin(sdk.DefaultBondDenom, delegation.Shares.TruncateInt()), delegationsRes[0].Balance) - - // Query unbonging delegation - unbondingTokens := sdk.TokensFromConsensusPower(10) - _, err = keeper.Undelegate(ctx, addrAcc2, val1.OperatorAddress, unbondingTokens.ToDec()) - require.NoError(t, err) - - queryBondParams = types.NewQueryBondsParams(addrAcc2, addrVal1) - bz, errRes = cdc.MarshalJSON(queryBondParams) - require.NoError(t, errRes) - - query = abci.RequestQuery{ - Path: "/custom/staking/unbondingDelegation", - Data: bz, - } - - unbond, found := keeper.GetUnbondingDelegation(ctx, addrAcc2, addrVal1) - require.True(t, found) - - res, err = queryUnbondingDelegation(ctx, query, keeper) - require.NoError(t, err) - - var unbondRes types.UnbondingDelegation - errRes = cdc.UnmarshalJSON(res, &unbondRes) - require.NoError(t, errRes) - - require.Equal(t, unbond, unbondRes) - - // error unknown request - query.Data = bz[:len(bz)-1] - - _, err = queryUnbondingDelegation(ctx, query, keeper) - require.Error(t, err) - - // Query Delegator Delegations - - query = abci.RequestQuery{ - Path: "/custom/staking/delegatorUnbondingDelegations", - Data: bz, - } - - res, err = queryDelegatorUnbondingDelegations(ctx, query, keeper) - require.NoError(t, err) - - var delegatorUbds []types.UnbondingDelegation - errRes = cdc.UnmarshalJSON(res, &delegatorUbds) - require.NoError(t, errRes) - require.Equal(t, unbond, delegatorUbds[0]) - - // error unknown request - query.Data = bz[:len(bz)-1] - - _, err = queryDelegatorUnbondingDelegations(ctx, query, keeper) - require.Error(t, err) - - // Query redelegation - redelegationTokens := sdk.TokensFromConsensusPower(10) - _, err = keeper.BeginRedelegation(ctx, addrAcc2, val1.OperatorAddress, - val2.OperatorAddress, redelegationTokens.ToDec()) - require.NoError(t, err) - redel, found := keeper.GetRedelegation(ctx, addrAcc2, val1.OperatorAddress, val2.OperatorAddress) - require.True(t, found) - - bz, errRes = cdc.MarshalJSON(types.NewQueryRedelegationParams(addrAcc2, val1.OperatorAddress, val2.OperatorAddress)) - require.NoError(t, errRes) - - query = abci.RequestQuery{ - Path: "/custom/staking/redelegations", - Data: bz, - } - - res, err = queryRedelegations(ctx, query, keeper) - require.NoError(t, err) - - var redelRes types.RedelegationResponses - errRes = cdc.UnmarshalJSON(res, &redelRes) - require.NoError(t, errRes) - require.Len(t, redelRes, 1) - require.Equal(t, redel.DelegatorAddress, redelRes[0].DelegatorAddress) - require.Equal(t, redel.ValidatorSrcAddress, redelRes[0].ValidatorSrcAddress) - require.Equal(t, redel.ValidatorDstAddress, redelRes[0].ValidatorDstAddress) - require.Len(t, redel.Entries, len(redelRes[0].Entries)) -} - -func TestQueryRedelegations(t *testing.T) { - cdc := codec.New() - ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000) - - // Create Validators and Delegation - val1 := types.NewValidator(addrVal1, pk1, types.Description{}) - val2 := types.NewValidator(addrVal2, pk2, types.Description{}) - keeper.SetValidator(ctx, val1) - keeper.SetValidator(ctx, val2) - - delAmount := sdk.TokensFromConsensusPower(100) - keeper.Delegate(ctx, addrAcc2, delAmount, sdk.Unbonded, val1, true) - _ = keeper.ApplyAndReturnValidatorSetUpdates(ctx) - - rdAmount := sdk.TokensFromConsensusPower(20) - keeper.BeginRedelegation(ctx, addrAcc2, val1.GetOperator(), val2.GetOperator(), rdAmount.ToDec()) - keeper.ApplyAndReturnValidatorSetUpdates(ctx) - - redel, found := keeper.GetRedelegation(ctx, addrAcc2, val1.OperatorAddress, val2.OperatorAddress) - require.True(t, found) - - // delegator redelegations - queryDelegatorParams := types.NewQueryDelegatorParams(addrAcc2) - bz, errRes := cdc.MarshalJSON(queryDelegatorParams) - require.NoError(t, errRes) - - query := abci.RequestQuery{ - Path: "/custom/staking/redelegations", - Data: bz, - } - - res, err := queryRedelegations(ctx, query, keeper) - require.NoError(t, err) - - var redelRes types.RedelegationResponses - errRes = cdc.UnmarshalJSON(res, &redelRes) - require.NoError(t, errRes) - require.Len(t, redelRes, 1) - require.Equal(t, redel.DelegatorAddress, redelRes[0].DelegatorAddress) - require.Equal(t, redel.ValidatorSrcAddress, redelRes[0].ValidatorSrcAddress) - require.Equal(t, redel.ValidatorDstAddress, redelRes[0].ValidatorDstAddress) - require.Len(t, redel.Entries, len(redelRes[0].Entries)) - - // validator redelegations - queryValidatorParams := types.NewQueryValidatorParams(val1.GetOperator()) - bz, errRes = cdc.MarshalJSON(queryValidatorParams) - require.NoError(t, errRes) - - query = abci.RequestQuery{ - Path: "/custom/staking/redelegations", - Data: bz, - } - - res, err = queryRedelegations(ctx, query, keeper) - require.NoError(t, err) - - errRes = cdc.UnmarshalJSON(res, &redelRes) - require.NoError(t, errRes) - require.Len(t, redelRes, 1) - require.Equal(t, redel.DelegatorAddress, redelRes[0].DelegatorAddress) - require.Equal(t, redel.ValidatorSrcAddress, redelRes[0].ValidatorSrcAddress) - require.Equal(t, redel.ValidatorDstAddress, redelRes[0].ValidatorDstAddress) - require.Len(t, redel.Entries, len(redelRes[0].Entries)) -} - func TestQueryUnbondingDelegation(t *testing.T) { cdc := codec.New() ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000) diff --git a/x/staking/keeper/querier_test.go b/x/staking/keeper/querier_test.go index 948529173198..7008547c4a62 100644 --- a/x/staking/keeper/querier_test.go +++ b/x/staking/keeper/querier_test.go @@ -4,8 +4,6 @@ import ( "fmt" "testing" - "github.com/cosmos/cosmos-sdk/x/distribution" - "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" @@ -13,6 +11,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/distribution" "github.com/cosmos/cosmos-sdk/x/staking" "github.com/cosmos/cosmos-sdk/x/staking/types" ) @@ -224,11 +223,11 @@ func TestQueryDelegation(t *testing.T) { app.StakingKeeper.SetValidator(ctx, val1) app.StakingKeeper.SetValidatorByPowerIndex(ctx, val1) app.DistrKeeper.SetValidatorHistoricalRewards(ctx, addrVal1, 18446744073709551615, distribution.ValidatorHistoricalRewards{ReferenceCount: 1}) - app.DistrKeeper.SetValidatorHistoricalRewards(ctx, addrVal2, 18446744073709551615, distribution.ValidatorHistoricalRewards{ReferenceCount: 1}) val2 := types.NewValidator(addrVal2, pk2, types.Description{}) app.StakingKeeper.SetValidator(ctx, val2) app.StakingKeeper.SetValidatorByPowerIndex(ctx, val2) + app.DistrKeeper.SetValidatorHistoricalRewards(ctx, addrVal2, 18446744073709551615, distribution.ValidatorHistoricalRewards{ReferenceCount: 1}) delTokens := sdk.TokensFromConsensusPower(20) _, err := app.StakingKeeper.Delegate(ctx, addrAcc2, delTokens, sdk.Unbonded, val1, true) @@ -437,71 +436,79 @@ func TestQueryDelegation(t *testing.T) { require.Len(t, redel.Entries, len(redelRes[0].Entries)) } -//func TestQueryRedelegations(t *testing.T) { -// cdc := codec.New() -// ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000) -// -// // Create Validators and Delegation -// val1 := types.NewValidator(addrVal1, pk1, types.Description{}) -// val2 := types.NewValidator(addrVal2, pk2, types.Description{}) -// keeper.SetValidator(ctx, val1) -// keeper.SetValidator(ctx, val2) -// -// delAmount := sdk.TokensFromConsensusPower(100) -// keeper.Delegate(ctx, addrAcc2, delAmount, sdk.Unbonded, val1, true) -// _ = keeper.ApplyAndReturnValidatorSetUpdates(ctx) -// -// rdAmount := sdk.TokensFromConsensusPower(20) -// keeper.BeginRedelegation(ctx, addrAcc2, val1.GetOperator(), val2.GetOperator(), rdAmount.ToDec()) -// keeper.ApplyAndReturnValidatorSetUpdates(ctx) -// -// redel, found := keeper.GetRedelegation(ctx, addrAcc2, val1.OperatorAddress, val2.OperatorAddress) -// require.True(t, found) -// -// // delegator redelegations -// queryDelegatorParams := types.NewQueryDelegatorParams(addrAcc2) -// bz, errRes := cdc.MarshalJSON(queryDelegatorParams) -// require.NoError(t, errRes) -// -// query := abci.RequestQuery{ -// Path: "/custom/staking/redelegations", -// Data: bz, -// } -// -// res, err := queryRedelegations(ctx, query, keeper) -// require.NoError(t, err) -// -// var redelRes types.RedelegationResponses -// errRes = cdc.UnmarshalJSON(res, &redelRes) -// require.NoError(t, errRes) -// require.Len(t, redelRes, 1) -// require.Equal(t, redel.DelegatorAddress, redelRes[0].DelegatorAddress) -// require.Equal(t, redel.ValidatorSrcAddress, redelRes[0].ValidatorSrcAddress) -// require.Equal(t, redel.ValidatorDstAddress, redelRes[0].ValidatorDstAddress) -// require.Len(t, redel.Entries, len(redelRes[0].Entries)) -// -// // validator redelegations -// queryValidatorParams := types.NewQueryValidatorParams(val1.GetOperator()) -// bz, errRes = cdc.MarshalJSON(queryValidatorParams) -// require.NoError(t, errRes) -// -// query = abci.RequestQuery{ -// Path: "/custom/staking/redelegations", -// Data: bz, -// } -// -// res, err = queryRedelegations(ctx, query, keeper) -// require.NoError(t, err) -// -// errRes = cdc.UnmarshalJSON(res, &redelRes) -// require.NoError(t, errRes) -// require.Len(t, redelRes, 1) -// require.Equal(t, redel.DelegatorAddress, redelRes[0].DelegatorAddress) -// require.Equal(t, redel.ValidatorSrcAddress, redelRes[0].ValidatorSrcAddress) -// require.Equal(t, redel.ValidatorDstAddress, redelRes[0].ValidatorDstAddress) -// require.Len(t, redel.Entries, len(redelRes[0].Entries)) -//} -// +func TestQueryRedelegations(t *testing.T) { + cdc := codec.New() + app := simapp.Setup(false) + ctx := app.BaseApp.NewContext(false, abci.Header{}) + querier := staking.NewQuerier(app.StakingKeeper) + + addrs := simapp.AddTestAddrs(app, ctx, 2, sdk.TokensFromConsensusPower(10000)) + addrAcc1, addrAcc2 := addrs[0], addrs[1] + addrVal1, addrVal2 := sdk.ValAddress(addrAcc1), sdk.ValAddress(addrAcc2) + + // Create Validators and Delegation + val1 := types.NewValidator(addrVal1, PKs[0], types.Description{}) + val2 := types.NewValidator(addrVal2, PKs[1], types.Description{}) + app.StakingKeeper.SetValidator(ctx, val1) + app.StakingKeeper.SetValidator(ctx, val2) + app.DistrKeeper.SetValidatorHistoricalRewards(ctx, addrVal1, 18446744073709551615, distribution.ValidatorHistoricalRewards{ReferenceCount: 1}) + app.DistrKeeper.SetValidatorHistoricalRewards(ctx, addrVal2, 18446744073709551615, distribution.ValidatorHistoricalRewards{ReferenceCount: 1}) + + delAmount := sdk.TokensFromConsensusPower(100) + app.StakingKeeper.Delegate(ctx, addrAcc2, delAmount, sdk.Unbonded, val1, true) + _ = app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + + rdAmount := sdk.TokensFromConsensusPower(20) + app.StakingKeeper.BeginRedelegation(ctx, addrAcc2, val1.GetOperator(), val2.GetOperator(), rdAmount.ToDec()) + app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + + redel, found := app.StakingKeeper.GetRedelegation(ctx, addrAcc2, val1.OperatorAddress, val2.OperatorAddress) + require.True(t, found) + + // delegator redelegations + queryDelegatorParams := types.NewQueryDelegatorParams(addrAcc2) + bz, errRes := cdc.MarshalJSON(queryDelegatorParams) + require.NoError(t, errRes) + + query := abci.RequestQuery{ + Path: "/custom/staking/redelegations", + Data: bz, + } + + res, err := querier(ctx, []string{types.QueryRedelegations}, query) + require.NoError(t, err) + + var redelRes types.RedelegationResponses + errRes = cdc.UnmarshalJSON(res, &redelRes) + require.NoError(t, errRes) + require.Len(t, redelRes, 1) + require.Equal(t, redel.DelegatorAddress, redelRes[0].DelegatorAddress) + require.Equal(t, redel.ValidatorSrcAddress, redelRes[0].ValidatorSrcAddress) + require.Equal(t, redel.ValidatorDstAddress, redelRes[0].ValidatorDstAddress) + require.Len(t, redel.Entries, len(redelRes[0].Entries)) + + // validator redelegations + queryValidatorParams := types.NewQueryValidatorParams(val1.GetOperator()) + bz, errRes = cdc.MarshalJSON(queryValidatorParams) + require.NoError(t, errRes) + + query = abci.RequestQuery{ + Path: "/custom/staking/redelegations", + Data: bz, + } + + res, err = querier(ctx, []string{types.QueryRedelegations}, query) + require.NoError(t, err) + + errRes = cdc.UnmarshalJSON(res, &redelRes) + require.NoError(t, errRes) + require.Len(t, redelRes, 1) + require.Equal(t, redel.DelegatorAddress, redelRes[0].DelegatorAddress) + require.Equal(t, redel.ValidatorSrcAddress, redelRes[0].ValidatorSrcAddress) + require.Equal(t, redel.ValidatorDstAddress, redelRes[0].ValidatorDstAddress) + require.Len(t, redel.Entries, len(redelRes[0].Entries)) +} + //func TestQueryUnbondingDelegation(t *testing.T) { // cdc := codec.New() // ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000) From fdba5b5904278bb8e79130ad3b34111e56005b6f Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Thu, 20 Feb 2020 18:10:37 +0100 Subject: [PATCH 11/90] finish keeper refactor for querier in staking using simapp --- x/staking/keeper/old_querier_test.go | 151 --------------- x/staking/keeper/querier_test.go | 277 ++++++++++++++------------- 2 files changed, 145 insertions(+), 283 deletions(-) delete mode 100644 x/staking/keeper/old_querier_test.go diff --git a/x/staking/keeper/old_querier_test.go b/x/staking/keeper/old_querier_test.go deleted file mode 100644 index 15074cfa6563..000000000000 --- a/x/staking/keeper/old_querier_test.go +++ /dev/null @@ -1,151 +0,0 @@ -package keeper - -import ( - "testing" - - abci "github.com/tendermint/tendermint/abci/types" - - "github.com/cosmos/cosmos-sdk/codec" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/stretchr/testify/require" -) - -var ( - addrAcc1, addrAcc2 = Addrs[0], Addrs[1] - addrVal1, addrVal2 = sdk.ValAddress(Addrs[0]), sdk.ValAddress(Addrs[1]) - pk1, pk2 = PKs[0], PKs[1] -) - -func TestQueryUnbondingDelegation(t *testing.T) { - cdc := codec.New() - ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000) - - // Create Validators and Delegation - val1 := types.NewValidator(addrVal1, pk1, types.Description{}) - keeper.SetValidator(ctx, val1) - - // delegate - delAmount := sdk.TokensFromConsensusPower(100) - _, err := keeper.Delegate(ctx, addrAcc1, delAmount, sdk.Unbonded, val1, true) - require.NoError(t, err) - _ = keeper.ApplyAndReturnValidatorSetUpdates(ctx) - - // undelegate - undelAmount := sdk.TokensFromConsensusPower(20) - _, err = keeper.Undelegate(ctx, addrAcc1, val1.GetOperator(), undelAmount.ToDec()) - require.NoError(t, err) - keeper.ApplyAndReturnValidatorSetUpdates(ctx) - - _, found := keeper.GetUnbondingDelegation(ctx, addrAcc1, val1.OperatorAddress) - require.True(t, found) - - // - // found: query unbonding delegation by delegator and validator - // - queryValidatorParams := types.NewQueryBondsParams(addrAcc1, val1.GetOperator()) - bz, errRes := cdc.MarshalJSON(queryValidatorParams) - require.NoError(t, errRes) - query := abci.RequestQuery{ - Path: "/custom/staking/unbondingDelegation", - Data: bz, - } - res, err := queryUnbondingDelegation(ctx, query, keeper) - require.NoError(t, err) - require.NotNil(t, res) - var ubDel types.UnbondingDelegation - require.NoError(t, cdc.UnmarshalJSON(res, &ubDel)) - require.Equal(t, addrAcc1, ubDel.DelegatorAddress) - require.Equal(t, val1.OperatorAddress, ubDel.ValidatorAddress) - require.Equal(t, 1, len(ubDel.Entries)) - - // - // not found: query unbonding delegation by delegator and validator - // - queryValidatorParams = types.NewQueryBondsParams(addrAcc2, val1.GetOperator()) - bz, errRes = cdc.MarshalJSON(queryValidatorParams) - require.NoError(t, errRes) - query = abci.RequestQuery{ - Path: "/custom/staking/unbondingDelegation", - Data: bz, - } - _, err = queryUnbondingDelegation(ctx, query, keeper) - require.Error(t, err) - - // - // found: query unbonding delegation by delegator and validator - // - queryDelegatorParams := types.NewQueryDelegatorParams(addrAcc1) - bz, errRes = cdc.MarshalJSON(queryDelegatorParams) - require.NoError(t, errRes) - query = abci.RequestQuery{ - Path: "/custom/staking/delegatorUnbondingDelegations", - Data: bz, - } - res, err = queryDelegatorUnbondingDelegations(ctx, query, keeper) - require.NoError(t, err) - require.NotNil(t, res) - var ubDels []types.UnbondingDelegation - require.NoError(t, cdc.UnmarshalJSON(res, &ubDels)) - require.Equal(t, 1, len(ubDels)) - require.Equal(t, addrAcc1, ubDels[0].DelegatorAddress) - require.Equal(t, val1.OperatorAddress, ubDels[0].ValidatorAddress) - - // - // not found: query unbonding delegation by delegator and validator - // - queryDelegatorParams = types.NewQueryDelegatorParams(addrAcc2) - bz, errRes = cdc.MarshalJSON(queryDelegatorParams) - require.NoError(t, errRes) - query = abci.RequestQuery{ - Path: "/custom/staking/delegatorUnbondingDelegations", - Data: bz, - } - res, err = queryDelegatorUnbondingDelegations(ctx, query, keeper) - require.NoError(t, err) - require.NotNil(t, res) - require.NoError(t, cdc.UnmarshalJSON(res, &ubDels)) - require.Equal(t, 0, len(ubDels)) -} - -func TestQueryHistoricalInfo(t *testing.T) { - cdc := codec.New() - ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000) - - // Create Validators and Delegation - val1 := types.NewValidator(addrVal1, pk1, types.Description{}) - val2 := types.NewValidator(addrVal2, pk2, types.Description{}) - vals := []types.Validator{val1, val2} - keeper.SetValidator(ctx, val1) - keeper.SetValidator(ctx, val2) - - header := abci.Header{ - ChainID: "HelloChain", - Height: 5, - } - hi := types.NewHistoricalInfo(header, vals) - keeper.SetHistoricalInfo(ctx, 5, hi) - - queryHistoricalParams := types.NewQueryHistoricalInfoParams(4) - bz, errRes := cdc.MarshalJSON(queryHistoricalParams) - require.NoError(t, errRes) - query := abci.RequestQuery{ - Path: "/custom/staking/historicalInfo", - Data: bz, - } - res, err := queryHistoricalInfo(ctx, query, keeper) - require.Error(t, err, "Invalid query passed") - require.Nil(t, res, "Invalid query returned non-nil result") - - queryHistoricalParams = types.NewQueryHistoricalInfoParams(5) - bz, errRes = cdc.MarshalJSON(queryHistoricalParams) - require.NoError(t, errRes) - query.Data = bz - res, err = queryHistoricalInfo(ctx, query, keeper) - require.NoError(t, err, "Valid query passed") - require.NotNil(t, res, "Valid query returned nil result") - - var recv types.HistoricalInfo - require.NoError(t, cdc.UnmarshalJSON(res, &recv)) - require.Equal(t, hi, recv, "HistoricalInfo query returned wrong result") -} diff --git a/x/staking/keeper/querier_test.go b/x/staking/keeper/querier_test.go index 7008547c4a62..19a260d531da 100644 --- a/x/staking/keeper/querier_test.go +++ b/x/staking/keeper/querier_test.go @@ -509,135 +509,148 @@ func TestQueryRedelegations(t *testing.T) { require.Len(t, redel.Entries, len(redelRes[0].Entries)) } -//func TestQueryUnbondingDelegation(t *testing.T) { -// cdc := codec.New() -// ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000) -// -// // Create Validators and Delegation -// val1 := types.NewValidator(addrVal1, pk1, types.Description{}) -// keeper.SetValidator(ctx, val1) -// -// // delegate -// delAmount := sdk.TokensFromConsensusPower(100) -// _, err := keeper.Delegate(ctx, addrAcc1, delAmount, sdk.Unbonded, val1, true) -// require.NoError(t, err) -// _ = keeper.ApplyAndReturnValidatorSetUpdates(ctx) -// -// // undelegate -// undelAmount := sdk.TokensFromConsensusPower(20) -// _, err = keeper.Undelegate(ctx, addrAcc1, val1.GetOperator(), undelAmount.ToDec()) -// require.NoError(t, err) -// keeper.ApplyAndReturnValidatorSetUpdates(ctx) -// -// _, found := keeper.GetUnbondingDelegation(ctx, addrAcc1, val1.OperatorAddress) -// require.True(t, found) -// -// // -// // found: query unbonding delegation by delegator and validator -// // -// queryValidatorParams := types.NewQueryBondsParams(addrAcc1, val1.GetOperator()) -// bz, errRes := cdc.MarshalJSON(queryValidatorParams) -// require.NoError(t, errRes) -// query := abci.RequestQuery{ -// Path: "/custom/staking/unbondingDelegation", -// Data: bz, -// } -// res, err := queryUnbondingDelegation(ctx, query, keeper) -// require.NoError(t, err) -// require.NotNil(t, res) -// var ubDel types.UnbondingDelegation -// require.NoError(t, cdc.UnmarshalJSON(res, &ubDel)) -// require.Equal(t, addrAcc1, ubDel.DelegatorAddress) -// require.Equal(t, val1.OperatorAddress, ubDel.ValidatorAddress) -// require.Equal(t, 1, len(ubDel.Entries)) -// -// // -// // not found: query unbonding delegation by delegator and validator -// // -// queryValidatorParams = types.NewQueryBondsParams(addrAcc2, val1.GetOperator()) -// bz, errRes = cdc.MarshalJSON(queryValidatorParams) -// require.NoError(t, errRes) -// query = abci.RequestQuery{ -// Path: "/custom/staking/unbondingDelegation", -// Data: bz, -// } -// _, err = queryUnbondingDelegation(ctx, query, keeper) -// require.Error(t, err) -// -// // -// // found: query unbonding delegation by delegator and validator -// // -// queryDelegatorParams := types.NewQueryDelegatorParams(addrAcc1) -// bz, errRes = cdc.MarshalJSON(queryDelegatorParams) -// require.NoError(t, errRes) -// query = abci.RequestQuery{ -// Path: "/custom/staking/delegatorUnbondingDelegations", -// Data: bz, -// } -// res, err = queryDelegatorUnbondingDelegations(ctx, query, keeper) -// require.NoError(t, err) -// require.NotNil(t, res) -// var ubDels []types.UnbondingDelegation -// require.NoError(t, cdc.UnmarshalJSON(res, &ubDels)) -// require.Equal(t, 1, len(ubDels)) -// require.Equal(t, addrAcc1, ubDels[0].DelegatorAddress) -// require.Equal(t, val1.OperatorAddress, ubDels[0].ValidatorAddress) -// -// // -// // not found: query unbonding delegation by delegator and validator -// // -// queryDelegatorParams = types.NewQueryDelegatorParams(addrAcc2) -// bz, errRes = cdc.MarshalJSON(queryDelegatorParams) -// require.NoError(t, errRes) -// query = abci.RequestQuery{ -// Path: "/custom/staking/delegatorUnbondingDelegations", -// Data: bz, -// } -// res, err = queryDelegatorUnbondingDelegations(ctx, query, keeper) -// require.NoError(t, err) -// require.NotNil(t, res) -// require.NoError(t, cdc.UnmarshalJSON(res, &ubDels)) -// require.Equal(t, 0, len(ubDels)) -//} -// -//func TestQueryHistoricalInfo(t *testing.T) { -// cdc := codec.New() -// ctx, _, _, keeper, _ := CreateTestInput(t, false, 10000) -// -// // Create Validators and Delegation -// val1 := types.NewValidator(addrVal1, pk1, types.Description{}) -// val2 := types.NewValidator(addrVal2, pk2, types.Description{}) -// vals := []types.Validator{val1, val2} -// keeper.SetValidator(ctx, val1) -// keeper.SetValidator(ctx, val2) -// -// header := abci.Header{ -// ChainID: "HelloChain", -// Height: 5, -// } -// hi := types.NewHistoricalInfo(header, vals) -// keeper.SetHistoricalInfo(ctx, 5, hi) -// -// queryHistoricalParams := types.NewQueryHistoricalInfoParams(4) -// bz, errRes := cdc.MarshalJSON(queryHistoricalParams) -// require.NoError(t, errRes) -// query := abci.RequestQuery{ -// Path: "/custom/staking/historicalInfo", -// Data: bz, -// } -// res, err := queryHistoricalInfo(ctx, query, keeper) -// require.Error(t, err, "Invalid query passed") -// require.Nil(t, res, "Invalid query returned non-nil result") -// -// queryHistoricalParams = types.NewQueryHistoricalInfoParams(5) -// bz, errRes = cdc.MarshalJSON(queryHistoricalParams) -// require.NoError(t, errRes) -// query.Data = bz -// res, err = queryHistoricalInfo(ctx, query, keeper) -// require.NoError(t, err, "Valid query passed") -// require.NotNil(t, res, "Valid query returned nil result") -// -// var recv types.HistoricalInfo -// require.NoError(t, cdc.UnmarshalJSON(res, &recv)) -// require.Equal(t, hi, recv, "HistoricalInfo query returned wrong result") -//} +func TestQueryUnbondingDelegation(t *testing.T) { + cdc := codec.New() + app := simapp.Setup(false) + ctx := app.BaseApp.NewContext(false, abci.Header{}) + querier := staking.NewQuerier(app.StakingKeeper) + + addrs := simapp.AddTestAddrs(app, ctx, 2, sdk.TokensFromConsensusPower(10000)) + addrAcc1, addrAcc2 := addrs[0], addrs[1] + addrVal1 := sdk.ValAddress(addrAcc1) + + // Create Validators and Delegation + val1 := types.NewValidator(addrVal1, PKs[0], types.Description{}) + app.StakingKeeper.SetValidator(ctx, val1) + app.DistrKeeper.SetValidatorHistoricalRewards(ctx, addrVal1, 18446744073709551615, distribution.ValidatorHistoricalRewards{ReferenceCount: 1}) + + // delegate + delAmount := sdk.TokensFromConsensusPower(100) + _, err := app.StakingKeeper.Delegate(ctx, addrAcc1, delAmount, sdk.Unbonded, val1, true) + require.NoError(t, err) + _ = app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + + // undelegate + undelAmount := sdk.TokensFromConsensusPower(20) + _, err = app.StakingKeeper.Undelegate(ctx, addrAcc1, val1.GetOperator(), undelAmount.ToDec()) + require.NoError(t, err) + app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + + _, found := app.StakingKeeper.GetUnbondingDelegation(ctx, addrAcc1, val1.OperatorAddress) + require.True(t, found) + + // + // found: query unbonding delegation by delegator and validator + // + queryValidatorParams := types.NewQueryBondsParams(addrAcc1, val1.GetOperator()) + bz, errRes := cdc.MarshalJSON(queryValidatorParams) + require.NoError(t, errRes) + query := abci.RequestQuery{ + Path: "/custom/staking/unbondingDelegation", + Data: bz, + } + res, err := querier(ctx, []string{types.QueryUnbondingDelegation}, query) + require.NoError(t, err) + require.NotNil(t, res) + var ubDel types.UnbondingDelegation + require.NoError(t, cdc.UnmarshalJSON(res, &ubDel)) + require.Equal(t, addrAcc1, ubDel.DelegatorAddress) + require.Equal(t, val1.OperatorAddress, ubDel.ValidatorAddress) + require.Equal(t, 1, len(ubDel.Entries)) + + // + // not found: query unbonding delegation by delegator and validator + // + queryValidatorParams = types.NewQueryBondsParams(addrAcc2, val1.GetOperator()) + bz, errRes = cdc.MarshalJSON(queryValidatorParams) + require.NoError(t, errRes) + query = abci.RequestQuery{ + Path: "/custom/staking/unbondingDelegation", + Data: bz, + } + res, err = querier(ctx, []string{types.QueryUnbondingDelegation}, query) + require.Error(t, err) + + // + // found: query unbonding delegation by delegator and validator + // + queryDelegatorParams := types.NewQueryDelegatorParams(addrAcc1) + bz, errRes = cdc.MarshalJSON(queryDelegatorParams) + require.NoError(t, errRes) + query = abci.RequestQuery{ + Path: "/custom/staking/delegatorUnbondingDelegations", + Data: bz, + } + res, err = querier(ctx, []string{types.QueryDelegatorUnbondingDelegations}, query) + require.NoError(t, err) + require.NotNil(t, res) + var ubDels []types.UnbondingDelegation + require.NoError(t, cdc.UnmarshalJSON(res, &ubDels)) + require.Equal(t, 1, len(ubDels)) + require.Equal(t, addrAcc1, ubDels[0].DelegatorAddress) + require.Equal(t, val1.OperatorAddress, ubDels[0].ValidatorAddress) + + // + // not found: query unbonding delegation by delegator and validator + // + queryDelegatorParams = types.NewQueryDelegatorParams(addrAcc2) + bz, errRes = cdc.MarshalJSON(queryDelegatorParams) + require.NoError(t, errRes) + query = abci.RequestQuery{ + Path: "/custom/staking/delegatorUnbondingDelegations", + Data: bz, + } + res, err = querier(ctx, []string{types.QueryDelegatorUnbondingDelegations}, query) + require.NoError(t, err) + require.NotNil(t, res) + require.NoError(t, cdc.UnmarshalJSON(res, &ubDels)) + require.Equal(t, 0, len(ubDels)) +} + +func TestQueryHistoricalInfo(t *testing.T) { + cdc := codec.New() + app := simapp.Setup(false) + ctx := app.BaseApp.NewContext(false, abci.Header{}) + querier := staking.NewQuerier(app.StakingKeeper) + + addrs := simapp.AddTestAddrs(app, ctx, 2, sdk.TokensFromConsensusPower(10000)) + addrAcc1, addrAcc2 := addrs[0], addrs[1] + addrVal1, addrVal2 := sdk.ValAddress(addrAcc1), sdk.ValAddress(addrAcc2) + + // Create Validators and Delegation + val1 := types.NewValidator(addrVal1, PKs[0], types.Description{}) + val2 := types.NewValidator(addrVal2, PKs[1], types.Description{}) + vals := []types.Validator{val1, val2} + app.StakingKeeper.SetValidator(ctx, val1) + app.StakingKeeper.SetValidator(ctx, val2) + + header := abci.Header{ + ChainID: "HelloChain", + Height: 5, + } + hi := types.NewHistoricalInfo(header, vals) + app.StakingKeeper.SetHistoricalInfo(ctx, 5, hi) + + queryHistoricalParams := types.NewQueryHistoricalInfoParams(4) + bz, errRes := cdc.MarshalJSON(queryHistoricalParams) + require.NoError(t, errRes) + query := abci.RequestQuery{ + Path: "/custom/staking/historicalInfo", + Data: bz, + } + res, err := querier(ctx, []string{types.QueryHistoricalInfo}, query) + require.Error(t, err, "Invalid query passed") + require.Nil(t, res, "Invalid query returned non-nil result") + + queryHistoricalParams = types.NewQueryHistoricalInfoParams(5) + bz, errRes = cdc.MarshalJSON(queryHistoricalParams) + require.NoError(t, errRes) + query.Data = bz + res, err = querier(ctx, []string{types.QueryHistoricalInfo}, query) + require.NoError(t, err, "Valid query passed") + require.NotNil(t, res, "Valid query returned nil result") + + var recv types.HistoricalInfo + require.NoError(t, cdc.UnmarshalJSON(res, &recv)) + require.Equal(t, hi, recv, "HistoricalInfo query returned wrong result") +} From 9eaa5b0e1aa128c245cd3c1f2a921e3290e739e9 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Fri, 21 Feb 2020 12:24:41 +0100 Subject: [PATCH 12/90] refactor delegation test TestUnbondDelegation to use simapp --- x/staking/keeper/delegation_test.go | 1648 ++++++++++++----------- x/staking/keeper/old_delegation_test.go | 765 +++++++++++ 2 files changed, 1600 insertions(+), 813 deletions(-) create mode 100644 x/staking/keeper/old_delegation_test.go diff --git a/x/staking/keeper/delegation_test.go b/x/staking/keeper/delegation_test.go index eda1a550cd67..798716b2c2d0 100644 --- a/x/staking/keeper/delegation_test.go +++ b/x/staking/keeper/delegation_test.go @@ -1,19 +1,25 @@ -package keeper +package keeper_test import ( "testing" "time" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/cosmos/cosmos-sdk/x/distribution" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/simapp" + abci "github.com/tendermint/tendermint/abci/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/staking/keeper" + "github.com/cosmos/cosmos-sdk/x/staking/types" ) // tests GetDelegation, GetDelegatorDelegations, SetDelegation, RemoveDelegation, GetDelegatorDelegations func TestDelegation(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 10) + app := simapp.Setup(false) + ctx := app.BaseApp.NewContext(false, abci.Header{}) //construct the validators amts := []sdk.Int{sdk.NewInt(9), sdk.NewInt(8), sdk.NewInt(7)} @@ -23,28 +29,28 @@ func TestDelegation(t *testing.T) { validators[i], _ = validators[i].AddTokensFromDel(amt) } - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], true) - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], true) - validators[2] = TestingUpdateValidator(keeper, ctx, validators[2], true) + validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], true) + validators[1] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[1], true) + validators[2] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[2], true) // first add a validators[0] to delegate too bond1to1 := types.NewDelegation(addrDels[0], addrVals[0], sdk.NewDec(9)) // check the empty keeper first - _, found := keeper.GetDelegation(ctx, addrDels[0], addrVals[0]) + _, found := app.StakingKeeper.GetDelegation(ctx, addrDels[0], addrVals[0]) require.False(t, found) // set and retrieve a record - keeper.SetDelegation(ctx, bond1to1) - resBond, found := keeper.GetDelegation(ctx, addrDels[0], addrVals[0]) + app.StakingKeeper.SetDelegation(ctx, bond1to1) + resBond, found := app.StakingKeeper.GetDelegation(ctx, addrDels[0], addrVals[0]) require.True(t, found) require.True(t, bond1to1.Equal(resBond)) // modify a records, save, and retrieve bond1to1.Shares = sdk.NewDec(99) - keeper.SetDelegation(ctx, bond1to1) - resBond, found = keeper.GetDelegation(ctx, addrDels[0], addrVals[0]) + app.StakingKeeper.SetDelegation(ctx, bond1to1) + resBond, found = app.StakingKeeper.GetDelegation(ctx, addrDels[0], addrVals[0]) require.True(t, found) require.True(t, bond1to1.Equal(resBond)) @@ -54,28 +60,28 @@ func TestDelegation(t *testing.T) { bond2to1 := types.NewDelegation(addrDels[1], addrVals[0], sdk.NewDec(9)) bond2to2 := types.NewDelegation(addrDels[1], addrVals[1], sdk.NewDec(9)) bond2to3 := types.NewDelegation(addrDels[1], addrVals[2], sdk.NewDec(9)) - keeper.SetDelegation(ctx, bond1to2) - keeper.SetDelegation(ctx, bond1to3) - keeper.SetDelegation(ctx, bond2to1) - keeper.SetDelegation(ctx, bond2to2) - keeper.SetDelegation(ctx, bond2to3) + app.StakingKeeper.SetDelegation(ctx, bond1to2) + app.StakingKeeper.SetDelegation(ctx, bond1to3) + app.StakingKeeper.SetDelegation(ctx, bond2to1) + app.StakingKeeper.SetDelegation(ctx, bond2to2) + app.StakingKeeper.SetDelegation(ctx, bond2to3) // test all bond retrieve capabilities - resBonds := keeper.GetDelegatorDelegations(ctx, addrDels[0], 5) + resBonds := app.StakingKeeper.GetDelegatorDelegations(ctx, addrDels[0], 5) require.Equal(t, 3, len(resBonds)) require.True(t, bond1to1.Equal(resBonds[0])) require.True(t, bond1to2.Equal(resBonds[1])) require.True(t, bond1to3.Equal(resBonds[2])) - resBonds = keeper.GetAllDelegatorDelegations(ctx, addrDels[0]) + resBonds = app.StakingKeeper.GetAllDelegatorDelegations(ctx, addrDels[0]) require.Equal(t, 3, len(resBonds)) - resBonds = keeper.GetDelegatorDelegations(ctx, addrDels[0], 2) + resBonds = app.StakingKeeper.GetDelegatorDelegations(ctx, addrDels[0], 2) require.Equal(t, 2, len(resBonds)) - resBonds = keeper.GetDelegatorDelegations(ctx, addrDels[1], 5) + resBonds = app.StakingKeeper.GetDelegatorDelegations(ctx, addrDels[1], 5) require.Equal(t, 3, len(resBonds)) require.True(t, bond2to1.Equal(resBonds[0])) require.True(t, bond2to2.Equal(resBonds[1])) require.True(t, bond2to3.Equal(resBonds[2])) - allBonds := keeper.GetAllDelegations(ctx) + allBonds := app.StakingKeeper.GetAllDelegations(ctx) require.Equal(t, 6, len(allBonds)) require.True(t, bond1to1.Equal(allBonds[0])) require.True(t, bond1to2.Equal(allBonds[1])) @@ -84,96 +90,108 @@ func TestDelegation(t *testing.T) { require.True(t, bond2to2.Equal(allBonds[4])) require.True(t, bond2to3.Equal(allBonds[5])) - resVals := keeper.GetDelegatorValidators(ctx, addrDels[0], 3) + resVals := app.StakingKeeper.GetDelegatorValidators(ctx, addrDels[0], 3) require.Equal(t, 3, len(resVals)) - resVals = keeper.GetDelegatorValidators(ctx, addrDels[1], 4) + resVals = app.StakingKeeper.GetDelegatorValidators(ctx, addrDels[1], 4) require.Equal(t, 3, len(resVals)) for i := 0; i < 3; i++ { - resVal, err := keeper.GetDelegatorValidator(ctx, addrDels[0], addrVals[i]) + resVal, err := app.StakingKeeper.GetDelegatorValidator(ctx, addrDels[0], addrVals[i]) require.Nil(t, err) require.Equal(t, addrVals[i], resVal.GetOperator()) - resVal, err = keeper.GetDelegatorValidator(ctx, addrDels[1], addrVals[i]) + resVal, err = app.StakingKeeper.GetDelegatorValidator(ctx, addrDels[1], addrVals[i]) require.Nil(t, err) require.Equal(t, addrVals[i], resVal.GetOperator()) - resDels := keeper.GetValidatorDelegations(ctx, addrVals[i]) + resDels := app.StakingKeeper.GetValidatorDelegations(ctx, addrVals[i]) require.Len(t, resDels, 2) } // delete a record - keeper.RemoveDelegation(ctx, bond2to3) - _, found = keeper.GetDelegation(ctx, addrDels[1], addrVals[2]) + app.StakingKeeper.RemoveDelegation(ctx, bond2to3) + _, found = app.StakingKeeper.GetDelegation(ctx, addrDels[1], addrVals[2]) require.False(t, found) - resBonds = keeper.GetDelegatorDelegations(ctx, addrDels[1], 5) + resBonds = app.StakingKeeper.GetDelegatorDelegations(ctx, addrDels[1], 5) require.Equal(t, 2, len(resBonds)) require.True(t, bond2to1.Equal(resBonds[0])) require.True(t, bond2to2.Equal(resBonds[1])) - resBonds = keeper.GetAllDelegatorDelegations(ctx, addrDels[1]) + resBonds = app.StakingKeeper.GetAllDelegatorDelegations(ctx, addrDels[1]) require.Equal(t, 2, len(resBonds)) // delete all the records from delegator 2 - keeper.RemoveDelegation(ctx, bond2to1) - keeper.RemoveDelegation(ctx, bond2to2) - _, found = keeper.GetDelegation(ctx, addrDels[1], addrVals[0]) + app.StakingKeeper.RemoveDelegation(ctx, bond2to1) + app.StakingKeeper.RemoveDelegation(ctx, bond2to2) + _, found = app.StakingKeeper.GetDelegation(ctx, addrDels[1], addrVals[0]) require.False(t, found) - _, found = keeper.GetDelegation(ctx, addrDels[1], addrVals[1]) + _, found = app.StakingKeeper.GetDelegation(ctx, addrDels[1], addrVals[1]) require.False(t, found) - resBonds = keeper.GetDelegatorDelegations(ctx, addrDels[1], 5) + resBonds = app.StakingKeeper.GetDelegatorDelegations(ctx, addrDels[1], 5) require.Equal(t, 0, len(resBonds)) } // tests Get/Set/Remove UnbondingDelegation func TestUnbondingDelegation(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 0) + app := simapp.Setup(false) + ctx := app.BaseApp.NewContext(false, abci.Header{}) - ubd := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 0, - time.Unix(0, 0), sdk.NewInt(5)) + ubd := types.NewUnbondingDelegation( + addrDels[0], + addrVals[0], + 0, + time.Unix(0, 0), + sdk.NewInt(5), + ) // set and retrieve a record - keeper.SetUnbondingDelegation(ctx, ubd) - resUnbond, found := keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) + app.StakingKeeper.SetUnbondingDelegation(ctx, ubd) + resUnbond, found := app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) require.True(t, found) require.True(t, ubd.Equal(resUnbond)) // modify a records, save, and retrieve ubd.Entries[0].Balance = sdk.NewInt(21) - keeper.SetUnbondingDelegation(ctx, ubd) + app.StakingKeeper.SetUnbondingDelegation(ctx, ubd) - resUnbonds := keeper.GetUnbondingDelegations(ctx, addrDels[0], 5) + resUnbonds := app.StakingKeeper.GetUnbondingDelegations(ctx, addrDels[0], 5) require.Equal(t, 1, len(resUnbonds)) - resUnbonds = keeper.GetAllUnbondingDelegations(ctx, addrDels[0]) + resUnbonds = app.StakingKeeper.GetAllUnbondingDelegations(ctx, addrDels[0]) require.Equal(t, 1, len(resUnbonds)) - resUnbond, found = keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) + resUnbond, found = app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) require.True(t, found) require.True(t, ubd.Equal(resUnbond)) // delete a record - keeper.RemoveUnbondingDelegation(ctx, ubd) - _, found = keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) + app.StakingKeeper.RemoveUnbondingDelegation(ctx, ubd) + _, found = app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) require.False(t, found) - resUnbonds = keeper.GetUnbondingDelegations(ctx, addrDels[0], 5) + resUnbonds = app.StakingKeeper.GetUnbondingDelegations(ctx, addrDels[0], 5) require.Equal(t, 0, len(resUnbonds)) - resUnbonds = keeper.GetAllUnbondingDelegations(ctx, addrDels[0]) + resUnbonds = app.StakingKeeper.GetAllUnbondingDelegations(ctx, addrDels[0]) require.Equal(t, 0, len(resUnbonds)) - } func TestUnbondDelegation(t *testing.T) { - ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) + app := simapp.Setup(false) + ctx := app.BaseApp.NewContext(false, abci.Header{}) startTokens := sdk.TokensFromConsensusPower(10) - notBondedPool := keeper.GetNotBondedPool(ctx) + notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) - require.NoError(t, bk.SetBalances(ctx, notBondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), startTokens)))) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) + require.NoError(t, + app.BankKeeper.SetBalances( + ctx, + notBondedPool.GetAddress(), + sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), startTokens)), + ), + ) + app.SupplyKeeper.SetModuleAccount(ctx, notBondedPool) // create a validator and a delegator to that validator // note this validator starts not-bonded @@ -182,19 +200,23 @@ func TestUnbondDelegation(t *testing.T) { validator, issuedShares := validator.AddTokensFromDel(startTokens) require.Equal(t, startTokens, issuedShares.RoundInt()) - validator = TestingUpdateValidator(keeper, ctx, validator, true) + validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) - keeper.SetDelegation(ctx, delegation) + app.StakingKeeper.SetDelegation(ctx, delegation) + app.DistrKeeper.SetDelegatorStartingInfo(ctx, addrVals[0], addrDels[0], distribution.DelegatorStartingInfo{}) + app.DistrKeeper.SetValidatorHistoricalRewards(ctx, addrVals[0], 18446744073709551615, distribution.ValidatorHistoricalRewards{ReferenceCount: 1}) bondTokens := sdk.TokensFromConsensusPower(6) - amount, err := keeper.unbond(ctx, addrDels[0], addrVals[0], bondTokens.ToDec()) + _, err := app.StakingKeeper.Undelegate(ctx, addrDels[0], addrVals[0], bondTokens.ToDec()) require.NoError(t, err) - require.Equal(t, bondTokens, amount) // shares to be added to an unbonding delegation - delegation, found := keeper.GetDelegation(ctx, addrDels[0], addrVals[0]) + notBondedPoolBalance := app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), app.StakingKeeper.BondDenom(ctx)) + require.Equal(t, bondTokens, notBondedPoolBalance.Amount) // shares to be added to an unbonding delegation + + delegation, found := app.StakingKeeper.GetDelegation(ctx, addrDels[0], addrVals[0]) require.True(t, found) - validator, found = keeper.GetValidator(ctx, addrVals[0]) + validator, found = app.StakingKeeper.GetValidator(ctx, addrVals[0]) require.True(t, found) remainingTokens := startTokens.Sub(bondTokens) @@ -202,755 +224,755 @@ func TestUnbondDelegation(t *testing.T) { require.Equal(t, remainingTokens, validator.BondedTokens()) } -func TestUnbondingDelegationsMaxEntries(t *testing.T) { - ctx, _, bk, keeper, _ := CreateTestInput(t, false, 1) - startTokens := sdk.TokensFromConsensusPower(10) - - bondDenom := keeper.BondDenom(ctx) - notBondedPool := keeper.GetNotBondedPool(ctx) - - err := bk.SetBalances(ctx, notBondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(bondDenom, startTokens))) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - // create a validator and a delegator to that validator - validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) - - validator, issuedShares := validator.AddTokensFromDel(startTokens) - require.Equal(t, startTokens, issuedShares.RoundInt()) - - validator = TestingUpdateValidator(keeper, ctx, validator, true) - require.True(sdk.IntEq(t, startTokens, validator.BondedTokens())) - require.True(t, validator.IsBonded()) - - delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) - keeper.SetDelegation(ctx, delegation) - - maxEntries := keeper.MaxEntries(ctx) - - oldBonded := bk.GetBalance(ctx, keeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount - oldNotBonded := bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount - - // should all pass - var completionTime time.Time - for i := uint32(0); i < maxEntries; i++ { - var err error - completionTime, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], sdk.NewDec(1)) - require.NoError(t, err) - } - - newBonded := bk.GetBalance(ctx, keeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount - newNotBonded := bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount - require.True(sdk.IntEq(t, newBonded, oldBonded.SubRaw(int64(maxEntries)))) - require.True(sdk.IntEq(t, newNotBonded, oldNotBonded.AddRaw(int64(maxEntries)))) - - oldBonded = bk.GetBalance(ctx, keeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount - oldNotBonded = bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount - - // an additional unbond should fail due to max entries - _, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], sdk.NewDec(1)) - require.Error(t, err) - - newBonded = bk.GetBalance(ctx, keeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount - newNotBonded = bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount - - require.True(sdk.IntEq(t, newBonded, oldBonded)) - require.True(sdk.IntEq(t, newNotBonded, oldNotBonded)) - - // mature unbonding delegations - ctx = ctx.WithBlockTime(completionTime) - err = keeper.CompleteUnbonding(ctx, addrDels[0], addrVals[0]) - require.NoError(t, err) - - newBonded = bk.GetBalance(ctx, keeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount - newNotBonded = bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount - require.True(sdk.IntEq(t, newBonded, oldBonded)) - require.True(sdk.IntEq(t, newNotBonded, oldNotBonded.SubRaw(int64(maxEntries)))) - - oldNotBonded = bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount - - // unbonding should work again - _, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], sdk.NewDec(1)) - require.NoError(t, err) - - newBonded = bk.GetBalance(ctx, keeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount - newNotBonded = bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount - require.True(sdk.IntEq(t, newBonded, oldBonded.SubRaw(1))) - require.True(sdk.IntEq(t, newNotBonded, oldNotBonded.AddRaw(1))) -} - -// test undelegating self delegation from a validator pushing it below MinSelfDelegation -// shift it from the bonded to unbonding state and jailed -func TestUndelegateSelfDelegationBelowMinSelfDelegation(t *testing.T) { - ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) - delTokens := sdk.TokensFromConsensusPower(10) - delCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), delTokens)) - - //create a validator with a self-delegation - validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) - - validator.MinSelfDelegation = delTokens - validator, issuedShares := validator.AddTokensFromDel(delTokens) - require.Equal(t, delTokens, issuedShares.RoundInt()) - - // add bonded tokens to pool for delegations - notBondedPool := keeper.GetNotBondedPool(ctx) - oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) - err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(delCoins...)) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - validator = TestingUpdateValidator(keeper, ctx, validator, true) - require.True(t, validator.IsBonded()) - - selfDelegation := types.NewDelegation(sdk.AccAddress(addrVals[0].Bytes()), addrVals[0], issuedShares) - keeper.SetDelegation(ctx, selfDelegation) - - // add bonded tokens to pool for delegations - bondedPool := keeper.GetBondedPool(ctx) - oldBonded := bk.GetAllBalances(ctx, bondedPool.GetAddress()) - err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) - - // create a second delegation to this validator - keeper.DeleteValidatorByPowerIndex(ctx, validator) - validator, issuedShares = validator.AddTokensFromDel(delTokens) - require.True(t, validator.IsBonded()) - require.Equal(t, delTokens, issuedShares.RoundInt()) - - // add bonded tokens to pool for delegations - oldBonded = bk.GetAllBalances(ctx, bondedPool.GetAddress()) - err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) - - validator = TestingUpdateValidator(keeper, ctx, validator, true) - delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) - keeper.SetDelegation(ctx, delegation) - - val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) - _, err = keeper.Undelegate(ctx, val0AccAddr, addrVals[0], sdk.TokensFromConsensusPower(6).ToDec()) - require.NoError(t, err) - - // end block - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 1, len(updates)) - - validator, found := keeper.GetValidator(ctx, addrVals[0]) - require.True(t, found) - require.Equal(t, sdk.TokensFromConsensusPower(14), validator.Tokens) - require.Equal(t, sdk.Unbonding, validator.Status) - require.True(t, validator.Jailed) -} - -func TestUndelegateFromUnbondingValidator(t *testing.T) { - ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) - delTokens := sdk.TokensFromConsensusPower(10) - delCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), delTokens)) - - //create a validator with a self-delegation - validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) - - validator, issuedShares := validator.AddTokensFromDel(delTokens) - require.Equal(t, delTokens, issuedShares.RoundInt()) - - // add bonded tokens to pool for delegations - notBondedPool := keeper.GetNotBondedPool(ctx) - oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) - err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(delCoins...)) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - validator = TestingUpdateValidator(keeper, ctx, validator, true) - require.True(t, validator.IsBonded()) - - selfDelegation := types.NewDelegation(sdk.AccAddress(addrVals[0].Bytes()), addrVals[0], issuedShares) - keeper.SetDelegation(ctx, selfDelegation) - - bondedPool := keeper.GetBondedPool(ctx) - oldBonded := bk.GetAllBalances(ctx, bondedPool.GetAddress()) - err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) - - // create a second delegation to this validator - keeper.DeleteValidatorByPowerIndex(ctx, validator) - - validator, issuedShares = validator.AddTokensFromDel(delTokens) - require.Equal(t, delTokens, issuedShares.RoundInt()) - - oldBonded = bk.GetAllBalances(ctx, bondedPool.GetAddress()) - err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) - - validator = TestingUpdateValidator(keeper, ctx, validator, true) - delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) - keeper.SetDelegation(ctx, delegation) - - oldBonded = bk.GetAllBalances(ctx, bondedPool.GetAddress()) - err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) - - header := ctx.BlockHeader() - blockHeight := int64(10) - header.Height = blockHeight - blockTime := time.Unix(333, 0) - header.Time = blockTime - ctx = ctx.WithBlockHeader(header) - - // unbond the all self-delegation to put validator in unbonding state - val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) - _, err = keeper.Undelegate(ctx, val0AccAddr, addrVals[0], delTokens.ToDec()) - require.NoError(t, err) - - // end block - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 1, len(updates)) - - validator, found := keeper.GetValidator(ctx, addrVals[0]) - require.True(t, found) - require.Equal(t, blockHeight, validator.UnbondingHeight) - params := keeper.GetParams(ctx) - require.True(t, blockTime.Add(params.UnbondingTime).Equal(validator.UnbondingTime)) - - blockHeight2 := int64(20) - blockTime2 := time.Unix(444, 0).UTC() - ctx = ctx.WithBlockHeight(blockHeight2) - ctx = ctx.WithBlockTime(blockTime2) - - // unbond some of the other delegation's shares - _, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], sdk.NewDec(6)) - require.NoError(t, err) - - // retrieve the unbonding delegation - ubd, found := keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) - require.True(t, found) - require.Len(t, ubd.Entries, 1) - require.True(t, ubd.Entries[0].Balance.Equal(sdk.NewInt(6))) - assert.Equal(t, blockHeight2, ubd.Entries[0].CreationHeight) - assert.True(t, blockTime2.Add(params.UnbondingTime).Equal(ubd.Entries[0].CompletionTime)) -} - -func TestUndelegateFromUnbondedValidator(t *testing.T) { - ctx, _, bk, keeper, _ := CreateTestInput(t, false, 1) - delTokens := sdk.TokensFromConsensusPower(10) - delCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), delTokens)) - - // add bonded tokens to pool for delegations - notBondedPool := keeper.GetNotBondedPool(ctx) - oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) - err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(delCoins...)) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - // create a validator with a self-delegation - validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) - - valTokens := sdk.TokensFromConsensusPower(10) - validator, issuedShares := validator.AddTokensFromDel(valTokens) - require.Equal(t, valTokens, issuedShares.RoundInt()) - validator = TestingUpdateValidator(keeper, ctx, validator, true) - require.True(t, validator.IsBonded()) - - val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) - selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) - keeper.SetDelegation(ctx, selfDelegation) - - bondedPool := keeper.GetBondedPool(ctx) - oldBonded := bk.GetAllBalances(ctx, bondedPool.GetAddress()) - err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) - - // create a second delegation to this validator - keeper.DeleteValidatorByPowerIndex(ctx, validator) - validator, issuedShares = validator.AddTokensFromDel(delTokens) - require.Equal(t, delTokens, issuedShares.RoundInt()) - validator = TestingUpdateValidator(keeper, ctx, validator, true) - require.True(t, validator.IsBonded()) - delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) - keeper.SetDelegation(ctx, delegation) - - ctx = ctx.WithBlockHeight(10) - ctx = ctx.WithBlockTime(time.Unix(333, 0)) - - // unbond the all self-delegation to put validator in unbonding state - _, err = keeper.Undelegate(ctx, val0AccAddr, addrVals[0], valTokens.ToDec()) - require.NoError(t, err) - - // end block - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 1, len(updates)) - - validator, found := keeper.GetValidator(ctx, addrVals[0]) - require.True(t, found) - require.Equal(t, ctx.BlockHeight(), validator.UnbondingHeight) - params := keeper.GetParams(ctx) - require.True(t, ctx.BlockHeader().Time.Add(params.UnbondingTime).Equal(validator.UnbondingTime)) - - // unbond the validator - ctx = ctx.WithBlockTime(validator.UnbondingTime) - keeper.UnbondAllMatureValidatorQueue(ctx) - - // Make sure validator is still in state because there is still an outstanding delegation - validator, found = keeper.GetValidator(ctx, addrVals[0]) - require.True(t, found) - require.Equal(t, validator.Status, sdk.Unbonded) - - // unbond some of the other delegation's shares - unbondTokens := sdk.TokensFromConsensusPower(6) - _, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], unbondTokens.ToDec()) - require.NoError(t, err) - - // unbond rest of the other delegation's shares - remainingTokens := delTokens.Sub(unbondTokens) - _, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], remainingTokens.ToDec()) - require.NoError(t, err) - - // now validator should now be deleted from state - validator, found = keeper.GetValidator(ctx, addrVals[0]) - require.False(t, found, "%v", validator) -} - -func TestUnbondingAllDelegationFromValidator(t *testing.T) { - ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) - delTokens := sdk.TokensFromConsensusPower(10) - delCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), delTokens)) - - // add bonded tokens to pool for delegations - notBondedPool := keeper.GetNotBondedPool(ctx) - oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) - err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(delCoins...)) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - //create a validator with a self-delegation - validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) - - valTokens := sdk.TokensFromConsensusPower(10) - validator, issuedShares := validator.AddTokensFromDel(valTokens) - require.Equal(t, valTokens, issuedShares.RoundInt()) - - validator = TestingUpdateValidator(keeper, ctx, validator, true) - require.True(t, validator.IsBonded()) - val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) - - selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) - keeper.SetDelegation(ctx, selfDelegation) - - // create a second delegation to this validator - keeper.DeleteValidatorByPowerIndex(ctx, validator) - validator, issuedShares = validator.AddTokensFromDel(delTokens) - require.Equal(t, delTokens, issuedShares.RoundInt()) - - bondedPool := keeper.GetBondedPool(ctx) - oldBonded := bk.GetAllBalances(ctx, bondedPool.GetAddress()) - err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) - - validator = TestingUpdateValidator(keeper, ctx, validator, true) - require.True(t, validator.IsBonded()) - - delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) - keeper.SetDelegation(ctx, delegation) - - ctx = ctx.WithBlockHeight(10) - ctx = ctx.WithBlockTime(time.Unix(333, 0)) - - // unbond the all self-delegation to put validator in unbonding state - _, err = keeper.Undelegate(ctx, val0AccAddr, addrVals[0], valTokens.ToDec()) - require.NoError(t, err) - - // end block - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 1, len(updates)) - - // unbond all the remaining delegation - _, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], delTokens.ToDec()) - require.NoError(t, err) - - // validator should still be in state and still be in unbonding state - validator, found := keeper.GetValidator(ctx, addrVals[0]) - require.True(t, found) - require.Equal(t, validator.Status, sdk.Unbonding) - - // unbond the validator - ctx = ctx.WithBlockTime(validator.UnbondingTime) - keeper.UnbondAllMatureValidatorQueue(ctx) - - // validator should now be deleted from state - _, found = keeper.GetValidator(ctx, addrVals[0]) - require.False(t, found) -} - -// Make sure that that the retrieving the delegations doesn't affect the state -func TestGetRedelegationsFromSrcValidator(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 0) - - rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 0, - time.Unix(0, 0), sdk.NewInt(5), - sdk.NewDec(5)) - - // set and retrieve a record - keeper.SetRedelegation(ctx, rd) - resBond, found := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) - require.True(t, found) - - // get the redelegations one time - redelegations := keeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0]) - require.Equal(t, 1, len(redelegations)) - require.True(t, redelegations[0].Equal(resBond)) - - // get the redelegations a second time, should be exactly the same - redelegations = keeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0]) - require.Equal(t, 1, len(redelegations)) - require.True(t, redelegations[0].Equal(resBond)) -} - -// tests Get/Set/Remove/Has UnbondingDelegation -func TestRedelegation(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 0) - - rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 0, - time.Unix(0, 0), sdk.NewInt(5), - sdk.NewDec(5)) - - // test shouldn't have and redelegations - has := keeper.HasReceivingRedelegation(ctx, addrDels[0], addrVals[1]) - require.False(t, has) - - // set and retrieve a record - keeper.SetRedelegation(ctx, rd) - resRed, found := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) - require.True(t, found) - - redelegations := keeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0]) - require.Equal(t, 1, len(redelegations)) - require.True(t, redelegations[0].Equal(resRed)) - - redelegations = keeper.GetRedelegations(ctx, addrDels[0], 5) - require.Equal(t, 1, len(redelegations)) - require.True(t, redelegations[0].Equal(resRed)) - - redelegations = keeper.GetAllRedelegations(ctx, addrDels[0], nil, nil) - require.Equal(t, 1, len(redelegations)) - require.True(t, redelegations[0].Equal(resRed)) - - // check if has the redelegation - has = keeper.HasReceivingRedelegation(ctx, addrDels[0], addrVals[1]) - require.True(t, has) - - // modify a records, save, and retrieve - rd.Entries[0].SharesDst = sdk.NewDec(21) - keeper.SetRedelegation(ctx, rd) - - resRed, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) - require.True(t, found) - require.True(t, rd.Equal(resRed)) - - redelegations = keeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0]) - require.Equal(t, 1, len(redelegations)) - require.True(t, redelegations[0].Equal(resRed)) - - redelegations = keeper.GetRedelegations(ctx, addrDels[0], 5) - require.Equal(t, 1, len(redelegations)) - require.True(t, redelegations[0].Equal(resRed)) - - // delete a record - keeper.RemoveRedelegation(ctx, rd) - _, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) - require.False(t, found) - - redelegations = keeper.GetRedelegations(ctx, addrDels[0], 5) - require.Equal(t, 0, len(redelegations)) - - redelegations = keeper.GetAllRedelegations(ctx, addrDels[0], nil, nil) - require.Equal(t, 0, len(redelegations)) -} - -func TestRedelegateToSameValidator(t *testing.T) { - ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) - valTokens := sdk.TokensFromConsensusPower(10) - startCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), valTokens)) - - // add bonded tokens to pool for delegations - notBondedPool := keeper.GetNotBondedPool(ctx) - oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) - err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(startCoins...)) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - // create a validator with a self-delegation - validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) - validator, issuedShares := validator.AddTokensFromDel(valTokens) - require.Equal(t, valTokens, issuedShares.RoundInt()) - validator = TestingUpdateValidator(keeper, ctx, validator, true) - require.True(t, validator.IsBonded()) - - val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) - selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) - keeper.SetDelegation(ctx, selfDelegation) - - _, err = keeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[0], sdk.NewDec(5)) - require.Error(t, err) -} - -func TestRedelegationMaxEntries(t *testing.T) { - ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) - startTokens := sdk.TokensFromConsensusPower(20) - startCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), startTokens)) - - // add bonded tokens to pool for delegations - notBondedPool := keeper.GetNotBondedPool(ctx) - oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) - err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(startCoins...)) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - // create a validator with a self-delegation - validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) - valTokens := sdk.TokensFromConsensusPower(10) - validator, issuedShares := validator.AddTokensFromDel(valTokens) - require.Equal(t, valTokens, issuedShares.RoundInt()) - validator = TestingUpdateValidator(keeper, ctx, validator, true) - val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) - selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) - keeper.SetDelegation(ctx, selfDelegation) - - // create a second validator - validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{}) - validator2, issuedShares = validator2.AddTokensFromDel(valTokens) - require.Equal(t, valTokens, issuedShares.RoundInt()) - - validator2 = TestingUpdateValidator(keeper, ctx, validator2, true) - require.Equal(t, sdk.Bonded, validator2.Status) - - maxEntries := keeper.MaxEntries(ctx) - - // redelegations should pass - var completionTime time.Time - for i := uint32(0); i < maxEntries; i++ { - var err error - completionTime, err = keeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], sdk.NewDec(1)) - require.NoError(t, err) - } - - // an additional redelegation should fail due to max entries - _, err = keeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], sdk.NewDec(1)) - require.Error(t, err) - - // mature redelegations - ctx = ctx.WithBlockTime(completionTime) - err = keeper.CompleteRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1]) - require.NoError(t, err) - - // redelegation should work again - _, err = keeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], sdk.NewDec(1)) - require.NoError(t, err) -} - -func TestRedelegateSelfDelegation(t *testing.T) { - ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) - startTokens := sdk.TokensFromConsensusPower(30) - startCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), startTokens)) - - // add bonded tokens to pool for delegations - notBondedPool := keeper.GetNotBondedPool(ctx) - oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) - err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(startCoins...)) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - //create a validator with a self-delegation - validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) - valTokens := sdk.TokensFromConsensusPower(10) - validator, issuedShares := validator.AddTokensFromDel(valTokens) - require.Equal(t, valTokens, issuedShares.RoundInt()) - - validator = TestingUpdateValidator(keeper, ctx, validator, true) - - val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) - selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) - keeper.SetDelegation(ctx, selfDelegation) - - // create a second validator - validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{}) - validator2, issuedShares = validator2.AddTokensFromDel(valTokens) - require.Equal(t, valTokens, issuedShares.RoundInt()) - validator2 = TestingUpdateValidator(keeper, ctx, validator2, true) - require.Equal(t, sdk.Bonded, validator2.Status) - - // create a second delegation to validator 1 - delTokens := sdk.TokensFromConsensusPower(10) - validator, issuedShares = validator.AddTokensFromDel(delTokens) - require.Equal(t, delTokens, issuedShares.RoundInt()) - validator = TestingUpdateValidator(keeper, ctx, validator, true) - - delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) - keeper.SetDelegation(ctx, delegation) - - _, err = keeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], delTokens.ToDec()) - require.NoError(t, err) - - // end block - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 2, len(updates)) - - validator, found := keeper.GetValidator(ctx, addrVals[0]) - require.True(t, found) - require.Equal(t, valTokens, validator.Tokens) - require.Equal(t, sdk.Unbonding, validator.Status) -} - -func TestRedelegateFromUnbondingValidator(t *testing.T) { - ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) - startTokens := sdk.TokensFromConsensusPower(30) - startCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), startTokens)) - - // add bonded tokens to pool for delegations - notBondedPool := keeper.GetNotBondedPool(ctx) - oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) - err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(startCoins...)) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - //create a validator with a self-delegation - validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) - - valTokens := sdk.TokensFromConsensusPower(10) - validator, issuedShares := validator.AddTokensFromDel(valTokens) - require.Equal(t, valTokens, issuedShares.RoundInt()) - validator = TestingUpdateValidator(keeper, ctx, validator, true) - val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) - selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) - keeper.SetDelegation(ctx, selfDelegation) - - // create a second delegation to this validator - keeper.DeleteValidatorByPowerIndex(ctx, validator) - delTokens := sdk.TokensFromConsensusPower(10) - validator, issuedShares = validator.AddTokensFromDel(delTokens) - require.Equal(t, delTokens, issuedShares.RoundInt()) - validator = TestingUpdateValidator(keeper, ctx, validator, true) - delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) - keeper.SetDelegation(ctx, delegation) - - // create a second validator - validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{}) - validator2, issuedShares = validator2.AddTokensFromDel(valTokens) - require.Equal(t, valTokens, issuedShares.RoundInt()) - validator2 = TestingUpdateValidator(keeper, ctx, validator2, true) - - header := ctx.BlockHeader() - blockHeight := int64(10) - header.Height = blockHeight - blockTime := time.Unix(333, 0) - header.Time = blockTime - ctx = ctx.WithBlockHeader(header) - - // unbond the all self-delegation to put validator in unbonding state - _, err = keeper.Undelegate(ctx, val0AccAddr, addrVals[0], delTokens.ToDec()) - require.NoError(t, err) - - // end block - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 1, len(updates)) - - validator, found := keeper.GetValidator(ctx, addrVals[0]) - require.True(t, found) - require.Equal(t, blockHeight, validator.UnbondingHeight) - params := keeper.GetParams(ctx) - require.True(t, blockTime.Add(params.UnbondingTime).Equal(validator.UnbondingTime)) - - //change the context - header = ctx.BlockHeader() - blockHeight2 := int64(20) - header.Height = blockHeight2 - blockTime2 := time.Unix(444, 0) - header.Time = blockTime2 - ctx = ctx.WithBlockHeader(header) - - // unbond some of the other delegation's shares - redelegateTokens := sdk.TokensFromConsensusPower(6) - _, err = keeper.BeginRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1], redelegateTokens.ToDec()) - require.NoError(t, err) - - // retrieve the unbonding delegation - ubd, found := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) - require.True(t, found) - require.Len(t, ubd.Entries, 1) - assert.Equal(t, blockHeight, ubd.Entries[0].CreationHeight) - assert.True(t, blockTime.Add(params.UnbondingTime).Equal(ubd.Entries[0].CompletionTime)) -} - -func TestRedelegateFromUnbondedValidator(t *testing.T) { - ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) - startTokens := sdk.TokensFromConsensusPower(30) - startCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), startTokens)) - - // add bonded tokens to pool for delegations - notBondedPool := keeper.GetNotBondedPool(ctx) - oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) - err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(startCoins...)) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - //create a validator with a self-delegation - validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) - - valTokens := sdk.TokensFromConsensusPower(10) - validator, issuedShares := validator.AddTokensFromDel(valTokens) - require.Equal(t, valTokens, issuedShares.RoundInt()) - validator = TestingUpdateValidator(keeper, ctx, validator, true) - val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) - selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) - keeper.SetDelegation(ctx, selfDelegation) - - // create a second delegation to this validator - keeper.DeleteValidatorByPowerIndex(ctx, validator) - delTokens := sdk.TokensFromConsensusPower(10) - validator, issuedShares = validator.AddTokensFromDel(delTokens) - require.Equal(t, delTokens, issuedShares.RoundInt()) - validator = TestingUpdateValidator(keeper, ctx, validator, true) - delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) - keeper.SetDelegation(ctx, delegation) - - // create a second validator - validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{}) - validator2, issuedShares = validator2.AddTokensFromDel(valTokens) - require.Equal(t, valTokens, issuedShares.RoundInt()) - validator2 = TestingUpdateValidator(keeper, ctx, validator2, true) - require.Equal(t, sdk.Bonded, validator2.Status) - - ctx = ctx.WithBlockHeight(10) - ctx = ctx.WithBlockTime(time.Unix(333, 0)) - - // unbond the all self-delegation to put validator in unbonding state - _, err = keeper.Undelegate(ctx, val0AccAddr, addrVals[0], delTokens.ToDec()) - require.NoError(t, err) - - // end block - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 1, len(updates)) - - validator, found := keeper.GetValidator(ctx, addrVals[0]) - require.True(t, found) - require.Equal(t, ctx.BlockHeight(), validator.UnbondingHeight) - params := keeper.GetParams(ctx) - require.True(t, ctx.BlockHeader().Time.Add(params.UnbondingTime).Equal(validator.UnbondingTime)) - - // unbond the validator - keeper.unbondingToUnbonded(ctx, validator) - - // redelegate some of the delegation's shares - redelegationTokens := sdk.TokensFromConsensusPower(6) - _, err = keeper.BeginRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1], redelegationTokens.ToDec()) - require.NoError(t, err) - - // no red should have been found - red, found := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) - require.False(t, found, "%v", red) -} +//func TestUnbondingDelegationsMaxEntries(t *testing.T) { +// ctx, _, bk, keeper, _ := CreateTestInput(t, false, 1) +// startTokens := sdk.TokensFromConsensusPower(10) +// +// bondDenom := keeper.BondDenom(ctx) +// notBondedPool := keeper.GetNotBondedPool(ctx) +// +// err := bk.SetBalances(ctx, notBondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(bondDenom, startTokens))) +// require.NoError(t, err) +// keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) +// +// // create a validator and a delegator to that validator +// validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) +// +// validator, issuedShares := validator.AddTokensFromDel(startTokens) +// require.Equal(t, startTokens, issuedShares.RoundInt()) +// +// validator = TestingUpdateValidator(keeper, ctx, validator, true) +// require.True(sdk.IntEq(t, startTokens, validator.BondedTokens())) +// require.True(t, validator.IsBonded()) +// +// delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) +// keeper.SetDelegation(ctx, delegation) +// +// maxEntries := keeper.MaxEntries(ctx) +// +// oldBonded := bk.GetBalance(ctx, keeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount +// oldNotBonded := bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount +// +// // should all pass +// var completionTime time.Time +// for i := uint32(0); i < maxEntries; i++ { +// var err error +// completionTime, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], sdk.NewDec(1)) +// require.NoError(t, err) +// } +// +// newBonded := bk.GetBalance(ctx, keeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount +// newNotBonded := bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount +// require.True(sdk.IntEq(t, newBonded, oldBonded.SubRaw(int64(maxEntries)))) +// require.True(sdk.IntEq(t, newNotBonded, oldNotBonded.AddRaw(int64(maxEntries)))) +// +// oldBonded = bk.GetBalance(ctx, keeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount +// oldNotBonded = bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount +// +// // an additional unbond should fail due to max entries +// _, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], sdk.NewDec(1)) +// require.Error(t, err) +// +// newBonded = bk.GetBalance(ctx, keeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount +// newNotBonded = bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount +// +// require.True(sdk.IntEq(t, newBonded, oldBonded)) +// require.True(sdk.IntEq(t, newNotBonded, oldNotBonded)) +// +// // mature unbonding delegations +// ctx = ctx.WithBlockTime(completionTime) +// err = keeper.CompleteUnbonding(ctx, addrDels[0], addrVals[0]) +// require.NoError(t, err) +// +// newBonded = bk.GetBalance(ctx, keeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount +// newNotBonded = bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount +// require.True(sdk.IntEq(t, newBonded, oldBonded)) +// require.True(sdk.IntEq(t, newNotBonded, oldNotBonded.SubRaw(int64(maxEntries)))) +// +// oldNotBonded = bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount +// +// // unbonding should work again +// _, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], sdk.NewDec(1)) +// require.NoError(t, err) +// +// newBonded = bk.GetBalance(ctx, keeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount +// newNotBonded = bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount +// require.True(sdk.IntEq(t, newBonded, oldBonded.SubRaw(1))) +// require.True(sdk.IntEq(t, newNotBonded, oldNotBonded.AddRaw(1))) +//} +// +//// test undelegating self delegation from a validator pushing it below MinSelfDelegation +//// shift it from the bonded to unbonding state and jailed +//func TestUndelegateSelfDelegationBelowMinSelfDelegation(t *testing.T) { +// ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) +// delTokens := sdk.TokensFromConsensusPower(10) +// delCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), delTokens)) +// +// //create a validator with a self-delegation +// validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) +// +// validator.MinSelfDelegation = delTokens +// validator, issuedShares := validator.AddTokensFromDel(delTokens) +// require.Equal(t, delTokens, issuedShares.RoundInt()) +// +// // add bonded tokens to pool for delegations +// notBondedPool := keeper.GetNotBondedPool(ctx) +// oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) +// err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(delCoins...)) +// require.NoError(t, err) +// keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) +// +// validator = TestingUpdateValidator(keeper, ctx, validator, true) +// require.True(t, validator.IsBonded()) +// +// selfDelegation := types.NewDelegation(sdk.AccAddress(addrVals[0].Bytes()), addrVals[0], issuedShares) +// keeper.SetDelegation(ctx, selfDelegation) +// +// // add bonded tokens to pool for delegations +// bondedPool := keeper.GetBondedPool(ctx) +// oldBonded := bk.GetAllBalances(ctx, bondedPool.GetAddress()) +// err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) +// require.NoError(t, err) +// keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) +// +// // create a second delegation to this validator +// keeper.DeleteValidatorByPowerIndex(ctx, validator) +// validator, issuedShares = validator.AddTokensFromDel(delTokens) +// require.True(t, validator.IsBonded()) +// require.Equal(t, delTokens, issuedShares.RoundInt()) +// +// // add bonded tokens to pool for delegations +// oldBonded = bk.GetAllBalances(ctx, bondedPool.GetAddress()) +// err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) +// require.NoError(t, err) +// keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) +// +// validator = TestingUpdateValidator(keeper, ctx, validator, true) +// delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) +// keeper.SetDelegation(ctx, delegation) +// +// val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) +// _, err = keeper.Undelegate(ctx, val0AccAddr, addrVals[0], sdk.TokensFromConsensusPower(6).ToDec()) +// require.NoError(t, err) +// +// // end block +// updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) +// require.Equal(t, 1, len(updates)) +// +// validator, found := keeper.GetValidator(ctx, addrVals[0]) +// require.True(t, found) +// require.Equal(t, sdk.TokensFromConsensusPower(14), validator.Tokens) +// require.Equal(t, sdk.Unbonding, validator.Status) +// require.True(t, validator.Jailed) +//} +// +//func TestUndelegateFromUnbondingValidator(t *testing.T) { +// ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) +// delTokens := sdk.TokensFromConsensusPower(10) +// delCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), delTokens)) +// +// //create a validator with a self-delegation +// validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) +// +// validator, issuedShares := validator.AddTokensFromDel(delTokens) +// require.Equal(t, delTokens, issuedShares.RoundInt()) +// +// // add bonded tokens to pool for delegations +// notBondedPool := keeper.GetNotBondedPool(ctx) +// oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) +// err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(delCoins...)) +// require.NoError(t, err) +// keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) +// +// validator = TestingUpdateValidator(keeper, ctx, validator, true) +// require.True(t, validator.IsBonded()) +// +// selfDelegation := types.NewDelegation(sdk.AccAddress(addrVals[0].Bytes()), addrVals[0], issuedShares) +// keeper.SetDelegation(ctx, selfDelegation) +// +// bondedPool := keeper.GetBondedPool(ctx) +// oldBonded := bk.GetAllBalances(ctx, bondedPool.GetAddress()) +// err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) +// require.NoError(t, err) +// keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) +// +// // create a second delegation to this validator +// keeper.DeleteValidatorByPowerIndex(ctx, validator) +// +// validator, issuedShares = validator.AddTokensFromDel(delTokens) +// require.Equal(t, delTokens, issuedShares.RoundInt()) +// +// oldBonded = bk.GetAllBalances(ctx, bondedPool.GetAddress()) +// err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) +// require.NoError(t, err) +// keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) +// +// validator = TestingUpdateValidator(keeper, ctx, validator, true) +// delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) +// keeper.SetDelegation(ctx, delegation) +// +// oldBonded = bk.GetAllBalances(ctx, bondedPool.GetAddress()) +// err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) +// require.NoError(t, err) +// keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) +// +// header := ctx.BlockHeader() +// blockHeight := int64(10) +// header.Height = blockHeight +// blockTime := time.Unix(333, 0) +// header.Time = blockTime +// ctx = ctx.WithBlockHeader(header) +// +// // unbond the all self-delegation to put validator in unbonding state +// val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) +// _, err = keeper.Undelegate(ctx, val0AccAddr, addrVals[0], delTokens.ToDec()) +// require.NoError(t, err) +// +// // end block +// updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) +// require.Equal(t, 1, len(updates)) +// +// validator, found := keeper.GetValidator(ctx, addrVals[0]) +// require.True(t, found) +// require.Equal(t, blockHeight, validator.UnbondingHeight) +// params := keeper.GetParams(ctx) +// require.True(t, blockTime.Add(params.UnbondingTime).Equal(validator.UnbondingTime)) +// +// blockHeight2 := int64(20) +// blockTime2 := time.Unix(444, 0).UTC() +// ctx = ctx.WithBlockHeight(blockHeight2) +// ctx = ctx.WithBlockTime(blockTime2) +// +// // unbond some of the other delegation's shares +// _, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], sdk.NewDec(6)) +// require.NoError(t, err) +// +// // retrieve the unbonding delegation +// ubd, found := keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) +// require.True(t, found) +// require.Len(t, ubd.Entries, 1) +// require.True(t, ubd.Entries[0].Balance.Equal(sdk.NewInt(6))) +// assert.Equal(t, blockHeight2, ubd.Entries[0].CreationHeight) +// assert.True(t, blockTime2.Add(params.UnbondingTime).Equal(ubd.Entries[0].CompletionTime)) +//} +// +//func TestUndelegateFromUnbondedValidator(t *testing.T) { +// ctx, _, bk, keeper, _ := CreateTestInput(t, false, 1) +// delTokens := sdk.TokensFromConsensusPower(10) +// delCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), delTokens)) +// +// // add bonded tokens to pool for delegations +// notBondedPool := keeper.GetNotBondedPool(ctx) +// oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) +// err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(delCoins...)) +// require.NoError(t, err) +// keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) +// +// // create a validator with a self-delegation +// validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) +// +// valTokens := sdk.TokensFromConsensusPower(10) +// validator, issuedShares := validator.AddTokensFromDel(valTokens) +// require.Equal(t, valTokens, issuedShares.RoundInt()) +// validator = TestingUpdateValidator(keeper, ctx, validator, true) +// require.True(t, validator.IsBonded()) +// +// val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) +// selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) +// keeper.SetDelegation(ctx, selfDelegation) +// +// bondedPool := keeper.GetBondedPool(ctx) +// oldBonded := bk.GetAllBalances(ctx, bondedPool.GetAddress()) +// err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) +// require.NoError(t, err) +// keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) +// +// // create a second delegation to this validator +// keeper.DeleteValidatorByPowerIndex(ctx, validator) +// validator, issuedShares = validator.AddTokensFromDel(delTokens) +// require.Equal(t, delTokens, issuedShares.RoundInt()) +// validator = TestingUpdateValidator(keeper, ctx, validator, true) +// require.True(t, validator.IsBonded()) +// delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) +// keeper.SetDelegation(ctx, delegation) +// +// ctx = ctx.WithBlockHeight(10) +// ctx = ctx.WithBlockTime(time.Unix(333, 0)) +// +// // unbond the all self-delegation to put validator in unbonding state +// _, err = keeper.Undelegate(ctx, val0AccAddr, addrVals[0], valTokens.ToDec()) +// require.NoError(t, err) +// +// // end block +// updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) +// require.Equal(t, 1, len(updates)) +// +// validator, found := keeper.GetValidator(ctx, addrVals[0]) +// require.True(t, found) +// require.Equal(t, ctx.BlockHeight(), validator.UnbondingHeight) +// params := keeper.GetParams(ctx) +// require.True(t, ctx.BlockHeader().Time.Add(params.UnbondingTime).Equal(validator.UnbondingTime)) +// +// // unbond the validator +// ctx = ctx.WithBlockTime(validator.UnbondingTime) +// keeper.UnbondAllMatureValidatorQueue(ctx) +// +// // Make sure validator is still in state because there is still an outstanding delegation +// validator, found = keeper.GetValidator(ctx, addrVals[0]) +// require.True(t, found) +// require.Equal(t, validator.Status, sdk.Unbonded) +// +// // unbond some of the other delegation's shares +// unbondTokens := sdk.TokensFromConsensusPower(6) +// _, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], unbondTokens.ToDec()) +// require.NoError(t, err) +// +// // unbond rest of the other delegation's shares +// remainingTokens := delTokens.Sub(unbondTokens) +// _, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], remainingTokens.ToDec()) +// require.NoError(t, err) +// +// // now validator should now be deleted from state +// validator, found = keeper.GetValidator(ctx, addrVals[0]) +// require.False(t, found, "%v", validator) +//} +// +//func TestUnbondingAllDelegationFromValidator(t *testing.T) { +// ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) +// delTokens := sdk.TokensFromConsensusPower(10) +// delCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), delTokens)) +// +// // add bonded tokens to pool for delegations +// notBondedPool := keeper.GetNotBondedPool(ctx) +// oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) +// err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(delCoins...)) +// require.NoError(t, err) +// keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) +// +// //create a validator with a self-delegation +// validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) +// +// valTokens := sdk.TokensFromConsensusPower(10) +// validator, issuedShares := validator.AddTokensFromDel(valTokens) +// require.Equal(t, valTokens, issuedShares.RoundInt()) +// +// validator = TestingUpdateValidator(keeper, ctx, validator, true) +// require.True(t, validator.IsBonded()) +// val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) +// +// selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) +// keeper.SetDelegation(ctx, selfDelegation) +// +// // create a second delegation to this validator +// keeper.DeleteValidatorByPowerIndex(ctx, validator) +// validator, issuedShares = validator.AddTokensFromDel(delTokens) +// require.Equal(t, delTokens, issuedShares.RoundInt()) +// +// bondedPool := keeper.GetBondedPool(ctx) +// oldBonded := bk.GetAllBalances(ctx, bondedPool.GetAddress()) +// err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) +// require.NoError(t, err) +// keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) +// +// validator = TestingUpdateValidator(keeper, ctx, validator, true) +// require.True(t, validator.IsBonded()) +// +// delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) +// keeper.SetDelegation(ctx, delegation) +// +// ctx = ctx.WithBlockHeight(10) +// ctx = ctx.WithBlockTime(time.Unix(333, 0)) +// +// // unbond the all self-delegation to put validator in unbonding state +// _, err = keeper.Undelegate(ctx, val0AccAddr, addrVals[0], valTokens.ToDec()) +// require.NoError(t, err) +// +// // end block +// updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) +// require.Equal(t, 1, len(updates)) +// +// // unbond all the remaining delegation +// _, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], delTokens.ToDec()) +// require.NoError(t, err) +// +// // validator should still be in state and still be in unbonding state +// validator, found := keeper.GetValidator(ctx, addrVals[0]) +// require.True(t, found) +// require.Equal(t, validator.Status, sdk.Unbonding) +// +// // unbond the validator +// ctx = ctx.WithBlockTime(validator.UnbondingTime) +// keeper.UnbondAllMatureValidatorQueue(ctx) +// +// // validator should now be deleted from state +// _, found = keeper.GetValidator(ctx, addrVals[0]) +// require.False(t, found) +//} +// +//// Make sure that that the retrieving the delegations doesn't affect the state +//func TestGetRedelegationsFromSrcValidator(t *testing.T) { +// ctx, _, _, keeper, _ := CreateTestInput(t, false, 0) +// +// rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 0, +// time.Unix(0, 0), sdk.NewInt(5), +// sdk.NewDec(5)) +// +// // set and retrieve a record +// keeper.SetRedelegation(ctx, rd) +// resBond, found := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) +// require.True(t, found) +// +// // get the redelegations one time +// redelegations := keeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0]) +// require.Equal(t, 1, len(redelegations)) +// require.True(t, redelegations[0].Equal(resBond)) +// +// // get the redelegations a second time, should be exactly the same +// redelegations = keeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0]) +// require.Equal(t, 1, len(redelegations)) +// require.True(t, redelegations[0].Equal(resBond)) +//} +// +//// tests Get/Set/Remove/Has UnbondingDelegation +//func TestRedelegation(t *testing.T) { +// ctx, _, _, keeper, _ := CreateTestInput(t, false, 0) +// +// rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 0, +// time.Unix(0, 0), sdk.NewInt(5), +// sdk.NewDec(5)) +// +// // test shouldn't have and redelegations +// has := keeper.HasReceivingRedelegation(ctx, addrDels[0], addrVals[1]) +// require.False(t, has) +// +// // set and retrieve a record +// keeper.SetRedelegation(ctx, rd) +// resRed, found := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) +// require.True(t, found) +// +// redelegations := keeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0]) +// require.Equal(t, 1, len(redelegations)) +// require.True(t, redelegations[0].Equal(resRed)) +// +// redelegations = keeper.GetRedelegations(ctx, addrDels[0], 5) +// require.Equal(t, 1, len(redelegations)) +// require.True(t, redelegations[0].Equal(resRed)) +// +// redelegations = keeper.GetAllRedelegations(ctx, addrDels[0], nil, nil) +// require.Equal(t, 1, len(redelegations)) +// require.True(t, redelegations[0].Equal(resRed)) +// +// // check if has the redelegation +// has = keeper.HasReceivingRedelegation(ctx, addrDels[0], addrVals[1]) +// require.True(t, has) +// +// // modify a records, save, and retrieve +// rd.Entries[0].SharesDst = sdk.NewDec(21) +// keeper.SetRedelegation(ctx, rd) +// +// resRed, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) +// require.True(t, found) +// require.True(t, rd.Equal(resRed)) +// +// redelegations = keeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0]) +// require.Equal(t, 1, len(redelegations)) +// require.True(t, redelegations[0].Equal(resRed)) +// +// redelegations = keeper.GetRedelegations(ctx, addrDels[0], 5) +// require.Equal(t, 1, len(redelegations)) +// require.True(t, redelegations[0].Equal(resRed)) +// +// // delete a record +// keeper.RemoveRedelegation(ctx, rd) +// _, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) +// require.False(t, found) +// +// redelegations = keeper.GetRedelegations(ctx, addrDels[0], 5) +// require.Equal(t, 0, len(redelegations)) +// +// redelegations = keeper.GetAllRedelegations(ctx, addrDels[0], nil, nil) +// require.Equal(t, 0, len(redelegations)) +//} +// +//func TestRedelegateToSameValidator(t *testing.T) { +// ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) +// valTokens := sdk.TokensFromConsensusPower(10) +// startCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), valTokens)) +// +// // add bonded tokens to pool for delegations +// notBondedPool := keeper.GetNotBondedPool(ctx) +// oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) +// err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(startCoins...)) +// require.NoError(t, err) +// keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) +// +// // create a validator with a self-delegation +// validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) +// validator, issuedShares := validator.AddTokensFromDel(valTokens) +// require.Equal(t, valTokens, issuedShares.RoundInt()) +// validator = TestingUpdateValidator(keeper, ctx, validator, true) +// require.True(t, validator.IsBonded()) +// +// val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) +// selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) +// keeper.SetDelegation(ctx, selfDelegation) +// +// _, err = keeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[0], sdk.NewDec(5)) +// require.Error(t, err) +//} +// +//func TestRedelegationMaxEntries(t *testing.T) { +// ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) +// startTokens := sdk.TokensFromConsensusPower(20) +// startCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), startTokens)) +// +// // add bonded tokens to pool for delegations +// notBondedPool := keeper.GetNotBondedPool(ctx) +// oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) +// err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(startCoins...)) +// require.NoError(t, err) +// keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) +// +// // create a validator with a self-delegation +// validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) +// valTokens := sdk.TokensFromConsensusPower(10) +// validator, issuedShares := validator.AddTokensFromDel(valTokens) +// require.Equal(t, valTokens, issuedShares.RoundInt()) +// validator = TestingUpdateValidator(keeper, ctx, validator, true) +// val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) +// selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) +// keeper.SetDelegation(ctx, selfDelegation) +// +// // create a second validator +// validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{}) +// validator2, issuedShares = validator2.AddTokensFromDel(valTokens) +// require.Equal(t, valTokens, issuedShares.RoundInt()) +// +// validator2 = TestingUpdateValidator(keeper, ctx, validator2, true) +// require.Equal(t, sdk.Bonded, validator2.Status) +// +// maxEntries := keeper.MaxEntries(ctx) +// +// // redelegations should pass +// var completionTime time.Time +// for i := uint32(0); i < maxEntries; i++ { +// var err error +// completionTime, err = keeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], sdk.NewDec(1)) +// require.NoError(t, err) +// } +// +// // an additional redelegation should fail due to max entries +// _, err = keeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], sdk.NewDec(1)) +// require.Error(t, err) +// +// // mature redelegations +// ctx = ctx.WithBlockTime(completionTime) +// err = keeper.CompleteRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1]) +// require.NoError(t, err) +// +// // redelegation should work again +// _, err = keeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], sdk.NewDec(1)) +// require.NoError(t, err) +//} +// +//func TestRedelegateSelfDelegation(t *testing.T) { +// ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) +// startTokens := sdk.TokensFromConsensusPower(30) +// startCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), startTokens)) +// +// // add bonded tokens to pool for delegations +// notBondedPool := keeper.GetNotBondedPool(ctx) +// oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) +// err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(startCoins...)) +// require.NoError(t, err) +// keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) +// +// //create a validator with a self-delegation +// validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) +// valTokens := sdk.TokensFromConsensusPower(10) +// validator, issuedShares := validator.AddTokensFromDel(valTokens) +// require.Equal(t, valTokens, issuedShares.RoundInt()) +// +// validator = TestingUpdateValidator(keeper, ctx, validator, true) +// +// val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) +// selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) +// keeper.SetDelegation(ctx, selfDelegation) +// +// // create a second validator +// validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{}) +// validator2, issuedShares = validator2.AddTokensFromDel(valTokens) +// require.Equal(t, valTokens, issuedShares.RoundInt()) +// validator2 = TestingUpdateValidator(keeper, ctx, validator2, true) +// require.Equal(t, sdk.Bonded, validator2.Status) +// +// // create a second delegation to validator 1 +// delTokens := sdk.TokensFromConsensusPower(10) +// validator, issuedShares = validator.AddTokensFromDel(delTokens) +// require.Equal(t, delTokens, issuedShares.RoundInt()) +// validator = TestingUpdateValidator(keeper, ctx, validator, true) +// +// delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) +// keeper.SetDelegation(ctx, delegation) +// +// _, err = keeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], delTokens.ToDec()) +// require.NoError(t, err) +// +// // end block +// updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) +// require.Equal(t, 2, len(updates)) +// +// validator, found := keeper.GetValidator(ctx, addrVals[0]) +// require.True(t, found) +// require.Equal(t, valTokens, validator.Tokens) +// require.Equal(t, sdk.Unbonding, validator.Status) +//} +// +//func TestRedelegateFromUnbondingValidator(t *testing.T) { +// ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) +// startTokens := sdk.TokensFromConsensusPower(30) +// startCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), startTokens)) +// +// // add bonded tokens to pool for delegations +// notBondedPool := keeper.GetNotBondedPool(ctx) +// oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) +// err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(startCoins...)) +// require.NoError(t, err) +// keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) +// +// //create a validator with a self-delegation +// validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) +// +// valTokens := sdk.TokensFromConsensusPower(10) +// validator, issuedShares := validator.AddTokensFromDel(valTokens) +// require.Equal(t, valTokens, issuedShares.RoundInt()) +// validator = TestingUpdateValidator(keeper, ctx, validator, true) +// val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) +// selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) +// keeper.SetDelegation(ctx, selfDelegation) +// +// // create a second delegation to this validator +// keeper.DeleteValidatorByPowerIndex(ctx, validator) +// delTokens := sdk.TokensFromConsensusPower(10) +// validator, issuedShares = validator.AddTokensFromDel(delTokens) +// require.Equal(t, delTokens, issuedShares.RoundInt()) +// validator = TestingUpdateValidator(keeper, ctx, validator, true) +// delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) +// keeper.SetDelegation(ctx, delegation) +// +// // create a second validator +// validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{}) +// validator2, issuedShares = validator2.AddTokensFromDel(valTokens) +// require.Equal(t, valTokens, issuedShares.RoundInt()) +// validator2 = TestingUpdateValidator(keeper, ctx, validator2, true) +// +// header := ctx.BlockHeader() +// blockHeight := int64(10) +// header.Height = blockHeight +// blockTime := time.Unix(333, 0) +// header.Time = blockTime +// ctx = ctx.WithBlockHeader(header) +// +// // unbond the all self-delegation to put validator in unbonding state +// _, err = keeper.Undelegate(ctx, val0AccAddr, addrVals[0], delTokens.ToDec()) +// require.NoError(t, err) +// +// // end block +// updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) +// require.Equal(t, 1, len(updates)) +// +// validator, found := keeper.GetValidator(ctx, addrVals[0]) +// require.True(t, found) +// require.Equal(t, blockHeight, validator.UnbondingHeight) +// params := keeper.GetParams(ctx) +// require.True(t, blockTime.Add(params.UnbondingTime).Equal(validator.UnbondingTime)) +// +// //change the context +// header = ctx.BlockHeader() +// blockHeight2 := int64(20) +// header.Height = blockHeight2 +// blockTime2 := time.Unix(444, 0) +// header.Time = blockTime2 +// ctx = ctx.WithBlockHeader(header) +// +// // unbond some of the other delegation's shares +// redelegateTokens := sdk.TokensFromConsensusPower(6) +// _, err = keeper.BeginRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1], redelegateTokens.ToDec()) +// require.NoError(t, err) +// +// // retrieve the unbonding delegation +// ubd, found := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) +// require.True(t, found) +// require.Len(t, ubd.Entries, 1) +// assert.Equal(t, blockHeight, ubd.Entries[0].CreationHeight) +// assert.True(t, blockTime.Add(params.UnbondingTime).Equal(ubd.Entries[0].CompletionTime)) +//} +// +//func TestRedelegateFromUnbondedValidator(t *testing.T) { +// ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) +// startTokens := sdk.TokensFromConsensusPower(30) +// startCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), startTokens)) +// +// // add bonded tokens to pool for delegations +// notBondedPool := keeper.GetNotBondedPool(ctx) +// oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) +// err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(startCoins...)) +// require.NoError(t, err) +// keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) +// +// //create a validator with a self-delegation +// validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) +// +// valTokens := sdk.TokensFromConsensusPower(10) +// validator, issuedShares := validator.AddTokensFromDel(valTokens) +// require.Equal(t, valTokens, issuedShares.RoundInt()) +// validator = TestingUpdateValidator(keeper, ctx, validator, true) +// val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) +// selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) +// keeper.SetDelegation(ctx, selfDelegation) +// +// // create a second delegation to this validator +// keeper.DeleteValidatorByPowerIndex(ctx, validator) +// delTokens := sdk.TokensFromConsensusPower(10) +// validator, issuedShares = validator.AddTokensFromDel(delTokens) +// require.Equal(t, delTokens, issuedShares.RoundInt()) +// validator = TestingUpdateValidator(keeper, ctx, validator, true) +// delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) +// keeper.SetDelegation(ctx, delegation) +// +// // create a second validator +// validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{}) +// validator2, issuedShares = validator2.AddTokensFromDel(valTokens) +// require.Equal(t, valTokens, issuedShares.RoundInt()) +// validator2 = TestingUpdateValidator(keeper, ctx, validator2, true) +// require.Equal(t, sdk.Bonded, validator2.Status) +// +// ctx = ctx.WithBlockHeight(10) +// ctx = ctx.WithBlockTime(time.Unix(333, 0)) +// +// // unbond the all self-delegation to put validator in unbonding state +// _, err = keeper.Undelegate(ctx, val0AccAddr, addrVals[0], delTokens.ToDec()) +// require.NoError(t, err) +// +// // end block +// updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) +// require.Equal(t, 1, len(updates)) +// +// validator, found := keeper.GetValidator(ctx, addrVals[0]) +// require.True(t, found) +// require.Equal(t, ctx.BlockHeight(), validator.UnbondingHeight) +// params := keeper.GetParams(ctx) +// require.True(t, ctx.BlockHeader().Time.Add(params.UnbondingTime).Equal(validator.UnbondingTime)) +// +// // unbond the validator +// keeper.unbondingToUnbonded(ctx, validator) +// +// // redelegate some of the delegation's shares +// redelegationTokens := sdk.TokensFromConsensusPower(6) +// _, err = keeper.BeginRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1], redelegationTokens.ToDec()) +// require.NoError(t, err) +// +// // no red should have been found +// red, found := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) +// require.False(t, found, "%v", red) +//} diff --git a/x/staking/keeper/old_delegation_test.go b/x/staking/keeper/old_delegation_test.go new file mode 100644 index 000000000000..2c83dd757774 --- /dev/null +++ b/x/staking/keeper/old_delegation_test.go @@ -0,0 +1,765 @@ +package keeper + +import ( + "testing" + "time" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/staking/types" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestUnbondingDelegationsMaxEntries(t *testing.T) { + ctx, _, bk, keeper, _ := CreateTestInput(t, false, 1) + startTokens := sdk.TokensFromConsensusPower(10) + + bondDenom := keeper.BondDenom(ctx) + notBondedPool := keeper.GetNotBondedPool(ctx) + + err := bk.SetBalances(ctx, notBondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(bondDenom, startTokens))) + require.NoError(t, err) + keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) + + // create a validator and a delegator to that validator + validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) + + validator, issuedShares := validator.AddTokensFromDel(startTokens) + require.Equal(t, startTokens, issuedShares.RoundInt()) + + validator = TestingUpdateValidator(keeper, ctx, validator, true) + require.True(sdk.IntEq(t, startTokens, validator.BondedTokens())) + require.True(t, validator.IsBonded()) + + delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) + keeper.SetDelegation(ctx, delegation) + + maxEntries := keeper.MaxEntries(ctx) + + oldBonded := bk.GetBalance(ctx, keeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount + oldNotBonded := bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount + + // should all pass + var completionTime time.Time + for i := uint32(0); i < maxEntries; i++ { + var err error + completionTime, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], sdk.NewDec(1)) + require.NoError(t, err) + } + + newBonded := bk.GetBalance(ctx, keeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount + newNotBonded := bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount + require.True(sdk.IntEq(t, newBonded, oldBonded.SubRaw(int64(maxEntries)))) + require.True(sdk.IntEq(t, newNotBonded, oldNotBonded.AddRaw(int64(maxEntries)))) + + oldBonded = bk.GetBalance(ctx, keeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount + oldNotBonded = bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount + + // an additional unbond should fail due to max entries + _, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], sdk.NewDec(1)) + require.Error(t, err) + + newBonded = bk.GetBalance(ctx, keeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount + newNotBonded = bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount + + require.True(sdk.IntEq(t, newBonded, oldBonded)) + require.True(sdk.IntEq(t, newNotBonded, oldNotBonded)) + + // mature unbonding delegations + ctx = ctx.WithBlockTime(completionTime) + err = keeper.CompleteUnbonding(ctx, addrDels[0], addrVals[0]) + require.NoError(t, err) + + newBonded = bk.GetBalance(ctx, keeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount + newNotBonded = bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount + require.True(sdk.IntEq(t, newBonded, oldBonded)) + require.True(sdk.IntEq(t, newNotBonded, oldNotBonded.SubRaw(int64(maxEntries)))) + + oldNotBonded = bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount + + // unbonding should work again + _, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], sdk.NewDec(1)) + require.NoError(t, err) + + newBonded = bk.GetBalance(ctx, keeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount + newNotBonded = bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount + require.True(sdk.IntEq(t, newBonded, oldBonded.SubRaw(1))) + require.True(sdk.IntEq(t, newNotBonded, oldNotBonded.AddRaw(1))) +} + +// test undelegating self delegation from a validator pushing it below MinSelfDelegation +// shift it from the bonded to unbonding state and jailed +func TestUndelegateSelfDelegationBelowMinSelfDelegation(t *testing.T) { + ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) + delTokens := sdk.TokensFromConsensusPower(10) + delCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), delTokens)) + + //create a validator with a self-delegation + validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) + + validator.MinSelfDelegation = delTokens + validator, issuedShares := validator.AddTokensFromDel(delTokens) + require.Equal(t, delTokens, issuedShares.RoundInt()) + + // add bonded tokens to pool for delegations + notBondedPool := keeper.GetNotBondedPool(ctx) + oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) + err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(delCoins...)) + require.NoError(t, err) + keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) + + validator = TestingUpdateValidator(keeper, ctx, validator, true) + require.True(t, validator.IsBonded()) + + selfDelegation := types.NewDelegation(sdk.AccAddress(addrVals[0].Bytes()), addrVals[0], issuedShares) + keeper.SetDelegation(ctx, selfDelegation) + + // add bonded tokens to pool for delegations + bondedPool := keeper.GetBondedPool(ctx) + oldBonded := bk.GetAllBalances(ctx, bondedPool.GetAddress()) + err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) + require.NoError(t, err) + keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) + + // create a second delegation to this validator + keeper.DeleteValidatorByPowerIndex(ctx, validator) + validator, issuedShares = validator.AddTokensFromDel(delTokens) + require.True(t, validator.IsBonded()) + require.Equal(t, delTokens, issuedShares.RoundInt()) + + // add bonded tokens to pool for delegations + oldBonded = bk.GetAllBalances(ctx, bondedPool.GetAddress()) + err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) + require.NoError(t, err) + keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) + + validator = TestingUpdateValidator(keeper, ctx, validator, true) + delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) + keeper.SetDelegation(ctx, delegation) + + val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) + _, err = keeper.Undelegate(ctx, val0AccAddr, addrVals[0], sdk.TokensFromConsensusPower(6).ToDec()) + require.NoError(t, err) + + // end block + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 1, len(updates)) + + validator, found := keeper.GetValidator(ctx, addrVals[0]) + require.True(t, found) + require.Equal(t, sdk.TokensFromConsensusPower(14), validator.Tokens) + require.Equal(t, sdk.Unbonding, validator.Status) + require.True(t, validator.Jailed) +} + +func TestUndelegateFromUnbondingValidator(t *testing.T) { + ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) + delTokens := sdk.TokensFromConsensusPower(10) + delCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), delTokens)) + + //create a validator with a self-delegation + validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) + + validator, issuedShares := validator.AddTokensFromDel(delTokens) + require.Equal(t, delTokens, issuedShares.RoundInt()) + + // add bonded tokens to pool for delegations + notBondedPool := keeper.GetNotBondedPool(ctx) + oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) + err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(delCoins...)) + require.NoError(t, err) + keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) + + validator = TestingUpdateValidator(keeper, ctx, validator, true) + require.True(t, validator.IsBonded()) + + selfDelegation := types.NewDelegation(sdk.AccAddress(addrVals[0].Bytes()), addrVals[0], issuedShares) + keeper.SetDelegation(ctx, selfDelegation) + + bondedPool := keeper.GetBondedPool(ctx) + oldBonded := bk.GetAllBalances(ctx, bondedPool.GetAddress()) + err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) + require.NoError(t, err) + keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) + + // create a second delegation to this validator + keeper.DeleteValidatorByPowerIndex(ctx, validator) + + validator, issuedShares = validator.AddTokensFromDel(delTokens) + require.Equal(t, delTokens, issuedShares.RoundInt()) + + oldBonded = bk.GetAllBalances(ctx, bondedPool.GetAddress()) + err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) + require.NoError(t, err) + keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) + + validator = TestingUpdateValidator(keeper, ctx, validator, true) + delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) + keeper.SetDelegation(ctx, delegation) + + oldBonded = bk.GetAllBalances(ctx, bondedPool.GetAddress()) + err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) + require.NoError(t, err) + keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) + + header := ctx.BlockHeader() + blockHeight := int64(10) + header.Height = blockHeight + blockTime := time.Unix(333, 0) + header.Time = blockTime + ctx = ctx.WithBlockHeader(header) + + // unbond the all self-delegation to put validator in unbonding state + val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) + _, err = keeper.Undelegate(ctx, val0AccAddr, addrVals[0], delTokens.ToDec()) + require.NoError(t, err) + + // end block + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 1, len(updates)) + + validator, found := keeper.GetValidator(ctx, addrVals[0]) + require.True(t, found) + require.Equal(t, blockHeight, validator.UnbondingHeight) + params := keeper.GetParams(ctx) + require.True(t, blockTime.Add(params.UnbondingTime).Equal(validator.UnbondingTime)) + + blockHeight2 := int64(20) + blockTime2 := time.Unix(444, 0).UTC() + ctx = ctx.WithBlockHeight(blockHeight2) + ctx = ctx.WithBlockTime(blockTime2) + + // unbond some of the other delegation's shares + _, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], sdk.NewDec(6)) + require.NoError(t, err) + + // retrieve the unbonding delegation + ubd, found := keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) + require.True(t, found) + require.Len(t, ubd.Entries, 1) + require.True(t, ubd.Entries[0].Balance.Equal(sdk.NewInt(6))) + assert.Equal(t, blockHeight2, ubd.Entries[0].CreationHeight) + assert.True(t, blockTime2.Add(params.UnbondingTime).Equal(ubd.Entries[0].CompletionTime)) +} + +func TestUndelegateFromUnbondedValidator(t *testing.T) { + ctx, _, bk, keeper, _ := CreateTestInput(t, false, 1) + delTokens := sdk.TokensFromConsensusPower(10) + delCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), delTokens)) + + // add bonded tokens to pool for delegations + notBondedPool := keeper.GetNotBondedPool(ctx) + oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) + err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(delCoins...)) + require.NoError(t, err) + keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) + + // create a validator with a self-delegation + validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) + + valTokens := sdk.TokensFromConsensusPower(10) + validator, issuedShares := validator.AddTokensFromDel(valTokens) + require.Equal(t, valTokens, issuedShares.RoundInt()) + validator = TestingUpdateValidator(keeper, ctx, validator, true) + require.True(t, validator.IsBonded()) + + val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) + selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) + keeper.SetDelegation(ctx, selfDelegation) + + bondedPool := keeper.GetBondedPool(ctx) + oldBonded := bk.GetAllBalances(ctx, bondedPool.GetAddress()) + err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) + require.NoError(t, err) + keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) + + // create a second delegation to this validator + keeper.DeleteValidatorByPowerIndex(ctx, validator) + validator, issuedShares = validator.AddTokensFromDel(delTokens) + require.Equal(t, delTokens, issuedShares.RoundInt()) + validator = TestingUpdateValidator(keeper, ctx, validator, true) + require.True(t, validator.IsBonded()) + delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) + keeper.SetDelegation(ctx, delegation) + + ctx = ctx.WithBlockHeight(10) + ctx = ctx.WithBlockTime(time.Unix(333, 0)) + + // unbond the all self-delegation to put validator in unbonding state + _, err = keeper.Undelegate(ctx, val0AccAddr, addrVals[0], valTokens.ToDec()) + require.NoError(t, err) + + // end block + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 1, len(updates)) + + validator, found := keeper.GetValidator(ctx, addrVals[0]) + require.True(t, found) + require.Equal(t, ctx.BlockHeight(), validator.UnbondingHeight) + params := keeper.GetParams(ctx) + require.True(t, ctx.BlockHeader().Time.Add(params.UnbondingTime).Equal(validator.UnbondingTime)) + + // unbond the validator + ctx = ctx.WithBlockTime(validator.UnbondingTime) + keeper.UnbondAllMatureValidatorQueue(ctx) + + // Make sure validator is still in state because there is still an outstanding delegation + validator, found = keeper.GetValidator(ctx, addrVals[0]) + require.True(t, found) + require.Equal(t, validator.Status, sdk.Unbonded) + + // unbond some of the other delegation's shares + unbondTokens := sdk.TokensFromConsensusPower(6) + _, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], unbondTokens.ToDec()) + require.NoError(t, err) + + // unbond rest of the other delegation's shares + remainingTokens := delTokens.Sub(unbondTokens) + _, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], remainingTokens.ToDec()) + require.NoError(t, err) + + // now validator should now be deleted from state + validator, found = keeper.GetValidator(ctx, addrVals[0]) + require.False(t, found, "%v", validator) +} + +func TestUnbondingAllDelegationFromValidator(t *testing.T) { + ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) + delTokens := sdk.TokensFromConsensusPower(10) + delCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), delTokens)) + + // add bonded tokens to pool for delegations + notBondedPool := keeper.GetNotBondedPool(ctx) + oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) + err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(delCoins...)) + require.NoError(t, err) + keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) + + //create a validator with a self-delegation + validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) + + valTokens := sdk.TokensFromConsensusPower(10) + validator, issuedShares := validator.AddTokensFromDel(valTokens) + require.Equal(t, valTokens, issuedShares.RoundInt()) + + validator = TestingUpdateValidator(keeper, ctx, validator, true) + require.True(t, validator.IsBonded()) + val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) + + selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) + keeper.SetDelegation(ctx, selfDelegation) + + // create a second delegation to this validator + keeper.DeleteValidatorByPowerIndex(ctx, validator) + validator, issuedShares = validator.AddTokensFromDel(delTokens) + require.Equal(t, delTokens, issuedShares.RoundInt()) + + bondedPool := keeper.GetBondedPool(ctx) + oldBonded := bk.GetAllBalances(ctx, bondedPool.GetAddress()) + err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) + require.NoError(t, err) + keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) + + validator = TestingUpdateValidator(keeper, ctx, validator, true) + require.True(t, validator.IsBonded()) + + delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) + keeper.SetDelegation(ctx, delegation) + + ctx = ctx.WithBlockHeight(10) + ctx = ctx.WithBlockTime(time.Unix(333, 0)) + + // unbond the all self-delegation to put validator in unbonding state + _, err = keeper.Undelegate(ctx, val0AccAddr, addrVals[0], valTokens.ToDec()) + require.NoError(t, err) + + // end block + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 1, len(updates)) + + // unbond all the remaining delegation + _, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], delTokens.ToDec()) + require.NoError(t, err) + + // validator should still be in state and still be in unbonding state + validator, found := keeper.GetValidator(ctx, addrVals[0]) + require.True(t, found) + require.Equal(t, validator.Status, sdk.Unbonding) + + // unbond the validator + ctx = ctx.WithBlockTime(validator.UnbondingTime) + keeper.UnbondAllMatureValidatorQueue(ctx) + + // validator should now be deleted from state + _, found = keeper.GetValidator(ctx, addrVals[0]) + require.False(t, found) +} + +// Make sure that that the retrieving the delegations doesn't affect the state +func TestGetRedelegationsFromSrcValidator(t *testing.T) { + ctx, _, _, keeper, _ := CreateTestInput(t, false, 0) + + rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 0, + time.Unix(0, 0), sdk.NewInt(5), + sdk.NewDec(5)) + + // set and retrieve a record + keeper.SetRedelegation(ctx, rd) + resBond, found := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) + require.True(t, found) + + // get the redelegations one time + redelegations := keeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0]) + require.Equal(t, 1, len(redelegations)) + require.True(t, redelegations[0].Equal(resBond)) + + // get the redelegations a second time, should be exactly the same + redelegations = keeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0]) + require.Equal(t, 1, len(redelegations)) + require.True(t, redelegations[0].Equal(resBond)) +} + +// tests Get/Set/Remove/Has UnbondingDelegation +func TestRedelegation(t *testing.T) { + ctx, _, _, keeper, _ := CreateTestInput(t, false, 0) + + rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 0, + time.Unix(0, 0), sdk.NewInt(5), + sdk.NewDec(5)) + + // test shouldn't have and redelegations + has := keeper.HasReceivingRedelegation(ctx, addrDels[0], addrVals[1]) + require.False(t, has) + + // set and retrieve a record + keeper.SetRedelegation(ctx, rd) + resRed, found := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) + require.True(t, found) + + redelegations := keeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0]) + require.Equal(t, 1, len(redelegations)) + require.True(t, redelegations[0].Equal(resRed)) + + redelegations = keeper.GetRedelegations(ctx, addrDels[0], 5) + require.Equal(t, 1, len(redelegations)) + require.True(t, redelegations[0].Equal(resRed)) + + redelegations = keeper.GetAllRedelegations(ctx, addrDels[0], nil, nil) + require.Equal(t, 1, len(redelegations)) + require.True(t, redelegations[0].Equal(resRed)) + + // check if has the redelegation + has = keeper.HasReceivingRedelegation(ctx, addrDels[0], addrVals[1]) + require.True(t, has) + + // modify a records, save, and retrieve + rd.Entries[0].SharesDst = sdk.NewDec(21) + keeper.SetRedelegation(ctx, rd) + + resRed, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) + require.True(t, found) + require.True(t, rd.Equal(resRed)) + + redelegations = keeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0]) + require.Equal(t, 1, len(redelegations)) + require.True(t, redelegations[0].Equal(resRed)) + + redelegations = keeper.GetRedelegations(ctx, addrDels[0], 5) + require.Equal(t, 1, len(redelegations)) + require.True(t, redelegations[0].Equal(resRed)) + + // delete a record + keeper.RemoveRedelegation(ctx, rd) + _, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) + require.False(t, found) + + redelegations = keeper.GetRedelegations(ctx, addrDels[0], 5) + require.Equal(t, 0, len(redelegations)) + + redelegations = keeper.GetAllRedelegations(ctx, addrDels[0], nil, nil) + require.Equal(t, 0, len(redelegations)) +} + +func TestRedelegateToSameValidator(t *testing.T) { + ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) + valTokens := sdk.TokensFromConsensusPower(10) + startCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), valTokens)) + + // add bonded tokens to pool for delegations + notBondedPool := keeper.GetNotBondedPool(ctx) + oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) + err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(startCoins...)) + require.NoError(t, err) + keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) + + // create a validator with a self-delegation + validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) + validator, issuedShares := validator.AddTokensFromDel(valTokens) + require.Equal(t, valTokens, issuedShares.RoundInt()) + validator = TestingUpdateValidator(keeper, ctx, validator, true) + require.True(t, validator.IsBonded()) + + val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) + selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) + keeper.SetDelegation(ctx, selfDelegation) + + _, err = keeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[0], sdk.NewDec(5)) + require.Error(t, err) +} + +func TestRedelegationMaxEntries(t *testing.T) { + ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) + startTokens := sdk.TokensFromConsensusPower(20) + startCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), startTokens)) + + // add bonded tokens to pool for delegations + notBondedPool := keeper.GetNotBondedPool(ctx) + oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) + err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(startCoins...)) + require.NoError(t, err) + keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) + + // create a validator with a self-delegation + validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) + valTokens := sdk.TokensFromConsensusPower(10) + validator, issuedShares := validator.AddTokensFromDel(valTokens) + require.Equal(t, valTokens, issuedShares.RoundInt()) + validator = TestingUpdateValidator(keeper, ctx, validator, true) + val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) + selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) + keeper.SetDelegation(ctx, selfDelegation) + + // create a second validator + validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{}) + validator2, issuedShares = validator2.AddTokensFromDel(valTokens) + require.Equal(t, valTokens, issuedShares.RoundInt()) + + validator2 = TestingUpdateValidator(keeper, ctx, validator2, true) + require.Equal(t, sdk.Bonded, validator2.Status) + + maxEntries := keeper.MaxEntries(ctx) + + // redelegations should pass + var completionTime time.Time + for i := uint32(0); i < maxEntries; i++ { + var err error + completionTime, err = keeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], sdk.NewDec(1)) + require.NoError(t, err) + } + + // an additional redelegation should fail due to max entries + _, err = keeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], sdk.NewDec(1)) + require.Error(t, err) + + // mature redelegations + ctx = ctx.WithBlockTime(completionTime) + err = keeper.CompleteRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1]) + require.NoError(t, err) + + // redelegation should work again + _, err = keeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], sdk.NewDec(1)) + require.NoError(t, err) +} + +func TestRedelegateSelfDelegation(t *testing.T) { + ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) + startTokens := sdk.TokensFromConsensusPower(30) + startCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), startTokens)) + + // add bonded tokens to pool for delegations + notBondedPool := keeper.GetNotBondedPool(ctx) + oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) + err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(startCoins...)) + require.NoError(t, err) + keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) + + //create a validator with a self-delegation + validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) + valTokens := sdk.TokensFromConsensusPower(10) + validator, issuedShares := validator.AddTokensFromDel(valTokens) + require.Equal(t, valTokens, issuedShares.RoundInt()) + + validator = TestingUpdateValidator(keeper, ctx, validator, true) + + val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) + selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) + keeper.SetDelegation(ctx, selfDelegation) + + // create a second validator + validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{}) + validator2, issuedShares = validator2.AddTokensFromDel(valTokens) + require.Equal(t, valTokens, issuedShares.RoundInt()) + validator2 = TestingUpdateValidator(keeper, ctx, validator2, true) + require.Equal(t, sdk.Bonded, validator2.Status) + + // create a second delegation to validator 1 + delTokens := sdk.TokensFromConsensusPower(10) + validator, issuedShares = validator.AddTokensFromDel(delTokens) + require.Equal(t, delTokens, issuedShares.RoundInt()) + validator = TestingUpdateValidator(keeper, ctx, validator, true) + + delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) + keeper.SetDelegation(ctx, delegation) + + _, err = keeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], delTokens.ToDec()) + require.NoError(t, err) + + // end block + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 2, len(updates)) + + validator, found := keeper.GetValidator(ctx, addrVals[0]) + require.True(t, found) + require.Equal(t, valTokens, validator.Tokens) + require.Equal(t, sdk.Unbonding, validator.Status) +} + +func TestRedelegateFromUnbondingValidator(t *testing.T) { + ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) + startTokens := sdk.TokensFromConsensusPower(30) + startCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), startTokens)) + + // add bonded tokens to pool for delegations + notBondedPool := keeper.GetNotBondedPool(ctx) + oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) + err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(startCoins...)) + require.NoError(t, err) + keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) + + //create a validator with a self-delegation + validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) + + valTokens := sdk.TokensFromConsensusPower(10) + validator, issuedShares := validator.AddTokensFromDel(valTokens) + require.Equal(t, valTokens, issuedShares.RoundInt()) + validator = TestingUpdateValidator(keeper, ctx, validator, true) + val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) + selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) + keeper.SetDelegation(ctx, selfDelegation) + + // create a second delegation to this validator + keeper.DeleteValidatorByPowerIndex(ctx, validator) + delTokens := sdk.TokensFromConsensusPower(10) + validator, issuedShares = validator.AddTokensFromDel(delTokens) + require.Equal(t, delTokens, issuedShares.RoundInt()) + validator = TestingUpdateValidator(keeper, ctx, validator, true) + delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) + keeper.SetDelegation(ctx, delegation) + + // create a second validator + validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{}) + validator2, issuedShares = validator2.AddTokensFromDel(valTokens) + require.Equal(t, valTokens, issuedShares.RoundInt()) + validator2 = TestingUpdateValidator(keeper, ctx, validator2, true) + + header := ctx.BlockHeader() + blockHeight := int64(10) + header.Height = blockHeight + blockTime := time.Unix(333, 0) + header.Time = blockTime + ctx = ctx.WithBlockHeader(header) + + // unbond the all self-delegation to put validator in unbonding state + _, err = keeper.Undelegate(ctx, val0AccAddr, addrVals[0], delTokens.ToDec()) + require.NoError(t, err) + + // end block + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 1, len(updates)) + + validator, found := keeper.GetValidator(ctx, addrVals[0]) + require.True(t, found) + require.Equal(t, blockHeight, validator.UnbondingHeight) + params := keeper.GetParams(ctx) + require.True(t, blockTime.Add(params.UnbondingTime).Equal(validator.UnbondingTime)) + + //change the context + header = ctx.BlockHeader() + blockHeight2 := int64(20) + header.Height = blockHeight2 + blockTime2 := time.Unix(444, 0) + header.Time = blockTime2 + ctx = ctx.WithBlockHeader(header) + + // unbond some of the other delegation's shares + redelegateTokens := sdk.TokensFromConsensusPower(6) + _, err = keeper.BeginRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1], redelegateTokens.ToDec()) + require.NoError(t, err) + + // retrieve the unbonding delegation + ubd, found := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) + require.True(t, found) + require.Len(t, ubd.Entries, 1) + assert.Equal(t, blockHeight, ubd.Entries[0].CreationHeight) + assert.True(t, blockTime.Add(params.UnbondingTime).Equal(ubd.Entries[0].CompletionTime)) +} + +func TestRedelegateFromUnbondedValidator(t *testing.T) { + ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) + startTokens := sdk.TokensFromConsensusPower(30) + startCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), startTokens)) + + // add bonded tokens to pool for delegations + notBondedPool := keeper.GetNotBondedPool(ctx) + oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) + err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(startCoins...)) + require.NoError(t, err) + keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) + + //create a validator with a self-delegation + validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) + + valTokens := sdk.TokensFromConsensusPower(10) + validator, issuedShares := validator.AddTokensFromDel(valTokens) + require.Equal(t, valTokens, issuedShares.RoundInt()) + validator = TestingUpdateValidator(keeper, ctx, validator, true) + val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) + selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) + keeper.SetDelegation(ctx, selfDelegation) + + // create a second delegation to this validator + keeper.DeleteValidatorByPowerIndex(ctx, validator) + delTokens := sdk.TokensFromConsensusPower(10) + validator, issuedShares = validator.AddTokensFromDel(delTokens) + require.Equal(t, delTokens, issuedShares.RoundInt()) + validator = TestingUpdateValidator(keeper, ctx, validator, true) + delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) + keeper.SetDelegation(ctx, delegation) + + // create a second validator + validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{}) + validator2, issuedShares = validator2.AddTokensFromDel(valTokens) + require.Equal(t, valTokens, issuedShares.RoundInt()) + validator2 = TestingUpdateValidator(keeper, ctx, validator2, true) + require.Equal(t, sdk.Bonded, validator2.Status) + + ctx = ctx.WithBlockHeight(10) + ctx = ctx.WithBlockTime(time.Unix(333, 0)) + + // unbond the all self-delegation to put validator in unbonding state + _, err = keeper.Undelegate(ctx, val0AccAddr, addrVals[0], delTokens.ToDec()) + require.NoError(t, err) + + // end block + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 1, len(updates)) + + validator, found := keeper.GetValidator(ctx, addrVals[0]) + require.True(t, found) + require.Equal(t, ctx.BlockHeight(), validator.UnbondingHeight) + params := keeper.GetParams(ctx) + require.True(t, ctx.BlockHeader().Time.Add(params.UnbondingTime).Equal(validator.UnbondingTime)) + + // unbond the validator + keeper.unbondingToUnbonded(ctx, validator) + + // redelegate some of the delegation's shares + redelegationTokens := sdk.TokensFromConsensusPower(6) + _, err = keeper.BeginRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1], redelegationTokens.ToDec()) + require.NoError(t, err) + + // no red should have been found + red, found := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) + require.False(t, found, "%v", red) +} From 27ff208fb878dd27673721736ecce5f8d401d3f3 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Fri, 21 Feb 2020 18:34:03 +0100 Subject: [PATCH 13/90] make all test pass temporary --- x/staking/keeper/delegation.go | 6 +- x/staking/keeper/delegation_test.go | 81 +++++++++++++++---------- x/staking/keeper/keeper.go | 5 +- x/staking/keeper/old_delegation_test.go | 77 ----------------------- x/staking/keeper/querier_test.go | 10 +++ x/staking/keeper/slash.go | 2 +- 6 files changed, 66 insertions(+), 115 deletions(-) diff --git a/x/staking/keeper/delegation.go b/x/staking/keeper/delegation.go index 9524c4feffa8..8b61f8abbd4e 100644 --- a/x/staking/keeper/delegation.go +++ b/x/staking/keeper/delegation.go @@ -548,7 +548,7 @@ func (k Keeper) Delegate( } // unbond a particular delegation and perform associated store operations -func (k Keeper) unbond( +func (k Keeper) Unbond( ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, shares sdk.Dec, ) (amount sdk.Int, err error) { @@ -654,7 +654,7 @@ func (k Keeper) Undelegate( return time.Time{}, types.ErrMaxUnbondingDelegationEntries } - returnAmount, err := k.unbond(ctx, delAddr, valAddr, sharesAmount) + returnAmount, err := k.Unbond(ctx, delAddr, valAddr, sharesAmount) if err != nil { return time.Time{}, err } @@ -751,7 +751,7 @@ func (k Keeper) BeginRedelegation( return time.Time{}, types.ErrMaxRedelegationEntries } - returnAmount, err := k.unbond(ctx, delAddr, valSrcAddr, sharesAmount) + returnAmount, err := k.Unbond(ctx, delAddr, valSrcAddr, sharesAmount) if err != nil { return time.Time{}, err } diff --git a/x/staking/keeper/delegation_test.go b/x/staking/keeper/delegation_test.go index 798716b2c2d0..4f4b5e7beabf 100644 --- a/x/staking/keeper/delegation_test.go +++ b/x/staking/keeper/delegation_test.go @@ -4,7 +4,7 @@ import ( "testing" "time" - "github.com/cosmos/cosmos-sdk/x/distribution" + "github.com/cosmos/cosmos-sdk/x/staking" "github.com/stretchr/testify/require" @@ -34,7 +34,6 @@ func TestDelegation(t *testing.T) { validators[2] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[2], true) // first add a validators[0] to delegate too - bond1to1 := types.NewDelegation(addrDels[0], addrVals[0], sdk.NewDec(9)) // check the empty keeper first @@ -181,6 +180,15 @@ func TestUnbondDelegation(t *testing.T) { app := simapp.Setup(false) ctx := app.BaseApp.NewContext(false, abci.Header{}) + codec := simapp.NewAppCodec() + app.StakingKeeper = keeper.NewKeeper( + codec.Staking, + app.GetKey(staking.StoreKey), + app.BankKeeper, + app.SupplyKeeper, + app.GetSubspace(staking.ModuleName), + ) + startTokens := sdk.TokensFromConsensusPower(10) notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) @@ -204,15 +212,11 @@ func TestUnbondDelegation(t *testing.T) { delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) app.StakingKeeper.SetDelegation(ctx, delegation) - app.DistrKeeper.SetDelegatorStartingInfo(ctx, addrVals[0], addrDels[0], distribution.DelegatorStartingInfo{}) - app.DistrKeeper.SetValidatorHistoricalRewards(ctx, addrVals[0], 18446744073709551615, distribution.ValidatorHistoricalRewards{ReferenceCount: 1}) bondTokens := sdk.TokensFromConsensusPower(6) - _, err := app.StakingKeeper.Undelegate(ctx, addrDels[0], addrVals[0], bondTokens.ToDec()) + amount, err := app.StakingKeeper.Unbond(ctx, addrDels[0], addrVals[0], bondTokens.ToDec()) require.NoError(t, err) - - notBondedPoolBalance := app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), app.StakingKeeper.BondDenom(ctx)) - require.Equal(t, bondTokens, notBondedPoolBalance.Amount) // shares to be added to an unbonding delegation + require.Equal(t, bondTokens, amount) // shares to be added to an unbonding delegation delegation, found := app.StakingKeeper.GetDelegation(ctx, addrDels[0], addrVals[0]) require.True(t, found) @@ -225,15 +229,26 @@ func TestUnbondDelegation(t *testing.T) { } //func TestUnbondingDelegationsMaxEntries(t *testing.T) { -// ctx, _, bk, keeper, _ := CreateTestInput(t, false, 1) +// app := simapp.Setup(false) +// ctx := app.BaseApp.NewContext(false, abci.Header{}) +// +// codec := simapp.NewAppCodec() +// app.StakingKeeper = keeper.NewKeeper( +// codec.Staking, +// app.GetKey(staking.StoreKey), +// app.BankKeeper, +// app.SupplyKeeper, +// app.GetSubspace(staking.ModuleName), +// ) +// // startTokens := sdk.TokensFromConsensusPower(10) // -// bondDenom := keeper.BondDenom(ctx) -// notBondedPool := keeper.GetNotBondedPool(ctx) +// bondDenom := app.StakingKeeper.BondDenom(ctx) +// notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) // -// err := bk.SetBalances(ctx, notBondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(bondDenom, startTokens))) +// err := app.BankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(bondDenom, startTokens))) // require.NoError(t, err) -// keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) +// app.SupplyKeeper.SetModuleAccount(ctx, notBondedPool) // // // create a validator and a delegator to that validator // validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) @@ -241,62 +256,62 @@ func TestUnbondDelegation(t *testing.T) { // validator, issuedShares := validator.AddTokensFromDel(startTokens) // require.Equal(t, startTokens, issuedShares.RoundInt()) // -// validator = TestingUpdateValidator(keeper, ctx, validator, true) +// validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) // require.True(sdk.IntEq(t, startTokens, validator.BondedTokens())) // require.True(t, validator.IsBonded()) // // delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) -// keeper.SetDelegation(ctx, delegation) +// app.StakingKeeper.SetDelegation(ctx, delegation) // -// maxEntries := keeper.MaxEntries(ctx) +// maxEntries := app.StakingKeeper.MaxEntries(ctx) // -// oldBonded := bk.GetBalance(ctx, keeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount -// oldNotBonded := bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount +// oldBonded := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount +// oldNotBonded := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount // // // should all pass // var completionTime time.Time // for i := uint32(0); i < maxEntries; i++ { // var err error -// completionTime, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], sdk.NewDec(1)) +// completionTime, err = app.StakingKeeper.Undelegate(ctx, addrDels[0], addrVals[0], sdk.NewDec(1)) // require.NoError(t, err) // } // -// newBonded := bk.GetBalance(ctx, keeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount -// newNotBonded := bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount +// newBonded := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount +// newNotBonded := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount // require.True(sdk.IntEq(t, newBonded, oldBonded.SubRaw(int64(maxEntries)))) // require.True(sdk.IntEq(t, newNotBonded, oldNotBonded.AddRaw(int64(maxEntries)))) // -// oldBonded = bk.GetBalance(ctx, keeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount -// oldNotBonded = bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount +// oldBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount +// oldNotBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount // // // an additional unbond should fail due to max entries -// _, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], sdk.NewDec(1)) +// _, err = app.StakingKeeper.Undelegate(ctx, addrDels[0], addrVals[0], sdk.NewDec(1)) // require.Error(t, err) // -// newBonded = bk.GetBalance(ctx, keeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount -// newNotBonded = bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount +// newBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount +// newNotBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount // // require.True(sdk.IntEq(t, newBonded, oldBonded)) // require.True(sdk.IntEq(t, newNotBonded, oldNotBonded)) // // // mature unbonding delegations // ctx = ctx.WithBlockTime(completionTime) -// err = keeper.CompleteUnbonding(ctx, addrDels[0], addrVals[0]) +// err = app.StakingKeeper.CompleteUnbonding(ctx, addrDels[0], addrVals[0]) // require.NoError(t, err) // -// newBonded = bk.GetBalance(ctx, keeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount -// newNotBonded = bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount +// newBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount +// newNotBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount // require.True(sdk.IntEq(t, newBonded, oldBonded)) // require.True(sdk.IntEq(t, newNotBonded, oldNotBonded.SubRaw(int64(maxEntries)))) // -// oldNotBonded = bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount +// oldNotBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount // // // unbonding should work again -// _, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], sdk.NewDec(1)) +// _, err = app.StakingKeeper.Undelegate(ctx, addrDels[0], addrVals[0], sdk.NewDec(1)) // require.NoError(t, err) // -// newBonded = bk.GetBalance(ctx, keeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount -// newNotBonded = bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount +// newBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount +// newNotBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount // require.True(sdk.IntEq(t, newBonded, oldBonded.SubRaw(1))) // require.True(sdk.IntEq(t, newNotBonded, oldNotBonded.AddRaw(1))) //} diff --git a/x/staking/keeper/keeper.go b/x/staking/keeper/keeper.go index ef7aab43557f..80fbf6191999 100644 --- a/x/staking/keeper/keeper.go +++ b/x/staking/keeper/keeper.go @@ -36,6 +36,9 @@ type Keeper struct { func NewKeeper( cdc codec.Marshaler, key sdk.StoreKey, bk types.BankKeeper, sk types.SupplyKeeper, ps params.Subspace, ) Keeper { + if !ps.HasKeyTable() { + ps = ps.WithKeyTable(ParamKeyTable()) + } // ensure bonded and not bonded module accounts are set if addr := sk.GetModuleAddress(types.BondedPoolName); addr == nil { @@ -51,7 +54,7 @@ func NewKeeper( cdc: cdc, bankKeeper: bk, supplyKeeper: sk, - paramstore: ps.WithKeyTable(ParamKeyTable()), + paramstore: ps, hooks: nil, validatorCache: make(map[string]cachedValidator, aminoCacheSize), validatorCacheList: list.New(), diff --git a/x/staking/keeper/old_delegation_test.go b/x/staking/keeper/old_delegation_test.go index 2c83dd757774..2e22045f707b 100644 --- a/x/staking/keeper/old_delegation_test.go +++ b/x/staking/keeper/old_delegation_test.go @@ -11,83 +11,6 @@ import ( "github.com/stretchr/testify/require" ) -func TestUnbondingDelegationsMaxEntries(t *testing.T) { - ctx, _, bk, keeper, _ := CreateTestInput(t, false, 1) - startTokens := sdk.TokensFromConsensusPower(10) - - bondDenom := keeper.BondDenom(ctx) - notBondedPool := keeper.GetNotBondedPool(ctx) - - err := bk.SetBalances(ctx, notBondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(bondDenom, startTokens))) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - // create a validator and a delegator to that validator - validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) - - validator, issuedShares := validator.AddTokensFromDel(startTokens) - require.Equal(t, startTokens, issuedShares.RoundInt()) - - validator = TestingUpdateValidator(keeper, ctx, validator, true) - require.True(sdk.IntEq(t, startTokens, validator.BondedTokens())) - require.True(t, validator.IsBonded()) - - delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) - keeper.SetDelegation(ctx, delegation) - - maxEntries := keeper.MaxEntries(ctx) - - oldBonded := bk.GetBalance(ctx, keeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount - oldNotBonded := bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount - - // should all pass - var completionTime time.Time - for i := uint32(0); i < maxEntries; i++ { - var err error - completionTime, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], sdk.NewDec(1)) - require.NoError(t, err) - } - - newBonded := bk.GetBalance(ctx, keeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount - newNotBonded := bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount - require.True(sdk.IntEq(t, newBonded, oldBonded.SubRaw(int64(maxEntries)))) - require.True(sdk.IntEq(t, newNotBonded, oldNotBonded.AddRaw(int64(maxEntries)))) - - oldBonded = bk.GetBalance(ctx, keeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount - oldNotBonded = bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount - - // an additional unbond should fail due to max entries - _, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], sdk.NewDec(1)) - require.Error(t, err) - - newBonded = bk.GetBalance(ctx, keeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount - newNotBonded = bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount - - require.True(sdk.IntEq(t, newBonded, oldBonded)) - require.True(sdk.IntEq(t, newNotBonded, oldNotBonded)) - - // mature unbonding delegations - ctx = ctx.WithBlockTime(completionTime) - err = keeper.CompleteUnbonding(ctx, addrDels[0], addrVals[0]) - require.NoError(t, err) - - newBonded = bk.GetBalance(ctx, keeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount - newNotBonded = bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount - require.True(sdk.IntEq(t, newBonded, oldBonded)) - require.True(sdk.IntEq(t, newNotBonded, oldNotBonded.SubRaw(int64(maxEntries)))) - - oldNotBonded = bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount - - // unbonding should work again - _, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], sdk.NewDec(1)) - require.NoError(t, err) - - newBonded = bk.GetBalance(ctx, keeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount - newNotBonded = bk.GetBalance(ctx, keeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount - require.True(sdk.IntEq(t, newBonded, oldBonded.SubRaw(1))) - require.True(sdk.IntEq(t, newNotBonded, oldNotBonded.AddRaw(1))) -} - // test undelegating self delegation from a validator pushing it below MinSelfDelegation // shift it from the bonded to unbonding state and jailed func TestUndelegateSelfDelegationBelowMinSelfDelegation(t *testing.T) { diff --git a/x/staking/keeper/querier_test.go b/x/staking/keeper/querier_test.go index 19a260d531da..90269a0bc926 100644 --- a/x/staking/keeper/querier_test.go +++ b/x/staking/keeper/querier_test.go @@ -13,6 +13,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/distribution" "github.com/cosmos/cosmos-sdk/x/staking" + "github.com/cosmos/cosmos-sdk/x/staking/keeper" "github.com/cosmos/cosmos-sdk/x/staking/types" ) @@ -211,6 +212,15 @@ func TestQueryDelegation(t *testing.T) { params := app.StakingKeeper.GetParams(ctx) querier := staking.NewQuerier(app.StakingKeeper) + codec := simapp.NewAppCodec() + app.StakingKeeper = keeper.NewKeeper( + codec.Staking, + app.GetKey(staking.StoreKey), + app.BankKeeper, + app.SupplyKeeper, + app.GetSubspace(staking.ModuleName), + ) + addrs := simapp.AddTestAddrs(app, ctx, 2, sdk.TokensFromConsensusPower(10000)) addrAcc1, addrAcc2 := addrs[0], addrs[1] addrVal1, addrVal2 := sdk.ValAddress(addrAcc1), sdk.ValAddress(addrAcc2) diff --git a/x/staking/keeper/slash.go b/x/staking/keeper/slash.go index 8841d3e8e4bd..76db0c8e99ba 100644 --- a/x/staking/keeper/slash.go +++ b/x/staking/keeper/slash.go @@ -254,7 +254,7 @@ func (k Keeper) slashRedelegation(ctx sdk.Context, srcValidator types.Validator, sharesToUnbond = delegation.Shares } - tokensToBurn, err := k.unbond(ctx, redelegation.DelegatorAddress, redelegation.ValidatorDstAddress, sharesToUnbond) + tokensToBurn, err := k.Unbond(ctx, redelegation.DelegatorAddress, redelegation.ValidatorDstAddress, sharesToUnbond) if err != nil { panic(fmt.Errorf("error unbonding delegator: %v", err)) } From 594e0a6bfa00370a85d9f04a453b1c5f189b9f15 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Fri, 21 Feb 2020 18:38:28 +0100 Subject: [PATCH 14/90] avoid usage of historicals --- x/staking/keeper/querier_test.go | 34 +++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/x/staking/keeper/querier_test.go b/x/staking/keeper/querier_test.go index 90269a0bc926..9be64f1ed001 100644 --- a/x/staking/keeper/querier_test.go +++ b/x/staking/keeper/querier_test.go @@ -11,7 +11,6 @@ import ( "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/distribution" "github.com/cosmos/cosmos-sdk/x/staking" "github.com/cosmos/cosmos-sdk/x/staking/keeper" "github.com/cosmos/cosmos-sdk/x/staking/types" @@ -143,6 +142,15 @@ func TestQueryValidators(t *testing.T) { params := app.StakingKeeper.GetParams(ctx) querier := staking.NewQuerier(app.StakingKeeper) + codec := simapp.NewAppCodec() + app.StakingKeeper = keeper.NewKeeper( + codec.Staking, + app.GetKey(staking.StoreKey), + app.BankKeeper, + app.SupplyKeeper, + app.GetSubspace(staking.ModuleName), + ) + addrs := simapp.AddTestAddrs(app, ctx, 500, sdk.TokensFromConsensusPower(10000)) // Create Validators @@ -232,12 +240,10 @@ func TestQueryDelegation(t *testing.T) { val1 := types.NewValidator(addrVal1, pk1, types.Description{}) app.StakingKeeper.SetValidator(ctx, val1) app.StakingKeeper.SetValidatorByPowerIndex(ctx, val1) - app.DistrKeeper.SetValidatorHistoricalRewards(ctx, addrVal1, 18446744073709551615, distribution.ValidatorHistoricalRewards{ReferenceCount: 1}) val2 := types.NewValidator(addrVal2, pk2, types.Description{}) app.StakingKeeper.SetValidator(ctx, val2) app.StakingKeeper.SetValidatorByPowerIndex(ctx, val2) - app.DistrKeeper.SetValidatorHistoricalRewards(ctx, addrVal2, 18446744073709551615, distribution.ValidatorHistoricalRewards{ReferenceCount: 1}) delTokens := sdk.TokensFromConsensusPower(20) _, err := app.StakingKeeper.Delegate(ctx, addrAcc2, delTokens, sdk.Unbonded, val1, true) @@ -344,7 +350,6 @@ func TestQueryDelegation(t *testing.T) { require.Error(t, err) // Query validator delegations - bz, errRes = cdc.MarshalJSON(types.NewQueryValidatorParams(addrVal1)) require.NoError(t, errRes) @@ -452,6 +457,15 @@ func TestQueryRedelegations(t *testing.T) { ctx := app.BaseApp.NewContext(false, abci.Header{}) querier := staking.NewQuerier(app.StakingKeeper) + codec := simapp.NewAppCodec() + app.StakingKeeper = keeper.NewKeeper( + codec.Staking, + app.GetKey(staking.StoreKey), + app.BankKeeper, + app.SupplyKeeper, + app.GetSubspace(staking.ModuleName), + ) + addrs := simapp.AddTestAddrs(app, ctx, 2, sdk.TokensFromConsensusPower(10000)) addrAcc1, addrAcc2 := addrs[0], addrs[1] addrVal1, addrVal2 := sdk.ValAddress(addrAcc1), sdk.ValAddress(addrAcc2) @@ -461,8 +475,6 @@ func TestQueryRedelegations(t *testing.T) { val2 := types.NewValidator(addrVal2, PKs[1], types.Description{}) app.StakingKeeper.SetValidator(ctx, val1) app.StakingKeeper.SetValidator(ctx, val2) - app.DistrKeeper.SetValidatorHistoricalRewards(ctx, addrVal1, 18446744073709551615, distribution.ValidatorHistoricalRewards{ReferenceCount: 1}) - app.DistrKeeper.SetValidatorHistoricalRewards(ctx, addrVal2, 18446744073709551615, distribution.ValidatorHistoricalRewards{ReferenceCount: 1}) delAmount := sdk.TokensFromConsensusPower(100) app.StakingKeeper.Delegate(ctx, addrAcc2, delAmount, sdk.Unbonded, val1, true) @@ -525,6 +537,15 @@ func TestQueryUnbondingDelegation(t *testing.T) { ctx := app.BaseApp.NewContext(false, abci.Header{}) querier := staking.NewQuerier(app.StakingKeeper) + codec := simapp.NewAppCodec() + app.StakingKeeper = keeper.NewKeeper( + codec.Staking, + app.GetKey(staking.StoreKey), + app.BankKeeper, + app.SupplyKeeper, + app.GetSubspace(staking.ModuleName), + ) + addrs := simapp.AddTestAddrs(app, ctx, 2, sdk.TokensFromConsensusPower(10000)) addrAcc1, addrAcc2 := addrs[0], addrs[1] addrVal1 := sdk.ValAddress(addrAcc1) @@ -532,7 +553,6 @@ func TestQueryUnbondingDelegation(t *testing.T) { // Create Validators and Delegation val1 := types.NewValidator(addrVal1, PKs[0], types.Description{}) app.StakingKeeper.SetValidator(ctx, val1) - app.DistrKeeper.SetValidatorHistoricalRewards(ctx, addrVal1, 18446744073709551615, distribution.ValidatorHistoricalRewards{ReferenceCount: 1}) // delegate delAmount := sdk.TokensFromConsensusPower(100) From e155b1083df117f64775fdac88508705207859bc Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Fri, 21 Feb 2020 18:49:54 +0100 Subject: [PATCH 15/90] refactor creation of the simapp --- x/staking/keeper/querier_test.go | 67 ++++------------------------ x/staking/keeper/test_common_test.go | 24 ++++++++++ 2 files changed, 32 insertions(+), 59 deletions(-) diff --git a/x/staking/keeper/querier_test.go b/x/staking/keeper/querier_test.go index 9be64f1ed001..09a19b894f4f 100644 --- a/x/staking/keeper/querier_test.go +++ b/x/staking/keeper/querier_test.go @@ -8,18 +8,15 @@ import ( abci "github.com/tendermint/tendermint/abci/types" - "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/staking" - "github.com/cosmos/cosmos-sdk/x/staking/keeper" "github.com/cosmos/cosmos-sdk/x/staking/types" ) func TestNewQuerier(t *testing.T) { - cdc := codec.New() - app := simapp.Setup(false) - ctx := app.BaseApp.NewContext(false, abci.Header{}) + cdc, app, ctx := getBaseSimappWithCustomKeeper() + addrs := simapp.AddTestAddrs(app, ctx, 500, sdk.NewInt(10000)) _, addrAcc2 := addrs[0], addrs[1] addrVal1, _ := sdk.ValAddress(addrs[0]), sdk.ValAddress(addrs[1]) @@ -109,9 +106,7 @@ func TestNewQuerier(t *testing.T) { } func TestQueryParametersPool(t *testing.T) { - cdc := codec.New() - app := simapp.Setup(false) - ctx := app.BaseApp.NewContext(false, abci.Header{}) + cdc, app, ctx := getBaseSimappWithCustomKeeper() querier := staking.NewQuerier(app.StakingKeeper) bondDenom := sdk.DefaultBondDenom @@ -136,21 +131,10 @@ func TestQueryParametersPool(t *testing.T) { } func TestQueryValidators(t *testing.T) { - cdc := codec.New() - app := simapp.Setup(false) - ctx := app.BaseApp.NewContext(false, abci.Header{}) + cdc, app, ctx := getBaseSimappWithCustomKeeper() params := app.StakingKeeper.GetParams(ctx) querier := staking.NewQuerier(app.StakingKeeper) - codec := simapp.NewAppCodec() - app.StakingKeeper = keeper.NewKeeper( - codec.Staking, - app.GetKey(staking.StoreKey), - app.BankKeeper, - app.SupplyKeeper, - app.GetSubspace(staking.ModuleName), - ) - addrs := simapp.AddTestAddrs(app, ctx, 500, sdk.TokensFromConsensusPower(10000)) // Create Validators @@ -214,21 +198,10 @@ func TestQueryValidators(t *testing.T) { } func TestQueryDelegation(t *testing.T) { - cdc := codec.New() - app := simapp.Setup(false) - ctx := app.BaseApp.NewContext(false, abci.Header{}) + cdc, app, ctx := getBaseSimappWithCustomKeeper() params := app.StakingKeeper.GetParams(ctx) querier := staking.NewQuerier(app.StakingKeeper) - codec := simapp.NewAppCodec() - app.StakingKeeper = keeper.NewKeeper( - codec.Staking, - app.GetKey(staking.StoreKey), - app.BankKeeper, - app.SupplyKeeper, - app.GetSubspace(staking.ModuleName), - ) - addrs := simapp.AddTestAddrs(app, ctx, 2, sdk.TokensFromConsensusPower(10000)) addrAcc1, addrAcc2 := addrs[0], addrs[1] addrVal1, addrVal2 := sdk.ValAddress(addrAcc1), sdk.ValAddress(addrAcc2) @@ -452,20 +425,9 @@ func TestQueryDelegation(t *testing.T) { } func TestQueryRedelegations(t *testing.T) { - cdc := codec.New() - app := simapp.Setup(false) - ctx := app.BaseApp.NewContext(false, abci.Header{}) + cdc, app, ctx := getBaseSimappWithCustomKeeper() querier := staking.NewQuerier(app.StakingKeeper) - codec := simapp.NewAppCodec() - app.StakingKeeper = keeper.NewKeeper( - codec.Staking, - app.GetKey(staking.StoreKey), - app.BankKeeper, - app.SupplyKeeper, - app.GetSubspace(staking.ModuleName), - ) - addrs := simapp.AddTestAddrs(app, ctx, 2, sdk.TokensFromConsensusPower(10000)) addrAcc1, addrAcc2 := addrs[0], addrs[1] addrVal1, addrVal2 := sdk.ValAddress(addrAcc1), sdk.ValAddress(addrAcc2) @@ -532,20 +494,9 @@ func TestQueryRedelegations(t *testing.T) { } func TestQueryUnbondingDelegation(t *testing.T) { - cdc := codec.New() - app := simapp.Setup(false) - ctx := app.BaseApp.NewContext(false, abci.Header{}) + cdc, app, ctx := getBaseSimappWithCustomKeeper() querier := staking.NewQuerier(app.StakingKeeper) - codec := simapp.NewAppCodec() - app.StakingKeeper = keeper.NewKeeper( - codec.Staking, - app.GetKey(staking.StoreKey), - app.BankKeeper, - app.SupplyKeeper, - app.GetSubspace(staking.ModuleName), - ) - addrs := simapp.AddTestAddrs(app, ctx, 2, sdk.TokensFromConsensusPower(10000)) addrAcc1, addrAcc2 := addrs[0], addrs[1] addrVal1 := sdk.ValAddress(addrAcc1) @@ -638,9 +589,7 @@ func TestQueryUnbondingDelegation(t *testing.T) { } func TestQueryHistoricalInfo(t *testing.T) { - cdc := codec.New() - app := simapp.Setup(false) - ctx := app.BaseApp.NewContext(false, abci.Header{}) + cdc, app, ctx := getBaseSimappWithCustomKeeper() querier := staking.NewQuerier(app.StakingKeeper) addrs := simapp.AddTestAddrs(app, ctx, 2, sdk.TokensFromConsensusPower(10000)) diff --git a/x/staking/keeper/test_common_test.go b/x/staking/keeper/test_common_test.go index 936c028148d2..0f2ceb58a210 100644 --- a/x/staking/keeper/test_common_test.go +++ b/x/staking/keeper/test_common_test.go @@ -5,6 +5,12 @@ import ( "encoding/hex" "strconv" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/simapp" + "github.com/cosmos/cosmos-sdk/x/staking" + "github.com/cosmos/cosmos-sdk/x/staking/keeper" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" @@ -96,3 +102,21 @@ func CreateTestAddr(addr string, bech string) sdk.AccAddress { return res } + +// getBaseSimappWithCustomKeeper Returns a simapp with custom StakingKeeper +// to avoid messing with the hooks. +func getBaseSimappWithCustomKeeper() (*codec.Codec, *simapp.SimApp, sdk.Context) { + cdc := codec.New() + app := simapp.Setup(false) + ctx := app.BaseApp.NewContext(false, abci.Header{}) + + app.StakingKeeper = keeper.NewKeeper( + simapp.NewAppCodec().Staking, + app.GetKey(staking.StoreKey), + app.BankKeeper, + app.SupplyKeeper, + app.GetSubspace(staking.ModuleName), + ) + + return cdc, app, ctx +} From 01aaf8446d3628ee99a11ae9897c29d88c9edea1 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Fri, 21 Feb 2020 18:54:10 +0100 Subject: [PATCH 16/90] refactor creation of simapp --- x/staking/keeper/delegation_test.go | 11 +++-------- x/staking/keeper/test_common_test.go | 9 ++++----- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/x/staking/keeper/delegation_test.go b/x/staking/keeper/delegation_test.go index 4f4b5e7beabf..31886eac1e0f 100644 --- a/x/staking/keeper/delegation_test.go +++ b/x/staking/keeper/delegation_test.go @@ -9,8 +9,6 @@ import ( "github.com/stretchr/testify/require" "github.com/cosmos/cosmos-sdk/simapp" - abci "github.com/tendermint/tendermint/abci/types" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/staking/keeper" "github.com/cosmos/cosmos-sdk/x/staking/types" @@ -18,8 +16,7 @@ import ( // tests GetDelegation, GetDelegatorDelegations, SetDelegation, RemoveDelegation, GetDelegatorDelegations func TestDelegation(t *testing.T) { - app := simapp.Setup(false) - ctx := app.BaseApp.NewContext(false, abci.Header{}) + _, app, ctx := getBaseSimappWithCustomKeeper() //construct the validators amts := []sdk.Int{sdk.NewInt(9), sdk.NewInt(8), sdk.NewInt(7)} @@ -133,8 +130,7 @@ func TestDelegation(t *testing.T) { // tests Get/Set/Remove UnbondingDelegation func TestUnbondingDelegation(t *testing.T) { - app := simapp.Setup(false) - ctx := app.BaseApp.NewContext(false, abci.Header{}) + _, app, ctx := getBaseSimappWithCustomKeeper() ubd := types.NewUnbondingDelegation( addrDels[0], @@ -177,8 +173,7 @@ func TestUnbondingDelegation(t *testing.T) { } func TestUnbondDelegation(t *testing.T) { - app := simapp.Setup(false) - ctx := app.BaseApp.NewContext(false, abci.Header{}) + _, app, ctx := getBaseSimappWithCustomKeeper() codec := simapp.NewAppCodec() app.StakingKeeper = keeper.NewKeeper( diff --git a/x/staking/keeper/test_common_test.go b/x/staking/keeper/test_common_test.go index 0f2ceb58a210..7c6cf8f0c2f9 100644 --- a/x/staking/keeper/test_common_test.go +++ b/x/staking/keeper/test_common_test.go @@ -5,16 +5,15 @@ import ( "encoding/hex" "strconv" + "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/staking" "github.com/cosmos/cosmos-sdk/x/staking/keeper" abci "github.com/tendermint/tendermint/abci/types" - - "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/ed25519" - - sdk "github.com/cosmos/cosmos-sdk/types" ) var ( From 89785765e049e6b8452108051aab765078dc290d Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Fri, 21 Feb 2020 19:19:57 +0100 Subject: [PATCH 17/90] comment before creating new way to generate accounts --- x/staking/keeper/delegation_test.go | 227 ++++++++++++++-------------- 1 file changed, 114 insertions(+), 113 deletions(-) diff --git a/x/staking/keeper/delegation_test.go b/x/staking/keeper/delegation_test.go index 31886eac1e0f..45879644be66 100644 --- a/x/staking/keeper/delegation_test.go +++ b/x/staking/keeper/delegation_test.go @@ -15,119 +15,120 @@ import ( ) // tests GetDelegation, GetDelegatorDelegations, SetDelegation, RemoveDelegation, GetDelegatorDelegations -func TestDelegation(t *testing.T) { - _, app, ctx := getBaseSimappWithCustomKeeper() - - //construct the validators - amts := []sdk.Int{sdk.NewInt(9), sdk.NewInt(8), sdk.NewInt(7)} - var validators [3]types.Validator - for i, amt := range amts { - validators[i] = types.NewValidator(addrVals[i], PKs[i], types.Description{}) - validators[i], _ = validators[i].AddTokensFromDel(amt) - } - - validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], true) - validators[1] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[1], true) - validators[2] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[2], true) - - // first add a validators[0] to delegate too - bond1to1 := types.NewDelegation(addrDels[0], addrVals[0], sdk.NewDec(9)) - - // check the empty keeper first - _, found := app.StakingKeeper.GetDelegation(ctx, addrDels[0], addrVals[0]) - require.False(t, found) - - // set and retrieve a record - app.StakingKeeper.SetDelegation(ctx, bond1to1) - resBond, found := app.StakingKeeper.GetDelegation(ctx, addrDels[0], addrVals[0]) - require.True(t, found) - require.True(t, bond1to1.Equal(resBond)) - - // modify a records, save, and retrieve - bond1to1.Shares = sdk.NewDec(99) - app.StakingKeeper.SetDelegation(ctx, bond1to1) - resBond, found = app.StakingKeeper.GetDelegation(ctx, addrDels[0], addrVals[0]) - require.True(t, found) - require.True(t, bond1to1.Equal(resBond)) - - // add some more records - bond1to2 := types.NewDelegation(addrDels[0], addrVals[1], sdk.NewDec(9)) - bond1to3 := types.NewDelegation(addrDels[0], addrVals[2], sdk.NewDec(9)) - bond2to1 := types.NewDelegation(addrDels[1], addrVals[0], sdk.NewDec(9)) - bond2to2 := types.NewDelegation(addrDels[1], addrVals[1], sdk.NewDec(9)) - bond2to3 := types.NewDelegation(addrDels[1], addrVals[2], sdk.NewDec(9)) - app.StakingKeeper.SetDelegation(ctx, bond1to2) - app.StakingKeeper.SetDelegation(ctx, bond1to3) - app.StakingKeeper.SetDelegation(ctx, bond2to1) - app.StakingKeeper.SetDelegation(ctx, bond2to2) - app.StakingKeeper.SetDelegation(ctx, bond2to3) - - // test all bond retrieve capabilities - resBonds := app.StakingKeeper.GetDelegatorDelegations(ctx, addrDels[0], 5) - require.Equal(t, 3, len(resBonds)) - require.True(t, bond1to1.Equal(resBonds[0])) - require.True(t, bond1to2.Equal(resBonds[1])) - require.True(t, bond1to3.Equal(resBonds[2])) - resBonds = app.StakingKeeper.GetAllDelegatorDelegations(ctx, addrDels[0]) - require.Equal(t, 3, len(resBonds)) - resBonds = app.StakingKeeper.GetDelegatorDelegations(ctx, addrDels[0], 2) - require.Equal(t, 2, len(resBonds)) - resBonds = app.StakingKeeper.GetDelegatorDelegations(ctx, addrDels[1], 5) - require.Equal(t, 3, len(resBonds)) - require.True(t, bond2to1.Equal(resBonds[0])) - require.True(t, bond2to2.Equal(resBonds[1])) - require.True(t, bond2to3.Equal(resBonds[2])) - allBonds := app.StakingKeeper.GetAllDelegations(ctx) - require.Equal(t, 6, len(allBonds)) - require.True(t, bond1to1.Equal(allBonds[0])) - require.True(t, bond1to2.Equal(allBonds[1])) - require.True(t, bond1to3.Equal(allBonds[2])) - require.True(t, bond2to1.Equal(allBonds[3])) - require.True(t, bond2to2.Equal(allBonds[4])) - require.True(t, bond2to3.Equal(allBonds[5])) - - resVals := app.StakingKeeper.GetDelegatorValidators(ctx, addrDels[0], 3) - require.Equal(t, 3, len(resVals)) - resVals = app.StakingKeeper.GetDelegatorValidators(ctx, addrDels[1], 4) - require.Equal(t, 3, len(resVals)) - - for i := 0; i < 3; i++ { - - resVal, err := app.StakingKeeper.GetDelegatorValidator(ctx, addrDels[0], addrVals[i]) - require.Nil(t, err) - require.Equal(t, addrVals[i], resVal.GetOperator()) - - resVal, err = app.StakingKeeper.GetDelegatorValidator(ctx, addrDels[1], addrVals[i]) - require.Nil(t, err) - require.Equal(t, addrVals[i], resVal.GetOperator()) - - resDels := app.StakingKeeper.GetValidatorDelegations(ctx, addrVals[i]) - require.Len(t, resDels, 2) - } - - // delete a record - app.StakingKeeper.RemoveDelegation(ctx, bond2to3) - _, found = app.StakingKeeper.GetDelegation(ctx, addrDels[1], addrVals[2]) - require.False(t, found) - resBonds = app.StakingKeeper.GetDelegatorDelegations(ctx, addrDels[1], 5) - require.Equal(t, 2, len(resBonds)) - require.True(t, bond2to1.Equal(resBonds[0])) - require.True(t, bond2to2.Equal(resBonds[1])) - - resBonds = app.StakingKeeper.GetAllDelegatorDelegations(ctx, addrDels[1]) - require.Equal(t, 2, len(resBonds)) - - // delete all the records from delegator 2 - app.StakingKeeper.RemoveDelegation(ctx, bond2to1) - app.StakingKeeper.RemoveDelegation(ctx, bond2to2) - _, found = app.StakingKeeper.GetDelegation(ctx, addrDels[1], addrVals[0]) - require.False(t, found) - _, found = app.StakingKeeper.GetDelegation(ctx, addrDels[1], addrVals[1]) - require.False(t, found) - resBonds = app.StakingKeeper.GetDelegatorDelegations(ctx, addrDels[1], 5) - require.Equal(t, 0, len(resBonds)) -} - +//func TestDelegation(t *testing.T) { +// _, app, ctx := getBaseSimappWithCustomKeeper() +// +// addrs := simapp.AddTestAddrs(app, ctx, 3, sdk.NewInt(10000)) +// +// //construct the validators +// amts := []sdk.Int{sdk.NewInt(9), sdk.NewInt(8), sdk.NewInt(7)} +// var validators [3]types.Validator +// for i, amt := range amts { +// validators[i] = types.NewValidator(sdk.ValAddress(addrs[i]), PKs[i], types.Description{}) +// validators[i], _ = validators[i].AddTokensFromDel(amt) +// } +// +// validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], true) +// validators[1] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[1], true) +// validators[2] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[2], true) +// +// // first add a validators[0] to delegate too +// bond1to1 := types.NewDelegation(addrs[0], sdk.ValAddress(addrs[0]), sdk.NewDec(9)) +// +// // check the empty keeper first +// _, found := app.StakingKeeper.GetDelegation(ctx, addrs[0], sdk.ValAddress(addrs[0])) +// require.False(t, found) +// +// // set and retrieve a record +// app.StakingKeeper.SetDelegation(ctx, bond1to1) +// resBond, found := app.StakingKeeper.GetDelegation(ctx, addrs[0], sdk.ValAddress(addrs[0])) +// require.True(t, found) +// require.True(t, bond1to1.Equal(resBond)) +// +// // modify a records, save, and retrieve +// bond1to1.Shares = sdk.NewDec(99) +// app.StakingKeeper.SetDelegation(ctx, bond1to1) +// resBond, found = app.StakingKeeper.GetDelegation(ctx, addrs[0], sdk.ValAddress(addrs[0])) +// require.True(t, found) +// require.True(t, bond1to1.Equal(resBond)) +// +// // add some more records +// bond1to2 := types.NewDelegation(addrs[0], sdk.ValAddress(addrs[1]), sdk.NewDec(9)) +// bond1to3 := types.NewDelegation(addrs[0], sdk.ValAddress(addrs[2]), sdk.NewDec(9)) +// bond2to1 := types.NewDelegation(addrs[1], sdk.ValAddress(addrs[0]), sdk.NewDec(9)) +// bond2to2 := types.NewDelegation(addrs[1], sdk.ValAddress(addrs[1]), sdk.NewDec(9)) +// bond2to3 := types.NewDelegation(addrs[1], sdk.ValAddress(addrs[2]), sdk.NewDec(9)) +// app.StakingKeeper.SetDelegation(ctx, bond1to2) +// app.StakingKeeper.SetDelegation(ctx, bond1to3) +// app.StakingKeeper.SetDelegation(ctx, bond2to1) +// app.StakingKeeper.SetDelegation(ctx, bond2to2) +// app.StakingKeeper.SetDelegation(ctx, bond2to3) +// +// // test all bond retrieve capabilities +// resBonds := app.StakingKeeper.GetDelegatorDelegations(ctx, addrs[0], 5) +// require.Equal(t, 3, len(resBonds)) +// require.True(t, bond1to1.Equal(resBonds[0])) +// require.True(t, bond1to2.Equal(resBonds[1])) +// require.True(t, bond1to3.Equal(resBonds[2])) +// resBonds = app.StakingKeeper.GetAllDelegatorDelegations(ctx, addrs[0]) +// require.Equal(t, 3, len(resBonds)) +// resBonds = app.StakingKeeper.GetDelegatorDelegations(ctx, addrs[0], 2) +// require.Equal(t, 2, len(resBonds)) +// resBonds = app.StakingKeeper.GetDelegatorDelegations(ctx, addrs[1], 5) +// require.Equal(t, 3, len(resBonds)) +// require.True(t, bond2to1.Equal(resBonds[0])) +// require.True(t, bond2to2.Equal(resBonds[1])) +// require.True(t, bond2to3.Equal(resBonds[2])) +// allBonds := app.StakingKeeper.GetAllDelegations(ctx) +// require.Equal(t, 6, len(allBonds)) +// require.True(t, bond1to1.Equal(allBonds[0])) +// require.True(t, bond1to2.Equal(allBonds[1])) +// require.True(t, bond1to3.Equal(allBonds[2])) +// require.True(t, bond2to1.Equal(allBonds[3])) +// require.True(t, bond2to2.Equal(allBonds[4])) +// require.True(t, bond2to3.Equal(allBonds[5])) +// +// resVals := app.StakingKeeper.GetDelegatorValidators(ctx, addrs[0], 3) +// require.Equal(t, 3, len(resVals)) +// resVals = app.StakingKeeper.GetDelegatorValidators(ctx, addrs[1], 4) +// require.Equal(t, 3, len(resVals)) +// +// for i := 0; i < 3; i++ { +// resVal, err := app.StakingKeeper.GetDelegatorValidator(ctx, addrs[0], sdk.ValAddress(addrs[i])) +// require.Nil(t, err) +// require.Equal(t, addrs[i], resVal.GetOperator()) +// +// resVal, err = app.StakingKeeper.GetDelegatorValidator(ctx, addrs[1], sdk.ValAddress(addrs[i])) +// require.Nil(t, err) +// require.Equal(t, addrs[i], resVal.GetOperator()) +// +// resDels := app.StakingKeeper.GetValidatorDelegations(ctx, sdk.ValAddress(addrs[i])) +// require.Len(t, resDels, 2) +// } +// +// // delete a record +// app.StakingKeeper.RemoveDelegation(ctx, bond2to3) +// _, found = app.StakingKeeper.GetDelegation(ctx, addrs[1], sdk.ValAddress(addrs[2])) +// require.False(t, found) +// resBonds = app.StakingKeeper.GetDelegatorDelegations(ctx, addrs[1], 5) +// require.Equal(t, 2, len(resBonds)) +// require.True(t, bond2to1.Equal(resBonds[0])) +// require.True(t, bond2to2.Equal(resBonds[1])) +// +// resBonds = app.StakingKeeper.GetAllDelegatorDelegations(ctx, addrs[1]) +// require.Equal(t, 2, len(resBonds)) +// +// // delete all the records from delegator 2 +// app.StakingKeeper.RemoveDelegation(ctx, bond2to1) +// app.StakingKeeper.RemoveDelegation(ctx, bond2to2) +// _, found = app.StakingKeeper.GetDelegation(ctx, addrs[1], sdk.ValAddress(addrs[0])) +// require.False(t, found) +// _, found = app.StakingKeeper.GetDelegation(ctx, addrs[1], sdk.ValAddress(addrs[1])) +// require.False(t, found) +// resBonds = app.StakingKeeper.GetDelegatorDelegations(ctx, addrDels[1], 5) +// require.Equal(t, 0, len(resBonds)) +//} +// // tests Get/Set/Remove UnbondingDelegation func TestUnbondingDelegation(t *testing.T) { _, app, ctx := getBaseSimappWithCustomKeeper() From ee7ccc37040862ef897a8aa32405537670cab686 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Fri, 21 Feb 2020 19:34:07 +0100 Subject: [PATCH 18/90] make TestDelegation pass with generated accounts --- simapp/test_helpers.go | 64 +++++++- x/staking/keeper/delegation_test.go | 228 ++++++++++++++-------------- 2 files changed, 175 insertions(+), 117 deletions(-) diff --git a/simapp/test_helpers.go b/simapp/test_helpers.go index 31b4db3b80cd..36237bc5ec4a 100644 --- a/simapp/test_helpers.go +++ b/simapp/test_helpers.go @@ -80,15 +80,52 @@ func SetupWithGenesisAccounts(genAccs []authexported.GenesisAccount, balances .. return app } -// AddTestAddrs constructs and returns accNum amount of accounts with an -// initial balance of accAmt -func AddTestAddrs(app *SimApp, ctx sdk.Context, accNum int, accAmt sdk.Int) []sdk.AccAddress { +type GenerateAccountStrategy func(int) []sdk.AccAddress + +func Random(accNum int) []sdk.AccAddress { testAddrs := make([]sdk.AccAddress, accNum) for i := 0; i < accNum; i++ { pk := ed25519.GenPrivKey().PubKey() testAddrs[i] = sdk.AccAddress(pk.Address()) } + return testAddrs +} + +func Incremental(accNum int) []sdk.AccAddress { + var addresses []sdk.AccAddress + var buffer bytes.Buffer + + // start at 100 so we can make up to 999 test addresses with valid test addresses + for i := 100; i < (accNum + 100); i++ { + numString := strconv.Itoa(i) + buffer.WriteString("A58856F0FD53BF058B4909A21AEC019107BA6") //base address string + + buffer.WriteString(numString) //adding on final two digits to make addresses unique + res, _ := sdk.AccAddressFromHex(buffer.String()) + bech := res.String() + addresses = append(addresses, TestAddr(buffer.String(), bech)) + buffer.Reset() + } + + return addresses +} + +// AddTestAddrs constructs and returns accNum amount of accounts with an +// initial balance of accAmt in random order +func AddTestAddrs(app *SimApp, ctx sdk.Context, accNum int, accAmt sdk.Int) []sdk.AccAddress { + return addTestAddrs(app, ctx, accNum, accAmt, Random) +} + +// AddTestAddrs constructs and returns accNum amount of accounts with an +// initial balance of accAmt in random order +func AddTestAddrsIncremental(app *SimApp, ctx sdk.Context, accNum int, accAmt sdk.Int) []sdk.AccAddress { + return addTestAddrs(app, ctx, accNum, accAmt, Incremental) +} + +func addTestAddrs(app *SimApp, ctx sdk.Context, accNum int, accAmt sdk.Int, strategy GenerateAccountStrategy) []sdk.AccAddress { + testAddrs := strategy(accNum) + initCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), accAmt)) totalSupply := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), accAmt.MulRaw(int64(len(testAddrs))))) prevSupply := app.SupplyKeeper.GetSupply(ctx) @@ -107,6 +144,27 @@ func AddTestAddrs(app *SimApp, ctx sdk.Context, accNum int, accAmt sdk.Int) []sd return testAddrs } +func TestAddr(addr string, bech string) sdk.AccAddress { + res, err := sdk.AccAddressFromHex(addr) + if err != nil { + panic(err) + } + bechexpected := res.String() + if bech != bechexpected { + panic("Bech encoding doesn't match reference") + } + + bechres, err := sdk.AccAddressFromBech32(bech) + if err != nil { + panic(err) + } + if !bytes.Equal(bechres, res) { + panic("Bech decode and hex decode don't match") + } + + return res +} + // CheckBalance checks the balance of an account. func CheckBalance(t *testing.T, app *SimApp, addr sdk.AccAddress, balances sdk.Coins) { ctxCheck := app.BaseApp.NewContext(true, abci.Header{}) diff --git a/x/staking/keeper/delegation_test.go b/x/staking/keeper/delegation_test.go index 45879644be66..7c0bac9c4bb9 100644 --- a/x/staking/keeper/delegation_test.go +++ b/x/staking/keeper/delegation_test.go @@ -15,120 +15,120 @@ import ( ) // tests GetDelegation, GetDelegatorDelegations, SetDelegation, RemoveDelegation, GetDelegatorDelegations -//func TestDelegation(t *testing.T) { -// _, app, ctx := getBaseSimappWithCustomKeeper() -// -// addrs := simapp.AddTestAddrs(app, ctx, 3, sdk.NewInt(10000)) -// -// //construct the validators -// amts := []sdk.Int{sdk.NewInt(9), sdk.NewInt(8), sdk.NewInt(7)} -// var validators [3]types.Validator -// for i, amt := range amts { -// validators[i] = types.NewValidator(sdk.ValAddress(addrs[i]), PKs[i], types.Description{}) -// validators[i], _ = validators[i].AddTokensFromDel(amt) -// } -// -// validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], true) -// validators[1] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[1], true) -// validators[2] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[2], true) -// -// // first add a validators[0] to delegate too -// bond1to1 := types.NewDelegation(addrs[0], sdk.ValAddress(addrs[0]), sdk.NewDec(9)) -// -// // check the empty keeper first -// _, found := app.StakingKeeper.GetDelegation(ctx, addrs[0], sdk.ValAddress(addrs[0])) -// require.False(t, found) -// -// // set and retrieve a record -// app.StakingKeeper.SetDelegation(ctx, bond1to1) -// resBond, found := app.StakingKeeper.GetDelegation(ctx, addrs[0], sdk.ValAddress(addrs[0])) -// require.True(t, found) -// require.True(t, bond1to1.Equal(resBond)) -// -// // modify a records, save, and retrieve -// bond1to1.Shares = sdk.NewDec(99) -// app.StakingKeeper.SetDelegation(ctx, bond1to1) -// resBond, found = app.StakingKeeper.GetDelegation(ctx, addrs[0], sdk.ValAddress(addrs[0])) -// require.True(t, found) -// require.True(t, bond1to1.Equal(resBond)) -// -// // add some more records -// bond1to2 := types.NewDelegation(addrs[0], sdk.ValAddress(addrs[1]), sdk.NewDec(9)) -// bond1to3 := types.NewDelegation(addrs[0], sdk.ValAddress(addrs[2]), sdk.NewDec(9)) -// bond2to1 := types.NewDelegation(addrs[1], sdk.ValAddress(addrs[0]), sdk.NewDec(9)) -// bond2to2 := types.NewDelegation(addrs[1], sdk.ValAddress(addrs[1]), sdk.NewDec(9)) -// bond2to3 := types.NewDelegation(addrs[1], sdk.ValAddress(addrs[2]), sdk.NewDec(9)) -// app.StakingKeeper.SetDelegation(ctx, bond1to2) -// app.StakingKeeper.SetDelegation(ctx, bond1to3) -// app.StakingKeeper.SetDelegation(ctx, bond2to1) -// app.StakingKeeper.SetDelegation(ctx, bond2to2) -// app.StakingKeeper.SetDelegation(ctx, bond2to3) -// -// // test all bond retrieve capabilities -// resBonds := app.StakingKeeper.GetDelegatorDelegations(ctx, addrs[0], 5) -// require.Equal(t, 3, len(resBonds)) -// require.True(t, bond1to1.Equal(resBonds[0])) -// require.True(t, bond1to2.Equal(resBonds[1])) -// require.True(t, bond1to3.Equal(resBonds[2])) -// resBonds = app.StakingKeeper.GetAllDelegatorDelegations(ctx, addrs[0]) -// require.Equal(t, 3, len(resBonds)) -// resBonds = app.StakingKeeper.GetDelegatorDelegations(ctx, addrs[0], 2) -// require.Equal(t, 2, len(resBonds)) -// resBonds = app.StakingKeeper.GetDelegatorDelegations(ctx, addrs[1], 5) -// require.Equal(t, 3, len(resBonds)) -// require.True(t, bond2to1.Equal(resBonds[0])) -// require.True(t, bond2to2.Equal(resBonds[1])) -// require.True(t, bond2to3.Equal(resBonds[2])) -// allBonds := app.StakingKeeper.GetAllDelegations(ctx) -// require.Equal(t, 6, len(allBonds)) -// require.True(t, bond1to1.Equal(allBonds[0])) -// require.True(t, bond1to2.Equal(allBonds[1])) -// require.True(t, bond1to3.Equal(allBonds[2])) -// require.True(t, bond2to1.Equal(allBonds[3])) -// require.True(t, bond2to2.Equal(allBonds[4])) -// require.True(t, bond2to3.Equal(allBonds[5])) -// -// resVals := app.StakingKeeper.GetDelegatorValidators(ctx, addrs[0], 3) -// require.Equal(t, 3, len(resVals)) -// resVals = app.StakingKeeper.GetDelegatorValidators(ctx, addrs[1], 4) -// require.Equal(t, 3, len(resVals)) -// -// for i := 0; i < 3; i++ { -// resVal, err := app.StakingKeeper.GetDelegatorValidator(ctx, addrs[0], sdk.ValAddress(addrs[i])) -// require.Nil(t, err) -// require.Equal(t, addrs[i], resVal.GetOperator()) -// -// resVal, err = app.StakingKeeper.GetDelegatorValidator(ctx, addrs[1], sdk.ValAddress(addrs[i])) -// require.Nil(t, err) -// require.Equal(t, addrs[i], resVal.GetOperator()) -// -// resDels := app.StakingKeeper.GetValidatorDelegations(ctx, sdk.ValAddress(addrs[i])) -// require.Len(t, resDels, 2) -// } -// -// // delete a record -// app.StakingKeeper.RemoveDelegation(ctx, bond2to3) -// _, found = app.StakingKeeper.GetDelegation(ctx, addrs[1], sdk.ValAddress(addrs[2])) -// require.False(t, found) -// resBonds = app.StakingKeeper.GetDelegatorDelegations(ctx, addrs[1], 5) -// require.Equal(t, 2, len(resBonds)) -// require.True(t, bond2to1.Equal(resBonds[0])) -// require.True(t, bond2to2.Equal(resBonds[1])) -// -// resBonds = app.StakingKeeper.GetAllDelegatorDelegations(ctx, addrs[1]) -// require.Equal(t, 2, len(resBonds)) -// -// // delete all the records from delegator 2 -// app.StakingKeeper.RemoveDelegation(ctx, bond2to1) -// app.StakingKeeper.RemoveDelegation(ctx, bond2to2) -// _, found = app.StakingKeeper.GetDelegation(ctx, addrs[1], sdk.ValAddress(addrs[0])) -// require.False(t, found) -// _, found = app.StakingKeeper.GetDelegation(ctx, addrs[1], sdk.ValAddress(addrs[1])) -// require.False(t, found) -// resBonds = app.StakingKeeper.GetDelegatorDelegations(ctx, addrDels[1], 5) -// require.Equal(t, 0, len(resBonds)) -//} -// +func TestDelegation(t *testing.T) { + _, app, ctx := getBaseSimappWithCustomKeeper() + + addrs := simapp.AddTestAddrsIncremental(app, ctx, 3, sdk.NewInt(10000)) + + //construct the validators + amts := []sdk.Int{sdk.NewInt(9), sdk.NewInt(8), sdk.NewInt(7)} + var validators [3]types.Validator + for i, amt := range amts { + validators[i] = types.NewValidator(sdk.ValAddress(addrs[i]), PKs[i], types.Description{}) + validators[i], _ = validators[i].AddTokensFromDel(amt) + } + + validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], true) + validators[1] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[1], true) + validators[2] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[2], true) + + // first add a validators[0] to delegate too + bond1to1 := types.NewDelegation(addrs[0], sdk.ValAddress(addrs[0]), sdk.NewDec(9)) + + // check the empty keeper first + _, found := app.StakingKeeper.GetDelegation(ctx, addrs[0], sdk.ValAddress(addrs[0])) + require.False(t, found) + + // set and retrieve a record + app.StakingKeeper.SetDelegation(ctx, bond1to1) + resBond, found := app.StakingKeeper.GetDelegation(ctx, addrs[0], sdk.ValAddress(addrs[0])) + require.True(t, found) + require.True(t, bond1to1.Equal(resBond)) + + // modify a records, save, and retrieve + bond1to1.Shares = sdk.NewDec(99) + app.StakingKeeper.SetDelegation(ctx, bond1to1) + resBond, found = app.StakingKeeper.GetDelegation(ctx, addrs[0], sdk.ValAddress(addrs[0])) + require.True(t, found) + require.True(t, bond1to1.Equal(resBond)) + + // add some more records + bond1to2 := types.NewDelegation(addrs[0], sdk.ValAddress(addrs[1]), sdk.NewDec(9)) + bond1to3 := types.NewDelegation(addrs[0], sdk.ValAddress(addrs[2]), sdk.NewDec(9)) + bond2to1 := types.NewDelegation(addrs[1], sdk.ValAddress(addrs[0]), sdk.NewDec(9)) + bond2to2 := types.NewDelegation(addrs[1], sdk.ValAddress(addrs[1]), sdk.NewDec(9)) + bond2to3 := types.NewDelegation(addrs[1], sdk.ValAddress(addrs[2]), sdk.NewDec(9)) + app.StakingKeeper.SetDelegation(ctx, bond1to2) + app.StakingKeeper.SetDelegation(ctx, bond1to3) + app.StakingKeeper.SetDelegation(ctx, bond2to1) + app.StakingKeeper.SetDelegation(ctx, bond2to2) + app.StakingKeeper.SetDelegation(ctx, bond2to3) + + // test all bond retrieve capabilities + resBonds := app.StakingKeeper.GetDelegatorDelegations(ctx, addrs[0], 5) + require.Equal(t, 3, len(resBonds)) + require.True(t, bond1to1.Equal(resBonds[0])) + require.True(t, bond1to2.Equal(resBonds[1])) + require.True(t, bond1to3.Equal(resBonds[2])) + resBonds = app.StakingKeeper.GetAllDelegatorDelegations(ctx, addrs[0]) + require.Equal(t, 3, len(resBonds)) + resBonds = app.StakingKeeper.GetDelegatorDelegations(ctx, addrs[0], 2) + require.Equal(t, 2, len(resBonds)) + resBonds = app.StakingKeeper.GetDelegatorDelegations(ctx, addrs[1], 5) + require.Equal(t, 3, len(resBonds)) + require.True(t, bond2to1.Equal(resBonds[0])) + require.True(t, bond2to2.Equal(resBonds[1])) + require.True(t, bond2to3.Equal(resBonds[2])) + allBonds := app.StakingKeeper.GetAllDelegations(ctx) + require.Equal(t, 6, len(allBonds)) + require.True(t, bond1to1.Equal(allBonds[0])) + require.True(t, bond1to2.Equal(allBonds[1])) + require.True(t, bond1to3.Equal(allBonds[2])) + require.True(t, bond2to1.Equal(allBonds[3])) + require.True(t, bond2to2.Equal(allBonds[4])) + require.True(t, bond2to3.Equal(allBonds[5])) + + resVals := app.StakingKeeper.GetDelegatorValidators(ctx, addrs[0], 3) + require.Equal(t, 3, len(resVals)) + resVals = app.StakingKeeper.GetDelegatorValidators(ctx, addrs[1], 4) + require.Equal(t, 3, len(resVals)) + + for i := 0; i < 3; i++ { + resVal, err := app.StakingKeeper.GetDelegatorValidator(ctx, addrs[0], sdk.ValAddress(addrs[i])) + require.Nil(t, err) + require.Equal(t, sdk.ValAddress(addrs[i]), resVal.GetOperator()) + + resVal, err = app.StakingKeeper.GetDelegatorValidator(ctx, addrs[1], sdk.ValAddress(addrs[i])) + require.Nil(t, err) + require.Equal(t, sdk.ValAddress(addrs[i]), resVal.GetOperator()) + + resDels := app.StakingKeeper.GetValidatorDelegations(ctx, sdk.ValAddress(addrs[i])) + require.Len(t, resDels, 2) + } + + // delete a record + app.StakingKeeper.RemoveDelegation(ctx, bond2to3) + _, found = app.StakingKeeper.GetDelegation(ctx, addrs[1], sdk.ValAddress(addrs[2])) + require.False(t, found) + resBonds = app.StakingKeeper.GetDelegatorDelegations(ctx, addrs[1], 5) + require.Equal(t, 2, len(resBonds)) + require.True(t, bond2to1.Equal(resBonds[0])) + require.True(t, bond2to2.Equal(resBonds[1])) + + resBonds = app.StakingKeeper.GetAllDelegatorDelegations(ctx, addrs[1]) + require.Equal(t, 2, len(resBonds)) + + // delete all the records from delegator 2 + app.StakingKeeper.RemoveDelegation(ctx, bond2to1) + app.StakingKeeper.RemoveDelegation(ctx, bond2to2) + _, found = app.StakingKeeper.GetDelegation(ctx, addrs[1], sdk.ValAddress(addrs[0])) + require.False(t, found) + _, found = app.StakingKeeper.GetDelegation(ctx, addrs[1], sdk.ValAddress(addrs[1])) + require.False(t, found) + resBonds = app.StakingKeeper.GetDelegatorDelegations(ctx, addrDels[1], 5) + require.Equal(t, 0, len(resBonds)) +} + // tests Get/Set/Remove UnbondingDelegation func TestUnbondingDelegation(t *testing.T) { _, app, ctx := getBaseSimappWithCustomKeeper() From e5b67801a3ff5ae083718c72f0c5ac9bcb448f97 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Fri, 21 Feb 2020 20:51:11 +0100 Subject: [PATCH 19/90] refactor to use accounts --- simapp/test_helpers.go | 8 ++++ x/staking/keeper/delegation_test.go | 61 +++++++++++++++-------------- 2 files changed, 40 insertions(+), 29 deletions(-) diff --git a/simapp/test_helpers.go b/simapp/test_helpers.go index 36237bc5ec4a..cfedd7d3188f 100644 --- a/simapp/test_helpers.go +++ b/simapp/test_helpers.go @@ -144,6 +144,14 @@ func addTestAddrs(app *SimApp, ctx sdk.Context, accNum int, accAmt sdk.Int, stra return testAddrs } +func ConvertAddrsToValAddrs(addrs []sdk.AccAddress) (valAddrs []sdk.ValAddress) { + for _, addr := range addrs { + valAddrs = append(valAddrs, sdk.ValAddress(addr)) + } + + return +} + func TestAddr(addr string, bech string) sdk.AccAddress { res, err := sdk.AccAddressFromHex(addr) if err != nil { diff --git a/x/staking/keeper/delegation_test.go b/x/staking/keeper/delegation_test.go index 7c0bac9c4bb9..dbf4de871ff3 100644 --- a/x/staking/keeper/delegation_test.go +++ b/x/staking/keeper/delegation_test.go @@ -4,12 +4,11 @@ import ( "testing" "time" - "github.com/cosmos/cosmos-sdk/x/staking" - "github.com/stretchr/testify/require" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/staking" "github.com/cosmos/cosmos-sdk/x/staking/keeper" "github.com/cosmos/cosmos-sdk/x/staking/types" ) @@ -19,12 +18,13 @@ func TestDelegation(t *testing.T) { _, app, ctx := getBaseSimappWithCustomKeeper() addrs := simapp.AddTestAddrsIncremental(app, ctx, 3, sdk.NewInt(10000)) + valAddrs := simapp.ConvertAddrsToValAddrs(addrs) //construct the validators amts := []sdk.Int{sdk.NewInt(9), sdk.NewInt(8), sdk.NewInt(7)} var validators [3]types.Validator for i, amt := range amts { - validators[i] = types.NewValidator(sdk.ValAddress(addrs[i]), PKs[i], types.Description{}) + validators[i] = types.NewValidator(valAddrs[i], PKs[i], types.Description{}) validators[i], _ = validators[i].AddTokensFromDel(amt) } @@ -33,31 +33,31 @@ func TestDelegation(t *testing.T) { validators[2] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[2], true) // first add a validators[0] to delegate too - bond1to1 := types.NewDelegation(addrs[0], sdk.ValAddress(addrs[0]), sdk.NewDec(9)) + bond1to1 := types.NewDelegation(addrs[0], valAddrs[0], sdk.NewDec(9)) // check the empty keeper first - _, found := app.StakingKeeper.GetDelegation(ctx, addrs[0], sdk.ValAddress(addrs[0])) + _, found := app.StakingKeeper.GetDelegation(ctx, addrs[0], valAddrs[0]) require.False(t, found) // set and retrieve a record app.StakingKeeper.SetDelegation(ctx, bond1to1) - resBond, found := app.StakingKeeper.GetDelegation(ctx, addrs[0], sdk.ValAddress(addrs[0])) + resBond, found := app.StakingKeeper.GetDelegation(ctx, addrs[0], valAddrs[0]) require.True(t, found) require.True(t, bond1to1.Equal(resBond)) // modify a records, save, and retrieve bond1to1.Shares = sdk.NewDec(99) app.StakingKeeper.SetDelegation(ctx, bond1to1) - resBond, found = app.StakingKeeper.GetDelegation(ctx, addrs[0], sdk.ValAddress(addrs[0])) + resBond, found = app.StakingKeeper.GetDelegation(ctx, addrs[0], valAddrs[0]) require.True(t, found) require.True(t, bond1to1.Equal(resBond)) // add some more records - bond1to2 := types.NewDelegation(addrs[0], sdk.ValAddress(addrs[1]), sdk.NewDec(9)) - bond1to3 := types.NewDelegation(addrs[0], sdk.ValAddress(addrs[2]), sdk.NewDec(9)) - bond2to1 := types.NewDelegation(addrs[1], sdk.ValAddress(addrs[0]), sdk.NewDec(9)) - bond2to2 := types.NewDelegation(addrs[1], sdk.ValAddress(addrs[1]), sdk.NewDec(9)) - bond2to3 := types.NewDelegation(addrs[1], sdk.ValAddress(addrs[2]), sdk.NewDec(9)) + bond1to2 := types.NewDelegation(addrs[0], valAddrs[1], sdk.NewDec(9)) + bond1to3 := types.NewDelegation(addrs[0], valAddrs[2], sdk.NewDec(9)) + bond2to1 := types.NewDelegation(addrs[1], valAddrs[0], sdk.NewDec(9)) + bond2to2 := types.NewDelegation(addrs[1], valAddrs[1], sdk.NewDec(9)) + bond2to3 := types.NewDelegation(addrs[1], valAddrs[2], sdk.NewDec(9)) app.StakingKeeper.SetDelegation(ctx, bond1to2) app.StakingKeeper.SetDelegation(ctx, bond1to3) app.StakingKeeper.SetDelegation(ctx, bond2to1) @@ -94,21 +94,21 @@ func TestDelegation(t *testing.T) { require.Equal(t, 3, len(resVals)) for i := 0; i < 3; i++ { - resVal, err := app.StakingKeeper.GetDelegatorValidator(ctx, addrs[0], sdk.ValAddress(addrs[i])) + resVal, err := app.StakingKeeper.GetDelegatorValidator(ctx, addrs[0], valAddrs[i]) require.Nil(t, err) - require.Equal(t, sdk.ValAddress(addrs[i]), resVal.GetOperator()) + require.Equal(t, valAddrs[i], resVal.GetOperator()) - resVal, err = app.StakingKeeper.GetDelegatorValidator(ctx, addrs[1], sdk.ValAddress(addrs[i])) + resVal, err = app.StakingKeeper.GetDelegatorValidator(ctx, addrs[1], valAddrs[i]) require.Nil(t, err) - require.Equal(t, sdk.ValAddress(addrs[i]), resVal.GetOperator()) + require.Equal(t, valAddrs[i], resVal.GetOperator()) - resDels := app.StakingKeeper.GetValidatorDelegations(ctx, sdk.ValAddress(addrs[i])) + resDels := app.StakingKeeper.GetValidatorDelegations(ctx, valAddrs[i]) require.Len(t, resDels, 2) } // delete a record app.StakingKeeper.RemoveDelegation(ctx, bond2to3) - _, found = app.StakingKeeper.GetDelegation(ctx, addrs[1], sdk.ValAddress(addrs[2])) + _, found = app.StakingKeeper.GetDelegation(ctx, addrs[1], valAddrs[2]) require.False(t, found) resBonds = app.StakingKeeper.GetDelegatorDelegations(ctx, addrs[1], 5) require.Equal(t, 2, len(resBonds)) @@ -121,9 +121,9 @@ func TestDelegation(t *testing.T) { // delete all the records from delegator 2 app.StakingKeeper.RemoveDelegation(ctx, bond2to1) app.StakingKeeper.RemoveDelegation(ctx, bond2to2) - _, found = app.StakingKeeper.GetDelegation(ctx, addrs[1], sdk.ValAddress(addrs[0])) + _, found = app.StakingKeeper.GetDelegation(ctx, addrs[1], valAddrs[0]) require.False(t, found) - _, found = app.StakingKeeper.GetDelegation(ctx, addrs[1], sdk.ValAddress(addrs[1])) + _, found = app.StakingKeeper.GetDelegation(ctx, addrs[1], valAddrs[1]) require.False(t, found) resBonds = app.StakingKeeper.GetDelegatorDelegations(ctx, addrDels[1], 5) require.Equal(t, 0, len(resBonds)) @@ -133,9 +133,12 @@ func TestDelegation(t *testing.T) { func TestUnbondingDelegation(t *testing.T) { _, app, ctx := getBaseSimappWithCustomKeeper() + delAddrs := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(10000)) + valAddrs := simapp.ConvertAddrsToValAddrs(delAddrs) + ubd := types.NewUnbondingDelegation( - addrDels[0], - addrVals[0], + delAddrs[0], + valAddrs[0], 0, time.Unix(0, 0), sdk.NewInt(5), @@ -143,7 +146,7 @@ func TestUnbondingDelegation(t *testing.T) { // set and retrieve a record app.StakingKeeper.SetUnbondingDelegation(ctx, ubd) - resUnbond, found := app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) + resUnbond, found := app.StakingKeeper.GetUnbondingDelegation(ctx, delAddrs[0], valAddrs[0]) require.True(t, found) require.True(t, ubd.Equal(resUnbond)) @@ -151,25 +154,25 @@ func TestUnbondingDelegation(t *testing.T) { ubd.Entries[0].Balance = sdk.NewInt(21) app.StakingKeeper.SetUnbondingDelegation(ctx, ubd) - resUnbonds := app.StakingKeeper.GetUnbondingDelegations(ctx, addrDels[0], 5) + resUnbonds := app.StakingKeeper.GetUnbondingDelegations(ctx, delAddrs[0], 5) require.Equal(t, 1, len(resUnbonds)) - resUnbonds = app.StakingKeeper.GetAllUnbondingDelegations(ctx, addrDels[0]) + resUnbonds = app.StakingKeeper.GetAllUnbondingDelegations(ctx, delAddrs[0]) require.Equal(t, 1, len(resUnbonds)) - resUnbond, found = app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) + resUnbond, found = app.StakingKeeper.GetUnbondingDelegation(ctx, delAddrs[0], valAddrs[0]) require.True(t, found) require.True(t, ubd.Equal(resUnbond)) // delete a record app.StakingKeeper.RemoveUnbondingDelegation(ctx, ubd) - _, found = app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) + _, found = app.StakingKeeper.GetUnbondingDelegation(ctx, delAddrs[0], valAddrs[0]) require.False(t, found) - resUnbonds = app.StakingKeeper.GetUnbondingDelegations(ctx, addrDels[0], 5) + resUnbonds = app.StakingKeeper.GetUnbondingDelegations(ctx, delAddrs[0], 5) require.Equal(t, 0, len(resUnbonds)) - resUnbonds = app.StakingKeeper.GetAllUnbondingDelegations(ctx, addrDels[0]) + resUnbonds = app.StakingKeeper.GetAllUnbondingDelegations(ctx, delAddrs[0]) require.Equal(t, 0, len(resUnbonds)) } From 8cf9219a53288a68847f7af0e66696c8b1c2bfd3 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Fri, 21 Feb 2020 21:05:56 +0100 Subject: [PATCH 20/90] refactor test unbondingdelegationsmax entries --- x/staking/keeper/delegation_test.go | 190 +++++++++++++--------------- 1 file changed, 88 insertions(+), 102 deletions(-) diff --git a/x/staking/keeper/delegation_test.go b/x/staking/keeper/delegation_test.go index dbf4de871ff3..9d7c2fbed31f 100644 --- a/x/staking/keeper/delegation_test.go +++ b/x/staking/keeper/delegation_test.go @@ -8,7 +8,6 @@ import ( "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/staking" "github.com/cosmos/cosmos-sdk/x/staking/keeper" "github.com/cosmos/cosmos-sdk/x/staking/types" ) @@ -179,14 +178,8 @@ func TestUnbondingDelegation(t *testing.T) { func TestUnbondDelegation(t *testing.T) { _, app, ctx := getBaseSimappWithCustomKeeper() - codec := simapp.NewAppCodec() - app.StakingKeeper = keeper.NewKeeper( - codec.Staking, - app.GetKey(staking.StoreKey), - app.BankKeeper, - app.SupplyKeeper, - app.GetSubspace(staking.ModuleName), - ) + delAddrs := simapp.AddTestAddrsIncremental(app, ctx, 1, sdk.NewInt(10000)) + valAddrs := simapp.ConvertAddrsToValAddrs(delAddrs) startTokens := sdk.TokensFromConsensusPower(10) notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) @@ -202,24 +195,24 @@ func TestUnbondDelegation(t *testing.T) { // create a validator and a delegator to that validator // note this validator starts not-bonded - validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) + validator := types.NewValidator(valAddrs[0], PKs[0], types.Description{}) validator, issuedShares := validator.AddTokensFromDel(startTokens) require.Equal(t, startTokens, issuedShares.RoundInt()) validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) - delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) + delegation := types.NewDelegation(delAddrs[0], valAddrs[0], issuedShares) app.StakingKeeper.SetDelegation(ctx, delegation) bondTokens := sdk.TokensFromConsensusPower(6) - amount, err := app.StakingKeeper.Unbond(ctx, addrDels[0], addrVals[0], bondTokens.ToDec()) + amount, err := app.StakingKeeper.Unbond(ctx, delAddrs[0], valAddrs[0], bondTokens.ToDec()) require.NoError(t, err) require.Equal(t, bondTokens, amount) // shares to be added to an unbonding delegation - delegation, found := app.StakingKeeper.GetDelegation(ctx, addrDels[0], addrVals[0]) + delegation, found := app.StakingKeeper.GetDelegation(ctx, delAddrs[0], valAddrs[0]) require.True(t, found) - validator, found = app.StakingKeeper.GetValidator(ctx, addrVals[0]) + validator, found = app.StakingKeeper.GetValidator(ctx, valAddrs[0]) require.True(t, found) remainingTokens := startTokens.Sub(bondTokens) @@ -227,94 +220,87 @@ func TestUnbondDelegation(t *testing.T) { require.Equal(t, remainingTokens, validator.BondedTokens()) } -//func TestUnbondingDelegationsMaxEntries(t *testing.T) { -// app := simapp.Setup(false) -// ctx := app.BaseApp.NewContext(false, abci.Header{}) -// -// codec := simapp.NewAppCodec() -// app.StakingKeeper = keeper.NewKeeper( -// codec.Staking, -// app.GetKey(staking.StoreKey), -// app.BankKeeper, -// app.SupplyKeeper, -// app.GetSubspace(staking.ModuleName), -// ) -// -// startTokens := sdk.TokensFromConsensusPower(10) -// -// bondDenom := app.StakingKeeper.BondDenom(ctx) -// notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) -// -// err := app.BankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(bondDenom, startTokens))) -// require.NoError(t, err) -// app.SupplyKeeper.SetModuleAccount(ctx, notBondedPool) -// -// // create a validator and a delegator to that validator -// validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) -// -// validator, issuedShares := validator.AddTokensFromDel(startTokens) -// require.Equal(t, startTokens, issuedShares.RoundInt()) -// -// validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) -// require.True(sdk.IntEq(t, startTokens, validator.BondedTokens())) -// require.True(t, validator.IsBonded()) -// -// delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) -// app.StakingKeeper.SetDelegation(ctx, delegation) -// -// maxEntries := app.StakingKeeper.MaxEntries(ctx) -// -// oldBonded := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount -// oldNotBonded := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount -// -// // should all pass -// var completionTime time.Time -// for i := uint32(0); i < maxEntries; i++ { -// var err error -// completionTime, err = app.StakingKeeper.Undelegate(ctx, addrDels[0], addrVals[0], sdk.NewDec(1)) -// require.NoError(t, err) -// } -// -// newBonded := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount -// newNotBonded := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount -// require.True(sdk.IntEq(t, newBonded, oldBonded.SubRaw(int64(maxEntries)))) -// require.True(sdk.IntEq(t, newNotBonded, oldNotBonded.AddRaw(int64(maxEntries)))) -// -// oldBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount -// oldNotBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount -// -// // an additional unbond should fail due to max entries -// _, err = app.StakingKeeper.Undelegate(ctx, addrDels[0], addrVals[0], sdk.NewDec(1)) -// require.Error(t, err) -// -// newBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount -// newNotBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount -// -// require.True(sdk.IntEq(t, newBonded, oldBonded)) -// require.True(sdk.IntEq(t, newNotBonded, oldNotBonded)) -// -// // mature unbonding delegations -// ctx = ctx.WithBlockTime(completionTime) -// err = app.StakingKeeper.CompleteUnbonding(ctx, addrDels[0], addrVals[0]) -// require.NoError(t, err) -// -// newBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount -// newNotBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount -// require.True(sdk.IntEq(t, newBonded, oldBonded)) -// require.True(sdk.IntEq(t, newNotBonded, oldNotBonded.SubRaw(int64(maxEntries)))) -// -// oldNotBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount -// -// // unbonding should work again -// _, err = app.StakingKeeper.Undelegate(ctx, addrDels[0], addrVals[0], sdk.NewDec(1)) -// require.NoError(t, err) -// -// newBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount -// newNotBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount -// require.True(sdk.IntEq(t, newBonded, oldBonded.SubRaw(1))) -// require.True(sdk.IntEq(t, newNotBonded, oldNotBonded.AddRaw(1))) -//} -// +func TestUnbondingDelegationsMaxEntries(t *testing.T) { + _, app, ctx := getBaseSimappWithCustomKeeper() + + addrDels := simapp.AddTestAddrsIncremental(app, ctx, 1, sdk.NewInt(10000)) + addrVals := simapp.ConvertAddrsToValAddrs(addrDels) + + startTokens := sdk.TokensFromConsensusPower(10) + + bondDenom := app.StakingKeeper.BondDenom(ctx) + notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) + + err := app.BankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(bondDenom, startTokens))) + require.NoError(t, err) + app.SupplyKeeper.SetModuleAccount(ctx, notBondedPool) + + // create a validator and a delegator to that validator + validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) + + validator, issuedShares := validator.AddTokensFromDel(startTokens) + require.Equal(t, startTokens, issuedShares.RoundInt()) + + validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) + require.True(sdk.IntEq(t, startTokens, validator.BondedTokens())) + require.True(t, validator.IsBonded()) + + delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) + app.StakingKeeper.SetDelegation(ctx, delegation) + + maxEntries := app.StakingKeeper.MaxEntries(ctx) + + oldBonded := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount + oldNotBonded := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount + + // should all pass + var completionTime time.Time + for i := uint32(0); i < maxEntries; i++ { + var err error + completionTime, err = app.StakingKeeper.Undelegate(ctx, addrDels[0], addrVals[0], sdk.NewDec(1)) + require.NoError(t, err) + } + + newBonded := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount + newNotBonded := app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount + require.True(sdk.IntEq(t, newBonded, oldBonded.SubRaw(int64(maxEntries)))) + require.True(sdk.IntEq(t, newNotBonded, oldNotBonded.AddRaw(int64(maxEntries)))) + + oldBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount + oldNotBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount + + // an additional unbond should fail due to max entries + _, err = app.StakingKeeper.Undelegate(ctx, addrDels[0], addrVals[0], sdk.NewDec(1)) + require.Error(t, err) + + newBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount + newNotBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount + + require.True(sdk.IntEq(t, newBonded, oldBonded)) + require.True(sdk.IntEq(t, newNotBonded, oldNotBonded)) + + // mature unbonding delegations + ctx = ctx.WithBlockTime(completionTime) + err = app.StakingKeeper.CompleteUnbonding(ctx, addrDels[0], addrVals[0]) + require.NoError(t, err) + + newBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount + newNotBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount + require.True(sdk.IntEq(t, newBonded, oldBonded)) + require.True(sdk.IntEq(t, newNotBonded, oldNotBonded.SubRaw(int64(maxEntries)))) + + oldNotBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount + + // unbonding should work again + _, err = app.StakingKeeper.Undelegate(ctx, addrDels[0], addrVals[0], sdk.NewDec(1)) + require.NoError(t, err) + + newBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetBondedPool(ctx).GetAddress(), bondDenom).Amount + newNotBonded = app.BankKeeper.GetBalance(ctx, app.StakingKeeper.GetNotBondedPool(ctx).GetAddress(), bondDenom).Amount + require.True(sdk.IntEq(t, newBonded, oldBonded.SubRaw(1))) + require.True(sdk.IntEq(t, newNotBonded, oldNotBonded.AddRaw(1))) +} + //// test undelegating self delegation from a validator pushing it below MinSelfDelegation //// shift it from the bonded to unbonding state and jailed //func TestUndelegateSelfDelegationBelowMinSelfDelegation(t *testing.T) { From 8378be277ce065be341a640c33e738c56a10d922 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Fri, 21 Feb 2020 21:18:24 +0100 Subject: [PATCH 21/90] refactor TestUndelegateSelfDelegationBelowMinSelfDelegation to use simapp --- x/staking/keeper/delegation_test.go | 129 ++++++++++++------------ x/staking/keeper/old_delegation_test.go | 71 +------------ 2 files changed, 69 insertions(+), 131 deletions(-) diff --git a/x/staking/keeper/delegation_test.go b/x/staking/keeper/delegation_test.go index 9d7c2fbed31f..d4004fd0385d 100644 --- a/x/staking/keeper/delegation_test.go +++ b/x/staking/keeper/delegation_test.go @@ -303,69 +303,72 @@ func TestUnbondingDelegationsMaxEntries(t *testing.T) { //// test undelegating self delegation from a validator pushing it below MinSelfDelegation //// shift it from the bonded to unbonding state and jailed -//func TestUndelegateSelfDelegationBelowMinSelfDelegation(t *testing.T) { -// ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) -// delTokens := sdk.TokensFromConsensusPower(10) -// delCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), delTokens)) -// -// //create a validator with a self-delegation -// validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) -// -// validator.MinSelfDelegation = delTokens -// validator, issuedShares := validator.AddTokensFromDel(delTokens) -// require.Equal(t, delTokens, issuedShares.RoundInt()) -// -// // add bonded tokens to pool for delegations -// notBondedPool := keeper.GetNotBondedPool(ctx) -// oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) -// err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(delCoins...)) -// require.NoError(t, err) -// keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) -// -// validator = TestingUpdateValidator(keeper, ctx, validator, true) -// require.True(t, validator.IsBonded()) -// -// selfDelegation := types.NewDelegation(sdk.AccAddress(addrVals[0].Bytes()), addrVals[0], issuedShares) -// keeper.SetDelegation(ctx, selfDelegation) -// -// // add bonded tokens to pool for delegations -// bondedPool := keeper.GetBondedPool(ctx) -// oldBonded := bk.GetAllBalances(ctx, bondedPool.GetAddress()) -// err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) -// require.NoError(t, err) -// keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) -// -// // create a second delegation to this validator -// keeper.DeleteValidatorByPowerIndex(ctx, validator) -// validator, issuedShares = validator.AddTokensFromDel(delTokens) -// require.True(t, validator.IsBonded()) -// require.Equal(t, delTokens, issuedShares.RoundInt()) -// -// // add bonded tokens to pool for delegations -// oldBonded = bk.GetAllBalances(ctx, bondedPool.GetAddress()) -// err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) -// require.NoError(t, err) -// keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) -// -// validator = TestingUpdateValidator(keeper, ctx, validator, true) -// delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) -// keeper.SetDelegation(ctx, delegation) -// -// val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) -// _, err = keeper.Undelegate(ctx, val0AccAddr, addrVals[0], sdk.TokensFromConsensusPower(6).ToDec()) -// require.NoError(t, err) -// -// // end block -// updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) -// require.Equal(t, 1, len(updates)) -// -// validator, found := keeper.GetValidator(ctx, addrVals[0]) -// require.True(t, found) -// require.Equal(t, sdk.TokensFromConsensusPower(14), validator.Tokens) -// require.Equal(t, sdk.Unbonding, validator.Status) -// require.True(t, validator.Jailed) -//} -// +func TestUndelegateSelfDelegationBelowMinSelfDelegation(t *testing.T) { + _, app, ctx := getBaseSimappWithCustomKeeper() + + addrDels := simapp.AddTestAddrsIncremental(app, ctx, 1, sdk.NewInt(10000)) + addrVals := simapp.ConvertAddrsToValAddrs(addrDels) + delTokens := sdk.TokensFromConsensusPower(10) + delCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), delTokens)) + + //create a validator with a self-delegation + validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) + + validator.MinSelfDelegation = delTokens + validator, issuedShares := validator.AddTokensFromDel(delTokens) + require.Equal(t, delTokens, issuedShares.RoundInt()) + + // add bonded tokens to pool for delegations + notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) + oldNotBonded := app.BankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress()) + err := app.BankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(delCoins...)) + require.NoError(t, err) + app.SupplyKeeper.SetModuleAccount(ctx, notBondedPool) + + validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) + require.True(t, validator.IsBonded()) + + selfDelegation := types.NewDelegation(sdk.AccAddress(addrVals[0].Bytes()), addrVals[0], issuedShares) + app.StakingKeeper.SetDelegation(ctx, selfDelegation) + + // add bonded tokens to pool for delegations + bondedPool := app.StakingKeeper.GetBondedPool(ctx) + oldBonded := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + err = app.BankKeeper.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) + require.NoError(t, err) + app.SupplyKeeper.SetModuleAccount(ctx, bondedPool) + + // create a second delegation to this validator + app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validator) + validator, issuedShares = validator.AddTokensFromDel(delTokens) + require.True(t, validator.IsBonded()) + require.Equal(t, delTokens, issuedShares.RoundInt()) + + // add bonded tokens to pool for delegations + oldBonded = app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + err = app.BankKeeper.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) + require.NoError(t, err) + app.SupplyKeeper.SetModuleAccount(ctx, bondedPool) + + validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) + delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) + app.StakingKeeper.SetDelegation(ctx, delegation) + + val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) + _, err = app.StakingKeeper.Undelegate(ctx, val0AccAddr, addrVals[0], sdk.TokensFromConsensusPower(6).ToDec()) + require.NoError(t, err) + + // end block + updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 1, len(updates)) + + validator, found := app.StakingKeeper.GetValidator(ctx, addrVals[0]) + require.True(t, found) + require.Equal(t, sdk.TokensFromConsensusPower(14), validator.Tokens) + require.Equal(t, sdk.Unbonding, validator.Status) + require.True(t, validator.Jailed) +} + //func TestUndelegateFromUnbondingValidator(t *testing.T) { // ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) // delTokens := sdk.TokensFromConsensusPower(10) diff --git a/x/staking/keeper/old_delegation_test.go b/x/staking/keeper/old_delegation_test.go index 2e22045f707b..00a28864da5b 100644 --- a/x/staking/keeper/old_delegation_test.go +++ b/x/staking/keeper/old_delegation_test.go @@ -4,77 +4,12 @@ import ( "testing" "time" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" -) - -// test undelegating self delegation from a validator pushing it below MinSelfDelegation -// shift it from the bonded to unbonding state and jailed -func TestUndelegateSelfDelegationBelowMinSelfDelegation(t *testing.T) { - ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) - delTokens := sdk.TokensFromConsensusPower(10) - delCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), delTokens)) - - //create a validator with a self-delegation - validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) - - validator.MinSelfDelegation = delTokens - validator, issuedShares := validator.AddTokensFromDel(delTokens) - require.Equal(t, delTokens, issuedShares.RoundInt()) - - // add bonded tokens to pool for delegations - notBondedPool := keeper.GetNotBondedPool(ctx) - oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) - err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(delCoins...)) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - validator = TestingUpdateValidator(keeper, ctx, validator, true) - require.True(t, validator.IsBonded()) - - selfDelegation := types.NewDelegation(sdk.AccAddress(addrVals[0].Bytes()), addrVals[0], issuedShares) - keeper.SetDelegation(ctx, selfDelegation) - - // add bonded tokens to pool for delegations - bondedPool := keeper.GetBondedPool(ctx) - oldBonded := bk.GetAllBalances(ctx, bondedPool.GetAddress()) - err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) - - // create a second delegation to this validator - keeper.DeleteValidatorByPowerIndex(ctx, validator) - validator, issuedShares = validator.AddTokensFromDel(delTokens) - require.True(t, validator.IsBonded()) - require.Equal(t, delTokens, issuedShares.RoundInt()) - - // add bonded tokens to pool for delegations - oldBonded = bk.GetAllBalances(ctx, bondedPool.GetAddress()) - err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) - - validator = TestingUpdateValidator(keeper, ctx, validator, true) - delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) - keeper.SetDelegation(ctx, delegation) - - val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) - _, err = keeper.Undelegate(ctx, val0AccAddr, addrVals[0], sdk.TokensFromConsensusPower(6).ToDec()) - require.NoError(t, err) - - // end block - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 1, len(updates)) - validator, found := keeper.GetValidator(ctx, addrVals[0]) - require.True(t, found) - require.Equal(t, sdk.TokensFromConsensusPower(14), validator.Tokens) - require.Equal(t, sdk.Unbonding, validator.Status) - require.True(t, validator.Jailed) -} + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/staking/types" +) func TestUndelegateFromUnbondingValidator(t *testing.T) { ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) From bbc2b33f7d8c9cb5169de8bc618fd540e365e863 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Mon, 24 Feb 2020 12:24:25 +0100 Subject: [PATCH 22/90] update TestUndelegate from unbonding validator and fix bug --- x/staking/keeper/delegation_test.go | 184 ++++++++++++------------ x/staking/keeper/old_delegation_test.go | 90 ------------ 2 files changed, 94 insertions(+), 180 deletions(-) diff --git a/x/staking/keeper/delegation_test.go b/x/staking/keeper/delegation_test.go index d4004fd0385d..073bc1b84634 100644 --- a/x/staking/keeper/delegation_test.go +++ b/x/staking/keeper/delegation_test.go @@ -4,6 +4,7 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/cosmos/cosmos-sdk/simapp" @@ -369,96 +370,99 @@ func TestUndelegateSelfDelegationBelowMinSelfDelegation(t *testing.T) { require.True(t, validator.Jailed) } -//func TestUndelegateFromUnbondingValidator(t *testing.T) { -// ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) -// delTokens := sdk.TokensFromConsensusPower(10) -// delCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), delTokens)) -// -// //create a validator with a self-delegation -// validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) -// -// validator, issuedShares := validator.AddTokensFromDel(delTokens) -// require.Equal(t, delTokens, issuedShares.RoundInt()) -// -// // add bonded tokens to pool for delegations -// notBondedPool := keeper.GetNotBondedPool(ctx) -// oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) -// err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(delCoins...)) -// require.NoError(t, err) -// keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) -// -// validator = TestingUpdateValidator(keeper, ctx, validator, true) -// require.True(t, validator.IsBonded()) -// -// selfDelegation := types.NewDelegation(sdk.AccAddress(addrVals[0].Bytes()), addrVals[0], issuedShares) -// keeper.SetDelegation(ctx, selfDelegation) -// -// bondedPool := keeper.GetBondedPool(ctx) -// oldBonded := bk.GetAllBalances(ctx, bondedPool.GetAddress()) -// err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) -// require.NoError(t, err) -// keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) -// -// // create a second delegation to this validator -// keeper.DeleteValidatorByPowerIndex(ctx, validator) -// -// validator, issuedShares = validator.AddTokensFromDel(delTokens) -// require.Equal(t, delTokens, issuedShares.RoundInt()) -// -// oldBonded = bk.GetAllBalances(ctx, bondedPool.GetAddress()) -// err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) -// require.NoError(t, err) -// keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) -// -// validator = TestingUpdateValidator(keeper, ctx, validator, true) -// delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) -// keeper.SetDelegation(ctx, delegation) -// -// oldBonded = bk.GetAllBalances(ctx, bondedPool.GetAddress()) -// err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) -// require.NoError(t, err) -// keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) -// -// header := ctx.BlockHeader() -// blockHeight := int64(10) -// header.Height = blockHeight -// blockTime := time.Unix(333, 0) -// header.Time = blockTime -// ctx = ctx.WithBlockHeader(header) -// -// // unbond the all self-delegation to put validator in unbonding state -// val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) -// _, err = keeper.Undelegate(ctx, val0AccAddr, addrVals[0], delTokens.ToDec()) -// require.NoError(t, err) -// -// // end block -// updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) -// require.Equal(t, 1, len(updates)) -// -// validator, found := keeper.GetValidator(ctx, addrVals[0]) -// require.True(t, found) -// require.Equal(t, blockHeight, validator.UnbondingHeight) -// params := keeper.GetParams(ctx) -// require.True(t, blockTime.Add(params.UnbondingTime).Equal(validator.UnbondingTime)) -// -// blockHeight2 := int64(20) -// blockTime2 := time.Unix(444, 0).UTC() -// ctx = ctx.WithBlockHeight(blockHeight2) -// ctx = ctx.WithBlockTime(blockTime2) -// -// // unbond some of the other delegation's shares -// _, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], sdk.NewDec(6)) -// require.NoError(t, err) -// -// // retrieve the unbonding delegation -// ubd, found := keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) -// require.True(t, found) -// require.Len(t, ubd.Entries, 1) -// require.True(t, ubd.Entries[0].Balance.Equal(sdk.NewInt(6))) -// assert.Equal(t, blockHeight2, ubd.Entries[0].CreationHeight) -// assert.True(t, blockTime2.Add(params.UnbondingTime).Equal(ubd.Entries[0].CompletionTime)) -//} -// +func TestUndelegateFromUnbondingValidator(t *testing.T) { + _, app, ctx := getBaseSimappWithCustomKeeper() + delTokens := sdk.TokensFromConsensusPower(10) + delCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), delTokens)) + + addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(0)) + addrVals := simapp.ConvertAddrsToValAddrs(addrDels) + + //create a validator with a self-delegation + validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) + + validator, issuedShares := validator.AddTokensFromDel(delTokens) + require.Equal(t, delTokens, issuedShares.RoundInt()) + + // add bonded tokens to pool for delegations + notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) + oldNotBonded := app.BankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress()) + err := app.BankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(delCoins...)) + require.NoError(t, err) + app.SupplyKeeper.SetModuleAccount(ctx, notBondedPool) + + validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) + require.True(t, validator.IsBonded()) + + selfDelegation := types.NewDelegation(addrVals[0].Bytes(), addrVals[0], issuedShares) + app.StakingKeeper.SetDelegation(ctx, selfDelegation) + + bondedPool := app.StakingKeeper.GetBondedPool(ctx) + oldBonded := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + err = app.BankKeeper.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) + require.NoError(t, err) + app.SupplyKeeper.SetModuleAccount(ctx, bondedPool) + + // create a second delegation to this validator + app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validator) + + validator, issuedShares = validator.AddTokensFromDel(delTokens) + require.Equal(t, delTokens, issuedShares.RoundInt()) + + oldBonded = app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + err = app.BankKeeper.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) + require.NoError(t, err) + app.SupplyKeeper.SetModuleAccount(ctx, bondedPool) + + validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) + delegation := types.NewDelegation(addrDels[1], addrVals[0], issuedShares) + app.StakingKeeper.SetDelegation(ctx, delegation) + + oldBonded = app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + err = app.BankKeeper.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) + require.NoError(t, err) + app.SupplyKeeper.SetModuleAccount(ctx, bondedPool) + + header := ctx.BlockHeader() + blockHeight := int64(10) + header.Height = blockHeight + blockTime := time.Unix(333, 0) + header.Time = blockTime + ctx = ctx.WithBlockHeader(header) + + // unbond the all self-delegation to put validator in unbonding state + val0AccAddr := sdk.AccAddress(addrVals[0]) + _, err = app.StakingKeeper.Undelegate(ctx, val0AccAddr, addrVals[0], delTokens.ToDec()) + require.NoError(t, err) + + // end block + updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 1, len(updates)) + + validator, found := app.StakingKeeper.GetValidator(ctx, addrVals[0]) + require.True(t, found) + require.Equal(t, blockHeight, validator.UnbondingHeight) + params := app.StakingKeeper.GetParams(ctx) + require.True(t, blockTime.Add(params.UnbondingTime).Equal(validator.UnbondingTime)) + + blockHeight2 := int64(20) + blockTime2 := time.Unix(444, 0).UTC() + ctx = ctx.WithBlockHeight(blockHeight2) + ctx = ctx.WithBlockTime(blockTime2) + + // unbond some of the other delegation's shares + _, err = app.StakingKeeper.Undelegate(ctx, addrDels[1], addrVals[0], sdk.NewDec(6)) + require.NoError(t, err) + + // retrieve the unbonding delegation + ubd, found := app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[1], addrVals[0]) + require.True(t, found) + require.Len(t, ubd.Entries, 1) + require.True(t, ubd.Entries[0].Balance.Equal(sdk.NewInt(6))) + assert.Equal(t, blockHeight2, ubd.Entries[0].CreationHeight) + assert.True(t, blockTime2.Add(params.UnbondingTime).Equal(ubd.Entries[0].CompletionTime)) +} + //func TestUndelegateFromUnbondedValidator(t *testing.T) { // ctx, _, bk, keeper, _ := CreateTestInput(t, false, 1) // delTokens := sdk.TokensFromConsensusPower(10) diff --git a/x/staking/keeper/old_delegation_test.go b/x/staking/keeper/old_delegation_test.go index 00a28864da5b..e4e2026425d3 100644 --- a/x/staking/keeper/old_delegation_test.go +++ b/x/staking/keeper/old_delegation_test.go @@ -11,96 +11,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/staking/types" ) -func TestUndelegateFromUnbondingValidator(t *testing.T) { - ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) - delTokens := sdk.TokensFromConsensusPower(10) - delCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), delTokens)) - - //create a validator with a self-delegation - validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) - - validator, issuedShares := validator.AddTokensFromDel(delTokens) - require.Equal(t, delTokens, issuedShares.RoundInt()) - - // add bonded tokens to pool for delegations - notBondedPool := keeper.GetNotBondedPool(ctx) - oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) - err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(delCoins...)) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - validator = TestingUpdateValidator(keeper, ctx, validator, true) - require.True(t, validator.IsBonded()) - - selfDelegation := types.NewDelegation(sdk.AccAddress(addrVals[0].Bytes()), addrVals[0], issuedShares) - keeper.SetDelegation(ctx, selfDelegation) - - bondedPool := keeper.GetBondedPool(ctx) - oldBonded := bk.GetAllBalances(ctx, bondedPool.GetAddress()) - err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) - - // create a second delegation to this validator - keeper.DeleteValidatorByPowerIndex(ctx, validator) - - validator, issuedShares = validator.AddTokensFromDel(delTokens) - require.Equal(t, delTokens, issuedShares.RoundInt()) - - oldBonded = bk.GetAllBalances(ctx, bondedPool.GetAddress()) - err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) - - validator = TestingUpdateValidator(keeper, ctx, validator, true) - delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) - keeper.SetDelegation(ctx, delegation) - - oldBonded = bk.GetAllBalances(ctx, bondedPool.GetAddress()) - err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) - - header := ctx.BlockHeader() - blockHeight := int64(10) - header.Height = blockHeight - blockTime := time.Unix(333, 0) - header.Time = blockTime - ctx = ctx.WithBlockHeader(header) - - // unbond the all self-delegation to put validator in unbonding state - val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) - _, err = keeper.Undelegate(ctx, val0AccAddr, addrVals[0], delTokens.ToDec()) - require.NoError(t, err) - - // end block - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 1, len(updates)) - - validator, found := keeper.GetValidator(ctx, addrVals[0]) - require.True(t, found) - require.Equal(t, blockHeight, validator.UnbondingHeight) - params := keeper.GetParams(ctx) - require.True(t, blockTime.Add(params.UnbondingTime).Equal(validator.UnbondingTime)) - - blockHeight2 := int64(20) - blockTime2 := time.Unix(444, 0).UTC() - ctx = ctx.WithBlockHeight(blockHeight2) - ctx = ctx.WithBlockTime(blockTime2) - - // unbond some of the other delegation's shares - _, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], sdk.NewDec(6)) - require.NoError(t, err) - - // retrieve the unbonding delegation - ubd, found := keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) - require.True(t, found) - require.Len(t, ubd.Entries, 1) - require.True(t, ubd.Entries[0].Balance.Equal(sdk.NewInt(6))) - assert.Equal(t, blockHeight2, ubd.Entries[0].CreationHeight) - assert.True(t, blockTime2.Add(params.UnbondingTime).Equal(ubd.Entries[0].CompletionTime)) -} - func TestUndelegateFromUnbondedValidator(t *testing.T) { ctx, _, bk, keeper, _ := CreateTestInput(t, false, 1) delTokens := sdk.TokensFromConsensusPower(10) From 6ce12184d4621ad234187322650e87b4738a6dba Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Mon, 24 Feb 2020 12:37:32 +0100 Subject: [PATCH 23/90] refactor TestUndelegateFromUnbondedValidator to use simapp --- x/staking/keeper/delegation_test.go | 165 ++++++++++++------------ x/staking/keeper/old_delegation_test.go | 81 ------------ 2 files changed, 84 insertions(+), 162 deletions(-) diff --git a/x/staking/keeper/delegation_test.go b/x/staking/keeper/delegation_test.go index 073bc1b84634..63e8e8fd7229 100644 --- a/x/staking/keeper/delegation_test.go +++ b/x/staking/keeper/delegation_test.go @@ -463,87 +463,90 @@ func TestUndelegateFromUnbondingValidator(t *testing.T) { assert.True(t, blockTime2.Add(params.UnbondingTime).Equal(ubd.Entries[0].CompletionTime)) } -//func TestUndelegateFromUnbondedValidator(t *testing.T) { -// ctx, _, bk, keeper, _ := CreateTestInput(t, false, 1) -// delTokens := sdk.TokensFromConsensusPower(10) -// delCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), delTokens)) -// -// // add bonded tokens to pool for delegations -// notBondedPool := keeper.GetNotBondedPool(ctx) -// oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) -// err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(delCoins...)) -// require.NoError(t, err) -// keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) -// -// // create a validator with a self-delegation -// validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) -// -// valTokens := sdk.TokensFromConsensusPower(10) -// validator, issuedShares := validator.AddTokensFromDel(valTokens) -// require.Equal(t, valTokens, issuedShares.RoundInt()) -// validator = TestingUpdateValidator(keeper, ctx, validator, true) -// require.True(t, validator.IsBonded()) -// -// val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) -// selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) -// keeper.SetDelegation(ctx, selfDelegation) -// -// bondedPool := keeper.GetBondedPool(ctx) -// oldBonded := bk.GetAllBalances(ctx, bondedPool.GetAddress()) -// err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) -// require.NoError(t, err) -// keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) -// -// // create a second delegation to this validator -// keeper.DeleteValidatorByPowerIndex(ctx, validator) -// validator, issuedShares = validator.AddTokensFromDel(delTokens) -// require.Equal(t, delTokens, issuedShares.RoundInt()) -// validator = TestingUpdateValidator(keeper, ctx, validator, true) -// require.True(t, validator.IsBonded()) -// delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) -// keeper.SetDelegation(ctx, delegation) -// -// ctx = ctx.WithBlockHeight(10) -// ctx = ctx.WithBlockTime(time.Unix(333, 0)) -// -// // unbond the all self-delegation to put validator in unbonding state -// _, err = keeper.Undelegate(ctx, val0AccAddr, addrVals[0], valTokens.ToDec()) -// require.NoError(t, err) -// -// // end block -// updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) -// require.Equal(t, 1, len(updates)) -// -// validator, found := keeper.GetValidator(ctx, addrVals[0]) -// require.True(t, found) -// require.Equal(t, ctx.BlockHeight(), validator.UnbondingHeight) -// params := keeper.GetParams(ctx) -// require.True(t, ctx.BlockHeader().Time.Add(params.UnbondingTime).Equal(validator.UnbondingTime)) -// -// // unbond the validator -// ctx = ctx.WithBlockTime(validator.UnbondingTime) -// keeper.UnbondAllMatureValidatorQueue(ctx) -// -// // Make sure validator is still in state because there is still an outstanding delegation -// validator, found = keeper.GetValidator(ctx, addrVals[0]) -// require.True(t, found) -// require.Equal(t, validator.Status, sdk.Unbonded) -// -// // unbond some of the other delegation's shares -// unbondTokens := sdk.TokensFromConsensusPower(6) -// _, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], unbondTokens.ToDec()) -// require.NoError(t, err) -// -// // unbond rest of the other delegation's shares -// remainingTokens := delTokens.Sub(unbondTokens) -// _, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], remainingTokens.ToDec()) -// require.NoError(t, err) -// -// // now validator should now be deleted from state -// validator, found = keeper.GetValidator(ctx, addrVals[0]) -// require.False(t, found, "%v", validator) -//} -// +func TestUndelegateFromUnbondedValidator(t *testing.T) { + _, app, ctx := getBaseSimappWithCustomKeeper() + delTokens := sdk.TokensFromConsensusPower(10) + delCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), delTokens)) + + addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(0)) + addrVals := simapp.ConvertAddrsToValAddrs(addrDels) + + // add bonded tokens to pool for delegations + notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) + oldNotBonded := app.BankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress()) + err := app.BankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(delCoins...)) + require.NoError(t, err) + app.SupplyKeeper.SetModuleAccount(ctx, notBondedPool) + + // create a validator with a self-delegation + validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) + + valTokens := sdk.TokensFromConsensusPower(10) + validator, issuedShares := validator.AddTokensFromDel(valTokens) + require.Equal(t, valTokens, issuedShares.RoundInt()) + validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) + require.True(t, validator.IsBonded()) + + val0AccAddr := sdk.AccAddress(addrVals[0]) + selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) + app.StakingKeeper.SetDelegation(ctx, selfDelegation) + + bondedPool := app.StakingKeeper.GetBondedPool(ctx) + oldBonded := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + err = app.BankKeeper.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) + require.NoError(t, err) + app.SupplyKeeper.SetModuleAccount(ctx, bondedPool) + + // create a second delegation to this validator + app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validator) + validator, issuedShares = validator.AddTokensFromDel(delTokens) + require.Equal(t, delTokens, issuedShares.RoundInt()) + validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) + require.True(t, validator.IsBonded()) + delegation := types.NewDelegation(addrDels[1], addrVals[0], issuedShares) + app.StakingKeeper.SetDelegation(ctx, delegation) + + ctx = ctx.WithBlockHeight(10) + ctx = ctx.WithBlockTime(time.Unix(333, 0)) + + // unbond the all self-delegation to put validator in unbonding state + _, err = app.StakingKeeper.Undelegate(ctx, val0AccAddr, addrVals[0], valTokens.ToDec()) + require.NoError(t, err) + + // end block + updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 1, len(updates)) + + validator, found := app.StakingKeeper.GetValidator(ctx, addrVals[0]) + require.True(t, found) + require.Equal(t, ctx.BlockHeight(), validator.UnbondingHeight) + params := app.StakingKeeper.GetParams(ctx) + require.True(t, ctx.BlockHeader().Time.Add(params.UnbondingTime).Equal(validator.UnbondingTime)) + + // unbond the validator + ctx = ctx.WithBlockTime(validator.UnbondingTime) + app.StakingKeeper.UnbondAllMatureValidatorQueue(ctx) + + // Make sure validator is still in state because there is still an outstanding delegation + validator, found = app.StakingKeeper.GetValidator(ctx, addrVals[0]) + require.True(t, found) + require.Equal(t, validator.Status, sdk.Unbonded) + + // unbond some of the other delegation's shares + unbondTokens := sdk.TokensFromConsensusPower(6) + _, err = app.StakingKeeper.Undelegate(ctx, addrDels[1], addrVals[0], unbondTokens.ToDec()) + require.NoError(t, err) + + // unbond rest of the other delegation's shares + remainingTokens := delTokens.Sub(unbondTokens) + _, err = app.StakingKeeper.Undelegate(ctx, addrDels[1], addrVals[0], remainingTokens.ToDec()) + require.NoError(t, err) + + // now validator should now be deleted from state + validator, found = app.StakingKeeper.GetValidator(ctx, addrVals[0]) + require.False(t, found, "%v", validator) +} + //func TestUnbondingAllDelegationFromValidator(t *testing.T) { // ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) // delTokens := sdk.TokensFromConsensusPower(10) diff --git a/x/staking/keeper/old_delegation_test.go b/x/staking/keeper/old_delegation_test.go index e4e2026425d3..7b31fc5cb9a2 100644 --- a/x/staking/keeper/old_delegation_test.go +++ b/x/staking/keeper/old_delegation_test.go @@ -11,87 +11,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/staking/types" ) -func TestUndelegateFromUnbondedValidator(t *testing.T) { - ctx, _, bk, keeper, _ := CreateTestInput(t, false, 1) - delTokens := sdk.TokensFromConsensusPower(10) - delCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), delTokens)) - - // add bonded tokens to pool for delegations - notBondedPool := keeper.GetNotBondedPool(ctx) - oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) - err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(delCoins...)) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - // create a validator with a self-delegation - validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) - - valTokens := sdk.TokensFromConsensusPower(10) - validator, issuedShares := validator.AddTokensFromDel(valTokens) - require.Equal(t, valTokens, issuedShares.RoundInt()) - validator = TestingUpdateValidator(keeper, ctx, validator, true) - require.True(t, validator.IsBonded()) - - val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) - selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) - keeper.SetDelegation(ctx, selfDelegation) - - bondedPool := keeper.GetBondedPool(ctx) - oldBonded := bk.GetAllBalances(ctx, bondedPool.GetAddress()) - err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) - - // create a second delegation to this validator - keeper.DeleteValidatorByPowerIndex(ctx, validator) - validator, issuedShares = validator.AddTokensFromDel(delTokens) - require.Equal(t, delTokens, issuedShares.RoundInt()) - validator = TestingUpdateValidator(keeper, ctx, validator, true) - require.True(t, validator.IsBonded()) - delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) - keeper.SetDelegation(ctx, delegation) - - ctx = ctx.WithBlockHeight(10) - ctx = ctx.WithBlockTime(time.Unix(333, 0)) - - // unbond the all self-delegation to put validator in unbonding state - _, err = keeper.Undelegate(ctx, val0AccAddr, addrVals[0], valTokens.ToDec()) - require.NoError(t, err) - - // end block - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 1, len(updates)) - - validator, found := keeper.GetValidator(ctx, addrVals[0]) - require.True(t, found) - require.Equal(t, ctx.BlockHeight(), validator.UnbondingHeight) - params := keeper.GetParams(ctx) - require.True(t, ctx.BlockHeader().Time.Add(params.UnbondingTime).Equal(validator.UnbondingTime)) - - // unbond the validator - ctx = ctx.WithBlockTime(validator.UnbondingTime) - keeper.UnbondAllMatureValidatorQueue(ctx) - - // Make sure validator is still in state because there is still an outstanding delegation - validator, found = keeper.GetValidator(ctx, addrVals[0]) - require.True(t, found) - require.Equal(t, validator.Status, sdk.Unbonded) - - // unbond some of the other delegation's shares - unbondTokens := sdk.TokensFromConsensusPower(6) - _, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], unbondTokens.ToDec()) - require.NoError(t, err) - - // unbond rest of the other delegation's shares - remainingTokens := delTokens.Sub(unbondTokens) - _, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], remainingTokens.ToDec()) - require.NoError(t, err) - - // now validator should now be deleted from state - validator, found = keeper.GetValidator(ctx, addrVals[0]) - require.False(t, found, "%v", validator) -} - func TestUnbondingAllDelegationFromValidator(t *testing.T) { ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) delTokens := sdk.TokensFromConsensusPower(10) From 62dbd8bcee9d53d49449432e4a059db52c2ae41e Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Mon, 24 Feb 2020 12:46:14 +0100 Subject: [PATCH 24/90] TestUnbondingAllDelegationFromValidator to use simapp --- x/staking/keeper/delegation_test.go | 147 ++++++++++++------------ x/staking/keeper/old_delegation_test.go | 72 ------------ 2 files changed, 75 insertions(+), 144 deletions(-) diff --git a/x/staking/keeper/delegation_test.go b/x/staking/keeper/delegation_test.go index 63e8e8fd7229..3250b0c2196b 100644 --- a/x/staking/keeper/delegation_test.go +++ b/x/staking/keeper/delegation_test.go @@ -547,78 +547,81 @@ func TestUndelegateFromUnbondedValidator(t *testing.T) { require.False(t, found, "%v", validator) } -//func TestUnbondingAllDelegationFromValidator(t *testing.T) { -// ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) -// delTokens := sdk.TokensFromConsensusPower(10) -// delCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), delTokens)) -// -// // add bonded tokens to pool for delegations -// notBondedPool := keeper.GetNotBondedPool(ctx) -// oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) -// err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(delCoins...)) -// require.NoError(t, err) -// keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) -// -// //create a validator with a self-delegation -// validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) -// -// valTokens := sdk.TokensFromConsensusPower(10) -// validator, issuedShares := validator.AddTokensFromDel(valTokens) -// require.Equal(t, valTokens, issuedShares.RoundInt()) -// -// validator = TestingUpdateValidator(keeper, ctx, validator, true) -// require.True(t, validator.IsBonded()) -// val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) -// -// selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) -// keeper.SetDelegation(ctx, selfDelegation) -// -// // create a second delegation to this validator -// keeper.DeleteValidatorByPowerIndex(ctx, validator) -// validator, issuedShares = validator.AddTokensFromDel(delTokens) -// require.Equal(t, delTokens, issuedShares.RoundInt()) -// -// bondedPool := keeper.GetBondedPool(ctx) -// oldBonded := bk.GetAllBalances(ctx, bondedPool.GetAddress()) -// err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) -// require.NoError(t, err) -// keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) -// -// validator = TestingUpdateValidator(keeper, ctx, validator, true) -// require.True(t, validator.IsBonded()) -// -// delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) -// keeper.SetDelegation(ctx, delegation) -// -// ctx = ctx.WithBlockHeight(10) -// ctx = ctx.WithBlockTime(time.Unix(333, 0)) -// -// // unbond the all self-delegation to put validator in unbonding state -// _, err = keeper.Undelegate(ctx, val0AccAddr, addrVals[0], valTokens.ToDec()) -// require.NoError(t, err) -// -// // end block -// updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) -// require.Equal(t, 1, len(updates)) -// -// // unbond all the remaining delegation -// _, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], delTokens.ToDec()) -// require.NoError(t, err) -// -// // validator should still be in state and still be in unbonding state -// validator, found := keeper.GetValidator(ctx, addrVals[0]) -// require.True(t, found) -// require.Equal(t, validator.Status, sdk.Unbonding) -// -// // unbond the validator -// ctx = ctx.WithBlockTime(validator.UnbondingTime) -// keeper.UnbondAllMatureValidatorQueue(ctx) -// -// // validator should now be deleted from state -// _, found = keeper.GetValidator(ctx, addrVals[0]) -// require.False(t, found) -//} -// +func TestUnbondingAllDelegationFromValidator(t *testing.T) { + _, app, ctx := getBaseSimappWithCustomKeeper() + delTokens := sdk.TokensFromConsensusPower(10) + delCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), delTokens)) + + addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(0)) + addrVals := simapp.ConvertAddrsToValAddrs(addrDels) + + // add bonded tokens to pool for delegations + notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) + oldNotBonded := app.BankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress()) + err := app.BankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(delCoins...)) + require.NoError(t, err) + app.SupplyKeeper.SetModuleAccount(ctx, notBondedPool) + + //create a validator with a self-delegation + validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) + + valTokens := sdk.TokensFromConsensusPower(10) + validator, issuedShares := validator.AddTokensFromDel(valTokens) + require.Equal(t, valTokens, issuedShares.RoundInt()) + + validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) + require.True(t, validator.IsBonded()) + val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) + + selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) + app.StakingKeeper.SetDelegation(ctx, selfDelegation) + + // create a second delegation to this validator + app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validator) + validator, issuedShares = validator.AddTokensFromDel(delTokens) + require.Equal(t, delTokens, issuedShares.RoundInt()) + + bondedPool := app.StakingKeeper.GetBondedPool(ctx) + oldBonded := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + err = app.BankKeeper.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) + require.NoError(t, err) + app.SupplyKeeper.SetModuleAccount(ctx, bondedPool) + + validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) + require.True(t, validator.IsBonded()) + + delegation := types.NewDelegation(addrDels[1], addrVals[0], issuedShares) + app.StakingKeeper.SetDelegation(ctx, delegation) + + ctx = ctx.WithBlockHeight(10) + ctx = ctx.WithBlockTime(time.Unix(333, 0)) + + // unbond the all self-delegation to put validator in unbonding state + _, err = app.StakingKeeper.Undelegate(ctx, val0AccAddr, addrVals[0], valTokens.ToDec()) + require.NoError(t, err) + + // end block + updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 1, len(updates)) + + // unbond all the remaining delegation + _, err = app.StakingKeeper.Undelegate(ctx, addrDels[1], addrVals[0], delTokens.ToDec()) + require.NoError(t, err) + + // validator should still be in state and still be in unbonding state + validator, found := app.StakingKeeper.GetValidator(ctx, addrVals[0]) + require.True(t, found) + require.Equal(t, validator.Status, sdk.Unbonding) + + // unbond the validator + ctx = ctx.WithBlockTime(validator.UnbondingTime) + app.StakingKeeper.UnbondAllMatureValidatorQueue(ctx) + + // validator should now be deleted from state + _, found = app.StakingKeeper.GetValidator(ctx, addrVals[0]) + require.False(t, found) +} + //// Make sure that that the retrieving the delegations doesn't affect the state //func TestGetRedelegationsFromSrcValidator(t *testing.T) { // ctx, _, _, keeper, _ := CreateTestInput(t, false, 0) diff --git a/x/staking/keeper/old_delegation_test.go b/x/staking/keeper/old_delegation_test.go index 7b31fc5cb9a2..03ec0f233c36 100644 --- a/x/staking/keeper/old_delegation_test.go +++ b/x/staking/keeper/old_delegation_test.go @@ -11,78 +11,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/staking/types" ) -func TestUnbondingAllDelegationFromValidator(t *testing.T) { - ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) - delTokens := sdk.TokensFromConsensusPower(10) - delCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), delTokens)) - - // add bonded tokens to pool for delegations - notBondedPool := keeper.GetNotBondedPool(ctx) - oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) - err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(delCoins...)) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - //create a validator with a self-delegation - validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) - - valTokens := sdk.TokensFromConsensusPower(10) - validator, issuedShares := validator.AddTokensFromDel(valTokens) - require.Equal(t, valTokens, issuedShares.RoundInt()) - - validator = TestingUpdateValidator(keeper, ctx, validator, true) - require.True(t, validator.IsBonded()) - val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) - - selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) - keeper.SetDelegation(ctx, selfDelegation) - - // create a second delegation to this validator - keeper.DeleteValidatorByPowerIndex(ctx, validator) - validator, issuedShares = validator.AddTokensFromDel(delTokens) - require.Equal(t, delTokens, issuedShares.RoundInt()) - - bondedPool := keeper.GetBondedPool(ctx) - oldBonded := bk.GetAllBalances(ctx, bondedPool.GetAddress()) - err = bk.SetBalances(ctx, bondedPool.GetAddress(), oldBonded.Add(delCoins...)) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) - - validator = TestingUpdateValidator(keeper, ctx, validator, true) - require.True(t, validator.IsBonded()) - - delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) - keeper.SetDelegation(ctx, delegation) - - ctx = ctx.WithBlockHeight(10) - ctx = ctx.WithBlockTime(time.Unix(333, 0)) - - // unbond the all self-delegation to put validator in unbonding state - _, err = keeper.Undelegate(ctx, val0AccAddr, addrVals[0], valTokens.ToDec()) - require.NoError(t, err) - - // end block - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 1, len(updates)) - - // unbond all the remaining delegation - _, err = keeper.Undelegate(ctx, addrDels[0], addrVals[0], delTokens.ToDec()) - require.NoError(t, err) - - // validator should still be in state and still be in unbonding state - validator, found := keeper.GetValidator(ctx, addrVals[0]) - require.True(t, found) - require.Equal(t, validator.Status, sdk.Unbonding) - - // unbond the validator - ctx = ctx.WithBlockTime(validator.UnbondingTime) - keeper.UnbondAllMatureValidatorQueue(ctx) - - // validator should now be deleted from state - _, found = keeper.GetValidator(ctx, addrVals[0]) - require.False(t, found) -} - // Make sure that that the retrieving the delegations doesn't affect the state func TestGetRedelegationsFromSrcValidator(t *testing.T) { ctx, _, _, keeper, _ := CreateTestInput(t, false, 0) From 9a5aae9f0e2ea03cee435d8d9725fd0a25b1228e Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Mon, 24 Feb 2020 12:50:02 +0100 Subject: [PATCH 25/90] refactor TestGetRedelegationsFromSrcValidator to use simapp --- x/staking/keeper/delegation_test.go | 51 +++++++++++++------------ x/staking/keeper/old_delegation_test.go | 24 ------------ 2 files changed, 27 insertions(+), 48 deletions(-) diff --git a/x/staking/keeper/delegation_test.go b/x/staking/keeper/delegation_test.go index 3250b0c2196b..bbcf4aa4d8bd 100644 --- a/x/staking/keeper/delegation_test.go +++ b/x/staking/keeper/delegation_test.go @@ -622,30 +622,33 @@ func TestUnbondingAllDelegationFromValidator(t *testing.T) { require.False(t, found) } -//// Make sure that that the retrieving the delegations doesn't affect the state -//func TestGetRedelegationsFromSrcValidator(t *testing.T) { -// ctx, _, _, keeper, _ := CreateTestInput(t, false, 0) -// -// rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 0, -// time.Unix(0, 0), sdk.NewInt(5), -// sdk.NewDec(5)) -// -// // set and retrieve a record -// keeper.SetRedelegation(ctx, rd) -// resBond, found := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) -// require.True(t, found) -// -// // get the redelegations one time -// redelegations := keeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0]) -// require.Equal(t, 1, len(redelegations)) -// require.True(t, redelegations[0].Equal(resBond)) -// -// // get the redelegations a second time, should be exactly the same -// redelegations = keeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0]) -// require.Equal(t, 1, len(redelegations)) -// require.True(t, redelegations[0].Equal(resBond)) -//} -// +// Make sure that that the retrieving the delegations doesn't affect the state +func TestGetRedelegationsFromSrcValidator(t *testing.T) { + _, app, ctx := getBaseSimappWithCustomKeeper() + + addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(0)) + addrVals := simapp.ConvertAddrsToValAddrs(addrDels) + + rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 0, + time.Unix(0, 0), sdk.NewInt(5), + sdk.NewDec(5)) + + // set and retrieve a record + app.StakingKeeper.SetRedelegation(ctx, rd) + resBond, found := app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) + require.True(t, found) + + // get the redelegations one time + redelegations := app.StakingKeeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0]) + require.Equal(t, 1, len(redelegations)) + require.True(t, redelegations[0].Equal(resBond)) + + // get the redelegations a second time, should be exactly the same + redelegations = app.StakingKeeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0]) + require.Equal(t, 1, len(redelegations)) + require.True(t, redelegations[0].Equal(resBond)) +} + //// tests Get/Set/Remove/Has UnbondingDelegation //func TestRedelegation(t *testing.T) { // ctx, _, _, keeper, _ := CreateTestInput(t, false, 0) diff --git a/x/staking/keeper/old_delegation_test.go b/x/staking/keeper/old_delegation_test.go index 03ec0f233c36..256c4e1928c8 100644 --- a/x/staking/keeper/old_delegation_test.go +++ b/x/staking/keeper/old_delegation_test.go @@ -11,30 +11,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/staking/types" ) -// Make sure that that the retrieving the delegations doesn't affect the state -func TestGetRedelegationsFromSrcValidator(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 0) - - rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 0, - time.Unix(0, 0), sdk.NewInt(5), - sdk.NewDec(5)) - - // set and retrieve a record - keeper.SetRedelegation(ctx, rd) - resBond, found := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) - require.True(t, found) - - // get the redelegations one time - redelegations := keeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0]) - require.Equal(t, 1, len(redelegations)) - require.True(t, redelegations[0].Equal(resBond)) - - // get the redelegations a second time, should be exactly the same - redelegations = keeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0]) - require.Equal(t, 1, len(redelegations)) - require.True(t, redelegations[0].Equal(resBond)) -} - // tests Get/Set/Remove/Has UnbondingDelegation func TestRedelegation(t *testing.T) { ctx, _, _, keeper, _ := CreateTestInput(t, false, 0) From e33844fa56abafdccfbff6053d64e69f109102dd Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Mon, 24 Feb 2020 13:11:18 +0100 Subject: [PATCH 26/90] refactor TestRedelegation to use simapp --- x/staking/keeper/delegation_test.go | 122 ++++++++++++------------ x/staking/keeper/old_delegation_test.go | 61 ------------ 2 files changed, 61 insertions(+), 122 deletions(-) diff --git a/x/staking/keeper/delegation_test.go b/x/staking/keeper/delegation_test.go index bbcf4aa4d8bd..b211b5543473 100644 --- a/x/staking/keeper/delegation_test.go +++ b/x/staking/keeper/delegation_test.go @@ -649,67 +649,67 @@ func TestGetRedelegationsFromSrcValidator(t *testing.T) { require.True(t, redelegations[0].Equal(resBond)) } -//// tests Get/Set/Remove/Has UnbondingDelegation -//func TestRedelegation(t *testing.T) { -// ctx, _, _, keeper, _ := CreateTestInput(t, false, 0) -// -// rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 0, -// time.Unix(0, 0), sdk.NewInt(5), -// sdk.NewDec(5)) -// -// // test shouldn't have and redelegations -// has := keeper.HasReceivingRedelegation(ctx, addrDels[0], addrVals[1]) -// require.False(t, has) -// -// // set and retrieve a record -// keeper.SetRedelegation(ctx, rd) -// resRed, found := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) -// require.True(t, found) -// -// redelegations := keeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0]) -// require.Equal(t, 1, len(redelegations)) -// require.True(t, redelegations[0].Equal(resRed)) -// -// redelegations = keeper.GetRedelegations(ctx, addrDels[0], 5) -// require.Equal(t, 1, len(redelegations)) -// require.True(t, redelegations[0].Equal(resRed)) -// -// redelegations = keeper.GetAllRedelegations(ctx, addrDels[0], nil, nil) -// require.Equal(t, 1, len(redelegations)) -// require.True(t, redelegations[0].Equal(resRed)) -// -// // check if has the redelegation -// has = keeper.HasReceivingRedelegation(ctx, addrDels[0], addrVals[1]) -// require.True(t, has) -// -// // modify a records, save, and retrieve -// rd.Entries[0].SharesDst = sdk.NewDec(21) -// keeper.SetRedelegation(ctx, rd) -// -// resRed, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) -// require.True(t, found) -// require.True(t, rd.Equal(resRed)) -// -// redelegations = keeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0]) -// require.Equal(t, 1, len(redelegations)) -// require.True(t, redelegations[0].Equal(resRed)) -// -// redelegations = keeper.GetRedelegations(ctx, addrDels[0], 5) -// require.Equal(t, 1, len(redelegations)) -// require.True(t, redelegations[0].Equal(resRed)) -// -// // delete a record -// keeper.RemoveRedelegation(ctx, rd) -// _, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) -// require.False(t, found) -// -// redelegations = keeper.GetRedelegations(ctx, addrDels[0], 5) -// require.Equal(t, 0, len(redelegations)) -// -// redelegations = keeper.GetAllRedelegations(ctx, addrDels[0], nil, nil) -// require.Equal(t, 0, len(redelegations)) -//} -// +// tests Get/Set/Remove/Has UnbondingDelegation +func TestRedelegation(t *testing.T) { + _, app, ctx := getBaseSimappWithCustomKeeper() + + rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 0, + time.Unix(0, 0), sdk.NewInt(5), + sdk.NewDec(5)) + + // test shouldn't have and redelegations + has := app.StakingKeeper.HasReceivingRedelegation(ctx, addrDels[0], addrVals[1]) + require.False(t, has) + + // set and retrieve a record + app.StakingKeeper.SetRedelegation(ctx, rd) + resRed, found := app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) + require.True(t, found) + + redelegations := app.StakingKeeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0]) + require.Equal(t, 1, len(redelegations)) + require.True(t, redelegations[0].Equal(resRed)) + + redelegations = app.StakingKeeper.GetRedelegations(ctx, addrDels[0], 5) + require.Equal(t, 1, len(redelegations)) + require.True(t, redelegations[0].Equal(resRed)) + + redelegations = app.StakingKeeper.GetAllRedelegations(ctx, addrDels[0], nil, nil) + require.Equal(t, 1, len(redelegations)) + require.True(t, redelegations[0].Equal(resRed)) + + // check if has the redelegation + has = app.StakingKeeper.HasReceivingRedelegation(ctx, addrDels[0], addrVals[1]) + require.True(t, has) + + // modify a records, save, and retrieve + rd.Entries[0].SharesDst = sdk.NewDec(21) + app.StakingKeeper.SetRedelegation(ctx, rd) + + resRed, found = app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) + require.True(t, found) + require.True(t, rd.Equal(resRed)) + + redelegations = app.StakingKeeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0]) + require.Equal(t, 1, len(redelegations)) + require.True(t, redelegations[0].Equal(resRed)) + + redelegations = app.StakingKeeper.GetRedelegations(ctx, addrDels[0], 5) + require.Equal(t, 1, len(redelegations)) + require.True(t, redelegations[0].Equal(resRed)) + + // delete a record + app.StakingKeeper.RemoveRedelegation(ctx, rd) + _, found = app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) + require.False(t, found) + + redelegations = app.StakingKeeper.GetRedelegations(ctx, addrDels[0], 5) + require.Equal(t, 0, len(redelegations)) + + redelegations = app.StakingKeeper.GetAllRedelegations(ctx, addrDels[0], nil, nil) + require.Equal(t, 0, len(redelegations)) +} + //func TestRedelegateToSameValidator(t *testing.T) { // ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) // valTokens := sdk.TokensFromConsensusPower(10) diff --git a/x/staking/keeper/old_delegation_test.go b/x/staking/keeper/old_delegation_test.go index 256c4e1928c8..48ba070e16f1 100644 --- a/x/staking/keeper/old_delegation_test.go +++ b/x/staking/keeper/old_delegation_test.go @@ -11,67 +11,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/staking/types" ) -// tests Get/Set/Remove/Has UnbondingDelegation -func TestRedelegation(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 0) - - rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 0, - time.Unix(0, 0), sdk.NewInt(5), - sdk.NewDec(5)) - - // test shouldn't have and redelegations - has := keeper.HasReceivingRedelegation(ctx, addrDels[0], addrVals[1]) - require.False(t, has) - - // set and retrieve a record - keeper.SetRedelegation(ctx, rd) - resRed, found := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) - require.True(t, found) - - redelegations := keeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0]) - require.Equal(t, 1, len(redelegations)) - require.True(t, redelegations[0].Equal(resRed)) - - redelegations = keeper.GetRedelegations(ctx, addrDels[0], 5) - require.Equal(t, 1, len(redelegations)) - require.True(t, redelegations[0].Equal(resRed)) - - redelegations = keeper.GetAllRedelegations(ctx, addrDels[0], nil, nil) - require.Equal(t, 1, len(redelegations)) - require.True(t, redelegations[0].Equal(resRed)) - - // check if has the redelegation - has = keeper.HasReceivingRedelegation(ctx, addrDels[0], addrVals[1]) - require.True(t, has) - - // modify a records, save, and retrieve - rd.Entries[0].SharesDst = sdk.NewDec(21) - keeper.SetRedelegation(ctx, rd) - - resRed, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) - require.True(t, found) - require.True(t, rd.Equal(resRed)) - - redelegations = keeper.GetRedelegationsFromSrcValidator(ctx, addrVals[0]) - require.Equal(t, 1, len(redelegations)) - require.True(t, redelegations[0].Equal(resRed)) - - redelegations = keeper.GetRedelegations(ctx, addrDels[0], 5) - require.Equal(t, 1, len(redelegations)) - require.True(t, redelegations[0].Equal(resRed)) - - // delete a record - keeper.RemoveRedelegation(ctx, rd) - _, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) - require.False(t, found) - - redelegations = keeper.GetRedelegations(ctx, addrDels[0], 5) - require.Equal(t, 0, len(redelegations)) - - redelegations = keeper.GetAllRedelegations(ctx, addrDels[0], nil, nil) - require.Equal(t, 0, len(redelegations)) -} - func TestRedelegateToSameValidator(t *testing.T) { ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) valTokens := sdk.TokensFromConsensusPower(10) From 27e20236a358259d788e088b570b1ff01d919be6 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Mon, 24 Feb 2020 13:16:32 +0100 Subject: [PATCH 27/90] refactor TestRedelegateToSameValidator to use simapp --- x/staking/keeper/delegation_test.go | 61 ++++++++++++++----------- x/staking/keeper/old_delegation_test.go | 27 ----------- 2 files changed, 34 insertions(+), 54 deletions(-) diff --git a/x/staking/keeper/delegation_test.go b/x/staking/keeper/delegation_test.go index b211b5543473..e340d97d464d 100644 --- a/x/staking/keeper/delegation_test.go +++ b/x/staking/keeper/delegation_test.go @@ -653,6 +653,9 @@ func TestGetRedelegationsFromSrcValidator(t *testing.T) { func TestRedelegation(t *testing.T) { _, app, ctx := getBaseSimappWithCustomKeeper() + addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(0)) + addrVals := simapp.ConvertAddrsToValAddrs(addrDels) + rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 0, time.Unix(0, 0), sdk.NewInt(5), sdk.NewDec(5)) @@ -710,33 +713,37 @@ func TestRedelegation(t *testing.T) { require.Equal(t, 0, len(redelegations)) } -//func TestRedelegateToSameValidator(t *testing.T) { -// ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) -// valTokens := sdk.TokensFromConsensusPower(10) -// startCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), valTokens)) -// -// // add bonded tokens to pool for delegations -// notBondedPool := keeper.GetNotBondedPool(ctx) -// oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) -// err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(startCoins...)) -// require.NoError(t, err) -// keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) -// -// // create a validator with a self-delegation -// validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) -// validator, issuedShares := validator.AddTokensFromDel(valTokens) -// require.Equal(t, valTokens, issuedShares.RoundInt()) -// validator = TestingUpdateValidator(keeper, ctx, validator, true) -// require.True(t, validator.IsBonded()) -// -// val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) -// selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) -// keeper.SetDelegation(ctx, selfDelegation) -// -// _, err = keeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[0], sdk.NewDec(5)) -// require.Error(t, err) -//} -// +func TestRedelegateToSameValidator(t *testing.T) { + _, app, ctx := getBaseSimappWithCustomKeeper() + + addrDels := simapp.AddTestAddrsIncremental(app, ctx, 1, sdk.NewInt(0)) + addrVals := simapp.ConvertAddrsToValAddrs(addrDels) + + valTokens := sdk.TokensFromConsensusPower(10) + startCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), valTokens)) + + // add bonded tokens to pool for delegations + notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) + oldNotBonded := app.BankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress()) + err := app.BankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(startCoins...)) + require.NoError(t, err) + app.SupplyKeeper.SetModuleAccount(ctx, notBondedPool) + + // create a validator with a self-delegation + validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) + validator, issuedShares := validator.AddTokensFromDel(valTokens) + require.Equal(t, valTokens, issuedShares.RoundInt()) + validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) + require.True(t, validator.IsBonded()) + + val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) + selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) + app.StakingKeeper.SetDelegation(ctx, selfDelegation) + + _, err = app.StakingKeeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[0], sdk.NewDec(5)) + require.Error(t, err) +} + //func TestRedelegationMaxEntries(t *testing.T) { // ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) // startTokens := sdk.TokensFromConsensusPower(20) diff --git a/x/staking/keeper/old_delegation_test.go b/x/staking/keeper/old_delegation_test.go index 48ba070e16f1..3e061619d559 100644 --- a/x/staking/keeper/old_delegation_test.go +++ b/x/staking/keeper/old_delegation_test.go @@ -11,33 +11,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/staking/types" ) -func TestRedelegateToSameValidator(t *testing.T) { - ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) - valTokens := sdk.TokensFromConsensusPower(10) - startCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), valTokens)) - - // add bonded tokens to pool for delegations - notBondedPool := keeper.GetNotBondedPool(ctx) - oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) - err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(startCoins...)) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - // create a validator with a self-delegation - validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) - validator, issuedShares := validator.AddTokensFromDel(valTokens) - require.Equal(t, valTokens, issuedShares.RoundInt()) - validator = TestingUpdateValidator(keeper, ctx, validator, true) - require.True(t, validator.IsBonded()) - - val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) - selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) - keeper.SetDelegation(ctx, selfDelegation) - - _, err = keeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[0], sdk.NewDec(5)) - require.Error(t, err) -} - func TestRedelegationMaxEntries(t *testing.T) { ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) startTokens := sdk.TokensFromConsensusPower(20) From ae44324d5a9acd25dfa4cccde2b0d746889eaf9f Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Mon, 24 Feb 2020 15:06:12 +0100 Subject: [PATCH 28/90] refacotr TestRedelegationMaxEntries to use simapp --- x/staking/keeper/delegation_test.go | 58 +++++++++++++++++++++++++ x/staking/keeper/old_delegation_test.go | 54 ----------------------- 2 files changed, 58 insertions(+), 54 deletions(-) diff --git a/x/staking/keeper/delegation_test.go b/x/staking/keeper/delegation_test.go index e340d97d464d..a73447cd2b7d 100644 --- a/x/staking/keeper/delegation_test.go +++ b/x/staking/keeper/delegation_test.go @@ -744,6 +744,64 @@ func TestRedelegateToSameValidator(t *testing.T) { require.Error(t, err) } +func TestRedelegationMaxEntries(t *testing.T) { + _, app, ctx := getBaseSimappWithCustomKeeper() + + addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(0)) + addrVals := simapp.ConvertAddrsToValAddrs(addrDels) + + startTokens := sdk.TokensFromConsensusPower(20) + startCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), startTokens)) + + // add bonded tokens to pool for delegations + notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) + oldNotBonded := app.BankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress()) + err := app.BankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(startCoins...)) + require.NoError(t, err) + app.SupplyKeeper.SetModuleAccount(ctx, notBondedPool) + + // create a validator with a self-delegation + validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) + valTokens := sdk.TokensFromConsensusPower(10) + validator, issuedShares := validator.AddTokensFromDel(valTokens) + require.Equal(t, valTokens, issuedShares.RoundInt()) + validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) + val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) + selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) + app.StakingKeeper.SetDelegation(ctx, selfDelegation) + + // create a second validator + validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{}) + validator2, issuedShares = validator2.AddTokensFromDel(valTokens) + require.Equal(t, valTokens, issuedShares.RoundInt()) + + validator2 = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator2, true) + require.Equal(t, sdk.Bonded, validator2.Status) + + maxEntries := app.StakingKeeper.MaxEntries(ctx) + + // redelegations should pass + var completionTime time.Time + for i := uint32(0); i < maxEntries; i++ { + var err error + completionTime, err = app.StakingKeeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], sdk.NewDec(1)) + require.NoError(t, err) + } + + // an additional redelegation should fail due to max entries + _, err = app.StakingKeeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], sdk.NewDec(1)) + require.Error(t, err) + + // mature redelegations + ctx = ctx.WithBlockTime(completionTime) + err = app.StakingKeeper.CompleteRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1]) + require.NoError(t, err) + + // redelegation should work again + _, err = app.StakingKeeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], sdk.NewDec(1)) + require.NoError(t, err) +} + //func TestRedelegationMaxEntries(t *testing.T) { // ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) // startTokens := sdk.TokensFromConsensusPower(20) diff --git a/x/staking/keeper/old_delegation_test.go b/x/staking/keeper/old_delegation_test.go index 3e061619d559..de600a24efdc 100644 --- a/x/staking/keeper/old_delegation_test.go +++ b/x/staking/keeper/old_delegation_test.go @@ -11,60 +11,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/staking/types" ) -func TestRedelegationMaxEntries(t *testing.T) { - ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) - startTokens := sdk.TokensFromConsensusPower(20) - startCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), startTokens)) - - // add bonded tokens to pool for delegations - notBondedPool := keeper.GetNotBondedPool(ctx) - oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) - err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(startCoins...)) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - // create a validator with a self-delegation - validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) - valTokens := sdk.TokensFromConsensusPower(10) - validator, issuedShares := validator.AddTokensFromDel(valTokens) - require.Equal(t, valTokens, issuedShares.RoundInt()) - validator = TestingUpdateValidator(keeper, ctx, validator, true) - val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) - selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) - keeper.SetDelegation(ctx, selfDelegation) - - // create a second validator - validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{}) - validator2, issuedShares = validator2.AddTokensFromDel(valTokens) - require.Equal(t, valTokens, issuedShares.RoundInt()) - - validator2 = TestingUpdateValidator(keeper, ctx, validator2, true) - require.Equal(t, sdk.Bonded, validator2.Status) - - maxEntries := keeper.MaxEntries(ctx) - - // redelegations should pass - var completionTime time.Time - for i := uint32(0); i < maxEntries; i++ { - var err error - completionTime, err = keeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], sdk.NewDec(1)) - require.NoError(t, err) - } - - // an additional redelegation should fail due to max entries - _, err = keeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], sdk.NewDec(1)) - require.Error(t, err) - - // mature redelegations - ctx = ctx.WithBlockTime(completionTime) - err = keeper.CompleteRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1]) - require.NoError(t, err) - - // redelegation should work again - _, err = keeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], sdk.NewDec(1)) - require.NoError(t, err) -} - func TestRedelegateSelfDelegation(t *testing.T) { ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) startTokens := sdk.TokensFromConsensusPower(30) From 5bf1fa00487aaf8369638a88013339b1638a52c5 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Mon, 24 Feb 2020 15:11:37 +0100 Subject: [PATCH 29/90] refactor delegation test --- x/staking/keeper/delegation_test.go | 239 ++++++------------------ x/staking/keeper/old_delegation_test.go | 53 ------ 2 files changed, 53 insertions(+), 239 deletions(-) diff --git a/x/staking/keeper/delegation_test.go b/x/staking/keeper/delegation_test.go index a73447cd2b7d..8b963853a697 100644 --- a/x/staking/keeper/delegation_test.go +++ b/x/staking/keeper/delegation_test.go @@ -802,192 +802,59 @@ func TestRedelegationMaxEntries(t *testing.T) { require.NoError(t, err) } -//func TestRedelegationMaxEntries(t *testing.T) { -// ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) -// startTokens := sdk.TokensFromConsensusPower(20) -// startCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), startTokens)) -// -// // add bonded tokens to pool for delegations -// notBondedPool := keeper.GetNotBondedPool(ctx) -// oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) -// err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(startCoins...)) -// require.NoError(t, err) -// keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) -// -// // create a validator with a self-delegation -// validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) -// valTokens := sdk.TokensFromConsensusPower(10) -// validator, issuedShares := validator.AddTokensFromDel(valTokens) -// require.Equal(t, valTokens, issuedShares.RoundInt()) -// validator = TestingUpdateValidator(keeper, ctx, validator, true) -// val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) -// selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) -// keeper.SetDelegation(ctx, selfDelegation) -// -// // create a second validator -// validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{}) -// validator2, issuedShares = validator2.AddTokensFromDel(valTokens) -// require.Equal(t, valTokens, issuedShares.RoundInt()) -// -// validator2 = TestingUpdateValidator(keeper, ctx, validator2, true) -// require.Equal(t, sdk.Bonded, validator2.Status) -// -// maxEntries := keeper.MaxEntries(ctx) -// -// // redelegations should pass -// var completionTime time.Time -// for i := uint32(0); i < maxEntries; i++ { -// var err error -// completionTime, err = keeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], sdk.NewDec(1)) -// require.NoError(t, err) -// } -// -// // an additional redelegation should fail due to max entries -// _, err = keeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], sdk.NewDec(1)) -// require.Error(t, err) -// -// // mature redelegations -// ctx = ctx.WithBlockTime(completionTime) -// err = keeper.CompleteRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1]) -// require.NoError(t, err) -// -// // redelegation should work again -// _, err = keeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], sdk.NewDec(1)) -// require.NoError(t, err) -//} -// -//func TestRedelegateSelfDelegation(t *testing.T) { -// ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) -// startTokens := sdk.TokensFromConsensusPower(30) -// startCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), startTokens)) -// -// // add bonded tokens to pool for delegations -// notBondedPool := keeper.GetNotBondedPool(ctx) -// oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) -// err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(startCoins...)) -// require.NoError(t, err) -// keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) -// -// //create a validator with a self-delegation -// validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) -// valTokens := sdk.TokensFromConsensusPower(10) -// validator, issuedShares := validator.AddTokensFromDel(valTokens) -// require.Equal(t, valTokens, issuedShares.RoundInt()) -// -// validator = TestingUpdateValidator(keeper, ctx, validator, true) -// -// val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) -// selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) -// keeper.SetDelegation(ctx, selfDelegation) -// -// // create a second validator -// validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{}) -// validator2, issuedShares = validator2.AddTokensFromDel(valTokens) -// require.Equal(t, valTokens, issuedShares.RoundInt()) -// validator2 = TestingUpdateValidator(keeper, ctx, validator2, true) -// require.Equal(t, sdk.Bonded, validator2.Status) -// -// // create a second delegation to validator 1 -// delTokens := sdk.TokensFromConsensusPower(10) -// validator, issuedShares = validator.AddTokensFromDel(delTokens) -// require.Equal(t, delTokens, issuedShares.RoundInt()) -// validator = TestingUpdateValidator(keeper, ctx, validator, true) -// -// delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) -// keeper.SetDelegation(ctx, delegation) -// -// _, err = keeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], delTokens.ToDec()) -// require.NoError(t, err) -// -// // end block -// updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) -// require.Equal(t, 2, len(updates)) -// -// validator, found := keeper.GetValidator(ctx, addrVals[0]) -// require.True(t, found) -// require.Equal(t, valTokens, validator.Tokens) -// require.Equal(t, sdk.Unbonding, validator.Status) -//} -// -//func TestRedelegateFromUnbondingValidator(t *testing.T) { -// ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) -// startTokens := sdk.TokensFromConsensusPower(30) -// startCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), startTokens)) -// -// // add bonded tokens to pool for delegations -// notBondedPool := keeper.GetNotBondedPool(ctx) -// oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) -// err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(startCoins...)) -// require.NoError(t, err) -// keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) -// -// //create a validator with a self-delegation -// validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) -// -// valTokens := sdk.TokensFromConsensusPower(10) -// validator, issuedShares := validator.AddTokensFromDel(valTokens) -// require.Equal(t, valTokens, issuedShares.RoundInt()) -// validator = TestingUpdateValidator(keeper, ctx, validator, true) -// val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) -// selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) -// keeper.SetDelegation(ctx, selfDelegation) -// -// // create a second delegation to this validator -// keeper.DeleteValidatorByPowerIndex(ctx, validator) -// delTokens := sdk.TokensFromConsensusPower(10) -// validator, issuedShares = validator.AddTokensFromDel(delTokens) -// require.Equal(t, delTokens, issuedShares.RoundInt()) -// validator = TestingUpdateValidator(keeper, ctx, validator, true) -// delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) -// keeper.SetDelegation(ctx, delegation) -// -// // create a second validator -// validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{}) -// validator2, issuedShares = validator2.AddTokensFromDel(valTokens) -// require.Equal(t, valTokens, issuedShares.RoundInt()) -// validator2 = TestingUpdateValidator(keeper, ctx, validator2, true) -// -// header := ctx.BlockHeader() -// blockHeight := int64(10) -// header.Height = blockHeight -// blockTime := time.Unix(333, 0) -// header.Time = blockTime -// ctx = ctx.WithBlockHeader(header) -// -// // unbond the all self-delegation to put validator in unbonding state -// _, err = keeper.Undelegate(ctx, val0AccAddr, addrVals[0], delTokens.ToDec()) -// require.NoError(t, err) -// -// // end block -// updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) -// require.Equal(t, 1, len(updates)) -// -// validator, found := keeper.GetValidator(ctx, addrVals[0]) -// require.True(t, found) -// require.Equal(t, blockHeight, validator.UnbondingHeight) -// params := keeper.GetParams(ctx) -// require.True(t, blockTime.Add(params.UnbondingTime).Equal(validator.UnbondingTime)) -// -// //change the context -// header = ctx.BlockHeader() -// blockHeight2 := int64(20) -// header.Height = blockHeight2 -// blockTime2 := time.Unix(444, 0) -// header.Time = blockTime2 -// ctx = ctx.WithBlockHeader(header) -// -// // unbond some of the other delegation's shares -// redelegateTokens := sdk.TokensFromConsensusPower(6) -// _, err = keeper.BeginRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1], redelegateTokens.ToDec()) -// require.NoError(t, err) -// -// // retrieve the unbonding delegation -// ubd, found := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) -// require.True(t, found) -// require.Len(t, ubd.Entries, 1) -// assert.Equal(t, blockHeight, ubd.Entries[0].CreationHeight) -// assert.True(t, blockTime.Add(params.UnbondingTime).Equal(ubd.Entries[0].CompletionTime)) -//} +func TestRedelegateSelfDelegation(t *testing.T) { + _, app, ctx := getBaseSimappWithCustomKeeper() + startTokens := sdk.TokensFromConsensusPower(30) + startCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), startTokens)) + + // add bonded tokens to pool for delegations + notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) + oldNotBonded := app.BankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress()) + err := app.BankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(startCoins...)) + require.NoError(t, err) + app.SupplyKeeper.SetModuleAccount(ctx, notBondedPool) + + //create a validator with a self-delegation + validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) + valTokens := sdk.TokensFromConsensusPower(10) + validator, issuedShares := validator.AddTokensFromDel(valTokens) + require.Equal(t, valTokens, issuedShares.RoundInt()) + + validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) + + val0AccAddr := sdk.AccAddress(addrVals[0]) + selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) + app.StakingKeeper.SetDelegation(ctx, selfDelegation) + + // create a second validator + validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{}) + validator2, issuedShares = validator2.AddTokensFromDel(valTokens) + require.Equal(t, valTokens, issuedShares.RoundInt()) + validator2 = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator2, true) + require.Equal(t, sdk.Bonded, validator2.Status) + + // create a second delegation to validator 1 + delTokens := sdk.TokensFromConsensusPower(10) + validator, issuedShares = validator.AddTokensFromDel(delTokens) + require.Equal(t, delTokens, issuedShares.RoundInt()) + validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) + + delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) + app.StakingKeeper.SetDelegation(ctx, delegation) + + _, err = app.StakingKeeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], delTokens.ToDec()) + require.NoError(t, err) + + // end block + updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 2, len(updates)) + + validator, found := app.StakingKeeper.GetValidator(ctx, addrVals[0]) + require.True(t, found) + require.Equal(t, valTokens, validator.Tokens) + require.Equal(t, sdk.Unbonding, validator.Status) +} + // //func TestRedelegateFromUnbondedValidator(t *testing.T) { // ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) diff --git a/x/staking/keeper/old_delegation_test.go b/x/staking/keeper/old_delegation_test.go index de600a24efdc..b8d233c24149 100644 --- a/x/staking/keeper/old_delegation_test.go +++ b/x/staking/keeper/old_delegation_test.go @@ -11,59 +11,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/staking/types" ) -func TestRedelegateSelfDelegation(t *testing.T) { - ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) - startTokens := sdk.TokensFromConsensusPower(30) - startCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), startTokens)) - - // add bonded tokens to pool for delegations - notBondedPool := keeper.GetNotBondedPool(ctx) - oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) - err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(startCoins...)) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - //create a validator with a self-delegation - validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) - valTokens := sdk.TokensFromConsensusPower(10) - validator, issuedShares := validator.AddTokensFromDel(valTokens) - require.Equal(t, valTokens, issuedShares.RoundInt()) - - validator = TestingUpdateValidator(keeper, ctx, validator, true) - - val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) - selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) - keeper.SetDelegation(ctx, selfDelegation) - - // create a second validator - validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{}) - validator2, issuedShares = validator2.AddTokensFromDel(valTokens) - require.Equal(t, valTokens, issuedShares.RoundInt()) - validator2 = TestingUpdateValidator(keeper, ctx, validator2, true) - require.Equal(t, sdk.Bonded, validator2.Status) - - // create a second delegation to validator 1 - delTokens := sdk.TokensFromConsensusPower(10) - validator, issuedShares = validator.AddTokensFromDel(delTokens) - require.Equal(t, delTokens, issuedShares.RoundInt()) - validator = TestingUpdateValidator(keeper, ctx, validator, true) - - delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) - keeper.SetDelegation(ctx, delegation) - - _, err = keeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], delTokens.ToDec()) - require.NoError(t, err) - - // end block - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 2, len(updates)) - - validator, found := keeper.GetValidator(ctx, addrVals[0]) - require.True(t, found) - require.Equal(t, valTokens, validator.Tokens) - require.Equal(t, sdk.Unbonding, validator.Status) -} - func TestRedelegateFromUnbondingValidator(t *testing.T) { ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) startTokens := sdk.TokensFromConsensusPower(30) From a1fcb07d0fa75e4d82debde577a135fcd8c9fa14 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Mon, 24 Feb 2020 15:28:25 +0100 Subject: [PATCH 30/90] refactor TestRedelegateFromUnbondingValidator to use simapp --- x/staking/keeper/delegation_test.go | 88 +++++++++++++++++++++++++ x/staking/keeper/old_delegation_test.go | 81 ----------------------- 2 files changed, 88 insertions(+), 81 deletions(-) diff --git a/x/staking/keeper/delegation_test.go b/x/staking/keeper/delegation_test.go index 8b963853a697..f886641b3f43 100644 --- a/x/staking/keeper/delegation_test.go +++ b/x/staking/keeper/delegation_test.go @@ -804,6 +804,10 @@ func TestRedelegationMaxEntries(t *testing.T) { func TestRedelegateSelfDelegation(t *testing.T) { _, app, ctx := getBaseSimappWithCustomKeeper() + + addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(0)) + addrVals := simapp.ConvertAddrsToValAddrs(addrDels) + startTokens := sdk.TokensFromConsensusPower(30) startCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), startTokens)) @@ -855,6 +859,90 @@ func TestRedelegateSelfDelegation(t *testing.T) { require.Equal(t, sdk.Unbonding, validator.Status) } +func TestRedelegateFromUnbondingValidator(t *testing.T) { + _, app, ctx := getBaseSimappWithCustomKeeper() + + addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(0)) + addrVals := simapp.ConvertAddrsToValAddrs(addrDels) + + startTokens := sdk.TokensFromConsensusPower(30) + startCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), startTokens)) + + // add bonded tokens to pool for delegations + notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) + oldNotBonded := app.BankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress()) + err := app.BankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(startCoins...)) + require.NoError(t, err) + app.SupplyKeeper.SetModuleAccount(ctx, notBondedPool) + + //create a validator with a self-delegation + validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) + + valTokens := sdk.TokensFromConsensusPower(10) + validator, issuedShares := validator.AddTokensFromDel(valTokens) + require.Equal(t, valTokens, issuedShares.RoundInt()) + validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) + val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) + selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) + app.StakingKeeper.SetDelegation(ctx, selfDelegation) + + // create a second delegation to this validator + app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validator) + delTokens := sdk.TokensFromConsensusPower(10) + validator, issuedShares = validator.AddTokensFromDel(delTokens) + require.Equal(t, delTokens, issuedShares.RoundInt()) + validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) + delegation := types.NewDelegation(addrDels[1], addrVals[0], issuedShares) + app.StakingKeeper.SetDelegation(ctx, delegation) + + // create a second validator + validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{}) + validator2, issuedShares = validator2.AddTokensFromDel(valTokens) + require.Equal(t, valTokens, issuedShares.RoundInt()) + validator2 = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator2, true) + + header := ctx.BlockHeader() + blockHeight := int64(10) + header.Height = blockHeight + blockTime := time.Unix(333, 0) + header.Time = blockTime + ctx = ctx.WithBlockHeader(header) + + // unbond the all self-delegation to put validator in unbonding state + _, err = app.StakingKeeper.Undelegate(ctx, val0AccAddr, addrVals[0], delTokens.ToDec()) + require.NoError(t, err) + + // end block + updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 1, len(updates)) + + validator, found := app.StakingKeeper.GetValidator(ctx, addrVals[0]) + require.True(t, found) + require.Equal(t, blockHeight, validator.UnbondingHeight) + params := app.StakingKeeper.GetParams(ctx) + require.True(t, blockTime.Add(params.UnbondingTime).Equal(validator.UnbondingTime)) + + //change the context + header = ctx.BlockHeader() + blockHeight2 := int64(20) + header.Height = blockHeight2 + blockTime2 := time.Unix(444, 0) + header.Time = blockTime2 + ctx = ctx.WithBlockHeader(header) + + // unbond some of the other delegation's shares + redelegateTokens := sdk.TokensFromConsensusPower(6) + _, err = app.StakingKeeper.BeginRedelegation(ctx, addrDels[1], addrVals[0], addrVals[1], redelegateTokens.ToDec()) + require.NoError(t, err) + + // retrieve the unbonding delegation + ubd, found := app.StakingKeeper.GetRedelegation(ctx, addrDels[1], addrVals[0], addrVals[1]) + require.True(t, found) + require.Len(t, ubd.Entries, 1) + assert.Equal(t, blockHeight, ubd.Entries[0].CreationHeight) + assert.True(t, blockTime.Add(params.UnbondingTime).Equal(ubd.Entries[0].CompletionTime)) +} + // //func TestRedelegateFromUnbondedValidator(t *testing.T) { // ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) diff --git a/x/staking/keeper/old_delegation_test.go b/x/staking/keeper/old_delegation_test.go index b8d233c24149..fc4bbabce553 100644 --- a/x/staking/keeper/old_delegation_test.go +++ b/x/staking/keeper/old_delegation_test.go @@ -4,93 +4,12 @@ import ( "testing" "time" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/staking/types" ) -func TestRedelegateFromUnbondingValidator(t *testing.T) { - ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) - startTokens := sdk.TokensFromConsensusPower(30) - startCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), startTokens)) - - // add bonded tokens to pool for delegations - notBondedPool := keeper.GetNotBondedPool(ctx) - oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) - err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(startCoins...)) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - //create a validator with a self-delegation - validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) - - valTokens := sdk.TokensFromConsensusPower(10) - validator, issuedShares := validator.AddTokensFromDel(valTokens) - require.Equal(t, valTokens, issuedShares.RoundInt()) - validator = TestingUpdateValidator(keeper, ctx, validator, true) - val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) - selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) - keeper.SetDelegation(ctx, selfDelegation) - - // create a second delegation to this validator - keeper.DeleteValidatorByPowerIndex(ctx, validator) - delTokens := sdk.TokensFromConsensusPower(10) - validator, issuedShares = validator.AddTokensFromDel(delTokens) - require.Equal(t, delTokens, issuedShares.RoundInt()) - validator = TestingUpdateValidator(keeper, ctx, validator, true) - delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) - keeper.SetDelegation(ctx, delegation) - - // create a second validator - validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{}) - validator2, issuedShares = validator2.AddTokensFromDel(valTokens) - require.Equal(t, valTokens, issuedShares.RoundInt()) - validator2 = TestingUpdateValidator(keeper, ctx, validator2, true) - - header := ctx.BlockHeader() - blockHeight := int64(10) - header.Height = blockHeight - blockTime := time.Unix(333, 0) - header.Time = blockTime - ctx = ctx.WithBlockHeader(header) - - // unbond the all self-delegation to put validator in unbonding state - _, err = keeper.Undelegate(ctx, val0AccAddr, addrVals[0], delTokens.ToDec()) - require.NoError(t, err) - - // end block - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 1, len(updates)) - - validator, found := keeper.GetValidator(ctx, addrVals[0]) - require.True(t, found) - require.Equal(t, blockHeight, validator.UnbondingHeight) - params := keeper.GetParams(ctx) - require.True(t, blockTime.Add(params.UnbondingTime).Equal(validator.UnbondingTime)) - - //change the context - header = ctx.BlockHeader() - blockHeight2 := int64(20) - header.Height = blockHeight2 - blockTime2 := time.Unix(444, 0) - header.Time = blockTime2 - ctx = ctx.WithBlockHeader(header) - - // unbond some of the other delegation's shares - redelegateTokens := sdk.TokensFromConsensusPower(6) - _, err = keeper.BeginRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1], redelegateTokens.ToDec()) - require.NoError(t, err) - - // retrieve the unbonding delegation - ubd, found := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) - require.True(t, found) - require.Len(t, ubd.Entries, 1) - assert.Equal(t, blockHeight, ubd.Entries[0].CreationHeight) - assert.True(t, blockTime.Add(params.UnbondingTime).Equal(ubd.Entries[0].CompletionTime)) -} - func TestRedelegateFromUnbondedValidator(t *testing.T) { ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) startTokens := sdk.TokensFromConsensusPower(30) From 17ee1f510a941bd0531e0463354ed660592bd910 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Mon, 24 Feb 2020 15:37:03 +0100 Subject: [PATCH 31/90] finish refactor delegation test --- x/staking/keeper/delegation_test.go | 141 ++++++++++++------------ x/staking/keeper/old_delegation_test.go | 80 -------------- x/staking/keeper/val_state_change.go | 2 +- x/staking/keeper/validator.go | 2 +- 4 files changed, 74 insertions(+), 151 deletions(-) delete mode 100644 x/staking/keeper/old_delegation_test.go diff --git a/x/staking/keeper/delegation_test.go b/x/staking/keeper/delegation_test.go index f886641b3f43..004314a927a9 100644 --- a/x/staking/keeper/delegation_test.go +++ b/x/staking/keeper/delegation_test.go @@ -943,72 +943,75 @@ func TestRedelegateFromUnbondingValidator(t *testing.T) { assert.True(t, blockTime.Add(params.UnbondingTime).Equal(ubd.Entries[0].CompletionTime)) } -// -//func TestRedelegateFromUnbondedValidator(t *testing.T) { -// ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) -// startTokens := sdk.TokensFromConsensusPower(30) -// startCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), startTokens)) -// -// // add bonded tokens to pool for delegations -// notBondedPool := keeper.GetNotBondedPool(ctx) -// oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) -// err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(startCoins...)) -// require.NoError(t, err) -// keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) -// -// //create a validator with a self-delegation -// validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) -// -// valTokens := sdk.TokensFromConsensusPower(10) -// validator, issuedShares := validator.AddTokensFromDel(valTokens) -// require.Equal(t, valTokens, issuedShares.RoundInt()) -// validator = TestingUpdateValidator(keeper, ctx, validator, true) -// val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) -// selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) -// keeper.SetDelegation(ctx, selfDelegation) -// -// // create a second delegation to this validator -// keeper.DeleteValidatorByPowerIndex(ctx, validator) -// delTokens := sdk.TokensFromConsensusPower(10) -// validator, issuedShares = validator.AddTokensFromDel(delTokens) -// require.Equal(t, delTokens, issuedShares.RoundInt()) -// validator = TestingUpdateValidator(keeper, ctx, validator, true) -// delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) -// keeper.SetDelegation(ctx, delegation) -// -// // create a second validator -// validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{}) -// validator2, issuedShares = validator2.AddTokensFromDel(valTokens) -// require.Equal(t, valTokens, issuedShares.RoundInt()) -// validator2 = TestingUpdateValidator(keeper, ctx, validator2, true) -// require.Equal(t, sdk.Bonded, validator2.Status) -// -// ctx = ctx.WithBlockHeight(10) -// ctx = ctx.WithBlockTime(time.Unix(333, 0)) -// -// // unbond the all self-delegation to put validator in unbonding state -// _, err = keeper.Undelegate(ctx, val0AccAddr, addrVals[0], delTokens.ToDec()) -// require.NoError(t, err) -// -// // end block -// updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) -// require.Equal(t, 1, len(updates)) -// -// validator, found := keeper.GetValidator(ctx, addrVals[0]) -// require.True(t, found) -// require.Equal(t, ctx.BlockHeight(), validator.UnbondingHeight) -// params := keeper.GetParams(ctx) -// require.True(t, ctx.BlockHeader().Time.Add(params.UnbondingTime).Equal(validator.UnbondingTime)) -// -// // unbond the validator -// keeper.unbondingToUnbonded(ctx, validator) -// -// // redelegate some of the delegation's shares -// redelegationTokens := sdk.TokensFromConsensusPower(6) -// _, err = keeper.BeginRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1], redelegationTokens.ToDec()) -// require.NoError(t, err) -// -// // no red should have been found -// red, found := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) -// require.False(t, found, "%v", red) -//} +func TestRedelegateFromUnbondedValidator(t *testing.T) { + _, app, ctx := getBaseSimappWithCustomKeeper() + + addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(0)) + addrVals := simapp.ConvertAddrsToValAddrs(addrDels) + + startTokens := sdk.TokensFromConsensusPower(30) + startCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), startTokens)) + + // add bonded tokens to pool for delegations + notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) + oldNotBonded := app.BankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress()) + err := app.BankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(startCoins...)) + require.NoError(t, err) + app.SupplyKeeper.SetModuleAccount(ctx, notBondedPool) + + //create a validator with a self-delegation + validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) + + valTokens := sdk.TokensFromConsensusPower(10) + validator, issuedShares := validator.AddTokensFromDel(valTokens) + require.Equal(t, valTokens, issuedShares.RoundInt()) + validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) + val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) + selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) + app.StakingKeeper.SetDelegation(ctx, selfDelegation) + + // create a second delegation to this validator + app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validator) + delTokens := sdk.TokensFromConsensusPower(10) + validator, issuedShares = validator.AddTokensFromDel(delTokens) + require.Equal(t, delTokens, issuedShares.RoundInt()) + validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) + delegation := types.NewDelegation(addrDels[1], addrVals[0], issuedShares) + app.StakingKeeper.SetDelegation(ctx, delegation) + + // create a second validator + validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{}) + validator2, issuedShares = validator2.AddTokensFromDel(valTokens) + require.Equal(t, valTokens, issuedShares.RoundInt()) + validator2 = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator2, true) + require.Equal(t, sdk.Bonded, validator2.Status) + + ctx = ctx.WithBlockHeight(10) + ctx = ctx.WithBlockTime(time.Unix(333, 0)) + + // unbond the all self-delegation to put validator in unbonding state + _, err = app.StakingKeeper.Undelegate(ctx, val0AccAddr, addrVals[0], delTokens.ToDec()) + require.NoError(t, err) + + // end block + updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 1, len(updates)) + + validator, found := app.StakingKeeper.GetValidator(ctx, addrVals[0]) + require.True(t, found) + require.Equal(t, ctx.BlockHeight(), validator.UnbondingHeight) + params := app.StakingKeeper.GetParams(ctx) + require.True(t, ctx.BlockHeader().Time.Add(params.UnbondingTime).Equal(validator.UnbondingTime)) + + // unbond the validator + app.StakingKeeper.UnbondingToUnbonded(ctx, validator) + + // redelegate some of the delegation's shares + redelegationTokens := sdk.TokensFromConsensusPower(6) + _, err = app.StakingKeeper.BeginRedelegation(ctx, addrDels[1], addrVals[0], addrVals[1], redelegationTokens.ToDec()) + require.NoError(t, err) + + // no red should have been found + red, found := app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) + require.False(t, found, "%v", red) +} diff --git a/x/staking/keeper/old_delegation_test.go b/x/staking/keeper/old_delegation_test.go deleted file mode 100644 index fc4bbabce553..000000000000 --- a/x/staking/keeper/old_delegation_test.go +++ /dev/null @@ -1,80 +0,0 @@ -package keeper - -import ( - "testing" - "time" - - "github.com/stretchr/testify/require" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/staking/types" -) - -func TestRedelegateFromUnbondedValidator(t *testing.T) { - ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) - startTokens := sdk.TokensFromConsensusPower(30) - startCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), startTokens)) - - // add bonded tokens to pool for delegations - notBondedPool := keeper.GetNotBondedPool(ctx) - oldNotBonded := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) - err := bk.SetBalances(ctx, notBondedPool.GetAddress(), oldNotBonded.Add(startCoins...)) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - //create a validator with a self-delegation - validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) - - valTokens := sdk.TokensFromConsensusPower(10) - validator, issuedShares := validator.AddTokensFromDel(valTokens) - require.Equal(t, valTokens, issuedShares.RoundInt()) - validator = TestingUpdateValidator(keeper, ctx, validator, true) - val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) - selfDelegation := types.NewDelegation(val0AccAddr, addrVals[0], issuedShares) - keeper.SetDelegation(ctx, selfDelegation) - - // create a second delegation to this validator - keeper.DeleteValidatorByPowerIndex(ctx, validator) - delTokens := sdk.TokensFromConsensusPower(10) - validator, issuedShares = validator.AddTokensFromDel(delTokens) - require.Equal(t, delTokens, issuedShares.RoundInt()) - validator = TestingUpdateValidator(keeper, ctx, validator, true) - delegation := types.NewDelegation(addrDels[0], addrVals[0], issuedShares) - keeper.SetDelegation(ctx, delegation) - - // create a second validator - validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{}) - validator2, issuedShares = validator2.AddTokensFromDel(valTokens) - require.Equal(t, valTokens, issuedShares.RoundInt()) - validator2 = TestingUpdateValidator(keeper, ctx, validator2, true) - require.Equal(t, sdk.Bonded, validator2.Status) - - ctx = ctx.WithBlockHeight(10) - ctx = ctx.WithBlockTime(time.Unix(333, 0)) - - // unbond the all self-delegation to put validator in unbonding state - _, err = keeper.Undelegate(ctx, val0AccAddr, addrVals[0], delTokens.ToDec()) - require.NoError(t, err) - - // end block - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 1, len(updates)) - - validator, found := keeper.GetValidator(ctx, addrVals[0]) - require.True(t, found) - require.Equal(t, ctx.BlockHeight(), validator.UnbondingHeight) - params := keeper.GetParams(ctx) - require.True(t, ctx.BlockHeader().Time.Add(params.UnbondingTime).Equal(validator.UnbondingTime)) - - // unbond the validator - keeper.unbondingToUnbonded(ctx, validator) - - // redelegate some of the delegation's shares - redelegationTokens := sdk.TokensFromConsensusPower(6) - _, err = keeper.BeginRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1], redelegationTokens.ToDec()) - require.NoError(t, err) - - // no red should have been found - red, found := keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) - require.False(t, found, "%v", red) -} diff --git a/x/staking/keeper/val_state_change.go b/x/staking/keeper/val_state_change.go index e05182e92876..b5f05cf9a00f 100644 --- a/x/staking/keeper/val_state_change.go +++ b/x/staking/keeper/val_state_change.go @@ -210,7 +210,7 @@ func (k Keeper) unbondedToBonded(ctx sdk.Context, validator types.Validator) typ } // switches a validator from unbonding state to unbonded state -func (k Keeper) unbondingToUnbonded(ctx sdk.Context, validator types.Validator) types.Validator { +func (k Keeper) UnbondingToUnbonded(ctx sdk.Context, validator types.Validator) types.Validator { if !validator.IsUnbonding() { panic(fmt.Sprintf("bad state transition unbondingToBonded, validator: %v\n", validator)) } diff --git a/x/staking/keeper/validator.go b/x/staking/keeper/validator.go index efc0ff517e9d..c8d4d597e9b3 100644 --- a/x/staking/keeper/validator.go +++ b/x/staking/keeper/validator.go @@ -441,7 +441,7 @@ func (k Keeper) UnbondAllMatureValidatorQueue(ctx sdk.Context) { panic("unexpected validator in unbonding queue; status was not unbonding") } - val = k.unbondingToUnbonded(ctx, val) + val = k.UnbondingToUnbonded(ctx, val) if val.GetDelegatorShares().IsZero() { k.RemoveValidator(ctx, val.OperatorAddress) } From 3910ec25f636717713b3a11334f4738e64712ff6 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Mon, 24 Feb 2020 16:14:16 +0100 Subject: [PATCH 32/90] refactor and remove unused code --- x/staking/keeper/delegation_test.go | 48 ++++++++++---------- x/staking/keeper/historical_info_test.go | 20 +++++---- x/staking/keeper/test_common_test.go | 56 +----------------------- 3 files changed, 37 insertions(+), 87 deletions(-) diff --git a/x/staking/keeper/delegation_test.go b/x/staking/keeper/delegation_test.go index 004314a927a9..a1b0c6841c54 100644 --- a/x/staking/keeper/delegation_test.go +++ b/x/staking/keeper/delegation_test.go @@ -17,8 +17,8 @@ import ( func TestDelegation(t *testing.T) { _, app, ctx := getBaseSimappWithCustomKeeper() - addrs := simapp.AddTestAddrsIncremental(app, ctx, 3, sdk.NewInt(10000)) - valAddrs := simapp.ConvertAddrsToValAddrs(addrs) + addrDels := simapp.AddTestAddrsIncremental(app, ctx, 3, sdk.NewInt(10000)) + valAddrs := simapp.ConvertAddrsToValAddrs(addrDels) //construct the validators amts := []sdk.Int{sdk.NewInt(9), sdk.NewInt(8), sdk.NewInt(7)} @@ -33,31 +33,31 @@ func TestDelegation(t *testing.T) { validators[2] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[2], true) // first add a validators[0] to delegate too - bond1to1 := types.NewDelegation(addrs[0], valAddrs[0], sdk.NewDec(9)) + bond1to1 := types.NewDelegation(addrDels[0], valAddrs[0], sdk.NewDec(9)) // check the empty keeper first - _, found := app.StakingKeeper.GetDelegation(ctx, addrs[0], valAddrs[0]) + _, found := app.StakingKeeper.GetDelegation(ctx, addrDels[0], valAddrs[0]) require.False(t, found) // set and retrieve a record app.StakingKeeper.SetDelegation(ctx, bond1to1) - resBond, found := app.StakingKeeper.GetDelegation(ctx, addrs[0], valAddrs[0]) + resBond, found := app.StakingKeeper.GetDelegation(ctx, addrDels[0], valAddrs[0]) require.True(t, found) require.True(t, bond1to1.Equal(resBond)) // modify a records, save, and retrieve bond1to1.Shares = sdk.NewDec(99) app.StakingKeeper.SetDelegation(ctx, bond1to1) - resBond, found = app.StakingKeeper.GetDelegation(ctx, addrs[0], valAddrs[0]) + resBond, found = app.StakingKeeper.GetDelegation(ctx, addrDels[0], valAddrs[0]) require.True(t, found) require.True(t, bond1to1.Equal(resBond)) // add some more records - bond1to2 := types.NewDelegation(addrs[0], valAddrs[1], sdk.NewDec(9)) - bond1to3 := types.NewDelegation(addrs[0], valAddrs[2], sdk.NewDec(9)) - bond2to1 := types.NewDelegation(addrs[1], valAddrs[0], sdk.NewDec(9)) - bond2to2 := types.NewDelegation(addrs[1], valAddrs[1], sdk.NewDec(9)) - bond2to3 := types.NewDelegation(addrs[1], valAddrs[2], sdk.NewDec(9)) + bond1to2 := types.NewDelegation(addrDels[0], valAddrs[1], sdk.NewDec(9)) + bond1to3 := types.NewDelegation(addrDels[0], valAddrs[2], sdk.NewDec(9)) + bond2to1 := types.NewDelegation(addrDels[1], valAddrs[0], sdk.NewDec(9)) + bond2to2 := types.NewDelegation(addrDels[1], valAddrs[1], sdk.NewDec(9)) + bond2to3 := types.NewDelegation(addrDels[1], valAddrs[2], sdk.NewDec(9)) app.StakingKeeper.SetDelegation(ctx, bond1to2) app.StakingKeeper.SetDelegation(ctx, bond1to3) app.StakingKeeper.SetDelegation(ctx, bond2to1) @@ -65,16 +65,16 @@ func TestDelegation(t *testing.T) { app.StakingKeeper.SetDelegation(ctx, bond2to3) // test all bond retrieve capabilities - resBonds := app.StakingKeeper.GetDelegatorDelegations(ctx, addrs[0], 5) + resBonds := app.StakingKeeper.GetDelegatorDelegations(ctx, addrDels[0], 5) require.Equal(t, 3, len(resBonds)) require.True(t, bond1to1.Equal(resBonds[0])) require.True(t, bond1to2.Equal(resBonds[1])) require.True(t, bond1to3.Equal(resBonds[2])) - resBonds = app.StakingKeeper.GetAllDelegatorDelegations(ctx, addrs[0]) + resBonds = app.StakingKeeper.GetAllDelegatorDelegations(ctx, addrDels[0]) require.Equal(t, 3, len(resBonds)) - resBonds = app.StakingKeeper.GetDelegatorDelegations(ctx, addrs[0], 2) + resBonds = app.StakingKeeper.GetDelegatorDelegations(ctx, addrDels[0], 2) require.Equal(t, 2, len(resBonds)) - resBonds = app.StakingKeeper.GetDelegatorDelegations(ctx, addrs[1], 5) + resBonds = app.StakingKeeper.GetDelegatorDelegations(ctx, addrDels[1], 5) require.Equal(t, 3, len(resBonds)) require.True(t, bond2to1.Equal(resBonds[0])) require.True(t, bond2to2.Equal(resBonds[1])) @@ -88,17 +88,17 @@ func TestDelegation(t *testing.T) { require.True(t, bond2to2.Equal(allBonds[4])) require.True(t, bond2to3.Equal(allBonds[5])) - resVals := app.StakingKeeper.GetDelegatorValidators(ctx, addrs[0], 3) + resVals := app.StakingKeeper.GetDelegatorValidators(ctx, addrDels[0], 3) require.Equal(t, 3, len(resVals)) - resVals = app.StakingKeeper.GetDelegatorValidators(ctx, addrs[1], 4) + resVals = app.StakingKeeper.GetDelegatorValidators(ctx, addrDels[1], 4) require.Equal(t, 3, len(resVals)) for i := 0; i < 3; i++ { - resVal, err := app.StakingKeeper.GetDelegatorValidator(ctx, addrs[0], valAddrs[i]) + resVal, err := app.StakingKeeper.GetDelegatorValidator(ctx, addrDels[0], valAddrs[i]) require.Nil(t, err) require.Equal(t, valAddrs[i], resVal.GetOperator()) - resVal, err = app.StakingKeeper.GetDelegatorValidator(ctx, addrs[1], valAddrs[i]) + resVal, err = app.StakingKeeper.GetDelegatorValidator(ctx, addrDels[1], valAddrs[i]) require.Nil(t, err) require.Equal(t, valAddrs[i], resVal.GetOperator()) @@ -108,22 +108,22 @@ func TestDelegation(t *testing.T) { // delete a record app.StakingKeeper.RemoveDelegation(ctx, bond2to3) - _, found = app.StakingKeeper.GetDelegation(ctx, addrs[1], valAddrs[2]) + _, found = app.StakingKeeper.GetDelegation(ctx, addrDels[1], valAddrs[2]) require.False(t, found) - resBonds = app.StakingKeeper.GetDelegatorDelegations(ctx, addrs[1], 5) + resBonds = app.StakingKeeper.GetDelegatorDelegations(ctx, addrDels[1], 5) require.Equal(t, 2, len(resBonds)) require.True(t, bond2to1.Equal(resBonds[0])) require.True(t, bond2to2.Equal(resBonds[1])) - resBonds = app.StakingKeeper.GetAllDelegatorDelegations(ctx, addrs[1]) + resBonds = app.StakingKeeper.GetAllDelegatorDelegations(ctx, addrDels[1]) require.Equal(t, 2, len(resBonds)) // delete all the records from delegator 2 app.StakingKeeper.RemoveDelegation(ctx, bond2to1) app.StakingKeeper.RemoveDelegation(ctx, bond2to2) - _, found = app.StakingKeeper.GetDelegation(ctx, addrs[1], valAddrs[0]) + _, found = app.StakingKeeper.GetDelegation(ctx, addrDels[1], valAddrs[0]) require.False(t, found) - _, found = app.StakingKeeper.GetDelegation(ctx, addrs[1], valAddrs[1]) + _, found = app.StakingKeeper.GetDelegation(ctx, addrDels[1], valAddrs[1]) require.False(t, found) resBonds = app.StakingKeeper.GetDelegatorDelegations(ctx, addrDels[1], 5) require.Equal(t, 0, len(resBonds)) diff --git a/x/staking/keeper/historical_info_test.go b/x/staking/keeper/historical_info_test.go index 73cc64de0f4e..d4ed693106e6 100644 --- a/x/staking/keeper/historical_info_test.go +++ b/x/staking/keeper/historical_info_test.go @@ -15,8 +15,10 @@ import ( ) func TestHistoricalInfo(t *testing.T) { - app := simapp.Setup(false) - ctx := app.BaseApp.NewContext(false, abci.Header{}) + _, app, ctx := getBaseSimappWithCustomKeeper() + + addrDels := simapp.AddTestAddrsIncremental(app, ctx, 50, sdk.NewInt(0)) + addrVals := simapp.ConvertAddrsToValAddrs(addrDels) validators := make([]types.Validator, len(addrVals)) @@ -41,8 +43,10 @@ func TestHistoricalInfo(t *testing.T) { } func TestTrackHistoricalInfo(t *testing.T) { - app := simapp.Setup(false) - ctx := app.BaseApp.NewContext(false, abci.Header{}) + _, app, ctx := getBaseSimappWithCustomKeeper() + + addrDels := simapp.AddTestAddrsIncremental(app, ctx, 50, sdk.NewInt(0)) + addrVals := simapp.ConvertAddrsToValAddrs(addrDels) // set historical entries in params to 5 params := types.DefaultParams() @@ -60,8 +64,8 @@ func TestTrackHistoricalInfo(t *testing.T) { Height: 5, } valSet := []types.Validator{ - types.NewValidator(sdk.ValAddress(Addrs[0]), PKs[0], types.Description{}), - types.NewValidator(sdk.ValAddress(Addrs[1]), PKs[1], types.Description{}), + types.NewValidator(addrVals[0], PKs[0], types.Description{}), + types.NewValidator(addrVals[1], PKs[1], types.Description{}), } hi4 := types.NewHistoricalInfo(h4, valSet) hi5 := types.NewHistoricalInfo(h5, valSet) @@ -75,10 +79,10 @@ func TestTrackHistoricalInfo(t *testing.T) { require.Equal(t, hi5, recv) // Set last validators in keeper - val1 := types.NewValidator(sdk.ValAddress(Addrs[2]), PKs[2], types.Description{}) + val1 := types.NewValidator(addrVals[2], PKs[2], types.Description{}) app.StakingKeeper.SetValidator(ctx, val1) app.StakingKeeper.SetLastValidatorPower(ctx, val1.OperatorAddress, 10) - val2 := types.NewValidator(sdk.ValAddress(Addrs[3]), PKs[3], types.Description{}) + val2 := types.NewValidator(addrVals[3], PKs[3], types.Description{}) vals := []types.Validator{val1, val2} sort.Sort(types.Validators(vals)) app.StakingKeeper.SetValidator(ctx, val2) diff --git a/x/staking/keeper/test_common_test.go b/x/staking/keeper/test_common_test.go index 7c6cf8f0c2f9..2275aff100fb 100644 --- a/x/staking/keeper/test_common_test.go +++ b/x/staking/keeper/test_common_test.go @@ -17,40 +17,9 @@ import ( ) var ( - Addrs = createTestAddrs(500) - PKs = createTestPubKeys(500) - - addrDels = []sdk.AccAddress{ - Addrs[0], - Addrs[1], - } - addrVals = []sdk.ValAddress{ - sdk.ValAddress(Addrs[2]), - sdk.ValAddress(Addrs[3]), - sdk.ValAddress(Addrs[4]), - sdk.ValAddress(Addrs[5]), - sdk.ValAddress(Addrs[6]), - } + PKs = createTestPubKeys(500) ) -func createTestAddrs(numAddrs int) []sdk.AccAddress { - var addresses []sdk.AccAddress - var buffer bytes.Buffer - - // start at 100 so we can make up to 999 test addresses with valid test addresses - for i := 100; i < (numAddrs + 100); i++ { - numString := strconv.Itoa(i) - buffer.WriteString("A58856F0FD53BF058B4909A21AEC019107BA6") //base address string - - buffer.WriteString(numString) //adding on final two digits to make addresses unique - res, _ := sdk.AccAddressFromHex(buffer.String()) - bech := res.String() - addresses = append(addresses, CreateTestAddr(buffer.String(), bech)) - buffer.Reset() - } - return addresses -} - // nolint: unparam func createTestPubKeys(numPubKeys int) []crypto.PubKey { var publicKeys []crypto.PubKey @@ -79,29 +48,6 @@ func NewPubKey(pk string) (res crypto.PubKey) { return pkEd } -// for incode address generation -func CreateTestAddr(addr string, bech string) sdk.AccAddress { - res, err := sdk.AccAddressFromHex(addr) - if err != nil { - panic(err) - } - - bechexpected := res.String() - if bech != bechexpected { - panic("Bech encoding doesn't match reference") - } - - bechres, err := sdk.AccAddressFromBech32(bech) - if err != nil { - panic(err) - } - if !bytes.Equal(bechres, res) { - panic("Bech decode and hex decode don't match") - } - - return res -} - // getBaseSimappWithCustomKeeper Returns a simapp with custom StakingKeeper // to avoid messing with the hooks. func getBaseSimappWithCustomKeeper() (*codec.Codec, *simapp.SimApp, sdk.Context) { From fe1012dc29d008650f6f550a501df094c6cd3791 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Mon, 24 Feb 2020 17:34:22 +0100 Subject: [PATCH 33/90] migrate revocation of old slash test --- x/staking/keeper/old_slash_test.go | 579 +++++++++++++++++++++++++++ x/staking/keeper/slash_test.go | 602 ++--------------------------- 2 files changed, 611 insertions(+), 570 deletions(-) create mode 100644 x/staking/keeper/old_slash_test.go diff --git a/x/staking/keeper/old_slash_test.go b/x/staking/keeper/old_slash_test.go new file mode 100644 index 000000000000..f6b442dc3c18 --- /dev/null +++ b/x/staking/keeper/old_slash_test.go @@ -0,0 +1,579 @@ +package keeper + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" + + abci "github.com/tendermint/tendermint/abci/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/staking/types" +) + +// TODO integrate with test_common.go helper (CreateTestInput) +// setup helper function - creates two validators +func setupHelper(t *testing.T, power int64) (sdk.Context, Keeper, types.Params) { + // setup + ctx, _, _, keeper, _ := CreateTestInput(t, false, power) + params := keeper.GetParams(ctx) + numVals := int64(3) + amt := sdk.TokensFromConsensusPower(power) + bondedCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), amt.MulRaw(numVals))) + + bondedPool := keeper.GetBondedPool(ctx) + require.NoError(t, keeper.bankKeeper.SetBalances(ctx, bondedPool.GetAddress(), bondedCoins)) + keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) + + // add numVals validators + for i := int64(0); i < numVals; i++ { + validator := types.NewValidator(addrVals[i], PKs[i], types.Description{}) + validator, _ = validator.AddTokensFromDel(amt) + validator = TestingUpdateValidator(keeper, ctx, validator, true) + keeper.SetValidatorByConsAddr(ctx, validator) + } + + return ctx, keeper, params +} + +//_________________________________________________________________________________ + +// tests slashUnbondingDelegation +func TestSlashUnbondingDelegation(t *testing.T) { + ctx, keeper, _ := setupHelper(t, 10) + fraction := sdk.NewDecWithPrec(5, 1) + + // set an unbonding delegation with expiration timestamp (beyond which the + // unbonding delegation shouldn't be slashed) + ubd := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 0, + time.Unix(5, 0), sdk.NewInt(10)) + + keeper.SetUnbondingDelegation(ctx, ubd) + + // unbonding started prior to the infraction height, stakw didn't contribute + slashAmount := keeper.slashUnbondingDelegation(ctx, ubd, 1, fraction) + require.Equal(t, int64(0), slashAmount.Int64()) + + // after the expiration time, no longer eligible for slashing + ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(10, 0)}) + keeper.SetUnbondingDelegation(ctx, ubd) + slashAmount = keeper.slashUnbondingDelegation(ctx, ubd, 0, fraction) + require.Equal(t, int64(0), slashAmount.Int64()) + + // test valid slash, before expiration timestamp and to which stake contributed + notBondedPool := keeper.GetNotBondedPool(ctx) + oldUnbondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress()) + ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(0, 0)}) + keeper.SetUnbondingDelegation(ctx, ubd) + slashAmount = keeper.slashUnbondingDelegation(ctx, ubd, 0, fraction) + require.Equal(t, int64(5), slashAmount.Int64()) + ubd, found := keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) + require.True(t, found) + require.Len(t, ubd.Entries, 1) + + // initial balance unchanged + require.Equal(t, sdk.NewInt(10), ubd.Entries[0].InitialBalance) + + // balance decreased + require.Equal(t, sdk.NewInt(5), ubd.Entries[0].Balance) + newUnbondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress()) + diffTokens := oldUnbondedPoolBalances.Sub(newUnbondedPoolBalances) + require.Equal(t, int64(5), diffTokens.AmountOf(keeper.BondDenom(ctx)).Int64()) +} + +// tests slashRedelegation +func TestSlashRedelegation(t *testing.T) { + ctx, keeper, _ := setupHelper(t, 10) + fraction := sdk.NewDecWithPrec(5, 1) + + // add bonded tokens to pool for (re)delegations + startCoins := sdk.NewCoins(sdk.NewInt64Coin(keeper.BondDenom(ctx), 15)) + bondedPool := keeper.GetBondedPool(ctx) + balances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + + require.NoError(t, keeper.bankKeeper.SetBalances(ctx, bondedPool.GetAddress(), balances.Add(startCoins...))) + keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) + + // set a redelegation with an expiration timestamp beyond which the + // redelegation shouldn't be slashed + rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 0, + time.Unix(5, 0), sdk.NewInt(10), sdk.NewDec(10)) + + keeper.SetRedelegation(ctx, rd) + + // set the associated delegation + del := types.NewDelegation(addrDels[0], addrVals[1], sdk.NewDec(10)) + keeper.SetDelegation(ctx, del) + + // started redelegating prior to the current height, stake didn't contribute to infraction + validator, found := keeper.GetValidator(ctx, addrVals[1]) + require.True(t, found) + slashAmount := keeper.slashRedelegation(ctx, validator, rd, 1, fraction) + require.Equal(t, int64(0), slashAmount.Int64()) + + // after the expiration time, no longer eligible for slashing + ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(10, 0)}) + keeper.SetRedelegation(ctx, rd) + validator, found = keeper.GetValidator(ctx, addrVals[1]) + require.True(t, found) + slashAmount = keeper.slashRedelegation(ctx, validator, rd, 0, fraction) + require.Equal(t, int64(0), slashAmount.Int64()) + + balances = keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + + // test valid slash, before expiration timestamp and to which stake contributed + ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(0, 0)}) + keeper.SetRedelegation(ctx, rd) + validator, found = keeper.GetValidator(ctx, addrVals[1]) + require.True(t, found) + slashAmount = keeper.slashRedelegation(ctx, validator, rd, 0, fraction) + require.Equal(t, int64(5), slashAmount.Int64()) + rd, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) + require.True(t, found) + require.Len(t, rd.Entries, 1) + + // end block + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 1, len(updates)) + + // initialbalance unchanged + require.Equal(t, sdk.NewInt(10), rd.Entries[0].InitialBalance) + + // shares decreased + del, found = keeper.GetDelegation(ctx, addrDels[0], addrVals[1]) + require.True(t, found) + require.Equal(t, int64(5), del.Shares.RoundInt64()) + + // pool bonded tokens should decrease + burnedCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), slashAmount)) + require.Equal(t, balances.Sub(burnedCoins), keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())) +} + +// tests Slash at a future height (must panic) +func TestSlashAtFutureHeight(t *testing.T) { + ctx, keeper, _ := setupHelper(t, 10) + consAddr := sdk.ConsAddress(PKs[0].Address()) + fraction := sdk.NewDecWithPrec(5, 1) + require.Panics(t, func() { keeper.Slash(ctx, consAddr, 1, 10, fraction) }) +} + +// test slash at a negative height +// this just represents pre-genesis and should have the same effect as slashing at height 0 +func TestSlashAtNegativeHeight(t *testing.T) { + ctx, keeper, _ := setupHelper(t, 10) + consAddr := sdk.ConsAddress(PKs[0].Address()) + fraction := sdk.NewDecWithPrec(5, 1) + + bondedPool := keeper.GetBondedPool(ctx) + oldBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + + validator, found := keeper.GetValidatorByConsAddr(ctx, consAddr) + require.True(t, found) + keeper.Slash(ctx, consAddr, -2, 10, fraction) + + // read updated state + validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr) + require.True(t, found) + + // end block + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 1, len(updates), "cons addr: %v, updates: %v", []byte(consAddr), updates) + + validator = keeper.mustGetValidator(ctx, validator.OperatorAddress) + // power decreased + require.Equal(t, int64(5), validator.GetConsensusPower()) + + // pool bonded shares decreased + newBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx)) + require.Equal(t, sdk.TokensFromConsensusPower(5).String(), diffTokens.String()) +} + +// tests Slash at the current height +func TestSlashValidatorAtCurrentHeight(t *testing.T) { + ctx, keeper, _ := setupHelper(t, 10) + consAddr := sdk.ConsAddress(PKs[0].Address()) + fraction := sdk.NewDecWithPrec(5, 1) + + bondedPool := keeper.GetBondedPool(ctx) + oldBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + + validator, found := keeper.GetValidatorByConsAddr(ctx, consAddr) + require.True(t, found) + keeper.Slash(ctx, consAddr, ctx.BlockHeight(), 10, fraction) + + // read updated state + validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr) + require.True(t, found) + + // end block + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 1, len(updates), "cons addr: %v, updates: %v", []byte(consAddr), updates) + + validator = keeper.mustGetValidator(ctx, validator.OperatorAddress) + // power decreased + require.Equal(t, int64(5), validator.GetConsensusPower()) + + // pool bonded shares decreased + newBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx)) + require.Equal(t, sdk.TokensFromConsensusPower(5).String(), diffTokens.String()) +} + +// tests Slash at a previous height with an unbonding delegation +func TestSlashWithUnbondingDelegation(t *testing.T) { + ctx, keeper, _ := setupHelper(t, 10) + consAddr := sdk.ConsAddress(PKs[0].Address()) + fraction := sdk.NewDecWithPrec(5, 1) + + // set an unbonding delegation with expiration timestamp beyond which the + // unbonding delegation shouldn't be slashed + ubdTokens := sdk.TokensFromConsensusPower(4) + ubd := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 11, + time.Unix(0, 0), ubdTokens) + keeper.SetUnbondingDelegation(ctx, ubd) + + // slash validator for the first time + ctx = ctx.WithBlockHeight(12) + bondedPool := keeper.GetBondedPool(ctx) + oldBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + + validator, found := keeper.GetValidatorByConsAddr(ctx, consAddr) + require.True(t, found) + keeper.Slash(ctx, consAddr, 10, 10, fraction) + + // end block + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 1, len(updates)) + + // read updating unbonding delegation + ubd, found = keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) + require.True(t, found) + require.Len(t, ubd.Entries, 1) + + // balance decreased + require.Equal(t, sdk.TokensFromConsensusPower(2), ubd.Entries[0].Balance) + + // bonded tokens burned + newBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx)) + require.Equal(t, sdk.TokensFromConsensusPower(3), diffTokens) + + // read updated validator + validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr) + require.True(t, found) + + // power decreased by 3 - 6 stake originally bonded at the time of infraction + // was still bonded at the time of discovery and was slashed by half, 4 stake + // bonded at the time of discovery hadn't been bonded at the time of infraction + // and wasn't slashed + require.Equal(t, int64(7), validator.GetConsensusPower()) + + // slash validator again + ctx = ctx.WithBlockHeight(13) + keeper.Slash(ctx, consAddr, 9, 10, fraction) + + ubd, found = keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) + require.True(t, found) + require.Len(t, ubd.Entries, 1) + + // balance decreased again + require.Equal(t, sdk.NewInt(0), ubd.Entries[0].Balance) + + // bonded tokens burned again + newBondedPoolBalances = keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx)) + require.Equal(t, sdk.TokensFromConsensusPower(6), diffTokens) + + // read updated validator + validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr) + require.True(t, found) + + // power decreased by 3 again + require.Equal(t, int64(4), validator.GetConsensusPower()) + + // slash validator again + // all originally bonded stake has been slashed, so this will have no effect + // on the unbonding delegation, but it will slash stake bonded since the infraction + // this may not be the desirable behaviour, ref https://github.com/cosmos/cosmos-sdk/issues/1440 + ctx = ctx.WithBlockHeight(13) + keeper.Slash(ctx, consAddr, 9, 10, fraction) + + ubd, found = keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) + require.True(t, found) + require.Len(t, ubd.Entries, 1) + + // balance unchanged + require.Equal(t, sdk.NewInt(0), ubd.Entries[0].Balance) + + // bonded tokens burned again + newBondedPoolBalances = keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx)) + require.Equal(t, sdk.TokensFromConsensusPower(9), diffTokens) + + // read updated validator + validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr) + require.True(t, found) + + // power decreased by 3 again + require.Equal(t, int64(1), validator.GetConsensusPower()) + + // slash validator again + // all originally bonded stake has been slashed, so this will have no effect + // on the unbonding delegation, but it will slash stake bonded since the infraction + // this may not be the desirable behaviour, ref https://github.com/cosmos/cosmos-sdk/issues/1440 + ctx = ctx.WithBlockHeight(13) + keeper.Slash(ctx, consAddr, 9, 10, fraction) + + ubd, found = keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) + require.True(t, found) + require.Len(t, ubd.Entries, 1) + + // balance unchanged + require.Equal(t, sdk.NewInt(0), ubd.Entries[0].Balance) + + // just 1 bonded token burned again since that's all the validator now has + newBondedPoolBalances = keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx)) + require.Equal(t, sdk.TokensFromConsensusPower(10), diffTokens) + + // apply TM updates + keeper.ApplyAndReturnValidatorSetUpdates(ctx) + + // read updated validator + // power decreased by 1 again, validator is out of stake + // validator should be in unbonding period + validator, _ = keeper.GetValidatorByConsAddr(ctx, consAddr) + require.Equal(t, validator.GetStatus(), sdk.Unbonding) +} + +// tests Slash at a previous height with a redelegation +func TestSlashWithRedelegation(t *testing.T) { + ctx, keeper, _ := setupHelper(t, 10) + consAddr := sdk.ConsAddress(PKs[0].Address()) + fraction := sdk.NewDecWithPrec(5, 1) + bondDenom := keeper.BondDenom(ctx) + + // set a redelegation + rdTokens := sdk.TokensFromConsensusPower(6) + rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 11, + time.Unix(0, 0), rdTokens, rdTokens.ToDec()) + keeper.SetRedelegation(ctx, rd) + + // set the associated delegation + del := types.NewDelegation(addrDels[0], addrVals[1], rdTokens.ToDec()) + keeper.SetDelegation(ctx, del) + + // update bonded tokens + bondedPool := keeper.GetBondedPool(ctx) + notBondedPool := keeper.GetNotBondedPool(ctx) + rdCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, rdTokens.MulRaw(2))) + + balances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + err := keeper.bankKeeper.SetBalances(ctx, bondedPool.GetAddress(), balances.Add(rdCoins...)) + require.NoError(t, err) + + keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) + + oldBonded := keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount + oldNotBonded := keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount + + // slash validator + ctx = ctx.WithBlockHeight(12) + validator, found := keeper.GetValidatorByConsAddr(ctx, consAddr) + require.True(t, found) + + require.NotPanics(t, func() { keeper.Slash(ctx, consAddr, 10, 10, fraction) }) + burnAmount := sdk.TokensFromConsensusPower(10).ToDec().Mul(fraction).TruncateInt() + + bondedPool = keeper.GetBondedPool(ctx) + notBondedPool = keeper.GetNotBondedPool(ctx) + + // burn bonded tokens from only from delegations + bondedPoolBalance := keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount + require.True(sdk.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance)) + + notBondedPoolBalance := keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount + require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance)) + oldBonded = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount + + // read updating redelegation + rd, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) + require.True(t, found) + require.Len(t, rd.Entries, 1) + // read updated validator + validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr) + require.True(t, found) + // power decreased by 2 - 4 stake originally bonded at the time of infraction + // was still bonded at the time of discovery and was slashed by half, 4 stake + // bonded at the time of discovery hadn't been bonded at the time of infraction + // and wasn't slashed + require.Equal(t, int64(8), validator.GetConsensusPower()) + + // slash the validator again + validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr) + require.True(t, found) + + require.NotPanics(t, func() { keeper.Slash(ctx, consAddr, 10, 10, sdk.OneDec()) }) + burnAmount = sdk.TokensFromConsensusPower(7) + + // read updated pool + bondedPool = keeper.GetBondedPool(ctx) + notBondedPool = keeper.GetNotBondedPool(ctx) + + // seven bonded tokens burned + bondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount + require.True(sdk.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance)) + require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance)) + + bondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount + require.True(sdk.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance)) + + notBondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount + require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance)) + oldBonded = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount + + // read updating redelegation + rd, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) + require.True(t, found) + require.Len(t, rd.Entries, 1) + // read updated validator + validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr) + require.True(t, found) + // power decreased by 4 + require.Equal(t, int64(4), validator.GetConsensusPower()) + + // slash the validator again, by 100% + ctx = ctx.WithBlockHeight(12) + validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr) + require.True(t, found) + + require.NotPanics(t, func() { keeper.Slash(ctx, consAddr, 10, 10, sdk.OneDec()) }) + + burnAmount = sdk.TokensFromConsensusPower(10).ToDec().Mul(sdk.OneDec()).TruncateInt() + burnAmount = burnAmount.Sub(sdk.OneDec().MulInt(rdTokens).TruncateInt()) + + // read updated pool + bondedPool = keeper.GetBondedPool(ctx) + notBondedPool = keeper.GetNotBondedPool(ctx) + + bondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount + require.True(sdk.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance)) + notBondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount + require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance)) + oldBonded = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount + + // read updating redelegation + rd, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) + require.True(t, found) + require.Len(t, rd.Entries, 1) + // apply TM updates + keeper.ApplyAndReturnValidatorSetUpdates(ctx) + // read updated validator + // validator decreased to zero power, should be in unbonding period + validator, _ = keeper.GetValidatorByConsAddr(ctx, consAddr) + require.Equal(t, validator.GetStatus(), sdk.Unbonding) + + // slash the validator again, by 100% + // no stake remains to be slashed + ctx = ctx.WithBlockHeight(12) + // validator still in unbonding period + validator, _ = keeper.GetValidatorByConsAddr(ctx, consAddr) + require.Equal(t, validator.GetStatus(), sdk.Unbonding) + + require.NotPanics(t, func() { keeper.Slash(ctx, consAddr, 10, 10, sdk.OneDec()) }) + + // read updated pool + bondedPool = keeper.GetBondedPool(ctx) + notBondedPool = keeper.GetNotBondedPool(ctx) + + bondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount + require.True(sdk.IntEq(t, oldBonded, bondedPoolBalance)) + notBondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount + require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance)) + + // read updating redelegation + rd, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) + require.True(t, found) + require.Len(t, rd.Entries, 1) + // read updated validator + // power still zero, still in unbonding period + validator, _ = keeper.GetValidatorByConsAddr(ctx, consAddr) + require.Equal(t, validator.GetStatus(), sdk.Unbonding) +} + +// tests Slash at a previous height with both an unbonding delegation and a redelegation +func TestSlashBoth(t *testing.T) { + ctx, keeper, _ := setupHelper(t, 10) + fraction := sdk.NewDecWithPrec(5, 1) + bondDenom := keeper.BondDenom(ctx) + + // set a redelegation with expiration timestamp beyond which the + // redelegation shouldn't be slashed + rdATokens := sdk.TokensFromConsensusPower(6) + rdA := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 11, + time.Unix(0, 0), rdATokens, + rdATokens.ToDec()) + keeper.SetRedelegation(ctx, rdA) + + // set the associated delegation + delA := types.NewDelegation(addrDels[0], addrVals[1], rdATokens.ToDec()) + keeper.SetDelegation(ctx, delA) + + // set an unbonding delegation with expiration timestamp (beyond which the + // unbonding delegation shouldn't be slashed) + ubdATokens := sdk.TokensFromConsensusPower(4) + ubdA := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 11, + time.Unix(0, 0), ubdATokens) + keeper.SetUnbondingDelegation(ctx, ubdA) + + bondedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, rdATokens.MulRaw(2))) + notBondedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, ubdATokens)) + + // update bonded tokens + bondedPool := keeper.GetBondedPool(ctx) + notBondedPool := keeper.GetNotBondedPool(ctx) + + bondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + require.NoError(t, keeper.bankKeeper.SetBalances(ctx, bondedPool.GetAddress(), bondedPoolBalances.Add(bondedCoins...))) + + notBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress()) + require.NoError(t, keeper.bankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), notBondedPoolBalances.Add(notBondedCoins...))) + + keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) + keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) + + oldBonded := keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount + oldNotBonded := keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount + // slash validator + ctx = ctx.WithBlockHeight(12) + validator, found := keeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(PKs[0])) + require.True(t, found) + consAddr0 := sdk.ConsAddress(PKs[0].Address()) + keeper.Slash(ctx, consAddr0, 10, 10, fraction) + + burnedNotBondedAmount := fraction.MulInt(ubdATokens).TruncateInt() + burnedBondAmount := sdk.TokensFromConsensusPower(10).ToDec().Mul(fraction).TruncateInt() + burnedBondAmount = burnedBondAmount.Sub(burnedNotBondedAmount) + + // read updated pool + bondedPool = keeper.GetBondedPool(ctx) + notBondedPool = keeper.GetNotBondedPool(ctx) + + bondedPoolBalance := keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount + require.True(sdk.IntEq(t, oldBonded.Sub(burnedBondAmount), bondedPoolBalance)) + + notBondedPoolBalance := keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount + require.True(sdk.IntEq(t, oldNotBonded.Sub(burnedNotBondedAmount), notBondedPoolBalance)) + + // read updating redelegation + rdA, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) + require.True(t, found) + require.Len(t, rdA.Entries, 1) + // read updated validator + validator, found = keeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(PKs[0])) + require.True(t, found) + // power not decreased, all stake was bonded since + require.Equal(t, int64(10), validator.GetConsensusPower()) +} diff --git a/x/staking/keeper/slash_test.go b/x/staking/keeper/slash_test.go index 2127cf51e196..3f88942a5c61 100644 --- a/x/staking/keeper/slash_test.go +++ b/x/staking/keeper/slash_test.go @@ -1,604 +1,66 @@ -package keeper +package keeper_test import ( "testing" - "time" - - "github.com/stretchr/testify/require" - - abci "github.com/tendermint/tendermint/abci/types" + "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/staking/keeper" "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/stretchr/testify/require" ) -// TODO integrate with test_common.go helper (CreateTestInput) -// setup helper function - creates two validators -func setupHelper(t *testing.T, power int64) (sdk.Context, Keeper, types.Params) { - // setup - ctx, _, _, keeper, _ := CreateTestInput(t, false, power) - params := keeper.GetParams(ctx) +// initConfig creates 3 validators and bootstrap the app. +func initConfig(t *testing.T) (*simapp.SimApp, sdk.Context, []sdk.ValAddress) { + _, app, ctx := getBaseSimappWithCustomKeeper() + + addrDels := simapp.AddTestAddrsIncremental(app, ctx, 3, sdk.NewInt(10000)) + addrVals := simapp.ConvertAddrsToValAddrs(addrDels) + numVals := int64(3) - amt := sdk.TokensFromConsensusPower(power) - bondedCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), amt.MulRaw(numVals))) + amt := sdk.TokensFromConsensusPower(10) + bondedCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), amt.MulRaw(numVals))) - bondedPool := keeper.GetBondedPool(ctx) - require.NoError(t, keeper.bankKeeper.SetBalances(ctx, bondedPool.GetAddress(), bondedCoins)) - keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) + notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) + err := app.BankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), bondedCoins) + require.NoError(t, err) + app.SupplyKeeper.SetModuleAccount(ctx, notBondedPool) + + bondedPool := app.StakingKeeper.GetBondedPool(ctx) + err = app.BankKeeper.SetBalances(ctx, bondedPool.GetAddress(), bondedCoins) + require.NoError(t, err) + app.SupplyKeeper.SetModuleAccount(ctx, bondedPool) - // add numVals validators for i := int64(0); i < numVals; i++ { validator := types.NewValidator(addrVals[i], PKs[i], types.Description{}) validator, _ = validator.AddTokensFromDel(amt) - validator = TestingUpdateValidator(keeper, ctx, validator, true) - keeper.SetValidatorByConsAddr(ctx, validator) + validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) + app.StakingKeeper.SetValidatorByConsAddr(ctx, validator) } - return ctx, keeper, params + return app, ctx, addrVals } -//_________________________________________________________________________________ - // tests Jail, Unjail func TestRevocation(t *testing.T) { - // setup - ctx, keeper, _ := setupHelper(t, 10) - addr := addrVals[0] + app, ctx, addrVals := initConfig(t) + consAddr := sdk.ConsAddress(PKs[0].Address()) // initial state - val, found := keeper.GetValidator(ctx, addr) + val, found := app.StakingKeeper.GetValidator(ctx, addrVals[0]) require.True(t, found) require.False(t, val.IsJailed()) // test jail - keeper.Jail(ctx, consAddr) - val, found = keeper.GetValidator(ctx, addr) + app.StakingKeeper.Jail(ctx, consAddr) + val, found = app.StakingKeeper.GetValidator(ctx, addrVals[0]) require.True(t, found) require.True(t, val.IsJailed()) // test unjail - keeper.Unjail(ctx, consAddr) - val, found = keeper.GetValidator(ctx, addr) + app.StakingKeeper.Unjail(ctx, consAddr) + val, found = app.StakingKeeper.GetValidator(ctx, addrVals[0]) require.True(t, found) require.False(t, val.IsJailed()) } - -// tests slashUnbondingDelegation -func TestSlashUnbondingDelegation(t *testing.T) { - ctx, keeper, _ := setupHelper(t, 10) - fraction := sdk.NewDecWithPrec(5, 1) - - // set an unbonding delegation with expiration timestamp (beyond which the - // unbonding delegation shouldn't be slashed) - ubd := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 0, - time.Unix(5, 0), sdk.NewInt(10)) - - keeper.SetUnbondingDelegation(ctx, ubd) - - // unbonding started prior to the infraction height, stakw didn't contribute - slashAmount := keeper.slashUnbondingDelegation(ctx, ubd, 1, fraction) - require.Equal(t, int64(0), slashAmount.Int64()) - - // after the expiration time, no longer eligible for slashing - ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(10, 0)}) - keeper.SetUnbondingDelegation(ctx, ubd) - slashAmount = keeper.slashUnbondingDelegation(ctx, ubd, 0, fraction) - require.Equal(t, int64(0), slashAmount.Int64()) - - // test valid slash, before expiration timestamp and to which stake contributed - notBondedPool := keeper.GetNotBondedPool(ctx) - oldUnbondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress()) - ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(0, 0)}) - keeper.SetUnbondingDelegation(ctx, ubd) - slashAmount = keeper.slashUnbondingDelegation(ctx, ubd, 0, fraction) - require.Equal(t, int64(5), slashAmount.Int64()) - ubd, found := keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) - require.True(t, found) - require.Len(t, ubd.Entries, 1) - - // initial balance unchanged - require.Equal(t, sdk.NewInt(10), ubd.Entries[0].InitialBalance) - - // balance decreased - require.Equal(t, sdk.NewInt(5), ubd.Entries[0].Balance) - newUnbondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress()) - diffTokens := oldUnbondedPoolBalances.Sub(newUnbondedPoolBalances) - require.Equal(t, int64(5), diffTokens.AmountOf(keeper.BondDenom(ctx)).Int64()) -} - -// tests slashRedelegation -func TestSlashRedelegation(t *testing.T) { - ctx, keeper, _ := setupHelper(t, 10) - fraction := sdk.NewDecWithPrec(5, 1) - - // add bonded tokens to pool for (re)delegations - startCoins := sdk.NewCoins(sdk.NewInt64Coin(keeper.BondDenom(ctx), 15)) - bondedPool := keeper.GetBondedPool(ctx) - balances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) - - require.NoError(t, keeper.bankKeeper.SetBalances(ctx, bondedPool.GetAddress(), balances.Add(startCoins...))) - keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) - - // set a redelegation with an expiration timestamp beyond which the - // redelegation shouldn't be slashed - rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 0, - time.Unix(5, 0), sdk.NewInt(10), sdk.NewDec(10)) - - keeper.SetRedelegation(ctx, rd) - - // set the associated delegation - del := types.NewDelegation(addrDels[0], addrVals[1], sdk.NewDec(10)) - keeper.SetDelegation(ctx, del) - - // started redelegating prior to the current height, stake didn't contribute to infraction - validator, found := keeper.GetValidator(ctx, addrVals[1]) - require.True(t, found) - slashAmount := keeper.slashRedelegation(ctx, validator, rd, 1, fraction) - require.Equal(t, int64(0), slashAmount.Int64()) - - // after the expiration time, no longer eligible for slashing - ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(10, 0)}) - keeper.SetRedelegation(ctx, rd) - validator, found = keeper.GetValidator(ctx, addrVals[1]) - require.True(t, found) - slashAmount = keeper.slashRedelegation(ctx, validator, rd, 0, fraction) - require.Equal(t, int64(0), slashAmount.Int64()) - - balances = keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) - - // test valid slash, before expiration timestamp and to which stake contributed - ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(0, 0)}) - keeper.SetRedelegation(ctx, rd) - validator, found = keeper.GetValidator(ctx, addrVals[1]) - require.True(t, found) - slashAmount = keeper.slashRedelegation(ctx, validator, rd, 0, fraction) - require.Equal(t, int64(5), slashAmount.Int64()) - rd, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) - require.True(t, found) - require.Len(t, rd.Entries, 1) - - // end block - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 1, len(updates)) - - // initialbalance unchanged - require.Equal(t, sdk.NewInt(10), rd.Entries[0].InitialBalance) - - // shares decreased - del, found = keeper.GetDelegation(ctx, addrDels[0], addrVals[1]) - require.True(t, found) - require.Equal(t, int64(5), del.Shares.RoundInt64()) - - // pool bonded tokens should decrease - burnedCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), slashAmount)) - require.Equal(t, balances.Sub(burnedCoins), keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())) -} - -// tests Slash at a future height (must panic) -func TestSlashAtFutureHeight(t *testing.T) { - ctx, keeper, _ := setupHelper(t, 10) - consAddr := sdk.ConsAddress(PKs[0].Address()) - fraction := sdk.NewDecWithPrec(5, 1) - require.Panics(t, func() { keeper.Slash(ctx, consAddr, 1, 10, fraction) }) -} - -// test slash at a negative height -// this just represents pre-genesis and should have the same effect as slashing at height 0 -func TestSlashAtNegativeHeight(t *testing.T) { - ctx, keeper, _ := setupHelper(t, 10) - consAddr := sdk.ConsAddress(PKs[0].Address()) - fraction := sdk.NewDecWithPrec(5, 1) - - bondedPool := keeper.GetBondedPool(ctx) - oldBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) - - validator, found := keeper.GetValidatorByConsAddr(ctx, consAddr) - require.True(t, found) - keeper.Slash(ctx, consAddr, -2, 10, fraction) - - // read updated state - validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr) - require.True(t, found) - - // end block - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 1, len(updates), "cons addr: %v, updates: %v", []byte(consAddr), updates) - - validator = keeper.mustGetValidator(ctx, validator.OperatorAddress) - // power decreased - require.Equal(t, int64(5), validator.GetConsensusPower()) - - // pool bonded shares decreased - newBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) - diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx)) - require.Equal(t, sdk.TokensFromConsensusPower(5).String(), diffTokens.String()) -} - -// tests Slash at the current height -func TestSlashValidatorAtCurrentHeight(t *testing.T) { - ctx, keeper, _ := setupHelper(t, 10) - consAddr := sdk.ConsAddress(PKs[0].Address()) - fraction := sdk.NewDecWithPrec(5, 1) - - bondedPool := keeper.GetBondedPool(ctx) - oldBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) - - validator, found := keeper.GetValidatorByConsAddr(ctx, consAddr) - require.True(t, found) - keeper.Slash(ctx, consAddr, ctx.BlockHeight(), 10, fraction) - - // read updated state - validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr) - require.True(t, found) - - // end block - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 1, len(updates), "cons addr: %v, updates: %v", []byte(consAddr), updates) - - validator = keeper.mustGetValidator(ctx, validator.OperatorAddress) - // power decreased - require.Equal(t, int64(5), validator.GetConsensusPower()) - - // pool bonded shares decreased - newBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) - diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx)) - require.Equal(t, sdk.TokensFromConsensusPower(5).String(), diffTokens.String()) -} - -// tests Slash at a previous height with an unbonding delegation -func TestSlashWithUnbondingDelegation(t *testing.T) { - ctx, keeper, _ := setupHelper(t, 10) - consAddr := sdk.ConsAddress(PKs[0].Address()) - fraction := sdk.NewDecWithPrec(5, 1) - - // set an unbonding delegation with expiration timestamp beyond which the - // unbonding delegation shouldn't be slashed - ubdTokens := sdk.TokensFromConsensusPower(4) - ubd := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 11, - time.Unix(0, 0), ubdTokens) - keeper.SetUnbondingDelegation(ctx, ubd) - - // slash validator for the first time - ctx = ctx.WithBlockHeight(12) - bondedPool := keeper.GetBondedPool(ctx) - oldBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) - - validator, found := keeper.GetValidatorByConsAddr(ctx, consAddr) - require.True(t, found) - keeper.Slash(ctx, consAddr, 10, 10, fraction) - - // end block - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 1, len(updates)) - - // read updating unbonding delegation - ubd, found = keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) - require.True(t, found) - require.Len(t, ubd.Entries, 1) - - // balance decreased - require.Equal(t, sdk.TokensFromConsensusPower(2), ubd.Entries[0].Balance) - - // bonded tokens burned - newBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) - diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx)) - require.Equal(t, sdk.TokensFromConsensusPower(3), diffTokens) - - // read updated validator - validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr) - require.True(t, found) - - // power decreased by 3 - 6 stake originally bonded at the time of infraction - // was still bonded at the time of discovery and was slashed by half, 4 stake - // bonded at the time of discovery hadn't been bonded at the time of infraction - // and wasn't slashed - require.Equal(t, int64(7), validator.GetConsensusPower()) - - // slash validator again - ctx = ctx.WithBlockHeight(13) - keeper.Slash(ctx, consAddr, 9, 10, fraction) - - ubd, found = keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) - require.True(t, found) - require.Len(t, ubd.Entries, 1) - - // balance decreased again - require.Equal(t, sdk.NewInt(0), ubd.Entries[0].Balance) - - // bonded tokens burned again - newBondedPoolBalances = keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) - diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx)) - require.Equal(t, sdk.TokensFromConsensusPower(6), diffTokens) - - // read updated validator - validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr) - require.True(t, found) - - // power decreased by 3 again - require.Equal(t, int64(4), validator.GetConsensusPower()) - - // slash validator again - // all originally bonded stake has been slashed, so this will have no effect - // on the unbonding delegation, but it will slash stake bonded since the infraction - // this may not be the desirable behaviour, ref https://github.com/cosmos/cosmos-sdk/issues/1440 - ctx = ctx.WithBlockHeight(13) - keeper.Slash(ctx, consAddr, 9, 10, fraction) - - ubd, found = keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) - require.True(t, found) - require.Len(t, ubd.Entries, 1) - - // balance unchanged - require.Equal(t, sdk.NewInt(0), ubd.Entries[0].Balance) - - // bonded tokens burned again - newBondedPoolBalances = keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) - diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx)) - require.Equal(t, sdk.TokensFromConsensusPower(9), diffTokens) - - // read updated validator - validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr) - require.True(t, found) - - // power decreased by 3 again - require.Equal(t, int64(1), validator.GetConsensusPower()) - - // slash validator again - // all originally bonded stake has been slashed, so this will have no effect - // on the unbonding delegation, but it will slash stake bonded since the infraction - // this may not be the desirable behaviour, ref https://github.com/cosmos/cosmos-sdk/issues/1440 - ctx = ctx.WithBlockHeight(13) - keeper.Slash(ctx, consAddr, 9, 10, fraction) - - ubd, found = keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) - require.True(t, found) - require.Len(t, ubd.Entries, 1) - - // balance unchanged - require.Equal(t, sdk.NewInt(0), ubd.Entries[0].Balance) - - // just 1 bonded token burned again since that's all the validator now has - newBondedPoolBalances = keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) - diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx)) - require.Equal(t, sdk.TokensFromConsensusPower(10), diffTokens) - - // apply TM updates - keeper.ApplyAndReturnValidatorSetUpdates(ctx) - - // read updated validator - // power decreased by 1 again, validator is out of stake - // validator should be in unbonding period - validator, _ = keeper.GetValidatorByConsAddr(ctx, consAddr) - require.Equal(t, validator.GetStatus(), sdk.Unbonding) -} - -// tests Slash at a previous height with a redelegation -func TestSlashWithRedelegation(t *testing.T) { - ctx, keeper, _ := setupHelper(t, 10) - consAddr := sdk.ConsAddress(PKs[0].Address()) - fraction := sdk.NewDecWithPrec(5, 1) - bondDenom := keeper.BondDenom(ctx) - - // set a redelegation - rdTokens := sdk.TokensFromConsensusPower(6) - rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 11, - time.Unix(0, 0), rdTokens, rdTokens.ToDec()) - keeper.SetRedelegation(ctx, rd) - - // set the associated delegation - del := types.NewDelegation(addrDels[0], addrVals[1], rdTokens.ToDec()) - keeper.SetDelegation(ctx, del) - - // update bonded tokens - bondedPool := keeper.GetBondedPool(ctx) - notBondedPool := keeper.GetNotBondedPool(ctx) - rdCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, rdTokens.MulRaw(2))) - - balances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) - err := keeper.bankKeeper.SetBalances(ctx, bondedPool.GetAddress(), balances.Add(rdCoins...)) - require.NoError(t, err) - - keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) - - oldBonded := keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount - oldNotBonded := keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount - - // slash validator - ctx = ctx.WithBlockHeight(12) - validator, found := keeper.GetValidatorByConsAddr(ctx, consAddr) - require.True(t, found) - - require.NotPanics(t, func() { keeper.Slash(ctx, consAddr, 10, 10, fraction) }) - burnAmount := sdk.TokensFromConsensusPower(10).ToDec().Mul(fraction).TruncateInt() - - bondedPool = keeper.GetBondedPool(ctx) - notBondedPool = keeper.GetNotBondedPool(ctx) - - // burn bonded tokens from only from delegations - bondedPoolBalance := keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount - require.True(sdk.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance)) - - notBondedPoolBalance := keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount - require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance)) - oldBonded = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount - - // read updating redelegation - rd, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) - require.True(t, found) - require.Len(t, rd.Entries, 1) - // read updated validator - validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr) - require.True(t, found) - // power decreased by 2 - 4 stake originally bonded at the time of infraction - // was still bonded at the time of discovery and was slashed by half, 4 stake - // bonded at the time of discovery hadn't been bonded at the time of infraction - // and wasn't slashed - require.Equal(t, int64(8), validator.GetConsensusPower()) - - // slash the validator again - validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr) - require.True(t, found) - - require.NotPanics(t, func() { keeper.Slash(ctx, consAddr, 10, 10, sdk.OneDec()) }) - burnAmount = sdk.TokensFromConsensusPower(7) - - // read updated pool - bondedPool = keeper.GetBondedPool(ctx) - notBondedPool = keeper.GetNotBondedPool(ctx) - - // seven bonded tokens burned - bondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount - require.True(sdk.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance)) - require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance)) - - bondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount - require.True(sdk.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance)) - - notBondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount - require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance)) - oldBonded = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount - - // read updating redelegation - rd, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) - require.True(t, found) - require.Len(t, rd.Entries, 1) - // read updated validator - validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr) - require.True(t, found) - // power decreased by 4 - require.Equal(t, int64(4), validator.GetConsensusPower()) - - // slash the validator again, by 100% - ctx = ctx.WithBlockHeight(12) - validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr) - require.True(t, found) - - require.NotPanics(t, func() { keeper.Slash(ctx, consAddr, 10, 10, sdk.OneDec()) }) - - burnAmount = sdk.TokensFromConsensusPower(10).ToDec().Mul(sdk.OneDec()).TruncateInt() - burnAmount = burnAmount.Sub(sdk.OneDec().MulInt(rdTokens).TruncateInt()) - - // read updated pool - bondedPool = keeper.GetBondedPool(ctx) - notBondedPool = keeper.GetNotBondedPool(ctx) - - bondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount - require.True(sdk.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance)) - notBondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount - require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance)) - oldBonded = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount - - // read updating redelegation - rd, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) - require.True(t, found) - require.Len(t, rd.Entries, 1) - // apply TM updates - keeper.ApplyAndReturnValidatorSetUpdates(ctx) - // read updated validator - // validator decreased to zero power, should be in unbonding period - validator, _ = keeper.GetValidatorByConsAddr(ctx, consAddr) - require.Equal(t, validator.GetStatus(), sdk.Unbonding) - - // slash the validator again, by 100% - // no stake remains to be slashed - ctx = ctx.WithBlockHeight(12) - // validator still in unbonding period - validator, _ = keeper.GetValidatorByConsAddr(ctx, consAddr) - require.Equal(t, validator.GetStatus(), sdk.Unbonding) - - require.NotPanics(t, func() { keeper.Slash(ctx, consAddr, 10, 10, sdk.OneDec()) }) - - // read updated pool - bondedPool = keeper.GetBondedPool(ctx) - notBondedPool = keeper.GetNotBondedPool(ctx) - - bondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount - require.True(sdk.IntEq(t, oldBonded, bondedPoolBalance)) - notBondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount - require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance)) - - // read updating redelegation - rd, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) - require.True(t, found) - require.Len(t, rd.Entries, 1) - // read updated validator - // power still zero, still in unbonding period - validator, _ = keeper.GetValidatorByConsAddr(ctx, consAddr) - require.Equal(t, validator.GetStatus(), sdk.Unbonding) -} - -// tests Slash at a previous height with both an unbonding delegation and a redelegation -func TestSlashBoth(t *testing.T) { - ctx, keeper, _ := setupHelper(t, 10) - fraction := sdk.NewDecWithPrec(5, 1) - bondDenom := keeper.BondDenom(ctx) - - // set a redelegation with expiration timestamp beyond which the - // redelegation shouldn't be slashed - rdATokens := sdk.TokensFromConsensusPower(6) - rdA := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 11, - time.Unix(0, 0), rdATokens, - rdATokens.ToDec()) - keeper.SetRedelegation(ctx, rdA) - - // set the associated delegation - delA := types.NewDelegation(addrDels[0], addrVals[1], rdATokens.ToDec()) - keeper.SetDelegation(ctx, delA) - - // set an unbonding delegation with expiration timestamp (beyond which the - // unbonding delegation shouldn't be slashed) - ubdATokens := sdk.TokensFromConsensusPower(4) - ubdA := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 11, - time.Unix(0, 0), ubdATokens) - keeper.SetUnbondingDelegation(ctx, ubdA) - - bondedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, rdATokens.MulRaw(2))) - notBondedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, ubdATokens)) - - // update bonded tokens - bondedPool := keeper.GetBondedPool(ctx) - notBondedPool := keeper.GetNotBondedPool(ctx) - - bondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) - require.NoError(t, keeper.bankKeeper.SetBalances(ctx, bondedPool.GetAddress(), bondedPoolBalances.Add(bondedCoins...))) - - notBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress()) - require.NoError(t, keeper.bankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), notBondedPoolBalances.Add(notBondedCoins...))) - - keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - oldBonded := keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount - oldNotBonded := keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount - // slash validator - ctx = ctx.WithBlockHeight(12) - validator, found := keeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(PKs[0])) - require.True(t, found) - consAddr0 := sdk.ConsAddress(PKs[0].Address()) - keeper.Slash(ctx, consAddr0, 10, 10, fraction) - - burnedNotBondedAmount := fraction.MulInt(ubdATokens).TruncateInt() - burnedBondAmount := sdk.TokensFromConsensusPower(10).ToDec().Mul(fraction).TruncateInt() - burnedBondAmount = burnedBondAmount.Sub(burnedNotBondedAmount) - - // read updated pool - bondedPool = keeper.GetBondedPool(ctx) - notBondedPool = keeper.GetNotBondedPool(ctx) - - bondedPoolBalance := keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount - require.True(sdk.IntEq(t, oldBonded.Sub(burnedBondAmount), bondedPoolBalance)) - - notBondedPoolBalance := keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount - require.True(sdk.IntEq(t, oldNotBonded.Sub(burnedNotBondedAmount), notBondedPoolBalance)) - - // read updating redelegation - rdA, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) - require.True(t, found) - require.Len(t, rdA.Entries, 1) - // read updated validator - validator, found = keeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(PKs[0])) - require.True(t, found) - // power not decreased, all stake was bonded since - require.Equal(t, int64(10), validator.GetConsensusPower()) -} From a34575a8bbdf0ca4e4464364e22929375d51fbeb Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Mon, 24 Feb 2020 18:30:30 +0100 Subject: [PATCH 34/90] fix TestSlashUnbondingDelegation test to use simapp --- x/staking/keeper/old_slash_test.go | 43 -------------------- x/staking/keeper/slash.go | 4 +- x/staking/keeper/slash_test.go | 64 ++++++++++++++++++++++++++---- 3 files changed, 58 insertions(+), 53 deletions(-) diff --git a/x/staking/keeper/old_slash_test.go b/x/staking/keeper/old_slash_test.go index f6b442dc3c18..66023db24df2 100644 --- a/x/staking/keeper/old_slash_test.go +++ b/x/staking/keeper/old_slash_test.go @@ -39,49 +39,6 @@ func setupHelper(t *testing.T, power int64) (sdk.Context, Keeper, types.Params) //_________________________________________________________________________________ -// tests slashUnbondingDelegation -func TestSlashUnbondingDelegation(t *testing.T) { - ctx, keeper, _ := setupHelper(t, 10) - fraction := sdk.NewDecWithPrec(5, 1) - - // set an unbonding delegation with expiration timestamp (beyond which the - // unbonding delegation shouldn't be slashed) - ubd := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 0, - time.Unix(5, 0), sdk.NewInt(10)) - - keeper.SetUnbondingDelegation(ctx, ubd) - - // unbonding started prior to the infraction height, stakw didn't contribute - slashAmount := keeper.slashUnbondingDelegation(ctx, ubd, 1, fraction) - require.Equal(t, int64(0), slashAmount.Int64()) - - // after the expiration time, no longer eligible for slashing - ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(10, 0)}) - keeper.SetUnbondingDelegation(ctx, ubd) - slashAmount = keeper.slashUnbondingDelegation(ctx, ubd, 0, fraction) - require.Equal(t, int64(0), slashAmount.Int64()) - - // test valid slash, before expiration timestamp and to which stake contributed - notBondedPool := keeper.GetNotBondedPool(ctx) - oldUnbondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress()) - ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(0, 0)}) - keeper.SetUnbondingDelegation(ctx, ubd) - slashAmount = keeper.slashUnbondingDelegation(ctx, ubd, 0, fraction) - require.Equal(t, int64(5), slashAmount.Int64()) - ubd, found := keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) - require.True(t, found) - require.Len(t, ubd.Entries, 1) - - // initial balance unchanged - require.Equal(t, sdk.NewInt(10), ubd.Entries[0].InitialBalance) - - // balance decreased - require.Equal(t, sdk.NewInt(5), ubd.Entries[0].Balance) - newUnbondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress()) - diffTokens := oldUnbondedPoolBalances.Sub(newUnbondedPoolBalances) - require.Equal(t, int64(5), diffTokens.AmountOf(keeper.BondDenom(ctx)).Int64()) -} - // tests slashRedelegation func TestSlashRedelegation(t *testing.T) { ctx, keeper, _ := setupHelper(t, 10) diff --git a/x/staking/keeper/slash.go b/x/staking/keeper/slash.go index 76db0c8e99ba..7f1bf5bba6bf 100644 --- a/x/staking/keeper/slash.go +++ b/x/staking/keeper/slash.go @@ -82,7 +82,7 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh // Iterate through unbonding delegations from slashed validator unbondingDelegations := k.GetUnbondingDelegationsFromValidator(ctx, operatorAddress) for _, unbondingDelegation := range unbondingDelegations { - amountSlashed := k.slashUnbondingDelegation(ctx, unbondingDelegation, infractionHeight, slashFactor) + amountSlashed := k.SlashUnbondingDelegation(ctx, unbondingDelegation, infractionHeight, slashFactor) if amountSlashed.IsZero() { continue } @@ -160,7 +160,7 @@ func (k Keeper) Unjail(ctx sdk.Context, consAddr sdk.ConsAddress) { // the unbonding delegation had enough stake to slash // (the amount actually slashed may be less if there's // insufficient stake remaining) -func (k Keeper) slashUnbondingDelegation(ctx sdk.Context, unbondingDelegation types.UnbondingDelegation, +func (k Keeper) SlashUnbondingDelegation(ctx sdk.Context, unbondingDelegation types.UnbondingDelegation, infractionHeight int64, slashFactor sdk.Dec) (totalSlashAmount sdk.Int) { now := ctx.BlockHeader().Time diff --git a/x/staking/keeper/slash_test.go b/x/staking/keeper/slash_test.go index 3f88942a5c61..37c5c4ee2b4b 100644 --- a/x/staking/keeper/slash_test.go +++ b/x/staking/keeper/slash_test.go @@ -2,6 +2,9 @@ package keeper_test import ( "testing" + "time" + + abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" @@ -11,21 +14,22 @@ import ( ) // initConfig creates 3 validators and bootstrap the app. -func initConfig(t *testing.T) (*simapp.SimApp, sdk.Context, []sdk.ValAddress) { +func initConfig(t *testing.T, power int64) (*simapp.SimApp, sdk.Context, []sdk.AccAddress, []sdk.ValAddress) { _, app, ctx := getBaseSimappWithCustomKeeper() - addrDels := simapp.AddTestAddrsIncremental(app, ctx, 3, sdk.NewInt(10000)) + addrDels := simapp.AddTestAddrsIncremental(app, ctx, 100, sdk.NewInt(10000)) addrVals := simapp.ConvertAddrsToValAddrs(addrDels) - numVals := int64(3) - amt := sdk.TokensFromConsensusPower(10) - bondedCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), amt.MulRaw(numVals))) + 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(), bondedCoins) + err := app.BankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), totalSupply) require.NoError(t, err) app.SupplyKeeper.SetModuleAccount(ctx, notBondedPool) + numVals := int64(3) + bondedCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), amt.MulRaw(numVals))) bondedPool := app.StakingKeeper.GetBondedPool(ctx) err = app.BankKeeper.SetBalances(ctx, bondedPool.GetAddress(), bondedCoins) require.NoError(t, err) @@ -38,12 +42,12 @@ func initConfig(t *testing.T) (*simapp.SimApp, sdk.Context, []sdk.ValAddress) { app.StakingKeeper.SetValidatorByConsAddr(ctx, validator) } - return app, ctx, addrVals + return app, ctx, addrDels, addrVals } // tests Jail, Unjail func TestRevocation(t *testing.T) { - app, ctx, addrVals := initConfig(t) + app, ctx, _, addrVals := initConfig(t, 5) consAddr := sdk.ConsAddress(PKs[0].Address()) @@ -64,3 +68,47 @@ func TestRevocation(t *testing.T) { require.True(t, found) require.False(t, val.IsJailed()) } + +// tests slashUnbondingDelegation +func TestSlashUnbondingDelegation(t *testing.T) { + app, ctx, addrDels, addrVals := initConfig(t, 10) + + fraction := sdk.NewDecWithPrec(5, 1) + + // set an unbonding delegation with expiration timestamp (beyond which the + // unbonding delegation shouldn't be slashed) + ubd := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 0, + time.Unix(5, 0), sdk.NewInt(10)) + + app.StakingKeeper.SetUnbondingDelegation(ctx, ubd) + + // unbonding started prior to the infraction height, stakw didn't contribute + slashAmount := app.StakingKeeper.SlashUnbondingDelegation(ctx, ubd, 1, fraction) + require.Equal(t, int64(0), slashAmount.Int64()) + + // after the expiration time, no longer eligible for slashing + ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(10, 0)}) + app.StakingKeeper.SetUnbondingDelegation(ctx, ubd) + slashAmount = app.StakingKeeper.SlashUnbondingDelegation(ctx, ubd, 0, fraction) + require.Equal(t, int64(0), slashAmount.Int64()) + + // test valid slash, before expiration timestamp and to which stake contributed + notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) + oldUnbondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress()) + ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(0, 0)}) + app.StakingKeeper.SetUnbondingDelegation(ctx, ubd) + slashAmount = app.StakingKeeper.SlashUnbondingDelegation(ctx, ubd, 0, fraction) + require.Equal(t, int64(5), slashAmount.Int64()) + ubd, found := app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) + require.True(t, found) + require.Len(t, ubd.Entries, 1) + + // initial balance unchanged + require.Equal(t, sdk.NewInt(10), ubd.Entries[0].InitialBalance) + + // balance decreased + require.Equal(t, sdk.NewInt(5), ubd.Entries[0].Balance) + newUnbondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress()) + diffTokens := oldUnbondedPoolBalances.Sub(newUnbondedPoolBalances) + require.Equal(t, int64(5), diffTokens.AmountOf(app.StakingKeeper.BondDenom(ctx)).Int64()) +} From 3ea53f56825e3522d2d5f02908118401897f0b15 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Mon, 24 Feb 2020 18:41:01 +0100 Subject: [PATCH 35/90] refactor TestSlashRedelegation to use simapp --- x/staking/keeper/old_slash_test.go | 70 ------------------------------ x/staking/keeper/slash.go | 4 +- x/staking/keeper/slash_test.go | 68 +++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 72 deletions(-) diff --git a/x/staking/keeper/old_slash_test.go b/x/staking/keeper/old_slash_test.go index 66023db24df2..bd311491b9f0 100644 --- a/x/staking/keeper/old_slash_test.go +++ b/x/staking/keeper/old_slash_test.go @@ -6,8 +6,6 @@ import ( "github.com/stretchr/testify/require" - abci "github.com/tendermint/tendermint/abci/types" - sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/staking/types" ) @@ -39,74 +37,6 @@ func setupHelper(t *testing.T, power int64) (sdk.Context, Keeper, types.Params) //_________________________________________________________________________________ -// tests slashRedelegation -func TestSlashRedelegation(t *testing.T) { - ctx, keeper, _ := setupHelper(t, 10) - fraction := sdk.NewDecWithPrec(5, 1) - - // add bonded tokens to pool for (re)delegations - startCoins := sdk.NewCoins(sdk.NewInt64Coin(keeper.BondDenom(ctx), 15)) - bondedPool := keeper.GetBondedPool(ctx) - balances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) - - require.NoError(t, keeper.bankKeeper.SetBalances(ctx, bondedPool.GetAddress(), balances.Add(startCoins...))) - keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) - - // set a redelegation with an expiration timestamp beyond which the - // redelegation shouldn't be slashed - rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 0, - time.Unix(5, 0), sdk.NewInt(10), sdk.NewDec(10)) - - keeper.SetRedelegation(ctx, rd) - - // set the associated delegation - del := types.NewDelegation(addrDels[0], addrVals[1], sdk.NewDec(10)) - keeper.SetDelegation(ctx, del) - - // started redelegating prior to the current height, stake didn't contribute to infraction - validator, found := keeper.GetValidator(ctx, addrVals[1]) - require.True(t, found) - slashAmount := keeper.slashRedelegation(ctx, validator, rd, 1, fraction) - require.Equal(t, int64(0), slashAmount.Int64()) - - // after the expiration time, no longer eligible for slashing - ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(10, 0)}) - keeper.SetRedelegation(ctx, rd) - validator, found = keeper.GetValidator(ctx, addrVals[1]) - require.True(t, found) - slashAmount = keeper.slashRedelegation(ctx, validator, rd, 0, fraction) - require.Equal(t, int64(0), slashAmount.Int64()) - - balances = keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) - - // test valid slash, before expiration timestamp and to which stake contributed - ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(0, 0)}) - keeper.SetRedelegation(ctx, rd) - validator, found = keeper.GetValidator(ctx, addrVals[1]) - require.True(t, found) - slashAmount = keeper.slashRedelegation(ctx, validator, rd, 0, fraction) - require.Equal(t, int64(5), slashAmount.Int64()) - rd, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) - require.True(t, found) - require.Len(t, rd.Entries, 1) - - // end block - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 1, len(updates)) - - // initialbalance unchanged - require.Equal(t, sdk.NewInt(10), rd.Entries[0].InitialBalance) - - // shares decreased - del, found = keeper.GetDelegation(ctx, addrDels[0], addrVals[1]) - require.True(t, found) - require.Equal(t, int64(5), del.Shares.RoundInt64()) - - // pool bonded tokens should decrease - burnedCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), slashAmount)) - require.Equal(t, balances.Sub(burnedCoins), keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())) -} - // tests Slash at a future height (must panic) func TestSlashAtFutureHeight(t *testing.T) { ctx, keeper, _ := setupHelper(t, 10) diff --git a/x/staking/keeper/slash.go b/x/staking/keeper/slash.go index 7f1bf5bba6bf..58e7ebee2bbe 100644 --- a/x/staking/keeper/slash.go +++ b/x/staking/keeper/slash.go @@ -92,7 +92,7 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh // Iterate through redelegations from slashed source validator redelegations := k.GetRedelegationsFromSrcValidator(ctx, operatorAddress) for _, redelegation := range redelegations { - amountSlashed := k.slashRedelegation(ctx, validator, redelegation, infractionHeight, slashFactor) + amountSlashed := k.SlashRedelegation(ctx, validator, redelegation, infractionHeight, slashFactor) if amountSlashed.IsZero() { continue } @@ -215,7 +215,7 @@ func (k Keeper) SlashUnbondingDelegation(ctx sdk.Context, unbondingDelegation ty // (the amount actually slashed may be less if there's // insufficient stake remaining) // NOTE this is only slashing for prior infractions from the source validator -func (k Keeper) slashRedelegation(ctx sdk.Context, srcValidator types.Validator, redelegation types.Redelegation, +func (k Keeper) SlashRedelegation(ctx sdk.Context, srcValidator types.Validator, redelegation types.Redelegation, infractionHeight int64, slashFactor sdk.Dec) (totalSlashAmount sdk.Int) { now := ctx.BlockHeader().Time diff --git a/x/staking/keeper/slash_test.go b/x/staking/keeper/slash_test.go index 37c5c4ee2b4b..15d735bbe983 100644 --- a/x/staking/keeper/slash_test.go +++ b/x/staking/keeper/slash_test.go @@ -112,3 +112,71 @@ func TestSlashUnbondingDelegation(t *testing.T) { diffTokens := oldUnbondedPoolBalances.Sub(newUnbondedPoolBalances) require.Equal(t, int64(5), diffTokens.AmountOf(app.StakingKeeper.BondDenom(ctx)).Int64()) } + +// tests slashRedelegation +func TestSlashRedelegation(t *testing.T) { + app, ctx, addrDels, addrVals := initConfig(t, 10) + fraction := sdk.NewDecWithPrec(5, 1) + + // add bonded tokens to pool for (re)delegations + startCoins := sdk.NewCoins(sdk.NewInt64Coin(app.StakingKeeper.BondDenom(ctx), 15)) + bondedPool := app.StakingKeeper.GetBondedPool(ctx) + balances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + + require.NoError(t, app.BankKeeper.SetBalances(ctx, bondedPool.GetAddress(), balances.Add(startCoins...))) + app.SupplyKeeper.SetModuleAccount(ctx, bondedPool) + + // set a redelegation with an expiration timestamp beyond which the + // redelegation shouldn't be slashed + rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 0, + time.Unix(5, 0), sdk.NewInt(10), sdk.NewDec(10)) + + app.StakingKeeper.SetRedelegation(ctx, rd) + + // set the associated delegation + del := types.NewDelegation(addrDels[0], addrVals[1], sdk.NewDec(10)) + app.StakingKeeper.SetDelegation(ctx, del) + + // started redelegating prior to the current height, stake didn't contribute to infraction + validator, found := app.StakingKeeper.GetValidator(ctx, addrVals[1]) + require.True(t, found) + slashAmount := app.StakingKeeper.SlashRedelegation(ctx, validator, rd, 1, fraction) + require.Equal(t, int64(0), slashAmount.Int64()) + + // after the expiration time, no longer eligible for slashing + ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(10, 0)}) + app.StakingKeeper.SetRedelegation(ctx, rd) + validator, found = app.StakingKeeper.GetValidator(ctx, addrVals[1]) + require.True(t, found) + slashAmount = app.StakingKeeper.SlashRedelegation(ctx, validator, rd, 0, fraction) + require.Equal(t, int64(0), slashAmount.Int64()) + + balances = app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + + // test valid slash, before expiration timestamp and to which stake contributed + ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(0, 0)}) + app.StakingKeeper.SetRedelegation(ctx, rd) + validator, found = app.StakingKeeper.GetValidator(ctx, addrVals[1]) + require.True(t, found) + slashAmount = app.StakingKeeper.SlashRedelegation(ctx, validator, rd, 0, fraction) + require.Equal(t, int64(5), slashAmount.Int64()) + rd, found = app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) + require.True(t, found) + require.Len(t, rd.Entries, 1) + + // end block + updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 1, len(updates)) + + // initialbalance unchanged + require.Equal(t, sdk.NewInt(10), rd.Entries[0].InitialBalance) + + // shares decreased + del, found = app.StakingKeeper.GetDelegation(ctx, addrDels[0], addrVals[1]) + require.True(t, found) + require.Equal(t, int64(5), del.Shares.RoundInt64()) + + // pool bonded tokens should decrease + burnedCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), slashAmount)) + require.Equal(t, balances.Sub(burnedCoins), app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())) +} From 7ee50eacf2fee5494978b8bb316a70f37b2b8bda Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Mon, 24 Feb 2020 18:43:51 +0100 Subject: [PATCH 36/90] refactor TestSlashAtFutureHeight test --- x/staking/keeper/old_slash_test.go | 8 -------- x/staking/keeper/slash_test.go | 9 +++++++++ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/x/staking/keeper/old_slash_test.go b/x/staking/keeper/old_slash_test.go index bd311491b9f0..f59ad9f8037b 100644 --- a/x/staking/keeper/old_slash_test.go +++ b/x/staking/keeper/old_slash_test.go @@ -37,14 +37,6 @@ func setupHelper(t *testing.T, power int64) (sdk.Context, Keeper, types.Params) //_________________________________________________________________________________ -// tests Slash at a future height (must panic) -func TestSlashAtFutureHeight(t *testing.T) { - ctx, keeper, _ := setupHelper(t, 10) - consAddr := sdk.ConsAddress(PKs[0].Address()) - fraction := sdk.NewDecWithPrec(5, 1) - require.Panics(t, func() { keeper.Slash(ctx, consAddr, 1, 10, fraction) }) -} - // test slash at a negative height // this just represents pre-genesis and should have the same effect as slashing at height 0 func TestSlashAtNegativeHeight(t *testing.T) { diff --git a/x/staking/keeper/slash_test.go b/x/staking/keeper/slash_test.go index 15d735bbe983..3aed1a8e15d0 100644 --- a/x/staking/keeper/slash_test.go +++ b/x/staking/keeper/slash_test.go @@ -180,3 +180,12 @@ func TestSlashRedelegation(t *testing.T) { burnedCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), slashAmount)) require.Equal(t, balances.Sub(burnedCoins), app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress())) } + +// tests Slash at a future height (must panic) +func TestSlashAtFutureHeight(t *testing.T) { + app, ctx, _, _ := initConfig(t, 10) + + consAddr := sdk.ConsAddress(PKs[0].Address()) + fraction := sdk.NewDecWithPrec(5, 1) + require.Panics(t, func() { app.StakingKeeper.Slash(ctx, consAddr, 1, 10, fraction) }) +} From b36cdac3e3993069bf88ef594c99a52d4e17aabc Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Mon, 24 Feb 2020 19:01:55 +0100 Subject: [PATCH 37/90] test TestSlashAtNegativeHeight migrated to simapp --- x/staking/keeper/old_slash_test.go | 32 -------------------------- x/staking/keeper/slash_test.go | 37 ++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 32 deletions(-) diff --git a/x/staking/keeper/old_slash_test.go b/x/staking/keeper/old_slash_test.go index f59ad9f8037b..61fe22d04b9a 100644 --- a/x/staking/keeper/old_slash_test.go +++ b/x/staking/keeper/old_slash_test.go @@ -37,38 +37,6 @@ func setupHelper(t *testing.T, power int64) (sdk.Context, Keeper, types.Params) //_________________________________________________________________________________ -// test slash at a negative height -// this just represents pre-genesis and should have the same effect as slashing at height 0 -func TestSlashAtNegativeHeight(t *testing.T) { - ctx, keeper, _ := setupHelper(t, 10) - consAddr := sdk.ConsAddress(PKs[0].Address()) - fraction := sdk.NewDecWithPrec(5, 1) - - bondedPool := keeper.GetBondedPool(ctx) - oldBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) - - validator, found := keeper.GetValidatorByConsAddr(ctx, consAddr) - require.True(t, found) - keeper.Slash(ctx, consAddr, -2, 10, fraction) - - // read updated state - validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr) - require.True(t, found) - - // end block - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 1, len(updates), "cons addr: %v, updates: %v", []byte(consAddr), updates) - - validator = keeper.mustGetValidator(ctx, validator.OperatorAddress) - // power decreased - require.Equal(t, int64(5), validator.GetConsensusPower()) - - // pool bonded shares decreased - newBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) - diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx)) - require.Equal(t, sdk.TokensFromConsensusPower(5).String(), diffTokens.String()) -} - // tests Slash at the current height func TestSlashValidatorAtCurrentHeight(t *testing.T) { ctx, keeper, _ := setupHelper(t, 10) diff --git a/x/staking/keeper/slash_test.go b/x/staking/keeper/slash_test.go index 3aed1a8e15d0..7630824b99c5 100644 --- a/x/staking/keeper/slash_test.go +++ b/x/staking/keeper/slash_test.go @@ -4,6 +4,8 @@ import ( "testing" "time" + "github.com/cosmos/cosmos-sdk/x/supply" + abci "github.com/tendermint/tendermint/abci/types" "github.com/cosmos/cosmos-sdk/simapp" @@ -35,6 +37,8 @@ func initConfig(t *testing.T, power int64) (*simapp.SimApp, sdk.Context, []sdk.A require.NoError(t, err) app.SupplyKeeper.SetModuleAccount(ctx, bondedPool) + app.SupplyKeeper.SetSupply(ctx, supply.NewSupply(totalSupply)) + for i := int64(0); i < numVals; i++ { validator := types.NewValidator(addrVals[i], PKs[i], types.Description{}) validator, _ = validator.AddTokensFromDel(amt) @@ -189,3 +193,36 @@ func TestSlashAtFutureHeight(t *testing.T) { fraction := sdk.NewDecWithPrec(5, 1) require.Panics(t, func() { app.StakingKeeper.Slash(ctx, consAddr, 1, 10, fraction) }) } + +// test slash at a negative height +// this just represents pre-genesis and should have the same effect as slashing at height 0 +func TestSlashAtNegativeHeight(t *testing.T) { + app, ctx, _, _ := initConfig(t, 10) + consAddr := sdk.ConsAddress(PKs[0].Address()) + fraction := sdk.NewDecWithPrec(5, 1) + + bondedPool := app.StakingKeeper.GetBondedPool(ctx) + oldBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + + validator, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr) + require.True(t, found) + app.StakingKeeper.Slash(ctx, consAddr, -2, 10, fraction) + + // read updated state + validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr) + require.True(t, found) + + // end block + updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 1, len(updates), "cons addr: %v, updates: %v", []byte(consAddr), updates) + + validator, found = app.StakingKeeper.GetValidator(ctx, validator.OperatorAddress) + require.True(t, found) + // power decreased + require.Equal(t, int64(5), validator.GetConsensusPower()) + + // pool bonded shares decreased + newBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(app.StakingKeeper.BondDenom(ctx)) + require.Equal(t, sdk.TokensFromConsensusPower(5).String(), diffTokens.String()) +} From a6767d31fe6b3c2e4706f8a386d587f9a5fd951e Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Tue, 25 Feb 2020 10:13:13 +0100 Subject: [PATCH 38/90] migrated two tests from slash_test to use simapp --- x/staking/keeper/old_slash_test.go | 159 ------------------------ x/staking/keeper/slash_test.go | 187 +++++++++++++++++++++++++++-- 2 files changed, 178 insertions(+), 168 deletions(-) diff --git a/x/staking/keeper/old_slash_test.go b/x/staking/keeper/old_slash_test.go index 61fe22d04b9a..a0c302c0ba68 100644 --- a/x/staking/keeper/old_slash_test.go +++ b/x/staking/keeper/old_slash_test.go @@ -36,165 +36,6 @@ func setupHelper(t *testing.T, power int64) (sdk.Context, Keeper, types.Params) } //_________________________________________________________________________________ - -// tests Slash at the current height -func TestSlashValidatorAtCurrentHeight(t *testing.T) { - ctx, keeper, _ := setupHelper(t, 10) - consAddr := sdk.ConsAddress(PKs[0].Address()) - fraction := sdk.NewDecWithPrec(5, 1) - - bondedPool := keeper.GetBondedPool(ctx) - oldBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) - - validator, found := keeper.GetValidatorByConsAddr(ctx, consAddr) - require.True(t, found) - keeper.Slash(ctx, consAddr, ctx.BlockHeight(), 10, fraction) - - // read updated state - validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr) - require.True(t, found) - - // end block - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 1, len(updates), "cons addr: %v, updates: %v", []byte(consAddr), updates) - - validator = keeper.mustGetValidator(ctx, validator.OperatorAddress) - // power decreased - require.Equal(t, int64(5), validator.GetConsensusPower()) - - // pool bonded shares decreased - newBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) - diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx)) - require.Equal(t, sdk.TokensFromConsensusPower(5).String(), diffTokens.String()) -} - -// tests Slash at a previous height with an unbonding delegation -func TestSlashWithUnbondingDelegation(t *testing.T) { - ctx, keeper, _ := setupHelper(t, 10) - consAddr := sdk.ConsAddress(PKs[0].Address()) - fraction := sdk.NewDecWithPrec(5, 1) - - // set an unbonding delegation with expiration timestamp beyond which the - // unbonding delegation shouldn't be slashed - ubdTokens := sdk.TokensFromConsensusPower(4) - ubd := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 11, - time.Unix(0, 0), ubdTokens) - keeper.SetUnbondingDelegation(ctx, ubd) - - // slash validator for the first time - ctx = ctx.WithBlockHeight(12) - bondedPool := keeper.GetBondedPool(ctx) - oldBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) - - validator, found := keeper.GetValidatorByConsAddr(ctx, consAddr) - require.True(t, found) - keeper.Slash(ctx, consAddr, 10, 10, fraction) - - // end block - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 1, len(updates)) - - // read updating unbonding delegation - ubd, found = keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) - require.True(t, found) - require.Len(t, ubd.Entries, 1) - - // balance decreased - require.Equal(t, sdk.TokensFromConsensusPower(2), ubd.Entries[0].Balance) - - // bonded tokens burned - newBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) - diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx)) - require.Equal(t, sdk.TokensFromConsensusPower(3), diffTokens) - - // read updated validator - validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr) - require.True(t, found) - - // power decreased by 3 - 6 stake originally bonded at the time of infraction - // was still bonded at the time of discovery and was slashed by half, 4 stake - // bonded at the time of discovery hadn't been bonded at the time of infraction - // and wasn't slashed - require.Equal(t, int64(7), validator.GetConsensusPower()) - - // slash validator again - ctx = ctx.WithBlockHeight(13) - keeper.Slash(ctx, consAddr, 9, 10, fraction) - - ubd, found = keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) - require.True(t, found) - require.Len(t, ubd.Entries, 1) - - // balance decreased again - require.Equal(t, sdk.NewInt(0), ubd.Entries[0].Balance) - - // bonded tokens burned again - newBondedPoolBalances = keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) - diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx)) - require.Equal(t, sdk.TokensFromConsensusPower(6), diffTokens) - - // read updated validator - validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr) - require.True(t, found) - - // power decreased by 3 again - require.Equal(t, int64(4), validator.GetConsensusPower()) - - // slash validator again - // all originally bonded stake has been slashed, so this will have no effect - // on the unbonding delegation, but it will slash stake bonded since the infraction - // this may not be the desirable behaviour, ref https://github.com/cosmos/cosmos-sdk/issues/1440 - ctx = ctx.WithBlockHeight(13) - keeper.Slash(ctx, consAddr, 9, 10, fraction) - - ubd, found = keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) - require.True(t, found) - require.Len(t, ubd.Entries, 1) - - // balance unchanged - require.Equal(t, sdk.NewInt(0), ubd.Entries[0].Balance) - - // bonded tokens burned again - newBondedPoolBalances = keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) - diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx)) - require.Equal(t, sdk.TokensFromConsensusPower(9), diffTokens) - - // read updated validator - validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr) - require.True(t, found) - - // power decreased by 3 again - require.Equal(t, int64(1), validator.GetConsensusPower()) - - // slash validator again - // all originally bonded stake has been slashed, so this will have no effect - // on the unbonding delegation, but it will slash stake bonded since the infraction - // this may not be the desirable behaviour, ref https://github.com/cosmos/cosmos-sdk/issues/1440 - ctx = ctx.WithBlockHeight(13) - keeper.Slash(ctx, consAddr, 9, 10, fraction) - - ubd, found = keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) - require.True(t, found) - require.Len(t, ubd.Entries, 1) - - // balance unchanged - require.Equal(t, sdk.NewInt(0), ubd.Entries[0].Balance) - - // just 1 bonded token burned again since that's all the validator now has - newBondedPoolBalances = keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) - diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(keeper.BondDenom(ctx)) - require.Equal(t, sdk.TokensFromConsensusPower(10), diffTokens) - - // apply TM updates - keeper.ApplyAndReturnValidatorSetUpdates(ctx) - - // read updated validator - // power decreased by 1 again, validator is out of stake - // validator should be in unbonding period - validator, _ = keeper.GetValidatorByConsAddr(ctx, consAddr) - require.Equal(t, validator.GetStatus(), sdk.Unbonding) -} - // tests Slash at a previous height with a redelegation func TestSlashWithRedelegation(t *testing.T) { ctx, keeper, _ := setupHelper(t, 10) diff --git a/x/staking/keeper/slash_test.go b/x/staking/keeper/slash_test.go index 7630824b99c5..f8fa6dfc89e6 100644 --- a/x/staking/keeper/slash_test.go +++ b/x/staking/keeper/slash_test.go @@ -4,6 +4,8 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "github.com/cosmos/cosmos-sdk/x/supply" abci "github.com/tendermint/tendermint/abci/types" @@ -15,12 +17,11 @@ import ( "github.com/stretchr/testify/require" ) -// initConfig creates 3 validators and bootstrap the app. -func initConfig(t *testing.T, power int64) (*simapp.SimApp, sdk.Context, []sdk.AccAddress, []sdk.ValAddress) { +// bootstrapSlashTest creates 3 validators and bootstrap the app. +func bootstrapSlashTest(t *testing.T, power int64) (*simapp.SimApp, sdk.Context, []sdk.AccAddress, []sdk.ValAddress) { _, app, ctx := getBaseSimappWithCustomKeeper() - addrDels := simapp.AddTestAddrsIncremental(app, ctx, 100, sdk.NewInt(10000)) - addrVals := simapp.ConvertAddrsToValAddrs(addrDels) + addrDels, addrVals := generateAddresses(app, ctx, 100) amt := sdk.TokensFromConsensusPower(power) totalSupply := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), amt.MulRaw(int64(len(addrDels))))) @@ -49,9 +50,17 @@ func initConfig(t *testing.T, power int64) (*simapp.SimApp, sdk.Context, []sdk.A return app, ctx, addrDels, addrVals } +// 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 +} + // tests Jail, Unjail func TestRevocation(t *testing.T) { - app, ctx, _, addrVals := initConfig(t, 5) + app, ctx, _, addrVals := bootstrapSlashTest(t, 5) consAddr := sdk.ConsAddress(PKs[0].Address()) @@ -75,7 +84,7 @@ func TestRevocation(t *testing.T) { // tests slashUnbondingDelegation func TestSlashUnbondingDelegation(t *testing.T) { - app, ctx, addrDels, addrVals := initConfig(t, 10) + app, ctx, addrDels, addrVals := bootstrapSlashTest(t, 10) fraction := sdk.NewDecWithPrec(5, 1) @@ -119,7 +128,7 @@ func TestSlashUnbondingDelegation(t *testing.T) { // tests slashRedelegation func TestSlashRedelegation(t *testing.T) { - app, ctx, addrDels, addrVals := initConfig(t, 10) + app, ctx, addrDels, addrVals := bootstrapSlashTest(t, 10) fraction := sdk.NewDecWithPrec(5, 1) // add bonded tokens to pool for (re)delegations @@ -187,7 +196,7 @@ func TestSlashRedelegation(t *testing.T) { // tests Slash at a future height (must panic) func TestSlashAtFutureHeight(t *testing.T) { - app, ctx, _, _ := initConfig(t, 10) + app, ctx, _, _ := bootstrapSlashTest(t, 10) consAddr := sdk.ConsAddress(PKs[0].Address()) fraction := sdk.NewDecWithPrec(5, 1) @@ -197,7 +206,7 @@ func TestSlashAtFutureHeight(t *testing.T) { // test slash at a negative height // this just represents pre-genesis and should have the same effect as slashing at height 0 func TestSlashAtNegativeHeight(t *testing.T) { - app, ctx, _, _ := initConfig(t, 10) + app, ctx, _, _ := bootstrapSlashTest(t, 10) consAddr := sdk.ConsAddress(PKs[0].Address()) fraction := sdk.NewDecWithPrec(5, 1) @@ -226,3 +235,163 @@ func TestSlashAtNegativeHeight(t *testing.T) { diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(app.StakingKeeper.BondDenom(ctx)) require.Equal(t, sdk.TokensFromConsensusPower(5).String(), diffTokens.String()) } + +// tests Slash at the current height +func TestSlashValidatorAtCurrentHeight(t *testing.T) { + app, ctx, _, _ := bootstrapSlashTest(t, 10) + consAddr := sdk.ConsAddress(PKs[0].Address()) + fraction := sdk.NewDecWithPrec(5, 1) + + bondedPool := app.StakingKeeper.GetBondedPool(ctx) + oldBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + + validator, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr) + require.True(t, found) + app.StakingKeeper.Slash(ctx, consAddr, ctx.BlockHeight(), 10, fraction) + + // read updated state + validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr) + require.True(t, found) + + // end block + updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 1, len(updates), "cons addr: %v, updates: %v", []byte(consAddr), updates) + + validator, found = app.StakingKeeper.GetValidator(ctx, validator.OperatorAddress) + assert.True(t, found) + // power decreased + require.Equal(t, int64(5), validator.GetConsensusPower()) + + // pool bonded shares decreased + newBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(app.StakingKeeper.BondDenom(ctx)) + require.Equal(t, sdk.TokensFromConsensusPower(5).String(), diffTokens.String()) +} + +// tests Slash at a previous height with an unbonding delegation +func TestSlashWithUnbondingDelegation(t *testing.T) { + app, ctx, addrDels, addrVals := bootstrapSlashTest(t, 10) + + consAddr := sdk.ConsAddress(PKs[0].Address()) + fraction := sdk.NewDecWithPrec(5, 1) + + // set an unbonding delegation with expiration timestamp beyond which the + // unbonding delegation shouldn't be slashed + ubdTokens := sdk.TokensFromConsensusPower(4) + ubd := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 11, + time.Unix(0, 0), ubdTokens) + app.StakingKeeper.SetUnbondingDelegation(ctx, ubd) + + // slash validator for the first time + ctx = ctx.WithBlockHeight(12) + bondedPool := app.StakingKeeper.GetBondedPool(ctx) + oldBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + + validator, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr) + require.True(t, found) + app.StakingKeeper.Slash(ctx, consAddr, 10, 10, fraction) + + // end block + updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 1, len(updates)) + + // read updating unbonding delegation + ubd, found = app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) + require.True(t, found) + require.Len(t, ubd.Entries, 1) + + // balance decreased + require.Equal(t, sdk.TokensFromConsensusPower(2), ubd.Entries[0].Balance) + + // bonded tokens burned + newBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + diffTokens := oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(app.StakingKeeper.BondDenom(ctx)) + require.Equal(t, sdk.TokensFromConsensusPower(3), diffTokens) + + // read updated validator + validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr) + require.True(t, found) + + // power decreased by 3 - 6 stake originally bonded at the time of infraction + // was still bonded at the time of discovery and was slashed by half, 4 stake + // bonded at the time of discovery hadn't been bonded at the time of infraction + // and wasn't slashed + require.Equal(t, int64(7), validator.GetConsensusPower()) + + // slash validator again + ctx = ctx.WithBlockHeight(13) + app.StakingKeeper.Slash(ctx, consAddr, 9, 10, fraction) + + ubd, found = app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) + require.True(t, found) + require.Len(t, ubd.Entries, 1) + + // balance decreased again + require.Equal(t, sdk.NewInt(0), ubd.Entries[0].Balance) + + // bonded tokens burned again + newBondedPoolBalances = app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(app.StakingKeeper.BondDenom(ctx)) + require.Equal(t, sdk.TokensFromConsensusPower(6), diffTokens) + + // read updated validator + validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr) + require.True(t, found) + + // power decreased by 3 again + require.Equal(t, int64(4), validator.GetConsensusPower()) + + // slash validator again + // all originally bonded stake has been slashed, so this will have no effect + // on the unbonding delegation, but it will slash stake bonded since the infraction + // this may not be the desirable behaviour, ref https://github.com/cosmos/cosmos-sdk/issues/1440 + ctx = ctx.WithBlockHeight(13) + app.StakingKeeper.Slash(ctx, consAddr, 9, 10, fraction) + + ubd, found = app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) + require.True(t, found) + require.Len(t, ubd.Entries, 1) + + // balance unchanged + require.Equal(t, sdk.NewInt(0), ubd.Entries[0].Balance) + + // bonded tokens burned again + newBondedPoolBalances = app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(app.StakingKeeper.BondDenom(ctx)) + require.Equal(t, sdk.TokensFromConsensusPower(9), diffTokens) + + // read updated validator + validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr) + require.True(t, found) + + // power decreased by 3 again + require.Equal(t, int64(1), validator.GetConsensusPower()) + + // slash validator again + // all originally bonded stake has been slashed, so this will have no effect + // on the unbonding delegation, but it will slash stake bonded since the infraction + // this may not be the desirable behaviour, ref https://github.com/cosmos/cosmos-sdk/issues/1440 + ctx = ctx.WithBlockHeight(13) + app.StakingKeeper.Slash(ctx, consAddr, 9, 10, fraction) + + ubd, found = app.StakingKeeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) + require.True(t, found) + require.Len(t, ubd.Entries, 1) + + // balance unchanged + require.Equal(t, sdk.NewInt(0), ubd.Entries[0].Balance) + + // just 1 bonded token burned again since that's all the validator now has + newBondedPoolBalances = app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + diffTokens = oldBondedPoolBalances.Sub(newBondedPoolBalances).AmountOf(app.StakingKeeper.BondDenom(ctx)) + require.Equal(t, sdk.TokensFromConsensusPower(10), diffTokens) + + // apply TM updates + app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + + // read updated validator + // power decreased by 1 again, validator is out of stake + // validator should be in unbonding period + validator, _ = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr) + require.Equal(t, validator.GetStatus(), sdk.Unbonding) +} From 15eaa129ee6adc2ed7522bb8608b665c9669003c Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Tue, 25 Feb 2020 10:24:58 +0100 Subject: [PATCH 39/90] refactor TestSlashWithRedelegation --- x/staking/keeper/old_slash_test.go | 156 ----------------------------- x/staking/keeper/slash_test.go | 156 +++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+), 156 deletions(-) diff --git a/x/staking/keeper/old_slash_test.go b/x/staking/keeper/old_slash_test.go index a0c302c0ba68..a5e253804e44 100644 --- a/x/staking/keeper/old_slash_test.go +++ b/x/staking/keeper/old_slash_test.go @@ -35,162 +35,6 @@ func setupHelper(t *testing.T, power int64) (sdk.Context, Keeper, types.Params) return ctx, keeper, params } -//_________________________________________________________________________________ -// tests Slash at a previous height with a redelegation -func TestSlashWithRedelegation(t *testing.T) { - ctx, keeper, _ := setupHelper(t, 10) - consAddr := sdk.ConsAddress(PKs[0].Address()) - fraction := sdk.NewDecWithPrec(5, 1) - bondDenom := keeper.BondDenom(ctx) - - // set a redelegation - rdTokens := sdk.TokensFromConsensusPower(6) - rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 11, - time.Unix(0, 0), rdTokens, rdTokens.ToDec()) - keeper.SetRedelegation(ctx, rd) - - // set the associated delegation - del := types.NewDelegation(addrDels[0], addrVals[1], rdTokens.ToDec()) - keeper.SetDelegation(ctx, del) - - // update bonded tokens - bondedPool := keeper.GetBondedPool(ctx) - notBondedPool := keeper.GetNotBondedPool(ctx) - rdCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, rdTokens.MulRaw(2))) - - balances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) - err := keeper.bankKeeper.SetBalances(ctx, bondedPool.GetAddress(), balances.Add(rdCoins...)) - require.NoError(t, err) - - keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) - - oldBonded := keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount - oldNotBonded := keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount - - // slash validator - ctx = ctx.WithBlockHeight(12) - validator, found := keeper.GetValidatorByConsAddr(ctx, consAddr) - require.True(t, found) - - require.NotPanics(t, func() { keeper.Slash(ctx, consAddr, 10, 10, fraction) }) - burnAmount := sdk.TokensFromConsensusPower(10).ToDec().Mul(fraction).TruncateInt() - - bondedPool = keeper.GetBondedPool(ctx) - notBondedPool = keeper.GetNotBondedPool(ctx) - - // burn bonded tokens from only from delegations - bondedPoolBalance := keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount - require.True(sdk.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance)) - - notBondedPoolBalance := keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount - require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance)) - oldBonded = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount - - // read updating redelegation - rd, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) - require.True(t, found) - require.Len(t, rd.Entries, 1) - // read updated validator - validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr) - require.True(t, found) - // power decreased by 2 - 4 stake originally bonded at the time of infraction - // was still bonded at the time of discovery and was slashed by half, 4 stake - // bonded at the time of discovery hadn't been bonded at the time of infraction - // and wasn't slashed - require.Equal(t, int64(8), validator.GetConsensusPower()) - - // slash the validator again - validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr) - require.True(t, found) - - require.NotPanics(t, func() { keeper.Slash(ctx, consAddr, 10, 10, sdk.OneDec()) }) - burnAmount = sdk.TokensFromConsensusPower(7) - - // read updated pool - bondedPool = keeper.GetBondedPool(ctx) - notBondedPool = keeper.GetNotBondedPool(ctx) - - // seven bonded tokens burned - bondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount - require.True(sdk.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance)) - require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance)) - - bondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount - require.True(sdk.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance)) - - notBondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount - require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance)) - oldBonded = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount - - // read updating redelegation - rd, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) - require.True(t, found) - require.Len(t, rd.Entries, 1) - // read updated validator - validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr) - require.True(t, found) - // power decreased by 4 - require.Equal(t, int64(4), validator.GetConsensusPower()) - - // slash the validator again, by 100% - ctx = ctx.WithBlockHeight(12) - validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr) - require.True(t, found) - - require.NotPanics(t, func() { keeper.Slash(ctx, consAddr, 10, 10, sdk.OneDec()) }) - - burnAmount = sdk.TokensFromConsensusPower(10).ToDec().Mul(sdk.OneDec()).TruncateInt() - burnAmount = burnAmount.Sub(sdk.OneDec().MulInt(rdTokens).TruncateInt()) - - // read updated pool - bondedPool = keeper.GetBondedPool(ctx) - notBondedPool = keeper.GetNotBondedPool(ctx) - - bondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount - require.True(sdk.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance)) - notBondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount - require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance)) - oldBonded = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount - - // read updating redelegation - rd, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) - require.True(t, found) - require.Len(t, rd.Entries, 1) - // apply TM updates - keeper.ApplyAndReturnValidatorSetUpdates(ctx) - // read updated validator - // validator decreased to zero power, should be in unbonding period - validator, _ = keeper.GetValidatorByConsAddr(ctx, consAddr) - require.Equal(t, validator.GetStatus(), sdk.Unbonding) - - // slash the validator again, by 100% - // no stake remains to be slashed - ctx = ctx.WithBlockHeight(12) - // validator still in unbonding period - validator, _ = keeper.GetValidatorByConsAddr(ctx, consAddr) - require.Equal(t, validator.GetStatus(), sdk.Unbonding) - - require.NotPanics(t, func() { keeper.Slash(ctx, consAddr, 10, 10, sdk.OneDec()) }) - - // read updated pool - bondedPool = keeper.GetBondedPool(ctx) - notBondedPool = keeper.GetNotBondedPool(ctx) - - bondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount - require.True(sdk.IntEq(t, oldBonded, bondedPoolBalance)) - notBondedPoolBalance = keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount - require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance)) - - // read updating redelegation - rd, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) - require.True(t, found) - require.Len(t, rd.Entries, 1) - // read updated validator - // power still zero, still in unbonding period - validator, _ = keeper.GetValidatorByConsAddr(ctx, consAddr) - require.Equal(t, validator.GetStatus(), sdk.Unbonding) -} - // tests Slash at a previous height with both an unbonding delegation and a redelegation func TestSlashBoth(t *testing.T) { ctx, keeper, _ := setupHelper(t, 10) diff --git a/x/staking/keeper/slash_test.go b/x/staking/keeper/slash_test.go index f8fa6dfc89e6..19b91a1f698f 100644 --- a/x/staking/keeper/slash_test.go +++ b/x/staking/keeper/slash_test.go @@ -395,3 +395,159 @@ func TestSlashWithUnbondingDelegation(t *testing.T) { validator, _ = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr) require.Equal(t, validator.GetStatus(), sdk.Unbonding) } + +//_________________________________________________________________________________ +// tests Slash at a previous height with a redelegation +func TestSlashWithRedelegation(t *testing.T) { + app, ctx, addrDels, addrVals := bootstrapSlashTest(t, 10) + consAddr := sdk.ConsAddress(PKs[0].Address()) + fraction := sdk.NewDecWithPrec(5, 1) + bondDenom := app.StakingKeeper.BondDenom(ctx) + + // set a redelegation + rdTokens := sdk.TokensFromConsensusPower(6) + rd := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 11, + time.Unix(0, 0), rdTokens, rdTokens.ToDec()) + app.StakingKeeper.SetRedelegation(ctx, rd) + + // set the associated delegation + del := types.NewDelegation(addrDels[0], addrVals[1], rdTokens.ToDec()) + app.StakingKeeper.SetDelegation(ctx, del) + + // update bonded tokens + bondedPool := app.StakingKeeper.GetBondedPool(ctx) + notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) + rdCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, rdTokens.MulRaw(2))) + + balances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + err := app.BankKeeper.SetBalances(ctx, bondedPool.GetAddress(), balances.Add(rdCoins...)) + require.NoError(t, err) + + app.SupplyKeeper.SetModuleAccount(ctx, bondedPool) + + oldBonded := app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount + oldNotBonded := app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount + + // slash validator + ctx = ctx.WithBlockHeight(12) + validator, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr) + require.True(t, found) + + require.NotPanics(t, func() { app.StakingKeeper.Slash(ctx, consAddr, 10, 10, fraction) }) + burnAmount := sdk.TokensFromConsensusPower(10).ToDec().Mul(fraction).TruncateInt() + + bondedPool = app.StakingKeeper.GetBondedPool(ctx) + notBondedPool = app.StakingKeeper.GetNotBondedPool(ctx) + + // burn bonded tokens from only from delegations + bondedPoolBalance := app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount + require.True(sdk.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance)) + + notBondedPoolBalance := app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount + require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance)) + oldBonded = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount + + // read updating redelegation + rd, found = app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) + require.True(t, found) + require.Len(t, rd.Entries, 1) + // read updated validator + validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr) + require.True(t, found) + // power decreased by 2 - 4 stake originally bonded at the time of infraction + // was still bonded at the time of discovery and was slashed by half, 4 stake + // bonded at the time of discovery hadn't been bonded at the time of infraction + // and wasn't slashed + require.Equal(t, int64(8), validator.GetConsensusPower()) + + // slash the validator again + validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr) + require.True(t, found) + + require.NotPanics(t, func() { app.StakingKeeper.Slash(ctx, consAddr, 10, 10, sdk.OneDec()) }) + burnAmount = sdk.TokensFromConsensusPower(7) + + // read updated pool + bondedPool = app.StakingKeeper.GetBondedPool(ctx) + notBondedPool = app.StakingKeeper.GetNotBondedPool(ctx) + + // seven bonded tokens burned + bondedPoolBalance = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount + require.True(sdk.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance)) + require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance)) + + bondedPoolBalance = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount + require.True(sdk.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance)) + + notBondedPoolBalance = app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount + require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance)) + oldBonded = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount + + // read updating redelegation + rd, found = app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) + require.True(t, found) + require.Len(t, rd.Entries, 1) + // read updated validator + validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr) + require.True(t, found) + // power decreased by 4 + require.Equal(t, int64(4), validator.GetConsensusPower()) + + // slash the validator again, by 100% + ctx = ctx.WithBlockHeight(12) + validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr) + require.True(t, found) + + require.NotPanics(t, func() { app.StakingKeeper.Slash(ctx, consAddr, 10, 10, sdk.OneDec()) }) + + burnAmount = sdk.TokensFromConsensusPower(10).ToDec().Mul(sdk.OneDec()).TruncateInt() + burnAmount = burnAmount.Sub(sdk.OneDec().MulInt(rdTokens).TruncateInt()) + + // read updated pool + bondedPool = app.StakingKeeper.GetBondedPool(ctx) + notBondedPool = app.StakingKeeper.GetNotBondedPool(ctx) + + bondedPoolBalance = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount + require.True(sdk.IntEq(t, oldBonded.Sub(burnAmount), bondedPoolBalance)) + notBondedPoolBalance = app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount + require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance)) + oldBonded = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount + + // read updating redelegation + rd, found = app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) + require.True(t, found) + require.Len(t, rd.Entries, 1) + // apply TM updates + app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + // read updated validator + // validator decreased to zero power, should be in unbonding period + validator, _ = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr) + require.Equal(t, validator.GetStatus(), sdk.Unbonding) + + // slash the validator again, by 100% + // no stake remains to be slashed + ctx = ctx.WithBlockHeight(12) + // validator still in unbonding period + validator, _ = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr) + require.Equal(t, validator.GetStatus(), sdk.Unbonding) + + require.NotPanics(t, func() { app.StakingKeeper.Slash(ctx, consAddr, 10, 10, sdk.OneDec()) }) + + // read updated pool + bondedPool = app.StakingKeeper.GetBondedPool(ctx) + notBondedPool = app.StakingKeeper.GetNotBondedPool(ctx) + + bondedPoolBalance = app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount + require.True(sdk.IntEq(t, oldBonded, bondedPoolBalance)) + notBondedPoolBalance = app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount + require.True(sdk.IntEq(t, oldNotBonded, notBondedPoolBalance)) + + // read updating redelegation + rd, found = app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) + require.True(t, found) + require.Len(t, rd.Entries, 1) + // read updated validator + // power still zero, still in unbonding period + validator, _ = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr) + require.Equal(t, validator.GetStatus(), sdk.Unbonding) +} From 0cddd4fff6a33a6da413b21e86073579d5c03cdd Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Tue, 25 Feb 2020 10:32:53 +0100 Subject: [PATCH 40/90] end refactoring slash_test --- x/staking/keeper/old_slash_test.go | 111 ----------------------------- x/staking/keeper/slash_test.go | 75 +++++++++++++++++++ 2 files changed, 75 insertions(+), 111 deletions(-) delete mode 100644 x/staking/keeper/old_slash_test.go diff --git a/x/staking/keeper/old_slash_test.go b/x/staking/keeper/old_slash_test.go deleted file mode 100644 index a5e253804e44..000000000000 --- a/x/staking/keeper/old_slash_test.go +++ /dev/null @@ -1,111 +0,0 @@ -package keeper - -import ( - "testing" - "time" - - "github.com/stretchr/testify/require" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/staking/types" -) - -// TODO integrate with test_common.go helper (CreateTestInput) -// setup helper function - creates two validators -func setupHelper(t *testing.T, power int64) (sdk.Context, Keeper, types.Params) { - // setup - ctx, _, _, keeper, _ := CreateTestInput(t, false, power) - params := keeper.GetParams(ctx) - numVals := int64(3) - amt := sdk.TokensFromConsensusPower(power) - bondedCoins := sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), amt.MulRaw(numVals))) - - bondedPool := keeper.GetBondedPool(ctx) - require.NoError(t, keeper.bankKeeper.SetBalances(ctx, bondedPool.GetAddress(), bondedCoins)) - keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) - - // add numVals validators - for i := int64(0); i < numVals; i++ { - validator := types.NewValidator(addrVals[i], PKs[i], types.Description{}) - validator, _ = validator.AddTokensFromDel(amt) - validator = TestingUpdateValidator(keeper, ctx, validator, true) - keeper.SetValidatorByConsAddr(ctx, validator) - } - - return ctx, keeper, params -} - -// tests Slash at a previous height with both an unbonding delegation and a redelegation -func TestSlashBoth(t *testing.T) { - ctx, keeper, _ := setupHelper(t, 10) - fraction := sdk.NewDecWithPrec(5, 1) - bondDenom := keeper.BondDenom(ctx) - - // set a redelegation with expiration timestamp beyond which the - // redelegation shouldn't be slashed - rdATokens := sdk.TokensFromConsensusPower(6) - rdA := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 11, - time.Unix(0, 0), rdATokens, - rdATokens.ToDec()) - keeper.SetRedelegation(ctx, rdA) - - // set the associated delegation - delA := types.NewDelegation(addrDels[0], addrVals[1], rdATokens.ToDec()) - keeper.SetDelegation(ctx, delA) - - // set an unbonding delegation with expiration timestamp (beyond which the - // unbonding delegation shouldn't be slashed) - ubdATokens := sdk.TokensFromConsensusPower(4) - ubdA := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 11, - time.Unix(0, 0), ubdATokens) - keeper.SetUnbondingDelegation(ctx, ubdA) - - bondedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, rdATokens.MulRaw(2))) - notBondedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, ubdATokens)) - - // update bonded tokens - bondedPool := keeper.GetBondedPool(ctx) - notBondedPool := keeper.GetNotBondedPool(ctx) - - bondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) - require.NoError(t, keeper.bankKeeper.SetBalances(ctx, bondedPool.GetAddress(), bondedPoolBalances.Add(bondedCoins...))) - - notBondedPoolBalances := keeper.bankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress()) - require.NoError(t, keeper.bankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), notBondedPoolBalances.Add(notBondedCoins...))) - - keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - oldBonded := keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount - oldNotBonded := keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount - // slash validator - ctx = ctx.WithBlockHeight(12) - validator, found := keeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(PKs[0])) - require.True(t, found) - consAddr0 := sdk.ConsAddress(PKs[0].Address()) - keeper.Slash(ctx, consAddr0, 10, 10, fraction) - - burnedNotBondedAmount := fraction.MulInt(ubdATokens).TruncateInt() - burnedBondAmount := sdk.TokensFromConsensusPower(10).ToDec().Mul(fraction).TruncateInt() - burnedBondAmount = burnedBondAmount.Sub(burnedNotBondedAmount) - - // read updated pool - bondedPool = keeper.GetBondedPool(ctx) - notBondedPool = keeper.GetNotBondedPool(ctx) - - bondedPoolBalance := keeper.bankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount - require.True(sdk.IntEq(t, oldBonded.Sub(burnedBondAmount), bondedPoolBalance)) - - notBondedPoolBalance := keeper.bankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount - require.True(sdk.IntEq(t, oldNotBonded.Sub(burnedNotBondedAmount), notBondedPoolBalance)) - - // read updating redelegation - rdA, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) - require.True(t, found) - require.Len(t, rdA.Entries, 1) - // read updated validator - validator, found = keeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(PKs[0])) - require.True(t, found) - // power not decreased, all stake was bonded since - require.Equal(t, int64(10), validator.GetConsensusPower()) -} diff --git a/x/staking/keeper/slash_test.go b/x/staking/keeper/slash_test.go index 19b91a1f698f..77296c19725e 100644 --- a/x/staking/keeper/slash_test.go +++ b/x/staking/keeper/slash_test.go @@ -551,3 +551,78 @@ func TestSlashWithRedelegation(t *testing.T) { validator, _ = app.StakingKeeper.GetValidatorByConsAddr(ctx, consAddr) require.Equal(t, validator.GetStatus(), sdk.Unbonding) } + +// tests Slash at a previous height with both an unbonding delegation and a redelegation +func TestSlashBoth(t *testing.T) { + app, ctx, addrDels, addrVals := bootstrapSlashTest(t, 10) + fraction := sdk.NewDecWithPrec(5, 1) + bondDenom := app.StakingKeeper.BondDenom(ctx) + + // set a redelegation with expiration timestamp beyond which the + // redelegation shouldn't be slashed + rdATokens := sdk.TokensFromConsensusPower(6) + rdA := types.NewRedelegation(addrDels[0], addrVals[0], addrVals[1], 11, + time.Unix(0, 0), rdATokens, + rdATokens.ToDec()) + app.StakingKeeper.SetRedelegation(ctx, rdA) + + // set the associated delegation + delA := types.NewDelegation(addrDels[0], addrVals[1], rdATokens.ToDec()) + app.StakingKeeper.SetDelegation(ctx, delA) + + // set an unbonding delegation with expiration timestamp (beyond which the + // unbonding delegation shouldn't be slashed) + ubdATokens := sdk.TokensFromConsensusPower(4) + ubdA := types.NewUnbondingDelegation(addrDels[0], addrVals[0], 11, + time.Unix(0, 0), ubdATokens) + app.StakingKeeper.SetUnbondingDelegation(ctx, ubdA) + + bondedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, rdATokens.MulRaw(2))) + notBondedCoins := sdk.NewCoins(sdk.NewCoin(bondDenom, ubdATokens)) + + // update bonded tokens + bondedPool := app.StakingKeeper.GetBondedPool(ctx) + notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) + + bondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + require.NoError(t, app.BankKeeper.SetBalances(ctx, bondedPool.GetAddress(), bondedPoolBalances.Add(bondedCoins...))) + + notBondedPoolBalances := app.BankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress()) + require.NoError(t, app.BankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), notBondedPoolBalances.Add(notBondedCoins...))) + + app.SupplyKeeper.SetModuleAccount(ctx, bondedPool) + app.SupplyKeeper.SetModuleAccount(ctx, notBondedPool) + + oldBonded := app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount + oldNotBonded := app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount + // slash validator + ctx = ctx.WithBlockHeight(12) + validator, found := app.StakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(PKs[0])) + require.True(t, found) + consAddr0 := sdk.ConsAddress(PKs[0].Address()) + app.StakingKeeper.Slash(ctx, consAddr0, 10, 10, fraction) + + burnedNotBondedAmount := fraction.MulInt(ubdATokens).TruncateInt() + burnedBondAmount := sdk.TokensFromConsensusPower(10).ToDec().Mul(fraction).TruncateInt() + burnedBondAmount = burnedBondAmount.Sub(burnedNotBondedAmount) + + // read updated pool + bondedPool = app.StakingKeeper.GetBondedPool(ctx) + notBondedPool = app.StakingKeeper.GetNotBondedPool(ctx) + + bondedPoolBalance := app.BankKeeper.GetBalance(ctx, bondedPool.GetAddress(), bondDenom).Amount + require.True(sdk.IntEq(t, oldBonded.Sub(burnedBondAmount), bondedPoolBalance)) + + notBondedPoolBalance := app.BankKeeper.GetBalance(ctx, notBondedPool.GetAddress(), bondDenom).Amount + require.True(sdk.IntEq(t, oldNotBonded.Sub(burnedNotBondedAmount), notBondedPoolBalance)) + + // read updating redelegation + rdA, found = app.StakingKeeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) + require.True(t, found) + require.Len(t, rdA.Entries, 1) + // read updated validator + validator, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(PKs[0])) + require.True(t, found) + // power not decreased, all stake was bonded since + require.Equal(t, int64(10), validator.GetConsensusPower()) +} From 66abd1f19f8587ecc00144de15b1626b65fb1c12 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Tue, 25 Feb 2020 11:43:51 +0100 Subject: [PATCH 41/90] refactor first test validation to simapp --- x/staking/keeper/old_validator_test.go | 1039 +++++++++++++++++++++++ x/staking/keeper/slash_test.go | 8 - x/staking/keeper/test_common_test.go | 16 + x/staking/keeper/validator_test.go | 1073 +----------------------- 4 files changed, 1086 insertions(+), 1050 deletions(-) create mode 100644 x/staking/keeper/old_validator_test.go diff --git a/x/staking/keeper/old_validator_test.go b/x/staking/keeper/old_validator_test.go new file mode 100644 index 000000000000..c5101a3c145b --- /dev/null +++ b/x/staking/keeper/old_validator_test.go @@ -0,0 +1,1039 @@ +package keeper + +import ( + "fmt" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + abci "github.com/tendermint/tendermint/abci/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/staking/types" +) + +func TestUpdateValidatorByPowerIndex(t *testing.T) { + ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) + + bondedPool := keeper.GetBondedPool(ctx) + notBondedPool := keeper.GetNotBondedPool(ctx) + bk.SetBalances(ctx, bondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), sdk.TokensFromConsensusPower(1234)))) + bk.SetBalances(ctx, notBondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), sdk.TokensFromConsensusPower(10000)))) + keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) + keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) + + // add a validator + validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) + validator, delSharesCreated := validator.AddTokensFromDel(sdk.TokensFromConsensusPower(100)) + require.Equal(t, sdk.Unbonded, validator.Status) + require.Equal(t, sdk.TokensFromConsensusPower(100), validator.Tokens) + TestingUpdateValidator(keeper, ctx, validator, true) + validator, found := keeper.GetValidator(ctx, addrVals[0]) + require.True(t, found) + require.Equal(t, sdk.TokensFromConsensusPower(100), validator.Tokens) + + power := types.GetValidatorsByPowerIndexKey(validator) + require.True(t, validatorByPowerIndexExists(keeper, ctx, power)) + + // burn half the delegator shares + keeper.DeleteValidatorByPowerIndex(ctx, validator) + validator, burned := validator.RemoveDelShares(delSharesCreated.Quo(sdk.NewDec(2))) + require.Equal(t, sdk.TokensFromConsensusPower(50), burned) + TestingUpdateValidator(keeper, ctx, validator, true) // update the validator, possibly kicking it out + require.False(t, validatorByPowerIndexExists(keeper, ctx, power)) + + validator, found = keeper.GetValidator(ctx, addrVals[0]) + require.True(t, found) + + power = types.GetValidatorsByPowerIndexKey(validator) + require.True(t, validatorByPowerIndexExists(keeper, ctx, power)) +} + +func TestUpdateBondedValidatorsDecreaseCliff(t *testing.T) { + numVals := 10 + maxVals := 5 + + // create context, keeper, and pool for tests + ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) + bondedPool := keeper.GetBondedPool(ctx) + notBondedPool := keeper.GetNotBondedPool(ctx) + + // create keeper parameters + params := keeper.GetParams(ctx) + params.MaxValidators = uint32(maxVals) + keeper.SetParams(ctx, params) + + // create a random pool + bk.SetBalances(ctx, bondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), sdk.TokensFromConsensusPower(1234)))) + bk.SetBalances(ctx, notBondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), sdk.TokensFromConsensusPower(10000)))) + keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) + keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) + + validators := make([]types.Validator, numVals) + for i := 0; i < len(validators); i++ { + moniker := fmt.Sprintf("val#%d", int64(i)) + val := types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{Moniker: moniker}) + delTokens := sdk.TokensFromConsensusPower(int64((i + 1) * 10)) + val, _ = val.AddTokensFromDel(delTokens) + + val = TestingUpdateValidator(keeper, ctx, val, true) + validators[i] = val + } + + nextCliffVal := validators[numVals-maxVals+1] + + // remove enough tokens to kick out the validator below the current cliff + // validator and next in line cliff validator + keeper.DeleteValidatorByPowerIndex(ctx, nextCliffVal) + shares := sdk.TokensFromConsensusPower(21) + nextCliffVal, _ = nextCliffVal.RemoveDelShares(shares.ToDec()) + nextCliffVal = TestingUpdateValidator(keeper, ctx, nextCliffVal, true) + + expectedValStatus := map[int]sdk.BondStatus{ + 9: sdk.Bonded, 8: sdk.Bonded, 7: sdk.Bonded, 5: sdk.Bonded, 4: sdk.Bonded, + 0: sdk.Unbonding, 1: sdk.Unbonding, 2: sdk.Unbonding, 3: sdk.Unbonding, 6: sdk.Unbonding, + } + + // require all the validators have their respective statuses + for valIdx, status := range expectedValStatus { + valAddr := validators[valIdx].OperatorAddress + val, _ := keeper.GetValidator(ctx, valAddr) + + assert.Equal( + t, status, val.GetStatus(), + fmt.Sprintf("expected validator at index %v to have status: %s", valIdx, status), + ) + } +} + +func TestSlashToZeroPowerRemoved(t *testing.T) { + // initialize setup + ctx, _, bk, keeper, _ := CreateTestInput(t, false, 100) + + // add a validator + validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) + valTokens := sdk.TokensFromConsensusPower(100) + + bondedPool := keeper.GetBondedPool(ctx) + err := bk.SetBalances(ctx, bondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), valTokens))) + require.NoError(t, err) + keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) + + validator, _ = validator.AddTokensFromDel(valTokens) + require.Equal(t, sdk.Unbonded, validator.Status) + require.Equal(t, valTokens, validator.Tokens) + keeper.SetValidatorByConsAddr(ctx, validator) + validator = TestingUpdateValidator(keeper, ctx, validator, true) + require.Equal(t, valTokens, validator.Tokens, "\nvalidator %v\npool %v", validator, valTokens) + + // slash the validator by 100% + consAddr0 := sdk.ConsAddress(PKs[0].Address()) + keeper.Slash(ctx, consAddr0, 0, 100, sdk.OneDec()) + // apply TM updates + keeper.ApplyAndReturnValidatorSetUpdates(ctx) + // validator should be unbonding + validator, _ = keeper.GetValidator(ctx, addrVals[0]) + require.Equal(t, validator.GetStatus(), sdk.Unbonding) +} + +// This function tests UpdateValidator, GetValidator, GetLastValidators, RemoveValidator +func TestValidatorBasics(t *testing.T) { + ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) + + //construct the validators + var validators [3]types.Validator + powers := []int64{9, 8, 7} + for i, power := range powers { + validators[i] = types.NewValidator(addrVals[i], PKs[i], types.Description{}) + validators[i].Status = sdk.Unbonded + validators[i].Tokens = sdk.ZeroInt() + tokens := sdk.TokensFromConsensusPower(power) + + validators[i], _ = validators[i].AddTokensFromDel(tokens) + } + assert.Equal(t, sdk.TokensFromConsensusPower(9), validators[0].Tokens) + assert.Equal(t, sdk.TokensFromConsensusPower(8), validators[1].Tokens) + assert.Equal(t, sdk.TokensFromConsensusPower(7), validators[2].Tokens) + + // check the empty keeper first + _, found := keeper.GetValidator(ctx, addrVals[0]) + require.False(t, found) + resVals := keeper.GetLastValidators(ctx) + require.Zero(t, len(resVals)) + + resVals = keeper.GetValidators(ctx, 2) + require.Zero(t, len(resVals)) + + // set and retrieve a record + validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], true) + keeper.SetValidatorByConsAddr(ctx, validators[0]) + resVal, found := keeper.GetValidator(ctx, addrVals[0]) + require.True(t, found) + assert.True(ValEq(t, validators[0], resVal)) + + // retrieve from consensus + resVal, found = keeper.GetValidatorByConsAddr(ctx, sdk.ConsAddress(PKs[0].Address())) + require.True(t, found) + assert.True(ValEq(t, validators[0], resVal)) + resVal, found = keeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(PKs[0])) + require.True(t, found) + assert.True(ValEq(t, validators[0], resVal)) + + resVals = keeper.GetLastValidators(ctx) + require.Equal(t, 1, len(resVals)) + assert.True(ValEq(t, validators[0], resVals[0])) + assert.Equal(t, sdk.Bonded, validators[0].Status) + assert.True(sdk.IntEq(t, sdk.TokensFromConsensusPower(9), validators[0].BondedTokens())) + + // modify a records, save, and retrieve + validators[0].Status = sdk.Bonded + validators[0].Tokens = sdk.TokensFromConsensusPower(10) + validators[0].DelegatorShares = validators[0].Tokens.ToDec() + validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], true) + resVal, found = keeper.GetValidator(ctx, addrVals[0]) + require.True(t, found) + assert.True(ValEq(t, validators[0], resVal)) + + resVals = keeper.GetLastValidators(ctx) + require.Equal(t, 1, len(resVals)) + assert.True(ValEq(t, validators[0], resVals[0])) + + // add other validators + validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], true) + validators[2] = TestingUpdateValidator(keeper, ctx, validators[2], true) + resVal, found = keeper.GetValidator(ctx, addrVals[1]) + require.True(t, found) + assert.True(ValEq(t, validators[1], resVal)) + resVal, found = keeper.GetValidator(ctx, addrVals[2]) + require.True(t, found) + assert.True(ValEq(t, validators[2], resVal)) + + resVals = keeper.GetLastValidators(ctx) + require.Equal(t, 3, len(resVals)) + assert.True(ValEq(t, validators[0], resVals[0])) // order doesn't matter here + assert.True(ValEq(t, validators[1], resVals[1])) + assert.True(ValEq(t, validators[2], resVals[2])) + + // remove a record + + // shouldn't be able to remove if status is not unbonded + assert.PanicsWithValue(t, + "cannot call RemoveValidator on bonded or unbonding validators", + func() { keeper.RemoveValidator(ctx, validators[1].OperatorAddress) }) + + // shouldn't be able to remove if there are still tokens left + validators[1].Status = sdk.Unbonded + keeper.SetValidator(ctx, validators[1]) + assert.PanicsWithValue(t, + "attempting to remove a validator which still contains tokens", + func() { keeper.RemoveValidator(ctx, validators[1].OperatorAddress) }) + + validators[1].Tokens = sdk.ZeroInt() // ...remove all tokens + keeper.SetValidator(ctx, validators[1]) // ...set the validator + keeper.RemoveValidator(ctx, validators[1].OperatorAddress) // Now it can be removed. + _, found = keeper.GetValidator(ctx, addrVals[1]) + require.False(t, found) +} + +// test how the validators are sorted, tests GetBondedValidatorsByPower +func TestGetValidatorSortingUnmixed(t *testing.T) { + ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) + + // initialize some validators into the state + amts := []int64{ + 0, + 100 * sdk.PowerReduction.Int64(), + 1 * sdk.PowerReduction.Int64(), + 400 * sdk.PowerReduction.Int64(), + 200 * sdk.PowerReduction.Int64()} + n := len(amts) + var validators [5]types.Validator + for i, amt := range amts { + validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) + validators[i].Status = sdk.Bonded + validators[i].Tokens = sdk.NewInt(amt) + validators[i].DelegatorShares = sdk.NewDec(amt) + TestingUpdateValidator(keeper, ctx, validators[i], true) + } + + // first make sure everything made it in to the gotValidator group + resValidators := keeper.GetBondedValidatorsByPower(ctx) + assert.Equal(t, n, len(resValidators)) + assert.Equal(t, sdk.NewInt(400).Mul(sdk.PowerReduction), resValidators[0].BondedTokens(), "%v", resValidators) + assert.Equal(t, sdk.NewInt(200).Mul(sdk.PowerReduction), resValidators[1].BondedTokens(), "%v", resValidators) + assert.Equal(t, sdk.NewInt(100).Mul(sdk.PowerReduction), resValidators[2].BondedTokens(), "%v", resValidators) + assert.Equal(t, sdk.NewInt(1).Mul(sdk.PowerReduction), resValidators[3].BondedTokens(), "%v", resValidators) + assert.Equal(t, sdk.NewInt(0), resValidators[4].BondedTokens(), "%v", resValidators) + assert.Equal(t, validators[3].OperatorAddress, resValidators[0].OperatorAddress, "%v", resValidators) + assert.Equal(t, validators[4].OperatorAddress, resValidators[1].OperatorAddress, "%v", resValidators) + assert.Equal(t, validators[1].OperatorAddress, resValidators[2].OperatorAddress, "%v", resValidators) + assert.Equal(t, validators[2].OperatorAddress, resValidators[3].OperatorAddress, "%v", resValidators) + assert.Equal(t, validators[0].OperatorAddress, resValidators[4].OperatorAddress, "%v", resValidators) + + // test a basic increase in voting power + validators[3].Tokens = sdk.NewInt(500).Mul(sdk.PowerReduction) + TestingUpdateValidator(keeper, ctx, validators[3], true) + resValidators = keeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, len(resValidators), n) + assert.True(ValEq(t, validators[3], resValidators[0])) + + // test a decrease in voting power + validators[3].Tokens = sdk.NewInt(300).Mul(sdk.PowerReduction) + TestingUpdateValidator(keeper, ctx, validators[3], true) + resValidators = keeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, len(resValidators), n) + assert.True(ValEq(t, validators[3], resValidators[0])) + assert.True(ValEq(t, validators[4], resValidators[1])) + + // test equal voting power, different age + validators[3].Tokens = sdk.NewInt(200).Mul(sdk.PowerReduction) + ctx = ctx.WithBlockHeight(10) + TestingUpdateValidator(keeper, ctx, validators[3], true) + resValidators = keeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, len(resValidators), n) + assert.True(ValEq(t, validators[3], resValidators[0])) + assert.True(ValEq(t, validators[4], resValidators[1])) + + // no change in voting power - no change in sort + ctx = ctx.WithBlockHeight(20) + TestingUpdateValidator(keeper, ctx, validators[4], true) + resValidators = keeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, len(resValidators), n) + assert.True(ValEq(t, validators[3], resValidators[0])) + assert.True(ValEq(t, validators[4], resValidators[1])) + + // change in voting power of both validators, both still in v-set, no age change + validators[3].Tokens = sdk.NewInt(300).Mul(sdk.PowerReduction) + validators[4].Tokens = sdk.NewInt(300).Mul(sdk.PowerReduction) + TestingUpdateValidator(keeper, ctx, validators[3], true) + resValidators = keeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, len(resValidators), n) + ctx = ctx.WithBlockHeight(30) + TestingUpdateValidator(keeper, ctx, validators[4], true) + resValidators = keeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, len(resValidators), n, "%v", resValidators) + assert.True(ValEq(t, validators[3], resValidators[0])) + assert.True(ValEq(t, validators[4], resValidators[1])) +} + +func TestGetValidatorSortingMixed(t *testing.T) { + ctx, _, bk, keeper, _ := CreateTestInput(t, false, 1000) + bondedPool := keeper.GetBondedPool(ctx) + notBondedPool := keeper.GetNotBondedPool(ctx) + + bk.SetBalances(ctx, bondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), sdk.TokensFromConsensusPower(501)))) + bk.SetBalances(ctx, notBondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), sdk.TokensFromConsensusPower(0)))) + keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) + keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) + + // now 2 max resValidators + params := keeper.GetParams(ctx) + params.MaxValidators = 2 + keeper.SetParams(ctx, params) + + // initialize some validators into the state + amts := []int64{ + 0, + 100 * sdk.PowerReduction.Int64(), + 1 * sdk.PowerReduction.Int64(), + 400 * sdk.PowerReduction.Int64(), + 200 * sdk.PowerReduction.Int64()} + + var validators [5]types.Validator + for i, amt := range amts { + validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) + validators[i].DelegatorShares = sdk.NewDec(amt) + validators[i].Status = sdk.Bonded + validators[i].Tokens = sdk.NewInt(amt) + TestingUpdateValidator(keeper, ctx, validators[i], true) + } + + val0, found := keeper.GetValidator(ctx, sdk.ValAddress(Addrs[0])) + require.True(t, found) + val1, found := keeper.GetValidator(ctx, sdk.ValAddress(Addrs[1])) + require.True(t, found) + val2, found := keeper.GetValidator(ctx, sdk.ValAddress(Addrs[2])) + require.True(t, found) + val3, found := keeper.GetValidator(ctx, sdk.ValAddress(Addrs[3])) + require.True(t, found) + val4, found := keeper.GetValidator(ctx, sdk.ValAddress(Addrs[4])) + require.True(t, found) + require.Equal(t, sdk.Bonded, val0.Status) + require.Equal(t, sdk.Unbonding, val1.Status) + require.Equal(t, sdk.Unbonding, val2.Status) + require.Equal(t, sdk.Bonded, val3.Status) + require.Equal(t, sdk.Bonded, val4.Status) + + // first make sure everything made it in to the gotValidator group + resValidators := keeper.GetBondedValidatorsByPower(ctx) + // The validators returned should match the max validators + assert.Equal(t, 2, len(resValidators)) + assert.Equal(t, sdk.NewInt(400).Mul(sdk.PowerReduction), resValidators[0].BondedTokens(), "%v", resValidators) + assert.Equal(t, sdk.NewInt(200).Mul(sdk.PowerReduction), resValidators[1].BondedTokens(), "%v", resValidators) + assert.Equal(t, validators[3].OperatorAddress, resValidators[0].OperatorAddress, "%v", resValidators) + assert.Equal(t, validators[4].OperatorAddress, resValidators[1].OperatorAddress, "%v", resValidators) +} + +// TODO separate out into multiple tests +func TestGetValidatorsEdgeCases(t *testing.T) { + ctx, _, bk, keeper, _ := CreateTestInput(t, false, 1000) + + // set max validators to 2 + params := keeper.GetParams(ctx) + nMax := uint32(2) + params.MaxValidators = nMax + keeper.SetParams(ctx, params) + + // initialize some validators into the state + powers := []int64{0, 100, 400, 400} + var validators [4]types.Validator + for i, power := range powers { + moniker := fmt.Sprintf("val#%d", int64(i)) + validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{Moniker: moniker}) + + tokens := sdk.TokensFromConsensusPower(power) + validators[i], _ = validators[i].AddTokensFromDel(tokens) + + notBondedPool := keeper.GetNotBondedPool(ctx) + balances := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) + require.NoError(t, bk.SetBalances(ctx, notBondedPool.GetAddress(), balances.Add(sdk.NewCoin(params.BondDenom, tokens)))) + + keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) + validators[i] = TestingUpdateValidator(keeper, ctx, validators[i], true) + } + + // ensure that the first two bonded validators are the largest validators + resValidators := keeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, nMax, uint32(len(resValidators))) + assert.True(ValEq(t, validators[2], resValidators[0])) + assert.True(ValEq(t, validators[3], resValidators[1])) + + // delegate 500 tokens to validator 0 + keeper.DeleteValidatorByPowerIndex(ctx, validators[0]) + delTokens := sdk.TokensFromConsensusPower(500) + validators[0], _ = validators[0].AddTokensFromDel(delTokens) + notBondedPool := keeper.GetNotBondedPool(ctx) + + newTokens := sdk.NewCoins() + balances := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) + require.NoError(t, bk.SetBalances(ctx, notBondedPool.GetAddress(), balances.Add(newTokens...))) + keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) + + // test that the two largest validators are + // a) validator 0 with 500 tokens + // b) validator 2 with 400 tokens (delegated before validator 3) + validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], true) + resValidators = keeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, nMax, uint32(len(resValidators))) + assert.True(ValEq(t, validators[0], resValidators[0])) + assert.True(ValEq(t, validators[2], resValidators[1])) + + // A validator which leaves the bonded validator set due to a decrease in voting power, + // then increases to the original voting power, does not get its spot back in the + // case of a tie. + // + // Order of operations for this test: + // - validator 3 enter validator set with 1 new token + // - validator 3 removed validator set by removing 201 tokens (validator 2 enters) + // - validator 3 adds 200 tokens (equal to validator 2 now) and does not get its spot back + + // validator 3 enters bonded validator set + ctx = ctx.WithBlockHeight(40) + + validators[3] = keeper.mustGetValidator(ctx, validators[3].OperatorAddress) + keeper.DeleteValidatorByPowerIndex(ctx, validators[3]) + validators[3], _ = validators[3].AddTokensFromDel(sdk.TokensFromConsensusPower(1)) + + notBondedPool = keeper.GetNotBondedPool(ctx) + newTokens = sdk.NewCoins(sdk.NewCoin(params.BondDenom, sdk.TokensFromConsensusPower(1))) + balances = bk.GetAllBalances(ctx, notBondedPool.GetAddress()) + require.NoError(t, bk.SetBalances(ctx, notBondedPool.GetAddress(), balances.Add(newTokens...))) + keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) + + validators[3] = TestingUpdateValidator(keeper, ctx, validators[3], true) + resValidators = keeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, nMax, uint32(len(resValidators))) + assert.True(ValEq(t, validators[0], resValidators[0])) + assert.True(ValEq(t, validators[3], resValidators[1])) + + // validator 3 kicked out temporarily + keeper.DeleteValidatorByPowerIndex(ctx, validators[3]) + rmTokens := validators[3].TokensFromShares(sdk.NewDec(201)).TruncateInt() + validators[3], _ = validators[3].RemoveDelShares(sdk.NewDec(201)) + + bondedPool := keeper.GetBondedPool(ctx) + balances = bk.GetAllBalances(ctx, bondedPool.GetAddress()) + require.NoError(t, bk.SetBalances(ctx, bondedPool.GetAddress(), balances.Add(sdk.NewCoin(params.BondDenom, rmTokens)))) + keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) + + validators[3] = TestingUpdateValidator(keeper, ctx, validators[3], true) + resValidators = keeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, nMax, uint32(len(resValidators))) + assert.True(ValEq(t, validators[0], resValidators[0])) + assert.True(ValEq(t, validators[2], resValidators[1])) + + // validator 3 does not get spot back + keeper.DeleteValidatorByPowerIndex(ctx, validators[3]) + validators[3], _ = validators[3].AddTokensFromDel(sdk.NewInt(200)) + + notBondedPool = keeper.GetNotBondedPool(ctx) + balances = bk.GetAllBalances(ctx, notBondedPool.GetAddress()) + require.NoError(t, bk.SetBalances(ctx, notBondedPool.GetAddress(), balances.Add(sdk.NewCoin(params.BondDenom, sdk.NewInt(200))))) + keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) + + validators[3] = TestingUpdateValidator(keeper, ctx, validators[3], true) + resValidators = keeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, nMax, uint32(len(resValidators))) + assert.True(ValEq(t, validators[0], resValidators[0])) + assert.True(ValEq(t, validators[2], resValidators[1])) + _, exists := keeper.GetValidator(ctx, validators[3].OperatorAddress) + require.True(t, exists) +} + +func TestValidatorBondHeight(t *testing.T) { + ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) + + // now 2 max resValidators + params := keeper.GetParams(ctx) + params.MaxValidators = 2 + keeper.SetParams(ctx, params) + + // initialize some validators into the state + var validators [3]types.Validator + validators[0] = types.NewValidator(sdk.ValAddress(PKs[0].Address().Bytes()), PKs[0], types.Description{}) + validators[1] = types.NewValidator(sdk.ValAddress(Addrs[1]), PKs[1], types.Description{}) + validators[2] = types.NewValidator(sdk.ValAddress(Addrs[2]), PKs[2], types.Description{}) + + tokens0 := sdk.TokensFromConsensusPower(200) + tokens1 := sdk.TokensFromConsensusPower(100) + tokens2 := sdk.TokensFromConsensusPower(100) + validators[0], _ = validators[0].AddTokensFromDel(tokens0) + validators[1], _ = validators[1].AddTokensFromDel(tokens1) + validators[2], _ = validators[2].AddTokensFromDel(tokens2) + + validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], true) + + //////////////////////////////////////// + // If two validators both increase to the same voting power in the same block, + // the one with the first transaction should become bonded + validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], true) + validators[2] = TestingUpdateValidator(keeper, ctx, validators[2], true) + + resValidators := keeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, uint32(len(resValidators)), params.MaxValidators) + + assert.True(ValEq(t, validators[0], resValidators[0])) + assert.True(ValEq(t, validators[1], resValidators[1])) + keeper.DeleteValidatorByPowerIndex(ctx, validators[1]) + keeper.DeleteValidatorByPowerIndex(ctx, validators[2]) + delTokens := sdk.TokensFromConsensusPower(50) + validators[1], _ = validators[1].AddTokensFromDel(delTokens) + validators[2], _ = validators[2].AddTokensFromDel(delTokens) + validators[2] = TestingUpdateValidator(keeper, ctx, validators[2], true) + resValidators = keeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, params.MaxValidators, uint32(len(resValidators))) + validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], true) + assert.True(ValEq(t, validators[0], resValidators[0])) + assert.True(ValEq(t, validators[2], resValidators[1])) +} + +func TestFullValidatorSetPowerChange(t *testing.T) { + ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) + params := keeper.GetParams(ctx) + max := 2 + params.MaxValidators = uint32(2) + keeper.SetParams(ctx, params) + + // initialize some validators into the state + powers := []int64{0, 100, 400, 400, 200} + var validators [5]types.Validator + for i, power := range powers { + validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) + tokens := sdk.TokensFromConsensusPower(power) + validators[i], _ = validators[i].AddTokensFromDel(tokens) + TestingUpdateValidator(keeper, ctx, validators[i], true) + } + for i := range powers { + var found bool + validators[i], found = keeper.GetValidator(ctx, validators[i].OperatorAddress) + require.True(t, found) + } + assert.Equal(t, sdk.Unbonded, validators[0].Status) + assert.Equal(t, sdk.Unbonding, validators[1].Status) + assert.Equal(t, sdk.Bonded, validators[2].Status) + assert.Equal(t, sdk.Bonded, validators[3].Status) + assert.Equal(t, sdk.Unbonded, validators[4].Status) + resValidators := keeper.GetBondedValidatorsByPower(ctx) + assert.Equal(t, max, len(resValidators)) + assert.True(ValEq(t, validators[2], resValidators[0])) // in the order of txs + assert.True(ValEq(t, validators[3], resValidators[1])) + + // test a swap in voting power + + tokens := sdk.TokensFromConsensusPower(600) + validators[0], _ = validators[0].AddTokensFromDel(tokens) + validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], true) + resValidators = keeper.GetBondedValidatorsByPower(ctx) + assert.Equal(t, max, len(resValidators)) + assert.True(ValEq(t, validators[0], resValidators[0])) + assert.True(ValEq(t, validators[2], resValidators[1])) +} + +func TestApplyAndReturnValidatorSetUpdatesAllNone(t *testing.T) { + ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) + + powers := []int64{10, 20} + var validators [2]types.Validator + for i, power := range powers { + valPubKey := PKs[i+1] + valAddr := sdk.ValAddress(valPubKey.Address().Bytes()) + + validators[i] = types.NewValidator(valAddr, valPubKey, types.Description{}) + tokens := sdk.TokensFromConsensusPower(power) + validators[i], _ = validators[i].AddTokensFromDel(tokens) + } + + // test from nothing to something + // tendermintUpdate set: {} -> {c1, c3} + require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) + keeper.SetValidator(ctx, validators[0]) + keeper.SetValidatorByPowerIndex(ctx, validators[0]) + keeper.SetValidator(ctx, validators[1]) + keeper.SetValidatorByPowerIndex(ctx, validators[1]) + + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) + assert.Equal(t, 2, len(updates)) + validators[0], _ = keeper.GetValidator(ctx, validators[0].OperatorAddress) + validators[1], _ = keeper.GetValidator(ctx, validators[1].OperatorAddress) + assert.Equal(t, validators[0].ABCIValidatorUpdate(), updates[1]) + assert.Equal(t, validators[1].ABCIValidatorUpdate(), updates[0]) +} + +func TestApplyAndReturnValidatorSetUpdatesIdentical(t *testing.T) { + ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) + + powers := []int64{10, 20} + var validators [2]types.Validator + for i, power := range powers { + validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) + + tokens := sdk.TokensFromConsensusPower(power) + validators[i], _ = validators[i].AddTokensFromDel(tokens) + + } + validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false) + validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], false) + require.Equal(t, 2, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) + + // test identical, + // tendermintUpdate set: {} -> {} + validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false) + validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], false) + require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) +} + +func TestApplyAndReturnValidatorSetUpdatesSingleValueChange(t *testing.T) { + ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) + + powers := []int64{10, 20} + var validators [2]types.Validator + for i, power := range powers { + + validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) + + tokens := sdk.TokensFromConsensusPower(power) + validators[i], _ = validators[i].AddTokensFromDel(tokens) + + } + validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false) + validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], false) + require.Equal(t, 2, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) + + // test single value change + // tendermintUpdate set: {} -> {c1'} + validators[0].Status = sdk.Bonded + validators[0].Tokens = sdk.TokensFromConsensusPower(600) + validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false) + + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) + + require.Equal(t, 1, len(updates)) + require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) +} + +func TestApplyAndReturnValidatorSetUpdatesMultipleValueChange(t *testing.T) { + ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) + + powers := []int64{10, 20} + var validators [2]types.Validator + for i, power := range powers { + + validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) + + tokens := sdk.TokensFromConsensusPower(power) + validators[i], _ = validators[i].AddTokensFromDel(tokens) + + } + validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false) + validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], false) + require.Equal(t, 2, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) + + // test multiple value change + // tendermintUpdate set: {c1, c3} -> {c1', c3'} + delTokens1 := sdk.TokensFromConsensusPower(190) + delTokens2 := sdk.TokensFromConsensusPower(80) + validators[0], _ = validators[0].AddTokensFromDel(delTokens1) + validators[1], _ = validators[1].AddTokensFromDel(delTokens2) + validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false) + validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], false) + + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 2, len(updates)) + require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) + require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) +} + +func TestApplyAndReturnValidatorSetUpdatesInserted(t *testing.T) { + ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) + + powers := []int64{10, 20, 5, 15, 25} + var validators [5]types.Validator + for i, power := range powers { + + validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) + + tokens := sdk.TokensFromConsensusPower(power) + validators[i], _ = validators[i].AddTokensFromDel(tokens) + + } + + validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false) + validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], false) + require.Equal(t, 2, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) + + // test validtor added at the beginning + // tendermintUpdate set: {} -> {c0} + keeper.SetValidator(ctx, validators[2]) + keeper.SetValidatorByPowerIndex(ctx, validators[2]) + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) + validators[2], _ = keeper.GetValidator(ctx, validators[2].OperatorAddress) + require.Equal(t, 1, len(updates)) + require.Equal(t, validators[2].ABCIValidatorUpdate(), updates[0]) + + // test validtor added at the beginning + // tendermintUpdate set: {} -> {c0} + keeper.SetValidator(ctx, validators[3]) + keeper.SetValidatorByPowerIndex(ctx, validators[3]) + updates = keeper.ApplyAndReturnValidatorSetUpdates(ctx) + validators[3], _ = keeper.GetValidator(ctx, validators[3].OperatorAddress) + require.Equal(t, 1, len(updates)) + require.Equal(t, validators[3].ABCIValidatorUpdate(), updates[0]) + + // test validtor added at the end + // tendermintUpdate set: {} -> {c0} + keeper.SetValidator(ctx, validators[4]) + keeper.SetValidatorByPowerIndex(ctx, validators[4]) + updates = keeper.ApplyAndReturnValidatorSetUpdates(ctx) + validators[4], _ = keeper.GetValidator(ctx, validators[4].OperatorAddress) + require.Equal(t, 1, len(updates)) + require.Equal(t, validators[4].ABCIValidatorUpdate(), updates[0]) +} + +func TestApplyAndReturnValidatorSetUpdatesWithCliffValidator(t *testing.T) { + ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) + params := types.DefaultParams() + params.MaxValidators = 2 + keeper.SetParams(ctx, params) + + powers := []int64{10, 20, 5} + var validators [5]types.Validator + for i, power := range powers { + + validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) + + tokens := sdk.TokensFromConsensusPower(power) + validators[i], _ = validators[i].AddTokensFromDel(tokens) + + } + validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false) + validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], false) + require.Equal(t, 2, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) + + // test validator added at the end but not inserted in the valset + // tendermintUpdate set: {} -> {} + TestingUpdateValidator(keeper, ctx, validators[2], false) + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 0, len(updates)) + + // test validator change its power and become a gotValidator (pushing out an existing) + // tendermintUpdate set: {} -> {c0, c4} + require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) + + tokens := sdk.TokensFromConsensusPower(10) + validators[2], _ = validators[2].AddTokensFromDel(tokens) + keeper.SetValidator(ctx, validators[2]) + keeper.SetValidatorByPowerIndex(ctx, validators[2]) + updates = keeper.ApplyAndReturnValidatorSetUpdates(ctx) + validators[2], _ = keeper.GetValidator(ctx, validators[2].OperatorAddress) + require.Equal(t, 2, len(updates), "%v", updates) + require.Equal(t, validators[0].ABCIValidatorUpdateZero(), updates[1]) + require.Equal(t, validators[2].ABCIValidatorUpdate(), updates[0]) +} + +func TestApplyAndReturnValidatorSetUpdatesPowerDecrease(t *testing.T) { + ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) + + powers := []int64{100, 100} + var validators [2]types.Validator + for i, power := range powers { + + validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) + + tokens := sdk.TokensFromConsensusPower(power) + validators[i], _ = validators[i].AddTokensFromDel(tokens) + + } + validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false) + validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], false) + require.Equal(t, 2, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) + + // check initial power + require.Equal(t, int64(100), validators[0].GetConsensusPower()) + require.Equal(t, int64(100), validators[1].GetConsensusPower()) + + // test multiple value change + // tendermintUpdate set: {c1, c3} -> {c1', c3'} + delTokens1 := sdk.TokensFromConsensusPower(20) + delTokens2 := sdk.TokensFromConsensusPower(30) + validators[0], _ = validators[0].RemoveDelShares(delTokens1.ToDec()) + validators[1], _ = validators[1].RemoveDelShares(delTokens2.ToDec()) + validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false) + validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], false) + + // power has changed + require.Equal(t, int64(80), validators[0].GetConsensusPower()) + require.Equal(t, int64(70), validators[1].GetConsensusPower()) + + // Tendermint updates should reflect power change + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 2, len(updates)) + require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) + require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) +} + +func TestApplyAndReturnValidatorSetUpdatesNewValidator(t *testing.T) { + ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) + params := keeper.GetParams(ctx) + params.MaxValidators = uint32(3) + + keeper.SetParams(ctx, params) + + powers := []int64{100, 100} + var validators [2]types.Validator + + // initialize some validators into the state + for i, power := range powers { + + valPubKey := PKs[i+1] + valAddr := sdk.ValAddress(valPubKey.Address().Bytes()) + + validators[i] = types.NewValidator(valAddr, valPubKey, types.Description{}) + tokens := sdk.TokensFromConsensusPower(power) + validators[i], _ = validators[i].AddTokensFromDel(tokens) + + keeper.SetValidator(ctx, validators[i]) + keeper.SetValidatorByPowerIndex(ctx, validators[i]) + } + + // verify initial Tendermint updates are correct + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, len(validators), len(updates)) + validators[0], _ = keeper.GetValidator(ctx, validators[0].OperatorAddress) + validators[1], _ = keeper.GetValidator(ctx, validators[1].OperatorAddress) + require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) + require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) + + require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) + + // update initial validator set + for i, power := range powers { + + keeper.DeleteValidatorByPowerIndex(ctx, validators[i]) + tokens := sdk.TokensFromConsensusPower(power) + validators[i], _ = validators[i].AddTokensFromDel(tokens) + + keeper.SetValidator(ctx, validators[i]) + keeper.SetValidatorByPowerIndex(ctx, validators[i]) + } + + // add a new validator that goes from zero power, to non-zero power, back to + // zero power + valPubKey := PKs[len(validators)+1] + valAddr := sdk.ValAddress(valPubKey.Address().Bytes()) + amt := sdk.NewInt(100) + + validator := types.NewValidator(valAddr, valPubKey, types.Description{}) + validator, _ = validator.AddTokensFromDel(amt) + + keeper.SetValidator(ctx, validator) + + validator, _ = validator.RemoveDelShares(amt.ToDec()) + keeper.SetValidator(ctx, validator) + keeper.SetValidatorByPowerIndex(ctx, validator) + + // add a new validator that increases in power + valPubKey = PKs[len(validators)+2] + valAddr = sdk.ValAddress(valPubKey.Address().Bytes()) + + validator = types.NewValidator(valAddr, valPubKey, types.Description{}) + tokens := sdk.TokensFromConsensusPower(500) + validator, _ = validator.AddTokensFromDel(tokens) + keeper.SetValidator(ctx, validator) + keeper.SetValidatorByPowerIndex(ctx, validator) + + // verify initial Tendermint updates are correct + updates = keeper.ApplyAndReturnValidatorSetUpdates(ctx) + validator, _ = keeper.GetValidator(ctx, validator.OperatorAddress) + validators[0], _ = keeper.GetValidator(ctx, validators[0].OperatorAddress) + validators[1], _ = keeper.GetValidator(ctx, validators[1].OperatorAddress) + require.Equal(t, len(validators)+1, len(updates)) + require.Equal(t, validator.ABCIValidatorUpdate(), updates[0]) + require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[1]) + require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[2]) +} + +func TestApplyAndReturnValidatorSetUpdatesBondTransition(t *testing.T) { + ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) + params := keeper.GetParams(ctx) + params.MaxValidators = uint32(2) + + keeper.SetParams(ctx, params) + + powers := []int64{100, 200, 300} + var validators [3]types.Validator + + // initialize some validators into the state + for i, power := range powers { + moniker := fmt.Sprintf("%d", i) + valPubKey := PKs[i+1] + valAddr := sdk.ValAddress(valPubKey.Address().Bytes()) + + validators[i] = types.NewValidator(valAddr, valPubKey, types.Description{Moniker: moniker}) + tokens := sdk.TokensFromConsensusPower(power) + validators[i], _ = validators[i].AddTokensFromDel(tokens) + keeper.SetValidator(ctx, validators[i]) + keeper.SetValidatorByPowerIndex(ctx, validators[i]) + } + + // verify initial Tendermint updates are correct + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 2, len(updates)) + validators[2], _ = keeper.GetValidator(ctx, validators[2].OperatorAddress) + validators[1], _ = keeper.GetValidator(ctx, validators[1].OperatorAddress) + require.Equal(t, validators[2].ABCIValidatorUpdate(), updates[0]) + require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) + + require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) + + // delegate to validator with lowest power but not enough to bond + ctx = ctx.WithBlockHeight(1) + + var found bool + validators[0], found = keeper.GetValidator(ctx, validators[0].OperatorAddress) + require.True(t, found) + + keeper.DeleteValidatorByPowerIndex(ctx, validators[0]) + tokens := sdk.TokensFromConsensusPower(1) + validators[0], _ = validators[0].AddTokensFromDel(tokens) + keeper.SetValidator(ctx, validators[0]) + keeper.SetValidatorByPowerIndex(ctx, validators[0]) + + // verify initial Tendermint updates are correct + require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) + + // create a series of events that will bond and unbond the validator with + // lowest power in a single block context (height) + ctx = ctx.WithBlockHeight(2) + + validators[1], found = keeper.GetValidator(ctx, validators[1].OperatorAddress) + require.True(t, found) + + keeper.DeleteValidatorByPowerIndex(ctx, validators[0]) + validators[0], _ = validators[0].RemoveDelShares(validators[0].DelegatorShares) + keeper.SetValidator(ctx, validators[0]) + keeper.SetValidatorByPowerIndex(ctx, validators[0]) + updates = keeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 0, len(updates)) + + keeper.DeleteValidatorByPowerIndex(ctx, validators[1]) + tokens = sdk.TokensFromConsensusPower(250) + validators[1], _ = validators[1].AddTokensFromDel(tokens) + keeper.SetValidator(ctx, validators[1]) + keeper.SetValidatorByPowerIndex(ctx, validators[1]) + + // verify initial Tendermint updates are correct + updates = keeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 1, len(updates)) + require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[0]) + + require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) +} + +func TestUpdateValidatorCommission(t *testing.T) { + ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) + ctx = ctx.WithBlockHeader(abci.Header{Time: time.Now().UTC()}) + + commission1 := types.NewCommissionWithTime( + sdk.NewDecWithPrec(1, 1), sdk.NewDecWithPrec(3, 1), + sdk.NewDecWithPrec(1, 1), time.Now().UTC().Add(time.Duration(-1)*time.Hour), + ) + commission2 := types.NewCommission(sdk.NewDecWithPrec(1, 1), sdk.NewDecWithPrec(3, 1), sdk.NewDecWithPrec(1, 1)) + + val1 := types.NewValidator(addrVals[0], PKs[0], types.Description{}) + val2 := types.NewValidator(addrVals[1], PKs[1], types.Description{}) + + val1, _ = val1.SetInitialCommission(commission1) + val2, _ = val2.SetInitialCommission(commission2) + + keeper.SetValidator(ctx, val1) + keeper.SetValidator(ctx, val2) + + testCases := []struct { + validator types.Validator + newRate sdk.Dec + expectedErr bool + }{ + {val1, sdk.ZeroDec(), true}, + {val2, sdk.NewDecWithPrec(-1, 1), true}, + {val2, sdk.NewDecWithPrec(4, 1), true}, + {val2, sdk.NewDecWithPrec(3, 1), true}, + {val2, sdk.NewDecWithPrec(2, 1), false}, + } + + for i, tc := range testCases { + commission, err := keeper.UpdateValidatorCommission(ctx, tc.validator, tc.newRate) + + if tc.expectedErr { + require.Error(t, err, "expected error for test case #%d with rate: %s", i, tc.newRate) + } else { + tc.validator.Commission = commission + keeper.SetValidator(ctx, tc.validator) + val, found := keeper.GetValidator(ctx, tc.validator.OperatorAddress) + + require.True(t, found, + "expected to find validator for test case #%d with rate: %s", i, tc.newRate, + ) + require.NoError(t, err, + "unexpected error for test case #%d with rate: %s", i, tc.newRate, + ) + require.Equal(t, tc.newRate, val.Commission.Rate, + "expected new validator commission rate for test case #%d with rate: %s", i, tc.newRate, + ) + require.Equal(t, ctx.BlockHeader().Time, val.Commission.UpdateTime, + "expected new validator commission update time for test case #%d with rate: %s", i, tc.newRate, + ) + } + } +} diff --git a/x/staking/keeper/slash_test.go b/x/staking/keeper/slash_test.go index 77296c19725e..fae13244c992 100644 --- a/x/staking/keeper/slash_test.go +++ b/x/staking/keeper/slash_test.go @@ -50,14 +50,6 @@ func bootstrapSlashTest(t *testing.T, power int64) (*simapp.SimApp, sdk.Context, return app, ctx, addrDels, addrVals } -// 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 -} - // tests Jail, Unjail func TestRevocation(t *testing.T) { app, ctx, _, addrVals := bootstrapSlashTest(t, 5) diff --git a/x/staking/keeper/test_common_test.go b/x/staking/keeper/test_common_test.go index 2275aff100fb..a32f3a7c0325 100644 --- a/x/staking/keeper/test_common_test.go +++ b/x/staking/keeper/test_common_test.go @@ -4,6 +4,7 @@ import ( "bytes" "encoding/hex" "strconv" + "testing" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" @@ -13,6 +14,7 @@ import ( 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" abci "github.com/tendermint/tendermint/abci/types" ) @@ -65,3 +67,17 @@ func getBaseSimappWithCustomKeeper() (*codec.Codec, *simapp.SimApp, sdk.Context) return cdc, app, ctx } + +// intended to be used with require/assert: require.True(ValEq(...)) +func ValEq(t *testing.T, exp, got types.Validator) (*testing.T, bool, string, types.Validator, types.Validator) { + return t, exp.MinEqual(got), "expected:\n%v\ngot:\n%v", exp, got +} + +// 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/keeper/validator_test.go b/x/staking/keeper/validator_test.go index 1b4d8f6a5ac8..de9c84b10cc3 100644 --- a/x/staking/keeper/validator_test.go +++ b/x/staking/keeper/validator_test.go @@ -1,22 +1,35 @@ -package keeper +package keeper_test import ( - "fmt" "testing" - "time" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/cosmos/cosmos-sdk/simapp" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - abci "github.com/tendermint/tendermint/abci/types" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/staking/types" ) -//_______________________________________________________ +func bootstrapValidatorTest(t *testing.T, power int64) (*simapp.SimApp, sdk.Context, []sdk.AccAddress, []sdk.ValAddress) { + _, app, ctx := getBaseSimappWithCustomKeeper() + + addrDels, addrVals := generateAddresses(app, ctx, 100) + + 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) + + return app, ctx, addrDels, addrVals +} func TestSetValidator(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 10) + app, ctx, _, _ := bootstrapValidatorTest(t, 10) valPubKey := PKs[0] valAddr := sdk.ValAddress(valPubKey.Address().Bytes()) @@ -28,12 +41,12 @@ func TestSetValidator(t *testing.T) { require.Equal(t, sdk.Unbonded, validator.Status) assert.Equal(t, valTokens, validator.Tokens) assert.Equal(t, valTokens, validator.DelegatorShares.RoundInt()) - keeper.SetValidator(ctx, validator) - keeper.SetValidatorByPowerIndex(ctx, validator) + app.StakingKeeper.SetValidator(ctx, validator) + app.StakingKeeper.SetValidatorByPowerIndex(ctx, validator) // ensure update - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - validator, found := keeper.GetValidator(ctx, valAddr) + updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + validator, found := app.StakingKeeper.GetValidator(ctx, valAddr) require.True(t, found) require.Equal(t, 1, len(updates)) require.Equal(t, validator.ABCIValidatorUpdate(), updates[0]) @@ -44,1050 +57,26 @@ func TestSetValidator(t *testing.T) { assert.Equal(t, valTokens, validator.DelegatorShares.RoundInt()) // Check each store for being saved - resVal, found := keeper.GetValidator(ctx, valAddr) + resVal, found := app.StakingKeeper.GetValidator(ctx, valAddr) assert.True(ValEq(t, validator, resVal)) require.True(t, found) - resVals := keeper.GetLastValidators(ctx) + resVals := app.StakingKeeper.GetLastValidators(ctx) require.Equal(t, 1, len(resVals)) assert.True(ValEq(t, validator, resVals[0])) - resVals = keeper.GetBondedValidatorsByPower(ctx) + resVals = app.StakingKeeper.GetBondedValidatorsByPower(ctx) require.Equal(t, 1, len(resVals)) require.True(ValEq(t, validator, resVals[0])) - resVals = keeper.GetValidators(ctx, 1) + resVals = app.StakingKeeper.GetValidators(ctx, 1) require.Equal(t, 1, len(resVals)) require.True(ValEq(t, validator, resVals[0])) - resVals = keeper.GetValidators(ctx, 10) + resVals = app.StakingKeeper.GetValidators(ctx, 10) require.Equal(t, 1, len(resVals)) require.True(ValEq(t, validator, resVals[0])) - allVals := keeper.GetAllValidators(ctx) + allVals := app.StakingKeeper.GetAllValidators(ctx) require.Equal(t, 1, len(allVals)) } - -func TestUpdateValidatorByPowerIndex(t *testing.T) { - ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) - - bondedPool := keeper.GetBondedPool(ctx) - notBondedPool := keeper.GetNotBondedPool(ctx) - bk.SetBalances(ctx, bondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), sdk.TokensFromConsensusPower(1234)))) - bk.SetBalances(ctx, notBondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), sdk.TokensFromConsensusPower(10000)))) - keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - // add a validator - validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) - validator, delSharesCreated := validator.AddTokensFromDel(sdk.TokensFromConsensusPower(100)) - require.Equal(t, sdk.Unbonded, validator.Status) - require.Equal(t, sdk.TokensFromConsensusPower(100), validator.Tokens) - TestingUpdateValidator(keeper, ctx, validator, true) - validator, found := keeper.GetValidator(ctx, addrVals[0]) - require.True(t, found) - require.Equal(t, sdk.TokensFromConsensusPower(100), validator.Tokens) - - power := types.GetValidatorsByPowerIndexKey(validator) - require.True(t, validatorByPowerIndexExists(keeper, ctx, power)) - - // burn half the delegator shares - keeper.DeleteValidatorByPowerIndex(ctx, validator) - validator, burned := validator.RemoveDelShares(delSharesCreated.Quo(sdk.NewDec(2))) - require.Equal(t, sdk.TokensFromConsensusPower(50), burned) - TestingUpdateValidator(keeper, ctx, validator, true) // update the validator, possibly kicking it out - require.False(t, validatorByPowerIndexExists(keeper, ctx, power)) - - validator, found = keeper.GetValidator(ctx, addrVals[0]) - require.True(t, found) - - power = types.GetValidatorsByPowerIndexKey(validator) - require.True(t, validatorByPowerIndexExists(keeper, ctx, power)) -} - -func TestUpdateBondedValidatorsDecreaseCliff(t *testing.T) { - numVals := 10 - maxVals := 5 - - // create context, keeper, and pool for tests - ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) - bondedPool := keeper.GetBondedPool(ctx) - notBondedPool := keeper.GetNotBondedPool(ctx) - - // create keeper parameters - params := keeper.GetParams(ctx) - params.MaxValidators = uint32(maxVals) - keeper.SetParams(ctx, params) - - // create a random pool - bk.SetBalances(ctx, bondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), sdk.TokensFromConsensusPower(1234)))) - bk.SetBalances(ctx, notBondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), sdk.TokensFromConsensusPower(10000)))) - keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - validators := make([]types.Validator, numVals) - for i := 0; i < len(validators); i++ { - moniker := fmt.Sprintf("val#%d", int64(i)) - val := types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{Moniker: moniker}) - delTokens := sdk.TokensFromConsensusPower(int64((i + 1) * 10)) - val, _ = val.AddTokensFromDel(delTokens) - - val = TestingUpdateValidator(keeper, ctx, val, true) - validators[i] = val - } - - nextCliffVal := validators[numVals-maxVals+1] - - // remove enough tokens to kick out the validator below the current cliff - // validator and next in line cliff validator - keeper.DeleteValidatorByPowerIndex(ctx, nextCliffVal) - shares := sdk.TokensFromConsensusPower(21) - nextCliffVal, _ = nextCliffVal.RemoveDelShares(shares.ToDec()) - nextCliffVal = TestingUpdateValidator(keeper, ctx, nextCliffVal, true) - - expectedValStatus := map[int]sdk.BondStatus{ - 9: sdk.Bonded, 8: sdk.Bonded, 7: sdk.Bonded, 5: sdk.Bonded, 4: sdk.Bonded, - 0: sdk.Unbonding, 1: sdk.Unbonding, 2: sdk.Unbonding, 3: sdk.Unbonding, 6: sdk.Unbonding, - } - - // require all the validators have their respective statuses - for valIdx, status := range expectedValStatus { - valAddr := validators[valIdx].OperatorAddress - val, _ := keeper.GetValidator(ctx, valAddr) - - assert.Equal( - t, status, val.GetStatus(), - fmt.Sprintf("expected validator at index %v to have status: %s", valIdx, status), - ) - } -} - -func TestSlashToZeroPowerRemoved(t *testing.T) { - // initialize setup - ctx, _, bk, keeper, _ := CreateTestInput(t, false, 100) - - // add a validator - validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) - valTokens := sdk.TokensFromConsensusPower(100) - - bondedPool := keeper.GetBondedPool(ctx) - err := bk.SetBalances(ctx, bondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), valTokens))) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) - - validator, _ = validator.AddTokensFromDel(valTokens) - require.Equal(t, sdk.Unbonded, validator.Status) - require.Equal(t, valTokens, validator.Tokens) - keeper.SetValidatorByConsAddr(ctx, validator) - validator = TestingUpdateValidator(keeper, ctx, validator, true) - require.Equal(t, valTokens, validator.Tokens, "\nvalidator %v\npool %v", validator, valTokens) - - // slash the validator by 100% - consAddr0 := sdk.ConsAddress(PKs[0].Address()) - keeper.Slash(ctx, consAddr0, 0, 100, sdk.OneDec()) - // apply TM updates - keeper.ApplyAndReturnValidatorSetUpdates(ctx) - // validator should be unbonding - validator, _ = keeper.GetValidator(ctx, addrVals[0]) - require.Equal(t, validator.GetStatus(), sdk.Unbonding) -} - -// This function tests UpdateValidator, GetValidator, GetLastValidators, RemoveValidator -func TestValidatorBasics(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) - - //construct the validators - var validators [3]types.Validator - powers := []int64{9, 8, 7} - for i, power := range powers { - validators[i] = types.NewValidator(addrVals[i], PKs[i], types.Description{}) - validators[i].Status = sdk.Unbonded - validators[i].Tokens = sdk.ZeroInt() - tokens := sdk.TokensFromConsensusPower(power) - - validators[i], _ = validators[i].AddTokensFromDel(tokens) - } - assert.Equal(t, sdk.TokensFromConsensusPower(9), validators[0].Tokens) - assert.Equal(t, sdk.TokensFromConsensusPower(8), validators[1].Tokens) - assert.Equal(t, sdk.TokensFromConsensusPower(7), validators[2].Tokens) - - // check the empty keeper first - _, found := keeper.GetValidator(ctx, addrVals[0]) - require.False(t, found) - resVals := keeper.GetLastValidators(ctx) - require.Zero(t, len(resVals)) - - resVals = keeper.GetValidators(ctx, 2) - require.Zero(t, len(resVals)) - - // set and retrieve a record - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], true) - keeper.SetValidatorByConsAddr(ctx, validators[0]) - resVal, found := keeper.GetValidator(ctx, addrVals[0]) - require.True(t, found) - assert.True(ValEq(t, validators[0], resVal)) - - // retrieve from consensus - resVal, found = keeper.GetValidatorByConsAddr(ctx, sdk.ConsAddress(PKs[0].Address())) - require.True(t, found) - assert.True(ValEq(t, validators[0], resVal)) - resVal, found = keeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(PKs[0])) - require.True(t, found) - assert.True(ValEq(t, validators[0], resVal)) - - resVals = keeper.GetLastValidators(ctx) - require.Equal(t, 1, len(resVals)) - assert.True(ValEq(t, validators[0], resVals[0])) - assert.Equal(t, sdk.Bonded, validators[0].Status) - assert.True(sdk.IntEq(t, sdk.TokensFromConsensusPower(9), validators[0].BondedTokens())) - - // modify a records, save, and retrieve - validators[0].Status = sdk.Bonded - validators[0].Tokens = sdk.TokensFromConsensusPower(10) - validators[0].DelegatorShares = validators[0].Tokens.ToDec() - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], true) - resVal, found = keeper.GetValidator(ctx, addrVals[0]) - require.True(t, found) - assert.True(ValEq(t, validators[0], resVal)) - - resVals = keeper.GetLastValidators(ctx) - require.Equal(t, 1, len(resVals)) - assert.True(ValEq(t, validators[0], resVals[0])) - - // add other validators - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], true) - validators[2] = TestingUpdateValidator(keeper, ctx, validators[2], true) - resVal, found = keeper.GetValidator(ctx, addrVals[1]) - require.True(t, found) - assert.True(ValEq(t, validators[1], resVal)) - resVal, found = keeper.GetValidator(ctx, addrVals[2]) - require.True(t, found) - assert.True(ValEq(t, validators[2], resVal)) - - resVals = keeper.GetLastValidators(ctx) - require.Equal(t, 3, len(resVals)) - assert.True(ValEq(t, validators[0], resVals[0])) // order doesn't matter here - assert.True(ValEq(t, validators[1], resVals[1])) - assert.True(ValEq(t, validators[2], resVals[2])) - - // remove a record - - // shouldn't be able to remove if status is not unbonded - assert.PanicsWithValue(t, - "cannot call RemoveValidator on bonded or unbonding validators", - func() { keeper.RemoveValidator(ctx, validators[1].OperatorAddress) }) - - // shouldn't be able to remove if there are still tokens left - validators[1].Status = sdk.Unbonded - keeper.SetValidator(ctx, validators[1]) - assert.PanicsWithValue(t, - "attempting to remove a validator which still contains tokens", - func() { keeper.RemoveValidator(ctx, validators[1].OperatorAddress) }) - - validators[1].Tokens = sdk.ZeroInt() // ...remove all tokens - keeper.SetValidator(ctx, validators[1]) // ...set the validator - keeper.RemoveValidator(ctx, validators[1].OperatorAddress) // Now it can be removed. - _, found = keeper.GetValidator(ctx, addrVals[1]) - require.False(t, found) -} - -// test how the validators are sorted, tests GetBondedValidatorsByPower -func TestGetValidatorSortingUnmixed(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) - - // initialize some validators into the state - amts := []int64{ - 0, - 100 * sdk.PowerReduction.Int64(), - 1 * sdk.PowerReduction.Int64(), - 400 * sdk.PowerReduction.Int64(), - 200 * sdk.PowerReduction.Int64()} - n := len(amts) - var validators [5]types.Validator - for i, amt := range amts { - validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) - validators[i].Status = sdk.Bonded - validators[i].Tokens = sdk.NewInt(amt) - validators[i].DelegatorShares = sdk.NewDec(amt) - TestingUpdateValidator(keeper, ctx, validators[i], true) - } - - // first make sure everything made it in to the gotValidator group - resValidators := keeper.GetBondedValidatorsByPower(ctx) - assert.Equal(t, n, len(resValidators)) - assert.Equal(t, sdk.NewInt(400).Mul(sdk.PowerReduction), resValidators[0].BondedTokens(), "%v", resValidators) - assert.Equal(t, sdk.NewInt(200).Mul(sdk.PowerReduction), resValidators[1].BondedTokens(), "%v", resValidators) - assert.Equal(t, sdk.NewInt(100).Mul(sdk.PowerReduction), resValidators[2].BondedTokens(), "%v", resValidators) - assert.Equal(t, sdk.NewInt(1).Mul(sdk.PowerReduction), resValidators[3].BondedTokens(), "%v", resValidators) - assert.Equal(t, sdk.NewInt(0), resValidators[4].BondedTokens(), "%v", resValidators) - assert.Equal(t, validators[3].OperatorAddress, resValidators[0].OperatorAddress, "%v", resValidators) - assert.Equal(t, validators[4].OperatorAddress, resValidators[1].OperatorAddress, "%v", resValidators) - assert.Equal(t, validators[1].OperatorAddress, resValidators[2].OperatorAddress, "%v", resValidators) - assert.Equal(t, validators[2].OperatorAddress, resValidators[3].OperatorAddress, "%v", resValidators) - assert.Equal(t, validators[0].OperatorAddress, resValidators[4].OperatorAddress, "%v", resValidators) - - // test a basic increase in voting power - validators[3].Tokens = sdk.NewInt(500).Mul(sdk.PowerReduction) - TestingUpdateValidator(keeper, ctx, validators[3], true) - resValidators = keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, len(resValidators), n) - assert.True(ValEq(t, validators[3], resValidators[0])) - - // test a decrease in voting power - validators[3].Tokens = sdk.NewInt(300).Mul(sdk.PowerReduction) - TestingUpdateValidator(keeper, ctx, validators[3], true) - resValidators = keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, len(resValidators), n) - assert.True(ValEq(t, validators[3], resValidators[0])) - assert.True(ValEq(t, validators[4], resValidators[1])) - - // test equal voting power, different age - validators[3].Tokens = sdk.NewInt(200).Mul(sdk.PowerReduction) - ctx = ctx.WithBlockHeight(10) - TestingUpdateValidator(keeper, ctx, validators[3], true) - resValidators = keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, len(resValidators), n) - assert.True(ValEq(t, validators[3], resValidators[0])) - assert.True(ValEq(t, validators[4], resValidators[1])) - - // no change in voting power - no change in sort - ctx = ctx.WithBlockHeight(20) - TestingUpdateValidator(keeper, ctx, validators[4], true) - resValidators = keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, len(resValidators), n) - assert.True(ValEq(t, validators[3], resValidators[0])) - assert.True(ValEq(t, validators[4], resValidators[1])) - - // change in voting power of both validators, both still in v-set, no age change - validators[3].Tokens = sdk.NewInt(300).Mul(sdk.PowerReduction) - validators[4].Tokens = sdk.NewInt(300).Mul(sdk.PowerReduction) - TestingUpdateValidator(keeper, ctx, validators[3], true) - resValidators = keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, len(resValidators), n) - ctx = ctx.WithBlockHeight(30) - TestingUpdateValidator(keeper, ctx, validators[4], true) - resValidators = keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, len(resValidators), n, "%v", resValidators) - assert.True(ValEq(t, validators[3], resValidators[0])) - assert.True(ValEq(t, validators[4], resValidators[1])) -} - -func TestGetValidatorSortingMixed(t *testing.T) { - ctx, _, bk, keeper, _ := CreateTestInput(t, false, 1000) - bondedPool := keeper.GetBondedPool(ctx) - notBondedPool := keeper.GetNotBondedPool(ctx) - - bk.SetBalances(ctx, bondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), sdk.TokensFromConsensusPower(501)))) - bk.SetBalances(ctx, notBondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), sdk.TokensFromConsensusPower(0)))) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) - - // now 2 max resValidators - params := keeper.GetParams(ctx) - params.MaxValidators = 2 - keeper.SetParams(ctx, params) - - // initialize some validators into the state - amts := []int64{ - 0, - 100 * sdk.PowerReduction.Int64(), - 1 * sdk.PowerReduction.Int64(), - 400 * sdk.PowerReduction.Int64(), - 200 * sdk.PowerReduction.Int64()} - - var validators [5]types.Validator - for i, amt := range amts { - validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) - validators[i].DelegatorShares = sdk.NewDec(amt) - validators[i].Status = sdk.Bonded - validators[i].Tokens = sdk.NewInt(amt) - TestingUpdateValidator(keeper, ctx, validators[i], true) - } - - val0, found := keeper.GetValidator(ctx, sdk.ValAddress(Addrs[0])) - require.True(t, found) - val1, found := keeper.GetValidator(ctx, sdk.ValAddress(Addrs[1])) - require.True(t, found) - val2, found := keeper.GetValidator(ctx, sdk.ValAddress(Addrs[2])) - require.True(t, found) - val3, found := keeper.GetValidator(ctx, sdk.ValAddress(Addrs[3])) - require.True(t, found) - val4, found := keeper.GetValidator(ctx, sdk.ValAddress(Addrs[4])) - require.True(t, found) - require.Equal(t, sdk.Bonded, val0.Status) - require.Equal(t, sdk.Unbonding, val1.Status) - require.Equal(t, sdk.Unbonding, val2.Status) - require.Equal(t, sdk.Bonded, val3.Status) - require.Equal(t, sdk.Bonded, val4.Status) - - // first make sure everything made it in to the gotValidator group - resValidators := keeper.GetBondedValidatorsByPower(ctx) - // The validators returned should match the max validators - assert.Equal(t, 2, len(resValidators)) - assert.Equal(t, sdk.NewInt(400).Mul(sdk.PowerReduction), resValidators[0].BondedTokens(), "%v", resValidators) - assert.Equal(t, sdk.NewInt(200).Mul(sdk.PowerReduction), resValidators[1].BondedTokens(), "%v", resValidators) - assert.Equal(t, validators[3].OperatorAddress, resValidators[0].OperatorAddress, "%v", resValidators) - assert.Equal(t, validators[4].OperatorAddress, resValidators[1].OperatorAddress, "%v", resValidators) -} - -// TODO separate out into multiple tests -func TestGetValidatorsEdgeCases(t *testing.T) { - ctx, _, bk, keeper, _ := CreateTestInput(t, false, 1000) - - // set max validators to 2 - params := keeper.GetParams(ctx) - nMax := uint32(2) - params.MaxValidators = nMax - keeper.SetParams(ctx, params) - - // initialize some validators into the state - powers := []int64{0, 100, 400, 400} - var validators [4]types.Validator - for i, power := range powers { - moniker := fmt.Sprintf("val#%d", int64(i)) - validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{Moniker: moniker}) - - tokens := sdk.TokensFromConsensusPower(power) - validators[i], _ = validators[i].AddTokensFromDel(tokens) - - notBondedPool := keeper.GetNotBondedPool(ctx) - balances := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) - require.NoError(t, bk.SetBalances(ctx, notBondedPool.GetAddress(), balances.Add(sdk.NewCoin(params.BondDenom, tokens)))) - - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - validators[i] = TestingUpdateValidator(keeper, ctx, validators[i], true) - } - - // ensure that the first two bonded validators are the largest validators - resValidators := keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, nMax, uint32(len(resValidators))) - assert.True(ValEq(t, validators[2], resValidators[0])) - assert.True(ValEq(t, validators[3], resValidators[1])) - - // delegate 500 tokens to validator 0 - keeper.DeleteValidatorByPowerIndex(ctx, validators[0]) - delTokens := sdk.TokensFromConsensusPower(500) - validators[0], _ = validators[0].AddTokensFromDel(delTokens) - notBondedPool := keeper.GetNotBondedPool(ctx) - - newTokens := sdk.NewCoins() - balances := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) - require.NoError(t, bk.SetBalances(ctx, notBondedPool.GetAddress(), balances.Add(newTokens...))) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - // test that the two largest validators are - // a) validator 0 with 500 tokens - // b) validator 2 with 400 tokens (delegated before validator 3) - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], true) - resValidators = keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, nMax, uint32(len(resValidators))) - assert.True(ValEq(t, validators[0], resValidators[0])) - assert.True(ValEq(t, validators[2], resValidators[1])) - - // A validator which leaves the bonded validator set due to a decrease in voting power, - // then increases to the original voting power, does not get its spot back in the - // case of a tie. - // - // Order of operations for this test: - // - validator 3 enter validator set with 1 new token - // - validator 3 removed validator set by removing 201 tokens (validator 2 enters) - // - validator 3 adds 200 tokens (equal to validator 2 now) and does not get its spot back - - // validator 3 enters bonded validator set - ctx = ctx.WithBlockHeight(40) - - validators[3] = keeper.mustGetValidator(ctx, validators[3].OperatorAddress) - keeper.DeleteValidatorByPowerIndex(ctx, validators[3]) - validators[3], _ = validators[3].AddTokensFromDel(sdk.TokensFromConsensusPower(1)) - - notBondedPool = keeper.GetNotBondedPool(ctx) - newTokens = sdk.NewCoins(sdk.NewCoin(params.BondDenom, sdk.TokensFromConsensusPower(1))) - balances = bk.GetAllBalances(ctx, notBondedPool.GetAddress()) - require.NoError(t, bk.SetBalances(ctx, notBondedPool.GetAddress(), balances.Add(newTokens...))) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - validators[3] = TestingUpdateValidator(keeper, ctx, validators[3], true) - resValidators = keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, nMax, uint32(len(resValidators))) - assert.True(ValEq(t, validators[0], resValidators[0])) - assert.True(ValEq(t, validators[3], resValidators[1])) - - // validator 3 kicked out temporarily - keeper.DeleteValidatorByPowerIndex(ctx, validators[3]) - rmTokens := validators[3].TokensFromShares(sdk.NewDec(201)).TruncateInt() - validators[3], _ = validators[3].RemoveDelShares(sdk.NewDec(201)) - - bondedPool := keeper.GetBondedPool(ctx) - balances = bk.GetAllBalances(ctx, bondedPool.GetAddress()) - require.NoError(t, bk.SetBalances(ctx, bondedPool.GetAddress(), balances.Add(sdk.NewCoin(params.BondDenom, rmTokens)))) - keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) - - validators[3] = TestingUpdateValidator(keeper, ctx, validators[3], true) - resValidators = keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, nMax, uint32(len(resValidators))) - assert.True(ValEq(t, validators[0], resValidators[0])) - assert.True(ValEq(t, validators[2], resValidators[1])) - - // validator 3 does not get spot back - keeper.DeleteValidatorByPowerIndex(ctx, validators[3]) - validators[3], _ = validators[3].AddTokensFromDel(sdk.NewInt(200)) - - notBondedPool = keeper.GetNotBondedPool(ctx) - balances = bk.GetAllBalances(ctx, notBondedPool.GetAddress()) - require.NoError(t, bk.SetBalances(ctx, notBondedPool.GetAddress(), balances.Add(sdk.NewCoin(params.BondDenom, sdk.NewInt(200))))) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - validators[3] = TestingUpdateValidator(keeper, ctx, validators[3], true) - resValidators = keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, nMax, uint32(len(resValidators))) - assert.True(ValEq(t, validators[0], resValidators[0])) - assert.True(ValEq(t, validators[2], resValidators[1])) - _, exists := keeper.GetValidator(ctx, validators[3].OperatorAddress) - require.True(t, exists) -} - -func TestValidatorBondHeight(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) - - // now 2 max resValidators - params := keeper.GetParams(ctx) - params.MaxValidators = 2 - keeper.SetParams(ctx, params) - - // initialize some validators into the state - var validators [3]types.Validator - validators[0] = types.NewValidator(sdk.ValAddress(PKs[0].Address().Bytes()), PKs[0], types.Description{}) - validators[1] = types.NewValidator(sdk.ValAddress(Addrs[1]), PKs[1], types.Description{}) - validators[2] = types.NewValidator(sdk.ValAddress(Addrs[2]), PKs[2], types.Description{}) - - tokens0 := sdk.TokensFromConsensusPower(200) - tokens1 := sdk.TokensFromConsensusPower(100) - tokens2 := sdk.TokensFromConsensusPower(100) - validators[0], _ = validators[0].AddTokensFromDel(tokens0) - validators[1], _ = validators[1].AddTokensFromDel(tokens1) - validators[2], _ = validators[2].AddTokensFromDel(tokens2) - - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], true) - - //////////////////////////////////////// - // If two validators both increase to the same voting power in the same block, - // the one with the first transaction should become bonded - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], true) - validators[2] = TestingUpdateValidator(keeper, ctx, validators[2], true) - - resValidators := keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, uint32(len(resValidators)), params.MaxValidators) - - assert.True(ValEq(t, validators[0], resValidators[0])) - assert.True(ValEq(t, validators[1], resValidators[1])) - keeper.DeleteValidatorByPowerIndex(ctx, validators[1]) - keeper.DeleteValidatorByPowerIndex(ctx, validators[2]) - delTokens := sdk.TokensFromConsensusPower(50) - validators[1], _ = validators[1].AddTokensFromDel(delTokens) - validators[2], _ = validators[2].AddTokensFromDel(delTokens) - validators[2] = TestingUpdateValidator(keeper, ctx, validators[2], true) - resValidators = keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, params.MaxValidators, uint32(len(resValidators))) - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], true) - assert.True(ValEq(t, validators[0], resValidators[0])) - assert.True(ValEq(t, validators[2], resValidators[1])) -} - -func TestFullValidatorSetPowerChange(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) - params := keeper.GetParams(ctx) - max := 2 - params.MaxValidators = uint32(2) - keeper.SetParams(ctx, params) - - // initialize some validators into the state - powers := []int64{0, 100, 400, 400, 200} - var validators [5]types.Validator - for i, power := range powers { - validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) - tokens := sdk.TokensFromConsensusPower(power) - validators[i], _ = validators[i].AddTokensFromDel(tokens) - TestingUpdateValidator(keeper, ctx, validators[i], true) - } - for i := range powers { - var found bool - validators[i], found = keeper.GetValidator(ctx, validators[i].OperatorAddress) - require.True(t, found) - } - assert.Equal(t, sdk.Unbonded, validators[0].Status) - assert.Equal(t, sdk.Unbonding, validators[1].Status) - assert.Equal(t, sdk.Bonded, validators[2].Status) - assert.Equal(t, sdk.Bonded, validators[3].Status) - assert.Equal(t, sdk.Unbonded, validators[4].Status) - resValidators := keeper.GetBondedValidatorsByPower(ctx) - assert.Equal(t, max, len(resValidators)) - assert.True(ValEq(t, validators[2], resValidators[0])) // in the order of txs - assert.True(ValEq(t, validators[3], resValidators[1])) - - // test a swap in voting power - - tokens := sdk.TokensFromConsensusPower(600) - validators[0], _ = validators[0].AddTokensFromDel(tokens) - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], true) - resValidators = keeper.GetBondedValidatorsByPower(ctx) - assert.Equal(t, max, len(resValidators)) - assert.True(ValEq(t, validators[0], resValidators[0])) - assert.True(ValEq(t, validators[2], resValidators[1])) -} - -func TestApplyAndReturnValidatorSetUpdatesAllNone(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) - - powers := []int64{10, 20} - var validators [2]types.Validator - for i, power := range powers { - valPubKey := PKs[i+1] - valAddr := sdk.ValAddress(valPubKey.Address().Bytes()) - - validators[i] = types.NewValidator(valAddr, valPubKey, types.Description{}) - tokens := sdk.TokensFromConsensusPower(power) - validators[i], _ = validators[i].AddTokensFromDel(tokens) - } - - // test from nothing to something - // tendermintUpdate set: {} -> {c1, c3} - require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) - keeper.SetValidator(ctx, validators[0]) - keeper.SetValidatorByPowerIndex(ctx, validators[0]) - keeper.SetValidator(ctx, validators[1]) - keeper.SetValidatorByPowerIndex(ctx, validators[1]) - - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - assert.Equal(t, 2, len(updates)) - validators[0], _ = keeper.GetValidator(ctx, validators[0].OperatorAddress) - validators[1], _ = keeper.GetValidator(ctx, validators[1].OperatorAddress) - assert.Equal(t, validators[0].ABCIValidatorUpdate(), updates[1]) - assert.Equal(t, validators[1].ABCIValidatorUpdate(), updates[0]) -} - -func TestApplyAndReturnValidatorSetUpdatesIdentical(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) - - powers := []int64{10, 20} - var validators [2]types.Validator - for i, power := range powers { - validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) - - tokens := sdk.TokensFromConsensusPower(power) - validators[i], _ = validators[i].AddTokensFromDel(tokens) - - } - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false) - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], false) - require.Equal(t, 2, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) - - // test identical, - // tendermintUpdate set: {} -> {} - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false) - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], false) - require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) -} - -func TestApplyAndReturnValidatorSetUpdatesSingleValueChange(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) - - powers := []int64{10, 20} - var validators [2]types.Validator - for i, power := range powers { - - validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) - - tokens := sdk.TokensFromConsensusPower(power) - validators[i], _ = validators[i].AddTokensFromDel(tokens) - - } - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false) - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], false) - require.Equal(t, 2, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) - - // test single value change - // tendermintUpdate set: {} -> {c1'} - validators[0].Status = sdk.Bonded - validators[0].Tokens = sdk.TokensFromConsensusPower(600) - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false) - - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - - require.Equal(t, 1, len(updates)) - require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) -} - -func TestApplyAndReturnValidatorSetUpdatesMultipleValueChange(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) - - powers := []int64{10, 20} - var validators [2]types.Validator - for i, power := range powers { - - validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) - - tokens := sdk.TokensFromConsensusPower(power) - validators[i], _ = validators[i].AddTokensFromDel(tokens) - - } - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false) - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], false) - require.Equal(t, 2, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) - - // test multiple value change - // tendermintUpdate set: {c1, c3} -> {c1', c3'} - delTokens1 := sdk.TokensFromConsensusPower(190) - delTokens2 := sdk.TokensFromConsensusPower(80) - validators[0], _ = validators[0].AddTokensFromDel(delTokens1) - validators[1], _ = validators[1].AddTokensFromDel(delTokens2) - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false) - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], false) - - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 2, len(updates)) - require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) - require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) -} - -func TestApplyAndReturnValidatorSetUpdatesInserted(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) - - powers := []int64{10, 20, 5, 15, 25} - var validators [5]types.Validator - for i, power := range powers { - - validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) - - tokens := sdk.TokensFromConsensusPower(power) - validators[i], _ = validators[i].AddTokensFromDel(tokens) - - } - - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false) - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], false) - require.Equal(t, 2, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) - - // test validtor added at the beginning - // tendermintUpdate set: {} -> {c0} - keeper.SetValidator(ctx, validators[2]) - keeper.SetValidatorByPowerIndex(ctx, validators[2]) - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - validators[2], _ = keeper.GetValidator(ctx, validators[2].OperatorAddress) - require.Equal(t, 1, len(updates)) - require.Equal(t, validators[2].ABCIValidatorUpdate(), updates[0]) - - // test validtor added at the beginning - // tendermintUpdate set: {} -> {c0} - keeper.SetValidator(ctx, validators[3]) - keeper.SetValidatorByPowerIndex(ctx, validators[3]) - updates = keeper.ApplyAndReturnValidatorSetUpdates(ctx) - validators[3], _ = keeper.GetValidator(ctx, validators[3].OperatorAddress) - require.Equal(t, 1, len(updates)) - require.Equal(t, validators[3].ABCIValidatorUpdate(), updates[0]) - - // test validtor added at the end - // tendermintUpdate set: {} -> {c0} - keeper.SetValidator(ctx, validators[4]) - keeper.SetValidatorByPowerIndex(ctx, validators[4]) - updates = keeper.ApplyAndReturnValidatorSetUpdates(ctx) - validators[4], _ = keeper.GetValidator(ctx, validators[4].OperatorAddress) - require.Equal(t, 1, len(updates)) - require.Equal(t, validators[4].ABCIValidatorUpdate(), updates[0]) -} - -func TestApplyAndReturnValidatorSetUpdatesWithCliffValidator(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) - params := types.DefaultParams() - params.MaxValidators = 2 - keeper.SetParams(ctx, params) - - powers := []int64{10, 20, 5} - var validators [5]types.Validator - for i, power := range powers { - - validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) - - tokens := sdk.TokensFromConsensusPower(power) - validators[i], _ = validators[i].AddTokensFromDel(tokens) - - } - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false) - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], false) - require.Equal(t, 2, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) - - // test validator added at the end but not inserted in the valset - // tendermintUpdate set: {} -> {} - TestingUpdateValidator(keeper, ctx, validators[2], false) - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 0, len(updates)) - - // test validator change its power and become a gotValidator (pushing out an existing) - // tendermintUpdate set: {} -> {c0, c4} - require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) - - tokens := sdk.TokensFromConsensusPower(10) - validators[2], _ = validators[2].AddTokensFromDel(tokens) - keeper.SetValidator(ctx, validators[2]) - keeper.SetValidatorByPowerIndex(ctx, validators[2]) - updates = keeper.ApplyAndReturnValidatorSetUpdates(ctx) - validators[2], _ = keeper.GetValidator(ctx, validators[2].OperatorAddress) - require.Equal(t, 2, len(updates), "%v", updates) - require.Equal(t, validators[0].ABCIValidatorUpdateZero(), updates[1]) - require.Equal(t, validators[2].ABCIValidatorUpdate(), updates[0]) -} - -func TestApplyAndReturnValidatorSetUpdatesPowerDecrease(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) - - powers := []int64{100, 100} - var validators [2]types.Validator - for i, power := range powers { - - validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) - - tokens := sdk.TokensFromConsensusPower(power) - validators[i], _ = validators[i].AddTokensFromDel(tokens) - - } - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false) - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], false) - require.Equal(t, 2, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) - - // check initial power - require.Equal(t, int64(100), validators[0].GetConsensusPower()) - require.Equal(t, int64(100), validators[1].GetConsensusPower()) - - // test multiple value change - // tendermintUpdate set: {c1, c3} -> {c1', c3'} - delTokens1 := sdk.TokensFromConsensusPower(20) - delTokens2 := sdk.TokensFromConsensusPower(30) - validators[0], _ = validators[0].RemoveDelShares(delTokens1.ToDec()) - validators[1], _ = validators[1].RemoveDelShares(delTokens2.ToDec()) - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false) - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], false) - - // power has changed - require.Equal(t, int64(80), validators[0].GetConsensusPower()) - require.Equal(t, int64(70), validators[1].GetConsensusPower()) - - // Tendermint updates should reflect power change - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 2, len(updates)) - require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) - require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) -} - -func TestApplyAndReturnValidatorSetUpdatesNewValidator(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) - params := keeper.GetParams(ctx) - params.MaxValidators = uint32(3) - - keeper.SetParams(ctx, params) - - powers := []int64{100, 100} - var validators [2]types.Validator - - // initialize some validators into the state - for i, power := range powers { - - valPubKey := PKs[i+1] - valAddr := sdk.ValAddress(valPubKey.Address().Bytes()) - - validators[i] = types.NewValidator(valAddr, valPubKey, types.Description{}) - tokens := sdk.TokensFromConsensusPower(power) - validators[i], _ = validators[i].AddTokensFromDel(tokens) - - keeper.SetValidator(ctx, validators[i]) - keeper.SetValidatorByPowerIndex(ctx, validators[i]) - } - - // verify initial Tendermint updates are correct - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, len(validators), len(updates)) - validators[0], _ = keeper.GetValidator(ctx, validators[0].OperatorAddress) - validators[1], _ = keeper.GetValidator(ctx, validators[1].OperatorAddress) - require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) - require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) - - require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) - - // update initial validator set - for i, power := range powers { - - keeper.DeleteValidatorByPowerIndex(ctx, validators[i]) - tokens := sdk.TokensFromConsensusPower(power) - validators[i], _ = validators[i].AddTokensFromDel(tokens) - - keeper.SetValidator(ctx, validators[i]) - keeper.SetValidatorByPowerIndex(ctx, validators[i]) - } - - // add a new validator that goes from zero power, to non-zero power, back to - // zero power - valPubKey := PKs[len(validators)+1] - valAddr := sdk.ValAddress(valPubKey.Address().Bytes()) - amt := sdk.NewInt(100) - - validator := types.NewValidator(valAddr, valPubKey, types.Description{}) - validator, _ = validator.AddTokensFromDel(amt) - - keeper.SetValidator(ctx, validator) - - validator, _ = validator.RemoveDelShares(amt.ToDec()) - keeper.SetValidator(ctx, validator) - keeper.SetValidatorByPowerIndex(ctx, validator) - - // add a new validator that increases in power - valPubKey = PKs[len(validators)+2] - valAddr = sdk.ValAddress(valPubKey.Address().Bytes()) - - validator = types.NewValidator(valAddr, valPubKey, types.Description{}) - tokens := sdk.TokensFromConsensusPower(500) - validator, _ = validator.AddTokensFromDel(tokens) - keeper.SetValidator(ctx, validator) - keeper.SetValidatorByPowerIndex(ctx, validator) - - // verify initial Tendermint updates are correct - updates = keeper.ApplyAndReturnValidatorSetUpdates(ctx) - validator, _ = keeper.GetValidator(ctx, validator.OperatorAddress) - validators[0], _ = keeper.GetValidator(ctx, validators[0].OperatorAddress) - validators[1], _ = keeper.GetValidator(ctx, validators[1].OperatorAddress) - require.Equal(t, len(validators)+1, len(updates)) - require.Equal(t, validator.ABCIValidatorUpdate(), updates[0]) - require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[1]) - require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[2]) -} - -func TestApplyAndReturnValidatorSetUpdatesBondTransition(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) - params := keeper.GetParams(ctx) - params.MaxValidators = uint32(2) - - keeper.SetParams(ctx, params) - - powers := []int64{100, 200, 300} - var validators [3]types.Validator - - // initialize some validators into the state - for i, power := range powers { - moniker := fmt.Sprintf("%d", i) - valPubKey := PKs[i+1] - valAddr := sdk.ValAddress(valPubKey.Address().Bytes()) - - validators[i] = types.NewValidator(valAddr, valPubKey, types.Description{Moniker: moniker}) - tokens := sdk.TokensFromConsensusPower(power) - validators[i], _ = validators[i].AddTokensFromDel(tokens) - keeper.SetValidator(ctx, validators[i]) - keeper.SetValidatorByPowerIndex(ctx, validators[i]) - } - - // verify initial Tendermint updates are correct - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 2, len(updates)) - validators[2], _ = keeper.GetValidator(ctx, validators[2].OperatorAddress) - validators[1], _ = keeper.GetValidator(ctx, validators[1].OperatorAddress) - require.Equal(t, validators[2].ABCIValidatorUpdate(), updates[0]) - require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) - - require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) - - // delegate to validator with lowest power but not enough to bond - ctx = ctx.WithBlockHeight(1) - - var found bool - validators[0], found = keeper.GetValidator(ctx, validators[0].OperatorAddress) - require.True(t, found) - - keeper.DeleteValidatorByPowerIndex(ctx, validators[0]) - tokens := sdk.TokensFromConsensusPower(1) - validators[0], _ = validators[0].AddTokensFromDel(tokens) - keeper.SetValidator(ctx, validators[0]) - keeper.SetValidatorByPowerIndex(ctx, validators[0]) - - // verify initial Tendermint updates are correct - require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) - - // create a series of events that will bond and unbond the validator with - // lowest power in a single block context (height) - ctx = ctx.WithBlockHeight(2) - - validators[1], found = keeper.GetValidator(ctx, validators[1].OperatorAddress) - require.True(t, found) - - keeper.DeleteValidatorByPowerIndex(ctx, validators[0]) - validators[0], _ = validators[0].RemoveDelShares(validators[0].DelegatorShares) - keeper.SetValidator(ctx, validators[0]) - keeper.SetValidatorByPowerIndex(ctx, validators[0]) - updates = keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 0, len(updates)) - - keeper.DeleteValidatorByPowerIndex(ctx, validators[1]) - tokens = sdk.TokensFromConsensusPower(250) - validators[1], _ = validators[1].AddTokensFromDel(tokens) - keeper.SetValidator(ctx, validators[1]) - keeper.SetValidatorByPowerIndex(ctx, validators[1]) - - // verify initial Tendermint updates are correct - updates = keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 1, len(updates)) - require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[0]) - - require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) -} - -func TestUpdateValidatorCommission(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) - ctx = ctx.WithBlockHeader(abci.Header{Time: time.Now().UTC()}) - - commission1 := types.NewCommissionWithTime( - sdk.NewDecWithPrec(1, 1), sdk.NewDecWithPrec(3, 1), - sdk.NewDecWithPrec(1, 1), time.Now().UTC().Add(time.Duration(-1)*time.Hour), - ) - commission2 := types.NewCommission(sdk.NewDecWithPrec(1, 1), sdk.NewDecWithPrec(3, 1), sdk.NewDecWithPrec(1, 1)) - - val1 := types.NewValidator(addrVals[0], PKs[0], types.Description{}) - val2 := types.NewValidator(addrVals[1], PKs[1], types.Description{}) - - val1, _ = val1.SetInitialCommission(commission1) - val2, _ = val2.SetInitialCommission(commission2) - - keeper.SetValidator(ctx, val1) - keeper.SetValidator(ctx, val2) - - testCases := []struct { - validator types.Validator - newRate sdk.Dec - expectedErr bool - }{ - {val1, sdk.ZeroDec(), true}, - {val2, sdk.NewDecWithPrec(-1, 1), true}, - {val2, sdk.NewDecWithPrec(4, 1), true}, - {val2, sdk.NewDecWithPrec(3, 1), true}, - {val2, sdk.NewDecWithPrec(2, 1), false}, - } - - for i, tc := range testCases { - commission, err := keeper.UpdateValidatorCommission(ctx, tc.validator, tc.newRate) - - if tc.expectedErr { - require.Error(t, err, "expected error for test case #%d with rate: %s", i, tc.newRate) - } else { - tc.validator.Commission = commission - keeper.SetValidator(ctx, tc.validator) - val, found := keeper.GetValidator(ctx, tc.validator.OperatorAddress) - - require.True(t, found, - "expected to find validator for test case #%d with rate: %s", i, tc.newRate, - ) - require.NoError(t, err, - "unexpected error for test case #%d with rate: %s", i, tc.newRate, - ) - require.Equal(t, tc.newRate, val.Commission.Rate, - "expected new validator commission rate for test case #%d with rate: %s", i, tc.newRate, - ) - require.Equal(t, ctx.BlockHeader().Time, val.Commission.UpdateTime, - "expected new validator commission update time for test case #%d with rate: %s", i, tc.newRate, - ) - } - } -} From 25681ad3ad53a94a5ef74f7f5b07beb4ec06db2d Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Tue, 25 Feb 2020 11:54:43 +0100 Subject: [PATCH 42/90] refacor TestUpdateValidatorByPowerIndex to use simapp --- x/staking/keeper/old_test_common.go | 6 ---- x/staking/keeper/old_validator_test.go | 37 ------------------------ x/staking/keeper/test_common_test.go | 1 - x/staking/keeper/validator_test.go | 40 ++++++++++++++++++++++++++ 4 files changed, 40 insertions(+), 44 deletions(-) diff --git a/x/staking/keeper/old_test_common.go b/x/staking/keeper/old_test_common.go index 8e4cd6b9aac7..82bd54a317ad 100644 --- a/x/staking/keeper/old_test_common.go +++ b/x/staking/keeper/old_test_common.go @@ -285,12 +285,6 @@ func TestingUpdateValidator(keeper Keeper, ctx sdk.Context, validator types.Vali return validator } -// nolint:deadcode, unused -func validatorByPowerIndexExists(k Keeper, ctx sdk.Context, power []byte) bool { - store := ctx.KVStore(k.storeKey) - return store.Has(power) -} - // RandomValidator returns a random validator given access to the keeper and ctx func RandomValidator(r *rand.Rand, keeper Keeper, ctx sdk.Context) (val types.Validator, ok bool) { vals := keeper.GetAllValidators(ctx) diff --git a/x/staking/keeper/old_validator_test.go b/x/staking/keeper/old_validator_test.go index c5101a3c145b..6151861f1695 100644 --- a/x/staking/keeper/old_validator_test.go +++ b/x/staking/keeper/old_validator_test.go @@ -14,43 +14,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/staking/types" ) -func TestUpdateValidatorByPowerIndex(t *testing.T) { - ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) - - bondedPool := keeper.GetBondedPool(ctx) - notBondedPool := keeper.GetNotBondedPool(ctx) - bk.SetBalances(ctx, bondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), sdk.TokensFromConsensusPower(1234)))) - bk.SetBalances(ctx, notBondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), sdk.TokensFromConsensusPower(10000)))) - keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - // add a validator - validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) - validator, delSharesCreated := validator.AddTokensFromDel(sdk.TokensFromConsensusPower(100)) - require.Equal(t, sdk.Unbonded, validator.Status) - require.Equal(t, sdk.TokensFromConsensusPower(100), validator.Tokens) - TestingUpdateValidator(keeper, ctx, validator, true) - validator, found := keeper.GetValidator(ctx, addrVals[0]) - require.True(t, found) - require.Equal(t, sdk.TokensFromConsensusPower(100), validator.Tokens) - - power := types.GetValidatorsByPowerIndexKey(validator) - require.True(t, validatorByPowerIndexExists(keeper, ctx, power)) - - // burn half the delegator shares - keeper.DeleteValidatorByPowerIndex(ctx, validator) - validator, burned := validator.RemoveDelShares(delSharesCreated.Quo(sdk.NewDec(2))) - require.Equal(t, sdk.TokensFromConsensusPower(50), burned) - TestingUpdateValidator(keeper, ctx, validator, true) // update the validator, possibly kicking it out - require.False(t, validatorByPowerIndexExists(keeper, ctx, power)) - - validator, found = keeper.GetValidator(ctx, addrVals[0]) - require.True(t, found) - - power = types.GetValidatorsByPowerIndexKey(validator) - require.True(t, validatorByPowerIndexExists(keeper, ctx, power)) -} - func TestUpdateBondedValidatorsDecreaseCliff(t *testing.T) { numVals := 10 maxVals := 5 diff --git a/x/staking/keeper/test_common_test.go b/x/staking/keeper/test_common_test.go index a32f3a7c0325..9293ed884a67 100644 --- a/x/staking/keeper/test_common_test.go +++ b/x/staking/keeper/test_common_test.go @@ -80,4 +80,3 @@ func generateAddresses(app *simapp.SimApp, ctx sdk.Context, numAddrs int) ([]sdk return addrDels, addrVals } - diff --git a/x/staking/keeper/validator_test.go b/x/staking/keeper/validator_test.go index de9c84b10cc3..c1dfc2ab6ba6 100644 --- a/x/staking/keeper/validator_test.go +++ b/x/staking/keeper/validator_test.go @@ -3,6 +3,8 @@ package keeper_test import ( "testing" + "github.com/cosmos/cosmos-sdk/x/staking/keeper" + "github.com/cosmos/cosmos-sdk/simapp" "github.com/stretchr/testify/assert" @@ -80,3 +82,41 @@ func TestSetValidator(t *testing.T) { allVals := app.StakingKeeper.GetAllValidators(ctx) require.Equal(t, 1, len(allVals)) } + +func TestUpdateValidatorByPowerIndex(t *testing.T) { + app, ctx, _, _ := bootstrapValidatorTest(t, 0) + _, addrVals := generateAddresses(app, ctx, 1) + + bondedPool := app.StakingKeeper.GetBondedPool(ctx) + notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) + app.BankKeeper.SetBalances(ctx, bondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.TokensFromConsensusPower(1234)))) + app.BankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.TokensFromConsensusPower(10000)))) + app.SupplyKeeper.SetModuleAccount(ctx, bondedPool) + app.SupplyKeeper.SetModuleAccount(ctx, notBondedPool) + + // add a validator + validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) + validator, delSharesCreated := validator.AddTokensFromDel(sdk.TokensFromConsensusPower(100)) + require.Equal(t, sdk.Unbonded, validator.Status) + require.Equal(t, sdk.TokensFromConsensusPower(100), validator.Tokens) + keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) + validator, found := app.StakingKeeper.GetValidator(ctx, addrVals[0]) + require.True(t, found) + require.Equal(t, sdk.TokensFromConsensusPower(100), validator.Tokens) + + power := types.GetValidatorsByPowerIndexKey(validator) + require.True(t, keeper.ValidatorByPowerIndexExists(ctx, app.StakingKeeper, power)) + + // burn half the delegator shares + app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validator) + validator, burned := validator.RemoveDelShares(delSharesCreated.Quo(sdk.NewDec(2))) + require.Equal(t, sdk.TokensFromConsensusPower(50), burned) + keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) // update the validator, possibly kicking it out + require.False(t, keeper.ValidatorByPowerIndexExists(ctx, app.StakingKeeper, power)) + + validator, found = app.StakingKeeper.GetValidator(ctx, addrVals[0]) + require.True(t, found) + + power = types.GetValidatorsByPowerIndexKey(validator) + require.True(t, keeper.ValidatorByPowerIndexExists(ctx, app.StakingKeeper, power)) +} From 385c5c556be57a677e6c7f5b7381e4db79501f2e Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Tue, 25 Feb 2020 11:59:15 +0100 Subject: [PATCH 43/90] refactor TestUpdateBondedValidatorsDecreaseCliff to simapp --- x/staking/keeper/old_validator_test.go | 57 ------------------------ x/staking/keeper/validator_test.go | 60 ++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 57 deletions(-) diff --git a/x/staking/keeper/old_validator_test.go b/x/staking/keeper/old_validator_test.go index 6151861f1695..168f36a57a69 100644 --- a/x/staking/keeper/old_validator_test.go +++ b/x/staking/keeper/old_validator_test.go @@ -14,63 +14,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/staking/types" ) -func TestUpdateBondedValidatorsDecreaseCliff(t *testing.T) { - numVals := 10 - maxVals := 5 - - // create context, keeper, and pool for tests - ctx, _, bk, keeper, _ := CreateTestInput(t, false, 0) - bondedPool := keeper.GetBondedPool(ctx) - notBondedPool := keeper.GetNotBondedPool(ctx) - - // create keeper parameters - params := keeper.GetParams(ctx) - params.MaxValidators = uint32(maxVals) - keeper.SetParams(ctx, params) - - // create a random pool - bk.SetBalances(ctx, bondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), sdk.TokensFromConsensusPower(1234)))) - bk.SetBalances(ctx, notBondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), sdk.TokensFromConsensusPower(10000)))) - keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - validators := make([]types.Validator, numVals) - for i := 0; i < len(validators); i++ { - moniker := fmt.Sprintf("val#%d", int64(i)) - val := types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{Moniker: moniker}) - delTokens := sdk.TokensFromConsensusPower(int64((i + 1) * 10)) - val, _ = val.AddTokensFromDel(delTokens) - - val = TestingUpdateValidator(keeper, ctx, val, true) - validators[i] = val - } - - nextCliffVal := validators[numVals-maxVals+1] - - // remove enough tokens to kick out the validator below the current cliff - // validator and next in line cliff validator - keeper.DeleteValidatorByPowerIndex(ctx, nextCliffVal) - shares := sdk.TokensFromConsensusPower(21) - nextCliffVal, _ = nextCliffVal.RemoveDelShares(shares.ToDec()) - nextCliffVal = TestingUpdateValidator(keeper, ctx, nextCliffVal, true) - - expectedValStatus := map[int]sdk.BondStatus{ - 9: sdk.Bonded, 8: sdk.Bonded, 7: sdk.Bonded, 5: sdk.Bonded, 4: sdk.Bonded, - 0: sdk.Unbonding, 1: sdk.Unbonding, 2: sdk.Unbonding, 3: sdk.Unbonding, 6: sdk.Unbonding, - } - - // require all the validators have their respective statuses - for valIdx, status := range expectedValStatus { - valAddr := validators[valIdx].OperatorAddress - val, _ := keeper.GetValidator(ctx, valAddr) - - assert.Equal( - t, status, val.GetStatus(), - fmt.Sprintf("expected validator at index %v to have status: %s", valIdx, status), - ) - } -} - func TestSlashToZeroPowerRemoved(t *testing.T) { // initialize setup ctx, _, bk, keeper, _ := CreateTestInput(t, false, 100) diff --git a/x/staking/keeper/validator_test.go b/x/staking/keeper/validator_test.go index c1dfc2ab6ba6..18a52f9489b6 100644 --- a/x/staking/keeper/validator_test.go +++ b/x/staking/keeper/validator_test.go @@ -1,6 +1,7 @@ package keeper_test import ( + "fmt" "testing" "github.com/cosmos/cosmos-sdk/x/staking/keeper" @@ -120,3 +121,62 @@ func TestUpdateValidatorByPowerIndex(t *testing.T) { power = types.GetValidatorsByPowerIndexKey(validator) require.True(t, keeper.ValidatorByPowerIndexExists(ctx, app.StakingKeeper, power)) } + +func TestUpdateBondedValidatorsDecreaseCliff(t *testing.T) { + numVals := 10 + maxVals := 5 + + // create context, keeper, and pool for tests + app, ctx, _, _ := bootstrapValidatorTest(t, 0) + _, valAddrs := generateAddresses(app, ctx, 10) + + bondedPool := app.StakingKeeper.GetBondedPool(ctx) + notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) + + // create keeper parameters + params := app.StakingKeeper.GetParams(ctx) + params.MaxValidators = uint32(maxVals) + app.StakingKeeper.SetParams(ctx, params) + + // create a random pool + app.BankKeeper.SetBalances(ctx, bondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.TokensFromConsensusPower(1234)))) + app.BankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.TokensFromConsensusPower(10000)))) + app.SupplyKeeper.SetModuleAccount(ctx, bondedPool) + app.SupplyKeeper.SetModuleAccount(ctx, notBondedPool) + + validators := make([]types.Validator, numVals) + for i := 0; i < len(validators); i++ { + moniker := fmt.Sprintf("val#%d", int64(i)) + val := types.NewValidator(valAddrs[i], PKs[i], types.Description{Moniker: moniker}) + delTokens := sdk.TokensFromConsensusPower(int64((i + 1) * 10)) + val, _ = val.AddTokensFromDel(delTokens) + + val = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, val, true) + validators[i] = val + } + + nextCliffVal := validators[numVals-maxVals+1] + + // remove enough tokens to kick out the validator below the current cliff + // validator and next in line cliff validator + app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, nextCliffVal) + shares := sdk.TokensFromConsensusPower(21) + nextCliffVal, _ = nextCliffVal.RemoveDelShares(shares.ToDec()) + nextCliffVal = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, nextCliffVal, true) + + expectedValStatus := map[int]sdk.BondStatus{ + 9: sdk.Bonded, 8: sdk.Bonded, 7: sdk.Bonded, 5: sdk.Bonded, 4: sdk.Bonded, + 0: sdk.Unbonding, 1: sdk.Unbonding, 2: sdk.Unbonding, 3: sdk.Unbonding, 6: sdk.Unbonding, + } + + // require all the validators have their respective statuses + for valIdx, status := range expectedValStatus { + valAddr := validators[valIdx].OperatorAddress + val, _ := app.StakingKeeper.GetValidator(ctx, valAddr) + + assert.Equal( + t, status, val.GetStatus(), + fmt.Sprintf("expected validator at index %v to have status: %s", valIdx, status), + ) + } +} From ed401119e4353a2a32367d8842c701ad89333f03 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Tue, 25 Feb 2020 13:18:49 +0100 Subject: [PATCH 44/90] refactor TestSlashToZeroPowerRemoved --- x/staking/keeper/old_validator_test.go | 30 ------------------ x/staking/keeper/validator_test.go | 44 ++++++++++++++++++++++---- 2 files changed, 38 insertions(+), 36 deletions(-) diff --git a/x/staking/keeper/old_validator_test.go b/x/staking/keeper/old_validator_test.go index 168f36a57a69..a7187b23cfca 100644 --- a/x/staking/keeper/old_validator_test.go +++ b/x/staking/keeper/old_validator_test.go @@ -14,36 +14,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/staking/types" ) -func TestSlashToZeroPowerRemoved(t *testing.T) { - // initialize setup - ctx, _, bk, keeper, _ := CreateTestInput(t, false, 100) - - // add a validator - validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) - valTokens := sdk.TokensFromConsensusPower(100) - - bondedPool := keeper.GetBondedPool(ctx) - err := bk.SetBalances(ctx, bondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), valTokens))) - require.NoError(t, err) - keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) - - validator, _ = validator.AddTokensFromDel(valTokens) - require.Equal(t, sdk.Unbonded, validator.Status) - require.Equal(t, valTokens, validator.Tokens) - keeper.SetValidatorByConsAddr(ctx, validator) - validator = TestingUpdateValidator(keeper, ctx, validator, true) - require.Equal(t, valTokens, validator.Tokens, "\nvalidator %v\npool %v", validator, valTokens) - - // slash the validator by 100% - consAddr0 := sdk.ConsAddress(PKs[0].Address()) - keeper.Slash(ctx, consAddr0, 0, 100, sdk.OneDec()) - // apply TM updates - keeper.ApplyAndReturnValidatorSetUpdates(ctx) - // validator should be unbonding - validator, _ = keeper.GetValidator(ctx, addrVals[0]) - require.Equal(t, validator.GetStatus(), sdk.Unbonding) -} - // This function tests UpdateValidator, GetValidator, GetLastValidators, RemoveValidator func TestValidatorBasics(t *testing.T) { ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) diff --git a/x/staking/keeper/validator_test.go b/x/staking/keeper/validator_test.go index 18a52f9489b6..c303d2029a46 100644 --- a/x/staking/keeper/validator_test.go +++ b/x/staking/keeper/validator_test.go @@ -4,6 +4,8 @@ import ( "fmt" "testing" + "github.com/cosmos/cosmos-sdk/x/supply" + "github.com/cosmos/cosmos-sdk/x/staking/keeper" "github.com/cosmos/cosmos-sdk/simapp" @@ -15,10 +17,10 @@ import ( "github.com/cosmos/cosmos-sdk/x/staking/types" ) -func bootstrapValidatorTest(t *testing.T, power int64) (*simapp.SimApp, sdk.Context, []sdk.AccAddress, []sdk.ValAddress) { +func bootstrapValidatorTest(t *testing.T, power int64, numAddrs int) (*simapp.SimApp, sdk.Context, []sdk.AccAddress, []sdk.ValAddress) { _, app, ctx := getBaseSimappWithCustomKeeper() - addrDels, addrVals := generateAddresses(app, ctx, 100) + addrDels, addrVals := generateAddresses(app, ctx, numAddrs) amt := sdk.TokensFromConsensusPower(power) totalSupply := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), amt.MulRaw(int64(len(addrDels))))) @@ -28,11 +30,13 @@ func bootstrapValidatorTest(t *testing.T, power int64) (*simapp.SimApp, sdk.Cont require.NoError(t, err) app.SupplyKeeper.SetModuleAccount(ctx, notBondedPool) + app.SupplyKeeper.SetSupply(ctx, supply.NewSupply(totalSupply)) + return app, ctx, addrDels, addrVals } func TestSetValidator(t *testing.T) { - app, ctx, _, _ := bootstrapValidatorTest(t, 10) + app, ctx, _, _ := bootstrapValidatorTest(t, 10, 100) valPubKey := PKs[0] valAddr := sdk.ValAddress(valPubKey.Address().Bytes()) @@ -85,7 +89,7 @@ func TestSetValidator(t *testing.T) { } func TestUpdateValidatorByPowerIndex(t *testing.T) { - app, ctx, _, _ := bootstrapValidatorTest(t, 0) + app, ctx, _, _ := bootstrapValidatorTest(t, 0, 100) _, addrVals := generateAddresses(app, ctx, 1) bondedPool := app.StakingKeeper.GetBondedPool(ctx) @@ -127,8 +131,7 @@ func TestUpdateBondedValidatorsDecreaseCliff(t *testing.T) { maxVals := 5 // create context, keeper, and pool for tests - app, ctx, _, _ := bootstrapValidatorTest(t, 0) - _, valAddrs := generateAddresses(app, ctx, 10) + app, ctx, _, valAddrs := bootstrapValidatorTest(t, 0, 100) bondedPool := app.StakingKeeper.GetBondedPool(ctx) notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) @@ -180,3 +183,32 @@ func TestUpdateBondedValidatorsDecreaseCliff(t *testing.T) { ) } } + +func TestSlashToZeroPowerRemoved(t *testing.T) { + // initialize setup + app, ctx, _, addrVals := bootstrapValidatorTest(t, 100, 20) + + // add a validator + validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) + valTokens := sdk.TokensFromConsensusPower(100) + + bondedPool := app.StakingKeeper.GetBondedPool(ctx) + err := app.BankKeeper.SetBalances(ctx, bondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), valTokens))) + require.NoError(t, err) + app.SupplyKeeper.SetModuleAccount(ctx, bondedPool) + + validator, _ = validator.AddTokensFromDel(valTokens) + require.Equal(t, sdk.Unbonded, validator.Status) + require.Equal(t, valTokens, validator.Tokens) + app.StakingKeeper.SetValidatorByConsAddr(ctx, validator) + validator = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validator, true) + require.Equal(t, valTokens, validator.Tokens, "\nvalidator %v\npool %v", validator, valTokens) + + // slash the validator by 100% + app.StakingKeeper.Slash(ctx, sdk.ConsAddress(PKs[0].Address()), 0, 100, sdk.OneDec()) + // apply TM updates + app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + // validator should be unbonding + validator, _ = app.StakingKeeper.GetValidator(ctx, addrVals[0]) + require.Equal(t, validator.GetStatus(), sdk.Unbonding) +} From 9fa658c3f94712bd867f3f4b2e84ea7e543f3719 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Tue, 25 Feb 2020 13:23:22 +0100 Subject: [PATCH 45/90] TestValidatorBasics --- x/staking/keeper/old_validator_test.go | 99 -------------------------- x/staking/keeper/validator_test.go | 99 ++++++++++++++++++++++++++ 2 files changed, 99 insertions(+), 99 deletions(-) diff --git a/x/staking/keeper/old_validator_test.go b/x/staking/keeper/old_validator_test.go index a7187b23cfca..0b4d4fc273ee 100644 --- a/x/staking/keeper/old_validator_test.go +++ b/x/staking/keeper/old_validator_test.go @@ -14,105 +14,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/staking/types" ) -// This function tests UpdateValidator, GetValidator, GetLastValidators, RemoveValidator -func TestValidatorBasics(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) - - //construct the validators - var validators [3]types.Validator - powers := []int64{9, 8, 7} - for i, power := range powers { - validators[i] = types.NewValidator(addrVals[i], PKs[i], types.Description{}) - validators[i].Status = sdk.Unbonded - validators[i].Tokens = sdk.ZeroInt() - tokens := sdk.TokensFromConsensusPower(power) - - validators[i], _ = validators[i].AddTokensFromDel(tokens) - } - assert.Equal(t, sdk.TokensFromConsensusPower(9), validators[0].Tokens) - assert.Equal(t, sdk.TokensFromConsensusPower(8), validators[1].Tokens) - assert.Equal(t, sdk.TokensFromConsensusPower(7), validators[2].Tokens) - - // check the empty keeper first - _, found := keeper.GetValidator(ctx, addrVals[0]) - require.False(t, found) - resVals := keeper.GetLastValidators(ctx) - require.Zero(t, len(resVals)) - - resVals = keeper.GetValidators(ctx, 2) - require.Zero(t, len(resVals)) - - // set and retrieve a record - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], true) - keeper.SetValidatorByConsAddr(ctx, validators[0]) - resVal, found := keeper.GetValidator(ctx, addrVals[0]) - require.True(t, found) - assert.True(ValEq(t, validators[0], resVal)) - - // retrieve from consensus - resVal, found = keeper.GetValidatorByConsAddr(ctx, sdk.ConsAddress(PKs[0].Address())) - require.True(t, found) - assert.True(ValEq(t, validators[0], resVal)) - resVal, found = keeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(PKs[0])) - require.True(t, found) - assert.True(ValEq(t, validators[0], resVal)) - - resVals = keeper.GetLastValidators(ctx) - require.Equal(t, 1, len(resVals)) - assert.True(ValEq(t, validators[0], resVals[0])) - assert.Equal(t, sdk.Bonded, validators[0].Status) - assert.True(sdk.IntEq(t, sdk.TokensFromConsensusPower(9), validators[0].BondedTokens())) - - // modify a records, save, and retrieve - validators[0].Status = sdk.Bonded - validators[0].Tokens = sdk.TokensFromConsensusPower(10) - validators[0].DelegatorShares = validators[0].Tokens.ToDec() - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], true) - resVal, found = keeper.GetValidator(ctx, addrVals[0]) - require.True(t, found) - assert.True(ValEq(t, validators[0], resVal)) - - resVals = keeper.GetLastValidators(ctx) - require.Equal(t, 1, len(resVals)) - assert.True(ValEq(t, validators[0], resVals[0])) - - // add other validators - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], true) - validators[2] = TestingUpdateValidator(keeper, ctx, validators[2], true) - resVal, found = keeper.GetValidator(ctx, addrVals[1]) - require.True(t, found) - assert.True(ValEq(t, validators[1], resVal)) - resVal, found = keeper.GetValidator(ctx, addrVals[2]) - require.True(t, found) - assert.True(ValEq(t, validators[2], resVal)) - - resVals = keeper.GetLastValidators(ctx) - require.Equal(t, 3, len(resVals)) - assert.True(ValEq(t, validators[0], resVals[0])) // order doesn't matter here - assert.True(ValEq(t, validators[1], resVals[1])) - assert.True(ValEq(t, validators[2], resVals[2])) - - // remove a record - - // shouldn't be able to remove if status is not unbonded - assert.PanicsWithValue(t, - "cannot call RemoveValidator on bonded or unbonding validators", - func() { keeper.RemoveValidator(ctx, validators[1].OperatorAddress) }) - - // shouldn't be able to remove if there are still tokens left - validators[1].Status = sdk.Unbonded - keeper.SetValidator(ctx, validators[1]) - assert.PanicsWithValue(t, - "attempting to remove a validator which still contains tokens", - func() { keeper.RemoveValidator(ctx, validators[1].OperatorAddress) }) - - validators[1].Tokens = sdk.ZeroInt() // ...remove all tokens - keeper.SetValidator(ctx, validators[1]) // ...set the validator - keeper.RemoveValidator(ctx, validators[1].OperatorAddress) // Now it can be removed. - _, found = keeper.GetValidator(ctx, addrVals[1]) - require.False(t, found) -} - // test how the validators are sorted, tests GetBondedValidatorsByPower func TestGetValidatorSortingUnmixed(t *testing.T) { ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) diff --git a/x/staking/keeper/validator_test.go b/x/staking/keeper/validator_test.go index c303d2029a46..4d866ab6868d 100644 --- a/x/staking/keeper/validator_test.go +++ b/x/staking/keeper/validator_test.go @@ -212,3 +212,102 @@ func TestSlashToZeroPowerRemoved(t *testing.T) { validator, _ = app.StakingKeeper.GetValidator(ctx, addrVals[0]) require.Equal(t, validator.GetStatus(), sdk.Unbonding) } + +// This function tests UpdateValidator, GetValidator, GetLastValidators, RemoveValidator +func TestValidatorBasics(t *testing.T) { + app, ctx, _, addrVals := bootstrapValidatorTest(t, 1000, 20) + + //construct the validators + var validators [3]types.Validator + powers := []int64{9, 8, 7} + for i, power := range powers { + validators[i] = types.NewValidator(addrVals[i], PKs[i], types.Description{}) + validators[i].Status = sdk.Unbonded + validators[i].Tokens = sdk.ZeroInt() + tokens := sdk.TokensFromConsensusPower(power) + + validators[i], _ = validators[i].AddTokensFromDel(tokens) + } + assert.Equal(t, sdk.TokensFromConsensusPower(9), validators[0].Tokens) + assert.Equal(t, sdk.TokensFromConsensusPower(8), validators[1].Tokens) + assert.Equal(t, sdk.TokensFromConsensusPower(7), validators[2].Tokens) + + // check the empty keeper first + _, found := app.StakingKeeper.GetValidator(ctx, addrVals[0]) + require.False(t, found) + resVals := app.StakingKeeper.GetLastValidators(ctx) + require.Zero(t, len(resVals)) + + resVals = app.StakingKeeper.GetValidators(ctx, 2) + require.Zero(t, len(resVals)) + + // set and retrieve a record + validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], true) + app.StakingKeeper.SetValidatorByConsAddr(ctx, validators[0]) + resVal, found := app.StakingKeeper.GetValidator(ctx, addrVals[0]) + require.True(t, found) + assert.True(ValEq(t, validators[0], resVal)) + + // retrieve from consensus + resVal, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, sdk.ConsAddress(PKs[0].Address())) + require.True(t, found) + assert.True(ValEq(t, validators[0], resVal)) + resVal, found = app.StakingKeeper.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(PKs[0])) + require.True(t, found) + assert.True(ValEq(t, validators[0], resVal)) + + resVals = app.StakingKeeper.GetLastValidators(ctx) + require.Equal(t, 1, len(resVals)) + assert.True(ValEq(t, validators[0], resVals[0])) + assert.Equal(t, sdk.Bonded, validators[0].Status) + assert.True(sdk.IntEq(t, sdk.TokensFromConsensusPower(9), validators[0].BondedTokens())) + + // modify a records, save, and retrieve + validators[0].Status = sdk.Bonded + validators[0].Tokens = sdk.TokensFromConsensusPower(10) + validators[0].DelegatorShares = validators[0].Tokens.ToDec() + validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], true) + resVal, found = app.StakingKeeper.GetValidator(ctx, addrVals[0]) + require.True(t, found) + assert.True(ValEq(t, validators[0], resVal)) + + resVals = app.StakingKeeper.GetLastValidators(ctx) + require.Equal(t, 1, len(resVals)) + assert.True(ValEq(t, validators[0], resVals[0])) + + // add other validators + validators[1] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[1], true) + validators[2] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[2], true) + resVal, found = app.StakingKeeper.GetValidator(ctx, addrVals[1]) + require.True(t, found) + assert.True(ValEq(t, validators[1], resVal)) + resVal, found = app.StakingKeeper.GetValidator(ctx, addrVals[2]) + require.True(t, found) + assert.True(ValEq(t, validators[2], resVal)) + + resVals = app.StakingKeeper.GetLastValidators(ctx) + require.Equal(t, 3, len(resVals)) + assert.True(ValEq(t, validators[0], resVals[0])) // order doesn't matter here + assert.True(ValEq(t, validators[1], resVals[1])) + assert.True(ValEq(t, validators[2], resVals[2])) + + // remove a record + + // shouldn't be able to remove if status is not unbonded + assert.PanicsWithValue(t, + "cannot call RemoveValidator on bonded or unbonding validators", + func() { app.StakingKeeper.RemoveValidator(ctx, validators[1].OperatorAddress) }) + + // shouldn't be able to remove if there are still tokens left + validators[1].Status = sdk.Unbonded + app.StakingKeeper.SetValidator(ctx, validators[1]) + assert.PanicsWithValue(t, + "attempting to remove a validator which still contains tokens", + func() { app.StakingKeeper.RemoveValidator(ctx, validators[1].OperatorAddress) }) + + validators[1].Tokens = sdk.ZeroInt() // ...remove all tokens + app.StakingKeeper.SetValidator(ctx, validators[1]) // ...set the validator + app.StakingKeeper.RemoveValidator(ctx, validators[1].OperatorAddress) // Now it can be removed. + _, found = app.StakingKeeper.GetValidator(ctx, addrVals[1]) + require.False(t, found) +} From 460619fa29e14a85f5621d24cc2cd5eaec9dafff Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Tue, 25 Feb 2020 13:27:05 +0100 Subject: [PATCH 46/90] refactro TestGetValidatorSortingUnmixed to simapp --- x/staking/keeper/old_validator_test.go | 81 -------------------------- x/staking/keeper/validator_test.go | 81 ++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 81 deletions(-) diff --git a/x/staking/keeper/old_validator_test.go b/x/staking/keeper/old_validator_test.go index 0b4d4fc273ee..6745217a6ea5 100644 --- a/x/staking/keeper/old_validator_test.go +++ b/x/staking/keeper/old_validator_test.go @@ -14,87 +14,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/staking/types" ) -// test how the validators are sorted, tests GetBondedValidatorsByPower -func TestGetValidatorSortingUnmixed(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) - - // initialize some validators into the state - amts := []int64{ - 0, - 100 * sdk.PowerReduction.Int64(), - 1 * sdk.PowerReduction.Int64(), - 400 * sdk.PowerReduction.Int64(), - 200 * sdk.PowerReduction.Int64()} - n := len(amts) - var validators [5]types.Validator - for i, amt := range amts { - validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) - validators[i].Status = sdk.Bonded - validators[i].Tokens = sdk.NewInt(amt) - validators[i].DelegatorShares = sdk.NewDec(amt) - TestingUpdateValidator(keeper, ctx, validators[i], true) - } - - // first make sure everything made it in to the gotValidator group - resValidators := keeper.GetBondedValidatorsByPower(ctx) - assert.Equal(t, n, len(resValidators)) - assert.Equal(t, sdk.NewInt(400).Mul(sdk.PowerReduction), resValidators[0].BondedTokens(), "%v", resValidators) - assert.Equal(t, sdk.NewInt(200).Mul(sdk.PowerReduction), resValidators[1].BondedTokens(), "%v", resValidators) - assert.Equal(t, sdk.NewInt(100).Mul(sdk.PowerReduction), resValidators[2].BondedTokens(), "%v", resValidators) - assert.Equal(t, sdk.NewInt(1).Mul(sdk.PowerReduction), resValidators[3].BondedTokens(), "%v", resValidators) - assert.Equal(t, sdk.NewInt(0), resValidators[4].BondedTokens(), "%v", resValidators) - assert.Equal(t, validators[3].OperatorAddress, resValidators[0].OperatorAddress, "%v", resValidators) - assert.Equal(t, validators[4].OperatorAddress, resValidators[1].OperatorAddress, "%v", resValidators) - assert.Equal(t, validators[1].OperatorAddress, resValidators[2].OperatorAddress, "%v", resValidators) - assert.Equal(t, validators[2].OperatorAddress, resValidators[3].OperatorAddress, "%v", resValidators) - assert.Equal(t, validators[0].OperatorAddress, resValidators[4].OperatorAddress, "%v", resValidators) - - // test a basic increase in voting power - validators[3].Tokens = sdk.NewInt(500).Mul(sdk.PowerReduction) - TestingUpdateValidator(keeper, ctx, validators[3], true) - resValidators = keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, len(resValidators), n) - assert.True(ValEq(t, validators[3], resValidators[0])) - - // test a decrease in voting power - validators[3].Tokens = sdk.NewInt(300).Mul(sdk.PowerReduction) - TestingUpdateValidator(keeper, ctx, validators[3], true) - resValidators = keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, len(resValidators), n) - assert.True(ValEq(t, validators[3], resValidators[0])) - assert.True(ValEq(t, validators[4], resValidators[1])) - - // test equal voting power, different age - validators[3].Tokens = sdk.NewInt(200).Mul(sdk.PowerReduction) - ctx = ctx.WithBlockHeight(10) - TestingUpdateValidator(keeper, ctx, validators[3], true) - resValidators = keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, len(resValidators), n) - assert.True(ValEq(t, validators[3], resValidators[0])) - assert.True(ValEq(t, validators[4], resValidators[1])) - - // no change in voting power - no change in sort - ctx = ctx.WithBlockHeight(20) - TestingUpdateValidator(keeper, ctx, validators[4], true) - resValidators = keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, len(resValidators), n) - assert.True(ValEq(t, validators[3], resValidators[0])) - assert.True(ValEq(t, validators[4], resValidators[1])) - - // change in voting power of both validators, both still in v-set, no age change - validators[3].Tokens = sdk.NewInt(300).Mul(sdk.PowerReduction) - validators[4].Tokens = sdk.NewInt(300).Mul(sdk.PowerReduction) - TestingUpdateValidator(keeper, ctx, validators[3], true) - resValidators = keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, len(resValidators), n) - ctx = ctx.WithBlockHeight(30) - TestingUpdateValidator(keeper, ctx, validators[4], true) - resValidators = keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, len(resValidators), n, "%v", resValidators) - assert.True(ValEq(t, validators[3], resValidators[0])) - assert.True(ValEq(t, validators[4], resValidators[1])) -} - func TestGetValidatorSortingMixed(t *testing.T) { ctx, _, bk, keeper, _ := CreateTestInput(t, false, 1000) bondedPool := keeper.GetBondedPool(ctx) diff --git a/x/staking/keeper/validator_test.go b/x/staking/keeper/validator_test.go index 4d866ab6868d..4a2a8a546c4b 100644 --- a/x/staking/keeper/validator_test.go +++ b/x/staking/keeper/validator_test.go @@ -311,3 +311,84 @@ func TestValidatorBasics(t *testing.T) { _, found = app.StakingKeeper.GetValidator(ctx, addrVals[1]) require.False(t, found) } + +// test how the validators are sorted, tests GetBondedValidatorsByPower +func TestGetValidatorSortingUnmixed(t *testing.T) { + app, ctx, addrs, _ := bootstrapValidatorTest(t, 1000, 20) + + // initialize some validators into the state + amts := []int64{ + 0, + 100 * sdk.PowerReduction.Int64(), + 1 * sdk.PowerReduction.Int64(), + 400 * sdk.PowerReduction.Int64(), + 200 * sdk.PowerReduction.Int64()} + n := len(amts) + var validators [5]types.Validator + for i, amt := range amts { + validators[i] = types.NewValidator(sdk.ValAddress(addrs[i]), PKs[i], types.Description{}) + validators[i].Status = sdk.Bonded + validators[i].Tokens = sdk.NewInt(amt) + validators[i].DelegatorShares = sdk.NewDec(amt) + keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[i], true) + } + + // first make sure everything made it in to the gotValidator group + resValidators := app.StakingKeeper.GetBondedValidatorsByPower(ctx) + assert.Equal(t, n, len(resValidators)) + assert.Equal(t, sdk.NewInt(400).Mul(sdk.PowerReduction), resValidators[0].BondedTokens(), "%v", resValidators) + assert.Equal(t, sdk.NewInt(200).Mul(sdk.PowerReduction), resValidators[1].BondedTokens(), "%v", resValidators) + assert.Equal(t, sdk.NewInt(100).Mul(sdk.PowerReduction), resValidators[2].BondedTokens(), "%v", resValidators) + assert.Equal(t, sdk.NewInt(1).Mul(sdk.PowerReduction), resValidators[3].BondedTokens(), "%v", resValidators) + assert.Equal(t, sdk.NewInt(0), resValidators[4].BondedTokens(), "%v", resValidators) + assert.Equal(t, validators[3].OperatorAddress, resValidators[0].OperatorAddress, "%v", resValidators) + assert.Equal(t, validators[4].OperatorAddress, resValidators[1].OperatorAddress, "%v", resValidators) + assert.Equal(t, validators[1].OperatorAddress, resValidators[2].OperatorAddress, "%v", resValidators) + assert.Equal(t, validators[2].OperatorAddress, resValidators[3].OperatorAddress, "%v", resValidators) + assert.Equal(t, validators[0].OperatorAddress, resValidators[4].OperatorAddress, "%v", resValidators) + + // test a basic increase in voting power + validators[3].Tokens = sdk.NewInt(500).Mul(sdk.PowerReduction) + keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[3], true) + resValidators = app.StakingKeeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, len(resValidators), n) + assert.True(ValEq(t, validators[3], resValidators[0])) + + // test a decrease in voting power + validators[3].Tokens = sdk.NewInt(300).Mul(sdk.PowerReduction) + keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[3], true) + resValidators = app.StakingKeeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, len(resValidators), n) + assert.True(ValEq(t, validators[3], resValidators[0])) + assert.True(ValEq(t, validators[4], resValidators[1])) + + // test equal voting power, different age + validators[3].Tokens = sdk.NewInt(200).Mul(sdk.PowerReduction) + ctx = ctx.WithBlockHeight(10) + keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[3], true) + resValidators = app.StakingKeeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, len(resValidators), n) + assert.True(ValEq(t, validators[3], resValidators[0])) + assert.True(ValEq(t, validators[4], resValidators[1])) + + // no change in voting power - no change in sort + ctx = ctx.WithBlockHeight(20) + keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[4], true) + resValidators = app.StakingKeeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, len(resValidators), n) + assert.True(ValEq(t, validators[3], resValidators[0])) + assert.True(ValEq(t, validators[4], resValidators[1])) + + // change in voting power of both validators, both still in v-set, no age change + validators[3].Tokens = sdk.NewInt(300).Mul(sdk.PowerReduction) + validators[4].Tokens = sdk.NewInt(300).Mul(sdk.PowerReduction) + keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[3], true) + resValidators = app.StakingKeeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, len(resValidators), n) + ctx = ctx.WithBlockHeight(30) + keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[4], true) + resValidators = app.StakingKeeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, len(resValidators), n, "%v", resValidators) + assert.True(ValEq(t, validators[3], resValidators[0])) + assert.True(ValEq(t, validators[4], resValidators[1])) +} From c7d68c59a94b876643a0a302cba10e48e8f70361 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Tue, 25 Feb 2020 13:38:27 +0100 Subject: [PATCH 47/90] refactor TestGetValidatorSortingMixed test to simap --- x/staking/keeper/old_validator_test.go | 58 -------------------------- x/staking/keeper/validator_test.go | 58 ++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 58 deletions(-) diff --git a/x/staking/keeper/old_validator_test.go b/x/staking/keeper/old_validator_test.go index 6745217a6ea5..9f7a8bd593e0 100644 --- a/x/staking/keeper/old_validator_test.go +++ b/x/staking/keeper/old_validator_test.go @@ -14,64 +14,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/staking/types" ) -func TestGetValidatorSortingMixed(t *testing.T) { - ctx, _, bk, keeper, _ := CreateTestInput(t, false, 1000) - bondedPool := keeper.GetBondedPool(ctx) - notBondedPool := keeper.GetNotBondedPool(ctx) - - bk.SetBalances(ctx, bondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), sdk.TokensFromConsensusPower(501)))) - bk.SetBalances(ctx, notBondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(keeper.BondDenom(ctx), sdk.TokensFromConsensusPower(0)))) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) - - // now 2 max resValidators - params := keeper.GetParams(ctx) - params.MaxValidators = 2 - keeper.SetParams(ctx, params) - - // initialize some validators into the state - amts := []int64{ - 0, - 100 * sdk.PowerReduction.Int64(), - 1 * sdk.PowerReduction.Int64(), - 400 * sdk.PowerReduction.Int64(), - 200 * sdk.PowerReduction.Int64()} - - var validators [5]types.Validator - for i, amt := range amts { - validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) - validators[i].DelegatorShares = sdk.NewDec(amt) - validators[i].Status = sdk.Bonded - validators[i].Tokens = sdk.NewInt(amt) - TestingUpdateValidator(keeper, ctx, validators[i], true) - } - - val0, found := keeper.GetValidator(ctx, sdk.ValAddress(Addrs[0])) - require.True(t, found) - val1, found := keeper.GetValidator(ctx, sdk.ValAddress(Addrs[1])) - require.True(t, found) - val2, found := keeper.GetValidator(ctx, sdk.ValAddress(Addrs[2])) - require.True(t, found) - val3, found := keeper.GetValidator(ctx, sdk.ValAddress(Addrs[3])) - require.True(t, found) - val4, found := keeper.GetValidator(ctx, sdk.ValAddress(Addrs[4])) - require.True(t, found) - require.Equal(t, sdk.Bonded, val0.Status) - require.Equal(t, sdk.Unbonding, val1.Status) - require.Equal(t, sdk.Unbonding, val2.Status) - require.Equal(t, sdk.Bonded, val3.Status) - require.Equal(t, sdk.Bonded, val4.Status) - - // first make sure everything made it in to the gotValidator group - resValidators := keeper.GetBondedValidatorsByPower(ctx) - // The validators returned should match the max validators - assert.Equal(t, 2, len(resValidators)) - assert.Equal(t, sdk.NewInt(400).Mul(sdk.PowerReduction), resValidators[0].BondedTokens(), "%v", resValidators) - assert.Equal(t, sdk.NewInt(200).Mul(sdk.PowerReduction), resValidators[1].BondedTokens(), "%v", resValidators) - assert.Equal(t, validators[3].OperatorAddress, resValidators[0].OperatorAddress, "%v", resValidators) - assert.Equal(t, validators[4].OperatorAddress, resValidators[1].OperatorAddress, "%v", resValidators) -} - // TODO separate out into multiple tests func TestGetValidatorsEdgeCases(t *testing.T) { ctx, _, bk, keeper, _ := CreateTestInput(t, false, 1000) diff --git a/x/staking/keeper/validator_test.go b/x/staking/keeper/validator_test.go index 4a2a8a546c4b..c72f560d8fb3 100644 --- a/x/staking/keeper/validator_test.go +++ b/x/staking/keeper/validator_test.go @@ -392,3 +392,61 @@ func TestGetValidatorSortingUnmixed(t *testing.T) { assert.True(ValEq(t, validators[3], resValidators[0])) assert.True(ValEq(t, validators[4], resValidators[1])) } + +func TestGetValidatorSortingMixed(t *testing.T) { + app, ctx, addrs, _ := bootstrapValidatorTest(t, 1000, 20) + bondedPool := app.StakingKeeper.GetBondedPool(ctx) + notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) + + app.BankKeeper.SetBalances(ctx, bondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.TokensFromConsensusPower(501)))) + app.BankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), sdk.TokensFromConsensusPower(0)))) + app.SupplyKeeper.SetModuleAccount(ctx, notBondedPool) + app.SupplyKeeper.SetModuleAccount(ctx, bondedPool) + + // now 2 max resValidators + params := app.StakingKeeper.GetParams(ctx) + params.MaxValidators = 2 + app.StakingKeeper.SetParams(ctx, params) + + // initialize some validators into the state + amts := []int64{ + 0, + 100 * sdk.PowerReduction.Int64(), + 1 * sdk.PowerReduction.Int64(), + 400 * sdk.PowerReduction.Int64(), + 200 * sdk.PowerReduction.Int64()} + + var validators [5]types.Validator + for i, amt := range amts { + validators[i] = types.NewValidator(sdk.ValAddress(addrs[i]), PKs[i], types.Description{}) + validators[i].DelegatorShares = sdk.NewDec(amt) + validators[i].Status = sdk.Bonded + validators[i].Tokens = sdk.NewInt(amt) + keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[i], true) + } + + val0, found := app.StakingKeeper.GetValidator(ctx, sdk.ValAddress(addrs[0])) + require.True(t, found) + val1, found := app.StakingKeeper.GetValidator(ctx, sdk.ValAddress(addrs[1])) + require.True(t, found) + val2, found := app.StakingKeeper.GetValidator(ctx, sdk.ValAddress(addrs[2])) + require.True(t, found) + val3, found := app.StakingKeeper.GetValidator(ctx, sdk.ValAddress(addrs[3])) + require.True(t, found) + val4, found := app.StakingKeeper.GetValidator(ctx, sdk.ValAddress(addrs[4])) + require.True(t, found) + require.Equal(t, sdk.Bonded, val0.Status) + require.Equal(t, sdk.Unbonding, val1.Status) + require.Equal(t, sdk.Unbonding, val2.Status) + require.Equal(t, sdk.Bonded, val3.Status) + require.Equal(t, sdk.Bonded, val4.Status) + + // first make sure everything made it in to the gotValidator group + resValidators := app.StakingKeeper.GetBondedValidatorsByPower(ctx) + // The validators returned should match the max validators + assert.Equal(t, 2, len(resValidators)) + assert.Equal(t, sdk.NewInt(400).Mul(sdk.PowerReduction), resValidators[0].BondedTokens(), "%v", resValidators) + assert.Equal(t, sdk.NewInt(200).Mul(sdk.PowerReduction), resValidators[1].BondedTokens(), "%v", resValidators) + assert.Equal(t, validators[3].OperatorAddress, resValidators[0].OperatorAddress, "%v", resValidators) + assert.Equal(t, validators[4].OperatorAddress, resValidators[1].OperatorAddress, "%v", resValidators) +} From 99554926e87ebfa38b1afa83c3a52ebd578ffbf9 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Tue, 25 Feb 2020 13:45:29 +0100 Subject: [PATCH 48/90] refctor TestGetValidatorsEdgeCases to use simapp --- x/staking/keeper/old_validator_test.go | 116 ------------------------ x/staking/keeper/validator_test.go | 118 +++++++++++++++++++++++++ 2 files changed, 118 insertions(+), 116 deletions(-) diff --git a/x/staking/keeper/old_validator_test.go b/x/staking/keeper/old_validator_test.go index 9f7a8bd593e0..d959b9f4b373 100644 --- a/x/staking/keeper/old_validator_test.go +++ b/x/staking/keeper/old_validator_test.go @@ -14,122 +14,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/staking/types" ) -// TODO separate out into multiple tests -func TestGetValidatorsEdgeCases(t *testing.T) { - ctx, _, bk, keeper, _ := CreateTestInput(t, false, 1000) - - // set max validators to 2 - params := keeper.GetParams(ctx) - nMax := uint32(2) - params.MaxValidators = nMax - keeper.SetParams(ctx, params) - - // initialize some validators into the state - powers := []int64{0, 100, 400, 400} - var validators [4]types.Validator - for i, power := range powers { - moniker := fmt.Sprintf("val#%d", int64(i)) - validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{Moniker: moniker}) - - tokens := sdk.TokensFromConsensusPower(power) - validators[i], _ = validators[i].AddTokensFromDel(tokens) - - notBondedPool := keeper.GetNotBondedPool(ctx) - balances := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) - require.NoError(t, bk.SetBalances(ctx, notBondedPool.GetAddress(), balances.Add(sdk.NewCoin(params.BondDenom, tokens)))) - - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - validators[i] = TestingUpdateValidator(keeper, ctx, validators[i], true) - } - - // ensure that the first two bonded validators are the largest validators - resValidators := keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, nMax, uint32(len(resValidators))) - assert.True(ValEq(t, validators[2], resValidators[0])) - assert.True(ValEq(t, validators[3], resValidators[1])) - - // delegate 500 tokens to validator 0 - keeper.DeleteValidatorByPowerIndex(ctx, validators[0]) - delTokens := sdk.TokensFromConsensusPower(500) - validators[0], _ = validators[0].AddTokensFromDel(delTokens) - notBondedPool := keeper.GetNotBondedPool(ctx) - - newTokens := sdk.NewCoins() - balances := bk.GetAllBalances(ctx, notBondedPool.GetAddress()) - require.NoError(t, bk.SetBalances(ctx, notBondedPool.GetAddress(), balances.Add(newTokens...))) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - // test that the two largest validators are - // a) validator 0 with 500 tokens - // b) validator 2 with 400 tokens (delegated before validator 3) - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], true) - resValidators = keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, nMax, uint32(len(resValidators))) - assert.True(ValEq(t, validators[0], resValidators[0])) - assert.True(ValEq(t, validators[2], resValidators[1])) - - // A validator which leaves the bonded validator set due to a decrease in voting power, - // then increases to the original voting power, does not get its spot back in the - // case of a tie. - // - // Order of operations for this test: - // - validator 3 enter validator set with 1 new token - // - validator 3 removed validator set by removing 201 tokens (validator 2 enters) - // - validator 3 adds 200 tokens (equal to validator 2 now) and does not get its spot back - - // validator 3 enters bonded validator set - ctx = ctx.WithBlockHeight(40) - - validators[3] = keeper.mustGetValidator(ctx, validators[3].OperatorAddress) - keeper.DeleteValidatorByPowerIndex(ctx, validators[3]) - validators[3], _ = validators[3].AddTokensFromDel(sdk.TokensFromConsensusPower(1)) - - notBondedPool = keeper.GetNotBondedPool(ctx) - newTokens = sdk.NewCoins(sdk.NewCoin(params.BondDenom, sdk.TokensFromConsensusPower(1))) - balances = bk.GetAllBalances(ctx, notBondedPool.GetAddress()) - require.NoError(t, bk.SetBalances(ctx, notBondedPool.GetAddress(), balances.Add(newTokens...))) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - validators[3] = TestingUpdateValidator(keeper, ctx, validators[3], true) - resValidators = keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, nMax, uint32(len(resValidators))) - assert.True(ValEq(t, validators[0], resValidators[0])) - assert.True(ValEq(t, validators[3], resValidators[1])) - - // validator 3 kicked out temporarily - keeper.DeleteValidatorByPowerIndex(ctx, validators[3]) - rmTokens := validators[3].TokensFromShares(sdk.NewDec(201)).TruncateInt() - validators[3], _ = validators[3].RemoveDelShares(sdk.NewDec(201)) - - bondedPool := keeper.GetBondedPool(ctx) - balances = bk.GetAllBalances(ctx, bondedPool.GetAddress()) - require.NoError(t, bk.SetBalances(ctx, bondedPool.GetAddress(), balances.Add(sdk.NewCoin(params.BondDenom, rmTokens)))) - keeper.supplyKeeper.SetModuleAccount(ctx, bondedPool) - - validators[3] = TestingUpdateValidator(keeper, ctx, validators[3], true) - resValidators = keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, nMax, uint32(len(resValidators))) - assert.True(ValEq(t, validators[0], resValidators[0])) - assert.True(ValEq(t, validators[2], resValidators[1])) - - // validator 3 does not get spot back - keeper.DeleteValidatorByPowerIndex(ctx, validators[3]) - validators[3], _ = validators[3].AddTokensFromDel(sdk.NewInt(200)) - - notBondedPool = keeper.GetNotBondedPool(ctx) - balances = bk.GetAllBalances(ctx, notBondedPool.GetAddress()) - require.NoError(t, bk.SetBalances(ctx, notBondedPool.GetAddress(), balances.Add(sdk.NewCoin(params.BondDenom, sdk.NewInt(200))))) - keeper.supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - validators[3] = TestingUpdateValidator(keeper, ctx, validators[3], true) - resValidators = keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, nMax, uint32(len(resValidators))) - assert.True(ValEq(t, validators[0], resValidators[0])) - assert.True(ValEq(t, validators[2], resValidators[1])) - _, exists := keeper.GetValidator(ctx, validators[3].OperatorAddress) - require.True(t, exists) -} - func TestValidatorBondHeight(t *testing.T) { ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) diff --git a/x/staking/keeper/validator_test.go b/x/staking/keeper/validator_test.go index c72f560d8fb3..8a122c6c3748 100644 --- a/x/staking/keeper/validator_test.go +++ b/x/staking/keeper/validator_test.go @@ -450,3 +450,121 @@ func TestGetValidatorSortingMixed(t *testing.T) { assert.Equal(t, validators[3].OperatorAddress, resValidators[0].OperatorAddress, "%v", resValidators) assert.Equal(t, validators[4].OperatorAddress, resValidators[1].OperatorAddress, "%v", resValidators) } + +// TODO separate out into multiple tests +func TestGetValidatorsEdgeCases(t *testing.T) { + app, ctx, addrs, _ := bootstrapValidatorTest(t, 1000, 20) + + // set max validators to 2 + params := app.StakingKeeper.GetParams(ctx) + nMax := uint32(2) + params.MaxValidators = nMax + app.StakingKeeper.SetParams(ctx, params) + + // initialize some validators into the state + powers := []int64{0, 100, 400, 400} + var validators [4]types.Validator + for i, power := range powers { + moniker := fmt.Sprintf("val#%d", int64(i)) + validators[i] = types.NewValidator(sdk.ValAddress(addrs[i]), PKs[i], types.Description{Moniker: moniker}) + + tokens := sdk.TokensFromConsensusPower(power) + validators[i], _ = validators[i].AddTokensFromDel(tokens) + + notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) + balances := app.BankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress()) + require.NoError(t, app.BankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), balances.Add(sdk.NewCoin(params.BondDenom, tokens)))) + + app.SupplyKeeper.SetModuleAccount(ctx, notBondedPool) + validators[i] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[i], true) + } + + // ensure that the first two bonded validators are the largest validators + resValidators := app.StakingKeeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, nMax, uint32(len(resValidators))) + assert.True(ValEq(t, validators[2], resValidators[0])) + assert.True(ValEq(t, validators[3], resValidators[1])) + + // delegate 500 tokens to validator 0 + app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validators[0]) + delTokens := sdk.TokensFromConsensusPower(500) + validators[0], _ = validators[0].AddTokensFromDel(delTokens) + notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) + + newTokens := sdk.NewCoins() + balances := app.BankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress()) + require.NoError(t, app.BankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), balances.Add(newTokens...))) + app.SupplyKeeper.SetModuleAccount(ctx, notBondedPool) + + // test that the two largest validators are + // a) validator 0 with 500 tokens + // b) validator 2 with 400 tokens (delegated before validator 3) + validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], true) + resValidators = app.StakingKeeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, nMax, uint32(len(resValidators))) + assert.True(ValEq(t, validators[0], resValidators[0])) + assert.True(ValEq(t, validators[2], resValidators[1])) + + // A validator which leaves the bonded validator set due to a decrease in voting power, + // then increases to the original voting power, does not get its spot back in the + // case of a tie. + // + // Order of operations for this test: + // - validator 3 enter validator set with 1 new token + // - validator 3 removed validator set by removing 201 tokens (validator 2 enters) + // - validator 3 adds 200 tokens (equal to validator 2 now) and does not get its spot back + + // validator 3 enters bonded validator set + ctx = ctx.WithBlockHeight(40) + + var found bool + validators[3], found = app.StakingKeeper.GetValidator(ctx, validators[3].OperatorAddress) + assert.True(t, found) + app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validators[3]) + validators[3], _ = validators[3].AddTokensFromDel(sdk.TokensFromConsensusPower(1)) + + notBondedPool = app.StakingKeeper.GetNotBondedPool(ctx) + newTokens = sdk.NewCoins(sdk.NewCoin(params.BondDenom, sdk.TokensFromConsensusPower(1))) + balances = app.BankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress()) + require.NoError(t, app.BankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), balances.Add(newTokens...))) + app.SupplyKeeper.SetModuleAccount(ctx, notBondedPool) + + validators[3] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[3], true) + resValidators = app.StakingKeeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, nMax, uint32(len(resValidators))) + assert.True(ValEq(t, validators[0], resValidators[0])) + assert.True(ValEq(t, validators[3], resValidators[1])) + + // validator 3 kicked out temporarily + app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validators[3]) + rmTokens := validators[3].TokensFromShares(sdk.NewDec(201)).TruncateInt() + validators[3], _ = validators[3].RemoveDelShares(sdk.NewDec(201)) + + bondedPool := app.StakingKeeper.GetBondedPool(ctx) + balances = app.BankKeeper.GetAllBalances(ctx, bondedPool.GetAddress()) + require.NoError(t, app.BankKeeper.SetBalances(ctx, bondedPool.GetAddress(), balances.Add(sdk.NewCoin(params.BondDenom, rmTokens)))) + app.SupplyKeeper.SetModuleAccount(ctx, bondedPool) + + validators[3] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[3], true) + resValidators = app.StakingKeeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, nMax, uint32(len(resValidators))) + assert.True(ValEq(t, validators[0], resValidators[0])) + assert.True(ValEq(t, validators[2], resValidators[1])) + + // validator 3 does not get spot back + app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validators[3]) + validators[3], _ = validators[3].AddTokensFromDel(sdk.NewInt(200)) + + notBondedPool = app.StakingKeeper.GetNotBondedPool(ctx) + balances = app.BankKeeper.GetAllBalances(ctx, notBondedPool.GetAddress()) + require.NoError(t, app.BankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), balances.Add(sdk.NewCoin(params.BondDenom, sdk.NewInt(200))))) + app.SupplyKeeper.SetModuleAccount(ctx, notBondedPool) + + validators[3] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[3], true) + resValidators = app.StakingKeeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, nMax, uint32(len(resValidators))) + assert.True(ValEq(t, validators[0], resValidators[0])) + assert.True(ValEq(t, validators[2], resValidators[1])) + _, exists := app.StakingKeeper.GetValidator(ctx, validators[3].OperatorAddress) + require.True(t, exists) +} From 96216c3dac388648cf66edf39fd626ef22703823 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Tue, 25 Feb 2020 13:51:48 +0100 Subject: [PATCH 49/90] make test TestValidatorBondHeight pass --- x/staking/keeper/old_validator_test.go | 47 -------------------------- x/staking/keeper/validator_test.go | 47 ++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 47 deletions(-) diff --git a/x/staking/keeper/old_validator_test.go b/x/staking/keeper/old_validator_test.go index d959b9f4b373..729903548d79 100644 --- a/x/staking/keeper/old_validator_test.go +++ b/x/staking/keeper/old_validator_test.go @@ -14,53 +14,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/staking/types" ) -func TestValidatorBondHeight(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) - - // now 2 max resValidators - params := keeper.GetParams(ctx) - params.MaxValidators = 2 - keeper.SetParams(ctx, params) - - // initialize some validators into the state - var validators [3]types.Validator - validators[0] = types.NewValidator(sdk.ValAddress(PKs[0].Address().Bytes()), PKs[0], types.Description{}) - validators[1] = types.NewValidator(sdk.ValAddress(Addrs[1]), PKs[1], types.Description{}) - validators[2] = types.NewValidator(sdk.ValAddress(Addrs[2]), PKs[2], types.Description{}) - - tokens0 := sdk.TokensFromConsensusPower(200) - tokens1 := sdk.TokensFromConsensusPower(100) - tokens2 := sdk.TokensFromConsensusPower(100) - validators[0], _ = validators[0].AddTokensFromDel(tokens0) - validators[1], _ = validators[1].AddTokensFromDel(tokens1) - validators[2], _ = validators[2].AddTokensFromDel(tokens2) - - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], true) - - //////////////////////////////////////// - // If two validators both increase to the same voting power in the same block, - // the one with the first transaction should become bonded - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], true) - validators[2] = TestingUpdateValidator(keeper, ctx, validators[2], true) - - resValidators := keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, uint32(len(resValidators)), params.MaxValidators) - - assert.True(ValEq(t, validators[0], resValidators[0])) - assert.True(ValEq(t, validators[1], resValidators[1])) - keeper.DeleteValidatorByPowerIndex(ctx, validators[1]) - keeper.DeleteValidatorByPowerIndex(ctx, validators[2]) - delTokens := sdk.TokensFromConsensusPower(50) - validators[1], _ = validators[1].AddTokensFromDel(delTokens) - validators[2], _ = validators[2].AddTokensFromDel(delTokens) - validators[2] = TestingUpdateValidator(keeper, ctx, validators[2], true) - resValidators = keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, params.MaxValidators, uint32(len(resValidators))) - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], true) - assert.True(ValEq(t, validators[0], resValidators[0])) - assert.True(ValEq(t, validators[2], resValidators[1])) -} - func TestFullValidatorSetPowerChange(t *testing.T) { ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) params := keeper.GetParams(ctx) diff --git a/x/staking/keeper/validator_test.go b/x/staking/keeper/validator_test.go index 8a122c6c3748..04bf52159c46 100644 --- a/x/staking/keeper/validator_test.go +++ b/x/staking/keeper/validator_test.go @@ -568,3 +568,50 @@ func TestGetValidatorsEdgeCases(t *testing.T) { _, exists := app.StakingKeeper.GetValidator(ctx, validators[3].OperatorAddress) require.True(t, exists) } + +func TestValidatorBondHeight(t *testing.T) { + app, ctx, addrs, _ := bootstrapValidatorTest(t, 1000, 20) + + // now 2 max resValidators + params := app.StakingKeeper.GetParams(ctx) + params.MaxValidators = 2 + app.StakingKeeper.SetParams(ctx, params) + + // initialize some validators into the state + var validators [3]types.Validator + validators[0] = types.NewValidator(sdk.ValAddress(PKs[0].Address().Bytes()), PKs[0], types.Description{}) + validators[1] = types.NewValidator(sdk.ValAddress(addrs[1]), PKs[1], types.Description{}) + validators[2] = types.NewValidator(sdk.ValAddress(addrs[2]), PKs[2], types.Description{}) + + tokens0 := sdk.TokensFromConsensusPower(200) + tokens1 := sdk.TokensFromConsensusPower(100) + tokens2 := sdk.TokensFromConsensusPower(100) + validators[0], _ = validators[0].AddTokensFromDel(tokens0) + validators[1], _ = validators[1].AddTokensFromDel(tokens1) + validators[2], _ = validators[2].AddTokensFromDel(tokens2) + + validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], true) + + //////////////////////////////////////// + // If two validators both increase to the same voting power in the same block, + // the one with the first transaction should become bonded + validators[1] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[1], true) + validators[2] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[2], true) + + resValidators := app.StakingKeeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, uint32(len(resValidators)), params.MaxValidators) + + assert.True(ValEq(t, validators[0], resValidators[0])) + assert.True(ValEq(t, validators[1], resValidators[1])) + app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validators[1]) + app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validators[2]) + delTokens := sdk.TokensFromConsensusPower(50) + validators[1], _ = validators[1].AddTokensFromDel(delTokens) + validators[2], _ = validators[2].AddTokensFromDel(delTokens) + validators[2] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[2], true) + resValidators = app.StakingKeeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, params.MaxValidators, uint32(len(resValidators))) + validators[1] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[1], true) + assert.True(ValEq(t, validators[0], resValidators[0])) + assert.True(ValEq(t, validators[2], resValidators[1])) +} From b4ab8e5e077c2a6dddcfd717ef5efce52b392b86 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Tue, 25 Feb 2020 13:54:55 +0100 Subject: [PATCH 50/90] refactor TestFullValidatorSetPowerChange test --- x/staking/keeper/old_validator_test.go | 42 -------------------------- x/staking/keeper/validator_test.go | 42 ++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/x/staking/keeper/old_validator_test.go b/x/staking/keeper/old_validator_test.go index 729903548d79..fa0884733d0b 100644 --- a/x/staking/keeper/old_validator_test.go +++ b/x/staking/keeper/old_validator_test.go @@ -14,48 +14,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/staking/types" ) -func TestFullValidatorSetPowerChange(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) - params := keeper.GetParams(ctx) - max := 2 - params.MaxValidators = uint32(2) - keeper.SetParams(ctx, params) - - // initialize some validators into the state - powers := []int64{0, 100, 400, 400, 200} - var validators [5]types.Validator - for i, power := range powers { - validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) - tokens := sdk.TokensFromConsensusPower(power) - validators[i], _ = validators[i].AddTokensFromDel(tokens) - TestingUpdateValidator(keeper, ctx, validators[i], true) - } - for i := range powers { - var found bool - validators[i], found = keeper.GetValidator(ctx, validators[i].OperatorAddress) - require.True(t, found) - } - assert.Equal(t, sdk.Unbonded, validators[0].Status) - assert.Equal(t, sdk.Unbonding, validators[1].Status) - assert.Equal(t, sdk.Bonded, validators[2].Status) - assert.Equal(t, sdk.Bonded, validators[3].Status) - assert.Equal(t, sdk.Unbonded, validators[4].Status) - resValidators := keeper.GetBondedValidatorsByPower(ctx) - assert.Equal(t, max, len(resValidators)) - assert.True(ValEq(t, validators[2], resValidators[0])) // in the order of txs - assert.True(ValEq(t, validators[3], resValidators[1])) - - // test a swap in voting power - - tokens := sdk.TokensFromConsensusPower(600) - validators[0], _ = validators[0].AddTokensFromDel(tokens) - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], true) - resValidators = keeper.GetBondedValidatorsByPower(ctx) - assert.Equal(t, max, len(resValidators)) - assert.True(ValEq(t, validators[0], resValidators[0])) - assert.True(ValEq(t, validators[2], resValidators[1])) -} - func TestApplyAndReturnValidatorSetUpdatesAllNone(t *testing.T) { ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) diff --git a/x/staking/keeper/validator_test.go b/x/staking/keeper/validator_test.go index 04bf52159c46..2d87b5497878 100644 --- a/x/staking/keeper/validator_test.go +++ b/x/staking/keeper/validator_test.go @@ -615,3 +615,45 @@ func TestValidatorBondHeight(t *testing.T) { assert.True(ValEq(t, validators[0], resValidators[0])) assert.True(ValEq(t, validators[2], resValidators[1])) } + +func TestFullValidatorSetPowerChange(t *testing.T) { + app, ctx, addrs, _ := bootstrapValidatorTest(t, 1000, 20) + params := app.StakingKeeper.GetParams(ctx) + max := 2 + params.MaxValidators = uint32(2) + app.StakingKeeper.SetParams(ctx, params) + + // initialize some validators into the state + powers := []int64{0, 100, 400, 400, 200} + var validators [5]types.Validator + for i, power := range powers { + validators[i] = types.NewValidator(sdk.ValAddress(addrs[i]), PKs[i], types.Description{}) + tokens := sdk.TokensFromConsensusPower(power) + validators[i], _ = validators[i].AddTokensFromDel(tokens) + keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[i], true) + } + for i := range powers { + var found bool + validators[i], found = app.StakingKeeper.GetValidator(ctx, validators[i].OperatorAddress) + require.True(t, found) + } + assert.Equal(t, sdk.Unbonded, validators[0].Status) + assert.Equal(t, sdk.Unbonding, validators[1].Status) + assert.Equal(t, sdk.Bonded, validators[2].Status) + assert.Equal(t, sdk.Bonded, validators[3].Status) + assert.Equal(t, sdk.Unbonded, validators[4].Status) + resValidators := app.StakingKeeper.GetBondedValidatorsByPower(ctx) + assert.Equal(t, max, len(resValidators)) + assert.True(ValEq(t, validators[2], resValidators[0])) // in the order of txs + assert.True(ValEq(t, validators[3], resValidators[1])) + + // test a swap in voting power + + tokens := sdk.TokensFromConsensusPower(600) + validators[0], _ = validators[0].AddTokensFromDel(tokens) + validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], true) + resValidators = app.StakingKeeper.GetBondedValidatorsByPower(ctx) + assert.Equal(t, max, len(resValidators)) + assert.True(ValEq(t, validators[0], resValidators[0])) + assert.True(ValEq(t, validators[2], resValidators[1])) +} From 9ae53260bff743c10f2308a90dbc8c4b72057718 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Tue, 25 Feb 2020 14:07:01 +0100 Subject: [PATCH 51/90] end refactoring validator_test --- x/staking/keeper/old_validator_test.go | 472 ------------------------- x/staking/keeper/validator_test.go | 469 +++++++++++++++++++++++- 2 files changed, 463 insertions(+), 478 deletions(-) delete mode 100644 x/staking/keeper/old_validator_test.go diff --git a/x/staking/keeper/old_validator_test.go b/x/staking/keeper/old_validator_test.go deleted file mode 100644 index fa0884733d0b..000000000000 --- a/x/staking/keeper/old_validator_test.go +++ /dev/null @@ -1,472 +0,0 @@ -package keeper - -import ( - "fmt" - "testing" - "time" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - - abci "github.com/tendermint/tendermint/abci/types" - - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/staking/types" -) - -func TestApplyAndReturnValidatorSetUpdatesAllNone(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) - - powers := []int64{10, 20} - var validators [2]types.Validator - for i, power := range powers { - valPubKey := PKs[i+1] - valAddr := sdk.ValAddress(valPubKey.Address().Bytes()) - - validators[i] = types.NewValidator(valAddr, valPubKey, types.Description{}) - tokens := sdk.TokensFromConsensusPower(power) - validators[i], _ = validators[i].AddTokensFromDel(tokens) - } - - // test from nothing to something - // tendermintUpdate set: {} -> {c1, c3} - require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) - keeper.SetValidator(ctx, validators[0]) - keeper.SetValidatorByPowerIndex(ctx, validators[0]) - keeper.SetValidator(ctx, validators[1]) - keeper.SetValidatorByPowerIndex(ctx, validators[1]) - - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - assert.Equal(t, 2, len(updates)) - validators[0], _ = keeper.GetValidator(ctx, validators[0].OperatorAddress) - validators[1], _ = keeper.GetValidator(ctx, validators[1].OperatorAddress) - assert.Equal(t, validators[0].ABCIValidatorUpdate(), updates[1]) - assert.Equal(t, validators[1].ABCIValidatorUpdate(), updates[0]) -} - -func TestApplyAndReturnValidatorSetUpdatesIdentical(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) - - powers := []int64{10, 20} - var validators [2]types.Validator - for i, power := range powers { - validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) - - tokens := sdk.TokensFromConsensusPower(power) - validators[i], _ = validators[i].AddTokensFromDel(tokens) - - } - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false) - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], false) - require.Equal(t, 2, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) - - // test identical, - // tendermintUpdate set: {} -> {} - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false) - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], false) - require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) -} - -func TestApplyAndReturnValidatorSetUpdatesSingleValueChange(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) - - powers := []int64{10, 20} - var validators [2]types.Validator - for i, power := range powers { - - validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) - - tokens := sdk.TokensFromConsensusPower(power) - validators[i], _ = validators[i].AddTokensFromDel(tokens) - - } - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false) - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], false) - require.Equal(t, 2, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) - - // test single value change - // tendermintUpdate set: {} -> {c1'} - validators[0].Status = sdk.Bonded - validators[0].Tokens = sdk.TokensFromConsensusPower(600) - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false) - - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - - require.Equal(t, 1, len(updates)) - require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) -} - -func TestApplyAndReturnValidatorSetUpdatesMultipleValueChange(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) - - powers := []int64{10, 20} - var validators [2]types.Validator - for i, power := range powers { - - validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) - - tokens := sdk.TokensFromConsensusPower(power) - validators[i], _ = validators[i].AddTokensFromDel(tokens) - - } - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false) - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], false) - require.Equal(t, 2, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) - - // test multiple value change - // tendermintUpdate set: {c1, c3} -> {c1', c3'} - delTokens1 := sdk.TokensFromConsensusPower(190) - delTokens2 := sdk.TokensFromConsensusPower(80) - validators[0], _ = validators[0].AddTokensFromDel(delTokens1) - validators[1], _ = validators[1].AddTokensFromDel(delTokens2) - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false) - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], false) - - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 2, len(updates)) - require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) - require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) -} - -func TestApplyAndReturnValidatorSetUpdatesInserted(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) - - powers := []int64{10, 20, 5, 15, 25} - var validators [5]types.Validator - for i, power := range powers { - - validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) - - tokens := sdk.TokensFromConsensusPower(power) - validators[i], _ = validators[i].AddTokensFromDel(tokens) - - } - - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false) - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], false) - require.Equal(t, 2, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) - - // test validtor added at the beginning - // tendermintUpdate set: {} -> {c0} - keeper.SetValidator(ctx, validators[2]) - keeper.SetValidatorByPowerIndex(ctx, validators[2]) - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - validators[2], _ = keeper.GetValidator(ctx, validators[2].OperatorAddress) - require.Equal(t, 1, len(updates)) - require.Equal(t, validators[2].ABCIValidatorUpdate(), updates[0]) - - // test validtor added at the beginning - // tendermintUpdate set: {} -> {c0} - keeper.SetValidator(ctx, validators[3]) - keeper.SetValidatorByPowerIndex(ctx, validators[3]) - updates = keeper.ApplyAndReturnValidatorSetUpdates(ctx) - validators[3], _ = keeper.GetValidator(ctx, validators[3].OperatorAddress) - require.Equal(t, 1, len(updates)) - require.Equal(t, validators[3].ABCIValidatorUpdate(), updates[0]) - - // test validtor added at the end - // tendermintUpdate set: {} -> {c0} - keeper.SetValidator(ctx, validators[4]) - keeper.SetValidatorByPowerIndex(ctx, validators[4]) - updates = keeper.ApplyAndReturnValidatorSetUpdates(ctx) - validators[4], _ = keeper.GetValidator(ctx, validators[4].OperatorAddress) - require.Equal(t, 1, len(updates)) - require.Equal(t, validators[4].ABCIValidatorUpdate(), updates[0]) -} - -func TestApplyAndReturnValidatorSetUpdatesWithCliffValidator(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) - params := types.DefaultParams() - params.MaxValidators = 2 - keeper.SetParams(ctx, params) - - powers := []int64{10, 20, 5} - var validators [5]types.Validator - for i, power := range powers { - - validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) - - tokens := sdk.TokensFromConsensusPower(power) - validators[i], _ = validators[i].AddTokensFromDel(tokens) - - } - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false) - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], false) - require.Equal(t, 2, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) - - // test validator added at the end but not inserted in the valset - // tendermintUpdate set: {} -> {} - TestingUpdateValidator(keeper, ctx, validators[2], false) - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 0, len(updates)) - - // test validator change its power and become a gotValidator (pushing out an existing) - // tendermintUpdate set: {} -> {c0, c4} - require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) - - tokens := sdk.TokensFromConsensusPower(10) - validators[2], _ = validators[2].AddTokensFromDel(tokens) - keeper.SetValidator(ctx, validators[2]) - keeper.SetValidatorByPowerIndex(ctx, validators[2]) - updates = keeper.ApplyAndReturnValidatorSetUpdates(ctx) - validators[2], _ = keeper.GetValidator(ctx, validators[2].OperatorAddress) - require.Equal(t, 2, len(updates), "%v", updates) - require.Equal(t, validators[0].ABCIValidatorUpdateZero(), updates[1]) - require.Equal(t, validators[2].ABCIValidatorUpdate(), updates[0]) -} - -func TestApplyAndReturnValidatorSetUpdatesPowerDecrease(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) - - powers := []int64{100, 100} - var validators [2]types.Validator - for i, power := range powers { - - validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) - - tokens := sdk.TokensFromConsensusPower(power) - validators[i], _ = validators[i].AddTokensFromDel(tokens) - - } - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false) - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], false) - require.Equal(t, 2, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) - - // check initial power - require.Equal(t, int64(100), validators[0].GetConsensusPower()) - require.Equal(t, int64(100), validators[1].GetConsensusPower()) - - // test multiple value change - // tendermintUpdate set: {c1, c3} -> {c1', c3'} - delTokens1 := sdk.TokensFromConsensusPower(20) - delTokens2 := sdk.TokensFromConsensusPower(30) - validators[0], _ = validators[0].RemoveDelShares(delTokens1.ToDec()) - validators[1], _ = validators[1].RemoveDelShares(delTokens2.ToDec()) - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false) - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], false) - - // power has changed - require.Equal(t, int64(80), validators[0].GetConsensusPower()) - require.Equal(t, int64(70), validators[1].GetConsensusPower()) - - // Tendermint updates should reflect power change - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 2, len(updates)) - require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) - require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) -} - -func TestApplyAndReturnValidatorSetUpdatesNewValidator(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) - params := keeper.GetParams(ctx) - params.MaxValidators = uint32(3) - - keeper.SetParams(ctx, params) - - powers := []int64{100, 100} - var validators [2]types.Validator - - // initialize some validators into the state - for i, power := range powers { - - valPubKey := PKs[i+1] - valAddr := sdk.ValAddress(valPubKey.Address().Bytes()) - - validators[i] = types.NewValidator(valAddr, valPubKey, types.Description{}) - tokens := sdk.TokensFromConsensusPower(power) - validators[i], _ = validators[i].AddTokensFromDel(tokens) - - keeper.SetValidator(ctx, validators[i]) - keeper.SetValidatorByPowerIndex(ctx, validators[i]) - } - - // verify initial Tendermint updates are correct - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, len(validators), len(updates)) - validators[0], _ = keeper.GetValidator(ctx, validators[0].OperatorAddress) - validators[1], _ = keeper.GetValidator(ctx, validators[1].OperatorAddress) - require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) - require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) - - require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) - - // update initial validator set - for i, power := range powers { - - keeper.DeleteValidatorByPowerIndex(ctx, validators[i]) - tokens := sdk.TokensFromConsensusPower(power) - validators[i], _ = validators[i].AddTokensFromDel(tokens) - - keeper.SetValidator(ctx, validators[i]) - keeper.SetValidatorByPowerIndex(ctx, validators[i]) - } - - // add a new validator that goes from zero power, to non-zero power, back to - // zero power - valPubKey := PKs[len(validators)+1] - valAddr := sdk.ValAddress(valPubKey.Address().Bytes()) - amt := sdk.NewInt(100) - - validator := types.NewValidator(valAddr, valPubKey, types.Description{}) - validator, _ = validator.AddTokensFromDel(amt) - - keeper.SetValidator(ctx, validator) - - validator, _ = validator.RemoveDelShares(amt.ToDec()) - keeper.SetValidator(ctx, validator) - keeper.SetValidatorByPowerIndex(ctx, validator) - - // add a new validator that increases in power - valPubKey = PKs[len(validators)+2] - valAddr = sdk.ValAddress(valPubKey.Address().Bytes()) - - validator = types.NewValidator(valAddr, valPubKey, types.Description{}) - tokens := sdk.TokensFromConsensusPower(500) - validator, _ = validator.AddTokensFromDel(tokens) - keeper.SetValidator(ctx, validator) - keeper.SetValidatorByPowerIndex(ctx, validator) - - // verify initial Tendermint updates are correct - updates = keeper.ApplyAndReturnValidatorSetUpdates(ctx) - validator, _ = keeper.GetValidator(ctx, validator.OperatorAddress) - validators[0], _ = keeper.GetValidator(ctx, validators[0].OperatorAddress) - validators[1], _ = keeper.GetValidator(ctx, validators[1].OperatorAddress) - require.Equal(t, len(validators)+1, len(updates)) - require.Equal(t, validator.ABCIValidatorUpdate(), updates[0]) - require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[1]) - require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[2]) -} - -func TestApplyAndReturnValidatorSetUpdatesBondTransition(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) - params := keeper.GetParams(ctx) - params.MaxValidators = uint32(2) - - keeper.SetParams(ctx, params) - - powers := []int64{100, 200, 300} - var validators [3]types.Validator - - // initialize some validators into the state - for i, power := range powers { - moniker := fmt.Sprintf("%d", i) - valPubKey := PKs[i+1] - valAddr := sdk.ValAddress(valPubKey.Address().Bytes()) - - validators[i] = types.NewValidator(valAddr, valPubKey, types.Description{Moniker: moniker}) - tokens := sdk.TokensFromConsensusPower(power) - validators[i], _ = validators[i].AddTokensFromDel(tokens) - keeper.SetValidator(ctx, validators[i]) - keeper.SetValidatorByPowerIndex(ctx, validators[i]) - } - - // verify initial Tendermint updates are correct - updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 2, len(updates)) - validators[2], _ = keeper.GetValidator(ctx, validators[2].OperatorAddress) - validators[1], _ = keeper.GetValidator(ctx, validators[1].OperatorAddress) - require.Equal(t, validators[2].ABCIValidatorUpdate(), updates[0]) - require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) - - require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) - - // delegate to validator with lowest power but not enough to bond - ctx = ctx.WithBlockHeight(1) - - var found bool - validators[0], found = keeper.GetValidator(ctx, validators[0].OperatorAddress) - require.True(t, found) - - keeper.DeleteValidatorByPowerIndex(ctx, validators[0]) - tokens := sdk.TokensFromConsensusPower(1) - validators[0], _ = validators[0].AddTokensFromDel(tokens) - keeper.SetValidator(ctx, validators[0]) - keeper.SetValidatorByPowerIndex(ctx, validators[0]) - - // verify initial Tendermint updates are correct - require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) - - // create a series of events that will bond and unbond the validator with - // lowest power in a single block context (height) - ctx = ctx.WithBlockHeight(2) - - validators[1], found = keeper.GetValidator(ctx, validators[1].OperatorAddress) - require.True(t, found) - - keeper.DeleteValidatorByPowerIndex(ctx, validators[0]) - validators[0], _ = validators[0].RemoveDelShares(validators[0].DelegatorShares) - keeper.SetValidator(ctx, validators[0]) - keeper.SetValidatorByPowerIndex(ctx, validators[0]) - updates = keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 0, len(updates)) - - keeper.DeleteValidatorByPowerIndex(ctx, validators[1]) - tokens = sdk.TokensFromConsensusPower(250) - validators[1], _ = validators[1].AddTokensFromDel(tokens) - keeper.SetValidator(ctx, validators[1]) - keeper.SetValidatorByPowerIndex(ctx, validators[1]) - - // verify initial Tendermint updates are correct - updates = keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 1, len(updates)) - require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[0]) - - require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) -} - -func TestUpdateValidatorCommission(t *testing.T) { - ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) - ctx = ctx.WithBlockHeader(abci.Header{Time: time.Now().UTC()}) - - commission1 := types.NewCommissionWithTime( - sdk.NewDecWithPrec(1, 1), sdk.NewDecWithPrec(3, 1), - sdk.NewDecWithPrec(1, 1), time.Now().UTC().Add(time.Duration(-1)*time.Hour), - ) - commission2 := types.NewCommission(sdk.NewDecWithPrec(1, 1), sdk.NewDecWithPrec(3, 1), sdk.NewDecWithPrec(1, 1)) - - val1 := types.NewValidator(addrVals[0], PKs[0], types.Description{}) - val2 := types.NewValidator(addrVals[1], PKs[1], types.Description{}) - - val1, _ = val1.SetInitialCommission(commission1) - val2, _ = val2.SetInitialCommission(commission2) - - keeper.SetValidator(ctx, val1) - keeper.SetValidator(ctx, val2) - - testCases := []struct { - validator types.Validator - newRate sdk.Dec - expectedErr bool - }{ - {val1, sdk.ZeroDec(), true}, - {val2, sdk.NewDecWithPrec(-1, 1), true}, - {val2, sdk.NewDecWithPrec(4, 1), true}, - {val2, sdk.NewDecWithPrec(3, 1), true}, - {val2, sdk.NewDecWithPrec(2, 1), false}, - } - - for i, tc := range testCases { - commission, err := keeper.UpdateValidatorCommission(ctx, tc.validator, tc.newRate) - - if tc.expectedErr { - require.Error(t, err, "expected error for test case #%d with rate: %s", i, tc.newRate) - } else { - tc.validator.Commission = commission - keeper.SetValidator(ctx, tc.validator) - val, found := keeper.GetValidator(ctx, tc.validator.OperatorAddress) - - require.True(t, found, - "expected to find validator for test case #%d with rate: %s", i, tc.newRate, - ) - require.NoError(t, err, - "unexpected error for test case #%d with rate: %s", i, tc.newRate, - ) - require.Equal(t, tc.newRate, val.Commission.Rate, - "expected new validator commission rate for test case #%d with rate: %s", i, tc.newRate, - ) - require.Equal(t, ctx.BlockHeader().Time, val.Commission.UpdateTime, - "expected new validator commission update time for test case #%d with rate: %s", i, tc.newRate, - ) - } - } -} diff --git a/x/staking/keeper/validator_test.go b/x/staking/keeper/validator_test.go index 2d87b5497878..6f2be5472501 100644 --- a/x/staking/keeper/validator_test.go +++ b/x/staking/keeper/validator_test.go @@ -3,18 +3,18 @@ package keeper_test import ( "fmt" "testing" - - "github.com/cosmos/cosmos-sdk/x/supply" - - "github.com/cosmos/cosmos-sdk/x/staking/keeper" - - "github.com/cosmos/cosmos-sdk/simapp" + "time" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/staking/keeper" "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/cosmos/cosmos-sdk/x/supply" ) func bootstrapValidatorTest(t *testing.T, power int64, numAddrs int) (*simapp.SimApp, sdk.Context, []sdk.AccAddress, []sdk.ValAddress) { @@ -657,3 +657,460 @@ func TestFullValidatorSetPowerChange(t *testing.T) { assert.True(ValEq(t, validators[0], resValidators[0])) assert.True(ValEq(t, validators[2], resValidators[1])) } + +func TestApplyAndReturnValidatorSetUpdatesAllNone(t *testing.T) { + app, ctx, _, _ := bootstrapValidatorTest(t, 1000, 20) + + powers := []int64{10, 20} + var validators [2]types.Validator + for i, power := range powers { + valPubKey := PKs[i+1] + valAddr := sdk.ValAddress(valPubKey.Address().Bytes()) + + validators[i] = types.NewValidator(valAddr, valPubKey, types.Description{}) + tokens := sdk.TokensFromConsensusPower(power) + validators[i], _ = validators[i].AddTokensFromDel(tokens) + } + + // test from nothing to something + // tendermintUpdate set: {} -> {c1, c3} + require.Equal(t, 0, len(app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx))) + app.StakingKeeper.SetValidator(ctx, validators[0]) + app.StakingKeeper.SetValidatorByPowerIndex(ctx, validators[0]) + app.StakingKeeper.SetValidator(ctx, validators[1]) + app.StakingKeeper.SetValidatorByPowerIndex(ctx, validators[1]) + + updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + assert.Equal(t, 2, len(updates)) + validators[0], _ = app.StakingKeeper.GetValidator(ctx, validators[0].OperatorAddress) + validators[1], _ = app.StakingKeeper.GetValidator(ctx, validators[1].OperatorAddress) + assert.Equal(t, validators[0].ABCIValidatorUpdate(), updates[1]) + assert.Equal(t, validators[1].ABCIValidatorUpdate(), updates[0]) +} + +func TestApplyAndReturnValidatorSetUpdatesIdentical(t *testing.T) { + app, ctx, addrs, _ := bootstrapValidatorTest(t, 1000, 20) + + powers := []int64{10, 20} + var validators [2]types.Validator + for i, power := range powers { + validators[i] = types.NewValidator(sdk.ValAddress(addrs[i]), PKs[i], types.Description{}) + + tokens := sdk.TokensFromConsensusPower(power) + validators[i], _ = validators[i].AddTokensFromDel(tokens) + + } + validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], false) + validators[1] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[1], false) + require.Equal(t, 2, len(app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx))) + + // test identical, + // tendermintUpdate set: {} -> {} + validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], false) + validators[1] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[1], false) + require.Equal(t, 0, len(app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx))) +} + +func TestApplyAndReturnValidatorSetUpdatesSingleValueChange(t *testing.T) { + app, ctx, addrs, _ := bootstrapValidatorTest(t, 1000, 20) + + powers := []int64{10, 20} + var validators [2]types.Validator + for i, power := range powers { + + validators[i] = types.NewValidator(sdk.ValAddress(addrs[i]), PKs[i], types.Description{}) + + tokens := sdk.TokensFromConsensusPower(power) + validators[i], _ = validators[i].AddTokensFromDel(tokens) + + } + validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], false) + validators[1] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[1], false) + require.Equal(t, 2, len(app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx))) + + // test single value change + // tendermintUpdate set: {} -> {c1'} + validators[0].Status = sdk.Bonded + validators[0].Tokens = sdk.TokensFromConsensusPower(600) + validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], false) + + updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + + require.Equal(t, 1, len(updates)) + require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) +} + +func TestApplyAndReturnValidatorSetUpdatesMultipleValueChange(t *testing.T) { + app, ctx, addrs, _ := bootstrapValidatorTest(t, 1000, 20) + + powers := []int64{10, 20} + var validators [2]types.Validator + for i, power := range powers { + + validators[i] = types.NewValidator(sdk.ValAddress(addrs[i]), PKs[i], types.Description{}) + + tokens := sdk.TokensFromConsensusPower(power) + validators[i], _ = validators[i].AddTokensFromDel(tokens) + + } + validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], false) + validators[1] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[1], false) + require.Equal(t, 2, len(app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx))) + + // test multiple value change + // tendermintUpdate set: {c1, c3} -> {c1', c3'} + delTokens1 := sdk.TokensFromConsensusPower(190) + delTokens2 := sdk.TokensFromConsensusPower(80) + validators[0], _ = validators[0].AddTokensFromDel(delTokens1) + validators[1], _ = validators[1].AddTokensFromDel(delTokens2) + validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], false) + validators[1] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[1], false) + + updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 2, len(updates)) + require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) + require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) +} + +func TestApplyAndReturnValidatorSetUpdatesInserted(t *testing.T) { + app, ctx, addrs, _ := bootstrapValidatorTest(t, 1000, 20) + + powers := []int64{10, 20, 5, 15, 25} + var validators [5]types.Validator + for i, power := range powers { + + validators[i] = types.NewValidator(sdk.ValAddress(addrs[i]), PKs[i], types.Description{}) + + tokens := sdk.TokensFromConsensusPower(power) + validators[i], _ = validators[i].AddTokensFromDel(tokens) + + } + + validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], false) + validators[1] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[1], false) + require.Equal(t, 2, len(app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx))) + + // test validtor added at the beginning + // tendermintUpdate set: {} -> {c0} + app.StakingKeeper.SetValidator(ctx, validators[2]) + app.StakingKeeper.SetValidatorByPowerIndex(ctx, validators[2]) + updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + validators[2], _ = app.StakingKeeper.GetValidator(ctx, validators[2].OperatorAddress) + require.Equal(t, 1, len(updates)) + require.Equal(t, validators[2].ABCIValidatorUpdate(), updates[0]) + + // test validtor added at the beginning + // tendermintUpdate set: {} -> {c0} + app.StakingKeeper.SetValidator(ctx, validators[3]) + app.StakingKeeper.SetValidatorByPowerIndex(ctx, validators[3]) + updates = app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + validators[3], _ = app.StakingKeeper.GetValidator(ctx, validators[3].OperatorAddress) + require.Equal(t, 1, len(updates)) + require.Equal(t, validators[3].ABCIValidatorUpdate(), updates[0]) + + // test validtor added at the end + // tendermintUpdate set: {} -> {c0} + app.StakingKeeper.SetValidator(ctx, validators[4]) + app.StakingKeeper.SetValidatorByPowerIndex(ctx, validators[4]) + updates = app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + validators[4], _ = app.StakingKeeper.GetValidator(ctx, validators[4].OperatorAddress) + require.Equal(t, 1, len(updates)) + require.Equal(t, validators[4].ABCIValidatorUpdate(), updates[0]) +} + +func TestApplyAndReturnValidatorSetUpdatesWithCliffValidator(t *testing.T) { + app, ctx, addrs, _ := bootstrapValidatorTest(t, 1000, 20) + params := types.DefaultParams() + params.MaxValidators = 2 + app.StakingKeeper.SetParams(ctx, params) + + powers := []int64{10, 20, 5} + var validators [5]types.Validator + for i, power := range powers { + + validators[i] = types.NewValidator(sdk.ValAddress(addrs[i]), PKs[i], types.Description{}) + + tokens := sdk.TokensFromConsensusPower(power) + validators[i], _ = validators[i].AddTokensFromDel(tokens) + + } + validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], false) + validators[1] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[1], false) + require.Equal(t, 2, len(app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx))) + + // test validator added at the end but not inserted in the valset + // tendermintUpdate set: {} -> {} + keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[2], false) + updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 0, len(updates)) + + // test validator change its power and become a gotValidator (pushing out an existing) + // tendermintUpdate set: {} -> {c0, c4} + require.Equal(t, 0, len(app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx))) + + tokens := sdk.TokensFromConsensusPower(10) + validators[2], _ = validators[2].AddTokensFromDel(tokens) + app.StakingKeeper.SetValidator(ctx, validators[2]) + app.StakingKeeper.SetValidatorByPowerIndex(ctx, validators[2]) + updates = app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + validators[2], _ = app.StakingKeeper.GetValidator(ctx, validators[2].OperatorAddress) + require.Equal(t, 2, len(updates), "%v", updates) + require.Equal(t, validators[0].ABCIValidatorUpdateZero(), updates[1]) + require.Equal(t, validators[2].ABCIValidatorUpdate(), updates[0]) +} + +func TestApplyAndReturnValidatorSetUpdatesPowerDecrease(t *testing.T) { + app, ctx, addrs, _ := bootstrapValidatorTest(t, 1000, 20) + + powers := []int64{100, 100} + var validators [2]types.Validator + for i, power := range powers { + + validators[i] = types.NewValidator(sdk.ValAddress(addrs[i]), PKs[i], types.Description{}) + + tokens := sdk.TokensFromConsensusPower(power) + validators[i], _ = validators[i].AddTokensFromDel(tokens) + + } + validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], false) + validators[1] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[1], false) + require.Equal(t, 2, len(app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx))) + + // check initial power + require.Equal(t, int64(100), validators[0].GetConsensusPower()) + require.Equal(t, int64(100), validators[1].GetConsensusPower()) + + // test multiple value change + // tendermintUpdate set: {c1, c3} -> {c1', c3'} + delTokens1 := sdk.TokensFromConsensusPower(20) + delTokens2 := sdk.TokensFromConsensusPower(30) + validators[0], _ = validators[0].RemoveDelShares(delTokens1.ToDec()) + validators[1], _ = validators[1].RemoveDelShares(delTokens2.ToDec()) + validators[0] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[0], false) + validators[1] = keeper.TestingUpdateValidator(app.StakingKeeper, ctx, validators[1], false) + + // power has changed + require.Equal(t, int64(80), validators[0].GetConsensusPower()) + require.Equal(t, int64(70), validators[1].GetConsensusPower()) + + // Tendermint updates should reflect power change + updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 2, len(updates)) + require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) + require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) +} + +func TestApplyAndReturnValidatorSetUpdatesNewValidator(t *testing.T) { + app, ctx, _, _ := bootstrapValidatorTest(t, 1000, 20) + params := app.StakingKeeper.GetParams(ctx) + params.MaxValidators = uint32(3) + + app.StakingKeeper.SetParams(ctx, params) + + powers := []int64{100, 100} + var validators [2]types.Validator + + // initialize some validators into the state + for i, power := range powers { + + valPubKey := PKs[i+1] + valAddr := sdk.ValAddress(valPubKey.Address().Bytes()) + + validators[i] = types.NewValidator(valAddr, valPubKey, types.Description{}) + tokens := sdk.TokensFromConsensusPower(power) + validators[i], _ = validators[i].AddTokensFromDel(tokens) + + app.StakingKeeper.SetValidator(ctx, validators[i]) + app.StakingKeeper.SetValidatorByPowerIndex(ctx, validators[i]) + } + + // verify initial Tendermint updates are correct + updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, len(validators), len(updates)) + validators[0], _ = app.StakingKeeper.GetValidator(ctx, validators[0].OperatorAddress) + validators[1], _ = app.StakingKeeper.GetValidator(ctx, validators[1].OperatorAddress) + require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) + require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) + + require.Equal(t, 0, len(app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx))) + + // update initial validator set + for i, power := range powers { + + app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validators[i]) + tokens := sdk.TokensFromConsensusPower(power) + validators[i], _ = validators[i].AddTokensFromDel(tokens) + + app.StakingKeeper.SetValidator(ctx, validators[i]) + app.StakingKeeper.SetValidatorByPowerIndex(ctx, validators[i]) + } + + // add a new validator that goes from zero power, to non-zero power, back to + // zero power + valPubKey := PKs[len(validators)+1] + valAddr := sdk.ValAddress(valPubKey.Address().Bytes()) + amt := sdk.NewInt(100) + + validator := types.NewValidator(valAddr, valPubKey, types.Description{}) + validator, _ = validator.AddTokensFromDel(amt) + + app.StakingKeeper.SetValidator(ctx, validator) + + validator, _ = validator.RemoveDelShares(amt.ToDec()) + app.StakingKeeper.SetValidator(ctx, validator) + app.StakingKeeper.SetValidatorByPowerIndex(ctx, validator) + + // add a new validator that increases in power + valPubKey = PKs[len(validators)+2] + valAddr = sdk.ValAddress(valPubKey.Address().Bytes()) + + validator = types.NewValidator(valAddr, valPubKey, types.Description{}) + tokens := sdk.TokensFromConsensusPower(500) + validator, _ = validator.AddTokensFromDel(tokens) + app.StakingKeeper.SetValidator(ctx, validator) + app.StakingKeeper.SetValidatorByPowerIndex(ctx, validator) + + // verify initial Tendermint updates are correct + updates = app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + validator, _ = app.StakingKeeper.GetValidator(ctx, validator.OperatorAddress) + validators[0], _ = app.StakingKeeper.GetValidator(ctx, validators[0].OperatorAddress) + validators[1], _ = app.StakingKeeper.GetValidator(ctx, validators[1].OperatorAddress) + require.Equal(t, len(validators)+1, len(updates)) + require.Equal(t, validator.ABCIValidatorUpdate(), updates[0]) + require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[1]) + require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[2]) +} + +func TestApplyAndReturnValidatorSetUpdatesBondTransition(t *testing.T) { + app, ctx, _, _ := bootstrapValidatorTest(t, 1000, 20) + params := app.StakingKeeper.GetParams(ctx) + params.MaxValidators = uint32(2) + + app.StakingKeeper.SetParams(ctx, params) + + powers := []int64{100, 200, 300} + var validators [3]types.Validator + + // initialize some validators into the state + for i, power := range powers { + moniker := fmt.Sprintf("%d", i) + valPubKey := PKs[i+1] + valAddr := sdk.ValAddress(valPubKey.Address().Bytes()) + + validators[i] = types.NewValidator(valAddr, valPubKey, types.Description{Moniker: moniker}) + tokens := sdk.TokensFromConsensusPower(power) + validators[i], _ = validators[i].AddTokensFromDel(tokens) + app.StakingKeeper.SetValidator(ctx, validators[i]) + app.StakingKeeper.SetValidatorByPowerIndex(ctx, validators[i]) + } + + // verify initial Tendermint updates are correct + updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 2, len(updates)) + validators[2], _ = app.StakingKeeper.GetValidator(ctx, validators[2].OperatorAddress) + validators[1], _ = app.StakingKeeper.GetValidator(ctx, validators[1].OperatorAddress) + require.Equal(t, validators[2].ABCIValidatorUpdate(), updates[0]) + require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) + + require.Equal(t, 0, len(app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx))) + + // delegate to validator with lowest power but not enough to bond + ctx = ctx.WithBlockHeight(1) + + var found bool + validators[0], found = app.StakingKeeper.GetValidator(ctx, validators[0].OperatorAddress) + require.True(t, found) + + app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validators[0]) + tokens := sdk.TokensFromConsensusPower(1) + validators[0], _ = validators[0].AddTokensFromDel(tokens) + app.StakingKeeper.SetValidator(ctx, validators[0]) + app.StakingKeeper.SetValidatorByPowerIndex(ctx, validators[0]) + + // verify initial Tendermint updates are correct + require.Equal(t, 0, len(app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx))) + + // create a series of events that will bond and unbond the validator with + // lowest power in a single block context (height) + ctx = ctx.WithBlockHeight(2) + + validators[1], found = app.StakingKeeper.GetValidator(ctx, validators[1].OperatorAddress) + require.True(t, found) + + app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validators[0]) + validators[0], _ = validators[0].RemoveDelShares(validators[0].DelegatorShares) + app.StakingKeeper.SetValidator(ctx, validators[0]) + app.StakingKeeper.SetValidatorByPowerIndex(ctx, validators[0]) + updates = app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 0, len(updates)) + + app.StakingKeeper.DeleteValidatorByPowerIndex(ctx, validators[1]) + tokens = sdk.TokensFromConsensusPower(250) + validators[1], _ = validators[1].AddTokensFromDel(tokens) + app.StakingKeeper.SetValidator(ctx, validators[1]) + app.StakingKeeper.SetValidatorByPowerIndex(ctx, validators[1]) + + // verify initial Tendermint updates are correct + updates = app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 1, len(updates)) + require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[0]) + + require.Equal(t, 0, len(app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx))) +} + +func TestUpdateValidatorCommission(t *testing.T) { + app, ctx, _, addrVals := bootstrapValidatorTest(t, 1000, 20) + ctx = ctx.WithBlockHeader(abci.Header{Time: time.Now().UTC()}) + + commission1 := types.NewCommissionWithTime( + sdk.NewDecWithPrec(1, 1), sdk.NewDecWithPrec(3, 1), + sdk.NewDecWithPrec(1, 1), time.Now().UTC().Add(time.Duration(-1)*time.Hour), + ) + commission2 := types.NewCommission(sdk.NewDecWithPrec(1, 1), sdk.NewDecWithPrec(3, 1), sdk.NewDecWithPrec(1, 1)) + + val1 := types.NewValidator(addrVals[0], PKs[0], types.Description{}) + val2 := types.NewValidator(addrVals[1], PKs[1], types.Description{}) + + val1, _ = val1.SetInitialCommission(commission1) + val2, _ = val2.SetInitialCommission(commission2) + + app.StakingKeeper.SetValidator(ctx, val1) + app.StakingKeeper.SetValidator(ctx, val2) + + testCases := []struct { + validator types.Validator + newRate sdk.Dec + expectedErr bool + }{ + {val1, sdk.ZeroDec(), true}, + {val2, sdk.NewDecWithPrec(-1, 1), true}, + {val2, sdk.NewDecWithPrec(4, 1), true}, + {val2, sdk.NewDecWithPrec(3, 1), true}, + {val2, sdk.NewDecWithPrec(2, 1), false}, + } + + for i, tc := range testCases { + commission, err := app.StakingKeeper.UpdateValidatorCommission(ctx, tc.validator, tc.newRate) + + if tc.expectedErr { + require.Error(t, err, "expected error for test case #%d with rate: %s", i, tc.newRate) + } else { + tc.validator.Commission = commission + app.StakingKeeper.SetValidator(ctx, tc.validator) + val, found := app.StakingKeeper.GetValidator(ctx, tc.validator.OperatorAddress) + + require.True(t, found, + "expected to find validator for test case #%d with rate: %s", i, tc.newRate, + ) + require.NoError(t, err, + "unexpected error for test case #%d with rate: %s", i, tc.newRate, + ) + require.Equal(t, tc.newRate, val.Commission.Rate, + "expected new validator commission rate for test case #%d with rate: %s", i, tc.newRate, + ) + require.Equal(t, ctx.BlockHeader().Time, val.Commission.UpdateTime, + "expected new validator commission update time for test case #%d with rate: %s", i, tc.newRate, + ) + } + } +} From 8f779b12b85be8a5cbeacf426459b69e6e884750 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Tue, 25 Feb 2020 15:11:52 +0100 Subject: [PATCH 52/90] clean code --- x/staking/genesis_test.go | 5 ++--- x/staking/keeper/old_test_common.go | 21 --------------------- 2 files changed, 2 insertions(+), 24 deletions(-) diff --git a/x/staking/genesis_test.go b/x/staking/genesis_test.go index 551239185fca..c58260424135 100644 --- a/x/staking/genesis_test.go +++ b/x/staking/genesis_test.go @@ -4,12 +4,11 @@ import ( "fmt" "testing" - "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/crypto/ed25519" sdk "github.com/cosmos/cosmos-sdk/types" keep "github.com/cosmos/cosmos-sdk/x/staking/keeper" diff --git a/x/staking/keeper/old_test_common.go b/x/staking/keeper/old_test_common.go index 82bd54a317ad..e1c75edeae29 100644 --- a/x/staking/keeper/old_test_common.go +++ b/x/staking/keeper/old_test_common.go @@ -31,29 +31,8 @@ import ( var ( Addrs = createTestAddrs(500) PKs = createTestPubKeys(500) - - addrDels = []sdk.AccAddress{ - Addrs[0], - Addrs[1], - } - addrVals = []sdk.ValAddress{ - sdk.ValAddress(Addrs[2]), - sdk.ValAddress(Addrs[3]), - sdk.ValAddress(Addrs[4]), - sdk.ValAddress(Addrs[5]), - sdk.ValAddress(Addrs[6]), - } ) -//_______________________________________________________________________________________ - -// intended to be used with require/assert: require.True(ValEq(...)) -func ValEq(t *testing.T, exp, got types.Validator) (*testing.T, bool, string, types.Validator, types.Validator) { - return t, exp.MinEqual(got), "expected:\n%v\ngot:\n%v", exp, got -} - -//_______________________________________________________________________________________ - // create a codec used only for testing func MakeTestCodec() *codec.Codec { var cdc = codec.New() From 632e65f575ae0874b5636b1fd5cd5121fa4a09b6 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Tue, 25 Feb 2020 15:27:51 +0100 Subject: [PATCH 53/90] move methods --- x/staking/genesis_test.go | 21 +- x/staking/handler_test.go | 367 ++++++++++++++-------------- x/staking/keeper/old_test_common.go | 208 ---------------- x/staking/test_common.go | 217 ++++++++++++++++ 4 files changed, 411 insertions(+), 402 deletions(-) create mode 100644 x/staking/test_common.go diff --git a/x/staking/genesis_test.go b/x/staking/genesis_test.go index c58260424135..730e7b0fc629 100644 --- a/x/staking/genesis_test.go +++ b/x/staking/genesis_test.go @@ -11,12 +11,11 @@ import ( "github.com/tendermint/tendermint/crypto/ed25519" sdk "github.com/cosmos/cosmos-sdk/types" - keep "github.com/cosmos/cosmos-sdk/x/staking/keeper" "github.com/cosmos/cosmos-sdk/x/staking/types" ) func TestInitGenesis(t *testing.T) { - ctx, accKeeper, bk, keeper, supplyKeeper := keep.CreateTestInput(t, false, 1000) + ctx, accKeeper, bk, keeper, supplyKeeper := CreateTestInput(t, false, 1000) valTokens := sdk.TokensFromConsensusPower(1) @@ -24,20 +23,20 @@ func TestInitGenesis(t *testing.T) { validators := make([]Validator, 2) var delegations []Delegation - pk0, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeConsPub, keep.PKs[0]) + pk0, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeConsPub, PKs[0]) require.NoError(t, err) - pk1, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeConsPub, keep.PKs[1]) + pk1, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeConsPub, PKs[1]) require.NoError(t, err) // initialize the validators - validators[0].OperatorAddress = sdk.ValAddress(keep.Addrs[0]) + validators[0].OperatorAddress = sdk.ValAddress(Addrs[0]) validators[0].ConsensusPubkey = pk0 validators[0].Description = NewDescription("hoop", "", "", "", "") validators[0].Status = sdk.Bonded validators[0].Tokens = valTokens validators[0].DelegatorShares = valTokens.ToDec() - validators[1].OperatorAddress = sdk.ValAddress(keep.Addrs[1]) + validators[1].OperatorAddress = sdk.ValAddress(Addrs[1]) validators[1].ConsensusPubkey = pk1 validators[1].Description = NewDescription("bloop", "", "", "", "") validators[1].Status = sdk.Bonded @@ -53,11 +52,11 @@ func TestInitGenesis(t *testing.T) { require.EqualValues(t, keeper.GetAllValidators(ctx), actualGenesis.Validators) // now make sure the validators are bonded and intra-tx counters are correct - resVal, found := keeper.GetValidator(ctx, sdk.ValAddress(keep.Addrs[0])) + resVal, found := keeper.GetValidator(ctx, sdk.ValAddress(Addrs[0])) require.True(t, found) require.Equal(t, sdk.Bonded, resVal.Status) - resVal, found = keeper.GetValidator(ctx, sdk.ValAddress(keep.Addrs[1])) + resVal, found = keeper.GetValidator(ctx, sdk.ValAddress(Addrs[1])) require.True(t, found) require.Equal(t, sdk.Bonded, resVal.Status) @@ -73,15 +72,15 @@ func TestInitGenesisLargeValidatorSet(t *testing.T) { size := 200 require.True(t, size > 100) - ctx, accKeeper, bk, keeper, supplyKeeper := keep.CreateTestInput(t, false, 1000) + ctx, accKeeper, bk, keeper, supplyKeeper := CreateTestInput(t, false, 1000) params := keeper.GetParams(ctx) delegations := []Delegation{} validators := make([]Validator, size) for i := range validators { - validators[i] = NewValidator(sdk.ValAddress(keep.Addrs[i]), - keep.PKs[i], NewDescription(fmt.Sprintf("#%d", i), "", "", "", "")) + validators[i] = NewValidator(sdk.ValAddress(Addrs[i]), + PKs[i], NewDescription(fmt.Sprintf("#%d", i), "", "", "", "")) validators[i].Status = sdk.Bonded diff --git a/x/staking/handler_test.go b/x/staking/handler_test.go index 51a2e61aa6c5..f18dda6ac00c 100644 --- a/x/staking/handler_test.go +++ b/x/staking/handler_test.go @@ -8,26 +8,27 @@ import ( 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" + . "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(keep.Addrs[0]), sdk.ValAddress(keep.Addrs[1]) + validatorAddr, validatorAddr3 := sdk.ValAddress(Addrs[0]), sdk.ValAddress(Addrs[1]) initPower := int64(1000000) initBond := sdk.TokensFromConsensusPower(initPower) - ctx, _, _, keeper, _ := keep.CreateTestInput(t, false, initPower) - handler := staking.NewHandler(keeper) + ctx, _, _, keeper, _ := CreateTestInput(t, false, initPower) + handler := NewHandler(keeper) // create validator - msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], initBond) + msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, PKs[0], initBond) res, err := handler(ctx, msgCreateValidator) require.NoError(t, err) require.NotNil(t, res) @@ -45,11 +46,11 @@ func TestValidatorByPowerIndex(t *testing.T) { // verify that the by power index exists validator, found := keeper.GetValidator(ctx, validatorAddr) require.True(t, found) - power := staking.GetValidatorsByPowerIndexKey(validator) + power := GetValidatorsByPowerIndexKey(validator) require.True(t, keep.ValidatorByPowerIndexExists(ctx, keeper, power)) // create a second validator keep it bonded - msgCreateValidator = NewTestMsgCreateValidator(validatorAddr3, keep.PKs[2], initBond) + msgCreateValidator = NewTestMsgCreateValidator(validatorAddr3, PKs[2], initBond) res, err = handler(ctx, msgCreateValidator) require.NoError(t, err) require.NotNil(t, res) @@ -59,7 +60,7 @@ func TestValidatorByPowerIndex(t *testing.T) { require.Equal(t, 1, len(updates)) // slash and jail the first validator - consAddr0 := sdk.ConsAddress(keep.PKs[0].Address()) + consAddr0 := sdk.ConsAddress(PKs[0].Address()) keeper.Slash(ctx, consAddr0, 0, initPower, sdk.NewDecWithPrec(5, 1)) keeper.Jail(ctx, consAddr0) keeper.ApplyAndReturnValidatorSetUpdates(ctx) @@ -76,17 +77,17 @@ func TestValidatorByPowerIndex(t *testing.T) { // but the new power record should have been created validator, found = keeper.GetValidator(ctx, validatorAddr) require.True(t, found) - power2 := staking.GetValidatorsByPowerIndexKey(validator) + 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 := staking.GetValidatorsByPowerIndexKey(validator) + power3 := GetValidatorsByPowerIndexKey(validator) require.Equal(t, power2, power3) // unbond self-delegation totalBond := validator.TokensFromShares(bond.GetShares()).TruncateInt() unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, totalBond) - msgUndelegate := staking.NewMsgUndelegate(sdk.AccAddress(validatorAddr), validatorAddr, unbondAmt) + msgUndelegate := NewMsgUndelegate(sdk.AccAddress(validatorAddr), validatorAddr, unbondAmt) res, err = handler(ctx, msgUndelegate) require.NoError(t, err) @@ -99,8 +100,8 @@ func TestValidatorByPowerIndex(t *testing.T) { require.NoError(t, err) ctx = ctx.WithBlockTime(finishTime) - staking.EndBlocker(ctx, keeper) - staking.EndBlocker(ctx, keeper) + EndBlocker(ctx, keeper) + EndBlocker(ctx, keeper) // verify that by power key nolonger exists _, found = keeper.GetValidator(ctx, validatorAddr) @@ -109,11 +110,11 @@ func TestValidatorByPowerIndex(t *testing.T) { } func TestDuplicatesMsgCreateValidator(t *testing.T) { - ctx, _, _, keeper, _ := keep.CreateTestInput(t, false, 1000) - handler := staking.NewHandler(keeper) + ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) + handler := NewHandler(keeper) - addr1, addr2 := sdk.ValAddress(keep.Addrs[0]), sdk.ValAddress(keep.Addrs[1]) - pk1, pk2 := keep.PKs[0], keep.PKs[1] + 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) @@ -130,7 +131,7 @@ func TestDuplicatesMsgCreateValidator(t *testing.T) { assert.Equal(t, pk1, validator.GetConsPubKey()) assert.Equal(t, valTokens, validator.BondedTokens()) assert.Equal(t, valTokens.ToDec(), validator.DelegatorShares) - assert.Equal(t, staking.Description{}, validator.Description) + assert.Equal(t, Description{}, validator.Description) // two validators can't have the same operator address msgCreateValidator2 := NewTestMsgCreateValidator(addr1, pk2, valTokens) @@ -162,14 +163,14 @@ func TestDuplicatesMsgCreateValidator(t *testing.T) { 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, staking.Description{}, validator.Description) + assert.Equal(t, Description{}, validator.Description) } func TestInvalidPubKeyTypeMsgCreateValidator(t *testing.T) { - ctx, _, _, keeper, _ := keep.CreateTestInput(t, false, 1000) - handler := staking.NewHandler(keeper) + ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) + handler := NewHandler(keeper) - addr := sdk.ValAddress(keep.Addrs[0]) + addr := sdk.ValAddress(Addrs[0]) invalidPk := secp256k1.GenPrivKey().PubKey() // invalid pukKey type should not be allowed @@ -188,13 +189,13 @@ func TestInvalidPubKeyTypeMsgCreateValidator(t *testing.T) { } func TestLegacyValidatorDelegations(t *testing.T) { - ctx, _, _, keeper, _ := keep.CreateTestInput(t, false, int64(1000)) - handler := staking.NewHandler(keeper) + ctx, _, _, keeper, _ := CreateTestInput(t, false, int64(1000)) + handler := NewHandler(keeper) bondAmount := sdk.TokensFromConsensusPower(10) - valAddr := sdk.ValAddress(keep.Addrs[0]) - valConsPubKey, valConsAddr := keep.PKs[0], sdk.ConsAddress(keep.PKs[0].Address()) - delAddr := keep.Addrs[1] + valAddr := sdk.ValAddress(Addrs[0]) + valConsPubKey, valConsAddr := PKs[0], sdk.ConsAddress(PKs[0].Address()) + delAddr := Addrs[1] // create validator msgCreateVal := NewTestMsgCreateValidator(valAddr, valConsPubKey, bondAmount) @@ -227,7 +228,7 @@ func TestLegacyValidatorDelegations(t *testing.T) { // unbond validator total self-delegations (which should jail the validator) unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, bondAmount) - msgUndelegate := staking.NewMsgUndelegate(sdk.AccAddress(valAddr), valAddr, unbondAmt) + msgUndelegate := NewMsgUndelegate(sdk.AccAddress(valAddr), valAddr, unbondAmt) res, err = handler(ctx, msgUndelegate) require.NoError(t, err) @@ -240,7 +241,7 @@ func TestLegacyValidatorDelegations(t *testing.T) { require.NoError(t, err) ctx = ctx.WithBlockTime(finishTime) - staking.EndBlocker(ctx, keeper) + EndBlocker(ctx, keeper) // verify the validator record still exists, is jailed, and has correct tokens validator, found = keeper.GetValidator(ctx, valAddr) @@ -291,16 +292,16 @@ func TestLegacyValidatorDelegations(t *testing.T) { func TestIncrementsMsgDelegate(t *testing.T) { initPower := int64(1000) initBond := sdk.TokensFromConsensusPower(initPower) - ctx, _, bk, keeper, _ := keep.CreateTestInput(t, false, initPower) - handler := staking.NewHandler(keeper) + ctx, _, bk, keeper, _ := CreateTestInput(t, false, initPower) + handler := NewHandler(keeper) params := keeper.GetParams(ctx) bondAmount := sdk.TokensFromConsensusPower(10) - validatorAddr, delegatorAddr := sdk.ValAddress(keep.Addrs[0]), keep.Addrs[1] + validatorAddr, delegatorAddr := sdk.ValAddress(Addrs[0]), Addrs[1] // first create validator - msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], bondAmount) + msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, PKs[0], bondAmount) res, err := handler(ctx, msgCreateValidator) require.NoError(t, err) require.NotNil(t, res) @@ -361,15 +362,15 @@ func TestIncrementsMsgDelegate(t *testing.T) { } func TestEditValidatorDecreaseMinSelfDelegation(t *testing.T) { - validatorAddr := sdk.ValAddress(keep.Addrs[0]) + validatorAddr := sdk.ValAddress(Addrs[0]) initPower := int64(100) initBond := sdk.TokensFromConsensusPower(100) - ctx, _, _, keeper, _ := keep.CreateTestInput(t, false, initPower) - handler := staking.NewHandler(keeper) + ctx, _, _, keeper, _ := CreateTestInput(t, false, initPower) + handler := NewHandler(keeper) // create validator - msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], initBond) + msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, PKs[0], initBond) msgCreateValidator.MinSelfDelegation = sdk.NewInt(2) res, err := handler(ctx, msgCreateValidator) require.NoError(t, err) @@ -388,22 +389,22 @@ func TestEditValidatorDecreaseMinSelfDelegation(t *testing.T) { initBond, gotBond, bond) newMinSelfDelegation := sdk.OneInt() - msgEditValidator := staking.NewMsgEditValidator(validatorAddr, staking.Description{}, nil, &newMinSelfDelegation) + 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(keep.Addrs[0]) + validatorAddr := sdk.ValAddress(Addrs[0]) initPower := int64(100) initBond := sdk.TokensFromConsensusPower(100) - ctx, _, _, keeper, _ := keep.CreateTestInput(t, false, initPower) - handler := staking.NewHandler(keeper) + ctx, _, _, keeper, _ := CreateTestInput(t, false, initPower) + handler := NewHandler(keeper) // create validator - msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], initBond) + msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, PKs[0], initBond) msgCreateValidator.MinSelfDelegation = sdk.NewInt(2) res, err := handler(ctx, msgCreateValidator) require.NoError(t, err) @@ -422,7 +423,7 @@ func TestEditValidatorIncreaseMinSelfDelegationBeyondCurrentBond(t *testing.T) { initBond, gotBond, bond) newMinSelfDelegation := initBond.Add(sdk.OneInt()) - msgEditValidator := staking.NewMsgEditValidator(validatorAddr, staking.Description{}, nil, &newMinSelfDelegation) + msgEditValidator := NewMsgEditValidator(validatorAddr, Description{}, nil, &newMinSelfDelegation) res, err = handler(ctx, msgEditValidator) require.Error(t, err) require.Nil(t, res) @@ -431,16 +432,16 @@ func TestEditValidatorIncreaseMinSelfDelegationBeyondCurrentBond(t *testing.T) { func TestIncrementsMsgUnbond(t *testing.T) { initPower := int64(1000) initBond := sdk.TokensFromConsensusPower(initPower) - ctx, _, bk, keeper, _ := keep.CreateTestInput(t, false, initPower) - handler := staking.NewHandler(keeper) + ctx, _, bk, keeper, _ := CreateTestInput(t, false, initPower) + handler := NewHandler(keeper) params := keeper.GetParams(ctx) denom := params.BondDenom // create validator, delegate - validatorAddr, delegatorAddr := sdk.ValAddress(keep.Addrs[0]), keep.Addrs[1] + validatorAddr, delegatorAddr := sdk.ValAddress(Addrs[0]), Addrs[1] - msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], initBond) + msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, PKs[0], initBond) res, err := handler(ctx, msgCreateValidator) require.NoError(t, err) require.NotNil(t, res) @@ -468,7 +469,7 @@ func TestIncrementsMsgUnbond(t *testing.T) { // just send the same msgUnbond multiple times // TODO use decimals here unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)) - msgUndelegate := staking.NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt) + msgUndelegate := NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt) numUnbonds := int64(5) for i := int64(0); i < numUnbonds; i++ { @@ -483,7 +484,7 @@ func TestIncrementsMsgUnbond(t *testing.T) { require.NoError(t, err) ctx = ctx.WithBlockTime(finishTime) - staking.EndBlocker(ctx, keeper) + EndBlocker(ctx, keeper) // check that the accounts and the bond account have the appropriate values validator, found = keeper.GetValidator(ctx, validatorAddr) @@ -521,7 +522,7 @@ func TestIncrementsMsgUnbond(t *testing.T) { for _, c := range errorCases { unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, c) - msgUndelegate := staking.NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt) + msgUndelegate := NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt) res, err = handler(ctx, msgUndelegate) require.Error(t, err) require.Nil(t, res) @@ -531,7 +532,7 @@ func TestIncrementsMsgUnbond(t *testing.T) { // should be able to unbond remaining unbondAmt = sdk.NewCoin(sdk.DefaultBondDenom, leftBonded) - msgUndelegate = staking.NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt) + 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) @@ -540,28 +541,28 @@ func TestIncrementsMsgUnbond(t *testing.T) { func TestMultipleMsgCreateValidator(t *testing.T) { initPower := int64(1000) initTokens := sdk.TokensFromConsensusPower(initPower) - ctx, _, bk, keeper, _ := keep.CreateTestInput(t, false, initPower) - handler := staking.NewHandler(keeper) + 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(keep.Addrs[0]), - sdk.ValAddress(keep.Addrs[1]), - sdk.ValAddress(keep.Addrs[2]), + sdk.ValAddress(Addrs[0]), + sdk.ValAddress(Addrs[1]), + sdk.ValAddress(Addrs[2]), } delegatorAddrs := []sdk.AccAddress{ - keep.Addrs[0], - keep.Addrs[1], - keep.Addrs[2], + Addrs[0], + Addrs[1], + Addrs[2], } // bond them all for i, validatorAddr := range validatorAddrs { valTokens := sdk.TokensFromConsensusPower(10) - msgCreateValidatorOnBehalfOf := NewTestMsgCreateValidator(validatorAddr, keep.PKs[i], valTokens) + msgCreateValidatorOnBehalfOf := NewTestMsgCreateValidator(validatorAddr, PKs[i], valTokens) res, err := handler(ctx, msgCreateValidatorOnBehalfOf) require.NoError(t, err) @@ -580,7 +581,7 @@ func TestMultipleMsgCreateValidator(t *testing.T) { require.Equal(t, balanceExpd, balanceGot, "expected account to have %d, got %d", balanceExpd, balanceGot) } - staking.EndBlocker(ctx, keeper) + EndBlocker(ctx, keeper) // unbond them all by removing delegation for i, validatorAddr := range validatorAddrs { @@ -588,7 +589,7 @@ func TestMultipleMsgCreateValidator(t *testing.T) { require.True(t, found) unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(10)) - msgUndelegate := staking.NewMsgUndelegate(delegatorAddrs[i], validatorAddr, unbondAmt) // remove delegation + msgUndelegate := NewMsgUndelegate(delegatorAddrs[i], validatorAddr, unbondAmt) // remove delegation res, err := handler(ctx, msgUndelegate) require.NoError(t, err) require.NotNil(t, res) @@ -600,10 +601,10 @@ func TestMultipleMsgCreateValidator(t *testing.T) { require.NoError(t, err) // adds validator into unbonding queue - staking.EndBlocker(ctx, keeper) + EndBlocker(ctx, keeper) // removes validator from queue and set - staking.EndBlocker(ctx.WithBlockTime(blockTime.Add(params.UnbondingTime)), keeper) + EndBlocker(ctx.WithBlockTime(blockTime.Add(params.UnbondingTime)), keeper) // Check that the validator is deleted from state validators := keeper.GetValidators(ctx, 100) @@ -619,12 +620,12 @@ func TestMultipleMsgCreateValidator(t *testing.T) { } func TestMultipleMsgDelegate(t *testing.T) { - ctx, _, _, keeper, _ := keep.CreateTestInput(t, false, 1000) - handler := staking.NewHandler(keeper) - validatorAddr, delegatorAddrs := sdk.ValAddress(keep.Addrs[0]), keep.Addrs[1:] + ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) + handler := NewHandler(keeper) + validatorAddr, delegatorAddrs := sdk.ValAddress(Addrs[0]), Addrs[1:] // first make a validator - msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], sdk.NewInt(10)) + msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, PKs[0], sdk.NewInt(10)) res, err := handler(ctx, msgCreateValidator) require.NoError(t, err) require.NotNil(t, res) @@ -645,7 +646,7 @@ func TestMultipleMsgDelegate(t *testing.T) { // unbond them all for _, delegatorAddr := range delegatorAddrs { unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)) - msgUndelegate := staking.NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt) + msgUndelegate := NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt) res, err := handler(ctx, msgUndelegate) require.NoError(t, err) @@ -658,7 +659,7 @@ func TestMultipleMsgDelegate(t *testing.T) { require.NoError(t, err) ctx = ctx.WithBlockTime(finishTime) - staking.EndBlocker(ctx, keeper) + EndBlocker(ctx, keeper) // check that the account is unbonded _, found := keeper.GetDelegation(ctx, delegatorAddr, validatorAddr) @@ -667,12 +668,12 @@ func TestMultipleMsgDelegate(t *testing.T) { } func TestJailValidator(t *testing.T) { - ctx, _, _, keeper, _ := keep.CreateTestInput(t, false, 1000) - handler := staking.NewHandler(keeper) - validatorAddr, delegatorAddr := sdk.ValAddress(keep.Addrs[0]), keep.Addrs[1] + ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) + handler := NewHandler(keeper) + validatorAddr, delegatorAddr := sdk.ValAddress(Addrs[0]), Addrs[1] // create the validator - msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], sdk.NewInt(10)) + msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, PKs[0], sdk.NewInt(10)) res, err := handler(ctx, msgCreateValidator) require.NoError(t, err) require.NotNil(t, res) @@ -685,7 +686,7 @@ func TestJailValidator(t *testing.T) { // unbond the validators bond portion unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)) - msgUndelegateValidator := staking.NewMsgUndelegate(sdk.AccAddress(validatorAddr), validatorAddr, unbondAmt) + msgUndelegateValidator := NewMsgUndelegate(sdk.AccAddress(validatorAddr), validatorAddr, unbondAmt) res, err = handler(ctx, msgUndelegateValidator) require.NoError(t, err) require.NotNil(t, res) @@ -697,14 +698,14 @@ func TestJailValidator(t *testing.T) { require.NoError(t, err) ctx = ctx.WithBlockTime(finishTime) - staking.EndBlocker(ctx, keeper) + 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 := staking.NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt) + msgUndelegateDelegator := NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt) res, err = handler(ctx, msgUndelegateDelegator) require.NoError(t, err) @@ -717,7 +718,7 @@ func TestJailValidator(t *testing.T) { require.NoError(t, err) ctx = ctx.WithBlockTime(finishTime) - staking.EndBlocker(ctx, keeper) + EndBlocker(ctx, keeper) // verify that the pubkey can now be reused res, err = handler(ctx, msgCreateValidator) @@ -726,9 +727,9 @@ func TestJailValidator(t *testing.T) { } func TestValidatorQueue(t *testing.T) { - ctx, _, _, keeper, _ := keep.CreateTestInput(t, false, 1000) - handler := staking.NewHandler(keeper) - validatorAddr, delegatorAddr := sdk.ValAddress(keep.Addrs[0]), keep.Addrs[1] + 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) @@ -737,7 +738,7 @@ func TestValidatorQueue(t *testing.T) { // create the validator valTokens := sdk.TokensFromConsensusPower(10) - msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], valTokens) + msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, PKs[0], valTokens) res, err := handler(ctx, msgCreateValidator) require.NoError(t, err) require.NotNil(t, res) @@ -749,11 +750,11 @@ func TestValidatorQueue(t *testing.T) { require.NoError(t, err) require.NotNil(t, res) - staking.EndBlocker(ctx, keeper) + EndBlocker(ctx, keeper) // unbond the all self-delegation to put validator in unbonding state unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, delTokens) - msgUndelegateValidator := staking.NewMsgUndelegate(sdk.AccAddress(validatorAddr), validatorAddr, unbondAmt) + msgUndelegateValidator := NewMsgUndelegate(sdk.AccAddress(validatorAddr), validatorAddr, unbondAmt) res, err = handler(ctx, msgUndelegateValidator) require.NoError(t, err) require.NotNil(t, res) @@ -765,7 +766,7 @@ func TestValidatorQueue(t *testing.T) { require.NoError(t, err) ctx = ctx.WithBlockTime(finishTime) - staking.EndBlocker(ctx, keeper) + EndBlocker(ctx, keeper) origHeader := ctx.BlockHeader() @@ -775,7 +776,7 @@ func TestValidatorQueue(t *testing.T) { // should still be unbonding at time 6 seconds later ctx = ctx.WithBlockTime(origHeader.Time.Add(time.Second * 6)) - staking.EndBlocker(ctx, keeper) + EndBlocker(ctx, keeper) validator, found = keeper.GetValidator(ctx, validatorAddr) require.True(t, found) @@ -783,7 +784,7 @@ func TestValidatorQueue(t *testing.T) { // should be in unbonded state at time 7 seconds later ctx = ctx.WithBlockTime(origHeader.Time.Add(time.Second * 7)) - staking.EndBlocker(ctx, keeper) + EndBlocker(ctx, keeper) validator, found = keeper.GetValidator(ctx, validatorAddr) require.True(t, found) @@ -791,9 +792,9 @@ func TestValidatorQueue(t *testing.T) { } func TestUnbondingPeriod(t *testing.T) { - ctx, _, _, keeper, _ := keep.CreateTestInput(t, false, 1000) - handler := staking.NewHandler(keeper) - validatorAddr := sdk.ValAddress(keep.Addrs[0]) + ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) + handler := NewHandler(keeper) + validatorAddr := sdk.ValAddress(Addrs[0]) // set the unbonding time params := keeper.GetParams(ctx) @@ -802,16 +803,16 @@ func TestUnbondingPeriod(t *testing.T) { // create the validator valTokens := sdk.TokensFromConsensusPower(10) - msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], valTokens) + msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, PKs[0], valTokens) res, err := handler(ctx, msgCreateValidator) require.NoError(t, err) require.NotNil(t, res) - staking.EndBlocker(ctx, keeper) + EndBlocker(ctx, keeper) // begin unbonding unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(10)) - msgUndelegate := staking.NewMsgUndelegate(sdk.AccAddress(validatorAddr), validatorAddr, unbondAmt) + msgUndelegate := NewMsgUndelegate(sdk.AccAddress(validatorAddr), validatorAddr, unbondAmt) res, err = handler(ctx, msgUndelegate) require.NoError(t, err) require.NotNil(t, res) @@ -822,30 +823,30 @@ func TestUnbondingPeriod(t *testing.T) { require.True(t, found, "should not have unbonded") // cannot complete unbonding at same time - staking.EndBlocker(ctx, keeper) + 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)) - staking.EndBlocker(ctx, keeper) + 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)) - staking.EndBlocker(ctx, keeper) + 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, _ := keep.CreateTestInput(t, false, 1000) - handler := staking.NewHandler(keeper) - validatorAddr, delegatorAddr := sdk.ValAddress(keep.Addrs[0]), keep.Addrs[1] + ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) + handler := NewHandler(keeper) + validatorAddr, delegatorAddr := sdk.ValAddress(Addrs[0]), Addrs[1] // create the validator - msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], sdk.NewInt(10)) + msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, PKs[0], sdk.NewInt(10)) res, err := handler(ctx, msgCreateValidator) require.NoError(t, err) require.NotNil(t, res) @@ -858,7 +859,7 @@ func TestUnbondingFromUnbondingValidator(t *testing.T) { // unbond the validators bond portion unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)) - msgUndelegateValidator := staking.NewMsgUndelegate(sdk.AccAddress(validatorAddr), validatorAddr, unbondAmt) + msgUndelegateValidator := NewMsgUndelegate(sdk.AccAddress(validatorAddr), validatorAddr, unbondAmt) res, err = handler(ctx, msgUndelegateValidator) require.NoError(t, err) require.NotNil(t, res) @@ -873,7 +874,7 @@ func TestUnbondingFromUnbondingValidator(t *testing.T) { ctx = ctx.WithBlockTime(finishTime.Add(time.Second * -1)) // unbond the delegator from the validator - msgUndelegateDelegator := staking.NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt) + msgUndelegateDelegator := NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt) res, err = handler(ctx, msgUndelegateDelegator) require.NoError(t, err) require.NotNil(t, res) @@ -881,7 +882,7 @@ func TestUnbondingFromUnbondingValidator(t *testing.T) { ctx = ctx.WithBlockTime(ctx.BlockHeader().Time.Add(keeper.UnbondingTime(ctx))) // Run the EndBlocker - staking.EndBlocker(ctx, keeper) + EndBlocker(ctx, keeper) // Check to make sure that the unbonding delegation is no longer in state // (meaning it was deleted in the above EndBlocker) @@ -890,9 +891,9 @@ func TestUnbondingFromUnbondingValidator(t *testing.T) { } func TestRedelegationPeriod(t *testing.T) { - ctx, _, bk, keeper, _ := keep.CreateTestInput(t, false, 1000) - handler := staking.NewHandler(keeper) - validatorAddr, validatorAddr2 := sdk.ValAddress(keep.Addrs[0]), sdk.ValAddress(keep.Addrs[1]) + 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 @@ -901,7 +902,7 @@ func TestRedelegationPeriod(t *testing.T) { keeper.SetParams(ctx, params) // create the validators - msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, keep.PKs[0], sdk.NewInt(10)) + msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, PKs[0], sdk.NewInt(10)) // initial balance amt1 := bk.GetBalance(ctx, sdk.AccAddress(validatorAddr), denom).Amount @@ -914,7 +915,7 @@ func TestRedelegationPeriod(t *testing.T) { 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, keep.PKs[1], sdk.NewInt(10)) + msgCreateValidator = NewTestMsgCreateValidator(validatorAddr2, PKs[1], sdk.NewInt(10)) res, err = handler(ctx, msgCreateValidator) require.NoError(t, err) require.NotNil(t, res) @@ -923,7 +924,7 @@ func TestRedelegationPeriod(t *testing.T) { // begin redelegate redAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)) - msgBeginRedelegate := staking.NewMsgBeginRedelegate(sdk.AccAddress(validatorAddr), validatorAddr, validatorAddr2, redAmt) + msgBeginRedelegate := NewMsgBeginRedelegate(sdk.AccAddress(validatorAddr), validatorAddr, validatorAddr2, redAmt) res, err = handler(ctx, msgBeginRedelegate) require.NoError(t, err) require.NotNil(t, res) @@ -935,59 +936,59 @@ func TestRedelegationPeriod(t *testing.T) { origHeader := ctx.BlockHeader() // cannot complete redelegation at same time - staking.EndBlocker(ctx, keeper) + 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)) - staking.EndBlocker(ctx, keeper) + 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)) - staking.EndBlocker(ctx, keeper) + 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, _ := keep.CreateTestInput(t, false, 1000) - handler := staking.NewHandler(keeper) + ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) + handler := NewHandler(keeper) - validatorAddr := sdk.ValAddress(keep.Addrs[0]) - validatorAddr2 := sdk.ValAddress(keep.Addrs[1]) - validatorAddr3 := sdk.ValAddress(keep.Addrs[2]) + 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, keep.PKs[0], sdk.NewInt(10)) + msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, PKs[0], sdk.NewInt(10)) res, err := handler(ctx, msgCreateValidator) require.NoError(t, err) require.NotNil(t, res) - msgCreateValidator = NewTestMsgCreateValidator(validatorAddr2, keep.PKs[1], sdk.NewInt(10)) + msgCreateValidator = NewTestMsgCreateValidator(validatorAddr2, PKs[1], sdk.NewInt(10)) res, err = handler(ctx, msgCreateValidator) require.NoError(t, err) require.NotNil(t, res) - msgCreateValidator = NewTestMsgCreateValidator(validatorAddr3, keep.PKs[2], sdk.NewInt(10)) + 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 := staking.NewMsgBeginRedelegate(sdk.AccAddress(validatorAddr), validatorAddr, validatorAddr2, redAmt) + 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 = staking.NewMsgBeginRedelegate(sdk.AccAddress(validatorAddr), validatorAddr2, validatorAddr3, redAmt) + msgBeginRedelegate = NewMsgBeginRedelegate(sdk.AccAddress(validatorAddr), validatorAddr2, validatorAddr3, redAmt) res, err = handler(ctx, msgBeginRedelegate) require.Error(t, err) require.Nil(t, res) @@ -996,7 +997,7 @@ func TestTransitiveRedelegation(t *testing.T) { ctx = ctx.WithBlockTime(blockTime.Add(params.UnbondingTime)) // complete first redelegation - staking.EndBlocker(ctx, keeper) + EndBlocker(ctx, keeper) // now should be able to redelegate from the second validator to the third res, err = handler(ctx, msgBeginRedelegate) @@ -1005,11 +1006,11 @@ func TestTransitiveRedelegation(t *testing.T) { } func TestMultipleRedelegationAtSameTime(t *testing.T) { - ctx, _, _, keeper, _ := keep.CreateTestInput(t, false, 1000) - handler := staking.NewHandler(keeper) + ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) + handler := NewHandler(keeper) - valAddr := sdk.ValAddress(keep.Addrs[0]) - valAddr2 := sdk.ValAddress(keep.Addrs[1]) + valAddr := sdk.ValAddress(Addrs[0]) + valAddr2 := sdk.ValAddress(Addrs[1]) // set the unbonding time params := keeper.GetParams(ctx) @@ -1018,23 +1019,23 @@ func TestMultipleRedelegationAtSameTime(t *testing.T) { // create the validators valTokens := sdk.TokensFromConsensusPower(10) - msgCreateValidator := NewTestMsgCreateValidator(valAddr, keep.PKs[0], valTokens) + msgCreateValidator := NewTestMsgCreateValidator(valAddr, PKs[0], valTokens) res, err := handler(ctx, msgCreateValidator) require.NoError(t, err) require.NotNil(t, res) - msgCreateValidator = NewTestMsgCreateValidator(valAddr2, keep.PKs[1], valTokens) + msgCreateValidator = NewTestMsgCreateValidator(valAddr2, PKs[1], valTokens) res, err = handler(ctx, msgCreateValidator) require.NoError(t, err) require.NotNil(t, res) // end block to bond them - staking.EndBlocker(ctx, keeper) + 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 := staking.NewMsgBeginRedelegate(selfDelAddr, valAddr, valAddr2, redAmt) + msgBeginRedelegate := NewMsgBeginRedelegate(selfDelAddr, valAddr, valAddr2, redAmt) res, err = handler(ctx, msgBeginRedelegate) require.NoError(t, err) require.NotNil(t, res) @@ -1056,18 +1057,18 @@ func TestMultipleRedelegationAtSameTime(t *testing.T) { // move forward in time, should complete both redelegations ctx = ctx.WithBlockTime(ctx.BlockHeader().Time.Add(1 * time.Second)) - staking.EndBlocker(ctx, keeper) + EndBlocker(ctx, keeper) rd, found = keeper.GetRedelegation(ctx, selfDelAddr, valAddr, valAddr2) require.False(t, found) } func TestMultipleRedelegationAtUniqueTimes(t *testing.T) { - ctx, _, _, keeper, _ := keep.CreateTestInput(t, false, 1000) - handler := staking.NewHandler(keeper) + ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) + handler := NewHandler(keeper) - valAddr := sdk.ValAddress(keep.Addrs[0]) - valAddr2 := sdk.ValAddress(keep.Addrs[1]) + valAddr := sdk.ValAddress(Addrs[0]) + valAddr2 := sdk.ValAddress(Addrs[1]) // set the unbonding time params := keeper.GetParams(ctx) @@ -1076,23 +1077,23 @@ func TestMultipleRedelegationAtUniqueTimes(t *testing.T) { // create the validators valTokens := sdk.TokensFromConsensusPower(10) - msgCreateValidator := NewTestMsgCreateValidator(valAddr, keep.PKs[0], valTokens) + msgCreateValidator := NewTestMsgCreateValidator(valAddr, PKs[0], valTokens) res, err := handler(ctx, msgCreateValidator) require.NoError(t, err) require.NotNil(t, res) - msgCreateValidator = NewTestMsgCreateValidator(valAddr2, keep.PKs[1], valTokens) + msgCreateValidator = NewTestMsgCreateValidator(valAddr2, PKs[1], valTokens) res, err = handler(ctx, msgCreateValidator) require.NoError(t, err) require.NotNil(t, res) // end block to bond them - staking.EndBlocker(ctx, keeper) + 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 := staking.NewMsgBeginRedelegate(selfDelAddr, valAddr, valAddr2, redAmt) + msgBeginRedelegate := NewMsgBeginRedelegate(selfDelAddr, valAddr, valAddr2, redAmt) res, err = handler(ctx, msgBeginRedelegate) require.NoError(t, err) require.NotNil(t, res) @@ -1110,23 +1111,23 @@ func TestMultipleRedelegationAtUniqueTimes(t *testing.T) { // move forward in time, should complete the first redelegation, but not the second ctx = ctx.WithBlockTime(ctx.BlockHeader().Time.Add(5 * time.Second)) - staking.EndBlocker(ctx, keeper) + 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)) - staking.EndBlocker(ctx, keeper) + EndBlocker(ctx, keeper) rd, found = keeper.GetRedelegation(ctx, selfDelAddr, valAddr, valAddr2) require.False(t, found) } func TestMultipleUnbondingDelegationAtSameTime(t *testing.T) { - ctx, _, _, keeper, _ := keep.CreateTestInput(t, false, 1000) - handler := staking.NewHandler(keeper) + ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) + handler := NewHandler(keeper) - valAddr := sdk.ValAddress(keep.Addrs[0]) + valAddr := sdk.ValAddress(Addrs[0]) // set the unbonding time params := keeper.GetParams(ctx) @@ -1135,18 +1136,18 @@ func TestMultipleUnbondingDelegationAtSameTime(t *testing.T) { // create the validator valTokens := sdk.TokensFromConsensusPower(10) - msgCreateValidator := NewTestMsgCreateValidator(valAddr, keep.PKs[0], valTokens) + msgCreateValidator := NewTestMsgCreateValidator(valAddr, PKs[0], valTokens) res, err := handler(ctx, msgCreateValidator) require.NoError(t, err) require.NotNil(t, res) // end block to bond - staking.EndBlocker(ctx, keeper) + 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 := staking.NewMsgUndelegate(selfDelAddr, valAddr, unbondAmt) + msgUndelegate := NewMsgUndelegate(selfDelAddr, valAddr, unbondAmt) res, err = handler(ctx, msgUndelegate) require.NoError(t, err) require.NotNil(t, res) @@ -1168,16 +1169,16 @@ func TestMultipleUnbondingDelegationAtSameTime(t *testing.T) { // move forwaubd in time, should complete both ubds ctx = ctx.WithBlockTime(ctx.BlockHeader().Time.Add(1 * time.Second)) - staking.EndBlocker(ctx, keeper) + EndBlocker(ctx, keeper) ubd, found = keeper.GetUnbondingDelegation(ctx, selfDelAddr, valAddr) require.False(t, found) } func TestMultipleUnbondingDelegationAtUniqueTimes(t *testing.T) { - ctx, _, _, keeper, _ := keep.CreateTestInput(t, false, 1000) - handler := staking.NewHandler(keeper) - valAddr := sdk.ValAddress(keep.Addrs[0]) + ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) + handler := NewHandler(keeper) + valAddr := sdk.ValAddress(Addrs[0]) // set the unbonding time params := keeper.GetParams(ctx) @@ -1186,18 +1187,18 @@ func TestMultipleUnbondingDelegationAtUniqueTimes(t *testing.T) { // create the validator valTokens := sdk.TokensFromConsensusPower(10) - msgCreateValidator := NewTestMsgCreateValidator(valAddr, keep.PKs[0], valTokens) + msgCreateValidator := NewTestMsgCreateValidator(valAddr, PKs[0], valTokens) res, err := handler(ctx, msgCreateValidator) require.NoError(t, err) require.NotNil(t, res) // end block to bond - staking.EndBlocker(ctx, keeper) + 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 := staking.NewMsgUndelegate(selfDelAddr, valAddr, unbondAmt) + msgUndelegate := NewMsgUndelegate(selfDelAddr, valAddr, unbondAmt) res, err = handler(ctx, msgUndelegate) require.NoError(t, err) require.NotNil(t, res) @@ -1220,25 +1221,25 @@ func TestMultipleUnbondingDelegationAtUniqueTimes(t *testing.T) { // move forwaubd in time, should complete the first redelegation, but not the second ctx = ctx.WithBlockTime(ctx.BlockHeader().Time.Add(5 * time.Second)) - staking.EndBlocker(ctx, keeper) + 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)) - staking.EndBlocker(ctx, keeper) + EndBlocker(ctx, keeper) ubd, found = keeper.GetUnbondingDelegation(ctx, selfDelAddr, valAddr) require.False(t, found) } func TestUnbondingWhenExcessValidators(t *testing.T) { - ctx, _, _, keeper, _ := keep.CreateTestInput(t, false, 1000) - handler := staking.NewHandler(keeper) + ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) + handler := NewHandler(keeper) - validatorAddr1 := sdk.ValAddress(keep.Addrs[0]) - validatorAddr2 := sdk.ValAddress(keep.Addrs[1]) - validatorAddr3 := sdk.ValAddress(keep.Addrs[2]) + validatorAddr1 := sdk.ValAddress(Addrs[0]) + validatorAddr2 := sdk.ValAddress(Addrs[1]) + validatorAddr3 := sdk.ValAddress(Addrs[2]) // set the unbonding time params := keeper.GetParams(ctx) @@ -1247,7 +1248,7 @@ func TestUnbondingWhenExcessValidators(t *testing.T) { // add three validators valTokens1 := sdk.TokensFromConsensusPower(50) - msgCreateValidator := NewTestMsgCreateValidator(validatorAddr1, keep.PKs[0], valTokens1) + msgCreateValidator := NewTestMsgCreateValidator(validatorAddr1, PKs[0], valTokens1) res, err := handler(ctx, msgCreateValidator) require.NoError(t, err) require.NotNil(t, res) @@ -1257,7 +1258,7 @@ func TestUnbondingWhenExcessValidators(t *testing.T) { require.Equal(t, 1, len(keeper.GetLastValidators(ctx))) valTokens2 := sdk.TokensFromConsensusPower(30) - msgCreateValidator = NewTestMsgCreateValidator(validatorAddr2, keep.PKs[1], valTokens2) + msgCreateValidator = NewTestMsgCreateValidator(validatorAddr2, PKs[1], valTokens2) res, err = handler(ctx, msgCreateValidator) require.NoError(t, err) require.NotNil(t, res) @@ -1267,7 +1268,7 @@ func TestUnbondingWhenExcessValidators(t *testing.T) { require.Equal(t, 2, len(keeper.GetLastValidators(ctx))) valTokens3 := sdk.TokensFromConsensusPower(10) - msgCreateValidator = NewTestMsgCreateValidator(validatorAddr3, keep.PKs[2], valTokens3) + msgCreateValidator = NewTestMsgCreateValidator(validatorAddr3, PKs[2], valTokens3) res, err = handler(ctx, msgCreateValidator) require.NoError(t, err) require.NotNil(t, res) @@ -1278,7 +1279,7 @@ func TestUnbondingWhenExcessValidators(t *testing.T) { // unbond the validator-2 unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, valTokens2) - msgUndelegate := staking.NewMsgUndelegate(sdk.AccAddress(validatorAddr2), validatorAddr2, unbondAmt) + msgUndelegate := NewMsgUndelegate(sdk.AccAddress(validatorAddr2), validatorAddr2, unbondAmt) res, err = handler(ctx, msgUndelegate) require.NoError(t, err) require.NotNil(t, res) @@ -1297,19 +1298,19 @@ func TestUnbondingWhenExcessValidators(t *testing.T) { } func TestBondUnbondRedelegateSlashTwice(t *testing.T) { - ctx, _, _, keeper, _ := keep.CreateTestInput(t, false, 1000) - handler := staking.NewHandler(keeper) + ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) + handler := NewHandler(keeper) - valA, valB, del := sdk.ValAddress(keep.Addrs[0]), sdk.ValAddress(keep.Addrs[1]), keep.Addrs[2] - consAddr0 := sdk.ConsAddress(keep.PKs[0].Address()) + 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, keep.PKs[0], valTokens) + msgCreateValidator := NewTestMsgCreateValidator(valA, PKs[0], valTokens) res, err := handler(ctx, msgCreateValidator) require.NoError(t, err) require.NotNil(t, res) - msgCreateValidator = NewTestMsgCreateValidator(valB, keep.PKs[1], valTokens) + msgCreateValidator = NewTestMsgCreateValidator(valB, PKs[1], valTokens) res, err = handler(ctx, msgCreateValidator) require.NoError(t, err) require.NotNil(t, res) @@ -1329,14 +1330,14 @@ func TestBondUnbondRedelegateSlashTwice(t *testing.T) { // begin unbonding 4 stake unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(4)) - msgUndelegate := staking.NewMsgUndelegate(del, valA, unbondAmt) + 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 := staking.NewMsgBeginRedelegate(del, valA, valB, redAmt) + msgBeginRedelegate := NewMsgBeginRedelegate(del, valA, valB, redAmt) res, err = handler(ctx, msgBeginRedelegate) require.NoError(t, err) require.NotNil(t, res) @@ -1395,7 +1396,7 @@ func TestBondUnbondRedelegateSlashTwice(t *testing.T) { require.Equal(t, sdk.NewDecFromInt(redAmt.Amount.QuoRaw(2)), delegation.Shares) // end blocker - staking.EndBlocker(ctx, keeper) + EndBlocker(ctx, keeper) // validator power should have been reduced to zero // validator should be in unbonding state @@ -1404,8 +1405,8 @@ func TestBondUnbondRedelegateSlashTwice(t *testing.T) { } func TestInvalidMsg(t *testing.T) { - k := keep.Keeper{} - h := staking.NewHandler(k) + k := Keeper{} + h := NewHandler(k) res, err := h(sdk.NewContext(nil, abci.Header{}, false, nil), sdk.NewTestMsg()) require.Error(t, err) @@ -1414,10 +1415,10 @@ func TestInvalidMsg(t *testing.T) { } func TestInvalidCoinDenom(t *testing.T) { - ctx, _, _, keeper, _ := keep.CreateTestInput(t, false, 1000) - handler := staking.NewHandler(keeper) + ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) + handler := NewHandler(keeper) - valA, valB, delAddr := sdk.ValAddress(keep.Addrs[0]), sdk.ValAddress(keep.Addrs[1]), keep.Addrs[2] + valA, valB, delAddr := sdk.ValAddress(Addrs[0]), sdk.ValAddress(Addrs[1]), Addrs[2] valTokens := sdk.TokensFromConsensusPower(100) invalidCoin := sdk.NewCoin("churros", valTokens) @@ -1426,17 +1427,17 @@ func TestInvalidCoinDenom(t *testing.T) { commission := types.NewCommissionRates(sdk.OneDec(), sdk.OneDec(), sdk.ZeroDec()) - msgCreate := types.NewMsgCreateValidator(valA, keep.PKs[0], invalidCoin, staking.Description{}, commission, sdk.OneInt()) + 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, keep.PKs[0], validCoin, staking.Description{}, commission, sdk.OneInt()) + 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, keep.PKs[1], validCoin, staking.Description{}, commission, sdk.OneInt()) + msgCreate = types.NewMsgCreateValidator(valB, PKs[1], validCoin, Description{}, commission, sdk.OneInt()) res, err = handler(ctx, msgCreate) require.NoError(t, err) require.NotNil(t, res) diff --git a/x/staking/keeper/old_test_common.go b/x/staking/keeper/old_test_common.go index e1c75edeae29..80a78701c0f9 100644 --- a/x/staking/keeper/old_test_common.go +++ b/x/staking/keeper/old_test_common.go @@ -2,220 +2,12 @@ package keeper // noalias import ( "bytes" - "encoding/hex" "math/rand" - "strconv" - "testing" - "github.com/stretchr/testify/require" - abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/tendermint/tendermint/libs/log" - tmtypes "github.com/tendermint/tendermint/types" - dbm "github.com/tendermint/tm-db" - - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth" - authexported "github.com/cosmos/cosmos-sdk/x/auth/exported" - "github.com/cosmos/cosmos-sdk/x/bank" - "github.com/cosmos/cosmos-sdk/x/params" "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/cosmos/cosmos-sdk/x/supply" -) - -// dummy addresses used for testing -// nolint:unused, deadcode -var ( - Addrs = createTestAddrs(500) - PKs = createTestPubKeys(500) ) -// create a codec used only for testing -func MakeTestCodec() *codec.Codec { - var cdc = codec.New() - - // Register Msgs - cdc.RegisterInterface((*sdk.Msg)(nil), nil) - cdc.RegisterConcrete(bank.MsgSend{}, "test/staking/Send", nil) - cdc.RegisterConcrete(types.MsgCreateValidator{}, "test/staking/CreateValidator", nil) - cdc.RegisterConcrete(types.MsgEditValidator{}, "test/staking/EditValidator", nil) - cdc.RegisterConcrete(types.MsgUndelegate{}, "test/staking/Undelegate", nil) - cdc.RegisterConcrete(types.MsgBeginRedelegate{}, "test/staking/BeginRedelegate", nil) - - // Register AppAccount - cdc.RegisterInterface((*authexported.Account)(nil), nil) - cdc.RegisterConcrete(&auth.BaseAccount{}, "test/staking/BaseAccount", nil) - supply.RegisterCodec(cdc) - codec.RegisterCrypto(cdc) - - return cdc -} - -// Hogpodge of all sorts of input required for testing. -// `initPower` is converted to an amount of tokens. -// If `initPower` is 0, no addrs get created. -func CreateTestInput(t *testing.T, isCheckTx bool, initPower int64) (sdk.Context, auth.AccountKeeper, types.BankKeeper, Keeper, types.SupplyKeeper) { - keyStaking := sdk.NewKVStoreKey(types.StoreKey) - keyAcc := sdk.NewKVStoreKey(auth.StoreKey) - bankKey := sdk.NewKVStoreKey(bank.StoreKey) - keyParams := sdk.NewKVStoreKey(params.StoreKey) - keySupply := sdk.NewKVStoreKey(supply.StoreKey) - - tkeyParams := sdk.NewTransientStoreKey(params.TStoreKey) - - db := dbm.NewMemDB() - ms := store.NewCommitMultiStore(db) - ms.MountStoreWithDB(keyStaking, sdk.StoreTypeIAVL, db) - ms.MountStoreWithDB(keyAcc, sdk.StoreTypeIAVL, db) - ms.MountStoreWithDB(bankKey, sdk.StoreTypeIAVL, db) - ms.MountStoreWithDB(keyParams, sdk.StoreTypeIAVL, db) - ms.MountStoreWithDB(tkeyParams, sdk.StoreTypeTransient, db) - ms.MountStoreWithDB(keySupply, sdk.StoreTypeIAVL, db) - err := ms.LoadLatestVersion() - require.Nil(t, err) - - ctx := sdk.NewContext(ms, abci.Header{ChainID: "foochainid"}, isCheckTx, log.NewNopLogger()) - ctx = ctx.WithConsensusParams( - &abci.ConsensusParams{ - Validator: &abci.ValidatorParams{ - PubKeyTypes: []string{tmtypes.ABCIPubKeyTypeEd25519}, - }, - }, - ) - cdc := MakeTestCodec() - - feeCollectorAcc := supply.NewEmptyModuleAccount(auth.FeeCollectorName) - notBondedPool := supply.NewEmptyModuleAccount(types.NotBondedPoolName, supply.Burner, supply.Staking) - bondPool := supply.NewEmptyModuleAccount(types.BondedPoolName, supply.Burner, supply.Staking) - - blacklistedAddrs := make(map[string]bool) - blacklistedAddrs[feeCollectorAcc.GetAddress().String()] = true - blacklistedAddrs[notBondedPool.GetAddress().String()] = true - blacklistedAddrs[bondPool.GetAddress().String()] = true - - pk := params.NewKeeper(params.ModuleCdc, keyParams, tkeyParams) - - accountKeeper := auth.NewAccountKeeper( - cdc, // amino codec - keyAcc, // target store - pk.Subspace(auth.DefaultParamspace), - auth.ProtoBaseAccount, // prototype - ) - - bk := bank.NewBaseKeeper( - cdc, - bankKey, - accountKeeper, - pk.Subspace(bank.DefaultParamspace), - blacklistedAddrs, - ) - - maccPerms := map[string][]string{ - auth.FeeCollectorName: nil, - types.NotBondedPoolName: {supply.Burner, supply.Staking}, - types.BondedPoolName: {supply.Burner, supply.Staking}, - } - supplyKeeper := supply.NewKeeper(cdc, keySupply, accountKeeper, bk, maccPerms) - - initTokens := sdk.TokensFromConsensusPower(initPower) - initCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens)) - totalSupply := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens.MulRaw(int64(len(Addrs))))) - - supplyKeeper.SetSupply(ctx, supply.NewSupply(totalSupply)) - - keeper := NewKeeper(types.ModuleCdc, keyStaking, bk, supplyKeeper, pk.Subspace(DefaultParamspace)) - keeper.SetParams(ctx, types.DefaultParams()) - - // set module accounts - require.NoError(t, bk.SetBalances(ctx, notBondedPool.GetAddress(), totalSupply)) - - supplyKeeper.SetModuleAccount(ctx, feeCollectorAcc) - supplyKeeper.SetModuleAccount(ctx, bondPool) - supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - // fill all the addresses with some coins, set the loose pool tokens simultaneously - for i, addr := range Addrs { - accountKeeper.SetAccount(ctx, auth.NewBaseAccount(addr, PKs[i], uint64(i), 0)) - require.NoError(t, bk.SetBalances(ctx, addr, initCoins)) - } - - return ctx, accountKeeper, bk, keeper, supplyKeeper -} - -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 -} - -// for incode address generation -func TestAddr(addr string, bech string) sdk.AccAddress { - - res, err := sdk.AccAddressFromHex(addr) - if err != nil { - panic(err) - } - bechexpected := res.String() - if bech != bechexpected { - panic("Bech encoding doesn't match reference") - } - - bechres, err := sdk.AccAddressFromBech32(bech) - if err != nil { - panic(err) - } - if !bytes.Equal(bechres, res) { - panic("Bech decode and hex decode don't match") - } - - return res -} - -// nolint: unparam -func createTestAddrs(numAddrs int) []sdk.AccAddress { - var addresses []sdk.AccAddress - var buffer bytes.Buffer - - // start at 100 so we can make up to 999 test addresses with valid test addresses - for i := 100; i < (numAddrs + 100); i++ { - numString := strconv.Itoa(i) - buffer.WriteString("A58856F0FD53BF058B4909A21AEC019107BA6") //base address string - - buffer.WriteString(numString) //adding on final two digits to make addresses unique - res, _ := sdk.AccAddressFromHex(buffer.String()) - bech := res.String() - addresses = append(addresses, TestAddr(buffer.String(), bech)) - buffer.Reset() - } - return addresses -} - -// 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 -} - -//_____________________________________________________________________________________ - // does a certain by-power index record exist func ValidatorByPowerIndexExists(ctx sdk.Context, keeper Keeper, power []byte) bool { store := ctx.KVStore(keeper.storeKey) diff --git a/x/staking/test_common.go b/x/staking/test_common.go new file mode 100644 index 000000000000..0760ebcc575a --- /dev/null +++ b/x/staking/test_common.go @@ -0,0 +1,217 @@ +package staking + +import ( + "bytes" + "encoding/hex" + "strconv" + "testing" + + "github.com/stretchr/testify/require" + + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/crypto" + "github.com/tendermint/tendermint/crypto/ed25519" + "github.com/tendermint/tendermint/libs/log" + tmtypes "github.com/tendermint/tendermint/types" + dbm "github.com/tendermint/tm-db" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/store" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" + authexported "github.com/cosmos/cosmos-sdk/x/auth/exported" + "github.com/cosmos/cosmos-sdk/x/bank" + "github.com/cosmos/cosmos-sdk/x/params" + "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/cosmos/cosmos-sdk/x/supply" +) + +// dummy addresses used for testing +// nolint:unused, deadcode +var ( + Addrs = createTestAddrs(500) + PKs = createTestPubKeys(500) +) + +// nolint: unparam +func createTestAddrs(numAddrs int) []sdk.AccAddress { + var addresses []sdk.AccAddress + var buffer bytes.Buffer + + // start at 100 so we can make up to 999 test addresses with valid test addresses + for i := 100; i < (numAddrs + 100); i++ { + numString := strconv.Itoa(i) + buffer.WriteString("A58856F0FD53BF058B4909A21AEC019107BA6") //base address string + + buffer.WriteString(numString) //adding on final two digits to make addresses unique + res, _ := sdk.AccAddressFromHex(buffer.String()) + bech := res.String() + addresses = append(addresses, TestAddr(buffer.String(), bech)) + buffer.Reset() + } + return addresses +} + +// 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 +} + +//_____________________________________________________________________________________ + +// Hogpodge of all sorts of input required for testing. +// `initPower` is converted to an amount of tokens. +// If `initPower` is 0, no addrs get created. +func CreateTestInput(t *testing.T, isCheckTx bool, initPower int64) (sdk.Context, auth.AccountKeeper, types.BankKeeper, Keeper, types.SupplyKeeper) { + keyStaking := sdk.NewKVStoreKey(types.StoreKey) + keyAcc := sdk.NewKVStoreKey(auth.StoreKey) + bankKey := sdk.NewKVStoreKey(bank.StoreKey) + keyParams := sdk.NewKVStoreKey(params.StoreKey) + keySupply := sdk.NewKVStoreKey(supply.StoreKey) + + tkeyParams := sdk.NewTransientStoreKey(params.TStoreKey) + + db := dbm.NewMemDB() + ms := store.NewCommitMultiStore(db) + ms.MountStoreWithDB(keyStaking, sdk.StoreTypeIAVL, db) + ms.MountStoreWithDB(keyAcc, sdk.StoreTypeIAVL, db) + ms.MountStoreWithDB(bankKey, sdk.StoreTypeIAVL, db) + ms.MountStoreWithDB(keyParams, sdk.StoreTypeIAVL, db) + ms.MountStoreWithDB(tkeyParams, sdk.StoreTypeTransient, db) + ms.MountStoreWithDB(keySupply, sdk.StoreTypeIAVL, db) + err := ms.LoadLatestVersion() + require.Nil(t, err) + + ctx := sdk.NewContext(ms, abci.Header{ChainID: "foochainid"}, isCheckTx, log.NewNopLogger()) + ctx = ctx.WithConsensusParams( + &abci.ConsensusParams{ + Validator: &abci.ValidatorParams{ + PubKeyTypes: []string{tmtypes.ABCIPubKeyTypeEd25519}, + }, + }, + ) + cdc := MakeTestCodec() + + feeCollectorAcc := supply.NewEmptyModuleAccount(auth.FeeCollectorName) + notBondedPool := supply.NewEmptyModuleAccount(types.NotBondedPoolName, supply.Burner, supply.Staking) + bondPool := supply.NewEmptyModuleAccount(types.BondedPoolName, supply.Burner, supply.Staking) + + blacklistedAddrs := make(map[string]bool) + blacklistedAddrs[feeCollectorAcc.GetAddress().String()] = true + blacklistedAddrs[notBondedPool.GetAddress().String()] = true + blacklistedAddrs[bondPool.GetAddress().String()] = true + + pk := params.NewKeeper(params.ModuleCdc, keyParams, tkeyParams) + + accountKeeper := auth.NewAccountKeeper( + cdc, // amino codec + keyAcc, // target store + pk.Subspace(auth.DefaultParamspace), + auth.ProtoBaseAccount, // prototype + ) + + bk := bank.NewBaseKeeper( + cdc, + bankKey, + accountKeeper, + pk.Subspace(bank.DefaultParamspace), + blacklistedAddrs, + ) + + maccPerms := map[string][]string{ + auth.FeeCollectorName: nil, + types.NotBondedPoolName: {supply.Burner, supply.Staking}, + types.BondedPoolName: {supply.Burner, supply.Staking}, + } + supplyKeeper := supply.NewKeeper(cdc, keySupply, accountKeeper, bk, maccPerms) + + initTokens := sdk.TokensFromConsensusPower(initPower) + initCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens)) + totalSupply := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens.MulRaw(int64(len(Addrs))))) + + supplyKeeper.SetSupply(ctx, supply.NewSupply(totalSupply)) + + keeper := NewKeeper(types.ModuleCdc, keyStaking, bk, supplyKeeper, pk.Subspace(DefaultParamspace)) + keeper.SetParams(ctx, types.DefaultParams()) + + // set module accounts + require.NoError(t, bk.SetBalances(ctx, notBondedPool.GetAddress(), totalSupply)) + + supplyKeeper.SetModuleAccount(ctx, feeCollectorAcc) + supplyKeeper.SetModuleAccount(ctx, bondPool) + supplyKeeper.SetModuleAccount(ctx, notBondedPool) + + // fill all the addresses with some coins, set the loose pool tokens simultaneously + for i, addr := range Addrs { + accountKeeper.SetAccount(ctx, auth.NewBaseAccount(addr, PKs[i], uint64(i), 0)) + require.NoError(t, bk.SetBalances(ctx, addr, initCoins)) + } + + return ctx, accountKeeper, bk, keeper, supplyKeeper +} + +// create a codec used only for testing +func MakeTestCodec() *codec.Codec { + var cdc = codec.New() + + // Register Msgs + cdc.RegisterInterface((*sdk.Msg)(nil), nil) + cdc.RegisterConcrete(bank.MsgSend{}, "test/staking/Send", nil) + cdc.RegisterConcrete(types.MsgCreateValidator{}, "test/staking/CreateValidator", nil) + cdc.RegisterConcrete(types.MsgEditValidator{}, "test/staking/EditValidator", nil) + cdc.RegisterConcrete(types.MsgUndelegate{}, "test/staking/Undelegate", nil) + cdc.RegisterConcrete(types.MsgBeginRedelegate{}, "test/staking/BeginRedelegate", nil) + + // Register AppAccount + cdc.RegisterInterface((*authexported.Account)(nil), nil) + cdc.RegisterConcrete(&auth.BaseAccount{}, "test/staking/BaseAccount", nil) + supply.RegisterCodec(cdc) + codec.RegisterCrypto(cdc) + + return cdc +} + +// for incode address generation +func TestAddr(addr string, bech string) sdk.AccAddress { + + res, err := sdk.AccAddressFromHex(addr) + if err != nil { + panic(err) + } + bechexpected := res.String() + if bech != bechexpected { + panic("Bech encoding doesn't match reference") + } + + bechres, err := sdk.AccAddressFromBech32(bech) + if err != nil { + panic(err) + } + if !bytes.Equal(bechres, res) { + panic("Bech decode and hex decode don't match") + } + + return res +} + +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 +} From b931c491aeddc4fb0f2824928cef9286bec21cf4 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Tue, 25 Feb 2020 15:29:53 +0100 Subject: [PATCH 54/90] rename --- x/staking/keeper/{old_test_common.go => test_common.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename x/staking/keeper/{old_test_common.go => test_common.go} (100%) diff --git a/x/staking/keeper/old_test_common.go b/x/staking/keeper/test_common.go similarity index 100% rename from x/staking/keeper/old_test_common.go rename to x/staking/keeper/test_common.go From a44bebc11cf2d2b293e298e347399e265ebd7c44 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Tue, 25 Feb 2020 15:31:22 +0100 Subject: [PATCH 55/90] rename commont test --- x/staking/keeper/{test_common_test.go => common_test.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename x/staking/keeper/{test_common_test.go => common_test.go} (100%) diff --git a/x/staking/keeper/test_common_test.go b/x/staking/keeper/common_test.go similarity index 100% rename from x/staking/keeper/test_common_test.go rename to x/staking/keeper/common_test.go From 194b97b1c1d37e6c6696923fa54b376789064fc1 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Tue, 25 Feb 2020 17:33:18 +0100 Subject: [PATCH 56/90] git remove unused vars --- x/staking/common_test.go | 9 --------- 1 file changed, 9 deletions(-) diff --git a/x/staking/common_test.go b/x/staking/common_test.go index 225832dd170f..291f5ea523ca 100644 --- a/x/staking/common_test.go +++ b/x/staking/common_test.go @@ -5,7 +5,6 @@ import ( "github.com/tendermint/tendermint/crypto/secp256k1" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/staking" "github.com/cosmos/cosmos-sdk/x/staking/types" ) @@ -16,14 +15,6 @@ var ( addr1 = sdk.AccAddress(priv1.PubKey().Address()) priv2 = secp256k1.GenPrivKey() addr2 = sdk.AccAddress(priv2.PubKey().Address()) - addr3 = sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()) - priv4 = secp256k1.GenPrivKey() - addr4 = sdk.AccAddress(priv4.PubKey().Address()) - coins = sdk.Coins{sdk.NewCoin("foocoin", sdk.NewInt(10))} - fee = auth.NewStdFee( - 100000, - sdk.Coins{sdk.NewCoin("foocoin", sdk.NewInt(0))}, - ) commissionRates = staking.NewCommissionRates(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()) ) From 660ffc8be5e14d41bcf7dff45ad983f02ed596a6 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Tue, 25 Feb 2020 18:01:18 +0100 Subject: [PATCH 57/90] refactor ordering functions --- simapp/test_helpers.go | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/simapp/test_helpers.go b/simapp/test_helpers.go index cfedd7d3188f..78f2fbc41476 100644 --- a/simapp/test_helpers.go +++ b/simapp/test_helpers.go @@ -82,7 +82,8 @@ func SetupWithGenesisAccounts(genAccs []authexported.GenesisAccount, balances .. type GenerateAccountStrategy func(int) []sdk.AccAddress -func Random(accNum int) []sdk.AccAddress { +// random is a strategy used by addTestAddrs() in order to generated addresses in random order. +func random(accNum int) []sdk.AccAddress { testAddrs := make([]sdk.AccAddress, accNum) for i := 0; i < accNum; i++ { pk := ed25519.GenPrivKey().PubKey() @@ -92,7 +93,8 @@ func Random(accNum int) []sdk.AccAddress { return testAddrs } -func Incremental(accNum int) []sdk.AccAddress { +// incremental is a strategy used by addTestAddrs() in order to generated addresses in ascending order. +func incremental(accNum int) []sdk.AccAddress { var addresses []sdk.AccAddress var buffer bytes.Buffer @@ -114,13 +116,13 @@ func Incremental(accNum int) []sdk.AccAddress { // AddTestAddrs constructs and returns accNum amount of accounts with an // initial balance of accAmt in random order func AddTestAddrs(app *SimApp, ctx sdk.Context, accNum int, accAmt sdk.Int) []sdk.AccAddress { - return addTestAddrs(app, ctx, accNum, accAmt, Random) + return addTestAddrs(app, ctx, accNum, accAmt, random) } // AddTestAddrs constructs and returns accNum amount of accounts with an // initial balance of accAmt in random order func AddTestAddrsIncremental(app *SimApp, ctx sdk.Context, accNum int, accAmt sdk.Int) []sdk.AccAddress { - return addTestAddrs(app, ctx, accNum, accAmt, Incremental) + return addTestAddrs(app, ctx, accNum, accAmt, incremental) } func addTestAddrs(app *SimApp, ctx sdk.Context, accNum int, accAmt sdk.Int, strategy GenerateAccountStrategy) []sdk.AccAddress { From 399ea763ee0a5fd28c90264a8b4ab11853a2b6e4 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Wed, 26 Feb 2020 10:47:39 +0100 Subject: [PATCH 58/90] 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 291f5ea523ca..871894b9bbcf 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 730e7b0fc629..29a6149e4bb3 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 f18dda6ac00c..bbbb2eaa8435 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) +//} From 315572bcd231f782a71d366c31fca99d8d0cf222 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Wed, 26 Feb 2020 11:33:25 +0100 Subject: [PATCH 59/90] refactor TestValidatorByPowerIndex --- x/staking/common_test.go | 4 +- x/staking/genesis_test.go | 2 +- x/staking/handler_test.go | 213 ++++++++++++++++++++++---------------- 3 files changed, 127 insertions(+), 92 deletions(-) diff --git a/x/staking/common_test.go b/x/staking/common_test.go index 871894b9bbcf..35f27d32c3ae 100644 --- a/x/staking/common_test.go +++ b/x/staking/common_test.go @@ -89,8 +89,8 @@ func getBaseSimappWithCustomKeeper() (*codec.Codec, *simapp.SimApp, sdk.Context) } // 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)) +func generateAddresses(app *simapp.SimApp, ctx sdk.Context, numAddrs int, accAmount int64) ([]sdk.AccAddress, []sdk.ValAddress) { + addrDels := simapp.AddTestAddrsIncremental(app, ctx, numAddrs, sdk.NewInt(accAmount)) addrVals := simapp.ConvertAddrsToValAddrs(addrDels) return addrDels, addrVals diff --git a/x/staking/genesis_test.go b/x/staking/genesis_test.go index 29a6149e4bb3..c50cd63bcdf4 100644 --- a/x/staking/genesis_test.go +++ b/x/staking/genesis_test.go @@ -21,7 +21,7 @@ import ( 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) + addrDels, addrVals := generateAddresses(app, ctx, numAddrs, 10000) amt := sdk.TokensFromConsensusPower(power) totalSupply := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), amt.MulRaw(int64(len(addrDels))))) diff --git a/x/staking/handler_test.go b/x/staking/handler_test.go index bbbb2eaa8435..40d985cfeb3e 100644 --- a/x/staking/handler_test.go +++ b/x/staking/handler_test.go @@ -1,94 +1,129 @@ package staking_test -//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)) -//} +import ( + "testing" + + gogotypes "github.com/gogo/protobuf/types" + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/simapp" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/staking" + "github.com/cosmos/cosmos-sdk/x/staking/keeper" + "github.com/cosmos/cosmos-sdk/x/staking/types" + "github.com/cosmos/cosmos-sdk/x/supply" +) + +func bootstrapHandlerGenesisTest(t *testing.T, power int64, numAddrs int, accAmount int64) (*simapp.SimApp, sdk.Context, []sdk.AccAddress, []sdk.ValAddress) { + _, app, ctx := getBaseSimappWithCustomKeeper() + + addrDels, addrVals := generateAddresses(app, ctx, numAddrs, accAmount) + + amt := sdk.TokensFromConsensusPower(power) + totalSupply := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), amt.MulRaw(int64(len(addrDels))))) + + notBondedPool := app.StakingKeeper.GetNotBondedPool(ctx) + err := app.BankKeeper.SetBalances(ctx, notBondedPool.GetAddress(), totalSupply) + require.NoError(t, err) + app.SupplyKeeper.SetModuleAccount(ctx, notBondedPool) + + app.SupplyKeeper.SetSupply(ctx, supply.NewSupply(totalSupply)) + + return app, ctx, addrDels, addrVals +} + +func TestValidatorByPowerIndex(t *testing.T) { + initPower := int64(1000000) + initBond := sdk.TokensFromConsensusPower(initPower) + + app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 10, 10000000000000) + + validatorAddr, validatorAddr3 := valAddrs[0], valAddrs[1] + + handler := staking.NewHandler(app.StakingKeeper) + + // create validator + msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, PKs[0], initBond) + res, err := handler(ctx, msgCreateValidator) + require.NoError(t, err) + require.NotNil(t, res) + + // must end-block + updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 1, len(updates)) + + // verify the self-delegation exists + bond, found := app.StakingKeeper.GetDelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr) + require.True(t, found) + gotBond := bond.Shares.RoundInt() + require.Equal(t, initBond, gotBond) + + // verify that the by power index exists + validator, found := app.StakingKeeper.GetValidator(ctx, validatorAddr) + require.True(t, found) + power := staking.GetValidatorsByPowerIndexKey(validator) + require.True(t, keeper.ValidatorByPowerIndexExists(ctx, app.StakingKeeper, power)) + + // create a second validator keep it bonded + msgCreateValidator = NewTestMsgCreateValidator(validatorAddr3, PKs[2], initBond) + res, err = handler(ctx, msgCreateValidator) + require.NoError(t, err) + require.NotNil(t, res) + + // must end-block + updates = app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 1, len(updates)) + + // slash and jail the first validator + consAddr0 := sdk.ConsAddress(PKs[0].Address()) + app.StakingKeeper.Slash(ctx, consAddr0, 0, initPower, sdk.NewDecWithPrec(5, 1)) + app.StakingKeeper.Jail(ctx, consAddr0) + app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + + validator, found = app.StakingKeeper.GetValidator(ctx, validatorAddr) + require.True(t, found) + require.Equal(t, sdk.Unbonding, validator.Status) // ensure is unbonding + require.Equal(t, initBond.QuoRaw(2), validator.Tokens) // ensure tokens slashed + app.StakingKeeper.Unjail(ctx, consAddr0) + + // the old power record should have been deleted as the power changed + require.False(t, keeper.ValidatorByPowerIndexExists(ctx, app.StakingKeeper, power)) + + // but the new power record should have been created + validator, found = app.StakingKeeper.GetValidator(ctx, validatorAddr) + require.True(t, found) + power2 := staking.GetValidatorsByPowerIndexKey(validator) + require.True(t, keeper.ValidatorByPowerIndexExists(ctx, app.StakingKeeper, power2)) + + // now the new record power index should be the same as the original record + power3 := staking.GetValidatorsByPowerIndexKey(validator) + require.Equal(t, power2, power3) + + // unbond self-delegation + totalBond := validator.TokensFromShares(bond.GetShares()).TruncateInt() + unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, totalBond) + msgUndelegate := staking.NewMsgUndelegate(sdk.AccAddress(validatorAddr), validatorAddr, unbondAmt) + + res, err = handler(ctx, msgUndelegate) + require.NoError(t, err) + require.NotNil(t, res) + + ts := &gogotypes.Timestamp{} + types.ModuleCdc.MustUnmarshalBinaryLengthPrefixed(res.Data, ts) + + finishTime, err := gogotypes.TimestampFromProto(ts) + require.NoError(t, err) + + ctx = ctx.WithBlockTime(finishTime) + staking.EndBlocker(ctx, app.StakingKeeper) + staking.EndBlocker(ctx, app.StakingKeeper) + + // verify that by power key nolonger exists + _, found = app.StakingKeeper.GetValidator(ctx, validatorAddr) + require.False(t, found) + require.False(t, keeper.ValidatorByPowerIndexExists(ctx, app.StakingKeeper, power3)) +} + // //func TestDuplicatesMsgCreateValidator(t *testing.T) { // ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) From 59ecf11a12af73920e6270609ae1108174bcafd4 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Wed, 26 Feb 2020 11:36:37 +0100 Subject: [PATCH 60/90] refactor TestDuplicatesMsgCreateValidator --- x/staking/handler_test.go | 118 ++++++++++++++++++++------------------ 1 file changed, 61 insertions(+), 57 deletions(-) diff --git a/x/staking/handler_test.go b/x/staking/handler_test.go index 40d985cfeb3e..38d6c57b2b6b 100644 --- a/x/staking/handler_test.go +++ b/x/staking/handler_test.go @@ -3,6 +3,8 @@ package staking_test import ( "testing" + "github.com/stretchr/testify/assert" + gogotypes "github.com/gogo/protobuf/types" "github.com/stretchr/testify/require" @@ -124,63 +126,65 @@ func TestValidatorByPowerIndex(t *testing.T) { require.False(t, keeper.ValidatorByPowerIndexExists(ctx, app.StakingKeeper, 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 TestDuplicatesMsgCreateValidator(t *testing.T) { + initPower := int64(1000000) + app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 10, 10000000000000) + + handler := staking.NewHandler(app.StakingKeeper) + + addr1, addr2 := valAddrs[0], valAddrs[1] + pk1, pk2 := PKs[0], PKs[1] + + valTokens := sdk.TokensFromConsensusPower(10) + msgCreateValidator1 := NewTestMsgCreateValidator(addr1, pk1, valTokens) + res, err := handler(ctx, msgCreateValidator1) + require.NoError(t, err) + require.NotNil(t, res) + + app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + + validator, found := app.StakingKeeper.GetValidator(ctx, addr1) + require.True(t, found) + assert.Equal(t, sdk.Bonded, validator.Status) + assert.Equal(t, addr1, validator.OperatorAddress) + assert.Equal(t, pk1, validator.GetConsPubKey()) + assert.Equal(t, valTokens, validator.BondedTokens()) + assert.Equal(t, valTokens.ToDec(), validator.DelegatorShares) + assert.Equal(t, types.Description{}, validator.Description) + + // two validators can't have the same operator address + msgCreateValidator2 := NewTestMsgCreateValidator(addr1, pk2, valTokens) + res, err = handler(ctx, msgCreateValidator2) + require.Error(t, err) + require.Nil(t, res) + + // two validators can't have the same pubkey + msgCreateValidator3 := NewTestMsgCreateValidator(addr2, pk1, valTokens) + res, err = handler(ctx, msgCreateValidator3) + require.Error(t, err) + require.Nil(t, res) + + // must have different pubkey and operator + msgCreateValidator4 := NewTestMsgCreateValidator(addr2, pk2, valTokens) + res, err = handler(ctx, msgCreateValidator4) + require.NoError(t, err) + require.NotNil(t, res) + + // must end-block + updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 1, len(updates)) + + validator, found = app.StakingKeeper.GetValidator(ctx, addr2) + + require.True(t, found) + assert.Equal(t, sdk.Bonded, validator.Status) + assert.Equal(t, addr2, validator.OperatorAddress) + assert.Equal(t, pk2, validator.GetConsPubKey()) + assert.True(sdk.IntEq(t, valTokens, validator.Tokens)) + assert.True(sdk.DecEq(t, valTokens.ToDec(), validator.DelegatorShares)) + assert.Equal(t, types.Description{}, validator.Description) +} + // //func TestInvalidPubKeyTypeMsgCreateValidator(t *testing.T) { // ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) From 030f612b6c707dd3d7ac933786c23f1587b27805 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Wed, 26 Feb 2020 12:23:55 +0100 Subject: [PATCH 61/90] refactor TestInvalidPubKeyTypeMsgCreateValidator --- x/staking/handler_test.go | 51 ++++++++++++++++++++++----------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/x/staking/handler_test.go b/x/staking/handler_test.go index 38d6c57b2b6b..e4281e16b41e 100644 --- a/x/staking/handler_test.go +++ b/x/staking/handler_test.go @@ -3,6 +3,10 @@ package staking_test import ( "testing" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/crypto/secp256k1" + tmtypes "github.com/tendermint/tendermint/types" + "github.com/stretchr/testify/assert" gogotypes "github.com/gogo/protobuf/types" @@ -185,28 +189,31 @@ func TestDuplicatesMsgCreateValidator(t *testing.T) { assert.Equal(t, types.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 TestInvalidPubKeyTypeMsgCreateValidator(t *testing.T) { + app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 1, 1000) + handler := staking.NewHandler(app.StakingKeeper) + ctx = ctx.WithConsensusParams(&abci.ConsensusParams{ + Validator: &abci.ValidatorParams{PubKeyTypes: []string{tmtypes.ABCIPubKeyTypeEd25519}}, + }) + + addr := valAddrs[0] + invalidPk := secp256k1.GenPrivKey().PubKey() + + // invalid pukKey type should not be allowed + msgCreateValidator := NewTestMsgCreateValidator(addr, invalidPk, sdk.NewInt(10)) + res, err := handler(ctx, msgCreateValidator) + require.Error(t, err) + require.Nil(t, res) + + ctx = ctx.WithConsensusParams(&abci.ConsensusParams{ + Validator: &abci.ValidatorParams{PubKeyTypes: []string{tmtypes.ABCIPubKeyTypeSecp256k1}}, + }) + + res, err = handler(ctx, msgCreateValidator) + require.NoError(t, err) + require.NotNil(t, res) +} + // //func TestLegacyValidatorDelegations(t *testing.T) { // ctx, _, _, keeper, _ := CreateTestInput(t, false, int64(1000)) From c314b93789af2206b6616010a415fdfbec91fa23 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Wed, 26 Feb 2020 13:28:18 +0100 Subject: [PATCH 62/90] temporary commit --- x/staking/common_test.go | 1 + x/staking/handler_test.go | 227 +++++++++++++++++++------------------- 2 files changed, 114 insertions(+), 114 deletions(-) diff --git a/x/staking/common_test.go b/x/staking/common_test.go index 35f27d32c3ae..9a3cfad368ea 100644 --- a/x/staking/common_test.go +++ b/x/staking/common_test.go @@ -84,6 +84,7 @@ func getBaseSimappWithCustomKeeper() (*codec.Codec, *simapp.SimApp, sdk.Context) app.SupplyKeeper, app.GetSubspace(staking.ModuleName), ) + app.StakingKeeper.SetParams(ctx, types.DefaultParams()) return codec.New(), app, ctx } diff --git a/x/staking/handler_test.go b/x/staking/handler_test.go index e4281e16b41e..2b1723f86a4a 100644 --- a/x/staking/handler_test.go +++ b/x/staking/handler_test.go @@ -214,118 +214,117 @@ func TestInvalidPubKeyTypeMsgCreateValidator(t *testing.T) { 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 TestLegacyValidatorDelegations(t *testing.T) { + app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 1, 100000000) + handler := staking.NewHandler(app.StakingKeeper) + + bondAmount := sdk.TokensFromConsensusPower(10) + valAddr := valAddrs[0] + valConsPubKey, valConsAddr := PKs[0], sdk.ConsAddress(PKs[0].Address()) + delAddr := delAddrs[0] + + // create validator + msgCreateVal := NewTestMsgCreateValidator(valAddr, valConsPubKey, bondAmount) + res, err := handler(ctx, msgCreateVal) + require.NoError(t, err) + require.NotNil(t, res) + + // must end-block + updates := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 1, len(updates)) + + // verify the validator exists and has the correct attributes + validator, found := app.StakingKeeper.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 = app.StakingKeeper.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 := types.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) + staking.EndBlocker(ctx, app.StakingKeeper) + + // verify the validator record still exists, is jailed, and has correct tokens + validator, found = app.StakingKeeper.GetValidator(ctx, valAddr) + require.True(t, found) + require.True(t, validator.Jailed) + require.Equal(t, bondAmount, validator.Tokens) + + // verify delegation still exists + bond, found := app.StakingKeeper.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 = app.StakingKeeper.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 + app.StakingKeeper.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 = app.StakingKeeper.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 = app.StakingKeeper.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) +// app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 2, 10000000) +// handler := staking.NewHandler(app.StakingKeeper) // -// params := keeper.GetParams(ctx) +// params := app.StakingKeeper.GetParams(ctx) // // bondAmount := sdk.TokensFromConsensusPower(10) -// validatorAddr, delegatorAddr := sdk.ValAddress(Addrs[0]), Addrs[1] +// validatorAddr, delegatorAddr := valAddrs[0], delAddrs[1] // // // first create validator // msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, PKs[0], bondAmount) @@ -334,22 +333,22 @@ func TestInvalidPubKeyTypeMsgCreateValidator(t *testing.T) { // require.NotNil(t, res) // // // apply TM updates -// keeper.ApplyAndReturnValidatorSetUpdates(ctx) +// app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) // -// validator, found := keeper.GetValidator(ctx, validatorAddr) +// validator, found := app.StakingKeeper.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) +// _, found = app.StakingKeeper.GetDelegation(ctx, delegatorAddr, validatorAddr) // require.False(t, found) // -// bond, found := keeper.GetDelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr) +// bond, found := app.StakingKeeper.GetDelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr) // require.True(t, found) // require.Equal(t, bondAmount, bond.Shares.RoundInt()) // -// bondedTokens := keeper.TotalBondedTokens(ctx) +// bondedTokens := app.StakingKeeper.TotalBondedTokens(ctx) // require.Equal(t, bondAmount.Int64(), bondedTokens.Int64()) // // // just send the same msgbond multiple times @@ -363,9 +362,9 @@ func TestInvalidPubKeyTypeMsgCreateValidator(t *testing.T) { // require.NotNil(t, res) // // //Check that the accounts and the bond account have the appropriate values -// validator, found := keeper.GetValidator(ctx, validatorAddr) +// validator, found := app.StakingKeeper.GetValidator(ctx, validatorAddr) // require.True(t, found) -// bond, found := keeper.GetDelegation(ctx, delegatorAddr, validatorAddr) +// bond, found := app.StakingKeeper.GetDelegation(ctx, delegatorAddr, validatorAddr) // require.True(t, found) // // expBond := bondAmount.MulRaw(i + 1) @@ -374,7 +373,7 @@ func TestInvalidPubKeyTypeMsgCreateValidator(t *testing.T) { // // gotBond := bond.Shares.RoundInt() // gotDelegatorShares := validator.DelegatorShares.RoundInt() -// gotDelegatorAcc := bk.GetBalance(ctx, delegatorAddr, params.BondDenom).Amount +// gotDelegatorAcc := app.BankKeeper.GetBalance(ctx, delegatorAddr, params.BondDenom).Amount // // require.Equal(t, expBond, gotBond, // "i: %v\nexpBond: %v\ngotBond: %v\nvalidator: %v\nbond: %v\n", From ee2180528222e85f95aa88bd228b41aeed703ef6 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Wed, 26 Feb 2020 14:52:34 +0100 Subject: [PATCH 63/90] refactor TestLegacyValidatorDelegations to use simapp --- x/staking/handler_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/staking/handler_test.go b/x/staking/handler_test.go index 2b1723f86a4a..e62b07663a99 100644 --- a/x/staking/handler_test.go +++ b/x/staking/handler_test.go @@ -215,13 +215,13 @@ func TestInvalidPubKeyTypeMsgCreateValidator(t *testing.T) { } func TestLegacyValidatorDelegations(t *testing.T) { - app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 1, 100000000) + app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 2, 100000000) handler := staking.NewHandler(app.StakingKeeper) bondAmount := sdk.TokensFromConsensusPower(10) valAddr := valAddrs[0] valConsPubKey, valConsAddr := PKs[0], sdk.ConsAddress(PKs[0].Address()) - delAddr := delAddrs[0] + delAddr := delAddrs[1] // create validator msgCreateVal := NewTestMsgCreateValidator(valAddr, valConsPubKey, bondAmount) From 3f319c257829e7be66ab3671fa75ba1530434450 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Wed, 26 Feb 2020 15:04:40 +0100 Subject: [PATCH 64/90] refactor TestIncrementsMsgDelegate --- x/staking/handler_test.go | 143 +++++++++++++++++++------------------- 1 file changed, 72 insertions(+), 71 deletions(-) diff --git a/x/staking/handler_test.go b/x/staking/handler_test.go index e62b07663a99..da1c1e6845a6 100644 --- a/x/staking/handler_test.go +++ b/x/staking/handler_test.go @@ -315,77 +315,78 @@ func TestLegacyValidatorDelegations(t *testing.T) { require.Equal(t, bondAmount.MulRaw(3), validator.DelegatorShares.RoundInt()) } -//func TestIncrementsMsgDelegate(t *testing.T) { -// initPower := int64(1000) -// initBond := sdk.TokensFromConsensusPower(initPower) -// app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 2, 10000000) -// handler := staking.NewHandler(app.StakingKeeper) -// -// params := app.StakingKeeper.GetParams(ctx) -// -// bondAmount := sdk.TokensFromConsensusPower(10) -// validatorAddr, delegatorAddr := valAddrs[0], delAddrs[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 -// app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) -// -// validator, found := app.StakingKeeper.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 = app.StakingKeeper.GetDelegation(ctx, delegatorAddr, validatorAddr) -// require.False(t, found) -// -// bond, found := app.StakingKeeper.GetDelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr) -// require.True(t, found) -// require.Equal(t, bondAmount, bond.Shares.RoundInt()) -// -// bondedTokens := app.StakingKeeper.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 := app.StakingKeeper.GetValidator(ctx, validatorAddr) -// require.True(t, found) -// bond, found := app.StakingKeeper.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 := app.BankKeeper.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 TestIncrementsMsgDelegate(t *testing.T) { + initPower := int64(1000) + initBond := sdk.TokensFromConsensusPower(initPower) + app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 2, 1000000000) + handler := staking.NewHandler(app.StakingKeeper) + + params := app.StakingKeeper.GetParams(ctx) + + bondAmount := sdk.TokensFromConsensusPower(10) + validatorAddr, delegatorAddr := valAddrs[0], delAddrs[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 + app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + + validator, found := app.StakingKeeper.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 = app.StakingKeeper.GetDelegation(ctx, delegatorAddr, validatorAddr) + require.False(t, found) + + bond, found := app.StakingKeeper.GetDelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr) + require.True(t, found) + require.Equal(t, bondAmount, bond.Shares.RoundInt()) + + bondedTokens := app.StakingKeeper.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 := app.StakingKeeper.GetValidator(ctx, validatorAddr) + require.True(t, found) + bond, found := app.StakingKeeper.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 := app.BankKeeper.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]) From 8ecd5b895426cd27f89ada22354c66d30f0c35df Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Wed, 26 Feb 2020 15:06:52 +0100 Subject: [PATCH 65/90] refactor next --- x/staking/handler_test.go | 69 +++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/x/staking/handler_test.go b/x/staking/handler_test.go index da1c1e6845a6..c98b54d11162 100644 --- a/x/staking/handler_test.go +++ b/x/staking/handler_test.go @@ -387,41 +387,40 @@ func TestIncrementsMsgDelegate(t *testing.T) { } } -// -//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 TestEditValidatorDecreaseMinSelfDelegation(t *testing.T) { + initPower := int64(100) + initBond := sdk.TokensFromConsensusPower(100) + app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 1, 1000000000) + + validatorAddr := valAddrs[0] + handler := staking.NewHandler(app.StakingKeeper) + + // 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 := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 1, len(updates)) + + // verify the self-delegation exists + bond, found := app.StakingKeeper.GetDelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr) + require.True(t, found) + gotBond := bond.Shares.RoundInt() + require.Equal(t, initBond, gotBond, + "initBond: %v\ngotBond: %v\nbond: %v\n", + initBond, gotBond, bond) + + newMinSelfDelegation := sdk.OneInt() + msgEditValidator := types.NewMsgEditValidator(validatorAddr, types.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]) // From a07ed83dd250aeb1fb319d356bc4767744088173 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Wed, 26 Feb 2020 15:08:43 +0100 Subject: [PATCH 66/90] refactor TestEditValidatorIncreaseMinSelfDelegationBeyondCurrentBond --- x/staking/handler_test.go | 69 ++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/x/staking/handler_test.go b/x/staking/handler_test.go index c98b54d11162..9a8d21dee009 100644 --- a/x/staking/handler_test.go +++ b/x/staking/handler_test.go @@ -421,40 +421,41 @@ func TestEditValidatorDecreaseMinSelfDelegation(t *testing.T) { 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 TestEditValidatorIncreaseMinSelfDelegationBeyondCurrentBond(t *testing.T) { + initPower := int64(100) + initBond := sdk.TokensFromConsensusPower(100) + + app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 2, 1000000000) + validatorAddr := valAddrs[0] + + handler := staking.NewHandler(app.StakingKeeper) + + // 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 := app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 1, len(updates)) + + // verify the self-delegation exists + bond, found := app.StakingKeeper.GetDelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr) + require.True(t, found) + gotBond := bond.Shares.RoundInt() + require.Equal(t, initBond, gotBond, + "initBond: %v\ngotBond: %v\nbond: %v\n", + initBond, gotBond, bond) + + newMinSelfDelegation := initBond.Add(sdk.OneInt()) + msgEditValidator := types.NewMsgEditValidator(validatorAddr, types.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) From 46d62ebfa96ed8a292a4a33634036390c60e345e Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Wed, 26 Feb 2020 15:13:08 +0100 Subject: [PATCH 67/90] refactor TestIncrementsMsgUnbond --- x/staking/handler_test.go | 219 +++++++++++++++++++------------------- 1 file changed, 110 insertions(+), 109 deletions(-) diff --git a/x/staking/handler_test.go b/x/staking/handler_test.go index 9a8d21dee009..e15768cee4d5 100644 --- a/x/staking/handler_test.go +++ b/x/staking/handler_test.go @@ -456,115 +456,116 @@ func TestEditValidatorIncreaseMinSelfDelegationBeyondCurrentBond(t *testing.T) { 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 TestIncrementsMsgUnbond(t *testing.T) { + initPower := int64(1000) + initBond := sdk.TokensFromConsensusPower(initPower) + + app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 2, 1000000000) + handler := staking.NewHandler(app.StakingKeeper) + + params := app.StakingKeeper.GetParams(ctx) + denom := params.BondDenom + + // create validator, delegate + validatorAddr, delegatorAddr := valAddrs[0], delAddrs[1] + + msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, PKs[0], initBond) + res, err := handler(ctx, msgCreateValidator) + require.NoError(t, err) + require.NotNil(t, res) + + // initial balance + amt1 := app.BankKeeper.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 := app.BankKeeper.GetBalance(ctx, delegatorAddr, denom).Amount + require.True(sdk.IntEq(t, amt1.Sub(initBond), amt2)) + + // apply TM updates + app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + + validator, found := app.StakingKeeper.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 := types.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) + staking.EndBlocker(ctx, app.StakingKeeper) + + // check that the accounts and the bond account have the appropriate values + validator, found = app.StakingKeeper.GetValidator(ctx, validatorAddr) + require.True(t, found) + bond, found := app.StakingKeeper.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 := app.BankKeeper.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 := types.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 = types.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) From d251f6436ef4751a3bf1315a6886d9c6366fd44a Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Wed, 26 Feb 2020 15:17:31 +0100 Subject: [PATCH 68/90] refator TestMultipleMsgCreateValidator --- x/staking/handler_test.go | 164 +++++++++++++++++++------------------- 1 file changed, 83 insertions(+), 81 deletions(-) diff --git a/x/staking/handler_test.go b/x/staking/handler_test.go index e15768cee4d5..2a9b4bc43a06 100644 --- a/x/staking/handler_test.go +++ b/x/staking/handler_test.go @@ -2,6 +2,7 @@ package staking_test import ( "testing" + "time" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto/secp256k1" @@ -566,87 +567,88 @@ func TestIncrementsMsgUnbond(t *testing.T) { 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 TestMultipleMsgCreateValidator(t *testing.T) { + initPower := int64(1000) + initTokens := sdk.TokensFromConsensusPower(initPower) + app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, initPower, 3, 1000000000) + + handler := staking.NewHandler(app.StakingKeeper) + + params := app.StakingKeeper.GetParams(ctx) + blockTime := time.Now().UTC() + ctx = ctx.WithBlockTime(blockTime) + + validatorAddrs := []sdk.ValAddress{ + valAddrs[0], + valAddrs[1], + valAddrs[2], + } + delegatorAddrs := []sdk.AccAddress{ + delAddrs[0], + delAddrs[1], + delAddrs[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 := app.StakingKeeper.GetValidators(ctx, 100) + require.Equal(t, (i + 1), len(validators)) + + val := validators[i] + balanceExpd := initTokens.Sub(valTokens) + balanceGot := app.BankKeeper.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) + } + + staking.EndBlocker(ctx, app.StakingKeeper) + + // unbond them all by removing delegation + for i, validatorAddr := range validatorAddrs { + _, found := app.StakingKeeper.GetValidator(ctx, validatorAddr) + require.True(t, found) + + unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(10)) + msgUndelegate := types.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 + staking.EndBlocker(ctx, app.StakingKeeper) + + // removes validator from queue and set + staking.EndBlocker(ctx.WithBlockTime(blockTime.Add(params.UnbondingTime)), app.StakingKeeper) + + // Check that the validator is deleted from state + validators := app.StakingKeeper.GetValidators(ctx, 100) + require.Equal(t, len(validatorAddrs)-(i+1), len(validators), + "expected %d validators got %d", len(validatorAddrs)-(i+1), len(validators)) + + _, found = app.StakingKeeper.GetValidator(ctx, validatorAddr) + require.False(t, found) + + gotBalance := app.BankKeeper.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) From 0e3b95857bdce4b2f8ef81817010a64f84730b46 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Wed, 26 Feb 2020 15:19:39 +0100 Subject: [PATCH 69/90] refactor TestMultipleMsgDelegate --- x/staking/handler_test.go | 96 +++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/x/staking/handler_test.go b/x/staking/handler_test.go index 2a9b4bc43a06..a27545dc8155 100644 --- a/x/staking/handler_test.go +++ b/x/staking/handler_test.go @@ -649,54 +649,54 @@ func TestMultipleMsgCreateValidator(t *testing.T) { } } -//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 TestMultipleMsgDelegate(t *testing.T) { + app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 50, 1000000000) + handler := staking.NewHandler(app.StakingKeeper) + validatorAddr, delegatorAddrs := valAddrs[0], delAddrs[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 := app.StakingKeeper.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 := types.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) + staking.EndBlocker(ctx, app.StakingKeeper) + + // check that the account is unbonded + _, found := app.StakingKeeper.GetDelegation(ctx, delegatorAddr, validatorAddr) + require.False(t, found) + } +} + //func TestJailValidator(t *testing.T) { // ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) // handler := NewHandler(keeper) From 0fcf1e20d64bb216454a909d4c6156eea33a1308 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Wed, 26 Feb 2020 15:21:42 +0100 Subject: [PATCH 70/90] refactor TestJailValidator --- x/staking/handler_test.go | 118 +++++++++++++++++++------------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/x/staking/handler_test.go b/x/staking/handler_test.go index a27545dc8155..991550bcc158 100644 --- a/x/staking/handler_test.go +++ b/x/staking/handler_test.go @@ -697,65 +697,65 @@ func TestMultipleMsgDelegate(t *testing.T) { } } -//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 TestJailValidator(t *testing.T) { + app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 2, 1000000000) + handler := staking.NewHandler(app.StakingKeeper) + validatorAddr, delegatorAddr := valAddrs[0], delAddrs[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 := types.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) + staking.EndBlocker(ctx, app.StakingKeeper) + + validator, found := app.StakingKeeper.GetValidator(ctx, validatorAddr) + require.True(t, found) + require.True(t, validator.Jailed, "%v", validator) + + // test that the delegator can still withdraw their bonds + msgUndelegateDelegator := types.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) + staking.EndBlocker(ctx, app.StakingKeeper) + + // 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) From eb26b478b4e51847c48c063f57e709a78a1b758f Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Wed, 26 Feb 2020 15:26:50 +0100 Subject: [PATCH 71/90] refactor TestUnbondingPeriod and TestValidatorQueue --- x/staking/handler_test.go | 228 +++++++++++++++++++------------------- 1 file changed, 114 insertions(+), 114 deletions(-) diff --git a/x/staking/handler_test.go b/x/staking/handler_test.go index 991550bcc158..9db8322c0337 100644 --- a/x/staking/handler_test.go +++ b/x/staking/handler_test.go @@ -756,120 +756,120 @@ func TestJailValidator(t *testing.T) { 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 TestValidatorQueue(t *testing.T) { + app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 2, 1000000000) + handler := staking.NewHandler(app.StakingKeeper) + validatorAddr, delegatorAddr := valAddrs[0], delAddrs[1] + + // set the unbonding time + params := app.StakingKeeper.GetParams(ctx) + params.UnbondingTime = 7 * time.Second + app.StakingKeeper.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) + + staking.EndBlocker(ctx, app.StakingKeeper) + + // unbond the all self-delegation to put validator in unbonding state + unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, delTokens) + msgUndelegateValidator := types.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) + staking.EndBlocker(ctx, app.StakingKeeper) + + origHeader := ctx.BlockHeader() + + validator, found := app.StakingKeeper.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)) + staking.EndBlocker(ctx, app.StakingKeeper) + + validator, found = app.StakingKeeper.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)) + staking.EndBlocker(ctx, app.StakingKeeper) + + validator, found = app.StakingKeeper.GetValidator(ctx, validatorAddr) + require.True(t, found) + require.True(t, validator.IsUnbonded(), "%v", validator) +} + +func TestUnbondingPeriod(t *testing.T) { + app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 1, 1000000000) + handler := staking.NewHandler(app.StakingKeeper) + validatorAddr := valAddrs[0] + + // set the unbonding time + params := app.StakingKeeper.GetParams(ctx) + params.UnbondingTime = 7 * time.Second + app.StakingKeeper.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) + + staking.EndBlocker(ctx, app.StakingKeeper) + + // begin unbonding + unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.TokensFromConsensusPower(10)) + msgUndelegate := types.NewMsgUndelegate(sdk.AccAddress(validatorAddr), validatorAddr, unbondAmt) + res, err = handler(ctx, msgUndelegate) + require.NoError(t, err) + require.NotNil(t, res) + + origHeader := ctx.BlockHeader() + + _, found := app.StakingKeeper.GetUnbondingDelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr) + require.True(t, found, "should not have unbonded") + + // cannot complete unbonding at same time + staking.EndBlocker(ctx, app.StakingKeeper) + _, found = app.StakingKeeper.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)) + staking.EndBlocker(ctx, app.StakingKeeper) + _, found = app.StakingKeeper.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)) + staking.EndBlocker(ctx, app.StakingKeeper) + _, found = app.StakingKeeper.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) From c58ec7f7b7df22dbf3b21a02ef21e2f08a932f41 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Wed, 26 Feb 2020 15:31:16 +0100 Subject: [PATCH 72/90] refactor TestUnbondingFromUnbondingValidator and TestRedelegationPeriod --- x/staking/handler_test.go | 226 +++++++++++++++++++------------------- 1 file changed, 113 insertions(+), 113 deletions(-) diff --git a/x/staking/handler_test.go b/x/staking/handler_test.go index 9db8322c0337..06d6e2157608 100644 --- a/x/staking/handler_test.go +++ b/x/staking/handler_test.go @@ -870,119 +870,119 @@ func TestUnbondingPeriod(t *testing.T) { 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 TestUnbondingFromUnbondingValidator(t *testing.T) { + app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 2, 1000000000) + handler := staking.NewHandler(app.StakingKeeper) + validatorAddr, delegatorAddr := valAddrs[0], delAddrs[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 := types.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 := types.NewMsgUndelegate(delegatorAddr, validatorAddr, unbondAmt) + res, err = handler(ctx, msgUndelegateDelegator) + require.NoError(t, err) + require.NotNil(t, res) + + ctx = ctx.WithBlockTime(ctx.BlockHeader().Time.Add(app.StakingKeeper.UnbondingTime(ctx))) + + // Run the EndBlocker + staking.EndBlocker(ctx, app.StakingKeeper) + + // Check to make sure that the unbonding delegation is no longer in state + // (meaning it was deleted in the above EndBlocker) + _, found := app.StakingKeeper.GetUnbondingDelegation(ctx, delegatorAddr, validatorAddr) + require.False(t, found, "should be removed from state") +} + +func TestRedelegationPeriod(t *testing.T) { + app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 2, 1000000000) + handler := staking.NewHandler(app.StakingKeeper) + validatorAddr, validatorAddr2 := valAddrs[0], valAddrs[1] + denom := app.StakingKeeper.GetParams(ctx).BondDenom + + // set the unbonding time + params := app.StakingKeeper.GetParams(ctx) + params.UnbondingTime = 7 * time.Second + app.StakingKeeper.SetParams(ctx, params) + + // create the validators + msgCreateValidator := NewTestMsgCreateValidator(validatorAddr, PKs[0], sdk.NewInt(10)) + + // initial balance + amt1 := app.BankKeeper.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 := app.BankKeeper.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 := app.BankKeeper.GetAllBalances(ctx, sdk.AccAddress(validatorAddr)) + + // begin redelegate + redAmt := sdk.NewCoin(sdk.DefaultBondDenom, sdk.NewInt(10)) + msgBeginRedelegate := types.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 := app.BankKeeper.GetAllBalances(ctx, sdk.AccAddress(validatorAddr)) + require.Equal(t, bal1, bal2) + + origHeader := ctx.BlockHeader() + + // cannot complete redelegation at same time + staking.EndBlocker(ctx, app.StakingKeeper) + _, found := app.StakingKeeper.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)) + staking.EndBlocker(ctx, app.StakingKeeper) + _, found = app.StakingKeeper.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)) + staking.EndBlocker(ctx, app.StakingKeeper) + _, found = app.StakingKeeper.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) From 4e16a0861c3acd1655d5922514a5ca164db5847e Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Wed, 26 Feb 2020 15:35:29 +0100 Subject: [PATCH 73/90] refactor TestTransitiveRedelegation and TestMultipleRedelegationAtSameTime --- x/staking/handler_test.go | 220 +++++++++++++++++++------------------- 1 file changed, 110 insertions(+), 110 deletions(-) diff --git a/x/staking/handler_test.go b/x/staking/handler_test.go index 06d6e2157608..59a1a83a903b 100644 --- a/x/staking/handler_test.go +++ b/x/staking/handler_test.go @@ -983,116 +983,116 @@ func TestRedelegationPeriod(t *testing.T) { 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 TestTransitiveRedelegation(t *testing.T) { + app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 3, 1000000000) + handler := staking.NewHandler(app.StakingKeeper) + + validatorAddr := valAddrs[0] + validatorAddr2 := valAddrs[1] + validatorAddr3 := valAddrs[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 := types.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 = types.NewMsgBeginRedelegate(sdk.AccAddress(validatorAddr), validatorAddr2, validatorAddr3, redAmt) + res, err = handler(ctx, msgBeginRedelegate) + require.Error(t, err) + require.Nil(t, res) + + params := app.StakingKeeper.GetParams(ctx) + ctx = ctx.WithBlockTime(blockTime.Add(params.UnbondingTime)) + + // complete first redelegation + staking.EndBlocker(ctx, app.StakingKeeper) + + // 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) { + app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 2, 1000000000) + handler := staking.NewHandler(app.StakingKeeper) + + valAddr := valAddrs[0] + valAddr2 := valAddrs[1] + + // set the unbonding time + params := app.StakingKeeper.GetParams(ctx) + params.UnbondingTime = 1 * time.Second + app.StakingKeeper.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 + staking.EndBlocker(ctx, app.StakingKeeper) + + // begin a redelegate + selfDelAddr := sdk.AccAddress(valAddr) // (the validator is it's own delegator) + redAmt := sdk.NewCoin(sdk.DefaultBondDenom, valTokens.QuoRaw(2)) + msgBeginRedelegate := types.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 := app.StakingKeeper.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 = app.StakingKeeper.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)) + staking.EndBlocker(ctx, app.StakingKeeper) + + rd, found = app.StakingKeeper.GetRedelegation(ctx, selfDelAddr, valAddr, valAddr2) + require.False(t, found) +} + //func TestMultipleRedelegationAtUniqueTimes(t *testing.T) { // ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) // handler := NewHandler(keeper) From 9381500fbc177dd40a6595a9dfb8ca4f97391a76 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Wed, 26 Feb 2020 15:39:56 +0100 Subject: [PATCH 74/90] refactor TestMultipleRedelegationAtUniqueTimes and TestMultipleUnbondingDelegationAtSameTime --- x/staking/handler_test.go | 224 +++++++++++++++++++------------------- 1 file changed, 112 insertions(+), 112 deletions(-) diff --git a/x/staking/handler_test.go b/x/staking/handler_test.go index 59a1a83a903b..c5b9c0cb1865 100644 --- a/x/staking/handler_test.go +++ b/x/staking/handler_test.go @@ -1093,118 +1093,118 @@ func TestMultipleRedelegationAtSameTime(t *testing.T) { 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 TestMultipleRedelegationAtUniqueTimes(t *testing.T) { + app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 2, 1000000000) + handler := staking.NewHandler(app.StakingKeeper) + + valAddr := valAddrs[0] + valAddr2 := valAddrs[1] + + // set the unbonding time + params := app.StakingKeeper.GetParams(ctx) + params.UnbondingTime = 10 * time.Second + app.StakingKeeper.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 + staking.EndBlocker(ctx, app.StakingKeeper) + + // begin a redelegate + selfDelAddr := sdk.AccAddress(valAddr) // (the validator is it's own delegator) + redAmt := sdk.NewCoin(sdk.DefaultBondDenom, valTokens.QuoRaw(2)) + msgBeginRedelegate := types.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 := app.StakingKeeper.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)) + staking.EndBlocker(ctx, app.StakingKeeper) + rd, found = app.StakingKeeper.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)) + staking.EndBlocker(ctx, app.StakingKeeper) + rd, found = app.StakingKeeper.GetRedelegation(ctx, selfDelAddr, valAddr, valAddr2) + require.False(t, found) +} + +func TestMultipleUnbondingDelegationAtSameTime(t *testing.T) { + app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 1, 1000000000) + handler := staking.NewHandler(app.StakingKeeper) + + valAddr := valAddrs[0] + + // set the unbonding time + params := app.StakingKeeper.GetParams(ctx) + params.UnbondingTime = 1 * time.Second + app.StakingKeeper.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 + staking.EndBlocker(ctx, app.StakingKeeper) + + // begin an unbonding delegation + selfDelAddr := sdk.AccAddress(valAddr) // (the validator is it's own delegator) + unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, valTokens.QuoRaw(2)) + msgUndelegate := types.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 := app.StakingKeeper.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 = app.StakingKeeper.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)) + staking.EndBlocker(ctx, app.StakingKeeper) + + ubd, found = app.StakingKeeper.GetUnbondingDelegation(ctx, selfDelAddr, valAddr) + require.False(t, found) +} + //func TestMultipleUnbondingDelegationAtUniqueTimes(t *testing.T) { // ctx, _, _, keeper, _ := CreateTestInput(t, false, 1000) // handler := NewHandler(keeper) From 015fd43f51ce5fbcd617b2c792af371ed5b7fb06 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Wed, 26 Feb 2020 15:44:15 +0100 Subject: [PATCH 75/90] refactor TestMultipleUnbondingDelegationAtUniqueTimes and TestUnbondingWhenExcessValidators --- x/staking/handler_test.go | 244 +++++++++++++++++++------------------- 1 file changed, 122 insertions(+), 122 deletions(-) diff --git a/x/staking/handler_test.go b/x/staking/handler_test.go index c5b9c0cb1865..46d804e56812 100644 --- a/x/staking/handler_test.go +++ b/x/staking/handler_test.go @@ -1205,128 +1205,128 @@ func TestMultipleUnbondingDelegationAtSameTime(t *testing.T) { 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 TestMultipleUnbondingDelegationAtUniqueTimes(t *testing.T) { + app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 1, 1000000000) + handler := staking.NewHandler(app.StakingKeeper) + valAddr := valAddrs[0] + + // set the unbonding time + params := app.StakingKeeper.GetParams(ctx) + params.UnbondingTime = 10 * time.Second + app.StakingKeeper.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 + staking.EndBlocker(ctx, app.StakingKeeper) + + // begin an unbonding delegation + selfDelAddr := sdk.AccAddress(valAddr) // (the validator is it's own delegator) + unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, valTokens.QuoRaw(2)) + msgUndelegate := staking.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 := app.StakingKeeper.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 = app.StakingKeeper.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)) + staking.EndBlocker(ctx, app.StakingKeeper) + ubd, found = app.StakingKeeper.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)) + staking.EndBlocker(ctx, app.StakingKeeper) + ubd, found = app.StakingKeeper.GetUnbondingDelegation(ctx, selfDelAddr, valAddr) + require.False(t, found) +} + +func TestUnbondingWhenExcessValidators(t *testing.T) { + app, ctx, _, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 3, 1000000000) + handler := staking.NewHandler(app.StakingKeeper) + + validatorAddr1 := valAddrs[0] + validatorAddr2 := valAddrs[1] + validatorAddr3 := valAddrs[2] + + // set the unbonding time + params := app.StakingKeeper.GetParams(ctx) + params.MaxValidators = 2 + app.StakingKeeper.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 + app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 1, len(app.StakingKeeper.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 + app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 2, len(app.StakingKeeper.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 + app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 2, len(app.StakingKeeper.GetLastValidators(ctx))) + + // unbond the validator-2 + unbondAmt := sdk.NewCoin(sdk.DefaultBondDenom, valTokens2) + msgUndelegate := types.NewMsgUndelegate(sdk.AccAddress(validatorAddr2), validatorAddr2, unbondAmt) + res, err = handler(ctx, msgUndelegate) + require.NoError(t, err) + require.NotNil(t, res) + + // apply TM updates + app.StakingKeeper.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 := app.StakingKeeper.GetLastValidators(ctx) + require.Equal(t, 2, len(vals), "vals %v", vals) + val1, found := app.StakingKeeper.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) From bbbbc612763ffaca101839901df2b3c41b02c665 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Wed, 26 Feb 2020 15:48:51 +0100 Subject: [PATCH 76/90] end refactor handler_test --- x/staking/handler_test.go | 352 +++++++++++++++++++------------------- 1 file changed, 177 insertions(+), 175 deletions(-) diff --git a/x/staking/handler_test.go b/x/staking/handler_test.go index 46d804e56812..3cb050a4dd9f 100644 --- a/x/staking/handler_test.go +++ b/x/staking/handler_test.go @@ -1,6 +1,7 @@ package staking_test import ( + "strings" "testing" "time" @@ -1327,178 +1328,179 @@ func TestUnbondingWhenExcessValidators(t *testing.T) { 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 TestBondUnbondRedelegateSlashTwice(t *testing.T) { + app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 3, 1000000000) + + handler := staking.NewHandler(app.StakingKeeper) + + valA, valB, del := valAddrs[0], valAddrs[1], delAddrs[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 := app.StakingKeeper.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 := types.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 := types.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 := app.StakingKeeper.GetDelegation(ctx, del, valB) + require.True(t, found) + require.Equal(t, sdk.NewDecFromInt(redAmt.Amount), delegation.Shares) + + // must apply validator updates + updates = app.StakingKeeper.ApplyAndReturnValidatorSetUpdates(ctx) + require.Equal(t, 2, len(updates)) + + // slash the validator by half + app.StakingKeeper.Slash(ctx, consAddr0, 0, 20, sdk.NewDecWithPrec(5, 1)) + + // unbonding delegation should have been slashed by half + ubd, found := app.StakingKeeper.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 := app.StakingKeeper.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 = app.StakingKeeper.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 := app.StakingKeeper.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) + app.StakingKeeper.Slash(ctx, consAddr0, 2, 10, sdk.NewDecWithPrec(5, 1)) + + // unbonding delegation should be unchanged + ubd, found = app.StakingKeeper.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 = app.StakingKeeper.GetRedelegation(ctx, del, valA, valB) + require.True(t, found) + require.Len(t, redelegation.Entries, 1) + + // destination delegation should be unchanged + delegation, found = app.StakingKeeper.GetDelegation(ctx, del, valB) + require.True(t, found) + require.Equal(t, sdk.NewDecFromInt(redAmt.Amount.QuoRaw(2)), delegation.Shares) + + // end blocker + staking.EndBlocker(ctx, app.StakingKeeper) + + // validator power should have been reduced to zero + // validator should be in unbonding state + validator, _ = app.StakingKeeper.GetValidator(ctx, valA) + require.Equal(t, validator.GetStatus(), sdk.Unbonding) +} + +func TestInvalidMsg(t *testing.T) { + k := staking.Keeper{} + h := staking.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) { + app, ctx, delAddrs, valAddrs := bootstrapHandlerGenesisTest(t, 1000, 3, 1000000000) + handler := staking.NewHandler(app.StakingKeeper) + + valA, valB, delAddr := valAddrs[0], valAddrs[1], delAddrs[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, types.Description{}, commission, sdk.OneInt()) + res, err := handler(ctx, msgCreate) + require.Error(t, err) + require.Nil(t, res) + + msgCreate = types.NewMsgCreateValidator(valA, PKs[0], validCoin, types.Description{}, commission, sdk.OneInt()) + res, err = handler(ctx, msgCreate) + require.NoError(t, err) + require.NotNil(t, res) + + msgCreate = types.NewMsgCreateValidator(valB, PKs[1], validCoin, types.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) +} From 64c2971c6f1572e3d835bd54bd454208cb44b87b Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Wed, 26 Feb 2020 15:51:45 +0100 Subject: [PATCH 77/90] remove test_common --- x/staking/test_common.go | 220 --------------------------------------- 1 file changed, 220 deletions(-) delete mode 100644 x/staking/test_common.go diff --git a/x/staking/test_common.go b/x/staking/test_common.go deleted file mode 100644 index 1b9708e78ef8..000000000000 --- a/x/staking/test_common.go +++ /dev/null @@ -1,220 +0,0 @@ -package staking - -import ( - "bytes" - "encoding/hex" - "strconv" - "testing" - - simappcodec "github.com/cosmos/cosmos-sdk/simapp/codec" - - "github.com/stretchr/testify/require" - - abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/tendermint/tendermint/libs/log" - tmtypes "github.com/tendermint/tendermint/types" - dbm "github.com/tendermint/tm-db" - - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/store" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth" - authexported "github.com/cosmos/cosmos-sdk/x/auth/exported" - "github.com/cosmos/cosmos-sdk/x/bank" - "github.com/cosmos/cosmos-sdk/x/params" - "github.com/cosmos/cosmos-sdk/x/staking/types" - "github.com/cosmos/cosmos-sdk/x/supply" -) - -// dummy addresses used for testing -// nolint:unused, deadcode -var ( - Addrs = createTestAddrs(500) - PKs = createTestPubKeys(500) -) - -// nolint: unparam -func createTestAddrs(numAddrs int) []sdk.AccAddress { - var addresses []sdk.AccAddress - var buffer bytes.Buffer - - // start at 100 so we can make up to 999 test addresses with valid test addresses - for i := 100; i < (numAddrs + 100); i++ { - numString := strconv.Itoa(i) - buffer.WriteString("A58856F0FD53BF058B4909A21AEC019107BA6") //base address string - - buffer.WriteString(numString) //adding on final two digits to make addresses unique - res, _ := sdk.AccAddressFromHex(buffer.String()) - bech := res.String() - addresses = append(addresses, TestAddr(buffer.String(), bech)) - buffer.Reset() - } - return addresses -} - -// 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 -} - -//_____________________________________________________________________________________ - -// Hogpodge of all sorts of input required for testing. -// `initPower` is converted to an amount of tokens. -// If `initPower` is 0, no addrs get created. -func CreateTestInput(t *testing.T, isCheckTx bool, initPower int64) (sdk.Context, auth.AccountKeeper, types.BankKeeper, Keeper, types.SupplyKeeper) { - keyStaking := sdk.NewKVStoreKey(types.StoreKey) - keyAcc := sdk.NewKVStoreKey(auth.StoreKey) - bankKey := sdk.NewKVStoreKey(bank.StoreKey) - keyParams := sdk.NewKVStoreKey(params.StoreKey) - keySupply := sdk.NewKVStoreKey(supply.StoreKey) - - tkeyParams := sdk.NewTransientStoreKey(params.TStoreKey) - - db := dbm.NewMemDB() - ms := store.NewCommitMultiStore(db) - ms.MountStoreWithDB(keyStaking, sdk.StoreTypeIAVL, db) - ms.MountStoreWithDB(keyAcc, sdk.StoreTypeIAVL, db) - ms.MountStoreWithDB(bankKey, sdk.StoreTypeIAVL, db) - ms.MountStoreWithDB(keyParams, sdk.StoreTypeIAVL, db) - ms.MountStoreWithDB(tkeyParams, sdk.StoreTypeTransient, db) - ms.MountStoreWithDB(keySupply, sdk.StoreTypeIAVL, db) - err := ms.LoadLatestVersion() - require.Nil(t, err) - - ctx := sdk.NewContext(ms, abci.Header{ChainID: "foochainid"}, isCheckTx, log.NewNopLogger()) - ctx = ctx.WithConsensusParams( - &abci.ConsensusParams{ - Validator: &abci.ValidatorParams{ - PubKeyTypes: []string{tmtypes.ABCIPubKeyTypeEd25519}, - }, - }, - ) - cdc := MakeTestCodec() - appCodec := simappcodec.NewAppCodec(cdc) - - feeCollectorAcc := supply.NewEmptyModuleAccount(auth.FeeCollectorName) - notBondedPool := supply.NewEmptyModuleAccount(types.NotBondedPoolName, supply.Burner, supply.Staking) - bondPool := supply.NewEmptyModuleAccount(types.BondedPoolName, supply.Burner, supply.Staking) - - blacklistedAddrs := make(map[string]bool) - blacklistedAddrs[feeCollectorAcc.GetAddress().String()] = true - blacklistedAddrs[notBondedPool.GetAddress().String()] = true - blacklistedAddrs[bondPool.GetAddress().String()] = true - - pk := params.NewKeeper(appCodec, keyParams, tkeyParams) - - accountKeeper := auth.NewAccountKeeper( - appCodec, - keyAcc, // target store - pk.Subspace(auth.DefaultParamspace), - auth.ProtoBaseAccount, // prototype - ) - - bk := bank.NewBaseKeeper( - appCodec, - bankKey, - accountKeeper, - pk.Subspace(bank.DefaultParamspace), - blacklistedAddrs, - ) - - maccPerms := map[string][]string{ - auth.FeeCollectorName: nil, - types.NotBondedPoolName: {supply.Burner, supply.Staking}, - types.BondedPoolName: {supply.Burner, supply.Staking}, - } - supplyKeeper := supply.NewKeeper(appCodec, keySupply, accountKeeper, bk, maccPerms) - - initTokens := sdk.TokensFromConsensusPower(initPower) - initCoins := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens)) - totalSupply := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, initTokens.MulRaw(int64(len(Addrs))))) - - supplyKeeper.SetSupply(ctx, supply.NewSupply(totalSupply)) - - keeper := NewKeeper(types.ModuleCdc, keyStaking, bk, supplyKeeper, pk.Subspace(DefaultParamspace)) - keeper.SetParams(ctx, types.DefaultParams()) - - // set module accounts - require.NoError(t, bk.SetBalances(ctx, notBondedPool.GetAddress(), totalSupply)) - - supplyKeeper.SetModuleAccount(ctx, feeCollectorAcc) - supplyKeeper.SetModuleAccount(ctx, bondPool) - supplyKeeper.SetModuleAccount(ctx, notBondedPool) - - // fill all the addresses with some coins, set the loose pool tokens simultaneously - for i, addr := range Addrs { - accountKeeper.SetAccount(ctx, auth.NewBaseAccount(addr, PKs[i], uint64(i), 0)) - require.NoError(t, bk.SetBalances(ctx, addr, initCoins)) - } - - return ctx, accountKeeper, bk, keeper, supplyKeeper -} - -// create a codec used only for testing -func MakeTestCodec() *codec.Codec { - var cdc = codec.New() - - // Register Msgs - cdc.RegisterInterface((*sdk.Msg)(nil), nil) - cdc.RegisterConcrete(bank.MsgSend{}, "test/staking/Send", nil) - cdc.RegisterConcrete(types.MsgCreateValidator{}, "test/staking/CreateValidator", nil) - cdc.RegisterConcrete(types.MsgEditValidator{}, "test/staking/EditValidator", nil) - cdc.RegisterConcrete(types.MsgUndelegate{}, "test/staking/Undelegate", nil) - cdc.RegisterConcrete(types.MsgBeginRedelegate{}, "test/staking/BeginRedelegate", nil) - - // Register AppAccount - cdc.RegisterInterface((*authexported.Account)(nil), nil) - cdc.RegisterConcrete(&auth.BaseAccount{}, "test/staking/BaseAccount", nil) - supply.RegisterCodec(cdc) - codec.RegisterCrypto(cdc) - - return cdc -} - -// for incode address generation -func TestAddr(addr string, bech string) sdk.AccAddress { - - res, err := sdk.AccAddressFromHex(addr) - if err != nil { - panic(err) - } - bechexpected := res.String() - if bech != bechexpected { - panic("Bech encoding doesn't match reference") - } - - bechres, err := sdk.AccAddressFromBech32(bech) - if err != nil { - panic(err) - } - if !bytes.Equal(bechres, res) { - panic("Bech decode and hex decode don't match") - } - - return res -} - -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 -} From 1d18f8839c2ec59e1bdf512b1f594219bae369b1 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Wed, 26 Feb 2020 15:57:41 +0100 Subject: [PATCH 78/90] remove create test public keys --- x/staking/keeper/common_test.go | 40 ++---------------------- x/staking/keeper/delegation_test.go | 30 +++++++++--------- x/staking/keeper/historical_info_test.go | 4 +-- x/staking/keeper/querier_test.go | 14 ++++----- x/staking/keeper/slash_test.go | 2 +- x/staking/keeper/validator_test.go | 2 +- 6 files changed, 29 insertions(+), 63 deletions(-) diff --git a/x/staking/keeper/common_test.go b/x/staking/keeper/common_test.go index 69a168e5a404..30306adc6f6e 100644 --- a/x/staking/keeper/common_test.go +++ b/x/staking/keeper/common_test.go @@ -1,14 +1,8 @@ package keeper_test import ( - "bytes" - "encoding/hex" - "strconv" "testing" - "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/crypto/ed25519" - "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/simapp" cdc "github.com/cosmos/cosmos-sdk/simapp/codec" @@ -20,40 +14,12 @@ import ( ) var ( - PKs = createTestPubKeys(500) + PKs = simapp.CreateTestPubKeys(500) ) -// 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 +// createTestInput Returns a simapp with custom StakingKeeper // to avoid messing with the hooks. -func getBaseSimappWithCustomKeeper() (*codec.Codec, *simapp.SimApp, sdk.Context) { +func createTestInput() (*codec.Codec, *simapp.SimApp, sdk.Context) { app := simapp.Setup(false) ctx := app.BaseApp.NewContext(false, abci.Header{}) diff --git a/x/staking/keeper/delegation_test.go b/x/staking/keeper/delegation_test.go index a1b0c6841c54..e1f7b7de2464 100644 --- a/x/staking/keeper/delegation_test.go +++ b/x/staking/keeper/delegation_test.go @@ -15,7 +15,7 @@ import ( // tests GetDelegation, GetDelegatorDelegations, SetDelegation, RemoveDelegation, GetDelegatorDelegations func TestDelegation(t *testing.T) { - _, app, ctx := getBaseSimappWithCustomKeeper() + _, app, ctx := createTestInput() addrDels := simapp.AddTestAddrsIncremental(app, ctx, 3, sdk.NewInt(10000)) valAddrs := simapp.ConvertAddrsToValAddrs(addrDels) @@ -131,7 +131,7 @@ func TestDelegation(t *testing.T) { // tests Get/Set/Remove UnbondingDelegation func TestUnbondingDelegation(t *testing.T) { - _, app, ctx := getBaseSimappWithCustomKeeper() + _, app, ctx := createTestInput() delAddrs := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(10000)) valAddrs := simapp.ConvertAddrsToValAddrs(delAddrs) @@ -177,7 +177,7 @@ func TestUnbondingDelegation(t *testing.T) { } func TestUnbondDelegation(t *testing.T) { - _, app, ctx := getBaseSimappWithCustomKeeper() + _, app, ctx := createTestInput() delAddrs := simapp.AddTestAddrsIncremental(app, ctx, 1, sdk.NewInt(10000)) valAddrs := simapp.ConvertAddrsToValAddrs(delAddrs) @@ -222,7 +222,7 @@ func TestUnbondDelegation(t *testing.T) { } func TestUnbondingDelegationsMaxEntries(t *testing.T) { - _, app, ctx := getBaseSimappWithCustomKeeper() + _, app, ctx := createTestInput() addrDels := simapp.AddTestAddrsIncremental(app, ctx, 1, sdk.NewInt(10000)) addrVals := simapp.ConvertAddrsToValAddrs(addrDels) @@ -305,7 +305,7 @@ func TestUnbondingDelegationsMaxEntries(t *testing.T) { //// test undelegating self delegation from a validator pushing it below MinSelfDelegation //// shift it from the bonded to unbonding state and jailed func TestUndelegateSelfDelegationBelowMinSelfDelegation(t *testing.T) { - _, app, ctx := getBaseSimappWithCustomKeeper() + _, app, ctx := createTestInput() addrDels := simapp.AddTestAddrsIncremental(app, ctx, 1, sdk.NewInt(10000)) addrVals := simapp.ConvertAddrsToValAddrs(addrDels) @@ -371,7 +371,7 @@ func TestUndelegateSelfDelegationBelowMinSelfDelegation(t *testing.T) { } func TestUndelegateFromUnbondingValidator(t *testing.T) { - _, app, ctx := getBaseSimappWithCustomKeeper() + _, app, ctx := createTestInput() delTokens := sdk.TokensFromConsensusPower(10) delCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), delTokens)) @@ -464,7 +464,7 @@ func TestUndelegateFromUnbondingValidator(t *testing.T) { } func TestUndelegateFromUnbondedValidator(t *testing.T) { - _, app, ctx := getBaseSimappWithCustomKeeper() + _, app, ctx := createTestInput() delTokens := sdk.TokensFromConsensusPower(10) delCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), delTokens)) @@ -548,7 +548,7 @@ func TestUndelegateFromUnbondedValidator(t *testing.T) { } func TestUnbondingAllDelegationFromValidator(t *testing.T) { - _, app, ctx := getBaseSimappWithCustomKeeper() + _, app, ctx := createTestInput() delTokens := sdk.TokensFromConsensusPower(10) delCoins := sdk.NewCoins(sdk.NewCoin(app.StakingKeeper.BondDenom(ctx), delTokens)) @@ -624,7 +624,7 @@ func TestUnbondingAllDelegationFromValidator(t *testing.T) { // Make sure that that the retrieving the delegations doesn't affect the state func TestGetRedelegationsFromSrcValidator(t *testing.T) { - _, app, ctx := getBaseSimappWithCustomKeeper() + _, app, ctx := createTestInput() addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(0)) addrVals := simapp.ConvertAddrsToValAddrs(addrDels) @@ -651,7 +651,7 @@ func TestGetRedelegationsFromSrcValidator(t *testing.T) { // tests Get/Set/Remove/Has UnbondingDelegation func TestRedelegation(t *testing.T) { - _, app, ctx := getBaseSimappWithCustomKeeper() + _, app, ctx := createTestInput() addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(0)) addrVals := simapp.ConvertAddrsToValAddrs(addrDels) @@ -714,7 +714,7 @@ func TestRedelegation(t *testing.T) { } func TestRedelegateToSameValidator(t *testing.T) { - _, app, ctx := getBaseSimappWithCustomKeeper() + _, app, ctx := createTestInput() addrDels := simapp.AddTestAddrsIncremental(app, ctx, 1, sdk.NewInt(0)) addrVals := simapp.ConvertAddrsToValAddrs(addrDels) @@ -745,7 +745,7 @@ func TestRedelegateToSameValidator(t *testing.T) { } func TestRedelegationMaxEntries(t *testing.T) { - _, app, ctx := getBaseSimappWithCustomKeeper() + _, app, ctx := createTestInput() addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(0)) addrVals := simapp.ConvertAddrsToValAddrs(addrDels) @@ -803,7 +803,7 @@ func TestRedelegationMaxEntries(t *testing.T) { } func TestRedelegateSelfDelegation(t *testing.T) { - _, app, ctx := getBaseSimappWithCustomKeeper() + _, app, ctx := createTestInput() addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(0)) addrVals := simapp.ConvertAddrsToValAddrs(addrDels) @@ -860,7 +860,7 @@ func TestRedelegateSelfDelegation(t *testing.T) { } func TestRedelegateFromUnbondingValidator(t *testing.T) { - _, app, ctx := getBaseSimappWithCustomKeeper() + _, app, ctx := createTestInput() addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(0)) addrVals := simapp.ConvertAddrsToValAddrs(addrDels) @@ -944,7 +944,7 @@ func TestRedelegateFromUnbondingValidator(t *testing.T) { } func TestRedelegateFromUnbondedValidator(t *testing.T) { - _, app, ctx := getBaseSimappWithCustomKeeper() + _, app, ctx := createTestInput() addrDels := simapp.AddTestAddrsIncremental(app, ctx, 2, sdk.NewInt(0)) addrVals := simapp.ConvertAddrsToValAddrs(addrDels) diff --git a/x/staking/keeper/historical_info_test.go b/x/staking/keeper/historical_info_test.go index d4ed693106e6..3a3f1100592b 100644 --- a/x/staking/keeper/historical_info_test.go +++ b/x/staking/keeper/historical_info_test.go @@ -15,7 +15,7 @@ import ( ) func TestHistoricalInfo(t *testing.T) { - _, app, ctx := getBaseSimappWithCustomKeeper() + _, app, ctx := createTestInput() addrDels := simapp.AddTestAddrsIncremental(app, ctx, 50, sdk.NewInt(0)) addrVals := simapp.ConvertAddrsToValAddrs(addrDels) @@ -43,7 +43,7 @@ func TestHistoricalInfo(t *testing.T) { } func TestTrackHistoricalInfo(t *testing.T) { - _, app, ctx := getBaseSimappWithCustomKeeper() + _, app, ctx := createTestInput() addrDels := simapp.AddTestAddrsIncremental(app, ctx, 50, sdk.NewInt(0)) addrVals := simapp.ConvertAddrsToValAddrs(addrDels) diff --git a/x/staking/keeper/querier_test.go b/x/staking/keeper/querier_test.go index 09a19b894f4f..3ca2ba33537f 100644 --- a/x/staking/keeper/querier_test.go +++ b/x/staking/keeper/querier_test.go @@ -15,7 +15,7 @@ import ( ) func TestNewQuerier(t *testing.T) { - cdc, app, ctx := getBaseSimappWithCustomKeeper() + cdc, app, ctx := createTestInput() addrs := simapp.AddTestAddrs(app, ctx, 500, sdk.NewInt(10000)) _, addrAcc2 := addrs[0], addrs[1] @@ -106,7 +106,7 @@ func TestNewQuerier(t *testing.T) { } func TestQueryParametersPool(t *testing.T) { - cdc, app, ctx := getBaseSimappWithCustomKeeper() + cdc, app, ctx := createTestInput() querier := staking.NewQuerier(app.StakingKeeper) bondDenom := sdk.DefaultBondDenom @@ -131,7 +131,7 @@ func TestQueryParametersPool(t *testing.T) { } func TestQueryValidators(t *testing.T) { - cdc, app, ctx := getBaseSimappWithCustomKeeper() + cdc, app, ctx := createTestInput() params := app.StakingKeeper.GetParams(ctx) querier := staking.NewQuerier(app.StakingKeeper) @@ -198,7 +198,7 @@ func TestQueryValidators(t *testing.T) { } func TestQueryDelegation(t *testing.T) { - cdc, app, ctx := getBaseSimappWithCustomKeeper() + cdc, app, ctx := createTestInput() params := app.StakingKeeper.GetParams(ctx) querier := staking.NewQuerier(app.StakingKeeper) @@ -425,7 +425,7 @@ func TestQueryDelegation(t *testing.T) { } func TestQueryRedelegations(t *testing.T) { - cdc, app, ctx := getBaseSimappWithCustomKeeper() + cdc, app, ctx := createTestInput() querier := staking.NewQuerier(app.StakingKeeper) addrs := simapp.AddTestAddrs(app, ctx, 2, sdk.TokensFromConsensusPower(10000)) @@ -494,7 +494,7 @@ func TestQueryRedelegations(t *testing.T) { } func TestQueryUnbondingDelegation(t *testing.T) { - cdc, app, ctx := getBaseSimappWithCustomKeeper() + cdc, app, ctx := createTestInput() querier := staking.NewQuerier(app.StakingKeeper) addrs := simapp.AddTestAddrs(app, ctx, 2, sdk.TokensFromConsensusPower(10000)) @@ -589,7 +589,7 @@ func TestQueryUnbondingDelegation(t *testing.T) { } func TestQueryHistoricalInfo(t *testing.T) { - cdc, app, ctx := getBaseSimappWithCustomKeeper() + cdc, app, ctx := createTestInput() querier := staking.NewQuerier(app.StakingKeeper) addrs := simapp.AddTestAddrs(app, ctx, 2, sdk.TokensFromConsensusPower(10000)) diff --git a/x/staking/keeper/slash_test.go b/x/staking/keeper/slash_test.go index fae13244c992..e333967a8cf7 100644 --- a/x/staking/keeper/slash_test.go +++ b/x/staking/keeper/slash_test.go @@ -19,7 +19,7 @@ import ( // bootstrapSlashTest creates 3 validators and bootstrap the app. func bootstrapSlashTest(t *testing.T, power int64) (*simapp.SimApp, sdk.Context, []sdk.AccAddress, []sdk.ValAddress) { - _, app, ctx := getBaseSimappWithCustomKeeper() + _, app, ctx := createTestInput() addrDels, addrVals := generateAddresses(app, ctx, 100) diff --git a/x/staking/keeper/validator_test.go b/x/staking/keeper/validator_test.go index 6f2be5472501..f7295a5421de 100644 --- a/x/staking/keeper/validator_test.go +++ b/x/staking/keeper/validator_test.go @@ -18,7 +18,7 @@ import ( ) func bootstrapValidatorTest(t *testing.T, power int64, numAddrs int) (*simapp.SimApp, sdk.Context, []sdk.AccAddress, []sdk.ValAddress) { - _, app, ctx := getBaseSimappWithCustomKeeper() + _, app, ctx := createTestInput() addrDels, addrVals := generateAddresses(app, ctx, numAddrs) From c94a98f4598237fff410d605bec7107f6e60b74b Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Wed, 26 Feb 2020 16:05:12 +0100 Subject: [PATCH 79/90] fix based on PR comments --- simapp/test_helpers.go | 28 +++++++++++++++++----------- x/staking/genesis_test.go | 3 +-- x/staking/handler_test.go | 9 ++++----- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/simapp/test_helpers.go b/simapp/test_helpers.go index 78f2fbc41476..aeabbc47805e 100644 --- a/simapp/test_helpers.go +++ b/simapp/test_helpers.go @@ -3,6 +3,7 @@ package simapp import ( "bytes" "encoding/hex" + "fmt" "strconv" "testing" @@ -106,7 +107,9 @@ func incremental(accNum int) []sdk.AccAddress { buffer.WriteString(numString) //adding on final two digits to make addresses unique res, _ := sdk.AccAddressFromHex(buffer.String()) bech := res.String() - addresses = append(addresses, TestAddr(buffer.String(), bech)) + addr, _ := TestAddr(buffer.String(), bech) + + addresses = append(addresses, addr) buffer.Reset() } @@ -146,33 +149,36 @@ func addTestAddrs(app *SimApp, ctx sdk.Context, accNum int, accAmt sdk.Int, stra return testAddrs } -func ConvertAddrsToValAddrs(addrs []sdk.AccAddress) (valAddrs []sdk.ValAddress) { +//ConvertAddrsToValAddrs converts the provided addresses to +func ConvertAddrsToValAddrs(addrs []sdk.AccAddress) []sdk.ValAddress { + var valAddrs []sdk.ValAddress + for _, addr := range addrs { valAddrs = append(valAddrs, sdk.ValAddress(addr)) } - return + return valAddrs } -func TestAddr(addr string, bech string) sdk.AccAddress { +func TestAddr(addr string, bech string) (sdk.AccAddress, error) { res, err := sdk.AccAddressFromHex(addr) if err != nil { - panic(err) + return nil, err } bechexpected := res.String() if bech != bechexpected { - panic("Bech encoding doesn't match reference") + return nil, fmt.Errorf("bech encoding doesn't match reference") } bechres, err := sdk.AccAddressFromBech32(bech) if err != nil { - panic(err) + return nil, err } if !bytes.Equal(bechres, res) { - panic("Bech decode and hex decode don't match") + return nil, err } - return res + return res, nil } // CheckBalance checks the balance of an account. @@ -268,14 +274,14 @@ func CreateTestPubKeys(numPubKeys int) []crypto.PubKey { 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())) + publicKeys = append(publicKeys, NewPubKeyFromHex(buffer.String())) buffer.Reset() } return publicKeys } -func NewPubKey(pk string) (res crypto.PubKey) { +func NewPubKeyFromHex(pk string) (res crypto.PubKey) { pkBytes, err := hex.DecodeString(pk) if err != nil { panic(err) diff --git a/x/staking/genesis_test.go b/x/staking/genesis_test.go index c50cd63bcdf4..3d3419f3ba54 100644 --- a/x/staking/genesis_test.go +++ b/x/staking/genesis_test.go @@ -5,11 +5,10 @@ import ( "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" diff --git a/x/staking/handler_test.go b/x/staking/handler_test.go index 3cb050a4dd9f..0f5f61edf233 100644 --- a/x/staking/handler_test.go +++ b/x/staking/handler_test.go @@ -5,15 +5,14 @@ import ( "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" - "github.com/stretchr/testify/assert" - - gogotypes "github.com/gogo/protobuf/types" - "github.com/stretchr/testify/require" - "github.com/cosmos/cosmos-sdk/simapp" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/staking" From 1648edfc0d40bf7327c7ef322d746a9c05153c36 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Wed, 26 Feb 2020 16:16:56 +0100 Subject: [PATCH 80/90] use prealloc array for ConvertAddrsToValAddrs --- simapp/test_helpers.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/simapp/test_helpers.go b/simapp/test_helpers.go index aeabbc47805e..e07e7373220f 100644 --- a/simapp/test_helpers.go +++ b/simapp/test_helpers.go @@ -151,10 +151,10 @@ func addTestAddrs(app *SimApp, ctx sdk.Context, accNum int, accAmt sdk.Int, stra //ConvertAddrsToValAddrs converts the provided addresses to func ConvertAddrsToValAddrs(addrs []sdk.AccAddress) []sdk.ValAddress { - var valAddrs []sdk.ValAddress + valAddrs := make([]sdk.ValAddress, len(addrs)) - for _, addr := range addrs { - valAddrs = append(valAddrs, sdk.ValAddress(addr)) + for i, addr := range addrs { + valAddrs[i] = sdk.ValAddress(addr) } return valAddrs From 14469ccc74dbd534a67a7c6d47efe4ec544c5a4a Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Wed, 26 Feb 2020 16:29:48 +0100 Subject: [PATCH 81/90] fix lint errors --- x/staking/keeper/querier_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/x/staking/keeper/querier_test.go b/x/staking/keeper/querier_test.go index 3ca2ba33537f..be4eab297caf 100644 --- a/x/staking/keeper/querier_test.go +++ b/x/staking/keeper/querier_test.go @@ -250,7 +250,7 @@ func TestQueryDelegation(t *testing.T) { // error unknown request query.Data = bz[:len(bz)-1] - res, err = querier(ctx, []string{types.QueryDelegatorValidators}, query) + _, err = querier(ctx, []string{types.QueryDelegatorValidators}, query) require.Error(t, err) // Query bonded validator @@ -275,7 +275,7 @@ func TestQueryDelegation(t *testing.T) { // error unknown request query.Data = bz[:len(bz)-1] - res, err = querier(ctx, []string{types.QueryDelegatorValidator}, query) + _, err = querier(ctx, []string{types.QueryDelegatorValidator}, query) require.Error(t, err) // Query delegation @@ -319,7 +319,7 @@ func TestQueryDelegation(t *testing.T) { // error unknown request query.Data = bz[:len(bz)-1] - res, err = querier(ctx, []string{types.QueryDelegation}, query) + _, err = querier(ctx, []string{types.QueryDelegation}, query) require.Error(t, err) // Query validator delegations From 4de26fd67a9855aa053a08410c4d56c9a502ff21 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Wed, 26 Feb 2020 16:35:04 +0100 Subject: [PATCH 82/90] fix lint errors 2 --- x/staking/keeper/querier_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/staking/keeper/querier_test.go b/x/staking/keeper/querier_test.go index be4eab297caf..e4b685836ea1 100644 --- a/x/staking/keeper/querier_test.go +++ b/x/staking/keeper/querier_test.go @@ -549,7 +549,7 @@ func TestQueryUnbondingDelegation(t *testing.T) { Path: "/custom/staking/unbondingDelegation", Data: bz, } - res, err = querier(ctx, []string{types.QueryUnbondingDelegation}, query) + _, err = querier(ctx, []string{types.QueryUnbondingDelegation}, query) require.Error(t, err) // From d279066285edfde41480fc5ddec3290b5cf41c8f Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Thu, 27 Feb 2020 16:47:59 +0100 Subject: [PATCH 83/90] remove duplicated func --- x/staking/common_test.go | 40 ++++------------------------------------ 1 file changed, 4 insertions(+), 36 deletions(-) diff --git a/x/staking/common_test.go b/x/staking/common_test.go index 9a3cfad368ea..e55baa0f0a90 100644 --- a/x/staking/common_test.go +++ b/x/staking/common_test.go @@ -1,18 +1,13 @@ 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" + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/simapp" + cdc "github.com/cosmos/cosmos-sdk/simapp/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/staking" "github.com/cosmos/cosmos-sdk/x/staking/keeper" @@ -28,7 +23,7 @@ var ( commissionRates = staking.NewCommissionRates(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()) - PKs = createTestPubKeys(500) + PKs = simapp.CreateTestPubKeys(500) ) func NewTestMsgCreateValidator(address sdk.ValAddress, pubKey crypto.PubKey, amt sdk.Int) staking.MsgCreateValidator { @@ -42,33 +37,6 @@ func NewTestMsgDelegate(delAddr sdk.AccAddress, valAddr sdk.ValAddress, amt sdk. 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) { From ce4693930840e74f3342a99ca7bc3d4779644790 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Thu, 27 Feb 2020 16:49:53 +0100 Subject: [PATCH 84/90] rename function names --- simapp/test_helpers.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/simapp/test_helpers.go b/simapp/test_helpers.go index e07e7373220f..180d57479e7e 100644 --- a/simapp/test_helpers.go +++ b/simapp/test_helpers.go @@ -83,8 +83,8 @@ func SetupWithGenesisAccounts(genAccs []authexported.GenesisAccount, balances .. type GenerateAccountStrategy func(int) []sdk.AccAddress -// random is a strategy used by addTestAddrs() in order to generated addresses in random order. -func random(accNum int) []sdk.AccAddress { +// createRandomAccounts is a strategy used by addTestAddrs() in order to generated addresses in random order. +func createRandomAccounts(accNum int) []sdk.AccAddress { testAddrs := make([]sdk.AccAddress, accNum) for i := 0; i < accNum; i++ { pk := ed25519.GenPrivKey().PubKey() @@ -94,8 +94,8 @@ func random(accNum int) []sdk.AccAddress { return testAddrs } -// incremental is a strategy used by addTestAddrs() in order to generated addresses in ascending order. -func incremental(accNum int) []sdk.AccAddress { +// createIncrementalAccounts is a strategy used by addTestAddrs() in order to generated addresses in ascending order. +func createIncrementalAccounts(accNum int) []sdk.AccAddress { var addresses []sdk.AccAddress var buffer bytes.Buffer @@ -119,13 +119,13 @@ func incremental(accNum int) []sdk.AccAddress { // AddTestAddrs constructs and returns accNum amount of accounts with an // initial balance of accAmt in random order func AddTestAddrs(app *SimApp, ctx sdk.Context, accNum int, accAmt sdk.Int) []sdk.AccAddress { - return addTestAddrs(app, ctx, accNum, accAmt, random) + return addTestAddrs(app, ctx, accNum, accAmt, createRandomAccounts) } // AddTestAddrs constructs and returns accNum amount of accounts with an // initial balance of accAmt in random order func AddTestAddrsIncremental(app *SimApp, ctx sdk.Context, accNum int, accAmt sdk.Int) []sdk.AccAddress { - return addTestAddrs(app, ctx, accNum, accAmt, incremental) + return addTestAddrs(app, ctx, accNum, accAmt, createIncrementalAccounts) } func addTestAddrs(app *SimApp, ctx sdk.Context, accNum int, accAmt sdk.Int, strategy GenerateAccountStrategy) []sdk.AccAddress { From 256e5fc863b85f67b53acbf4391281fd3bee4ea6 Mon Sep 17 00:00:00 2001 From: Alexander Bezobchuk Date: Fri, 28 Feb 2020 09:58:55 -0800 Subject: [PATCH 85/90] Update simapp/test_helpers.go --- simapp/test_helpers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simapp/test_helpers.go b/simapp/test_helpers.go index a653a16dc9c6..5bd478eb2d53 100644 --- a/simapp/test_helpers.go +++ b/simapp/test_helpers.go @@ -269,7 +269,7 @@ 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 + // 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 From 9aa2088c23b4225e350cd832db534f78c76412dc Mon Sep 17 00:00:00 2001 From: Alexander Bezobchuk Date: Fri, 28 Feb 2020 09:59:06 -0800 Subject: [PATCH 86/90] Update x/staking/keeper/keeper.go --- x/staking/keeper/keeper.go | 1 + 1 file changed, 1 insertion(+) diff --git a/x/staking/keeper/keeper.go b/x/staking/keeper/keeper.go index 451065b3c2ba..b809e070ca95 100644 --- a/x/staking/keeper/keeper.go +++ b/x/staking/keeper/keeper.go @@ -36,6 +36,7 @@ type Keeper struct { func NewKeeper( cdc codec.Marshaler, key sdk.StoreKey, bk types.BankKeeper, sk types.SupplyKeeper, ps paramtypes.Subspace, ) Keeper { + if !ps.HasKeyTable() { ps = ps.WithKeyTable(ParamKeyTable()) } From 03af49bda292cfa8b550a07da982f968462cf328 Mon Sep 17 00:00:00 2001 From: Alexander Bezobchuk Date: Fri, 28 Feb 2020 09:59:17 -0800 Subject: [PATCH 87/90] Update simapp/test_helpers.go --- simapp/test_helpers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simapp/test_helpers.go b/simapp/test_helpers.go index 5bd478eb2d53..b4ef5dbe022b 100644 --- a/simapp/test_helpers.go +++ b/simapp/test_helpers.go @@ -149,7 +149,7 @@ func addTestAddrs(app *SimApp, ctx sdk.Context, accNum int, accAmt sdk.Int, stra return testAddrs } -//ConvertAddrsToValAddrs converts the provided addresses to +// ConvertAddrsToValAddrs converts the provided addresses to ValAddress. func ConvertAddrsToValAddrs(addrs []sdk.AccAddress) []sdk.ValAddress { valAddrs := make([]sdk.ValAddress, len(addrs)) From 19546f21979485c79366c2847d1a8a4b154b6257 Mon Sep 17 00:00:00 2001 From: Alexander Bezobchuk Date: Fri, 28 Feb 2020 09:59:26 -0800 Subject: [PATCH 88/90] Update simapp/test_helpers.go --- simapp/test_helpers.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/simapp/test_helpers.go b/simapp/test_helpers.go index b4ef5dbe022b..4232e7e8d190 100644 --- a/simapp/test_helpers.go +++ b/simapp/test_helpers.go @@ -272,8 +272,8 @@ func CreateTestPubKeys(numPubKeys int) []crypto.PubKey { // 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 + buffer.WriteString("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AF") // base pubkey string + buffer.WriteString(numString) // adding on final two digits to make pubkeys unique publicKeys = append(publicKeys, NewPubKeyFromHex(buffer.String())) buffer.Reset() } From f8442bb46f90f5a44658ac28921ec56abf1a5991 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Fri, 28 Feb 2020 19:06:03 +0100 Subject: [PATCH 89/90] add last touches to the PR --- simapp/test_helpers.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/simapp/test_helpers.go b/simapp/test_helpers.go index 4232e7e8d190..3838b26952fb 100644 --- a/simapp/test_helpers.go +++ b/simapp/test_helpers.go @@ -265,6 +265,7 @@ func incrementAllSequenceNumbers(initSeqNums []uint64) { } } +// CreateTestPubKeys generates crypto.PubKeys in ascending order. func CreateTestPubKeys(numPubKeys int) []crypto.PubKey { var publicKeys []crypto.PubKey var buffer bytes.Buffer @@ -281,12 +282,12 @@ func CreateTestPubKeys(numPubKeys int) []crypto.PubKey { return publicKeys } +// NewPubKeyFromHex returns a PubKey from a hex string. func NewPubKeyFromHex(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 From f090da2100fd969d660dd609c1f8298fe368a390 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Fri, 28 Feb 2020 19:07:10 +0100 Subject: [PATCH 90/90] edit text --- simapp/test_helpers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simapp/test_helpers.go b/simapp/test_helpers.go index 3838b26952fb..a557e7f5d397 100644 --- a/simapp/test_helpers.go +++ b/simapp/test_helpers.go @@ -265,7 +265,7 @@ func incrementAllSequenceNumbers(initSeqNums []uint64) { } } -// CreateTestPubKeys generates crypto.PubKeys in ascending order. +// CreateTestPubKeys returns a total of numPubKeys public keys in ascending order. func CreateTestPubKeys(numPubKeys int) []crypto.PubKey { var publicKeys []crypto.PubKey var buffer bytes.Buffer