Skip to content

fix: use Default::default() for TransactionInfo for forward compatibility#401

Merged
mattsse merged 1 commit into
mainfrom
feat/alloy-timestamp
Jan 26, 2026
Merged

fix: use Default::default() for TransactionInfo for forward compatibility#401
mattsse merged 1 commit into
mainfrom
feat/alloy-timestamp

Conversation

@mattsse
Copy link
Copy Markdown
Contributor

@mattsse mattsse commented Jan 26, 2026

Use ..Default::default() pattern to ensure forward compatibility when new fields are added to TransactionInfo.

This prepares the crate for upcoming changes to add a block_timestamp field.

Related: ethereum/execution-apis#729

…lity

Use `..Default::default()` pattern to ensure forward compatibility when
new fields are added to `TransactionInfo`.

Related: ethereum/execution-apis#729
Amp-Thread-ID: https://ampcode.com/threads/T-019bfc1a-6448-779a-b74a-8b8e53a73680
Co-authored-by: Amp <amp@ampcode.com>
@mattsse mattsse requested a review from DaniPopes as a code owner January 26, 2026 21:42
@mattsse mattsse merged commit 010908d into main Jan 26, 2026
12 checks passed
asdv23 added a commit to mantle-xyz/revm-inspectors that referenced this pull request May 11, 2026
…#9)

* chore: bump revm 30.0.2 (paradigmxyz#379)

bump patch

* chore: bump revm 30.0.2 (paradigmxyz#380)

* chore: bump to revm 33 (paradigmxyz#381)

## Motivation

<!--
Explain the context and why you're making that change. What is the
problem
you're trying to solve? In some cases there is not a problem and this
can be
thought of as being the motivation for your change.
-->

Per: https://github.com/bluealloy/revm/releases/tag/v100

* chore: release 0.33.0

* feat: Fix geth prestate filtering for prefunded creations (paradigmxyz#383)

This aims at resolving issues mentioned in paradigmxyz#382 , typically this one :
<img width="1818" height="694" alt="image"
src="https://github.com/user-attachments/assets/51b82944-c711-421b-8479-05095ae9bbce"
/>

To fix this , what i did was : 
- Keep track of addresses that are marked as Create and were truly empty
in the database snapshot. Only these addresses are filtered from the
prestate diff so prefunded contract deployments remain visible.

- Introduce account_was_empty helper to avoid re-computing the emptiness
check and add a regression test
(prestate_diff_keeps_prefunded_created_accounts) that covers a prefunded
creation vs. a true empty-address creation.

cc @mattsse  Please check it out if it resolves 

should close this one paradigmxyz/reth#19703

---------

Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>

* feat: upstream DebugInspector from reth (paradigmxyz#384)

Moves `DebugInspector` from reth to revm-inspectors as requested in
paradigmxyz/reth#19932.

This was introduced in paradigmxyz/reth#19925 to unify debug tracing
across all Geth tracer types.

* chore: release 0.33.1

* test: add test for string error decode (paradigmxyz#386)

* fix: use pre code if hash matches (paradigmxyz#387)

this fixes an issue where we would return diffs like

```
                "post": {
                    "0x093f6c270ac22ec240f0c6fd7414ea774ca8d3e5": {},
                    "0x2641c2ded63a0c640629f5edf1189e0f53c06561": {},
```

for `0x91b066df39661db7bcca1cb8bb8afd11816414408d44cbfcf6144f440d5dfe3b`
ref paradigmxyz/reth#19703

however nothing changed in the account here and these should have been
filtered out via:


https://github.com/paradigmxyz/revm-inspectors/blob/f7503520888efc11eac3142fe7d611c519811b25/src/tracing/builder/geth.rs#L349-L349

and cleared from post via:


https://github.com/alloy-rs/alloy/blob/35e20437670d987680a6715bcc173f3d357f8254/crates/rpc-types-trace/src/geth/pre_state.rs#L188-L201

the reason why this didn't work is because:

the code can be None here which would make retain_change not remove the
values

```
          "result": {
                "post": {
                    "0x093f6c270ac22ec240f0c6fd7414ea774ca8d3e5": {},
                    "0x2641c2ded63a0c640629f5edf1189e0f53c06561": {},
                    "0x95222290dd7278aa3ddd389cc1e1d165cc4bafe5": {
                        "balance": "0xc87826afc2b88254"
                    },
                    "0xbf5495efe5db9ce00f80364c8b423567e58d2110": {
                        "storage": {
                            "0x0000000000000000000000000000000000000000000000000000000000000035": "0x000000000000000000000000000000000000000000004b7b53b759cac06bc3b2",
                            "0xec8c572bc2e66bfe14376dece39002d6d97d311020c59bc23a93016013e92439": "0x0000000000000000000000000000000000000000000000000f294a8cb09ad9cb"
                        }
                    },
                    "0xbfe474605fb7f1cf3693a3f21af2e329f7222462": {
                        "balance": "0x269f4a55a240465",
                        "nonce": 5
                    },
                    "0xf2f305d14dcd8aaef887e0428b3c9534795d0d60": {
                        "balance": "0xe984e9959d534d3cdf"
                    }
                },
                "pre": {
                    "0x093f6c270ac22ec240f0c6fd7414ea774ca8d3e5": {
                        "balance": "0x1ea3abe47d76b5e00",
                        "code": "..",
                        "nonce": 1
                    },
                    "0x2641c2ded63a0c640629f5edf1189e0f53c06561": {
                        "balance": "0x1cb3ca6ff6dc41400",
                        "code": "..",
                        "nonce": 1
                    },
                    "0x95222290dd7278aa3ddd389cc1e1d165cc4bafe5": {
                        "balance": "0xc8781d351add1146",
                        "nonce": 797368
                    },
                    "0xbf5495efe5db9ce00f80364c8b423567e58d2110": {
                        "balance": "0x0",
                        "code": "...",
                        "nonce": 1,
                        "storage": {
                            "0x0000000000000000000000000000000000000000000000000000000000000035": "0x000000000000000000000000000000000000000000004b7b448e0f3e0fd0e9e7"
                        }
                    },
                    "0xbfe474605fb7f1cf3693a3f21af2e329f7222462": {
                        "balance": "0x11d7cc57700ae2ed",
                        "nonce": 4
                    },
                    "0xf2f305d14dcd8aaef887e0428b3c9534795d0d60": {
                        "balance": "0xe975a599714e5f3cdf",
                        "code": "...",
                        "nonce": 1
                    }
                }
            },

```

we can always use the precode here if the hashes match

* chore: release 0.33.2

* feat: add support for erc7562 tracer (paradigmxyz#392)

This aims to resolve this issue :
paradigmxyz#391

cc @mattsse

* feat: stage revm to 34.0.0 (paradigmxyz#385)

stage latest main commit

---------

Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>

* chore: release 0.34.0

* ci: update to tempoxyz (paradigmxyz#395)

* fix: always include storage values for `SLOAD` and `SSTORE` in `GethTrace` (paradigmxyz#389)

The default tracer for `debug_*` RPC methods was not reporting warmed
storage values. This deviates from Get's implementation
and—seemingly—the documented expectation:

```rs
/// Represents a storage change during execution.
///
/// This maps to evm internals:
/// [JournalEntry::StorageChanged](revm::JournalEntry::StorageChanged)
///
/// It is used to track both storage change and warm load of a storage slot. For warm load in regard
/// to EIP-2929 AccessList had_value will be None.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct StorageChange {
    /// key of the storage slot
    pub key: U256,
    /// Current value of the storage slot
    pub value: U256,
    /// The previous value of the storage slot, if any
    pub had_value: Option<U256>,
    /// How this storage was accessed
    pub reason: StorageChangeReason,
}
```

In particular, the `SLOAD` for pc `235`, `279`, and `308` are missing
`"storage"`. This PR resolves the issue.


For reference:


[revm-inspectors.json](https://github.com/user-attachments/files/24275105/revm-inspectors.json)

[geth.json](https://github.com/user-attachments/files/24275106/geth.json)

* test: add prestate replay testing infrastructure (paradigmxyz#399)

Add reusable tooling for debugging RPC tracing using prestate tracer
responses captured from mainnet transactions.

## Changes

- Add `tests/it/repro.rs` with:
  - `ReproTestFixture`/`TxData` types for deserializing JSON fixtures
  - `spec_id_from_ethereum_hardfork`/`spec_id_from_block` helpers
  - `build_db_from_prestate` to populate CacheDB from AccountState
  - `ReproContext` builder for easy test setup

- Add `testdata/repro/tx-selfdestruct.json` fixture from reth's e2e test
  (mainnet tx 0x391f4b6a...selfdestruct via USDT withdrawal)

- Add `alloy-hardforks` dev dependency for block-to-hardfork mapping

## Usage

```rust
const FIXTURE: &str = include_str!("../../testdata/repro/my-fixture.json");

#[test]
fn test_my_trace() {
    let ctx = ReproContext::load(FIXTURE);
    let config = PreStateConfig::default();

    let mut inspector = TracingInspector::new(
        TracingInspectorConfig::from_geth_prestate_config(&config)
    );

    let db = ctx.db.clone();
    let mut evm = Context::mainnet()
        .with_db(ctx.db.clone())
        .modify_cfg_chained(|cfg| cfg.spec = ctx.spec_id)
        .build_mainnet()
        .with_inspector(&mut inspector);

    let res = evm.inspect_tx(ctx.tx_env()).unwrap();
    // ... assertions on trace results
}
```

This enables writing repro tests with the flow:
**raw transaction + prestate JSON → configure tracer → run → assert**

Refs:
https://github.com/paradigmxyz/reth/blob/main/crates/ethereum/node/tests/e2e/prestate.rs

---------

Co-authored-by: Amp <amp@ampcode.com>

* fix: use Default::default() for TransactionInfo for forward compatibility (paradigmxyz#401)

Use `..Default::default()` pattern to ensure forward compatibility when
new fields are added to `TransactionInfo`.

This prepares the crate for upcoming changes to add a `block_timestamp`
field.

Related: ethereum/execution-apis#729

Co-authored-by: Amp <amp@ampcode.com>

* chore: release 0.34.1

* feat: expose refund_counter in `CallTrace` (paradigmxyz#402)

Required to be able to recover pre-refund totals from purely just the
`CallTrace` for gas introspection in foundry.
foundry-rs/foundry#13262

* chore: release 0.34.2

* chore: bump MSRV to 1.91 (paradigmxyz#407)

Bump MSRV from 1.86 to 1.91.

* feat: implement Clone for DebugInspector (paradigmxyz#406)

Implement `Clone` for `DebugInspector` to enable use with `TxTracer`,
which requires `Inspector: Clone`.

Non-JS variants clone trivially. The `Js` variant reconstructs the
`JsInspector` from its stored `code` and `config` — same approach
`fuse()` already uses.

* devnet2-revm: bump revm patch for release procedure (paradigmxyz#408)

## Summary
This PR is part of the **revm release procedure** (`devnet2-revm`
chain).

It bumps revm-inspectors to revm v35.0.0.

## Changes
- Bump `revm` dependency from 34.0.0 to 35.0.0 in `Cargo.toml`.
- Adapt to upstream API change: `journal().precompile_addresses()` now
returns a type that requires `.iter().copied().collect()` instead of
`.clone()`.
- Lower `gas_limit` in selfdestruct tests from 100M to 10M to comply
with EIP-7825 transaction gas limit cap enforced in revm 35.

## Validation
- `cargo check`
- `cargo +nightly clippy --workspace --all-targets --all-features`

## Procedure Context
This is an intermediate dependency bump in the revm release flow before
downstream updates in `alloy-evm` and `reth`.

* chore: release 0.35.0

* chore: bump revm to 36.0.0 (paradigmxyz#409)

## Summary
- Bump `revm` dependency from 35.0.0 to 36.0.0

## Test plan
- [x] `cargo check` passes
- [x] `cargo test` passes (all 37 tests)

* chore: release 0.36.0

* fix: omit empty returnData in geth struct log trace (paradigmxyz#411)

## Summary

Only include `returnData` in structLog output when the return-data
buffer is non-empty, matching geth's behavior.

## Motivation

[ethpandaops trace comparison
report](https://investigations.ethpandaops.io/2026-01/trace-comparisons/reth/)
shows reth emitting `returnData: "0x"` on **every** structLog step
(~1.1M occurrences across 500 txs), while geth/erigon/nethermind/besu
all omit it.

Geth applies two independent gates before including `returnData`:
1. `cfg.EnableReturnData == true` (opt-in config) — we had this
2. `len(ReturnData) > 0` in `toLegacyJSON` — we were missing this

## Changes

- `src/tracing/builder/geth.rs`: add `!step.returndata.is_empty()` check
alongside the existing `opts.is_return_data_enabled()` gate

## Testing

`cargo test --workspace` — all 24 tests pass, clippy clean.

Co-Authored-By: Matthias Seitz
<19890894+mattsse@users.noreply.github.com>

Prompted by: mattsse

Co-authored-by: Matthias Seitz <19890894+mattsse@users.noreply.github.com>

* feat: add set_transaction_caller and set_transaction_target (paradigmxyz#412)

Adds `set_transaction_caller` and `set_transaction_target` to
`TracingInspector`, following the same pattern as
`set_transaction_gas_used` / `set_transaction_gas_limit`.

Custom transaction types (e.g. AA batches) may execute via a multi-call
handler where the EVM's `call()` entry point doesn't reflect the actual
transaction sender/recipient. This causes `callTracer` to report zeroed
`from`/`to` on the root frame. These methods allow the execution layer
to correct the root trace after execution.

Co-Authored-By: zhygis <5236121+Zygimantass@users.noreply.github.com>

Prompted by: zygis

---------

Co-authored-by: zhygis <5236121+Zygimantass@users.noreply.github.com>
Co-authored-by: Arsenii Kulikov <klkvrr@gmail.com>

* chore: release 0.36.1

* chore: relax `CTX` bounds on `StorageInspector` `Inspector` impl (paradigmxyz#416)

Relax `CTX` bounds on `StorageInspector` `Inspector` impl as it doesn't
use `Context`.

* fix: eip-7708 logs (paradigmxyz#413)

CallLog discarded the original Log.address during conversion and
geth_empty_call_frame() reconstructed it from execution_address(). This
is wrong for any log whose emitter differs from the call frame's
execution context — most notably EIP-7708 system-level ETH transfer
logs, which are emitted from SYSTEM_ADDRESS
(0xfffffffffffffffffffffffffffffffffffffffe) rather than the executing
contract.

Changes

src/tracing/types.rs
- Add address: Address field to CallLog to preserve the original log
emitter
- Update From<Log> to store log.address instead of discarding it
- Fix geth_empty_call_frame() to use log.address instead of
self.execution_address()

tests/it/geth.rs
- test_geth_calltracer_logs_eip7708: value-transferring CALL to a
precompile under AMSTERDAM — verifies the log address is
ETH_TRANSFER_LOG_ADDRESS, not the contract or precompile address
- test_geth_calltracer_logs_address_regular: regular LOG0 emission —
verifies the log address is the emitting contract
- test_geth_calltracer_logs_delegatecall: DELEGATECALL regression —
verifies the log address is the proxy (execution context), not the
implementation (bytecode) address

Breaking

CallLog is a public struct with a new address: Address field. Downstream
consumers that construct CallLog manually will need to provide this
field.

Co-authored-by: Kai Yu <kai.yu@Kai-Yu-MacBook-Pro.local>

* chore: bump alloy to 2.0 (paradigmxyz#421)

Bump alloy dependencies to released 2.0.0. No `[patch.crates-io]`
needed.

Supersedes paradigmxyz#419

* chore: release 0.37.0

* tip1016: revm state-gas integration (paradigmxyz#405)

## Summary
- Update revm rev to `e3223d5b38f7affb901601ed917fa7cdc466be74`
(rakita/state-gas branch) for TIP-1016 dual-limit gas accounting

## Test plan
- [x] `cargo check` compiles clean
- [x] `cargo +nightly clippy` passes
- [x] `cargo nextest run` — all 37 tests pass

---------

Co-authored-by: Federico Gimenez <federico.gimenez@gmail.com>

* chore: release 0.38.0

* fix: check if opcode is valid (paradigmxyz#422)

TracingInspector creates OpCodes via `new_unchecked` at `start_step` to
handle unknown/custom opcodes. In `step_end`, `step.op.outputs()` calls
`OpCode::info()` which panics with `"opcode not found"` when the opcode
byte has no entry in `OPCODE_INFO`.

Guard with `is_valid()` — unknown opcodes default to 0 outputs.

Prompted by: Dragan

---------

Co-authored-by: rakita <13179220+rakita@users.noreply.github.com>
Co-authored-by: rakita <rakita@users.noreply.github.com>

* chore: release 0.38.1

* fix(tracing): always include refund counter, wire enableReturnData config (paradigmxyz#424)

Two fixes based on the [ethpandaops trace
comparison](https://investigations.ethpandaops.io/2026-01/trace-comparisons/):

1. Always include the refund counter in struct logs, even when zero.
Previously omitted when value was 0, causing missing fields in trace
output.

2. Wire `enableReturnData` from `GethDefaultTracingOptions` through to
`TracingInspectorConfig::record_returndata_snapshots`. Previously this
option was ignored, so returnData was never captured even when
explicitly requested.

Verified on a live reth archive node:
- Refund: 22,476/67,028 steps → **67,028/67,028** steps
- returnData with `enableReturnData: true`: 0 steps → **24,537** steps

* fix(tracing): align memory encoding and returnData gating (paradigmxyz#425)

Two fixes to align with the [opcode tracer
spec](ethereum/execution-apis#762):

1. Memory chunks now use `0x`-prefixed `bytes32` encoding. Previously
`convert_memory()` used bare `hex::encode` without the prefix.

2. `returnData` is now included on every step when `enableReturnData` is
true, even when the buffer is empty. Previously skipped when empty.

---------

Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>

* chore: bump revm to 38.0.0 (paradigmxyz#427)

## Summary
- Bumps `revm` from `37.0.0` to `38.0.0`.

## Test plan
- [ ] `cargo build` passes
- [ ] `cargo test` passes
- [ ] CI green

* chore: release 0.39.0

* fix: use .values() instead of iter with unused key to satisfy clippy

* Revert "fix: use .values() instead of iter with unused key to satisfy clippy"

This reverts commit d7d6d46.

* Reapply "fix: use .values() instead of iter with unused key to satisfy clippy"

This reverts commit 43a426e.

---------

Co-authored-by: rakita <rakita@users.noreply.github.com>
Co-authored-by: zerosnacks <95942363+zerosnacks@users.noreply.github.com>
Co-authored-by: Arsenii Kulikov <klkvrr@gmail.com>
Co-authored-by: Karl Yu <43113774+0xKarl98@users.noreply.github.com>
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
Co-authored-by: Alex Pikme <30472093+reject-i@users.noreply.github.com>
Co-authored-by: DaniPopes <57450786+DaniPopes@users.noreply.github.com>
Co-authored-by: Wodann <Wodann@users.noreply.github.com>
Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: Philippe Dumonet <philippe@dumo.net>
Co-authored-by: stevencartavia <112043913+stevencartavia@users.noreply.github.com>
Co-authored-by: Derek Cofausper <256792747+decofe@users.noreply.github.com>
Co-authored-by: Matthias Seitz <19890894+mattsse@users.noreply.github.com>
Co-authored-by: zhygis <5236121+Zygimantass@users.noreply.github.com>
Co-authored-by: Mablr <59505383+mablr@users.noreply.github.com>
Co-authored-by: Kai Yu <kai.yu@circle.com>
Co-authored-by: Kai Yu <kai.yu@Kai-Yu-MacBook-Pro.local>
Co-authored-by: Federico Gimenez <federico.gimenez@gmail.com>
Co-authored-by: rakita <13179220+rakita@users.noreply.github.com>
Co-authored-by: figtracer <me@figtracer.com>
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.

1 participant