Documentation ¶
Index ¶
- Constants
- Variables
- func CanonicalTime(t time.Time) string
- func CanonicalizeDataHash(bid *pb.DataHash) *pb.CanonicalDataHash
- func CanonicalizeProposal(chainID string, proposal *pb.Proposal) pb.CanonicalProposal
- func CanonicalizeVote(chainID string, vote *pb.Vote) pb.CanonicalVote
- func IsErrNotEnoughVotingPowerSigned(err error) bool
- func IsVoteTypeValid(t pb.SignedMsgType) bool
- func MaxCommitBytes(valCount int) int64
- func MsgToProto(msg Message) (*cpb.Message, error)
- func MustEncode(msg Message) []byte
- func NewConciliator(p *pubsub.PubSub, self PrivProposer) *conciliator
- func ProposalSignBytes(chainID string, p *pb.Proposal) []byte
- func RandValidator(randPower bool, minPower int64) (*Proposer, PrivProposer)
- func RandValidatorSet(numValidators int, votingPower int64) (*ProposerSet, []PrivProposer)
- func ValidateHash(h []byte) error
- func ValidateTime(t time.Time) error
- func ValidatorListString(vals []*Proposer) string
- func VoteSignBytes(chainID string, vote *pb.Vote) []byte
- type Address
- type Commit
- func (commit *Commit) BitArray() *bits.BitArray
- func (commit *Commit) GetByIndex(valIdx int32) *Vote
- func (commit *Commit) GetVote(valIdx int32) *Vote
- func (commit *Commit) Hash() tmbytes.HexBytes
- func (commit *Commit) IsCommit() bool
- func (commit *Commit) Size() int
- func (commit *Commit) StringIndented(indent string) string
- func (commit *Commit) ToProto() *pb.Commit
- func (commit *Commit) Type() byte
- func (commit *Commit) ValidateBasic() error
- func (commit *Commit) VoteSignBytes(chainID string, valIdx int32) []byte
- type CommitSig
- func (cs CommitSig) Absent() bool
- func (cs CommitSig) DataHash(commitDataHash DataHash) DataHash
- func (cs CommitSig) ForBlock() bool
- func (cs *CommitSig) FromProto(csp pb.CommitSig) error
- func (cs CommitSig) String() string
- func (cs *CommitSig) ToProto() *pb.CommitSig
- func (cs CommitSig) ValidateBasic() error
- type Consensus
- type DataHash
- type DataHashFlag
- type ErrInvalidCommitHeight
- type ErrInvalidCommitSignatures
- type ErrNotEnoughVotingPowerSigned
- type ErrVoteConflictingVotes
- type ErroringMockPV
- type HasVoteMessage
- type Message
- type MockPV
- func (pv MockPV) DisableChecks()
- func (pv MockPV) ExtractIntoValidator(votingPower int64) *Proposer
- func (pv MockPV) GetPubKey() (crypto.PubKey, error)
- func (pv MockPV) SignProposal(chainID string, proposal *pb.Proposal) error
- func (pv MockPV) SignVote(chainID string, vote *pb.Vote) error
- func (pv MockPV) String() string
- type NewRoundStepMessage
- type NewValidBlockMessage
- type PeerRoundState
- type PrivProposer
- type PrivValidatorsByAddress
- type Proposal
- type ProposalMessage
- type ProposalPOLMessage
- type Proposer
- type ProposerSet
- func (vals *ProposerSet) Copy() *ProposerSet
- func (vals *ProposerSet) CopyIncrementProposerPriority(times int32) *ProposerSet
- func (vals *ProposerSet) GetByAddress(address []byte) (index int32, val *Proposer)
- func (vals *ProposerSet) GetByIndex(index int32) (address []byte, val *Proposer)
- func (vals *ProposerSet) GetProposer() (proposer *Proposer)
- func (vals *ProposerSet) HasAddress(address []byte) bool
- func (vals *ProposerSet) Hash() []byte
- func (vals *ProposerSet) IncrementProposerPriority(times int32)
- func (vals *ProposerSet) IsNilOrEmpty() bool
- func (vals *ProposerSet) Iterate(fn func(index int, val *Proposer) bool)
- func (vals *ProposerSet) RescalePriorities(diffMax int64)
- func (vals *ProposerSet) Size() int
- func (vals *ProposerSet) String() string
- func (vals *ProposerSet) StringIndented(indent string) string
- func (vals *ProposerSet) ToProto() (*pb.ValidatorSet, error)
- func (vals *ProposerSet) TotalVotingPower() int64
- func (vals *ProposerSet) UpdateWithChangeSet(changes []*Proposer) error
- func (vals *ProposerSet) ValidateBasic() error
- func (vals *ProposerSet) VerifyCommit(chainID string, data []byte, commit *Commit) error
- func (vals *ProposerSet) VerifyCommitLight(chainID string, blockID DataHash, commit *Commit) error
- func (vals *ProposerSet) VerifyCommitLightTrusting(chainID string, commit *Commit, trustLevel tmmath.Fraction) error
- type ProposerStore
- type RoundState
- func (rs *RoundState) CompleteProposalEvent() types.EventDataCompleteProposal
- func (rs *RoundState) NewRoundEvent() types.EventDataNewRound
- func (rs *RoundState) RoundStateEvent() types.EventDataRoundState
- func (rs *RoundState) RoundStateSimple() RoundStateSimple
- func (rs *RoundState) String() string
- func (rs *RoundState) StringIndented(indent string) string
- func (rs *RoundState) StringShort() string
- type RoundStateSimple
- type RoundStepType
- type Validator
- type ValidatorsByAddress
- type ValidatorsByVotingPower
- type Vote
- type VoteMessage
- type VoteSet
- func (voteSet *VoteSet) AddVote(vote *Vote) (added bool, err error)
- func (voteSet *VoteSet) BitArray() *bits.BitArray
- func (voteSet *VoteSet) BitArrayByBlockID(blockID DataHash) *bits.BitArray
- func (voteSet *VoteSet) BitArrayString() string
- func (voteSet *VoteSet) ChainID() string
- func (voteSet *VoteSet) Done() <-chan struct{}
- func (voteSet *VoteSet) GetByAddress(address []byte) *Vote
- func (voteSet *VoteSet) GetByIndex(valIndex int32) *Vote
- func (voteSet *VoteSet) HasAll() bool
- func (voteSet *VoteSet) HasTwoThirdsAny() bool
- func (voteSet *VoteSet) HasTwoThirdsMajority() bool
- func (voteSet *VoteSet) IsCommit() bool
- func (voteSet *VoteSet) List() []Vote
- func (voteSet *VoteSet) LogString() string
- func (voteSet *VoteSet) MakeCommit() *Commit
- func (voteSet *VoteSet) MarshalJSON() ([]byte, error)
- func (voteSet *VoteSet) SetPeerMaj23(peerID peer.ID, blockID DataHash) error
- func (voteSet *VoteSet) Size() int
- func (voteSet *VoteSet) String() string
- func (voteSet *VoteSet) StringIndented(indent string) string
- func (voteSet *VoteSet) StringShort() string
- func (voteSet *VoteSet) TwoThirdsMajority() (blockID DataHash, ok bool)
- func (voteSet *VoteSet) Type() byte
- func (voteSet *VoteSet) VoteStrings() []string
- type VoteSetBitsMessage
- type VoteSetJSON
- type VoteSetMaj23Message
- type VoteSetReader
Constants ¶
const ( // Max size of commit without any commitSigs -> 82 for DataHash, 8 for Height, 4 for Round. MaxCommitOverheadBytes int64 = 94 // Commit sig size is made up of 64 bytes for the signature, 20 bytes for the address, // 1 byte for the flag and 14 bytes for the timestamp MaxCommitSigBytes int64 = 109 )
const ( // MaxTotalVotingPower - the maximum allowed total voting power. // It needs to be sufficiently small to, in all cases: // 1. prevent clipping in incrementProposerPriority() // 2. let (diff+diffMax-1) not overflow in IncrementProposerPriority() // (Proof of 1 is tricky, left to the reader). // It could be higher, but this is sufficiently large for our purposes, // and leaves room for defensive purposes. MaxTotalVotingPower = int64(math.MaxInt64) / 8 // PriorityWindowSizeFactor - is a constant that when multiplied with the // total voting power gives the maximum allowed distance between validator // priorities. PriorityWindowSizeFactor = 2 )
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
const ( // MaxVotesCount is the maximum number of votes in a set. Used in ValidateBasic funcs for // protection against DOS attacks. Note this implies a corresponding equal limit to // the number of validators. MaxVotesCount = 10000 )
const TimeFormat = time.RFC3339Nano
TimeFormat is used for generating the sigs
Variables ¶
var ( ErrProposalSignature = errors.New("invalid proposal signature") ErrProposalRound = errors.New("invalid proposal round") ErrAddingVote = errors.New("adding vote") ErrSignatureFoundInPastBlocks = errors.New("found signature from the same key") )
var ( ErrVoteUnexpectedStep = errors.New("unexpected step") ErrVoteInvalidValidatorIndex = errors.New("invalid validator index") ErrVoteInvalidValidatorAddress = errors.New("invalid validator address") ErrVoteInvalidSignature = errors.New("invalid signature") ErrVoteInvalidDataHash = errors.New("invalid data hash") ErrVoteNonDeterministicSignature = errors.New("non-deterministic signature") ErrVoteNil = errors.New("nil vote") ErrVoteInvalidType = errors.New("invalid vote type") )
var ErrTotalVotingPowerOverflow = fmt.Errorf("total voting power of resulting valset exceeds max %d", MaxTotalVotingPower)
ErrTotalVotingPowerOverflow is returned if the total voting power of the resulting validator set exceeds MaxTotalVotingPower.
var ErroringMockPVErr = errors.New("erroringMockPV always returns an error")
var ( // MaxSignatureSize is a maximum allowed signature size for the Proposal // and Vote. // XXX: secp256k1 does not have Size nor MaxSize defined. MaxSignatureSize = tmmath.MaxInt(ed25519.SignatureSize, 64) )
Functions ¶
func CanonicalTime ¶
CanonicalTime can be used to stringify time in a canonical way.
func CanonicalizeDataHash ¶
func CanonicalizeDataHash(bid *pb.DataHash) *pb.CanonicalDataHash
func CanonicalizeProposal ¶
func CanonicalizeProposal(chainID string, proposal *pb.Proposal) pb.CanonicalProposal
CanonicalizeVote transforms the given Proposal to a CanonicalProposal.
func CanonicalizeVote ¶
func CanonicalizeVote(chainID string, vote *pb.Vote) pb.CanonicalVote
CanonicalizeVote transforms the given Vote to a CanonicalVote, which does not contain ValidatorIndex and ValidatorAddress fields.
func IsErrNotEnoughVotingPowerSigned ¶
IsErrNotEnoughVotingPowerSigned returns true if err is ErrNotEnoughVotingPowerSigned.
func IsVoteTypeValid ¶
func IsVoteTypeValid(t pb.SignedMsgType) bool
IsVoteTypeValid returns true if t is a valid vote type.
func MaxCommitBytes ¶
func MsgToProto ¶
MsgToProto takes a consensus message type and returns the proto defined consensus message
func MustEncode ¶
MustEncode takes the reactors msg, makes it proto and marshals it this mimics `MustMarshalBinaryBare` in that is panics on error
func NewConciliator ¶
func NewConciliator(p *pubsub.PubSub, self PrivProposer) *conciliator
func ProposalSignBytes ¶
ProposalSignBytes returns the proto-encoding of the canonicalized Proposal, for signing. Panics if the marshaling fails.
The encoded Protobuf message is varint length-prefixed (using MarshalDelimited) for backwards-compatibility with the Amino encoding, due to e.g. hardware devices that rely on this encoding.
See CanonicalizeProposal
func RandValidator ¶
func RandValidator(randPower bool, minPower int64) (*Proposer, PrivProposer)
RandValidator returns a randomized validator, useful for testing. UNSTABLE
func RandValidatorSet ¶
func RandValidatorSet(numValidators int, votingPower int64) (*ProposerSet, []PrivProposer)
RandValidatorSet returns a randomized validator set (size: +numValidators+), where each validator has a voting power of +votingPower+.
EXPOSED FOR TESTING.
func ValidateHash ¶
ValidateHash returns an error if the hash is not empty, but its size != tmhash.Size.
func ValidateTime ¶
ValidateTime does a basic time validation ensuring time does not drift too much: +/- one year. TODO: reduce this to eg 1 day NOTE: DO NOT USE in ValidateBasic methods in this package. This function can only be used for real time validation, like on proposals and votes in the consensus. If consensus is stuck, and rounds increase for more than a day, having only a 1-day band here could break things... Can't use for validating blocks because we may be syncing years worth of history.
func ValidatorListString ¶
ValidatorListString returns a prettified validator list for logging purposes.
func VoteSignBytes ¶
VoteSignBytes returns the proto-encoding of the canonicalized Vote, for signing. Panics is the marshaling fails.
The encoded Protobuf message is varint length-prefixed (using MarshalDelimited) for backwards-compatibility with the Amino encoding, due to e.g. hardware devices that rely on this encoding.
See CanonicalizeVote
Types ¶
type Commit ¶
type Commit struct { // NOTE: The signatures are in order of address to preserve the bonded // ProposerSet order. // Any peer with a block can gossip signatures by index with a peer without // recalculating the active ProposerSet. DataHash DataHash `json:"block_id"` Signatures []CommitSig `json:"signatures"` // contains filtered or unexported fields }
Commit contains the evidence that a block was committed by a set of validators. NOTE: Commit is empty for height 1, but never nil.
func CommitFromProto ¶
FromProto sets a protobuf Commit to the given pointer. It returns an error if the commit is invalid.
func MakeCommit ¶
func (*Commit) BitArray ¶
BitArray returns a BitArray of which validators voted for DataHash or nil in this commit. Implements VoteSetReader.
func (*Commit) GetByIndex ¶
GetByIndex returns the vote corresponding to a given validator index. Panics if `index >= commit.Size()`. Implements VoteSetReader.
func (*Commit) GetVote ¶
GetVote converts the CommitSig for the given valIdx to a Vote. Returns nil if the precommit at valIdx is nil. Panics if valIdx >= commit.Size().
func (*Commit) IsCommit ¶
IsCommit returns true if there is at least one signature. Implements VoteSetReader.
func (*Commit) Size ¶
Size returns the number of signatures in the commit. Implements VoteSetReader.
func (*Commit) StringIndented ¶
StringIndented returns a string representation of the commit.
func (*Commit) Type ¶
Type returns the vote type of the commit, which is always VoteTypePrecommit Implements VoteSetReader.
func (*Commit) ValidateBasic ¶
ValidateBasic performs basic validation that doesn't involve state data. Does not actually check the cryptographic signatures.
func (*Commit) VoteSignBytes ¶
VoteSignBytes returns the bytes of the Vote corresponding to valIdx for signing.
The only unique part is the Timestamp - all other fields signed over are otherwise the same for all validators.
Panics if valIdx >= commit.Size().
See VoteSignBytes
type CommitSig ¶
type CommitSig struct { DataHashFlag DataHashFlag `json:"block_id_flag"` ValidatorAddress Address `json:"validator_address"` Timestamp time.Time `json:"timestamp"` Signature []byte `json:"signature"` }
CommitSig is a part of the Vote included in a Commit.
func NewCommitSigAbsent ¶
func NewCommitSigAbsent() CommitSig
NewCommitSigAbsent returns new CommitSig with DataHashFlagAbsent. Other fields are all empty.
func NewCommitSigForBlock ¶
NewCommitSigForBlock returns new CommitSig with DataHashFlagCommit.
func (CommitSig) DataHash ¶
DataHash returns the Commit's DataHash if CommitSig indicates signing, otherwise - empty DataHash.
func (*CommitSig) FromProto ¶
FromProto sets a protobuf CommitSig to the given pointer. It returns an error if the CommitSig is invalid.
func (CommitSig) String ¶
CommitSig returns a string representation of CommitSig.
1. first 6 bytes of signature 2. first 6 bytes of validator address 3. block ID flag 4. timestamp
func (CommitSig) ValidateBasic ¶
ValidateBasic performs basic validation.
type DataHash ¶
func (DataHash) IsComplete ¶
IsComplete returns true if this is a valid BlockID of a non-nil block.
func (DataHash) ValidateBasic ¶
ValidateBasic performs basic validation.
type DataHashFlag ¶
type DataHashFlag byte
DataHashFlag indicates which DataHash the signature is for.
const ( // DataHashFlagAbsent - no vote was received from a validator. DataHashFlagAbsent DataHashFlag = iota + 1 // DataHashFlagCommit - voted for the Commit.DataHash. DataHashFlagCommit // DataHashFlagNil - voted for nil. DataHashFlagNil )
type ErrInvalidCommitHeight ¶
ErrInvalidCommitHeight is returned when we encounter a commit with an unexpected height.
func NewErrInvalidCommitHeight ¶
func NewErrInvalidCommitHeight(expected, actual int64) ErrInvalidCommitHeight
func (ErrInvalidCommitHeight) Error ¶
func (e ErrInvalidCommitHeight) Error() string
type ErrInvalidCommitSignatures ¶
ErrInvalidCommitSignatures is returned when we encounter a commit where the number of signatures doesn't match the number of validators.
func NewErrInvalidCommitSignatures ¶
func NewErrInvalidCommitSignatures(expected, actual int) ErrInvalidCommitSignatures
func (ErrInvalidCommitSignatures) Error ¶
func (e ErrInvalidCommitSignatures) Error() string
type ErrNotEnoughVotingPowerSigned ¶
ErrNotEnoughVotingPowerSigned is returned when not enough validators signed a commit.
func (ErrNotEnoughVotingPowerSigned) Error ¶
func (e ErrNotEnoughVotingPowerSigned) Error() string
type ErrVoteConflictingVotes ¶
func NewConflictingVoteError ¶
func NewConflictingVoteError(vote1, vote2 *Vote) *ErrVoteConflictingVotes
func (*ErrVoteConflictingVotes) Error ¶
func (err *ErrVoteConflictingVotes) Error() string
type ErroringMockPV ¶
type ErroringMockPV struct {
MockPV
}
func NewErroringMockPV ¶
func NewErroringMockPV() *ErroringMockPV
func (*ErroringMockPV) SignProposal ¶
func (pv *ErroringMockPV) SignProposal(chainID string, proposal *pb.Proposal) error
type HasVoteMessage ¶
type HasVoteMessage struct { Height int64 Round int32 Type pb.SignedMsgType Index int32 }
HasVoteMessage is sent to indicate that a particular vote has been received.
func (*HasVoteMessage) String ¶
func (m *HasVoteMessage) String() string
String returns a string representation.
func (*HasVoteMessage) ValidateBasic ¶
func (m *HasVoteMessage) ValidateBasic() error
ValidateBasic performs basic validation.
type Message ¶
type Message interface {
ValidateBasic() error
}
Message is a message that can be sent and received on the Reactor
type MockPV ¶
MockPV implements PrivProposer without any safety or persistence. Only use it for testing.
func NewMockPVWithParams ¶
func NewMockPVWithParams(privKey crypto.PrivKey, breakProposalSigning, breakVoteSigning bool) MockPV
NewMockPVWithParams allows one to create a MockPV instance, but with finer grained control over the operation of the mock validator. This is useful for mocking test failures.
func (MockPV) ExtractIntoValidator ¶
func (MockPV) SignProposal ¶
SignProposal implements PrivProposer.
type NewRoundStepMessage ¶
type NewRoundStepMessage struct { Height int64 Round int32 Step RoundStepType SecondsSinceStartTime int64 LastCommitRound int32 }
NewRoundStepMessage is sent for every step taken in the ConsensusState. For every height/round/step transition
func (*NewRoundStepMessage) String ¶
func (m *NewRoundStepMessage) String() string
String returns a string representation.
func (*NewRoundStepMessage) ValidateBasic ¶
func (m *NewRoundStepMessage) ValidateBasic() error
ValidateBasic performs basic validation.
func (*NewRoundStepMessage) ValidateHeight ¶
func (m *NewRoundStepMessage) ValidateHeight(initialHeight int64) error
ValidateHeight validates the height given the chain's initial height.
type NewValidBlockMessage ¶
type NewValidBlockMessage struct { Height int64 Round int32 // TODO: BlockParts removed, requires some sort of ID IsCommit bool }
NewValidBlockMessage is sent when a validator observes a valid block B in some round r, i.e., there is a Proposal for block B and 2/3+ prevotes for the block B in the round r. In case the block is also committed, then IsCommit flag is set to true.
func (*NewValidBlockMessage) String ¶
func (m *NewValidBlockMessage) String() string
String returns a string representation.
func (*NewValidBlockMessage) ValidateBasic ¶
func (m *NewValidBlockMessage) ValidateBasic() error
ValidateBasic performs basic validation.
type PeerRoundState ¶
type PeerRoundState struct { Height int64 `json:"height"` // Height peer is at Round int32 `json:"round"` // Round peer is at, -1 if unknown. Step RoundStepType `json:"step"` // Step peer is at // Estimated start of round 0 at this height StartTime time.Time `json:"start_time"` // True if peer has proposal for this round Proposal bool `json:"proposal"` ProposalBlockPartSetHeader types.PartSetHeader `json:"proposal_block_part_set_header"` ProposalBlockParts *bits.BitArray `json:"proposal_block_parts"` // Proposal's POL round. -1 if none. ProposalPOLRound int32 `json:"proposal_pol_round"` // nil until ProposalPOLMessage received. ProposalPOL *bits.BitArray `json:"proposal_pol"` Prevotes *bits.BitArray `json:"prevotes"` // All votes peer has for this round Precommits *bits.BitArray `json:"precommits"` // All precommits peer has for this round LastCommitRound int32 `json:"last_commit_round"` // Round of commit for last height. -1 if none. LastCommit *bits.BitArray `json:"last_commit"` // All commit precommits of commit for last height. // Round that we have commit for. Not necessarily unique. -1 if none. CatchupCommitRound int32 `json:"catchup_commit_round"` // All commit precommits peer has for this height & CatchupCommitRound CatchupCommit *bits.BitArray `json:"catchup_commit"` }
PeerRoundState contains the known state of a peer. NOTE: Read-only when returned by PeerState.GetRoundState().
func (PeerRoundState) String ¶
func (prs PeerRoundState) String() string
String returns a string representation of the PeerRoundState
func (PeerRoundState) StringIndented ¶
func (prs PeerRoundState) StringIndented(indent string) string
StringIndented returns a string representation of the PeerRoundState
type PrivProposer ¶
type PrivProposer interface { GetPubKey() (crypto.PubKey, error) SignVote(chainID string, vote *pb.Vote) error SignProposal(chainID string, proposal *pb.Proposal) error }
PrivProposer defines the functionality of a local Tendermint validator that signs votes and proposals, and never double signs.
type PrivValidatorsByAddress ¶
type PrivValidatorsByAddress []PrivProposer
func (PrivValidatorsByAddress) Len ¶
func (pvs PrivValidatorsByAddress) Len() int
func (PrivValidatorsByAddress) Less ¶
func (pvs PrivValidatorsByAddress) Less(i, j int) bool
func (PrivValidatorsByAddress) Swap ¶
func (pvs PrivValidatorsByAddress) Swap(i, j int)
type Proposal ¶
type Proposal struct { Type pb.SignedMsgType Round int32 `json:"round"` // there can not be greater than 2_147_483_647 rounds POLRound int32 `json:"pol_round"` // -1 if null. Timestamp time.Time `json:"timestamp"` Signature []byte `json:"signature"` Data []byte `json:"data"` }
Proposal defines a block proposal for the consensus. It refers to the block by BlockID field. It must be signed by the correct proposer for the given Height/Round to be considered valid. It may depend on votes from a previous round, a so-called Proof-of-Lock (POL) round, as noted in the POLRound. If POLRound >= 0, then BlockID corresponds to the block that is locked in POLRound.
func NewProposal ¶
NewProposal returns a new Proposal. If there is no POLRound, polRound should be -1.
func ProposalFromProto ¶
FromProto sets a protobuf Proposal to the given pointer. It returns an error if the proposal is invalid.
func (*Proposal) String ¶
String returns a string representation of the Proposal.
1. height 2. round 3. block ID 4. POL round 5. first 6 bytes of signature 6. timestamp
See BlockID#String.
func (*Proposal) ValidateBasic ¶
ValidateBasic performs basic validation.
type ProposalMessage ¶
type ProposalMessage struct {
Proposal *Proposal
}
ProposalMessage is sent when a new block is proposed.
func (*ProposalMessage) String ¶
func (m *ProposalMessage) String() string
String returns a string representation.
func (*ProposalMessage) ValidateBasic ¶
func (m *ProposalMessage) ValidateBasic() error
ValidateBasic performs basic validation.
type ProposalPOLMessage ¶
ProposalPOLMessage is sent when a previous proposal is re-proposed.
func (*ProposalPOLMessage) String ¶
func (m *ProposalPOLMessage) String() string
String returns a string representation.
func (*ProposalPOLMessage) ValidateBasic ¶
func (m *ProposalPOLMessage) ValidateBasic() error
ValidateBasic performs basic validation.
type Proposer ¶
type Proposer struct { Address Address `json:"address"` PubKey crypto.PubKey `json:"pub_key"` VotingPower int64 `json:"voting_power"` ProposerPriority int64 `json:"proposer_priority"` }
Proposer is a volatile state for each Proposer NOTE: The ProposerPriority is not included in Proposer.Hash(); make sure to update that method if changes are made here
func NewValidator ¶
NewValidator returns a new validator with the given pubkey and voting power.
func ValidatorFromProto ¶
ValidatorFromProto fromProto sets a protobuf Proposer to the given pointer. It returns an error if the public key is invalid.
func (*Proposer) Bytes ¶
Bytes computes the unique encoding of a validator with a given voting power. These are the bytes that gets hashed in consensus. It excludes address as its redundant with the pubkey. This also excludes ProposerPriority which changes every round.
func (*Proposer) CompareProposerPriority ¶
CompareProposerPriority returns the one with higher ProposerPriority.
func (*Proposer) Copy ¶
Copy creates a new copy of the validator so we can mutate ProposerPriority. Panics if the validator is nil.
func (*Proposer) String ¶
String returns a string representation of String.
1. address 2. public key 3. voting power 4. proposer priority
func (*Proposer) ValidateBasic ¶
ValidateBasic performs basic validation.
type ProposerSet ¶
type ProposerSet struct { // NOTE: persisted via reflect, must be exported. Proposers []*Proposer `json:"validators"` Proposer *Proposer `json:"proposer"` // contains filtered or unexported fields }
ProposerSet represent a set of *Proposer at a given height.
The validators can be fetched by address or index. The index is in order of .VotingPower, so the indices are fixed for all rounds of a given blockchain height - ie. the validators are sorted by their voting power (descending). Secondary index - .Address (ascending).
On the other hand, the .ProposerPriority of each validator and the designated .GetProposer() of a set changes every round, upon calling .IncrementProposerPriority().
NOTE: Not goroutine-safe. NOTE: All get/set to validators should copy the value for safety.
func NewValidatorSet ¶
func NewValidatorSet(valz []*Proposer) *ProposerSet
NewValidatorSet initializes a ProposerSet by copying over the values from `valz`, a list of Validators. If valz is nil or empty, the new ProposerSet will have an empty list of Validators.
The addresses of validators in `valz` must be unique otherwise the function panics.
Note the validator set size has an implied limit equal to that of the MaxVotesCount - commits by a validator set larger than this will fail validation.
func ValidatorSetFromExistingValidators ¶
func ValidatorSetFromExistingValidators(valz []*Proposer) (*ProposerSet, error)
ValidatorSetFromExistingValidators takes an existing array of validators and rebuilds the exact same validator set that corresponds to it without changing the proposer priority or power if any of the validators fail validate basic then an empty set is returned.
func ValidatorSetFromProto ¶
func ValidatorSetFromProto(vp *pb.ValidatorSet) (*ProposerSet, error)
ValidatorSetFromProto sets a protobuf ProposerSet to the given pointer. It returns an error if any of the validators from the set or the proposer is invalid
func (*ProposerSet) Copy ¶
func (vals *ProposerSet) Copy() *ProposerSet
Copy each validator into a new ProposerSet.
func (*ProposerSet) CopyIncrementProposerPriority ¶
func (vals *ProposerSet) CopyIncrementProposerPriority(times int32) *ProposerSet
CopyIncrementProposerPriority increments ProposerPriority and updates the proposer on a copy, and returns it.
func (*ProposerSet) GetByAddress ¶
func (vals *ProposerSet) GetByAddress(address []byte) (index int32, val *Proposer)
GetByAddress returns an index of the validator with address and validator itself (copy) if found. Otherwise, -1 and nil are returned.
func (*ProposerSet) GetByIndex ¶
func (vals *ProposerSet) GetByIndex(index int32) (address []byte, val *Proposer)
GetByIndex returns the validator's address and validator itself (copy) by index. It returns nil values if index is less than 0 or greater or equal to len(ProposerSet.Proposers).
func (*ProposerSet) GetProposer ¶
func (vals *ProposerSet) GetProposer() (proposer *Proposer)
GetProposer returns the current proposer. If the validator set is empty, nil is returned.
func (*ProposerSet) HasAddress ¶
func (vals *ProposerSet) HasAddress(address []byte) bool
HasAddress returns true if address given is in the validator set, false - otherwise.
func (*ProposerSet) Hash ¶
func (vals *ProposerSet) Hash() []byte
Hash returns the Merkle root hash build using validators (as leaves) in the set.
func (*ProposerSet) IncrementProposerPriority ¶
func (vals *ProposerSet) IncrementProposerPriority(times int32)
IncrementProposerPriority increments ProposerPriority of each validator and updates the proposer. Panics if validator set is empty. `times` must be positive.
func (*ProposerSet) IsNilOrEmpty ¶
func (vals *ProposerSet) IsNilOrEmpty() bool
IsNilOrEmpty returns true if validator set is nil or empty.
func (*ProposerSet) Iterate ¶
func (vals *ProposerSet) Iterate(fn func(index int, val *Proposer) bool)
Iterate will run the given function over the set.
func (*ProposerSet) RescalePriorities ¶
func (vals *ProposerSet) RescalePriorities(diffMax int64)
RescalePriorities rescales the priorities such that the distance between the maximum and minimum is smaller than `diffMax`. Panics if validator set is empty.
func (*ProposerSet) Size ¶
func (vals *ProposerSet) Size() int
Size returns the length of the validator set.
func (*ProposerSet) String ¶
func (vals *ProposerSet) String() string
String returns a string representation of ProposerSet.
See StringIndented.
func (*ProposerSet) StringIndented ¶
func (vals *ProposerSet) StringIndented(indent string) string
StringIndented returns an intended String.
See Proposer#String.
func (*ProposerSet) ToProto ¶
func (vals *ProposerSet) ToProto() (*pb.ValidatorSet, error)
ToProto converts ProposerSet to protobuf
func (*ProposerSet) TotalVotingPower ¶
func (vals *ProposerSet) TotalVotingPower() int64
TotalVotingPower returns the sum of the voting powers of all validators. It recomputes the total voting power if required.
func (*ProposerSet) UpdateWithChangeSet ¶
func (vals *ProposerSet) UpdateWithChangeSet(changes []*Proposer) error
UpdateWithChangeSet attempts to update the validator set with 'changes'. It performs the following steps:
- validates the changes making sure there are no duplicates and splits them in updates and deletes
- verifies that applying the changes will not result in errors
- computes the total voting power BEFORE removals to ensure that in the next steps the priorities across old and newly added validators are fair
- computes the priorities of new validators against the final set
- applies the updates against the validator set
- applies the removals against the validator set
- performs scaling and centering of priority values
If an error is detected during verification steps, it is returned and the validator set is not changed.
func (*ProposerSet) ValidateBasic ¶
func (vals *ProposerSet) ValidateBasic() error
func (*ProposerSet) VerifyCommit ¶
func (vals *ProposerSet) VerifyCommit(chainID string, data []byte, commit *Commit) error
VerifyCommit verifies +2/3 of the set had signed the given commit.
It checks all the signatures! While it's safe to exit as soon as we have 2/3+ signatures, doing so would impact incentivization logic in the ABCI application that depends on the LastCommitInfo sent in BeginBlock, which includes which validators signed. For instance, Gaia incentivizes proposers with a bonus for including more than +2/3 of the signatures.
func (*ProposerSet) VerifyCommitLight ¶
func (vals *ProposerSet) VerifyCommitLight(chainID string, blockID DataHash, commit *Commit) error
VerifyCommitLight verifies +2/3 of the set had signed the given commit.
This method is primarily used by the light client and does not check all the signatures.
func (*ProposerSet) VerifyCommitLightTrusting ¶
func (vals *ProposerSet) VerifyCommitLightTrusting(chainID string, commit *Commit, trustLevel tmmath.Fraction) error
VerifyCommitLightTrusting verifies that trustLevel of the validator set signed this commit.
NOTE the given validators do not necessarily correspond to the validator set for this commit, but there may be some intersection.
This method is primarily used by the light client and does not check all the signatures.
type ProposerStore ¶
type ProposerStore interface {
Get(context.Context, string) (*ProposerSet, error)
}
type RoundState ¶
type RoundState struct { Height int64 `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 *types.ValidatorSet `json:"validators"` Proposal *types.Proposal `json:"proposal"` ProposalBlock *types.Block `json:"proposal_block"` ProposalBlockParts *types.PartSet `json:"proposal_block_parts"` LockedRound int32 `json:"locked_round"` LockedBlock *types.Block `json:"locked_block"` LockedBlockParts *types.PartSet `json:"locked_block_parts"` // Last known round with POL for non-nil valid block. ValidRound int32 `json:"valid_round"` ValidBlock *types.Block `json:"valid_block"` // Last known block of POL mentioned above. // Last known block parts of POL mentioned above. ValidBlockParts *types.PartSet `json:"valid_block_parts"` // Votes *HeightVoteSet `json:"votes"` CommitRound int32 `json:"commit_round"` // LastCommit *types.VoteSet `json:"last_commit"` // Last precommits at Height-1 LastValidators *types.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) CompleteProposalEvent ¶
func (rs *RoundState) CompleteProposalEvent() types.EventDataCompleteProposal
CompleteProposalEvent returns information about a proposed block as an event.
func (*RoundState) NewRoundEvent ¶
func (rs *RoundState) NewRoundEvent() types.EventDataNewRound
NewRoundEvent returns the RoundState with proposer information as an event.
func (*RoundState) RoundStateEvent ¶
func (rs *RoundState) RoundStateEvent() types.EventDataRoundState
RoundStateEvent returns the H/R/S of the RoundState as an event.
func (*RoundState) RoundStateSimple ¶
func (rs *RoundState) RoundStateSimple() RoundStateSimple
Compress the RoundState to RoundStateSimple
func (*RoundState) StringIndented ¶
func (rs *RoundState) StringIndented(indent string) string
StringIndented returns a string
func (*RoundState) StringShort ¶
func (rs *RoundState) StringShort() string
StringShort returns a string
type RoundStateSimple ¶
type RoundStateSimple struct { HeightRoundStep string `json:"height/round/step"` StartTime time.Time `json:"start_time"` ProposalBlockHash bytes.HexBytes `json:"proposal_block_hash"` LockedBlockHash bytes.HexBytes `json:"locked_block_hash"` ValidBlockHash bytes.HexBytes `json:"valid_block_hash"` // Votes json.RawMessage `json:"height_vote_set"` Proposer types.ValidatorInfo `json:"proposer"` }
Compressed version of the RoundState for use in RPC
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 ValidatorsByAddress ¶
type ValidatorsByAddress []*Proposer
ValidatorsByAddress implements sort.Interface for []*Proposer based on the Address field.
func (ValidatorsByAddress) Len ¶
func (valz ValidatorsByAddress) Len() int
func (ValidatorsByAddress) Less ¶
func (valz ValidatorsByAddress) Less(i, j int) bool
func (ValidatorsByAddress) Swap ¶
func (valz ValidatorsByAddress) Swap(i, j int)
type ValidatorsByVotingPower ¶
type ValidatorsByVotingPower []*Proposer
ValidatorsByVotingPower implements sort.Interface for []*Proposer based on the VotingPower and Address fields.
func (ValidatorsByVotingPower) Len ¶
func (valz ValidatorsByVotingPower) Len() int
func (ValidatorsByVotingPower) Less ¶
func (valz ValidatorsByVotingPower) Less(i, j int) bool
func (ValidatorsByVotingPower) Swap ¶
func (valz ValidatorsByVotingPower) Swap(i, j int)
type Vote ¶
type Vote struct { Type pb.SignedMsgType `json:"type"` DataHash DataHash `json:"block_id"` // zero if vote is nil. Timestamp time.Time `json:"timestamp"` ValidatorAddress Address `json:"validator_address"` ValidatorIndex int32 `json:"validator_index"` Signature []byte `json:"signature"` }
Vote represents a prevote, precommit, or commit vote from validators for consensus.
func MakeVote ¶
func MakeVote( height int64, dataHash DataHash, valSet *ProposerSet, privVal PrivProposer, chainID string, now time.Time, ) (*Vote, error)
func VoteFromProto ¶
FromProto converts a proto generetad type to a handwritten type return type, nil if everything converts safely, otherwise nil, error
func (*Vote) String ¶
String returns a string representation of Vote.
1. validator index 2. first 6 bytes of validator address 3. height 4. round, 5. type byte 6. type string 7. first 6 bytes of block hash 8. first 6 bytes of signature 9. timestamp
func (*Vote) ToProto ¶
ToProto converts the handwritten type to proto generated type return type, nil if everything converts safely, otherwise nil, error
func (*Vote) ValidateBasic ¶
ValidateBasic performs basic validation.
type VoteMessage ¶
type VoteMessage struct {
Vote *Vote
}
VoteMessage is sent when voting for a proposal (or lack thereof).
func (*VoteMessage) String ¶
func (m *VoteMessage) String() string
String returns a string representation.
func (*VoteMessage) ValidateBasic ¶
func (m *VoteMessage) ValidateBasic() error
ValidateBasic performs basic validation.
type VoteSet ¶
type VoteSet struct {
// contains filtered or unexported fields
}
VoteSet helps collect signatures from validators at each height+round for a predefined vote type.
We need VoteSet to be able to keep track of conflicting votes when validators double-sign. Yet, we can't keep track of *all* the votes seen, as that could be a DoS attack vector.
There are two storage areas for votes. 1. voteSet.votes 2. voteSet.votesByBlock
`.votes` is the "canonical" list of votes. It always has at least one vote, if a vote from a validator had been seen at all. Usually it keeps track of the first vote seen, but when a 2/3 majority is found, votes for that get priority and are copied over from `.votesByBlock`.
`.votesByBlock` keeps track of a list of votes for a particular block. There are two ways a &blockVotes{} gets created in `.votesByBlock`. 1. the first vote seen by a validator was for the particular block. 2. a peer claims to have seen 2/3 majority for the particular block.
Since the first vote from a validator will always get added in `.votesByBlock` , all votes in `.votes` will have a corresponding entry in `.votesByBlock`.
When a &blockVotes{} in `.votesByBlock` reaches a 2/3 majority quorum, its votes are copied into `.votes`.
All this is memory bounded because conflicting votes only get added if a peer told us to track that block, each peer only gets to tell us 1 such block, and, there's only a limited number of peers.
NOTE: Assumes that the sum total of voting power does not exceed MaxUInt64.
func CommitToVoteSet ¶
func CommitToVoteSet(chainID string, commit *Commit, vals *ProposerSet) *VoteSet
CommitToVoteSet constructs a VoteSet from the Commit and validator set. Panics if signatures from the commit can't be added to the voteset. Inverse of VoteSet.MakeCommit().
func NewVoteSet ¶
func NewVoteSet(chainID string, signedMsgType pb.SignedMsgType, valSet *ProposerSet) *VoteSet
Constructs a new VoteSet struct used to accumulate votes for given height/round.
func (*VoteSet) AddVote ¶
Returns added=true if vote is valid and new. Otherwise returns err=ErrVote[
UnexpectedStep | InvalidIndex | InvalidAddress | InvalidSignature | InvalidBlockHash | ConflictingVotes ]
Duplicate votes return added=false, err=nil. Conflicting votes return added=*, err=ErrVoteConflictingVotes. NOTE: vote should not be mutated after adding. NOTE: VoteSet must not be nil NOTE: Vote must not be nil
func (*VoteSet) BitArrayByBlockID ¶
func (*VoteSet) BitArrayString ¶
Return the bit-array of votes including the fraction of power that has voted like: "BA{29:xx__x__x_x___x__x_______xxx__} 856/1304 = 0.66"
func (*VoteSet) GetByAddress ¶
func (*VoteSet) GetByIndex ¶
NOTE: if validator has conflicting votes, returns "canonical" vote Implements VoteSetReader.
func (*VoteSet) HasTwoThirdsAny ¶
func (*VoteSet) HasTwoThirdsMajority ¶
func (*VoteSet) LogString ¶
LogString produces a logging suitable string representation of the vote set.
func (*VoteSet) MakeCommit ¶
MakeCommit constructs a Commit from the VoteSet. It only includes precommits for the block, which has 2/3+ majority, and nil.
Panics if the vote type is not PrecommitType or if there's no +2/3 votes for a single block.
func (*VoteSet) MarshalJSON ¶
Marshal the VoteSet to JSON. Same as String(), just in JSON, and without the height/round/signedMsgType (since its already included in the votes).
func (*VoteSet) SetPeerMaj23 ¶
If a peer claims that it has 2/3 majority for given blockKey, call this. NOTE: if there are too many peers, or too much peer churn, this can cause memory issues. TODO: implement ability to remove peers too NOTE: VoteSet must not be nil TODO: may be remove this??
func (*VoteSet) StringIndented ¶
StringIndented returns an indented String.
Height Round Type Votes Votes bit array 2/3+ majority
See Vote#String.
func (*VoteSet) StringShort ¶
StringShort returns a short representation of VoteSet.
1. height 2. round 3. signed msg type 4. first 2/3+ majority 5. fraction of voted power 6. votes bit array 7. 2/3+ majority for each peer
func (*VoteSet) TwoThirdsMajority ¶
If there was a +2/3 majority for blockID, return blockID and true. Else, return the empty BlockID{} and false.
func (*VoteSet) VoteStrings ¶
Returns a list of votes compressed to more readable strings.
type VoteSetBitsMessage ¶
type VoteSetBitsMessage struct { Height int64 Round int32 Type pb.SignedMsgType DataHash DataHash Votes *bits.BitArray }
VoteSetBitsMessage is sent to communicate the bit-array of votes seen for the BlockID.
func (*VoteSetBitsMessage) String ¶
func (m *VoteSetBitsMessage) String() string
String returns a string representation.
func (*VoteSetBitsMessage) ValidateBasic ¶
func (m *VoteSetBitsMessage) ValidateBasic() error
ValidateBasic performs basic validation.
type VoteSetJSON ¶
type VoteSetJSON struct { Votes []string `json:"votes"` VotesBitArray string `json:"votes_bit_array"` PeerMaj23s map[peer.ID]DataHash `json:"peer_maj_23s"` }
More human readable JSON of the vote set NOTE: insufficient for unmarshalling from (compressed votes) TODO: make the peerMaj23s nicer to read (eg just the block hash)
type VoteSetMaj23Message ¶
type VoteSetMaj23Message struct { Height int64 Round int32 Type pb.SignedMsgType DataHash DataHash }
VoteSetMaj23Message is sent to indicate that a given BlockID has seen +2/3 votes.
func (*VoteSetMaj23Message) String ¶
func (m *VoteSetMaj23Message) String() string
String returns a string representation.
func (*VoteSetMaj23Message) ValidateBasic ¶
func (m *VoteSetMaj23Message) ValidateBasic() error
ValidateBasic performs basic validation.