RewindToTimestamp() in rewind.go temporarily performs an FCU to a synthetic block before doing an FCU back to the actual target block. This synthetic block is constructed to have the same block number, timestamp, content and parent as the target block, but its fee recipient is modified in order to produce a different hash:
|
// Step 1: Insert a synthetic block (modified fee recipient) which |
|
// is built on the parent of the target block: |
|
// [n-1,parent] <-- [n,target] <--...<-- [m>n,unsafe] |
|
// |
|
// [n,synthetic] |
|
syntheticBlockHash, err := e.insertSyntheticPayload(ctx, targetBlock.Number) |
However, the fee recipient of a block can influence the execution of the transactions within the block (for example, it is observable in EVM code using the COINBASE opcode). As a result, if the block contains a transaction that depends on the fee recipient, modifying the fee recipient without recomputing the payload's state root and other execution-derived fields might cause it to be rejected when NewPayload() is called from within insertSyntheticPayload(). This would cause an error and make it impossible to go through with the rewind to the target block no matter how many times it is attempted, potentially halting progress of cross-validation.
Recommendation
Construct the synthetic block by modifying a field that does not affect execution results, such as ExtraData, instead of FeeRecipient. Alternatively, provide a fallback that recomputes fields that depend on execution results, such as the state root, in the case that NewPayload() fails.
RewindToTimestamp()inrewind.gotemporarily performs an FCU to a synthetic block before doing an FCU back to the actual target block. This synthetic block is constructed to have the same block number, timestamp, content and parent as the target block, but its fee recipient is modified in order to produce a different hash:_audits_Ethereum-optimism_optimism_interopv2/op-supernode/supernode/chain_container/engine_controller/rewind.go
Lines 47 to 52 in bd29b7d
However, the fee recipient of a block can influence the execution of the transactions within the block (for example, it is observable in EVM code using the
COINBASEopcode). As a result, if the block contains a transaction that depends on the fee recipient, modifying the fee recipient without recomputing the payload's state root and other execution-derived fields might cause it to be rejected whenNewPayload()is called from withininsertSyntheticPayload(). This would cause an error and make it impossible to go through with the rewind to the target block no matter how many times it is attempted, potentially halting progress of cross-validation.Recommendation
Construct the synthetic block by modifying a field that does not affect execution results, such as
ExtraData, instead ofFeeRecipient. Alternatively, provide a fallback that recomputes fields that depend on execution results, such as the state root, in the case thatNewPayload()fails.