Fix uncle processing in historical POW blocks #9432
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Since the merge of #7936, released in version
v2.49.0
and onward, Erigon has been unable to properly download and process historical Ethereum POW blocks. This makes a mainnet sync from block 0 with snapshotting disabled (--snapshots=false
) impossible.I discovered this issue while working on the Erigon-Pulse fork for PulseChain, but the issue remains here, and has been verified with a vanilla version of Erigon v2.57.3 against Ethereum Mainnet.
Detail
When doing a full sync from block zero with snapshotting disabled, the following error will occur:
This failure is deterministic and the process will revert back to the beginning of the
[3/12 Senders]
stage. After reprocessing senders, it will eventually fail execution on the same transaction every time.Looking into this issue, I discovered that the balance for the sender at the parent block
46273
was too low. The sender should in fact have15156250000000000000
, enough to cover the transaction costs shown in the error message.Digging further into the history of this account, I found that the balance was too low because uncle rewards for an earlier mined block had not been properly awarded. The
15 ETH
in the chain state was the result of 3 blocks previously mined by the account, but the uncle reward of0.15625 ETH
had not been awarded for block2839
.This led me to discover the issue, that uncles are being dropped entirely in the new downloader:
GetBlock()
, which is required for uncle verification. After passing uncles through properly, the panic() here was triggered.It's a little surprising this has gone overlooked for so long, but I suspect that almost nobody is doing a full sync w/o snapshots. It is painfully slow afterall.
Fixed
This PR adds 3 commits fixing the issue. The first is a broken test, followed by the missing uncles fix which also resolves the broken test. The final commit adds the missing implementations in the header stage.
This fix has been verified with a fresh sync.