Skip to content

Commit dbdbd35

Browse files
committed
fix: don't merge class instances and add tests
1 parent 9ca7f5a commit dbdbd35

File tree

2 files changed

+103
-45
lines changed

2 files changed

+103
-45
lines changed

v-next/hardhat/src/internal/builtin-plugins/network-manager/config-override.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,11 @@ export function mergeConfigOverride<T extends object>(
7575
const result = { ...target };
7676

7777
for (const key in source) {
78-
if (isObject(source[key])) {
78+
if (
79+
isObject(source[key]) &&
80+
// Only merge recursively objects that are not class instances
81+
Object.getPrototypeOf(source[key]) === Object.prototype
82+
) {
7983
/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions
8084
-- result[key] is either an object or undefined, so we default it to {} */
8185
result[key] = mergeConfigOverride(

v-next/hardhat/test/internal/builtin-plugins/network-manager/network-manager.ts

+98-44
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type {
66
NetworkManager,
77
} from "../../../../src/types/network.js";
88
import type {
9+
EdrNetworkConfigOverride,
910
HttpNetworkConfigOverride,
1011
NetworkConfig,
1112
} from "@ignored/hardhat-vnext/types/config";
@@ -18,62 +19,69 @@ import { assertRejectsWithHardhatError } from "@nomicfoundation/hardhat-test-uti
1819
import { expectTypeOf } from "expect-type";
1920

2021
import { createHardhatRuntimeEnvironment } from "../../../../src/hre.js";
22+
import {
23+
resolveEdrNetwork,
24+
resolveHttpNetwork,
25+
} from "../../../../src/internal/builtin-plugins/network-manager/config-resolution.js";
2126
import { NetworkManagerImplementation } from "../../../../src/internal/builtin-plugins/network-manager/network-manager.js";
2227
import { validateNetworkUserConfig } from "../../../../src/internal/builtin-plugins/network-manager/type-validation.js";
2328
import {
2429
GENERIC_CHAIN_TYPE,
2530
L1_CHAIN_TYPE,
2631
OPTIMISM_CHAIN_TYPE,
2732
} from "../../../../src/internal/constants.js";
28-
import { FixedValueConfigurationVariable } from "../../../../src/internal/core/configuration-variables.js";
33+
import {
34+
FixedValueConfigurationVariable,
35+
resolveConfigurationVariable,
36+
} from "../../../../src/internal/core/configuration-variables.js";
2937

3038
describe("NetworkManagerImplementation", () => {
3139
let hre: HardhatRuntimeEnvironment;
3240
let networkManager: NetworkManager;
33-
const networks: Record<string, NetworkConfig> = {
34-
localhost: {
35-
type: "http",
36-
chainId: undefined,
37-
chainType: undefined,
38-
from: undefined,
39-
gas: "auto",
40-
gasMultiplier: 1,
41-
gasPrice: "auto",
42-
accounts: [],
43-
url: new FixedValueConfigurationVariable("http://localhost:8545"),
44-
timeout: 20_000,
45-
httpHeaders: {},
46-
},
47-
customNetwork: {
48-
type: "http",
49-
chainId: undefined,
50-
chainType: undefined,
51-
from: undefined,
52-
gas: "auto",
53-
gasMultiplier: 1,
54-
gasPrice: "auto",
55-
accounts: [],
56-
url: new FixedValueConfigurationVariable("http://node.customNetwork.com"),
57-
timeout: 20_000,
58-
httpHeaders: {},
59-
},
60-
myNetwork: {
61-
type: "http",
62-
chainId: undefined,
63-
chainType: OPTIMISM_CHAIN_TYPE,
64-
from: undefined,
65-
gas: "auto",
66-
gasMultiplier: 1,
67-
gasPrice: "auto",
68-
accounts: [],
69-
url: new FixedValueConfigurationVariable("http://node.myNetwork.com"),
70-
timeout: 20_000,
71-
httpHeaders: {},
72-
},
73-
};
41+
let networks: Record<string, NetworkConfig>;
7442

7543
before(async () => {
7644
hre = await createHardhatRuntimeEnvironment({});
45+
46+
networks = {
47+
localhost: resolveHttpNetwork(
48+
{
49+
type: "http",
50+
url: "http://localhost:8545",
51+
},
52+
(varOrStr) => resolveConfigurationVariable(hre.hooks, varOrStr),
53+
),
54+
customNetwork: resolveHttpNetwork(
55+
{
56+
type: "http",
57+
url: "http://node.customNetwork.com",
58+
},
59+
(varOrStr) => resolveConfigurationVariable(hre.hooks, varOrStr),
60+
),
61+
myNetwork: resolveHttpNetwork(
62+
{
63+
type: "http",
64+
chainType: OPTIMISM_CHAIN_TYPE,
65+
url: "http://node.myNetwork.com",
66+
},
67+
(varOrStr) => resolveConfigurationVariable(hre.hooks, varOrStr),
68+
),
69+
edrNetwork: resolveEdrNetwork(
70+
{
71+
type: "edr",
72+
chainType: OPTIMISM_CHAIN_TYPE,
73+
mining: {
74+
auto: true,
75+
mempool: {
76+
order: "priority",
77+
},
78+
},
79+
},
80+
"",
81+
(varOrStr) => resolveConfigurationVariable(hre.hooks, varOrStr),
82+
),
83+
};
84+
7785
networkManager = new NetworkManagerImplementation(
7886
"localhost",
7987
GENERIC_CHAIN_TYPE,
@@ -116,10 +124,10 @@ describe("NetworkManagerImplementation", () => {
116124

117125
it("should override the network's chain config with the specified chain config", async () => {
118126
const httpConfigOverride: HttpNetworkConfigOverride = {
119-
chainId: 1234,
127+
chainId: 1234, // optional in the resolved config
120128
timeout: 30_000, // specific to http networks
121129
};
122-
const networkConnection = await networkManager.connect(
130+
let networkConnection = await networkManager.connect(
123131
"myNetwork",
124132
OPTIMISM_CHAIN_TYPE,
125133
httpConfigOverride,
@@ -130,6 +138,52 @@ describe("NetworkManagerImplementation", () => {
130138
...networks.myNetwork,
131139
...httpConfigOverride,
132140
});
141+
142+
// Overriding the url is handled differently
143+
// so we need to test it separately
144+
networkConnection = await networkManager.connect(
145+
"myNetwork",
146+
OPTIMISM_CHAIN_TYPE,
147+
{
148+
url: "http://localhost:8545",
149+
},
150+
);
151+
assert.equal(networkConnection.networkName, "myNetwork");
152+
assert.equal(networkConnection.chainType, OPTIMISM_CHAIN_TYPE);
153+
assert.deepEqual(networkConnection.networkConfig, {
154+
...networks.myNetwork,
155+
url: new FixedValueConfigurationVariable("http://localhost:8545"),
156+
});
157+
});
158+
159+
it("should override the network's chain config with the specified chain config recursively", async () => {
160+
const edrConfigOverride: EdrNetworkConfigOverride = {
161+
mining: {
162+
mempool: {
163+
order: "fifo",
164+
},
165+
},
166+
};
167+
const networkConnection = await networkManager.connect(
168+
"edrNetwork",
169+
OPTIMISM_CHAIN_TYPE,
170+
edrConfigOverride,
171+
);
172+
assert.equal(networkConnection.networkName, "edrNetwork");
173+
assert.equal(networkConnection.chainType, OPTIMISM_CHAIN_TYPE);
174+
assert.equal(networks.edrNetwork.type, "edr"); // this is for the type assertion
175+
assert.deepEqual(networkConnection.networkConfig, {
176+
...networks.edrNetwork,
177+
...edrConfigOverride,
178+
mining: {
179+
...networks.edrNetwork.mining,
180+
...edrConfigOverride.mining,
181+
mempool: {
182+
...networks.edrNetwork.mining.mempool,
183+
...edrConfigOverride.mining?.mempool,
184+
},
185+
},
186+
});
133187
});
134188

135189
it("should throw an error if the specified network doesn't exist", async () => {

0 commit comments

Comments
 (0)