@aztec/sequencer-client 0.0.1-commit.ffe5b04ea → 0.0.1-commit.fff30aa
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.
- package/dest/client/sequencer-client.d.ts +5 -12
- package/dest/client/sequencer-client.d.ts.map +1 -1
- package/dest/client/sequencer-client.js +22 -72
- package/dest/config.d.ts +2 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +7 -1
- package/dest/global_variable_builder/global_builder.d.ts +13 -7
- package/dest/global_variable_builder/global_builder.d.ts.map +1 -1
- package/dest/global_variable_builder/global_builder.js +22 -21
- package/dest/global_variable_builder/index.d.ts +2 -2
- package/dest/global_variable_builder/index.d.ts.map +1 -1
- package/dest/publisher/config.d.ts +1 -5
- package/dest/publisher/config.d.ts.map +1 -1
- package/dest/publisher/config.js +1 -6
- package/dest/publisher/index.d.ts +1 -2
- package/dest/publisher/index.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher-factory.d.ts +1 -1
- package/dest/publisher/sequencer-publisher-factory.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher-factory.js +0 -14
- package/dest/publisher/sequencer-publisher.d.ts +15 -18
- package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher.js +70 -290
- package/dest/sequencer/checkpoint_proposal_job.d.ts +3 -1
- package/dest/sequencer/checkpoint_proposal_job.d.ts.map +1 -1
- package/dest/sequencer/checkpoint_proposal_job.js +66 -63
- package/dest/sequencer/checkpoint_voter.d.ts +1 -2
- package/dest/sequencer/checkpoint_voter.d.ts.map +1 -1
- package/dest/sequencer/checkpoint_voter.js +2 -5
- package/dest/sequencer/sequencer.d.ts +6 -3
- package/dest/sequencer/sequencer.d.ts.map +1 -1
- package/dest/sequencer/sequencer.js +17 -16
- package/dest/sequencer/types.d.ts +2 -5
- package/dest/sequencer/types.d.ts.map +1 -1
- package/dest/test/mock_checkpoint_builder.d.ts +4 -4
- package/dest/test/mock_checkpoint_builder.d.ts.map +1 -1
- package/dest/test/mock_checkpoint_builder.js +2 -0
- package/package.json +28 -28
- package/src/client/sequencer-client.ts +34 -94
- package/src/config.ts +8 -1
- package/src/global_variable_builder/global_builder.ts +22 -23
- package/src/global_variable_builder/index.ts +1 -1
- package/src/publisher/config.ts +0 -9
- package/src/publisher/index.ts +0 -3
- package/src/publisher/sequencer-publisher-factory.ts +0 -15
- package/src/publisher/sequencer-publisher.ts +71 -276
- package/src/sequencer/checkpoint_proposal_job.ts +93 -77
- package/src/sequencer/checkpoint_voter.ts +1 -12
- package/src/sequencer/sequencer.ts +20 -17
- package/src/sequencer/types.ts +2 -5
- package/src/test/mock_checkpoint_builder.ts +5 -3
- package/dest/publisher/l1_tx_failed_store/factory.d.ts +0 -11
- package/dest/publisher/l1_tx_failed_store/factory.d.ts.map +0 -1
- package/dest/publisher/l1_tx_failed_store/factory.js +0 -22
- package/dest/publisher/l1_tx_failed_store/failed_tx_store.d.ts +0 -59
- package/dest/publisher/l1_tx_failed_store/failed_tx_store.d.ts.map +0 -1
- package/dest/publisher/l1_tx_failed_store/failed_tx_store.js +0 -1
- package/dest/publisher/l1_tx_failed_store/file_store_failed_tx_store.d.ts +0 -15
- package/dest/publisher/l1_tx_failed_store/file_store_failed_tx_store.d.ts.map +0 -1
- package/dest/publisher/l1_tx_failed_store/file_store_failed_tx_store.js +0 -34
- package/dest/publisher/l1_tx_failed_store/index.d.ts +0 -4
- package/dest/publisher/l1_tx_failed_store/index.d.ts.map +0 -1
- package/dest/publisher/l1_tx_failed_store/index.js +0 -2
- package/src/publisher/l1_tx_failed_store/factory.ts +0 -32
- package/src/publisher/l1_tx_failed_store/failed_tx_store.ts +0 -55
- package/src/publisher/l1_tx_failed_store/file_store_failed_tx_store.ts +0 -46
- package/src/publisher/l1_tx_failed_store/index.ts +0 -3
|
@@ -34,13 +34,18 @@ import { type Checkpoint, validateCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
|
34
34
|
import { getSlotStartBuildTimestamp } from '@aztec/stdlib/epoch-helpers';
|
|
35
35
|
import { Gas } from '@aztec/stdlib/gas';
|
|
36
36
|
import {
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
type BlockBuilderOptions,
|
|
38
|
+
InsufficientValidTxsError,
|
|
39
39
|
type ResolvedSequencerConfig,
|
|
40
40
|
type WorldStateSynchronizer,
|
|
41
41
|
} from '@aztec/stdlib/interfaces/server';
|
|
42
42
|
import { type L1ToL2MessageSource, computeInHashFromL1ToL2Messages } from '@aztec/stdlib/messaging';
|
|
43
|
-
import type {
|
|
43
|
+
import type {
|
|
44
|
+
BlockProposal,
|
|
45
|
+
BlockProposalOptions,
|
|
46
|
+
CheckpointProposal,
|
|
47
|
+
CheckpointProposalOptions,
|
|
48
|
+
} from '@aztec/stdlib/p2p';
|
|
44
49
|
import { orderAttestations, trimAttestations } from '@aztec/stdlib/p2p';
|
|
45
50
|
import type { L2BlockBuiltStats } from '@aztec/stdlib/stats';
|
|
46
51
|
import { type FailedTx, Tx } from '@aztec/stdlib/tx';
|
|
@@ -265,7 +270,8 @@ export class CheckpointProposalJob implements Traceable {
|
|
|
265
270
|
this.setStateFn(SequencerState.ASSEMBLING_CHECKPOINT, this.slot);
|
|
266
271
|
const checkpoint = await checkpointBuilder.completeCheckpoint();
|
|
267
272
|
|
|
268
|
-
// Final validation
|
|
273
|
+
// Final validation: per-block limits are only checked if the operator set them explicitly.
|
|
274
|
+
// Otherwise, checkpoint-level budgets were already enforced by the redistribution logic.
|
|
269
275
|
try {
|
|
270
276
|
validateCheckpoint(checkpoint, {
|
|
271
277
|
rollupManaLimit: this.l1Constants.rollupManaLimit,
|
|
@@ -402,6 +408,7 @@ export class CheckpointProposalJob implements Traceable {
|
|
|
402
408
|
const blocksInCheckpoint: L2Block[] = [];
|
|
403
409
|
const txHashesAlreadyIncluded = new Set<string>();
|
|
404
410
|
const initialBlockNumber = BlockNumber(this.syncedToBlockNumber + 1);
|
|
411
|
+
const slot = this.slot;
|
|
405
412
|
|
|
406
413
|
// Last block in the checkpoint will usually be flagged as pending broadcast, so we send it along with the checkpoint proposal
|
|
407
414
|
let blockPendingBroadcast: { block: L2Block; txs: Tx[] } | undefined = undefined;
|
|
@@ -415,11 +422,7 @@ export class CheckpointProposalJob implements Traceable {
|
|
|
415
422
|
const timingInfo = this.timetable.canStartNextBlock(secondsIntoSlot);
|
|
416
423
|
|
|
417
424
|
if (!timingInfo.canStart) {
|
|
418
|
-
this.log.debug(`Not enough time left in slot to start another block`, {
|
|
419
|
-
slot: this.slot,
|
|
420
|
-
blocksBuilt,
|
|
421
|
-
secondsIntoSlot,
|
|
422
|
-
});
|
|
425
|
+
this.log.debug(`Not enough time left in slot to start another block`, { slot, blocksBuilt, secondsIntoSlot });
|
|
423
426
|
break;
|
|
424
427
|
}
|
|
425
428
|
|
|
@@ -451,53 +454,37 @@ export class CheckpointProposalJob implements Traceable {
|
|
|
451
454
|
} else if ('error' in buildResult) {
|
|
452
455
|
// If there was an error building the block, just exit the loop and give up the rest of the slot
|
|
453
456
|
if (!(buildResult.error instanceof SequencerInterruptedError)) {
|
|
454
|
-
this.log.warn(`Halting block building for slot ${
|
|
455
|
-
slot: this.slot,
|
|
456
|
-
blocksBuilt,
|
|
457
|
-
error: buildResult.error,
|
|
458
|
-
});
|
|
457
|
+
this.log.warn(`Halting block building for slot ${slot}`, { slot, blocksBuilt, error: buildResult.error });
|
|
459
458
|
}
|
|
460
459
|
break;
|
|
461
460
|
}
|
|
462
461
|
|
|
463
462
|
const { block, usedTxs } = buildResult;
|
|
464
463
|
blocksInCheckpoint.push(block);
|
|
465
|
-
|
|
466
|
-
// Sync the proposed block to the archiver to make it available
|
|
467
|
-
// Note that the checkpoint builder uses its own fork so it should not need to wait for this syncing
|
|
468
|
-
// Eventually we should refactor the checkpoint builder to not need a separate long-lived fork
|
|
469
|
-
// Fire and forget - don't block the critical path, but log errors
|
|
470
|
-
this.syncProposedBlockToArchiver(block).catch(err => {
|
|
471
|
-
this.log.error(`Failed to sync proposed block ${block.number} to archiver`, { blockNumber: block.number, err });
|
|
472
|
-
});
|
|
473
|
-
|
|
474
464
|
usedTxs.forEach(tx => txHashesAlreadyIncluded.add(tx.txHash.toString()));
|
|
475
465
|
|
|
476
|
-
// If this is the last block,
|
|
466
|
+
// If this is the last block, send the proposed block to the archiver,
|
|
467
|
+
// and exit the loop now so we can build the checkpoint and start collecting attestations.
|
|
477
468
|
if (timingInfo.isLastBlock) {
|
|
478
|
-
this.
|
|
479
|
-
|
|
480
|
-
blockNumber,
|
|
481
|
-
blocksBuilt,
|
|
482
|
-
});
|
|
469
|
+
await this.syncProposedBlockToArchiver(block);
|
|
470
|
+
this.log.verbose(`Completed final block ${blockNumber} for slot ${slot}`, { slot, blockNumber, blocksBuilt });
|
|
483
471
|
blockPendingBroadcast = { block, txs: usedTxs };
|
|
484
472
|
break;
|
|
485
473
|
}
|
|
486
474
|
|
|
487
|
-
//
|
|
488
|
-
//
|
|
489
|
-
if
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
}
|
|
475
|
+
// Broadcast the block proposal (unless we're in fisherman mode) unless the block is the last one,
|
|
476
|
+
// in which case we'll broadcast it along with the checkpoint at the end of the loop.
|
|
477
|
+
// Note that we only send the block to the archiver if we manage to create the proposal, so if there's
|
|
478
|
+
// a HA error we don't pollute our archiver with a block that won't make it to the chain.
|
|
479
|
+
const proposal = await this.createBlockProposal(block, inHash, usedTxs, blockProposalOptions);
|
|
480
|
+
|
|
481
|
+
// Sync the proposed block to the archiver to make it available, only after we've managed to sign the proposal.
|
|
482
|
+
// We wait for the sync to succeed, as this helps catch consistency errors, even if it means we lose some time for block-building.
|
|
483
|
+
// If this throws, we abort the entire checkpoint.
|
|
484
|
+
await this.syncProposedBlockToArchiver(block);
|
|
485
|
+
|
|
486
|
+
// Once we have a signed proposal and the archiver agreed with our proposed block, then we broadcast it.
|
|
487
|
+
proposal && (await this.p2pClient.broadcastProposal(proposal));
|
|
501
488
|
|
|
502
489
|
// Wait until the next block's start time
|
|
503
490
|
await this.waitUntilNextSubslot(timingInfo.deadline);
|
|
@@ -511,6 +498,28 @@ export class CheckpointProposalJob implements Traceable {
|
|
|
511
498
|
return { blocksInCheckpoint, blockPendingBroadcast };
|
|
512
499
|
}
|
|
513
500
|
|
|
501
|
+
/** Creates a block proposal for a given block via the validator client (unless in fisherman mode) */
|
|
502
|
+
private createBlockProposal(
|
|
503
|
+
block: L2Block,
|
|
504
|
+
inHash: Fr,
|
|
505
|
+
usedTxs: Tx[],
|
|
506
|
+
blockProposalOptions: BlockProposalOptions,
|
|
507
|
+
): Promise<BlockProposal | undefined> {
|
|
508
|
+
if (this.config.fishermanMode) {
|
|
509
|
+
this.log.info(`Skipping block proposal for block ${block.number} in fisherman mode`);
|
|
510
|
+
return Promise.resolve(undefined);
|
|
511
|
+
}
|
|
512
|
+
return this.validatorClient.createBlockProposal(
|
|
513
|
+
block.header,
|
|
514
|
+
block.indexWithinCheckpoint,
|
|
515
|
+
inHash,
|
|
516
|
+
block.archive.root,
|
|
517
|
+
usedTxs,
|
|
518
|
+
this.proposer,
|
|
519
|
+
blockProposalOptions,
|
|
520
|
+
);
|
|
521
|
+
}
|
|
522
|
+
|
|
514
523
|
/** Sleeps until it is time to produce the next block in the slot */
|
|
515
524
|
@trackSpan('CheckpointProposalJob.waitUntilNextSubslot')
|
|
516
525
|
private async waitUntilNextSubslot(nextSubslotStart: number) {
|
|
@@ -542,8 +551,7 @@ export class CheckpointProposalJob implements Traceable {
|
|
|
542
551
|
|
|
543
552
|
try {
|
|
544
553
|
// Wait until we have enough txs to build the block
|
|
545
|
-
const minTxs = this.
|
|
546
|
-
const { availableTxs, canStartBuilding } = await this.waitForMinTxs(opts);
|
|
554
|
+
const { availableTxs, canStartBuilding, minTxs } = await this.waitForMinTxs(opts);
|
|
547
555
|
if (!canStartBuilding) {
|
|
548
556
|
this.log.warn(
|
|
549
557
|
`Not enough txs to build block ${blockNumber} at index ${indexWithinCheckpoint} in slot ${this.slot} (got ${availableTxs} txs but needs ${minTxs})`,
|
|
@@ -567,9 +575,11 @@ export class CheckpointProposalJob implements Traceable {
|
|
|
567
575
|
);
|
|
568
576
|
this.setStateFn(SequencerState.CREATING_BLOCK, this.slot);
|
|
569
577
|
|
|
570
|
-
// Per-block limits
|
|
578
|
+
// Per-block limits are operator overrides (from SEQ_MAX_L2_BLOCK_GAS etc.) further capped
|
|
571
579
|
// by remaining checkpoint-level budgets inside CheckpointBuilder before each block is built.
|
|
572
|
-
|
|
580
|
+
// minValidTxs is passed into the builder so it can reject the block *before* updating state.
|
|
581
|
+
const minValidTxs = forceCreate ? 0 : (this.config.minValidTxsPerBlock ?? minTxs);
|
|
582
|
+
const blockBuilderOptions: BlockBuilderOptions = {
|
|
573
583
|
maxTransactions: this.config.maxTxsPerBlock,
|
|
574
584
|
maxBlockGas:
|
|
575
585
|
this.config.maxL2BlockGas !== undefined || this.config.maxDABlockGas !== undefined
|
|
@@ -577,9 +587,14 @@ export class CheckpointProposalJob implements Traceable {
|
|
|
577
587
|
: undefined,
|
|
578
588
|
deadline: buildDeadline,
|
|
579
589
|
isBuildingProposal: true,
|
|
590
|
+
minValidTxs,
|
|
591
|
+
maxBlocksPerCheckpoint: this.timetable.maxNumberOfBlocks,
|
|
592
|
+
perBlockAllocationMultiplier: this.config.perBlockAllocationMultiplier,
|
|
580
593
|
};
|
|
581
594
|
|
|
582
|
-
// Actually build the block by executing txs
|
|
595
|
+
// Actually build the block by executing txs. The builder throws InsufficientValidTxsError
|
|
596
|
+
// if the number of successfully processed txs is below minValidTxs, ensuring state is not
|
|
597
|
+
// updated for blocks that will be discarded.
|
|
583
598
|
const buildResult = await this.buildSingleBlockWithCheckpointBuilder(
|
|
584
599
|
checkpointBuilder,
|
|
585
600
|
pendingTxs,
|
|
@@ -591,14 +606,16 @@ export class CheckpointProposalJob implements Traceable {
|
|
|
591
606
|
// If any txs failed during execution, drop them from the mempool so we don't pick them up again
|
|
592
607
|
await this.dropFailedTxsFromP2P(buildResult.failedTxs);
|
|
593
608
|
|
|
594
|
-
|
|
595
|
-
// too long, then we may not get to minTxsPerBlock after executing public functions.
|
|
596
|
-
const minValidTxs = this.config.minValidTxsPerBlock ?? minTxs;
|
|
597
|
-
const numTxs = buildResult.status === 'no-valid-txs' ? 0 : buildResult.numTxs;
|
|
598
|
-
if (buildResult.status === 'no-valid-txs' || (!forceCreate && numTxs < minValidTxs)) {
|
|
609
|
+
if (buildResult.status === 'insufficient-valid-txs') {
|
|
599
610
|
this.log.warn(
|
|
600
611
|
`Block ${blockNumber} at index ${indexWithinCheckpoint} on slot ${this.slot} has too few valid txs to be proposed`,
|
|
601
|
-
{
|
|
612
|
+
{
|
|
613
|
+
slot: this.slot,
|
|
614
|
+
blockNumber,
|
|
615
|
+
numTxs: buildResult.processedCount,
|
|
616
|
+
indexWithinCheckpoint,
|
|
617
|
+
minValidTxs,
|
|
618
|
+
},
|
|
602
619
|
);
|
|
603
620
|
this.eventEmitter.emit('block-build-failed', { reason: `Insufficient valid txs`, slot: this.slot });
|
|
604
621
|
this.metrics.recordBlockProposalFailed('insufficient_valid_txs');
|
|
@@ -606,7 +623,7 @@ export class CheckpointProposalJob implements Traceable {
|
|
|
606
623
|
}
|
|
607
624
|
|
|
608
625
|
// Block creation succeeded, emit stats and metrics
|
|
609
|
-
const { block, publicProcessorDuration, usedTxs, blockBuildDuration } = buildResult;
|
|
626
|
+
const { block, publicProcessorDuration, usedTxs, blockBuildDuration, numTxs } = buildResult;
|
|
610
627
|
|
|
611
628
|
const blockStats = {
|
|
612
629
|
eventName: 'l2-block-built',
|
|
@@ -637,13 +654,13 @@ export class CheckpointProposalJob implements Traceable {
|
|
|
637
654
|
}
|
|
638
655
|
}
|
|
639
656
|
|
|
640
|
-
/** Uses the checkpoint builder to build a block, catching
|
|
657
|
+
/** Uses the checkpoint builder to build a block, catching InsufficientValidTxsError. */
|
|
641
658
|
private async buildSingleBlockWithCheckpointBuilder(
|
|
642
659
|
checkpointBuilder: CheckpointBuilder,
|
|
643
660
|
pendingTxs: AsyncIterable<Tx>,
|
|
644
661
|
blockNumber: BlockNumber,
|
|
645
662
|
blockTimestamp: bigint,
|
|
646
|
-
blockBuilderOptions:
|
|
663
|
+
blockBuilderOptions: BlockBuilderOptions,
|
|
647
664
|
) {
|
|
648
665
|
try {
|
|
649
666
|
const workTimer = new Timer();
|
|
@@ -651,8 +668,12 @@ export class CheckpointProposalJob implements Traceable {
|
|
|
651
668
|
const blockBuildDuration = workTimer.ms();
|
|
652
669
|
return { ...result, blockBuildDuration, status: 'success' as const };
|
|
653
670
|
} catch (err: unknown) {
|
|
654
|
-
if (isErrorClass(err,
|
|
655
|
-
return {
|
|
671
|
+
if (isErrorClass(err, InsufficientValidTxsError)) {
|
|
672
|
+
return {
|
|
673
|
+
failedTxs: err.failedTxs,
|
|
674
|
+
processedCount: err.processedCount,
|
|
675
|
+
status: 'insufficient-valid-txs' as const,
|
|
676
|
+
};
|
|
656
677
|
}
|
|
657
678
|
throw err;
|
|
658
679
|
}
|
|
@@ -665,7 +686,7 @@ export class CheckpointProposalJob implements Traceable {
|
|
|
665
686
|
blockNumber: BlockNumber;
|
|
666
687
|
indexWithinCheckpoint: IndexWithinCheckpoint;
|
|
667
688
|
buildDeadline: Date | undefined;
|
|
668
|
-
}): Promise<{ canStartBuilding: boolean; availableTxs: number }> {
|
|
689
|
+
}): Promise<{ canStartBuilding: boolean; availableTxs: number; minTxs: number }> {
|
|
669
690
|
const { indexWithinCheckpoint, blockNumber, buildDeadline, forceCreate } = opts;
|
|
670
691
|
|
|
671
692
|
// We only allow a block with 0 txs in the first block of the checkpoint
|
|
@@ -682,7 +703,7 @@ export class CheckpointProposalJob implements Traceable {
|
|
|
682
703
|
// If we're past deadline, or we have no deadline, give up
|
|
683
704
|
const now = this.dateProvider.nowAsDate();
|
|
684
705
|
if (startBuildingDeadline === undefined || now >= startBuildingDeadline) {
|
|
685
|
-
return { canStartBuilding: false, availableTxs
|
|
706
|
+
return { canStartBuilding: false, availableTxs, minTxs };
|
|
686
707
|
}
|
|
687
708
|
|
|
688
709
|
// Wait a bit before checking again
|
|
@@ -695,7 +716,7 @@ export class CheckpointProposalJob implements Traceable {
|
|
|
695
716
|
availableTxs = await this.p2pClient.getPendingTxCount();
|
|
696
717
|
}
|
|
697
718
|
|
|
698
|
-
return { canStartBuilding: true, availableTxs };
|
|
719
|
+
return { canStartBuilding: true, availableTxs, minTxs };
|
|
699
720
|
}
|
|
700
721
|
|
|
701
722
|
/**
|
|
@@ -833,20 +854,11 @@ export class CheckpointProposalJob implements Traceable {
|
|
|
833
854
|
this.log.warn(`Shuffling attestation ordering in checkpoint for slot ${slotNumber} (proposer #${proposerIndex})`);
|
|
834
855
|
|
|
835
856
|
const shuffled = [...attestations];
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
for (let k = 0; k < shuffled.length; k++) {
|
|
842
|
-
if (!shuffled[k].signature.isEmpty() && k !== proposerIndex) {
|
|
843
|
-
swappable.push(k);
|
|
844
|
-
}
|
|
845
|
-
}
|
|
846
|
-
if (swappable.length >= 2) {
|
|
847
|
-
const [i, j] = [swappable[0], swappable[1]];
|
|
848
|
-
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
|
|
849
|
-
}
|
|
857
|
+
const [i, j] = [(proposerIndex + 1) % shuffled.length, (proposerIndex + 2) % shuffled.length];
|
|
858
|
+
const valueI = shuffled[i];
|
|
859
|
+
const valueJ = shuffled[j];
|
|
860
|
+
shuffled[i] = valueJ;
|
|
861
|
+
shuffled[j] = valueI;
|
|
850
862
|
|
|
851
863
|
const signers = new CommitteeAttestationsAndSigners(attestations).getSigners();
|
|
852
864
|
return new MaliciousCommitteeAttestationsAndSigners(shuffled, signers);
|
|
@@ -869,9 +881,13 @@ export class CheckpointProposalJob implements Traceable {
|
|
|
869
881
|
* Adds the proposed block to the archiver so it's available via P2P.
|
|
870
882
|
* Gossip doesn't echo messages back to the sender, so the proposer's archiver/world-state
|
|
871
883
|
* would never receive its own block without this explicit sync.
|
|
884
|
+
*
|
|
885
|
+
* In fisherman mode we skip this push: the fisherman builds blocks locally for validation
|
|
886
|
+
* and fee analysis only, and pushing them to the archiver causes spurious reorg cascades
|
|
887
|
+
* whenever the real proposer's block arrives from L1.
|
|
872
888
|
*/
|
|
873
889
|
private async syncProposedBlockToArchiver(block: L2Block): Promise<void> {
|
|
874
|
-
if (this.config.skipPushProposedBlocksToArchiver !== false) {
|
|
890
|
+
if (this.config.skipPushProposedBlocksToArchiver !== false || this.config.fishermanMode) {
|
|
875
891
|
this.log.warn(`Skipping push of proposed block ${block.number} to archiver`, {
|
|
876
892
|
blockNumber: block.number,
|
|
877
893
|
slot: block.header.globalVariables.slotNumber,
|
|
@@ -2,7 +2,6 @@ import type { SlotNumber } from '@aztec/foundation/branded-types';
|
|
|
2
2
|
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
3
3
|
import type { Logger } from '@aztec/foundation/log';
|
|
4
4
|
import type { SlasherClientInterface } from '@aztec/slasher';
|
|
5
|
-
import { getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
|
|
6
5
|
import type { ResolvedSequencerConfig } from '@aztec/stdlib/interfaces/server';
|
|
7
6
|
import type { ValidatorClient } from '@aztec/validator-client';
|
|
8
7
|
import { DutyAlreadySignedError } from '@aztec/validator-ha-signer/errors';
|
|
@@ -18,7 +17,6 @@ import type { SequencerRollupConstants } from './types.js';
|
|
|
18
17
|
* Handles governance and slashing voting for a given slot.
|
|
19
18
|
*/
|
|
20
19
|
export class CheckpointVoter {
|
|
21
|
-
private slotTimestamp: bigint;
|
|
22
20
|
private governanceSigner: (msg: TypedDataDefinition) => Promise<`0x${string}`>;
|
|
23
21
|
private slashingSigner: (msg: TypedDataDefinition) => Promise<`0x${string}`>;
|
|
24
22
|
|
|
@@ -33,8 +31,6 @@ export class CheckpointVoter {
|
|
|
33
31
|
private readonly metrics: SequencerMetrics,
|
|
34
32
|
private readonly log: Logger,
|
|
35
33
|
) {
|
|
36
|
-
this.slotTimestamp = getTimestampForSlot(this.slot, this.l1Constants);
|
|
37
|
-
|
|
38
34
|
// Create separate signers with appropriate duty contexts for governance and slashing votes
|
|
39
35
|
// These use HA protection to ensure only one node signs per slot/duty
|
|
40
36
|
const governanceContext: SigningContext = { slot: this.slot, dutyType: DutyType.GOVERNANCE_VOTE };
|
|
@@ -77,7 +73,6 @@ export class CheckpointVoter {
|
|
|
77
73
|
return await this.publisher.enqueueGovernanceCastSignal(
|
|
78
74
|
governanceProposerPayload,
|
|
79
75
|
this.slot,
|
|
80
|
-
this.slotTimestamp,
|
|
81
76
|
this.attestorAddress,
|
|
82
77
|
this.governanceSigner,
|
|
83
78
|
);
|
|
@@ -108,13 +103,7 @@ export class CheckpointVoter {
|
|
|
108
103
|
|
|
109
104
|
this.metrics.recordSlashingAttempt(actions.length);
|
|
110
105
|
|
|
111
|
-
return await this.publisher.enqueueSlashingActions(
|
|
112
|
-
actions,
|
|
113
|
-
this.slot,
|
|
114
|
-
this.slotTimestamp,
|
|
115
|
-
this.attestorAddress,
|
|
116
|
-
this.slashingSigner,
|
|
117
|
-
);
|
|
106
|
+
return await this.publisher.enqueueSlashingActions(actions, this.slot, this.attestorAddress, this.slashingSigner);
|
|
118
107
|
} catch (err) {
|
|
119
108
|
if (err instanceof DutyAlreadySignedError) {
|
|
120
109
|
this.log.info(`Slashing vote already signed by another node`, {
|
|
@@ -14,7 +14,7 @@ import type { P2P } from '@aztec/p2p';
|
|
|
14
14
|
import type { SlasherClientInterface } from '@aztec/slasher';
|
|
15
15
|
import type { BlockData, L2BlockSink, L2BlockSource, ValidateCheckpointResult } from '@aztec/stdlib/block';
|
|
16
16
|
import type { Checkpoint } from '@aztec/stdlib/checkpoint';
|
|
17
|
-
import {
|
|
17
|
+
import { getSlotStartBuildTimestamp } from '@aztec/stdlib/epoch-helpers';
|
|
18
18
|
import {
|
|
19
19
|
type ResolvedSequencerConfig,
|
|
20
20
|
type SequencerConfig,
|
|
@@ -143,6 +143,11 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
143
143
|
this.log.info('Started sequencer');
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
+
/** Triggers an immediate run of the sequencer, bypassing the polling interval. */
|
|
147
|
+
public trigger() {
|
|
148
|
+
return this.runningPromise?.trigger();
|
|
149
|
+
}
|
|
150
|
+
|
|
146
151
|
/** Stops the sequencer from building blocks and moves to STOPPED state. */
|
|
147
152
|
public async stop(): Promise<void> {
|
|
148
153
|
this.log.info(`Stopping sequencer`);
|
|
@@ -281,8 +286,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
281
286
|
|
|
282
287
|
const logCtx = {
|
|
283
288
|
now,
|
|
284
|
-
|
|
285
|
-
syncedToL2Slot: getSlotAtTimestamp(syncedTo.l1Timestamp, this.l1Constants),
|
|
289
|
+
syncedToL2Slot: syncedTo.syncedL2Slot,
|
|
286
290
|
slot,
|
|
287
291
|
slotTs: ts,
|
|
288
292
|
checkpointNumber,
|
|
@@ -328,7 +332,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
328
332
|
|
|
329
333
|
// Check with the rollup contract if we can indeed propose at the next L2 slot. This check should not fail
|
|
330
334
|
// if all the previous checks are good, but we do it just in case.
|
|
331
|
-
const canProposeCheck = await publisher.
|
|
335
|
+
const canProposeCheck = await publisher.canProposeAt(
|
|
332
336
|
syncedTo.archive,
|
|
333
337
|
proposer ?? EthAddress.ZERO,
|
|
334
338
|
invalidateCheckpoint,
|
|
@@ -475,16 +479,15 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
475
479
|
* We don't check against the previous block submitted since it may have been reorg'd out.
|
|
476
480
|
*/
|
|
477
481
|
protected async checkSync(args: { ts: bigint; slot: SlotNumber }): Promise<SequencerSyncCheckResult | undefined> {
|
|
478
|
-
// Check that the archiver
|
|
479
|
-
//
|
|
480
|
-
//
|
|
481
|
-
const
|
|
482
|
-
const { slot
|
|
483
|
-
if (
|
|
482
|
+
// Check that the archiver has fully synced the L2 slot before the one we want to propose in.
|
|
483
|
+
// The archiver reports sync progress via L1 block timestamps and synced checkpoint slots.
|
|
484
|
+
// See getSyncedL2SlotNumber for how missed L1 blocks are handled.
|
|
485
|
+
const syncedL2Slot = await this.l2BlockSource.getSyncedL2SlotNumber();
|
|
486
|
+
const { slot } = args;
|
|
487
|
+
if (syncedL2Slot === undefined || syncedL2Slot + 1 < slot) {
|
|
484
488
|
this.log.debug(`Cannot propose block at next L2 slot ${slot} due to pending sync from L1`, {
|
|
485
489
|
slot,
|
|
486
|
-
|
|
487
|
-
l1Timestamp,
|
|
490
|
+
syncedL2Slot,
|
|
488
491
|
});
|
|
489
492
|
return undefined;
|
|
490
493
|
}
|
|
@@ -524,7 +527,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
524
527
|
checkpointNumber: CheckpointNumber.ZERO,
|
|
525
528
|
blockNumber: BlockNumber.ZERO,
|
|
526
529
|
archive,
|
|
527
|
-
|
|
530
|
+
syncedL2Slot,
|
|
528
531
|
pendingChainValidationStatus,
|
|
529
532
|
};
|
|
530
533
|
}
|
|
@@ -541,7 +544,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
541
544
|
blockNumber: blockData.header.getBlockNumber(),
|
|
542
545
|
checkpointNumber: blockData.checkpointNumber,
|
|
543
546
|
archive: blockData.archive.root,
|
|
544
|
-
|
|
547
|
+
syncedL2Slot,
|
|
545
548
|
pendingChainValidationStatus,
|
|
546
549
|
};
|
|
547
550
|
}
|
|
@@ -720,7 +723,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
720
723
|
syncedTo: SequencerSyncCheckResult,
|
|
721
724
|
currentSlot: SlotNumber,
|
|
722
725
|
): Promise<void> {
|
|
723
|
-
const { pendingChainValidationStatus,
|
|
726
|
+
const { pendingChainValidationStatus, syncedL2Slot } = syncedTo;
|
|
724
727
|
if (pendingChainValidationStatus.valid) {
|
|
725
728
|
return;
|
|
726
729
|
}
|
|
@@ -735,7 +738,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
735
738
|
|
|
736
739
|
const logData = {
|
|
737
740
|
invalidL1Timestamp: invalidCheckpointTimestamp,
|
|
738
|
-
|
|
741
|
+
syncedL2Slot,
|
|
739
742
|
invalidCheckpoint: pendingChainValidationStatus.checkpoint,
|
|
740
743
|
secondsBeforeInvalidatingBlockAsCommitteeMember,
|
|
741
744
|
secondsBeforeInvalidatingBlockAsNonCommitteeMember,
|
|
@@ -882,6 +885,6 @@ type SequencerSyncCheckResult = {
|
|
|
882
885
|
checkpointNumber: CheckpointNumber;
|
|
883
886
|
blockNumber: BlockNumber;
|
|
884
887
|
archive: Fr;
|
|
885
|
-
|
|
888
|
+
syncedL2Slot: SlotNumber;
|
|
886
889
|
pendingChainValidationStatus: ValidateCheckpointResult;
|
|
887
890
|
};
|
package/src/sequencer/types.ts
CHANGED
|
@@ -2,8 +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'
|
|
6
|
-
|
|
7
|
-
/** Total L2 gas (mana) allowed per checkpoint. Fetched from L1 getManaLimit(). */
|
|
8
|
-
rollupManaLimit: number;
|
|
9
|
-
};
|
|
5
|
+
'ethereumSlotDuration' | 'l1GenesisTime' | 'slotDuration' | 'rollupManaLimit'
|
|
6
|
+
>;
|
|
@@ -4,11 +4,11 @@ import { unfreeze } from '@aztec/foundation/types';
|
|
|
4
4
|
import { L2Block } from '@aztec/stdlib/block';
|
|
5
5
|
import { Checkpoint } from '@aztec/stdlib/checkpoint';
|
|
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:
|
|
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:
|
|
77
|
+
opts: BlockBuilderOptions,
|
|
78
78
|
): Promise<BuildBlockInCheckpointResult> {
|
|
79
79
|
this.buildBlockCalls.push({ blockNumber, timestamp, opts });
|
|
80
80
|
|
|
@@ -304,6 +304,8 @@ export class MockCheckpointsBuilder implements ICheckpointsBuilder {
|
|
|
304
304
|
if (!this.checkpointBuilder) {
|
|
305
305
|
// Auto-create a builder if none was set
|
|
306
306
|
this.checkpointBuilder = new MockCheckpointBuilder(constants, checkpointNumber);
|
|
307
|
+
} else {
|
|
308
|
+
this.checkpointBuilder.resetCheckpointState();
|
|
307
309
|
}
|
|
308
310
|
|
|
309
311
|
return Promise.resolve(this.checkpointBuilder);
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { type Logger } from '@aztec/foundation/log';
|
|
2
|
-
import type { L1TxFailedStore } from './failed_tx_store.js';
|
|
3
|
-
/**
|
|
4
|
-
* Creates an L1TxFailedStore from a config string.
|
|
5
|
-
* Supports any backend that FileStore supports (GCS, S3, R2, local filesystem).
|
|
6
|
-
* @param config - Config string (e.g., 'gs://bucket/path', 's3://bucket/path', 'file:///path'). If undefined, returns undefined.
|
|
7
|
-
* @param logger - Optional logger.
|
|
8
|
-
* @returns The store instance, or undefined if config is not provided.
|
|
9
|
-
*/
|
|
10
|
-
export declare function createL1TxFailedStore(config: string | undefined, logger?: Logger): Promise<L1TxFailedStore | undefined>;
|
|
11
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFjdG9yeS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3B1Ymxpc2hlci9sMV90eF9mYWlsZWRfc3RvcmUvZmFjdG9yeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsS0FBSyxNQUFNLEVBQWdCLE1BQU0sdUJBQXVCLENBQUM7QUFHbEUsT0FBTyxLQUFLLEVBQUUsZUFBZSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFHNUQ7Ozs7OztHQU1HO0FBQ0gsd0JBQXNCLHFCQUFxQixDQUN6QyxNQUFNLEVBQUUsTUFBTSxHQUFHLFNBQVMsRUFDMUIsTUFBTSxHQUFFLE1BQXFELEdBQzVELE9BQU8sQ0FBQyxlQUFlLEdBQUcsU0FBUyxDQUFDLENBZXRDIn0=
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/publisher/l1_tx_failed_store/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;AAGlE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAG5D;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,MAAM,GAAE,MAAqD,GAC5D,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC,CAetC"}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { createLogger } from '@aztec/foundation/log';
|
|
2
|
-
import { createFileStore } from '@aztec/stdlib/file-store';
|
|
3
|
-
import { FileStoreL1TxFailedStore } from './file_store_failed_tx_store.js';
|
|
4
|
-
/**
|
|
5
|
-
* Creates an L1TxFailedStore from a config string.
|
|
6
|
-
* Supports any backend that FileStore supports (GCS, S3, R2, local filesystem).
|
|
7
|
-
* @param config - Config string (e.g., 'gs://bucket/path', 's3://bucket/path', 'file:///path'). If undefined, returns undefined.
|
|
8
|
-
* @param logger - Optional logger.
|
|
9
|
-
* @returns The store instance, or undefined if config is not provided.
|
|
10
|
-
*/ export async function createL1TxFailedStore(config, logger = createLogger('sequencer:l1-tx-failed-store')) {
|
|
11
|
-
if (!config) {
|
|
12
|
-
return undefined;
|
|
13
|
-
}
|
|
14
|
-
const fileStore = await createFileStore(config, logger);
|
|
15
|
-
if (!fileStore) {
|
|
16
|
-
throw new Error(`Failed to create file store from config: '${config}'. ` + `Supported formats: 'gs://bucket/path', 's3://bucket/path', 'file:///path'.`);
|
|
17
|
-
}
|
|
18
|
-
logger.info(`Created L1 tx failed store`, {
|
|
19
|
-
config
|
|
20
|
-
});
|
|
21
|
-
return new FileStoreL1TxFailedStore(fileStore, logger);
|
|
22
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import type { Hex } from 'viem';
|
|
2
|
-
/** URI pointing to a stored failed L1 transaction. */
|
|
3
|
-
export type FailedL1TxUri = string & {
|
|
4
|
-
__brand: 'FailedL1TxUri';
|
|
5
|
-
};
|
|
6
|
-
/** A failed L1 transaction captured for debugging and replay. */
|
|
7
|
-
export type FailedL1Tx = {
|
|
8
|
-
/** Tx hash (for reverts) or keccak256(request.data) (for simulation/send failures). */
|
|
9
|
-
id: Hex;
|
|
10
|
-
/** Unix timestamp (ms) when failure occurred. */
|
|
11
|
-
timestamp: number;
|
|
12
|
-
/** Whether the failure was during simulation or after sending. */
|
|
13
|
-
failureType: 'simulation' | 'revert' | 'send-error';
|
|
14
|
-
/** The actual L1 transaction for replay (multicall-encoded for bundled txs). */
|
|
15
|
-
request: {
|
|
16
|
-
to: Hex;
|
|
17
|
-
data: Hex;
|
|
18
|
-
value?: string;
|
|
19
|
-
};
|
|
20
|
-
/** Raw blob data as hex for replay. */
|
|
21
|
-
blobData?: Hex[];
|
|
22
|
-
/** L1 block number at time of failure (simulation target or receipt block). */
|
|
23
|
-
l1BlockNumber: string;
|
|
24
|
-
/** Receipt info (present only for on-chain reverts). */
|
|
25
|
-
receipt?: {
|
|
26
|
-
transactionHash: Hex;
|
|
27
|
-
blockNumber: string;
|
|
28
|
-
gasUsed: string;
|
|
29
|
-
status: 'reverted';
|
|
30
|
-
};
|
|
31
|
-
/** Error information. */
|
|
32
|
-
error: {
|
|
33
|
-
message: string;
|
|
34
|
-
/** Decoded error name (e.g., 'Rollup__InvalidProposer'). */
|
|
35
|
-
name?: string;
|
|
36
|
-
};
|
|
37
|
-
/** Context metadata. */
|
|
38
|
-
context: {
|
|
39
|
-
/** Actions involved (e.g., ['propose', 'governance-signal']). */
|
|
40
|
-
actions: string[];
|
|
41
|
-
/** Individual request data for each action (metadata, not used for replay). */
|
|
42
|
-
requests?: Array<{
|
|
43
|
-
action: string;
|
|
44
|
-
to: Hex;
|
|
45
|
-
data: Hex;
|
|
46
|
-
}>;
|
|
47
|
-
checkpointNumber?: number;
|
|
48
|
-
slot?: number;
|
|
49
|
-
sender: Hex;
|
|
50
|
-
};
|
|
51
|
-
};
|
|
52
|
-
/** Store for failed L1 transactions for debugging purposes. */
|
|
53
|
-
export interface L1TxFailedStore {
|
|
54
|
-
/** Saves a failed transaction and returns its URI. */
|
|
55
|
-
saveFailedTx(tx: FailedL1Tx): Promise<FailedL1TxUri>;
|
|
56
|
-
/** Retrieves a failed transaction by its URI. */
|
|
57
|
-
getFailedTx(uri: FailedL1TxUri): Promise<FailedL1Tx>;
|
|
58
|
-
}
|
|
59
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFpbGVkX3R4X3N0b3JlLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvcHVibGlzaGVyL2wxX3R4X2ZhaWxlZF9zdG9yZS9mYWlsZWRfdHhfc3RvcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsR0FBRyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRWhDLHNEQUFzRDtBQUN0RCxNQUFNLE1BQU0sYUFBYSxHQUFHLE1BQU0sR0FBRztJQUFFLE9BQU8sRUFBRSxlQUFlLENBQUE7Q0FBRSxDQUFDO0FBRWxFLGlFQUFpRTtBQUNqRSxNQUFNLE1BQU0sVUFBVSxHQUFHO0lBQ3ZCLHVGQUF1RjtJQUN2RixFQUFFLEVBQUUsR0FBRyxDQUFDO0lBQ1IsaURBQWlEO0lBQ2pELFNBQVMsRUFBRSxNQUFNLENBQUM7SUFDbEIsa0VBQWtFO0lBQ2xFLFdBQVcsRUFBRSxZQUFZLEdBQUcsUUFBUSxHQUFHLFlBQVksQ0FBQztJQUNwRCxnRkFBZ0Y7SUFDaEYsT0FBTyxFQUFFO1FBQ1AsRUFBRSxFQUFFLEdBQUcsQ0FBQztRQUNSLElBQUksRUFBRSxHQUFHLENBQUM7UUFDVixLQUFLLENBQUMsRUFBRSxNQUFNLENBQUM7S0FDaEIsQ0FBQztJQUNGLHVDQUF1QztJQUN2QyxRQUFRLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQztJQUNqQiwrRUFBK0U7SUFDL0UsYUFBYSxFQUFFLE1BQU0sQ0FBQztJQUN0Qix3REFBd0Q7SUFDeEQsT0FBTyxDQUFDLEVBQUU7UUFDUixlQUFlLEVBQUUsR0FBRyxDQUFDO1FBQ3JCLFdBQVcsRUFBRSxNQUFNLENBQUM7UUFDcEIsT0FBTyxFQUFFLE1BQU0sQ0FBQztRQUNoQixNQUFNLEVBQUUsVUFBVSxDQUFDO0tBQ3BCLENBQUM7SUFDRix5QkFBeUI7SUFDekIsS0FBSyxFQUFFO1FBQ0wsT0FBTyxFQUFFLE1BQU0sQ0FBQztRQUNoQiw0REFBNEQ7UUFDNUQsSUFBSSxDQUFDLEVBQUUsTUFBTSxDQUFDO0tBQ2YsQ0FBQztJQUNGLHdCQUF3QjtJQUN4QixPQUFPLEVBQUU7UUFDUCxpRUFBaUU7UUFDakUsT0FBTyxFQUFFLE1BQU0sRUFBRSxDQUFDO1FBQ2xCLCtFQUErRTtRQUMvRSxRQUFRLENBQUMsRUFBRSxLQUFLLENBQUM7WUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDO1lBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQztZQUFDLElBQUksRUFBRSxHQUFHLENBQUE7U0FBRSxDQUFDLENBQUM7UUFDekQsZ0JBQWdCLENBQUMsRUFBRSxNQUFNLENBQUM7UUFDMUIsSUFBSSxDQUFDLEVBQUUsTUFBTSxDQUFDO1FBQ2QsTUFBTSxFQUFFLEdBQUcsQ0FBQztLQUNiLENBQUM7Q0FDSCxDQUFDO0FBRUYsK0RBQStEO0FBQy9ELE1BQU0sV0FBVyxlQUFlO0lBQzlCLHNEQUFzRDtJQUN0RCxZQUFZLENBQUMsRUFBRSxFQUFFLFVBQVUsR0FBRyxPQUFPLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDckQsaURBQWlEO0lBQ2pELFdBQVcsQ0FBQyxHQUFHLEVBQUUsYUFBYSxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztDQUN0RCJ9
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"failed_tx_store.d.ts","sourceRoot":"","sources":["../../../src/publisher/l1_tx_failed_store/failed_tx_store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAEhC,sDAAsD;AACtD,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG;IAAE,OAAO,EAAE,eAAe,CAAA;CAAE,CAAC;AAElE,iEAAiE;AACjE,MAAM,MAAM,UAAU,GAAG;IACvB,uFAAuF;IACvF,EAAE,EAAE,GAAG,CAAC;IACR,iDAAiD;IACjD,SAAS,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,WAAW,EAAE,YAAY,GAAG,QAAQ,GAAG,YAAY,CAAC;IACpD,gFAAgF;IAChF,OAAO,EAAE;QACP,EAAE,EAAE,GAAG,CAAC;QACR,IAAI,EAAE,GAAG,CAAC;QACV,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,uCAAuC;IACvC,QAAQ,CAAC,EAAE,GAAG,EAAE,CAAC;IACjB,+EAA+E;IAC/E,aAAa,EAAE,MAAM,CAAC;IACtB,wDAAwD;IACxD,OAAO,CAAC,EAAE;QACR,eAAe,EAAE,GAAG,CAAC;QACrB,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,UAAU,CAAC;KACpB,CAAC;IACF,yBAAyB;IACzB,KAAK,EAAE;QACL,OAAO,EAAE,MAAM,CAAC;QAChB,4DAA4D;QAC5D,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,wBAAwB;IACxB,OAAO,EAAE;QACP,iEAAiE;QACjE,OAAO,EAAE,MAAM,EAAE,CAAC;QAClB,+EAA+E;QAC/E,QAAQ,CAAC,EAAE,KAAK,CAAC;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,EAAE,EAAE,GAAG,CAAC;YAAC,IAAI,EAAE,GAAG,CAAA;SAAE,CAAC,CAAC;QACzD,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,GAAG,CAAC;KACb,CAAC;CACH,CAAC;AAEF,+DAA+D;AAC/D,MAAM,WAAW,eAAe;IAC9B,sDAAsD;IACtD,YAAY,CAAC,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IACrD,iDAAiD;IACjD,WAAW,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;CACtD"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
/** Store for failed L1 transactions for debugging purposes. */ export { };
|