@aztec/aztec-node 0.0.1-commit.6c91f13 → 0.0.1-commit.96bb3f7

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.
@@ -1,19 +1,385 @@
1
- function _ts_decorate(decorators, target, key, desc) {
2
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
- else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
- return c > 3 && r && Object.defineProperty(target, key, r), r;
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 { createBlobClient } from '@aztec/blob-client/client';
10
- import { createReadOnlyFileStoreBlobClients, createWritableFileStoreBlobClient } from '@aztec/blob-client/filestore';
376
+ import { createBlobClientWithFileStores } from '@aztec/blob-client/client';
11
377
  import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
12
378
  import { EpochCache } from '@aztec/epoch-cache';
13
379
  import { createEthereumChain } from '@aztec/ethereum/chain';
14
380
  import { getPublicClient } from '@aztec/ethereum/client';
15
381
  import { RegistryContract, RollupContract } from '@aztec/ethereum/contracts';
16
- import { BlockNumber } from '@aztec/foundation/branded-types';
382
+ import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types';
17
383
  import { compactArray, pick } from '@aztec/foundation/collection';
18
384
  import { Fr } from '@aztec/foundation/curves/bn254';
19
385
  import { EthAddress } from '@aztec/foundation/eth-address';
@@ -27,8 +393,7 @@ import { trySnapshotSync, uploadSnapshot } from '@aztec/node-lib/actions';
27
393
  import { createForwarderL1TxUtilsFromEthSigner, createL1TxUtilsWithBlobsFromEthSigner } from '@aztec/node-lib/factories';
28
394
  import { createP2PClient, getDefaultAllowedSetupFunctions } from '@aztec/p2p';
29
395
  import { ProtocolContractAddress } from '@aztec/protocol-contracts';
30
- import { BlockBuilder, GlobalVariableBuilder, SequencerClient, createValidatorForAcceptingTxs } from '@aztec/sequencer-client';
31
- import { CheckpointsBuilder } from '@aztec/sequencer-client';
396
+ import { BlockBuilder, GlobalVariableBuilder, SequencerClient } from '@aztec/sequencer-client';
32
397
  import { PublicProcessorFactory } from '@aztec/simulator/server';
33
398
  import { AttestationsBlockWatcher, EpochPruneWatcher, createSlasher } from '@aztec/slasher';
34
399
  import { CollectionLimitsConfig, PublicSimulatorConfig } from '@aztec/stdlib/avm';
@@ -44,12 +409,15 @@ import { MerkleTreeId, NullifierMembershipWitness, PublicDataWitness } from '@az
44
409
  import { PublicSimulationOutput, TxReceipt, TxStatus } from '@aztec/stdlib/tx';
45
410
  import { getPackageVersion } from '@aztec/stdlib/update-checker';
46
411
  import { Attributes, getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
47
- import { NodeKeystoreAdapter, ValidatorClient, createBlockProposalHandler, createValidatorClient } from '@aztec/validator-client';
412
+ import { FullNodeCheckpointsBuilder as CheckpointsBuilder, FullNodeCheckpointsBuilder, NodeKeystoreAdapter, ValidatorClient, createBlockProposalHandler, createValidatorClient, createValidatorForAcceptingTxs } from '@aztec/validator-client';
48
413
  import { createWorldStateSynchronizer } from '@aztec/world-state';
49
414
  import { createPublicClient, fallback, http } from 'viem';
50
415
  import { createSentinel } from '../sentinel/factory.js';
51
416
  import { createKeyStoreForValidator } from './config.js';
52
417
  import { NodeMetrics } from './node_metrics.js';
418
+ _dec = trackSpan('AztecNodeService.simulatePublicCalls', (tx)=>({
419
+ [Attributes.TX_HASH]: tx.getTxHash().toString()
420
+ }));
53
421
  /**
54
422
  * The aztec node.
55
423
  */ export class AztecNodeService {
@@ -73,6 +441,15 @@ import { NodeMetrics } from './node_metrics.js';
73
441
  telemetry;
74
442
  log;
75
443
  blobClient;
444
+ static{
445
+ ({ e: [_initProto] } = _apply_decs_2203_r(this, [
446
+ [
447
+ _dec,
448
+ 2,
449
+ "simulatePublicCalls"
450
+ ]
451
+ ], []));
452
+ }
76
453
  metrics;
77
454
  // Prevent two snapshot operations to happen simultaneously
78
455
  isUploadingSnapshot;
@@ -98,7 +475,7 @@ import { NodeMetrics } from './node_metrics.js';
98
475
  this.telemetry = telemetry;
99
476
  this.log = log;
100
477
  this.blobClient = blobClient;
101
- this.isUploadingSnapshot = false;
478
+ this.isUploadingSnapshot = (_initProto(this), false);
102
479
  this.metrics = new NodeMetrics(telemetry, 'AztecNodeService');
103
480
  this.tracer = telemetry.getTracer('AztecNodeService');
104
481
  this.log.info(`Aztec Node version: ${this.packageVersion}`);
@@ -174,20 +551,7 @@ import { NodeMetrics } from './node_metrics.js';
174
551
  if (config.rollupVersion !== Number(rollupVersionFromRollup)) {
175
552
  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}).`);
176
553
  }
177
- const blobFileStoreMetadata = {
178
- l1ChainId: config.l1ChainId,
179
- rollupVersion: config.rollupVersion,
180
- rollupAddress: config.l1Contracts.rollupAddress.toString()
181
- };
182
- const [fileStoreClients, fileStoreUploadClient] = await Promise.all([
183
- createReadOnlyFileStoreBlobClients(config.blobFileStoreUrls, blobFileStoreMetadata, log),
184
- createWritableFileStoreBlobClient(config.blobFileStoreUploadUrl, blobFileStoreMetadata, log)
185
- ]);
186
- const blobClient = deps.blobClient ?? createBlobClient(config, {
187
- logger: createLogger('node:blob-client:client'),
188
- fileStoreClients,
189
- fileStoreUploadClient
190
- });
554
+ const blobClient = await createBlobClientWithFileStores(config, createLogger('node:blob-client:client'));
191
555
  // attempt snapshot sync if possible
192
556
  await trySnapshotSync(config, log);
193
557
  const epochCache = await EpochCache.create(config.l1Contracts.rollupAddress, config, {
@@ -212,24 +576,32 @@ import { NodeMetrics } from './node_metrics.js';
212
576
  const p2pClient = await createP2PClient(P2PClientType.Full, config, archiver, proofVerifier, worldStateSynchronizer, epochCache, packageVersion, dateProvider, telemetry, deps.p2pClientDeps);
213
577
  // We should really not be modifying the config object
214
578
  config.txPublicSetupAllowList = config.txPublicSetupAllowList ?? await getDefaultAllowedSetupFunctions();
579
+ // Create BlockBuilder for EpochPruneWatcher (slasher functionality)
215
580
  const blockBuilder = new BlockBuilder({
216
581
  ...config,
217
582
  l1GenesisTime,
218
583
  slotDuration: Number(slotDuration)
219
584
  }, worldStateSynchronizer, archiver, dateProvider, telemetry);
585
+ // Create FullNodeCheckpointsBuilder for validator and non-validator block proposal handling
586
+ const validatorCheckpointsBuilder = new FullNodeCheckpointsBuilder({
587
+ ...config,
588
+ l1GenesisTime,
589
+ slotDuration: Number(slotDuration)
590
+ }, archiver, dateProvider, telemetry);
220
591
  // We'll accumulate sentinel watchers here
221
592
  const watchers = [];
222
593
  // Create validator client if required
223
594
  const validatorClient = createValidatorClient(config, {
595
+ checkpointsBuilder: validatorCheckpointsBuilder,
596
+ worldState: worldStateSynchronizer,
224
597
  p2pClient,
225
598
  telemetry,
226
599
  dateProvider,
227
600
  epochCache,
228
- blockBuilder,
229
601
  blockSource: archiver,
230
602
  l1ToL2MessageSource: archiver,
231
603
  keyStoreManager,
232
- fileStoreBlobUploadClient: fileStoreUploadClient
604
+ blobClient
233
605
  });
234
606
  // If we have a validator client, register it as a source of offenses for the slasher,
235
607
  // and have it register callbacks on the p2p client *before* we start it, otherwise messages
@@ -245,7 +617,8 @@ import { NodeMetrics } from './node_metrics.js';
245
617
  if (!validatorClient && config.alwaysReexecuteBlockProposals) {
246
618
  log.info('Setting up block proposal reexecution for monitoring');
247
619
  createBlockProposalHandler(config, {
248
- blockBuilder,
620
+ checkpointsBuilder: validatorCheckpointsBuilder,
621
+ worldState: worldStateSynchronizer,
249
622
  epochCache,
250
623
  blockSource: archiver,
251
624
  l1ToL2MessageSource: archiver,
@@ -429,11 +802,20 @@ import { NodeMetrics } from './node_metrics.js';
429
802
  async getPublishedBlocks(from, limit) {
430
803
  return await this.blockSource.getPublishedBlocks(from, limit) ?? [];
431
804
  }
805
+ async getPublishedCheckpoints(from, limit) {
806
+ return await this.blockSource.getPublishedCheckpoints(from, limit) ?? [];
807
+ }
808
+ async getL2BlocksNew(from, limit) {
809
+ return await this.blockSource.getL2BlocksNew(from, limit) ?? [];
810
+ }
811
+ async getCheckpointedBlocks(from, limit, proven) {
812
+ return await this.blockSource.getCheckpointedBlocks(from, limit, proven) ?? [];
813
+ }
432
814
  /**
433
- * Method to fetch the current base fees.
434
- * @returns The current base fees.
435
- */ async getCurrentBaseFees() {
436
- return await this.globalVariableBuilder.getCurrentBaseFees();
815
+ * Method to fetch the current min L2 fees.
816
+ * @returns The current min L2 fees.
817
+ */ async getCurrentMinFees() {
818
+ return await this.globalVariableBuilder.getCurrentMinFees();
437
819
  }
438
820
  async getMaxPriorityFees() {
439
821
  for await (const tx of this.p2pClient.iteratePendingTxs()){
@@ -555,6 +937,12 @@ import { NodeMetrics } from './node_metrics.js';
555
937
  this.log.info(`Stopped Aztec Node`);
556
938
  }
557
939
  /**
940
+ * Returns the blob client used by this node.
941
+ * @internal - Exposed for testing purposes only.
942
+ */ getBlobClient() {
943
+ return this.blobClient;
944
+ }
945
+ /**
558
946
  * Method to retrieve pending txs.
559
947
  * @param limit - The number of items to returns
560
948
  * @param after - The last known pending tx. Used for pagination
@@ -699,12 +1087,25 @@ import { NodeMetrics } from './node_metrics.js';
699
1087
  return messageIndex !== undefined;
700
1088
  }
701
1089
  /**
702
- * Returns all the L2 to L1 messages in a block.
703
- * @param blockNumber - The block number at which to get the data.
704
- * @returns The L2 to L1 messages (undefined if the block number is not found).
705
- */ async getL2ToL1Messages(blockNumber) {
706
- const block = await this.blockSource.getBlock(blockNumber === 'latest' ? await this.getBlockNumber() : blockNumber);
707
- return block?.body.txEffects.map((txEffect)=>txEffect.l2ToL1Msgs);
1090
+ * Returns all the L2 to L1 messages in an epoch.
1091
+ * @param epoch - The epoch at which to get the data.
1092
+ * @returns The L2 to L1 messages (empty array if the epoch is not found).
1093
+ */ async getL2ToL1Messages(epoch) {
1094
+ // Assumes `getBlocksForEpoch` returns blocks in ascending order of block number.
1095
+ const blocks = await this.blockSource.getBlocksForEpoch(epoch);
1096
+ const blocksInCheckpoints = [];
1097
+ let previousSlotNumber = SlotNumber.ZERO;
1098
+ let checkpointIndex = -1;
1099
+ for (const block of blocks){
1100
+ const slotNumber = block.header.globalVariables.slotNumber;
1101
+ if (slotNumber !== previousSlotNumber) {
1102
+ checkpointIndex++;
1103
+ blocksInCheckpoints.push([]);
1104
+ previousSlotNumber = slotNumber;
1105
+ }
1106
+ blocksInCheckpoints[checkpointIndex].push(block);
1107
+ }
1108
+ return blocksInCheckpoints.map((blocks)=>blocks.map((block)=>block.body.txEffects.map((txEffect)=>txEffect.l2ToL1Msgs)));
708
1109
  }
709
1110
  /**
710
1111
  * Returns a sibling path for a leaf in the committed blocks tree.
@@ -887,7 +1288,7 @@ import { NodeMetrics } from './node_metrics.js';
887
1288
  l1ChainId: this.l1ChainId,
888
1289
  rollupVersion: this.version,
889
1290
  setupAllowList: this.config.txPublicSetupAllowList ?? await getDefaultAllowedSetupFunctions(),
890
- gasFees: await this.getCurrentBaseFees(),
1291
+ gasFees: await this.getCurrentMinFees(),
891
1292
  skipFeeEnforcement,
892
1293
  txsPermitted: !this.config.disableTransactions
893
1294
  });
@@ -950,7 +1351,7 @@ import { NodeMetrics } from './node_metrics.js';
950
1351
  throw new Error(`Archiver initial sync not complete. Cannot start snapshot.`);
951
1352
  }
952
1353
  // And it has an L2 block hash
953
- const l2BlockHash = await archiver.getL2Tips().then((tips)=>tips.latest.hash);
1354
+ const l2BlockHash = await archiver.getL2Tips().then((tips)=>tips.proposed.hash);
954
1355
  if (!l2BlockHash) {
955
1356
  this.metrics.recordSnapshotError();
956
1357
  throw new Error(`Archiver has no latest L2 block hash downloaded. Cannot start snapshot.`);
@@ -977,7 +1378,7 @@ import { NodeMetrics } from './node_metrics.js';
977
1378
  if (!('rollbackTo' in archiver)) {
978
1379
  throw new Error('Archiver implementation does not support rollbacks.');
979
1380
  }
980
- const finalizedBlock = await archiver.getL2Tips().then((tips)=>tips.finalized.number);
1381
+ const finalizedBlock = await archiver.getL2Tips().then((tips)=>tips.finalized.block.number);
981
1382
  if (targetBlock < finalizedBlock) {
982
1383
  if (force) {
983
1384
  this.log.warn(`Clearing world state database to allow rolling back behind finalized block ${finalizedBlock}`);
@@ -1066,8 +1467,3 @@ import { NodeMetrics } from './node_metrics.js';
1066
1467
  return await this.worldStateSynchronizer.syncImmediate(blockSourceHeight);
1067
1468
  }
1068
1469
  }
1069
- _ts_decorate([
1070
- trackSpan('AztecNodeService.simulatePublicCalls', (tx)=>({
1071
- [Attributes.TX_HASH]: tx.getTxHash().toString()
1072
- }))
1073
- ], AztecNodeService.prototype, "simulatePublicCalls", null);
@@ -1,5 +1,5 @@
1
1
  import type { EpochCache } from '@aztec/epoch-cache';
2
- import { BlockNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
2
+ import { CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
3
3
  import { EthAddress } from '@aztec/foundation/eth-address';
4
4
  import { RunningPromise } from '@aztec/foundation/running-promise';
5
5
  import { type L2TipsStore } from '@aztec/kv-store/stores';
@@ -22,8 +22,8 @@ export declare class Sentinel extends Sentinel_base implements L2BlockStreamEven
22
22
  protected l2TipsStore: L2TipsStore;
23
23
  protected initialSlot: SlotNumber | undefined;
24
24
  protected lastProcessedSlot: SlotNumber | undefined;
25
- protected slotNumberToBlock: Map<SlotNumber, {
26
- blockNumber: BlockNumber;
25
+ protected slotNumberToCheckpoint: Map<SlotNumber, {
26
+ checkpointNumber: CheckpointNumber;
27
27
  archive: string;
28
28
  attestors: EthAddress[];
29
29
  }>;
@@ -34,6 +34,7 @@ export declare class Sentinel extends Sentinel_base implements L2BlockStreamEven
34
34
  protected init(): Promise<void>;
35
35
  stop(): Promise<void>;
36
36
  handleBlockStreamEvent(event: L2BlockStreamEvent): Promise<void>;
37
+ protected handleCheckpoint(event: L2BlockStreamEvent): void;
37
38
  protected handleChainProven(event: L2BlockStreamEvent): Promise<void>;
38
39
  protected computeProvenPerformance(epoch: EpochNumber): Promise<ValidatorsEpochPerformance>;
39
40
  /**
@@ -89,4 +90,4 @@ export declare class Sentinel extends Sentinel_base implements L2BlockStreamEven
89
90
  } | undefined;
90
91
  }
91
92
  export {};
92
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VudGluZWwuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZW50aW5lbC9zZW50aW5lbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFBRSxVQUFVLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUV2RixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFFM0QsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQ25FLE9BQU8sRUFBcUIsS0FBSyxXQUFXLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUM3RSxPQUFPLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDNUMsT0FBTyxFQUlMLEtBQUssT0FBTyxFQUNaLEtBQUssY0FBYyxFQUNwQixNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sS0FBSyxFQUFFLGFBQWEsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzNELE9BQU8sRUFDTCxLQUFLLGFBQWEsRUFDbEIsYUFBYSxFQUNiLEtBQUssa0JBQWtCLEVBQ3ZCLEtBQUsseUJBQXlCLEVBRS9CLE1BQU0scUJBQXFCLENBQUM7QUFFN0IsT0FBTyxLQUFLLEVBQ1Ysb0JBQW9CLEVBQ3BCLGNBQWMsRUFDZCxzQkFBc0IsRUFDdEIscUJBQXFCLEVBQ3JCLG1CQUFtQixFQUNuQiwwQkFBMEIsRUFDMUIsZUFBZSxFQUNoQixNQUFNLDBCQUEwQixDQUFDO0FBSWxDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxZQUFZLENBQUM7O0FBRTNDLHFCQUFhLFFBQVMsU0FBUSxhQUEyQyxZQUFXLHlCQUF5QixFQUFFLE9BQU87SUFZbEgsU0FBUyxDQUFDLFVBQVUsRUFBRSxVQUFVO0lBQ2hDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsYUFBYTtJQUNq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
93
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VudGluZWwuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZW50aW5lbC9zZW50aW5lbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxVQUFVLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNyRCxPQUFPLEVBQWUsZ0JBQWdCLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBRXpHLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUUzRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDbkUsT0FBTyxFQUFxQixLQUFLLFdBQVcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzdFLE9BQU8sS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUM1QyxPQUFPLEVBSUwsS0FBSyxPQUFPLEVBQ1osS0FBSyxjQUFjLEVBQ3BCLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEIsT0FBTyxLQUFLLEVBQUUsYUFBYSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDM0QsT0FBTyxFQUNMLEtBQUssYUFBYSxFQUNsQixhQUFhLEVBQ2IsS0FBSyxrQkFBa0IsRUFDdkIsS0FBSyx5QkFBeUIsRUFFL0IsTUFBTSxxQkFBcUIsQ0FBQztBQUU3QixPQUFPLEtBQUssRUFDVixvQkFBb0IsRUFDcEIsY0FBYyxFQUNkLHNCQUFzQixFQUN0QixxQkFBcUIsRUFDckIsbUJBQW1CLEVBQ25CLDBCQUEwQixFQUMxQixlQUFlLEVBQ2hCLE1BQU0sMEJBQTBCLENBQUM7QUFJbEMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLFlBQVksQ0FBQzs7QUFFM0MscUJBQWEsUUFBUyxTQUFRLGFBQTJDLFlBQVcseUJBQXlCLEVBQUUsT0FBTztJQWNsSCxTQUFTLENBQUMsVUFBVSxFQUFFLFVBQVU7SUFDaEMsU0FBUyxDQUFDLFFBQVEsRUFBRSxhQUFhO0lB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