Skip to content

HotStuff uses block interface #4170

Open

Description

This issue is based on [this PR comment](noted by Yurii).

Context

Currently, we have a different kinds of blocks in our code base:

  • flow.Block
    // Block (currently) includes the header, the payload hashes as well as the
    // payload contents.
    type Block struct {
    Header *Header
    Payload *Payload
    }
  • Collections, which are conceptually also blocks from the perspective of the cluster consensus:
    // Block represents a block in collection node cluster consensus. It contains
    // a standard block header with a payload containing only a single collection.
    type Block struct {
    Header *flow.Header
    Payload *Payload
    }
  • HotStuff's abstract notion of a block
    // Block is the HotStuff algorithm's concept of a block, which - in the bigger picture - corresponds
    // to the block header.
    type Block struct {
    View uint64
    BlockID flow.Identifier
    ProposerID flow.Identifier
    QC *flow.QuorumCertificate
    PayloadHash flow.Identifier
    Timestamp time.Time
    }

Using a separate block struct for HotStuff introduces code duplication, ambiguity. Furthermore, other components ingesting notifications often lack auxiliary information not contained in the HotStuff block. This leads to ambiguity and conceptual complexity.

When implementing HotStuff, we have emphasized a strong separation from the rest of the protocol, which has two benefits: We can easily isolate HotStuff to run scientific consensus experiments, or use it for other purposes. Second, the remainder of the protocol also becomes relatively agnostic about consensus, which simplifies upgrading and evolving Flow's consensus implementation. This is the reason, why HotStuff has its own high-level notion of blocks, because payload and header contain lots of information that is entirely irrelevant for HotStuff.

Suggestion

In my opinion, it would be best to change HotStuff to work with:

  • a Block interface:
    • has getter-methods to expose the information that we currently hold in these fields:
      View uint64
      BlockID flow.Identifier
      ProposerID flow.Identifier
      QC *flow.QuorumCertificate
    • In my opinion, the following could be dropped from HotStuff's block interface:
      PayloadHash flow.Identifier
      Timestamp time.Time
      because they are never used (except for generic logging).
  • The notion of QC is foundational to HotStuff.
    • I would suggest to represent QCs in HotStuff via their own interface. The interface enables us to define important structures such as
      // CertifiedBlock holds a certified block, which is a block and a QC that pointing to it.
      // A QC is the aggregated form of votes from a supermajority of HotStuff participants.
      // Existence of a QC proves validity of the block. A certified block satisfies:
      // Block.View == QC.View and Block.BlockID == QC.BlockID
      type CertifiedBlock struct {
      Block *Block
      QC *flow.QuorumCertificate
      }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions