hardhat 2.12.6 → 2.12.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/internal/core/config/config-loading.d.ts.map +1 -1
- package/internal/core/config/config-loading.js +1 -0
- package/internal/core/config/config-loading.js.map +1 -1
- package/internal/core/config/config-validation.d.ts +2 -0
- package/internal/core/config/config-validation.d.ts.map +1 -1
- package/internal/core/config/config-validation.js +18 -1
- package/internal/core/config/config-validation.js.map +1 -1
- package/internal/core/providers/construction.d.ts.map +1 -1
- package/internal/core/providers/construction.js +25 -5
- package/internal/core/providers/construction.js.map +1 -1
- package/internal/core/providers/http.d.ts +2 -2
- package/internal/core/providers/http.d.ts.map +1 -1
- package/internal/core/providers/http.js +28 -4
- package/internal/core/providers/http.js.map +1 -1
- package/internal/hardhat-network/jsonrpc/handler.d.ts +1 -0
- package/internal/hardhat-network/jsonrpc/handler.d.ts.map +1 -1
- package/internal/hardhat-network/jsonrpc/handler.js +13 -18
- package/internal/hardhat-network/jsonrpc/handler.js.map +1 -1
- package/internal/hardhat-network/provider/modules/evm.d.ts +2 -1
- package/internal/hardhat-network/provider/modules/evm.d.ts.map +1 -1
- package/internal/hardhat-network/provider/modules/evm.js +10 -4
- package/internal/hardhat-network/provider/modules/evm.js.map +1 -1
- package/internal/hardhat-network/provider/node-types.d.ts +1 -1
- package/internal/hardhat-network/provider/node-types.d.ts.map +1 -1
- package/internal/hardhat-network/provider/node.d.ts +1 -0
- package/internal/hardhat-network/provider/node.d.ts.map +1 -1
- package/internal/hardhat-network/provider/node.js +6 -4
- package/internal/hardhat-network/provider/node.js.map +1 -1
- package/internal/hardhat-network/provider/provider.d.ts +25 -21
- package/internal/hardhat-network/provider/provider.d.ts.map +1 -1
- package/internal/hardhat-network/provider/provider.js +25 -42
- package/internal/hardhat-network/provider/provider.js.map +1 -1
- package/internal/hardhat-network/provider/utils/putGenesisBlock.d.ts +1 -1
- package/internal/hardhat-network/provider/utils/putGenesisBlock.d.ts.map +1 -1
- package/internal/hardhat-network/provider/utils/putGenesisBlock.js +2 -2
- package/internal/hardhat-network/provider/utils/putGenesisBlock.js.map +1 -1
- package/internal/util/download.d.ts.map +1 -1
- package/internal/util/download.js +12 -9
- package/internal/util/download.js.map +1 -1
- package/internal/util/proxy.d.ts +2 -0
- package/internal/util/proxy.d.ts.map +1 -0
- package/internal/util/proxy.js +19 -0
- package/internal/util/proxy.js.map +1 -0
- package/package.json +1 -2
- package/src/internal/core/config/config-loading.ts +3 -1
- package/src/internal/core/config/config-validation.ts +20 -0
- package/src/internal/core/providers/construction.ts +29 -24
- package/src/internal/core/providers/http.ts +16 -10
- package/src/internal/hardhat-network/jsonrpc/handler.ts +31 -28
- package/src/internal/hardhat-network/provider/modules/evm.ts +15 -3
- package/src/internal/hardhat-network/provider/node-types.ts +1 -1
- package/src/internal/hardhat-network/provider/node.ts +5 -1
- package/src/internal/hardhat-network/provider/provider.ts +60 -49
- package/src/internal/hardhat-network/provider/utils/putGenesisBlock.ts +2 -2
- package/src/internal/util/download.ts +12 -11
- package/src/internal/util/proxy.ts +18 -0
- package/src/types/config.ts +2 -0
- package/types/config.d.ts +2 -0
- package/types/config.d.ts.map +1 -1
|
@@ -6,14 +6,14 @@ const ethereumjs_util_1 = require("@nomicfoundation/ethereumjs-util");
|
|
|
6
6
|
const date_1 = require("../../../util/date");
|
|
7
7
|
const hardforks_1 = require("../../../util/hardforks");
|
|
8
8
|
const getCurrentTimestamp_1 = require("./getCurrentTimestamp");
|
|
9
|
-
async function putGenesisBlock(blockchain, common, { initialDate, blockGasLimit }, stateTrie, hardfork, initialMixHash, initialBaseFee) {
|
|
9
|
+
async function putGenesisBlock(blockchain, common, { initialDate, blockGasLimit: initialBlockGasLimit }, stateTrie, hardfork, initialMixHash, initialBaseFee) {
|
|
10
10
|
const initialBlockTimestamp = initialDate !== undefined
|
|
11
11
|
? (0, date_1.dateToTimestampSeconds)(initialDate)
|
|
12
12
|
: (0, getCurrentTimestamp_1.getCurrentTimestamp)();
|
|
13
13
|
const isPostMerge = (0, hardforks_1.hardforkGte)(hardfork, hardforks_1.HardforkName.MERGE);
|
|
14
14
|
const header = {
|
|
15
15
|
timestamp: `0x${initialBlockTimestamp.toString(16)}`,
|
|
16
|
-
gasLimit:
|
|
16
|
+
gasLimit: initialBlockGasLimit,
|
|
17
17
|
difficulty: isPostMerge ? 0 : 1,
|
|
18
18
|
nonce: isPostMerge ? "0x0000000000000000" : "0x0000000000000042",
|
|
19
19
|
extraData: "0x1234",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"putGenesisBlock.js","sourceRoot":"","sources":["../../../../src/internal/hardhat-network/provider/utils/putGenesisBlock.ts"],"names":[],"mappings":";;;AAAA,wEAAsE;AAGtE,sEAA+D;AAE/D,6CAA4D;AAC5D,uDAAoE;AAGpE,+DAA4D;AAErD,KAAK,UAAU,eAAe,CACnC,UAA6B,EAC7B,MAAc,EACd,EAAE,WAAW,EAAE,aAAa,EAAmB,
|
|
1
|
+
{"version":3,"file":"putGenesisBlock.js","sourceRoot":"","sources":["../../../../src/internal/hardhat-network/provider/utils/putGenesisBlock.ts"],"names":[],"mappings":";;;AAAA,wEAAsE;AAGtE,sEAA+D;AAE/D,6CAA4D;AAC5D,uDAAoE;AAGpE,+DAA4D;AAErD,KAAK,UAAU,eAAe,CACnC,UAA6B,EAC7B,MAAc,EACd,EAAE,WAAW,EAAE,aAAa,EAAE,oBAAoB,EAAmB,EACrE,SAAe,EACf,QAAsB,EACtB,cAAsB,EACtB,cAAuB;IAEvB,MAAM,qBAAqB,GACzB,WAAW,KAAK,SAAS;QACvB,CAAC,CAAC,IAAA,6BAAsB,EAAC,WAAW,CAAC;QACrC,CAAC,CAAC,IAAA,yCAAmB,GAAE,CAAC;IAE5B,MAAM,WAAW,GAAG,IAAA,uBAAW,EAAC,QAAQ,EAAE,wBAAY,CAAC,KAAK,CAAC,CAAC;IAE9D,MAAM,MAAM,GAAe;QACzB,SAAS,EAAE,KAAK,qBAAqB,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE;QACpD,QAAQ,EAAE,oBAAoB;QAC9B,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/B,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,oBAAoB;QAChE,SAAS,EAAE,QAAQ;QACnB,SAAS,EAAE,IAAA,6BAAW,EAAC,SAAS,CAAC,IAAI,EAAE,CAAC;KACzC,CAAC;IAEF,IAAI,WAAW,EAAE;QACf,MAAM,CAAC,OAAO,GAAG,cAAc,CAAC;KACjC;IAED,IAAI,cAAc,KAAK,SAAS,EAAE;QAChC,MAAM,CAAC,aAAa,GAAG,cAAc,CAAC;KACvC;IAED,MAAM,YAAY,GAAG,wBAAK,CAAC,aAAa,CACtC;QACE,MAAM;KACP,EACD;QACE,MAAM;QACN,6BAA6B,EAAE,IAAI;KACpC,CACF,CAAC;IAEF,MAAM,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;AAC1C,CAAC;AA5CD,0CA4CC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../src/internal/util/download.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../src/internal/util/download.ts"],"names":[],"mappings":"AAsBA,wBAAsB,QAAQ,CAC5B,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,aAAa,SAAQ,EACrB,YAAY,GAAE;IAAE,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;CAAO,iBA4C9C"}
|
|
@@ -28,6 +28,7 @@ const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
|
28
28
|
const path_1 = __importDefault(require("path"));
|
|
29
29
|
const util_1 = __importDefault(require("util"));
|
|
30
30
|
const packageInfo_1 = require("./packageInfo");
|
|
31
|
+
const proxy_1 = require("./proxy");
|
|
31
32
|
const TEMP_FILE_PREFIX = "tmp-";
|
|
32
33
|
function resolveTempFileName(filePath) {
|
|
33
34
|
const { dir, ext, name } = path_1.default.parse(filePath);
|
|
@@ -41,19 +42,17 @@ async function download(url, filePath, timeoutMillis = 10000, extraHeaders = {})
|
|
|
41
42
|
const { pipeline } = await Promise.resolve().then(() => __importStar(require("stream")));
|
|
42
43
|
const { getGlobalDispatcher, ProxyAgent, request } = await Promise.resolve().then(() => __importStar(require("undici")));
|
|
43
44
|
const streamPipeline = util_1.default.promisify(pipeline);
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
return getGlobalDispatcher();
|
|
45
|
+
let dispatcher;
|
|
46
|
+
if (process.env.http_proxy !== undefined && (0, proxy_1.shouldUseProxy)(url)) {
|
|
47
|
+
dispatcher = new ProxyAgent(process.env.http_proxy);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
dispatcher = getGlobalDispatcher();
|
|
52
51
|
}
|
|
53
52
|
const hardhatVersion = (0, packageInfo_1.getHardhatVersion)();
|
|
54
53
|
// Fetch the url
|
|
55
54
|
const response = await request(url, {
|
|
56
|
-
dispatcher
|
|
55
|
+
dispatcher,
|
|
57
56
|
headersTimeout: timeoutMillis,
|
|
58
57
|
maxRedirections: 10,
|
|
59
58
|
method: "GET",
|
|
@@ -68,6 +67,10 @@ async function download(url, filePath, timeoutMillis = 10000, extraHeaders = {})
|
|
|
68
67
|
await streamPipeline(response.body, fs_1.default.createWriteStream(tmpFilePath));
|
|
69
68
|
return fs_extra_1.default.move(tmpFilePath, filePath, { overwrite: true });
|
|
70
69
|
}
|
|
70
|
+
else {
|
|
71
|
+
// undici's response bodies must always be consumed to prevent leaks
|
|
72
|
+
await response.body.text();
|
|
73
|
+
}
|
|
71
74
|
// eslint-disable-next-line @nomiclabs/hardhat-internal-rules/only-hardhat-error
|
|
72
75
|
throw new Error(`Failed to download ${url} - ${response.statusCode} received. ${await response.body.text()}`);
|
|
73
76
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"download.js","sourceRoot":"","sources":["../../src/internal/util/download.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"download.js","sourceRoot":"","sources":["../../src/internal/util/download.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAEA,4CAAoB;AACpB,wDAA+B;AAC/B,gDAAwB;AACxB,gDAAwB;AAExB,+CAAkD;AAClD,mCAAyC;AAEzC,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEhC,SAAS,mBAAmB,CAAC,QAAgB;IAC3C,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,cAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAEhD,OAAO,cAAI,CAAC,MAAM,CAAC;QACjB,GAAG;QACH,GAAG;QACH,IAAI,EAAE,GAAG,gBAAgB,GAAG,IAAI,EAAE;KACnC,CAAC,CAAC;AACL,CAAC;AAEM,KAAK,UAAU,QAAQ,CAC5B,GAAW,EACX,QAAgB,EAChB,aAAa,GAAG,KAAK,EACrB,eAA2C,EAAE;IAE7C,MAAM,EAAE,QAAQ,EAAE,GAAG,wDAAa,QAAQ,GAAC,CAAC;IAC5C,MAAM,EAAE,mBAAmB,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,wDAAa,QAAQ,GAAC,CAAC;IAC5E,MAAM,cAAc,GAAG,cAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAEhD,IAAI,UAAsB,CAAC;IAC3B,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,KAAK,SAAS,IAAI,IAAA,sBAAc,EAAC,GAAG,CAAC,EAAE;QAC/D,UAAU,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;KACrD;SAAM;QACL,UAAU,GAAG,mBAAmB,EAAE,CAAC;KACpC;IAED,MAAM,cAAc,GAAG,IAAA,+BAAiB,GAAE,CAAC;IAE3C,gBAAgB;IAChB,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE;QAClC,UAAU;QACV,cAAc,EAAE,aAAa;QAC7B,eAAe,EAAE,EAAE;QACnB,MAAM,EAAE,KAAK;QACb,OAAO,EAAE;YACP,GAAG,YAAY;YACf,YAAY,EAAE,WAAW,cAAc,EAAE;SAC1C;KACF,CAAC,CAAC;IAEH,IAAI,QAAQ,CAAC,UAAU,IAAI,GAAG,IAAI,QAAQ,CAAC,UAAU,IAAI,GAAG,EAAE;QAC5D,MAAM,WAAW,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QAClD,MAAM,kBAAO,CAAC,SAAS,CAAC,cAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;QAEhD,MAAM,cAAc,CAAC,QAAQ,CAAC,IAAI,EAAE,YAAE,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC,CAAC;QACvE,OAAO,kBAAO,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;KACjE;SAAM;QACL,oEAAoE;QACpE,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;KAC5B;IAED,gFAAgF;IAChF,MAAM,IAAI,KAAK,CACb,sBAAsB,GAAG,MACvB,QAAQ,CAAC,UACX,cAAc,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAC3C,CAAC;AACJ,CAAC;AAhDD,4BAgDC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/internal/util/proxy.ts"],"names":[],"mappings":"AAAA,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAiBnD"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.shouldUseProxy = void 0;
|
|
4
|
+
function shouldUseProxy(url) {
|
|
5
|
+
const { hostname } = new URL(url);
|
|
6
|
+
const noProxy = process.env.NO_PROXY;
|
|
7
|
+
if (hostname === "localhost" || hostname === "127.0.0.1" || noProxy === "*") {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
if (noProxy !== undefined && noProxy !== "") {
|
|
11
|
+
const noProxyList = noProxy.split(",");
|
|
12
|
+
if (noProxyList.includes(hostname)) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
exports.shouldUseProxy = shouldUseProxy;
|
|
19
|
+
//# sourceMappingURL=proxy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy.js","sourceRoot":"","sources":["../../src/internal/util/proxy.ts"],"names":[],"mappings":";;;AAAA,SAAgB,cAAc,CAAC,GAAW;IACxC,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IAClC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC;IAErC,IAAI,QAAQ,KAAK,WAAW,IAAI,QAAQ,KAAK,WAAW,IAAI,OAAO,KAAK,GAAG,EAAE;QAC3E,OAAO,KAAK,CAAC;KACd;IAED,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,EAAE,EAAE;QAC3C,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAEvC,IAAI,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE;YAClC,OAAO,KAAK,CAAC;SACd;KACF;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAjBD,wCAiBC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hardhat",
|
|
3
|
-
"version": "2.12.
|
|
3
|
+
"version": "2.12.7",
|
|
4
4
|
"author": "Nomic Labs LLC",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://hardhat.org",
|
|
@@ -90,7 +90,6 @@
|
|
|
90
90
|
"ethers": "^5.0.0",
|
|
91
91
|
"mocha": "^10.0.0",
|
|
92
92
|
"prettier": "2.4.1",
|
|
93
|
-
"proxy": "^1.0.2",
|
|
94
93
|
"rimraf": "^3.0.2",
|
|
95
94
|
"sinon": "^9.0.0",
|
|
96
95
|
"time-require": "^0.1.2",
|
|
@@ -19,7 +19,7 @@ import { getUserConfigPath } from "../project-structure";
|
|
|
19
19
|
|
|
20
20
|
import { SUPPORTED_SOLIDITY_VERSION_RANGE } from "../../hardhat-network/stack-traces/constants";
|
|
21
21
|
import { resolveConfig } from "./config-resolution";
|
|
22
|
-
import { validateConfig } from "./config-validation";
|
|
22
|
+
import { validateConfig, validateResolvedConfig } from "./config-validation";
|
|
23
23
|
import { DEFAULT_SOLC_VERSION } from "./default-config";
|
|
24
24
|
|
|
25
25
|
const log = debug("hardhat:core:config");
|
|
@@ -108,6 +108,8 @@ export function loadConfigAndTasks(
|
|
|
108
108
|
extender(resolved, frozenUserConfig);
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
+
validateResolvedConfig(resolved);
|
|
112
|
+
|
|
111
113
|
if (showSolidityConfigWarnings) {
|
|
112
114
|
checkUnsupportedSolidityConfig(resolved);
|
|
113
115
|
checkUnsupportedRemappings(resolved);
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { HardhatConfig as HardhatConfigT } from "../../../types";
|
|
2
|
+
|
|
1
3
|
import * as t from "io-ts";
|
|
2
4
|
import { Context, getFunctionName, ValidationError } from "io-ts/lib";
|
|
3
5
|
import { Reporter } from "io-ts/lib/Reporter";
|
|
@@ -573,3 +575,21 @@ export function getValidationErrors(config: any): string[] {
|
|
|
573
575
|
const ioTsErrors = DotPathReporter.report(result);
|
|
574
576
|
return [...errors, ...ioTsErrors];
|
|
575
577
|
}
|
|
578
|
+
|
|
579
|
+
export function validateResolvedConfig(resolvedConfig: HardhatConfigT) {
|
|
580
|
+
const solcConfigs = [
|
|
581
|
+
...resolvedConfig.solidity.compilers,
|
|
582
|
+
...Object.values(resolvedConfig.solidity.overrides),
|
|
583
|
+
];
|
|
584
|
+
const runs = solcConfigs
|
|
585
|
+
.filter(({ settings }) => settings?.optimizer?.runs !== undefined)
|
|
586
|
+
.map(({ settings }) => settings?.optimizer?.runs);
|
|
587
|
+
|
|
588
|
+
for (const run of runs) {
|
|
589
|
+
if (run >= 2 ** 32) {
|
|
590
|
+
throw new HardhatError(ERRORS.GENERAL.INVALID_CONFIG, {
|
|
591
|
+
errors: "The number of optimizer runs exceeds the maximum of 2**32 - 1",
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
}
|
|
@@ -86,31 +86,36 @@ export function createProvider(
|
|
|
86
86
|
require("../../hardhat-network/provider/utils/disk-cache") as typeof DiskCacheT;
|
|
87
87
|
|
|
88
88
|
eip1193Provider = new HardhatNetworkProvider(
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
89
|
+
{
|
|
90
|
+
chainId: hardhatNetConfig.chainId,
|
|
91
|
+
networkId: hardhatNetConfig.chainId,
|
|
92
|
+
hardfork: hardhatNetConfig.hardfork,
|
|
93
|
+
blockGasLimit: hardhatNetConfig.blockGasLimit,
|
|
94
|
+
initialBaseFeePerGas: hardhatNetConfig.initialBaseFeePerGas,
|
|
95
|
+
minGasPrice: hardhatNetConfig.minGasPrice,
|
|
96
|
+
throwOnTransactionFailures: hardhatNetConfig.throwOnTransactionFailures,
|
|
97
|
+
throwOnCallFailures: hardhatNetConfig.throwOnCallFailures,
|
|
98
|
+
automine: hardhatNetConfig.mining.auto,
|
|
99
|
+
intervalMining: hardhatNetConfig.mining.interval,
|
|
100
|
+
// This cast is valid because of the config validation and resolution
|
|
101
|
+
mempoolOrder: hardhatNetConfig.mining.mempool.order as MempoolOrder,
|
|
102
|
+
chains: hardhatNetConfig.chains,
|
|
103
|
+
coinbase: hardhatNetConfig.coinbase,
|
|
104
|
+
genesisAccounts: accounts,
|
|
105
|
+
allowUnlimitedContractSize: hardhatNetConfig.allowUnlimitedContractSize,
|
|
106
|
+
allowBlocksWithSameTimestamp:
|
|
107
|
+
hardhatNetConfig.allowBlocksWithSameTimestamp ?? false,
|
|
108
|
+
initialDate:
|
|
109
|
+
hardhatNetConfig.initialDate !== undefined
|
|
110
|
+
? parseDateString(hardhatNetConfig.initialDate)
|
|
111
|
+
: undefined,
|
|
112
|
+
experimentalHardhatNetworkMessageTraceHooks,
|
|
113
|
+
forkConfig,
|
|
114
|
+
forkCachePath:
|
|
115
|
+
paths !== undefined ? getForkCacheDirPath(paths) : undefined,
|
|
116
|
+
},
|
|
103
117
|
new ModulesLogger(hardhatNetConfig.loggingEnabled),
|
|
104
|
-
|
|
105
|
-
artifacts,
|
|
106
|
-
hardhatNetConfig.allowUnlimitedContractSize,
|
|
107
|
-
hardhatNetConfig.initialDate !== undefined
|
|
108
|
-
? parseDateString(hardhatNetConfig.initialDate)
|
|
109
|
-
: undefined,
|
|
110
|
-
experimentalHardhatNetworkMessageTraceHooks,
|
|
111
|
-
forkConfig,
|
|
112
|
-
paths !== undefined ? getForkCacheDirPath(paths) : undefined,
|
|
113
|
-
hardhatNetConfig.coinbase
|
|
118
|
+
artifacts
|
|
114
119
|
);
|
|
115
120
|
} else {
|
|
116
121
|
const HttpProvider = importProvider<
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import type * as Undici from "undici";
|
|
2
2
|
|
|
3
3
|
import { EventEmitter } from "events";
|
|
4
4
|
|
|
@@ -17,6 +17,7 @@ import {
|
|
|
17
17
|
import { getHardhatVersion } from "../../util/packageInfo";
|
|
18
18
|
import { HardhatError } from "../errors";
|
|
19
19
|
import { ERRORS } from "../errors-list";
|
|
20
|
+
import { shouldUseProxy } from "../../util/proxy";
|
|
20
21
|
|
|
21
22
|
import { ProviderError } from "./errors";
|
|
22
23
|
|
|
@@ -33,7 +34,7 @@ const hardhatVersion = getHardhatVersion();
|
|
|
33
34
|
|
|
34
35
|
export class HttpProvider extends EventEmitter implements EIP1193Provider {
|
|
35
36
|
private _nextRequestId = 1;
|
|
36
|
-
private _dispatcher: Dispatcher;
|
|
37
|
+
private _dispatcher: Undici.Dispatcher;
|
|
37
38
|
private _path: string;
|
|
38
39
|
private _authHeader: string | undefined;
|
|
39
40
|
|
|
@@ -42,11 +43,11 @@ export class HttpProvider extends EventEmitter implements EIP1193Provider {
|
|
|
42
43
|
private readonly _networkName: string,
|
|
43
44
|
private readonly _extraHeaders: { [name: string]: string } = {},
|
|
44
45
|
private readonly _timeout = 20000,
|
|
45
|
-
client: Dispatcher | undefined = undefined
|
|
46
|
+
client: Undici.Dispatcher | undefined = undefined
|
|
46
47
|
) {
|
|
47
48
|
super();
|
|
48
49
|
|
|
49
|
-
const { Pool } = require("undici") as
|
|
50
|
+
const { Pool, ProxyAgent } = require("undici") as typeof Undici;
|
|
50
51
|
|
|
51
52
|
const url = new URL(this._url);
|
|
52
53
|
this._path = url.pathname;
|
|
@@ -59,6 +60,10 @@ export class HttpProvider extends EventEmitter implements EIP1193Provider {
|
|
|
59
60
|
).toString("base64")}`;
|
|
60
61
|
try {
|
|
61
62
|
this._dispatcher = client ?? new Pool(url.origin);
|
|
63
|
+
|
|
64
|
+
if (process.env.http_proxy !== undefined && shouldUseProxy(url.origin)) {
|
|
65
|
+
this._dispatcher = new ProxyAgent(process.env.http_proxy);
|
|
66
|
+
}
|
|
62
67
|
} catch (e) {
|
|
63
68
|
if (e instanceof TypeError && e.message === "Invalid URL") {
|
|
64
69
|
e.message += ` ${url.origin}`;
|
|
@@ -163,10 +168,13 @@ export class HttpProvider extends EventEmitter implements EIP1193Provider {
|
|
|
163
168
|
request: JsonRpcRequest | JsonRpcRequest[],
|
|
164
169
|
retryNumber = 0
|
|
165
170
|
): Promise<JsonRpcResponse | JsonRpcResponse[]> {
|
|
171
|
+
const { request: sendRequest } = await import("undici");
|
|
172
|
+
const url = new URL(this._url);
|
|
173
|
+
|
|
166
174
|
try {
|
|
167
|
-
const response = await
|
|
175
|
+
const response = await sendRequest(url, {
|
|
176
|
+
dispatcher: this._dispatcher,
|
|
168
177
|
method: "POST",
|
|
169
|
-
path: this._path,
|
|
170
178
|
body: JSON.stringify(request),
|
|
171
179
|
maxRedirections: 10,
|
|
172
180
|
headersTimeout:
|
|
@@ -194,8 +202,6 @@ export class HttpProvider extends EventEmitter implements EIP1193Provider {
|
|
|
194
202
|
return await this._retry(request, seconds, retryNumber);
|
|
195
203
|
}
|
|
196
204
|
|
|
197
|
-
const url = new URL(this._url);
|
|
198
|
-
|
|
199
205
|
// eslint-disable-next-line @nomiclabs/hardhat-internal-rules/only-hardhat-error
|
|
200
206
|
throw new ProviderError(
|
|
201
207
|
`Too Many Requests error received from ${url.hostname}`,
|
|
@@ -255,12 +261,12 @@ export class HttpProvider extends EventEmitter implements EIP1193Provider {
|
|
|
255
261
|
return true;
|
|
256
262
|
}
|
|
257
263
|
|
|
258
|
-
private _isRateLimitResponse(response: Dispatcher.ResponseData) {
|
|
264
|
+
private _isRateLimitResponse(response: Undici.Dispatcher.ResponseData) {
|
|
259
265
|
return response.statusCode === TOO_MANY_REQUEST_STATUS;
|
|
260
266
|
}
|
|
261
267
|
|
|
262
268
|
private _getRetryAfterSeconds(
|
|
263
|
-
response: Dispatcher.ResponseData
|
|
269
|
+
response: Undici.Dispatcher.ResponseData
|
|
264
270
|
): number | undefined {
|
|
265
271
|
const header = response.headers["retry-after"];
|
|
266
272
|
|
|
@@ -82,40 +82,23 @@ export class JsonRpcHandler {
|
|
|
82
82
|
this._provider.addListener("notification", listener);
|
|
83
83
|
|
|
84
84
|
ws.on("message", async (msg) => {
|
|
85
|
-
let rpcReq: JsonRpcRequest |
|
|
86
|
-
let rpcResp: JsonRpcResponse |
|
|
85
|
+
let rpcReq: JsonRpcRequest | JsonRpcRequest[];
|
|
86
|
+
let rpcResp: JsonRpcResponse | JsonRpcResponse[];
|
|
87
87
|
|
|
88
88
|
try {
|
|
89
89
|
rpcReq = _readWsRequest(msg as string);
|
|
90
90
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
// so we can cleanup on websocket close.
|
|
99
|
-
if (
|
|
100
|
-
rpcReq.method === "eth_subscribe" &&
|
|
101
|
-
isSuccessfulJsonResponse(rpcResp)
|
|
102
|
-
) {
|
|
103
|
-
subscriptions.push(rpcResp.result);
|
|
104
|
-
}
|
|
91
|
+
rpcResp = Array.isArray(rpcReq)
|
|
92
|
+
? await Promise.all(
|
|
93
|
+
rpcReq.map((req) =>
|
|
94
|
+
this._handleSingleWsRequest(req, subscriptions)
|
|
95
|
+
)
|
|
96
|
+
)
|
|
97
|
+
: await this._handleSingleWsRequest(rpcReq, subscriptions);
|
|
105
98
|
} catch (error) {
|
|
106
99
|
rpcResp = _handleError(error);
|
|
107
100
|
}
|
|
108
101
|
|
|
109
|
-
// Validate the RPC response.
|
|
110
|
-
if (!isValidJsonResponse(rpcResp)) {
|
|
111
|
-
// Malformed response coming from the provider, report to user as an internal error.
|
|
112
|
-
rpcResp = _handleError(new InternalError("Internal error"));
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
if (rpcReq !== undefined) {
|
|
116
|
-
rpcResp.id = rpcReq.id;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
102
|
ws.send(JSON.stringify(rpcResp));
|
|
120
103
|
});
|
|
121
104
|
|
|
@@ -155,7 +138,9 @@ export class JsonRpcHandler {
|
|
|
155
138
|
res.end(JSON.stringify(rpcResp));
|
|
156
139
|
}
|
|
157
140
|
|
|
158
|
-
private async _handleSingleRequest(
|
|
141
|
+
private async _handleSingleRequest(
|
|
142
|
+
req: JsonRpcRequest
|
|
143
|
+
): Promise<JsonRpcResponse> {
|
|
159
144
|
if (!isValidJsonRequest(req)) {
|
|
160
145
|
return _handleError(new InvalidRequestError("Invalid request"));
|
|
161
146
|
}
|
|
@@ -182,6 +167,24 @@ export class JsonRpcHandler {
|
|
|
182
167
|
return rpcResp;
|
|
183
168
|
}
|
|
184
169
|
|
|
170
|
+
private async _handleSingleWsRequest(
|
|
171
|
+
rpcReq: JsonRpcRequest,
|
|
172
|
+
subscriptions: string[]
|
|
173
|
+
) {
|
|
174
|
+
const rpcResp = await this._handleSingleRequest(rpcReq);
|
|
175
|
+
|
|
176
|
+
// If eth_subscribe was successful, keep track of the subscription id,
|
|
177
|
+
// so we can cleanup on websocket close.
|
|
178
|
+
if (
|
|
179
|
+
rpcReq.method === "eth_subscribe" &&
|
|
180
|
+
isSuccessfulJsonResponse(rpcResp)
|
|
181
|
+
) {
|
|
182
|
+
subscriptions.push(rpcResp.result);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return rpcResp;
|
|
186
|
+
}
|
|
187
|
+
|
|
185
188
|
private _handleRequest = async (
|
|
186
189
|
req: JsonRpcRequest
|
|
187
190
|
): Promise<JsonRpcResponse> => {
|
|
@@ -218,7 +221,7 @@ const _readJsonHttpRequest = async (req: IncomingMessage): Promise<any> => {
|
|
|
218
221
|
return json;
|
|
219
222
|
};
|
|
220
223
|
|
|
221
|
-
const _readWsRequest = (msg: string): JsonRpcRequest => {
|
|
224
|
+
const _readWsRequest = (msg: string): JsonRpcRequest | JsonRpcRequest[] => {
|
|
222
225
|
let json: any;
|
|
223
226
|
try {
|
|
224
227
|
json = JSON.parse(msg);
|
|
@@ -32,6 +32,7 @@ export class EvmModule {
|
|
|
32
32
|
private readonly _node: HardhatNode,
|
|
33
33
|
private readonly _miningTimer: MiningTimer,
|
|
34
34
|
private readonly _logger: ModulesLogger,
|
|
35
|
+
private readonly _allowBlocksWithSameTimestamp: boolean,
|
|
35
36
|
private readonly _experimentalHardhatNetworkMessageTraceHooks: BoundExperimentalHardhatNetworkMessageTraceHook[] = []
|
|
36
37
|
) {}
|
|
37
38
|
|
|
@@ -86,12 +87,23 @@ export class EvmModule {
|
|
|
86
87
|
const latestBlock = await this._node.getLatestBlock();
|
|
87
88
|
const increment = BigInt(timestamp) - latestBlock.header.timestamp;
|
|
88
89
|
|
|
89
|
-
if (increment
|
|
90
|
+
if (increment < 0n) {
|
|
90
91
|
throw new InvalidInputError(
|
|
91
|
-
`Timestamp ${timestamp.toString()} is lower than
|
|
92
|
-
|
|
92
|
+
`Timestamp ${timestamp.toString()} is lower than the previous block's timestamp ${
|
|
93
|
+
latestBlock.header.timestamp
|
|
94
|
+
}`
|
|
93
95
|
);
|
|
94
96
|
}
|
|
97
|
+
|
|
98
|
+
if (!this._allowBlocksWithSameTimestamp && increment === 0n) {
|
|
99
|
+
throw new InvalidInputError(
|
|
100
|
+
`Timestamp ${timestamp.toString()} is equal to the previous block's timestamp.
|
|
101
|
+
|
|
102
|
+
Enable the "allowBlocksWithSameTimestamp" option in the Hardhat network configuration to allow this.
|
|
103
|
+
`
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
95
107
|
this._node.setNextBlockTimestamp(BigInt(timestamp));
|
|
96
108
|
return timestamp.toString();
|
|
97
109
|
}
|
|
@@ -24,7 +24,6 @@ interface CommonConfig {
|
|
|
24
24
|
hardfork: string;
|
|
25
25
|
minGasPrice: bigint;
|
|
26
26
|
networkId: number;
|
|
27
|
-
networkName: string;
|
|
28
27
|
allowUnlimitedContractSize?: boolean;
|
|
29
28
|
initialDate?: Date;
|
|
30
29
|
tracingConfig?: TracingConfig;
|
|
@@ -32,6 +31,7 @@ interface CommonConfig {
|
|
|
32
31
|
mempoolOrder: MempoolOrder;
|
|
33
32
|
coinbase: string;
|
|
34
33
|
chains: HardhatNetworkChainsConfig;
|
|
34
|
+
allowBlocksWithSameTimestamp: boolean;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
export type LocalNodeConfig = CommonConfig;
|
|
@@ -146,6 +146,7 @@ export class HardhatNode extends EventEmitter {
|
|
|
146
146
|
mempoolOrder,
|
|
147
147
|
networkId,
|
|
148
148
|
chainId,
|
|
149
|
+
allowBlocksWithSameTimestamp,
|
|
149
150
|
} = config;
|
|
150
151
|
|
|
151
152
|
let stateManager: StateManager;
|
|
@@ -293,6 +294,7 @@ export class HardhatNode extends EventEmitter {
|
|
|
293
294
|
hardfork,
|
|
294
295
|
hardforkActivations,
|
|
295
296
|
mixHashGenerator,
|
|
297
|
+
allowBlocksWithSameTimestamp,
|
|
296
298
|
tracingConfig,
|
|
297
299
|
forkNetworkId,
|
|
298
300
|
forkBlockNum,
|
|
@@ -378,6 +380,7 @@ Hardhat Network's forking functionality only works with blocks from at least spu
|
|
|
378
380
|
public readonly hardfork: HardforkName,
|
|
379
381
|
private readonly _hardforkActivations: HardforkHistoryConfig,
|
|
380
382
|
private _mixHashGenerator: RandomBufferGenerator,
|
|
383
|
+
private _allowBlocksWithSameTimestamp: boolean,
|
|
381
384
|
tracingConfig?: TracingConfig,
|
|
382
385
|
private _forkNetworkId?: number,
|
|
383
386
|
private _forkBlockNumber?: bigint,
|
|
@@ -494,7 +497,8 @@ Hardhat Network's forking functionality only works with blocks from at least spu
|
|
|
494
497
|
const [, offsetShouldChange, newOffset] = timestampAndOffset;
|
|
495
498
|
|
|
496
499
|
const needsTimestampIncrease =
|
|
497
|
-
|
|
500
|
+
!this._allowBlocksWithSameTimestamp &&
|
|
501
|
+
(await this._timestampClashesWithPreviousBlockOne(blockTimestamp));
|
|
498
502
|
if (needsTimestampIncrease) {
|
|
499
503
|
blockTimestamp += 1n;
|
|
500
504
|
}
|