<div align="center">
# VRF-PBFT
**A Rust implementation of VRF-enhanced PBFT consensus protocol**
[](LICENSE)
[](https://www.rust-lang.org)
<img src="assets/vrf_pbft_logo.png" alt="VRF-PBFT Logo" width="300">
</div>
---
## Installation
```sh
# Clone
git clone https://github.com/Adel-Ayoub/vrf-pbft.git
cd vrf-pbft
# Build
cargo build
# Run tests
cargo test
# Run examples
cargo run --example single_round
cargo run --example simulation
cargo run --example byzantine
```
---
## Architecture
### Consensus Flow
<div align="center">
```
┌──────────────────────────────────────────────────────────┐
│ VRF Role Assignment │
│ Each node runs VRF sortition to determine its role │
│ Proposer(~1) │ Validator(~3f+1) │ Packer(~f+1) │ Normal │
└──────────────────────────┬───────────────────────────────┘
│
▼
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│PrePrepare│─▶│ Prepare │─▶│ Commit │─▶│ Reply │
│ │ │ │ │ │ │ │
│ Proposer │ │Validators│ │Validators│ │ Block │
│ creates │ │ vote on │ │ confirm │ │finalized │
│ block │ │ block │ │ votes │ │ │
└──────────┘ └──────────┘ └──────────┘ └──────────┘
needs needs
2/3+1 2/3+1
votes votes
```
</div>
### Sortition Algorithm
<div align="center">
```
VRF Proof Binomial CDF (log-space)
┌─────────┐ ┌─────────────────────────────────────┐
│ sk + α │────▶│ hash → [0,1) uniform random value │
└─────────┘ │ p = expected / total_weight │
│ Walk CDF: P(X ≤ k) for k = 0..w │
│Return first k where val < cumulative│
└──────────────────┬──────────────────┘
│
k > 0 ──▶ Selected
k = 0 ──▶ Not selected
```
</div>
---
## How It Works
### VRF (Verifiable Random Function)
Each node uses ECVRF (SECP256K1) to privately determine its role for each round. The selection is random but cryptographically verifiable. Higher-weight nodes are more likely to be selected, implementing proof-of-stake.
### PBFT (Practical Byzantine Fault Tolerance)
The protocol tolerates up to **f** Byzantine (malicious) nodes out of **3f+1** total. A quorum of **2f+1** votes is required at each voting phase. Byzantine nodes can vote against valid blocks, but they cannot prevent consensus as long as enough honest validators are elected.
### Per-Round Lifecycle
1. **VRF Sortition** -- each node independently determines its role
2. **PrePrepare** -- the elected proposer creates a block linked to the previous hash
3. **Prepare** -- validators check `prev_hash` against their ledger and vote
4. **Commit** -- validators confirm their votes
5. **Reply** -- the finalized block is appended to all nodes' ledgers
Rounds where no proposer is elected or quorum is not reached are skipped.
---
## Features
### Implemented
#### Consensus Protocol
- PBFT 4-phase consensus (PrePrepare, Prepare, Commit, Reply)
- Stage transition validation
- Adaptive quorum threshold (2/3+1 of committee, capped at 2f+1)
#### VRF Sortition
- ECVRF with SECP256K1_SHA256_TAI cipher suite
- Binomial CDF in log-space for numerical stability
- Per-role expected values (separate probabilities for Proposer, Validator, Packer)
- Weight-based selection (proof-of-stake)
#### Byzantine Fault Tolerance
- Configurable fault tolerance parameter `f`
- Duplicate vote detection via voter identity tracking
- Byzantine nodes modeled as always-reject voters
- System tolerates up to `f` faults out of `3f+1` nodes
#### Block Chain Integrity
- SHA-256 block hashing
- `prev_hash` chain linking validated by all honest nodes
- Deterministic serialization via `bincode`
---
## Examples
### Single Round
Runs a minimal 4-node consensus (f=1) until one round succeeds:
```sh
cargo run --example single_round
```
```
Running VRF-PBFT with 4 nodes (f=1)...
Consensus reached on round 4!
Proposer: node 2
Prev hash: f5a5fd42d16a2030...
Hash: fcf00efdad604ede...
Messages exchanged: 4
```
### Simulation
Runs 100 rounds with 10 weighted nodes (f=3), showing proposer distribution:
```sh
cargo run --example simulation
```
```
Results:
Rounds attempted: 100
Blocks committed: 60
Success rate: 60.0%
Proposer distribution:
Node 1 (weight 500): 31 blocks
Node 2 (weight 300): 15 blocks
Node 3 (weight 200): 2 blocks
...
Ledger consistency: PASS
```
### Byzantine
Demonstrates fault tolerance with 2 Byzantine nodes out of 7 (f=2):
```sh
cargo run --example byzantine
```
```
Byzantine fault tolerance demo
Nodes: 7 (5 honest, 2 byzantine)
f=2: system tolerates up to 2 faults
Threshold: 2f+1 = 5
After 100 round attempts:
Blocks committed: 27
Ledger consistency: PASS
```
---
## Project Structure
```
vrf-pbft/
├── Cargo.toml
├── README.md
├── LICENSE
├── assets/
│ └── vrf_pbft_logo.png
├── src/
│ ├── lib.rs # Crate root and re-exports
│ ├── types.rs # Hash, Block, Role, Stage types
│ ├── error.rs # Error handling with thiserror
│ ├── vrf.rs # VRF client + binomial sortition
│ ├── node.rs # Consensus node with VRF role assignment
│ ├── engine.rs # Multi-node consensus orchestrator
│ └── pbft/
│ ├── mod.rs # PBFT module re-exports
│ ├── message.rs # Protocol messages (PrePrepare, Prepare, Commit, Reply)
│ ├── stage.rs # Stage transition validation
│ └── round.rs # Round state with vote tracking
├── tests/
│ ├── integration.rs # End-to-end consensus tests
│ ├── pbft_test.rs # PBFT message and round tests
│ └── vrf_test.rs # VRF key generation, proof, and sortition tests
└── examples/
├── single_round.rs # Minimal single-round demo
├── simulation.rs # Multi-round weighted simulation
└── byzantine.rs # Byzantine fault tolerance demo
```
---
## Requirements
- Rust toolchain (1.70+)
- OpenSSL (for ECVRF)
---
## Dependencies
| `vrf` | ECVRF implementation (SECP256K1) |
| `sha2` | SHA-256 block hashing |
| `serde` + `bincode` | Deterministic serialization |
| `rand` + `rand_chacha` | Deterministic key generation |
| `thiserror` | Error type derivation |
| `libm` | Log-gamma for binomial CDF |
---
## Protocol Parameters
| Total nodes | `3f + 1` | Minimum nodes for fault tolerance |
| Quorum | `2f + 1` | Votes needed per phase |
| Expected proposers | `1` | Average proposers per round |
| Expected validators | `3f + 1` | Average validators per round |
| Expected packers | `f + 1` | Average packers per round |
---
## License
MIT License - Copyright (c) 2026 Adel-Ayoub
See [LICENSE](LICENSE) for details.