Bugfix; update slashing spec

This commit is contained in:
Christopher Goes 2018-10-15 23:01:29 +02:00
parent ec53a14b57
commit 83f7a4cb7b
7 changed files with 25 additions and 20 deletions

View File

@ -93,14 +93,14 @@ for val in block.Validators:
index := signInfo.IndexOffset % SIGNED_BLOCKS_WINDOW
signInfo.IndexOffset++
previous = SigningBitArray.Get(val.Address, index)
previous = MissedBlockBitArray.Get(val.Address, index)
// update counter if array has changed
if !previous and val in block.AbsentValidators:
SigningBitArray.Set(val.Address, index, true)
MissedBlockBitArray.Set(val.Address, index, true)
signInfo.MissedBlocksCounter++
else if previous and val not in block.AbsentValidators:
SigningBitArray.Set(val.Address, index, false)
MissedBlockBitArray.Set(val.Address, index, false)
signInfo.MissedBlocksCounter--
// else previous == val not in block.AbsentValidators, no change
@ -111,7 +111,9 @@ for val in block.Validators:
maxMissed = SIGNED_BLOCKS_WINDOW / 2
if height > minHeight AND signInfo.MissedBlocksCounter > maxMissed:
signInfo.JailedUntil = block.Time + DOWNTIME_UNBOND_DURATION
signInfo.IndexOffset = 0
signInfo.MissedBlocksCounter = 0
clearMissedBlockBitArray()
slash & unbond the validator
SigningInfo.Set(val.Address, signInfo)

View File

@ -12,6 +12,17 @@ and `SlashedSoFar` of `0`:
```
onValidatorBonded(address sdk.ValAddress)
signingInfo, found = getValidatorSigningInfo(address)
if !found {
signingInfo = ValidatorSigningInfo {
StartHeight : CurrentHeight,
IndexOffset : 0,
JailedUntil : time.Unix(0, 0),
MissedBloskCounter : 0
}
setValidatorSigningInfo(signingInfo)
}
slashingPeriod = SlashingPeriod{
ValidatorAddr : address,
StartHeight : CurrentHeight,

View File

@ -17,18 +17,18 @@ Information about validator activity is tracked in a `ValidatorSigningInfo`.
It is indexed in the store as follows:
- SigningInfo: ` 0x01 | ValTendermintAddr -> amino(valSigningInfo)`
- SigningBitArray: ` 0x02 | ValTendermintAddr | LittleEndianUint64(signArrayIndex) -> VarInt(didSign)`
- MissedBlocksBitArray: ` 0x02 | ValTendermintAddr | LittleEndianUint64(signArrayIndex) -> VarInt(didMiss)`
The first map allows us to easily lookup the recent signing info for a
validator, according to the Tendermint validator address. The second map acts as
a bit-array of size `SIGNED_BLOCKS_WINDOW` that tells us if the validator signed for a given index in the bit-array.
a bit-array of size `SIGNED_BLOCKS_WINDOW` that tells us if the validator missed the block for a given index in the bit-array.
The index in the bit-array is given as little endian uint64.
The result is a `varint` that takes on `0` or `1`, where `0` indicates the
validator did not sign the corresponding block, and `1` indicates they did.
validator did not miss (did sign) the corresponding block, and `1` indicates they missed the block (did not sign).
Note that the SigningBitArray is not explicitly initialized up-front. Keys are
Note that the MissedBlocksBitArray is not explicitly initialized up-front. Keys are
added as we progress through the first `SIGNED_BLOCKS_WINDOW` blocks for a newly
bonded validator.

View File

@ -25,10 +25,6 @@ handleMsgUnjail(tx TxUnjail)
if block time < info.JailedUntil
fail with "Validator still jailed, cannot unjail until period has expired"
// Update the start height so the validator won't be immediately unbonded again
info.StartHeight = BlockHeight
setValidatorSigningInfo(info)
validator.Jailed = false
setValidator(validator)

View File

@ -46,11 +46,7 @@ func handleMsgUnjail(ctx sdk.Context, msg MsgUnjail, k Keeper) sdk.Result {
return ErrValidatorJailed(k.codespace).Result()
}
// update the starting height so the validator can't be immediately jailed
// again
info.StartHeight = ctx.BlockHeight()
k.setValidatorSigningInfo(ctx, consAddr, info)
// unjail the validator
k.validatorSet.Unjail(ctx, consAddr)
tags := sdk.NewTags("action", []byte("unjail"), "validator", []byte(msg.ValidatorAddr.String()))

View File

@ -16,8 +16,8 @@ func (k Keeper) onValidatorBonded(ctx sdk.Context, address sdk.ConsAddress) {
JailedUntil: time.Unix(0, 0),
MissedBlocksCounter: 0,
}
}
k.setValidatorSigningInfo(ctx, address, signingInfo)
}
// Create a new slashing period when a validator is bonded
slashingPeriod := ValidatorSlashingPeriod{

View File

@ -245,10 +245,10 @@ func TestHandleAbsentValidator(t *testing.T) {
pool = sk.GetPool(ctx)
require.Equal(t, amtInt-slashAmt-secondSlashAmt, pool.BondedTokens.RoundInt64())
// validator start height should have been changed
// validator start height should not have been changed
info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address()))
require.True(t, found)
require.Equal(t, height, info.StartHeight)
require.Equal(t, int64(0), info.StartHeight)
// we've missed 2 blocks more than the maximum, so the counter was reset to 0 at 1 block more and is now 1
require.Equal(t, int64(1), info.MissedBlocksCounter)