@aztec/sequencer-client 0.72.1 → 0.74.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.
Files changed (70) hide show
  1. package/dest/client/sequencer-client.d.ts +11 -6
  2. package/dest/client/sequencer-client.d.ts.map +1 -1
  3. package/dest/client/sequencer-client.js +46 -10
  4. package/dest/config.d.ts +1 -1
  5. package/dest/config.d.ts.map +1 -1
  6. package/dest/config.js +3 -4
  7. package/dest/publisher/config.d.ts +5 -0
  8. package/dest/publisher/config.d.ts.map +1 -1
  9. package/dest/publisher/config.js +9 -2
  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 +2 -2
  13. package/dest/publisher/{l1-publisher-metrics.d.ts → sequencer-publisher-metrics.d.ts} +6 -2
  14. package/dest/publisher/sequencer-publisher-metrics.d.ts.map +1 -0
  15. package/dest/publisher/sequencer-publisher-metrics.js +111 -0
  16. package/dest/publisher/sequencer-publisher.d.ts +163 -0
  17. package/dest/publisher/sequencer-publisher.d.ts.map +1 -0
  18. package/dest/publisher/sequencer-publisher.js +528 -0
  19. package/dest/sequencer/allowed.d.ts +1 -1
  20. package/dest/sequencer/allowed.d.ts.map +1 -1
  21. package/dest/sequencer/allowed.js +4 -4
  22. package/dest/sequencer/metrics.d.ts +1 -1
  23. package/dest/sequencer/metrics.d.ts.map +1 -1
  24. package/dest/sequencer/metrics.js +3 -4
  25. package/dest/sequencer/sequencer.d.ts +17 -10
  26. package/dest/sequencer/sequencer.d.ts.map +1 -1
  27. package/dest/sequencer/sequencer.js +103 -109
  28. package/dest/sequencer/utils.d.ts +1 -1
  29. package/dest/sequencer/utils.d.ts.map +1 -1
  30. package/dest/sequencer/utils.js +3 -3
  31. package/dest/slasher/factory.d.ts +2 -2
  32. package/dest/slasher/factory.d.ts.map +1 -1
  33. package/dest/slasher/factory.js +2 -2
  34. package/dest/slasher/slasher_client.d.ts +4 -4
  35. package/dest/slasher/slasher_client.d.ts.map +1 -1
  36. package/dest/slasher/slasher_client.js +38 -26
  37. package/dest/test/index.d.ts +3 -3
  38. package/dest/test/index.d.ts.map +1 -1
  39. package/dest/test/index.js +1 -2
  40. package/dest/tx_validator/gas_validator.d.ts.map +1 -1
  41. package/dest/tx_validator/gas_validator.js +4 -3
  42. package/dest/tx_validator/test_utils.d.ts +4 -4
  43. package/dest/tx_validator/test_utils.d.ts.map +1 -1
  44. package/dest/tx_validator/test_utils.js +3 -3
  45. package/package.json +21 -20
  46. package/src/client/sequencer-client.ts +81 -14
  47. package/src/config.ts +3 -3
  48. package/src/publisher/config.ts +13 -1
  49. package/src/publisher/index.ts +1 -1
  50. package/src/publisher/{l1-publisher-metrics.ts → sequencer-publisher-metrics.ts} +41 -2
  51. package/src/publisher/sequencer-publisher.ts +710 -0
  52. package/src/sequencer/allowed.ts +3 -3
  53. package/src/sequencer/metrics.ts +2 -3
  54. package/src/sequencer/sequencer.ts +138 -125
  55. package/src/sequencer/utils.ts +5 -2
  56. package/src/slasher/factory.ts +3 -3
  57. package/src/slasher/slasher_client.ts +44 -30
  58. package/src/test/index.ts +2 -4
  59. package/src/tx_validator/gas_validator.ts +5 -4
  60. package/src/tx_validator/test_utils.ts +5 -5
  61. package/dest/publisher/l1-publisher-metrics.d.ts.map +0 -1
  62. package/dest/publisher/l1-publisher-metrics.js +0 -85
  63. package/dest/publisher/l1-publisher.d.ts +0 -195
  64. package/dest/publisher/l1-publisher.d.ts.map +0 -1
  65. package/dest/publisher/l1-publisher.js +0 -930
  66. package/dest/test/test-l1-publisher.d.ts +0 -9
  67. package/dest/test/test-l1-publisher.d.ts.map +0 -1
  68. package/dest/test/test-l1-publisher.js +0 -11
  69. package/src/publisher/l1-publisher.ts +0 -1288
  70. package/src/test/test-l1-publisher.ts +0 -20
@@ -10,7 +10,7 @@ import { INITIAL_L2_BLOCK_NUM } from '@aztec/circuits.js/constants';
10
10
  import { type L1ContractsConfig, type L1ReaderConfig, createEthereumChain } from '@aztec/ethereum';
11
11
  import { EthAddress } from '@aztec/foundation/eth-address';
12
12
  import { createLogger } from '@aztec/foundation/log';
13
- import { type AztecKVStore, type AztecMap, type AztecSingleton } from '@aztec/kv-store';
13
+ import type { AztecAsyncKVStore, AztecAsyncMap, AztecAsyncSingleton } from '@aztec/kv-store';
14
14
  import { SlashFactoryAbi } from '@aztec/l1-artifacts';
15
15
  import { type TelemetryClient, WithTracer, getTelemetryClient } from '@aztec/telemetry-client';
16
16
 
@@ -92,9 +92,9 @@ export class SlasherClient extends WithTracer {
92
92
  private latestBlockNumberAtStart = -1;
93
93
  private provenBlockNumberAtStart = -1;
94
94
 
95
- private synchedBlockHashes: AztecMap<number, string>;
96
- private synchedLatestBlockNumber: AztecSingleton<number>;
97
- private synchedProvenBlockNumber: AztecSingleton<number>;
95
+ private synchedBlockHashes: AztecAsyncMap<number, string>;
96
+ private synchedLatestBlockNumber: AztecAsyncSingleton<number>;
97
+ private synchedProvenBlockNumber: AztecAsyncSingleton<number>;
98
98
 
99
99
  private blockStream;
100
100
 
@@ -110,7 +110,7 @@ export class SlasherClient extends WithTracer {
110
110
 
111
111
  constructor(
112
112
  private config: SlasherConfig & L1ContractsConfig & L1ReaderConfig,
113
- private store: AztecKVStore,
113
+ private store: AztecAsyncKVStore,
114
114
  private l2BlockSource: L2BlockSource,
115
115
  telemetry: TelemetryClient = getTelemetryClient(),
116
116
  private log = createLogger('slasher'),
@@ -178,17 +178,17 @@ export class SlasherClient extends WithTracer {
178
178
  }
179
179
 
180
180
  public getL2BlockHash(number: number): Promise<string | undefined> {
181
- return Promise.resolve(this.synchedBlockHashes.get(number));
181
+ return this.synchedBlockHashes.getAsync(number);
182
182
  }
183
183
 
184
- public getL2Tips(): Promise<L2Tips> {
185
- const latestBlockNumber = this.getSyncedLatestBlockNum();
184
+ public async getL2Tips(): Promise<L2Tips> {
185
+ const latestBlockNumber = await this.getSyncedLatestBlockNum();
186
186
  let latestBlockHash: string | undefined;
187
- const provenBlockNumber = this.getSyncedProvenBlockNum();
187
+ const provenBlockNumber = await this.getSyncedProvenBlockNum();
188
188
  let provenBlockHash: string | undefined;
189
189
 
190
190
  if (latestBlockNumber > 0) {
191
- latestBlockHash = this.synchedBlockHashes.get(latestBlockNumber);
191
+ latestBlockHash = await this.synchedBlockHashes.getAsync(latestBlockNumber);
192
192
  if (typeof latestBlockHash === 'undefined') {
193
193
  this.log.warn(`Block hash for latest block ${latestBlockNumber} not found`);
194
194
  throw new Error();
@@ -196,7 +196,7 @@ export class SlasherClient extends WithTracer {
196
196
  }
197
197
 
198
198
  if (provenBlockNumber > 0) {
199
- provenBlockHash = this.synchedBlockHashes.get(provenBlockNumber);
199
+ provenBlockHash = await this.synchedBlockHashes.getAsync(provenBlockNumber);
200
200
  if (typeof provenBlockHash === 'undefined') {
201
201
  this.log.warn(`Block hash for proven block ${provenBlockNumber} not found`);
202
202
  throw new Error();
@@ -220,7 +220,7 @@ export class SlasherClient extends WithTracer {
220
220
  // TODO (alexg): I think we can prune the block hashes map here
221
221
  break;
222
222
  case 'chain-proven': {
223
- const from = this.getSyncedProvenBlockNum() + 1;
223
+ const from = (await this.getSyncedProvenBlockNum()) + 1;
224
224
  const limit = event.blockNumber - from + 1;
225
225
  await this.handleProvenL2Blocks(await this.l2BlockSource.getBlocks(from, limit));
226
226
  break;
@@ -247,8 +247,8 @@ export class SlasherClient extends WithTracer {
247
247
  this.latestBlockNumberAtStart = await this.l2BlockSource.getBlockNumber();
248
248
  this.provenBlockNumberAtStart = await this.l2BlockSource.getProvenBlockNumber();
249
249
 
250
- const syncedLatestBlock = this.getSyncedLatestBlockNum() + 1;
251
- const syncedProvenBlock = this.getSyncedProvenBlockNum() + 1;
250
+ const syncedLatestBlock = (await this.getSyncedLatestBlockNum()) + 1;
251
+ const syncedProvenBlock = (await this.getSyncedProvenBlockNum()) + 1;
252
252
 
253
253
  // if there are blocks to be retrieved, go to a synching state
254
254
  if (syncedLatestBlock <= this.latestBlockNumberAtStart || syncedProvenBlock <= this.provenBlockNumberAtStart) {
@@ -278,6 +278,8 @@ export class SlasherClient extends WithTracer {
278
278
  this.log.debug('Stopping Slasher client...');
279
279
  await this.blockStream.stop();
280
280
  this.log.debug('Stopped block downloader');
281
+ await this.store.close();
282
+ this.log.debug('Stopped slasher store');
281
283
  this.setCurrentState(SlasherClientState.STOPPED);
282
284
  this.log.info('Slasher client stopped.');
283
285
  }
@@ -294,16 +296,16 @@ export class SlasherClient extends WithTracer {
294
296
  * Public function to check the latest block number that the slasher client is synced to.
295
297
  * @returns Block number of latest L2 Block we've synced with.
296
298
  */
297
- public getSyncedLatestBlockNum() {
298
- return this.synchedLatestBlockNumber.get() ?? INITIAL_L2_BLOCK_NUM - 1;
299
+ public async getSyncedLatestBlockNum(): Promise<number> {
300
+ return (await this.synchedLatestBlockNumber.getAsync()) ?? INITIAL_L2_BLOCK_NUM - 1;
299
301
  }
300
302
 
301
303
  /**
302
304
  * Public function to check the latest proven block number that the slasher client is synced to.
303
305
  * @returns Block number of latest proven L2 Block we've synced with.
304
306
  */
305
- public getSyncedProvenBlockNum() {
306
- return this.synchedProvenBlockNumber.get() ?? INITIAL_L2_BLOCK_NUM - 1;
307
+ public async getSyncedProvenBlockNum(): Promise<number> {
308
+ return (await this.synchedProvenBlockNumber.getAsync()) ?? INITIAL_L2_BLOCK_NUM - 1;
307
309
  }
308
310
 
309
311
  /**
@@ -311,11 +313,14 @@ export class SlasherClient extends WithTracer {
311
313
  * @returns Information about slasher client status: state & syncedToBlockNum.
312
314
  */
313
315
  public async getStatus(): Promise<SlasherSyncState> {
314
- const blockNumber = this.getSyncedLatestBlockNum();
316
+ const blockNumber = await this.getSyncedLatestBlockNum();
315
317
  const blockHash =
316
318
  blockNumber == 0
317
319
  ? ''
318
- : await this.l2BlockSource.getBlockHeader(blockNumber).then(header => header?.hash().toString());
320
+ : await this.l2BlockSource
321
+ .getBlockHeader(blockNumber)
322
+ .then(header => header?.hash())
323
+ .then(hash => hash?.toString());
319
324
  return Promise.resolve({
320
325
  state: this.currentState,
321
326
  syncedToL2Block: { number: blockNumber, hash: blockHash },
@@ -329,14 +334,19 @@ export class SlasherClient extends WithTracer {
329
334
  */
330
335
  private async handleLatestL2Blocks(blocks: L2Block[]): Promise<void> {
331
336
  if (!blocks.length) {
332
- return Promise.resolve();
337
+ return;
333
338
  }
334
339
 
335
- const lastBlockNum = blocks[blocks.length - 1].number;
336
- await Promise.all(blocks.map(block => this.synchedBlockHashes.set(block.number, block.hash().toString())));
337
- await this.synchedLatestBlockNumber.set(lastBlockNum);
338
- this.log.debug(`Synched to latest block ${lastBlockNum}`);
339
- this.startServiceIfSynched();
340
+ await this.store.transactionAsync(async () => {
341
+ for (const block of blocks) {
342
+ await this.synchedBlockHashes.set(block.number, (await block.hash()).toString());
343
+ }
344
+
345
+ const lastBlockNum = blocks[blocks.length - 1].number;
346
+ await this.synchedLatestBlockNumber.set(lastBlockNum);
347
+ });
348
+
349
+ await this.startServiceIfSynched();
340
350
  }
341
351
 
342
352
  /**
@@ -352,7 +362,7 @@ export class SlasherClient extends WithTracer {
352
362
  await this.synchedProvenBlockNumber.set(lastBlockNum);
353
363
  this.log.debug(`Synched to proven block ${lastBlockNum}`);
354
364
 
355
- this.startServiceIfSynched();
365
+ await this.startServiceIfSynched();
356
366
  }
357
367
 
358
368
  private async handlePruneL2Blocks(latestBlock: number): Promise<void> {
@@ -376,11 +386,15 @@ export class SlasherClient extends WithTracer {
376
386
  await this.synchedLatestBlockNumber.set(latestBlock);
377
387
  }
378
388
 
379
- private startServiceIfSynched() {
389
+ private async startServiceIfSynched() {
390
+ const [latestBlock, provenBlock] = await Promise.all([
391
+ this.getSyncedLatestBlockNum(),
392
+ this.getSyncedProvenBlockNum(),
393
+ ]);
380
394
  if (
381
395
  this.currentState === SlasherClientState.SYNCHING &&
382
- this.getSyncedLatestBlockNum() >= this.latestBlockNumberAtStart &&
383
- this.getSyncedProvenBlockNum() >= this.provenBlockNumberAtStart
396
+ latestBlock >= this.latestBlockNumberAtStart &&
397
+ provenBlock >= this.provenBlockNumberAtStart
384
398
  ) {
385
399
  this.log.debug(`Synched to blocks at start`);
386
400
  this.setCurrentState(SlasherClientState.RUNNING);
package/src/test/index.ts CHANGED
@@ -1,14 +1,14 @@
1
1
  import { type PublicProcessorFactory } from '@aztec/simulator/server';
2
2
 
3
3
  import { SequencerClient } from '../client/sequencer-client.js';
4
- import { type L1Publisher } from '../publisher/l1-publisher.js';
4
+ import { type SequencerPublisher } from '../publisher/sequencer-publisher.js';
5
5
  import { Sequencer } from '../sequencer/sequencer.js';
6
6
  import { type SequencerTimetable } from '../sequencer/timetable.js';
7
7
 
8
8
  class TestSequencer_ extends Sequencer {
9
9
  public override publicProcessorFactory!: PublicProcessorFactory;
10
10
  public override timetable!: SequencerTimetable;
11
- public override publisher!: L1Publisher;
11
+ public override publisher!: SequencerPublisher;
12
12
  }
13
13
 
14
14
  export type TestSequencer = TestSequencer_;
@@ -18,5 +18,3 @@ class TestSequencerClient_ extends SequencerClient {
18
18
  }
19
19
 
20
20
  export type TestSequencerClient = TestSequencerClient_;
21
-
22
- export * from './test-l1-publisher.js';
@@ -74,20 +74,21 @@ export class GasTxValidator implements TxValidator<Tx> {
74
74
  // Read current balance of the feePayer
75
75
  const initialBalance = await this.#publicDataSource.storageRead(
76
76
  this.#feeJuiceAddress,
77
- computeFeePayerBalanceStorageSlot(feePayer),
77
+ await computeFeePayerBalanceStorageSlot(feePayer),
78
78
  );
79
79
 
80
80
  // If there is a claim in this tx that increases the fee payer balance in Fee Juice, add it to balance
81
81
  const setupFns = getExecutionRequestsByPhase(tx, TxExecutionPhase.SETUP);
82
+ const increasePublicBalanceSelector = await FunctionSelector.fromSignature(
83
+ '_increase_public_balance((Field),(Field,Field))',
84
+ );
82
85
  const claimFunctionCall = setupFns.find(
83
86
  fn =>
84
87
  fn.callContext.contractAddress.equals(this.#feeJuiceAddress) &&
85
88
  fn.callContext.msgSender.equals(this.#feeJuiceAddress) &&
86
89
  fn.args.length > 2 &&
87
90
  // Public functions get routed through the dispatch function, whose first argument is the target function selector.
88
- fn.args[0].equals(
89
- FunctionSelector.fromSignature('_increase_public_balance((Field),(Field,Field))').toField(),
90
- ) &&
91
+ fn.args[0].equals(increasePublicBalanceSelector.toField()) &&
91
92
  fn.args[1].equals(feePayer.toField()) &&
92
93
  !fn.callContext.isStaticCall,
93
94
  );
@@ -6,7 +6,7 @@ export function patchNonRevertibleFn(
6
6
  tx: Tx,
7
7
  index: number,
8
8
  overrides: { address?: AztecAddress; selector: FunctionSelector; args?: Fr[]; msgSender?: AztecAddress },
9
- ): { address: AztecAddress; selector: FunctionSelector } {
9
+ ): Promise<{ address: AztecAddress; selector: FunctionSelector }> {
10
10
  return patchFn('nonRevertibleAccumulatedData', tx, index, overrides);
11
11
  }
12
12
 
@@ -14,16 +14,16 @@ export function patchRevertibleFn(
14
14
  tx: Tx,
15
15
  index: number,
16
16
  overrides: { address?: AztecAddress; selector: FunctionSelector; args?: Fr[]; msgSender?: AztecAddress },
17
- ): { address: AztecAddress; selector: FunctionSelector } {
17
+ ): Promise<{ address: AztecAddress; selector: FunctionSelector }> {
18
18
  return patchFn('revertibleAccumulatedData', tx, index, overrides);
19
19
  }
20
20
 
21
- function patchFn(
21
+ async function patchFn(
22
22
  where: 'revertibleAccumulatedData' | 'nonRevertibleAccumulatedData',
23
23
  tx: Tx,
24
24
  index: number,
25
25
  overrides: { address?: AztecAddress; selector: FunctionSelector; args?: Fr[]; msgSender?: AztecAddress },
26
- ): { address: AztecAddress; selector: FunctionSelector } {
26
+ ): Promise<{ address: AztecAddress; selector: FunctionSelector }> {
27
27
  const fn = tx.enqueuedPublicFunctionCalls.at(-1 * index - 1)!;
28
28
  fn.callContext.contractAddress = overrides.address ?? fn.callContext.contractAddress;
29
29
  fn.callContext.functionSelector = overrides.selector;
@@ -36,7 +36,7 @@ function patchFn(
36
36
  request.msgSender = fn.callContext.msgSender;
37
37
  request.functionSelector = fn.callContext.functionSelector;
38
38
  request.isStaticCall = fn.callContext.isStaticCall;
39
- request.argsHash = computeVarArgsHash(fn.args);
39
+ request.argsHash = await computeVarArgsHash(fn.args);
40
40
  tx.data.forPublic![where].publicCallRequests[index] = request;
41
41
 
42
42
  return {
@@ -1 +0,0 @@
1
- {"version":3,"file":"l1-publisher-metrics.d.ts","sourceRoot":"","sources":["../../src/publisher/l1-publisher-metrics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC3G,OAAO,EAIL,KAAK,eAAe,EAGrB,MAAM,yBAAyB,CAAC;AAIjC,MAAM,MAAM,QAAQ,GAAG,aAAa,GAAG,SAAS,GAAG,sBAAsB,CAAC;AAE1E,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAY;IAE5B,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,UAAU,CAAY;IAC9B,OAAO,CAAC,KAAK,CAAY;IACzB,OAAO,CAAC,cAAc,CAAY;IAClC,OAAO,CAAC,aAAa,CAAY;IACjC,OAAO,CAAC,iBAAiB,CAAY;IACrC,OAAO,CAAC,iBAAiB,CAAY;gBAEzB,MAAM,EAAE,eAAe,EAAE,IAAI,SAAgB;IAkDzD,cAAc,CAAC,MAAM,EAAE,QAAQ;IAO/B,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB;IAIhE,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB;IAInE,4BAA4B,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc;IAItE,OAAO,CAAC,QAAQ;CA6BjB"}
@@ -1,85 +0,0 @@
1
- import { Attributes, Metrics, ValueType, } from '@aztec/telemetry-client';
2
- import { formatEther } from 'viem/utils';
3
- export class L1PublisherMetrics {
4
- constructor(client, name = 'L1Publisher') {
5
- const meter = client.getMeter(name);
6
- this.gasPrice = meter.createHistogram(Metrics.L1_PUBLISHER_GAS_PRICE, {
7
- description: 'The gas price used for transactions',
8
- unit: 'gwei',
9
- valueType: ValueType.DOUBLE,
10
- });
11
- this.txCount = meter.createUpDownCounter(Metrics.L1_PUBLISHER_TX_COUNT, {
12
- description: 'The number of transactions processed',
13
- });
14
- this.txDuration = meter.createHistogram(Metrics.L1_PUBLISHER_TX_DURATION, {
15
- description: 'The duration of transaction processing',
16
- unit: 'ms',
17
- valueType: ValueType.INT,
18
- });
19
- this.txGas = meter.createHistogram(Metrics.L1_PUBLISHER_TX_GAS, {
20
- description: 'The gas consumed by transactions',
21
- unit: 'gas',
22
- valueType: ValueType.INT,
23
- });
24
- this.txCalldataSize = meter.createHistogram(Metrics.L1_PUBLISHER_TX_CALLDATA_SIZE, {
25
- description: 'The size of the calldata in transactions',
26
- unit: 'By',
27
- valueType: ValueType.INT,
28
- });
29
- this.txCalldataGas = meter.createHistogram(Metrics.L1_PUBLISHER_TX_CALLDATA_GAS, {
30
- description: 'The gas consumed by the calldata in transactions',
31
- unit: 'gas',
32
- valueType: ValueType.INT,
33
- });
34
- this.txBlobDataGasUsed = meter.createHistogram(Metrics.L1_PUBLISHER_TX_BLOBDATA_GAS_USED, {
35
- description: 'The amount of blob gas used in transactions',
36
- unit: 'gas',
37
- valueType: ValueType.INT,
38
- });
39
- this.txBlobDataGasCost = meter.createHistogram(Metrics.L1_PUBLISHER_TX_BLOBDATA_GAS_COST, {
40
- description: 'The gas cost of blobs in transactions',
41
- unit: 'gwei',
42
- valueType: ValueType.INT,
43
- });
44
- }
45
- recordFailedTx(txType) {
46
- this.txCount.add(1, {
47
- [Attributes.L1_TX_TYPE]: txType,
48
- [Attributes.OK]: false,
49
- });
50
- }
51
- recordSubmitProof(durationMs, stats) {
52
- this.recordTx('submitProof', durationMs, stats);
53
- }
54
- recordProcessBlockTx(durationMs, stats) {
55
- this.recordTx('process', durationMs, stats);
56
- }
57
- recordClaimEpochProofRightTx(durationMs, stats) {
58
- this.recordTx('claimEpochProofRight', durationMs, stats);
59
- }
60
- recordTx(txType, durationMs, stats) {
61
- const attributes = {
62
- [Attributes.L1_TX_TYPE]: txType,
63
- [Attributes.L1_SENDER]: stats.sender,
64
- };
65
- this.txCount.add(1, {
66
- ...attributes,
67
- [Attributes.OK]: true,
68
- });
69
- this.txDuration.record(Math.ceil(durationMs), attributes);
70
- this.txGas.record(
71
- // safe to downcast - total block limit is 30M gas which fits in a JS number
72
- Number(stats.gasUsed), attributes);
73
- this.txCalldataGas.record(stats.calldataGas, attributes);
74
- this.txCalldataSize.record(stats.calldataSize, attributes);
75
- this.txBlobDataGasCost.record(Number(stats.blobDataGas), attributes);
76
- this.txBlobDataGasUsed.record(Number(stats.blobGasUsed), attributes);
77
- try {
78
- this.gasPrice.record(parseInt(formatEther(stats.gasPrice, 'gwei'), 10));
79
- }
80
- catch (e) {
81
- // ignore
82
- }
83
- }
84
- }
85
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibDEtcHVibGlzaGVyLW1ldHJpY3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcHVibGlzaGVyL2wxLXB1Ymxpc2hlci1tZXRyaWNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFDTCxVQUFVLEVBRVYsT0FBTyxFQUdQLFNBQVMsR0FDVixNQUFNLHlCQUF5QixDQUFDO0FBRWpDLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFJekMsTUFBTSxPQUFPLGtCQUFrQjtJQVc3QixZQUFZLE1BQXVCLEVBQUUsSUFBSSxHQUFHLGFBQWE7UUFDdkQsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUVwQyxJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLHNCQUFzQixFQUFFO1lBQ3BFLFdBQVcsRUFBRSxxQ0FBcUM7WUFDbEQsSUFBSSxFQUFFLE1BQU07WUFDWixTQUFTLEVBQUUsU0FBUyxDQUFDLE1BQU07U0FDNUIsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUMsbUJBQW1CLENBQUMsT0FBTyxDQUFDLHFCQUFxQixFQUFFO1lBQ3RFLFdBQVcsRUFBRSxzQ0FBc0M7U0FDcEQsQ0FBQyxDQUFDO1FBRUgsSUFBSSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyx3QkFBd0IsRUFBRTtZQUN4RSxXQUFXLEVBQUUsd0NBQXdDO1lBQ3JELElBQUksRUFBRSxJQUFJO1lBQ1YsU0FBUyxFQUFFLFNBQVMsQ0FBQyxHQUFHO1NBQ3pCLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsbUJBQW1CLEVBQUU7WUFDOUQsV0FBVyxFQUFFLGtDQUFrQztZQUMvQyxJQUFJLEVBQUUsS0FBSztZQUNY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
@@ -1,195 +0,0 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
- /// <reference types="node" resolution-mode="require"/>
3
- import { type BlobSinkClientInterface } from '@aztec/blob-sink/client';
4
- import { type EpochProofClaim, type EpochProofQuote, type L2Block, type TxHash } from '@aztec/circuit-types';
5
- import { AZTEC_MAX_EPOCH_DURATION, type BlockHeader, EthAddress, type Proof } from '@aztec/circuits.js';
6
- import { type FeeRecipient, type RootRollupPublicInputs } from '@aztec/circuits.js/rollup';
7
- import { type EthereumChain, type L1ContractsConfig } from '@aztec/ethereum';
8
- import { Blob } from '@aztec/foundation/blob';
9
- import { type Signature } from '@aztec/foundation/eth-signature';
10
- import { Fr } from '@aztec/foundation/fields';
11
- import { type Logger } from '@aztec/foundation/log';
12
- import { type Tuple } from '@aztec/foundation/serialize';
13
- import { RollupAbi } from '@aztec/l1-artifacts';
14
- import { type TelemetryClient } from '@aztec/telemetry-client';
15
- import { type Chain, type Client, type GetContractReturnType, type HttpTransport, type PrivateKeyAccount, type PublicActions, type PublicClient, type PublicRpcSchema, type WalletActions, type WalletClient, type WalletRpcSchema } from 'viem';
16
- import { type PublisherConfig, type TxSenderConfig } from './config.js';
17
- /**
18
- * Stats for a sent transaction.
19
- */
20
- export type TransactionStats = {
21
- /** Address of the sender. */
22
- sender: string;
23
- /** Hash of the transaction. */
24
- transactionHash: string;
25
- /** Size in bytes of the tx calldata */
26
- calldataSize: number;
27
- /** Gas required to pay for the calldata inclusion (depends on size and number of zeros) */
28
- calldataGas: number;
29
- };
30
- /**
31
- * Minimal information from a tx receipt.
32
- */
33
- export type MinimalTransactionReceipt = {
34
- /** True if the tx was successful, false if reverted. */
35
- status: boolean;
36
- /** Hash of the transaction. */
37
- transactionHash: `0x${string}`;
38
- /** Effective gas used by the tx. */
39
- gasUsed: bigint;
40
- /** Effective gas price paid by the tx. */
41
- gasPrice: bigint;
42
- /** Logs emitted in this tx. */
43
- logs: any[];
44
- /** Block number in which this tx was mined. */
45
- blockNumber: bigint;
46
- /** The block hash in which this tx was mined */
47
- blockHash: `0x${string}`;
48
- };
49
- /** Arguments to the submitEpochProof method of the rollup contract */
50
- export type L1SubmitEpochProofArgs = {
51
- epochSize: number;
52
- previousArchive: Fr;
53
- endArchive: Fr;
54
- previousBlockHash: Fr;
55
- endBlockHash: Fr;
56
- endTimestamp: Fr;
57
- outHash: Fr;
58
- proverId: Fr;
59
- fees: Tuple<FeeRecipient, typeof AZTEC_MAX_EPOCH_DURATION>;
60
- proof: Proof;
61
- };
62
- export declare enum VoteType {
63
- GOVERNANCE = 0,
64
- SLASHING = 1
65
- }
66
- type GetSlashPayloadCallBack = (slotNumber: bigint) => Promise<EthAddress | undefined>;
67
- /**
68
- * Publishes L2 blocks to L1. This implementation does *not* retry a transaction in
69
- * the event of network congestion, but should work for local development.
70
- * - If sending (not mining) a tx fails, it retries indefinitely at 1-minute intervals.
71
- * - If the tx is not mined, keeps polling indefinitely at 1-second intervals.
72
- *
73
- * Adapted from https://github.com/AztecProtocol/aztec2-internal/blob/master/falafel/src/rollup_publisher.ts.
74
- */
75
- export declare class L1Publisher {
76
- private interruptibleSleep;
77
- private sleepTimeMs;
78
- private interrupted;
79
- private metrics;
80
- protected governanceLog: Logger;
81
- protected governanceProposerAddress?: EthAddress;
82
- private governancePayload;
83
- protected slashingLog: Logger;
84
- protected slashingProposerAddress?: EthAddress;
85
- private getSlashPayload?;
86
- private myLastVotes;
87
- protected log: Logger;
88
- protected rollupContract: GetContractReturnType<typeof RollupAbi, WalletClient<HttpTransport, Chain, PrivateKeyAccount>>;
89
- protected publicClient: PublicClient<HttpTransport, Chain>;
90
- protected walletClient: WalletClient<HttpTransport, Chain, PrivateKeyAccount>;
91
- protected account: PrivateKeyAccount;
92
- protected ethereumSlotDuration: bigint;
93
- private blobSinkClient;
94
- static PROPOSE_GAS_GUESS: bigint;
95
- static PROPOSE_AND_CLAIM_GAS_GUESS: bigint;
96
- private readonly l1TxUtils;
97
- constructor(config: TxSenderConfig & PublisherConfig & Pick<L1ContractsConfig, 'ethereumSlotDuration'>, deps?: {
98
- telemetry?: TelemetryClient;
99
- blobSinkClient?: BlobSinkClientInterface;
100
- });
101
- registerSlashPayloadGetter(callback: GetSlashPayloadCallBack): void;
102
- private getSlashingProposerAddress;
103
- get publisherAddress(): `0x${string}`;
104
- protected createWalletClient(account: PrivateKeyAccount, chain: EthereumChain): WalletClient<HttpTransport, Chain, PrivateKeyAccount>;
105
- getGovernancePayload(): EthAddress;
106
- setGovernancePayload(payload: EthAddress): void;
107
- getSenderAddress(): EthAddress;
108
- getClient(): Client<HttpTransport, Chain, PrivateKeyAccount, [
109
- ...WalletRpcSchema,
110
- ...PublicRpcSchema
111
- ], PublicActions<HttpTransport, Chain> & WalletActions<Chain, PrivateKeyAccount>>;
112
- getRollupContract(): GetContractReturnType<typeof RollupAbi, WalletClient<HttpTransport, Chain, PrivateKeyAccount>>;
113
- /**
114
- * @notice Calls `canProposeAtTime` with the time of the next Ethereum block and the sender address
115
- *
116
- * @dev Throws if unable to propose
117
- *
118
- * @param archive - The archive that we expect to be current state
119
- * @return slot - The L2 slot number of the next Ethereum block,
120
- * @return blockNumber - The L2 block number of the next L2 block
121
- */
122
- canProposeAtNextEthBlock(archive: Buffer): Promise<[bigint, bigint]>;
123
- getClaimableEpoch(): Promise<bigint | undefined>;
124
- getEpochForSlotNumber(slotNumber: bigint): Promise<bigint>;
125
- getEpochToProve(): Promise<bigint | undefined>;
126
- getProofClaim(): Promise<EpochProofClaim | undefined>;
127
- validateProofQuote(quote: EpochProofQuote): Promise<EpochProofQuote | undefined>;
128
- /**
129
- * @notice Will call `validateHeader` to make sure that it is possible to propose
130
- *
131
- * @dev Throws if unable to propose
132
- *
133
- * @param header - The header to propose
134
- * @param digest - The digest that attestations are signing over
135
- *
136
- */
137
- validateBlockForSubmission(header: BlockHeader, attestationData?: {
138
- digest: Buffer;
139
- signatures: Signature[];
140
- }): Promise<bigint>;
141
- getCurrentEpochCommittee(): Promise<EthAddress[]>;
142
- getTransactionStats(txHash: string): Promise<TransactionStats | undefined>;
143
- castVote(slotNumber: bigint, timestamp: bigint, voteType: VoteType): Promise<boolean>;
144
- /**
145
- * Proposes a L2 block on L1.
146
- * @param block - L2 block to propose.
147
- * @returns True once the tx has been confirmed and is successful, false on revert or interrupt, blocks otherwise.
148
- */
149
- proposeL2Block(block: L2Block, attestations?: Signature[], txHashes?: TxHash[], proofQuote?: EpochProofQuote, opts?: {
150
- txTimeoutAt?: Date;
151
- }): Promise<boolean>;
152
- /** Calls claimEpochProofRight in the Rollup contract to submit a chosen prover quote for the previous epoch. */
153
- claimEpochProofRight(proofQuote: EpochProofQuote): Promise<boolean>;
154
- private tryGetErrorFromRevertedTx;
155
- submitEpochProof(args: {
156
- epochNumber: number;
157
- fromBlock: number;
158
- toBlock: number;
159
- publicInputs: RootRollupPublicInputs;
160
- proof: Proof;
161
- }): Promise<boolean>;
162
- private validateEpochProofSubmission;
163
- /**
164
- * Calling `interrupt` will cause any in progress call to `publishRollup` to return `false` asap.
165
- * Be warned, the call may return false even if the tx subsequently gets successfully mined.
166
- * In practice this shouldn't matter, as we'll only ever be calling `interrupt` when we know it's going to fail.
167
- * A call to `restart` is required before you can continue publishing.
168
- */
169
- interrupt(): void;
170
- /** Restarts the publisher after calling `interrupt`. */
171
- restart(): void;
172
- private sendSubmitEpochProofTx;
173
- private prepareProposeTx;
174
- private getSubmitEpochProofArgs;
175
- private sendProposeTx;
176
- private sendProposeAndClaimTx;
177
- /**
178
- * Returns a tx receipt if the tx has been mined.
179
- * @param txHash - Hash of the tx to look for.
180
- * @returns Undefined if the tx hasn't been mined yet, the receipt otherwise.
181
- */
182
- getTransactionReceipt(txHash: string): Promise<MinimalTransactionReceipt | undefined>;
183
- protected sleepOrInterrupted(): Promise<void>;
184
- /**
185
- * Send blobs to the blob sink
186
- *
187
- * If a blob sink url is configured, then we send blobs to the blob sink
188
- * - for now we use the blockHash as the identifier for the blobs;
189
- * In the future this will move to be the beacon block id - which takes a bit more work
190
- * to calculate and will need to be mocked in e2e tests
191
- */
192
- protected sendBlobsToBlobSink(blockHash: string, blobs: Blob[]): Promise<boolean>;
193
- }
194
- export {};
195
- //# sourceMappingURL=l1-publisher.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"l1-publisher.d.ts","sourceRoot":"","sources":["../../src/publisher/l1-publisher.ts"],"names":[],"mappings":"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"}