@aztec/aztec-node 4.0.0-nightly.20250907 → 4.0.0-nightly.20260108
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/dest/aztec-node/config.d.ts +9 -4
- package/dest/aztec-node/config.d.ts.map +1 -1
- package/dest/aztec-node/config.js +22 -20
- package/dest/aztec-node/node_metrics.d.ts +5 -1
- package/dest/aztec-node/node_metrics.d.ts.map +1 -1
- package/dest/aztec-node/node_metrics.js +21 -0
- package/dest/aztec-node/server.d.ts +70 -51
- package/dest/aztec-node/server.d.ts.map +1 -1
- package/dest/aztec-node/server.js +589 -98
- package/dest/bin/index.d.ts +1 -1
- package/dest/index.d.ts +1 -1
- package/dest/sentinel/config.d.ts +2 -1
- package/dest/sentinel/config.d.ts.map +1 -1
- package/dest/sentinel/config.js +16 -0
- package/dest/sentinel/factory.d.ts +1 -1
- package/dest/sentinel/factory.d.ts.map +1 -1
- package/dest/sentinel/factory.js +3 -1
- package/dest/sentinel/index.d.ts +1 -1
- package/dest/sentinel/sentinel.d.ts +20 -19
- package/dest/sentinel/sentinel.d.ts.map +1 -1
- package/dest/sentinel/sentinel.js +33 -21
- package/dest/sentinel/store.d.ts +8 -5
- package/dest/sentinel/store.d.ts.map +1 -1
- package/dest/sentinel/store.js +8 -4
- package/dest/test/index.d.ts +1 -1
- package/package.json +29 -28
- package/src/aztec-node/config.ts +36 -41
- package/src/aztec-node/node_metrics.ts +28 -0
- package/src/aztec-node/server.ts +273 -139
- package/src/sentinel/config.ts +18 -0
- package/src/sentinel/factory.ts +5 -1
- package/src/sentinel/sentinel.ts +60 -40
- package/src/sentinel/store.ts +18 -13
|
@@ -1,48 +1,424 @@
|
|
|
1
|
-
function
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
function applyDecs2203RFactory() {
|
|
2
|
+
function createAddInitializerMethod(initializers, decoratorFinishedRef) {
|
|
3
|
+
return function addInitializer(initializer) {
|
|
4
|
+
assertNotFinished(decoratorFinishedRef, "addInitializer");
|
|
5
|
+
assertCallable(initializer, "An initializer");
|
|
6
|
+
initializers.push(initializer);
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
function memberDec(dec, name, desc, initializers, kind, isStatic, isPrivate, metadata, value) {
|
|
10
|
+
var kindStr;
|
|
11
|
+
switch(kind){
|
|
12
|
+
case 1:
|
|
13
|
+
kindStr = "accessor";
|
|
14
|
+
break;
|
|
15
|
+
case 2:
|
|
16
|
+
kindStr = "method";
|
|
17
|
+
break;
|
|
18
|
+
case 3:
|
|
19
|
+
kindStr = "getter";
|
|
20
|
+
break;
|
|
21
|
+
case 4:
|
|
22
|
+
kindStr = "setter";
|
|
23
|
+
break;
|
|
24
|
+
default:
|
|
25
|
+
kindStr = "field";
|
|
26
|
+
}
|
|
27
|
+
var ctx = {
|
|
28
|
+
kind: kindStr,
|
|
29
|
+
name: isPrivate ? "#" + name : name,
|
|
30
|
+
static: isStatic,
|
|
31
|
+
private: isPrivate,
|
|
32
|
+
metadata: metadata
|
|
33
|
+
};
|
|
34
|
+
var decoratorFinishedRef = {
|
|
35
|
+
v: false
|
|
36
|
+
};
|
|
37
|
+
ctx.addInitializer = createAddInitializerMethod(initializers, decoratorFinishedRef);
|
|
38
|
+
var get, set;
|
|
39
|
+
if (kind === 0) {
|
|
40
|
+
if (isPrivate) {
|
|
41
|
+
get = desc.get;
|
|
42
|
+
set = desc.set;
|
|
43
|
+
} else {
|
|
44
|
+
get = function() {
|
|
45
|
+
return this[name];
|
|
46
|
+
};
|
|
47
|
+
set = function(v) {
|
|
48
|
+
this[name] = v;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
} else if (kind === 2) {
|
|
52
|
+
get = function() {
|
|
53
|
+
return desc.value;
|
|
54
|
+
};
|
|
55
|
+
} else {
|
|
56
|
+
if (kind === 1 || kind === 3) {
|
|
57
|
+
get = function() {
|
|
58
|
+
return desc.get.call(this);
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
if (kind === 1 || kind === 4) {
|
|
62
|
+
set = function(v) {
|
|
63
|
+
desc.set.call(this, v);
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
ctx.access = get && set ? {
|
|
68
|
+
get: get,
|
|
69
|
+
set: set
|
|
70
|
+
} : get ? {
|
|
71
|
+
get: get
|
|
72
|
+
} : {
|
|
73
|
+
set: set
|
|
74
|
+
};
|
|
75
|
+
try {
|
|
76
|
+
return dec(value, ctx);
|
|
77
|
+
} finally{
|
|
78
|
+
decoratorFinishedRef.v = true;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function assertNotFinished(decoratorFinishedRef, fnName) {
|
|
82
|
+
if (decoratorFinishedRef.v) {
|
|
83
|
+
throw new Error("attempted to call " + fnName + " after decoration was finished");
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function assertCallable(fn, hint) {
|
|
87
|
+
if (typeof fn !== "function") {
|
|
88
|
+
throw new TypeError(hint + " must be a function");
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function assertValidReturnValue(kind, value) {
|
|
92
|
+
var type = typeof value;
|
|
93
|
+
if (kind === 1) {
|
|
94
|
+
if (type !== "object" || value === null) {
|
|
95
|
+
throw new TypeError("accessor decorators must return an object with get, set, or init properties or void 0");
|
|
96
|
+
}
|
|
97
|
+
if (value.get !== undefined) {
|
|
98
|
+
assertCallable(value.get, "accessor.get");
|
|
99
|
+
}
|
|
100
|
+
if (value.set !== undefined) {
|
|
101
|
+
assertCallable(value.set, "accessor.set");
|
|
102
|
+
}
|
|
103
|
+
if (value.init !== undefined) {
|
|
104
|
+
assertCallable(value.init, "accessor.init");
|
|
105
|
+
}
|
|
106
|
+
} else if (type !== "function") {
|
|
107
|
+
var hint;
|
|
108
|
+
if (kind === 0) {
|
|
109
|
+
hint = "field";
|
|
110
|
+
} else if (kind === 10) {
|
|
111
|
+
hint = "class";
|
|
112
|
+
} else {
|
|
113
|
+
hint = "method";
|
|
114
|
+
}
|
|
115
|
+
throw new TypeError(hint + " decorators must return a function or void 0");
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function applyMemberDec(ret, base, decInfo, name, kind, isStatic, isPrivate, initializers, metadata) {
|
|
119
|
+
var decs = decInfo[0];
|
|
120
|
+
var desc, init, value;
|
|
121
|
+
if (isPrivate) {
|
|
122
|
+
if (kind === 0 || kind === 1) {
|
|
123
|
+
desc = {
|
|
124
|
+
get: decInfo[3],
|
|
125
|
+
set: decInfo[4]
|
|
126
|
+
};
|
|
127
|
+
} else if (kind === 3) {
|
|
128
|
+
desc = {
|
|
129
|
+
get: decInfo[3]
|
|
130
|
+
};
|
|
131
|
+
} else if (kind === 4) {
|
|
132
|
+
desc = {
|
|
133
|
+
set: decInfo[3]
|
|
134
|
+
};
|
|
135
|
+
} else {
|
|
136
|
+
desc = {
|
|
137
|
+
value: decInfo[3]
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
} else if (kind !== 0) {
|
|
141
|
+
desc = Object.getOwnPropertyDescriptor(base, name);
|
|
142
|
+
}
|
|
143
|
+
if (kind === 1) {
|
|
144
|
+
value = {
|
|
145
|
+
get: desc.get,
|
|
146
|
+
set: desc.set
|
|
147
|
+
};
|
|
148
|
+
} else if (kind === 2) {
|
|
149
|
+
value = desc.value;
|
|
150
|
+
} else if (kind === 3) {
|
|
151
|
+
value = desc.get;
|
|
152
|
+
} else if (kind === 4) {
|
|
153
|
+
value = desc.set;
|
|
154
|
+
}
|
|
155
|
+
var newValue, get, set;
|
|
156
|
+
if (typeof decs === "function") {
|
|
157
|
+
newValue = memberDec(decs, name, desc, initializers, kind, isStatic, isPrivate, metadata, value);
|
|
158
|
+
if (newValue !== void 0) {
|
|
159
|
+
assertValidReturnValue(kind, newValue);
|
|
160
|
+
if (kind === 0) {
|
|
161
|
+
init = newValue;
|
|
162
|
+
} else if (kind === 1) {
|
|
163
|
+
init = newValue.init;
|
|
164
|
+
get = newValue.get || value.get;
|
|
165
|
+
set = newValue.set || value.set;
|
|
166
|
+
value = {
|
|
167
|
+
get: get,
|
|
168
|
+
set: set
|
|
169
|
+
};
|
|
170
|
+
} else {
|
|
171
|
+
value = newValue;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
} else {
|
|
175
|
+
for(var i = decs.length - 1; i >= 0; i--){
|
|
176
|
+
var dec = decs[i];
|
|
177
|
+
newValue = memberDec(dec, name, desc, initializers, kind, isStatic, isPrivate, metadata, value);
|
|
178
|
+
if (newValue !== void 0) {
|
|
179
|
+
assertValidReturnValue(kind, newValue);
|
|
180
|
+
var newInit;
|
|
181
|
+
if (kind === 0) {
|
|
182
|
+
newInit = newValue;
|
|
183
|
+
} else if (kind === 1) {
|
|
184
|
+
newInit = newValue.init;
|
|
185
|
+
get = newValue.get || value.get;
|
|
186
|
+
set = newValue.set || value.set;
|
|
187
|
+
value = {
|
|
188
|
+
get: get,
|
|
189
|
+
set: set
|
|
190
|
+
};
|
|
191
|
+
} else {
|
|
192
|
+
value = newValue;
|
|
193
|
+
}
|
|
194
|
+
if (newInit !== void 0) {
|
|
195
|
+
if (init === void 0) {
|
|
196
|
+
init = newInit;
|
|
197
|
+
} else if (typeof init === "function") {
|
|
198
|
+
init = [
|
|
199
|
+
init,
|
|
200
|
+
newInit
|
|
201
|
+
];
|
|
202
|
+
} else {
|
|
203
|
+
init.push(newInit);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
if (kind === 0 || kind === 1) {
|
|
210
|
+
if (init === void 0) {
|
|
211
|
+
init = function(instance, init) {
|
|
212
|
+
return init;
|
|
213
|
+
};
|
|
214
|
+
} else if (typeof init !== "function") {
|
|
215
|
+
var ownInitializers = init;
|
|
216
|
+
init = function(instance, init) {
|
|
217
|
+
var value = init;
|
|
218
|
+
for(var i = 0; i < ownInitializers.length; i++){
|
|
219
|
+
value = ownInitializers[i].call(instance, value);
|
|
220
|
+
}
|
|
221
|
+
return value;
|
|
222
|
+
};
|
|
223
|
+
} else {
|
|
224
|
+
var originalInitializer = init;
|
|
225
|
+
init = function(instance, init) {
|
|
226
|
+
return originalInitializer.call(instance, init);
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
ret.push(init);
|
|
230
|
+
}
|
|
231
|
+
if (kind !== 0) {
|
|
232
|
+
if (kind === 1) {
|
|
233
|
+
desc.get = value.get;
|
|
234
|
+
desc.set = value.set;
|
|
235
|
+
} else if (kind === 2) {
|
|
236
|
+
desc.value = value;
|
|
237
|
+
} else if (kind === 3) {
|
|
238
|
+
desc.get = value;
|
|
239
|
+
} else if (kind === 4) {
|
|
240
|
+
desc.set = value;
|
|
241
|
+
}
|
|
242
|
+
if (isPrivate) {
|
|
243
|
+
if (kind === 1) {
|
|
244
|
+
ret.push(function(instance, args) {
|
|
245
|
+
return value.get.call(instance, args);
|
|
246
|
+
});
|
|
247
|
+
ret.push(function(instance, args) {
|
|
248
|
+
return value.set.call(instance, args);
|
|
249
|
+
});
|
|
250
|
+
} else if (kind === 2) {
|
|
251
|
+
ret.push(value);
|
|
252
|
+
} else {
|
|
253
|
+
ret.push(function(instance, args) {
|
|
254
|
+
return value.call(instance, args);
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
} else {
|
|
258
|
+
Object.defineProperty(base, name, desc);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
function applyMemberDecs(Class, decInfos, metadata) {
|
|
263
|
+
var ret = [];
|
|
264
|
+
var protoInitializers;
|
|
265
|
+
var staticInitializers;
|
|
266
|
+
var existingProtoNonFields = new Map();
|
|
267
|
+
var existingStaticNonFields = new Map();
|
|
268
|
+
for(var i = 0; i < decInfos.length; i++){
|
|
269
|
+
var decInfo = decInfos[i];
|
|
270
|
+
if (!Array.isArray(decInfo)) continue;
|
|
271
|
+
var kind = decInfo[1];
|
|
272
|
+
var name = decInfo[2];
|
|
273
|
+
var isPrivate = decInfo.length > 3;
|
|
274
|
+
var isStatic = kind >= 5;
|
|
275
|
+
var base;
|
|
276
|
+
var initializers;
|
|
277
|
+
if (isStatic) {
|
|
278
|
+
base = Class;
|
|
279
|
+
kind = kind - 5;
|
|
280
|
+
staticInitializers = staticInitializers || [];
|
|
281
|
+
initializers = staticInitializers;
|
|
282
|
+
} else {
|
|
283
|
+
base = Class.prototype;
|
|
284
|
+
protoInitializers = protoInitializers || [];
|
|
285
|
+
initializers = protoInitializers;
|
|
286
|
+
}
|
|
287
|
+
if (kind !== 0 && !isPrivate) {
|
|
288
|
+
var existingNonFields = isStatic ? existingStaticNonFields : existingProtoNonFields;
|
|
289
|
+
var existingKind = existingNonFields.get(name) || 0;
|
|
290
|
+
if (existingKind === true || existingKind === 3 && kind !== 4 || existingKind === 4 && kind !== 3) {
|
|
291
|
+
throw new Error("Attempted to decorate a public method/accessor that has the same name as a previously decorated public method/accessor. This is not currently supported by the decorators plugin. Property name was: " + name);
|
|
292
|
+
} else if (!existingKind && kind > 2) {
|
|
293
|
+
existingNonFields.set(name, kind);
|
|
294
|
+
} else {
|
|
295
|
+
existingNonFields.set(name, true);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
applyMemberDec(ret, base, decInfo, name, kind, isStatic, isPrivate, initializers, metadata);
|
|
299
|
+
}
|
|
300
|
+
pushInitializers(ret, protoInitializers);
|
|
301
|
+
pushInitializers(ret, staticInitializers);
|
|
302
|
+
return ret;
|
|
303
|
+
}
|
|
304
|
+
function pushInitializers(ret, initializers) {
|
|
305
|
+
if (initializers) {
|
|
306
|
+
ret.push(function(instance) {
|
|
307
|
+
for(var i = 0; i < initializers.length; i++){
|
|
308
|
+
initializers[i].call(instance);
|
|
309
|
+
}
|
|
310
|
+
return instance;
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
function applyClassDecs(targetClass, classDecs, metadata) {
|
|
315
|
+
if (classDecs.length > 0) {
|
|
316
|
+
var initializers = [];
|
|
317
|
+
var newClass = targetClass;
|
|
318
|
+
var name = targetClass.name;
|
|
319
|
+
for(var i = classDecs.length - 1; i >= 0; i--){
|
|
320
|
+
var decoratorFinishedRef = {
|
|
321
|
+
v: false
|
|
322
|
+
};
|
|
323
|
+
try {
|
|
324
|
+
var nextNewClass = classDecs[i](newClass, {
|
|
325
|
+
kind: "class",
|
|
326
|
+
name: name,
|
|
327
|
+
addInitializer: createAddInitializerMethod(initializers, decoratorFinishedRef),
|
|
328
|
+
metadata
|
|
329
|
+
});
|
|
330
|
+
} finally{
|
|
331
|
+
decoratorFinishedRef.v = true;
|
|
332
|
+
}
|
|
333
|
+
if (nextNewClass !== undefined) {
|
|
334
|
+
assertValidReturnValue(10, nextNewClass);
|
|
335
|
+
newClass = nextNewClass;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
return [
|
|
339
|
+
defineMetadata(newClass, metadata),
|
|
340
|
+
function() {
|
|
341
|
+
for(var i = 0; i < initializers.length; i++){
|
|
342
|
+
initializers[i].call(newClass);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
];
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
function defineMetadata(Class, metadata) {
|
|
349
|
+
return Object.defineProperty(Class, Symbol.metadata || Symbol.for("Symbol.metadata"), {
|
|
350
|
+
configurable: true,
|
|
351
|
+
enumerable: true,
|
|
352
|
+
value: metadata
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
return function applyDecs2203R(targetClass, memberDecs, classDecs, parentClass) {
|
|
356
|
+
if (parentClass !== void 0) {
|
|
357
|
+
var parentMetadata = parentClass[Symbol.metadata || Symbol.for("Symbol.metadata")];
|
|
358
|
+
}
|
|
359
|
+
var metadata = Object.create(parentMetadata === void 0 ? null : parentMetadata);
|
|
360
|
+
var e = applyMemberDecs(targetClass, memberDecs, metadata);
|
|
361
|
+
if (!classDecs.length) defineMetadata(targetClass, metadata);
|
|
362
|
+
return {
|
|
363
|
+
e: e,
|
|
364
|
+
get c () {
|
|
365
|
+
return applyClassDecs(targetClass, classDecs, metadata);
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
};
|
|
6
369
|
}
|
|
370
|
+
function _apply_decs_2203_r(targetClass, memberDecs, classDecs, parentClass) {
|
|
371
|
+
return (_apply_decs_2203_r = applyDecs2203RFactory())(targetClass, memberDecs, classDecs, parentClass);
|
|
372
|
+
}
|
|
373
|
+
var _dec, _initProto;
|
|
7
374
|
import { createArchiver } from '@aztec/archiver';
|
|
8
375
|
import { BBCircuitVerifier, QueuedIVCVerifier, TestCircuitVerifier } from '@aztec/bb-prover';
|
|
9
|
-
import {
|
|
376
|
+
import { createBlobClientWithFileStores } from '@aztec/blob-client/client';
|
|
10
377
|
import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
|
|
11
378
|
import { EpochCache } from '@aztec/epoch-cache';
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
379
|
+
import { createEthereumChain } from '@aztec/ethereum/chain';
|
|
380
|
+
import { getPublicClient } from '@aztec/ethereum/client';
|
|
381
|
+
import { RegistryContract, RollupContract } from '@aztec/ethereum/contracts';
|
|
382
|
+
import { BlockNumber } from '@aztec/foundation/branded-types';
|
|
14
383
|
import { compactArray, pick } from '@aztec/foundation/collection';
|
|
384
|
+
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
15
385
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
16
|
-
import { Fr } from '@aztec/foundation/fields';
|
|
17
386
|
import { BadRequestError } from '@aztec/foundation/json-rpc';
|
|
18
387
|
import { createLogger } from '@aztec/foundation/log';
|
|
19
|
-
import { SerialQueue } from '@aztec/foundation/queue';
|
|
20
388
|
import { count } from '@aztec/foundation/string';
|
|
21
389
|
import { DateProvider, Timer } from '@aztec/foundation/timer';
|
|
22
390
|
import { MembershipWitness } from '@aztec/foundation/trees';
|
|
23
391
|
import { KeystoreManager, loadKeystores, mergeKeystores } from '@aztec/node-keystore';
|
|
24
392
|
import { trySnapshotSync, uploadSnapshot } from '@aztec/node-lib/actions';
|
|
393
|
+
import { createForwarderL1TxUtilsFromEthSigner, createL1TxUtilsWithBlobsFromEthSigner } from '@aztec/node-lib/factories';
|
|
25
394
|
import { createP2PClient, getDefaultAllowedSetupFunctions } from '@aztec/p2p';
|
|
26
395
|
import { ProtocolContractAddress } from '@aztec/protocol-contracts';
|
|
27
396
|
import { BlockBuilder, GlobalVariableBuilder, SequencerClient, createValidatorForAcceptingTxs } from '@aztec/sequencer-client';
|
|
397
|
+
import { CheckpointsBuilder } from '@aztec/sequencer-client';
|
|
28
398
|
import { PublicProcessorFactory } from '@aztec/simulator/server';
|
|
29
399
|
import { AttestationsBlockWatcher, EpochPruneWatcher, createSlasher } from '@aztec/slasher';
|
|
400
|
+
import { CollectionLimitsConfig, PublicSimulatorConfig } from '@aztec/stdlib/avm';
|
|
30
401
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
31
402
|
import { L2BlockHash } from '@aztec/stdlib/block';
|
|
403
|
+
import { GasFees } from '@aztec/stdlib/gas';
|
|
32
404
|
import { computePublicDataTreeLeafSlot } from '@aztec/stdlib/hash';
|
|
33
405
|
import { AztecNodeAdminConfigSchema } from '@aztec/stdlib/interfaces/client';
|
|
34
406
|
import { tryStop } from '@aztec/stdlib/interfaces/server';
|
|
407
|
+
import { InboxLeaf } from '@aztec/stdlib/messaging';
|
|
35
408
|
import { P2PClientType } from '@aztec/stdlib/p2p';
|
|
36
409
|
import { MerkleTreeId, NullifierMembershipWitness, PublicDataWitness } from '@aztec/stdlib/trees';
|
|
37
410
|
import { PublicSimulationOutput, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
|
|
38
411
|
import { getPackageVersion } from '@aztec/stdlib/update-checker';
|
|
39
412
|
import { Attributes, getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
|
|
40
|
-
import { NodeKeystoreAdapter, ValidatorClient, createValidatorClient } from '@aztec/validator-client';
|
|
413
|
+
import { NodeKeystoreAdapter, ValidatorClient, createBlockProposalHandler, createValidatorClient } from '@aztec/validator-client';
|
|
41
414
|
import { createWorldStateSynchronizer } from '@aztec/world-state';
|
|
42
415
|
import { createPublicClient, fallback, http } from 'viem';
|
|
43
416
|
import { createSentinel } from '../sentinel/factory.js';
|
|
44
417
|
import { createKeyStoreForValidator } from './config.js';
|
|
45
418
|
import { NodeMetrics } from './node_metrics.js';
|
|
419
|
+
_dec = trackSpan('AztecNodeService.simulatePublicCalls', (tx)=>({
|
|
420
|
+
[Attributes.TX_HASH]: tx.getTxHash().toString()
|
|
421
|
+
}));
|
|
46
422
|
/**
|
|
47
423
|
* The aztec node.
|
|
48
424
|
*/ export class AztecNodeService {
|
|
@@ -65,13 +441,21 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
65
441
|
proofVerifier;
|
|
66
442
|
telemetry;
|
|
67
443
|
log;
|
|
444
|
+
blobClient;
|
|
445
|
+
static{
|
|
446
|
+
({ e: [_initProto] } = _apply_decs_2203_r(this, [
|
|
447
|
+
[
|
|
448
|
+
_dec,
|
|
449
|
+
2,
|
|
450
|
+
"simulatePublicCalls"
|
|
451
|
+
]
|
|
452
|
+
], []));
|
|
453
|
+
}
|
|
68
454
|
metrics;
|
|
69
455
|
// Prevent two snapshot operations to happen simultaneously
|
|
70
456
|
isUploadingSnapshot;
|
|
71
|
-
// Serial queue to ensure that we only send one tx at a time
|
|
72
|
-
txQueue;
|
|
73
457
|
tracer;
|
|
74
|
-
constructor(config, p2pClient, blockSource, logsSource, contractDataSource, l1ToL2MessageSource, worldStateSynchronizer, sequencer, slasherClient, validatorsSentinel, epochPruneWatcher, l1ChainId, version, globalVariableBuilder, epochCache, packageVersion, proofVerifier, telemetry = getTelemetryClient(), log = createLogger('node')){
|
|
458
|
+
constructor(config, p2pClient, blockSource, logsSource, contractDataSource, l1ToL2MessageSource, worldStateSynchronizer, sequencer, slasherClient, validatorsSentinel, epochPruneWatcher, l1ChainId, version, globalVariableBuilder, epochCache, packageVersion, proofVerifier, telemetry = getTelemetryClient(), log = createLogger('node'), blobClient){
|
|
75
459
|
this.config = config;
|
|
76
460
|
this.p2pClient = p2pClient;
|
|
77
461
|
this.blockSource = blockSource;
|
|
@@ -91,11 +475,10 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
91
475
|
this.proofVerifier = proofVerifier;
|
|
92
476
|
this.telemetry = telemetry;
|
|
93
477
|
this.log = log;
|
|
94
|
-
this.
|
|
95
|
-
this.
|
|
478
|
+
this.blobClient = blobClient;
|
|
479
|
+
this.isUploadingSnapshot = (_initProto(this), false);
|
|
96
480
|
this.metrics = new NodeMetrics(telemetry, 'AztecNodeService');
|
|
97
481
|
this.tracer = telemetry.getTracer('AztecNodeService');
|
|
98
|
-
this.txQueue.start();
|
|
99
482
|
this.log.info(`Aztec Node version: ${this.packageVersion}`);
|
|
100
483
|
this.log.info(`Aztec Node started on chain 0x${l1ChainId.toString(16)}`, config.l1Contracts);
|
|
101
484
|
}
|
|
@@ -118,9 +501,6 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
118
501
|
const packageVersion = getPackageVersion() ?? '';
|
|
119
502
|
const telemetry = deps.telemetry ?? getTelemetryClient();
|
|
120
503
|
const dateProvider = deps.dateProvider ?? new DateProvider();
|
|
121
|
-
const blobSinkClient = deps.blobSinkClient ?? createBlobSinkClient(config, {
|
|
122
|
-
logger: createLogger('node:blob-sink:client')
|
|
123
|
-
});
|
|
124
504
|
const ethereumChain = createEthereumChain(config.l1RpcUrls, config.l1ChainId);
|
|
125
505
|
// Build a key store from file if given or from environment otherwise
|
|
126
506
|
let keyStoreManager;
|
|
@@ -134,6 +514,7 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
134
514
|
keyStoreManager = new KeystoreManager(keyStore);
|
|
135
515
|
}
|
|
136
516
|
}
|
|
517
|
+
await keyStoreManager?.validateSigners();
|
|
137
518
|
// If we are a validator, verify our configuration before doing too much more.
|
|
138
519
|
if (!config.disableValidator) {
|
|
139
520
|
if (keyStoreManager === undefined) {
|
|
@@ -142,7 +523,7 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
142
523
|
if (!keyStoreProvided) {
|
|
143
524
|
log.warn('KEY STORE CREATED FROM ENVIRONMENT, IT IS RECOMMENDED TO USE A FILE-BASED KEY STORE IN PRODUCTION ENVIRONMENTS');
|
|
144
525
|
}
|
|
145
|
-
ValidatorClient.validateKeyStoreConfiguration(keyStoreManager);
|
|
526
|
+
ValidatorClient.validateKeyStoreConfiguration(keyStoreManager, log);
|
|
146
527
|
}
|
|
147
528
|
// validate that the actual chain id matches that specified in configuration
|
|
148
529
|
if (config.l1ChainId !== ethereumChain.chainInfo.id) {
|
|
@@ -150,7 +531,9 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
150
531
|
}
|
|
151
532
|
const publicClient = createPublicClient({
|
|
152
533
|
chain: ethereumChain.chainInfo,
|
|
153
|
-
transport: fallback(config.l1RpcUrls.map((url)=>http(url
|
|
534
|
+
transport: fallback(config.l1RpcUrls.map((url)=>http(url, {
|
|
535
|
+
batch: false
|
|
536
|
+
}))),
|
|
154
537
|
pollingInterval: config.viemPollingIntervalMS
|
|
155
538
|
});
|
|
156
539
|
const l1ContractsAddresses = await RegistryContract.collectAddresses(publicClient, config.l1Contracts.registryAddress, config.rollupVersion ?? 'canonical');
|
|
@@ -169,89 +552,131 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
169
552
|
if (config.rollupVersion !== Number(rollupVersionFromRollup)) {
|
|
170
553
|
log.warn(`Registry looked up and returned a rollup with version (${config.rollupVersion}), but this does not match with version detected from the rollup directly: (${rollupVersionFromRollup}).`);
|
|
171
554
|
}
|
|
555
|
+
const blobClient = await createBlobClientWithFileStores(config, createLogger('node:blob-client:client'));
|
|
172
556
|
// attempt snapshot sync if possible
|
|
173
557
|
await trySnapshotSync(config, log);
|
|
174
558
|
const epochCache = await EpochCache.create(config.l1Contracts.rollupAddress, config, {
|
|
175
559
|
dateProvider
|
|
176
560
|
});
|
|
177
561
|
const archiver = await createArchiver(config, {
|
|
178
|
-
|
|
562
|
+
blobClient,
|
|
179
563
|
epochCache,
|
|
180
564
|
telemetry,
|
|
181
565
|
dateProvider
|
|
182
566
|
}, {
|
|
183
|
-
blockUntilSync:
|
|
567
|
+
blockUntilSync: !config.skipArchiverInitialSync
|
|
184
568
|
});
|
|
185
569
|
// now create the merkle trees and the world state synchronizer
|
|
186
570
|
const worldStateSynchronizer = await createWorldStateSynchronizer(config, archiver, options.prefilledPublicData, telemetry);
|
|
187
|
-
const circuitVerifier = config.realProofs ? await BBCircuitVerifier.new(config) : new TestCircuitVerifier();
|
|
571
|
+
const circuitVerifier = config.realProofs || config.debugForceTxProofVerification ? await BBCircuitVerifier.new(config) : new TestCircuitVerifier(config.proverTestVerificationDelayMs);
|
|
188
572
|
if (!config.realProofs) {
|
|
189
573
|
log.warn(`Aztec node is accepting fake proofs`);
|
|
190
574
|
}
|
|
191
575
|
const proofVerifier = new QueuedIVCVerifier(config, circuitVerifier);
|
|
192
576
|
// create the tx pool and the p2p client, which will need the l2 block source
|
|
193
577
|
const p2pClient = await createP2PClient(P2PClientType.Full, config, archiver, proofVerifier, worldStateSynchronizer, epochCache, packageVersion, dateProvider, telemetry, deps.p2pClientDeps);
|
|
194
|
-
//
|
|
195
|
-
await worldStateSynchronizer.start();
|
|
196
|
-
// Start p2p. Note that it depends on world state to be running.
|
|
197
|
-
await p2pClient.start();
|
|
578
|
+
// We should really not be modifying the config object
|
|
198
579
|
config.txPublicSetupAllowList = config.txPublicSetupAllowList ?? await getDefaultAllowedSetupFunctions();
|
|
199
580
|
const blockBuilder = new BlockBuilder({
|
|
200
581
|
...config,
|
|
201
582
|
l1GenesisTime,
|
|
202
583
|
slotDuration: Number(slotDuration)
|
|
203
584
|
}, worldStateSynchronizer, archiver, dateProvider, telemetry);
|
|
585
|
+
// We'll accumulate sentinel watchers here
|
|
204
586
|
const watchers = [];
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
587
|
+
// Create validator client if required
|
|
588
|
+
const validatorClient = createValidatorClient(config, {
|
|
589
|
+
p2pClient,
|
|
590
|
+
telemetry,
|
|
591
|
+
dateProvider,
|
|
592
|
+
epochCache,
|
|
593
|
+
blockBuilder,
|
|
594
|
+
blockSource: archiver,
|
|
595
|
+
l1ToL2MessageSource: archiver,
|
|
596
|
+
keyStoreManager,
|
|
597
|
+
blobClient
|
|
598
|
+
});
|
|
599
|
+
// If we have a validator client, register it as a source of offenses for the slasher,
|
|
600
|
+
// and have it register callbacks on the p2p client *before* we start it, otherwise messages
|
|
601
|
+
// like attestations or auths will fail.
|
|
602
|
+
if (validatorClient) {
|
|
603
|
+
watchers.push(validatorClient);
|
|
604
|
+
if (!options.dontStartSequencer) {
|
|
605
|
+
await validatorClient.registerHandlers();
|
|
211
606
|
}
|
|
212
607
|
}
|
|
608
|
+
// If there's no validator client but alwaysReexecuteBlockProposals is enabled,
|
|
609
|
+
// create a BlockProposalHandler to reexecute block proposals for monitoring
|
|
610
|
+
if (!validatorClient && config.alwaysReexecuteBlockProposals) {
|
|
611
|
+
log.info('Setting up block proposal reexecution for monitoring');
|
|
612
|
+
createBlockProposalHandler(config, {
|
|
613
|
+
blockBuilder,
|
|
614
|
+
epochCache,
|
|
615
|
+
blockSource: archiver,
|
|
616
|
+
l1ToL2MessageSource: archiver,
|
|
617
|
+
p2pClient,
|
|
618
|
+
dateProvider,
|
|
619
|
+
telemetry
|
|
620
|
+
}).registerForReexecution(p2pClient);
|
|
621
|
+
}
|
|
622
|
+
// Start world state and wait for it to sync to the archiver.
|
|
623
|
+
await worldStateSynchronizer.start();
|
|
624
|
+
// Start p2p. Note that it depends on world state to be running.
|
|
625
|
+
await p2pClient.start();
|
|
626
|
+
const validatorsSentinel = await createSentinel(epochCache, archiver, p2pClient, config);
|
|
627
|
+
if (validatorsSentinel && config.slashInactivityPenalty > 0n) {
|
|
628
|
+
watchers.push(validatorsSentinel);
|
|
629
|
+
}
|
|
213
630
|
let epochPruneWatcher;
|
|
214
631
|
if (config.slashPrunePenalty > 0n || config.slashDataWithholdingPenalty > 0n) {
|
|
215
632
|
epochPruneWatcher = new EpochPruneWatcher(archiver, archiver, epochCache, p2pClient.getTxProvider(), blockBuilder, config);
|
|
216
|
-
await epochPruneWatcher.start();
|
|
217
633
|
watchers.push(epochPruneWatcher);
|
|
218
634
|
}
|
|
219
635
|
// We assume we want to slash for invalid attestations unless all max penalties are set to 0
|
|
220
636
|
let attestationsBlockWatcher;
|
|
221
637
|
if (config.slashProposeInvalidAttestationsPenalty > 0n || config.slashAttestDescendantOfInvalidPenalty > 0n) {
|
|
222
638
|
attestationsBlockWatcher = new AttestationsBlockWatcher(archiver, epochCache, config);
|
|
223
|
-
await attestationsBlockWatcher.start();
|
|
224
639
|
watchers.push(attestationsBlockWatcher);
|
|
225
640
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
keyStoreManager
|
|
235
|
-
});
|
|
236
|
-
if (validatorClient) {
|
|
237
|
-
watchers.push(validatorClient);
|
|
238
|
-
}
|
|
239
|
-
log.verbose(`All Aztec Node subsystems synced`);
|
|
641
|
+
// Start p2p-related services once the archiver has completed sync
|
|
642
|
+
void archiver.waitForInitialSync().then(async ()=>{
|
|
643
|
+
await p2pClient.start();
|
|
644
|
+
await validatorsSentinel?.start();
|
|
645
|
+
await epochPruneWatcher?.start();
|
|
646
|
+
await attestationsBlockWatcher?.start();
|
|
647
|
+
log.info(`All p2p services started`);
|
|
648
|
+
}).catch((err)=>log.error('Failed to start p2p services after archiver sync', err));
|
|
240
649
|
// Validator enabled, create/start relevant service
|
|
241
650
|
let sequencer;
|
|
242
651
|
let slasherClient;
|
|
243
|
-
if (!config.disableValidator) {
|
|
652
|
+
if (!config.disableValidator && validatorClient) {
|
|
244
653
|
// We create a slasher only if we have a sequencer, since all slashing actions go through the sequencer publisher
|
|
245
654
|
// as they are executed when the node is selected as proposer.
|
|
246
655
|
const validatorAddresses = keyStoreManager ? NodeKeystoreAdapter.fromKeyStoreManager(keyStoreManager).getAddresses() : [];
|
|
247
656
|
slasherClient = await createSlasher(config, config.l1Contracts, getPublicClient(config), watchers, dateProvider, epochCache, validatorAddresses, undefined);
|
|
248
657
|
await slasherClient.start();
|
|
249
|
-
const l1TxUtils = keyStoreManager.createAllValidatorPublisherSigners().
|
|
250
|
-
|
|
658
|
+
const l1TxUtils = config.publisherForwarderAddress ? await createForwarderL1TxUtilsFromEthSigner(publicClient, keyStoreManager.createAllValidatorPublisherSigners(), config.publisherForwarderAddress, {
|
|
659
|
+
...config,
|
|
660
|
+
scope: 'sequencer'
|
|
661
|
+
}, {
|
|
662
|
+
telemetry,
|
|
663
|
+
logger: log.createChild('l1-tx-utils'),
|
|
664
|
+
dateProvider
|
|
665
|
+
}) : await createL1TxUtilsWithBlobsFromEthSigner(publicClient, keyStoreManager.createAllValidatorPublisherSigners(), {
|
|
666
|
+
...config,
|
|
667
|
+
scope: 'sequencer'
|
|
668
|
+
}, {
|
|
669
|
+
telemetry,
|
|
670
|
+
logger: log.createChild('l1-tx-utils'),
|
|
671
|
+
dateProvider
|
|
251
672
|
});
|
|
673
|
+
// Create and start the sequencer client
|
|
674
|
+
const checkpointsBuilder = new CheckpointsBuilder({
|
|
675
|
+
...config,
|
|
676
|
+
l1GenesisTime,
|
|
677
|
+
slotDuration: Number(slotDuration)
|
|
678
|
+
}, archiver, dateProvider, telemetry);
|
|
252
679
|
sequencer = await SequencerClient.new(config, {
|
|
253
|
-
// if deps were provided, they should override the defaults,
|
|
254
|
-
// or things that we created in this function
|
|
255
680
|
...deps,
|
|
256
681
|
epochCache,
|
|
257
682
|
l1TxUtils,
|
|
@@ -259,20 +684,28 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
259
684
|
p2pClient,
|
|
260
685
|
worldStateSynchronizer,
|
|
261
686
|
slasherClient,
|
|
262
|
-
|
|
687
|
+
checkpointsBuilder,
|
|
263
688
|
l2BlockSource: archiver,
|
|
264
689
|
l1ToL2MessageSource: archiver,
|
|
265
690
|
telemetry,
|
|
266
691
|
dateProvider,
|
|
267
|
-
|
|
692
|
+
blobClient,
|
|
268
693
|
nodeKeyStore: keyStoreManager
|
|
269
694
|
});
|
|
270
695
|
}
|
|
271
696
|
if (!options.dontStartSequencer && sequencer) {
|
|
272
697
|
await sequencer.start();
|
|
273
698
|
log.verbose(`Sequencer started`);
|
|
699
|
+
} else if (sequencer) {
|
|
700
|
+
log.warn(`Sequencer created but not started`);
|
|
274
701
|
}
|
|
275
|
-
|
|
702
|
+
const globalVariableBuilder = new GlobalVariableBuilder({
|
|
703
|
+
...config,
|
|
704
|
+
rollupVersion: BigInt(config.rollupVersion),
|
|
705
|
+
l1GenesisTime,
|
|
706
|
+
slotDuration: Number(slotDuration)
|
|
707
|
+
});
|
|
708
|
+
return new AztecNodeService(config, p2pClient, archiver, archiver, archiver, archiver, worldStateSynchronizer, sequencer, slasherClient, validatorsSentinel, epochPruneWatcher, ethereumChain.chainInfo.id, config.rollupVersion, globalVariableBuilder, epochCache, packageVersion, proofVerifier, telemetry, log, blobClient);
|
|
276
709
|
}
|
|
277
710
|
/**
|
|
278
711
|
* Returns the sequencer client instance.
|
|
@@ -298,6 +731,9 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
298
731
|
getEncodedEnr() {
|
|
299
732
|
return Promise.resolve(this.p2pClient.getEnr()?.encodeTxt());
|
|
300
733
|
}
|
|
734
|
+
async getAllowedPublicSetup() {
|
|
735
|
+
return this.config.txPublicSetupAllowList ?? await getDefaultAllowedSetupFunctions();
|
|
736
|
+
}
|
|
301
737
|
/**
|
|
302
738
|
* Method to determine if the node is ready to accept transactions.
|
|
303
739
|
* @returns - Flag indicating the readiness for tx submission.
|
|
@@ -328,7 +764,24 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
328
764
|
* @param number - The block number being requested.
|
|
329
765
|
* @returns The requested block.
|
|
330
766
|
*/ async getBlock(number) {
|
|
331
|
-
|
|
767
|
+
const blockNumber = number === 'latest' ? await this.getBlockNumber() : number;
|
|
768
|
+
return await this.blockSource.getBlock(blockNumber);
|
|
769
|
+
}
|
|
770
|
+
/**
|
|
771
|
+
* Get a block specified by its hash.
|
|
772
|
+
* @param blockHash - The block hash being requested.
|
|
773
|
+
* @returns The requested block.
|
|
774
|
+
*/ async getBlockByHash(blockHash) {
|
|
775
|
+
const publishedBlock = await this.blockSource.getPublishedBlockByHash(blockHash);
|
|
776
|
+
return publishedBlock?.block;
|
|
777
|
+
}
|
|
778
|
+
/**
|
|
779
|
+
* Get a block specified by its archive root.
|
|
780
|
+
* @param archive - The archive root being requested.
|
|
781
|
+
* @returns The requested block.
|
|
782
|
+
*/ async getBlockByArchive(archive) {
|
|
783
|
+
const publishedBlock = await this.blockSource.getPublishedBlockByArchive(archive);
|
|
784
|
+
return publishedBlock?.block;
|
|
332
785
|
}
|
|
333
786
|
/**
|
|
334
787
|
* Method to request blocks. Will attempt to return all requested blocks but will return only those available.
|
|
@@ -342,10 +795,19 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
342
795
|
return await this.blockSource.getPublishedBlocks(from, limit) ?? [];
|
|
343
796
|
}
|
|
344
797
|
/**
|
|
345
|
-
* Method to fetch the current
|
|
346
|
-
* @returns The current
|
|
347
|
-
*/ async
|
|
348
|
-
return await this.globalVariableBuilder.
|
|
798
|
+
* Method to fetch the current min L2 fees.
|
|
799
|
+
* @returns The current min L2 fees.
|
|
800
|
+
*/ async getCurrentMinFees() {
|
|
801
|
+
return await this.globalVariableBuilder.getCurrentMinFees();
|
|
802
|
+
}
|
|
803
|
+
async getMaxPriorityFees() {
|
|
804
|
+
for await (const tx of this.p2pClient.iteratePendingTxs()){
|
|
805
|
+
return tx.getGasSettings().maxPriorityFeesPerGas;
|
|
806
|
+
}
|
|
807
|
+
return GasFees.from({
|
|
808
|
+
feePerDaGas: 0n,
|
|
809
|
+
feePerL2Gas: 0n
|
|
810
|
+
});
|
|
349
811
|
}
|
|
350
812
|
/**
|
|
351
813
|
* Method to fetch the latest block number synchronized by the node.
|
|
@@ -380,22 +842,11 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
380
842
|
getContract(address) {
|
|
381
843
|
return this.contractDataSource.getContract(address);
|
|
382
844
|
}
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
* @param from - The block number from which to begin retrieving logs.
|
|
386
|
-
* @param limit - The maximum number of blocks to retrieve logs from.
|
|
387
|
-
* @returns An array of private logs from the specified range of blocks.
|
|
388
|
-
*/ getPrivateLogs(from, limit) {
|
|
389
|
-
return this.logsSource.getPrivateLogs(from, limit);
|
|
845
|
+
getPrivateLogsByTags(tags) {
|
|
846
|
+
return this.logsSource.getPrivateLogsByTags(tags);
|
|
390
847
|
}
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
* @param tags - The tags to filter the logs by.
|
|
394
|
-
* @param logsPerTag - The maximum number of logs to return for each tag. By default no limit is set
|
|
395
|
-
* @returns For each received tag, an array of matching logs is returned. An empty array implies no logs match
|
|
396
|
-
* that tag.
|
|
397
|
-
*/ getLogsByTags(tags, logsPerTag) {
|
|
398
|
-
return this.logsSource.getLogsByTags(tags, logsPerTag);
|
|
848
|
+
getPublicLogsByTagsFromContract(contractAddress, tags) {
|
|
849
|
+
return this.logsSource.getPublicLogsByTagsFromContract(contractAddress, tags);
|
|
399
850
|
}
|
|
400
851
|
/**
|
|
401
852
|
* Gets public logs based on the provided filter.
|
|
@@ -415,7 +866,7 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
415
866
|
* Method to submit a transaction to the p2p pool.
|
|
416
867
|
* @param tx - The transaction to be submitted.
|
|
417
868
|
*/ async sendTx(tx) {
|
|
418
|
-
await this
|
|
869
|
+
await this.#sendTx(tx);
|
|
419
870
|
}
|
|
420
871
|
async #sendTx(tx) {
|
|
421
872
|
const timer = new Timer();
|
|
@@ -456,7 +907,6 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
456
907
|
* Method to stop the aztec node.
|
|
457
908
|
*/ async stop() {
|
|
458
909
|
this.log.info(`Stopping Aztec Node`);
|
|
459
|
-
await this.txQueue.end();
|
|
460
910
|
await tryStop(this.validatorsSentinel);
|
|
461
911
|
await tryStop(this.epochPruneWatcher);
|
|
462
912
|
await tryStop(this.slasherClient);
|
|
@@ -465,10 +915,17 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
465
915
|
await tryStop(this.p2pClient);
|
|
466
916
|
await tryStop(this.worldStateSynchronizer);
|
|
467
917
|
await tryStop(this.blockSource);
|
|
918
|
+
await tryStop(this.blobClient);
|
|
468
919
|
await tryStop(this.telemetry);
|
|
469
920
|
this.log.info(`Stopped Aztec Node`);
|
|
470
921
|
}
|
|
471
922
|
/**
|
|
923
|
+
* Returns the blob client used by this node.
|
|
924
|
+
* @internal - Exposed for testing purposes only.
|
|
925
|
+
*/ getBlobClient() {
|
|
926
|
+
return this.blobClient;
|
|
927
|
+
}
|
|
928
|
+
/**
|
|
472
929
|
* Method to retrieve pending txs.
|
|
473
930
|
* @param limit - The number of items to returns
|
|
474
931
|
* @param after - The last known pending tx. Used for pagination
|
|
@@ -520,7 +977,7 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
520
977
|
// Now we obtain the block hashes from the archive tree by calling await `committedDb.getLeafValue(treeId, index)`
|
|
521
978
|
// (note that block number corresponds to the leaf index in the archive tree).
|
|
522
979
|
const blockHashes = await Promise.all(uniqueBlockNumbers.map((blockNumber)=>{
|
|
523
|
-
return committedDb.getLeafValue(MerkleTreeId.ARCHIVE, blockNumber);
|
|
980
|
+
return committedDb.getLeafValue(MerkleTreeId.ARCHIVE, BigInt(blockNumber));
|
|
524
981
|
}));
|
|
525
982
|
// If any of the block hashes are undefined, we throw an error.
|
|
526
983
|
for(let i = 0; i < uniqueBlockNumbers.length; i++){
|
|
@@ -528,7 +985,7 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
528
985
|
throw new Error(`Block hash is undefined for block number ${uniqueBlockNumbers[i]}`);
|
|
529
986
|
}
|
|
530
987
|
}
|
|
531
|
-
// Create
|
|
988
|
+
// Create DataInBlock objects by combining indices, blockNumbers and blockHashes and return them.
|
|
532
989
|
return maybeIndices.map((index, i)=>{
|
|
533
990
|
if (index === undefined) {
|
|
534
991
|
return undefined;
|
|
@@ -543,7 +1000,7 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
543
1000
|
return undefined;
|
|
544
1001
|
}
|
|
545
1002
|
return {
|
|
546
|
-
l2BlockNumber: Number(blockNumber),
|
|
1003
|
+
l2BlockNumber: BlockNumber(Number(blockNumber)),
|
|
547
1004
|
l2BlockHash: L2BlockHash.fromField(blockHash),
|
|
548
1005
|
data: index
|
|
549
1006
|
};
|
|
@@ -600,12 +1057,17 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
600
1057
|
witness.path
|
|
601
1058
|
];
|
|
602
1059
|
}
|
|
1060
|
+
async getL1ToL2MessageBlock(l1ToL2Message) {
|
|
1061
|
+
const messageIndex = await this.l1ToL2MessageSource.getL1ToL2MessageIndex(l1ToL2Message);
|
|
1062
|
+
return messageIndex ? BlockNumber.fromCheckpointNumber(InboxLeaf.checkpointNumberFromIndex(messageIndex)) : undefined;
|
|
1063
|
+
}
|
|
603
1064
|
/**
|
|
604
1065
|
* Returns whether an L1 to L2 message is synced by archiver and if it's ready to be included in a block.
|
|
605
1066
|
* @param l1ToL2Message - The L1 to L2 message to check.
|
|
606
1067
|
* @returns Whether the message is synced and ready to be included in a block.
|
|
607
1068
|
*/ async isL1ToL2MessageSynced(l1ToL2Message) {
|
|
608
|
-
|
|
1069
|
+
const messageIndex = await this.l1ToL2MessageSource.getL1ToL2MessageIndex(l1ToL2Message);
|
|
1070
|
+
return messageIndex !== undefined;
|
|
609
1071
|
}
|
|
610
1072
|
/**
|
|
611
1073
|
* Returns all the L2 to L1 messages in a block.
|
|
@@ -715,7 +1177,21 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
715
1177
|
* Returns the currently committed block header, or the initial header if no blocks have been produced.
|
|
716
1178
|
* @returns The current committed block header.
|
|
717
1179
|
*/ async getBlockHeader(blockNumber = 'latest') {
|
|
718
|
-
return blockNumber ===
|
|
1180
|
+
return blockNumber === BlockNumber.ZERO || blockNumber === 'latest' && await this.blockSource.getBlockNumber() === BlockNumber.ZERO ? this.worldStateSynchronizer.getCommitted().getInitialHeader() : this.blockSource.getBlockHeader(blockNumber === 'latest' ? blockNumber : blockNumber);
|
|
1181
|
+
}
|
|
1182
|
+
/**
|
|
1183
|
+
* Get a block header specified by its hash.
|
|
1184
|
+
* @param blockHash - The block hash being requested.
|
|
1185
|
+
* @returns The requested block header.
|
|
1186
|
+
*/ async getBlockHeaderByHash(blockHash) {
|
|
1187
|
+
return await this.blockSource.getBlockHeaderByHash(blockHash);
|
|
1188
|
+
}
|
|
1189
|
+
/**
|
|
1190
|
+
* Get a block header specified by its archive root.
|
|
1191
|
+
* @param archive - The archive root being requested.
|
|
1192
|
+
* @returns The requested block header.
|
|
1193
|
+
*/ async getBlockHeaderByArchive(archive) {
|
|
1194
|
+
return await this.blockSource.getBlockHeaderByArchive(archive);
|
|
719
1195
|
}
|
|
720
1196
|
/**
|
|
721
1197
|
* Simulates the public part of a transaction with the current state.
|
|
@@ -729,7 +1205,7 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
729
1205
|
throw new BadRequestError(`Transaction total gas limit ${txGasLimit + teardownGasLimit} (${txGasLimit} + ${teardownGasLimit}) exceeds maximum gas limit ${this.config.rpcSimulatePublicMaxGasLimit} for simulation`);
|
|
730
1206
|
}
|
|
731
1207
|
const txHash = tx.getTxHash();
|
|
732
|
-
const blockNumber = await this.blockSource.getBlockNumber() + 1;
|
|
1208
|
+
const blockNumber = BlockNumber(await this.blockSource.getBlockNumber() + 1);
|
|
733
1209
|
// If sequencer is not initialized, we just set these values to zero for simulation.
|
|
734
1210
|
const coinbase = EthAddress.ZERO;
|
|
735
1211
|
const feeRecipient = AztecAddress.ZERO;
|
|
@@ -742,7 +1218,17 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
742
1218
|
});
|
|
743
1219
|
const merkleTreeFork = await this.worldStateSynchronizer.fork();
|
|
744
1220
|
try {
|
|
745
|
-
const
|
|
1221
|
+
const config = PublicSimulatorConfig.from({
|
|
1222
|
+
skipFeeEnforcement,
|
|
1223
|
+
collectDebugLogs: true,
|
|
1224
|
+
collectHints: false,
|
|
1225
|
+
collectCallMetadata: true,
|
|
1226
|
+
collectStatistics: false,
|
|
1227
|
+
collectionLimits: CollectionLimitsConfig.from({
|
|
1228
|
+
maxDebugLogMemoryReads: this.config.rpcSimulatePublicMaxDebugLogMemoryReads
|
|
1229
|
+
})
|
|
1230
|
+
});
|
|
1231
|
+
const processor = publicProcessorFactory.create(merkleTreeFork, newGlobalVariables, config);
|
|
746
1232
|
// REFACTOR: Consider merging ProcessReturnValues into ProcessedTx
|
|
747
1233
|
const [processedTxs, failedTxs, _usedTxs, returns] = await processor.process([
|
|
748
1234
|
tx
|
|
@@ -765,14 +1251,14 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
765
1251
|
const verifier = isSimulation ? undefined : this.proofVerifier;
|
|
766
1252
|
// We accept transactions if they are not expired by the next slot (checked based on the IncludeByTimestamp field)
|
|
767
1253
|
const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
|
|
768
|
-
const blockNumber = await this.blockSource.getBlockNumber() + 1;
|
|
1254
|
+
const blockNumber = BlockNumber(await this.blockSource.getBlockNumber() + 1);
|
|
769
1255
|
const validator = createValidatorForAcceptingTxs(db, this.contractDataSource, verifier, {
|
|
770
1256
|
timestamp: nextSlotTimestamp,
|
|
771
1257
|
blockNumber,
|
|
772
1258
|
l1ChainId: this.l1ChainId,
|
|
773
1259
|
rollupVersion: this.version,
|
|
774
1260
|
setupAllowList: this.config.txPublicSetupAllowList ?? await getDefaultAllowedSetupFunctions(),
|
|
775
|
-
gasFees: await this.
|
|
1261
|
+
gasFees: await this.getCurrentMinFees(),
|
|
776
1262
|
skipFeeEnforcement,
|
|
777
1263
|
txsPermitted: !this.config.disableTransactions
|
|
778
1264
|
});
|
|
@@ -791,8 +1277,11 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
791
1277
|
this.sequencer?.updateConfig(config);
|
|
792
1278
|
this.slasherClient?.updateConfig(config);
|
|
793
1279
|
this.validatorsSentinel?.updateConfig(config);
|
|
794
|
-
// this.blockBuilder.updateConfig(config); // TODO: Spyros has a PR to add the builder to `this`, so we can do this
|
|
795
1280
|
await this.p2pClient.updateP2PConfig(config);
|
|
1281
|
+
const archiver = this.blockSource;
|
|
1282
|
+
if ('updateConfig' in archiver) {
|
|
1283
|
+
archiver.updateConfig(config);
|
|
1284
|
+
}
|
|
796
1285
|
if (newConfig.realProofs !== this.config.realProofs) {
|
|
797
1286
|
this.proofVerifier = config.realProofs ? await BBCircuitVerifier.new(newConfig) : new TestCircuitVerifier();
|
|
798
1287
|
}
|
|
@@ -823,26 +1312,33 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
823
1312
|
// We break support for archiver running remotely to the node
|
|
824
1313
|
const archiver = this.blockSource;
|
|
825
1314
|
if (!('backupTo' in archiver)) {
|
|
1315
|
+
this.metrics.recordSnapshotError();
|
|
826
1316
|
throw new Error('Archiver implementation does not support backups. Cannot generate snapshot.');
|
|
827
1317
|
}
|
|
828
1318
|
// Test that the archiver has done an initial sync.
|
|
829
1319
|
if (!archiver.isInitialSyncComplete()) {
|
|
1320
|
+
this.metrics.recordSnapshotError();
|
|
830
1321
|
throw new Error(`Archiver initial sync not complete. Cannot start snapshot.`);
|
|
831
1322
|
}
|
|
832
1323
|
// And it has an L2 block hash
|
|
833
1324
|
const l2BlockHash = await archiver.getL2Tips().then((tips)=>tips.latest.hash);
|
|
834
1325
|
if (!l2BlockHash) {
|
|
1326
|
+
this.metrics.recordSnapshotError();
|
|
835
1327
|
throw new Error(`Archiver has no latest L2 block hash downloaded. Cannot start snapshot.`);
|
|
836
1328
|
}
|
|
837
1329
|
if (this.isUploadingSnapshot) {
|
|
1330
|
+
this.metrics.recordSnapshotError();
|
|
838
1331
|
throw new Error(`Snapshot upload already in progress. Cannot start another one until complete.`);
|
|
839
1332
|
}
|
|
840
1333
|
// Do not wait for the upload to be complete to return to the caller, but flag that an operation is in progress
|
|
841
1334
|
this.isUploadingSnapshot = true;
|
|
1335
|
+
const timer = new Timer();
|
|
842
1336
|
void uploadSnapshot(location, this.blockSource, this.worldStateSynchronizer, this.config, this.log).then(()=>{
|
|
843
1337
|
this.isUploadingSnapshot = false;
|
|
1338
|
+
this.metrics.recordSnapshot(timer.ms());
|
|
844
1339
|
}).catch((err)=>{
|
|
845
1340
|
this.isUploadingSnapshot = false;
|
|
1341
|
+
this.metrics.recordSnapshotError();
|
|
846
1342
|
this.log.error(`Error uploading snapshot: ${err}`);
|
|
847
1343
|
});
|
|
848
1344
|
return Promise.resolve();
|
|
@@ -915,7 +1411,7 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
915
1411
|
if (typeof blockNumber === 'number' && blockNumber < INITIAL_L2_BLOCK_NUM - 1) {
|
|
916
1412
|
throw new Error('Invalid block number to get world state for: ' + blockNumber);
|
|
917
1413
|
}
|
|
918
|
-
let blockSyncedTo =
|
|
1414
|
+
let blockSyncedTo = BlockNumber.ZERO;
|
|
919
1415
|
try {
|
|
920
1416
|
// Attempt to sync the world state if necessary
|
|
921
1417
|
blockSyncedTo = await this.#syncWorldState();
|
|
@@ -938,11 +1434,6 @@ import { NodeMetrics } from './node_metrics.js';
|
|
|
938
1434
|
* @returns A promise that fulfils once the world state is synced
|
|
939
1435
|
*/ async #syncWorldState() {
|
|
940
1436
|
const blockSourceHeight = await this.blockSource.getBlockNumber();
|
|
941
|
-
return this.worldStateSynchronizer.syncImmediate(blockSourceHeight);
|
|
1437
|
+
return await this.worldStateSynchronizer.syncImmediate(blockSourceHeight);
|
|
942
1438
|
}
|
|
943
1439
|
}
|
|
944
|
-
_ts_decorate([
|
|
945
|
-
trackSpan('AztecNodeService.simulatePublicCalls', (tx)=>({
|
|
946
|
-
[Attributes.TX_HASH]: tx.getTxHash().toString()
|
|
947
|
-
}))
|
|
948
|
-
], AztecNodeService.prototype, "simulatePublicCalls", null);
|