@aztec/sequencer-client 4.0.0-nightly.20260112 → 4.0.0-nightly.20260114

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.
Files changed (59) hide show
  1. package/dest/client/sequencer-client.d.ts +4 -5
  2. package/dest/client/sequencer-client.d.ts.map +1 -1
  3. package/dest/config.d.ts +1 -1
  4. package/dest/config.d.ts.map +1 -1
  5. package/dest/config.js +8 -1
  6. package/dest/index.d.ts +2 -3
  7. package/dest/index.d.ts.map +1 -1
  8. package/dest/index.js +1 -2
  9. package/dest/publisher/sequencer-publisher.d.ts +15 -15
  10. package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
  11. package/dest/publisher/sequencer-publisher.js +44 -46
  12. package/dest/sequencer/block_builder.d.ts +2 -2
  13. package/dest/sequencer/block_builder.d.ts.map +1 -1
  14. package/dest/sequencer/block_builder.js +5 -5
  15. package/dest/sequencer/checkpoint_proposal_job.d.ts +11 -8
  16. package/dest/sequencer/checkpoint_proposal_job.d.ts.map +1 -1
  17. package/dest/sequencer/checkpoint_proposal_job.js +56 -30
  18. package/dest/sequencer/index.d.ts +1 -2
  19. package/dest/sequencer/index.d.ts.map +1 -1
  20. package/dest/sequencer/index.js +0 -1
  21. package/dest/sequencer/metrics.d.ts +3 -3
  22. package/dest/sequencer/metrics.d.ts.map +1 -1
  23. package/dest/sequencer/metrics.js +4 -4
  24. package/dest/sequencer/sequencer.d.ts +13 -12
  25. package/dest/sequencer/sequencer.d.ts.map +1 -1
  26. package/dest/sequencer/sequencer.js +30 -28
  27. package/dest/test/index.d.ts +2 -3
  28. package/dest/test/index.d.ts.map +1 -1
  29. package/dest/test/mock_checkpoint_builder.d.ts +13 -3
  30. package/dest/test/mock_checkpoint_builder.d.ts.map +1 -1
  31. package/dest/test/mock_checkpoint_builder.js +27 -2
  32. package/dest/test/utils.d.ts +8 -4
  33. package/dest/test/utils.d.ts.map +1 -1
  34. package/dest/test/utils.js +19 -9
  35. package/package.json +27 -27
  36. package/src/client/sequencer-client.ts +3 -4
  37. package/src/config.ts +7 -0
  38. package/src/index.ts +0 -3
  39. package/src/publisher/sequencer-publisher.ts +75 -70
  40. package/src/sequencer/block_builder.ts +5 -3
  41. package/src/sequencer/checkpoint_proposal_job.ts +68 -38
  42. package/src/sequencer/index.ts +0 -1
  43. package/src/sequencer/metrics.ts +4 -4
  44. package/src/sequencer/sequencer.ts +47 -34
  45. package/src/test/index.ts +1 -2
  46. package/src/test/mock_checkpoint_builder.ts +45 -3
  47. package/src/test/utils.ts +36 -9
  48. package/dest/sequencer/checkpoint_builder.d.ts +0 -63
  49. package/dest/sequencer/checkpoint_builder.d.ts.map +0 -1
  50. package/dest/sequencer/checkpoint_builder.js +0 -131
  51. package/dest/tx_validator/nullifier_cache.d.ts +0 -14
  52. package/dest/tx_validator/nullifier_cache.d.ts.map +0 -1
  53. package/dest/tx_validator/nullifier_cache.js +0 -24
  54. package/dest/tx_validator/tx_validator_factory.d.ts +0 -18
  55. package/dest/tx_validator/tx_validator_factory.d.ts.map +0 -1
  56. package/dest/tx_validator/tx_validator_factory.js +0 -53
  57. package/src/sequencer/checkpoint_builder.ts +0 -217
  58. package/src/tx_validator/nullifier_cache.ts +0 -30
  59. package/src/tx_validator/tx_validator_factory.ts +0 -133
@@ -43,7 +43,7 @@ export class SequencerMetrics {
43
43
  private blockProposalPrecheckFailed: UpDownCounter;
44
44
  private checkpointSuccess: UpDownCounter;
45
45
  private slashingAttempts: UpDownCounter;
46
- private blockAttestationDelay: Histogram;
46
+ private checkpointAttestationDelay: Histogram;
47
47
 
48
48
  // Fisherman fee analysis metrics
49
49
  private fishermanWouldBeIncluded: UpDownCounter;
@@ -75,7 +75,7 @@ export class SequencerMetrics {
75
75
 
76
76
  this.stateTransitionBufferDuration = this.meter.createHistogram(Metrics.SEQUENCER_STATE_TRANSITION_BUFFER_DURATION);
77
77
 
78
- this.blockAttestationDelay = this.meter.createHistogram(Metrics.SEQUENCER_BLOCK_ATTESTATION_DELAY);
78
+ this.checkpointAttestationDelay = this.meter.createHistogram(Metrics.SEQUENCER_CHECKPOINT_ATTESTATION_DELAY);
79
79
 
80
80
  // Init gauges and counters
81
81
  this.blockCounter.add(0, {
@@ -156,8 +156,8 @@ export class SequencerMetrics {
156
156
  this.timeToCollectAttestations.record(0);
157
157
  }
158
158
 
159
- public recordBlockAttestationDelay(duration: number) {
160
- this.blockAttestationDelay.record(duration);
159
+ public recordCheckpointAttestationDelay(duration: number) {
160
+ this.checkpointAttestationDelay.record(duration);
161
161
  }
162
162
 
163
163
  public recordCollectedAttestations(count: number, durationMs: number) {
@@ -12,7 +12,7 @@ import type { DateProvider } from '@aztec/foundation/timer';
12
12
  import type { TypedEventEmitter } from '@aztec/foundation/types';
13
13
  import type { P2P } from '@aztec/p2p';
14
14
  import type { SlasherClientInterface } from '@aztec/slasher';
15
- import type { L2BlockNew, L2BlockSource, ValidateBlockResult } from '@aztec/stdlib/block';
15
+ import type { L2BlockNew, L2BlockSink, L2BlockSource, ValidateCheckpointResult } from '@aztec/stdlib/block';
16
16
  import type { Checkpoint } from '@aztec/stdlib/checkpoint';
17
17
  import { getSlotAtTimestamp, getSlotStartBuildTimestamp } from '@aztec/stdlib/epoch-helpers';
18
18
  import {
@@ -25,15 +25,14 @@ import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
25
25
  import { pickFromSchema } from '@aztec/stdlib/schemas';
26
26
  import { MerkleTreeId } from '@aztec/stdlib/trees';
27
27
  import { Attributes, type TelemetryClient, type Tracer, getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
28
- import type { ValidatorClient } from '@aztec/validator-client';
28
+ import { FullNodeCheckpointsBuilder, type ValidatorClient } from '@aztec/validator-client';
29
29
 
30
30
  import EventEmitter from 'node:events';
31
31
 
32
32
  import { DefaultSequencerConfig } from '../config.js';
33
33
  import type { GlobalVariableBuilder } from '../global_variable_builder/global_builder.js';
34
34
  import type { SequencerPublisherFactory } from '../publisher/sequencer-publisher-factory.js';
35
- import type { InvalidateBlockRequest, SequencerPublisher } from '../publisher/sequencer-publisher.js';
36
- import { FullNodeCheckpointsBuilder } from './checkpoint_builder.js';
35
+ import type { InvalidateCheckpointRequest, SequencerPublisher } from '../publisher/sequencer-publisher.js';
37
36
  import { CheckpointProposalJob } from './checkpoint_proposal_job.js';
38
37
  import { CheckpointVoter } from './checkpoint_voter.js';
39
38
  import { SequencerInterruptedError, SequencerTooSlowError } from './errors.js';
@@ -91,7 +90,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
91
90
  protected p2pClient: P2P,
92
91
  protected worldState: WorldStateSynchronizer,
93
92
  protected slasherClient: SlasherClientInterface | undefined,
94
- protected l2BlockSource: L2BlockSource,
93
+ protected l2BlockSource: L2BlockSource & L2BlockSink,
95
94
  protected l1ToL2MessageSource: L1ToL2MessageSource,
96
95
  protected checkpointsBuilder: FullNodeCheckpointsBuilder,
97
96
  protected l1Constants: SequencerRollupConstants,
@@ -203,7 +202,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
203
202
  const { slot, ts, now, epoch } = this.epochCache.getEpochAndSlotInNextL1Slot();
204
203
 
205
204
  // Check if we are synced and it's our slot, grab a publisher, check previous block invalidation, etc
206
- const checkpointProposalJob = await this.prepareCheckpointProposal(slot, ts, now);
205
+ const checkpointProposalJob = await this.prepareCheckpointProposal(epoch, slot, ts, now);
207
206
  if (!checkpointProposalJob) {
208
207
  return;
209
208
  }
@@ -235,6 +234,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
235
234
  */
236
235
  @trackSpan('Sequencer.prepareCheckpointProposal')
237
236
  private async prepareCheckpointProposal(
237
+ epoch: EpochNumber,
238
238
  slot: SlotNumber,
239
239
  ts: bigint,
240
240
  now: bigint,
@@ -264,8 +264,8 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
264
264
  return undefined;
265
265
  }
266
266
 
267
- // TODO(palla/mbps): Compute proper checkpoint number
268
- const checkpointNumber = CheckpointNumber.fromBlockNumber(BlockNumber(syncedTo.blockNumber + 1));
267
+ // Next checkpoint follows from the last synced one
268
+ const checkpointNumber = CheckpointNumber(syncedTo.checkpointNumber + 1);
269
269
 
270
270
  const logCtx = {
271
271
  now,
@@ -281,9 +281,9 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
281
281
  this.setState(SequencerState.PROPOSER_CHECK, slot);
282
282
  const [canPropose, proposer] = await this.checkCanPropose(slot);
283
283
 
284
- // If we are not a proposer check if we should invalidate a invalid block, and bail
284
+ // If we are not a proposer check if we should invalidate an invalid checkpoint, and bail
285
285
  if (!canPropose) {
286
- await this.considerInvalidatingBlock(syncedTo, slot);
286
+ await this.considerInvalidatingCheckpoint(syncedTo, slot);
287
287
  return undefined;
288
288
  }
289
289
 
@@ -313,15 +313,14 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
313
313
  }
314
314
 
315
315
  // Prepare invalidation request if the pending chain is invalid (returns undefined if no need)
316
- // TODO(palla/mbps): We need to invalidate checkpoints, not blocks
317
- const invalidateBlock = await publisher.simulateInvalidateBlock(syncedTo.pendingChainValidationStatus);
316
+ const invalidateCheckpoint = await publisher.simulateInvalidateCheckpoint(syncedTo.pendingChainValidationStatus);
318
317
 
319
318
  // Check with the rollup contract if we can indeed propose at the next L2 slot. This check should not fail
320
319
  // if all the previous checks are good, but we do it just in case.
321
320
  const canProposeCheck = await publisher.canProposeAtNextEthBlock(
322
321
  syncedTo.archive,
323
322
  proposer ?? EthAddress.ZERO,
324
- invalidateBlock,
323
+ invalidateCheckpoint,
325
324
  );
326
325
 
327
326
  if (canProposeCheck === undefined) {
@@ -359,39 +358,44 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
359
358
 
360
359
  // Create and return the checkpoint proposal job
361
360
  return this.createCheckpointProposalJob(
361
+ epoch,
362
362
  slot,
363
363
  checkpointNumber,
364
364
  syncedTo.blockNumber,
365
365
  proposer,
366
366
  publisher,
367
367
  attestorAddress,
368
- invalidateBlock,
368
+ invalidateCheckpoint,
369
369
  );
370
370
  }
371
371
 
372
372
  protected createCheckpointProposalJob(
373
+ epoch: EpochNumber,
373
374
  slot: SlotNumber,
374
375
  checkpointNumber: CheckpointNumber,
375
376
  syncedToBlockNumber: BlockNumber,
376
377
  proposer: EthAddress | undefined,
377
378
  publisher: SequencerPublisher,
378
379
  attestorAddress: EthAddress,
379
- invalidateBlock: InvalidateBlockRequest | undefined,
380
+ invalidateCheckpoint: InvalidateCheckpointRequest | undefined,
380
381
  ): CheckpointProposalJob {
381
382
  return new CheckpointProposalJob(
383
+ epoch,
382
384
  slot,
383
385
  checkpointNumber,
384
386
  syncedToBlockNumber,
385
387
  proposer,
386
388
  publisher,
387
389
  attestorAddress,
388
- invalidateBlock,
390
+ invalidateCheckpoint,
389
391
  this.validatorClient,
390
392
  this.globalsBuilder,
391
393
  this.p2pClient,
392
394
  this.worldState,
393
395
  this.l1ToL2MessageSource,
396
+ this.l2BlockSource,
394
397
  this.checkpointsBuilder,
398
+ this.l2BlockSource,
395
399
  this.l1Constants,
396
400
  this.config,
397
401
  this.timetable,
@@ -471,9 +475,9 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
471
475
  number: syncSummary.latestBlockNumber,
472
476
  hash: syncSummary.latestBlockHash,
473
477
  })),
474
- this.l2BlockSource.getL2Tips().then(t => t.latest),
478
+ this.l2BlockSource.getL2Tips().then(t => t.proposed),
475
479
  this.p2pClient.getStatus().then(p2p => p2p.syncedToL2Block),
476
- this.l1ToL2MessageSource.getL2Tips().then(t => t.latest),
480
+ this.l1ToL2MessageSource.getL2Tips().then(t => t.proposed),
477
481
  this.l2BlockSource.getPendingChainValidationStatus(),
478
482
  ] as const);
479
483
 
@@ -481,6 +485,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
481
485
 
482
486
  // Handle zero as a special case, since the block hash won't match across services if we're changing the prefilled data for the genesis block,
483
487
  // as the world state can compute the new genesis block hash, but other components use the hardcoded constant.
488
+ // TODO(palla/mbps): Fix the above. All components should be able to handle dynamic genesis block hashes.
484
489
  const result =
485
490
  (l2BlockSource.number === 0 && worldState.number === 0 && p2p.number === 0 && l1ToL2MessageSource.number === 0) ||
486
491
  (worldState.hash === l2BlockSource.hash &&
@@ -496,7 +501,13 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
496
501
  const blockNumber = worldState.number;
497
502
  if (blockNumber < INITIAL_L2_BLOCK_NUM) {
498
503
  const archive = new Fr((await this.worldState.getCommitted().getTreeInfo(MerkleTreeId.ARCHIVE)).root);
499
- return { blockNumber: BlockNumber(INITIAL_L2_BLOCK_NUM - 1), archive, l1Timestamp, pendingChainValidationStatus };
504
+ return {
505
+ checkpointNumber: CheckpointNumber.ZERO,
506
+ blockNumber: BlockNumber.ZERO,
507
+ archive,
508
+ l1Timestamp,
509
+ pendingChainValidationStatus,
510
+ };
500
511
  }
501
512
 
502
513
  const block = await this.l2BlockSource.getL2BlockNew(blockNumber);
@@ -509,6 +520,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
509
520
  return {
510
521
  block,
511
522
  blockNumber: block.number,
523
+ checkpointNumber: block.checkpointNumber,
512
524
  archive: block.archive.root,
513
525
  l1Timestamp,
514
526
  pendingChainValidationStatus,
@@ -629,12 +641,12 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
629
641
  }
630
642
 
631
643
  /**
632
- * Considers invalidating a block if the pending chain is invalid. Depends on how long the invalid block
644
+ * Considers invalidating a checkpoint if the pending chain is invalid. Depends on how long the invalid checkpoint
633
645
  * has been there without being invalidated and whether the sequencer is in the committee or not. We always
634
646
  * have the proposer try to invalidate, but if they fail, the sequencers in the committee are expected to try,
635
647
  * and if they fail, any sequencer will try as well.
636
648
  */
637
- protected async considerInvalidatingBlock(
649
+ protected async considerInvalidatingCheckpoint(
638
650
  syncedTo: SequencerSyncCheckResult,
639
651
  currentSlot: SlotNumber,
640
652
  ): Promise<void> {
@@ -643,18 +655,18 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
643
655
  return;
644
656
  }
645
657
 
646
- const invalidBlockNumber = pendingChainValidationStatus.block.blockNumber;
647
- const invalidBlockTimestamp = pendingChainValidationStatus.block.timestamp;
648
- const timeSinceChainInvalid = this.dateProvider.nowInSeconds() - Number(invalidBlockTimestamp);
658
+ const invalidCheckpointNumber = pendingChainValidationStatus.checkpoint.checkpointNumber;
659
+ const invalidCheckpointTimestamp = pendingChainValidationStatus.checkpoint.timestamp;
660
+ const timeSinceChainInvalid = this.dateProvider.nowInSeconds() - Number(invalidCheckpointTimestamp);
649
661
  const ourValidatorAddresses = this.validatorClient.getValidatorAddresses();
650
662
 
651
663
  const { secondsBeforeInvalidatingBlockAsCommitteeMember, secondsBeforeInvalidatingBlockAsNonCommitteeMember } =
652
664
  this.config;
653
665
 
654
666
  const logData = {
655
- invalidL1Timestamp: invalidBlockTimestamp,
667
+ invalidL1Timestamp: invalidCheckpointTimestamp,
656
668
  l1Timestamp,
657
- invalidBlock: pendingChainValidationStatus.block,
669
+ invalidCheckpoint: pendingChainValidationStatus.checkpoint,
658
670
  secondsBeforeInvalidatingBlockAsCommitteeMember,
659
671
  secondsBeforeInvalidatingBlockAsNonCommitteeMember,
660
672
  ourValidatorAddresses,
@@ -700,25 +712,25 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
700
712
 
701
713
  const { publisher } = await this.publisherFactory.create(validatorToUse);
702
714
 
703
- const invalidateBlock = await publisher.simulateInvalidateBlock(pendingChainValidationStatus);
704
- if (!invalidateBlock) {
705
- this.log.warn(`Failed to simulate invalidate block`, logData);
715
+ const invalidateCheckpoint = await publisher.simulateInvalidateCheckpoint(pendingChainValidationStatus);
716
+ if (!invalidateCheckpoint) {
717
+ this.log.warn(`Failed to simulate invalidate checkpoint`, logData);
706
718
  return;
707
719
  }
708
720
 
709
721
  this.log.info(
710
722
  invalidateAsCommitteeMember
711
- ? `Invalidating block ${invalidBlockNumber} as committee member`
712
- : `Invalidating block ${invalidBlockNumber} as non-committee member`,
723
+ ? `Invalidating checkpoint ${invalidCheckpointNumber} as committee member`
724
+ : `Invalidating checkpoint ${invalidCheckpointNumber} as non-committee member`,
713
725
  logData,
714
726
  );
715
727
 
716
- publisher.enqueueInvalidateBlock(invalidateBlock);
728
+ publisher.enqueueInvalidateCheckpoint(invalidateCheckpoint);
717
729
 
718
730
  if (!this.config.fishermanMode) {
719
731
  await publisher.sendRequests();
720
732
  } else {
721
- this.log.info('Invalidating block in fisherman mode, clearing pending requests');
733
+ this.log.info('Invalidating checkpoint in fisherman mode, clearing pending requests');
722
734
  publisher.clearPendingRequests();
723
735
  }
724
736
  }
@@ -792,8 +804,9 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
792
804
 
793
805
  type SequencerSyncCheckResult = {
794
806
  block?: L2BlockNew;
807
+ checkpointNumber: CheckpointNumber;
795
808
  blockNumber: BlockNumber;
796
809
  archive: Fr;
797
810
  l1Timestamp: bigint;
798
- pendingChainValidationStatus: ValidateBlockResult;
811
+ pendingChainValidationStatus: ValidateCheckpointResult;
799
812
  };
package/src/test/index.ts CHANGED
@@ -1,12 +1,11 @@
1
1
  import type { L1TxUtilsWithBlobs } from '@aztec/ethereum/l1-tx-utils-with-blobs';
2
2
  import type { PublisherManager } from '@aztec/ethereum/publisher-manager';
3
3
  import type { PublicProcessorFactory } from '@aztec/simulator/server';
4
- import type { ValidatorClient } from '@aztec/validator-client';
4
+ import type { FullNodeCheckpointsBuilder, ValidatorClient } from '@aztec/validator-client';
5
5
 
6
6
  import { SequencerClient } from '../client/sequencer-client.js';
7
7
  import type { SequencerPublisherFactory } from '../publisher/sequencer-publisher-factory.js';
8
8
  import type { SequencerPublisher } from '../publisher/sequencer-publisher.js';
9
- import type { FullNodeCheckpointsBuilder } from '../sequencer/checkpoint_builder.js';
10
9
  import { Sequencer } from '../sequencer/sequencer.js';
11
10
  import type { SequencerTimetable } from '../sequencer/timetable.js';
12
11
 
@@ -9,12 +9,11 @@ import type { FullNodeBlockBuilderConfig, PublicProcessorLimits } from '@aztec/s
9
9
  import { CheckpointHeader } from '@aztec/stdlib/rollup';
10
10
  import { makeAppendOnlyTreeSnapshot } from '@aztec/stdlib/testing';
11
11
  import type { CheckpointGlobalVariables, Tx } from '@aztec/stdlib/tx';
12
-
13
12
  import type {
14
13
  BuildBlockInCheckpointResult,
15
14
  CheckpointBuilder,
16
15
  FullNodeCheckpointsBuilder,
17
- } from '../sequencer/checkpoint_builder.js';
16
+ } from '@aztec/validator-client';
18
17
 
19
18
  /**
20
19
  * A fake CheckpointBuilder for testing that implements the same interface as the real one.
@@ -189,6 +188,14 @@ export class MockCheckpointsBuilder implements FunctionsOf<FullNodeCheckpointsBu
189
188
  checkpointNumber: CheckpointNumber;
190
189
  constants: CheckpointGlobalVariables;
191
190
  l1ToL2Messages: Fr[];
191
+ previousCheckpointOutHashes: Fr[];
192
+ }> = [];
193
+ public openCheckpointCalls: Array<{
194
+ checkpointNumber: CheckpointNumber;
195
+ constants: CheckpointGlobalVariables;
196
+ l1ToL2Messages: Fr[];
197
+ previousCheckpointOutHashes: Fr[];
198
+ existingBlocks: L2BlockNew[];
192
199
  }> = [];
193
200
  public updateConfigCalls: Array<Partial<FullNodeBlockBuilderConfig>> = [];
194
201
 
@@ -218,6 +225,15 @@ export class MockCheckpointsBuilder implements FunctionsOf<FullNodeCheckpointsBu
218
225
  return this.checkpointBuilder;
219
226
  }
220
227
 
228
+ getConfig(): FullNodeBlockBuilderConfig {
229
+ return {
230
+ l1GenesisTime: 0n,
231
+ slotDuration: 24,
232
+ l1ChainId: 1,
233
+ rollupVersion: 1,
234
+ };
235
+ }
236
+
221
237
  updateConfig(config: Partial<FullNodeBlockBuilderConfig>): void {
222
238
  this.updateConfigCalls.push(config);
223
239
  }
@@ -226,9 +242,34 @@ export class MockCheckpointsBuilder implements FunctionsOf<FullNodeCheckpointsBu
226
242
  checkpointNumber: CheckpointNumber,
227
243
  constants: CheckpointGlobalVariables,
228
244
  l1ToL2Messages: Fr[],
245
+ previousCheckpointOutHashes: Fr[],
246
+ _fork: unknown,
247
+ ): Promise<CheckpointBuilder> {
248
+ this.startCheckpointCalls.push({ checkpointNumber, constants, l1ToL2Messages, previousCheckpointOutHashes });
249
+
250
+ if (!this.checkpointBuilder) {
251
+ // Auto-create a builder if none was set
252
+ this.checkpointBuilder = new MockCheckpointBuilder(constants, checkpointNumber);
253
+ }
254
+
255
+ return Promise.resolve(this.checkpointBuilder as unknown as CheckpointBuilder);
256
+ }
257
+
258
+ openCheckpoint(
259
+ checkpointNumber: CheckpointNumber,
260
+ constants: CheckpointGlobalVariables,
261
+ l1ToL2Messages: Fr[],
262
+ previousCheckpointOutHashes: Fr[],
229
263
  _fork: unknown,
264
+ existingBlocks: L2BlockNew[] = [],
230
265
  ): Promise<CheckpointBuilder> {
231
- this.startCheckpointCalls.push({ checkpointNumber, constants, l1ToL2Messages });
266
+ this.openCheckpointCalls.push({
267
+ checkpointNumber,
268
+ constants,
269
+ l1ToL2Messages,
270
+ previousCheckpointOutHashes,
271
+ existingBlocks,
272
+ });
232
273
 
233
274
  if (!this.checkpointBuilder) {
234
275
  // Auto-create a builder if none was set
@@ -242,6 +283,7 @@ export class MockCheckpointsBuilder implements FunctionsOf<FullNodeCheckpointsBu
242
283
  reset(): void {
243
284
  this.checkpointBuilder = undefined;
244
285
  this.startCheckpointCalls = [];
286
+ this.openCheckpointCalls = [];
245
287
  this.updateConfigCalls = [];
246
288
  }
247
289
  }
package/src/test/utils.ts CHANGED
@@ -8,7 +8,7 @@ import { Signature } from '@aztec/foundation/eth-signature';
8
8
  import type { P2P } from '@aztec/p2p';
9
9
  import { PublicDataWrite } from '@aztec/stdlib/avm';
10
10
  import { CommitteeAttestation, L2BlockNew } from '@aztec/stdlib/block';
11
- import { BlockAttestation, BlockProposal, ConsensusPayload } from '@aztec/stdlib/p2p';
11
+ import { BlockProposal, CheckpointAttestation, CheckpointProposal, ConsensusPayload } from '@aztec/stdlib/p2p';
12
12
  import { CheckpointHeader } from '@aztec/stdlib/rollup';
13
13
  import { makeAppendOnlyTreeSnapshot, mockTxForRollup } from '@aztec/stdlib/testing';
14
14
  import { BlockHeader, GlobalVariables, type Tx, makeProcessedTxFromPrivateOnlyTx } from '@aztec/stdlib/tx';
@@ -80,6 +80,7 @@ function createCheckpointHeaderFromBlock(block: L2BlockNew): CheckpointHeader {
80
80
  Fr.random(), // blockHeadersHash - mock value for testing
81
81
  Fr.random(), // blobsHash - mock value for testing
82
82
  Fr.random(), // inHash - mock value for testing
83
+ Fr.random(), // outHash - mock value for testing
83
84
  gv.slotNumber,
84
85
  gv.timestamp,
85
86
  gv.coinbase,
@@ -93,23 +94,49 @@ function createCheckpointHeaderFromBlock(block: L2BlockNew): CheckpointHeader {
93
94
  * Creates a block proposal from a block and signature
94
95
  */
95
96
  export function createBlockProposal(block: L2BlockNew, signature: Signature): BlockProposal {
96
- const checkpointHeader = createCheckpointHeaderFromBlock(block);
97
- const consensusPayload = new ConsensusPayload(checkpointHeader, block.archive.root);
98
97
  const txHashes = block.body.txEffects.map(tx => tx.txHash);
99
- return new BlockProposal(consensusPayload, signature, txHashes);
98
+ return new BlockProposal(
99
+ block.header,
100
+ block.indexWithinCheckpoint,
101
+ Fr.ZERO, // inHash - using zero for testing
102
+ block.archive.root,
103
+ txHashes,
104
+ signature,
105
+ );
100
106
  }
101
107
 
102
108
  /**
103
- * Creates a block attestation from a block and signature.
109
+ * Creates a checkpoint proposal from a block and signature
110
+ */
111
+ export function createCheckpointProposal(
112
+ block: L2BlockNew,
113
+ checkpointSignature: Signature,
114
+ blockSignature?: Signature,
115
+ ): CheckpointProposal {
116
+ const txHashes = block.body.txEffects.map(tx => tx.txHash);
117
+ const checkpointHeader = createCheckpointHeaderFromBlock(block);
118
+ return new CheckpointProposal(checkpointHeader, block.archive.root, checkpointSignature, {
119
+ blockHeader: block.header,
120
+ indexWithinCheckpoint: block.indexWithinCheckpoint,
121
+ txHashes,
122
+ signature: blockSignature ?? checkpointSignature, // Use checkpoint signature as block signature if not provided
123
+ });
124
+ }
125
+
126
+ /**
127
+ * Creates a checkpoint attestation from a block and signature.
104
128
  * Note: We manually set the sender since we use random signatures in tests.
105
129
  * In production, the sender is recovered from the signature.
106
130
  */
107
- export function createBlockAttestation(block: L2BlockNew, signature: Signature, sender: EthAddress): BlockAttestation {
131
+ export function createCheckpointAttestation(
132
+ block: L2BlockNew,
133
+ signature: Signature,
134
+ sender: EthAddress,
135
+ ): CheckpointAttestation {
108
136
  const checkpointHeader = createCheckpointHeaderFromBlock(block);
109
- const consensusPayload = new ConsensusPayload(checkpointHeader, block.archive.root);
110
- const attestation = new BlockAttestation(consensusPayload, signature, signature);
137
+ const payload = new ConsensusPayload(checkpointHeader, block.archive.root);
138
+ const attestation = new CheckpointAttestation(payload, signature, signature);
111
139
  // Set sender directly for testing (bypasses signature recovery)
112
-
113
140
  (attestation as any).sender = sender;
114
141
  return attestation;
115
142
  }
@@ -1,63 +0,0 @@
1
- import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types';
2
- import { Fr } from '@aztec/foundation/curves/bn254';
3
- import { DateProvider, Timer } from '@aztec/foundation/timer';
4
- import { LightweightCheckpointBuilder } from '@aztec/prover-client/light';
5
- import { PublicProcessor } from '@aztec/simulator/server';
6
- import { L2BlockNew } from '@aztec/stdlib/block';
7
- import { Checkpoint } from '@aztec/stdlib/checkpoint';
8
- import type { ContractDataSource } from '@aztec/stdlib/contract';
9
- import { Gas } from '@aztec/stdlib/gas';
10
- import { type FullNodeBlockBuilderConfig, type MerkleTreeWriteOperations, type PublicProcessorLimits } from '@aztec/stdlib/interfaces/server';
11
- import { type CheckpointGlobalVariables, type FailedTx, GlobalVariables, Tx } from '@aztec/stdlib/tx';
12
- import { type TelemetryClient } from '@aztec/telemetry-client';
13
- export interface BuildBlockInCheckpointResult {
14
- block: L2BlockNew;
15
- publicGas: Gas;
16
- publicProcessorDuration: number;
17
- numTxs: number;
18
- failedTxs: FailedTx[];
19
- blockBuildingTimer: Timer;
20
- usedTxs: Tx[];
21
- }
22
- /**
23
- * Builder for a single checkpoint. Handles building blocks within the checkpoint
24
- * and completing it.
25
- */
26
- export declare class CheckpointBuilder {
27
- private checkpointBuilder;
28
- private fork;
29
- private config;
30
- private contractDataSource;
31
- private dateProvider;
32
- private telemetryClient;
33
- constructor(checkpointBuilder: LightweightCheckpointBuilder, fork: MerkleTreeWriteOperations, config: FullNodeBlockBuilderConfig, contractDataSource: ContractDataSource, dateProvider: DateProvider, telemetryClient: TelemetryClient);
34
- getConstantData(): CheckpointGlobalVariables;
35
- /**
36
- * Builds a single block within this checkpoint.
37
- */
38
- buildBlock(pendingTxs: Iterable<Tx> | AsyncIterable<Tx>, blockNumber: BlockNumber, timestamp: bigint, opts: PublicProcessorLimits): Promise<BuildBlockInCheckpointResult>;
39
- /** Completes the checkpoint and returns it. */
40
- completeCheckpoint(): Promise<Checkpoint>;
41
- /** Gets the checkpoint currently in progress. */
42
- getCheckpoint(): Promise<Checkpoint>;
43
- protected makeBlockBuilderDeps(globalVariables: GlobalVariables, fork: MerkleTreeWriteOperations): Promise<{
44
- processor: PublicProcessor;
45
- validator: import("@aztec/stdlib/interfaces/server").PublicProcessorValidator;
46
- }>;
47
- }
48
- /**
49
- * Factory for creating checkpoint builders.
50
- */
51
- export declare class FullNodeCheckpointsBuilder {
52
- private config;
53
- private contractDataSource;
54
- private dateProvider;
55
- private telemetryClient;
56
- constructor(config: FullNodeBlockBuilderConfig, contractDataSource: ContractDataSource, dateProvider: DateProvider, telemetryClient?: TelemetryClient);
57
- updateConfig(config: Partial<FullNodeBlockBuilderConfig>): void;
58
- /**
59
- * Starts a new checkpoint and returns a CheckpointBuilder to build blocks within it.
60
- */
61
- startCheckpoint(checkpointNumber: CheckpointNumber, constants: CheckpointGlobalVariables, l1ToL2Messages: Fr[], fork: MerkleTreeWriteOperations): Promise<CheckpointBuilder>;
62
- }
63
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2twb2ludF9idWlsZGVyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VxdWVuY2VyL2NoZWNrcG9pbnRfYnVpbGRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsV0FBVyxFQUFFLGdCQUFnQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFaEYsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBR3BELE9BQU8sRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFXLE1BQU0seUJBQXlCLENBQUM7QUFFdkUsT0FBTyxFQUFFLDRCQUE0QixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDMUUsT0FBTyxFQUdMLGVBQWUsRUFFaEIsTUFBTSx5QkFBeUIsQ0FBQztBQUNqQyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDakQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3RELE9BQU8sS0FBSyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDakUsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ3hDLE9BQU8sRUFDTCxLQUFLLDBCQUEwQixFQUUvQixLQUFLLHlCQUF5QixFQUM5QixLQUFLLHFCQUFxQixFQUMzQixNQUFNLGlDQUFpQyxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxLQUFLLHlCQUF5QixFQUFFLEtBQUssUUFBUSxFQUFFLGVBQWUsRUFBRSxFQUFFLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUN0RyxPQUFPLEVBQUUsS0FBSyxlQUFlLEVBQXNCLE1BQU0seUJBQXlCLENBQUM7QUFNbkYsTUFBTSxXQUFXLDRCQUE0QjtJQUMzQyxLQUFLLEVBQUUsVUFBVSxDQUFDO0lBQ2xCLFNBQVMsRUFBRSxHQUFHLENBQUM7SUFDZix1QkFBdUIsRUFBRSxNQUFNLENBQUM7SUFDaEMsTUFBTSxFQUFFLE1BQU0sQ0FBQztJQUNmLFNBQVMsRUFBRSxRQUFRLEVBQUUsQ0FBQztJQUN0QixrQkFBa0IsRUFBRSxLQUFLLENBQUM7SUFDMUIsT0FBTyxFQUFFLEVBQUUsRUFBRSxDQUFDO0NBQ2Y7QUFFRDs7O0dBR0c7QUFDSCxxQkFBYSxpQkFBaUI7SUFFMUIsT0FBTyxDQUFDLGlCQUFpQjtJQUN6QixPQUFPLENBQUMsSUFBSTtJQUNaLE9BQU8sQ0FBQyxNQUFNO0lBQ2QsT0FBTyxDQUFDLGtCQUFrQjtJQUMxQixPQUFPLENBQUMsWUFBWTtJQUNwQixPQUFPLENBQUMsZUFBZTtJQU56QixZQUNVLGlCQUFpQixFQUFFLDRCQUE0QixFQUMvQyxJQUFJLEVBQUUseUJBQXlCLEVBQy9CLE1BQU0sRUFBRSwwQkFBMEIsRUFDbEMsa0JBQWtCLEVBQUUsa0JBQWtCLEVBQ3RDLFlBQVksRUFBRSxZQUFZLEVBQzFCLGVBQWUsRUFBRSxlQUFlLEVBQ3RDO0lBRUosZUFBZSxJQUFJLHlCQUF5QixDQUUzQztJQUVEOztPQUVHO0lBQ0csVUFBVSxDQUNkLFVBQVUsRUFBRSxRQUFRLENBQUMsRUFBRSxDQUFDLEdBQUcsYUFBYSxDQUFDLEVBQUUsQ0FBQyxFQUM1QyxXQUFXLEVBQUUsV0FBVyxFQUN4QixTQUFTLEVBQUUsTUFBTSxFQUNqQixJQUFJLEVBQUUscUJBQXFCLEdBQzFCLE9BQU8sQ0FBQyw0QkFBNEIsQ0FBQyxDQXdDdkM7SUFFRCwrQ0FBK0M7SUFDekMsa0JBQWtCLElBQUksT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQVU5QztJQUVELGlEQUFpRDtJQUNqRCxhQUFhLElBQUksT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUVuQztJQUVELFVBQWdCLG9CQUFvQixDQUFDLGVBQWUsRUFBRSxlQUFlLEVBQUUsSUFBSSxFQUFFLHlCQUF5Qjs7O09Ba0NyRztDQUNGO0FBRUQ7O0dBRUc7QUFDSCxxQkFBYSwwQkFBMEI7SUFFbkMsT0FBTyxDQUFDLE1BQU07SUFDZCxPQUFPLENBQUMsa0JBQWtCO0lBQzFCLE9BQU8sQ0FBQyxZQUFZO0lBQ3BCLE9BQU8sQ0FBQyxlQUFlO0lBSnpCLFlBQ1UsTUFBTSxFQUFFLDBCQUEwQixFQUNsQyxrQkFBa0IsRUFBRSxrQkFBa0IsRUFDdEMsWUFBWSxFQUFFLFlBQVksRUFDMUIsZUFBZSxHQUFFLGVBQXNDLEVBQzdEO0lBRUcsWUFBWSxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsMEJBQTBCLENBQUMsUUFFOUQ7SUFFRDs7T0FFRztJQUNHLGVBQWUsQ0FDbkIsZ0JBQWdCLEVBQUUsZ0JBQWdCLEVBQ2xDLFNBQVMsRUFBRSx5QkFBeUIsRUFDcEMsY0FBYyxFQUFFLEVBQUUsRUFBRSxFQUNwQixJQUFJLEVBQUUseUJBQXlCLEdBQzlCLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxDQTJCNUI7Q0FDRiJ9
@@ -1 +0,0 @@
1
- {"version":3,"file":"checkpoint_builder.d.ts","sourceRoot":"","sources":["../../src/sequencer/checkpoint_builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAEhF,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AAGpD,OAAO,EAAE,YAAY,EAAE,KAAK,EAAW,MAAM,yBAAyB,CAAC;AAEvE,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAGL,eAAe,EAEhB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AACxC,OAAO,EACL,KAAK,0BAA0B,EAE/B,KAAK,yBAAyB,EAC9B,KAAK,qBAAqB,EAC3B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,KAAK,yBAAyB,EAAE,KAAK,QAAQ,EAAE,eAAe,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AACtG,OAAO,EAAE,KAAK,eAAe,EAAsB,MAAM,yBAAyB,CAAC;AAMnF,MAAM,WAAW,4BAA4B;IAC3C,KAAK,EAAE,UAAU,CAAC;IAClB,SAAS,EAAE,GAAG,CAAC;IACf,uBAAuB,EAAE,MAAM,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,kBAAkB,EAAE,KAAK,CAAC;IAC1B,OAAO,EAAE,EAAE,EAAE,CAAC;CACf;AAED;;;GAGG;AACH,qBAAa,iBAAiB;IAE1B,OAAO,CAAC,iBAAiB;IACzB,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,kBAAkB;IAC1B,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,eAAe;IANzB,YACU,iBAAiB,EAAE,4BAA4B,EAC/C,IAAI,EAAE,yBAAyB,EAC/B,MAAM,EAAE,0BAA0B,EAClC,kBAAkB,EAAE,kBAAkB,EACtC,YAAY,EAAE,YAAY,EAC1B,eAAe,EAAE,eAAe,EACtC;IAEJ,eAAe,IAAI,yBAAyB,CAE3C;IAED;;OAEG;IACG,UAAU,CACd,UAAU,EAAE,QAAQ,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC,EAAE,CAAC,EAC5C,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,qBAAqB,GAC1B,OAAO,CAAC,4BAA4B,CAAC,CAwCvC;IAED,+CAA+C;IACzC,kBAAkB,IAAI,OAAO,CAAC,UAAU,CAAC,CAU9C;IAED,iDAAiD;IACjD,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC,CAEnC;IAED,UAAgB,oBAAoB,CAAC,eAAe,EAAE,eAAe,EAAE,IAAI,EAAE,yBAAyB;;;OAkCrG;CACF;AAED;;GAEG;AACH,qBAAa,0BAA0B;IAEnC,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,kBAAkB;IAC1B,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,eAAe;IAJzB,YACU,MAAM,EAAE,0BAA0B,EAClC,kBAAkB,EAAE,kBAAkB,EACtC,YAAY,EAAE,YAAY,EAC1B,eAAe,GAAE,eAAsC,EAC7D;IAEG,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,0BAA0B,CAAC,QAE9D;IAED;;OAEG;IACG,eAAe,CACnB,gBAAgB,EAAE,gBAAgB,EAClC,SAAS,EAAE,yBAAyB,EACpC,cAAc,EAAE,EAAE,EAAE,EACpB,IAAI,EAAE,yBAAyB,GAC9B,OAAO,CAAC,iBAAiB,CAAC,CA2B5B;CACF"}