From 2171895acf6017bbd6eada7c612b37b7201b78cd Mon Sep 17 00:00:00 2001 From: chengwenxi Date: Thu, 20 Dec 2018 18:54:34 +0800 Subject: [PATCH] use address instead of bond height / intratxcounter for deduplication --- app/v0/export.go | 1 - client/stake/utils.go | 23 ++-- modules/slashing/keeper_test.go | 4 +- modules/stake/genesis.go | 19 +-- modules/stake/genesis_test.go | 2 - modules/stake/handler.go | 4 - modules/stake/keeper/delegation.go | 2 +- modules/stake/keeper/delegation_test.go | 48 ++++---- modules/stake/keeper/keeper.go | 21 ---- modules/stake/keeper/key.go | 41 +++++-- modules/stake/keeper/key_test.go | 8 +- modules/stake/keeper/slash_test.go | 3 +- modules/stake/keeper/test_common.go | 33 ++++- modules/stake/keeper/validator.go | 5 - modules/stake/keeper/validator_test.go | 125 +++++++++---------- modules/stake/querier/queryable_test.go | 1 - modules/stake/stake.go | 1 - modules/stake/types/genesis.go | 1 - modules/stake/types/validator.go | 153 +++++++++++------------- 19 files changed, 238 insertions(+), 257 deletions(-) diff --git a/app/v0/export.go b/app/v0/export.go index bed0ca602..ee716832c 100644 --- a/app/v0/export.go +++ b/app/v0/export.go @@ -138,7 +138,6 @@ func (p *ProtocolVersion0) prepForZeroHeightGenesis(ctx sdk.Context) { panic("expected validator, not found") } validator.BondHeight = 0 - validator.BondIntraTxCounter = counter validator.UnbondingHeight = 0 p.StakeKeeper.SetValidator(ctx, validator) counter++ diff --git a/client/stake/utils.go b/client/stake/utils.go index 1851c0c28..953a3d0a7 100644 --- a/client/stake/utils.go +++ b/client/stake/utils.go @@ -148,18 +148,17 @@ func ConvertValidatorToValidatorOutput(cliCtx context.CLIContext, v stake.Valida UpdateTime: v.Commission.UpdateTime, } return ValidatorOutput{ - OperatorAddr: v.OperatorAddr, - ConsPubKey: bechValPubkey, - Jailed: v.Jailed, - Status: v.Status, - Tokens: utils.ConvertDecToRat(v.Tokens).Mul(exRate).FloatString(), - DelegatorShares: utils.ConvertDecToRat(v.DelegatorShares).Mul(exRate).FloatString(), - Description: v.Description, - BondHeight: v.UnbondingHeight, - BondIntraTxCounter: v.BondIntraTxCounter, - UnbondingHeight: v.UnbondingHeight, - UnbondingMinTime: v.UnbondingMinTime, - Commission: commission, + OperatorAddr: v.OperatorAddr, + ConsPubKey: bechValPubkey, + Jailed: v.Jailed, + Status: v.Status, + Tokens: utils.ConvertDecToRat(v.Tokens).Mul(exRate).FloatString(), + DelegatorShares: utils.ConvertDecToRat(v.DelegatorShares).Mul(exRate).FloatString(), + Description: v.Description, + BondHeight: v.UnbondingHeight, + UnbondingHeight: v.UnbondingHeight, + UnbondingMinTime: v.UnbondingMinTime, + Commission: commission, } } diff --git a/modules/slashing/keeper_test.go b/modules/slashing/keeper_test.go index 5bda77123..ca1154fc3 100644 --- a/modules/slashing/keeper_test.go +++ b/modules/slashing/keeper_test.go @@ -416,13 +416,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.NewIntWithDecimal(2, 18))) + got = sh(ctx, newTestMsgDelegate(sdk.AccAddress(addrs[2]), addrs[0], sdk.NewIntWithDecimal(3, 18))) 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/modules/stake/genesis.go b/modules/stake/genesis.go index 803291598..93dc19e30 100644 --- a/modules/stake/genesis.go +++ b/modules/stake/genesis.go @@ -11,12 +11,10 @@ import ( "github.com/irisnet/irishub/modules/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. -// Returns final validator set after applying all declaration and delegations +// 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. func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) (res []abci.ValidatorUpdate, err error) { // We need to pretend to be "n blocks before genesis", where "n" is the validator update delay, @@ -26,14 +24,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 +86,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) @@ -117,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/modules/stake/genesis_test.go b/modules/stake/genesis_test.go index 0d57d8eea..b974c363e 100644 --- a/modules/stake/genesis_test.go +++ b/modules/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/modules/stake/handler.go b/modules/stake/handler.go index 045394c54..819e445a2 100644 --- a/modules/stake/handler.go +++ b/modules/stake/handler.go @@ -35,10 +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.EmptyTags() - - // Reset the intra-transaction counter. - k.SetIntraTxCounter(ctx, 0) - // Calculate validator set changes. // // NOTE: ApplyAndReturnValidatorSetUpdates has to come before diff --git a/modules/stake/keeper/delegation.go b/modules/stake/keeper/delegation.go index de882efe7..8af3e26a5 100644 --- a/modules/stake/keeper/delegation.go +++ b/modules/stake/keeper/delegation.go @@ -573,7 +573,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/modules/stake/keeper/delegation_test.go b/modules/stake/keeper/delegation_test.go index fb7d866e5..97fb873e3 100644 --- a/modules/stake/keeper/delegation_test.go +++ b/modules/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.NewIntWithDecimal(10, 18)) require.Equal(t, sdk.NewDecFromInt(sdk.NewIntWithDecimal(10, 18)), issuedShares) keeper.SetPool(ctx, pool) - validator = TestingUpdateValidator(keeper, ctx, validator) + validator = TestingUpdateValidator(keeper, ctx, validator, true) pool = keeper.GetPool(ctx) require.Equal(t, sdk.NewDecFromInt(sdk.NewIntWithDecimal(10, 18)), pool.BondedTokens) @@ -230,7 +230,7 @@ func TestUndelegateSelfDelegation(t *testing.T) { validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewIntWithDecimal(10, 18)) require.Equal(t, sdk.NewDecFromInt(sdk.NewIntWithDecimal(10, 18)), issuedShares) 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.NewIntWithDecimal(10, 18)) require.Equal(t, sdk.NewDecFromInt(sdk.NewIntWithDecimal(10, 18)), issuedShares) 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.NewIntWithDecimal(10, 18)) require.Equal(t, sdk.NewDecFromInt(sdk.NewIntWithDecimal(10, 18)), issuedShares) 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.NewIntWithDecimal(10, 18)) require.Equal(t, sdk.NewDecFromInt(sdk.NewIntWithDecimal(10, 18)), issuedShares) 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.NewIntWithDecimal(10, 18)) require.Equal(t, sdk.NewDecFromInt(sdk.NewIntWithDecimal(10, 18)), issuedShares) 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.NewIntWithDecimal(10, 18)) require.Equal(t, sdk.NewDecFromInt(sdk.NewIntWithDecimal(10, 18)), issuedShares) 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.NewIntWithDecimal(10, 18)) require.Equal(t, sdk.NewDecFromInt(sdk.NewIntWithDecimal(10, 18)), issuedShares) 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.NewIntWithDecimal(10, 18)) require.Equal(t, sdk.NewDecFromInt(sdk.NewIntWithDecimal(10, 18)), issuedShares) 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.NewIntWithDecimal(10, 18)) require.Equal(t, sdk.NewDecFromInt(sdk.NewIntWithDecimal(10, 18)), issuedShares) 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, sdk.NewDecFromInt(sdk.NewIntWithDecimal(10, 18)), issuedShares) pool.BondedTokens = pool.BondedTokens.Add(sdk.NewDecFromInt(sdk.NewIntWithDecimal(10, 18))) 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.NewIntWithDecimal(10, 18)) require.Equal(t, sdk.NewDecFromInt(sdk.NewIntWithDecimal(10, 18)), issuedShares) 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.NewIntWithDecimal(10, 18)) require.Equal(t, sdk.NewDecFromInt(sdk.NewIntWithDecimal(10, 18)), issuedShares) 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.NewIntWithDecimal(10, 18)) require.Equal(t, sdk.NewDecFromInt(sdk.NewIntWithDecimal(10, 18)), issuedShares) 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.NewIntWithDecimal(10, 18)) require.Equal(t, sdk.NewDecFromInt(sdk.NewIntWithDecimal(10, 18)), issuedShares) 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.NewIntWithDecimal(10, 18)) require.Equal(t, sdk.NewDecFromInt(sdk.NewIntWithDecimal(10, 18)), issuedShares) 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, pool) validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewIntWithDecimal(10, 18)) - validator.BondIntraTxCounter = 1 require.Equal(t, sdk.NewDecFromInt(sdk.NewIntWithDecimal(10, 18)), issuedShares) 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.NewIntWithDecimal(10, 18)) require.Equal(t, sdk.NewDecFromInt(sdk.NewIntWithDecimal(10, 18)), issuedShares) 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/modules/stake/keeper/keeper.go b/modules/stake/keeper/keeper.go index 7c353e834..cf682fa30 100644 --- a/modules/stake/keeper/keeper.go +++ b/modules/stake/keeper/keeper.go @@ -143,24 +143,3 @@ func (k Keeper) BurnAmount(ctx sdk.Context, amount sdk.Dec) { func (k Keeper) GetStakeDenom(ctx sdk.Context) string { return types.StakeDenom } - -//__________________________________________________________________________ - -// 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/modules/stake/keeper/key.go b/modules/stake/keeper/key.go index 94b12c55e..a8134cb36 100644 --- a/modules/stake/keeper/key.go +++ b/modules/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,35 @@ 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 +274,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/modules/stake/keeper/key_test.go b/modules/stake/keeper/key_test.go index a6070687c..6e5a6e3ac 100644 --- a/modules/stake/keeper/key_test.go +++ b/modules/stake/keeper/key_test.go @@ -36,10 +36,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/modules/stake/keeper/slash_test.go b/modules/stake/keeper/slash_test.go index ffa54dc33..765e99828 100644 --- a/modules/stake/keeper/slash_test.go +++ b/modules/stake/keeper/slash_test.go @@ -26,10 +26,9 @@ func setupHelper(t *testing.T, amt sdk.Int) (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, amt) - validator.BondIntraTxCounter = int16(i) pool.BondedTokens = pool.BondedTokens.Add(sdk.NewDecFromInt(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/modules/stake/keeper/test_common.go b/modules/stake/keeper/test_common.go index 03c468c10..e4db45855 100644 --- a/modules/stake/keeper/test_common.go +++ b/modules/stake/keeper/test_common.go @@ -200,12 +200,37 @@ 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 { - pool := keeper.GetPool(ctx) +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()) + } + } + } + pool := keeper.GetPool(ctx) keeper.SetValidatorByPowerIndex(ctx, validator, pool) - keeper.ApplyAndReturnValidatorSetUpdates(ctx) - validator, found := keeper.GetValidator(ctx, validator.OperatorAddr) + if apply { + keeper.ApplyAndReturnValidatorSetUpdates(ctx) + validator, found := keeper.GetValidator(ctx, validator.OperatorAddr) + if !found { + panic("validator expected but not found") + } + return validator + } + cachectx, _ := ctx.CacheContext() + keeper.ApplyAndReturnValidatorSetUpdates(cachectx) + validator, found := keeper.GetValidator(cachectx, validator.OperatorAddr) if !found { panic("validator expected but not found") } diff --git a/modules/stake/keeper/validator.go b/modules/stake/keeper/validator.go index 35ec03376..63c6f4401 100644 --- a/modules/stake/keeper/validator.go +++ b/modules/stake/keeper/validator.go @@ -130,11 +130,6 @@ func (k Keeper) AddValidatorTokensAndShares(ctx sdk.Context, validator types.Val pool := k.GetPool(ctx) k.DeleteValidatorByPowerIndex(ctx, validator, pool) 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, pool) diff --git a/modules/stake/keeper/validator_test.go b/modules/stake/keeper/validator_test.go index 4ac01479c..3353b6292 100644 --- a/modules/stake/keeper/validator_test.go +++ b/modules/stake/keeper/validator_test.go @@ -83,7 +83,7 @@ func TestUpdateValidatorByPowerIndex(t *testing.T) { require.Equal(t, sdk.Unbonded, validator.Status) require.Equal(t, sdk.NewDecFromInt(sdk.NewIntWithDecimal(100, 18)), validator.Tokens) 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, sdk.NewDecFromInt(sdk.NewIntWithDecimal(100, 18)), validator.Tokens, "\nvalidator %v\npool %v", validator, pool) @@ -96,8 +96,8 @@ func TestUpdateValidatorByPowerIndex(t *testing.T) { keeper.DeleteValidatorByPowerIndex(ctx, validator, pool) validator, pool, burned := validator.RemoveDelShares(pool, delSharesCreated.Quo(sdk.NewDec(2))) require.Equal(t, sdk.NewDecFromInt(sdk.NewIntWithDecimal(50, 18)), burned) - 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) @@ -130,11 +130,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.NewIntWithDecimal(int64((i+1)*10), 18)) keeper.SetPool(ctx, pool) - val = TestingUpdateValidator(keeper, ctx, val) + val = TestingUpdateValidator(keeper, ctx, val, true) validators[i] = val } @@ -145,7 +144,7 @@ func TestUpdateBondedValidatorsDecreaseCliff(t *testing.T) { keeper.DeleteValidatorByPowerIndex(ctx, nextCliffVal, pool) nextCliffVal, pool, _ = nextCliffVal.RemoveDelShares(pool, sdk.NewDecFromInt(sdk.NewIntWithDecimal(21, 18))) 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, @@ -177,7 +176,7 @@ func TestSlashToZeroPowerRemoved(t *testing.T) { require.Equal(t, sdk.NewDecFromInt(sdk.NewIntWithDecimal(100, 18)), validator.Tokens) keeper.SetPool(ctx, pool) keeper.SetValidatorByConsAddr(ctx, validator) - validator = TestingUpdateValidator(keeper, ctx, validator) + validator = TestingUpdateValidator(keeper, ctx, validator, true) require.Equal(t, sdk.NewDecFromInt(sdk.NewIntWithDecimal(100, 18)), validator.Tokens, "\nvalidator %v\npool %v", validator, pool) // slash the validator by 100% @@ -222,7 +221,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) @@ -249,7 +248,7 @@ func TestValidatorBasics(t *testing.T) { validators[0].Status = sdk.Bonded validators[0].Tokens = sdk.NewDecFromInt(sdk.NewIntWithDecimal(10, 18)) validators[0].DelegatorShares = sdk.NewDecFromInt(sdk.NewIntWithDecimal(10, 18)) - 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)) @@ -259,8 +258,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)) @@ -295,7 +294,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 @@ -314,14 +313,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])) @@ -330,7 +329,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])) @@ -340,7 +339,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])) @@ -349,11 +348,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])) @@ -391,7 +390,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) @@ -443,9 +442,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, 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 { @@ -461,7 +459,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) { keeper.DeleteValidatorByPowerIndex(ctx, validators[0], pool) validators[0], pool, _ = validators[0].AddTokensFromDel(pool, sdk.NewIntWithDecimal(500, 18)) 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])) @@ -479,7 +477,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) { keeper.DeleteValidatorByPowerIndex(ctx, validators[3], pool) validators[3], pool, _ = validators[3].AddTokensFromDel(pool, sdk.NewIntWithDecimal(1, 18)) 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])) @@ -489,7 +487,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) { keeper.DeleteValidatorByPowerIndex(ctx, validators[3], pool) validators[3], pool, _ = validators[3].RemoveDelShares(pool, sdk.NewDecFromInt(sdk.NewIntWithDecimal(201, 18))) 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])) @@ -499,7 +497,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) { keeper.DeleteValidatorByPowerIndex(ctx, validators[3], pool) validators[3], pool, _ = validators[3].AddTokensFromDel(pool, sdk.NewIntWithDecimal(200, 18)) 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])) @@ -523,22 +521,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.NewIntWithDecimal(200, 18)) validators[1], pool, _ = validators[1].AddTokensFromDel(pool, sdk.NewIntWithDecimal(100, 18)) validators[2], pool, _ = validators[2].AddTokensFromDel(pool, sdk.NewIntWithDecimal(100, 18)) 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) @@ -552,10 +547,10 @@ func TestValidatorBondHeight(t *testing.T) { validators[1], pool, _ = validators[1].AddTokensFromDel(pool, sdk.NewIntWithDecimal(50, 18)) validators[2], pool, _ = validators[2].AddTokensFromDel(pool, sdk.NewIntWithDecimal(50, 18)) 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])) } @@ -574,9 +569,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, 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 @@ -597,7 +591,7 @@ func TestFullValidatorSetPowerChange(t *testing.T) { pool := keeper.GetPool(ctx) validators[0], pool, _ = validators[0].AddTokensFromDel(pool, sdk.NewIntWithDecimal(600, 18)) 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, 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], true) + validators[1] = TestingUpdateValidator(keeper, ctx, validators[1], true) require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) } @@ -670,15 +664,15 @@ func TestApplyAndReturnValidatorSetUpdatesSingleValueChange(t *testing.T) { validators[i], pool, _ = validators[i].AddTokensFromDel(pool, 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.NewDecFromInt(sdk.NewIntWithDecimal(600, 18)) - 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, 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.NewIntWithDecimal(190, 18)) validators[1], pool, _ = validators[1].AddTokensFromDel(pool, sdk.NewIntWithDecimal(80, 18)) 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, 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} @@ -776,13 +770,13 @@ func TestApplyAndReturnValidatorSetUpdatesWithCliffValidator(t *testing.T) { validators[i], pool, _ = validators[i].AddTokensFromDel(pool, 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)) @@ -811,12 +805,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, 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), validators[0].GetPower()) @@ -828,8 +821,8 @@ func TestApplyAndReturnValidatorSetUpdatesPowerDecrease(t *testing.T) { validators[0], pool, _ = validators[0].RemoveDelShares(pool, sdk.NewDecFromInt(sdk.NewIntWithDecimal(20, 18))) validators[1], pool, _ = validators[1].RemoveDelShares(pool, sdk.NewDecFromInt(sdk.NewIntWithDecimal(30, 18))) 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), validators[0].GetPower()) @@ -859,7 +852,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, amt) keeper.SetPool(ctx, pool) @@ -945,7 +937,6 @@ func TestApplyAndReturnValidatorSetUpdatesBondTransition(t *testing.T) { validators[i] = types.NewValidator(valAddr, valPubKey, types.Description{Moniker: moniker}) validators[i], pool, _ = validators[i].AddTokensFromDel(pool, amt) - validators[i].BondIntraTxCounter = int16(i) keeper.SetPool(ctx, pool) keeper.SetValidator(ctx, validators[i]) keeper.SetValidatorByPowerIndex(ctx, validators[i], pool) diff --git a/modules/stake/querier/queryable_test.go b/modules/stake/querier/queryable_test.go index c87769ef7..0c9f00a10 100644 --- a/modules/stake/querier/queryable_test.go +++ b/modules/stake/querier/queryable_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], pool) } diff --git a/modules/stake/stake.go b/modules/stake/stake.go index e974d22f0..5702e1746 100644 --- a/modules/stake/stake.go +++ b/modules/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/modules/stake/types/genesis.go b/modules/stake/types/genesis.go index adb83aabe..ae5237976 100644 --- a/modules/stake/types/genesis.go +++ b/modules/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/modules/stake/types/validator.go b/modules/stake/types/validator.go index b17342b1a..6777bd4fe 100644 --- a/modules/stake/types/validator.go +++ b/modules/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 } @@ -182,18 +177,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 +202,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) && @@ -444,15 +437,15 @@ func (v Validator) GetStatus() sdk.BondStatus { return v.Status } func (v Validator) GetOperator() sdk.ValAddress { return v.OperatorAddr } func (v Validator) GetConsPubKey() crypto.PubKey { return v.ConsPubKey } func (v Validator) GetConsAddr() sdk.ConsAddress { return sdk.ConsAddress(v.ConsPubKey.Address()) } -func (v Validator) GetPower() sdk.Dec { +func (v Validator) GetPower() sdk.Dec { tokenPrecision := sdk.NewIntWithDecimal(1, 18) return v.BondedTokens().QuoInt(tokenPrecision) } -func (v Validator) GetPotentialPower() sdk.Dec { +func (v Validator) GetPotentialPower() sdk.Dec { tokenPrecision := sdk.NewIntWithDecimal(1, 18) return v.Tokens.QuoInt(tokenPrecision) } -func (v Validator) GetTokens() sdk.Dec { return v.Tokens } -func (v Validator) GetCommission() sdk.Dec { return v.Commission.Rate } -func (v Validator) GetDelegatorShares() sdk.Dec { return v.DelegatorShares } -func (v Validator) GetBondHeight() int64 { return v.BondHeight } +func (v Validator) GetTokens() sdk.Dec { return v.Tokens } +func (v Validator) GetCommission() sdk.Dec { return v.Commission.Rate } +func (v Validator) GetDelegatorShares() sdk.Dec { return v.DelegatorShares } +func (v Validator) GetBondHeight() int64 { return v.BondHeight }