@aztec/sequencer-client 0.0.1-commit.e2b2873ed → 0.0.1-commit.e304674f1

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 (85) hide show
  1. package/dest/client/sequencer-client.d.ts +15 -7
  2. package/dest/client/sequencer-client.d.ts.map +1 -1
  3. package/dest/client/sequencer-client.js +60 -30
  4. package/dest/config.d.ts +26 -6
  5. package/dest/config.d.ts.map +1 -1
  6. package/dest/config.js +44 -21
  7. package/dest/global_variable_builder/global_builder.d.ts +15 -11
  8. package/dest/global_variable_builder/global_builder.d.ts.map +1 -1
  9. package/dest/global_variable_builder/global_builder.js +29 -25
  10. package/dest/global_variable_builder/index.d.ts +2 -2
  11. package/dest/global_variable_builder/index.d.ts.map +1 -1
  12. package/dest/publisher/config.d.ts +47 -17
  13. package/dest/publisher/config.d.ts.map +1 -1
  14. package/dest/publisher/config.js +121 -42
  15. package/dest/publisher/index.d.ts +2 -1
  16. package/dest/publisher/index.d.ts.map +1 -1
  17. package/dest/publisher/l1_tx_failed_store/factory.d.ts +11 -0
  18. package/dest/publisher/l1_tx_failed_store/factory.d.ts.map +1 -0
  19. package/dest/publisher/l1_tx_failed_store/factory.js +22 -0
  20. package/dest/publisher/l1_tx_failed_store/failed_tx_store.d.ts +59 -0
  21. package/dest/publisher/l1_tx_failed_store/failed_tx_store.d.ts.map +1 -0
  22. package/dest/publisher/l1_tx_failed_store/failed_tx_store.js +1 -0
  23. package/dest/publisher/l1_tx_failed_store/file_store_failed_tx_store.d.ts +15 -0
  24. package/dest/publisher/l1_tx_failed_store/file_store_failed_tx_store.d.ts.map +1 -0
  25. package/dest/publisher/l1_tx_failed_store/file_store_failed_tx_store.js +34 -0
  26. package/dest/publisher/l1_tx_failed_store/index.d.ts +4 -0
  27. package/dest/publisher/l1_tx_failed_store/index.d.ts.map +1 -0
  28. package/dest/publisher/l1_tx_failed_store/index.js +2 -0
  29. package/dest/publisher/sequencer-publisher-factory.d.ts +11 -5
  30. package/dest/publisher/sequencer-publisher-factory.d.ts.map +1 -1
  31. package/dest/publisher/sequencer-publisher-factory.js +27 -3
  32. package/dest/publisher/sequencer-publisher.d.ts +82 -37
  33. package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
  34. package/dest/publisher/sequencer-publisher.js +430 -118
  35. package/dest/sequencer/checkpoint_proposal_job.d.ts +36 -9
  36. package/dest/sequencer/checkpoint_proposal_job.d.ts.map +1 -1
  37. package/dest/sequencer/checkpoint_proposal_job.js +361 -192
  38. package/dest/sequencer/checkpoint_voter.d.ts +1 -2
  39. package/dest/sequencer/checkpoint_voter.d.ts.map +1 -1
  40. package/dest/sequencer/checkpoint_voter.js +2 -5
  41. package/dest/sequencer/events.d.ts +2 -1
  42. package/dest/sequencer/events.d.ts.map +1 -1
  43. package/dest/sequencer/metrics.d.ts +21 -5
  44. package/dest/sequencer/metrics.d.ts.map +1 -1
  45. package/dest/sequencer/metrics.js +97 -15
  46. package/dest/sequencer/sequencer.d.ts +40 -17
  47. package/dest/sequencer/sequencer.d.ts.map +1 -1
  48. package/dest/sequencer/sequencer.js +152 -95
  49. package/dest/sequencer/timetable.d.ts +7 -3
  50. package/dest/sequencer/timetable.d.ts.map +1 -1
  51. package/dest/sequencer/timetable.js +21 -12
  52. package/dest/sequencer/types.d.ts +2 -2
  53. package/dest/sequencer/types.d.ts.map +1 -1
  54. package/dest/test/index.d.ts +3 -5
  55. package/dest/test/index.d.ts.map +1 -1
  56. package/dest/test/mock_checkpoint_builder.d.ts +11 -11
  57. package/dest/test/mock_checkpoint_builder.d.ts.map +1 -1
  58. package/dest/test/mock_checkpoint_builder.js +45 -34
  59. package/dest/test/utils.d.ts +3 -3
  60. package/dest/test/utils.d.ts.map +1 -1
  61. package/dest/test/utils.js +5 -4
  62. package/package.json +27 -28
  63. package/src/client/sequencer-client.ts +76 -30
  64. package/src/config.ts +56 -27
  65. package/src/global_variable_builder/global_builder.ts +38 -27
  66. package/src/global_variable_builder/index.ts +1 -1
  67. package/src/publisher/config.ts +153 -43
  68. package/src/publisher/index.ts +3 -0
  69. package/src/publisher/l1_tx_failed_store/factory.ts +32 -0
  70. package/src/publisher/l1_tx_failed_store/failed_tx_store.ts +55 -0
  71. package/src/publisher/l1_tx_failed_store/file_store_failed_tx_store.ts +46 -0
  72. package/src/publisher/l1_tx_failed_store/index.ts +3 -0
  73. package/src/publisher/sequencer-publisher-factory.ts +38 -9
  74. package/src/publisher/sequencer-publisher.ts +503 -168
  75. package/src/sequencer/README.md +81 -12
  76. package/src/sequencer/checkpoint_proposal_job.ts +471 -201
  77. package/src/sequencer/checkpoint_voter.ts +1 -12
  78. package/src/sequencer/events.ts +1 -1
  79. package/src/sequencer/metrics.ts +106 -18
  80. package/src/sequencer/sequencer.ts +216 -109
  81. package/src/sequencer/timetable.ts +26 -15
  82. package/src/sequencer/types.ts +1 -1
  83. package/src/test/index.ts +2 -4
  84. package/src/test/mock_checkpoint_builder.ts +63 -49
  85. package/src/test/utils.ts +5 -2
@@ -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,
@@ -70,6 +70,9 @@ export class SequencerTimetable {
70
70
  /** Maximum number of blocks that can be built in this slot configuration */
71
71
  public readonly maxNumberOfBlocks: number;
72
72
 
73
+ /** Whether pipelining is enabled (checkpoint finalization deferred to next slot). */
74
+ public readonly pipelining: boolean;
75
+
73
76
  constructor(
74
77
  opts: {
75
78
  ethereumSlotDuration: number;
@@ -78,9 +81,10 @@ export class SequencerTimetable {
78
81
  p2pPropagationTime?: number;
79
82
  blockDurationMs?: number;
80
83
  enforce: boolean;
84
+ pipelining?: boolean;
81
85
  },
82
86
  private readonly metrics?: SequencerMetrics,
83
- private readonly log = createLogger('sequencer:timetable'),
87
+ private readonly log?: Logger,
84
88
  ) {
85
89
  this.ethereumSlotDuration = opts.ethereumSlotDuration;
86
90
  this.aztecSlotDuration = opts.aztecSlotDuration;
@@ -88,6 +92,7 @@ export class SequencerTimetable {
88
92
  this.p2pPropagationTime = opts.p2pPropagationTime ?? DEFAULT_P2P_PROPAGATION_TIME;
89
93
  this.blockDuration = opts.blockDurationMs ? opts.blockDurationMs / 1000 : undefined;
90
94
  this.enforce = opts.enforce;
95
+ this.pipelining = opts.pipelining ?? false;
91
96
 
92
97
  // Assume zero-cost propagation time and faster runs in test environments where L1 slot duration is shortened
93
98
  if (this.ethereumSlotDuration < 8) {
@@ -116,23 +121,28 @@ export class SequencerTimetable {
116
121
  if (!this.blockDuration) {
117
122
  this.maxNumberOfBlocks = 1; // Single block per slot
118
123
  } else {
119
- const timeReservedAtEnd =
120
- this.blockDuration + // Last sub-slot for validator re-execution
121
- this.checkpointFinalizationTime; // Checkpoint finalization
124
+ // When pipelining, finalization is deferred to the next slot, but we still need
125
+ // a sub-slot for validator re-execution so they can produce attestations.
126
+ let timeReservedAtEnd = this.blockDuration; // Validatior re-execution only
127
+ if (!this.pipelining) {
128
+ timeReservedAtEnd += this.checkpointFinalizationTime;
129
+ }
130
+
122
131
  const timeAvailableForBlocks = this.aztecSlotDuration - this.initializationOffset - timeReservedAtEnd;
123
132
  this.maxNumberOfBlocks = Math.floor(timeAvailableForBlocks / this.blockDuration);
124
133
  }
125
134
 
126
- // Minimum work to do within a slot for building a block with the minimum time for execution and publishing its checkpoint
127
- const minWorkToDo =
128
- this.initializationOffset +
129
- this.minExecutionTime * 2 + // Execution and reexecution
130
- this.checkpointFinalizationTime;
135
+ // Minimum work to do within a slot for building a block with the minimum time for execution and publishing its checkpoint.
136
+ // When pipelining, finalization is deferred, but we still need time for execution and validator re-execution.
137
+ let minWorkToDo = this.initializationOffset + this.minExecutionTime * 2;
138
+ if (!this.pipelining) {
139
+ minWorkToDo += this.checkpointFinalizationTime;
140
+ }
131
141
 
132
142
  const initializeDeadline = this.aztecSlotDuration - minWorkToDo;
133
143
  this.initializeDeadline = initializeDeadline;
134
144
 
135
- this.log.verbose(
145
+ this.log?.info(
136
146
  `Sequencer timetable initialized with ${this.maxNumberOfBlocks} blocks per slot (${this.enforce ? 'enforced' : 'not enforced'})`,
137
147
  {
138
148
  ethereumSlotDuration: this.ethereumSlotDuration,
@@ -144,6 +154,7 @@ export class SequencerTimetable {
144
154
  blockAssembleTime: this.checkpointAssembleTime,
145
155
  initializeDeadline: this.initializeDeadline,
146
156
  enforce: this.enforce,
157
+ pipelining: this.pipelining,
147
158
  minWorkToDo,
148
159
  blockDuration: this.blockDuration,
149
160
  maxNumberOfBlocks: this.maxNumberOfBlocks,
@@ -206,7 +217,7 @@ export class SequencerTimetable {
206
217
  }
207
218
 
208
219
  this.metrics?.recordStateTransitionBufferMs(Math.floor(bufferSeconds * 1000), newState);
209
- this.log.trace(`Enough time to transition to ${newState}`, { maxAllowedTime, secondsIntoSlot });
220
+ this.log?.trace(`Enough time to transition to ${newState}`, { maxAllowedTime, secondsIntoSlot });
210
221
  }
211
222
 
212
223
  /**
@@ -242,7 +253,7 @@ export class SequencerTimetable {
242
253
  const canStart = available >= this.minExecutionTime;
243
254
  const deadline = secondsIntoSlot + available;
244
255
 
245
- this.log.verbose(
256
+ this.log?.verbose(
246
257
  `${canStart ? 'Can' : 'Cannot'} start single-block checkpoint at ${secondsIntoSlot}s into slot`,
247
258
  { secondsIntoSlot, maxAllowed, available, deadline },
248
259
  );
@@ -262,7 +273,7 @@ export class SequencerTimetable {
262
273
  // Found an available sub-slot! Is this the last one?
263
274
  const isLastBlock = subSlot === this.maxNumberOfBlocks;
264
275
 
265
- this.log.verbose(
276
+ this.log?.verbose(
266
277
  `Can start ${isLastBlock ? 'last block' : 'block'} in sub-slot ${subSlot} with deadline ${deadline}s`,
267
278
  { secondsIntoSlot, deadline, timeUntilDeadline, subSlot, maxBlocks: this.maxNumberOfBlocks },
268
279
  );
@@ -272,7 +283,7 @@ export class SequencerTimetable {
272
283
  }
273
284
 
274
285
  // No sub-slots available with enough time
275
- this.log.verbose(`No time left to start any more blocks`, {
286
+ this.log?.verbose(`No time left to start any more blocks`, {
276
287
  secondsIntoSlot,
277
288
  maxBlocks: this.maxNumberOfBlocks,
278
289
  initializationOffset: this.initializationOffset,
@@ -2,5 +2,5 @@ import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
2
2
 
3
3
  export type SequencerRollupConstants = Pick<
4
4
  L1RollupConstants,
5
- 'ethereumSlotDuration' | 'l1GenesisTime' | 'slotDuration'
5
+ 'ethereumSlotDuration' | 'l1GenesisTime' | 'slotDuration' | 'rollupManaLimit'
6
6
  >;
package/src/test/index.ts CHANGED
@@ -1,18 +1,16 @@
1
- import type { L1TxUtilsWithBlobs } from '@aztec/ethereum/l1-tx-utils-with-blobs';
1
+ import type { L1TxUtils } from '@aztec/ethereum/l1-tx-utils';
2
2
  import type { PublisherManager } from '@aztec/ethereum/publisher-manager';
3
3
  import type { PublicProcessorFactory } from '@aztec/simulator/server';
4
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
- import type { SequencerPublisher } from '../publisher/sequencer-publisher.js';
9
8
  import { Sequencer } from '../sequencer/sequencer.js';
10
9
  import type { SequencerTimetable } from '../sequencer/timetable.js';
11
10
 
12
11
  class TestSequencer_ extends Sequencer {
13
12
  declare public publicProcessorFactory: PublicProcessorFactory;
14
13
  declare public timetable: SequencerTimetable;
15
- declare public publisher: SequencerPublisher;
16
14
  declare public publisherFactory: SequencerPublisherFactory;
17
15
  declare public validatorClient: ValidatorClient;
18
16
  declare public checkpointsBuilder: FullNodeCheckpointsBuilder;
@@ -22,7 +20,7 @@ export type TestSequencer = TestSequencer_;
22
20
 
23
21
  class TestSequencerClient_ extends SequencerClient {
24
22
  declare public sequencer: TestSequencer;
25
- declare public publisherManager: PublisherManager<L1TxUtilsWithBlobs>;
23
+ declare public publisherManager: PublisherManager<L1TxUtils>;
26
24
  }
27
25
 
28
26
  export type TestSequencerClient = TestSequencerClient_;
@@ -1,14 +1,14 @@
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
+ BlockBuilderOptions,
7
8
  FullNodeBlockBuilderConfig,
8
9
  ICheckpointBlockBuilder,
9
10
  ICheckpointsBuilder,
10
11
  MerkleTreeWriteOperations,
11
- PublicProcessorLimits,
12
12
  } from '@aztec/stdlib/interfaces/server';
13
13
  import { CheckpointHeader } from '@aztec/stdlib/rollup';
14
14
  import { makeAppendOnlyTreeSnapshot } from '@aztec/stdlib/testing';
@@ -32,7 +32,7 @@ export class MockCheckpointBuilder implements ICheckpointBlockBuilder {
32
32
  public buildBlockCalls: Array<{
33
33
  blockNumber: BlockNumber;
34
34
  timestamp: bigint;
35
- opts: PublicProcessorLimits;
35
+ opts: BlockBuilderOptions;
36
36
  }> = [];
37
37
  /** Track all consumed transaction hashes across buildBlock calls */
38
38
  public consumedTxHashes: Set<string> = new Set();
@@ -74,7 +74,7 @@ export class MockCheckpointBuilder implements ICheckpointBlockBuilder {
74
74
  pendingTxs: Iterable<Tx> | AsyncIterable<Tx>,
75
75
  blockNumber: BlockNumber,
76
76
  timestamp: bigint,
77
- opts: PublicProcessorLimits,
77
+ opts: BlockBuilderOptions,
78
78
  ): Promise<BuildBlockInCheckpointResult> {
79
79
  this.buildBlockCalls.push({ blockNumber, timestamp, opts });
80
80
 
@@ -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
 
@@ -205,6 +205,7 @@ export class MockCheckpointsBuilder implements ICheckpointsBuilder {
205
205
  constants: CheckpointGlobalVariables;
206
206
  l1ToL2Messages: Fr[];
207
207
  previousCheckpointOutHashes: Fr[];
208
+ feeAssetPriceModifier: bigint;
208
209
  }> = [];
209
210
  public openCheckpointCalls: Array<{
210
211
  checkpointNumber: CheckpointNumber;
@@ -212,6 +213,7 @@ export class MockCheckpointsBuilder implements ICheckpointsBuilder {
212
213
  l1ToL2Messages: Fr[];
213
214
  previousCheckpointOutHashes: Fr[];
214
215
  existingBlocks: L2Block[];
216
+ feeAssetPriceModifier: bigint;
215
217
  }> = [];
216
218
  public updateConfigCalls: Array<Partial<FullNodeBlockBuilderConfig>> = [];
217
219
 
@@ -247,6 +249,7 @@ export class MockCheckpointsBuilder implements ICheckpointsBuilder {
247
249
  slotDuration: 24,
248
250
  l1ChainId: 1,
249
251
  rollupVersion: 1,
252
+ rollupManaLimit: 200_000_000,
250
253
  };
251
254
  }
252
255
 
@@ -257,15 +260,24 @@ export class MockCheckpointsBuilder implements ICheckpointsBuilder {
257
260
  startCheckpoint(
258
261
  checkpointNumber: CheckpointNumber,
259
262
  constants: CheckpointGlobalVariables,
263
+ feeAssetPriceModifier: bigint,
260
264
  l1ToL2Messages: Fr[],
261
265
  previousCheckpointOutHashes: Fr[],
262
266
  _fork: MerkleTreeWriteOperations,
263
267
  ): Promise<ICheckpointBlockBuilder> {
264
- this.startCheckpointCalls.push({ checkpointNumber, constants, l1ToL2Messages, previousCheckpointOutHashes });
268
+ this.startCheckpointCalls.push({
269
+ checkpointNumber,
270
+ constants,
271
+ l1ToL2Messages,
272
+ previousCheckpointOutHashes,
273
+ feeAssetPriceModifier,
274
+ });
265
275
 
266
276
  if (!this.checkpointBuilder) {
267
277
  // Auto-create a builder if none was set
268
278
  this.checkpointBuilder = new MockCheckpointBuilder(constants, checkpointNumber);
279
+ } else {
280
+ this.checkpointBuilder.resetCheckpointState();
269
281
  }
270
282
 
271
283
  return Promise.resolve(this.checkpointBuilder);
@@ -274,6 +286,7 @@ export class MockCheckpointsBuilder implements ICheckpointsBuilder {
274
286
  openCheckpoint(
275
287
  checkpointNumber: CheckpointNumber,
276
288
  constants: CheckpointGlobalVariables,
289
+ feeAssetPriceModifier: bigint,
277
290
  l1ToL2Messages: Fr[],
278
291
  previousCheckpointOutHashes: Fr[],
279
292
  _fork: MerkleTreeWriteOperations,
@@ -285,6 +298,7 @@ export class MockCheckpointsBuilder implements ICheckpointsBuilder {
285
298
  l1ToL2Messages,
286
299
  previousCheckpointOutHashes,
287
300
  existingBlocks,
301
+ feeAssetPriceModifier,
288
302
  });
289
303
 
290
304
  if (!this.checkpointBuilder) {
package/src/test/utils.ts CHANGED
@@ -56,6 +56,7 @@ export async function makeBlock(txs: Tx[], globalVariables: GlobalVariables): Pr
56
56
  export function mockPendingTxs(p2p: MockProxy<P2P>, txs: Tx[]): void {
57
57
  p2p.getPendingTxCount.mockResolvedValue(txs.length);
58
58
  p2p.iteratePendingTxs.mockImplementation(() => mockTxIterator(Promise.resolve(txs)));
59
+ p2p.iterateEligiblePendingTxs.mockImplementation(() => mockTxIterator(Promise.resolve(txs)));
59
60
  }
60
61
 
61
62
  /**
@@ -118,10 +119,11 @@ export function createCheckpointProposal(
118
119
  block: L2Block,
119
120
  checkpointSignature: Signature,
120
121
  blockSignature?: Signature,
122
+ feeAssetPriceModifier: bigint = 0n,
121
123
  ): CheckpointProposal {
122
124
  const txHashes = block.body.txEffects.map(tx => tx.txHash);
123
125
  const checkpointHeader = createCheckpointHeaderFromBlock(block);
124
- return new CheckpointProposal(checkpointHeader, block.archive.root, checkpointSignature, {
126
+ return new CheckpointProposal(checkpointHeader, block.archive.root, feeAssetPriceModifier, checkpointSignature, {
125
127
  blockHeader: block.header,
126
128
  indexWithinCheckpoint: block.indexWithinCheckpoint,
127
129
  txHashes,
@@ -138,9 +140,10 @@ export function createCheckpointAttestation(
138
140
  block: L2Block,
139
141
  signature: Signature,
140
142
  sender: EthAddress,
143
+ feeAssetPriceModifier: bigint = 0n,
141
144
  ): CheckpointAttestation {
142
145
  const checkpointHeader = createCheckpointHeaderFromBlock(block);
143
- const payload = new ConsensusPayload(checkpointHeader, block.archive.root);
146
+ const payload = new ConsensusPayload(checkpointHeader, block.archive.root, feeAssetPriceModifier);
144
147
  const attestation = new CheckpointAttestation(payload, signature, signature);
145
148
  // Set sender directly for testing (bypasses signature recovery)
146
149
  (attestation as any).sender = sender;