hardhat 2.17.3 → 2.18.0
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/README.md +1 -1
- package/builtin-tasks/help.js +36 -5
- package/builtin-tasks/help.js.map +1 -1
- package/internal/cli/ArgumentsParser.d.ts +7 -2
- package/internal/cli/ArgumentsParser.d.ts.map +1 -1
- package/internal/cli/ArgumentsParser.js +72 -11
- package/internal/cli/ArgumentsParser.js.map +1 -1
- package/internal/cli/HelpPrinter.d.ts +7 -3
- package/internal/cli/HelpPrinter.d.ts.map +1 -1
- package/internal/cli/HelpPrinter.js +53 -22
- package/internal/cli/HelpPrinter.js.map +1 -1
- package/internal/cli/cli.js +69 -27
- package/internal/cli/cli.js.map +1 -1
- package/internal/core/config/config-env.d.ts +2 -1
- package/internal/core/config/config-env.d.ts.map +1 -1
- package/internal/core/config/config-env.js +7 -1
- package/internal/core/config/config-env.js.map +1 -1
- package/internal/core/errors-list.d.ts +42 -0
- package/internal/core/errors-list.d.ts.map +1 -1
- package/internal/core/errors-list.js +52 -2
- package/internal/core/errors-list.js.map +1 -1
- package/internal/core/jsonrpc/types/input/blockTag.d.ts +3 -3
- package/internal/core/jsonrpc/types/input/filterRequest.d.ts +6 -6
- package/internal/core/runtime-environment.d.ts +5 -3
- package/internal/core/runtime-environment.d.ts.map +1 -1
- package/internal/core/runtime-environment.js +30 -7
- package/internal/core/runtime-environment.js.map +1 -1
- package/internal/core/tasks/dsl.d.ts +10 -1
- package/internal/core/tasks/dsl.d.ts.map +1 -1
- package/internal/core/tasks/dsl.js +64 -4
- package/internal/core/tasks/dsl.js.map +1 -1
- package/internal/core/tasks/task-definitions.d.ts +31 -4
- package/internal/core/tasks/task-definitions.d.ts.map +1 -1
- package/internal/core/tasks/task-definitions.js +51 -5
- package/internal/core/tasks/task-definitions.js.map +1 -1
- package/internal/core/tasks/util.d.ts +6 -0
- package/internal/core/tasks/util.d.ts.map +1 -0
- package/internal/core/tasks/util.js +19 -0
- package/internal/core/tasks/util.js.map +1 -0
- package/internal/hardhat-network/provider/modules/base.d.ts +17 -0
- package/internal/hardhat-network/provider/modules/base.d.ts.map +1 -0
- package/internal/hardhat-network/provider/modules/base.js +127 -0
- package/internal/hardhat-network/provider/modules/base.js.map +1 -0
- package/internal/hardhat-network/provider/modules/debug.d.ts +5 -3
- package/internal/hardhat-network/provider/modules/debug.d.ts.map +1 -1
- package/internal/hardhat-network/provider/modules/debug.js +21 -5
- package/internal/hardhat-network/provider/modules/debug.js.map +1 -1
- package/internal/hardhat-network/provider/modules/eth.d.ts +2 -7
- package/internal/hardhat-network/provider/modules/eth.d.ts.map +1 -1
- package/internal/hardhat-network/provider/modules/eth.js +12 -60
- package/internal/hardhat-network/provider/modules/eth.js.map +1 -1
- package/internal/hardhat-network/provider/node.d.ts +1 -0
- package/internal/hardhat-network/provider/node.d.ts.map +1 -1
- package/internal/hardhat-network/provider/node.js +6 -0
- package/internal/hardhat-network/provider/node.js.map +1 -1
- package/internal/lib/hardhat-lib.d.ts.map +1 -1
- package/internal/lib/hardhat-lib.js +1 -1
- package/internal/lib/hardhat-lib.js.map +1 -1
- package/internal/sentry/anonymizer.d.ts.map +1 -1
- package/internal/sentry/anonymizer.js +3 -1
- package/internal/sentry/anonymizer.js.map +1 -1
- package/package.json +1 -1
- package/register.js +1 -1
- package/register.js.map +1 -1
- package/src/builtin-tasks/help.ts +47 -5
- package/src/internal/cli/ArgumentsParser.ts +79 -13
- package/src/internal/cli/HelpPrinter.ts +89 -24
- package/src/internal/cli/cli.ts +106 -38
- package/src/internal/core/config/config-env.ts +11 -0
- package/src/internal/core/errors-list.ts +56 -2
- package/src/internal/core/runtime-environment.ts +32 -7
- package/src/internal/core/tasks/dsl.ts +99 -4
- package/src/internal/core/tasks/task-definitions.ts +97 -3
- package/src/internal/core/tasks/util.ts +18 -0
- package/src/internal/hardhat-network/provider/modules/base.ts +156 -0
- package/src/internal/hardhat-network/provider/modules/debug.ts +50 -9
- package/src/internal/hardhat-network/provider/modules/eth.ts +16 -91
- package/src/internal/hardhat-network/provider/node.ts +12 -0
- package/src/internal/lib/hardhat-lib.ts +1 -0
- package/src/internal/sentry/anonymizer.ts +3 -1
- package/src/register.ts +1 -0
- package/src/types/runtime.ts +35 -1
- package/types/runtime.d.ts +24 -1
- package/types/runtime.d.ts.map +1 -1
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ActionType,
|
|
3
|
+
ScopeDefinition,
|
|
4
|
+
ScopesMap,
|
|
3
5
|
TaskArguments,
|
|
4
6
|
TaskDefinition,
|
|
7
|
+
TaskIdentifier,
|
|
5
8
|
TasksMap,
|
|
6
9
|
} from "../../../types";
|
|
10
|
+
import { HardhatError, assertHardhatInvariant } from "../errors";
|
|
11
|
+
import { ERRORS } from "../errors-list";
|
|
7
12
|
|
|
8
13
|
import {
|
|
9
14
|
OverriddenTaskDefinition,
|
|
15
|
+
SimpleScopeDefinition,
|
|
10
16
|
SimpleTaskDefinition,
|
|
11
17
|
} from "./task-definitions";
|
|
18
|
+
import { parseTaskIdentifier } from "./util";
|
|
12
19
|
|
|
13
20
|
/**
|
|
14
21
|
* This class defines the DSL used in Hardhat config files
|
|
@@ -18,6 +25,7 @@ export class TasksDSL {
|
|
|
18
25
|
public readonly internalTask = this.subtask;
|
|
19
26
|
|
|
20
27
|
private readonly _tasks: TasksMap = {};
|
|
28
|
+
private readonly _scopes: ScopesMap = {};
|
|
21
29
|
|
|
22
30
|
/**
|
|
23
31
|
* Creates a task, overriding any previous task with the same name.
|
|
@@ -56,6 +64,8 @@ export class TasksDSL {
|
|
|
56
64
|
descriptionOrAction?: string | ActionType<TaskArgumentsT>,
|
|
57
65
|
action?: ActionType<TaskArgumentsT>
|
|
58
66
|
): TaskDefinition {
|
|
67
|
+
// if this function is updated, update the corresponding callback
|
|
68
|
+
// passed to `new SimpleScopeDefinition`
|
|
59
69
|
return this._addTask(name, descriptionOrAction, action, false);
|
|
60
70
|
}
|
|
61
71
|
|
|
@@ -96,9 +106,56 @@ export class TasksDSL {
|
|
|
96
106
|
descriptionOrAction?: string | ActionType<TaskArgumentsT>,
|
|
97
107
|
action?: ActionType<TaskArgumentsT>
|
|
98
108
|
): TaskDefinition {
|
|
109
|
+
// if this function is updated, update the corresponding callback
|
|
110
|
+
// passed to `new SimpleScopeDefinition`
|
|
99
111
|
return this._addTask(name, descriptionOrAction, action, true);
|
|
100
112
|
}
|
|
101
113
|
|
|
114
|
+
public scope(name: string, description?: string): ScopeDefinition {
|
|
115
|
+
if (this._tasks[name] !== undefined) {
|
|
116
|
+
throw new HardhatError(ERRORS.TASK_DEFINITIONS.TASK_SCOPE_CLASH, {
|
|
117
|
+
scopeName: name,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const scopeDefinition = this._scopes[name];
|
|
122
|
+
|
|
123
|
+
if (scopeDefinition !== undefined) {
|
|
124
|
+
// if the scope already exists, the only thing we might
|
|
125
|
+
// do is to update its description
|
|
126
|
+
if (description !== undefined) {
|
|
127
|
+
scopeDefinition.setDescription(description);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return scopeDefinition;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const scope = new SimpleScopeDefinition(
|
|
134
|
+
name,
|
|
135
|
+
description,
|
|
136
|
+
(taskName, descriptionOrAction, action) =>
|
|
137
|
+
// if this function is updated, update the dsl.task function too
|
|
138
|
+
this._addTask(
|
|
139
|
+
{ scope: name, task: taskName },
|
|
140
|
+
descriptionOrAction,
|
|
141
|
+
action,
|
|
142
|
+
false
|
|
143
|
+
),
|
|
144
|
+
(subtaskName, descriptionOrAction, action) =>
|
|
145
|
+
// if this function is updated, update the dsl.subtask function too
|
|
146
|
+
this._addTask(
|
|
147
|
+
{ scope: name, task: subtaskName },
|
|
148
|
+
descriptionOrAction,
|
|
149
|
+
action,
|
|
150
|
+
true
|
|
151
|
+
)
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
this._scopes[name] = scope;
|
|
155
|
+
|
|
156
|
+
return scope;
|
|
157
|
+
}
|
|
158
|
+
|
|
102
159
|
/**
|
|
103
160
|
* Retrieves the task definitions.
|
|
104
161
|
*
|
|
@@ -108,13 +165,41 @@ export class TasksDSL {
|
|
|
108
165
|
return this._tasks;
|
|
109
166
|
}
|
|
110
167
|
|
|
168
|
+
/**
|
|
169
|
+
* Retrieves the scoped task definitions.
|
|
170
|
+
*
|
|
171
|
+
* @returns The scoped tasks container.
|
|
172
|
+
*/
|
|
173
|
+
public getScopesDefinitions(): ScopesMap {
|
|
174
|
+
return this._scopes;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
public getTaskDefinition(
|
|
178
|
+
scope: string | undefined,
|
|
179
|
+
name: string
|
|
180
|
+
): TaskDefinition | undefined {
|
|
181
|
+
if (scope === undefined) {
|
|
182
|
+
return this._tasks[name];
|
|
183
|
+
} else {
|
|
184
|
+
return this._scopes[scope]?.tasks?.[name];
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
111
188
|
private _addTask<TaskArgumentsT extends TaskArguments>(
|
|
112
|
-
|
|
189
|
+
taskIdentifier: TaskIdentifier,
|
|
113
190
|
descriptionOrAction?: string | ActionType<TaskArgumentsT>,
|
|
114
191
|
action?: ActionType<TaskArgumentsT>,
|
|
115
192
|
isSubtask?: boolean
|
|
116
193
|
) {
|
|
117
|
-
const
|
|
194
|
+
const { scope, task } = parseTaskIdentifier(taskIdentifier);
|
|
195
|
+
|
|
196
|
+
if (scope === undefined && this._scopes[task] !== undefined) {
|
|
197
|
+
throw new HardhatError(ERRORS.TASK_DEFINITIONS.SCOPE_TASK_CLASH, {
|
|
198
|
+
taskName: task,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const parentTaskDefinition = this.getTaskDefinition(scope, task);
|
|
118
203
|
|
|
119
204
|
let taskDefinition: TaskDefinition;
|
|
120
205
|
|
|
@@ -124,7 +209,7 @@ export class TasksDSL {
|
|
|
124
209
|
isSubtask
|
|
125
210
|
);
|
|
126
211
|
} else {
|
|
127
|
-
taskDefinition = new SimpleTaskDefinition(
|
|
212
|
+
taskDefinition = new SimpleTaskDefinition(taskIdentifier, isSubtask);
|
|
128
213
|
}
|
|
129
214
|
|
|
130
215
|
if (descriptionOrAction instanceof Function) {
|
|
@@ -140,7 +225,17 @@ export class TasksDSL {
|
|
|
140
225
|
taskDefinition.setAction(action);
|
|
141
226
|
}
|
|
142
227
|
|
|
143
|
-
|
|
228
|
+
if (scope === undefined) {
|
|
229
|
+
this._tasks[task] = taskDefinition;
|
|
230
|
+
} else {
|
|
231
|
+
const scopeDefinition = this._scopes[scope];
|
|
232
|
+
assertHardhatInvariant(
|
|
233
|
+
scopeDefinition !== undefined,
|
|
234
|
+
"It shouldn't be possible to create a task in a scope that doesn't exist"
|
|
235
|
+
);
|
|
236
|
+
scopeDefinition.tasks[task] = taskDefinition;
|
|
237
|
+
}
|
|
238
|
+
|
|
144
239
|
return taskDefinition;
|
|
145
240
|
}
|
|
146
241
|
}
|
|
@@ -4,13 +4,17 @@ import {
|
|
|
4
4
|
CLIArgumentType,
|
|
5
5
|
ParamDefinition,
|
|
6
6
|
ParamDefinitionsMap,
|
|
7
|
+
ScopeDefinition,
|
|
7
8
|
TaskArguments,
|
|
8
9
|
TaskDefinition,
|
|
10
|
+
TaskIdentifier,
|
|
11
|
+
TasksMap,
|
|
9
12
|
} from "../../../types";
|
|
10
13
|
import { HardhatError } from "../errors";
|
|
11
14
|
import { ErrorDescriptor, ERRORS } from "../errors-list";
|
|
12
15
|
import * as types from "../params/argumentTypes";
|
|
13
16
|
import { HARDHAT_PARAM_DEFINITIONS } from "../params/hardhat-params";
|
|
17
|
+
import { parseTaskIdentifier } from "./util";
|
|
14
18
|
|
|
15
19
|
function isCLIArgumentType(
|
|
16
20
|
type: ArgumentType<any>
|
|
@@ -26,6 +30,12 @@ function isCLIArgumentType(
|
|
|
26
30
|
*
|
|
27
31
|
*/
|
|
28
32
|
export class SimpleTaskDefinition implements TaskDefinition {
|
|
33
|
+
public get name() {
|
|
34
|
+
return this._task;
|
|
35
|
+
}
|
|
36
|
+
public get scope() {
|
|
37
|
+
return this._scope;
|
|
38
|
+
}
|
|
29
39
|
public get description() {
|
|
30
40
|
return this._description;
|
|
31
41
|
}
|
|
@@ -36,6 +46,8 @@ export class SimpleTaskDefinition implements TaskDefinition {
|
|
|
36
46
|
private _positionalParamNames: Set<string>;
|
|
37
47
|
private _hasVariadicParam: boolean;
|
|
38
48
|
private _hasOptionalPositionalParam: boolean;
|
|
49
|
+
private _scope?: string;
|
|
50
|
+
private _task: string;
|
|
39
51
|
private _description?: string;
|
|
40
52
|
|
|
41
53
|
/**
|
|
@@ -43,19 +55,22 @@ export class SimpleTaskDefinition implements TaskDefinition {
|
|
|
43
55
|
*
|
|
44
56
|
* This definition will have no params, and will throw a HH205 if executed.
|
|
45
57
|
*
|
|
46
|
-
* @param
|
|
58
|
+
* @param taskIdentifier The task's identifier.
|
|
47
59
|
* @param isSubtask `true` if the task is a subtask, `false` otherwise.
|
|
48
60
|
*/
|
|
49
61
|
constructor(
|
|
50
|
-
|
|
62
|
+
taskIdentifier: TaskIdentifier,
|
|
51
63
|
public readonly isSubtask: boolean = false
|
|
52
64
|
) {
|
|
53
65
|
this._positionalParamNames = new Set();
|
|
54
66
|
this._hasVariadicParam = false;
|
|
55
67
|
this._hasOptionalPositionalParam = false;
|
|
68
|
+
const { scope, task } = parseTaskIdentifier(taskIdentifier);
|
|
69
|
+
this._scope = scope;
|
|
70
|
+
this._task = task;
|
|
56
71
|
this.action = () => {
|
|
57
72
|
throw new HardhatError(ERRORS.TASK_DEFINITIONS.ACTION_NOT_SET, {
|
|
58
|
-
taskName:
|
|
73
|
+
taskName: this._task,
|
|
59
74
|
});
|
|
60
75
|
};
|
|
61
76
|
}
|
|
@@ -562,6 +577,10 @@ export class OverriddenTaskDefinition implements TaskDefinition {
|
|
|
562
577
|
this.parentTaskDefinition = parentTaskDefinition;
|
|
563
578
|
}
|
|
564
579
|
|
|
580
|
+
/**
|
|
581
|
+
* Sets the task's description.
|
|
582
|
+
* @param description The description.
|
|
583
|
+
*/
|
|
565
584
|
public setDescription(description: string) {
|
|
566
585
|
this._description = description;
|
|
567
586
|
return this;
|
|
@@ -579,6 +598,13 @@ export class OverriddenTaskDefinition implements TaskDefinition {
|
|
|
579
598
|
return this;
|
|
580
599
|
}
|
|
581
600
|
|
|
601
|
+
/**
|
|
602
|
+
* Retrieves the parent task's scope.
|
|
603
|
+
*/
|
|
604
|
+
public get scope() {
|
|
605
|
+
return this.parentTaskDefinition.scope;
|
|
606
|
+
}
|
|
607
|
+
|
|
582
608
|
/**
|
|
583
609
|
* Retrieves the parent task's name.
|
|
584
610
|
*/
|
|
@@ -734,3 +760,71 @@ export class OverriddenTaskDefinition implements TaskDefinition {
|
|
|
734
760
|
});
|
|
735
761
|
}
|
|
736
762
|
}
|
|
763
|
+
|
|
764
|
+
type AddTaskFunction = <TaskArgumentsT extends TaskArguments>(
|
|
765
|
+
name: string,
|
|
766
|
+
descriptionOrAction?: string | ActionType<TaskArgumentsT>,
|
|
767
|
+
action?: ActionType<TaskArgumentsT>
|
|
768
|
+
) => TaskDefinition;
|
|
769
|
+
|
|
770
|
+
export class SimpleScopeDefinition implements ScopeDefinition {
|
|
771
|
+
public tasks: TasksMap = {};
|
|
772
|
+
|
|
773
|
+
constructor(
|
|
774
|
+
public readonly name: string,
|
|
775
|
+
private _description: string | undefined,
|
|
776
|
+
private _addTask: AddTaskFunction,
|
|
777
|
+
private _addSubtask: AddTaskFunction
|
|
778
|
+
) {}
|
|
779
|
+
|
|
780
|
+
public get description() {
|
|
781
|
+
return this._description;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
public setDescription(description: string): this {
|
|
785
|
+
this._description = description;
|
|
786
|
+
return this;
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
public task<TaskArgumentsT extends TaskArguments>(
|
|
790
|
+
name: string,
|
|
791
|
+
description?: string,
|
|
792
|
+
action?: ActionType<TaskArgumentsT>
|
|
793
|
+
): TaskDefinition;
|
|
794
|
+
public task<TaskArgumentsT extends TaskArguments>(
|
|
795
|
+
name: string,
|
|
796
|
+
action: ActionType<TaskArgumentsT>
|
|
797
|
+
): TaskDefinition;
|
|
798
|
+
public task<TaskArgumentsT extends TaskArguments>(
|
|
799
|
+
name: string,
|
|
800
|
+
descriptionOrAction?: string | ActionType<TaskArgumentsT>,
|
|
801
|
+
action?: ActionType<TaskArgumentsT>
|
|
802
|
+
) {
|
|
803
|
+
const task = this._addTask(name, descriptionOrAction, action);
|
|
804
|
+
|
|
805
|
+
this.tasks[name] = task;
|
|
806
|
+
|
|
807
|
+
return task;
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
public subtask<TaskArgumentsT extends TaskArguments>(
|
|
811
|
+
name: string,
|
|
812
|
+
description?: string,
|
|
813
|
+
action?: ActionType<TaskArgumentsT>
|
|
814
|
+
): TaskDefinition;
|
|
815
|
+
public subtask<TaskArgumentsT extends TaskArguments>(
|
|
816
|
+
name: string,
|
|
817
|
+
action: ActionType<TaskArgumentsT>
|
|
818
|
+
): TaskDefinition;
|
|
819
|
+
public subtask<TaskArgumentsT extends TaskArguments>(
|
|
820
|
+
name: string,
|
|
821
|
+
descriptionOrAction?: string | ActionType<TaskArgumentsT>,
|
|
822
|
+
action?: ActionType<TaskArgumentsT>
|
|
823
|
+
) {
|
|
824
|
+
const subtask = this._addSubtask(name, descriptionOrAction, action);
|
|
825
|
+
|
|
826
|
+
this.tasks[name] = subtask;
|
|
827
|
+
|
|
828
|
+
return subtask;
|
|
829
|
+
}
|
|
830
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { TaskIdentifier } from "../../../types";
|
|
2
|
+
|
|
3
|
+
export function parseTaskIdentifier(taskIdentifier: TaskIdentifier): {
|
|
4
|
+
scope: string | undefined;
|
|
5
|
+
task: string;
|
|
6
|
+
} {
|
|
7
|
+
if (typeof taskIdentifier === "string") {
|
|
8
|
+
return {
|
|
9
|
+
scope: undefined,
|
|
10
|
+
task: taskIdentifier,
|
|
11
|
+
};
|
|
12
|
+
} else {
|
|
13
|
+
return {
|
|
14
|
+
scope: taskIdentifier.scope,
|
|
15
|
+
task: taskIdentifier.task,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { Block } from "@nomicfoundation/ethereumjs-block";
|
|
2
|
+
import {
|
|
3
|
+
bufferToHex,
|
|
4
|
+
toBuffer,
|
|
5
|
+
zeroAddress,
|
|
6
|
+
} from "@nomicfoundation/ethereumjs-util";
|
|
7
|
+
import {
|
|
8
|
+
OptionalRpcNewBlockTag,
|
|
9
|
+
RpcNewBlockTag,
|
|
10
|
+
} from "../../../core/jsonrpc/types/input/blockTag";
|
|
11
|
+
import { HardhatNode } from "../node";
|
|
12
|
+
import * as BigIntUtils from "../../../util/bigint";
|
|
13
|
+
import {
|
|
14
|
+
InvalidArgumentsError,
|
|
15
|
+
InvalidInputError,
|
|
16
|
+
} from "../../../core/providers/errors";
|
|
17
|
+
import { RpcCallRequest } from "../../../core/jsonrpc/types/input/callRequest";
|
|
18
|
+
import { CallParams } from "../node-types";
|
|
19
|
+
import { RpcAccessList } from "../../../core/jsonrpc/types/access-list";
|
|
20
|
+
|
|
21
|
+
/* eslint-disable @nomicfoundation/hardhat-internal-rules/only-hardhat-error */
|
|
22
|
+
|
|
23
|
+
export class Base {
|
|
24
|
+
constructor(protected readonly _node: HardhatNode) {}
|
|
25
|
+
|
|
26
|
+
public async resolveNewBlockTag(
|
|
27
|
+
newBlockTag: OptionalRpcNewBlockTag,
|
|
28
|
+
defaultValue: RpcNewBlockTag = "latest"
|
|
29
|
+
): Promise<bigint | "pending"> {
|
|
30
|
+
if (newBlockTag === undefined) {
|
|
31
|
+
newBlockTag = defaultValue;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (newBlockTag === "pending") {
|
|
35
|
+
return "pending";
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (newBlockTag === "latest") {
|
|
39
|
+
return this._node.getLatestBlockNumber();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (newBlockTag === "earliest") {
|
|
43
|
+
return 0n;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (newBlockTag === "safe" || newBlockTag === "finalized") {
|
|
47
|
+
this._checkPostMergeBlockTags(newBlockTag);
|
|
48
|
+
|
|
49
|
+
return this._node.getLatestBlockNumber();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (!BigIntUtils.isBigInt(newBlockTag)) {
|
|
53
|
+
if ("blockNumber" in newBlockTag && "blockHash" in newBlockTag) {
|
|
54
|
+
throw new InvalidArgumentsError(
|
|
55
|
+
"Invalid block tag received. Only one of hash or block number can be used."
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if ("blockNumber" in newBlockTag && "requireCanonical" in newBlockTag) {
|
|
60
|
+
throw new InvalidArgumentsError(
|
|
61
|
+
"Invalid block tag received. requireCanonical only works with hashes."
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
let block: Block | undefined;
|
|
67
|
+
if (BigIntUtils.isBigInt(newBlockTag)) {
|
|
68
|
+
block = await this._node.getBlockByNumber(newBlockTag);
|
|
69
|
+
} else if ("blockNumber" in newBlockTag) {
|
|
70
|
+
block = await this._node.getBlockByNumber(newBlockTag.blockNumber);
|
|
71
|
+
} else {
|
|
72
|
+
block = await this._node.getBlockByHash(newBlockTag.blockHash);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (block === undefined) {
|
|
76
|
+
const latestBlock = this._node.getLatestBlockNumber();
|
|
77
|
+
|
|
78
|
+
throw new InvalidInputError(
|
|
79
|
+
`Received invalid block tag ${this._newBlockTagToString(
|
|
80
|
+
newBlockTag
|
|
81
|
+
)}. Latest block number is ${latestBlock.toString()}`
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return block.header.number;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
public async rpcCallRequestToNodeCallParams(
|
|
89
|
+
rpcCall: RpcCallRequest
|
|
90
|
+
): Promise<CallParams> {
|
|
91
|
+
return {
|
|
92
|
+
to: rpcCall.to,
|
|
93
|
+
from:
|
|
94
|
+
rpcCall.from !== undefined
|
|
95
|
+
? rpcCall.from
|
|
96
|
+
: await this._getDefaultCallFrom(),
|
|
97
|
+
data: rpcCall.data !== undefined ? rpcCall.data : toBuffer([]),
|
|
98
|
+
gasLimit:
|
|
99
|
+
rpcCall.gas !== undefined ? rpcCall.gas : this._node.getBlockGasLimit(),
|
|
100
|
+
value: rpcCall.value !== undefined ? rpcCall.value : 0n,
|
|
101
|
+
accessList:
|
|
102
|
+
rpcCall.accessList !== undefined
|
|
103
|
+
? this._rpcAccessListToNodeAccessList(rpcCall.accessList)
|
|
104
|
+
: undefined,
|
|
105
|
+
gasPrice: rpcCall.gasPrice,
|
|
106
|
+
maxFeePerGas: rpcCall.maxFeePerGas,
|
|
107
|
+
maxPriorityFeePerGas: rpcCall.maxPriorityFeePerGas,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
protected _rpcAccessListToNodeAccessList(
|
|
112
|
+
rpcAccessList: RpcAccessList
|
|
113
|
+
): Array<[Buffer, Buffer[]]> {
|
|
114
|
+
return rpcAccessList.map((tuple) => [
|
|
115
|
+
tuple.address,
|
|
116
|
+
tuple.storageKeys ?? [],
|
|
117
|
+
]);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
protected _checkPostMergeBlockTags(blockTag: "safe" | "finalized") {
|
|
121
|
+
const isPostMerge = this._node.isPostMergeHardfork();
|
|
122
|
+
const hardfork = this._node.hardfork;
|
|
123
|
+
|
|
124
|
+
if (!isPostMerge) {
|
|
125
|
+
throw new InvalidArgumentsError(
|
|
126
|
+
`The '${blockTag}' block tag is not allowed in pre-merge hardforks. You are using the '${hardfork}' hardfork.`
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
protected _newBlockTagToString(tag: RpcNewBlockTag): string {
|
|
132
|
+
if (typeof tag === "string") {
|
|
133
|
+
return tag;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (BigIntUtils.isBigInt(tag)) {
|
|
137
|
+
return tag.toString();
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if ("blockNumber" in tag) {
|
|
141
|
+
return tag.blockNumber.toString();
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return bufferToHex(tag.blockHash);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
private async _getDefaultCallFrom(): Promise<Buffer> {
|
|
148
|
+
const localAccounts = await this._node.getLocalAccountAddresses();
|
|
149
|
+
|
|
150
|
+
if (localAccounts.length === 0) {
|
|
151
|
+
return toBuffer(zeroAddress());
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return toBuffer(localAccounts[0]);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import { rpcHash } from "../../../core/jsonrpc/types/base-types";
|
|
2
|
+
import {
|
|
3
|
+
OptionalRpcNewBlockTag,
|
|
4
|
+
optionalRpcNewBlockTag,
|
|
5
|
+
} from "../../../core/jsonrpc/types/input/blockTag";
|
|
6
|
+
import {
|
|
7
|
+
RpcCallRequest,
|
|
8
|
+
rpcCallRequest,
|
|
9
|
+
} from "../../../core/jsonrpc/types/input/callRequest";
|
|
2
10
|
import {
|
|
3
11
|
rpcDebugTracingConfig,
|
|
4
12
|
RpcDebugTracingConfig,
|
|
@@ -10,17 +18,22 @@ import {
|
|
|
10
18
|
} from "../../../core/providers/errors";
|
|
11
19
|
import { HardhatNode } from "../node";
|
|
12
20
|
import { RpcDebugTraceOutput } from "../output";
|
|
21
|
+
import { Base } from "./base";
|
|
13
22
|
|
|
14
23
|
/* eslint-disable @nomicfoundation/hardhat-internal-rules/only-hardhat-error */
|
|
15
24
|
|
|
16
|
-
export class DebugModule {
|
|
17
|
-
constructor(
|
|
25
|
+
export class DebugModule extends Base {
|
|
26
|
+
constructor(_node: HardhatNode) {
|
|
27
|
+
super(_node);
|
|
28
|
+
}
|
|
18
29
|
|
|
19
30
|
public async processRequest(
|
|
20
31
|
method: string,
|
|
21
32
|
params: any[] = []
|
|
22
33
|
): Promise<any> {
|
|
23
34
|
switch (method) {
|
|
35
|
+
case "debug_traceCall":
|
|
36
|
+
return this._traceCallAction(...this._traceCallParams(params));
|
|
24
37
|
case "debug_traceTransaction":
|
|
25
38
|
return this._traceTransactionAction(
|
|
26
39
|
...this._traceTransactionParams(params)
|
|
@@ -30,6 +43,34 @@ export class DebugModule {
|
|
|
30
43
|
throw new MethodNotFoundError(`Method ${method} not found`);
|
|
31
44
|
}
|
|
32
45
|
|
|
46
|
+
// debug_traceCall
|
|
47
|
+
|
|
48
|
+
private _traceCallParams(
|
|
49
|
+
params: any[]
|
|
50
|
+
): [RpcCallRequest, OptionalRpcNewBlockTag, RpcDebugTracingConfig] {
|
|
51
|
+
const validatedParams = validateParams(
|
|
52
|
+
params,
|
|
53
|
+
rpcCallRequest,
|
|
54
|
+
optionalRpcNewBlockTag,
|
|
55
|
+
rpcDebugTracingConfig
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
this._validateTracerParam(validatedParams[2]);
|
|
59
|
+
|
|
60
|
+
return validatedParams;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
private async _traceCallAction(
|
|
64
|
+
callConfig: RpcCallRequest,
|
|
65
|
+
block: OptionalRpcNewBlockTag,
|
|
66
|
+
traceConfig: RpcDebugTracingConfig
|
|
67
|
+
): Promise<RpcDebugTraceOutput> {
|
|
68
|
+
const callParams = await this.rpcCallRequestToNodeCallParams(callConfig);
|
|
69
|
+
const blockNumber = await this.resolveNewBlockTag(block);
|
|
70
|
+
|
|
71
|
+
return this._node.traceCall(callParams, blockNumber, traceConfig);
|
|
72
|
+
}
|
|
73
|
+
|
|
33
74
|
// debug_traceTransaction
|
|
34
75
|
|
|
35
76
|
private _traceTransactionParams(
|
|
@@ -46,6 +87,13 @@ export class DebugModule {
|
|
|
46
87
|
return validatedParams;
|
|
47
88
|
}
|
|
48
89
|
|
|
90
|
+
private async _traceTransactionAction(
|
|
91
|
+
hash: Buffer,
|
|
92
|
+
config: RpcDebugTracingConfig
|
|
93
|
+
): Promise<RpcDebugTraceOutput> {
|
|
94
|
+
return this._node.traceTransaction(hash, config);
|
|
95
|
+
}
|
|
96
|
+
|
|
49
97
|
private _validateTracerParam(config: RpcDebugTracingConfig) {
|
|
50
98
|
if (config?.tracer !== undefined) {
|
|
51
99
|
throw new InvalidArgumentsError(
|
|
@@ -53,11 +101,4 @@ export class DebugModule {
|
|
|
53
101
|
);
|
|
54
102
|
}
|
|
55
103
|
}
|
|
56
|
-
|
|
57
|
-
private async _traceTransactionAction(
|
|
58
|
-
hash: Buffer,
|
|
59
|
-
config: RpcDebugTracingConfig
|
|
60
|
-
): Promise<RpcDebugTraceOutput> {
|
|
61
|
-
return this._node.traceTransaction(hash, config);
|
|
62
|
-
}
|
|
63
104
|
}
|