Skip to main content
Cowboy orders and finalizes blocks with Simplex BFT proof-of-stake. This page digests the protocol-level design (whitepaper §6); for the per-block execution that happens once a block is proposed, see the block lifecycle.

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), and Finalize.
  • 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.
A quorum certificate (QC) carries the block identity (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 block B_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 broadcast Nullify 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):
ConstantValueRole
Leader timeout1 stime a proposer has to propose before view-change pressure
Certification timeout2 stime to certify/notarize a proposal
Nullify retry10 sview-change (nullify) retry interval
Fetch timeout2 sblock-fetch-from-peer timeout
A node that has fallen behind catches up via state-sync; while syncing it is granted a 10× longer activity timeout so it isn’t dropped mid-catch-up (see Snapshots & Restore).

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-1559 BLOCK_CYCLES_TARGET); the reserved shares below are from types/src/constants.rs (LANE_*_CYCLES):
LaneReserved (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
Unused capacity cascades from higher- to lower-priority lanes. Within a lane, proposers select by highest effective fee (ties broken by 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.

MEV: what’s mitigated, what isn’t

Mitigated by construction: front-running and sandwiching (≤1s observation, ~2s finality), multi-block proposer observation (rotation), strategic self-ordering (VRF), and cross-lane congestion attacks (lane isolation). Cowboy uses no encrypted mempool — the observation window is already minimal. Explicitly out of scope (application-level concerns): single-block proposer censorship, private off-chain orderflow, and JIT MEV against actors that publish predictable state transitions (price clearings, oracle pushes). Applications needing stronger guarantees should layer commit-reveal, slippage caps, or batch auctions in actor logic — the protocol provides the substrate (1s blocks, VRF ordering, lane isolation), not application-level MEV resistance.