Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix uncle processing in historical POW blocks #9432

Merged
merged 3 commits into from
Feb 15, 2024

Conversation

sjb933
Copy link
Contributor

@sjb933 sjb933 commented Feb 12, 2024

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:

[INFO] [02-08|09:06:11.859] [3/12 Senders] DONE                      in=7h55m24.504489889s
[INFO] [02-08|09:06:11.861] [4/12 Execution] Blocks execution        from=0 to=19180016
[WARN] [02-08|09:06:12.599] [4/12 Execution] Execution failed        block=46274 hash=0x8252137084baebea389ddb826c4e7a63cbef2effc0d6526a5394377e5e8dada0 err="invalid block: could not apply tx 0 from block 46274 [0x669890439f5093b7dfbca9b06de1d6da78ceacf1ec0753252b3e6cf10ff81a3e]: insufficient funds for gas * price + value: address 0xdC49b9dc1AbB93Ebb856547a1C0578D65f4A32DE have 15000000000000000000 want 15024629952223800000"
[INFO] [02-08|09:06:12.602] [4/12 Execution] Completed on            block=46273

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 have 15156250000000000000, 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 of 0.15625 ETH had not been awarded for block 2839.

This led me to discover the issue, that uncles are being dropped entirely in the new downloader:

  1. Uncles aren't being passed from the engineapi block downloader (nil is passed).
  2. Uncles aren't being considered when mapping from native types to the execution engine's GRPC types.
  3. Uncles aren't being considered when mapping back from execution engine's GRPC types to the native types.
  4. The header stage is lacking an implementation for 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.

Note that because the issue originates in the downloader, once the execution failure has been encountered, the entire db must be deleted and a fresh sync started. Erigon cannot recover from the downloaded blocks being inserted into the DB w/ missing uncles.

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.

@AskAlexSharov AskAlexSharov merged commit 3e47a43 into ledgerwatch:devel Feb 15, 2024
7 checks passed
somnathb1 added a commit that referenced this pull request Mar 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants