Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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,24 +116,40 @@ 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",
},
},
};
} as const;
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);
const extendedConfig = await extendUserConfig(config, 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",
},
},
} as const;
const next = async (nextConfig: HardhatUserConfig) => nextConfig;

const extendedConfig = await extendUserConfig(config, 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 +1384,93 @@ 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(
localhost.type === "edr-simulated",
"The network type should be 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(localhost.allowBlocksWithSameTimestamp, false);
assert.equal(localhost.allowUnlimitedContractSize, false);
assert.equal(localhost.blockGasLimit, 60_000_000n);
assert.deepEqual(localhost.mining, {
auto: true,
interval: 0,
mempool: { order: "priority" },
});
assert.equal(localhost.throwOnCallFailures, true);
assert.equal(localhost.throwOnTransactionFailures, true);
assert.equal(localhost.loggingEnabled, false);
assert.equal(localhost.minGasPrice, 0n);
assert.equal(localhost.networkId, 31337);
assert.equal(localhost.forking, 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