Count missed blocks instead of signed blocks
This commit is contained in:
parent
b55f29f72d
commit
5fd7297e25
|
@ -53,7 +53,7 @@ func TestJailedValidatorDelegations(t *testing.T) {
|
||||||
StartHeight: int64(0),
|
StartHeight: int64(0),
|
||||||
IndexOffset: int64(0),
|
IndexOffset: int64(0),
|
||||||
JailedUntil: time.Unix(0, 0),
|
JailedUntil: time.Unix(0, 0),
|
||||||
SignedBlocksCounter: int64(0),
|
MissedBlocksCounter: int64(0),
|
||||||
}
|
}
|
||||||
slashingKeeper.setValidatorSigningInfo(ctx, consAddr, newInfo)
|
slashingKeeper.setValidatorSigningInfo(ctx, consAddr, newInfo)
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ func (k Keeper) onValidatorBonded(ctx sdk.Context, address sdk.ConsAddress) {
|
||||||
StartHeight: ctx.BlockHeight(),
|
StartHeight: ctx.BlockHeight(),
|
||||||
IndexOffset: 0,
|
IndexOffset: 0,
|
||||||
JailedUntil: time.Unix(0, 0),
|
JailedUntil: time.Unix(0, 0),
|
||||||
SignedBlocksCounter: 0,
|
MissedBlocksCounter: 0,
|
||||||
}
|
}
|
||||||
k.setValidatorSigningInfo(ctx, address, signingInfo)
|
k.setValidatorSigningInfo(ctx, address, signingInfo)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
// This counter just tracks the sum of the bit array
|
||||||
// That way we avoid needing to read/write the whole array each time
|
// That way we avoid needing to read/write the whole array each time
|
||||||
previous := k.getValidatorSigningBitArray(ctx, consAddr, index)
|
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
|
// Array value at this index has not changed, no need to update counter
|
||||||
} else if previous && !signed {
|
} else if !previous && missed {
|
||||||
// Array value has changed from signed to unsigned, decrement counter
|
// Array value has changed from not missed to missed, increment counter
|
||||||
k.setValidatorSigningBitArray(ctx, consAddr, index, false)
|
|
||||||
signInfo.SignedBlocksCounter--
|
|
||||||
} else if !previous && signed {
|
|
||||||
// Array value has changed from unsigned to signed, increment counter
|
|
||||||
k.setValidatorSigningBitArray(ctx, consAddr, index, true)
|
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 {
|
if missed {
|
||||||
logger.Info(fmt.Sprintf("Absent validator %s at height %d, %d signed, threshold %d", addr, height, signInfo.SignedBlocksCounter, k.MinSignedPerWindow(ctx)))
|
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)
|
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)
|
validator := k.validatorSet.ValidatorByConsAddr(ctx, consAddr)
|
||||||
if validator != nil && !validator.GetJailed() {
|
if validator != nil && !validator.GetJailed() {
|
||||||
// Downtime confirmed: slash and jail the validator
|
// Downtime confirmed: slash and jail the validator
|
||||||
|
|
|
@ -148,7 +148,7 @@ func TestHandleAbsentValidator(t *testing.T) {
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Equal(t, int64(0), info.StartHeight)
|
require.Equal(t, int64(0), info.StartHeight)
|
||||||
require.Equal(t, int64(0), info.IndexOffset)
|
require.Equal(t, int64(0), info.IndexOffset)
|
||||||
require.Equal(t, int64(0), info.SignedBlocksCounter)
|
require.Equal(t, int64(0), info.MissedBlocksCounter)
|
||||||
height := int64(0)
|
height := int64(0)
|
||||||
|
|
||||||
// 1000 first blocks OK
|
// 1000 first blocks OK
|
||||||
|
@ -159,7 +159,7 @@ func TestHandleAbsentValidator(t *testing.T) {
|
||||||
info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
|
info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Equal(t, int64(0), info.StartHeight)
|
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
|
// 500 blocks missed
|
||||||
for ; height < keeper.SignedBlocksWindow(ctx)+(keeper.SignedBlocksWindow(ctx)-keeper.MinSignedPerWindow(ctx)); height++ {
|
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()))
|
info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Equal(t, int64(0), info.StartHeight)
|
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 should be bonded still
|
||||||
validator, _ := sk.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val))
|
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()))
|
info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Equal(t, int64(0), info.StartHeight)
|
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
|
// end block
|
||||||
stake.EndBlocker(ctx, sk)
|
stake.EndBlocker(ctx, sk)
|
||||||
|
@ -204,7 +204,7 @@ func TestHandleAbsentValidator(t *testing.T) {
|
||||||
info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
|
info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Equal(t, int64(0), info.StartHeight)
|
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
|
// end block
|
||||||
stake.EndBlocker(ctx, sk)
|
stake.EndBlocker(ctx, sk)
|
||||||
|
@ -246,7 +246,7 @@ func TestHandleAbsentValidator(t *testing.T) {
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Equal(t, height, info.StartHeight)
|
require.Equal(t, height, info.StartHeight)
|
||||||
// we've missed 2 blocks more than the maximum
|
// 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
|
// validator should not be immediately jailed again
|
||||||
height++
|
height++
|
||||||
|
@ -308,7 +308,7 @@ func TestHandleNewValidator(t *testing.T) {
|
||||||
require.True(t, found)
|
require.True(t, found)
|
||||||
require.Equal(t, keeper.SignedBlocksWindow(ctx)+1, info.StartHeight)
|
require.Equal(t, keeper.SignedBlocksWindow(ctx)+1, info.StartHeight)
|
||||||
require.Equal(t, int64(2), info.IndexOffset)
|
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)
|
require.Equal(t, time.Unix(0, 0).UTC(), info.JailedUntil)
|
||||||
|
|
||||||
// validator should be bonded still, should not have been jailed or slashed
|
// validator should be bonded still, should not have been jailed or slashed
|
||||||
|
|
|
@ -48,12 +48,12 @@ func (k Keeper) setValidatorSigningBitArray(ctx sdk.Context, address sdk.ConsAdd
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct a new `ValidatorSigningInfo` struct
|
// 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{
|
return ValidatorSigningInfo{
|
||||||
StartHeight: startHeight,
|
StartHeight: startHeight,
|
||||||
IndexOffset: indexOffset,
|
IndexOffset: indexOffset,
|
||||||
JailedUntil: jailedUntil,
|
JailedUntil: jailedUntil,
|
||||||
SignedBlocksCounter: signedBlocksCounter,
|
MissedBlocksCounter: missedBlocksCounter,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,11 +62,11 @@ type ValidatorSigningInfo struct {
|
||||||
StartHeight int64 `json:"start_height"` // height at which validator was first a candidate OR was unjailed
|
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
|
IndexOffset int64 `json:"index_offset"` // index offset into signed block bit array
|
||||||
JailedUntil time.Time `json:"jailed_until"` // timestamp validator cannot be unjailed until
|
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)
|
MissedBlocksCounter int64 `json:"misseded_blocks_counter"` // missed blocks counter (to avoid scanning the array every time)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return human readable signing info
|
// Return human readable signing info
|
||||||
func (i ValidatorSigningInfo) HumanReadableString() string {
|
func (i ValidatorSigningInfo) HumanReadableString() string {
|
||||||
return fmt.Sprintf("Start height: %d, index offset: %d, jailed until: %v, signed blocks counter: %d",
|
return fmt.Sprintf("Start height: %d, index offset: %d, jailed until: %v, missed blocks counter: %d",
|
||||||
i.StartHeight, i.IndexOffset, i.JailedUntil, i.SignedBlocksCounter)
|
i.StartHeight, i.IndexOffset, i.JailedUntil, i.MissedBlocksCounter)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ func TestGetSetValidatorSigningInfo(t *testing.T) {
|
||||||
StartHeight: int64(4),
|
StartHeight: int64(4),
|
||||||
IndexOffset: int64(3),
|
IndexOffset: int64(3),
|
||||||
JailedUntil: time.Unix(2, 0),
|
JailedUntil: time.Unix(2, 0),
|
||||||
SignedBlocksCounter: int64(10),
|
MissedBlocksCounter: int64(10),
|
||||||
}
|
}
|
||||||
keeper.setValidatorSigningInfo(ctx, sdk.ConsAddress(addrs[0]), newInfo)
|
keeper.setValidatorSigningInfo(ctx, sdk.ConsAddress(addrs[0]), newInfo)
|
||||||
info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(addrs[0]))
|
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.StartHeight, int64(4))
|
||||||
require.Equal(t, info.IndexOffset, int64(3))
|
require.Equal(t, info.IndexOffset, int64(3))
|
||||||
require.Equal(t, info.JailedUntil, time.Unix(2, 0).UTC())
|
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) {
|
func TestGetSetValidatorSigningBitArray(t *testing.T) {
|
||||||
ctx, _, _, _, keeper := createTestInput(t)
|
ctx, _, _, _, keeper := createTestInput(t)
|
||||||
signed := keeper.getValidatorSigningBitArray(ctx, sdk.ConsAddress(addrs[0]), 0)
|
missed := keeper.getValidatorSigningBitArray(ctx, sdk.ConsAddress(addrs[0]), 0)
|
||||||
require.False(t, signed) // treat empty key as unsigned
|
require.False(t, missed) // treat empty key as not missed
|
||||||
keeper.setValidatorSigningBitArray(ctx, sdk.ConsAddress(addrs[0]), 0, true)
|
keeper.setValidatorSigningBitArray(ctx, sdk.ConsAddress(addrs[0]), 0, true)
|
||||||
signed = keeper.getValidatorSigningBitArray(ctx, sdk.ConsAddress(addrs[0]), 0)
|
missed = keeper.getValidatorSigningBitArray(ctx, sdk.ConsAddress(addrs[0]), 0)
|
||||||
require.True(t, signed) // now should be signed
|
require.True(t, missed) // now should be missed
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ func TestBeginBlocker(t *testing.T) {
|
||||||
require.Equal(t, ctx.BlockHeight(), info.StartHeight)
|
require.Equal(t, ctx.BlockHeight(), info.StartHeight)
|
||||||
require.Equal(t, int64(1), info.IndexOffset)
|
require.Equal(t, int64(1), info.IndexOffset)
|
||||||
require.Equal(t, time.Unix(0, 0).UTC(), info.JailedUntil)
|
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)
|
height := int64(0)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue