@aztec/sequencer-client 0.0.1-commit.3d8f95d → 0.0.1-commit.3fd054f6
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 +15 -7
- package/dest/client/sequencer-client.d.ts.map +1 -1
- package/dest/client/sequencer-client.js +60 -26
- package/dest/config.d.ts +26 -6
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +44 -21
- package/dest/global_variable_builder/global_builder.d.ts +14 -10
- 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 +47 -17
- package/dest/publisher/config.d.ts.map +1 -1
- package/dest/publisher/config.js +121 -42
- package/dest/publisher/index.d.ts +2 -1
- package/dest/publisher/index.d.ts.map +1 -1
- package/dest/publisher/l1_tx_failed_store/factory.d.ts +11 -0
- package/dest/publisher/l1_tx_failed_store/factory.d.ts.map +1 -0
- package/dest/publisher/l1_tx_failed_store/factory.js +22 -0
- package/dest/publisher/l1_tx_failed_store/failed_tx_store.d.ts +59 -0
- package/dest/publisher/l1_tx_failed_store/failed_tx_store.d.ts.map +1 -0
- package/dest/publisher/l1_tx_failed_store/failed_tx_store.js +1 -0
- package/dest/publisher/l1_tx_failed_store/file_store_failed_tx_store.d.ts +15 -0
- package/dest/publisher/l1_tx_failed_store/file_store_failed_tx_store.d.ts.map +1 -0
- package/dest/publisher/l1_tx_failed_store/file_store_failed_tx_store.js +34 -0
- package/dest/publisher/l1_tx_failed_store/index.d.ts +4 -0
- package/dest/publisher/l1_tx_failed_store/index.d.ts.map +1 -0
- package/dest/publisher/l1_tx_failed_store/index.js +2 -0
- package/dest/publisher/sequencer-publisher-factory.d.ts +11 -3
- package/dest/publisher/sequencer-publisher-factory.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher-factory.js +27 -2
- package/dest/publisher/sequencer-publisher.d.ts +33 -9
- package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher.js +332 -39
- package/dest/sequencer/checkpoint_proposal_job.d.ts +13 -7
- package/dest/sequencer/checkpoint_proposal_job.d.ts.map +1 -1
- package/dest/sequencer/checkpoint_proposal_job.js +235 -137
- package/dest/sequencer/events.d.ts +2 -1
- package/dest/sequencer/events.d.ts.map +1 -1
- package/dest/sequencer/metrics.d.ts +21 -5
- package/dest/sequencer/metrics.d.ts.map +1 -1
- package/dest/sequencer/metrics.js +97 -15
- package/dest/sequencer/sequencer.d.ts +28 -15
- package/dest/sequencer/sequencer.d.ts.map +1 -1
- package/dest/sequencer/sequencer.js +93 -85
- package/dest/sequencer/timetable.d.ts +4 -3
- package/dest/sequencer/timetable.d.ts.map +1 -1
- package/dest/sequencer/timetable.js +6 -7
- package/dest/sequencer/types.d.ts +2 -2
- package/dest/sequencer/types.d.ts.map +1 -1
- package/dest/test/index.d.ts +3 -5
- package/dest/test/index.d.ts.map +1 -1
- package/dest/test/mock_checkpoint_builder.d.ts +11 -11
- package/dest/test/mock_checkpoint_builder.d.ts.map +1 -1
- package/dest/test/mock_checkpoint_builder.js +45 -34
- package/dest/test/utils.d.ts +3 -3
- package/dest/test/utils.d.ts.map +1 -1
- package/dest/test/utils.js +5 -4
- package/package.json +27 -28
- package/src/client/sequencer-client.ts +76 -23
- package/src/config.ts +56 -27
- package/src/global_variable_builder/global_builder.ts +23 -24
- package/src/global_variable_builder/index.ts +1 -1
- package/src/publisher/config.ts +153 -43
- package/src/publisher/index.ts +3 -0
- package/src/publisher/l1_tx_failed_store/factory.ts +32 -0
- package/src/publisher/l1_tx_failed_store/failed_tx_store.ts +55 -0
- package/src/publisher/l1_tx_failed_store/file_store_failed_tx_store.ts +46 -0
- package/src/publisher/l1_tx_failed_store/index.ts +3 -0
- package/src/publisher/sequencer-publisher-factory.ts +38 -6
- package/src/publisher/sequencer-publisher.ts +338 -53
- package/src/sequencer/checkpoint_proposal_job.ts +320 -148
- package/src/sequencer/events.ts +1 -1
- package/src/sequencer/metrics.ts +106 -18
- package/src/sequencer/sequencer.ts +127 -97
- package/src/sequencer/timetable.ts +7 -7
- package/src/sequencer/types.ts +1 -1
- package/src/test/index.ts +2 -4
- package/src/test/mock_checkpoint_builder.ts +63 -49
- package/src/test/utils.ts +5 -2
|
@@ -380,7 +380,7 @@ import { Fr } from '@aztec/foundation/curves/bn254';
|
|
|
380
380
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
381
381
|
import { createLogger } from '@aztec/foundation/log';
|
|
382
382
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
383
|
-
import {
|
|
383
|
+
import { getSlotStartBuildTimestamp } from '@aztec/stdlib/epoch-helpers';
|
|
384
384
|
import { SequencerConfigSchema } from '@aztec/stdlib/interfaces/server';
|
|
385
385
|
import { pickFromSchema } from '@aztec/stdlib/schemas';
|
|
386
386
|
import { MerkleTreeId } from '@aztec/stdlib/trees';
|
|
@@ -455,13 +455,6 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
455
455
|
/** Last successful checkpoint proposed */ lastCheckpointProposed;
|
|
456
456
|
/** The last epoch for which we logged strategy comparison in fisherman mode. */ lastEpochForStrategyComparison;
|
|
457
457
|
/** The maximum number of seconds that the sequencer can be into a slot to transition to a particular state. */ timetable;
|
|
458
|
-
// This shouldn't be here as this gets re-created each time we build/propose a block.
|
|
459
|
-
// But we have a number of tests that abuse/rely on this class having a permanent publisher.
|
|
460
|
-
// As long as those tests only configure a single publisher they will continue to work.
|
|
461
|
-
// This will get re-assigned every time the sequencer goes to build a new block to a publisher that is valid
|
|
462
|
-
// for the block proposer.
|
|
463
|
-
// TODO(palla/mbps): Remove this field and fix tests
|
|
464
|
-
publisher;
|
|
465
458
|
/** Config for the sequencer */ config;
|
|
466
459
|
constructor(publisherFactory, validatorClient, globalsBuilder, p2pClient, worldState, slasherClient, l2BlockSource, l1ToL2MessageSource, checkpointsBuilder, l1Constants, dateProvider, epochCache, rollupContract, config, telemetry = getTelemetryClient(), log = createLogger('sequencer')){
|
|
467
460
|
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.checkpointsBuilder = checkpointsBuilder, this.l1Constants = l1Constants, this.dateProvider = dateProvider, this.epochCache = epochCache, this.rollupContract = rollupContract, this.telemetry = telemetry, this.log = log, this.state = (_initProto(this), SequencerState.STOPPED), this.config = DefaultSequencerConfig;
|
|
@@ -474,7 +467,7 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
474
467
|
}
|
|
475
468
|
/** Updates sequencer config by the defined values and updates the timetable */ updateConfig(config) {
|
|
476
469
|
const filteredConfig = pickFromSchema(config, SequencerConfigSchema);
|
|
477
|
-
this.log.info(`Updated sequencer config`, omit(filteredConfig, '
|
|
470
|
+
this.log.info(`Updated sequencer config`, omit(filteredConfig, 'txPublicSetupAllowListExtend'));
|
|
478
471
|
this.config = merge(this.config, filteredConfig);
|
|
479
472
|
this.timetable = new SequencerTimetable({
|
|
480
473
|
ethereumSlotDuration: this.l1Constants.ethereumSlotDuration,
|
|
@@ -485,9 +478,8 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
485
478
|
enforce: this.config.enforceTimeTable
|
|
486
479
|
}, this.metrics, this.log);
|
|
487
480
|
}
|
|
488
|
-
/** Initializes the sequencer (precomputes tables
|
|
481
|
+
/** Initializes the sequencer (precomputes tables). Takes about 3s. */ init() {
|
|
489
482
|
getKzg();
|
|
490
|
-
this.publisher = (await this.publisherFactory.create(undefined)).publisher;
|
|
491
483
|
}
|
|
492
484
|
/** Starts the sequencer and moves to IDLE state. */ start() {
|
|
493
485
|
this.runningPromise = new RunningPromise(this.safeWork.bind(this), this.log, this.config.sequencerPollingIntervalMS);
|
|
@@ -502,7 +494,7 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
502
494
|
this.setState(SequencerState.STOPPING, undefined, {
|
|
503
495
|
force: true
|
|
504
496
|
});
|
|
505
|
-
this.
|
|
497
|
+
await this.publisherFactory.stopAll();
|
|
506
498
|
await this.runningPromise?.stop();
|
|
507
499
|
this.setState(SequencerState.STOPPED, undefined, {
|
|
508
500
|
force: true
|
|
@@ -517,7 +509,6 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
517
509
|
error: err
|
|
518
510
|
});
|
|
519
511
|
if (err instanceof SequencerTooSlowError) {
|
|
520
|
-
// TODO(palla/mbps): Add missing states
|
|
521
512
|
// Log as warn only if we had to abort halfway through the block proposal
|
|
522
513
|
const logLvl = [
|
|
523
514
|
SequencerState.INITIALIZING_CHECKPOINT,
|
|
@@ -548,9 +539,10 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
548
539
|
* - Submit checkpoint
|
|
549
540
|
*/ async work() {
|
|
550
541
|
this.setState(SequencerState.SYNCHRONIZING, undefined);
|
|
551
|
-
const { slot, ts,
|
|
542
|
+
const { slot, ts, nowSeconds, epoch } = this.epochCache.getEpochAndSlotInNextL1Slot();
|
|
543
|
+
const { slot: targetSlot, epoch: targetEpoch } = this.epochCache.getTargetEpochAndSlotInNextL1Slot();
|
|
552
544
|
// Check if we are synced and it's our slot, grab a publisher, check previous block invalidation, etc
|
|
553
|
-
const checkpointProposalJob = await this.prepareCheckpointProposal(epoch,
|
|
545
|
+
const checkpointProposalJob = await this.prepareCheckpointProposal(slot, targetSlot, epoch, targetEpoch, ts, nowSeconds);
|
|
554
546
|
if (!checkpointProposalJob) {
|
|
555
547
|
return;
|
|
556
548
|
}
|
|
@@ -560,10 +552,10 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
560
552
|
if (checkpoint) {
|
|
561
553
|
this.lastCheckpointProposed = checkpoint;
|
|
562
554
|
}
|
|
563
|
-
// Log fee strategy comparison if on fisherman
|
|
564
|
-
if (this.config.fishermanMode && (this.lastEpochForStrategyComparison === undefined ||
|
|
565
|
-
this.logStrategyComparison(
|
|
566
|
-
this.lastEpochForStrategyComparison =
|
|
555
|
+
// Log fee strategy comparison if on fisherman (uses target epoch since we mirror the proposer's perspective)
|
|
556
|
+
if (this.config.fishermanMode && (this.lastEpochForStrategyComparison === undefined || targetEpoch > this.lastEpochForStrategyComparison)) {
|
|
557
|
+
this.logStrategyComparison(targetEpoch, checkpointProposalJob.getPublisher());
|
|
558
|
+
this.lastEpochForStrategyComparison = targetEpoch;
|
|
567
559
|
}
|
|
568
560
|
return checkpoint;
|
|
569
561
|
}
|
|
@@ -571,17 +563,17 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
571
563
|
* Prepares the checkpoint proposal by performing all necessary checks and setup.
|
|
572
564
|
* This is the initial step in the main loop.
|
|
573
565
|
* @returns CheckpointProposalJob if successful, undefined if we are not yet synced or are not the proposer.
|
|
574
|
-
*/ async prepareCheckpointProposal(epoch,
|
|
575
|
-
// Check we have not already processed this slot (cheapest check)
|
|
566
|
+
*/ async prepareCheckpointProposal(slot, targetSlot, epoch, targetEpoch, ts, nowSeconds) {
|
|
567
|
+
// Check we have not already processed this target slot (cheapest check)
|
|
576
568
|
// We only check this if enforce timetable is set, since we want to keep processing the same slot if we are not
|
|
577
569
|
// running against actual time (eg when we use sandbox-style automining)
|
|
578
|
-
if (this.lastSlotForCheckpointProposalJob && this.lastSlotForCheckpointProposalJob >=
|
|
579
|
-
this.log.trace(`
|
|
570
|
+
if (this.lastSlotForCheckpointProposalJob && this.lastSlotForCheckpointProposalJob >= targetSlot && this.config.enforceTimeTable) {
|
|
571
|
+
this.log.trace(`Target slot ${targetSlot} has already been processed`);
|
|
580
572
|
return undefined;
|
|
581
573
|
}
|
|
582
|
-
// But if we have already proposed for this slot,
|
|
583
|
-
if (this.lastCheckpointProposed && this.lastCheckpointProposed.header.slotNumber >=
|
|
584
|
-
this.log.trace(`Slot ${
|
|
574
|
+
// But if we have already proposed for this slot, then we definitely have to skip it, automining or not
|
|
575
|
+
if (this.lastCheckpointProposed && this.lastCheckpointProposed.header.slotNumber >= targetSlot) {
|
|
576
|
+
this.log.trace(`Slot ${targetSlot} has already been published as checkpoint ${this.lastCheckpointProposed.number}`);
|
|
585
577
|
return undefined;
|
|
586
578
|
}
|
|
587
579
|
// Check all components are synced to latest as seen by the archiver (queries all subsystems)
|
|
@@ -592,16 +584,18 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
592
584
|
if (!syncedTo) {
|
|
593
585
|
await this.tryVoteWhenSyncFails({
|
|
594
586
|
slot,
|
|
587
|
+
targetSlot,
|
|
595
588
|
ts
|
|
596
589
|
});
|
|
597
590
|
return undefined;
|
|
598
591
|
}
|
|
599
|
-
// If escape hatch is open for
|
|
592
|
+
// If escape hatch is open for the target epoch, do not start checkpoint proposal work and do not attempt invalidations.
|
|
600
593
|
// Still perform governance/slashing voting (as proposer) once per slot.
|
|
601
|
-
|
|
594
|
+
// When pipelining, we check the target epoch (slot+1's epoch) since that's the epoch we're building for.
|
|
595
|
+
const isEscapeHatchOpen = await this.epochCache.isEscapeHatchOpen(targetEpoch);
|
|
602
596
|
if (isEscapeHatchOpen) {
|
|
603
597
|
this.setState(SequencerState.PROPOSER_CHECK, slot);
|
|
604
|
-
const [canPropose, proposer] = await this.checkCanPropose(
|
|
598
|
+
const [canPropose, proposer] = await this.checkCanPropose(targetSlot);
|
|
605
599
|
if (canPropose) {
|
|
606
600
|
await this.tryVoteWhenEscapeHatchOpen({
|
|
607
601
|
slot,
|
|
@@ -619,29 +613,29 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
619
613
|
// Next checkpoint follows from the last synced one
|
|
620
614
|
const checkpointNumber = CheckpointNumber(syncedTo.checkpointNumber + 1);
|
|
621
615
|
const logCtx = {
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
syncedToL2Slot: getSlotAtTimestamp(syncedTo.l1Timestamp, this.l1Constants),
|
|
616
|
+
nowSeconds,
|
|
617
|
+
syncedToL2Slot: syncedTo.syncedL2Slot,
|
|
625
618
|
slot,
|
|
619
|
+
targetSlot,
|
|
626
620
|
slotTs: ts,
|
|
627
621
|
checkpointNumber,
|
|
628
622
|
isPendingChainValid: pick(syncedTo.pendingChainValidationStatus, 'valid', 'reason', 'invalidIndex')
|
|
629
623
|
};
|
|
630
|
-
// Check that we are a proposer for the
|
|
624
|
+
// Check that we are a proposer for the target slot.
|
|
631
625
|
this.setState(SequencerState.PROPOSER_CHECK, slot);
|
|
632
|
-
const [canPropose, proposer] = await this.checkCanPropose(
|
|
626
|
+
const [canPropose, proposer] = await this.checkCanPropose(targetSlot);
|
|
633
627
|
// If we are not a proposer check if we should invalidate an invalid checkpoint, and bail
|
|
634
628
|
if (!canPropose) {
|
|
635
629
|
await this.considerInvalidatingCheckpoint(syncedTo, slot);
|
|
636
630
|
return undefined;
|
|
637
631
|
}
|
|
638
|
-
// Check that the slot is not taken by a block already (should never happen, since only us can propose for this slot)
|
|
639
|
-
if (syncedTo.
|
|
640
|
-
this.log.warn(`Cannot propose block at
|
|
632
|
+
// Check that the target slot is not taken by a block already (should never happen, since only us can propose for this slot)
|
|
633
|
+
if (syncedTo.blockData && syncedTo.blockData.header.getSlot() >= targetSlot) {
|
|
634
|
+
this.log.warn(`Cannot propose block at target slot ${targetSlot} since that slot was taken by block ${syncedTo.blockNumber}`, {
|
|
641
635
|
...logCtx,
|
|
642
|
-
block: syncedTo.
|
|
636
|
+
block: syncedTo.blockData.header.toInspect()
|
|
643
637
|
});
|
|
644
|
-
this.metrics.
|
|
638
|
+
this.metrics.recordCheckpointPrecheckFailed('slot_already_taken');
|
|
645
639
|
return undefined;
|
|
646
640
|
}
|
|
647
641
|
// We now need to get ourselves a publisher.
|
|
@@ -651,7 +645,6 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
651
645
|
const proposerForPublisher = this.config.fishermanMode ? undefined : proposer;
|
|
652
646
|
const { attestorAddress, publisher } = await this.publisherFactory.create(proposerForPublisher);
|
|
653
647
|
this.log.verbose(`Created publisher at address ${publisher.getSenderAddress()} for attestor ${attestorAddress}`);
|
|
654
|
-
this.publisher = publisher;
|
|
655
648
|
// In fisherman mode, set the actual proposer's address for simulations
|
|
656
649
|
if (this.config.fishermanMode && proposer) {
|
|
657
650
|
publisher.setProposerAddressForSimulation(proposer);
|
|
@@ -659,29 +652,31 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
659
652
|
}
|
|
660
653
|
// Prepare invalidation request if the pending chain is invalid (returns undefined if no need)
|
|
661
654
|
const invalidateCheckpoint = await publisher.simulateInvalidateCheckpoint(syncedTo.pendingChainValidationStatus);
|
|
662
|
-
// Check with the rollup contract if we can indeed propose at the
|
|
655
|
+
// Check with the rollup contract if we can indeed propose at the target slot. This check should not fail
|
|
663
656
|
// if all the previous checks are good, but we do it just in case.
|
|
664
|
-
const canProposeCheck = await publisher.
|
|
657
|
+
const canProposeCheck = await publisher.canProposeAt(syncedTo.archive, proposer ?? EthAddress.ZERO, {
|
|
658
|
+
...invalidateCheckpoint
|
|
659
|
+
});
|
|
665
660
|
if (canProposeCheck === undefined) {
|
|
666
661
|
this.log.warn(`Cannot propose checkpoint ${checkpointNumber} at slot ${slot} due to failed rollup contract check`, logCtx);
|
|
667
662
|
this.emit('proposer-rollup-check-failed', {
|
|
668
663
|
reason: 'Rollup contract check failed',
|
|
669
664
|
slot
|
|
670
665
|
});
|
|
671
|
-
this.metrics.
|
|
666
|
+
this.metrics.recordCheckpointPrecheckFailed('rollup_contract_check_failed');
|
|
672
667
|
return undefined;
|
|
673
668
|
}
|
|
674
|
-
if (canProposeCheck.slot !==
|
|
675
|
-
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 ${
|
|
669
|
+
if (canProposeCheck.slot !== targetSlot) {
|
|
670
|
+
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 ${targetSlot} but got ${canProposeCheck.slot}.`, {
|
|
676
671
|
...logCtx,
|
|
677
672
|
rollup: canProposeCheck,
|
|
678
|
-
expectedSlot:
|
|
673
|
+
expectedSlot: targetSlot
|
|
679
674
|
});
|
|
680
675
|
this.emit('proposer-rollup-check-failed', {
|
|
681
676
|
reason: 'Slot mismatch',
|
|
682
677
|
slot
|
|
683
678
|
});
|
|
684
|
-
this.metrics.
|
|
679
|
+
this.metrics.recordCheckpointPrecheckFailed('slot_mismatch');
|
|
685
680
|
return undefined;
|
|
686
681
|
}
|
|
687
682
|
if (canProposeCheck.checkpointNumber !== checkpointNumber) {
|
|
@@ -694,20 +689,26 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
694
689
|
reason: 'Block mismatch',
|
|
695
690
|
slot
|
|
696
691
|
});
|
|
697
|
-
this.metrics.
|
|
692
|
+
this.metrics.recordCheckpointPrecheckFailed('block_number_mismatch');
|
|
698
693
|
return undefined;
|
|
699
694
|
}
|
|
700
|
-
this.lastSlotForCheckpointProposalJob =
|
|
701
|
-
await this.p2pClient.prepareForSlot(
|
|
702
|
-
this.log.info(`Preparing checkpoint proposal ${checkpointNumber}
|
|
695
|
+
this.lastSlotForCheckpointProposalJob = targetSlot;
|
|
696
|
+
await this.p2pClient.prepareForSlot(targetSlot);
|
|
697
|
+
this.log.info(`Preparing checkpoint proposal ${checkpointNumber} for target slot ${targetSlot} during wall-clock slot ${slot}`, {
|
|
703
698
|
...logCtx,
|
|
704
|
-
proposer
|
|
699
|
+
proposer,
|
|
700
|
+
pipeliningEnabled: this.epochCache.isProposerPipeliningEnabled()
|
|
705
701
|
});
|
|
706
702
|
// Create and return the checkpoint proposal job
|
|
707
|
-
return this.createCheckpointProposalJob(epoch,
|
|
703
|
+
return this.createCheckpointProposalJob(slot, targetSlot, epoch, targetEpoch, checkpointNumber, syncedTo.blockNumber, proposer, publisher, attestorAddress, invalidateCheckpoint);
|
|
708
704
|
}
|
|
709
|
-
createCheckpointProposalJob(epoch,
|
|
710
|
-
return new CheckpointProposalJob(epoch,
|
|
705
|
+
createCheckpointProposalJob(slot, targetSlot, epoch, targetEpoch, checkpointNumber, syncedToBlockNumber, proposer, publisher, attestorAddress, invalidateCheckpoint) {
|
|
706
|
+
return new CheckpointProposalJob(slot, targetSlot, epoch, targetEpoch, checkpointNumber, syncedToBlockNumber, proposer, publisher, attestorAddress, invalidateCheckpoint, this.validatorClient, this.globalsBuilder, this.p2pClient, this.worldState, this.l1ToL2MessageSource, this.l2BlockSource, this.checkpointsBuilder, this.l2BlockSource, this.l1Constants, this.config, this.timetable, this.slasherClient, this.epochCache, this.dateProvider, this.metrics, this, this.setState.bind(this), this.tracer, this.log.getBindings());
|
|
707
|
+
}
|
|
708
|
+
/**
|
|
709
|
+
* Returns the current sequencer state.
|
|
710
|
+
*/ getState() {
|
|
711
|
+
return this.state;
|
|
711
712
|
}
|
|
712
713
|
/**
|
|
713
714
|
* Internal helper for setting the sequencer state and checks if we have enough time left in the slot to transition to the new state.
|
|
@@ -749,16 +750,15 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
749
750
|
* Returns whether all dependencies have caught up.
|
|
750
751
|
* We don't check against the previous block submitted since it may have been reorg'd out.
|
|
751
752
|
*/ async checkSync(args) {
|
|
752
|
-
// Check that the archiver
|
|
753
|
-
//
|
|
754
|
-
//
|
|
755
|
-
const
|
|
756
|
-
const { slot
|
|
757
|
-
if (
|
|
753
|
+
// Check that the archiver has fully synced the L2 slot before the one we want to propose in.
|
|
754
|
+
// The archiver reports sync progress via L1 block timestamps and synced checkpoint slots.
|
|
755
|
+
// See getSyncedL2SlotNumber for how missed L1 blocks are handled.
|
|
756
|
+
const syncedL2Slot = await this.l2BlockSource.getSyncedL2SlotNumber();
|
|
757
|
+
const { slot } = args;
|
|
758
|
+
if (syncedL2Slot === undefined || syncedL2Slot + 1 < slot) {
|
|
758
759
|
this.log.debug(`Cannot propose block at next L2 slot ${slot} due to pending sync from L1`, {
|
|
759
760
|
slot,
|
|
760
|
-
|
|
761
|
-
l1Timestamp
|
|
761
|
+
syncedL2Slot
|
|
762
762
|
});
|
|
763
763
|
return undefined;
|
|
764
764
|
}
|
|
@@ -794,44 +794,44 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
794
794
|
checkpointNumber: CheckpointNumber.ZERO,
|
|
795
795
|
blockNumber: BlockNumber.ZERO,
|
|
796
796
|
archive,
|
|
797
|
-
|
|
797
|
+
syncedL2Slot,
|
|
798
798
|
pendingChainValidationStatus
|
|
799
799
|
};
|
|
800
800
|
}
|
|
801
|
-
const
|
|
802
|
-
if (!
|
|
801
|
+
const blockData = await this.l2BlockSource.getBlockData(blockNumber);
|
|
802
|
+
if (!blockData) {
|
|
803
803
|
// this shouldn't really happen because a moment ago we checked that all components were in sync
|
|
804
|
-
this.log.error(`Failed to get L2 block ${blockNumber} from the archiver with all components in sync`);
|
|
804
|
+
this.log.error(`Failed to get L2 block data ${blockNumber} from the archiver with all components in sync`);
|
|
805
805
|
return undefined;
|
|
806
806
|
}
|
|
807
807
|
return {
|
|
808
|
-
|
|
809
|
-
blockNumber:
|
|
810
|
-
checkpointNumber:
|
|
811
|
-
archive:
|
|
812
|
-
|
|
808
|
+
blockData,
|
|
809
|
+
blockNumber: blockData.header.getBlockNumber(),
|
|
810
|
+
checkpointNumber: blockData.checkpointNumber,
|
|
811
|
+
archive: blockData.archive.root,
|
|
812
|
+
syncedL2Slot,
|
|
813
813
|
pendingChainValidationStatus
|
|
814
814
|
};
|
|
815
815
|
}
|
|
816
816
|
/**
|
|
817
817
|
* Checks if we are the proposer for the next slot.
|
|
818
818
|
* @returns True if we can propose, and the proposer address (undefined if anyone can propose)
|
|
819
|
-
*/ async checkCanPropose(
|
|
819
|
+
*/ async checkCanPropose(targetSlot) {
|
|
820
820
|
let proposer;
|
|
821
821
|
try {
|
|
822
|
-
proposer = await this.epochCache.getProposerAttesterAddressInSlot(
|
|
822
|
+
proposer = await this.epochCache.getProposerAttesterAddressInSlot(targetSlot);
|
|
823
823
|
} catch (e) {
|
|
824
824
|
if (e instanceof NoCommitteeError) {
|
|
825
|
-
if (this.lastSlotForNoCommitteeWarning !==
|
|
826
|
-
this.lastSlotForNoCommitteeWarning =
|
|
827
|
-
this.log.warn(`Cannot propose at
|
|
825
|
+
if (this.lastSlotForNoCommitteeWarning !== targetSlot) {
|
|
826
|
+
this.lastSlotForNoCommitteeWarning = targetSlot;
|
|
827
|
+
this.log.warn(`Cannot propose at target slot ${targetSlot} since the committee does not exist on L1`);
|
|
828
828
|
}
|
|
829
829
|
return [
|
|
830
830
|
false,
|
|
831
831
|
undefined
|
|
832
832
|
];
|
|
833
833
|
}
|
|
834
|
-
this.log.error(`Error getting proposer for slot ${
|
|
834
|
+
this.log.error(`Error getting proposer for target slot ${targetSlot}`, e);
|
|
835
835
|
return [
|
|
836
836
|
false,
|
|
837
837
|
undefined
|
|
@@ -854,7 +854,8 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
854
854
|
const validatorAddresses = this.validatorClient.getValidatorAddresses();
|
|
855
855
|
const weAreProposer = validatorAddresses.some((addr)=>addr.equals(proposer));
|
|
856
856
|
if (!weAreProposer) {
|
|
857
|
-
this.log.debug(`Cannot propose at slot ${
|
|
857
|
+
this.log.debug(`Cannot propose at target slot ${targetSlot} since we are not a proposer`, {
|
|
858
|
+
targetSlot,
|
|
858
859
|
validatorAddresses,
|
|
859
860
|
proposer
|
|
860
861
|
});
|
|
@@ -863,6 +864,10 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
863
864
|
proposer
|
|
864
865
|
];
|
|
865
866
|
}
|
|
867
|
+
this.log.debug(`We are the proposer for target slot ${targetSlot}`, {
|
|
868
|
+
targetSlot,
|
|
869
|
+
proposer
|
|
870
|
+
});
|
|
866
871
|
return [
|
|
867
872
|
true,
|
|
868
873
|
proposer
|
|
@@ -872,7 +877,7 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
872
877
|
* Tries to vote on slashing actions and governance when the sync check fails but we're past the max time for initializing a proposal.
|
|
873
878
|
* This allows the sequencer to participate in governance/slashing votes even when it cannot build blocks.
|
|
874
879
|
*/ async tryVoteWhenSyncFails(args) {
|
|
875
|
-
const { slot } = args;
|
|
880
|
+
const { slot, targetSlot } = args;
|
|
876
881
|
// Prevent duplicate attempts in the same slot
|
|
877
882
|
if (this.lastSlotForFallbackVote === slot) {
|
|
878
883
|
this.log.trace(`Already attempted to vote in slot ${slot} (skipping)`);
|
|
@@ -895,7 +900,7 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
895
900
|
maxAllowedTime
|
|
896
901
|
});
|
|
897
902
|
// Check if we're a proposer or proposal is open
|
|
898
|
-
const [canPropose, proposer] = await this.checkCanPropose(
|
|
903
|
+
const [canPropose, proposer] = await this.checkCanPropose(targetSlot);
|
|
899
904
|
if (!canPropose) {
|
|
900
905
|
this.log.trace(`Cannot vote in slot ${slot} since we are not a proposer`, {
|
|
901
906
|
slot,
|
|
@@ -911,8 +916,8 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
911
916
|
attestorAddress,
|
|
912
917
|
slot
|
|
913
918
|
});
|
|
914
|
-
// Enqueue governance and slashing votes
|
|
915
|
-
const voter = new CheckpointVoter(
|
|
919
|
+
// Enqueue governance and slashing votes (voter uses the target slot for L1 submission)
|
|
920
|
+
const voter = new CheckpointVoter(targetSlot, publisher, attestorAddress, this.validatorClient, this.slasherClient, this.l1Constants, this.config, this.metrics, this.log);
|
|
916
921
|
const votesPromises = voter.enqueueVotes();
|
|
917
922
|
const votes = await Promise.all(votesPromises);
|
|
918
923
|
if (votes.every((p)=>!p)) {
|
|
@@ -959,7 +964,7 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
959
964
|
* have the proposer try to invalidate, but if they fail, the sequencers in the committee are expected to try,
|
|
960
965
|
* and if they fail, any sequencer will try as well.
|
|
961
966
|
*/ async considerInvalidatingCheckpoint(syncedTo, currentSlot) {
|
|
962
|
-
const { pendingChainValidationStatus,
|
|
967
|
+
const { pendingChainValidationStatus, syncedL2Slot } = syncedTo;
|
|
963
968
|
if (pendingChainValidationStatus.valid) {
|
|
964
969
|
return;
|
|
965
970
|
}
|
|
@@ -970,7 +975,7 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
970
975
|
const { secondsBeforeInvalidatingBlockAsCommitteeMember, secondsBeforeInvalidatingBlockAsNonCommitteeMember } = this.config;
|
|
971
976
|
const logData = {
|
|
972
977
|
invalidL1Timestamp: invalidCheckpointTimestamp,
|
|
973
|
-
|
|
978
|
+
syncedL2Slot,
|
|
974
979
|
invalidCheckpoint: pendingChainValidationStatus.checkpoint,
|
|
975
980
|
secondsBeforeInvalidatingBlockAsCommitteeMember,
|
|
976
981
|
secondsBeforeInvalidatingBlockAsNonCommitteeMember,
|
|
@@ -1061,6 +1066,9 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
1061
1066
|
getValidatorAddresses() {
|
|
1062
1067
|
return this.validatorClient?.getValidatorAddresses();
|
|
1063
1068
|
}
|
|
1069
|
+
/** Updates the publisher factory's node keystore adapter after a keystore reload. */ updatePublisherNodeKeyStore(adapter) {
|
|
1070
|
+
this.publisherFactory.updateNodeKeyStore(adapter);
|
|
1071
|
+
}
|
|
1064
1072
|
getConfig() {
|
|
1065
1073
|
return this.config;
|
|
1066
1074
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import type { Logger } from '@aztec/foundation/log';
|
|
1
2
|
import type { SequencerMetrics } from './metrics.js';
|
|
2
3
|
import { SequencerState } from './utils.js';
|
|
3
4
|
export declare class SequencerTimetable {
|
|
4
5
|
private readonly metrics?;
|
|
5
|
-
private readonly log
|
|
6
|
+
private readonly log?;
|
|
6
7
|
/**
|
|
7
8
|
* How late into the slot can we be to start working. Computed as the total time needed for assembling and publishing a block,
|
|
8
9
|
* assuming an execution time equal to `minExecutionTime`, subtracted from the slot duration. This means that, if the proposer
|
|
@@ -56,7 +57,7 @@ export declare class SequencerTimetable {
|
|
|
56
57
|
p2pPropagationTime?: number;
|
|
57
58
|
blockDurationMs?: number;
|
|
58
59
|
enforce: boolean;
|
|
59
|
-
}, metrics?: SequencerMetrics | undefined, log?:
|
|
60
|
+
}, metrics?: SequencerMetrics | undefined, log?: Logger | undefined);
|
|
60
61
|
getMaxAllowedTime(state: Extract<SequencerState, SequencerState.STOPPED | SequencerState.IDLE | SequencerState.SYNCHRONIZING>): undefined;
|
|
61
62
|
getMaxAllowedTime(state: Exclude<SequencerState, SequencerState.STOPPED | SequencerState.IDLE | SequencerState.SYNCHRONIZING>): number;
|
|
62
63
|
getMaxAllowedTime(state: SequencerState): number | undefined;
|
|
@@ -84,4 +85,4 @@ export declare class SequencerTimetable {
|
|
|
84
85
|
isLastBlock: boolean;
|
|
85
86
|
};
|
|
86
87
|
}
|
|
87
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
88
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZXRhYmxlLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VxdWVuY2VyL3RpbWV0YWJsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQVNwRCxPQUFPLEtBQUssRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUNyRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRTVDLHFCQUFhLGtCQUFrQjtJQXFFM0IsT0FBTyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUM7SUFDekIsT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUM7SUFyRXZCOzs7O09BSUc7SUFDSCxTQUFnQixrQkFBa0IsRUFBRSxNQUFNLENBQUM7SUFFM0M7Ozs7T0FJRztJQUNILFNBQWdCLG9CQUFvQixFQUFFLE1BQU0sQ0FBQztJQUU3Qzs7Ozs7T0FLRztJQUNILFNBQWdCLDBCQUEwQixFQUFFLE1BQU0sQ0FBQztJQUVuRDs7OztPQUlHO0lBQ0gsU0FBZ0IsZ0JBQWdCLEVBQUUsTUFBTSxDQUFDO0lBRXpDOzs7T0FHRztJQUNILFNBQWdCLGdCQUFnQixFQUFFLE1BQU0sQ0FBc0I7SUFFOUQsdURBQXVEO0lBQ3ZELFNBQWdCLDRCQUE0QixFQUFFLE1BQU0sQ0FBa0M7SUFFdEYsbUdBQW1HO0lBQ25HLFNBQWdCLGtCQUFrQixFQUFFLE1BQU0sQ0FBQztJQUUzQyxtRkFBbUY7SUFDbkYsU0FBZ0Isc0JBQXNCLEVBQUUsTUFBTSxDQUE0QjtJQUUxRSx3Q0FBd0M7SUFDeEMsU0FBZ0Isb0JBQW9CLEVBQUUsTUFBTSxDQUFDO0lBRTdDLGtGQUFrRjtJQUNsRixTQUFnQixpQkFBaUIsRUFBRSxNQUFNLENBQUM7SUFFMUMsNERBQTREO0lBQzVELFNBQWdCLE9BQU8sRUFBRSxPQUFPLENBQUM7SUFFakMsb0dBQW9HO0lBQ3BHLFNBQWdCLGFBQWEsRUFBRSxNQUFNLEdBQUcsU0FBUyxDQUFDO0lBRWxELDRFQUE0RTtJQUM1RSxTQUFnQixpQkFBaUIsRUFBRSxNQUFNLENBQUM7SUFFMUMsWUFDRSxJQUFJLEVBQUU7UUFDSixvQkFBb0IsRUFBRSxNQUFNLENBQUM7UUFDN0IsaUJBQWlCLEVBQUUsTUFBTSxDQUFDO1FBQzFCLGdCQUFnQixFQUFFLE1BQU0sQ0FBQztRQUN6QixrQkFBa0IsQ0FBQyxFQUFFLE1BQU0sQ0FBQztRQUM1QixlQUFlLENBQUMsRUFBRSxNQUFNLENBQUM7UUFDekIsT0FBTyxFQUFFLE9BQU8sQ0FBQztLQUNsQixFQUNnQixPQUFPLENBQUMsOEJBQWtCLEVBQzFCLEdBQUcsQ0FBQyxvQkFBUSxFQTJFOUI7SUFFTSxpQkFBaUIsQ0FDdEIsS0FBSyxFQUFFLE9BQU8sQ0FBQyxjQUFjLEVBQUUsY0FBYyxDQUFDLE9BQU8sR0FBRyxjQUFjLENBQUMsSUFBSSxHQUFHLGNBQWMsQ0FBQyxhQUFhLENBQUMsR0FDMUcsU0FBUyxDQUFDO0lBQ04saUJBQWlCLENBQ3RCLEtBQUssRUFBRSxPQUFPLENBQUMsY0FBYyxFQUFFLGNBQWMsQ0FBQyxPQUFPLEdBQUcsY0FBYyxDQUFDLElBQUksR0FBRyxjQUFjLENBQUMsYUFBYSxDQUFDLEdBQzFHLE1BQU0sQ0FBQztJQUNILGlCQUFpQixDQUFDLEtBQUssRUFBRSxjQUFjLEdBQUcsTUFBTSxHQUFHLFNBQVMsQ0FBQztJQTJCN0QsY0FBYyxDQUFDLFFBQVEsRUFBRSxjQUFjLEVBQUUsZUFBZSxFQUFFLE1BQU0sUUFpQnRFO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDSSxpQkFBaUIsQ0FDdEIsZUFBZSxFQUFFLE1BQU0sR0FFckI7UUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDO1FBQUMsUUFBUSxFQUFFLFNBQVMsQ0FBQztRQUFDLFdBQVcsRUFBRSxJQUFJLENBQUE7S0FBRSxHQUMxRDtRQUFFLFFBQVEsRUFBRSxLQUFLLENBQUM7UUFBQyxRQUFRLEVBQUUsU0FBUyxDQUFDO1FBQUMsV0FBVyxFQUFFLEtBQUssQ0FBQTtLQUFFLEdBQzVEO1FBQUUsUUFBUSxFQUFFLE9BQU8sQ0FBQztRQUFDLFFBQVEsRUFBRSxNQUFNLENBQUM7UUFBQyxXQUFXLEVBQUUsT0FBTyxDQUFBO0tBQUUsQ0F3RGhFO0NBQ0YifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timetable.d.ts","sourceRoot":"","sources":["../../src/sequencer/timetable.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"timetable.d.ts","sourceRoot":"","sources":["../../src/sequencer/timetable.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AASpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C,qBAAa,kBAAkB;IAqE3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;IACzB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;IArEvB;;;;OAIG;IACH,SAAgB,kBAAkB,EAAE,MAAM,CAAC;IAE3C;;;;OAIG;IACH,SAAgB,oBAAoB,EAAE,MAAM,CAAC;IAE7C;;;;;OAKG;IACH,SAAgB,0BAA0B,EAAE,MAAM,CAAC;IAEnD;;;;OAIG;IACH,SAAgB,gBAAgB,EAAE,MAAM,CAAC;IAEzC;;;OAGG;IACH,SAAgB,gBAAgB,EAAE,MAAM,CAAsB;IAE9D,uDAAuD;IACvD,SAAgB,4BAA4B,EAAE,MAAM,CAAkC;IAEtF,mGAAmG;IACnG,SAAgB,kBAAkB,EAAE,MAAM,CAAC;IAE3C,mFAAmF;IACnF,SAAgB,sBAAsB,EAAE,MAAM,CAA4B;IAE1E,wCAAwC;IACxC,SAAgB,oBAAoB,EAAE,MAAM,CAAC;IAE7C,kFAAkF;IAClF,SAAgB,iBAAiB,EAAE,MAAM,CAAC;IAE1C,4DAA4D;IAC5D,SAAgB,OAAO,EAAE,OAAO,CAAC;IAEjC,oGAAoG;IACpG,SAAgB,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAElD,4EAA4E;IAC5E,SAAgB,iBAAiB,EAAE,MAAM,CAAC;IAE1C,YACE,IAAI,EAAE;QACJ,oBAAoB,EAAE,MAAM,CAAC;QAC7B,iBAAiB,EAAE,MAAM,CAAC;QAC1B,gBAAgB,EAAE,MAAM,CAAC;QACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,OAAO,EAAE,OAAO,CAAC;KAClB,EACgB,OAAO,CAAC,8BAAkB,EAC1B,GAAG,CAAC,oBAAQ,EA2E9B;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;IA2B7D,cAAc,CAAC,QAAQ,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,QAiBtE;IAED;;;;;;;;OAQG;IACI,iBAAiB,CACtB,eAAe,EAAE,MAAM,GAErB;QAAE,QAAQ,EAAE,IAAI,CAAC;QAAC,QAAQ,EAAE,SAAS,CAAC;QAAC,WAAW,EAAE,IAAI,CAAA;KAAE,GAC1D;QAAE,QAAQ,EAAE,KAAK,CAAC;QAAC,QAAQ,EAAE,SAAS,CAAC;QAAC,WAAW,EAAE,KAAK,CAAA;KAAE,GAC5D;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,OAAO,CAAA;KAAE,CAwDhE;CACF"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { createLogger } from '@aztec/aztec.js/log';
|
|
2
1
|
import { CHECKPOINT_ASSEMBLE_TIME, CHECKPOINT_INITIALIZATION_TIME, DEFAULT_P2P_PROPAGATION_TIME, MIN_EXECUTION_TIME } from '@aztec/stdlib/timetable';
|
|
3
2
|
import { SequencerTooSlowError } from './errors.js';
|
|
4
3
|
import { SequencerState } from './utils.js';
|
|
@@ -38,7 +37,7 @@ export class SequencerTimetable {
|
|
|
38
37
|
/** Whether assertTimeLeft will throw if not enough time. */ enforce;
|
|
39
38
|
/** Duration per block when building multiple blocks per slot (undefined = single block per slot) */ blockDuration;
|
|
40
39
|
/** Maximum number of blocks that can be built in this slot configuration */ maxNumberOfBlocks;
|
|
41
|
-
constructor(opts, metrics, log
|
|
40
|
+
constructor(opts, metrics, log){
|
|
42
41
|
this.metrics = metrics;
|
|
43
42
|
this.log = log;
|
|
44
43
|
this.minExecutionTime = MIN_EXECUTION_TIME;
|
|
@@ -81,7 +80,7 @@ export class SequencerTimetable {
|
|
|
81
80
|
this.checkpointFinalizationTime;
|
|
82
81
|
const initializeDeadline = this.aztecSlotDuration - minWorkToDo;
|
|
83
82
|
this.initializeDeadline = initializeDeadline;
|
|
84
|
-
this.log
|
|
83
|
+
this.log?.info(`Sequencer timetable initialized with ${this.maxNumberOfBlocks} blocks per slot (${this.enforce ? 'enforced' : 'not enforced'})`, {
|
|
85
84
|
ethereumSlotDuration: this.ethereumSlotDuration,
|
|
86
85
|
aztecSlotDuration: this.aztecSlotDuration,
|
|
87
86
|
l1PublishingTime: this.l1PublishingTime,
|
|
@@ -138,7 +137,7 @@ export class SequencerTimetable {
|
|
|
138
137
|
throw new SequencerTooSlowError(newState, maxAllowedTime, secondsIntoSlot);
|
|
139
138
|
}
|
|
140
139
|
this.metrics?.recordStateTransitionBufferMs(Math.floor(bufferSeconds * 1000), newState);
|
|
141
|
-
this.log
|
|
140
|
+
this.log?.trace(`Enough time to transition to ${newState}`, {
|
|
142
141
|
maxAllowedTime,
|
|
143
142
|
secondsIntoSlot
|
|
144
143
|
});
|
|
@@ -172,7 +171,7 @@ export class SequencerTimetable {
|
|
|
172
171
|
const available = (maxAllowed - secondsIntoSlot) / 2; // Split remaining time: half for execution, half for re-execution
|
|
173
172
|
const canStart = available >= this.minExecutionTime;
|
|
174
173
|
const deadline = secondsIntoSlot + available;
|
|
175
|
-
this.log
|
|
174
|
+
this.log?.verbose(`${canStart ? 'Can' : 'Cannot'} start single-block checkpoint at ${secondsIntoSlot}s into slot`, {
|
|
176
175
|
secondsIntoSlot,
|
|
177
176
|
maxAllowed,
|
|
178
177
|
available,
|
|
@@ -194,7 +193,7 @@ export class SequencerTimetable {
|
|
|
194
193
|
if (timeUntilDeadline >= this.minExecutionTime) {
|
|
195
194
|
// Found an available sub-slot! Is this the last one?
|
|
196
195
|
const isLastBlock = subSlot === this.maxNumberOfBlocks;
|
|
197
|
-
this.log
|
|
196
|
+
this.log?.verbose(`Can start ${isLastBlock ? 'last block' : 'block'} in sub-slot ${subSlot} with deadline ${deadline}s`, {
|
|
198
197
|
secondsIntoSlot,
|
|
199
198
|
deadline,
|
|
200
199
|
timeUntilDeadline,
|
|
@@ -209,7 +208,7 @@ export class SequencerTimetable {
|
|
|
209
208
|
}
|
|
210
209
|
}
|
|
211
210
|
// No sub-slots available with enough time
|
|
212
|
-
this.log
|
|
211
|
+
this.log?.verbose(`No time left to start any more blocks`, {
|
|
213
212
|
secondsIntoSlot,
|
|
214
213
|
maxBlocks: this.maxNumberOfBlocks,
|
|
215
214
|
initializationOffset: this.initializationOffset
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
|
|
2
|
-
export type SequencerRollupConstants = Pick<L1RollupConstants, 'ethereumSlotDuration' | 'l1GenesisTime' | 'slotDuration'>;
|
|
3
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
2
|
+
export type SequencerRollupConstants = Pick<L1RollupConstants, 'ethereumSlotDuration' | 'l1GenesisTime' | 'slotDuration' | 'rollupManaLimit'>;
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXF1ZW5jZXIvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUVyRSxNQUFNLE1BQU0sd0JBQXdCLEdBQUcsSUFBSSxDQUN6QyxpQkFBaUIsRUFDakIsc0JBQXNCLEdBQUcsZUFBZSxHQUFHLGNBQWMsR0FBRyxpQkFBaUIsQ0FDOUUsQ0FBQyJ9
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sequencer/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAErE,MAAM,MAAM,wBAAwB,GAAG,IAAI,CACzC,iBAAiB,EACjB,sBAAsB,GAAG,eAAe,GAAG,cAAc,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sequencer/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAErE,MAAM,MAAM,wBAAwB,GAAG,IAAI,CACzC,iBAAiB,EACjB,sBAAsB,GAAG,eAAe,GAAG,cAAc,GAAG,iBAAiB,CAC9E,CAAC"}
|
package/dest/test/index.d.ts
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { L1TxUtils } from '@aztec/ethereum/l1-tx-utils';
|
|
2
2
|
import type { PublisherManager } from '@aztec/ethereum/publisher-manager';
|
|
3
3
|
import type { PublicProcessorFactory } from '@aztec/simulator/server';
|
|
4
4
|
import type { FullNodeCheckpointsBuilder, ValidatorClient } from '@aztec/validator-client';
|
|
5
5
|
import { SequencerClient } from '../client/sequencer-client.js';
|
|
6
6
|
import type { SequencerPublisherFactory } from '../publisher/sequencer-publisher-factory.js';
|
|
7
|
-
import type { SequencerPublisher } from '../publisher/sequencer-publisher.js';
|
|
8
7
|
import { Sequencer } from '../sequencer/sequencer.js';
|
|
9
8
|
import type { SequencerTimetable } from '../sequencer/timetable.js';
|
|
10
9
|
declare class TestSequencer_ extends Sequencer {
|
|
11
10
|
publicProcessorFactory: PublicProcessorFactory;
|
|
12
11
|
timetable: SequencerTimetable;
|
|
13
|
-
publisher: SequencerPublisher;
|
|
14
12
|
publisherFactory: SequencerPublisherFactory;
|
|
15
13
|
validatorClient: ValidatorClient;
|
|
16
14
|
checkpointsBuilder: FullNodeCheckpointsBuilder;
|
|
@@ -18,8 +16,8 @@ declare class TestSequencer_ extends Sequencer {
|
|
|
18
16
|
export type TestSequencer = TestSequencer_;
|
|
19
17
|
declare class TestSequencerClient_ extends SequencerClient {
|
|
20
18
|
sequencer: TestSequencer;
|
|
21
|
-
publisherManager: PublisherManager<
|
|
19
|
+
publisherManager: PublisherManager<L1TxUtils>;
|
|
22
20
|
}
|
|
23
21
|
export type TestSequencerClient = TestSequencerClient_;
|
|
24
22
|
export {};
|
|
25
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
23
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90ZXN0L2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQzdELE9BQU8sS0FBSyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDMUUsT0FBTyxLQUFLLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN0RSxPQUFPLEtBQUssRUFBRSwwQkFBMEIsRUFBRSxlQUFlLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUUzRixPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDaEUsT0FBTyxLQUFLLEVBQUUseUJBQXlCLEVBQUUsTUFBTSw2Q0FBNkMsQ0FBQztBQUM3RixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDdEQsT0FBTyxLQUFLLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUVwRSxjQUFNLGNBQWUsU0FBUSxTQUFTO0lBQ3JCLHNCQUFzQixFQUFFLHNCQUFzQixDQUFDO0lBQy9DLFNBQVMsRUFBRSxrQkFBa0IsQ0FBQztJQUM5QixnQkFBZ0IsRUFBRSx5QkFBeUIsQ0FBQztJQUM1QyxlQUFlLEVBQUUsZUFBZSxDQUFDO0lBQ2pDLGtCQUFrQixFQUFFLDBCQUEwQixDQUFDO0NBQy9EO0FBRUQsTUFBTSxNQUFNLGFBQWEsR0FBRyxjQUFjLENBQUM7QUFFM0MsY0FBTSxvQkFBcUIsU0FBUSxlQUFlO0lBQ2pDLFNBQVMsRUFBRSxhQUFhLENBQUM7SUFDekIsZ0JBQWdCLEVBQUUsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLENBQUM7Q0FDOUQ7QUFFRCxNQUFNLE1BQU0sbUJBQW1CLEdBQUcsb0JBQW9CLENBQUMifQ==
|
package/dest/test/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,KAAK,EAAE,0BAA0B,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE3F,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,6CAA6C,CAAC;AAC7F,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAEpE,cAAM,cAAe,SAAQ,SAAS;IACrB,sBAAsB,EAAE,sBAAsB,CAAC;IAC/C,SAAS,EAAE,kBAAkB,CAAC;IAC9B,gBAAgB,EAAE,yBAAyB,CAAC;IAC5C,eAAe,EAAE,eAAe,CAAC;IACjC,kBAAkB,EAAE,0BAA0B,CAAC;CAC/D;AAED,MAAM,MAAM,aAAa,GAAG,cAAc,CAAC;AAE3C,cAAM,oBAAqB,SAAQ,eAAe;IACjC,SAAS,EAAE,aAAa,CAAC;IACzB,gBAAgB,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC;CAC9D;AAED,MAAM,MAAM,mBAAmB,GAAG,oBAAoB,CAAC"}
|