From 317be2bc16c923b705117d77cd3ff86c9a2cdc36 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 5 Oct 2018 19:56:17 +0200 Subject: [PATCH] Clarify ValidatorUpdateDelay --- x/slashing/keeper.go | 5 +++-- x/slashing/keeper_test.go | 1 + x/slashing/keys.go | 5 +++-- x/slashing/params.go | 6 ------ x/slashing/slashing_period.go | 3 ++- x/stake/genesis.go | 8 ++++---- x/stake/types/params.go | 14 +++++++++++--- 7 files changed, 24 insertions(+), 18 deletions(-) diff --git a/x/slashing/keeper.go b/x/slashing/keeper.go index dc316b2b6f..473a5f5f68 100644 --- a/x/slashing/keeper.go +++ b/x/slashing/keeper.go @@ -9,6 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/params" + stake "github.com/cosmos/cosmos-sdk/x/stake/types" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" ) @@ -60,7 +61,7 @@ func (k Keeper) handleDoubleSign(ctx sdk.Context, addr crypto.Address, infractio // Note that this *can* result in a "distributionHeight" of -1, // i.e. at the end of the pre-genesis block (none) = at the beginning of the genesis block. // That's fine since this is just used to filter unbonding delegations & redelegations. - distributionHeight := infractionHeight - ValidatorUpdateDelay + distributionHeight := infractionHeight - stake.ValidatorUpdateDelay // Cap the amount slashed to the penalty for the worst infraction // within the slashing period when this infraction was committed @@ -137,7 +138,7 @@ func (k Keeper) handleValidatorSignature(ctx sdk.Context, addr crypto.Address, p // Note that this *can* result in a "distributionHeight" of -1 or -2, // i.e. at the end of the pre-genesis block (none) = at the beginning of the genesis block. // That's fine since this is just used to filter unbonding delegations & redelegations. - distributionHeight := height - ValidatorUpdateDelay - 1 + distributionHeight := height - stake.ValidatorUpdateDelay - 1 k.validatorSet.Slash(ctx, consAddr, distributionHeight, power, k.SlashFractionDowntime(ctx)) k.validatorSet.Jail(ctx, consAddr) signInfo.JailedUntil = ctx.BlockHeader().Time.Add(k.DowntimeUnbondDuration(ctx)) diff --git a/x/slashing/keeper_test.go b/x/slashing/keeper_test.go index 43c8e2a203..cf67af1920 100644 --- a/x/slashing/keeper_test.go +++ b/x/slashing/keeper_test.go @@ -250,6 +250,7 @@ func TestHandleAbsentValidator(t *testing.T) { info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address())) require.True(t, found) require.Equal(t, height, info.StartHeight) + // we've missed 2 blocks more than the maximum require.Equal(t, keeper.SignedBlocksWindow(ctx)-keeper.MinSignedPerWindow(ctx)-2, info.SignedBlocksCounter) // validator should not be immediately jailed again diff --git a/x/slashing/keys.go b/x/slashing/keys.go index 4303f4635e..ec453cedca 100644 --- a/x/slashing/keys.go +++ b/x/slashing/keys.go @@ -4,6 +4,7 @@ import ( "encoding/binary" sdk "github.com/cosmos/cosmos-sdk/types" + stake "github.com/cosmos/cosmos-sdk/x/stake/types" ) // key prefix bytes @@ -34,8 +35,8 @@ func GetValidatorSlashingPeriodPrefix(v sdk.ConsAddress) []byte { // stored by *Tendermint* address (not operator address) followed by start height func GetValidatorSlashingPeriodKey(v sdk.ConsAddress, startHeight int64) []byte { b := make([]byte, 8) - // this needs to be height + 1 because the slashing period for genesis validators starts at height -1 - binary.BigEndian.PutUint64(b, uint64(startHeight+1)) + // this needs to be height + ValidatorUpdateDelay because the slashing period for genesis validators starts at height -ValidatorUpdateDelay + binary.BigEndian.PutUint64(b, uint64(startHeight+stake.ValidatorUpdateDelay)) return append(GetValidatorSlashingPeriodPrefix(v), b...) } diff --git a/x/slashing/params.go b/x/slashing/params.go index 467af3c113..6e18e5f481 100644 --- a/x/slashing/params.go +++ b/x/slashing/params.go @@ -15,12 +15,6 @@ const ( DowntimeUnbondDurationKey = "slashing/DowntimeUnbondDuration" SlashFractionDoubleSignKey = "slashing/SlashFractionDoubleSign" SlashFractionDowntimeKey = "slashing/SlashFractionDowntime" - - // Delay, in blocks, between when validator updates are returned to Tendermint and when they are applied - // For example, if this is 0, the validator set at the end of a block will sign the next block, or - // if this is 1, the validator set at the end of a block will sign the block after the next. - // Constant as this should not change without a hard fork. - ValidatorUpdateDelay int64 = 1 ) // MaxEvidenceAge - Max age for evidence - 21 days (3 weeks) diff --git a/x/slashing/slashing_period.go b/x/slashing/slashing_period.go index 1d94aa5599..0595d5eeb2 100644 --- a/x/slashing/slashing_period.go +++ b/x/slashing/slashing_period.go @@ -5,6 +5,7 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + stake "github.com/cosmos/cosmos-sdk/x/stake/types" ) // Cap an infraction's slash amount by the slashing period in which it was committed @@ -68,7 +69,7 @@ func (k Keeper) unmarshalSlashingPeriodKeyValue(key []byte, value []byte) Valida var slashingPeriodValue ValidatorSlashingPeriodValue k.cdc.MustUnmarshalBinary(value, &slashingPeriodValue) address := sdk.ConsAddress(key[1 : 1+sdk.AddrLen]) - startHeight := int64(binary.BigEndian.Uint64(key[1+sdk.AddrLen:1+sdk.AddrLen+8]) - 1) + startHeight := int64(binary.BigEndian.Uint64(key[1+sdk.AddrLen:1+sdk.AddrLen+8]) - uint64(stake.ValidatorUpdateDelay)) return ValidatorSlashingPeriod{ ValidatorAddr: address, StartHeight: startHeight, diff --git a/x/stake/genesis.go b/x/stake/genesis.go index 336e414fe7..1d500bd822 100644 --- a/x/stake/genesis.go +++ b/x/stake/genesis.go @@ -17,10 +17,10 @@ import ( // 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) { - // We need to pretend to be "one block before genesis" so that e.g. slashing periods - // are correctly initialized for the validator set one-block offset - the first TM block - // is at height 0, so state updates applied from genesis.json are in block -1. - ctx = ctx.WithBlockHeight(-1) + // We need to pretend to be "n blocks before genesis", where "n" is the validator update delay, + // so that e.g. slashing periods are correctly initialized for the validator set + // e.g. with a one-block offset - the first TM block is at height 0, so state updates applied from genesis.json are in block -1. + ctx = ctx.WithBlockHeight(-types.ValidatorUpdateDelay) keeper.SetPool(ctx, data.Pool) keeper.SetParams(ctx, data.Params) diff --git a/x/stake/types/params.go b/x/stake/types/params.go index 4dcc3782a8..c3685f7c30 100644 --- a/x/stake/types/params.go +++ b/x/stake/types/params.go @@ -9,9 +9,17 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -// defaultUnbondingTime reflects three weeks in seconds as the default -// unbonding time. -const defaultUnbondingTime time.Duration = 60 * 60 * 24 * 3 * time.Second +const ( + // defaultUnbondingTime reflects three weeks in seconds as the default + // unbonding time. + defaultUnbondingTime time.Duration = 60 * 60 * 24 * 3 * time.Second + + // Delay, in blocks, between when validator updates are returned to Tendermint and when they are applied + // For example, if this is 0, the validator set at the end of a block will sign the next block, or + // if this is 1, the validator set at the end of a block will sign the block after the next. + // Constant as this should not change without a hard fork. + ValidatorUpdateDelay int64 = 1 +) // Params defines the high level settings for staking type Params struct {