@aztec/sequencer-client 5.0.0-nightly.20260705 → 5.0.0-nightly.20260706
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 +16 -3
- package/dest/client/sequencer-client.d.ts.map +1 -1
- package/dest/client/sequencer-client.js +17 -3
- package/dest/config.js +1 -1
- package/dest/sequencer/checkpoint_proposal_job.d.ts +4 -6
- package/dest/sequencer/checkpoint_proposal_job.d.ts.map +1 -1
- package/dest/sequencer/checkpoint_proposal_job.js +8 -9
- 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 +38 -4
- package/dest/sequencer/sequencer.d.ts.map +1 -1
- package/dest/sequencer/sequencer.js +81 -21
- package/package.json +27 -27
- package/src/client/sequencer-client.ts +19 -3
- package/src/config.ts +1 -1
- package/src/sequencer/checkpoint_proposal_job.ts +9 -11
- package/src/sequencer/requests_tracker.ts +43 -0
- package/src/sequencer/sequencer.ts +83 -15
|
@@ -62,12 +62,25 @@ export declare class SequencerClient {
|
|
|
62
62
|
* @param config - New parameters.
|
|
63
63
|
*/
|
|
64
64
|
updateConfig(config: SequencerConfig & Partial<ValidatorClientFullConfig>): void;
|
|
65
|
-
/**
|
|
65
|
+
/**
|
|
66
|
+
* Starts (or resumes) the sequencer, validator, publishers, and metrics. Each underlying start is
|
|
67
|
+
* idempotent, so this is safe to call after a previous {@link pause} to resume building and publishing.
|
|
68
|
+
* The publisher manager is started before the sequencer's poll loop so publishing is ready before the
|
|
69
|
+
* sequencer first tries to publish to L1.
|
|
70
|
+
*/
|
|
66
71
|
start(): Promise<void>;
|
|
67
72
|
/**
|
|
68
|
-
* Stops the sequencer
|
|
73
|
+
* Stops the sequencer, validator, publishers, and metrics for good, draining in-flight work. This is the
|
|
74
|
+
* final teardown path: stopping the validator client closes its slashing-protection database. For a
|
|
75
|
+
* restartable pause (e.g. around a test clock warp) use {@link pause} instead.
|
|
69
76
|
*/
|
|
70
77
|
stop(): Promise<void>;
|
|
78
|
+
/**
|
|
79
|
+
* Gracefully pauses block production, waiting for in-flight work to finish rather than interrupting it,
|
|
80
|
+
* while leaving the validator, publishers, and metrics running so the sequencer can be resumed with
|
|
81
|
+
* {@link start}. Used by tests that pause sequencers around an L1 clock warp.
|
|
82
|
+
*/
|
|
83
|
+
pause(): Promise<void>;
|
|
71
84
|
/** Triggers an immediate run of the sequencer, bypassing the polling interval. */
|
|
72
85
|
trigger(): Promise<void> | undefined;
|
|
73
86
|
getSequencer(): Sequencer;
|
|
@@ -78,4 +91,4 @@ export declare class SequencerClient {
|
|
|
78
91
|
get validatorAddresses(): EthAddress[] | undefined;
|
|
79
92
|
get maxL2BlockGas(): number | undefined;
|
|
80
93
|
}
|
|
81
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
94
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VxdWVuY2VyLWNsaWVudC5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NsaWVudC9zZXF1ZW5jZXItY2xpZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFFckUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBR2hELE9BQU8sRUFBRSxLQUFLLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUN0RSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUNyRSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFFM0QsT0FBTyxLQUFLLEVBQUUsWUFBWSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDNUQsT0FBTyxLQUFLLEVBQUUsZUFBZSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDNUQsT0FBTyxLQUFLLEVBQUUsR0FBRyxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ3RDLE9BQU8sS0FBSyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0QsT0FBTyxLQUFLLEVBQUUsV0FBVyxFQUFFLGFBQWEsRUFBRSxzQkFBc0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQzlGLE9BQU8sS0FBSyxFQUFFLHlCQUF5QixFQUFFLHNCQUFzQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDekcsT0FBTyxLQUFLLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNuRSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssZUFBZSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDMUUsT0FBTyxFQUFFLDBCQUEwQixFQUFFLG1CQUFtQixFQUFFLEtBQUssZUFBZSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFaEgsT0FBTyxFQUFFLEtBQUsscUJB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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sequencer-client.d.ts","sourceRoot":"","sources":["../../src/client/sequencer-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAErE,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGhD,OAAO,EAAE,KAAK,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC9F,OAAO,KAAK,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzG,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1E,OAAO,EAAE,0BAA0B,EAAE,mBAAmB,EAAE,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAEhH,OAAO,EAAE,KAAK,qBAAqB,EAAyC,MAAM,cAAc,CAAC;AACjG,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AACjF,OAAO,EAAE,yBAAyB,EAAE,MAAM,6CAA6C,CAAC;AACxF,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExE;;GAEG;AACH,qBAAa,eAAe;IAExB,SAAS,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,SAAS,CAAC;IACvD,SAAS,CAAC,SAAS,EAAE,SAAS;IAC9B,SAAS,CAAC,kBAAkB,EAAE,0BAA0B;IACxD,SAAS,CAAC,eAAe,CAAC;IAC1B,OAAO,CAAC,SAAS,CAAC;IAClB,OAAO,CAAC,QAAQ,CAAC;IANnB,YACY,gBAAgB,EAAE,gBAAgB,CAAC,SAAS,CAAC,EAC7C,SAAS,EAAE,SAAS,EACpB,kBAAkB,EAAE,0BAA0B,EAC9C,eAAe,CAAC,6BAAiB,EACnC,SAAS,CAAC,uBAAW,EACrB,QAAQ,CAAC,qBAAS,EACxB;IAEJ;;;;;;;;;;;OAWG;IACH,OAAoB,GAAG,CACrB,MAAM,EAAE,qBAAqB,EAC7B,IAAI,EAAE;QACJ,eAAe,EAAE,eAAe,CAAC;QACjC,SAAS,EAAE,GAAG,CAAC;QACf,sBAAsB,EAAE,sBAAsB,CAAC;QAC/C,aAAa,EAAE,sBAAsB,GAAG,SAAS,CAAC;QAClD,kBAAkB,EAAE,0BAA0B,CAAC;QAC/C,aAAa,EAAE,aAAa,GAAG,WAAW,GAAG,sBAAsB,CAAC;QACpE,mBAAmB,EAAE,mBAAmB,CAAC;QACzC,SAAS,EAAE,eAAe,CAAC;QAC3B,gBAAgB,CAAC,EAAE,yBAAyB,CAAC;QAC7C,UAAU,EAAE,mBAAmB,CAAC;QAChC,YAAY,EAAE,YAAY,CAAC;QAC3B,UAAU,CAAC,EAAE,UAAU,CAAC;QACxB,SAAS,EAAE,SAAS,EAAE,CAAC;QACvB,eAAe,CAAC,EAAE,SAAS,CAAC;QAC5B,YAAY,EAAE,eAAe,CAAC;QAC9B,qBAAqB,EAAE,qBAAqB,CAAC;KAC9C,4BAsGF;IAED;;;OAGG;IACI,YAAY,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,yBAAyB,CAAC,QAI/E;IAED
|
|
1
|
+
{"version":3,"file":"sequencer-client.d.ts","sourceRoot":"","sources":["../../src/client/sequencer-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAErE,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAGhD,OAAO,EAAE,KAAK,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC9F,OAAO,KAAK,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzG,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1E,OAAO,EAAE,0BAA0B,EAAE,mBAAmB,EAAE,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAEhH,OAAO,EAAE,KAAK,qBAAqB,EAAyC,MAAM,cAAc,CAAC;AACjG,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AACjF,OAAO,EAAE,yBAAyB,EAAE,MAAM,6CAA6C,CAAC;AACxF,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExE;;GAEG;AACH,qBAAa,eAAe;IAExB,SAAS,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,SAAS,CAAC;IACvD,SAAS,CAAC,SAAS,EAAE,SAAS;IAC9B,SAAS,CAAC,kBAAkB,EAAE,0BAA0B;IACxD,SAAS,CAAC,eAAe,CAAC;IAC1B,OAAO,CAAC,SAAS,CAAC;IAClB,OAAO,CAAC,QAAQ,CAAC;IANnB,YACY,gBAAgB,EAAE,gBAAgB,CAAC,SAAS,CAAC,EAC7C,SAAS,EAAE,SAAS,EACpB,kBAAkB,EAAE,0BAA0B,EAC9C,eAAe,CAAC,6BAAiB,EACnC,SAAS,CAAC,uBAAW,EACrB,QAAQ,CAAC,qBAAS,EACxB;IAEJ;;;;;;;;;;;OAWG;IACH,OAAoB,GAAG,CACrB,MAAM,EAAE,qBAAqB,EAC7B,IAAI,EAAE;QACJ,eAAe,EAAE,eAAe,CAAC;QACjC,SAAS,EAAE,GAAG,CAAC;QACf,sBAAsB,EAAE,sBAAsB,CAAC;QAC/C,aAAa,EAAE,sBAAsB,GAAG,SAAS,CAAC;QAClD,kBAAkB,EAAE,0BAA0B,CAAC;QAC/C,aAAa,EAAE,aAAa,GAAG,WAAW,GAAG,sBAAsB,CAAC;QACpE,mBAAmB,EAAE,mBAAmB,CAAC;QACzC,SAAS,EAAE,eAAe,CAAC;QAC3B,gBAAgB,CAAC,EAAE,yBAAyB,CAAC;QAC7C,UAAU,EAAE,mBAAmB,CAAC;QAChC,YAAY,EAAE,YAAY,CAAC;QAC3B,UAAU,CAAC,EAAE,UAAU,CAAC;QACxB,SAAS,EAAE,SAAS,EAAE,CAAC;QACvB,eAAe,CAAC,EAAE,SAAS,CAAC;QAC5B,YAAY,EAAE,eAAe,CAAC;QAC9B,qBAAqB,EAAE,qBAAqB,CAAC;KAC9C,4BAsGF;IAED;;;OAGG;IACI,YAAY,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,yBAAyB,CAAC,QAI/E;IAED;;;;;OAKG;IACU,KAAK,kBAKjB;IAED;;;;OAIG;IACU,IAAI,kBAKhB;IAED;;;;OAIG;IACU,KAAK,kBAEjB;IAED,kFAAkF;IAC3E,OAAO,8BAEb;IAEM,YAAY,IAAI,SAAS,CAE/B;IAED,qFAAqF;IAC9E,2BAA2B,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI,CAErE;IAED,iFAAiF;IACjF,UAAU,IAAI,OAAO,GAAG,SAAS,CAEhC;IAED,IAAI,kBAAkB,IAAI,UAAU,EAAE,GAAG,SAAS,CAEjD;IAED,IAAI,aAAa,IAAI,MAAM,GAAG,SAAS,CAEtC;CACF"}
|
|
@@ -103,20 +103,34 @@ import { Sequencer } from '../sequencer/index.js';
|
|
|
103
103
|
this.checkpointsBuilder.updateConfig(config);
|
|
104
104
|
this.validatorClient?.updateConfig(config);
|
|
105
105
|
}
|
|
106
|
-
/**
|
|
106
|
+
/**
|
|
107
|
+
* Starts (or resumes) the sequencer, validator, publishers, and metrics. Each underlying start is
|
|
108
|
+
* idempotent, so this is safe to call after a previous {@link pause} to resume building and publishing.
|
|
109
|
+
* The publisher manager is started before the sequencer's poll loop so publishing is ready before the
|
|
110
|
+
* sequencer first tries to publish to L1.
|
|
111
|
+
*/ async start() {
|
|
107
112
|
await this.validatorClient?.start();
|
|
113
|
+
await this.publisherManager.start();
|
|
108
114
|
this.sequencer.start();
|
|
109
115
|
this.l1Metrics?.start();
|
|
110
|
-
await this.publisherManager.start();
|
|
111
116
|
}
|
|
112
117
|
/**
|
|
113
|
-
* Stops the sequencer
|
|
118
|
+
* Stops the sequencer, validator, publishers, and metrics for good, draining in-flight work. This is the
|
|
119
|
+
* final teardown path: stopping the validator client closes its slashing-protection database. For a
|
|
120
|
+
* restartable pause (e.g. around a test clock warp) use {@link pause} instead.
|
|
114
121
|
*/ async stop() {
|
|
115
122
|
await this.sequencer.stop();
|
|
116
123
|
await this.validatorClient?.stop();
|
|
117
124
|
await this.publisherManager.stop();
|
|
118
125
|
this.l1Metrics?.stop();
|
|
119
126
|
}
|
|
127
|
+
/**
|
|
128
|
+
* Gracefully pauses block production, waiting for in-flight work to finish rather than interrupting it,
|
|
129
|
+
* while leaving the validator, publishers, and metrics running so the sequencer can be resumed with
|
|
130
|
+
* {@link start}. Used by tests that pause sequencers around an L1 clock warp.
|
|
131
|
+
*/ async pause() {
|
|
132
|
+
await this.sequencer.pause();
|
|
133
|
+
}
|
|
120
134
|
/** Triggers an immediate run of the sequencer, bypassing the polling interval. */ trigger() {
|
|
121
135
|
return this.sequencer.trigger();
|
|
122
136
|
}
|
package/dest/config.js
CHANGED
|
@@ -187,7 +187,7 @@ export const sequencerConfigMappings = {
|
|
|
187
187
|
...booleanConfigHelper(DefaultSequencerConfig.buildCheckpointIfEmpty)
|
|
188
188
|
},
|
|
189
189
|
skipPushProposedBlocksToArchiver: {
|
|
190
|
-
description: 'Skip pushing proposed blocks to archiver (
|
|
190
|
+
description: 'Skip pushing proposed blocks to archiver (test only)',
|
|
191
191
|
...booleanConfigHelper(DefaultSequencerConfig.skipPushProposedBlocksToArchiver)
|
|
192
192
|
},
|
|
193
193
|
minBlocksForCheckpoint: {
|
|
@@ -20,6 +20,7 @@ import type { InvalidateCheckpointRequest, SequencerPublisher } from '../publish
|
|
|
20
20
|
import type { CheckpointProposalJobMetricsRecorder } from './checkpoint_proposal_job_metrics.js';
|
|
21
21
|
import type { SequencerEvents } from './events.js';
|
|
22
22
|
import type { SequencerMetrics } from './metrics.js';
|
|
23
|
+
import type { RequestsTracker } from './requests_tracker.js';
|
|
23
24
|
import type { SequencerRollupConstants } from './types.js';
|
|
24
25
|
import { SequencerState } from './utils.js';
|
|
25
26
|
/**
|
|
@@ -56,13 +57,12 @@ export declare class CheckpointProposalJob implements Traceable {
|
|
|
56
57
|
private readonly metrics;
|
|
57
58
|
private readonly checkpointMetrics;
|
|
58
59
|
protected readonly eventEmitter: TypedEventEmitter<SequencerEvents>;
|
|
60
|
+
protected readonly pendingRequests: RequestsTracker;
|
|
59
61
|
private readonly setStateFn;
|
|
60
62
|
readonly tracer: Tracer;
|
|
61
63
|
private readonly proposedCheckpointData?;
|
|
62
64
|
protected readonly log: Logger;
|
|
63
65
|
private readonly checkpointEventLog;
|
|
64
|
-
/** Tracks the fire-and-forget L1 submission promise so it can be awaited during shutdown. */
|
|
65
|
-
private pendingL1Submission;
|
|
66
66
|
private readonly interruptibleSleep;
|
|
67
67
|
private interrupted;
|
|
68
68
|
/**
|
|
@@ -73,7 +73,7 @@ export declare class CheckpointProposalJob implements Traceable {
|
|
|
73
73
|
*/
|
|
74
74
|
private checkpointSimulationOverridesPlan?;
|
|
75
75
|
private getSignatureContext;
|
|
76
|
-
constructor(targetSlot: SlotNumber, targetEpoch: EpochNumber, checkpointNumber: CheckpointNumber, syncedToBlockNumber: BlockNumber, checkpointedCheckpointNumber: CheckpointNumber, proposer: EthAddress | undefined, publisher: SequencerPublisher, attestorAddress: EthAddress, invalidateCheckpoint: InvalidateCheckpointRequest | undefined, validatorClient: ValidatorClient, globalsBuilder: GlobalVariableBuilder, p2pClient: P2P, worldState: WorldStateSynchronizer, l1ToL2MessageSource: L1ToL2MessageSource, l2BlockSource: L2BlockSource, checkpointsBuilder: FullNodeCheckpointsBuilder, blockSink: L2BlockSink & ProposedCheckpointSink, l1Constants: SequencerRollupConstants, signatureContext: CoordinationSignatureContext, config: ResolvedSequencerConfig, timetable: ProposerTimetable, slasherClient: SlasherClientInterface | undefined, epochCache: EpochCache, dateProvider: DateProvider, metrics: SequencerMetrics, checkpointMetrics: CheckpointProposalJobMetricsRecorder, eventEmitter: TypedEventEmitter<SequencerEvents>, setStateFn: (state: SequencerState, slot: SlotNumber) => void, tracer: Tracer, bindings?: LoggerBindings, proposedCheckpointData?: ProposedCheckpointData | undefined);
|
|
76
|
+
constructor(targetSlot: SlotNumber, targetEpoch: EpochNumber, checkpointNumber: CheckpointNumber, syncedToBlockNumber: BlockNumber, checkpointedCheckpointNumber: CheckpointNumber, proposer: EthAddress | undefined, publisher: SequencerPublisher, attestorAddress: EthAddress, invalidateCheckpoint: InvalidateCheckpointRequest | undefined, validatorClient: ValidatorClient, globalsBuilder: GlobalVariableBuilder, p2pClient: P2P, worldState: WorldStateSynchronizer, l1ToL2MessageSource: L1ToL2MessageSource, l2BlockSource: L2BlockSource, checkpointsBuilder: FullNodeCheckpointsBuilder, blockSink: L2BlockSink & ProposedCheckpointSink, l1Constants: SequencerRollupConstants, signatureContext: CoordinationSignatureContext, config: ResolvedSequencerConfig, timetable: ProposerTimetable, slasherClient: SlasherClientInterface | undefined, epochCache: EpochCache, dateProvider: DateProvider, metrics: SequencerMetrics, checkpointMetrics: CheckpointProposalJobMetricsRecorder, eventEmitter: TypedEventEmitter<SequencerEvents>, pendingRequests: RequestsTracker, setStateFn: (state: SequencerState, slot: SlotNumber) => void, tracer: Tracer, bindings?: LoggerBindings, proposedCheckpointData?: ProposedCheckpointData | undefined);
|
|
77
77
|
/**
|
|
78
78
|
* The wall-clock slot during which this job builds, i.e. the slot one before {@link targetSlot} under
|
|
79
79
|
* proposer pipelining. Also the slot of the parent checkpoint this job builds on top of.
|
|
@@ -85,8 +85,6 @@ export declare class CheckpointProposalJob implements Traceable {
|
|
|
85
85
|
* its own target slot, so callers only pass the state.
|
|
86
86
|
*/
|
|
87
87
|
private setState;
|
|
88
|
-
/** Awaits the pending L1 submission if one is in progress. Call during shutdown. */
|
|
89
|
-
awaitPendingSubmission(): Promise<void>;
|
|
90
88
|
/** Interrupts job-owned waits, including the publisher's send-at-slot sleep, so shutdown can finish. */
|
|
91
89
|
interrupt(): void;
|
|
92
90
|
private awaitInterruptibleSleep;
|
|
@@ -157,4 +155,4 @@ export declare class CheckpointProposalJob implements Traceable {
|
|
|
157
155
|
protected waitForTxsPollingInterval(): Promise<void>;
|
|
158
156
|
getPublisher(): SequencerPublisher;
|
|
159
157
|
}
|
|
160
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
158
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2twb2ludF9wcm9wb3NhbF9qb2IuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXF1ZW5jZXIvY2hlY2twb2ludF9wcm9wb3NhbF9qb2IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLEtBQUssVUFBVSxFQUFtQyxNQUFNLG9CQUFvQixDQUFDO0FBRXRGLE9BQU8sRUFDTCxXQUFXLEVBQ1gsZ0JBQWdCLEVBQ2hCLFdBQVcsRUFDWCxxQkFBcUIsRUFDckIsVUFBVSxFQUNYLE1BQU0saUNBQWlDLENBQUM7QUFTekMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRzNELE9BQU8sRUFBRSxLQUFLLE1BQU0sRUFBRSxLQUFLLGNBQWMsRUFBZ0IsTUFBTSx1QkFBdUIsQ0FBQztBQUV2RixPQUFPLEVBQUUsS0FBSyxZQUFZLEVBQVMsTUFBTSx5QkFBeUIsQ0FBQztBQUNuRSxPQUFPLEVBQUUsS0FBSyxpQkFBaUIsRUFBMEIsTUFBTSx5QkFBeUIsQ0FBQztBQUN6RixPQUFPLEtBQUssRUFBRSxHQUFHLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDdEMsT0FBTyxLQUFLLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM3RCxPQUFPLEVBR0wsT0FBTyxFQUNQLEtBQUssV0FBVyxFQUNoQixLQUFLLGFBQWEsRUFFbEIsS0FBSyxzQkFBc0IsRUFFNUIsTUFBTSxxQkFBcUIsQ0FBQztBQUM3QixPQUFPLEVBQ0wsS0FBSyxVQUFVLEVBQ2YsS0FBSyxzQkFBc0IsRUFJNUIsTUFBTSwwQkFBMEIsQ0FBQztBQUdsQyxPQUFPLEVBR0wsS0FBSyx1QkFBdUIsRUFDNUIsS0FBSyxzQkFBc0IsRUFDNUIsTUFBTSxpQ0FBaUMsQ0FBQztBQUN6QyxPQUFPLEVBQUUsS0FBSyxtQkFBbUIsRUFBbUMsTUFBTSx5QkFBeUIsQ0FBQztBQUNwRyxPQUFPLEtBQUssRUFNViw0QkFBNEIsRUFDN0IsTUFBTSxtQkFBbUIsQ0FBQztBQUczQixPQUFPLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ2pFLE9BQU8sRUFBaUIsRUFBRSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFckQsT0FBTyxFQUFjLEtBQUssU0FBUyxFQUFFLEtBQUssTUFBTSxFQUFhLE1BQU0seUJBQXlCLENBQUM7QUFDN0YsT0FBTyxFQUFFLGlCQUFpQixFQUFFLEtBQUssMEJBQTBCLEVBQUUsS0FBSyxlQUFlLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUduSCxPQUFPLEtBQUssRUFBRSxxQkFBcUIsRUFBRSxNQUFNLDhDQUE4QyxDQUFDO0FBQzFGLE9BQU8sS0FBSyxFQUFFLDJCQUEyQixFQUFFLGtCQUFrQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDM0csT0FBTyxLQUFLLEVBQUUsb0NBQW9DLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQztBQUdqRyxPQUFPLEtBQUssRUFBRSxlQUFlLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDbkQsT0FBTyxLQUFLLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDckQsT0FBTyxLQUFLLEVBQUUsZUFBZSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDN0QsT0FBTyxLQUFLLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDM0QsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLFlBQVksQ0FBQztBQW9CNUM7Ozs7O0dBS0c7QUFDSCxxQkFBYSxxQkFBc0IsWUFBVyxTQUFTO0lBb0JuRCxPQUFPLENBQUMsUUFBUSxDQUFDLFVBQVU7SUFDM0IsT0FBTyxDQUFDLFFBQVEsQ0FBQyxXQUFXO0lBQzVCLE9BQU8sQ0FBQyxRQUFRLENBQUMsZ0JBQWdCO0lBQ2pDLE9BQU8sQ0FBQyxRQUFRLENBQUMsbUJBQW1CO0lBQ3BDLE9BQU8sQ0FBQyxRQUFRLENBQUMsNEJBQTRCO0lBRTdDLE9BQU8sQ0FBQyxRQUFRLENBQUMsUUFBUTtJQUN6QixPQUFPLENBQUMsUUFBUSxDQUFDLFNBQVM7SUFDMUIsT0FBTyxDQUFDLFFBQVEsQ0FBQyxlQUFlO0lBQ2hDLE9BQU8sQ0FBQyxRQUFRLENBQUMsb0JBQW9CO0lBQ3JDLE9BQU8sQ0FBQyxRQUFRLENBQUMsZUFBZTtJQUNoQyxPQUFPLENBQUMsUUFBUSxDQUFDLGNBQWM7SUFDL0IsT0FBTyxDQUFDLFFBQVEsQ0FBQyxTQUFTO0lBQzFCLE9BQU8sQ0FBQyxRQUFRLENBQUMsVUFBVTtJQUMzQixPQUFPLENBQUMsUUFBUSxDQUFDLG1CQUFtQjtJQUNwQyxPQUFPLENBQUMsUUFBUSxDQUFDLGFBQWE7SUFDOUIsT0FBTyxDQUFDLFFBQVEsQ0FBQyxrQkFBa0I7SUFDbkMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxTQUFTO0lBQzFCLE9BQU8sQ0FBQyxRQUFRLENBQUMsV0FBVztJQUM1QixPQUFPLENBQUMsUUFBUSxDQUFDLGdCQUFnQjtJQUNqQyxTQUFTLENBQUMsTUFBTSxFQUFFLHVCQUF1QjtJQUN6QyxTQUFTLENBQUMsU0FBUyxFQUFFLGlCQUFpQjtJQUN0QyxPQUFPLENBQUMsUUFBUSxDQUFDLGFBQWE7SUFDOUIsT0FBTyxDQUFDLFFBQVEsQ0FBQyxVQUFVO0lBQzNCLE9BQU8sQ0FBQyxRQUFRLENBQUMsWUFBWTtJQUM3QixPQUFPLENBQUMsUUFBUSxDQUFDLE9BQU87SUFDeEIsT0FBTyxDQUFDLFFBQVEsQ0FBQyxpQkFBaUI7SUFDbEMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxZQUFZLEVBQUUsaUJBQWlCLENBQUMsZUFBZSxDQUFDO0lBR25FLFNBQVMsQ0FBQyxRQUFRLENBQUMsZUFBZSxFQUFFLGVBQWU7SUFDbkQsT0FBTyxDQUFDLFFBQVEsQ0FBQyxVQUFVO2FBQ1gsTUFBTSxFQUFFLE1BQU07SUFFOUIsT0FBTyxDQUFDLFFBQVEsQ0FBQyxzQkFBc0IsQ0FBQztJQXJEMUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDO0lBQy9CLE9BQU8sQ0FBQyxRQUFRLENBQUMsa0JBQWtCLENBQVM7SUFFNUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBNEI7SUFDL0QsT0FBTyxDQUFDLFdBQVcsQ0FBUztJQUU1Qjs7Ozs7T0FLRztJQUNILE9BQU8sQ0FBQyxpQ0FBaUMsQ0FBQyxDQUEwQjtJQUVwRSxPQUFPLENBQUMsbUJBQW1CO0lBSTNCLFlBQ21CLFVBQVUsRUFBRSxVQUFVLEVBQ3RCLFdBQVcsRUFBRSxXQUFXLEVBQ3hCLGdCQUFnQixFQUFFLGdCQUFnQixFQUNsQyxtQkFBbUIsRUFBRSxXQUFXLEVBQ2hDLDRCQUE0QixFQUFFLGdCQUFnQixFQUU5QyxRQUFRLEVBQUUsVUFBVSxHQUFHLFNBQVMsRUFDaEMsU0FBUyxFQUFFLGtCQUFrQixFQUM3QixlQUFlLEVBQUUsVUFBVSxFQUMzQixvQkFBb0IsRUFBRSwyQkFBMkIsR0FBRyxTQUFTLEVBQzdELGVBQWUsRUFBRSxlQUFlLEVBQ2hDLGNBQWMsRUFBRSxxQkFBcUIsRUFDckMsU0FBUyxFQUFFLEdBQUcsRUFDZCxVQUFVLEVBQUUsc0JBQXNCLEVBQ2xDLG1CQUFtQixFQUFFLG1CQUFtQixFQUN4QyxhQUFhLEVBQUUsYUFBYSxFQUM1QixrQkFBa0IsRUFBRSwwQkFBMEIsRUFDOUMsU0FBUyxFQUFFLFdBQVcsR0FBRyxzQkFBc0IsRUFDL0MsV0FBVyxFQUFFLHdCQUF3QixFQUNyQyxnQkFBZ0IsRUFBRSw0QkFBNEIsRUFDckQsTUFBTSxFQUFFLHVCQUF1QixFQUMvQixTQUFTLEVBQUUsaUJBQWlCLEVBQ3JCLGFBQWEsRUFBRSxzQkFBc0IsR0FBRyxTQUFTLEVBQ2pELFVBQVUsRUFBRSxVQUFVLEVBQ3RCLFlBQVksRUFBRSxZQUFZLEVBQzFCLE9BQU8sRUFBRSxnQkFBZ0IsRUFDekIsaUJBQWlCLEVBQUUsb0NBQW9DLEVBQ3JELFlBQVksRUFBRSxpQkFBaUIsQ0FBQyxlQUFlLENBQUMsRUFHaEQsZUFBZSxFQUFFLGVBQWUsRUFDbEMsVUFBVSxFQUFFLENBQUMsS0FBSyxFQUFFLGNBQWMsRUFBRSxJQUFJLEVBQUUsVUFBVSxLQUFLLElBQUksRUFDOUQsTUFBTSxFQUFFLE1BQU0sRUFDOUIsUUFBUSxDQUFDLEVBQUUsY0FBYyxFQUNSLHNCQUFzQixDQUFDLG9DQUF3QixFQVVqRTtJQUVEOzs7T0FHRztJQUNILE9BQU8sQ0FBQyxZQUFZO0lBSXBCOzs7O09BSUc7SUFDSCxPQUFPLENBQUMsUUFBUTtJQUloQix3R0FBd0c7SUFDakcsU0FBUyxJQUFJLElBQUksQ0FJdkI7WUFFYSx1QkFBdUI7SUFpQnJDLE9BQU8sQ0FBQyxrQkFBa0I7SUFPMUI7Ozs7OztPQU1HO0lBRVUsT0FBTyxJQUFJLE9BQU8sQ0FBQyxVQUFVLEdBQUcsU0FBUyxDQUFDLENBa0R0RDtZQU1hLDRDQUE0QztZQXNGNUMsOEJBQThCO1lBc0M5Qix5QkFBeUI7SUErQnZDOzs7Ozs7T0FNRztJQUNILFVBQWdCLGdDQUFnQyxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0EwRW5FO0lBRUQsNkVBQTZFO0lBQzdFLE9BQU8sQ0FBQyxnQ0FBZ0M7WUFVMUIsbUJBQW1CO1lBd0JuQixpQkFBaUI7WUFnVGpCLHdCQUF3QjtJQWlJdEMscUdBQXFHO0lBQ3JHLE9BQU8sQ0FBQyxtQkFBbUI7SUFzQjNCOzs7T0FHRztJQUNILFVBQ2dCLG9CQUFvQixDQUFDLGdCQUFnQixFQUFFLE1BQU0saUJBTTVEO0lBRUQsdUVBQXVFO0lBQ3ZFLFVBQ2dCLGdCQUFnQixDQUM5QixpQkFBaUIsRUFBRSxpQkFBaUIsRUFDcEMsSUFBSSxFQUFFO1FBQ0osV0FBVyxDQUFDLEVBQUUsT0FBTyxDQUFDO1FBQ3RCLGNBQWMsRUFBRSxNQUFNLENBQUM7UUFDdkIsV0FBVyxFQUFFLFdBQVcsQ0FBQztRQUN6QixxQkFBcUIsRUFBRSxxQkFBcUIsQ0FBQztRQUM3QyxhQUFhLEVBQUUsSUFBSSxHQUFHLFNBQVMsQ0FBQztRQUNoQyx1QkFBdUIsRUFBRSxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7S0FDdEMsR0FDQSxPQUFPLENBQ1I7UUFBRSxLQUFLLEVBQUUsT0FBTyxDQUFDO1FBQUMsT0FBTyxFQUFFLEVBQUUsRUFBRSxDQUFBO0tBQUUsR0FBRztRQUFFLE9BQU8sRUFBRSxrQkFBa0IsR0FBRyx3QkFBd0IsQ0FBQTtLQUFFLEdBQUc7UUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFBO0tBQUUsQ0FDbEgsQ0F3S0E7WUFHYSxxQ0FBcUM7WUEwQnJDLGFBQWE7WUFxQ2IsOEJBQThCO1lBbUM5QixtQkFBbUI7SUE0R2pDLE9BQU8sQ0FBQyx5QkFBeUI7SUF5QmpDLHdFQUF3RTtJQUN4RSxPQUFPLENBQUMsc0JBQXNCO1lBdUVoQixvQkFBb0I7WUFtQnBCLDJCQUEyQjtZQXlCM0IsZ0NBQWdDO1lBMEJoQyw4QkFBOEI7SUF3QjVDOztPQUVHO0lBQ0gsT0FBTyxDQUFDLG9CQUFvQjtJQW1CNUIsa0ZBQWtGO0lBQ2xGLFVBQWdCLHlCQUF5QixJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FFekQ7SUFFTSxZQUFZLHVCQUVsQjtDQUNGIn0=
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"checkpoint_proposal_job.d.ts","sourceRoot":"","sources":["../../src/sequencer/checkpoint_proposal_job.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAmC,MAAM,oBAAoB,CAAC;AAEtF,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,WAAW,EACX,qBAAqB,EACrB,UAAU,EACX,MAAM,iCAAiC,CAAC;AASzC,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAG3D,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,cAAc,EAAgB,MAAM,uBAAuB,CAAC;AAEvF,OAAO,EAAE,KAAK,YAAY,EAAS,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,KAAK,iBAAiB,EAA0B,MAAM,yBAAyB,CAAC;AACzF,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAGL,OAAO,EACP,KAAK,WAAW,EAChB,KAAK,aAAa,EAElB,KAAK,sBAAsB,EAE5B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,KAAK,UAAU,EACf,KAAK,sBAAsB,EAI5B,MAAM,0BAA0B,CAAC;AAGlC,OAAO,EAGL,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC5B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,KAAK,mBAAmB,EAAmC,MAAM,yBAAyB,CAAC;AACpG,OAAO,KAAK,EAMV,4BAA4B,EAC7B,MAAM,mBAAmB,CAAC;AAG3B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACjE,OAAO,EAAiB,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAErD,OAAO,EAAc,KAAK,SAAS,EAAE,KAAK,MAAM,EAAa,MAAM,yBAAyB,CAAC;AAC7F,OAAO,EAAE,iBAAiB,EAAE,KAAK,0BAA0B,EAAE,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAGnH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,8CAA8C,CAAC;AAC1F,OAAO,KAAK,EAAE,2BAA2B,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC3G,OAAO,KAAK,EAAE,oCAAoC,EAAE,MAAM,sCAAsC,CAAC;AAGjG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAoB5C;;;;;GAKG;AACH,qBAAa,qBAAsB,YAAW,SAAS;
|
|
1
|
+
{"version":3,"file":"checkpoint_proposal_job.d.ts","sourceRoot":"","sources":["../../src/sequencer/checkpoint_proposal_job.ts"],"names":[],"mappings":"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"}
|
|
@@ -501,6 +501,7 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
501
501
|
metrics;
|
|
502
502
|
checkpointMetrics;
|
|
503
503
|
eventEmitter;
|
|
504
|
+
pendingRequests;
|
|
504
505
|
setStateFn;
|
|
505
506
|
tracer;
|
|
506
507
|
proposedCheckpointData;
|
|
@@ -545,7 +546,6 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
545
546
|
}
|
|
546
547
|
log;
|
|
547
548
|
checkpointEventLog;
|
|
548
|
-
/** Tracks the fire-and-forget L1 submission promise so it can be awaited during shutdown. */ pendingL1Submission;
|
|
549
549
|
interruptibleSleep;
|
|
550
550
|
interrupted;
|
|
551
551
|
/**
|
|
@@ -558,7 +558,9 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
558
558
|
return this.signatureContext;
|
|
559
559
|
}
|
|
560
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,
|
|
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){
|
|
562
564
|
this.targetSlot = targetSlot;
|
|
563
565
|
this.targetEpoch = targetEpoch;
|
|
564
566
|
this.checkpointNumber = checkpointNumber;
|
|
@@ -586,6 +588,7 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
586
588
|
this.metrics = metrics;
|
|
587
589
|
this.checkpointMetrics = checkpointMetrics;
|
|
588
590
|
this.eventEmitter = eventEmitter;
|
|
591
|
+
this.pendingRequests = pendingRequests;
|
|
589
592
|
this.setStateFn = setStateFn;
|
|
590
593
|
this.tracer = tracer;
|
|
591
594
|
this.proposedCheckpointData = proposedCheckpointData;
|
|
@@ -613,10 +616,6 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
613
616
|
*/ setState(state) {
|
|
614
617
|
this.setStateFn(state, this.targetSlot);
|
|
615
618
|
}
|
|
616
|
-
/** Awaits the pending L1 submission if one is in progress. Call during shutdown. */ async awaitPendingSubmission() {
|
|
617
|
-
this.log.info('Awaiting pending L1 payload submission');
|
|
618
|
-
await this.pendingL1Submission;
|
|
619
|
-
}
|
|
620
619
|
/** Interrupts job-owned waits, including the publisher's send-at-slot sleep, so shutdown can finish. */ interrupt() {
|
|
621
620
|
this.interrupted = true;
|
|
622
621
|
this.interruptibleSleep.interrupt(true);
|
|
@@ -667,7 +666,7 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
667
666
|
// signature verification to fail silently inside Multicall3. Delay submission to the
|
|
668
667
|
// start of `targetSlot` so the tx mines in the slot the vote was signed for.
|
|
669
668
|
if (!this.config.fishermanMode) {
|
|
670
|
-
this.
|
|
669
|
+
this.pendingRequests.trackRequest(this.publisher.sendRequestsAt(this.targetSlot), ()=>this.interrupt());
|
|
671
670
|
}
|
|
672
671
|
return undefined;
|
|
673
672
|
}
|
|
@@ -679,13 +678,13 @@ _dec = trackSpan('CheckpointProposalJob.execute'), _dec1 = trackSpan('Checkpoint
|
|
|
679
678
|
return checkpoint;
|
|
680
679
|
}
|
|
681
680
|
// Background the attestation → signing → L1 pipeline so the work loop is unblocked
|
|
682
|
-
this.
|
|
681
|
+
this.pendingRequests.trackRequest(this.waitForAttestationsAndEnqueueSubmissionAsync(broadcast, votesPromises), ()=>this.interrupt());
|
|
683
682
|
// Return the built checkpoint immediately — the work loop is now unblocked
|
|
684
683
|
return checkpoint;
|
|
685
684
|
}
|
|
686
685
|
/**
|
|
687
686
|
* Background pipeline: collects attestations, signs them, enqueues the checkpoint, and submits to L1.
|
|
688
|
-
* 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.
|
|
689
688
|
*/ async waitForAttestationsAndEnqueueSubmissionAsync(broadcast, votesPromises) {
|
|
690
689
|
const { checkpoint } = broadcast;
|
|
691
690
|
try {
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tracks fire-and-forget requests so a shutdown path can interrupt any in-flight work and await it to
|
|
3
|
+
* settle. Each tracked request is a promise plus an optional interrupt callback; the entry removes itself
|
|
4
|
+
* from the bag once its promise settles, so the tracker only ever holds requests that are still in flight.
|
|
5
|
+
*/
|
|
6
|
+
export declare class RequestsTracker {
|
|
7
|
+
private readonly requests;
|
|
8
|
+
private nextId;
|
|
9
|
+
/** Number of in-flight requests currently tracked. */
|
|
10
|
+
get size(): number;
|
|
11
|
+
/**
|
|
12
|
+
* Tracks a fire-and-forget request. `interrupt`, when provided, is invoked by {@link interruptRequests}
|
|
13
|
+
* to cancel the in-flight work so its promise settles promptly. The entry auto-removes once `promise`
|
|
14
|
+
* settles, whether it resolves or rejects.
|
|
15
|
+
*/
|
|
16
|
+
trackRequest(promise: Promise<unknown>, interrupt?: () => void): void;
|
|
17
|
+
/** Interrupts every in-flight request that was tracked with an interrupt callback. */
|
|
18
|
+
interruptRequests(): void;
|
|
19
|
+
/** Awaits every currently in-flight request to settle. */
|
|
20
|
+
awaitRequests(): Promise<void>;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVxdWVzdHNfdHJhY2tlci5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlcXVlbmNlci9yZXF1ZXN0c190cmFja2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUdBOzs7O0dBSUc7QUFDSCxxQkFBYSxlQUFlO0lBQzFCLE9BQU8sQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFxQztJQUM5RCxPQUFPLENBQUMsTUFBTSxDQUFLO0lBRW5CLHNEQUFzRDtJQUN0RCxJQUFXLElBQUksSUFBSSxNQUFNLENBRXhCO0lBRUQ7Ozs7T0FJRztJQUNJLFlBQVksQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFLFNBQVMsQ0FBQyxFQUFFLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FPM0U7SUFFRCxzRkFBc0Y7SUFDL0UsaUJBQWlCLElBQUksSUFBSSxDQUkvQjtJQUVELDBEQUEwRDtJQUM3QyxhQUFhLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUUxQztDQUNGIn0=
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requests_tracker.d.ts","sourceRoot":"","sources":["../../src/sequencer/requests_tracker.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqC;IAC9D,OAAO,CAAC,MAAM,CAAK;IAEnB,sDAAsD;IACtD,IAAW,IAAI,IAAI,MAAM,CAExB;IAED;;;;OAIG;IACI,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,SAAS,CAAC,EAAE,MAAM,IAAI,GAAG,IAAI,CAO3E;IAED,sFAAsF;IAC/E,iBAAiB,IAAI,IAAI,CAI/B;IAED,0DAA0D;IAC7C,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAE1C;CACF"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/** A tracked request: the awaitable to wait on, plus an optional interrupt to cancel it early. */ /**
|
|
2
|
+
* Tracks fire-and-forget requests so a shutdown path can interrupt any in-flight work and await it to
|
|
3
|
+
* settle. Each tracked request is a promise plus an optional interrupt callback; the entry removes itself
|
|
4
|
+
* from the bag once its promise settles, so the tracker only ever holds requests that are still in flight.
|
|
5
|
+
*/ export class RequestsTracker {
|
|
6
|
+
requests = new Map();
|
|
7
|
+
nextId = 0;
|
|
8
|
+
/** Number of in-flight requests currently tracked. */ get size() {
|
|
9
|
+
return this.requests.size;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Tracks a fire-and-forget request. `interrupt`, when provided, is invoked by {@link interruptRequests}
|
|
13
|
+
* to cancel the in-flight work so its promise settles promptly. The entry auto-removes once `promise`
|
|
14
|
+
* settles, whether it resolves or rejects.
|
|
15
|
+
*/ trackRequest(promise, interrupt) {
|
|
16
|
+
const id = this.nextId++;
|
|
17
|
+
const settled = promise.then(()=>this.requests.delete(id), ()=>this.requests.delete(id));
|
|
18
|
+
this.requests.set(id, {
|
|
19
|
+
promise: settled,
|
|
20
|
+
interrupt
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
/** Interrupts every in-flight request that was tracked with an interrupt callback. */ interruptRequests() {
|
|
24
|
+
for (const { interrupt } of this.requests.values()){
|
|
25
|
+
interrupt?.();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/** Awaits every currently in-flight request to settle. */ async awaitRequests() {
|
|
29
|
+
await Promise.all([
|
|
30
|
+
...this.requests.values()
|
|
31
|
+
].map((request)=>request.promise));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -4,6 +4,7 @@ import { BlockNumber, CheckpointNumber, EpochNumber, SlotNumber } from '@aztec/f
|
|
|
4
4
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
5
5
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
6
6
|
import { type Logger } from '@aztec/foundation/log';
|
|
7
|
+
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
7
8
|
import type { DateProvider } from '@aztec/foundation/timer';
|
|
8
9
|
import type { TypedEventEmitter } from '@aztec/foundation/types';
|
|
9
10
|
import type { P2P } from '@aztec/p2p';
|
|
@@ -21,6 +22,7 @@ import type { SequencerPublisherFactory } from '../publisher/sequencer-publisher
|
|
|
21
22
|
import type { InvalidateCheckpointRequest, SequencerPublisher } from '../publisher/sequencer-publisher.js';
|
|
22
23
|
import { CheckpointProposalJob } from './checkpoint_proposal_job.js';
|
|
23
24
|
import type { SequencerEvents } from './events.js';
|
|
25
|
+
import { RequestsTracker } from './requests_tracker.js';
|
|
24
26
|
import type { SequencerRollupConstants } from './types.js';
|
|
25
27
|
import { SequencerState } from './utils.js';
|
|
26
28
|
export { SequencerState };
|
|
@@ -58,7 +60,7 @@ export declare class Sequencer extends Sequencer_base {
|
|
|
58
60
|
protected rollupContract: RollupContract;
|
|
59
61
|
protected telemetry: TelemetryClient;
|
|
60
62
|
protected log: Logger;
|
|
61
|
-
|
|
63
|
+
protected runningPromise?: RunningPromise;
|
|
62
64
|
private state;
|
|
63
65
|
private stateSlotNumber;
|
|
64
66
|
/** Wall-clock time (ms, via the date provider) at which the current state was entered. */
|
|
@@ -81,6 +83,16 @@ export declare class Sequencer extends Sequencer_base {
|
|
|
81
83
|
private lastEpochForStrategyComparison;
|
|
82
84
|
/** The last checkpoint proposal job, tracked so we can await its pending L1 submission during shutdown. */
|
|
83
85
|
protected lastCheckpointProposalJob: CheckpointProposalJob | undefined;
|
|
86
|
+
/**
|
|
87
|
+
* In-flight fire-and-forget requests that {@link stop} interrupts and drains, and {@link pause} awaits
|
|
88
|
+
* untouched: the checkpoint proposal jobs' backgrounded L1 submissions (each job is handed this shared
|
|
89
|
+
* tracker) plus the sequencer's own fallback submissions (votes/prune when we cannot build, or
|
|
90
|
+
* escape-hatch votes). Each fallback send is gated by its wrapper publisher's interruptible target-slot
|
|
91
|
+
* sleep; the tracked interrupt wakes that sleep so the send short-circuits without publishing. A wrapper
|
|
92
|
+
* is created for a single send and is never restarted, so once interrupted its sleeper can never publish
|
|
93
|
+
* a stale-slot tx, even after the pooled publishers are restarted by a later {@link start}.
|
|
94
|
+
*/
|
|
95
|
+
protected readonly pendingRequests: RequestsTracker;
|
|
84
96
|
/** Proposer schedule and block sub-slot timetable for the sequencer, rebuilt on every config update. */
|
|
85
97
|
protected timetable: ProposerTimetable;
|
|
86
98
|
/** Config for the sequencer */
|
|
@@ -126,12 +138,34 @@ export declare class Sequencer extends Sequencer_base {
|
|
|
126
138
|
private assertConfigMeetsNetworkTxLimits;
|
|
127
139
|
/** Initializes the sequencer (precomputes tables). Takes about 3s. */
|
|
128
140
|
init(): void;
|
|
129
|
-
/**
|
|
141
|
+
/**
|
|
142
|
+
* Starts (or restarts) the sequencer and moves it to the IDLE state. Idempotent: a start while already
|
|
143
|
+
* running is a no-op, so it never orphans the previous poll loop. A start while STOPPING throws, since the
|
|
144
|
+
* in-flight stop would mark the fresh loop's state STOPPED and orphan it — silently doing nothing would
|
|
145
|
+
* leave the caller believing the sequencer is running when it is on its way to STOPPED. Safe to call after
|
|
146
|
+
* a previous {@link stop} has resolved; the caller must also restart the publishers (see
|
|
147
|
+
* {@link SequencerClient.start}) so L1 publishing is re-enabled.
|
|
148
|
+
*/
|
|
130
149
|
start(): void;
|
|
131
150
|
/** Triggers an immediate run of the sequencer, bypassing the polling interval. */
|
|
132
151
|
trigger(): Promise<void> | undefined;
|
|
133
|
-
/**
|
|
152
|
+
/**
|
|
153
|
+
* Stops the sequencer from building blocks and moves it to STOPPED state, interrupting the in-flight
|
|
154
|
+
* work() iteration and its pending L1 submissions for a fast shutdown, then draining before returning.
|
|
155
|
+
* Idempotent: a second call while already stopped or stopping is a no-op. Lifecycle calls are expected
|
|
156
|
+
* to be serialized by the caller. For a restartable pause that lets in-flight work finish untouched
|
|
157
|
+
* (e.g. around a test clock warp), use {@link pause} instead.
|
|
158
|
+
*/
|
|
134
159
|
stop(): Promise<void>;
|
|
160
|
+
/**
|
|
161
|
+
* Gracefully pauses block production so the sequencer can later be resumed with {@link start}: halts the
|
|
162
|
+
* poll loop and waits for the in-flight work() iteration and every pending L1 submission / fallback send
|
|
163
|
+
* to finish, without interrupting them. No interrupt lands mid-build, so no spurious checkpoint-error is
|
|
164
|
+
* emitted and no enqueued checkpoint is dropped. Deliberately does not stop inner services (validator/HA
|
|
165
|
+
* signer, publishers), so the slashing-protection store stays open and the sequencer stays restartable.
|
|
166
|
+
* Used by tests that pause sequencers around an L1 clock warp. Idempotent.
|
|
167
|
+
*/
|
|
168
|
+
pause(): Promise<void>;
|
|
135
169
|
/** Main sequencer loop with a try/catch */
|
|
136
170
|
protected safeWork(): Promise<void>;
|
|
137
171
|
/** Returns the current state of the sequencer. */
|
|
@@ -286,4 +320,4 @@ type SequencerSyncCheckResult = {
|
|
|
286
320
|
syncedL2Slot: SlotNumber;
|
|
287
321
|
pendingChainValidationStatus: ValidateCheckpointResult;
|
|
288
322
|
};
|
|
289
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
323
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VxdWVuY2VyLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VxdWVuY2VyL3NlcXVlbmNlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsS0FBSyxVQUFVLEVBQW1DLE1BQU0sb0JBQW9CLENBQUM7QUFDdEYsT0FBTyxFQUFvQixLQUFLLGNBQWMsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ2xGLE9BQU8sRUFBRSxXQUFXLEVBQUUsZ0JBQWdCLEVBQUUsV0FBVyxFQUFFLFVBQVUsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBRXpHLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNwRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDM0QsT0FBTyxFQUFFLEtBQUssTUFBTSxFQUFnQixNQUFNLHVCQUF1QixDQUFDO0FBQ2xFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUNuRSxPQUFPLEtBQUssRUFBRSxZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM1RCxPQUFPLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ2pFLE9BQU8sS0FBSyxFQUFFLEdBQUcsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUN0QyxPQUFPLEtBQUssRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdELE9BQU8sS0FBSyxFQUNWLFNBQVMsRUFDVCxXQUFXLEVBQ1gsYUFBYSxFQUNiLHNCQUFzQixFQUN0Qix3QkFBd0IsRUFDekIsTUFBTSxxQkFBcUIsQ0FBQztBQUM3QixPQUFPLEVBQ0wsS0FBSyxVQUFVLEVBQ2YsS0FBSyxzQkFBc0IsRUFFNUIsTUFBTSwwQkFBMEIsQ0FBQztBQUNsQyxPQUFPLEtBQUssRUFBRSxXQUFXLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQU94RCxPQUFPLEVBQ0wsS0FBSyx1QkFB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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sequencer.d.ts","sourceRoot":"","sources":["../../src/sequencer/sequencer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,UAAU,EAAmC,MAAM,oBAAoB,CAAC;AACtF,OAAO,EAAoB,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAClF,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAEzG,OAAO,EAAE,EAAE,EAAE,MAAM,gCAAgC,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"sequencer.d.ts","sourceRoot":"","sources":["../../src/sequencer/sequencer.ts"],"names":[],"mappings":"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"}
|
|
@@ -393,6 +393,7 @@ import { CheckpointProposalJobMetrics } from './checkpoint_proposal_job_metrics.
|
|
|
393
393
|
import { CheckpointVoter } from './checkpoint_voter.js';
|
|
394
394
|
import { SequencerInterruptedError } from './errors.js';
|
|
395
395
|
import { SequencerMetrics } from './metrics.js';
|
|
396
|
+
import { RequestsTracker } from './requests_tracker.js';
|
|
396
397
|
import { SequencerState } from './utils.js';
|
|
397
398
|
export { SequencerState };
|
|
398
399
|
_dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpointProposal'), _dec2 = trackSpan('Sequencer.tryVoteAndPruneWhenCannotBuild', ({ slot })=>({
|
|
@@ -462,11 +463,20 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
462
463
|
/** Last successful checkpoint proposed */ lastCheckpointProposed;
|
|
463
464
|
/** The last epoch for which we logged strategy comparison in fisherman mode. */ lastEpochForStrategyComparison;
|
|
464
465
|
/** The last checkpoint proposal job, tracked so we can await its pending L1 submission during shutdown. */ lastCheckpointProposalJob;
|
|
466
|
+
/**
|
|
467
|
+
* In-flight fire-and-forget requests that {@link stop} interrupts and drains, and {@link pause} awaits
|
|
468
|
+
* untouched: the checkpoint proposal jobs' backgrounded L1 submissions (each job is handed this shared
|
|
469
|
+
* tracker) plus the sequencer's own fallback submissions (votes/prune when we cannot build, or
|
|
470
|
+
* escape-hatch votes). Each fallback send is gated by its wrapper publisher's interruptible target-slot
|
|
471
|
+
* sleep; the tracked interrupt wakes that sleep so the send short-circuits without publishing. A wrapper
|
|
472
|
+
* is created for a single send and is never restarted, so once interrupted its sleeper can never publish
|
|
473
|
+
* a stale-slot tx, even after the pooled publishers are restarted by a later {@link start}.
|
|
474
|
+
*/ pendingRequests;
|
|
465
475
|
/** Proposer schedule and block sub-slot timetable for the sequencer, rebuilt on every config update. */ timetable;
|
|
466
476
|
/** Config for the sequencer */ config;
|
|
467
477
|
signatureContext;
|
|
468
478
|
constructor(publisherFactory, validatorClient, globalsBuilder, p2pClient, worldState, slasherClient, l2BlockSource, l1ToL2MessageSource, checkpointsBuilder, l1Constants, dateProvider, epochCache, rollupContract, config, telemetry = getTelemetryClient(), log = createLogger('sequencer')){
|
|
469
|
-
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;
|
|
479
|
+
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.pendingRequests = new RequestsTracker(), this.config = DefaultSequencerConfig;
|
|
470
480
|
this.stateLog = log.createChild('state');
|
|
471
481
|
this.stateEnteredAtMs = this.dateProvider.now();
|
|
472
482
|
// Add [FISHERMAN] prefix to logger if in fisherman mode
|
|
@@ -580,7 +590,21 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
580
590
|
/** Initializes the sequencer (precomputes tables). Takes about 3s. */ init() {
|
|
581
591
|
getKzg();
|
|
582
592
|
}
|
|
583
|
-
/**
|
|
593
|
+
/**
|
|
594
|
+
* Starts (or restarts) the sequencer and moves it to the IDLE state. Idempotent: a start while already
|
|
595
|
+
* running is a no-op, so it never orphans the previous poll loop. A start while STOPPING throws, since the
|
|
596
|
+
* in-flight stop would mark the fresh loop's state STOPPED and orphan it — silently doing nothing would
|
|
597
|
+
* leave the caller believing the sequencer is running when it is on its way to STOPPED. Safe to call after
|
|
598
|
+
* a previous {@link stop} has resolved; the caller must also restart the publishers (see
|
|
599
|
+
* {@link SequencerClient.start}) so L1 publishing is re-enabled.
|
|
600
|
+
*/ start() {
|
|
601
|
+
if (this.state === SequencerState.STOPPING) {
|
|
602
|
+
throw new Error('Cannot start sequencer while it is stopping');
|
|
603
|
+
}
|
|
604
|
+
if (this.runningPromise?.isRunning()) {
|
|
605
|
+
this.log.warn('Attempted to start sequencer that is already running');
|
|
606
|
+
return;
|
|
607
|
+
}
|
|
584
608
|
this.runningPromise = new RunningPromise(this.safeWork.bind(this), this.log, this.config.sequencerPollingIntervalMS);
|
|
585
609
|
this.setState(SequencerState.IDLE, undefined, {
|
|
586
610
|
force: true
|
|
@@ -591,20 +615,56 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
591
615
|
/** Triggers an immediate run of the sequencer, bypassing the polling interval. */ trigger() {
|
|
592
616
|
return this.runningPromise?.trigger();
|
|
593
617
|
}
|
|
594
|
-
/**
|
|
618
|
+
/**
|
|
619
|
+
* Stops the sequencer from building blocks and moves it to STOPPED state, interrupting the in-flight
|
|
620
|
+
* work() iteration and its pending L1 submissions for a fast shutdown, then draining before returning.
|
|
621
|
+
* Idempotent: a second call while already stopped or stopping is a no-op. Lifecycle calls are expected
|
|
622
|
+
* to be serialized by the caller. For a restartable pause that lets in-flight work finish untouched
|
|
623
|
+
* (e.g. around a test clock warp), use {@link pause} instead.
|
|
624
|
+
*/ async stop() {
|
|
625
|
+
if (this.state === SequencerState.STOPPED || this.state === SequencerState.STOPPING) {
|
|
626
|
+
this.log.debug(`Sequencer already ${this.state.toLowerCase()}, ignoring stop`);
|
|
627
|
+
return;
|
|
628
|
+
}
|
|
595
629
|
this.log.info(`Stopping sequencer`);
|
|
596
630
|
this.setState(SequencerState.STOPPING, undefined, {
|
|
597
631
|
force: true
|
|
598
632
|
});
|
|
599
633
|
this.lastCheckpointProposalJob?.interrupt();
|
|
600
634
|
await this.publisherFactory.stopAll();
|
|
635
|
+
// Stop the poll loop and await the in-flight work() iteration. work() registers its fire-and-forget
|
|
636
|
+
// requests synchronously before returning, so once the loop has stopped, pendingRequests holds every
|
|
637
|
+
// request that will ever exist. Interrupting any earlier could miss a request registered by the last
|
|
638
|
+
// in-flight iteration.
|
|
601
639
|
await this.runningPromise?.stop();
|
|
602
|
-
|
|
640
|
+
this.pendingRequests.interruptRequests();
|
|
641
|
+
await this.pendingRequests.awaitRequests();
|
|
603
642
|
this.setState(SequencerState.STOPPED, undefined, {
|
|
604
643
|
force: true
|
|
605
644
|
});
|
|
606
645
|
this.log.info('Stopped sequencer');
|
|
607
646
|
}
|
|
647
|
+
/**
|
|
648
|
+
* Gracefully pauses block production so the sequencer can later be resumed with {@link start}: halts the
|
|
649
|
+
* poll loop and waits for the in-flight work() iteration and every pending L1 submission / fallback send
|
|
650
|
+
* to finish, without interrupting them. No interrupt lands mid-build, so no spurious checkpoint-error is
|
|
651
|
+
* emitted and no enqueued checkpoint is dropped. Deliberately does not stop inner services (validator/HA
|
|
652
|
+
* signer, publishers), so the slashing-protection store stays open and the sequencer stays restartable.
|
|
653
|
+
* Used by tests that pause sequencers around an L1 clock warp. Idempotent.
|
|
654
|
+
*/ async pause() {
|
|
655
|
+
if (!this.runningPromise?.isRunning()) {
|
|
656
|
+
this.log.debug('Sequencer not running, ignoring pause');
|
|
657
|
+
return;
|
|
658
|
+
}
|
|
659
|
+
this.log.info('Pausing sequencer');
|
|
660
|
+
// Halt the poll loop and let the in-flight iteration finish naturally — no interrupt, and no STOPPING
|
|
661
|
+
// state, since entering STOPPING would make the iteration's own setState calls throw and fail it.
|
|
662
|
+
// work() registers its fire-and-forget requests synchronously before returning, so once the loop has
|
|
663
|
+
// stopped pendingRequests holds every request that will ever exist; awaiting it lets them all finish.
|
|
664
|
+
await this.runningPromise.stop();
|
|
665
|
+
await this.pendingRequests.awaitRequests();
|
|
666
|
+
this.log.info('Paused sequencer');
|
|
667
|
+
}
|
|
608
668
|
/** Main sequencer loop with a try/catch */ async safeWork() {
|
|
609
669
|
try {
|
|
610
670
|
await this.work();
|
|
@@ -731,18 +791,6 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
731
791
|
}
|
|
732
792
|
return undefined;
|
|
733
793
|
}
|
|
734
|
-
// We are the proposer and the escape hatch is closed: now run the full sync check before building.
|
|
735
|
-
const syncedTo = await this.checkSync({
|
|
736
|
-
ts,
|
|
737
|
-
slot
|
|
738
|
-
});
|
|
739
|
-
if (!syncedTo) {
|
|
740
|
-
await this.tryVoteAndPruneWhenCannotBuild({
|
|
741
|
-
slot,
|
|
742
|
-
targetSlot
|
|
743
|
-
});
|
|
744
|
-
return undefined;
|
|
745
|
-
}
|
|
746
794
|
// Explicit build-loop entry gate: if we are past the latest useful block-building start for the
|
|
747
795
|
// target slot, abandon building for this slot. The proposer prioritizes the ideal L1-publish path
|
|
748
796
|
// and does not plan around the late consensus-handoff path. This is the proposer build path's
|
|
@@ -766,6 +814,15 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
766
814
|
this.lastSlotForCheckpointProposalJob = targetSlot;
|
|
767
815
|
return undefined;
|
|
768
816
|
}
|
|
817
|
+
// We are the proposer, the escape hatch is closed, and we have time before the build start deadline.
|
|
818
|
+
// Now run the full sync check before building.
|
|
819
|
+
const syncedTo = await this.checkSync({
|
|
820
|
+
ts,
|
|
821
|
+
slot
|
|
822
|
+
});
|
|
823
|
+
if (!syncedTo) {
|
|
824
|
+
return undefined;
|
|
825
|
+
}
|
|
769
826
|
// Next checkpoint follows from the last synced one
|
|
770
827
|
const checkpointNumber = CheckpointNumber(syncedTo.checkpointNumber + 1);
|
|
771
828
|
const logCtx = {
|
|
@@ -926,7 +983,7 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
926
983
|
return this.createCheckpointProposalJob(targetSlot, targetEpoch, checkpointNumber, syncedTo.blockNumber, syncedTo.checkpointedCheckpointNumber, proposer, publisher, attestorAddress, invalidateCheckpoint, syncedTo.proposedCheckpointData);
|
|
927
984
|
}
|
|
928
985
|
createCheckpointProposalJob(targetSlot, targetEpoch, checkpointNumber, syncedToBlockNumber, checkpointedCheckpointNumber, proposer, publisher, attestorAddress, invalidateCheckpoint, proposedCheckpointData) {
|
|
929
|
-
return new CheckpointProposalJob(targetSlot, targetEpoch, checkpointNumber, syncedToBlockNumber, checkpointedCheckpointNumber, 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);
|
|
986
|
+
return new CheckpointProposalJob(targetSlot, targetEpoch, checkpointNumber, syncedToBlockNumber, checkpointedCheckpointNumber, 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.pendingRequests, this.setState.bind(this), this.tracer, this.log.getBindings(), proposedCheckpointData);
|
|
930
987
|
}
|
|
931
988
|
/**
|
|
932
989
|
* Returns the current sequencer state.
|
|
@@ -1207,12 +1264,13 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
1207
1264
|
// Votes are EIP-712-signed for `targetSlot` (the pipelined slot in which the multicall is
|
|
1208
1265
|
// expected to mine). Delay submission to the start of `targetSlot` so the tx mines in the
|
|
1209
1266
|
// slot the votes were signed for. We fire-and-forget so we don't block the sequencer's
|
|
1210
|
-
// work loop while waiting for the target slot to start.
|
|
1211
|
-
|
|
1267
|
+
// work loop while waiting for the target slot to start, but track it so stop() can drain it.
|
|
1268
|
+
const send = publisher.sendRequestsAt(targetSlot).catch((err)=>{
|
|
1212
1269
|
this.log.error(`Failed to publish fallback requests despite sync failure for slot ${slot}`, err, {
|
|
1213
1270
|
slot
|
|
1214
1271
|
});
|
|
1215
1272
|
});
|
|
1273
|
+
this.pendingRequests.trackRequest(send, ()=>publisher.interrupt());
|
|
1216
1274
|
}
|
|
1217
1275
|
async tryEnqueuePruneIfPrunable(targetSlot, publisher) {
|
|
1218
1276
|
try {
|
|
@@ -1261,13 +1319,15 @@ _dec = trackSpan('Sequencer.work'), _dec1 = trackSpan('Sequencer.prepareCheckpoi
|
|
|
1261
1319
|
// the multicall mines in the slot the votes were signed for; otherwise the L1 contract reads
|
|
1262
1320
|
// `signaler = getCurrentProposer()` against the wrong slot and signature verification fails
|
|
1263
1321
|
// silently inside Multicall3. Fire-and-forget so we don't block the sequencer's work loop while
|
|
1264
|
-
// waiting for the target slot to start, mirroring tryVoteAndPruneWhenCannotBuild
|
|
1265
|
-
|
|
1322
|
+
// waiting for the target slot to start, mirroring tryVoteAndPruneWhenCannotBuild, but tracked so
|
|
1323
|
+
// stop() can drain it.
|
|
1324
|
+
const send = publisher.sendRequestsAt(targetSlot).catch((err)=>{
|
|
1266
1325
|
this.log.error(`Failed to publish escape-hatch votes for slot ${slot}`, err, {
|
|
1267
1326
|
slot,
|
|
1268
1327
|
targetSlot
|
|
1269
1328
|
});
|
|
1270
1329
|
});
|
|
1330
|
+
this.pendingRequests.trackRequest(send, ()=>publisher.interrupt());
|
|
1271
1331
|
}
|
|
1272
1332
|
/**
|
|
1273
1333
|
* Considers invalidating a block if the pending chain is invalid. Depends on how long the invalid block
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/sequencer-client",
|
|
3
|
-
"version": "5.0.0-nightly.
|
|
3
|
+
"version": "5.0.0-nightly.20260706",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -27,37 +27,37 @@
|
|
|
27
27
|
"test:integration:run": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --no-cache --config jest.integration.config.json"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@aztec/aztec.js": "5.0.0-nightly.
|
|
31
|
-
"@aztec/bb-prover": "5.0.0-nightly.
|
|
32
|
-
"@aztec/blob-client": "5.0.0-nightly.
|
|
33
|
-
"@aztec/blob-lib": "5.0.0-nightly.
|
|
34
|
-
"@aztec/constants": "5.0.0-nightly.
|
|
35
|
-
"@aztec/epoch-cache": "5.0.0-nightly.
|
|
36
|
-
"@aztec/ethereum": "5.0.0-nightly.
|
|
37
|
-
"@aztec/foundation": "5.0.0-nightly.
|
|
38
|
-
"@aztec/l1-artifacts": "5.0.0-nightly.
|
|
39
|
-
"@aztec/node-keystore": "5.0.0-nightly.
|
|
40
|
-
"@aztec/noir-acvm_js": "5.0.0-nightly.
|
|
41
|
-
"@aztec/noir-contracts.js": "5.0.0-nightly.
|
|
42
|
-
"@aztec/noir-protocol-circuits-types": "5.0.0-nightly.
|
|
43
|
-
"@aztec/noir-types": "5.0.0-nightly.
|
|
44
|
-
"@aztec/p2p": "5.0.0-nightly.
|
|
45
|
-
"@aztec/protocol-contracts": "5.0.0-nightly.
|
|
46
|
-
"@aztec/prover-client": "5.0.0-nightly.
|
|
47
|
-
"@aztec/simulator": "5.0.0-nightly.
|
|
48
|
-
"@aztec/slasher": "5.0.0-nightly.
|
|
49
|
-
"@aztec/stdlib": "5.0.0-nightly.
|
|
50
|
-
"@aztec/telemetry-client": "5.0.0-nightly.
|
|
51
|
-
"@aztec/validator-client": "5.0.0-nightly.
|
|
52
|
-
"@aztec/validator-ha-signer": "5.0.0-nightly.
|
|
53
|
-
"@aztec/world-state": "5.0.0-nightly.
|
|
30
|
+
"@aztec/aztec.js": "5.0.0-nightly.20260706",
|
|
31
|
+
"@aztec/bb-prover": "5.0.0-nightly.20260706",
|
|
32
|
+
"@aztec/blob-client": "5.0.0-nightly.20260706",
|
|
33
|
+
"@aztec/blob-lib": "5.0.0-nightly.20260706",
|
|
34
|
+
"@aztec/constants": "5.0.0-nightly.20260706",
|
|
35
|
+
"@aztec/epoch-cache": "5.0.0-nightly.20260706",
|
|
36
|
+
"@aztec/ethereum": "5.0.0-nightly.20260706",
|
|
37
|
+
"@aztec/foundation": "5.0.0-nightly.20260706",
|
|
38
|
+
"@aztec/l1-artifacts": "5.0.0-nightly.20260706",
|
|
39
|
+
"@aztec/node-keystore": "5.0.0-nightly.20260706",
|
|
40
|
+
"@aztec/noir-acvm_js": "5.0.0-nightly.20260706",
|
|
41
|
+
"@aztec/noir-contracts.js": "5.0.0-nightly.20260706",
|
|
42
|
+
"@aztec/noir-protocol-circuits-types": "5.0.0-nightly.20260706",
|
|
43
|
+
"@aztec/noir-types": "5.0.0-nightly.20260706",
|
|
44
|
+
"@aztec/p2p": "5.0.0-nightly.20260706",
|
|
45
|
+
"@aztec/protocol-contracts": "5.0.0-nightly.20260706",
|
|
46
|
+
"@aztec/prover-client": "5.0.0-nightly.20260706",
|
|
47
|
+
"@aztec/simulator": "5.0.0-nightly.20260706",
|
|
48
|
+
"@aztec/slasher": "5.0.0-nightly.20260706",
|
|
49
|
+
"@aztec/stdlib": "5.0.0-nightly.20260706",
|
|
50
|
+
"@aztec/telemetry-client": "5.0.0-nightly.20260706",
|
|
51
|
+
"@aztec/validator-client": "5.0.0-nightly.20260706",
|
|
52
|
+
"@aztec/validator-ha-signer": "5.0.0-nightly.20260706",
|
|
53
|
+
"@aztec/world-state": "5.0.0-nightly.20260706",
|
|
54
54
|
"lodash.chunk": "^4.2.0",
|
|
55
55
|
"tslib": "^2.4.0",
|
|
56
56
|
"viem": "npm:@aztec/viem@2.38.2"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
|
-
"@aztec/archiver": "5.0.0-nightly.
|
|
60
|
-
"@aztec/kv-store": "5.0.0-nightly.
|
|
59
|
+
"@aztec/archiver": "5.0.0-nightly.20260706",
|
|
60
|
+
"@aztec/kv-store": "5.0.0-nightly.20260706",
|
|
61
61
|
"@electric-sql/pglite": "^0.3.14",
|
|
62
62
|
"@jest/globals": "^30.0.0",
|
|
63
63
|
"@types/jest": "^30.0.0",
|
|
@@ -180,16 +180,23 @@ export class SequencerClient {
|
|
|
180
180
|
this.validatorClient?.updateConfig(config);
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
-
/**
|
|
183
|
+
/**
|
|
184
|
+
* Starts (or resumes) the sequencer, validator, publishers, and metrics. Each underlying start is
|
|
185
|
+
* idempotent, so this is safe to call after a previous {@link pause} to resume building and publishing.
|
|
186
|
+
* The publisher manager is started before the sequencer's poll loop so publishing is ready before the
|
|
187
|
+
* sequencer first tries to publish to L1.
|
|
188
|
+
*/
|
|
184
189
|
public async start() {
|
|
185
190
|
await this.validatorClient?.start();
|
|
191
|
+
await this.publisherManager.start();
|
|
186
192
|
this.sequencer.start();
|
|
187
193
|
this.l1Metrics?.start();
|
|
188
|
-
await this.publisherManager.start();
|
|
189
194
|
}
|
|
190
195
|
|
|
191
196
|
/**
|
|
192
|
-
* Stops the sequencer
|
|
197
|
+
* Stops the sequencer, validator, publishers, and metrics for good, draining in-flight work. This is the
|
|
198
|
+
* final teardown path: stopping the validator client closes its slashing-protection database. For a
|
|
199
|
+
* restartable pause (e.g. around a test clock warp) use {@link pause} instead.
|
|
193
200
|
*/
|
|
194
201
|
public async stop() {
|
|
195
202
|
await this.sequencer.stop();
|
|
@@ -198,6 +205,15 @@ export class SequencerClient {
|
|
|
198
205
|
this.l1Metrics?.stop();
|
|
199
206
|
}
|
|
200
207
|
|
|
208
|
+
/**
|
|
209
|
+
* Gracefully pauses block production, waiting for in-flight work to finish rather than interrupting it,
|
|
210
|
+
* while leaving the validator, publishers, and metrics running so the sequencer can be resumed with
|
|
211
|
+
* {@link start}. Used by tests that pause sequencers around an L1 clock warp.
|
|
212
|
+
*/
|
|
213
|
+
public async pause() {
|
|
214
|
+
await this.sequencer.pause();
|
|
215
|
+
}
|
|
216
|
+
|
|
201
217
|
/** Triggers an immediate run of the sequencer, bypassing the polling interval. */
|
|
202
218
|
public trigger() {
|
|
203
219
|
return this.sequencer.trigger();
|
package/src/config.ts
CHANGED
|
@@ -242,7 +242,7 @@ export const sequencerConfigMappings: ConfigMappingsType<SequencerConfig> = {
|
|
|
242
242
|
...booleanConfigHelper(DefaultSequencerConfig.buildCheckpointIfEmpty),
|
|
243
243
|
},
|
|
244
244
|
skipPushProposedBlocksToArchiver: {
|
|
245
|
-
description: 'Skip pushing proposed blocks to archiver (
|
|
245
|
+
description: 'Skip pushing proposed blocks to archiver (test only)',
|
|
246
246
|
...booleanConfigHelper(DefaultSequencerConfig.skipPushProposedBlocksToArchiver),
|
|
247
247
|
},
|
|
248
248
|
minBlocksForCheckpoint: {
|
|
@@ -74,6 +74,7 @@ import { CheckpointVoter } from './checkpoint_voter.js';
|
|
|
74
74
|
import { SequencerInterruptedError } from './errors.js';
|
|
75
75
|
import type { SequencerEvents } from './events.js';
|
|
76
76
|
import type { SequencerMetrics } from './metrics.js';
|
|
77
|
+
import type { RequestsTracker } from './requests_tracker.js';
|
|
77
78
|
import type { SequencerRollupConstants } from './types.js';
|
|
78
79
|
import { SequencerState } from './utils.js';
|
|
79
80
|
|
|
@@ -105,8 +106,6 @@ export class CheckpointProposalJob implements Traceable {
|
|
|
105
106
|
protected readonly log: Logger;
|
|
106
107
|
private readonly checkpointEventLog: Logger;
|
|
107
108
|
|
|
108
|
-
/** Tracks the fire-and-forget L1 submission promise so it can be awaited during shutdown. */
|
|
109
|
-
private pendingL1Submission: Promise<void> | undefined;
|
|
110
109
|
private readonly interruptibleSleep = new InterruptibleSleep();
|
|
111
110
|
private interrupted = false;
|
|
112
111
|
|
|
@@ -151,6 +150,9 @@ export class CheckpointProposalJob implements Traceable {
|
|
|
151
150
|
private readonly metrics: SequencerMetrics,
|
|
152
151
|
private readonly checkpointMetrics: CheckpointProposalJobMetricsRecorder,
|
|
153
152
|
protected readonly eventEmitter: TypedEventEmitter<SequencerEvents>,
|
|
153
|
+
// Shared with the owning sequencer, which drains it during shutdown; the fire-and-forget L1
|
|
154
|
+
// submission this job backgrounds is tracked here rather than in a job-local tracker.
|
|
155
|
+
protected readonly pendingRequests: RequestsTracker,
|
|
154
156
|
private readonly setStateFn: (state: SequencerState, slot: SlotNumber) => void,
|
|
155
157
|
public readonly tracer: Tracer,
|
|
156
158
|
bindings?: LoggerBindings,
|
|
@@ -183,12 +185,6 @@ export class CheckpointProposalJob implements Traceable {
|
|
|
183
185
|
this.setStateFn(state, this.targetSlot);
|
|
184
186
|
}
|
|
185
187
|
|
|
186
|
-
/** Awaits the pending L1 submission if one is in progress. Call during shutdown. */
|
|
187
|
-
public async awaitPendingSubmission(): Promise<void> {
|
|
188
|
-
this.log.info('Awaiting pending L1 payload submission');
|
|
189
|
-
await this.pendingL1Submission;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
188
|
/** Interrupts job-owned waits, including the publisher's send-at-slot sleep, so shutdown can finish. */
|
|
193
189
|
public interrupt(): void {
|
|
194
190
|
this.interrupted = true;
|
|
@@ -257,7 +253,7 @@ export class CheckpointProposalJob implements Traceable {
|
|
|
257
253
|
// signature verification to fail silently inside Multicall3. Delay submission to the
|
|
258
254
|
// start of `targetSlot` so the tx mines in the slot the vote was signed for.
|
|
259
255
|
if (!this.config.fishermanMode) {
|
|
260
|
-
this.
|
|
256
|
+
this.pendingRequests.trackRequest(this.publisher.sendRequestsAt(this.targetSlot), () => this.interrupt());
|
|
261
257
|
}
|
|
262
258
|
return undefined;
|
|
263
259
|
}
|
|
@@ -272,7 +268,9 @@ export class CheckpointProposalJob implements Traceable {
|
|
|
272
268
|
}
|
|
273
269
|
|
|
274
270
|
// Background the attestation → signing → L1 pipeline so the work loop is unblocked
|
|
275
|
-
this.
|
|
271
|
+
this.pendingRequests.trackRequest(this.waitForAttestationsAndEnqueueSubmissionAsync(broadcast, votesPromises), () =>
|
|
272
|
+
this.interrupt(),
|
|
273
|
+
);
|
|
276
274
|
|
|
277
275
|
// Return the built checkpoint immediately — the work loop is now unblocked
|
|
278
276
|
return checkpoint;
|
|
@@ -280,7 +278,7 @@ export class CheckpointProposalJob implements Traceable {
|
|
|
280
278
|
|
|
281
279
|
/**
|
|
282
280
|
* Background pipeline: collects attestations, signs them, enqueues the checkpoint, and submits to L1.
|
|
283
|
-
* Runs as a fire-and-forget task
|
|
281
|
+
* Runs as a fire-and-forget task tracked in the sequencer's shared tracker so the work loop is unblocked.
|
|
284
282
|
*/
|
|
285
283
|
private async waitForAttestationsAndEnqueueSubmissionAsync(
|
|
286
284
|
broadcast: CheckpointProposalBroadcast,
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/** A tracked request: the awaitable to wait on, plus an optional interrupt to cancel it early. */
|
|
2
|
+
type TrackedRequest = { promise: Promise<unknown>; interrupt?: () => void };
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Tracks fire-and-forget requests so a shutdown path can interrupt any in-flight work and await it to
|
|
6
|
+
* settle. Each tracked request is a promise plus an optional interrupt callback; the entry removes itself
|
|
7
|
+
* from the bag once its promise settles, so the tracker only ever holds requests that are still in flight.
|
|
8
|
+
*/
|
|
9
|
+
export class RequestsTracker {
|
|
10
|
+
private readonly requests = new Map<number, TrackedRequest>();
|
|
11
|
+
private nextId = 0;
|
|
12
|
+
|
|
13
|
+
/** Number of in-flight requests currently tracked. */
|
|
14
|
+
public get size(): number {
|
|
15
|
+
return this.requests.size;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Tracks a fire-and-forget request. `interrupt`, when provided, is invoked by {@link interruptRequests}
|
|
20
|
+
* to cancel the in-flight work so its promise settles promptly. The entry auto-removes once `promise`
|
|
21
|
+
* settles, whether it resolves or rejects.
|
|
22
|
+
*/
|
|
23
|
+
public trackRequest(promise: Promise<unknown>, interrupt?: () => void): void {
|
|
24
|
+
const id = this.nextId++;
|
|
25
|
+
const settled = promise.then(
|
|
26
|
+
() => this.requests.delete(id),
|
|
27
|
+
() => this.requests.delete(id),
|
|
28
|
+
);
|
|
29
|
+
this.requests.set(id, { promise: settled, interrupt });
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Interrupts every in-flight request that was tracked with an interrupt callback. */
|
|
33
|
+
public interruptRequests(): void {
|
|
34
|
+
for (const { interrupt } of this.requests.values()) {
|
|
35
|
+
interrupt?.();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Awaits every currently in-flight request to settle. */
|
|
40
|
+
public async awaitRequests(): Promise<void> {
|
|
41
|
+
await Promise.all([...this.requests.values()].map(request => request.promise));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -55,6 +55,7 @@ import { CheckpointVoter } from './checkpoint_voter.js';
|
|
|
55
55
|
import { SequencerInterruptedError } from './errors.js';
|
|
56
56
|
import type { SequencerEvents } from './events.js';
|
|
57
57
|
import { SequencerMetrics } from './metrics.js';
|
|
58
|
+
import { RequestsTracker } from './requests_tracker.js';
|
|
58
59
|
import type { SequencerRollupConstants } from './types.js';
|
|
59
60
|
import { SequencerState } from './utils.js';
|
|
60
61
|
|
|
@@ -79,7 +80,7 @@ type SequencerSlotContext = {
|
|
|
79
80
|
* - Votes for proposals and slashes on L1
|
|
80
81
|
*/
|
|
81
82
|
export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<SequencerEvents>) {
|
|
82
|
-
|
|
83
|
+
protected runningPromise?: RunningPromise;
|
|
83
84
|
private state = SequencerState.STOPPED;
|
|
84
85
|
private stateSlotNumber: SlotNumber | undefined;
|
|
85
86
|
/** Wall-clock time (ms, via the date provider) at which the current state was entered. */
|
|
@@ -110,6 +111,17 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
110
111
|
/** The last checkpoint proposal job, tracked so we can await its pending L1 submission during shutdown. */
|
|
111
112
|
protected lastCheckpointProposalJob: CheckpointProposalJob | undefined;
|
|
112
113
|
|
|
114
|
+
/**
|
|
115
|
+
* In-flight fire-and-forget requests that {@link stop} interrupts and drains, and {@link pause} awaits
|
|
116
|
+
* untouched: the checkpoint proposal jobs' backgrounded L1 submissions (each job is handed this shared
|
|
117
|
+
* tracker) plus the sequencer's own fallback submissions (votes/prune when we cannot build, or
|
|
118
|
+
* escape-hatch votes). Each fallback send is gated by its wrapper publisher's interruptible target-slot
|
|
119
|
+
* sleep; the tracked interrupt wakes that sleep so the send short-circuits without publishing. A wrapper
|
|
120
|
+
* is created for a single send and is never restarted, so once interrupted its sleeper can never publish
|
|
121
|
+
* a stale-slot tx, even after the pooled publishers are restarted by a later {@link start}.
|
|
122
|
+
*/
|
|
123
|
+
protected readonly pendingRequests = new RequestsTracker();
|
|
124
|
+
|
|
113
125
|
/** Proposer schedule and block sub-slot timetable for the sequencer, rebuilt on every config update. */
|
|
114
126
|
protected timetable!: ProposerTimetable;
|
|
115
127
|
|
|
@@ -273,8 +285,22 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
273
285
|
getKzg();
|
|
274
286
|
}
|
|
275
287
|
|
|
276
|
-
/**
|
|
288
|
+
/**
|
|
289
|
+
* Starts (or restarts) the sequencer and moves it to the IDLE state. Idempotent: a start while already
|
|
290
|
+
* running is a no-op, so it never orphans the previous poll loop. A start while STOPPING throws, since the
|
|
291
|
+
* in-flight stop would mark the fresh loop's state STOPPED and orphan it — silently doing nothing would
|
|
292
|
+
* leave the caller believing the sequencer is running when it is on its way to STOPPED. Safe to call after
|
|
293
|
+
* a previous {@link stop} has resolved; the caller must also restart the publishers (see
|
|
294
|
+
* {@link SequencerClient.start}) so L1 publishing is re-enabled.
|
|
295
|
+
*/
|
|
277
296
|
public start() {
|
|
297
|
+
if (this.state === SequencerState.STOPPING) {
|
|
298
|
+
throw new Error('Cannot start sequencer while it is stopping');
|
|
299
|
+
}
|
|
300
|
+
if (this.runningPromise?.isRunning()) {
|
|
301
|
+
this.log.warn('Attempted to start sequencer that is already running');
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
278
304
|
this.runningPromise = new RunningPromise(
|
|
279
305
|
this.safeWork.bind(this),
|
|
280
306
|
this.log,
|
|
@@ -290,18 +316,56 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
290
316
|
return this.runningPromise?.trigger();
|
|
291
317
|
}
|
|
292
318
|
|
|
293
|
-
/**
|
|
319
|
+
/**
|
|
320
|
+
* Stops the sequencer from building blocks and moves it to STOPPED state, interrupting the in-flight
|
|
321
|
+
* work() iteration and its pending L1 submissions for a fast shutdown, then draining before returning.
|
|
322
|
+
* Idempotent: a second call while already stopped or stopping is a no-op. Lifecycle calls are expected
|
|
323
|
+
* to be serialized by the caller. For a restartable pause that lets in-flight work finish untouched
|
|
324
|
+
* (e.g. around a test clock warp), use {@link pause} instead.
|
|
325
|
+
*/
|
|
294
326
|
public async stop(): Promise<void> {
|
|
327
|
+
if (this.state === SequencerState.STOPPED || this.state === SequencerState.STOPPING) {
|
|
328
|
+
this.log.debug(`Sequencer already ${this.state.toLowerCase()}, ignoring stop`);
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
295
331
|
this.log.info(`Stopping sequencer`);
|
|
296
332
|
this.setState(SequencerState.STOPPING, undefined, { force: true });
|
|
297
333
|
this.lastCheckpointProposalJob?.interrupt();
|
|
298
334
|
await this.publisherFactory.stopAll();
|
|
335
|
+
// Stop the poll loop and await the in-flight work() iteration. work() registers its fire-and-forget
|
|
336
|
+
// requests synchronously before returning, so once the loop has stopped, pendingRequests holds every
|
|
337
|
+
// request that will ever exist. Interrupting any earlier could miss a request registered by the last
|
|
338
|
+
// in-flight iteration.
|
|
299
339
|
await this.runningPromise?.stop();
|
|
300
|
-
|
|
340
|
+
this.pendingRequests.interruptRequests();
|
|
341
|
+
await this.pendingRequests.awaitRequests();
|
|
301
342
|
this.setState(SequencerState.STOPPED, undefined, { force: true });
|
|
302
343
|
this.log.info('Stopped sequencer');
|
|
303
344
|
}
|
|
304
345
|
|
|
346
|
+
/**
|
|
347
|
+
* Gracefully pauses block production so the sequencer can later be resumed with {@link start}: halts the
|
|
348
|
+
* poll loop and waits for the in-flight work() iteration and every pending L1 submission / fallback send
|
|
349
|
+
* to finish, without interrupting them. No interrupt lands mid-build, so no spurious checkpoint-error is
|
|
350
|
+
* emitted and no enqueued checkpoint is dropped. Deliberately does not stop inner services (validator/HA
|
|
351
|
+
* signer, publishers), so the slashing-protection store stays open and the sequencer stays restartable.
|
|
352
|
+
* Used by tests that pause sequencers around an L1 clock warp. Idempotent.
|
|
353
|
+
*/
|
|
354
|
+
public async pause(): Promise<void> {
|
|
355
|
+
if (!this.runningPromise?.isRunning()) {
|
|
356
|
+
this.log.debug('Sequencer not running, ignoring pause');
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
this.log.info('Pausing sequencer');
|
|
360
|
+
// Halt the poll loop and let the in-flight iteration finish naturally — no interrupt, and no STOPPING
|
|
361
|
+
// state, since entering STOPPING would make the iteration's own setState calls throw and fail it.
|
|
362
|
+
// work() registers its fire-and-forget requests synchronously before returning, so once the loop has
|
|
363
|
+
// stopped pendingRequests holds every request that will ever exist; awaiting it lets them all finish.
|
|
364
|
+
await this.runningPromise.stop();
|
|
365
|
+
await this.pendingRequests.awaitRequests();
|
|
366
|
+
this.log.info('Paused sequencer');
|
|
367
|
+
}
|
|
368
|
+
|
|
305
369
|
/** Main sequencer loop with a try/catch */
|
|
306
370
|
protected async safeWork() {
|
|
307
371
|
try {
|
|
@@ -452,13 +516,6 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
452
516
|
return undefined;
|
|
453
517
|
}
|
|
454
518
|
|
|
455
|
-
// We are the proposer and the escape hatch is closed: now run the full sync check before building.
|
|
456
|
-
const syncedTo = await this.checkSync({ ts, slot });
|
|
457
|
-
if (!syncedTo) {
|
|
458
|
-
await this.tryVoteAndPruneWhenCannotBuild({ slot, targetSlot });
|
|
459
|
-
return undefined;
|
|
460
|
-
}
|
|
461
|
-
|
|
462
519
|
// Explicit build-loop entry gate: if we are past the latest useful block-building start for the
|
|
463
520
|
// target slot, abandon building for this slot. The proposer prioritizes the ideal L1-publish path
|
|
464
521
|
// and does not plan around the late consensus-handoff path. This is the proposer build path's
|
|
@@ -480,6 +537,13 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
480
537
|
return undefined;
|
|
481
538
|
}
|
|
482
539
|
|
|
540
|
+
// We are the proposer, the escape hatch is closed, and we have time before the build start deadline.
|
|
541
|
+
// Now run the full sync check before building.
|
|
542
|
+
const syncedTo = await this.checkSync({ ts, slot });
|
|
543
|
+
if (!syncedTo) {
|
|
544
|
+
return undefined;
|
|
545
|
+
}
|
|
546
|
+
|
|
483
547
|
// Next checkpoint follows from the last synced one
|
|
484
548
|
const checkpointNumber = CheckpointNumber(syncedTo.checkpointNumber + 1);
|
|
485
549
|
|
|
@@ -707,6 +771,7 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
707
771
|
this.metrics,
|
|
708
772
|
this.checkpointProposalJobMetrics.createRecorder(),
|
|
709
773
|
this,
|
|
774
|
+
this.pendingRequests,
|
|
710
775
|
this.setState.bind(this),
|
|
711
776
|
this.tracer,
|
|
712
777
|
this.log.getBindings(),
|
|
@@ -1023,10 +1088,11 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
1023
1088
|
// Votes are EIP-712-signed for `targetSlot` (the pipelined slot in which the multicall is
|
|
1024
1089
|
// expected to mine). Delay submission to the start of `targetSlot` so the tx mines in the
|
|
1025
1090
|
// slot the votes were signed for. We fire-and-forget so we don't block the sequencer's
|
|
1026
|
-
// work loop while waiting for the target slot to start.
|
|
1027
|
-
|
|
1091
|
+
// work loop while waiting for the target slot to start, but track it so stop() can drain it.
|
|
1092
|
+
const send = publisher.sendRequestsAt(targetSlot).catch(err => {
|
|
1028
1093
|
this.log.error(`Failed to publish fallback requests despite sync failure for slot ${slot}`, err, { slot });
|
|
1029
1094
|
});
|
|
1095
|
+
this.pendingRequests.trackRequest(send, () => publisher.interrupt());
|
|
1030
1096
|
}
|
|
1031
1097
|
|
|
1032
1098
|
private async tryEnqueuePruneIfPrunable(targetSlot: SlotNumber, publisher: SequencerPublisher): Promise<boolean> {
|
|
@@ -1096,10 +1162,12 @@ export class Sequencer extends (EventEmitter as new () => TypedEventEmitter<Sequ
|
|
|
1096
1162
|
// the multicall mines in the slot the votes were signed for; otherwise the L1 contract reads
|
|
1097
1163
|
// `signaler = getCurrentProposer()` against the wrong slot and signature verification fails
|
|
1098
1164
|
// silently inside Multicall3. Fire-and-forget so we don't block the sequencer's work loop while
|
|
1099
|
-
// waiting for the target slot to start, mirroring tryVoteAndPruneWhenCannotBuild
|
|
1100
|
-
|
|
1165
|
+
// waiting for the target slot to start, mirroring tryVoteAndPruneWhenCannotBuild, but tracked so
|
|
1166
|
+
// stop() can drain it.
|
|
1167
|
+
const send = publisher.sendRequestsAt(targetSlot).catch(err => {
|
|
1101
1168
|
this.log.error(`Failed to publish escape-hatch votes for slot ${slot}`, err, { slot, targetSlot });
|
|
1102
1169
|
});
|
|
1170
|
+
this.pendingRequests.trackRequest(send, () => publisher.interrupt());
|
|
1103
1171
|
}
|
|
1104
1172
|
|
|
1105
1173
|
/**
|