hardhat 2.6.8 → 2.7.0
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 +17 -0
- package/builtin-tasks/node.js +2 -2
- package/internal/artifacts.d.ts +49 -0
- package/internal/artifacts.d.ts.map +1 -1
- package/internal/artifacts.js +191 -55
- package/internal/artifacts.js.map +1 -1
- package/internal/cli/analytics.js +2 -2
- package/internal/cli/analytics.js.map +1 -1
- package/internal/cli/cli.js +1 -1
- package/internal/cli/cli.js.map +1 -1
- package/internal/constants.d.ts +2 -0
- package/internal/constants.d.ts.map +1 -1
- package/internal/constants.js +3 -1
- package/internal/constants.js.map +1 -1
- package/internal/core/config/config-loading.d.ts.map +1 -1
- package/internal/core/config/config-loading.js +15 -1
- 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 +21 -0
- package/internal/core/config/config-resolution.js.map +1 -1
- package/internal/core/config/config-validation.d.ts +1 -0
- package/internal/core/config/config-validation.d.ts.map +1 -1
- package/internal/core/config/config-validation.js +88 -13
- package/internal/core/config/config-validation.js.map +1 -1
- package/internal/core/config/default-config.d.ts.map +1 -1
- package/internal/core/config/default-config.js +7 -1
- package/internal/core/config/default-config.js.map +1 -1
- package/internal/core/errors-list.js +2 -2
- package/internal/core/errors-list.js.map +1 -1
- package/internal/core/jsonrpc/types/output/log.d.ts +1 -0
- package/internal/core/jsonrpc/types/output/log.d.ts.map +1 -1
- package/internal/core/jsonrpc/types/output/log.js +1 -0
- package/internal/core/jsonrpc/types/output/log.js.map +1 -1
- package/internal/core/jsonrpc/types/output/receipt.d.ts +1 -0
- package/internal/core/jsonrpc/types/output/receipt.d.ts.map +1 -1
- package/internal/core/params/hardhat-params.js +2 -2
- package/internal/core/params/hardhat-params.js.map +1 -1
- package/internal/core/providers/construction.d.ts.map +1 -1
- package/internal/core/providers/construction.js +4 -2
- package/internal/core/providers/construction.js.map +1 -1
- package/internal/core/typescript-support.d.ts +1 -1
- package/internal/core/typescript-support.d.ts.map +1 -1
- package/internal/core/typescript-support.js +4 -1
- package/internal/core/typescript-support.js.map +1 -1
- package/internal/hardhat-network/jsonrpc/client.d.ts +2 -0
- package/internal/hardhat-network/jsonrpc/client.d.ts.map +1 -1
- package/internal/hardhat-network/provider/TransactionQueue.d.ts +2 -1
- package/internal/hardhat-network/provider/TransactionQueue.d.ts.map +1 -1
- package/internal/hardhat-network/provider/TransactionQueue.js +16 -2
- package/internal/hardhat-network/provider/TransactionQueue.js.map +1 -1
- package/internal/hardhat-network/provider/fork/ForkBlockchain.d.ts.map +1 -1
- package/internal/hardhat-network/provider/fork/ForkBlockchain.js +1 -3
- package/internal/hardhat-network/provider/fork/ForkBlockchain.js.map +1 -1
- package/internal/hardhat-network/provider/modules/hardhat.d.ts +2 -0
- package/internal/hardhat-network/provider/modules/hardhat.d.ts.map +1 -1
- package/internal/hardhat-network/provider/modules/hardhat.js +10 -0
- package/internal/hardhat-network/provider/modules/hardhat.js.map +1 -1
- package/internal/hardhat-network/provider/node-types.d.ts +5 -0
- package/internal/hardhat-network/provider/node-types.d.ts.map +1 -1
- package/internal/hardhat-network/provider/node-types.js.map +1 -1
- package/internal/hardhat-network/provider/node.d.ts +3 -1
- package/internal/hardhat-network/provider/node.d.ts.map +1 -1
- package/internal/hardhat-network/provider/node.js +13 -7
- package/internal/hardhat-network/provider/node.js.map +1 -1
- package/internal/hardhat-network/provider/output.d.ts +1 -1
- package/internal/hardhat-network/provider/output.d.ts.map +1 -1
- package/internal/hardhat-network/provider/output.js +9 -6
- package/internal/hardhat-network/provider/output.js.map +1 -1
- package/internal/hardhat-network/provider/provider.d.ts +5 -2
- package/internal/hardhat-network/provider/provider.d.ts.map +1 -1
- package/internal/hardhat-network/provider/provider.js +7 -2
- package/internal/hardhat-network/provider/provider.js.map +1 -1
- package/package.json +4 -4
- package/register.js +1 -1
- package/register.js.map +1 -1
- package/src/builtin-tasks/node.ts +2 -2
- package/src/internal/artifacts.ts +268 -71
- package/src/internal/cli/analytics.ts +1 -1
- package/src/internal/cli/cli.ts +1 -1
- package/src/internal/constants.ts +3 -0
- package/src/internal/core/config/config-loading.ts +23 -1
- package/src/internal/core/config/config-resolution.ts +28 -0
- package/src/internal/core/config/config-validation.ts +147 -15
- package/src/internal/core/config/default-config.ts +7 -1
- package/src/internal/core/errors-list.ts +2 -2
- package/src/internal/core/jsonrpc/types/output/log.ts +1 -0
- package/src/internal/core/params/hardhat-params.ts +2 -2
- package/src/internal/core/providers/construction.ts +8 -2
- package/src/internal/core/typescript-support.ts +5 -1
- package/src/internal/hardhat-network/provider/TransactionQueue.ts +31 -4
- package/src/internal/hardhat-network/provider/fork/ForkBlockchain.ts +1 -3
- package/src/internal/hardhat-network/provider/modules/hardhat.ts +14 -0
- package/src/internal/hardhat-network/provider/node-types.ts +6 -0
- package/src/internal/hardhat-network/provider/node.ts +15 -5
- package/src/internal/hardhat-network/provider/output.ts +9 -9
- package/src/internal/hardhat-network/provider/provider.ts +8 -1
- package/src/register.ts +1 -1
- package/src/types/config.ts +14 -0
- package/src/utils/contract-names.ts +112 -0
- package/src/utils/source-names.ts +1 -1
- package/types/config.d.ts +10 -0
- package/types/config.d.ts.map +1 -1
- package/utils/contract-names.d.ts +10 -0
- package/utils/contract-names.d.ts.map +1 -1
- package/utils/contract-names.js +92 -1
- package/utils/contract-names.js.map +1 -1
- package/utils/source-names.d.ts +1 -1
- package/utils/source-names.js +1 -1
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
getFullyQualifiedName,
|
|
16
16
|
isFullyQualifiedName,
|
|
17
17
|
parseFullyQualifiedName,
|
|
18
|
+
findDistance,
|
|
18
19
|
} from "../utils/contract-names";
|
|
19
20
|
import { replaceBackslashes } from "../utils/source-names";
|
|
20
21
|
|
|
@@ -23,6 +24,7 @@ import {
|
|
|
23
24
|
BUILD_INFO_DIR_NAME,
|
|
24
25
|
BUILD_INFO_FORMAT_VERSION,
|
|
25
26
|
DEBUG_FILE_FORMAT_VERSION,
|
|
27
|
+
EDIT_DISTANCE_THRESHOLD,
|
|
26
28
|
} from "./constants";
|
|
27
29
|
import { HardhatError } from "./core/errors";
|
|
28
30
|
import { ERRORS } from "./core/errors-list";
|
|
@@ -45,71 +47,13 @@ export class Artifacts implements IArtifacts {
|
|
|
45
47
|
}
|
|
46
48
|
|
|
47
49
|
public async readArtifact(name: string): Promise<Artifact> {
|
|
48
|
-
const { trueCasePath } = await import("true-case-path");
|
|
49
50
|
const artifactPath = await this._getArtifactPath(name);
|
|
50
|
-
|
|
51
|
-
try {
|
|
52
|
-
const trueCaseArtifactPath = await trueCasePath(
|
|
53
|
-
path.relative(this._artifactsPath, artifactPath),
|
|
54
|
-
this._artifactsPath
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
if (artifactPath !== trueCaseArtifactPath) {
|
|
58
|
-
throw new HardhatError(ERRORS.ARTIFACTS.WRONG_CASING, {
|
|
59
|
-
correct: trueCaseArtifactPath,
|
|
60
|
-
incorrect: artifactPath,
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return await fsExtra.readJson(trueCaseArtifactPath);
|
|
65
|
-
} catch (error) {
|
|
66
|
-
if (
|
|
67
|
-
typeof error.message === "string" &&
|
|
68
|
-
error.message.includes("no matching file exists")
|
|
69
|
-
) {
|
|
70
|
-
throw new HardhatError(ERRORS.INTERNAL.WRONG_ARTIFACT_PATH, {
|
|
71
|
-
contractName: name,
|
|
72
|
-
artifactPath,
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// eslint-disable-next-line @nomiclabs/hardhat-internal-rules/only-hardhat-error
|
|
77
|
-
throw error;
|
|
78
|
-
}
|
|
51
|
+
return fsExtra.readJson(artifactPath);
|
|
79
52
|
}
|
|
80
53
|
|
|
81
54
|
public readArtifactSync(name: string): Artifact {
|
|
82
|
-
const { trueCasePathSync } = require("true-case-path");
|
|
83
55
|
const artifactPath = this._getArtifactPathSync(name);
|
|
84
|
-
|
|
85
|
-
try {
|
|
86
|
-
const trueCaseArtifactPath = trueCasePathSync(
|
|
87
|
-
path.relative(this._artifactsPath, artifactPath),
|
|
88
|
-
this._artifactsPath
|
|
89
|
-
);
|
|
90
|
-
|
|
91
|
-
if (artifactPath !== trueCaseArtifactPath) {
|
|
92
|
-
throw new HardhatError(ERRORS.ARTIFACTS.WRONG_CASING, {
|
|
93
|
-
correct: trueCaseArtifactPath,
|
|
94
|
-
incorrect: artifactPath,
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
return fsExtra.readJsonSync(trueCaseArtifactPath);
|
|
99
|
-
} catch (error) {
|
|
100
|
-
if (
|
|
101
|
-
typeof error.message === "string" &&
|
|
102
|
-
error.message.includes("no matching file exists")
|
|
103
|
-
) {
|
|
104
|
-
throw new HardhatError(ERRORS.INTERNAL.WRONG_ARTIFACT_PATH, {
|
|
105
|
-
contractName: name,
|
|
106
|
-
artifactPath,
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// eslint-disable-next-line @nomiclabs/hardhat-internal-rules/only-hardhat-error
|
|
111
|
-
throw error;
|
|
112
|
-
}
|
|
56
|
+
return fsExtra.readJsonSync(artifactPath);
|
|
113
57
|
}
|
|
114
58
|
|
|
115
59
|
public async artifactExists(name: string): Promise<boolean> {
|
|
@@ -130,7 +74,7 @@ export class Artifacts implements IArtifacts {
|
|
|
130
74
|
fullyQualifiedName: string
|
|
131
75
|
): Promise<BuildInfo | undefined> {
|
|
132
76
|
const artifactPath =
|
|
133
|
-
this.
|
|
77
|
+
this.formArtifactPathFromFullyQualifiedName(fullyQualifiedName);
|
|
134
78
|
|
|
135
79
|
const debugFilePath = this._getDebugFilePath(artifactPath);
|
|
136
80
|
const buildInfoPath = await this._getBuildInfoFromDebugFile(debugFilePath);
|
|
@@ -173,7 +117,7 @@ export class Artifacts implements IArtifacts {
|
|
|
173
117
|
);
|
|
174
118
|
|
|
175
119
|
const artifactPath =
|
|
176
|
-
this.
|
|
120
|
+
this.formArtifactPathFromFullyQualifiedName(fullyQualifiedName);
|
|
177
121
|
|
|
178
122
|
await fsExtra.ensureDir(path.dirname(artifactPath));
|
|
179
123
|
|
|
@@ -280,6 +224,18 @@ export class Artifacts implements IArtifacts {
|
|
|
280
224
|
}
|
|
281
225
|
}
|
|
282
226
|
|
|
227
|
+
/**
|
|
228
|
+
* Returns the absolute path to the given artifact
|
|
229
|
+
*/
|
|
230
|
+
public formArtifactPathFromFullyQualifiedName(
|
|
231
|
+
fullyQualifiedName: string
|
|
232
|
+
): string {
|
|
233
|
+
const { sourceName, contractName } =
|
|
234
|
+
parseFullyQualifiedName(fullyQualifiedName);
|
|
235
|
+
|
|
236
|
+
return path.join(this._artifactsPath, sourceName, `${contractName}.json`);
|
|
237
|
+
}
|
|
238
|
+
|
|
283
239
|
private _getBuildInfoName(
|
|
284
240
|
solcVersion: string,
|
|
285
241
|
solcLongVersion: string,
|
|
@@ -307,7 +263,7 @@ export class Artifacts implements IArtifacts {
|
|
|
307
263
|
*/
|
|
308
264
|
private async _getArtifactPath(name: string): Promise<string> {
|
|
309
265
|
if (isFullyQualifiedName(name)) {
|
|
310
|
-
return this.
|
|
266
|
+
return this._getValidArtifactPathFromFullyQualifiedName(name);
|
|
311
267
|
}
|
|
312
268
|
|
|
313
269
|
const files = await this.getArtifactPaths();
|
|
@@ -346,9 +302,11 @@ export class Artifacts implements IArtifacts {
|
|
|
346
302
|
}
|
|
347
303
|
|
|
348
304
|
private _getArtifactPathsSync(): string[] {
|
|
349
|
-
|
|
305
|
+
const paths = globSync(path.join(this._artifactsPath, "**/*.json"), {
|
|
350
306
|
ignore: [this._buildInfosGlob, this._dbgsGlob],
|
|
351
307
|
});
|
|
308
|
+
|
|
309
|
+
return paths.sort();
|
|
352
310
|
}
|
|
353
311
|
|
|
354
312
|
/**
|
|
@@ -356,13 +314,69 @@ export class Artifacts implements IArtifacts {
|
|
|
356
314
|
*/
|
|
357
315
|
private _getArtifactPathSync(name: string): string {
|
|
358
316
|
if (isFullyQualifiedName(name)) {
|
|
359
|
-
return this.
|
|
317
|
+
return this._getValidArtifactPathFromFullyQualifiedNameSync(name);
|
|
360
318
|
}
|
|
361
319
|
|
|
362
320
|
const files = this._getArtifactPathsSync();
|
|
363
321
|
return this._getArtifactPathFromFiles(name, files);
|
|
364
322
|
}
|
|
365
323
|
|
|
324
|
+
/**
|
|
325
|
+
* Same signature as imported function, but abstracted to handle the only error we consistently care about
|
|
326
|
+
*/
|
|
327
|
+
private async _trueCasePath(
|
|
328
|
+
filePath: string,
|
|
329
|
+
basePath?: string
|
|
330
|
+
): Promise<string | null> {
|
|
331
|
+
const { trueCasePath } = await import("true-case-path");
|
|
332
|
+
|
|
333
|
+
try {
|
|
334
|
+
const result = await trueCasePath(filePath, basePath);
|
|
335
|
+
return result;
|
|
336
|
+
} catch (error: unknown) {
|
|
337
|
+
if (error instanceof Error) {
|
|
338
|
+
if (error.message.includes("no matching file exists")) {
|
|
339
|
+
return null;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// eslint-disable-next-line @nomiclabs/hardhat-internal-rules/only-hardhat-error
|
|
344
|
+
throw error;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Same signature as imported function, but abstracted to handle the only error we consistently care about
|
|
350
|
+
* and synchronous
|
|
351
|
+
*/
|
|
352
|
+
private _trueCasePathSync(
|
|
353
|
+
filePath: string,
|
|
354
|
+
basePath?: string
|
|
355
|
+
): string | null {
|
|
356
|
+
const { trueCasePathSync } = require("true-case-path");
|
|
357
|
+
|
|
358
|
+
try {
|
|
359
|
+
const result = trueCasePathSync(filePath, basePath);
|
|
360
|
+
return result;
|
|
361
|
+
} catch (error: unknown) {
|
|
362
|
+
if (error instanceof Error) {
|
|
363
|
+
if (error.message.includes("no matching file exists")) {
|
|
364
|
+
return null;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// eslint-disable-next-line @nomiclabs/hardhat-internal-rules/only-hardhat-error
|
|
369
|
+
throw error;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* DO NOT DELETE OR CHANGE
|
|
375
|
+
*
|
|
376
|
+
* use this.formArtifactPathFromFullyQualifiedName instead
|
|
377
|
+
* @deprecated until typechain migrates to public version
|
|
378
|
+
* @see https://github.com/dethcrypto/TypeChain/issues/544
|
|
379
|
+
*/
|
|
366
380
|
private _getArtifactPathFromFullyQualifiedName(
|
|
367
381
|
fullyQualifiedName: string
|
|
368
382
|
): string {
|
|
@@ -372,6 +386,191 @@ export class Artifacts implements IArtifacts {
|
|
|
372
386
|
return path.join(this._artifactsPath, sourceName, `${contractName}.json`);
|
|
373
387
|
}
|
|
374
388
|
|
|
389
|
+
private async _getValidArtifactPathFromFullyQualifiedName(
|
|
390
|
+
fullyQualifiedName: string
|
|
391
|
+
): Promise<string> {
|
|
392
|
+
const artifactPath =
|
|
393
|
+
this.formArtifactPathFromFullyQualifiedName(fullyQualifiedName);
|
|
394
|
+
|
|
395
|
+
const trueCaseArtifactPath = await this._trueCasePath(
|
|
396
|
+
path.relative(this._artifactsPath, artifactPath),
|
|
397
|
+
this._artifactsPath
|
|
398
|
+
);
|
|
399
|
+
|
|
400
|
+
if (trueCaseArtifactPath === null) {
|
|
401
|
+
return this._handleWrongArtifactForFullyQualifiedName(fullyQualifiedName);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
if (artifactPath !== trueCaseArtifactPath) {
|
|
405
|
+
throw new HardhatError(ERRORS.ARTIFACTS.WRONG_CASING, {
|
|
406
|
+
correct: trueCaseArtifactPath,
|
|
407
|
+
incorrect: artifactPath,
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
return artifactPath;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
private _getAllContractNamesFromFiles(files: string[]): string[] {
|
|
415
|
+
return files.map((file) => {
|
|
416
|
+
const fqn = this._getFullyQualifiedNameFromPath(file);
|
|
417
|
+
return parseFullyQualifiedName(fqn).contractName;
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
private _getAllFullyQualifiedNamesSync(): string[] {
|
|
422
|
+
const paths = this._getArtifactPathsSync();
|
|
423
|
+
return paths.map((p) => this._getFullyQualifiedNameFromPath(p)).sort();
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
private _formatSuggestions(names: string[], contractName?: string): string {
|
|
427
|
+
switch (names.length) {
|
|
428
|
+
case 0:
|
|
429
|
+
return "";
|
|
430
|
+
case 1:
|
|
431
|
+
return `Did you mean "${names[0]}"?`;
|
|
432
|
+
default:
|
|
433
|
+
return `We found some that were similar:
|
|
434
|
+
|
|
435
|
+
${names.map((n) => ` * ${n}`).join(os.EOL)}
|
|
436
|
+
|
|
437
|
+
Please replace "${contractName}" for the correct contract name wherever you are trying to read its artifact.
|
|
438
|
+
`;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
private _handleWrongArtifactForFullyQualifiedName(
|
|
443
|
+
fullyQualifiedName: string
|
|
444
|
+
): never {
|
|
445
|
+
const names = this._getAllFullyQualifiedNamesSync();
|
|
446
|
+
|
|
447
|
+
const similarNames = this._getSimilarContractNames(
|
|
448
|
+
fullyQualifiedName,
|
|
449
|
+
names
|
|
450
|
+
);
|
|
451
|
+
|
|
452
|
+
throw new HardhatError(ERRORS.ARTIFACTS.NOT_FOUND, {
|
|
453
|
+
contractName: fullyQualifiedName,
|
|
454
|
+
suggestion: this._formatSuggestions(similarNames),
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
private _handleWrongArtifactForContractName(
|
|
459
|
+
contractName: string,
|
|
460
|
+
files: string[]
|
|
461
|
+
): never {
|
|
462
|
+
const names = this._getAllContractNamesFromFiles(files);
|
|
463
|
+
|
|
464
|
+
let similarNames = this._getSimilarContractNames(contractName, names);
|
|
465
|
+
|
|
466
|
+
if (similarNames.length > 1) {
|
|
467
|
+
similarNames = this._filterDuplicatesAsFullyQualifiedNames(
|
|
468
|
+
files,
|
|
469
|
+
similarNames
|
|
470
|
+
);
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
throw new HardhatError(ERRORS.ARTIFACTS.NOT_FOUND, {
|
|
474
|
+
contractName,
|
|
475
|
+
suggestion: this._formatSuggestions(similarNames, contractName),
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
/**
|
|
480
|
+
* If the project has these contracts:
|
|
481
|
+
* - 'contracts/Greeter.sol:Greeter'
|
|
482
|
+
* - 'contracts/Meeter.sol:Greeter'
|
|
483
|
+
* - 'contracts/Greater.sol:Greater'
|
|
484
|
+
* And the user tries to get an artifact with the name 'Greter', then
|
|
485
|
+
* the suggestions will be 'Greeter', 'Greeter', and 'Greater'.
|
|
486
|
+
*
|
|
487
|
+
* We don't want to show duplicates here, so we use FQNs for those. The
|
|
488
|
+
* suggestions will then be:
|
|
489
|
+
* - 'contracts/Greeter.sol:Greeter'
|
|
490
|
+
* - 'contracts/Meeter.sol:Greeter'
|
|
491
|
+
* - 'Greater'
|
|
492
|
+
*/
|
|
493
|
+
private _filterDuplicatesAsFullyQualifiedNames(
|
|
494
|
+
files: string[],
|
|
495
|
+
similarNames: string[]
|
|
496
|
+
): string[] {
|
|
497
|
+
const outputNames = [];
|
|
498
|
+
const groups = similarNames.reduce((obj, cur) => {
|
|
499
|
+
obj[cur] = obj[cur] ? obj[cur] + 1 : 1;
|
|
500
|
+
return obj;
|
|
501
|
+
}, {} as { [k: string]: number });
|
|
502
|
+
|
|
503
|
+
for (const [name, occurrences] of Object.entries(groups)) {
|
|
504
|
+
if (occurrences > 1) {
|
|
505
|
+
for (const file of files) {
|
|
506
|
+
if (path.basename(file) === `${name}.json`) {
|
|
507
|
+
outputNames.push(this._getFullyQualifiedNameFromPath(file));
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
continue;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
outputNames.push(name);
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
return outputNames;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
*
|
|
521
|
+
* @param givenName can be FQN or contract name
|
|
522
|
+
* @param names MUST match type of givenName (i.e. array of FQN's if givenName is FQN)
|
|
523
|
+
* @returns
|
|
524
|
+
*/
|
|
525
|
+
private _getSimilarContractNames(
|
|
526
|
+
givenName: string,
|
|
527
|
+
names: string[]
|
|
528
|
+
): string[] {
|
|
529
|
+
let shortestDistance = EDIT_DISTANCE_THRESHOLD;
|
|
530
|
+
let mostSimilarNames: string[] = [];
|
|
531
|
+
for (const name of names) {
|
|
532
|
+
const distance = findDistance(givenName, name);
|
|
533
|
+
|
|
534
|
+
if (distance < shortestDistance) {
|
|
535
|
+
shortestDistance = distance;
|
|
536
|
+
mostSimilarNames = [name];
|
|
537
|
+
continue;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
if (distance === shortestDistance) {
|
|
541
|
+
mostSimilarNames.push(name);
|
|
542
|
+
continue;
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
return mostSimilarNames;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
private _getValidArtifactPathFromFullyQualifiedNameSync(
|
|
550
|
+
fullyQualifiedName: string
|
|
551
|
+
): string {
|
|
552
|
+
const artifactPath =
|
|
553
|
+
this.formArtifactPathFromFullyQualifiedName(fullyQualifiedName);
|
|
554
|
+
|
|
555
|
+
const trueCaseArtifactPath = this._trueCasePathSync(
|
|
556
|
+
path.relative(this._artifactsPath, artifactPath),
|
|
557
|
+
this._artifactsPath
|
|
558
|
+
);
|
|
559
|
+
|
|
560
|
+
if (trueCaseArtifactPath === null) {
|
|
561
|
+
return this._handleWrongArtifactForFullyQualifiedName(fullyQualifiedName);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
if (artifactPath !== trueCaseArtifactPath) {
|
|
565
|
+
throw new HardhatError(ERRORS.ARTIFACTS.WRONG_CASING, {
|
|
566
|
+
correct: trueCaseArtifactPath,
|
|
567
|
+
incorrect: artifactPath,
|
|
568
|
+
});
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
return artifactPath;
|
|
572
|
+
}
|
|
573
|
+
|
|
375
574
|
private _getDebugFilePath(artifactPath: string): string {
|
|
376
575
|
return artifactPath.replace(/\.json$/, ".dbg.json");
|
|
377
576
|
}
|
|
@@ -385,15 +584,13 @@ export class Artifacts implements IArtifacts {
|
|
|
385
584
|
});
|
|
386
585
|
|
|
387
586
|
if (matchingFiles.length === 0) {
|
|
388
|
-
|
|
389
|
-
contractName,
|
|
390
|
-
});
|
|
587
|
+
return this._handleWrongArtifactForContractName(contractName, files);
|
|
391
588
|
}
|
|
392
589
|
|
|
393
590
|
if (matchingFiles.length > 1) {
|
|
394
|
-
const candidates = matchingFiles
|
|
395
|
-
|
|
396
|
-
|
|
591
|
+
const candidates = matchingFiles.map((file) =>
|
|
592
|
+
this._getFullyQualifiedNameFromPath(file)
|
|
593
|
+
);
|
|
397
594
|
|
|
398
595
|
throw new HardhatError(ERRORS.ARTIFACTS.MULTIPLE_FOUND, {
|
|
399
596
|
contractName,
|
|
@@ -3,7 +3,7 @@ import debug from "debug";
|
|
|
3
3
|
import fetch from "node-fetch";
|
|
4
4
|
import os from "os";
|
|
5
5
|
import qs from "qs";
|
|
6
|
-
import uuid from "uuid
|
|
6
|
+
import { v4 as uuid } from "uuid";
|
|
7
7
|
|
|
8
8
|
import * as builtinTaskNames from "../../builtin-tasks/task-names";
|
|
9
9
|
import { isLocalDev } from "../core/execution-mode";
|
package/src/internal/cli/cli.ts
CHANGED
|
@@ -20,10 +20,13 @@ export const HARDHAT_NETWORK_SUPPORTED_HARDFORKS = [
|
|
|
20
20
|
"london",
|
|
21
21
|
];
|
|
22
22
|
|
|
23
|
+
export const HARDHAT_MEMPOOL_SUPPORTED_ORDERS = <const>["fifo", "priority"];
|
|
24
|
+
|
|
23
25
|
export const ARTIFACT_FORMAT_VERSION = "hh-sol-artifact-1";
|
|
24
26
|
export const DEBUG_FILE_FORMAT_VERSION = "hh-sol-dbg-1";
|
|
25
27
|
export const BUILD_INFO_FORMAT_VERSION = "hh-sol-build-info-1";
|
|
26
28
|
export const BUILD_INFO_DIR_NAME = "build-info";
|
|
29
|
+
export const EDIT_DISTANCE_THRESHOLD = 3;
|
|
27
30
|
|
|
28
31
|
export const HARDHAT_NETWORK_RESET_EVENT = "hardhatNetworkReset";
|
|
29
32
|
export const HARDHAT_NETWORK_REVERT_SNAPSHOT_EVENT =
|
|
@@ -92,6 +92,7 @@ export function loadConfigAndTasks(
|
|
|
92
92
|
|
|
93
93
|
if (showSolidityConfigWarnings) {
|
|
94
94
|
checkUnsupportedSolidityConfig(resolved);
|
|
95
|
+
checkUnsupportedRemappings(resolved);
|
|
95
96
|
}
|
|
96
97
|
|
|
97
98
|
return resolved;
|
|
@@ -223,7 +224,7 @@ function checkMissingSolidityConfig(userConfig: any) {
|
|
|
223
224
|
if (userConfig.solidity === undefined) {
|
|
224
225
|
console.warn(
|
|
225
226
|
chalk.yellow(
|
|
226
|
-
`Solidity compiler is not configured. Version ${DEFAULT_SOLC_VERSION} will be used by default. Add a 'solidity' entry to your configuration to
|
|
227
|
+
`Solidity compiler is not configured. Version ${DEFAULT_SOLC_VERSION} will be used by default. Add a 'solidity' entry to your configuration to suppress this warning.
|
|
227
228
|
|
|
228
229
|
Learn more about compiler configuration at https://hardhat.org/config"
|
|
229
230
|
`
|
|
@@ -261,3 +262,24 @@ Learn more at https://hardhat.org/reference/solidity-support
|
|
|
261
262
|
);
|
|
262
263
|
}
|
|
263
264
|
}
|
|
265
|
+
|
|
266
|
+
function checkUnsupportedRemappings({ solidity }: HardhatConfig) {
|
|
267
|
+
const solcConfigs = [
|
|
268
|
+
...solidity.compilers,
|
|
269
|
+
...Object.values(solidity.overrides),
|
|
270
|
+
];
|
|
271
|
+
const remappings = solcConfigs.filter(
|
|
272
|
+
({ settings }) => settings.remappings !== undefined
|
|
273
|
+
);
|
|
274
|
+
|
|
275
|
+
if (remappings.length > 0) {
|
|
276
|
+
console.warn(
|
|
277
|
+
chalk.yellow(
|
|
278
|
+
`Solidity remappings are not currently supported; you may experience unexpected compilation results. Remove any 'remappings' fields from your configuration to suppress this warning.
|
|
279
|
+
|
|
280
|
+
Learn more about compiler configuration at https://hardhat.org/config
|
|
281
|
+
`
|
|
282
|
+
)
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
@@ -10,6 +10,8 @@ import {
|
|
|
10
10
|
HardhatNetworkForkingConfig,
|
|
11
11
|
HardhatNetworkMiningConfig,
|
|
12
12
|
HardhatNetworkMiningUserConfig,
|
|
13
|
+
HardhatNetworkMempoolConfig,
|
|
14
|
+
HardhatNetworkMempoolUserConfig,
|
|
13
15
|
HardhatNetworkUserConfig,
|
|
14
16
|
HardhatUserConfig,
|
|
15
17
|
HDAccountsUserConfig,
|
|
@@ -228,10 +230,12 @@ function resolveHttpNetworkConfig(
|
|
|
228
230
|
function resolveMiningConfig(
|
|
229
231
|
userConfig: HardhatNetworkMiningUserConfig | undefined
|
|
230
232
|
): HardhatNetworkMiningConfig {
|
|
233
|
+
const mempool = resolveMempoolConfig(userConfig?.mempool);
|
|
231
234
|
if (userConfig === undefined) {
|
|
232
235
|
return {
|
|
233
236
|
auto: true,
|
|
234
237
|
interval: 0,
|
|
238
|
+
mempool,
|
|
235
239
|
};
|
|
236
240
|
}
|
|
237
241
|
|
|
@@ -241,6 +245,7 @@ function resolveMiningConfig(
|
|
|
241
245
|
return {
|
|
242
246
|
auto: true,
|
|
243
247
|
interval: 0,
|
|
248
|
+
mempool,
|
|
244
249
|
};
|
|
245
250
|
}
|
|
246
251
|
|
|
@@ -248,6 +253,7 @@ function resolveMiningConfig(
|
|
|
248
253
|
return {
|
|
249
254
|
auto: false,
|
|
250
255
|
interval,
|
|
256
|
+
mempool,
|
|
251
257
|
};
|
|
252
258
|
}
|
|
253
259
|
|
|
@@ -255,6 +261,7 @@ function resolveMiningConfig(
|
|
|
255
261
|
return {
|
|
256
262
|
auto,
|
|
257
263
|
interval: 0,
|
|
264
|
+
mempool,
|
|
258
265
|
};
|
|
259
266
|
}
|
|
260
267
|
|
|
@@ -262,9 +269,30 @@ function resolveMiningConfig(
|
|
|
262
269
|
return {
|
|
263
270
|
auto: auto!,
|
|
264
271
|
interval: interval!,
|
|
272
|
+
mempool,
|
|
265
273
|
};
|
|
266
274
|
}
|
|
267
275
|
|
|
276
|
+
function resolveMempoolConfig(
|
|
277
|
+
userConfig: HardhatNetworkMempoolUserConfig | undefined
|
|
278
|
+
): HardhatNetworkMempoolConfig {
|
|
279
|
+
if (userConfig === undefined) {
|
|
280
|
+
return {
|
|
281
|
+
order: "priority",
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
if (userConfig.order === undefined) {
|
|
286
|
+
return {
|
|
287
|
+
order: "priority",
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
return {
|
|
292
|
+
order: userConfig.order,
|
|
293
|
+
} as HardhatNetworkMempoolConfig;
|
|
294
|
+
}
|
|
295
|
+
|
|
268
296
|
function resolveSolidityConfig(userConfig: HardhatUserConfig): SolidityConfig {
|
|
269
297
|
const userSolidityConfig = userConfig.solidity ?? DEFAULT_SOLC_VERSION;
|
|
270
298
|
|