Expand description
A lightweight consensus library for making binary decisions in P2P networks.
This library implements the Hashgraph-like Consensus Protocol, which lets groups of peers vote on proposals and reach agreement even when some peers are unreliable or malicious. It’s designed to be fast (O(log n) rounds), secure (Byzantine fault tolerant), and easy to embed in your application.
§How it works
- Someone creates a
types::CreateProposalRequestwithin ascope. - Peers cast votes (yes/no), each cryptographically signed and linked into a hashgraph.
- Once enough votes are collected the session transitions to
session::ConsensusState::ConsensusReachedand atypes::ConsensusEventis emitted.
§What the library does NOT do
This library handles consensus calculation (vote validation, hashgraph verification, threshold math, liveness rules). It performs no I/O and no orchestration. Your application is responsible for:
- Network propagation — gossip proposals and votes to peers yourself;
call
process_incoming_proposal/process_incoming_voteon receipt. - Timeout scheduling — schedule a timer per proposal and call
handle_consensus_timeoutwhen it fires. Without this, proposals with offline voters stayActiveforever and silent-peer liveness logic never runs. expected_voters_countaccuracy — this drives all threshold math; a wrong value produces wrong results.- Session eviction awareness — the default service keeps at most 10 sessions per scope; older sessions are silently dropped.
§Architecture
ConsensusService is the single entry point.
It is generic over two pluggable backends:
ConsensusStorage— where sessions and votes are persisted (in-memory, database, etc.)ConsensusEventBus— how consensus events are delivered (broadcast channel, message queue, etc.)
All consensus business logic lives in the service. The backends are pure
infrastructure — swap them without changing any consensus behavior.
Use storage() and
event_bus() to access the backends
directly for reads, cleanup, and event subscription.
§Getting started
The main entry point is service::DefaultConsensusService (a type alias for
service::ConsensusService with in-memory storage and broadcast events).
use hashgraph_like_consensus::{
scope::ScopeID,
service::DefaultConsensusService,
types::CreateProposalRequest,
};
use alloy::signers::local::PrivateKeySigner;
let service = DefaultConsensusService::default();
let scope = ScopeID::from("my-scope");
let signer = PrivateKeySigner::random();
let proposal = service
.create_proposal(
&scope,
CreateProposalRequest::new(
"Upgrade contract".into(),
b"Switch to v2".to_vec(),
signer.address().as_slice().to_vec(),
3, // expected voters
60, // expiration (seconds from now)
true, // liveness: silent peers count as YES at timeout
)?,
)
.await?;
let vote = service
.cast_vote(&scope, proposal.proposal_id, true, signer)
.await?;§Modules
| Module | Purpose |
|---|---|
service | ConsensusService and DefaultConsensusService |
session | ConsensusSession, ConsensusConfig, and ConsensusState |
scope | ConsensusScope trait and ScopeID alias |
scope_config | Per-scope defaults (ScopeConfig, NetworkType) |
types | Request/event types (CreateProposalRequest, ConsensusEvent) |
storage | ConsensusStorage trait and InMemoryConsensusStorage |
events | ConsensusEventBus trait and BroadcastEventBus |
error | ConsensusError enum |
utils | Low-level validation and hashing helpers |
Modules§
- error
- Error types for the consensus library.
- events
- protos
- scope
- scope_
config - Scope-level configuration for consensus defaults.
- service
- service_
stats - Scope-level statistics for monitoring consensus activity.
- session
- Consensus session and configuration types.
- storage
- Storage trait and default in-memory implementation.
- types
- Core request and event types.
- utils
- Low-level helpers for hashing, signing, validation, and consensus calculation.