@aztec/aztec-node 4.0.0-nightly.20250907 → 4.0.0-nightly.20260108

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
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, createBlobClientWithFileStores } from '@aztec/blob-client/client';
4
4
  import {
5
5
  ARCHIVE_HEIGHT,
6
6
  INITIAL_L2_BLOCK_NUM,
@@ -10,26 +10,25 @@ import {
10
10
  type PUBLIC_DATA_TREE_HEIGHT,
11
11
  } from '@aztec/constants';
12
12
  import { EpochCache, type EpochCacheInterface } from '@aztec/epoch-cache';
13
- import {
14
- type EthSigner,
15
- type L1ContractAddresses,
16
- RegistryContract,
17
- RollupContract,
18
- createEthereumChain,
19
- getPublicClient,
20
- } from '@aztec/ethereum';
21
- import { createL1TxUtilsWithBlobsFromEthSigner } from '@aztec/ethereum/l1-tx-utils-with-blobs';
13
+ import { createEthereumChain } from '@aztec/ethereum/chain';
14
+ import { getPublicClient } from '@aztec/ethereum/client';
15
+ import { RegistryContract, RollupContract } from '@aztec/ethereum/contracts';
16
+ import type { L1ContractAddresses } from '@aztec/ethereum/l1-contract-addresses';
17
+ import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types';
22
18
  import { compactArray, pick } from '@aztec/foundation/collection';
19
+ import { Fr } from '@aztec/foundation/curves/bn254';
23
20
  import { EthAddress } from '@aztec/foundation/eth-address';
24
- import { Fr } from '@aztec/foundation/fields';
25
21
  import { BadRequestError } from '@aztec/foundation/json-rpc';
26
22
  import { type Logger, createLogger } from '@aztec/foundation/log';
27
- import { SerialQueue } from '@aztec/foundation/queue';
28
23
  import { count } from '@aztec/foundation/string';
29
24
  import { DateProvider, Timer } from '@aztec/foundation/timer';
30
25
  import { MembershipWitness, SiblingPath } from '@aztec/foundation/trees';
31
26
  import { KeystoreManager, loadKeystores, mergeKeystores } from '@aztec/node-keystore';
32
27
  import { trySnapshotSync, uploadSnapshot } from '@aztec/node-lib/actions';
28
+ import {
29
+ createForwarderL1TxUtilsFromEthSigner,
30
+ createL1TxUtilsWithBlobsFromEthSigner,
31
+ } from '@aztec/node-lib/factories';
33
32
  import { type P2P, type P2PClientDeps, createP2PClient, getDefaultAllowedSetupFunctions } from '@aztec/p2p';
34
33
  import { ProtocolContractAddress } from '@aztec/protocol-contracts';
35
34
  import {
@@ -39,6 +38,7 @@ import {
39
38
  type SequencerPublisher,
40
39
  createValidatorForAcceptingTxs,
41
40
  } from '@aztec/sequencer-client';
41
+ import { CheckpointsBuilder } from '@aztec/sequencer-client';
42
42
  import { PublicProcessorFactory } from '@aztec/simulator/server';
43
43
  import {
44
44
  AttestationsBlockWatcher,
@@ -47,12 +47,13 @@ import {
47
47
  type Watcher,
48
48
  createSlasher,
49
49
  } from '@aztec/slasher';
50
+ import { CollectionLimitsConfig, PublicSimulatorConfig } from '@aztec/stdlib/avm';
50
51
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
51
52
  import {
52
- type InBlock,
53
+ type BlockParameter,
54
+ type DataInBlock,
53
55
  type L2Block,
54
56
  L2BlockHash,
55
- type L2BlockNumber,
56
57
  type L2BlockSource,
57
58
  type PublishedL2Block,
58
59
  } from '@aztec/stdlib/block';
@@ -63,7 +64,7 @@ import type {
63
64
  NodeInfo,
64
65
  ProtocolContractAddresses,
65
66
  } from '@aztec/stdlib/contract';
66
- import type { GasFees } from '@aztec/stdlib/gas';
67
+ import { GasFees } from '@aztec/stdlib/gas';
67
68
  import { computePublicDataTreeLeafSlot } from '@aztec/stdlib/hash';
68
69
  import {
69
70
  type AztecNode,
@@ -74,6 +75,7 @@ import {
74
75
  type GetPublicLogsResponse,
75
76
  } from '@aztec/stdlib/interfaces/client';
76
77
  import {
78
+ type AllowedElement,
77
79
  type ClientProtocolCircuitVerifier,
78
80
  type L2LogsSource,
79
81
  type Service,
@@ -81,8 +83,8 @@ import {
81
83
  type WorldStateSynchronizer,
82
84
  tryStop,
83
85
  } from '@aztec/stdlib/interfaces/server';
84
- import type { LogFilter, PrivateLog, TxScopedL2Log } from '@aztec/stdlib/logs';
85
- import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
86
+ import type { LogFilter, SiloedTag, Tag, TxScopedL2Log } from '@aztec/stdlib/logs';
87
+ import { InboxLeaf, type L1ToL2MessageSource } from '@aztec/stdlib/messaging';
86
88
  import { P2PClientType } from '@aztec/stdlib/p2p';
87
89
  import type { Offense, SlashPayloadRound } from '@aztec/stdlib/slashing';
88
90
  import type { NullifierLeafPreimage, PublicDataTreeLeaf, PublicDataTreeLeafPreimage } from '@aztec/stdlib/trees';
@@ -108,7 +110,12 @@ import {
108
110
  getTelemetryClient,
109
111
  trackSpan,
110
112
  } from '@aztec/telemetry-client';
111
- import { NodeKeystoreAdapter, ValidatorClient, createValidatorClient } from '@aztec/validator-client';
113
+ import {
114
+ NodeKeystoreAdapter,
115
+ ValidatorClient,
116
+ createBlockProposalHandler,
117
+ createValidatorClient,
118
+ } from '@aztec/validator-client';
112
119
  import { createWorldStateSynchronizer } from '@aztec/world-state';
113
120
 
114
121
  import { createPublicClient, fallback, http } from 'viem';
@@ -127,9 +134,6 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
127
134
  // Prevent two snapshot operations to happen simultaneously
128
135
  private isUploadingSnapshot = false;
129
136
 
130
- // Serial queue to ensure that we only send one tx at a time
131
- private txQueue: SerialQueue = new SerialQueue();
132
-
133
137
  public readonly tracer: Tracer;
134
138
 
135
139
  constructor(
@@ -152,10 +156,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
152
156
  private proofVerifier: ClientProtocolCircuitVerifier,
153
157
  private telemetry: TelemetryClient = getTelemetryClient(),
154
158
  private log = createLogger('node'),
159
+ private blobClient?: BlobClientInterface,
155
160
  ) {
156
161
  this.metrics = new NodeMetrics(telemetry, 'AztecNodeService');
157
162
  this.tracer = telemetry.getTracer('AztecNodeService');
158
- this.txQueue.start();
159
163
 
160
164
  this.log.info(`Aztec Node version: ${this.packageVersion}`);
161
165
  this.log.info(`Aztec Node started on chain 0x${l1ChainId.toString(16)}`, config.l1Contracts);
@@ -182,7 +186,6 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
182
186
  logger?: Logger;
183
187
  publisher?: SequencerPublisher;
184
188
  dateProvider?: DateProvider;
185
- blobSinkClient?: BlobSinkClientInterface;
186
189
  p2pClientDeps?: P2PClientDeps<P2PClientType.Full>;
187
190
  } = {},
188
191
  options: {
@@ -195,8 +198,6 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
195
198
  const packageVersion = getPackageVersion() ?? '';
196
199
  const telemetry = deps.telemetry ?? getTelemetryClient();
197
200
  const dateProvider = deps.dateProvider ?? new DateProvider();
198
- const blobSinkClient =
199
- deps.blobSinkClient ?? createBlobSinkClient(config, { logger: createLogger('node:blob-sink:client') });
200
201
  const ethereumChain = createEthereumChain(config.l1RpcUrls, config.l1ChainId);
201
202
 
202
203
  // Build a key store from file if given or from environment otherwise
@@ -212,6 +213,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
212
213
  }
213
214
  }
214
215
 
216
+ await keyStoreManager?.validateSigners();
217
+
215
218
  // If we are a validator, verify our configuration before doing too much more.
216
219
  if (!config.disableValidator) {
217
220
  if (keyStoreManager === undefined) {
@@ -222,7 +225,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
222
225
  'KEY STORE CREATED FROM ENVIRONMENT, IT IS RECOMMENDED TO USE A FILE-BASED KEY STORE IN PRODUCTION ENVIRONMENTS',
223
226
  );
224
227
  }
225
- ValidatorClient.validateKeyStoreConfiguration(keyStoreManager);
228
+ ValidatorClient.validateKeyStoreConfiguration(keyStoreManager, log);
226
229
  }
227
230
 
228
231
  // validate that the actual chain id matches that specified in configuration
@@ -234,7 +237,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
234
237
 
235
238
  const publicClient = createPublicClient({
236
239
  chain: ethereumChain.chainInfo,
237
- transport: fallback(config.l1RpcUrls.map((url: string) => http(url))),
240
+ transport: fallback(config.l1RpcUrls.map((url: string) => http(url, { batch: false }))),
238
241
  pollingInterval: config.viemPollingIntervalMS,
239
242
  });
240
243
 
@@ -262,6 +265,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
262
265
  );
263
266
  }
264
267
 
268
+ const blobClient = await createBlobClientWithFileStores(config, createLogger('node:blob-client:client'));
269
+
265
270
  // attempt snapshot sync if possible
266
271
  await trySnapshotSync(config, log);
267
272
 
@@ -269,8 +274,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
269
274
 
270
275
  const archiver = await createArchiver(
271
276
  config,
272
- { blobSinkClient, epochCache, telemetry, dateProvider },
273
- { blockUntilSync: true },
277
+ { blobClient, epochCache, telemetry, dateProvider },
278
+ { blockUntilSync: !config.skipArchiverInitialSync },
274
279
  );
275
280
 
276
281
  // now create the merkle trees and the world state synchronizer
@@ -280,7 +285,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
280
285
  options.prefilledPublicData,
281
286
  telemetry,
282
287
  );
283
- const circuitVerifier = config.realProofs ? await BBCircuitVerifier.new(config) : new TestCircuitVerifier();
288
+ const circuitVerifier =
289
+ config.realProofs || config.debugForceTxProofVerification
290
+ ? await BBCircuitVerifier.new(config)
291
+ : new TestCircuitVerifier(config.proverTestVerificationDelayMs);
284
292
  if (!config.realProofs) {
285
293
  log.warn(`Aztec node is accepting fake proofs`);
286
294
  }
@@ -300,12 +308,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
300
308
  deps.p2pClientDeps,
301
309
  );
302
310
 
303
- // Start world state and wait for it to sync to the archiver.
304
- await worldStateSynchronizer.start();
305
-
306
- // Start p2p. Note that it depends on world state to be running.
307
- await p2pClient.start();
308
-
311
+ // We should really not be modifying the config object
309
312
  config.txPublicSetupAllowList = config.txPublicSetupAllowList ?? (await getDefaultAllowedSetupFunctions());
310
313
 
311
314
  const blockBuilder = new BlockBuilder(
@@ -316,17 +319,58 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
316
319
  telemetry,
317
320
  );
318
321
 
322
+ // We'll accumulate sentinel watchers here
319
323
  const watchers: Watcher[] = [];
320
324
 
321
- const validatorsSentinel = await createSentinel(epochCache, archiver, p2pClient, config);
322
- if (validatorsSentinel) {
323
- // we can run a sentinel without trying to slash.
324
- await validatorsSentinel.start();
325
- if (config.slashInactivityPenalty > 0n) {
326
- watchers.push(validatorsSentinel);
325
+ // Create validator client if required
326
+ const validatorClient = createValidatorClient(config, {
327
+ p2pClient,
328
+ telemetry,
329
+ dateProvider,
330
+ epochCache,
331
+ blockBuilder,
332
+ blockSource: archiver,
333
+ l1ToL2MessageSource: archiver,
334
+ keyStoreManager,
335
+ blobClient,
336
+ });
337
+
338
+ // If we have a validator client, register it as a source of offenses for the slasher,
339
+ // and have it register callbacks on the p2p client *before* we start it, otherwise messages
340
+ // like attestations or auths will fail.
341
+ if (validatorClient) {
342
+ watchers.push(validatorClient);
343
+ if (!options.dontStartSequencer) {
344
+ await validatorClient.registerHandlers();
327
345
  }
328
346
  }
329
347
 
348
+ // If there's no validator client but alwaysReexecuteBlockProposals is enabled,
349
+ // create a BlockProposalHandler to reexecute block proposals for monitoring
350
+ if (!validatorClient && config.alwaysReexecuteBlockProposals) {
351
+ log.info('Setting up block proposal reexecution for monitoring');
352
+ createBlockProposalHandler(config, {
353
+ blockBuilder,
354
+ epochCache,
355
+ blockSource: archiver,
356
+ l1ToL2MessageSource: archiver,
357
+ p2pClient,
358
+ dateProvider,
359
+ telemetry,
360
+ }).registerForReexecution(p2pClient);
361
+ }
362
+
363
+ // Start world state and wait for it to sync to the archiver.
364
+ await worldStateSynchronizer.start();
365
+
366
+ // Start p2p. Note that it depends on world state to be running.
367
+ await p2pClient.start();
368
+
369
+ const validatorsSentinel = await createSentinel(epochCache, archiver, p2pClient, config);
370
+ if (validatorsSentinel && config.slashInactivityPenalty > 0n) {
371
+ watchers.push(validatorsSentinel);
372
+ }
373
+
330
374
  let epochPruneWatcher: EpochPruneWatcher | undefined;
331
375
  if (config.slashPrunePenalty > 0n || config.slashDataWithholdingPenalty > 0n) {
332
376
  epochPruneWatcher = new EpochPruneWatcher(
@@ -337,7 +381,6 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
337
381
  blockBuilder,
338
382
  config,
339
383
  );
340
- await epochPruneWatcher.start();
341
384
  watchers.push(epochPruneWatcher);
342
385
  }
343
386
 
@@ -345,32 +388,25 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
345
388
  let attestationsBlockWatcher: AttestationsBlockWatcher | undefined;
346
389
  if (config.slashProposeInvalidAttestationsPenalty > 0n || config.slashAttestDescendantOfInvalidPenalty > 0n) {
347
390
  attestationsBlockWatcher = new AttestationsBlockWatcher(archiver, epochCache, config);
348
- await attestationsBlockWatcher.start();
349
391
  watchers.push(attestationsBlockWatcher);
350
392
  }
351
393
 
352
- const validatorClient = createValidatorClient(config, {
353
- p2pClient,
354
- telemetry,
355
- dateProvider,
356
- epochCache,
357
- blockBuilder,
358
- blockSource: archiver,
359
- l1ToL2MessageSource: archiver,
360
- keyStoreManager,
361
- });
362
-
363
- if (validatorClient) {
364
- watchers.push(validatorClient);
365
- }
366
-
367
- log.verbose(`All Aztec Node subsystems synced`);
394
+ // Start p2p-related services once the archiver has completed sync
395
+ void archiver
396
+ .waitForInitialSync()
397
+ .then(async () => {
398
+ await p2pClient.start();
399
+ await validatorsSentinel?.start();
400
+ await epochPruneWatcher?.start();
401
+ await attestationsBlockWatcher?.start();
402
+ log.info(`All p2p services started`);
403
+ })
404
+ .catch(err => log.error('Failed to start p2p services after archiver sync', err));
368
405
 
369
406
  // Validator enabled, create/start relevant service
370
407
  let sequencer: SequencerClient | undefined;
371
408
  let slasherClient: SlasherClientInterface | undefined;
372
-
373
- if (!config.disableValidator) {
409
+ if (!config.disableValidator && validatorClient) {
374
410
  // We create a slasher only if we have a sequencer, since all slashing actions go through the sequencer publisher
375
411
  // as they are executed when the node is selected as proposer.
376
412
  const validatorAddresses = keyStoreManager
@@ -389,13 +425,30 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
389
425
  );
390
426
  await slasherClient.start();
391
427
 
392
- const l1TxUtils = keyStoreManager!.createAllValidatorPublisherSigners().map((signer: EthSigner) => {
393
- return createL1TxUtilsWithBlobsFromEthSigner(publicClient, signer, log, dateProvider, config);
394
- });
428
+ const l1TxUtils = config.publisherForwarderAddress
429
+ ? await createForwarderL1TxUtilsFromEthSigner(
430
+ publicClient,
431
+ keyStoreManager!.createAllValidatorPublisherSigners(),
432
+ config.publisherForwarderAddress,
433
+ { ...config, scope: 'sequencer' },
434
+ { telemetry, logger: log.createChild('l1-tx-utils'), dateProvider },
435
+ )
436
+ : await createL1TxUtilsWithBlobsFromEthSigner(
437
+ publicClient,
438
+ keyStoreManager!.createAllValidatorPublisherSigners(),
439
+ { ...config, scope: 'sequencer' },
440
+ { telemetry, logger: log.createChild('l1-tx-utils'), dateProvider },
441
+ );
442
+
443
+ // Create and start the sequencer client
444
+ const checkpointsBuilder = new CheckpointsBuilder(
445
+ { ...config, l1GenesisTime, slotDuration: Number(slotDuration) },
446
+ archiver,
447
+ dateProvider,
448
+ telemetry,
449
+ );
395
450
 
396
451
  sequencer = await SequencerClient.new(config, {
397
- // if deps were provided, they should override the defaults,
398
- // or things that we created in this function
399
452
  ...deps,
400
453
  epochCache,
401
454
  l1TxUtils,
@@ -403,12 +456,12 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
403
456
  p2pClient,
404
457
  worldStateSynchronizer,
405
458
  slasherClient,
406
- blockBuilder,
459
+ checkpointsBuilder,
407
460
  l2BlockSource: archiver,
408
461
  l1ToL2MessageSource: archiver,
409
462
  telemetry,
410
463
  dateProvider,
411
- blobSinkClient,
464
+ blobClient,
412
465
  nodeKeyStore: keyStoreManager!,
413
466
  });
414
467
  }
@@ -416,8 +469,17 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
416
469
  if (!options.dontStartSequencer && sequencer) {
417
470
  await sequencer.start();
418
471
  log.verbose(`Sequencer started`);
472
+ } else if (sequencer) {
473
+ log.warn(`Sequencer created but not started`);
419
474
  }
420
475
 
476
+ const globalVariableBuilder = new GlobalVariableBuilder({
477
+ ...config,
478
+ rollupVersion: BigInt(config.rollupVersion),
479
+ l1GenesisTime,
480
+ slotDuration: Number(slotDuration),
481
+ });
482
+
421
483
  return new AztecNodeService(
422
484
  config,
423
485
  p2pClient,
@@ -432,12 +494,13 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
432
494
  epochPruneWatcher,
433
495
  ethereumChain.chainInfo.id,
434
496
  config.rollupVersion,
435
- new GlobalVariableBuilder(config),
497
+ globalVariableBuilder,
436
498
  epochCache,
437
499
  packageVersion,
438
500
  proofVerifier,
439
501
  telemetry,
440
502
  log,
503
+ blobClient,
441
504
  );
442
505
  }
443
506
 
@@ -473,6 +536,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
473
536
  return Promise.resolve(this.p2pClient.getEnr()?.encodeTxt());
474
537
  }
475
538
 
539
+ public async getAllowedPublicSetup(): Promise<AllowedElement[]> {
540
+ return this.config.txPublicSetupAllowList ?? (await getDefaultAllowedSetupFunctions());
541
+ }
542
+
476
543
  /**
477
544
  * Method to determine if the node is ready to accept transactions.
478
545
  * @returns - Flag indicating the readiness for tx submission.
@@ -508,8 +575,29 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
508
575
  * @param number - The block number being requested.
509
576
  * @returns The requested block.
510
577
  */
511
- public async getBlock(number: number): Promise<L2Block | undefined> {
512
- return await this.blockSource.getBlock(number);
578
+ public async getBlock(number: BlockParameter): Promise<L2Block | undefined> {
579
+ const blockNumber = number === 'latest' ? await this.getBlockNumber() : (number as BlockNumber);
580
+ return await this.blockSource.getBlock(blockNumber);
581
+ }
582
+
583
+ /**
584
+ * Get a block specified by its hash.
585
+ * @param blockHash - The block hash being requested.
586
+ * @returns The requested block.
587
+ */
588
+ public async getBlockByHash(blockHash: Fr): Promise<L2Block | undefined> {
589
+ const publishedBlock = await this.blockSource.getPublishedBlockByHash(blockHash);
590
+ return publishedBlock?.block;
591
+ }
592
+
593
+ /**
594
+ * Get a block specified by its archive root.
595
+ * @param archive - The archive root being requested.
596
+ * @returns The requested block.
597
+ */
598
+ public async getBlockByArchive(archive: Fr): Promise<L2Block | undefined> {
599
+ const publishedBlock = await this.blockSource.getPublishedBlockByArchive(archive);
600
+ return publishedBlock?.block;
513
601
  }
514
602
 
515
603
  /**
@@ -518,31 +606,39 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
518
606
  * @param limit - The maximum number of blocks to obtain.
519
607
  * @returns The blocks requested.
520
608
  */
521
- public async getBlocks(from: number, limit: number): Promise<L2Block[]> {
609
+ public async getBlocks(from: BlockNumber, limit: number): Promise<L2Block[]> {
522
610
  return (await this.blockSource.getBlocks(from, limit)) ?? [];
523
611
  }
524
612
 
525
- public async getPublishedBlocks(from: number, limit: number): Promise<PublishedL2Block[]> {
613
+ public async getPublishedBlocks(from: BlockNumber, limit: number): Promise<PublishedL2Block[]> {
526
614
  return (await this.blockSource.getPublishedBlocks(from, limit)) ?? [];
527
615
  }
528
616
 
529
617
  /**
530
- * Method to fetch the current base fees.
531
- * @returns The current base fees.
618
+ * Method to fetch the current min L2 fees.
619
+ * @returns The current min L2 fees.
532
620
  */
533
- public async getCurrentBaseFees(): Promise<GasFees> {
534
- return await this.globalVariableBuilder.getCurrentBaseFees();
621
+ public async getCurrentMinFees(): Promise<GasFees> {
622
+ return await this.globalVariableBuilder.getCurrentMinFees();
623
+ }
624
+
625
+ public async getMaxPriorityFees(): Promise<GasFees> {
626
+ for await (const tx of this.p2pClient.iteratePendingTxs()) {
627
+ return tx.getGasSettings().maxPriorityFeesPerGas;
628
+ }
629
+
630
+ return GasFees.from({ feePerDaGas: 0n, feePerL2Gas: 0n });
535
631
  }
536
632
 
537
633
  /**
538
634
  * Method to fetch the latest block number synchronized by the node.
539
635
  * @returns The block number.
540
636
  */
541
- public async getBlockNumber(): Promise<number> {
637
+ public async getBlockNumber(): Promise<BlockNumber> {
542
638
  return await this.blockSource.getBlockNumber();
543
639
  }
544
640
 
545
- public async getProvenBlockNumber(): Promise<number> {
641
+ public async getProvenBlockNumber(): Promise<BlockNumber> {
546
642
  return await this.blockSource.getProvenBlockNumber();
547
643
  }
548
644
 
@@ -578,25 +674,12 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
578
674
  return this.contractDataSource.getContract(address);
579
675
  }
580
676
 
581
- /**
582
- * Retrieves all private logs from up to `limit` blocks, starting from the block number `from`.
583
- * @param from - The block number from which to begin retrieving logs.
584
- * @param limit - The maximum number of blocks to retrieve logs from.
585
- * @returns An array of private logs from the specified range of blocks.
586
- */
587
- public getPrivateLogs(from: number, limit: number): Promise<PrivateLog[]> {
588
- return this.logsSource.getPrivateLogs(from, limit);
677
+ public getPrivateLogsByTags(tags: SiloedTag[]): Promise<TxScopedL2Log[][]> {
678
+ return this.logsSource.getPrivateLogsByTags(tags);
589
679
  }
590
680
 
591
- /**
592
- * Gets all logs that match any of the received tags (i.e. logs with their first field equal to a tag).
593
- * @param tags - The tags to filter the logs by.
594
- * @param logsPerTag - The maximum number of logs to return for each tag. By default no limit is set
595
- * @returns For each received tag, an array of matching logs is returned. An empty array implies no logs match
596
- * that tag.
597
- */
598
- public getLogsByTags(tags: Fr[], logsPerTag?: number): Promise<TxScopedL2Log[][]> {
599
- return this.logsSource.getLogsByTags(tags, logsPerTag);
681
+ public getPublicLogsByTagsFromContract(contractAddress: AztecAddress, tags: Tag[]): Promise<TxScopedL2Log[][]> {
682
+ return this.logsSource.getPublicLogsByTagsFromContract(contractAddress, tags);
600
683
  }
601
684
 
602
685
  /**
@@ -622,7 +705,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
622
705
  * @param tx - The transaction to be submitted.
623
706
  */
624
707
  public async sendTx(tx: Tx) {
625
- await this.txQueue.put(() => this.#sendTx(tx));
708
+ await this.#sendTx(tx);
626
709
  }
627
710
 
628
711
  async #sendTx(tx: Tx) {
@@ -669,7 +752,6 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
669
752
  */
670
753
  public async stop() {
671
754
  this.log.info(`Stopping Aztec Node`);
672
- await this.txQueue.end();
673
755
  await tryStop(this.validatorsSentinel);
674
756
  await tryStop(this.epochPruneWatcher);
675
757
  await tryStop(this.slasherClient);
@@ -678,10 +760,19 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
678
760
  await tryStop(this.p2pClient);
679
761
  await tryStop(this.worldStateSynchronizer);
680
762
  await tryStop(this.blockSource);
763
+ await tryStop(this.blobClient);
681
764
  await tryStop(this.telemetry);
682
765
  this.log.info(`Stopped Aztec Node`);
683
766
  }
684
767
 
768
+ /**
769
+ * Returns the blob client used by this node.
770
+ * @internal - Exposed for testing purposes only.
771
+ */
772
+ public getBlobClient(): BlobClientInterface | undefined {
773
+ return this.blobClient;
774
+ }
775
+
685
776
  /**
686
777
  * Method to retrieve pending txs.
687
778
  * @param limit - The number of items to returns
@@ -723,10 +814,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
723
814
  * @returns The indices of leaves and the block metadata of a block in which the leaves were inserted.
724
815
  */
725
816
  public async findLeavesIndexes(
726
- blockNumber: L2BlockNumber,
817
+ blockNumber: BlockParameter,
727
818
  treeId: MerkleTreeId,
728
819
  leafValues: Fr[],
729
- ): Promise<(InBlock<bigint> | undefined)[]> {
820
+ ): Promise<(DataInBlock<bigint> | undefined)[]> {
730
821
  const committedDb = await this.#getWorldState(blockNumber);
731
822
  const maybeIndices = await committedDb.findLeafIndices(
732
823
  treeId,
@@ -752,7 +843,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
752
843
  // (note that block number corresponds to the leaf index in the archive tree).
753
844
  const blockHashes = await Promise.all(
754
845
  uniqueBlockNumbers.map(blockNumber => {
755
- return committedDb.getLeafValue(MerkleTreeId.ARCHIVE, blockNumber!);
846
+ return committedDb.getLeafValue(MerkleTreeId.ARCHIVE, BigInt(blockNumber));
756
847
  }),
757
848
  );
758
849
 
@@ -763,7 +854,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
763
854
  }
764
855
  }
765
856
 
766
- // Create InBlock objects by combining indices, blockNumbers and blockHashes and return them.
857
+ // Create DataInBlock objects by combining indices, blockNumbers and blockHashes and return them.
767
858
  return maybeIndices.map((index, i) => {
768
859
  if (index === undefined) {
769
860
  return undefined;
@@ -778,7 +869,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
778
869
  return undefined;
779
870
  }
780
871
  return {
781
- l2BlockNumber: Number(blockNumber),
872
+ l2BlockNumber: BlockNumber(Number(blockNumber)),
782
873
  l2BlockHash: L2BlockHash.fromField(blockHash),
783
874
  data: index,
784
875
  };
@@ -792,7 +883,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
792
883
  * @returns The sibling path for the leaf index.
793
884
  */
794
885
  public async getNullifierSiblingPath(
795
- blockNumber: L2BlockNumber,
886
+ blockNumber: BlockParameter,
796
887
  leafIndex: bigint,
797
888
  ): Promise<SiblingPath<typeof NULLIFIER_TREE_HEIGHT>> {
798
889
  const committedDb = await this.#getWorldState(blockNumber);
@@ -806,7 +897,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
806
897
  * @returns The sibling path for the leaf index.
807
898
  */
808
899
  public async getNoteHashSiblingPath(
809
- blockNumber: L2BlockNumber,
900
+ blockNumber: BlockParameter,
810
901
  leafIndex: bigint,
811
902
  ): Promise<SiblingPath<typeof NOTE_HASH_TREE_HEIGHT>> {
812
903
  const committedDb = await this.#getWorldState(blockNumber);
@@ -814,7 +905,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
814
905
  }
815
906
 
816
907
  public async getArchiveMembershipWitness(
817
- blockNumber: L2BlockNumber,
908
+ blockNumber: BlockParameter,
818
909
  archive: Fr,
819
910
  ): Promise<MembershipWitness<typeof ARCHIVE_HEIGHT> | undefined> {
820
911
  const committedDb = await this.#getWorldState(blockNumber);
@@ -825,7 +916,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
825
916
  }
826
917
 
827
918
  public async getNoteHashMembershipWitness(
828
- blockNumber: L2BlockNumber,
919
+ blockNumber: BlockParameter,
829
920
  noteHash: Fr,
830
921
  ): Promise<MembershipWitness<typeof NOTE_HASH_TREE_HEIGHT> | undefined> {
831
922
  const committedDb = await this.#getWorldState(blockNumber);
@@ -845,7 +936,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
845
936
  * @returns A tuple of the index and the sibling path of the L1ToL2Message (undefined if not found).
846
937
  */
847
938
  public async getL1ToL2MessageMembershipWitness(
848
- blockNumber: L2BlockNumber,
939
+ blockNumber: BlockParameter,
849
940
  l1ToL2Message: Fr,
850
941
  ): Promise<[bigint, SiblingPath<typeof L1_TO_L2_MSG_TREE_HEIGHT>] | undefined> {
851
942
  const db = await this.#getWorldState(blockNumber);
@@ -858,13 +949,21 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
858
949
  return [witness.index, witness.path];
859
950
  }
860
951
 
952
+ public async getL1ToL2MessageBlock(l1ToL2Message: Fr): Promise<BlockNumber | undefined> {
953
+ const messageIndex = await this.l1ToL2MessageSource.getL1ToL2MessageIndex(l1ToL2Message);
954
+ return messageIndex
955
+ ? BlockNumber.fromCheckpointNumber(InboxLeaf.checkpointNumberFromIndex(messageIndex))
956
+ : undefined;
957
+ }
958
+
861
959
  /**
862
960
  * Returns whether an L1 to L2 message is synced by archiver and if it's ready to be included in a block.
863
961
  * @param l1ToL2Message - The L1 to L2 message to check.
864
962
  * @returns Whether the message is synced and ready to be included in a block.
865
963
  */
866
964
  public async isL1ToL2MessageSynced(l1ToL2Message: Fr): Promise<boolean> {
867
- return (await this.l1ToL2MessageSource.getL1ToL2MessageIndex(l1ToL2Message)) !== undefined;
965
+ const messageIndex = await this.l1ToL2MessageSource.getL1ToL2MessageIndex(l1ToL2Message);
966
+ return messageIndex !== undefined;
868
967
  }
869
968
 
870
969
  /**
@@ -872,8 +971,10 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
872
971
  * @param blockNumber - The block number at which to get the data.
873
972
  * @returns The L2 to L1 messages (undefined if the block number is not found).
874
973
  */
875
- public async getL2ToL1Messages(blockNumber: L2BlockNumber): Promise<Fr[][] | undefined> {
876
- const block = await this.blockSource.getBlock(blockNumber === 'latest' ? await this.getBlockNumber() : blockNumber);
974
+ public async getL2ToL1Messages(blockNumber: BlockParameter): Promise<Fr[][] | undefined> {
975
+ const block = await this.blockSource.getBlock(
976
+ blockNumber === 'latest' ? await this.getBlockNumber() : (blockNumber as BlockNumber),
977
+ );
877
978
  return block?.body.txEffects.map(txEffect => txEffect.l2ToL1Msgs);
878
979
  }
879
980
 
@@ -884,7 +985,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
884
985
  * @returns The sibling path.
885
986
  */
886
987
  public async getArchiveSiblingPath(
887
- blockNumber: L2BlockNumber,
988
+ blockNumber: BlockParameter,
888
989
  leafIndex: bigint,
889
990
  ): Promise<SiblingPath<typeof ARCHIVE_HEIGHT>> {
890
991
  const committedDb = await this.#getWorldState(blockNumber);
@@ -898,7 +999,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
898
999
  * @returns The sibling path.
899
1000
  */
900
1001
  public async getPublicDataSiblingPath(
901
- blockNumber: L2BlockNumber,
1002
+ blockNumber: BlockParameter,
902
1003
  leafIndex: bigint,
903
1004
  ): Promise<SiblingPath<typeof PUBLIC_DATA_TREE_HEIGHT>> {
904
1005
  const committedDb = await this.#getWorldState(blockNumber);
@@ -912,7 +1013,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
912
1013
  * @returns The nullifier membership witness (if found).
913
1014
  */
914
1015
  public async getNullifierMembershipWitness(
915
- blockNumber: L2BlockNumber,
1016
+ blockNumber: BlockParameter,
916
1017
  nullifier: Fr,
917
1018
  ): Promise<NullifierMembershipWitness | undefined> {
918
1019
  const db = await this.#getWorldState(blockNumber);
@@ -945,7 +1046,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
945
1046
  * TODO: This is a confusing behavior and we should eventually address that.
946
1047
  */
947
1048
  public async getLowNullifierMembershipWitness(
948
- blockNumber: L2BlockNumber,
1049
+ blockNumber: BlockParameter,
949
1050
  nullifier: Fr,
950
1051
  ): Promise<NullifierMembershipWitness | undefined> {
951
1052
  const committedDb = await this.#getWorldState(blockNumber);
@@ -963,7 +1064,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
963
1064
  return new NullifierMembershipWitness(BigInt(index), preimageData as NullifierLeafPreimage, siblingPath);
964
1065
  }
965
1066
 
966
- async getPublicDataWitness(blockNumber: L2BlockNumber, leafSlot: Fr): Promise<PublicDataWitness | undefined> {
1067
+ async getPublicDataWitness(blockNumber: BlockParameter, leafSlot: Fr): Promise<PublicDataWitness | undefined> {
967
1068
  const committedDb = await this.#getWorldState(blockNumber);
968
1069
  const lowLeafResult = await committedDb.getPreviousValueIndex(MerkleTreeId.PUBLIC_DATA_TREE, leafSlot.toBigInt());
969
1070
  if (!lowLeafResult) {
@@ -989,7 +1090,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
989
1090
  * @param blockNumber - The block number at which to get the data or 'latest'.
990
1091
  * @returns Storage value at the given contract slot.
991
1092
  */
992
- public async getPublicStorageAt(blockNumber: L2BlockNumber, contract: AztecAddress, slot: Fr): Promise<Fr> {
1093
+ public async getPublicStorageAt(blockNumber: BlockParameter, contract: AztecAddress, slot: Fr): Promise<Fr> {
993
1094
  const committedDb = await this.#getWorldState(blockNumber);
994
1095
  const leafSlot = await computePublicDataTreeLeafSlot(contract, slot);
995
1096
 
@@ -1008,10 +1109,29 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1008
1109
  * Returns the currently committed block header, or the initial header if no blocks have been produced.
1009
1110
  * @returns The current committed block header.
1010
1111
  */
1011
- public async getBlockHeader(blockNumber: L2BlockNumber = 'latest'): Promise<BlockHeader | undefined> {
1012
- return blockNumber === 0 || (blockNumber === 'latest' && (await this.blockSource.getBlockNumber()) === 0)
1112
+ public async getBlockHeader(blockNumber: BlockParameter = 'latest'): Promise<BlockHeader | undefined> {
1113
+ return blockNumber === BlockNumber.ZERO ||
1114
+ (blockNumber === 'latest' && (await this.blockSource.getBlockNumber()) === BlockNumber.ZERO)
1013
1115
  ? this.worldStateSynchronizer.getCommitted().getInitialHeader()
1014
- : this.blockSource.getBlockHeader(blockNumber);
1116
+ : this.blockSource.getBlockHeader(blockNumber === 'latest' ? blockNumber : (blockNumber as BlockNumber));
1117
+ }
1118
+
1119
+ /**
1120
+ * Get a block header specified by its hash.
1121
+ * @param blockHash - The block hash being requested.
1122
+ * @returns The requested block header.
1123
+ */
1124
+ public async getBlockHeaderByHash(blockHash: Fr): Promise<BlockHeader | undefined> {
1125
+ return await this.blockSource.getBlockHeaderByHash(blockHash);
1126
+ }
1127
+
1128
+ /**
1129
+ * Get a block header specified by its archive root.
1130
+ * @param archive - The archive root being requested.
1131
+ * @returns The requested block header.
1132
+ */
1133
+ public async getBlockHeaderByArchive(archive: Fr): Promise<BlockHeader | undefined> {
1134
+ return await this.blockSource.getBlockHeaderByArchive(archive);
1015
1135
  }
1016
1136
 
1017
1137
  /**
@@ -1037,7 +1157,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1037
1157
  }
1038
1158
 
1039
1159
  const txHash = tx.getTxHash();
1040
- const blockNumber = (await this.blockSource.getBlockNumber()) + 1;
1160
+ const blockNumber = BlockNumber((await this.blockSource.getBlockNumber()) + 1);
1041
1161
 
1042
1162
  // If sequencer is not initialized, we just set these values to zero for simulation.
1043
1163
  const coinbase = EthAddress.ZERO;
@@ -1062,12 +1182,17 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1062
1182
 
1063
1183
  const merkleTreeFork = await this.worldStateSynchronizer.fork();
1064
1184
  try {
1065
- const processor = publicProcessorFactory.create(
1066
- merkleTreeFork,
1067
- newGlobalVariables,
1185
+ const config = PublicSimulatorConfig.from({
1068
1186
  skipFeeEnforcement,
1069
- /*clientInitiatedSimulation*/ true,
1070
- );
1187
+ collectDebugLogs: true,
1188
+ collectHints: false,
1189
+ collectCallMetadata: true,
1190
+ collectStatistics: false,
1191
+ collectionLimits: CollectionLimitsConfig.from({
1192
+ maxDebugLogMemoryReads: this.config.rpcSimulatePublicMaxDebugLogMemoryReads,
1193
+ }),
1194
+ });
1195
+ const processor = publicProcessorFactory.create(merkleTreeFork, newGlobalVariables, config);
1071
1196
 
1072
1197
  // REFACTOR: Consider merging ProcessReturnValues into ProcessedTx
1073
1198
  const [processedTxs, failedTxs, _usedTxs, returns] = await processor.process([tx]);
@@ -1099,14 +1224,14 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1099
1224
 
1100
1225
  // We accept transactions if they are not expired by the next slot (checked based on the IncludeByTimestamp field)
1101
1226
  const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
1102
- const blockNumber = (await this.blockSource.getBlockNumber()) + 1;
1227
+ const blockNumber = BlockNumber((await this.blockSource.getBlockNumber()) + 1);
1103
1228
  const validator = createValidatorForAcceptingTxs(db, this.contractDataSource, verifier, {
1104
1229
  timestamp: nextSlotTimestamp,
1105
1230
  blockNumber,
1106
1231
  l1ChainId: this.l1ChainId,
1107
1232
  rollupVersion: this.version,
1108
1233
  setupAllowList: this.config.txPublicSetupAllowList ?? (await getDefaultAllowedSetupFunctions()),
1109
- gasFees: await this.getCurrentBaseFees(),
1234
+ gasFees: await this.getCurrentMinFees(),
1110
1235
  skipFeeEnforcement,
1111
1236
  txsPermitted: !this.config.disableTransactions,
1112
1237
  });
@@ -1125,9 +1250,11 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1125
1250
  this.sequencer?.updateConfig(config);
1126
1251
  this.slasherClient?.updateConfig(config);
1127
1252
  this.validatorsSentinel?.updateConfig(config);
1128
- // this.blockBuilder.updateConfig(config); // TODO: Spyros has a PR to add the builder to `this`, so we can do this
1129
1253
  await this.p2pClient.updateP2PConfig(config);
1130
-
1254
+ const archiver = this.blockSource as Archiver;
1255
+ if ('updateConfig' in archiver) {
1256
+ archiver.updateConfig(config);
1257
+ }
1131
1258
  if (newConfig.realProofs !== this.config.realProofs) {
1132
1259
  this.proofVerifier = config.realProofs ? await BBCircuitVerifier.new(newConfig) : new TestCircuitVerifier();
1133
1260
  }
@@ -1154,8 +1281,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1154
1281
 
1155
1282
  public getValidatorStats(
1156
1283
  validatorAddress: EthAddress,
1157
- fromSlot?: bigint,
1158
- toSlot?: bigint,
1284
+ fromSlot?: SlotNumber,
1285
+ toSlot?: SlotNumber,
1159
1286
  ): Promise<SingleValidatorStats | undefined> {
1160
1287
  return this.validatorsSentinel?.getValidatorStats(validatorAddress, fromSlot, toSlot) ?? Promise.resolve(undefined);
1161
1288
  }
@@ -1165,39 +1292,46 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1165
1292
  // We break support for archiver running remotely to the node
1166
1293
  const archiver = this.blockSource as Archiver;
1167
1294
  if (!('backupTo' in archiver)) {
1295
+ this.metrics.recordSnapshotError();
1168
1296
  throw new Error('Archiver implementation does not support backups. Cannot generate snapshot.');
1169
1297
  }
1170
1298
 
1171
1299
  // Test that the archiver has done an initial sync.
1172
1300
  if (!archiver.isInitialSyncComplete()) {
1301
+ this.metrics.recordSnapshotError();
1173
1302
  throw new Error(`Archiver initial sync not complete. Cannot start snapshot.`);
1174
1303
  }
1175
1304
 
1176
1305
  // And it has an L2 block hash
1177
1306
  const l2BlockHash = await archiver.getL2Tips().then(tips => tips.latest.hash);
1178
1307
  if (!l2BlockHash) {
1308
+ this.metrics.recordSnapshotError();
1179
1309
  throw new Error(`Archiver has no latest L2 block hash downloaded. Cannot start snapshot.`);
1180
1310
  }
1181
1311
 
1182
1312
  if (this.isUploadingSnapshot) {
1313
+ this.metrics.recordSnapshotError();
1183
1314
  throw new Error(`Snapshot upload already in progress. Cannot start another one until complete.`);
1184
1315
  }
1185
1316
 
1186
1317
  // Do not wait for the upload to be complete to return to the caller, but flag that an operation is in progress
1187
1318
  this.isUploadingSnapshot = true;
1319
+ const timer = new Timer();
1188
1320
  void uploadSnapshot(location, this.blockSource as Archiver, this.worldStateSynchronizer, this.config, this.log)
1189
1321
  .then(() => {
1190
1322
  this.isUploadingSnapshot = false;
1323
+ this.metrics.recordSnapshot(timer.ms());
1191
1324
  })
1192
1325
  .catch(err => {
1193
1326
  this.isUploadingSnapshot = false;
1327
+ this.metrics.recordSnapshotError();
1194
1328
  this.log.error(`Error uploading snapshot: ${err}`);
1195
1329
  });
1196
1330
 
1197
1331
  return Promise.resolve();
1198
1332
  }
1199
1333
 
1200
- public async rollbackTo(targetBlock: number, force?: boolean): Promise<void> {
1334
+ public async rollbackTo(targetBlock: BlockNumber, force?: boolean): Promise<void> {
1201
1335
  const archiver = this.blockSource as Archiver;
1202
1336
  if (!('rollbackTo' in archiver)) {
1203
1337
  throw new Error('Archiver implementation does not support rollbacks.');
@@ -1269,12 +1403,12 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1269
1403
  * @param blockNumber - The block number at which to get the data.
1270
1404
  * @returns An instance of a committed MerkleTreeOperations
1271
1405
  */
1272
- async #getWorldState(blockNumber: L2BlockNumber) {
1406
+ async #getWorldState(blockNumber: BlockParameter) {
1273
1407
  if (typeof blockNumber === 'number' && blockNumber < INITIAL_L2_BLOCK_NUM - 1) {
1274
1408
  throw new Error('Invalid block number to get world state for: ' + blockNumber);
1275
1409
  }
1276
1410
 
1277
- let blockSyncedTo: number = 0;
1411
+ let blockSyncedTo: BlockNumber = BlockNumber.ZERO;
1278
1412
  try {
1279
1413
  // Attempt to sync the world state if necessary
1280
1414
  blockSyncedTo = await this.#syncWorldState();
@@ -1288,7 +1422,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1288
1422
  return this.worldStateSynchronizer.getCommitted();
1289
1423
  } else if (blockNumber <= blockSyncedTo) {
1290
1424
  this.log.debug(`Using snapshot for block ${blockNumber}, world state synced upto ${blockSyncedTo}`);
1291
- return this.worldStateSynchronizer.getSnapshot(blockNumber);
1425
+ return this.worldStateSynchronizer.getSnapshot(blockNumber as BlockNumber);
1292
1426
  } else {
1293
1427
  throw new Error(`Block ${blockNumber} not yet synced`);
1294
1428
  }
@@ -1298,8 +1432,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1298
1432
  * Ensure we fully sync the world state
1299
1433
  * @returns A promise that fulfils once the world state is synced
1300
1434
  */
1301
- async #syncWorldState(): Promise<number> {
1435
+ async #syncWorldState(): Promise<BlockNumber> {
1302
1436
  const blockSourceHeight = await this.blockSource.getBlockNumber();
1303
- return this.worldStateSynchronizer.syncImmediate(blockSourceHeight);
1437
+ return await this.worldStateSynchronizer.syncImmediate(blockSourceHeight);
1304
1438
  }
1305
1439
  }