This note is to clarify the nuances of new types of reorgs that can happen after the Gloas fork. The reason for this note is some confusion that seems to have been caused by the need to creating a new Engine API intrepretation.

Honest reorgs pre Fulu

Consensus nodes sync beacon blocks in a two step communication process with the execution engine. When they receive the beacon block, it contains the execution payload, the CL passes it to the EL via a call to the notify_newPayload engine API call. After the payload has been validated, the CL informs the EL that this payload is the new head via a call to the notify_ForkchoiceUpdated engine API call. All in all, the beacon block arrives around 2 seconds into the slot, and shortly after the engine has updated the head and users requesting information about the status of the Ethereum network get this information rather quickly. For all users, this process happens almost immediately after the beacon block arrives, no matter if the beacon block is early or late during the slot.

However, when the beacon block N (with execution blocknumber n) arrives later than 4 seconds into the slot, then the proposer of the next slot starts building a payload based on N-1 (blocknumber n-1). To effect this, the proposer witholds his call of FCU, they rather send an FCU with payload attributes and the hash of N-1, triggering block production for N+1 (with blocknumber n) to be based on N-1, and only sends the notify_newPayload call for N, never informing the EL of any FCU to N. Notice that everybody else (not proposing) on the other hand did send FCU, so their head advanced from N-1 to N. I am using slot numbers here for the blocks, but on the EL of course, the block number for N+1 and the blocknumber of N will be equal, they are both the succesor of N-1. The proposer instead later release his beacon block N+1 and attesters accept it, so they send FCU for N+1. Notice that for attesters the chain has advanced N-1-> N -> N+1. Thus they see a reorg of block numbers n-1 -> n -> n.

The execution engine of the proposer on the other hand, does not even see this reorg, the head in that EL is N-1 -> N+1, never seeing N as head.

Most importantly, neither user of the EL ever see a rollback of the chain.

Honest reorgs pos Gloas

In the Gloas fork a different situation can happen, blocks and payloads are synced at different times. The reorg of a full beacon block that is late, with a payload as above, continues working in the same way. But however, the following series of events is new and can actually happen.

  • The beacon block N-1 arrives. It becomes head on the beacon chain.
  • The payload for N-1, with blocknumber n-1 arrives, it becomes head and FCU is sent.
  • The beacon block for N arrives early in its slot, it becomes head in the beacon chain.
  • The payload for N does not arrive during its slot.
  • During the slot N+1 there is no beacon block, attesters then vote to their head, which is the combination of N in the beacon chain and n-1 in the EL.
  • Later during the slot N+1 the payload for N, with blocknumber n arrives. This payload is imported, in the beacon chain and a call to notify_NewPayload is sent and the head becomes (N, n).
  • The proposer of N+2 however, when running forkchoice to produce his block N+2, realizes that all the attestations in the previous slot, shift the head back to N being empty!

This is the crucial point, this proposer, may have even had imported very early and fine the payload for N, but attestations are forcing him to reorg this payload n that no one has seen apparently.

There are many consequences that follow downstream of this scenario. Some of them are of higher urgency than others.

Trigerring block production

The proposer/builder of N+2 needs to build the payload (which will have blocknumber n) on top of n-1, thus, he must send FCU with payload attributes to n-1. Thus he would send consecutively two FCUs to the engine n -> n-1. From the point of view of the EL this is a rollback, not a reorg.

From the point of view of the CL this is an actual reorg: the chain reorged from (N, full) to (N, empty) which are two competing nodes with common ancestor (N-1, full).

This is the unique urgent thing that the CL needs the EL to implement. Anything else affects UX of Ethereum and is subject to debate.

Informing users of the rollback.

Differently than attesters in the Fulu case, the attesters in this case also see a reorg (N-1, full) -> (N, empty) -> (N, full) -> (N, empty). There is no rollback here, each of the last two arrows is a reorg. The first one happens when the payload arrives, still during slot N+1, the second one when they move into slot N+2 and they account for the attestations during slot N+1. Later when the last block arrives this chain is extended to (N+2, full).

From the point of view of the EL of those users on the other hand this sequence of events is n-1 -> n -> n-1, a rollback! then later they take a new block n' (the one built on slot N+2). This reorg n -> n-1 -> n' in two steps, used to be informed to users as simply n -> n' and now a user that queries the EL will see these new rollbacks, possibly affecting user experience on L1.

What is the correct behavior?

The only feature that is critical to the protocol is the hability of triggering block production. This happens when the call of FCU has payload attributes and this is only seen by the proposing node. All the other calls to FCU without payload attributes are not strictly necessary and is debatable if they should even be sent in the first place. They are reflected in the UX as rollbacks of the chain and the EL client itself needs to handle it.

Prysm does not send these calls that produce rollbacks. We only send FCU when we need to trigger block production. For non proposing nodes, the next FCU would come directly when the reorging payload arrives, being a normal reorg from the point of view of the EL.

There is an argument to send the EL the rollback however, this is information that is available in the CL that the user on the EL (specially time sensitive ones) could prefer to have. That is, these users could know that the payload has been rolled back and the next block will most likely reorg it, they could find this out very early, but if we do not send this FCU, it could take a long time for them to find out. Specially if there are many missing blocks in the middle.