cosmos / cosmos/evm

[Bug] eth_createAccessList never traces the call and returns the input access list unchanged

Open
#1,282 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
164
Forks
215
Avg merge
3d 58m
Merged PRs (30d)
12

Description

## Type

- [x] Bug
- [ ] Feature
- [ ] Proposal / Discussion

## Summary

`eth_createAccessList` never traces the call. `createAccessList` runs the tx through `DoCall` (a plain `EthCall` gRPC query, no tracer attached) and then builds `newTracer` from the *input* access list, so `newTracer.Equal(prevTracer)` is true on the first iteration and the method returns whatever access list the caller passed in (empty by default). No SLOAD/SSTORE/EXT*/BALANCE/CALL target is ever recorded.

https://github.com/cosmos/evm/blob/469142db41aee479102cf878f8ac2bbe2b0c7a22/rpc/backend/tx_info.go#L480-L494

```go
for {
accessList := prevTracer.AccessList()
traceArgs.AccessList = &accessList
res, err := b.DoCall(ctx, *traceArgs, blockNum, overrides) // no tracer involved
...
newTracer := logger.NewAccessListTracer(accessList, addressesToExclude) // built from the input, not from execution
if newTracer.Equal(prevTracer) { // always true
return accessList, res.GasUsed, vmErr, nil
}
```

In go-ethereum the tracer is passed to the EVM via `vm.Config{Tracer: tracer.Hooks()}` and `tracer.Equal(prevTracer)` compares what was actually touched. Here nothing bridges the tracer to `ApplyMessageWithConfig`.

## Reproduction (for bugs)

`main` (`469142d`), `./local_node.sh -y`, dev account `0xc6fe5d33615a1c52c08018c47e8bc53646a0e101`.

1. Deploy a contract whose runtime is `PUSH20 0x1111…1111; BALANCE; STOP` (touches another account, which geth reports in the access list):

```
eth_sendTransaction {"from":"0xc6fe…e101","data":"0x6017600c60003960176000f37311111111111111111111111111111111111111113100","gas":"0x30000"}
-> deployed at 0xe2f81b30e1d47dffdbb6ab41ec5f0572705b026d
```

2. Ask for the access list:

```
eth_createAccessList [{"from":"0xc6fe…e101","to":"0xe2f81b30…026d","data":"0x"},"latest"]
-> {"accessList":[],"gasUsed":"0x5c33"}
```

geth returns `[{"address":"0x1111111111111111111111111111111111111111","storageKeys":[]}]` for the same call.

3. Pass a bogus list in; it comes back unchanged (and the call is even charged for it):

```
eth_createAccessList [{"from":…,"to":"0xe2f81b30…026d","data":"0x","accessList":[{"address":"0xdeaddeaddeaddeaddeaddeaddeaddeaddeaddead","storageKeys":["0x…01"]}]},"latest"]
-> {"accessList":[{"address":"0xdeaddeaddeaddeaddeaddeaddeaddeaddeaddead","storageKeys":["0x…01"]}],"gasUsed":"0x6cff"}
```

The unit test `TestCreateAccessList` only checks that a result is returned, so it does not catch this.

## Impact

The method has been a no-op since it was added (#346). Clients that rely on it to build EIP-2930 access lists (ethers `populateTransaction`, viem `prepareTransactionRequest` with `accessList`, MEV/simulation tooling) silently get an empty or unchanged list, so the "optimized" transactions never get the expected gas savings.

Fixing it needs the tracer to run inside the EVM: either an `EthCall`/`TraceCall` variant in `x/vm` that installs `logger.NewAccessListTracer(...).Hooks()` as `tracingHooks` in `ApplyMessageWithConfig` and returns the list, or deriving the list from a `prestateTracer` `debug_traceCall` (accounts + storage keys minus the exclude set). I can send a PR for either approach if you tell me which one you prefer.

## Related

- #346 (original implementation)

## Checklist

- [x] Linked to a GitHub Issue (or this is the Issue)
- [x] Repro steps included (for bugs)
- [x] Impact described
- [x] I understand minor typo/style doc fixes will not be accepted

Contributor guide

Open the contributing guide

Research direction

Start in rpc/backend/tx_info.go around createAccessList and run TestCreateAccessList, which currently checks only that a result is returned. Then inspect the x/vm call path, especially ApplyMessageWithConfig and the DoCall path, to determine how tracing hooks can reach execution. Done means eth_createAccessList reports the accounts and storage keys actually touched, rather than returning only the input list, with tests covering the reproduced BALANCE case.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
backend-api-design, blockchain
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.