From c0487996abf709cfec6bb2b6b3bd256d1310fa3a Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 28 May 2018 23:46:08 +0200 Subject: [PATCH] Update slashing docs, slight index change --- docs/spec/staking/valset-changes.md | 18 ++++++++++++------ x/slashing/keeper.go | 2 +- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/docs/spec/staking/valset-changes.md b/docs/spec/staking/valset-changes.md index e5979af39a..0e635fd047 100644 --- a/docs/spec/staking/valset-changes.md +++ b/docs/spec/staking/valset-changes.md @@ -156,25 +156,30 @@ The following information is stored with each validator candidate, and is only n ```go type ValidatorSigningInfo struct { StartHeight int64 - SignedBlocksBitArray BitArray + IndexOffset int64 + JailedUntil int64 SignedBlocksCounter int64 + SignedBlocksBitArray BitArray } ``` Where: * `StartHeight` is set to the height that the candidate became an active validator (with non-zero voting power). +* `IndexOffset` is incremented each time the candidate was a bonded validator in a block (and may have signed a precommit or not). +* `JailedUntil` is set whenever the candidate is revoked due to downtime +* `SignedBlocksCounter` is a counter kept to avoid unnecessary array reads. `SignedBlocksBitArray.Sum() == SignedBlocksCounter` always. * `SignedBlocksBitArray` is a bit-array of size `SIGNED_BLOCKS_WINDOW` that records, for each of the last `SIGNED_BLOCKS_WINDOW` blocks, whether or not this validator was included in the LastCommit. It uses a `1` if the validator was included, and a `0` if it was not. Note it is initialized with all 0s. -* `SignedBlocksCounter` is a counter kept to avoid unnecessary array reads. `SignedBlocksBitArray.Sum() == SignedBlocksCounter` always. At the beginning of each block, we update the signing info for each validator and check if they should be automatically unbonded: ``` -h = block.Height -index = h % SIGNED_BLOCKS_WINDOW +height := block.Height for val in block.Validators: signInfo = val.SignInfo + index := signInfo.IndexOffset % SIGNED_BLOCKS_WINDOW + signInfo.IndexOffset++ previous = signInfo.SignedBlocksBitArray.Get(index) // update counter if array has changed @@ -191,6 +196,7 @@ for val in block.Validators: // included in 50% of the recent LastCommits minHeight = signInfo.StartHeight + SIGNED_BLOCKS_WINDOW minSigned = SIGNED_BLOCKS_WINDOW / 2 - if h > minHeight AND signInfo.SignedBlocksCounter < minSigned: - unbond the validator + if height > minHeight AND signInfo.SignedBlocksCounter < minSigned: + signInfo.JailedUntil = block.Time + DOWNTIME_UNBOND_DURATION + slash & unbond the validator ``` diff --git a/x/slashing/keeper.go b/x/slashing/keeper.go index c8fcbe1b92..8b0d585ec5 100644 --- a/x/slashing/keeper.go +++ b/x/slashing/keeper.go @@ -51,8 +51,8 @@ func (k Keeper) handleValidatorSignature(ctx sdk.Context, pubkey crypto.PubKey, } address := pubkey.Address() signInfo, _ := k.getValidatorSigningInfo(ctx, address) - signInfo.IndexOffset++ index := signInfo.IndexOffset % SignedBlocksWindow + signInfo.IndexOffset++ previous := k.getValidatorSigningBitArray(ctx, address, index) if previous && !signed { k.setValidatorSigningBitArray(ctx, address, index, false)