Skip to content

fix: evm tx index and log indexes are not patched (alternative design)#1132

Merged
vladjdk merged 53 commits into
mainfrom
vlad/pr-812-alt-design
Apr 27, 2026
Merged

fix: evm tx index and log indexes are not patched (alternative design)#1132
vladjdk merged 53 commits into
mainfrom
vlad/pr-812-alt-design

Conversation

@vladjdk
Copy link
Copy Markdown
Member

@vladjdk vladjdk commented Apr 24, 2026

Alternative to #812.

Fixes EVM tx and log indexing under BlockSTM, and keeps RPC receipt indices consistent in mixed-tx blocks.

ctx.TxIndex() is actually correct under both sequential and STM runners. The SDK passes the original block-order index into deliverTx.

However, the SDK's STMRunner passes the original block-order index into deliverTx, which BaseApp forwards into ctx.TxIndex(). The only invariant parallel execution actually breaks is the cumulative log.Index, since it depends on the log count of every prior successful eth tx in the block.

These are patched once per block, post-execution, by evmtypes.PatchTxResponses, installed as a TxRunner wrapper via the new x/vm/runner package (runner.SetRunner is now required for sequential and STM runners alike).

Changes from #812:

  • Restore ctx.TxIndex() in TxConfig, receipt.TransactionIndex, and the ante handler's EmitTxHashEvent. These were zeroed in the original patch.
  • PatchTxResponses modifies existing event attributes in place instead of synthesizing new events.
  • PatchTxResponses doesn't halt on non-TxMsgData payloads (similar to how Ethermint handled this case)
  • Guard test for the SDK TxIndex assumptions (DefaultRunner/STMRunner pass the slice position into deliverTx).
  • End-to-end RPC test (adapted from fix: logindex json rpc #1087) for block-global log.Index across receipts.

@vladjdk vladjdk requested a review from a team as a code owner April 24, 2026 15:36
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 24, 2026

Greptile Summary

This PR fixes EVM tx and log indexing under BlockSTM by narrowing the post-execution patch to only the two fields that parallel execution actually breaks (log.Index and log.TxIndex), while restoring ctx.TxIndex() plumbing everywhere it was unnecessarily stripped. The PatchTxResponses function now also rewrites the ante-emitted ethereum_tx event's AttributeKeyTxIndex from the cosmos-level position to the eth-only rank, so receipt.TransactionIndex (derived from the stored event) stays consistent with log.TxIndex in mixed-tx blocks — directly addressing the divergence raised in the prior review thread. Previous concerns about hard failures on non-EVM tx unmarshal are resolved by the continue-on-unmarshal-failure path, which is covered by TestPatchTxResponses_NonTxMsgDataDoesNotHaltBlock.

Confidence Score: 5/5

Safe to merge; all remaining findings are P2 test-quality observations that do not affect production correctness.

The core logic is well-reasoned and the two previously raised P1 concerns (unmarshal hard-failure and ethTxIndex divergence in mixed blocks) are both addressed and tested. The only open findings are P2: a misleading test-case name in response_test.go and a minor coverage gap in the STM contract test's outer assertions. Neither affects runtime behavior.

x/vm/types/response_test.go — test case names for failed-tx scenarios should be clarified to avoid implying the counter never advances for failed EVM txs

Important Files Changed

Filename Overview
x/vm/types/response.go New PatchTxResponses function rewrites log.Index, log.TxIndex, and ante-emitted event AttributeKeyTxIndex from cosmos-position to eth-only rank; outer unmarshal failure now continues instead of returning an error (addressing previous reviewer concern)
x/vm/types/response_test.go Good coverage for event rewriting and mixed-block scenarios; "mixed success and failed txs" test uses an artificial failed-tx-without-event scenario that doesn't match real production behavior, making the test name misleading
x/vm/runner/runner.go Clean patchingRunner wrapper: delegates to inner runner, applies PatchTxResponses post-execution; SetRunner helper centralises the wiring previously inlined in evmd/app.go
x/vm/runner/runner_test.go Covers log-index patching, error propagation, and no-eth-response passthrough; encodeEthResponse helper faithfully reproduces production encoding path
x/vm/runner/tx_index_contract_test.go Guards the SDK contract that both DefaultRunner and STMRunner pass original block-order index to deliverTx; STM outer assertion only checks runs>=1 rather than strict per-position uniqueness
ante/evm/11_emit_event.go EmitTxHashEvent now emits ctx.TxIndex() (cosmos-level position) which PatchTxResponses will rewrite to eth-only rank; comment updated to reflect the new rationale
rpc/backend/comet_to_eth.go ReceiptsFromCometBlock uses txResult.EthTxIndex (now eth-only rank from patched events) for receipt.TransactionIndex; correctly aligned with log.TxIndex after PatchTxResponses
evmd/app.go Replaces inline customRunner with vmrunner.SetRunner; cleaner and avoids duplicating the PatchTxResponses wrapping logic per consuming application

Sequence Diagram

sequenceDiagram
    participant BaseApp
    participant patchingRunner
    participant inner as inner TxRunner (STM/Default)
    participant deliverTx
    participant AnteHandler
    participant PatchTxResponses

    BaseApp->>patchingRunner: Run(ctx, ms, txs, deliverTx)
    patchingRunner->>inner: Run(ctx, ms, txs, deliverTx)
    loop each tx[i] in parallel (STM) or serial
        inner->>deliverTx: deliverTx(tx, decoded, ms, txIndex=i)
        deliverTx->>AnteHandler: AnteHandle(ctx with TxIndex=i)
        AnteHandler-->>deliverTx: EmitTxHashEvent(cosmos-pos=i)
        deliverTx-->>inner: ExecTxResult{Events[ethereum_tx.TxIndex=i], Data[log.TxIndex=raw]}
    end
    inner-->>patchingRunner: []ExecTxResult (raw indices)
    patchingRunner->>PatchTxResponses: rewrite log.Index, log.TxIndex, event.AttributeKeyTxIndex
    Note over PatchTxResponses: ethTxIndex counter tracks eth-only rank<br/>events rewritten cosmos-pos to eth-rank<br/>log.TxIndex and log.Index set cumulatively
    PatchTxResponses-->>patchingRunner: []ExecTxResult (patched)
    patchingRunner-->>BaseApp: []ExecTxResult (patched)
    Note over BaseApp: Stored events carry eth-only rank<br/>receipt.TransactionIndex == log.TxIndex
Loading

Reviews (2): Last reviewed commit: "comment" | Re-trigger Greptile

Comment thread x/vm/types/response.go
Comment thread x/vm/types/response.go
@vladjdk vladjdk requested a review from mmsqe April 24, 2026 15:56
@vladjdk
Copy link
Copy Markdown
Member Author

vladjdk commented Apr 24, 2026

@greptile review

Comment thread x/vm/types/response.go Outdated
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 24, 2026

Codecov Report

❌ Patch coverage is 68.88889% with 28 lines in your changes missing coverage. Please review.
✅ Project coverage is 65.55%. Comparing base (ee31585) to head (c833608).
⚠️ Report is 6 commits behind head on main.

Files with missing lines Patch % Lines
x/vm/types/response.go 72.54% 3 Missing and 11 partials ⚠️
rpc/backend/comet_to_eth.go 16.66% 4 Missing and 1 partial ⚠️
rpc/backend/tx_info.go 0.00% 4 Missing and 1 partial ⚠️
rpc/backend/utils.go 62.50% 1 Missing and 2 partials ⚠️
rpc/backend/tracing.go 0.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1132      +/-   ##
==========================================
+ Coverage   62.24%   65.55%   +3.30%     
==========================================
  Files         332      335       +3     
  Lines       23725    23643      -82     
==========================================
+ Hits        14767    15498     +731     
+ Misses       7072     6930     -142     
+ Partials     1886     1215     -671     
Files with missing lines Coverage Δ
ante/evm/11_emit_event.go 100.00% <ø> (ø)
ante/evm/mono_decorator.go 75.19% <100.00%> (ø)
indexer/kv_indexer.go 73.21% <100.00%> (ø)
rpc/types/events.go 77.98% <100.00%> (+0.41%) ⬆️
rpc/types/utils.go 39.93% <ø> (-0.92%) ⬇️
x/vm/keeper/abci.go 91.30% <ø> (-0.37%) ⬇️
x/vm/keeper/config.go 94.11% <100.00%> (ø)
x/vm/keeper/keeper.go 89.63% <ø> (+17.46%) ⬆️
x/vm/runner/runner.go 100.00% <100.00%> (ø)
x/vm/types/tx_result.go 100.00% <100.00%> (ø)
... and 5 more

... and 26 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@cosmos cosmos deleted a comment from vladcosmoslabs Apr 24, 2026
Comment thread x/vm/types/response.go
Comment thread rpc/backend/utils.go Outdated
Comment thread x/vm/keeper/abci.go
@vladjdk vladjdk added this pull request to the merge queue Apr 27, 2026
Merged via the queue into main with commit a23f79c Apr 27, 2026
23 of 24 checks passed
@vladjdk vladjdk deleted the vlad/pr-812-alt-design branch April 27, 2026 12:56
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.

5 participants