hotstuff_rs/
lib.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*
    Copyright © 2023, ParallelChain Lab
    Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0
*/

#![allow(rustdoc::private_intra_doc_links)]

//! A Rust Programming Language library for Byzantine Fault Tolerant (BFT) State Machine Replication
//! (SMR), intended for production systems.
//!
//! # Features
//!
//! - **Pluggable components**: library users get to provide their own business logic
//!   ([`app`]), key-value storage ([`kv_store`](crate::block_tree::pluggables::KVStore)), and peer-to-peer
//!   networking ([`network`](crate::networking::network)). HotStuff-rs is agnostic to these details and
//!   can therefore be adapted to many use-cases.
//! - **Dynamic validator sets**: `App`s can control and change the set of replicas ("validators") that
//!   vote to replicate the state machine without any downtime or manual configuration. Unlike older
//!   generations of SMR, "validator set updates" are not stop-the-world operations.
//! - **View synchronization**: HotStuff-rs implements Byzantine View Synchronization in the [`pacemaker`]
//!   module. This enables it to quickly bring replicas' view number in sync and therefore recover quickly
//!   from a network disruption.
//! - **Rigorous specification**: HotStuff-rs is not only rigorously specified, but its specification is
//!   integrated into its Rustdocs so that they remain up-to-date with the implementation. This includes
//!   proofs of correctness for each of its subprotocols.
//!
//! # Getting started
//!
//! To replicate your application using HotStuff-rs, you need to represent it as a type and then
//! have the type implement the [`App`](app) trait.
//!
//! Then, [`initialize`](replica::Replica::initialize) the replica's storage,
//! [`build`](replica::ReplicaSpec::builder) a `ReplicaSpec`,
//! and then [`start`](replica::ReplicaSpec::start) the replica.
//!
//! An example on [how to start a replica](replica#starting-a-replica) can be found in the rustdocs for
//! the `replica` module.
//!
//! # Understanding HotStuff-rs
//!
//! The best way to understand HotStuff-rs is by reading these Rustdocs (so be happy, you are already at
//! the right place!).
//!
//! HotStuff-rs' Rustdocs are designed to be both **documentation**, and **specification**. This means
//! that it does not only *describe* the current (v0.4.0) version of this (Rust) implementation of
//! HotStuff-rs, but also *prescribes* a protocol that developers can use to implement BFT SMR libraries
//! that are compatible with HotStuff-rs.
//!
//! Before starting to read these Rustdocs, it is helpful to have a good high-level awareness of the
//! concepts behind HotStuff-rs, as well as a high-level picture of how the library's modules are
//! organized.
//!
//! The [Concepts](#concepts) subsection helps with the former by introducing a slew of the important
//! concepts in a way gives a sense of the relationships between them, as well as linking to further
//! reading resources whenever they are available, while the [Organization](#organization) subsection
//! helps with the latter by briefly describing how the module tree is structured.
//!
//! ## Concepts
//!
//! The library user implements their business logic in an [`App`](app) and provides a handle to it
//! to HotStuff-rs via the `app` setter on [`ReplicaSpecBuilder`](replica::ReplicaSpec::builder). The
//! library user then [`start`](replica::ReplicaSpec::start)s a replica.
//!
//! Upon startup, the replica starts a background thread called the [`algorithm`] thread. The algorithm
//! thread then creates instances of HotStuff-rs' three subprotocols--namely [`hotstuff`],
//! [`pacemaker`], and [`block_sync`]--and starts to poll these instances in an infinite loop, driving
//! each subprotocol forward.
//!
//! The Pacemaker subprotocol works to keep track of an increasing counter called the "view number",
//! which is a sort of logical clock that the algorithm thread uses to decide the replica should do at
//! any moment in time. At any given view, a replica could either be a
//! [validator, or a listener](replica#kinds-of-replicas). Suppose that it is a validator. Then, it
//! needs to play a [role](hotstuff::roles) in the HotStuff subpprotocol.
//!
//! The two main roles validator can play in the HotStuff subprotocol are:
//! [Proposer](hotstuff::roles::is_proposer), and [Phase-Voter](hotstuff::roles::is_phase_voter). These
//! two roles are not mutually exclusive. For example, it could be that in a given view, a  validator
//! is both a proposer, and a phase-voter.
//!
//! Suppose that a validator is a proposer. Then, it will begin the view by calling
//! [`produce_block`](app::App::produce_block) to ask the `App` to generate the contents of a new
//! [`Block`](types::block::Block). Then, it will pack the block in a
//! [`Proposal`](hotstuff::messages::Proposal) and broadcast this to all other replicas through the
//! user-provided P2P [`Network`](networking::network).
//!
//! Suppose further that the validator is also phase-voter. Then, after broadcasting the proposal, the
//! validator will wait to receive a proposal from the `Network`. Upon receiving a `Proposal` (which
//! could be the same `Proposal` it just itself proposed), it will call
//! [`validate_block`](app::App::validate_block) to ask the `App` to ask it to validate the block
//! according to user-defined application-level semantics.
//!
//! If the block is valid, then the replica will create a [`PhaseVote`](hotstuff::messages::PhaseVote)
//! by signing a message with its  [`SigningKey`](types::crypto_primitives::SigningKey), and send this
//! to the [`phase_vote_recipient`](hotstuff::roles::phase_vote_recipient). Then, it will insert the
//! block to its [Block Tree](block_tree), which the library stores in the
//! [`KVStore`](block_tree::pluggables::KVStore) provided by the user.
//!
//! The overall result is an immutable "block chain" that is guaranteed to satisfy safety and liveness
//! [`invariants`](block_tree::invariants) as long as no more than 1/3rd of the
//! [`TotalPower`](types::data_types::TotalPower) of a
//! [`ValidatorSet`](types::validator_set::ValidatorSet) is faulty.
//!
//! As all of this is happening, the algorithm constantly emits [`events`], which user code can receive
//! as they occur by registering event handlers.
//!
//! ## Module organization
//!
//! HotStuff-rs' modules are organized into two levels depending on whether the definitions they contain
//! are **subprotocol**-specific, or commonly used across multiple subprotocols.
//!
//! The three subprotocols of HotStuff-rs and their associated modules are:
//! 1. **HotStuff** ([`hotstuff`]): the subprotocol for committing blocks.
//! 2. **Pacemaker** ([`pacemaker`]): the subprotocol for bringing replicas into the same view so that they
//!    can start committing blocks.
//! 3. **Block Sync** ([`block_sync`]): the subprotocol for bringing replicas' block trees up-to-date after
//!    periods of time in which they miss messages.
//!
//! Modules not listed above not subprotocol-specific.

pub mod app;

mod algorithm;

pub mod types;

pub mod logging;

pub mod pacemaker;

pub mod hotstuff;

pub mod block_tree;

pub mod networking;

pub mod block_sync;

pub mod replica;

mod event_bus;

pub mod events;