@aztec/ethereum 0.80.0 → 0.82.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.
@@ -73,6 +73,10 @@ export class RollupContract {
73
73
  return this.rollup.address;
74
74
  }
75
75
 
76
+ getContract(): GetContractReturnType<typeof RollupAbi, ViemPublicClient> {
77
+ return this.rollup;
78
+ }
79
+
76
80
  @memoize
77
81
  public async getSlashingProposer() {
78
82
  const slasherAddress = await this.rollup.read.getSlasher();
@@ -116,8 +120,32 @@ export class RollupContract {
116
120
  return this.rollup.read.getMinimumStake();
117
121
  }
118
122
 
123
+ @memoize
124
+ getManaTarget() {
125
+ return this.rollup.read.getManaTarget();
126
+ }
127
+
128
+ @memoize
129
+ getProvingCostPerMana() {
130
+ return this.rollup.read.getProvingCostPerManaInEth();
131
+ }
132
+
133
+ @memoize
134
+ getProvingCostPerManaInFeeAsset() {
135
+ return this.rollup.read.getProvingCostPerManaInFeeAsset();
136
+ }
137
+
138
+ @memoize
139
+ getManaLimit() {
140
+ return this.rollup.read.getManaLimit();
141
+ }
142
+
143
+ getSlasher() {
144
+ return this.rollup.read.getSlasher();
145
+ }
146
+
119
147
  public async getSlashingProposerAddress() {
120
- const slasherAddress = await this.rollup.read.getSlasher();
148
+ const slasherAddress = await this.getSlasher();
121
149
  const slasher = getContract({
122
150
  address: getAddress(slasherAddress.toString()),
123
151
  abi: SlasherAbi,
@@ -138,8 +166,15 @@ export class RollupContract {
138
166
  return this.rollup.read.getCurrentSlot();
139
167
  }
140
168
 
141
- getCommitteeAt(timestamp: bigint) {
142
- return this.rollup.read.getCommitteeAt([timestamp]);
169
+ async getCommitteeAt(timestamp: bigint) {
170
+ const { result } = await this.client.simulateContract({
171
+ address: this.address,
172
+ abi: RollupAbi,
173
+ functionName: 'getCommitteeAt',
174
+ args: [timestamp],
175
+ });
176
+
177
+ return result;
143
178
  }
144
179
 
145
180
  getSampleSeedAt(timestamp: bigint) {
@@ -150,16 +185,37 @@ export class RollupContract {
150
185
  return this.rollup.read.getCurrentSampleSeed();
151
186
  }
152
187
 
153
- getCurrentEpochCommittee() {
154
- return this.rollup.read.getCurrentEpochCommittee();
188
+ async getCurrentEpochCommittee() {
189
+ const { result } = await this.client.simulateContract({
190
+ address: this.address,
191
+ abi: RollupAbi,
192
+ functionName: 'getCurrentEpochCommittee',
193
+ args: [],
194
+ });
195
+
196
+ return result;
155
197
  }
156
198
 
157
- getCurrentProposer() {
158
- return this.rollup.read.getCurrentProposer();
199
+ async getCurrentProposer() {
200
+ const { result } = await this.client.simulateContract({
201
+ address: this.address,
202
+ abi: RollupAbi,
203
+ functionName: 'getCurrentProposer',
204
+ args: [],
205
+ });
206
+
207
+ return result;
159
208
  }
160
209
 
161
- getProposerAt(timestamp: bigint) {
162
- return this.rollup.read.getProposerAt([timestamp]);
210
+ async getProposerAt(timestamp: bigint) {
211
+ const { result } = await this.client.simulateContract({
212
+ address: this.address,
213
+ abi: RollupAbi,
214
+ functionName: 'getProposerAt',
215
+ args: [timestamp],
216
+ });
217
+
218
+ return result;
163
219
  }
164
220
 
165
221
  getBlock(blockNumber: bigint) {
@@ -234,7 +290,13 @@ export class RollupContract {
234
290
  account: `0x${string}` | Account,
235
291
  ): Promise<void> {
236
292
  try {
237
- await this.rollup.read.validateHeader(args, { account });
293
+ await this.client.simulateContract({
294
+ address: this.address,
295
+ abi: RollupAbi,
296
+ functionName: 'validateHeader',
297
+ args,
298
+ account,
299
+ });
238
300
  } catch (error: unknown) {
239
301
  throw formatViemError(error);
240
302
  }
@@ -259,10 +321,16 @@ export class RollupContract {
259
321
  }
260
322
  const timeOfNextL1Slot = (await this.client.getBlock()).timestamp + slotDuration;
261
323
  try {
262
- const [slot, blockNumber] = await this.rollup.read.canProposeAtTime(
263
- [timeOfNextL1Slot, `0x${archive.toString('hex')}`],
264
- { account },
265
- );
324
+ const {
325
+ result: [slot, blockNumber],
326
+ } = await this.client.simulateContract({
327
+ address: this.address,
328
+ abi: RollupAbi,
329
+ functionName: 'canProposeAtTime',
330
+ args: [timeOfNextL1Slot, `0x${archive.toString('hex')}`],
331
+ account,
332
+ });
333
+
266
334
  return [slot, blockNumber];
267
335
  } catch (err: unknown) {
268
336
  throw formatViemError(err);
@@ -270,7 +338,82 @@ export class RollupContract {
270
338
  }
271
339
 
272
340
  /** Calls getHasSubmitted directly. Returns whether the given prover has submitted a proof with the given length for the given epoch. */
273
- public getHasSubmittedProof(epochNumber: number, numberOfBlocksInEpoch: number, prover: EthAddress) {
274
- return this.rollup.read.getHasSubmitted([BigInt(epochNumber), BigInt(numberOfBlocksInEpoch), prover.toString()]);
341
+ public getHasSubmittedProof(epochNumber: number, numberOfBlocksInEpoch: number, prover: Hex | EthAddress) {
342
+ if (prover instanceof EthAddress) {
343
+ prover = prover.toString();
344
+ }
345
+ return this.rollup.read.getHasSubmitted([BigInt(epochNumber), BigInt(numberOfBlocksInEpoch), prover]);
346
+ }
347
+
348
+ getManaBaseFeeAt(timestamp: bigint, inFeeAsset: boolean) {
349
+ return this.rollup.read.getManaBaseFeeAt([timestamp, inFeeAsset]);
350
+ }
351
+
352
+ getVersion() {
353
+ return this.rollup.read.getVersion();
354
+ }
355
+
356
+ getSlotAt(timestamp: bigint) {
357
+ return this.rollup.read.getSlotAt([timestamp]);
358
+ }
359
+
360
+ status(blockNumber: bigint, options?: { blockNumber?: bigint }) {
361
+ return this.rollup.read.status([blockNumber], options);
362
+ }
363
+
364
+ canPruneAtTime(timestamp: bigint, options?: { blockNumber?: bigint }) {
365
+ return this.rollup.read.canPruneAtTime([timestamp], options);
366
+ }
367
+
368
+ archive() {
369
+ return this.rollup.read.archive();
370
+ }
371
+
372
+ archiveAt(blockNumber: bigint) {
373
+ return this.rollup.read.archiveAt([blockNumber]);
374
+ }
375
+
376
+ getSequencerRewards(address: Hex | EthAddress) {
377
+ if (address instanceof EthAddress) {
378
+ address = address.toString();
379
+ }
380
+ return this.rollup.read.getSequencerRewards([address]);
381
+ }
382
+
383
+ getSpecificProverRewardsForEpoch(epoch: bigint, prover: Hex | EthAddress) {
384
+ if (prover instanceof EthAddress) {
385
+ prover = prover.toString();
386
+ }
387
+ return this.rollup.read.getSpecificProverRewardsForEpoch([epoch, prover]);
388
+ }
389
+
390
+ getAttesters() {
391
+ return this.rollup.read.getAttesters();
392
+ }
393
+
394
+ getEpochCommittee(epoch: bigint) {
395
+ return this.rollup.read.getEpochCommittee([epoch]);
396
+ }
397
+
398
+ getInfo(address: Hex | EthAddress) {
399
+ if (address instanceof EthAddress) {
400
+ address = address.toString();
401
+ }
402
+ return this.rollup.read.getInfo([address]);
403
+ }
404
+
405
+ getBlobPublicInputsHash(blockNumber: bigint) {
406
+ return this.rollup.read.getBlobPublicInputsHash([blockNumber]);
407
+ }
408
+
409
+ getStakingAsset() {
410
+ return this.rollup.read.getStakingAsset();
411
+ }
412
+
413
+ getProposerForAttester(attester: Hex | EthAddress) {
414
+ if (attester instanceof EthAddress) {
415
+ attester = attester.toString();
416
+ }
417
+ return this.rollup.read.getProposerForAttester([attester]);
275
418
  }
276
419
  }
@@ -6,6 +6,8 @@ import {
6
6
  CoinIssuerBytecode,
7
7
  ExtRollupLibAbi,
8
8
  ExtRollupLibBytecode,
9
+ FeeAssetHandlerAbi,
10
+ FeeAssetHandlerBytecode,
9
11
  FeeJuicePortalAbi,
10
12
  FeeJuicePortalBytecode,
11
13
  ForwarderAbi,
@@ -188,6 +190,10 @@ export const l1Artifacts = {
188
190
  contractAbi: RegisterNewRollupVersionPayloadAbi,
189
191
  contractBytecode: RegisterNewRollupVersionPayloadBytecode as Hex,
190
192
  },
193
+ feeAssetHandler: {
194
+ contractAbi: FeeAssetHandlerAbi,
195
+ contractBytecode: FeeAssetHandlerBytecode as Hex,
196
+ },
191
197
  };
192
198
 
193
199
  export interface DeployL1ContractsArgs extends L1ContractsConfig {
@@ -328,6 +334,8 @@ export const deployRollup = async (
328
334
  minimumStake: args.minimumStake,
329
335
  slashingQuorum: args.slashingQuorum,
330
336
  slashingRoundSize: args.slashingRoundSize,
337
+ manaTarget: args.manaTarget,
338
+ provingCostPerMana: args.provingCostPerMana,
331
339
  };
332
340
  const genesisStateArgs = {
333
341
  vkTreeRoot: args.vkTreeRoot.toString(),
@@ -388,19 +396,15 @@ export const cheat_initializeValidatorSet = async (
388
396
  acceleratedTestDeployments: boolean | undefined,
389
397
  logger: Logger,
390
398
  ) => {
391
- const rollup = getContract({
392
- address: getAddress(rollupAddress.toString()),
393
- abi: l1Artifacts.rollup.contractAbi,
394
- client: clients.walletClient,
395
- });
396
- const minimumStake = await rollup.read.getMinimumStake();
399
+ const rollup = new RollupContract(clients.publicClient, rollupAddress);
400
+ const minimumStake = await rollup.getMinimumStake();
397
401
  if (validators && validators.length > 0) {
398
402
  // Check if some of the initial validators are already registered, so we support idempotent deployments
399
403
  if (!acceleratedTestDeployments) {
400
404
  const validatorsInfo = await Promise.all(
401
405
  validators.map(async address => ({
402
406
  address,
403
- ...(await rollup.read.getInfo([address])),
407
+ ...(await rollup.getInfo(address)),
404
408
  })),
405
409
  );
406
410
  const existingValidators = validatorsInfo.filter(v => v.status !== 0);
@@ -460,6 +464,44 @@ export const cheat_initializeValidatorSet = async (
460
464
  }
461
465
  };
462
466
 
467
+ /**
468
+ * Initialize the fee asset handler and make it a minter on the fee asset.
469
+ * @note This function will only be used for testing purposes.
470
+ *
471
+ * @param clients - The L1 clients.
472
+ * @param deployer - The L1 deployer.
473
+ * @param feeAssetAddress - The address of the fee asset.
474
+ * @param logger - The logger.
475
+ */
476
+ // eslint-disable-next-line camelcase
477
+ export const cheat_initializeFeeAssetHandler = async (
478
+ clients: L1Clients,
479
+ deployer: L1Deployer,
480
+ feeAssetAddress: EthAddress,
481
+ logger: Logger,
482
+ ): Promise<{
483
+ feeAssetHandlerAddress: EthAddress;
484
+ txHash: Hex;
485
+ }> => {
486
+ const feeAssetHandlerAddress = await deployer.deploy(l1Artifacts.feeAssetHandler, [
487
+ clients.walletClient.account.address,
488
+ feeAssetAddress.toString(),
489
+ BigInt(1e18),
490
+ ]);
491
+ logger.verbose(`Deployed FeeAssetHandler at ${feeAssetHandlerAddress}`);
492
+
493
+ const { txHash } = await deployer.sendTransaction({
494
+ to: feeAssetAddress.toString(),
495
+ data: encodeFunctionData({
496
+ abi: l1Artifacts.feeAsset.contractAbi,
497
+ functionName: 'addMinter',
498
+ args: [feeAssetHandlerAddress.toString()],
499
+ }),
500
+ });
501
+ logger.verbose(`Added fee asset handler ${feeAssetHandlerAddress} as minter on fee asset in ${txHash}`);
502
+ return { feeAssetHandlerAddress, txHash };
503
+ };
504
+
463
505
  /**
464
506
  * Deploys the aztec L1 contracts; Rollup & (optionally) Decoder Helper.
465
507
  * @param rpcUrls - List of URLs of the ETH RPC to use for deployment.
@@ -535,7 +577,7 @@ export const deployL1Contracts = async (
535
577
  // @note @LHerskind the assets are expected to be the same at some point, but for better
536
578
  // configurability they are different for now.
537
579
  const governanceAddress = await deployer.deploy(l1Artifacts.governance, [
538
- feeAssetAddress.toString(),
580
+ stakingAssetAddress.toString(),
539
581
  governanceProposerAddress.toString(),
540
582
  ]);
541
583
  logger.verbose(`Deployed Governance at ${governanceAddress}`);
@@ -579,29 +621,24 @@ export const deployL1Contracts = async (
579
621
  // Transaction hashes to await
580
622
  const txHashes: Hex[] = [];
581
623
 
582
- if (args.acceleratedTestDeployments || !(await feeAsset.read.freeForAll())) {
583
- const { txHash } = await deployer.sendTransaction({
584
- to: feeAssetAddress.toString(),
585
- data: encodeFunctionData({
586
- abi: l1Artifacts.feeAsset.contractAbi,
587
- functionName: 'setFreeForAll',
588
- args: [true],
589
- }),
590
- });
591
- logger.verbose(`Fee asset set to free for all in ${txHash}`);
592
- txHashes.push(txHash);
593
- }
624
+ const { feeAssetHandlerAddress, txHash: feeAssetHandlerTxHash } = await cheat_initializeFeeAssetHandler(
625
+ clients,
626
+ deployer,
627
+ feeAssetAddress,
628
+ logger,
629
+ );
630
+ txHashes.push(feeAssetHandlerTxHash);
594
631
 
595
- if (args.acceleratedTestDeployments || (await feeAsset.read.owner()) !== getAddress(coinIssuerAddress.toString())) {
632
+ if (args.acceleratedTestDeployments || !(await feeAsset.read.minters([coinIssuerAddress.toString()]))) {
596
633
  const { txHash } = await deployer.sendTransaction({
597
634
  to: feeAssetAddress.toString(),
598
635
  data: encodeFunctionData({
599
636
  abi: l1Artifacts.feeAsset.contractAbi,
600
- functionName: 'transferOwnership',
637
+ functionName: 'addMinter',
601
638
  args: [coinIssuerAddress.toString()],
602
639
  }),
603
640
  });
604
- logger.verbose(`Fee asset transferred ownership to coin issuer in ${txHash}`);
641
+ logger.verbose(`Added coin issuer ${coinIssuerAddress} as minter on fee asset in ${txHash}`);
605
642
  txHashes.push(txHash);
606
643
  }
607
644
 
@@ -754,6 +791,7 @@ export const deployL1Contracts = async (
754
791
  l1ContractAddresses: {
755
792
  ...l1Contracts,
756
793
  slashFactoryAddress,
794
+ feeAssetHandlerAddress,
757
795
  },
758
796
  };
759
797
  };
@@ -26,7 +26,7 @@ export const L1ContractsNames = [
26
26
  /** Provides the directory of current L1 contract addresses */
27
27
  export type L1ContractAddresses = {
28
28
  [K in (typeof L1ContractsNames)[number]]: EthAddress;
29
- } & { slashFactoryAddress?: EthAddress | undefined };
29
+ } & { slashFactoryAddress?: EthAddress | undefined; feeAssetHandlerAddress?: EthAddress | undefined };
30
30
 
31
31
  export const L1ContractAddressesSchema = z.object({
32
32
  rollupAddress: schemas.EthAddress,
@@ -41,6 +41,7 @@ export const L1ContractAddressesSchema = z.object({
41
41
  governanceProposerAddress: schemas.EthAddress,
42
42
  governanceAddress: schemas.EthAddress,
43
43
  slashFactoryAddress: schemas.EthAddress.optional(),
44
+ feeAssetHandlerAddress: schemas.EthAddress.optional(),
44
45
  }) satisfies ZodFor<L1ContractAddresses>;
45
46
 
46
47
  const parseEnv = (val: string) => EthAddress.fromString(val);
@@ -106,4 +107,9 @@ export const l1ContractAddressesMapping: ConfigMappingsType<L1ContractAddresses>
106
107
  description: 'The deployed L1 slashFactory contract address',
107
108
  parseEnv,
108
109
  },
110
+ feeAssetHandlerAddress: {
111
+ env: 'FEE_ASSET_HANDLER_CONTRACT_ADDRESS',
112
+ description: 'The deployed L1 feeAssetHandler contract address',
113
+ parseEnv,
114
+ },
109
115
  };
@@ -108,7 +108,7 @@ export const l1TxUtilsConfigMappings: ConfigMappingsType<L1TxUtilsConfig> = {
108
108
  maxGwei: {
109
109
  description: 'Maximum gas price in gwei',
110
110
  env: 'L1_GAS_PRICE_MAX',
111
- ...bigintConfigHelper(100n),
111
+ ...bigintConfigHelper(500n),
112
112
  },
113
113
  maxBlobGwei: {
114
114
  description: 'Maximum blob fee per gas in gwei',
@@ -209,7 +209,6 @@ export class L1TxUtils {
209
209
  ...defaultL1TxUtilsConfig,
210
210
  ...(config || {}),
211
211
  };
212
- this.logger?.debug('Initializing L1 TX utils with config', { config: this.config });
213
212
  }
214
213
 
215
214
  public interrupt() {
package/src/queries.ts CHANGED
@@ -33,6 +33,8 @@ export async function getL1ContractsConfig(
33
33
  governanceProposerRoundSize,
34
34
  slashingQuorum,
35
35
  slashingRoundSize,
36
+ manaTarget,
37
+ provingCostPerMana,
36
38
  ] = await Promise.all([
37
39
  rollup.getL1StartBlock(),
38
40
  rollup.getL1GenesisTime(),
@@ -45,6 +47,8 @@ export async function getL1ContractsConfig(
45
47
  governanceProposer.getRoundSize(),
46
48
  slasherProposer.getQuorumSize(),
47
49
  slasherProposer.getRoundSize(),
50
+ rollup.getManaTarget(),
51
+ rollup.getProvingCostPerMana(),
48
52
  ] as const);
49
53
 
50
54
  return {
@@ -59,6 +63,8 @@ export async function getL1ContractsConfig(
59
63
  minimumStake,
60
64
  slashingQuorum: Number(slashingQuorum),
61
65
  slashingRoundSize: Number(slashingRoundSize),
66
+ manaTarget: manaTarget,
67
+ provingCostPerMana: provingCostPerMana,
62
68
  };
63
69
  }
64
70
 
@@ -1,11 +1,12 @@
1
1
  import type { Logger } from '@aztec/foundation/log';
2
2
  import { GovernanceAbi } from '@aztec/l1-artifacts/GovernanceAbi';
3
- import { TestERC20Abi as FeeJuiceAbi } from '@aztec/l1-artifacts/TestERC20Abi';
3
+ import { TestERC20Abi as StakingAssetAbi } from '@aztec/l1-artifacts/TestERC20Abi';
4
4
 
5
5
  import { type GetContractReturnType, type PrivateKeyAccount, getContract } from 'viem';
6
6
 
7
7
  import { EthCheatCodes } from '../eth_cheat_codes.js';
8
8
  import type { L1ContractAddresses } from '../l1_contract_addresses.js';
9
+ import { L1TxUtils } from '../l1_tx_utils.js';
9
10
  import type { L1Clients } from '../types.js';
10
11
 
11
12
  export async function executeGovernanceProposal(
@@ -20,13 +21,12 @@ export async function executeGovernanceProposal(
20
21
  ) {
21
22
  const proposal = await governance.read.getProposal([proposalId]);
22
23
 
24
+ const l1TxUtils = new L1TxUtils(publicClient, walletClient);
25
+
23
26
  const waitL1Block = async () => {
24
- await publicClient.waitForTransactionReceipt({
25
- hash: await walletClient.sendTransaction({
26
- to: privateKey.address,
27
- value: 1n,
28
- account: privateKey,
29
- }),
27
+ await l1TxUtils.sendAndMonitorTransaction({
28
+ to: walletClient.account.address,
29
+ value: 1n,
30
30
  });
31
31
  };
32
32
 
@@ -62,8 +62,8 @@ export async function createGovernanceProposal(
62
62
  logger: Logger,
63
63
  ): Promise<{ governance: GetContractReturnType<typeof GovernanceAbi, L1Clients['publicClient']>; voteAmount: bigint }> {
64
64
  const token = getContract({
65
- address: addresses.feeJuiceAddress.toString(),
66
- abi: FeeJuiceAbi,
65
+ address: addresses.stakingAssetAddress.toString(),
66
+ abi: StakingAssetAbi,
67
67
  client: publicClient,
68
68
  });
69
69