cosmos-sdk/x/staking/spec/02_state_transitions.md

6.1 KiB

State Transitions

This document describes the state transition operations pertaining to:

  1. Validators
  2. Delegations
  3. Slashing

Validators

State transitions in validators are performed on every EndBlock in order to check for changes in the active ValidatorSet.

Unbonded to Bonded

The following transition occurs when a validator's ranking in the ValidatorPowerIndex surpasses that of the LastValidator.

  • set validator.Status to Bonded
  • send the validator.Tokens from the NotBondedTokens to the BondedPool ModuleAccount
  • delete the existing record from ValidatorByPowerIndex
  • add a new updated record to the ValidatorByPowerIndex
  • update the Validator object for this validator
  • if it exists, delete any ValidatorQueue record for this validator

Bonded to Unbonding

When a validator begins the unbonding process the following operations occur:

  • send the validator.Tokens from the BondedPool to the NotBondedTokens ModuleAccount
  • set validator.Status to Unbonding
  • delete the existing record from ValidatorByPowerIndex
  • add a new updated record to the ValidatorByPowerIndex
  • update the Validator object for this validator
  • insert a new record into the ValidatorQueue for this validator

Unbonding to Unbonded

A validator moves from unbonding to unbonded when the ValidatorQueue object moves from bonded to unbonded

  • update the Validator object for this validator
  • set validator.Status to Unbonded

Jail/Unjail

when a validator is jailed it is effectively removed from the Tendermint set. this process may be also be reversed. the following operations occur:

  • set Validator.Jailed and update object
  • if jailed delete record from ValidatorByPowerIndex
  • if unjailed add record to ValidatorByPowerIndex

Delegations

Delegate

When a delegation occurs both the validator and the delegation objects are affected

  • determine the delegators shares based on tokens delegated and the validator's exchange rate
  • remove tokens from the sending account
  • add shares the delegation object or add them to a created validator object
  • add new delegator shares and update the Validator object
  • transfer the delegation.Amount from the delegator's account to the BondedPool or the NotBondedPool ModuleAccount depending if the validator.Status is Bonded or not
  • delete the existing record from ValidatorByPowerIndex
  • add an new updated record to the ValidatorByPowerIndex

Begin Unbonding

As a part of the Undelegate and Complete Unbonding state transitions Unbond Delegation may be called.

  • subtract the unbonded shares from delegator
  • if the validator is Unbonding or Bonded add the tokens to an UnbondingDelegation Entry
  • if the validator is Unbonded send the tokens directly to the withdraw account
  • update the delegation or remove the delegation if there are no more shares
  • if the delegation is the operator of the validator and no more shares exist then trigger a jail validator
  • update the validator with removed the delegator shares and associated coins
  • if the validator state is Bonded, transfer the Coins worth of the unbonded shares from the BondedPool to the NotBondedPool ModuleAccount
  • remove the validator if it is unbonded and there are no more delegation shares.

Complete Unbonding

For undelegations which do not complete immediately, the following operations occur when the unbonding delegation queue element matures:

  • remove the entry from the UnbondingDelegation object
  • transfer the tokens from the NotBondedPool ModuleAccount to the delegator Account

Begin Redelegation

Redelegations affect the delegation, source and destination validators.

  • perform an unbond delegation from the source validator to retrieve the tokens worth of the unbonded shares
  • using the unbonded tokens, Delegate them to the destination validator
  • if the sourceValidator.Status is Bonded, and the destinationValidator is not, transfer the newly delegated tokens from the BondedPool to the NotBondedPool ModuleAccount
  • otherwise, if the sourceValidator.Status is not Bonded, and the destinationValidator is Bonded, transfer the newly delegated tokens from the NotBondedPool to the BondedPool ModuleAccount
  • record the token amount in an new entry in the relevant Redelegation

Complete Redelegation

When a redelegations complete the following occurs:

  • remove the entry from the Redelegation object

Slashing

Slash Validator

When a Validator is slashed, the following occurs:

  • The total slashAmount is calculated as the slashFactor (a chain parameter) * TokensFromConsensusPower, the total number of tokens bonded to the validator at the time of the infraction.
  • Every unbonding delegation and redelegation from the validator are slashed by the slashFactor percentage of the initialBalance.
  • Each amount slashed from redelegations and unbonding delegations is subtracted from the total slash amount.
  • The remaingSlashAmount is then slashed from the validator's tokens in the BondedPool or NonBondedPool depending on the validator's status. This reduces the total supply of tokens.

Slash Unbonding Delegation

When a validator is slashed, so are those unbonding delegations from the validator that began unbonding after the time of the infraction. Every entry in every unbonding delegation from the validator is slashed by slashFactor. The amount slashed is calculated from the InitialBalance of the delegation and is capped to prevent a resulting negative balance. Completed (or mature) unbondings are not slashed.

Slash Redelegation

When a validator is slashed, so are all redelegations from the validator that began after the infraction. Redelegations are slashed by slashFactor. The amount slashed is calculated from the InitialBalance of the delegation and is capped to prevent a resulting negative balance. Mature redelegations are not slashed.