Skip to content

Incorrect gas estimation when high gas limit is needed to execute the transaction but not used #9061

@fedgiac

Description

@fedgiac

Description

Consider the following contract:

contract GasCraver {
    bool public stateChanged = false;

    function foo() external {
        if (gasleft() < 1_000_000) {
            revert("I want more gas");
        }
        stateChanged = true;
    }
}

foo() can be called without reverting if using a gas limit larger than ~1M, but the executed transaction only consumes ~45k gas.
When calling eth_estimateGas on Nethermind I see an estimation of ~45k, which would cause the call to revert.
According to the specs for eth_estimateGas, I instead expect it to return how much gas is necessary to allow the transaction to complete, which would be a bit more than 1M gas in this case.

Steps to Reproduce

There's a deployed version of this contract for testing at address 0xbFcbE82a626ed578B66e80DD72825a9d524357cd on Gnosis.
Calling eth_estimateGas on Nethermind/v1.32.2+d3e7eb98/linux-x64/dotnet9.0.6 returns 43702.
Using another node, like Erigon, returns a more reasonable result of 1021181.

Trying the same on Sepolia (0xc1ea023E38c3d3472ae688C24131BcBc805C1164) returns 1029663 with Reth and 1031376 with Geth. I don't have access to a Nethermind node on Sepolia to see if it's a Gnosis issue.

You can try out this call with custom node URLs by editing the following script.

Helper script for testing
#!/bin/bash

set -o errexit -o nounset -o pipefail

rpc_id=0

rpc() {
  local node=$1
  local method=$2
  local params=$3
  rpc_id=$(("$rpc_id" + 1))
  curl \
    --silent \
    -X POST \
    -H "Content-Type: application/json" \
    --max-time 15 \
    "$node" \
    --data "{\"method\":\"$method\",\"params\":$params,\"id\":$rpc_id,\"jsonrpc\":\"2.0\"}"
}

get_node_version() {
  local node=$1
  rpc "$node" web3_clientVersion '[]' | jq --raw-output '.result'
}

get_estimation() {
  local node=$1
  local gas_craver=$2
  local address_with_eth='0x5112D584a1C72Fc250176B57aEba5fFbbB287D8F'
  rpc "$node" "eth_estimateGas" "[{\
\"from\":\"$address_with_eth\",\
\"to\":\"$gas_craver\",\
\"data\":\"0xc2985578\"
}]" \
  | jq --raw-output '.result'
}

gas_craver='0xbFcbE82a626ed578B66e80DD72825a9d524357cd'

echo "Testing contract $gas_craver."
for node in \
'https://rpc.gnosis.gateway.fm' \
'https://gnosis-mainnet.public.blastapi.io' \
; do
  echo "> Using RPC $node..."
  version=$(get_node_version "$node")
  estimation=$(get_estimation "$node" "$gas_craver")
  echo "$((16#${estimation##0x})) with version $version"
done

Output:

Testing contract 0x6e8E85BC6FF7925533Ad7c19E4b9f0d167A95157.
> Using RPC https://rpc.gnosis.gateway.fm...
43702 with version Nethermind/v1.32.2+d3e7eb98/linux-x64/dotnet9.0.6
> Using RPC https://gnosis-mainnet.public.blastapi.io...
1021181 with version erigon/3.0.11/linux-amd64/go1.23.6

Same script but using Sepolia and different nodes:

Testing contract 0xc1ea023E38c3d3472ae688C24131BcBc805C1164.
> Using RPC https://eth-sepolia.public.blastapi.io...
1029663 with version reth/v1.6.0-d8451e5/x86_64-unknown-linux-gnu
> Using RPC https://ethereum-sepolia-rpc.publicnode.com...
1031376 with version Geth/v1.15.11-stable-36b2371c/linux-amd64/go1.23.10

Actual behavior

Estimate from eth_estimateGas causes subsequent call to revert.

Expected behavior

A much higher estimate should be returned by eth_estimateGas.

Desktop (please complete the following information):

I didn't run this test locally but I tested with all free RPCs from Chainlist and used web3_clientVersion to narrow down the issue to Nethermind nodes. Note that sometimes some RPCs on Gnosis use both Nethermind and Erigon in parallel, which could give misleading results in this test.
Affected versions include:

  • Nethermind/v1.32.2+d3e7eb98/linux-x64/dotnet9.0.6
  • Nethermind/v1.31.11+2be1890e/linux-x64/dotnet9.0.5
  • Nethermind/v1.31.8+8fca47e8/linux-x64/dotnet9.0.4

Metadata

Metadata

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions