Documentation ¶
Index ¶
- type SafetyRules
- func (r *SafetyRules) IsSafeToTimeout(curView uint64, newestQC *flow.QuorumCertificate, ...) error
- func (r *SafetyRules) IsSafeToVote(proposal *model.Proposal) error
- func (r *SafetyRules) ProduceTimeout(curView uint64, newestQC *flow.QuorumCertificate, ...) (*model.TimeoutObject, error)
- func (r *SafetyRules) ProduceVote(proposal *model.Proposal, curView uint64) (*model.Vote, error)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type SafetyRules ¶
type SafetyRules struct {
// contains filtered or unexported fields
}
SafetyRules is a dedicated module that enforces consensus safety. This component has the sole authority to generate votes and timeouts. It follows voting and timeout rules for creating votes and timeouts respectively. Caller can be sure that created vote or timeout doesn't break safety and can be used in consensus process. SafetyRules relies on hotstuff.Persister to store latest state of hotstuff.SafetyData.
The voting rules implemented by SafetyRules are:
- Replicas vote strictly in increasing rounds
- Each block has to include a TC or a QC from the previous round. a. [Happy path] If the previous round resulted in a QC then new QC should extend it. b. [Recovery path] If the previous round did *not* result in a QC, the leader of the subsequent round *must* include a valid TC for the previous round in its block.
NOT safe for concurrent use.
func New ¶
func New( signer hotstuff.Signer, persist hotstuff.Persister, committee hotstuff.DynamicCommittee, ) (*SafetyRules, error)
New creates a new SafetyRules instance
func (*SafetyRules) IsSafeToTimeout ¶
func (r *SafetyRules) IsSafeToTimeout(curView uint64, newestQC *flow.QuorumCertificate, lastViewTC *flow.TimeoutCertificate) error
IsSafeToTimeout checks if it's safe to timeout with proposed data, i.e. timing out won't break safety. newestQC is the valid QC with the greatest view that we have observed. lastViewTC is the TC for the previous view (might be nil).
When generating a timeout, the inputs are provided by node-internal components. Failure to comply with the protocol is a symptom of an internal bug. We don't expect any errors during normal operations.
func (*SafetyRules) IsSafeToVote ¶
func (r *SafetyRules) IsSafeToVote(proposal *model.Proposal) error
IsSafeToVote checks if this proposal is valid in terms of voting rules, if voting for this proposal won't break safety rules. Expected errors during normal operations:
- NoVoteError if replica already acted during this view (either voted or generated timeout)
func (*SafetyRules) ProduceTimeout ¶
func (r *SafetyRules) ProduceTimeout(curView uint64, newestQC *flow.QuorumCertificate, lastViewTC *flow.TimeoutCertificate) (*model.TimeoutObject, error)
ProduceTimeout takes current view, highest locally known QC and TC (optional, must be nil if and only if QC is for previous view) and decides whether to produce timeout for current view. Returns:
- (timeout, nil): It is safe to timeout for current view using newestQC and lastViewTC.
- (nil, model.NoTimeoutError): If replica is not part of the authorized consensus committee (anymore) and therefore is not authorized to produce a valid timeout object. This sentinel error is _expected_ during normal operation, e.g. during the grace-period after Epoch switchover or after the replica self-ejected.
All other errors are unexpected and potential symptoms of uncovered edge cases or corrupted internal state (fatal).
func (*SafetyRules) ProduceVote ¶
ProduceVote will make a decision on whether it will vote for the given proposal, the returned error indicates whether to vote or not. To ensure that only safe proposals are being voted on, we check that the proposer is a valid committee member and that the proposal complies with voting rules. We expect that only well-formed proposals with valid signatures are submitted for voting. The curView is taken as input to ensure SafetyRules will only vote for proposals at current view and prevent double voting. Returns:
- (vote, nil): On the _first_ block for the current view that is safe to vote for. Subsequently, voter does _not_ vote for any other block with the same (or lower) view.
- (nil, model.NoVoteError): If the voter decides that it does not want to vote for the given block. 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).