evidence

package
v100.0.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 3, 2024 License: Apache-2.0 Imports: 19 Imported by: 0

Documentation

Overview

Package evidence handles all evidence storage and gossiping from detection to block proposal. For the different types of evidence refer to the `evidence.go` file in the types package or https://github.com/KYVENetwork/cometbft/v100/blob/main/spec/consensus/light-client/accountability.md.

Gossiping

The core functionality begins with the evidence reactor (see reactor. go) which operates both the sending and receiving of evidence.

The `Receive` function takes a list of evidence and does the following:

1. Checks that it does not already have the evidence stored

2. Verifies the evidence against the node's state (see state/validation.go#VerifyEvidence)

3. Stores the evidence to a db and a concurrent list

The gossiping of evidence is initiated when a peer is added which starts a go routine to broadcast currently uncommitted evidence at intervals of 60 seconds (set by the by broadcastEvidenceIntervalS). It uses a concurrent list to store the evidence and before sending verifies that each evidence is still valid in the sense that it has not exceeded the max evidence age and height (see types/params.go#EvidenceParams).

There are two buckets that evidence can be stored in: Pending & Committed.

1. Pending is awaiting to be committed (evidence is usually broadcasted then)

2. Committed is for those already on the block and is to ensure that evidence isn't submitted twice

All evidence is proto encoded to disk.

Proposing

When a new block is being proposed (in state/execution.go#CreateProposalBlock), `PendingEvidence(maxBytes)` is called to send up to the maxBytes of uncommitted evidence, from the evidence store, prioritized in order of age. All evidence is checked for expiration.

When a node receives evidence in a block it will use the evidence module as a cache first to see if it has already verified the evidence before trying to verify it again.

Once the proposed evidence is submitted, the evidence is marked as committed and is moved from the broadcasted set to the committed set. As a result it is also removed from the concurrent list so that it is no longer gossiped.

Minor Functionality

As all evidence (including POLC's) are bounded by an expiration date, those that exceed this are no longer needed and hence pruned. Currently, only committed evidence in which a marker to the height that the evidence was committed and hence very small is saved. All updates are made from the `Update(block, state)` function which should be called when a new block is committed.

Index

Constants

View Source
const (
	EvidenceChannel = byte(0x38)
)

Variables

View Source
var (
	ErrEvidenceAlreadyCommitted = errors.New("evidence was already committed")
	ErrDuplicateEvidence        = errors.New("duplicate evidence")
)

Functions

func IsEvidenceExpired

func IsEvidenceExpired(heightNow int64, timeNow time.Time, heightEv int64, timeEv time.Time, evidenceParams types.EvidenceParams) bool

check that the evidence hasn't expired.

func VerifyDuplicateVote

func VerifyDuplicateVote(e *types.DuplicateVoteEvidence, chainID string, valSet *types.ValidatorSet) error

VerifyDuplicateVote verifies DuplicateVoteEvidence against the state of full node. This involves the following checks:

  • the validator is in the validator set at the height of the evidence
  • the height, round, type and validator address of the votes must be the same
  • the block ID's must be different
  • The signatures must both be valid

func VerifyLightClientAttack

func VerifyLightClientAttack(
	e *types.LightClientAttackEvidence,
	commonHeader, trustedHeader *types.SignedHeader,
	commonVals *types.ValidatorSet,
) error

VerifyLightClientAttack verifies LightClientAttackEvidence against the state of the full node. This involves the following checks:

  • the common header from the full node has at least 1/3 voting power which is also present in the conflicting header's commit
  • 2/3+ of the conflicting validator set correctly signed the conflicting block
  • the nodes trusted header at the same height as the conflicting header has a different hash
  • all signatures must be checked as this will be used as evidence

CONTRACT: must run ValidateBasic() on the evidence before verifying

must check that the evidence has not expired (i.e. is outside the maximum age threshold)

Types

type BlockStore

type BlockStore interface {
	LoadBlockMeta(height int64) *types.BlockMeta
	LoadBlockCommit(height int64) *types.Commit
	Height() int64
}

type ErrAddressNotValidatorAtHeight

type ErrAddressNotValidatorAtHeight struct {
	Address bytes.HexBytes
	Height  int64
}

func (ErrAddressNotValidatorAtHeight) Error

type ErrConflictingBlock

type ErrConflictingBlock struct {
	ConflictingBlockError error
}

func (ErrConflictingBlock) Error

func (e ErrConflictingBlock) Error() string

type ErrDuplicateEvidenceHRTMismatch

type ErrDuplicateEvidenceHRTMismatch struct {
	VoteA types.Vote
	VoteB types.Vote
}

ErrDuplicateEvidenceHRTMismatch is returned when double sign evidence's votes are not from the same height, round or type.

func (ErrDuplicateEvidenceHRTMismatch) Error

type ErrInvalidEvidence

type ErrInvalidEvidence struct {
	EvidenceError error
}

func (ErrInvalidEvidence) Error

func (e ErrInvalidEvidence) Error() string

type ErrInvalidEvidenceValidators

type ErrInvalidEvidenceValidators struct {
	ValError error
}

ErrInvalidEvidenceValidators is returned when evidence validation spots an error related to validator set.

func (ErrInvalidEvidenceValidators) Error

func (ErrInvalidEvidenceValidators) Unwrap

type ErrNoCommitAtHeight

type ErrNoCommitAtHeight struct {
	Height int64
}

func (ErrNoCommitAtHeight) Error

func (e ErrNoCommitAtHeight) Error() string

type ErrNoHeaderAtHeight

type ErrNoHeaderAtHeight struct {
	Height int64
}

func (ErrNoHeaderAtHeight) Error

func (e ErrNoHeaderAtHeight) Error() string

type ErrSameBlockIDs

type ErrSameBlockIDs struct {
	BlockID types.BlockID
}

ErrSameBlockIDs is returned if a duplicate vote evidence has votes from the same block id (should be different).

func (ErrSameBlockIDs) Error

func (e ErrSameBlockIDs) Error() string

type ErrUnrecognizedEvidenceType

type ErrUnrecognizedEvidenceType struct {
	Evidence types.Evidence
}

func (ErrUnrecognizedEvidenceType) Error

type ErrValidatorAddressesDoNotMatch

type ErrValidatorAddressesDoNotMatch struct {
	ValidatorA bytes.HexBytes
	ValidatorB bytes.HexBytes
}

ErrValidatorAddressesDoNotMatch is returned when provided DuplicateVoteEvidence's votes have different validators as signers.

func (ErrValidatorAddressesDoNotMatch) Error

type ErrVotingPowerDoesNotMatch

type ErrVotingPowerDoesNotMatch struct {
	TrustedVotingPower  int64
	EvidenceVotingPower int64
}

ErrVotingPowerDoesNotMatch is returned when voting power from trusted validator set does not match voting power from evidence.

func (ErrVotingPowerDoesNotMatch) Error

type KeyLayout

type KeyLayout interface {
	CalcKeyCommitted(evidence types.Evidence) []byte

	CalcKeyPending(evidence types.Evidence) []byte

	PrefixToBytesPending() []byte

	PrefixToBytesCommitted() []byte
}

type PeerState

type PeerState interface {
	GetHeight() int64
}

PeerState describes the state of a peer.

type Pool

type Pool struct {
	// contains filtered or unexported fields
}

Pool maintains a pool of valid evidence to be broadcasted and committed.

func NewPool

func NewPool(evidenceDB dbm.DB, stateDB sm.Store, blockStore BlockStore, options ...PoolOptions) (*Pool, error)

NewPool creates an evidence pool. If using an existing evidence store, it will add all pending evidence to the concurrent list.

func (*Pool) AddEvidence

func (evpool *Pool) AddEvidence(ev types.Evidence) error

AddEvidence checks the evidence is valid and adds it to the pool.

func (*Pool) CheckEvidence

func (evpool *Pool) CheckEvidence(evList types.EvidenceList) error

CheckEvidence takes an array of evidence from a block and verifies all the evidence there. If it has already verified the evidence then it jumps to the next one. It ensures that no evidence has already been committed or is being proposed twice. It also adds any evidence that it doesn't currently have so that it can quickly form ABCI Evidence later.

func (*Pool) Close

func (evpool *Pool) Close() error

func (*Pool) EvidenceFront

func (evpool *Pool) EvidenceFront() *clist.CElement

EvidenceFront goes to the first evidence in the clist.

func (*Pool) EvidenceWaitChan

func (evpool *Pool) EvidenceWaitChan() <-chan struct{}

EvidenceWaitChan is a channel that closes once the first evidence in the list is there. i.e Front is not nil.

func (*Pool) PendingEvidence

func (evpool *Pool) PendingEvidence(maxBytes int64) ([]types.Evidence, int64)

PendingEvidence is used primarily as part of block proposal and returns up to maxNum of uncommitted evidence.

func (*Pool) ReportConflictingVotes

func (evpool *Pool) ReportConflictingVotes(voteA, voteB *types.Vote)

ReportConflictingVotes takes two conflicting votes and forms duplicate vote evidence, adding it eventually to the evidence pool.

Duplicate vote attacks happen before the block is committed and the timestamp is finalized, thus the evidence pool holds these votes in a buffer, forming the evidence from them once consensus at that height has been reached and `Update()` with the new state called.

Votes are not verified.

func (*Pool) SetLogger

func (evpool *Pool) SetLogger(l log.Logger)

SetLogger sets the Logger.

func (*Pool) Size

func (evpool *Pool) Size() uint32

Size returns the number of evidence in the pool.

func (*Pool) State

func (evpool *Pool) State() sm.State

State returns the current state of the evpool.

func (*Pool) Update

func (evpool *Pool) Update(state sm.State, ev types.EvidenceList)

Update takes both the new state and the evidence committed at that height and performs the following operations:

  1. Take any conflicting votes from consensus and use the state's LastBlockTime to form DuplicateVoteEvidence and add it to the pool.
  2. Update the pool's state which contains evidence params relating to expiry.
  3. Moves pending evidence that has now been committed into the committed pool.
  4. Removes any expired evidence based on both height and time.

type PoolOptions

type PoolOptions func(*Pool)

func WithDBKeyLayout

func WithDBKeyLayout(dbKeyLayoutV string) PoolOptions

WithCompaction sets the compaciton parameters.

type Reactor

type Reactor struct {
	p2p.BaseReactor
	// contains filtered or unexported fields
}

Reactor handles evpool evidence broadcasting amongst peers.

func NewReactor

func NewReactor(evpool *Pool) *Reactor

NewReactor returns a new Reactor with the given config and evpool.

func (*Reactor) AddPeer

func (evR *Reactor) AddPeer(peer p2p.Peer)

AddPeer implements Reactor.

func (*Reactor) GetChannels

func (*Reactor) GetChannels() []*p2p.ChannelDescriptor

GetChannels implements Reactor. It returns the list of channels for this reactor.

func (*Reactor) Receive

func (evR *Reactor) Receive(e p2p.Envelope)

Receive implements Reactor. It adds any received evidence to the evpool.

func (*Reactor) SetEventBus

func (evR *Reactor) SetEventBus(b *types.EventBus)

SetEventBus implements events.Eventable.

func (*Reactor) SetLogger

func (evR *Reactor) SetLogger(l log.Logger)

SetLogger sets the Logger on the reactor and the underlying Evidence.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL