ledgerwatch / erigon

Ethereum implementation on the efficiency frontier
GNU Lesser General Public License v3.0
3.03k stars 1.05k forks source link

Fix gas fee calculation for debug calls #10825

Closed mininny closed 5 days ago

mininny commented 1 week ago

Hi guys, we had an issue come up on our fork of erigon regarding some gas fee calculation: https://github.com/testinprod-io/op-erigon/issues/183

We thought this would apply to upstream erigon as well, so brought the changes here too.

I'd appreciate any feedbacks or concerns for this 😄

Problem

This PR fixes gas fee calculation for rpc calls. It mostly borrows changes from geth and resolves previous issues.

curl "https://localhost:8545 " -X POST -H "Content-Type: application/json" -d  ' {"jsonrpc": "2.0", "id": "1", "method": "eth_estimateGas", "params": [{"from": "0xa5B8492D8223D255dB279C7c3ebdA34Be5eC9D85","data": "0x00", "to": "0xa5B8492D8223D255dB279C7c3ebdA34Be5eC9D85" }, "pending"]}'   

Results in:

"code":-32000,"message":"insufficient funds for gas * price + value: address 0xa5B8492D8223D255dB279C7c3ebdA34Be5eC9D85 have 0 want 56956314575938201239799312"

Instead, it should return a valid RPC response.

Detail

Currently, erigon sets the gasFeeCap to header's baseFee by default. Setting gasFeeCap to baseFee will prevent calling eth_estimateGas with 0-balance accounts because the account's balance has to be bigger than the baseFee.

However, in practice, many debug calls and estimateGas calls are called on 0-balance accounts, and without any gas-related fields set. Previous version of erigon and Geth allowed debug calls to be called on 0-balance accounts without setting gas parameters, so this PR attempts to bring back such behavior.

Solution

There is evm.Config().NoBaseFee which is used to signify that base fee is not required for this evm call. When this field is set AND gasPrice is not assigned, we set the block context's baseFee to 0. Because the baseFee is configured to 0 for these debug rpc calls, the feeCap will be always bigger than baseFee which passes the eip1599 validation. Also, 0-account balances will be able to call rpcs since the required gasFee is 0.

This allows any debug calls without explicit gasPrice to also ignore the baseFee when calculating account balance/eip1559 check/etc.

Also, currently, NoBaseFee is set to true for calls like estimateGas/createAccessList/eth_call, but not for debug_traceCall. This PR also sets NoBaseFee to true for debug_traceCall so that they can also ignore the base fee rule when needed.

This PR from geth addresses similar concern: https://github.com/ethereum/go-ethereum/pull/23027