Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/four-lies-flash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"hardhat": patch
---

Allow overriding the type of the network configs `default` and `localhost` [#7805](https://github.com/NomicFoundation/hardhat/pull/7805)
Original file line number Diff line number Diff line change
Expand Up @@ -38,33 +38,54 @@ export async function extendUserConfig(
const networks: Record<string, NetworkUserConfig> =
extendedConfig.networks ?? {};

const localhostConfig: Omit<HttpNetworkUserConfig, "url"> = {
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- This is always http
...(networks.localhost as HttpNetworkUserConfig),
};
const localhostConfig: NetworkUserConfig | undefined = networks.localhost;
const defaultConfig: NetworkUserConfig | undefined = networks.default;

const defaultConfig: Partial<EdrNetworkUserConfig> = {
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- This is always edr
...(networks.default as EdrNetworkUserConfig),
};
let extendedLocalhostConfig: NetworkUserConfig;
if (
localhostConfig === undefined ||
localhostConfig.type === undefined ||
localhostConfig.type === "http"
) {
extendedLocalhostConfig = {
url: "http://localhost:8545",
type: "http",
/* 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. */
...(localhostConfig as Partial<HttpNetworkUserConfig>),
};
} else {
extendedLocalhostConfig = localhostConfig;
}

let extendedDefaultConfig: NetworkUserConfig;
if (
defaultConfig === undefined ||
defaultConfig.type === undefined ||
defaultConfig.type === "edr-simulated"
) {
extendedDefaultConfig = {
chainId: 31337,
gas: "auto",
gasMultiplier: 1,
gasPrice: "auto",
type: "edr-simulated",
/* 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. */
...(defaultConfig as Partial<EdrNetworkUserConfig>),
};
} else {
extendedDefaultConfig = defaultConfig;
}

return {
...extendedConfig,
networks: {
...networks,
localhost: {
url: "http://localhost:8545",
...localhostConfig,
type: "http",
},
[DEFAULT_NETWORK_NAME]: {
chainId: 31337,
gas: "auto",
gasMultiplier: 1,
gasPrice: "auto",
...defaultConfig,
type: "edr-simulated",
},
localhost: extendedLocalhostConfig,
[DEFAULT_NETWORK_NAME]: extendedDefaultConfig,
},
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,43 @@ describe("network-manager/hook-handlers/config", () => {
});
});

it("should extend the localhost network when its type is undefined", async () => {
const config = {
networks: {
localhost: {},
},
};
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?.localhost, {
type: "http",
url: "http://localhost:8545",
});
});

it("should extend the default network when its type is undefined", async () => {
const config = {
networks: {
default: {},
},
};
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?.default, {
chainId: 31337,
gas: "auto",
gasMultiplier: 1,
gasPrice: "auto",
type: "edr-simulated",
});
});

it("should allow setting other properties of the localhost network", async () => {
const config: HardhatUserConfig = {
networks: {
Expand Down Expand Up @@ -79,11 +116,11 @@ describe("network-manager/hook-handlers/config", () => {
});
});

it("should not allow overriding the type of the localhost network", async () => {
it("should allow overriding the type of the localhost network", async () => {
Comment thread
alcuadrado marked this conversation as resolved.
const config = {
networks: {
localhost: {
type: "http2",
type: "edr-simulated",
},
},
};
Expand All @@ -93,10 +130,30 @@ describe("network-manager/hook-handlers/config", () => {
-- testing invalid network type for js users */
const extendedConfig = await extendUserConfig(config as any, next);
assert.deepEqual(extendedConfig.networks?.localhost, {
url: "http://localhost:8545",
type: "http",
type: "edr-simulated",
});
});

it("should allow overriding the type of the default network", async () => {
Comment thread
alcuadrado marked this conversation as resolved.
const config = {
networks: {
default: {
type: "http",
url: "http://localhost:8545",
},
},
};
const next = async (nextConfig: HardhatUserConfig) => nextConfig;

/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions
-- testing invalid network type for js users */
const extendedConfig = await extendUserConfig(config as any, next);
assert.equal(extendedConfig.networks?.default.type, "http");
assert.equal(
extendedConfig.networks?.default.url,
"http://localhost:8545",
);
});
});

describe("validateUserConfig", () => {
Expand Down Expand Up @@ -1331,6 +1388,113 @@ describe("network-manager/hook-handlers/config", () => {
});
});

it("should resolve the localhost network when its type is overridden to edr-simulated", async () => {
// This is how the user config looks like after it's been extended
// by the extendUserConfig hook handler when the user overrides
// the localhost network type to "edr-simulated".
const extendedConfig: HardhatUserConfig = {
paths: {
cache: "/tmp/hardhat-cache",
},
networks: {
localhost: {
type: "edr-simulated",
},
},
};

const resolvedConfig = await resolveUserConfig(
extendedConfig,
(variable) => resolveConfigurationVariable(hre.hooks, variable),
next,
);

const localhost = resolvedConfig.networks.localhost;
assert.equal(localhost.type, "edr-simulated");
assert.equal(localhost.chainId, 31337);
assert.equal(localhost.chainType, undefined);
assert.equal(localhost.from, undefined);
assert.equal(localhost.gas, "auto");
assert.equal(localhost.gasMultiplier, 1);
assert.equal(localhost.gasPrice, "auto");

// EDR-specific fields
assert.equal(
"allowBlocksWithSameTimestamp" in localhost &&
localhost.allowBlocksWithSameTimestamp,
false,
);
assert.equal(
"allowUnlimitedContractSize" in localhost &&
localhost.allowUnlimitedContractSize,
false,
);
assert.equal(
"blockGasLimit" in localhost && localhost.blockGasLimit,
60_000_000n,
);
assert.deepEqual("mining" in localhost && localhost.mining, {
auto: true,
interval: 0,
mempool: { order: "priority" },
});
assert.equal(
"throwOnCallFailures" in localhost && localhost.throwOnCallFailures,
true,
);
assert.equal(
"throwOnTransactionFailures" in localhost &&
localhost.throwOnTransactionFailures,
true,
);
assert.equal(
"loggingEnabled" in localhost && localhost.loggingEnabled,
false,
);
assert.equal("minGasPrice" in localhost && localhost.minGasPrice, 0n);
assert.equal("networkId" in localhost && localhost.networkId, 31337);
assert.equal(
"forking" in localhost ? localhost.forking : undefined,
undefined,
);
});

it("should resolve the default network when its type is overridden to http", async () => {
// This is how the user config looks like after it's been extended
// by the extendUserConfig hook handler when the user overrides
// the default network type to "http".
const extendedConfig: HardhatUserConfig = {
networks: {
default: {
type: "http",
url: "http://localhost:8545",
},
},
};

const resolvedConfig = await resolveUserConfig(
extendedConfig,
(variable) => resolveConfigurationVariable(hre.hooks, variable),
next,
);

assert.deepEqual(resolvedConfig.networks, {
default: {
type: "http",
chainId: undefined,
chainType: undefined,
from: undefined,
gas: "auto",
gasMultiplier: 1,
gasPrice: "auto",
accounts: "remote",
url: new FixedValueConfigurationVariable("http://localhost:8545"),
timeout: 300_000,
httpHeaders: {},
},
});
});

describe("accounts", () => {
it("should normalize the accounts' private keys", async () => {
const userConfig: HardhatUserConfig = {
Expand Down