Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Anvil's gas response for trace_debugTransaction is inconsistent with geth's responses for tracer 'callTracer' #6873

Closed
2 tasks
prasincs opened this issue Jan 22, 2024 · 2 comments
Assignees
Labels
T-bug Type: bug

Comments

@prasincs
Copy link

prasincs commented Jan 22, 2024

Component

Anvil

Have you ensured that all of these are up to date?

  • Foundry
  • Foundryup

What version of Foundry are you on?

forge 0.2.0 (03f5a95 2024-01-17T16:52:30.332226795Z)

What command(s) is the bug in?

anvil

Operating System

Linux

Describe the bug

The original behavior here is inconsistent with geth. To validate this - I ran geth devnet and ran two curl commands after making a trivial transfer in geth console

eth.sendTransaction({from: eth.coinbase, to: "0xb26Dc5174FFBeDD212247f258F53d16A1FECa444", value: web3.toWei(5, "ether")})
"0xe75c4a7d51af886595c16d531f11d71675d73deca3b81a41b235f20c63c0bcac"

When you call debug_traceTransaction without any additional params, note that the gas is in uint64 without hex encoding

curl -H "Content-Type: application/json" --data '{"method":"debug_traceTransaction","params":["0xe75c4a7d51af886595c16d531f11d71675d73deca3b81a41b235f20c63c0bcac"], "id":1,"jsonrpc":"2.0"}' http://localhost:8545

returns

{"jsonrpc":"2.0","id":1,"result":{"gas":21000,"failed":false,"returnValue":"","structLogs":[]}}

However, when you call with calltracer, gas is in hex

curl -H "Content-Type: application/json" --data '{"method":"debug_traceTransaction","params":["0xe75c4a7d51af886595c16d531f11d71675d73deca3b81a41b235f20c63c0bcac", {"tracer": "callTracer"}], "id":1,"jsonrpc":"2.0"}' http://localhost:8545
{"jsonrpc":"2.0","id":1,"result":{"from":"0x6bf51811c63eba59c232a07bd89c37016ad2620f","gas":"0x5208","gasUsed":"0x5208","to":"0xb26dc5174ffbedd212247f258f53d16a1feca444","input":"0x","value":"0x4563918244f40000","type":"CALL"}}

However, when you use anvil (and I'll jump to mainnet impersonation test described in https://book.getfoundry.sh/tutorials/forking-mainnet-with-cast-anvil)
the instructions have gotten slightly outdated as the $LUCKY_USER has drained their $DAI, but we can still use the old block

anvil --fork-url https://mainnet.infura.io/v3/$INFURA_KEY@19013589

in another window

export ALICE=0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266
export DAI=0x6b175474e89094c44da98b954eedeac495271d0f
export LUCKY_USER=0xad0135af20fa82e106607257143d0060a7eb5cbf
cast rpc anvil_impersonateAccount $LUCKY_USER
cast send $DAI \
—unlocked \
--from $LUCKY_USER \
  "transfer(address,uint256)(bool)" \
  $ALICE \
  300000000000000000000000

returns

blockHash               0xa71fa8906bcc76873601589c94e7e54296633147eed17a49c3660602e9c88f8e
blockNumber             19013590
contractAddress
cumulativeGasUsed       47030
effectiveGasPrice       26422153696
gasUsed                 47030
logs                    [{"address":"0x6b175474e89094c44da98b954eedeac495271d0f","topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef","0x000000000000000000000000ad0135af20fa82e106607257143d0060a7eb5cbf","0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266"],"data":"0x000000000000000000000000000000000000000000003f870857a3e0e3800000","blockHash":"0xa71fa8906bcc76873601589c94e7e54296633147eed17a49c3660602e9c88f8e","blockNumber":"0x1221fd6","transactionHash":"0xd4d6860b4e84f876ad942ae68de859789cc56e8cbc22ec90df88cd3a9b2aee7d","transactionIndex":"0x0","logIndex":"0x0","removed":false}]
logsBloom               0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800800000000000000000000000000000000000001000000000000000000000010000000000000000000000004000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000020000000000000000000000200200000000000000000000

so far good..

Now if I trace this transaction, I get gas as a number - good.

curl -H "Content-Type: application/json" --data '{"method":"debug_traceTransaction","params": ["0xd4d6860b4e84f876ad942ae68de859789cc56e8cbc22ec90df88cd3a9b2aee7d"], "id":1,"jsonrpc":"2.0"}' http://localhost:8545
{"jsonrpc":"2.0","id":1,"result":{"failed":false,"gas":47030,"returnValue":"0000000000000000000000000000000000000000000000000000000000000001","structLogs":[]}}

However with callTracer it's still a number and not in hex

curl -H "Content-Type: application/json" --data '{"method":"debug_traceTransaction","params": ["0xd4d6860b4e84f876ad942ae68de859789cc56e8cbc22ec90df88cd3a9b2aee7d", {"tracer": "callTracer"}], "id":1,"jsonrpc":"2.0"}' http://localhost:8545
{"jsonrpc":"2.0","id":1,"result":{"failed":false,"gas":47030,"returnValue":"0000000000000000000000000000000000000000000000000000000000000001","structLogs":[]}}

This means any Go RPC Clients using the go-ethereum hexutil.Big or hexutil.Uint64 will fail because they expect the numbers to be in hex. This means that ansible cannot be used as a drop in replacement for clients using geth currently without also changing the type for gas to accept both int and hex string.
I'm aware this is a quirk of geth and perhaps related to the calltracer being a javascript function, but if the goal is to make anvil drop in replacement for geth for development, it'd be good to replicate the behavior geth has. I'd love to fix geth upstream too but I'm not sure if the breakage for clients relying on this behavior is worth it.

@prasincs prasincs added the T-bug Type: bug label Jan 22, 2024
@gakonst gakonst added this to Foundry Jan 22, 2024
@github-project-automation github-project-automation bot moved this to Todo in Foundry Jan 22, 2024
@mattsse mattsse self-assigned this Jan 22, 2024
@mattsse
Copy link
Member

mattsse commented Jan 22, 2024

thanks for flagging!

we likely just need to change how these are serialized

@mattsse
Copy link
Member

mattsse commented Jan 22, 2024

okay, this is actually not related to the calltracer, it's just that the call tracer isn't properly handled atm

the fields of the callframe are hex:

https://github.com/alloy-rs/alloy/blob/2ee7b8b2821294f0661b2588e1fd7fcd2640adc0/crates/rpc-trace-types/src/geth/call.rs#L12-L17

I'm closing this one, and opening an issue to add calltracer support

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-bug Type: bug
Projects
Archived in project
Development

No branches or pull requests

2 participants