@aztec/end-to-end 2.0.0-nightly.20250902 → 2.0.0-rc.1

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 (38) hide show
  1. package/dest/bench/client_flows/client_flows_benchmark.d.ts +1 -1
  2. package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
  3. package/dest/bench/client_flows/client_flows_benchmark.js +6 -7
  4. package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
  5. package/dest/e2e_epochs/epochs_test.js +2 -2
  6. package/dest/e2e_fees/bridging_race.notest.js +3 -5
  7. package/dest/e2e_fees/fees_test.d.ts +1 -1
  8. package/dest/e2e_fees/fees_test.d.ts.map +1 -1
  9. package/dest/e2e_fees/fees_test.js +4 -5
  10. package/dest/e2e_l1_publisher/write_json.d.ts.map +1 -0
  11. package/dest/fixtures/e2e_prover_test.d.ts +1 -1
  12. package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
  13. package/dest/fixtures/e2e_prover_test.js +10 -10
  14. package/dest/fixtures/snapshot_manager.d.ts.map +1 -1
  15. package/dest/fixtures/snapshot_manager.js +1 -21
  16. package/dest/fixtures/utils.d.ts.map +1 -1
  17. package/dest/fixtures/utils.js +1 -3
  18. package/dest/shared/gas_portal_test_harness.d.ts +5 -5
  19. package/dest/shared/gas_portal_test_harness.d.ts.map +1 -1
  20. package/dest/shared/gas_portal_test_harness.js +6 -16
  21. package/dest/spartan/utils.d.ts +35 -22
  22. package/dest/spartan/utils.d.ts.map +1 -1
  23. package/dest/spartan/utils.js +117 -46
  24. package/package.json +36 -36
  25. package/src/bench/client_flows/client_flows_benchmark.ts +9 -17
  26. package/src/e2e_epochs/epochs_test.ts +7 -2
  27. package/src/e2e_fees/bridging_race.notest.ts +6 -5
  28. package/src/e2e_fees/fees_test.ts +7 -9
  29. package/src/fixtures/e2e_prover_test.ts +7 -6
  30. package/src/fixtures/snapshot_manager.ts +1 -28
  31. package/src/fixtures/utils.ts +1 -3
  32. package/src/shared/gas_portal_test_harness.ts +8 -17
  33. package/src/spartan/DEVELOP.md +116 -0
  34. package/src/spartan/utils.ts +126 -48
  35. package/dest/integration_l1_publisher/write_json.d.ts.map +0 -1
  36. /package/dest/{integration_l1_publisher → e2e_l1_publisher}/write_json.d.ts +0 -0
  37. /package/dest/{integration_l1_publisher → e2e_l1_publisher}/write_json.js +0 -0
  38. /package/src/{integration_l1_publisher → e2e_l1_publisher}/write_json.ts +0 -0
@@ -1,27 +1,23 @@
1
1
  import { createLogger, sleep } from '@aztec/aztec.js';
2
2
  import { makeBackoff, retry } from '@aztec/foundation/retry';
3
- import { createAztecNodeAdminClient } from '@aztec/stdlib/interfaces/client';
3
+ import { schemas } from '@aztec/foundation/schemas';
4
+ import { createAztecNodeAdminClient, createAztecNodeClient } from '@aztec/stdlib/interfaces/client';
4
5
  import { exec, execSync, spawn } from 'child_process';
5
6
  import path from 'path';
6
7
  import { promisify } from 'util';
8
+ import { createPublicClient, fallback, http } from 'viem';
7
9
  import { z } from 'zod';
8
- export const RPC_SERVICE_NAME = 'services/aztec-infra-rpc-aztec-node';
9
10
  const execAsync = promisify(exec);
10
11
  const logger = createLogger('e2e:k8s-utils');
11
12
  const testConfigSchema = z.object({
12
- NAMESPACE: z.string().min(1, 'NAMESPACE env variable must be set'),
13
- L1_ACCOUNT_MNEMONIC: z.string().default('test test test test test test test test test test test junk'),
14
- K8S_CLUSTER: z.string().min(1, 'K8S_CLUSTER env variable must be set'),
15
- REGION: z.string().optional(),
16
- PROJECT_ID: z.string().optional(),
17
- AZTEC_REAL_PROOFS: z.coerce.boolean().default(false)
13
+ NAMESPACE: z.string().default('scenario'),
14
+ REAL_VERIFIER: schemas.Boolean.optional().default(true),
15
+ CREATE_ETH_DEVNET: schemas.Boolean.optional().default(false),
16
+ L1_RPC_URLS_JSON: z.string().optional()
18
17
  });
19
18
  export function setupEnvironment(env) {
20
19
  const config = testConfigSchema.parse(env);
21
- if (config.K8S_CLUSTER !== 'kind') {
22
- const command = `gcloud container clusters get-credentials ${config.K8S_CLUSTER} --region=${config.REGION} --project=${config.PROJECT_ID}`;
23
- execSync(command);
24
- }
20
+ logger.warn(`Loaded env config`, config);
25
21
  return config;
26
22
  }
27
23
  /**
@@ -73,7 +69,7 @@ export function runProjectScript(script, args, logger, env) {
73
69
  }
74
70
  export async function startPortForward({ resource, namespace, containerPort, hostPort }) {
75
71
  const hostPortAsString = hostPort ? hostPort.toString() : '';
76
- logger.info(`kubectl port-forward -n ${namespace} ${resource} ${hostPortAsString}:${containerPort}`);
72
+ logger.debug(`kubectl port-forward -n ${namespace} ${resource} ${hostPortAsString}:${containerPort}`);
77
73
  const process1 = spawn('kubectl', [
78
74
  'port-forward',
79
75
  '-n',
@@ -95,20 +91,20 @@ export async function startPortForward({ resource, namespace, containerPort, hos
95
91
  const str = data.toString();
96
92
  if (!isResolved && str.includes('Forwarding from')) {
97
93
  isResolved = true;
98
- logger.info(str);
94
+ logger.debug(`Port forward for ${resource}: ${str}`);
99
95
  const port = str.search(/:\d+/);
100
96
  if (port === -1) {
101
97
  throw new Error('Port not found in port forward output');
102
98
  }
103
99
  const portNumber = parseInt(str.slice(port + 1));
104
- logger.info(`Port forward connected: ${portNumber}`);
100
+ logger.verbose(`Port forwarded for ${resource} at ${portNumber}:${containerPort}`);
105
101
  resolve(portNumber);
106
102
  } else {
107
103
  logger.silent(str);
108
104
  }
109
105
  });
110
106
  process1.stderr?.on('data', (data)=>{
111
- logger.info(data.toString());
107
+ logger.verbose(`Port forward for ${resource}: ${data.toString()}`);
112
108
  // It's a strange thing:
113
109
  // If we don't pipe stderr, then the port forwarding does not work.
114
110
  // Log to silent because this doesn't actually report errors,
@@ -118,16 +114,16 @@ export async function startPortForward({ resource, namespace, containerPort, hos
118
114
  process1.on('close', ()=>{
119
115
  if (!isResolved) {
120
116
  isResolved = true;
121
- logger.warn('Port forward closed before connection established');
117
+ logger.warn(`Port forward for ${resource} closed before connection established`);
122
118
  resolve(0);
123
119
  }
124
120
  });
125
121
  process1.on('error', (error)=>{
126
- logger.error(`Port forward error: ${error}`);
122
+ logger.error(`Port forward for ${resource} error: ${error}`);
127
123
  resolve(0);
128
124
  });
129
125
  process1.on('exit', (code)=>{
130
- logger.info(`Port forward exited with code ${code}`);
126
+ logger.verbose(`Port forward for ${resource} exited with code ${code}`);
131
127
  resolve(0);
132
128
  });
133
129
  });
@@ -139,19 +135,26 @@ export async function startPortForward({ resource, namespace, containerPort, hos
139
135
  }
140
136
  export function startPortForwardForRPC(namespace) {
141
137
  return startPortForward({
142
- resource: RPC_SERVICE_NAME,
138
+ resource: `services/${namespace}-rpc-aztec-node`,
143
139
  namespace,
144
140
  containerPort: 8080
145
141
  });
146
142
  }
143
+ export function startPortForwardForEthereum(namespace) {
144
+ return startPortForward({
145
+ resource: `services/${namespace}-eth-execution`,
146
+ namespace,
147
+ containerPort: 8545
148
+ });
149
+ }
147
150
  export async function deleteResourceByName({ resource, namespace, name, force = false }) {
148
151
  const command = `kubectl delete ${resource} ${name} -n ${namespace} --ignore-not-found=true --wait=true ${force ? '--force' : ''}`;
149
152
  logger.info(`command: ${command}`);
150
153
  const { stdout } = await execAsync(command);
151
154
  return stdout;
152
155
  }
153
- export async function deleteResourceByLabel({ resource, namespace, label, timeout = '5m' }) {
154
- const command = `kubectl delete ${resource} -l ${label} -n ${namespace} --ignore-not-found=true --wait=true --timeout=${timeout}`;
156
+ export async function deleteResourceByLabel({ resource, namespace, label, timeout = '5m', force = false }) {
157
+ const command = `kubectl delete ${resource} -l ${label} -n ${namespace} --ignore-not-found=true --wait=true --timeout=${timeout} ${force ? '--force' : ''}`;
155
158
  logger.info(`command: ${command}`);
156
159
  const { stdout } = await execAsync(command);
157
160
  return stdout;
@@ -204,13 +207,13 @@ async function execHelmCommand(args) {
204
207
  const deleteArgs = {
205
208
  resource: 'podchaos',
206
209
  namespace: chaosMeshNamespace,
207
- name: `${targetNamespace}-${instanceName}`
210
+ label: `app.kubernetes.io/instance=${instanceName}`
208
211
  };
209
212
  logger.info(`Deleting podchaos resource`);
210
- await deleteResourceByName(deleteArgs).catch((e)=>{
213
+ await deleteResourceByLabel(deleteArgs).catch((e)=>{
211
214
  logger.error(`Error deleting podchaos resource: ${e}`);
212
215
  logger.info(`Force deleting podchaos resource`);
213
- return deleteResourceByName({
216
+ return deleteResourceByLabel({
214
217
  ...deleteArgs,
215
218
  force: true
216
219
  });
@@ -336,40 +339,108 @@ export async function enableValidatorDynamicBootNode(instanceName, namespace, sp
336
339
  });
337
340
  logger.info(`Validator dynamic boot node enabled`);
338
341
  }
339
- export async function updateSequencerConfig(url, config) {
340
- const node = createAztecNodeAdminClient(url);
341
- // Retry incase the port forward is not ready yet
342
- await retry(()=>node.setConfig(config), 'Update sequencer config', makeBackoff([
343
- 1,
344
- 3,
345
- 6
346
- ]), logger);
347
- }
348
342
  export async function getSequencers(namespace) {
349
- const command = `kubectl get pods -l app=validator -n ${namespace} -o jsonpath='{.items[*].metadata.name}'`;
343
+ const command = `kubectl get pods -l app.kubernetes.io/component=validator -n ${namespace} -o jsonpath='{.items[*].metadata.name}'`;
350
344
  const { stdout } = await execAsync(command);
351
- return stdout.split(' ');
345
+ const sequencers = stdout.split(' ');
346
+ logger.verbose(`Found sequencer pods ${sequencers.join(', ')}`);
347
+ return sequencers;
352
348
  }
353
- async function updateK8sSequencersConfig(args) {
354
- const { containerPort, namespace, config } = args;
349
+ export function updateSequencersConfig(env, config) {
350
+ return withSequencersAdmin(env, async (client)=>{
351
+ await client.setConfig(config);
352
+ return client.getConfig();
353
+ });
354
+ }
355
+ export function getSequencersConfig(env) {
356
+ return withSequencersAdmin(env, (client)=>client.getConfig());
357
+ }
358
+ export async function withSequencersAdmin(env, fn) {
359
+ const adminContainerPort = 8880;
360
+ const namespace = env.NAMESPACE;
355
361
  const sequencers = await getSequencers(namespace);
362
+ const results = [];
356
363
  for (const sequencer of sequencers){
357
364
  const { process: process1, port } = await startPortForward({
358
365
  resource: `pod/${sequencer}`,
359
366
  namespace,
360
- containerPort
367
+ containerPort: adminContainerPort
361
368
  });
362
369
  const url = `http://localhost:${port}`;
363
- await updateSequencerConfig(url, config);
370
+ await retry(()=>fetch(`${url}/status`).then((res)=>res.status === 200), 'forward node admin port', makeBackoff([
371
+ 1,
372
+ 1,
373
+ 2,
374
+ 6
375
+ ]), logger, true);
376
+ const client = createAztecNodeAdminClient(url);
377
+ results.push(await fn(client));
364
378
  process1.kill();
365
379
  }
380
+ return results;
366
381
  }
367
- export async function updateSequencersConfig(env, config) {
368
- await updateK8sSequencersConfig({
369
- containerPort: 8880,
370
- namespace: env.NAMESPACE,
371
- config
372
- });
382
+ /**
383
+ * Returns a public viem client to the eth execution node. If it was part of a local eth devnet,
384
+ * it first port-forwards the service and points to it. Otherwise, just uses the external RPC url.
385
+ */ export async function getPublicViemClient(env, /** If set, will push the new process into it */ processes) {
386
+ const { NAMESPACE, CREATE_ETH_DEVNET, L1_RPC_URLS_JSON } = env;
387
+ if (CREATE_ETH_DEVNET) {
388
+ logger.info(`Creating port forward to eth execution node`);
389
+ const { process: process1, port } = await startPortForward({
390
+ resource: `svc/${NAMESPACE}-eth-execution`,
391
+ namespace: NAMESPACE,
392
+ containerPort: 8545
393
+ });
394
+ const url = `http://127.0.0.1:${port}`;
395
+ const client = createPublicClient({
396
+ transport: fallback([
397
+ http(url)
398
+ ])
399
+ });
400
+ if (processes) {
401
+ processes.push(process1);
402
+ }
403
+ return {
404
+ url,
405
+ client,
406
+ process: process1
407
+ };
408
+ } else {
409
+ logger.info(`Connecting to the eth execution node at ${L1_RPC_URLS_JSON}`);
410
+ if (!L1_RPC_URLS_JSON) {
411
+ throw new Error(`L1_RPC_URLS_JSON is not defined`);
412
+ }
413
+ const client = createPublicClient({
414
+ transport: fallback([
415
+ http(L1_RPC_URLS_JSON)
416
+ ])
417
+ });
418
+ return {
419
+ url: L1_RPC_URLS_JSON,
420
+ client
421
+ };
422
+ }
423
+ }
424
+ /** Queries an Aztec node for the L1 deployment addresses */ export async function getL1DeploymentAddresses(env) {
425
+ let forwardProcess;
426
+ try {
427
+ const [sequencer] = await getSequencers(env.NAMESPACE);
428
+ const { process: process1, port } = await startPortForward({
429
+ resource: `pod/${sequencer}`,
430
+ namespace: env.NAMESPACE,
431
+ containerPort: 8080
432
+ });
433
+ forwardProcess = process1;
434
+ const url = `http://127.0.0.1:${port}`;
435
+ const node = createAztecNodeClient(url);
436
+ return await retry(()=>node.getNodeInfo().then((i)=>i.l1ContractAddresses), 'get node info', makeBackoff([
437
+ 1,
438
+ 3,
439
+ 6
440
+ ]), logger);
441
+ } finally{
442
+ forwardProcess?.kill();
443
+ }
373
444
  }
374
445
  /**
375
446
  * Rolls the Aztec pods in the given namespace.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aztec/end-to-end",
3
- "version": "2.0.0-nightly.20250902",
3
+ "version": "2.0.0-rc.1",
4
4
  "type": "module",
5
5
  "exports": "./dest/index.js",
6
6
  "inherits": [
@@ -25,41 +25,41 @@
25
25
  "formatting": "run -T prettier --check ./src && run -T eslint ./src"
26
26
  },
27
27
  "dependencies": {
28
- "@aztec/accounts": "2.0.0-nightly.20250902",
29
- "@aztec/archiver": "2.0.0-nightly.20250902",
30
- "@aztec/aztec": "2.0.0-nightly.20250902",
31
- "@aztec/aztec-node": "2.0.0-nightly.20250902",
32
- "@aztec/aztec.js": "2.0.0-nightly.20250902",
33
- "@aztec/bb-prover": "2.0.0-nightly.20250902",
34
- "@aztec/blob-lib": "2.0.0-nightly.20250902",
35
- "@aztec/blob-sink": "2.0.0-nightly.20250902",
36
- "@aztec/bot": "2.0.0-nightly.20250902",
37
- "@aztec/cli": "2.0.0-nightly.20250902",
38
- "@aztec/constants": "2.0.0-nightly.20250902",
39
- "@aztec/entrypoints": "2.0.0-nightly.20250902",
40
- "@aztec/epoch-cache": "2.0.0-nightly.20250902",
41
- "@aztec/ethereum": "2.0.0-nightly.20250902",
42
- "@aztec/foundation": "2.0.0-nightly.20250902",
43
- "@aztec/kv-store": "2.0.0-nightly.20250902",
44
- "@aztec/l1-artifacts": "2.0.0-nightly.20250902",
45
- "@aztec/merkle-tree": "2.0.0-nightly.20250902",
46
- "@aztec/node-keystore": "2.0.0-nightly.20250902",
47
- "@aztec/noir-contracts.js": "2.0.0-nightly.20250902",
48
- "@aztec/noir-noirc_abi": "2.0.0-nightly.20250902",
49
- "@aztec/noir-protocol-circuits-types": "2.0.0-nightly.20250902",
50
- "@aztec/noir-test-contracts.js": "2.0.0-nightly.20250902",
51
- "@aztec/p2p": "2.0.0-nightly.20250902",
52
- "@aztec/protocol-contracts": "2.0.0-nightly.20250902",
53
- "@aztec/prover-client": "2.0.0-nightly.20250902",
54
- "@aztec/prover-node": "2.0.0-nightly.20250902",
55
- "@aztec/pxe": "2.0.0-nightly.20250902",
56
- "@aztec/sequencer-client": "2.0.0-nightly.20250902",
57
- "@aztec/simulator": "2.0.0-nightly.20250902",
58
- "@aztec/slasher": "2.0.0-nightly.20250902",
59
- "@aztec/stdlib": "2.0.0-nightly.20250902",
60
- "@aztec/telemetry-client": "2.0.0-nightly.20250902",
61
- "@aztec/validator-client": "2.0.0-nightly.20250902",
62
- "@aztec/world-state": "2.0.0-nightly.20250902",
28
+ "@aztec/accounts": "2.0.0-rc.1",
29
+ "@aztec/archiver": "2.0.0-rc.1",
30
+ "@aztec/aztec": "2.0.0-rc.1",
31
+ "@aztec/aztec-node": "2.0.0-rc.1",
32
+ "@aztec/aztec.js": "2.0.0-rc.1",
33
+ "@aztec/bb-prover": "2.0.0-rc.1",
34
+ "@aztec/blob-lib": "2.0.0-rc.1",
35
+ "@aztec/blob-sink": "2.0.0-rc.1",
36
+ "@aztec/bot": "2.0.0-rc.1",
37
+ "@aztec/cli": "2.0.0-rc.1",
38
+ "@aztec/constants": "2.0.0-rc.1",
39
+ "@aztec/entrypoints": "2.0.0-rc.1",
40
+ "@aztec/epoch-cache": "2.0.0-rc.1",
41
+ "@aztec/ethereum": "2.0.0-rc.1",
42
+ "@aztec/foundation": "2.0.0-rc.1",
43
+ "@aztec/kv-store": "2.0.0-rc.1",
44
+ "@aztec/l1-artifacts": "2.0.0-rc.1",
45
+ "@aztec/merkle-tree": "2.0.0-rc.1",
46
+ "@aztec/node-keystore": "2.0.0-rc.1",
47
+ "@aztec/noir-contracts.js": "2.0.0-rc.1",
48
+ "@aztec/noir-noirc_abi": "2.0.0-rc.1",
49
+ "@aztec/noir-protocol-circuits-types": "2.0.0-rc.1",
50
+ "@aztec/noir-test-contracts.js": "2.0.0-rc.1",
51
+ "@aztec/p2p": "2.0.0-rc.1",
52
+ "@aztec/protocol-contracts": "2.0.0-rc.1",
53
+ "@aztec/prover-client": "2.0.0-rc.1",
54
+ "@aztec/prover-node": "2.0.0-rc.1",
55
+ "@aztec/pxe": "2.0.0-rc.1",
56
+ "@aztec/sequencer-client": "2.0.0-rc.1",
57
+ "@aztec/simulator": "2.0.0-rc.1",
58
+ "@aztec/slasher": "2.0.0-rc.1",
59
+ "@aztec/stdlib": "2.0.0-rc.1",
60
+ "@aztec/telemetry-client": "2.0.0-rc.1",
61
+ "@aztec/validator-client": "2.0.0-rc.1",
62
+ "@aztec/world-state": "2.0.0-rc.1",
63
63
  "@iarna/toml": "^2.2.5",
64
64
  "@jest/globals": "^30.0.0",
65
65
  "@noble/curves": "=1.0.0",
@@ -16,7 +16,6 @@ import {
16
16
  createLogger,
17
17
  } from '@aztec/aztec.js';
18
18
  import { CheatCodes } from '@aztec/aztec/testing';
19
- import { FEE_FUNDING_FOR_TESTER_ACCOUNT } from '@aztec/constants';
20
19
  import { type DeployL1ContractsArgs, RollupContract, createExtendedL1Client, deployL1Contract } from '@aztec/ethereum';
21
20
  import { ChainMonitor } from '@aztec/ethereum/test';
22
21
  import { randomBytes } from '@aztec/foundation/crypto';
@@ -155,10 +154,13 @@ export class ClientFlowsBenchmark {
155
154
  await this.snapshotManager.teardown();
156
155
  }
157
156
 
158
- async mintAndBridgeFeeJuice(address: AztecAddress, amount: bigint) {
159
- const claim = await this.feeJuiceBridgeTestHarness.prepareTokensOnL1(amount, address);
157
+ async mintAndBridgeFeeJuice(address: AztecAddress) {
158
+ const claim = await this.feeJuiceBridgeTestHarness.prepareTokensOnL1(address);
160
159
  const { claimSecret: secret, messageLeafIndex: index } = claim;
161
- await this.feeJuiceContract.methods.claim(address, amount, secret, index).send({ from: this.adminAddress }).wait();
160
+ await this.feeJuiceContract.methods
161
+ .claim(address, claim.claimAmount, secret, index)
162
+ .send({ from: this.adminAddress })
163
+ .wait();
162
164
  }
163
165
 
164
166
  /** Admin mints bananaCoin tokens privately to the target address and redeems them. */
@@ -304,11 +306,7 @@ export class ClientFlowsBenchmark {
304
306
 
305
307
  this.logger.info(`BananaPay deployed at ${bananaFPC.address}`);
306
308
 
307
- await this.feeJuiceBridgeTestHarness.bridgeFromL1ToL2(
308
- FEE_FUNDING_FOR_TESTER_ACCOUNT,
309
- bananaFPC.address,
310
- this.adminAddress,
311
- );
309
+ await this.feeJuiceBridgeTestHarness.bridgeFromL1ToL2(bananaFPC.address, this.adminAddress);
312
310
 
313
311
  return { bananaFPCAddress: bananaFPC.address };
314
312
  },
@@ -361,10 +359,7 @@ export class ClientFlowsBenchmark {
361
359
  const benchysAccountManager = await this.createBenchmarkingAccountManager(this.pxe, accountType);
362
360
  const benchysWallet = await benchysAccountManager.getWallet();
363
361
  const benchysAddress = benchysAccountManager.getAddress();
364
- const claim = await this.feeJuiceBridgeTestHarness.prepareTokensOnL1(
365
- FEE_FUNDING_FOR_TESTER_ACCOUNT,
366
- benchysAddress,
367
- );
362
+ const claim = await this.feeJuiceBridgeTestHarness.prepareTokensOnL1(benchysAddress);
368
363
  const paymentMethod = new FeeJuicePaymentMethodWithClaim(benchysWallet, claim);
369
364
  await benchysAccountManager.deploy({ fee: { paymentMethod } }).wait();
370
365
  // Register benchy on the user's PXE, where we're going to be interacting from
@@ -409,10 +404,7 @@ export class ClientFlowsBenchmark {
409
404
  }
410
405
 
411
406
  public async getBridgedFeeJuicePaymentMethodForWallet(wallet: Wallet) {
412
- const claim = await this.feeJuiceBridgeTestHarness.prepareTokensOnL1(
413
- FEE_FUNDING_FOR_TESTER_ACCOUNT,
414
- wallet.getAddress(),
415
- );
407
+ const claim = await this.feeJuiceBridgeTestHarness.prepareTokensOnL1(wallet.getAddress());
416
408
  return new FeeJuicePaymentMethodWithClaim(wallet, claim);
417
409
  }
418
410
 
@@ -92,7 +92,7 @@ export class EpochsTestContext {
92
92
  : DEFAULT_L1_BLOCK_TIME;
93
93
  const ethereumSlotDuration = opts.ethereumSlotDuration ?? envEthereumSlotDuration;
94
94
  const aztecSlotDuration = opts.aztecSlotDuration ?? ethereumSlotDuration * 2;
95
- const aztecEpochDuration = opts.aztecEpochDuration ?? 4;
95
+ const aztecEpochDuration = opts.aztecEpochDuration ?? 6;
96
96
  const aztecProofSubmissionEpochs = opts.aztecProofSubmissionEpochs ?? 1;
97
97
  return { ethereumSlotDuration, aztecSlotDuration, aztecEpochDuration, aztecProofSubmissionEpochs };
98
98
  }
@@ -278,7 +278,12 @@ export class EpochsTestContext {
278
278
  public async waitUntilEpochStarts(epoch: number) {
279
279
  const [start] = getTimestampRangeForEpoch(BigInt(epoch), this.constants);
280
280
  this.logger.info(`Waiting until L1 timestamp ${start} is reached as the start of epoch ${epoch}`);
281
- await waitUntilL1Timestamp(this.l1Client, start - BigInt(this.L1_BLOCK_TIME_IN_S));
281
+ await waitUntilL1Timestamp(
282
+ this.l1Client,
283
+ start - BigInt(this.L1_BLOCK_TIME_IN_S),
284
+ undefined,
285
+ 30 * this.epochDuration,
286
+ );
282
287
  return start;
283
288
  }
284
289
 
@@ -1,6 +1,5 @@
1
1
  import { getSchnorrAccount } from '@aztec/accounts/schnorr';
2
2
  import { Fr, type Logger, type PXE, sleep } from '@aztec/aztec.js';
3
- import { FEE_FUNDING_FOR_TESTER_ACCOUNT } from '@aztec/constants';
4
3
  import { Fq } from '@aztec/foundation/fields';
5
4
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
6
5
 
@@ -64,11 +63,13 @@ describe('e2e_fees bridging_race', () => {
64
63
  // Waiting for the archiver to sync the message _before_ waiting for the mandatory 2 L2 blocks to pass fixed it
65
64
  // This was added everywhere we wait for two blocks, which is spread across three different places in the codebase
66
65
  // Yes, we need to REFACTOR it at some point
67
- const amount = FEE_FUNDING_FOR_TESTER_ACCOUNT;
68
- const claim = await t.feeJuiceBridgeTestHarness.prepareTokensOnL1(amount, bobsAddress);
66
+ const claim = await t.feeJuiceBridgeTestHarness.prepareTokensOnL1(bobsAddress);
69
67
  const { claimSecret: secret, messageLeafIndex: index } = claim;
70
- await t.feeJuiceContract.methods.claim(bobsAddress, amount, secret, index).send({ from: bobsAddress }).wait();
68
+ await t.feeJuiceContract.methods
69
+ .claim(bobsAddress, claim.claimAmount, secret, index)
70
+ .send({ from: bobsAddress })
71
+ .wait();
71
72
  const [balance] = await t.getGasBalanceFn(bobsAddress);
72
- expect(balance).toEqual(amount);
73
+ expect(balance).toEqual(claim.claimAmount);
73
74
  });
74
75
  });
@@ -9,7 +9,6 @@ import {
9
9
  sleep,
10
10
  } from '@aztec/aztec.js';
11
11
  import { CheatCodes } from '@aztec/aztec/testing';
12
- import { FEE_FUNDING_FOR_TESTER_ACCOUNT } from '@aztec/constants';
13
12
  import { type DeployL1ContractsArgs, RollupContract, createExtendedL1Client } from '@aztec/ethereum';
14
13
  import { ChainMonitor } from '@aztec/ethereum/test';
15
14
  import { EthAddress } from '@aztec/foundation/eth-address';
@@ -158,10 +157,13 @@ export class FeesTest {
158
157
  return { sequencerBlockRewards, proverBlockRewards };
159
158
  }
160
159
 
161
- async mintAndBridgeFeeJuice(minter: AztecAddress, recipient: AztecAddress, amount: bigint) {
162
- const claim = await this.feeJuiceBridgeTestHarness.prepareTokensOnL1(amount, recipient);
160
+ async mintAndBridgeFeeJuice(minter: AztecAddress, recipient: AztecAddress) {
161
+ const claim = await this.feeJuiceBridgeTestHarness.prepareTokensOnL1(recipient);
163
162
  const { claimSecret: secret, messageLeafIndex: index } = claim;
164
- await this.feeJuiceContract.methods.claim(recipient, amount, secret, index).send({ from: minter }).wait();
163
+ await this.feeJuiceContract.methods
164
+ .claim(recipient, claim.claimAmount, secret, index)
165
+ .send({ from: minter })
166
+ .wait();
165
167
  }
166
168
 
167
169
  /** Alice mints bananaCoin tokens privately to the target address and redeems them. */
@@ -287,11 +289,7 @@ export class FeesTest {
287
289
 
288
290
  this.logger.info(`BananaPay deployed at ${bananaFPC.address}`);
289
291
 
290
- await this.feeJuiceBridgeTestHarness.bridgeFromL1ToL2(
291
- FEE_FUNDING_FOR_TESTER_ACCOUNT,
292
- bananaFPC.address,
293
- this.aliceAddress,
294
- );
292
+ await this.feeJuiceBridgeTestHarness.bridgeFromL1ToL2(bananaFPC.address, this.aliceAddress);
295
293
 
296
294
  return {
297
295
  bananaFPCAddress: bananaFPC.address,
@@ -26,7 +26,7 @@ import type { BlobSinkServer } from '@aztec/blob-sink/server';
26
26
  import type { DeployL1ContractsReturnType } from '@aztec/ethereum';
27
27
  import { Buffer32 } from '@aztec/foundation/buffer';
28
28
  import { SecretValue } from '@aztec/foundation/config';
29
- import { TestERC20Abi } from '@aztec/l1-artifacts';
29
+ import { FeeAssetHandlerAbi } from '@aztec/l1-artifacts';
30
30
  import { TokenContract } from '@aztec/noir-contracts.js/Token';
31
31
  import { type ProverNode, type ProverNodeConfig, createProverNode } from '@aztec/prover-node';
32
32
  import type { PXEService } from '@aztec/pxe/server';
@@ -289,7 +289,7 @@ export class FullProverTest {
289
289
  this.proverAddress = EthAddress.fromString(proverNodeSenderAddress);
290
290
 
291
291
  this.logger.verbose(`Funding prover node at ${proverNodeSenderAddress}`);
292
- await this.mintL1ERC20(proverNodeSenderAddress, 100_000_000n);
292
+ await this.mintFeeJuice(proverNodeSenderAddress);
293
293
 
294
294
  this.logger.verbose('Starting prover node');
295
295
  const proverConfig: ProverNodeConfig = {
@@ -328,11 +328,12 @@ export class FullProverTest {
328
328
  return this;
329
329
  }
330
330
 
331
- private async mintL1ERC20(recipient: Hex, amount: bigint) {
332
- const erc20Address = this.context.deployL1ContractsValues.l1ContractAddresses.feeJuiceAddress;
331
+ private async mintFeeJuice(recipient: Hex) {
332
+ const handlerAddress = this.context.deployL1ContractsValues.l1ContractAddresses.feeAssetHandlerAddress!;
333
+ this.logger.verbose(`Minting fee juice to ${recipient} using handler at ${handlerAddress}`);
333
334
  const client = this.context.deployL1ContractsValues.l1Client;
334
- const erc20 = getContract({ abi: TestERC20Abi, address: erc20Address.toString(), client });
335
- const hash = await erc20.write.mint([recipient, amount]);
335
+ const handler = getContract({ abi: FeeAssetHandlerAbi, address: handlerAddress.toString(), client });
336
+ const hash = await handler.write.mint([recipient]);
336
337
  await this.context.deployL1ContractsValues.l1Client.waitForTransactionReceipt({ hash });
337
338
  }
338
339
 
@@ -21,8 +21,6 @@ import { type BlobSinkServer, createBlobSinkServer } from '@aztec/blob-sink/serv
21
21
  import {
22
22
  type DeployL1ContractsArgs,
23
23
  type DeployL1ContractsReturnType,
24
- FeeAssetArtifact,
25
- RollupContract,
26
24
  createExtendedL1Client,
27
25
  deployMulticall3,
28
26
  getL1ContractsConfigEnvVars,
@@ -49,7 +47,7 @@ import fs from 'fs/promises';
49
47
  import getPort from 'get-port';
50
48
  import { tmpdir } from 'os';
51
49
  import path, { join } from 'path';
52
- import { type Hex, getContract } from 'viem';
50
+ import type { Hex } from 'viem';
53
51
  import { mnemonicToAccount } from 'viem/accounts';
54
52
  import { foundry } from 'viem/chains';
55
53
 
@@ -383,31 +381,6 @@ async function setupFromFresh(
383
381
  aztecNodeConfig.rollupVersion = deployL1ContractsValues.rollupVersion;
384
382
  aztecNodeConfig.l1PublishRetryIntervalMS = 100;
385
383
 
386
- if (opts.fundRewardDistributor) {
387
- // Mints block rewards for 10000 blocks to the rewardDistributor contract
388
-
389
- const rollup = new RollupContract(
390
- deployL1ContractsValues.l1Client,
391
- deployL1ContractsValues.l1ContractAddresses.rollupAddress,
392
- );
393
-
394
- const blockReward = await rollup.getBlockReward();
395
- const mintAmount = 10_000n * (blockReward as bigint);
396
-
397
- const feeJuice = getContract({
398
- address: deployL1ContractsValues.l1ContractAddresses.feeJuiceAddress.toString(),
399
- abi: FeeAssetArtifact.contractAbi,
400
- client: deployL1ContractsValues.l1Client,
401
- });
402
-
403
- const rewardDistributorMintTxHash = await feeJuice.write.mint(
404
- [deployL1ContractsValues.l1ContractAddresses.rewardDistributorAddress.toString(), mintAmount],
405
- {} as any,
406
- );
407
- await deployL1ContractsValues.l1Client.waitForTransactionReceipt({ hash: rewardDistributorMintTxHash });
408
- logger.info(`Funding rewardDistributor in ${rewardDistributorMintTxHash}`);
409
- }
410
-
411
384
  const dateProvider = new TestDateProvider();
412
385
 
413
386
  const watcher = new AnvilTestWatcher(
@@ -382,9 +382,7 @@ export type EndToEndContext = {
382
382
  */
383
383
  export async function setup(
384
384
  numberOfAccounts = 1,
385
- opts: SetupOptions = {
386
- customForwarderContractAddress: EthAddress.ZERO,
387
- },
385
+ opts: SetupOptions = {},
388
386
  pxeOpts: Partial<PXEServiceConfig> = {},
389
387
  chain: Chain = foundry,
390
388
  ): Promise<EndToEndContext> {
@@ -12,17 +12,14 @@ import {
12
12
  retryUntil,
13
13
  } from '@aztec/aztec.js';
14
14
  import type { ExtendedViemWalletClient } from '@aztec/ethereum';
15
- import { TestERC20Abi } from '@aztec/l1-artifacts/TestERC20Abi';
16
15
  import { FeeJuiceContract } from '@aztec/noir-contracts.js/FeeJuice';
17
16
  import { ProtocolContractAddress } from '@aztec/protocol-contracts';
18
17
  import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
19
18
 
20
- import { getContract } from 'viem';
21
-
22
19
  export interface IGasBridgingTestHarness {
23
20
  getL1FeeJuiceBalance(address: EthAddress): Promise<bigint>;
24
- prepareTokensOnL1(bridgeAmount: bigint, owner: AztecAddress): Promise<L2AmountClaim>;
25
- bridgeFromL1ToL2(bridgeAmount: bigint, owner: AztecAddress, claimer: AztecAddress): Promise<void>;
21
+ prepareTokensOnL1(owner: AztecAddress): Promise<L2AmountClaim>;
22
+ bridgeFromL1ToL2(owner: AztecAddress, claimer: AztecAddress): Promise<void>;
26
23
  feeJuice: FeeJuiceContract;
27
24
  l1FeeJuiceAddress: EthAddress;
28
25
  }
@@ -119,16 +116,9 @@ export class GasBridgingTestHarness implements IGasBridgingTestHarness {
119
116
  this.l1TokenManager = this.feeJuicePortalManager.getTokenManager();
120
117
  }
121
118
 
122
- async mintTokensOnL1(amount: bigint, to: EthAddress = this.ethAccount) {
119
+ async mintTokensOnL1(to: EthAddress = this.ethAccount) {
123
120
  // const balanceBefore = await this.l1TokenManager.getL1TokenBalance(to.toString());
124
121
  await this.l1TokenManager.mint(to.toString());
125
- const feeAssetL1 = getContract({
126
- address: this.l1FeeJuiceAddress.toString(),
127
- abi: TestERC20Abi,
128
- client: this.l1Client,
129
- });
130
-
131
- await feeAssetL1.write.mint([to.toString(), amount]);
132
122
 
133
123
  // expect(await this.l1TokenManager.getL1TokenBalance(to.toString())).toEqual(balanceBefore + amount);
134
124
  }
@@ -156,8 +146,9 @@ export class GasBridgingTestHarness implements IGasBridgingTestHarness {
156
146
  expect(balance).toBe(expectedBalance);
157
147
  }
158
148
 
159
- async prepareTokensOnL1(bridgeAmount: bigint, owner: AztecAddress) {
160
- await this.mintTokensOnL1(bridgeAmount);
149
+ async prepareTokensOnL1(owner: AztecAddress) {
150
+ const bridgeAmount = await this.l1TokenManager.getMintAmount();
151
+ await this.mintTokensOnL1();
161
152
  const claim = await this.sendTokensToPortalPublic(bridgeAmount, owner);
162
153
 
163
154
  const isSynced = async () => await this.aztecNode.isL1ToL2MessageSynced(Fr.fromHexString(claim.messageHash));
@@ -170,9 +161,9 @@ export class GasBridgingTestHarness implements IGasBridgingTestHarness {
170
161
  return claim;
171
162
  }
172
163
 
173
- async bridgeFromL1ToL2(bridgeAmount: bigint, owner: AztecAddress, claimer: AztecAddress) {
164
+ async bridgeFromL1ToL2(owner: AztecAddress, claimer: AztecAddress) {
174
165
  // Prepare the tokens on the L1 side
175
- const claim = await this.prepareTokensOnL1(bridgeAmount, owner);
166
+ const claim = await this.prepareTokensOnL1(owner);
176
167
 
177
168
  // Consume L1 -> L2 message and claim tokens privately on L2
178
169
  await this.consumeMessageOnAztecAndClaimPrivately(owner, claimer, claim);