@aztec/aztec-node 0.0.1-commit.8c0b8ff → 0.0.1-commit.8cb2d04d8

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.
@@ -372,7 +372,8 @@ function _apply_decs_2203_r(targetClass, memberDecs, classDecs, parentClass) {
372
372
  }
373
373
  var _dec, _initProto;
374
374
  import { createArchiver } from '@aztec/archiver';
375
- import { BBCircuitVerifier, QueuedIVCVerifier, TestCircuitVerifier } from '@aztec/bb-prover';
375
+ import { BBCircuitVerifier, BatchChonkVerifier, QueuedIVCVerifier } from '@aztec/bb-prover';
376
+ import { TestCircuitVerifier } from '@aztec/bb-prover/test';
376
377
  import { createBlobClientWithFileStores } from '@aztec/blob-client/client';
377
378
  import { Blob } from '@aztec/blob-lib';
378
379
  import { EpochCache } from '@aztec/epoch-cache';
@@ -396,7 +397,7 @@ import { createP2PClient, createTxValidatorForAcceptingTxsOverRPC, getDefaultAll
396
397
  import { ProtocolContractAddress } from '@aztec/protocol-contracts';
397
398
  import { createProverNode } from '@aztec/prover-node';
398
399
  import { createKeyStoreForProver } from '@aztec/prover-node/config';
399
- import { GlobalVariableBuilder, SequencerClient } from '@aztec/sequencer-client';
400
+ import { FeeProviderImpl, GlobalVariableBuilder, SequencerClient } from '@aztec/sequencer-client';
400
401
  import { PublicProcessorFactory } from '@aztec/simulator/server';
401
402
  import { AttestationsBlockWatcher, EpochPruneWatcher, createSlasher } from '@aztec/slasher';
402
403
  import { CollectionLimitsConfig, PublicSimulatorConfig } from '@aztec/stdlib/avm';
@@ -439,9 +440,11 @@ _dec = trackSpan('AztecNodeService.simulatePublicCalls', (tx)=>({
439
440
  l1ChainId;
440
441
  version;
441
442
  globalVariableBuilder;
443
+ feeProvider;
442
444
  epochCache;
443
445
  packageVersion;
444
- proofVerifier;
446
+ peerProofVerifier;
447
+ rpcProofVerifier;
445
448
  telemetry;
446
449
  log;
447
450
  blobClient;
@@ -462,7 +465,7 @@ _dec = trackSpan('AztecNodeService.simulatePublicCalls', (tx)=>({
462
465
  // Prevent two snapshot operations to happen simultaneously
463
466
  isUploadingSnapshot;
464
467
  tracer;
465
- constructor(config, p2pClient, blockSource, logsSource, contractDataSource, l1ToL2MessageSource, worldStateSynchronizer, sequencer, proverNode, slasherClient, validatorsSentinel, epochPruneWatcher, l1ChainId, version, globalVariableBuilder, epochCache, packageVersion, proofVerifier, telemetry = getTelemetryClient(), log = createLogger('node'), blobClient, validatorClient, keyStoreManager, debugLogStore = new NullDebugLogStore()){
468
+ constructor(config, p2pClient, blockSource, logsSource, contractDataSource, l1ToL2MessageSource, worldStateSynchronizer, sequencer, proverNode, slasherClient, validatorsSentinel, epochPruneWatcher, l1ChainId, version, globalVariableBuilder, feeProvider, epochCache, packageVersion, peerProofVerifier, rpcProofVerifier, telemetry = getTelemetryClient(), log = createLogger('node'), blobClient, validatorClient, keyStoreManager, debugLogStore = new NullDebugLogStore()){
466
469
  this.config = config;
467
470
  this.p2pClient = p2pClient;
468
471
  this.blockSource = blockSource;
@@ -478,9 +481,11 @@ _dec = trackSpan('AztecNodeService.simulatePublicCalls', (tx)=>({
478
481
  this.l1ChainId = l1ChainId;
479
482
  this.version = version;
480
483
  this.globalVariableBuilder = globalVariableBuilder;
484
+ this.feeProvider = feeProvider;
481
485
  this.epochCache = epochCache;
482
486
  this.packageVersion = packageVersion;
483
- this.proofVerifier = proofVerifier;
487
+ this.peerProofVerifier = peerProofVerifier;
488
+ this.rpcProofVerifier = rpcProofVerifier;
484
489
  this.telemetry = telemetry;
485
490
  this.log = log;
486
491
  this.blobClient = blobClient;
@@ -500,6 +505,9 @@ _dec = trackSpan('AztecNodeService.simulatePublicCalls', (tx)=>({
500
505
  throw new Error('debugLogStore should never be enabled when realProofs are set');
501
506
  }
502
507
  }
508
+ /** @internal Exposed for testing — returns the RPC proof verifier. */ getProofVerifier() {
509
+ return this.rpcProofVerifier;
510
+ }
503
511
  async getWorldStateSyncStatus() {
504
512
  const status = await this.worldStateSynchronizer.status();
505
513
  return status.syncSummary;
@@ -597,8 +605,18 @@ _dec = trackSpan('AztecNodeService.simulatePublicCalls', (tx)=>({
597
605
  blockUntilSync: !config.skipArchiverInitialSync
598
606
  });
599
607
  // now create the merkle trees and the world state synchronizer
600
- const worldStateSynchronizer = await createWorldStateSynchronizer(config, archiver, options.prefilledPublicData, telemetry);
601
- const circuitVerifier = config.realProofs || config.debugForceTxProofVerification ? await BBCircuitVerifier.new(config) : new TestCircuitVerifier(config.proverTestVerificationDelayMs);
608
+ const worldStateSynchronizer = await createWorldStateSynchronizer(config, archiver, options.genesis, telemetry);
609
+ const useRealVerifiers = config.realProofs || config.debugForceTxProofVerification;
610
+ let peerProofVerifier;
611
+ let rpcProofVerifier;
612
+ if (useRealVerifiers) {
613
+ peerProofVerifier = await BatchChonkVerifier.new(config, config.bbChonkVerifyMaxBatch, 'peer');
614
+ const rpcVerifier = await BBCircuitVerifier.new(config);
615
+ rpcProofVerifier = new QueuedIVCVerifier(rpcVerifier, config.numConcurrentIVCVerifiers);
616
+ } else {
617
+ peerProofVerifier = new TestCircuitVerifier(config.proverTestVerificationDelayMs);
618
+ rpcProofVerifier = new TestCircuitVerifier(config.proverTestVerificationDelayMs);
619
+ }
602
620
  let debugLogStore;
603
621
  if (!config.realProofs) {
604
622
  log.warn(`Aztec node is accepting fake proofs`);
@@ -607,13 +625,12 @@ _dec = trackSpan('AztecNodeService.simulatePublicCalls', (tx)=>({
607
625
  } else {
608
626
  debugLogStore = new NullDebugLogStore();
609
627
  }
610
- const proofVerifier = new QueuedIVCVerifier(config, circuitVerifier);
611
628
  const proverOnly = config.enableProverNode && config.disableValidator;
612
629
  if (proverOnly) {
613
630
  log.info('Starting in prover-only mode: skipping validator, sequencer, sentinel, and slasher subsystems');
614
631
  }
615
632
  // create the tx pool and the p2p client, which will need the l2 block source
616
- const p2pClient = await createP2PClient(config, archiver, proofVerifier, worldStateSynchronizer, epochCache, packageVersion, dateProvider, telemetry, deps.p2pClientDeps);
633
+ const p2pClient = await createP2PClient(config, archiver, peerProofVerifier, worldStateSynchronizer, epochCache, packageVersion, dateProvider, telemetry, deps.p2pClientDeps);
617
634
  // We'll accumulate sentinel watchers here
618
635
  const watchers = [];
619
636
  // Create FullNodeCheckpointsBuilder for block proposal handling and tx validation.
@@ -646,6 +663,9 @@ _dec = trackSpan('AztecNodeService.simulatePublicCalls', (tx)=>({
646
663
  // like attestations or auths will fail.
647
664
  if (validatorClient) {
648
665
  watchers.push(validatorClient);
666
+ const vc = validatorClient;
667
+ const getValidatorAddresses = ()=>vc.getValidatorAddresses().map((a)=>a.toString());
668
+ validatorClient.getProposalHandler().register(p2pClient, true, archiver, getValidatorAddresses);
649
669
  if (!options.dontStartSequencer) {
650
670
  await validatorClient.registerHandlers();
651
671
  }
@@ -654,7 +674,7 @@ _dec = trackSpan('AztecNodeService.simulatePublicCalls', (tx)=>({
654
674
  // If there's no validator client, create a ProposalHandler to handle block and checkpoint proposals
655
675
  // for monitoring or reexecution. Reexecution (default) allows us to follow the pending chain,
656
676
  // while non-reexecution is used for validating the proposals and collecting their txs.
657
- // Checkpoint proposals are handled if the blob client can upload blobs.
677
+ // Checkpoint proposals rebuild blobs if the blob client can upload blobs.
658
678
  if (!validatorClient) {
659
679
  const reexecute = !!config.alwaysReexecuteBlockProposals;
660
680
  log.info(`Setting up proposal handler` + (reexecute ? ' with reexecution of proposals' : ''));
@@ -668,7 +688,7 @@ _dec = trackSpan('AztecNodeService.simulatePublicCalls', (tx)=>({
668
688
  blobClient,
669
689
  dateProvider,
670
690
  telemetry
671
- }).register(p2pClient, reexecute);
691
+ }).register(p2pClient, reexecute, archiver);
672
692
  }
673
693
  // Start world state and wait for it to sync to the archiver.
674
694
  await worldStateSynchronizer.start();
@@ -694,19 +714,20 @@ _dec = trackSpan('AztecNodeService.simulatePublicCalls', (tx)=>({
694
714
  }
695
715
  // Start p2p-related services once the archiver has completed sync
696
716
  void archiver.waitForInitialSync().then(async ()=>{
697
- await p2pClient.start();
698
717
  await validatorsSentinel?.start();
699
718
  await epochPruneWatcher?.start();
700
719
  await attestationsBlockWatcher?.start();
701
720
  log.info(`All p2p services started`);
702
721
  }).catch((err)=>log.error('Failed to start p2p services after archiver sync', err));
703
- const globalVariableBuilder = new GlobalVariableBuilder(dateProvider, publicClient, {
722
+ const globalVariableBuilderConfig = {
704
723
  l1Contracts: config.l1Contracts,
705
724
  ethereumSlotDuration: config.ethereumSlotDuration,
706
725
  rollupVersion: BigInt(config.rollupVersion),
707
726
  l1GenesisTime,
708
727
  slotDuration: Number(slotDuration)
709
- });
728
+ };
729
+ const globalVariableBuilder = new GlobalVariableBuilder(dateProvider, publicClient, globalVariableBuilderConfig);
730
+ const feeProvider = new FeeProviderImpl(dateProvider, publicClient, globalVariableBuilderConfig);
710
731
  // Validator enabled, create/start relevant service
711
732
  let sequencer;
712
733
  let slasherClient;
@@ -733,6 +754,22 @@ _dec = trackSpan('AztecNodeService.simulatePublicCalls', (tx)=>({
733
754
  dateProvider,
734
755
  kzg: Blob.getViemKzgInstance()
735
756
  });
757
+ // Create a funder L1TxUtils from the keystore funding account (if configured)
758
+ const fundingSigner = keyStoreManager?.createFundingSigner();
759
+ let funderL1TxUtils;
760
+ if (fundingSigner) {
761
+ const [funder] = await createL1TxUtilsFromSigners(publicClient, [
762
+ fundingSigner
763
+ ], {
764
+ ...config,
765
+ scope: 'sequencer'
766
+ }, {
767
+ telemetry,
768
+ logger: log.createChild('l1-tx-utils:funder'),
769
+ dateProvider
770
+ });
771
+ funderL1TxUtils = funder;
772
+ }
736
773
  // Create and start the sequencer client
737
774
  const checkpointsBuilder = new CheckpointsBuilder({
738
775
  ...config,
@@ -744,6 +781,7 @@ _dec = trackSpan('AztecNodeService.simulatePublicCalls', (tx)=>({
744
781
  ...deps,
745
782
  epochCache,
746
783
  l1TxUtils,
784
+ funderL1TxUtils,
747
785
  validatorClient,
748
786
  p2pClient,
749
787
  worldStateSynchronizer,
@@ -785,7 +823,7 @@ _dec = trackSpan('AztecNodeService.simulatePublicCalls', (tx)=>({
785
823
  log.info(`Prover node subsystem created but not started`);
786
824
  }
787
825
  }
788
- const node = new AztecNodeService(config, p2pClient, archiver, archiver, archiver, archiver, worldStateSynchronizer, sequencer, proverNode, slasherClient, validatorsSentinel, epochPruneWatcher, ethereumChain.chainInfo.id, config.rollupVersion, globalVariableBuilder, epochCache, packageVersion, proofVerifier, telemetry, log, blobClient, validatorClient, keyStoreManager, debugLogStore);
826
+ const node = new AztecNodeService(config, p2pClient, archiver, archiver, archiver, archiver, worldStateSynchronizer, sequencer, proverNode, slasherClient, validatorsSentinel, epochPruneWatcher, ethereumChain.chainInfo.id, config.rollupVersion, globalVariableBuilder, feeProvider, epochCache, packageVersion, peerProofVerifier, rpcProofVerifier, telemetry, log, blobClient, validatorClient, keyStoreManager, debugLogStore);
789
827
  return node;
790
828
  }
791
829
  /**
@@ -900,11 +938,11 @@ _dec = trackSpan('AztecNodeService.simulatePublicCalls', (tx)=>({
900
938
  getCheckpointsDataForEpoch(epochNumber) {
901
939
  return this.blockSource.getCheckpointsDataForEpoch(epochNumber);
902
940
  }
903
- /**
904
- * Method to fetch the current min L2 fees.
905
- * @returns The current min L2 fees.
906
- */ async getCurrentMinFees() {
907
- return await this.globalVariableBuilder.getCurrentMinFees();
941
+ async getCurrentMinFees() {
942
+ return await this.feeProvider.getCurrentMinFees();
943
+ }
944
+ /** Returns predicted min fees for the current slot and next N slots. */ async getPredictedMinFees(manaUsage) {
945
+ return await this.feeProvider.getPredictedMinFees(manaUsage);
908
946
  }
909
947
  async getMaxPriorityFees() {
910
948
  for await (const tx of this.p2pClient.iteratePendingTxs()){
@@ -955,28 +993,36 @@ _dec = trackSpan('AztecNodeService.simulatePublicCalls', (tx)=>({
955
993
  return this.contractDataSource.getContract(address);
956
994
  }
957
995
  async getPrivateLogsByTags(tags, page, referenceBlock) {
996
+ let upToBlockNumber;
958
997
  if (referenceBlock) {
959
998
  const initialBlockHash = await this.#getInitialHeaderHash();
960
- if (!referenceBlock.equals(initialBlockHash)) {
999
+ if (referenceBlock.equals(initialBlockHash)) {
1000
+ upToBlockNumber = BlockNumber(0);
1001
+ } else {
961
1002
  const header = await this.blockSource.getBlockHeaderByHash(referenceBlock);
962
1003
  if (!header) {
963
1004
  throw new Error(`Block ${referenceBlock.toString()} not found in the node. This might indicate a reorg has occurred.`);
964
1005
  }
1006
+ upToBlockNumber = header.globalVariables.blockNumber;
965
1007
  }
966
1008
  }
967
- return this.logsSource.getPrivateLogsByTags(tags, page);
1009
+ return this.logsSource.getPrivateLogsByTags(tags, page, upToBlockNumber);
968
1010
  }
969
1011
  async getPublicLogsByTagsFromContract(contractAddress, tags, page, referenceBlock) {
1012
+ let upToBlockNumber;
970
1013
  if (referenceBlock) {
971
1014
  const initialBlockHash = await this.#getInitialHeaderHash();
972
- if (!referenceBlock.equals(initialBlockHash)) {
1015
+ if (referenceBlock.equals(initialBlockHash)) {
1016
+ upToBlockNumber = BlockNumber(0);
1017
+ } else {
973
1018
  const header = await this.blockSource.getBlockHeaderByHash(referenceBlock);
974
1019
  if (!header) {
975
1020
  throw new Error(`Block ${referenceBlock.toString()} not found in the node. This might indicate a reorg has occurred.`);
976
1021
  }
1022
+ upToBlockNumber = header.globalVariables.blockNumber;
977
1023
  }
978
1024
  }
979
- return this.logsSource.getPublicLogsByTagsFromContract(contractAddress, tags, page);
1025
+ return this.logsSource.getPublicLogsByTagsFromContract(contractAddress, tags, page, upToBlockNumber);
980
1026
  }
981
1027
  /**
982
1028
  * Gets public logs based on the provided filter.
@@ -1049,7 +1095,10 @@ _dec = trackSpan('AztecNodeService.simulatePublicCalls', (tx)=>({
1049
1095
  await tryStop(this.validatorsSentinel);
1050
1096
  await tryStop(this.epochPruneWatcher);
1051
1097
  await tryStop(this.slasherClient);
1052
- await tryStop(this.proofVerifier);
1098
+ await Promise.all([
1099
+ tryStop(this.peerProofVerifier),
1100
+ tryStop(this.rpcProofVerifier)
1101
+ ]);
1053
1102
  await tryStop(this.sequencer);
1054
1103
  await tryStop(this.proverNode);
1055
1104
  await tryStop(this.p2pClient);
@@ -1132,32 +1181,26 @@ _dec = trackSpan('AztecNodeService.simulatePublicCalls', (tx)=>({
1132
1181
  if (blockNumber === undefined) {
1133
1182
  throw new Error(`Block number not found for leaf index ${index} in tree ${MerkleTreeId[treeId]}`);
1134
1183
  }
1135
- const blockHash = blockNumberToHash.get(blockNumber);
1136
- if (blockHash === undefined) {
1184
+ const l2BlockHash = blockNumberToHash.get(blockNumber);
1185
+ if (l2BlockHash === undefined) {
1137
1186
  throw new Error(`Block hash not found for block number ${blockNumber}`);
1138
1187
  }
1139
1188
  return {
1140
1189
  l2BlockNumber: blockNumber,
1141
- l2BlockHash: new BlockHash(blockHash),
1190
+ l2BlockHash,
1142
1191
  data: index
1143
1192
  };
1144
1193
  });
1145
1194
  }
1146
1195
  async getBlockHashMembershipWitness(referenceBlock, blockHash) {
1147
- // Block 0 (the initial block) has an empty archive, so no membership witness can exist.
1148
- if (referenceBlock === BlockNumber.ZERO) {
1149
- return undefined;
1150
- }
1151
- if (BlockHash.isBlockHash(referenceBlock)) {
1152
- const initialBlockHash = await this.#getInitialHeaderHash();
1153
- if (referenceBlock.equals(initialBlockHash)) {
1154
- return undefined;
1155
- }
1156
- }
1157
1196
  // The Noir circuit checks the archive membership proof against `anchor_block_header.last_archive.root`,
1158
1197
  // which is the archive tree root BEFORE the anchor block was added (i.e. the state after block N-1).
1159
1198
  // So we need the world state at block N-1, not block N, to produce a sibling path matching that root.
1160
1199
  const referenceBlockNumber = await this.resolveBlockNumber(referenceBlock);
1200
+ if (referenceBlockNumber === BlockNumber.ZERO) {
1201
+ // Block 0 (the initial block) has an empty archive, so no membership witness can exist.
1202
+ return undefined;
1203
+ }
1161
1204
  const committedDb = await this.getWorldState(BlockNumber(referenceBlockNumber - 1));
1162
1205
  const [pathAndIndex] = await committedDb.findSiblingPaths(MerkleTreeId.ARCHIVE, [
1163
1206
  blockHash
@@ -1345,7 +1388,7 @@ _dec = trackSpan('AztecNodeService.simulatePublicCalls', (tx)=>({
1345
1388
  }
1346
1389
  async isValidTx(tx, { isSimulation, skipFeeEnforcement } = {}) {
1347
1390
  const db = this.worldStateSynchronizer.getCommitted();
1348
- const verifier = isSimulation ? undefined : this.proofVerifier;
1391
+ const verifier = isSimulation ? undefined : this.rpcProofVerifier;
1349
1392
  // We accept transactions if they are not expired by the next slot (checked based on the ExpirationTimestamp field)
1350
1393
  const { ts: nextSlotTimestamp } = this.epochCache.getEpochAndSlotInNextL1Slot();
1351
1394
  const blockNumber = BlockNumber(await this.blockSource.getBlockNumber() + 1);
@@ -1387,7 +1430,18 @@ _dec = trackSpan('AztecNodeService.simulatePublicCalls', (tx)=>({
1387
1430
  archiver.updateConfig(config);
1388
1431
  }
1389
1432
  if (newConfig.realProofs !== this.config.realProofs) {
1390
- this.proofVerifier = config.realProofs ? await BBCircuitVerifier.new(newConfig) : new TestCircuitVerifier();
1433
+ await Promise.all([
1434
+ tryStop(this.peerProofVerifier),
1435
+ tryStop(this.rpcProofVerifier)
1436
+ ]);
1437
+ if (newConfig.realProofs) {
1438
+ this.peerProofVerifier = await BatchChonkVerifier.new(newConfig, newConfig.bbChonkVerifyMaxBatch, 'peer');
1439
+ const rpcVerifier = await BBCircuitVerifier.new(newConfig);
1440
+ this.rpcProofVerifier = new QueuedIVCVerifier(rpcVerifier, newConfig.numConcurrentIVCVerifiers);
1441
+ } else {
1442
+ this.peerProofVerifier = new TestCircuitVerifier();
1443
+ this.rpcProofVerifier = new TestCircuitVerifier();
1444
+ }
1391
1445
  }
1392
1446
  this.config = newConfig;
1393
1447
  }
@@ -1447,7 +1501,7 @@ _dec = trackSpan('AztecNodeService.simulatePublicCalls', (tx)=>({
1447
1501
  });
1448
1502
  return Promise.resolve();
1449
1503
  }
1450
- async rollbackTo(targetBlock, force) {
1504
+ async rollbackTo(targetBlock, force, resumeSync = true) {
1451
1505
  const archiver = this.blockSource;
1452
1506
  if (!('rollbackTo' in archiver)) {
1453
1507
  throw new Error('Archiver implementation does not support rollbacks.');
@@ -1475,9 +1529,13 @@ _dec = trackSpan('AztecNodeService.simulatePublicCalls', (tx)=>({
1475
1529
  this.log.error(`Error during rollback`, err);
1476
1530
  throw err;
1477
1531
  } finally{
1478
- this.log.info(`Resuming world state and archiver sync.`);
1479
- this.worldStateSynchronizer.resumeSync();
1480
- archiver.resume();
1532
+ if (resumeSync) {
1533
+ this.log.info(`Resuming world state and archiver sync.`);
1534
+ this.worldStateSynchronizer.resumeSync();
1535
+ archiver.resume();
1536
+ } else {
1537
+ this.log.info(`Sync left paused after rollback (resumeSync=false).`);
1538
+ }
1481
1539
  }
1482
1540
  }
1483
1541
  async pauseSync() {
@@ -1491,18 +1549,12 @@ _dec = trackSpan('AztecNodeService.simulatePublicCalls', (tx)=>({
1491
1549
  this.blockSource.resume();
1492
1550
  return Promise.resolve();
1493
1551
  }
1494
- getSlashPayloads() {
1495
- if (!this.slasherClient) {
1496
- throw new Error(`Slasher client not enabled`);
1497
- }
1498
- return this.slasherClient.getSlashPayloads();
1499
- }
1500
1552
  getSlashOffenses(round) {
1501
1553
  if (!this.slasherClient) {
1502
1554
  throw new Error(`Slasher client not enabled`);
1503
1555
  }
1504
1556
  if (round === 'all') {
1505
- return this.slasherClient.getPendingOffenses();
1557
+ return this.slasherClient.getOffenses();
1506
1558
  } else {
1507
1559
  return this.slasherClient.gatherOffensesForRound(round === 'current' ? undefined : BigInt(round));
1508
1560
  }
@@ -1648,7 +1700,7 @@ _dec = trackSpan('AztecNodeService.simulatePublicCalls', (tx)=>({
1648
1700
  // Double-check world-state synced to the same block hash as was requested
1649
1701
  if (BlockHash.isBlockHash(block)) {
1650
1702
  const blockHash = await snapshot.getLeafValue(MerkleTreeId.ARCHIVE, BigInt(blockNumber));
1651
- if (!blockHash || !new BlockHash(blockHash).equals(block)) {
1703
+ if (!blockHash || !block.equals(blockHash)) {
1652
1704
  throw new Error(`Block hash ${block.toString()} not found in world state at block number ${blockNumber}. If the node API has been queried with anchor block hash possibly a reorg has occurred.`);
1653
1705
  }
1654
1706
  }
@@ -1,9 +1,9 @@
1
1
  import type { EpochCache } from '@aztec/epoch-cache';
2
- import type { DataStoreConfig } from '@aztec/kv-store/config';
3
2
  import type { P2PClient } from '@aztec/p2p';
4
3
  import type { L2BlockSource } from '@aztec/stdlib/block';
5
4
  import type { SlasherConfig } from '@aztec/stdlib/interfaces/server';
5
+ import type { DataStoreConfig } from '@aztec/stdlib/kv-store';
6
6
  import type { SentinelConfig } from './config.js';
7
7
  import { Sentinel } from './sentinel.js';
8
8
  export declare function createSentinel(epochCache: EpochCache, archiver: L2BlockSource, p2p: P2PClient, config: SentinelConfig & DataStoreConfig & SlasherConfig, logger?: import("@aztec/foundation/log").Logger): Promise<Sentinel | undefined>;
9
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFjdG9yeS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlbnRpbmVsL2ZhY3RvcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFckQsT0FBTyxLQUFLLEVBQUUsZUFBZSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFOUQsT0FBTyxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQzVDLE9BQU8sS0FBSyxFQUFFLGFBQWEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3pELE9BQU8sS0FBSyxFQUFFLGFBQWEsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBRXJFLE9BQU8sS0FBSyxFQUFFLGNBQWMsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNsRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBR3pDLHdCQUFzQixjQUFjLENBQ2xDLFVBQVUsRUFBRSxVQUFVLEVBQ3RCLFFBQVEsRUFBRSxhQUFhLEVBQ3ZCLEdBQUcsRUFBRSxTQUFTLEVBQ2QsTUFBTSxFQUFFLGNBQWMsR0FBRyxlQUFlLEdBQUcsYUFBYSxFQUN4RCxNQUFNLHlDQUFnQyxHQUNyQyxPQUFPLENBQUMsUUFBUSxHQUFHLFNBQVMsQ0FBQyxDQVkvQiJ9
9
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFjdG9yeS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlbnRpbmVsL2ZhY3RvcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFHckQsT0FBTyxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQzVDLE9BQU8sS0FBSyxFQUFFLGFBQWEsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3pELE9BQU8sS0FBSyxFQUFFLGFBQWEsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3JFLE9BQU8sS0FBSyxFQUFFLGVBQWUsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRTlELE9BQU8sS0FBSyxFQUFFLGNBQWMsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUNsRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBR3pDLHdCQUFzQixjQUFjLENBQ2xDLFVBQVUsRUFBRSxVQUFVLEVBQ3RCLFFBQVEsRUFBRSxhQUFhLEVBQ3ZCLEdBQUcsRUFBRSxTQUFTLEVBQ2QsTUFBTSxFQUFFLGNBQWMsR0FBRyxlQUFlLEdBQUcsYUFBYSxFQUN4RCxNQUFNLHlDQUFnQyxHQUNyQyxPQUFPLENBQUMsUUFBUSxHQUFHLFNBQVMsQ0FBQyxDQVkvQiJ9
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/sentinel/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAErE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,wBAAsB,cAAc,CAClC,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,aAAa,EACvB,GAAG,EAAE,SAAS,EACd,MAAM,EAAE,cAAc,GAAG,eAAe,GAAG,aAAa,EACxD,MAAM,yCAAgC,GACrC,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAY/B"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/sentinel/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,wBAAsB,cAAc,CAClC,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,aAAa,EACvB,GAAG,EAAE,SAAS,EACd,MAAM,EAAE,cAAc,GAAG,eAAe,GAAG,aAAa,EACxD,MAAM,yCAAgC,GACrC,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAY/B"}
@@ -48,7 +48,7 @@ export class Sentinel extends EventEmitter {
48
48
  this.runningPromise.start();
49
49
  }
50
50
  /** Loads initial slot and initializes blockstream. We will not process anything at or before the initial slot. */ async init() {
51
- this.initialSlot = this.epochCache.getEpochAndSlotNow().slot;
51
+ this.initialSlot = this.epochCache.getSlotNow();
52
52
  const startingBlock = BlockNumber(await this.archiver.getBlockNumber());
53
53
  this.logger.info(`Starting validator sentinel with initial slot ${this.initialSlot} and block ${startingBlock}`);
54
54
  this.blockStream = new L2BlockStream(this.archiver, this.l2TipsStore, this, this.logger, {
@@ -157,13 +157,13 @@ export class Sentinel extends EventEmitter {
157
157
  return false;
158
158
  }
159
159
  // Check that we have at least requiredConsecutiveEpochs and that all of them are above the inactivity threshold
160
- return pastEpochs.slice(0, requiredConsecutiveEpochs).every((p)=>p.missed / p.total >= this.config.slashInactivityTargetPercentage);
160
+ return pastEpochs.slice(0, requiredConsecutiveEpochs).every((p)=>p.total === 0 ? false : p.missed / p.total >= this.config.slashInactivityTargetPercentage);
161
161
  }
162
162
  async handleProvenPerformance(epoch, performance) {
163
163
  if (this.config.slashInactivityPenalty === 0n) {
164
164
  return;
165
165
  }
166
- const inactiveValidators = getEntries(performance).filter(([_, { missed, total }])=>missed / total >= this.config.slashInactivityTargetPercentage).map(([address])=>address);
166
+ const inactiveValidators = getEntries(performance).filter(([_, { missed, total }])=>total > 0 && missed / total >= this.config.slashInactivityTargetPercentage).map(([address])=>address);
167
167
  this.logger.debug(`Found ${inactiveValidators.length} inactive validators in epoch ${epoch}`, {
168
168
  inactiveValidators,
169
169
  epoch,
@@ -190,7 +190,7 @@ export class Sentinel extends EventEmitter {
190
190
  * Note that we do not process historical data, since we rely on p2p data for processing,
191
191
  * and we don't have that data if we were offline during the period.
192
192
  */ async work() {
193
- const { slot: currentSlot } = this.epochCache.getEpochAndSlotNow();
193
+ const currentSlot = this.epochCache.getSlotNow();
194
194
  try {
195
195
  // Manually sync the block stream to ensure we have the latest data.
196
196
  // Note we never `start` the blockstream, so it loops at the same pace as we do.
@@ -351,7 +351,7 @@ export class Sentinel extends EventEmitter {
351
351
  v.toString(),
352
352
  await this.store.getHistory(v)
353
353
  ]))) : await this.store.getHistories();
354
- const slotNow = this.epochCache.getEpochAndSlotNow().slot;
354
+ const slotNow = this.epochCache.getSlotNow();
355
355
  fromSlot ??= SlotNumber(Math.max((this.lastProcessedSlot ?? slotNow) - this.store.getHistoryLength(), 0));
356
356
  toSlot ??= this.lastProcessedSlot ?? slotNow;
357
357
  const stats = mapValues(histories, (history, address)=>this.computeStatsForValidator(address, history ?? [], fromSlot, toSlot));
@@ -367,7 +367,7 @@ export class Sentinel extends EventEmitter {
367
367
  if (!history || history.length === 0) {
368
368
  return undefined;
369
369
  }
370
- const slotNow = this.epochCache.getEpochAndSlotNow().slot;
370
+ const slotNow = this.epochCache.getSlotNow();
371
371
  const effectiveFromSlot = fromSlot ?? SlotNumber(Math.max((this.lastProcessedSlot ?? slotNow) - this.store.getHistoryLength(), 0));
372
372
  const effectiveToSlot = toSlot ?? this.lastProcessedSlot ?? slotNow;
373
373
  const historyLength = BigInt(this.store.getHistoryLength());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/aztec-node",
3
- "version": "0.0.1-commit.8c0b8ff",
3
+ "version": "0.0.1-commit.8cb2d04d8",
4
4
  "main": "dest/index.js",
5
5
  "type": "module",
6
6
  "exports": {
@@ -65,32 +65,31 @@
65
65
  ]
66
66
  },
67
67
  "dependencies": {
68
- "@aztec/archiver": "0.0.1-commit.8c0b8ff",
69
- "@aztec/bb-prover": "0.0.1-commit.8c0b8ff",
70
- "@aztec/blob-client": "0.0.1-commit.8c0b8ff",
71
- "@aztec/blob-lib": "0.0.1-commit.8c0b8ff",
72
- "@aztec/constants": "0.0.1-commit.8c0b8ff",
73
- "@aztec/epoch-cache": "0.0.1-commit.8c0b8ff",
74
- "@aztec/ethereum": "0.0.1-commit.8c0b8ff",
75
- "@aztec/foundation": "0.0.1-commit.8c0b8ff",
76
- "@aztec/kv-store": "0.0.1-commit.8c0b8ff",
77
- "@aztec/l1-artifacts": "0.0.1-commit.8c0b8ff",
78
- "@aztec/merkle-tree": "0.0.1-commit.8c0b8ff",
79
- "@aztec/node-keystore": "0.0.1-commit.8c0b8ff",
80
- "@aztec/node-lib": "0.0.1-commit.8c0b8ff",
81
- "@aztec/noir-protocol-circuits-types": "0.0.1-commit.8c0b8ff",
82
- "@aztec/p2p": "0.0.1-commit.8c0b8ff",
83
- "@aztec/protocol-contracts": "0.0.1-commit.8c0b8ff",
84
- "@aztec/prover-client": "0.0.1-commit.8c0b8ff",
85
- "@aztec/prover-node": "0.0.1-commit.8c0b8ff",
86
- "@aztec/sequencer-client": "0.0.1-commit.8c0b8ff",
87
- "@aztec/simulator": "0.0.1-commit.8c0b8ff",
88
- "@aztec/slasher": "0.0.1-commit.8c0b8ff",
89
- "@aztec/stdlib": "0.0.1-commit.8c0b8ff",
90
- "@aztec/telemetry-client": "0.0.1-commit.8c0b8ff",
91
- "@aztec/validator-client": "0.0.1-commit.8c0b8ff",
92
- "@aztec/validator-ha-signer": "0.0.1-commit.8c0b8ff",
93
- "@aztec/world-state": "0.0.1-commit.8c0b8ff",
68
+ "@aztec/archiver": "0.0.1-commit.8cb2d04d8",
69
+ "@aztec/bb-prover": "0.0.1-commit.8cb2d04d8",
70
+ "@aztec/blob-client": "0.0.1-commit.8cb2d04d8",
71
+ "@aztec/blob-lib": "0.0.1-commit.8cb2d04d8",
72
+ "@aztec/constants": "0.0.1-commit.8cb2d04d8",
73
+ "@aztec/epoch-cache": "0.0.1-commit.8cb2d04d8",
74
+ "@aztec/ethereum": "0.0.1-commit.8cb2d04d8",
75
+ "@aztec/foundation": "0.0.1-commit.8cb2d04d8",
76
+ "@aztec/kv-store": "0.0.1-commit.8cb2d04d8",
77
+ "@aztec/l1-artifacts": "0.0.1-commit.8cb2d04d8",
78
+ "@aztec/node-keystore": "0.0.1-commit.8cb2d04d8",
79
+ "@aztec/node-lib": "0.0.1-commit.8cb2d04d8",
80
+ "@aztec/noir-protocol-circuits-types": "0.0.1-commit.8cb2d04d8",
81
+ "@aztec/p2p": "0.0.1-commit.8cb2d04d8",
82
+ "@aztec/protocol-contracts": "0.0.1-commit.8cb2d04d8",
83
+ "@aztec/prover-client": "0.0.1-commit.8cb2d04d8",
84
+ "@aztec/prover-node": "0.0.1-commit.8cb2d04d8",
85
+ "@aztec/sequencer-client": "0.0.1-commit.8cb2d04d8",
86
+ "@aztec/simulator": "0.0.1-commit.8cb2d04d8",
87
+ "@aztec/slasher": "0.0.1-commit.8cb2d04d8",
88
+ "@aztec/stdlib": "0.0.1-commit.8cb2d04d8",
89
+ "@aztec/telemetry-client": "0.0.1-commit.8cb2d04d8",
90
+ "@aztec/validator-client": "0.0.1-commit.8cb2d04d8",
91
+ "@aztec/validator-ha-signer": "0.0.1-commit.8cb2d04d8",
92
+ "@aztec/world-state": "0.0.1-commit.8cb2d04d8",
94
93
  "koa": "^2.16.1",
95
94
  "koa-router": "^13.1.1",
96
95
  "tslib": "^2.4.0",
@@ -3,7 +3,6 @@ import { type GenesisStateConfig, genesisStateConfigMappings } from '@aztec/ethe
3
3
  import { type L1ContractAddresses, l1ContractAddressesMapping } from '@aztec/ethereum/l1-contract-addresses';
4
4
  import { type ConfigMappingsType, booleanConfigHelper, getConfigFromMappings } from '@aztec/foundation/config';
5
5
  import { EthAddress } from '@aztec/foundation/eth-address';
6
- import { type DataStoreConfig, dataConfigMappings } from '@aztec/kv-store/config';
7
6
  import {
8
7
  type KeyStore,
9
8
  type ValidatorKeyStore,
@@ -27,6 +26,7 @@ import { slasherConfigMappings } from '@aztec/slasher';
27
26
  import { AztecAddress } from '@aztec/stdlib/aztec-address';
28
27
  import { type NodeRPCConfig, nodeRpcConfigMappings } from '@aztec/stdlib/config';
29
28
  import type { SlasherConfig } from '@aztec/stdlib/interfaces/server';
29
+ import { type DataStoreConfig, dataConfigMappings } from '@aztec/stdlib/kv-store';
30
30
  import { type ValidatorClientConfig, validatorClientConfigMappings } from '@aztec/validator-client/config';
31
31
  import { type WorldStateConfig, worldStateConfigMappings } from '@aztec/world-state/config';
32
32