Skip to content

Commit

Permalink
Merge pull request #5195 from NomicFoundation/hardhat-tracer-support
Browse files Browse the repository at this point in the history
`hardhat-tracer` support
  • Loading branch information
fvictorio authored May 31, 2024
2 parents d2ce024 + b45eb94 commit 0c7b68e
Show file tree
Hide file tree
Showing 8 changed files with 750 additions and 658 deletions.
5 changes: 5 additions & 0 deletions .changeset/tall-coins-sin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"hardhat": patch
---

Made internal changes to allow `hardhat-tracer` to work with Hardhat again
2 changes: 1 addition & 1 deletion packages/hardhat-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@
"dependencies": {
"@ethersproject/abi": "^5.1.2",
"@metamask/eth-sig-util": "^4.0.0",
"@nomicfoundation/edr": "^0.3.8",
"@nomicfoundation/edr": "^0.4.0",
"@nomicfoundation/ethereumjs-common": "4.0.4",
"@nomicfoundation/ethereumjs-tx": "5.0.4",
"@nomicfoundation/ethereumjs-util": "9.0.4",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ export class EdrProviderWrapper

const needsTraces =
this._node._vm.evm.events.eventNames().length > 0 ||
this._node._vm.events.eventNames().length > 0 ||
this._rawTraceCallbacks.onStep !== undefined ||
this._rawTraceCallbacks.onAfterMessage !== undefined ||
this._rawTraceCallbacks.onBeforeMessage !== undefined;
Expand All @@ -378,7 +379,14 @@ export class EdrProviderWrapper
const rawTraces = responseObject.traces;
for (const rawTrace of rawTraces) {
const trace = rawTrace.trace();

// beforeTx event
if (this._node._vm.events.listenerCount("beforeTx") > 0) {
this._node._vm.events.emit("beforeTx");
}

for (const traceItem of trace) {
// step event
if ("pc" in traceItem) {
if (this._node._vm.evm.events.listenerCount("step") > 0) {
this._node._vm.evm.events.emit(
Expand All @@ -389,7 +397,9 @@ export class EdrProviderWrapper
if (this._rawTraceCallbacks.onStep !== undefined) {
await this._rawTraceCallbacks.onStep(traceItem);
}
} else if ("executionResult" in traceItem) {
}
// afterMessage event
else if ("executionResult" in traceItem) {
if (this._node._vm.evm.events.listenerCount("afterMessage") > 0) {
this._node._vm.evm.events.emit(
"afterMessage",
Expand All @@ -401,7 +411,9 @@ export class EdrProviderWrapper
traceItem.executionResult
);
}
} else {
}
// beforeMessage event
else {
if (this._node._vm.evm.events.listenerCount("beforeMessage") > 0) {
this._node._vm.evm.events.emit(
"beforeMessage",
Expand All @@ -413,6 +425,11 @@ export class EdrProviderWrapper
}
}
}

// afterTx event
if (this._node._vm.events.listenerCount("afterTx") > 0) {
this._node._vm.events.emit("afterTx");
}
}
}

Expand Down Expand Up @@ -478,6 +495,10 @@ export class EdrProviderWrapper
);
}

private _setVerboseTracing(enabled: boolean) {
this._provider.setVerboseTracing(enabled);
}

private _ethEventListener(event: SubscriptionEvent) {
const subscription = `0x${event.filterId.toString(16)}`;
const results = Array.isArray(event.result) ? event.result : [event.result];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,24 +208,55 @@ export function edrRpcDebugTraceToHardhat(
export function edrTracingStepToMinimalInterpreterStep(
step: TracingStep
): MinimalInterpreterStep {
return {
const minimalInterpreterStep: MinimalInterpreterStep = {
pc: Number(step.pc),
depth: step.depth,
opcode: {
name: step.opcode,
},
stack: step.stackTop !== undefined ? [step.stackTop] : [],
stack: step.stack,
};

if (step.memory !== undefined) {
minimalInterpreterStep.memory = step.memory;
}

return minimalInterpreterStep;
}

export function edrTracingMessageResultToMinimalEVMResult(
tracingMessageResult: TracingMessageResult
): MinimalEVMResult {
return {
const { result, contractAddress } = tracingMessageResult.executionResult;

// only SuccessResult has logs
const success = "logs" in result;

const minimalEVMResult: MinimalEVMResult = {
execResult: {
executionGasUsed: tracingMessageResult.executionResult.result.gasUsed,
executionGasUsed: result.gasUsed,
success,
},
};

// only success and exceptional halt have reason
if ("reason" in result) {
minimalEVMResult.execResult.reason = result.reason;
}
if ("output" in result) {
const { output } = result;
if (Buffer.isBuffer(output)) {
minimalEVMResult.execResult.output = output;
} else {
minimalEVMResult.execResult.output = output.returnValue;
}
}

if (contractAddress !== undefined) {
minimalEVMResult.execResult.contractAddress = new Address(contractAddress);
}

return minimalEVMResult;
}

export function edrTracingMessageToMinimalMessage(
Expand All @@ -241,5 +272,6 @@ export function edrTracingMessageToMinimalMessage(
value: message.value,
caller: new Address(message.caller),
gasLimit: message.gasLimit,
isStaticCall: message.isStaticCall,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ import { AsyncEventEmitter } from "@nomicfoundation/ethereumjs-util";
* interface only has the things used by those plugins.
*/
export interface MinimalEthereumJsVm {
events: AsyncEventEmitter<MinimalEthereumJsVmEvents>;
evm: {
events: AsyncEventEmitter<MinimalEthereumJsVmEvents>;
events: AsyncEventEmitter<MinimalEthereumJsEvmEvents>;
};
stateManager: {
putContractCode: (address: Address, code: Buffer) => Promise<void>;
Expand All @@ -27,10 +28,18 @@ export interface MinimalEthereumJsVm {
};
}

// we need to use a type instead of an interface to satisfy the type constarint
// we need to use a type instead of an interface to satisfy the type constraint
// of the AsyncEventEmitter type param
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
type MinimalEthereumJsVmEvents = {
beforeTx: () => void;
afterTx: () => void;
};

// we need to use a type instead of an interface to satisfy the type constraint
// of the AsyncEventEmitter type param
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
type MinimalEthereumJsEvmEvents = {
beforeMessage: (
data: MinimalMessage,
resolve?: (result?: any) => void
Expand All @@ -46,13 +55,15 @@ type MinimalEthereumJsVmEvents = {
};

export class MinimalEthereumJsVmEventEmitter extends AsyncEventEmitter<MinimalEthereumJsVmEvents> {}
export class MinimalEthereumJsEvmEventEmitter extends AsyncEventEmitter<MinimalEthereumJsEvmEvents> {}

export function getMinimalEthereumJsVm(
provider: EdrProviderT
): MinimalEthereumJsVm {
const minimalEthereumJsVm: MinimalEthereumJsVm = {
events: new MinimalEthereumJsVmEventEmitter(),
evm: {
events: new MinimalEthereumJsVmEventEmitter(),
events: new MinimalEthereumJsEvmEventEmitter(),
},
stateManager: {
putContractCode: async (address: Address, code: Buffer) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { ExceptionalHalt, SuccessReason } from "@nomicfoundation/edr";
import type { Address } from "@nomicfoundation/ethereumjs-util";

/**
Expand All @@ -12,10 +13,15 @@ export interface MinimalInterpreterStep {
name: string;
};
stack: bigint[];
memory?: Uint8Array;
}

export interface MinimalExecResult {
success: boolean;
executionGasUsed: bigint;
contractAddress?: Address;
reason?: SuccessReason | ExceptionalHalt;
output?: Buffer;
}

export interface MinimalEVMResult {
Expand All @@ -29,4 +35,5 @@ export interface MinimalMessage {
data: Uint8Array;
caller: Address;
gasLimit: bigint;
isStaticCall: boolean;
}
4 changes: 3 additions & 1 deletion packages/hardhat-truffle5/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@
"rimraf": "^3.0.2",
"ts-node": "^10.8.0",
"typescript": "~5.0.0",
"web3": "^1.0.0-beta.36"
"web3": "^1.0.0-beta.36",
"web3-eth-abi": "1.10.4",
"web3-utils": "1.10.4"
},
"peerDependencies": {
"@nomiclabs/hardhat-web3": "workspace:^2.0.0",
Expand Down
Loading

0 comments on commit 0c7b68e

Please sign in to comment.