Expand description
Methods for building and running a replica as well as initializing its storage.
HotStuff-rs works to safely replicate a state machine in multiple processes. In our terminology,
these processes are called ‘replicas’, and therefore the set of all replicas is called the
‘replica set’. Each replica is uniquely identified by an Ed25519
VerifyingKey
.
They key components of this module are:
- The builder-pattern interface to construct a specification of the replica with:
ReplicaSpec::builder
to construct aReplicaSpecBuilder
,- The setters of the
ReplicaSpecBuilder
, and - The
ReplicaSpecBuilder::build
method to construct aReplicaSpec
,
- The function to start a
Replica
given its specification, - The function to initialize the replica’s Block Tree,
- The type which keeps the replica alive.
§Kinds of replicas
At any given moment a Replica could either be a Validator, or a Listener, depending on whether it is currently allowed to take part in consensus decisions:
- Validators: replicas that currently take part in consensus decisions.
- Listeners: replicas that currently do not take part in consensus decisions, but rather merely replicates the block tree.
As the definition above implies, the Validator Set is dynamic, and will change as validator set-updating blocks are produced and committed.
§Becoming a Listener
While HotStuff-rs keeps track of the current committed (and possibly the previous) validator set in
the persistent block tree, it does not keep track of a “Listener Set” anywhere, and nor can the
App
ever specify “Listener Set Updates”.
This begs the question: “if HotStuff-rs does not know who the listeners are, how can the listeners receive blocks and replicate the block tree?”
In order for listeners to replicate the block tree, the library user should make sure that the
broadcast
method of the networking implementation it provides sends messages to
all the peers the replica is connected to, and not only the validators. The library user is free
to implement their own mechanism or deciding which peers, besides those in the validator set, should
be connected to the network. This reduces the process of becoming a listener to the process of
becoming a peer in the user-provided network.
messages.
§Starting a replica
Below is an example that demonstrates how to build and start running a replica using the builder pattern:
let replica =
ReplicaSpec::builder()
.app(app)
.pacemaker(pacemaker)
.configuration(configuration)
.kv_store(kv_store)
.network(network)
.on_commit(commit_handler)
.on_nudge(nudge_handler)
.build()
.start()
§Required setters
The required setters are for providing the trait implementations required to run a replica:
.app(...)
.network(...)
.kv_store(...)
.pacemaker(...)
.configuration(...)
§Optional setters
The optional setters are for registering user-defined event handlers for events from crate::events:
.on_insert_block(...)
.on_commit_block(...)
.on_prune_block(...)
.on_update_highest_pc(...)
.on_update_locked_view(...)
.on_update_validator_set(...)
.on_propose(...)
.on_nudge(...)
.on_phase_vote(...)
.on_new_view(...)
.on_receive_proposal(...)
.on_receive_nudge(...)
.on_receive_phase_vote(...)
.on_receive_new_view(...)
.on_start_view(...)
.on_view_timeout(...)]
.on_collect_pc(...)
.on_start_sync(...)
.on_end_sync(...)
.on_receive_sync_request(...)
.on_receive_sync_response(...)
The replica’s configuration can also be defined using the builder pattern, for example:
let configuration =
Configuration::builder()
.me(keypair)
.chain_id(0)
.sync_request_limit(10)
.sync_response_timeout(Duration::new(3, 0))
.progress_msg_buffer_capacity(1024)
.log_events(true)
.build()
Structs§
- Stores the user-defined parameters required to start the replica, that is:
- A handle to the background threads of a HotStuff-rs replica. When this value is dropped, all background threads are gracefully shut down.
- Stores all necessary parameters and trait implementations required to run the Replica.