Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Slashing for equivocation

Proofs stop invalid state transitions. They do not stop a validator from signing two conflicting messages, which is how a Byzantine third of a committee certifies two conflicting histories. Equivocation leaves signed evidence, so it can be punished: anyone who holds the two messages reports them, the offender forfeits its whole stake, and the reporter is paid a share.

The evidence

ReportEquivocation { evidence } (specification §5.30) carries one of two kinds of evidence. Signatures are checked with the keys the validator set records for the signer.

EvidenceWhat it showsConditions
Headers { first, second }Two consensus headers by one author for the same roundSame author, chain, epoch, shard and round; different digests; both signatures verify
Approvals { first, second }Two lane approvals by one validator for two transactions that spend the same object versionSame validator, chain, epoch and shard; different transactions sharing an input (id, version); both transactions unexpired at the reporting Pulse; both approvals verify

An honest validator approves a second spend of an object version only once the first transaction can no longer execute: it succeeded or failed, which moves every input it names to a new version, or it expired. So two approvals of live transactions are proof; once either transaction has expired, the evidence no longer counts.

A rejected transaction is the case to watch. It wrote nothing, so its inputs keep their versions, and it may still execute later. The node therefore keeps its locks until it expires, and refuses a second spend of its inputs until then. Releasing them at the rejection, as the reference node did before an independent review found it, let an owner frame honest validators: get a transaction rejected by spending one of its other inputs elsewhere, then spend the rest again and report every validator that approved both (Security reviews).

The penalty

If the evidence holds and the offender is neither already slashed nor withdrawn:

  1. Its whole stake and its unclaimed rewards are forfeited, and its status becomes Slashed.
  2. If it has a pool of delegated stake, the pool loses a tenth of its stake, unbonding delegations included (Pooled stake).
  3. The reporter receives reporter_permille thousandths of the offender’s own stake and of its rewards (5 % on the devnet), never of its pool’s slashed tenth, which goes to the treasury whole: a share of it would let an operator with a large enough pool profit from reporting itself.
  4. The rest goes to the treasury. It is not a fee, so it is never paid out as rewards (Rewards).
  5. The events ValidatorSlashed { validator, amount, reporter, reward } and, with a pool, PoolSlashed { validator, amount } are emitted.

The reporter’s share is small on purpose: a validator that reports itself to recover its stake still loses 95 % of it.

The offender keeps its seat, and its weight in quorums, until the epoch ends; at the boundary it is not Active, so it leaves the active set (impl:slashed-seat), even if no other validator is eligible. A chain whose every eligible validator was slashed then halts (Epochs). An Exited validator still waiting out its unbonding period can be slashed; a Withdrawn one has nothing left to slash.

Evidence is not bound to a chain or a time

The two messages must agree with each other on the chain, but nothing requires that chain to be this one, and header evidence never expires. An offence is an offence wherever it was signed. So an operator must not use a validator’s keys on more than one network: an equivocation on a test network, where it costs nothing, would slash the stake here (impl:evidence-scope).

Who reports

Anyone with the two signed messages. A validator that receives two headers from one author for one round logs the offender (validator <i> detected Byzantine behavior by …), but it does not submit the report itself. In the staking demo, an account called watchdog does.

On the devnet

sion demo staking --local makes the newcomer equivocate. This is an adversary simulation: the demo signs two headers with the validator’s devnet keys, which anyone can derive.

           ADVERSARY SIMULATION: validator a6f32863 signs two different consensus headers for the same round
Pulse  31  watchdog reports both signed headers: Done: validator a6f32863 slashed: 50,000 USD forfeited, 2,500 USD of it to watchdog for the report; fee 0.005 USD.
           epoch 2 begins with 4 validators: the slashed validator lost its seat
           light client: still following, 2 boundary proof(s) from the pinned genesis ✓
Result: who certifies is part of the state transition, proven like any balance; stake buys seats, misbehaviour is evidence anyone can submit, and a client needs nothing but the genesis it pinned.

When a report is refused

SituationReason
Two headers with different authors, chains, epochs, shards or roundsthe headers are not for the same author and round
The same header twicethe headers are the same
A header signature failsa header signature does not verify
Two approvals by different validators, chains, epochs or shardsthe approvals are not by the same validator
The same transaction twicethe approvals are of the same transaction
One of the transactions has expiredan approved transaction has expired
No shared input versionthe transactions spend no common object version
The offender was already slashed or has withdrawnthe validator was already slashed or has withdrawn

Not covered

Equivocation is the only validator offence that can be slashed. The architecture also slashes validators that certify an invalid state transition; that is not built: a header whose World Proof fails is caught by verification, but no transaction slashes its signers. Stalling, censorship and withholding cannot be attributed to anyone, so the architecture counters them with rotation, forced inclusion and sampling instead (Censorship resistance).