vrf-pbft 0.1.0

A Rust implementation of VRF-enhanced PBFT consensus protocol
Documentation
<div align="center">

# VRF-PBFT

**A Rust implementation of VRF-enhanced PBFT consensus protocol**

[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
[![Rust](https://img.shields.io/badge/rust-1.70+-orange.svg)](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

| Crate | Purpose |
|-------|---------|
| `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

| Parameter | Formula | Description |
|-----------|---------|-------------|
| 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.