Documentation
¶
Index ¶
- Constants
- Variables
- func Canonical(t time.Time) time.Time
- func CanonicalNow() time.Time
- func CanonicalNowMs() int64
- func IsVoteTypeValid(t SignedMsgType) bool
- func MedianTime(commit *Commit, validators *ValidatorSet) uint64
- func SafeAddInt32(a, b int32) int32
- func SafeConvertInt32(a int64) int32
- func SafeConvertInt32FromUint32(a uint32) int32
- func SafeConvertInt8(a int64) (int8, error)
- func SafeConvertUint32FromInt32(a int32) uint32
- func SafeConvertUint8(a int64) (uint8, error)
- func SafeSubInt32(a, b int32) int32
- type BaseService
- type BlockExecutor
- type BlockIDFlag
- type BlockStore
- type ChainState
- type Commit
- type CommitSig
- type ConsensusConfig
- type ConsensusState
- func (cs *ConsensusState) GetLastHeight() uint64
- func (cs *ConsensusState) GetRoundState() *RoundState
- func (cs *ConsensusState) LoadCommit(height uint64) *Commit
- func (cs *ConsensusState) OnStart(ctx context.Context) error
- func (cs *ConsensusState) OnStop()
- func (cs *ConsensusState) ProcessCommittedBlock(fb *FullBlock)
- func (cs *ConsensusState) ProcessSyncRequest(csq *ConsensusSyncRequest) ([]interface{}, error)
- func (cs *ConsensusState) SetPrivValidator(priv PrivValidator)
- func (cs *ConsensusState) SetTimeoutTicker(timeoutTicker TimeoutTicker)
- func (cs *ConsensusState) String() string
- func (cs *ConsensusState) Wait()
- type ConsensusSyncRequest
- type ConsensusSyncResponse
- type DefaultBlockExecutor
- func (be *DefaultBlockExecutor) ApplyBlock(ctx context.Context, state ChainState, block *FullBlock) (ChainState, error)
- func (be *DefaultBlockExecutor) MakeBlock(chainState *ChainState, height uint64, commit *Commit, ...) *FullBlock
- func (be *DefaultBlockExecutor) ValidateBlock(state ChainState, b *FullBlock) error
- type EcdsaPubKey
- type ErrVoteConflictingVotes
- type EventDataRoundState
- type FullBlock
- type Header
- type HeightVoteSet
- type Implementation
- type Message
- type MsgInfo
- type PrivValidator
- type PrivValidatorLocal
- func (pv *PrivValidatorLocal) Address() common.Address
- func (pv *PrivValidatorLocal) GetPubKey(context.Context) (PubKey, error)
- func (pv *PrivValidatorLocal) SignProposal(ctx context.Context, chainID string, proposal *Proposal) error
- func (pv *PrivValidatorLocal) SignVote(ctx context.Context, chainId string, vote *Vote) error
- type PrivValidatorType
- type Proposal
- type ProposalMessage
- type PubKey
- type RoundState
- type RoundStepType
- type Service
- type SignedMsgType
- type TimeoutTicker
- type Validator
- type ValidatorSet
- type Vote
- type VoteMessage
- type VoteSet
Constants ¶
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 )
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 ¶
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
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") )
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 )
var ErrOverflowInt32 = errors.New("int32 overflow")
var ErrOverflowInt8 = errors.New("int8 overflow")
var ErrOverflowUint8 = errors.New("uint8 overflow")
var MaxSignatureSize = 65
Functions ¶
func Canonical ¶
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 ¶
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 ¶
SafeAddInt32 adds two int32 integers If there is an overflow this will panic
func SafeConvertInt32 ¶
SafeConvertInt32 takes a int and checks if it overflows If there is an overflow this will panic
func SafeConvertInt8 ¶
SafeConvertInt8 takes an int64 and checks if it overflows If there is an overflow it returns an error
func SafeConvertUint8 ¶
SafeConvertUint8 takes an int64 and checks if it overflows If there is an overflow it returns an error
func SafeSubInt32 ¶
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.
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 (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 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) 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 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 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 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 ¶
type PrivValidatorType ¶
type PrivValidatorType uint8
PrivValidatorType defines the implemtation types.
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 ¶
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.
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 ValidatorSet ¶
type ValidatorSet = types.ValidatorSet
type VoteMessage ¶
type VoteMessage = types.VoteMessage