Skip to content

Commit 18f8e9b

Browse files
committed
refactor: Streamline VMTracer construction in EDR stack trace tests
1 parent 91f6e21 commit 18f8e9b

File tree

4 files changed

+36
-59
lines changed

4 files changed

+36
-59
lines changed

packages/hardhat-core/src/internal/hardhat-network/provider/provider.ts

+19-31
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,9 @@ import type {
1212
import type {
1313
EdrContext,
1414
Provider as EdrProviderT,
15-
ExecutionResult,
1615
RawTrace,
1716
Response,
1817
SubscriptionEvent,
19-
TracingMessage,
20-
TracingStep,
2118
} from "@nomicfoundation/edr";
2219
import { Common } from "@nomicfoundation/ethereumjs-common";
2320
import chalk from "chalk";
@@ -152,12 +149,6 @@ export function getNodeConfig(
152149
};
153150
}
154151

155-
export interface RawTraceCallbacks {
156-
onStep?: (messageTrace: TracingStep) => Promise<void>;
157-
onBeforeMessage?: (messageTrace: TracingMessage) => Promise<void>;
158-
onAfterMessage?: (messageTrace: ExecutionResult) => Promise<void>;
159-
}
160-
161152
class EdrProviderEventAdapter extends EventEmitter {}
162153

163154
type CallOverrideCallback = (
@@ -184,7 +175,7 @@ export class EdrProviderWrapper
184175
},
185176
private readonly _eventAdapter: EdrProviderEventAdapter,
186177
private readonly _vmTraceDecoder: VmTraceDecoder,
187-
private readonly _rawTraceCallbacks: RawTraceCallbacks,
178+
private readonly _vmTracer: VMTracer | undefined,
188179
// The common configuration for EthereumJS VM is not used by EDR, but tests expect it as part of the provider.
189180
private readonly _common: Common,
190181
tracingConfig?: TracingConfig
@@ -199,8 +190,8 @@ export class EdrProviderWrapper
199190
public static async create(
200191
config: HardhatNetworkProviderConfig,
201192
loggerConfig: LoggerConfig,
202-
rawTraceCallbacks: RawTraceCallbacks,
203-
tracingConfig?: TracingConfig
193+
tracingConfig?: TracingConfig,
194+
vmTracer?: VMTracer
204195
): Promise<EdrProviderWrapper> {
205196
const { Provider } = requireNapiRsModule(
206197
"@nomicfoundation/edr"
@@ -325,7 +316,7 @@ export class EdrProviderWrapper
325316
minimalEthereumJsNode,
326317
eventAdapter,
327318
vmTraceDecoder,
328-
rawTraceCallbacks,
319+
vmTracer,
329320
common,
330321
tracingConfig
331322
);
@@ -371,9 +362,7 @@ export class EdrProviderWrapper
371362
const needsTraces =
372363
this._node._vm.evm.events.eventNames().length > 0 ||
373364
this._node._vm.events.eventNames().length > 0 ||
374-
this._rawTraceCallbacks.onStep !== undefined ||
375-
this._rawTraceCallbacks.onAfterMessage !== undefined ||
376-
this._rawTraceCallbacks.onBeforeMessage !== undefined;
365+
this._vmTracer !== undefined;
377366

378367
if (needsTraces) {
379368
const rawTraces = responseObject.traces;
@@ -394,9 +383,8 @@ export class EdrProviderWrapper
394383
edrTracingStepToMinimalInterpreterStep(traceItem)
395384
);
396385
}
397-
if (this._rawTraceCallbacks.onStep !== undefined) {
398-
await this._rawTraceCallbacks.onStep(traceItem);
399-
}
386+
387+
this._vmTracer?.addStep(traceItem);
400388
}
401389
// afterMessage event
402390
else if ("executionResult" in traceItem) {
@@ -406,11 +394,8 @@ export class EdrProviderWrapper
406394
edrTracingMessageResultToMinimalEVMResult(traceItem)
407395
);
408396
}
409-
if (this._rawTraceCallbacks.onAfterMessage !== undefined) {
410-
await this._rawTraceCallbacks.onAfterMessage(
411-
traceItem.executionResult
412-
);
413-
}
397+
398+
this._vmTracer?.addAfterMessage(traceItem.executionResult);
414399
}
415400
// beforeMessage event
416401
else {
@@ -420,9 +405,8 @@ export class EdrProviderWrapper
420405
edrTracingMessageToMinimalMessage(traceItem)
421406
);
422407
}
423-
if (this._rawTraceCallbacks.onBeforeMessage !== undefined) {
424-
await this._rawTraceCallbacks.onBeforeMessage(traceItem);
425-
}
408+
409+
this._vmTracer?.addBeforeMessage(traceItem);
426410
}
427411
}
428412

@@ -484,6 +468,11 @@ export class EdrProviderWrapper
484468
}
485469
}
486470

471+
/** Used for internal stack traces integration tests. Only defined there. */
472+
public vmTracer(): VMTracer | undefined {
473+
return this._vmTracer;
474+
}
475+
487476
// temporarily added to make smock work with HH+EDR
488477
private _setCallOverrideCallback(callback: CallOverrideCallback) {
489478
this._callOverrideCallback = callback;
@@ -588,11 +577,11 @@ export class EdrProviderWrapper
588577
const trace = rawTrace.trace();
589578
for (const traceItem of trace) {
590579
if ("pc" in traceItem) {
591-
await vmTracer.addStep(traceItem);
580+
vmTracer.addStep(traceItem);
592581
} else if ("executionResult" in traceItem) {
593-
await vmTracer.addAfterMessage(traceItem.executionResult);
582+
vmTracer.addAfterMessage(traceItem.executionResult);
594583
} else {
595-
await vmTracer.addBeforeMessage(traceItem);
584+
vmTracer.addBeforeMessage(traceItem);
596585
}
597586
}
598587

@@ -634,7 +623,6 @@ export async function createHardhatNetworkProvider(
634623
return EdrProviderWrapper.create(
635624
hardhatNetworkProviderConfig,
636625
loggerConfig,
637-
{},
638626
await makeTracingConfig(artifacts)
639627
);
640628
}

packages/hardhat-core/src/internal/hardhat-network/stack-traces/vm-tracer.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ export class VMTracer {
5454
return this._throwErrors || this._lastError === undefined;
5555
}
5656

57-
public async addBeforeMessage(message: TracingMessage) {
57+
public addBeforeMessage(message: TracingMessage) {
5858
if (!this._shouldKeepTracing()) {
5959
return;
6060
}
@@ -151,7 +151,7 @@ export class VMTracer {
151151
}
152152
}
153153

154-
public async addStep(step: TracingStep) {
154+
public addStep(step: TracingStep) {
155155
if (!this._shouldKeepTracing()) {
156156
return;
157157
}
@@ -177,7 +177,7 @@ export class VMTracer {
177177
}
178178
}
179179

180-
public async addAfterMessage(result: ExecutionResult, haltOverride?: Exit) {
180+
public addAfterMessage(result: ExecutionResult, haltOverride?: Exit) {
181181
if (!this._shouldKeepTracing()) {
182182
return;
183183
}

packages/hardhat-core/test/internal/hardhat-network/stack-traces/execution.ts

+11-17
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { assert } from "chai";
2+
13
import {
24
bigIntToHex,
35
bytesToHex,
@@ -29,7 +31,7 @@ const senderAddress = bytesToHex(privateToAddress(toBuffer(senderPrivateKey)));
2931
export async function instantiateProvider(
3032
loggerConfig: LoggerConfig,
3133
tracingConfig: TracingConfig
32-
): Promise<[EdrProviderWrapper, VMTracer]> {
34+
): Promise<EdrProviderWrapper> {
3335
const config = {
3436
hardfork: "shanghai",
3537
chainId: 1,
@@ -55,26 +57,14 @@ export async function instantiateProvider(
5557
enableTransientStorage: false,
5658
};
5759

58-
const vmTracer = new VMTracer(false);
59-
6060
const provider = await EdrProviderWrapper.create(
6161
config,
6262
loggerConfig,
63-
{
64-
onStep: async (step) => {
65-
await vmTracer.addStep(step);
66-
},
67-
onAfterMessage: async (message) => {
68-
await vmTracer.addAfterMessage(message);
69-
},
70-
onBeforeMessage: async (message) => {
71-
await vmTracer.addBeforeMessage(message);
72-
},
73-
},
74-
tracingConfig
63+
tracingConfig,
64+
new VMTracer(false)
7565
);
7666

77-
return [provider, vmTracer];
67+
return provider;
7868
}
7969

8070
export function encodeConstructorParams(
@@ -116,9 +106,13 @@ export interface TxData {
116106

117107
export async function traceTransaction(
118108
provider: EdrProviderWrapper,
119-
vmTracer: VMTracer,
120109
txData: TxData
121110
): Promise<MessageTrace> {
111+
const vmTracer = provider.vmTracer();
112+
if (vmTracer === undefined) {
113+
assert.fail("VMTracer should always be initialized in stack-traces");
114+
}
115+
122116
try {
123117
await provider.request({
124118
method: "eth_sendTransaction",

packages/hardhat-core/test/internal/hardhat-network/stack-traces/test.ts

+3-8
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import {
2727
} from "../../../../src/internal/hardhat-network/stack-traces/solidity-stack-trace";
2828
import { SolidityTracer } from "../../../../src/internal/hardhat-network/stack-traces/solidityTracer";
2929
import { VmTraceDecoder } from "../../../../src/internal/hardhat-network/stack-traces/vm-trace-decoder";
30-
import { VMTracer } from "../../../../src/internal/hardhat-network/stack-traces/vm-tracer";
3130
import {
3231
BuildInfo,
3332
CompilerInput,
@@ -498,7 +497,7 @@ async function runTest(
498497

499498
const logger = new FakeModulesLogger();
500499
const solidityTracer = new SolidityTracer();
501-
const [provider, vmTracer] = await instantiateProvider(
500+
const provider = await instantiateProvider(
502501
{
503502
enabled: false,
504503
printLineFn: logger.printLineFn(),
@@ -517,7 +516,6 @@ async function runTest(
517516
txIndex,
518517
tx,
519518
provider,
520-
vmTracer,
521519
compilerOutput,
522520
txIndexToContract
523521
);
@@ -541,7 +539,6 @@ async function runTest(
541539
txIndex,
542540
tx,
543541
provider,
544-
vmTracer,
545542
compilerOutput,
546543
contract!
547544
);
@@ -650,7 +647,6 @@ async function runDeploymentTransactionTest(
650647
txIndex: number,
651648
tx: DeploymentTransaction,
652649
provider: EdrProviderWrapper,
653-
vmTracer: VMTracer,
654650
compilerOutput: CompilerOutput,
655651
txIndexToContract: Map<number, DeployedContract>
656652
): Promise<CreateMessageTrace> {
@@ -682,7 +678,7 @@ async function runDeploymentTransactionTest(
682678

683679
const data = Buffer.concat([deploymentBytecode, params]);
684680

685-
const trace = await traceTransaction(provider, vmTracer, {
681+
const trace = await traceTransaction(provider, {
686682
value: tx.value !== undefined ? BigInt(tx.value) : undefined,
687683
data,
688684
gas: tx.gas !== undefined ? BigInt(tx.gas) : undefined,
@@ -695,7 +691,6 @@ async function runCallTransactionTest(
695691
txIndex: number,
696692
tx: CallTransaction,
697693
provider: EdrProviderWrapper,
698-
vmTracer: VMTracer,
699694
compilerOutput: CompilerOutput,
700695
contract: DeployedContract
701696
): Promise<CallMessageTrace> {
@@ -716,7 +711,7 @@ async function runCallTransactionTest(
716711
data = Buffer.from([]);
717712
}
718713

719-
const trace = await traceTransaction(provider, vmTracer, {
714+
const trace = await traceTransaction(provider, {
720715
to: contract.address,
721716
value: tx.value !== undefined ? BigInt(tx.value) : undefined,
722717
data,

0 commit comments

Comments
 (0)