Skip to content

Add downloadCompilers parallel hook for extensible compiler downloads#8009

Merged
marianfe merged 6 commits intomainfrom
feat/solx-step2-download-compilers-hook
Mar 24, 2026
Merged

Add downloadCompilers parallel hook for extensible compiler downloads#8009
marianfe merged 6 commits intomainfrom
feat/solx-step2-download-compilers-hook

Conversation

@marianfe
Copy link
Copy Markdown
Contributor

@marianfe marianfe commented Feb 26, 2026

Summary

Create and export two new hooks in the build system, downloadCompilers and getCompiler, which can later be used for the solx plugin.
This is part 2 in the chain of PRs to introduce solx support in Hardhat 3.

The downloadCompilers hook is a parallel hook that allows each compiler plugin to handle the downloads for their own compiler.type, and we need the getCompiler chained hook to be able to correctly set the path to the new downloaded binaries prior to compilation invocation.

The previous Part 1 PR is here: #8008

Details

  • Extract solc download logic into a new downloadCompilers parallel hook.
  • All registered handlers run concurrently via runParallelHandlers.
  • Built-in handler filters for solc configs only (type undefined or "solc") using isSolcConfig()
  • Third-party plugins register their own handlers for custom compiler types
  • Collect all compiler configs from all build profiles (including overrides) before downloading

Depends on: #8008 (multi-compiler abstraction)

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Feb 26, 2026

🦋 Changeset detected

Latest commit: 0d075d2

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

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

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

@marianfe marianfe added no docs needed This PR doesn't require links to documentation no peer bump needed labels Feb 26, 2026
@marianfe marianfe force-pushed the feat/solx-step1-core-multi-compiler branch from 1cd6812 to 0f7deb7 Compare February 26, 2026 12:03
@marianfe marianfe force-pushed the feat/solx-step2-download-compilers-hook branch 2 times, most recently from fd0f189 to 9deb0c9 Compare February 26, 2026 12:23
@marianfe marianfe requested a review from Copilot February 26, 2026 12:25
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces a new downloadCompilers parallel hook in the Hardhat build system to enable extensible compiler downloads. This is part 2 in a series of changes to add multi-compiler support, specifically preparing for solx support in Hardhat 3.

Changes:

  • Added a new downloadCompilers parallel hook that receives all compiler configs from all build profiles
  • Created a built-in hook handler that filters for solc compilers and downloads them in parallel
  • Refactored the build system to use the new hook instead of directly calling downloadSolcCompilers

Reviewed changes

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

Show a summary per file
File Description
v-next/hardhat/src/internal/builtin-plugins/solidity/type-extensions.ts Adds the downloadCompilers hook definition to the SolidityHooks interface with comprehensive documentation
v-next/hardhat/src/internal/builtin-plugins/solidity/hook-handlers/solidity.ts Implements the built-in handler that filters for solc configs and downloads them
v-next/hardhat/src/internal/builtin-plugins/solidity/build-system/build-system.ts Refactors download logic to use the new hook and returns full compiler configs instead of just versions
v-next/hardhat/src/internal/builtin-plugins/solidity/index.ts Registers the new solidity hook handler
v-next/hardhat/test/internal/builtin-plugins/solidity/hooks.ts Adds comprehensive test coverage for the new hook
v-next/hardhat/test/internal/builtin-plugins/solidity/build-system/build-system.ts Updates tests to register the built-in hook handlers
.changeset/good-eels-buy.md Documents the change for the changelog

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@marianfe marianfe force-pushed the feat/solx-step1-core-multi-compiler branch 2 times, most recently from d004fe7 to 7cade07 Compare March 4, 2026 12:27
@marianfe marianfe force-pushed the feat/solx-step2-download-compilers-hook branch 2 times, most recently from 0fe2822 to 1b72adc Compare March 5, 2026 15:26
@marianfe marianfe force-pushed the feat/solx-step1-core-multi-compiler branch from e265b1b to 5a48ee9 Compare March 5, 2026 15:42
@marianfe marianfe force-pushed the feat/solx-step2-download-compilers-hook branch from 1b72adc to 7b0ac41 Compare March 5, 2026 15:42
@marianfe marianfe force-pushed the feat/solx-step1-core-multi-compiler branch from 5a48ee9 to 2fe6cb9 Compare March 5, 2026 15:44
@marianfe marianfe force-pushed the feat/solx-step2-download-compilers-hook branch from 7b0ac41 to daa40ad Compare March 5, 2026 15:44
@marianfe marianfe force-pushed the feat/solx-step1-core-multi-compiler branch from 2fe6cb9 to 5b313d0 Compare March 6, 2026 09:24
@marianfe marianfe force-pushed the feat/solx-step2-download-compilers-hook branch 3 times, most recently from 070b562 to 85e74f6 Compare March 6, 2026 09:51
@marianfe marianfe force-pushed the feat/solx-step1-core-multi-compiler branch from 5b313d0 to a7a1164 Compare March 6, 2026 09:58
@marianfe marianfe force-pushed the feat/solx-step2-download-compilers-hook branch from 85e74f6 to c64fb8d Compare March 6, 2026 09:58
@marianfe marianfe force-pushed the feat/solx-step1-core-multi-compiler branch from a7a1164 to 29875a4 Compare March 6, 2026 10:07
@marianfe marianfe force-pushed the feat/solx-step2-download-compilers-hook branch from c64fb8d to 5a80f5b Compare March 6, 2026 10:07
@marianfe marianfe requested review from alcuadrado and kanej March 6, 2026 10:09

// We download the compiler for the build info as it may not be configured
// in the HH config, hence not downloaded with the other compilers
// Build info recompilation is always solc-only: build info files are
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.

I would say that this is an outdated assumption. BuildInfos should include the compiler type, so we should run the same download logic here.

See this change where I added compilerType to SolidityBuildInfo: 6ed3056

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.

We could create a partial SolidityCompilerConfig like this:

import type { SolidityBuildInfo } from "hardhat/types/solidity";
import type { SolidityCompilerConfig } from "hardhat/types/config";

function getPartialSolidityCompilerConfigFromBuildInfo(
  buildInfo: SolidityBuildInfo,
): SolidityCompilerConfig {
  return {
    // This cast may result in a "type" that no plugin can handle. So we should
    // probably have a way to know if a handler downlaoded a certain compiler,
    // and throw otherwise. This can't be done with parallel one, but can be
    // done with chained ones.
    type: buildInfo.compilerType as SolidityCompilerConfig["type"],
    version: buildInfo.solcVersion,
    settings: buildInfo.input.settings,
  };
}

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.

There's no way to know if the buildinfo was built with wasm solc, but that's ok. We were already doing preferWasm: false below

} from "@nomicfoundation/hardhat-utils/fs";

import { SolidityBuildSystemImplementation } from "../../../../../src/internal/builtin-plugins/solidity/build-system/build-system.js";
import createSolidityHookHandlers from "../../../../../src/internal/builtin-plugins/solidity/hook-handlers/solidity.js";
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.

Small tip: Moving the implementation of the handler into a separate file makes the test nicer.

The way we tend to think about it is this:

  • If the handler requires the context, we may keep the implementation there, and use more integration-like tests.
  • If the handler is more pure, we separate it and unit test it.

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.

For example, this test file has hooks.setContext({} as HookContext); which I don't really like. It assumes that the HookContext is not used b any of the tests. I'd rather unit-test the handler.

hookHandlers: {
config: () => import("./hook-handlers/config.js"),
hre: () => import("./hook-handlers/hre.js"),
solidity: () => import("./hook-handlers/solidity.js"),
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 is a surprisingly nice pattern

}

for (const job of runnableCompilationJobs) {
const compilerType = job.solcConfig.type ?? "solc";
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.

I guess the changes in this file from here on in fact belong to #8008, but it's not important. Just mentioning it for my future reference and clarity.

Copy link
Copy Markdown
Member

@alcuadrado alcuadrado Mar 8, 2026

Choose a reason for hiding this comment

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

Reviewed these changes. LGTM

let jobsPerVersion = jobsPerVersionAndEvmVersion.get(solcVersion);
// Group by compiler type + Solidity version to produce separate log
// lines for e.g. "solc 0.8.33" vs "solx 0.1.3 (Solidity 0.8.33)".
const groupKey = `${compilerType}#${solcVersion}`;
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.

I'm more of a fan of multi-level maps than this combined keys, as the type system enforces that you give them some thought. I'm not agains this either.

[runnableCompilationJob.solcConfig],
async (_context, cfg) =>
getCompiler(cfg.version, {
preferWasm: resolvePreferWasm(cfg, buildProfile.preferWasm),
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.

I like this. The buildProfile.preferWasm shouldn't affect any other compiler type. I actually forbid using it for build profiles with non-solc compilers in 558ec52

resolveConfigurationVariable,
);
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- test registers unregistered types
resolved.solidity.registeredCompilerTypes.push(...(types as any[]));
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.

Just for future reference: in actual plugins we return new resolved config objects rather than modifying it. Otherwise understanding what's going on in the presence of multiple plugins gets really tricky.

@kanej kanej removed their request for review March 9, 2026 09:40
@kanej kanej mentioned this pull request Mar 9, 2026
4 tasks
@marianfe marianfe force-pushed the feat/solx-step1-core-multi-compiler branch from 5544e68 to 5d68d88 Compare March 16, 2026 18:11
@marianfe marianfe force-pushed the feat/solx-step2-download-compilers-hook branch from ef42da0 to 2198ddc Compare March 16, 2026 18:11
@marianfe marianfe force-pushed the feat/solx-step1-core-multi-compiler branch from 5d68d88 to 1163e75 Compare March 16, 2026 18:23
@marianfe marianfe force-pushed the feat/solx-step2-download-compilers-hook branch 2 times, most recently from c9abdd0 to f820760 Compare March 19, 2026 13:22
Base automatically changed from feat/solx-step1-core-multi-compiler to main March 23, 2026 11:23
@marianfe marianfe force-pushed the feat/solx-step2-download-compilers-hook branch from f820760 to 0d075d2 Compare March 23, 2026 11:33
Copy link
Copy Markdown
Member

@alcuadrado alcuadrado left a comment

Choose a reason for hiding this comment

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

LGTM. I created an issue for the only open comment, which can be addressed in the future, if needed: #8081

@marianfe marianfe added this pull request to the merge queue Mar 24, 2026
Merged via the queue into main with commit 2fe2daa Mar 24, 2026
213 checks passed
@marianfe marianfe deleted the feat/solx-step2-download-compilers-hook branch March 24, 2026 20:34
@github-actions github-actions bot mentioned this pull request Mar 24, 2026
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

None yet

Development

Successfully merging this pull request may close these issues.

4 participants