github.com/koko1123/flow-go-1@v0.29.6/consensus/hotstuff/forks/forks.go (about) 1 package forks 2 3 import ( 4 "fmt" 5 6 "github.com/koko1123/flow-go-1/consensus/hotstuff" 7 "github.com/koko1123/flow-go-1/consensus/hotstuff/model" 8 "github.com/koko1123/flow-go-1/model/flow" 9 ) 10 11 // Forks implements the hotstuff.Reactor API 12 type Forks struct { 13 finalizer Finalizer 14 forkchoice ForkChoice 15 } 16 17 var _ hotstuff.Forks = (*Forks)(nil) 18 19 // New creates a Forks instance 20 func New(finalizer Finalizer, forkchoice ForkChoice) *Forks { 21 return &Forks{ 22 finalizer: finalizer, 23 forkchoice: forkchoice, 24 } 25 } 26 27 // GetBlocksForView returns all the blocks for a certain view. 28 func (f *Forks) GetBlocksForView(view uint64) []*model.Block { 29 return f.finalizer.GetBlocksForView(view) 30 } 31 32 // GetBlock returns the block for the given block ID 33 func (f *Forks) GetBlock(id flow.Identifier) (*model.Block, bool) { 34 return f.finalizer.GetBlock(id) 35 } 36 37 // FinalizedBlock returns the latest finalized block 38 func (f *Forks) FinalizedBlock() *model.Block { 39 return f.finalizer.FinalizedBlock() 40 } 41 42 // FinalizedView returns the view of the latest finalized block 43 func (f *Forks) FinalizedView() uint64 { 44 return f.finalizer.FinalizedBlock().View 45 } 46 47 // IsSafeBlock returns whether a block is safe to vote for. 48 func (f *Forks) IsSafeBlock(block *model.Block) bool { 49 if err := f.finalizer.VerifyBlock(block); err != nil { 50 return false 51 } 52 return f.finalizer.IsSafeBlock(block) 53 } 54 55 // AddBlock passes the block to the finalizer for finalization and 56 // gives the QC to forkchoice for updating the preferred parent block 57 func (f *Forks) AddBlock(block *model.Block) error { 58 if err := f.finalizer.VerifyBlock(block); err != nil { 59 // technically, this not strictly required. However, we leave this as a sanity check for now 60 return fmt.Errorf("cannot add invalid block to Forks: %w", err) 61 } 62 err := f.finalizer.AddBlock(block) 63 if err != nil { 64 return fmt.Errorf("error storing block in Forks: %w", err) 65 } 66 67 // We only process the block's QC if the block's view is larger than the last finalized block. 68 // By ignoring hte qc's of block's at or below the finalized view, we allow the genesis block 69 // to have a nil QC. 70 if block.View <= f.finalizer.FinalizedBlock().View { 71 return nil 72 } 73 return f.AddQC(block.QC) 74 } 75 76 // MakeForkChoice returns the block to build new block proposal from for the current view. 77 // the QC is the QC that points to that block. 78 func (f *Forks) MakeForkChoice(curView uint64) (*flow.QuorumCertificate, *model.Block, error) { 79 return f.forkchoice.MakeForkChoice(curView) 80 } 81 82 // AddQC gives the QC to the forkchoice for updating the preferred parent block 83 func (f *Forks) AddQC(qc *flow.QuorumCertificate) error { 84 return f.forkchoice.AddQC(qc) // forkchoice ensures that block referenced by qc is known 85 }