consensus

package
v0.0.0-...-a163439 Latest Latest
Warning

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

Go to latest
Published: Apr 11, 2022 License: MIT Imports: 19 Imported by: 0

Documentation

Index

Constants

View Source
const (
	MockSignerClient      = PrivValidatorType(0x00) // mock signer
	FileSignerClient      = PrivValidatorType(0x01) // signer client via file
	RetrySignerClient     = PrivValidatorType(0x02) // signer client with retry via socket
	SignerSocketClient    = PrivValidatorType(0x03) // signer client via socket
	ErrorMockSignerClient = PrivValidatorType(0x04) // error mock signer
	SignerGRPCClient      = PrivValidatorType(0x05) // signer client via gRPC
)
View Source
const (
	RoundStepNewHeight     = RoundStepType(0x01) // Wait til CommitTime + timeoutCommit
	RoundStepNewRound      = RoundStepType(0x02) // Setup new round and go to RoundStepPropose
	RoundStepPropose       = RoundStepType(0x03) // Did propose, gossip proposal
	RoundStepPrevote       = RoundStepType(0x04) // Did prevote, gossip prevotes
	RoundStepPrevoteWait   = RoundStepType(0x05) // Did receive any +2/3 prevotes, start timeout
	RoundStepPrecommit     = RoundStepType(0x06) // Did precommit, gossip precommits
	RoundStepPrecommitWait = RoundStepType(0x07) // Did receive any +2/3 precommits, start timeout
	RoundStepCommit        = RoundStepType(0x08) // Entered commit state machine

)

RoundStepType

Variables

View Source
var (
	ErrInvalidProposalSignature   = errors.New("error invalid proposal signature")
	ErrInvalidProposalPOLRound    = errors.New("error invalid proposal POL round")
	ErrAddingVote                 = errors.New("error adding vote")
	ErrSignatureFoundInPastBlocks = errors.New("found signature from the same key")
)

Consensus sentinel errors

View Source
var (
	// ErrAlreadyStarted is returned when somebody tries to start an already
	// running service.
	ErrAlreadyStarted = errors.New("already started")
	// ErrAlreadyStopped is returned when somebody tries to stop an already
	// stopped service (without resetting it).
	ErrAlreadyStopped = errors.New("already stopped")
	// ErrNotStarted is returned when somebody tries to stop a not running
	// service.
	ErrNotStarted = errors.New("not started")
)
View Source
var (
	NewVoteSet                       = types.NewVoteSet
	NewValidatorSet                  = types.NewValidatorSet
	VerifyCommit                     = types.VerifyCommit
	NewHeightVoteSet                 = types.NewHeightVoteSet
	ErrVoteNonDeterministicSignature = types.ErrVoteNonDeterministicSignature
	// BlockIDFlagAbsent - no vote was received from a validator.
	BlockIDFlagAbsent BlockIDFlag = types.BlockIDFlagAbsent
	// BlockIDFlagCommit - voted for the Commit.BlockID.
	BlockIDFlagCommit = types.BlockIDFlagCommit
	// BlockIDFlagNil - voted for nil.
	BlockIDFlagNil = types.BlockIDFlagAbsent

	NewCommit          = types.NewCommit
	CommitToVoteSet    = types.CommitToVoteSet
	NewProposal        = types.NewProposal
	NewCommitSigAbsent = types.NewCommitSigAbsent
)
View Source
var ErrOverflowInt32 = errors.New("int32 overflow")
View Source
var ErrOverflowInt8 = errors.New("int8 overflow")
View Source
var ErrOverflowUint8 = errors.New("uint8 overflow")
View Source
var MaxSignatureSize = 65

Functions

func Canonical

func Canonical(t time.Time) time.Time

Canonical returns UTC time with no monotonic component. Stripping the monotonic component is for time equality. See https://github.com/tendermint/tendermint/pull/2203#discussion_r215064334

func CanonicalNow

func CanonicalNow() time.Time

Now returns the current time in UTC with no monotonic component.

func CanonicalNowMs

func CanonicalNowMs() int64

func IsVoteTypeValid

func IsVoteTypeValid(t SignedMsgType) bool

IsVoteTypeValid returns true if t is a valid vote type.

func MedianTime

func MedianTime(commit *Commit, validators *ValidatorSet) uint64

MedianTime computes a median time for a given Commit (based on Timestamp field of votes messages) and the corresponding validator set. The computed time is always between timestamps of the votes sent by honest processes, i.e., a faulty processes can not arbitrarily increase or decrease the computed value.

func SafeAddInt32

func SafeAddInt32(a, b int32) int32

SafeAddInt32 adds two int32 integers If there is an overflow this will panic

func SafeConvertInt32

func SafeConvertInt32(a int64) int32

SafeConvertInt32 takes a int and checks if it overflows If there is an overflow this will panic

func SafeConvertInt32FromUint32

func SafeConvertInt32FromUint32(a uint32) int32

func SafeConvertInt8

func SafeConvertInt8(a int64) (int8, error)

SafeConvertInt8 takes an int64 and checks if it overflows If there is an overflow it returns an error

func SafeConvertUint32FromInt32

func SafeConvertUint32FromInt32(a int32) uint32

func SafeConvertUint8

func SafeConvertUint8(a int64) (uint8, error)

SafeConvertUint8 takes an int64 and checks if it overflows If there is an overflow it returns an error

func SafeSubInt32

func SafeSubInt32(a, b int32) int32

SafeSubInt32 subtracts two int32 integers If there is an overflow this will panic

Types

type BaseService

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

Classical-inheritance-style service declarations. Services can be started, then stopped, then optionally restarted.

Users can override the OnStart/OnStop methods. In the absence of errors, these methods are guaranteed to be called at most once. If OnStart returns an error, service won't be marked as started, so the user can call Start again.

A call to Reset will panic, unless OnReset is overwritten, allowing OnStart/OnStop to be called again.

The caller must ensure that Start and Stop are not called concurrently.

It is ok to call Stop without calling Start first.

Typical usage:

type FooService struct {
	BaseService
	// private fields
}

func NewFooService() *FooService {
	fs := &FooService{
		// init
	}
	fs.BaseService = *NewBaseService(log, "FooService", fs)
	return fs
}

func (fs *FooService) OnStart(ctx context.Context) error {
	fs.BaseService.OnStart() // Always call the overridden method.
	// initialize private fields
	// start subroutines, etc.
}

func (fs *FooService) OnStop() error {
	fs.BaseService.OnStop() // Always call the overridden method.
	// close/destroy private fields
	// stop subroutines, etc.
}

func NewBaseService

func NewBaseService(name string, impl Implementation) *BaseService

NewBaseService creates a new BaseService.

func (*BaseService) IsRunning

func (bs *BaseService) IsRunning() bool

IsRunning implements Service by returning true or false depending on the service's state.

func (*BaseService) Start

func (bs *BaseService) Start(ctx context.Context) error

Start starts the Service and calls its OnStart method. An error will be returned if the service is already running or stopped. To restart a stopped service, call Reset.

func (*BaseService) Stop

func (bs *BaseService) Stop() error

Stop implements Service by calling OnStop (if defined) and closing quit channel. An error will be returned if the service is already stopped.

func (*BaseService) String

func (bs *BaseService) String() string

String implements Service by returning a string representation of the service.

func (*BaseService) Wait

func (bs *BaseService) Wait()

Wait blocks until the service is stopped.

type BlockExecutor

type BlockExecutor interface {
	ValidateBlock(ChainState, *FullBlock) error                             // validate the block by tentatively executing it
	ApplyBlock(context.Context, ChainState, *FullBlock) (ChainState, error) // apply the block
	MakeBlock(chainState *ChainState, height uint64, commit *Commit, proposerAddress common.Address) *FullBlock
}

func NewDefaultBlockExecutor

func NewDefaultBlockExecutor(db *leveldb.DB) BlockExecutor

type BlockIDFlag

type BlockIDFlag = types.BlockIDFlag

BlockIDFlag indicates which BlockID the signature is for.

type BlockStore

type BlockStore interface {
	Base() uint64   // first known contiguous block height
	Height() uint64 // last known contiguous block height
	Size() uint64   // return number of blocks in the store

	LoadBlock(height uint64) *FullBlock
	LoadBlockCommit(height uint64) *Commit
	LoadSeenCommit() *Commit

	SaveBlock(*FullBlock, *Commit)
}

type ChainState

type ChainState struct {
	// immutable
	ChainID       string
	InitialHeight uint64 // should be 1, not 0, when starting from height 1

	// LastBlockHeight=0 at genesis (ie. block(H=0) does not exist)
	LastBlockHeight uint64
	LastBlockID     common.Hash
	LastBlockTime   uint64

	// LastValidators is used to validate block.LastCommit.
	// Validators are persisted to the database separately every time they change,
	// so we can query for historical validator sets.
	// Note that if s.LastBlockHeight causes a valset change,
	// we set s.LastHeightValidatorsChanged = s.LastBlockHeight + 1 + 1
	// Extra +1 due to nextValSet delay.
	Validators                  *ValidatorSet
	LastValidators              *ValidatorSet
	LastHeightValidatorsChanged int64

	// Consensus parameters used for validating blocks.
	// Changes returned by EndBlock and updated after Commit.
	// ConsensusParams                  types.ConsensusParams
	// LastHeightConsensusParamsChanged int64
	Epoch uint64

	// the latest AppHash we've received from calling abci.Commit()
	AppHash []byte
}

State is a short description of the latest committed block of the Tendermint consensus. It keeps all information necessary to validate new blocks, including the last validator set and the consensus params. All fields are exposed so the struct can be easily serialized, but none of them should be mutated directly. Instead, use state.Copy() or updateState(...). NOTE: not goroutine-safe.

func MakeChainState

func MakeChainState(
	chainID string,
	parentHeight uint64,
	parentHash common.Hash,
	parentTimeMs uint64,
	lastValSet *ValidatorSet,
	valSet *ValidatorSet,
	epoch uint64,
) *ChainState

func MakeGenesisChainState

func MakeGenesisChainState(chainID string, genesisTimeMs uint64, validatorAddrs []common.Address, votingPowers []int64, epoch uint64, proposerReptition int64) *ChainState

func (ChainState) Copy

func (state ChainState) Copy() ChainState

func (ChainState) IsEmpty

func (state ChainState) IsEmpty() bool

IsEmpty returns true if the State is equal to the empty State.

func (ChainState) MakeBlock

func (state ChainState) MakeBlock(
	height uint64,

	commit *Commit,

	proposerAddress common.Address,
) *FullBlock

MakeBlock builds a block from the current state with the given txs, commit, and evidence. Note it also takes a proposerAddress because the state does not track rounds, and hence does not know the correct proposer. TODO: fix this!

type Commit

type Commit = types.Commit

type CommitSig

type CommitSig = types.CommitSig

type ConsensusConfig

type ConsensusConfig = params.ConsensusConfig

type ConsensusState

type ConsensusState struct {
	BaseService

	RoundState
	// contains filtered or unexported fields
}

State handles execution of the consensus algorithm. It processes votes and proposals, and upon reaching agreement, commits blocks to the chain and executes them against the application. The internal state machine receives input from peers, the internal validator, and from a timer.

func NewConsensusState

func NewConsensusState(
	ctx context.Context,
	cfg *ConsensusConfig,
	state ChainState,
	blockExec BlockExecutor,
	blockStore BlockStore,
	peerInMsgQueue chan MsgInfo,
	peerOutMsgQueue chan Message,

) *ConsensusState

NewState returns a new State.

func (*ConsensusState) GetLastHeight

func (cs *ConsensusState) GetLastHeight() uint64

GetLastHeight returns the last height committed. If there were no blocks, returns 0.

func (*ConsensusState) GetRoundState

func (cs *ConsensusState) GetRoundState() *RoundState

GetRoundState returns a shallow copy of the internal consensus state.

func (*ConsensusState) LoadCommit

func (cs *ConsensusState) LoadCommit(height uint64) *Commit

LoadCommit loads the commit for a given height.

func (*ConsensusState) OnStart

func (cs *ConsensusState) OnStart(ctx context.Context) error

OnStart loads the latest state via the WAL, and starts the timeout and receive routines.

func (*ConsensusState) OnStop

func (cs *ConsensusState) OnStop()

OnStop implements service.Service.

func (*ConsensusState) ProcessCommittedBlock

func (cs *ConsensusState) ProcessCommittedBlock(fb *FullBlock)

func (*ConsensusState) ProcessSyncRequest

func (cs *ConsensusState) ProcessSyncRequest(csq *ConsensusSyncRequest) ([]interface{}, error)

func (*ConsensusState) SetPrivValidator

func (cs *ConsensusState) SetPrivValidator(priv PrivValidator)

SetPrivValidator sets the private validator account for signing votes. It immediately requests pubkey and caches it.

func (*ConsensusState) SetTimeoutTicker

func (cs *ConsensusState) SetTimeoutTicker(timeoutTicker TimeoutTicker)

SetTimeoutTicker sets the local timer. It may be useful to overwrite for testing.

func (*ConsensusState) String

func (cs *ConsensusState) String() string

String returns a string.

func (*ConsensusState) Wait

func (cs *ConsensusState) Wait()

Wait waits for the the main routine to return. NOTE: be sure to Stop() the event switch and drain any event channels or this may deadlock

type ConsensusSyncRequest

type ConsensusSyncRequest struct {
	Height           uint64
	Round            uint32
	HasProposal      uint8 // whether the proposal is received
	PrevotesBitmap   []uint64
	PrecommitsBitmap []uint64
}

Ask for consensus sync to another peer The consensus will response with a list of votes and possible proposal

func (*ConsensusSyncRequest) ValidateBasic

func (csr *ConsensusSyncRequest) ValidateBasic() error

type ConsensusSyncResponse

type ConsensusSyncResponse struct {
	IsCommited  uint8 // whether return a commited block or proposal/vote messages
	MessageData [][]byte
}

type DefaultBlockExecutor

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

func (*DefaultBlockExecutor) ApplyBlock

func (be *DefaultBlockExecutor) ApplyBlock(ctx context.Context, state ChainState, block *FullBlock) (ChainState, error)

func (*DefaultBlockExecutor) MakeBlock

func (be *DefaultBlockExecutor) MakeBlock(
	chainState *ChainState, height uint64,

	commit *Commit,

	proposerAddress common.Address) *FullBlock

func (*DefaultBlockExecutor) ValidateBlock

func (be *DefaultBlockExecutor) ValidateBlock(state ChainState, b *FullBlock) error

type EcdsaPubKey

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

func (*EcdsaPubKey) Address

func (pubkey *EcdsaPubKey) Address() common.Address

func (*EcdsaPubKey) Type

func (pubkey *EcdsaPubKey) Type() string

func (*EcdsaPubKey) VerifySignature

func (pubkey *EcdsaPubKey) VerifySignature(msg []byte, sig []byte) bool

type ErrVoteConflictingVotes

type ErrVoteConflictingVotes = types.ErrVoteConflictingVotes

type EventDataRoundState

type EventDataRoundState struct {
	Height uint64 `json:"height"`
	Round  int32  `json:"round"`
	Step   string `json:"step"`
}

NOTE: This goes into the replay WAL

type FullBlock

type FullBlock = types.FullBlock
type Header = types.Header

type HeightVoteSet

type HeightVoteSet = types.HeightVoteSet

type Implementation

type Implementation interface {
	Service

	// Called by the Services Start Method
	OnStart(context.Context) error

	// Called when the service's context is canceled.
	OnStop()
}

Implementation describes the implementation that the BaseService implementation wraps.

type Message

type Message interface {
	ValidateBasic() error
}

Message defines an interface that the consensus domain types implement. When a proto message is received on a consensus p2p Channel, it is wrapped and then converted to a Message via MsgFromProto.

type MsgInfo

type MsgInfo struct {
	Msg    Message `json:"msg"`
	PeerID string  `json:"peer_key"`
}

msgs from the reactor which may update the state

type PrivValidator

type PrivValidator interface {
	GetPubKey(context.Context) (PubKey, error)

	SignVote(ctx context.Context, chainID string, vote *Vote) error
	SignProposal(ctx context.Context, chainID string, proposal *Proposal) error
}

PrivValidator defines the functionality of a local Tendermint validator that signs votes and proposals, and never double signs.

func GeneratePrivValidatorLocal

func GeneratePrivValidatorLocal() PrivValidator

generate a local priv validator with random key.

type PrivValidatorLocal

type PrivValidatorLocal struct {
	PrivKey *ecdsa.PrivateKey
}

func NewPrivValidatorLocal

func NewPrivValidatorLocal(privKey *ecdsa.PrivateKey) *PrivValidatorLocal

func (*PrivValidatorLocal) Address

func (pv *PrivValidatorLocal) Address() common.Address

func (*PrivValidatorLocal) GetPubKey

func (pv *PrivValidatorLocal) GetPubKey(context.Context) (PubKey, error)

func (*PrivValidatorLocal) SignProposal

func (pv *PrivValidatorLocal) SignProposal(ctx context.Context, chainID string, proposal *Proposal) error

func (*PrivValidatorLocal) SignVote

func (pv *PrivValidatorLocal) SignVote(ctx context.Context, chainId string, vote *Vote) error

type PrivValidatorType

type PrivValidatorType uint8

PrivValidatorType defines the implemtation types.

type Proposal

type Proposal = types.Proposal

type ProposalMessage

type ProposalMessage = types.ProposalMessage

type PubKey

type PubKey interface {
	Address() common.Address
	// Bytes() []byte
	VerifySignature(msg []byte, sig []byte) bool
	// Equals(PubKey) bool
	Type() string
}

func NewEcdsaPubKey

func NewEcdsaPubKey(addr common.Address) PubKey

type RoundState

type RoundState struct {
	Height    uint64        `json:"height"` // Height we are working on
	Round     int32         `json:"round"`
	Step      RoundStepType `json:"step"`
	StartTime time.Time     `json:"start_time"`

	// Subjective time when +2/3 precommits for Block at Round were found
	CommitTime    time.Time     `json:"commit_time"`
	Validators    *ValidatorSet `json:"validators"`
	Proposal      *Proposal     `json:"proposal"`
	ProposalBlock *FullBlock    `json:"proposal_block"`
	LockedRound   int32         `json:"locked_round"`
	LockedBlock   *FullBlock    `json:"locked_block"`

	// Last known round with POL for non-nil valid block.
	ValidRound int32      `json:"valid_round"`
	ValidBlock *FullBlock `json:"valid_block"` // Last known block of POL mentioned above.

	// Last known block parts of POL mentioned above.
	Votes                     *HeightVoteSet `json:"votes"`
	CommitRound               int32          `json:"commit_round"` //
	LastCommit                *VoteSet       `json:"last_commit"`  // Last precommits at Height-1
	LastValidators            *ValidatorSet  `json:"last_validators"`
	TriggeredTimeoutPrecommit bool           `json:"triggered_timeout_precommit"`
}

RoundState defines the internal consensus state. NOTE: Not thread safe. Should only be manipulated by functions downstream of the cs.receiveRoutine

func (*RoundState) RoundStateEvent

func (rs *RoundState) RoundStateEvent() EventDataRoundState

RoundStateEvent returns the H/R/S of the RoundState as an event.

type RoundStepType

type RoundStepType uint8 // These must be numeric, ordered.

RoundStepType enumerates the state of the consensus state machine

func (RoundStepType) IsValid

func (rs RoundStepType) IsValid() bool

IsValid returns true if the step is valid, false if unknown/undefined.

func (RoundStepType) String

func (rs RoundStepType) String() string

String returns a string

type Service

type Service interface {
	// Start is called to start the service, which should run until
	// the context terminates. If the service is already running, Start
	// must report an error.
	Start(context.Context) error

	// Return true if the service is running
	IsRunning() bool

	// String representation of the service
	String() string

	// Wait blocks until the service is stopped.
	Wait()
}

Service defines a service that can be started, stopped, and reset.

type SignedMsgType

type SignedMsgType = types.SignedMsgType

SignedMsgType is a type of signed message in the consensus.

const (
	UnknownType SignedMsgType = types.UnknownType
	// Votes
	PrevoteType   SignedMsgType = types.PrevoteType
	PrecommitType SignedMsgType = types.PrecommitType
	// Proposals
	ProposalType SignedMsgType = types.ProposalType
)

type TimeoutTicker

type TimeoutTicker interface {
	Start(context.Context) error
	Stop() error
	IsRunning() bool
	Chan() <-chan timeoutInfo       // on which to receive a timeout
	ScheduleTimeout(ti timeoutInfo) // reset the timer
}

TimeoutTicker is a timer that schedules timeouts conditional on the height/round/step in the timeoutInfo. The timeoutInfo.Duration may be non-positive.

func NewTimeoutTicker

func NewTimeoutTicker() TimeoutTicker

NewTimeoutTicker returns a new TimeoutTicker.

type Validator

type Validator = types.Validator

type ValidatorSet

type ValidatorSet = types.ValidatorSet

type Vote

type Vote = types.Vote

type VoteMessage

type VoteMessage = types.VoteMessage

type VoteSet

type VoteSet = types.VoteSet

Jump to

Keyboard shortcuts

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