hardhat 2.22.4 → 2.22.6
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/cli/bootstrap.js +2 -3
- package/internal/cli/bootstrap.js.map +1 -1
- package/internal/cli/constants.d.ts.map +1 -1
- package/internal/cli/constants.js +1 -1
- package/internal/cli/constants.js.map +1 -1
- package/internal/cli/is-node-version-to-warn-on.d.ts +13 -0
- package/internal/cli/is-node-version-to-warn-on.d.ts.map +1 -0
- package/internal/cli/is-node-version-to-warn-on.js +46 -0
- package/internal/cli/is-node-version-to-warn-on.js.map +1 -0
- package/internal/core/config/default-config.d.ts.map +1 -1
- package/internal/core/config/default-config.js +26 -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 +9 -0
- package/internal/core/errors-list.js.map +1 -1
- package/internal/core/providers/http.d.ts.map +1 -1
- package/internal/core/providers/http.js +5 -0
- package/internal/core/providers/http.js.map +1 -1
- package/internal/hardhat-network/provider/provider.d.ts +12 -8
- package/internal/hardhat-network/provider/provider.d.ts.map +1 -1
- package/internal/hardhat-network/provider/provider.js +35 -21
- package/internal/hardhat-network/provider/provider.js.map +1 -1
- package/internal/hardhat-network/provider/utils/convertToEdr.d.ts.map +1 -1
- package/internal/hardhat-network/provider/utils/convertToEdr.js +30 -4
- package/internal/hardhat-network/provider/utils/convertToEdr.js.map +1 -1
- package/internal/hardhat-network/provider/vm/exit.d.ts +0 -1
- package/internal/hardhat-network/provider/vm/exit.d.ts.map +1 -1
- package/internal/hardhat-network/provider/vm/exit.js +0 -16
- package/internal/hardhat-network/provider/vm/exit.js.map +1 -1
- package/internal/hardhat-network/provider/vm/minimal-vm.d.ts +8 -1
- package/internal/hardhat-network/provider/vm/minimal-vm.d.ts.map +1 -1
- package/internal/hardhat-network/provider/vm/minimal-vm.js +6 -2
- package/internal/hardhat-network/provider/vm/minimal-vm.js.map +1 -1
- package/internal/hardhat-network/provider/vm/types.d.ts +8 -0
- package/internal/hardhat-network/provider/vm/types.d.ts.map +1 -1
- package/internal/hardhat-network/stack-traces/message-trace.d.ts +0 -2
- package/internal/hardhat-network/stack-traces/message-trace.d.ts.map +1 -1
- package/internal/hardhat-network/stack-traces/message-trace.js.map +1 -1
- package/internal/hardhat-network/stack-traces/vm-tracer.d.ts +8 -7
- package/internal/hardhat-network/stack-traces/vm-tracer.d.ts.map +1 -1
- package/internal/hardhat-network/stack-traces/vm-tracer.js +13 -29
- package/internal/hardhat-network/stack-traces/vm-tracer.js.map +1 -1
- package/package.json +3 -9
- package/src/internal/cli/bootstrap.ts +3 -3
- package/src/internal/cli/constants.ts +1 -1
- package/src/internal/cli/is-node-version-to-warn-on.ts +54 -0
- package/src/internal/core/config/default-config.ts +26 -0
- package/src/internal/core/errors-list.ts +11 -0
- package/src/internal/core/providers/http.ts +6 -0
- package/src/internal/hardhat-network/provider/provider.ts +46 -33
- package/src/internal/hardhat-network/provider/utils/convertToEdr.ts +36 -4
- package/src/internal/hardhat-network/provider/vm/exit.ts +0 -21
- package/src/internal/hardhat-network/provider/vm/minimal-vm.ts +14 -3
- package/src/internal/hardhat-network/provider/vm/types.ts +7 -0
- package/src/internal/hardhat-network/stack-traces/message-trace.ts +0 -2
- package/src/internal/hardhat-network/stack-traces/vm-tracer.ts +13 -26
- package/internal/hardhat-network/provider/MiningTimer.d.ts +0 -28
- package/internal/hardhat-network/provider/MiningTimer.d.ts.map +0 -1
- package/internal/hardhat-network/provider/MiningTimer.js +0 -96
- package/internal/hardhat-network/provider/MiningTimer.js.map +0 -1
- package/src/internal/hardhat-network/provider/MiningTimer.ts +0 -118
|
@@ -141,6 +141,32 @@ export const defaultHardhatNetworkParams: Omit<
|
|
|
141
141
|
]),
|
|
142
142
|
},
|
|
143
143
|
],
|
|
144
|
+
// TODO: the rest of this config is a temporary workaround,
|
|
145
|
+
// see https://github.com/NomicFoundation/edr/issues/522
|
|
146
|
+
[
|
|
147
|
+
10, // optimism mainnet
|
|
148
|
+
{
|
|
149
|
+
hardforkHistory: new Map([[HardforkName.SHANGHAI, 0]]),
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
[
|
|
153
|
+
11155420, // optimism sepolia
|
|
154
|
+
{
|
|
155
|
+
hardforkHistory: new Map([[HardforkName.SHANGHAI, 0]]),
|
|
156
|
+
},
|
|
157
|
+
],
|
|
158
|
+
[
|
|
159
|
+
42161, // arbitrum one
|
|
160
|
+
{
|
|
161
|
+
hardforkHistory: new Map([[HardforkName.SHANGHAI, 0]]),
|
|
162
|
+
},
|
|
163
|
+
],
|
|
164
|
+
[
|
|
165
|
+
421614, // arbitrum sepolia
|
|
166
|
+
{
|
|
167
|
+
hardforkHistory: new Map([[HardforkName.SHANGHAI, 0]]),
|
|
168
|
+
},
|
|
169
|
+
],
|
|
144
170
|
]),
|
|
145
171
|
};
|
|
146
172
|
|
|
@@ -475,6 +475,17 @@ Please double check your transactions' parameters.`,
|
|
|
475
475
|
Please check that you are sending an \`address\` parameter.`,
|
|
476
476
|
shouldBeReported: false,
|
|
477
477
|
},
|
|
478
|
+
EMPTY_URL: {
|
|
479
|
+
number: 117,
|
|
480
|
+
message:
|
|
481
|
+
"Empty string `%value%` for network or forking URL - Expected a non-empty string.",
|
|
482
|
+
title:
|
|
483
|
+
"Empty string `%value%` for network or forking URL - Expected a non-empty string.",
|
|
484
|
+
description: `You are trying to connect to a network with an empty network or forking URL.
|
|
485
|
+
|
|
486
|
+
Please check that you are sending a non-empty string for network or forking \`URL\` parameter.`,
|
|
487
|
+
shouldBeReported: false,
|
|
488
|
+
},
|
|
478
489
|
},
|
|
479
490
|
TASK_DEFINITIONS: {
|
|
480
491
|
PARAM_AFTER_VARIADIC: {
|
|
@@ -51,6 +51,12 @@ export class HttpProvider extends EventEmitter implements EIP1193Provider {
|
|
|
51
51
|
|
|
52
52
|
const { Pool, ProxyAgent } = require("undici") as typeof Undici;
|
|
53
53
|
|
|
54
|
+
if (this._url.trim().length === 0) {
|
|
55
|
+
throw new HardhatError(ERRORS.NETWORK.EMPTY_URL, {
|
|
56
|
+
value: this._url,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
54
60
|
const url = new URL(this._url);
|
|
55
61
|
this._path = url.pathname;
|
|
56
62
|
this._authHeader =
|
|
@@ -12,12 +12,9 @@ import type {
|
|
|
12
12
|
import type {
|
|
13
13
|
EdrContext,
|
|
14
14
|
Provider as EdrProviderT,
|
|
15
|
-
ExecutionResult,
|
|
16
15
|
RawTrace,
|
|
17
16
|
Response,
|
|
18
17
|
SubscriptionEvent,
|
|
19
|
-
TracingMessage,
|
|
20
|
-
TracingStep,
|
|
21
18
|
} from "@nomicfoundation/edr";
|
|
22
19
|
import { Common } from "@nomicfoundation/ethereumjs-common";
|
|
23
20
|
import chalk from "chalk";
|
|
@@ -152,12 +149,6 @@ export function getNodeConfig(
|
|
|
152
149
|
};
|
|
153
150
|
}
|
|
154
151
|
|
|
155
|
-
export interface RawTraceCallbacks {
|
|
156
|
-
onStep?: (messageTrace: TracingStep) => Promise<void>;
|
|
157
|
-
onBeforeMessage?: (messageTrace: TracingMessage) => Promise<void>;
|
|
158
|
-
onAfterMessage?: (messageTrace: ExecutionResult) => Promise<void>;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
152
|
class EdrProviderEventAdapter extends EventEmitter {}
|
|
162
153
|
|
|
163
154
|
type CallOverrideCallback = (
|
|
@@ -176,6 +167,9 @@ export class EdrProviderWrapper
|
|
|
176
167
|
// temporarily added to make smock work with HH+EDR
|
|
177
168
|
private _callOverrideCallback?: CallOverrideCallback;
|
|
178
169
|
|
|
170
|
+
/** Used for internal stack trace tests. */
|
|
171
|
+
private _vmTracer?: VMTracer;
|
|
172
|
+
|
|
179
173
|
private constructor(
|
|
180
174
|
private readonly _provider: EdrProviderT,
|
|
181
175
|
// we add this for backwards-compatibility with plugins like solidity-coverage
|
|
@@ -184,7 +178,6 @@ export class EdrProviderWrapper
|
|
|
184
178
|
},
|
|
185
179
|
private readonly _eventAdapter: EdrProviderEventAdapter,
|
|
186
180
|
private readonly _vmTraceDecoder: VmTraceDecoder,
|
|
187
|
-
private readonly _rawTraceCallbacks: RawTraceCallbacks,
|
|
188
181
|
// The common configuration for EthereumJS VM is not used by EDR, but tests expect it as part of the provider.
|
|
189
182
|
private readonly _common: Common,
|
|
190
183
|
tracingConfig?: TracingConfig
|
|
@@ -199,7 +192,6 @@ export class EdrProviderWrapper
|
|
|
199
192
|
public static async create(
|
|
200
193
|
config: HardhatNetworkProviderConfig,
|
|
201
194
|
loggerConfig: LoggerConfig,
|
|
202
|
-
rawTraceCallbacks: RawTraceCallbacks,
|
|
203
195
|
tracingConfig?: TracingConfig
|
|
204
196
|
): Promise<EdrProviderWrapper> {
|
|
205
197
|
const { Provider } = requireNapiRsModule(
|
|
@@ -325,7 +317,6 @@ export class EdrProviderWrapper
|
|
|
325
317
|
minimalEthereumJsNode,
|
|
326
318
|
eventAdapter,
|
|
327
319
|
vmTraceDecoder,
|
|
328
|
-
rawTraceCallbacks,
|
|
329
320
|
common,
|
|
330
321
|
tracingConfig
|
|
331
322
|
);
|
|
@@ -370,15 +361,21 @@ export class EdrProviderWrapper
|
|
|
370
361
|
|
|
371
362
|
const needsTraces =
|
|
372
363
|
this._node._vm.evm.events.eventNames().length > 0 ||
|
|
373
|
-
this.
|
|
374
|
-
this.
|
|
375
|
-
this._rawTraceCallbacks.onBeforeMessage !== undefined;
|
|
364
|
+
this._node._vm.events.eventNames().length > 0 ||
|
|
365
|
+
this._vmTracer !== undefined;
|
|
376
366
|
|
|
377
367
|
if (needsTraces) {
|
|
378
368
|
const rawTraces = responseObject.traces;
|
|
379
369
|
for (const rawTrace of rawTraces) {
|
|
380
370
|
const trace = rawTrace.trace();
|
|
371
|
+
|
|
372
|
+
// beforeTx event
|
|
373
|
+
if (this._node._vm.events.listenerCount("beforeTx") > 0) {
|
|
374
|
+
this._node._vm.events.emit("beforeTx");
|
|
375
|
+
}
|
|
376
|
+
|
|
381
377
|
for (const traceItem of trace) {
|
|
378
|
+
// step event
|
|
382
379
|
if ("pc" in traceItem) {
|
|
383
380
|
if (this._node._vm.evm.events.listenerCount("step") > 0) {
|
|
384
381
|
this._node._vm.evm.events.emit(
|
|
@@ -386,33 +383,37 @@ export class EdrProviderWrapper
|
|
|
386
383
|
edrTracingStepToMinimalInterpreterStep(traceItem)
|
|
387
384
|
);
|
|
388
385
|
}
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
386
|
+
|
|
387
|
+
this._vmTracer?.addStep(traceItem);
|
|
388
|
+
}
|
|
389
|
+
// afterMessage event
|
|
390
|
+
else if ("executionResult" in traceItem) {
|
|
393
391
|
if (this._node._vm.evm.events.listenerCount("afterMessage") > 0) {
|
|
394
392
|
this._node._vm.evm.events.emit(
|
|
395
393
|
"afterMessage",
|
|
396
394
|
edrTracingMessageResultToMinimalEVMResult(traceItem)
|
|
397
395
|
);
|
|
398
396
|
}
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
} else {
|
|
397
|
+
|
|
398
|
+
this._vmTracer?.addAfterMessage(traceItem.executionResult);
|
|
399
|
+
}
|
|
400
|
+
// beforeMessage event
|
|
401
|
+
else {
|
|
405
402
|
if (this._node._vm.evm.events.listenerCount("beforeMessage") > 0) {
|
|
406
403
|
this._node._vm.evm.events.emit(
|
|
407
404
|
"beforeMessage",
|
|
408
405
|
edrTracingMessageToMinimalMessage(traceItem)
|
|
409
406
|
);
|
|
410
407
|
}
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
}
|
|
408
|
+
|
|
409
|
+
this._vmTracer?.addBeforeMessage(traceItem);
|
|
414
410
|
}
|
|
415
411
|
}
|
|
412
|
+
|
|
413
|
+
// afterTx event
|
|
414
|
+
if (this._node._vm.events.listenerCount("afterTx") > 0) {
|
|
415
|
+
this._node._vm.events.emit("afterTx");
|
|
416
|
+
}
|
|
416
417
|
}
|
|
417
418
|
}
|
|
418
419
|
|
|
@@ -467,6 +468,15 @@ export class EdrProviderWrapper
|
|
|
467
468
|
}
|
|
468
469
|
}
|
|
469
470
|
|
|
471
|
+
/**
|
|
472
|
+
* Sets a `VMTracer` that observes EVM throughout requests.
|
|
473
|
+
*
|
|
474
|
+
* Used for internal stack traces integration tests.
|
|
475
|
+
*/
|
|
476
|
+
public setVmTracer(vmTracer?: VMTracer) {
|
|
477
|
+
this._vmTracer = vmTracer;
|
|
478
|
+
}
|
|
479
|
+
|
|
470
480
|
// temporarily added to make smock work with HH+EDR
|
|
471
481
|
private _setCallOverrideCallback(callback: CallOverrideCallback) {
|
|
472
482
|
this._callOverrideCallback = callback;
|
|
@@ -478,6 +488,10 @@ export class EdrProviderWrapper
|
|
|
478
488
|
);
|
|
479
489
|
}
|
|
480
490
|
|
|
491
|
+
private _setVerboseTracing(enabled: boolean) {
|
|
492
|
+
this._provider.setVerboseTracing(enabled);
|
|
493
|
+
}
|
|
494
|
+
|
|
481
495
|
private _ethEventListener(event: SubscriptionEvent) {
|
|
482
496
|
const subscription = `0x${event.filterId.toString(16)}`;
|
|
483
497
|
const results = Array.isArray(event.result) ? event.result : [event.result];
|
|
@@ -562,16 +576,16 @@ export class EdrProviderWrapper
|
|
|
562
576
|
private async _rawTraceToSolidityStackTrace(
|
|
563
577
|
rawTrace: RawTrace
|
|
564
578
|
): Promise<SolidityStackTrace | undefined> {
|
|
565
|
-
const vmTracer = new VMTracer(
|
|
579
|
+
const vmTracer = new VMTracer();
|
|
566
580
|
|
|
567
581
|
const trace = rawTrace.trace();
|
|
568
582
|
for (const traceItem of trace) {
|
|
569
583
|
if ("pc" in traceItem) {
|
|
570
|
-
|
|
584
|
+
vmTracer.addStep(traceItem);
|
|
571
585
|
} else if ("executionResult" in traceItem) {
|
|
572
|
-
|
|
586
|
+
vmTracer.addAfterMessage(traceItem.executionResult);
|
|
573
587
|
} else {
|
|
574
|
-
|
|
588
|
+
vmTracer.addBeforeMessage(traceItem);
|
|
575
589
|
}
|
|
576
590
|
}
|
|
577
591
|
|
|
@@ -613,7 +627,6 @@ export async function createHardhatNetworkProvider(
|
|
|
613
627
|
return EdrProviderWrapper.create(
|
|
614
628
|
hardhatNetworkProviderConfig,
|
|
615
629
|
loggerConfig,
|
|
616
|
-
{},
|
|
617
630
|
await makeTracingConfig(artifacts)
|
|
618
631
|
);
|
|
619
632
|
}
|
|
@@ -208,24 +208,55 @@ export function edrRpcDebugTraceToHardhat(
|
|
|
208
208
|
export function edrTracingStepToMinimalInterpreterStep(
|
|
209
209
|
step: TracingStep
|
|
210
210
|
): MinimalInterpreterStep {
|
|
211
|
-
|
|
211
|
+
const minimalInterpreterStep: MinimalInterpreterStep = {
|
|
212
212
|
pc: Number(step.pc),
|
|
213
213
|
depth: step.depth,
|
|
214
214
|
opcode: {
|
|
215
215
|
name: step.opcode,
|
|
216
216
|
},
|
|
217
|
-
stack: step.
|
|
217
|
+
stack: step.stack,
|
|
218
218
|
};
|
|
219
|
+
|
|
220
|
+
if (step.memory !== undefined) {
|
|
221
|
+
minimalInterpreterStep.memory = step.memory;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
return minimalInterpreterStep;
|
|
219
225
|
}
|
|
220
226
|
|
|
221
227
|
export function edrTracingMessageResultToMinimalEVMResult(
|
|
222
228
|
tracingMessageResult: TracingMessageResult
|
|
223
229
|
): MinimalEVMResult {
|
|
224
|
-
|
|
230
|
+
const { result, contractAddress } = tracingMessageResult.executionResult;
|
|
231
|
+
|
|
232
|
+
// only SuccessResult has logs
|
|
233
|
+
const success = "logs" in result;
|
|
234
|
+
|
|
235
|
+
const minimalEVMResult: MinimalEVMResult = {
|
|
225
236
|
execResult: {
|
|
226
|
-
executionGasUsed:
|
|
237
|
+
executionGasUsed: result.gasUsed,
|
|
238
|
+
success,
|
|
227
239
|
},
|
|
228
240
|
};
|
|
241
|
+
|
|
242
|
+
// only success and exceptional halt have reason
|
|
243
|
+
if ("reason" in result) {
|
|
244
|
+
minimalEVMResult.execResult.reason = result.reason;
|
|
245
|
+
}
|
|
246
|
+
if ("output" in result) {
|
|
247
|
+
const { output } = result;
|
|
248
|
+
if (Buffer.isBuffer(output)) {
|
|
249
|
+
minimalEVMResult.execResult.output = output;
|
|
250
|
+
} else {
|
|
251
|
+
minimalEVMResult.execResult.output = output.returnValue;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if (contractAddress !== undefined) {
|
|
256
|
+
minimalEVMResult.execResult.contractAddress = new Address(contractAddress);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
return minimalEVMResult;
|
|
229
260
|
}
|
|
230
261
|
|
|
231
262
|
export function edrTracingMessageToMinimalMessage(
|
|
@@ -241,5 +272,6 @@ export function edrTracingMessageToMinimalMessage(
|
|
|
241
272
|
value: message.value,
|
|
242
273
|
caller: new Address(message.caller),
|
|
243
274
|
gasLimit: message.gasLimit,
|
|
275
|
+
isStaticCall: message.isStaticCall,
|
|
244
276
|
};
|
|
245
277
|
}
|
|
@@ -91,25 +91,4 @@ export class Exit {
|
|
|
91
91
|
|
|
92
92
|
const _exhaustiveCheck: never = this.kind;
|
|
93
93
|
}
|
|
94
|
-
|
|
95
|
-
public getEdrExceptionalHalt(): ExceptionalHalt {
|
|
96
|
-
const { ExceptionalHalt } = requireNapiRsModule(
|
|
97
|
-
"@nomicfoundation/edr"
|
|
98
|
-
) as typeof import("@nomicfoundation/edr");
|
|
99
|
-
|
|
100
|
-
switch (this.kind) {
|
|
101
|
-
case ExitCode.OUT_OF_GAS:
|
|
102
|
-
return ExceptionalHalt.OutOfGas;
|
|
103
|
-
case ExitCode.INVALID_OPCODE:
|
|
104
|
-
return ExceptionalHalt.OpcodeNotFound;
|
|
105
|
-
case ExitCode.CODESIZE_EXCEEDS_MAXIMUM:
|
|
106
|
-
return ExceptionalHalt.CreateContractSizeLimit;
|
|
107
|
-
case ExitCode.CREATE_COLLISION:
|
|
108
|
-
return ExceptionalHalt.CreateCollision;
|
|
109
|
-
|
|
110
|
-
default:
|
|
111
|
-
// eslint-disable-next-line @nomicfoundation/hardhat-internal-rules/only-hardhat-error
|
|
112
|
-
throw new Error(`Unmatched exit code: ${this.kind}`);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
94
|
}
|
|
@@ -13,8 +13,9 @@ import { AsyncEventEmitter } from "@nomicfoundation/ethereumjs-util";
|
|
|
13
13
|
* interface only has the things used by those plugins.
|
|
14
14
|
*/
|
|
15
15
|
export interface MinimalEthereumJsVm {
|
|
16
|
+
events: AsyncEventEmitter<MinimalEthereumJsVmEvents>;
|
|
16
17
|
evm: {
|
|
17
|
-
events: AsyncEventEmitter<
|
|
18
|
+
events: AsyncEventEmitter<MinimalEthereumJsEvmEvents>;
|
|
18
19
|
};
|
|
19
20
|
stateManager: {
|
|
20
21
|
putContractCode: (address: Address, code: Buffer) => Promise<void>;
|
|
@@ -27,10 +28,18 @@ export interface MinimalEthereumJsVm {
|
|
|
27
28
|
};
|
|
28
29
|
}
|
|
29
30
|
|
|
30
|
-
// we need to use a type instead of an interface to satisfy the type
|
|
31
|
+
// we need to use a type instead of an interface to satisfy the type constraint
|
|
31
32
|
// of the AsyncEventEmitter type param
|
|
32
33
|
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
|
|
33
34
|
type MinimalEthereumJsVmEvents = {
|
|
35
|
+
beforeTx: () => void;
|
|
36
|
+
afterTx: () => void;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// we need to use a type instead of an interface to satisfy the type constraint
|
|
40
|
+
// of the AsyncEventEmitter type param
|
|
41
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
|
|
42
|
+
type MinimalEthereumJsEvmEvents = {
|
|
34
43
|
beforeMessage: (
|
|
35
44
|
data: MinimalMessage,
|
|
36
45
|
resolve?: (result?: any) => void
|
|
@@ -46,13 +55,15 @@ type MinimalEthereumJsVmEvents = {
|
|
|
46
55
|
};
|
|
47
56
|
|
|
48
57
|
export class MinimalEthereumJsVmEventEmitter extends AsyncEventEmitter<MinimalEthereumJsVmEvents> {}
|
|
58
|
+
export class MinimalEthereumJsEvmEventEmitter extends AsyncEventEmitter<MinimalEthereumJsEvmEvents> {}
|
|
49
59
|
|
|
50
60
|
export function getMinimalEthereumJsVm(
|
|
51
61
|
provider: EdrProviderT
|
|
52
62
|
): MinimalEthereumJsVm {
|
|
53
63
|
const minimalEthereumJsVm: MinimalEthereumJsVm = {
|
|
64
|
+
events: new MinimalEthereumJsVmEventEmitter(),
|
|
54
65
|
evm: {
|
|
55
|
-
events: new
|
|
66
|
+
events: new MinimalEthereumJsEvmEventEmitter(),
|
|
56
67
|
},
|
|
57
68
|
stateManager: {
|
|
58
69
|
putContractCode: async (address: Address, code: Buffer) => {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ExceptionalHalt, SuccessReason } from "@nomicfoundation/edr";
|
|
1
2
|
import type { Address } from "@nomicfoundation/ethereumjs-util";
|
|
2
3
|
|
|
3
4
|
/**
|
|
@@ -12,10 +13,15 @@ export interface MinimalInterpreterStep {
|
|
|
12
13
|
name: string;
|
|
13
14
|
};
|
|
14
15
|
stack: bigint[];
|
|
16
|
+
memory?: Uint8Array;
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
export interface MinimalExecResult {
|
|
20
|
+
success: boolean;
|
|
18
21
|
executionGasUsed: bigint;
|
|
22
|
+
contractAddress?: Address;
|
|
23
|
+
reason?: SuccessReason | ExceptionalHalt;
|
|
24
|
+
output?: Buffer;
|
|
19
25
|
}
|
|
20
26
|
|
|
21
27
|
export interface MinimalEVMResult {
|
|
@@ -29,4 +35,5 @@ export interface MinimalMessage {
|
|
|
29
35
|
data: Uint8Array;
|
|
30
36
|
caller: Address;
|
|
31
37
|
gasLimit: bigint;
|
|
38
|
+
isStaticCall: boolean;
|
|
32
39
|
}
|
|
@@ -34,8 +34,6 @@ export interface PrecompileMessageTrace extends BaseMessageTrace {
|
|
|
34
34
|
|
|
35
35
|
export interface BaseEvmMessageTrace extends BaseMessageTrace {
|
|
36
36
|
code: Uint8Array;
|
|
37
|
-
value: bigint;
|
|
38
|
-
returnData: Uint8Array;
|
|
39
37
|
steps: MessageTraceStep[];
|
|
40
38
|
bytecode?: Bytecode;
|
|
41
39
|
// The following is just an optimization: When processing this traces it's useful to know ahead of
|
|
@@ -26,6 +26,10 @@ import {
|
|
|
26
26
|
const DUMMY_RETURN_DATA = Buffer.from([]);
|
|
27
27
|
const DUMMY_GAS_USED = 0n;
|
|
28
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Consumes the incoming VM trace events, until an error occurs, to keep track
|
|
31
|
+
* of the last top level message trace/error.
|
|
32
|
+
*/
|
|
29
33
|
export class VMTracer {
|
|
30
34
|
public tracingSteps: TracingStep[] = [];
|
|
31
35
|
|
|
@@ -33,7 +37,7 @@ export class VMTracer {
|
|
|
33
37
|
private _lastError: Error | undefined;
|
|
34
38
|
private _maxPrecompileNumber;
|
|
35
39
|
|
|
36
|
-
constructor(
|
|
40
|
+
constructor() {
|
|
37
41
|
// TODO: temporarily hardcoded to remove the need of using ethereumjs' common and evm here
|
|
38
42
|
this._maxPrecompileNumber = 10;
|
|
39
43
|
}
|
|
@@ -46,15 +50,11 @@ export class VMTracer {
|
|
|
46
50
|
return this._lastError;
|
|
47
51
|
}
|
|
48
52
|
|
|
49
|
-
public clearLastError() {
|
|
50
|
-
this._lastError = undefined;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
53
|
private _shouldKeepTracing() {
|
|
54
|
-
return this.
|
|
54
|
+
return this._lastError === undefined;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
public
|
|
57
|
+
public addBeforeMessage(message: TracingMessage) {
|
|
58
58
|
if (!this._shouldKeepTracing()) {
|
|
59
59
|
return;
|
|
60
60
|
}
|
|
@@ -143,15 +143,11 @@ export class VMTracer {
|
|
|
143
143
|
|
|
144
144
|
this._messageTraces.push(trace);
|
|
145
145
|
} catch (error) {
|
|
146
|
-
|
|
147
|
-
throw error;
|
|
148
|
-
} else {
|
|
149
|
-
this._lastError = error as Error;
|
|
150
|
-
}
|
|
146
|
+
this._lastError = error as Error;
|
|
151
147
|
}
|
|
152
148
|
}
|
|
153
149
|
|
|
154
|
-
public
|
|
150
|
+
public addStep(step: TracingStep) {
|
|
155
151
|
if (!this._shouldKeepTracing()) {
|
|
156
152
|
return;
|
|
157
153
|
}
|
|
@@ -169,15 +165,11 @@ export class VMTracer {
|
|
|
169
165
|
|
|
170
166
|
trace.steps.push({ pc: Number(step.pc) });
|
|
171
167
|
} catch (error) {
|
|
172
|
-
|
|
173
|
-
throw error;
|
|
174
|
-
} else {
|
|
175
|
-
this._lastError = error as Error;
|
|
176
|
-
}
|
|
168
|
+
this._lastError = error as Error;
|
|
177
169
|
}
|
|
178
170
|
}
|
|
179
171
|
|
|
180
|
-
public
|
|
172
|
+
public addAfterMessage(result: ExecutionResult) {
|
|
181
173
|
if (!this._shouldKeepTracing()) {
|
|
182
174
|
return;
|
|
183
175
|
}
|
|
@@ -197,8 +189,7 @@ export class VMTracer {
|
|
|
197
189
|
).address;
|
|
198
190
|
}
|
|
199
191
|
} else if (isHaltResult(executionResult)) {
|
|
200
|
-
trace.exit =
|
|
201
|
-
haltOverride ?? Exit.fromEdrExceptionalHalt(executionResult.reason);
|
|
192
|
+
trace.exit = Exit.fromEdrExceptionalHalt(executionResult.reason);
|
|
202
193
|
|
|
203
194
|
trace.returnData = Buffer.from([]);
|
|
204
195
|
} else {
|
|
@@ -211,11 +202,7 @@ export class VMTracer {
|
|
|
211
202
|
this._messageTraces.pop();
|
|
212
203
|
}
|
|
213
204
|
} catch (error) {
|
|
214
|
-
|
|
215
|
-
throw error;
|
|
216
|
-
} else {
|
|
217
|
-
this._lastError = error as Error;
|
|
218
|
-
}
|
|
205
|
+
this._lastError = error as Error;
|
|
219
206
|
}
|
|
220
207
|
}
|
|
221
208
|
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { IntervalMiningConfig } from "./node-types";
|
|
2
|
-
/**
|
|
3
|
-
* Timer used to periodically call the given mining function.
|
|
4
|
-
*
|
|
5
|
-
* `_blockTime` can be a number or a pair of numbers (of milliseconds). If it
|
|
6
|
-
* is a number, it will call the given function repeatedly every `_blockTime`
|
|
7
|
-
* milliseconds. If it is a pair of numbers, then after each call it will
|
|
8
|
-
* randomly choose how much to wait until the next call.
|
|
9
|
-
*
|
|
10
|
-
* `_mineFunction` is the function to call. It can be async, and it is assumed
|
|
11
|
-
* that it will never throw.
|
|
12
|
-
*/
|
|
13
|
-
export declare class MiningTimer {
|
|
14
|
-
private _blockTime;
|
|
15
|
-
private readonly _mineFunction;
|
|
16
|
-
private _state;
|
|
17
|
-
private _timeout;
|
|
18
|
-
constructor(_blockTime: IntervalMiningConfig, _mineFunction: () => Promise<any>);
|
|
19
|
-
getBlockTime(): IntervalMiningConfig;
|
|
20
|
-
enabled(): boolean;
|
|
21
|
-
setBlockTime(blockTime: IntervalMiningConfig): void;
|
|
22
|
-
start(): void;
|
|
23
|
-
stop(): void;
|
|
24
|
-
private _validateBlockTime;
|
|
25
|
-
private _loop;
|
|
26
|
-
private _getNextBlockTime;
|
|
27
|
-
}
|
|
28
|
-
//# sourceMappingURL=MiningTimer.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"MiningTimer.d.ts","sourceRoot":"","sources":["../../../src/internal/hardhat-network/provider/MiningTimer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AASpD;;;;;;;;;;GAUG;AACH,qBAAa,WAAW;IAKpB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,QAAQ,CAAC,aAAa;IALhC,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,QAAQ,CAA+B;gBAGrC,UAAU,EAAE,oBAAoB,EACvB,aAAa,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC;IAK7C,YAAY,IAAI,oBAAoB;IAIpC,OAAO,IAAI,OAAO;IAIlB,YAAY,CAAC,SAAS,EAAE,oBAAoB,GAAG,IAAI;IAiBnD,KAAK,IAAI,IAAI;IAWb,IAAI,IAAI,IAAI;IAYnB,OAAO,CAAC,kBAAkB;YAaZ,KAAK;IAcnB,OAAO,CAAC,iBAAiB;CAW1B"}
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MiningTimer = void 0;
|
|
4
|
-
var MiningTimerState;
|
|
5
|
-
(function (MiningTimerState) {
|
|
6
|
-
MiningTimerState[MiningTimerState["STOP"] = 0] = "STOP";
|
|
7
|
-
MiningTimerState[MiningTimerState["RUNNING"] = 1] = "RUNNING";
|
|
8
|
-
})(MiningTimerState || (MiningTimerState = {}));
|
|
9
|
-
/* eslint-disable @nomicfoundation/hardhat-internal-rules/only-hardhat-error */
|
|
10
|
-
/**
|
|
11
|
-
* Timer used to periodically call the given mining function.
|
|
12
|
-
*
|
|
13
|
-
* `_blockTime` can be a number or a pair of numbers (of milliseconds). If it
|
|
14
|
-
* is a number, it will call the given function repeatedly every `_blockTime`
|
|
15
|
-
* milliseconds. If it is a pair of numbers, then after each call it will
|
|
16
|
-
* randomly choose how much to wait until the next call.
|
|
17
|
-
*
|
|
18
|
-
* `_mineFunction` is the function to call. It can be async, and it is assumed
|
|
19
|
-
* that it will never throw.
|
|
20
|
-
*/
|
|
21
|
-
class MiningTimer {
|
|
22
|
-
constructor(_blockTime, _mineFunction) {
|
|
23
|
-
this._blockTime = _blockTime;
|
|
24
|
-
this._mineFunction = _mineFunction;
|
|
25
|
-
this._state = MiningTimerState.STOP;
|
|
26
|
-
this._timeout = null;
|
|
27
|
-
this._validateBlockTime(_blockTime);
|
|
28
|
-
}
|
|
29
|
-
getBlockTime() {
|
|
30
|
-
return this._blockTime;
|
|
31
|
-
}
|
|
32
|
-
enabled() {
|
|
33
|
-
return this._blockTime !== 0;
|
|
34
|
-
}
|
|
35
|
-
setBlockTime(blockTime) {
|
|
36
|
-
this._validateBlockTime(blockTime);
|
|
37
|
-
if (blockTime === 0) {
|
|
38
|
-
this.stop();
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
this._blockTime = blockTime;
|
|
42
|
-
if (this._state === MiningTimerState.RUNNING) {
|
|
43
|
-
this.stop();
|
|
44
|
-
}
|
|
45
|
-
this.start();
|
|
46
|
-
}
|
|
47
|
-
start() {
|
|
48
|
-
if (this._state === MiningTimerState.RUNNING || !this.enabled()) {
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
const blockTime = this._getNextBlockTime();
|
|
52
|
-
this._state = MiningTimerState.RUNNING;
|
|
53
|
-
this._timeout = setTimeout(() => this._loop(), blockTime);
|
|
54
|
-
}
|
|
55
|
-
stop() {
|
|
56
|
-
if (this._state === MiningTimerState.STOP) {
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
this._state = MiningTimerState.STOP;
|
|
60
|
-
if (this._timeout !== null) {
|
|
61
|
-
clearTimeout(this._timeout);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
_validateBlockTime(blockTime) {
|
|
65
|
-
if (Array.isArray(blockTime)) {
|
|
66
|
-
const [rangeStart, rangeEnd] = blockTime;
|
|
67
|
-
if (rangeEnd < rangeStart) {
|
|
68
|
-
throw new Error("Invalid block time range");
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
if (blockTime < 0) {
|
|
73
|
-
throw new Error("Block time cannot be negative");
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
async _loop() {
|
|
78
|
-
if (this._state === MiningTimerState.STOP) {
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
await this._mineFunction();
|
|
82
|
-
const blockTime = this._getNextBlockTime();
|
|
83
|
-
this._timeout = setTimeout(() => {
|
|
84
|
-
this._loop(); // eslint-disable-line @typescript-eslint/no-floating-promises
|
|
85
|
-
}, blockTime);
|
|
86
|
-
}
|
|
87
|
-
_getNextBlockTime() {
|
|
88
|
-
if (Array.isArray(this._blockTime)) {
|
|
89
|
-
const [minBlockTime, maxBlockTime] = this._blockTime;
|
|
90
|
-
return (minBlockTime + Math.floor(Math.random() * (maxBlockTime - minBlockTime)));
|
|
91
|
-
}
|
|
92
|
-
return this._blockTime;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
exports.MiningTimer = MiningTimer;
|
|
96
|
-
//# sourceMappingURL=MiningTimer.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"MiningTimer.js","sourceRoot":"","sources":["../../../src/internal/hardhat-network/provider/MiningTimer.ts"],"names":[],"mappings":"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"}
|