@aztec/end-to-end 0.0.1-commit.2448fdb → 0.0.1-commit.2606882

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 (172) hide show
  1. package/dest/bench/client_flows/benchmark.d.ts +15 -1
  2. package/dest/bench/client_flows/benchmark.d.ts.map +1 -1
  3. package/dest/bench/client_flows/benchmark.js +17 -0
  4. package/dest/bench/client_flows/client_flows_benchmark.d.ts +2 -2
  5. package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
  6. package/dest/bench/client_flows/client_flows_benchmark.js +25 -35
  7. package/dest/bench/utils.d.ts +1 -1
  8. package/dest/bench/utils.d.ts.map +1 -1
  9. package/dest/bench/utils.js +2 -0
  10. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +3 -3
  11. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts.map +1 -1
  12. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.js +13 -4
  13. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts +15 -4
  14. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts.map +1 -1
  15. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.js +39 -7
  16. package/dest/e2e_deploy_contract/deploy_test.d.ts +3 -3
  17. package/dest/e2e_deploy_contract/deploy_test.d.ts.map +1 -1
  18. package/dest/e2e_deploy_contract/deploy_test.js +2 -1
  19. package/dest/e2e_epochs/epochs_test.d.ts +23 -2
  20. package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
  21. package/dest/e2e_epochs/epochs_test.js +83 -12
  22. package/dest/e2e_fees/fees_test.d.ts +5 -2
  23. package/dest/e2e_fees/fees_test.d.ts.map +1 -1
  24. package/dest/e2e_fees/fees_test.js +31 -5
  25. package/dest/e2e_nested_contract/nested_contract_test.d.ts +3 -3
  26. package/dest/e2e_nested_contract/nested_contract_test.d.ts.map +1 -1
  27. package/dest/e2e_nested_contract/nested_contract_test.js +2 -1
  28. package/dest/e2e_p2p/inactivity_slash_test.js +3 -3
  29. package/dest/e2e_p2p/p2p_network.d.ts +11 -10
  30. package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
  31. package/dest/e2e_p2p/p2p_network.js +47 -28
  32. package/dest/e2e_p2p/reqresp/utils.d.ts +1 -1
  33. package/dest/e2e_p2p/reqresp/utils.d.ts.map +1 -1
  34. package/dest/e2e_p2p/reqresp/utils.js +42 -13
  35. package/dest/e2e_p2p/shared.d.ts +23 -26
  36. package/dest/e2e_p2p/shared.d.ts.map +1 -1
  37. package/dest/e2e_p2p/shared.js +62 -80
  38. package/dest/e2e_token_contract/token_contract_test.d.ts +3 -3
  39. package/dest/e2e_token_contract/token_contract_test.d.ts.map +1 -1
  40. package/dest/e2e_token_contract/token_contract_test.js +4 -2
  41. package/dest/fixtures/e2e_prover_test.d.ts +6 -5
  42. package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
  43. package/dest/fixtures/e2e_prover_test.js +9 -13
  44. package/dest/fixtures/elu_monitor.d.ts +21 -0
  45. package/dest/fixtures/elu_monitor.d.ts.map +1 -0
  46. package/dest/fixtures/elu_monitor.js +102 -0
  47. package/dest/fixtures/fixtures.d.ts +70 -1
  48. package/dest/fixtures/fixtures.d.ts.map +1 -1
  49. package/dest/fixtures/fixtures.js +65 -0
  50. package/dest/fixtures/get_bb_config.d.ts +1 -1
  51. package/dest/fixtures/get_bb_config.d.ts.map +1 -1
  52. package/dest/fixtures/get_bb_config.js +5 -5
  53. package/dest/fixtures/ha_setup.d.ts +2 -2
  54. package/dest/fixtures/ha_setup.d.ts.map +1 -1
  55. package/dest/fixtures/ha_setup.js +1 -1
  56. package/dest/fixtures/schnorr_hardcoded_account_contract.d.ts +25 -0
  57. package/dest/fixtures/schnorr_hardcoded_account_contract.d.ts.map +1 -0
  58. package/dest/fixtures/schnorr_hardcoded_account_contract.js +37 -0
  59. package/dest/fixtures/setup.d.ts +44 -10
  60. package/dest/fixtures/setup.d.ts.map +1 -1
  61. package/dest/fixtures/setup.js +145 -19
  62. package/dest/fixtures/setup_p2p_test.d.ts +10 -6
  63. package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
  64. package/dest/fixtures/setup_p2p_test.js +8 -8
  65. package/dest/fixtures/token_utils.d.ts +1 -1
  66. package/dest/fixtures/token_utils.d.ts.map +1 -1
  67. package/dest/fixtures/token_utils.js +2 -5
  68. package/dest/fixtures/utils.d.ts +2 -2
  69. package/dest/fixtures/utils.d.ts.map +1 -1
  70. package/dest/fixtures/utils.js +1 -1
  71. package/dest/install_legacy_contracts.d.cts +1 -1
  72. package/dest/install_legacy_contracts.d.cts.map +1 -1
  73. package/dest/legacy-jest-resolver.d.cts +1 -1
  74. package/dest/legacy-jest-resolver.d.cts.map +1 -1
  75. package/dest/shared/cross_chain_test_harness.d.ts +4 -2
  76. package/dest/shared/cross_chain_test_harness.d.ts.map +1 -1
  77. package/dest/shared/cross_chain_test_harness.js +9 -5
  78. package/dest/shared/gas_portal_test_harness.d.ts +8 -5
  79. package/dest/shared/gas_portal_test_harness.d.ts.map +1 -1
  80. package/dest/shared/gas_portal_test_harness.js +17 -8
  81. package/dest/shared/jest_setup.js +41 -1
  82. package/dest/shared/submit-transactions.d.ts +1 -1
  83. package/dest/shared/submit-transactions.d.ts.map +1 -1
  84. package/dest/shared/uniswap_l1_l2.d.ts +1 -1
  85. package/dest/shared/uniswap_l1_l2.d.ts.map +1 -1
  86. package/dest/shared/uniswap_l1_l2.js +50 -32
  87. package/dest/shared/wait_for_l1_to_l2_message.d.ts +13 -0
  88. package/dest/shared/wait_for_l1_to_l2_message.d.ts.map +1 -0
  89. package/dest/shared/wait_for_l1_to_l2_message.js +10 -0
  90. package/dest/simulators/lending_simulator.d.ts +10 -3
  91. package/dest/simulators/lending_simulator.d.ts.map +1 -1
  92. package/dest/simulators/lending_simulator.js +23 -11
  93. package/dest/simulators/token_simulator.js +1 -1
  94. package/dest/spartan/setup_test_wallets.d.ts +1 -1
  95. package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
  96. package/dest/spartan/setup_test_wallets.js +67 -43
  97. package/dest/spartan/tx_metrics.d.ts +18 -4
  98. package/dest/spartan/tx_metrics.d.ts.map +1 -1
  99. package/dest/spartan/tx_metrics.js +74 -21
  100. package/dest/spartan/utils/config.d.ts +10 -30
  101. package/dest/spartan/utils/config.d.ts.map +1 -1
  102. package/dest/spartan/utils/config.js +3 -1
  103. package/dest/spartan/utils/index.d.ts +2 -1
  104. package/dest/spartan/utils/index.d.ts.map +1 -1
  105. package/dest/spartan/utils/index.js +2 -0
  106. package/dest/spartan/utils/nodes.d.ts +4 -5
  107. package/dest/spartan/utils/nodes.d.ts.map +1 -1
  108. package/dest/spartan/utils/nodes.js +11 -11
  109. package/dest/spartan/utils/pod_logs.d.ts +25 -0
  110. package/dest/spartan/utils/pod_logs.d.ts.map +1 -0
  111. package/dest/spartan/utils/pod_logs.js +74 -0
  112. package/dest/test-wallet/test_wallet.d.ts +3 -2
  113. package/dest/test-wallet/test_wallet.d.ts.map +1 -1
  114. package/dest/test-wallet/test_wallet.js +52 -28
  115. package/dest/test-wallet/utils.d.ts +3 -3
  116. package/dest/test-wallet/utils.d.ts.map +1 -1
  117. package/dest/test-wallet/utils.js +2 -7
  118. package/dest/test-wallet/wallet_worker_script.js +7 -2
  119. package/dest/test-wallet/worker_wallet.d.ts +2 -1
  120. package/dest/test-wallet/worker_wallet.d.ts.map +1 -1
  121. package/dest/test-wallet/worker_wallet.js +6 -2
  122. package/dest/test-wallet/worker_wallet_schema.d.ts +110 -224
  123. package/dest/test-wallet/worker_wallet_schema.d.ts.map +1 -1
  124. package/dest/test-wallet/worker_wallet_schema.js +14 -2
  125. package/package.json +48 -46
  126. package/src/bench/client_flows/benchmark.ts +19 -0
  127. package/src/bench/client_flows/client_flows_benchmark.ts +62 -51
  128. package/src/bench/utils.ts +2 -1
  129. package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +21 -4
  130. package/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +49 -11
  131. package/src/e2e_deploy_contract/deploy_test.ts +3 -2
  132. package/src/e2e_epochs/epochs_test.ts +85 -9
  133. package/src/e2e_fees/fees_test.ts +37 -4
  134. package/src/e2e_nested_contract/nested_contract_test.ts +3 -1
  135. package/src/e2e_p2p/inactivity_slash_test.ts +3 -3
  136. package/src/e2e_p2p/p2p_network.ts +58 -40
  137. package/src/e2e_p2p/reqresp/utils.ts +51 -12
  138. package/src/e2e_p2p/shared.ts +60 -113
  139. package/src/e2e_token_contract/token_contract_test.ts +12 -2
  140. package/src/fixtures/dumps/epoch_proof_result.json +1 -1
  141. package/src/fixtures/e2e_prover_test.ts +15 -18
  142. package/src/fixtures/elu_monitor.ts +126 -0
  143. package/src/fixtures/fixtures.ts +83 -0
  144. package/src/fixtures/get_bb_config.ts +7 -6
  145. package/src/fixtures/ha_setup.ts +4 -2
  146. package/src/fixtures/schnorr_hardcoded_account_contract.ts +49 -0
  147. package/src/fixtures/setup.ts +175 -24
  148. package/src/fixtures/setup_p2p_test.ts +13 -9
  149. package/src/fixtures/token_utils.ts +1 -4
  150. package/src/fixtures/utils.ts +2 -0
  151. package/src/guides/up_quick_start.sh +0 -2
  152. package/src/install_legacy_contracts.cjs +9 -5
  153. package/src/legacy-jest-resolver.cjs +15 -4
  154. package/src/shared/cross_chain_test_harness.ts +14 -4
  155. package/src/shared/gas_portal_test_harness.ts +20 -10
  156. package/src/shared/jest_setup.ts +51 -1
  157. package/src/shared/submit-transactions.ts +1 -4
  158. package/src/shared/uniswap_l1_l2.ts +84 -40
  159. package/src/shared/wait_for_l1_to_l2_message.ts +23 -0
  160. package/src/simulators/lending_simulator.ts +27 -13
  161. package/src/simulators/token_simulator.ts +1 -1
  162. package/src/spartan/setup_test_wallets.ts +65 -40
  163. package/src/spartan/tx_metrics.ts +82 -24
  164. package/src/spartan/utils/config.ts +2 -0
  165. package/src/spartan/utils/index.ts +3 -0
  166. package/src/spartan/utils/nodes.ts +17 -12
  167. package/src/spartan/utils/pod_logs.ts +99 -0
  168. package/src/test-wallet/test_wallet.ts +49 -24
  169. package/src/test-wallet/utils.ts +3 -7
  170. package/src/test-wallet/wallet_worker_script.ts +5 -2
  171. package/src/test-wallet/worker_wallet.ts +7 -3
  172. package/src/test-wallet/worker_wallet_schema.ts +2 -2
@@ -28,7 +28,7 @@ import type { ContractInstanceWithAddress } from '@aztec/stdlib/contract';
28
28
  import { GasSettings } from '@aztec/stdlib/gas';
29
29
  import { deriveSigningKey } from '@aztec/stdlib/keys';
30
30
 
31
- import { MNEMONIC } from '../../fixtures/fixtures.js';
31
+ import { AUTOMINE_E2E_OPTS, MNEMONIC, getPaddedMaxFeesPerGas } from '../../fixtures/fixtures.js';
32
32
  import { type EndToEndContext, type SetupOptions, deployAccounts, setup, teardown } from '../../fixtures/setup.js';
33
33
  import { mintTokensToPrivate } from '../../fixtures/token_utils.js';
34
34
  import { setupSponsoredFPC } from '../../fixtures/utils.js';
@@ -88,33 +88,35 @@ export class ClientFlowsBenchmark {
88
88
 
89
89
  public realProofs = ['true', '1'].includes(process.env.REAL_PROOFS ?? '');
90
90
 
91
- public paymentMethods: Record<BenchmarkingFeePaymentMethod, { forWallet: FeePaymentMethodGetter; circuits: number }> =
92
- {
93
- // eslint-disable-next-line camelcase
94
- bridged_fee_juice: {
95
- forWallet: this.getBridgedFeeJuicePaymentMethodForWallet.bind(this),
96
- circuits: 2, // FeeJuice claim + kernel inner
97
- },
98
- // eslint-disable-next-line camelcase
99
- private_fpc: {
100
- forWallet: this.getPrivateFPCPaymentMethodForWallet.bind(this),
101
- circuits:
102
- 2 + // FPC entrypoint + kernel inner
103
- 2 + // BananaCoin transfer_to_public + kernel inner
104
- 2 + // Account verify_private_authwit + kernel inner
105
- 2, // BananaCoin prepare_private_balance_increase + kernel inner
106
- },
107
- // eslint-disable-next-line camelcase
108
- sponsored_fpc: {
109
- forWallet: this.getSponsoredFPCPaymentMethodForWallet.bind(this),
110
- circuits: 2, // Sponsored FPC sponsor_unconditionally + kernel inner
111
- },
112
- // eslint-disable-next-line camelcase
113
- fee_juice: {
114
- forWallet: () => Promise.resolve(undefined),
115
- circuits: 0,
116
- },
117
- };
91
+ // `apps` is the number of private function calls contributed by this payment method.
92
+ // Each app produces one execution step at proving time; the orchestrator additionally produces
93
+ // one kernel step per batch of N apps (see `expectedExecutionSteps` in `benchmark.ts`).
94
+ public paymentMethods: Record<BenchmarkingFeePaymentMethod, { forWallet: FeePaymentMethodGetter; apps: number }> = {
95
+ // eslint-disable-next-line camelcase
96
+ bridged_fee_juice: {
97
+ forWallet: this.getBridgedFeeJuicePaymentMethodForWallet.bind(this),
98
+ apps: 1, // FeeJuice claim
99
+ },
100
+ // eslint-disable-next-line camelcase
101
+ private_fpc: {
102
+ forWallet: this.getPrivateFPCPaymentMethodForWallet.bind(this),
103
+ apps:
104
+ 1 + // FPC entrypoint
105
+ 1 + // BananaCoin transfer_to_public
106
+ 1 + // Account verify_private_authwit
107
+ 1, // BananaCoin prepare_private_balance_increase
108
+ },
109
+ // eslint-disable-next-line camelcase
110
+ sponsored_fpc: {
111
+ forWallet: this.getSponsoredFPCPaymentMethodForWallet.bind(this),
112
+ apps: 1, // Sponsored FPC sponsor_unconditionally
113
+ },
114
+ // eslint-disable-next-line camelcase
115
+ fee_juice: {
116
+ forWallet: () => Promise.resolve(undefined),
117
+ apps: 0,
118
+ },
119
+ };
118
120
 
119
121
  public config: ClientFlowsConfig;
120
122
 
@@ -123,7 +125,7 @@ export class ClientFlowsBenchmark {
123
125
 
124
126
  constructor(testName?: string, setupOptions: Partial<SetupOptions & DeployAztecL1ContractsArgs> = {}) {
125
127
  this.logger = createLogger(`bench:client_flows${testName ? `:${testName}` : ''}`);
126
- this.setupOptions = { startProverNode: true, ...setupOptions };
128
+ this.setupOptions = { ...AUTOMINE_E2E_OPTS, startProverNode: true, ...setupOptions };
127
129
  this.config = BENCHMARK_CONFIG === 'key_flows' ? KEY_FLOWS_CONFIG : FULL_FLOWS_CONFIG;
128
130
  ProxyLogger.create();
129
131
  this.proxyLogger = ProxyLogger.getInstance();
@@ -152,6 +154,7 @@ export class ClientFlowsBenchmark {
152
154
 
153
155
  async teardown() {
154
156
  await this.chainMonitor.stop();
157
+ await this.userWallet?.stop();
155
158
  await teardown(this.context);
156
159
  }
157
160
 
@@ -249,11 +252,14 @@ export class ClientFlowsBenchmark {
249
252
 
250
253
  async applyDeployBananaToken() {
251
254
  this.logger.info('Applying banana token deployment');
252
- const {
253
- receipt: { contract: bananaCoin, instance: bananaCoinInstance },
254
- } = await BananaCoin.deploy(this.adminWallet, this.adminAddress, 'BC', 'BC', 18n).send({
255
+ const { contract: bananaCoin, instance: bananaCoinInstance } = await BananaCoin.deploy(
256
+ this.adminWallet,
257
+ this.adminAddress,
258
+ 'BC',
259
+ 'BC',
260
+ 18n,
261
+ ).send({
255
262
  from: this.adminAddress,
256
- wait: { returnReceipt: true },
257
263
  });
258
264
  this.logger.info(`BananaCoin deployed at ${bananaCoin.address}`);
259
265
  this.bananaCoin = bananaCoin;
@@ -262,11 +268,14 @@ export class ClientFlowsBenchmark {
262
268
 
263
269
  async applyDeployCandyBarToken() {
264
270
  this.logger.info('Applying candy bar token deployment');
265
- const {
266
- receipt: { contract: candyBarCoin, instance: candyBarCoinInstance },
267
- } = await TokenContract.deploy(this.adminWallet, this.adminAddress, 'CBC', 'CBC', 18n).send({
271
+ const { contract: candyBarCoin, instance: candyBarCoinInstance } = await TokenContract.deploy(
272
+ this.adminWallet,
273
+ this.adminAddress,
274
+ 'CBC',
275
+ 'CBC',
276
+ 18n,
277
+ ).send({
268
278
  from: this.adminAddress,
269
- wait: { returnReceipt: true },
270
279
  });
271
280
  this.logger.info(`CandyBarCoin deployed at ${candyBarCoin.address}`);
272
281
  this.candyBarCoin = candyBarCoin;
@@ -279,11 +288,12 @@ export class ClientFlowsBenchmark {
279
288
  expect((await this.context.wallet.getContractMetadata(feeJuiceContract.address)).isContractPublished).toBe(true);
280
289
 
281
290
  const bananaCoin = this.bananaCoin;
282
- const {
283
- receipt: { contract: bananaFPC, instance: bananaFPCInstance },
284
- } = await FPCContract.deploy(this.adminWallet, bananaCoin.address, this.adminAddress).send({
291
+ const { contract: bananaFPC, instance: bananaFPCInstance } = await FPCContract.deploy(
292
+ this.adminWallet,
293
+ bananaCoin.address,
294
+ this.adminAddress,
295
+ ).send({
285
296
  from: this.adminAddress,
286
- wait: { returnReceipt: true },
287
297
  });
288
298
 
289
299
  this.logger.info(`BananaPay deployed at ${bananaFPC.address}`);
@@ -339,7 +349,7 @@ export class ClientFlowsBenchmark {
339
349
  // Register benchy on the user's Wallet, where we're going to be interacting from
340
350
  const accountManager = await this.userWallet.createAccount({
341
351
  secret: benchysAccount.getSecretKey(),
342
- salt: new Fr(benchysAccount.salt),
352
+ salt: new Fr(benchysAccountManager.getInstance().salt),
343
353
  contract: benchysAccountManager.getAccountContract(),
344
354
  });
345
355
  return accountManager.address;
@@ -347,20 +357,21 @@ export class ClientFlowsBenchmark {
347
357
 
348
358
  public async applyDeployAmm() {
349
359
  this.logger.info('Applying AMM deployment');
350
- const {
351
- receipt: { contract: liquidityToken, instance: liquidityTokenInstance },
352
- } = await TokenContract.deploy(this.adminWallet, this.adminAddress, 'LPT', 'LPT', 18n).send({
360
+ const { contract: liquidityToken, instance: liquidityTokenInstance } = await TokenContract.deploy(
361
+ this.adminWallet,
362
+ this.adminAddress,
363
+ 'LPT',
364
+ 'LPT',
365
+ 18n,
366
+ ).send({
353
367
  from: this.adminAddress,
354
- wait: { returnReceipt: true },
355
368
  });
356
- const {
357
- receipt: { contract: amm, instance: ammInstance },
358
- } = await AMMContract.deploy(
369
+ const { contract: amm, instance: ammInstance } = await AMMContract.deploy(
359
370
  this.adminWallet,
360
371
  this.bananaCoin.address,
361
372
  this.candyBarCoin.address,
362
373
  liquidityToken.address,
363
- ).send({ from: this.adminAddress, wait: { returnReceipt: true } });
374
+ ).send({ from: this.adminAddress });
364
375
  this.logger.info(`AMM deployed at ${amm.address}`);
365
376
  await liquidityToken.methods.set_minter(amm.address, true).send({ from: this.adminAddress });
366
377
  this.liquidityToken = liquidityToken;
@@ -377,7 +388,7 @@ export class ClientFlowsBenchmark {
377
388
  public async getPrivateFPCPaymentMethodForWallet(wallet: Wallet, sender: AztecAddress) {
378
389
  // The private fee paying method assembled on the app side requires knowledge of the maximum
379
390
  // fee the user is willing to pay
380
- const maxFeesPerGas = (await this.aztecNode.getCurrentMinFees()).mul(1.5);
391
+ const maxFeesPerGas = await getPaddedMaxFeesPerGas(this.aztecNode);
381
392
  const gasSettings = GasSettings.fallback({ maxFeesPerGas });
382
393
  return new PrivateFeePaymentMethod(this.bananaFPC.address, sender, wallet, gasSettings);
383
394
  }
@@ -11,6 +11,7 @@ import type { BenchmarkDataPoint, BenchmarkMetricsType, BenchmarkTelemetryClient
11
11
  import { mkdirSync, writeFileSync } from 'fs';
12
12
  import path from 'path';
13
13
 
14
+ import { PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js';
14
15
  import { type EndToEndContext, type SetupOptions, setup } from '../fixtures/utils.js';
15
16
 
16
17
  /**
@@ -23,7 +24,7 @@ export async function benchmarkSetup(
23
24
  benchOutput?: string;
24
25
  },
25
26
  ) {
26
- const context = await setup(1, { ...opts, telemetryConfig: { benchmark: true } });
27
+ const context = await setup(1, { ...PIPELINING_SETUP_OPTS, ...opts, telemetryConfig: { benchmark: true } });
27
28
  const defaultAccountAddress = context.accounts[0];
28
29
  const { contract } = await BenchmarkingContract.deploy(context.wallet).send({ from: defaultAccountAddress });
29
30
  context.logger.info(`Deployed benchmarking contract at ${contract.address}`);
@@ -14,7 +14,15 @@ import type { AztecNodeDebug } from '@aztec/stdlib/interfaces/client';
14
14
 
15
15
  import { jest } from '@jest/globals';
16
16
 
17
- import { type EndToEndContext, deployAccounts, publicDeployAccounts, setup, teardown } from '../fixtures/setup.js';
17
+ import {
18
+ type EndToEndContext,
19
+ type SetupOptions,
20
+ deployAccounts,
21
+ ensureAuthRegistryPublished,
22
+ publicDeployAccounts,
23
+ setup,
24
+ teardown,
25
+ } from '../fixtures/setup.js';
18
26
  import { TokenSimulator } from '../simulators/token_simulator.js';
19
27
  import type { TestWallet } from '../test-wallet/test_wallet.js';
20
28
 
@@ -69,6 +77,12 @@ export class BlacklistTokenContractTest {
69
77
  }
70
78
 
71
79
  async crossTimestampOfChange() {
80
+ // Under AUTOMINE_E2E_OPTS, the 86400s warp crosses many epochs without any proofs being
81
+ // submitted. Mark current pending checkpoints as proven first so the rollup contract's
82
+ // pruning window doesn't reset the chain tip to genesis (which would make the warp's
83
+ // own empty-checkpoint propose fail with Rollup__InvalidArchive). See the AutomineSequencer
84
+ // README "Epoch proving caveat" and the equivalent pattern in lending_simulator.progressSlots.
85
+ await this.cheatCodes.rollup.markAsProven();
72
86
  await this.cheatCodes.warpL2TimeAtLeastBy(this.aztecNode, BlacklistTokenContractTest.CHANGE_ROLES_DELAY);
73
87
  }
74
88
 
@@ -78,8 +92,9 @@ export class BlacklistTokenContractTest {
78
92
  * 2. Publicly deploy accounts, deploy token contract and a "bad account".
79
93
  */
80
94
  async applyBaseSetup() {
81
- // Adding a timeout of 2 minutes in here such that it is propagated to the underlying tests
82
- jest.setTimeout(120_000);
95
+ // Bumped from 2 min: pipelined cadence (~24s/dependent-tx) makes the 3-account deploy plus token/bad-account/
96
+ // proxy deploys exceed the original window.
97
+ jest.setTimeout(600_000);
83
98
 
84
99
  this.logger.info('Deploying 3 accounts');
85
100
  const { deployedAccounts } = await deployAccounts(
@@ -99,6 +114,7 @@ export class BlacklistTokenContractTest {
99
114
  this.blacklistedAddress = deployedAccounts[2].address;
100
115
 
101
116
  this.logger.info('Setting up blacklist token contract');
117
+ await ensureAuthRegistryPublished(this.wallet, this.adminAddress);
102
118
  // Create the token contract state.
103
119
  this.logger.verbose(`Public deploy accounts...`);
104
120
  await publicDeployAccounts(this.wallet, [this.adminAddress, this.otherAddress, this.blacklistedAddress]);
@@ -139,9 +155,10 @@ export class BlacklistTokenContractTest {
139
155
  ).toEqual(new Role().withAdmin().toNoirStruct());
140
156
  }
141
157
 
142
- async setup() {
158
+ async setup(opts: Partial<SetupOptions> = {}) {
143
159
  this.logger.info('Setting up fresh context');
144
160
  this.context = await setup(0, {
161
+ ...opts,
145
162
  fundSponsoredFPC: true,
146
163
  skipAccountDeployment: true,
147
164
  });
@@ -4,7 +4,7 @@ import { waitForProven } from '@aztec/aztec.js/contracts';
4
4
  import { type Logger, createLogger } from '@aztec/aztec.js/log';
5
5
  import type { AztecNode } from '@aztec/aztec.js/node';
6
6
  import type { TxReceipt } from '@aztec/aztec.js/tx';
7
- import { CheatCodes } from '@aztec/aztec/testing';
7
+ import { CheatCodes, EpochTestSettler } from '@aztec/aztec/testing';
8
8
  import { createExtendedL1Client } from '@aztec/ethereum/client';
9
9
  import { InboxContract, OutboxContract, RollupContract } from '@aztec/ethereum/contracts';
10
10
  import type {
@@ -12,12 +12,14 @@ import type {
12
12
  DeployAztecL1ContractsReturnType,
13
13
  } from '@aztec/ethereum/deploy-aztec-l1-contracts';
14
14
  import { deployL1Contract } from '@aztec/ethereum/deploy-l1-contract';
15
+ import { pickL1ContractAddresses } from '@aztec/ethereum/l1-contract-addresses';
15
16
  import type { ExtendedViemWalletClient } from '@aztec/ethereum/types';
16
17
  import { EpochNumber } from '@aztec/foundation/branded-types';
17
18
  import { sleep } from '@aztec/foundation/sleep';
18
19
  import { TestERC20Abi, TestERC20Bytecode } from '@aztec/l1-artifacts';
19
20
  import { TokenContract } from '@aztec/noir-contracts.js/Token';
20
21
  import { TokenBridgeContract } from '@aztec/noir-contracts.js/TokenBridge';
22
+ import type { PXEConfig } from '@aztec/pxe/server';
21
23
  import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
22
24
 
23
25
  import { MNEMONIC } from '../fixtures/fixtures.js';
@@ -25,6 +27,7 @@ import {
25
27
  type EndToEndContext,
26
28
  type SetupOptions,
27
29
  deployAccounts,
30
+ ensureAuthRegistryPublished,
28
31
  publicDeployAccounts,
29
32
  setup,
30
33
  teardown,
@@ -36,6 +39,7 @@ export class CrossChainMessagingTest {
36
39
  private requireEpochProven: boolean;
37
40
  private setupOptions: SetupOptions;
38
41
  private deployL1ContractsArgs: Partial<DeployAztecL1ContractsArgs>;
42
+ private pxeOpts: Partial<PXEConfig>;
39
43
  logger: Logger;
40
44
  context!: EndToEndContext;
41
45
  aztecNode!: AztecNode;
@@ -58,12 +62,23 @@ export class CrossChainMessagingTest {
58
62
  outbox!: OutboxContract;
59
63
  cheatCodes!: CheatCodes;
60
64
 
65
+ /**
66
+ * Background loop that marks each completed epoch as proven on L1. Started in `applyBaseSetup`
67
+ * when the test runs without a real prover node, because the e2e fixture uses L1 interval mining
68
+ * and the AnvilTestWatcher's auto-prove loop only runs under L1 automine. Without this, L1's
69
+ * `aztecProofSubmissionEpochs` window expires mid-test and triggers a chain prune that drops
70
+ * in-flight wallet txs. Tests that intentionally pause proving (e.g. inbox drift tests) can
71
+ * stop it via `await t.epochTestSettler?.stop()`.
72
+ */
73
+ epochTestSettler?: EpochTestSettler;
74
+
61
75
  deployL1ContractsValues!: DeployAztecL1ContractsReturnType;
62
76
 
63
77
  constructor(
64
78
  testName: string,
65
79
  opts: SetupOptions = {},
66
80
  deployL1ContractsArgs: Partial<DeployAztecL1ContractsArgs> = {},
81
+ pxeOpts: Partial<PXEConfig> = {},
67
82
  ) {
68
83
  this.logger = createLogger(`e2e:e2e_cross_chain_messaging:${testName}`);
69
84
  this.setupOptions = opts;
@@ -71,17 +86,25 @@ export class CrossChainMessagingTest {
71
86
  initialValidators: [],
72
87
  ...deployL1ContractsArgs,
73
88
  };
89
+ this.pxeOpts = pxeOpts;
74
90
  this.requireEpochProven = opts.startProverNode ?? false;
75
91
  }
76
92
 
77
- async setup() {
93
+ async setup(opts: Partial<SetupOptions> = {}, pxeOpts: Partial<PXEConfig> = {}) {
78
94
  this.logger.info('Setting up cross chain messaging test');
79
- this.context = await setup(0, {
80
- ...this.setupOptions,
81
- fundSponsoredFPC: true,
82
- skipAccountDeployment: true,
83
- l1ContractsArgs: this.deployL1ContractsArgs,
84
- });
95
+ // Recompute requireEpochProven from the merged options so per-call startProverNode is honored.
96
+ this.requireEpochProven = opts.startProverNode ?? this.setupOptions.startProverNode ?? false;
97
+ this.context = await setup(
98
+ 0,
99
+ {
100
+ ...this.setupOptions,
101
+ ...opts,
102
+ fundSponsoredFPC: true,
103
+ skipAccountDeployment: true,
104
+ l1ContractsArgs: { ...this.deployL1ContractsArgs, ...opts.l1ContractsArgs },
105
+ },
106
+ { ...this.pxeOpts, ...pxeOpts },
107
+ );
85
108
  await this.applyBaseSetup();
86
109
  }
87
110
 
@@ -98,12 +121,13 @@ export class CrossChainMessagingTest {
98
121
 
99
122
  async catchUpProvenChain() {
100
123
  const bn = await this.aztecNode.getBlockNumber();
101
- while ((await this.aztecNode.getProvenBlockNumber()) < bn) {
124
+ while ((await this.aztecNode.getBlockNumber('proven')) < bn) {
102
125
  await sleep(1000);
103
126
  }
104
127
  }
105
128
 
106
129
  async teardown() {
130
+ await this.epochTestSettler?.stop();
107
131
  await teardown(this.context);
108
132
  }
109
133
 
@@ -119,6 +143,19 @@ export class CrossChainMessagingTest {
119
143
  if (this.requireEpochProven) {
120
144
  // Turn off the watcher to prevent it from keep marking blocks as proven.
121
145
  this.context.watcher.setIsMarkingAsProven(false);
146
+ } else {
147
+ // When no real prover is running, the L1 proof window (aztecProofSubmissionEpochs) would
148
+ // otherwise expire mid-test and trigger a chain prune. The AnvilTestWatcher's auto-prove
149
+ // loop is dormant under L1 interval mining (it gates on `isAutoMining`), so start an
150
+ // EpochTestSettler to mark each completed epoch as proven on L1.
151
+ this.epochTestSettler = new EpochTestSettler(
152
+ this.context.ethCheatCodes,
153
+ this.context.deployL1ContractsValues.l1ContractAddresses.rollupAddress,
154
+ this.context.aztecNodeService.getBlockSource(),
155
+ this.logger.createChild('epoch-settler'),
156
+ { pollingIntervalMs: 500 },
157
+ );
158
+ await this.epochTestSettler.start();
122
159
  }
123
160
 
124
161
  // Deploy 3 accounts
@@ -135,6 +172,7 @@ export class CrossChainMessagingTest {
135
172
  // Set up cross chain messaging
136
173
  this.logger.info('Applying e2e_cross_chain_messaging setup');
137
174
 
175
+ await ensureAuthRegistryPublished(this.wallet, this.ownerAddress);
138
176
  // Create the token contract state.
139
177
  this.logger.verbose(`Public deploy accounts...`);
140
178
  await publicDeployAccounts(this.wallet, [this.ownerAddress, this.user1Address, this.user2Address]);
@@ -171,7 +209,7 @@ export class CrossChainMessagingTest {
171
209
  const l1Client = createExtendedL1Client(this.aztecNodeConfig.l1RpcUrls, MNEMONIC);
172
210
  this.l1Client = l1Client;
173
211
 
174
- const l1Contracts = this.aztecNodeConfig.l1Contracts;
212
+ const l1Contracts = pickL1ContractAddresses(this.aztecNodeConfig);
175
213
  this.rollup = new RollupContract(l1Client, l1Contracts.rollupAddress.toString());
176
214
  this.inbox = new InboxContract(l1Client, l1Contracts.inboxAddress.toString());
177
215
  this.outbox = new OutboxContract(l1Client, l1Contracts.outboxAddress.toString());
@@ -185,7 +223,7 @@ export class CrossChainMessagingTest {
185
223
  tokenPortalAddress,
186
224
  crossChainContext.underlying,
187
225
  l1Client,
188
- this.aztecNodeConfig.l1Contracts,
226
+ pickL1ContractAddresses(this.aztecNodeConfig),
189
227
  this.wallet,
190
228
  this.ownerAddress,
191
229
  );
@@ -9,7 +9,7 @@ import type { Wallet } from '@aztec/aztec.js/wallet';
9
9
  import type { StatefulTestContract } from '@aztec/noir-test-contracts.js/StatefulTest';
10
10
  import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
11
11
 
12
- import { type EndToEndContext, deployAccounts, setup, teardown } from '../fixtures/setup.js';
12
+ import { type EndToEndContext, type SetupOptions, deployAccounts, setup, teardown } from '../fixtures/setup.js';
13
13
  import type { TestWallet } from '../test-wallet/test_wallet.js';
14
14
 
15
15
  export class DeployTest {
@@ -24,9 +24,10 @@ export class DeployTest {
24
24
  this.logger = createLogger(`e2e:e2e_deploy_contract:${testName}`);
25
25
  }
26
26
 
27
- async setup() {
27
+ async setup(opts: Partial<SetupOptions> = {}) {
28
28
  this.logger.info('Setting up test environment');
29
29
  this.context = await setup(0, {
30
+ ...opts,
30
31
  fundSponsoredFPC: true,
31
32
  skipAccountDeployment: true,
32
33
  });
@@ -1,5 +1,7 @@
1
+ import type { InitialAccountData } from '@aztec/accounts/testing';
1
2
  import type { Archiver } from '@aztec/archiver';
2
3
  import { type AztecNodeConfig, AztecNodeService } from '@aztec/aztec-node';
4
+ import { getAccountContractAddress } from '@aztec/aztec.js/account';
3
5
  import { getTimestampRangeForEpoch } from '@aztec/aztec.js/block';
4
6
  import { getContractInstanceFromInstantiationParams } from '@aztec/aztec.js/contracts';
5
7
  import { Fr } from '@aztec/aztec.js/fields';
@@ -34,6 +36,10 @@ import { join } from 'path';
34
36
  import type { Hex } from 'viem';
35
37
  import { privateKeyToAccount } from 'viem/accounts';
36
38
 
39
+ import {
40
+ SCHNORR_HARDCODED_PRIVATE_KEY,
41
+ SchnorrHardcodedKeyAccountContract,
42
+ } from '../fixtures/schnorr_hardcoded_account_contract.js';
37
43
  import {
38
44
  type EndToEndContext,
39
45
  type SetupOptions,
@@ -41,6 +47,7 @@ import {
41
47
  getPrivateKeyFromIndex,
42
48
  setup,
43
49
  } from '../fixtures/utils.js';
50
+ import type { TestWallet } from '../test-wallet/test_wallet.js';
44
51
 
45
52
  export const WORLD_STATE_CHECKPOINT_HISTORY = 2;
46
53
  export const WORLD_STATE_BLOCK_CHECK_INTERVAL = 50;
@@ -51,6 +58,13 @@ export type EpochsTestOpts = Partial<SetupOptions> & {
51
58
  numberOfAccounts?: number;
52
59
  pxeOpts?: Partial<PXEConfig>;
53
60
  aztecSlotDurationInL1Slots?: number;
61
+ /** Skip creating/registering the hardcoded account during setup (for tests that handle accounts themselves). */
62
+ skipHardcodedAccount?: boolean;
63
+ /**
64
+ * Force the hardcoded-account fast-path even when an initial sequencer is running. Useful for
65
+ * tests with tight per-block gas budgets that can't fit a full account-deploy tx.
66
+ */
67
+ useHardcodedAccount?: boolean;
54
68
  };
55
69
 
56
70
  export type TrackedSequencerEvent = {
@@ -121,10 +135,20 @@ export class EpochsTestContext {
121
135
  this.L1_BLOCK_TIME_IN_S = ethereumSlotDuration;
122
136
  this.L2_SLOT_DURATION_IN_S = aztecSlotDuration;
123
137
 
138
+ // Auto-create a hardcoded account funded via genesis when:
139
+ // - skipInitialSequencer is set (no sequencer to deploy on-chain), or
140
+ // - useHardcodedAccount is explicitly requested (e.g. tight per-block gas budgets that
141
+ // can't fit a full account-deploy tx).
142
+ const useHardcodedAccount = (opts.skipInitialSequencer || opts.useHardcodedAccount) && !opts.skipHardcodedAccount;
143
+ let hardcodedAccountData: InitialAccountData | undefined;
144
+ if (useHardcodedAccount) {
145
+ hardcodedAccountData = await EpochsTestContext.getHardcodedAccountData(Fr.random(), Fr.random());
146
+ }
147
+
124
148
  // Set up system without any account nor protocol contracts
125
149
  // and with faster block times and shorter epochs.
126
150
  const context = await setup(
127
- opts.numberOfAccounts ?? 0,
151
+ useHardcodedAccount ? 0 : (opts.numberOfAccounts ?? 0),
128
152
  {
129
153
  automineL1Setup: true,
130
154
  checkIntervalMs: 50,
@@ -139,15 +163,13 @@ export class EpochsTestContext {
139
163
  realProofs: false,
140
164
  startProverNode: true,
141
165
  proverTestDelayMs: opts.proverTestDelayMs ?? 0,
142
- // We use numeric incremental prover ids for simplicity, but we can switch to
143
- // using the prover's eth address if the proverId is used for something in the rollup contract
144
- // Use numeric EthAddress for deterministic prover id
145
166
  proverId: EthAddress.fromNumber(1),
146
167
  worldStateCheckpointHistory: WORLD_STATE_CHECKPOINT_HISTORY,
147
168
  exitDelaySeconds: DefaultL1ContractsConfig.exitDelaySeconds,
148
- slasherFlavor: 'none',
169
+ slasherEnabled: false,
149
170
  l1PublishingTime,
150
171
  ...opts,
172
+ ...(hardcodedAccountData ? { initialFundedAccounts: [hardcodedAccountData], numberOfAccounts: 0 } : {}),
151
173
  },
152
174
  // Use checkpointed chain tip for PXE by default to avoid issues with blocks being dropped due to pruned anchor blocks.
153
175
  // Can be overridden via opts.pxeOpts.
@@ -155,6 +177,11 @@ export class EpochsTestContext {
155
177
  );
156
178
 
157
179
  this.context = context;
180
+
181
+ // Register the hardcoded account in PXE (local only, no on-chain deployment needed).
182
+ if (hardcodedAccountData) {
183
+ await this.registerHardcodedAccount(hardcodedAccountData);
184
+ }
158
185
  this.proverNodes = context.proverNode ? [context.proverNode] : [];
159
186
  this.nodes = context.aztecNode ? [context.aztecNode as AztecNodeService] : [];
160
187
  this.logger = context.logger;
@@ -197,6 +224,35 @@ export class EpochsTestContext {
197
224
  await this.context.teardown();
198
225
  }
199
226
 
227
+ /**
228
+ * Computes InitialAccountData for a SchnorrHardcodedKeyAccountContract.
229
+ * This contract has a hardcoded signing key and no initializer, so it can be used without
230
+ * on-chain deployment. Pass the returned data in `initialFundedAccounts` so the address
231
+ * gets funded with fee juice in genesis.
232
+ */
233
+ public static async getHardcodedAccountData(secret: Fr, salt: Fr): Promise<InitialAccountData> {
234
+ const contract = new SchnorrHardcodedKeyAccountContract();
235
+ const address = await getAccountContractAddress(contract, secret, salt);
236
+ const signingKey = SCHNORR_HARDCODED_PRIVATE_KEY;
237
+ return { secret, salt, signingKey, address };
238
+ }
239
+
240
+ /**
241
+ * Registers a SchnorrHardcodedKeyAccountContract in PXE. The account must have been funded
242
+ * at genesis (via getHardcodedAccountData). No on-chain deployment or block mining needed.
243
+ */
244
+ public async registerHardcodedAccount(accountData: InitialAccountData) {
245
+ const contract = new SchnorrHardcodedKeyAccountContract();
246
+ const wallet = this.context.wallet;
247
+ const accountManager = await (wallet as TestWallet).createAccount({
248
+ secret: accountData.secret,
249
+ salt: accountData.salt,
250
+ contract,
251
+ });
252
+ this.context.accounts = [accountManager.address];
253
+ return accountManager.address;
254
+ }
255
+
200
256
  public async createProverNode(opts: { dontStart?: boolean } & Partial<ProverNodeConfig> = {}) {
201
257
  this.logger.warn('Creating and syncing a simulated prover node...');
202
258
  const proverNodePrivateKey = this.getNextPrivateKey();
@@ -223,7 +279,7 @@ export class EpochsTestContext {
223
279
  },
224
280
  },
225
281
  {
226
- prefilledPublicData: this.context.prefilledPublicData ?? [],
282
+ genesis: this.context.genesis,
227
283
  dontStart: opts.dontStart,
228
284
  },
229
285
  ),
@@ -278,7 +334,7 @@ export class EpochsTestContext {
278
334
  slashingProtectionDb: opts.slashingProtectionDb,
279
335
  },
280
336
  {
281
- prefilledPublicData: this.context.prefilledPublicData,
337
+ genesis: this.context.genesis,
282
338
  ...opts,
283
339
  },
284
340
  ),
@@ -349,7 +405,7 @@ export class EpochsTestContext {
349
405
  await sleep(waitTime);
350
406
  const [syncState, tips] = await Promise.all([
351
407
  this.context.aztecNode.getWorldStateSyncStatus(),
352
- await this.context.aztecNode.getL2Tips(),
408
+ await this.context.aztecNode.getChainTips(),
353
409
  ]);
354
410
  this.logger.info(`Wait for node synch ${blockNumber} ${type}`, { blockNumber, type, syncState, tips });
355
411
  if (type === 'proven') {
@@ -416,7 +472,7 @@ export class EpochsTestContext {
416
472
  /** Verifies at least one checkpoint has the target number of blocks (for MBPS validation). */
417
473
  public async assertMultipleBlocksPerSlot(targetBlockCount: number) {
418
474
  const archiver = (this.context.aztecNode as AztecNodeService).getBlockSource() as Archiver;
419
- const checkpoints = await archiver.getCheckpoints(CheckpointNumber(1), 50);
475
+ const checkpoints = await archiver.getCheckpoints({ from: CheckpointNumber(1), limit: 50 });
420
476
 
421
477
  this.logger.warn(`Retrieved ${checkpoints.length} checkpoints from archiver`, {
422
478
  checkpoints: checkpoints.map(pc => pc.checkpoint.getStats()),
@@ -448,6 +504,7 @@ export class EpochsTestContext {
448
504
  public watchSequencerEvents(
449
505
  sequencers: SequencerClient[],
450
506
  getMetadata: (i: number) => Record<string, any> = () => ({}),
507
+ additionalFailEventKeys: (keyof SequencerEvents)[] = [],
451
508
  ) {
452
509
  const stateChanges: TrackedSequencerEvent[] = [];
453
510
  const failEvents: TrackedSequencerEvent[] = [];
@@ -458,6 +515,11 @@ export class EpochsTestContext {
458
515
  'block-build-failed',
459
516
  'checkpoint-publish-failed',
460
517
  'proposer-rollup-check-failed',
518
+ 'checkpoint-error',
519
+ 'checkpoint-publish-failed',
520
+ 'header-validation-failed',
521
+ 'pipelined-checkpoint-discarded',
522
+ ...additionalFailEventKeys,
461
523
  ];
462
524
 
463
525
  const makeEvent = (
@@ -487,6 +549,13 @@ export class EpochsTestContext {
487
549
  });
488
550
  failEventsKeys.forEach(eventName => {
489
551
  sequencer.getSequencer().on(eventName, (args: Parameters<SequencerEvents[typeof eventName]>[0]) => {
552
+ // Skip benign block-build-failed events where the builder rejected the block because it
553
+ // could not collect enough valid txs. This is the same "not enough txs" case as
554
+ // block-tx-count-check-failed (which is already excluded above), just detected after we
555
+ // started processing txs rather than before.
556
+ if (eventName === 'block-build-failed' && (args as { reason?: string }).reason === 'Insufficient valid txs') {
557
+ return;
558
+ }
490
559
  const evt = makeEvent(i, eventName, args);
491
560
  failEvents.push(evt);
492
561
  this.logger.error(`Failed event ${eventName} from sequencer ${sequencerIndex}`, undefined, evt);
@@ -496,4 +565,11 @@ export class EpochsTestContext {
496
565
 
497
566
  return { failEvents, stateChanges };
498
567
  }
568
+
569
+ public assertNoFailuresFromSequencers(failEvents: TrackedSequencerEvent[]) {
570
+ if (failEvents.length > 0) {
571
+ this.logger.error(`Failed events from sequencers`, failEvents);
572
+ }
573
+ expect(failEvents).toEqual([]);
574
+ }
499
575
  }