@aztec/sequencer-client 0.43.0 → 0.44.0

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.
@@ -2,6 +2,7 @@ import { type L1ToL2MessageSource, type L2BlockSource } from '@aztec/circuit-typ
2
2
  import { type BlockProver } from '@aztec/circuit-types/interfaces';
3
3
  import { type P2P } from '@aztec/p2p';
4
4
  import { type SimulationProvider } from '@aztec/simulator';
5
+ import { type TelemetryClient } from '@aztec/telemetry-client';
5
6
  import { type ContractDataSource } from '@aztec/types/contracts';
6
7
  import { type WorldStateSynchronizer } from '@aztec/world-state';
7
8
  import { type SequencerClientConfig } from '../config.js';
@@ -24,7 +25,7 @@ export declare class SequencerClient {
24
25
  * @param simulationProvider - An instance of a simulation provider
25
26
  * @returns A new running instance.
26
27
  */
27
- static new(config: SequencerClientConfig, p2pClient: P2P, worldStateSynchronizer: WorldStateSynchronizer, contractDataSource: ContractDataSource, l2BlockSource: L2BlockSource, l1ToL2MessageSource: L1ToL2MessageSource, prover: BlockProver, simulationProvider: SimulationProvider): Promise<SequencerClient>;
28
+ static new(config: SequencerClientConfig, p2pClient: P2P, worldStateSynchronizer: WorldStateSynchronizer, contractDataSource: ContractDataSource, l2BlockSource: L2BlockSource, l1ToL2MessageSource: L1ToL2MessageSource, prover: BlockProver, simulationProvider: SimulationProvider, telemetryClient: TelemetryClient): Promise<SequencerClient>;
28
29
  /**
29
30
  * Updates sequencer config.
30
31
  * @param config - New parameters.
@@ -1 +1 @@
1
- {"version":3,"file":"sequencer-client.d.ts","sourceRoot":"","sources":["../../src/client/sequencer-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,mBAAmB,EAAE,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACpF,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAA0B,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACnF,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAEjE,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAG1D,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAGxE;;GAEG;AACH,qBAAa,eAAe;IACd,OAAO,CAAC,SAAS;gBAAT,SAAS,EAAE,SAAS;IAExC;;;;;;;;;;;OAWG;WACiB,GAAG,CACrB,MAAM,EAAE,qBAAqB,EAC7B,SAAS,EAAE,GAAG,EACd,sBAAsB,EAAE,sBAAsB,EAC9C,kBAAkB,EAAE,kBAAkB,EACtC,aAAa,EAAE,aAAa,EAC5B,mBAAmB,EAAE,mBAAmB,EACxC,MAAM,EAAE,WAAW,EACnB,kBAAkB,EAAE,kBAAkB;IAyBxC;;;OAGG;IACI,qBAAqB,CAAC,MAAM,EAAE,eAAe;IAIpD;;OAEG;IACU,IAAI;IAIjB;;OAEG;IACI,OAAO;IAId,IAAI,QAAQ,yCAEX;IAED,IAAI,YAAY,2CAEf;CACF"}
1
+ {"version":3,"file":"sequencer-client.d.ts","sourceRoot":"","sources":["../../src/client/sequencer-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,mBAAmB,EAAE,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACpF,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAA0B,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACnF,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,KAAK,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAEjE,OAAO,EAAE,KAAK,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAG1D,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAGxE;;GAEG;AACH,qBAAa,eAAe;IACd,OAAO,CAAC,SAAS;gBAAT,SAAS,EAAE,SAAS;IAExC;;;;;;;;;;;OAWG;WACiB,GAAG,CACrB,MAAM,EAAE,qBAAqB,EAC7B,SAAS,EAAE,GAAG,EACd,sBAAsB,EAAE,sBAAsB,EAC9C,kBAAkB,EAAE,kBAAkB,EACtC,aAAa,EAAE,aAAa,EAC5B,mBAAmB,EAAE,mBAAmB,EACxC,MAAM,EAAE,WAAW,EACnB,kBAAkB,EAAE,kBAAkB,EACtC,eAAe,EAAE,eAAe;IA+BlC;;;OAGG;IACI,qBAAqB,CAAC,MAAM,EAAE,eAAe;IAIpD;;OAEG;IACU,IAAI;IAIjB;;OAEG;IACI,OAAO;IAId,IAAI,QAAQ,yCAEX;IAED,IAAI,YAAY,2CAEf;CACF"}
@@ -22,12 +22,12 @@ export class SequencerClient {
22
22
  * @param simulationProvider - An instance of a simulation provider
23
23
  * @returns A new running instance.
24
24
  */
25
- static async new(config, p2pClient, worldStateSynchronizer, contractDataSource, l2BlockSource, l1ToL2MessageSource, prover, simulationProvider) {
25
+ static async new(config, p2pClient, worldStateSynchronizer, contractDataSource, l2BlockSource, l1ToL2MessageSource, prover, simulationProvider, telemetryClient) {
26
26
  const publisher = getL1Publisher(config);
27
27
  const globalsBuilder = getGlobalVariableBuilder(config);
28
28
  const merkleTreeDb = worldStateSynchronizer.getLatest();
29
- const publicProcessorFactory = new PublicProcessorFactory(merkleTreeDb, contractDataSource, simulationProvider);
30
- const sequencer = new Sequencer(publisher, globalsBuilder, p2pClient, worldStateSynchronizer, prover, l2BlockSource, l1ToL2MessageSource, publicProcessorFactory, new TxValidatorFactory(merkleTreeDb, contractDataSource, !!config.enforceFees), config);
29
+ const publicProcessorFactory = new PublicProcessorFactory(merkleTreeDb, contractDataSource, simulationProvider, telemetryClient);
30
+ const sequencer = new Sequencer(publisher, globalsBuilder, p2pClient, worldStateSynchronizer, prover, l2BlockSource, l1ToL2MessageSource, publicProcessorFactory, new TxValidatorFactory(merkleTreeDb, contractDataSource, !!config.enforceFees), telemetryClient, config);
31
31
  await sequencer.start();
32
32
  return new SequencerClient(sequencer);
33
33
  }
@@ -57,4 +57,4 @@ export class SequencerClient {
57
57
  return this.sequencer.feeRecipient;
58
58
  }
59
59
  }
60
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VxdWVuY2VyLWNsaWVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbGllbnQvc2VxdWVuY2VyLWNsaWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFHQSxPQUFPLEVBQUUsc0JBQXNCLEVBQTJCLE1BQU0sa0JBQWtCLENBQUM7QUFLbkYsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDL0UsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxTQUFTLEVBQXdCLE1BQU0sdUJBQXVCLENBQUM7QUFDeEUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFFN0U7O0dBRUc7QUFDSCxNQUFNLE9BQU8sZUFBZTtJQUMxQixZQUFvQixTQUFvQjtRQUFwQixjQUFTLEdBQVQsU0FBUyxDQUFXO0lBQUcsQ0FBQztJQUU1Qzs7Ozs7Ozs7Ozs7T0FXRztJQUNJLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUNyQixNQUE2QixFQUM3QixTQUFjLEVBQ2Qsc0JBQThDLEVBQzlDLGtCQUFzQyxFQUN0QyxhQUE0QixFQUM1QixtQkFBd0MsRUFDeEMsTUFBbUIsRUFDbkIsa0JBQXNDO1FBRXRDLE1BQU0sU0FBUyxHQUFHLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN6QyxNQUFNLGNBQWMsR0FBRyx3QkFBd0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN4RCxNQUFNLFlBQVksR0FBRyxzQkFBc0IsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUV4RCxNQUFNLHNCQUFzQixHQUFHLElBQUksc0JBQXNCLENBQUMsWUFBWSxFQUFFLGtCQUFrQixFQUFFLGtCQUFrQixDQUFDLENBQUM7UUFFaEgsTUFBTSxTQUFTLEdBQUcsSUFBSSxTQUFTLENBQzdCLFNBQVMsRUFDVCxjQUFjLEVBQ2QsU0FBUyxFQUNULHNCQUFzQixFQUN0QixNQUFNLEVBQ04sYUFBYSxFQUNiLG1CQUFtQixFQUNuQixzQkFBc0IsRUFDdEIsSUFBSSxrQkFBa0IsQ0FBQyxZQUFZLEVBQUUsa0JBQWtCLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUMsRUFDOUUsTUFBTSxDQUNQLENBQUM7UUFFRixNQUFNLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUN4QixPQUFPLElBQUksZUFBZSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3hDLENBQUM7SUFFRDs7O09BR0c7SUFDSSxxQkFBcUIsQ0FBQyxNQUF1QjtRQUNsRCxJQUFJLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN0QyxDQUFDO0lBRUQ7O09BRUc7SUFDSSxLQUFLLENBQUMsSUFBSTtRQUNmLE1BQU0sSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUM5QixDQUFDO0lBRUQ7O09BRUc7SUFDSSxPQUFPO1FBQ1osSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBRUQsSUFBSSxRQUFRO1FBQ1YsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQztJQUNqQyxDQUFDO0lBRUQsSUFBSSxZQUFZO1FBQ2QsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQztJQUNyQyxDQUFDO0NBQ0YifQ==
60
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VxdWVuY2VyLWNsaWVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbGllbnQvc2VxdWVuY2VyLWNsaWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFHQSxPQUFPLEVBQUUsc0JBQXNCLEVBQTJCLE1BQU0sa0JBQWtCLENBQUM7QUFNbkYsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDL0UsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxTQUFTLEVBQXdCLE1BQU0sdUJBQXVCLENBQUM7QUFDeEUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFFN0U7O0dBRUc7QUFDSCxNQUFNLE9BQU8sZUFBZTtJQUMxQixZQUFvQixTQUFvQjtRQUFwQixjQUFTLEdBQVQsU0FBUyxDQUFXO0lBQUcsQ0FBQztJQUU1Qzs7Ozs7Ozs7Ozs7T0FXRztJQUNJLE1BQU0sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUNyQixNQUE2QixFQUM3QixTQUFjLEVBQ2Qsc0JBQThDLEVBQzlDLGtCQUFzQyxFQUN0QyxhQUE0QixFQUM1QixtQkFBd0MsRUFDeEMsTUFBbUIsRUFDbkIsa0JBQXNDLEVBQ3RDLGVBQWdDO1FBRWhDLE1BQU0sU0FBUyxHQUFHLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN6QyxNQUFNLGNBQWMsR0FBRyx3QkFBd0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN4RCxNQUFNLFlBQVksR0FBRyxzQkFBc0IsQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUV4RCxNQUFNLHNCQUFzQixHQUFHLElBQUksc0JBQXNCLENBQ3ZELFlBQVksRUFDWixrQkFBa0IsRUFDbEIsa0JBQWtCLEVBQ2xCLGVBQWUsQ0FDaEIsQ0FBQztRQUVGLE1BQU0sU0FBUyxHQUFHLElBQUksU0FBUyxDQUM3QixTQUFTLEVBQ1QsY0FBYyxFQUNkLFNBQVMsRUFDVCxzQkFBc0IsRUFDdEIsTUFBTSxFQUNOLGFBQWEsRUFDYixtQkFBbUIsRUFDbkIsc0JBQXNCLEVBQ3RCLElBQUksa0JBQWtCLENBQUMsWUFBWSxFQUFFLGtCQUFrQixFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLEVBQzlFLGVBQWUsRUFDZixNQUFNLENBQ1AsQ0FBQztRQUVGLE1BQU0sU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3hCLE9BQU8sSUFBSSxlQUFlLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDeEMsQ0FBQztJQUVEOzs7T0FHRztJQUNJLHFCQUFxQixDQUFDLE1BQXVCO1FBQ2xELElBQUksQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3RDLENBQUM7SUFFRDs7T0FFRztJQUNJLEtBQUssQ0FBQyxJQUFJO1FBQ2YsTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQzlCLENBQUM7SUFFRDs7T0FFRztJQUNJLE9BQU87UUFDWixJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQzNCLENBQUM7SUFFRCxJQUFJLFFBQVE7UUFDVixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDO0lBQ2pDLENBQUM7SUFFRCxJQUFJLFlBQVk7UUFDZCxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFDO0lBQ3JDLENBQUM7Q0FDRiJ9
@@ -4,6 +4,7 @@ import { AztecAddress, EthAddress, type Proof } from '@aztec/circuits.js';
4
4
  import { Fr } from '@aztec/foundation/fields';
5
5
  import { type P2P } from '@aztec/p2p';
6
6
  import { type PublicProcessorFactory } from '@aztec/simulator';
7
+ import { type TelemetryClient, type Tracer } from '@aztec/telemetry-client';
7
8
  import { type WorldStateSynchronizer } from '@aztec/world-state';
8
9
  import { type GlobalVariableBuilder } from '../global_variable_builder/global_builder.js';
9
10
  import { type L1Publisher } from '../publisher/l1-publisher.js';
@@ -40,7 +41,8 @@ export declare class Sequencer {
40
41
  private allowedInSetup;
41
42
  private allowedInTeardown;
42
43
  private maxBlockSizeInBytes;
43
- constructor(publisher: L1Publisher, globalsBuilder: GlobalVariableBuilder, p2pClient: P2P, worldState: WorldStateSynchronizer, prover: BlockProver, l2BlockSource: L2BlockSource, l1ToL2MessageSource: L1ToL2MessageSource, publicProcessorFactory: PublicProcessorFactory, txValidatorFactory: TxValidatorFactory, config?: SequencerConfig, log?: import("@aztec/foundation/log").Logger);
44
+ readonly tracer: Tracer;
45
+ constructor(publisher: L1Publisher, globalsBuilder: GlobalVariableBuilder, p2pClient: P2P, worldState: WorldStateSynchronizer, prover: BlockProver, l2BlockSource: L2BlockSource, l1ToL2MessageSource: L1ToL2MessageSource, publicProcessorFactory: PublicProcessorFactory, txValidatorFactory: TxValidatorFactory, telemetry: TelemetryClient, config?: SequencerConfig, log?: import("@aztec/foundation/log").Logger);
44
46
  /**
45
47
  * Updates sequencer config.
46
48
  * @param config - New parameters.
@@ -70,6 +72,7 @@ export declare class Sequencer {
70
72
  * Grabs up to maxTxsPerBlock from the p2p client, constructs a block, and pushes it to L1.
71
73
  */
72
74
  protected work(): Promise<void>;
75
+ private buildBlockAndPublish;
73
76
  /**
74
77
  * Publishes the L2Block to the rollup contract.
75
78
  * @param block - The L2Block to be published.
@@ -1 +1 @@
1
- {"version":3,"file":"sequencer.d.ts","sourceRoot":"","sources":["../../src/sequencer/sequencer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sequencer.d.ts","sourceRoot":"","sources":["../../src/sequencer/sequencer.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { __esDecorate, __runInitializers } from "tslib";
1
2
  import { Tx, } from '@aztec/circuit-types';
2
3
  import { BlockProofError, PROVING_STATUS, } from '@aztec/circuit-types/interfaces';
3
4
  import { AztecAddress, EthAddress } from '@aztec/circuits.js';
@@ -5,6 +6,7 @@ import { Fr } from '@aztec/foundation/fields';
5
6
  import { createDebugLogger } from '@aztec/foundation/log';
6
7
  import { RunningPromise } from '@aztec/foundation/running-promise';
7
8
  import { Timer, elapsed } from '@aztec/foundation/timer';
9
+ import { Attributes, trackSpan } from '@aztec/telemetry-client';
8
10
  /**
9
11
  * Sequencer client
10
12
  * - Wins a period of time to become the sequencer (depending on finalized protocol).
@@ -14,281 +16,300 @@ import { Timer, elapsed } from '@aztec/foundation/timer';
14
16
  * - Receives results to those proofs from the network (repeats as necessary) (not for this milestone).
15
17
  * - Publishes L1 tx(s) to the rollup contract via RollupPublisher.
16
18
  */
17
- export class Sequencer {
18
- constructor(publisher, globalsBuilder, p2pClient, worldState, prover, l2BlockSource, l1ToL2MessageSource, publicProcessorFactory, txValidatorFactory, config = {}, log = createDebugLogger('aztec:sequencer')) {
19
- this.publisher = publisher;
20
- this.globalsBuilder = globalsBuilder;
21
- this.p2pClient = p2pClient;
22
- this.worldState = worldState;
23
- this.prover = prover;
24
- this.l2BlockSource = l2BlockSource;
25
- this.l1ToL2MessageSource = l1ToL2MessageSource;
26
- this.publicProcessorFactory = publicProcessorFactory;
27
- this.txValidatorFactory = txValidatorFactory;
28
- this.log = log;
29
- this.pollingIntervalMs = 1000;
30
- this.maxTxsPerBlock = 32;
31
- this.minTxsPerBLock = 1;
32
- // TODO: zero values should not be allowed for the following 2 values in PROD
33
- this._coinbase = EthAddress.ZERO;
34
- this._feeRecipient = AztecAddress.ZERO;
35
- this.lastPublishedBlock = 0;
36
- this.state = SequencerState.STOPPED;
37
- this.allowedInSetup = [];
38
- this.allowedInTeardown = [];
39
- this.maxBlockSizeInBytes = 1024 * 1024;
40
- this.updateConfig(config);
41
- this.log.verbose(`Initialized sequencer with ${this.minTxsPerBLock}-${this.maxTxsPerBlock} txs per block.`);
42
- }
43
- /**
44
- * Updates sequencer config.
45
- * @param config - New parameters.
46
- */
47
- updateConfig(config) {
48
- if (config.transactionPollingIntervalMS) {
49
- this.pollingIntervalMs = config.transactionPollingIntervalMS;
50
- }
51
- if (config.maxTxsPerBlock) {
52
- this.maxTxsPerBlock = config.maxTxsPerBlock;
53
- }
54
- if (config.minTxsPerBlock) {
55
- this.minTxsPerBLock = config.minTxsPerBlock;
56
- }
57
- if (config.coinbase) {
58
- this._coinbase = config.coinbase;
59
- }
60
- if (config.feeRecipient) {
61
- this._feeRecipient = config.feeRecipient;
62
- }
63
- if (config.allowedInSetup) {
64
- this.allowedInSetup = config.allowedInSetup;
65
- }
66
- if (config.maxBlockSizeInBytes) {
67
- this.maxBlockSizeInBytes = config.maxBlockSizeInBytes;
68
- }
69
- // TODO(#5917) remove this. it is no longer needed since we don't need to whitelist functions in teardown
70
- if (config.allowedInTeardown) {
71
- this.allowedInTeardown = config.allowedInTeardown;
72
- }
73
- }
74
- /**
75
- * Starts the sequencer and moves to IDLE state. Blocks until the initial sync is complete.
76
- */
77
- async start() {
78
- await this.initialSync();
79
- this.runningPromise = new RunningPromise(this.work.bind(this), this.pollingIntervalMs);
80
- this.runningPromise.start();
81
- this.state = SequencerState.IDLE;
82
- this.log.info('Sequencer started');
83
- }
84
- /**
85
- * Stops the sequencer from processing txs and moves to STOPPED state.
86
- */
87
- async stop() {
88
- this.log.debug(`Stopping sequencer`);
89
- await this.runningPromise?.stop();
90
- this.publisher.interrupt();
91
- this.state = SequencerState.STOPPED;
92
- this.log.info('Stopped sequencer');
93
- }
94
- /**
95
- * Starts a previously stopped sequencer.
96
- */
97
- restart() {
98
- this.log.info('Restarting sequencer');
99
- this.publisher.restart();
100
- this.runningPromise.start();
101
- this.state = SequencerState.IDLE;
102
- }
103
- /**
104
- * Returns the current state of the sequencer.
105
- * @returns An object with a state entry with one of SequencerState.
106
- */
107
- status() {
108
- return { state: this.state };
109
- }
110
- async initialSync() {
111
- // TODO: Should we wait for world state to be ready, or is the caller expected to run await start?
112
- this.lastPublishedBlock = await this.worldState.status().then((s) => s.syncedToL2Block);
113
- }
114
- /**
115
- * Grabs up to maxTxsPerBlock from the p2p client, constructs a block, and pushes it to L1.
116
- */
117
- async work() {
118
- try {
119
- // Update state when the previous block has been synced
120
- const prevBlockSynced = await this.isBlockSynced();
121
- if (prevBlockSynced && this.state === SequencerState.PUBLISHING_BLOCK) {
122
- this.log.debug(`Block has been synced`);
19
+ let Sequencer = (() => {
20
+ var _a;
21
+ let _instanceExtraInitializers = [];
22
+ let _buildBlockAndPublish_decorators;
23
+ let _publishL2Block_decorators;
24
+ return _a = class Sequencer {
25
+ constructor(publisher, globalsBuilder, p2pClient, worldState, prover, l2BlockSource, l1ToL2MessageSource, publicProcessorFactory, txValidatorFactory, telemetry, config = {}, log = createDebugLogger('aztec:sequencer')) {
26
+ this.publisher = (__runInitializers(this, _instanceExtraInitializers), publisher);
27
+ this.globalsBuilder = globalsBuilder;
28
+ this.p2pClient = p2pClient;
29
+ this.worldState = worldState;
30
+ this.prover = prover;
31
+ this.l2BlockSource = l2BlockSource;
32
+ this.l1ToL2MessageSource = l1ToL2MessageSource;
33
+ this.publicProcessorFactory = publicProcessorFactory;
34
+ this.txValidatorFactory = txValidatorFactory;
35
+ this.log = log;
36
+ this.pollingIntervalMs = 1000;
37
+ this.maxTxsPerBlock = 32;
38
+ this.minTxsPerBLock = 1;
39
+ // TODO: zero values should not be allowed for the following 2 values in PROD
40
+ this._coinbase = EthAddress.ZERO;
41
+ this._feeRecipient = AztecAddress.ZERO;
42
+ this.lastPublishedBlock = 0;
43
+ this.state = SequencerState.STOPPED;
44
+ this.allowedInSetup = [];
45
+ this.allowedInTeardown = [];
46
+ this.maxBlockSizeInBytes = 1024 * 1024;
47
+ this.updateConfig(config);
48
+ this.tracer = telemetry.getTracer('Sequencer');
49
+ this.log.verbose(`Initialized sequencer with ${this.minTxsPerBLock}-${this.maxTxsPerBlock} txs per block.`);
50
+ }
51
+ /**
52
+ * Updates sequencer config.
53
+ * @param config - New parameters.
54
+ */
55
+ updateConfig(config) {
56
+ if (config.transactionPollingIntervalMS) {
57
+ this.pollingIntervalMs = config.transactionPollingIntervalMS;
58
+ }
59
+ if (config.maxTxsPerBlock) {
60
+ this.maxTxsPerBlock = config.maxTxsPerBlock;
61
+ }
62
+ if (config.minTxsPerBlock) {
63
+ this.minTxsPerBLock = config.minTxsPerBlock;
64
+ }
65
+ if (config.coinbase) {
66
+ this._coinbase = config.coinbase;
67
+ }
68
+ if (config.feeRecipient) {
69
+ this._feeRecipient = config.feeRecipient;
70
+ }
71
+ if (config.allowedInSetup) {
72
+ this.allowedInSetup = config.allowedInSetup;
73
+ }
74
+ if (config.maxBlockSizeInBytes) {
75
+ this.maxBlockSizeInBytes = config.maxBlockSizeInBytes;
76
+ }
77
+ // TODO(#5917) remove this. it is no longer needed since we don't need to whitelist functions in teardown
78
+ if (config.allowedInTeardown) {
79
+ this.allowedInTeardown = config.allowedInTeardown;
80
+ }
81
+ }
82
+ /**
83
+ * Starts the sequencer and moves to IDLE state. Blocks until the initial sync is complete.
84
+ */
85
+ async start() {
86
+ await this.initialSync();
87
+ this.runningPromise = new RunningPromise(this.work.bind(this), this.pollingIntervalMs);
88
+ this.runningPromise.start();
123
89
  this.state = SequencerState.IDLE;
90
+ this.log.info('Sequencer started');
124
91
  }
125
- // Do not go forward with new block if the previous one has not been mined and processed
126
- if (!prevBlockSynced) {
127
- return;
92
+ /**
93
+ * Stops the sequencer from processing txs and moves to STOPPED state.
94
+ */
95
+ async stop() {
96
+ this.log.debug(`Stopping sequencer`);
97
+ await this.runningPromise?.stop();
98
+ this.publisher.interrupt();
99
+ this.state = SequencerState.STOPPED;
100
+ this.log.info('Stopped sequencer');
128
101
  }
129
- const historicalHeader = (await this.l2BlockSource.getBlock(-1))?.header;
130
- const newBlockNumber = (historicalHeader === undefined
131
- ? await this.l2BlockSource.getBlockNumber()
132
- : Number(historicalHeader.globalVariables.blockNumber.toBigInt())) + 1;
133
- // Do not go forward with new block if not my turn
134
- if (!(await this.publisher.isItMyTurnToSubmit(newBlockNumber))) {
135
- this.log.verbose('Not my turn to submit block');
136
- return;
102
+ /**
103
+ * Starts a previously stopped sequencer.
104
+ */
105
+ restart() {
106
+ this.log.info('Restarting sequencer');
107
+ this.publisher.restart();
108
+ this.runningPromise.start();
109
+ this.state = SequencerState.IDLE;
137
110
  }
138
- const workTimer = new Timer();
139
- this.state = SequencerState.WAITING_FOR_TXS;
140
- // Get txs to build the new block
141
- const pendingTxs = await this.p2pClient.getTxs();
142
- if (pendingTxs.length < this.minTxsPerBLock) {
143
- return;
111
+ /**
112
+ * Returns the current state of the sequencer.
113
+ * @returns An object with a state entry with one of SequencerState.
114
+ */
115
+ status() {
116
+ return { state: this.state };
117
+ }
118
+ async initialSync() {
119
+ // TODO: Should we wait for world state to be ready, or is the caller expected to run await start?
120
+ this.lastPublishedBlock = await this.worldState.status().then((s) => s.syncedToL2Block);
144
121
  }
145
- this.log.debug(`Retrieved ${pendingTxs.length} txs from P2P pool`);
146
122
  /**
147
- * We'll call this function before running expensive operations to avoid wasted work.
123
+ * Grabs up to maxTxsPerBlock from the p2p client, constructs a block, and pushes it to L1.
148
124
  */
149
- const assertBlockHeight = async () => {
150
- const currentBlockNumber = await this.l2BlockSource.getBlockNumber();
151
- if (currentBlockNumber + 1 !== newBlockNumber) {
152
- throw new Error('New block was emitted while building block');
125
+ async work() {
126
+ try {
127
+ // Update state when the previous block has been synced
128
+ const prevBlockSynced = await this.isBlockSynced();
129
+ if (prevBlockSynced && this.state === SequencerState.PUBLISHING_BLOCK) {
130
+ this.log.debug(`Block has been synced`);
131
+ this.state = SequencerState.IDLE;
132
+ }
133
+ // Do not go forward with new block if the previous one has not been mined and processed
134
+ if (!prevBlockSynced) {
135
+ return;
136
+ }
137
+ const historicalHeader = (await this.l2BlockSource.getBlock(-1))?.header;
138
+ const newBlockNumber = (historicalHeader === undefined
139
+ ? await this.l2BlockSource.getBlockNumber()
140
+ : Number(historicalHeader.globalVariables.blockNumber.toBigInt())) + 1;
141
+ // Do not go forward with new block if not my turn
142
+ if (!(await this.publisher.isItMyTurnToSubmit(newBlockNumber))) {
143
+ this.log.verbose('Not my turn to submit block');
144
+ return;
145
+ }
146
+ this.state = SequencerState.WAITING_FOR_TXS;
147
+ // Get txs to build the new block
148
+ const pendingTxs = await this.p2pClient.getTxs();
149
+ if (pendingTxs.length < this.minTxsPerBLock) {
150
+ return;
151
+ }
152
+ this.log.debug(`Retrieved ${pendingTxs.length} txs from P2P pool`);
153
+ const newGlobalVariables = await this.globalsBuilder.buildGlobalVariables(new Fr(newBlockNumber), this._coinbase, this._feeRecipient);
154
+ // TODO: It should be responsibility of the P2P layer to validate txs before passing them on here
155
+ const allValidTxs = await this.takeValidTxs(pendingTxs, this.txValidatorFactory.validatorForNewTxs(newGlobalVariables, this.allowedInSetup));
156
+ // TODO: We are taking the size of the tx from private-land, but we should be doing this after running
157
+ // public functions. Only reason why we do it here now is because the public processor and orchestrator
158
+ // are set up such that they require knowing the total number of txs in advance. Still, main reason for
159
+ // exceeding max block size in bytes is contract class registration, which happens in private-land. This
160
+ // may break if we start emitting lots of log data from public-land.
161
+ const validTxs = this.takeTxsWithinMaxSize(allValidTxs);
162
+ if (validTxs.length < this.minTxsPerBLock) {
163
+ return;
164
+ }
165
+ await this.buildBlockAndPublish(validTxs, newGlobalVariables, historicalHeader);
153
166
  }
154
- if (!(await this.publisher.isItMyTurnToSubmit(newBlockNumber))) {
155
- throw new Error(`Not this sequencer turn to submit block`);
167
+ catch (err) {
168
+ if (BlockProofError.isBlockProofError(err)) {
169
+ const txHashes = err.txHashes.filter(h => !h.isZero());
170
+ this.log.warn(`Proving block failed, removing ${txHashes.length} txs from pool`);
171
+ await this.p2pClient.deleteTxs(txHashes);
172
+ }
173
+ this.log.error(`Rolling back world state DB due to error assembling block`, err.stack);
174
+ // Cancel any further proving on the block
175
+ this.prover?.cancelBlock();
176
+ await this.worldState.getLatest().rollback();
156
177
  }
157
- };
158
- const newGlobalVariables = await this.globalsBuilder.buildGlobalVariables(new Fr(newBlockNumber), this._coinbase, this._feeRecipient);
159
- // TODO: It should be responsibility of the P2P layer to validate txs before passing them on here
160
- const allValidTxs = await this.takeValidTxs(pendingTxs, this.txValidatorFactory.validatorForNewTxs(newGlobalVariables, this.allowedInSetup));
161
- // TODO: We are taking the size of the tx from private-land, but we should be doing this after running
162
- // public functions. Only reason why we do it here now is because the public processor and orchestrator
163
- // are set up such that they require knowing the total number of txs in advance. Still, main reason for
164
- // exceeding max block size in bytes is contract class registration, which happens in private-land. This
165
- // may break if we start emitting lots of log data from public-land.
166
- const validTxs = this.takeTxsWithinMaxSize(allValidTxs);
167
- if (validTxs.length < this.minTxsPerBLock) {
168
- return;
169
178
  }
170
- this.log.info(`Building block ${newBlockNumber} with ${validTxs.length} transactions`);
171
- this.state = SequencerState.CREATING_BLOCK;
172
- // Get l1 to l2 messages from the contract
173
- this.log.debug('Requesting L1 to L2 messages from contract');
174
- const l1ToL2Messages = await this.l1ToL2MessageSource.getL1ToL2Messages(BigInt(newBlockNumber));
175
- this.log.verbose(`Retrieved ${l1ToL2Messages.length} L1 to L2 messages for block ${newBlockNumber}`);
176
- // We create a fresh processor each time to reset any cached state (eg storage writes)
177
- const processor = await this.publicProcessorFactory.create(historicalHeader, newGlobalVariables);
178
- const blockBuildingTimer = new Timer();
179
- // We must initialise the block to be a power of 2 in size
180
- const numRealTxs = validTxs.length;
181
- const pow2 = Math.log2(numRealTxs);
182
- // TODO turn this back into a Math.ceil once we can pad blocks to the next-power-of-2 with empty txs
183
- const totalTxs = 2 ** Math.ceil(pow2);
184
- const blockSize = Math.max(2, totalTxs);
185
- const blockTicket = await this.prover.startNewBlock(blockSize, newGlobalVariables, l1ToL2Messages);
186
- const [publicProcessorDuration, [processedTxs, failedTxs]] = await elapsed(() => processor.process(validTxs, blockSize, this.prover, this.txValidatorFactory.validatorForProcessedTxs()));
187
- if (failedTxs.length > 0) {
188
- const failedTxData = failedTxs.map(fail => fail.tx);
189
- this.log.debug(`Dropping failed txs ${Tx.getHashes(failedTxData).join(', ')}`);
190
- await this.p2pClient.deleteTxs(Tx.getHashes(failedTxData));
179
+ async buildBlockAndPublish(validTxs, newGlobalVariables, historicalHeader) {
180
+ const workTimer = new Timer();
181
+ this.state = SequencerState.CREATING_BLOCK;
182
+ this.log.info(`Building block ${newGlobalVariables.blockNumber.toNumber()} with ${validTxs.length} transactions`);
183
+ const assertBlockHeight = async () => {
184
+ const currentBlockNumber = await this.l2BlockSource.getBlockNumber();
185
+ if (currentBlockNumber + 1 !== newGlobalVariables.blockNumber.toNumber()) {
186
+ throw new Error('New block was emitted while building block');
187
+ }
188
+ if (!(await this.publisher.isItMyTurnToSubmit(newGlobalVariables.blockNumber.toNumber()))) {
189
+ throw new Error(`Not this sequencer turn to submit block`);
190
+ }
191
+ };
192
+ // Get l1 to l2 messages from the contract
193
+ this.log.debug('Requesting L1 to L2 messages from contract');
194
+ const l1ToL2Messages = await this.l1ToL2MessageSource.getL1ToL2Messages(newGlobalVariables.blockNumber.toBigInt());
195
+ this.log.verbose(`Retrieved ${l1ToL2Messages.length} L1 to L2 messages for block ${newGlobalVariables.blockNumber.toNumber()}`);
196
+ // We create a fresh processor each time to reset any cached state (eg storage writes)
197
+ const processor = await this.publicProcessorFactory.create(historicalHeader, newGlobalVariables);
198
+ const numRealTxs = validTxs.length;
199
+ const pow2 = Math.log2(numRealTxs);
200
+ const totalTxs = 2 ** Math.ceil(pow2);
201
+ const blockSize = Math.max(2, totalTxs);
202
+ const blockBuildingTimer = new Timer();
203
+ const blockTicket = await this.prover.startNewBlock(blockSize, newGlobalVariables, l1ToL2Messages);
204
+ const [publicProcessorDuration, [processedTxs, failedTxs]] = await elapsed(() => processor.process(validTxs, blockSize, this.prover, this.txValidatorFactory.validatorForProcessedTxs()));
205
+ if (failedTxs.length > 0) {
206
+ const failedTxData = failedTxs.map(fail => fail.tx);
207
+ this.log.debug(`Dropping failed txs ${Tx.getHashes(failedTxData).join(', ')}`);
208
+ await this.p2pClient.deleteTxs(Tx.getHashes(failedTxData));
209
+ }
210
+ if (processedTxs.length === 0) {
211
+ this.log.verbose('No txs processed correctly to build block. Exiting');
212
+ this.prover.cancelBlock();
213
+ return;
214
+ }
215
+ await assertBlockHeight();
216
+ // All real transactions have been added, set the block as full and complete the proving.
217
+ await this.prover.setBlockCompleted();
218
+ // Here we are now waiting for the block to be proven.
219
+ // TODO(@PhilWindle) We should probably periodically check for things like another
220
+ // block being published before ours instead of just waiting on our block
221
+ const result = await blockTicket.provingPromise;
222
+ if (result.status === PROVING_STATUS.FAILURE) {
223
+ throw new Error(`Block proving failed, reason: ${result.reason}`);
224
+ }
225
+ await assertBlockHeight();
226
+ // Block is proven, now finalise and publish!
227
+ const { block, aggregationObject, proof } = await this.prover.finaliseBlock();
228
+ await assertBlockHeight();
229
+ this.log.verbose(`Assembled block ${block.number}`, {
230
+ eventName: 'l2-block-built',
231
+ duration: workTimer.ms(),
232
+ publicProcessDuration: publicProcessorDuration,
233
+ rollupCircuitsDuration: blockBuildingTimer.ms(),
234
+ ...block.getStats(),
235
+ });
236
+ await this.publishL2Block(block, aggregationObject, proof);
237
+ this.log.info(`Submitted rollup block ${block.number} with ${processedTxs.length} transactions`);
191
238
  }
192
- if (processedTxs.length === 0) {
193
- this.log.verbose('No txs processed correctly to build block. Exiting');
194
- this.prover.cancelBlock();
195
- return;
239
+ /**
240
+ * Publishes the L2Block to the rollup contract.
241
+ * @param block - The L2Block to be published.
242
+ */
243
+ async publishL2Block(block, aggregationObject, proof) {
244
+ // Publishes new block to the network and awaits the tx to be mined
245
+ this.state = SequencerState.PUBLISHING_BLOCK;
246
+ const publishedL2Block = await this.publisher.processL2Block(block, aggregationObject, proof);
247
+ if (publishedL2Block) {
248
+ this.lastPublishedBlock = block.number;
249
+ }
250
+ else {
251
+ throw new Error(`Failed to publish block`);
252
+ }
196
253
  }
197
- await assertBlockHeight();
198
- // All real transactions have been added, set the block as full and complete the proving.
199
- await this.prover.setBlockCompleted();
200
- // Here we are now waiting for the block to be proven.
201
- // TODO(@PhilWindle) We should probably periodically check for things like another
202
- // block being published before ours instead of just waiting on our block
203
- const result = await blockTicket.provingPromise;
204
- if (result.status === PROVING_STATUS.FAILURE) {
205
- throw new Error(`Block proving failed, reason: ${result.reason}`);
254
+ async takeValidTxs(txs, validator) {
255
+ const [valid, invalid] = await validator.validateTxs(txs);
256
+ if (invalid.length > 0) {
257
+ this.log.debug(`Dropping invalid txs from the p2p pool ${Tx.getHashes(invalid).join(', ')}`);
258
+ await this.p2pClient.deleteTxs(Tx.getHashes(invalid));
259
+ }
260
+ return valid.slice(0, this.maxTxsPerBlock);
206
261
  }
207
- await assertBlockHeight();
208
- // Block is proven, now finalise and publish!
209
- const { block, aggregationObject, proof } = await this.prover.finaliseBlock();
210
- await assertBlockHeight();
211
- this.log.verbose(`Assembled block ${block.number}`, {
212
- eventName: 'l2-block-built',
213
- duration: workTimer.ms(),
214
- publicProcessDuration: publicProcessorDuration,
215
- rollupCircuitsDuration: blockBuildingTimer.ms(),
216
- ...block.getStats(),
217
- });
218
- await this.publishL2Block(block, aggregationObject, proof);
219
- this.log.info(`Submitted rollup block ${block.number} with ${processedTxs.length} transactions`);
220
- }
221
- catch (err) {
222
- if (BlockProofError.isBlockProofError(err)) {
223
- const txHashes = err.txHashes.filter(h => !h.isZero());
224
- this.log.warn(`Proving block failed, removing ${txHashes.length} txs from pool`);
225
- await this.p2pClient.deleteTxs(txHashes);
262
+ takeTxsWithinMaxSize(txs) {
263
+ const maxSize = this.maxBlockSizeInBytes;
264
+ let totalSize = 0;
265
+ const toReturn = [];
266
+ for (const tx of txs) {
267
+ const txSize = tx.getSize() - tx.proof.toBuffer().length;
268
+ if (totalSize + txSize > maxSize) {
269
+ this.log.warn(`Dropping tx ${tx.getTxHash()} with estimated size ${txSize} due to exceeding ${maxSize} block size limit (currently at ${totalSize})`);
270
+ continue;
271
+ }
272
+ toReturn.push(tx);
273
+ totalSize += txSize;
274
+ }
275
+ return toReturn;
226
276
  }
227
- this.log.error(`Rolling back world state DB due to error assembling block`, err.stack);
228
- // Cancel any further proving on the block
229
- this.prover?.cancelBlock();
230
- await this.worldState.getLatest().rollback();
231
- }
232
- }
233
- /**
234
- * Publishes the L2Block to the rollup contract.
235
- * @param block - The L2Block to be published.
236
- */
237
- async publishL2Block(block, aggregationObject, proof) {
238
- // Publishes new block to the network and awaits the tx to be mined
239
- this.state = SequencerState.PUBLISHING_BLOCK;
240
- const publishedL2Block = await this.publisher.processL2Block(block, aggregationObject, proof);
241
- if (publishedL2Block) {
242
- this.lastPublishedBlock = block.number;
243
- }
244
- else {
245
- throw new Error(`Failed to publish block`);
246
- }
247
- }
248
- async takeValidTxs(txs, validator) {
249
- const [valid, invalid] = await validator.validateTxs(txs);
250
- if (invalid.length > 0) {
251
- this.log.debug(`Dropping invalid txs from the p2p pool ${Tx.getHashes(invalid).join(', ')}`);
252
- await this.p2pClient.deleteTxs(Tx.getHashes(invalid));
253
- }
254
- return valid.slice(0, this.maxTxsPerBlock);
255
- }
256
- takeTxsWithinMaxSize(txs) {
257
- const maxSize = this.maxBlockSizeInBytes;
258
- let totalSize = 0;
259
- const toReturn = [];
260
- for (const tx of txs) {
261
- const txSize = tx.getSize() - tx.proof.toBuffer().length;
262
- if (totalSize + txSize > maxSize) {
263
- this.log.warn(`Dropping tx ${tx.getTxHash()} with estimated size ${txSize} due to exceeding ${maxSize} block size limit (currently at ${totalSize})`);
264
- continue;
277
+ /**
278
+ * Returns whether the previous block sent has been mined, and all dependencies have caught up with it.
279
+ * @returns Boolean indicating if our dependencies are synced to the latest block.
280
+ */
281
+ async isBlockSynced() {
282
+ const syncedBlocks = await Promise.all([
283
+ this.worldState.status().then((s) => s.syncedToL2Block),
284
+ this.p2pClient.getStatus().then(s => s.syncedToL2Block),
285
+ this.l2BlockSource.getBlockNumber(),
286
+ this.l1ToL2MessageSource.getBlockNumber(),
287
+ ]);
288
+ const min = Math.min(...syncedBlocks);
289
+ return min >= this.lastPublishedBlock;
265
290
  }
266
- toReturn.push(tx);
267
- totalSize += txSize;
268
- }
269
- return toReturn;
270
- }
271
- /**
272
- * Returns whether the previous block sent has been mined, and all dependencies have caught up with it.
273
- * @returns Boolean indicating if our dependencies are synced to the latest block.
274
- */
275
- async isBlockSynced() {
276
- const syncedBlocks = await Promise.all([
277
- this.worldState.status().then((s) => s.syncedToL2Block),
278
- this.p2pClient.getStatus().then(s => s.syncedToL2Block),
279
- this.l2BlockSource.getBlockNumber(),
280
- this.l1ToL2MessageSource.getBlockNumber(),
281
- ]);
282
- const min = Math.min(...syncedBlocks);
283
- return min >= this.lastPublishedBlock;
284
- }
285
- get coinbase() {
286
- return this._coinbase;
287
- }
288
- get feeRecipient() {
289
- return this._feeRecipient;
290
- }
291
- }
291
+ get coinbase() {
292
+ return this._coinbase;
293
+ }
294
+ get feeRecipient() {
295
+ return this._feeRecipient;
296
+ }
297
+ },
298
+ (() => {
299
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
300
+ _buildBlockAndPublish_decorators = [trackSpan('Sequencer.buildBlockAndPublish', (_validTxs, newGlobalVariables, _historicalHeader) => ({
301
+ [Attributes.BLOCK_NUMBER]: newGlobalVariables.blockNumber.toNumber(),
302
+ }))];
303
+ _publishL2Block_decorators = [trackSpan('Sequencer.publishL2Block', block => ({
304
+ [Attributes.BLOCK_NUMBER]: block.number,
305
+ }))];
306
+ __esDecorate(_a, null, _buildBlockAndPublish_decorators, { kind: "method", name: "buildBlockAndPublish", static: false, private: false, access: { has: obj => "buildBlockAndPublish" in obj, get: obj => obj.buildBlockAndPublish }, metadata: _metadata }, null, _instanceExtraInitializers);
307
+ __esDecorate(_a, null, _publishL2Block_decorators, { kind: "method", name: "publishL2Block", static: false, private: false, access: { has: obj => "publishL2Block" in obj, get: obj => obj.publishL2Block }, metadata: _metadata }, null, _instanceExtraInitializers);
308
+ if (_metadata) Object.defineProperty(_a, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
309
+ })(),
310
+ _a;
311
+ })();
312
+ export { Sequencer };
292
313
  /**
293
314
  * State of the sequencer.
294
315
  */
@@ -319,4 +340,4 @@ export var SequencerState;
319
340
  */
320
341
  SequencerState[SequencerState["STOPPED"] = 5] = "STOPPED";
321
342
  })(SequencerState || (SequencerState = {}));
322
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VxdWVuY2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlcXVlbmNlci9zZXF1ZW5jZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUtMLEVBQUUsR0FFSCxNQUFNLHNCQUFzQixDQUFDO0FBQzlCLE9BQU8sRUFFTCxlQUFlLEVBRWYsY0FBYyxHQUNmLE1BQU0saUNBQWlDLENBQUM7QUFFekMsT0FBTyxFQUFFLFlBQVksRUFBRSxVQUFVLEVBQWMsTUFBTSxvQkFBb0IsQ0FBQztBQUMxRSxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDOUMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDMUQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQ25FLE9BQU8sRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFVekQ7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLE9BQU8sU0FBUztJQWNwQixZQUNVLFNBQXNCLEVBQ3RCLGNBQXFDLEVBQ3JDLFNBQWMsRUFDZCxVQUFrQyxFQUNsQyxNQUFtQixFQUNuQixhQUE0QixFQUM1QixtQkFBd0MsRUFDeEMsc0JBQThDLEVBQzlDLGtCQUFzQyxFQUM5QyxTQUEwQixFQUFFLEVBQ3BCLE1BQU0saUJBQWlCLENBQUMsaUJBQWlCLENBQUM7UUFWMUMsY0FBUyxHQUFULFNBQVMsQ0FBYTtRQUN0QixtQkFBYyxHQUFkLGNBQWMsQ0FBdUI7UUFDckMsY0FBUyxHQUFULFNBQVMsQ0FBSztRQUNkLGVBQVUsR0FBVixVQUFVLENBQXdCO1FBQ2xDLFdBQU0sR0FBTixNQUFNLENBQWE7UUFDbkIsa0JBQWEsR0FBYixhQUFhLENBQWU7UUFDNUIsd0JBQW1CLEdBQW5CLG1CQUFtQixDQUFxQjtRQUN4QywyQkFBc0IsR0FBdEIsc0JBQXNCLENBQXdCO1FBQzlDLHVCQUFrQixHQUFsQixr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
343
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VxdWVuY2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlcXVlbmNlci9zZXF1ZW5jZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFLTCxFQUFFLEdBRUgsTUFBTSxzQkFBc0IsQ0FBQztBQUM5QixPQUFPLEVBRUwsZUFBZSxFQUVmLGNBQWMsR0FDZixNQUFNLGlDQUFpQyxDQUFDO0FBRXpDLE9BQU8sRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFpRCxNQUFNLG9CQUFvQixDQUFDO0FBQzdHLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUM5QyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDbkUsT0FBTyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUd6RCxPQUFPLEVBQUUsVUFBVSxFQUFxQyxTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQVFuRzs7Ozs7Ozs7R0FRRztJQUNVLFNBQVM7Ozs7O3NCQUFULFNBQVM7WUFnQnBCLFlBQ1UsU0FBc0IsRUFDdEIsY0FBcUMsRUFDckMsU0FBYyxFQUNkLFVBQWtDLEVBQ2xDLE1BQW1CLEVBQ25CLGFBQTRCLEVBQzVCLG1CQUF3QyxFQUN4QyxzQkFBOEMsRUFDOUMsa0JBQXNDLEVBQzlDLFNBQTBCLEVBQzFCLFNBQTBCLEVBQUUsRUFDcEIsTUFBTSxpQkFBaUIsQ0FBQyxpQkFBaUIsQ0FBQztnQkFYMUMsY0FBUyxJQWpCUixtREFBUyxFQWlCVixTQUFTLEVBQWE7Z0JBQ3RCLG1CQUFjLEdBQWQsY0FBYyxDQUF1QjtnQkFDckMsY0FBUyxHQUFULFNBQVMsQ0FBSztnQkFDZCxlQUFVLEdBQVYsVUFBVSxDQUF3QjtnQkFDbEMsV0FBTSxHQUFOLE1BQU0sQ0FBYTtnQkFDbkIsa0JBQWEsR0FBYixh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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/sequencer-client",
3
- "version": "0.43.0",
3
+ "version": "0.44.0",
4
4
  "type": "module",
5
5
  "exports": "./dest/index.js",
6
6
  "typedocOptions": {
@@ -24,19 +24,20 @@
24
24
  "test:integration:run": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --no-cache --config jest.integration.config.json"
25
25
  },
26
26
  "dependencies": {
27
- "@aztec/circuit-types": "0.43.0",
28
- "@aztec/circuits.js": "0.43.0",
29
- "@aztec/ethereum": "0.43.0",
30
- "@aztec/foundation": "0.43.0",
31
- "@aztec/l1-artifacts": "0.43.0",
32
- "@aztec/merkle-tree": "0.43.0",
33
- "@aztec/noir-contracts.js": "0.43.0",
34
- "@aztec/noir-protocol-circuits-types": "0.43.0",
35
- "@aztec/p2p": "0.43.0",
36
- "@aztec/protocol-contracts": "0.43.0",
37
- "@aztec/simulator": "0.43.0",
38
- "@aztec/types": "0.43.0",
39
- "@aztec/world-state": "0.43.0",
27
+ "@aztec/circuit-types": "0.44.0",
28
+ "@aztec/circuits.js": "0.44.0",
29
+ "@aztec/ethereum": "0.44.0",
30
+ "@aztec/foundation": "0.44.0",
31
+ "@aztec/l1-artifacts": "0.44.0",
32
+ "@aztec/merkle-tree": "0.44.0",
33
+ "@aztec/noir-contracts.js": "0.44.0",
34
+ "@aztec/noir-protocol-circuits-types": "0.44.0",
35
+ "@aztec/p2p": "0.44.0",
36
+ "@aztec/protocol-contracts": "0.44.0",
37
+ "@aztec/simulator": "0.44.0",
38
+ "@aztec/telemetry-client": "0.44.0",
39
+ "@aztec/types": "0.44.0",
40
+ "@aztec/world-state": "0.44.0",
40
41
  "@noir-lang/acvm_js": "portal:../../noir/packages/acvm_js",
41
42
  "@noir-lang/types": "portal:../../noir/packages/types",
42
43
  "lodash.chunk": "^4.2.0",
@@ -78,7 +79,15 @@
78
79
  ],
79
80
  "transform": {
80
81
  "^.+\\.tsx?$": [
81
- "@swc/jest"
82
+ "@swc/jest",
83
+ {
84
+ "jsc": {
85
+ "parser": {
86
+ "syntax": "typescript",
87
+ "decorators": true
88
+ }
89
+ }
90
+ }
82
91
  ]
83
92
  },
84
93
  "moduleNameMapper": {
@@ -2,6 +2,7 @@ import { type L1ToL2MessageSource, type L2BlockSource } from '@aztec/circuit-typ
2
2
  import { type BlockProver } from '@aztec/circuit-types/interfaces';
3
3
  import { type P2P } from '@aztec/p2p';
4
4
  import { PublicProcessorFactory, type SimulationProvider } from '@aztec/simulator';
5
+ import { type TelemetryClient } from '@aztec/telemetry-client';
5
6
  import { type ContractDataSource } from '@aztec/types/contracts';
6
7
  import { type WorldStateSynchronizer } from '@aztec/world-state';
7
8
 
@@ -38,12 +39,18 @@ export class SequencerClient {
38
39
  l1ToL2MessageSource: L1ToL2MessageSource,
39
40
  prover: BlockProver,
40
41
  simulationProvider: SimulationProvider,
42
+ telemetryClient: TelemetryClient,
41
43
  ) {
42
44
  const publisher = getL1Publisher(config);
43
45
  const globalsBuilder = getGlobalVariableBuilder(config);
44
46
  const merkleTreeDb = worldStateSynchronizer.getLatest();
45
47
 
46
- const publicProcessorFactory = new PublicProcessorFactory(merkleTreeDb, contractDataSource, simulationProvider);
48
+ const publicProcessorFactory = new PublicProcessorFactory(
49
+ merkleTreeDb,
50
+ contractDataSource,
51
+ simulationProvider,
52
+ telemetryClient,
53
+ );
47
54
 
48
55
  const sequencer = new Sequencer(
49
56
  publisher,
@@ -55,6 +62,7 @@ export class SequencerClient {
55
62
  l1ToL2MessageSource,
56
63
  publicProcessorFactory,
57
64
  new TxValidatorFactory(merkleTreeDb, contractDataSource, !!config.enforceFees),
65
+ telemetryClient,
58
66
  config,
59
67
  );
60
68
 
@@ -13,13 +13,14 @@ import {
13
13
  PROVING_STATUS,
14
14
  } from '@aztec/circuit-types/interfaces';
15
15
  import { type L2BlockBuiltStats } from '@aztec/circuit-types/stats';
16
- import { AztecAddress, EthAddress, type Proof } from '@aztec/circuits.js';
16
+ import { AztecAddress, EthAddress, type GlobalVariables, type Header, type Proof } from '@aztec/circuits.js';
17
17
  import { Fr } from '@aztec/foundation/fields';
18
18
  import { createDebugLogger } from '@aztec/foundation/log';
19
19
  import { RunningPromise } from '@aztec/foundation/running-promise';
20
20
  import { Timer, elapsed } from '@aztec/foundation/timer';
21
21
  import { type P2P } from '@aztec/p2p';
22
22
  import { type PublicProcessorFactory } from '@aztec/simulator';
23
+ import { Attributes, type TelemetryClient, type Tracer, trackSpan } from '@aztec/telemetry-client';
23
24
  import { type WorldStateStatus, type WorldStateSynchronizer } from '@aztec/world-state';
24
25
 
25
26
  import { type GlobalVariableBuilder } from '../global_variable_builder/global_builder.js';
@@ -50,6 +51,8 @@ export class Sequencer {
50
51
  private allowedInTeardown: AllowedElement[] = [];
51
52
  private maxBlockSizeInBytes: number = 1024 * 1024;
52
53
 
54
+ public readonly tracer: Tracer;
55
+
53
56
  constructor(
54
57
  private publisher: L1Publisher,
55
58
  private globalsBuilder: GlobalVariableBuilder,
@@ -60,10 +63,12 @@ export class Sequencer {
60
63
  private l1ToL2MessageSource: L1ToL2MessageSource,
61
64
  private publicProcessorFactory: PublicProcessorFactory,
62
65
  private txValidatorFactory: TxValidatorFactory,
66
+ telemetry: TelemetryClient,
63
67
  config: SequencerConfig = {},
64
68
  private log = createDebugLogger('aztec:sequencer'),
65
69
  ) {
66
70
  this.updateConfig(config);
71
+ this.tracer = telemetry.getTracer('Sequencer');
67
72
  this.log.verbose(`Initialized sequencer with ${this.minTxsPerBLock}-${this.maxTxsPerBlock} txs per block.`);
68
73
  }
69
74
 
@@ -174,7 +179,6 @@ export class Sequencer {
174
179
  return;
175
180
  }
176
181
 
177
- const workTimer = new Timer();
178
182
  this.state = SequencerState.WAITING_FOR_TXS;
179
183
 
180
184
  // Get txs to build the new block
@@ -184,19 +188,6 @@ export class Sequencer {
184
188
  }
185
189
  this.log.debug(`Retrieved ${pendingTxs.length} txs from P2P pool`);
186
190
 
187
- /**
188
- * We'll call this function before running expensive operations to avoid wasted work.
189
- */
190
- const assertBlockHeight = async () => {
191
- const currentBlockNumber = await this.l2BlockSource.getBlockNumber();
192
- if (currentBlockNumber + 1 !== newBlockNumber) {
193
- throw new Error('New block was emitted while building block');
194
- }
195
- if (!(await this.publisher.isItMyTurnToSubmit(newBlockNumber))) {
196
- throw new Error(`Not this sequencer turn to submit block`);
197
- }
198
- };
199
-
200
191
  const newGlobalVariables = await this.globalsBuilder.buildGlobalVariables(
201
192
  new Fr(newBlockNumber),
202
193
  this._coinbase,
@@ -220,72 +211,7 @@ export class Sequencer {
220
211
  return;
221
212
  }
222
213
 
223
- this.log.info(`Building block ${newBlockNumber} with ${validTxs.length} transactions`);
224
- this.state = SequencerState.CREATING_BLOCK;
225
-
226
- // Get l1 to l2 messages from the contract
227
- this.log.debug('Requesting L1 to L2 messages from contract');
228
- const l1ToL2Messages = await this.l1ToL2MessageSource.getL1ToL2Messages(BigInt(newBlockNumber));
229
- this.log.verbose(`Retrieved ${l1ToL2Messages.length} L1 to L2 messages for block ${newBlockNumber}`);
230
-
231
- // We create a fresh processor each time to reset any cached state (eg storage writes)
232
- const processor = await this.publicProcessorFactory.create(historicalHeader, newGlobalVariables);
233
-
234
- const blockBuildingTimer = new Timer();
235
-
236
- // We must initialise the block to be a power of 2 in size
237
- const numRealTxs = validTxs.length;
238
- const pow2 = Math.log2(numRealTxs);
239
- // TODO turn this back into a Math.ceil once we can pad blocks to the next-power-of-2 with empty txs
240
- const totalTxs = 2 ** Math.ceil(pow2);
241
- const blockSize = Math.max(2, totalTxs);
242
- const blockTicket = await this.prover.startNewBlock(blockSize, newGlobalVariables, l1ToL2Messages);
243
-
244
- const [publicProcessorDuration, [processedTxs, failedTxs]] = await elapsed(() =>
245
- processor.process(validTxs, blockSize, this.prover, this.txValidatorFactory.validatorForProcessedTxs()),
246
- );
247
- if (failedTxs.length > 0) {
248
- const failedTxData = failedTxs.map(fail => fail.tx);
249
- this.log.debug(`Dropping failed txs ${Tx.getHashes(failedTxData).join(', ')}`);
250
- await this.p2pClient.deleteTxs(Tx.getHashes(failedTxData));
251
- }
252
-
253
- if (processedTxs.length === 0) {
254
- this.log.verbose('No txs processed correctly to build block. Exiting');
255
- this.prover.cancelBlock();
256
- return;
257
- }
258
-
259
- await assertBlockHeight();
260
-
261
- // All real transactions have been added, set the block as full and complete the proving.
262
- await this.prover.setBlockCompleted();
263
-
264
- // Here we are now waiting for the block to be proven.
265
- // TODO(@PhilWindle) We should probably periodically check for things like another
266
- // block being published before ours instead of just waiting on our block
267
- const result = await blockTicket.provingPromise;
268
- if (result.status === PROVING_STATUS.FAILURE) {
269
- throw new Error(`Block proving failed, reason: ${result.reason}`);
270
- }
271
-
272
- await assertBlockHeight();
273
-
274
- // Block is proven, now finalise and publish!
275
- const { block, aggregationObject, proof } = await this.prover.finaliseBlock();
276
-
277
- await assertBlockHeight();
278
-
279
- this.log.verbose(`Assembled block ${block.number}`, {
280
- eventName: 'l2-block-built',
281
- duration: workTimer.ms(),
282
- publicProcessDuration: publicProcessorDuration,
283
- rollupCircuitsDuration: blockBuildingTimer.ms(),
284
- ...block.getStats(),
285
- } satisfies L2BlockBuiltStats);
286
-
287
- await this.publishL2Block(block, aggregationObject, proof);
288
- this.log.info(`Submitted rollup block ${block.number} with ${processedTxs.length} transactions`);
214
+ await this.buildBlockAndPublish(validTxs, newGlobalVariables, historicalHeader);
289
215
  } catch (err) {
290
216
  if (BlockProofError.isBlockProofError(err)) {
291
217
  const txHashes = err.txHashes.filter(h => !h.isZero());
@@ -299,10 +225,100 @@ export class Sequencer {
299
225
  }
300
226
  }
301
227
 
228
+ @trackSpan('Sequencer.buildBlockAndPublish', (_validTxs, newGlobalVariables, _historicalHeader) => ({
229
+ [Attributes.BLOCK_NUMBER]: newGlobalVariables.blockNumber.toNumber(),
230
+ }))
231
+ private async buildBlockAndPublish(
232
+ validTxs: Tx[],
233
+ newGlobalVariables: GlobalVariables,
234
+ historicalHeader: Header | undefined,
235
+ ): Promise<void> {
236
+ const workTimer = new Timer();
237
+ this.state = SequencerState.CREATING_BLOCK;
238
+ this.log.info(`Building block ${newGlobalVariables.blockNumber.toNumber()} with ${validTxs.length} transactions`);
239
+
240
+ const assertBlockHeight = async () => {
241
+ const currentBlockNumber = await this.l2BlockSource.getBlockNumber();
242
+ if (currentBlockNumber + 1 !== newGlobalVariables.blockNumber.toNumber()) {
243
+ throw new Error('New block was emitted while building block');
244
+ }
245
+ if (!(await this.publisher.isItMyTurnToSubmit(newGlobalVariables.blockNumber.toNumber()))) {
246
+ throw new Error(`Not this sequencer turn to submit block`);
247
+ }
248
+ };
249
+
250
+ // Get l1 to l2 messages from the contract
251
+ this.log.debug('Requesting L1 to L2 messages from contract');
252
+ const l1ToL2Messages = await this.l1ToL2MessageSource.getL1ToL2Messages(newGlobalVariables.blockNumber.toBigInt());
253
+ this.log.verbose(
254
+ `Retrieved ${l1ToL2Messages.length} L1 to L2 messages for block ${newGlobalVariables.blockNumber.toNumber()}`,
255
+ );
256
+
257
+ // We create a fresh processor each time to reset any cached state (eg storage writes)
258
+ const processor = await this.publicProcessorFactory.create(historicalHeader, newGlobalVariables);
259
+
260
+ const numRealTxs = validTxs.length;
261
+ const pow2 = Math.log2(numRealTxs);
262
+ const totalTxs = 2 ** Math.ceil(pow2);
263
+ const blockSize = Math.max(2, totalTxs);
264
+
265
+ const blockBuildingTimer = new Timer();
266
+ const blockTicket = await this.prover.startNewBlock(blockSize, newGlobalVariables, l1ToL2Messages);
267
+
268
+ const [publicProcessorDuration, [processedTxs, failedTxs]] = await elapsed(() =>
269
+ processor.process(validTxs, blockSize, this.prover, this.txValidatorFactory.validatorForProcessedTxs()),
270
+ );
271
+ if (failedTxs.length > 0) {
272
+ const failedTxData = failedTxs.map(fail => fail.tx);
273
+ this.log.debug(`Dropping failed txs ${Tx.getHashes(failedTxData).join(', ')}`);
274
+ await this.p2pClient.deleteTxs(Tx.getHashes(failedTxData));
275
+ }
276
+
277
+ if (processedTxs.length === 0) {
278
+ this.log.verbose('No txs processed correctly to build block. Exiting');
279
+ this.prover.cancelBlock();
280
+ return;
281
+ }
282
+
283
+ await assertBlockHeight();
284
+
285
+ // All real transactions have been added, set the block as full and complete the proving.
286
+ await this.prover.setBlockCompleted();
287
+
288
+ // Here we are now waiting for the block to be proven.
289
+ // TODO(@PhilWindle) We should probably periodically check for things like another
290
+ // block being published before ours instead of just waiting on our block
291
+ const result = await blockTicket.provingPromise;
292
+ if (result.status === PROVING_STATUS.FAILURE) {
293
+ throw new Error(`Block proving failed, reason: ${result.reason}`);
294
+ }
295
+
296
+ await assertBlockHeight();
297
+
298
+ // Block is proven, now finalise and publish!
299
+ const { block, aggregationObject, proof } = await this.prover.finaliseBlock();
300
+
301
+ await assertBlockHeight();
302
+
303
+ this.log.verbose(`Assembled block ${block.number}`, {
304
+ eventName: 'l2-block-built',
305
+ duration: workTimer.ms(),
306
+ publicProcessDuration: publicProcessorDuration,
307
+ rollupCircuitsDuration: blockBuildingTimer.ms(),
308
+ ...block.getStats(),
309
+ } satisfies L2BlockBuiltStats);
310
+
311
+ await this.publishL2Block(block, aggregationObject, proof);
312
+ this.log.info(`Submitted rollup block ${block.number} with ${processedTxs.length} transactions`);
313
+ }
314
+
302
315
  /**
303
316
  * Publishes the L2Block to the rollup contract.
304
317
  * @param block - The L2Block to be published.
305
318
  */
319
+ @trackSpan('Sequencer.publishL2Block', block => ({
320
+ [Attributes.BLOCK_NUMBER]: block.number,
321
+ }))
306
322
  protected async publishL2Block(block: L2Block, aggregationObject: Fr[], proof: Proof) {
307
323
  // Publishes new block to the network and awaits the tx to be mined
308
324
  this.state = SequencerState.PUBLISHING_BLOCK;