diff --git a/x/slashing/hooks.go b/x/slashing/hooks.go index 701a6b2cd..a2e6c506a 100644 --- a/x/slashing/hooks.go +++ b/x/slashing/hooks.go @@ -1,11 +1,25 @@ package slashing import ( + "time" + sdk "github.com/cosmos/cosmos-sdk/types" ) -// Create a new slashing period when a validator is bonded func (k Keeper) onValidatorBonded(ctx sdk.Context, address sdk.ConsAddress) { + // Create a new signing info if necessary + _, found := k.getValidatorSigningInfo(ctx, address) + if !found { + signingInfo := ValidatorSigningInfo{ + StartHeight: ctx.BlockHeight(), + IndexOffset: 0, + JailedUntil: time.Unix(0, 0), + SignedBlocksCounter: 0, + } + k.setValidatorSigningInfo(ctx, address, signingInfo) + } + + // Create a new slashing period when a validator is bonded slashingPeriod := ValidatorSlashingPeriod{ ValidatorAddr: address, StartHeight: ctx.BlockHeight(), diff --git a/x/slashing/keeper.go b/x/slashing/keeper.go index 94dd9f0d0..9cd7076cb 100644 --- a/x/slashing/keeper.go +++ b/x/slashing/keeper.go @@ -101,8 +101,7 @@ func (k Keeper) handleValidatorSignature(ctx sdk.Context, addr crypto.Address, p // Will use the 0-value default signing info if not present, except for start height signInfo, found := k.getValidatorSigningInfo(ctx, consAddr) if !found { - // If this validator has never been seen before, construct a new SigningInfo with the correct start height - signInfo = NewValidatorSigningInfo(height, 0, time.Unix(0, 0), 0) + panic(fmt.Sprintf("Expected signing info for validator %s but not found", consAddr)) } index := signInfo.IndexOffset % k.SignedBlocksWindow(ctx) signInfo.IndexOffset++ diff --git a/x/slashing/keeper_test.go b/x/slashing/keeper_test.go index cf67af192..23a3ae2de 100644 --- a/x/slashing/keeper_test.go +++ b/x/slashing/keeper_test.go @@ -28,7 +28,6 @@ func TestHandleDoubleSign(t *testing.T) { ctx, ck, sk, _, keeper := createTestInput(t) // validator added pre-genesis ctx = ctx.WithBlockHeight(-1) - sk = sk.WithHooks(keeper.Hooks()) amtInt := int64(100) operatorAddr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt) got := stake.NewHandler(sk)(ctx, newTestMsgCreateValidator(operatorAddr, val, amt)) @@ -69,7 +68,6 @@ func TestSlashingPeriodCap(t *testing.T) { // initial setup ctx, ck, sk, _, keeper := createTestInput(t) - sk = sk.WithHooks(keeper.Hooks()) amtInt := int64(100) operatorAddr, amt := addrs[0], sdk.NewInt(amtInt) valConsPubKey, valConsAddr := pks[0], pks[0].Address() @@ -135,7 +133,6 @@ func TestHandleAbsentValidator(t *testing.T) { // initial setup ctx, ck, sk, _, keeper := createTestInput(t) - sk = sk.WithHooks(keeper.Hooks()) amtInt := int64(100) addr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt) sh := stake.NewHandler(sk) @@ -146,14 +143,12 @@ func TestHandleAbsentValidator(t *testing.T) { keeper.AddValidators(ctx, validatorUpdates) require.Equal(t, ck.GetCoins(ctx, sdk.AccAddress(addr)), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins.Sub(amt)}}) require.True(t, sdk.NewDecFromInt(amt).Equal(sk.Validator(ctx, addr).GetPower())) + // will exist since the validator has been bonded info, found := keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address())) - require.False(t, found) + require.True(t, found) require.Equal(t, int64(0), info.StartHeight) require.Equal(t, int64(0), info.IndexOffset) require.Equal(t, int64(0), info.SignedBlocksCounter) - // default time.Time value - var blankTime time.Time - require.Equal(t, blankTime, info.JailedUntil) height := int64(0) // 1000 first blocks OK @@ -292,6 +287,11 @@ func TestHandleNewValidator(t *testing.T) { ctx, ck, sk, _, keeper := createTestInput(t) addr, val, amt := addrs[0], pks[0], int64(100) sh := stake.NewHandler(sk) + + // 1000 first blocks not a validator + ctx = ctx.WithBlockHeight(keeper.SignedBlocksWindow(ctx) + 1) + + // Validator created got := sh(ctx, newTestMsgCreateValidator(addr, val, sdk.NewInt(amt))) require.True(t, got.IsOK()) validatorUpdates := stake.EndBlocker(ctx, sk) @@ -299,9 +299,6 @@ func TestHandleNewValidator(t *testing.T) { require.Equal(t, ck.GetCoins(ctx, sdk.AccAddress(addr)), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins.SubRaw(amt)}}) require.Equal(t, sdk.NewDec(amt), sk.Validator(ctx, addr).GetPower()) - // 1000 first blocks not a validator - ctx = ctx.WithBlockHeight(keeper.SignedBlocksWindow(ctx) + 1) - // Now a validator, for two blocks keeper.handleValidatorSignature(ctx, val.Address(), 100, true) ctx = ctx.WithBlockHeight(keeper.SignedBlocksWindow(ctx) + 2) diff --git a/x/slashing/test_common.go b/x/slashing/test_common.go index 7c97a8537..25140c824 100644 --- a/x/slashing/test_common.go +++ b/x/slashing/test_common.go @@ -84,6 +84,7 @@ func createTestInput(t *testing.T) (sdk.Context, bank.Keeper, stake.Keeper, para } require.Nil(t, err) keeper := NewKeeper(cdc, keySlashing, sk, params.Getter(), DefaultCodespace) + sk = sk.WithHooks(keeper.Hooks()) return ctx, ck, sk, params.Setter(), keeper }