@aztec/end-to-end 0.0.1-commit.18ccd8f0 → 0.0.1-commit.1a421b1a1

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 (187) hide show
  1. package/dest/bench/client_flows/client_flows_benchmark.d.ts +2 -2
  2. package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
  3. package/dest/bench/client_flows/client_flows_benchmark.js +19 -11
  4. package/dest/bench/client_flows/config.d.ts +2 -2
  5. package/dest/bench/client_flows/config.d.ts.map +1 -1
  6. package/dest/bench/client_flows/config.js +18 -0
  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 +6 -3
  10. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +4 -2
  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 +22 -12
  13. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts +2 -2
  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 +3 -2
  16. package/dest/e2e_deploy_contract/deploy_test.d.ts +2 -2
  17. package/dest/e2e_deploy_contract/deploy_test.d.ts.map +1 -1
  18. package/dest/e2e_epochs/epochs_test.d.ts +9 -7
  19. package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
  20. package/dest/e2e_epochs/epochs_test.js +59 -33
  21. package/dest/e2e_fees/fees_test.d.ts +2 -2
  22. package/dest/e2e_fees/fees_test.d.ts.map +1 -1
  23. package/dest/e2e_fees/fees_test.js +18 -11
  24. package/dest/e2e_nested_contract/nested_contract_test.d.ts +1 -1
  25. package/dest/e2e_nested_contract/nested_contract_test.d.ts.map +1 -1
  26. package/dest/e2e_nested_contract/nested_contract_test.js +4 -6
  27. package/dest/e2e_p2p/p2p_network.d.ts +5 -4
  28. package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
  29. package/dest/e2e_p2p/p2p_network.js +24 -7
  30. package/dest/e2e_p2p/reqresp/utils.d.ts +22 -0
  31. package/dest/e2e_p2p/reqresp/utils.d.ts.map +1 -0
  32. package/dest/e2e_p2p/reqresp/utils.js +190 -0
  33. package/dest/e2e_p2p/shared.d.ts +22 -2
  34. package/dest/e2e_p2p/shared.d.ts.map +1 -1
  35. package/dest/e2e_p2p/shared.js +38 -3
  36. package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.d.ts +2 -0
  37. package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.d.ts.map +1 -0
  38. package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.js +184 -0
  39. package/dest/e2e_storage_proof/fixtures/storage_proof_fixture.d.ts +18 -0
  40. package/dest/e2e_storage_proof/fixtures/storage_proof_fixture.d.ts.map +1 -0
  41. package/dest/e2e_storage_proof/fixtures/storage_proof_fixture.js +120 -0
  42. package/dest/e2e_token_contract/token_contract_test.d.ts +4 -2
  43. package/dest/e2e_token_contract/token_contract_test.d.ts.map +1 -1
  44. package/dest/e2e_token_contract/token_contract_test.js +19 -9
  45. package/dest/fixtures/authwit_proxy.d.ts +15 -0
  46. package/dest/fixtures/authwit_proxy.d.ts.map +1 -0
  47. package/dest/fixtures/authwit_proxy.js +30 -0
  48. package/dest/fixtures/e2e_prover_test.d.ts +4 -4
  49. package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
  50. package/dest/fixtures/e2e_prover_test.js +33 -40
  51. package/dest/fixtures/elu_monitor.d.ts +21 -0
  52. package/dest/fixtures/elu_monitor.d.ts.map +1 -0
  53. package/dest/fixtures/elu_monitor.js +102 -0
  54. package/dest/fixtures/fixtures.d.ts +5 -1
  55. package/dest/fixtures/fixtures.d.ts.map +1 -1
  56. package/dest/fixtures/fixtures.js +6 -0
  57. package/dest/fixtures/ha_setup.d.ts +71 -0
  58. package/dest/fixtures/ha_setup.d.ts.map +1 -0
  59. package/dest/fixtures/ha_setup.js +116 -0
  60. package/dest/fixtures/index.d.ts +2 -1
  61. package/dest/fixtures/index.d.ts.map +1 -1
  62. package/dest/fixtures/index.js +1 -0
  63. package/dest/fixtures/setup.d.ts +44 -23
  64. package/dest/fixtures/setup.d.ts.map +1 -1
  65. package/dest/fixtures/setup.js +64 -153
  66. package/dest/fixtures/setup_p2p_test.d.ts +15 -7
  67. package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
  68. package/dest/fixtures/setup_p2p_test.js +18 -12
  69. package/dest/fixtures/token_utils.d.ts +2 -2
  70. package/dest/fixtures/token_utils.d.ts.map +1 -1
  71. package/dest/fixtures/token_utils.js +5 -4
  72. package/dest/shared/cross_chain_test_harness.d.ts +1 -1
  73. package/dest/shared/cross_chain_test_harness.d.ts.map +1 -1
  74. package/dest/shared/cross_chain_test_harness.js +13 -13
  75. package/dest/shared/gas_portal_test_harness.js +2 -2
  76. package/dest/shared/index.d.ts +2 -1
  77. package/dest/shared/index.d.ts.map +1 -1
  78. package/dest/shared/index.js +1 -0
  79. package/dest/shared/jest_setup.js +41 -1
  80. package/dest/shared/mock_state_view.d.ts +86 -0
  81. package/dest/shared/mock_state_view.d.ts.map +1 -0
  82. package/dest/shared/mock_state_view.js +186 -0
  83. package/dest/shared/submit-transactions.d.ts +2 -2
  84. package/dest/shared/submit-transactions.d.ts.map +1 -1
  85. package/dest/shared/submit-transactions.js +1 -1
  86. package/dest/shared/uniswap_l1_l2.d.ts +1 -1
  87. package/dest/shared/uniswap_l1_l2.d.ts.map +1 -1
  88. package/dest/shared/uniswap_l1_l2.js +13 -11
  89. package/dest/simulators/lending_simulator.d.ts +1 -1
  90. package/dest/simulators/lending_simulator.d.ts.map +1 -1
  91. package/dest/simulators/lending_simulator.js +2 -2
  92. package/dest/simulators/token_simulator.d.ts +1 -1
  93. package/dest/simulators/token_simulator.d.ts.map +1 -1
  94. package/dest/simulators/token_simulator.js +3 -24
  95. package/dest/spartan/setup_test_wallets.d.ts +12 -3
  96. package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
  97. package/dest/spartan/setup_test_wallets.js +54 -11
  98. package/dest/spartan/tx_metrics.js +1 -1
  99. package/dest/spartan/utils/bot.d.ts +3 -2
  100. package/dest/spartan/utils/bot.d.ts.map +1 -1
  101. package/dest/spartan/utils/bot.js +2 -1
  102. package/dest/spartan/utils/config.d.ts +10 -1
  103. package/dest/spartan/utils/config.d.ts.map +1 -1
  104. package/dest/spartan/utils/config.js +4 -1
  105. package/dest/spartan/utils/index.d.ts +6 -4
  106. package/dest/spartan/utils/index.d.ts.map +1 -1
  107. package/dest/spartan/utils/index.js +6 -2
  108. package/dest/spartan/utils/k8s.d.ts +31 -1
  109. package/dest/spartan/utils/k8s.d.ts.map +1 -1
  110. package/dest/spartan/utils/k8s.js +124 -0
  111. package/dest/spartan/utils/nodes.d.ts +14 -5
  112. package/dest/spartan/utils/nodes.d.ts.map +1 -1
  113. package/dest/spartan/utils/nodes.js +204 -33
  114. package/dest/spartan/utils/pod_logs.d.ts +25 -0
  115. package/dest/spartan/utils/pod_logs.d.ts.map +1 -0
  116. package/dest/spartan/utils/pod_logs.js +74 -0
  117. package/dest/spartan/utils/scripts.d.ts +18 -4
  118. package/dest/spartan/utils/scripts.d.ts.map +1 -1
  119. package/dest/spartan/utils/scripts.js +19 -4
  120. package/dest/test-wallet/test_wallet.d.ts +83 -0
  121. package/dest/test-wallet/test_wallet.d.ts.map +1 -0
  122. package/dest/test-wallet/test_wallet.js +214 -0
  123. package/dest/test-wallet/utils.d.ts +41 -0
  124. package/dest/test-wallet/utils.d.ts.map +1 -0
  125. package/dest/test-wallet/utils.js +71 -0
  126. package/dest/test-wallet/wallet_worker_script.d.ts +2 -0
  127. package/dest/test-wallet/wallet_worker_script.d.ts.map +1 -0
  128. package/dest/test-wallet/wallet_worker_script.js +48 -0
  129. package/dest/test-wallet/worker_wallet.d.ts +52 -0
  130. package/dest/test-wallet/worker_wallet.d.ts.map +1 -0
  131. package/dest/test-wallet/worker_wallet.js +151 -0
  132. package/dest/test-wallet/worker_wallet_schema.d.ts +274 -0
  133. package/dest/test-wallet/worker_wallet_schema.d.ts.map +1 -0
  134. package/dest/test-wallet/worker_wallet_schema.js +10 -0
  135. package/package.json +46 -43
  136. package/src/bench/client_flows/client_flows_benchmark.ts +42 -38
  137. package/src/bench/client_flows/config.ts +9 -1
  138. package/src/bench/utils.ts +8 -3
  139. package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +28 -15
  140. package/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +7 -8
  141. package/src/e2e_deploy_contract/deploy_test.ts +3 -3
  142. package/src/e2e_epochs/epochs_test.ts +74 -63
  143. package/src/e2e_fees/bridging_race.notest.ts +1 -1
  144. package/src/e2e_fees/fees_test.ts +20 -28
  145. package/src/e2e_nested_contract/nested_contract_test.ts +7 -5
  146. package/src/e2e_p2p/inactivity_slash_test.ts +4 -4
  147. package/src/e2e_p2p/p2p_network.ts +36 -10
  148. package/src/e2e_p2p/reqresp/utils.ts +256 -0
  149. package/src/e2e_p2p/shared.ts +58 -3
  150. package/src/e2e_storage_proof/fixtures/storage_proof.json +915 -0
  151. package/src/e2e_storage_proof/fixtures/storage_proof_fetcher.ts +190 -0
  152. package/src/e2e_storage_proof/fixtures/storage_proof_fixture.ts +173 -0
  153. package/src/e2e_token_contract/token_contract_test.ts +26 -9
  154. package/src/fixtures/authwit_proxy.ts +50 -0
  155. package/src/fixtures/dumps/epoch_proof_result.json +1 -1
  156. package/src/fixtures/e2e_prover_test.ts +39 -43
  157. package/src/fixtures/elu_monitor.ts +126 -0
  158. package/src/fixtures/fixtures.ts +10 -0
  159. package/src/fixtures/ha_setup.ts +186 -0
  160. package/src/fixtures/index.ts +1 -0
  161. package/src/fixtures/setup.ts +100 -214
  162. package/src/fixtures/setup_p2p_test.ts +25 -24
  163. package/src/fixtures/token_utils.ts +6 -3
  164. package/src/guides/up_quick_start.sh +3 -3
  165. package/src/shared/cross_chain_test_harness.ts +13 -9
  166. package/src/shared/gas_portal_test_harness.ts +1 -1
  167. package/src/shared/index.ts +1 -0
  168. package/src/shared/jest_setup.ts +51 -1
  169. package/src/shared/mock_state_view.ts +188 -0
  170. package/src/shared/submit-transactions.ts +3 -2
  171. package/src/shared/uniswap_l1_l2.ts +15 -15
  172. package/src/simulators/lending_simulator.ts +4 -2
  173. package/src/simulators/token_simulator.ts +6 -30
  174. package/src/spartan/setup_test_wallets.ts +102 -17
  175. package/src/spartan/tx_metrics.ts +1 -1
  176. package/src/spartan/utils/bot.ts +4 -1
  177. package/src/spartan/utils/config.ts +3 -0
  178. package/src/spartan/utils/index.ts +10 -1
  179. package/src/spartan/utils/k8s.ts +160 -0
  180. package/src/spartan/utils/nodes.ts +251 -31
  181. package/src/spartan/utils/pod_logs.ts +99 -0
  182. package/src/spartan/utils/scripts.ts +43 -7
  183. package/src/test-wallet/test_wallet.ts +306 -0
  184. package/src/test-wallet/utils.ts +112 -0
  185. package/src/test-wallet/wallet_worker_script.ts +60 -0
  186. package/src/test-wallet/worker_wallet.ts +213 -0
  187. package/src/test-wallet/worker_wallet_schema.ts +13 -0
@@ -13,11 +13,14 @@ import type { Logger } from '@aztec/foundation/log';
13
13
  import { retryUntil } from '@aztec/foundation/retry';
14
14
  import { TokenContract } from '@aztec/noir-contracts.js/Token';
15
15
  import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
16
- import { TestWallet, proveInteraction, registerInitialLocalNetworkAccountsInWallet } from '@aztec/test-wallet/server';
16
+ import { registerInitialLocalNetworkAccountsInWallet } from '@aztec/wallets/testing';
17
17
 
18
18
  import { getACVMConfig } from '../fixtures/get_acvm_config.js';
19
19
  import { getBBConfig } from '../fixtures/get_bb_config.js';
20
20
  import { getSponsoredFPCAddress, registerSponsoredFPC } from '../fixtures/utils.js';
21
+ import { TestWallet } from '../test-wallet/test_wallet.js';
22
+ import { proveInteraction } from '../test-wallet/utils.js';
23
+ import { WorkerWallet } from '../test-wallet/worker_wallet.js';
21
24
 
22
25
  export interface TestAccounts {
23
26
  aztecNode: AztecNode;
@@ -85,11 +88,19 @@ export async function deploySponsoredTestAccountsWithTokens(
85
88
 
86
89
  const paymentMethod = new SponsoredFeePaymentMethod(await getSponsoredFPCAddress());
87
90
  const recipientDeployMethod = await recipientAccount.getDeployMethod();
88
- await recipientDeployMethod.send({ from: AztecAddress.ZERO, fee: { paymentMethod }, wait: { timeout: 2400 } });
91
+ await recipientDeployMethod.send({
92
+ from: AztecAddress.ZERO,
93
+ fee: { paymentMethod },
94
+ wait: { timeout: 2400 },
95
+ });
89
96
  await Promise.all(
90
97
  fundedAccounts.map(async a => {
91
98
  const deployMethod = await a.getDeployMethod();
92
- await deployMethod.send({ from: AztecAddress.ZERO, fee: { paymentMethod }, wait: { timeout: 2400 } }); // increase timeout on purpose in order to account for two empty epochs
99
+ await deployMethod.send({
100
+ from: AztecAddress.ZERO,
101
+ fee: { paymentMethod },
102
+ wait: { timeout: 2400 },
103
+ }); // increase timeout on purpose in order to account for two empty epochs
93
104
  logger.info(`Account deployed at ${a.address}`);
94
105
  }),
95
106
  );
@@ -118,16 +129,28 @@ export async function deploySponsoredTestAccountsWithTokens(
118
129
  }
119
130
 
120
131
  async function deployAccountWithDiagnostics(
121
- account: { getDeployMethod: () => Promise<{ send: (opts: any) => any }>; address: any },
132
+ account: { getDeployMethod: () => Promise<{ simulate: (opts: any) => any; send: (opts: any) => any }>; address: any },
122
133
  paymentMethod: SponsoredFeePaymentMethod,
123
134
  aztecNode: AztecNode,
124
135
  logger: Logger,
125
136
  accountLabel: string,
137
+ estimateGas?: boolean,
126
138
  ): Promise<void> {
127
139
  const deployMethod = await account.getDeployMethod();
128
140
  let txHash;
129
141
  try {
130
- txHash = await deployMethod.send({ from: AztecAddress.ZERO, fee: { paymentMethod }, wait: NO_WAIT });
142
+ let gasSettings;
143
+ if (estimateGas) {
144
+ const sim = await deployMethod.simulate({ from: AztecAddress.ZERO, fee: { paymentMethod } });
145
+ gasSettings = sim.estimatedGas;
146
+ logger.info(`${accountLabel} estimated gas: DA=${gasSettings.gasLimits.daGas} L2=${gasSettings.gasLimits.l2Gas}`);
147
+ }
148
+ const deployResult = await deployMethod.send({
149
+ from: AztecAddress.ZERO,
150
+ fee: { paymentMethod, gasSettings },
151
+ wait: NO_WAIT,
152
+ });
153
+ txHash = deployResult.txHash;
131
154
  await waitForTx(aztecNode, txHash, { timeout: 2400 });
132
155
  logger.info(`${accountLabel} deployed at ${account.address}`);
133
156
  } catch (error) {
@@ -149,18 +172,29 @@ async function deployAccountWithDiagnostics(
149
172
  }
150
173
 
151
174
  async function deployAccountsInBatches(
152
- accounts: { getDeployMethod: () => Promise<{ send: (opts: any) => any }>; address: any }[],
175
+ accounts: {
176
+ getDeployMethod: () => Promise<{ simulate: (opts: any) => any; send: (opts: any) => any }>;
177
+ address: any;
178
+ }[],
153
179
  paymentMethod: SponsoredFeePaymentMethod,
154
180
  aztecNode: AztecNode,
155
181
  logger: Logger,
156
182
  labelPrefix: string,
157
183
  batchSize = 2,
184
+ estimateGas?: boolean,
158
185
  ): Promise<void> {
159
186
  for (let i = 0; i < accounts.length; i += batchSize) {
160
187
  const batch = accounts.slice(i, i + batchSize);
161
188
  await Promise.all(
162
189
  batch.map((account, idx) =>
163
- deployAccountWithDiagnostics(account, paymentMethod, aztecNode, logger, `${labelPrefix}${i + idx + 1}`),
190
+ deployAccountWithDiagnostics(
191
+ account,
192
+ paymentMethod,
193
+ aztecNode,
194
+ logger,
195
+ `${labelPrefix}${i + idx + 1}`,
196
+ estimateGas,
197
+ ),
164
198
  ),
165
199
  );
166
200
  }
@@ -171,6 +205,7 @@ export async function deploySponsoredTestAccounts(
171
205
  aztecNode: AztecNode,
172
206
  logger: Logger,
173
207
  numberOfFundedWallets = 1,
208
+ opts?: { estimateGas?: boolean },
174
209
  ): Promise<TestAccountsWithoutTokens> {
175
210
  const [recipient, ...funded] = await generateSchnorrAccounts(numberOfFundedWallets + 1);
176
211
  const recipientAccount = await wallet.createSchnorrAccount(recipient.secret, recipient.salt);
@@ -180,8 +215,23 @@ export async function deploySponsoredTestAccounts(
180
215
 
181
216
  const paymentMethod = new SponsoredFeePaymentMethod(await getSponsoredFPCAddress());
182
217
 
183
- await deployAccountWithDiagnostics(recipientAccount, paymentMethod, aztecNode, logger, 'Recipient account');
184
- await deployAccountsInBatches(fundedAccounts, paymentMethod, aztecNode, logger, 'Funded account ', 2);
218
+ await deployAccountWithDiagnostics(
219
+ recipientAccount,
220
+ paymentMethod,
221
+ aztecNode,
222
+ logger,
223
+ 'Recipient account',
224
+ opts?.estimateGas,
225
+ );
226
+ await deployAccountsInBatches(
227
+ fundedAccounts,
228
+ paymentMethod,
229
+ aztecNode,
230
+ logger,
231
+ 'Funded account ',
232
+ 2,
233
+ opts?.estimateGas,
234
+ );
185
235
 
186
236
  return {
187
237
  aztecNode,
@@ -263,7 +313,7 @@ async function bridgeL1FeeJuice(
263
313
  const claim = await portal.bridgeTokensPublic(recipient, amount, true /* mint */);
264
314
 
265
315
  const isSynced = async () =>
266
- (await aztecNode.getL1ToL2MessageBlock(Fr.fromHexString(claim.messageHash))) !== undefined;
316
+ (await aztecNode.getL1ToL2MessageCheckpoint(Fr.fromHexString(claim.messageHash))) !== undefined;
267
317
  await retryUntil(isSynced, `message ${claim.messageHash} sync`, 24, 0.5);
268
318
 
269
319
  log.info(`Created a claim for ${amount} L1 fee juice to ${recipient}.`, claim);
@@ -295,13 +345,9 @@ async function deployTokenAndMint(
295
345
  logger: Logger,
296
346
  ) {
297
347
  logger.verbose(`Deploying TokenContract...`);
298
- const { contract: tokenContract } = await TokenContract.deploy(
299
- wallet,
300
- admin,
301
- TOKEN_NAME,
302
- TOKEN_SYMBOL,
303
- TOKEN_DECIMALS,
304
- ).send({
348
+ const {
349
+ receipt: { contract: tokenContract },
350
+ } = await TokenContract.deploy(wallet, admin, TOKEN_NAME, TOKEN_SYMBOL, TOKEN_DECIMALS).send({
305
351
  from: admin,
306
352
  fee: {
307
353
  paymentMethod,
@@ -395,3 +441,42 @@ export async function createWalletAndAztecNodeClient(
395
441
  },
396
442
  };
397
443
  }
444
+
445
+ export type WorkerWalletWrapper = {
446
+ wallet: WorkerWallet;
447
+ aztecNode: AztecNode;
448
+ cleanup: () => Promise<void>;
449
+ };
450
+
451
+ export async function createWorkerWalletClient(
452
+ nodeUrl: string,
453
+ proverEnabled: boolean,
454
+ logger: Logger,
455
+ ): Promise<WorkerWalletWrapper> {
456
+ const aztecNode = createAztecNodeClient(nodeUrl);
457
+ const [bbConfig, acvmConfig] = await Promise.all([getBBConfig(logger), getACVMConfig(logger)]);
458
+
459
+ // Strip cleanup functions — they can't be structured-cloned for worker transfer
460
+ const { cleanup: bbCleanup, ...bbPaths } = bbConfig ?? {};
461
+ const { cleanup: acvmCleanup, ...acvmPaths } = acvmConfig ?? {};
462
+
463
+ const pxeConfig = {
464
+ dataDirectory: undefined,
465
+ dataStoreMapSizeKb: 1024 * 1024,
466
+ ...bbPaths,
467
+ ...acvmPaths,
468
+ proverEnabled,
469
+ };
470
+
471
+ const wallet = await WorkerWallet.create(nodeUrl, pxeConfig);
472
+
473
+ return {
474
+ wallet,
475
+ aztecNode,
476
+ async cleanup() {
477
+ await wallet.stop();
478
+ await bbCleanup?.();
479
+ await acvmCleanup?.();
480
+ },
481
+ };
482
+ }
@@ -296,7 +296,7 @@ export class TxInclusionMetrics {
296
296
  value: stats.mean,
297
297
  },
298
298
  {
299
- name: `${group}/median_inclusion`,
299
+ name: `${group}/p50_inclusion`,
300
300
  unit: 's',
301
301
  value: stats.median,
302
302
  },
@@ -34,7 +34,8 @@ export async function installTransferBot({
34
34
  logger: log,
35
35
  replicas = 1,
36
36
  txIntervalSeconds = 10,
37
- followChain = 'PENDING',
37
+ followChain = 'CHECKPOINTED',
38
+ pxeSyncChainTip = 'proposed',
38
39
  mnemonic = process.env.LABS_INFRA_MNEMONIC ?? 'test test test test test test test test test test test junk',
39
40
  mnemonicStartIndex,
40
41
  botPrivateKey = process.env.BOT_TRANSFERS_L2_PRIVATE_KEY ?? '0xcafe01',
@@ -49,6 +50,7 @@ export async function installTransferBot({
49
50
  replicas?: number;
50
51
  txIntervalSeconds?: number;
51
52
  followChain?: string;
53
+ pxeSyncChainTip?: string;
52
54
  mnemonic?: string;
53
55
  mnemonicStartIndex?: number | string;
54
56
  botPrivateKey?: string;
@@ -67,6 +69,7 @@ export async function installTransferBot({
67
69
  'bot.replicaCount': replicas,
68
70
  'bot.txIntervalSeconds': txIntervalSeconds,
69
71
  'bot.followChain': followChain,
72
+ 'bot.pxeSyncChainTip': pxeSyncChainTip,
70
73
  'bot.botPrivateKey': botPrivateKey,
71
74
  'bot.nodeUrl': resolvedNodeUrl,
72
75
  'bot.mnemonic': mnemonic,
@@ -8,6 +8,7 @@ const logger = createLogger('e2e:k8s-utils');
8
8
  const testConfigSchema = z.object({
9
9
  NAMESPACE: z.string().default('scenario'),
10
10
  REAL_VERIFIER: schemas.Boolean.optional().default(true),
11
+ DEBUG_FORCE_TX_PROOF_VERIFICATION: schemas.Boolean.optional().default(true),
11
12
  CREATE_ETH_DEVNET: schemas.Boolean.optional().default(false),
12
13
  L1_RPC_URLS_JSON: z.string().optional(),
13
14
  L1_ACCOUNT_MNEMONIC: z.string().optional(),
@@ -15,6 +16,8 @@ const testConfigSchema = z.object({
15
16
  AZTEC_EPOCH_DURATION: z.coerce.number().optional().default(32),
16
17
  AZTEC_PROOF_SUBMISSION_WINDOW: z.coerce.number().optional().default(5),
17
18
  AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET: z.coerce.number().optional().default(2),
19
+ FUNDING_PRIVATE_KEY: z.string().optional(),
20
+ AZTEC_ADMIN_API_KEY: z.string().optional(),
18
21
  });
19
22
 
20
23
  export type TestConfig = z.infer<typeof testConfigSchema>;
@@ -5,7 +5,7 @@
5
5
  export { type TestConfig, setupEnvironment } from './config.js';
6
6
 
7
7
  // Scripts
8
- export { getGitProjectRoot, getAztecBin, runAztecBin, runProjectScript } from './scripts.js';
8
+ export { type ScriptResult, getGitProjectRoot, getAztecBin, runAztecBin, runProjectScript } from './scripts.js';
9
9
 
10
10
  // K8s operations
11
11
  export {
@@ -24,6 +24,8 @@ export {
24
24
  getServiceEndpoint,
25
25
  getRPCEndpoint,
26
26
  getEthereumEndpoint,
27
+ createResilientPrometheusConnection,
28
+ scaleProverAgents,
27
29
  } from './k8s.js';
28
30
 
29
31
  // Chaos Mesh
@@ -39,12 +41,16 @@ export {
39
41
  applyNetworkShaping,
40
42
  } from './chaos.js';
41
43
 
44
+ // Helm
45
+ export { hasDeployedHelmRelease } from './helm.js';
46
+
42
47
  // Bot management
43
48
  export { restartBot, installTransferBot, uninstallTransferBot } from './bot.js';
44
49
 
45
50
  // Node operations (sequencers, validators, pods)
46
51
  export {
47
52
  awaitCheckpointNumber,
53
+ waitForProvenToAdvance,
48
54
  getSequencers,
49
55
  updateSequencersConfig,
50
56
  getSequencersConfig,
@@ -60,3 +66,6 @@ export { getPublicViemClient, getL1DeploymentAddresses, getNodeClient } from './
60
66
 
61
67
  // Health checks
62
68
  export { ChainHealth, type ChainHealthSnapshot } from './health.js';
69
+
70
+ // Pod log extraction
71
+ export { type BlockBuiltLogEntry, fetchBlockBuiltLogs } from './pod_logs.js';
@@ -1,4 +1,5 @@
1
1
  import { createLogger } from '@aztec/aztec.js/log';
2
+ import type { Logger } from '@aztec/foundation/log';
2
3
  import { promiseWithResolvers } from '@aztec/foundation/promise';
3
4
  import { retryUntil } from '@aztec/foundation/retry';
4
5
 
@@ -6,6 +7,8 @@ import { type ChildProcess, exec, spawn } from 'child_process';
6
7
  import path from 'path';
7
8
  import { promisify } from 'util';
8
9
 
10
+ import { AlertTriggeredError, GrafanaClient } from '../../quality_of_service/grafana_client.js';
11
+
9
12
  const execAsync = promisify(exec);
10
13
 
11
14
  const logger = createLogger('e2e:k8s-utils');
@@ -370,6 +373,163 @@ export async function waitForResourcesByName({
370
373
  );
371
374
  }
372
375
 
376
+ /**
377
+ * Waits for all StatefulSets matching a label to have all their replicas ready.
378
+ *
379
+ * @param namespace - Kubernetes namespace
380
+ * @param label - Label selector for StatefulSets (e.g., "app.kubernetes.io/component=sequencer-node")
381
+ * @param timeoutSeconds - Maximum time to wait in seconds
382
+ * @param pollIntervalSeconds - How often to check status
383
+ */
384
+ export async function waitForStatefulSetsReady({
385
+ namespace,
386
+ label,
387
+ timeoutSeconds = 600,
388
+ pollIntervalSeconds = 5,
389
+ }: {
390
+ namespace: string;
391
+ label: string;
392
+ timeoutSeconds?: number;
393
+ pollIntervalSeconds?: number;
394
+ }): Promise<void> {
395
+ logger.info(`Waiting for StatefulSets with label ${label} to have all replicas ready (timeout: ${timeoutSeconds}s)`);
396
+
397
+ await retryUntil(
398
+ async () => {
399
+ // Get all StatefulSets matching the label
400
+ const getCmd = `kubectl get statefulset -l ${label} -n ${namespace} -o json`;
401
+ const { stdout } = await execAsync(getCmd);
402
+ const result = JSON.parse(stdout);
403
+
404
+ if (!result.items || result.items.length === 0) {
405
+ logger.verbose(`No StatefulSets found with label ${label}`);
406
+ return false;
407
+ }
408
+
409
+ // Check each StatefulSet
410
+ for (const sts of result.items) {
411
+ const name = sts.metadata.name;
412
+ const desired = sts.spec.replicas ?? 0;
413
+ const ready = sts.status.readyReplicas ?? 0;
414
+ const updated = sts.status.updatedReplicas ?? 0;
415
+
416
+ if (ready < desired || updated < desired) {
417
+ logger.verbose(`StatefulSet ${name}: ${ready}/${desired} ready, ${updated}/${desired} updated`);
418
+ return false;
419
+ }
420
+ }
421
+
422
+ logger.info(`All StatefulSets with label ${label} are ready`);
423
+ return true;
424
+ },
425
+ `StatefulSets with label ${label} to be ready`,
426
+ timeoutSeconds,
427
+ pollIntervalSeconds,
428
+ );
429
+ }
430
+
431
+ /**
432
+ * Creates a Prometheus connection that can re-establish port-forward on failure.
433
+ * Returns functions to connect and run alert checks that automatically reconnect if needed.
434
+ *
435
+ * @param namespace - K8s namespace to fall back to if metrics namespace doesn't have Prometheus
436
+ * @param endpoints - Array to track created endpoints for cleanup
437
+ * @param log - Logger instance
438
+ */
439
+ export function createResilientPrometheusConnection(
440
+ namespace: string,
441
+ endpoints: ServiceEndpoint[],
442
+ log: Logger,
443
+ ): {
444
+ connect: () => Promise<GrafanaClient>;
445
+ runAlertCheck: (alerts: Parameters<GrafanaClient['runAlertCheck']>[0]) => Promise<void>;
446
+ } {
447
+ let alertChecker: GrafanaClient | undefined;
448
+ let currentEndpoint: ServiceEndpoint | undefined;
449
+
450
+ const connect = async (): Promise<GrafanaClient> => {
451
+ // Kill existing connection if any
452
+ if (currentEndpoint?.process) {
453
+ currentEndpoint.process.kill();
454
+ }
455
+
456
+ // Try metrics namespace first, then network namespace
457
+ let promPort = 0;
458
+ let promUrl = '';
459
+ let promProc: ChildProcess | undefined;
460
+
461
+ try {
462
+ const metricsResult = await startPortForward({
463
+ resource: `svc/metrics-prometheus-server`,
464
+ namespace: 'metrics',
465
+ containerPort: 80,
466
+ });
467
+ promProc = metricsResult.process;
468
+ promPort = metricsResult.port;
469
+ promUrl = `http://127.0.0.1:${promPort}/api/v1`;
470
+ } catch {
471
+ // Metrics namespace might not have Prometheus, try network namespace
472
+ log.verbose('Metrics namespace Prometheus not available, trying network namespace');
473
+ }
474
+
475
+ if (promPort === 0) {
476
+ const nsResult = await startPortForward({
477
+ resource: `svc/prometheus-server`,
478
+ namespace,
479
+ containerPort: 80,
480
+ });
481
+ promProc = nsResult.process;
482
+ promPort = nsResult.port;
483
+ promUrl = `http://127.0.0.1:${promPort}/api/v1`;
484
+ }
485
+
486
+ if (!promProc || promPort === 0) {
487
+ throw new Error('Unable to port-forward to Prometheus');
488
+ }
489
+
490
+ currentEndpoint = { url: promUrl, process: promProc };
491
+ endpoints.push(currentEndpoint);
492
+ alertChecker = new GrafanaClient(log, { grafanaEndpoint: promUrl, grafanaCredentials: '' });
493
+ log.info(`Established Prometheus connection at ${promUrl}`);
494
+ return alertChecker;
495
+ };
496
+
497
+ const runAlertCheck = async (alerts: Parameters<GrafanaClient['runAlertCheck']>[0]): Promise<void> => {
498
+ if (!alertChecker) {
499
+ alertChecker = await connect();
500
+ }
501
+
502
+ try {
503
+ await alertChecker.runAlertCheck(alerts);
504
+ } catch (err) {
505
+ // If it's an AlertTriggeredError (expected behavior)
506
+ if (err instanceof AlertTriggeredError) {
507
+ throw err;
508
+ }
509
+
510
+ // Check if it's a connection error (port-forward died)
511
+ const errorStr = String(err);
512
+ if (errorStr.includes('fetch failed') || errorStr.includes('ECONNREFUSED') || errorStr.includes('ECONNRESET')) {
513
+ log.warn(`Prometheus connection lost, re-establishing port-forward...`);
514
+ alertChecker = await connect();
515
+ await alertChecker.runAlertCheck(alerts);
516
+ } else {
517
+ throw err;
518
+ }
519
+ }
520
+ };
521
+
522
+ return { connect, runAlertCheck };
523
+ }
524
+
525
+ /** Scales the prover-agent Deployment to the given number of replicas. */
526
+ export async function scaleProverAgents(namespace: string, replicas: number, log: Logger): Promise<void> {
527
+ const label = 'app.kubernetes.io/component=prover-agent';
528
+ const command = `kubectl scale deployment -l ${label} -n ${namespace} --replicas=${replicas} --timeout=2m`;
529
+ log.info(`Scaling prover agents to ${replicas}: ${command}`);
530
+ await execAsync(command);
531
+ }
532
+
373
533
  export function getChartDir(spartanDir: string, chartName: string) {
374
534
  return path.join(spartanDir.trim(), chartName);
375
535
  }