Skip to content

Conversation

@m-Peter
Copy link
Collaborator

@m-Peter m-Peter commented Sep 10, 2025

Closes: #791

Description

Just like eth_call, eth_estimateGas also includes support for overriding certain block header fields.
This was added in Geth, as part of ethereum/go-ethereum#30695 .


For contributor use:

  • Targeted PR against master branch
  • Linked to Github issue with discussion and accepted design OR link to spec that describes this work.
  • Code follows the standards mentioned here.
  • Updated relevant documentation
  • Re-reviewed Files changed in the Github PR explorer
  • Added appropriate labels

Summary by CodeRabbit

  • New Features

    • Added support for block-level overrides in gas estimation and call simulations (block number, timestamp, randomness, coinbase). Existing behavior and error handling remain when overrides are not provided.
  • Tests

    • Added end-to-end tests and fixtures validating gas estimation with and without block overrides, exercising multiple block attributes and confirming response structure and values.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 10, 2025

Walkthrough

Adds blockOverrides support to eth_estimateGas by updating API and requester/EVM signatures to accept and forward block-level overrides into the EVM dry-run path, and adds e2e Web3.js tests and fixtures validating gas estimates with various block overrides.

Changes

Cohort / File(s) Summary
API: EstimateGas signature update
api/api.go
Adds blockOverrides *ethTypes.BlockOverrides parameter to BlockChainAPI.EstimateGas and forwards it to b.evm.EstimateGas.
Requester/EVM plumbing
services/requester/requester.go
Extends Requester interface and EVM methods: Call and EstimateGas now accept blockOverrides and pass them through to existing dry-run logic.
E2E test harness
tests/e2e_web3js_test.go
Adds subtest "test gas estimation block overrides" to run new fixture in TestWeb3_E2E.
Web3.js test & fixtures
tests/web3js/estimate_gas_overrides_test.js, tests/fixtures/blockOverrides.sol, tests/fixtures/blockOverridesABI.json, tests/fixtures/blockOverrides.byte
New JS test exercising eth_estimateGas with/without block overrides; adds Solidity fixture, ABI, and compiled bytecode used by the test.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant API as BlockChainAPI
  participant Requester as Requester/EVM
  participant EVM as dryRunTx

  Note over Client,API: eth_estimateGas (may include blockOverrides)
  Client->>API: EstimateGas(ctx, txArgs, blockNumOrHash, stateOverrides, blockOverrides)
  API->>Requester: EstimateGas(txArgs, from, height, stateOverrides, blockOverrides)
  Requester->>EVM: dryRunTx(..., stateOverrides, blockOverrides)
  EVM-->>Requester: gasUsed
  Requester-->>API: gasUsed
  API-->>Client: hex gasUsed

  Note right of EVM: Block view assembled with overrides\n(number, timestamp, prevrandao, coinbase)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • peterargue
  • zhangchiqing
  • janezpodhostnik

Pre-merge checks (5 passed)

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "Apply block overrides in eth_estimateGas JSON-RPC endpoint" accurately describes the main change in the changeset. The PR adds block override parameter support to the EstimateGas method across multiple files (api/api.go and services/requester/requester.go), updates method signatures to include blockOverrides parameters, and adds comprehensive tests to validate the new functionality. The title is clear, specific, and directly relates to the core objective of extending eth_estimateGas to support block header overrides.
Linked Issues Check ✅ Passed The code changes fully meet the requirements specified in linked issue #791. The objective was to extend eth_estimateGas to accept and apply block overrides like eth_call, matching Geth v1.15.0 behavior. The implementation adds blockOverrides parameters to EstimateGas method signatures in both BlockChainAPI and Requester interface, updates the internal EVM calls to pass through block overrides, and includes comprehensive tests that validate the functionality with various block header override scenarios (number, timestamp, prevrandao, coinbase).
Out of Scope Changes Check ✅ Passed All changes in the pull request are directly related to the objective of adding block override support to eth_estimateGas. The modifications include updating method signatures to accept blockOverrides parameters, threading them through the call chain, and adding comprehensive test fixtures and test cases. The new test files (blockOverrides.sol, blockOverrides.byte, blockOverridesABI.json, estimate_gas_overrides_test.js) are necessary to validate the new functionality and ensure it works correctly with various block header overrides.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

Poem

I twitch my whiskers, tap the chain,
I tweak the block — no bug, no pain.
Number, time, and rand I coax,
Gas wakes up and spares its jokes.
A rabbit helper, hopping light, tests pass by moonlight.

✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch mpeter/estimate-gas-with-block-overrides

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
services/requester/requester.go (1)

346-351: Cap by overridden block gas limit and fix underflow in failingGasLimit

  • If blockOverrides.GasLimit is set, passingGasLimit should be capped by it to match geth semantics; otherwise the first dryRun can exceed the overridden block limit.
  • failingGasLimit = result.GasConsumed - 1 underflows when GasConsumed == 0.

Apply this diff:

   // Determine the highest gas limit that can be used during the estimation.
   passingGasLimit = blockGasLimit
   if txArgs.Gas != nil && (uint64(*txArgs.Gas) >= gethParams.TxGas) {
     passingGasLimit = uint64(*txArgs.Gas)
   }
+  // Cap by overridden block gas limit if provided
+  if blockOverrides != nil && blockOverrides.GasLimit != nil {
+    if uint64(*blockOverrides.GasLimit) < passingGasLimit {
+      passingGasLimit = uint64(*blockOverrides.GasLimit)
+    }
+  }
@@
-  failingGasLimit = result.GasConsumed - 1
+  if result.GasConsumed > 0 {
+    failingGasLimit = result.GasConsumed - 1
+  } else {
+    failingGasLimit = 0
+  }

Also applies to: 376-376

🧹 Nitpick comments (4)
services/requester/requester.go (1)

337-345: Minor robustness nits in estimator loop

  • Consider clamping optimisticGasLimit to passingGasLimit before calling dryRun to avoid redundant high-gas calls when caps are tight.
  • In the bisection step, if mid > passingGasLimit due to arithmetic, clamp mid to passingGasLimit.

These are defensive and won’t change outcomes in nominal cases.

Also applies to: 381-394, 405-419

tests/web3js/estimate_gas_overrides_test.js (3)

39-39: Fix Number vs BigInt comparisons for stability

web3.utils.hexToNumber returns a Number, but expectations use BigInt literals (…n). Compare BigInt-to-BigInt to avoid surprises.

Apply this diff:

-    assert.equal(web3.utils.hexToNumber(response.body.result), 21651n)
+    assert.strictEqual(BigInt(response.body.result), 21651n)
@@
-    assert.equal(web3.utils.hexToNumber(response.body.result), 21651n)
+    assert.strictEqual(BigInt(response.body.result), 21651n)
@@
-    assert.equal(web3.utils.hexToNumber(response.body.result), 21607n)
+    assert.strictEqual(BigInt(response.body.result), 21607n)
@@
-    assert.equal(web3.utils.hexToNumber(response.body.result), 21607n)
+    assert.strictEqual(BigInt(response.body.result), 21607n)
@@
-    assert.equal(web3.utils.hexToNumber(response.body.result), 21584n)
+    assert.strictEqual(BigInt(response.body.result), 21584n)

Also applies to: 48-48, 60-60, 69-69, 90-90


22-49: Reduce brittleness: assert invariance/difference rather than exact gas values

Exact gas values (21651, 21607, 21584) can drift with EVM changes. Prefer asserting:

  • block.number/time overrides do not affect gas (equal before/after).
  • prevrandao override may affect gas (different before/after).

I can propose a patch if you want to switch to relational assertions.

Also applies to: 50-70, 71-91


22-49: Add a test for blockOverrides.gasLimit capping

Once EstimateGas caps by overridden GasLimit, add a case that sets a low gasLimit override and asserts estimatedGas <= that cap (or appropriate failure). This guards the intended semantics.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a55163d and 73dab2a.

📒 Files selected for processing (4)
  • api/api.go (2 hunks)
  • services/requester/requester.go (2 hunks)
  • tests/e2e_web3js_test.go (1 hunks)
  • tests/web3js/estimate_gas_overrides_test.js (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
tests/e2e_web3js_test.go (1)
bootstrap/bootstrap.go (1)
  • Run (707-723)
api/api.go (1)
eth/types/types.go (1)
  • BlockOverrides (450-459)
services/requester/requester.go (1)
eth/types/types.go (1)
  • BlockOverrides (450-459)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Test
🔇 Additional comments (6)
services/requester/requester.go (3)

66-72: Plumbing blockOverrides through Call: LGTM

The additional blockOverrides parameter is correctly threaded into Call and passed down to the dry-run path.


76-83: Add blockOverrides to EstimateGas: LGTM

Signature and interface update look consistent with the Call path and API layer.


324-333: Ensure dry-run honors block overrides in gas estimation

Passing blockOverrides into dryRunTx is correct and aligns EstimateGas with eth_call behavior.

api/api.go (2)

696-697: Expose blockOverrides in eth_estimateGas: LGTM

API surface matches geth v1.15.0 calling convention.


727-733: Forward blockOverrides to backend: LGTM

Correctly forwards overrides to the requester’s EstimateGas.

tests/e2e_web3js_test.go (1)

49-51: Good coverage: adds an end-to-end estimateGas override test

Placement in the suite and wiring via runWeb3Test look good.

@m-Peter m-Peter force-pushed the mpeter/estimate-gas-with-block-overrides branch from 73dab2a to 3ef41ff Compare September 12, 2025 09:13
@m-Peter m-Peter merged commit ac1bbac into main Sep 12, 2025
2 checks passed
@m-Peter m-Peter deleted the mpeter/estimate-gas-with-block-overrides branch September 12, 2025 09:19
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
tests/fixtures/blockOverrides.sol (2)

24-26: Make the address type explicit in the coinbase comparison.

Avoid relying on implicit conversions; compare against an address(...).

-        if (block.coinbase == 0x658Bdf435d810C91414eC09147DAA6DB62406379) {
+        if (block.coinbase == address(0x658Bdf435d810C91414eC09147DAA6DB62406379)) {

8-11: Fix typo in comment.

"overrided" → "overridden".

-        // overrided, resulting in higher gas usage.
+        // overridden, resulting in higher gas usage.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 73dab2a and 3ef41ff.

📒 Files selected for processing (7)
  • api/api.go (2 hunks)
  • services/requester/requester.go (2 hunks)
  • tests/e2e_web3js_test.go (1 hunks)
  • tests/fixtures/blockOverrides.byte (1 hunks)
  • tests/fixtures/blockOverrides.sol (1 hunks)
  • tests/fixtures/blockOverridesABI.json (1 hunks)
  • tests/web3js/estimate_gas_overrides_test.js (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • tests/fixtures/blockOverrides.byte
  • tests/fixtures/blockOverridesABI.json
🚧 Files skipped from review as they are similar to previous changes (3)
  • tests/e2e_web3js_test.go
  • api/api.go
  • services/requester/requester.go
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Test
🔇 Additional comments (1)
tests/web3js/estimate_gas_overrides_test.js (1)

41-45: Sanity-check field names match Geth’s block override schema.

Keys look correct (number, time, random, coinbase). Keep as-is; just noting for future maintainers.

If you want, I can add a follow-up test that sets multiple overrides at once to validate additive gas effects.

Also applies to: 59-63, 77-82, 96-100

@@ -0,0 +1,36 @@
// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.8.2 <0.9.0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Bump pragma to ensure block.prevrandao exists (>=0.8.18).

block.prevrandao wasn’t available before 0.8.18; the current range allows compilers that will fail. Tighten the lower bound.

-pragma solidity >=0.8.2 <0.9.0;
+pragma solidity >=0.8.18 <0.9.0;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
pragma solidity >=0.8.2 <0.9.0;
pragma solidity >=0.8.18 <0.9.0;
🤖 Prompt for AI Agents
In tests/fixtures/blockOverrides.sol around line 3, the pragma range allows
compilers older than 0.8.18 which lack block.prevrandao; update the pragma to
require at least 0.8.18 by changing the lower bound from 0.8.2 to 0.8.18 (i.e.,
make the pragma read "pragma solidity >=0.8.18 <0.9.0;") so the contract is
compiled with a version that supports block.prevrandao.

Comment on lines +33 to +104
let response = await helpers.callRPCMethod(
'eth_estimateGas',
[txArgs, 'latest', null, null]
)
assert.equal(response.status, 200)
assert.isDefined(response.body)
assert.equal(web3.utils.hexToNumber(response.body.result), 21473n)

// Override the `block.number` value to `9090`.
response = await helpers.callRPCMethod(
'eth_estimateGas',
[txArgs, 'latest', null, { number: '0x2382' }]
)
assert.equal(response.status, 200)
assert.isDefined(response.body)
assert.equal(web3.utils.hexToNumber(response.body.result), 273693n)

// Check the `block.timestamp` value, without overrides
response = await helpers.callRPCMethod(
'eth_estimateGas',
[txArgs, 'latest', null, null]
)
assert.equal(response.status, 200)
assert.isDefined(response.body)
assert.equal(web3.utils.hexToNumber(response.body.result), 21473n)

// Override the `block.timestamp` value to `0x674DB1E1`.
response = await helpers.callRPCMethod(
'eth_estimateGas',
[txArgs, 'latest', null, { time: '0x674DB1E1' }]
)
assert.equal(response.status, 200)
assert.isDefined(response.body)
assert.equal(web3.utils.hexToNumber(response.body.result), 273693n)

// Check the `block.prevrandao` value, without overrides
response = await helpers.callRPCMethod(
'eth_estimateGas',
[txArgs, 'latest', null, null]
)
assert.equal(response.status, 200)
assert.isDefined(response.body)
assert.equal(web3.utils.hexToNumber(response.body.result), 21473n)

// Override the `block.prevrandao` value to `0x7914bb5b13bac6f621bc37bbf6e406fbf4472aaaaf17ec2f309a92aca4e27fc0`.
let random = '0x7914bb5b13bac6f621bc37bbf6e406fbf4472aaaaf17ec2f309a92aca4e27fc0'
response = await helpers.callRPCMethod(
'eth_estimateGas',
[txArgs, 'latest', null, { random: random }]
)
assert.equal(response.status, 200)
assert.isDefined(response.body)
assert.equal(web3.utils.hexToNumber(response.body.result), 273693n)

// Check the `block.coinbase` value, without overrides
response = await helpers.callRPCMethod(
'eth_estimateGas',
[txArgs, 'latest', null, null]
)
assert.equal(response.status, 200)
assert.isDefined(response.body)
assert.equal(web3.utils.hexToNumber(response.body.result), 21473n)

// Override the `block.coinbase` value to `0x658Bdf435d810C91414eC09147DAA6DB62406379`.
response = await helpers.callRPCMethod(
'eth_estimateGas',
[txArgs, 'latest', null, { coinbase: '0x658Bdf435d810C91414eC09147DAA6DB62406379' }]
)
assert.equal(response.status, 200)
assert.isDefined(response.body)
assert.equal(web3.utils.hexToNumber(response.body.result), 273693n)
})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Avoid brittle exact gas assertions; compare against baseline and parse as BigInt.

Exact gas varies by solc/EVM settings. Capture baseline once and assert overrides increase it. Also use hexToNumberString + BigInt to avoid 53-bit issues.

-    let response = await helpers.callRPCMethod(
+    let response = await helpers.callRPCMethod(
         'eth_estimateGas',
         [txArgs, 'latest', null, null]
     )
     assert.equal(response.status, 200)
     assert.isDefined(response.body)
-    assert.equal(web3.utils.hexToNumber(response.body.result), 21473n)
+    const baselineGas = BigInt(web3.utils.hexToNumberString(response.body.result))

     // Override the `block.number` value to `9090`.
     response = await helpers.callRPCMethod(
         'eth_estimateGas',
         [txArgs, 'latest', null, { number: '0x2382' }]
     )
     assert.equal(response.status, 200)
     assert.isDefined(response.body)
-    assert.equal(web3.utils.hexToNumber(response.body.result), 273693n)
+    let gas = BigInt(web3.utils.hexToNumberString(response.body.result))
+    assert.isTrue(gas > baselineGas, 'block.number override should increase gas')

     // Check the `block.timestamp` value, without overrides
     response = await helpers.callRPCMethod(
         'eth_estimateGas',
         [txArgs, 'latest', null, null]
     )
     assert.equal(response.status, 200)
     assert.isDefined(response.body)
-    assert.equal(web3.utils.hexToNumber(response.body.result), 21473n)
+    gas = BigInt(web3.utils.hexToNumberString(response.body.result))
+    assert.equal(gas, baselineGas)

     // Override the `block.timestamp` value to `0x674DB1E1`.
     response = await helpers.callRPCMethod(
         'eth_estimateGas',
         [txArgs, 'latest', null, { time: '0x674DB1E1' }]
     )
     assert.equal(response.status, 200)
     assert.isDefined(response.body)
-    assert.equal(web3.utils.hexToNumber(response.body.result), 273693n)
+    gas = BigInt(web3.utils.hexToNumberString(response.body.result))
+    assert.isTrue(gas > baselineGas, 'block.timestamp override should increase gas')

     // Check the `block.prevrandao` value, without overrides
     response = await helpers.callRPCMethod(
         'eth_estimateGas',
         [txArgs, 'latest', null, null]
     )
     assert.equal(response.status, 200)
     assert.isDefined(response.body)
-    assert.equal(web3.utils.hexToNumber(response.body.result), 21473n)
+    gas = BigInt(web3.utils.hexToNumberString(response.body.result))
+    assert.equal(gas, baselineGas)

     // Override the `block.prevrandao` value to `0x7914bb5b13...`.
     let random = '0x7914bb5b13bac6f621bc37bbf6e406fbf4472aaaaf17ec2f309a92aca4e27fc0'
     response = await helpers.callRPCMethod(
         'eth_estimateGas',
         [txArgs, 'latest', null, { random: random }]
     )
     assert.equal(response.status, 200)
     assert.isDefined(response.body)
-    assert.equal(web3.utils.hexToNumber(response.body.result), 273693n)
+    gas = BigInt(web3.utils.hexToNumberString(response.body.result))
+    assert.isTrue(gas > baselineGas, 'prevrandao override should increase gas')

     // Check the `block.coinbase` value, without overrides
     response = await helpers.callRPCMethod(
         'eth_estimateGas',
         [txArgs, 'latest', null, null]
     )
     assert.equal(response.status, 200)
     assert.isDefined(response.body)
-    assert.equal(web3.utils.hexToNumber(response.body.result), 21473n)
+    gas = BigInt(web3.utils.hexToNumberString(response.body.result))
+    assert.equal(gas, baselineGas)

     // Override the `block.coinbase` value to `0x658Bdf...`.
     response = await helpers.callRPCMethod(
         'eth_estimateGas',
         [txArgs, 'latest', null, { coinbase: '0x658Bdf435d810C91414eC09147DAA6DB62406379' }]
     )
     assert.equal(response.status, 200)
     assert.isDefined(response.body)
-    assert.equal(web3.utils.hexToNumber(response.body.result), 273693n)
+    gas = BigInt(web3.utils.hexToNumberString(response.body.result))
+    assert.isTrue(gas > baselineGas, 'coinbase override should increase gas')
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let response = await helpers.callRPCMethod(
'eth_estimateGas',
[txArgs, 'latest', null, null]
)
assert.equal(response.status, 200)
assert.isDefined(response.body)
assert.equal(web3.utils.hexToNumber(response.body.result), 21473n)
// Override the `block.number` value to `9090`.
response = await helpers.callRPCMethod(
'eth_estimateGas',
[txArgs, 'latest', null, { number: '0x2382' }]
)
assert.equal(response.status, 200)
assert.isDefined(response.body)
assert.equal(web3.utils.hexToNumber(response.body.result), 273693n)
// Check the `block.timestamp` value, without overrides
response = await helpers.callRPCMethod(
'eth_estimateGas',
[txArgs, 'latest', null, null]
)
assert.equal(response.status, 200)
assert.isDefined(response.body)
assert.equal(web3.utils.hexToNumber(response.body.result), 21473n)
// Override the `block.timestamp` value to `0x674DB1E1`.
response = await helpers.callRPCMethod(
'eth_estimateGas',
[txArgs, 'latest', null, { time: '0x674DB1E1' }]
)
assert.equal(response.status, 200)
assert.isDefined(response.body)
assert.equal(web3.utils.hexToNumber(response.body.result), 273693n)
// Check the `block.prevrandao` value, without overrides
response = await helpers.callRPCMethod(
'eth_estimateGas',
[txArgs, 'latest', null, null]
)
assert.equal(response.status, 200)
assert.isDefined(response.body)
assert.equal(web3.utils.hexToNumber(response.body.result), 21473n)
// Override the `block.prevrandao` value to `0x7914bb5b13bac6f621bc37bbf6e406fbf4472aaaaf17ec2f309a92aca4e27fc0`.
let random = '0x7914bb5b13bac6f621bc37bbf6e406fbf4472aaaaf17ec2f309a92aca4e27fc0'
response = await helpers.callRPCMethod(
'eth_estimateGas',
[txArgs, 'latest', null, { random: random }]
)
assert.equal(response.status, 200)
assert.isDefined(response.body)
assert.equal(web3.utils.hexToNumber(response.body.result), 273693n)
// Check the `block.coinbase` value, without overrides
response = await helpers.callRPCMethod(
'eth_estimateGas',
[txArgs, 'latest', null, null]
)
assert.equal(response.status, 200)
assert.isDefined(response.body)
assert.equal(web3.utils.hexToNumber(response.body.result), 21473n)
// Override the `block.coinbase` value to `0x658Bdf435d810C91414eC09147DAA6DB62406379`.
response = await helpers.callRPCMethod(
'eth_estimateGas',
[txArgs, 'latest', null, { coinbase: '0x658Bdf435d810C91414eC09147DAA6DB62406379' }]
)
assert.equal(response.status, 200)
assert.isDefined(response.body)
assert.equal(web3.utils.hexToNumber(response.body.result), 273693n)
})
let response = await helpers.callRPCMethod(
'eth_estimateGas',
[txArgs, 'latest', null, null]
)
assert.equal(response.status, 200)
assert.isDefined(response.body)
const baselineGas = BigInt(web3.utils.hexToNumberString(response.body.result))
// Override the `block.number` value to `9090`.
response = await helpers.callRPCMethod(
'eth_estimateGas',
[txArgs, 'latest', null, { number: '0x2382' }]
)
assert.equal(response.status, 200)
assert.isDefined(response.body)
let gas = BigInt(web3.utils.hexToNumberString(response.body.result))
assert.isTrue(gas > baselineGas, 'block.number override should increase gas')
// Check the `block.timestamp` value, without overrides
response = await helpers.callRPCMethod(
'eth_estimateGas',
[txArgs, 'latest', null, null]
)
assert.equal(response.status, 200)
assert.isDefined(response.body)
gas = BigInt(web3.utils.hexToNumberString(response.body.result))
assert.equal(gas, baselineGas)
// Override the `block.timestamp` value to `0x674DB1E1`.
response = await helpers.callRPCMethod(
'eth_estimateGas',
[txArgs, 'latest', null, { time: '0x674DB1E1' }]
)
assert.equal(response.status, 200)
assert.isDefined(response.body)
gas = BigInt(web3.utils.hexToNumberString(response.body.result))
assert.isTrue(gas > baselineGas, 'block.timestamp override should increase gas')
// Check the `block.prevrandao` value, without overrides
response = await helpers.callRPCMethod(
'eth_estimateGas',
[txArgs, 'latest', null, null]
)
assert.equal(response.status, 200)
assert.isDefined(response.body)
gas = BigInt(web3.utils.hexToNumberString(response.body.result))
assert.equal(gas, baselineGas)
// Override the `block.prevrandao` value to `0x7914bb5b13bac6f621bc37bbf6e406fbf4472aaaaf17ec2f309a92aca4e27fc0`.
let random = '0x7914bb5b13bac6f621bc37bbf6e406fbf4472aaaaf17ec2f309a92aca4e27fc0'
response = await helpers.callRPCMethod(
'eth_estimateGas',
[txArgs, 'latest', null, { random: random }]
)
assert.equal(response.status, 200)
assert.isDefined(response.body)
gas = BigInt(web3.utils.hexToNumberString(response.body.result))
assert.isTrue(gas > baselineGas, 'prevrandao override should increase gas')
// Check the `block.coinbase` value, without overrides
response = await helpers.callRPCMethod(
'eth_estimateGas',
[txArgs, 'latest', null, null]
)
assert.equal(response.status, 200)
assert.isDefined(response.body)
gas = BigInt(web3.utils.hexToNumberString(response.body.result))
assert.equal(gas, baselineGas)
// Override the `block.coinbase` value to `0x658Bdf435d810C91414eC09147DAA6DB62406379`.
response = await helpers.callRPCMethod(
'eth_estimateGas',
[txArgs, 'latest', null, { coinbase: '0x658Bdf435d810C91414eC09147DAA6DB62406379' }]
)
assert.equal(response.status, 200)
assert.isDefined(response.body)
gas = BigInt(web3.utils.hexToNumberString(response.body.result))
assert.isTrue(gas > baselineGas, 'coinbase override should increase gas')
})
🤖 Prompt for AI Agents
In tests/web3js/estimate_gas_overrides_test.js around lines 33 to 104, the test
uses brittle exact gas assertions; instead capture a single baseline gas result
(call eth_estimateGas once with no overrides), convert results using
web3.utils.hexToNumberString and BigInt, then for each override call assert
BigInt(overrideResult) > BigInt(baseline) (or >= if appropriate) rather than
comparing to hardcoded numbers; update all comparisons to parse via
hexToNumberString+BigInt and remove the fixed numeric literals.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Update eth_estimateGas JSON-RPC endpoint to support block overrides

3 participants