Ethereum's FFG Turns Out to Be Tendermint

I recently noticed that Ethereum’s FFG closely resembles Tendermint, even though the two protocols are described in quite different ways.

At a high level, the base rules of FFG are like two-chain HotStuff. On top of that, each epoch has 32 slots. The fixed 12 seconds of each slot play the same role as the lock-waiting time of a Tendermint view-change.

FFG can be split into three parts: the commit rule, the vote rule, and the slashing rule. The first two are essentially identical to two-chain HotStuff. In the language of partially synchronous BFT, the commit rule is as follows. Consider two blocks $a$ and $b$ in adjacent views, where $b$ extends $a$. When both $a$ and $b$ have collected a QC, a node commits $a$. The vote rule is that a node votes for the current block only if it extends the highest lock the node holds.

The slashing rule has two parts. The second part means the following. Suppose a node casts the link $v \to v+k$, where $k$ is a positive integer. Casting this link is equivalent to holding the lock on the block of view $v$. Suppose the same node also casts the link $v-a \to v+b$, where $a$ and $b$ are positive integers. Then the two votes form a surround vote, and the node is slashed. In the language of partially synchronous BFT, this is the same as holding a higher lock and still voting for a lower lock.

Moreover, FFG commits in a two-chain manner. So, in theory, it has the same hidden-lock problem, even though Ethereum does not need to run a view-change. Ethereum uses the span of one epoch to ensure that, even when a hidden lock appears, all honest nodes synchronize to the highest lock and extend that lock in the next view, that is, the next epoch. Recall that Tendermint assumes that, after a fixed delay, a node receives the locks of all honest nodes. The two mechanisms are the same.

A protocol like Ethereum’s FFG does not need a view-change. In general, a view-change serves two purposes. The first is to change the leader. The second is to synchronize information. Ethereum already uses NTP and PoS to rotate to a new slot every 12 seconds, and to a new epoch every $32 \times 12$ seconds, with no message needed to trigger the change. As for synchronizing information, the span of one epoch almost guarantees that all necessary information has reached every node.

Back to Blogs