diff --git a/x/slashing/keeper.go b/x/slashing/keeper.go index c7cf06369..d5ae09ef2 100644 --- a/x/slashing/keeper.go +++ b/x/slashing/keeper.go @@ -58,8 +58,8 @@ func (k Keeper) handleValidatorSignature(ctx sdk.Context, pubkey crypto.PubKey, // Will use the 0-value default signing info if not present, except for start height signInfo, found := k.getValidatorSigningInfo(ctx, address) if !found { - // If this validator has never been seen before, set the start height - signInfo.StartHeight = height + // If this validator has never been seen before, construct a new SigningInfo with the correct start height + signInfo = NewValidatorSigningInfo(height, 0, 0, 0) } index := signInfo.IndexOffset % SignedBlocksWindow signInfo.IndexOffset++ diff --git a/x/slashing/keeper_test.go b/x/slashing/keeper_test.go index 3e78d939d..1f8f9db07 100644 --- a/x/slashing/keeper_test.go +++ b/x/slashing/keeper_test.go @@ -11,6 +11,8 @@ import ( "github.com/cosmos/cosmos-sdk/x/stake" ) +// Test that a validator is slashed correctly +// when we discover evidence of equivocation func TestHandleDoubleSign(t *testing.T) { // initial setup @@ -32,6 +34,8 @@ func TestHandleDoubleSign(t *testing.T) { require.Equal(t, sdk.NewRat(amt).Mul(sdk.NewRat(19).Quo(sdk.NewRat(20))), sk.Validator(ctx, addr).GetPower()) } +// Test a validator through uptime, downtime, revocation, +// unrevocation, starting height reset, and revocation again func TestHandleAbsentValidator(t *testing.T) { // initial setup @@ -130,6 +134,9 @@ func TestHandleAbsentValidator(t *testing.T) { require.Equal(t, sdk.Unbonded, validator.GetStatus()) } +// Test a new validator entering the validator set +// Ensure that SigningInfo.StartHeight is set correctly +// and that they are not immediately revoked func TestHandleNewValidator(t *testing.T) { // initial setup ctx, ck, sk, keeper := createTestInput(t) diff --git a/x/slashing/signing_info.go b/x/slashing/signing_info.go index a2df0505a..acbe1738b 100644 --- a/x/slashing/signing_info.go +++ b/x/slashing/signing_info.go @@ -47,6 +47,16 @@ func (k Keeper) setValidatorSigningBitArray(ctx sdk.Context, address sdk.Address store.Set(GetValidatorSigningBitArrayKey(address, index), bz) } +// Construct a new `ValidatorSigningInfo` struct +func NewValidatorSigningInfo(startHeight int64, indexOffset int64, jailedUntil int64, signedBlocksCounter int64) ValidatorSigningInfo { + return ValidatorSigningInfo{ + StartHeight: startHeight, + IndexOffset: indexOffset, + JailedUntil: jailedUntil, + SignedBlocksCounter: signedBlocksCounter, + } +} + // Signing info for a validator type ValidatorSigningInfo struct { StartHeight int64 `json:"start_height"` // height at which validator was first a candidate OR was unrevoked