Checkpoints, Casper FFG & Finality
The previous page gave the network a way to choose a head: LMD-GHOST walks from a trusted root and, at every fork, follows the subtree that the most recent attestations weigh down. That fork choice is excellent at answering “which block is the current tip?” — but it never says a block is done. A heavier fork could always, in principle, appear and pull the head sideways. GHOST gives you a most-likely history, not a permanent one.
This page adds the missing half: a way to declare a block final — irreversible not by probability but by economics. Ethereum does this with Casper FFG (Friendly Finality Gadget), a voting protocol that runs on top of the fork choice and, every couple of epochs, stamps a block as history that cannot be rewritten unless an attacker is willing to burn at least a third of all the ETH staked in the network. That is the sharpest answer this book gives to its throughline: untrusting strangers don’t just agree on the shared world computer’s state — they can make a past state unrewritable, and we can name the exact price of trying.
Two protocols, one job: probable head + permanent history
Section titled “Two protocols, one job: probable head + permanent history”It helps to hold the two mechanisms apart before we join them.
LMD-GHOST (fork choice) CASPER FFG (finality gadget) ───────────────────────── ────────────────────────────── question : which block is question : which blocks are the current HEAD? FINALIZED (permanent)? cadence : every slot (12s) cadence : every epoch boundary input : latest attestation input : FFG votes on per validator (source, target) checkpoints output : a head to build on output : a finalized checkpoint, (can still move) which never moves againGHOST is fast and fluid; it re-decides the head every slot. FFG is slow and firm; it moves in steps of whole epochs and, when it commits, it commits forever. Combining them into one protocol is called Gasper (from GHOST + Casper), and we return to that join at the end. First, the pieces.
Checkpoints: the first block of each epoch
Section titled “Checkpoints: the first block of each epoch”FFG does not vote on every block — that would be far too much traffic, since a slot is 12 seconds and an epoch is 32 of them. Instead it votes only on checkpoints, and a checkpoint is a deliberately cheap thing to name:
A checkpoint is the block at the first slot of an epoch (technically, the block that is the head at that boundary), tagged with that epoch number.
So finality advances in coarse, epoch-sized jumps. Between checkpoints the chain still fills with 32 slots of blocks and attestations as usual; the checkpoints are just the mile-markers FFG argues about.
epoch N-1 epoch N epoch N+1 ┌───────────────┐ ┌───────────────┐ ┌────────────── │ 32 slots │ │ 32 slots │ │ 32 slots … └───────────────┘ └───────────────┘ └────────────── ▲ checkpoint C(N-1) ▲ checkpoint C(N) ▲ checkpoint C(N+1) first block of N-1 first block of N first block of N+1Naming checkpoints by epoch boundaries gives every validator the same, unambiguous set of things to vote
on: not “block 0xabc…?” but “the checkpoint for epoch N.” Everyone can compute what that refers to from
their own view of the chain.
The FFG vote: a link from source to target
Section titled “The FFG vote: a link from source to target”A Casper FFG vote is not a vote for a single block. It is a vote for a link between two checkpoints — an ordered pair:
FFG vote = ( source , target )
source : an EARLIER checkpoint the validator already considers justified target : a LATER checkpoint the validator is attesting SHOULD become justifiedEvery attestation a validator makes each epoch (the same attestation that carries its
LMD-GHOST head vote) also carries this (source, target)
FFG vote. One signed message does double duty: it nudges the fork choice and it casts a finality
vote. That packing is why Gasper can run both protocols without doubling the network’s message load.
The source → target framing matters because it turns finality into a chain of links, each one built on
a checkpoint the previous link already blessed. A validator may only cast a source it believes is already
justified — you cannot bootstrap finality out of nothing; each link stands on the last.
Justification, then finalization: the two-epoch rule
Section titled “Justification, then finalization: the two-epoch rule”Now the core rule — two thresholds, applied in order.
Step 1 — justification: 2/3 of stake attests to a target
Section titled “Step 1 — justification: 2/3 of stake attests to a target”A checkpoint becomes justified when FFG votes whose target is that checkpoint are signed by
validators controlling at least two-thirds of the total staked ETH. Not two-thirds of validators by
count — two-thirds by stake weight, because attestation weight is measured in
effective balance, not headcount.
Why exactly two-thirds? It is the classic Byzantine-fault-tolerant supermajority. If honest validators control more than 2/3 of stake, then two conflicting checkpoints can never both reach the 2/3 bar in the same epoch without some validators voting for both — and voting for two conflicting targets is a slashable offence (we meet the exact rule on the slashing page). So the 2/3 threshold buys a guarantee: to justify two contradictory checkpoints, at least 1/3 of stake must have provably double-voted and can be burned.
Step 2 — finalization: justify a checkpoint’s direct child too
Section titled “Step 2 — finalization: justify a checkpoint’s direct child too”Justification alone is not final — a justified checkpoint can, in rare reorg scenarios, still be undone. Finalization needs one more step:
A justified checkpoint
C(N)becomes finalized when the very next checkpointC(N+1)— its direct child, one epoch later — also gets justified, by a supermajority link whose source isC(N).
In other words: two consecutive epoch boundaries both cross the 2/3 line, with the second’s vote pointing
its source at the first. When that happens, the earlier checkpoint is sealed.
epoch N epoch N+1 C(N) ───────────► C(N+1) │ justified │ justified, with source = C(N) │ (2/3 target) (2/3 target, source→C(N)) ▼ C(N) is now FINALIZED ✔ (irreversible)Because it takes justifying two checkpoints an epoch apart, finality lags the head by roughly two epochs. With a 6.4-minute epoch, that is the famous ~12.8 minutes: when the network is healthy, a block written now is finalized about two epochs — a shade under thirteen minutes — later.
Why reverting a finalized checkpoint costs 1/3 of all stake
Section titled “Why reverting a finalized checkpoint costs 1/3 of all stake”This is the payoff — and it is worth being precise about why the price is exactly one-third.
Suppose an attacker wants to finalize a conflicting history: a different checkpoint at the same height as one that is already finalized. To finalize anything, FFG needs 2/3 of total stake voting for the attacker’s checkpoints. But 2/3 of stake is already committed (honest validators voted for the real finalized checkpoint). For a second, conflicting checkpoint to also clear 2/3, the two supermajorities must overlap by at least:
2/3 + 2/3 − 1 = 1/3 of total stake
→ at least a THIRD of all staked ETH must have voted for BOTH conflicting checkpoints — a provable double-vote.Every one of those overlapping validators has signed two contradictory FFG votes, which is exactly the slashable condition. Anyone can submit the two conflicting signatures as a proof, and the protocol burns the offending stake. So the attack is not merely hard — it is self-incriminating and priced: to rewrite finalized history you must forfeit at least one-third of every ETH staked in the entire network, a sum measured (as of 2024) in the tens of billions of dollars. Finality here is not a statistical comfort; it is a receipt with a number on it.
honest world : one finalized history, no one slashed attacker rewrites it : two 2/3-supermajorities must overlap ≥ 1/3 → ≥ 1/3 of ALL stake is provably double-signed → that stake is SLASHED (burned) cost to revert : ≥ one third of all staked ETH, destroyedContrast: probabilistic finality that never reaches 100%
Section titled “Contrast: probabilistic finality that never reaches 100%”Bitcoin — and Ethereum’s own pre-Merge Proof of Work — offers probabilistic finality. A payment does not become final; it becomes exponentially unlikely to reverse as blocks pile on top of it. Six confirmations is convention, not a theorem. The probability of a deep reorg shrinks toward zero but never touches it — there is no block height at which the protocol declares “this can no longer be undone.” Security there is “an attacker would have to out-work the whole network,” an ongoing race with no finish line.
BITCOIN / PoW (probabilistic) ETHEREUM PoS + FFG (explicit) ───────────────────────────── ───────────────────────────────── safer as blocks accrue safe once finalized — a binary flip asymptotes toward 100%, reaches a definite "final" state never arrives after ~2 epochs revert cost : re-mine + out-hash revert cost : burn ≥1/3 of all stake (rentable, no one is punished) (slashed — attacker loses the bond)FFG’s finality is a genuinely different kind of guarantee: explicit and binary, and backed by a cost that is destroyed rather than merely spent. That is Ethereum’s headline claim for Proof of Stake — and also the source of its one asterisk, which we turn to next.
Under the hood — weak subjectivity for fresh nodes
Section titled “Under the hood — weak subjectivity for fresh nodes”Explicit finality comes with a subtle catch for a brand-new node syncing from scratch. A fresh Bitcoin node can verify the whole chain from genesis using nothing but the most-work rule; its trust is objective. A fresh Ethereum node cannot always do the equivalent, because of long-range attacks: validators who staked long ago, got finalized, and then withdrew their stake no longer have anything to lose. Nothing stops them from signing an entirely fake alternate history branching from back when they were still active — their old keys can sign whatever they like now that their bond is gone. Slashing only bites stake that is still bonded.
To an observer who has been online and watching finality tick forward, this is a non-issue — they saw the real checkpoints get finalized in real time and will never accept a conflicting old fork. But a node booting for the first time, handed both histories, cannot tell which is real from the protocol rules alone. The fix is weak subjectivity: a fresh node is given a recent trusted checkpoint (a finalized block hash from within the last few months, shipped in client software or fetched from a trusted source) and told “sync forward from here, never accept a fork that conflicts with this.” PoW advocates consider this a real weakening of trustlessness; PoS advocates consider a months-old checkpoint a mild, practical assumption that ordinary software updates already make.
Gasper: layering FFG on LMD-GHOST as one protocol
Section titled “Gasper: layering FFG on LMD-GHOST as one protocol”We have kept the two mechanisms apart for teaching. In the live protocol they are welded into one, and the weld is called Gasper. The join is elegant because each mechanism handles what the other cannot:
- LMD-GHOST picks the head every slot — fast, fluid, always answers “what do I build on now?”
- Casper FFG finalizes checkpoints every epoch — slow, firm, answers “what can never be undone?”
- The fork choice is constrained by finality. GHOST is not allowed to wander freely from genesis; it must start its walk from the latest justified checkpoint and may never select a head that would contradict a finalized one. Finality fences off the part of history GHOST is even allowed to reconsider.
┌─────────────────────────────────────────────────────────┐ │ GASPER = LMD-GHOST + Casper FFG │ │ │ │ every slot : GHOST chooses the head, │ │ starting from the latest JUSTIFIED point │ │ and never crossing a FINALIZED one │ │ │ │ every epoch: FFG turns 2/3-supermajority votes into │ │ justified → finalized checkpoints, which │ │ then become GHOST's new floor │ └─────────────────────────────────────────────────────────┘The two loops feed each other: FFG’s finalized checkpoints become the immovable floor GHOST builds up from, and GHOST’s head is what determines which checkpoint the next round of FFG votes will target. One signed attestation per validator per epoch carries both votes. That is Gasper: a probable head that updates every twelve seconds, riding on a permanent history that hardens every thirteen minutes.
The architect’s lens
Section titled “The architect’s lens”Casper FFG is the component that turns a probable head into permanent history — interrogate why it earns its place on top of a fork choice that already worked.
- Why does it exist? Because LMD-GHOST alone only ever gives a most-likely head that can still move; FFG adds an explicit, irreversible finality that a probabilistic fork choice can never produce on its own.
- What problem does it solve? It lets untrusting strangers agree that a past state is done — sealed after ~12.8 minutes with a named price for reversal (≥1/3 of all staked ETH, slashed), replacing Bitcoin’s “safer forever, final never” with a binary, economic guarantee.
- What are the trade-offs? Finality is slow (two epochs, not seconds), it demands 2/3 of stake online and honest or it stalls (as on 11–12 May 2023), and it introduces weak subjectivity — a fresh node needs a recent trusted checkpoint to rule out long-range forks, where a PoW node bootstraps objectively from genesis.
- When should I avoid it? When objective, from-genesis verification with no trusted-checkpoint assumption is the hard requirement — the property Bitcoin guards by keeping probabilistic PoW finality instead.
- What breaks if I remove it? You are back to a bare fork choice: the chain still picks a head every slot, but nothing is ever irreversible — every past block remains theoretically reorg-able, deep reorgs regain plausibility, and the “reverting costs 1/3 of all stake” guarantee that anchors Ethereum’s settlement disappears.
Check your understanding
Section titled “Check your understanding”- What exactly is a checkpoint in Casper FFG, and why does FFG vote on checkpoints rather than on every block?
- An FFG vote is a
(source, target)pair, not a vote for one block. What does each component mean, and what rule restricts whichsourcea validator may cast? - State the two-step rule precisely: what makes a checkpoint justified, and what additional condition makes it finalized? Roughly how long does the whole thing take on a healthy network, and why?
- Show why reverting a finalized checkpoint forces an attacker to forfeit at least one-third of all staked ETH. Where does the “1/3” number come from, and what makes that stake actually get destroyed?
- Contrast FFG’s finality with Bitcoin’s, and explain weak subjectivity: why can a fresh Bitcoin node bootstrap objectively while a fresh Ethereum node may need a trusted checkpoint?
Show answers
- A checkpoint is the block at the first slot of an epoch (the head at that epoch boundary), tagged with the epoch number. FFG votes on checkpoints, not every block, because voting on all ~32 blocks per epoch would flood the network; epoch-boundary checkpoints give every validator the same small, unambiguous set of things to vote on, so finality advances in coarse epoch-sized jumps.
- The source is an earlier checkpoint the validator already considers justified; the target is a
later checkpoint it is attesting should become justified. A validator may only pick a
sourceit believes is already justified — finality is a chain of links, each standing on the last, so you cannot bootstrap it from nothing. - A checkpoint is justified when FFG votes with that checkpoint as
targetare signed by validators controlling ≥2/3 of total staked ETH (by stake weight, not headcount). It becomes finalized when its direct child checkpoint (the next epoch’s) also gets justified via a link whosesourceis the first checkpoint — two consecutive justified checkpoints. That takes ~2 epochs; with a 6.4-minute epoch that is ~12.8 minutes. - Finalizing a conflicting checkpoint would need a second 2/3-of-stake supermajority, but 2/3 is already
committed to the real checkpoint. Two 2/3 sets must overlap by
2/3 + 2/3 − 1 = 1/3of total stake, so at least a third of all stake must have signed both conflicting FFG votes — a provable double-vote. That is a slashable offence: anyone submits the two signatures and the protocol burns the offending stake, so reverting finalized history costs ≥1/3 of all staked ETH, destroyed. - Bitcoin’s finality is probabilistic — a block grows exponentially harder to reverse as blocks accrue but the probability never reaches zero, so there is no “final” state. FFG’s finality is explicit and binary — after ~2 epochs a checkpoint is finalized and reverting it has a fixed slashing price. Weak subjectivity: a fresh Bitcoin node verifies from genesis using only the most-work rule (objective), but a fresh Ethereum node can’t distinguish the real history from a long-range fork forged by validators who have since unstaked (and so can’t be slashed), so it must start from a recent trusted checkpoint and refuse conflicting forks.