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