Simplex BFT at a glance
- ~1-second blocks, ~2-second finality. Finality is on commit, not after a long probabilistic wait.
- Message types — the underlying commonware Simplex protocol uses
Notarize(vote on a proposal),Nullify(view-change), andFinalize. - Votes aggregate via threshold BLS12-381 with buffered batch verification — a quorum certificate is a single group signature reconstructed from a t-of-n quorum of partial signatures, not N signatures.
block_hash, height,
round) and a single BLS12-381 threshold signature over the block_hash || height || round domain, reconstructed from a t-of-n quorum of validator partial
signatures. A threshold scheme yields one group signature and carries no
per-signer bitmap (unlike plain aggregate BLS). Cowboy uses
commonware_consensus::simplex::scheme::bls12381_threshold.
Mandatory proposer rotation (VRF)
Unlike stable-leader BFT, the proposer rotates every block via the VRF beacon. Each block header MUST carry the proposer’s VRF output + proof for the current height, and validators MUST verify it against the epoch seed. This is a deliberate MEV-resistance choice: no single validator observes transaction flow across consecutive blocks. The same VRF beacon also drives deterministic intra-block transaction ordering (whitepaper §6), so a proposer can’t strategically place its own transactions.Finality — the two-chain commit rule
A blockB_h is final when its direct child has a QC: if QC(B_{h+1}) exists
and B_h is the parent of B_{h+1}, then B_h is finalized. Implementations may
expose “committed” and “finalized” as distinct states. The chain never reorgs
past finality, which is what makes ~2s finality a hard guarantee rather than a
heuristic.
View change
On timeout, validators broadcastNullify carrying their highest known QC,
and the next proposer MUST build on the highest-QC block. The timeouts are
compiled into the validator (not runtime-configurable):
| Constant | Value | Role |
|---|---|---|
| Leader timeout | 1 s | time a proposer has to propose before view-change pressure |
| Certification timeout | 2 s | time to certify/notarize a proposal |
| Nullify retry | 10 s | view-change (nullify) retry interval |
| Fetch timeout | 2 s | block-fetch-from-peer timeout |
Networking
- Transport: QUIC over TLS 1.3 (required).
- Gossip: transactions flood to all peers; blocks are relayed by validators; votes go directly to the proposer.
- Peer discovery: DHT-based with bootstrap nodes.
- NAT traversal is out of protocol scope at genesis — operators own reachability (see whitepaper §6.2 / the deployment guide).
Block-space lanes
Per-block compute (the cycle gas meter) is partitioned into dedicated lanes so autonomous-actor work (timers, runner results) can’t be starved by user-transaction spam. The lanes sum to the 80M-cycle block cap (4× the 20M EIP-1559BLOCK_CYCLES_TARGET); the reserved shares below are from
types/src/constants.rs (LANE_*_CYCLES):
| Lane | Reserved (of 80M cycles) | Contents |
|---|---|---|
| System | ~50% (40.00M) | validator updates, governance, slashing |
| User | ~27.8% (22.22M) | user transactions |
| Runner | ~11.1% (8.89M) | runner job results, attestations, storage manifest anchors |
| Timer | ~11.1% (8.89M) | scheduled timer executions |
tx_hash) up to lane
capacity, then apply VRF ordering to the selected set. Each lane’s basefee is
global_basefee × lane_fee_multiplier (all 1.0× at genesis, Tier-0
governance-tunable). See the fee model.

