Skip to content

Support better gas estimation to avoid internal OOG errors - #8501

Open
ChristopherDedominici wants to merge 18 commits into
mainfrom
better-gas-estimation-impl
Open

Support better gas estimation to avoid internal OOG errors#8501
ChristopherDedominici wants to merge 18 commits into
mainfrom
better-gas-estimation-impl

Conversation

@ChristopherDedominici

@ChristopherDedominici ChristopherDedominici commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Fixes #8399

Link to website PR: NomicFoundation/hardhat-website#292

@ChristopherDedominici ChristopherDedominici self-assigned this Aug 11, 2026
Copilot AI lite review requested due to automatic review settings August 11, 2026 17:47
@github-project-automation github-project-automation Bot moved this to Backlog in Hardhat Aug 11, 2026
@ChristopherDedominici ChristopherDedominici moved this from Backlog to In Progress in Hardhat Aug 11, 2026
@changeset-bot

changeset-bot Bot commented Aug 11, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 8fce209

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
hardhat Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Wires Hardhat’s EDR network configuration through to EDR’s new gas estimation mode that prevents silent internal out-of-gas (OOG) failures, and adds error mapping + an automatic-gas fallback path for the new “unavoidable internal OOG” estimation failure.

Changes:

  • Added gasEstimationMode to EDR network config (validation + resolved default to noInternalOutOfGas) and mapped it to EDR’s GasEstimationMode enum.
  • Introduced InternalCallOutOfGasError and mapped EDR’s new estimation failure reason to it during eth_estimateGas.
  • When gas: "auto" on EDR networks, if estimation fails with InternalCallOutOfGasError, fall back to the resolved default transaction gas limit (EIP-7825-aware, capped to block gas limit where applicable), without applying the gas multiplier.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/hardhat/src/internal/builtin-plugins/network-manager/type-validation.ts Validates gasEstimationMode as a supported string union for EDR networks.
packages/hardhat/src/internal/builtin-plugins/network-manager/type-extensions/config.ts Extends config types to expose gasEstimationMode (user + resolved).
packages/hardhat/src/internal/builtin-plugins/network-manager/config-resolution.ts Resolves default gasEstimationMode to noInternalOutOfGas.
packages/hardhat/src/internal/builtin-plugins/network-manager/provider-errors.ts Adds InternalCallOutOfGasError surfaced to JSON-RPC clients.
packages/hardhat/src/internal/builtin-plugins/network-manager/edr/type-validation.ts Adds a type guard for EDR’s internal-OOG estimation failure data.
packages/hardhat/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.ts Maps Hardhat mode to EDR enum; refines default gas cap logic and adds resolveEdrDefaultTransactionGasLimit.
packages/hardhat/src/internal/builtin-plugins/network-manager/edr/edr-provider.ts Plumbs gasEstimationMode into EDR config and maps internal-OOG estimation failures to InternalCallOutOfGasError.
packages/hardhat/src/internal/builtin-plugins/network-manager/request-handlers/handlers/gas/multiplied-gas-estimation.ts Adds fallback gas handling for internal-OOG estimation failures.
packages/hardhat/src/internal/builtin-plugins/network-manager/request-handlers/handlers/gas/automatic-gas-handler.ts Passes fallback gas into the shared estimation logic.
packages/hardhat/src/internal/builtin-plugins/network-manager/request-handlers/handlers-array.ts Computes EDR-only fallback gas limit and wires it into AutomaticGasHandler.
packages/hardhat/test/internal/edr/context.ts Updates EDR test config stub to include required gasEstimationMode.
packages/hardhat/test/internal/builtin-plugins/network-manager/utils/apply-coverage-network-overrides.ts Updates coverage override tests to include gasEstimationMode.
packages/hardhat/test/internal/builtin-plugins/network-manager/request-handlers/handlers/gas/automatic-gas-handler.ts Adds unit tests for internal-OOG fallback vs rethrow behavior.
packages/hardhat/test/internal/builtin-plugins/network-manager/network-manager.ts Adds validation tests for gasEstimationMode.
packages/hardhat/test/internal/builtin-plugins/network-manager/hook-handlers/config.ts Asserts default resolved gasEstimationMode is noInternalOutOfGas.
packages/hardhat/test/internal/builtin-plugins/network-manager/config-resolution.ts Adds resolution coverage for gasEstimationMode (explicit + default).
packages/hardhat/test/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.ts Adds unit tests for new conversion helpers and mode-to-enum mapping.
packages/hardhat/test/internal/builtin-plugins/network-manager/edr/edr-provider.ts Adds integration tests for internal-OOG behavior in both estimation modes and auto-gas fallback behavior.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Copilot AI review requested due to automatic review settings August 12, 2026 11:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 19 out of 19 changed files in this pull request and generated no new comments.

Suppressed comments (1)

packages/hardhat/src/internal/builtin-plugins/network-manager/request-handlers/handlers-array.ts:9

  • The new top-level import of resolveEdrDefaultTransactionGasLimit pulls in edr/utils/convert-to-edr, which eagerly imports @nomicfoundation/edr (large/native dependency). Since createHandlersArray is used for all network types, this makes EDR load even for pure HTTP networks. Consider lazily loading this helper only inside the networkConfig.type === "edr-simulated" branch (e.g. await import(...), ideally cached) or moving the gas-limit helper to a lightweight module that doesn’t import @nomicfoundation/edr.
import { resolveEdrDefaultTransactionGasLimit } from "../edr/utils/convert-to-edr.js";

Copilot AI review requested due to automatic review settings August 13, 2026 12:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 25 out of 25 changed files in this pull request and generated no new comments.

Suppressed comments (1)

.changeset/bold-geckos-agree.md:6

  • The changeset description doesn’t mention that noInternalOutOfGas is now the resolved default gasEstimationMode for EDR networks. Since this changes default behavior (and can surface a new estimation error), it should be called out explicitly in the release note so users know how to restore the previous behavior via topLevelSuccess.
Add `gasEstimationMode` config option to EDR networks, featuring a `"noInternalOutOfGas"` mode to prevent misleading `eth_estimateGas` results when internal calls run out of gas.

Copilot AI review requested due to automatic review settings August 18, 2026 09:21

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 23 out of 23 changed files in this pull request and generated no new comments.

Copilot AI review requested due to automatic review settings August 18, 2026 14:06
@ChristopherDedominici ChristopherDedominici added no docs needed This PR doesn't require links to documentation and removed status:triaging labels Aug 18, 2026
@ChristopherDedominici
ChristopherDedominici marked this pull request as ready for review August 18, 2026 14:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 21 out of 21 changed files in this pull request and generated no new comments.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 21 out of 21 changed files in this pull request and generated no new comments.

Suppressed comments (2)

packages/hardhat/src/internal/builtin-plugins/network-manager/request-handlers/handlers/gas/multiplied-gas-estimation.ts:94

  • This unconditional header-based cap is incorrect when blockGasLimit: false. In that configuration EDR has no mining block gas limit, but eth_getBlockByNumber still reports a header gas limit; therefore a configured transactionGasCap/default above that value is silently reduced here. A transaction whose top-level execution needs the configured fallback can then OOG even though EDR would accept it. Only cap when a mining block gas limit is actually enforced (and preserve the exact resolved fallback otherwise).
        this.#fallbackGas !== undefined
      ) {
        const blockGasLimit = BigInt(await this.#fetchBlockGasLimit("pending"));

packages/hardhat/src/internal/builtin-plugins/network-manager/request-handlers/handlers/gas/multiplied-gas-estimation.ts:90

  • Automatic gas still fails for clients connected to hardhat node over HTTP. HttpProvider deserializes this as a plain ProviderError carrying data.reason, so this instanceof check cannot recognize it; moreover, those connections deliberately receive no fallback value. As a result, eth_sendTransaction without gas rethrows the estimation error instead of using the node's default transaction gas limit, contrary to the automatic-gas requirement. Recognize the serialized discriminator and let the remote node apply its default (for example, by forwarding the request without injecting gas), or otherwise obtain the server-resolved fallback.

This issue also appears on line 92 of the same file.

      // transaction rejected.
      if (

Copilot AI review requested due to automatic review settings August 18, 2026 14:33

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 21 out of 21 changed files in this pull request and generated no new comments.

Copilot AI review requested due to automatic review settings August 18, 2026 14:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 21 out of 21 changed files in this pull request and generated no new comments.

Suppressed comments (1)

packages/hardhat/src/internal/builtin-plugins/network-manager/request-handlers/handlers/gas/multiplied-gas-estimation.ts:96

  • #fetchBlockGasLimit converts the pending limit with hexStringToNumber before this BigInt conversion. Since blockGasLimit explicitly accepts bigints above Number.MAX_SAFE_INTEGER, a valid large limit makes this fallback throw InvalidParameterError instead of sending the transaction. Parse the pending quantity directly as a bigint on this path.
        const blockGasLimit = BigInt(await this.#fetchBlockGasLimit("pending"));

        return numberToHexString(min(this.#fallbackGas, blockGasLimit));

@ChristopherDedominici ChristopherDedominici moved this from In Progress to In Review in Hardhat Aug 18, 2026
@schaable
schaable requested review from schaable and removed request for alcuadrado August 25, 2026 16:29
`the ${blockTag} block should have a gasLimit`,
);

return hexStringToNumber(block.gasLimit);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this will fail for anything above Number.MAX_SAFE_INTEGER. Consider using hexStringToBigInt

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

True in principle, hexStringToNumber throws above 2^53-1, but it's pre-existing code, unreachable on any real chain's gas limit, and fixing it properly means converting the whole estimation path (including line 61 and the float multiplier math) to bigint, not just that one line. So considering that no chain is at risk, I"d skip

"hardhat": minor
---

Add `gasEstimationMode` config option to EDR networks, featuring a `"noInternalOutOfGas"` mode to prevent misleading `eth_estimateGas` results when internal calls run out of gas.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
Add `gasEstimationMode` config option to EDR networks, featuring a `"noInternalOutOfGas"` mode to prevent misleading `eth_estimateGas` results when internal calls run out of gas.
Added the `gasEstimationMode` config option to EDR-simulated networks, defaulting to `"noInternalOutOfGas"`: `eth_estimateGas` now returns a gas limit that also keeps calls internal to the transaction from running out of gas, and fails with a descriptive error when no gas limit can prevent it. Set it to `"topLevelSuccess"` for the previous behavior, where only the top-level call had to succeed.

error instanceof InternalCallOutOfGasError &&
this.#fallbackGas !== undefined
) {
const blockGasLimit = BigInt(await this.#fetchBlockGasLimit("pending"));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If the network doesn't enforce a blockGasLimit, this will unnecessarily cap the estimation. Is this the expected behavior?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done here: b394f58

Copilot AI review requested due to automatic review settings August 31, 2026 20:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 21 out of 21 changed files in this pull request and generated 2 comments.

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

Labels

no docs needed This PR doesn't require links to documentation no peer bump needed

Projects

Status: In Review

Development

Successfully merging this pull request may close these issues.

Support better gas estimation to avoid internal OOG errors

4 participants