github.com/onflow/flow-go@v0.33.17/consensus/hotstuff/model/block.go (about) 1 package model 2 3 import ( 4 "fmt" 5 "time" 6 7 "github.com/onflow/flow-go/model/flow" 8 ) 9 10 // Block is the HotStuff algorithm's concept of a block, which - in the bigger picture - corresponds 11 // to the block header. 12 type Block struct { 13 View uint64 14 BlockID flow.Identifier 15 ProposerID flow.Identifier 16 QC *flow.QuorumCertificate 17 PayloadHash flow.Identifier 18 Timestamp time.Time 19 } 20 21 // BlockFromFlow converts a flow header to a hotstuff block. 22 func BlockFromFlow(header *flow.Header) *Block { 23 block := Block{ 24 BlockID: header.ID(), 25 View: header.View, 26 QC: header.QuorumCertificate(), 27 ProposerID: header.ProposerID, 28 PayloadHash: header.PayloadHash, 29 Timestamp: header.Timestamp, 30 } 31 32 return &block 33 } 34 35 // GenesisBlockFromFlow returns a HotStuff block model representing a genesis 36 // block based on the given header. 37 func GenesisBlockFromFlow(header *flow.Header) *Block { 38 genesis := &Block{ 39 BlockID: header.ID(), 40 View: header.View, 41 ProposerID: header.ProposerID, 42 QC: nil, 43 PayloadHash: header.PayloadHash, 44 Timestamp: header.Timestamp, 45 } 46 return genesis 47 } 48 49 // CertifiedBlock holds a certified block, which is a block and a QC that is pointing to 50 // the block. A QC is the aggregated form of votes from a supermajority of HotStuff and 51 // therefore proves validity of the block. A certified block satisfies: 52 // Block.View == QC.View and Block.BlockID == QC.BlockID 53 type CertifiedBlock struct { 54 Block *Block 55 CertifyingQC *flow.QuorumCertificate 56 } 57 58 // NewCertifiedBlock constructs a new certified block. It checks the consistency 59 // requirements and returns an exception otherwise: 60 // 61 // Block.View == QC.View and Block.BlockID == QC.BlockID 62 func NewCertifiedBlock(block *Block, qc *flow.QuorumCertificate) (CertifiedBlock, error) { 63 if block.View != qc.View { 64 return CertifiedBlock{}, fmt.Errorf("block's view (%d) should equal the qc's view (%d)", block.View, qc.View) 65 } 66 if block.BlockID != qc.BlockID { 67 return CertifiedBlock{}, fmt.Errorf("block's ID (%v) should equal the block referenced by the qc (%d)", block.BlockID, qc.BlockID) 68 } 69 return CertifiedBlock{Block: block, CertifyingQC: qc}, nil 70 } 71 72 // ID returns unique identifier for the block. 73 // To avoid repeated computation, we use value from the QC. 74 func (b *CertifiedBlock) ID() flow.Identifier { 75 return b.Block.BlockID 76 } 77 78 // View returns view where the block was proposed. 79 func (b *CertifiedBlock) View() uint64 { 80 return b.Block.View 81 }