hardhat 2.22.10 → 2.22.12
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/console.sol +1 -1
- package/internal/cli/project-creation.d.ts +1 -1
- package/internal/cli/project-creation.js +1 -1
- package/internal/core/providers/lazy-initialization.d.ts.map +1 -1
- package/internal/core/providers/lazy-initialization.js +10 -10
- package/internal/core/providers/lazy-initialization.js.map +1 -1
- package/internal/hardhat-network/jsonrpc/handler.d.ts.map +1 -1
- package/internal/hardhat-network/jsonrpc/handler.js +2 -1
- package/internal/hardhat-network/jsonrpc/handler.js.map +1 -1
- package/internal/hardhat-network/provider/provider.d.ts +2 -3
- package/internal/hardhat-network/provider/provider.d.ts.map +1 -1
- package/internal/hardhat-network/provider/provider.js +5 -19
- package/internal/hardhat-network/provider/provider.js.map +1 -1
- package/internal/hardhat-network/provider/return-data.d.ts +2 -15
- package/internal/hardhat-network/provider/return-data.d.ts.map +1 -1
- package/internal/hardhat-network/provider/return-data.js +2 -50
- package/internal/hardhat-network/provider/return-data.js.map +1 -1
- package/internal/hardhat-network/provider/vm/exit.d.ts +2 -20
- package/internal/hardhat-network/provider/vm/exit.d.ts.map +1 -1
- package/internal/hardhat-network/provider/vm/exit.js +3 -78
- package/internal/hardhat-network/provider/vm/exit.js.map +1 -1
- package/internal/hardhat-network/stack-traces/compiler-to-model.d.ts +2 -3
- package/internal/hardhat-network/stack-traces/compiler-to-model.d.ts.map +1 -1
- package/internal/hardhat-network/stack-traces/compiler-to-model.js +2 -351
- package/internal/hardhat-network/stack-traces/compiler-to-model.js.map +1 -1
- package/internal/hardhat-network/stack-traces/consoleLogger.d.ts +2 -1
- package/internal/hardhat-network/stack-traces/consoleLogger.d.ts.map +1 -1
- package/internal/hardhat-network/stack-traces/consoleLogger.js +2 -1
- package/internal/hardhat-network/stack-traces/consoleLogger.js.map +1 -1
- package/internal/hardhat-network/stack-traces/constants.d.ts +1 -1
- package/internal/hardhat-network/stack-traces/constants.js +1 -1
- package/internal/hardhat-network/stack-traces/debug.d.ts +2 -7
- package/internal/hardhat-network/stack-traces/debug.d.ts.map +1 -1
- package/internal/hardhat-network/stack-traces/debug.js +3 -143
- package/internal/hardhat-network/stack-traces/debug.js.map +1 -1
- package/internal/hardhat-network/stack-traces/library-utils.d.ts +2 -11
- package/internal/hardhat-network/stack-traces/library-utils.d.ts.map +1 -1
- package/internal/hardhat-network/stack-traces/library-utils.js +3 -61
- package/internal/hardhat-network/stack-traces/library-utils.js.map +1 -1
- package/internal/hardhat-network/stack-traces/logger.js +596 -596
- package/internal/hardhat-network/stack-traces/logger.js.map +1 -1
- package/internal/hardhat-network/stack-traces/message-trace.d.ts +2 -51
- package/internal/hardhat-network/stack-traces/message-trace.d.ts.map +1 -1
- package/internal/hardhat-network/stack-traces/message-trace.js +0 -46
- package/internal/hardhat-network/stack-traces/message-trace.js.map +1 -1
- package/internal/hardhat-network/stack-traces/solidity-errors.d.ts.map +1 -1
- package/internal/hardhat-network/stack-traces/solidity-errors.js +58 -53
- package/internal/hardhat-network/stack-traces/solidity-errors.js.map +1 -1
- package/internal/hardhat-network/stack-traces/solidity-stack-trace.d.ts +4 -155
- package/internal/hardhat-network/stack-traces/solidity-stack-trace.d.ts.map +1 -1
- package/internal/hardhat-network/stack-traces/solidity-stack-trace.js +12 -37
- package/internal/hardhat-network/stack-traces/solidity-stack-trace.js.map +1 -1
- package/internal/hardhat-network/stack-traces/solidityTracer.d.ts +2 -13
- package/internal/hardhat-network/stack-traces/solidityTracer.d.ts.map +1 -1
- package/internal/hardhat-network/stack-traces/solidityTracer.js +2 -162
- package/internal/hardhat-network/stack-traces/solidityTracer.js.map +1 -1
- package/internal/hardhat-network/stack-traces/vm-trace-decoder.d.ts +4 -15
- package/internal/hardhat-network/stack-traces/vm-trace-decoder.d.ts.map +1 -1
- package/internal/hardhat-network/stack-traces/vm-trace-decoder.js +6 -70
- package/internal/hardhat-network/stack-traces/vm-trace-decoder.js.map +1 -1
- package/internal/hardhat-network/stack-traces/vm-tracer.d.ts +2 -19
- package/internal/hardhat-network/stack-traces/vm-tracer.d.ts.map +1 -1
- package/internal/hardhat-network/stack-traces/vm-tracer.js +3 -150
- package/internal/hardhat-network/stack-traces/vm-tracer.js.map +1 -1
- package/internal/solidity/compiler/solc-info.d.ts.map +1 -1
- package/internal/solidity/compiler/solc-info.js +3 -0
- package/internal/solidity/compiler/solc-info.js.map +1 -1
- package/package.json +6 -5
- package/sample-projects/javascript/contracts/Lock.sol +1 -1
- package/sample-projects/javascript/hardhat.config.js +1 -1
- package/sample-projects/javascript/ignition/modules/Lock.js +3 -0
- package/sample-projects/javascript-esm/contracts/Lock.sol +1 -1
- package/sample-projects/javascript-esm/hardhat.config.cjs +1 -1
- package/sample-projects/javascript-esm/ignition/modules/Lock.js +3 -0
- package/sample-projects/typescript/contracts/Lock.sol +1 -1
- package/sample-projects/typescript/hardhat.config.ts +1 -1
- package/sample-projects/typescript/ignition/modules/Lock.ts +3 -0
- package/sample-projects/typescript-viem/contracts/Lock.sol +1 -1
- package/sample-projects/typescript-viem/hardhat.config.ts +1 -1
- package/sample-projects/typescript-viem/ignition/modules/Lock.ts +3 -0
- package/src/internal/cli/project-creation.ts +1 -1
- package/src/internal/core/providers/lazy-initialization.ts +13 -13
- package/src/internal/hardhat-network/jsonrpc/handler.ts +2 -1
- package/src/internal/hardhat-network/provider/provider.ts +11 -24
- package/src/internal/hardhat-network/provider/return-data.ts +5 -73
- package/src/internal/hardhat-network/provider/vm/exit.ts +4 -92
- package/src/internal/hardhat-network/stack-traces/compiler-to-model.ts +5 -697
- package/src/internal/hardhat-network/stack-traces/consoleLogger.ts +2 -1
- package/src/internal/hardhat-network/stack-traces/constants.ts +1 -1
- package/src/internal/hardhat-network/stack-traces/debug.ts +5 -218
- package/src/internal/hardhat-network/stack-traces/library-utils.ts +5 -90
- package/src/internal/hardhat-network/stack-traces/logger.ts +596 -596
- package/src/internal/hardhat-network/stack-traces/message-trace.ts +5 -122
- package/src/internal/hardhat-network/stack-traces/solidity-errors.ts +16 -15
- package/src/internal/hardhat-network/stack-traces/solidity-stack-trace.ts +83 -186
- package/src/internal/hardhat-network/stack-traces/solidityTracer.ts +5 -253
- package/src/internal/hardhat-network/stack-traces/vm-trace-decoder.ts +15 -108
- package/src/internal/hardhat-network/stack-traces/vm-tracer.ts +5 -206
- package/src/internal/solidity/compiler/solc-info.ts +3 -0
- package/internal/hardhat-network/stack-traces/contracts-identifier.d.ts +0 -15
- package/internal/hardhat-network/stack-traces/contracts-identifier.d.ts.map +0 -1
- package/internal/hardhat-network/stack-traces/contracts-identifier.js +0 -166
- package/internal/hardhat-network/stack-traces/contracts-identifier.js.map +0 -1
- package/internal/hardhat-network/stack-traces/error-inferrer.d.ts +0 -85
- package/internal/hardhat-network/stack-traces/error-inferrer.d.ts.map +0 -1
- package/internal/hardhat-network/stack-traces/error-inferrer.js +0 -1168
- package/internal/hardhat-network/stack-traces/error-inferrer.js.map +0 -1
- package/internal/hardhat-network/stack-traces/mapped-inlined-internal-functions-heuristics.d.ts +0 -24
- package/internal/hardhat-network/stack-traces/mapped-inlined-internal-functions-heuristics.d.ts.map +0 -1
- package/internal/hardhat-network/stack-traces/mapped-inlined-internal-functions-heuristics.js +0 -116
- package/internal/hardhat-network/stack-traces/mapped-inlined-internal-functions-heuristics.js.map +0 -1
- package/internal/hardhat-network/stack-traces/model.d.ts +0 -140
- package/internal/hardhat-network/stack-traces/model.d.ts.map +0 -1
- package/internal/hardhat-network/stack-traces/model.js +0 -328
- package/internal/hardhat-network/stack-traces/model.js.map +0 -1
- package/internal/hardhat-network/stack-traces/opcodes.d.ts +0 -266
- package/internal/hardhat-network/stack-traces/opcodes.d.ts.map +0 -1
- package/internal/hardhat-network/stack-traces/opcodes.js +0 -320
- package/internal/hardhat-network/stack-traces/opcodes.js.map +0 -1
- package/internal/hardhat-network/stack-traces/source-maps.d.ts +0 -13
- package/internal/hardhat-network/stack-traces/source-maps.d.ts.map +0 -1
- package/internal/hardhat-network/stack-traces/source-maps.js +0 -106
- package/internal/hardhat-network/stack-traces/source-maps.js.map +0 -1
- package/src/internal/hardhat-network/stack-traces/contracts-identifier.ts +0 -235
- package/src/internal/hardhat-network/stack-traces/error-inferrer.ts +0 -1845
- package/src/internal/hardhat-network/stack-traces/mapped-inlined-internal-functions-heuristics.ts +0 -163
- package/src/internal/hardhat-network/stack-traces/model.ts +0 -409
- package/src/internal/hardhat-network/stack-traces/opcodes.ts +0 -344
- package/src/internal/hardhat-network/stack-traces/source-maps.ts +0 -167
|
@@ -1,255 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { requireNapiRsModule } from "../../../common/napi-rs";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
const { SolidityTracer } = requireNapiRsModule(
|
|
4
|
+
"@nomicfoundation/edr"
|
|
5
|
+
) as typeof import("@nomicfoundation/edr");
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
ErrorInferrer,
|
|
8
|
-
instructionToCallstackStackTraceEntry,
|
|
9
|
-
SubmessageData,
|
|
10
|
-
} from "./error-inferrer";
|
|
11
|
-
import {
|
|
12
|
-
adjustStackTrace,
|
|
13
|
-
stackTraceMayRequireAdjustments,
|
|
14
|
-
} from "./mapped-inlined-internal-functions-heuristics";
|
|
15
|
-
import {
|
|
16
|
-
DecodedCallMessageTrace,
|
|
17
|
-
DecodedCreateMessageTrace,
|
|
18
|
-
DecodedEvmMessageTrace,
|
|
19
|
-
EvmMessageTrace,
|
|
20
|
-
EvmStep,
|
|
21
|
-
isCreateTrace,
|
|
22
|
-
isDecodedCallTrace,
|
|
23
|
-
isDecodedCreateTrace,
|
|
24
|
-
isEvmStep,
|
|
25
|
-
isPrecompileTrace,
|
|
26
|
-
MessageTrace,
|
|
27
|
-
PrecompileMessageTrace,
|
|
28
|
-
} from "./message-trace";
|
|
29
|
-
import { Instruction, JumpType } from "./model";
|
|
30
|
-
import { Opcode } from "./opcodes";
|
|
31
|
-
import {
|
|
32
|
-
SolidityStackTrace,
|
|
33
|
-
SolidityStackTraceEntry,
|
|
34
|
-
StackTraceEntryType,
|
|
35
|
-
} from "./solidity-stack-trace";
|
|
36
|
-
|
|
37
|
-
export class SolidityTracer {
|
|
38
|
-
private _errorInferrer = new ErrorInferrer();
|
|
39
|
-
|
|
40
|
-
public getStackTrace(
|
|
41
|
-
maybeDecodedMessageTrace: MessageTrace
|
|
42
|
-
): SolidityStackTrace {
|
|
43
|
-
if (!maybeDecodedMessageTrace.exit.isError()) {
|
|
44
|
-
return [];
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
if (isPrecompileTrace(maybeDecodedMessageTrace)) {
|
|
48
|
-
return this._getPrecompileMessageStackTrace(maybeDecodedMessageTrace);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (isDecodedCreateTrace(maybeDecodedMessageTrace)) {
|
|
52
|
-
return this._getCreateMessageStackTrace(maybeDecodedMessageTrace);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
if (isDecodedCallTrace(maybeDecodedMessageTrace)) {
|
|
56
|
-
return this._getCallMessageStackTrace(maybeDecodedMessageTrace);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
return this._getUnrecognizedMessageStackTrace(maybeDecodedMessageTrace);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
private _getCallMessageStackTrace(
|
|
63
|
-
trace: DecodedCallMessageTrace
|
|
64
|
-
): SolidityStackTrace {
|
|
65
|
-
const inferredError =
|
|
66
|
-
this._errorInferrer.inferBeforeTracingCallMessage(trace);
|
|
67
|
-
|
|
68
|
-
if (inferredError !== undefined) {
|
|
69
|
-
return inferredError;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return this._traceEvmExecution(trace);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
private _getUnrecognizedMessageStackTrace(
|
|
76
|
-
trace: EvmMessageTrace
|
|
77
|
-
): SolidityStackTrace {
|
|
78
|
-
const subtrace = this._getLastSubtrace(trace);
|
|
79
|
-
|
|
80
|
-
if (subtrace !== undefined) {
|
|
81
|
-
// This is not a very exact heuristic, but most of the time it will be right, as solidity
|
|
82
|
-
// reverts if a call fails, and most contracts are in solidity
|
|
83
|
-
if (
|
|
84
|
-
subtrace.exit.isError() &&
|
|
85
|
-
equalsBytes(trace.returnData, subtrace.returnData)
|
|
86
|
-
) {
|
|
87
|
-
let unrecognizedEntry: SolidityStackTraceEntry;
|
|
88
|
-
|
|
89
|
-
if (isCreateTrace(trace)) {
|
|
90
|
-
unrecognizedEntry = {
|
|
91
|
-
type: StackTraceEntryType.UNRECOGNIZED_CREATE_CALLSTACK_ENTRY,
|
|
92
|
-
};
|
|
93
|
-
} else {
|
|
94
|
-
unrecognizedEntry = {
|
|
95
|
-
type: StackTraceEntryType.UNRECOGNIZED_CONTRACT_CALLSTACK_ENTRY,
|
|
96
|
-
address: trace.address,
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
return [unrecognizedEntry, ...this.getStackTrace(subtrace)];
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
if (trace.exit.kind === ExitCode.CODESIZE_EXCEEDS_MAXIMUM) {
|
|
105
|
-
return [
|
|
106
|
-
{
|
|
107
|
-
type: StackTraceEntryType.CONTRACT_TOO_LARGE_ERROR,
|
|
108
|
-
},
|
|
109
|
-
];
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const isInvalidOpcodeError = trace.exit.kind === ExitCode.INVALID_OPCODE;
|
|
113
|
-
|
|
114
|
-
if (isCreateTrace(trace)) {
|
|
115
|
-
return [
|
|
116
|
-
{
|
|
117
|
-
type: StackTraceEntryType.UNRECOGNIZED_CREATE_ERROR,
|
|
118
|
-
message: new ReturnData(trace.returnData),
|
|
119
|
-
isInvalidOpcodeError,
|
|
120
|
-
},
|
|
121
|
-
];
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
return [
|
|
125
|
-
{
|
|
126
|
-
type: StackTraceEntryType.UNRECOGNIZED_CONTRACT_ERROR,
|
|
127
|
-
address: trace.address,
|
|
128
|
-
message: new ReturnData(trace.returnData),
|
|
129
|
-
isInvalidOpcodeError,
|
|
130
|
-
},
|
|
131
|
-
];
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
private _getCreateMessageStackTrace(
|
|
135
|
-
trace: DecodedCreateMessageTrace
|
|
136
|
-
): SolidityStackTrace {
|
|
137
|
-
const inferredError =
|
|
138
|
-
this._errorInferrer.inferBeforeTracingCreateMessage(trace);
|
|
139
|
-
|
|
140
|
-
if (inferredError !== undefined) {
|
|
141
|
-
return inferredError;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
return this._traceEvmExecution(trace);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
private _getPrecompileMessageStackTrace(
|
|
148
|
-
trace: PrecompileMessageTrace
|
|
149
|
-
): SolidityStackTrace {
|
|
150
|
-
return [
|
|
151
|
-
{
|
|
152
|
-
type: StackTraceEntryType.PRECOMPILE_ERROR,
|
|
153
|
-
precompile: trace.precompile,
|
|
154
|
-
},
|
|
155
|
-
];
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
private _traceEvmExecution(
|
|
159
|
-
trace: DecodedEvmMessageTrace
|
|
160
|
-
): SolidityStackTrace {
|
|
161
|
-
const stackTrace = this._rawTraceEvmExecution(trace);
|
|
162
|
-
|
|
163
|
-
if (stackTraceMayRequireAdjustments(stackTrace, trace)) {
|
|
164
|
-
return adjustStackTrace(stackTrace, trace);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
return stackTrace;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
private _rawTraceEvmExecution(
|
|
171
|
-
trace: DecodedEvmMessageTrace
|
|
172
|
-
): SolidityStackTrace {
|
|
173
|
-
const stacktrace: SolidityStackTrace = [];
|
|
174
|
-
|
|
175
|
-
let subtracesSeen = 0;
|
|
176
|
-
|
|
177
|
-
// There was a jump into a function according to the sourcemaps
|
|
178
|
-
let jumpedIntoFunction = false;
|
|
179
|
-
|
|
180
|
-
const functionJumpdests: Instruction[] = [];
|
|
181
|
-
|
|
182
|
-
let lastSubmessageData: SubmessageData | undefined;
|
|
183
|
-
|
|
184
|
-
for (let stepIndex = 0; stepIndex < trace.steps.length; stepIndex++) {
|
|
185
|
-
const step = trace.steps[stepIndex];
|
|
186
|
-
const nextStep = trace.steps[stepIndex + 1];
|
|
187
|
-
|
|
188
|
-
if (isEvmStep(step)) {
|
|
189
|
-
const inst = trace.bytecode.getInstruction(step.pc);
|
|
190
|
-
|
|
191
|
-
if (
|
|
192
|
-
inst.jumpType === JumpType.INTO_FUNCTION &&
|
|
193
|
-
nextStep !== undefined
|
|
194
|
-
) {
|
|
195
|
-
const nextEvmStep = nextStep as EvmStep; // A jump can't be followed by a subtrace
|
|
196
|
-
const nextInst = trace.bytecode.getInstruction(nextEvmStep.pc);
|
|
197
|
-
|
|
198
|
-
if (nextInst !== undefined && nextInst.opcode === Opcode.JUMPDEST) {
|
|
199
|
-
stacktrace.push(
|
|
200
|
-
instructionToCallstackStackTraceEntry(trace.bytecode, inst)
|
|
201
|
-
);
|
|
202
|
-
if (nextInst.location !== undefined) {
|
|
203
|
-
jumpedIntoFunction = true;
|
|
204
|
-
}
|
|
205
|
-
functionJumpdests.push(nextInst);
|
|
206
|
-
}
|
|
207
|
-
} else if (inst.jumpType === JumpType.OUTOF_FUNCTION) {
|
|
208
|
-
stacktrace.pop();
|
|
209
|
-
functionJumpdests.pop();
|
|
210
|
-
}
|
|
211
|
-
} else {
|
|
212
|
-
subtracesSeen += 1;
|
|
213
|
-
|
|
214
|
-
// If there are more subtraces, this one didn't terminate the execution
|
|
215
|
-
if (subtracesSeen < trace.numberOfSubtraces) {
|
|
216
|
-
continue;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
const submessageTrace = this.getStackTrace(step);
|
|
220
|
-
|
|
221
|
-
lastSubmessageData = {
|
|
222
|
-
messageTrace: step,
|
|
223
|
-
stepIndex,
|
|
224
|
-
stacktrace: submessageTrace,
|
|
225
|
-
};
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
const stacktraceWithInferredError = this._errorInferrer.inferAfterTracing(
|
|
230
|
-
trace,
|
|
231
|
-
stacktrace,
|
|
232
|
-
functionJumpdests,
|
|
233
|
-
jumpedIntoFunction,
|
|
234
|
-
lastSubmessageData
|
|
235
|
-
);
|
|
236
|
-
|
|
237
|
-
return this._errorInferrer.filterRedundantFrames(
|
|
238
|
-
stacktraceWithInferredError
|
|
239
|
-
);
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
private _getLastSubtrace(trace: EvmMessageTrace): MessageTrace | undefined {
|
|
243
|
-
if (trace.numberOfSubtraces < 1) {
|
|
244
|
-
return undefined;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
let i = trace.steps.length - 1;
|
|
248
|
-
|
|
249
|
-
while (isEvmStep(trace.steps[i])) {
|
|
250
|
-
i -= 1;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
return trace.steps[i] as MessageTrace;
|
|
254
|
-
}
|
|
255
|
-
}
|
|
7
|
+
export { SolidityTracer };
|
|
@@ -1,121 +1,22 @@
|
|
|
1
|
+
import type { VmTraceDecoder as VmTraceDecoderT } from "@nomicfoundation/edr";
|
|
1
2
|
import chalk from "chalk";
|
|
2
3
|
import debug from "debug";
|
|
3
4
|
import { Reporter } from "../../sentry/reporter";
|
|
4
5
|
import { TracingConfig } from "../provider/node-types";
|
|
5
|
-
import {
|
|
6
|
-
import { ContractsIdentifier } from "./contracts-identifier";
|
|
7
|
-
import {
|
|
8
|
-
isCreateTrace,
|
|
9
|
-
isEvmStep,
|
|
10
|
-
isPrecompileTrace,
|
|
11
|
-
MessageTrace,
|
|
12
|
-
} from "./message-trace";
|
|
13
|
-
import { Bytecode, ContractFunctionType } from "./model";
|
|
14
|
-
import {
|
|
15
|
-
FALLBACK_FUNCTION_NAME,
|
|
16
|
-
RECEIVE_FUNCTION_NAME,
|
|
17
|
-
UNRECOGNIZED_CONTRACT_NAME,
|
|
18
|
-
UNRECOGNIZED_FUNCTION_NAME,
|
|
19
|
-
} from "./solidity-stack-trace";
|
|
6
|
+
import { requireNapiRsModule } from "../../../common/napi-rs";
|
|
20
7
|
|
|
21
8
|
const log = debug("hardhat:core:hardhat-network:node");
|
|
22
9
|
|
|
23
|
-
|
|
24
|
-
|
|
10
|
+
const { VmTraceDecoder, initializeVmTraceDecoder } = requireNapiRsModule(
|
|
11
|
+
"@nomicfoundation/edr"
|
|
12
|
+
) as typeof import("@nomicfoundation/edr");
|
|
25
13
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
calldata?: Buffer
|
|
29
|
-
): { contractName: string; functionName?: string } {
|
|
30
|
-
const isCreate = calldata === undefined;
|
|
31
|
-
const bytecode = this._contractsIdentifier.getBytecodeForCall(
|
|
32
|
-
code,
|
|
33
|
-
isCreate
|
|
34
|
-
);
|
|
35
|
-
|
|
36
|
-
const contractName = bytecode?.contract.name ?? UNRECOGNIZED_CONTRACT_NAME;
|
|
37
|
-
|
|
38
|
-
if (isCreate) {
|
|
39
|
-
return {
|
|
40
|
-
contractName,
|
|
41
|
-
};
|
|
42
|
-
} else {
|
|
43
|
-
if (bytecode === undefined) {
|
|
44
|
-
return {
|
|
45
|
-
contractName,
|
|
46
|
-
functionName: "",
|
|
47
|
-
};
|
|
48
|
-
} else {
|
|
49
|
-
const func = bytecode.contract.getFunctionFromSelector(
|
|
50
|
-
calldata.slice(0, 4)
|
|
51
|
-
);
|
|
52
|
-
|
|
53
|
-
const functionName: string =
|
|
54
|
-
func === undefined
|
|
55
|
-
? UNRECOGNIZED_FUNCTION_NAME
|
|
56
|
-
: func.type === ContractFunctionType.FALLBACK
|
|
57
|
-
? FALLBACK_FUNCTION_NAME
|
|
58
|
-
: func.type === ContractFunctionType.RECEIVE
|
|
59
|
-
? RECEIVE_FUNCTION_NAME
|
|
60
|
-
: func.name;
|
|
61
|
-
|
|
62
|
-
return {
|
|
63
|
-
contractName,
|
|
64
|
-
functionName,
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
public tryToDecodeMessageTrace(messageTrace: MessageTrace): MessageTrace {
|
|
71
|
-
if (isPrecompileTrace(messageTrace)) {
|
|
72
|
-
return messageTrace;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return {
|
|
76
|
-
...messageTrace,
|
|
77
|
-
bytecode: this._contractsIdentifier.getBytecodeForCall(
|
|
78
|
-
messageTrace.code,
|
|
79
|
-
isCreateTrace(messageTrace)
|
|
80
|
-
),
|
|
81
|
-
steps: messageTrace.steps.map((s) =>
|
|
82
|
-
isEvmStep(s) ? s : this.tryToDecodeMessageTrace(s)
|
|
83
|
-
),
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
public addBytecode(bytecode: Bytecode) {
|
|
88
|
-
this._contractsIdentifier.addBytecode(bytecode);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export function initializeVmTraceDecoder(
|
|
93
|
-
vmTraceDecoder: VmTraceDecoder,
|
|
14
|
+
function initializeVmTraceDecoderWrapper(
|
|
15
|
+
vmTraceDecoder: VmTraceDecoderT,
|
|
94
16
|
tracingConfig: TracingConfig
|
|
95
17
|
) {
|
|
96
|
-
if (tracingConfig.buildInfos === undefined) {
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
18
|
try {
|
|
101
|
-
|
|
102
|
-
const bytecodes = createModelsAndDecodeBytecodes(
|
|
103
|
-
buildInfo.solcVersion,
|
|
104
|
-
buildInfo.input,
|
|
105
|
-
buildInfo.output
|
|
106
|
-
);
|
|
107
|
-
|
|
108
|
-
for (const bytecode of bytecodes) {
|
|
109
|
-
if (
|
|
110
|
-
tracingConfig.ignoreContracts === true &&
|
|
111
|
-
bytecode.contract.name.startsWith("Ignored")
|
|
112
|
-
) {
|
|
113
|
-
continue;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
vmTraceDecoder.addBytecode(bytecode);
|
|
117
|
-
}
|
|
118
|
-
}
|
|
19
|
+
initializeVmTraceDecoder(vmTraceDecoder, tracingConfig);
|
|
119
20
|
} catch (error) {
|
|
120
21
|
console.warn(
|
|
121
22
|
chalk.yellow(
|
|
@@ -124,7 +25,7 @@ export function initializeVmTraceDecoder(
|
|
|
124
25
|
);
|
|
125
26
|
|
|
126
27
|
log(
|
|
127
|
-
"Hardhat Network tracing disabled:
|
|
28
|
+
"Hardhat Network tracing disabled: VmTraceDecoder failed to be initialized. Please report this to help us improve Hardhat.\n",
|
|
128
29
|
error
|
|
129
30
|
);
|
|
130
31
|
|
|
@@ -133,3 +34,9 @@ export function initializeVmTraceDecoder(
|
|
|
133
34
|
}
|
|
134
35
|
}
|
|
135
36
|
}
|
|
37
|
+
|
|
38
|
+
export {
|
|
39
|
+
VmTraceDecoder,
|
|
40
|
+
VmTraceDecoderT,
|
|
41
|
+
initializeVmTraceDecoderWrapper as initializeVmTraceDecoder,
|
|
42
|
+
};
|
|
@@ -1,208 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
CreateOutput,
|
|
3
|
-
ExecutionResult,
|
|
4
|
-
TracingMessage,
|
|
5
|
-
TracingStep,
|
|
6
|
-
} from "@nomicfoundation/edr";
|
|
1
|
+
import { requireNapiRsModule } from "../../../common/napi-rs";
|
|
7
2
|
|
|
8
|
-
|
|
3
|
+
const { VmTracer } = requireNapiRsModule(
|
|
4
|
+
"@nomicfoundation/edr"
|
|
5
|
+
) as typeof import("@nomicfoundation/edr");
|
|
9
6
|
|
|
10
|
-
|
|
11
|
-
import { Exit, ExitCode } from "../provider/vm/exit";
|
|
12
|
-
|
|
13
|
-
import {
|
|
14
|
-
CallMessageTrace,
|
|
15
|
-
CreateMessageTrace,
|
|
16
|
-
isCreateTrace,
|
|
17
|
-
isHaltResult,
|
|
18
|
-
isPrecompileTrace,
|
|
19
|
-
isSuccessResult,
|
|
20
|
-
MessageTrace,
|
|
21
|
-
PrecompileMessageTrace,
|
|
22
|
-
} from "./message-trace";
|
|
23
|
-
|
|
24
|
-
/* eslint-disable @nomicfoundation/hardhat-internal-rules/only-hardhat-error */
|
|
25
|
-
|
|
26
|
-
const DUMMY_RETURN_DATA = Buffer.from([]);
|
|
27
|
-
const DUMMY_GAS_USED = 0n;
|
|
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
|
-
*/
|
|
33
|
-
export class VMTracer {
|
|
34
|
-
public tracingSteps: TracingStep[] = [];
|
|
35
|
-
|
|
36
|
-
private _messageTraces: MessageTrace[] = [];
|
|
37
|
-
private _lastError: Error | undefined;
|
|
38
|
-
private _maxPrecompileNumber;
|
|
39
|
-
|
|
40
|
-
constructor() {
|
|
41
|
-
// TODO: temporarily hardcoded to remove the need of using ethereumjs' common and evm here
|
|
42
|
-
this._maxPrecompileNumber = 10;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
public getLastTopLevelMessageTrace(): MessageTrace | undefined {
|
|
46
|
-
return this._messageTraces[0];
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
public getLastError(): Error | undefined {
|
|
50
|
-
return this._lastError;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
private _shouldKeepTracing() {
|
|
54
|
-
return this._lastError === undefined;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
public addBeforeMessage(message: TracingMessage) {
|
|
58
|
-
if (!this._shouldKeepTracing()) {
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
try {
|
|
63
|
-
let trace: MessageTrace;
|
|
64
|
-
|
|
65
|
-
if (message.depth === 0) {
|
|
66
|
-
this._messageTraces = [];
|
|
67
|
-
this.tracingSteps = [];
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if (message.to === undefined) {
|
|
71
|
-
const createTrace: CreateMessageTrace = {
|
|
72
|
-
code: message.data,
|
|
73
|
-
steps: [],
|
|
74
|
-
value: message.value,
|
|
75
|
-
exit: new Exit(ExitCode.SUCCESS),
|
|
76
|
-
returnData: DUMMY_RETURN_DATA,
|
|
77
|
-
numberOfSubtraces: 0,
|
|
78
|
-
depth: message.depth,
|
|
79
|
-
deployedContract: undefined,
|
|
80
|
-
gasUsed: DUMMY_GAS_USED,
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
trace = createTrace;
|
|
84
|
-
} else {
|
|
85
|
-
const toAsBigInt = bytesToBigInt(message.to);
|
|
86
|
-
|
|
87
|
-
if (toAsBigInt > 0 && toAsBigInt <= this._maxPrecompileNumber) {
|
|
88
|
-
const precompileTrace: PrecompileMessageTrace = {
|
|
89
|
-
precompile: Number(toAsBigInt),
|
|
90
|
-
calldata: message.data,
|
|
91
|
-
value: message.value,
|
|
92
|
-
exit: new Exit(ExitCode.SUCCESS),
|
|
93
|
-
returnData: DUMMY_RETURN_DATA,
|
|
94
|
-
depth: message.depth,
|
|
95
|
-
gasUsed: DUMMY_GAS_USED,
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
trace = precompileTrace;
|
|
99
|
-
} else {
|
|
100
|
-
const codeAddress = message.codeAddress;
|
|
101
|
-
|
|
102
|
-
// if we enter here, then `to` is not undefined, therefore
|
|
103
|
-
// `codeAddress` and `code` should be defined
|
|
104
|
-
assertHardhatInvariant(
|
|
105
|
-
codeAddress !== undefined,
|
|
106
|
-
"codeAddress should be defined"
|
|
107
|
-
);
|
|
108
|
-
assertHardhatInvariant(
|
|
109
|
-
message.code !== undefined,
|
|
110
|
-
"code should be defined"
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
const callTrace: CallMessageTrace = {
|
|
114
|
-
code: message.code,
|
|
115
|
-
calldata: message.data,
|
|
116
|
-
steps: [],
|
|
117
|
-
value: message.value,
|
|
118
|
-
exit: new Exit(ExitCode.SUCCESS),
|
|
119
|
-
returnData: DUMMY_RETURN_DATA,
|
|
120
|
-
address: message.to,
|
|
121
|
-
numberOfSubtraces: 0,
|
|
122
|
-
depth: message.depth,
|
|
123
|
-
gasUsed: DUMMY_GAS_USED,
|
|
124
|
-
codeAddress,
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
trace = callTrace;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
if (this._messageTraces.length > 0) {
|
|
132
|
-
const parentTrace = this._messageTraces[this._messageTraces.length - 1];
|
|
133
|
-
|
|
134
|
-
if (isPrecompileTrace(parentTrace)) {
|
|
135
|
-
throw new Error(
|
|
136
|
-
"This should not happen: message execution started while a precompile was executing"
|
|
137
|
-
);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
parentTrace.steps.push(trace);
|
|
141
|
-
parentTrace.numberOfSubtraces += 1;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
this._messageTraces.push(trace);
|
|
145
|
-
} catch (error) {
|
|
146
|
-
this._lastError = error as Error;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
public addStep(step: TracingStep) {
|
|
151
|
-
if (!this._shouldKeepTracing()) {
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
this.tracingSteps.push(step);
|
|
156
|
-
|
|
157
|
-
try {
|
|
158
|
-
const trace = this._messageTraces[this._messageTraces.length - 1];
|
|
159
|
-
|
|
160
|
-
if (isPrecompileTrace(trace)) {
|
|
161
|
-
throw new Error(
|
|
162
|
-
"This should not happen: step event fired while a precompile was executing"
|
|
163
|
-
);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
trace.steps.push({ pc: Number(step.pc) });
|
|
167
|
-
} catch (error) {
|
|
168
|
-
this._lastError = error as Error;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
public addAfterMessage(result: ExecutionResult) {
|
|
173
|
-
if (!this._shouldKeepTracing()) {
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
try {
|
|
178
|
-
const trace = this._messageTraces[this._messageTraces.length - 1];
|
|
179
|
-
trace.gasUsed = result.result.gasUsed;
|
|
180
|
-
|
|
181
|
-
const executionResult = result.result;
|
|
182
|
-
if (isSuccessResult(executionResult)) {
|
|
183
|
-
trace.exit = Exit.fromEdrSuccessReason(executionResult.reason);
|
|
184
|
-
trace.returnData = executionResult.output.returnValue;
|
|
185
|
-
|
|
186
|
-
if (isCreateTrace(trace)) {
|
|
187
|
-
trace.deployedContract = (
|
|
188
|
-
executionResult.output as CreateOutput
|
|
189
|
-
).address;
|
|
190
|
-
}
|
|
191
|
-
} else if (isHaltResult(executionResult)) {
|
|
192
|
-
trace.exit = Exit.fromEdrExceptionalHalt(executionResult.reason);
|
|
193
|
-
|
|
194
|
-
trace.returnData = Buffer.from([]);
|
|
195
|
-
} else {
|
|
196
|
-
trace.exit = new Exit(ExitCode.REVERT);
|
|
197
|
-
|
|
198
|
-
trace.returnData = executionResult.output;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
if (this._messageTraces.length > 1) {
|
|
202
|
-
this._messageTraces.pop();
|
|
203
|
-
}
|
|
204
|
-
} catch (error) {
|
|
205
|
-
this._lastError = error as Error;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
}
|
|
7
|
+
export { VmTracer as VMTracer };
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { Bytecode } from "./model";
|
|
2
|
-
export declare class ContractsIdentifier {
|
|
3
|
-
private readonly _enableCache;
|
|
4
|
-
private _trie;
|
|
5
|
-
private _cache;
|
|
6
|
-
constructor(_enableCache?: boolean);
|
|
7
|
-
addBytecode(bytecode: Bytecode): void;
|
|
8
|
-
getBytecodeForCall(code: Uint8Array, isCreate: boolean): Bytecode | undefined;
|
|
9
|
-
private _searchBytecode;
|
|
10
|
-
/**
|
|
11
|
-
* Returns true if the lastByte is placed right when the metadata starts or after it.
|
|
12
|
-
*/
|
|
13
|
-
private _isMatchingMetadata;
|
|
14
|
-
}
|
|
15
|
-
//# sourceMappingURL=contracts-identifier.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"contracts-identifier.d.ts","sourceRoot":"","sources":["../../../src/internal/hardhat-network/stack-traces/contracts-identifier.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAmFnC,qBAAa,mBAAmB;IAIlB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAHzC,OAAO,CAAC,KAAK,CAAwB;IACrC,OAAO,CAAC,MAAM,CAAoC;gBAErB,YAAY,UAAO;IAEzC,WAAW,CAAC,QAAQ,EAAE,QAAQ;IAK9B,kBAAkB,CACvB,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,OAAO,GAChB,QAAQ,GAAG,SAAS;IAwBvB,OAAO,CAAC,eAAe;IAyFvB;;OAEG;IACH,OAAO,CAAC,mBAAmB;CAc5B"}
|