@aztec/sequencer-client 0.0.1-commit.2f68f620 → 0.0.1-commit.3100065
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/README.md +27 -27
- package/dest/client/sequencer-client.d.ts +16 -3
- package/dest/client/sequencer-client.d.ts.map +1 -1
- package/dest/client/sequencer-client.js +17 -12
- package/dest/config.d.ts +6 -2
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +23 -14
- package/dest/global_variable_builder/fee_predictor.d.ts +1 -1
- package/dest/global_variable_builder/fee_predictor.d.ts.map +1 -1
- package/dest/global_variable_builder/fee_predictor.js +11 -1
- package/dest/global_variable_builder/fee_provider.d.ts +1 -1
- package/dest/global_variable_builder/fee_provider.d.ts.map +1 -1
- package/dest/global_variable_builder/fee_provider.js +27 -5
- package/dest/global_variable_builder/global_builder.d.ts +3 -16
- package/dest/global_variable_builder/global_builder.d.ts.map +1 -1
- package/dest/global_variable_builder/global_builder.js +2 -25
- package/dest/index.d.ts +2 -2
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -1
- package/dest/publisher/config.d.ts +5 -1
- package/dest/publisher/config.d.ts.map +1 -1
- package/dest/publisher/config.js +11 -1
- package/dest/publisher/l1_to_l2_messaging.d.ts +21 -0
- package/dest/publisher/l1_to_l2_messaging.d.ts.map +1 -0
- package/dest/publisher/l1_to_l2_messaging.js +70 -0
- package/dest/publisher/sequencer-publisher.d.ts +17 -4
- package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher.js +119 -22
- package/dest/publisher/write_json.d.ts +11 -0
- package/dest/publisher/write_json.d.ts.map +1 -0
- package/dest/publisher/write_json.js +57 -0
- package/dest/sequencer/automine/automine_factory.d.ts +5 -3
- package/dest/sequencer/automine/automine_factory.d.ts.map +1 -1
- package/dest/sequencer/automine/automine_factory.js +2 -1
- package/dest/sequencer/automine/automine_sequencer.d.ts +43 -5
- package/dest/sequencer/automine/automine_sequencer.d.ts.map +1 -1
- package/dest/sequencer/automine/automine_sequencer.js +199 -18
- package/dest/sequencer/automine/index.d.ts +3 -0
- package/dest/sequencer/automine/index.d.ts.map +1 -0
- package/dest/sequencer/automine/index.js +2 -0
- package/dest/sequencer/checkpoint_proposal_job.d.ts +24 -16
- package/dest/sequencer/checkpoint_proposal_job.d.ts.map +1 -1
- package/dest/sequencer/checkpoint_proposal_job.js +98 -90
- package/dest/sequencer/errors.d.ts +1 -8
- package/dest/sequencer/errors.d.ts.map +1 -1
- package/dest/sequencer/errors.js +0 -9
- package/dest/sequencer/events.d.ts +16 -5
- package/dest/sequencer/events.d.ts.map +1 -1
- package/dest/sequencer/index.d.ts +1 -3
- package/dest/sequencer/index.d.ts.map +1 -1
- package/dest/sequencer/index.js +0 -2
- package/dest/sequencer/requests_tracker.d.ts +22 -0
- package/dest/sequencer/requests_tracker.d.ts.map +1 -0
- package/dest/sequencer/requests_tracker.js +33 -0
- package/dest/sequencer/sequencer.d.ts +110 -36
- package/dest/sequencer/sequencer.d.ts.map +1 -1
- package/dest/sequencer/sequencer.js +329 -174
- package/dest/test/index.d.ts +3 -3
- package/dest/test/index.d.ts.map +1 -1
- package/dest/test/utils.d.ts +15 -1
- package/dest/test/utils.d.ts.map +1 -1
- package/dest/test/utils.js +18 -1
- package/package.json +28 -27
- package/src/client/sequencer-client.ts +20 -13
- package/src/config.ts +25 -12
- package/src/global_variable_builder/fee_predictor.ts +11 -1
- package/src/global_variable_builder/fee_provider.ts +27 -5
- package/src/global_variable_builder/global_builder.ts +2 -34
- package/src/index.ts +1 -10
- package/src/publisher/config.ts +22 -1
- package/src/publisher/l1_to_l2_messaging.ts +85 -0
- package/src/publisher/sequencer-publisher.ts +116 -23
- package/src/publisher/write_json.ts +78 -0
- package/src/sequencer/automine/README.md +18 -4
- package/src/sequencer/automine/automine_factory.ts +8 -1
- package/src/sequencer/automine/automine_sequencer.ts +221 -20
- package/src/sequencer/automine/index.ts +6 -0
- package/src/sequencer/checkpoint_proposal_job.ts +119 -100
- package/src/sequencer/errors.ts +0 -15
- package/src/sequencer/events.ts +16 -4
- package/src/sequencer/index.ts +0 -2
- package/src/sequencer/requests_tracker.ts +43 -0
- package/src/sequencer/sequencer.ts +360 -187
- package/src/test/index.ts +2 -2
- package/src/test/utils.ts +33 -0
- package/dest/sequencer/chain_state_overrides.d.ts +0 -61
- package/dest/sequencer/chain_state_overrides.d.ts.map +0 -1
- package/dest/sequencer/chain_state_overrides.js +0 -98
- package/dest/sequencer/timetable.d.ts +0 -98
- package/dest/sequencer/timetable.d.ts.map +0 -1
- package/dest/sequencer/timetable.js +0 -227
- package/src/sequencer/README.md +0 -243
- package/src/sequencer/chain_state_overrides.ts +0 -162
- package/src/sequencer/timetable.ts +0 -288
|
@@ -435,8 +435,9 @@ function applyDecs2203RFactory() {
|
|
|
435
435
|
function _apply_decs_2203_r(targetClass, memberDecs, classDecs, parentClass) {
|
|
436
436
|
return (_apply_decs_2203_r = applyDecs2203RFactory())(targetClass, memberDecs, classDecs, parentClass);
|
|
437
437
|
}
|
|
438
|
-
var _dec, _dec1, _dec2, _dec3, _dec4, _dec5, _dec6,
|
|
439
|
-
import {
|
|
438
|
+
var _dec, _dec1, _dec2, _dec3, _dec4, _dec5, _dec6, _initProto;
|
|
439
|
+
import { PROPOSER_PIPELINING_SLOT_OFFSET } from '@aztec/epoch-cache';
|
|
440
|
+
import { BlockNumber, CheckpointNumber, IndexWithinCheckpoint, SlotNumber } from '@aztec/foundation/branded-types';
|
|
440
441
|
import { randomInt } from '@aztec/foundation/crypto/random';
|
|
441
442
|
import { flipSignature, generateRecoverableSignature, generateUnrecoverableSignature } from '@aztec/foundation/crypto/secp256k1-signer';
|
|
442
443
|
import { InterruptError, TimeoutError } from '@aztec/foundation/error';
|
|
@@ -445,9 +446,9 @@ import { createLogger } from '@aztec/foundation/log';
|
|
|
445
446
|
import { InterruptibleSleep } from '@aztec/foundation/sleep';
|
|
446
447
|
import { Timer } from '@aztec/foundation/timer';
|
|
447
448
|
import { isErrorClass, unfreeze } from '@aztec/foundation/types';
|
|
448
|
-
import { CommitteeAttestationsAndSigners, MaliciousCommitteeAttestationsAndSigners } from '@aztec/stdlib/block';
|
|
449
|
-
import { getPreviousCheckpointOutHashes, validateCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
450
|
-
import { computeQuorum,
|
|
449
|
+
import { CommitteeAttestationsAndSigners, MaliciousCommitteeAttestationsAndSigners, MaliciousYParityCommitteeAttestationsAndSigners } from '@aztec/stdlib/block';
|
|
450
|
+
import { buildCheckpointSimulationOverridesPlan, getPreviousCheckpointOutHashes, validateCheckpoint } from '@aztec/stdlib/checkpoint';
|
|
451
|
+
import { computeQuorum, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
|
|
451
452
|
import { Gas } from '@aztec/stdlib/gas';
|
|
452
453
|
import { InsufficientValidTxsError } from '@aztec/stdlib/interfaces/server';
|
|
453
454
|
import { computeInHashFromL1ToL2Messages } from '@aztec/stdlib/messaging';
|
|
@@ -455,7 +456,6 @@ import { orderAttestations, trimAttestations } from '@aztec/stdlib/p2p';
|
|
|
455
456
|
import { AttestationTimeoutError } from '@aztec/stdlib/validators';
|
|
456
457
|
import { Attributes, trackSpan } from '@aztec/telemetry-client';
|
|
457
458
|
import { DutyAlreadySignedError, SlashingProtectionError } from '@aztec/validator-ha-signer/errors';
|
|
458
|
-
import { buildCheckpointSimulationOverridesPlan } from './chain_state_overrides.js';
|
|
459
459
|
import { CheckpointVoter } from './checkpoint_voter.js';
|
|
460
460
|
import { SequencerInterruptedError } from './errors.js';
|
|
461
461
|
import { SequencerState } from './utils.js';
|
|
@@ -467,14 +467,13 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
467
467
|
[Attributes.COINBASE]: this.validatorClient.getCoinbaseForAttestor(this.attestorAddress)?.toString(),
|
|
468
468
|
[Attributes.SLOT_NUMBER]: this.targetSlot
|
|
469
469
|
};
|
|
470
|
-
}), _dec2 = trackSpan('CheckpointProposalJob.buildBlocksForCheckpoint'), _dec3 = trackSpan('CheckpointProposalJob.waitUntilNextSubslot'), _dec4 = trackSpan('CheckpointProposalJob.buildSingleBlock'), _dec5 = trackSpan('CheckpointProposalJob.waitForMinTxs'), _dec6 = trackSpan('CheckpointProposalJob.waitForAttestations')
|
|
470
|
+
}), _dec2 = trackSpan('CheckpointProposalJob.buildBlocksForCheckpoint'), _dec3 = trackSpan('CheckpointProposalJob.waitUntilNextSubslot'), _dec4 = trackSpan('CheckpointProposalJob.buildSingleBlock'), _dec5 = trackSpan('CheckpointProposalJob.waitForMinTxs'), _dec6 = trackSpan('CheckpointProposalJob.waitForAttestations');
|
|
471
471
|
/**
|
|
472
472
|
* Handles the execution of a checkpoint proposal after the initial preparation phase.
|
|
473
473
|
* This includes building blocks, collecting attestations, and publishing the checkpoint to L1,
|
|
474
474
|
* as well as enqueueing votes for slashing and governance proposals. This class is created from
|
|
475
475
|
* the Sequencer once the check for being the proposer for the slot has succeeded.
|
|
476
476
|
*/ export class CheckpointProposalJob {
|
|
477
|
-
slotNow;
|
|
478
477
|
targetSlot;
|
|
479
478
|
targetEpoch;
|
|
480
479
|
checkpointNumber;
|
|
@@ -502,6 +501,7 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
502
501
|
metrics;
|
|
503
502
|
checkpointMetrics;
|
|
504
503
|
eventEmitter;
|
|
504
|
+
pendingRequests;
|
|
505
505
|
setStateFn;
|
|
506
506
|
tracer;
|
|
507
507
|
proposedCheckpointData;
|
|
@@ -541,17 +541,11 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
541
541
|
_dec6,
|
|
542
542
|
2,
|
|
543
543
|
"waitForAttestations"
|
|
544
|
-
],
|
|
545
|
-
[
|
|
546
|
-
_dec7,
|
|
547
|
-
2,
|
|
548
|
-
"waitUntilTimeInSlot"
|
|
549
544
|
]
|
|
550
545
|
], []));
|
|
551
546
|
}
|
|
552
547
|
log;
|
|
553
548
|
checkpointEventLog;
|
|
554
|
-
/** Tracks the fire-and-forget L1 submission promise so it can be awaited during shutdown. */ pendingL1Submission;
|
|
555
549
|
interruptibleSleep;
|
|
556
550
|
interrupted;
|
|
557
551
|
/**
|
|
@@ -563,9 +557,10 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
563
557
|
getSignatureContext() {
|
|
564
558
|
return this.signatureContext;
|
|
565
559
|
}
|
|
566
|
-
constructor(
|
|
567
|
-
proposer, publisher, attestorAddress, invalidateCheckpoint, validatorClient, globalsBuilder, p2pClient, worldState, l1ToL2MessageSource, l2BlockSource, checkpointsBuilder, blockSink, l1Constants, signatureContext, config, timetable, slasherClient, epochCache, dateProvider, metrics, checkpointMetrics, eventEmitter,
|
|
568
|
-
|
|
560
|
+
constructor(targetSlot, targetEpoch, checkpointNumber, syncedToBlockNumber, checkpointedCheckpointNumber, // TODO(palla/mbps): Can we remove the proposer in favor of attestorAddress? Need to check fisherman-node flows.
|
|
561
|
+
proposer, publisher, attestorAddress, invalidateCheckpoint, validatorClient, globalsBuilder, p2pClient, worldState, l1ToL2MessageSource, l2BlockSource, checkpointsBuilder, blockSink, l1Constants, signatureContext, config, timetable, slasherClient, epochCache, dateProvider, metrics, checkpointMetrics, eventEmitter, // Shared with the owning sequencer, which drains it during shutdown; the fire-and-forget L1
|
|
562
|
+
// submission this job backgrounds is tracked here rather than in a job-local tracker.
|
|
563
|
+
pendingRequests, setStateFn, tracer, bindings, proposedCheckpointData){
|
|
569
564
|
this.targetSlot = targetSlot;
|
|
570
565
|
this.targetEpoch = targetEpoch;
|
|
571
566
|
this.checkpointNumber = checkpointNumber;
|
|
@@ -593,6 +588,7 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
593
588
|
this.metrics = metrics;
|
|
594
589
|
this.checkpointMetrics = checkpointMetrics;
|
|
595
590
|
this.eventEmitter = eventEmitter;
|
|
591
|
+
this.pendingRequests = pendingRequests;
|
|
596
592
|
this.setStateFn = setStateFn;
|
|
597
593
|
this.tracer = tracer;
|
|
598
594
|
this.proposedCheckpointData = proposedCheckpointData;
|
|
@@ -600,16 +596,25 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
600
596
|
this.interrupted = false;
|
|
601
597
|
this.log = createLogger('sequencer:checkpoint-proposal', {
|
|
602
598
|
...bindings,
|
|
603
|
-
instanceId: `slot-${this.
|
|
599
|
+
instanceId: `slot-${this.getBuildSlot()}`
|
|
604
600
|
});
|
|
605
601
|
this.checkpointEventLog = createLogger('sequencer:checkpoint-events', {
|
|
606
602
|
...bindings,
|
|
607
|
-
instanceId: `slot-${this.
|
|
603
|
+
instanceId: `slot-${this.getBuildSlot()}`
|
|
608
604
|
});
|
|
609
605
|
}
|
|
610
|
-
/**
|
|
611
|
-
|
|
612
|
-
|
|
606
|
+
/**
|
|
607
|
+
* The wall-clock slot during which this job builds, i.e. the slot one before {@link targetSlot} under
|
|
608
|
+
* proposer pipelining. Also the slot of the parent checkpoint this job builds on top of.
|
|
609
|
+
*/ getBuildSlot() {
|
|
610
|
+
return SlotNumber(this.targetSlot - PROPOSER_PIPELINING_SLOT_OFFSET);
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* Sets the sequencer state for this job, reporting the target slot the checkpoint is being proposed for
|
|
614
|
+
* (not the wall-clock build slot). The slot is informational on the event payload/metrics; the job knows
|
|
615
|
+
* its own target slot, so callers only pass the state.
|
|
616
|
+
*/ setState(state) {
|
|
617
|
+
this.setStateFn(state, this.targetSlot);
|
|
613
618
|
}
|
|
614
619
|
/** Interrupts job-owned waits, including the publisher's send-at-slot sleep, so shutdown can finish. */ interrupt() {
|
|
615
620
|
this.interrupted = true;
|
|
@@ -661,7 +666,7 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
661
666
|
// signature verification to fail silently inside Multicall3. Delay submission to the
|
|
662
667
|
// start of `targetSlot` so the tx mines in the slot the vote was signed for.
|
|
663
668
|
if (!this.config.fishermanMode) {
|
|
664
|
-
this.
|
|
669
|
+
this.pendingRequests.trackRequest(this.publisher.sendRequestsAt(this.targetSlot), ()=>this.interrupt());
|
|
665
670
|
}
|
|
666
671
|
return undefined;
|
|
667
672
|
}
|
|
@@ -673,13 +678,13 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
673
678
|
return checkpoint;
|
|
674
679
|
}
|
|
675
680
|
// Background the attestation → signing → L1 pipeline so the work loop is unblocked
|
|
676
|
-
this.
|
|
681
|
+
this.pendingRequests.trackRequest(this.waitForAttestationsAndEnqueueSubmissionAsync(broadcast, votesPromises), ()=>this.interrupt());
|
|
677
682
|
// Return the built checkpoint immediately — the work loop is now unblocked
|
|
678
683
|
return checkpoint;
|
|
679
684
|
}
|
|
680
685
|
/**
|
|
681
686
|
* Background pipeline: collects attestations, signs them, enqueues the checkpoint, and submits to L1.
|
|
682
|
-
* Runs as a fire-and-forget task
|
|
687
|
+
* Runs as a fire-and-forget task tracked in the sequencer's shared tracker so the work loop is unblocked.
|
|
683
688
|
*/ async waitForAttestationsAndEnqueueSubmissionAsync(broadcast, votesPromises) {
|
|
684
689
|
const { checkpoint } = broadcast;
|
|
685
690
|
try {
|
|
@@ -696,7 +701,7 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
696
701
|
});
|
|
697
702
|
}
|
|
698
703
|
// If we failed to collect attestations, at least check if we need to issue an invalidation
|
|
699
|
-
if (!signedAttestations && await this.waitForSyncedL2SlotNumber(this.
|
|
704
|
+
if (!signedAttestations && await this.waitForSyncedL2SlotNumber(this.getBuildSlot())) {
|
|
700
705
|
const validationStatus = await this.l2BlockSource.getPendingChainValidationStatus();
|
|
701
706
|
if (!validationStatus.valid) {
|
|
702
707
|
this.log.warn(`Checkpoint ${validationStatus.checkpoint.checkpointNumber} has invalid attestations, enqueuing invalidation in spite of attestation collection failure`, {
|
|
@@ -769,11 +774,15 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
769
774
|
}
|
|
770
775
|
/** Enqueues the checkpoint for L1 submission. Called after pipeline sleep in execute(). */ async enqueueCheckpointForSubmission(result) {
|
|
771
776
|
const { checkpoint, attestations, attestationsSignature } = result;
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
+
this.setState(SequencerState.PUBLISHING_CHECKPOINT);
|
|
778
|
+
// Latest L1 block the propose can still land in for the target slot: the last Ethereum block inside
|
|
779
|
+
// the target slot (`target_slot_start + S - E`). This is one ethereum slot later than
|
|
780
|
+
// `attestation_deadline` (= last_ethereum_block_in_target_slot - E), which bounds when validators must
|
|
781
|
+
// have signed, not when the proposer must have sent. Using the attestation deadline here is too tight:
|
|
782
|
+
// attestations are collected up to (and, when not enforcing, past) it, so the propose tx would be
|
|
783
|
+
// enqueued already expired and time out before it can mine.
|
|
784
|
+
const lastL1BlockInTargetSlot = Number(getTimestampForSlot(this.targetSlot, this.l1Constants)) + this.l1Constants.slotDuration - this.l1Constants.ethereumSlotDuration;
|
|
785
|
+
const txTimeoutAt = new Date(lastL1BlockInTargetSlot * 1000);
|
|
777
786
|
// If we have been configured to potentially skip publishing checkpoint then roll the dice here
|
|
778
787
|
if (this.config.skipPublishingCheckpointsPercent !== undefined && this.config.skipPublishingCheckpointsPercent > 0) {
|
|
779
788
|
const roll = Math.max(0, randomInt(100));
|
|
@@ -832,8 +841,8 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
832
841
|
return true;
|
|
833
842
|
}
|
|
834
843
|
const parentCheckpointNumber = CheckpointNumber(this.checkpointNumber - 1);
|
|
835
|
-
// Wait until archiver has synced L1 past the parent's slot (
|
|
836
|
-
if (!await this.waitForSyncedL2SlotNumber(this.
|
|
844
|
+
// Wait until archiver has synced L1 past the parent's slot (the build slot, one before targetSlot)
|
|
845
|
+
if (!await this.waitForSyncedL2SlotNumber(this.getBuildSlot())) {
|
|
837
846
|
return false;
|
|
838
847
|
}
|
|
839
848
|
const tips = await this.l2BlockSource.getL2Tips();
|
|
@@ -930,7 +939,7 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
930
939
|
// Measure against the wall-clock slot whose build window we are currently using.
|
|
931
940
|
// In pipelining mode `targetSlot` is intentionally one slot ahead, which makes the
|
|
932
941
|
// target-slot boundary a full slot away from the actual build start time.
|
|
933
|
-
const slotBoundaryMs = Number(getTimestampForSlot(this.
|
|
942
|
+
const slotBoundaryMs = Number(getTimestampForSlot(this.getBuildSlot(), this.l1Constants)) * 1000;
|
|
934
943
|
this.checkpointMetrics.recordPipelinedCheckpointBuildStartOffsetFromSlotBoundary(now - slotBoundaryMs);
|
|
935
944
|
}
|
|
936
945
|
this.checkpointMetrics.startCheckpointTiming(now);
|
|
@@ -938,9 +947,9 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
938
947
|
const coinbase = this.validatorClient.getCoinbaseForAttestor(this.attestorAddress);
|
|
939
948
|
const feeRecipient = this.validatorClient.getFeeRecipientForAttestor(this.attestorAddress);
|
|
940
949
|
// Start the checkpoint
|
|
941
|
-
this.
|
|
950
|
+
this.setState(SequencerState.INITIALIZING_CHECKPOINT);
|
|
942
951
|
this.logCheckpointEvent('slot-started', `Starting checkpoint proposal for slot ${this.targetSlot}`, {
|
|
943
|
-
buildSlot: this.
|
|
952
|
+
buildSlot: this.getBuildSlot(),
|
|
944
953
|
submissionSlot: this.targetSlot,
|
|
945
954
|
slot: this.targetSlot,
|
|
946
955
|
checkpointNumber: this.checkpointNumber,
|
|
@@ -1056,7 +1065,7 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
1056
1065
|
}
|
|
1057
1066
|
// Assemble and broadcast the checkpoint proposal, including the last block that was not
|
|
1058
1067
|
// broadcasted yet, and wait to collect the committee attestations.
|
|
1059
|
-
this.
|
|
1068
|
+
this.setState(SequencerState.ASSEMBLING_CHECKPOINT);
|
|
1060
1069
|
const checkpoint = await checkpointBuilder.completeCheckpoint();
|
|
1061
1070
|
// Final validation: per-block limits are only checked if the operator set them explicitly.
|
|
1062
1071
|
// Otherwise, checkpoint-level budgets were already enforced by the redistribution logic.
|
|
@@ -1076,7 +1085,7 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
1076
1085
|
reason: 'invalid_checkpoint',
|
|
1077
1086
|
checkpoint: checkpoint.header.toInspect()
|
|
1078
1087
|
});
|
|
1079
|
-
this.log.error(`Built an invalid checkpoint at slot ${this.
|
|
1088
|
+
this.log.error(`Built an invalid checkpoint at slot ${this.targetSlot} (skipping proposal)`, err, {
|
|
1080
1089
|
slot: this.targetSlot,
|
|
1081
1090
|
checkpointNumber: this.checkpointNumber,
|
|
1082
1091
|
blocksBuilt: blocksInCheckpoint.length,
|
|
@@ -1089,7 +1098,7 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
1089
1098
|
this.checkpointMetrics.recordCheckpointBuild(checkpointBuildTimer.ms(), blocksInCheckpoint.length, checkpoint.getStats().txCount, Number(checkpoint.header.totalManaUsed.toBigInt()));
|
|
1090
1099
|
this.logCheckpointEvent('built', `Checkpoint built for slot ${this.targetSlot}`, {
|
|
1091
1100
|
slot: this.targetSlot,
|
|
1092
|
-
buildSlot: this.
|
|
1101
|
+
buildSlot: this.getBuildSlot(),
|
|
1093
1102
|
checkpointNumber: this.checkpointNumber,
|
|
1094
1103
|
proposer: this.proposer?.toString(),
|
|
1095
1104
|
attestorAddress: this.attestorAddress.toString(),
|
|
@@ -1194,13 +1203,13 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
1194
1203
|
});
|
|
1195
1204
|
break;
|
|
1196
1205
|
}
|
|
1197
|
-
const
|
|
1198
|
-
const timingInfo = this.timetable.
|
|
1206
|
+
const nowSeconds = this.dateProvider.now() / 1000;
|
|
1207
|
+
const timingInfo = this.timetable.selectNextSubslot(this.targetSlot, nowSeconds);
|
|
1199
1208
|
if (!timingInfo.canStart) {
|
|
1200
1209
|
this.log.debug(`Not enough time left in slot to start another block`, {
|
|
1201
1210
|
slot: this.targetSlot,
|
|
1202
1211
|
blocksBuilt,
|
|
1203
|
-
|
|
1212
|
+
nowSeconds
|
|
1204
1213
|
});
|
|
1205
1214
|
break;
|
|
1206
1215
|
}
|
|
@@ -1209,16 +1218,15 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
1209
1218
|
blockTimestamp: timestamp,
|
|
1210
1219
|
// Create an empty block if we haven't already and this is the last one
|
|
1211
1220
|
forceCreate: timingInfo.isLastBlock && blocksBuilt === 0 && this.config.buildCheckpointIfEmpty,
|
|
1212
|
-
|
|
1213
|
-
buildDeadline: timingInfo.deadline ? new Date((this.getSlotStartBuildTimestamp() + timingInfo.deadline) * 1000) : undefined,
|
|
1221
|
+
buildDeadline: new Date(timingInfo.deadline * 1000),
|
|
1214
1222
|
blockNumber,
|
|
1215
1223
|
indexWithinCheckpoint,
|
|
1216
1224
|
txHashesAlreadyIncluded
|
|
1217
1225
|
});
|
|
1218
1226
|
// If we failed to build the block due to insufficient txs, we try again if there is still time left in the slot
|
|
1219
1227
|
if ('failure' in buildResult) {
|
|
1220
|
-
// If this was the last subslot,
|
|
1221
|
-
if (timingInfo.isLastBlock
|
|
1228
|
+
// If this was the last subslot, we're done.
|
|
1229
|
+
if (timingInfo.isLastBlock) {
|
|
1222
1230
|
break;
|
|
1223
1231
|
}
|
|
1224
1232
|
// Otherwise, if there is still time for more blocks, we wait until the next subslot and try again
|
|
@@ -1287,12 +1295,15 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
1287
1295
|
}
|
|
1288
1296
|
return this.validatorClient.createBlockProposal(block.header, this.checkpointNumber, block.indexWithinCheckpoint, inHash, block.archive.root, usedTxs, this.proposer, blockProposalOptions);
|
|
1289
1297
|
}
|
|
1290
|
-
/**
|
|
1291
|
-
|
|
1292
|
-
|
|
1298
|
+
/**
|
|
1299
|
+
* Sleeps until it is time to produce the next block in the slot.
|
|
1300
|
+
* @param nextSubslotStart - Absolute wall-clock timestamp in seconds of the previous sub-slot deadline.
|
|
1301
|
+
*/ async waitUntilNextSubslot(nextSubslotStart) {
|
|
1302
|
+
this.setState(SequencerState.WAITING_UNTIL_NEXT_BLOCK);
|
|
1303
|
+
this.log.verbose(`Waiting until time for the next block at ${nextSubslotStart}s`, {
|
|
1293
1304
|
slot: this.targetSlot
|
|
1294
1305
|
});
|
|
1295
|
-
await this.
|
|
1306
|
+
await this.awaitInterruptibleSleep(Math.max(0, nextSubslotStart * 1000 - this.dateProvider.now()));
|
|
1296
1307
|
}
|
|
1297
1308
|
/** Builds a single block. Called from the main block building loop. */ async buildSingleBlock(checkpointBuilder, opts) {
|
|
1298
1309
|
const { blockTimestamp, forceCreate, blockNumber, indexWithinCheckpoint, buildDeadline, txHashesAlreadyIncluded } = opts;
|
|
@@ -1302,7 +1313,7 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
1302
1313
|
});
|
|
1303
1314
|
try {
|
|
1304
1315
|
// Wait until we have enough txs to build the block
|
|
1305
|
-
const {
|
|
1316
|
+
const { canStartBuilding, minTxs } = await this.waitForMinTxs(opts);
|
|
1306
1317
|
if (!canStartBuilding) {
|
|
1307
1318
|
this.logCheckpointEvent('block-build-failed', `Block build failed for slot ${this.targetSlot}`, {
|
|
1308
1319
|
reason: 'insufficient_txs',
|
|
@@ -1310,21 +1321,18 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
1310
1321
|
slot: this.targetSlot,
|
|
1311
1322
|
checkpointNumber: this.checkpointNumber,
|
|
1312
1323
|
indexWithinCheckpoint,
|
|
1313
|
-
availableTxs,
|
|
1314
1324
|
minTxs
|
|
1315
1325
|
});
|
|
1316
|
-
this.log.
|
|
1326
|
+
this.log.verbose(`Not enough age-eligible txs to build block ${blockNumber} at index ${indexWithinCheckpoint} in slot ${this.targetSlot} (needs ${minTxs} eligible)`, {
|
|
1317
1327
|
reason: 'insufficient_txs',
|
|
1318
1328
|
blockNumber,
|
|
1319
1329
|
slot: this.targetSlot,
|
|
1320
1330
|
checkpointNumber: this.checkpointNumber,
|
|
1321
1331
|
indexWithinCheckpoint,
|
|
1322
|
-
availableTxs,
|
|
1323
1332
|
minTxs
|
|
1324
1333
|
});
|
|
1325
1334
|
this.eventEmitter.emit('block-tx-count-check-failed', {
|
|
1326
1335
|
minTxs,
|
|
1327
|
-
availableTxs,
|
|
1328
1336
|
slot: this.targetSlot
|
|
1329
1337
|
});
|
|
1330
1338
|
this.metrics.recordBlockProposalFailed('insufficient_txs');
|
|
@@ -1334,13 +1342,17 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
1334
1342
|
}
|
|
1335
1343
|
// Create iterator to pending txs. We filter out txs already included in previous blocks in the checkpoint
|
|
1336
1344
|
// just in case p2p failed to sync the provisional block and didn't get to remove those txs from the mempool yet.
|
|
1337
|
-
|
|
1338
|
-
|
|
1345
|
+
// Block building only executes txs, so we skip loading their proofs unless these same tx objects get attached
|
|
1346
|
+
// to the broadcasted proposals via publishTxsWithProposals.
|
|
1347
|
+
const pendingTxs = filter(this.p2pClient.iterateEligiblePendingTxs({
|
|
1348
|
+
includeProof: !!this.config.publishTxsWithProposals
|
|
1349
|
+
}), (tx)=>!txHashesAlreadyIncluded.has(tx.txHash.toString()));
|
|
1350
|
+
this.log.debug(`Building block ${blockNumber} at index ${indexWithinCheckpoint} for slot ${this.targetSlot}`, {
|
|
1339
1351
|
slot: this.targetSlot,
|
|
1340
1352
|
blockNumber,
|
|
1341
1353
|
indexWithinCheckpoint
|
|
1342
1354
|
});
|
|
1343
|
-
this.
|
|
1355
|
+
this.setState(SequencerState.CREATING_BLOCK);
|
|
1344
1356
|
// Per-block limits are operator overrides (from SEQ_MAX_L2_BLOCK_GAS etc.) further capped
|
|
1345
1357
|
// by remaining checkpoint-level budgets inside CheckpointBuilder before each block is built.
|
|
1346
1358
|
// minValidTxs is passed into the builder so it can reject the block *before* updating state.
|
|
@@ -1351,8 +1363,9 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
1351
1363
|
deadline: buildDeadline,
|
|
1352
1364
|
isBuildingProposal: true,
|
|
1353
1365
|
minValidTxs,
|
|
1354
|
-
maxBlocksPerCheckpoint: this.timetable.
|
|
1355
|
-
perBlockAllocationMultiplier: this.config.perBlockAllocationMultiplier
|
|
1366
|
+
maxBlocksPerCheckpoint: this.timetable.getMaxBlocksPerCheckpoint(),
|
|
1367
|
+
perBlockAllocationMultiplier: this.config.perBlockAllocationMultiplier,
|
|
1368
|
+
perBlockDAAllocationMultiplier: this.config.perBlockDAAllocationMultiplier
|
|
1356
1369
|
};
|
|
1357
1370
|
// Actually build the block by executing txs. The builder throws InsufficientValidTxsError
|
|
1358
1371
|
// if the number of successfully processed txs is below minValidTxs, ensuring state is not
|
|
@@ -1413,7 +1426,7 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
1413
1426
|
checkpointNumber: this.checkpointNumber,
|
|
1414
1427
|
indexWithinCheckpoint: block.indexWithinCheckpoint,
|
|
1415
1428
|
slot: this.targetSlot,
|
|
1416
|
-
buildSlot: this.
|
|
1429
|
+
buildSlot: this.getBuildSlot()
|
|
1417
1430
|
});
|
|
1418
1431
|
this.metrics.recordBuiltBlock(blockBuildDuration, block.header.totalManaUsed.toNumberUnsafe(), this.targetSlot);
|
|
1419
1432
|
return {
|
|
@@ -1469,38 +1482,37 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
1469
1482
|
const { indexWithinCheckpoint, blockNumber, buildDeadline, forceCreate } = opts;
|
|
1470
1483
|
// We only allow a block with 0 txs in the first block of the checkpoint
|
|
1471
1484
|
const minTxs = indexWithinCheckpoint > 0 && this.config.minTxsPerBlock === 0 ? 1 : this.config.minTxsPerBlock;
|
|
1472
|
-
//
|
|
1473
|
-
const startBuildingDeadline = buildDeadline ? new Date(buildDeadline.getTime() - this.timetable.
|
|
1474
|
-
|
|
1475
|
-
|
|
1485
|
+
// Latest time to keep waiting for txs: wait_for_txs_deadline = block_build_deadline(k) - min_block_duration.
|
|
1486
|
+
const startBuildingDeadline = buildDeadline ? new Date(buildDeadline.getTime() - this.timetable.minBlockDuration * 1000) : undefined;
|
|
1487
|
+
// Gate on age-eligible txs so we don't start building on txs the builder would then filter out for being
|
|
1488
|
+
// too fresh. hasEligiblePendingTxs early-exits once minTxs are eligible instead of counting the whole pool.
|
|
1489
|
+
while(!forceCreate && !await this.p2pClient.hasEligiblePendingTxs(minTxs)){
|
|
1476
1490
|
// If we're past deadline, or we have no deadline, give up
|
|
1477
1491
|
const now = this.dateProvider.nowAsDate();
|
|
1478
1492
|
if (startBuildingDeadline === undefined || now >= startBuildingDeadline) {
|
|
1479
1493
|
return {
|
|
1480
1494
|
canStartBuilding: false,
|
|
1481
|
-
availableTxs,
|
|
1482
1495
|
minTxs
|
|
1483
1496
|
};
|
|
1484
1497
|
}
|
|
1485
1498
|
// Wait a bit before checking again
|
|
1486
|
-
this.
|
|
1487
|
-
this.log.verbose(`Waiting for
|
|
1499
|
+
this.setState(SequencerState.WAITING_FOR_TXS);
|
|
1500
|
+
this.log.verbose(`Waiting for ${minTxs} age-eligible txs to build block ${blockNumber} at index ${indexWithinCheckpoint} in slot ${this.targetSlot}`, {
|
|
1488
1501
|
blockNumber,
|
|
1489
1502
|
slot: this.targetSlot,
|
|
1490
|
-
indexWithinCheckpoint
|
|
1503
|
+
indexWithinCheckpoint,
|
|
1504
|
+
minTxs
|
|
1491
1505
|
});
|
|
1492
1506
|
await this.waitForTxsPollingInterval();
|
|
1493
|
-
availableTxs = await this.p2pClient.getPendingTxCount();
|
|
1494
1507
|
}
|
|
1495
1508
|
return {
|
|
1496
1509
|
canStartBuilding: true,
|
|
1497
|
-
availableTxs,
|
|
1498
1510
|
minTxs
|
|
1499
1511
|
};
|
|
1500
1512
|
}
|
|
1501
1513
|
async getSignedCommitteeAttestations(broadcast) {
|
|
1502
1514
|
const { proposal, blockProposedAt } = broadcast;
|
|
1503
|
-
this.
|
|
1515
|
+
this.setState(SequencerState.COLLECTING_ATTESTATIONS);
|
|
1504
1516
|
const attestations = await this.waitForAttestations(proposal);
|
|
1505
1517
|
if (!attestations) {
|
|
1506
1518
|
return undefined;
|
|
@@ -1551,9 +1563,10 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
1551
1563
|
});
|
|
1552
1564
|
return new CommitteeAttestationsAndSigners(orderAttestations(attestations ?? [], committee), this.getSignatureContext());
|
|
1553
1565
|
}
|
|
1554
|
-
|
|
1555
|
-
const
|
|
1556
|
-
|
|
1566
|
+
// Hard attestation-collection cutoff = the single consensus attestation_deadline (target_slot_start + S - 2E).
|
|
1567
|
+
const attestationDeadlineSeconds = this.timetable.getAttestationDeadline(this.targetSlot);
|
|
1568
|
+
const attestationDeadline = new Date(attestationDeadlineSeconds * 1000);
|
|
1569
|
+
this.metrics.recordRequiredAttestations(numberOfRequiredAttestations, Math.max(0, attestationDeadline.getTime() - this.dateProvider.now()));
|
|
1557
1570
|
const collectAttestationsTimer = new Timer();
|
|
1558
1571
|
let collectedAttestationsCount = 0;
|
|
1559
1572
|
try {
|
|
@@ -1571,7 +1584,7 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
1571
1584
|
submittedCount: trimmed.length
|
|
1572
1585
|
});
|
|
1573
1586
|
// Manipulate the attestations if we've been configured to do so
|
|
1574
|
-
if (this.config.injectFakeAttestation || this.config.injectHighSValueAttestation || this.config.injectUnrecoverableSignatureAttestation || this.config.shuffleAttestationOrdering) {
|
|
1587
|
+
if (this.config.injectFakeAttestation || this.config.injectHighSValueAttestation || this.config.injectUnrecoverableSignatureAttestation || this.config.injectYParityAttestation || this.config.shuffleAttestationOrdering) {
|
|
1575
1588
|
return this.manipulateAttestations(proposal.slotNumber, epoch, seed, committee, sorted);
|
|
1576
1589
|
}
|
|
1577
1590
|
return new CommitteeAttestationsAndSigners(sorted, this.getSignatureContext());
|
|
@@ -1643,6 +1656,14 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
1643
1656
|
}
|
|
1644
1657
|
return new CommitteeAttestationsAndSigners(attestations, this.getSignatureContext());
|
|
1645
1658
|
}
|
|
1659
|
+
if (this.config.injectYParityAttestation) {
|
|
1660
|
+
// Force every non-proposer signed slot's recovery byte to yParity (v ∈ {0, 1}) form in the packed L1
|
|
1661
|
+
// tuple, after packAttestations has canonicalized it. The proposer's own slot is left canonical so
|
|
1662
|
+
// propose() still passes verifyProposer. Models a malicious proposer landing a checkpoint L1 accepts
|
|
1663
|
+
// but that can never be proven (ECDSA.recover rejects v ∉ {27, 28}).
|
|
1664
|
+
this.log.warn(`Injecting yParity attestations in checkpoint for slot ${slotNumber} (proposer #${proposerIndex})`);
|
|
1665
|
+
return new MaliciousYParityCommitteeAttestationsAndSigners(attestations, proposerIndex, this.getSignatureContext());
|
|
1666
|
+
}
|
|
1646
1667
|
if (this.config.shuffleAttestationOrdering) {
|
|
1647
1668
|
this.log.warn(`Shuffling attestation ordering in checkpoint for slot ${slotNumber} (proposer #${proposerIndex})`);
|
|
1648
1669
|
const shuffled = [
|
|
@@ -1771,22 +1792,9 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
1771
1792
|
}
|
|
1772
1793
|
return false;
|
|
1773
1794
|
}
|
|
1774
|
-
/** Waits
|
|
1775
|
-
const slotStartTimestamp = this.getSlotStartBuildTimestamp();
|
|
1776
|
-
const targetTimestamp = slotStartTimestamp + targetSecondsIntoSlot;
|
|
1777
|
-
const delayMs = targetTimestamp * 1000 - this.dateProvider.nowAsDate().getTime();
|
|
1778
|
-
await this.awaitInterruptibleSleep(delayMs);
|
|
1779
|
-
}
|
|
1780
|
-
/** Pause between mempool polls in waitForMinTxs. Extracted for test overriding. */ async waitForTxsPollingInterval() {
|
|
1795
|
+
/** Waits the polling interval for transactions. Extracted for test overriding. */ async waitForTxsPollingInterval() {
|
|
1781
1796
|
await this.awaitInterruptibleSleep(TXS_POLLING_MS);
|
|
1782
1797
|
}
|
|
1783
|
-
getSlotStartBuildTimestamp() {
|
|
1784
|
-
return getSlotStartBuildTimestamp(this.slotNow, this.l1Constants);
|
|
1785
|
-
}
|
|
1786
|
-
getSecondsIntoSlot() {
|
|
1787
|
-
const slotStartTimestamp = this.getSlotStartBuildTimestamp();
|
|
1788
|
-
return Number((this.dateProvider.now() / 1000 - slotStartTimestamp).toFixed(3));
|
|
1789
|
-
}
|
|
1790
1798
|
getPublisher() {
|
|
1791
1799
|
return this.publisher;
|
|
1792
1800
|
}
|
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
import type { SequencerState } from './utils.js';
|
|
2
|
-
export declare class SequencerTooSlowError extends Error {
|
|
3
|
-
readonly proposedState: SequencerState;
|
|
4
|
-
readonly maxAllowedTime: number;
|
|
5
|
-
readonly currentTime: number;
|
|
6
|
-
constructor(proposedState: SequencerState, maxAllowedTime: number, currentTime: number);
|
|
7
|
-
}
|
|
8
1
|
export declare class SequencerInterruptedError extends Error {
|
|
9
2
|
constructor();
|
|
10
3
|
}
|
|
11
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
4
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJyb3JzLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VxdWVuY2VyL2Vycm9ycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxxQkFBYSx5QkFBMEIsU0FBUSxLQUFLO0lBQ2xELGNBR0M7Q0FDRiJ9
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/sequencer/errors.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/sequencer/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,yBAA0B,SAAQ,KAAK;IAClD,cAGC;CACF"}
|
package/dest/sequencer/errors.js
CHANGED
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
export class SequencerTooSlowError extends Error {
|
|
2
|
-
proposedState;
|
|
3
|
-
maxAllowedTime;
|
|
4
|
-
currentTime;
|
|
5
|
-
constructor(proposedState, maxAllowedTime, currentTime){
|
|
6
|
-
super(`Too far into slot for ${proposedState} (time into slot ${currentTime}s greater than ${maxAllowedTime}s allowance)`), this.proposedState = proposedState, this.maxAllowedTime = maxAllowedTime, this.currentTime = currentTime;
|
|
7
|
-
this.name = 'SequencerTooSlowError';
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
1
|
export class SequencerInterruptedError extends Error {
|
|
11
2
|
constructor(){
|
|
12
3
|
super(`Sequencer was interrupted`);
|
|
@@ -3,12 +3,24 @@ import type { BlockHash } from '@aztec/stdlib/block';
|
|
|
3
3
|
import type { Action } from '../publisher/sequencer-publisher.js';
|
|
4
4
|
import type { SequencerState } from './utils.js';
|
|
5
5
|
export type SequencerEvents = {
|
|
6
|
+
/**
|
|
7
|
+
* Emitted on every sequencer state transition (including no-op transitions to the same state). The
|
|
8
|
+
* timing fields are anchored to the build frame of the slot being proposed for, not to wall-clock
|
|
9
|
+
* slot boundaries, because the proposer builds for `targetSlot` during the previous (build) slot.
|
|
10
|
+
*
|
|
11
|
+
* - `oldState` / `newState` are the previous and new {@link SequencerState}.
|
|
12
|
+
* - `secondsIntoBuildFrame` is the wall-clock seconds elapsed since the build-frame start of
|
|
13
|
+
* `targetSlot` (`now − getBuildFrameStart(targetSlot)`). Undefined for lifecycle states with no
|
|
14
|
+
* associated slot (e.g. IDLE/STOPPING). It can be negative if the transition happens before the
|
|
15
|
+
* build frame opens.
|
|
16
|
+
* - `targetSlot` is the slot the checkpoint is being proposed for (the submission slot, one ahead of
|
|
17
|
+
* the wall-clock build slot under pipelining). Undefined for lifecycle states with no slot.
|
|
18
|
+
*/
|
|
6
19
|
['state-changed']: (args: {
|
|
7
20
|
oldState: SequencerState;
|
|
8
21
|
newState: SequencerState;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
timeReferenceSlot?: SlotNumber;
|
|
22
|
+
secondsIntoBuildFrame?: number;
|
|
23
|
+
targetSlot?: SlotNumber;
|
|
12
24
|
}) => void;
|
|
13
25
|
/**
|
|
14
26
|
* Emitted by the sequencer once it has decided it is going to attempt to build a
|
|
@@ -40,7 +52,6 @@ export type SequencerEvents = {
|
|
|
40
52
|
}) => void;
|
|
41
53
|
['block-tx-count-check-failed']: (args: {
|
|
42
54
|
minTxs: number;
|
|
43
|
-
availableTxs: number;
|
|
44
55
|
slot: SlotNumber;
|
|
45
56
|
}) => void;
|
|
46
57
|
['block-build-failed']: (args: {
|
|
@@ -89,4 +100,4 @@ export type SequencerEvents = {
|
|
|
89
100
|
reason: string;
|
|
90
101
|
}) => void;
|
|
91
102
|
};
|
|
92
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
103
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXZlbnRzLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VxdWVuY2VyL2V2ZW50cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssRUFBRSxXQUFXLEVBQUUsZ0JBQWdCLEVBQUUscUJBQXFCLEVBQUUsVUFBVSxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDeEgsT0FBTyxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFckQsT0FBTyxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDbEUsT0FBTyxLQUFLLEVBQUUsY0FBYyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRWpELE1BQU0sTUFBTSxlQUFlLEdBQUc7SUFDNUI7Ozs7Ozs7Ozs7OztPQVlHO0lBQ0gsQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRTtRQUN4QixRQUFRLEVBQUUsY0FBYyxDQUFDO1FBQ3pCLFFBQVEsRUFBRSxjQUFjLENBQUM7UUFDekIscUJBQXFCLENBQUMsRUFBRSxNQUFNLENBQUM7UUFDL0IsVUFBVSxDQUFDLEVBQUUsVUFBVSxDQUFDO0tBQ3pCLEtBQUssSUFBSSxDQUFDO0lBQ1g7Ozs7Ozs7Ozs7Ozs7Ozs7T0FnQkc7SUFDSCxDQUFDLHNCQUFzQixDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUU7UUFDL0IsVUFBVSxFQUFFLFVBQVUsQ0FBQztRQUN2QixnQkFBZ0IsRUFBRSxnQkFBZ0IsQ0FBQztRQUNuQyxpQkFBaUIsRUFBRSxPQUFPLENBQUM7UUFDM0IsY0FBYyxFQUFFLGdCQUFnQixHQUFHLFNBQVMsQ0FBQztRQUM3QyxnQkFBZ0IsRUFBRSxnQkFBZ0IsR0FBRyxTQUFTLENBQUM7S0FDaEQsS0FBSyxJQUFJLENBQUM7SUFDWCxDQUFDLDhCQUE4QixDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUU7UUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDO1FBQUMsSUFBSSxFQUFFLFVBQVUsQ0FBQTtLQUFFLEtBQUssSUFBSSxDQUFDO0lBQ3ZGLENBQUMsNkJBQTZCLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRTtRQUFFLE1BQU0sRUFBRSxNQUFNLENBQUM7UUFBQyxJQUFJLEVBQUUsVUFBVSxDQUFBO0tBQUUsS0FBSyxJQUFJLENBQUM7SUFDdEYsQ0FBQyxvQkFBb0IsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFO1FBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQztRQUFDLElBQUksRUFBRSxVQUFVLENBQUE7S0FBRSxLQUFLLElBQUksQ0FBQztJQUM3RSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUU7UUFDekIsV0FBVyxFQUFFLFdBQVcsQ0FBQztRQUN6QixTQUFTLEVBQUUsU0FBUyxDQUFDO1FBQ3JCLGdCQUFnQixFQUFFLGdCQUFnQixDQUFDO1FBQ25DLHFCQUFxQixFQUFFLHFCQUFxQixDQUFDO1FBQzdDLElBQUksRUFBRSxVQUFVLENBQUM7UUFDakIsU0FBUyxFQUFFLFVBQVUsQ0FBQztLQUN2QixLQUFLLElBQUksQ0FBQztJQUNYLENBQUMsa0JBQWtCLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRTtRQUFFLElBQUksRUFBRSxVQUFVLENBQUE7S0FBRSxLQUFLLElBQUksQ0FBQztJQUMzRDs7Ozs7T0FLRztJQUNILENBQUMsMEJBQTBCLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRTtRQUNuQyxJQUFJLEVBQUUsVUFBVSxDQUFDO1FBQ2pCLGdCQUFnQixFQUFFLGdCQUFnQixDQUFDO1FBQ25DLE1BQU0sRUFBRSxNQUFNLENBQUM7S0FDaEIsS0FBSyxJQUFJLENBQUM7SUFDWCxDQUFDLDJCQUEyQixDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUU7UUFDcEMsSUFBSSxFQUFFLFVBQVUsQ0FBQztRQUNqQixpQkFBaUIsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDO1FBQzdCLGFBQWEsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDO1FBQ3pCLFdBQVcsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDO1FBQ3ZCLGNBQWMsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDO0tBQzNCLEtBQUssSUFBSSxDQUFDO0lBQ1gsQ0FBQyxzQkFBc0IsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFO1FBQUUsVUFBVSxFQUFFLGdCQUFnQixDQUFDO1FBQUMsSUFBSSxFQUFFLFVBQVUsQ0FBQTtLQUFFLEtBQUssSUFBSSxDQUFDO0lBQzdGLENBQUMsa0JBQWtCLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRTtRQUFFLEtBQUssRUFBRSxLQUFLLENBQUE7S0FBRSxLQUFLLElBQUksQ0FBQztJQUN2RCxDQUFDLGdDQUFnQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUU7UUFDekMsSUFBSSxFQUFFLFVBQVUsQ0FBQztRQUNqQixnQkFBZ0IsRUFBRSxnQkFBZ0IsQ0FBQztRQUNuQyxNQUFNLEVBQUUsTUFBTSxDQUFDO0tBQ2hCLEtBQUssSUFBSSxDQUFDO0NBQ1osQ0FBQyJ9
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/sequencer/events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AACxH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,MAAM,eAAe,GAAG;IAC5B,CAAC,eAAe,CAAC,EAAE,CAAC,IAAI,EAAE;QACxB,QAAQ,EAAE,cAAc,CAAC;QACzB,QAAQ,EAAE,cAAc,CAAC;QACzB,
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/sequencer/events.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
export * from './automine/automine_factory.js';
|
|
2
|
-
export * from './automine/automine_sequencer.js';
|
|
3
1
|
export * from './checkpoint_proposal_job.js';
|
|
4
2
|
export * from './checkpoint_voter.js';
|
|
5
3
|
export * from './config.js';
|
|
6
4
|
export * from './events.js';
|
|
7
5
|
export * from './sequencer.js';
|
|
8
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
6
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXF1ZW5jZXIvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyw4QkFBOEIsQ0FBQztBQUM3QyxjQUFjLHVCQUF1QixDQUFDO0FBQ3RDLGNBQWMsYUFBYSxDQUFDO0FBQzVCLGNBQWMsYUFBYSxDQUFDO0FBQzVCLGNBQWMsZ0JBQWdCLENBQUMifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sequencer/index.ts"],"names":[],"mappings":"AAAA,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sequencer/index.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAC;AAC7C,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC"}
|