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 }