cosmos-sdk/docs/spec/slashing/state.md

81 lines
3.9 KiB
Markdown
Raw Normal View History

2018-08-20 09:28:40 -07:00
# State
2018-05-23 12:42:37 -07:00
2018-08-20 09:28:40 -07:00
## Signing Info
2018-05-23 12:42:37 -07:00
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.
2018-05-23 12:42:37 -07:00
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)).
2018-05-23 12:42:37 -07:00
Validators are penalized for failing to be included in the LastCommit for some
number of blocks by being automatically unbonded.
2018-05-23 12:42:37 -07:00
Information about validator activity is tracked in a `ValidatorSigningInfo`.
It is indexed in the store as follows:
- SigningInfo: ` 0x01 | ValTendermintAddr -> amino(valSigningInfo)`
2018-10-15 14:01:29 -07:00
- 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
2018-10-15 14:01:29 -07:00
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
2018-10-15 14:01:29 -07:00
validator did not miss (did sign) the corresponding block, and `1` indicates they missed the block (did not sign).
2018-10-15 14:01:29 -07:00
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.
The information stored for tracking validator liveness is as follows:
```go
type ValidatorSigningInfo struct {
2018-08-13 06:48:23 -07:00
StartHeight int64 // Height at which the validator became able to sign blocks
IndexOffset int64 // Offset into the signed block bit array
2018-08-14 02:31:39 -07:00
JailedUntilHeight int64 // Block height until which the validator is jailed,
2018-08-13 06:48:23 -07:00
// or sentinel value of 0 for not jailed
2018-10-11 16:04:57 -07:00
MissedBlocksCounter int64 // Running counter of missed blocks
}
```
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).
2018-08-22 08:56:13 -07:00
* `JailedUntil` is set whenever the candidate is jailed due to downtime
2018-10-11 16:04:57 -07:00
* `MissedBlocksCounter` is a counter kept to avoid unnecessary array reads. `MissedBlocksBitArray.Sum() == MissedBlocksCounter` always.
2018-08-13 06:48:23 -07:00
2018-08-20 09:28:40 -07:00
## Slashing Period
2018-08-13 06:48:23 -07:00
2018-08-14 02:31:39 -07:00
A slashing period is a start and end block height associated with a particular validator,
2018-08-23 04:43:01 -07:00
within which only the "worst infraction counts" (see the [Overview](overview.md)): the total
amount of slashing for infractions committed within the period (and discovered whenever) is
capped at the penalty for the worst offense.
2018-08-13 06:48:23 -07:00
This period starts when a validator is first bonded and ends when a validator is slashed & jailed
2018-08-14 09:04:32 -07:00
for any reason. When the validator rejoins the validator set (perhaps through unjailing themselves,
and perhaps also changing signing keys), they enter into a new period.
2018-08-13 06:48:23 -07:00
Slashing periods are indexed in the store as follows:
2018-08-13 08:52:58 -07:00
- SlashingPeriod: ` 0x03 | ValTendermintAddr | StartHeight -> amino(slashingPeriod) `
2018-08-13 06:48:23 -07:00
2018-08-14 02:31:39 -07:00
This allows us to look up slashing period by a validator's address, the only lookup necessary,
2018-08-13 08:52:58 -07:00
and iterate over start height to efficiently retrieve the most recent slashing period(s)
or those beginning after a given height.
2018-08-13 06:48:23 -07:00
```go
type SlashingPeriod struct {
ValidatorAddr sdk.ValAddress // Tendermint address of the validator
StartHeight int64 // Block height at which slashing period begin
EndHeight int64 // Block height at which slashing period ended
SlashedSoFar sdk.Rat // Fraction slashed so far, cumulative
2018-08-13 06:48:23 -07:00
}
```