hotstuff

package module
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 27, 2025 License: MIT Imports: 10 Imported by: 3

README

hotstuff

Go Reference Test golangci-lint codecov

Deprecation Warning: This branch is no longer maintained. Please see the main branch as the starting point for new development. This branch is kept for archival purposes.

relab/hotstuff is a framework for experimenting with HotStuff and similar consensus protocols. It provides a set of modules and interfaces that make it easy to test different algorithms. It also provides a tool for deploying and running experiments on multiple servers via SSH.

If you use this project for research, please cite the APpLIED workshop paper and the repository itself.

Contents

Build Dependencies

  • Go (at least version 1.18)

If you modify any of the protobuf files, you will need the following to compile them:

  • Protobuf compiler (at least version 3.15)

  • The gRPC and gorums plugins for protobuf.

    • Linux and macOS users can run make tools to install these.
    • The Windows build script downloads them automatically.
    • They can also be installed manually:
      • go install github.com/relab/gorums/cmd/protoc-gen-gorums
      • go install google.golang.org/protobuf/cmd/protoc-gen-go

Getting Started

Linux and macOS
  • Compile command line utilities by running make.
Windows
  • Run .\build.ps1 with PowerShell.

NOTE: you should use ./hotstuff.exe instead of ./hotstuff when running commands.

Running Experiments

See the experimentation documentation for details.

The hotstuff command line utility can be used to run experiments locally, or on remote servers using SSH. For a list of options, run ./hotstuff help run.

The plot command line utility can be used to create graphs from measurements. Run ./plot --help for a list of options.

Safety Testing with Twins

We have implemented the Twins strategy [6] for testing the safety of the consensus implementations. See the twins documentation for details.

Modules

The following components are modular:

  • Consensus
    • The "core" of the consensus protocol, which decides when a replica should vote for a proposal, and when a block should be committed.
    • 3 implementations:
      • chainedhotstuff: The three-phase pipelined HotStuff protocol presented in the HotStuff paper [1].
      • fasthotstuff: A two-chain version of HotStuff designed to prevent forking attacks [3].
      • simplehotstuff: A simplified version of chainedhotstuff [4].
  • Crypto
    • Implements the cryptographic primitives used by HotStuff, namely quorum certificates.
    • 2 implementations:
      • ecdsa: A very simple implementation where quorum certificates are represented by arrays of ECDSA signatures.
      • bls12: An implementation of threshold signatures based on BLS12-381 aggregated signatures.
  • Synchronizer
    • Implements a view-synchronization algorithm. It is responsible for synchronizing replicas to the same view number.
    • Current implementation based on DiemBFT's RoundState [5].
  • Blockchain
    • Implements storage for the block chain. Currently we have an in-memory cache of a fixed size.
  • Leader rotation
    • Decides which replica should be the leader of a view.
    • Currently either a fixed leader or round-robin.
  • Networking/Backend

These modules are designed to be interchangeable and simple to implement. It is also possible to add custom modules that can interact with the modules we listed above.

Consensus Interfaces

There are two ways to implement a new consensus protocol, depending on the requirements of the new protocol. The Consensus module interface is the most general, but also the most difficult to implement. That is because it is oriented towards the other modules, and the other modules rely on it to perform certain operations, such as verifying proposals, interacting with the BlockChain, Acceptor, Executor, and Synchronizer modules, and so on. That is why we provide a simplified Rules interface and the optional ProposeRuler interface. These interfaces are only required to implement the core rules of the consensus protocol, namely deciding whether or not to vote for a proposal, whether or not it is safe to commit a block, and optionally how to create new blocks. These interfaces do not require any interaction with other modules, as that is taken care of by a default implementation of the Consensus interface.

The Consensus and Rules interfaces can also be used to override the behavior of other consensus implementations. The consensus/byzantine package contains some examples of byzantine behaviors that can be implemented by wrapping implementations of these interfaces.

Crypto Interfaces

In a similar way to the Consensus interface, the Crypto interface also introduces a simplified, lower-level interface that should be used to implement new crypto algorithms. The Crypto interface itself provides methods for working with the high-level structures such as quorum certificates. However, to make it easy to implement new crypto algorithms, the CryptoImpl interface can be used instead. This interface deals with signatures and threshold signatures directly, which are used by the Crypto interface to implement quorum certificates.

References

[1] M. Yin, D. Malkhi, M. K. Reiter, G. Golan Gueta, and I. Abraham, “HotStuff: BFT Consensus in the Lens of Blockchain,” Mar 2018.

[2] Tormod Erevik Lea, Leander Jehl, and Hein Meling. Towards New Abstractions for Implementing Quorum-based Systems. In 37th International Conference on Distributed Computing Systems (ICDCS), Jun 2017.

[3] Mohammad M. Jalalzai, Jianyu Niu, Chen Feng, Fangyu Gai. Fast-HotStuff: A Fast and Resilient HotStuff Protocol, Oct 2020.

[4] Leander Jehl. Formal Verification of HotStuff, Jun 2021.

[5] Baudet, Mathieu, et al. "State machine replication in the libra blockchain." The Libra Assn., Tech. Rep (2019).

[6] S. Bano, A. Sonnino, A. Chursin, D. Perelman, en D. Malkhi, “Twins: White-Glove Approach for BFT Testing”, 2020.

[7] Hanish Gogada, Hein Meling, Leander Jehl, and John Ingve Olsen. An Extensible Framework for Implementing and Validating Byzantine Fault-Tolerant Protocols. In ApPLIED 2023: Proceedings of the 5th workshop on Advanced tools, programming languages, and PLatforms for Implementing and Evaluating algorithms for Distributed systems, 2023.

Documentation

Overview

Package hotstuff implements the basic types that are used by hotstuff.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IDSetToString added in v0.5.0

func IDSetToString(set IDSet) string

IDSetToString formats an IDSet as a string.

func NumFaulty added in v0.3.0

func NumFaulty(n int) int

NumFaulty calculates 'f', which is the number of replicas that can be faulty for a configuration of size 'n'.

func QuorumSize added in v0.3.0

func QuorumSize(n int) int

QuorumSize calculates '2f + 1', which is the quorum size for a configuration of size 'n'.

Types

type AggregateQC added in v0.5.0

type AggregateQC struct {
	// contains filtered or unexported fields
}

AggregateQC is a set of QCs extracted from timeout messages and an aggregate signature of the timeout signatures.

This is used by the Fast-HotStuff consensus protocol.

func NewAggregateQC added in v0.5.0

func NewAggregateQC(qcs map[ID]QuorumCert, sig QuorumSignature, view View) AggregateQC

NewAggregateQC returns a new AggregateQC from the QC map and the threshold signature.

func (AggregateQC) QCs added in v0.5.0

func (aggQC AggregateQC) QCs() map[ID]QuorumCert

QCs returns the quorum certificates in the AggregateQC.

func (AggregateQC) Sig added in v0.5.0

func (aggQC AggregateQC) Sig() QuorumSignature

Sig returns the threshold signature in the AggregateQC.

func (AggregateQC) String added in v0.5.0

func (aggQC AggregateQC) String() string

func (AggregateQC) View added in v0.5.0

func (aggQC AggregateQC) View() View

View returns the view in which the AggregateQC was created.

type Block added in v0.2.0

type Block struct {
	// contains filtered or unexported fields
}

Block contains a propsed "command", metadata for the protocol, and a link to the "parent" block.

func GetGenesis added in v0.2.0

func GetGenesis() *Block

GetGenesis returns the genesis block.

func NewBlock added in v0.2.0

func NewBlock(parent Hash, cert QuorumCert, cmd Command, view View, proposer ID) *Block

NewBlock creates a new Block

func (*Block) Command added in v0.2.0

func (b *Block) Command() Command

Command returns the command

func (*Block) Hash added in v0.2.0

func (b *Block) Hash() Hash

Hash returns the hash of the Block

func (*Block) Parent added in v0.2.0

func (b *Block) Parent() Hash

Parent returns the hash of the parent Block

func (*Block) Proposer added in v0.2.0

func (b *Block) Proposer() ID

Proposer returns the id of the replica who proposed the block.

func (*Block) QuorumCert added in v0.2.0

func (b *Block) QuorumCert() QuorumCert

QuorumCert returns the quorum certificate in the block

func (*Block) SetTimestamp added in v0.5.0

func (b *Block) SetTimestamp(ts time.Time)

func (*Block) String added in v0.2.0

func (b *Block) String() string

func (*Block) Timestamp added in v0.5.0

func (b *Block) Timestamp() time.Time

Timestamp returns the timestamp of the block

func (*Block) ToBytes added in v0.2.0

func (b *Block) ToBytes() []byte

ToBytes returns the raw byte form of the Block, to be used for hashing, etc.

func (*Block) View added in v0.2.0

func (b *Block) View() View

View returns the view in which the Block was proposed

type Command added in v0.2.0

type Command string

Command is a client request to be executed by the consensus protocol.

The string type is used because it is immutable and can hold arbitrary bytes of any length.

type CommitEvent added in v0.5.0

type CommitEvent struct {
	Commands int
}

CommitEvent is raised whenever a block is committed, and includes the number of client commands that were executed.

type ConsensusLatencyEvent added in v0.5.0

type ConsensusLatencyEvent struct {
	Latency time.Duration
}

type Hash added in v0.2.0

type Hash [32]byte

Hash is a SHA256 hash

func (Hash) String added in v0.2.0

func (h Hash) String() string

type ID added in v0.2.0

type ID uint32

ID uniquely identifies a replica

func (ID) ToBytes added in v0.3.0

func (id ID) ToBytes() []byte

ToBytes returns the ID as bytes.

type IDSet added in v0.5.0

type IDSet interface {
	// Add adds an ID to the set.
	Add(id ID)
	// Contains returns true if the set contains the ID.
	Contains(id ID) bool
	// ForEach calls f for each ID in the set.
	ForEach(f func(ID))
	// RangeWhile calls f for each ID in the set until f returns false.
	RangeWhile(f func(ID) bool)
	// Len returns the number of entries in the set.
	Len() int
}

IDSet implements a set of replica IDs. It is used to show which replicas participated in some event.

func NewIDSet added in v0.5.0

func NewIDSet() IDSet

NewIDSet returns a new IDSet using the default implementation.

type NewViewMsg added in v0.5.0

type NewViewMsg struct {
	ID       ID       // The ID of the replica who sent the message.
	SyncInfo SyncInfo // The highest QC / TC.
}

NewViewMsg is sent to the leader whenever a replica decides to advance to the next view. It contains the highest QC or TC known to the replica.

type PartialCert added in v0.2.0

type PartialCert struct {
	// contains filtered or unexported fields
}

PartialCert is a signed block hash.

func NewPartialCert added in v0.5.0

func NewPartialCert(signature QuorumSignature, blockHash Hash) PartialCert

NewPartialCert returns a new partial certificate.

func (PartialCert) BlockHash added in v0.2.0

func (pc PartialCert) BlockHash() Hash

BlockHash returns the hash of the block that was signed.

func (PartialCert) Signature added in v0.2.0

func (pc PartialCert) Signature() QuorumSignature

Signature returns the signature.

func (PartialCert) Signer added in v0.5.0

func (pc PartialCert) Signer() ID

Signer returns the ID of the replica that created the certificate.

func (PartialCert) ToBytes added in v0.5.0

func (pc PartialCert) ToBytes() []byte

ToBytes returns a byte representation of the partial certificate.

type PrivateKey added in v0.2.0

type PrivateKey interface {
	// Public returns the public key associated with this private key.
	Public() PublicKey
}

PrivateKey is the private part of a replica's key pair.

type ProposeMsg added in v0.5.0

type ProposeMsg struct {
	ID          ID           // The ID of the replica who sent the message.
	Block       *Block       // The block that is proposed.
	AggregateQC *AggregateQC // Optional AggregateQC
}

ProposeMsg is broadcast when a leader makes a proposal.

func (ProposeMsg) String added in v0.5.0

func (p ProposeMsg) String() string

type PublicKey added in v0.2.0

type PublicKey = crypto.PublicKey

PublicKey is the public part of a replica's key pair.

type QuorumCert added in v0.2.0

type QuorumCert struct {
	// contains filtered or unexported fields
}

QuorumCert (QC) is a certificate for a Block created by a quorum of partial certificates.

func NewQuorumCert added in v0.5.0

func NewQuorumCert(signature QuorumSignature, view View, hash Hash) QuorumCert

NewQuorumCert creates a new quorum cert from the given values.

func (QuorumCert) BlockHash added in v0.2.0

func (qc QuorumCert) BlockHash() Hash

BlockHash returns the hash of the block that was signed.

func (QuorumCert) Equals added in v0.5.0

func (qc QuorumCert) Equals(other QuorumCert) bool

Equals returns true if the other QC equals this QC.

func (QuorumCert) Signature added in v0.5.0

func (qc QuorumCert) Signature() QuorumSignature

Signature returns the threshold signature.

func (QuorumCert) String added in v0.5.0

func (qc QuorumCert) String() string

func (QuorumCert) ToBytes added in v0.5.0

func (qc QuorumCert) ToBytes() []byte

ToBytes returns a byte representation of the quorum certificate.

func (QuorumCert) View added in v0.5.0

func (qc QuorumCert) View() View

View returns the view in which the QC was created.

type QuorumSignature added in v0.5.0

type QuorumSignature interface {
	ToBytes
	// Participants returns the IDs of replicas who participated in the threshold signature.
	Participants() IDSet
}

QuorumSignature is a signature that is only valid when it contains the signatures of a quorum of replicas.

type SyncInfo added in v0.5.0

type SyncInfo struct {
	// contains filtered or unexported fields
}

SyncInfo holds the highest known QC or TC. Generally, if highQC.View > highTC.View, there is no need to include highTC in the SyncInfo. However, if highQC.View < highTC.View, we should still include highQC. This can also hold an AggregateQC for Fast-Hotstuff.

func NewSyncInfo added in v0.5.0

func NewSyncInfo() SyncInfo

NewSyncInfo returns a new SyncInfo struct.

func (SyncInfo) AggQC added in v0.5.0

func (si SyncInfo) AggQC() (_ AggregateQC, _ bool)

AggQC returns the AggregateQC, if present.

func (SyncInfo) QC added in v0.5.0

func (si SyncInfo) QC() (_ QuorumCert, _ bool)

QC returns the quorum certificate, if present.

func (SyncInfo) String added in v0.5.0

func (si SyncInfo) String() string

func (SyncInfo) TC added in v0.5.0

func (si SyncInfo) TC() (_ TimeoutCert, _ bool)

TC returns the timeout certificate, if present.

func (SyncInfo) WithAggQC added in v0.5.0

func (si SyncInfo) WithAggQC(aggQC AggregateQC) SyncInfo

WithAggQC returns a copy of the SyncInfo struct with the given AggregateQC.

func (SyncInfo) WithQC added in v0.5.0

func (si SyncInfo) WithQC(qc QuorumCert) SyncInfo

WithQC returns a copy of the SyncInfo struct with the given QC.

func (SyncInfo) WithTC added in v0.5.0

func (si SyncInfo) WithTC(tc TimeoutCert) SyncInfo

WithTC returns a copy of the SyncInfo struct with the given TC.

type ThresholdSignature deprecated added in v0.5.0

type ThresholdSignature = QuorumSignature

ThresholdSignature is a signature that is only valid when it contains the signatures of a quorum of replicas.

Deprecated: renamed to QuorumSignature

type TimeoutCert added in v0.5.0

type TimeoutCert struct {
	// contains filtered or unexported fields
}

TimeoutCert (TC) is a certificate created by a quorum of timeout messages.

func NewTimeoutCert added in v0.5.0

func NewTimeoutCert(signature QuorumSignature, view View) TimeoutCert

NewTimeoutCert returns a new timeout certificate.

func (TimeoutCert) Signature added in v0.5.0

func (tc TimeoutCert) Signature() QuorumSignature

Signature returns the threshold signature.

func (TimeoutCert) String added in v0.5.0

func (tc TimeoutCert) String() string

func (TimeoutCert) ToBytes added in v0.5.0

func (tc TimeoutCert) ToBytes() []byte

ToBytes returns a byte representation of the timeout certificate.

func (TimeoutCert) View added in v0.5.0

func (tc TimeoutCert) View() View

View returns the view in which the timeouts occurred.

type TimeoutMsg added in v0.5.0

type TimeoutMsg struct {
	ID            ID              // The ID of the replica who sent the message.
	View          View            // The view that the replica wants to enter.
	ViewSignature QuorumSignature // A signature of the view
	MsgSignature  QuorumSignature // A signature of the view, QC.BlockHash, and the replica ID
	SyncInfo      SyncInfo        // The highest QC/TC known to the sender.
}

TimeoutMsg is broadcast whenever a replica has a local timeout.

func (TimeoutMsg) String added in v0.5.0

func (timeout TimeoutMsg) String() string

func (TimeoutMsg) ToBytes added in v0.5.0

func (timeout TimeoutMsg) ToBytes() []byte

ToBytes returns a byte form of the timeout message.

type ToBytes added in v0.2.0

type ToBytes interface {
	// ToBytes returns the object as bytes.
	ToBytes() []byte
}

ToBytes is an object that can be converted into bytes for the purposes of hashing, etc.

type View added in v0.2.0

type View uint64

View is a number that uniquely identifies a view.

func (View) ToBytes added in v0.5.0

func (v View) ToBytes() []byte

ToBytes returns the view as bytes.

type VoteMsg added in v0.5.0

type VoteMsg struct {
	ID          ID          // the ID of the replica who sent the message.
	PartialCert PartialCert // The partial certificate.
	Deferred    bool
}

VoteMsg is sent to the leader by replicas voting on a proposal.

func (VoteMsg) String added in v0.5.0

func (v VoteMsg) String() string

Directories

Path Synopsis
Package backend implements the networking backend for hotstuff using the Gorums framework.
Package backend implements the networking backend for hotstuff using the Gorums framework.
Package blockchain provides an implementation of the consensus.BlockChain interface.
Package blockchain provides an implementation of the consensus.BlockChain interface.
Package client implements a simple client for testing HotStuff.
Package client implements a simple client for testing HotStuff.
cmd
hotstuff command
Hotstuff is a utility for running HotStuff clients and replicas.
Hotstuff is a utility for running HotStuff clients and replicas.
latencygen command
LatencyGen generates a Go source file containing the latency matrix.
LatencyGen generates a Go source file containing the latency matrix.
plot command
Plot is a tool for plotting measurements from a HotStuff experiment.
Plot is a tool for plotting measurements from a HotStuff experiment.
Package consensus defines the types and interfaces that are used to implement consensus.
Package consensus defines the types and interfaces that are used to implement consensus.
byzantine
Package byzantine contiains byzantine behaviors that can be applied to the consensus protocols.
Package byzantine contiains byzantine behaviors that can be applied to the consensus protocols.
chainedhotstuff
Package chainedhotstuff implements the pipelined three-chain version of the HotStuff protocol.
Package chainedhotstuff implements the pipelined three-chain version of the HotStuff protocol.
fasthotstuff
Package fasthotstuff implements the two-chain Fast-HotStuff protocol.
Package fasthotstuff implements the two-chain Fast-HotStuff protocol.
simplehotstuff
Package simplehotstuff implements a simplified version of the three-chain HotStuff protocol.
Package simplehotstuff implements a simplified version of the three-chain HotStuff protocol.
Package crypto provides implementations of the Crypto interface.
Package crypto provides implementations of the Crypto interface.
bls12
Package bls12 implements the crypto primitives used by HotStuff using curve BLS12-381.
Package bls12 implements the crypto primitives used by HotStuff using curve BLS12-381.
ecdsa
Package ecdsa implements the spec-k256 curve signature.
Package ecdsa implements the spec-k256 curve signature.
eddsa
Package eddsa implements the ed25519 curve signature.
Package eddsa implements the ed25519 curve signature.
keygen
Package keygen provides helper methods for generating, serializing, and deserializing public keys, private keys and certificates.
Package keygen provides helper methods for generating, serializing, and deserializing public keys, private keys and certificates.
Package eventloop provides an event loop which is widely used by modules.
Package eventloop provides an event loop which is widely used by modules.
internal
cli
Package cli provide command line interface helpers for hotstuff.
Package cli provide command line interface helpers for hotstuff.
latency
Code generated by latencygen.
Code generated by latencygen.
mocks
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.
orchestration
Package orchestration implements deployment and orchestration of hotstuff replicas and clients on remote hosts.
Package orchestration implements deployment and orchestration of hotstuff replicas and clients on remote hosts.
profiling
Package profiling provides helpers for using various profilers.
Package profiling provides helpers for using various profilers.
proto/hotstuffpb
Package hotstuffpb contains protocol buffers message types and conversion functions for the HotStuff protocol.
Package hotstuffpb contains protocol buffers message types and conversion functions for the HotStuff protocol.
protostream
Package protostream implements reading and writing of protobuf messages to data streams.
Package protostream implements reading and writing of protobuf messages to data streams.
testutil
Package testutil provides helper methods that are useful for implementing tests.
Package testutil provides helper methods that are useful for implementing tests.
Package kauri contains the implementation of the Kauri protocol
Package kauri contains the implementation of the Kauri protocol
Package leaderrotation provide various leader rotation algorithms.
Package leaderrotation provide various leader rotation algorithms.
Package logging defines the Logger interface which is used by the module system.
Package logging defines the Logger interface which is used by the module system.
Package metrics contains modules that collect data or metrics from other modules.
Package metrics contains modules that collect data or metrics from other modules.
plotting
Package plotting provides functions and structures for plotting measurement data collected from running an experiment.
Package plotting provides functions and structures for plotting measurement data collected from running an experiment.
types
Package types defines various types for metrics collection.
Package types defines various types for metrics collection.
Package modules contains the module system used in the hotstuff project.
Package modules contains the module system used in the hotstuff project.
Package replica provides the required code for starting and running a replica and handling client requests.
Package replica provides the required code for starting and running a replica and handling client requests.
Package synchronizer implements the synchronizer module.
Package synchronizer implements the synchronizer module.
Package twins implements a framework for testing HotStuff implementations.
Package twins implements a framework for testing HotStuff implementations.
util
gpool
Package gpool provides a generic sync.Pool.
Package gpool provides a generic sync.Pool.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL