mirror of
https://github.com/QuilibriumNetwork/ceremonyclient.git
synced 2026-02-21 10:27:26 +08:00
* wip: conversion of hotstuff from flow into Q-oriented model * bulk of tests * remaining non-integration tests * add integration test, adjust log interface, small tweaks * further adjustments, restore full pacemaker shape * add component lifecycle management+supervisor * further refinements * resolve timeout hanging * mostly finalized state for consensus * bulk of engine swap out * lifecycle-ify most types * wiring nearly complete, missing needed hooks for proposals * plugged in, vetting message validation paths * global consensus, plugged in and verified * app shard now wired in too * do not decode empty keys.yml (#456) * remove obsolete engine.maxFrames config parameter (#454) * default to Info log level unless debug is enabled (#453) * respect config's "logging" section params, remove obsolete single-file logging (#452) * Trivial code cleanup aiming to reduce Go compiler warnings (#451) * simplify range traversal * simplify channel read for single select case * delete rand.Seed() deprecated in Go 1.20 and no-op as of Go 1.24 * simplify range traversal * simplify channel read for single select case * remove redundant type from array * simplify range traversal * simplify channel read for single select case * RC slate * finalize 2.1.0.5 * Update comments in StrictMonotonicCounter Fix comment formatting and clarify description. --------- Co-authored-by: Black Swan <3999712+blacks1ne@users.noreply.github.com>
74 lines
3.7 KiB
Go
74 lines
3.7 KiB
Go
package consensus
|
|
|
|
import "source.quilibrium.com/quilibrium/monorepo/consensus/models"
|
|
|
|
// SafetyRules enforces all consensus rules that guarantee safety. It produces
|
|
// votes for the given states or TimeoutState for the given ranks, only if all
|
|
// safety rules are satisfied. In particular, SafetyRules guarantees a
|
|
// foundational security theorem for HotStuff, which we utilize also outside of
|
|
// consensus (e.g. queuing pending states for execution, verification, sealing
|
|
// etc):
|
|
//
|
|
// THEOREM: For each rank, there can be at most 1 certified state.
|
|
//
|
|
// Implementations are generally *not* concurrency safe.
|
|
type SafetyRules[StateT models.Unique, VoteT models.Unique] interface {
|
|
// ProduceVote takes a state proposal and current rank, and decides whether to
|
|
// vote for the state. Voting is deterministic, i.e. voting for same proposal
|
|
// will always result in the same vote.
|
|
// Returns:
|
|
// * (vote, nil): On the _first_ state for the current rank that is safe to
|
|
// vote for. Subsequently, voter does _not_ vote for any _other_ state with
|
|
// the same (or lower) rank. SafetyRules internally caches and persists its
|
|
// latest vote. As long as the SafetyRules' internal state remains
|
|
// unchanged, ProduceVote will return its cached for identical inputs.
|
|
// * (nil, model.NoVoteError): If the safety module decides that it is not
|
|
// safe to vote for the given state. This is a sentinel error and
|
|
// _expected_ during normal operation.
|
|
// All other errors are unexpected and potential symptoms of uncovered edge
|
|
// cases or corrupted internal state (fatal).
|
|
ProduceVote(
|
|
proposal *models.SignedProposal[StateT, VoteT],
|
|
curRank uint64,
|
|
) (*VoteT, error)
|
|
|
|
// ProduceTimeout takes current rank, highest locally known QC and TC
|
|
// (optional, must be nil if and only if QC is for previous rank) and decides
|
|
// whether to produce timeout for current rank.
|
|
// Returns:
|
|
// * (timeout, nil): It is safe to timeout for current rank using newestQC
|
|
// and lastRankTC.
|
|
// * (nil, model.NoTimeoutError): If replica is not part of the authorized
|
|
// consensus committee (anymore) and therefore is not authorized to produce
|
|
// a valid timeout state. This sentinel error is _expected_ during normal
|
|
// operation, e.g. during the grace-period after Rank switchover or after
|
|
// the replica self-ejected.
|
|
// All other errors are unexpected and potential symptoms of uncovered edge
|
|
// cases or corrupted internal state (fatal).
|
|
ProduceTimeout(
|
|
curRank uint64,
|
|
newestQC models.QuorumCertificate,
|
|
lastRankTC models.TimeoutCertificate,
|
|
) (*models.TimeoutState[VoteT], error)
|
|
|
|
// SignOwnProposal takes an unsigned state proposal and produces a vote for
|
|
// it. Vote is a cryptographic commitment to the proposal. By adding the vote
|
|
// to an unsigned proposal, the caller constructs a signed state proposal.
|
|
// This method has to be used only by the leader, which must be the proposer
|
|
// of the state (or an exception is returned).
|
|
// Implementors must guarantee that:
|
|
// - vote on the proposal satisfies safety rules
|
|
// - maximum one proposal is signed per rank
|
|
// Returns:
|
|
// * (vote, nil): the passed unsigned proposal is a valid one, and it's safe
|
|
// to make a proposal. Subsequently, leader does _not_ produce any _other_
|
|
// proposal with the same (or lower) rank.
|
|
// * (nil, model.NoVoteError): according to HotStuff's Safety Rules, it is
|
|
// not safe to sign the given proposal. This could happen because we have
|
|
// already proposed or timed out for the given rank. This is a sentinel
|
|
// error and _expected_ during normal operation.
|
|
// All other errors are unexpected and potential symptoms of uncovered edge
|
|
// cases or corrupted internal state (fatal).
|
|
SignOwnProposal(unsignedProposal *models.Proposal[StateT]) (*VoteT, error)
|
|
}
|