github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/consensus/hotstuff/safety_rules.go (about)

     1  package hotstuff
     2  
     3  import (
     4  	"github.com/onflow/flow-go/consensus/hotstuff/model"
     5  	"github.com/onflow/flow-go/model/flow"
     6  )
     7  
     8  type SafetyData struct {
     9  	// LockedOneChainView is the head block's view of the newest 1-chain this replica has voted for.
    10  	// The 1-chain can be indirect.
    11  	//     <ยทยท <QC>[B0] <- <QC_B0>[B1] <- [my vote for B1]
    12  	// In the depicted scenario, the replica voted for block B1, which forms a (potentially indirect)
    13  	// 1-chain on top of B0. The replica updated LockedOneChainView to the max of the current value and
    14  	// QC_B0.View = B0.View. Thereby, the safety module guarantees that the replica will not sign
    15  	// a TimeoutObject that would allow a malicious leader to fork below the latest finalized block.
    16  	LockedOneChainView uint64
    17  	// HighestAcknowledgedView is the highest view where we have voted or triggered a timeout
    18  	HighestAcknowledgedView uint64
    19  	// LastTimeout is the last timeout that was produced by this node (may be nil if no timeout occurred yet)
    20  	LastTimeout *model.TimeoutObject
    21  }
    22  
    23  // SafetyRules enforces all consensus rules that guarantee safety. It produces votes for
    24  // the given blocks or TimeoutObject for the given views, only if all safety rules are satisfied.
    25  type SafetyRules interface {
    26  	// ProduceVote takes a block proposal and current view, and decides whether to vote for the block.
    27  	// Voting is deterministic meaning voting for same proposal will always result in the same vote.
    28  	// Returns:
    29  	//  * (vote, nil): On the _first_ block for the current view that is safe to vote for.
    30  	//    Subsequently, voter does _not_ vote for any _other_  block with the same (or lower) view.
    31  	//    SafetyRules internally caches and persists its latest vote. As long as the SafetyRules' internal
    32  	//    state remains unchanged, ProduceVote will return its cached for identical inputs.
    33  	//  * (nil, model.NoVoteError): If the safety module decides that it is not safe to vote for the given block.
    34  	//    This is a sentinel error and _expected_ during normal operation.
    35  	// All other errors are unexpected and potential symptoms of uncovered edge cases or corrupted internal state (fatal).
    36  	ProduceVote(proposal *model.Proposal, curView uint64) (*model.Vote, error)
    37  	// ProduceTimeout takes current view, highest locally known QC and TC (optional, must be nil if and
    38  	// only if QC is for previous view) and decides whether to produce timeout for current view.
    39  	// Returns:
    40  	//  * (timeout, nil): It is safe to timeout for current view using newestQC and lastViewTC.
    41  	//  * (nil, model.NoTimeoutError): If replica is not part of the authorized consensus committee (anymore) and
    42  	//    therefore is not authorized to produce a valid timeout object. This sentinel error is _expected_ during
    43  	//    normal operation, e.g. during the grace-period after Epoch switchover or after the replica self-ejected.
    44  	// All other errors are unexpected and potential symptoms of uncovered edge cases or corrupted internal state (fatal).
    45  	ProduceTimeout(curView uint64, newestQC *flow.QuorumCertificate, lastViewTC *flow.TimeoutCertificate) (*model.TimeoutObject, error)
    46  }