diff --git a/.changeset/big-pumas-fail.md b/.changeset/big-pumas-fail.md new file mode 100644 index 0000000000..9a2d6563c1 --- /dev/null +++ b/.changeset/big-pumas-fail.md @@ -0,0 +1,5 @@ +--- +"hardhat": patch +--- + +Fixed an edge case where Hardhat would hang if `debug_traceTransaction` was used with an OOG transaction sent to a precompile. diff --git a/packages/hardhat-core/src/internal/hardhat-network/stack-traces/vm-debug-tracer.ts b/packages/hardhat-core/src/internal/hardhat-network/stack-traces/vm-debug-tracer.ts index 63c3431466..723b67bf7d 100644 --- a/packages/hardhat-core/src/internal/hardhat-network/stack-traces/vm-debug-tracer.ts +++ b/packages/hardhat-core/src/internal/hardhat-network/stack-traces/vm-debug-tracer.ts @@ -222,7 +222,10 @@ export class VMDebugTracer { ); // geth does this for some reason - if (result.execResult.exceptionError?.error === "out of gas") { + if ( + rpcStructLogs.length > 0 && + result.execResult.exceptionError?.error === "out of gas" + ) { rpcStructLogs[rpcStructLogs.length - 1].error = {}; } diff --git a/packages/hardhat-core/test/internal/hardhat-network/provider/modules/debug.ts b/packages/hardhat-core/test/internal/hardhat-network/provider/modules/debug.ts index 8dd06654c9..39128a67ed 100644 --- a/packages/hardhat-core/test/internal/hardhat-network/provider/modules/debug.ts +++ b/packages/hardhat-core/test/internal/hardhat-network/provider/modules/debug.ts @@ -127,6 +127,31 @@ describe("Debug module", function () { assertEqualTraces(trace, modifiesStateTrace); }); + it("should trace an OOG transaction sent to a precompile", async function () { + await sendDummyTransaction(this.provider, 0, { + from: DEFAULT_ACCOUNTS_ADDRESSES[1], + to: "0x0000000000000000000000000000000000000001", + }).catch(() => {}); + + const block = await this.provider.send("eth_getBlockByNumber", [ + "latest", + false, + ]); + + const txHash = block.transactions[0]; + + const trace: RpcDebugTraceOutput = await this.provider.send( + "debug_traceTransaction", + [txHash] + ); + assert.deepEqual(trace, { + gas: 21_000, + failed: true, + returnValue: "", + structLogs: [], + }); + }); + describe("berlin", function () { useProvider({ hardfork: "berlin" });