diff --git a/docs/spec/WIP_provisioning/state.md b/docs/spec/WIP_provisioning/state.md new file mode 100644 index 0000000000..0711b01aac --- /dev/null +++ b/docs/spec/WIP_provisioning/state.md @@ -0,0 +1,13 @@ + + +Validator + +* Adjustment factor used to passively calculate each validators entitled fees + from `GlobalState.FeePool` + +Delegation Shares + +* AdjustmentFeePool: Adjustment factor used to passively calculate each bonds + entitled fees from `GlobalState.FeePool` +* AdjustmentRewardPool: Adjustment factor used to passively calculate each + bonds entitled fees from `Validator.ProposerRewardPool` diff --git a/docs/spec/slashing/end-block.md b/docs/spec/slashing/end_block.md similarity index 60% rename from docs/spec/slashing/end-block.md rename to docs/spec/slashing/end_block.md index 840269d3ec..d86b7110b0 100644 --- a/docs/spec/slashing/end-block.md +++ b/docs/spec/slashing/end_block.md @@ -1,4 +1,4 @@ -# Validator Set Changes +# End-Block ## Slashing @@ -72,68 +72,27 @@ for redel in redels { ## Automatic Unbonding -Every block includes a set of precommits by the validators for the previous block, -known as the LastCommit. A LastCommit is valid so long as it contains precommits from +2/3 of voting power. - -Proposers are incentivized to include precommits from all -validators in the LastCommit by receiving additional fees -proportional to the difference between the voting power included in the -LastCommit and +2/3 (see [TODO](https://github.com/cosmos/cosmos-sdk/issues/967)). - -Validators are penalized for failing to be included in the LastCommit for some -number of blocks by being automatically unbonded. - -Maps: - -- map1: < prefix-info | tm val addr > -> -- map2: < prefix-bit-array | tm val addr | LE uint64 index in sign bit array > -> < signed bool > - -The following information is stored with each validator candidate, and is only non-zero if the candidate becomes an active validator: - -```go -type ValidatorSigningInfo struct { - StartHeight int64 - IndexOffset int64 - JailedUntil int64 - SignedBlocksCounter int64 -} - -``` - -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. - - -Map2 simulates a bit array - better to do the lookup rather than read/write the -bitarray every time. Size of bit-array is `SIGNED_BLOCKS_WINDOW`. It records, for each of the last `SIGNED_BLOCKS_WINDOW` blocks, -whether or not this validator was included in the LastCommit. -It sets the value to true if the validator was included and false if not. -Note it is not explicilty initialized (the keys wont exist). - At the beginning of each block, we update the signing info for each validator and check if they should be automatically unbonded: ``` height := block.Height for val in block.Validators: - signInfo = getSignInfo(val.Address) + signInfo = SigningInfo.Get(val.Address) if signInfo == nil{ signInfo.StartHeight = height } index := signInfo.IndexOffset % SIGNED_BLOCKS_WINDOW signInfo.IndexOffset++ - previous = getDidSign(val.Address, index) + previous = SigningBitArray.Get(val.Address, index) // update counter if array has changed if previous and val in block.AbsentValidators: - setDidSign(val.Address, index, false) + SigningBitArray.Set(val.Address, index, false) signInfo.SignedBlocksCounter-- else if !previous and val not in block.AbsentValidators: - setDidSign(val.Address, index, true) + SigningBitArray.Set(val.Address, index, true) signInfo.SignedBlocksCounter++ // else previous == val not in block.AbsentValidators, no change @@ -147,5 +106,5 @@ for val in block.Validators: slash & unbond the validator - setSignInfo(val.Address, signInfo) + SigningInfo.Set(val.Address, signInfo) ``` diff --git a/docs/spec/slashing/state.md b/docs/spec/slashing/state.md index 0711b01aac..1df9d5022d 100644 --- a/docs/spec/slashing/state.md +++ b/docs/spec/slashing/state.md @@ -1,13 +1,51 @@ +## State +### Signing Info -Validator +Every block includes a set of precommits by the validators for the previous block, +known as the LastCommit. A LastCommit is valid so long as it contains precommits from +2/3 of voting power. -* Adjustment factor used to passively calculate each validators entitled fees - from `GlobalState.FeePool` +Proposers are incentivized to include precommits from all +validators in the LastCommit by receiving additional fees +proportional to the difference between the voting power included in the +LastCommit and +2/3 (see [TODO](https://github.com/cosmos/cosmos-sdk/issues/967)). -Delegation Shares +Validators are penalized for failing to be included in the LastCommit for some +number of blocks by being automatically unbonded. -* AdjustmentFeePool: Adjustment factor used to passively calculate each bonds - entitled fees from `GlobalState.FeePool` -* AdjustmentRewardPool: Adjustment factor used to passively calculate each - bonds entitled fees from `Validator.ProposerRewardPool` +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)` + +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. + +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. + +Note that the SigningBitArray is not explicitly initialized up-front. Keys are +added as we progress through the first `SIGNED_BLOCKS_WINDOW` blocks for a newly +bonded validator. + +The information stored for tracking validator liveness is as follows: + +```go +type ValidatorSigningInfo struct { + StartHeight int64 + IndexOffset int64 + JailedUntil int64 + SignedBlocksCounter int64 +} + +``` + +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.