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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"sentinel.d.ts","sourceRoot":"","sources":["../../src/sentinel/sentinel.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sentinel.d.ts","sourceRoot":"","sources":["../../src/sentinel/sentinel.ts"],"names":[],"mappings":"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"}
@@ -5,7 +5,7 @@ import { createLogger } from '@aztec/foundation/log';
5
5
  import { RunningPromise } from '@aztec/foundation/running-promise';
6
6
  import { L2TipsMemoryStore } from '@aztec/kv-store/stores';
7
7
  import { OffenseType, WANT_TO_SLASH_EVENT } from '@aztec/slasher';
8
- import { L2BlockStream, getAttestationInfoFromPublishedL2Block } from '@aztec/stdlib/block';
8
+ import { L2BlockStream, getAttestationInfoFromPublishedCheckpoint } from '@aztec/stdlib/block';
9
9
  import { getEpochAtSlot, getSlotRangeForEpoch, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
10
10
  import EventEmitter from 'node:events';
11
11
  export class Sentinel extends EventEmitter {
@@ -21,9 +21,9 @@ export class Sentinel extends EventEmitter {
21
21
  initialSlot;
22
22
  lastProcessedSlot;
23
23
  // eslint-disable-next-line aztec-custom/no-non-primitive-in-collections
24
- slotNumberToBlock;
24
+ slotNumberToCheckpoint;
25
25
  constructor(epochCache, archiver, p2p, store, config, logger = createLogger('node:sentinel')){
26
- super(), this.epochCache = epochCache, this.archiver = archiver, this.p2p = p2p, this.store = store, this.config = config, this.logger = logger, this.slotNumberToBlock = new Map();
26
+ super(), this.epochCache = epochCache, this.archiver = archiver, this.p2p = p2p, this.store = store, this.config = config, this.logger = logger, this.slotNumberToCheckpoint = new Map();
27
27
  this.l2TipsStore = new L2TipsMemoryStore();
28
28
  const interval = epochCache.getL1Constants().ethereumSlotDuration * 1000 / 4;
29
29
  this.runningPromise = new RunningPromise(this.work.bind(this), logger, interval);
@@ -51,33 +51,38 @@ export class Sentinel extends EventEmitter {
51
51
  }
52
52
  async handleBlockStreamEvent(event) {
53
53
  await this.l2TipsStore.handleBlockStreamEvent(event);
54
- if (event.type === 'blocks-added') {
55
- // Store mapping from slot to archive, block number, and attestors
56
- for (const block of event.blocks){
57
- this.slotNumberToBlock.set(block.block.header.getSlot(), {
58
- blockNumber: BlockNumber(block.block.number),
59
- archive: block.block.archive.root.toString(),
60
- attestors: getAttestationInfoFromPublishedL2Block(block).filter((a)=>a.status === 'recovered-from-signature').map((a)=>a.address)
61
- });
62
- }
63
- // Prune the archive map to only keep at most N entries
64
- const historyLength = this.store.getHistoryLength();
65
- if (this.slotNumberToBlock.size > historyLength) {
66
- const toDelete = Array.from(this.slotNumberToBlock.keys()).sort((a, b)=>Number(a - b)).slice(0, this.slotNumberToBlock.size - historyLength);
67
- for (const key of toDelete){
68
- this.slotNumberToBlock.delete(key);
69
- }
70
- }
54
+ if (event.type === 'chain-checkpointed') {
55
+ this.handleCheckpoint(event);
71
56
  } else if (event.type === 'chain-proven') {
72
57
  await this.handleChainProven(event);
73
58
  }
74
59
  }
60
+ handleCheckpoint(event) {
61
+ if (event.type !== 'chain-checkpointed') {
62
+ return;
63
+ }
64
+ const checkpoint = event.checkpoint;
65
+ // Store mapping from slot to archive, checkpoint number, and attestors
66
+ this.slotNumberToCheckpoint.set(checkpoint.checkpoint.header.slotNumber, {
67
+ checkpointNumber: checkpoint.checkpoint.number,
68
+ archive: checkpoint.checkpoint.archive.root.toString(),
69
+ attestors: getAttestationInfoFromPublishedCheckpoint(checkpoint).filter((a)=>a.status === 'recovered-from-signature').map((a)=>a.address)
70
+ });
71
+ // Prune the archive map to only keep at most N entries
72
+ const historyLength = this.store.getHistoryLength();
73
+ if (this.slotNumberToCheckpoint.size > historyLength) {
74
+ const toDelete = Array.from(this.slotNumberToCheckpoint.keys()).sort((a, b)=>Number(a - b)).slice(0, this.slotNumberToCheckpoint.size - historyLength);
75
+ for (const key of toDelete){
76
+ this.slotNumberToCheckpoint.delete(key);
77
+ }
78
+ }
79
+ }
75
80
  async handleChainProven(event) {
76
81
  if (event.type !== 'chain-proven') {
77
82
  return;
78
83
  }
79
- const blockNumber = BlockNumber(event.block.number);
80
- const block = await this.archiver.getBlock(blockNumber);
84
+ const blockNumber = event.block.number;
85
+ const block = await this.archiver.getL2BlockNew(blockNumber);
81
86
  if (!block) {
82
87
  this.logger.error(`Failed to get block ${blockNumber}`, {
83
88
  block
@@ -221,8 +226,8 @@ export class Sentinel extends EventEmitter {
221
226
  });
222
227
  return false;
223
228
  }
224
- const archiverLastBlockHash = await this.l2TipsStore.getL2Tips().then((tip)=>tip.latest.hash);
225
- const p2pLastBlockHash = await this.p2p.getL2Tips().then((tips)=>tips.latest.hash);
229
+ const archiverLastBlockHash = await this.l2TipsStore.getL2Tips().then((tip)=>tip.proposed.hash);
230
+ const p2pLastBlockHash = await this.p2p.getL2Tips().then((tips)=>tips.proposed.hash);
226
231
  const isP2pSynced = archiverLastBlockHash === p2pLastBlockHash;
227
232
  if (!isP2pSynced) {
228
233
  this.logger.debug(`Waiting for P2P client to sync with archiver`, {
@@ -262,8 +267,8 @@ export class Sentinel extends EventEmitter {
262
267
  // or all attestations for all proposals in the slot if no block was mined.
263
268
  // We gather from both p2p (contains the ones seen on the p2p layer) and archiver
264
269
  // (contains the ones synced from mined blocks, which we may have missed from p2p).
265
- const block = this.slotNumberToBlock.get(slot);
266
- const p2pAttested = await this.p2p.getAttestationsForSlot(slot, block?.archive);
270
+ const block = this.slotNumberToCheckpoint.get(slot);
271
+ const p2pAttested = await this.p2p.getCheckpointAttestationsForSlot(slot, block?.archive);
267
272
  // Filter out attestations with invalid signatures
268
273
  const p2pAttestors = p2pAttested.map((a)=>a.getSender()).filter((s)=>s !== undefined);
269
274
  const attestors = new Set([
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/aztec-node",
3
- "version": "0.0.1-commit.6c91f13",
3
+ "version": "0.0.1-commit.96bb3f7",
4
4
  "main": "dest/index.js",
5
5
  "type": "module",
6
6
  "exports": {
@@ -9,7 +9,6 @@
9
9
  "./sentinel": "./dest/aztec-node/sentinel.js",
10
10
  "./test": "./dest/test/index.js"
11
11
  },
12
- "bin": "./dest/bin/index.js",
13
12
  "typedocOptions": {
14
13
  "entryPoints": [
15
14
  "./src/index.ts"
@@ -66,29 +65,29 @@
66
65
  ]
67
66
  },
68
67
  "dependencies": {
69
- "@aztec/archiver": "0.0.1-commit.6c91f13",
70
- "@aztec/bb-prover": "0.0.1-commit.6c91f13",
71
- "@aztec/blob-client": "0.0.1-commit.6c91f13",
72
- "@aztec/constants": "0.0.1-commit.6c91f13",
73
- "@aztec/epoch-cache": "0.0.1-commit.6c91f13",
74
- "@aztec/ethereum": "0.0.1-commit.6c91f13",
75
- "@aztec/foundation": "0.0.1-commit.6c91f13",
76
- "@aztec/kv-store": "0.0.1-commit.6c91f13",
77
- "@aztec/l1-artifacts": "0.0.1-commit.6c91f13",
78
- "@aztec/merkle-tree": "0.0.1-commit.6c91f13",
79
- "@aztec/node-keystore": "0.0.1-commit.6c91f13",
80
- "@aztec/node-lib": "0.0.1-commit.6c91f13",
81
- "@aztec/noir-protocol-circuits-types": "0.0.1-commit.6c91f13",
82
- "@aztec/p2p": "0.0.1-commit.6c91f13",
83
- "@aztec/protocol-contracts": "0.0.1-commit.6c91f13",
84
- "@aztec/prover-client": "0.0.1-commit.6c91f13",
85
- "@aztec/sequencer-client": "0.0.1-commit.6c91f13",
86
- "@aztec/simulator": "0.0.1-commit.6c91f13",
87
- "@aztec/slasher": "0.0.1-commit.6c91f13",
88
- "@aztec/stdlib": "0.0.1-commit.6c91f13",
89
- "@aztec/telemetry-client": "0.0.1-commit.6c91f13",
90
- "@aztec/validator-client": "0.0.1-commit.6c91f13",
91
- "@aztec/world-state": "0.0.1-commit.6c91f13",
68
+ "@aztec/archiver": "0.0.1-commit.96bb3f7",
69
+ "@aztec/bb-prover": "0.0.1-commit.96bb3f7",
70
+ "@aztec/blob-client": "0.0.1-commit.96bb3f7",
71
+ "@aztec/constants": "0.0.1-commit.96bb3f7",
72
+ "@aztec/epoch-cache": "0.0.1-commit.96bb3f7",
73
+ "@aztec/ethereum": "0.0.1-commit.96bb3f7",
74
+ "@aztec/foundation": "0.0.1-commit.96bb3f7",
75
+ "@aztec/kv-store": "0.0.1-commit.96bb3f7",
76
+ "@aztec/l1-artifacts": "0.0.1-commit.96bb3f7",
77
+ "@aztec/merkle-tree": "0.0.1-commit.96bb3f7",
78
+ "@aztec/node-keystore": "0.0.1-commit.96bb3f7",
79
+ "@aztec/node-lib": "0.0.1-commit.96bb3f7",
80
+ "@aztec/noir-protocol-circuits-types": "0.0.1-commit.96bb3f7",
81
+ "@aztec/p2p": "0.0.1-commit.96bb3f7",
82
+ "@aztec/protocol-contracts": "0.0.1-commit.96bb3f7",
83
+ "@aztec/prover-client": "0.0.1-commit.96bb3f7",
84
+ "@aztec/sequencer-client": "0.0.1-commit.96bb3f7",
85
+ "@aztec/simulator": "0.0.1-commit.96bb3f7",
86
+ "@aztec/slasher": "0.0.1-commit.96bb3f7",
87
+ "@aztec/stdlib": "0.0.1-commit.96bb3f7",
88
+ "@aztec/telemetry-client": "0.0.1-commit.96bb3f7",
89
+ "@aztec/validator-client": "0.0.1-commit.96bb3f7",
90
+ "@aztec/world-state": "0.0.1-commit.96bb3f7",
92
91
  "koa": "^2.16.1",
93
92
  "koa-router": "^13.1.1",
94
93
  "tslib": "^2.4.0",
@@ -1,11 +1,4 @@
1
- import {
2
- Attributes,
3
- type Histogram,
4
- Metrics,
5
- type TelemetryClient,
6
- type UpDownCounter,
7
- ValueType,
8
- } from '@aztec/telemetry-client';
1
+ import { Attributes, type Histogram, Metrics, type TelemetryClient, type UpDownCounter } from '@aztec/telemetry-client';
9
2
 
10
3
  export class NodeMetrics {
11
4
  private receiveTxCount: UpDownCounter;
@@ -16,23 +9,12 @@ export class NodeMetrics {
16
9
 
17
10
  constructor(client: TelemetryClient, name = 'AztecNode') {
18
11
  const meter = client.getMeter(name);
19
- this.receiveTxCount = meter.createUpDownCounter(Metrics.NODE_RECEIVE_TX_COUNT, {});
20
- this.receiveTxDuration = meter.createHistogram(Metrics.NODE_RECEIVE_TX_DURATION, {
21
- description: 'The duration of the receiveTx method',
22
- unit: 'ms',
23
- valueType: ValueType.INT,
24
- });
12
+ this.receiveTxCount = meter.createUpDownCounter(Metrics.NODE_RECEIVE_TX_COUNT);
13
+ this.receiveTxDuration = meter.createHistogram(Metrics.NODE_RECEIVE_TX_DURATION);
25
14
 
26
- this.snapshotDuration = meter.createHistogram(Metrics.NODE_SNAPSHOT_DURATION, {
27
- description: 'How long taking a snapshot takes',
28
- unit: 'ms',
29
- valueType: ValueType.INT,
30
- });
15
+ this.snapshotDuration = meter.createHistogram(Metrics.NODE_SNAPSHOT_DURATION);
31
16
 
32
- this.snapshotErrorCount = meter.createUpDownCounter(Metrics.NODE_SNAPSHOT_ERROR_COUNT, {
33
- description: 'How many snapshot errors have happened',
34
- valueType: ValueType.INT,
35
- });
17
+ this.snapshotErrorCount = meter.createUpDownCounter(Metrics.NODE_SNAPSHOT_ERROR_COUNT);
36
18
 
37
19
  this.snapshotErrorCount.add(0);
38
20
  }
@@ -1,11 +1,6 @@
1
1
  import { Archiver, createArchiver } from '@aztec/archiver';
2
2
  import { BBCircuitVerifier, QueuedIVCVerifier, TestCircuitVerifier } from '@aztec/bb-prover';
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';
3
+ import { type BlobClientInterface, createBlobClientWithFileStores } from '@aztec/blob-client/client';
9
4
  import {
10
5
  ARCHIVE_HEIGHT,
11
6
  INITIAL_L2_BLOCK_NUM,
@@ -19,7 +14,7 @@ import { createEthereumChain } from '@aztec/ethereum/chain';
19
14
  import { getPublicClient } from '@aztec/ethereum/client';
20
15
  import { RegistryContract, RollupContract } from '@aztec/ethereum/contracts';
21
16
  import type { L1ContractAddresses } from '@aztec/ethereum/l1-contract-addresses';
22
- import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types';
17
+ import { BlockNumber, CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
23
18
  import { compactArray, pick } from '@aztec/foundation/collection';
24
19
  import { Fr } from '@aztec/foundation/curves/bn254';
25
20
  import { EthAddress } from '@aztec/foundation/eth-address';
@@ -36,14 +31,7 @@ import {
36
31
  } from '@aztec/node-lib/factories';
37
32
  import { type P2P, type P2PClientDeps, createP2PClient, getDefaultAllowedSetupFunctions } from '@aztec/p2p';
38
33
  import { ProtocolContractAddress } from '@aztec/protocol-contracts';
39
- import {
40
- BlockBuilder,
41
- GlobalVariableBuilder,
42
- SequencerClient,
43
- type SequencerPublisher,
44
- createValidatorForAcceptingTxs,
45
- } from '@aztec/sequencer-client';
46
- import { CheckpointsBuilder } from '@aztec/sequencer-client';
34
+ import { BlockBuilder, GlobalVariableBuilder, SequencerClient, type SequencerPublisher } from '@aztec/sequencer-client';
47
35
  import { PublicProcessorFactory } from '@aztec/simulator/server';
48
36
  import {
49
37
  AttestationsBlockWatcher,
@@ -59,9 +47,11 @@ import {
59
47
  type DataInBlock,
60
48
  type L2Block,
61
49
  L2BlockHash,
50
+ L2BlockNew,
62
51
  type L2BlockSource,
63
52
  type PublishedL2Block,
64
53
  } from '@aztec/stdlib/block';
54
+ import type { PublishedCheckpoint } from '@aztec/stdlib/checkpoint';
65
55
  import type {
66
56
  ContractClassPublic,
67
57
  ContractDataSource,
@@ -116,10 +106,13 @@ import {
116
106
  trackSpan,
117
107
  } from '@aztec/telemetry-client';
118
108
  import {
109
+ FullNodeCheckpointsBuilder as CheckpointsBuilder,
110
+ FullNodeCheckpointsBuilder,
119
111
  NodeKeystoreAdapter,
120
112
  ValidatorClient,
121
113
  createBlockProposalHandler,
122
114
  createValidatorClient,
115
+ createValidatorForAcceptingTxs,
123
116
  } from '@aztec/validator-client';
124
117
  import { createWorldStateSynchronizer } from '@aztec/world-state';
125
118
 
@@ -191,7 +184,6 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
191
184
  logger?: Logger;
192
185
  publisher?: SequencerPublisher;
193
186
  dateProvider?: DateProvider;
194
- blobClient?: BlobClientInterface;
195
187
  p2pClientDeps?: P2PClientDeps<P2PClientType.Full>;
196
188
  } = {},
197
189
  options: {
@@ -271,24 +263,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
271
263
  );
272
264
  }
273
265
 
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
- });
266
+ const blobClient = await createBlobClientWithFileStores(config, createLogger('node:blob-client:client'));
292
267
 
293
268
  // attempt snapshot sync if possible
294
269
  await trySnapshotSync(config, log);
@@ -334,6 +309,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
334
309
  // We should really not be modifying the config object
335
310
  config.txPublicSetupAllowList = config.txPublicSetupAllowList ?? (await getDefaultAllowedSetupFunctions());
336
311
 
312
+ // Create BlockBuilder for EpochPruneWatcher (slasher functionality)
337
313
  const blockBuilder = new BlockBuilder(
338
314
  { ...config, l1GenesisTime, slotDuration: Number(slotDuration) },
339
315
  worldStateSynchronizer,
@@ -342,20 +318,29 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
342
318
  telemetry,
343
319
  );
344
320
 
321
+ // Create FullNodeCheckpointsBuilder for validator and non-validator block proposal handling
322
+ const validatorCheckpointsBuilder = new FullNodeCheckpointsBuilder(
323
+ { ...config, l1GenesisTime, slotDuration: Number(slotDuration) },
324
+ archiver,
325
+ dateProvider,
326
+ telemetry,
327
+ );
328
+
345
329
  // We'll accumulate sentinel watchers here
346
330
  const watchers: Watcher[] = [];
347
331
 
348
332
  // Create validator client if required
349
333
  const validatorClient = createValidatorClient(config, {
334
+ checkpointsBuilder: validatorCheckpointsBuilder,
335
+ worldState: worldStateSynchronizer,
350
336
  p2pClient,
351
337
  telemetry,
352
338
  dateProvider,
353
339
  epochCache,
354
- blockBuilder,
355
340
  blockSource: archiver,
356
341
  l1ToL2MessageSource: archiver,
357
342
  keyStoreManager,
358
- fileStoreBlobUploadClient: fileStoreUploadClient,
343
+ blobClient,
359
344
  });
360
345
 
361
346
  // If we have a validator client, register it as a source of offenses for the slasher,
@@ -373,7 +358,8 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
373
358
  if (!validatorClient && config.alwaysReexecuteBlockProposals) {
374
359
  log.info('Setting up block proposal reexecution for monitoring');
375
360
  createBlockProposalHandler(config, {
376
- blockBuilder,
361
+ checkpointsBuilder: validatorCheckpointsBuilder,
362
+ worldState: worldStateSynchronizer,
377
363
  epochCache,
378
364
  blockSource: archiver,
379
365
  l1ToL2MessageSource: archiver,
@@ -637,12 +623,24 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
637
623
  return (await this.blockSource.getPublishedBlocks(from, limit)) ?? [];
638
624
  }
639
625
 
626
+ public async getPublishedCheckpoints(from: CheckpointNumber, limit: number): Promise<PublishedCheckpoint[]> {
627
+ return (await this.blockSource.getPublishedCheckpoints(from, limit)) ?? [];
628
+ }
629
+
630
+ public async getL2BlocksNew(from: BlockNumber, limit: number): Promise<L2BlockNew[]> {
631
+ return (await this.blockSource.getL2BlocksNew(from, limit)) ?? [];
632
+ }
633
+
634
+ public async getCheckpointedBlocks(from: BlockNumber, limit: number, proven?: boolean) {
635
+ return (await this.blockSource.getCheckpointedBlocks(from, limit, proven)) ?? [];
636
+ }
637
+
640
638
  /**
641
- * Method to fetch the current base fees.
642
- * @returns The current base fees.
639
+ * Method to fetch the current min L2 fees.
640
+ * @returns The current min L2 fees.
643
641
  */
644
- public async getCurrentBaseFees(): Promise<GasFees> {
645
- return await this.globalVariableBuilder.getCurrentBaseFees();
642
+ public async getCurrentMinFees(): Promise<GasFees> {
643
+ return await this.globalVariableBuilder.getCurrentMinFees();
646
644
  }
647
645
 
648
646
  public async getMaxPriorityFees(): Promise<GasFees> {
@@ -788,6 +786,14 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
788
786
  this.log.info(`Stopped Aztec Node`);
789
787
  }
790
788
 
789
+ /**
790
+ * Returns the blob client used by this node.
791
+ * @internal - Exposed for testing purposes only.
792
+ */
793
+ public getBlobClient(): BlobClientInterface | undefined {
794
+ return this.blobClient;
795
+ }
796
+
791
797
  /**
792
798
  * Method to retrieve pending txs.
793
799
  * @param limit - The number of items to returns
@@ -982,15 +988,28 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
982
988
  }
983
989
 
984
990
  /**
985
- * Returns all the L2 to L1 messages in a block.
986
- * @param blockNumber - The block number at which to get the data.
987
- * @returns The L2 to L1 messages (undefined if the block number is not found).
991
+ * Returns all the L2 to L1 messages in an epoch.
992
+ * @param epoch - The epoch at which to get the data.
993
+ * @returns The L2 to L1 messages (empty array if the epoch is not found).
988
994
  */
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),
995
+ public async getL2ToL1Messages(epoch: EpochNumber): Promise<Fr[][][][]> {
996
+ // Assumes `getBlocksForEpoch` returns blocks in ascending order of block number.
997
+ const blocks = await this.blockSource.getBlocksForEpoch(epoch);
998
+ const blocksInCheckpoints: L2Block[][] = [];
999
+ let previousSlotNumber = SlotNumber.ZERO;
1000
+ let checkpointIndex = -1;
1001
+ for (const block of blocks) {
1002
+ const slotNumber = block.header.globalVariables.slotNumber;
1003
+ if (slotNumber !== previousSlotNumber) {
1004
+ checkpointIndex++;
1005
+ blocksInCheckpoints.push([]);
1006
+ previousSlotNumber = slotNumber;
1007
+ }
1008
+ blocksInCheckpoints[checkpointIndex].push(block);
1009
+ }
1010
+ return blocksInCheckpoints.map(blocks =>
1011
+ blocks.map(block => block.body.txEffects.map(txEffect => txEffect.l2ToL1Msgs)),
992
1012
  );
993
- return block?.body.txEffects.map(txEffect => txEffect.l2ToL1Msgs);
994
1013
  }
995
1014
 
996
1015
  /**
@@ -1246,7 +1265,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1246
1265
  l1ChainId: this.l1ChainId,
1247
1266
  rollupVersion: this.version,
1248
1267
  setupAllowList: this.config.txPublicSetupAllowList ?? (await getDefaultAllowedSetupFunctions()),
1249
- gasFees: await this.getCurrentBaseFees(),
1268
+ gasFees: await this.getCurrentMinFees(),
1250
1269
  skipFeeEnforcement,
1251
1270
  txsPermitted: !this.config.disableTransactions,
1252
1271
  });
@@ -1318,7 +1337,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1318
1337
  }
1319
1338
 
1320
1339
  // And it has an L2 block hash
1321
- const l2BlockHash = await archiver.getL2Tips().then(tips => tips.latest.hash);
1340
+ const l2BlockHash = await archiver.getL2Tips().then(tips => tips.proposed.hash);
1322
1341
  if (!l2BlockHash) {
1323
1342
  this.metrics.recordSnapshotError();
1324
1343
  throw new Error(`Archiver has no latest L2 block hash downloaded. Cannot start snapshot.`);
@@ -1352,7 +1371,7 @@ export class AztecNodeService implements AztecNode, AztecNodeAdmin, Traceable {
1352
1371
  throw new Error('Archiver implementation does not support rollbacks.');
1353
1372
  }
1354
1373
 
1355
- const finalizedBlock = await archiver.getL2Tips().then(tips => tips.finalized.number);
1374
+ const finalizedBlock = await archiver.getL2Tips().then(tips => tips.finalized.block.number);
1356
1375
  if (targetBlock < finalizedBlock) {
1357
1376
  if (force) {
1358
1377
  this.log.warn(`Clearing world state database to allow rolling back behind finalized block ${finalizedBlock}`);
@@ -1,5 +1,5 @@
1
1
  import type { EpochCache } from '@aztec/epoch-cache';
2
- import { BlockNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
2
+ import { BlockNumber, CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/foundation/branded-types';
3
3
  import { countWhile, filterAsync, fromEntries, getEntries, mapValues } from '@aztec/foundation/collection';
4
4
  import { EthAddress } from '@aztec/foundation/eth-address';
5
5
  import { createLogger } from '@aztec/foundation/log';
@@ -19,7 +19,7 @@ import {
19
19
  L2BlockStream,
20
20
  type L2BlockStreamEvent,
21
21
  type L2BlockStreamEventHandler,
22
- getAttestationInfoFromPublishedL2Block,
22
+ getAttestationInfoFromPublishedCheckpoint,
23
23
  } from '@aztec/stdlib/block';
24
24
  import { getEpochAtSlot, getSlotRangeForEpoch, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
25
25
  import type {
@@ -44,8 +44,10 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme
44
44
  protected initialSlot: SlotNumber | undefined;
45
45
  protected lastProcessedSlot: SlotNumber | undefined;
46
46
  // eslint-disable-next-line aztec-custom/no-non-primitive-in-collections
47
- protected slotNumberToBlock: Map<SlotNumber, { blockNumber: BlockNumber; archive: string; attestors: EthAddress[] }> =
48
- new Map();
47
+ protected slotNumberToCheckpoint: Map<
48
+ SlotNumber,
49
+ { checkpointNumber: CheckpointNumber; archive: string; attestors: EthAddress[] }
50
+ > = new Map();
49
51
 
50
52
  constructor(
51
53
  protected epochCache: EpochCache,
@@ -87,39 +89,46 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme
87
89
 
88
90
  public async handleBlockStreamEvent(event: L2BlockStreamEvent): Promise<void> {
89
91
  await this.l2TipsStore.handleBlockStreamEvent(event);
90
- if (event.type === 'blocks-added') {
91
- // Store mapping from slot to archive, block number, and attestors
92
- for (const block of event.blocks) {
93
- this.slotNumberToBlock.set(block.block.header.getSlot(), {
94
- blockNumber: BlockNumber(block.block.number),
95
- archive: block.block.archive.root.toString(),
96
- attestors: getAttestationInfoFromPublishedL2Block(block)
97
- .filter(a => a.status === 'recovered-from-signature')
98
- .map(a => a.address!),
99
- });
100
- }
101
-
102
- // Prune the archive map to only keep at most N entries
103
- const historyLength = this.store.getHistoryLength();
104
- if (this.slotNumberToBlock.size > historyLength) {
105
- const toDelete = Array.from(this.slotNumberToBlock.keys())
106
- .sort((a, b) => Number(a - b))
107
- .slice(0, this.slotNumberToBlock.size - historyLength);
108
- for (const key of toDelete) {
109
- this.slotNumberToBlock.delete(key);
110
- }
111
- }
92
+ if (event.type === 'chain-checkpointed') {
93
+ this.handleCheckpoint(event);
112
94
  } else if (event.type === 'chain-proven') {
113
95
  await this.handleChainProven(event);
114
96
  }
115
97
  }
116
98
 
99
+ protected handleCheckpoint(event: L2BlockStreamEvent) {
100
+ if (event.type !== 'chain-checkpointed') {
101
+ return;
102
+ }
103
+ const checkpoint = event.checkpoint;
104
+
105
+ // Store mapping from slot to archive, checkpoint number, and attestors
106
+ this.slotNumberToCheckpoint.set(checkpoint.checkpoint.header.slotNumber, {
107
+ checkpointNumber: checkpoint.checkpoint.number,
108
+ archive: checkpoint.checkpoint.archive.root.toString(),
109
+ attestors: getAttestationInfoFromPublishedCheckpoint(checkpoint)
110
+ .filter(a => a.status === 'recovered-from-signature')
111
+ .map(a => a.address!),
112
+ });
113
+
114
+ // Prune the archive map to only keep at most N entries
115
+ const historyLength = this.store.getHistoryLength();
116
+ if (this.slotNumberToCheckpoint.size > historyLength) {
117
+ const toDelete = Array.from(this.slotNumberToCheckpoint.keys())
118
+ .sort((a, b) => Number(a - b))
119
+ .slice(0, this.slotNumberToCheckpoint.size - historyLength);
120
+ for (const key of toDelete) {
121
+ this.slotNumberToCheckpoint.delete(key);
122
+ }
123
+ }
124
+ }
125
+
117
126
  protected async handleChainProven(event: L2BlockStreamEvent) {
118
127
  if (event.type !== 'chain-proven') {
119
128
  return;
120
129
  }
121
- const blockNumber = BlockNumber(event.block.number);
122
- const block = await this.archiver.getBlock(blockNumber);
130
+ const blockNumber = event.block.number;
131
+ const block = await this.archiver.getL2BlockNew(blockNumber);
123
132
  if (!block) {
124
133
  this.logger.error(`Failed to get block ${blockNumber}`, { block });
125
134
  return;
@@ -291,8 +300,8 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme
291
300
  return false;
292
301
  }
293
302
 
294
- const archiverLastBlockHash = await this.l2TipsStore.getL2Tips().then(tip => tip.latest.hash);
295
- const p2pLastBlockHash = await this.p2p.getL2Tips().then(tips => tips.latest.hash);
303
+ const archiverLastBlockHash = await this.l2TipsStore.getL2Tips().then(tip => tip.proposed.hash);
304
+ const p2pLastBlockHash = await this.p2p.getL2Tips().then(tips => tips.proposed.hash);
296
305
  const isP2pSynced = archiverLastBlockHash === p2pLastBlockHash;
297
306
  if (!isP2pSynced) {
298
307
  this.logger.debug(`Waiting for P2P client to sync with archiver`, { archiverLastBlockHash, p2pLastBlockHash });
@@ -331,8 +340,8 @@ export class Sentinel extends (EventEmitter as new () => WatcherEmitter) impleme
331
340
  // or all attestations for all proposals in the slot if no block was mined.
332
341
  // We gather from both p2p (contains the ones seen on the p2p layer) and archiver
333
342
  // (contains the ones synced from mined blocks, which we may have missed from p2p).
334
- const block = this.slotNumberToBlock.get(slot);
335
- const p2pAttested = await this.p2p.getAttestationsForSlot(slot, block?.archive);
343
+ const block = this.slotNumberToCheckpoint.get(slot);
344
+ const p2pAttested = await this.p2p.getCheckpointAttestationsForSlot(slot, block?.archive);
336
345
  // Filter out attestations with invalid signatures
337
346
  const p2pAttestors = p2pAttested.map(a => a.getSender()).filter((s): s is EthAddress => s !== undefined);
338
347
  const attestors = new Set(