From 133134ca520b6fd437f587ec682c63db9ba431af Mon Sep 17 00:00:00 2001 From: Jae Kwon Date: Mon, 10 Dec 2018 02:49:37 -0800 Subject: [PATCH] Use address instead of bond height / intratxcounter for deduplication (#3055) --- PENDING.md | 1 + cmd/gaia/app/export.go | 1 - x/slashing/keeper_test.go | 4 +- x/stake/genesis.go | 18 +--- x/stake/genesis_test.go | 2 - x/stake/handler.go | 3 - x/stake/keeper/delegation.go | 2 +- x/stake/keeper/delegation_test.go | 48 +++++----- x/stake/keeper/keeper.go | 21 ----- x/stake/keeper/key.go | 42 +++++++-- x/stake/keeper/key_test.go | 8 +- x/stake/keeper/slash_test.go | 3 +- x/stake/keeper/test_common.go | 38 ++++++-- x/stake/keeper/validator.go | 5 - x/stake/keeper/validator_test.go | 125 ++++++++++++------------- x/stake/querier/querier_test.go | 1 - x/stake/stake.go | 1 - x/stake/types/genesis.go | 1 - x/stake/types/validator.go | 146 ++++++++++++++---------------- 19 files changed, 227 insertions(+), 243 deletions(-) diff --git a/PENDING.md b/PENDING.md index 202205111f50..af6171e94274 100644 --- a/PENDING.md +++ b/PENDING.md @@ -18,6 +18,7 @@ BREAKING CHANGES * SDK - [auth] \#2952 Signatures are no longer serialized on chain with the account number and sequence number + - [stake] \#3055 Use address instead of bond height / intratxcounter for deduplication * Tendermint diff --git a/cmd/gaia/app/export.go b/cmd/gaia/app/export.go index 346830f90c9f..a2aa420874db 100644 --- a/cmd/gaia/app/export.go +++ b/cmd/gaia/app/export.go @@ -123,7 +123,6 @@ func (app *GaiaApp) prepForZeroHeightGenesis(ctx sdk.Context) { panic("expected validator, not found") } validator.BondHeight = 0 - validator.BondIntraTxCounter = counter validator.UnbondingHeight = 0 app.stakeKeeper.SetValidator(ctx, validator) counter++ diff --git a/x/slashing/keeper_test.go b/x/slashing/keeper_test.go index 6dc9ab8008a5..dd32ea3f8267 100644 --- a/x/slashing/keeper_test.go +++ b/x/slashing/keeper_test.go @@ -419,13 +419,13 @@ func TestValidatorDippingInAndOut(t *testing.T) { ctx = ctx.WithBlockHeight(height) // validator added back in - got = sh(ctx, newTestMsgDelegate(sdk.AccAddress(addrs[2]), addrs[0], sdk.NewInt(2))) + got = sh(ctx, newTestMsgDelegate(sdk.AccAddress(addrs[2]), addrs[0], sdk.NewInt(3))) require.True(t, got.IsOK()) validatorUpdates, _ = stake.EndBlocker(ctx, sk) require.Equal(t, 2, len(validatorUpdates)) validator, _ = sk.GetValidator(ctx, addr) require.Equal(t, sdk.Bonded, validator.Status) - newAmt = int64(102) + newAmt = int64(103) // validator misses a block keeper.handleValidatorSignature(ctx, val.Address(), newAmt, false) diff --git a/x/stake/genesis.go b/x/stake/genesis.go index 0a5e3e25f093..d4039003e9e4 100644 --- a/x/stake/genesis.go +++ b/x/stake/genesis.go @@ -11,11 +11,10 @@ import ( "github.com/cosmos/cosmos-sdk/x/stake/types" ) -// InitGenesis sets the pool and parameters for the provided keeper and -// initializes the IntraTxCounter. For each validator in data, it sets that -// validator in the keeper along with manually setting the indexes. In -// addition, it also sets any delegations found in data. Finally, it updates -// the bonded validators. +// InitGenesis sets the pool and parameters for the provided keeper. For each +// validator in data, it sets that validator in the keeper along with manually +// setting the indexes. In addition, it also sets any delegations found in +// data. Finally, it updates the bonded validators. // Returns final validator set after applying all declaration and delegations func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) (res []abci.ValidatorUpdate, err error) { @@ -26,14 +25,9 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) (res [ keeper.SetPool(ctx, data.Pool) keeper.SetParams(ctx, data.Params) - keeper.SetIntraTxCounter(ctx, data.IntraTxCounter) keeper.SetLastTotalPower(ctx, data.LastTotalPower) - for i, validator := range data.Validators { - // set the intra-tx counter to the order the validators are presented, if necessary - if !data.Exported { - validator.BondIntraTxCounter = int16(i) - } + for _, validator := range data.Validators { keeper.SetValidator(ctx, validator) // Manually set indices for the first time @@ -93,7 +87,6 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) (res [ func ExportGenesis(ctx sdk.Context, keeper Keeper) types.GenesisState { pool := keeper.GetPool(ctx) params := keeper.GetParams(ctx) - intraTxCounter := keeper.GetIntraTxCounter(ctx) lastTotalPower := keeper.GetLastTotalPower(ctx) validators := keeper.GetAllValidators(ctx) bonds := keeper.GetAllDelegations(ctx) @@ -116,7 +109,6 @@ func ExportGenesis(ctx sdk.Context, keeper Keeper) types.GenesisState { return types.GenesisState{ Pool: pool, Params: params, - IntraTxCounter: intraTxCounter, LastTotalPower: lastTotalPower, LastValidatorPowers: lastValidatorPowers, Validators: validators, diff --git a/x/stake/genesis_test.go b/x/stake/genesis_test.go index 3f7295a7a033..dfe5b7d1bed9 100644 --- a/x/stake/genesis_test.go +++ b/x/stake/genesis_test.go @@ -53,12 +53,10 @@ func TestInitGenesis(t *testing.T) { resVal, found := keeper.GetValidator(ctx, sdk.ValAddress(keep.Addrs[0])) require.True(t, found) require.Equal(t, sdk.Bonded, resVal.Status) - require.Equal(t, int16(0), resVal.BondIntraTxCounter) resVal, found = keeper.GetValidator(ctx, sdk.ValAddress(keep.Addrs[1])) require.True(t, found) require.Equal(t, sdk.Bonded, resVal.Status) - require.Equal(t, int16(1), resVal.BondIntraTxCounter) abcivals := make([]abci.ValidatorUpdate, len(vals)) for i, val := range validators { diff --git a/x/stake/handler.go b/x/stake/handler.go index 811fe7114684..f8792da786b5 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -35,9 +35,6 @@ func NewHandler(k keeper.Keeper) sdk.Handler { // Called every block, update validator set func EndBlocker(ctx sdk.Context, k keeper.Keeper) (validatorUpdates []abci.ValidatorUpdate, endBlockerTags sdk.Tags) { - // Reset the intra-transaction counter. - k.SetIntraTxCounter(ctx, 0) - // Calculate validator set changes. // // NOTE: ApplyAndReturnValidatorSetUpdates has to come before diff --git a/x/stake/keeper/delegation.go b/x/stake/keeper/delegation.go index 811b1562937c..2567f3dfbbc7 100644 --- a/x/stake/keeper/delegation.go +++ b/x/stake/keeper/delegation.go @@ -572,7 +572,7 @@ func (k Keeper) CompleteUnbonding(ctx sdk.Context, delAddr sdk.AccAddress, valAd return nil } -// complete unbonding an unbonding record +// begin unbonding / redelegation; create a redelegation record func (k Keeper) BeginRedelegation(ctx sdk.Context, delAddr sdk.AccAddress, valSrcAddr, valDstAddr sdk.ValAddress, sharesAmount sdk.Dec) (types.Redelegation, sdk.Error) { diff --git a/x/stake/keeper/delegation_test.go b/x/stake/keeper/delegation_test.go index 043f19193d1e..584db1ef6f85 100644 --- a/x/stake/keeper/delegation_test.go +++ b/x/stake/keeper/delegation_test.go @@ -26,9 +26,9 @@ func TestDelegation(t *testing.T) { } keeper.SetPool(ctx, pool) - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0]) - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1]) - validators[2] = TestingUpdateValidator(keeper, ctx, validators[2]) + validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], true) + validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], true) + validators[2] = TestingUpdateValidator(keeper, ctx, validators[2], true) // first add a validators[0] to delegate too @@ -188,7 +188,7 @@ func TestUnbondDelegation(t *testing.T) { validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = TestingUpdateValidator(keeper, ctx, validator) + validator = TestingUpdateValidator(keeper, ctx, validator, true) pool = keeper.GetPool(ctx) require.Equal(t, int64(10), pool.BondedTokens.RoundInt64()) @@ -230,7 +230,7 @@ func TestUndelegateSelfDelegation(t *testing.T) { validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = TestingUpdateValidator(keeper, ctx, validator) + validator = TestingUpdateValidator(keeper, ctx, validator, true) pool = keeper.GetPool(ctx) selfDelegation := types.Delegation{ DelegatorAddr: sdk.AccAddress(addrVals[0].Bytes()), @@ -244,7 +244,7 @@ func TestUndelegateSelfDelegation(t *testing.T) { validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = TestingUpdateValidator(keeper, ctx, validator) + validator = TestingUpdateValidator(keeper, ctx, validator, true) pool = keeper.GetPool(ctx) delegation := types.Delegation{ DelegatorAddr: addrDels[0], @@ -278,7 +278,7 @@ func TestUndelegateFromUnbondingValidator(t *testing.T) { validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = TestingUpdateValidator(keeper, ctx, validator) + validator = TestingUpdateValidator(keeper, ctx, validator, true) pool = keeper.GetPool(ctx) selfDelegation := types.Delegation{ DelegatorAddr: sdk.AccAddress(addrVals[0].Bytes()), @@ -292,7 +292,7 @@ func TestUndelegateFromUnbondingValidator(t *testing.T) { validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = TestingUpdateValidator(keeper, ctx, validator) + validator = TestingUpdateValidator(keeper, ctx, validator, true) pool = keeper.GetPool(ctx) delegation := types.Delegation{ DelegatorAddr: addrDels[0], @@ -354,7 +354,7 @@ func TestUndelegateFromUnbondedValidator(t *testing.T) { validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = TestingUpdateValidator(keeper, ctx, validator) + validator = TestingUpdateValidator(keeper, ctx, validator, true) pool = keeper.GetPool(ctx) val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) selfDelegation := types.Delegation{ @@ -369,7 +369,7 @@ func TestUndelegateFromUnbondedValidator(t *testing.T) { validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = TestingUpdateValidator(keeper, ctx, validator) + validator = TestingUpdateValidator(keeper, ctx, validator, true) pool = keeper.GetPool(ctx) delegation := types.Delegation{ DelegatorAddr: addrDels[0], @@ -433,7 +433,7 @@ func TestUnbondingAllDelegationFromValidator(t *testing.T) { validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = TestingUpdateValidator(keeper, ctx, validator) + validator = TestingUpdateValidator(keeper, ctx, validator, true) pool = keeper.GetPool(ctx) val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) selfDelegation := types.Delegation{ @@ -448,7 +448,7 @@ func TestUnbondingAllDelegationFromValidator(t *testing.T) { validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = TestingUpdateValidator(keeper, ctx, validator) + validator = TestingUpdateValidator(keeper, ctx, validator, true) pool = keeper.GetPool(ctx) delegation := types.Delegation{ DelegatorAddr: addrDels[0], @@ -595,7 +595,7 @@ func TestRedelegateToSameValidator(t *testing.T) { validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = TestingUpdateValidator(keeper, ctx, validator) + validator = TestingUpdateValidator(keeper, ctx, validator, true) pool = keeper.GetPool(ctx) val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) selfDelegation := types.Delegation{ @@ -621,7 +621,7 @@ func TestRedelegateSelfDelegation(t *testing.T) { validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = TestingUpdateValidator(keeper, ctx, validator) + validator = TestingUpdateValidator(keeper, ctx, validator, true) pool = keeper.GetPool(ctx) val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) selfDelegation := types.Delegation{ @@ -637,14 +637,14 @@ func TestRedelegateSelfDelegation(t *testing.T) { require.Equal(t, int64(10), issuedShares.RoundInt64()) pool.BondedTokens = pool.BondedTokens.Add(sdk.NewDec(10)) keeper.SetPool(ctx, pool) - validator2 = TestingUpdateValidator(keeper, ctx, validator2) + validator2 = TestingUpdateValidator(keeper, ctx, validator2, true) require.Equal(t, sdk.Bonded, validator2.Status) // create a second delegation to this validator validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = TestingUpdateValidator(keeper, ctx, validator) + validator = TestingUpdateValidator(keeper, ctx, validator, true) pool = keeper.GetPool(ctx) delegation := types.Delegation{ DelegatorAddr: addrDels[0], @@ -673,12 +673,11 @@ func TestRedelegateFromUnbondingValidator(t *testing.T) { //create a validator with a self-delegation validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) - validator.BondIntraTxCounter = 1 validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = TestingUpdateValidator(keeper, ctx, validator) + validator = TestingUpdateValidator(keeper, ctx, validator, true) pool = keeper.GetPool(ctx) val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) selfDelegation := types.Delegation{ @@ -693,7 +692,7 @@ func TestRedelegateFromUnbondingValidator(t *testing.T) { validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = TestingUpdateValidator(keeper, ctx, validator) + validator = TestingUpdateValidator(keeper, ctx, validator, true) pool = keeper.GetPool(ctx) delegation := types.Delegation{ DelegatorAddr: addrDels[0], @@ -704,11 +703,10 @@ func TestRedelegateFromUnbondingValidator(t *testing.T) { // create a second validator validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{}) - validator2.BondIntraTxCounter = 2 validator2, pool, issuedShares = validator2.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator2 = TestingUpdateValidator(keeper, ctx, validator2) + validator2 = TestingUpdateValidator(keeper, ctx, validator2, true) header := ctx.BlockHeader() blockHeight := int64(10) @@ -762,7 +760,7 @@ func TestRedelegateFromUnbondedValidator(t *testing.T) { validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = TestingUpdateValidator(keeper, ctx, validator) + validator = TestingUpdateValidator(keeper, ctx, validator, true) pool = keeper.GetPool(ctx) val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) selfDelegation := types.Delegation{ @@ -775,10 +773,9 @@ func TestRedelegateFromUnbondedValidator(t *testing.T) { // create a second delegation to this validator keeper.DeleteValidatorByPowerIndex(ctx, validator) validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10)) - validator.BondIntraTxCounter = 1 require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = TestingUpdateValidator(keeper, ctx, validator) + validator = TestingUpdateValidator(keeper, ctx, validator, true) pool = keeper.GetPool(ctx) delegation := types.Delegation{ DelegatorAddr: addrDels[0], @@ -789,11 +786,10 @@ func TestRedelegateFromUnbondedValidator(t *testing.T) { // create a second validator validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{}) - validator2.BondIntraTxCounter = 2 validator2, pool, issuedShares = validator2.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator2 = TestingUpdateValidator(keeper, ctx, validator2) + validator2 = TestingUpdateValidator(keeper, ctx, validator2, true) require.Equal(t, sdk.Bonded, validator2.Status) ctx = ctx.WithBlockHeight(10) diff --git a/x/stake/keeper/keeper.go b/x/stake/keeper/keeper.go index b6c973f98e05..a66daa1a554d 100644 --- a/x/stake/keeper/keeper.go +++ b/x/stake/keeper/keeper.go @@ -132,24 +132,3 @@ func (k Keeper) DeleteLastValidatorPower(ctx sdk.Context, operator sdk.ValAddres store := ctx.KVStore(k.storeKey) store.Delete(GetLastValidatorPowerKey(operator)) } - -//__________________________________________________________________________ - -// get the current in-block validator operation counter -func (k Keeper) GetIntraTxCounter(ctx sdk.Context) int16 { - store := ctx.KVStore(k.storeKey) - b := store.Get(IntraTxCounterKey) - if b == nil { - return 0 - } - var counter int16 - k.cdc.MustUnmarshalBinaryLengthPrefixed(b, &counter) - return counter -} - -// set the current in-block validator operation counter -func (k Keeper) SetIntraTxCounter(ctx sdk.Context, counter int16) { - store := ctx.KVStore(k.storeKey) - bz := k.cdc.MustMarshalBinaryLengthPrefixed(counter) - store.Set(IntraTxCounterKey, bz) -} diff --git a/x/stake/keeper/key.go b/x/stake/keeper/key.go index 34fa1a5b230f..ce1429052317 100644 --- a/x/stake/keeper/key.go +++ b/x/stake/keeper/key.go @@ -15,8 +15,7 @@ var ( // Keys for store prefixes // TODO DEPRECATED: delete in next release and reorder keys // ParamKey = []byte{0x00} // key for parameters relating to staking - PoolKey = []byte{0x01} // key for the staking pools - IntraTxCounterKey = []byte{0x02} // key for intra-block tx index + PoolKey = []byte{0x01} // key for the staking pools // Last* values are const during a block. LastValidatorPowerKey = []byte{0x11} // prefix for each key to a validator index, for bonded validators @@ -84,22 +83,34 @@ func getValidatorPowerRank(validator types.Validator) []byte { binary.BigEndian.PutUint64(tendermintPowerBytes[:], uint64(tendermintPower)) powerBytes := tendermintPowerBytes - powerBytesLen := len(powerBytes) + powerBytesLen := len(powerBytes) // 8 - // key is of format prefix || powerbytes || heightBytes || counterBytes - key := make([]byte, 1+powerBytesLen+8+2) + // key is of format prefix || powerbytes || addrBytes + key := make([]byte, 1+powerBytesLen+sdk.AddrLen) key[0] = ValidatorsByPowerIndexKey[0] copy(key[1:powerBytesLen+1], powerBytes) - - // include heightBytes height is inverted (older validators first) - binary.BigEndian.PutUint64(key[powerBytesLen+1:powerBytesLen+9], ^uint64(validator.BondHeight)) - // include counterBytes, counter is inverted (first txns have priority) - binary.BigEndian.PutUint16(key[powerBytesLen+9:powerBytesLen+11], ^uint16(validator.BondIntraTxCounter)) + operAddrInvr := cp(validator.OperatorAddr) + for i, b := range operAddrInvr { + operAddrInvr[i] = ^b + } + copy(key[powerBytesLen+1:], operAddrInvr) return key } +func parseValidatorPowerRankKey(key []byte) (operAddr []byte) { + powerBytesLen := 8 + if len(key) != 1+powerBytesLen+sdk.AddrLen { + panic("Invalid validator power rank key length") + } + operAddr = cp(key[powerBytesLen+1:]) + for i, b := range operAddr { + operAddr[i] = ^b + } + return operAddr +} + // gets the prefix for all unbonding delegations from a delegator func GetValidatorQueueTimeKey(timestamp time.Time) []byte { bz := sdk.FormatTimeBytes(timestamp) @@ -262,3 +273,14 @@ func GetREDsByDelToValDstIndexKey(delAddr sdk.AccAddress, valDstAddr sdk.ValAddr GetREDsToValDstIndexKey(valDstAddr), delAddr.Bytes()...) } + +//------------------------------------------------- + +func cp(bz []byte) (ret []byte) { + if bz == nil { + return nil + } + ret = make([]byte, len(bz)) + copy(ret, bz) + return ret +} diff --git a/x/stake/keeper/key_test.go b/x/stake/keeper/key_test.go index 385f313c15b5..0658e4b244c5 100644 --- a/x/stake/keeper/key_test.go +++ b/x/stake/keeper/key_test.go @@ -35,10 +35,10 @@ func TestGetValidatorPowerRank(t *testing.T) { validator types.Validator wantHex string }{ - {val1, "230000000000000000ffffffffffffffffffff"}, - {val2, "230000000000000001ffffffffffffffffffff"}, - {val3, "23000000000000000affffffffffffffffffff"}, - {val4, "230000010000000000ffffffffffffffffffff"}, + {val1, "2300000000000000009c288ede7df62742fc3b7d0962045a8cef0f79f6"}, + {val2, "2300000000000000019c288ede7df62742fc3b7d0962045a8cef0f79f6"}, + {val3, "23000000000000000a9c288ede7df62742fc3b7d0962045a8cef0f79f6"}, + {val4, "2300000100000000009c288ede7df62742fc3b7d0962045a8cef0f79f6"}, } for i, tt := range tests { got := hex.EncodeToString(getValidatorPowerRank(tt.validator)) diff --git a/x/stake/keeper/slash_test.go b/x/stake/keeper/slash_test.go index 9c23576c34ca..9f89dd210864 100644 --- a/x/stake/keeper/slash_test.go +++ b/x/stake/keeper/slash_test.go @@ -26,10 +26,9 @@ func setupHelper(t *testing.T, amt int64) (sdk.Context, Keeper, types.Params) { for i := 0; i < numVals; i++ { validator := types.NewValidator(addrVals[i], PKs[i], types.Description{}) validator, pool, _ = validator.AddTokensFromDel(pool, sdk.NewInt(amt)) - validator.BondIntraTxCounter = int16(i) pool.BondedTokens = pool.BondedTokens.Add(sdk.NewDec(amt)) keeper.SetPool(ctx, pool) - validator = TestingUpdateValidator(keeper, ctx, validator) + validator = TestingUpdateValidator(keeper, ctx, validator, true) keeper.SetValidatorByConsAddr(ctx, validator) } pool = keeper.GetPool(ctx) diff --git a/x/stake/keeper/test_common.go b/x/stake/keeper/test_common.go index 244a8107fa3e..f52b41c44420 100644 --- a/x/stake/keeper/test_common.go +++ b/x/stake/keeper/test_common.go @@ -201,15 +201,41 @@ func ValidatorByPowerIndexExists(ctx sdk.Context, keeper Keeper, power []byte) b } // update validator for testing -func TestingUpdateValidator(keeper Keeper, ctx sdk.Context, validator types.Validator) types.Validator { +func TestingUpdateValidator(keeper Keeper, ctx sdk.Context, validator types.Validator, apply bool) types.Validator { keeper.SetValidator(ctx, validator) + { // Remove any existing power key for validator. + store := ctx.KVStore(keeper.storeKey) + iterator := sdk.KVStorePrefixIterator(store, ValidatorsByPowerIndexKey) + deleted := false + for ; iterator.Valid(); iterator.Next() { + valAddr := parseValidatorPowerRankKey(iterator.Key()) + if bytes.Equal(valAddr, validator.OperatorAddr) { + if deleted { + panic("found duplicate power index key") + } else { + deleted = true + } + store.Delete(iterator.Key()) + } + } + } keeper.SetValidatorByPowerIndex(ctx, validator) - keeper.ApplyAndReturnValidatorSetUpdates(ctx) - validator, found := keeper.GetValidator(ctx, validator.OperatorAddr) - if !found { - panic("validator expected but not found") + if apply { + keeper.ApplyAndReturnValidatorSetUpdates(ctx) + validator, found := keeper.GetValidator(ctx, validator.OperatorAddr) + if !found { + panic("validator expected but not found") + } + return validator + } else { + cachectx, _ := ctx.CacheContext() + keeper.ApplyAndReturnValidatorSetUpdates(cachectx) + validator, found := keeper.GetValidator(cachectx, validator.OperatorAddr) + if !found { + panic("validator expected but not found") + } + return validator } - return validator } func validatorByPowerIndexExists(k Keeper, ctx sdk.Context, power []byte) bool { diff --git a/x/stake/keeper/validator.go b/x/stake/keeper/validator.go index 2d71ec513aac..8ec062605590 100644 --- a/x/stake/keeper/validator.go +++ b/x/stake/keeper/validator.go @@ -129,11 +129,6 @@ func (k Keeper) AddValidatorTokensAndShares(ctx sdk.Context, validator types.Val k.DeleteValidatorByPowerIndex(ctx, validator) pool := k.GetPool(ctx) validator, pool, addedShares = validator.AddTokensFromDel(pool, tokensToAdd) - // increment the intra-tx counter - // in case of a conflict, the validator which least recently changed power takes precedence - counter := k.GetIntraTxCounter(ctx) - validator.BondIntraTxCounter = counter - k.SetIntraTxCounter(ctx, counter+1) k.SetValidator(ctx, validator) k.SetPool(ctx, pool) k.SetValidatorByPowerIndex(ctx, validator) diff --git a/x/stake/keeper/validator_test.go b/x/stake/keeper/validator_test.go index ed89f0edf47b..71b0edcd1d06 100644 --- a/x/stake/keeper/validator_test.go +++ b/x/stake/keeper/validator_test.go @@ -84,7 +84,7 @@ func TestUpdateValidatorByPowerIndex(t *testing.T) { require.Equal(t, sdk.Unbonded, validator.Status) require.Equal(t, int64(100), validator.Tokens.RoundInt64()) keeper.SetPool(ctx, pool) - TestingUpdateValidator(keeper, ctx, validator) + TestingUpdateValidator(keeper, ctx, validator, true) validator, found := keeper.GetValidator(ctx, addrVals[0]) require.True(t, found) require.Equal(t, int64(100), validator.Tokens.RoundInt64(), "\nvalidator %v\npool %v", validator, pool) @@ -97,8 +97,8 @@ func TestUpdateValidatorByPowerIndex(t *testing.T) { keeper.DeleteValidatorByPowerIndex(ctx, validator) validator, pool, burned := validator.RemoveDelShares(pool, delSharesCreated.Quo(sdk.NewDec(2))) require.Equal(t, int64(50), burned.RoundInt64()) - keeper.SetPool(ctx, pool) // update the pool - TestingUpdateValidator(keeper, ctx, validator) // update the validator, possibly kicking it out + keeper.SetPool(ctx, pool) // update the pool + TestingUpdateValidator(keeper, ctx, validator, true) // update the validator, possibly kicking it out require.False(t, validatorByPowerIndexExists(keeper, ctx, power)) pool = keeper.GetPool(ctx) @@ -131,11 +131,10 @@ func TestUpdateBondedValidatorsDecreaseCliff(t *testing.T) { moniker := fmt.Sprintf("val#%d", int64(i)) val := types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{Moniker: moniker}) val.BondHeight = int64(i) - val.BondIntraTxCounter = int16(i) val, pool, _ = val.AddTokensFromDel(pool, sdk.NewInt(int64((i+1)*10))) keeper.SetPool(ctx, pool) - val = TestingUpdateValidator(keeper, ctx, val) + val = TestingUpdateValidator(keeper, ctx, val, true) validators[i] = val } @@ -146,7 +145,7 @@ func TestUpdateBondedValidatorsDecreaseCliff(t *testing.T) { keeper.DeleteValidatorByPowerIndex(ctx, nextCliffVal) nextCliffVal, pool, _ = nextCliffVal.RemoveDelShares(pool, sdk.NewDec(21)) keeper.SetPool(ctx, pool) - nextCliffVal = TestingUpdateValidator(keeper, ctx, nextCliffVal) + 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, @@ -178,7 +177,7 @@ func TestSlashToZeroPowerRemoved(t *testing.T) { require.Equal(t, int64(100), validator.Tokens.RoundInt64()) keeper.SetPool(ctx, pool) keeper.SetValidatorByConsAddr(ctx, validator) - validator = TestingUpdateValidator(keeper, ctx, validator) + validator = TestingUpdateValidator(keeper, ctx, validator, true) require.Equal(t, int64(100), validator.Tokens.RoundInt64(), "\nvalidator %v\npool %v", validator, pool) // slash the validator by 100% @@ -223,7 +222,7 @@ func TestValidatorBasics(t *testing.T) { assert.True(sdk.DecEq(t, sdk.ZeroDec(), pool.BondedTokens)) // set and retrieve a record - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0]) + validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], true) keeper.SetValidatorByConsAddr(ctx, validators[0]) resVal, found := keeper.GetValidator(ctx, addrVals[0]) require.True(t, found) @@ -250,7 +249,7 @@ func TestValidatorBasics(t *testing.T) { validators[0].Status = sdk.Bonded validators[0].Tokens = sdk.NewDec(10) validators[0].DelegatorShares = sdk.NewDec(10) - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0]) + 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)) @@ -260,8 +259,8 @@ func TestValidatorBasics(t *testing.T) { assert.True(ValEq(t, validators[0], resVals[0])) // add other validators - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1]) - validators[2] = TestingUpdateValidator(keeper, ctx, validators[2]) + 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)) @@ -296,7 +295,7 @@ func GetValidatorSortingUnmixed(t *testing.T) { validators[i].Status = sdk.Bonded validators[i].Tokens = sdk.NewDec(amt) validators[i].DelegatorShares = sdk.NewDec(amt) - TestingUpdateValidator(keeper, ctx, validators[i]) + TestingUpdateValidator(keeper, ctx, validators[i], true) } // first make sure everything made it in to the gotValidator group @@ -315,14 +314,14 @@ func GetValidatorSortingUnmixed(t *testing.T) { // test a basic increase in voting power validators[3].Tokens = sdk.NewDec(500) - TestingUpdateValidator(keeper, ctx, validators[3]) + 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.NewDec(300) - TestingUpdateValidator(keeper, ctx, validators[3]) + TestingUpdateValidator(keeper, ctx, validators[3], true) resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, len(resValidators), n) assert.True(ValEq(t, validators[3], resValidators[0])) @@ -331,7 +330,7 @@ func GetValidatorSortingUnmixed(t *testing.T) { // test equal voting power, different age validators[3].Tokens = sdk.NewDec(200) ctx = ctx.WithBlockHeight(10) - TestingUpdateValidator(keeper, ctx, validators[3]) + TestingUpdateValidator(keeper, ctx, validators[3], true) resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, len(resValidators), n) assert.True(ValEq(t, validators[3], resValidators[0])) @@ -341,7 +340,7 @@ func GetValidatorSortingUnmixed(t *testing.T) { // no change in voting power - no change in sort ctx = ctx.WithBlockHeight(20) - TestingUpdateValidator(keeper, ctx, validators[4]) + TestingUpdateValidator(keeper, ctx, validators[4], true) resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, len(resValidators), n) assert.True(ValEq(t, validators[3], resValidators[0])) @@ -350,11 +349,11 @@ func GetValidatorSortingUnmixed(t *testing.T) { // change in voting power of both validators, both still in v-set, no age change validators[3].Tokens = sdk.NewDec(300) validators[4].Tokens = sdk.NewDec(300) - TestingUpdateValidator(keeper, ctx, validators[3]) + 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]) + 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])) @@ -392,7 +391,7 @@ func GetValidatorSortingMixed(t *testing.T) { validators[4].Tokens = sdk.NewDec(amts[4]) for i := range amts { - TestingUpdateValidator(keeper, ctx, validators[i]) + TestingUpdateValidator(keeper, ctx, validators[i], true) } val0, found := keeper.GetValidator(ctx, sdk.ValAddress(Addrs[0])) require.True(t, found) @@ -444,9 +443,8 @@ func TestGetValidatorsEdgeCases(t *testing.T) { moniker := fmt.Sprintf("val#%d", int64(i)) validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{Moniker: moniker}) validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) - validators[i].BondIntraTxCounter = int16(i) keeper.SetPool(ctx, pool) - validators[i] = TestingUpdateValidator(keeper, ctx, validators[i]) + validators[i] = TestingUpdateValidator(keeper, ctx, validators[i], true) } for i := range amts { @@ -462,7 +460,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) { keeper.DeleteValidatorByPowerIndex(ctx, validators[0]) validators[0], pool, _ = validators[0].AddTokensFromDel(pool, sdk.NewInt(500)) keeper.SetPool(ctx, pool) - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0]) + validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], true) resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, nMax, uint16(len(resValidators))) assert.True(ValEq(t, validators[0], resValidators[0])) @@ -480,7 +478,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) { keeper.DeleteValidatorByPowerIndex(ctx, validators[3]) validators[3], pool, _ = validators[3].AddTokensFromDel(pool, sdk.NewInt(1)) keeper.SetPool(ctx, pool) - validators[3] = TestingUpdateValidator(keeper, ctx, validators[3]) + validators[3] = TestingUpdateValidator(keeper, ctx, validators[3], true) resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, nMax, uint16(len(resValidators))) assert.True(ValEq(t, validators[0], resValidators[0])) @@ -490,7 +488,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) { keeper.DeleteValidatorByPowerIndex(ctx, validators[3]) validators[3], pool, _ = validators[3].RemoveDelShares(pool, sdk.NewDec(201)) keeper.SetPool(ctx, pool) - validators[3] = TestingUpdateValidator(keeper, ctx, validators[3]) + validators[3] = TestingUpdateValidator(keeper, ctx, validators[3], true) resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, nMax, uint16(len(resValidators))) assert.True(ValEq(t, validators[0], resValidators[0])) @@ -500,7 +498,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) { keeper.DeleteValidatorByPowerIndex(ctx, validators[3]) validators[3], pool, _ = validators[3].AddTokensFromDel(pool, sdk.NewInt(200)) keeper.SetPool(ctx, pool) - validators[3] = TestingUpdateValidator(keeper, ctx, validators[3]) + validators[3] = TestingUpdateValidator(keeper, ctx, validators[3], true) resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, nMax, uint16(len(resValidators))) assert.True(ValEq(t, validators[0], resValidators[0])) @@ -524,22 +522,19 @@ func TestValidatorBondHeight(t *testing.T) { validators[0] = types.NewValidator(sdk.ValAddress(Addrs[0]), 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{}) - validators[0].BondIntraTxCounter = 0 - validators[1].BondIntraTxCounter = 1 - validators[2].BondIntraTxCounter = 2 validators[0], pool, _ = validators[0].AddTokensFromDel(pool, sdk.NewInt(200)) validators[1], pool, _ = validators[1].AddTokensFromDel(pool, sdk.NewInt(100)) validators[2], pool, _ = validators[2].AddTokensFromDel(pool, sdk.NewInt(100)) keeper.SetPool(ctx, pool) - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0]) + 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]) - validators[2] = TestingUpdateValidator(keeper, ctx, validators[2]) + validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], true) + validators[2] = TestingUpdateValidator(keeper, ctx, validators[2], true) pool = keeper.GetPool(ctx) @@ -553,10 +548,10 @@ func TestValidatorBondHeight(t *testing.T) { validators[1], pool, _ = validators[1].AddTokensFromDel(pool, sdk.NewInt(50)) validators[2], pool, _ = validators[2].AddTokensFromDel(pool, sdk.NewInt(50)) keeper.SetPool(ctx, pool) - validators[2] = TestingUpdateValidator(keeper, ctx, validators[2]) + validators[2] = TestingUpdateValidator(keeper, ctx, validators[2], true) resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, params.MaxValidators, uint16(len(resValidators))) - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1]) + validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], true) assert.True(ValEq(t, validators[0], resValidators[0])) assert.True(ValEq(t, validators[2], resValidators[1])) } @@ -575,9 +570,8 @@ func TestFullValidatorSetPowerChange(t *testing.T) { pool := keeper.GetPool(ctx) validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) - validators[i].BondIntraTxCounter = int16(i) keeper.SetPool(ctx, pool) - TestingUpdateValidator(keeper, ctx, validators[i]) + TestingUpdateValidator(keeper, ctx, validators[i], true) } for i := range amts { var found bool @@ -598,7 +592,7 @@ func TestFullValidatorSetPowerChange(t *testing.T) { pool := keeper.GetPool(ctx) validators[0], pool, _ = validators[0].AddTokensFromDel(pool, sdk.NewInt(600)) keeper.SetPool(ctx, pool) - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0]) + 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])) @@ -648,14 +642,14 @@ func TestApplyAndReturnValidatorSetUpdatesIdentical(t *testing.T) { validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) keeper.SetPool(ctx, pool) } - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0]) - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1]) - require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) + 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]) - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1]) + validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false) + validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], false) require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) } @@ -670,15 +664,15 @@ func TestApplyAndReturnValidatorSetUpdatesSingleValueChange(t *testing.T) { validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) keeper.SetPool(ctx, pool) } - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0]) - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1]) - require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) + 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.NewDec(600) - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0]) + validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false) updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) @@ -697,9 +691,9 @@ func TestApplyAndReturnValidatorSetUpdatesMultipleValueChange(t *testing.T) { validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) keeper.SetPool(ctx, pool) } - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0]) - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1]) - require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) + 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'} @@ -707,13 +701,13 @@ func TestApplyAndReturnValidatorSetUpdatesMultipleValueChange(t *testing.T) { validators[0], pool, _ = validators[0].AddTokensFromDel(pool, sdk.NewInt(190)) validators[1], pool, _ = validators[1].AddTokensFromDel(pool, sdk.NewInt(80)) keeper.SetPool(ctx, pool) - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0]) - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1]) + 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[1]) - require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[0]) + require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) + require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) } func TestApplyAndReturnValidatorSetUpdatesInserted(t *testing.T) { @@ -727,9 +721,9 @@ func TestApplyAndReturnValidatorSetUpdatesInserted(t *testing.T) { validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) keeper.SetPool(ctx, pool) } - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0]) - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1]) - require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) + 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} @@ -773,13 +767,13 @@ func TestApplyAndReturnValidatorSetUpdatesWithCliffValidator(t *testing.T) { validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) keeper.SetPool(ctx, pool) } - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0]) - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1]) - require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) + 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]) + TestingUpdateValidator(keeper, ctx, validators[2], false) updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 0, len(updates)) @@ -808,12 +802,11 @@ func TestApplyAndReturnValidatorSetUpdatesPowerDecrease(t *testing.T) { pool := keeper.GetPool(ctx) validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) - validators[i].BondIntraTxCounter = int16(i) keeper.SetPool(ctx, pool) } - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0]) - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1]) - require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) + 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, sdk.NewDec(100).RoundInt64(), validators[0].GetPower().RoundInt64()) @@ -825,8 +818,8 @@ func TestApplyAndReturnValidatorSetUpdatesPowerDecrease(t *testing.T) { validators[0], pool, _ = validators[0].RemoveDelShares(pool, sdk.NewDec(20)) validators[1], pool, _ = validators[1].RemoveDelShares(pool, sdk.NewDec(30)) keeper.SetPool(ctx, pool) - validators[0] = TestingUpdateValidator(keeper, ctx, validators[0]) - validators[1] = TestingUpdateValidator(keeper, ctx, validators[1]) + validators[0] = TestingUpdateValidator(keeper, ctx, validators[0], false) + validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], false) // power has changed require.Equal(t, sdk.NewDec(80).RoundInt64(), validators[0].GetPower().RoundInt64()) @@ -856,7 +849,6 @@ func TestApplyAndReturnValidatorSetUpdatesNewValidator(t *testing.T) { valAddr := sdk.ValAddress(valPubKey.Address().Bytes()) validators[i] = types.NewValidator(valAddr, valPubKey, types.Description{}) - validators[i].BondIntraTxCounter = int16(i) validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) keeper.SetPool(ctx, pool) @@ -942,7 +934,6 @@ func TestApplyAndReturnValidatorSetUpdatesBondTransition(t *testing.T) { validators[i] = types.NewValidator(valAddr, valPubKey, types.Description{Moniker: moniker}) validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) - validators[i].BondIntraTxCounter = int16(i) keeper.SetPool(ctx, pool) keeper.SetValidator(ctx, validators[i]) keeper.SetValidatorByPowerIndex(ctx, validators[i]) diff --git a/x/stake/querier/querier_test.go b/x/stake/querier/querier_test.go index d6ea3639e661..c13a378973c4 100644 --- a/x/stake/querier/querier_test.go +++ b/x/stake/querier/querier_test.go @@ -27,7 +27,6 @@ func TestNewQuerier(t *testing.T) { for i, amt := range amts { validators[i] = types.NewValidator(sdk.ValAddress(keep.Addrs[i]), keep.PKs[i], types.Description{}) validators[i], pool, _ = validators[i].AddTokensFromDel(pool, amt) - validators[i].BondIntraTxCounter = int16(i) keeper.SetValidator(ctx, validators[i]) keeper.SetValidatorByPowerIndex(ctx, validators[i]) } diff --git a/x/stake/stake.go b/x/stake/stake.go index 2e5b8feb7060..f5a029a728d2 100644 --- a/x/stake/stake.go +++ b/x/stake/stake.go @@ -38,7 +38,6 @@ var ( GetDelegationKey = keeper.GetDelegationKey GetDelegationsKey = keeper.GetDelegationsKey PoolKey = keeper.PoolKey - IntraTxCounterKey = keeper.IntraTxCounterKey LastValidatorPowerKey = keeper.LastValidatorPowerKey LastTotalPowerKey = keeper.LastTotalPowerKey ValidatorsKey = keeper.ValidatorsKey diff --git a/x/stake/types/genesis.go b/x/stake/types/genesis.go index 1085e8f97087..12c73278137b 100644 --- a/x/stake/types/genesis.go +++ b/x/stake/types/genesis.go @@ -8,7 +8,6 @@ import ( type GenesisState struct { Pool Pool `json:"pool"` Params Params `json:"params"` - IntraTxCounter int16 `json:"intra_tx_counter"` LastTotalPower sdk.Int `json:"last_total_power"` LastValidatorPowers []LastValidatorPower `json:"last_validator_powers"` Validators []Validator `json:"validators"` diff --git a/x/stake/types/validator.go b/x/stake/types/validator.go index 90558dd96d2d..517671c3a2a1 100644 --- a/x/stake/types/validator.go +++ b/x/stake/types/validator.go @@ -29,9 +29,8 @@ type Validator struct { Tokens sdk.Dec `json:"tokens"` // delegated tokens (incl. self-delegation) DelegatorShares sdk.Dec `json:"delegator_shares"` // total shares issued to a validator's delegators - Description Description `json:"description"` // description terms for the validator - BondHeight int64 `json:"bond_height"` // earliest height as a bonded validator - BondIntraTxCounter int16 `json:"bond_intra_tx_counter"` // block-local tx index of validator change + Description Description `json:"description"` // description terms for the validator + BondHeight int64 `json:"bond_height"` // earliest height as a bonded validator UnbondingHeight int64 `json:"unbonding_height"` // if unbonding, height at which this validator has begun unbonding UnbondingMinTime time.Time `json:"unbonding_time"` // if unbonding, min time for the validator to complete unbonding @@ -42,50 +41,47 @@ type Validator struct { // NewValidator - initialize a new validator func NewValidator(operator sdk.ValAddress, pubKey crypto.PubKey, description Description) Validator { return Validator{ - OperatorAddr: operator, - ConsPubKey: pubKey, - Jailed: false, - Status: sdk.Unbonded, - Tokens: sdk.ZeroDec(), - DelegatorShares: sdk.ZeroDec(), - Description: description, - BondHeight: int64(0), - BondIntraTxCounter: int16(0), - UnbondingHeight: int64(0), - UnbondingMinTime: time.Unix(0, 0).UTC(), - Commission: NewCommission(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()), + OperatorAddr: operator, + ConsPubKey: pubKey, + Jailed: false, + Status: sdk.Unbonded, + Tokens: sdk.ZeroDec(), + DelegatorShares: sdk.ZeroDec(), + Description: description, + BondHeight: int64(0), + UnbondingHeight: int64(0), + UnbondingMinTime: time.Unix(0, 0).UTC(), + Commission: NewCommission(sdk.ZeroDec(), sdk.ZeroDec(), sdk.ZeroDec()), } } // what's kept in the store value type validatorValue struct { - ConsPubKey crypto.PubKey - Jailed bool - Status sdk.BondStatus - Tokens sdk.Dec - DelegatorShares sdk.Dec - Description Description - BondHeight int64 - BondIntraTxCounter int16 - UnbondingHeight int64 - UnbondingMinTime time.Time - Commission Commission + ConsPubKey crypto.PubKey + Jailed bool + Status sdk.BondStatus + Tokens sdk.Dec + DelegatorShares sdk.Dec + Description Description + BondHeight int64 + UnbondingHeight int64 + UnbondingMinTime time.Time + Commission Commission } // return the redelegation without fields contained within the key for the store func MustMarshalValidator(cdc *codec.Codec, validator Validator) []byte { val := validatorValue{ - ConsPubKey: validator.ConsPubKey, - Jailed: validator.Jailed, - Status: validator.Status, - Tokens: validator.Tokens, - DelegatorShares: validator.DelegatorShares, - Description: validator.Description, - BondHeight: validator.BondHeight, - BondIntraTxCounter: validator.BondIntraTxCounter, - UnbondingHeight: validator.UnbondingHeight, - UnbondingMinTime: validator.UnbondingMinTime, - Commission: validator.Commission, + ConsPubKey: validator.ConsPubKey, + Jailed: validator.Jailed, + Status: validator.Status, + Tokens: validator.Tokens, + DelegatorShares: validator.DelegatorShares, + Description: validator.Description, + BondHeight: validator.BondHeight, + UnbondingHeight: validator.UnbondingHeight, + UnbondingMinTime: validator.UnbondingMinTime, + Commission: validator.Commission, } return cdc.MustMarshalBinaryLengthPrefixed(val) } @@ -112,18 +108,17 @@ func UnmarshalValidator(cdc *codec.Codec, operatorAddr, value []byte) (validator } return Validator{ - OperatorAddr: operatorAddr, - ConsPubKey: storeValue.ConsPubKey, - Jailed: storeValue.Jailed, - Tokens: storeValue.Tokens, - Status: storeValue.Status, - DelegatorShares: storeValue.DelegatorShares, - Description: storeValue.Description, - BondHeight: storeValue.BondHeight, - BondIntraTxCounter: storeValue.BondIntraTxCounter, - UnbondingHeight: storeValue.UnbondingHeight, - UnbondingMinTime: storeValue.UnbondingMinTime, - Commission: storeValue.Commission, + OperatorAddr: operatorAddr, + ConsPubKey: storeValue.ConsPubKey, + Jailed: storeValue.Jailed, + Tokens: storeValue.Tokens, + Status: storeValue.Status, + DelegatorShares: storeValue.DelegatorShares, + Description: storeValue.Description, + BondHeight: storeValue.BondHeight, + UnbondingHeight: storeValue.UnbondingHeight, + UnbondingMinTime: storeValue.UnbondingMinTime, + Commission: storeValue.Commission, }, nil } @@ -164,9 +159,8 @@ type bechValidator struct { Tokens sdk.Dec `json:"tokens"` // delegated tokens (incl. self-delegation) DelegatorShares sdk.Dec `json:"delegator_shares"` // total shares issued to a validator's delegators - Description Description `json:"description"` // description terms for the validator - BondHeight int64 `json:"bond_height"` // earliest height as a bonded validator - BondIntraTxCounter int16 `json:"bond_intra_tx_counter"` // block-local tx index of validator change + Description Description `json:"description"` // description terms for the validator + BondHeight int64 `json:"bond_height"` // earliest height as a bonded validator UnbondingHeight int64 `json:"unbonding_height"` // if unbonding, height at which this validator has begun unbonding UnbondingMinTime time.Time `json:"unbonding_time"` // if unbonding, min time for the validator to complete unbonding @@ -182,18 +176,17 @@ func (v Validator) MarshalJSON() ([]byte, error) { } return codec.Cdc.MarshalJSON(bechValidator{ - OperatorAddr: v.OperatorAddr, - ConsPubKey: bechConsPubKey, - Jailed: v.Jailed, - Status: v.Status, - Tokens: v.Tokens, - DelegatorShares: v.DelegatorShares, - Description: v.Description, - BondHeight: v.BondHeight, - BondIntraTxCounter: v.BondIntraTxCounter, - UnbondingHeight: v.UnbondingHeight, - UnbondingMinTime: v.UnbondingMinTime, - Commission: v.Commission, + OperatorAddr: v.OperatorAddr, + ConsPubKey: bechConsPubKey, + Jailed: v.Jailed, + Status: v.Status, + Tokens: v.Tokens, + DelegatorShares: v.DelegatorShares, + Description: v.Description, + BondHeight: v.BondHeight, + UnbondingHeight: v.UnbondingHeight, + UnbondingMinTime: v.UnbondingMinTime, + Commission: v.Commission, }) } @@ -208,25 +201,24 @@ func (v *Validator) UnmarshalJSON(data []byte) error { return err } *v = Validator{ - OperatorAddr: bv.OperatorAddr, - ConsPubKey: consPubKey, - Jailed: bv.Jailed, - Tokens: bv.Tokens, - Status: bv.Status, - DelegatorShares: bv.DelegatorShares, - Description: bv.Description, - BondHeight: bv.BondHeight, - BondIntraTxCounter: bv.BondIntraTxCounter, - UnbondingHeight: bv.UnbondingHeight, - UnbondingMinTime: bv.UnbondingMinTime, - Commission: bv.Commission, + OperatorAddr: bv.OperatorAddr, + ConsPubKey: consPubKey, + Jailed: bv.Jailed, + Tokens: bv.Tokens, + Status: bv.Status, + DelegatorShares: bv.DelegatorShares, + Description: bv.Description, + BondHeight: bv.BondHeight, + UnbondingHeight: bv.UnbondingHeight, + UnbondingMinTime: bv.UnbondingMinTime, + Commission: bv.Commission, } return nil } //___________________________________________________________________ -// only the vitals - does not check bond height of IntraTxCounter +// only the vitals func (v Validator) Equal(v2 Validator) bool { return v.ConsPubKey.Equals(v2.ConsPubKey) && bytes.Equal(v.OperatorAddr, v2.OperatorAddr) &&