-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
203 additions
and
127 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,54 +1,62 @@ | ||
# State | ||
|
||
## Signing Info | ||
## Signing Info (Liveness) | ||
|
||
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. | ||
Every block includes a set of precommits by the validators for the previous block, | ||
known as the `LastCommitInfo` provided by Tendermint. A `LastCommitInfo` is valid so | ||
long as it contains precommits from +2/3 of total 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)). | ||
Proposers are incentivized to include precommits from all validators in the `LastCommitInfo` | ||
by receiving additional fees proportional to the difference between the voting | ||
power included in the `LastCommitInfo` 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. | ||
Validators are penalized for failing to be included in the `LastCommitInfo` for some | ||
number of blocks by being automatically jailed, potentially slashed, and unbonded. | ||
|
||
Information about validator activity is tracked in a `ValidatorSigningInfo`. | ||
Information about validator's liveness activity is tracked through `ValidatorSigningInfo`. | ||
It is indexed in the store as follows: | ||
|
||
- SigningInfo: ` 0x01 | ValTendermintAddr -> amino(valSigningInfo)` | ||
- MissedBlocksBitArray: ` 0x02 | ValTendermintAddr | LittleEndianUint64(signArrayIndex) -> VarInt(didMiss)` | ||
- ValidatorSigningInfo: ` 0x01 | ConsAddress -> amino(valSigningInfo)` | ||
- MissedBlocksBitArray: ` 0x02 | ConsAddress | 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 missed the block for a given index in the bit-array. | ||
|
||
The index in the bit-array is given as little endian uint64. | ||
The first mapping allows us to easily lookup the recent signing info for a | ||
validator based on the validator's consensus address. The second mapping acts | ||
as a bit-array of size `SignedBlocksWindow` 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 miss (did sign) the corresponding block, and `1` indicates they missed the block (did not sign). | ||
validator did not miss (did sign) the corresponding block, and `1` indicates | ||
they missed the block (did not sign). | ||
|
||
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. | ||
Note that the `MissedBlocksBitArray` is not explicitly initialized up-front. Keys | ||
are added as we progress through the first `SignedBlocksWindow` blocks for a newly | ||
bonded validator. The `SignedBlocksWindow` parameter defines the size | ||
(number of blocks) of the sliding window used to track validator liveness. | ||
|
||
The information stored for tracking validator liveness is as follows: | ||
|
||
```go | ||
type ValidatorSigningInfo struct { | ||
StartHeight int64 // Height at which the validator became able to sign blocks | ||
IndexOffset int64 // Offset into the signed block bit array | ||
JailedUntilHeight int64 // Block height until which the validator is jailed, | ||
// or sentinel value of 0 for not jailed | ||
Tombstoned bool // Whether a validator is tombstoned or not | ||
MissedBlocksCounter int64 // Running counter of missed blocks | ||
Address sdk.ConsAddress | ||
StartHeight int64 | ||
IndexOffset int64 | ||
JailedUntil time.Time | ||
Tombstoned bool | ||
MissedBlocksCounter 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 jailed due to downtime | ||
* `Tombstoned` is set once a validator's first double sign evidence comes in | ||
* `MissedBlocksCounter` is a counter kept to avoid unnecessary array reads. `MissedBlocksBitArray.Sum() == MissedBlocksCounter` always. | ||
|
||
- __Address__: The validator's consensus address. | ||
- __StartHeight__: The height that the candidate became an active validator | ||
(with non-zero voting power). | ||
- __IndexOffset__: Index which is incremented each time the validator was a bonded | ||
in a block and may have signed a precommit or not. This in conjunction with the | ||
`SignedBlocksWindow` param determines the index in the `MissedBlocksBitArray`. | ||
- __JailedUntil__: Time for which the validator is jailed until due to liveness downtime. | ||
- __Tombstoned__: Desribes if the validator is tombstoned or not. It is set once the | ||
validator commits an equivocation or for any other configured misbehiavor. | ||
- __MissedBlocksCounter__: A counter kept to avoid unnecessary array reads. Note | ||
that `Sum(MissedBlocksBitArray)` equals `MissedBlocksCounter` always. |
Oops, something went wrong.