@aztec/sequencer-client 0.0.1-commit.ef17749e1 → 0.0.1-commit.f1b29a41e
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 +4 -12
- package/dest/client/sequencer-client.d.ts.map +1 -1
- package/dest/client/sequencer-client.js +27 -76
- package/dest/config.d.ts +4 -3
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +9 -2
- package/dest/global_variable_builder/global_builder.d.ts +15 -9
- package/dest/global_variable_builder/global_builder.d.ts.map +1 -1
- package/dest/global_variable_builder/global_builder.js +29 -25
- package/dest/global_variable_builder/index.d.ts +2 -2
- package/dest/global_variable_builder/index.d.ts.map +1 -1
- package/dest/publisher/config.d.ts +13 -1
- package/dest/publisher/config.d.ts.map +1 -1
- package/dest/publisher/config.js +17 -2
- package/dest/publisher/sequencer-publisher-factory.d.ts +3 -3
- package/dest/publisher/sequencer-publisher-factory.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher-factory.js +2 -2
- package/dest/publisher/sequencer-publisher.d.ts +52 -25
- package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher.js +98 -42
- package/dest/sequencer/checkpoint_proposal_job.d.ts +33 -6
- package/dest/sequencer/checkpoint_proposal_job.d.ts.map +1 -1
- package/dest/sequencer/checkpoint_proposal_job.js +261 -141
- package/dest/sequencer/checkpoint_voter.d.ts +1 -2
- package/dest/sequencer/checkpoint_voter.d.ts.map +1 -1
- package/dest/sequencer/checkpoint_voter.js +2 -5
- package/dest/sequencer/events.d.ts +2 -1
- package/dest/sequencer/events.d.ts.map +1 -1
- package/dest/sequencer/metrics.d.ts +5 -1
- package/dest/sequencer/metrics.d.ts.map +1 -1
- package/dest/sequencer/metrics.js +11 -0
- package/dest/sequencer/sequencer.d.ts +19 -7
- package/dest/sequencer/sequencer.d.ts.map +1 -1
- package/dest/sequencer/sequencer.js +123 -68
- package/dest/sequencer/types.d.ts +2 -5
- package/dest/sequencer/types.d.ts.map +1 -1
- package/dest/test/mock_checkpoint_builder.d.ts +4 -4
- package/dest/test/mock_checkpoint_builder.d.ts.map +1 -1
- package/package.json +27 -28
- package/src/client/sequencer-client.ts +37 -101
- package/src/config.ts +12 -1
- package/src/global_variable_builder/global_builder.ts +37 -26
- package/src/global_variable_builder/index.ts +1 -1
- package/src/publisher/config.ts +32 -0
- package/src/publisher/sequencer-publisher-factory.ts +3 -3
- package/src/publisher/sequencer-publisher.ts +144 -54
- package/src/sequencer/checkpoint_proposal_job.ts +340 -147
- package/src/sequencer/checkpoint_voter.ts +1 -12
- package/src/sequencer/events.ts +1 -1
- package/src/sequencer/metrics.ts +14 -0
- package/src/sequencer/sequencer.ts +178 -79
- package/src/sequencer/types.ts +2 -5
- package/src/test/mock_checkpoint_builder.ts +3 -3
|
@@ -19,15 +19,10 @@ import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
|
|
|
19
19
|
import { L1Metrics, type TelemetryClient } from '@aztec/telemetry-client';
|
|
20
20
|
import { FullNodeCheckpointsBuilder, NodeKeystoreAdapter, type ValidatorClient } from '@aztec/validator-client';
|
|
21
21
|
|
|
22
|
-
import {
|
|
23
|
-
|
|
24
|
-
type SequencerClientConfig,
|
|
25
|
-
getPublisherConfigFromSequencerConfig,
|
|
26
|
-
} from '../config.js';
|
|
27
|
-
import { GlobalVariableBuilder } from '../global_variable_builder/index.js';
|
|
22
|
+
import { type SequencerClientConfig, getPublisherConfigFromSequencerConfig } from '../config.js';
|
|
23
|
+
import type { GlobalVariableBuilder } from '../global_variable_builder/index.js';
|
|
28
24
|
import { SequencerPublisherFactory } from '../publisher/sequencer-publisher-factory.js';
|
|
29
25
|
import { Sequencer, type SequencerConfig } from '../sequencer/index.js';
|
|
30
|
-
import { SequencerTimetable } from '../sequencer/timetable.js';
|
|
31
26
|
|
|
32
27
|
/**
|
|
33
28
|
* Encapsulates the full sequencer and publisher.
|
|
@@ -70,7 +65,9 @@ export class SequencerClient {
|
|
|
70
65
|
dateProvider: DateProvider;
|
|
71
66
|
epochCache?: EpochCache;
|
|
72
67
|
l1TxUtils: L1TxUtils[];
|
|
68
|
+
funderL1TxUtils?: L1TxUtils;
|
|
73
69
|
nodeKeyStore: KeystoreManager;
|
|
70
|
+
globalVariableBuilder: GlobalVariableBuilder;
|
|
74
71
|
},
|
|
75
72
|
) {
|
|
76
73
|
const {
|
|
@@ -92,16 +89,14 @@ export class SequencerClient {
|
|
|
92
89
|
publicClient,
|
|
93
90
|
l1TxUtils.map(x => x.getSenderAddress()),
|
|
94
91
|
);
|
|
95
|
-
const publisherManager = new PublisherManager(
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
);
|
|
92
|
+
const publisherManager = new PublisherManager(l1TxUtils, getPublisherConfigFromSequencerConfig(config), {
|
|
93
|
+
bindings: log.getBindings(),
|
|
94
|
+
funder: deps.funderL1TxUtils,
|
|
95
|
+
});
|
|
100
96
|
const rollupContract = new RollupContract(publicClient, config.l1Contracts.rollupAddress.toString());
|
|
101
|
-
const [l1GenesisTime, slotDuration,
|
|
97
|
+
const [l1GenesisTime, slotDuration, rollupManaLimit] = await Promise.all([
|
|
102
98
|
rollupContract.getL1GenesisTime(),
|
|
103
99
|
rollupContract.getSlotDuration(),
|
|
104
|
-
rollupContract.getVersion(),
|
|
105
100
|
rollupContract.getManaLimit().then(Number),
|
|
106
101
|
] as const);
|
|
107
102
|
|
|
@@ -118,6 +113,7 @@ export class SequencerClient {
|
|
|
118
113
|
l1ChainId: chainId,
|
|
119
114
|
viemPollingIntervalMS: config.viemPollingIntervalMS,
|
|
120
115
|
ethereumSlotDuration: config.ethereumSlotDuration,
|
|
116
|
+
enableProposerPipelining: config.enableProposerPipelining,
|
|
121
117
|
},
|
|
122
118
|
{ dateProvider: deps.dateProvider },
|
|
123
119
|
));
|
|
@@ -144,13 +140,7 @@ export class SequencerClient {
|
|
|
144
140
|
|
|
145
141
|
const ethereumSlotDuration = config.ethereumSlotDuration;
|
|
146
142
|
|
|
147
|
-
const globalsBuilder =
|
|
148
|
-
...config,
|
|
149
|
-
l1GenesisTime,
|
|
150
|
-
slotDuration: Number(slotDuration),
|
|
151
|
-
ethereumSlotDuration,
|
|
152
|
-
rollupVersion,
|
|
153
|
-
});
|
|
143
|
+
const globalsBuilder = deps.globalVariableBuilder;
|
|
154
144
|
|
|
155
145
|
// When running in anvil, assume we can post a tx up until one second before the end of an L1 slot.
|
|
156
146
|
// Otherwise, we need the full L1 slot duration for publishing to ensure inclusion.
|
|
@@ -160,12 +150,7 @@ export class SequencerClient {
|
|
|
160
150
|
const l1PublishingTimeBasedOnChain = isAnvilTestChain(config.l1ChainId) ? 1 : ethereumSlotDuration;
|
|
161
151
|
const l1PublishingTime = config.l1PublishingTime ?? l1PublishingTimeBasedOnChain;
|
|
162
152
|
|
|
163
|
-
const { maxL2BlockGas, maxDABlockGas, maxTxsPerBlock } =
|
|
164
|
-
config,
|
|
165
|
-
rollupManaLimit,
|
|
166
|
-
l1PublishingTime,
|
|
167
|
-
log,
|
|
168
|
-
);
|
|
153
|
+
const { maxL2BlockGas, maxDABlockGas, maxTxsPerBlock } = capPerBlockLimits(config, rollupManaLimit, log);
|
|
169
154
|
|
|
170
155
|
const l1Constants = { l1GenesisTime, slotDuration: Number(slotDuration), ethereumSlotDuration, rollupManaLimit };
|
|
171
156
|
|
|
@@ -211,7 +196,7 @@ export class SequencerClient {
|
|
|
211
196
|
await this.validatorClient?.start();
|
|
212
197
|
this.sequencer.start();
|
|
213
198
|
this.l1Metrics?.start();
|
|
214
|
-
await this.publisherManager.
|
|
199
|
+
await this.publisherManager.start();
|
|
215
200
|
}
|
|
216
201
|
|
|
217
202
|
/**
|
|
@@ -220,7 +205,7 @@ export class SequencerClient {
|
|
|
220
205
|
public async stop() {
|
|
221
206
|
await this.sequencer.stop();
|
|
222
207
|
await this.validatorClient?.stop();
|
|
223
|
-
this.publisherManager.
|
|
208
|
+
await this.publisherManager.stop();
|
|
224
209
|
this.l1Metrics?.stop();
|
|
225
210
|
}
|
|
226
211
|
|
|
@@ -248,88 +233,39 @@ export class SequencerClient {
|
|
|
248
233
|
}
|
|
249
234
|
|
|
250
235
|
/**
|
|
251
|
-
*
|
|
252
|
-
*
|
|
253
|
-
* Otherwise, derives it as (checkpointLimit / maxBlocks) * multiplier, capped at the checkpoint limit.
|
|
236
|
+
* Caps operator-provided per-block limits at checkpoint-level limits.
|
|
237
|
+
* Returns undefined for any limit the operator didn't set — the checkpoint builder handles redistribution.
|
|
254
238
|
*/
|
|
255
|
-
|
|
239
|
+
function capPerBlockLimits(
|
|
256
240
|
config: SequencerClientConfig,
|
|
257
241
|
rollupManaLimit: number,
|
|
258
|
-
l1PublishingTime: number,
|
|
259
242
|
log: ReturnType<typeof createLogger>,
|
|
260
|
-
): { maxL2BlockGas: number; maxDABlockGas: number; maxTxsPerBlock: number } {
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
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));
|
|
243
|
+
): { maxL2BlockGas: number | undefined; maxDABlockGas: number | undefined; maxTxsPerBlock: number | undefined } {
|
|
244
|
+
let maxL2BlockGas = config.maxL2BlockGas;
|
|
245
|
+
if (maxL2BlockGas !== undefined && maxL2BlockGas > rollupManaLimit) {
|
|
246
|
+
log.warn(`Provided MAX_L2_BLOCK_GAS ${maxL2BlockGas} exceeds rollup mana limit ${rollupManaLimit} (capping)`);
|
|
247
|
+
maxL2BlockGas = rollupManaLimit;
|
|
285
248
|
}
|
|
286
249
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
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));
|
|
250
|
+
let maxDABlockGas = config.maxDABlockGas;
|
|
251
|
+
if (maxDABlockGas !== undefined && maxDABlockGas > MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT) {
|
|
252
|
+
log.warn(
|
|
253
|
+
`Provided MAX_DA_BLOCK_GAS ${maxDABlockGas} exceeds DA checkpoint limit ${MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT} (capping)`,
|
|
254
|
+
);
|
|
255
|
+
maxDABlockGas = MAX_PROCESSABLE_DA_GAS_PER_CHECKPOINT;
|
|
301
256
|
}
|
|
302
257
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
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),
|
|
258
|
+
let maxTxsPerBlock = config.maxTxsPerBlock;
|
|
259
|
+
if (
|
|
260
|
+
maxTxsPerBlock !== undefined &&
|
|
261
|
+
config.maxTxsPerCheckpoint !== undefined &&
|
|
262
|
+
maxTxsPerBlock > config.maxTxsPerCheckpoint
|
|
263
|
+
) {
|
|
264
|
+
log.warn(
|
|
265
|
+
`Provided MAX_TX_PER_BLOCK ${maxTxsPerBlock} exceeds MAX_TX_PER_CHECKPOINT ${config.maxTxsPerCheckpoint} (capping)`,
|
|
319
266
|
);
|
|
320
|
-
|
|
321
|
-
maxTxsPerBlock = defaultMaxTxsPerBlock;
|
|
267
|
+
maxTxsPerBlock = config.maxTxsPerCheckpoint;
|
|
322
268
|
}
|
|
323
269
|
|
|
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
270
|
return { maxL2BlockGas, maxDABlockGas, maxTxsPerBlock };
|
|
335
271
|
}
|
package/src/config.ts
CHANGED
|
@@ -13,8 +13,10 @@ import { type P2PConfig, p2pConfigMappings } from '@aztec/p2p/config';
|
|
|
13
13
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
14
14
|
import {
|
|
15
15
|
type ChainConfig,
|
|
16
|
+
type PipelineConfig,
|
|
16
17
|
type SequencerConfig,
|
|
17
18
|
chainConfigMappings,
|
|
19
|
+
pipelineConfigMappings,
|
|
18
20
|
sharedSequencerConfigMappings,
|
|
19
21
|
} from '@aztec/stdlib/config';
|
|
20
22
|
import type { ResolvedSequencerConfig } from '@aztec/stdlib/interfaces/server';
|
|
@@ -40,7 +42,8 @@ export const DefaultSequencerConfig = {
|
|
|
40
42
|
minTxsPerBlock: 1,
|
|
41
43
|
buildCheckpointIfEmpty: false,
|
|
42
44
|
publishTxsWithProposals: false,
|
|
43
|
-
perBlockAllocationMultiplier: 2,
|
|
45
|
+
perBlockAllocationMultiplier: 1.2,
|
|
46
|
+
redistributeCheckpointBudget: true,
|
|
44
47
|
enforceTimeTable: true,
|
|
45
48
|
attestationPropagationTime: DEFAULT_P2P_PROPAGATION_TIME,
|
|
46
49
|
secondsBeforeInvalidatingBlockAsCommitteeMember: 144, // 12 L1 blocks
|
|
@@ -67,6 +70,7 @@ export type SequencerClientConfig = SequencerPublisherConfig &
|
|
|
67
70
|
SequencerConfig &
|
|
68
71
|
L1ReaderConfig &
|
|
69
72
|
ChainConfig &
|
|
73
|
+
PipelineConfig &
|
|
70
74
|
Pick<P2PConfig, 'txPublicSetupAllowListExtend'> &
|
|
71
75
|
Pick<L1ContractsConfig, 'ethereumSlotDuration' | 'aztecSlotDuration' | 'aztecEpochDuration'>;
|
|
72
76
|
|
|
@@ -112,6 +116,12 @@ export const sequencerConfigMappings: ConfigMappingsType<SequencerConfig> = {
|
|
|
112
116
|
' Values greater than one allow early blocks to use more than their even share, relying on checkpoint-level capping for later blocks.',
|
|
113
117
|
...numberConfigHelper(DefaultSequencerConfig.perBlockAllocationMultiplier),
|
|
114
118
|
},
|
|
119
|
+
redistributeCheckpointBudget: {
|
|
120
|
+
env: 'SEQ_REDISTRIBUTE_CHECKPOINT_BUDGET',
|
|
121
|
+
description:
|
|
122
|
+
'Redistribute remaining checkpoint budget evenly across remaining blocks instead of allowing a single block to consume the entire remaining budget.',
|
|
123
|
+
...booleanConfigHelper(DefaultSequencerConfig.redistributeCheckpointBudget),
|
|
124
|
+
},
|
|
115
125
|
coinbase: {
|
|
116
126
|
env: 'COINBASE',
|
|
117
127
|
parseEnv: (val: string) => (val ? EthAddress.fromString(val) : undefined),
|
|
@@ -234,6 +244,7 @@ export const sequencerClientConfigMappings: ConfigMappingsType<SequencerClientCo
|
|
|
234
244
|
...sequencerTxSenderConfigMappings,
|
|
235
245
|
...sequencerPublisherConfigMappings,
|
|
236
246
|
...chainConfigMappings,
|
|
247
|
+
...pipelineConfigMappings,
|
|
237
248
|
...pickConfigMappings(l1ContractsConfigMappings, ['ethereumSlotDuration', 'aztecSlotDuration', 'aztecEpochDuration']),
|
|
238
249
|
};
|
|
239
250
|
|
|
@@ -1,22 +1,27 @@
|
|
|
1
|
-
import { createEthereumChain } from '@aztec/ethereum/chain';
|
|
2
|
-
import type { L1ContractsConfig } from '@aztec/ethereum/config';
|
|
3
1
|
import { RollupContract } from '@aztec/ethereum/contracts';
|
|
4
|
-
import type {
|
|
2
|
+
import type { L1ContractAddresses } from '@aztec/ethereum/l1-contract-addresses';
|
|
5
3
|
import type { ViemPublicClient } from '@aztec/ethereum/types';
|
|
6
4
|
import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types';
|
|
7
5
|
import { Fr } from '@aztec/foundation/curves/bn254';
|
|
8
6
|
import type { EthAddress } from '@aztec/foundation/eth-address';
|
|
9
7
|
import { createLogger } from '@aztec/foundation/log';
|
|
8
|
+
import type { DateProvider } from '@aztec/foundation/timer';
|
|
10
9
|
import type { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
11
|
-
import { type L1RollupConstants, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
|
|
10
|
+
import { type L1RollupConstants, getNextL1SlotTimestamp, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
|
|
12
11
|
import { GasFees } from '@aztec/stdlib/gas';
|
|
13
12
|
import type {
|
|
13
|
+
BuildCheckpointGlobalVariablesOpts,
|
|
14
14
|
CheckpointGlobalVariables,
|
|
15
15
|
GlobalVariableBuilder as GlobalVariableBuilderInterface,
|
|
16
16
|
} from '@aztec/stdlib/tx';
|
|
17
17
|
import { GlobalVariables } from '@aztec/stdlib/tx';
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
/** Configuration for the GlobalVariableBuilder (excludes L1 client config). */
|
|
20
|
+
export type GlobalVariableBuilderConfig = {
|
|
21
|
+
l1Contracts: Pick<L1ContractAddresses, 'rollupAddress'>;
|
|
22
|
+
ethereumSlotDuration: number;
|
|
23
|
+
rollupVersion: bigint;
|
|
24
|
+
} & Pick<L1RollupConstants, 'slotDuration' | 'l1GenesisTime'>;
|
|
20
25
|
|
|
21
26
|
/**
|
|
22
27
|
* Simple global variables builder.
|
|
@@ -27,7 +32,6 @@ export class GlobalVariableBuilder implements GlobalVariableBuilderInterface {
|
|
|
27
32
|
private currentL1BlockNumber: bigint | undefined = undefined;
|
|
28
33
|
|
|
29
34
|
private readonly rollupContract: RollupContract;
|
|
30
|
-
private readonly publicClient: ViemPublicClient;
|
|
31
35
|
private readonly ethereumSlotDuration: number;
|
|
32
36
|
private readonly aztecSlotDuration: number;
|
|
33
37
|
private readonly l1GenesisTime: bigint;
|
|
@@ -36,28 +40,18 @@ export class GlobalVariableBuilder implements GlobalVariableBuilderInterface {
|
|
|
36
40
|
private version: Fr;
|
|
37
41
|
|
|
38
42
|
constructor(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
43
|
+
private readonly dateProvider: DateProvider,
|
|
44
|
+
private readonly publicClient: ViemPublicClient,
|
|
45
|
+
config: GlobalVariableBuilderConfig,
|
|
42
46
|
) {
|
|
43
|
-
const { l1RpcUrls, l1ChainId: chainId, l1Contracts } = config;
|
|
44
|
-
|
|
45
|
-
const chain = createEthereumChain(l1RpcUrls, chainId);
|
|
46
|
-
|
|
47
47
|
this.version = new Fr(config.rollupVersion);
|
|
48
|
-
this.chainId = new Fr(
|
|
48
|
+
this.chainId = new Fr(this.publicClient.chain!.id);
|
|
49
49
|
|
|
50
50
|
this.ethereumSlotDuration = config.ethereumSlotDuration;
|
|
51
51
|
this.aztecSlotDuration = config.slotDuration;
|
|
52
52
|
this.l1GenesisTime = config.l1GenesisTime;
|
|
53
53
|
|
|
54
|
-
this.
|
|
55
|
-
chain: chain.chainInfo,
|
|
56
|
-
transport: fallback(chain.rpcUrls.map(url => http(url, { batch: false }))),
|
|
57
|
-
pollingInterval: config.viemPollingIntervalMS,
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
this.rollupContract = new RollupContract(this.publicClient, l1Contracts.rollupAddress);
|
|
54
|
+
this.rollupContract = new RollupContract(this.publicClient, config.l1Contracts.rollupAddress);
|
|
61
55
|
}
|
|
62
56
|
|
|
63
57
|
/**
|
|
@@ -73,7 +67,10 @@ export class GlobalVariableBuilder implements GlobalVariableBuilderInterface {
|
|
|
73
67
|
const earliestTimestamp = await this.rollupContract.getTimestampForSlot(
|
|
74
68
|
SlotNumber.fromBigInt(BigInt(lastCheckpoint.slotNumber) + 1n),
|
|
75
69
|
);
|
|
76
|
-
const nextEthTimestamp =
|
|
70
|
+
const nextEthTimestamp = getNextL1SlotTimestamp(this.dateProvider.nowInSeconds(), {
|
|
71
|
+
l1GenesisTime: this.l1GenesisTime,
|
|
72
|
+
ethereumSlotDuration: this.ethereumSlotDuration,
|
|
73
|
+
});
|
|
77
74
|
const timestamp = earliestTimestamp > nextEthTimestamp ? earliestTimestamp : nextEthTimestamp;
|
|
78
75
|
|
|
79
76
|
return new GasFees(0, await this.rollupContract.getManaMinFeeAt(timestamp, true));
|
|
@@ -108,7 +105,10 @@ export class GlobalVariableBuilder implements GlobalVariableBuilderInterface {
|
|
|
108
105
|
const slot: SlotNumber =
|
|
109
106
|
maybeSlot ??
|
|
110
107
|
(await this.rollupContract.getSlotAt(
|
|
111
|
-
|
|
108
|
+
getNextL1SlotTimestamp(this.dateProvider.nowInSeconds(), {
|
|
109
|
+
l1GenesisTime: this.l1GenesisTime,
|
|
110
|
+
ethereumSlotDuration: this.ethereumSlotDuration,
|
|
111
|
+
}),
|
|
112
112
|
));
|
|
113
113
|
|
|
114
114
|
const checkpointGlobalVariables = await this.buildCheckpointGlobalVariables(coinbase, feeRecipient, slot);
|
|
@@ -120,6 +120,7 @@ export class GlobalVariableBuilder implements GlobalVariableBuilderInterface {
|
|
|
120
120
|
coinbase: EthAddress,
|
|
121
121
|
feeRecipient: AztecAddress,
|
|
122
122
|
slotNumber: SlotNumber,
|
|
123
|
+
opts?: BuildCheckpointGlobalVariablesOpts,
|
|
123
124
|
): Promise<CheckpointGlobalVariables> {
|
|
124
125
|
const { chainId, version } = this;
|
|
125
126
|
|
|
@@ -128,9 +129,19 @@ export class GlobalVariableBuilder implements GlobalVariableBuilderInterface {
|
|
|
128
129
|
l1GenesisTime: this.l1GenesisTime,
|
|
129
130
|
});
|
|
130
131
|
|
|
131
|
-
//
|
|
132
|
-
//
|
|
133
|
-
const
|
|
132
|
+
// When pipelining, force the proposed checkpoint number and fee header to the parent so that
|
|
133
|
+
// the fee computation matches what L1 will see when the previous pipelined checkpoint has landed.
|
|
134
|
+
const pendingNumberOverride = await this.rollupContract.makePendingCheckpointNumberOverride(
|
|
135
|
+
opts?.forcePendingCheckpointNumber,
|
|
136
|
+
);
|
|
137
|
+
const feeHeaderOverride = opts?.forceProposedFeeHeader
|
|
138
|
+
? await this.rollupContract.makeFeeHeaderOverride(
|
|
139
|
+
opts.forceProposedFeeHeader.checkpointNumber,
|
|
140
|
+
opts.forceProposedFeeHeader.feeHeader,
|
|
141
|
+
)
|
|
142
|
+
: [];
|
|
143
|
+
const stateOverride = RollupContract.mergeStateOverrides(pendingNumberOverride, feeHeaderOverride);
|
|
144
|
+
const gasFees = new GasFees(0, await this.rollupContract.getManaMinFeeAt(timestamp, true, stateOverride));
|
|
134
145
|
|
|
135
146
|
return { chainId, version, slotNumber, timestamp, coinbase, feeRecipient, gasFees };
|
|
136
147
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { GlobalVariableBuilder } from './global_builder.js';
|
|
1
|
+
export { GlobalVariableBuilder, type GlobalVariableBuilderConfig } from './global_builder.js';
|
package/src/publisher/config.ts
CHANGED
|
@@ -4,6 +4,8 @@ import { type L1TxUtilsConfig, l1TxUtilsConfigMappings } from '@aztec/ethereum/l
|
|
|
4
4
|
import { type ConfigMappingsType, SecretValue, booleanConfigHelper } from '@aztec/foundation/config';
|
|
5
5
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
6
6
|
|
|
7
|
+
import { parseEther } from 'viem';
|
|
8
|
+
|
|
7
9
|
/** Configuration of the transaction publisher. */
|
|
8
10
|
export type TxSenderConfig = L1ReaderConfig & {
|
|
9
11
|
/** The private key to be used by the publisher. */
|
|
@@ -50,13 +52,37 @@ export type PublisherConfig = L1TxUtilsConfig &
|
|
|
50
52
|
publisherForwarderAddress?: EthAddress;
|
|
51
53
|
/** Store for failed L1 transaction inputs (test networks only). Format: gs://bucket/path */
|
|
52
54
|
l1TxFailedStore?: string;
|
|
55
|
+
/** Min ETH balance below which a publisher gets funded. Undefined = funding disabled. */
|
|
56
|
+
publisherFundingThreshold?: bigint;
|
|
57
|
+
/** Amount of ETH to send when funding a publisher. Undefined = funding disabled. */
|
|
58
|
+
publisherFundingAmount?: bigint;
|
|
53
59
|
};
|
|
54
60
|
|
|
61
|
+
/** Shared config mappings for publisher funding, used by both sequencer and prover publisher configs. */
|
|
62
|
+
const publisherFundingConfigMappings = {
|
|
63
|
+
publisherFundingThreshold: {
|
|
64
|
+
env: 'PUBLISHER_FUNDING_THRESHOLD' as const,
|
|
65
|
+
description:
|
|
66
|
+
'Min ETH balance below which a publisher gets funded. Specified in ether (e.g. 0.1). Unset = funding disabled.',
|
|
67
|
+
parseEnv: (val: string) => parseEther(val),
|
|
68
|
+
},
|
|
69
|
+
publisherFundingAmount: {
|
|
70
|
+
env: 'PUBLISHER_FUNDING_AMOUNT' as const,
|
|
71
|
+
description:
|
|
72
|
+
'Amount of ETH to send when funding a publisher. Specified in ether (e.g. 0.5). Unset = funding disabled.',
|
|
73
|
+
parseEnv: (val: string) => parseEther(val),
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
|
|
55
77
|
export type ProverPublisherConfig = L1TxUtilsConfig &
|
|
56
78
|
BlobClientConfig & {
|
|
57
79
|
fishermanMode?: boolean;
|
|
58
80
|
proverPublisherAllowInvalidStates?: boolean;
|
|
59
81
|
proverPublisherForwarderAddress?: EthAddress;
|
|
82
|
+
/** Min ETH balance below which a publisher gets funded. Undefined = funding disabled. */
|
|
83
|
+
publisherFundingThreshold?: bigint;
|
|
84
|
+
/** Amount of ETH to send when funding a publisher. Undefined = funding disabled. */
|
|
85
|
+
publisherFundingAmount?: bigint;
|
|
60
86
|
};
|
|
61
87
|
|
|
62
88
|
export type SequencerPublisherConfig = L1TxUtilsConfig &
|
|
@@ -66,6 +92,10 @@ export type SequencerPublisherConfig = L1TxUtilsConfig &
|
|
|
66
92
|
sequencerPublisherForwarderAddress?: EthAddress;
|
|
67
93
|
/** Store for failed L1 transaction inputs (test networks only). Format: gs://bucket/path */
|
|
68
94
|
l1TxFailedStore?: string;
|
|
95
|
+
/** Min ETH balance below which a publisher gets funded. Undefined = funding disabled. */
|
|
96
|
+
publisherFundingThreshold?: bigint;
|
|
97
|
+
/** Amount of ETH to send when funding a publisher. Undefined = funding disabled. */
|
|
98
|
+
publisherFundingAmount?: bigint;
|
|
69
99
|
};
|
|
70
100
|
|
|
71
101
|
export function getPublisherConfigFromProverConfig(config: ProverPublisherConfig): PublisherConfig {
|
|
@@ -142,6 +172,7 @@ export const sequencerPublisherConfigMappings: ConfigMappingsType<SequencerPubli
|
|
|
142
172
|
env: 'L1_TX_FAILED_STORE',
|
|
143
173
|
description: 'Store for failed L1 transaction inputs (test networks only). Format: gs://bucket/path',
|
|
144
174
|
},
|
|
175
|
+
...publisherFundingConfigMappings,
|
|
145
176
|
};
|
|
146
177
|
|
|
147
178
|
export const proverPublisherConfigMappings: ConfigMappingsType<ProverPublisherConfig & L1TxUtilsConfig> = {
|
|
@@ -163,4 +194,5 @@ export const proverPublisherConfigMappings: ConfigMappingsType<ProverPublisherCo
|
|
|
163
194
|
description: 'Address of the forwarder contract to wrap all L1 transactions through (for testing purposes only)',
|
|
164
195
|
parseEnv: (val: string) => (val ? EthAddress.fromString(val) : undefined),
|
|
165
196
|
},
|
|
197
|
+
...publisherFundingConfigMappings,
|
|
166
198
|
};
|
|
@@ -117,8 +117,8 @@ export class SequencerPublisherFactory {
|
|
|
117
117
|
};
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
/**
|
|
121
|
-
public
|
|
122
|
-
this.deps.publisherManager.
|
|
120
|
+
/** Stops all publishers managed by this factory. Used during sequencer shutdown. */
|
|
121
|
+
public async stopAll(): Promise<void> {
|
|
122
|
+
await this.deps.publisherManager.stop();
|
|
123
123
|
}
|
|
124
124
|
}
|