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  }