BFT Consensus
Overview
The Byzantine Fault-Tolerant (BFT) consensus mechanism runs 3-phase PBFT when blocks are finalized. It requires n ≥ 3f + 1 nodes to tolerate f faulty or malicious nodes. This replaces the finalize_block() step in Event Submission for BFT mode.
For PoA and PoF consensus flows, see Consensus Mechanisms .
Requirement : Minimum 4 nodes to tolerate 1 Byzantine failure (n=4, f=1: 3×1+1=4).
Flow Diagram — 3-Phase PBFT
sequenceDiagram
autonumber
participant OS as ⚙️ OrderingService
participant L as 👑 Leader Node
participant V1 as 🖥️ Validator 1
participant V2 as 🖥️ Validator 2
participant Vf as 🖥️ Validator f
OS->>L: Events batch ready → trigger consensus
rect rgb(0, 0, 0, 0)
Note over L,Vf: PHASE 1 — PRE-PREPARE
L->>L: Assign sequence number, create PRE-PREPARE message
L->>V1: PRE-PREPARE(view, seq, block_digest)
L->>V2: PRE-PREPARE(view, seq, block_digest)
L->>Vf: PRE-PREPARE(view, seq, block_digest)
end
rect rgb(0, 0, 0, 0)
Note over L,Vf: PHASE 2 — PREPARE
V1->>V1: Validate PRE-PREPARE, broadcast PREPARE
V1->>L: PREPARE(view, seq, digest)
V1->>V2: PREPARE(view, seq, digest)
V2->>L: PREPARE(view, seq, digest)
V2->>V1: PREPARE(view, seq, digest)
Note over L: Collect 2f PREPARE votes
end
rect rgb(0, 0, 0, 0)
Note over L,Vf: PHASE 3 — COMMIT
L->>V1: COMMIT(view, seq, digest)
L->>V2: COMMIT(view, seq, digest)
V1->>L: COMMIT(view, seq, digest)
V2->>L: COMMIT(view, seq, digest)
Note over L: Collect 2f+1 COMMIT votes → finalize
L->>L: Finalize & sign block
L->>OS: Block committed → push to commit_queue
end
Flow Diagram — View Change (Leader Failure)
sequenceDiagram
autonumber
participant V1 as 🖥️ Validator 1
participant VM as 🔄 BFTViewChangeManager
participant NEW as 👑 New Leader
Note over V1: Leader timeout detected (no PRE-PREPARE received)
V1->>VM: trigger_view_change(current_view, failed_leader)
VM->>VM: view += 1
VM->>VM: Broadcast VIEW-CHANGE to all validators
VM->>VM: Collect f+1 VIEW-CHANGE votes
VM->>NEW: Elect new leader: Validators[new_view % n]
NEW->>NEW: Broadcast NEW-VIEW message
NEW->>NEW: Restart from Phase 1 — PRE-PREPARE
Step-by-Step Breakdown
Step
Description
PRE-PREPARE
Leader assigns sequence number and broadcasts block digest to all validators
PREPARE
Each validator validates the PRE-PREPARE, then broadcasts its own PREPARE vote. Leader collects 2f votes
COMMIT
Leader broadcasts COMMIT. Each node collects 2f+1 COMMIT votes, then finalizes locally
View Change
If leader silent > timeout: validators increment view, elect Validators[view % n] as new leader
Consensus Comparison
Algorithm
Mechanism
Fault Tolerance
Use Case
PoA
Identity-based, authority signs
Validator reputation
Private / internal networks
PoF
Rotating leader, quorum height % n
Distributed trust
Consortium / multi-org
BFT
3-phase PBFT
Up to f Byzantine nodes in 3f+1
Critical / adversarial environments
Error Handling
Condition
Behavior
Leader timeout
View Change triggered, new leader elected (Validators[new_view % n])
Validator sends invalid digest
Vote discarded, not counted toward quorum
Network partition < f nodes
Protocol continues if quorum (2f+1) still reachable
Network partition ≥ f+1 nodes
Protocol halts until partition heals (safety over liveness)
Key Classes & Methods
Step
Class / Method
File
3-Phase PBFT
BFTConsensus.run_consensus()
consensus/bft/consensus.py
PRE-PREPARE
BFTConsensus._send_pre_prepare()
consensus/bft/consensus.py
PREPARE collect
BFTConsensus._handle_prepare()
consensus/bft/consensus.py
COMMIT finalize
BFTConsensus._handle_commit()
consensus/bft/consensus.py
View Change
BFTViewChangeManager.trigger_view_change()
consensus/bft/consensus.py
Transport
ZmqTransport.send() / receive()
network/zmq_transport.py