@aztec/sequencer-client 0.0.1-commit.9ef841308 → 0.0.1-commit.a89ec08

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 +3 -2
  2. package/dest/client/sequencer-client.d.ts.map +1 -1
  3. package/dest/client/sequencer-client.js +7 -8
  4. package/dest/config.d.ts +3 -3
  5. package/dest/config.d.ts.map +1 -1
  6. package/dest/config.js +1 -2
  7. package/dest/publisher/config.d.ts +1 -17
  8. package/dest/publisher/config.d.ts.map +1 -1
  9. package/dest/publisher/config.js +3 -23
  10. package/dest/publisher/index.d.ts +1 -2
  11. package/dest/publisher/index.d.ts.map +1 -1
  12. package/dest/publisher/sequencer-publisher-factory.d.ts +3 -3
  13. package/dest/publisher/sequencer-publisher-factory.d.ts.map +1 -1
  14. package/dest/publisher/sequencer-publisher-factory.js +2 -16
  15. package/dest/publisher/sequencer-publisher.d.ts +2 -12
  16. package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
  17. package/dest/publisher/sequencer-publisher.js +11 -260
  18. package/dest/sequencer/checkpoint_proposal_job.d.ts +4 -10
  19. package/dest/sequencer/checkpoint_proposal_job.d.ts.map +1 -1
  20. package/dest/sequencer/checkpoint_proposal_job.js +75 -117
  21. package/dest/sequencer/events.d.ts +1 -2
  22. package/dest/sequencer/events.d.ts.map +1 -1
  23. package/dest/sequencer/metrics.d.ts +1 -5
  24. package/dest/sequencer/metrics.d.ts.map +1 -1
  25. package/dest/sequencer/metrics.js +0 -11
  26. package/dest/sequencer/sequencer.d.ts +5 -4
  27. package/dest/sequencer/sequencer.d.ts.map +1 -1
  28. package/dest/sequencer/sequencer.js +49 -58
  29. package/dest/test/mock_checkpoint_builder.d.ts +1 -1
  30. package/dest/test/mock_checkpoint_builder.d.ts.map +1 -1
  31. package/dest/test/mock_checkpoint_builder.js +2 -0
  32. package/package.json +28 -27
  33. package/src/client/sequencer-client.ts +12 -8
  34. package/src/config.ts +0 -4
  35. package/src/publisher/config.ts +0 -41
  36. package/src/publisher/index.ts +0 -3
  37. package/src/publisher/sequencer-publisher-factory.ts +3 -18
  38. package/src/publisher/sequencer-publisher.ts +16 -237
  39. package/src/sequencer/checkpoint_proposal_job.ts +66 -139
  40. package/src/sequencer/events.ts +1 -1
  41. package/src/sequencer/metrics.ts +0 -14
  42. package/src/sequencer/sequencer.ts +57 -83
  43. package/src/test/mock_checkpoint_builder.ts +2 -0
  44. package/dest/publisher/l1_tx_failed_store/factory.d.ts +0 -11
  45. package/dest/publisher/l1_tx_failed_store/factory.d.ts.map +0 -1
  46. package/dest/publisher/l1_tx_failed_store/factory.js +0 -22
  47. package/dest/publisher/l1_tx_failed_store/failed_tx_store.d.ts +0 -59
  48. package/dest/publisher/l1_tx_failed_store/failed_tx_store.d.ts.map +0 -1
  49. package/dest/publisher/l1_tx_failed_store/failed_tx_store.js +0 -1
  50. package/dest/publisher/l1_tx_failed_store/file_store_failed_tx_store.d.ts +0 -15
  51. package/dest/publisher/l1_tx_failed_store/file_store_failed_tx_store.d.ts.map +0 -1
  52. package/dest/publisher/l1_tx_failed_store/file_store_failed_tx_store.js +0 -34
  53. package/dest/publisher/l1_tx_failed_store/index.d.ts +0 -4
  54. package/dest/publisher/l1_tx_failed_store/index.d.ts.map +0 -1
  55. package/dest/publisher/l1_tx_failed_store/index.js +0 -2
  56. package/src/publisher/l1_tx_failed_store/factory.ts +0 -32
  57. package/src/publisher/l1_tx_failed_store/failed_tx_store.ts +0 -55
  58. package/src/publisher/l1_tx_failed_store/file_store_failed_tx_store.ts +0 -46
  59. package/src/publisher/l1_tx_failed_store/index.ts +0 -3
@@ -4,8 +4,6 @@ import { type L1TxUtilsConfig, l1TxUtilsConfigMappings } from '@aztec/ethereum/l
4
4
  import { type ConfigMappingsType, SecretValue, booleanConfigHelper } from '@aztec/foundation/config';
5
5
  import { EthAddress } from '@aztec/foundation/eth-address';
6
6
 
7
- import { parseEther } from 'viem';
8
-
9
7
  /** Configuration of the transaction publisher. */
10
8
  export type TxSenderConfig = L1ReaderConfig & {
11
9
  /** The private key to be used by the publisher. */
@@ -50,39 +48,13 @@ export type PublisherConfig = L1TxUtilsConfig &
50
48
  fishermanMode?: boolean;
51
49
  /** Address of the forwarder contract to wrap all L1 transactions through (for testing purposes only) */
52
50
  publisherForwarderAddress?: EthAddress;
53
- /** Store for failed L1 transaction inputs (test networks only). Format: gs://bucket/path */
54
- l1TxFailedStore?: string;
55
- /** Min ETH balance below which a publisher gets funded. Undefined = funding disabled. */
56
- publisherFundingThreshold?: bigint;
57
- /** Amount of ETH to send when funding a publisher. Undefined = funding disabled. */
58
- publisherFundingAmount?: bigint;
59
51
  };
60
52
 
61
- /** Shared config mappings for publisher funding, used by both sequencer and prover publisher configs. */
62
- const publisherFundingConfigMappings = {
63
- publisherFundingThreshold: {
64
- env: 'PUBLISHER_FUNDING_THRESHOLD' as const,
65
- description:
66
- 'Min ETH balance below which a publisher gets funded. Specified in ether (e.g. 0.1). Unset = funding disabled.',
67
- parseEnv: (val: string) => parseEther(val),
68
- },
69
- publisherFundingAmount: {
70
- env: 'PUBLISHER_FUNDING_AMOUNT' as const,
71
- description:
72
- 'Amount of ETH to send when funding a publisher. Specified in ether (e.g. 0.5). Unset = funding disabled.',
73
- parseEnv: (val: string) => parseEther(val),
74
- },
75
- };
76
-
77
53
  export type ProverPublisherConfig = L1TxUtilsConfig &
78
54
  BlobClientConfig & {
79
55
  fishermanMode?: boolean;
80
56
  proverPublisherAllowInvalidStates?: boolean;
81
57
  proverPublisherForwarderAddress?: EthAddress;
82
- /** Min ETH balance below which a publisher gets funded. Undefined = funding disabled. */
83
- publisherFundingThreshold?: bigint;
84
- /** Amount of ETH to send when funding a publisher. Undefined = funding disabled. */
85
- publisherFundingAmount?: bigint;
86
58
  };
87
59
 
88
60
  export type SequencerPublisherConfig = L1TxUtilsConfig &
@@ -90,12 +62,6 @@ export type SequencerPublisherConfig = L1TxUtilsConfig &
90
62
  fishermanMode?: boolean;
91
63
  sequencerPublisherAllowInvalidStates?: boolean;
92
64
  sequencerPublisherForwarderAddress?: EthAddress;
93
- /** Store for failed L1 transaction inputs (test networks only). Format: gs://bucket/path */
94
- l1TxFailedStore?: string;
95
- /** Min ETH balance below which a publisher gets funded. Undefined = funding disabled. */
96
- publisherFundingThreshold?: bigint;
97
- /** Amount of ETH to send when funding a publisher. Undefined = funding disabled. */
98
- publisherFundingAmount?: bigint;
99
65
  };
100
66
 
101
67
  export function getPublisherConfigFromProverConfig(config: ProverPublisherConfig): PublisherConfig {
@@ -111,7 +77,6 @@ export function getPublisherConfigFromSequencerConfig(config: SequencerPublisher
111
77
  ...config,
112
78
  publisherAllowInvalidStates: config.sequencerPublisherAllowInvalidStates,
113
79
  publisherForwarderAddress: config.sequencerPublisherForwarderAddress,
114
- l1TxFailedStore: config.l1TxFailedStore,
115
80
  };
116
81
  }
117
82
 
@@ -168,11 +133,6 @@ export const sequencerPublisherConfigMappings: ConfigMappingsType<SequencerPubli
168
133
  description: 'Address of the forwarder contract to wrap all L1 transactions through (for testing purposes only)',
169
134
  parseEnv: (val: string) => (val ? EthAddress.fromString(val) : undefined),
170
135
  },
171
- l1TxFailedStore: {
172
- env: 'L1_TX_FAILED_STORE',
173
- description: 'Store for failed L1 transaction inputs (test networks only). Format: gs://bucket/path',
174
- },
175
- ...publisherFundingConfigMappings,
176
136
  };
177
137
 
178
138
  export const proverPublisherConfigMappings: ConfigMappingsType<ProverPublisherConfig & L1TxUtilsConfig> = {
@@ -194,5 +154,4 @@ export const proverPublisherConfigMappings: ConfigMappingsType<ProverPublisherCo
194
154
  description: 'Address of the forwarder contract to wrap all L1 transactions through (for testing purposes only)',
195
155
  parseEnv: (val: string) => (val ? EthAddress.fromString(val) : undefined),
196
156
  },
197
- ...publisherFundingConfigMappings,
198
157
  };
@@ -3,6 +3,3 @@ export { SequencerPublisherFactory } from './sequencer-publisher-factory.js';
3
3
 
4
4
  // Used for tests
5
5
  export { SequencerPublisherMetrics } from './sequencer-publisher-metrics.js';
6
-
7
- // Failed L1 tx store (optional, for test networks)
8
- export { type FailedL1Tx, type FailedL1TxUri, type L1TxFailedStore } from './l1_tx_failed_store/index.js';
@@ -81,23 +81,8 @@ export class SequencerPublisherFactory {
81
81
  const rollup = this.deps.rollupContract;
82
82
  const slashingProposerContract = await rollup.getSlashingProposer();
83
83
 
84
- const getNextPublisher = async (excludeAddresses: EthAddress[]): Promise<L1TxUtils | undefined> => {
85
- const exclusionFilter: PublisherFilter<L1TxUtils> = (utils: L1TxUtils) => {
86
- if (excludeAddresses.some(addr => addr.equals(utils.getSenderAddress()))) {
87
- return false;
88
- }
89
- return filter(utils);
90
- };
91
- try {
92
- return await this.deps.publisherManager.getAvailablePublisher(exclusionFilter);
93
- } catch {
94
- return undefined;
95
- }
96
- };
97
-
98
84
  const publisher = new SequencerPublisher(this.sequencerConfig, {
99
85
  l1TxUtils: l1Publisher,
100
- getNextPublisher,
101
86
  telemetry: this.deps.telemetry,
102
87
  blobClient: this.deps.blobClient,
103
88
  rollupContract: this.deps.rollupContract,
@@ -117,8 +102,8 @@ export class SequencerPublisherFactory {
117
102
  };
118
103
  }
119
104
 
120
- /** Stops all publishers managed by this factory. Used during sequencer shutdown. */
121
- public async stopAll(): Promise<void> {
122
- await this.deps.publisherManager.stop();
105
+ /** Interrupts all publishers managed by this factory. Used during sequencer shutdown. */
106
+ public interruptAll(): void {
107
+ this.deps.publisherManager.interrupt();
123
108
  }
124
109
  }
@@ -31,7 +31,6 @@ import { CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types';
31
31
  import { trimmedBytesLength } from '@aztec/foundation/buffer';
32
32
  import { pick } from '@aztec/foundation/collection';
33
33
  import type { Fr } from '@aztec/foundation/curves/bn254';
34
- import { TimeoutError } from '@aztec/foundation/error';
35
34
  import { EthAddress } from '@aztec/foundation/eth-address';
36
35
  import { Signature, type ViemSignature } from '@aztec/foundation/eth-signature';
37
36
  import { type Logger, createLogger } from '@aztec/foundation/log';
@@ -48,19 +47,9 @@ import type { CheckpointHeader } from '@aztec/stdlib/rollup';
48
47
  import type { L1PublishCheckpointStats } from '@aztec/stdlib/stats';
49
48
  import { type TelemetryClient, type Tracer, getTelemetryClient, trackSpan } from '@aztec/telemetry-client';
50
49
 
51
- import {
52
- type Hex,
53
- type StateOverride,
54
- type TransactionReceipt,
55
- type TypedDataDefinition,
56
- encodeFunctionData,
57
- keccak256,
58
- multicall3Abi,
59
- toHex,
60
- } from 'viem';
50
+ import { type StateOverride, type TransactionReceipt, type TypedDataDefinition, encodeFunctionData, toHex } from 'viem';
61
51
 
62
52
  import type { SequencerPublisherConfig } from './config.js';
63
- import { type FailedL1Tx, type L1TxFailedStore, createL1TxFailedStore } from './l1_tx_failed_store/index.js';
64
53
  import { SequencerPublisherMetrics } from './sequencer-publisher-metrics.js';
65
54
 
66
55
  /** Arguments to the process method of the rollup contract */
@@ -122,7 +111,6 @@ export class SequencerPublisher {
122
111
  private interrupted = false;
123
112
  private metrics: SequencerPublisherMetrics;
124
113
  public epochCache: EpochCache;
125
- private failedTxStore?: Promise<L1TxFailedStore | undefined>;
126
114
 
127
115
  protected governanceLog = createLogger('sequencer:publisher:governance');
128
116
  protected slashingLog = createLogger('sequencer:publisher:slashing');
@@ -142,9 +130,6 @@ export class SequencerPublisher {
142
130
  /** Address to use for simulations in fisherman mode (actual proposer's address) */
143
131
  private proposerAddressForSimulation?: EthAddress;
144
132
 
145
- /** Optional callback to obtain a replacement publisher when the current one fails to send. */
146
- private getNextPublisher?: (excludeAddresses: EthAddress[]) => Promise<L1TxUtils | undefined>;
147
-
148
133
  /** L1 fee analyzer for fisherman mode */
149
134
  private l1FeeAnalyzer?: L1FeeAnalyzer;
150
135
 
@@ -168,7 +153,7 @@ export class SequencerPublisher {
168
153
  protected requests: RequestWithExpiry[] = [];
169
154
 
170
155
  constructor(
171
- private config: Pick<SequencerPublisherConfig, 'fishermanMode' | 'l1TxFailedStore'> &
156
+ private config: Pick<SequencerPublisherConfig, 'fishermanMode'> &
172
157
  Pick<L1ContractsConfig, 'ethereumSlotDuration' | 'aztecSlotDuration'> & { l1ChainId: number },
173
158
  deps: {
174
159
  telemetry?: TelemetryClient;
@@ -183,7 +168,6 @@ export class SequencerPublisher {
183
168
  metrics: SequencerPublisherMetrics;
184
169
  lastActions: Partial<Record<Action, SlotNumber>>;
185
170
  log?: Logger;
186
- getNextPublisher?: (excludeAddresses: EthAddress[]) => Promise<L1TxUtils | undefined>;
187
171
  },
188
172
  ) {
189
173
  this.log = deps.log ?? createLogger('sequencer:publisher');
@@ -199,7 +183,6 @@ export class SequencerPublisher {
199
183
  this.metrics = deps.metrics ?? new SequencerPublisherMetrics(telemetry, 'SequencerPublisher');
200
184
  this.tracer = telemetry.getTracer('SequencerPublisher');
201
185
  this.l1TxUtils = deps.l1TxUtils;
202
- this.getNextPublisher = deps.getNextPublisher;
203
186
 
204
187
  this.rollupContract = deps.rollupContract;
205
188
 
@@ -228,31 +211,6 @@ export class SequencerPublisher {
228
211
  this.rollupContract,
229
212
  createLogger('sequencer:publisher:price-oracle'),
230
213
  );
231
-
232
- // Initialize failed L1 tx store (optional, for test networks)
233
- this.failedTxStore = createL1TxFailedStore(config.l1TxFailedStore, this.log);
234
- }
235
-
236
- /**
237
- * Backs up a failed L1 transaction to the configured store for debugging.
238
- * Does nothing if no store is configured.
239
- */
240
- private backupFailedTx(failedTx: Omit<FailedL1Tx, 'timestamp'>): void {
241
- if (!this.failedTxStore) {
242
- return;
243
- }
244
-
245
- const tx: FailedL1Tx = {
246
- ...failedTx,
247
- timestamp: Date.now(),
248
- };
249
-
250
- // Fire and forget - don't block on backup
251
- void this.failedTxStore
252
- .then(store => store?.saveFailedTx(tx))
253
- .catch(err => {
254
- this.log.warn(`Failed to backup failed L1 tx to store`, err);
255
- });
256
214
  }
257
215
 
258
216
  public getRollupContract(): RollupContract {
@@ -291,7 +249,7 @@ export class SequencerPublisher {
291
249
  }
292
250
 
293
251
  public getCurrentL2Slot(): SlotNumber {
294
- return this.epochCache.getSlotNow();
252
+ return this.epochCache.getEpochAndSlotNow().slot;
295
253
  }
296
254
 
297
255
  /**
@@ -434,36 +392,19 @@ export class SequencerPublisher {
434
392
  validRequests.sort((a, b) => compareActions(a.action, b.action));
435
393
 
436
394
  try {
437
- // Capture context for failed tx backup before sending
438
- const l1BlockNumber = await this.l1TxUtils.getBlockNumber();
439
- const multicallData = encodeFunctionData({
440
- abi: multicall3Abi,
441
- functionName: 'aggregate3',
442
- args: [
443
- validRequests.map(r => ({
444
- target: r.request.to!,
445
- callData: r.request.data!,
446
- allowFailure: true,
447
- })),
448
- ],
449
- });
450
- const blobDataHex = blobConfig?.blobs?.map(b => toHex(b)) as Hex[] | undefined;
451
-
452
- const txContext = { multicallData, blobData: blobDataHex, l1BlockNumber };
453
-
454
395
  this.log.debug('Forwarding transactions', {
455
396
  validRequests: validRequests.map(request => request.action),
456
397
  txConfig,
457
398
  });
458
- const result = await this.forwardWithPublisherRotation(validRequests, txConfig, blobConfig);
459
- if (result === undefined) {
460
- return undefined;
461
- }
462
- const { successfulActions = [], failedActions = [] } = this.callbackBundledTransactions(
463
- validRequests,
464
- result,
465
- txContext,
399
+ const result = await Multicall3.forward(
400
+ validRequests.map(request => request.request),
401
+ this.l1TxUtils,
402
+ txConfig,
403
+ blobConfig,
404
+ this.rollupContract.address,
405
+ this.log,
466
406
  );
407
+ const { successfulActions = [], failedActions = [] } = this.callbackBundledTransactions(validRequests, result);
467
408
  return { result, expiredActions, sentActions: validActions, successfulActions, failedActions };
468
409
  } catch (err) {
469
410
  const viemError = formatViemError(err);
@@ -481,76 +422,13 @@ export class SequencerPublisher {
481
422
  }
482
423
  }
483
424
 
484
- /**
485
- * Forwards transactions via Multicall3, rotating to the next available publisher if a send
486
- * failure occurs (i.e. the tx never reached the chain).
487
- * On-chain reverts and simulation errors are returned as-is without rotation.
488
- */
489
- private async forwardWithPublisherRotation(
490
- validRequests: RequestWithExpiry[],
491
- txConfig: RequestWithExpiry['gasConfig'],
492
- blobConfig: L1BlobInputs | undefined,
493
- ) {
494
- const triedAddresses: EthAddress[] = [];
495
- let currentPublisher = this.l1TxUtils;
496
-
497
- while (true) {
498
- triedAddresses.push(currentPublisher.getSenderAddress());
499
- try {
500
- const result = await Multicall3.forward(
501
- validRequests.map(r => r.request),
502
- currentPublisher,
503
- txConfig,
504
- blobConfig,
505
- this.rollupContract.address,
506
- this.log,
507
- );
508
- this.l1TxUtils = currentPublisher;
509
- return result;
510
- } catch (err) {
511
- if (err instanceof TimeoutError) {
512
- throw err;
513
- }
514
- const viemError = formatViemError(err);
515
- if (!this.getNextPublisher) {
516
- this.log.error('Failed to publish bundled transactions', viemError);
517
- return undefined;
518
- }
519
- this.log.warn(
520
- `Publisher ${currentPublisher.getSenderAddress()} failed to send, rotating to next publisher`,
521
- viemError,
522
- );
523
- const nextPublisher = await this.getNextPublisher([...triedAddresses]);
524
- if (!nextPublisher) {
525
- this.log.error('All available publishers exhausted, failed to publish bundled transactions');
526
- return undefined;
527
- }
528
- currentPublisher = nextPublisher;
529
- }
530
- }
531
- }
532
-
533
425
  private callbackBundledTransactions(
534
426
  requests: RequestWithExpiry[],
535
- result: { receipt: TransactionReceipt; errorMsg?: string } | FormattedViemError | undefined,
536
- txContext: { multicallData: Hex; blobData?: Hex[]; l1BlockNumber: bigint },
427
+ result?: { receipt: TransactionReceipt } | FormattedViemError,
537
428
  ) {
538
429
  const actionsListStr = requests.map(r => r.action).join(', ');
539
430
  if (result instanceof FormattedViemError) {
540
431
  this.log.error(`Failed to publish bundled transactions (${actionsListStr})`, result);
541
- this.backupFailedTx({
542
- id: keccak256(txContext.multicallData),
543
- failureType: 'send-error',
544
- request: { to: MULTI_CALL_3_ADDRESS, data: txContext.multicallData },
545
- blobData: txContext.blobData,
546
- l1BlockNumber: txContext.l1BlockNumber.toString(),
547
- error: { message: result.message, name: result.name },
548
- context: {
549
- actions: requests.map(r => r.action),
550
- requests: requests.map(r => ({ action: r.action, to: r.request.to! as Hex, data: r.request.data! })),
551
- sender: this.getSenderAddress().toString(),
552
- },
553
- });
554
432
  return { failedActions: requests.map(r => r.action) };
555
433
  } else {
556
434
  this.log.verbose(`Published bundled transactions (${actionsListStr})`, {
@@ -572,30 +450,6 @@ export class SequencerPublisher {
572
450
  failedActions.push(request.action);
573
451
  }
574
452
  }
575
- // Single backup for the whole reverted tx
576
- if (failedActions.length > 0 && result?.receipt?.status === 'reverted') {
577
- this.backupFailedTx({
578
- id: result.receipt.transactionHash,
579
- failureType: 'revert',
580
- request: { to: MULTI_CALL_3_ADDRESS, data: txContext.multicallData },
581
- blobData: txContext.blobData,
582
- l1BlockNumber: result.receipt.blockNumber.toString(),
583
- receipt: {
584
- transactionHash: result.receipt.transactionHash,
585
- blockNumber: result.receipt.blockNumber.toString(),
586
- gasUsed: (result.receipt.gasUsed ?? 0n).toString(),
587
- status: 'reverted',
588
- },
589
- error: { message: result.errorMsg ?? 'Transaction reverted' },
590
- context: {
591
- actions: failedActions,
592
- requests: requests
593
- .filter(r => failedActions.includes(r.action))
594
- .map(r => ({ action: r.action, to: r.request.to! as Hex, data: r.request.data! })),
595
- sender: this.getSenderAddress().toString(),
596
- },
597
- });
598
- }
599
453
  return { successfulActions, failedActions };
600
454
  }
601
455
  }
@@ -613,7 +467,7 @@ export class SequencerPublisher {
613
467
  // TODO: #14291 - should loop through multiple keys to check if any of them can propose
614
468
  const ignoredErrors = ['SlotAlreadyInChain', 'InvalidProposer', 'InvalidArchive'];
615
469
 
616
- const pipelined = opts.pipelined ?? this.epochCache.isProposerPipeliningEnabled();
470
+ const pipelined = opts.pipelined ?? false;
617
471
  const slotOffset = pipelined ? this.aztecSlotDuration : 0n;
618
472
  const nextL1SlotTs = this.getNextL1SlotTimestamp() + slotOffset;
619
473
 
@@ -632,7 +486,6 @@ export class SequencerPublisher {
632
486
  return undefined;
633
487
  });
634
488
  }
635
-
636
489
  /**
637
490
  * @notice Will simulate `validateHeader` to make sure that the block header is valid
638
491
  * @dev This is a convenience function that can be used by the sequencer to validate a "partial" header.
@@ -712,8 +565,6 @@ export class SequencerPublisher {
712
565
  const request = this.buildInvalidateCheckpointRequest(validationResult);
713
566
  this.log.debug(`Simulating invalidate checkpoint ${checkpointNumber}`, { ...logData, request });
714
567
 
715
- const l1BlockNumber = await this.l1TxUtils.getBlockNumber();
716
-
717
568
  try {
718
569
  const { gasUsed } = await this.l1TxUtils.simulate(
719
570
  request,
@@ -765,18 +616,6 @@ export class SequencerPublisher {
765
616
 
766
617
  // Otherwise, throw. We cannot build the next checkpoint if we cannot invalidate the previous one.
767
618
  this.log.error(`Simulation for invalidate checkpoint ${checkpointNumber} failed`, viemError, logData);
768
- this.backupFailedTx({
769
- id: keccak256(request.data!),
770
- failureType: 'simulation',
771
- request: { to: request.to!, data: request.data!, value: request.value?.toString() },
772
- l1BlockNumber: l1BlockNumber.toString(),
773
- error: { message: viemError.message, name: viemError.name },
774
- context: {
775
- actions: [`invalidate-${reason}`],
776
- checkpointNumber,
777
- sender: this.getSenderAddress().toString(),
778
- },
779
- });
780
619
  throw new Error(`Failed to simulate invalidate checkpoint ${checkpointNumber}`, { cause: viemError });
781
620
  }
782
621
  }
@@ -921,7 +760,6 @@ export class SequencerPublisher {
921
760
  lastValidL2Slot: slotNumber,
922
761
  });
923
762
 
924
- const l1BlockNumber = await this.l1TxUtils.getBlockNumber();
925
763
  const timestamp = this.getSimulationTimestamp(slotNumber);
926
764
 
927
765
  try {
@@ -931,19 +769,6 @@ export class SequencerPublisher {
931
769
  const viemError = formatViemError(err);
932
770
  this.log.error(`Failed simulation for ${action} at slot ${slotNumber} (enqueuing the action anyway)`, viemError, {
933
771
  simulationTimestamp: timestamp,
934
- l1BlockNumber,
935
- });
936
- this.backupFailedTx({
937
- id: keccak256(request.data!),
938
- failureType: 'simulation',
939
- request: { to: request.to!, data: request.data!, value: request.value?.toString() },
940
- l1BlockNumber: l1BlockNumber.toString(),
941
- error: { message: viemError.message, name: viemError.name },
942
- context: {
943
- actions: [action],
944
- slot: slotNumber,
945
- sender: this.getSenderAddress().toString(),
946
- },
947
772
  });
948
773
  // Yes, we enqueue the request anyway, in case there was a bug with the simulation itself
949
774
  }
@@ -1229,8 +1054,6 @@ export class SequencerPublisher {
1229
1054
 
1230
1055
  this.log.debug(`Simulating ${action} for slot ${slotNumber}`, logData);
1231
1056
 
1232
- const l1BlockNumber = await this.l1TxUtils.getBlockNumber();
1233
-
1234
1057
  let gasUsed: bigint;
1235
1058
  const simulateAbi = mergeAbis([request.abi ?? [], ErrorsAbi]);
1236
1059
 
@@ -1241,19 +1064,6 @@ export class SequencerPublisher {
1241
1064
  const viemError = formatViemError(err, simulateAbi);
1242
1065
  this.log.error(`Simulation for ${action} at ${slotNumber} failed`, viemError, logData);
1243
1066
 
1244
- this.backupFailedTx({
1245
- id: keccak256(request.data!),
1246
- failureType: 'simulation',
1247
- request: { to: request.to!, data: request.data!, value: request.value?.toString() },
1248
- l1BlockNumber: l1BlockNumber.toString(),
1249
- error: { message: viemError.message, name: viemError.name },
1250
- context: {
1251
- actions: [action],
1252
- slot: slotNumber,
1253
- sender: this.getSenderAddress().toString(),
1254
- },
1255
- });
1256
-
1257
1067
  return false;
1258
1068
  }
1259
1069
 
@@ -1336,27 +1146,9 @@ export class SequencerPublisher {
1336
1146
  kzg,
1337
1147
  },
1338
1148
  )
1339
- .catch(async err => {
1340
- const viemError = formatViemError(err);
1341
- this.log.error(`Failed to validate blobs`, viemError.message, { metaMessages: viemError.metaMessages });
1342
- const validateBlobsData = encodeFunctionData({
1343
- abi: RollupAbi,
1344
- functionName: 'validateBlobs',
1345
- args: [blobInput],
1346
- });
1347
- const l1BlockNumber = await this.l1TxUtils.getBlockNumber();
1348
- this.backupFailedTx({
1349
- id: keccak256(validateBlobsData),
1350
- failureType: 'simulation',
1351
- request: { to: this.rollupContract.address as Hex, data: validateBlobsData },
1352
- blobData: encodedData.blobs.map(b => toHex(b.data)) as Hex[],
1353
- l1BlockNumber: l1BlockNumber.toString(),
1354
- error: { message: viemError.message, name: viemError.name },
1355
- context: {
1356
- actions: ['validate-blobs'],
1357
- sender: this.getSenderAddress().toString(),
1358
- },
1359
- });
1149
+ .catch(err => {
1150
+ const { message, metaMessages } = formatViemError(err);
1151
+ this.log.error(`Failed to validate blobs`, message, { metaMessages });
1360
1152
  throw new Error('Failed to validate blobs');
1361
1153
  });
1362
1154
  }
@@ -1433,7 +1225,6 @@ export class SequencerPublisher {
1433
1225
  });
1434
1226
  }
1435
1227
 
1436
- const l1BlockNumber = await this.l1TxUtils.getBlockNumber();
1437
1228
  const simTs = this.getSimulationTimestamp(SlotNumber.fromBigInt(args[0].header.slotNumber));
1438
1229
 
1439
1230
  const simulationResult = await this.l1TxUtils
@@ -1468,18 +1259,6 @@ export class SequencerPublisher {
1468
1259
  };
1469
1260
  }
1470
1261
  this.log.error(`Failed to simulate propose tx`, viemError, { simulationTimestamp: simTs });
1471
- this.backupFailedTx({
1472
- id: keccak256(rollupData),
1473
- failureType: 'simulation',
1474
- request: { to: this.rollupContract.address, data: rollupData },
1475
- l1BlockNumber: l1BlockNumber.toString(),
1476
- error: { message: viemError.message, name: viemError.name },
1477
- context: {
1478
- actions: ['propose'],
1479
- slot: Number(args[0].header.slotNumber),
1480
- sender: this.getSenderAddress().toString(),
1481
- },
1482
- });
1483
1262
  throw err;
1484
1263
  });
1485
1264