@aztec/aztec-node 0.0.1-commit.5daedc8 → 0.0.1-commit.6c91f13

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,6 +1,11 @@
1
1
  import { Archiver, createArchiver } from '@aztec/archiver';
2
2
  import { BBCircuitVerifier, QueuedIVCVerifier, TestCircuitVerifier } from '@aztec/bb-prover';
3
- import { type BlobSinkClientInterface, createBlobSinkClient } from '@aztec/blob-sink/client';
3
+ import { type BlobClientInterface, createBlobClient } from '@aztec/blob-client/client';
4
+ import {
5
+ type BlobFileStoreMetadata,
6
+ createReadOnlyFileStoreBlobClients,
7
+ createWritableFileStoreBlobClient,
8
+ } from '@aztec/blob-client/filestore';
4
9
  import {
5
10
  ARCHIVE_HEIGHT,
6
11
  INITIAL_L2_BLOCK_NUM,
@@ -10,17 +15,14 @@ import {
10
15
  type PUBLIC_DATA_TREE_HEIGHT,
11
16
  } from '@aztec/constants';
12
17
  import { EpochCache, type EpochCacheInterface } from '@aztec/epoch-cache';
13
- import {
14
- type L1ContractAddresses,
15
- RegistryContract,
16
- RollupContract,
17
- createEthereumChain,
18
- getPublicClient,
19
- } from '@aztec/ethereum';
20
- import { SlotNumber } from '@aztec/foundation/branded-types';
18
+ import { createEthereumChain } from '@aztec/ethereum/chain';
19
+ import { getPublicClient } from '@aztec/ethereum/client';
20
+ import { RegistryContract, RollupContract } from '@aztec/ethereum/contracts';
21
+ import type { L1ContractAddresses } from '@aztec/ethereum/l1-contract-addresses';
22
+ import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types';
21
23
  import { compactArray, pick } from '@aztec/foundation/collection';
24
+ import { Fr } from '@aztec/foundation/curves/bn254';
22
25
  import { EthAddress } from '@aztec/foundation/eth-address';
23
- import { Fr } from '@aztec/foundation/fields';
24
26
  import { BadRequestError } from '@aztec/foundation/json-rpc';
25
27
  import { type Logger, createLogger } from '@aztec/foundation/log';
26
28
  import { count } from '@aztec/foundation/string';
@@ -28,7 +30,10 @@ import { DateProvider, Timer } from '@aztec/foundation/timer';
28
30
  import { MembershipWitness, SiblingPath } from '@aztec/foundation/trees';
29
31
  import { KeystoreManager, loadKeystores, mergeKeystores } from '@aztec/node-keystore';
30
32
  import { trySnapshotSync, uploadSnapshot } from '@aztec/node-lib/actions';
31
- import { createL1TxUtilsWithBlobsFromEthSigner } from '@aztec/node-lib/factories';
33
+ import {
34
+ createForwarderL1TxUtilsFromEthSigner,
35
+ createL1TxUtilsWithBlobsFromEthSigner,
36
+ } from '@aztec/node-lib/factories';
32
37
  import { type P2P, type P2PClientDeps, createP2PClient, getDefaultAllowedSetupFunctions } from '@aztec/p2p';
33
38
  import { ProtocolContractAddress } from '@aztec/protocol-contracts';
34
39
  import {
@@ -38,6 +43,7 @@ import {
38
43
  type SequencerPublisher,
39
44
  createValidatorForAcceptingTxs,
40
45
  } from '@aztec/sequencer-client';
46
+ import { CheckpointsBuilder } from '@aztec/sequencer-client';
41
47
  import { PublicProcessorFactory } from '@aztec/simulator/server';
42
48
  import {
43
49
  AttestationsBlockWatcher,
@@ -46,13 +52,13 @@ import {
46
52
  type Watcher,
47
53
  createSlasher,
48
54
  } from '@aztec/slasher';
49
- import { PublicSimulatorConfig } from '@aztec/stdlib/avm';
55
+ import { CollectionLimitsConfig, PublicSimulatorConfig } from '@aztec/stdlib/avm';
50
56
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
51
57
  import {
52
- type InBlock,
58
+ type BlockParameter,
59
+ type DataInBlock,
53
60
  type L2Block,
54
61
  L2BlockHash,
55
- type L2BlockNumber,
56
62
  type L2BlockSource,
57
63
  type PublishedL2Block,
58
64
  } from '@aztec/stdlib/block';
@@ -82,7 +88,7 @@ import {
82
88
  type WorldStateSynchronizer,
83
89
  tryStop,
84
90
  } from '@aztec/stdlib/interfaces/server';
85
- import type { LogFilter, PrivateLog, TxScopedL2Log } from '@aztec/stdlib/logs';
91
+ import type { LogFilter, SiloedTag, Tag, TxScopedL2Log } from '@aztec/stdlib/logs';
86
92
  import { InboxLeaf, type L1ToL2MessageSource } from '@aztec/stdlib/messaging';
87
93
  import { P2PClientType } from '@aztec/stdlib/p2p';
88
94
  import type { Offense, SlashPayloadRound } from '@aztec/stdlib/slashing';
@@ -155,6 +161,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
155
161
  private proofVerifier: ClientProtocolCircuitVerifier,
156
162
  private telemetry: TelemetryClient = getTelemetryClient(),
157
163
  private log = createLogger('node'),
164
+ private blobClient?: BlobClientInterface,
158
165
  ) {
159
166
  this.metrics = new NodeMetrics(telemetry, 'AztecNodeService');
160
167
  this.tracer = telemetry.getTracer('AztecNodeService');
@@ -184,7 +191,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
184
191
  logger?: Logger;
185
192
  publisher?: SequencerPublisher;
186
193
  dateProvider?: DateProvider;
187
- blobSinkClient?: BlobSinkClientInterface;
194
+ blobClient?: BlobClientInterface;
188
195
  p2pClientDeps?: P2PClientDeps<P2PClientType.Full>;
189
196
  } = {},
190
197
  options: {
@@ -197,8 +204,6 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
197
204
  const packageVersion = getPackageVersion() ?? '';
198
205
  const telemetry = deps.telemetry ?? getTelemetryClient();
199
206
  const dateProvider = deps.dateProvider ?? new DateProvider();
200
- const blobSinkClient =
201
- deps.blobSinkClient ?? createBlobSinkClient(config, { logger: createLogger('node:blob-sink:client') });
202
207
  const ethereumChain = createEthereumChain(config.l1RpcUrls, config.l1ChainId);
203
208
 
204
209
  // Build a key store from file if given or from environment otherwise
@@ -238,7 +243,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
238
243
 
239
244
  const publicClient = createPublicClient({
240
245
  chain: ethereumChain.chainInfo,
241
- transport: fallback(config.l1RpcUrls.map((url: string) => http(url))),
246
+ transport: fallback(config.l1RpcUrls.map((url: string) => http(url, { batch: false }))),
242
247
  pollingInterval: config.viemPollingIntervalMS,
243
248
  });
244
249
 
@@ -266,6 +271,25 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
266
271
  );
267
272
  }
268
273
 
274
+ const blobFileStoreMetadata: BlobFileStoreMetadata = {
275
+ l1ChainId: config.l1ChainId,
276
+ rollupVersion: config.rollupVersion,
277
+ rollupAddress: config.l1Contracts.rollupAddress.toString(),
278
+ };
279
+
280
+ const [fileStoreClients, fileStoreUploadClient] = await Promise.all([
281
+ createReadOnlyFileStoreBlobClients(config.blobFileStoreUrls, blobFileStoreMetadata, log),
282
+ createWritableFileStoreBlobClient(config.blobFileStoreUploadUrl, blobFileStoreMetadata, log),
283
+ ]);
284
+
285
+ const blobClient =
286
+ deps.blobClient ??
287
+ createBlobClient(config, {
288
+ logger: createLogger('node:blob-client:client'),
289
+ fileStoreClients,
290
+ fileStoreUploadClient,
291
+ });
292
+
269
293
  // attempt snapshot sync if possible
270
294
  await trySnapshotSync(config, log);
271
295
 
@@ -273,7 +297,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
273
297
 
274
298
  const archiver = await createArchiver(
275
299
  config,
276
- { blobSinkClient, epochCache, telemetry, dateProvider },
300
+ { blobClient, epochCache, telemetry, dateProvider },
277
301
  { blockUntilSync: !config.skipArchiverInitialSync },
278
302
  );
279
303
 
@@ -284,9 +308,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
284
308
  options.prefilledPublicData,
285
309
  telemetry,
286
310
  );
287
- const circuitVerifier = config.realProofs
288
- ? await BBCircuitVerifier.new(config)
289
- : new TestCircuitVerifier(config.proverTestVerificationDelayMs);
311
+ const circuitVerifier =
312
+ config.realProofs || config.debugForceTxProofVerification
313
+ ? await BBCircuitVerifier.new(config)
314
+ : new TestCircuitVerifier(config.proverTestVerificationDelayMs);
290
315
  if (!config.realProofs) {
291
316
  log.warn(`Aztec node is accepting fake proofs`);
292
317
  }
@@ -330,6 +355,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
330
355
  blockSource: archiver,
331
356
  l1ToL2MessageSource: archiver,
332
357
  keyStoreManager,
358
+ fileStoreBlobUploadClient: fileStoreUploadClient,
333
359
  });
334
360
 
335
361
  // If we have a validator client, register it as a source of offenses for the slasher,
@@ -403,7 +429,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
403
429
  // Validator enabled, create/start relevant service
404
430
  let sequencer: SequencerClient | undefined;
405
431
  let slasherClient: SlasherClientInterface | undefined;
406
- if (!config.disableValidator) {
432
+ if (!config.disableValidator && validatorClient) {
407
433
  // We create a slasher only if we have a sequencer, since all slashing actions go through the sequencer publisher
408
434
  // as they are executed when the node is selected as proposer.
409
435
  const validatorAddresses = keyStoreManager
@@ -422,14 +448,29 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
422
448
  );
423
449
  await slasherClient.start();
424
450
 
425
- const l1TxUtils = await createL1TxUtilsWithBlobsFromEthSigner(
426
- publicClient,
427
- keyStoreManager!.createAllValidatorPublisherSigners(),
428
- { ...config, scope: 'sequencer' },
429
- { telemetry, logger: log.createChild('l1-tx-utils'), dateProvider },
430
- );
451
+ const l1TxUtils = config.publisherForwarderAddress
452
+ ? await createForwarderL1TxUtilsFromEthSigner(
453
+ publicClient,
454
+ keyStoreManager!.createAllValidatorPublisherSigners(),
455
+ config.publisherForwarderAddress,
456
+ { ...config, scope: 'sequencer' },
457
+ { telemetry, logger: log.createChild('l1-tx-utils'), dateProvider },
458
+ )
459
+ : await createL1TxUtilsWithBlobsFromEthSigner(
460
+ publicClient,
461
+ keyStoreManager!.createAllValidatorPublisherSigners(),
462
+ { ...config, scope: 'sequencer' },
463
+ { telemetry, logger: log.createChild('l1-tx-utils'), dateProvider },
464
+ );
431
465
 
432
466
  // Create and start the sequencer client
467
+ const checkpointsBuilder = new CheckpointsBuilder(
468
+ { ...config, l1GenesisTime, slotDuration: Number(slotDuration) },
469
+ archiver,
470
+ dateProvider,
471
+ telemetry,
472
+ );
473
+
433
474
  sequencer = await SequencerClient.new(config, {
434
475
  ...deps,
435
476
  epochCache,
@@ -438,12 +479,12 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
438
479
  p2pClient,
439
480
  worldStateSynchronizer,
440
481
  slasherClient,
441
- blockBuilder,
482
+ checkpointsBuilder,
442
483
  l2BlockSource: archiver,
443
484
  l1ToL2MessageSource: archiver,
444
485
  telemetry,
445
486
  dateProvider,
446
- blobSinkClient,
487
+ blobClient,
447
488
  nodeKeyStore: keyStoreManager!,
448
489
  });
449
490
  }
@@ -455,6 +496,13 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
455
496
  log.warn(`Sequencer created but not started`);
456
497
  }
457
498
 
499
+ const globalVariableBuilder = new GlobalVariableBuilder({
500
+ ...config,
501
+ rollupVersion: BigInt(config.rollupVersion),
502
+ l1GenesisTime,
503
+ slotDuration: Number(slotDuration),
504
+ });
505
+
458
506
  return new AztecNodeService(
459
507
  config,
460
508
  p2pClient,
@@ -469,12 +517,13 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
469
517
  epochPruneWatcher,
470
518
  ethereumChain.chainInfo.id,
471
519
  config.rollupVersion,
472
- new GlobalVariableBuilder(config),
520
+ globalVariableBuilder,
473
521
  epochCache,
474
522
  packageVersion,
475
523
  proofVerifier,
476
524
  telemetry,
477
525
  log,
526
+ blobClient,
478
527
  );
479
528
  }
480
529
 
@@ -549,8 +598,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
549
598
  * @param number - The block number being requested.
550
599
  * @returns The requested block.
551
600
  */
552
- public async getBlock(number: L2BlockNumber): Promise<L2Block | undefined> {
553
- const blockNumber = number === 'latest' ? await this.getBlockNumber() : number;
601
+ public async getBlock(number: BlockParameter): Promise<L2Block | undefined> {
602
+ const blockNumber = number === 'latest' ? await this.getBlockNumber() : (number as BlockNumber);
554
603
  return await this.blockSource.getBlock(blockNumber);
555
604
  }
556
605
 
@@ -580,11 +629,11 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
580
629
  * @param limit - The maximum number of blocks to obtain.
581
630
  * @returns The blocks requested.
582
631
  */
583
- public async getBlocks(from: number, limit: number): Promise<L2Block[]> {
632
+ public async getBlocks(from: BlockNumber, limit: number): Promise<L2Block[]> {
584
633
  return (await this.blockSource.getBlocks(from, limit)) ?? [];
585
634
  }
586
635
 
587
- public async getPublishedBlocks(from: number, limit: number): Promise<PublishedL2Block[]> {
636
+ public async getPublishedBlocks(from: BlockNumber, limit: number): Promise<PublishedL2Block[]> {
588
637
  return (await this.blockSource.getPublishedBlocks(from, limit)) ?? [];
589
638
  }
590
639
 
@@ -608,11 +657,11 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
608
657
  * Method to fetch the latest block number synchronized by the node.
609
658
  * @returns The block number.
610
659
  */
611
- public async getBlockNumber(): Promise<number> {
660
+ public async getBlockNumber(): Promise<BlockNumber> {
612
661
  return await this.blockSource.getBlockNumber();
613
662
  }
614
663
 
615
- public async getProvenBlockNumber(): Promise<number> {
664
+ public async getProvenBlockNumber(): Promise<BlockNumber> {
616
665
  return await this.blockSource.getProvenBlockNumber();
617
666
  }
618
667
 
@@ -648,25 +697,12 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
648
697
  return this.contractDataSource.getContract(address);
649
698
  }
650
699
 
651
- /**
652
- * Retrieves all private logs from up to `limit` blocks, starting from the block number `from`.
653
- * @param from - The block number from which to begin retrieving logs.
654
- * @param limit - The maximum number of blocks to retrieve logs from.
655
- * @returns An array of private logs from the specified range of blocks.
656
- */
657
- public getPrivateLogs(from: number, limit: number): Promise<PrivateLog[]> {
658
- return this.logsSource.getPrivateLogs(from, limit);
700
+ public getPrivateLogsByTags(tags: SiloedTag[]): Promise<TxScopedL2Log[][]> {
701
+ return this.logsSource.getPrivateLogsByTags(tags);
659
702
  }
660
703
 
661
- /**
662
- * Gets all logs that match any of the received tags (i.e. logs with their first field equal to a tag).
663
- * @param tags - The tags to filter the logs by.
664
- * @param logsPerTag - The maximum number of logs to return for each tag. By default no limit is set
665
- * @returns For each received tag, an array of matching logs is returned. An empty array implies no logs match
666
- * that tag.
667
- */
668
- public getLogsByTags(tags: Fr[], logsPerTag?: number): Promise<TxScopedL2Log[][]> {
669
- return this.logsSource.getLogsByTags(tags, logsPerTag);
704
+ public getPublicLogsByTagsFromContract(contractAddress: AztecAddress, tags: Tag[]): Promise<TxScopedL2Log[][]> {
705
+ return this.logsSource.getPublicLogsByTagsFromContract(contractAddress, tags);
670
706
  }
671
707
 
672
708
  /**
@@ -747,6 +783,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
747
783
  await tryStop(this.p2pClient);
748
784
  await tryStop(this.worldStateSynchronizer);
749
785
  await tryStop(this.blockSource);
786
+ await tryStop(this.blobClient);
750
787
  await tryStop(this.telemetry);
751
788
  this.log.info(`Stopped Aztec Node`);
752
789
  }
@@ -792,10 +829,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
792
829
  * @returns The indices of leaves and the block metadata of a block in which the leaves were inserted.
793
830
  */
794
831
  public async findLeavesIndexes(
795
- blockNumber: L2BlockNumber,
832
+ blockNumber: BlockParameter,
796
833
  treeId: MerkleTreeId,
797
834
  leafValues: Fr[],
798
- ): Promise<(InBlock<bigint> | undefined)[]> {
835
+ ): Promise<(DataInBlock<bigint> | undefined)[]> {
799
836
  const committedDb = await this.#getWorldState(blockNumber);
800
837
  const maybeIndices = await committedDb.findLeafIndices(
801
838
  treeId,
@@ -821,7 +858,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
821
858
  // (note that block number corresponds to the leaf index in the archive tree).
822
859
  const blockHashes = await Promise.all(
823
860
  uniqueBlockNumbers.map(blockNumber => {
824
- return committedDb.getLeafValue(MerkleTreeId.ARCHIVE, blockNumber!);
861
+ return committedDb.getLeafValue(MerkleTreeId.ARCHIVE, BigInt(blockNumber));
825
862
  }),
826
863
  );
827
864
 
@@ -832,7 +869,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
832
869
  }
833
870
  }
834
871
 
835
- // Create InBlock objects by combining indices, blockNumbers and blockHashes and return them.
872
+ // Create DataInBlock objects by combining indices, blockNumbers and blockHashes and return them.
836
873
  return maybeIndices.map((index, i) => {
837
874
  if (index === undefined) {
838
875
  return undefined;
@@ -847,7 +884,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
847
884
  return undefined;
848
885
  }
849
886
  return {
850
- l2BlockNumber: Number(blockNumber),
887
+ l2BlockNumber: BlockNumber(Number(blockNumber)),
851
888
  l2BlockHash: L2BlockHash.fromField(blockHash),
852
889
  data: index,
853
890
  };
@@ -861,7 +898,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
861
898
  * @returns The sibling path for the leaf index.
862
899
  */
863
900
  public async getNullifierSiblingPath(
864
- blockNumber: L2BlockNumber,
901
+ blockNumber: BlockParameter,
865
902
  leafIndex: bigint,
866
903
  ): Promise<SiblingPath<typeof NULLIFIER_TREE_HEIGHT>> {
867
904
  const committedDb = await this.#getWorldState(blockNumber);
@@ -875,7 +912,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
875
912
  * @returns The sibling path for the leaf index.
876
913
  */
877
914
  public async getNoteHashSiblingPath(
878
- blockNumber: L2BlockNumber,
915
+ blockNumber: BlockParameter,
879
916
  leafIndex: bigint,
880
917
  ): Promise<SiblingPath<typeof NOTE_HASH_TREE_HEIGHT>> {
881
918
  const committedDb = await this.#getWorldState(blockNumber);
@@ -883,7 +920,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
883
920
  }
884
921
 
885
922
  public async getArchiveMembershipWitness(
886
- blockNumber: L2BlockNumber,
923
+ blockNumber: BlockParameter,
887
924
  archive: Fr,
888
925
  ): Promise<MembershipWitness<typeof ARCHIVE_HEIGHT> | undefined> {
889
926
  const committedDb = await this.#getWorldState(blockNumber);
@@ -894,7 +931,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
894
931
  }
895
932
 
896
933
  public async getNoteHashMembershipWitness(
897
- blockNumber: L2BlockNumber,
934
+ blockNumber: BlockParameter,
898
935
  noteHash: Fr,
899
936
  ): Promise<MembershipWitness<typeof NOTE_HASH_TREE_HEIGHT> | undefined> {
900
937
  const committedDb = await this.#getWorldState(blockNumber);
@@ -914,7 +951,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
914
951
  * @returns A tuple of the index and the sibling path of the L1ToL2Message (undefined if not found).
915
952
  */
916
953
  public async getL1ToL2MessageMembershipWitness(
917
- blockNumber: L2BlockNumber,
954
+ blockNumber: BlockParameter,
918
955
  l1ToL2Message: Fr,
919
956
  ): Promise<[bigint, SiblingPath<typeof L1_TO_L2_MSG_TREE_HEIGHT>] | undefined> {
920
957
  const db = await this.#getWorldState(blockNumber);
@@ -927,9 +964,11 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
927
964
  return [witness.index, witness.path];
928
965
  }
929
966
 
930
- public async getL1ToL2MessageBlock(l1ToL2Message: Fr): Promise<number | undefined> {
967
+ public async getL1ToL2MessageBlock(l1ToL2Message: Fr): Promise<BlockNumber | undefined> {
931
968
  const messageIndex = await this.l1ToL2MessageSource.getL1ToL2MessageIndex(l1ToL2Message);
932
- return messageIndex ? InboxLeaf.l2BlockFromIndex(messageIndex) : undefined;
969
+ return messageIndex
970
+ ? BlockNumber.fromCheckpointNumber(InboxLeaf.checkpointNumberFromIndex(messageIndex))
971
+ : undefined;
933
972
  }
934
973
 
935
974
  /**
@@ -947,8 +986,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
947
986
  * @param blockNumber - The block number at which to get the data.
948
987
  * @returns The L2 to L1 messages (undefined if the block number is not found).
949
988
  */
950
- public async getL2ToL1Messages(blockNumber: L2BlockNumber): Promise<Fr[][] | undefined> {
951
- const block = await this.blockSource.getBlock(blockNumber === 'latest' ? await this.getBlockNumber() : blockNumber);
989
+ public async getL2ToL1Messages(blockNumber: BlockParameter): Promise<Fr[][] | undefined> {
990
+ const block = await this.blockSource.getBlock(
991
+ blockNumber === 'latest' ? await this.getBlockNumber() : (blockNumber as BlockNumber),
992
+ );
952
993
  return block?.body.txEffects.map(txEffect => txEffect.l2ToL1Msgs);
953
994
  }
954
995
 
@@ -959,7 +1000,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
959
1000
  * @returns The sibling path.
960
1001
  */
961
1002
  public async getArchiveSiblingPath(
962
- blockNumber: L2BlockNumber,
1003
+ blockNumber: BlockParameter,
963
1004
  leafIndex: bigint,
964
1005
  ): Promise<SiblingPath<typeof ARCHIVE_HEIGHT>> {
965
1006
  const committedDb = await this.#getWorldState(blockNumber);
@@ -973,7 +1014,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
973
1014
  * @returns The sibling path.
974
1015
  */
975
1016
  public async getPublicDataSiblingPath(
976
- blockNumber: L2BlockNumber,
1017
+ blockNumber: BlockParameter,
977
1018
  leafIndex: bigint,
978
1019
  ): Promise<SiblingPath<typeof PUBLIC_DATA_TREE_HEIGHT>> {
979
1020
  const committedDb = await this.#getWorldState(blockNumber);
@@ -987,7 +1028,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
987
1028
  * @returns The nullifier membership witness (if found).
988
1029
  */
989
1030
  public async getNullifierMembershipWitness(
990
- blockNumber: L2BlockNumber,
1031
+ blockNumber: BlockParameter,
991
1032
  nullifier: Fr,
992
1033
  ): Promise<NullifierMembershipWitness | undefined> {
993
1034
  const db = await this.#getWorldState(blockNumber);
@@ -1020,7 +1061,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1020
1061
  * TODO: This is a confusing behavior and we should eventually address that.
1021
1062
  */
1022
1063
  public async getLowNullifierMembershipWitness(
1023
- blockNumber: L2BlockNumber,
1064
+ blockNumber: BlockParameter,
1024
1065
  nullifier: Fr,
1025
1066
  ): Promise<NullifierMembershipWitness | undefined> {
1026
1067
  const committedDb = await this.#getWorldState(blockNumber);
@@ -1038,7 +1079,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1038
1079
  return new NullifierMembershipWitness(BigInt(index), preimageData as NullifierLeafPreimage, siblingPath);
1039
1080
  }
1040
1081
 
1041
- async getPublicDataWitness(blockNumber: L2BlockNumber, leafSlot: Fr): Promise<PublicDataWitness | undefined> {
1082
+ async getPublicDataWitness(blockNumber: BlockParameter, leafSlot: Fr): Promise<PublicDataWitness | undefined> {
1042
1083
  const committedDb = await this.#getWorldState(blockNumber);
1043
1084
  const lowLeafResult = await committedDb.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot.toBigInt());
1044
1085
  if (!lowLeafResult) {
@@ -1064,7 +1105,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1064
1105
  * @param blockNumber - The block number at which to get the data or 'latest'.
1065
1106
  * @returns Storage value at the given contract slot.
1066
1107
  */
1067
- public async getPublicStorageAt(blockNumber: L2BlockNumber, contract: AztecAddress, slot: Fr): Promise<Fr> {
1108
+ public async getPublicStorageAt(blockNumber: BlockParameter, contract: AztecAddress, slot: Fr): Promise<Fr> {
1068
1109
  const committedDb = await this.#getWorldState(blockNumber);
1069
1110
  const leafSlot = await computePublicDataTreeLeafSlot(contract, slot);
1070
1111
 
@@ -1083,10 +1124,11 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1083
1124
  * Returns the currently committed block header, or the initial header if no blocks have been produced.
1084
1125
  * @returns The current committed block header.
1085
1126
  */
1086
- public async getBlockHeader(blockNumber: L2BlockNumber = 'latest'): Promise<BlockHeader | undefined> {
1087
- return blockNumber === 0 || (blockNumber === 'latest' && (await this.blockSource.getBlockNumber()) === 0)
1127
+ public async getBlockHeader(blockNumber: BlockParameter = 'latest'): Promise<BlockHeader | undefined> {
1128
+ return blockNumber === BlockNumber.ZERO ||
1129
+ (blockNumber === 'latest' && (await this.blockSource.getBlockNumber()) === BlockNumber.ZERO)
1088
1130
  ? this.worldStateSynchronizer.getCommitted().getInitialHeader()
1089
- : this.blockSource.getBlockHeader(blockNumber);
1131
+ : this.blockSource.getBlockHeader(blockNumber === 'latest' ? blockNumber : (blockNumber as BlockNumber));
1090
1132
  }
1091
1133
 
1092
1134
  /**
@@ -1130,7 +1172,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1130
1172
  }
1131
1173
 
1132
1174
  const txHash = tx.getTxHash();
1133
- const blockNumber = (await this.blockSource.getBlockNumber()) + 1;
1175
+ const blockNumber = BlockNumber((await this.blockSource.getBlockNumber()) + 1);
1134
1176
 
1135
1177
  // If sequencer is not initialized, we just set these values to zero for simulation.
1136
1178
  const coinbase = EthAddress.ZERO;
@@ -1160,8 +1202,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1160
1202
  collectDebugLogs: true,
1161
1203
  collectHints: false,
1162
1204
  collectCallMetadata: true,
1163
- maxDebugLogMemoryReads: this.config.rpcSimulatePublicMaxDebugLogMemoryReads,
1164
1205
  collectStatistics: false,
1206
+ collectionLimits: CollectionLimitsConfig.from({
1207
+ maxDebugLogMemoryReads: this.config.rpcSimulatePublicMaxDebugLogMemoryReads,
1208
+ }),
1165
1209
  });
1166
1210
  const processor = publicProcessorFactory.create(merkleTreeFork, newGlobalVariables, config);
1167
1211
 
@@ -1195,7 +1239,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1195
1239
 
1196
1240
  // We accept transactions if they are not expired by the next slot (checked based on the IncludeByTimestamp field)
1197
1241
  const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
1198
- const blockNumber = (await this.blockSource.getBlockNumber()) + 1;
1242
+ const blockNumber = BlockNumber((await this.blockSource.getBlockNumber()) + 1);
1199
1243
  const validator = createValidatorForAcceptingTxs(db, this.contractDataSource, verifier, {
1200
1244
  timestamp: nextSlotTimestamp,
1201
1245
  blockNumber,
@@ -1302,7 +1346,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1302
1346
  return Promise.resolve();
1303
1347
  }
1304
1348
 
1305
- public async rollbackTo(targetBlock: number, force?: boolean): Promise<void> {
1349
+ public async rollbackTo(targetBlock: BlockNumber, force?: boolean): Promise<void> {
1306
1350
  const archiver = this.blockSource as Archiver;
1307
1351
  if (!('rollbackTo' in archiver)) {
1308
1352
  throw new Error('Archiver implementation does not support rollbacks.');
@@ -1374,12 +1418,12 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1374
1418
  * @param blockNumber - The block number at which to get the data.
1375
1419
  * @returns An instance of a committed MerkleTreeOperations
1376
1420
  */
1377
- async #getWorldState(blockNumber: L2BlockNumber) {
1421
+ async #getWorldState(blockNumber: BlockParameter) {
1378
1422
  if (typeof blockNumber === 'number' && blockNumber < INITIAL_L2_BLOCK_NUM - 1) {
1379
1423
  throw new Error('Invalid block number to get world state for: ' + blockNumber);
1380
1424
  }
1381
1425
 
1382
- let blockSyncedTo: number = 0;
1426
+ let blockSyncedTo: BlockNumber = BlockNumber.ZERO;
1383
1427
  try {
1384
1428
  // Attempt to sync the world state if necessary
1385
1429
  blockSyncedTo = await this.#syncWorldState();
@@ -1393,7 +1437,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1393
1437
  return this.worldStateSynchronizer.getCommitted();
1394
1438
  } else if (blockNumber <= blockSyncedTo) {
1395
1439
  this.log.debug(`Using snapshot for block ${blockNumber}, world state synced upto ${blockSyncedTo}`);
1396
- return this.worldStateSynchronizer.getSnapshot(blockNumber);
1440
+ return this.worldStateSynchronizer.getSnapshot(blockNumber as BlockNumber);
1397
1441
  } else {
1398
1442
  throw new Error(`Block ${blockNumber} not yet synced`);
1399
1443
  }
@@ -1403,8 +1447,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1403
1447
  * Ensure we fully sync the world state
1404
1448
  * @returns A promise that fulfils once the world state is synced
1405
1449
  */
1406
- async #syncWorldState(): Promise<number> {
1450
+ async #syncWorldState(): Promise<BlockNumber> {
1407
1451
  const blockSourceHeight = await this.blockSource.getBlockNumber();
1408
- return this.worldStateSynchronizer.syncImmediate(blockSourceHeight);
1452
+ return await this.worldStateSynchronizer.syncImmediate(blockSourceHeight);
1409
1453
  }
1410
1454
  }
@@ -1,5 +1,5 @@
1
1
  import type { EpochCache } from '@aztec/epoch-cache';
2
- import { EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
2
+ import { BlockNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
3
3
  import { countWhile, filterAsync, fromEntries, getEntries, mapValues } from '@aztec/foundation/collection';
4
4
  import { EthAddress } from '@aztec/foundation/eth-address';
5
5
  import { createLogger } from '@aztec/foundation/log';
@@ -44,7 +44,7 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme
44
44
  protected initialSlot: SlotNumber | undefined;
45
45
  protected lastProcessedSlot: SlotNumber | undefined;
46
46
  // eslint-disable-next-line aztec-custom/no-non-primitive-in-collections
47
- protected slotNumberToBlock: Map<SlotNumber, { blockNumber: number; archive: string; attestors: EthAddress[] }> =
47
+ protected slotNumberToBlock: Map<SlotNumber, { blockNumber: BlockNumber; archive: string; attestors: EthAddress[] }> =
48
48
  new Map();
49
49
 
50
50
  constructor(
@@ -76,7 +76,7 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme
76
76
  /** Loads initial slot and initializes blockstream. We will not process anything at or before the initial slot. */
77
77
  protected async init() {
78
78
  this.initialSlot = this.epochCache.getEpochAndSlotNow().slot;
79
- const startingBlock = await this.archiver.getBlockNumber();
79
+ const startingBlock = BlockNumber(await this.archiver.getBlockNumber());
80
80
  this.logger.info(`Starting validator sentinel with initial slot ${this.initialSlot} and block ${startingBlock}`);
81
81
  this.blockStream = new L2BlockStream(this.archiver, this.l2TipsStore, this, this.logger, { startingBlock });
82
82
  }
@@ -91,7 +91,7 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme
91
91
  // Store mapping from slot to archive, block number, and attestors
92
92
  for (const block of event.blocks) {
93
93
  this.slotNumberToBlock.set(block.block.header.getSlot(), {
94
- blockNumber: block.block.number,
94
+ blockNumber: BlockNumber(block.block.number),
95
95
  archive: block.block.archive.root.toString(),
96
96
  attestors: getAttestationInfoFromPublishedL2Block(block)
97
97
  .filter(a => a.status === 'recovered-from-signature')
@@ -118,7 +118,7 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme
118
118
  if (event.type !== 'chain-proven') {
119
119
  return;
120
120
  }
121
- const blockNumber = event.block.number;
121
+ const blockNumber = BlockNumber(event.block.number);
122
122
  const block = await this.archiver.getBlock(blockNumber);
123
123
  if (!block) {
124
124
  this.logger.error(`Failed to get block ${blockNumber}`, { block });