@aztec/sequencer-client 0.0.1-commit.5de5ca79e → 0.0.1-commit.6201a7b05

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 (77) hide show
  1. package/dest/client/sequencer-client.d.ts +6 -1
  2. package/dest/client/sequencer-client.d.ts.map +1 -1
  3. package/dest/client/sequencer-client.js +11 -17
  4. package/dest/config.d.ts +1 -1
  5. package/dest/config.d.ts.map +1 -1
  6. package/dest/config.js +13 -12
  7. package/dest/global_variable_builder/fee_predictor.d.ts +37 -0
  8. package/dest/global_variable_builder/fee_predictor.d.ts.map +1 -0
  9. package/dest/global_variable_builder/fee_predictor.js +128 -0
  10. package/dest/global_variable_builder/fee_provider.d.ts +21 -0
  11. package/dest/global_variable_builder/fee_provider.d.ts.map +1 -0
  12. package/dest/global_variable_builder/fee_provider.js +58 -0
  13. package/dest/global_variable_builder/global_builder.d.ts +15 -14
  14. package/dest/global_variable_builder/global_builder.d.ts.map +1 -1
  15. package/dest/global_variable_builder/global_builder.js +16 -51
  16. package/dest/global_variable_builder/index.d.ts +4 -2
  17. package/dest/global_variable_builder/index.d.ts.map +1 -1
  18. package/dest/global_variable_builder/index.js +2 -0
  19. package/dest/publisher/config.d.ts +13 -1
  20. package/dest/publisher/config.d.ts.map +1 -1
  21. package/dest/publisher/config.js +19 -4
  22. package/dest/publisher/l1_tx_failed_store/failed_tx_store.d.ts +3 -4
  23. package/dest/publisher/l1_tx_failed_store/failed_tx_store.d.ts.map +1 -1
  24. package/dest/publisher/sequencer-publisher-factory.d.ts +3 -5
  25. package/dest/publisher/sequencer-publisher-factory.d.ts.map +1 -1
  26. package/dest/publisher/sequencer-publisher-factory.js +2 -3
  27. package/dest/publisher/sequencer-publisher.d.ts +48 -42
  28. package/dest/publisher/sequencer-publisher.d.ts.map +1 -1
  29. package/dest/publisher/sequencer-publisher.js +119 -111
  30. package/dest/sequencer/chain_state_overrides.d.ts +25 -0
  31. package/dest/sequencer/chain_state_overrides.d.ts.map +1 -0
  32. package/dest/sequencer/chain_state_overrides.js +39 -0
  33. package/dest/sequencer/checkpoint_proposal_job.d.ts +41 -11
  34. package/dest/sequencer/checkpoint_proposal_job.d.ts.map +1 -1
  35. package/dest/sequencer/checkpoint_proposal_job.js +525 -149
  36. package/dest/sequencer/checkpoint_proposal_job_metrics.d.ts +34 -0
  37. package/dest/sequencer/checkpoint_proposal_job_metrics.d.ts.map +1 -0
  38. package/dest/sequencer/checkpoint_proposal_job_metrics.js +72 -0
  39. package/dest/sequencer/checkpoint_voter.d.ts +1 -2
  40. package/dest/sequencer/checkpoint_voter.d.ts.map +1 -1
  41. package/dest/sequencer/checkpoint_voter.js +2 -5
  42. package/dest/sequencer/events.d.ts +6 -1
  43. package/dest/sequencer/events.d.ts.map +1 -1
  44. package/dest/sequencer/metrics.d.ts +9 -10
  45. package/dest/sequencer/metrics.d.ts.map +1 -1
  46. package/dest/sequencer/metrics.js +34 -20
  47. package/dest/sequencer/sequencer.d.ts +27 -7
  48. package/dest/sequencer/sequencer.d.ts.map +1 -1
  49. package/dest/sequencer/sequencer.js +106 -28
  50. package/dest/sequencer/timetable.d.ts +14 -1
  51. package/dest/sequencer/timetable.d.ts.map +1 -1
  52. package/dest/sequencer/timetable.js +45 -36
  53. package/dest/test/utils.d.ts +1 -1
  54. package/dest/test/utils.d.ts.map +1 -1
  55. package/dest/test/utils.js +7 -6
  56. package/package.json +27 -27
  57. package/src/client/sequencer-client.ts +16 -24
  58. package/src/config.ts +13 -11
  59. package/src/global_variable_builder/README.md +44 -0
  60. package/src/global_variable_builder/fee_predictor.ts +172 -0
  61. package/src/global_variable_builder/fee_provider.ts +75 -0
  62. package/src/global_variable_builder/global_builder.ts +26 -63
  63. package/src/global_variable_builder/index.ts +3 -1
  64. package/src/publisher/config.ts +38 -4
  65. package/src/publisher/l1_tx_failed_store/failed_tx_store.ts +3 -1
  66. package/src/publisher/sequencer-publisher-factory.ts +3 -6
  67. package/src/publisher/sequencer-publisher.ts +183 -159
  68. package/src/sequencer/README.md +82 -13
  69. package/src/sequencer/chain_state_overrides.ts +87 -0
  70. package/src/sequencer/checkpoint_proposal_job.ts +616 -167
  71. package/src/sequencer/checkpoint_proposal_job_metrics.ts +128 -0
  72. package/src/sequencer/checkpoint_voter.ts +1 -12
  73. package/src/sequencer/events.ts +5 -0
  74. package/src/sequencer/metrics.ts +43 -24
  75. package/src/sequencer/sequencer.ts +148 -32
  76. package/src/sequencer/timetable.ts +57 -45
  77. package/src/test/utils.ts +28 -10
@@ -1,15 +1,16 @@
1
- import { createEthereumChain } from '@aztec/ethereum/chain';
2
- import { makeL1HttpTransport } from '@aztec/ethereum/client';
3
- import type { L1ContractsConfig } from '@aztec/ethereum/config';
4
- import { RollupContract } from '@aztec/ethereum/contracts';
5
- import type { L1ReaderConfig } from '@aztec/ethereum/l1-reader';
1
+ import {
2
+ RollupContract,
3
+ type SimulationOverridesPlan,
4
+ buildSimulationOverridesStateOverride,
5
+ } from '@aztec/ethereum/contracts';
6
+ import type { L1ContractAddresses } from '@aztec/ethereum/l1-contract-addresses';
6
7
  import type { ViemPublicClient } from '@aztec/ethereum/types';
7
8
  import { BlockNumber, SlotNumber } from '@aztec/foundation/branded-types';
8
9
  import { Fr } from '@aztec/foundation/curves/bn254';
9
10
  import type { EthAddress } from '@aztec/foundation/eth-address';
10
- import { createLogger } from '@aztec/foundation/log';
11
+ import type { DateProvider } from '@aztec/foundation/timer';
11
12
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
12
- import { type L1RollupConstants, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
13
+ import { type L1RollupConstants, getNextL1SlotTimestamp, getTimestampForSlot } from '@aztec/stdlib/epoch-helpers';
13
14
  import { GasFees } from '@aztec/stdlib/gas';
14
15
  import type {
15
16
  CheckpointGlobalVariables,
@@ -17,18 +18,18 @@ import type {
17
18
  } from '@aztec/stdlib/tx';
18
19
  import { GlobalVariables } from '@aztec/stdlib/tx';
19
20
 
20
- import { createPublicClient } from 'viem';
21
+ /** Configuration for the GlobalVariableBuilder (excludes L1 client config). */
22
+ export type GlobalVariableBuilderConfig = {
23
+ l1Contracts: Pick<L1ContractAddresses, 'rollupAddress'>;
24
+ ethereumSlotDuration: number;
25
+ rollupVersion: bigint;
26
+ } & Pick<L1RollupConstants, 'slotDuration' | 'l1GenesisTime'>;
21
27
 
22
28
  /**
23
29
  * Simple global variables builder.
24
30
  */
25
31
  export class GlobalVariableBuilder implements GlobalVariableBuilderInterface {
26
- private log = createLogger('sequencer:global_variable_builder');
27
- private currentMinFees: Promise<GasFees> = Promise.resolve(new GasFees(0, 0));
28
- private currentL1BlockNumber: bigint | undefined = undefined;
29
-
30
32
  private readonly rollupContract: RollupContract;
31
- private readonly publicClient: ViemPublicClient;
32
33
  private readonly ethereumSlotDuration: number;
33
34
  private readonly aztecSlotDuration: number;
34
35
  private readonly l1GenesisTime: bigint;
@@ -37,59 +38,18 @@ export class GlobalVariableBuilder implements GlobalVariableBuilderInterface {
37
38
  private version: Fr;
38
39
 
39
40
  constructor(
40
- config: L1ReaderConfig &
41
- Pick<L1ContractsConfig, 'ethereumSlotDuration'> &
42
- Pick<L1RollupConstants, 'slotDuration' | 'l1GenesisTime'> & { rollupVersion: bigint },
41
+ private readonly dateProvider: DateProvider,
42
+ private readonly publicClient: ViemPublicClient,
43
+ config: GlobalVariableBuilderConfig,
43
44
  ) {
44
- const { l1RpcUrls, l1ChainId: chainId, l1Contracts } = config;
45
-
46
- const chain = createEthereumChain(l1RpcUrls, chainId);
47
-
48
45
  this.version = new Fr(config.rollupVersion);
49
- this.chainId = new Fr(chainId);
46
+ this.chainId = new Fr(this.publicClient.chain!.id);
50
47
 
51
48
  this.ethereumSlotDuration = config.ethereumSlotDuration;
52
49
  this.aztecSlotDuration = config.slotDuration;
53
50
  this.l1GenesisTime = config.l1GenesisTime;
54
51
 
55
- this.publicClient = createPublicClient({
56
- chain: chain.chainInfo,
57
- transport: makeL1HttpTransport(chain.rpcUrls, { timeout: config.l1HttpTimeoutMS }),
58
- pollingInterval: config.viemPollingIntervalMS,
59
- });
60
-
61
- this.rollupContract = new RollupContract(this.publicClient, l1Contracts.rollupAddress);
62
- }
63
-
64
- /**
65
- * Computes the "current" min fees, e.g., the price that you currently should pay to get include in the next block
66
- * @returns Min fees for the next block
67
- */
68
- private async computeCurrentMinFees(): Promise<GasFees> {
69
- // Since this might be called in the middle of a slot where a block might have been published,
70
- // we need to fetch the last block written, and estimate the earliest timestamp for the next block.
71
- // The timestamp of that last block will act as a lower bound for the next block.
72
-
73
- const lastCheckpoint = await this.rollupContract.getPendingCheckpoint();
74
- const earliestTimestamp = await this.rollupContract.getTimestampForSlot(
75
- SlotNumber.fromBigInt(BigInt(lastCheckpoint.slotNumber) + 1n),
76
- );
77
- const nextEthTimestamp = BigInt((await this.publicClient.getBlock()).timestamp + BigInt(this.ethereumSlotDuration));
78
- const timestamp = earliestTimestamp > nextEthTimestamp ? earliestTimestamp : nextEthTimestamp;
79
-
80
- return new GasFees(0, await this.rollupContract.getManaMinFeeAt(timestamp, true));
81
- }
82
-
83
- public async getCurrentMinFees(): Promise<GasFees> {
84
- // Get the current block number
85
- const blockNumber = await this.publicClient.getBlockNumber();
86
-
87
- // If the L1 block number has changed then chain a new promise to get the current min fees
88
- if (this.currentL1BlockNumber === undefined || blockNumber > this.currentL1BlockNumber) {
89
- this.currentL1BlockNumber = blockNumber;
90
- this.currentMinFees = this.currentMinFees.then(() => this.computeCurrentMinFees());
91
- }
92
- return this.currentMinFees;
52
+ this.rollupContract = new RollupContract(this.publicClient, config.l1Contracts.rollupAddress);
93
53
  }
94
54
 
95
55
  /**
@@ -109,7 +69,10 @@ export class GlobalVariableBuilder implements GlobalVariableBuilderInterface {
109
69
  const slot: SlotNumber =
110
70
  maybeSlot ??
111
71
  (await this.rollupContract.getSlotAt(
112
- BigInt((await this.publicClient.getBlock()).timestamp + BigInt(this.ethereumSlotDuration)),
72
+ getNextL1SlotTimestamp(this.dateProvider.nowInSeconds(), {
73
+ l1GenesisTime: this.l1GenesisTime,
74
+ ethereumSlotDuration: this.ethereumSlotDuration,
75
+ }),
113
76
  ));
114
77
 
115
78
  const checkpointGlobalVariables = await this.buildCheckpointGlobalVariables(coinbase, feeRecipient, slot);
@@ -121,6 +84,7 @@ export class GlobalVariableBuilder implements GlobalVariableBuilderInterface {
121
84
  coinbase: EthAddress,
122
85
  feeRecipient: AztecAddress,
123
86
  slotNumber: SlotNumber,
87
+ simulationOverridesPlan?: SimulationOverridesPlan,
124
88
  ): Promise<CheckpointGlobalVariables> {
125
89
  const { chainId, version } = this;
126
90
 
@@ -129,9 +93,8 @@ export class GlobalVariableBuilder implements GlobalVariableBuilderInterface {
129
93
  l1GenesisTime: this.l1GenesisTime,
130
94
  });
131
95
 
132
- // We can skip much of the logic in getCurrentMinFees since it we already check that we are not within a slot elsewhere.
133
- // TODO(palla/mbps): Can we use a cached value here?
134
- const gasFees = new GasFees(0, await this.rollupContract.getManaMinFeeAt(timestamp, true));
96
+ const stateOverride = await buildSimulationOverridesStateOverride(this.rollupContract, simulationOverridesPlan);
97
+ const gasFees = new GasFees(0, await this.rollupContract.getManaMinFeeAt(timestamp, true, stateOverride));
135
98
 
136
99
  return { chainId, version, slotNumber, timestamp, coinbase, feeRecipient, gasFees };
137
100
  }
@@ -1 +1,3 @@
1
- export { GlobalVariableBuilder } from './global_builder.js';
1
+ export { FeeProviderImpl } from './fee_provider.js';
2
+ export { GlobalVariableBuilder, type GlobalVariableBuilderConfig } from './global_builder.js';
3
+ export { FeePredictor } from './fee_predictor.js';
@@ -4,6 +4,8 @@ import { type L1TxUtilsConfig, l1TxUtilsConfigMappings } from '@aztec/ethereum/l
4
4
  import { type ConfigMappingsType, SecretValue, booleanConfigHelper } from '@aztec/foundation/config';
5
5
  import { EthAddress } from '@aztec/foundation/eth-address';
6
6
 
7
+ import { parseEther } from 'viem';
8
+
7
9
  /** Configuration of the transaction publisher. */
8
10
  export type TxSenderConfig = L1ReaderConfig & {
9
11
  /** The private key to be used by the publisher. */
@@ -50,13 +52,37 @@ export type PublisherConfig = L1TxUtilsConfig &
50
52
  publisherForwarderAddress?: EthAddress;
51
53
  /** Store for failed L1 transaction inputs (test networks only). Format: gs://bucket/path */
52
54
  l1TxFailedStore?: string;
55
+ /** Min ETH balance below which a publisher gets funded. Undefined = funding disabled. */
56
+ publisherFundingThreshold?: bigint;
57
+ /** Amount of ETH to send when funding a publisher. Undefined = funding disabled. */
58
+ publisherFundingAmount?: bigint;
53
59
  };
54
60
 
61
+ /** Shared config mappings for publisher funding, used by both sequencer and prover publisher configs. */
62
+ const publisherFundingConfigMappings = {
63
+ publisherFundingThreshold: {
64
+ env: 'PUBLISHER_FUNDING_THRESHOLD' as const,
65
+ description:
66
+ 'Min ETH balance below which a publisher gets funded. Specified in ether (e.g. 0.1). Unset = funding disabled.',
67
+ parseEnv: (val: string) => parseEther(val),
68
+ },
69
+ publisherFundingAmount: {
70
+ env: 'PUBLISHER_FUNDING_AMOUNT' as const,
71
+ description:
72
+ 'Amount of ETH to send when funding a publisher. Specified in ether (e.g. 0.5). Unset = funding disabled.',
73
+ parseEnv: (val: string) => parseEther(val),
74
+ },
75
+ };
76
+
55
77
  export type ProverPublisherConfig = L1TxUtilsConfig &
56
78
  BlobClientConfig & {
57
79
  fishermanMode?: boolean;
58
80
  proverPublisherAllowInvalidStates?: boolean;
59
81
  proverPublisherForwarderAddress?: EthAddress;
82
+ /** Min ETH balance below which a publisher gets funded. Undefined = funding disabled. */
83
+ publisherFundingThreshold?: bigint;
84
+ /** Amount of ETH to send when funding a publisher. Undefined = funding disabled. */
85
+ publisherFundingAmount?: bigint;
60
86
  };
61
87
 
62
88
  export type SequencerPublisherConfig = L1TxUtilsConfig &
@@ -66,6 +92,10 @@ export type SequencerPublisherConfig = L1TxUtilsConfig &
66
92
  sequencerPublisherForwarderAddress?: EthAddress;
67
93
  /** Store for failed L1 transaction inputs (test networks only). Format: gs://bucket/path */
68
94
  l1TxFailedStore?: string;
95
+ /** Min ETH balance below which a publisher gets funded. Undefined = funding disabled. */
96
+ publisherFundingThreshold?: bigint;
97
+ /** Amount of ETH to send when funding a publisher. Undefined = funding disabled. */
98
+ publisherFundingAmount?: bigint;
69
99
  };
70
100
 
71
101
  export function getPublisherConfigFromProverConfig(config: ProverPublisherConfig): PublisherConfig {
@@ -90,7 +120,8 @@ export const proverTxSenderConfigMappings: ConfigMappingsType<Omit<ProverTxSende
90
120
  proverPublisherPrivateKeys: {
91
121
  env: `PROVER_PUBLISHER_PRIVATE_KEYS`,
92
122
  description: 'The private keys to be used by the prover publisher.',
93
- parseEnv: (val: string) => val.split(',').map(key => new SecretValue(`0x${key.replace('0x', '')}`)),
123
+ parseEnv: (val: string) =>
124
+ val.split(',').map(key => new SecretValue(`0x${key.replace('0x', '')}` as `0x${string}`)),
94
125
  defaultValue: [],
95
126
  fallback: [`PROVER_PUBLISHER_PRIVATE_KEY`],
96
127
  },
@@ -107,7 +138,8 @@ export const sequencerTxSenderConfigMappings: ConfigMappingsType<Omit<SequencerT
107
138
  sequencerPublisherPrivateKeys: {
108
139
  env: `SEQ_PUBLISHER_PRIVATE_KEYS`,
109
140
  description: 'The private keys to be used by the sequencer publisher.',
110
- parseEnv: (val: string) => val.split(',').map(key => new SecretValue(`0x${key.replace('0x', '')}`)),
141
+ parseEnv: (val: string) =>
142
+ val.split(',').map(key => new SecretValue(`0x${key.replace('0x', '')}` as `0x${string}`)),
111
143
  defaultValue: [],
112
144
  fallback: [`SEQ_PUBLISHER_PRIVATE_KEY`],
113
145
  },
@@ -136,12 +168,13 @@ export const sequencerPublisherConfigMappings: ConfigMappingsType<SequencerPubli
136
168
  sequencerPublisherForwarderAddress: {
137
169
  env: `SEQ_PUBLISHER_FORWARDER_ADDRESS`,
138
170
  description: 'Address of the forwarder contract to wrap all L1 transactions through (for testing purposes only)',
139
- parseEnv: (val: string) => (val ? EthAddress.fromString(val) : undefined),
171
+ parseEnv: (val: string) => EthAddress.fromString(val),
140
172
  },
141
173
  l1TxFailedStore: {
142
174
  env: 'L1_TX_FAILED_STORE',
143
175
  description: 'Store for failed L1 transaction inputs (test networks only). Format: gs://bucket/path',
144
176
  },
177
+ ...publisherFundingConfigMappings,
145
178
  };
146
179
 
147
180
  export const proverPublisherConfigMappings: ConfigMappingsType<ProverPublisherConfig & L1TxUtilsConfig> = {
@@ -161,6 +194,7 @@ export const proverPublisherConfigMappings: ConfigMappingsType<ProverPublisherCo
161
194
  proverPublisherForwarderAddress: {
162
195
  env: `PROVER_PUBLISHER_FORWARDER_ADDRESS`,
163
196
  description: 'Address of the forwarder contract to wrap all L1 transactions through (for testing purposes only)',
164
- parseEnv: (val: string) => (val ? EthAddress.fromString(val) : undefined),
197
+ parseEnv: (val: string) => EthAddress.fromString(val),
165
198
  },
199
+ ...publisherFundingConfigMappings,
166
200
  };
@@ -1,7 +1,9 @@
1
+ import type { Branded } from '@aztec/foundation/branded-types';
2
+
1
3
  import type { Hex } from 'viem';
2
4
 
3
5
  /** URI pointing to a stored failed L1 transaction. */
4
- export type FailedL1TxUri = string & { __brand: 'FailedL1TxUri' };
6
+ export type FailedL1TxUri = Branded<string, 'FailedL1TxUri'>;
5
7
 
6
8
  /** A failed L1 transaction captured for debugging and replay. */
7
9
  export type FailedL1Tx = {
@@ -7,7 +7,6 @@ import type { L1TxUtils } from '@aztec/ethereum/l1-tx-utils';
7
7
  import type { PublisherFilter, PublisherManager } from '@aztec/ethereum/publisher-manager';
8
8
  import { SlotNumber } from '@aztec/foundation/branded-types';
9
9
  import type { DateProvider } from '@aztec/foundation/timer';
10
- import type { SlashFactoryContract } from '@aztec/stdlib/l1-contracts';
11
10
  import type { TelemetryClient } from '@aztec/telemetry-client';
12
11
  import { NodeKeystoreAdapter } from '@aztec/validator-client';
13
12
 
@@ -40,7 +39,6 @@ export class SequencerPublisherFactory {
40
39
  epochCache: EpochCache;
41
40
  rollupContract: RollupContract;
42
41
  governanceProposerContract: GovernanceProposerContract;
43
- slashFactoryContract: SlashFactoryContract;
44
42
  nodeKeyStore: NodeKeystoreAdapter;
45
43
  logger?: Logger;
46
44
  },
@@ -104,7 +102,6 @@ export class SequencerPublisherFactory {
104
102
  epochCache: this.deps.epochCache,
105
103
  governanceProposerContract: this.deps.governanceProposerContract,
106
104
  slashingProposerContract,
107
- slashFactoryContract: this.deps.slashFactoryContract,
108
105
  dateProvider: this.deps.dateProvider,
109
106
  metrics: this.publisherMetrics,
110
107
  lastActions: this.lastActions,
@@ -117,8 +114,8 @@ export class SequencerPublisherFactory {
117
114
  };
118
115
  }
119
116
 
120
- /** Interrupts all publishers managed by this factory. Used during sequencer shutdown. */
121
- public interruptAll(): void {
122
- this.deps.publisherManager.interrupt();
117
+ /** Stops all publishers managed by this factory. Used during sequencer shutdown. */
118
+ public async stopAll(): Promise<void> {
119
+ await this.deps.publisherManager.stop();
123
120
  }
124
121
  }