github.com/koko1123/flow-go-1@v0.29.6/consensus/hotstuff/README.md (about)

     1  # Flow's HotStuff
     2  
     3  We use a BFT consensus algorithm with deterministic finality in Flow for
     4  * Consensus Nodes: deciding on the content of blocks
     5  * Cluster of Collector Nodes: batching transactions into collections. 
     6  
     7  Flow uses a derivative of HotStuff 
     8  (see paper [HotStuff: BFT Consensus in the Lens of Blockchain (version 6)](https://arxiv.org/abs/1803.05069v6) for the original algorithm).
     9  Our implementation is a mixture of Chained HotStuff and Event-Driven HotStuff with a few additional, minor modifications:
    10  * We employ the rules for locking on blocks and block finalization from Event-Driven HotStuff. 
    11  Specifically, we lock the newest block which has an (direct or indirect) 2-chain built on top. 
    12  We finalize a block when it has a 3-chain built on top where with the first two chain links being _direct_.  
    13  * The way we progress though views follows the Chained HotStuff algorithm. 
    14  A replica only votes or proposes for its current view.  
    15  * Flow's HotStuff does not implement `ViewChange` messages
    16  (akin to the approach taken in [Streamlet:  Textbook Streamlined Blockchains](https://eprint.iacr.org/2020/088.pdf))
    17  * Flow uses a decentralized random beacon (based on [Dfinity's proposal](https://dfinity.org/pdf-viewer/library/dfinity-consensus.pdf)).
    18  The random beacon is run by Flow's consensus nodes and integrated into the consensus voting process.  
    19  
    20  #### Node weights
    21  
    22  In Flow, there are multiple HotStuff instances running in parallel. Specifically, the consensus nodes form a HotStuff committee and each collector cluster is its own committee. In the following, we refer to an authorized set of nodes, who run a particular HotStuff instance as a (HotStuff) `committee`.  
    23  
    24  * Flow allows nodes to have different weights, reflecting how much they are trusted by the protocol.
    25    The weight of a node can change over time due to stake changes or discovering protocol violations. 
    26    A `super-majority` of nodes is defined as a subset of the consensus committee,
    27    where the nodes have _more_ than 2/3 of the entire committee's accumulated weight.
    28  * The messages from zero-weighted nodes are ignored by all committee members.       
    29   
    30   
    31  ## Architecture 
    32  
    33  #### Determining block validity 
    34  
    35  In addition to HotStuff's requirements on block validity, the Flow protocol adds additional requirements. 
    36  For example, it is illegal to repeatedly include the same payload entities (e.g. collections, challenges, etc) in the same fork.
    37  Generally, payload entities expire. However within the expiry horizon, all ancestors of a block need to be known 
    38  to verify that payload entities are not repeated. 
    39  
    40  We exclude the entire logic for determining payload validity from the HotStuff core implementation. 
    41  This functionality is encapsulated in the Chain Compliance Layer (CCL) which precedes HotStuff. 
    42  The CCL forwards a block to the HotStuff core logic only if 
    43  * the block's payload is valid,
    44  * the block is connected to the most recently finalized block, and
    45  * all ancestors have previously been processed by HotStuff. 
    46  
    47  If ancestors of a block are missing, the CCL caches the respective block and (iteratively) requests missing ancestors.
    48  
    49  #### Payload generation
    50  Payloads are generated outside of the HotStuff core logic. HotStuff only incorporates the payload root hash into the block header. 
    51  
    52  #### Structure of votes 
    53  In Flow's HotStuff implementation, votes are used for two purposes: 
    54  1. Prove that a super-majority of committee nodes considers the respective block a valid extension of the chain. 
    55  Therefore, nodes include a `StakingSignature` (BLS with curve BLS12-381) in their vote.  
    56  2. Construct a Source of Randomness as described in [Dfinity's Random Beacon](https://dfinity.org/pdf-viewer/library/dfinity-consensus.pdf).
    57  Therefore, consensus nodes include a `RandomBeaconSignature` (also BLS with curve BLS12-381, used in a threshold signature scheme) in their vote.  
    58  
    59  When the primary collects the votes, it verifies the `StakingSignature` and the `RandomBeaconSignature`.
    60  If either signature is invalid, the entire vote is discarded. From all valid votes, the
    61  `StakingSignatures` and the `RandomBeaconSignatures` are aggregated separately. 
    62  (note: Only the aggregation of the `RandomBeaconSignature` into a threshold signature is currently implemented. 
    63  Aggregation of the BLS `StakingSignatures` will be added later.)
    64  
    65  * Following [version 6 of the HotStuff paper](https://arxiv.org/abs/1803.05069v6), 
    66  replicas forward their votes for block `b` to the leader of the _next_ view, i.e. the primary for view `b.View + 1`. 
    67  * A proposer will attach its own vote for its proposal in the block proposal message 
    68  (instead of signing the block proposal for authenticity and separately sending a vote). 
    69  
    70  
    71  #### Primary section
    72  For primary section, we use a randomized, weight-proportional selection.
    73  
    74  
    75  ### Component Overview 
    76  HotStuff's core logic is broken down into multiple components. 
    77  The figure below illustrates the dependencies of the core components and information flow between these components.
    78  
    79  ![](/docs/HotStuffEventLoop.png)
    80  
    81  * `HotStuffEngine` and `ChainComplianceLayer` do not contain any core HotStuff logic. 
    82  They are responsible for relaying HotStuff messages and validating block payloads respectively. 
    83  * `EventLoop` buffers all incoming events, so `EventHandler` can process one event at a time in a single thread.
    84  * `EventHandler` orchestrates all HotStuff components and implements [HotStuff's state machine](/docs/StateMachine.png).
    85  The event handler is designed to be executed single-threaded. 
    86  * `Communicator` relays outgoing HotStuff messages (votes and block proposals)
    87  * `Pacemaker` is a basic PaceMaker to ensure liveness by keeping the majority of committee replicas in the same view
    88  * `Forks` maintains an in-memory representation of all blocks `b`, whose view is larger or equal to the view of the latest finalized block (known to this specific replica).
    89  As blocks with missing ancestors are cached outside of HotStuff (by the Chain Compliance Layer), 
    90  all blocks stored in `Forks` are guaranteed to be connected to the genesis block 
    91  (or the trusted checkpoint from which the replica started). Internally, `Forks` consists of multiple layers:
    92     - `LevelledForest`: A blockchain forms a Tree. When removing all blocks with views strictly smaller than the last finalized block, the chain decomposes into multiple disconnected trees. In graph theory, such structure is a forest. To separate general graph-theoretical concepts from the concrete block-chain application, `LevelledForest` refers to blocks as graph `vertices` and to a block's view number as `level`. The `LevelledForest` is an in-memory data structure to store and maintain a levelled forest. It provides functions to add vertices, query vertices by their ID (block's hash), query vertices by level, query the children of a vertex, and prune vertices by level (remove them from memory).
    93     - `Finalizer`: the finalizer uses the `LevelledForest` to store blocks. The Finalizer tracks the locked and finalized blocks. Furthermore, it evaluates whether a block is safe to vote for.
    94     - `ForkChoice`: implements the fork choice rule. Currently, `NewestForkChoice` always uses the quorum certificate (QC) with the largest view to build a new block (i.e. the fork a super-majority voted for most recently).
    95     - `Forks` is the highest level. It bundles the `Finalizer` and `ForkChoice` into one component.
    96  * `Validator` validates the HotStuff-relevant aspects of
    97     - QC: total weight of all signers is more than 2/3 of committee weight, validity of signatures, view number is strictly monotonously increasing
    98     - block proposal: from designated primary for the block's respective view, contains proposer's vote for its own block, QC in block is valid
    99     - vote: validity of signature, voter is has positive weight 
   100  * `VoteAggregator` caches votes on a per-block basis and builds QC if enough votes have been accumulated.
   101  * `Voter` tracks the view of the latest vote and determines whether or not to vote for a block (by calling `forks.IsSafeBlock`)
   102  * `Committee` maintains the list of all authorized network members and their respective weight on a per-block basis. Furthermore, the committee contains the primary selection algorithm. 
   103  * `BlockProducer` constructs the payload of a block, after the HotStuff core logic has decided which fork to extend 
   104  
   105  # Implementation
   106  
   107  We have translated the Chained HotStuff protocol into a state machine shown below. The state machine is implemented 
   108  in `EventHandler`.
   109  
   110  ![](/docs/StateMachine.png)
   111  
   112  #### PaceMaker
   113  The HotStuff state machine interacts with the PaceMaker, which triggers view changes. Conceptually, the PaceMaker
   114  interfaces with the `EventHandler` in two different modes:
   115  * [asynchronous] On timeouts, the PaceMaker will emit a timeout event, which is processed as any other event (such as incoming blocks or votes) through the `EventLoop`.
   116  * [synchronous] When progress is made following the happy-path business logic, the  `EventHandler` will inform the PaceMaker about completing the respective 
   117  processing step via a direct method call (see `PaceMaker interface`). If the PaceMaker changed the view in response, it returns 
   118  a `NewViewEvent` which will be synchronously processed by the  `EventHandler`.
   119  
   120  Flow's PaceMaker is simple (compared to Libra's PaceMaker for instance). It solely relies on increasing the timeouts 
   121  exponentially if no progress is made and exponentially decreasing timeouts on the happy path. 
   122  The timeout values are limited by lower and upper-bounds to ensure that the PaceMaker can change from large to small timeouts in a reasonable number of views. 
   123  The specific values for lower and upper timeout bounds are protocol-specified; we envision the bounds to be on the order of 1sec (lower bound) and multiple days (upper bound).
   124  
   125  **Progress**, from the perspective of the PaceMaker is defined as entering view `V`
   126  for which the replica knows a QC with `V = QC.view + 1`. 
   127  In other words, we transition into the next view due to reaching quorum in the last view.
   128    
   129  A central, non-trivial functionality of the PaceMaker is to _skip views_. 
   130  Specifically, given a QC with view `qc.view`, the Pacemaker will skip ahead to view `qc.view + 1` if `currentView ≤ qc.view`.
   131    
   132  <img src="https://github.com/onflow/flow-go/blob/master/docs/PaceMaker.png" width="200">
   133   
   134   
   135  
   136  ## Code structure
   137  
   138  All relevant code implementing the core HotStuff business logic is contained in `/consensus/hotstuff/` (folder containing this README).
   139  When starting to look into the code, we suggest starting with `/consensus/hotstuff/event_loop.go` and `/consensus/hotstuff/event_handler.go`. 
   140  
   141  
   142  ### Folder structure
   143  
   144  All files in the `/consensus/hotstuff/` folder, except for `event_loop.go` and `follower_loop.go`, are interfaces for HotStuff-related components. 
   145  The concrete implementations for all HotStuff-relevant components are in corresponding sub-folders. 
   146  For completeness, we list the component implemented in each subfolder below: 
   147  
   148  * `/consensus/hotstuff/blockproducer` builds a block proposal for a specified QC, interfaces with the logic for assembling a block payload, combines all relevant fields into a new block proposal.
   149  * `/consensus/hotstuff/committee` maintains the list of all authorized network members and their respective weight on a per-block basis; contains the primary selection algorithm. 
   150  * `/consensus/hotstuff/eventhandler` orchestrates all HotStuff components and implements the HotStuff state machine. The event handler is designed to be executed single-threaded.
   151  * `/consensus/hotstuff/follower` This component is only used by nodes that are _not_ participating in the HotStuff committee. As Flow has dedicated node roles with specialized network functions, only a subset of nodes run the full HotStuff protocol. Nevertheless, all nodes need to be able to act on blocks being finalized. The approach we have taken for Flow is that block proposals are broadcast to all nodes (including non-committee nodes). Non-committee nodes locally determine block finality by applying HotStuff's finality rules. The HotStuff Follower contains the functionality to consume block proposals and trigger downstream processing of finalized blocks. The Follower does not _actively_ participate in HotStuff. 
   152  * `/consensus/hotstuff/forks` maintains an in-memory representation of all blocks `b`, whose view is larger or equal to the view of the latest finalized block (known to this specific HotStuff replica). 
   153  It tracks the last finalized block, the currently locked block, evaluates whether it is safe to vote for a given block and provides a Fork-Choice when the replica is primary.  
   154  * `/consensus/hotstuff/helper` contains broadly-used helper functions for testing  
   155  * `/consensus/hotstuff/integration` integration tests for verifying correct interaction of multiple HotStuff replicas
   156  * `/consensus/hotstuff/model` contains the HotStuff data models, including block proposal, QC, etc. 
   157  Many HotStuff data models are built on top of basic data models defined in `/model/flow/`.
   158  * `/consensus/hotstuff/notifications`: All relevant events within the HotStuff logic are exported though a notification system. While the notifications are _not_ used HotStuff-internally, they notify other components within the same node of relevant progress and are used for collecting HotStuff metrics.
   159  * `/consensus/hotstuff/pacemaker` contains the implementation of Flow's basic PaceMaker, as described above.
   160  * `/consensus/hotstuff/persister` for performance reasons, the implementation maintains the consensus state largely in-memory. The `persister` stores the last entered view and the view of the latest voted block persistenlty on disk. This allows recovery after a crash without the risk of equivocation.       
   161  * `/consensus/hotstuff/runner` helper code for starting and shutting down the HotStuff logic safely in a multithreaded environment.  
   162  * `/consensus/hotstuff/validator` holds the logic for validating the HotStuff-relevant aspects of blocks, QCs, and votes
   163  * `/consensus/hotstuff/verification` contains integration of Flow's cryptographic primitives (signing and signature verification) 
   164  * `/consensus/hotstuff/voteaggregator` caches votes on a per-block basis and builds a QC if enough votes have been accumulated.
   165  * `/consensus/hotstuff/voter` tracks the view of the latest vote and determines whether or not to vote for a block
   166  
   167  ## Pending Extensions  
   168  * BLS Aggregation of the `StakingSignatures`
   169  * include Epochs 
   170  * upgrade PaceMaker to include Timeout Certificates 
   171  * refactor crypto integration (code in `verification` and dependent modules) for better auditability
   172  
   173  ## Telemetry
   174  
   175  The HotStuff state machine exposes some details about its internal progress as notification through the `hotstuff.Consumer`.
   176  The following figure depicts at which points notifications are emitted. 
   177  
   178  ![](/docs/StateMachine_wirth_notifications.png)
   179  
   180  We have implemented a telemetry system (`hotstuff.notifications.TelemetryConsumer`) which implements the `Consumer` interface.
   181  The `TelemetryConsumer` tracks all events as belonging together that were emitted during a path through the state machine.
   182  Each `path` through the state machine is identified by a unique id.
   183  Generally, the `TelemetryConsumer` could export the collected data to a variety of backends.
   184  For now, we export the data to a logger.
   185  
   186  
   187   
   188  
   189