I am aware that eth_estimateGas
is not intended to be exact,
but currently, I'm getting actual gasUsed
values
that are approximately 6% of the value returned by eth_estimateGas
.
In the following example, I invoke the same smart contract with the exact same inputs twice, with only 1 difference:
- In the 1st invocation,
gasLimit = eth_estimateGas
- In the 2nd invocation,
gasLimit = eth_estimateGas * 0.064
- This value is a very small fraction of the estimate
- This value was obtained through trial-and-error ... not through any calculations
// with exact estimated amount of gas
const estimatedGas2 = (await expendGasSc.estimateGas.updateState(1_000_000_123n)).toBigInt();
console.log('estimatedGas2', estimatedGas2);
const gasLimit2 = estimatedGas2 * 1n;
console.log('gasLimit2', gasLimit2);
const txResponse2 = await (await expendGasSc
.updateState(
1_000_000_123n,
{ gasLimit: gasLimit2 },
))
.wait();
const gasUsed2 = txResponse2.gasUsed.toBigInt();
console.log('gasUsed2', gasUsed2);
// with small fraction of estimated amount of gas
const estimatedGas4 = (await expendGasSc.estimateGas.updateState(1_000_000_123n)).toBigInt();
console.log('estimatedGas4', estimatedGas4);
const gasLimit4 = estimatedGas4 * 64n / 1000n; // <--- 6.4%
console.log('gasLimit4', gasLimit4);
const txResponse4 = await (await expendGasSc
.updateState(
1_000_000_123n,
{ gasLimit: gasLimit4 },
))
.wait();
console.log('txResponse4', txResponse4);
const gasUsed4 = txResponse4.gasUsed.toBigInt();
console.log('gasUsed4', gasUsed4);
Here are the results:
- When
gasLimit
is 400,000,gasUsed
is 320,000- This is exactly 80% of the specified
gasLimit
, indicating that HIP-185's gas over-reservation penalty *is likely to have kicked in. - See this answer to my previous related question for context.
- This is exactly 80% of the specified
- When
gasLimit
is 25,600,gasUsed
is 23,816- This is greater than 80% of the specified
gasLimit
, indicating that HIP-185's gas over-reservation penalty has not kicked in
- This is greater than 80% of the specified
estimatedGas2 400000n
gasLimit2 400000n
gasUsed2 320000n
estimatedGas4 400000n
gasLimit4 25600n
gasUsed4 23816n
Therefore, I am expecting eth_estimateGas
to return a value
that is much closer to 23,816 than 400,000.
Why is it returning such an unexpectedly high estimate
compared to the actual?
Here's the smart contract:
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.18;
contract ExpendSomeGasDemo {
uint256 public state;
function updateState(
uint256 newState
)
public
returns (uint256 updatedState)
{
state = newState;
updatedState = newState;
}
}
Note that this contract is deployed on Hedera Testnet:
0x9C58D0159495F7a8853A24574f2B8F348a72424c
Note that the Javascript example above is using ethers.js.
Note that this question is a follow up to my previous one:
Large discrepancy in gasUsed
values in near-identical transactions on Hedera - why?