@aztec/sequencer-client 0.0.1-commit.b655e406 → 0.0.1-commit.d3ec352c

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 (55) hide show
  1. package/dest/client/index.d.ts +1 -1
  2. package/dest/client/sequencer-client.d.ts +1 -1
  3. package/dest/client/sequencer-client.d.ts.map +1 -1
  4. package/dest/client/sequencer-client.js +2 -1
  5. package/dest/config.d.ts +1 -1
  6. package/dest/config.d.ts.map +1 -1
  7. package/dest/config.js +9 -0
  8. package/dest/global_variable_builder/global_builder.d.ts +3 -6
  9. package/dest/global_variable_builder/global_builder.d.ts.map +1 -1
  10. package/dest/global_variable_builder/global_builder.js +9 -6
  11. package/dest/global_variable_builder/index.d.ts +1 -1
  12. package/dest/index.d.ts +1 -1
  13. package/dest/publisher/config.d.ts +3 -1
  14. package/dest/publisher/config.d.ts.map +1 -1
  15. package/dest/publisher/config.js +5 -0
  16. package/dest/publisher/index.d.ts +1 -1
  17. package/dest/publisher/sequencer-publisher-factory.d.ts +1 -1
  18. package/dest/publisher/sequencer-publisher-factory.d.ts.map +1 -1
  19. package/dest/publisher/sequencer-publisher-metrics.d.ts +1 -1
  20. package/dest/publisher/sequencer-publisher-metrics.d.ts.map +1 -1
  21. package/dest/publisher/sequencer-publisher.d.ts +35 -29
  22. package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
  23. package/dest/publisher/sequencer-publisher.js +115 -62
  24. package/dest/sequencer/block_builder.d.ts +3 -2
  25. package/dest/sequencer/block_builder.d.ts.map +1 -1
  26. package/dest/sequencer/block_builder.js +12 -8
  27. package/dest/sequencer/config.d.ts +1 -1
  28. package/dest/sequencer/errors.d.ts +1 -1
  29. package/dest/sequencer/errors.d.ts.map +1 -1
  30. package/dest/sequencer/index.d.ts +1 -1
  31. package/dest/sequencer/metrics.d.ts +11 -2
  32. package/dest/sequencer/metrics.d.ts.map +1 -1
  33. package/dest/sequencer/metrics.js +38 -0
  34. package/dest/sequencer/sequencer.d.ts +19 -27
  35. package/dest/sequencer/sequencer.d.ts.map +1 -1
  36. package/dest/sequencer/sequencer.js +175 -51
  37. package/dest/sequencer/timetable.d.ts +1 -1
  38. package/dest/sequencer/timetable.d.ts.map +1 -1
  39. package/dest/sequencer/utils.d.ts +1 -1
  40. package/dest/test/index.d.ts +1 -1
  41. package/dest/tx_validator/nullifier_cache.d.ts +1 -1
  42. package/dest/tx_validator/nullifier_cache.d.ts.map +1 -1
  43. package/dest/tx_validator/tx_validator_factory.d.ts +4 -3
  44. package/dest/tx_validator/tx_validator_factory.d.ts.map +1 -1
  45. package/package.json +31 -30
  46. package/src/client/sequencer-client.ts +2 -2
  47. package/src/config.ts +10 -0
  48. package/src/global_variable_builder/global_builder.ts +13 -9
  49. package/src/publisher/config.ts +8 -0
  50. package/src/publisher/sequencer-publisher-factory.ts +2 -1
  51. package/src/publisher/sequencer-publisher.ts +155 -84
  52. package/src/sequencer/block_builder.ts +15 -11
  53. package/src/sequencer/metrics.ts +51 -2
  54. package/src/sequencer/sequencer.ts +215 -72
  55. package/src/tx_validator/tx_validator_factory.ts +2 -1
@@ -4,8 +4,9 @@ function _ts_decorate(decorators, target, key, desc) {
4
4
  else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  }
7
- import { BLOBS_PER_BLOCK, FIELDS_PER_BLOB, INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
7
+ import { BLOBS_PER_CHECKPOINT, FIELDS_PER_BLOB, INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
8
8
  import { FormattedViemError, NoCommitteeError } from '@aztec/ethereum';
9
+ import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types';
9
10
  import { omit, pick } from '@aztec/foundation/collection';
10
11
  import { randomInt } from '@aztec/foundation/crypto';
11
12
  import { EthAddress } from '@aztec/foundation/eth-address';
@@ -15,7 +16,7 @@ import { createLogger } from '@aztec/foundation/log';
15
16
  import { RunningPromise } from '@aztec/foundation/running-promise';
16
17
  import { Timer } from '@aztec/foundation/timer';
17
18
  import { unfreeze } from '@aztec/foundation/types';
18
- import { CommitteeAttestationsAndSigners } from '@aztec/stdlib/block';
19
+ import { CommitteeAttestationsAndSigners, MaliciousCommitteeAttestationsAndSigners } from '@aztec/stdlib/block';
19
20
  import { getSlotAtTimestamp, getSlotStartBuildTimestamp } from '@aztec/stdlib/epoch-helpers';
20
21
  import { Gas } from '@aztec/stdlib/gas';
21
22
  import { SequencerConfigSchema } from '@aztec/stdlib/interfaces/server';
@@ -69,6 +70,7 @@ export { SequencerState };
69
70
  lastBlockPublished;
70
71
  governanceProposerPayload;
71
72
  /** The last slot for which we attempted to vote when sync failed, to prevent duplicate attempts. */ lastSlotForVoteWhenSyncFailed;
73
+ /** The last slot for which we built a validation block in fisherman mode, to prevent duplicate attempts. */ lastSlotForValidationBlock;
72
74
  /** The maximum number of seconds that the sequencer can be into a slot to transition to a particular state. */ timetable;
73
75
  enforceTimeTable;
74
76
  // This shouldn't be here as this gets re-created each time we build/propose a block.
@@ -79,6 +81,10 @@ export { SequencerState };
79
81
  publisher;
80
82
  constructor(publisherFactory, validatorClient, globalsBuilder, p2pClient, worldState, slasherClient, l2BlockSource, l1ToL2MessageSource, blockBuilder, l1Constants, dateProvider, epochCache, rollupContract, config, telemetry = getTelemetryClient(), log = createLogger('sequencer')){
81
83
  super(), this.publisherFactory = publisherFactory, this.validatorClient = validatorClient, this.globalsBuilder = globalsBuilder, this.p2pClient = p2pClient, this.worldState = worldState, this.slasherClient = slasherClient, this.l2BlockSource = l2BlockSource, this.l1ToL2MessageSource = l1ToL2MessageSource, this.blockBuilder = blockBuilder, this.l1Constants = l1Constants, this.dateProvider = dateProvider, this.epochCache = epochCache, this.rollupContract = rollupContract, this.config = config, this.telemetry = telemetry, this.log = log, this.pollingIntervalMs = 1000, this.maxTxsPerBlock = 32, this.minTxsPerBlock = 1, this.maxL1TxInclusionTimeIntoSlot = 0, this.state = SequencerState.STOPPED, this.maxBlockSizeInBytes = 1024 * 1024, this.maxBlockGas = new Gas(100e9, 100e9), this.enforceTimeTable = false;
84
+ // Add [FISHERMAN] prefix to logger if in fisherman mode
85
+ if (this.config.fishermanMode) {
86
+ this.log = log.createChild('[FISHERMAN]');
87
+ }
82
88
  this.metrics = new SequencerMetrics(telemetry, this.rollupContract, 'Sequencer');
83
89
  // Initialize config
84
90
  this.updateConfig(this.config);
@@ -201,7 +207,7 @@ export { SequencerState };
201
207
  return;
202
208
  }
203
209
  const chainTipArchive = syncedTo.archive;
204
- const newBlockNumber = syncedTo.blockNumber + 1;
210
+ const newBlockNumber = BlockNumber(syncedTo.blockNumber + 1);
205
211
  const syncLogData = {
206
212
  now,
207
213
  syncedToL1Ts: syncedTo.l1Timestamp,
@@ -215,25 +221,50 @@ export { SequencerState };
215
221
  // Check that we are a proposer for the next slot
216
222
  this.setState(SequencerState.PROPOSER_CHECK, slot);
217
223
  const [canPropose, proposer] = await this.checkCanPropose(slot);
218
- // If we are not a proposer, check if we should invalidate a invalid block, and bail
224
+ // If we are not a proposer check if we should invalidate a invalid block, and bail
219
225
  if (!canPropose) {
220
226
  await this.considerInvalidatingBlock(syncedTo, slot);
221
227
  return;
222
228
  }
229
+ // In fisherman mode, check if we've already validated this slot to prevent duplicate attempts
230
+ if (this.config.fishermanMode) {
231
+ if (this.lastSlotForValidationBlock === slot) {
232
+ this.log.trace(`Already validated block building for slot ${slot} (skipping)`, {
233
+ slot
234
+ });
235
+ return;
236
+ }
237
+ this.log.debug(`Building validation block for slot ${slot} (actual proposer: ${proposer?.toString() ?? 'none'})`, {
238
+ slot,
239
+ proposer: proposer?.toString()
240
+ });
241
+ // Mark this slot as being validated
242
+ this.lastSlotForValidationBlock = slot;
243
+ }
223
244
  // Check that the slot is not taken by a block already (should never happen, since only us can propose for this slot)
224
245
  if (syncedTo.block && syncedTo.block.header.getSlot() >= slot) {
225
246
  this.log.warn(`Cannot propose block at next L2 slot ${slot} since that slot was taken by block ${syncedTo.blockNumber}`, {
226
247
  ...syncLogData,
227
248
  block: syncedTo.block.header.toInspect()
228
249
  });
250
+ this.metrics.recordBlockProposalPrecheckFailed('slot_already_taken');
229
251
  return;
230
252
  }
231
253
  // We now need to get ourselves a publisher.
232
254
  // The returned attestor will be the one we provided if we provided one.
233
255
  // Otherwise it will be a valid attestor for the returned publisher.
234
- const { attestorAddress, publisher } = await this.publisherFactory.create(proposer);
256
+ // In fisherman mode, pass undefined to use the fisherman's own keystore instead of the actual proposer's
257
+ const { attestorAddress, publisher } = await this.publisherFactory.create(this.config.fishermanMode ? undefined : proposer);
235
258
  this.log.verbose(`Created publisher at address ${publisher.getSenderAddress()} for attestor ${attestorAddress}`);
236
259
  this.publisher = publisher;
260
+ // In fisherman mode, set the actual proposer's address for simulations
261
+ if (this.config.fishermanMode) {
262
+ if (proposer) {
263
+ publisher.setProposerAddressForSimulation(proposer);
264
+ this.log.debug(`Set proposer address ${proposer} for simulation in fisherman mode`);
265
+ }
266
+ }
267
+ // Get proposer credentials
237
268
  const coinbase = this.validatorClient.getCoinbaseForAttestor(attestorAddress);
238
269
  const feeRecipient = this.validatorClient.getFeeRecipientForAttestor(attestorAddress);
239
270
  // Prepare invalidation request if the pending chain is invalid (returns undefined if no need)
@@ -246,6 +277,7 @@ export { SequencerState };
246
277
  this.emit('proposer-rollup-check-failed', {
247
278
  reason: 'Rollup contract check failed'
248
279
  });
280
+ this.metrics.recordBlockProposalPrecheckFailed('rollup_contract_check_failed');
249
281
  return;
250
282
  } else if (canProposeCheck.slot !== slot) {
251
283
  this.log.warn(`Cannot propose block due to slot mismatch with rollup contract (this can be caused by a clock out of sync). Expected slot ${slot} but got ${canProposeCheck.slot}.`, {
@@ -257,9 +289,10 @@ export { SequencerState };
257
289
  this.emit('proposer-rollup-check-failed', {
258
290
  reason: 'Slot mismatch'
259
291
  });
292
+ this.metrics.recordBlockProposalPrecheckFailed('slot_mismatch');
260
293
  return;
261
- } else if (canProposeCheck.blockNumber !== BigInt(newBlockNumber)) {
262
- this.log.warn(`Cannot propose block due to block mismatch with rollup contract (this can be caused by a pending archiver sync). Expected block ${newBlockNumber} but got ${canProposeCheck.blockNumber}.`, {
294
+ } else if (canProposeCheck.checkpointNumber !== CheckpointNumber.fromBlockNumber(newBlockNumber)) {
295
+ this.log.warn(`Cannot propose block due to block mismatch with rollup contract (this can be caused by a pending archiver sync). Expected block ${newBlockNumber} but got ${canProposeCheck.checkpointNumber}.`, {
263
296
  ...syncLogData,
264
297
  rollup: canProposeCheck,
265
298
  newBlockNumber,
@@ -268,6 +301,7 @@ export { SequencerState };
268
301
  this.emit('proposer-rollup-check-failed', {
269
302
  reason: 'Block mismatch'
270
303
  });
304
+ this.metrics.recordBlockProposalPrecheckFailed('block_number_mismatch');
271
305
  return;
272
306
  }
273
307
  this.log.debug(`Can propose block ${newBlockNumber} at slot ${slot} as ${proposer}`, {
@@ -275,6 +309,7 @@ export { SequencerState };
275
309
  });
276
310
  const newGlobalVariables = await this.globalsBuilder.buildGlobalVariables(newBlockNumber, coinbase, feeRecipient, slot);
277
311
  // Enqueue governance and slashing votes (returns promises that will be awaited later)
312
+ // In fisherman mode, we simulate slashing but don't actually publish to L1
278
313
  const votesPromises = this.enqueueGovernanceAndSlashingVotes(publisher, attestorAddress, slot, newGlobalVariables.timestamp);
279
314
  // Enqueues block invalidation
280
315
  if (invalidateBlock && !this.config.skipInvalidateBlockAsProposer) {
@@ -282,21 +317,45 @@ export { SequencerState };
282
317
  }
283
318
  // Actual block building
284
319
  this.setState(SequencerState.INITIALIZING_PROPOSAL, slot);
320
+ this.metrics.incOpenSlot(slot, proposer?.toString() ?? 'unknown');
285
321
  const block = await this.tryBuildBlockAndEnqueuePublish(slot, proposer, newBlockNumber, publisher, newGlobalVariables, chainTipArchive, invalidateBlock);
286
322
  // Wait until the voting promises have resolved, so all requests are enqueued
287
323
  await Promise.all(votesPromises);
288
- // And send the tx to L1
289
- const l1Response = await publisher.sendRequests();
290
- const proposedBlock = l1Response?.successfulActions.find((a)=>a === 'propose');
291
- if (proposedBlock) {
292
- this.lastBlockPublished = block;
293
- this.emit('block-published', {
294
- blockNumber: newBlockNumber,
295
- slot: Number(slot)
296
- });
297
- await this.metrics.incFilledSlot(publisher.getSenderAddress().toString(), coinbase);
298
- } else if (block) {
299
- this.emit('block-publish-failed', l1Response ?? {});
324
+ // In fisherman mode, we don't publish to L1
325
+ if (this.config.fishermanMode) {
326
+ // Clear pending requests
327
+ publisher.clearPendingRequests();
328
+ if (block) {
329
+ this.log.info(`Validation block building SUCCEEDED for slot ${slot}`, {
330
+ blockNumber: newBlockNumber,
331
+ slot: Number(slot),
332
+ archive: block.archive.toString(),
333
+ txCount: block.body.txEffects.length
334
+ });
335
+ this.lastBlockPublished = block;
336
+ this.metrics.recordBlockProposalSuccess();
337
+ } else {
338
+ // Block building failed in fisherman mode
339
+ this.log.warn(`Validation block building FAILED for slot ${slot}`, {
340
+ blockNumber: newBlockNumber,
341
+ slot: Number(slot)
342
+ });
343
+ this.metrics.recordBlockProposalFailed('block_build_failed');
344
+ }
345
+ } else {
346
+ // Normal mode: send the tx to L1
347
+ const l1Response = await publisher.sendRequests();
348
+ const proposedBlock = l1Response?.successfulActions.find((a)=>a === 'propose');
349
+ if (proposedBlock) {
350
+ this.lastBlockPublished = block;
351
+ this.emit('block-published', {
352
+ blockNumber: newBlockNumber,
353
+ slot: Number(slot)
354
+ });
355
+ await this.metrics.incFilledSlot(publisher.getSenderAddress().toString(), coinbase);
356
+ } else if (block) {
357
+ this.emit('block-publish-failed', l1Response ?? {});
358
+ }
300
359
  }
301
360
  this.setState(SequencerState.IDLE, undefined);
302
361
  }
@@ -313,6 +372,7 @@ export { SequencerState };
313
372
  ...newGlobalVariables,
314
373
  timestamp: newGlobalVariables.timestamp,
315
374
  lastArchiveRoot: chainTipArchive,
375
+ blockHeadersHash: Fr.ZERO,
316
376
  contentCommitment: ContentCommitment.empty(),
317
377
  totalManaUsed: Fr.ZERO
318
378
  });
@@ -336,6 +396,7 @@ export { SequencerState };
336
396
  slot
337
397
  });
338
398
  }
399
+ this.metrics.recordBlockProposalFailed(err.name || 'unknown_error');
339
400
  }
340
401
  } else {
341
402
  this.log.verbose(`Not enough txs to build block ${newBlockNumber} at slot ${slot} (got ${pendingTxCount} txs, need ${this.minTxsPerBlock})`, {
@@ -347,6 +408,7 @@ export { SequencerState };
347
408
  minTxs: this.minTxsPerBlock,
348
409
  availableTxs: pendingTxCount
349
410
  });
411
+ this.metrics.recordBlockProposalFailed('insufficient_txs');
350
412
  }
351
413
  return block;
352
414
  }
@@ -421,7 +483,7 @@ export { SequencerState };
421
483
  maxTransactions: this.maxTxsPerBlock,
422
484
  maxBlockSize: this.maxBlockSizeInBytes,
423
485
  maxBlockGas: this.maxBlockGas,
424
- maxBlobFields: BLOBS_PER_BLOCK * FIELDS_PER_BLOB,
486
+ maxBlobFields: BLOBS_PER_CHECKPOINT * FIELDS_PER_BLOB,
425
487
  deadline
426
488
  };
427
489
  }
@@ -438,12 +500,12 @@ export { SequencerState };
438
500
  */ async buildBlockAndEnqueuePublish(pendingTxs, proposalHeader, newGlobalVariables, proposerAddress, invalidateBlock, publisher) {
439
501
  await publisher.validateBlockHeader(proposalHeader, invalidateBlock);
440
502
  const blockNumber = newGlobalVariables.blockNumber;
441
- const slot = proposalHeader.slotNumber.toBigInt();
503
+ const slot = proposalHeader.slotNumber;
442
504
  const l1ToL2Messages = await this.l1ToL2MessageSource.getL1ToL2Messages(blockNumber);
443
505
  const workTimer = new Timer();
444
506
  this.setState(SequencerState.CREATING_BLOCK, slot);
445
507
  try {
446
- const blockBuilderOptions = this.getBlockBuilderOptions(Number(slot));
508
+ const blockBuilderOptions = this.getBlockBuilderOptions(slot);
447
509
  const buildBlockRes = await this.blockBuilder.buildBlock(pendingTxs, l1ToL2Messages, newGlobalVariables, blockBuilderOptions);
448
510
  const { publicGas, block, publicProcessorDuration, numTxs, numMsgs, blockBuildingTimer, usedTxs, failedTxs } = buildBlockRes;
449
511
  const blockBuildDuration = workTimer.ms();
@@ -476,16 +538,22 @@ export { SequencerState };
476
538
  txHashes,
477
539
  ...blockStats
478
540
  });
479
- this.log.debug('Collecting attestations');
480
- const attestations = await this.collectAttestations(block, usedTxs, proposerAddress);
481
- if (attestations !== undefined) {
482
- this.log.verbose(`Collected ${attestations.length} attestations`, {
541
+ // In fisherman mode, skip attestation collection
542
+ let attestationsAndSigners;
543
+ if (this.config.fishermanMode) {
544
+ this.log.debug('Skipping attestation collection');
545
+ attestationsAndSigners = CommitteeAttestationsAndSigners.empty();
546
+ } else {
547
+ this.log.debug('Collecting attestations');
548
+ attestationsAndSigners = await this.collectAttestations(block, usedTxs, proposerAddress);
549
+ this.log.verbose(`Collected ${attestationsAndSigners.attestations.length} attestations for block ${blockNumber} at slot ${slot}`, {
483
550
  blockHash,
484
- blockNumber
551
+ blockNumber,
552
+ slot
485
553
  });
486
554
  }
487
- const attestationsAndSigners = new CommitteeAttestationsAndSigners(attestations ?? []);
488
- const attestationsAndSignersSignature = this.validatorClient ? await this.validatorClient.signAttestationsAndSigners(attestationsAndSigners, proposerAddress ?? publisher.getSenderAddress()) : Signature.empty();
555
+ // In fisherman mode, skip attestation signing
556
+ const attestationsAndSignersSignature = this.config.fishermanMode || !this.validatorClient ? Signature.empty() : await this.validatorClient.signAttestationsAndSigners(attestationsAndSigners, proposerAddress ?? publisher.getSenderAddress());
489
557
  await this.enqueuePublishL2Block(block, attestationsAndSigners, attestationsAndSignersSignature, invalidateBlock, publisher);
490
558
  this.metrics.recordBuiltBlock(blockBuildDuration, publicGas.l2Gas);
491
559
  return block;
@@ -495,38 +563,36 @@ export { SequencerState };
495
563
  }
496
564
  }
497
565
  async collectAttestations(block, txs, proposerAddress) {
498
- const { committee } = await this.epochCache.getCommittee(block.header.getSlot());
566
+ const { committee, seed, epoch } = await this.epochCache.getCommittee(block.slot);
499
567
  // We checked above that the committee is defined, so this should never happen.
500
568
  if (!committee) {
501
569
  throw new Error('No committee when collecting attestations');
502
570
  }
503
571
  if (committee.length === 0) {
504
572
  this.log.verbose(`Attesting committee is empty`);
505
- return undefined;
573
+ return CommitteeAttestationsAndSigners.empty();
506
574
  } else {
507
575
  this.log.debug(`Attesting committee length is ${committee.length}`);
508
576
  }
509
577
  if (!this.validatorClient) {
510
- const msg = 'Missing validator client: Cannot collect attestations';
511
- this.log.error(msg);
512
- throw new Error(msg);
578
+ throw new Error('Missing validator client: Cannot collect attestations');
513
579
  }
514
580
  const numberOfRequiredAttestations = Math.floor(committee.length * 2 / 3) + 1;
515
- const slotNumber = block.header.globalVariables.slotNumber.toBigInt();
581
+ const slotNumber = block.header.globalVariables.slotNumber;
516
582
  this.setState(SequencerState.COLLECTING_ATTESTATIONS, slotNumber);
517
583
  this.log.debug('Creating block proposal for validators');
518
584
  const blockProposalOptions = {
519
585
  publishFullTxs: !!this.config.publishTxsWithProposals,
520
586
  broadcastInvalidBlockProposal: this.config.broadcastInvalidBlockProposal
521
587
  };
522
- const proposal = await this.validatorClient.createBlockProposal(block.header.globalVariables.blockNumber, block.getCheckpointHeader(), block.archive.root, block.header.state, txs, proposerAddress, blockProposalOptions);
588
+ const proposal = await this.validatorClient.createBlockProposal(block.header.globalVariables.blockNumber, block.getCheckpointHeader(), block.archive.root, txs, proposerAddress, blockProposalOptions);
523
589
  if (!proposal) {
524
590
  throw new Error(`Failed to create block proposal`);
525
591
  }
526
592
  if (this.config.skipCollectingAttestations) {
527
593
  this.log.warn('Skipping attestation collection as per config (attesting with own keys only)');
528
594
  const attestations = await this.validatorClient?.collectOwnAttestations(proposal);
529
- return orderAttestations(attestations ?? [], committee);
595
+ return new CommitteeAttestationsAndSigners(orderAttestations(attestations ?? [], committee));
530
596
  }
531
597
  this.log.debug('Broadcasting block proposal to validators');
532
598
  await this.validatorClient.broadcastBlockProposal(proposal);
@@ -540,13 +606,11 @@ export { SequencerState };
540
606
  collectedAttestationsCount = attestations.length;
541
607
  // note: the smart contract requires that the signatures are provided in the order of the committee
542
608
  const sorted = orderAttestations(attestations, committee);
543
- if (this.config.injectFakeAttestation) {
544
- const nonEmpty = sorted.filter((a)=>!a.signature.isEmpty());
545
- const randomIndex = randomInt(nonEmpty.length);
546
- this.log.warn(`Injecting fake attestation in block ${block.number}`);
547
- unfreeze(nonEmpty[randomIndex]).signature = Signature.random();
609
+ // manipulate the attestations if we've been configured to do so
610
+ if (this.config.injectFakeAttestation || this.config.shuffleAttestationOrdering) {
611
+ return this.manipulateAttestations(block, epoch, seed, committee, sorted);
548
612
  }
549
- return sorted;
613
+ return new CommitteeAttestationsAndSigners(sorted);
550
614
  } catch (err) {
551
615
  if (err && err instanceof AttestationTimeoutError) {
552
616
  collectedAttestationsCount = err.collectedCount;
@@ -556,14 +620,51 @@ export { SequencerState };
556
620
  this.metrics.recordCollectedAttestations(collectedAttestationsCount, timer.ms());
557
621
  }
558
622
  }
623
+ /** Breaks the attestations before publishing based on attack configs */ manipulateAttestations(block, epoch, seed, committee, attestations) {
624
+ // Compute the proposer index in the committee, since we dont want to tweak it.
625
+ // Otherwise, the L1 rollup contract will reject the block outright.
626
+ const proposerIndex = Number(this.epochCache.computeProposerIndex(block.slot, epoch, seed, BigInt(committee.length)));
627
+ if (this.config.injectFakeAttestation) {
628
+ // Find non-empty attestations that are not from the proposer
629
+ const nonProposerIndices = [];
630
+ for(let i = 0; i < attestations.length; i++){
631
+ if (!attestations[i].signature.isEmpty() && i !== proposerIndex) {
632
+ nonProposerIndices.push(i);
633
+ }
634
+ }
635
+ if (nonProposerIndices.length > 0) {
636
+ const targetIndex = nonProposerIndices[randomInt(nonProposerIndices.length)];
637
+ this.log.warn(`Injecting fake attestation in block ${block.number} at index ${targetIndex}`);
638
+ unfreeze(attestations[targetIndex]).signature = Signature.random();
639
+ }
640
+ return new CommitteeAttestationsAndSigners(attestations);
641
+ }
642
+ if (this.config.shuffleAttestationOrdering) {
643
+ this.log.warn(`Shuffling attestation ordering in block ${block.number} (proposer index ${proposerIndex})`);
644
+ const shuffled = [
645
+ ...attestations
646
+ ];
647
+ const [i, j] = [
648
+ (proposerIndex + 1) % shuffled.length,
649
+ (proposerIndex + 2) % shuffled.length
650
+ ];
651
+ const valueI = shuffled[i];
652
+ const valueJ = shuffled[j];
653
+ shuffled[i] = valueJ;
654
+ shuffled[j] = valueI;
655
+ const signers = new CommitteeAttestationsAndSigners(attestations).getSigners();
656
+ return new MaliciousCommitteeAttestationsAndSigners(shuffled, signers);
657
+ }
658
+ return new CommitteeAttestationsAndSigners(attestations);
659
+ }
559
660
  /**
560
661
  * Publishes the L2Block to the rollup contract.
561
662
  * @param block - The L2Block to be published.
562
663
  */ async enqueuePublishL2Block(block, attestationsAndSigners, attestationsAndSignersSignature, invalidateBlock, publisher) {
563
664
  // Publishes new block to the network and awaits the tx to be mined
564
- this.setState(SequencerState.PUBLISHING_BLOCK, block.header.globalVariables.slotNumber.toBigInt());
665
+ this.setState(SequencerState.PUBLISHING_BLOCK, block.header.globalVariables.slotNumber);
565
666
  // Time out tx at the end of the slot
566
- const slot = block.header.globalVariables.slotNumber.toNumber();
667
+ const slot = block.header.globalVariables.slotNumber;
567
668
  const txTimeoutAt = new Date((this.getSlotStartBuildTimestamp(slot) + this.aztecSlotDuration) * 1000);
568
669
  const enqueued = await publisher.enqueueProposeL2Block(block, attestationsAndSigners, attestationsAndSignersSignature, {
569
670
  txTimeoutAt,
@@ -601,9 +702,9 @@ export { SequencerState };
601
702
  this.l2BlockSource.getPendingChainValidationStatus()
602
703
  ]);
603
704
  const [worldState, l2BlockSource, p2p, l1ToL2MessageSource, pendingChainValidationStatus] = syncedBlocks;
604
- // The archiver reports 'undefined' hash for the genesis block
605
- // because it doesn't have access to world state to compute it (facepalm)
606
- const result = l2BlockSource.hash === undefined ? worldState.number === 0 && p2p.number === 0 && l1ToL2MessageSource.number === 0 : worldState.hash === l2BlockSource.hash && p2p.hash === l2BlockSource.hash && l1ToL2MessageSource.hash === l2BlockSource.hash;
705
+ // 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,
706
+ // as the world state can compute the new genesis block hash, but other components use the hardcoded constant.
707
+ const result = l2BlockSource.number === 0 && worldState.number === 0 && p2p.number === 0 && l1ToL2MessageSource.number === 0 || worldState.hash === l2BlockSource.hash && p2p.hash === l2BlockSource.hash && l1ToL2MessageSource.hash === l2BlockSource.hash;
607
708
  if (!result) {
608
709
  this.log.debug(`Sequencer sync check failed`, {
609
710
  worldState,
@@ -618,7 +719,7 @@ export { SequencerState };
618
719
  if (blockNumber < INITIAL_L2_BLOCK_NUM) {
619
720
  const archive = new Fr((await this.worldState.getCommitted().getTreeInfo(MerkleTreeId.ARCHIVE)).root);
620
721
  return {
621
- blockNumber: INITIAL_L2_BLOCK_NUM - 1,
722
+ blockNumber: BlockNumber(INITIAL_L2_BLOCK_NUM - 1),
622
723
  archive,
623
724
  l1Timestamp,
624
725
  pendingChainValidationStatus
@@ -655,7 +756,18 @@ export { SequencerState };
655
756
  });
656
757
  return false;
657
758
  }) : undefined;
658
- const enqueueSlashingPromise = this.slasherClient ? this.slasherClient.getProposerActions(slot).then((actions)=>publisher.enqueueSlashingActions(actions, slot, timestamp, attestorAddress, signerFn)).catch((err)=>{
759
+ const enqueueSlashingPromise = this.slasherClient ? this.slasherClient.getProposerActions(slot).then((actions)=>{
760
+ // Record metrics for fisherman mode
761
+ if (this.config.fishermanMode && actions.length > 0) {
762
+ this.log.debug(`Fisherman mode: simulating ${actions.length} slashing action(s) for slot ${slot}`, {
763
+ slot,
764
+ actionCount: actions.length
765
+ });
766
+ this.metrics.recordSlashingAttempt(actions.length);
767
+ }
768
+ // Enqueue the actions to fully simulate L1 tx building (they won't be sent in fisherman mode)
769
+ return publisher.enqueueSlashingActions(actions, slot, timestamp, attestorAddress, signerFn);
770
+ }).catch((err)=>{
659
771
  this.log.error(`Error enqueuing slashing actions`, err, {
660
772
  slot
661
773
  });
@@ -701,6 +813,13 @@ export { SequencerState };
701
813
  undefined
702
814
  ];
703
815
  }
816
+ // In fisherman mode, just return the current proposer
817
+ if (this.config.fishermanMode) {
818
+ return [
819
+ true,
820
+ proposer
821
+ ];
822
+ }
704
823
  const validatorAddresses = this.validatorClient.getValidatorAddresses();
705
824
  const weAreProposer = validatorAddresses.some((addr)=>addr.equals(proposer));
706
825
  if (!weAreProposer) {
@@ -812,7 +931,12 @@ export { SequencerState };
812
931
  }
813
932
  this.log.info(invalidateAsCommitteeMember ? `Invalidating block ${invalidBlockNumber} as committee member` : `Invalidating block ${invalidBlockNumber} as non-committee member`, logData);
814
933
  publisher.enqueueInvalidateBlock(invalidateBlock);
815
- await publisher.sendRequests();
934
+ if (!this.config.fishermanMode) {
935
+ await publisher.sendRequests();
936
+ } else {
937
+ this.log.info('Invalidating block in fisherman mode, clearing pending requests');
938
+ publisher.clearPendingRequests();
939
+ }
816
940
  }
817
941
  getSlotStartBuildTimestamp(slotNumber) {
818
942
  return getSlotStartBuildTimestamp(slotNumber, this.l1Constants);
@@ -47,4 +47,4 @@ export declare class SequencerTimetable {
47
47
  getMaxAllowedTime(state: SequencerState): number | undefined;
48
48
  assertTimeLeft(newState: SequencerState, secondsIntoSlot: number): void;
49
49
  }
50
- //# sourceMappingURL=timetable.d.ts.map
50
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZXRhYmxlLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VxdWVuY2VyL3RpbWV0YWJsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFJQSxPQUFPLEtBQUssRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUNyRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBTTVDLHFCQUFhLGtCQUFrQjtJQStDM0IsT0FBTyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUM7SUFDekIsT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHO0lBL0N0Qjs7OztPQUlHO0lBQ0gsU0FBZ0Isa0JBQWtCLEVBQUUsTUFBTSxDQUFDO0lBRTNDOzs7O09BSUc7SUFDSCxTQUFnQixnQkFBZ0IsU0FBQztJQUVqQyxzSEFBc0g7SUFDdEgsU0FBZ0IsZ0JBQWdCLEVBQUUsTUFBTSxDQUFzQjtJQUU5RCx1REFBdUQ7SUFDdkQsU0FBZ0IsZ0JBQWdCLEVBQUUsTUFBTSxDQUFzQjtJQUU5RCxtR0FBbUc7SUFDbkcsU0FBZ0IsMEJBQTBCLEVBQUUsTUFBTSxDQUFDO0lBRW5ELG1JQUFtSTtJQUNuSSxTQUFnQixtQkFBbUIsRUFBRSxNQUFNLENBQXlCO0lBRXBFLHdDQUF3QztJQUN4QyxTQUFnQixvQkFBb0IsRUFBRSxNQUFNLENBQUM7SUFFN0Msa0ZBQWtGO0lBQ2xGLFNBQWdCLGlCQUFpQixFQUFFLE1BQU0sQ0FBQztJQUUxQywySUFBMkk7SUFDM0ksU0FBZ0IsNEJBQTRCLEVBQUUsTUFBTSxDQUFDO0lBRXJELDREQUE0RDtJQUM1RCxTQUFnQixPQUFPLEVBQUUsT0FBTyxDQUFDO0lBRWpDLFlBQ0UsSUFBSSxFQUFFO1FBQ0osb0JBQW9CLEVBQUUsTUFBTSxDQUFDO1FBQzdCLGlCQUFpQixFQUFFLE1BQU0sQ0FBQztRQUMxQiw0QkFBNEIsRUFBRSxNQUFNLENBQUM7UUFDckMsMEJBQTBCLENBQUMsRUFBRSxNQUFNLENBQUM7UUFDcEMsT0FBTyxFQUFFLE9BQU8sQ0FBQztLQUNsQixFQUNnQixPQUFPLENBQUMsOEJBQWtCLEVBQzFCLEdBQUcsdUNBQXNDLEVBNkMzRDtJQUVELE9BQU8sS0FBSyx5Q0FBeUMsR0FFcEQ7SUFFTSwyQkFBMkIsQ0FBQyxlQUFlLEVBQUUsTUFBTSxHQUFHLE1BQU0sQ0FhbEU7SUFFRCxPQUFPLEtBQUssMEJBQTBCLEdBRXJDO0lBRU0seUJBQXlCLENBQUMsZUFBZSxDQUFDLEVBQUUsTUFBTSxHQUFHLE1BQU0sQ0FRakU7SUFFTSxpQkFBaUIsQ0FDdEIsS0FBSyxFQUFFLE9BQU8sQ0FBQyxjQUFjLEVBQUUsY0FBYyxDQUFDLE9BQU8sR0FBRyxjQUFjLENBQUMsSUFBSSxHQUFHLGNBQWMsQ0FBQyxhQUFhLENBQUMsR0FDMUcsU0FBUyxDQUFDO0lBQ04saUJBQWlCLENBQ3RCLEtBQUssRUFBRSxPQUFPLENBQUMsY0FBYyxFQUFFLGNBQWMsQ0FBQyxPQUFPLEdBQUcsY0FBYyxDQUFDLElBQUksR0FBRyxjQUFjLENBQUMsYUFBYSxDQUFDLEdBQzFHLE1BQU0sQ0FBQztJQUNILGlCQUFpQixDQUFDLEtBQUssRUFBRSxjQUFjLEdBQUcsTUFBTSxHQUFHLFNBQVMsQ0FBQztJQXdCN0QsY0FBYyxDQUFDLFFBQVEsRUFBRSxjQUFjLEVBQUUsZUFBZSxFQUFFLE1BQU0sUUFpQnRFO0NBQ0YifQ==
@@ -1 +1 @@
1
- {"version":3,"file":"timetable.d.ts","sourceRoot":"","sources":["../../src/sequencer/timetable.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAM5C,qBAAa,kBAAkB;IA+C3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IACzB,OAAO,CAAC,QAAQ,CAAC,GAAG;IA/CtB;;;;OAIG;IACH,SAAgB,kBAAkB,EAAE,MAAM,CAAC;IAE3C;;;;OAIG;IACH,SAAgB,gBAAgB,SAAC;IAEjC,sHAAsH;IACtH,SAAgB,gBAAgB,EAAE,MAAM,CAAsB;IAE9D,uDAAuD;IACvD,SAAgB,gBAAgB,EAAE,MAAM,CAAsB;IAE9D,mGAAmG;IACnG,SAAgB,0BAA0B,EAAE,MAAM,CAAC;IAEnD,mIAAmI;IACnI,SAAgB,mBAAmB,EAAE,MAAM,CAAyB;IAEpE,wCAAwC;IACxC,SAAgB,oBAAoB,EAAE,MAAM,CAAC;IAE7C,kFAAkF;IAClF,SAAgB,iBAAiB,EAAE,MAAM,CAAC;IAE1C,2IAA2I;IAC3I,SAAgB,4BAA4B,EAAE,MAAM,CAAC;IAErD,4DAA4D;IAC5D,SAAgB,OAAO,EAAE,OAAO,CAAC;gBAG/B,IAAI,EAAE;QACJ,oBAAoB,EAAE,MAAM,CAAC;QAC7B,iBAAiB,EAAE,MAAM,CAAC;QAC1B,4BAA4B,EAAE,MAAM,CAAC;QACrC,0BAA0B,CAAC,EAAE,MAAM,CAAC;QACpC,OAAO,EAAE,OAAO,CAAC;KAClB,EACgB,OAAO,CAAC,EAAE,gBAAgB,YAAA,EAC1B,GAAG,uCAAsC;IA+C5D,OAAO,KAAK,yCAAyC,GAEpD;IAEM,2BAA2B,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM;IAenE,OAAO,KAAK,0BAA0B,GAErC;IAEM,yBAAyB,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM;IAU3D,iBAAiB,CACtB,KAAK,EAAE,OAAO,CAAC,cAAc,EAAE,cAAc,CAAC,OAAO,GAAG,cAAc,CAAC,IAAI,GAAG,cAAc,CAAC,aAAa,CAAC,GAC1G,SAAS;IACL,iBAAiB,CACtB,KAAK,EAAE,OAAO,CAAC,cAAc,EAAE,cAAc,CAAC,OAAO,GAAG,cAAc,CAAC,IAAI,GAAG,cAAc,CAAC,aAAa,CAAC,GAC1G,MAAM;IACF,iBAAiB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,GAAG,SAAS;IAwB5D,cAAc,CAAC,QAAQ,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM;CAkBxE"}
1
+ {"version":3,"file":"timetable.d.ts","sourceRoot":"","sources":["../../src/sequencer/timetable.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAM5C,qBAAa,kBAAkB;IA+C3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IACzB,OAAO,CAAC,QAAQ,CAAC,GAAG;IA/CtB;;;;OAIG;IACH,SAAgB,kBAAkB,EAAE,MAAM,CAAC;IAE3C;;;;OAIG;IACH,SAAgB,gBAAgB,SAAC;IAEjC,sHAAsH;IACtH,SAAgB,gBAAgB,EAAE,MAAM,CAAsB;IAE9D,uDAAuD;IACvD,SAAgB,gBAAgB,EAAE,MAAM,CAAsB;IAE9D,mGAAmG;IACnG,SAAgB,0BAA0B,EAAE,MAAM,CAAC;IAEnD,mIAAmI;IACnI,SAAgB,mBAAmB,EAAE,MAAM,CAAyB;IAEpE,wCAAwC;IACxC,SAAgB,oBAAoB,EAAE,MAAM,CAAC;IAE7C,kFAAkF;IAClF,SAAgB,iBAAiB,EAAE,MAAM,CAAC;IAE1C,2IAA2I;IAC3I,SAAgB,4BAA4B,EAAE,MAAM,CAAC;IAErD,4DAA4D;IAC5D,SAAgB,OAAO,EAAE,OAAO,CAAC;IAEjC,YACE,IAAI,EAAE;QACJ,oBAAoB,EAAE,MAAM,CAAC;QAC7B,iBAAiB,EAAE,MAAM,CAAC;QAC1B,4BAA4B,EAAE,MAAM,CAAC;QACrC,0BAA0B,CAAC,EAAE,MAAM,CAAC;QACpC,OAAO,EAAE,OAAO,CAAC;KAClB,EACgB,OAAO,CAAC,8BAAkB,EAC1B,GAAG,uCAAsC,EA6C3D;IAED,OAAO,KAAK,yCAAyC,GAEpD;IAEM,2BAA2B,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAalE;IAED,OAAO,KAAK,0BAA0B,GAErC;IAEM,yBAAyB,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CAQjE;IAEM,iBAAiB,CACtB,KAAK,EAAE,OAAO,CAAC,cAAc,EAAE,cAAc,CAAC,OAAO,GAAG,cAAc,CAAC,IAAI,GAAG,cAAc,CAAC,aAAa,CAAC,GAC1G,SAAS,CAAC;IACN,iBAAiB,CACtB,KAAK,EAAE,OAAO,CAAC,cAAc,EAAE,cAAc,CAAC,OAAO,GAAG,cAAc,CAAC,IAAI,GAAG,cAAc,CAAC,aAAa,CAAC,GAC1G,MAAM,CAAC;IACH,iBAAiB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,GAAG,SAAS,CAAC;IAwB7D,cAAc,CAAC,QAAQ,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,QAiBtE;CACF"}
@@ -21,4 +21,4 @@ export declare enum SequencerState {
21
21
  export type SequencerStateWithSlot = SequencerState.INITIALIZING_PROPOSAL | SequencerState.CREATING_BLOCK | SequencerState.COLLECTING_ATTESTATIONS | SequencerState.PUBLISHING_BLOCK | SequencerState.PROPOSER_CHECK;
22
22
  export type SequencerStateCallback = () => SequencerState;
23
23
  export declare function sequencerStateToNumber(state: SequencerState): number;
24
- //# sourceMappingURL=utils.d.ts.map
24
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXF1ZW5jZXIvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsb0JBQVksY0FBYztJQUN4QixxRUFBcUU7SUFDckUsT0FBTyxZQUFZO0lBQ25CLGdFQUFnRTtJQUNoRSxRQUFRLGFBQWE7SUFDckIscURBQXFEO0lBQ3JELElBQUksU0FBUztJQUNiLHVDQUF1QztJQUN2QyxhQUFhLGtCQUFrQjtJQUMvQiw0REFBNEQ7SUFDNUQsY0FBYyxtQkFBbUI7SUFDakMsMElBQTBJO0lBQzFJLHFCQUFxQiwwQkFBMEI7SUFDL0MsNklBQTZJO0lBQzdJLGNBQWMsbUJBQW1CO0lBQ2pDLDZFQUE2RTtJQUM3RSx1QkFBdUIsNEJBQTRCO0lBQ25ELDJHQUEyRztJQUMzRyxnQkFBZ0IscUJBQXFCO0NBQ3RDO0FBRUQsTUFBTSxNQUFNLHNCQUFzQixHQUM5QixjQUFjLENBQUMscUJBQXFCLEdBQ3BDLGNBQWMsQ0FBQyxjQUFjLEdBQzdCLGNBQWMsQ0FBQyx1QkFBdUIsR0FDdEMsY0FBYyxDQUFDLGdCQUFnQixHQUMvQixjQUFjLENBQUMsY0FBYyxDQUFDO0FBRWxDLE1BQU0sTUFBTSxzQkFBc0IsR0FBRyxNQUFNLGNBQWMsQ0FBQztBQUUxRCx3QkFBZ0Isc0JBQXNCLENBQUMsS0FBSyxFQUFFLGNBQWMsR0FBRyxNQUFNLENBRXBFIn0=
@@ -21,4 +21,4 @@ declare class TestSequencerClient_ extends SequencerClient {
21
21
  }
22
22
  export type TestSequencerClient = TestSequencerClient_;
23
23
  export {};
24
- //# sourceMappingURL=index.d.ts.map
24
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90ZXN0L2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLGdCQUFnQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDeEQsT0FBTyxLQUFLLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx3Q0FBd0MsQ0FBQztBQUNqRixPQUFPLEtBQUssRUFBRSxzQkFBc0IsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3RFLE9BQU8sS0FBSyxFQUFFLGVBQWUsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRS9ELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUNoRSxPQUFPLEtBQUssRUFBRSx5QkFBeUIsRUFBRSxNQUFNLDZDQUE2QyxDQUFDO0FBQzdGLE9BQU8sS0FBSyxFQUFFLGtCQUFrQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDOUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ3RELE9BQU8sS0FBSyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFFcEUsY0FBTSxjQUFlLFNBQVEsU0FBUztJQUNyQixzQkFBc0IsRUFBRSxzQkFBc0IsQ0FBQztJQUMvQyxTQUFTLEVBQUUsa0JBQWtCLENBQUM7SUFDOUIsU0FBUyxFQUFFLGtCQUFrQixDQUFDO0lBQzlCLGdCQUFnQixFQUFFLHlCQUF5QixDQUFDO0lBQzVDLGVBQWUsRUFBRSxlQUFlLENBQUM7Q0FDakQ7QUFFRCxNQUFNLE1BQU0sYUFBYSxHQUFHLGNBQWMsQ0FBQztBQUUzQyxjQUFNLG9CQUFxQixTQUFRLGVBQWU7SUFDakMsU0FBUyxFQUFFLGFBQWEsQ0FBQztJQUN6QixnQkFBZ0IsRUFBRSxnQkFBZ0IsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0NBQ3ZFO0FBRUQsTUFBTSxNQUFNLG1CQUFtQixHQUFHLG9CQUFvQixDQUFDIn0=
@@ -11,4 +11,4 @@ export declare class NullifierCache implements NullifierSource {
11
11
  nullifiersExist(nullifiers: Buffer[]): Promise<boolean[]>;
12
12
  addNullifiers(nullifiers: Buffer[]): void;
13
13
  }
14
- //# sourceMappingURL=nullifier_cache.d.ts.map
14
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibnVsbGlmaWVyX2NhY2hlLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHhfdmFsaWRhdG9yL251bGxpZmllcl9jYWNoZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxlQUFlLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDbEQsT0FBTyxLQUFLLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUdoRjs7O0dBR0c7QUFDSCxxQkFBYSxjQUFlLFlBQVcsZUFBZTtJQUd4QyxPQUFPLENBQUMsRUFBRTtJQUZ0QixVQUFVLEVBQUUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBRXhCLFlBQW9CLEVBQUUsRUFBRSx3QkFBd0IsRUFFL0M7SUFFWSxlQUFlLENBQUMsVUFBVSxFQUFFLE1BQU0sRUFBRSxHQUFHLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQU9yRTtJQUVNLGFBQWEsQ0FBQyxVQUFVLEVBQUUsTUFBTSxFQUFFLFFBSXhDO0NBQ0YifQ==
@@ -1 +1 @@
1
- {"version":3,"file":"nullifier_cache.d.ts","sourceRoot":"","sources":["../../src/tx_validator/nullifier_cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAGhF;;;GAGG;AACH,qBAAa,cAAe,YAAW,eAAe;IAGxC,OAAO,CAAC,EAAE;IAFtB,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;gBAEJ,EAAE,EAAE,wBAAwB;IAInC,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAS/D,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE;CAK1C"}
1
+ {"version":3,"file":"nullifier_cache.d.ts","sourceRoot":"","sources":["../../src/tx_validator/nullifier_cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAGhF;;;GAGG;AACH,qBAAa,cAAe,YAAW,eAAe;IAGxC,OAAO,CAAC,EAAE;IAFtB,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAExB,YAAoB,EAAE,EAAE,wBAAwB,EAE/C;IAEY,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAOrE;IAEM,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,QAIxC;CACF"}
@@ -1,17 +1,18 @@
1
+ import { BlockNumber } from '@aztec/foundation/branded-types';
1
2
  import type { ContractDataSource } from '@aztec/stdlib/contract';
2
3
  import type { GasFees } from '@aztec/stdlib/gas';
3
4
  import type { AllowedElement, ClientProtocolCircuitVerifier, MerkleTreeReadOperations, PublicProcessorValidator } from '@aztec/stdlib/interfaces/server';
4
5
  import { GlobalVariables, type Tx, type TxValidator } from '@aztec/stdlib/tx';
5
6
  import type { UInt64 } from '@aztec/stdlib/types';
6
- export declare function createValidatorForAcceptingTxs(db: MerkleTreeReadOperations, contractDataSource: ContractDataSource, verifier: ClientProtocolCircuitVerifier | undefined, { l1ChainId, rollupVersion, setupAllowList, gasFees, skipFeeEnforcement, timestamp, blockNumber, txsPermitted, }: {
7
+ export declare function createValidatorForAcceptingTxs(db: MerkleTreeReadOperations, contractDataSource: ContractDataSource, verifier: ClientProtocolCircuitVerifier | undefined, { l1ChainId, rollupVersion, setupAllowList, gasFees, skipFeeEnforcement, timestamp, blockNumber, txsPermitted }: {
7
8
  l1ChainId: number;
8
9
  rollupVersion: number;
9
10
  setupAllowList: AllowedElement[];
10
11
  gasFees: GasFees;
11
12
  skipFeeEnforcement?: boolean;
12
13
  timestamp: UInt64;
13
- blockNumber: number;
14
+ blockNumber: BlockNumber;
14
15
  txsPermitted: boolean;
15
16
  }): TxValidator<Tx>;
16
17
  export declare function createValidatorForBlockBuilding(db: MerkleTreeReadOperations, contractDataSource: ContractDataSource, globalVariables: GlobalVariables, setupAllowList: AllowedElement[]): PublicProcessorValidator;
17
- //# sourceMappingURL=tx_validator_factory.d.ts.map
18
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHhfdmFsaWRhdG9yX2ZhY3RvcnkuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90eF92YWxpZGF0b3IvdHhfdmFsaWRhdG9yX2ZhY3RvcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBaUI5RCxPQUFPLEtBQUssRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ2pFLE9BQU8sS0FBSyxFQUFFLE9BQU8sRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ2pELE9BQU8sS0FBSyxFQUNWLGNBQWMsRUFDZCw2QkFBNkIsRUFDN0Isd0JBQXdCLEVBQ3hCLHdCQUF3QixFQUN6QixNQUFNLGlDQUFpQyxDQUFDO0FBRXpDLE9BQU8sRUFBRSxlQUFlLEVBQUUsS0FBSyxFQUFFLEVBQUUsS0FBSyxXQUFXLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUM5RSxPQUFPLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUlsRCx3QkFBZ0IsOEJBQThCLENBQzVDLEVBQUUsRUFBRSx3QkFBd0IsRUFDNUIsa0JBQWtCLEVBQUUsa0JBQWtCLEVBQ3RDLFFBQVEsRUFBRSw2QkFBNkIsR0FBRyxTQUFTLEVBQ25ELEVBQ0UsU0FBUyxFQUNULGFBQWEsRUFDYixjQUFjLEVBQ2QsT0FBTyxFQUNQLGtCQUFrQixFQUNsQixTQUFTLEVBQ1QsV0FBVyxFQUNYLFlBQVksRUFDYixFQUFFO0lBQ0QsU0FBUyxFQUFFLE1BQU0sQ0FBQztJQUNsQixhQUFhLEVBQUUsTUFBTSxDQUFDO0lBQ3RCLGNBQWMsRUFBRSxjQUFjLEVBQUUsQ0FBQztJQUNqQyxPQUFPLEVBQUUsT0FBTyxDQUFDO0lBQ2pCLGtCQUFrQixDQUFDLEVBQUUsT0FBTyxDQUFDO0lBQzdCLFNBQVMsRUFBRSxNQUFNLENBQUM7SUFDbEIsV0FBVyxFQUFFLFdBQVcsQ0FBQztJQUN6QixZQUFZLEVBQUUsT0FBTyxDQUFDO0NBQ3ZCLEdBQ0EsV0FBVyxDQUFDLEVBQUUsQ0FBQyxDQTRCakI7QUFFRCx3QkFBZ0IsK0JBQStCLENBQzdDLEVBQUUsRUFBRSx3QkFBd0IsRUFDNUIsa0JBQWtCLEVBQUUsa0JBQWtCLEVBQ3RDLGVBQWUsRUFBRSxlQUFlLEVBQ2hDLGNBQWMsRUFBRSxjQUFjLEVBQUUsR0FDL0Isd0JBQXdCLENBZ0IxQiJ9
@@ -1 +1 @@
1
- {"version":3,"file":"tx_validator_factory.d.ts","sourceRoot":"","sources":["../../src/tx_validator/tx_validator_factory.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EACV,cAAc,EACd,6BAA6B,EAC7B,wBAAwB,EACxB,wBAAwB,EACzB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,EAAE,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC9E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAIlD,wBAAgB,8BAA8B,CAC5C,EAAE,EAAE,wBAAwB,EAC5B,kBAAkB,EAAE,kBAAkB,EACtC,QAAQ,EAAE,6BAA6B,GAAG,SAAS,EACnD,EACE,SAAS,EACT,aAAa,EACb,cAAc,EACd,OAAO,EACP,kBAAkB,EAClB,SAAS,EACT,WAAW,EACX,YAAY,GACb,EAAE;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,cAAc,EAAE,CAAC;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;CACvB,GACA,WAAW,CAAC,EAAE,CAAC,CA4BjB;AAED,wBAAgB,+BAA+B,CAC7C,EAAE,EAAE,wBAAwB,EAC5B,kBAAkB,EAAE,kBAAkB,EACtC,eAAe,EAAE,eAAe,EAChC,cAAc,EAAE,cAAc,EAAE,GAC/B,wBAAwB,CAgB1B"}
1
+ {"version":3,"file":"tx_validator_factory.d.ts","sourceRoot":"","sources":["../../src/tx_validator/tx_validator_factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAiB9D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EACV,cAAc,EACd,6BAA6B,EAC7B,wBAAwB,EACxB,wBAAwB,EACzB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,EAAE,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC9E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAIlD,wBAAgB,8BAA8B,CAC5C,EAAE,EAAE,wBAAwB,EAC5B,kBAAkB,EAAE,kBAAkB,EACtC,QAAQ,EAAE,6BAA6B,GAAG,SAAS,EACnD,EACE,SAAS,EACT,aAAa,EACb,cAAc,EACd,OAAO,EACP,kBAAkB,EAClB,SAAS,EACT,WAAW,EACX,YAAY,EACb,EAAE;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,cAAc,EAAE,CAAC;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,WAAW,CAAC;IACzB,YAAY,EAAE,OAAO,CAAC;CACvB,GACA,WAAW,CAAC,EAAE,CAAC,CA4BjB;AAED,wBAAgB,+BAA+B,CAC7C,EAAE,EAAE,wBAAwB,EAC5B,kBAAkB,EAAE,kBAAkB,EACtC,eAAe,EAAE,eAAe,EAChC,cAAc,EAAE,cAAc,EAAE,GAC/B,wBAAwB,CAgB1B"}