Skip to content

build(solidity): raise hardhat to 2.29, which Node 24 needs - #4204

Merged
piotr-roslaniec merged 2 commits into
mainfrom
chore/solidity-hardhat-2.29-node-24
Jul 27, 2026
Merged

build(solidity): raise hardhat to 2.29, which Node 24 needs#4204
piotr-roslaniec merged 2 commits into
mainfrom
chore/solidity-hardhat-2.29-node-24

Conversation

@mswilkison

@mswilkison mswilkison commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Stacked on #4203. The last dependency step: hardhat 2.19.5 → 2.29.0 in
both packages.

smock capped this at 2.19.5. It is gone as of #4203, so the ceiling lifts —
and 2.26+ is what Node 24 requires. Below it, Hardhat's solc download fails on
Node 24 with HH502, because npm's undici and Node 24's bundled undici share a
global-dispatcher symbol.

Verified

Whole suite, both packages, both runtimes:

Node 22 Node 24
ecdsa 673 / 44 pending / 0 673 / 44 / 0
random-beacon 955 / 0 pending / 0 955 / 0 / 0

Identical to the pre-bump results, so nothing regressed — and it is safe to
land before or after the Node bump in #4201, in either order.

The other thing 2.29 brings

before after
random-beacon 3m 23s
ecdsa 2m 31s

That is EDR, the Rust execution engine, backported into the 2.x line.

Two tests needed adjusting

challengeDkgResult has an inline gas check, and two tests deliberately
underfund the call to trigger it. hardhat 2.29 defaults to a newer hardfork,
where EIP-7623's intrinsic calldata floor is enforced before execution:

ProviderError: Transaction requires gas floor of 161720 but got limit of 100000

The node rejected the transaction outright, so the contract's own check never
ran — the tests had stopped testing the thing they name. The limits move to
just above each floor (100000 → 170000, 200000 → 220000), still far short
of what the call needs to complete, so both revert inside the contract as
intended.

The alternative was pinning the hardfork back to 2.19.5's default. Rejected:
mainnet is past it, and running the suite against an older EVM than production
is a worse trade than adjusting two gas limits.

After this

Node 22 → 24 in the five workflows, two Dockerfiles and two engines fields —
a small follow-up, and the reason the whole chain existed. #4201 already moved
those from 18 to 22; this makes 24 reachable for the first time.

Summary by CodeRabbit

  • Chores

    • Updated the Hardhat development tooling to version 2.29.0 for the ECDSA and random beacon packages.
  • Tests

    • Updated gas-limit scenarios to accurately validate insufficient-gas behavior under current transaction gas rules.
    • Clarified test coverage for contract-level gas checks.

The last dependency step. smock capped this at 2.19.5 and is gone, so the
ceiling is lifted: hardhat 2.29 is the current 2.x line, and 2.26+ is what Node
24 requires -- below it, Hardhat's solc download fails on Node 24 with HH502,
because npm's undici and Node 24's bundled undici share a global-dispatcher
symbol.

Verified on both runtimes, both packages:

                  Node 22        Node 24
  ecdsa           673 / 44 / 0   673 / 44 / 0
  random-beacon   955 /  0 / 0   955 /  0 / 0

Identical to the pre-bump results, so nothing regressed and the PR is safe to
land before or after the Node bump in #4201.

Worth noting the wall clock, since it is the other thing 2.29 brings: the
random-beacon suite goes from 3m to 23s and ecdsa from 2m to 31s. That is EDR,
the Rust execution engine, backported into the 2.x line.

Two tests needed adjusting, both the same cause. `challengeDkgResult` has an
inline gas check, and two tests deliberately underfund the call to trigger it.
hardhat 2.29 defaults to a newer hardfork, where EIP-7623's intrinsic calldata
floor is enforced *before* execution:

  ProviderError: Transaction requires gas floor of 161720 but got limit of 100000

so the node rejected the transaction outright and the contract's own check
never ran -- the tests passed for the wrong reason, or rather stopped testing
anything. The limits move to just above each floor (100000 -> 170000 and
200000 -> 220000), which keeps them far short of what the call needs to
complete, so both still revert inside the contract as intended.

The alternative was pinning the hardfork back to what 2.19.5 defaulted to.
Rejected: mainnet is past it, and running the suite against an older EVM than
production is a worse trade than adjusting two gas limits.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Hardhat is upgraded from 2.19.5 to 2.29.0 in two Solidity packages. Two challengeDkgResult insufficient-gas tests increase transaction gas limits and clarify intrinsic calldata floor behavior.

Changes

Hardhat gas-floor compatibility

Layer / File(s) Summary
Upgrade Hardhat development dependencies
solidity/ecdsa/package.json, solidity/random-beacon/package.json
Updates the Hardhat development dependency from 2.19.5 to 2.29.0.
Adjust challengeDkgResult gas-limit tests
solidity/ecdsa/test/WalletRegistry.CustomErrors.test.ts, solidity/ecdsa/test/WalletRegistry.WalletCreation.test.ts
Raises test transaction gas limits and documents the distinction between Hardhat’s intrinsic calldata floor and contract execution gas checks.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related issues

  • Issue 4209: The Hardhat 2.29.0 upgrade is identified as a prerequisite for the planned Hardhat 3 migration in these Solidity packages.

Suggested reviewers: lionakhnazarov, piotr-roslaniec

🚥 Pre-merge checks | ✅ 5
✅ 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 clearly summarizes the main change: upgrading Hardhat to 2.29 to support Node 24.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/solidity-hardhat-2.29-node-24

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.

mswilkison added a commit that referenced this pull request Jul 27, 2026
The end of the chain, and the reason for it. Five workflows, two Dockerfiles
and two `engines` fields go from Node 18.15.0 -- end of life since 2025-04-30 --
straight to 24.11.1, the current LTS, supported until 2028-04-30.

This was not reachable before. Node 24 needs hardhat >= 2.26, because below it
Hardhat's solc download fails with HH502: npm's undici and Node 24's bundled
undici share a global-dispatcher symbol, so the download reaches Node's
internal dispatcher, which rejects `maxRedirections`. hardhat >= 2.21 in turn
broke @defi-wonderland/smock, and no smock version ever reached 2.26. The
dependency was archived, so no version ever would. That is why #4203 removed it
and #4204 raised hardhat before this commit could exist.

The failure that started it, now passing on the same machine and the same
runtime -- cold compiler cache, which is what a CI runner always has:

  before   Error HH502: Couldn't download compiler versions list.
  after    Compiled 75 Solidity files successfully

Verified, whole suite, both packages, on Node 24.11.1:

  ecdsa           673 passing / 44 pending / 0 failing
  random-beacon   955 passing /  0 pending / 0 failing

Docker base images are pinned to `node:24.11.1-alpine` rather than the floating
`node:24-alpine`, matching the exact version CI pins, so the two runtimes
cannot drift apart.

This supersedes #4201, which moved the same nine files from 18 to 22 while 24
was still out of reach. If that lands first this needs a one-token rebase per
site; if this chain lands, #4201 can be closed.

BREAKING CHANGE: the solidity packages now require Node >= 24.0.0. Contributors
on Node 18 or 20 will need to upgrade.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Base automatically changed from chore/solidity-remove-smock to chore/solidity-hardhat-2.19-smock-pin July 27, 2026 17:12
Base automatically changed from chore/solidity-hardhat-2.19-smock-pin to main July 27, 2026 19:39

@piotr-roslaniec piotr-roslaniec left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Self-approve as repo admin. hardhat 2.19.5 -> 2.29.0 in both packages. 6 files, 664 +/- 2046. yarn.lock updates remove @chainsafe/* (replaced by @ethereumjs/*). Two test gas-limit adjustments (100000->170000, 200000->220000) explained in-line with EIP-7623 floor reasoning.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@solidity/ecdsa/test/WalletRegistry.WalletCreation.test.ts`:
- Around line 3018-3026: Update the comment above the challengeDkgResult call in
the gas-limit test to state that gasLimit 220000 clears Hardhat’s pre-execution
calldata floor and exercises the contract-level gas check; remove language
implying the test asserts rejection below that floor.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1bb7817c-8f09-4bed-92fd-6b3fc5280a87

📥 Commits

Reviewing files that changed from the base of the PR and between f45317c and fc611dd.

⛔ Files ignored due to path filters (2)
  • solidity/ecdsa/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
  • solidity/random-beacon/yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (4)
  • solidity/ecdsa/package.json
  • solidity/ecdsa/test/WalletRegistry.CustomErrors.test.ts
  • solidity/ecdsa/test/WalletRegistry.WalletCreation.test.ts
  • solidity/random-beacon/package.json

Comment on lines +3018 to +3026
// Above EIP-7623's intrinsic calldata floor, which hardhat
// 2.29 enforces before execution -- below it the node rejects
// the transaction outright and the contract's own gas check
// never runs, which is what this asserts on. Still far short of
// what `challengeDkgResult` needs to complete.
await expect(
walletRegistry
.connect(thirdParty)
.challengeDkgResult(dkgResult, { gasLimit: 200000 })
.challengeDkgResult(dkgResult, { gasLimit: 220000 })

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== locate file =="
fd -a 'WalletRegistry.WalletCreation.test.ts' . || true

echo "== relevant lines =="
FILE="$(fd 'WalletRegistry.WalletCreation.test.ts' . | head -n 1)"
if [ -n "${FILE:-}" ]; then
  wc -l "$FILE"
  sed -n '2980,3055p' "$FILE" | cat -n | sed 's/^/  /'
fi

echo "== nearby expect assertions =="
rg -n "challengeDkgResult|gasLimit: 220000|EIP-7623|intrinsic calldata floor|below it|contract's own gas check" "$FILE" || true

echo "== repo version/config hints =="
for f in package.json pnpm-lock.yaml yarn.lock package-lock.json hardhat.config.* tsconfig.json; do
  [ -f "$f" ] && printf '\n-- %s --\n' "$f" && sed -n '1,220p' "$f" | rg -n '"hardhat"|"hardhat-ethers"|2\.29|hardhat-ethers|hardhat-verify|gasReporter|gasLimit' -C 2 || true
done

Repository: threshold-network/keep-core

Length of output: 6585


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== hardhat deps across tracked files =="
rg -n '"hardhat"|"hardhat-ethers"|hardhat-version|gasLimit' --glob '!node_modules' --glob '!dist' --glob '!build' . | head -n 200 || true

echo "== package manifests =="
git ls-files '*package.json' | while read -r f; do
  echo "-- $f --"
  sed -n '1,240p' "$f" | jq -r '
    ["dependencies","devDependencies","peerDependencies"][] // empty
    as $section
    | ("[" + $section + "]: " + (.[$section] | tostring))
  ' 2>/dev/null | rg "hardhat|hardhat-ethers" || true
done

echo "== hardhat config gas settings =="
git ls-files 'hardhat.config.*' | while read -r f; do
  echo "-- $f --"
  sed -n '1,260p' "$f" | rg -n "gasLimit|hardhat|evmVersion|fork|mempool|gasMultiplier|gasPrice|maxFee|gas" -C 3 || true
done

Repository: threshold-network/keep-core

Length of output: 50384


🌐 Web query:

Hardhat 2.29 EIP-7623 intrinsic calldata floor gasMinimum documentation

💡 Result:

As of July 27, 2026, Hardhat v2.29.0 does not contain specific implementation logic or documentation regarding the intrinsic calldata floor gas requirement introduced by EIP-7623 [1][2]. The v2.29.0 release was a minor update focused on Mocha compatibility and TypeScript initialization [1]. EIP-7623: Increase calldata cost is an Ethereum standard that mandates a change in how transaction gas is calculated, specifically by introducing a minimum gas floor for data-heavy transactions [3][4]. Under this EIP, transactions that do not exceed a certain threshold of gas spent on EVM operations relative to gas spent on calldata are subject to an increased calldata cost (10/40 gas per byte) [3][4]. This ensures that data-heavy transactions contribute more appropriately to the network's gas usage, effectively reducing the maximum block size [3][4]. While node software and core development libraries (such as Geth) have moved to implement this logic [5], Hardhat's core package (v2.29.0) does not explicitly detail support for this intrinsic gas floor in its release notes or documentation [1][6][7]. Users relying on Hardhat for testing environments that require EIP-7623 compliance should monitor ongoing updates to Hardhat's Ethereum Development Runtime (EDR) or subsequent Hardhat versions, as EIP support in Hardhat is typically rolled out through these components [6][7][8].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== tracked package manifests =="
git ls-files '*package.json' | sed -n '1,120p'

echo "== hardhat dependency lines in tracked manifests only =="
git ls-files '*package.json' \
  | xargs -r rg -n '"hardhat"|"hardhat-ethers"|`@nomicfoundation/hardhat-network`'| head -n 200 || true

echo "== package-manager/config lock summary =="
for f in package-lock.json pnpm-lock.yaml yarn.lock bun.lockb bun.lock README.md; do
  [ -e "$f" ] && printf '\n-- %s --\n' "$f" && sed -n '1,180p' "$f" | rg -n 'hardhat|hardhat-ethers|`@nomicfoundation/hardhat-network`|lockfileVersion|packageManager' -C 2 || true
done

echo "== test gas-limit comments context nearby =="
sed -n '3008,3032p' solidity/ecdsa/test/WalletRegistry.WalletCreation.test.ts | cat -n

Repository: threshold-network/keep-core

Length of output: 1909


Clarify which gas-failure path this test covers.

gasLimit: 220000 clears the pre-execution gas minimum, so this test is meant to exercise the contract-level challengeDkgResult gas check, not the Hardhat rejection for transactions below that minimum. Update the comment to avoid describing the below-floor rejection as the behavior under test.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@solidity/ecdsa/test/WalletRegistry.WalletCreation.test.ts` around lines 3018
- 3026, Update the comment above the challengeDkgResult call in the gas-limit
test to state that gasLimit 220000 clears Hardhat’s pre-execution calldata floor
and exercises the contract-level gas check; remove language implying the test
asserts rejection below that floor.

@piotr-roslaniec
piotr-roslaniec merged commit 6f87e20 into main Jul 27, 2026
30 checks passed
@piotr-roslaniec
piotr-roslaniec deleted the chore/solidity-hardhat-2.29-node-24 branch July 27, 2026 19:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants