@aztec/sequencer-client 3.0.0-canary.a9708bd → 3.0.0-devnet.3

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.
Files changed (56) hide show
  1. package/dest/client/sequencer-client.d.ts +5 -4
  2. package/dest/client/sequencer-client.d.ts.map +1 -1
  3. package/dest/client/sequencer-client.js +17 -12
  4. package/dest/config.d.ts +2 -1
  5. package/dest/config.d.ts.map +1 -1
  6. package/dest/config.js +10 -0
  7. package/dest/publisher/config.d.ts +2 -8
  8. package/dest/publisher/config.d.ts.map +1 -1
  9. package/dest/publisher/config.js +7 -16
  10. package/dest/publisher/index.d.ts +1 -1
  11. package/dest/publisher/index.d.ts.map +1 -1
  12. package/dest/publisher/index.js +1 -1
  13. package/dest/publisher/sequencer-publisher-factory.d.ts +6 -1
  14. package/dest/publisher/sequencer-publisher-factory.d.ts.map +1 -1
  15. package/dest/publisher/sequencer-publisher-factory.js +8 -1
  16. package/dest/publisher/sequencer-publisher-metrics.d.ts +1 -1
  17. package/dest/publisher/sequencer-publisher-metrics.d.ts.map +1 -1
  18. package/dest/publisher/sequencer-publisher-metrics.js +1 -1
  19. package/dest/publisher/sequencer-publisher.d.ts +16 -22
  20. package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
  21. package/dest/publisher/sequencer-publisher.js +72 -72
  22. package/dest/sequencer/block_builder.d.ts +2 -5
  23. package/dest/sequencer/block_builder.d.ts.map +1 -1
  24. package/dest/sequencer/block_builder.js +18 -6
  25. package/dest/sequencer/errors.d.ts +11 -0
  26. package/dest/sequencer/errors.d.ts.map +1 -0
  27. package/dest/sequencer/errors.js +15 -0
  28. package/dest/sequencer/metrics.d.ts +6 -18
  29. package/dest/sequencer/metrics.d.ts.map +1 -1
  30. package/dest/sequencer/metrics.js +22 -88
  31. package/dest/sequencer/sequencer.d.ts +8 -7
  32. package/dest/sequencer/sequencer.d.ts.map +1 -1
  33. package/dest/sequencer/sequencer.js +55 -33
  34. package/dest/sequencer/timetable.d.ts +1 -7
  35. package/dest/sequencer/timetable.d.ts.map +1 -1
  36. package/dest/sequencer/timetable.js +3 -10
  37. package/dest/sequencer/utils.d.ts +10 -24
  38. package/dest/sequencer/utils.d.ts.map +1 -1
  39. package/dest/sequencer/utils.js +9 -24
  40. package/dest/tx_validator/tx_validator_factory.d.ts.map +1 -1
  41. package/dest/tx_validator/tx_validator_factory.js +11 -8
  42. package/package.json +29 -29
  43. package/src/client/sequencer-client.ts +18 -9
  44. package/src/config.ts +11 -0
  45. package/src/publisher/config.ts +13 -22
  46. package/src/publisher/index.ts +1 -1
  47. package/src/publisher/sequencer-publisher-factory.ts +13 -2
  48. package/src/publisher/sequencer-publisher-metrics.ts +1 -1
  49. package/src/publisher/sequencer-publisher.ts +101 -98
  50. package/src/sequencer/block_builder.ts +20 -21
  51. package/src/sequencer/errors.ts +21 -0
  52. package/src/sequencer/metrics.ts +25 -101
  53. package/src/sequencer/sequencer.ts +85 -58
  54. package/src/sequencer/timetable.ts +3 -14
  55. package/src/sequencer/utils.ts +10 -24
  56. package/src/tx_validator/tx_validator_factory.ts +10 -5
@@ -1,28 +1,13 @@
1
1
  export var SequencerState = /*#__PURE__*/ function(SequencerState) {
2
- /**
3
- * Sequencer is stopped and not processing any txs from the pool.
4
- */ SequencerState["STOPPED"] = "STOPPED";
5
- /**
6
- * Sequencer is awaiting the next call to work().
7
- */ SequencerState["IDLE"] = "IDLE";
8
- /**
9
- * Synchronizing with the L2 chain.
10
- */ SequencerState["SYNCHRONIZING"] = "SYNCHRONIZING";
11
- /**
12
- * Checking if we are the proposer for the current slot.
13
- */ SequencerState["PROPOSER_CHECK"] = "PROPOSER_CHECK";
14
- /**
15
- * Initializing the block proposal. Will move to CREATING_BLOCK if there are valid txs to include, or back to SYNCHRONIZING otherwise.
16
- */ SequencerState["INITIALIZING_PROPOSAL"] = "INITIALIZING_PROPOSAL";
17
- /**
18
- * Creating a new L2 block. Includes processing public function calls and running rollup circuits. Will move to PUBLISHING_CONTRACT_DATA.
19
- */ SequencerState["CREATING_BLOCK"] = "CREATING_BLOCK";
20
- /**
21
- * Collecting attestations from its peers. Will move to PUBLISHING_BLOCK.
22
- */ SequencerState["COLLECTING_ATTESTATIONS"] = "COLLECTING_ATTESTATIONS";
23
- /**
24
- * Sending the tx to L1 with the L2 block data and awaiting it to be mined. Will move to SYNCHRONIZING.
25
- */ SequencerState["PUBLISHING_BLOCK"] = "PUBLISHING_BLOCK";
2
+ /** Sequencer is stopped and not processing any txs from the pool. */ SequencerState["STOPPED"] = "STOPPED";
3
+ /** Sequencer is being stopped. Will move to STOPPED shortly. */ SequencerState["STOPPING"] = "STOPPING";
4
+ /** Sequencer is awaiting the next call to work(). */ SequencerState["IDLE"] = "IDLE";
5
+ /** Synchronizing with the L2 chain. */ SequencerState["SYNCHRONIZING"] = "SYNCHRONIZING";
6
+ /** Checking if we are the proposer for the current slot. */ SequencerState["PROPOSER_CHECK"] = "PROPOSER_CHECK";
7
+ /** Initializing the block proposal. Will move to CREATING_BLOCK if there are valid txs to include, or back to SYNCHRONIZING otherwise. */ SequencerState["INITIALIZING_PROPOSAL"] = "INITIALIZING_PROPOSAL";
8
+ /** Creating a new L2 block. Includes processing public function calls and running rollup circuits. Will move to PUBLISHING_CONTRACT_DATA. */ SequencerState["CREATING_BLOCK"] = "CREATING_BLOCK";
9
+ /** Collecting attestations from its peers. Will move to PUBLISHING_BLOCK. */ SequencerState["COLLECTING_ATTESTATIONS"] = "COLLECTING_ATTESTATIONS";
10
+ /** Sending the tx to L1 with the L2 block data and awaiting it to be mined. Will move to SYNCHRONIZING. */ SequencerState["PUBLISHING_BLOCK"] = "PUBLISHING_BLOCK";
26
11
  return SequencerState;
27
12
  }({});
28
13
  export function sequencerStateToNumber(state) {
@@ -1 +1 @@
1
- {"version":3,"file":"tx_validator_factory.d.ts","sourceRoot":"","sources":["../../src/tx_validator/tx_validator_factory.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EACV,cAAc,EACd,6BAA6B,EAC7B,wBAAwB,EACxB,wBAAwB,EACzB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,EAAE,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC9E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAIlD,wBAAgB,8BAA8B,CAC5C,EAAE,EAAE,wBAAwB,EAC5B,kBAAkB,EAAE,kBAAkB,EACtC,QAAQ,EAAE,6BAA6B,GAAG,SAAS,EACnD,EACE,SAAS,EACT,aAAa,EACb,cAAc,EACd,OAAO,EACP,kBAAkB,EAClB,SAAS,EACT,WAAW,EACX,YAAY,GACb,EAAE;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,cAAc,EAAE,CAAC;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;CACvB,GACA,WAAW,CAAC,EAAE,CAAC,CA0BjB;AAED,wBAAgB,+BAA+B,CAC7C,EAAE,EAAE,wBAAwB,EAC5B,kBAAkB,EAAE,kBAAkB,EACtC,eAAe,EAAE,eAAe,EAChC,cAAc,EAAE,cAAc,EAAE,GAC/B,wBAAwB,CAgB1B"}
1
+ {"version":3,"file":"tx_validator_factory.d.ts","sourceRoot":"","sources":["../../src/tx_validator/tx_validator_factory.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EACV,cAAc,EACd,6BAA6B,EAC7B,wBAAwB,EACxB,wBAAwB,EACzB,MAAM,iCAAiC,CAAC;AAEzC,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,EAAE,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC9E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAIlD,wBAAgB,8BAA8B,CAC5C,EAAE,EAAE,wBAAwB,EAC5B,kBAAkB,EAAE,kBAAkB,EACtC,QAAQ,EAAE,6BAA6B,GAAG,SAAS,EACnD,EACE,SAAS,EACT,aAAa,EACb,cAAc,EACd,OAAO,EACP,kBAAkB,EAClB,SAAS,EACT,WAAW,EACX,YAAY,GACb,EAAE;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,cAAc,EAAE,CAAC;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;CACvB,GACA,WAAW,CAAC,EAAE,CAAC,CA4BjB;AAED,wBAAgB,+BAA+B,CAC7C,EAAE,EAAE,wBAAwB,EAC5B,kBAAkB,EAAE,kBAAkB,EACtC,eAAe,EAAE,eAAe,EAChC,cAAc,EAAE,cAAc,EAAE,GAC/B,wBAAwB,CAgB1B"}
@@ -1,7 +1,7 @@
1
1
  import { Fr } from '@aztec/foundation/fields';
2
2
  import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
3
- import { AggregateTxValidator, ArchiveCache, BlockHeaderTxValidator, DataTxValidator, DoubleSpendTxValidator, GasTxValidator, MetadataTxValidator, PhasesTxValidator, TxPermittedValidator, TxProofValidator } from '@aztec/p2p';
4
- import { ProtocolContractAddress, protocolContractTreeRoot } from '@aztec/protocol-contracts';
3
+ import { AggregateTxValidator, ArchiveCache, BlockHeaderTxValidator, DataTxValidator, DoubleSpendTxValidator, GasTxValidator, MetadataTxValidator, PhasesTxValidator, TimestampTxValidator, TxPermittedValidator, TxProofValidator } from '@aztec/p2p';
4
+ import { ProtocolContractAddress, protocolContractsHash } from '@aztec/protocol-contracts';
5
5
  import { DatabasePublicStateSource } from '@aztec/stdlib/trees';
6
6
  import { NullifierCache } from './nullifier_cache.js';
7
7
  export function createValidatorForAcceptingTxs(db, contractDataSource, verifier, { l1ChainId, rollupVersion, setupAllowList, gasFees, skipFeeEnforcement, timestamp, blockNumber, txsPermitted }) {
@@ -11,11 +11,13 @@ export function createValidatorForAcceptingTxs(db, contractDataSource, verifier,
11
11
  new MetadataTxValidator({
12
12
  l1ChainId: new Fr(l1ChainId),
13
13
  rollupVersion: new Fr(rollupVersion),
14
- timestamp,
15
- blockNumber,
16
- protocolContractTreeRoot,
14
+ protocolContractsHash,
17
15
  vkTreeRoot: getVKTreeRoot()
18
16
  }),
17
+ new TimestampTxValidator({
18
+ timestamp,
19
+ blockNumber
20
+ }),
19
21
  new DoubleSpendTxValidator(new NullifierCache(db)),
20
22
  new PhasesTxValidator(contractDataSource, setupAllowList, timestamp),
21
23
  new BlockHeaderTxValidator(new ArchiveCache(db))
@@ -42,9 +44,10 @@ function preprocessValidator(nullifierCache, archiveCache, publicStateSource, co
42
44
  return new AggregateTxValidator(new MetadataTxValidator({
43
45
  l1ChainId: globalVariables.chainId,
44
46
  rollupVersion: globalVariables.version,
45
- timestamp: globalVariables.timestamp,
46
- blockNumber: globalVariables.blockNumber,
47
- protocolContractTreeRoot,
47
+ protocolContractsHash,
48
48
  vkTreeRoot: getVKTreeRoot()
49
+ }), new TimestampTxValidator({
50
+ timestamp: globalVariables.timestamp,
51
+ blockNumber: globalVariables.blockNumber
49
52
  }), new DoubleSpendTxValidator(nullifierCache), new PhasesTxValidator(contractDataSource, setupAllowList, globalVariables.timestamp), new GasTxValidator(publicStateSource, ProtocolContractAddress.FeeJuice, globalVariables.gasFees), new BlockHeaderTxValidator(archiveCache));
50
53
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/sequencer-client",
3
- "version": "3.0.0-canary.a9708bd",
3
+ "version": "3.0.0-devnet.3",
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": "3.0.0-canary.a9708bd",
30
- "@aztec/bb-prover": "3.0.0-canary.a9708bd",
31
- "@aztec/blob-lib": "3.0.0-canary.a9708bd",
32
- "@aztec/blob-sink": "3.0.0-canary.a9708bd",
33
- "@aztec/constants": "3.0.0-canary.a9708bd",
34
- "@aztec/epoch-cache": "3.0.0-canary.a9708bd",
35
- "@aztec/ethereum": "3.0.0-canary.a9708bd",
36
- "@aztec/foundation": "3.0.0-canary.a9708bd",
37
- "@aztec/l1-artifacts": "3.0.0-canary.a9708bd",
38
- "@aztec/merkle-tree": "3.0.0-canary.a9708bd",
39
- "@aztec/noir-acvm_js": "3.0.0-canary.a9708bd",
40
- "@aztec/noir-contracts.js": "3.0.0-canary.a9708bd",
41
- "@aztec/noir-protocol-circuits-types": "3.0.0-canary.a9708bd",
42
- "@aztec/noir-types": "3.0.0-canary.a9708bd",
43
- "@aztec/p2p": "3.0.0-canary.a9708bd",
44
- "@aztec/protocol-contracts": "3.0.0-canary.a9708bd",
45
- "@aztec/prover-client": "3.0.0-canary.a9708bd",
46
- "@aztec/simulator": "3.0.0-canary.a9708bd",
47
- "@aztec/slasher": "3.0.0-canary.a9708bd",
48
- "@aztec/stdlib": "3.0.0-canary.a9708bd",
49
- "@aztec/telemetry-client": "3.0.0-canary.a9708bd",
50
- "@aztec/validator-client": "3.0.0-canary.a9708bd",
51
- "@aztec/world-state": "3.0.0-canary.a9708bd",
29
+ "@aztec/aztec.js": "3.0.0-devnet.3",
30
+ "@aztec/bb-prover": "3.0.0-devnet.3",
31
+ "@aztec/blob-lib": "3.0.0-devnet.3",
32
+ "@aztec/blob-sink": "3.0.0-devnet.3",
33
+ "@aztec/constants": "3.0.0-devnet.3",
34
+ "@aztec/epoch-cache": "3.0.0-devnet.3",
35
+ "@aztec/ethereum": "3.0.0-devnet.3",
36
+ "@aztec/foundation": "3.0.0-devnet.3",
37
+ "@aztec/l1-artifacts": "3.0.0-devnet.3",
38
+ "@aztec/merkle-tree": "3.0.0-devnet.3",
39
+ "@aztec/node-keystore": "3.0.0-devnet.3",
40
+ "@aztec/noir-acvm_js": "3.0.0-devnet.3",
41
+ "@aztec/noir-contracts.js": "3.0.0-devnet.3",
42
+ "@aztec/noir-protocol-circuits-types": "3.0.0-devnet.3",
43
+ "@aztec/noir-types": "3.0.0-devnet.3",
44
+ "@aztec/p2p": "3.0.0-devnet.3",
45
+ "@aztec/protocol-contracts": "3.0.0-devnet.3",
46
+ "@aztec/prover-client": "3.0.0-devnet.3",
47
+ "@aztec/simulator": "3.0.0-devnet.3",
48
+ "@aztec/slasher": "3.0.0-devnet.3",
49
+ "@aztec/stdlib": "3.0.0-devnet.3",
50
+ "@aztec/telemetry-client": "3.0.0-devnet.3",
51
+ "@aztec/validator-client": "3.0.0-devnet.3",
52
+ "@aztec/world-state": "3.0.0-devnet.3",
52
53
  "lodash.chunk": "^4.2.0",
53
- "lodash.pick": "^4.4.0",
54
54
  "tslib": "^2.4.0",
55
- "viem": "2.23.7"
55
+ "viem": "npm:@spalladino/viem@2.38.2-eip7594.0"
56
56
  },
57
57
  "devDependencies": {
58
- "@aztec/archiver": "3.0.0-canary.a9708bd",
59
- "@aztec/kv-store": "3.0.0-canary.a9708bd",
58
+ "@aztec/archiver": "3.0.0-devnet.3",
59
+ "@aztec/kv-store": "3.0.0-devnet.3",
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.1",
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",
@@ -15,7 +15,11 @@ import type { KeystoreManager } from '@aztec/node-keystore';
15
15
  import type { P2P } from '@aztec/p2p';
16
16
  import type { SlasherClientInterface } from '@aztec/slasher';
17
17
  import type { L2BlockSource } from '@aztec/stdlib/block';
18
- import type { IFullNodeBlockBuilder, WorldStateSynchronizer } from '@aztec/stdlib/interfaces/server';
18
+ import type {
19
+ IFullNodeBlockBuilder,
20
+ ValidatorClientFullConfig,
21
+ WorldStateSynchronizer,
22
+ } from '@aztec/stdlib/interfaces/server';
19
23
  import { SlashFactoryContract } from '@aztec/stdlib/l1-contracts';
20
24
  import type { L1ToL2MessageSource } from '@aztec/stdlib/messaging';
21
25
  import { L1Metrics, type TelemetryClient } from '@aztec/telemetry-client';
@@ -33,6 +37,7 @@ export class SequencerClient {
33
37
  constructor(
34
38
  protected publisherManager: PublisherManager<L1TxUtilsWithBlobs>,
35
39
  protected sequencer: Sequencer,
40
+ protected blockBuilder: IFullNodeBlockBuilder,
36
41
  protected validatorClient?: ValidatorClient,
37
42
  private l1Metrics?: L1Metrics,
38
43
  ) {}
@@ -79,7 +84,7 @@ export class SequencerClient {
79
84
  telemetry: telemetryClient,
80
85
  } = deps;
81
86
  const { l1RpcUrls: rpcUrls, l1ChainId: chainId } = config;
82
- const log = createLogger('sequencer-client');
87
+ const log = createLogger('sequencer');
83
88
  const publicClient = getPublicClient(config);
84
89
  const l1TxUtils = deps.l1TxUtils;
85
90
  const l1Metrics = new L1Metrics(
@@ -87,7 +92,7 @@ export class SequencerClient {
87
92
  publicClient,
88
93
  l1TxUtils.map(x => x.getSenderAddress()),
89
94
  );
90
- const publisherManager = new PublisherManager(l1TxUtils);
95
+ const publisherManager = new PublisherManager(l1TxUtils, config);
91
96
  const rollupContract = new RollupContract(publicClient, config.l1Contracts.rollupAddress.toString());
92
97
  const [l1GenesisTime, slotDuration] = await Promise.all([
93
98
  rollupContract.getL1GenesisTime(),
@@ -106,9 +111,7 @@ export class SequencerClient {
106
111
  l1RpcUrls: rpcUrls,
107
112
  l1ChainId: chainId,
108
113
  viemPollingIntervalMS: config.viemPollingIntervalMS,
109
- aztecSlotDuration: config.aztecSlotDuration,
110
114
  ethereumSlotDuration: config.ethereumSlotDuration,
111
- aztecEpochDuration: config.aztecEpochDuration,
112
115
  },
113
116
  { dateProvider: deps.dateProvider },
114
117
  ));
@@ -130,6 +133,7 @@ export class SequencerClient {
130
133
  dateProvider: deps.dateProvider,
131
134
  publisherManager,
132
135
  nodeKeyStore: NodeKeystoreAdapter.fromKeyStoreManager(deps.nodeKeyStore),
136
+ logger: log,
133
137
  });
134
138
  const globalsBuilder = new GlobalVariableBuilder(config);
135
139
 
@@ -175,19 +179,22 @@ export class SequencerClient {
175
179
  rollupContract,
176
180
  { ...config, maxL1TxInclusionTimeIntoSlot, maxL2BlockGas: sequencerManaLimit },
177
181
  telemetryClient,
182
+ log,
178
183
  );
179
184
 
180
185
  await sequencer.init();
181
186
 
182
- return new SequencerClient(publisherManager, sequencer, validatorClient, l1Metrics);
187
+ return new SequencerClient(publisherManager, sequencer, blockBuilder, validatorClient, l1Metrics);
183
188
  }
184
189
 
185
190
  /**
186
- * Updates sequencer config.
191
+ * Updates sequencer and validator client config.
187
192
  * @param config - New parameters.
188
193
  */
189
- public updateSequencerConfig(config: SequencerConfig) {
190
- return this.sequencer.updateConfig(config);
194
+ public updateConfig(config: SequencerConfig & Partial<ValidatorClientFullConfig>) {
195
+ this.sequencer.updateConfig(config);
196
+ this.blockBuilder.updateConfig(config);
197
+ this.validatorClient?.updateConfig(config);
191
198
  }
192
199
 
193
200
  /** Starts the sequencer. */
@@ -195,6 +202,7 @@ export class SequencerClient {
195
202
  await this.validatorClient?.start();
196
203
  this.sequencer.start();
197
204
  this.l1Metrics?.start();
205
+ await this.publisherManager.loadState();
198
206
  }
199
207
 
200
208
  /**
@@ -202,6 +210,7 @@ export class SequencerClient {
202
210
  */
203
211
  public async stop() {
204
212
  await this.sequencer.stop();
213
+ await this.validatorClient?.stop();
205
214
  this.publisherManager.interrupt();
206
215
  this.l1Metrics?.stop();
207
216
  }
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 &
@@ -143,12 +145,21 @@ export const sequencerConfigMappings: ConfigMappingsType<SequencerConfig> = {
143
145
  description: 'Do not invalidate the previous block if invalid when we are the proposer (for testing only)',
144
146
  ...booleanConfigHelper(false),
145
147
  },
148
+ broadcastInvalidBlockProposal: {
149
+ description: 'Broadcast invalid block proposals with corrupted state (for testing only)',
150
+ ...booleanConfigHelper(false),
151
+ },
152
+ injectFakeAttestation: {
153
+ description: 'Inject a fake attestation (for testing only)',
154
+ ...booleanConfigHelper(false),
155
+ },
146
156
  ...pickConfigMappings(p2pConfigMappings, ['txPublicSetupAllowList']),
147
157
  };
148
158
 
149
159
  export const sequencerClientConfigMappings: ConfigMappingsType<SequencerClientConfig> = {
150
160
  ...validatorClientConfigMappings,
151
161
  ...sequencerConfigMappings,
162
+ ...keyStoreConfigMappings,
152
163
  ...l1ReaderConfigMappings,
153
164
  ...getTxSenderConfigMappings('SEQ'),
154
165
  ...getPublisherConfigMappings('SEQ'),
@@ -5,7 +5,12 @@ import {
5
5
  l1ReaderConfigMappings,
6
6
  l1TxUtilsConfigMappings,
7
7
  } from '@aztec/ethereum';
8
- import { type ConfigMappingsType, SecretValue, getConfigFromMappings } from '@aztec/foundation/config';
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,11 +26,6 @@ export type TxSenderConfig = L1ReaderConfig & {
21
26
  * Publisher addresses to be used with a remote signer
22
27
  */
23
28
  publisherAddresses?: EthAddress[];
24
-
25
- /**
26
- * The address of the custom forwarder contract.
27
- */
28
- customForwarderContractAddress: EthAddress;
29
29
  };
30
30
 
31
31
  /**
@@ -33,28 +33,20 @@ export type TxSenderConfig = L1ReaderConfig & {
33
33
  */
34
34
  export type PublisherConfig = L1TxUtilsConfig &
35
35
  BlobSinkConfig & {
36
- /**
37
- * The interval to wait between publish retries.
38
- */
39
- l1PublishRetryIntervalMS: number;
36
+ /** True to use publishers in invalid states (timed out, cancelled, etc) if no other is available */
37
+ publisherAllowInvalidStates?: boolean;
40
38
  };
41
39
 
42
40
  export const getTxSenderConfigMappings: (
43
41
  scope: 'PROVER' | 'SEQ',
44
42
  ) => ConfigMappingsType<Omit<TxSenderConfig, 'l1Contracts'>> = (scope: 'PROVER' | 'SEQ') => ({
45
43
  ...l1ReaderConfigMappings,
46
- customForwarderContractAddress: {
47
- env: `CUSTOM_FORWARDER_CONTRACT_ADDRESS`,
48
- parseEnv: (val: string) => EthAddress.fromString(val),
49
- description: 'The address of the custom forwarder contract.',
50
- defaultValue: EthAddress.ZERO,
51
- },
52
44
  publisherPrivateKeys: {
53
45
  env: scope === 'PROVER' ? `PROVER_PUBLISHER_PRIVATE_KEYS` : `SEQ_PUBLISHER_PRIVATE_KEYS`,
54
46
  description: 'The private keys to be used by the publisher.',
55
47
  parseEnv: (val: string) => val.split(',').map(key => new SecretValue(`0x${key.replace('0x', '')}`)),
56
48
  defaultValue: [],
57
- fallback: scope === 'PROVER' ? ['PROVER_PUBLISHER_PRIVATE_KEY'] : ['SEQ_PUBLISHER_PRIVATE_KEY'],
49
+ fallback: [scope === 'PROVER' ? `PROVER_PUBLISHER_PRIVATE_KEY` : `SEQ_PUBLISHER_PRIVATE_KEY`],
58
50
  },
59
51
  publisherAddresses: {
60
52
  env: scope === 'PROVER' ? `PROVER_PUBLISHER_ADDRESSES` : `SEQ_PUBLISHER_ADDRESSES`,
@@ -71,11 +63,10 @@ export function getTxSenderConfigFromEnv(scope: 'PROVER' | 'SEQ'): Omit<TxSender
71
63
  export const getPublisherConfigMappings: (
72
64
  scope: 'PROVER' | 'SEQ',
73
65
  ) => ConfigMappingsType<PublisherConfig & L1TxUtilsConfig> = scope => ({
74
- l1PublishRetryIntervalMS: {
75
- env: scope === `PROVER` ? `PROVER_PUBLISH_RETRY_INTERVAL_MS` : `SEQ_PUBLISH_RETRY_INTERVAL_MS`,
76
- parseEnv: (val: string) => +val,
77
- defaultValue: 1000,
78
- description: 'The interval to wait between publish retries.',
66
+ publisherAllowInvalidStates: {
67
+ description: 'True to use publishers in invalid states (timed out, cancelled, etc) if no other is available',
68
+ env: scope === `PROVER` ? `PROVER_PUBLISHER_ALLOW_INVALID_STATES` : `SEQ_PUBLISHER_ALLOW_INVALID_STATES`,
69
+ ...booleanConfigHelper(true),
79
70
  },
80
71
  ...l1TxUtilsConfigMappings,
81
72
  ...blobSinkConfigMapping,
@@ -1,4 +1,4 @@
1
- export { SequencerPublisher, SignalType } from './sequencer-publisher.js';
1
+ export { SequencerPublisher } from './sequencer-publisher.js';
2
2
  export { SequencerPublisherFactory } from './sequencer-publisher-factory.js';
3
3
 
4
4
  // Used for tests
@@ -1,4 +1,5 @@
1
- import { EthAddress } from '@aztec/aztec.js';
1
+ import { EthAddress } from '@aztec/aztec.js/addresses';
2
+ import { type Logger, createLogger } from '@aztec/aztec.js/log';
2
3
  import type { BlobSinkClientInterface } from '@aztec/blob-sink/client';
3
4
  import type { EpochCache } from '@aztec/epoch-cache';
4
5
  import type { GovernanceProposerContract, PublisherFilter, PublisherManager, RollupContract } from '@aztec/ethereum';
@@ -10,7 +11,7 @@ import { NodeKeystoreAdapter } from '@aztec/validator-client';
10
11
 
11
12
  import type { SequencerClientConfig } from '../config.js';
12
13
  import { SequencerPublisherMetrics } from './sequencer-publisher-metrics.js';
13
- import { SequencerPublisher } from './sequencer-publisher.js';
14
+ import { type Action, SequencerPublisher } from './sequencer-publisher.js';
14
15
 
15
16
  export type AttestorPublisherPair = {
16
17
  attestorAddress: EthAddress;
@@ -19,6 +20,12 @@ export type AttestorPublisherPair = {
19
20
 
20
21
  export class SequencerPublisherFactory {
21
22
  private publisherMetrics: SequencerPublisherMetrics;
23
+
24
+ /** Stores the last slot in which every action was carried out by a publisher */
25
+ private lastActions: Partial<Record<Action, bigint>> = {};
26
+
27
+ private logger: Logger;
28
+
22
29
  constructor(
23
30
  private sequencerConfig: SequencerClientConfig,
24
31
  private deps: {
@@ -31,9 +38,11 @@ export class SequencerPublisherFactory {
31
38
  governanceProposerContract: GovernanceProposerContract;
32
39
  slashFactoryContract: SlashFactoryContract;
33
40
  nodeKeyStore: NodeKeystoreAdapter;
41
+ logger?: Logger;
34
42
  },
35
43
  ) {
36
44
  this.publisherMetrics = new SequencerPublisherMetrics(deps.telemetry, 'SequencerPublisher');
45
+ this.logger = deps.logger ?? createLogger('sequencer');
37
46
  }
38
47
  /**
39
48
  * Creates a new SequencerPublisher instance.
@@ -69,6 +78,8 @@ export class SequencerPublisherFactory {
69
78
  slashFactoryContract: this.deps.slashFactoryContract,
70
79
  dateProvider: this.deps.dateProvider,
71
80
  metrics: this.publisherMetrics,
81
+ lastActions: this.lastActions,
82
+ log: this.logger.createChild('publisher'),
72
83
  });
73
84
 
74
85
  return {
@@ -1,4 +1,4 @@
1
- import { createLogger } from '@aztec/aztec.js';
1
+ import { createLogger } from '@aztec/aztec.js/log';
2
2
  import type { L1PublishBlockStats, L1PublishStats } from '@aztec/stdlib/stats';
3
3
  import {
4
4
  Attributes,