cosmos-sdk/x/evidence/spec/06_begin_block.md
Denis Fadeev 13378bd2cf Docs: hide frontmatter, bugfixes (#5413)
* encoding

* working on baseapp doc

* baseapp work

* reorg

* almost there

* finish first draft

* remove old files

* module doc start

* finish intro

* working

* workinnn

* add transactions into core

* hans comments

* add transactions into core

* working

* gautier comments

* clean

* working

* consolidate intro

* querier

* workiiiing

* refactor for new module interface

* karoly review

* working on baseapp doc

* baseapp work

* reorg

* almost there

* finish first draft

* remove old files

* finish intro

* workinnn

* initial commit after rebase

* query-lifecycle and started modules-interfaces

* query-lifecycle first draft done

* module interfaces first draft

* rest and intro skeletons

* rest and intro done

* small edits and links

* comments

* revisions

* cli.md comments

* comments

* minor edits

* better flow for query lifecycle

* add transactions into core

* hans comments

* add transactions into core

* checkout master-docs files

* deleted some

* remove modules readme

* cli.md comments

* comments

* module-interfaces comments

* Merge PR #4857: Add Context concept doc

* working

* working

* finish messages and queries

* handler

* querier

* last comments!

* punctuation

* querier2

* consolidate intro

* querier

* workiiiing

* refactor for new module interface

* karoly review

* working on baseapp doc

* baseapp work

* reorg

* almost there

* finish first draft

* remove old files

* finish intro

* workinnn

* initial commit after rebase

* query-lifecycle and started modules-interfaces

* query-lifecycle first draft done

* module interfaces first draft

* rest and intro skeletons

* rest and intro done

* small edits and links

* comments

* revisions

* cli.md comments

* comments

* minor edits

* better flow for query lifecycle

* checkout master-docs files

* deleted some

* remove modules readme

* cli.md comments

* comments

* module-interfaces comments

* keeper

* genesis

* finish

* Apply suggestions from code review

Co-Authored-By: Hans Schoenburg <hschoenburg@users.noreply.github.com>

* hans review

* Update docs/core/baseapp.md

Co-Authored-By: Hans Schoenburg <hschoenburg@users.noreply.github.com>

* working

* last comment

* workin

* Apply suggestions from code review

* encoding and node

* almost finish store

* finish docs

* fixes

* fede comments + permalinks

* hans review

* add more permalinks

* update docs theme version (#5239)

* R4R: Docs Cleanup (#5246)

* start

* work

* work

* work

* remove table of content

* links intro

* fix links

* remove junk

* cleanup

* cleanup

* work

* finish cleanup

* addback readmes

* remove nft

* fix links

* remove dup

* remove dup

* remove dup

* remove dup

* remove dup

* fix links

* add subscribe events

* refine rest

* index page

* sidebar

* theme version

* theme version

* testing netlify

* theme version

* tooltip example

* version

* testing code embedding

* reverting back

* theme version

* version

* version

* version

* readme and version

* cleanup

* redo app anatomy

* modules readme, theme version

* theme version

* fix modules list

* theme version

* new snippets

* modules readme

* update docs readme

* modify synopsis

* version

* fix yaml

* version

* version

* version

* version

* version

* version

* version

* version

* version

* version

* add hide banner

* version

* version

* version

* small fixes

* modules readme, version

* remove hotkeys dep, version

* version

* version

* version

* version

* version

* version

* version

* slight notice

* fix links and hide

* permalinks

* small clean

* version

* resolve conflicts, add google analytics

* fix merge remants

* version

* changelog 1/2

* Changelog: docs UI

* version

* remove merge conflicts

* Code: Update link for Contributing to the docs to docs_readme

* HTML/CSS: Update layout of homepage footer to match new layout in Figma

* version

* final modifs

* modules, version

* modules readme

* link to module list from homepage

* version

* building modules link

* version

* version

* fonts

* version

* version

* fix link

* fix package.json

* links in explore sdk section

* core concepts

* version

* change delimeters for frontmatter

* frontmatter in comments

* version

* temp add tiny-cookie

* fixed link issues

* fixed styling issues, copy

* hide frontmatter

* hide frontmatter

* layout fixes, padded ascii diagram

* fira sans font for code
2019-12-17 08:44:44 -03:00

3.9 KiB

BeginBlock

Evidence Handling

Tendermint blocks can include Evidence, which indicates that a validator committed malicious behavior. The relevant information is forwarded to the application as ABCI Evidence in abci.RequestBeginBlock so that the validator an be accordingly punished.

Equivocation

Currently, the evidence module only handles evidence of type Equivocation which is derived from Tendermint's ABCIEvidenceTypeDuplicateVote during BeginBlock.

For some Equivocation submitted in block to be valid, it must satisfy:

Evidence.Timestamp >= block.Timestamp - MaxEvidenceAge

Where Evidence.Timestamp is the timestamp in the block at height Evidence.Height and block.Timestamp is the current block timestamp.

If valid Equivocation evidence is included in a block, the validator's stake is reduced (slashed) by SlashFractionDoubleSign, which is defined by the x/slashing module, of what their stake was when the infraction occurred (rather than when the evidence was discovered). We want to "follow the stake", i.e. the stake which contributed to the infraction should be slashed, even if it has since been redelegated or started unbonding.

In addition, the validator is permanently jailed and tombstoned making it impossible for that validator to ever re-enter the validator set.

The Equivocation evidence is handled as follows:

func (k Keeper) HandleDoubleSign(ctx Context, evidence Equivocation) {
  consAddr := evidence.GetConsensusAddress()
  infractionHeight := evidence.GetHeight()

  // calculate the age of the evidence
  blockTime := ctx.BlockHeader().Time
  age := blockTime.Sub(evidence.GetTime())

  // reject evidence we cannot handle
  if _, err := k.slashingKeeper.GetPubkey(ctx, consAddr.Bytes()); err != nil {
    return
  }

  // reject evidence if it is too old
  if age > k.MaxEvidenceAge(ctx) {
    return
  }

  // reject evidence if the validator is already unbonded
  validator := k.stakingKeeper.ValidatorByConsAddr(ctx, consAddr)
  if validator == nil || validator.IsUnbonded() {
    return
  }

  // verify the validator has signing info in order to be slashed and tombstoned
  if ok := k.slashingKeeper.HasValidatorSigningInfo(ctx, consAddr); !ok {
    panic(...)
  }

  // reject evidence if the validator is already tombstoned
  if k.slashingKeeper.IsTombstoned(ctx, consAddr) {
    return
  }

  // We need to retrieve the stake distribution which signed the block, so we
  // subtract ValidatorUpdateDelay from the evidence height.
  // Note, that this *can* result in a negative "distributionHeight", up to
  // -ValidatorUpdateDelay, i.e. at the end of the
  // pre-genesis block (none) = at the beginning of the genesis block.
  // That's fine since this is just used to filter unbonding delegations & redelegations.
  distributionHeight := infractionHeight - sdk.ValidatorUpdateDelay

  // Slash validator. The `power` is the int64 power of the validator as provided
  // to/by Tendermint. This value is validator.Tokens as sent to Tendermint via
  // ABCI, and now received as evidence. The fraction is passed in to separately
  // to slash unbonding and rebonding delegations.
  k.slashingKeeper.Slash(ctx, consAddr, evidence.GetValidatorPower(), distributionHeight)

  // Jail the validator if not already jailed. This will begin unbonding the
  // validator if not already unbonding (tombstoned).
  if !validator.IsJailed() {
    k.slashingKeeper.Jail(ctx, consAddr)
  }

  k.slashingKeeper.JailUntil(ctx, consAddr, types.DoubleSignJailEndTime)
  k.slashingKeeper.Tombstone(ctx, consAddr)
}

Note, the slashing, jailing, and tombstoning calls are delegated through the x/slashing module which emit informative events and finally delegate calls to the x/staking module. Documentation on slashing and jailing can be found in the x/staking spec