diff --git a/.changeset/big-rings-listen.md b/.changeset/big-rings-listen.md new file mode 100644 index 00000000000..05d8afeb085 --- /dev/null +++ b/.changeset/big-rings-listen.md @@ -0,0 +1,5 @@ +--- +"hardhat": patch +--- + +Update `hardhat node` to always use the new `node` network (#7989)[https://github.com/NomicFoundation/hardhat/pull/7989] diff --git a/v-next/hardhat-ethers/test/plugin-functionalities.ts b/v-next/hardhat-ethers/test/plugin-functionalities.ts index 6555691bbf4..f247ec32a11 100644 --- a/v-next/hardhat-ethers/test/plugin-functionalities.ts +++ b/v-next/hardhat-ethers/test/plugin-functionalities.ts @@ -18,6 +18,7 @@ import { assertIsSigner, initializeTestEthers, spawnTestRpcServer, + tryUntil, } from "./helpers/helpers.js"; describe("Ethers plugin", () => { @@ -719,12 +720,9 @@ describe("Ethers plugin", () => { await greeter.setGreeting("Hola"); - // wait for 1.5 polling intervals for the event to fire - await new Promise((resolve) => setTimeout(resolve, 100)); + await tryUntil(() => assert.equal(eventEmitted, true)); await greeter.removeAllListeners(); - - assert.equal(eventEmitted, true); }); describe("with hardhat's signer", () => { @@ -948,11 +946,9 @@ describe("Ethers plugin", () => { await deployedGreeter.setGreeting("Hola"); - // wait for 1.5 polling intervals for the event to fire - await new Promise((resolve) => setTimeout(resolve, 100)); + await tryUntil(() => assert.equal(eventEmitted, true)); deployedGreeter.removeAllListeners(); - assert.equal(eventEmitted, true); }); }); @@ -1160,11 +1156,9 @@ describe("Ethers plugin", () => { await deployedGreeter.setGreeting("Hola"); - // wait for the event to fire - await new Promise((resolve) => setTimeout(resolve, 100)); + await tryUntil(() => assert.equal(emitted, true)); await wsProvider.destroy(); - assert.equal(emitted, true); }); }); }); diff --git a/v-next/hardhat/src/internal/builtin-plugins/network-manager/hook-handlers/config.ts b/v-next/hardhat/src/internal/builtin-plugins/network-manager/hook-handlers/config.ts index d7bcea55817..94a79d962c5 100644 --- a/v-next/hardhat/src/internal/builtin-plugins/network-manager/hook-handlers/config.ts +++ b/v-next/hardhat/src/internal/builtin-plugins/network-manager/hook-handlers/config.ts @@ -40,6 +40,7 @@ export async function extendUserConfig( const localhostConfig: NetworkUserConfig | undefined = networks.localhost; const defaultConfig: NetworkUserConfig | undefined = networks.default; + const nodeConfig: NetworkUserConfig | undefined = networks.node; let extendedLocalhostConfig: NetworkUserConfig; if ( @@ -59,6 +60,14 @@ export async function extendUserConfig( extendedLocalhostConfig = localhostConfig; } + const defaultEdrNetworkConfigValues = { + chainId: 31337, + gas: "auto", + gasMultiplier: 1, + gasPrice: "auto", + type: "edr-simulated", + } as const; + let extendedDefaultConfig: NetworkUserConfig; if ( defaultConfig === undefined || @@ -66,11 +75,7 @@ export async function extendUserConfig( defaultConfig.type === "edr-simulated" ) { extendedDefaultConfig = { - chainId: 31337, - gas: "auto", - gasMultiplier: 1, - gasPrice: "auto", - type: "edr-simulated", + ...defaultEdrNetworkConfigValues, /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- We cast it here because otherwise TS complains that some fields are always overwritten, which is not true for js incomplete configs. */ @@ -80,12 +85,30 @@ export async function extendUserConfig( extendedDefaultConfig = defaultConfig; } + let extendedNodeConfig: NetworkUserConfig; + if ( + nodeConfig === undefined || + nodeConfig.type === undefined || + nodeConfig.type === "edr-simulated" + ) { + extendedNodeConfig = { + ...defaultEdrNetworkConfigValues, + /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions + -- We cast it here because otherwise TS complains that url and http will + be always overwritten, which is not true for js incomplete configs. */ + ...(nodeConfig as Partial), + }; + } else { + extendedNodeConfig = nodeConfig; + } + return { ...extendedConfig, networks: { ...networks, localhost: extendedLocalhostConfig, [DEFAULT_NETWORK_NAME]: extendedDefaultConfig, + node: extendedNodeConfig, }, }; } diff --git a/v-next/hardhat/src/internal/builtin-plugins/network-manager/type-validation.ts b/v-next/hardhat/src/internal/builtin-plugins/network-manager/type-validation.ts index 1644579b079..2dfc8098445 100644 --- a/v-next/hardhat/src/internal/builtin-plugins/network-manager/type-validation.ts +++ b/v-next/hardhat/src/internal/builtin-plugins/network-manager/type-validation.ts @@ -344,6 +344,15 @@ function refineEdrNetworkUserConfig( { defaultChainType = GENERIC_CHAIN_TYPE, networks = {} }: HardhatUserConfig, ctx: RefinementCtx, ): void { + const nodeNetwork = networks.node; + if (nodeNetwork !== undefined && nodeNetwork.type !== "edr-simulated") { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + path: ["networks", "node", "type"], + message: "The node network type must be 'edr-simulated'", + }); + } + for (const [networkName, network] of Object.entries(networks)) { if (network.type === "edr-simulated") { const { chainType, hardfork, minGasPrice, initialBaseFeePerGas } = diff --git a/v-next/hardhat/src/internal/builtin-plugins/node/task-action.ts b/v-next/hardhat/src/internal/builtin-plugins/node/task-action.ts index 529d234ad6b..90d87857d3f 100644 --- a/v-next/hardhat/src/internal/builtin-plugins/node/task-action.ts +++ b/v-next/hardhat/src/internal/builtin-plugins/node/task-action.ts @@ -12,7 +12,6 @@ import { ensureDir, exists } from "@nomicfoundation/hardhat-utils/fs"; import chalk from "chalk"; import debug from "debug"; -import { DEFAULT_NETWORK_NAME } from "../../constants.js"; import { isSupportedChainType } from "../../edr/chain-type.js"; import { BUILD_INFO_DIR_NAME } from "../artifacts/artifact-manager.js"; import { EdrProvider } from "../network-manager/edr/edr-provider.js"; @@ -42,7 +41,7 @@ const nodeAction: NewTaskActionFunction = async ( const network = hre.globalOptions.network !== undefined ? hre.globalOptions.network - : DEFAULT_NETWORK_NAME; + : "node"; if (!(network in hre.config.networks)) { throw new HardhatError(HardhatError.ERRORS.CORE.NETWORK.NETWORK_NOT_FOUND, { @@ -64,6 +63,7 @@ const nodeAction: NewTaskActionFunction = async ( } = { network, }; + // NOTE: We create an empty network config override here. We add to it based // on the result of arguments parsing. We can expand the list of arguments // as much as needed. diff --git a/v-next/hardhat/test/internal/builtin-plugins/network-manager/hook-handlers/config.ts b/v-next/hardhat/test/internal/builtin-plugins/network-manager/hook-handlers/config.ts index 48d1587ea6c..34897eae4c8 100644 --- a/v-next/hardhat/test/internal/builtin-plugins/network-manager/hook-handlers/config.ts +++ b/v-next/hardhat/test/internal/builtin-plugins/network-manager/hook-handlers/config.ts @@ -150,6 +150,61 @@ describe("network-manager/hook-handlers/config", () => { "http://localhost:8545", ); }); + + it("should extend the user config with the node network", async () => { + const config: HardhatUserConfig = {}; + const next = async (nextConfig: HardhatUserConfig) => nextConfig; + + const extendedConfig = await extendUserConfig(config, next); + assert.deepEqual(extendedConfig.networks?.node, { + chainId: 31337, + gas: "auto", + gasMultiplier: 1, + gasPrice: "auto", + type: "edr-simulated", + }); + }); + + it("should allow setting other properties of the node network", async () => { + const config: HardhatUserConfig = { + networks: { + node: { + type: "edr-simulated", + chainId: 5555, + }, + }, + }; + const next = async (nextConfig: HardhatUserConfig) => nextConfig; + + const extendedConfig = await extendUserConfig(config, next); + assert.deepEqual(extendedConfig.networks?.node, { + chainId: 5555, + gas: "auto", + gasMultiplier: 1, + gasPrice: "auto", + type: "edr-simulated", + }); + }); + + it("should extend the node network when its type is undefined", async () => { + const config = { + networks: { + node: {}, + }, + }; + const next = async (nextConfig: HardhatUserConfig) => nextConfig; + + /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions + -- testing incomplete config for js users */ + const extendedConfig = await extendUserConfig(config as any, next); + assert.deepEqual(extendedConfig.networks?.node, { + chainId: 31337, + gas: "auto", + gasMultiplier: 1, + gasPrice: "auto", + type: "edr-simulated", + }); + }); }); describe("validateUserConfig", () => { @@ -213,6 +268,26 @@ describe("network-manager/hook-handlers/config", () => { ]); }); + it("should throw if the node network type is not edr-simulated", async () => { + const config = { + networks: { + node: { + type: "http", + url: "http://localhost:8545", + }, + }, + } as const; + + const validationErrors = await validateNetworkUserConfig(config); + + assertValidationErrors(validationErrors, [ + { + path: ["networks", "node", "type"], + message: "The node network type must be 'edr-simulated'", + }, + ]); + }); + it("should throw if the network type is not valid", async () => { const config = { networks: {