Documentation
¶
Index ¶
- Constants
- Variables
- func ErrAggregateSignature(err error) lib.ErrorI
- func ErrDuplicateProposerMessage() lib.ErrorI
- func ErrDuplicateVote() lib.ErrorI
- func ErrEmptyMessage() lib.ErrorI
- func ErrFailedSafeNodePredicate() lib.ErrorI
- func ErrInvalidPartialSignature() lib.ErrorI
- func ErrInvalidPublicKey() lib.ErrorI
- func ErrInvalidSignatureLength() lib.ErrorI
- func ErrMismatchPublicKeys() lib.ErrorI
- func ErrMismatchedProposals() lib.ErrorI
- func ErrNoSafeNodeJustification() lib.ErrorI
- func ErrPartialSignatureEmpty() lib.ErrorI
- func ErrUnableToAddSigner(err error) lib.ErrorI
- func ErrUnknownConsensusMsg(t proto.Message) lib.ErrorI
- func IsCandidate(votingPower, totalVotingPower, expectedCandidates uint64, vrfOut []byte) bool
- func SelectProposerFromCandidates(candidates []VRFCandidate, data *lib.SortitionData, v *lib.ConsensusValidators) (proposerPubKey []byte)
- func Sortition(p *SortitionParams) (out []byte, vrf *lib.Signature, isCandidate bool)
- func VRF(lastNProposers [][]byte, rootHeight, height, round uint64, ...) *lib.Signature
- func VerifyCandidate(p *SortitionVerifyParams) (out []byte, isCandidate bool)
- type BFT
- func (b *BFT) AddDSE(e *DoubleSignEvidences, ev *DoubleSignEvidence) (err lib.ErrorI)
- func (b *BFT) AddPacemakerMessage(msg *Message) (err lib.ErrorI)
- func (b *BFT) AddPartialQC(m *Message) (err lib.ErrorI)
- func (b *BFT) AddProposal(m *Message) lib.ErrorI
- func (b *BFT) AddVote(vote *Message) lib.ErrorI
- func (b *BFT) BlockToHash(blk []byte) (hash []byte)
- func (b *BFT) CheckProposerAndProposal(msg *Message) (interrupt bool)
- func (b *BFT) CheckProposerMessage(x *Message) (isPartialQC bool, err lib.ErrorI)
- func (b *BFT) CheckReplicaMessage(x *Message) lib.ErrorI
- func (b *BFT) GetBlockHash() (hash []byte)
- func (b *BFT) GetElectionCandidates() (candidates []VRFCandidate)
- func (b *BFT) GetLeadingVote() (m *Message, maxVotePercent uint64, maxVotes uint64)
- func (b *BFT) GetLocalDSE() DoubleSignEvidences
- func (b *BFT) GetMajorityVote() (m *Message, sig *lib.AggregateSignature, err lib.ErrorI)
- func (b *BFT) GetProposal() *Message
- func (b *BFT) HandleMessage(message proto.Message) lib.ErrorI
- func (b *BFT) HandlePhase()
- func (b *BFT) IsProposer(id []byte) bool
- func (b *BFT) NewHeight(keepLocks ...bool)
- func (b *BFT) NewRound(newHeight bool)
- func (b *BFT) Pacemaker()
- func (b *BFT) PhaseHas23Maj() bool
- func (b *BFT) ProcessDSE(dse ...*DoubleSignEvidence) (results []*lib.DoubleSigner, e lib.ErrorI)
- func (b *BFT) ProposalsResetForNewCommittee()
- func (b *BFT) RoundInterrupt()
- func (b *BFT) RunVDF(seed []byte) (err lib.ErrorI)
- func (b *BFT) SafeNode(msg *Message) lib.ErrorI
- func (b *BFT) SelfIsProposer() bool
- func (b *BFT) SelfIsValidator() bool
- func (b *BFT) SetTimerForNextPhase(processTime time.Duration)
- func (b *BFT) SetWaitTimers(phaseWaitTime, processTime time.Duration)
- func (b *BFT) Start()
- func (b *BFT) StartCommitPhase()
- func (b *BFT) StartCommitProcessPhase()
- func (b *BFT) StartElectionPhase()
- func (b *BFT) StartElectionVotePhase()
- func (b *BFT) StartPrecommitPhase()
- func (b *BFT) StartPrecommitVotePhase()
- func (b *BFT) StartProposePhase()
- func (b *BFT) StartProposeVotePhase()
- func (b *BFT) VDFSeed() ([]byte, lib.ErrorI)
- func (b *BFT) ValidateByzantineEvidence(slashRecipients *lib.SlashRecipients, be *ByzantineEvidence) lib.ErrorI
- func (b *BFT) VerifyVDF(vote *Message) (bool, lib.ErrorI)
- func (b *BFT) WaitTime(phase Phase, round uint64) (waitTime time.Duration)
- type ByzantineEvidence
- type Controller
- type DoubleSignEvidence
- func (x *DoubleSignEvidence) Check(vs lib.ValidatorSet, view *lib.View, minimumEvidenceHeight uint64) lib.ErrorI
- func (x *DoubleSignEvidence) CheckBasic() lib.ErrorI
- func (*DoubleSignEvidence) Descriptor() ([]byte, []int)deprecated
- func (x *DoubleSignEvidence) GetVoteA() *lib.QuorumCertificate
- func (x *DoubleSignEvidence) GetVoteB() *lib.QuorumCertificate
- func (*DoubleSignEvidence) ProtoMessage()
- func (x *DoubleSignEvidence) ProtoReflect() protoreflect.Message
- func (x *DoubleSignEvidence) Reset()
- func (x *DoubleSignEvidence) String() string
- type DoubleSignEvidences
- func (*DoubleSignEvidences) Descriptor() ([]byte, []int)deprecated
- func (x *DoubleSignEvidences) GetDeDuplicator() map[string]bool
- func (x *DoubleSignEvidences) GetEvidence() []*DoubleSignEvidence
- func (*DoubleSignEvidences) ProtoMessage()
- func (x *DoubleSignEvidences) ProtoReflect() protoreflect.Message
- func (x *DoubleSignEvidences) Reset()
- func (x *DoubleSignEvidences) String() string
- type Message
- func (*Message) Descriptor() ([]byte, []int)deprecated
- func (x *Message) GetHeader() *lib.View
- func (x *Message) GetHighQc() *lib.QuorumCertificate
- func (x *Message) GetLastDoubleSignEvidence() []*DoubleSignEvidence
- func (x *Message) GetQc() *lib.QuorumCertificate
- func (x *Message) GetSignature() *lib.Signature
- func (x *Message) GetVdf() *crypto.VDF
- func (x *Message) GetVrf() *lib.Signature
- func (x *Message) IsPacemakerMessage() bool
- func (x *Message) IsProposerMessage() bool
- func (x *Message) IsReplicaMessage() bool
- func (*Message) ProtoMessage()
- func (x *Message) ProtoReflect() protoreflect.Message
- func (x *Message) Reset()
- func (x *Message) Sign(privateKey crypto.PrivateKeyI) lib.ErrorI
- func (x *Message) SignBytes() (signBytes []byte)
- func (x *Message) String() string
- type PacemakerMessages
- type PartialQCs
- type Phase
- type ProposalsForHeight
- type QC
- type ResetBFT
- type SortitionParams
- type SortitionVerifyParams
- type VRFCandidate
- type ValSet
- type VoteSet
- type VotesForHeight
Constants ¶
const ( Election = lib.Phase_ELECTION ElectionVote = lib.Phase_ELECTION_VOTE Propose = lib.Phase_PROPOSE ProposeVote = lib.Phase_PROPOSE_VOTE Precommit = lib.Phase_PRECOMMIT PrecommitVote = lib.Phase_PRECOMMIT_VOTE Commit = lib.Phase_COMMIT CommitProcess = lib.Phase_COMMIT_PROCESS RoundInterrupt = lib.Phase_ROUND_INTERRUPT Pacemaker = lib.Phase_PACEMAKER BlockTimeToVDFTargetCoefficient = .65 // how much the commit process time is reduced for VDF processing )
Variables ¶
var File_bft_proto protoreflect.FileDescriptor
Functions ¶
func ErrAggregateSignature ¶
func ErrDuplicateVote ¶
func ErrEmptyMessage ¶
func ErrInvalidPublicKey ¶
func ErrMismatchPublicKeys ¶
func ErrMismatchedProposals ¶
func ErrUnableToAddSigner ¶
func IsCandidate ¶
IsCandidate: determines if the Validator is a Candidate from their voting power and VRF output - Creates a candidacy cutoff point for a Validator based on their stake (more stake = higher chance of being a Candidate) - Checks if number(vrfOut) is below the cutoff
func SelectProposerFromCandidates ¶
func SelectProposerFromCandidates(candidates []VRFCandidate, data *lib.SortitionData, v *lib.ConsensusValidators) (proposerPubKey []byte)
SelectProposerFromCandidates() chooses the `Leader` by comparing the pre-validated VRF Candidates, no candidates falls back to StakeWeightedRandom selection
func Sortition ¶
func Sortition(p *SortitionParams) (out []byte, vrf *lib.Signature, isCandidate bool)
Sortition() runs the VRF and uses the Hash(output) to determine if IsCandidate
func VRF ¶
func VRF(lastNProposers [][]byte, rootHeight, height, round uint64, privateKey crypto.PrivateKeyI) *lib.Signature
VRF() 'Practical Verifiable Random Function': a function that given a secret key and a message, generates a unique random-looking number along with a certificate that anyone can check to confirm that this number was produced correctly from that specific message, without revealing the private key or how the number was made. NOTE: Academically speaking, this is not a true VRF because BLS signatures are not perfectly uniformly distributed in the strictest mathematical sense. The slight deviation from perfect uniformity does not significantly affect the security of BLS signatures are still considered secure and suitable for applications like digital signatures, VRFs, and blockchain consensus mechanisms.
func VerifyCandidate ¶
func VerifyCandidate(p *SortitionVerifyParams) (out []byte, isCandidate bool)
VerifyCandidate verifies that a remote peer is in fact a Leader Candidate by running the IsCandidate function using the provided VRF out
Types ¶
type BFT ¶
type BFT struct { *lib.View // the current period during which the BFT is occurring (CreatedHeight/Round/Phase) Votes VotesForHeight // 'votes' received from Replica (non-leader) Validators Proposals ProposalsForHeight // 'proposals' received from the Leader Validator(s) ProposerKey []byte // the public key of the proposer ValidatorSet ValSet // the current set of Validators HighQC *QC // the highest PRECOMMIT quorum certificate the node is aware of for this CreatedHeight Block []byte // the current Block being voted on (the foundational unit of the blockchain) BlockHash []byte // the current hash of the block being voted on Results *lib.CertificateResult // the current Result being voted on (reward and slash recipients) SortitionData *lib.SortitionData // the current data being used for VRF+CDF Leader Election VDFService *lib.VDFService // the verifiable delay service, run once per block as a deterrent against long-range-attacks HighVDF *crypto.VDF // the highest VDF among replicas - if the chain is using VDF for long-range-attack protection ByzantineEvidence *ByzantineEvidence // evidence of faulty or malicious Validators collected during the BFT process PartialQCs PartialQCs // potentially implicating evidence that may turn into ByzantineEvidence if paired with an equivocating QC PacemakerMessages PacemakerMessages // View messages from the current ValidatorSet allowing the node to synchronize to the highest +2/3 seen Round Controller // reference to the Controller for callbacks like producing and validating the proposal via the plugin or gossiping commit message ResetBFT chan ResetBFT // trigger that resets the BFT due to a new Target block or a new Canopy block PhaseTimer *time.Timer // ensures the node waits for a configured duration (Round x phaseTimeout) to allow for full voter participation PublicKey []byte // self consensus public key PrivateKey crypto.PrivateKeyI // self consensus private key Config lib.Config // self configuration Metrics *lib.Metrics // telemetry // contains filtered or unexported fields }
BFT is a structure that holds data for a Hotstuff BFT instance
func New ¶
func New(c lib.Config, valKey crypto.PrivateKeyI, rootHeight, height uint64, con Controller, vdfEnabled bool, m *lib.Metrics, l lib.LoggerI) (*BFT, lib.ErrorI)
New() creates a new instance of HotstuffBFT for a specific Committee
func (*BFT) AddDSE ¶
func (b *BFT) AddDSE(e *DoubleSignEvidences, ev *DoubleSignEvidence) (err lib.ErrorI)
AddDSE() validates and adds new DoubleSign Evidence to a list of DoubleSignEvidences
func (*BFT) AddPacemakerMessage ¶
AddPacemakerMessage() adds the 'View' message to the list (keyed by public key string)
func (*BFT) AddPartialQC ¶
AddPartialQC() saves a non-majority Quorum Certificate which is a big hint of faulty behavior
func (*BFT) AddProposal ¶
AddProposal() saves a validated proposal from the Leader in memory
func (*BFT) BlockToHash ¶
BlockToHash() converts block bytes into a hash
func (*BFT) CheckProposerAndProposal ¶
CheckProposerAndProposal() ensures the Leader message has the correct sender public key and correct ProposalHash
func (*BFT) CheckProposerMessage ¶
CheckProposerMessage() validates an inbound message from the Leader Validator
func (*BFT) CheckReplicaMessage ¶
CheckReplicaMessage() validates an inbound message from a Replica Validator
func (*BFT) GetBlockHash ¶
GetBlockHash() retrieves the hash from the block
func (*BFT) GetElectionCandidates ¶
func (b *BFT) GetElectionCandidates() (candidates []VRFCandidate)
GetElectionCandidates() retrieves ELECTION messages, verifies, and returns the candidate(s)
func (*BFT) GetLeadingVote ¶
GetLeadingVote() returns the unique Vote Message that has the most power behind it and the number and percent voted that voted for it
func (*BFT) GetLocalDSE ¶
func (b *BFT) GetLocalDSE() DoubleSignEvidences
GetLocalDSE() returns the double sign evidences collected by the local node
func (*BFT) GetMajorityVote ¶
GetMajorityVote() returns the Message and AggregateSignature with a VoteSet with a +2/3 majority from the Replicas NOTE: Votes for a specific Height-Round-Phase are organized by `Payload Hash` to ensure that all Replicas are voting on the same proposal
func (*BFT) GetProposal ¶
GetProposal() retrieves a proposal from the leader at the latest View
func (*BFT) HandleMessage ¶
HandleMessage handles and routes incoming consensus message from a Validator peer
func (*BFT) HandlePhase ¶
func (b *BFT) HandlePhase()
HandlePhase() is the main BFT Phase stepping loop
func (*BFT) IsProposer ¶
IsProposer() returns true if specific public key is the expected Leader public key
func (*BFT) NewHeight ¶
NewHeight() initializes / resets consensus variables preparing for the NewHeight
func (*BFT) NewRound ¶
NewRound() initializes the VoteSet and Proposals cache for the next round - increments the round count if not NewHeight (goes to Round 0)
func (*BFT) Pacemaker ¶
func (b *BFT) Pacemaker()
Pacemaker() begins the Pacemaker process after ROUND-INTERRUPT timeout occurs - sets the highest round that +2/3rds majority of replicas have seen
func (*BFT) PhaseHas23Maj ¶
PhaseHas23Maj() returns true if the node received enough messages to optimistically move forward
func (*BFT) ProcessDSE ¶
func (b *BFT) ProcessDSE(dse ...*DoubleSignEvidence) (results []*lib.DoubleSigner, e lib.ErrorI)
ProcessDSE() validates each piece of double sign evidence and returns a list of double signers
func (*BFT) ProposalsResetForNewCommittee ¶
func (b *BFT) ProposalsResetForNewCommittee()
ProposalsResetForNewCommittee resets proposals when the root chain sends a 'NewCommittee' reset command
func (*BFT) RoundInterrupt ¶
func (b *BFT) RoundInterrupt()
RoundInterrupt() begins the ROUND-INTERRUPT phase after any phase errors ROUND-INTERRUPT: - Replica sends current View message to other replicas (Pacemaker vote)
func (*BFT) SafeNode ¶
SafeNode is the codified Hotstuff SafeNodePredicate: - Protects replicas who may have committed to a previous value by locking on that value when signing a Precommit Message - May unlock if new proposer:
- SAFETY: uses the same value the replica is locked on (safe because it will match the value that may have been committed by others)
- LIVENESS: uses a lock with a higher round (safe because replica is convinced no other replica committed to their locked value as +2/3rds locked on a higher round)
func (*BFT) SelfIsProposer ¶
SelfIsPropose() returns true if this node is the Leader
func (*BFT) SelfIsValidator ¶
SelfIsValidator() returns true if this node is part of the ValSet
func (*BFT) SetTimerForNextPhase ¶
SetTimerForNextPhase() calculates the wait time for a specific phase/Round, resets the Phase wait timer
func (*BFT) SetWaitTimers ¶
SetWaitTimers() sets the phase wait timer - Phase Timeout ensures the node waits for a configured duration (Round x phaseTimeout) to allow for full voter participation This design balances synchronization speed during adverse conditions with maximizing voter participation under normal conditions
func (*BFT) Start ¶
func (b *BFT) Start()
Start() initiates the HotStuff BFT service. - Phase Timeout ensures the node waits for a configured duration (Round x phaseTimeout) to allow for full voter participation This design balances synchronization speed during adverse conditions with maximizing voter participation under normal conditions - ResetBFT occurs upon receipt of a Quorum Certificate
- (a) Canopy chainId <committeeSet changed, reset but keep locks to prevent conflicting validator sets between peers during a view change>
- (b) Target chainId <mission accomplished, move to next height>
func (*BFT) StartCommitPhase ¶
func (b *BFT) StartCommitPhase()
StartCommitPhase() begins the Commit after the PRECOMMIT-VOTE phase timeout COMMIT PHASE: - Leader reviews the collected Replica PRECOMMIT votes (votes signing off on the validity of the Leader's Proposal)
- Aggregates the signatures from the Replicas to form a +2/3 threshold multi-signature
- Leader creates a COMMIT message with the Proposal hashes and justifies the message with the +2/3 threshold multi-signature
func (*BFT) StartCommitProcessPhase ¶
func (b *BFT) StartCommitProcessPhase()
StartCommitProcessPhase() begins the COMMIT-PROCESS phase after the COMMIT phase timeout COMMIT-PROCESS PHASE: - Replica reviews the message from the Leader by validating the justification (+2/3 multi-sig) proving that +2/3rds of Replicas are locked on the Proposal - Replica clears Byzantine Evidence - Replica gossips the Quorum Certificate message to Peers - If Leader, send the Proposal (reward) Transaction
func (*BFT) StartElectionPhase ¶
func (b *BFT) StartElectionPhase()
StartElectionPhase() begins the ElectionPhase after the CommitProcess (normal) or Pacemaker (previous Round failure) timeouts ELECTION PHASE: - Replicas run the Cumulative Distribution Function and a 'practical' Verifiable Random Function - If they are a candidate they send the VRF Out to the replicas
func (*BFT) StartElectionVotePhase ¶
func (b *BFT) StartElectionVotePhase()
StartElectionVotePhase() begins the ElectionVotePhase after the ELECTION phase timeout ELECTION-VOTE PHASE: - Replicas review messages from Candidates and determine the 'Leader' by the highest VRF - If no Candidate messages received, fallback to stake weighted random 'Leader' selection - Replicas send a signed (aggregable) ELECTION vote to the Leader (Proposer) - With this vote, the Replica attaches any Byzantine evidence or 'Locked' QC they have collected as well as their VDF output
func (*BFT) StartPrecommitPhase ¶
func (b *BFT) StartPrecommitPhase()
StartPrecommitPhase() begins the PrecommitPhase after the PROPOSE-VOTE phase timeout PRECOMMIT PHASE: - Leader reviews the collected Replica PROPOSE votes (votes signing off on the validity of the Leader's Proposal)
- Aggregates the signatures from the Replicas to form a +2/3 threshold multi-signature
- Leader creates a PRECOMMIT message with the Proposal hashes and justifies the message with the +2/3 threshold multi-signature
func (*BFT) StartPrecommitVotePhase ¶
func (b *BFT) StartPrecommitVotePhase()
StartPrecommitVotePhase() begins the Precommit vote after the PRECOMMIT phase timeout PRECOMMIT-VOTE PHASE: - Replica reviews the message from the Leader by validating the justification (+2/3 multi-sig) proving that +2/3rds of Replicas approved the Proposal - Replica `Locks` on the Proposal to protect those who may commit as a consequence of providing the aggregable signature - Replicas send a signed (aggregable) PROPOSE vote to the Leader
func (*BFT) StartProposePhase ¶
func (b *BFT) StartProposePhase()
StartProposePhase() begins the ProposePhase after the ELECTION-VOTE phase timeout PROPOSE PHASE: - Leader reviews the collected vote messages from Replicas
- Determines the highest 'lock' (HighQC) if one exists for this CreatedHeight
- Combines any ByzantineEvidence sent from Replicas into their own
- Aggregates the signatures from the Replicas to form a +2/3 threshold multi-signature
- If a HighQC exists, use that as the Proposal - if not, the Leader produces a Proposal with ByzantineEvidence using the specific plugin - Leader creates a PROPOSE message from the Proposal and justifies the message with the +2/3 threshold multi-signature
func (*BFT) StartProposeVotePhase ¶
func (b *BFT) StartProposeVotePhase()
StartProposeVotePhase() begins the ProposeVote after the PROPOSE phase timeout PROPOSE-VOTE PHASE: - Replica reviews the message from the Leader by validating the justification (+2/3 multi-sig) proving that they are in-fact the leader - If the Replica is currently Locked on a previous Proposal for this CreatedHeight, the new Proposal must pass the SAFE-NODE-PREDICATE - Replica Validates the proposal using the byzantine evidence and the specific plugin - Replicas send a signed (aggregable) PROPOSE vote to the Leader
func (*BFT) ValidateByzantineEvidence ¶
func (b *BFT) ValidateByzantineEvidence(slashRecipients *lib.SlashRecipients, be *ByzantineEvidence) lib.ErrorI
ValidateByzantineEvidence() ensures the DoubleSigners in the Proposal are supported by the ByzantineEvidence
type ByzantineEvidence ¶
type ByzantineEvidence struct {
DSE DoubleSignEvidences // Evidence of `DoubleSigning`: Signing two different messages for the same View is against protocol rules (breaks protocol safety)
}
ByzantineEvidence represents a collection of evidence that supports byzantine behavior during the BFT lifecycle this Evidence is circulated to the Leader of a Round and is processed in the execution of Reward Transactions
type Controller ¶
type Controller interface { Lock() Unlock() // ChainHeight returns the height of the target-chain ChainHeight() uint64 // RootChainHeight returns the height of the root-chain RootChainHeight() uint64 // ProduceProposal() as a Leader, create a Proposal in the form of a block and certificate results ProduceProposal(be *ByzantineEvidence, vdf *crypto.VDF) (block []byte, results *lib.CertificateResult, err lib.ErrorI) // ValidateCertificate() as a Replica, validates the leader proposal ValidateProposal(qc *lib.QuorumCertificate, evidence *ByzantineEvidence) lib.ErrorI // LoadCertificate() gets the Quorum Certificate from the chainId-> plugin at a certain height LoadCertificate(height uint64) (*lib.QuorumCertificate, lib.ErrorI) // GossipBlock() is a P2P call to gossip a completed Quorum Certificate with a Proposal GossipBlock(certificate *lib.QuorumCertificate, sender []byte) // SendToSelf() is a P2P call to directly send a completed Quorum Certificate to self SelfSendBlock(qc *lib.QuorumCertificate) // SendToReplicas() is a P2P call to directly send a Consensus message to all Replicas SendToReplicas(replicas lib.ValidatorSet, msg lib.Signable) // SendToProposer() is a P2P call to directly send a Consensus message to the Leader SendToProposer(msg lib.Signable) // LoadRootChainId() returns the unique identifier of the root chain LoadRootChainId(height uint64) (rootChainId uint64) // IsOwnRoot() returns a boolean if self chain is root LoadIsOwnRoot() bool // Syncing() returns true if the plugin is currently syncing Syncing() *atomic.Bool // SendCertificateResultsTx() is a P2P call that allows a Leader to submit their CertificateResults (reward) transaction SendCertificateResultsTx(certificate *lib.QuorumCertificate) // LoadCommittee() loads the ValidatorSet operating under ChainId LoadCommittee(rootChainId, rootHeight uint64) (lib.ValidatorSet, lib.ErrorI) // LoadCommitteeHeightInState() loads the committee information from state as updated by the quorum certificates LoadCommitteeData() (*lib.CommitteeData, lib.ErrorI) // LoadLastProposers() loads the last Canopy committee proposers for sortition data LoadLastProposers(rootHeight uint64) (*lib.Proposers, lib.ErrorI) // LoadMinimumEvidenceHeight() loads the Canopy enforced minimum height for valid Byzantine Evidence LoadMinimumEvidenceHeight() (uint64, lib.ErrorI) // IsValidDoubleSigner() checks to see if the double signer is valid for this specific height IsValidDoubleSigner(height uint64, address []byte) bool }
Controller defines the expected parent interface for the BFT structure, providing various callback functions that manage interactions with BFT and other parts of the application like FSM, P2P and Storage
type DoubleSignEvidence ¶
type DoubleSignEvidence struct { // vote_a: one of two quorum certificates that are of the same View that have conflicting payloads both that are // signed by one or more validators VoteA *lib.QuorumCertificate `protobuf:"bytes,1,opt,name=vote_a,json=voteA,proto3" json:"voteA"` // @gotags: json:"voteA" // vote_b: one of two quorum certificates that are of the same View that have conflicting payloads both that are // signed by one or more validators VoteB *lib.QuorumCertificate `protobuf:"bytes,2,opt,name=vote_b,json=voteB,proto3" json:"voteB"` // @gotags: json:"voteB" // contains filtered or unexported fields }
double_sign_evidence is proof that a validator has signed two conflicting proposals at the same block height and round showing dishonest or faulty behavior and triggering slashes to protect the network’s integrity
func (*DoubleSignEvidence) Check ¶
func (x *DoubleSignEvidence) Check(vs lib.ValidatorSet, view *lib.View, minimumEvidenceHeight uint64) lib.ErrorI
Check() validates the double sign evidence
func (*DoubleSignEvidence) CheckBasic ¶
func (x *DoubleSignEvidence) CheckBasic() lib.ErrorI
CheckBasic() executes basic sanity checks on the DoubleSign Evidence It's important to note that DoubleSign evidence may be processed for any height thus it's never validated against 'current height'
func (*DoubleSignEvidence) Descriptor
deprecated
func (*DoubleSignEvidence) Descriptor() ([]byte, []int)
Deprecated: Use DoubleSignEvidence.ProtoReflect.Descriptor instead.
func (*DoubleSignEvidence) GetVoteA ¶
func (x *DoubleSignEvidence) GetVoteA() *lib.QuorumCertificate
func (*DoubleSignEvidence) GetVoteB ¶
func (x *DoubleSignEvidence) GetVoteB() *lib.QuorumCertificate
func (*DoubleSignEvidence) ProtoMessage ¶
func (*DoubleSignEvidence) ProtoMessage()
func (*DoubleSignEvidence) ProtoReflect ¶
func (x *DoubleSignEvidence) ProtoReflect() protoreflect.Message
func (*DoubleSignEvidence) Reset ¶
func (x *DoubleSignEvidence) Reset()
func (*DoubleSignEvidence) String ¶
func (x *DoubleSignEvidence) String() string
type DoubleSignEvidences ¶
type DoubleSignEvidences struct { // evidence: a list of double sign evidence Evidence []*DoubleSignEvidence `protobuf:"bytes,1,rep,name=Evidence,proto3" json:"evidence"` // @gotags: json:"evidence" // de-duplicator: a map structure that prevents accidental collision of evidence in the list DeDuplicator map[string]bool `` // @gotags: json:"deduplicator" /* 156-byte string literal not displayed */ // contains filtered or unexported fields }
double_sign_evidences is a de-duplicated list of double sign evidence
func NewDSE ¶
func NewDSE(dse ...[]*DoubleSignEvidence) DoubleSignEvidences
NewDSE() creates a list of DoubleSignEvidences with a built-in DeDuplicator
func (*DoubleSignEvidences) Descriptor
deprecated
func (*DoubleSignEvidences) Descriptor() ([]byte, []int)
Deprecated: Use DoubleSignEvidences.ProtoReflect.Descriptor instead.
func (*DoubleSignEvidences) GetDeDuplicator ¶
func (x *DoubleSignEvidences) GetDeDuplicator() map[string]bool
func (*DoubleSignEvidences) GetEvidence ¶
func (x *DoubleSignEvidences) GetEvidence() []*DoubleSignEvidence
func (*DoubleSignEvidences) ProtoMessage ¶
func (*DoubleSignEvidences) ProtoMessage()
func (*DoubleSignEvidences) ProtoReflect ¶
func (x *DoubleSignEvidences) ProtoReflect() protoreflect.Message
func (*DoubleSignEvidences) Reset ¶
func (x *DoubleSignEvidences) Reset()
func (*DoubleSignEvidences) String ¶
func (x *DoubleSignEvidences) String() string
type Message ¶
type Message struct { // header: the current view of the consensus process according to the sender Header *lib.View `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"` // vrf: the output of the vrf allowing participants to trust the leader was chosen fairly and securely. Vrf *lib.Signature `protobuf:"bytes,2,opt,name=vrf,proto3" json:"vrf,omitempty"` // qc: proof that a minimum number of validators have agreed on a proposal, typically represented by their collective // signatures (aggregated by the leader), which confirms consensus and allows the network to move forward Qc *lib.QuorumCertificate `protobuf:"bytes,3,opt,name=qc,proto3" json:"qc,omitempty"` // high_qc: the latest 'round' quorum certificate where a +2/3rds of validators reached quorum for the PRECOMMIT phase // This serves as a secure proof to protect those who may have committed in a type II asynchronous network HighQc *lib.QuorumCertificate `protobuf:"bytes,4,opt,name=high_qc,json=highQc,proto3" json:"highQC"` // @gotags: json:"highQC" // double_sign_evidence: proof that a validator has signed two conflicting proposals at the same View LastDoubleSignEvidence []*DoubleSignEvidence `protobuf:"bytes,5,rep,name=last_double_sign_evidence,json=lastDoubleSignEvidence,proto3" json:"lastDoubleSignEvidence"` // @gotags: json:"lastDoubleSignEvidence" // vdf: a Verifiable Delay Function is a cryptographic function that takes a fixed time to compute // but is fast to verify, deterring historical fork attacks like the long-range-attack Vdf *crypto.VDF `protobuf:"bytes,6,opt,name=vdf,proto3" json:"vdf,omitempty"` // signature: the digital signature of the sender of the consensus message Signature *lib.Signature `protobuf:"bytes,7,opt,name=signature,proto3" json:"signature,omitempty"` // contains filtered or unexported fields }
***************************************************************************************************** This file is auto-generated from source files in `/lib/.proto/*` using Protocol Buffers (protobuf)
Protobuf is a language-neutral, platform-neutral serialization format. It allows users to define objects in a way that’s both efficient to store and fast to transmit over the network. These definitions are compiled into code that *enables different systems and programming languages to communicate in a byte-perfect manner*
To update these structures, make changes to the source .proto files, then recompile to regenerate this file. These auto-generated files are easily recognized by checking for a `.pb.go` ending ***************************************************************************************************** _ _ _ (Consensus) Message
This structure defines the wire message used in the BFT consensus process. Validators use these messages to propose, vote on, and confirm blocks, allowing the network agree on a single version of the blockchain, even in there exists faulty or malicious actors.
func (*Message) Descriptor
deprecated
func (*Message) GetHighQc ¶
func (x *Message) GetHighQc() *lib.QuorumCertificate
func (*Message) GetLastDoubleSignEvidence ¶
func (x *Message) GetLastDoubleSignEvidence() []*DoubleSignEvidence
func (*Message) GetQc ¶
func (x *Message) GetQc() *lib.QuorumCertificate
func (*Message) GetSignature ¶
func (*Message) IsPacemakerMessage ¶
IsPacemakerMessage() determines if the message should describe the View of a Validator for the Pacemaker logic
func (*Message) IsProposerMessage ¶
IsProposerMessage() determines if the message should originate from a Validator acting as a Leader
func (*Message) IsReplicaMessage ¶
IsReplicaMessage() determines if the message should originate from a Validator acting as a Replica (voter)
func (*Message) ProtoMessage ¶
func (*Message) ProtoMessage()
func (*Message) ProtoReflect ¶
func (x *Message) ProtoReflect() protoreflect.Message
func (*Message) Sign ¶
func (x *Message) Sign(privateKey crypto.PrivateKeyI) lib.ErrorI
Sign() is a convenience method for performing a digital signature with this message using a Private Key and fills the 'signature' field of the Message
type PacemakerMessages ¶
PacemakerMessages is a collection of 'View' messages keyed by each Replica's public key These messages help Replicas synchronize their Rounds more effectively during periods of instability or failure
type PartialQCs ¶
DoubleSignEvidence: By PartialQC
With < 1/3 Byzantine actors, two conflicting Quorum Certs with +2/3 majority cannot exist for the same view
Double signs can be detected when a leader sends a PartialQC (< +2/3 majority) to a replica, and that replica already holds a +2/3 majority QC for the same view (from another leader or an earlier message)
Correct replicas save PartialQCs to check for double-sign evidence, which they share with the next proposer during the ElectionVote phase
type ProposalsForHeight ¶
ProposalsForHeight are an in-memory list of messages received from the Leader NOTE: an array of Messages is required for the ELECTION phase as there can be multiple proposals if there is multiple Candidates
type SortitionParams ¶
type SortitionParams struct { *lib.SortitionData // the seed data used for sortition PrivateKey crypto.PrivateKeyI // the private key of the Validator }
SortitionParams are the input params to run the Sortition function
type SortitionVerifyParams ¶
type SortitionVerifyParams struct { *lib.SortitionData // seed data the peer used for sortition Signature []byte // the VRF out of the peer PublicKey crypto.PublicKeyI // the public key of the peer }
SortitionVerifyParams are the input params to verify the Sortition function
type VRFCandidate ¶
type VRFCandidate struct { PublicKey crypto.PublicKeyI // the public key of the Candidate Out []byte // the hash of the VRF signature }
VRFCandidate is a comparable structure that enables the selection of the Leader between candidates
type ValSet ¶
type ValSet = lib.ValidatorSet
type VoteSet ¶
type VoteSet struct { Vote *Message `json:"vote,omitempty"` TotalVotedPower uint64 `json:"totalVotedPower,omitempty"` // contains filtered or unexported fields }
VoteSet holds the unique Vote Message, a power count of the Replicas who have voted for this, and an aggregation of the Replicas signatures to prove the vote count