Skip to content

[feat] Remove non-EVM events from being emitted when an EVM tx succeeds with a VM error #2542

@Unique-Divine

Description

@Unique-Divine

Prevent non-EVM module events from leaking on failed EVM transactions

TL;DR: Currently on Nibiru, an EVM tx can fail at VM execution level (not consensus), yet Cosmos SDK events emitted during precompile/module calls still remain in tx events, which makes failed txs look like successful module state transitions.

Context - EVM Execution Semantics

When an EVM transaction is executed, there are different semantics around what dictates a transaction that's supposed to be included in a block versus excluded.

  1. (Case - Consensus Error): If the transaction fails due to gas configuration or other consensus error rules, it is not included in the block and fails early.
  2. (Case - VM Error): If an error is not a consensus error but occurs during VM execution due to smart contract logic or other things that may occur during the actual state transition, there's still gas taken for that and a transaction is still created on the blockchain, but no state transition occurs because it's failed. This is called a VM error.
  3. (Case - EVM Tx Success): If everything works perfectly, no consensus error, no VM errors, the state
    transition is validated and the state is saved, and this is a full-on, true
    success.

When an EVM transaction occurs that uses, for example, the Wasm precompile or emits other events from other SDK modules that are not x/evm, the events still show up in the case of a VM error. That makes it a bit confusing to read the block or base tooling off of indexing events, because you then have to pay attention to if the event was emitted from an actual transaction that was saved but was a failure. That is quite annoying for indexers.

Where the confusion comes from

  • Precompiles (e.g. Wasm/FunToken) call Cosmos modules and emit SDK events.
  • In precompile setup (OnRunStart), execution uses sdb.Ctx() with gas adjustments, but event emission is not isolated/reverted.
  • EVM state/logs are snapshot-aware via SDB, but SDK EventManager emissions are not automatically rolled back with EVM revert semantics.

Result: on VM-failed txs, non-EVM module events can still appear in block events.

Why indexers struggle

If an indexer consumes events alone, a failed EVM tx can appear to have completed bank/wasm/module transitions. Indexers must cross-check failure metadata (EventEthereumTx.VmError / receipt status), which is brittle and noisy.

The Ask

Detect which events can be cleaned up in the case of a VM error, and prevent them from being emitted in the block. This way, events only show up for state transitions that actually occurred, becoming saved and finalized.

  • Suppress on VM-failed txs: module/precompile side-effect events (message, bank/wasm action events, etc.)
  • Keep: essential EVM failure metadata events (e.g. EventEthereumTx) so failed txs remain discoverable and semantically correct.

Metadata

Metadata

Assignees

Labels

goPull requests that update go codex: evmRelates to Nibiru EVM or the EVM Module

Type

No type

Projects

Status

✅ Completed

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions