Bugfix; update slashing spec
This commit is contained in:
parent
ec53a14b57
commit
83f7a4cb7b
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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()))
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
k.setValidatorSigningInfo(ctx, address, signingInfo)
|
||||
|
||||
// Create a new slashing period when a validator is bonded
|
||||
slashingPeriod := ValidatorSlashingPeriod{
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
Loading…
Reference in New Issue