x/slashing
Punishments for a validator are triggered when they either make a byzantine fault or become non-live:
- Liveness Faults (Low availability)
A validator is said to be non-live when they fail to successfully sign at least min_signed_per_window
blocks (in percentage) in the last signed_blocks_window
blocks. signed_blocks_window
and min_signed_per_window
are network parameters and can be configured during genesis and can be updated during runtime by the governance module.
For example, if block_signing_window
is 2000
blocks and min_signed_per_window
is 0.5
, a validator will be marked as non-live and jailed if they fail to successfully sign at least 2000*0.5=1000
blocks in the last 2000
blocks.
- Byzantine Faults
A validator is said to make a byzantine fault when they sign conflicting messages/blocks at the same height and round. Tendermint has mechanisms to publish evidence of validators that signed conflicting votes so they can be punished by the slashing module. For example:
Validator who votes for two different blocks within a single round ("Equivocation validator"/ "Double signing")
Validator who signs commit messages for arbitrary application state ("Lunatic validator").
The evidence of a set of validators attempting to mislead a light client can also be detected and captured. However, even the Amnesia attack can be detected, punishment can not be applied at this stage, as we can not deduce the malicious validators.
Tendermint passes Evidence
of a byzantine validator in BeginBlock
request. Before jailing any account due to byzantine fault, that evidence should be verified. Also, it should be checked that evidence provided by tendermint is not older than max_age
in tendermint.
Inactivity Slashing
It is important that the validators maintain excellent availability and network connectivity to perform their tasks. A penalty should be imposed on validators' misbehaviour to reinforce this.
When a validator fails to successfully sign missed_block_threshold
blocks in the last block_signing_window
blocks, it is immediately jailed and punished by deducting funds from their bonded and unbonded amount and removing them from the active validator set. The funds to be deducted are calculated based on slash_fraction_downtime
.
Jailing
A validator is jailed when they make liveness or Byzantine fault. When a validator is jailed, it will no longer be considered as an active validator until they are un-jailed. Futhermore, it cannot be un-jailed before downtime_jail_duration
. This downtime_jail_duration
is a network parameter which can be configured during genesis.
When a validator is jailed because of a byzantine fault, their validator public key is added to a list of permanently banned validators and cannot re-join the network as a validator with the same public key, see staking tombstone
Un-jailing
When a jailed validator wishes to resume normal operations (after downtime_jail_duration
has passed), they can create an unjail
transaction which marks them as un-jailed. Validator will then rejoin the validator set once it has been successful un-jailed.
Slashing for Byzantine Fault
When there is byzantine fault detected, they are immediately slashed other than jailed. The funds to be deducted are calculated based on slash_fraction_double_sign
. Furthermore, validators who commit this double-signing fault will also be put into the "tombstone state", which means it will be blacklisted and jailed forever.