[F-2026-17738] - Reverted derived execution still emits events and mutates block bloom #16
Merged
Merged
Conversation
…nintended state persistence
…ived EVM execution
…F-2026-17738) A reverted derived call must not contribute logs or bloom for uncommitted state, but it must still emit a tx_log event paired with its ethereum_tx. The JSON-RPC log builder (TxLogsFromEvents) matches logs to txs positionally — the Nth tx_log belongs to the Nth eth tx — so dropping the tx_log on failure desyncs logs across the other derived txs in the same block (wrong logs on one receipt, missing logs on another). Always emit the ethereum_tx + tx_log + message triple under commit; on a revert res.Logs is empty so the tx_log carries no logs, and the bloom/log-size transients are guarded behind !res.Failed(). The failed tx therefore shows a status-0 receipt with empty logs and no bloom side effects. Adds regression tests: - EthTxLogEventsStayPaired: interleaved success/failure derived calls keep the ethereum_tx and tx_log event counts equal (fails on the drop-tx_log approach). - FailedExecutionNoBloomSideEffect: a reverted call leaves bloom/log-size unchanged while still emitting the ethereum_tx + empty tx_log pair.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
[F-2026-17738] - Reverted derived execution still emits events and mutates block bloom
Issue
In
DerivedEVMCallWithData, whencommit=trueand the EVM execution reverts (res.Failed()==true), the event emission block is only gated onif commit— with no check on whether the execution succeeded. This causes three incorrect side effects on the failure path:File:
x/vm/keeper/call_evm.goBug 1 —
EventTypeTxLogemitted for reverted transactionsIn Ethereum, a reverted transaction produces no logs — the EVM clears them on REVERT. Emitting
EventTypeTxLogfor a failed execution creates ghost log entries that downstream indexers, block explorers, and RPC clients treat as real, even though no corresponding state change exists in the store.Bug 2 — Block bloom filter polluted by reverted logs
The block bloom filter only covers logs from successful transactions. Updating it with logs from a reverted execution means
eth_getLogsbloom lookups return false positives — clients believe a contract emitted an event in a block when it did not.Bug 3 — Internal contradiction
The code explicitly acknowledges the failure by appending
EthereumTxFailedto the receipt event attributes, yet immediately proceeds to emitEventTypeTxLogwith logs from that same failed execution.Impact
Clients observing logs, receipts, and bloom effects see uncommitted state. This causes inconsistency across explorers, traces, and downstream indexers — they record events for executions that left no trace in the actual chain state.
Solution
Split the event emission into two parts:
Always emit (for both success and failure):
EventTypeEthereumTx— this is the transaction receipt; failed transactions still appear in the block in Ethereum, just with a failed status. Indexers need this to know the tx was attempted.EventTypeMessage— module-level bookkeeping, not state-dependent.Only emit on
!res.Failed():EventTypeTxLog— reverted transactions produce no logs.SetBlockBloomTransient— bloom only covers successful tx logs.SetLogSizeTransient— only counts committed logs.txLogAttrsconstruction — moved inside the guard since it is only needed forEventTypeTxLog.Behavior after fix
commitres.Failed()truetruefalseFailed derived executions remain trackable via the
EventTypeEthereumTxreceipt event (which carries theEthereumTxFailedattribute), but produce no phantom logs and do not corrupt the block bloom — matching Ethereum's own behavior for reverted transactions.Closes: #XXXX
Author Checklist
All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.
I have...
mainbranch