hardhat 2.19.3 → 2.19.5
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/README.md +6 -0
- package/builtin-tasks/compile.js +11 -2
- package/builtin-tasks/compile.js.map +1 -1
- package/internal/cli/analytics.d.ts +2 -0
- package/internal/cli/analytics.d.ts.map +1 -1
- package/internal/cli/analytics.js +37 -3
- package/internal/cli/analytics.js.map +1 -1
- package/internal/cli/cli.js +34 -4
- package/internal/cli/cli.js.map +1 -1
- package/internal/cli/project-creation.d.ts.map +1 -1
- package/internal/cli/project-creation.js +7 -10
- package/internal/cli/project-creation.js.map +1 -1
- package/internal/cli/version-notifier.d.ts +2 -0
- package/internal/cli/version-notifier.d.ts.map +1 -0
- package/internal/cli/version-notifier.js +217 -0
- package/internal/cli/version-notifier.js.map +1 -0
- package/internal/core/config/config-loading.d.ts.map +1 -1
- package/internal/core/config/config-loading.js +3 -3
- package/internal/core/config/config-loading.js.map +1 -1
- package/internal/core/config/config-resolution.d.ts.map +1 -1
- package/internal/core/config/config-resolution.js +10 -6
- package/internal/core/config/config-resolution.js.map +1 -1
- package/internal/core/config/config-validation.d.ts +2 -2
- package/internal/core/config/config-validation.d.ts.map +1 -1
- package/internal/core/config/config-validation.js +2 -2
- package/internal/core/config/config-validation.js.map +1 -1
- package/internal/core/providers/gas-providers.d.ts.map +1 -1
- package/internal/core/providers/gas-providers.js +7 -0
- package/internal/core/providers/gas-providers.js.map +1 -1
- package/internal/hardhat-network/stack-traces/panic-errors.js +1 -1
- package/internal/hardhat-network/stack-traces/panic-errors.js.map +1 -1
- package/internal/hardhat-network/stack-traces/solidity-errors.js +13 -1
- package/internal/hardhat-network/stack-traces/solidity-errors.js.map +1 -1
- package/internal/solidity/compiler/downloader.d.ts.map +1 -1
- package/internal/solidity/compiler/downloader.js +2 -2
- package/internal/solidity/compiler/downloader.js.map +1 -1
- package/internal/solidity/compiler/index.d.ts +2 -1
- package/internal/solidity/compiler/index.d.ts.map +1 -1
- package/internal/solidity/compiler/index.js +25 -2
- package/internal/solidity/compiler/index.js.map +1 -1
- package/internal/util/fs-utils.d.ts +1 -1
- package/internal/util/fs-utils.js +1 -1
- package/internal/util/multi-process-mutex.d.ts +12 -0
- package/internal/util/multi-process-mutex.d.ts.map +1 -0
- package/internal/util/multi-process-mutex.js +116 -0
- package/internal/util/multi-process-mutex.js.map +1 -0
- package/internal/util/report-telemetry-consent.d.ts +2 -0
- package/internal/util/report-telemetry-consent.d.ts.map +1 -0
- package/internal/util/report-telemetry-consent.js +15 -0
- package/internal/util/report-telemetry-consent.js.map +1 -0
- package/package.json +2 -1
- package/src/builtin-tasks/compile.ts +20 -2
- package/src/internal/cli/analytics.ts +82 -6
- package/src/internal/cli/cli.ts +16 -9
- package/src/internal/cli/project-creation.ts +9 -19
- package/src/internal/cli/version-notifier.ts +268 -0
- package/src/internal/core/config/config-loading.ts +2 -1
- package/src/internal/core/config/config-resolution.ts +7 -1
- package/src/internal/core/config/config-validation.ts +9 -2
- package/src/internal/core/providers/gas-providers.ts +8 -0
- package/src/internal/hardhat-network/stack-traces/panic-errors.ts +1 -1
- package/src/internal/hardhat-network/stack-traces/solidity-errors.ts +17 -1
- package/src/internal/sentry/transport.ts +1 -1
- package/src/internal/solidity/compiler/downloader.ts +2 -2
- package/src/internal/solidity/compiler/index.ts +22 -2
- package/src/internal/util/fs-utils.ts +1 -1
- package/src/internal/util/multi-process-mutex.ts +133 -0
- package/src/internal/util/report-telemetry-consent.ts +19 -0
package/src/internal/cli/cli.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
2
|
import debug from "debug";
|
|
3
3
|
import "source-map-support/register";
|
|
4
|
+
|
|
4
5
|
import {
|
|
5
6
|
TASK_COMPILE,
|
|
6
7
|
TASK_HELP,
|
|
@@ -34,16 +35,14 @@ import {
|
|
|
34
35
|
hasConsentedTelemetry,
|
|
35
36
|
hasPromptedForHHVSCode,
|
|
36
37
|
writePromptedForHHVSCode,
|
|
37
|
-
writeTelemetryConsent,
|
|
38
38
|
} from "../util/global-dir";
|
|
39
39
|
import { getPackageJson } from "../util/packageInfo";
|
|
40
|
-
|
|
41
40
|
import { saveFlamegraph } from "../core/flamegraph";
|
|
42
|
-
import { Analytics } from "./analytics";
|
|
41
|
+
import { Analytics, requestTelemetryConsent } from "./analytics";
|
|
43
42
|
import { ArgumentsParser } from "./ArgumentsParser";
|
|
44
43
|
import { enableEmoji } from "./emoji";
|
|
45
44
|
import { createProject, showSoliditySurveyMessage } from "./project-creation";
|
|
46
|
-
import { confirmHHVSCodeInstallation
|
|
45
|
+
import { confirmHHVSCodeInstallation } from "./prompt";
|
|
47
46
|
import {
|
|
48
47
|
InstallationState,
|
|
49
48
|
installHardhatVSCode,
|
|
@@ -247,11 +246,7 @@ async function main() {
|
|
|
247
246
|
process.stdout.isTTY === true &&
|
|
248
247
|
process.env.HARDHAT_DISABLE_TELEMETRY_PROMPT !== "true"
|
|
249
248
|
) {
|
|
250
|
-
telemetryConsent = await
|
|
251
|
-
|
|
252
|
-
if (telemetryConsent !== undefined) {
|
|
253
|
-
writeTelemetryConsent(telemetryConsent);
|
|
254
|
-
}
|
|
249
|
+
telemetryConsent = await requestTelemetryConsent();
|
|
255
250
|
}
|
|
256
251
|
|
|
257
252
|
const analytics = await Analytics.getInstance(telemetryConsent);
|
|
@@ -372,6 +367,18 @@ async function main() {
|
|
|
372
367
|
if (process.exitCode !== 0) {
|
|
373
368
|
showViaIRWarning(resolvedConfig);
|
|
374
369
|
}
|
|
370
|
+
|
|
371
|
+
// we notify of new versions only if the tests failed
|
|
372
|
+
if (process.exitCode !== 0) {
|
|
373
|
+
try {
|
|
374
|
+
const { showNewVersionNotification } = await import(
|
|
375
|
+
"./version-notifier"
|
|
376
|
+
);
|
|
377
|
+
await showNewVersionNotification();
|
|
378
|
+
} catch {
|
|
379
|
+
// ignore possible version notifier errors
|
|
380
|
+
}
|
|
381
|
+
}
|
|
375
382
|
}
|
|
376
383
|
|
|
377
384
|
log(`Killing Hardhat after successfully running task ${taskName}`);
|
|
@@ -7,10 +7,7 @@ import { assertHardhatInvariant, HardhatError } from "../core/errors";
|
|
|
7
7
|
import { ERRORS } from "../core/errors-list";
|
|
8
8
|
import { getRecommendedGitIgnore } from "../core/project-structure";
|
|
9
9
|
import { getAllFilesMatching } from "../util/fs-utils";
|
|
10
|
-
import {
|
|
11
|
-
hasConsentedTelemetry,
|
|
12
|
-
writeTelemetryConsent,
|
|
13
|
-
} from "../util/global-dir";
|
|
10
|
+
import { hasConsentedTelemetry } from "../util/global-dir";
|
|
14
11
|
import { fromEntries } from "../util/lang";
|
|
15
12
|
import {
|
|
16
13
|
getPackageJson,
|
|
@@ -18,13 +15,14 @@ import {
|
|
|
18
15
|
PackageJson,
|
|
19
16
|
} from "../util/packageInfo";
|
|
20
17
|
import { pluralize } from "../util/strings";
|
|
18
|
+
import { isRunningOnCiServer } from "../util/ci-detection";
|
|
21
19
|
import {
|
|
22
20
|
confirmRecommendedDepsInstallation,
|
|
23
|
-
confirmTelemetryConsent,
|
|
24
21
|
confirmProjectCreation,
|
|
25
22
|
} from "./prompt";
|
|
26
23
|
import { emoji } from "./emoji";
|
|
27
24
|
import { Dependencies, PackageManager } from "./types";
|
|
25
|
+
import { requestTelemetryConsent } from "./analytics";
|
|
28
26
|
|
|
29
27
|
enum Action {
|
|
30
28
|
CREATE_JAVASCRIPT_PROJECT_ACTION = "Create a JavaScript project",
|
|
@@ -463,13 +461,10 @@ export async function createProject() {
|
|
|
463
461
|
|
|
464
462
|
if (
|
|
465
463
|
process.env.HARDHAT_DISABLE_TELEMETRY_PROMPT !== "true" &&
|
|
464
|
+
!isRunningOnCiServer() &&
|
|
466
465
|
hasConsentedTelemetry() === undefined
|
|
467
466
|
) {
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
if (telemetryConsent !== undefined) {
|
|
471
|
-
writeTelemetryConsent(telemetryConsent);
|
|
472
|
-
}
|
|
467
|
+
await requestTelemetryConsent();
|
|
473
468
|
}
|
|
474
469
|
|
|
475
470
|
await copySampleProject(projectRoot, action, isEsm);
|
|
@@ -573,12 +568,8 @@ async function doesNpmAutoInstallPeerDependencies() {
|
|
|
573
568
|
async function installRecommendedDependencies(dependencies: Dependencies) {
|
|
574
569
|
console.log("");
|
|
575
570
|
|
|
576
|
-
// The reason we don't quote the dependencies here is because they are going
|
|
577
|
-
// to be used in child_process.spawn, which doesn't require escaping string,
|
|
578
|
-
// and can actually fail if you do.
|
|
579
571
|
const installCmd = await getRecommendedDependenciesInstallationCommand(
|
|
580
|
-
dependencies
|
|
581
|
-
false
|
|
572
|
+
dependencies
|
|
582
573
|
);
|
|
583
574
|
return installDependencies(installCmd[0], installCmd.slice(1));
|
|
584
575
|
}
|
|
@@ -616,11 +607,10 @@ async function installDependencies(
|
|
|
616
607
|
}
|
|
617
608
|
|
|
618
609
|
async function getRecommendedDependenciesInstallationCommand(
|
|
619
|
-
dependencies: Dependencies
|
|
620
|
-
quoteDependencies = true
|
|
610
|
+
dependencies: Dependencies
|
|
621
611
|
): Promise<string[]> {
|
|
622
|
-
const deps = Object.entries(dependencies).map(
|
|
623
|
-
|
|
612
|
+
const deps = Object.entries(dependencies).map(
|
|
613
|
+
([name, version]) => `"${name}@${version}"`
|
|
624
614
|
);
|
|
625
615
|
|
|
626
616
|
if (await isYarnProject()) {
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import boxen from "boxen";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import fsExtra from "fs-extra";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
6
|
+
import semver from "semver";
|
|
7
|
+
|
|
8
|
+
import { getCacheDir } from "../util/global-dir";
|
|
9
|
+
import { getHardhatVersion } from "../util/packageInfo";
|
|
10
|
+
|
|
11
|
+
const GITHUB_API_URL = "https://api.github.com";
|
|
12
|
+
const GITHUB_OWNER = "NomicFoundation";
|
|
13
|
+
const GITHUB_REPO = "hardhat";
|
|
14
|
+
const V3_RELEASE_TAG = "hardhat@3.0.0";
|
|
15
|
+
const V3_RELEASE_VERSION_NOTIFIER_ASSET_NAME = "version-notifier-message.txt";
|
|
16
|
+
const V3_RELEASE_MAX_TIMES_SHOWN = 5;
|
|
17
|
+
const CURRENT_HARDHAT_MAJOR_VERSION = 2;
|
|
18
|
+
|
|
19
|
+
const boxenOptions = {
|
|
20
|
+
padding: 1,
|
|
21
|
+
borderStyle: "round",
|
|
22
|
+
borderColor: "yellow",
|
|
23
|
+
} as const;
|
|
24
|
+
|
|
25
|
+
interface VersionNotifierCache {
|
|
26
|
+
lastCheck: string | 0;
|
|
27
|
+
v3TimesShown: number;
|
|
28
|
+
v3Release?: Release;
|
|
29
|
+
v3ReleaseMessage?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/* eslint-disable @typescript-eslint/naming-convention */
|
|
33
|
+
interface Release {
|
|
34
|
+
name: string;
|
|
35
|
+
tag_name: string;
|
|
36
|
+
draft: boolean;
|
|
37
|
+
prerelease: boolean;
|
|
38
|
+
published_at: string;
|
|
39
|
+
html_url: string;
|
|
40
|
+
assets: Array<{
|
|
41
|
+
name: string;
|
|
42
|
+
browser_download_url: string;
|
|
43
|
+
}>;
|
|
44
|
+
body: string; // release notes
|
|
45
|
+
}
|
|
46
|
+
/* eslint-enable @typescript-eslint/naming-convention */
|
|
47
|
+
|
|
48
|
+
export async function showNewVersionNotification() {
|
|
49
|
+
const cache = await readCache();
|
|
50
|
+
|
|
51
|
+
const lastCheckDate = new Date(cache.lastCheck);
|
|
52
|
+
const now = new Date();
|
|
53
|
+
const oneDay = 1000 * 60 * 60 * 24;
|
|
54
|
+
|
|
55
|
+
if (now.getTime() - lastCheckDate.getTime() < oneDay) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const hardhatVersion = getHardhatVersion();
|
|
60
|
+
|
|
61
|
+
const releases = await getReleases();
|
|
62
|
+
|
|
63
|
+
const sortedV2Versions = releases
|
|
64
|
+
// filter and map releases to versions
|
|
65
|
+
.flatMap((release) => {
|
|
66
|
+
const [packageName, rawPackageVersion] = release.tag_name.split("@");
|
|
67
|
+
|
|
68
|
+
const packageVersion = semver.valid(rawPackageVersion);
|
|
69
|
+
|
|
70
|
+
// filter out a release if:
|
|
71
|
+
// - it's not a hardhat-core release
|
|
72
|
+
// - it's a draft or a prerelease
|
|
73
|
+
// - the version is invalid
|
|
74
|
+
// - the major version is not the current major
|
|
75
|
+
if (
|
|
76
|
+
packageName !== GITHUB_REPO ||
|
|
77
|
+
release.draft ||
|
|
78
|
+
release.prerelease ||
|
|
79
|
+
packageVersion === null ||
|
|
80
|
+
semver.major(packageVersion) !== CURRENT_HARDHAT_MAJOR_VERSION
|
|
81
|
+
) {
|
|
82
|
+
return [];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return [packageVersion];
|
|
86
|
+
})
|
|
87
|
+
// sort in descending order by version
|
|
88
|
+
.sort((releaseAVersion, releaseBVersion) => {
|
|
89
|
+
return semver.rcompare(releaseAVersion, releaseBVersion);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
const latestV2Version: string | undefined = sortedV2Versions[0];
|
|
93
|
+
|
|
94
|
+
const v3Release = cache.v3Release ?? (await getV3Release());
|
|
95
|
+
|
|
96
|
+
if (latestV2Version === undefined && v3Release === undefined) {
|
|
97
|
+
// this should never happen unless the github api is down
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (
|
|
102
|
+
latestV2Version !== undefined &&
|
|
103
|
+
semver.gt(latestV2Version, hardhatVersion)
|
|
104
|
+
) {
|
|
105
|
+
let installationCommand = "npm install";
|
|
106
|
+
if (await fsExtra.pathExists("yarn.lock")) {
|
|
107
|
+
installationCommand = "yarn add";
|
|
108
|
+
} else if (await fsExtra.pathExists("pnpm-lock.yaml")) {
|
|
109
|
+
installationCommand = "pnpm install";
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
console.log(
|
|
113
|
+
boxen(
|
|
114
|
+
`New Hardhat release available! ${chalk.red(
|
|
115
|
+
hardhatVersion
|
|
116
|
+
)} -> ${chalk.green(latestV2Version)}.
|
|
117
|
+
|
|
118
|
+
Changelog: https://hardhat.org/release/${latestV2Version}
|
|
119
|
+
|
|
120
|
+
Run "${installationCommand} hardhat@latest" to update.`,
|
|
121
|
+
boxenOptions
|
|
122
|
+
)
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (
|
|
127
|
+
v3Release !== undefined &&
|
|
128
|
+
cache.v3TimesShown < V3_RELEASE_MAX_TIMES_SHOWN
|
|
129
|
+
) {
|
|
130
|
+
const releaseVersion = semver.valid(v3Release.tag_name.split("@")[1]);
|
|
131
|
+
|
|
132
|
+
if (releaseVersion !== null) {
|
|
133
|
+
cache.v3ReleaseMessage ??= await getV3ReleaseMessage(v3Release);
|
|
134
|
+
if (cache.v3ReleaseMessage !== undefined) {
|
|
135
|
+
console.log(boxen(cache.v3ReleaseMessage, boxenOptions));
|
|
136
|
+
cache.v3TimesShown++;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
await writeCache({
|
|
142
|
+
...cache,
|
|
143
|
+
lastCheck: now.toISOString(),
|
|
144
|
+
v3Release,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
async function readCache(): Promise<VersionNotifierCache> {
|
|
149
|
+
const cacheDir = await getCacheDir();
|
|
150
|
+
const versionNotifierCachePath = join(cacheDir, "version-notifier.json");
|
|
151
|
+
|
|
152
|
+
let cache: VersionNotifierCache = {
|
|
153
|
+
lastCheck: 0, // new Date(0) represents the unix epoch
|
|
154
|
+
v3TimesShown: 0,
|
|
155
|
+
};
|
|
156
|
+
try {
|
|
157
|
+
const fileContents = await readFile(versionNotifierCachePath, "utf-8");
|
|
158
|
+
const { lastCheck, v3TimesShown } = JSON.parse(fileContents);
|
|
159
|
+
|
|
160
|
+
cache = {
|
|
161
|
+
lastCheck: typeof lastCheck === "string" ? lastCheck : 0,
|
|
162
|
+
v3TimesShown: typeof v3TimesShown === "number" ? v3TimesShown : 0,
|
|
163
|
+
};
|
|
164
|
+
} catch (error: any) {
|
|
165
|
+
// We don't care if it fails
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return cache;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
async function writeCache(cache: VersionNotifierCache) {
|
|
172
|
+
const cacheDir = await getCacheDir();
|
|
173
|
+
const versionNotifierCachePath = join(cacheDir, "version-notifier.json");
|
|
174
|
+
|
|
175
|
+
try {
|
|
176
|
+
await mkdir(cacheDir, { recursive: true });
|
|
177
|
+
await writeFile(versionNotifierCachePath, JSON.stringify(cache, null, 2));
|
|
178
|
+
} catch (error) {
|
|
179
|
+
// We don't care if it fails
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
async function getReleases(): Promise<Release[]> {
|
|
184
|
+
const { request } = await import("undici");
|
|
185
|
+
let releases: Release[] = [];
|
|
186
|
+
|
|
187
|
+
try {
|
|
188
|
+
const githubResponse = await request(
|
|
189
|
+
`${GITHUB_API_URL}/repos/${GITHUB_OWNER}/${GITHUB_REPO}/releases`,
|
|
190
|
+
{
|
|
191
|
+
method: "GET",
|
|
192
|
+
headers: {
|
|
193
|
+
"User-Agent": "Hardhat",
|
|
194
|
+
"X-GitHub-Api-Version": "2022-11-28",
|
|
195
|
+
},
|
|
196
|
+
query: {
|
|
197
|
+
per_page: 100,
|
|
198
|
+
},
|
|
199
|
+
}
|
|
200
|
+
);
|
|
201
|
+
releases = (await githubResponse.body.json()) as Release[];
|
|
202
|
+
} catch (error: any) {
|
|
203
|
+
// We don't care if it fails
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return releases;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
async function getV3Release(): Promise<Release | undefined> {
|
|
210
|
+
const { request } = await import("undici");
|
|
211
|
+
let v3Release: Release | undefined;
|
|
212
|
+
|
|
213
|
+
try {
|
|
214
|
+
const githubResponse = await request(
|
|
215
|
+
`${GITHUB_API_URL}/repos/${GITHUB_OWNER}/${GITHUB_REPO}/releases/tags/${V3_RELEASE_TAG}`,
|
|
216
|
+
{
|
|
217
|
+
method: "GET",
|
|
218
|
+
headers: {
|
|
219
|
+
"User-Agent": "Hardhat",
|
|
220
|
+
"X-GitHub-Api-Version": "2022-11-28",
|
|
221
|
+
},
|
|
222
|
+
}
|
|
223
|
+
);
|
|
224
|
+
|
|
225
|
+
const jsonResponse = (await githubResponse.body.json()) as any;
|
|
226
|
+
if (jsonResponse.message === "Not Found") {
|
|
227
|
+
// eslint-disable-next-line @nomicfoundation/hardhat-internal-rules/only-hardhat-error
|
|
228
|
+
throw new Error("Not Found");
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
v3Release = jsonResponse as Release;
|
|
232
|
+
} catch (error: any) {
|
|
233
|
+
// We don't care if it fails
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return v3Release;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
async function getV3ReleaseMessage(
|
|
240
|
+
v3Release: Release
|
|
241
|
+
): Promise<string | undefined> {
|
|
242
|
+
const { request } = await import("undici");
|
|
243
|
+
|
|
244
|
+
const versionNotifierAsset = v3Release.assets.find(
|
|
245
|
+
({ name }) => name === V3_RELEASE_VERSION_NOTIFIER_ASSET_NAME
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
if (versionNotifierAsset === undefined) {
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
let v3ReleaseMessage;
|
|
253
|
+
try {
|
|
254
|
+
const githubResponse = await request(
|
|
255
|
+
versionNotifierAsset.browser_download_url,
|
|
256
|
+
{
|
|
257
|
+
method: "GET",
|
|
258
|
+
maxRedirections: 10,
|
|
259
|
+
}
|
|
260
|
+
);
|
|
261
|
+
|
|
262
|
+
v3ReleaseMessage = await githubResponse.body.text();
|
|
263
|
+
} catch (error: any) {
|
|
264
|
+
// We don't care if it fails
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
return v3ReleaseMessage;
|
|
268
|
+
}
|
|
@@ -20,7 +20,6 @@ import { getUserConfigPath } from "../project-structure";
|
|
|
20
20
|
|
|
21
21
|
import { SUPPORTED_SOLIDITY_VERSION_RANGE } from "../../hardhat-network/stack-traces/constants";
|
|
22
22
|
import { resolveConfig } from "./config-resolution";
|
|
23
|
-
import { validateConfig, validateResolvedConfig } from "./config-validation";
|
|
24
23
|
import { DEFAULT_SOLC_VERSION } from "./default-config";
|
|
25
24
|
|
|
26
25
|
const log = debug("hardhat:core:config");
|
|
@@ -68,6 +67,8 @@ export function loadConfigAndTasks(
|
|
|
68
67
|
showSolidityConfigWarnings: false,
|
|
69
68
|
}
|
|
70
69
|
): { resolvedConfig: HardhatConfig; userConfig: HardhatUserConfig } {
|
|
70
|
+
const { validateConfig, validateResolvedConfig } =
|
|
71
|
+
require("./config-validation") as typeof import("./config-validation");
|
|
71
72
|
let configPath =
|
|
72
73
|
hardhatArguments !== undefined ? hardhatArguments.config : undefined;
|
|
73
74
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type { LoDashStatic } from "lodash";
|
|
2
|
+
|
|
2
3
|
import path from "path";
|
|
3
4
|
import semver from "semver";
|
|
4
5
|
|
|
@@ -62,6 +63,7 @@ export function resolveConfig(
|
|
|
62
63
|
userConfigPath: string,
|
|
63
64
|
userConfig: HardhatUserConfig
|
|
64
65
|
): HardhatConfig {
|
|
66
|
+
const cloneDeep = require("lodash/cloneDeep") as LoDashStatic["cloneDeep"];
|
|
65
67
|
userConfig = cloneDeep(userConfig);
|
|
66
68
|
|
|
67
69
|
return {
|
|
@@ -77,6 +79,7 @@ export function resolveConfig(
|
|
|
77
79
|
function resolveNetworksConfig(
|
|
78
80
|
networksConfig: NetworksUserConfig = {}
|
|
79
81
|
): NetworksConfig {
|
|
82
|
+
const cloneDeep = require("lodash/cloneDeep") as LoDashStatic["cloneDeep"];
|
|
80
83
|
const hardhatNetworkConfig = networksConfig[HARDHAT_NETWORK_NAME];
|
|
81
84
|
|
|
82
85
|
const localhostNetworkConfig =
|
|
@@ -128,6 +131,7 @@ function normalizeHexString(str: string): string {
|
|
|
128
131
|
function resolveHardhatNetworkConfig(
|
|
129
132
|
hardhatNetworkConfig: HardhatNetworkUserConfig = {}
|
|
130
133
|
): HardhatNetworkConfig {
|
|
134
|
+
const cloneDeep = require("lodash/cloneDeep") as LoDashStatic["cloneDeep"];
|
|
131
135
|
const clonedDefaultHardhatNetworkParams = cloneDeep(
|
|
132
136
|
defaultHardhatNetworkParams
|
|
133
137
|
);
|
|
@@ -246,6 +250,7 @@ function isHdAccountsConfig(
|
|
|
246
250
|
function resolveHttpNetworkConfig(
|
|
247
251
|
networkConfig: HttpNetworkUserConfig
|
|
248
252
|
): HttpNetworkConfig {
|
|
253
|
+
const cloneDeep = require("lodash/cloneDeep") as LoDashStatic["cloneDeep"];
|
|
249
254
|
const accounts: HttpNetworkAccountsConfig =
|
|
250
255
|
networkConfig.accounts === undefined
|
|
251
256
|
? defaultHttpNetworkParams.accounts
|
|
@@ -427,6 +432,7 @@ function resolveCompiler(compiler: SolcUserConfig): SolcConfig {
|
|
|
427
432
|
}
|
|
428
433
|
|
|
429
434
|
function resolveMochaConfig(userConfig: HardhatUserConfig): Mocha.MochaOptions {
|
|
435
|
+
const cloneDeep = require("lodash/cloneDeep") as LoDashStatic["cloneDeep"];
|
|
430
436
|
return {
|
|
431
437
|
...cloneDeep(defaultMochaOptions),
|
|
432
438
|
...userConfig.mocha,
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import type { HardhatConfig as HardhatConfigT } from "../../../types";
|
|
2
|
+
import type {
|
|
3
|
+
Context,
|
|
4
|
+
ValidationError,
|
|
5
|
+
getFunctionName as getFunctionNameT,
|
|
6
|
+
} from "io-ts/lib";
|
|
7
|
+
import type { Reporter } from "io-ts/lib/Reporter";
|
|
2
8
|
|
|
3
9
|
import * as t from "io-ts";
|
|
4
|
-
import { Context, getFunctionName, ValidationError } from "io-ts/lib";
|
|
5
|
-
import { Reporter } from "io-ts/lib/Reporter";
|
|
6
10
|
|
|
7
11
|
import {
|
|
8
12
|
HARDHAT_MEMPOOL_SUPPORTED_ORDERS,
|
|
@@ -19,6 +23,9 @@ import { defaultHardhatNetworkParams } from "./default-config";
|
|
|
19
23
|
|
|
20
24
|
function stringify(v: any): string {
|
|
21
25
|
if (typeof v === "function") {
|
|
26
|
+
const { getFunctionName } = require("io-ts/lib") as {
|
|
27
|
+
getFunctionName: typeof getFunctionNameT;
|
|
28
|
+
};
|
|
22
29
|
return getFunctionName(v);
|
|
23
30
|
}
|
|
24
31
|
if (typeof v === "number" && !isFinite(v)) {
|
|
@@ -273,6 +273,14 @@ export class AutomaticGasPriceProvider extends ProviderWrapper {
|
|
|
273
273
|
}
|
|
274
274
|
}
|
|
275
275
|
|
|
276
|
+
// If after all of these we still have a 0 wei maxPriorityFeePerGas, we
|
|
277
|
+
// use 1 wei. This is to improve the UX of the automatic gas price
|
|
278
|
+
// on chains that are very empty (i.e local testnets). This will be very
|
|
279
|
+
// unlikely to trigger on a live chain.
|
|
280
|
+
if (maxPriorityFeePerGas === 0n) {
|
|
281
|
+
maxPriorityFeePerGas = 1n;
|
|
282
|
+
}
|
|
283
|
+
|
|
276
284
|
return {
|
|
277
285
|
// Each block increases the base fee by 1/8 at most, when full.
|
|
278
286
|
// We have the next block's base fee, so we compute a cap for the
|
|
@@ -13,7 +13,7 @@ function panicErrorCodeToReason(errorCode: bigint): string | undefined {
|
|
|
13
13
|
case 0x1n:
|
|
14
14
|
return "Assertion error";
|
|
15
15
|
case 0x11n:
|
|
16
|
-
return "Arithmetic operation
|
|
16
|
+
return "Arithmetic operation overflowed outside of an unchecked block";
|
|
17
17
|
case 0x12n:
|
|
18
18
|
return "Division or modulo division by zero";
|
|
19
19
|
case 0x21n:
|
|
@@ -391,7 +391,7 @@ class SolidityCallSite implements NodeJS.CallSite {
|
|
|
391
391
|
}
|
|
392
392
|
|
|
393
393
|
public getScriptNameOrSourceURL() {
|
|
394
|
-
return
|
|
394
|
+
return "";
|
|
395
395
|
}
|
|
396
396
|
|
|
397
397
|
public getThis() {
|
|
@@ -425,4 +425,20 @@ class SolidityCallSite implements NodeJS.CallSite {
|
|
|
425
425
|
public isToplevel() {
|
|
426
426
|
return false;
|
|
427
427
|
}
|
|
428
|
+
|
|
429
|
+
public getScriptHash(): string {
|
|
430
|
+
return "";
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
public getEnclosingColumnNumber(): number {
|
|
434
|
+
return 0;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
public getEnclosingLineNumber(): number {
|
|
438
|
+
return 0;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
public toString(): string {
|
|
442
|
+
return "[SolidityCallSite]";
|
|
443
|
+
}
|
|
428
444
|
}
|
|
@@ -8,7 +8,7 @@ import { promisify } from "util";
|
|
|
8
8
|
import { download } from "../../util/download";
|
|
9
9
|
import { assertHardhatInvariant, HardhatError } from "../../core/errors";
|
|
10
10
|
import { ERRORS } from "../../core/errors-list";
|
|
11
|
-
import {
|
|
11
|
+
import { MultiProcessMutex } from "../../util/multi-process-mutex";
|
|
12
12
|
|
|
13
13
|
const log = debug("hardhat:core:solidity:downloader");
|
|
14
14
|
|
|
@@ -126,7 +126,7 @@ export class CompilerDownloader implements ICompilerDownloader {
|
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
public static defaultCompilerListCachePeriod = 3_600_00;
|
|
129
|
-
private readonly _mutex = new
|
|
129
|
+
private readonly _mutex = new MultiProcessMutex("compiler-download");
|
|
130
130
|
|
|
131
131
|
/**
|
|
132
132
|
* Use CompilerDownloader.getConcurrencySafeDownloader instead
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { execFile } from "child_process";
|
|
2
2
|
import * as fs from "fs";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import * as semver from "semver";
|
|
3
6
|
import { CompilerInput, CompilerOutput } from "../../../types";
|
|
4
7
|
import { HardhatError } from "../../core/errors";
|
|
5
8
|
import { ERRORS } from "../../core/errors-list";
|
|
@@ -68,14 +71,31 @@ export class Compiler implements ICompiler {
|
|
|
68
71
|
}
|
|
69
72
|
|
|
70
73
|
export class NativeCompiler implements ICompiler {
|
|
71
|
-
constructor(private _pathToSolc: string) {}
|
|
74
|
+
constructor(private _pathToSolc: string, private _solcVersion?: string) {}
|
|
72
75
|
|
|
73
76
|
public async compile(input: CompilerInput) {
|
|
77
|
+
const args = ["--standard-json"];
|
|
78
|
+
|
|
79
|
+
// Logic to make sure that solc default import callback is not being used.
|
|
80
|
+
// If solcVersion is not defined or <= 0.6.8, do not add extra args.
|
|
81
|
+
if (this._solcVersion !== undefined) {
|
|
82
|
+
if (semver.gte(this._solcVersion, "0.8.22")) {
|
|
83
|
+
// version >= 0.8.22
|
|
84
|
+
args.push("--no-import-callback");
|
|
85
|
+
} else if (semver.gte(this._solcVersion, "0.6.9")) {
|
|
86
|
+
// version >= 0.6.9
|
|
87
|
+
const tmpFolder = path.join(os.tmpdir(), "hardhat-solc");
|
|
88
|
+
fs.mkdirSync(tmpFolder, { recursive: true });
|
|
89
|
+
args.push(`--base-path`);
|
|
90
|
+
args.push(tmpFolder);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
74
94
|
const output: string = await new Promise((resolve, reject) => {
|
|
75
95
|
try {
|
|
76
96
|
const process = execFile(
|
|
77
97
|
this._pathToSolc,
|
|
78
|
-
|
|
98
|
+
args,
|
|
79
99
|
{
|
|
80
100
|
maxBuffer: 1024 * 1024 * 500,
|
|
81
101
|
},
|
|
@@ -65,7 +65,7 @@ export function getRealPathSync(absolutePath: string): string {
|
|
|
65
65
|
*
|
|
66
66
|
* @param absolutePathToDir A directory. If it doesn't exist `[]` is returned.
|
|
67
67
|
* @param matches A function to filter files (not directories)
|
|
68
|
-
* @returns An
|
|
68
|
+
* @returns An array of absolute paths. Each file has its true case, except
|
|
69
69
|
* for the initial absolutePathToDir part, which preserves the given casing.
|
|
70
70
|
* No order is guaranteed.
|
|
71
71
|
*/
|