@aztec/aztec-node 0.0.1-commit.b655e406 → 0.0.1-commit.c7c42ec

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,25 +15,25 @@ 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';
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';
20
23
  import { compactArray, pick } from '@aztec/foundation/collection';
24
+ import { Fr } from '@aztec/foundation/curves/bn254';
21
25
  import { EthAddress } from '@aztec/foundation/eth-address';
22
- import { Fr } from '@aztec/foundation/fields';
23
26
  import { BadRequestError } from '@aztec/foundation/json-rpc';
24
27
  import { type Logger, createLogger } from '@aztec/foundation/log';
25
- import { SerialQueue } from '@aztec/foundation/queue';
26
28
  import { count } from '@aztec/foundation/string';
27
29
  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,12 +52,13 @@ import {
46
52
  type Watcher,
47
53
  createSlasher,
48
54
  } from '@aztec/slasher';
55
+ import { CollectionLimitsConfig, PublicSimulatorConfig } from '@aztec/stdlib/avm';
49
56
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
50
57
  import {
51
- type InBlock,
58
+ type BlockParameter,
59
+ type DataInBlock,
52
60
  type L2Block,
53
61
  L2BlockHash,
54
- type L2BlockNumber,
55
62
  type L2BlockSource,
56
63
  type PublishedL2Block,
57
64
  } from '@aztec/stdlib/block';
@@ -62,7 +69,7 @@ import type {
62
69
  NodeInfo,
63
70
  ProtocolContractAddresses,
64
71
  } from '@aztec/stdlib/contract';
65
- import type { GasFees } from '@aztec/stdlib/gas';
72
+ import { GasFees } from '@aztec/stdlib/gas';
66
73
  import { computePublicDataTreeLeafSlot } from '@aztec/stdlib/hash';
67
74
  import {
68
75
  type AztecNode,
@@ -81,7 +88,7 @@ import {
81
88
  type WorldStateSynchronizer,
82
89
  tryStop,
83
90
  } from '@aztec/stdlib/interfaces/server';
84
- import type { LogFilter, PrivateLog, TxScopedL2Log } from '@aztec/stdlib/logs';
91
+ import type { LogFilter, SiloedTag, Tag, TxScopedL2Log } from '@aztec/stdlib/logs';
85
92
  import { InboxLeaf, type L1ToL2MessageSource } from '@aztec/stdlib/messaging';
86
93
  import { P2PClientType } from '@aztec/stdlib/p2p';
87
94
  import type { Offense, SlashPayloadRound } from '@aztec/stdlib/slashing';
@@ -132,9 +139,6 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
132
139
  // Prevent two snapshot operations to happen simultaneously
133
140
  private isUploadingSnapshot = false;
134
141
 
135
- // Serial queue to ensure that we only send one tx at a time
136
- private txQueue: SerialQueue = new SerialQueue();
137
-
138
142
  public readonly tracer: Tracer;
139
143
 
140
144
  constructor(
@@ -157,10 +161,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
157
161
  private proofVerifier: ClientProtocolCircuitVerifier,
158
162
  private telemetry: TelemetryClient = getTelemetryClient(),
159
163
  private log = createLogger('node'),
164
+ private blobClient?: BlobClientInterface,
160
165
  ) {
161
166
  this.metrics = new NodeMetrics(telemetry, 'AztecNodeService');
162
167
  this.tracer = telemetry.getTracer('AztecNodeService');
163
- this.txQueue.start();
164
168
 
165
169
  this.log.info(`Aztec Node version: ${this.packageVersion}`);
166
170
  this.log.info(`Aztec Node started on chain 0x${l1ChainId.toString(16)}`, config.l1Contracts);
@@ -187,7 +191,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
187
191
  logger?: Logger;
188
192
  publisher?: SequencerPublisher;
189
193
  dateProvider?: DateProvider;
190
- blobSinkClient?: BlobSinkClientInterface;
194
+ blobClient?: BlobClientInterface;
191
195
  p2pClientDeps?: P2PClientDeps<P2PClientType.Full>;
192
196
  } = {},
193
197
  options: {
@@ -200,8 +204,6 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
200
204
  const packageVersion = getPackageVersion() ?? '';
201
205
  const telemetry = deps.telemetry ?? getTelemetryClient();
202
206
  const dateProvider = deps.dateProvider ?? new DateProvider();
203
- const blobSinkClient =
204
- deps.blobSinkClient ?? createBlobSinkClient(config, { logger: createLogger('node:blob-sink:client') });
205
207
  const ethereumChain = createEthereumChain(config.l1RpcUrls, config.l1ChainId);
206
208
 
207
209
  // Build a key store from file if given or from environment otherwise
@@ -241,7 +243,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
241
243
 
242
244
  const publicClient = createPublicClient({
243
245
  chain: ethereumChain.chainInfo,
244
- transport: fallback(config.l1RpcUrls.map((url: string) => http(url))),
246
+ transport: fallback(config.l1RpcUrls.map((url: string) => http(url, { batch: false }))),
245
247
  pollingInterval: config.viemPollingIntervalMS,
246
248
  });
247
249
 
@@ -269,6 +271,25 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
269
271
  );
270
272
  }
271
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
+
272
293
  // attempt snapshot sync if possible
273
294
  await trySnapshotSync(config, log);
274
295
 
@@ -276,7 +297,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
276
297
 
277
298
  const archiver = await createArchiver(
278
299
  config,
279
- { blobSinkClient, epochCache, telemetry, dateProvider },
300
+ { blobClient, epochCache, telemetry, dateProvider },
280
301
  { blockUntilSync: !config.skipArchiverInitialSync },
281
302
  );
282
303
 
@@ -287,7 +308,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
287
308
  options.prefilledPublicData,
288
309
  telemetry,
289
310
  );
290
- const circuitVerifier = config.realProofs ? await BBCircuitVerifier.new(config) : new TestCircuitVerifier();
311
+ const circuitVerifier =
312
+ config.realProofs || config.debugForceTxProofVerification
313
+ ? await BBCircuitVerifier.new(config)
314
+ : new TestCircuitVerifier(config.proverTestVerificationDelayMs);
291
315
  if (!config.realProofs) {
292
316
  log.warn(`Aztec node is accepting fake proofs`);
293
317
  }
@@ -331,6 +355,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
331
355
  blockSource: archiver,
332
356
  l1ToL2MessageSource: archiver,
333
357
  keyStoreManager,
358
+ fileStoreBlobUploadClient: fileStoreUploadClient,
334
359
  });
335
360
 
336
361
  // If we have a validator client, register it as a source of offenses for the slasher,
@@ -404,7 +429,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
404
429
  // Validator enabled, create/start relevant service
405
430
  let sequencer: SequencerClient | undefined;
406
431
  let slasherClient: SlasherClientInterface | undefined;
407
- if (!config.disableValidator) {
432
+ if (!config.disableValidator && validatorClient) {
408
433
  // We create a slasher only if we have a sequencer, since all slashing actions go through the sequencer publisher
409
434
  // as they are executed when the node is selected as proposer.
410
435
  const validatorAddresses = keyStoreManager
@@ -423,14 +448,29 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
423
448
  );
424
449
  await slasherClient.start();
425
450
 
426
- const l1TxUtils = await createL1TxUtilsWithBlobsFromEthSigner(
427
- publicClient,
428
- keyStoreManager!.createAllValidatorPublisherSigners(),
429
- { ...config, scope: 'sequencer' },
430
- { telemetry, logger: log.createChild('l1-tx-utils'), dateProvider },
431
- );
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
+ );
432
465
 
433
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
+
434
474
  sequencer = await SequencerClient.new(config, {
435
475
  ...deps,
436
476
  epochCache,
@@ -439,12 +479,12 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
439
479
  p2pClient,
440
480
  worldStateSynchronizer,
441
481
  slasherClient,
442
- blockBuilder,
482
+ checkpointsBuilder,
443
483
  l2BlockSource: archiver,
444
484
  l1ToL2MessageSource: archiver,
445
485
  telemetry,
446
486
  dateProvider,
447
- blobSinkClient,
487
+ blobClient,
448
488
  nodeKeyStore: keyStoreManager!,
449
489
  });
450
490
  }
@@ -456,6 +496,13 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
456
496
  log.warn(`Sequencer created but not started`);
457
497
  }
458
498
 
499
+ const globalVariableBuilder = new GlobalVariableBuilder({
500
+ ...config,
501
+ rollupVersion: BigInt(config.rollupVersion),
502
+ l1GenesisTime,
503
+ slotDuration: Number(slotDuration),
504
+ });
505
+
459
506
  return new AztecNodeService(
460
507
  config,
461
508
  p2pClient,
@@ -470,12 +517,13 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
470
517
  epochPruneWatcher,
471
518
  ethereumChain.chainInfo.id,
472
519
  config.rollupVersion,
473
- new GlobalVariableBuilder(config),
520
+ globalVariableBuilder,
474
521
  epochCache,
475
522
  packageVersion,
476
523
  proofVerifier,
477
524
  telemetry,
478
525
  log,
526
+ blobClient,
479
527
  );
480
528
  }
481
529
 
@@ -550,8 +598,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
550
598
  * @param number - The block number being requested.
551
599
  * @returns The requested block.
552
600
  */
553
- public async getBlock(number: L2BlockNumber): Promise<L2Block | undefined> {
554
- 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);
555
603
  return await this.blockSource.getBlock(blockNumber);
556
604
  }
557
605
 
@@ -581,11 +629,11 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
581
629
  * @param limit - The maximum number of blocks to obtain.
582
630
  * @returns The blocks requested.
583
631
  */
584
- public async getBlocks(from: number, limit: number): Promise<L2Block[]> {
632
+ public async getBlocks(from: BlockNumber, limit: number): Promise<L2Block[]> {
585
633
  return (await this.blockSource.getBlocks(from, limit)) ?? [];
586
634
  }
587
635
 
588
- public async getPublishedBlocks(from: number, limit: number): Promise<PublishedL2Block[]> {
636
+ public async getPublishedBlocks(from: BlockNumber, limit: number): Promise<PublishedL2Block[]> {
589
637
  return (await this.blockSource.getPublishedBlocks(from, limit)) ?? [];
590
638
  }
591
639
 
@@ -597,15 +645,23 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
597
645
  return await this.globalVariableBuilder.getCurrentBaseFees();
598
646
  }
599
647
 
648
+ public async getMaxPriorityFees(): Promise<GasFees> {
649
+ for await (const tx of this.p2pClient.iteratePendingTxs()) {
650
+ return tx.getGasSettings().maxPriorityFeesPerGas;
651
+ }
652
+
653
+ return GasFees.from({ feePerDaGas: 0n, feePerL2Gas: 0n });
654
+ }
655
+
600
656
  /**
601
657
  * Method to fetch the latest block number synchronized by the node.
602
658
  * @returns The block number.
603
659
  */
604
- public async getBlockNumber(): Promise<number> {
660
+ public async getBlockNumber(): Promise<BlockNumber> {
605
661
  return await this.blockSource.getBlockNumber();
606
662
  }
607
663
 
608
- public async getProvenBlockNumber(): Promise<number> {
664
+ public async getProvenBlockNumber(): Promise<BlockNumber> {
609
665
  return await this.blockSource.getProvenBlockNumber();
610
666
  }
611
667
 
@@ -641,25 +697,12 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
641
697
  return this.contractDataSource.getContract(address);
642
698
  }
643
699
 
644
- /**
645
- * Retrieves all private logs from up to `limit` blocks, starting from the block number `from`.
646
- * @param from - The block number from which to begin retrieving logs.
647
- * @param limit - The maximum number of blocks to retrieve logs from.
648
- * @returns An array of private logs from the specified range of blocks.
649
- */
650
- public getPrivateLogs(from: number, limit: number): Promise<PrivateLog[]> {
651
- return this.logsSource.getPrivateLogs(from, limit);
700
+ public getPrivateLogsByTags(tags: SiloedTag[]): Promise<TxScopedL2Log[][]> {
701
+ return this.logsSource.getPrivateLogsByTags(tags);
652
702
  }
653
703
 
654
- /**
655
- * Gets all logs that match any of the received tags (i.e. logs with their first field equal to a tag).
656
- * @param tags - The tags to filter the logs by.
657
- * @param logsPerTag - The maximum number of logs to return for each tag. By default no limit is set
658
- * @returns For each received tag, an array of matching logs is returned. An empty array implies no logs match
659
- * that tag.
660
- */
661
- public getLogsByTags(tags: Fr[], logsPerTag?: number): Promise<TxScopedL2Log[][]> {
662
- return this.logsSource.getLogsByTags(tags, logsPerTag);
704
+ public getPublicLogsByTagsFromContract(contractAddress: AztecAddress, tags: Tag[]): Promise<TxScopedL2Log[][]> {
705
+ return this.logsSource.getPublicLogsByTagsFromContract(contractAddress, tags);
663
706
  }
664
707
 
665
708
  /**
@@ -685,7 +728,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
685
728
  * @param tx - The transaction to be submitted.
686
729
  */
687
730
  public async sendTx(tx: Tx) {
688
- await this.txQueue.put(() => this.#sendTx(tx));
731
+ await this.#sendTx(tx);
689
732
  }
690
733
 
691
734
  async #sendTx(tx: Tx) {
@@ -732,7 +775,6 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
732
775
  */
733
776
  public async stop() {
734
777
  this.log.info(`Stopping Aztec Node`);
735
- await this.txQueue.end();
736
778
  await tryStop(this.validatorsSentinel);
737
779
  await tryStop(this.epochPruneWatcher);
738
780
  await tryStop(this.slasherClient);
@@ -741,6 +783,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
741
783
  await tryStop(this.p2pClient);
742
784
  await tryStop(this.worldStateSynchronizer);
743
785
  await tryStop(this.blockSource);
786
+ await tryStop(this.blobClient);
744
787
  await tryStop(this.telemetry);
745
788
  this.log.info(`Stopped Aztec Node`);
746
789
  }
@@ -786,10 +829,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
786
829
  * @returns The indices of leaves and the block metadata of a block in which the leaves were inserted.
787
830
  */
788
831
  public async findLeavesIndexes(
789
- blockNumber: L2BlockNumber,
832
+ blockNumber: BlockParameter,
790
833
  treeId: MerkleTreeId,
791
834
  leafValues: Fr[],
792
- ): Promise<(InBlock<bigint> | undefined)[]> {
835
+ ): Promise<(DataInBlock<bigint> | undefined)[]> {
793
836
  const committedDb = await this.#getWorldState(blockNumber);
794
837
  const maybeIndices = await committedDb.findLeafIndices(
795
838
  treeId,
@@ -815,7 +858,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
815
858
  // (note that block number corresponds to the leaf index in the archive tree).
816
859
  const blockHashes = await Promise.all(
817
860
  uniqueBlockNumbers.map(blockNumber => {
818
- return committedDb.getLeafValue(MerkleTreeId.ARCHIVE, blockNumber!);
861
+ return committedDb.getLeafValue(MerkleTreeId.ARCHIVE, BigInt(blockNumber));
819
862
  }),
820
863
  );
821
864
 
@@ -826,7 +869,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
826
869
  }
827
870
  }
828
871
 
829
- // 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.
830
873
  return maybeIndices.map((index, i) => {
831
874
  if (index === undefined) {
832
875
  return undefined;
@@ -841,7 +884,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
841
884
  return undefined;
842
885
  }
843
886
  return {
844
- l2BlockNumber: Number(blockNumber),
887
+ l2BlockNumber: BlockNumber(Number(blockNumber)),
845
888
  l2BlockHash: L2BlockHash.fromField(blockHash),
846
889
  data: index,
847
890
  };
@@ -855,7 +898,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
855
898
  * @returns The sibling path for the leaf index.
856
899
  */
857
900
  public async getNullifierSiblingPath(
858
- blockNumber: L2BlockNumber,
901
+ blockNumber: BlockParameter,
859
902
  leafIndex: bigint,
860
903
  ): Promise<SiblingPath<typeof NULLIFIER_TREE_HEIGHT>> {
861
904
  const committedDb = await this.#getWorldState(blockNumber);
@@ -869,7 +912,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
869
912
  * @returns The sibling path for the leaf index.
870
913
  */
871
914
  public async getNoteHashSiblingPath(
872
- blockNumber: L2BlockNumber,
915
+ blockNumber: BlockParameter,
873
916
  leafIndex: bigint,
874
917
  ): Promise<SiblingPath<typeof NOTE_HASH_TREE_HEIGHT>> {
875
918
  const committedDb = await this.#getWorldState(blockNumber);
@@ -877,7 +920,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
877
920
  }
878
921
 
879
922
  public async getArchiveMembershipWitness(
880
- blockNumber: L2BlockNumber,
923
+ blockNumber: BlockParameter,
881
924
  archive: Fr,
882
925
  ): Promise<MembershipWitness<typeof ARCHIVE_HEIGHT> | undefined> {
883
926
  const committedDb = await this.#getWorldState(blockNumber);
@@ -888,7 +931,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
888
931
  }
889
932
 
890
933
  public async getNoteHashMembershipWitness(
891
- blockNumber: L2BlockNumber,
934
+ blockNumber: BlockParameter,
892
935
  noteHash: Fr,
893
936
  ): Promise<MembershipWitness<typeof NOTE_HASH_TREE_HEIGHT> | undefined> {
894
937
  const committedDb = await this.#getWorldState(blockNumber);
@@ -908,7 +951,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
908
951
  * @returns A tuple of the index and the sibling path of the L1ToL2Message (undefined if not found).
909
952
  */
910
953
  public async getL1ToL2MessageMembershipWitness(
911
- blockNumber: L2BlockNumber,
954
+ blockNumber: BlockParameter,
912
955
  l1ToL2Message: Fr,
913
956
  ): Promise<[bigint, SiblingPath<typeof L1_TO_L2_MSG_TREE_HEIGHT>] | undefined> {
914
957
  const db = await this.#getWorldState(blockNumber);
@@ -921,9 +964,11 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
921
964
  return [witness.index, witness.path];
922
965
  }
923
966
 
924
- public async getL1ToL2MessageBlock(l1ToL2Message: Fr): Promise<number | undefined> {
967
+ public async getL1ToL2MessageBlock(l1ToL2Message: Fr): Promise<BlockNumber | undefined> {
925
968
  const messageIndex = await this.l1ToL2MessageSource.getL1ToL2MessageIndex(l1ToL2Message);
926
- return messageIndex ? InboxLeaf.l2BlockFromIndex(messageIndex) : undefined;
969
+ return messageIndex
970
+ ? BlockNumber.fromCheckpointNumber(InboxLeaf.checkpointNumberFromIndex(messageIndex))
971
+ : undefined;
927
972
  }
928
973
 
929
974
  /**
@@ -941,8 +986,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
941
986
  * @param blockNumber - The block number at which to get the data.
942
987
  * @returns The L2 to L1 messages (undefined if the block number is not found).
943
988
  */
944
- public async getL2ToL1Messages(blockNumber: L2BlockNumber): Promise<Fr[][] | undefined> {
945
- 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
+ );
946
993
  return block?.body.txEffects.map(txEffect => txEffect.l2ToL1Msgs);
947
994
  }
948
995
 
@@ -953,7 +1000,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
953
1000
  * @returns The sibling path.
954
1001
  */
955
1002
  public async getArchiveSiblingPath(
956
- blockNumber: L2BlockNumber,
1003
+ blockNumber: BlockParameter,
957
1004
  leafIndex: bigint,
958
1005
  ): Promise<SiblingPath<typeof ARCHIVE_HEIGHT>> {
959
1006
  const committedDb = await this.#getWorldState(blockNumber);
@@ -967,7 +1014,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
967
1014
  * @returns The sibling path.
968
1015
  */
969
1016
  public async getPublicDataSiblingPath(
970
- blockNumber: L2BlockNumber,
1017
+ blockNumber: BlockParameter,
971
1018
  leafIndex: bigint,
972
1019
  ): Promise<SiblingPath<typeof PUBLIC_DATA_TREE_HEIGHT>> {
973
1020
  const committedDb = await this.#getWorldState(blockNumber);
@@ -981,7 +1028,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
981
1028
  * @returns The nullifier membership witness (if found).
982
1029
  */
983
1030
  public async getNullifierMembershipWitness(
984
- blockNumber: L2BlockNumber,
1031
+ blockNumber: BlockParameter,
985
1032
  nullifier: Fr,
986
1033
  ): Promise<NullifierMembershipWitness | undefined> {
987
1034
  const db = await this.#getWorldState(blockNumber);
@@ -1014,7 +1061,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1014
1061
  * TODO: This is a confusing behavior and we should eventually address that.
1015
1062
  */
1016
1063
  public async getLowNullifierMembershipWitness(
1017
- blockNumber: L2BlockNumber,
1064
+ blockNumber: BlockParameter,
1018
1065
  nullifier: Fr,
1019
1066
  ): Promise<NullifierMembershipWitness | undefined> {
1020
1067
  const committedDb = await this.#getWorldState(blockNumber);
@@ -1032,7 +1079,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1032
1079
  return new NullifierMembershipWitness(BigInt(index), preimageData as NullifierLeafPreimage, siblingPath);
1033
1080
  }
1034
1081
 
1035
- async getPublicDataWitness(blockNumber: L2BlockNumber, leafSlot: Fr): Promise<PublicDataWitness | undefined> {
1082
+ async getPublicDataWitness(blockNumber: BlockParameter, leafSlot: Fr): Promise<PublicDataWitness | undefined> {
1036
1083
  const committedDb = await this.#getWorldState(blockNumber);
1037
1084
  const lowLeafResult = await committedDb.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot.toBigInt());
1038
1085
  if (!lowLeafResult) {
@@ -1058,7 +1105,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1058
1105
  * @param blockNumber - The block number at which to get the data or 'latest'.
1059
1106
  * @returns Storage value at the given contract slot.
1060
1107
  */
1061
- public async getPublicStorageAt(blockNumber: L2BlockNumber, contract: AztecAddress, slot: Fr): Promise<Fr> {
1108
+ public async getPublicStorageAt(blockNumber: BlockParameter, contract: AztecAddress, slot: Fr): Promise<Fr> {
1062
1109
  const committedDb = await this.#getWorldState(blockNumber);
1063
1110
  const leafSlot = await computePublicDataTreeLeafSlot(contract, slot);
1064
1111
 
@@ -1077,10 +1124,11 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1077
1124
  * Returns the currently committed block header, or the initial header if no blocks have been produced.
1078
1125
  * @returns The current committed block header.
1079
1126
  */
1080
- public async getBlockHeader(blockNumber: L2BlockNumber = 'latest'): Promise<BlockHeader | undefined> {
1081
- 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)
1082
1130
  ? this.worldStateSynchronizer.getCommitted().getInitialHeader()
1083
- : this.blockSource.getBlockHeader(blockNumber);
1131
+ : this.blockSource.getBlockHeader(blockNumber === 'latest' ? blockNumber : (blockNumber as BlockNumber));
1084
1132
  }
1085
1133
 
1086
1134
  /**
@@ -1124,7 +1172,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1124
1172
  }
1125
1173
 
1126
1174
  const txHash = tx.getTxHash();
1127
- const blockNumber = (await this.blockSource.getBlockNumber()) + 1;
1175
+ const blockNumber = BlockNumber((await this.blockSource.getBlockNumber()) + 1);
1128
1176
 
1129
1177
  // If sequencer is not initialized, we just set these values to zero for simulation.
1130
1178
  const coinbase = EthAddress.ZERO;
@@ -1149,11 +1197,17 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1149
1197
 
1150
1198
  const merkleTreeFork = await this.worldStateSynchronizer.fork();
1151
1199
  try {
1152
- const processor = publicProcessorFactory.create(merkleTreeFork, newGlobalVariables, {
1200
+ const config = PublicSimulatorConfig.from({
1153
1201
  skipFeeEnforcement,
1154
- clientInitiatedSimulation: true,
1155
- maxDebugLogMemoryReads: this.config.rpcSimulatePublicMaxDebugLogMemoryReads,
1202
+ collectDebugLogs: true,
1203
+ collectHints: false,
1204
+ collectCallMetadata: true,
1205
+ collectStatistics: false,
1206
+ collectionLimits: CollectionLimitsConfig.from({
1207
+ maxDebugLogMemoryReads: this.config.rpcSimulatePublicMaxDebugLogMemoryReads,
1208
+ }),
1156
1209
  });
1210
+ const processor = publicProcessorFactory.create(merkleTreeFork, newGlobalVariables, config);
1157
1211
 
1158
1212
  // REFACTOR: Consider merging ProcessReturnValues into ProcessedTx
1159
1213
  const [processedTxs, failedTxs, _usedTxs, returns] = await processor.process([tx]);
@@ -1185,7 +1239,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1185
1239
 
1186
1240
  // We accept transactions if they are not expired by the next slot (checked based on the IncludeByTimestamp field)
1187
1241
  const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
1188
- const blockNumber = (await this.blockSource.getBlockNumber()) + 1;
1242
+ const blockNumber = BlockNumber((await this.blockSource.getBlockNumber()) + 1);
1189
1243
  const validator = createValidatorForAcceptingTxs(db, this.contractDataSource, verifier, {
1190
1244
  timestamp: nextSlotTimestamp,
1191
1245
  blockNumber,
@@ -1242,8 +1296,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1242
1296
 
1243
1297
  public getValidatorStats(
1244
1298
  validatorAddress: EthAddress,
1245
- fromSlot?: bigint,
1246
- toSlot?: bigint,
1299
+ fromSlot?: SlotNumber,
1300
+ toSlot?: SlotNumber,
1247
1301
  ): Promise<SingleValidatorStats | undefined> {
1248
1302
  return this.validatorsSentinel?.getValidatorStats(validatorAddress, fromSlot, toSlot) ?? Promise.resolve(undefined);
1249
1303
  }
@@ -1292,7 +1346,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1292
1346
  return Promise.resolve();
1293
1347
  }
1294
1348
 
1295
- public async rollbackTo(targetBlock: number, force?: boolean): Promise<void> {
1349
+ public async rollbackTo(targetBlock: BlockNumber, force?: boolean): Promise<void> {
1296
1350
  const archiver = this.blockSource as Archiver;
1297
1351
  if (!('rollbackTo' in archiver)) {
1298
1352
  throw new Error('Archiver implementation does not support rollbacks.');
@@ -1364,12 +1418,12 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1364
1418
  * @param blockNumber - The block number at which to get the data.
1365
1419
  * @returns An instance of a committed MerkleTreeOperations
1366
1420
  */
1367
- async #getWorldState(blockNumber: L2BlockNumber) {
1421
+ async #getWorldState(blockNumber: BlockParameter) {
1368
1422
  if (typeof blockNumber === 'number' && blockNumber < INITIAL_L2_BLOCK_NUM - 1) {
1369
1423
  throw new Error('Invalid block number to get world state for: ' + blockNumber);
1370
1424
  }
1371
1425
 
1372
- let blockSyncedTo: number = 0;
1426
+ let blockSyncedTo: BlockNumber = BlockNumber.ZERO;
1373
1427
  try {
1374
1428
  // Attempt to sync the world state if necessary
1375
1429
  blockSyncedTo = await this.#syncWorldState();
@@ -1383,7 +1437,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1383
1437
  return this.worldStateSynchronizer.getCommitted();
1384
1438
  } else if (blockNumber <= blockSyncedTo) {
1385
1439
  this.log.debug(`Using snapshot for block ${blockNumber}, world state synced upto ${blockSyncedTo}`);
1386
- return this.worldStateSynchronizer.getSnapshot(blockNumber);
1440
+ return this.worldStateSynchronizer.getSnapshot(blockNumber as BlockNumber);
1387
1441
  } else {
1388
1442
  throw new Error(`Block ${blockNumber} not yet synced`);
1389
1443
  }
@@ -1393,8 +1447,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1393
1447
  * Ensure we fully sync the world state
1394
1448
  * @returns A promise that fulfils once the world state is synced
1395
1449
  */
1396
- async #syncWorldState(): Promise<number> {
1450
+ async #syncWorldState(): Promise<BlockNumber> {
1397
1451
  const blockSourceHeight = await this.blockSource.getBlockNumber();
1398
- return this.worldStateSynchronizer.syncImmediate(blockSourceHeight);
1452
+ return await this.worldStateSynchronizer.syncImmediate(blockSourceHeight);
1399
1453
  }
1400
1454
  }