Go-ethereum: Discrepency on eth_call rpc responses when the from field is omitted

Created on 17 Feb 2020  路  8Comments  路  Source: ethereum/go-ethereum

Hi there,

Please note that this is an issue tracker reserved for bug reports and feature requests.

For general questions please use the gitter channel or the Ethereum stack exchange at https://ethereum.stackexchange.com.

System information

Geth version: geth v1.9.10
OS & Version: Linux
Commit hash : 58cf568

Expected behaviour

JSON-RPC response to eth_call with and without the optional from field should be the same

Actual behaviour

An Infura user reported an issue with mismatched responses when omitting the from field. The issue was reported to ethers.js (https://github.com/ethers-io/ethers.js/issues/705) but we were able to reproduce the error on the Ropsten network using a curl request directly to a geth node.

Steps to reproduce the behaviour

The user reported accurate repro steps here: https://github.com/ethers-io/ethers.js/issues/705#issuecomment-583298472

Without a from field

curl -H "Accept: application/json" -X POST --data-raw '{"method":"eth_call","params":[{"to":"0xaf4c11A90e98D0C5ecFb403C62Cc8Dfe8DF11030","data":"0xb7a56985000000000000000000000000e2a8950bc498e19457be5bbe2c25bc1f535c743e000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"latest"],"id":43,"jsonrpc":"2.0"}' http://localhost:8545

With a from field

curl -H "Accept: application/json" -X POST --data-raw '{"method":"eth_call","params":[{"from":"0xe2a8950bc498e19457be5bbe2c25bc1f535c743e","to":"0xaf4c11A90e98D0C5ecFb403C62Cc8Dfe8DF11030","data":"0xb7a56985000000000000000000000000e2a8950bc498e19457be5bbe2c25bc1f535c743e000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"latest"],"id":43,"jsonrpc":"2.0"}' http://localhost:8545

The expected behavior is that these responses should be identical

Most helpful comment

Totally understand that the from field could make a difference. Based on that user's report on the linked ethers.js issue, the odd thing was that with and without the from field Geth and Parity seem to have diverging behavior here. Infura soley runs geth for mainnet, another provider Alchemy uses Parity. The reporter included a link to test against Alchemy:

 # Geth with from field
curl -H "Accept: application/json" -X POST --data-raw '{"method":"eth_call","params":[{"from":"0xe2a8950bc498e19457be5bbe2c25bc1f535c743e","to":"0xaf4c11A90e98D0C5ecFb403C62Cc8Dfe8DF11030","data":"0xb7a56985000000000000000000000000e2a8950bc498e19457be5bbe2c25bc1f535c743e000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"latest"],"id":43,"jsonrpc":"2.0"}' https://ropsten.infura.io/v3/7d0d81d0919f4f05b9ab6634be01ee73

{"jsonrpc":"2.0","id":43,"result":"0xfffffffffffffffffffffffffffffffffffffffffffffffffee3c828fc9f2bff"}                                                         

# Geth without from field
 curl -H "Accept: application/json" -X POST --data-raw '{"method":"eth_call","params":[{"to":"0xaf4c11A90e98D0C5ecFb403C62Cc8Dfe8DF11030","data":"0xb7a56985000000000000000000000000e2a8950bc498e19457be5bbe2c25bc1f535c743e000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"latest"],"id":43,"jsonrpc":"2.0"}' https://ropsten.infura.io/v3/7d0d81d0919f4f05b9ab6634be01ee73

{"jsonrpc":"2.0","id":43,"result":"0x000000000000000000000000000000000000000000000000128ad616fa50945f"}

# Parity with from field
curl -H "Accept: application/json" -X POST --data-raw '{"method":"eth_call","params":[{"from":"0xe2a8950bc498e19457be5bbe2c25bc1f535c743e","to":"0xaf4c11A90e98D0C5ecFb403C62Cc8Dfe8DF11030","data":"0xb7a56985000000000000000000000000e2a8950bc498e19457be5bbe2c25bc1f535c743e000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"latest"],"id":43,"jsonrpc":"2.0"}' https://eth-ropsten.alchemyapi.io/jsonrpc/_gg7wSSi0KMBsdKnGVfHDueq6xMB9EkC

{"jsonrpc": "2.0", "result": "0x000000000000000000000000000000000000000000000000128ad616fa50945f", "id": 43}                                               

# Parity without from field
curl -H "Accept: application/json" -X POST --data-raw '{"method":"eth_call","params":[{"to":"0xaf4c11A90e98D0C5ecFb403C62Cc8Dfe8DF11030","data":"0xb7a56985000000000000000000000000e2a8950bc498e19457be5bbe2c25bc1f535c743e000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"latest"],"id":43,"jsonrpc":"2.0"}' https://eth-ropsten.alchemyapi.io/jsonrpc/_gg7wSSi0KMBsdKnGVfHDueq6xMB9EkC

{"jsonrpc": "2.0", "result": "0x000000000000000000000000000000000000000000000000128ad616fa50945f", "id": 43}                                                                       

Maybe the issue is that Parity is providing the incorrect response here but I wasn't sure. Any insights would be helpful.

All 8 comments

I don't understand how you can expect them to be identical.聽The rpc endpoint simulates a call, and if the call depends on the tx origin, then whether "from" was supplied externally or not makes a difference.Either I misunderstood something, or this works as expected

Totally understand that the from field could make a difference. Based on that user's report on the linked ethers.js issue, the odd thing was that with and without the from field Geth and Parity seem to have diverging behavior here. Infura soley runs geth for mainnet, another provider Alchemy uses Parity. The reporter included a link to test against Alchemy:

 # Geth with from field
curl -H "Accept: application/json" -X POST --data-raw '{"method":"eth_call","params":[{"from":"0xe2a8950bc498e19457be5bbe2c25bc1f535c743e","to":"0xaf4c11A90e98D0C5ecFb403C62Cc8Dfe8DF11030","data":"0xb7a56985000000000000000000000000e2a8950bc498e19457be5bbe2c25bc1f535c743e000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"latest"],"id":43,"jsonrpc":"2.0"}' https://ropsten.infura.io/v3/7d0d81d0919f4f05b9ab6634be01ee73

{"jsonrpc":"2.0","id":43,"result":"0xfffffffffffffffffffffffffffffffffffffffffffffffffee3c828fc9f2bff"}                                                         

# Geth without from field
 curl -H "Accept: application/json" -X POST --data-raw '{"method":"eth_call","params":[{"to":"0xaf4c11A90e98D0C5ecFb403C62Cc8Dfe8DF11030","data":"0xb7a56985000000000000000000000000e2a8950bc498e19457be5bbe2c25bc1f535c743e000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"latest"],"id":43,"jsonrpc":"2.0"}' https://ropsten.infura.io/v3/7d0d81d0919f4f05b9ab6634be01ee73

{"jsonrpc":"2.0","id":43,"result":"0x000000000000000000000000000000000000000000000000128ad616fa50945f"}

# Parity with from field
curl -H "Accept: application/json" -X POST --data-raw '{"method":"eth_call","params":[{"from":"0xe2a8950bc498e19457be5bbe2c25bc1f535c743e","to":"0xaf4c11A90e98D0C5ecFb403C62Cc8Dfe8DF11030","data":"0xb7a56985000000000000000000000000e2a8950bc498e19457be5bbe2c25bc1f535c743e000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"latest"],"id":43,"jsonrpc":"2.0"}' https://eth-ropsten.alchemyapi.io/jsonrpc/_gg7wSSi0KMBsdKnGVfHDueq6xMB9EkC

{"jsonrpc": "2.0", "result": "0x000000000000000000000000000000000000000000000000128ad616fa50945f", "id": 43}                                               

# Parity without from field
curl -H "Accept: application/json" -X POST --data-raw '{"method":"eth_call","params":[{"to":"0xaf4c11A90e98D0C5ecFb403C62Cc8Dfe8DF11030","data":"0xb7a56985000000000000000000000000e2a8950bc498e19457be5bbe2c25bc1f535c743e000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"},"latest"],"id":43,"jsonrpc":"2.0"}' https://eth-ropsten.alchemyapi.io/jsonrpc/_gg7wSSi0KMBsdKnGVfHDueq6xMB9EkC

{"jsonrpc": "2.0", "result": "0x000000000000000000000000000000000000000000000000128ad616fa50945f", "id": 43}                                                                       

Maybe the issue is that Parity is providing the incorrect response here but I wasn't sure. Any insights would be helpful.

So, if not given a from, geth will try to use the "first" local account. If there are no local accounts on the node where this executes, it will use 0x00..0 as from. I'm not sure what parity uses, but in general, this means that even across two geth-nodes you're not guaranteed to get the same behaviour.

I don't know what the "best" default is here.

I think we should remove this implicit "first local account" behavior. Two reasons: local accounts can be different on every machine, and it's the only reason why we depend on accounts from the API implementation.

Parity uses null account address by default, which is the saner choice.

@egalano test again with the new version go geth 2.2.1

We're a bit tied here. My preference would be to make the from mandatory, in the API-call. @fjl would rather just set it to 0x00..0 if not supplied.

I think using 0x0..0 is a bad idea, since that particular address is quirky and special. Zeroes means that something is not set, and can have strange side-effects on executions. It's also used as a burn-address, and has huge amounts of ether and tokens on it.

If we make it mandatory, web3-providers and libraries can always choose to allow the user to have it optional, but then the libraries would have to provide the default themselves.

Putting this out there -- opinions?

I would go with using 0x00 as the default to match parity's behavior. The only thing I might be concerned about would be if someone were already expecting the first local account behavior. What ability would that person have to revert to the previous behavior after this next release. Maybe we start with enabling this new behavior via a cli flag and then making it the default after a set period of time? It probably isn't necessary to go to that length to keep this backwards compatible but we really won't know until someone files a ticket.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

362228416 picture 362228416  路  3Comments

VoR0220 picture VoR0220  路  3Comments

phpsamsb picture phpsamsb  路  3Comments

vogelito picture vogelito  路  3Comments

ysqi picture ysqi  路  3Comments