hardhat 3.0.5 → 3.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/dist/src/internal/builtin-plugins/coverage/hook-handlers/solidity.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/coverage/hook-handlers/solidity.js +1 -2
- package/dist/src/internal/builtin-plugins/coverage/hook-handlers/solidity.js.map +1 -1
- package/dist/src/internal/builtin-plugins/network-manager/edr/edr-provider.d.ts +1 -0
- package/dist/src/internal/builtin-plugins/network-manager/edr/edr-provider.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/network-manager/edr/edr-provider.js +9 -2
- package/dist/src/internal/builtin-plugins/network-manager/edr/edr-provider.js.map +1 -1
- package/dist/src/internal/builtin-plugins/network-manager/hook-handlers/hre.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/network-manager/hook-handlers/hre.js +13 -5
- package/dist/src/internal/builtin-plugins/network-manager/hook-handlers/hre.js.map +1 -1
- package/dist/src/internal/builtin-plugins/network-manager/hook-handlers/network.js +1 -1
- package/dist/src/internal/builtin-plugins/network-manager/hook-handlers/network.js.map +1 -1
- package/dist/src/internal/builtin-plugins/network-manager/network-manager.d.ts +4 -3
- package/dist/src/internal/builtin-plugins/network-manager/network-manager.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/network-manager/network-manager.js +79 -37
- package/dist/src/internal/builtin-plugins/network-manager/network-manager.js.map +1 -1
- package/dist/src/internal/builtin-plugins/network-manager/type-validation.js +2 -2
- package/dist/src/internal/builtin-plugins/network-manager/type-validation.js.map +1 -1
- package/dist/src/internal/builtin-plugins/node/artifacts/build-info-watcher.d.ts +25 -0
- package/dist/src/internal/builtin-plugins/node/artifacts/build-info-watcher.d.ts.map +1 -0
- package/dist/src/internal/builtin-plugins/node/artifacts/build-info-watcher.js +56 -0
- package/dist/src/internal/builtin-plugins/node/artifacts/build-info-watcher.js.map +1 -0
- package/dist/src/internal/builtin-plugins/node/helpers.d.ts +12 -0
- package/dist/src/internal/builtin-plugins/node/helpers.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/node/helpers.js +32 -0
- package/dist/src/internal/builtin-plugins/node/helpers.js.map +1 -1
- package/dist/src/internal/builtin-plugins/node/json-rpc/server.d.ts +3 -10
- package/dist/src/internal/builtin-plugins/node/json-rpc/server.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/node/json-rpc/server.js +1 -1
- package/dist/src/internal/builtin-plugins/node/json-rpc/server.js.map +1 -1
- package/dist/src/internal/builtin-plugins/node/task-action.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/node/task-action.js +14 -4
- package/dist/src/internal/builtin-plugins/node/task-action.js.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity/build-system/build-system.d.ts +13 -5
- package/dist/src/internal/builtin-plugins/solidity/build-system/build-system.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity/build-system/build-system.js +126 -58
- package/dist/src/internal/builtin-plugins/solidity/build-system/build-system.js.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity/build-system/cache.d.ts +1 -1
- package/dist/src/internal/builtin-plugins/solidity/build-system/cache.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity/hook-handlers/hre.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity/hook-handlers/hre.js +14 -6
- package/dist/src/internal/builtin-plugins/solidity/hook-handlers/hre.js.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity/index.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity/index.js +8 -0
- package/dist/src/internal/builtin-plugins/solidity/index.js.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity/tasks/build.d.ts +4 -2
- package/dist/src/internal/builtin-plugins/solidity/tasks/build.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity/tasks/build.js +37 -10
- package/dist/src/internal/builtin-plugins/solidity/tasks/build.js.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity-test/config.d.ts +4 -2
- package/dist/src/internal/builtin-plugins/solidity-test/config.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity-test/config.js +24 -4
- package/dist/src/internal/builtin-plugins/solidity-test/config.js.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity-test/helpers.d.ts +3 -1
- package/dist/src/internal/builtin-plugins/solidity-test/helpers.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity-test/helpers.js +26 -3
- package/dist/src/internal/builtin-plugins/solidity-test/helpers.js.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity-test/hook-handlers/config.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity-test/hook-handlers/config.js +1 -1
- package/dist/src/internal/builtin-plugins/solidity-test/hook-handlers/config.js.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity-test/task-action.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity-test/task-action.js +26 -43
- package/dist/src/internal/builtin-plugins/solidity-test/task-action.js.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity-test/type-extensions.d.ts +17 -7
- package/dist/src/internal/builtin-plugins/solidity-test/type-extensions.d.ts.map +1 -1
- package/dist/src/internal/core/hre.d.ts +29 -1
- package/dist/src/internal/core/hre.d.ts.map +1 -1
- package/dist/src/internal/core/hre.js +57 -20
- package/dist/src/internal/core/hre.js.map +1 -1
- package/dist/src/internal/core/plugins/resolve-plugin-list.js +40 -3
- package/dist/src/internal/core/plugins/resolve-plugin-list.js.map +1 -1
- package/dist/src/internal/utils/package.d.ts +1 -0
- package/dist/src/internal/utils/package.d.ts.map +1 -1
- package/dist/src/internal/utils/package.js +17 -1
- package/dist/src/internal/utils/package.js.map +1 -1
- package/dist/src/types/hre.d.ts +4 -0
- package/dist/src/types/hre.d.ts.map +1 -1
- package/dist/src/types/network.d.ts +40 -0
- package/dist/src/types/network.d.ts.map +1 -1
- package/dist/src/types/plugins.d.ts +8 -0
- package/dist/src/types/plugins.d.ts.map +1 -1
- package/dist/src/types/solidity/build-system.d.ts +23 -8
- package/dist/src/types/solidity/build-system.d.ts.map +1 -1
- package/package.json +5 -4
- package/src/internal/builtin-plugins/coverage/hook-handlers/solidity.ts +2 -3
- package/src/internal/builtin-plugins/network-manager/edr/edr-provider.ts +20 -1
- package/src/internal/builtin-plugins/network-manager/hook-handlers/hre.ts +36 -18
- package/src/internal/builtin-plugins/network-manager/hook-handlers/network.ts +1 -1
- package/src/internal/builtin-plugins/network-manager/network-manager.ts +137 -60
- package/src/internal/builtin-plugins/network-manager/type-validation.ts +2 -2
- package/src/internal/builtin-plugins/node/artifacts/build-info-watcher.ts +82 -0
- package/src/internal/builtin-plugins/node/helpers.ts +64 -0
- package/src/internal/builtin-plugins/node/json-rpc/server.ts +3 -10
- package/src/internal/builtin-plugins/node/task-action.ts +31 -5
- package/src/internal/builtin-plugins/solidity/build-system/build-system.ts +203 -98
- package/src/internal/builtin-plugins/solidity/build-system/cache.ts +1 -1
- package/src/internal/builtin-plugins/solidity/hook-handlers/hre.ts +22 -5
- package/src/internal/builtin-plugins/solidity/index.ts +8 -0
- package/src/internal/builtin-plugins/solidity/tasks/build.ts +59 -16
- package/src/internal/builtin-plugins/solidity-test/config.ts +46 -3
- package/src/internal/builtin-plugins/solidity-test/helpers.ts +44 -4
- package/src/internal/builtin-plugins/solidity-test/hook-handlers/config.ts +5 -1
- package/src/internal/builtin-plugins/solidity-test/task-action.ts +39 -54
- package/src/internal/builtin-plugins/solidity-test/type-extensions.ts +23 -9
- package/src/internal/core/hre.ts +102 -32
- package/src/internal/core/plugins/resolve-plugin-list.ts +57 -3
- package/src/internal/utils/package.ts +31 -1
- package/src/types/hre.ts +4 -0
- package/src/types/network.ts +45 -0
- package/src/types/plugins.ts +5 -0
- package/src/types/solidity/build-system.ts +23 -7
- package/templates/hardhat-3/01-node-test-runner-viem/package.json +3 -3
- package/templates/hardhat-3/02-mocha-ethers/package.json +4 -4
|
@@ -2,36 +2,40 @@ import type { CoverageConfig } from "./edr/types/coverage.js";
|
|
|
2
2
|
import type { ArtifactManager } from "../../../types/artifacts.js";
|
|
3
3
|
import type {
|
|
4
4
|
ChainDescriptorsConfig,
|
|
5
|
+
HardhatUserConfig,
|
|
5
6
|
NetworkConfig,
|
|
6
7
|
NetworkConfigOverride,
|
|
7
|
-
NetworkUserConfig,
|
|
8
8
|
} from "../../../types/config.js";
|
|
9
9
|
import type { HookManager } from "../../../types/hooks.js";
|
|
10
10
|
import type {
|
|
11
11
|
ChainType,
|
|
12
12
|
DefaultChainType,
|
|
13
|
+
JsonRpcServer,
|
|
13
14
|
NetworkConnection,
|
|
14
15
|
NetworkConnectionParams,
|
|
15
16
|
NetworkManager,
|
|
16
17
|
} from "../../../types/network.js";
|
|
18
|
+
import type { HardhatPlugin } from "../../../types/plugins.js";
|
|
17
19
|
import type {
|
|
18
20
|
EthereumProvider,
|
|
19
21
|
JsonRpcRequest,
|
|
20
22
|
JsonRpcResponse,
|
|
21
23
|
} from "../../../types/providers.js";
|
|
22
24
|
|
|
23
|
-
import {
|
|
24
|
-
|
|
25
|
+
import {
|
|
26
|
+
HardhatError,
|
|
27
|
+
assertHardhatInvariant,
|
|
28
|
+
} from "@nomicfoundation/hardhat-errors";
|
|
29
|
+
import { exists, readBinaryFile } from "@nomicfoundation/hardhat-utils/fs";
|
|
25
30
|
import { deepMerge } from "@nomicfoundation/hardhat-utils/lang";
|
|
26
31
|
|
|
27
|
-
import {
|
|
32
|
+
import { resolveUserConfigToHardhatConfig } from "../../core/hre.js";
|
|
28
33
|
import { isSupportedChainType } from "../../edr/chain-type.js";
|
|
34
|
+
import { JsonRpcServerImplementation } from "../node/json-rpc/server.js";
|
|
29
35
|
|
|
30
|
-
import { resolveEdrNetwork, resolveHttpNetwork } from "./config-resolution.js";
|
|
31
36
|
import { EdrProvider } from "./edr/edr-provider.js";
|
|
32
37
|
import { HttpProvider } from "./http-provider.js";
|
|
33
38
|
import { NetworkConnectionImplementation } from "./network-connection.js";
|
|
34
|
-
import { validateNetworkConfigOverride } from "./type-validation.js";
|
|
35
39
|
|
|
36
40
|
export type JsonRpcRequestWrapperFunction = (
|
|
37
41
|
request: JsonRpcRequest,
|
|
@@ -44,8 +48,10 @@ export class NetworkManagerImplementation implements NetworkManager {
|
|
|
44
48
|
readonly #networkConfigs: Readonly<Record<string, Readonly<NetworkConfig>>>;
|
|
45
49
|
readonly #hookManager: Readonly<HookManager>;
|
|
46
50
|
readonly #artifactsManager: Readonly<ArtifactManager>;
|
|
47
|
-
readonly #
|
|
51
|
+
readonly #userConfig: Readonly<HardhatUserConfig>;
|
|
48
52
|
readonly #chainDescriptors: Readonly<ChainDescriptorsConfig>;
|
|
53
|
+
readonly #userProvidedConfigPath: Readonly<string | undefined>;
|
|
54
|
+
readonly #projectRoot: string;
|
|
49
55
|
|
|
50
56
|
#nextConnectionId = 0;
|
|
51
57
|
|
|
@@ -55,16 +61,20 @@ export class NetworkManagerImplementation implements NetworkManager {
|
|
|
55
61
|
networkConfigs: Record<string, NetworkConfig>,
|
|
56
62
|
hookManager: HookManager,
|
|
57
63
|
artifactsManager: ArtifactManager,
|
|
58
|
-
|
|
64
|
+
userConfig: HardhatUserConfig,
|
|
59
65
|
chainDescriptors: ChainDescriptorsConfig,
|
|
66
|
+
userProvidedConfigPath: string | undefined,
|
|
67
|
+
projectRoot: string,
|
|
60
68
|
) {
|
|
61
69
|
this.#defaultNetwork = defaultNetwork;
|
|
62
70
|
this.#defaultChainType = defaultChainType;
|
|
63
71
|
this.#networkConfigs = networkConfigs;
|
|
64
72
|
this.#hookManager = hookManager;
|
|
65
73
|
this.#artifactsManager = artifactsManager;
|
|
66
|
-
this.#
|
|
74
|
+
this.#userConfig = userConfig;
|
|
67
75
|
this.#chainDescriptors = chainDescriptors;
|
|
76
|
+
this.#userProvidedConfigPath = userProvidedConfigPath;
|
|
77
|
+
this.#projectRoot = projectRoot;
|
|
68
78
|
}
|
|
69
79
|
|
|
70
80
|
public async connect<
|
|
@@ -97,6 +107,23 @@ export class NetworkManagerImplementation implements NetworkManager {
|
|
|
97
107
|
return networkConnection as NetworkConnection<ChainTypeT>;
|
|
98
108
|
}
|
|
99
109
|
|
|
110
|
+
public async createServer(
|
|
111
|
+
networkOrParams: NetworkConnectionParams | string = "default",
|
|
112
|
+
_hostname?: string,
|
|
113
|
+
port?: number,
|
|
114
|
+
): Promise<JsonRpcServer> {
|
|
115
|
+
const insideDocker = await exists("/.dockerenv");
|
|
116
|
+
const hostname = _hostname ?? (insideDocker ? "0.0.0.0" : "127.0.0.1");
|
|
117
|
+
|
|
118
|
+
const { provider } = await this.connect(networkOrParams);
|
|
119
|
+
|
|
120
|
+
return new JsonRpcServerImplementation({
|
|
121
|
+
hostname,
|
|
122
|
+
port,
|
|
123
|
+
provider,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
|
|
100
127
|
async #initializeNetworkConnection<ChainTypeT extends ChainType | string>(
|
|
101
128
|
networkName?: string,
|
|
102
129
|
chainType?: ChainTypeT,
|
|
@@ -113,57 +140,10 @@ export class NetworkManagerImplementation implements NetworkManager {
|
|
|
113
140
|
);
|
|
114
141
|
}
|
|
115
142
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
networkConfigOverride.type !==
|
|
121
|
-
this.#networkConfigs[resolvedNetworkName].type
|
|
122
|
-
) {
|
|
123
|
-
throw new HardhatError(
|
|
124
|
-
HardhatError.ERRORS.CORE.NETWORK.INVALID_CONFIG_OVERRIDE,
|
|
125
|
-
{
|
|
126
|
-
errors: `\t* The type of the network cannot be changed.`,
|
|
127
|
-
},
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const newConfig = deepMerge(
|
|
132
|
-
this.#userConfigNetworks[resolvedNetworkName],
|
|
133
|
-
networkConfigOverride,
|
|
134
|
-
);
|
|
135
|
-
|
|
136
|
-
// As normalizeNetworkConfigOverride is not type-safe, we validate the
|
|
137
|
-
// normalized network config override immediately after normalizing it.
|
|
138
|
-
const validationErrors = await validateNetworkConfigOverride(newConfig);
|
|
139
|
-
if (validationErrors.length > 0) {
|
|
140
|
-
throw new HardhatError(
|
|
141
|
-
HardhatError.ERRORS.CORE.NETWORK.INVALID_CONFIG_OVERRIDE,
|
|
142
|
-
{
|
|
143
|
-
errors: `\t${validationErrors
|
|
144
|
-
.map((error) =>
|
|
145
|
-
error.path.length > 0
|
|
146
|
-
? `* Error in ${error.path.join(".")}: ${error.message}`
|
|
147
|
-
: `* ${error.message}`,
|
|
148
|
-
)
|
|
149
|
-
.join("\n\t")}`,
|
|
150
|
-
},
|
|
151
|
-
);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
resolvedNetworkConfigOverride =
|
|
155
|
-
newConfig.type === "http"
|
|
156
|
-
? resolveHttpNetwork(newConfig, (strOrConfigVar) =>
|
|
157
|
-
resolveConfigurationVariable(this.#hookManager, strOrConfigVar),
|
|
158
|
-
)
|
|
159
|
-
: resolveEdrNetwork(newConfig, "", (strOrConfigVar) =>
|
|
160
|
-
resolveConfigurationVariable(this.#hookManager, strOrConfigVar),
|
|
161
|
-
);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
const resolvedNetworkConfig =
|
|
165
|
-
resolvedNetworkConfigOverride ??
|
|
166
|
-
this.#networkConfigs[resolvedNetworkName];
|
|
143
|
+
const resolvedNetworkConfig = await this.#resolveNetworkConfig(
|
|
144
|
+
resolvedNetworkName,
|
|
145
|
+
networkConfigOverride,
|
|
146
|
+
);
|
|
167
147
|
|
|
168
148
|
/* eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
169
149
|
-- Cast to ChainTypeT because we know it's valid */
|
|
@@ -293,6 +273,88 @@ export class NetworkManagerImplementation implements NetworkManager {
|
|
|
293
273
|
);
|
|
294
274
|
}
|
|
295
275
|
|
|
276
|
+
/**
|
|
277
|
+
* Resolve the network connection configuration settings for the network name
|
|
278
|
+
* and taking into account any configuration overrides.
|
|
279
|
+
*
|
|
280
|
+
* @param resolvedNetworkName the network name for selecting the appropriate network config
|
|
281
|
+
* @param networkConfigOverride any network config options to override the
|
|
282
|
+
* defaults for the named network
|
|
283
|
+
* @returns a valid network configuration including any config additions from
|
|
284
|
+
* plugins
|
|
285
|
+
*/
|
|
286
|
+
async #resolveNetworkConfig(
|
|
287
|
+
resolvedNetworkName: string,
|
|
288
|
+
networkConfigOverride: NetworkConfigOverride | undefined,
|
|
289
|
+
): Promise<NetworkConfig> {
|
|
290
|
+
if (networkConfigOverride === undefined) {
|
|
291
|
+
return this.#networkConfigs[resolvedNetworkName];
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (
|
|
295
|
+
"type" in networkConfigOverride &&
|
|
296
|
+
networkConfigOverride.type !==
|
|
297
|
+
this.#networkConfigs[resolvedNetworkName].type
|
|
298
|
+
) {
|
|
299
|
+
throw new HardhatError(
|
|
300
|
+
HardhatError.ERRORS.CORE.NETWORK.INVALID_CONFIG_OVERRIDE,
|
|
301
|
+
{
|
|
302
|
+
errors: `\t* The type of the network cannot be changed.`,
|
|
303
|
+
},
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
const newConfig = deepMerge(this.#userConfig, {
|
|
308
|
+
networks: {
|
|
309
|
+
[resolvedNetworkName]: networkConfigOverride,
|
|
310
|
+
},
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
// This is safe, the plugins used in resolution are registered
|
|
314
|
+
// with the hook handler, this property is only used for
|
|
315
|
+
// ensuring the original plugins are available at the end
|
|
316
|
+
// of resolution.
|
|
317
|
+
const resolvedPlugins: HardhatPlugin[] = [];
|
|
318
|
+
|
|
319
|
+
const configResolutionResult = await resolveUserConfigToHardhatConfig(
|
|
320
|
+
newConfig,
|
|
321
|
+
this.#hookManager,
|
|
322
|
+
this.#projectRoot,
|
|
323
|
+
this.#userProvidedConfigPath,
|
|
324
|
+
resolvedPlugins,
|
|
325
|
+
);
|
|
326
|
+
|
|
327
|
+
if (!configResolutionResult.success) {
|
|
328
|
+
throw new HardhatError(
|
|
329
|
+
HardhatError.ERRORS.CORE.NETWORK.INVALID_CONFIG_OVERRIDE,
|
|
330
|
+
{
|
|
331
|
+
errors: `\t${configResolutionResult.userConfigValidationErrors
|
|
332
|
+
.map((error) => {
|
|
333
|
+
const path = this.#normaliseErrorPathToNetworkConfig(
|
|
334
|
+
error.path,
|
|
335
|
+
resolvedNetworkName,
|
|
336
|
+
);
|
|
337
|
+
|
|
338
|
+
return path.length > 0
|
|
339
|
+
? `* Error in ${path.join(".")}: ${error.message}`
|
|
340
|
+
: `* ${error.message}`;
|
|
341
|
+
})
|
|
342
|
+
.join("\n\t")}`,
|
|
343
|
+
},
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
const resolvedNetworkConfigOverride =
|
|
348
|
+
configResolutionResult.config.networks[resolvedNetworkName];
|
|
349
|
+
|
|
350
|
+
assertHardhatInvariant(
|
|
351
|
+
resolvedNetworkConfigOverride !== undefined,
|
|
352
|
+
"The overridden network config should translate through the hook resolution of user config",
|
|
353
|
+
);
|
|
354
|
+
|
|
355
|
+
return resolvedNetworkConfigOverride;
|
|
356
|
+
}
|
|
357
|
+
|
|
296
358
|
async #getBuildInfosAndOutputsAsBuffers(): Promise<
|
|
297
359
|
Array<{ buildInfo: Uint8Array; output: Uint8Array }>
|
|
298
360
|
> {
|
|
@@ -315,4 +377,19 @@ export class NetworkManagerImplementation implements NetworkManager {
|
|
|
315
377
|
|
|
316
378
|
return results;
|
|
317
379
|
}
|
|
380
|
+
|
|
381
|
+
#normaliseErrorPathToNetworkConfig(
|
|
382
|
+
path: Array<string | number>,
|
|
383
|
+
resolvedNetworkName: string,
|
|
384
|
+
): Array<string | number> {
|
|
385
|
+
if (path[0] !== undefined && path[0] === "networks") {
|
|
386
|
+
path = path.slice(1);
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
if (path[0] !== undefined && path[0] === resolvedNetworkName) {
|
|
390
|
+
path = path.slice(1);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
return path;
|
|
394
|
+
}
|
|
318
395
|
}
|
|
@@ -404,8 +404,8 @@ const userConfigSchema = z.object({
|
|
|
404
404
|
|
|
405
405
|
const networkConfigOverrideSchema = z
|
|
406
406
|
.discriminatedUnion("type", [
|
|
407
|
-
httpNetworkUserConfigSchema.
|
|
408
|
-
edrNetworkUserConfigSchema.
|
|
407
|
+
httpNetworkUserConfigSchema.passthrough(),
|
|
408
|
+
edrNetworkUserConfigSchema.passthrough(),
|
|
409
409
|
])
|
|
410
410
|
.superRefine(refineEdrNetworkUserConfig);
|
|
411
411
|
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { FSWatcher } from "chokidar";
|
|
2
|
+
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
|
|
5
|
+
import debug from "debug";
|
|
6
|
+
|
|
7
|
+
export type BuildInfoWatcher = FSWatcher;
|
|
8
|
+
export type BuildInfoHandler = (buildId: string) => Promise<void>;
|
|
9
|
+
|
|
10
|
+
const log = debug("hardhat:core:tasks:node:artifacts");
|
|
11
|
+
|
|
12
|
+
const STABILITY_THRESHOLD = 250;
|
|
13
|
+
const POLL_INTERVAL = 50;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* `listener` is a callback function invoked when a new file is added to the
|
|
17
|
+
* build info directory. It processes the received event to check whether it is
|
|
18
|
+
* for a build info file.
|
|
19
|
+
*
|
|
20
|
+
* If so, it extracts the build id from it and triggers the provided handler
|
|
21
|
+
* with the extracted build id as an argument. Any errors encountered during
|
|
22
|
+
* handler execution are captured and logged.
|
|
23
|
+
*
|
|
24
|
+
* @param absolutePath - The absolute path of the file added to the build info directory.
|
|
25
|
+
*
|
|
26
|
+
* This function is exposed for testing purposes only.
|
|
27
|
+
*/
|
|
28
|
+
export async function listener(
|
|
29
|
+
handler: BuildInfoHandler,
|
|
30
|
+
absolutePath: string,
|
|
31
|
+
): Promise<void> {
|
|
32
|
+
log(`Detected change in ${absolutePath}`);
|
|
33
|
+
|
|
34
|
+
const isBuildInfoFile =
|
|
35
|
+
absolutePath.endsWith(".json") && !absolutePath.endsWith(".output.json");
|
|
36
|
+
|
|
37
|
+
if (!isBuildInfoFile) {
|
|
38
|
+
log(`File ${absolutePath} is not a build info file`);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const buildId = path.basename(absolutePath).replace(".json", "");
|
|
43
|
+
|
|
44
|
+
await handler(buildId).catch(async (error: unknown) => {
|
|
45
|
+
log(
|
|
46
|
+
`There was a problem executing the handler for build ${buildId}.`,
|
|
47
|
+
error,
|
|
48
|
+
);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* `watchBuildInfo` is a function that creates a watch over provided build info
|
|
54
|
+
* directory. If it encounters a build info file being added, it will trigger
|
|
55
|
+
* the provided handler, passing the build id as an argument. This allows for
|
|
56
|
+
* further processing or actions to be taken upon completion of a build.
|
|
57
|
+
*/
|
|
58
|
+
export async function watchBuildInfo(
|
|
59
|
+
buildInfoDirPath: string,
|
|
60
|
+
handler: BuildInfoHandler,
|
|
61
|
+
): Promise<BuildInfoWatcher> {
|
|
62
|
+
const { watch } = await import("chokidar");
|
|
63
|
+
|
|
64
|
+
// NOTE: Deleting the build info directory while it is being watched will
|
|
65
|
+
// effectively cause the watcher to stop working.
|
|
66
|
+
// NOTE: We use chokidar's `awaitWriteFinish` option because we are certain
|
|
67
|
+
// the build info file will be added after the build info output file.
|
|
68
|
+
const watcher = watch(buildInfoDirPath, {
|
|
69
|
+
persistent: true,
|
|
70
|
+
ignoreInitial: true,
|
|
71
|
+
awaitWriteFinish: {
|
|
72
|
+
stabilityThreshold: STABILITY_THRESHOLD,
|
|
73
|
+
pollInterval: POLL_INTERVAL,
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// NOTE: We listen only to the "add" event because the contents of the build info
|
|
78
|
+
// files identified by a build id should be considered immutable under usual circumstances.
|
|
79
|
+
watcher.on("add", listener.bind(null, handler));
|
|
80
|
+
|
|
81
|
+
return watcher;
|
|
82
|
+
}
|
|
@@ -1,9 +1,19 @@
|
|
|
1
|
+
import type { BuildInfo } from "../../../types/artifacts.js";
|
|
1
2
|
import type { EdrNetworkAccountsConfig } from "../../../types/config.js";
|
|
3
|
+
import type { SolidityBuildInfoOutput } from "../../../types/solidity.js";
|
|
4
|
+
import type { EdrProvider } from "../network-manager/edr/edr-provider.js";
|
|
2
5
|
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
readJsonFile,
|
|
10
|
+
readJsonFileAsStream,
|
|
11
|
+
} from "@nomicfoundation/hardhat-utils/fs";
|
|
3
12
|
import { hexStringToBytes } from "@nomicfoundation/hardhat-utils/hex";
|
|
4
13
|
import chalk from "chalk";
|
|
5
14
|
import { addr } from "micro-eth-signer";
|
|
6
15
|
|
|
16
|
+
import { sendErrorTelemetry } from "../../cli/telemetry/sentry/reporter.js";
|
|
7
17
|
import { isDefaultEdrNetworkHDAccountsConfig } from "../network-manager/edr/edr-provider.js";
|
|
8
18
|
import { normalizeEdrNetworkAccountsConfig } from "../network-manager/edr/utils/convert-to-edr.js";
|
|
9
19
|
|
|
@@ -64,6 +74,60 @@ export async function formatEdrNetworkConfigAccounts(
|
|
|
64
74
|
return formattedAccountsLines.join("\n");
|
|
65
75
|
}
|
|
66
76
|
|
|
77
|
+
/**
|
|
78
|
+
* Creates a handler function that will be called on buildInfo file creations
|
|
79
|
+
* (triggered from the compilation pipeline); the handler reads the build info
|
|
80
|
+
* file and uploads the key details into the EDR instance.
|
|
81
|
+
*
|
|
82
|
+
* @param buildInfoDirPath - The path (under artifacts) to the build info
|
|
83
|
+
* directory
|
|
84
|
+
* @param provider - The EDR provider being updated.
|
|
85
|
+
* @returns The handler function that is called with the buildId to upload.
|
|
86
|
+
*/
|
|
87
|
+
export function createBuildInfoUploadHandlerFrom(
|
|
88
|
+
buildInfoDirPath: string,
|
|
89
|
+
provider: EdrProvider,
|
|
90
|
+
log: debug.Debugger,
|
|
91
|
+
): (buildId: string) => Promise<void> {
|
|
92
|
+
const buildInfoHandler = async (buildId: string) => {
|
|
93
|
+
try {
|
|
94
|
+
log(`Adding new compilation result for build ${buildId} to the node`);
|
|
95
|
+
const buildInfo: BuildInfo = await readJsonFile(
|
|
96
|
+
path.join(buildInfoDirPath, `${buildId}.json`),
|
|
97
|
+
);
|
|
98
|
+
const buildInfoOutput: SolidityBuildInfoOutput =
|
|
99
|
+
await readJsonFileAsStream(
|
|
100
|
+
path.join(buildInfoDirPath, `${buildId}.output.json`),
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
await provider.addCompilationResult(
|
|
104
|
+
buildInfo.solcVersion,
|
|
105
|
+
buildInfo.input,
|
|
106
|
+
buildInfoOutput.output,
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
log(`Added compiler result for ${buildId}`);
|
|
110
|
+
} catch (error) {
|
|
111
|
+
console.warn(
|
|
112
|
+
chalk.yellow(
|
|
113
|
+
`There was a problem adding the new compiler result for build ${buildId}.`,
|
|
114
|
+
),
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
log(
|
|
118
|
+
"Last compilation result couldn't be added. Please report this to help us improve Hardhat.\n",
|
|
119
|
+
error,
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
if (error instanceof Error) {
|
|
123
|
+
await sendErrorTelemetry(error);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
return buildInfoHandler;
|
|
129
|
+
}
|
|
130
|
+
|
|
67
131
|
// NOTE: This function is exported for testing purposes only
|
|
68
132
|
export function getPublicPrivateKeysWarning(): string {
|
|
69
133
|
return chalk.bold(
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { JsonRpcServer } from "../../../../types/network.js";
|
|
1
2
|
import type { EthereumProvider } from "../../../../types/providers.js";
|
|
2
3
|
import type { Server } from "node:http";
|
|
3
4
|
import type { AddressInfo } from "node:net";
|
|
@@ -11,17 +12,9 @@ import { JsonRpcHandler } from "./handler.js";
|
|
|
11
12
|
|
|
12
13
|
const log = debug("hardhat:core:tasks:node:json-rpc:server");
|
|
13
14
|
|
|
14
|
-
export interface JsonRpcServer {
|
|
15
|
-
listen(): Promise<{ address: string; port: number }>;
|
|
16
|
-
waitUntilClosed(): Promise<void>;
|
|
17
|
-
|
|
18
|
-
close(): Promise<void>;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
15
|
export interface JsonRpcServerConfig {
|
|
22
16
|
hostname: string;
|
|
23
|
-
port
|
|
24
|
-
|
|
17
|
+
port?: number;
|
|
25
18
|
provider: EthereumProvider;
|
|
26
19
|
}
|
|
27
20
|
|
|
@@ -56,7 +49,7 @@ export class JsonRpcServerImplementation implements JsonRpcServer {
|
|
|
56
49
|
});
|
|
57
50
|
};
|
|
58
51
|
|
|
59
|
-
public
|
|
52
|
+
public afterClosed = async (): Promise<void> => {
|
|
60
53
|
const httpServerClosed = new Promise((resolve) => {
|
|
61
54
|
this.#httpServer.once("close", resolve);
|
|
62
55
|
});
|
|
@@ -1,19 +1,30 @@
|
|
|
1
1
|
import type { EdrNetworkConfigOverride } from "../../../types/config.js";
|
|
2
2
|
import type { NewTaskActionFunction } from "../../../types/tasks.js";
|
|
3
3
|
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
|
|
4
6
|
import {
|
|
5
7
|
assertHardhatInvariant,
|
|
6
8
|
HardhatError,
|
|
7
9
|
} from "@nomicfoundation/hardhat-errors";
|
|
8
|
-
import { exists } from "@nomicfoundation/hardhat-utils/fs";
|
|
10
|
+
import { ensureDir, exists } from "@nomicfoundation/hardhat-utils/fs";
|
|
9
11
|
import chalk from "chalk";
|
|
12
|
+
import debug from "debug";
|
|
10
13
|
|
|
11
14
|
import { DEFAULT_NETWORK_NAME } from "../../constants.js";
|
|
12
15
|
import { isSupportedChainType } from "../../edr/chain-type.js";
|
|
16
|
+
import { BUILD_INFO_DIR_NAME } from "../artifacts/artifact-manager.js";
|
|
17
|
+
import { EdrProvider } from "../network-manager/edr/edr-provider.js";
|
|
13
18
|
|
|
14
|
-
import {
|
|
19
|
+
import { watchBuildInfo } from "./artifacts/build-info-watcher.js";
|
|
20
|
+
import {
|
|
21
|
+
createBuildInfoUploadHandlerFrom,
|
|
22
|
+
formatEdrNetworkConfigAccounts,
|
|
23
|
+
} from "./helpers.js";
|
|
15
24
|
import { JsonRpcServerImplementation } from "./json-rpc/server.js";
|
|
16
25
|
|
|
26
|
+
const log = debug("hardhat:core:tasks:node");
|
|
27
|
+
|
|
17
28
|
interface NodeActionArguments {
|
|
18
29
|
hostname?: string;
|
|
19
30
|
port: number;
|
|
@@ -94,6 +105,11 @@ const nodeAction: NewTaskActionFunction<NodeActionArguments> = async (
|
|
|
94
105
|
override: networkConfigOverride,
|
|
95
106
|
});
|
|
96
107
|
|
|
108
|
+
assertHardhatInvariant(
|
|
109
|
+
provider instanceof EdrProvider,
|
|
110
|
+
"Provider must be EdrProvider, since only edr networks are supported",
|
|
111
|
+
);
|
|
112
|
+
|
|
97
113
|
// NOTE: We enable logging for the node
|
|
98
114
|
await provider.request({
|
|
99
115
|
method: "hardhat_setLoggingEnabled",
|
|
@@ -112,7 +128,7 @@ const nodeAction: NewTaskActionFunction<NodeActionArguments> = async (
|
|
|
112
128
|
}
|
|
113
129
|
}
|
|
114
130
|
|
|
115
|
-
const server
|
|
131
|
+
const server = new JsonRpcServerImplementation({
|
|
116
132
|
hostname,
|
|
117
133
|
port: args.port,
|
|
118
134
|
provider,
|
|
@@ -128,7 +144,16 @@ const nodeAction: NewTaskActionFunction<NodeActionArguments> = async (
|
|
|
128
144
|
|
|
129
145
|
console.log();
|
|
130
146
|
|
|
131
|
-
|
|
147
|
+
const buildInfoDirPath = path.join(
|
|
148
|
+
hre.config.paths.artifacts,
|
|
149
|
+
BUILD_INFO_DIR_NAME,
|
|
150
|
+
);
|
|
151
|
+
await ensureDir(buildInfoDirPath);
|
|
152
|
+
|
|
153
|
+
const buildInfoWatcher = await watchBuildInfo(
|
|
154
|
+
buildInfoDirPath,
|
|
155
|
+
createBuildInfoUploadHandlerFrom(buildInfoDirPath, provider, log),
|
|
156
|
+
);
|
|
132
157
|
|
|
133
158
|
// NOTE: Before creating the node, we check if the input network config is of type edr.
|
|
134
159
|
// We only proceed if it is. Hence, we can assume that the output network config is of type edr as well.
|
|
@@ -139,7 +164,8 @@ const nodeAction: NewTaskActionFunction<NodeActionArguments> = async (
|
|
|
139
164
|
|
|
140
165
|
console.log(await formatEdrNetworkConfigAccounts(networkConfig.accounts));
|
|
141
166
|
|
|
142
|
-
await server.
|
|
167
|
+
await server.afterClosed();
|
|
168
|
+
await buildInfoWatcher.close();
|
|
143
169
|
};
|
|
144
170
|
|
|
145
171
|
export default nodeAction;
|