Summary
On Erigon v3.5.0 with the default parallel block execution path (Block-STM, EXEC3_PARALLEL=true), the node serves an incorrect transaction receipt for at least one Ethereum mainnet transaction: the wrong status, the wrong gasUsed, and an empty logs array where a log should exist.
This is distinct from the already-filed logIndex corruption (#22106 / PR #22110), which corrupts only logIndex / cumulativeGasUsed metadata and does not change a receipt's status, gasUsed, or drop its logs. The corruption reported here is not explained by the #22110 diff and, as far as we can find, has no existing issue.
Environment
- Erigon version: v3.5.0 (
erigon/3.5.0/linux-amd64)
- Chain: Ethereum mainnet
- Node type: archive
- Execution mode: parallel block execution (Block-STM),
EXEC3_PARALLEL=true (v3.5.0 default)
Affected transaction
| Field |
Value |
| Block number |
25439102 (0x1842b7e) |
| Transaction index |
229 |
| Transaction hash |
0x6a835c4fe9782ef4376ebb0dc73d1323bff6c72b9120f27b2ba241b03f8e49c3 |
Steps to reproduce
curl -s http://<erigon-v3.5.0-node>:8545 \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_getBlockReceipts","params":["0x1842b7e"]}' \
| jq '.result[] | select(.transactionIndex=="0xe5")'
(0xe5 = index 229.) eth_getTransactionReceipt for the tx hash returns the same incorrect values.
Expected vs actual (tx index 229)
Actual — served by erigon v3.5.0:
{ "status": "0x0", "gasUsed": "0x1b21a", "logs": [] }
Expected — canonical:
{ "status": "0x1", "gasUsed": "0x204dc", "logs": [ /* 1 log */ ] }
Canonical values confirmed by 5 independent public RPC providers and an independent geth v1.17.4 node.
receiptsRoot mismatch (key observation)
The block header stored on the erigon node carries the correct canonical receiptsRoot 0xd95c17b2a2efc5c9a49ea84847d9698e1a3a5bcd760fce3fcdd406701294e9a8, but the receipts the node serves for this block do not hash to it. The corruption is persisted in the ReceiptDomain, not the header.
Broader block symptoms
Impact
- OP-stack L1 derivation breaks. op-node validates L1 receipts against the block's receipt root; because the served receipts don't hash to the (correct) header root, it fails with
expected receipt root X but computed Y from retrieved receipts, stalling L2 finality for every L2 using this node as its L1 source.
- Silent correctness failure. The on-chain-canonical receipt is
status 0x1 (success); the node serves status 0x0 (failed) with wrong gasUsed and a missing log. A successful transaction is served as reverted, and any consumer relying on receipt status/gas/logs is served incorrect data with no error surfaced.
Suspected cause (not confirmed)
The Block-STM path appears to persist a receipt from a non-final transaction incarnation (an aborted/re-executed speculative attempt under optimistic concurrency) rather than the committed final incarnation — which would explain both the downstream cumulativeGasUsed/logIndex shift and the wrong status/gasUsed/missing-log on tx 229, while the header root (computed elsewhere) stays canonical. Hypothesis based on symptoms + confinement to the parallel-execution path.
Relation to existing issues
Confirmed vs suspected
Confirmed: v3.5.0 serves status 0x0/gasUsed 0x1b21a/empty logs for tx 229; canonical is status 0x1/gasUsed 0x204dc/1 log (5 public RPCs + geth v1.17.4); header receiptsRoot is canonical and served receipts don't hash to it; downstream cumulativeGasUsed/logIndex shifted; op-node L1 derivation fails against this node.
Suspected: non-final Block-STM incarnation persisted to ReceiptDomain; same class as #21490.
Mitigation note
EXEC3_PARALLEL=false stops new corruption but already-persisted receipts remain wrong and require re-derivation (re-execution of affected blocks).
Summary
On Erigon v3.5.0 with the default parallel block execution path (Block-STM,
EXEC3_PARALLEL=true), the node serves an incorrect transaction receipt for at least one Ethereum mainnet transaction: the wrongstatus, the wronggasUsed, and an emptylogsarray where a log should exist.This is distinct from the already-filed logIndex corruption (#22106 / PR #22110), which corrupts only
logIndex/cumulativeGasUsedmetadata and does not change a receipt'sstatus,gasUsed, or drop its logs. The corruption reported here is not explained by the #22110 diff and, as far as we can find, has no existing issue.Environment
erigon/3.5.0/linux-amd64)EXEC3_PARALLEL=true(v3.5.0 default)Affected transaction
25439102(0x1842b7e)2290x6a835c4fe9782ef4376ebb0dc73d1323bff6c72b9120f27b2ba241b03f8e49c3Steps to reproduce
(
0xe5= index 229.)eth_getTransactionReceiptfor the tx hash returns the same incorrect values.Expected vs actual (tx index 229)
Actual — served by erigon v3.5.0:
{ "status": "0x0", "gasUsed": "0x1b21a", "logs": [] }Expected — canonical:
{ "status": "0x1", "gasUsed": "0x204dc", "logs": [ /* 1 log */ ] }Canonical values confirmed by 5 independent public RPC providers and an independent geth v1.17.4 node.
receiptsRoot mismatch (key observation)
The block header stored on the erigon node carries the correct canonical
receiptsRoot0xd95c17b2a2efc5c9a49ea84847d9698e1a3a5bcd760fce3fcdd406701294e9a8, but the receipts the node serves for this block do not hash to it. The corruption is persisted in the ReceiptDomain, not the header.Broader block symptoms
cumulativeGasUsedandlogIndex(theeth_getLogsreturns inconsistent log indexes #22106 symptom).status, wronggasUsed, and a missing log — the part not covered byeth_getLogsreturns inconsistent log indexes #22106/stagedsync: Fix logIndex reset and missing websocket notifications in parallel execution #22110.Impact
expected receipt root X but computed Y from retrieved receipts, stalling L2 finality for every L2 using this node as its L1 source.status 0x1(success); the node servesstatus 0x0(failed) with wronggasUsedand a missing log. A successful transaction is served as reverted, and any consumer relying on receipt status/gas/logs is served incorrect data with no error surfaced.Suspected cause (not confirmed)
The Block-STM path appears to persist a receipt from a non-final transaction incarnation (an aborted/re-executed speculative attempt under optimistic concurrency) rather than the committed final incarnation — which would explain both the downstream
cumulativeGasUsed/logIndexshift and the wrongstatus/gasUsed/missing-log on tx 229, while the header root (computed elsewhere) stays canonical. Hypothesis based on symptoms + confinement to the parallel-execution path.Relation to existing issues
eth_getLogsreturns inconsistent log indexes #22106 / PR stagedsync: Fix logIndex reset and missing websocket notifications in parallel execution #22110 — logIndex + cumulativeGasUsed corruption under parallel execution. Does not cover the wrongstatus/gasUsed/dropped-log here.Confirmed vs suspected
Confirmed: v3.5.0 serves
status 0x0/gasUsed 0x1b21a/empty logs for tx 229; canonical isstatus 0x1/gasUsed 0x204dc/1 log (5 public RPCs + geth v1.17.4); headerreceiptsRootis canonical and served receipts don't hash to it; downstreamcumulativeGasUsed/logIndexshifted; op-node L1 derivation fails against this node.Suspected: non-final Block-STM incarnation persisted to ReceiptDomain; same class as #21490.
Mitigation note
EXEC3_PARALLEL=falsestops new corruption but already-persisted receipts remain wrong and require re-derivation (re-execution of affected blocks).