@aztec/sequencer-client 0.0.1-commit.e588bc7e5 → 0.0.1-commit.e5a3663dd
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 +3 -1
- package/dest/client/sequencer-client.d.ts.map +1 -1
- package/dest/client/sequencer-client.js +3 -4
- package/dest/config.d.ts +2 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +16 -14
- package/dest/global_variable_builder/fee_predictor.d.ts +37 -0
- package/dest/global_variable_builder/fee_predictor.d.ts.map +1 -0
- package/dest/global_variable_builder/fee_predictor.js +128 -0
- package/dest/global_variable_builder/fee_provider.d.ts +21 -0
- package/dest/global_variable_builder/fee_provider.d.ts.map +1 -0
- package/dest/global_variable_builder/fee_provider.js +58 -0
- package/dest/global_variable_builder/global_builder.d.ts +4 -9
- package/dest/global_variable_builder/global_builder.d.ts.map +1 -1
- package/dest/global_variable_builder/global_builder.js +3 -41
- package/dest/global_variable_builder/index.d.ts +3 -1
- package/dest/global_variable_builder/index.d.ts.map +1 -1
- package/dest/global_variable_builder/index.js +2 -0
- package/dest/publisher/config.d.ts +1 -1
- package/dest/publisher/config.d.ts.map +1 -1
- package/dest/publisher/config.js +2 -2
- package/dest/publisher/l1_tx_failed_store/failed_tx_store.d.ts +3 -4
- package/dest/publisher/l1_tx_failed_store/failed_tx_store.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher-factory.d.ts +1 -3
- package/dest/publisher/sequencer-publisher-factory.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher-factory.js +0 -1
- package/dest/publisher/sequencer-publisher.d.ts +16 -35
- package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher.js +62 -94
- package/dest/sequencer/chain_state_overrides.d.ts +25 -0
- package/dest/sequencer/chain_state_overrides.d.ts.map +1 -0
- package/dest/sequencer/chain_state_overrides.js +39 -0
- package/dest/sequencer/checkpoint_proposal_job.d.ts +33 -22
- package/dest/sequencer/checkpoint_proposal_job.d.ts.map +1 -1
- package/dest/sequencer/checkpoint_proposal_job.js +479 -170
- package/dest/sequencer/checkpoint_proposal_job_metrics.d.ts +34 -0
- package/dest/sequencer/checkpoint_proposal_job_metrics.d.ts.map +1 -0
- package/dest/sequencer/checkpoint_proposal_job_metrics.js +72 -0
- package/dest/sequencer/events.d.ts +6 -1
- package/dest/sequencer/events.d.ts.map +1 -1
- package/dest/sequencer/metrics.d.ts +9 -10
- package/dest/sequencer/metrics.d.ts.map +1 -1
- package/dest/sequencer/metrics.js +34 -20
- package/dest/sequencer/sequencer.d.ts +16 -5
- package/dest/sequencer/sequencer.d.ts.map +1 -1
- package/dest/sequencer/sequencer.js +63 -30
- package/dest/sequencer/timetable.d.ts +14 -1
- package/dest/sequencer/timetable.d.ts.map +1 -1
- package/dest/sequencer/timetable.js +45 -36
- package/dest/test/utils.d.ts +1 -1
- package/dest/test/utils.d.ts.map +1 -1
- package/dest/test/utils.js +7 -6
- package/package.json +27 -27
- package/src/client/sequencer-client.ts +5 -7
- package/src/config.ts +15 -11
- package/src/global_variable_builder/README.md +44 -0
- package/src/global_variable_builder/fee_predictor.ts +172 -0
- package/src/global_variable_builder/fee_provider.ts +75 -0
- package/src/global_variable_builder/global_builder.ts +7 -54
- package/src/global_variable_builder/index.ts +2 -0
- package/src/publisher/config.ts +6 -4
- package/src/publisher/l1_tx_failed_store/failed_tx_store.ts +3 -1
- package/src/publisher/sequencer-publisher-factory.ts +0 -3
- package/src/publisher/sequencer-publisher.ts +108 -156
- package/src/sequencer/README.md +82 -13
- package/src/sequencer/chain_state_overrides.ts +87 -0
- package/src/sequencer/checkpoint_proposal_job.ts +572 -218
- package/src/sequencer/checkpoint_proposal_job_metrics.ts +128 -0
- package/src/sequencer/events.ts +5 -0
- package/src/sequencer/metrics.ts +43 -24
- package/src/sequencer/sequencer.ts +81 -35
- package/src/sequencer/timetable.ts +57 -45
- package/src/test/utils.ts +28 -10
|
@@ -373,7 +373,7 @@ function _apply_decs_2203_r(targetClass, memberDecs, classDecs, parentClass) {
|
|
|
373
373
|
var _dec, _dec1, _dec2, _dec3, _initProto;
|
|
374
374
|
import { getKzg } from '@aztec/blob-lib';
|
|
375
375
|
import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
|
|
376
|
-
import { NoCommitteeError } from '@aztec/ethereum/contracts';
|
|
376
|
+
import { NoCommitteeError, SimulationOverridesBuilder } from '@aztec/ethereum/contracts';
|
|
377
377
|
import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types';
|
|
378
378
|
import { merge, omit, pick } from '@aztec/foundation/collection';
|
|
379
379
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
@@ -388,6 +388,7 @@ import { Attributes, getTelemetryClient, trackSpan } from '@aztec/telemetry-clie
|
|
|
388
388
|
import EventEmitter from 'node:events';
|
|
389
389
|
import { DefaultSequencerConfig } from '../config.js';
|
|
390
390
|
import { CheckpointProposalJob } from './checkpoint_proposal_job.js';
|
|
391
|
+
import { CheckpointProposalJobMetrics } from './checkpoint_proposal_job_metrics.js';
|
|
391
392
|
import { CheckpointVoter } from './checkpoint_voter.js';
|
|
392
393
|
import { SequencerInterruptedError, SequencerTooSlowError } from './errors.js';
|
|
393
394
|
import { SequencerMetrics } from './metrics.js';
|
|
@@ -448,7 +449,11 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
448
449
|
}
|
|
449
450
|
runningPromise;
|
|
450
451
|
state;
|
|
452
|
+
stateSlotNumber;
|
|
453
|
+
stateEnteredAtMs;
|
|
451
454
|
metrics;
|
|
455
|
+
checkpointProposalJobMetrics;
|
|
456
|
+
stateLog;
|
|
452
457
|
/** The last slot for which we attempted to perform our voting duties with degraded block production */ lastSlotForFallbackVote;
|
|
453
458
|
/** The last slot for which we logged "no committee" warning, to avoid spam */ lastSlotForNoCommitteeWarning;
|
|
454
459
|
/** The last slot for which we triggered a checkpoint proposal job, to prevent duplicate attempts. */ lastSlotForCheckpointProposalJob;
|
|
@@ -457,26 +462,35 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
457
462
|
/** The last checkpoint proposal job, tracked so we can await its pending L1 submission during shutdown. */ lastCheckpointProposalJob;
|
|
458
463
|
/** The maximum number of seconds that the sequencer can be into a slot to transition to a particular state. */ timetable;
|
|
459
464
|
/** Config for the sequencer */ config;
|
|
465
|
+
signatureContext;
|
|
460
466
|
constructor(publisherFactory, validatorClient, globalsBuilder, p2pClient, worldState, slasherClient, l2BlockSource, l1ToL2MessageSource, checkpointsBuilder, l1Constants, dateProvider, epochCache, rollupContract, config, telemetry = getTelemetryClient(), log = createLogger('sequencer')){
|
|
461
|
-
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;
|
|
467
|
+
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.stateEnteredAtMs = performance.now(), this.config = DefaultSequencerConfig;
|
|
468
|
+
this.stateLog = log.createChild('state');
|
|
462
469
|
// Add [FISHERMAN] prefix to logger if in fisherman mode
|
|
463
470
|
if (config.fishermanMode) {
|
|
464
471
|
this.log = log.createChild('[FISHERMAN]');
|
|
465
472
|
}
|
|
473
|
+
this.signatureContext = {
|
|
474
|
+
chainId: config.l1ChainId,
|
|
475
|
+
rollupAddress: config.l1Contracts.rollupAddress
|
|
476
|
+
};
|
|
466
477
|
this.metrics = new SequencerMetrics(telemetry, this.rollupContract, 'Sequencer');
|
|
478
|
+
this.checkpointProposalJobMetrics = new CheckpointProposalJobMetrics(telemetry);
|
|
467
479
|
this.updateConfig(config);
|
|
468
480
|
}
|
|
469
481
|
/** Updates sequencer config by the defined values and updates the timetable */ updateConfig(config) {
|
|
470
482
|
const filteredConfig = pickFromSchema(config, SequencerConfigSchema);
|
|
471
483
|
this.log.info(`Updated sequencer config`, omit(filteredConfig, 'txPublicSetupAllowListExtend'));
|
|
472
484
|
this.config = merge(this.config, filteredConfig);
|
|
485
|
+
const p2pPropagationTime = this.config.attestationPropagationTime;
|
|
473
486
|
this.timetable = new SequencerTimetable({
|
|
474
487
|
ethereumSlotDuration: this.l1Constants.ethereumSlotDuration,
|
|
475
488
|
aztecSlotDuration: this.aztecSlotDuration,
|
|
476
489
|
l1PublishingTime: this.l1PublishingTime,
|
|
477
|
-
p2pPropagationTime
|
|
490
|
+
p2pPropagationTime,
|
|
478
491
|
blockDurationMs: this.config.blockDurationMs,
|
|
479
|
-
enforce: this.config.enforceTimeTable
|
|
492
|
+
enforce: this.config.enforceTimeTable,
|
|
493
|
+
pipelining: this.epochCache.isProposerPipeliningEnabled()
|
|
480
494
|
}, this.metrics, this.log);
|
|
481
495
|
}
|
|
482
496
|
/** Initializes the sequencer (precomputes tables). Takes about 3s. */ init() {
|
|
@@ -490,6 +504,9 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
490
504
|
this.runningPromise.start();
|
|
491
505
|
this.log.info('Started sequencer');
|
|
492
506
|
}
|
|
507
|
+
/** Triggers an immediate run of the sequencer, bypassing the polling interval. */ trigger() {
|
|
508
|
+
return this.runningPromise?.trigger();
|
|
509
|
+
}
|
|
493
510
|
/** Stops the sequencer from building blocks and moves to STOPPED state. */ async stop() {
|
|
494
511
|
this.log.info(`Stopping sequencer`);
|
|
495
512
|
this.setState(SequencerState.STOPPING, undefined, {
|
|
@@ -616,13 +633,6 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
616
633
|
}
|
|
617
634
|
// Next checkpoint follows from the last synced one
|
|
618
635
|
const checkpointNumber = CheckpointNumber(syncedTo.checkpointNumber + 1);
|
|
619
|
-
// Guard: don't exceed 1-deep pipeline. Without a proposed checkpoint, we can only build
|
|
620
|
-
// confirmed + 1. With a proposed checkpoint, we can build confirmed + 2.
|
|
621
|
-
const confirmedCkpt = syncedTo.checkpointedCheckpointNumber;
|
|
622
|
-
if (checkpointNumber > confirmedCkpt + 2) {
|
|
623
|
-
this.log.warn(`Skipping slot ${targetSlot}: checkpoint ${checkpointNumber} exceeds max pipeline depth (confirmed=${confirmedCkpt})`);
|
|
624
|
-
return undefined;
|
|
625
|
-
}
|
|
626
636
|
const logCtx = {
|
|
627
637
|
nowSeconds,
|
|
628
638
|
syncedToL2Slot: syncedTo.syncedL2Slot,
|
|
@@ -640,6 +650,13 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
640
650
|
await this.considerInvalidatingCheckpoint(syncedTo, slot);
|
|
641
651
|
return undefined;
|
|
642
652
|
}
|
|
653
|
+
// Guard: don't exceed 1-deep pipeline. Without a proposed checkpoint, we can only build
|
|
654
|
+
// confirmed + 1. With a proposed checkpoint, we can build confirmed + 2.
|
|
655
|
+
const confirmedCkpt = syncedTo.checkpointedCheckpointNumber;
|
|
656
|
+
if (checkpointNumber > confirmedCkpt + 2) {
|
|
657
|
+
this.log.verbose(`Skipping slot ${targetSlot}: checkpoint ${checkpointNumber} exceeds max pipeline depth (confirmed=${confirmedCkpt})`);
|
|
658
|
+
return undefined;
|
|
659
|
+
}
|
|
643
660
|
// Check that the target slot is not taken by a block already (should never happen, since only us can propose for this slot)
|
|
644
661
|
if (syncedTo.blockData && syncedTo.blockData.header.getSlot() >= targetSlot) {
|
|
645
662
|
this.log.warn(`Cannot propose block at target slot ${targetSlot} since that slot was taken by block ${syncedTo.blockNumber}`, {
|
|
@@ -667,17 +684,13 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
667
684
|
// The L1 contract reads archives[proposedCheckpointNumber] and compares it with the provided archive.
|
|
668
685
|
// When invalidating or pipelining, the local archive may differ from L1's, so we adjust accordingly.
|
|
669
686
|
let archiveForCheck = syncedTo.archive;
|
|
670
|
-
const
|
|
687
|
+
const l1SimulationOverridesBuilder = new SimulationOverridesBuilder();
|
|
671
688
|
if (this.epochCache.isProposerPipeliningEnabled() && syncedTo.hasProposedCheckpoint) {
|
|
672
689
|
// Parent checkpoint hasn't landed on L1 yet. Override both the proposed checkpoint number
|
|
673
690
|
// and the archive at that checkpoint so L1 simulation sees the correct chain tip.
|
|
674
691
|
const parentCheckpointNumber = CheckpointNumber(checkpointNumber - 1);
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
checkpointNumber: parentCheckpointNumber,
|
|
678
|
-
archive: syncedTo.archive
|
|
679
|
-
};
|
|
680
|
-
this.metrics.recordPipelineDepth(1);
|
|
692
|
+
l1SimulationOverridesBuilder.forPendingCheckpoint(parentCheckpointNumber).withPendingArchive(syncedTo.archive);
|
|
693
|
+
this.metrics.recordPipelineDepth(syncedTo.checkpointNumber - syncedTo.checkpointedCheckpointNumber);
|
|
681
694
|
this.log.verbose(`Building on top of proposed checkpoint (pending=${syncedTo.proposedCheckpointData?.checkpointNumber})`);
|
|
682
695
|
// Clear the invalidation - the proposed checkpoint should handle it.
|
|
683
696
|
invalidateCheckpoint = undefined;
|
|
@@ -685,12 +698,13 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
685
698
|
// After invalidation, L1 will roll back to checkpoint N-1. The archive at N-1 already
|
|
686
699
|
// exists on L1, so we just pass the matching archive (the lastArchive of the invalid checkpoint).
|
|
687
700
|
archiveForCheck = invalidateCheckpoint.lastArchive;
|
|
688
|
-
|
|
701
|
+
l1SimulationOverridesBuilder.forPendingCheckpoint(invalidateCheckpoint.forcePendingCheckpointNumber);
|
|
689
702
|
this.metrics.recordPipelineDepth(0);
|
|
690
703
|
} else {
|
|
691
704
|
this.metrics.recordPipelineDepth(0);
|
|
692
705
|
}
|
|
693
|
-
const
|
|
706
|
+
const simulationOverridesPlan = l1SimulationOverridesBuilder.build();
|
|
707
|
+
const canProposeCheck = await publisher.canProposeAt(archiveForCheck, proposer ?? EthAddress.ZERO, simulationOverridesPlan);
|
|
694
708
|
if (canProposeCheck === undefined) {
|
|
695
709
|
this.log.warn(`Cannot propose checkpoint ${checkpointNumber} at slot ${slot} due to failed rollup contract check`, logCtx);
|
|
696
710
|
this.emit('proposer-rollup-check-failed', {
|
|
@@ -737,7 +751,7 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
737
751
|
return this.createCheckpointProposalJob(slot, targetSlot, targetEpoch, checkpointNumber, syncedTo.blockNumber, proposer, publisher, attestorAddress, invalidateCheckpoint, syncedTo.proposedCheckpointData);
|
|
738
752
|
}
|
|
739
753
|
createCheckpointProposalJob(slot, targetSlot, targetEpoch, checkpointNumber, syncedToBlockNumber, proposer, publisher, attestorAddress, invalidateCheckpoint, proposedCheckpointData) {
|
|
740
|
-
return new CheckpointProposalJob(slot, targetSlot, 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(), proposedCheckpointData);
|
|
754
|
+
return new CheckpointProposalJob(slot, targetSlot, 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.signatureContext, this.config, this.timetable, this.slasherClient, this.epochCache, this.dateProvider, this.metrics, this.checkpointProposalJobMetrics.createRecorder(), this, this.setState.bind(this), this.tracer, this.log.getBindings(), proposedCheckpointData);
|
|
741
755
|
}
|
|
742
756
|
/**
|
|
743
757
|
* Returns the current sequencer state.
|
|
@@ -763,21 +777,37 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
763
777
|
secondsIntoSlot = this.getSecondsIntoSlot(slotNumber);
|
|
764
778
|
this.timetable.assertTimeLeft(proposedState, secondsIntoSlot);
|
|
765
779
|
}
|
|
780
|
+
const oldState = this.state;
|
|
781
|
+
const oldStateSlotNumber = this.stateSlotNumber;
|
|
782
|
+
const stateChanged = proposedState !== oldState;
|
|
783
|
+
const transitionAtMs = performance.now();
|
|
784
|
+
const stateDurationMs = transitionAtMs - this.stateEnteredAtMs;
|
|
766
785
|
const boringStates = [
|
|
767
786
|
SequencerState.IDLE,
|
|
768
787
|
SequencerState.SYNCHRONIZING
|
|
769
788
|
];
|
|
770
|
-
const logLevel = boringStates.includes(proposedState) && boringStates.includes(
|
|
771
|
-
this.
|
|
789
|
+
const logLevel = boringStates.includes(proposedState) && boringStates.includes(oldState) ? 'trace' : 'debug';
|
|
790
|
+
this.stateLog[logLevel](`Transitioning from ${oldState} to ${proposedState}`, {
|
|
791
|
+
oldState,
|
|
792
|
+
newState: proposedState,
|
|
772
793
|
slotNumber,
|
|
773
|
-
|
|
794
|
+
stateSlotNumber: oldStateSlotNumber,
|
|
795
|
+
secondsIntoSlot,
|
|
796
|
+
...stateChanged && {
|
|
797
|
+
stateDurationMs: Math.ceil(stateDurationMs)
|
|
798
|
+
}
|
|
774
799
|
});
|
|
775
800
|
this.emit('state-changed', {
|
|
776
|
-
oldState
|
|
801
|
+
oldState,
|
|
777
802
|
newState: proposedState,
|
|
778
803
|
secondsIntoSlot,
|
|
779
804
|
slot: slotNumber
|
|
780
805
|
});
|
|
806
|
+
if (stateChanged) {
|
|
807
|
+
this.metrics.recordStateDuration(stateDurationMs, oldState);
|
|
808
|
+
this.stateEnteredAtMs = transitionAtMs;
|
|
809
|
+
this.stateSlotNumber = slotNumber;
|
|
810
|
+
}
|
|
781
811
|
this.state = proposedState;
|
|
782
812
|
}
|
|
783
813
|
/**
|
|
@@ -807,21 +837,24 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
807
837
|
proposedCheckpoint: t.proposedCheckpoint
|
|
808
838
|
})),
|
|
809
839
|
this.p2pClient.getStatus().then((p2p)=>p2p.syncedToL2Block),
|
|
810
|
-
this.l1ToL2MessageSource.getL2Tips().then((t)=>
|
|
840
|
+
this.l1ToL2MessageSource.getL2Tips().then((t)=>({
|
|
841
|
+
proposed: t.proposed,
|
|
842
|
+
checkpointed: t.checkpointed
|
|
843
|
+
})),
|
|
811
844
|
this.l2BlockSource.getPendingChainValidationStatus(),
|
|
812
|
-
this.l2BlockSource.
|
|
845
|
+
this.l2BlockSource.getLastProposedCheckpoint()
|
|
813
846
|
]);
|
|
814
|
-
const [worldState, l2Tips, p2p,
|
|
847
|
+
const [worldState, l2Tips, p2p, l1ToL2MessageSourceTips, pendingChainValidationStatus, proposedCheckpointData] = syncedBlocks;
|
|
815
848
|
// Handle zero as a special case, since the block hash won't match across services if we're changing the prefilled data for the genesis block,
|
|
816
849
|
// as the world state can compute the new genesis block hash, but other components use the hardcoded constant.
|
|
817
850
|
// TODO(palla/mbps): Fix the above. All components should be able to handle dynamic genesis block hashes.
|
|
818
|
-
const result = l2Tips.proposed.number === 0 && worldState.number === 0 && p2p.number === 0 &&
|
|
851
|
+
const result = l2Tips.proposed.number === 0 && l2Tips.checkpointed.block.number === 0 && l2Tips.checkpointed.checkpoint.number === 0 && worldState.number === 0 && p2p.number === 0 && l1ToL2MessageSourceTips.proposed.number === 0 && l1ToL2MessageSourceTips.checkpointed.block.number === 0 && l1ToL2MessageSourceTips.checkpointed.checkpoint.number === 0 || worldState.hash === l2Tips.proposed.hash && p2p.hash === l2Tips.proposed.hash && l1ToL2MessageSourceTips.proposed.hash === l2Tips.proposed.hash && l1ToL2MessageSourceTips.checkpointed.block.hash === l2Tips.checkpointed.block.hash && l1ToL2MessageSourceTips.checkpointed.checkpoint.hash === l2Tips.checkpointed.checkpoint.hash;
|
|
819
852
|
if (!result) {
|
|
820
853
|
this.log.debug(`Sequencer sync check failed`, {
|
|
821
854
|
worldState,
|
|
822
855
|
l2BlockSource: l2Tips.proposed,
|
|
823
856
|
p2p,
|
|
824
|
-
|
|
857
|
+
l1ToL2MessageSourceTips
|
|
825
858
|
});
|
|
826
859
|
return undefined;
|
|
827
860
|
}
|
|
@@ -4,6 +4,7 @@ import { SequencerState } from './utils.js';
|
|
|
4
4
|
export declare class SequencerTimetable {
|
|
5
5
|
private readonly metrics?;
|
|
6
6
|
private readonly log?;
|
|
7
|
+
private readonly checkpointTiming;
|
|
7
8
|
/**
|
|
8
9
|
* How late into the slot can we be to start working. Computed as the total time needed for assembling and publishing a block,
|
|
9
10
|
* assuming an execution time equal to `minExecutionTime`, subtracted from the slot duration. This means that, if the proposer
|
|
@@ -50,6 +51,13 @@ export declare class SequencerTimetable {
|
|
|
50
51
|
readonly blockDuration: number | undefined;
|
|
51
52
|
/** Maximum number of blocks that can be built in this slot configuration */
|
|
52
53
|
readonly maxNumberOfBlocks: number;
|
|
54
|
+
/** Whether pipelining is enabled (checkpoint finalization deferred to next slot). */
|
|
55
|
+
readonly pipelining: boolean;
|
|
56
|
+
/**
|
|
57
|
+
* How far into the target slot attestation collection can extend when pipelining.
|
|
58
|
+
* Covers validator re-execution (one block duration) plus one-way attestation return.
|
|
59
|
+
*/
|
|
60
|
+
readonly pipeliningAttestationGracePeriod: number;
|
|
53
61
|
constructor(opts: {
|
|
54
62
|
ethereumSlotDuration: number;
|
|
55
63
|
aztecSlotDuration: number;
|
|
@@ -57,7 +65,12 @@ export declare class SequencerTimetable {
|
|
|
57
65
|
p2pPropagationTime?: number;
|
|
58
66
|
blockDurationMs?: number;
|
|
59
67
|
enforce: boolean;
|
|
68
|
+
pipelining?: boolean;
|
|
60
69
|
}, metrics?: SequencerMetrics | undefined, log?: Logger | undefined);
|
|
70
|
+
getCheckpointAssemblyDeadline(): number;
|
|
71
|
+
getCheckpointAttestationDeadline(): number;
|
|
72
|
+
getCheckpointAttestationStartDeadline(): number;
|
|
73
|
+
getCheckpointPublishingDeadline(): number;
|
|
61
74
|
getMaxAllowedTime(state: Extract<SequencerState, SequencerState.STOPPED | SequencerState.IDLE | SequencerState.SYNCHRONIZING>): undefined;
|
|
62
75
|
getMaxAllowedTime(state: Exclude<SequencerState, SequencerState.STOPPED | SequencerState.IDLE | SequencerState.SYNCHRONIZING>): number;
|
|
63
76
|
getMaxAllowedTime(state: SequencerState): number | undefined;
|
|
@@ -85,4 +98,4 @@ export declare class SequencerTimetable {
|
|
|
85
98
|
isLastBlock: boolean;
|
|
86
99
|
};
|
|
87
100
|
}
|
|
88
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
101
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZXRhYmxlLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VxdWVuY2VyL3RpbWV0YWJsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQVdwRCxPQUFPLEtBQUssRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUNyRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRTVDLHFCQUFhLGtCQUFrQjtJQWlGM0IsT0FBTyxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUM7SUFDekIsT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUM7SUFqRnZCLE9BQU8sQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLENBQW1CO0lBRXBEOzs7O09BSUc7SUFDSCxTQUFnQixrQkFBa0IsRUFBRSxNQUFNLENBQUM7SUFFM0M7Ozs7T0FJRztJQUNILFNBQWdCLG9CQUFvQixFQUFFLE1BQU0sQ0FBQztJQUU3Qzs7Ozs7T0FLRztJQUNILFNBQWdCLDBCQUEwQixFQUFFLE1BQU0sQ0FBQztJQUVuRDs7OztPQUlHO0lBQ0gsU0FBZ0IsZ0JBQWdCLEVBQUUsTUFBTSxDQUFDO0lBRXpDOzs7T0FHRztJQUNILFNBQWdCLGdCQUFnQixFQUFFLE1BQU0sQ0FBc0I7SUFFOUQsdURBQXVEO0lBQ3ZELFNBQWdCLDRCQUE0QixFQUFFLE1BQU0sQ0FBa0M7SUFFdEYsbUdBQW1HO0lBQ25HLFNBQWdCLGtCQUFrQixFQUFFLE1BQU0sQ0FBQztJQUUzQyxtRkFBbUY7SUFDbkYsU0FBZ0Isc0JBQXNCLEVBQUUsTUFBTSxDQUE0QjtJQUUxRSx3Q0FBd0M7SUFDeEMsU0FBZ0Isb0JBQW9CLEVBQUUsTUFBTSxDQUFDO0lBRTdDLGtGQUFrRjtJQUNsRixTQUFnQixpQkFBaUIsRUFBRSxNQUFNLENBQUM7SUFFMUMsNERBQTREO0lBQzVELFNBQWdCLE9BQU8sRUFBRSxPQUFPLENBQUM7SUFFakMsb0dBQW9HO0lBQ3BHLFNBQWdCLGFBQWEsRUFBRSxNQUFNLEdBQUcsU0FBUyxDQUFDO0lBRWxELDRFQUE0RTtJQUM1RSxTQUFnQixpQkFBaUIsRUFBRSxNQUFNLENBQUM7SUFFMUMscUZBQXFGO0lBQ3JGLFNBQWdCLFVBQVUsRUFBRSxPQUFPLENBQUM7SUFFcEM7OztPQUdHO0lBQ0gsU0FBZ0IsZ0NBQWdDLEVBQUUsTUFBTSxDQUFDO0lBRXpELFlBQ0UsSUFBSSxFQUFFO1FBQ0osb0JBQW9CLEVBQUUsTUFBTSxDQUFDO1FBQzdCLGlCQUFpQixFQUFFLE1BQU0sQ0FBQztRQUMxQixnQkFBZ0IsRUFBRSxNQUFNLENBQUM7UUFDekIsa0JBQWtCLENBQUMsRUFBRSxNQUFNLENBQUM7UUFDNUIsZUFBZSxDQUFDLEVBQUUsTUFBTSxDQUFDO1FBQ3pCLE9BQU8sRUFBRSxPQUFPLENBQUM7UUFDakIsVUFBVSxDQUFDLEVBQUUsT0FBTyxDQUFDO0tBQ3RCLEVBQ2dCLE9BQU8sQ0FBQyw4QkFBa0IsRUFDMUIsR0FBRyxDQUFDLG9CQUFRLEVBd0Q5QjtJQUVNLDZCQUE2QixJQUFJLE1BQU0sQ0FFN0M7SUFFTSxnQ0FBZ0MsSUFBSSxNQUFNLENBRWhEO0lBRU0scUNBQXFDLElBQUksTUFBTSxDQUVyRDtJQUVNLCtCQUErQixJQUFJLE1BQU0sQ0FFL0M7SUFFTSxpQkFBaUIsQ0FDdEIsS0FBSyxFQUFFLE9BQU8sQ0FBQyxjQUFjLEVBQUUsY0FBYyxDQUFDLE9BQU8sR0FBRyxjQUFjLENBQUMsSUFBSSxHQUFHLGNBQWMsQ0FBQyxhQUFhLENBQUMsR0FDMUcsU0FBUyxDQUFDO0lBQ04saUJBQWlCLENBQ3RCLEtBQUssRUFBRSxPQUFPLENBQUMsY0FBYyxFQUFFLGNBQWMsQ0FBQyxPQUFPLEdBQUcsY0FBYyxDQUFDLElBQUksR0FBRyxjQUFjLENBQUMsYUFBYSxDQUFDLEdBQzFHLE1BQU0sQ0FBQztJQUNILGlCQUFpQixDQUFDLEtBQUssRUFBRSxjQUFjLEdBQUcsTUFBTSxHQUFHLFNBQVMsQ0FBQztJQTRCN0QsY0FBYyxDQUFDLFFBQVEsRUFBRSxjQUFjLEVBQUUsZUFBZSxFQUFFLE1BQU0sUUFpQnRFO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDSSxpQkFBaUIsQ0FDdEIsZUFBZSxFQUFFLE1BQU0sR0FFckI7UUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDO1FBQUMsUUFBUSxFQUFFLFNBQVMsQ0FBQztRQUFDLFdBQVcsRUFBRSxJQUFJLENBQUE7S0FBRSxHQUMxRDtRQUFFLFFBQVEsRUFBRSxLQUFLLENBQUM7UUFBQyxRQUFRLEVBQUUsU0FBUyxDQUFDO1FBQUMsV0FBVyxFQUFFLEtBQUssQ0FBQTtLQUFFLEdBQzVEO1FBQUUsUUFBUSxFQUFFLE9BQU8sQ0FBQztRQUFDLFFBQVEsRUFBRSxNQUFNLENBQUM7UUFBQyxXQUFXLEVBQUUsT0FBTyxDQUFBO0tBQUUsQ0F3RGhFO0NBQ0YifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timetable.d.ts","sourceRoot":"","sources":["../../src/sequencer/timetable.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"timetable.d.ts","sourceRoot":"","sources":["../../src/sequencer/timetable.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { CHECKPOINT_ASSEMBLE_TIME, CHECKPOINT_INITIALIZATION_TIME, DEFAULT_P2P_PROPAGATION_TIME, MIN_EXECUTION_TIME } from '@aztec/stdlib/timetable';
|
|
1
|
+
import { CHECKPOINT_ASSEMBLE_TIME, CHECKPOINT_INITIALIZATION_TIME, DEFAULT_P2P_PROPAGATION_TIME, MIN_EXECUTION_TIME, createCheckpointTimingModel } from '@aztec/stdlib/timetable';
|
|
2
2
|
import { SequencerTooSlowError } from './errors.js';
|
|
3
3
|
import { SequencerState } from './utils.js';
|
|
4
4
|
export class SequencerTimetable {
|
|
5
5
|
metrics;
|
|
6
6
|
log;
|
|
7
|
+
checkpointTiming;
|
|
7
8
|
/**
|
|
8
9
|
* How late into the slot can we be to start working. Computed as the total time needed for assembling and publishing a block,
|
|
9
10
|
* assuming an execution time equal to `minExecutionTime`, subtracted from the slot duration. This means that, if the proposer
|
|
@@ -37,6 +38,11 @@ export class SequencerTimetable {
|
|
|
37
38
|
/** Whether assertTimeLeft will throw if not enough time. */ enforce;
|
|
38
39
|
/** Duration per block when building multiple blocks per slot (undefined = single block per slot) */ blockDuration;
|
|
39
40
|
/** Maximum number of blocks that can be built in this slot configuration */ maxNumberOfBlocks;
|
|
41
|
+
/** Whether pipelining is enabled (checkpoint finalization deferred to next slot). */ pipelining;
|
|
42
|
+
/**
|
|
43
|
+
* How far into the target slot attestation collection can extend when pipelining.
|
|
44
|
+
* Covers validator re-execution (one block duration) plus one-way attestation return.
|
|
45
|
+
*/ pipeliningAttestationGracePeriod;
|
|
40
46
|
constructor(opts, metrics, log){
|
|
41
47
|
this.metrics = metrics;
|
|
42
48
|
this.log = log;
|
|
@@ -46,40 +52,28 @@ export class SequencerTimetable {
|
|
|
46
52
|
this.ethereumSlotDuration = opts.ethereumSlotDuration;
|
|
47
53
|
this.aztecSlotDuration = opts.aztecSlotDuration;
|
|
48
54
|
this.l1PublishingTime = opts.l1PublishingTime;
|
|
49
|
-
this.p2pPropagationTime = opts.p2pPropagationTime ?? DEFAULT_P2P_PROPAGATION_TIME;
|
|
50
55
|
this.blockDuration = opts.blockDurationMs ? opts.blockDurationMs / 1000 : undefined;
|
|
51
56
|
this.enforce = opts.enforce;
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
this.
|
|
55
|
-
this.
|
|
56
|
-
this.
|
|
57
|
-
this.
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
57
|
+
this.pipelining = opts.pipelining ?? false;
|
|
58
|
+
this.checkpointTiming = createCheckpointTimingModel({
|
|
59
|
+
aztecSlotDuration: this.aztecSlotDuration,
|
|
60
|
+
ethereumSlotDuration: this.ethereumSlotDuration,
|
|
61
|
+
blockDuration: this.blockDuration,
|
|
62
|
+
l1PublishingTime: this.l1PublishingTime,
|
|
63
|
+
p2pPropagationTime: opts.p2pPropagationTime ?? DEFAULT_P2P_PROPAGATION_TIME,
|
|
64
|
+
pipelining: this.pipelining
|
|
65
|
+
});
|
|
66
|
+
this.p2pPropagationTime = this.checkpointTiming.p2pPropagationTime;
|
|
67
|
+
this.checkpointAssembleTime = this.checkpointTiming.checkpointAssembleTime;
|
|
68
|
+
this.checkpointInitializationTime = this.checkpointTiming.checkpointInitializationTime;
|
|
69
|
+
this.minExecutionTime = this.checkpointTiming.minExecutionTime;
|
|
63
70
|
// Calculate initialization offset - estimate of time needed for sync + proposer check
|
|
64
71
|
// This is the baseline for all sub-slot deadlines
|
|
65
|
-
this.initializationOffset = this.checkpointInitializationTime;
|
|
66
|
-
|
|
67
|
-
this.
|
|
68
|
-
this.
|
|
69
|
-
|
|
70
|
-
if (!this.blockDuration) {
|
|
71
|
-
this.maxNumberOfBlocks = 1; // Single block per slot
|
|
72
|
-
} else {
|
|
73
|
-
const timeReservedAtEnd = this.blockDuration + // Last sub-slot for validator re-execution
|
|
74
|
-
this.checkpointFinalizationTime; // Checkpoint finalization
|
|
75
|
-
const timeAvailableForBlocks = this.aztecSlotDuration - this.initializationOffset - timeReservedAtEnd;
|
|
76
|
-
this.maxNumberOfBlocks = Math.floor(timeAvailableForBlocks / this.blockDuration);
|
|
77
|
-
}
|
|
78
|
-
// Minimum work to do within a slot for building a block with the minimum time for execution and publishing its checkpoint
|
|
79
|
-
const minWorkToDo = this.initializationOffset + this.minExecutionTime * 2 + // Execution and reexecution
|
|
80
|
-
this.checkpointFinalizationTime;
|
|
81
|
-
const initializeDeadline = this.aztecSlotDuration - minWorkToDo;
|
|
82
|
-
this.initializeDeadline = initializeDeadline;
|
|
72
|
+
this.initializationOffset = this.checkpointTiming.checkpointInitializationTime;
|
|
73
|
+
this.checkpointFinalizationTime = this.checkpointTiming.checkpointFinalizationTime;
|
|
74
|
+
this.pipeliningAttestationGracePeriod = this.checkpointTiming.pipeliningAttestationGracePeriod;
|
|
75
|
+
this.maxNumberOfBlocks = this.checkpointTiming.calculateMaxBlocksPerSlot();
|
|
76
|
+
this.initializeDeadline = this.checkpointTiming.initializeDeadline;
|
|
83
77
|
this.log?.info(`Sequencer timetable initialized with ${this.maxNumberOfBlocks} blocks per slot (${this.enforce ? 'enforced' : 'not enforced'})`, {
|
|
84
78
|
ethereumSlotDuration: this.ethereumSlotDuration,
|
|
85
79
|
aztecSlotDuration: this.aztecSlotDuration,
|
|
@@ -90,14 +84,28 @@ export class SequencerTimetable {
|
|
|
90
84
|
blockAssembleTime: this.checkpointAssembleTime,
|
|
91
85
|
initializeDeadline: this.initializeDeadline,
|
|
92
86
|
enforce: this.enforce,
|
|
93
|
-
|
|
87
|
+
pipelining: this.pipelining,
|
|
88
|
+
pipeliningAttestationGracePeriod: this.pipeliningAttestationGracePeriod,
|
|
89
|
+
minWorkToDo: this.checkpointTiming.minimumBuildSlotWork,
|
|
94
90
|
blockDuration: this.blockDuration,
|
|
95
91
|
maxNumberOfBlocks: this.maxNumberOfBlocks
|
|
96
92
|
});
|
|
97
|
-
if (initializeDeadline <= 0) {
|
|
98
|
-
throw new Error(`Block proposal initialize deadline cannot be negative (got ${initializeDeadline} from total time needed ${
|
|
93
|
+
if (this.initializeDeadline <= 0) {
|
|
94
|
+
throw new Error(`Block proposal initialize deadline cannot be negative (got ${this.initializeDeadline} from total time needed ${this.checkpointTiming.minimumBuildSlotWork} and a slot duration of ${this.aztecSlotDuration}).`);
|
|
99
95
|
}
|
|
100
96
|
}
|
|
97
|
+
getCheckpointAssemblyDeadline() {
|
|
98
|
+
return this.checkpointTiming.checkpointAssemblyDeadline;
|
|
99
|
+
}
|
|
100
|
+
getCheckpointAttestationDeadline() {
|
|
101
|
+
return this.checkpointTiming.checkpointAttestationDeadline;
|
|
102
|
+
}
|
|
103
|
+
getCheckpointAttestationStartDeadline() {
|
|
104
|
+
return this.checkpointTiming.checkpointAttestationStartDeadline;
|
|
105
|
+
}
|
|
106
|
+
getCheckpointPublishingDeadline() {
|
|
107
|
+
return this.checkpointTiming.checkpointPublishingDeadline;
|
|
108
|
+
}
|
|
101
109
|
getMaxAllowedTime(state) {
|
|
102
110
|
switch(state){
|
|
103
111
|
case SequencerState.STOPPED:
|
|
@@ -113,10 +121,11 @@ export class SequencerTimetable {
|
|
|
113
121
|
case SequencerState.WAITING_UNTIL_NEXT_BLOCK:
|
|
114
122
|
return this.initializeDeadline + this.checkpointInitializationTime;
|
|
115
123
|
case SequencerState.ASSEMBLING_CHECKPOINT:
|
|
124
|
+
return this.getCheckpointAssemblyDeadline();
|
|
116
125
|
case SequencerState.COLLECTING_ATTESTATIONS:
|
|
117
|
-
return this.
|
|
126
|
+
return this.getCheckpointAttestationStartDeadline();
|
|
118
127
|
case SequencerState.PUBLISHING_CHECKPOINT:
|
|
119
|
-
return this.
|
|
128
|
+
return this.getCheckpointPublishingDeadline();
|
|
120
129
|
default:
|
|
121
130
|
{
|
|
122
131
|
const _exhaustiveCheck = state;
|
package/dest/test/utils.d.ts
CHANGED
|
@@ -50,4 +50,4 @@ export declare function setupTxsAndBlock(p2p: MockProxy<P2P>, globalVariables: G
|
|
|
50
50
|
txs: Tx[];
|
|
51
51
|
block: L2Block;
|
|
52
52
|
}>;
|
|
53
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
53
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90ZXN0L3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUdBLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQztBQUM1RSxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDcEQsT0FBTyxLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDaEUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQzVELE9BQU8sS0FBSyxFQUFFLEdBQUcsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUV0QyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDcEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxxQkFBcUIsRUFBRSxrQkFBa0IsRUFBb0IsTUFBTSxtQkFBbUIsQ0FBQztBQU8vRyxPQUFPLEVBQWUsZUFBZSxFQUFFLEtBQUssRUFBRSxFQUFvQyxNQUFNLGtCQUFrQixDQUFDO0FBRTNHLE9BQU8sS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBR3BELE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxzQkFBc0IsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBRTdGOztHQUVHO0FBQ0gsd0JBQXNCLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLEVBQUUsRUFBRSxHQUFHLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FNckU7QUFFRDs7R0FFRztBQUNILHdCQUFzQixTQUFTLENBQUMsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLGVBQWUsRUFBRSxlQUFlLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQWdCN0Y7QUFFRDs7R0FFRztBQUNILHdCQUFnQixjQUFjLENBQUMsR0FBRyxFQUFFLFNBQVMsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsSUFBSSxDQUluRTtBQUVEOztHQUVHO0FBQ0gsd0JBQXVCLGNBQWMsQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDLEVBQUUsRUFBRSxDQUFDLEdBQUcscUJBQXFCLENBQUMsRUFBRSxDQUFDLENBSW5GO0FBRUQ7O0dBRUc7QUFDSCx3QkFBZ0Isb0JBQW9CLENBQUMsTUFBTSxFQUFFLGVBQWUsR0FBRyxvQkFBb0IsRUFBRSxDQUdwRjtBQXVCRDs7R0FFRztBQUNILHdCQUFnQixtQkFBbUIsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxTQUFTLEdBQUcsYUFBYSxDQVd2RjtBQUVEOztHQUVHO0FBQ0gsd0JBQWdCLHdCQUF3QixDQUN0QyxLQUFLLEVBQUUsT0FBTyxFQUNkLG1CQUFtQixFQUFFLFNBQVMsRUFDOUIsY0FBYyxDQUFDLEVBQUUsU0FBUyxFQUMxQixxQkFBcUIsR0FBRSxNQUFXLEdBQ2pDLGtCQUFrQixDQWdCcEI7QUFFRDs7OztHQUlHO0FBQ0gsd0JBQWdCLDJCQUEyQixDQUN6QyxLQUFLLEVBQUUsT0FBTyxFQUNkLFNBQVMsRUFBRSxTQUFTLEVBQ3BCLE1BQU0sRUFBRSxVQUFVLEVBQ2xCLHFCQUFxQixHQUFFLE1BQVcsR0FDakMscUJBQXFCLENBYXZCO0FBRUQ7OztHQUdHO0FBQ0gsd0JBQXNCLGdCQUFnQixDQUNwQyxHQUFHLEVBQUUsU0FBUyxDQUFDLEdBQUcsQ0FBQyxFQUNuQixlQUFlLEVBQUUsZUFBZSxFQUNoQyxPQUFPLEVBQUUsTUFBTSxFQUNmLE9BQU8sRUFBRSxFQUFFLEdBQ1YsT0FBTyxDQUFDO0lBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxDQUFDO0lBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQTtDQUFFLENBQUMsQ0FLeEMifQ==
|
package/dest/test/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/test/utils.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAC;AAC5E,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAC5D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,kBAAkB,EAAoB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/test/utils.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAC;AAC5E,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAC5D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,kBAAkB,EAAoB,MAAM,mBAAmB,CAAC;AAO/G,OAAO,EAAe,eAAe,EAAE,KAAK,EAAE,EAAoC,MAAM,kBAAkB,CAAC;AAE3G,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAGpD,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAE7F;;GAEG;AACH,wBAAsB,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC,CAMrE;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,eAAe,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,CAgB7F;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,SAAS,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,IAAI,CAInE;AAED;;GAEG;AACH,wBAAuB,cAAc,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,GAAG,qBAAqB,CAAC,EAAE,CAAC,CAInF;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,eAAe,GAAG,oBAAoB,EAAE,CAGpF;AAuBD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,GAAG,aAAa,CAWvF;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,OAAO,EACd,mBAAmB,EAAE,SAAS,EAC9B,cAAc,CAAC,EAAE,SAAS,EAC1B,qBAAqB,GAAE,MAAW,GACjC,kBAAkB,CAgBpB;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,OAAO,EACd,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,UAAU,EAClB,qBAAqB,GAAE,MAAW,GACjC,qBAAqB,CAavB;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,SAAS,CAAC,GAAG,CAAC,EACnB,eAAe,EAAE,eAAe,EAChC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,EAAE,GACV,OAAO,CAAC;IAAE,GAAG,EAAE,EAAE,EAAE,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAC,CAKxC"}
|
package/dest/test/utils.js
CHANGED
|
@@ -7,7 +7,7 @@ import { PublicDataWrite } from '@aztec/stdlib/avm';
|
|
|
7
7
|
import { CommitteeAttestation, L2Block } from '@aztec/stdlib/block';
|
|
8
8
|
import { BlockProposal, CheckpointAttestation, CheckpointProposal, ConsensusPayload } from '@aztec/stdlib/p2p';
|
|
9
9
|
import { CheckpointHeader } from '@aztec/stdlib/rollup';
|
|
10
|
-
import { makeAppendOnlyTreeSnapshot, mockTxForRollup } from '@aztec/stdlib/testing';
|
|
10
|
+
import { TEST_COORDINATION_SIGNATURE_CONTEXT, makeAppendOnlyTreeSnapshot, mockTxForRollup } from '@aztec/stdlib/testing';
|
|
11
11
|
import { BlockHeader, makeProcessedTxFromPrivateOnlyTx } from '@aztec/stdlib/tx';
|
|
12
12
|
// Re-export mock classes from their dedicated file
|
|
13
13
|
export { MockCheckpointBuilder, MockCheckpointsBuilder } from './mock_checkpoint_builder.js';
|
|
@@ -64,14 +64,14 @@ export { MockCheckpointBuilder, MockCheckpointsBuilder } from './mock_checkpoint
|
|
|
64
64
|
* Creates a block proposal from a block and signature
|
|
65
65
|
*/ export function createBlockProposal(block, signature) {
|
|
66
66
|
const txHashes = block.body.txEffects.map((tx)=>tx.txHash);
|
|
67
|
-
return new BlockProposal(block.header, block.indexWithinCheckpoint, Fr.ZERO, block.archive.root, txHashes, signature);
|
|
67
|
+
return new BlockProposal(block.header, block.indexWithinCheckpoint, Fr.ZERO, block.archive.root, txHashes, signature, TEST_COORDINATION_SIGNATURE_CONTEXT);
|
|
68
68
|
}
|
|
69
69
|
/**
|
|
70
70
|
* Creates a checkpoint proposal from a block and signature
|
|
71
71
|
*/ export function createCheckpointProposal(block, checkpointSignature, blockSignature, feeAssetPriceModifier = 0n) {
|
|
72
72
|
const txHashes = block.body.txEffects.map((tx)=>tx.txHash);
|
|
73
73
|
const checkpointHeader = createCheckpointHeaderFromBlock(block);
|
|
74
|
-
return new CheckpointProposal(checkpointHeader, block.archive.root, feeAssetPriceModifier, checkpointSignature, {
|
|
74
|
+
return new CheckpointProposal(checkpointHeader, block.archive.root, feeAssetPriceModifier, checkpointSignature, TEST_COORDINATION_SIGNATURE_CONTEXT, {
|
|
75
75
|
blockHeader: block.header,
|
|
76
76
|
indexWithinCheckpoint: block.indexWithinCheckpoint,
|
|
77
77
|
txHashes,
|
|
@@ -84,10 +84,11 @@ export { MockCheckpointBuilder, MockCheckpointsBuilder } from './mock_checkpoint
|
|
|
84
84
|
* In production, the sender is recovered from the signature.
|
|
85
85
|
*/ export function createCheckpointAttestation(block, signature, sender, feeAssetPriceModifier = 0n) {
|
|
86
86
|
const checkpointHeader = createCheckpointHeaderFromBlock(block);
|
|
87
|
-
const payload = new ConsensusPayload(checkpointHeader, block.archive.root, feeAssetPriceModifier);
|
|
87
|
+
const payload = new ConsensusPayload(checkpointHeader, block.archive.root, feeAssetPriceModifier, TEST_COORDINATION_SIGNATURE_CONTEXT);
|
|
88
88
|
const attestation = new CheckpointAttestation(payload, signature, signature);
|
|
89
|
-
//
|
|
90
|
-
attestation.
|
|
89
|
+
// Bypass signature recovery for testing since we use random signatures
|
|
90
|
+
attestation.getSender = ()=>sender;
|
|
91
|
+
attestation.getProposer = ()=>sender;
|
|
91
92
|
return attestation;
|
|
92
93
|
}
|
|
93
94
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/sequencer-client",
|
|
3
|
-
"version": "0.0.1-commit.
|
|
3
|
+
"version": "0.0.1-commit.e5a3663dd",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -26,37 +26,37 @@
|
|
|
26
26
|
"test:integration:run": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --no-cache --config jest.integration.config.json"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@aztec/aztec.js": "0.0.1-commit.
|
|
30
|
-
"@aztec/bb-prover": "0.0.1-commit.
|
|
31
|
-
"@aztec/blob-client": "0.0.1-commit.
|
|
32
|
-
"@aztec/blob-lib": "0.0.1-commit.
|
|
33
|
-
"@aztec/constants": "0.0.1-commit.
|
|
34
|
-
"@aztec/epoch-cache": "0.0.1-commit.
|
|
35
|
-
"@aztec/ethereum": "0.0.1-commit.
|
|
36
|
-
"@aztec/foundation": "0.0.1-commit.
|
|
37
|
-
"@aztec/l1-artifacts": "0.0.1-commit.
|
|
38
|
-
"@aztec/node-keystore": "0.0.1-commit.
|
|
39
|
-
"@aztec/noir-acvm_js": "0.0.1-commit.
|
|
40
|
-
"@aztec/noir-contracts.js": "0.0.1-commit.
|
|
41
|
-
"@aztec/noir-protocol-circuits-types": "0.0.1-commit.
|
|
42
|
-
"@aztec/noir-types": "0.0.1-commit.
|
|
43
|
-
"@aztec/p2p": "0.0.1-commit.
|
|
44
|
-
"@aztec/protocol-contracts": "0.0.1-commit.
|
|
45
|
-
"@aztec/prover-client": "0.0.1-commit.
|
|
46
|
-
"@aztec/simulator": "0.0.1-commit.
|
|
47
|
-
"@aztec/slasher": "0.0.1-commit.
|
|
48
|
-
"@aztec/stdlib": "0.0.1-commit.
|
|
49
|
-
"@aztec/telemetry-client": "0.0.1-commit.
|
|
50
|
-
"@aztec/validator-client": "0.0.1-commit.
|
|
51
|
-
"@aztec/validator-ha-signer": "0.0.1-commit.
|
|
52
|
-
"@aztec/world-state": "0.0.1-commit.
|
|
29
|
+
"@aztec/aztec.js": "0.0.1-commit.e5a3663dd",
|
|
30
|
+
"@aztec/bb-prover": "0.0.1-commit.e5a3663dd",
|
|
31
|
+
"@aztec/blob-client": "0.0.1-commit.e5a3663dd",
|
|
32
|
+
"@aztec/blob-lib": "0.0.1-commit.e5a3663dd",
|
|
33
|
+
"@aztec/constants": "0.0.1-commit.e5a3663dd",
|
|
34
|
+
"@aztec/epoch-cache": "0.0.1-commit.e5a3663dd",
|
|
35
|
+
"@aztec/ethereum": "0.0.1-commit.e5a3663dd",
|
|
36
|
+
"@aztec/foundation": "0.0.1-commit.e5a3663dd",
|
|
37
|
+
"@aztec/l1-artifacts": "0.0.1-commit.e5a3663dd",
|
|
38
|
+
"@aztec/node-keystore": "0.0.1-commit.e5a3663dd",
|
|
39
|
+
"@aztec/noir-acvm_js": "0.0.1-commit.e5a3663dd",
|
|
40
|
+
"@aztec/noir-contracts.js": "0.0.1-commit.e5a3663dd",
|
|
41
|
+
"@aztec/noir-protocol-circuits-types": "0.0.1-commit.e5a3663dd",
|
|
42
|
+
"@aztec/noir-types": "0.0.1-commit.e5a3663dd",
|
|
43
|
+
"@aztec/p2p": "0.0.1-commit.e5a3663dd",
|
|
44
|
+
"@aztec/protocol-contracts": "0.0.1-commit.e5a3663dd",
|
|
45
|
+
"@aztec/prover-client": "0.0.1-commit.e5a3663dd",
|
|
46
|
+
"@aztec/simulator": "0.0.1-commit.e5a3663dd",
|
|
47
|
+
"@aztec/slasher": "0.0.1-commit.e5a3663dd",
|
|
48
|
+
"@aztec/stdlib": "0.0.1-commit.e5a3663dd",
|
|
49
|
+
"@aztec/telemetry-client": "0.0.1-commit.e5a3663dd",
|
|
50
|
+
"@aztec/validator-client": "0.0.1-commit.e5a3663dd",
|
|
51
|
+
"@aztec/validator-ha-signer": "0.0.1-commit.e5a3663dd",
|
|
52
|
+
"@aztec/world-state": "0.0.1-commit.e5a3663dd",
|
|
53
53
|
"lodash.chunk": "^4.2.0",
|
|
54
54
|
"tslib": "^2.4.0",
|
|
55
55
|
"viem": "npm:@aztec/viem@2.38.2"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
|
-
"@aztec/archiver": "0.0.1-commit.
|
|
59
|
-
"@aztec/kv-store": "0.0.1-commit.
|
|
58
|
+
"@aztec/archiver": "0.0.1-commit.e5a3663dd",
|
|
59
|
+
"@aztec/kv-store": "0.0.1-commit.e5a3663dd",
|
|
60
60
|
"@electric-sql/pglite": "^0.3.14",
|
|
61
61
|
"@jest/globals": "^30.0.0",
|
|
62
62
|
"@types/jest": "^30.0.0",
|
|
@@ -14,7 +14,6 @@ import type { P2P } from '@aztec/p2p';
|
|
|
14
14
|
import type { SlasherClientInterface } from '@aztec/slasher';
|
|
15
15
|
import type { L2BlockSink, L2BlockSource } from '@aztec/stdlib/block';
|
|
16
16
|
import type { ValidatorClientFullConfig, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
|
|
17
|
-
import { SlashFactoryContract } from '@aztec/stdlib/l1-contracts';
|
|
18
17
|
import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
|
|
19
18
|
import { L1Metrics, type TelemetryClient } from '@aztec/telemetry-client';
|
|
20
19
|
import { FullNodeCheckpointsBuilder, NodeKeystoreAdapter, type ValidatorClient } from '@aztec/validator-client';
|
|
@@ -118,11 +117,6 @@ export class SequencerClient {
|
|
|
118
117
|
{ dateProvider: deps.dateProvider },
|
|
119
118
|
));
|
|
120
119
|
|
|
121
|
-
const slashFactoryContract = new SlashFactoryContract(
|
|
122
|
-
publicClient,
|
|
123
|
-
config.l1Contracts.slashFactoryAddress?.toString() ?? EthAddress.ZERO.toString(),
|
|
124
|
-
);
|
|
125
|
-
|
|
126
120
|
const publisherFactory =
|
|
127
121
|
deps.publisherFactory ??
|
|
128
122
|
new SequencerPublisherFactory(config, {
|
|
@@ -130,7 +124,6 @@ export class SequencerClient {
|
|
|
130
124
|
blobClient: deps.blobClient,
|
|
131
125
|
epochCache,
|
|
132
126
|
governanceProposerContract,
|
|
133
|
-
slashFactoryContract,
|
|
134
127
|
rollupContract,
|
|
135
128
|
dateProvider: deps.dateProvider,
|
|
136
129
|
publisherManager,
|
|
@@ -209,6 +202,11 @@ export class SequencerClient {
|
|
|
209
202
|
this.l1Metrics?.stop();
|
|
210
203
|
}
|
|
211
204
|
|
|
205
|
+
/** Triggers an immediate run of the sequencer, bypassing the polling interval. */
|
|
206
|
+
public trigger() {
|
|
207
|
+
return this.sequencer.trigger();
|
|
208
|
+
}
|
|
209
|
+
|
|
212
210
|
public getSequencer(): Sequencer {
|
|
213
211
|
return this.sequencer;
|
|
214
212
|
}
|