@aztec/sequencer-client 0.0.1-commit.ff7989d6c → 0.0.1-commit.ffe5b04ea

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 +12 -1
  2. package/dest/client/sequencer-client.d.ts.map +1 -1
  3. package/dest/client/sequencer-client.js +85 -13
  4. package/dest/config.d.ts +23 -4
  5. package/dest/config.d.ts.map +1 -1
  6. package/dest/config.js +23 -16
  7. package/dest/publisher/config.d.ts +5 -1
  8. package/dest/publisher/config.d.ts.map +1 -1
  9. package/dest/publisher/config.js +6 -1
  10. package/dest/publisher/index.d.ts +2 -1
  11. package/dest/publisher/index.d.ts.map +1 -1
  12. package/dest/publisher/l1_tx_failed_store/factory.d.ts +11 -0
  13. package/dest/publisher/l1_tx_failed_store/factory.d.ts.map +1 -0
  14. package/dest/publisher/l1_tx_failed_store/factory.js +22 -0
  15. package/dest/publisher/l1_tx_failed_store/failed_tx_store.d.ts +59 -0
  16. package/dest/publisher/l1_tx_failed_store/failed_tx_store.d.ts.map +1 -0
  17. package/dest/publisher/l1_tx_failed_store/failed_tx_store.js +1 -0
  18. package/dest/publisher/l1_tx_failed_store/file_store_failed_tx_store.d.ts +15 -0
  19. package/dest/publisher/l1_tx_failed_store/file_store_failed_tx_store.d.ts.map +1 -0
  20. package/dest/publisher/l1_tx_failed_store/file_store_failed_tx_store.js +34 -0
  21. package/dest/publisher/l1_tx_failed_store/index.d.ts +4 -0
  22. package/dest/publisher/l1_tx_failed_store/index.d.ts.map +1 -0
  23. package/dest/publisher/l1_tx_failed_store/index.js +2 -0
  24. package/dest/publisher/sequencer-publisher-factory.d.ts +1 -1
  25. package/dest/publisher/sequencer-publisher-factory.d.ts.map +1 -1
  26. package/dest/publisher/sequencer-publisher-factory.js +14 -0
  27. package/dest/publisher/sequencer-publisher.d.ts +12 -2
  28. package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
  29. package/dest/publisher/sequencer-publisher.js +258 -9
  30. package/dest/sequencer/checkpoint_proposal_job.d.ts +2 -4
  31. package/dest/sequencer/checkpoint_proposal_job.d.ts.map +1 -1
  32. package/dest/sequencer/checkpoint_proposal_job.js +68 -37
  33. package/dest/sequencer/sequencer.d.ts +9 -6
  34. package/dest/sequencer/sequencer.d.ts.map +1 -1
  35. package/dest/sequencer/sequencer.js +1 -1
  36. package/dest/sequencer/timetable.d.ts +4 -3
  37. package/dest/sequencer/timetable.d.ts.map +1 -1
  38. package/dest/sequencer/timetable.js +6 -7
  39. package/dest/sequencer/types.d.ts +5 -2
  40. package/dest/sequencer/types.d.ts.map +1 -1
  41. package/dest/test/mock_checkpoint_builder.d.ts +4 -6
  42. package/dest/test/mock_checkpoint_builder.d.ts.map +1 -1
  43. package/dest/test/mock_checkpoint_builder.js +39 -30
  44. package/package.json +28 -28
  45. package/src/client/sequencer-client.ts +111 -12
  46. package/src/config.ts +28 -19
  47. package/src/publisher/config.ts +9 -0
  48. package/src/publisher/index.ts +3 -0
  49. package/src/publisher/l1_tx_failed_store/factory.ts +32 -0
  50. package/src/publisher/l1_tx_failed_store/failed_tx_store.ts +55 -0
  51. package/src/publisher/l1_tx_failed_store/file_store_failed_tx_store.ts +46 -0
  52. package/src/publisher/l1_tx_failed_store/index.ts +3 -0
  53. package/src/publisher/sequencer-publisher-factory.ts +15 -0
  54. package/src/publisher/sequencer-publisher.ts +237 -15
  55. package/src/sequencer/checkpoint_proposal_job.ts +90 -44
  56. package/src/sequencer/sequencer.ts +1 -1
  57. package/src/sequencer/timetable.ts +7 -7
  58. package/src/sequencer/types.ts +4 -1
  59. package/src/test/mock_checkpoint_builder.ts +48 -45
@@ -110,7 +110,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
110
110
  /** Updates sequencer config by the defined values and updates the timetable */
111
111
  public updateConfig(config: Partial<SequencerConfig>) {
112
112
  const filteredConfig = pickFromSchema(config, SequencerConfigSchema);
113
- this.log.info(`Updated sequencer config`, omit(filteredConfig, 'txPublicSetupAllowList'));
113
+ this.log.info(`Updated sequencer config`, omit(filteredConfig, 'txPublicSetupAllowListExtend'));
114
114
  this.config = merge(this.config, filteredConfig);
115
115
  this.timetable = new SequencerTimetable(
116
116
  {
@@ -1,4 +1,4 @@
1
- import { createLogger } from '@aztec/aztec.js/log';
1
+ import type { Logger } from '@aztec/foundation/log';
2
2
  import {
3
3
  CHECKPOINT_ASSEMBLE_TIME,
4
4
  CHECKPOINT_INITIALIZATION_TIME,
@@ -80,7 +80,7 @@ export class SequencerTimetable {
80
80
  enforce: boolean;
81
81
  },
82
82
  private readonly metrics?: SequencerMetrics,
83
- private readonly log = createLogger('sequencer:timetable'),
83
+ private readonly log?: Logger,
84
84
  ) {
85
85
  this.ethereumSlotDuration = opts.ethereumSlotDuration;
86
86
  this.aztecSlotDuration = opts.aztecSlotDuration;
@@ -132,7 +132,7 @@ export class SequencerTimetable {
132
132
  const initializeDeadline = this.aztecSlotDuration - minWorkToDo;
133
133
  this.initializeDeadline = initializeDeadline;
134
134
 
135
- this.log.verbose(
135
+ this.log?.info(
136
136
  `Sequencer timetable initialized with ${this.maxNumberOfBlocks} blocks per slot (${this.enforce ? 'enforced' : 'not enforced'})`,
137
137
  {
138
138
  ethereumSlotDuration: this.ethereumSlotDuration,
@@ -206,7 +206,7 @@ export class SequencerTimetable {
206
206
  }
207
207
 
208
208
  this.metrics?.recordStateTransitionBufferMs(Math.floor(bufferSeconds * 1000), newState);
209
- this.log.trace(`Enough time to transition to ${newState}`, { maxAllowedTime, secondsIntoSlot });
209
+ this.log?.trace(`Enough time to transition to ${newState}`, { maxAllowedTime, secondsIntoSlot });
210
210
  }
211
211
 
212
212
  /**
@@ -242,7 +242,7 @@ export class SequencerTimetable {
242
242
  const canStart = available >= this.minExecutionTime;
243
243
  const deadline = secondsIntoSlot + available;
244
244
 
245
- this.log.verbose(
245
+ this.log?.verbose(
246
246
  `${canStart ? 'Can' : 'Cannot'} start single-block checkpoint at ${secondsIntoSlot}s into slot`,
247
247
  { secondsIntoSlot, maxAllowed, available, deadline },
248
248
  );
@@ -262,7 +262,7 @@ export class SequencerTimetable {
262
262
  // Found an available sub-slot! Is this the last one?
263
263
  const isLastBlock = subSlot === this.maxNumberOfBlocks;
264
264
 
265
- this.log.verbose(
265
+ this.log?.verbose(
266
266
  `Can start ${isLastBlock ? 'last block' : 'block'} in sub-slot ${subSlot} with deadline ${deadline}s`,
267
267
  { secondsIntoSlot, deadline, timeUntilDeadline, subSlot, maxBlocks: this.maxNumberOfBlocks },
268
268
  );
@@ -272,7 +272,7 @@ export class SequencerTimetable {
272
272
  }
273
273
 
274
274
  // No sub-slots available with enough time
275
- this.log.verbose(`No time left to start any more blocks`, {
275
+ this.log?.verbose(`No time left to start any more blocks`, {
276
276
  secondsIntoSlot,
277
277
  maxBlocks: this.maxNumberOfBlocks,
278
278
  initializationOffset: this.initializationOffset,
@@ -3,4 +3,7 @@ import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
3
3
  export type SequencerRollupConstants = Pick<
4
4
  L1RollupConstants,
5
5
  'ethereumSlotDuration' | 'l1GenesisTime' | 'slotDuration'
6
- >;
6
+ > & {
7
+ /** Total L2 gas (mana) allowed per checkpoint. Fetched from L1 getManaLimit(). */
8
+ rollupManaLimit: number;
9
+ };
@@ -1,8 +1,8 @@
1
- import { type BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types';
1
+ import { type BlockNumber, CheckpointNumber, IndexWithinCheckpoint } from '@aztec/foundation/branded-types';
2
2
  import { Fr } from '@aztec/foundation/curves/bn254';
3
+ import { unfreeze } from '@aztec/foundation/types';
3
4
  import { L2Block } from '@aztec/stdlib/block';
4
5
  import { Checkpoint } from '@aztec/stdlib/checkpoint';
5
- import { Gas } from '@aztec/stdlib/gas';
6
6
  import type {
7
7
  FullNodeBlockBuilderConfig,
8
8
  ICheckpointBlockBuilder,
@@ -86,8 +86,10 @@ export class MockCheckpointBuilder implements ICheckpointBlockBuilder {
86
86
  let usedTxs: Tx[];
87
87
 
88
88
  if (this.blockProvider) {
89
- // Dynamic mode: get block from provider
90
- block = this.blockProvider();
89
+ // Dynamic mode: get block from provider, cloning to avoid shared references across multiple buildBlock calls
90
+ block = L2Block.fromBuffer(this.blockProvider().toBuffer());
91
+ block.header.globalVariables.blockNumber = blockNumber;
92
+ await block.header.recomputeHash();
91
93
  usedTxs = [];
92
94
  this.builtBlocks.push(block);
93
95
  } else {
@@ -113,81 +115,79 @@ export class MockCheckpointBuilder implements ICheckpointBlockBuilder {
113
115
 
114
116
  return {
115
117
  block,
116
- publicGas: Gas.empty(),
117
118
  publicProcessorDuration: 0,
118
119
  numTxs: block?.body?.txEffects?.length ?? usedTxs.length,
119
120
  usedTxs,
120
121
  failedTxs: [],
121
- usedTxBlobFields: block?.body?.txEffects?.reduce((sum, tx) => sum + tx.getNumBlobFields(), 0) ?? 0,
122
122
  };
123
123
  }
124
124
 
125
125
  completeCheckpoint(): Promise<Checkpoint> {
126
126
  this.completeCheckpointCalled = true;
127
127
  const allBlocks = this.blockProvider ? this.builtBlocks : this.blocks;
128
- const lastBlock = allBlocks[allBlocks.length - 1];
129
- // Create a CheckpointHeader from the last block's header for testing
130
- const checkpointHeader = this.createCheckpointHeader(lastBlock);
131
- return Promise.resolve(
132
- new Checkpoint(
133
- makeAppendOnlyTreeSnapshot(lastBlock.header.globalVariables.blockNumber + 1),
134
- checkpointHeader,
135
- allBlocks,
136
- this.checkpointNumber,
137
- ),
138
- );
128
+ return this.buildCheckpoint(allBlocks);
139
129
  }
140
130
 
141
131
  getCheckpoint(): Promise<Checkpoint> {
142
132
  this.getCheckpointCalled = true;
143
133
  const builtBlocks = this.blockProvider ? this.builtBlocks : this.blocks.slice(0, this.blockIndex);
144
- const lastBlock = builtBlocks[builtBlocks.length - 1];
145
- if (!lastBlock) {
134
+ if (builtBlocks.length === 0) {
146
135
  throw new Error('No blocks built yet');
147
136
  }
148
- // Create a CheckpointHeader from the last block's header for testing
149
- const checkpointHeader = this.createCheckpointHeader(lastBlock);
150
- return Promise.resolve(
151
- new Checkpoint(
152
- makeAppendOnlyTreeSnapshot(lastBlock.header.globalVariables.blockNumber + 1),
153
- checkpointHeader,
154
- builtBlocks,
155
- this.checkpointNumber,
156
- ),
157
- );
137
+ return this.buildCheckpoint(builtBlocks);
158
138
  }
159
139
 
160
- /**
161
- * Creates a CheckpointHeader from a block's header for testing.
162
- * This is a simplified version that creates a minimal CheckpointHeader.
163
- */
164
- private createCheckpointHeader(block: L2Block): CheckpointHeader {
165
- const header = block.header;
166
- const gv = header.globalVariables;
167
- return CheckpointHeader.empty({
168
- lastArchiveRoot: header.lastArchive.root,
169
- blockHeadersHash: Fr.random(), // Use random for testing
140
+ /** Builds a structurally valid Checkpoint from a list of blocks, fixing up indexes and archive chaining. */
141
+ private async buildCheckpoint(blocks: L2Block[]): Promise<Checkpoint> {
142
+ // Fix up indexWithinCheckpoint and archive chaining so the checkpoint passes structural validation.
143
+ for (let i = 0; i < blocks.length; i++) {
144
+ blocks[i].indexWithinCheckpoint = IndexWithinCheckpoint(i);
145
+ if (i > 0) {
146
+ unfreeze(blocks[i].header).lastArchive = blocks[i - 1].archive;
147
+ await blocks[i].header.recomputeHash();
148
+ }
149
+ }
150
+
151
+ const firstBlock = blocks[0];
152
+ const lastBlock = blocks[blocks.length - 1];
153
+ const gv = firstBlock.header.globalVariables;
154
+
155
+ const checkpointHeader = CheckpointHeader.empty({
156
+ lastArchiveRoot: firstBlock.header.lastArchive.root,
157
+ blockHeadersHash: Fr.random(),
170
158
  slotNumber: gv.slotNumber,
171
159
  timestamp: gv.timestamp,
172
160
  coinbase: gv.coinbase,
173
161
  feeRecipient: gv.feeRecipient,
174
162
  gasFees: gv.gasFees,
175
- totalManaUsed: header.totalManaUsed,
163
+ totalManaUsed: lastBlock.header.totalManaUsed,
176
164
  });
165
+
166
+ return new Checkpoint(
167
+ makeAppendOnlyTreeSnapshot(lastBlock.header.globalVariables.blockNumber + 1),
168
+ checkpointHeader,
169
+ blocks,
170
+ this.checkpointNumber,
171
+ );
177
172
  }
178
173
 
179
- /** Reset for reuse in another test */
180
- reset(): void {
181
- this.blocks = [];
174
+ /** Resets per-checkpoint state (built blocks, consumed txs) while preserving config (blockProvider, seeded blocks). */
175
+ resetCheckpointState(): void {
182
176
  this.builtBlocks = [];
183
- this.usedTxsPerBlock = [];
184
177
  this.blockIndex = 0;
185
- this.buildBlockCalls = [];
186
178
  this.consumedTxHashes.clear();
187
179
  this.completeCheckpointCalled = false;
188
180
  this.getCheckpointCalled = false;
181
+ }
182
+
183
+ /** Reset for reuse in another test */
184
+ reset(): void {
185
+ this.blocks = [];
186
+ this.usedTxsPerBlock = [];
187
+ this.buildBlockCalls = [];
189
188
  this.errorOnBuild = undefined;
190
189
  this.blockProvider = undefined;
190
+ this.resetCheckpointState();
191
191
  }
192
192
  }
193
193
 
@@ -249,6 +249,7 @@ export class MockCheckpointsBuilder implements ICheckpointsBuilder {
249
249
  slotDuration: 24,
250
250
  l1ChainId: 1,
251
251
  rollupVersion: 1,
252
+ rollupManaLimit: 200_000_000,
252
253
  };
253
254
  }
254
255
 
@@ -275,6 +276,8 @@ export class MockCheckpointsBuilder implements ICheckpointsBuilder {
275
276
  if (!this.checkpointBuilder) {
276
277
  // Auto-create a builder if none was set
277
278
  this.checkpointBuilder = new MockCheckpointBuilder(constants, checkpointNumber);
279
+ } else {
280
+ this.checkpointBuilder.resetCheckpointState();
278
281
  }
279
282
 
280
283
  return Promise.resolve(this.checkpointBuilder);