From f912618b8a68efce3240ea2051627b50e2a9aadb Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Tue, 18 Feb 2020 13:42:53 +0100 Subject: [PATCH 001/101] 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 dbde12e7b1..8b59555e65 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 002/101] 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 0000000000..33a4f0c1ab --- /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 db372bce2c..50250116ef 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 003/101] 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 50250116ef..73cc64de0f 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 004/101] 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 33a4f0c1ab..8b43af1739 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 2bbd468ae0..202290762b 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 005/101] 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 0000000000..3203755cc6 --- /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 202290762b..50bb8b34d0 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 006/101] 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 50bb8b34d0..4f348a429a 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 8b43af1739..936c028148 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 007/101] fix test query validators --- simapp/test_helpers.go | 30 +++++++++++++ x/staking/keeper/old_test_common.go | 3 +- x/staking/keeper/querier_test.go | 70 ++++++++++++++++------------- 3 files changed, 70 insertions(+), 33 deletions(-) diff --git a/simapp/test_helpers.go b/simapp/test_helpers.go index abc87ed635..31b4db3b80 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 005cfbfb1f..8e4cd6b9aa 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 4f348a429a..333b3b28e6 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, + query := abci.RequestQuery{ + Path: "/custom/staking/validator", + Data: bz, + } + res, err := querier(ctx, []string{types.QueryValidator}, query) + require.NoError(t, err) + + var queriedValidator types.Validator + err = cdc.UnmarshalJSON(res, &queriedValidator) + require.NoError(t, err) + + require.Equal(t, validator, queriedValidator) } - 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) - - require.Equal(t, queriedValidators[0], validator) } 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 008/101] 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 333b3b28e6..0289bb102c 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 009/101] 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 0289bb102c..9485291731 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 010/101] 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 3203755cc6..15074cfa65 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 9485291731..7008547c4a 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 011/101] 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 15074cfa65..0000000000 --- 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 7008547c4a..19a260d531 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 012/101] 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 eda1a550cd..798716b2c2 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 0000000000..2c83dd7577 --- /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 013/101] 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 9524c4feff..8b61f8abbd 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 798716b2c2..4f4b5e7bea 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 ef7aab4355..80fbf61919 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 2c83dd7577..2e22045f70 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 19a260d531..90269a0bc9 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 8841d3e8e4..76db0c8e99 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 014/101] 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 90269a0bc9..9be64f1ed0 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 015/101] 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 9be64f1ed0..09a19b894f 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 936c028148..0f2ceb58a2 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 016/101] refactor creation of simapp --- x/staking/keeper/delegation_test.go | 11 +++-------- x/staking/keeper/test_common_test.go | 11 +++++------ 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/x/staking/keeper/delegation_test.go b/x/staking/keeper/delegation_test.go index 4f4b5e7bea..31886eac1e 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 0f2ceb58a2..7c6cf8f0c2 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/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" + "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" ) var ( From 89785765e049e6b8452108051aab765078dc290d Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Fri, 21 Feb 2020 19:19:57 +0100 Subject: [PATCH 017/101] 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 31886eac1e..45879644be 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 018/101] 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 31b4db3b80..36237bc5ec 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 45879644be..7c0bac9c4b 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 019/101] 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 36237bc5ec..cfedd7d318 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 7c0bac9c4b..dbf4de871f 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 020/101] 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 dbf4de871f..9d7c2fbed3 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 021/101] 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 9d7c2fbed3..d4004fd038 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 2e22045f70..00a28864da 100644 --- a/x/staking/keeper/old_delegation_test.go +++ b/x/staking/keeper/old_delegation_test.go @@ -4,78 +4,13 @@ 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" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/staking/types" ) -// 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) From bbc2b33f7d8c9cb5169de8bc618fd540e365e863 Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Mon, 24 Feb 2020 12:24:25 +0100 Subject: [PATCH 022/101] 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 d4004fd038..073bc1b846 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 00a28864da..e4e2026425 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 023/101] 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 073bc1b846..63e8e8fd72 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 e4e2026425..7b31fc5cb9 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 024/101] 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 63e8e8fd72..3250b0c219 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 7b31fc5cb9..03ec0f233c 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 025/101] 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 3250b0c219..bbcf4aa4d8 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 03ec0f233c..256c4e1928 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 026/101] 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 bbcf4aa4d8..b211b55434 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 256c4e1928..48ba070e16 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 027/101] 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 b211b55434..e340d97d46 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 48ba070e16..3e061619d5 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 028/101] 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 e340d97d46..a73447cd2b 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 3e061619d5..de600a24ef 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 029/101] 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 a73447cd2b..8b963853a6 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 de600a24ef..b8d233c241 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 030/101] 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 8b963853a6..f886641b3f 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 b8d233c241..fc4bbabce5 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 031/101] 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 f886641b3f..004314a927 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 fc4bbabce5..0000000000 --- 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 e05182e928..b5f05cf9a0 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 efc0ff517e..c8d4d597e9 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 032/101] 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 004314a927..a1b0c6841c 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 73cc64de0f..d4ed693106 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 7c6cf8f0c2..2275aff100 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 033/101] 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 0000000000..f6b442dc3c --- /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 2127cf51e1..3f88942a5c 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 034/101] 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 f6b442dc3c..66023db24d 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 76db0c8e99..7f1bf5bba6 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 3f88942a5c..37c5c4ee2b 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 035/101] 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 66023db24d..bd311491b9 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 7f1bf5bba6..58e7ebee2b 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 37c5c4ee2b..15d735bbe9 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 036/101] 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 bd311491b9..f59ad9f803 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 15d735bbe9..3aed1a8e15 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 037/101] 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 f59ad9f803..61fe22d04b 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 3aed1a8e15..7630824b99 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 038/101] 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 61fe22d04b..a0c302c0ba 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 7630824b99..f8fa6dfc89 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 039/101] 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 a0c302c0ba..a5e253804e 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 f8fa6dfc89..19b91a1f69 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 040/101] 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 a5e253804e..0000000000 --- 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 19b91a1f69..77296c1972 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 041/101] 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 0000000000..c5101a3c14 --- /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 77296c1972..fae13244c9 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 2275aff100..a32f3a7c03 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 1b4d8f6a5a..de9c84b10c 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 042/101] 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 8e4cd6b9aa..82bd54a317 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 c5101a3c14..6151861f16 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 a32f3a7c03..9293ed884a 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 de9c84b10c..c1dfc2ab6b 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 043/101] 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 6151861f16..168f36a57a 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 c1dfc2ab6b..18a52f9489 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 044/101] 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 168f36a57a..a7187b23cf 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 18a52f9489..c303d2029a 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 045/101] 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 a7187b23cf..0b4d4fc273 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 c303d2029a..4d866ab686 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 046/101] 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 0b4d4fc273..6745217a6e 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 4d866ab686..4a2a8a546c 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 047/101] 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 6745217a6e..9f7a8bd593 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 4a2a8a546c..c72f560d8f 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 048/101] 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 9f7a8bd593..d959b9f4b3 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 c72f560d8f..8a122c6c37 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 049/101] 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 d959b9f4b3..729903548d 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 8a122c6c37..04bf52159c 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 050/101] 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 729903548d..fa0884733d 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 04bf52159c..2d87b54978 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 051/101] 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 fa0884733d..0000000000 --- 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 2d87b54978..6f2be54725 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 052/101] 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 551239185f..c582604241 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 82bd54a317..e1c75edeae 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 053/101] 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 c582604241..730e7b0fc6 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 51a2e61aa6..f18dda6ac0 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 e1c75edeae..80a78701c0 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 0000000000..0760ebcc57 --- /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 054/101] 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 055/101] 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 056/101] 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 225832dd17..291f5ea523 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 057/101] 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 cfedd7d318..78f2fbc414 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 058/101] 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 291f5ea523..871894b9bb 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 730e7b0fc6..29a6149e4b 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 f18dda6ac0..bbbb2eaa84 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 059/101] 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 871894b9bb..35f27d32c3 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 29a6149e4b..c50cd63bcd 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 bbbb2eaa84..40d985cfeb 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 060/101] 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 40d985cfeb..38d6c57b2b 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 061/101] 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 38d6c57b2b..e4281e16b4 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 062/101] 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 35f27d32c3..9a3cfad368 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 e4281e16b4..2b1723f86a 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 063/101] 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 2b1723f86a..e62b07663a 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 064/101] 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 e62b07663a..da1c1e6845 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 065/101] 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 da1c1e6845..c98b54d111 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 066/101] 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 c98b54d111..9a8d21dee0 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 067/101] 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 9a8d21dee0..e15768cee4 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 068/101] 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 e15768cee4..2a9b4bc43a 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 069/101] 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 2a9b4bc43a..a27545dc81 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 070/101] 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 a27545dc81..991550bcc1 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 071/101] 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 991550bcc1..9db8322c03 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 072/101] 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 9db8322c03..06d6e21576 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 073/101] 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 06d6e21576..59a1a83a90 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 074/101] 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 59a1a83a90..c5b9c0cb18 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 075/101] 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 c5b9c0cb18..46d804e568 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 076/101] 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 46d804e568..3cb050a4dd 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 077/101] 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 1b9708e78e..0000000000 --- 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 078/101] 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 69a168e5a4..30306adc6f 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 a1b0c6841c..e1f7b7de24 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 d4ed693106..3a3f110059 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 09a19b894f..3ca2ba3353 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 fae13244c9..e333967a8c 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 6f2be54725..f7295a5421 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 079/101] 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 78f2fbc414..aeabbc4780 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 c50cd63bcd..3d3419f3ba 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 3cb050a4dd..0f5f61edf2 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 080/101] 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 aeabbc4780..e07e737322 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 081/101] 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 3ca2ba3353..be4eab297c 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 082/101] 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 be4eab297c..e4b685836e 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 2b75f506044665e682dbec9138bfac88e51f4079 Mon Sep 17 00:00:00 2001 From: Anthony Date: Thu, 27 Feb 2020 14:37:16 +0700 Subject: [PATCH 083/101] Merge PR #5708: fix type for the event documentation --- docs/core/events.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/core/events.md b/docs/core/events.md index 359e2b94a4..d5ac5893f0 100644 --- a/docs/core/events.md +++ b/docs/core/events.md @@ -16,7 +16,7 @@ various messages and index transactions." Events are implemented in the Cosmos SDK as an alias of the ABCI `Event` type and take the form of: `{eventType}.{eventAttribute}={value}`. -+++ https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/abci/types/types.pb.go#L2661-L2667 ++++ https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/abci/types/types.pb.go#L2187-L2193 Events contain: From 8227d9e376e0bbedb2a3d3f3933e012cbe3cf709 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Wed, 26 Feb 2020 23:47:05 -0800 Subject: [PATCH 084/101] Bump github.com/golang/protobuf from 1.3.3 to 1.3.4 (#5707) Bumps [github.com/golang/protobuf](https://github.com/golang/protobuf) from 1.3.3 to 1.3.4. - [Release notes](https://github.com/golang/protobuf/releases) - [Commits](https://github.com/golang/protobuf/compare/v1.3.3...v1.3.4) Signed-off-by: dependabot-preview[bot] Co-authored-by: Alexander Bezobchuk --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 1ebba790a5..d9debb5a73 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/cosmos/ledger-cosmos-go v0.11.1 github.com/gogo/protobuf v1.3.1 github.com/golang/mock v1.3.1-0.20190508161146-9fa652df1129 - github.com/golang/protobuf v1.3.3 + github.com/golang/protobuf v1.3.4 github.com/gorilla/handlers v1.4.2 github.com/gorilla/mux v1.7.4 github.com/hashicorp/golang-lru v0.5.4 diff --git a/go.sum b/go.sum index c4f48196d4..7eeaf96559 100644 --- a/go.sum +++ b/go.sum @@ -95,6 +95,8 @@ github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4 h1:87PNWwrRvUSnqS4dlcBU/ftvOIBep4sYuBLlh6rX2wk= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= From 5a2e59ebb23d1d23546f1145d8814a457655935a Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Thu, 27 Feb 2020 10:53:22 +0000 Subject: [PATCH 085/101] Exclude proto files from format (#5706) * Don't change proto files on make format The format target does not need to depend on tools. Thus remove dependency. * Run make format Co-authored-by: Alexander Bezobchuk --- Makefile | 8 ++++---- client/cmd_test.go | 6 +++--- codec/amino_codec_test.go | 5 +++-- codec/hybrid_codec_test.go | 3 ++- codec/proto_codec_test.go | 3 ++- types/address_bench_test.go | 3 ++- types/decimal_test.go | 3 ++- x/bank/client/rest/rest.go | 3 ++- x/bank/types/key_test.go | 3 ++- x/params/keeper/common_test.go | 7 ++++--- x/params/keeper/keeper_test.go | 3 ++- x/params/types/table_test.go | 3 ++- x/staking/types/commission.go | 3 ++- x/staking/types/delegation.go | 3 ++- x/staking/types/params.go | 3 ++- x/upgrade/client/cli/query.go | 1 + x/upgrade/keeper/keeper.go | 1 + x/upgrade/keeper/querier.go | 1 + 18 files changed, 39 insertions(+), 23 deletions(-) diff --git a/Makefile b/Makefile index 96f04d16a8..68d7a359ab 100644 --- a/Makefile +++ b/Makefile @@ -191,10 +191,10 @@ lint: go mod verify .PHONY: lint -format: tools - find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/lcd/statik/statik.go" | xargs gofmt -w -s - find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/lcd/statik/statik.go" | xargs misspell -w - find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/lcd/statik/statik.go" | xargs goimports -w -local github.com/cosmos/cosmos-sdk +format: + find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/lcd/statik/statik.go" -not -name '*.pb.go' | xargs gofmt -w -s + find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/lcd/statik/statik.go" -not -name '*.pb.go' | xargs misspell -w + find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/lcd/statik/statik.go" -not -name '*.pb.go' | xargs goimports -w -local github.com/cosmos/cosmos-sdk .PHONY: format ############################################################################### diff --git a/client/cmd_test.go b/client/cmd_test.go index 675cc296ae..554d399537 100644 --- a/client/cmd_test.go +++ b/client/cmd_test.go @@ -37,10 +37,10 @@ func TestValidateCmd(t *testing.T) { args []string wantErr bool }{ - {"misspelled command", []string{"comission"}, true}, // nolint: misspell + {"misspelled command", []string{"commission"}, true}, // nolint: misspell {"no command provided", []string{}, false}, - {"help flag", []string{"comission", "--help"}, false}, // nolint: misspell - {"shorthand help flag", []string{"comission", "-h"}, false}, // nolint: misspell + {"help flag", []string{"commission", "--help"}, false}, // nolint: misspell + {"shorthand help flag", []string{"commission", "-h"}, false}, // nolint: misspell } for _, tt := range tests { diff --git a/codec/amino_codec_test.go b/codec/amino_codec_test.go index 31eeb413e8..3836b22d38 100644 --- a/codec/amino_codec_test.go +++ b/codec/amino_codec_test.go @@ -3,10 +3,11 @@ package codec_test import ( "testing" - "github.com/cosmos/cosmos-sdk/codec" - "github.com/cosmos/cosmos-sdk/codec/testdata" "github.com/stretchr/testify/require" amino "github.com/tendermint/go-amino" + + "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/codec/testdata" ) func createTestCodec() *amino.Codec { diff --git a/codec/hybrid_codec_test.go b/codec/hybrid_codec_test.go index 353f0c3896..911ae8c9d9 100644 --- a/codec/hybrid_codec_test.go +++ b/codec/hybrid_codec_test.go @@ -3,9 +3,10 @@ package codec_test import ( "testing" + "github.com/stretchr/testify/require" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/testdata" - "github.com/stretchr/testify/require" ) func TestHybridCodec(t *testing.T) { diff --git a/codec/proto_codec_test.go b/codec/proto_codec_test.go index c49544e060..aae71b4dfd 100644 --- a/codec/proto_codec_test.go +++ b/codec/proto_codec_test.go @@ -3,9 +3,10 @@ package codec_test import ( "testing" + "github.com/stretchr/testify/require" + "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/codec/testdata" - "github.com/stretchr/testify/require" ) func TestProtoCodec(t *testing.T) { diff --git a/types/address_bench_test.go b/types/address_bench_test.go index 8e438a81da..1bb0d15f61 100644 --- a/types/address_bench_test.go +++ b/types/address_bench_test.go @@ -5,9 +5,10 @@ import ( "testing" "time" - "github.com/cosmos/cosmos-sdk/types" "github.com/stretchr/testify/require" + "github.com/cosmos/cosmos-sdk/types" + "github.com/tendermint/tendermint/crypto/ed25519" ) diff --git a/types/decimal_test.go b/types/decimal_test.go index c56d303ee1..33ca99d498 100644 --- a/types/decimal_test.go +++ b/types/decimal_test.go @@ -6,10 +6,11 @@ import ( "math/big" "testing" - "github.com/cosmos/cosmos-sdk/codec" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" yaml "gopkg.in/yaml.v2" + + "github.com/cosmos/cosmos-sdk/codec" ) // create a decimal from a decimal string (ex. "1234.5678") diff --git a/x/bank/client/rest/rest.go b/x/bank/client/rest/rest.go index b2b1ff84c8..578e41c067 100644 --- a/x/bank/client/rest/rest.go +++ b/x/bank/client/rest/rest.go @@ -1,8 +1,9 @@ package rest import ( - "github.com/cosmos/cosmos-sdk/client/context" "github.com/gorilla/mux" + + "github.com/cosmos/cosmos-sdk/client/context" ) // RegisterRoutes - Central function to define routes that get registered by the main application diff --git a/x/bank/types/key_test.go b/x/bank/types/key_test.go index b1e5a76141..f3b5717fbe 100644 --- a/x/bank/types/key_test.go +++ b/x/bank/types/key_test.go @@ -3,9 +3,10 @@ package types_test import ( "testing" + "github.com/stretchr/testify/require" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/stretchr/testify/require" ) func cloneAppend(bz []byte, tail []byte) (res []byte) { diff --git a/x/params/keeper/common_test.go b/x/params/keeper/common_test.go index 92d9f1ee56..c6c151809c 100644 --- a/x/params/keeper/common_test.go +++ b/x/params/keeper/common_test.go @@ -1,14 +1,15 @@ package keeper_test import ( + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/libs/log" + 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" paramskeeper "github.com/cosmos/cosmos-sdk/x/params/keeper" "github.com/cosmos/cosmos-sdk/x/params/types/proposal" - abci "github.com/tendermint/tendermint/abci/types" - "github.com/tendermint/tendermint/libs/log" - dbm "github.com/tendermint/tm-db" ) func testComponents() (codec.Marshaler, sdk.Context, sdk.StoreKey, sdk.StoreKey, paramskeeper.Keeper) { diff --git a/x/params/keeper/keeper_test.go b/x/params/keeper/keeper_test.go index 0c34558e9f..de83f1f344 100644 --- a/x/params/keeper/keeper_test.go +++ b/x/params/keeper/keeper_test.go @@ -4,10 +4,11 @@ import ( "reflect" "testing" + "github.com/stretchr/testify/require" + "github.com/cosmos/cosmos-sdk/store/prefix" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/params/types" - "github.com/stretchr/testify/require" ) func validateNoOp(_ interface{}) error { return nil } diff --git a/x/params/types/table_test.go b/x/params/types/table_test.go index db2c9d3215..0baff40f8c 100644 --- a/x/params/types/table_test.go +++ b/x/params/types/table_test.go @@ -4,8 +4,9 @@ import ( "testing" "time" - "github.com/cosmos/cosmos-sdk/x/params/types" "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/x/params/types" ) func TestKeyTable(t *testing.T) { diff --git a/x/staking/types/commission.go b/x/staking/types/commission.go index 9a58210f61..54891b5dca 100644 --- a/x/staking/types/commission.go +++ b/x/staking/types/commission.go @@ -3,8 +3,9 @@ package types import ( "time" - sdk "github.com/cosmos/cosmos-sdk/types" yaml "gopkg.in/yaml.v2" + + sdk "github.com/cosmos/cosmos-sdk/types" ) // NewCommissionRates returns an initialized validator commission rates. diff --git a/x/staking/types/delegation.go b/x/staking/types/delegation.go index f25aaac7b2..51fca1d38e 100644 --- a/x/staking/types/delegation.go +++ b/x/staking/types/delegation.go @@ -6,10 +6,11 @@ import ( "strings" "time" + yaml "gopkg.in/yaml.v2" + "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/staking/exported" - yaml "gopkg.in/yaml.v2" ) // Implements Delegation interface diff --git a/x/staking/types/params.go b/x/staking/types/params.go index b738f1b06e..8d2b14ec69 100644 --- a/x/staking/types/params.go +++ b/x/staking/types/params.go @@ -6,10 +6,11 @@ import ( "strings" "time" + yaml "gopkg.in/yaml.v2" + "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" paramtypes "github.com/cosmos/cosmos-sdk/x/params/types" - yaml "gopkg.in/yaml.v2" ) // Staking params default values diff --git a/x/upgrade/client/cli/query.go b/x/upgrade/client/cli/query.go index c9022a4824..390ed9e5de 100644 --- a/x/upgrade/client/cli/query.go +++ b/x/upgrade/client/cli/query.go @@ -3,6 +3,7 @@ package cli import ( "encoding/binary" "fmt" + "github.com/cosmos/cosmos-sdk/x/upgrade/types" "github.com/spf13/cobra" diff --git a/x/upgrade/keeper/keeper.go b/x/upgrade/keeper/keeper.go index 03802b335c..ba789aeb7b 100644 --- a/x/upgrade/keeper/keeper.go +++ b/x/upgrade/keeper/keeper.go @@ -3,6 +3,7 @@ package keeper import ( "encoding/binary" "fmt" + "github.com/cosmos/cosmos-sdk/x/upgrade/types" "github.com/tendermint/tendermint/libs/log" diff --git a/x/upgrade/keeper/querier.go b/x/upgrade/keeper/querier.go index 2a3ff8bf6d..2aebceeac0 100644 --- a/x/upgrade/keeper/querier.go +++ b/x/upgrade/keeper/querier.go @@ -2,6 +2,7 @@ package keeper import ( "encoding/binary" + "github.com/cosmos/cosmos-sdk/x/upgrade/types" abci "github.com/tendermint/tendermint/abci/types" From d279066285edfde41480fc5ddec3290b5cf41c8f Mon Sep 17 00:00:00 2001 From: Jonathan Gimeno Date: Thu, 27 Feb 2020 16:47:59 +0100 Subject: [PATCH 086/101] 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 9a3cfad368..e55baa0f0a 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" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/crypto" + "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" - 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" @@ -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 087/101] 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 e07e737322..180d57479e 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 de0f1a9e40eb36ddbd2c7ce844caa8599acd4f9a Mon Sep 17 00:00:00 2001 From: Marko Date: Fri, 28 Feb 2020 06:36:42 +0100 Subject: [PATCH 088/101] Merge PR #5714: tools: add mergify --- .mergify.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .mergify.yml diff --git a/.mergify.yml b/.mergify.yml new file mode 100644 index 0000000000..f827f65542 --- /dev/null +++ b/.mergify.yml @@ -0,0 +1,10 @@ +pull_request_rules: + - name: automatic merge for master when CI passes, has 1 review and has the label automerge + conditions: + - "#approved-reviews-by>=1" + - "status-success=ci/circleci - Pull Request" + - base=master + - label=automerge + actions: + merge: + method: squash From 0b7449129af3268c1d0e4d3fef4741beb2b4aa30 Mon Sep 17 00:00:00 2001 From: Anil Kumar Kammari Date: Fri, 28 Feb 2020 11:56:04 +0530 Subject: [PATCH 089/101] Merge PR #5500: Regen network/multistore upgrades --- baseapp/baseapp.go | 60 -------- baseapp/baseapp_test.go | 50 ------- simapp/app.go | 4 +- simapp/app_test.go | 6 +- simapp/sim_bench_test.go | 4 +- simapp/sim_test.go | 12 +- simapp/test_helpers.go | 4 +- store/types/store.go | 7 + x/crisis/handler_test.go | 2 +- x/crisis/internal/keeper/integration_test.go | 2 +- x/gov/genesis_test.go | 2 +- x/upgrade/abci.go | 8 ++ x/upgrade/abci_test.go | 34 ++++- x/upgrade/alias.go | 1 + x/upgrade/doc.go | 21 +++ x/upgrade/keeper/keeper.go | 70 ++++++++- x/upgrade/spec/01_concepts.md | 27 ++++ x/upgrade/types/storeloader.go | 23 +++ x/upgrade/types/storeloader_test.go | 144 +++++++++++++++++++ 19 files changed, 351 insertions(+), 130 deletions(-) create mode 100644 x/upgrade/types/storeloader.go create mode 100644 x/upgrade/types/storeloader_test.go diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 3837a34ccc..4fe7d0ba80 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -1,11 +1,8 @@ package baseapp import ( - "encoding/json" "errors" "fmt" - "io/ioutil" - "os" "reflect" "runtime/debug" "strings" @@ -17,7 +14,6 @@ import ( dbm "github.com/tendermint/tm-db" "github.com/cosmos/cosmos-sdk/store" - storetypes "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) @@ -226,62 +222,6 @@ func DefaultStoreLoader(ms sdk.CommitMultiStore) error { return ms.LoadLatestVersion() } -// StoreLoaderWithUpgrade is used to prepare baseapp with a fixed StoreLoader -// pattern. This is useful in test cases, or with custom upgrade loading logic. -func StoreLoaderWithUpgrade(upgrades *storetypes.StoreUpgrades) StoreLoader { - return func(ms sdk.CommitMultiStore) error { - return ms.LoadLatestVersionAndUpgrade(upgrades) - } -} - -// UpgradeableStoreLoader can be configured by SetStoreLoader() to check for the -// existence of a given upgrade file - json encoded StoreUpgrades data. -// -// If not file is present, it will peform the default load (no upgrades to store). -// -// If the file is present, it will parse the file and execute those upgrades -// (rename or delete stores), while loading the data. It will also delete the -// upgrade file upon successful load, so that the upgrade is only applied once, -// and not re-applied on next restart -// -// This is useful for in place migrations when a store key is renamed between -// two versions of the software. (TODO: this code will move to x/upgrades -// when PR #4233 is merged, here mainly to help test the design) -func UpgradeableStoreLoader(upgradeInfoPath string) StoreLoader { - return func(ms sdk.CommitMultiStore) error { - _, err := os.Stat(upgradeInfoPath) - if os.IsNotExist(err) { - return DefaultStoreLoader(ms) - } else if err != nil { - return err - } - - // there is a migration file, let's execute - data, err := ioutil.ReadFile(upgradeInfoPath) - if err != nil { - return fmt.Errorf("cannot read upgrade file %s: %v", upgradeInfoPath, err) - } - - var upgrades storetypes.StoreUpgrades - err = json.Unmarshal(data, &upgrades) - if err != nil { - return fmt.Errorf("cannot parse upgrade file: %v", err) - } - - err = ms.LoadLatestVersionAndUpgrade(&upgrades) - if err != nil { - return fmt.Errorf("load and upgrade database: %v", err) - } - - // if we have a successful load, we delete the file - err = os.Remove(upgradeInfoPath) - if err != nil { - return fmt.Errorf("deleting upgrade file %s: %v", upgradeInfoPath, err) - } - return nil - } -} - // LoadVersion loads the BaseApp application version. It will panic if called // more than once on a running baseapp. func (app *BaseApp) LoadVersion(version int64, baseKey *sdk.KVStoreKey) error { diff --git a/baseapp/baseapp_test.go b/baseapp/baseapp_test.go index 6ee5aabbb0..840531865d 100644 --- a/baseapp/baseapp_test.go +++ b/baseapp/baseapp_test.go @@ -4,7 +4,6 @@ import ( "bytes" "encoding/binary" "fmt" - "io/ioutil" "os" "sync" "testing" @@ -137,18 +136,6 @@ func useDefaultLoader(app *BaseApp) { app.SetStoreLoader(DefaultStoreLoader) } -func useUpgradeLoader(upgrades *store.StoreUpgrades) func(*BaseApp) { - return func(app *BaseApp) { - app.SetStoreLoader(StoreLoaderWithUpgrade(upgrades)) - } -} - -func useFileUpgradeLoader(upgradeInfoPath string) func(*BaseApp) { - return func(app *BaseApp) { - app.SetStoreLoader(UpgradeableStoreLoader(upgradeInfoPath)) - } -} - func initStore(t *testing.T, db dbm.DB, storeKey string, k, v []byte) { rs := rootmulti.NewStore(db) rs.SetPruning(store.PruneNothing) @@ -184,19 +171,6 @@ func checkStore(t *testing.T, db dbm.DB, ver int64, storeKey string, k, v []byte // Test that we can make commits and then reload old versions. // Test that LoadLatestVersion actually does. func TestSetLoader(t *testing.T) { - // write a renamer to a file - f, err := ioutil.TempFile("", "upgrade-*.json") - require.NoError(t, err) - data := []byte(`{"renamed":[{"old_key": "bnk", "new_key": "banker"}]}`) - _, err = f.Write(data) - require.NoError(t, err) - configName := f.Name() - require.NoError(t, f.Close()) - - // make sure it exists before running everything - _, err = os.Stat(configName) - require.NoError(t, err) - cases := map[string]struct { setLoader func(*BaseApp) origStoreKey string @@ -211,26 +185,6 @@ func TestSetLoader(t *testing.T) { origStoreKey: "foo", loadStoreKey: "foo", }, - "rename with inline opts": { - setLoader: useUpgradeLoader(&store.StoreUpgrades{ - Renamed: []store.StoreRename{{ - OldKey: "foo", - NewKey: "bar", - }}, - }), - origStoreKey: "foo", - loadStoreKey: "bar", - }, - "file loader with missing file": { - setLoader: useFileUpgradeLoader(configName + "randomchars"), - origStoreKey: "bnk", - loadStoreKey: "bnk", - }, - "file loader with existing file": { - setLoader: useFileUpgradeLoader(configName), - origStoreKey: "bnk", - loadStoreKey: "banker", - }, } k := []byte("key") @@ -265,10 +219,6 @@ func TestSetLoader(t *testing.T) { checkStore(t, db, 2, tc.loadStoreKey, []byte("foo"), nil) }) } - - // ensure config file was deleted - _, err = os.Stat(configName) - require.True(t, os.IsNotExist(err)) } func TestAppVersionSetterGetter(t *testing.T) { diff --git a/simapp/app.go b/simapp/app.go index e7253c9a78..67b6d9e119 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -122,7 +122,7 @@ type SimApp struct { // NewSimApp returns a reference to an initialized SimApp. func NewSimApp( logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest bool, skipUpgradeHeights map[int64]bool, - invCheckPeriod uint, baseAppOptions ...func(*bam.BaseApp), + homePath string, invCheckPeriod uint, baseAppOptions ...func(*bam.BaseApp), ) *SimApp { // TODO: Remove cdc in favor of appCodec once all modules are migrated. @@ -189,7 +189,7 @@ func NewSimApp( app.CrisisKeeper = crisis.NewKeeper( app.subspaces[crisis.ModuleName], invCheckPeriod, app.SupplyKeeper, auth.FeeCollectorName, ) - app.UpgradeKeeper = upgrade.NewKeeper(skipUpgradeHeights, keys[upgrade.StoreKey], appCodec) + app.UpgradeKeeper = upgrade.NewKeeper(skipUpgradeHeights, keys[upgrade.StoreKey], appCodec, homePath) // create evidence keeper with router evidenceKeeper := evidence.NewKeeper( diff --git a/simapp/app_test.go b/simapp/app_test.go index 9cf211a941..17b6b3c286 100644 --- a/simapp/app_test.go +++ b/simapp/app_test.go @@ -15,7 +15,7 @@ import ( func TestSimAppExport(t *testing.T) { db := dbm.NewMemDB() - app := NewSimApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, 0) + app := NewSimApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0) genesisState := NewDefaultGenesisState() stateBytes, err := codec.MarshalJSONIndent(app.Codec(), genesisState) @@ -31,7 +31,7 @@ func TestSimAppExport(t *testing.T) { app.Commit() // Making a new app object with the db, so that initchain hasn't been called - app2 := NewSimApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, 0) + app2 := NewSimApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0) _, _, err = app2.ExportAppStateAndValidators(false, []string{}) require.NoError(t, err, "ExportAppStateAndValidators should not have an error") } @@ -39,7 +39,7 @@ func TestSimAppExport(t *testing.T) { // ensure that black listed addresses are properly set in bank keeper func TestBlackListedAddrs(t *testing.T) { db := dbm.NewMemDB() - app := NewSimApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, 0) + app := NewSimApp(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0) for acc := range maccPerms { require.Equal(t, !allowedReceivingModAcc[acc], app.BankKeeper.BlacklistedAddr(app.SupplyKeeper.GetModuleAddress(acc))) diff --git a/simapp/sim_bench_test.go b/simapp/sim_bench_test.go index b09a3a9090..6d8ee05dbf 100644 --- a/simapp/sim_bench_test.go +++ b/simapp/sim_bench_test.go @@ -26,7 +26,7 @@ func BenchmarkFullAppSimulation(b *testing.B) { } }() - app := NewSimApp(logger, db, nil, true, map[int64]bool{}, FlagPeriodValue, interBlockCacheOpt()) + app := NewSimApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, interBlockCacheOpt()) // run randomized simulation _, simParams, simErr := simulation.SimulateFromSeed( @@ -65,7 +65,7 @@ func BenchmarkInvariants(b *testing.B) { } }() - app := NewSimApp(logger, db, nil, true, map[int64]bool{}, FlagPeriodValue, interBlockCacheOpt()) + app := NewSimApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, interBlockCacheOpt()) // run randomized simulation _, simParams, simErr := simulation.SimulateFromSeed( diff --git a/simapp/sim_test.go b/simapp/sim_test.go index 18cb24a894..6053ff83cc 100644 --- a/simapp/sim_test.go +++ b/simapp/sim_test.go @@ -63,7 +63,7 @@ func TestFullAppSimulation(t *testing.T) { require.NoError(t, os.RemoveAll(dir)) }() - app := NewSimApp(logger, db, nil, true, map[int64]bool{}, FlagPeriodValue, fauxMerkleModeOpt) + app := NewSimApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, fauxMerkleModeOpt) require.Equal(t, "SimApp", app.Name()) // run randomized simulation @@ -95,7 +95,7 @@ func TestAppImportExport(t *testing.T) { require.NoError(t, os.RemoveAll(dir)) }() - app := NewSimApp(logger, db, nil, true, map[int64]bool{}, FlagPeriodValue, fauxMerkleModeOpt) + app := NewSimApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, fauxMerkleModeOpt) require.Equal(t, "SimApp", app.Name()) // Run randomized simulation @@ -129,7 +129,7 @@ func TestAppImportExport(t *testing.T) { require.NoError(t, os.RemoveAll(newDir)) }() - newApp := NewSimApp(log.NewNopLogger(), newDB, nil, true, map[int64]bool{}, FlagPeriodValue, fauxMerkleModeOpt) + newApp := NewSimApp(log.NewNopLogger(), newDB, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, fauxMerkleModeOpt) require.Equal(t, "SimApp", newApp.Name()) var genesisState GenesisState @@ -181,7 +181,7 @@ func TestAppSimulationAfterImport(t *testing.T) { require.NoError(t, os.RemoveAll(dir)) }() - app := NewSimApp(logger, db, nil, true, map[int64]bool{}, FlagPeriodValue, fauxMerkleModeOpt) + app := NewSimApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, fauxMerkleModeOpt) require.Equal(t, "SimApp", app.Name()) // Run randomized simulation @@ -220,7 +220,7 @@ func TestAppSimulationAfterImport(t *testing.T) { require.NoError(t, os.RemoveAll(newDir)) }() - newApp := NewSimApp(log.NewNopLogger(), newDB, nil, true, map[int64]bool{}, FlagPeriodValue, fauxMerkleModeOpt) + newApp := NewSimApp(log.NewNopLogger(), newDB, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, fauxMerkleModeOpt) require.Equal(t, "SimApp", newApp.Name()) newApp.InitChain(abci.RequestInitChain{ @@ -266,7 +266,7 @@ func TestAppStateDeterminism(t *testing.T) { db := dbm.NewMemDB() - app := NewSimApp(logger, db, nil, true, map[int64]bool{}, FlagPeriodValue, interBlockCacheOpt()) + app := NewSimApp(logger, db, nil, true, map[int64]bool{}, DefaultNodeHome, FlagPeriodValue, interBlockCacheOpt()) fmt.Printf( "running non-determinism simulation; seed %d: %d/%d, attempt: %d/%d\n", diff --git a/simapp/test_helpers.go b/simapp/test_helpers.go index abc87ed635..234995a19b 100644 --- a/simapp/test_helpers.go +++ b/simapp/test_helpers.go @@ -23,7 +23,7 @@ import ( // Setup initializes a new SimApp. A Nop logger is set in SimApp. func Setup(isCheckTx bool) *SimApp { db := dbm.NewMemDB() - app := NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, 0) + app := NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0) if !isCheckTx { // init chain must be called to stop deliverState from being nil genesisState := NewDefaultGenesisState() @@ -48,7 +48,7 @@ func Setup(isCheckTx bool) *SimApp { // accounts and possible balances. func SetupWithGenesisAccounts(genAccs []authexported.GenesisAccount, balances ...bank.Balance) *SimApp { db := dbm.NewMemDB() - app := NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, 0) + app := NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, DefaultNodeHome, 0) // initialize the chain with the passed in genesis accounts genesisState := NewDefaultGenesisState() diff --git a/store/types/store.go b/store/types/store.go index d48585f8fc..72575baa6a 100644 --- a/store/types/store.go +++ b/store/types/store.go @@ -44,6 +44,13 @@ type StoreUpgrades struct { Deleted []string `json:"deleted"` } +// UpgradeInfo defines height and name of the upgrade +// to ensure multistore upgrades happen only at matching height. +type UpgradeInfo struct { + Name string `json:"name"` + Height int64 `json:"height"` +} + // StoreRename defines a name change of a sub-store. // All data previously under a PrefixStore with OldKey will be copied // to a PrefixStore with NewKey, then deleted from OldKey store. diff --git a/x/crisis/handler_test.go b/x/crisis/handler_test.go index 2db4012d2f..83907543f2 100644 --- a/x/crisis/handler_test.go +++ b/x/crisis/handler_test.go @@ -25,7 +25,7 @@ var ( func createTestApp() (*simapp.SimApp, sdk.Context, []sdk.AccAddress) { db := dbm.NewMemDB() - app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, 1) + app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 1) ctx := app.NewContext(true, abci.Header{}) constantFee := sdk.NewInt64Coin(sdk.DefaultBondDenom, 10) diff --git a/x/crisis/internal/keeper/integration_test.go b/x/crisis/internal/keeper/integration_test.go index a98a0b4453..4dc123fda4 100644 --- a/x/crisis/internal/keeper/integration_test.go +++ b/x/crisis/internal/keeper/integration_test.go @@ -11,7 +11,7 @@ import ( func createTestApp() *simapp.SimApp { db := dbm.NewMemDB() - app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, 5) + app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 5) // init chain must be called to stop deliverState from being nil genesisState := simapp.NewDefaultGenesisState() stateBytes, err := codec.MarshalJSONIndent(app.Codec(), genesisState) diff --git a/x/gov/genesis_test.go b/x/gov/genesis_test.go index 133c7c4f3a..d9f8857b16 100644 --- a/x/gov/genesis_test.go +++ b/x/gov/genesis_test.go @@ -63,7 +63,7 @@ func TestImportExportQueues(t *testing.T) { } db := dbm.NewMemDB() - app2 := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, 0) + app2 := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, map[int64]bool{}, simapp.DefaultNodeHome, 0) app2.InitChain( abci.RequestInitChain{ diff --git a/x/upgrade/abci.go b/x/upgrade/abci.go index 11edf7fbbc..f5c6d6a348 100644 --- a/x/upgrade/abci.go +++ b/x/upgrade/abci.go @@ -38,6 +38,14 @@ func BeginBlocker(k Keeper, ctx sdk.Context, _ abci.RequestBeginBlock) { upgradeMsg := fmt.Sprintf("UPGRADE \"%s\" NEEDED at %s: %s", plan.Name, plan.DueAt(), plan.Info) // We don't have an upgrade handler for this upgrade name, meaning this software is out of date so shutdown ctx.Logger().Error(upgradeMsg) + + // Write the upgrade info to disk. The UpgradeStoreLoader uses this info to perform or skip + // store migrations. + err := k.DumpUpgradeInfoToDisk(ctx.BlockHeight(), plan.Name) + if err != nil { + panic(fmt.Errorf("unable to write upgrade info to filesystem: %s", err.Error())) + } + panic(upgradeMsg) } // We have an upgrade handler for this upgrade name, so apply the upgrade diff --git a/x/upgrade/abci_test.go b/x/upgrade/abci_test.go index c82fe757a5..aa2bf33cfb 100644 --- a/x/upgrade/abci_test.go +++ b/x/upgrade/abci_test.go @@ -1,10 +1,15 @@ package upgrade_test import ( + "encoding/json" "errors" + "io/ioutil" + "os" "testing" "time" + storetypes "github.com/cosmos/cosmos-sdk/store/types" + "github.com/stretchr/testify/require" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/libs/log" @@ -31,7 +36,7 @@ var s TestSuite func setupTest(height int64, skip map[int64]bool) TestSuite { db := dbm.NewMemDB() - app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, skip, 0) + app := simapp.NewSimApp(log.NewNopLogger(), db, nil, true, skip, simapp.DefaultNodeHome, 0) genesisState := simapp.NewDefaultGenesisState() stateBytes, err := codec.MarshalJSONIndent(app.Codec(), genesisState) if err != nil { @@ -393,3 +398,30 @@ func TestUpgradeWithoutSkip(t *testing.T) { VerifyDoUpgrade(t) VerifyDone(t, s.ctx, "test") } + +func TestDumpUpgradeInfoToFile(t *testing.T) { + s := setupTest(10, map[int64]bool{}) + + planHeight := s.ctx.BlockHeight() + 1 + name := "test" + t.Log("verify if upgrade height is dumped to file") + err := s.keeper.DumpUpgradeInfoToDisk(planHeight, name) + require.Nil(t, err) + + upgradeInfoFilePath, err := s.keeper.GetUpgradeInfoPath() + require.Nil(t, err) + + data, err := ioutil.ReadFile(upgradeInfoFilePath) + require.NoError(t, err) + + var upgradeInfo storetypes.UpgradeInfo + err = json.Unmarshal(data, &upgradeInfo) + require.Nil(t, err) + + t.Log("Verify upgrade height from file matches ") + require.Equal(t, upgradeInfo.Height, planHeight) + + // clear the test file + err = os.Remove(upgradeInfoFilePath) + require.Nil(t, err) +} diff --git a/x/upgrade/alias.go b/x/upgrade/alias.go index c8ae7bf631..784eb681b1 100644 --- a/x/upgrade/alias.go +++ b/x/upgrade/alias.go @@ -27,6 +27,7 @@ var ( NewSoftwareUpgradeProposal = types.NewSoftwareUpgradeProposal NewCancelSoftwareUpgradeProposal = types.NewCancelSoftwareUpgradeProposal NewQueryAppliedParams = types.NewQueryAppliedParams + UpgradeStoreLoader = types.UpgradeStoreLoader NewKeeper = keeper.NewKeeper NewQuerier = keeper.NewQuerier ) diff --git a/x/upgrade/doc.go b/x/upgrade/doc.go index 160580d5c7..79867f7a8e 100644 --- a/x/upgrade/doc.go +++ b/x/upgrade/doc.go @@ -68,6 +68,27 @@ as well as providing the opportunity for the upgraded software to perform any ne (with the old binary) and applying the migration (with the new binary) are enforced in the state machine. Actually switching the binaries is an ops task and not handled inside the sdk / abci app. +Here is a sample code to set store migrations with an upgrade: + + // this configures a no-op upgrade handler for the "my-fancy-upgrade" upgrade + app.UpgradeKeeper.SetUpgradeHandler("my-fancy-upgrade", func(ctx sdk.Context, plan upgrade.Plan) { + // upgrade changes here + }) + + upgradeInfo := app.UpgradeKeeper.ReadUpgradeInfoFromDisk() + if upgradeInfo.Name == "my-fancy-upgrade" && !app.UpgradeKeeper.IsSkipHeight(upgradeInfo.Height) { + storeUpgrades := store.StoreUpgrades{ + Renamed: []store.StoreRename{{ + OldKey: "foo", + NewKey: "bar", + }}, + Deleted: []string{}, + } + + // configure store loader that checks if version == upgradeHeight and applies store upgrades + app.SetStoreLoader(upgrade.UpgradeStoreLoader(upgradeInfo.Height, &storeUpgrades)) + } + Halt Behavior Before halting the ABCI state machine in the BeginBlocker method, the upgrade module will log an error diff --git a/x/upgrade/keeper/keeper.go b/x/upgrade/keeper/keeper.go index ba789aeb7b..a5bed9e360 100644 --- a/x/upgrade/keeper/keeper.go +++ b/x/upgrade/keeper/keeper.go @@ -2,19 +2,30 @@ package keeper import ( "encoding/binary" + "encoding/json" "fmt" + "io/ioutil" + "os" + "path" + "path/filepath" "github.com/cosmos/cosmos-sdk/x/upgrade/types" "github.com/tendermint/tendermint/libs/log" + tmos "github.com/tendermint/tendermint/libs/os" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/store/prefix" + store "github.com/cosmos/cosmos-sdk/store/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) +// UpgradeInfoFileName file to store upgrade information +const UpgradeInfoFileName string = "upgrade-info.json" + type Keeper struct { + homePath string skipUpgradeHeights map[int64]bool storeKey sdk.StoreKey cdc codec.Marshaler @@ -22,8 +33,9 @@ type Keeper struct { } // NewKeeper constructs an upgrade Keeper -func NewKeeper(skipUpgradeHeights map[int64]bool, storeKey sdk.StoreKey, cdc codec.Marshaler) Keeper { +func NewKeeper(skipUpgradeHeights map[int64]bool, storeKey sdk.StoreKey, cdc codec.Marshaler, homePath string) Keeper { return Keeper{ + homePath: homePath, skipUpgradeHeights: skipUpgradeHeights, storeKey: storeKey, cdc: cdc, @@ -131,3 +143,59 @@ func (k Keeper) ApplyUpgrade(ctx sdk.Context, plan types.Plan) { func (k Keeper) IsSkipHeight(height int64) bool { return k.skipUpgradeHeights[height] } + +// DumpUpgradeInfoToDisk writes upgrade information to UpgradeInfoFileName. +func (k Keeper) DumpUpgradeInfoToDisk(height int64, name string) error { + upgradeInfoFilePath, err := k.GetUpgradeInfoPath() + if err != nil { + return err + } + + upgradeInfo := store.UpgradeInfo{ + Name: name, + Height: height, + } + info, err := json.Marshal(upgradeInfo) + if err != nil { + return err + } + + return ioutil.WriteFile(upgradeInfoFilePath, info, 0644) +} + +// GetUpgradeInfoPath returns the upgrade info file path +func (k Keeper) GetUpgradeInfoPath() (string, error) { + upgradeInfoFileDir := path.Join(k.getHomeDir(), "data") + err := tmos.EnsureDir(upgradeInfoFileDir, os.ModePerm) + if err != nil { + return "", err + } + + return filepath.Join(upgradeInfoFileDir, UpgradeInfoFileName), nil +} + +// getHomeDir returns the height at which the given upgrade was executed +func (k Keeper) getHomeDir() string { + return k.homePath +} + +// ReadUpgradeInfoFromDisk returns the name and height of the upgrade +// which is written to disk by the old binary when panic'ing +// if there's an error in reading the info, +// it assumes that the upgrade info is not available +func (k Keeper) ReadUpgradeInfoFromDisk() (upgradeInfo store.UpgradeInfo) { + upgradeInfoPath, err := k.GetUpgradeInfoPath() + // if error in reading the path, assume there are no upgrades + if err != nil { + return upgradeInfo + } + + data, err := ioutil.ReadFile(upgradeInfoPath) + // if error in reading the file, assume there are no upgrades + if err != nil { + return upgradeInfo + } + + json.Unmarshal(data, &upgradeInfo) + return +} diff --git a/x/upgrade/spec/01_concepts.md b/x/upgrade/spec/01_concepts.md index 19205591fc..54147f8b5e 100644 --- a/x/upgrade/spec/01_concepts.md +++ b/x/upgrade/spec/01_concepts.md @@ -56,6 +56,33 @@ During each `EndBlock` execution, the `x/upgrade` module checks if there exists `Handler` is executed. If the `Plan` is expected to execute but no `Handler` is registered or if the binary was upgraded too early, the node will gracefully panic and exit. +## StoreLoader + + +The `x/upgrade` module also facilitates store migrations as part of the upgrade. The +`StoreLoader` sets the migrations that need to occur before the new binary can +successfully run the chain. This `StoreLoader` is also application specific and +not defined on a per-module basis. Registering this `StoreLoader` is done via +`app#SetStoreLoader` in the application. + +```go +func UpgradeStoreLoader (upgradeHeight int64, storeUpgrades *store.StoreUpgrades) baseapp.StoreLoader +``` + +If there's a planned upgrade and the upgrade height is reached, the old binary writes `UpgradeInfo` to the disk before panic'ing. + +```go +type UpgradeInfo struct { + Name string + Height int64 +} +``` + +This information is critical to ensure the `StoreUpgrades` happens smoothly at correct height and +expected upgrade. It eliminiates the chances for the new binary to execute `StoreUpgrades` multiple +times everytime on restart. Also if there are multiple upgrades planned on same height, the `Name` +will ensure these `StoreUpgrades` takes place only in planned upgrade handler. + ## Proposal Typically, a `Plan` is proposed and submitted through governance via a `SoftwareUpgradeProposal`. diff --git a/x/upgrade/types/storeloader.go b/x/upgrade/types/storeloader.go new file mode 100644 index 0000000000..0ff168dcc3 --- /dev/null +++ b/x/upgrade/types/storeloader.go @@ -0,0 +1,23 @@ +package types + +import ( + "github.com/cosmos/cosmos-sdk/baseapp" + store "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// UpgradeStoreLoader is used to prepare baseapp with a fixed StoreLoader +// pattern. This is useful for custom upgrade loading logic. +func UpgradeStoreLoader(upgradeHeight int64, storeUpgrades *store.StoreUpgrades) baseapp.StoreLoader { + return func(ms sdk.CommitMultiStore) error { + if upgradeHeight == ms.LastCommitID().Version { + // Check if the current commit version and upgrade height matches + if len(storeUpgrades.Renamed) > 0 || len(storeUpgrades.Deleted) > 0 { + return ms.LoadLatestVersionAndUpgrade(storeUpgrades) + } + } + + // Otherwise load default store loader + return baseapp.DefaultStoreLoader(ms) + } +} diff --git a/x/upgrade/types/storeloader_test.go b/x/upgrade/types/storeloader_test.go new file mode 100644 index 0000000000..955ab07cdf --- /dev/null +++ b/x/upgrade/types/storeloader_test.go @@ -0,0 +1,144 @@ +package types + +import ( + "encoding/json" + "io/ioutil" + "os" + "path/filepath" + "testing" + + "github.com/spf13/viper" + "github.com/stretchr/testify/require" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/libs/log" + dbm "github.com/tendermint/tm-db" + + "github.com/cosmos/cosmos-sdk/baseapp" + "github.com/cosmos/cosmos-sdk/client/flags" + "github.com/cosmos/cosmos-sdk/store/rootmulti" + store "github.com/cosmos/cosmos-sdk/store/types" + "github.com/cosmos/cosmos-sdk/tests" + sdk "github.com/cosmos/cosmos-sdk/types" +) + +func useUpgradeLoader(height int64, upgrades *store.StoreUpgrades) func(*baseapp.BaseApp) { + return func(app *baseapp.BaseApp) { + app.SetStoreLoader(UpgradeStoreLoader(height, upgrades)) + } +} + +func defaultLogger() log.Logger { + return log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "sdk/app") +} + +func initStore(t *testing.T, db dbm.DB, storeKey string, k, v []byte) { + rs := rootmulti.NewStore(db) + rs.SetPruning(store.PruneNothing) + key := sdk.NewKVStoreKey(storeKey) + rs.MountStoreWithDB(key, store.StoreTypeIAVL, nil) + err := rs.LoadLatestVersion() + require.Nil(t, err) + require.Equal(t, int64(0), rs.LastCommitID().Version) + + // write some data in substore + kv, _ := rs.GetStore(key).(store.KVStore) + require.NotNil(t, kv) + kv.Set(k, v) + commitID := rs.Commit() + require.Equal(t, int64(1), commitID.Version) +} + +func checkStore(t *testing.T, db dbm.DB, ver int64, storeKey string, k, v []byte) { + rs := rootmulti.NewStore(db) + rs.SetPruning(store.PruneNothing) + key := sdk.NewKVStoreKey(storeKey) + rs.MountStoreWithDB(key, store.StoreTypeIAVL, nil) + err := rs.LoadLatestVersion() + require.Nil(t, err) + require.Equal(t, ver, rs.LastCommitID().Version) + + // query data in substore + kv, _ := rs.GetStore(key).(store.KVStore) + + require.NotNil(t, kv) + require.Equal(t, v, kv.Get(k)) +} + +// Test that we can make commits and then reload old versions. +// Test that LoadLatestVersion actually does. +func TestSetLoader(t *testing.T) { + // set a temporary home dir + homeDir, cleanUp := tests.NewTestCaseDir(t) + defer cleanUp() + // TODO cleanup viper + viper.Set(flags.FlagHome, homeDir) + + upgradeInfoFilePath := filepath.Join(homeDir, "upgrade-info.json") + upgradeInfo := &store.UpgradeInfo{ + Name: "test", Height: 0, + } + data, err := json.Marshal(upgradeInfo) + require.NoError(t, err) + err = ioutil.WriteFile(upgradeInfoFilePath, data, 0644) + require.NoError(t, err) + + // make sure it exists before running everything + _, err = os.Stat(upgradeInfoFilePath) + require.NoError(t, err) + + cases := map[string]struct { + setLoader func(*baseapp.BaseApp) + origStoreKey string + loadStoreKey string + }{ + "don't set loader": { + origStoreKey: "foo", + loadStoreKey: "foo", + }, + "rename with inline opts": { + setLoader: useUpgradeLoader(0, &store.StoreUpgrades{ + Renamed: []store.StoreRename{{ + OldKey: "foo", + NewKey: "bar", + }}, + }), + origStoreKey: "foo", + loadStoreKey: "bar", + }, + } + + k := []byte("key") + v := []byte("value") + + for name, tc := range cases { + tc := tc + t.Run(name, func(t *testing.T) { + // prepare a db with some data + db := dbm.NewMemDB() + + initStore(t, db, tc.origStoreKey, k, v) + + // load the app with the existing db + opts := []func(*baseapp.BaseApp){baseapp.SetPruning(store.PruneNothing)} + if tc.setLoader != nil { + opts = append(opts, tc.setLoader) + } + + app := baseapp.NewBaseApp(t.Name(), defaultLogger(), db, nil, opts...) + capKey := sdk.NewKVStoreKey(baseapp.MainStoreKey) + app.MountStores(capKey) + app.MountStores(sdk.NewKVStoreKey(tc.loadStoreKey)) + err := app.LoadLatestVersion(capKey) + require.Nil(t, err) + + // "execute" one block + app.BeginBlock(abci.RequestBeginBlock{Header: abci.Header{Height: 2}}) + res := app.Commit() + require.NotNil(t, res.Data) + + // check db is properly updated + checkStore(t, db, 2, tc.loadStoreKey, k, v) + checkStore(t, db, 2, tc.loadStoreKey, []byte("foo"), nil) + }) + } +} From 66f8e35b90286cc89eb26f98c0cd8f78f47bce8e Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Fri, 28 Feb 2020 12:26:11 +0000 Subject: [PATCH 090/101] Build with go1.14 (#5719) --- .circleci/config.yml | 2 +- CHANGELOG.md | 1 + README.md | 2 +- go.mod | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 04ec877e3f..15b9578e28 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,7 +3,7 @@ version: 2.1 executors: golang: docker: - - image: circleci/golang:1.13 + - image: circleci/golang:1.14 docs: docker: - image: tendermintdev/docker-website-deployment diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c3a38ae1e..138724a6cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,6 +46,7 @@ balances or a single balance by denom when the `denom` query parameter is presen ### API Breaking Changes +* [\#5719](https://github.com/cosmos/cosmos-sdk/pull/5719) Bump Go requirement to 1.14+ * (x/params) [\#5619](https://github.com/cosmos/cosmos-sdk/pull/5619) The `x/params` keeper now accepts a `codec.Marshaller` instead of a reference to an amino codec. Amino is still used for JSON serialization. * (types) [\#5579](https://github.com/cosmos/cosmos-sdk/pull/5579) The `keepRecent` field has been removed from the `PruningOptions` type. diff --git a/README.md b/README.md index d1ee3d585a..c783fc279e 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ It is being used to build [`Gaia`](https://github.com/cosmos/gaia), the first im **WARNING**: The SDK has mostly stabilized, but we are still making some breaking changes. -**Note**: Requires [Go 1.13+](https://golang.org/dl/) +**Note**: Requires [Go 1.14+](https://golang.org/dl/) ## Quick Start diff --git a/go.mod b/go.mod index d9debb5a73..1599418dc4 100644 --- a/go.mod +++ b/go.mod @@ -35,4 +35,4 @@ require ( replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.2-alpha.regen.1 -go 1.13 +go 1.14 From 1b78457135a4104bc3af97f20654d49e2ea87454 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Fri, 28 Feb 2020 13:19:00 +0000 Subject: [PATCH 091/101] Run go mod tidy (#5721) --- go.sum | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/go.sum b/go.sum index 7eeaf96559..5ad5221596 100644 --- a/go.sum +++ b/go.sum @@ -35,7 +35,6 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= @@ -45,7 +44,6 @@ github.com/cosmos/ledger-cosmos-go v0.11.1 h1:9JIYsGnXP613pb2vPjFeMMjBI5lEDsEaF6 github.com/cosmos/ledger-cosmos-go v0.11.1/go.mod h1:J8//BsAGTo3OC/vDLjMRFLW6q0WAaXvHnVc7ZmE8iUY= github.com/cosmos/ledger-go v0.9.2 h1:Nnao/dLwaVTk1Q5U9THldpUMMXU94BOTWPddSmVB6pI= github.com/cosmos/ledger-go v0.9.2/go.mod h1:oZJ2hHAZROdlHiwTg4t7kP+GKIIkBT+o6c9QWFanOyI= -github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/danieljoos/wincred v1.0.2 h1:zf4bhty2iLuwgjgpraD2E9UbvO+fe54XXGJbOwe23fU= github.com/danieljoos/wincred v1.0.2/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3EJbmjhLdK9U= @@ -196,8 +194,6 @@ github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084 h1:sofwID9zm4tzrgykg80hfFph1mryUeLRsUfoocVVmRY= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/rakyll/statik v0.1.6 h1:uICcfUXpgqtw2VopbIncslhAmE5hwc4g20TEyEENBNs= -github.com/rakyll/statik v0.1.6/go.mod h1:OEi9wJV/fMUAGx1eNjq75DKDsJVuEv1U0oYdX6GX8Zs= github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= github.com/rcrowley/go-metrics v0.0.0-20180503174638-e2704e165165 h1:nkcn14uNmFEuGCb2mBZbBb24RdNRL08b/wb+xBOYpuk= @@ -209,7 +205,6 @@ github.com/regen-network/protobuf v1.3.2-alpha.regen.1/go.mod h1:lye6mqhOn/GCw1z github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= @@ -226,8 +221,6 @@ github.com/spf13/afero v1.2.1/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTd github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.1/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v0.0.6 h1:breEStsVwemnKh2/s6gMvSdMEkwW0sK8vGStnlVBMCs= github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= @@ -236,7 +229,6 @@ github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0 github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= github.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k= github.com/spf13/viper v1.6.2 h1:7aKfF+e8/k68gda3LOjo5RxiUqddoFxVq4BKBPrxk5E= @@ -249,8 +241,6 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.0 h1:DMOzIV76tmoDNE9pX6RSN0aDtCYeCg5VueieJaAo1uw= -github.com/stretchr/testify v1.5.0/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= @@ -279,7 +269,6 @@ github.com/tendermint/tm-db v0.4.1 h1:TvX7JWjJOVZ+N3y+I86wddrGttOdMmmBxXcu0/Y7ZJ github.com/tendermint/tm-db v0.4.1/go.mod h1:JsJ6qzYkCGiGwm5GHl/H5GLI9XLb6qZX7PRe425dHAY= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/zondax/hid v0.9.0 h1:eiT3P6vNxAEVxXMw66eZUAAnU2zD33JBkfG/EnfAKl8= @@ -292,7 +281,6 @@ go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -327,7 +315,6 @@ golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= From a5fd4705edf66e3fc94c5d5d7a74f05fb41d0a76 Mon Sep 17 00:00:00 2001 From: Marko Date: Fri, 28 Feb 2020 18:36:26 +0100 Subject: [PATCH 092/101] Merge PR #5723: fix config file --- .mergify.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.mergify.yml b/.mergify.yml index f827f65542..6e153d510b 100644 --- a/.mergify.yml +++ b/.mergify.yml @@ -1,10 +1,10 @@ pull_request_rules: - - name: automatic merge for master when CI passes, has 1 review and has the label automerge + - name: automerge to master with label automerge and branch protection passing conditions: - "#approved-reviews-by>=1" - - "status-success=ci/circleci - Pull Request" - base=master - label=automerge actions: merge: method: squash + strict: true From 5c1c64bfae95e62dd71960465e54ce05552110a1 Mon Sep 17 00:00:00 2001 From: Alexander Bezobchuk Date: Fri, 28 Feb 2020 09:51:00 -0800 Subject: [PATCH 093/101] Merge PR #5718: Return Empty GasInfo on Failed Msg Validation --- CHANGELOG.md | 2 ++ baseapp/baseapp.go | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 138724a6cb..be120952fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,6 +67,8 @@ to now accept a `codec.JSONMarshaler` for modular serialization of genesis state ### Bug Fixes +* (baseapp) [\#5718](https://github.com/cosmos/cosmos-sdk/pull/5718) Remove call to `ctx.BlockGasMeter` during failed message validation which +resulted in a panic when the tx execution mode was `CheckTx`. * (client) [\#5618](https://github.com/cosmos/cosmos-sdk/pull/5618) Fix crash on the client when the verifier is not set. * (x/distribution) [\#5620](https://github.com/cosmos/cosmos-sdk/pull/5620) Fix nil pointer deref in distribution tax/rewward validation helpers. * (genesis) [\#5086](https://github.com/cosmos/cosmos-sdk/issues/5086) Ensure `gentxs` are always an empty array instead of `nil` diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 4fe7d0ba80..0373a199cf 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -521,8 +521,7 @@ func (app *BaseApp) runTx(mode runTxMode, txBytes []byte, tx sdk.Tx) (gInfo sdk. msgs := tx.GetMsgs() if err := validateBasicTxMsgs(msgs); err != nil { - gInfo = sdk.GasInfo{GasUsed: ctx.BlockGasMeter().GasConsumed()} - return gInfo, nil, err + return sdk.GasInfo{}, nil, err } if app.anteHandler != nil { From 256e5fc863b85f67b53acbf4391281fd3bee4ea6 Mon Sep 17 00:00:00 2001 From: Alexander Bezobchuk Date: Fri, 28 Feb 2020 09:58:55 -0800 Subject: [PATCH 094/101] 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 a653a16dc9..5bd478eb2d 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 095/101] 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 451065b3c2..b809e070ca 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 096/101] 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 5bd478eb2d..b4ef5dbe02 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 097/101] 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 b4ef5dbe02..4232e7e8d1 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 098/101] 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 4232e7e8d1..3838b26952 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 099/101] 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 3838b26952..a557e7f5d3 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 From d0941838954e0ce2d8c8849313da2cbdc3a7736d Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Fri, 28 Feb 2020 18:14:01 +0000 Subject: [PATCH 100/101] Increase code coverage of version up to 100% (#5726) --- version/command.go | 53 ++++++++++++++++++------------------ version/version_test.go | 60 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 26 deletions(-) create mode 100644 version/version_test.go diff --git a/version/command.go b/version/command.go index 9c3b0cfda2..80163db2d4 100644 --- a/version/command.go +++ b/version/command.go @@ -2,7 +2,6 @@ package version import ( "encoding/json" - "fmt" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -21,29 +20,31 @@ func init() { var Cmd = &cobra.Command{ Use: "version", Short: "Print the app version", - RunE: func(_ *cobra.Command, _ []string) error { - verInfo := NewInfo() - - if !viper.GetBool(flagLong) { - fmt.Println(verInfo.Version) - return nil - } - - var bz []byte - var err error - - switch viper.GetString(cli.OutputFlag) { - case "json": - bz, err = json.Marshal(verInfo) - default: - bz, err = yaml.Marshal(&verInfo) - } - - if err != nil { - return err - } - - _, err = fmt.Println(string(bz)) - return err - }, + RunE: runVersionCmd, +} + +func runVersionCmd(cmd *cobra.Command, args []string) error { + verInfo := NewInfo() + + if !viper.GetBool(flagLong) { + cmd.Println(verInfo.Version) + return nil + } + + var bz []byte + var err error + + switch viper.GetString(cli.OutputFlag) { + case "json": + bz, err = json.Marshal(verInfo) + default: + bz, err = yaml.Marshal(&verInfo) + } + + if err != nil { + return err + } + + cmd.Println(string(bz)) + return nil } diff --git a/version/version_test.go b/version/version_test.go new file mode 100644 index 0000000000..d125b99469 --- /dev/null +++ b/version/version_test.go @@ -0,0 +1,60 @@ +package version + +import ( + "encoding/json" + "fmt" + "runtime" + "testing" + + "github.com/spf13/viper" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/tendermint/tendermint/libs/cli" + + "github.com/cosmos/cosmos-sdk/tests" +) + +func TestNewInfo(t *testing.T) { + info := NewInfo() + want := fmt.Sprintf(`: +git commit: +build tags: +%s`, fmt.Sprintf("go version %s %s/%s", runtime.Version(), runtime.GOOS, runtime.GOARCH)) + require.Equal(t, want, info.String()) +} + +func TestInfo_String(t *testing.T) { + info := Info{ + Name: "testapp", + ServerName: "testappd", + ClientName: "testappcli", + Version: "1.0.0", + GitCommit: "1b78457135a4104bc3af97f20654d49e2ea87454", + BuildTags: "netgo,ledger", + GoVersion: "go version go1.14 linux/amd64", + } + want := fmt.Sprintf(`testapp: 1.0.0 +git commit: 1b78457135a4104bc3af97f20654d49e2ea87454 +build tags: netgo,ledger +go version go1.14 linux/amd64`) + require.Equal(t, want, info.String()) +} + +func Test_runVersionCmd(t *testing.T) { + require.NotNil(t, Cmd) + _, mockOut, _ := tests.ApplyMockIO(Cmd) + + viper.Set(cli.OutputFlag, "") + viper.Set(flagLong, false) + require.NoError(t, runVersionCmd(Cmd, nil)) + assert.Equal(t, "\n", mockOut.String()) + mockOut.Reset() + + viper.Set(cli.OutputFlag, "json") + viper.Set(flagLong, true) + info := NewInfo() + stringInfo, err := json.Marshal(info) + require.NoError(t, err) + require.NoError(t, runVersionCmd(Cmd, nil)) + assert.Equal(t, string(stringInfo)+"\n", mockOut.String()) +} From 7080949f4e3f79c21c445bc3eb3fac99820ca709 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Fri, 28 Feb 2020 18:27:42 +0000 Subject: [PATCH 101/101] Update CODEOWNERS as per @jaekwon's directives (#5728) --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index ca82ba88da..a5519d4ce5 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,4 +1,4 @@ # CODEOWNERS: https://help.github.com/articles/about-codeowners/ # Primary repo maintainers -* @alexanderbez @jackzampolin @alessio @fedekunze +* @alexanderbez @alessio @fedekunze @nylira @hschoenburg