Skip to content

Commit 55a59d6

Browse files
committed
WIP: working so far
1 parent 0cc20ca commit 55a59d6

File tree

4 files changed

+24
-154
lines changed

4 files changed

+24
-154
lines changed

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

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { bytesToHex as bufferToHex } from "@nomicfoundation/ethereumjs-util";
22
import chalk from "chalk";
33

4-
import { stackTraceEntryTypeToString } from "@nomicfoundation/edr";
4+
import { ReturnData, stackTraceEntryTypeToString } from "@nomicfoundation/edr";
55
import {
66
CallMessageTrace,
77
CreateMessageTrace,
@@ -152,7 +152,9 @@ function traceSteps(
152152
: "";
153153

154154
console.log(
155-
`${margin} ${pc} ${opcodeToString(inst.opcode)} ${jump}`.padEnd(50),
155+
`${margin} ${pc} ${opcodeToString(inst.opcode)} ${jump}`.padEnd(
156+
50
157+
),
156158
location
157159
);
158160
} else if (isPush(inst.opcode)) {
@@ -191,7 +193,7 @@ function flattenSourceReference(sourceReference?: SourceReference) {
191193
export function printStackTrace(trace: SolidityStackTrace) {
192194
const withDecodedMessages = trace.map((entry) =>
193195
entry.type === StackTraceEntryType.REVERT_ERROR
194-
? { ...entry, message: entry.message.decodeError() }
196+
? { ...entry, message: new ReturnData(entry.returnData).decodeError() }
195197
: entry
196198
);
197199

packages/hardhat-core/src/internal/hardhat-network/stack-traces/mapped-inlined-internal-functions-heuristics.ts

+4-143
Original file line numberDiff line numberDiff line change
@@ -18,146 +18,7 @@
1818
* more meaningful errors.
1919
*/
2020

21-
import semver from "semver";
22-
23-
import {
24-
DecodedEvmMessageTrace,
25-
isDecodedCallTrace,
26-
isDecodedCreateTrace,
27-
isEvmStep,
28-
} from "./message-trace";
29-
import { Opcode } from "./opcodes";
30-
import {
31-
SolidityStackTrace,
32-
StackTraceEntryType,
33-
} from "./solidity-stack-trace";
34-
35-
const FIRST_SOLC_VERSION_WITH_MAPPED_SMALL_INTERNAL_FUNCTIONS = "0.6.9";
36-
37-
export function stackTraceMayRequireAdjustments(
38-
stackTrace: SolidityStackTrace,
39-
decodedTrace: DecodedEvmMessageTrace
40-
): boolean {
41-
if (stackTrace.length === 0) {
42-
return false;
43-
}
44-
45-
const lastFrame = stackTrace[stackTrace.length - 1];
46-
47-
return (
48-
lastFrame.type === StackTraceEntryType.REVERT_ERROR &&
49-
!lastFrame.isInvalidOpcodeError &&
50-
lastFrame.message.isEmpty() &&
51-
semver.gte(
52-
decodedTrace.bytecode.compilerVersion,
53-
FIRST_SOLC_VERSION_WITH_MAPPED_SMALL_INTERNAL_FUNCTIONS
54-
)
55-
);
56-
}
57-
58-
export function adjustStackTrace(
59-
stackTrace: SolidityStackTrace,
60-
decodedTrace: DecodedEvmMessageTrace
61-
): SolidityStackTrace {
62-
const start = stackTrace.slice(0, -1);
63-
const [revert] = stackTrace.slice(-1);
64-
65-
if (isNonContractAccountCalledError(decodedTrace)) {
66-
return [
67-
...start,
68-
{
69-
type: StackTraceEntryType.NONCONTRACT_ACCOUNT_CALLED_ERROR,
70-
sourceReference: revert.sourceReference!,
71-
},
72-
];
73-
}
74-
75-
if (isConstructorInvalidParamsError(decodedTrace)) {
76-
return [
77-
...start,
78-
{
79-
type: StackTraceEntryType.INVALID_PARAMS_ERROR,
80-
sourceReference: revert.sourceReference!,
81-
},
82-
];
83-
}
84-
85-
if (isCallInvalidParamsError(decodedTrace)) {
86-
return [
87-
...start,
88-
{
89-
type: StackTraceEntryType.INVALID_PARAMS_ERROR,
90-
sourceReference: revert.sourceReference!,
91-
},
92-
];
93-
}
94-
95-
return stackTrace;
96-
}
97-
98-
function isNonContractAccountCalledError(
99-
decodedTrace: DecodedEvmMessageTrace
100-
): boolean {
101-
return matchOpcodes(decodedTrace, -9, [
102-
Opcode.EXTCODESIZE,
103-
Opcode.ISZERO,
104-
Opcode.DUP1,
105-
Opcode.ISZERO,
106-
]);
107-
}
108-
109-
function isConstructorInvalidParamsError(decodedTrace: DecodedEvmMessageTrace) {
110-
if (!isDecodedCreateTrace(decodedTrace)) {
111-
return false;
112-
}
113-
114-
return (
115-
matchOpcodes(decodedTrace, -20, [Opcode.CODESIZE]) &&
116-
matchOpcodes(decodedTrace, -15, [Opcode.CODECOPY]) &&
117-
matchOpcodes(decodedTrace, -7, [Opcode.LT, Opcode.ISZERO])
118-
);
119-
}
120-
121-
function isCallInvalidParamsError(decodedTrace: DecodedEvmMessageTrace) {
122-
if (!isDecodedCallTrace(decodedTrace)) {
123-
return false;
124-
}
125-
126-
return (
127-
matchOpcodes(decodedTrace, -11, [Opcode.CALLDATASIZE]) &&
128-
matchOpcodes(decodedTrace, -7, [Opcode.LT, Opcode.ISZERO])
129-
);
130-
}
131-
132-
function matchOpcode(
133-
decodedTrace: DecodedEvmMessageTrace,
134-
stepIndex: number,
135-
opcode: Opcode
136-
): boolean {
137-
const [step] = decodedTrace.steps.slice(stepIndex, stepIndex + 1);
138-
139-
if (step === undefined || !isEvmStep(step)) {
140-
return false;
141-
}
142-
143-
const instruction = decodedTrace.bytecode.getInstruction(step.pc);
144-
145-
return instruction.opcode === opcode;
146-
}
147-
148-
function matchOpcodes(
149-
decodedTrace: DecodedEvmMessageTrace,
150-
firstStepIndex: number,
151-
opcodes: Opcode[]
152-
): boolean {
153-
let index = firstStepIndex;
154-
for (const opcode of opcodes) {
155-
if (!matchOpcode(decodedTrace, index, opcode)) {
156-
return false;
157-
}
158-
159-
index += 1;
160-
}
161-
162-
return true;
163-
}
21+
export {
22+
stackTraceMayRequireAdjustments,
23+
adjustStackTrace,
24+
} from "@nomicfoundation/edr";

packages/hardhat-core/src/internal/hardhat-network/stack-traces/solidity-errors.ts

+13-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { bytesToHex as bufferToHex } from "@nomicfoundation/ethereumjs-util";
22

3+
import { ReturnData } from "../provider/return-data";
34
import { panicErrorCodeToMessage } from "./panic-errors";
45
import {
56
CONSTRUCTOR_FUNCTION_NAME,
@@ -259,19 +260,21 @@ function getMessageFromLastStackTraceEntry(
259260

260261
case StackTraceEntryType.UNRECOGNIZED_CREATE_ERROR:
261262
case StackTraceEntryType.UNRECOGNIZED_CONTRACT_ERROR:
262-
if (stackTraceEntry.message.isErrorReturnData()) {
263-
return `VM Exception while processing transaction: reverted with reason string '${stackTraceEntry.message.decodeError()}'`;
263+
if (new ReturnData(stackTraceEntry.returnData).isErrorReturnData()) {
264+
return `VM Exception while processing transaction: reverted with reason string '${new ReturnData(
265+
stackTraceEntry.returnData
266+
).decodeError()}'`;
264267
}
265268

266-
if (stackTraceEntry.message.isPanicReturnData()) {
269+
if (new ReturnData(stackTraceEntry.returnData).isPanicReturnData()) {
267270
const message = panicErrorCodeToMessage(
268-
stackTraceEntry.message.decodePanic()
271+
new ReturnData(stackTraceEntry.returnData).decodePanic()
269272
);
270273
return `VM Exception while processing transaction: ${message}`;
271274
}
272275

273-
if (!stackTraceEntry.message.isEmpty()) {
274-
const returnData = Buffer.from(stackTraceEntry.message.value).toString(
276+
if (!new ReturnData(stackTraceEntry.returnData).isEmpty()) {
277+
const returnData = Buffer.from(stackTraceEntry.returnData).toString(
275278
"hex"
276279
);
277280

@@ -285,8 +288,10 @@ function getMessageFromLastStackTraceEntry(
285288
return "Transaction reverted without a reason string";
286289

287290
case StackTraceEntryType.REVERT_ERROR:
288-
if (stackTraceEntry.message.isErrorReturnData()) {
289-
return `VM Exception while processing transaction: reverted with reason string '${stackTraceEntry.message.decodeError()}'`;
291+
if (new ReturnData(stackTraceEntry.returnData).isErrorReturnData()) {
292+
return `VM Exception while processing transaction: reverted with reason string '${new ReturnData(
293+
stackTraceEntry.returnData
294+
).decodeError()}'`;
290295
}
291296

292297
if (stackTraceEntry.isInvalidOpcodeError) {

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

+2
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ export class SolidityTracer {
118118
{
119119
type: StackTraceEntryType.UNRECOGNIZED_CREATE_ERROR,
120120
message: new ReturnData(trace.returnData),
121+
returnData: trace.returnData,
121122
isInvalidOpcodeError,
122123
},
123124
];
@@ -128,6 +129,7 @@ export class SolidityTracer {
128129
type: StackTraceEntryType.UNRECOGNIZED_CONTRACT_ERROR,
129130
address: trace.address,
130131
message: new ReturnData(trace.returnData),
132+
returnData: trace.returnData,
131133
isInvalidOpcodeError,
132134
},
133135
];

0 commit comments

Comments
 (0)