consensus

package
v0.0.0-...-7c12c5a Latest Latest
Warning

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

Go to latest
Published: Oct 21, 2015 License: GPL-2.0, GPL-3.0 Imports: 20 Imported by: 0

README

The core consensus algorithm.

  • state.go - The state machine as detailed in the whitepaper
  • reactor.go - A reactor that connects the state machine to the gossip network

Documentation

Index

Constants

View Source
const (
	StateChannel = byte(0x20)
	DataChannel  = byte(0x21)
	VoteChannel  = byte(0x22)
)
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

)

Variables

View Source
var (
	ErrPeerStateHeightRegression = errors.New("Error peer state height regression")
	ErrPeerStateInvalidStartTime = errors.New("Error peer state invalid startTime")
)
View Source
var (
	ErrInvalidProposalSignature = errors.New("Error invalid proposal signature")
	ErrInvalidProposalPOLRound  = errors.New("Error invalid proposal POL round")
	ErrAddingVote               = errors.New("Error adding vote")
	ErrVoteHeightMismatch       = errors.New("Error vote height mismatch")
)

Functions

This section is empty.

Types

type BlockPartMessage

type BlockPartMessage struct {
	Height int
	Round  int
	Part   *types.Part
}

func (*BlockPartMessage) String

func (m *BlockPartMessage) String() string

type CommitStepMessage

type CommitStepMessage struct {
	Height           int
	BlockPartsHeader types.PartSetHeader
	BlockParts       *BitArray
}

func (*CommitStepMessage) String

func (m *CommitStepMessage) String() string

type ConsensusMessage

type ConsensusMessage interface{}

func DecodeMessage

func DecodeMessage(bz []byte) (msgType byte, msg ConsensusMessage, err error)

TODO: check for unnecessary extra bytes at the end.

type ConsensusReactor

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

func NewConsensusReactor

func NewConsensusReactor(consensusState *ConsensusState, blockStore *bc.BlockStore, fastSync bool) *ConsensusReactor

func (*ConsensusReactor) AddPeer

func (conR *ConsensusReactor) AddPeer(peer *p2p.Peer)

Implements Reactor

func (*ConsensusReactor) GetChannels

func (conR *ConsensusReactor) GetChannels() []*p2p.ChannelDescriptor

Implements Reactor

func (*ConsensusReactor) OnStart

func (conR *ConsensusReactor) OnStart() error

func (*ConsensusReactor) OnStop

func (conR *ConsensusReactor) OnStop()

func (*ConsensusReactor) Receive

func (conR *ConsensusReactor) Receive(chID byte, peer *p2p.Peer, msgBytes []byte)

Implements Reactor NOTE: We process these messages even when we're fast_syncing.

func (*ConsensusReactor) RemovePeer

func (conR *ConsensusReactor) RemovePeer(peer *p2p.Peer, reason interface{})

Implements Reactor

func (*ConsensusReactor) SetFireable

func (conR *ConsensusReactor) SetFireable(evsw events.Fireable)

implements events.Eventable

func (*ConsensusReactor) SetPrivValidator

func (conR *ConsensusReactor) SetPrivValidator(priv *types.PrivValidator)

Sets our private validator account for signing votes.

func (*ConsensusReactor) SwitchToConsensus

func (conR *ConsensusReactor) SwitchToConsensus(state *sm.State)

Switch from the fast_sync to the consensus: reset the state, turn off fast_sync, start the consensus-state-machine

type ConsensusState

type ConsensusState struct {
	BaseService

	RoundState
	// contains filtered or unexported fields
}

Tracks consensus state across block heights and rounds.

func NewConsensusState

func NewConsensusState(state *sm.State, blockStore *bc.BlockStore, mempoolReactor *mempl.MempoolReactor) *ConsensusState

func (*ConsensusState) AddProposalBlockPart

func (cs *ConsensusState) AddProposalBlockPart(height int, part *types.Part) (added bool, err error)

NOTE: block is not necessarily valid. This can trigger us to go into EnterPrevote asynchronously (before we timeout of propose) or to attempt to commit

func (*ConsensusState) AddVote

func (cs *ConsensusState) AddVote(valIndex int, vote *types.Vote, peerKey string) (added bool, address []byte, err error)

func (*ConsensusState) EnterCommit

func (cs *ConsensusState) EnterCommit(height int, commitRound int)

Enter: +2/3 precommits for block

func (*ConsensusState) EnterNewRound

func (cs *ConsensusState) EnterNewRound(height int, round int, timedOut bool)

Enter: +2/3 precommits for nil at (height,round-1) Enter: `timeoutPrecommits` after any +2/3 precommits from (height,round-1) Enter: `startTime = commitTime+timeoutCommit` from NewHeight(height) NOTE: cs.StartTime was already set for height.

func (*ConsensusState) EnterPrecommit

func (cs *ConsensusState) EnterPrecommit(height int, round int, timedOut bool)

Enter: +2/3 precomits for block or nil. Enter: `timeoutPrevote` after any +2/3 prevotes. Enter: any +2/3 precommits for next round. Lock & precommit the ProposalBlock if we have enough prevotes for it (a POL in this round) else, unlock an existing lock and precommit nil if +2/3 of prevotes were nil, else, precommit nil otherwise.

func (*ConsensusState) EnterPrecommitWait

func (cs *ConsensusState) EnterPrecommitWait(height int, round int)

Enter: any +2/3 precommits for next round.

func (*ConsensusState) EnterPrevote

func (cs *ConsensusState) EnterPrevote(height int, round int, timedOut bool)

Enter: `timeoutPropose` after entering Propose. Enter: proposal block and POL is ready. Enter: any +2/3 prevotes for future round. Prevote for LockedBlock if we're locked, or ProposalBlock if valid. Otherwise vote nil.

func (*ConsensusState) EnterPrevoteWait

func (cs *ConsensusState) EnterPrevoteWait(height int, round int)

Enter: any +2/3 prevotes at next round.

func (*ConsensusState) EnterPropose

func (cs *ConsensusState) EnterPropose(height int, round int)

Enter: from NewRound(height,round).

func (*ConsensusState) FinalizeCommit

func (cs *ConsensusState) FinalizeCommit(height int)

Increment height and goto RoundStepNewHeight

func (*ConsensusState) GetRoundState

func (cs *ConsensusState) GetRoundState() *RoundState

func (*ConsensusState) GetState

func (cs *ConsensusState) GetState() *sm.State

func (*ConsensusState) NewStepCh

func (cs *ConsensusState) NewStepCh() chan *RoundState

func (*ConsensusState) OnStart

func (cs *ConsensusState) OnStart() error

func (*ConsensusState) OnStop

func (cs *ConsensusState) OnStop()

func (*ConsensusState) SetFireable

func (cs *ConsensusState) SetFireable(evsw events.Fireable)

implements events.Eventable

func (*ConsensusState) SetPrivValidator

func (cs *ConsensusState) SetPrivValidator(priv *types.PrivValidator)

func (*ConsensusState) SetProposal

func (cs *ConsensusState) SetProposal(proposal *types.Proposal) error

func (*ConsensusState) String

func (cs *ConsensusState) String() string

func (*ConsensusState) TryAddVote

func (cs *ConsensusState) TryAddVote(valIndex int, vote *types.Vote, peerKey string) (bool, error)

Attempt to add the vote. if its a duplicate signature, dupeout the validator

type HasVoteMessage

type HasVoteMessage struct {
	Height int
	Round  int
	Type   byte
	Index  int
}

func (*HasVoteMessage) String

func (m *HasVoteMessage) String() string

type HeightVoteSet

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

Keeps track of all VoteSets from round 0 to round 'round'.

Also keeps track of up to one RoundVoteSet greater than 'round' from each peer, to facilitate catchup syncing of commits.

A commit is +2/3 precommits for a block at a round, but which round is not known in advance, so when a peer provides a precommit for a round greater than mtx.round, we create a new entry in roundVoteSets but also remember the peer to prevent abuse.

func NewHeightVoteSet

func NewHeightVoteSet(height int, valSet *types.ValidatorSet) *HeightVoteSet

func (*HeightVoteSet) AddByIndex

func (hvs *HeightVoteSet) AddByIndex(valIndex int, vote *types.Vote, peerKey string) (added bool, address []byte, err error)

Duplicate votes return added=false, err=nil. By convention, peerKey is "" if origin is self.

func (*HeightVoteSet) Height

func (hvs *HeightVoteSet) Height() int

func (*HeightVoteSet) POLRound

func (hvs *HeightVoteSet) POLRound() int

Last round that has +2/3 prevotes for a particular block or nil. Returns -1 if no such round exists.

func (*HeightVoteSet) Precommits

func (hvs *HeightVoteSet) Precommits(round int) *types.VoteSet

func (*HeightVoteSet) Prevotes

func (hvs *HeightVoteSet) Prevotes(round int) *types.VoteSet

func (*HeightVoteSet) Round

func (hvs *HeightVoteSet) Round() int

func (*HeightVoteSet) SetRound

func (hvs *HeightVoteSet) SetRound(round int)

Create more RoundVoteSets up to round.

func (*HeightVoteSet) String

func (hvs *HeightVoteSet) String() string

func (*HeightVoteSet) StringIndented

func (hvs *HeightVoteSet) StringIndented(indent string) string

type NewRoundStepMessage

type NewRoundStepMessage struct {
	Height                int
	Round                 int
	Step                  RoundStepType
	SecondsSinceStartTime int
	LastCommitRound       int
}

For every height/round/step transition

func (*NewRoundStepMessage) String

func (m *NewRoundStepMessage) String() string

type PeerRoundState

type PeerRoundState struct {
	Height                   int                 // Height peer is at
	Round                    int                 // Round peer is at, -1 if unknown.
	Step                     RoundStepType       // Step peer is at
	StartTime                time.Time           // Estimated start of round 0 at this height
	Proposal                 bool                // True if peer has proposal for this round
	ProposalBlockPartsHeader types.PartSetHeader //
	ProposalBlockParts       *BitArray           //
	ProposalPOLRound         int                 // Proposal's POL round. -1 if none.
	ProposalPOL              *BitArray           // nil until ProposalPOLMessage received.
	Prevotes                 *BitArray           // All votes peer has for this round
	Precommits               *BitArray           // All precommits peer has for this round
	LastCommitRound          int                 // Round of commit for last height. -1 if none.
	LastCommit               *BitArray           // All commit precommits of commit for last height.
	CatchupCommitRound       int                 // Round that we have commit for. Not necessarily unique. -1 if none.
	CatchupCommit            *BitArray           // All commit precommits peer has for this height & CatchupCommitRound
}

Read only when returned by PeerState.GetRoundState().

type PeerState

type PeerState struct {
	Peer *p2p.Peer

	PeerRoundState
	// contains filtered or unexported fields
}

func NewPeerState

func NewPeerState(peer *p2p.Peer) *PeerState

func (*PeerState) ApplyCommitStepMessage

func (ps *PeerState) ApplyCommitStepMessage(msg *CommitStepMessage)

func (*PeerState) ApplyHasVoteMessage

func (ps *PeerState) ApplyHasVoteMessage(msg *HasVoteMessage)

func (*PeerState) ApplyNewRoundStepMessage

func (ps *PeerState) ApplyNewRoundStepMessage(msg *NewRoundStepMessage)

func (*PeerState) ApplyProposalPOLMessage

func (ps *PeerState) ApplyProposalPOLMessage(msg *ProposalPOLMessage)

func (*PeerState) EnsureVoteBitArrays

func (ps *PeerState) EnsureVoteBitArrays(height int, numValidators int)

NOTE: It's important to make sure that numValidators actually matches what the node sees as the number of validators for height.

func (*PeerState) GetHeight

func (ps *PeerState) GetHeight() int

Returns an atomic snapshot of the PeerRoundState's height used by the mempool to ensure peers are caught up before broadcasting new txs

func (*PeerState) GetRoundState

func (ps *PeerState) GetRoundState() *PeerRoundState

Returns an atomic snapshot of the PeerRoundState. There's no point in mutating it since it won't change PeerState.

func (*PeerState) PickSendVote

func (ps *PeerState) PickSendVote(votes types.VoteSetReader) (ok bool)

Convenience function to send vote to peer. Returns true if vote was sent.

func (*PeerState) PickVoteToSend

func (ps *PeerState) PickVoteToSend(votes types.VoteSetReader) (index int, vote *types.Vote, ok bool)

votes: Must be the correct Size() for the Height().

func (*PeerState) SetHasProposal

func (ps *PeerState) SetHasProposal(proposal *types.Proposal)

func (*PeerState) SetHasProposalBlockPart

func (ps *PeerState) SetHasProposalBlockPart(height int, round int, index int)

func (*PeerState) SetHasVote

func (ps *PeerState) SetHasVote(vote *types.Vote, index int)

type ProposalMessage

type ProposalMessage struct {
	Proposal *types.Proposal
}

func (*ProposalMessage) String

func (m *ProposalMessage) String() string

type ProposalPOLMessage

type ProposalPOLMessage struct {
	Height           int
	ProposalPOLRound int
	ProposalPOL      *BitArray
}

func (*ProposalPOLMessage) String

func (m *ProposalPOLMessage) String() string

type RoundState

type RoundState struct {
	Height             int // Height we are working on
	Round              int
	Step               RoundStepType
	StartTime          time.Time
	CommitTime         time.Time // Subjective time when +2/3 precommits for Block at Round were found
	Validators         *types.ValidatorSet
	Proposal           *types.Proposal
	ProposalBlock      *types.Block
	ProposalBlockParts *types.PartSet
	LockedRound        int
	LockedBlock        *types.Block
	LockedBlockParts   *types.PartSet
	Votes              *HeightVoteSet
	CommitRound        int            //
	LastCommit         *types.VoteSet // Last precommits at Height-1
	LastValidators     *types.ValidatorSet
}

Immutable when returned from ConsensusState.GetRoundState()

func (*RoundState) RoundStateEvent

func (rs *RoundState) RoundStateEvent() *types.EventDataRoundState

func (*RoundState) String

func (rs *RoundState) String() string

func (*RoundState) StringIndented

func (rs *RoundState) StringIndented(indent string) string

func (*RoundState) StringShort

func (rs *RoundState) StringShort() string

type RoundStepType

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

func (RoundStepType) String

func (rs RoundStepType) String() string

type RoundVoteSet

type RoundVoteSet struct {
	Prevotes   *types.VoteSet
	Precommits *types.VoteSet
}

type VoteMessage

type VoteMessage struct {
	ValidatorIndex int
	Vote           *types.Vote
}

func (*VoteMessage) String

func (m *VoteMessage) String() string

Jump to

Keyboard shortcuts

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