Byzantine Fault Tolerance
Honest nodes reach agreement even when some nodes lie. Toggle traitors and watch the quorum math.
How Byzantine Fault Tolerance Works
The Byzantine Generals Problem asks: how can a group of nodes agree on a value when some of them might be actively malicious — lying, sending conflicting messages, or colluding? This is harder than crash failures. A crashed node is silent; a Byzantine node can say anything.
The answer, proved by Lamport, Shostak, and Pease in 1982: you need at least 3f+1 nodes to tolerate f Byzantine faults. With 4 nodes (above), you can tolerate 1 traitor. With 7 nodes, you could handle 2. Fewer than 3f+1 and the traitors can cause honest nodes to disagree.
This simulation models PBFT (Practical Byzantine Fault Tolerance), the protocol Castro and Liskov described in 1999. It runs in phases:
Client Request. The client sends its request to all replicas, not just the primary. This is important: when the primary is Byzantine, honest nodes already know a request is pending, so they can timeout and trigger a view change.
Pre-Prepare. The primary receives the client request and broadcasts a PRE-PREPARE message with a proposed value to all replicas. This assigns an order to the request.
Prepare. Each honest replica that accepts the pre-prepare broadcasts a PREPARE message to all other replicas. A node waits until it has 2f+1 matching prepares (including its own). This ensures that a majority of honest nodes agree on the request and its ordering — even if the primary is Byzantine and tried to send different values to different replicas.
Commit. Once a node has enough prepares, it broadcasts COMMIT to all others. When a node collects 2f+1 matching commits, it executes the request and replies to the client. The commit phase ensures that even if some nodes were slow during prepare, the decision is durable across the group.
Why 3f+1? Any two quorums of 2f+1 nodes (out of 3f+1 total) overlap in at least f+1 nodes. Since at most f are Byzantine, at least one node in the overlap is honest. This honest node in the intersection guarantees consistency — it won't confirm two different values. With fewer than 3f+1 nodes, Byzantine nodes could create two non-overlapping "honest-looking" quorums that disagree.
View changes. What if the primary itself is Byzantine? It could refuse to send PRE-PREPARE, or send conflicting values to different replicas. PBFT handles this with a view change: if honest nodes don't hear from the primary within a timeout, they rotate to a new primary (round-robin through the replicas) and retry. This keeps happening until an honest node becomes primary.
Try the scenario buttons above to see different failure modes. Conflicting Primary is especially interesting — the Byzantine primary sends different values to different replicas, and honest nodes detect the conflict during the prepare phase when they can't agree on a single value.