Simplex is a leader-based consensus protocol. Validators take turns proposing blocks and then collectively vote on them. The protocol produces a single, ever-growing chain of finalized blocks that every honest validator agrees on.
Simplex proceeds in slots, each representing a designated opportunity to propose a block. For
every slot, a validator is selected as the leader responsible for proposing a candidate block. The
leader broadcasts its candidate, every validator checks it, and if validation succeeds, casts a
notarization vote. Once a validator sees notarization votes totaling
If the leader is offline or malicious, the slot eventually times out and validators cast skip votes instead. A quorum of skip votes lets the protocol move on without producing a block for that slot.
An honest validator never both finalizes and skips the same slot, and never notarizes two different candidates for the same slot. Because any two quorums overlap in at least one honest validator, these per-validator constraints lift to global guarantees: at most one candidate can be finalized per slot, and a finalized slot can never be skipped. This is the core of safety.
Multiple notarized but non-finalized chains may temporarily coexist if, because of network conditions or leader misbehavior, a sequence of slots is both skipped and has valid candidates. Such forks collapse as soon as the next finalization quorum is achieved, since any candidate in the later slot must necessarily be a descendant of a slot that was not skipped. Honest validators thus commit a candidate to the ledger once it has a finalized descendant.
The rest of this document rigorously develops the flavor of the protocol used in TON and is organized as follows:
-
Section 1 formally defines the ledger model and the voting rules that honest validators must follow to guarantee safety.
-
Section 2 proves safety: finalized chains are always consistent, regardless of network conditions or adversary behavior.
-
Section 3 refines the rules into a concrete protocol by adding candidate generation rules, formalizing timeouts, and describing mechanisms required for operation in a lossy network. We then prove that the resulting protocol achieves liveness: with probability
$1$ , the output log grows without bound. -
Section 4 covers practical considerations that do not affect safety or liveness but improve throughput, and maps concepts from this document to their counterparts in the C++ implementation.
We consider a system of
Each honest validator holds an EUF-CMA-resistant signing key pair; each validator's public key is known to all. No assumption is made about Byzantine validators' keys beyond possession of a public key.
Let
-
Genesis validity.
$\mathsf{ValidSeq}(\varnothing) = \mathsf{true}$ . -
Extendability. For every valid sequence
$(d_1,\dots,d_m)$ , there exists some$d$ such that$\mathsf{ValidSeq}(d_1,\dots,d_m,d)$ holds.
A sequence
Consensus does not depend on the internal structure of payloads beyond these properties.
Slots. Slot number is a discrete index $s \in \mathbb{N}0$. Slots are grouped into leader windows of size $L$. Window $k$ covers slots $[kL, (k+1)L)$ with an associated leader $v{(k \bmod n)+1}$.
Candidates. A candidate is a tuple
-
$s$ is the slot number, -
$d \in \mathcal{D}$ is the block payload, -
$(s_p, h_p)$ is a parent reference: either$(-1, \varnothing)$ or a pair with$s_p < s$ , -
$\sigma$ is a valid signature by the leader of the window containing$s$ over$(s, d, s_p, h_p)$ .
For a candidate
Chains. A chain ending at
- the first candidate has the genesis parent:
$(s_{p1},h_{p1}) = (-1,\varnothing)$ , and - each subsequent candidate references the previous one:
$(s_{pi},h_{pi}) = (s_{i-1},h_{i-1})$ for$i \in [2, m]$ .
The slot set of a chain is
The associated sequence
A candidate
Votes. At any point, a validator may cast a vote signed by its signing key certifying some statement
Certificates. A certificate for a statement
We say that
We implicitly set the statements
A particular validator
-
$\mathsf{Notar}(s,h)$ . Validator$v$ has not cast a vote for$\mathsf{Notar}(s, h')$ for$h \ne h'$ , and there exists a candidate$(s,d,s_p,h_p,\sigma)$ identified by$(s,h)$ such that:-
$\mathsf{Notar}(s_p,h_p)$ is reached, - for each slot
$s_p < s' < s$ , the statement$\mathsf{Skip}(s')$ is reached, - the candidate
$(s,h)$ is valid.
-
-
$\mathsf{Skip}(s)$ . Validator$v$ has not cast a vote for any statement$\mathsf{Final}(s,h)$ . -
$\mathsf{Final}(s,h)$ .$\mathsf{Notar}(s,h)$ is reached, and validator$v$ has not cast a vote for$\mathsf{Skip}(s)$ .
Honest validators cast votes only when they can verify that the corresponding conditions hold. They are not required to cast votes immediately when the conditions become provable.
Lemma 2.1 (Final–Skip exclusion). For any slot
Proof. Suppose both are reached. Each certificate has total signing weight
Lemma 2.2 (Unique notarization). For any slot
Proof. If
Lemma 2.3 (Finalization implies notarization). If
Proof. The certificate for
Lemma 2.4 (Unique finalization). For any slot
Proof. Suppose
Lemma 2.5 (Chain notarization). If
Proof. By induction on chain length. For the head,
Theorem 2.6 (Safety). If
Proof. If
Otherwise, let
Let $(s^, h^)$ be the candidate identifier with the largest slot $s^$ such that $v$ has observed $\mathsf{Final}(s^, h^)$, or $(-1, \varnothing)$ if no finalization has been observed. The output log of $v$ is the chain state of the chain ending at $(s^, h^*)$.
Corollary 2.7 (Consistency). Any two honest validators' output logs are such that one is a prefix of the other.
Proof. Let $(s_a^, h_a^)$ and $(s_b^, h_b^)$ be the latest finalized identifiers observed by
validators
The permission for
Safety holds unconditionally but says nothing about progress. The voting rules in Section 1.4 are
compatible with validators never casting a single vote. To prove liveness, we need to specify when
honest validators actually vote, how leaders produce candidates, and how the network delivers
messages between validators. This section provides those operational rules (Section 3.1), introduces a
probabilistic network model (Section 3.2), and then proves that, under these rules and this model,
finalization happens infinitely often with probability
Fix parameters
An honest validator
Rule 1 (Frontier tracking). A slot
When
The next two rules describe how validators obtain and produce candidates.
Rule 2 (Candidate resolution). Honest validators store candidates they have voted
Given a certificate proving that
Rule 3 (Leader duty). When window
-
$s_p < kL$ , -
$\mathsf{Notar}(s_p,h_p)$ is reached, -
$\mathsf{Skip}(s')$ is reached for every$s_p < s' < kL$ .
Validator
The candidate is broadcast to all validators.
The following three rules govern how validators vote on candidates and handle leader failures.
Rule 4 (Notarize). Upon receiving a candidate
-
$v$ has not previously voted$\mathsf{Notar}(s,\cdot)$ for any candidate at slot$s$ . -
$\mathsf{Notar}(s_p,h_p)$ is reached. - For every slot
$s'$ with$s_p < s' < s$ ,$\mathsf{Skip}(s')$ is reached. - Candidate
$(s,h)$ is valid.
Rule 5 (Finalize). Validator
-
$v$ has voted$\mathsf{Notar}(s,h)$ , -
$\mathsf{Notar}(s,h)$ is reached, -
$v$ has not voted$\mathsf{Skip}(s)$ .
Rule 6 (Skip). For each window
Let $k^$ be the window containing the largest slot $s^$ such that
The final two rules handle certificate propagation and recovery from stalls.
Rule 7 (Certificate formation and rebroadcast). When
Rule 8 (Standstill resolution). When
- the certificate for
$\mathsf{Final}(s,\cdot)$ with largest slot$s$ that$v$ has observed (unless$s=-1$ ), - all certificates
$v$ holds for slots$> s$ , - all votes cast by
$v$ for slots$> s$ .
We consider the following two-phase network model:
-
Adversarial phase (
$t < T_\mathsf{GST}$ ). The adversary controls message delivery between all pairs of validators: it may delay, reorder, or drop messages arbitrarily. -
Good phase (
$t \ge T_\mathsf{GST}$ ). Each message sent by an honest validator to another honest validator is an independent trial: it is delivered within time$\delta$ with probability$1-r$ and lost otherwise. Here$r \in [0,1)$ is the drop rate.
Unlike the standard GST model, which assumes perfect delivery after stabilization, we retain
independent message loss after
Assumption 9 (Vote and certificate delivery). Each vote or certificate sent from one
honest validator to another after
Assumption 10 (Candidate broadcast delivery). For any slot where the designated leader
is honest and broadcasts a candidate after
Assumption 11 (Candidate resolution success). Each candidate-resolution request sent to
an honest validator after
Let
Let
$$ E_0 := {\text{no slot } s > s_f \text{ is ever finalized after } t_0}.
$$
Lemma 3.1 (Eventual dissemination of honest-held data). Condition on
Proof. Under
Fix
$$
\Pr[\text{$v$ never receives
$$
Since the set of honest sender-receiver pairs is finite, this holds simultaneously for all
of them with probability
Lemma 3.2 (Every slot is eventually cleared under an infinite standstill). Condition on
Proof. Proceed by induction on
Assume that every slot
Now consider slot
-
Some honest validator eventually observes
$\mathsf{Notar}(s,h)$ for some$h$ .By Lemma 3.1, every honest validator eventually observes the same notarization certificate. Therefore slot
$s$ is eventually cleared for every honest validator by Rule 1. -
No honest validator ever observes any
$\mathsf{Notar}(s,\cdot)$ .It can be shown that in this case no honest validator can ever prove that any
$\mathsf{Notar}(s,\cdot)$ is reached. (Broadly, if no honest validator observes a particular certificate, no honest validator can prove the existence of such.)Therefore no honest validator ever votes
$\mathsf{Final}(s,\cdot)$ , because Rule 5 requires proving that some$\mathsf{Notar}(s,\cdot)$ is reached. Since the window containing$s$ is active and Rule 6 gives a finite skip timeout, every honest validator eventually votes$\mathsf{Skip}(s)$ .The total honest weight is
$W-f \ge q$ , so honest skip votes alone suffice to reach$\mathsf{Skip}(s)$ . Each honest validator includes its own skip vote in every subsequent standstill broadcast, so by Lemma 3.1 every honest validator eventually receives enough honest skip votes to observe$\mathsf{Skip}(s)$ . Thus slot$s$ is eventually cleared for every honest validator.
In both cases, slot
Lemma 3.3 (Locally provable eligible bases in sufficiently late active windows). Condition on
Proof. Fix such
If
Since window
If
Finally, any chain ending at a base with slot
Lemma 3.4 (Tail bound for state resolution). There exist constants
Let
$$ \Pr[\text{resolution is not completed within time } T] \le C_\mathrm{res} m^{\beta+1} T^{-\beta}.
$$
In particular, for a base in window
$$ \Pr[\text{base state is not resolved within time } T] \le C'_\mathrm{res} k^{\beta+1} T^{-\beta}
$$
for a suitable constant
Proof. Consider one missing candidate on the chain. Because the chain is certified
slot-by-slot, at least one honest validator stores that candidate: honest validators store
all candidates they vote
A single resolution request chooses a uniformly random peer. The probability that the
request is addressed to an honest holder is at least
By Rule 2, retries use exponentially increasing timeouts. Therefore there exist constants
$$ \Pr[\text{one fixed candidate is still unresolved after time } T] \le (1-a)^{\lfloor B' \ln(T/B) \rfloor}.
$$
Setting
Now let the chain length be at most
$$ \Pr[P] \le m \cdot C_0 (T/m)^{-\beta} = C_0 m^{\beta+1} T^{-\beta}.
$$
This proves the claim with
Lemma 3.5 (Uniform positive chance of finalization in late honest windows). There exist constants
Let
Proof. Fix such a window
Let
We will show that, for all sufficiently large
-
$u$ resolves the chosen base and produces the candidate quickly, - the candidate reaches a quorum-weight honest set
$H_k$ , - the leader's proof of eligibility reaches every validator in
$H_k$ via standstill broadcasts, - every validator in
$H_k$ resolves the base state quickly, - notarization and finalization votes are exchanged quickly enough.
We treat these steps in order.
First, the leader must resolve the chosen base state and produce its candidate. Since any
chain ending at a base with slot
$$ \Pr[\text{leader does not finish this within time } \tau_k/4] \le C_1 k^{\beta+1} \tau_k^{-\beta}
$$
for some constant
Second, once the candidate is produced and broadcast, Assumption 10 implies that with
probability at least
Third, the validators in
As long as no new finalized block is observed, Rule 8 makes the leader rebroadcast all of
these certificates every
$$ M_k := \left\lfloor \frac{\tau_k}{2T_s} \right\rfloor - 1
$$
standstill attempts once
$$ \Pr[P'] \le n(kL+1)(1-p_\mathrm{sdeliv})^{M_k}.
$$
The right-hand side tends to
Fourth, each validator in
$$ \Pr[\text{some validator in } H_k \text{ fails to resolve within time } \tau_k/4] \le C_2 k^{\beta+1} \tau_k^{-\beta}
$$
for some constant
Fifth, the resulting notarization and finalization votes must be exchanged quickly enough.
Choose some collector
- every validator in
$H_k$ delivers its notarization vote to$c_k$ within$\delta$ ; -
$c_k$ delivers the resulting notarization certificate to every validator in$H_k$ within$\delta$ ; - every validator in
$H_k$ delivers its finalization vote to$c_k$ within$\delta$ .
This involves at most
$$ \Pr[E_\mathrm{vote}] \ge p_\mathrm{sdeliv}^{3n}.
$$
Now define the success event
- the leader resolves the chosen base and produces the candidate within
$\tau_k/4$ ; - the candidate reaches an honest set
$H_k$ of total weight at least$q$ within$\Delta_\mathrm{bcast}$ ; - by time
$\tau_k/2$ , every validator in$H_k$ has received all certificates in$P_k$ ; - by time
$\tau_k/2 + \tau_k/4$ , every validator in$H_k$ has resolved the base state; -
$E_\mathrm{vote}$ occurs.
On
The total time used on
$$ C_1 k^{\beta+1}\tau_k^{-\beta}
- C_2 k^{\beta+1}\tau_k^{-\beta}
- n(kL+1)(1-p_\mathrm{sdeliv})^{M_k} \le \frac{1}{2}.
$$
For such
$$ \Pr[E_k] \ge \frac{1}{2}, p_\mathrm{bcast}, p_\mathrm{sdeliv}^{3n}.
$$
Set
Finally, on
Theorem 3.6 (A later finalization occurs almost surely). Fix any finite execution prefix ending at time
Proof. Let
By Lemma 3.2, on
Enumerate, on the event
Lemma 3.5 states that for every
$$ \Pr!\left[\bigcap_{i=1}^m A_i^c\right] \le (1-\varepsilon)^m \qquad\text{for every } m \ge 1.
$$
But on
$$ \Pr[E_0] \le \Pr!\left[\bigcap_{i=1}^m A_i^c\right] \le (1-\varepsilon)^m \qquad\text{for every } m \ge 1.
$$
Letting
Theorem 3.7 (Infinitely many finalized blocks). With probability
Proof. Define a sequence of random slots $(S_j){j \ge 0}$ recursively by $S_0 := -1$, and for each $j \ge 0$, let $S{j+1}$ be the smallest slot strictly larger than
Theorem 3.6 applies after any finite execution prefix. In particular, on the event that
$$ \Pr[S_{j+1} < \infty \mid S_j < \infty] = 1 \qquad\text{for every } j \ge 0.
$$
By induction on
$$ \Pr[S_j < \infty] = 1 \qquad\text{for every } j \ge 0.
$$
Hence, with probability
Theorem 3.7 establishes almost-sure liveness. Under the operational rules of Section 3.1 and the
probabilistic post-$T_\mathsf{GST}$ network model of Section 3.2, the protocol finalizes blocks
infinitely often with probability
In the C++ node, the implementation lives in validator/consensus/. The following table maps
protocol concepts to their code counterparts:
| Protocol concept | Code |
|---|---|
| Slot |
CandidateId::slot (types.h); per-slot state in ConsensusState::slots_ (simplex/state.h) |
slots_per_leader_window in NewConsensusConfig::Simplex
|
|
| Leader rotation |
SimplexCollatorSchedule::expected_collator_for: simplex/bus.cpp) |
| Candidate |
struct Candidate (types.h): id, parent, block data, leader signature |
|
|
NotarizeVote, SkipVote, FinalizeVote (simplex/votes.h) |
| Certificates |
Certificate<T> template (simplex/certificate.h); aliases NotarCert, SkipCert, FinalCert
|
| Frontier |
PoolImpl::now_ (simplex/pool.cpp): smallest slot not yet notarized or skipped |
| Rule 1 (frontier tracking) |
PoolImpl::advance_present advances now_; ConsensusState::notify_finalized prunes old slots |
| Rule 2 (candidate resolution) |
CandidateResolverImpl (simplex/candidate-resolver.cpp): random-peer fetch with exponential backoff (0.5 s initial, 1.5$\times$, 30 s cap) |
| Rule 3 (leader duty) |
BlockProducerImpl::generate_candidates (block-producer.cpp): produces |
| Rule 4 (notarize) |
ConsensusImpl::try_notarize (simplex/consensus.cpp): async pipeline of parent wait |
| Rule 5 (finalize) |
ConsensusImpl::try_vote_final (simplex/consensus.cpp) |
| Rule 6 (skip) |
ConsensusImpl::alarm (simplex/consensus.cpp): fires after first_block_timeout_s_ per window |
| Rule 7 (cert formation/rebroadcast) |
PoolImpl::handle_vote (simplex/pool.cpp) forms certs at quorum; PoolImpl::handle_our_certificate rebroadcasts obtained certificates |
| Rule 8 (standstill) |
PoolImpl::alarm (simplex/pool.cpp): fires every 10 s, broadcasts all held certs and own votes |
Communication uses a private validator overlay (simplex/private-overlay.cpp). Votes and
certificates are sent individually to each peer. Candidates are broadcast using two-step FEC
erasure coding (overlay/broadcast-twostep.cpp), where the data is split into
Rule 3 only requires the leader to produce one candidate per window. The implementation produces
generate_candidates loops over all slots in the window, producing one candidate per slot
with each referencing the previous as its parent. Later candidates in the window begin generation
immediately without waiting for earlier ones to be notarized, since the leader already knows the
only possible parent — it just produced it.
The implementation sometimes suppresses votes that the Section 3.1 rules would require. None of these affect liveness, since in all such situations the suppressed vote would not lead to formation of a new certificate for a non-finalized slot.
Rule 6 requires first_block_max_timeout_s is planned.
Assumptions 10 and 11 require bounded delivery times
The egress induced by the protocol is currently unbounded. In particular, a sufficiently long period of asynchrony (or a bug) can induce a state whose synchronization saturates link capacity, causing unsynchronized state to only grow further — a death spiral. We plan to address this with better timeout tuning and optimizations to the standstill resolution mechanism.
The two-step FEC encoding uses
The network model requires drop probabilities to be independent across packets. In practice, QUIC is more likely to drop packets after a burst of high momentary egress, even when it could have spread the load over time. We plan to address this by more precise tracking of the moment each message becomes irrelevant for the protocol, allowing earlier cancellation and reducing unnecessary egress.
The leader sometimes produces an empty candidate — one that references an existing block by
its BlockIdExt rather than carrying new block data. Empty candidates participate in consensus
normally (they are notarized, finalized, and form chains) but do not advance any user-visible
blockchain state.
Empty candidates are generated in two situations, both driven by constraints external to consensus:
-
A shardchain leader generates empty candidates when the masterchain's last finalized seqno falls more than 8 blocks behind the shard's current tip. This is a legacy validation requirement that prevents the shardchain from building an arbitrarily long tail of blocks that the masterchain has not yet acknowledged.
-
A masterchain leader generates empty candidates when the next block to produce would be more than one seqno ahead of the last consensus-finalized block. This ensures that every masterchain block eventually receives finalization signatures, which all non-validator nodes depend on.