Skip to content

Slashing Notes

Yang SONG edited this page Dec 15, 2021 · 4 revisions

Slashing Notes

Slashing Due To Evidence Submitted

There are two ways that eveidence been handled.

  1. Submit through a MsgSubmitEvidence. (It seems our chain-main does not register the route for handling this Msg)
  2. Tendermint submit evidence to BeginBlocker().

In both way, the evidence should be handled by x/evidence/keeper/infraction.go HandleEquivocationEvidence().

Slashing Due To Missing Validator Signature

Slashing is triggered due to missing validator signatures in multiple blocks (maybe due to validator is down).

https://github.com/cosmos/cosmos-sdk/blob/314e1d52c248e61847e0d78be165fc9d843ef812/x/slashing/keeper/infractions.go#L87

General Picture of Evidence Submitted: BeginBlocker()

This section targets to give a general picture of the execution stack when evidence is submitted.

x/evidence/abci.go BeginBlocker()

https://github.com/cosmos/cosmos-sdk/blob/314e1d52c248e61847e0d78be165fc9d843ef812/x/evidence/abci.go#L17

Main Logic: Slash()

The most important logic is in this function. Validator token balance changes also happens here.

x/staking/keeper/slash.go Slash()

https://github.com/cosmos/cosmos-sdk/blob/314e1d52c248e61847e0d78be165fc9d843ef812/x/staking/keeper/slash.go#L24

Be aware of the inputs:

  • power is from the infraction height
  • infractionHeight is in fact, 1 block ahead of the infration height

Major steps

  1. Calculate slash amount based on power at infration height, let's call it TotalSlash.

  2. Get Validator from store.

  3. If input infrationHeight < currentBlockHeight, loop through UnbondingDelegation and Redelegation on that validator.

  1. Calculate total amount slashed on the UnbondingDelegation and Redelegation entries, let's call it SlashOnX.

  2. Removed tokens from Validator.Tokens.

  • The real amount removed from Validator.Tokens is SlashOnValidator = TotalSlash - SlashOnX.
  1. SlashOnValidator tokens are burned from module accounts (NotBondedPool, BondedPool). The total supply is decreased.

  2. SlashOnValidator is returned and later, wrapped in slash event.

Difficulty of Getting the Slash Amount on Redelegation Destination Validator

When a slash event is detected, it includes the amount of tokens slashed on the validator that committed the misbehavior, which is good.

Slashed on UnbindingDelegation (Undelegation) is also fine, as it will not affect any validator's balance.

Problem

But the problem is on Redelegation.

Say if a user do a redelegation from Validator A to Validator B.

Before the redelegation, the Validator A committed a misbehavior (let's say double sign two blocks).

Then when the evidence on this misbehavior is committed, Validator B will also be slashed. And there is no message or event indicating the amount of tokens slashed on Validator B.

A Brute Force Solution

https://github.com/cosmos/cosmos-sdk/blob/314e1d52c248e61847e0d78be165fc9d843ef812/x/staking/keeper/slash.go#L220

To calculate the slash amount on redelegation destination validator, on our indexing server, we need track many things:

  • We need to keep track of all Redelegation entries, which is to find the destination validator and to calculate the shares to slash.
  • We need to keep track of all Delegation entries.
  • We need to keep track of all Validator entries, so that we could convert the shares to real amount of tokens to slash.

The last part is not a good news for us.

  • If we assume the blocks come in a ordered manner, then it is fine.
  • But if we want to scale the projections, multiple goroutine running in parallel, it will be impossible. As at the moment of calculating the slash amount on destination validator, you need to know the tokens balance of validator before the slashing.