hardhat 2.8.4 → 2.9.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/LICENSE +3 -61
- package/README.md +1 -1
- package/builtin-tasks/compile.js +86 -51
- package/builtin-tasks/compile.js.map +1 -1
- package/builtin-tasks/node.js.map +1 -1
- package/builtin-tasks/test.js +30 -5
- package/builtin-tasks/test.js.map +1 -1
- package/builtin-tasks/utils/solidity-files-cache.d.ts.map +1 -1
- package/builtin-tasks/utils/solidity-files-cache.js.map +1 -1
- package/internal/cli/analytics.js +2 -2
- package/internal/cli/analytics.js.map +1 -1
- package/internal/cli/cli.js +3 -3
- package/internal/cli/project-creation.d.ts.map +1 -1
- package/internal/cli/project-creation.js +23 -0
- package/internal/cli/project-creation.js.map +1 -1
- package/internal/core/config/config-loading.d.ts.map +1 -1
- package/internal/core/config/config-loading.js.map +1 -1
- 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/config/default-config.d.ts +2 -0
- package/internal/core/config/default-config.d.ts.map +1 -1
- package/internal/core/config/default-config.js +1 -0
- package/internal/core/config/default-config.js.map +1 -1
- package/internal/core/errors-list.d.ts +7 -0
- package/internal/core/errors-list.d.ts.map +1 -1
- package/internal/core/errors-list.js +13 -0
- package/internal/core/errors-list.js.map +1 -1
- package/internal/core/providers/accounts.d.ts +1 -1
- package/internal/core/providers/accounts.d.ts.map +1 -1
- package/internal/core/providers/accounts.js +2 -2
- package/internal/core/providers/accounts.js.map +1 -1
- package/internal/core/providers/construction.d.ts.map +1 -1
- package/internal/core/providers/construction.js +1 -1
- package/internal/core/providers/construction.js.map +1 -1
- package/internal/core/providers/http.d.ts +5 -1
- package/internal/core/providers/http.d.ts.map +1 -1
- package/internal/core/providers/http.js +35 -31
- package/internal/core/providers/http.js.map +1 -1
- package/internal/core/providers/util.d.ts +1 -1
- package/internal/core/providers/util.d.ts.map +1 -1
- package/internal/core/providers/util.js +3 -3
- package/internal/core/providers/util.js.map +1 -1
- package/internal/hardhat-network/jsonrpc/server.d.ts.map +1 -1
- package/internal/hardhat-network/jsonrpc/server.js +7 -2
- package/internal/hardhat-network/jsonrpc/server.js.map +1 -1
- package/internal/hardhat-network/provider/BlockchainBase.d.ts +26 -0
- package/internal/hardhat-network/provider/BlockchainBase.d.ts.map +1 -0
- package/internal/hardhat-network/provider/BlockchainBase.js +92 -0
- package/internal/hardhat-network/provider/BlockchainBase.js.map +1 -0
- package/internal/hardhat-network/provider/BlockchainData.d.ts +32 -0
- package/internal/hardhat-network/provider/BlockchainData.d.ts.map +1 -1
- package/internal/hardhat-network/provider/BlockchainData.js +78 -1
- package/internal/hardhat-network/provider/BlockchainData.js.map +1 -1
- package/internal/hardhat-network/provider/HardhatBlockchain.d.ts +9 -15
- package/internal/hardhat-network/provider/HardhatBlockchain.d.ts.map +1 -1
- package/internal/hardhat-network/provider/HardhatBlockchain.js +15 -73
- package/internal/hardhat-network/provider/HardhatBlockchain.js.map +1 -1
- package/internal/hardhat-network/provider/fork/ForkBlockchain.d.ts +6 -14
- package/internal/hardhat-network/provider/fork/ForkBlockchain.d.ts.map +1 -1
- package/internal/hardhat-network/provider/fork/ForkBlockchain.js +23 -73
- package/internal/hardhat-network/provider/fork/ForkBlockchain.js.map +1 -1
- package/internal/hardhat-network/provider/modules/eth.js +2 -2
- package/internal/hardhat-network/provider/modules/eth.js.map +1 -1
- package/internal/hardhat-network/provider/modules/hardhat.d.ts +3 -0
- package/internal/hardhat-network/provider/modules/hardhat.d.ts.map +1 -1
- package/internal/hardhat-network/provider/modules/hardhat.js +40 -5
- package/internal/hardhat-network/provider/modules/hardhat.js.map +1 -1
- package/internal/hardhat-network/provider/modules/logger.d.ts +4 -2
- package/internal/hardhat-network/provider/modules/logger.d.ts.map +1 -1
- package/internal/hardhat-network/provider/modules/logger.js +38 -12
- package/internal/hardhat-network/provider/modules/logger.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 +9 -1
- package/internal/hardhat-network/provider/node.d.ts.map +1 -1
- package/internal/hardhat-network/provider/node.js +57 -8
- package/internal/hardhat-network/provider/node.js.map +1 -1
- package/internal/hardhat-network/provider/provider.d.ts +1 -1
- package/internal/hardhat-network/provider/provider.d.ts.map +1 -1
- package/internal/hardhat-network/provider/provider.js.map +1 -1
- package/internal/hardhat-network/provider/types/HardhatBlockchainInterface.d.ts +2 -1
- package/internal/hardhat-network/provider/types/HardhatBlockchainInterface.d.ts.map +1 -1
- package/internal/hardhat-network/provider/utils/makeForkClient.d.ts.map +1 -1
- package/internal/hardhat-network/provider/utils/makeForkClient.js +2 -1
- package/internal/hardhat-network/provider/utils/makeForkClient.js.map +1 -1
- package/internal/hardhat-network/provider/utils/putGenesisBlock.js +1 -1
- package/internal/hardhat-network/stack-traces/debug.js +1 -1
- package/internal/hardhat-network/stack-traces/debug.js.map +1 -1
- package/internal/hardhat-network/stack-traces/error-inferrer.d.ts.map +1 -1
- package/internal/hardhat-network/stack-traces/error-inferrer.js +21 -12
- package/internal/hardhat-network/stack-traces/error-inferrer.js.map +1 -1
- package/internal/hardhat-network/stack-traces/solidity-errors.js +2 -2
- package/internal/hardhat-network/stack-traces/solidity-errors.js.map +1 -1
- package/internal/hardhat-network/stack-traces/solidity-stack-trace.d.ts +3 -2
- package/internal/hardhat-network/stack-traces/solidity-stack-trace.d.ts.map +1 -1
- package/internal/solidity/compilation-job.d.ts.map +1 -1
- package/internal/solidity/compilation-job.js.map +1 -1
- package/internal/solidity/compiler/downloader.d.ts +2 -2
- package/internal/solidity/compiler/downloader.d.ts.map +1 -1
- package/internal/solidity/compiler/downloader.js +3 -3
- package/internal/solidity/compiler/downloader.js.map +1 -1
- package/internal/util/download.d.ts.map +1 -1
- package/internal/util/download.js +22 -24
- package/internal/util/download.js.map +1 -1
- package/internal/util/glob.d.ts.map +1 -1
- package/internal/util/glob.js.map +1 -1
- package/internal/util/global-dir.d.ts.map +1 -1
- package/internal/util/global-dir.js.map +1 -1
- package/internal/util/keys-derivation.d.ts +1 -1
- package/internal/util/keys-derivation.d.ts.map +1 -1
- package/internal/util/keys-derivation.js +2 -2
- package/internal/util/keys-derivation.js.map +1 -1
- package/package.json +10 -10
- package/sample-projects/advanced-ts/README.md +1 -1
- package/src/builtin-tasks/compile.ts +94 -76
- package/src/builtin-tasks/node.ts +2 -1
- package/src/builtin-tasks/test.ts +69 -11
- package/src/builtin-tasks/utils/solidity-files-cache.ts +3 -2
- package/src/internal/cli/analytics.ts +2 -2
- package/src/internal/cli/cli.ts +3 -3
- package/src/internal/cli/project-creation.ts +40 -0
- package/src/internal/core/config/config-loading.ts +2 -1
- package/src/internal/core/config/config-validation.ts +2 -0
- package/src/internal/core/config/default-config.ts +1 -0
- package/src/internal/core/errors-list.ts +13 -0
- package/src/internal/core/providers/accounts.ts +4 -2
- package/src/internal/core/providers/construction.ts +3 -1
- package/src/internal/core/providers/http.ts +47 -16
- package/src/internal/core/providers/util.ts +6 -3
- package/src/internal/hardhat-network/jsonrpc/server.ts +16 -3
- package/src/internal/hardhat-network/provider/BlockchainBase.ts +137 -0
- package/src/internal/hardhat-network/provider/BlockchainData.ts +144 -0
- package/src/internal/hardhat-network/provider/HardhatBlockchain.ts +34 -87
- package/src/internal/hardhat-network/provider/fork/ForkBlockchain.ts +45 -90
- package/src/internal/hardhat-network/provider/modules/eth.ts +2 -2
- package/src/internal/hardhat-network/provider/modules/hardhat.ts +51 -5
- package/src/internal/hardhat-network/provider/modules/logger.ts +50 -14
- package/src/internal/hardhat-network/provider/node-types.ts +2 -2
- package/src/internal/hardhat-network/provider/node.ts +81 -8
- package/src/internal/hardhat-network/provider/provider.ts +9 -8
- package/src/internal/hardhat-network/provider/types/HardhatBlockchainInterface.ts +7 -1
- package/src/internal/hardhat-network/provider/utils/makeForkClient.ts +2 -1
- package/src/internal/hardhat-network/provider/utils/putGenesisBlock.ts +1 -1
- package/src/internal/hardhat-network/stack-traces/debug.ts +1 -1
- package/src/internal/hardhat-network/stack-traces/error-inferrer.ts +21 -13
- package/src/internal/hardhat-network/stack-traces/solidity-errors.ts +2 -2
- package/src/internal/hardhat-network/stack-traces/solidity-stack-trace.ts +3 -2
- package/src/internal/solidity/compilation-job.ts +2 -1
- package/src/internal/solidity/compiler/downloader.ts +5 -3
- package/src/internal/util/download.ts +26 -31
- package/src/internal/util/glob.ts +1 -0
- package/src/internal/util/global-dir.ts +2 -1
- package/src/internal/util/keys-derivation.ts +3 -2
- package/src/types/config.ts +4 -0
- package/types/config.d.ts +4 -0
- package/types/config.d.ts.map +1 -1
|
@@ -1,60 +1,50 @@
|
|
|
1
1
|
import { Block } from "@ethereumjs/block";
|
|
2
|
+
import Common from "@ethereumjs/common";
|
|
2
3
|
import { TypedTransaction } from "@ethereumjs/tx";
|
|
3
4
|
import { BN, zeros } from "ethereumjs-util";
|
|
4
5
|
|
|
5
|
-
import {
|
|
6
|
+
import { BlockchainBase } from "./BlockchainBase";
|
|
6
7
|
import { FilterParams } from "./node-types";
|
|
7
|
-
import { RpcLogOutput
|
|
8
|
+
import { RpcLogOutput } from "./output";
|
|
8
9
|
import { HardhatBlockchainInterface } from "./types/HardhatBlockchainInterface";
|
|
9
10
|
|
|
10
11
|
/* eslint-disable @nomiclabs/hardhat-internal-rules/only-hardhat-error */
|
|
11
12
|
|
|
12
|
-
export class HardhatBlockchain
|
|
13
|
-
|
|
13
|
+
export class HardhatBlockchain
|
|
14
|
+
extends BlockchainBase
|
|
15
|
+
implements HardhatBlockchainInterface
|
|
16
|
+
{
|
|
14
17
|
private _length = 0;
|
|
15
18
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
if (block === undefined) {
|
|
19
|
-
throw new Error("No block available");
|
|
20
|
-
}
|
|
21
|
-
return block;
|
|
19
|
+
constructor(common: Common) {
|
|
20
|
+
super(common);
|
|
22
21
|
}
|
|
23
22
|
|
|
24
|
-
public
|
|
25
|
-
|
|
26
|
-
): Promise<Block | null> {
|
|
27
|
-
if (typeof blockHashOrNumber === "number") {
|
|
28
|
-
return this._data.getBlockByNumber(new BN(blockHashOrNumber)) ?? null;
|
|
29
|
-
}
|
|
30
|
-
if (BN.isBN(blockHashOrNumber)) {
|
|
31
|
-
return this._data.getBlockByNumber(blockHashOrNumber) ?? null;
|
|
32
|
-
}
|
|
33
|
-
return this._data.getBlockByHash(blockHashOrNumber) ?? null;
|
|
23
|
+
public getLatestBlockNumber(): BN {
|
|
24
|
+
return new BN(this._length - 1);
|
|
34
25
|
}
|
|
35
26
|
|
|
36
27
|
public async addBlock(block: Block): Promise<Block> {
|
|
37
28
|
this._validateBlock(block);
|
|
38
|
-
const totalDifficulty = this._computeTotalDifficulty(block);
|
|
29
|
+
const totalDifficulty = await this._computeTotalDifficulty(block);
|
|
39
30
|
this._data.addBlock(block, totalDifficulty);
|
|
40
31
|
this._length += 1;
|
|
41
32
|
return block;
|
|
42
33
|
}
|
|
43
34
|
|
|
44
|
-
public
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
this.deleteBlock(blockHash);
|
|
35
|
+
public reserveBlocks(
|
|
36
|
+
count: BN,
|
|
37
|
+
interval: BN,
|
|
38
|
+
previousBlockStateRoot: Buffer,
|
|
39
|
+
previousBlockTotalDifficulty: BN
|
|
40
|
+
) {
|
|
41
|
+
super.reserveBlocks(
|
|
42
|
+
count,
|
|
43
|
+
interval,
|
|
44
|
+
previousBlockStateRoot,
|
|
45
|
+
previousBlockTotalDifficulty
|
|
46
|
+
);
|
|
47
|
+
this._length = this._length + count.toNumber();
|
|
58
48
|
}
|
|
59
49
|
|
|
60
50
|
public deleteLaterBlocks(block: Block): void {
|
|
@@ -62,12 +52,8 @@ export class HardhatBlockchain implements HardhatBlockchainInterface {
|
|
|
62
52
|
if (actual === undefined) {
|
|
63
53
|
throw new Error("Invalid block");
|
|
64
54
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
);
|
|
68
|
-
if (nextBlock !== undefined) {
|
|
69
|
-
this._delBlock(nextBlock);
|
|
70
|
-
}
|
|
55
|
+
|
|
56
|
+
this._delBlock(actual.header.number.addn(1));
|
|
71
57
|
}
|
|
72
58
|
|
|
73
59
|
public async getTotalDifficulty(blockHash: Buffer): Promise<BN> {
|
|
@@ -84,12 +70,6 @@ export class HardhatBlockchain implements HardhatBlockchainInterface {
|
|
|
84
70
|
return this.getLocalTransaction(transactionHash);
|
|
85
71
|
}
|
|
86
72
|
|
|
87
|
-
public getLocalTransaction(
|
|
88
|
-
transactionHash: Buffer
|
|
89
|
-
): TypedTransaction | undefined {
|
|
90
|
-
return this._data.getTransaction(transactionHash);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
73
|
public async getBlockByTransactionHash(
|
|
94
74
|
transactionHash: Buffer
|
|
95
75
|
): Promise<Block | null> {
|
|
@@ -101,36 +81,21 @@ export class HardhatBlockchain implements HardhatBlockchainInterface {
|
|
|
101
81
|
return this._data.getTransactionReceipt(transactionHash) ?? null;
|
|
102
82
|
}
|
|
103
83
|
|
|
104
|
-
public addTransactionReceipts(receipts: RpcReceiptOutput[]) {
|
|
105
|
-
for (const receipt of receipts) {
|
|
106
|
-
this._data.addTransactionReceipt(receipt);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
84
|
public async getLogs(filterParams: FilterParams): Promise<RpcLogOutput[]> {
|
|
111
85
|
return this._data.getLogs(filterParams);
|
|
112
86
|
}
|
|
113
87
|
|
|
114
|
-
public iterator(
|
|
115
|
-
_name: string,
|
|
116
|
-
_onBlock: (block: Block, reorg: boolean) => void | Promise<void>
|
|
117
|
-
): Promise<number | void> {
|
|
118
|
-
throw new Error("Method not implemented.");
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
public async getBaseFee(): Promise<BN> {
|
|
122
|
-
const latestBlock = await this.getLatestBlock();
|
|
123
|
-
return latestBlock.header.calcNextBaseFee();
|
|
124
|
-
}
|
|
125
|
-
|
|
126
88
|
private _validateBlock(block: Block) {
|
|
127
89
|
const blockNumber = block.header.number.toNumber();
|
|
128
90
|
const parentHash = block.header.parentHash;
|
|
129
91
|
const parent = this._data.getBlockByNumber(new BN(blockNumber - 1));
|
|
130
92
|
|
|
131
93
|
if (this._length !== blockNumber) {
|
|
132
|
-
throw new Error(
|
|
94
|
+
throw new Error(
|
|
95
|
+
`Invalid block number ${blockNumber}. Expected ${this._length}.`
|
|
96
|
+
);
|
|
133
97
|
}
|
|
98
|
+
|
|
134
99
|
if (
|
|
135
100
|
(blockNumber === 0 && !parentHash.equals(zeros(32))) ||
|
|
136
101
|
(blockNumber > 0 &&
|
|
@@ -141,26 +106,8 @@ export class HardhatBlockchain implements HardhatBlockchainInterface {
|
|
|
141
106
|
}
|
|
142
107
|
}
|
|
143
108
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
return difficulty;
|
|
148
|
-
}
|
|
149
|
-
const parentTD = this._data.getTotalDifficulty(block.header.parentHash);
|
|
150
|
-
if (parentTD === undefined) {
|
|
151
|
-
throw new Error("This should never happen");
|
|
152
|
-
}
|
|
153
|
-
return parentTD.add(difficulty);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
private _delBlock(block: Block): void {
|
|
157
|
-
const blockNumber = block.header.number.toNumber();
|
|
158
|
-
for (let i = blockNumber; i < this._length; i++) {
|
|
159
|
-
const current = this._data.getBlockByNumber(new BN(i));
|
|
160
|
-
if (current !== undefined) {
|
|
161
|
-
this._data.removeBlock(current);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
this._length = blockNumber;
|
|
109
|
+
protected _delBlock(blockNumber: BN): void {
|
|
110
|
+
super._delBlock(blockNumber);
|
|
111
|
+
this._length = blockNumber.toNumber();
|
|
165
112
|
}
|
|
166
113
|
}
|
|
@@ -9,7 +9,7 @@ import { RpcTransactionReceipt } from "../../../core/jsonrpc/types/output/receip
|
|
|
9
9
|
import { RpcTransaction } from "../../../core/jsonrpc/types/output/transaction";
|
|
10
10
|
import { InternalError } from "../../../core/providers/errors";
|
|
11
11
|
import { JsonRpcClient } from "../../jsonrpc/client";
|
|
12
|
-
import {
|
|
12
|
+
import { BlockchainBase } from "../BlockchainBase";
|
|
13
13
|
import { FilterParams } from "../node-types";
|
|
14
14
|
import {
|
|
15
15
|
remoteReceiptToRpcReceiptOutput,
|
|
@@ -29,28 +29,35 @@ import { rpcToTxData } from "./rpcToTxData";
|
|
|
29
29
|
|
|
30
30
|
/* eslint-disable @nomiclabs/hardhat-internal-rules/only-hardhat-error */
|
|
31
31
|
|
|
32
|
-
export class ForkBlockchain
|
|
33
|
-
|
|
32
|
+
export class ForkBlockchain
|
|
33
|
+
extends BlockchainBase
|
|
34
|
+
implements HardhatBlockchainInterface
|
|
35
|
+
{
|
|
34
36
|
private _latestBlockNumber = this._forkBlockNumber;
|
|
35
37
|
|
|
36
38
|
constructor(
|
|
37
39
|
private _jsonRpcClient: JsonRpcClient,
|
|
38
40
|
private _forkBlockNumber: BN,
|
|
39
|
-
|
|
40
|
-
) {
|
|
41
|
+
common: Common
|
|
42
|
+
) {
|
|
43
|
+
super(common);
|
|
44
|
+
}
|
|
41
45
|
|
|
42
|
-
public
|
|
43
|
-
|
|
44
|
-
if (block === null) {
|
|
45
|
-
throw new Error("Block not found");
|
|
46
|
-
}
|
|
47
|
-
return block;
|
|
46
|
+
public getLatestBlockNumber(): BN {
|
|
47
|
+
return this._latestBlockNumber;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
public async getBlock(
|
|
51
51
|
blockHashOrNumber: Buffer | number | BN
|
|
52
52
|
): Promise<Block | null> {
|
|
53
|
-
|
|
53
|
+
if (
|
|
54
|
+
(typeof blockHashOrNumber === "number" || BN.isBN(blockHashOrNumber)) &&
|
|
55
|
+
this._data.isReservedBlock(new BN(blockHashOrNumber))
|
|
56
|
+
) {
|
|
57
|
+
this._data.fulfillBlockReservation(new BN(blockHashOrNumber));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
let block: Block | undefined | null;
|
|
54
61
|
if (Buffer.isBuffer(blockHashOrNumber)) {
|
|
55
62
|
block = await this._getBlockByHash(blockHashOrNumber);
|
|
56
63
|
return block ?? null;
|
|
@@ -63,7 +70,11 @@ export class ForkBlockchain implements HardhatBlockchainInterface {
|
|
|
63
70
|
public async addBlock(block: Block): Promise<Block> {
|
|
64
71
|
const blockNumber = new BN(block.header.number);
|
|
65
72
|
if (!blockNumber.eq(this._latestBlockNumber.addn(1))) {
|
|
66
|
-
throw new Error(
|
|
73
|
+
throw new Error(
|
|
74
|
+
`Invalid block number ${blockNumber.toNumber()}. Expected ${this._latestBlockNumber
|
|
75
|
+
.addn(1)
|
|
76
|
+
.toNumber()}`
|
|
77
|
+
);
|
|
67
78
|
}
|
|
68
79
|
|
|
69
80
|
// When forking a network whose consensus is not the classic PoW,
|
|
@@ -82,20 +93,19 @@ export class ForkBlockchain implements HardhatBlockchainInterface {
|
|
|
82
93
|
return block;
|
|
83
94
|
}
|
|
84
95
|
|
|
85
|
-
public
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
this.deleteBlock(blockHash);
|
|
96
|
+
public reserveBlocks(
|
|
97
|
+
count: BN,
|
|
98
|
+
interval: BN,
|
|
99
|
+
previousBlockStateRoot: Buffer,
|
|
100
|
+
previousBlockTotalDifficulty: BN
|
|
101
|
+
) {
|
|
102
|
+
super.reserveBlocks(
|
|
103
|
+
count,
|
|
104
|
+
interval,
|
|
105
|
+
previousBlockStateRoot,
|
|
106
|
+
previousBlockTotalDifficulty
|
|
107
|
+
);
|
|
108
|
+
this._latestBlockNumber = this._latestBlockNumber.add(count);
|
|
99
109
|
}
|
|
100
110
|
|
|
101
111
|
public deleteLaterBlocks(block: Block): void {
|
|
@@ -109,10 +119,8 @@ export class ForkBlockchain implements HardhatBlockchainInterface {
|
|
|
109
119
|
if (this._forkBlockNumber.gte(nextBlockNumber)) {
|
|
110
120
|
throw new Error("Cannot delete remote block");
|
|
111
121
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
return this._delBlock(nextBlock);
|
|
115
|
-
}
|
|
122
|
+
|
|
123
|
+
this._delBlock(nextBlockNumber);
|
|
116
124
|
}
|
|
117
125
|
|
|
118
126
|
public async getTotalDifficulty(blockHash: Buffer): Promise<BN> {
|
|
@@ -144,12 +152,6 @@ export class ForkBlockchain implements HardhatBlockchainInterface {
|
|
|
144
152
|
return tx;
|
|
145
153
|
}
|
|
146
154
|
|
|
147
|
-
public getLocalTransaction(
|
|
148
|
-
transactionHash: Buffer
|
|
149
|
-
): TypedTransaction | undefined {
|
|
150
|
-
return this._data.getTransaction(transactionHash);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
155
|
public async getBlockByTransactionHash(
|
|
154
156
|
transactionHash: Buffer
|
|
155
157
|
): Promise<Block | null> {
|
|
@@ -185,12 +187,6 @@ export class ForkBlockchain implements HardhatBlockchainInterface {
|
|
|
185
187
|
return null;
|
|
186
188
|
}
|
|
187
189
|
|
|
188
|
-
public addTransactionReceipts(receipts: RpcReceiptOutput[]) {
|
|
189
|
-
for (const receipt of receipts) {
|
|
190
|
-
this._data.addTransactionReceipt(receipt);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
190
|
public getForkBlockNumber() {
|
|
195
191
|
return this._forkBlockNumber;
|
|
196
192
|
}
|
|
@@ -220,18 +216,6 @@ export class ForkBlockchain implements HardhatBlockchainInterface {
|
|
|
220
216
|
return this._data.getLogs(filterParams);
|
|
221
217
|
}
|
|
222
218
|
|
|
223
|
-
public iterator(
|
|
224
|
-
_name: string,
|
|
225
|
-
_onBlock: (block: Block, reorg: boolean) => void | Promise<void>
|
|
226
|
-
): Promise<number | void> {
|
|
227
|
-
throw new Error("Method not implemented.");
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
public async getBaseFee(): Promise<BN> {
|
|
231
|
-
const latestBlock = await this.getLatestBlock();
|
|
232
|
-
return latestBlock.header.calcNextBaseFee();
|
|
233
|
-
}
|
|
234
|
-
|
|
235
219
|
private async _getBlockByHash(blockHash: Buffer) {
|
|
236
220
|
const block = this._data.getBlockByHash(blockHash);
|
|
237
221
|
if (block !== undefined) {
|
|
@@ -245,8 +229,8 @@ export class ForkBlockchain implements HardhatBlockchainInterface {
|
|
|
245
229
|
if (blockNumber.gt(this._latestBlockNumber)) {
|
|
246
230
|
return undefined;
|
|
247
231
|
}
|
|
248
|
-
const block =
|
|
249
|
-
if (block !==
|
|
232
|
+
const block = await super.getBlock(blockNumber);
|
|
233
|
+
if (block !== null) {
|
|
250
234
|
return block;
|
|
251
235
|
}
|
|
252
236
|
const rpcBlock = await this._jsonRpcClient.getBlockByNumber(
|
|
@@ -319,41 +303,12 @@ export class ForkBlockchain implements HardhatBlockchainInterface {
|
|
|
319
303
|
return block;
|
|
320
304
|
}
|
|
321
305
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
const blockNumber = new BN(block.header.number);
|
|
325
|
-
if (blockNumber.eqn(0)) {
|
|
326
|
-
return difficulty;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
const parentBlock =
|
|
330
|
-
this._data.getBlockByNumber(blockNumber.subn(1)) ??
|
|
331
|
-
(await this.getBlock(blockNumber.subn(1)));
|
|
332
|
-
if (parentBlock === null) {
|
|
333
|
-
throw new Error("Block not found");
|
|
334
|
-
}
|
|
335
|
-
const parentHash = parentBlock.hash();
|
|
336
|
-
const parentTD = this._data.getTotalDifficulty(parentHash);
|
|
337
|
-
if (parentTD === undefined) {
|
|
338
|
-
throw new Error("This should never happen");
|
|
339
|
-
}
|
|
340
|
-
return parentTD.add(difficulty);
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
private _delBlock(block: Block): void {
|
|
344
|
-
if (new BN(block.header.number).lte(this._forkBlockNumber)) {
|
|
306
|
+
protected _delBlock(blockNumber: BN): void {
|
|
307
|
+
if (blockNumber.lte(this._forkBlockNumber)) {
|
|
345
308
|
throw new Error("Cannot delete remote block");
|
|
346
309
|
}
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
for (let i = blockNumber; this._latestBlockNumber.gten(i); i++) {
|
|
350
|
-
const current = this._data.getBlockByNumber(new BN(i));
|
|
351
|
-
if (current !== undefined) {
|
|
352
|
-
this._data.removeBlock(current);
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
this._latestBlockNumber = new BN(blockNumber).subn(1);
|
|
310
|
+
super._delBlock(blockNumber);
|
|
311
|
+
this._latestBlockNumber = blockNumber.subn(1);
|
|
357
312
|
}
|
|
358
313
|
|
|
359
314
|
private _processRemoteTransaction(rpcTransaction: RpcTransaction | null) {
|
|
@@ -325,7 +325,7 @@ export class EthModule {
|
|
|
325
325
|
}
|
|
326
326
|
|
|
327
327
|
private async _blockNumberAction(): Promise<string> {
|
|
328
|
-
const blockNumber =
|
|
328
|
+
const blockNumber = this._node.getLatestBlockNumber();
|
|
329
329
|
return numberToRpcQuantity(blockNumber);
|
|
330
330
|
}
|
|
331
331
|
|
|
@@ -1405,7 +1405,7 @@ export class EthModule {
|
|
|
1405
1405
|
}
|
|
1406
1406
|
|
|
1407
1407
|
if (block === undefined) {
|
|
1408
|
-
const latestBlock =
|
|
1408
|
+
const latestBlock = this._node.getLatestBlockNumber();
|
|
1409
1409
|
|
|
1410
1410
|
throw new InvalidInputError(
|
|
1411
1411
|
`Received invalid block tag ${this._newBlockTagToString(
|
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
InvalidInputError,
|
|
27
27
|
MethodNotFoundError,
|
|
28
28
|
} from "../../../core/providers/errors";
|
|
29
|
+
import { optional } from "../../../util/io-ts";
|
|
29
30
|
import { MessageTrace } from "../../stack-traces/message-trace";
|
|
30
31
|
import { HardhatNode } from "../node";
|
|
31
32
|
import { ForkConfig, MineBlockResult } from "../node-types";
|
|
@@ -111,6 +112,9 @@ export class HardhatModule {
|
|
|
111
112
|
|
|
112
113
|
case "hardhat_setCoinbase":
|
|
113
114
|
return this._setCoinbaseAction(...this._setCoinbaseParams(params));
|
|
115
|
+
|
|
116
|
+
case "hardhat_mine":
|
|
117
|
+
return this._hardhatMineAction(...this._hardhatMineParams(params));
|
|
114
118
|
}
|
|
115
119
|
|
|
116
120
|
throw new MethodNotFoundError(`Method ${method} not found`);
|
|
@@ -173,14 +177,14 @@ export class HardhatModule {
|
|
|
173
177
|
|
|
174
178
|
const isEmpty = result.block.transactions.length === 0;
|
|
175
179
|
if (isEmpty) {
|
|
176
|
-
this._logger.
|
|
180
|
+
this._logger.printIntervalMinedBlockNumber(
|
|
177
181
|
blockNumber,
|
|
178
182
|
isEmpty,
|
|
179
183
|
result.block.header.baseFeePerGas
|
|
180
184
|
);
|
|
181
185
|
} else {
|
|
182
|
-
await this._logBlock(result);
|
|
183
|
-
this._logger.
|
|
186
|
+
await this._logBlock(result, { isIntervalMined: true });
|
|
187
|
+
this._logger.printIntervalMinedBlockNumber(blockNumber, isEmpty);
|
|
184
188
|
const printedSomething = this._logger.printLogs();
|
|
185
189
|
if (printedSomething) {
|
|
186
190
|
this._logger.printEmptyLine();
|
|
@@ -360,7 +364,31 @@ export class HardhatModule {
|
|
|
360
364
|
return true;
|
|
361
365
|
}
|
|
362
366
|
|
|
363
|
-
|
|
367
|
+
// hardhat_mine
|
|
368
|
+
private async _hardhatMineAction(blockCount?: BN, interval?: BN) {
|
|
369
|
+
const mineBlockResults = await this._node.mineBlocks(blockCount, interval);
|
|
370
|
+
|
|
371
|
+
for (const [i, result] of mineBlockResults.entries()) {
|
|
372
|
+
await this._logHardhatMinedBlock(result);
|
|
373
|
+
|
|
374
|
+
// print an empty line after logging blocks with txs,
|
|
375
|
+
// unless it's the last logged block
|
|
376
|
+
const isEmpty = result.block.transactions.length === 0;
|
|
377
|
+
if (!isEmpty && i + 1 < mineBlockResults.length) {
|
|
378
|
+
this._logger.logEmptyLine();
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
return true;
|
|
383
|
+
}
|
|
384
|
+
private _hardhatMineParams(params: any[]): [BN | undefined, BN | undefined] {
|
|
385
|
+
return validateParams(params, optional(rpcQuantity), optional(rpcQuantity));
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
private async _logBlock(
|
|
389
|
+
result: MineBlockResult,
|
|
390
|
+
{ isIntervalMined }: { isIntervalMined: boolean }
|
|
391
|
+
) {
|
|
364
392
|
const { block, traces } = result;
|
|
365
393
|
|
|
366
394
|
const codes: Buffer[] = [];
|
|
@@ -373,7 +401,11 @@ export class HardhatModule {
|
|
|
373
401
|
codes.push(code);
|
|
374
402
|
}
|
|
375
403
|
|
|
376
|
-
|
|
404
|
+
if (isIntervalMined) {
|
|
405
|
+
this._logger.logIntervalMinedBlock(result, codes);
|
|
406
|
+
} else {
|
|
407
|
+
this._logger.logMinedBlock(result, codes);
|
|
408
|
+
}
|
|
377
409
|
|
|
378
410
|
for (const txTrace of traces) {
|
|
379
411
|
await this._runHardhatNetworkMessageTraceHooks(txTrace.trace, false);
|
|
@@ -392,4 +424,18 @@ export class HardhatModule {
|
|
|
392
424
|
await hook(trace, isCall);
|
|
393
425
|
}
|
|
394
426
|
}
|
|
427
|
+
|
|
428
|
+
private async _logHardhatMinedBlock(result: MineBlockResult) {
|
|
429
|
+
const isEmpty = result.block.transactions.length === 0;
|
|
430
|
+
const blockNumber = result.block.header.number.toNumber();
|
|
431
|
+
|
|
432
|
+
if (isEmpty) {
|
|
433
|
+
this._logger.logEmptyHardhatMinedBlock(
|
|
434
|
+
blockNumber,
|
|
435
|
+
result.block.header.baseFeePerGas
|
|
436
|
+
);
|
|
437
|
+
} else {
|
|
438
|
+
await this._logBlock(result, { isIntervalMined: false });
|
|
439
|
+
}
|
|
440
|
+
}
|
|
395
441
|
}
|
|
@@ -27,7 +27,8 @@ interface PrintOptions {
|
|
|
27
27
|
color?: Chalk;
|
|
28
28
|
replaceLastLine?: boolean;
|
|
29
29
|
collapsePrintedMethod?: boolean;
|
|
30
|
-
|
|
30
|
+
collapseIntervalMinedBlock?: boolean;
|
|
31
|
+
collapseHardhatMinedBlock?: boolean;
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
function printLine(line: string) {
|
|
@@ -61,7 +62,8 @@ export class ModulesLogger {
|
|
|
61
62
|
private _logs: Array<string | [string, string]> = [];
|
|
62
63
|
private _titleLength = 0;
|
|
63
64
|
private _currentIndent = 0;
|
|
64
|
-
private
|
|
65
|
+
private _emptyIntervalMinedBlocksRangeStart: number | undefined = undefined;
|
|
66
|
+
private _emptyHardhatMinedBlocksRangeStart: number | undefined = undefined;
|
|
65
67
|
private _methodBeingCollapsed?: string;
|
|
66
68
|
private _methodCollapsedCount: number = 0;
|
|
67
69
|
|
|
@@ -395,18 +397,18 @@ export class ModulesLogger {
|
|
|
395
397
|
return true;
|
|
396
398
|
}
|
|
397
399
|
|
|
398
|
-
public
|
|
400
|
+
public printIntervalMinedBlockNumber(
|
|
399
401
|
blockNumber: number,
|
|
400
402
|
isEmpty: boolean,
|
|
401
403
|
baseFeePerGas?: BN
|
|
402
404
|
) {
|
|
403
|
-
if (this.
|
|
405
|
+
if (this._emptyIntervalMinedBlocksRangeStart !== undefined) {
|
|
404
406
|
this._print(
|
|
405
|
-
`Mined empty block range #${this.
|
|
406
|
-
{
|
|
407
|
+
`Mined empty block range #${this._emptyIntervalMinedBlocksRangeStart} to #${blockNumber}`,
|
|
408
|
+
{ collapseIntervalMinedBlock: true, replaceLastLine: true }
|
|
407
409
|
);
|
|
408
410
|
} else {
|
|
409
|
-
this.
|
|
411
|
+
this._emptyIntervalMinedBlocksRangeStart = blockNumber;
|
|
410
412
|
|
|
411
413
|
if (isEmpty) {
|
|
412
414
|
this._print(
|
|
@@ -414,7 +416,7 @@ export class ModulesLogger {
|
|
|
414
416
|
baseFeePerGas !== undefined ? ` with base fee ${baseFeePerGas}` : ""
|
|
415
417
|
}`,
|
|
416
418
|
{
|
|
417
|
-
|
|
419
|
+
collapseIntervalMinedBlock: true,
|
|
418
420
|
}
|
|
419
421
|
);
|
|
420
422
|
|
|
@@ -422,11 +424,35 @@ export class ModulesLogger {
|
|
|
422
424
|
}
|
|
423
425
|
|
|
424
426
|
this._print(`Mined block #${blockNumber}`, {
|
|
425
|
-
|
|
427
|
+
collapseIntervalMinedBlock: true,
|
|
426
428
|
});
|
|
427
429
|
}
|
|
428
430
|
}
|
|
429
431
|
|
|
432
|
+
public logEmptyHardhatMinedBlock(blockNumber: number, baseFeePerGas?: BN) {
|
|
433
|
+
this._indent(() => {
|
|
434
|
+
if (this._emptyHardhatMinedBlocksRangeStart !== undefined) {
|
|
435
|
+
this._log(
|
|
436
|
+
`Mined empty block range #${this._emptyHardhatMinedBlocksRangeStart} to #${blockNumber}`,
|
|
437
|
+
{ collapseHardhatMinedBlock: true, replaceLastLine: true }
|
|
438
|
+
);
|
|
439
|
+
} else {
|
|
440
|
+
this._emptyHardhatMinedBlocksRangeStart = blockNumber;
|
|
441
|
+
|
|
442
|
+
this._log(
|
|
443
|
+
`Mined empty block #${blockNumber}${
|
|
444
|
+
baseFeePerGas !== undefined ? ` with base fee ${baseFeePerGas}` : ""
|
|
445
|
+
}`,
|
|
446
|
+
{
|
|
447
|
+
collapseHardhatMinedBlock: true,
|
|
448
|
+
}
|
|
449
|
+
);
|
|
450
|
+
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
|
|
430
456
|
public printMetaMaskWarning() {
|
|
431
457
|
const message =
|
|
432
458
|
"If you are using MetaMask, you can learn how to fix this error here: https://hardhat.org/metamask-issue";
|
|
@@ -510,12 +536,19 @@ export class ModulesLogger {
|
|
|
510
536
|
if (printOptions.collapsePrintedMethod !== true) {
|
|
511
537
|
this._stopCollapsingMethod();
|
|
512
538
|
}
|
|
513
|
-
if (printOptions.
|
|
514
|
-
this.
|
|
539
|
+
if (printOptions.collapseIntervalMinedBlock !== true) {
|
|
540
|
+
this._emptyIntervalMinedBlocksRangeStart = undefined;
|
|
541
|
+
}
|
|
542
|
+
if (printOptions.collapseHardhatMinedBlock !== true) {
|
|
543
|
+
this._emptyHardhatMinedBlocksRangeStart = undefined;
|
|
515
544
|
}
|
|
516
545
|
const formattedMessage = this._format(msg, printOptions);
|
|
517
546
|
|
|
518
|
-
|
|
547
|
+
if (printOptions.replaceLastLine === true) {
|
|
548
|
+
this._logs[this._logs.length - 1] = formattedMessage;
|
|
549
|
+
} else {
|
|
550
|
+
this._logs.push(formattedMessage);
|
|
551
|
+
}
|
|
519
552
|
}
|
|
520
553
|
|
|
521
554
|
private _logError(err: Error) {
|
|
@@ -579,8 +612,11 @@ export class ModulesLogger {
|
|
|
579
612
|
if (printOptions.collapsePrintedMethod !== true) {
|
|
580
613
|
this._stopCollapsingMethod();
|
|
581
614
|
}
|
|
582
|
-
if (printOptions.
|
|
583
|
-
this.
|
|
615
|
+
if (printOptions.collapseIntervalMinedBlock !== true) {
|
|
616
|
+
this._emptyIntervalMinedBlocksRangeStart = undefined;
|
|
617
|
+
}
|
|
618
|
+
if (printOptions.collapseHardhatMinedBlock !== true) {
|
|
619
|
+
this._emptyHardhatMinedBlocksRangeStart = undefined;
|
|
584
620
|
}
|
|
585
621
|
const formattedMessage = this._format(msg, printOptions);
|
|
586
622
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { ReturnData } from "./return-data";
|
|
2
|
+
|
|
1
3
|
import { Block } from "@ethereumjs/block";
|
|
2
4
|
import { RunBlockResult } from "@ethereumjs/vm/dist/runBlock";
|
|
3
5
|
import { BN } from "ethereumjs-util";
|
|
@@ -6,8 +8,6 @@ import { HARDHAT_MEMPOOL_SUPPORTED_ORDERS } from "../../constants";
|
|
|
6
8
|
import { BuildInfo, HardhatNetworkChainsConfig } from "../../../types";
|
|
7
9
|
import { MessageTrace } from "../stack-traces/message-trace";
|
|
8
10
|
|
|
9
|
-
import type { ReturnData } from "./return-data";
|
|
10
|
-
|
|
11
11
|
export type NodeConfig = LocalNodeConfig | ForkedNodeConfig;
|
|
12
12
|
|
|
13
13
|
export function isForkedNodeConfig(
|