diff --git a/x/slashing/handler_test.go b/x/slashing/handler_test.go index 059b19059..79092aebb 100644 --- a/x/slashing/handler_test.go +++ b/x/slashing/handler_test.go @@ -53,7 +53,7 @@ func TestJailedValidatorDelegations(t *testing.T) { StartHeight: int64(0), IndexOffset: int64(0), JailedUntil: time.Unix(0, 0), - SignedBlocksCounter: int64(0), + MissedBlocksCounter: int64(0), } slashingKeeper.setValidatorSigningInfo(ctx, consAddr, newInfo) diff --git a/x/slashing/hooks.go b/x/slashing/hooks.go index a2e6c506a..808260830 100644 --- a/x/slashing/hooks.go +++ b/x/slashing/hooks.go @@ -14,7 +14,7 @@ func (k Keeper) onValidatorBonded(ctx sdk.Context, address sdk.ConsAddress) { StartHeight: ctx.BlockHeight(), IndexOffset: 0, JailedUntil: time.Unix(0, 0), - SignedBlocksCounter: 0, + MissedBlocksCounter: 0, } k.setValidatorSigningInfo(ctx, address, signingInfo) } diff --git a/x/slashing/keeper.go b/x/slashing/keeper.go index 9cd7076cb..23e30fe1e 100644 --- a/x/slashing/keeper.go +++ b/x/slashing/keeper.go @@ -110,23 +110,25 @@ func (k Keeper) handleValidatorSignature(ctx sdk.Context, addr crypto.Address, p // This counter just tracks the sum of the bit array // That way we avoid needing to read/write the whole array each time previous := k.getValidatorSigningBitArray(ctx, consAddr, index) - if previous == signed { + missed := !signed + if previous == missed { // Array value at this index has not changed, no need to update counter - } else if previous && !signed { - // Array value has changed from signed to unsigned, decrement counter - k.setValidatorSigningBitArray(ctx, consAddr, index, false) - signInfo.SignedBlocksCounter-- - } else if !previous && signed { - // Array value has changed from unsigned to signed, increment counter + } else if !previous && missed { + // Array value has changed from not missed to missed, increment counter k.setValidatorSigningBitArray(ctx, consAddr, index, true) - signInfo.SignedBlocksCounter++ + signInfo.MissedBlocksCounter++ + } else if previous && !missed { + // Array value has changed from missed to not missed, decrement counter + k.setValidatorSigningBitArray(ctx, consAddr, index, false) + signInfo.MissedBlocksCounter-- } - if !signed { - logger.Info(fmt.Sprintf("Absent validator %s at height %d, %d signed, threshold %d", addr, height, signInfo.SignedBlocksCounter, k.MinSignedPerWindow(ctx))) + if missed { + logger.Info(fmt.Sprintf("Absent validator %s at height %d, %d missed, threshold %d", addr, height, signInfo.MissedBlocksCounter, k.MinSignedPerWindow(ctx))) } minHeight := signInfo.StartHeight + k.SignedBlocksWindow(ctx) - if height > minHeight && signInfo.SignedBlocksCounter < k.MinSignedPerWindow(ctx) { + maxMissed := k.SignedBlocksWindow(ctx) - k.MinSignedPerWindow(ctx) + if height > minHeight && signInfo.MissedBlocksCounter > maxMissed { validator := k.validatorSet.ValidatorByConsAddr(ctx, consAddr) if validator != nil && !validator.GetJailed() { // Downtime confirmed: slash and jail the validator diff --git a/x/slashing/keeper_test.go b/x/slashing/keeper_test.go index 23a3ae2de..32469b6d3 100644 --- a/x/slashing/keeper_test.go +++ b/x/slashing/keeper_test.go @@ -148,7 +148,7 @@ func TestHandleAbsentValidator(t *testing.T) { 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) + require.Equal(t, int64(0), info.MissedBlocksCounter) height := int64(0) // 1000 first blocks OK @@ -159,7 +159,7 @@ func TestHandleAbsentValidator(t *testing.T) { info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address())) require.True(t, found) require.Equal(t, int64(0), info.StartHeight) - require.Equal(t, keeper.SignedBlocksWindow(ctx), info.SignedBlocksCounter) + require.Equal(t, int64(0), info.MissedBlocksCounter) // 500 blocks missed for ; height < keeper.SignedBlocksWindow(ctx)+(keeper.SignedBlocksWindow(ctx)-keeper.MinSignedPerWindow(ctx)); height++ { @@ -169,7 +169,7 @@ func TestHandleAbsentValidator(t *testing.T) { info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address())) require.True(t, found) require.Equal(t, int64(0), info.StartHeight) - require.Equal(t, keeper.SignedBlocksWindow(ctx)-keeper.MinSignedPerWindow(ctx), info.SignedBlocksCounter) + require.Equal(t, keeper.SignedBlocksWindow(ctx)-keeper.MinSignedPerWindow(ctx), info.MissedBlocksCounter) // validator should be bonded still validator, _ := sk.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val)) @@ -183,7 +183,7 @@ func TestHandleAbsentValidator(t *testing.T) { info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address())) require.True(t, found) require.Equal(t, int64(0), info.StartHeight) - require.Equal(t, keeper.SignedBlocksWindow(ctx)-keeper.MinSignedPerWindow(ctx)-1, info.SignedBlocksCounter) + require.Equal(t, keeper.SignedBlocksWindow(ctx)-keeper.MinSignedPerWindow(ctx)+1, info.MissedBlocksCounter) // end block stake.EndBlocker(ctx, sk) @@ -204,7 +204,7 @@ func TestHandleAbsentValidator(t *testing.T) { info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address())) require.True(t, found) require.Equal(t, int64(0), info.StartHeight) - require.Equal(t, keeper.SignedBlocksWindow(ctx)-keeper.MinSignedPerWindow(ctx)-2, info.SignedBlocksCounter) + require.Equal(t, keeper.SignedBlocksWindow(ctx)-keeper.MinSignedPerWindow(ctx)+2, info.MissedBlocksCounter) // end block stake.EndBlocker(ctx, sk) @@ -246,7 +246,7 @@ func TestHandleAbsentValidator(t *testing.T) { 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) + require.Equal(t, keeper.SignedBlocksWindow(ctx)-keeper.MinSignedPerWindow(ctx)+2, info.MissedBlocksCounter) // validator should not be immediately jailed again height++ @@ -308,7 +308,7 @@ func TestHandleNewValidator(t *testing.T) { require.True(t, found) require.Equal(t, keeper.SignedBlocksWindow(ctx)+1, info.StartHeight) require.Equal(t, int64(2), info.IndexOffset) - require.Equal(t, int64(1), info.SignedBlocksCounter) + require.Equal(t, int64(1), info.MissedBlocksCounter) require.Equal(t, time.Unix(0, 0).UTC(), info.JailedUntil) // validator should be bonded still, should not have been jailed or slashed diff --git a/x/slashing/signing_info.go b/x/slashing/signing_info.go index 1adf49abc..64f47838a 100644 --- a/x/slashing/signing_info.go +++ b/x/slashing/signing_info.go @@ -48,25 +48,25 @@ func (k Keeper) setValidatorSigningBitArray(ctx sdk.Context, address sdk.ConsAdd } // Construct a new `ValidatorSigningInfo` struct -func NewValidatorSigningInfo(startHeight int64, indexOffset int64, jailedUntil time.Time, signedBlocksCounter int64) ValidatorSigningInfo { +func NewValidatorSigningInfo(startHeight int64, indexOffset int64, jailedUntil time.Time, missedBlocksCounter int64) ValidatorSigningInfo { return ValidatorSigningInfo{ StartHeight: startHeight, IndexOffset: indexOffset, JailedUntil: jailedUntil, - SignedBlocksCounter: signedBlocksCounter, + MissedBlocksCounter: missedBlocksCounter, } } // Signing info for a validator type ValidatorSigningInfo struct { - StartHeight int64 `json:"start_height"` // height at which validator was first a candidate OR was unjailed - IndexOffset int64 `json:"index_offset"` // index offset into signed block bit array - JailedUntil time.Time `json:"jailed_until"` // timestamp validator cannot be unjailed until - SignedBlocksCounter int64 `json:"signed_blocks_counter"` // signed blocks counter (to avoid scanning the array every time) + StartHeight int64 `json:"start_height"` // height at which validator was first a candidate OR was unjailed + IndexOffset int64 `json:"index_offset"` // index offset into signed block bit array + JailedUntil time.Time `json:"jailed_until"` // timestamp validator cannot be unjailed until + MissedBlocksCounter int64 `json:"misseded_blocks_counter"` // missed blocks counter (to avoid scanning the array every time) } // Return human readable signing info func (i ValidatorSigningInfo) HumanReadableString() string { - return fmt.Sprintf("Start height: %d, index offset: %d, jailed until: %v, signed blocks counter: %d", - i.StartHeight, i.IndexOffset, i.JailedUntil, i.SignedBlocksCounter) + return fmt.Sprintf("Start height: %d, index offset: %d, jailed until: %v, missed blocks counter: %d", + i.StartHeight, i.IndexOffset, i.JailedUntil, i.MissedBlocksCounter) } diff --git a/x/slashing/signing_info_test.go b/x/slashing/signing_info_test.go index 7aff0da95..1b22d7461 100644 --- a/x/slashing/signing_info_test.go +++ b/x/slashing/signing_info_test.go @@ -17,7 +17,7 @@ func TestGetSetValidatorSigningInfo(t *testing.T) { StartHeight: int64(4), IndexOffset: int64(3), JailedUntil: time.Unix(2, 0), - SignedBlocksCounter: int64(10), + MissedBlocksCounter: int64(10), } keeper.setValidatorSigningInfo(ctx, sdk.ConsAddress(addrs[0]), newInfo) info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(addrs[0])) @@ -25,14 +25,14 @@ func TestGetSetValidatorSigningInfo(t *testing.T) { require.Equal(t, info.StartHeight, int64(4)) require.Equal(t, info.IndexOffset, int64(3)) require.Equal(t, info.JailedUntil, time.Unix(2, 0).UTC()) - require.Equal(t, info.SignedBlocksCounter, int64(10)) + require.Equal(t, info.MissedBlocksCounter, int64(10)) } func TestGetSetValidatorSigningBitArray(t *testing.T) { ctx, _, _, _, keeper := createTestInput(t) - signed := keeper.getValidatorSigningBitArray(ctx, sdk.ConsAddress(addrs[0]), 0) - require.False(t, signed) // treat empty key as unsigned + missed := keeper.getValidatorSigningBitArray(ctx, sdk.ConsAddress(addrs[0]), 0) + require.False(t, missed) // treat empty key as not missed keeper.setValidatorSigningBitArray(ctx, sdk.ConsAddress(addrs[0]), 0, true) - signed = keeper.getValidatorSigningBitArray(ctx, sdk.ConsAddress(addrs[0]), 0) - require.True(t, signed) // now should be signed + missed = keeper.getValidatorSigningBitArray(ctx, sdk.ConsAddress(addrs[0]), 0) + require.True(t, missed) // now should be missed } diff --git a/x/slashing/tick_test.go b/x/slashing/tick_test.go index a98d97c54..c85d4f4cb 100644 --- a/x/slashing/tick_test.go +++ b/x/slashing/tick_test.go @@ -45,7 +45,7 @@ func TestBeginBlocker(t *testing.T) { require.Equal(t, ctx.BlockHeight(), info.StartHeight) require.Equal(t, int64(1), info.IndexOffset) require.Equal(t, time.Unix(0, 0).UTC(), info.JailedUntil) - require.Equal(t, int64(1), info.SignedBlocksCounter) + require.Equal(t, int64(0), info.MissedBlocksCounter) height := int64(0)