@aztec/sequencer-client 2.0.3-rc.9 → 2.1.0-rc.1
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.map +1 -1
- package/dest/client/sequencer-client.js +5 -4
- package/dest/config.d.ts +2 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +2 -0
- package/dest/publisher/config.d.ts +5 -3
- package/dest/publisher/config.d.ts.map +1 -1
- package/dest/publisher/config.js +13 -5
- package/dest/publisher/index.d.ts +1 -1
- package/dest/publisher/index.d.ts.map +1 -1
- package/dest/publisher/index.js +1 -1
- package/dest/publisher/sequencer-publisher-factory.d.ts +5 -1
- package/dest/publisher/sequencer-publisher-factory.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher-factory.js +8 -1
- package/dest/publisher/sequencer-publisher.d.ts +13 -15
- package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
- package/dest/publisher/sequencer-publisher.js +58 -55
- package/dest/sequencer/metrics.d.ts +5 -17
- package/dest/sequencer/metrics.d.ts.map +1 -1
- package/dest/sequencer/metrics.js +22 -88
- package/dest/sequencer/sequencer.d.ts +4 -3
- package/dest/sequencer/sequencer.d.ts.map +1 -1
- package/dest/sequencer/sequencer.js +16 -17
- package/package.json +28 -28
- package/src/client/sequencer-client.ts +4 -2
- package/src/config.ts +3 -0
- package/src/publisher/config.ts +23 -5
- package/src/publisher/index.ts +1 -1
- package/src/publisher/sequencer-publisher-factory.ts +12 -2
- package/src/publisher/sequencer-publisher.ts +77 -69
- package/src/sequencer/metrics.ts +24 -100
- package/src/sequencer/sequencer.ts +42 -38
|
@@ -4,14 +4,16 @@ function _ts_decorate(decorators, target, key, desc) {
|
|
|
4
4
|
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
}
|
|
7
|
-
import { INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
|
|
7
|
+
import { BLOBS_PER_BLOCK, FIELDS_PER_BLOB, INITIAL_L2_BLOCK_NUM } from '@aztec/constants';
|
|
8
8
|
import { FormattedViemError, NoCommitteeError } from '@aztec/ethereum';
|
|
9
9
|
import { omit, pick } from '@aztec/foundation/collection';
|
|
10
10
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
11
|
+
import { Signature } from '@aztec/foundation/eth-signature';
|
|
11
12
|
import { Fr } from '@aztec/foundation/fields';
|
|
12
13
|
import { createLogger } from '@aztec/foundation/log';
|
|
13
14
|
import { RunningPromise } from '@aztec/foundation/running-promise';
|
|
14
15
|
import { Timer } from '@aztec/foundation/timer';
|
|
16
|
+
import { CommitteeAttestationsAndSigners } from '@aztec/stdlib/block';
|
|
15
17
|
import { getSlotAtTimestamp } from '@aztec/stdlib/epoch-helpers';
|
|
16
18
|
import { Gas } from '@aztec/stdlib/gas';
|
|
17
19
|
import { SequencerConfigSchema } from '@aztec/stdlib/interfaces/server';
|
|
@@ -72,10 +74,7 @@ export { SequencerState };
|
|
|
72
74
|
publisher;
|
|
73
75
|
constructor(publisherFactory, validatorClient, globalsBuilder, p2pClient, worldState, slasherClient, l2BlockSource, l1ToL2MessageSource, blockBuilder, l1Constants, dateProvider, epochCache, rollupContract, config, telemetry = getTelemetryClient(), log = createLogger('sequencer')){
|
|
74
76
|
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.blockBuilder = blockBuilder, this.l1Constants = l1Constants, this.dateProvider = dateProvider, this.epochCache = epochCache, this.rollupContract = rollupContract, this.config = config, this.telemetry = telemetry, this.log = log, this.pollingIntervalMs = 1000, this.maxTxsPerBlock = 32, this.minTxsPerBlock = 1, this.maxL1TxInclusionTimeIntoSlot = 0, this.state = SequencerState.STOPPED, this.maxBlockSizeInBytes = 1024 * 1024, this.maxBlockGas = new Gas(100e9, 100e9), this.enforceTimeTable = false;
|
|
75
|
-
|
|
76
|
-
const validatorAddresses = this.validatorClient?.getValidatorAddresses() ?? [];
|
|
77
|
-
const coinbase = validatorAddresses.length === 0 ? EthAddress.ZERO : this.validatorClient?.getCoinbaseForAttestor(validatorAddresses[0]) ?? EthAddress.ZERO;
|
|
78
|
-
this.metrics = new SequencerMetrics(telemetry, ()=>this.state, coinbase, this.rollupContract, 'Sequencer');
|
|
77
|
+
this.metrics = new SequencerMetrics(telemetry, this.rollupContract, 'Sequencer');
|
|
79
78
|
// Initialize config
|
|
80
79
|
this.updateConfig(this.config);
|
|
81
80
|
}
|
|
@@ -140,7 +139,6 @@ export { SequencerState };
|
|
|
140
139
|
/**
|
|
141
140
|
* Starts the sequencer and moves to IDLE state.
|
|
142
141
|
*/ start() {
|
|
143
|
-
this.metrics.start();
|
|
144
142
|
this.runningPromise = new RunningPromise(this.work.bind(this), this.log, this.pollingIntervalMs);
|
|
145
143
|
this.setState(SequencerState.IDLE, undefined, {
|
|
146
144
|
force: true
|
|
@@ -152,7 +150,6 @@ export { SequencerState };
|
|
|
152
150
|
* Stops the sequencer from processing txs and moves to STOPPED state.
|
|
153
151
|
*/ async stop() {
|
|
154
152
|
this.log.info(`Stopping sequencer`);
|
|
155
|
-
this.metrics.stop();
|
|
156
153
|
this.publisher?.interrupt();
|
|
157
154
|
await this.validatorClient?.stop();
|
|
158
155
|
await this.runningPromise?.stop();
|
|
@@ -259,7 +256,6 @@ export { SequencerState };
|
|
|
259
256
|
this.publisher = publisher;
|
|
260
257
|
const coinbase = this.validatorClient.getCoinbaseForAttestor(attestorAddress);
|
|
261
258
|
const feeRecipient = this.validatorClient.getFeeRecipientForAttestor(attestorAddress);
|
|
262
|
-
this.metrics.setCoinbase(coinbase);
|
|
263
259
|
// Prepare invalidation request if the pending chain is invalid (returns undefined if no need)
|
|
264
260
|
const invalidateBlock = await publisher.simulateInvalidateBlock(syncedTo.pendingChainValidationStatus);
|
|
265
261
|
const canProposeCheck = await publisher.canProposeAtNextEthBlock(chainTipArchive, proposerAddressInNextSlot, invalidateBlock);
|
|
@@ -317,6 +313,7 @@ export { SequencerState };
|
|
|
317
313
|
publisher.enqueueInvalidateBlock(invalidateBlock);
|
|
318
314
|
}
|
|
319
315
|
this.setState(SequencerState.INITIALIZING_PROPOSAL, slot);
|
|
316
|
+
this.metrics.incOpenSlot(slot, proposerAddressInNextSlot.toString());
|
|
320
317
|
this.log.verbose(`Preparing proposal for block ${newBlockNumber} at slot ${slot}`, {
|
|
321
318
|
proposer: proposerInNextSlot?.toString(),
|
|
322
319
|
coinbase,
|
|
@@ -379,7 +376,7 @@ export { SequencerState };
|
|
|
379
376
|
blockNumber: newBlockNumber,
|
|
380
377
|
slot: Number(slot)
|
|
381
378
|
});
|
|
382
|
-
this.metrics.incFilledSlot(publisher.getSenderAddress().toString());
|
|
379
|
+
await this.metrics.incFilledSlot(publisher.getSenderAddress().toString(), coinbase);
|
|
383
380
|
} else if (block) {
|
|
384
381
|
this.emit('block-publish-failed', l1Response ?? {});
|
|
385
382
|
}
|
|
@@ -452,6 +449,7 @@ export { SequencerState };
|
|
|
452
449
|
maxTransactions: this.maxTxsPerBlock,
|
|
453
450
|
maxBlockSize: this.maxBlockSizeInBytes,
|
|
454
451
|
maxBlockGas: this.maxBlockGas,
|
|
452
|
+
maxBlobFields: BLOBS_PER_BLOCK * FIELDS_PER_BLOB,
|
|
455
453
|
deadline
|
|
456
454
|
};
|
|
457
455
|
}
|
|
@@ -470,7 +468,6 @@ export { SequencerState };
|
|
|
470
468
|
const blockNumber = newGlobalVariables.blockNumber;
|
|
471
469
|
const slot = proposalHeader.slotNumber.toBigInt();
|
|
472
470
|
const l1ToL2Messages = await this.l1ToL2MessageSource.getL1ToL2Messages(blockNumber);
|
|
473
|
-
// this.metrics.recordNewBlock(blockNumber, validTxs.length);
|
|
474
471
|
const workTimer = new Timer();
|
|
475
472
|
this.setState(SequencerState.CREATING_BLOCK, slot);
|
|
476
473
|
try {
|
|
@@ -515,7 +512,9 @@ export { SequencerState };
|
|
|
515
512
|
blockNumber
|
|
516
513
|
});
|
|
517
514
|
}
|
|
518
|
-
|
|
515
|
+
const attestationsAndSigners = new CommitteeAttestationsAndSigners(attestations ?? []);
|
|
516
|
+
const attestationsAndSignersSignature = this.validatorClient ? await this.validatorClient.signAttestationsAndSigners(attestationsAndSigners, proposerAddress) : Signature.empty();
|
|
517
|
+
await this.enqueuePublishL2Block(block, attestationsAndSigners, attestationsAndSignersSignature, invalidateBlock, publisher);
|
|
519
518
|
this.metrics.recordBuiltBlock(blockBuildDuration, publicGas.l2Gas);
|
|
520
519
|
return block;
|
|
521
520
|
} catch (err) {
|
|
@@ -561,32 +560,32 @@ export { SequencerState };
|
|
|
561
560
|
const attestationTimeAllowed = this.enforceTimeTable ? this.timetable.getMaxAllowedTime(SequencerState.PUBLISHING_BLOCK) : this.aztecSlotDuration;
|
|
562
561
|
this.metrics.recordRequiredAttestations(numberOfRequiredAttestations, attestationTimeAllowed);
|
|
563
562
|
const timer = new Timer();
|
|
564
|
-
let
|
|
563
|
+
let collectedAttestationsCount = 0;
|
|
565
564
|
try {
|
|
566
565
|
const attestationDeadline = new Date(this.dateProvider.now() + attestationTimeAllowed * 1000);
|
|
567
566
|
const attestations = await this.validatorClient.collectAttestations(proposal, numberOfRequiredAttestations, attestationDeadline);
|
|
568
|
-
|
|
567
|
+
collectedAttestationsCount = attestations.length;
|
|
569
568
|
// note: the smart contract requires that the signatures are provided in the order of the committee
|
|
570
569
|
return orderAttestations(attestations, committee);
|
|
571
570
|
} catch (err) {
|
|
572
571
|
if (err && err instanceof AttestationTimeoutError) {
|
|
573
|
-
|
|
572
|
+
collectedAttestationsCount = err.collectedCount;
|
|
574
573
|
}
|
|
575
574
|
throw err;
|
|
576
575
|
} finally{
|
|
577
|
-
this.metrics.recordCollectedAttestations(
|
|
576
|
+
this.metrics.recordCollectedAttestations(collectedAttestationsCount, timer.ms());
|
|
578
577
|
}
|
|
579
578
|
}
|
|
580
579
|
/**
|
|
581
580
|
* Publishes the L2Block to the rollup contract.
|
|
582
581
|
* @param block - The L2Block to be published.
|
|
583
|
-
*/ async enqueuePublishL2Block(block,
|
|
582
|
+
*/ async enqueuePublishL2Block(block, attestationsAndSigners, attestationsAndSignersSignature, invalidateBlock, publisher) {
|
|
584
583
|
// Publishes new block to the network and awaits the tx to be mined
|
|
585
584
|
this.setState(SequencerState.PUBLISHING_BLOCK, block.header.globalVariables.slotNumber.toBigInt());
|
|
586
585
|
// Time out tx at the end of the slot
|
|
587
586
|
const slot = block.header.globalVariables.slotNumber.toNumber();
|
|
588
587
|
const txTimeoutAt = new Date((this.getSlotStartBuildTimestamp(slot) + this.aztecSlotDuration) * 1000);
|
|
589
|
-
const enqueued = await publisher.enqueueProposeL2Block(block,
|
|
588
|
+
const enqueued = await publisher.enqueueProposeL2Block(block, attestationsAndSigners, attestationsAndSignersSignature, {
|
|
590
589
|
txTimeoutAt,
|
|
591
590
|
forcePendingBlockNumber: invalidateBlock?.forcePendingBlockNumber
|
|
592
591
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aztec/sequencer-client",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0-rc.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./dest/index.js",
|
|
@@ -26,37 +26,37 @@
|
|
|
26
26
|
"test:integration:run": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --no-cache --config jest.integration.config.json"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@aztec/aztec.js": "2.0
|
|
30
|
-
"@aztec/bb-prover": "2.0
|
|
31
|
-
"@aztec/blob-lib": "2.0
|
|
32
|
-
"@aztec/blob-sink": "2.0
|
|
33
|
-
"@aztec/constants": "2.0
|
|
34
|
-
"@aztec/epoch-cache": "2.0
|
|
35
|
-
"@aztec/ethereum": "2.0
|
|
36
|
-
"@aztec/foundation": "2.0
|
|
37
|
-
"@aztec/l1-artifacts": "2.0
|
|
38
|
-
"@aztec/merkle-tree": "2.0
|
|
39
|
-
"@aztec/
|
|
40
|
-
"@aztec/noir-
|
|
41
|
-
"@aztec/noir-
|
|
42
|
-
"@aztec/noir-types": "2.0
|
|
43
|
-
"@aztec/
|
|
44
|
-
"@aztec/
|
|
45
|
-
"@aztec/
|
|
46
|
-
"@aztec/
|
|
47
|
-
"@aztec/
|
|
48
|
-
"@aztec/
|
|
49
|
-
"@aztec/
|
|
50
|
-
"@aztec/
|
|
51
|
-
"@aztec/
|
|
29
|
+
"@aztec/aztec.js": "2.1.0-rc.1",
|
|
30
|
+
"@aztec/bb-prover": "2.1.0-rc.1",
|
|
31
|
+
"@aztec/blob-lib": "2.1.0-rc.1",
|
|
32
|
+
"@aztec/blob-sink": "2.1.0-rc.1",
|
|
33
|
+
"@aztec/constants": "2.1.0-rc.1",
|
|
34
|
+
"@aztec/epoch-cache": "2.1.0-rc.1",
|
|
35
|
+
"@aztec/ethereum": "2.1.0-rc.1",
|
|
36
|
+
"@aztec/foundation": "2.1.0-rc.1",
|
|
37
|
+
"@aztec/l1-artifacts": "2.1.0-rc.1",
|
|
38
|
+
"@aztec/merkle-tree": "2.1.0-rc.1",
|
|
39
|
+
"@aztec/node-keystore": "2.1.0-rc.1",
|
|
40
|
+
"@aztec/noir-acvm_js": "2.1.0-rc.1",
|
|
41
|
+
"@aztec/noir-contracts.js": "2.1.0-rc.1",
|
|
42
|
+
"@aztec/noir-protocol-circuits-types": "2.1.0-rc.1",
|
|
43
|
+
"@aztec/noir-types": "2.1.0-rc.1",
|
|
44
|
+
"@aztec/p2p": "2.1.0-rc.1",
|
|
45
|
+
"@aztec/protocol-contracts": "2.1.0-rc.1",
|
|
46
|
+
"@aztec/prover-client": "2.1.0-rc.1",
|
|
47
|
+
"@aztec/simulator": "2.1.0-rc.1",
|
|
48
|
+
"@aztec/slasher": "2.1.0-rc.1",
|
|
49
|
+
"@aztec/stdlib": "2.1.0-rc.1",
|
|
50
|
+
"@aztec/telemetry-client": "2.1.0-rc.1",
|
|
51
|
+
"@aztec/validator-client": "2.1.0-rc.1",
|
|
52
|
+
"@aztec/world-state": "2.1.0-rc.1",
|
|
52
53
|
"lodash.chunk": "^4.2.0",
|
|
53
|
-
"lodash.pick": "^4.4.0",
|
|
54
54
|
"tslib": "^2.4.0",
|
|
55
55
|
"viem": "2.23.7"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
|
-
"@aztec/archiver": "2.0
|
|
59
|
-
"@aztec/kv-store": "2.0
|
|
58
|
+
"@aztec/archiver": "2.1.0-rc.1",
|
|
59
|
+
"@aztec/kv-store": "2.1.0-rc.1",
|
|
60
60
|
"@jest/globals": "^30.0.0",
|
|
61
61
|
"@types/jest": "^30.0.0",
|
|
62
62
|
"@types/lodash.chunk": "^4.2.7",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"@types/node": "^22.15.17",
|
|
65
65
|
"concurrently": "^7.6.0",
|
|
66
66
|
"eslint": "^9.26.0",
|
|
67
|
-
"express": "^4.21.
|
|
67
|
+
"express": "^4.21.2",
|
|
68
68
|
"jest": "^30.0.0",
|
|
69
69
|
"jest-mock-extended": "^4.0.0",
|
|
70
70
|
"prettier": "^3.5.3",
|
|
@@ -84,7 +84,7 @@ export class SequencerClient {
|
|
|
84
84
|
telemetry: telemetryClient,
|
|
85
85
|
} = deps;
|
|
86
86
|
const { l1RpcUrls: rpcUrls, l1ChainId: chainId } = config;
|
|
87
|
-
const log = createLogger('sequencer
|
|
87
|
+
const log = createLogger('sequencer');
|
|
88
88
|
const publicClient = getPublicClient(config);
|
|
89
89
|
const l1TxUtils = deps.l1TxUtils;
|
|
90
90
|
const l1Metrics = new L1Metrics(
|
|
@@ -92,7 +92,7 @@ export class SequencerClient {
|
|
|
92
92
|
publicClient,
|
|
93
93
|
l1TxUtils.map(x => x.getSenderAddress()),
|
|
94
94
|
);
|
|
95
|
-
const publisherManager = new PublisherManager(l1TxUtils);
|
|
95
|
+
const publisherManager = new PublisherManager(l1TxUtils, config);
|
|
96
96
|
const rollupContract = new RollupContract(publicClient, config.l1Contracts.rollupAddress.toString());
|
|
97
97
|
const [l1GenesisTime, slotDuration] = await Promise.all([
|
|
98
98
|
rollupContract.getL1GenesisTime(),
|
|
@@ -133,6 +133,7 @@ export class SequencerClient {
|
|
|
133
133
|
dateProvider: deps.dateProvider,
|
|
134
134
|
publisherManager,
|
|
135
135
|
nodeKeyStore: NodeKeystoreAdapter.fromKeyStoreManager(deps.nodeKeyStore),
|
|
136
|
+
logger: log,
|
|
136
137
|
});
|
|
137
138
|
const globalsBuilder = new GlobalVariableBuilder(config);
|
|
138
139
|
|
|
@@ -178,6 +179,7 @@ export class SequencerClient {
|
|
|
178
179
|
rollupContract,
|
|
179
180
|
{ ...config, maxL1TxInclusionTimeIntoSlot, maxL2BlockGas: sequencerManaLimit },
|
|
180
181
|
telemetryClient,
|
|
182
|
+
log,
|
|
181
183
|
);
|
|
182
184
|
|
|
183
185
|
await sequencer.init();
|
package/src/config.ts
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
pickConfigMappings,
|
|
13
13
|
} from '@aztec/foundation/config';
|
|
14
14
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
15
|
+
import { type KeyStoreConfig, keyStoreConfigMappings } from '@aztec/node-keystore';
|
|
15
16
|
import { type P2PConfig, p2pConfigMappings } from '@aztec/p2p';
|
|
16
17
|
import { AztecAddress } from '@aztec/stdlib/aztec-address';
|
|
17
18
|
import { type ChainConfig, type SequencerConfig, chainConfigMappings } from '@aztec/stdlib/config';
|
|
@@ -33,6 +34,7 @@ export const DEFAULT_ATTESTATION_PROPAGATION_TIME = 2;
|
|
|
33
34
|
* Configuration settings for the SequencerClient.
|
|
34
35
|
*/
|
|
35
36
|
export type SequencerClientConfig = PublisherConfig &
|
|
37
|
+
KeyStoreConfig &
|
|
36
38
|
ValidatorClientConfig &
|
|
37
39
|
TxSenderConfig &
|
|
38
40
|
SequencerConfig &
|
|
@@ -149,6 +151,7 @@ export const sequencerConfigMappings: ConfigMappingsType<SequencerConfig> = {
|
|
|
149
151
|
export const sequencerClientConfigMappings: ConfigMappingsType<SequencerClientConfig> = {
|
|
150
152
|
...validatorClientConfigMappings,
|
|
151
153
|
...sequencerConfigMappings,
|
|
154
|
+
...keyStoreConfigMappings,
|
|
152
155
|
...l1ReaderConfigMappings,
|
|
153
156
|
...getTxSenderConfigMappings('SEQ'),
|
|
154
157
|
...getPublisherConfigMappings('SEQ'),
|
package/src/publisher/config.ts
CHANGED
|
@@ -5,7 +5,12 @@ import {
|
|
|
5
5
|
l1ReaderConfigMappings,
|
|
6
6
|
l1TxUtilsConfigMappings,
|
|
7
7
|
} from '@aztec/ethereum';
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
type ConfigMappingsType,
|
|
10
|
+
SecretValue,
|
|
11
|
+
booleanConfigHelper,
|
|
12
|
+
getConfigFromMappings,
|
|
13
|
+
} from '@aztec/foundation/config';
|
|
9
14
|
import { EthAddress } from '@aztec/foundation/eth-address';
|
|
10
15
|
|
|
11
16
|
/**
|
|
@@ -21,6 +26,9 @@ export type TxSenderConfig = L1ReaderConfig & {
|
|
|
21
26
|
* Publisher addresses to be used with a remote signer
|
|
22
27
|
*/
|
|
23
28
|
publisherAddresses?: EthAddress[];
|
|
29
|
+
|
|
30
|
+
/** Whether this publisher is enabled */
|
|
31
|
+
publisherEnabled?: boolean;
|
|
24
32
|
};
|
|
25
33
|
|
|
26
34
|
/**
|
|
@@ -28,10 +36,10 @@ export type TxSenderConfig = L1ReaderConfig & {
|
|
|
28
36
|
*/
|
|
29
37
|
export type PublisherConfig = L1TxUtilsConfig &
|
|
30
38
|
BlobSinkConfig & {
|
|
31
|
-
/**
|
|
32
|
-
* The interval to wait between publish retries.
|
|
33
|
-
*/
|
|
39
|
+
/** The interval to wait between publish retries. */
|
|
34
40
|
l1PublishRetryIntervalMS: number;
|
|
41
|
+
/** True to use publishers in invalid states (timed out, cancelled, etc) if no other is available */
|
|
42
|
+
publisherAllowInvalidStates?: boolean;
|
|
35
43
|
};
|
|
36
44
|
|
|
37
45
|
export const getTxSenderConfigMappings: (
|
|
@@ -43,7 +51,7 @@ export const getTxSenderConfigMappings: (
|
|
|
43
51
|
description: 'The private keys to be used by the publisher.',
|
|
44
52
|
parseEnv: (val: string) => val.split(',').map(key => new SecretValue(`0x${key.replace('0x', '')}`)),
|
|
45
53
|
defaultValue: [],
|
|
46
|
-
fallback: scope === 'PROVER' ?
|
|
54
|
+
fallback: [scope === 'PROVER' ? `PROVER_PUBLISHER_PRIVATE_KEY` : `SEQ_PUBLISHER_PRIVATE_KEY`],
|
|
47
55
|
},
|
|
48
56
|
publisherAddresses: {
|
|
49
57
|
env: scope === 'PROVER' ? `PROVER_PUBLISHER_ADDRESSES` : `SEQ_PUBLISHER_ADDRESSES`,
|
|
@@ -51,6 +59,11 @@ export const getTxSenderConfigMappings: (
|
|
|
51
59
|
parseEnv: (val: string) => val.split(',').map(address => EthAddress.fromString(address)),
|
|
52
60
|
defaultValue: [],
|
|
53
61
|
},
|
|
62
|
+
publisherEnabled: {
|
|
63
|
+
env: scope === 'PROVER' ? `PROVER_PUBLISHER_ENABLED` : `SEQ_PUBLISHER_ENABLED`,
|
|
64
|
+
description: 'Whether this L1 publisher is enabled',
|
|
65
|
+
...booleanConfigHelper(true),
|
|
66
|
+
},
|
|
54
67
|
});
|
|
55
68
|
|
|
56
69
|
export function getTxSenderConfigFromEnv(scope: 'PROVER' | 'SEQ'): Omit<TxSenderConfig, 'l1Contracts'> {
|
|
@@ -66,6 +79,11 @@ export const getPublisherConfigMappings: (
|
|
|
66
79
|
defaultValue: 1000,
|
|
67
80
|
description: 'The interval to wait between publish retries.',
|
|
68
81
|
},
|
|
82
|
+
publisherAllowInvalidStates: {
|
|
83
|
+
description: 'True to use publishers in invalid states (timed out, cancelled, etc) if no other is available',
|
|
84
|
+
env: scope === `PROVER` ? `PROVER_PUBLISHER_ALLOW_INVALID_STATES` : `SEQ_PUBLISHER_ALLOW_INVALID_STATES`,
|
|
85
|
+
...booleanConfigHelper(false),
|
|
86
|
+
},
|
|
69
87
|
...l1TxUtilsConfigMappings,
|
|
70
88
|
...blobSinkConfigMapping,
|
|
71
89
|
});
|
package/src/publisher/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EthAddress } from '@aztec/aztec.js';
|
|
1
|
+
import { EthAddress, type Logger, createLogger } from '@aztec/aztec.js';
|
|
2
2
|
import type { BlobSinkClientInterface } from '@aztec/blob-sink/client';
|
|
3
3
|
import type { EpochCache } from '@aztec/epoch-cache';
|
|
4
4
|
import type { GovernanceProposerContract, PublisherFilter, PublisherManager, RollupContract } from '@aztec/ethereum';
|
|
@@ -10,7 +10,7 @@ import { NodeKeystoreAdapter } from '@aztec/validator-client';
|
|
|
10
10
|
|
|
11
11
|
import type { SequencerClientConfig } from '../config.js';
|
|
12
12
|
import { SequencerPublisherMetrics } from './sequencer-publisher-metrics.js';
|
|
13
|
-
import { SequencerPublisher } from './sequencer-publisher.js';
|
|
13
|
+
import { type Action, SequencerPublisher } from './sequencer-publisher.js';
|
|
14
14
|
|
|
15
15
|
export type AttestorPublisherPair = {
|
|
16
16
|
attestorAddress: EthAddress;
|
|
@@ -19,6 +19,12 @@ export type AttestorPublisherPair = {
|
|
|
19
19
|
|
|
20
20
|
export class SequencerPublisherFactory {
|
|
21
21
|
private publisherMetrics: SequencerPublisherMetrics;
|
|
22
|
+
|
|
23
|
+
/** Stores the last slot in which every action was carried out by a publisher */
|
|
24
|
+
private lastActions: Partial<Record<Action, bigint>> = {};
|
|
25
|
+
|
|
26
|
+
private logger: Logger;
|
|
27
|
+
|
|
22
28
|
constructor(
|
|
23
29
|
private sequencerConfig: SequencerClientConfig,
|
|
24
30
|
private deps: {
|
|
@@ -31,9 +37,11 @@ export class SequencerPublisherFactory {
|
|
|
31
37
|
governanceProposerContract: GovernanceProposerContract;
|
|
32
38
|
slashFactoryContract: SlashFactoryContract;
|
|
33
39
|
nodeKeyStore: NodeKeystoreAdapter;
|
|
40
|
+
logger?: Logger;
|
|
34
41
|
},
|
|
35
42
|
) {
|
|
36
43
|
this.publisherMetrics = new SequencerPublisherMetrics(deps.telemetry, 'SequencerPublisher');
|
|
44
|
+
this.logger = deps.logger ?? createLogger('sequencer');
|
|
37
45
|
}
|
|
38
46
|
/**
|
|
39
47
|
* Creates a new SequencerPublisher instance.
|
|
@@ -69,6 +77,8 @@ export class SequencerPublisherFactory {
|
|
|
69
77
|
slashFactoryContract: this.deps.slashFactoryContract,
|
|
70
78
|
dateProvider: this.deps.dateProvider,
|
|
71
79
|
metrics: this.publisherMetrics,
|
|
80
|
+
lastActions: this.lastActions,
|
|
81
|
+
log: this.logger.createChild('publisher'),
|
|
72
82
|
});
|
|
73
83
|
|
|
74
84
|
return {
|