@aztec/sequencer-client 3.0.3 → 3.9.9-nightly.20260312
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 +32 -15
- package/dest/client/sequencer-client.d.ts.map +1 -1
- package/dest/client/sequencer-client.js +116 -27
- package/dest/config.d.ts +29 -4
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +103 -40
- package/dest/global_variable_builder/global_builder.d.ts +17 -11
- package/dest/global_variable_builder/global_builder.d.ts.map +1 -1
- package/dest/global_variable_builder/global_builder.js +48 -39
- package/dest/index.d.ts +2 -3
- package/dest/index.d.ts.map +1 -1
- package/dest/index.js +1 -2
- package/dest/publisher/config.d.ts +33 -19
- package/dest/publisher/config.d.ts.map +1 -1
- package/dest/publisher/config.js +102 -43
- package/dest/publisher/sequencer-publisher-factory.d.ts +13 -5
- package/dest/publisher/sequencer-publisher-factory.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher-factory.js +14 -3
- package/dest/publisher/sequencer-publisher-metrics.d.ts +3 -3
- package/dest/publisher/sequencer-publisher-metrics.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher-metrics.js +23 -86
- package/dest/publisher/sequencer-publisher.d.ts +58 -45
- package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher.js +628 -139
- package/dest/sequencer/checkpoint_proposal_job.d.ts +100 -0
- package/dest/sequencer/checkpoint_proposal_job.d.ts.map +1 -0
- package/dest/sequencer/checkpoint_proposal_job.js +1234 -0
- package/dest/sequencer/checkpoint_voter.d.ts +35 -0
- package/dest/sequencer/checkpoint_voter.d.ts.map +1 -0
- package/dest/sequencer/checkpoint_voter.js +109 -0
- package/dest/sequencer/events.d.ts +46 -0
- package/dest/sequencer/events.d.ts.map +1 -0
- package/dest/sequencer/events.js +1 -0
- package/dest/sequencer/index.d.ts +4 -2
- package/dest/sequencer/index.d.ts.map +1 -1
- package/dest/sequencer/index.js +3 -1
- package/dest/sequencer/metrics.d.ts +37 -5
- package/dest/sequencer/metrics.d.ts.map +1 -1
- package/dest/sequencer/metrics.js +216 -72
- package/dest/sequencer/sequencer.d.ts +122 -131
- package/dest/sequencer/sequencer.d.ts.map +1 -1
- package/dest/sequencer/sequencer.js +705 -635
- package/dest/sequencer/timetable.d.ts +54 -16
- package/dest/sequencer/timetable.d.ts.map +1 -1
- package/dest/sequencer/timetable.js +147 -62
- package/dest/sequencer/types.d.ts +3 -0
- package/dest/sequencer/types.d.ts.map +1 -0
- package/dest/sequencer/types.js +1 -0
- package/dest/sequencer/utils.d.ts +14 -8
- package/dest/sequencer/utils.d.ts.map +1 -1
- package/dest/sequencer/utils.js +7 -4
- package/dest/test/index.d.ts +5 -6
- package/dest/test/index.d.ts.map +1 -1
- package/dest/test/mock_checkpoint_builder.d.ts +95 -0
- package/dest/test/mock_checkpoint_builder.d.ts.map +1 -0
- package/dest/test/mock_checkpoint_builder.js +233 -0
- package/dest/test/utils.d.ts +53 -0
- package/dest/test/utils.d.ts.map +1 -0
- package/dest/test/utils.js +104 -0
- package/package.json +30 -28
- package/src/client/sequencer-client.ts +154 -45
- package/src/config.ts +119 -45
- package/src/global_variable_builder/global_builder.ts +57 -51
- package/src/index.ts +1 -7
- package/src/publisher/config.ts +115 -46
- package/src/publisher/sequencer-publisher-factory.ts +26 -9
- package/src/publisher/sequencer-publisher-metrics.ts +19 -71
- package/src/publisher/sequencer-publisher.ts +334 -176
- package/src/sequencer/README.md +531 -0
- package/src/sequencer/checkpoint_proposal_job.ts +950 -0
- package/src/sequencer/checkpoint_voter.ts +130 -0
- package/src/sequencer/events.ts +27 -0
- package/src/sequencer/index.ts +3 -1
- package/src/sequencer/metrics.ts +267 -81
- package/src/sequencer/sequencer.ts +444 -834
- package/src/sequencer/timetable.ts +178 -83
- package/src/sequencer/types.ts +6 -0
- package/src/sequencer/utils.ts +18 -9
- package/src/test/index.ts +4 -5
- package/src/test/mock_checkpoint_builder.ts +325 -0
- package/src/test/utils.ts +167 -0
- package/dest/sequencer/block_builder.d.ts +0 -28
- package/dest/sequencer/block_builder.d.ts.map +0 -1
- package/dest/sequencer/block_builder.js +0 -127
- package/dest/tx_validator/nullifier_cache.d.ts +0 -14
- package/dest/tx_validator/nullifier_cache.d.ts.map +0 -1
- package/dest/tx_validator/nullifier_cache.js +0 -24
- package/dest/tx_validator/tx_validator_factory.d.ts +0 -18
- package/dest/tx_validator/tx_validator_factory.d.ts.map +0 -1
- package/dest/tx_validator/tx_validator_factory.js +0 -53
- package/src/sequencer/block_builder.ts +0 -214
- package/src/tx_validator/nullifier_cache.ts +0 -30
- package/src/tx_validator/tx_validator_factory.ts +0 -133
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { BlobClientInterface } from '@aztec/blob-client/client';
|
|
2
|
+
import { MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT } from '@aztec/constants';
|
|
2
3
|
import { EpochCache } from '@aztec/epoch-cache';
|
|
3
4
|
import { isAnvilTestChain } from '@aztec/ethereum/chain';
|
|
4
5
|
import { getPublicClient } from '@aztec/ethereum/client';
|
|
5
6
|
import { GovernanceProposerContract, RollupContract } from '@aztec/ethereum/contracts';
|
|
6
|
-
import {
|
|
7
|
+
import { type Delayer, L1TxUtils } from '@aztec/ethereum/l1-tx-utils';
|
|
7
8
|
import { PublisherManager } from '@aztec/ethereum/publisher-manager';
|
|
8
9
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
9
10
|
import { createLogger } from '@aztec/foundation/log';
|
|
@@ -11,32 +12,34 @@ import type { DateProvider } from '@aztec/foundation/timer';
|
|
|
11
12
|
import type { KeystoreManager } from '@aztec/node-keystore';
|
|
12
13
|
import type { P2P } from '@aztec/p2p';
|
|
13
14
|
import type { SlasherClientInterface } from '@aztec/slasher';
|
|
14
|
-
import type { L2BlockSource } from '@aztec/stdlib/block';
|
|
15
|
-
import type {
|
|
16
|
-
IFullNodeBlockBuilder,
|
|
17
|
-
ValidatorClientFullConfig,
|
|
18
|
-
WorldStateSynchronizer,
|
|
19
|
-
} from '@aztec/stdlib/interfaces/server';
|
|
15
|
+
import type { L2BlockSink, L2BlockSource } from '@aztec/stdlib/block';
|
|
16
|
+
import type { ValidatorClientFullConfig, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
|
|
20
17
|
import { SlashFactoryContract } from '@aztec/stdlib/l1-contracts';
|
|
21
18
|
import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
|
|
22
19
|
import { L1Metrics, type TelemetryClient } from '@aztec/telemetry-client';
|
|
23
|
-
import { NodeKeystoreAdapter, type ValidatorClient } from '@aztec/validator-client';
|
|
20
|
+
import { FullNodeCheckpointsBuilder, NodeKeystoreAdapter, type ValidatorClient } from '@aztec/validator-client';
|
|
24
21
|
|
|
25
|
-
import
|
|
22
|
+
import {
|
|
23
|
+
DefaultSequencerConfig,
|
|
24
|
+
type SequencerClientConfig,
|
|
25
|
+
getPublisherConfigFromSequencerConfig,
|
|
26
|
+
} from '../config.js';
|
|
26
27
|
import { GlobalVariableBuilder } from '../global_variable_builder/index.js';
|
|
27
28
|
import { SequencerPublisherFactory } from '../publisher/sequencer-publisher-factory.js';
|
|
28
29
|
import { Sequencer, type SequencerConfig } from '../sequencer/index.js';
|
|
30
|
+
import { SequencerTimetable } from '../sequencer/timetable.js';
|
|
29
31
|
|
|
30
32
|
/**
|
|
31
33
|
* Encapsulates the full sequencer and publisher.
|
|
32
34
|
*/
|
|
33
35
|
export class SequencerClient {
|
|
34
36
|
constructor(
|
|
35
|
-
protected publisherManager: PublisherManager<
|
|
37
|
+
protected publisherManager: PublisherManager<L1TxUtils>,
|
|
36
38
|
protected sequencer: Sequencer,
|
|
37
|
-
protected
|
|
39
|
+
protected checkpointsBuilder: FullNodeCheckpointsBuilder,
|
|
38
40
|
protected validatorClient?: ValidatorClient,
|
|
39
41
|
private l1Metrics?: L1Metrics,
|
|
42
|
+
private delayer_?: Delayer,
|
|
40
43
|
) {}
|
|
41
44
|
|
|
42
45
|
/**
|
|
@@ -54,19 +57,19 @@ export class SequencerClient {
|
|
|
54
57
|
public static async new(
|
|
55
58
|
config: SequencerClientConfig,
|
|
56
59
|
deps: {
|
|
57
|
-
validatorClient: ValidatorClient
|
|
60
|
+
validatorClient: ValidatorClient;
|
|
58
61
|
p2pClient: P2P;
|
|
59
62
|
worldStateSynchronizer: WorldStateSynchronizer;
|
|
60
63
|
slasherClient: SlasherClientInterface | undefined;
|
|
61
|
-
|
|
62
|
-
l2BlockSource: L2BlockSource;
|
|
64
|
+
checkpointsBuilder: FullNodeCheckpointsBuilder;
|
|
65
|
+
l2BlockSource: L2BlockSource & L2BlockSink;
|
|
63
66
|
l1ToL2MessageSource: L1ToL2MessageSource;
|
|
64
67
|
telemetry: TelemetryClient;
|
|
65
68
|
publisherFactory?: SequencerPublisherFactory;
|
|
66
|
-
|
|
69
|
+
blobClient: BlobClientInterface;
|
|
67
70
|
dateProvider: DateProvider;
|
|
68
71
|
epochCache?: EpochCache;
|
|
69
|
-
l1TxUtils:
|
|
72
|
+
l1TxUtils: L1TxUtils[];
|
|
70
73
|
nodeKeyStore: KeystoreManager;
|
|
71
74
|
},
|
|
72
75
|
) {
|
|
@@ -75,7 +78,7 @@ export class SequencerClient {
|
|
|
75
78
|
p2pClient,
|
|
76
79
|
worldStateSynchronizer,
|
|
77
80
|
slasherClient,
|
|
78
|
-
|
|
81
|
+
checkpointsBuilder,
|
|
79
82
|
l2BlockSource,
|
|
80
83
|
l1ToL2MessageSource,
|
|
81
84
|
telemetry: telemetryClient,
|
|
@@ -89,11 +92,17 @@ export class SequencerClient {
|
|
|
89
92
|
publicClient,
|
|
90
93
|
l1TxUtils.map(x => x.getSenderAddress()),
|
|
91
94
|
);
|
|
92
|
-
const publisherManager = new PublisherManager(
|
|
95
|
+
const publisherManager = new PublisherManager(
|
|
96
|
+
l1TxUtils,
|
|
97
|
+
getPublisherConfigFromSequencerConfig(config),
|
|
98
|
+
log.getBindings(),
|
|
99
|
+
);
|
|
93
100
|
const rollupContract = new RollupContract(publicClient, config.l1Contracts.rollupAddress.toString());
|
|
94
|
-
const [l1GenesisTime, slotDuration] = await Promise.all([
|
|
101
|
+
const [l1GenesisTime, slotDuration, rollupVersion, rollupManaLimit] = await Promise.all([
|
|
95
102
|
rollupContract.getL1GenesisTime(),
|
|
96
103
|
rollupContract.getSlotDuration(),
|
|
104
|
+
rollupContract.getVersion(),
|
|
105
|
+
rollupContract.getManaLimit().then(Number),
|
|
97
106
|
] as const);
|
|
98
107
|
|
|
99
108
|
const governanceProposerContract = new GovernanceProposerContract(
|
|
@@ -122,7 +131,7 @@ export class SequencerClient {
|
|
|
122
131
|
deps.publisherFactory ??
|
|
123
132
|
new SequencerPublisherFactory(config, {
|
|
124
133
|
telemetry: telemetryClient,
|
|
125
|
-
|
|
134
|
+
blobClient: deps.blobClient,
|
|
126
135
|
epochCache,
|
|
127
136
|
governanceProposerContract,
|
|
128
137
|
slashFactoryContract,
|
|
@@ -132,33 +141,33 @@ export class SequencerClient {
|
|
|
132
141
|
nodeKeyStore: NodeKeystoreAdapter.fromKeyStoreManager(deps.nodeKeyStore),
|
|
133
142
|
logger: log,
|
|
134
143
|
});
|
|
135
|
-
const globalsBuilder = new GlobalVariableBuilder(config);
|
|
136
144
|
|
|
137
145
|
const ethereumSlotDuration = config.ethereumSlotDuration;
|
|
138
146
|
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
}
|
|
147
|
+
const globalsBuilder = new GlobalVariableBuilder({
|
|
148
|
+
...config,
|
|
149
|
+
l1GenesisTime,
|
|
150
|
+
slotDuration: Number(slotDuration),
|
|
151
|
+
ethereumSlotDuration,
|
|
152
|
+
rollupVersion,
|
|
153
|
+
});
|
|
147
154
|
|
|
148
155
|
// When running in anvil, assume we can post a tx up until one second before the end of an L1 slot.
|
|
149
|
-
// Otherwise,
|
|
150
|
-
// maxL1TxInclusionTimeIntoSlot of zero) to get the tx into that L1 slot.
|
|
156
|
+
// Otherwise, we need the full L1 slot duration for publishing to ensure inclusion.
|
|
151
157
|
// In theory, the L1 slot has an initial 4s phase where the block is propagated, so we could
|
|
152
|
-
//
|
|
158
|
+
// reduce the publishing time allowance. However, we prefer being conservative.
|
|
153
159
|
// See https://www.blocknative.com/blog/anatomy-of-a-slot#7 for more info.
|
|
154
|
-
const
|
|
155
|
-
const
|
|
160
|
+
const l1PublishingTimeBasedOnChain = isAnvilTestChain(config.l1ChainId) ? 1 : ethereumSlotDuration;
|
|
161
|
+
const l1PublishingTime = config.l1PublishingTime ?? l1PublishingTimeBasedOnChain;
|
|
156
162
|
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
163
|
+
const { maxL2BlockGas, maxDABlockGas, maxTxsPerBlock, maxBlocksPerCheckpoint } = computeBlockLimits(
|
|
164
|
+
config,
|
|
165
|
+
rollupManaLimit,
|
|
166
|
+
l1PublishingTime,
|
|
167
|
+
log,
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
const l1Constants = { l1GenesisTime, slotDuration: Number(slotDuration), ethereumSlotDuration, rollupManaLimit };
|
|
162
171
|
|
|
163
172
|
const sequencer = new Sequencer(
|
|
164
173
|
publisherFactory,
|
|
@@ -169,19 +178,22 @@ export class SequencerClient {
|
|
|
169
178
|
slasherClient,
|
|
170
179
|
l2BlockSource,
|
|
171
180
|
l1ToL2MessageSource,
|
|
172
|
-
|
|
181
|
+
checkpointsBuilder,
|
|
173
182
|
l1Constants,
|
|
174
183
|
deps.dateProvider,
|
|
175
184
|
epochCache,
|
|
176
185
|
rollupContract,
|
|
177
|
-
{ ...config,
|
|
186
|
+
{ ...config, l1PublishingTime, maxL2BlockGas, maxDABlockGas, maxTxsPerBlock, maxBlocksPerCheckpoint },
|
|
178
187
|
telemetryClient,
|
|
179
188
|
log,
|
|
180
189
|
);
|
|
181
190
|
|
|
182
|
-
|
|
191
|
+
sequencer.init();
|
|
192
|
+
|
|
193
|
+
// Extract the shared delayer from the first L1TxUtils instance (all instances share the same delayer)
|
|
194
|
+
const delayer = l1TxUtils[0]?.delayer;
|
|
183
195
|
|
|
184
|
-
return new SequencerClient(publisherManager, sequencer,
|
|
196
|
+
return new SequencerClient(publisherManager, sequencer, checkpointsBuilder, validatorClient, l1Metrics, delayer);
|
|
185
197
|
}
|
|
186
198
|
|
|
187
199
|
/**
|
|
@@ -190,7 +202,7 @@ export class SequencerClient {
|
|
|
190
202
|
*/
|
|
191
203
|
public updateConfig(config: SequencerConfig & Partial<ValidatorClientFullConfig>) {
|
|
192
204
|
this.sequencer.updateConfig(config);
|
|
193
|
-
this.
|
|
205
|
+
this.checkpointsBuilder.updateConfig(config);
|
|
194
206
|
this.validatorClient?.updateConfig(config);
|
|
195
207
|
}
|
|
196
208
|
|
|
@@ -216,6 +228,16 @@ export class SequencerClient {
|
|
|
216
228
|
return this.sequencer;
|
|
217
229
|
}
|
|
218
230
|
|
|
231
|
+
/** Updates the publisher factory's node keystore adapter after a keystore reload. */
|
|
232
|
+
public updatePublisherNodeKeyStore(adapter: NodeKeystoreAdapter): void {
|
|
233
|
+
this.sequencer.updatePublisherNodeKeyStore(adapter);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/** Returns the shared tx delayer for sequencer L1 txs, if enabled. Test-only. */
|
|
237
|
+
getDelayer(): Delayer | undefined {
|
|
238
|
+
return this.delayer_;
|
|
239
|
+
}
|
|
240
|
+
|
|
219
241
|
get validatorAddresses(): EthAddress[] | undefined {
|
|
220
242
|
return this.sequencer.getValidatorAddresses();
|
|
221
243
|
}
|
|
@@ -224,3 +246,90 @@ export class SequencerClient {
|
|
|
224
246
|
return this.sequencer.maxL2BlockGas;
|
|
225
247
|
}
|
|
226
248
|
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Computes per-block L2 gas, DA gas, and TX count budgets based on the L1 rollup limits and the timetable.
|
|
252
|
+
* If the user explicitly set a limit, it is capped at the corresponding checkpoint limit.
|
|
253
|
+
* Otherwise, derives it as (checkpointLimit / maxBlocks) * multiplier, capped at the checkpoint limit.
|
|
254
|
+
*/
|
|
255
|
+
export function computeBlockLimits(
|
|
256
|
+
config: SequencerClientConfig,
|
|
257
|
+
rollupManaLimit: number,
|
|
258
|
+
l1PublishingTime: number,
|
|
259
|
+
log: ReturnType<typeof createLogger>,
|
|
260
|
+
): { maxL2BlockGas: number; maxDABlockGas: number; maxTxsPerBlock: number; maxBlocksPerCheckpoint: number } {
|
|
261
|
+
const maxNumberOfBlocks = new SequencerTimetable({
|
|
262
|
+
ethereumSlotDuration: config.ethereumSlotDuration,
|
|
263
|
+
aztecSlotDuration: config.aztecSlotDuration,
|
|
264
|
+
l1PublishingTime,
|
|
265
|
+
p2pPropagationTime: config.attestationPropagationTime,
|
|
266
|
+
blockDurationMs: config.blockDurationMs,
|
|
267
|
+
enforce: config.enforceTimeTable ?? DefaultSequencerConfig.enforceTimeTable,
|
|
268
|
+
}).maxNumberOfBlocks;
|
|
269
|
+
|
|
270
|
+
const multiplier = config.perBlockAllocationMultiplier ?? DefaultSequencerConfig.perBlockAllocationMultiplier;
|
|
271
|
+
|
|
272
|
+
// Compute maxL2BlockGas
|
|
273
|
+
let maxL2BlockGas: number;
|
|
274
|
+
if (config.maxL2BlockGas !== undefined) {
|
|
275
|
+
if (config.maxL2BlockGas > rollupManaLimit) {
|
|
276
|
+
log.warn(
|
|
277
|
+
`Provided MAX_L2_BLOCK_GAS ${config.maxL2BlockGas} exceeds L1 rollup mana limit ${rollupManaLimit} (capping)`,
|
|
278
|
+
);
|
|
279
|
+
maxL2BlockGas = rollupManaLimit;
|
|
280
|
+
} else {
|
|
281
|
+
maxL2BlockGas = config.maxL2BlockGas;
|
|
282
|
+
}
|
|
283
|
+
} else {
|
|
284
|
+
maxL2BlockGas = Math.min(rollupManaLimit, Math.ceil((rollupManaLimit / maxNumberOfBlocks) * multiplier));
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Compute maxDABlockGas
|
|
288
|
+
const daCheckpointLimit = MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT;
|
|
289
|
+
let maxDABlockGas: number;
|
|
290
|
+
if (config.maxDABlockGas !== undefined) {
|
|
291
|
+
if (config.maxDABlockGas > daCheckpointLimit) {
|
|
292
|
+
log.warn(
|
|
293
|
+
`Provided MAX_DA_BLOCK_GAS ${config.maxDABlockGas} exceeds DA checkpoint limit ${daCheckpointLimit} (capping)`,
|
|
294
|
+
);
|
|
295
|
+
maxDABlockGas = daCheckpointLimit;
|
|
296
|
+
} else {
|
|
297
|
+
maxDABlockGas = config.maxDABlockGas;
|
|
298
|
+
}
|
|
299
|
+
} else {
|
|
300
|
+
maxDABlockGas = Math.min(daCheckpointLimit, Math.ceil((daCheckpointLimit / maxNumberOfBlocks) * multiplier));
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
// Compute maxTxsPerBlock
|
|
304
|
+
const defaultMaxTxsPerBlock = 32;
|
|
305
|
+
let maxTxsPerBlock: number;
|
|
306
|
+
if (config.maxTxsPerBlock !== undefined) {
|
|
307
|
+
if (config.maxTxsPerCheckpoint !== undefined && config.maxTxsPerBlock > config.maxTxsPerCheckpoint) {
|
|
308
|
+
log.warn(
|
|
309
|
+
`Provided MAX_TX_PER_BLOCK ${config.maxTxsPerBlock} exceeds MAX_TX_PER_CHECKPOINT ${config.maxTxsPerCheckpoint} (capping)`,
|
|
310
|
+
);
|
|
311
|
+
maxTxsPerBlock = config.maxTxsPerCheckpoint;
|
|
312
|
+
} else {
|
|
313
|
+
maxTxsPerBlock = config.maxTxsPerBlock;
|
|
314
|
+
}
|
|
315
|
+
} else if (config.maxTxsPerCheckpoint !== undefined) {
|
|
316
|
+
maxTxsPerBlock = Math.min(
|
|
317
|
+
config.maxTxsPerCheckpoint,
|
|
318
|
+
Math.ceil((config.maxTxsPerCheckpoint / maxNumberOfBlocks) * multiplier),
|
|
319
|
+
);
|
|
320
|
+
} else {
|
|
321
|
+
maxTxsPerBlock = defaultMaxTxsPerBlock;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
log.info(`Computed block limits L2=${maxL2BlockGas} DA=${maxDABlockGas} maxTxs=${maxTxsPerBlock}`, {
|
|
325
|
+
maxL2BlockGas,
|
|
326
|
+
maxDABlockGas,
|
|
327
|
+
maxTxsPerBlock,
|
|
328
|
+
rollupManaLimit,
|
|
329
|
+
daCheckpointLimit,
|
|
330
|
+
maxNumberOfBlocks,
|
|
331
|
+
multiplier,
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
return { maxL2BlockGas, maxDABlockGas, maxTxsPerBlock, maxBlocksPerCheckpoint: maxNumberOfBlocks };
|
|
335
|
+
}
|
package/src/config.ts
CHANGED
|
@@ -11,64 +11,116 @@ import { EthAddress } from '@aztec/foundation/eth-address';
|
|
|
11
11
|
import { type KeyStoreConfig, keyStoreConfigMappings } from '@aztec/node-keystore/config';
|
|
12
12
|
import { type P2PConfig, p2pConfigMappings } from '@aztec/p2p/config';
|
|
13
13
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
14
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
type ChainConfig,
|
|
16
|
+
type SequencerConfig,
|
|
17
|
+
chainConfigMappings,
|
|
18
|
+
sharedSequencerConfigMappings,
|
|
19
|
+
} from '@aztec/stdlib/config';
|
|
20
|
+
import type { ResolvedSequencerConfig } from '@aztec/stdlib/interfaces/server';
|
|
21
|
+
import { DEFAULT_P2P_PROPAGATION_TIME } from '@aztec/stdlib/timetable';
|
|
15
22
|
import { type ValidatorClientConfig, validatorClientConfigMappings } from '@aztec/validator-client/config';
|
|
16
23
|
|
|
17
24
|
import {
|
|
18
|
-
type
|
|
19
|
-
type
|
|
20
|
-
|
|
21
|
-
|
|
25
|
+
type SequencerPublisherConfig,
|
|
26
|
+
type SequencerTxSenderConfig,
|
|
27
|
+
sequencerPublisherConfigMappings,
|
|
28
|
+
sequencerTxSenderConfigMappings,
|
|
22
29
|
} from './publisher/config.js';
|
|
23
30
|
|
|
24
31
|
export * from './publisher/config.js';
|
|
25
32
|
export type { SequencerConfig };
|
|
26
33
|
|
|
27
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Default values for SequencerConfig.
|
|
36
|
+
* Centralized location for all sequencer configuration defaults.
|
|
37
|
+
*/
|
|
38
|
+
export const DefaultSequencerConfig = {
|
|
39
|
+
sequencerPollingIntervalMS: 500,
|
|
40
|
+
minTxsPerBlock: 1,
|
|
41
|
+
buildCheckpointIfEmpty: false,
|
|
42
|
+
publishTxsWithProposals: false,
|
|
43
|
+
perBlockAllocationMultiplier: 1.2,
|
|
44
|
+
redistributeCheckpointBudget: true,
|
|
45
|
+
enforceTimeTable: true,
|
|
46
|
+
attestationPropagationTime: DEFAULT_P2P_PROPAGATION_TIME,
|
|
47
|
+
secondsBeforeInvalidatingBlockAsCommitteeMember: 144, // 12 L1 blocks
|
|
48
|
+
secondsBeforeInvalidatingBlockAsNonCommitteeMember: 432, // 36 L1 blocks
|
|
49
|
+
skipCollectingAttestations: false,
|
|
50
|
+
skipInvalidateBlockAsProposer: false,
|
|
51
|
+
broadcastInvalidBlockProposal: false,
|
|
52
|
+
injectFakeAttestation: false,
|
|
53
|
+
injectHighSValueAttestation: false,
|
|
54
|
+
injectUnrecoverableSignatureAttestation: false,
|
|
55
|
+
fishermanMode: false,
|
|
56
|
+
shuffleAttestationOrdering: false,
|
|
57
|
+
skipPushProposedBlocksToArchiver: false,
|
|
58
|
+
skipPublishingCheckpointsPercent: 0,
|
|
59
|
+
} satisfies ResolvedSequencerConfig;
|
|
28
60
|
|
|
29
61
|
/**
|
|
30
62
|
* Configuration settings for the SequencerClient.
|
|
31
63
|
*/
|
|
32
|
-
export type SequencerClientConfig =
|
|
64
|
+
export type SequencerClientConfig = SequencerPublisherConfig &
|
|
33
65
|
KeyStoreConfig &
|
|
34
66
|
ValidatorClientConfig &
|
|
35
|
-
|
|
67
|
+
SequencerTxSenderConfig &
|
|
36
68
|
SequencerConfig &
|
|
37
69
|
L1ReaderConfig &
|
|
38
70
|
ChainConfig &
|
|
39
|
-
Pick<P2PConfig, '
|
|
71
|
+
Pick<P2PConfig, 'txPublicSetupAllowListExtend'> &
|
|
40
72
|
Pick<L1ContractsConfig, 'ethereumSlotDuration' | 'aztecSlotDuration' | 'aztecEpochDuration'>;
|
|
41
73
|
|
|
42
74
|
export const sequencerConfigMappings: ConfigMappingsType<SequencerConfig> = {
|
|
43
|
-
|
|
44
|
-
env: '
|
|
45
|
-
description: 'The number of ms to wait between polling for
|
|
46
|
-
...numberConfigHelper(
|
|
47
|
-
},
|
|
48
|
-
|
|
49
|
-
env: '
|
|
50
|
-
description: 'The maximum number of txs
|
|
51
|
-
|
|
75
|
+
sequencerPollingIntervalMS: {
|
|
76
|
+
env: 'SEQ_POLLING_INTERVAL_MS',
|
|
77
|
+
description: 'The number of ms to wait between polling for checking to build on the next slot.',
|
|
78
|
+
...numberConfigHelper(DefaultSequencerConfig.sequencerPollingIntervalMS),
|
|
79
|
+
},
|
|
80
|
+
maxTxsPerCheckpoint: {
|
|
81
|
+
env: 'SEQ_MAX_TX_PER_CHECKPOINT',
|
|
82
|
+
description: 'The maximum number of txs across all blocks in a checkpoint.',
|
|
83
|
+
parseEnv: (val: string) => (val ? parseInt(val, 10) : undefined),
|
|
52
84
|
},
|
|
53
85
|
minTxsPerBlock: {
|
|
54
86
|
env: 'SEQ_MIN_TX_PER_BLOCK',
|
|
55
87
|
description: 'The minimum number of txs to include in a block.',
|
|
56
|
-
...numberConfigHelper(
|
|
88
|
+
...numberConfigHelper(DefaultSequencerConfig.minTxsPerBlock),
|
|
89
|
+
},
|
|
90
|
+
minValidTxsPerBlock: {
|
|
91
|
+
description:
|
|
92
|
+
'The minimum number of valid txs (after execution) to include in a block. If not set, falls back to minTxsPerBlock.',
|
|
57
93
|
},
|
|
58
94
|
publishTxsWithProposals: {
|
|
59
95
|
env: 'SEQ_PUBLISH_TXS_WITH_PROPOSALS',
|
|
60
96
|
description: 'Whether to publish txs with proposals.',
|
|
61
|
-
...booleanConfigHelper(
|
|
97
|
+
...booleanConfigHelper(DefaultSequencerConfig.publishTxsWithProposals),
|
|
62
98
|
},
|
|
63
99
|
maxL2BlockGas: {
|
|
64
100
|
env: 'SEQ_MAX_L2_BLOCK_GAS',
|
|
65
101
|
description: 'The maximum L2 block gas.',
|
|
66
|
-
|
|
102
|
+
parseEnv: (val: string) => (val ? parseInt(val, 10) : undefined),
|
|
67
103
|
},
|
|
68
104
|
maxDABlockGas: {
|
|
69
105
|
env: 'SEQ_MAX_DA_BLOCK_GAS',
|
|
70
106
|
description: 'The maximum DA block gas.',
|
|
71
|
-
|
|
107
|
+
parseEnv: (val: string) => (val ? parseInt(val, 10) : undefined),
|
|
108
|
+
},
|
|
109
|
+
perBlockAllocationMultiplier: {
|
|
110
|
+
env: 'SEQ_PER_BLOCK_ALLOCATION_MULTIPLIER',
|
|
111
|
+
description:
|
|
112
|
+
'Per-block gas budget multiplier for both L2 and DA gas. Budget per block is (checkpointLimit / maxBlocks) * multiplier.' +
|
|
113
|
+
' Values greater than one allow early blocks to use more than their even share, relying on checkpoint-level capping for later blocks.',
|
|
114
|
+
...numberConfigHelper(DefaultSequencerConfig.perBlockAllocationMultiplier),
|
|
115
|
+
},
|
|
116
|
+
redistributeCheckpointBudget: {
|
|
117
|
+
env: 'SEQ_REDISTRIBUTE_CHECKPOINT_BUDGET',
|
|
118
|
+
description:
|
|
119
|
+
'Redistribute remaining checkpoint budget evenly across remaining blocks instead of allowing a single block to consume the entire remaining budget.',
|
|
120
|
+
...booleanConfigHelper(DefaultSequencerConfig.redistributeCheckpointBudget),
|
|
121
|
+
},
|
|
122
|
+
maxBlocksPerCheckpoint: {
|
|
123
|
+
description: 'Computed max number of blocks per checkpoint from timetable.',
|
|
72
124
|
},
|
|
73
125
|
coinbase: {
|
|
74
126
|
env: 'COINBASE',
|
|
@@ -88,78 +140,100 @@ export const sequencerConfigMappings: ConfigMappingsType<SequencerConfig> = {
|
|
|
88
140
|
env: 'ACVM_BINARY_PATH',
|
|
89
141
|
description: 'The path to the ACVM binary',
|
|
90
142
|
},
|
|
91
|
-
maxBlockSizeInBytes: {
|
|
92
|
-
env: 'SEQ_MAX_BLOCK_SIZE_IN_BYTES',
|
|
93
|
-
description: 'Max block size',
|
|
94
|
-
...numberConfigHelper(1024 * 1024),
|
|
95
|
-
},
|
|
96
143
|
enforceTimeTable: {
|
|
97
144
|
env: 'SEQ_ENFORCE_TIME_TABLE',
|
|
98
145
|
description: 'Whether to enforce the time table when building blocks',
|
|
99
|
-
...booleanConfigHelper(),
|
|
100
|
-
defaultValue: true,
|
|
146
|
+
...booleanConfigHelper(DefaultSequencerConfig.enforceTimeTable),
|
|
101
147
|
},
|
|
102
148
|
governanceProposerPayload: {
|
|
103
149
|
env: 'GOVERNANCE_PROPOSER_PAYLOAD_ADDRESS',
|
|
104
150
|
description: 'The address of the payload for the governanceProposer',
|
|
105
151
|
parseEnv: (val: string) => EthAddress.fromString(val),
|
|
106
|
-
defaultValue: EthAddress.ZERO,
|
|
107
152
|
},
|
|
108
|
-
|
|
109
|
-
env: '
|
|
110
|
-
description: 'How
|
|
153
|
+
l1PublishingTime: {
|
|
154
|
+
env: 'SEQ_L1_PUBLISHING_TIME_ALLOWANCE_IN_SLOT',
|
|
155
|
+
description: 'How much time (in seconds) we allow in the slot for publishing the L1 tx (defaults to 1 L1 slot).',
|
|
111
156
|
parseEnv: (val: string) => (val ? parseInt(val, 10) : undefined),
|
|
112
157
|
},
|
|
113
158
|
attestationPropagationTime: {
|
|
114
159
|
env: 'SEQ_ATTESTATION_PROPAGATION_TIME',
|
|
115
160
|
description: 'How many seconds it takes for proposals and attestations to travel across the p2p layer (one-way)',
|
|
116
|
-
...numberConfigHelper(
|
|
161
|
+
...numberConfigHelper(DefaultSequencerConfig.attestationPropagationTime),
|
|
117
162
|
},
|
|
118
163
|
fakeProcessingDelayPerTxMs: {
|
|
119
164
|
description: 'Used for testing to introduce a fake delay after processing each tx',
|
|
120
165
|
},
|
|
166
|
+
fakeThrowAfterProcessingTxCount: {
|
|
167
|
+
description: 'Used for testing to throw an error after processing N txs',
|
|
168
|
+
},
|
|
121
169
|
secondsBeforeInvalidatingBlockAsCommitteeMember: {
|
|
122
170
|
env: 'SEQ_SECONDS_BEFORE_INVALIDATING_BLOCK_AS_COMMITTEE_MEMBER',
|
|
123
171
|
description:
|
|
124
172
|
'How many seconds to wait before trying to invalidate a block from the pending chain as a committee member (zero to never invalidate).' +
|
|
125
173
|
' The next proposer is expected to invalidate, so the committee acts as a fallback.',
|
|
126
|
-
...numberConfigHelper(
|
|
174
|
+
...numberConfigHelper(DefaultSequencerConfig.secondsBeforeInvalidatingBlockAsCommitteeMember),
|
|
127
175
|
},
|
|
128
176
|
secondsBeforeInvalidatingBlockAsNonCommitteeMember: {
|
|
129
177
|
env: 'SEQ_SECONDS_BEFORE_INVALIDATING_BLOCK_AS_NON_COMMITTEE_MEMBER',
|
|
130
178
|
description:
|
|
131
179
|
'How many seconds to wait before trying to invalidate a block from the pending chain as a non-committee member (zero to never invalidate).' +
|
|
132
180
|
' The next proposer is expected to invalidate, then the committee, so other sequencers act as a fallback.',
|
|
133
|
-
...numberConfigHelper(
|
|
181
|
+
...numberConfigHelper(DefaultSequencerConfig.secondsBeforeInvalidatingBlockAsNonCommitteeMember),
|
|
134
182
|
},
|
|
135
183
|
skipCollectingAttestations: {
|
|
136
184
|
description:
|
|
137
185
|
'Whether to skip collecting attestations from validators and only use self-attestations (for testing only)',
|
|
138
|
-
...booleanConfigHelper(
|
|
186
|
+
...booleanConfigHelper(DefaultSequencerConfig.skipCollectingAttestations),
|
|
139
187
|
},
|
|
140
188
|
skipInvalidateBlockAsProposer: {
|
|
141
189
|
description: 'Do not invalidate the previous block if invalid when we are the proposer (for testing only)',
|
|
142
|
-
...booleanConfigHelper(
|
|
190
|
+
...booleanConfigHelper(DefaultSequencerConfig.skipInvalidateBlockAsProposer),
|
|
143
191
|
},
|
|
144
192
|
broadcastInvalidBlockProposal: {
|
|
145
193
|
description: 'Broadcast invalid block proposals with corrupted state (for testing only)',
|
|
146
|
-
...booleanConfigHelper(
|
|
194
|
+
...booleanConfigHelper(DefaultSequencerConfig.broadcastInvalidBlockProposal),
|
|
147
195
|
},
|
|
148
196
|
injectFakeAttestation: {
|
|
149
197
|
description: 'Inject a fake attestation (for testing only)',
|
|
150
|
-
...booleanConfigHelper(
|
|
198
|
+
...booleanConfigHelper(DefaultSequencerConfig.injectFakeAttestation),
|
|
199
|
+
},
|
|
200
|
+
injectHighSValueAttestation: {
|
|
201
|
+
description: 'Inject a malleable attestation with a high-s value (for testing only)',
|
|
202
|
+
...booleanConfigHelper(DefaultSequencerConfig.injectHighSValueAttestation),
|
|
203
|
+
},
|
|
204
|
+
injectUnrecoverableSignatureAttestation: {
|
|
205
|
+
description: 'Inject an attestation with an unrecoverable signature (for testing only)',
|
|
206
|
+
...booleanConfigHelper(DefaultSequencerConfig.injectUnrecoverableSignatureAttestation),
|
|
151
207
|
},
|
|
152
208
|
fishermanMode: {
|
|
153
209
|
env: 'FISHERMAN_MODE',
|
|
154
210
|
description:
|
|
155
211
|
'Whether to run in fisherman mode: builds blocks on every slot for validation without publishing to L1',
|
|
156
|
-
...booleanConfigHelper(
|
|
212
|
+
...booleanConfigHelper(DefaultSequencerConfig.fishermanMode),
|
|
157
213
|
},
|
|
158
214
|
shuffleAttestationOrdering: {
|
|
159
215
|
description: 'Shuffle attestation ordering to create invalid ordering (for testing only)',
|
|
160
|
-
...booleanConfigHelper(
|
|
216
|
+
...booleanConfigHelper(DefaultSequencerConfig.shuffleAttestationOrdering),
|
|
217
|
+
},
|
|
218
|
+
...sharedSequencerConfigMappings,
|
|
219
|
+
buildCheckpointIfEmpty: {
|
|
220
|
+
env: 'SEQ_BUILD_CHECKPOINT_IF_EMPTY',
|
|
221
|
+
description: 'Have sequencer build and publish an empty checkpoint if there are no txs',
|
|
222
|
+
...booleanConfigHelper(DefaultSequencerConfig.buildCheckpointIfEmpty),
|
|
223
|
+
},
|
|
224
|
+
skipPushProposedBlocksToArchiver: {
|
|
225
|
+
description: 'Skip pushing proposed blocks to archiver (default: true)',
|
|
226
|
+
...booleanConfigHelper(DefaultSequencerConfig.skipPushProposedBlocksToArchiver),
|
|
227
|
+
},
|
|
228
|
+
minBlocksForCheckpoint: {
|
|
229
|
+
description: 'Minimum number of blocks required for a checkpoint proposal (test only)',
|
|
230
|
+
},
|
|
231
|
+
skipPublishingCheckpointsPercent: {
|
|
232
|
+
env: 'SEQ_SKIP_CHECKPOINT_PUBLISH_PERCENT',
|
|
233
|
+
description: 'Percent probability (0 - 100) of sequencer skipping checkpoint publishing (testing only)',
|
|
234
|
+
...numberConfigHelper(DefaultSequencerConfig.skipPublishingCheckpointsPercent),
|
|
161
235
|
},
|
|
162
|
-
...pickConfigMappings(p2pConfigMappings, ['
|
|
236
|
+
...pickConfigMappings(p2pConfigMappings, ['txPublicSetupAllowListExtend']),
|
|
163
237
|
};
|
|
164
238
|
|
|
165
239
|
export const sequencerClientConfigMappings: ConfigMappingsType<SequencerClientConfig> = {
|
|
@@ -167,8 +241,8 @@ export const sequencerClientConfigMappings: ConfigMappingsType<SequencerClientCo
|
|
|
167
241
|
...sequencerConfigMappings,
|
|
168
242
|
...keyStoreConfigMappings,
|
|
169
243
|
...l1ReaderConfigMappings,
|
|
170
|
-
...
|
|
171
|
-
...
|
|
244
|
+
...sequencerTxSenderConfigMappings,
|
|
245
|
+
...sequencerPublisherConfigMappings,
|
|
172
246
|
...chainConfigMappings,
|
|
173
247
|
...pickConfigMappings(l1ContractsConfigMappings, ['ethereumSlotDuration', 'aztecSlotDuration', 'aztecEpochDuration']),
|
|
174
248
|
};
|