@aztec/sequencer-client 0.0.1-commit.96bb3f7 → 0.0.1-commit.a072138

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 (53) hide show
  1. package/dest/client/sequencer-client.js +1 -1
  2. package/dest/config.d.ts +1 -1
  3. package/dest/config.d.ts.map +1 -1
  4. package/dest/config.js +1 -3
  5. package/dest/global_variable_builder/global_builder.js +2 -2
  6. package/dest/index.d.ts +2 -2
  7. package/dest/index.d.ts.map +1 -1
  8. package/dest/index.js +1 -1
  9. package/dest/publisher/sequencer-publisher-metrics.d.ts +1 -1
  10. package/dest/publisher/sequencer-publisher-metrics.d.ts.map +1 -1
  11. package/dest/publisher/sequencer-publisher-metrics.js +12 -4
  12. package/dest/publisher/sequencer-publisher.d.ts +1 -2
  13. package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
  14. package/dest/publisher/sequencer-publisher.js +39 -18
  15. package/dest/sequencer/checkpoint_proposal_job.d.ts +28 -9
  16. package/dest/sequencer/checkpoint_proposal_job.d.ts.map +1 -1
  17. package/dest/sequencer/checkpoint_proposal_job.js +134 -31
  18. package/dest/sequencer/checkpoint_voter.d.ts +3 -2
  19. package/dest/sequencer/checkpoint_voter.d.ts.map +1 -1
  20. package/dest/sequencer/checkpoint_voter.js +34 -10
  21. package/dest/sequencer/index.d.ts +1 -2
  22. package/dest/sequencer/index.d.ts.map +1 -1
  23. package/dest/sequencer/index.js +0 -1
  24. package/dest/sequencer/metrics.d.ts +2 -2
  25. package/dest/sequencer/metrics.d.ts.map +1 -1
  26. package/dest/sequencer/metrics.js +27 -17
  27. package/dest/sequencer/sequencer.d.ts +17 -9
  28. package/dest/sequencer/sequencer.d.ts.map +1 -1
  29. package/dest/sequencer/sequencer.js +67 -11
  30. package/dest/test/mock_checkpoint_builder.d.ts +17 -13
  31. package/dest/test/mock_checkpoint_builder.d.ts.map +1 -1
  32. package/dest/test/mock_checkpoint_builder.js +28 -10
  33. package/dest/test/utils.d.ts +8 -8
  34. package/dest/test/utils.d.ts.map +1 -1
  35. package/dest/test/utils.js +7 -7
  36. package/package.json +30 -28
  37. package/src/client/sequencer-client.ts +1 -1
  38. package/src/config.ts +1 -3
  39. package/src/global_variable_builder/global_builder.ts +2 -2
  40. package/src/index.ts +1 -6
  41. package/src/publisher/sequencer-publisher-metrics.ts +7 -3
  42. package/src/publisher/sequencer-publisher.ts +34 -18
  43. package/src/sequencer/checkpoint_proposal_job.ts +183 -51
  44. package/src/sequencer/checkpoint_voter.ts +32 -7
  45. package/src/sequencer/index.ts +0 -1
  46. package/src/sequencer/metrics.ts +36 -18
  47. package/src/sequencer/sequencer.ts +82 -10
  48. package/src/test/mock_checkpoint_builder.ts +64 -34
  49. package/src/test/utils.ts +19 -12
  50. package/dest/sequencer/block_builder.d.ts +0 -26
  51. package/dest/sequencer/block_builder.d.ts.map +0 -1
  52. package/dest/sequencer/block_builder.js +0 -129
  53. package/src/sequencer/block_builder.ts +0 -216
@@ -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, L2BlockSink, L2BlockSource, ValidateCheckpointResult } from '@aztec/stdlib/block';
15
+ import type { L2Block, 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 {
@@ -57,8 +57,8 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
57
57
  private state = SequencerState.STOPPED;
58
58
  private metrics: SequencerMetrics;
59
59
 
60
- /** The last slot for which we attempted to vote when sync failed, to prevent duplicate attempts. */
61
- private lastSlotForVoteWhenSyncFailed: SlotNumber | undefined;
60
+ /** The last slot for which we attempted to perform our voting duties with degraded block production */
61
+ private lastSlotForFallbackVote: SlotNumber | undefined;
62
62
 
63
63
  /** The last slot for which we triggered a checkpoint proposal job, to prevent duplicate attempts. */
64
64
  private lastSlotForCheckpointProposalJob: SlotNumber | undefined;
@@ -202,7 +202,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
202
202
  const { slot, ts, now, epoch } = this.epochCache.getEpochAndSlotInNextL1Slot();
203
203
 
204
204
  // Check if we are synced and it's our slot, grab a publisher, check previous block invalidation, etc
205
- const checkpointProposalJob = await this.prepareCheckpointProposal(slot, ts, now);
205
+ const checkpointProposalJob = await this.prepareCheckpointProposal(epoch, slot, ts, now);
206
206
  if (!checkpointProposalJob) {
207
207
  return;
208
208
  }
@@ -234,6 +234,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
234
234
  */
235
235
  @trackSpan('Sequencer.prepareCheckpointProposal')
236
236
  private async prepareCheckpointProposal(
237
+ epoch: EpochNumber,
237
238
  slot: SlotNumber,
238
239
  ts: bigint,
239
240
  now: bigint,
@@ -263,6 +264,25 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
263
264
  return undefined;
264
265
  }
265
266
 
267
+ // If escape hatch is open for this epoch, do not start checkpoint proposal work and do not attempt invalidations.
268
+ // Still perform governance/slashing voting (as proposer) once per slot.
269
+ const isEscapeHatchOpen = await this.epochCache.isEscapeHatchOpen(epoch);
270
+
271
+ if (isEscapeHatchOpen) {
272
+ this.setState(SequencerState.PROPOSER_CHECK, slot);
273
+ const [canPropose, proposer] = await this.checkCanPropose(slot);
274
+ if (canPropose) {
275
+ await this.tryVoteWhenEscapeHatchOpen({ slot, proposer });
276
+ } else {
277
+ this.log.trace(`Escape hatch open but we are not proposer, skipping vote-only actions`, {
278
+ slot,
279
+ epoch,
280
+ proposer,
281
+ });
282
+ }
283
+ return undefined;
284
+ }
285
+
266
286
  // Next checkpoint follows from the last synced one
267
287
  const checkpointNumber = CheckpointNumber(syncedTo.checkpointNumber + 1);
268
288
 
@@ -357,6 +377,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
357
377
 
358
378
  // Create and return the checkpoint proposal job
359
379
  return this.createCheckpointProposalJob(
380
+ epoch,
360
381
  slot,
361
382
  checkpointNumber,
362
383
  syncedTo.blockNumber,
@@ -368,6 +389,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
368
389
  }
369
390
 
370
391
  protected createCheckpointProposalJob(
392
+ epoch: EpochNumber,
371
393
  slot: SlotNumber,
372
394
  checkpointNumber: CheckpointNumber,
373
395
  syncedToBlockNumber: BlockNumber,
@@ -377,6 +399,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
377
399
  invalidateCheckpoint: InvalidateCheckpointRequest | undefined,
378
400
  ): CheckpointProposalJob {
379
401
  return new CheckpointProposalJob(
402
+ epoch,
380
403
  slot,
381
404
  checkpointNumber,
382
405
  syncedToBlockNumber,
@@ -389,6 +412,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
389
412
  this.p2pClient,
390
413
  this.worldState,
391
414
  this.l1ToL2MessageSource,
415
+ this.l2BlockSource,
392
416
  this.checkpointsBuilder,
393
417
  this.l2BlockSource,
394
418
  this.l1Constants,
@@ -400,8 +424,8 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
400
424
  this.metrics,
401
425
  this,
402
426
  this.setState.bind(this),
403
- this.log,
404
427
  this.tracer,
428
+ this.log.getBindings(),
405
429
  );
406
430
  }
407
431
 
@@ -505,7 +529,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
505
529
  };
506
530
  }
507
531
 
508
- const block = await this.l2BlockSource.getL2BlockNew(blockNumber);
532
+ const block = await this.l2BlockSource.getL2Block(blockNumber);
509
533
  if (!block) {
510
534
  // this shouldn't really happen because a moment ago we checked that all components were in sync
511
535
  this.log.error(`Failed to get L2 block ${blockNumber} from the archiver with all components in sync`);
@@ -569,7 +593,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
569
593
  const { slot } = args;
570
594
 
571
595
  // Prevent duplicate attempts in the same slot
572
- if (this.lastSlotForVoteWhenSyncFailed === slot) {
596
+ if (this.lastSlotForFallbackVote === slot) {
573
597
  this.log.trace(`Already attempted to vote in slot ${slot} (skipping)`);
574
598
  return;
575
599
  }
@@ -601,7 +625,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
601
625
  }
602
626
 
603
627
  // Mark this slot as attempted
604
- this.lastSlotForVoteWhenSyncFailed = slot;
628
+ this.lastSlotForFallbackVote = slot;
605
629
 
606
630
  // Get a publisher for voting
607
631
  const { attestorAddress, publisher } = await this.publisherFactory.create(proposer);
@@ -636,7 +660,55 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
636
660
  }
637
661
 
638
662
  /**
639
- * Considers invalidating a checkpoint if the pending chain is invalid. Depends on how long the invalid checkpoint
663
+ * Tries to vote on slashing actions and governance proposals when escape hatch is open.
664
+ * This allows the sequencer to participate in voting without performing checkpoint proposal work.
665
+ */
666
+ @trackSpan('Sequencer.tryVoteWhenEscapeHatchOpen', ({ slot }) => ({ [Attributes.SLOT_NUMBER]: slot }))
667
+ protected async tryVoteWhenEscapeHatchOpen(args: {
668
+ slot: SlotNumber;
669
+ proposer: EthAddress | undefined;
670
+ }): Promise<void> {
671
+ const { slot, proposer } = args;
672
+
673
+ // Prevent duplicate attempts in the same slot
674
+ if (this.lastSlotForFallbackVote === slot) {
675
+ this.log.trace(`Already attempted to vote in slot ${slot} (escape hatch open, skipping)`);
676
+ return;
677
+ }
678
+
679
+ // Mark this slot as attempted
680
+ this.lastSlotForFallbackVote = slot;
681
+
682
+ const { attestorAddress, publisher } = await this.publisherFactory.create(proposer);
683
+
684
+ this.log.debug(`Escape hatch open for slot ${slot}, attempting vote-only actions`, { slot, attestorAddress });
685
+
686
+ const voter = new CheckpointVoter(
687
+ slot,
688
+ publisher,
689
+ attestorAddress,
690
+ this.validatorClient,
691
+ this.slasherClient,
692
+ this.l1Constants,
693
+ this.config,
694
+ this.metrics,
695
+ this.log,
696
+ );
697
+
698
+ const votesPromises = voter.enqueueVotes();
699
+ const votes = await Promise.all(votesPromises);
700
+
701
+ if (votes.every(p => !p)) {
702
+ this.log.debug(`No votes to enqueue for slot ${slot} (escape hatch open)`);
703
+ return;
704
+ }
705
+
706
+ this.log.info(`Voting in slot ${slot} (escape hatch open)`, { slot });
707
+ await publisher.sendRequests();
708
+ }
709
+
710
+ /**
711
+ * Considers invalidating a block if the pending chain is invalid. Depends on how long the invalid block
640
712
  * has been there without being invalidated and whether the sequencer is in the committee or not. We always
641
713
  * have the proposer try to invalidate, but if they fail, the sequencers in the committee are expected to try,
642
714
  * and if they fail, any sequencer will try as well.
@@ -798,7 +870,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
798
870
  }
799
871
 
800
872
  type SequencerSyncCheckResult = {
801
- block?: L2BlockNew;
873
+ block?: L2Block;
802
874
  checkpointNumber: CheckpointNumber;
803
875
  blockNumber: BlockNumber;
804
876
  archive: Fr;
@@ -1,32 +1,32 @@
1
1
  import { type BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types';
2
2
  import { Fr } from '@aztec/foundation/curves/bn254';
3
- import { Timer } from '@aztec/foundation/timer';
4
- import type { FunctionsOf } from '@aztec/foundation/types';
5
- import { L2BlockNew } from '@aztec/stdlib/block';
3
+ import { L2Block } from '@aztec/stdlib/block';
6
4
  import { Checkpoint } from '@aztec/stdlib/checkpoint';
7
5
  import { Gas } from '@aztec/stdlib/gas';
8
- import type { FullNodeBlockBuilderConfig, PublicProcessorLimits } from '@aztec/stdlib/interfaces/server';
6
+ import type {
7
+ FullNodeBlockBuilderConfig,
8
+ ICheckpointBlockBuilder,
9
+ ICheckpointsBuilder,
10
+ MerkleTreeWriteOperations,
11
+ PublicProcessorLimits,
12
+ } from '@aztec/stdlib/interfaces/server';
9
13
  import { CheckpointHeader } from '@aztec/stdlib/rollup';
10
14
  import { makeAppendOnlyTreeSnapshot } from '@aztec/stdlib/testing';
11
15
  import type { CheckpointGlobalVariables, Tx } from '@aztec/stdlib/tx';
12
- import type {
13
- BuildBlockInCheckpointResult,
14
- CheckpointBuilder,
15
- FullNodeCheckpointsBuilder,
16
- } from '@aztec/validator-client';
16
+ import type { BuildBlockInCheckpointResult } from '@aztec/validator-client';
17
17
 
18
18
  /**
19
19
  * A fake CheckpointBuilder for testing that implements the same interface as the real one.
20
20
  * Can be seeded with blocks to return sequentially on each `buildBlock` call.
21
21
  */
22
- export class MockCheckpointBuilder implements FunctionsOf<CheckpointBuilder> {
23
- private blocks: L2BlockNew[] = [];
24
- private builtBlocks: L2BlockNew[] = [];
22
+ export class MockCheckpointBuilder implements ICheckpointBlockBuilder {
23
+ private blocks: L2Block[] = [];
24
+ private builtBlocks: L2Block[] = [];
25
25
  private usedTxsPerBlock: Tx[][] = [];
26
26
  private blockIndex = 0;
27
27
 
28
28
  /** Optional function to dynamically provide the block (alternative to seedBlocks) */
29
- private blockProvider: (() => L2BlockNew) | undefined = undefined;
29
+ private blockProvider: (() => L2Block) | undefined = undefined;
30
30
 
31
31
  /** Track calls for assertions */
32
32
  public buildBlockCalls: Array<{
@@ -34,6 +34,8 @@ export class MockCheckpointBuilder implements FunctionsOf<CheckpointBuilder> {
34
34
  timestamp: bigint;
35
35
  opts: PublicProcessorLimits;
36
36
  }> = [];
37
+ /** Track all consumed transaction hashes across buildBlock calls */
38
+ public consumedTxHashes: Set<string> = new Set();
37
39
  public completeCheckpointCalled = false;
38
40
  public getCheckpointCalled = false;
39
41
 
@@ -46,7 +48,7 @@ export class MockCheckpointBuilder implements FunctionsOf<CheckpointBuilder> {
46
48
  ) {}
47
49
 
48
50
  /** Seed the builder with blocks to return on successive buildBlock calls */
49
- seedBlocks(blocks: L2BlockNew[], usedTxsPerBlock?: Tx[][]): this {
51
+ seedBlocks(blocks: L2Block[], usedTxsPerBlock?: Tx[][]): this {
50
52
  this.blocks = blocks;
51
53
  this.usedTxsPerBlock = usedTxsPerBlock ?? blocks.map(() => []);
52
54
  this.blockIndex = 0;
@@ -58,7 +60,7 @@ export class MockCheckpointBuilder implements FunctionsOf<CheckpointBuilder> {
58
60
  * Set a function that provides blocks dynamically.
59
61
  * Useful for tests where the block is determined at call time (e.g., sequencer tests).
60
62
  */
61
- setBlockProvider(provider: () => L2BlockNew): this {
63
+ setBlockProvider(provider: () => L2Block): this {
62
64
  this.blockProvider = provider;
63
65
  this.blocks = [];
64
66
  return this;
@@ -68,8 +70,8 @@ export class MockCheckpointBuilder implements FunctionsOf<CheckpointBuilder> {
68
70
  return this.constants;
69
71
  }
70
72
 
71
- buildBlock(
72
- _pendingTxs: Iterable<Tx> | AsyncIterable<Tx>,
73
+ async buildBlock(
74
+ pendingTxs: Iterable<Tx> | AsyncIterable<Tx>,
73
75
  blockNumber: BlockNumber,
74
76
  timestamp: bigint,
75
77
  opts: PublicProcessorLimits,
@@ -77,10 +79,10 @@ export class MockCheckpointBuilder implements FunctionsOf<CheckpointBuilder> {
77
79
  this.buildBlockCalls.push({ blockNumber, timestamp, opts });
78
80
 
79
81
  if (this.errorOnBuild) {
80
- return Promise.reject(this.errorOnBuild);
82
+ throw this.errorOnBuild;
81
83
  }
82
84
 
83
- let block: L2BlockNew;
85
+ let block: L2Block;
84
86
  let usedTxs: Tx[];
85
87
 
86
88
  if (this.blockProvider) {
@@ -96,15 +98,28 @@ export class MockCheckpointBuilder implements FunctionsOf<CheckpointBuilder> {
96
98
  this.builtBlocks.push(block);
97
99
  }
98
100
 
99
- return Promise.resolve({
101
+ // Check that no pending tx has already been consumed
102
+ for await (const tx of pendingTxs) {
103
+ const hash = tx.getTxHash().toString();
104
+ if (this.consumedTxHashes.has(hash)) {
105
+ throw new Error(`Transaction ${hash} was already consumed in a previous block`);
106
+ }
107
+ }
108
+
109
+ // Add used txs to consumed set
110
+ for (const tx of usedTxs) {
111
+ this.consumedTxHashes.add(tx.getTxHash().toString());
112
+ }
113
+
114
+ return {
100
115
  block,
101
116
  publicGas: Gas.empty(),
102
117
  publicProcessorDuration: 0,
103
118
  numTxs: block?.body?.txEffects?.length ?? usedTxs.length,
104
- blockBuildingTimer: new Timer(),
105
119
  usedTxs,
106
120
  failedTxs: [],
107
- });
121
+ usedTxBlobFields: block?.body?.txEffects?.reduce((sum, tx) => sum + tx.getNumBlobFields(), 0) ?? 0,
122
+ };
108
123
  }
109
124
 
110
125
  completeCheckpoint(): Promise<Checkpoint> {
@@ -146,7 +161,7 @@ export class MockCheckpointBuilder implements FunctionsOf<CheckpointBuilder> {
146
161
  * Creates a CheckpointHeader from a block's header for testing.
147
162
  * This is a simplified version that creates a minimal CheckpointHeader.
148
163
  */
149
- private createCheckpointHeader(block: L2BlockNew): CheckpointHeader {
164
+ private createCheckpointHeader(block: L2Block): CheckpointHeader {
150
165
  const header = block.header;
151
166
  const gv = header.globalVariables;
152
167
  return CheckpointHeader.empty({
@@ -168,6 +183,7 @@ export class MockCheckpointBuilder implements FunctionsOf<CheckpointBuilder> {
168
183
  this.usedTxsPerBlock = [];
169
184
  this.blockIndex = 0;
170
185
  this.buildBlockCalls = [];
186
+ this.consumedTxHashes.clear();
171
187
  this.completeCheckpointCalled = false;
172
188
  this.getCheckpointCalled = false;
173
189
  this.errorOnBuild = undefined;
@@ -180,7 +196,7 @@ export class MockCheckpointBuilder implements FunctionsOf<CheckpointBuilder> {
180
196
  * as FullNodeCheckpointsBuilder. Returns MockCheckpointBuilder instances.
181
197
  * Does NOT use jest mocks - this is a proper test double.
182
198
  */
183
- export class MockCheckpointsBuilder implements FunctionsOf<FullNodeCheckpointsBuilder> {
199
+ export class MockCheckpointsBuilder implements ICheckpointsBuilder {
184
200
  private checkpointBuilder: MockCheckpointBuilder | undefined;
185
201
 
186
202
  /** Track calls for assertions */
@@ -188,12 +204,14 @@ export class MockCheckpointsBuilder implements FunctionsOf<FullNodeCheckpointsBu
188
204
  checkpointNumber: CheckpointNumber;
189
205
  constants: CheckpointGlobalVariables;
190
206
  l1ToL2Messages: Fr[];
207
+ previousCheckpointOutHashes: Fr[];
191
208
  }> = [];
192
209
  public openCheckpointCalls: Array<{
193
210
  checkpointNumber: CheckpointNumber;
194
211
  constants: CheckpointGlobalVariables;
195
212
  l1ToL2Messages: Fr[];
196
- existingBlocks: L2BlockNew[];
213
+ previousCheckpointOutHashes: Fr[];
214
+ existingBlocks: L2Block[];
197
215
  }> = [];
198
216
  public updateConfigCalls: Array<Partial<FullNodeBlockBuilderConfig>> = [];
199
217
 
@@ -240,33 +258,45 @@ export class MockCheckpointsBuilder implements FunctionsOf<FullNodeCheckpointsBu
240
258
  checkpointNumber: CheckpointNumber,
241
259
  constants: CheckpointGlobalVariables,
242
260
  l1ToL2Messages: Fr[],
243
- _fork: unknown,
244
- ): Promise<CheckpointBuilder> {
245
- this.startCheckpointCalls.push({ checkpointNumber, constants, l1ToL2Messages });
261
+ previousCheckpointOutHashes: Fr[],
262
+ _fork: MerkleTreeWriteOperations,
263
+ ): Promise<ICheckpointBlockBuilder> {
264
+ this.startCheckpointCalls.push({ checkpointNumber, constants, l1ToL2Messages, previousCheckpointOutHashes });
246
265
 
247
266
  if (!this.checkpointBuilder) {
248
267
  // Auto-create a builder if none was set
249
268
  this.checkpointBuilder = new MockCheckpointBuilder(constants, checkpointNumber);
250
269
  }
251
270
 
252
- return Promise.resolve(this.checkpointBuilder as unknown as CheckpointBuilder);
271
+ return Promise.resolve(this.checkpointBuilder);
253
272
  }
254
273
 
255
274
  openCheckpoint(
256
275
  checkpointNumber: CheckpointNumber,
257
276
  constants: CheckpointGlobalVariables,
258
277
  l1ToL2Messages: Fr[],
259
- _fork: unknown,
260
- existingBlocks: L2BlockNew[] = [],
261
- ): Promise<CheckpointBuilder> {
262
- this.openCheckpointCalls.push({ checkpointNumber, constants, l1ToL2Messages, existingBlocks });
278
+ previousCheckpointOutHashes: Fr[],
279
+ _fork: MerkleTreeWriteOperations,
280
+ existingBlocks: L2Block[] = [],
281
+ ): Promise<ICheckpointBlockBuilder> {
282
+ this.openCheckpointCalls.push({
283
+ checkpointNumber,
284
+ constants,
285
+ l1ToL2Messages,
286
+ previousCheckpointOutHashes,
287
+ existingBlocks,
288
+ });
263
289
 
264
290
  if (!this.checkpointBuilder) {
265
291
  // Auto-create a builder if none was set
266
292
  this.checkpointBuilder = new MockCheckpointBuilder(constants, checkpointNumber);
267
293
  }
268
294
 
269
- return Promise.resolve(this.checkpointBuilder as unknown as CheckpointBuilder);
295
+ return Promise.resolve(this.checkpointBuilder);
296
+ }
297
+
298
+ getFork(_blockNumber: BlockNumber): Promise<MerkleTreeWriteOperations> {
299
+ throw new Error('MockCheckpointsBuilder.getFork not implemented');
270
300
  }
271
301
 
272
302
  /** Reset for reuse in another test */
package/src/test/utils.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Body } from '@aztec/aztec.js/block';
2
- import { CheckpointNumber } from '@aztec/foundation/branded-types';
2
+ import { CheckpointNumber, IndexWithinCheckpoint } from '@aztec/foundation/branded-types';
3
3
  import { times } from '@aztec/foundation/collection';
4
4
  import { Secp256k1Signer } from '@aztec/foundation/crypto/secp256k1-signer';
5
5
  import { Fr } from '@aztec/foundation/curves/bn254';
@@ -7,7 +7,7 @@ import type { EthAddress } from '@aztec/foundation/eth-address';
7
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
- import { CommitteeAttestation, L2BlockNew } from '@aztec/stdlib/block';
10
+ import { CommitteeAttestation, L2Block } from '@aztec/stdlib/block';
11
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';
@@ -30,9 +30,9 @@ export async function makeTx(seed?: number, chainId?: Fr): Promise<Tx> {
30
30
  }
31
31
 
32
32
  /**
33
- * Creates an L2BlockNew from transactions and global variables
33
+ * Creates an L2Block from transactions and global variables
34
34
  */
35
- export async function makeBlock(txs: Tx[], globalVariables: GlobalVariables): Promise<L2BlockNew> {
35
+ export async function makeBlock(txs: Tx[], globalVariables: GlobalVariables): Promise<L2Block> {
36
36
  const processedTxs = await Promise.all(
37
37
  txs.map(tx =>
38
38
  makeProcessedTxFromPrivateOnlyTx(tx, Fr.ZERO, new PublicDataWrite(Fr.random(), Fr.random()), globalVariables),
@@ -41,7 +41,13 @@ export async function makeBlock(txs: Tx[], globalVariables: GlobalVariables): Pr
41
41
  const body = new Body(processedTxs.map(tx => tx.txEffect));
42
42
  const header = BlockHeader.empty({ globalVariables });
43
43
  const archive = makeAppendOnlyTreeSnapshot(globalVariables.blockNumber + 1);
44
- return new L2BlockNew(archive, header, body, CheckpointNumber(globalVariables.blockNumber), 0);
44
+ return new L2Block(
45
+ archive,
46
+ header,
47
+ body,
48
+ CheckpointNumber.fromBlockNumber(globalVariables.blockNumber),
49
+ IndexWithinCheckpoint(0),
50
+ );
45
51
  }
46
52
 
47
53
  /**
@@ -70,16 +76,17 @@ export function createMockSignatures(signer: Secp256k1Signer): CommitteeAttestat
70
76
  }
71
77
 
72
78
  /**
73
- * Creates a CheckpointHeader from an L2BlockNew for testing purposes.
74
- * Uses mock values for blockHeadersHash, blobsHash and inHash since L2BlockNew doesn't have these fields.
79
+ * Creates a CheckpointHeader from an L2Block for testing purposes.
80
+ * Uses mock values for blockHeadersHash, blobsHash and inHash since L2Block doesn't have these fields.
75
81
  */
76
- function createCheckpointHeaderFromBlock(block: L2BlockNew): CheckpointHeader {
82
+ function createCheckpointHeaderFromBlock(block: L2Block): CheckpointHeader {
77
83
  const gv = block.header.globalVariables;
78
84
  return new CheckpointHeader(
79
85
  block.header.lastArchive.root,
80
86
  Fr.random(), // blockHeadersHash - mock value for testing
81
87
  Fr.random(), // blobsHash - mock value for testing
82
88
  Fr.random(), // inHash - mock value for testing
89
+ Fr.random(), // outHash - mock value for testing
83
90
  gv.slotNumber,
84
91
  gv.timestamp,
85
92
  gv.coinbase,
@@ -92,7 +99,7 @@ function createCheckpointHeaderFromBlock(block: L2BlockNew): CheckpointHeader {
92
99
  /**
93
100
  * Creates a block proposal from a block and signature
94
101
  */
95
- export function createBlockProposal(block: L2BlockNew, signature: Signature): BlockProposal {
102
+ export function createBlockProposal(block: L2Block, signature: Signature): BlockProposal {
96
103
  const txHashes = block.body.txEffects.map(tx => tx.txHash);
97
104
  return new BlockProposal(
98
105
  block.header,
@@ -108,7 +115,7 @@ export function createBlockProposal(block: L2BlockNew, signature: Signature): Bl
108
115
  * Creates a checkpoint proposal from a block and signature
109
116
  */
110
117
  export function createCheckpointProposal(
111
- block: L2BlockNew,
118
+ block: L2Block,
112
119
  checkpointSignature: Signature,
113
120
  blockSignature?: Signature,
114
121
  ): CheckpointProposal {
@@ -128,7 +135,7 @@ export function createCheckpointProposal(
128
135
  * In production, the sender is recovered from the signature.
129
136
  */
130
137
  export function createCheckpointAttestation(
131
- block: L2BlockNew,
138
+ block: L2Block,
132
139
  signature: Signature,
133
140
  sender: EthAddress,
134
141
  ): CheckpointAttestation {
@@ -149,7 +156,7 @@ export async function setupTxsAndBlock(
149
156
  globalVariables: GlobalVariables,
150
157
  txCount: number,
151
158
  chainId: Fr,
152
- ): Promise<{ txs: Tx[]; block: L2BlockNew }> {
159
+ ): Promise<{ txs: Tx[]; block: L2Block }> {
153
160
  const txs = await Promise.all(times(txCount, i => makeTx(i + 1, chainId)));
154
161
  const block = await makeBlock(txs, globalVariables);
155
162
  mockPendingTxs(p2p, txs);
@@ -1,26 +0,0 @@
1
- import { BlockNumber } from '@aztec/foundation/branded-types';
2
- import type { Fr } from '@aztec/foundation/curves/bn254';
3
- import { DateProvider } from '@aztec/foundation/timer';
4
- import { PublicProcessor } from '@aztec/simulator/server';
5
- import type { ContractDataSource } from '@aztec/stdlib/contract';
6
- import type { BuildBlockResult, FullNodeBlockBuilderConfig, IFullNodeBlockBuilder, MerkleTreeWriteOperations, PublicProcessorLimits, PublicProcessorValidator, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
7
- import { GlobalVariables, Tx } from '@aztec/stdlib/tx';
8
- import { type TelemetryClient } from '@aztec/telemetry-client';
9
- export declare class FullNodeBlockBuilder implements IFullNodeBlockBuilder {
10
- private config;
11
- private worldState;
12
- private contractDataSource;
13
- private dateProvider;
14
- private telemetryClient;
15
- constructor(config: FullNodeBlockBuilderConfig, worldState: WorldStateSynchronizer, contractDataSource: ContractDataSource, dateProvider: DateProvider, telemetryClient?: TelemetryClient);
16
- getConfig(): FullNodeBlockBuilderConfig;
17
- updateConfig(config: Partial<FullNodeBlockBuilderConfig>): void;
18
- makeBlockBuilderDeps(globalVariables: GlobalVariables, fork: MerkleTreeWriteOperations): Promise<{
19
- processor: PublicProcessor;
20
- validator: PublicProcessorValidator;
21
- }>;
22
- private syncToPreviousBlock;
23
- buildBlock(pendingTxs: Iterable<Tx> | AsyncIterable<Tx>, l1ToL2Messages: Fr[], globalVariables: GlobalVariables, opts: PublicProcessorLimits, suppliedFork?: MerkleTreeWriteOperations): Promise<BuildBlockResult>;
24
- getFork(blockNumber: BlockNumber): Promise<MerkleTreeWriteOperations>;
25
- }
26
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmxvY2tfYnVpbGRlci5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlcXVlbmNlci9ibG9ja19idWlsZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUU5RCxPQUFPLEtBQUssRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUl6RCxPQUFPLEVBQUUsWUFBWSxFQUFrQixNQUFNLHlCQUF5QixDQUFDO0FBR3ZFLE9BQU8sRUFHTCxlQUFlLEVBRWhCLE1BQU0seUJBQXlCLENBQUM7QUFDakMsT0FBTyxLQUFLLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUdqRSxPQUFPLEtBQUssRUFDVixnQkFBZ0IsRUFDaEIsMEJBQTBCLEVBQzFCLHFCQUFxQixFQUNyQix5QkFBeUIsRUFDekIscUJBQXFCLEVBQ3JCLHdCQUF3QixFQUN4QixzQkFBc0IsRUFDdkIsTUFBTSxpQ0FBaUMsQ0FBQztBQUN6QyxPQUFPLEVBQUUsZUFBZSxFQUFFLEVBQUUsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxLQUFLLGVBQWUsRUFBc0IsTUFBTSx5QkFBeUIsQ0FBQztBQTBFbkYscUJBQWEsb0JBQXFCLFlBQVcscUJBQXFCO0lBRTlELE9BQU8sQ0FBQyxNQUFNO0lBQ2QsT0FBTyxDQUFDLFVBQVU7SUFDbEIsT0FBTyxDQUFDLGtCQUFrQjtJQUMxQixPQUFPLENBQUMsWUFBWTtJQUNwQixPQUFPLENBQUMsZUFBZTtJQUx6QixZQUNVLE1BQU0sRUFBRSwwQkFBMEIsRUFDbEMsVUFBVSxFQUFFLHNCQUFzQixFQUNsQyxrQkFBa0IsRUFBRSxrQkFBa0IsRUFDdEMsWUFBWSxFQUFFLFlBQVksRUFDMUIsZUFBZSxHQUFFLGVBQXNDLEVBQzdEO0lBRUcsU0FBUyxJQUFJLDBCQUEwQixDQUU3QztJQUVNLFlBQVksQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLDBCQUEwQixDQUFDLFFBRTlEO0lBRVksb0JBQW9CLENBQUMsZUFBZSxFQUFFLGVBQWUsRUFBRSxJQUFJLEVBQUUseUJBQXlCOzs7T0FrQ2xHO1lBRWEsbUJBQW1CO0lBVTNCLFVBQVUsQ0FDZCxVQUFVLEVBQUUsUUFBUSxDQUFDLEVBQUUsQ0FBQyxHQUFHLGFBQWEsQ0FBQyxFQUFFLENBQUMsRUFDNUMsY0FBYyxFQUFFLEVBQUUsRUFBRSxFQUNwQixlQUFlLEVBQUUsZUFBZSxFQUNoQyxJQUFJLEVBQUUscUJBQXFCLEVBQzNCLFlBQVksQ0FBQyxFQUFFLHlCQUF5QixHQUN2QyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsQ0FzQzNCO0lBRUQsT0FBTyxDQUFDLFdBQVcsRUFBRSxXQUFXLEdBQUcsT0FBTyxDQUFDLHlCQUF5QixDQUFDLENBRXBFO0NBQ0YifQ==
@@ -1 +0,0 @@
1
- {"version":3,"file":"block_builder.d.ts","sourceRoot":"","sources":["../../src/sequencer/block_builder.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAE9D,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AAIzD,OAAO,EAAE,YAAY,EAAkB,MAAM,yBAAyB,CAAC;AAGvE,OAAO,EAGL,eAAe,EAEhB,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAGjE,OAAO,KAAK,EACV,gBAAgB,EAChB,0BAA0B,EAC1B,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,EACrB,wBAAwB,EACxB,sBAAsB,EACvB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,KAAK,eAAe,EAAsB,MAAM,yBAAyB,CAAC;AA0EnF,qBAAa,oBAAqB,YAAW,qBAAqB;IAE9D,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,kBAAkB;IAC1B,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,eAAe;IALzB,YACU,MAAM,EAAE,0BAA0B,EAClC,UAAU,EAAE,sBAAsB,EAClC,kBAAkB,EAAE,kBAAkB,EACtC,YAAY,EAAE,YAAY,EAC1B,eAAe,GAAE,eAAsC,EAC7D;IAEG,SAAS,IAAI,0BAA0B,CAE7C;IAEM,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,0BAA0B,CAAC,QAE9D;IAEY,oBAAoB,CAAC,eAAe,EAAE,eAAe,EAAE,IAAI,EAAE,yBAAyB;;;OAkClG;YAEa,mBAAmB;IAU3B,UAAU,CACd,UAAU,EAAE,QAAQ,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC,EAAE,CAAC,EAC5C,cAAc,EAAE,EAAE,EAAE,EACpB,eAAe,EAAE,eAAe,EAChC,IAAI,EAAE,qBAAqB,EAC3B,YAAY,CAAC,EAAE,yBAAyB,GACvC,OAAO,CAAC,gBAAgB,CAAC,CAsC3B;IAED,OAAO,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAEpE;CACF"}