@aztec/end-to-end 0.0.1-commit.86469d5 → 0.0.1-commit.8655d4a

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 (226) hide show
  1. package/README.md +27 -0
  2. package/dest/bench/client_flows/benchmark.d.ts +15 -1
  3. package/dest/bench/client_flows/benchmark.d.ts.map +1 -1
  4. package/dest/bench/client_flows/benchmark.js +17 -0
  5. package/dest/bench/client_flows/client_flows_benchmark.d.ts +3 -3
  6. package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
  7. package/dest/bench/client_flows/client_flows_benchmark.js +36 -39
  8. package/dest/bench/client_flows/config.d.ts +2 -2
  9. package/dest/bench/client_flows/config.d.ts.map +1 -1
  10. package/dest/bench/client_flows/config.js +18 -0
  11. package/dest/bench/utils.d.ts +1 -1
  12. package/dest/bench/utils.d.ts.map +1 -1
  13. package/dest/bench/utils.js +8 -3
  14. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +8 -5
  15. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts.map +1 -1
  16. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.js +36 -17
  17. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts +16 -5
  18. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts.map +1 -1
  19. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.js +42 -9
  20. package/dest/e2e_deploy_contract/deploy_test.d.ts +4 -4
  21. package/dest/e2e_deploy_contract/deploy_test.d.ts.map +1 -1
  22. package/dest/e2e_deploy_contract/deploy_test.js +2 -1
  23. package/dest/e2e_epochs/epochs_test.d.ts +33 -8
  24. package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
  25. package/dest/e2e_epochs/epochs_test.js +143 -44
  26. package/dest/e2e_fees/fees_test.d.ts +6 -3
  27. package/dest/e2e_fees/fees_test.d.ts.map +1 -1
  28. package/dest/e2e_fees/fees_test.js +50 -17
  29. package/dest/e2e_nested_contract/nested_contract_test.d.ts +3 -3
  30. package/dest/e2e_nested_contract/nested_contract_test.d.ts.map +1 -1
  31. package/dest/e2e_nested_contract/nested_contract_test.js +6 -7
  32. package/dest/e2e_p2p/inactivity_slash_test.d.ts +1 -1
  33. package/dest/e2e_p2p/inactivity_slash_test.d.ts.map +1 -1
  34. package/dest/e2e_p2p/inactivity_slash_test.js +5 -3
  35. package/dest/e2e_p2p/p2p_network.d.ts +14 -12
  36. package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
  37. package/dest/e2e_p2p/p2p_network.js +70 -34
  38. package/dest/e2e_p2p/reqresp/utils.d.ts +3 -3
  39. package/dest/e2e_p2p/reqresp/utils.d.ts.map +1 -1
  40. package/dest/e2e_p2p/reqresp/utils.js +67 -14
  41. package/dest/e2e_p2p/shared.d.ts +26 -8
  42. package/dest/e2e_p2p/shared.d.ts.map +1 -1
  43. package/dest/e2e_p2p/shared.js +78 -51
  44. package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.d.ts +2 -0
  45. package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.d.ts.map +1 -0
  46. package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.js +184 -0
  47. package/dest/e2e_storage_proof/fixtures/storage_proof_fixture.d.ts +18 -0
  48. package/dest/e2e_storage_proof/fixtures/storage_proof_fixture.d.ts.map +1 -0
  49. package/dest/e2e_storage_proof/fixtures/storage_proof_fixture.js +120 -0
  50. package/dest/e2e_token_contract/token_contract_test.d.ts +6 -4
  51. package/dest/e2e_token_contract/token_contract_test.d.ts.map +1 -1
  52. package/dest/e2e_token_contract/token_contract_test.js +23 -11
  53. package/dest/fixtures/authwit_proxy.d.ts +15 -0
  54. package/dest/fixtures/authwit_proxy.d.ts.map +1 -0
  55. package/dest/fixtures/authwit_proxy.js +34 -0
  56. package/dest/fixtures/e2e_prover_test.d.ts +9 -8
  57. package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
  58. package/dest/fixtures/e2e_prover_test.js +39 -50
  59. package/dest/fixtures/elu_monitor.d.ts +21 -0
  60. package/dest/fixtures/elu_monitor.d.ts.map +1 -0
  61. package/dest/fixtures/elu_monitor.js +102 -0
  62. package/dest/fixtures/fixtures.d.ts +77 -1
  63. package/dest/fixtures/fixtures.d.ts.map +1 -1
  64. package/dest/fixtures/fixtures.js +74 -0
  65. package/dest/fixtures/get_bb_config.d.ts +1 -1
  66. package/dest/fixtures/get_bb_config.d.ts.map +1 -1
  67. package/dest/fixtures/get_bb_config.js +5 -5
  68. package/dest/fixtures/ha_setup.d.ts +2 -2
  69. package/dest/fixtures/ha_setup.d.ts.map +1 -1
  70. package/dest/fixtures/ha_setup.js +4 -2
  71. package/dest/fixtures/schnorr_hardcoded_account_contract.d.ts +25 -0
  72. package/dest/fixtures/schnorr_hardcoded_account_contract.d.ts.map +1 -0
  73. package/dest/fixtures/schnorr_hardcoded_account_contract.js +37 -0
  74. package/dest/fixtures/setup.d.ts +80 -32
  75. package/dest/fixtures/setup.d.ts.map +1 -1
  76. package/dest/fixtures/setup.js +186 -167
  77. package/dest/fixtures/setup_p2p_test.d.ts +22 -10
  78. package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
  79. package/dest/fixtures/setup_p2p_test.js +23 -17
  80. package/dest/fixtures/token_utils.d.ts +2 -2
  81. package/dest/fixtures/token_utils.d.ts.map +1 -1
  82. package/dest/fixtures/token_utils.js +5 -7
  83. package/dest/fixtures/utils.d.ts +2 -2
  84. package/dest/fixtures/utils.d.ts.map +1 -1
  85. package/dest/fixtures/utils.js +1 -1
  86. package/dest/forward-compatibility/wallet_rpc_client.d.ts +7 -0
  87. package/dest/forward-compatibility/wallet_rpc_client.d.ts.map +1 -0
  88. package/dest/forward-compatibility/wallet_rpc_client.js +15 -0
  89. package/dest/forward-compatibility/wallet_service.d.ts +3 -0
  90. package/dest/forward-compatibility/wallet_service.d.ts.map +1 -0
  91. package/dest/forward-compatibility/wallet_service.js +109 -0
  92. package/dest/install_legacy_contracts.d.cts +10 -0
  93. package/dest/install_legacy_contracts.d.cts.map +1 -0
  94. package/dest/legacy-jest-resolver.d.cts +3 -0
  95. package/dest/legacy-jest-resolver.d.cts.map +1 -0
  96. package/dest/shared/cross_chain_test_harness.d.ts +4 -2
  97. package/dest/shared/cross_chain_test_harness.d.ts.map +1 -1
  98. package/dest/shared/cross_chain_test_harness.js +22 -18
  99. package/dest/shared/gas_portal_test_harness.d.ts +8 -5
  100. package/dest/shared/gas_portal_test_harness.d.ts.map +1 -1
  101. package/dest/shared/gas_portal_test_harness.js +19 -10
  102. package/dest/shared/index.d.ts +2 -1
  103. package/dest/shared/index.d.ts.map +1 -1
  104. package/dest/shared/index.js +1 -0
  105. package/dest/shared/jest_setup.js +41 -1
  106. package/dest/shared/mock_state_view.d.ts +86 -0
  107. package/dest/shared/mock_state_view.d.ts.map +1 -0
  108. package/dest/shared/mock_state_view.js +186 -0
  109. package/dest/shared/submit-transactions.d.ts +2 -2
  110. package/dest/shared/submit-transactions.d.ts.map +1 -1
  111. package/dest/shared/submit-transactions.js +1 -1
  112. package/dest/shared/uniswap_l1_l2.d.ts +1 -1
  113. package/dest/shared/uniswap_l1_l2.d.ts.map +1 -1
  114. package/dest/shared/uniswap_l1_l2.js +62 -39
  115. package/dest/shared/wait_for_l1_to_l2_message.d.ts +13 -0
  116. package/dest/shared/wait_for_l1_to_l2_message.d.ts.map +1 -0
  117. package/dest/shared/wait_for_l1_to_l2_message.js +10 -0
  118. package/dest/simulators/lending_simulator.d.ts +10 -3
  119. package/dest/simulators/lending_simulator.d.ts.map +1 -1
  120. package/dest/simulators/lending_simulator.js +26 -14
  121. package/dest/simulators/token_simulator.d.ts +1 -1
  122. package/dest/simulators/token_simulator.d.ts.map +1 -1
  123. package/dest/simulators/token_simulator.js +3 -24
  124. package/dest/spartan/setup_test_wallets.d.ts +12 -3
  125. package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
  126. package/dest/spartan/setup_test_wallets.js +103 -40
  127. package/dest/spartan/tx_metrics.d.ts +18 -4
  128. package/dest/spartan/tx_metrics.d.ts.map +1 -1
  129. package/dest/spartan/tx_metrics.js +74 -21
  130. package/dest/spartan/utils/bot.d.ts +3 -2
  131. package/dest/spartan/utils/bot.d.ts.map +1 -1
  132. package/dest/spartan/utils/bot.js +2 -1
  133. package/dest/spartan/utils/config.d.ts +11 -28
  134. package/dest/spartan/utils/config.d.ts.map +1 -1
  135. package/dest/spartan/utils/config.js +4 -1
  136. package/dest/spartan/utils/index.d.ts +5 -3
  137. package/dest/spartan/utils/index.d.ts.map +1 -1
  138. package/dest/spartan/utils/index.js +5 -1
  139. package/dest/spartan/utils/k8s.d.ts +3 -1
  140. package/dest/spartan/utils/k8s.d.ts.map +1 -1
  141. package/dest/spartan/utils/k8s.js +6 -0
  142. package/dest/spartan/utils/nodes.d.ts +4 -5
  143. package/dest/spartan/utils/nodes.d.ts.map +1 -1
  144. package/dest/spartan/utils/nodes.js +11 -11
  145. package/dest/spartan/utils/pod_logs.d.ts +25 -0
  146. package/dest/spartan/utils/pod_logs.d.ts.map +1 -0
  147. package/dest/spartan/utils/pod_logs.js +74 -0
  148. package/dest/spartan/utils/scripts.d.ts +18 -4
  149. package/dest/spartan/utils/scripts.d.ts.map +1 -1
  150. package/dest/spartan/utils/scripts.js +19 -4
  151. package/dest/test-wallet/test_wallet.d.ts +85 -0
  152. package/dest/test-wallet/test_wallet.d.ts.map +1 -0
  153. package/dest/test-wallet/test_wallet.js +273 -0
  154. package/dest/test-wallet/utils.d.ts +41 -0
  155. package/dest/test-wallet/utils.d.ts.map +1 -0
  156. package/dest/test-wallet/utils.js +66 -0
  157. package/dest/test-wallet/wallet_worker_script.d.ts +2 -0
  158. package/dest/test-wallet/wallet_worker_script.d.ts.map +1 -0
  159. package/dest/test-wallet/wallet_worker_script.js +48 -0
  160. package/dest/test-wallet/worker_wallet.d.ts +53 -0
  161. package/dest/test-wallet/worker_wallet.d.ts.map +1 -0
  162. package/dest/test-wallet/worker_wallet.js +155 -0
  163. package/dest/test-wallet/worker_wallet_schema.d.ts +160 -0
  164. package/dest/test-wallet/worker_wallet_schema.d.ts.map +1 -0
  165. package/dest/test-wallet/worker_wallet_schema.js +22 -0
  166. package/package.json +49 -45
  167. package/src/bench/client_flows/benchmark.ts +19 -0
  168. package/src/bench/client_flows/client_flows_benchmark.ts +64 -49
  169. package/src/bench/client_flows/config.ts +9 -1
  170. package/src/bench/utils.ts +10 -4
  171. package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +52 -25
  172. package/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +56 -19
  173. package/src/e2e_deploy_contract/deploy_test.ts +6 -5
  174. package/src/e2e_epochs/epochs_test.ts +166 -68
  175. package/src/e2e_fees/bridging_race.notest.ts +1 -1
  176. package/src/e2e_fees/fees_test.ts +57 -32
  177. package/src/e2e_nested_contract/nested_contract_test.ts +10 -6
  178. package/src/e2e_p2p/inactivity_slash_test.ts +9 -7
  179. package/src/e2e_p2p/p2p_network.ts +93 -49
  180. package/src/e2e_p2p/reqresp/utils.ts +84 -17
  181. package/src/e2e_p2p/shared.ts +95 -65
  182. package/src/e2e_storage_proof/fixtures/storage_proof.json +915 -0
  183. package/src/e2e_storage_proof/fixtures/storage_proof_fetcher.ts +190 -0
  184. package/src/e2e_storage_proof/fixtures/storage_proof_fixture.ts +173 -0
  185. package/src/e2e_token_contract/token_contract_test.ts +38 -11
  186. package/src/fixtures/authwit_proxy.ts +54 -0
  187. package/src/fixtures/dumps/epoch_proof_result.json +1 -1
  188. package/src/fixtures/e2e_prover_test.ts +49 -56
  189. package/src/fixtures/elu_monitor.ts +126 -0
  190. package/src/fixtures/fixtures.ts +96 -0
  191. package/src/fixtures/get_bb_config.ts +7 -6
  192. package/src/fixtures/ha_setup.ts +7 -3
  193. package/src/fixtures/schnorr_hardcoded_account_contract.ts +49 -0
  194. package/src/fixtures/setup.ts +251 -231
  195. package/src/fixtures/setup_p2p_test.ts +37 -32
  196. package/src/fixtures/token_utils.ts +3 -3
  197. package/src/fixtures/utils.ts +2 -0
  198. package/src/forward-compatibility/wallet_rpc_client.ts +14 -0
  199. package/src/forward-compatibility/wallet_service.ts +104 -0
  200. package/src/guides/up_quick_start.sh +3 -5
  201. package/src/install_legacy_contracts.cjs +75 -0
  202. package/src/legacy-jest-resolver.cjs +112 -0
  203. package/src/shared/cross_chain_test_harness.ts +27 -13
  204. package/src/shared/gas_portal_test_harness.ts +21 -11
  205. package/src/shared/index.ts +1 -0
  206. package/src/shared/jest_setup.ts +51 -1
  207. package/src/shared/mock_state_view.ts +188 -0
  208. package/src/shared/submit-transactions.ts +3 -2
  209. package/src/shared/uniswap_l1_l2.ts +80 -55
  210. package/src/shared/wait_for_l1_to_l2_message.ts +23 -0
  211. package/src/simulators/lending_simulator.ts +32 -14
  212. package/src/simulators/token_simulator.ts +6 -30
  213. package/src/spartan/setup_test_wallets.ts +142 -34
  214. package/src/spartan/tx_metrics.ts +82 -24
  215. package/src/spartan/utils/bot.ts +4 -1
  216. package/src/spartan/utils/config.ts +3 -0
  217. package/src/spartan/utils/index.ts +8 -1
  218. package/src/spartan/utils/k8s.ts +8 -0
  219. package/src/spartan/utils/nodes.ts +17 -12
  220. package/src/spartan/utils/pod_logs.ts +99 -0
  221. package/src/spartan/utils/scripts.ts +43 -7
  222. package/src/test-wallet/test_wallet.ts +376 -0
  223. package/src/test-wallet/utils.ts +108 -0
  224. package/src/test-wallet/wallet_worker_script.ts +60 -0
  225. package/src/test-wallet/worker_wallet.ts +218 -0
  226. package/src/test-wallet/worker_wallet_schema.ts +13 -0
@@ -0,0 +1,23 @@
1
+ import type { Fr } from '@aztec/aztec.js/fields';
2
+ import type { AztecNode } from '@aztec/aztec.js/node';
3
+ import { retryUntil } from '@aztec/foundation/retry';
4
+
5
+ /**
6
+ * Waits until the archiver has seen the L1 to L2 message and indexed it. Unlike
7
+ * {@link waitForL1ToL2MessageReady} from `@aztec/aztec.js/messaging`, this does not
8
+ * require the L2 chain to have advanced to the message's checkpoint — it only confirms
9
+ * the message has been picked up from L1. Use this in tests that explicitly produce L2
10
+ * blocks afterwards to make the message consumable.
11
+ */
12
+ export function waitForL1ToL2MessageSeen(
13
+ node: Pick<AztecNode, 'getL1ToL2MessageCheckpoint'>,
14
+ l1ToL2MessageHash: Fr,
15
+ opts: { timeoutSeconds: number },
16
+ ) {
17
+ return retryUntil(
18
+ async () => (await node.getL1ToL2MessageCheckpoint(l1ToL2MessageHash)) !== undefined,
19
+ `L1 to L2 message ${l1ToL2MessageHash.toString()} seen`,
20
+ opts.timeoutSeconds,
21
+ 1,
22
+ );
23
+ }
@@ -7,6 +7,7 @@ import { SlotNumber } from '@aztec/foundation/branded-types';
7
7
  import { poseidon2Hash } from '@aztec/foundation/crypto/poseidon';
8
8
  import type { TestDateProvider } from '@aztec/foundation/timer';
9
9
  import type { LendingContract } from '@aztec/noir-contracts.js/Lending';
10
+ import type { AztecNode, AztecNodeDebug } from '@aztec/stdlib/interfaces/client';
10
11
 
11
12
  import type { TokenSimulator } from './token_simulator.js';
12
13
 
@@ -92,30 +93,45 @@ export class LendingSimulator {
92
93
  public stableCoin: TokenSimulator,
93
94
  ) {}
94
95
 
95
- async prepare() {
96
+ prepare() {
96
97
  this.accumulator = BASE;
97
- const slot = await this.rollup.getSlotAt(BigInt(await this.cc.eth.timestamp()) + BigInt(this.ethereumSlotDuration));
98
- this.time = Number(await this.rollup.getTimestampForSlot(slot));
98
+ this.time = 0;
99
99
  }
100
100
 
101
- async progressSlots(diff: number, dateProvider?: TestDateProvider) {
101
+ /**
102
+ * Advances the simulator's accumulator and clock to match a block timestamp observed on chain.
103
+ * Call this BEFORE applying any accumulator-sensitive mutation (borrow/repay) so the mutation
104
+ * sees the same accumulator as the contract did during execution.
105
+ */
106
+ observeBlockTimestamp(ts: number) {
107
+ const diff = ts - this.time;
108
+ if (diff > 0) {
109
+ this.accumulator = muldivDown(this.accumulator, computeMultiplier(this.rate, BigInt(diff)), BASE);
110
+ }
111
+ this.time = ts;
112
+ }
113
+
114
+ async progressSlots(diff: number, _dateProvider?: TestDateProvider, node?: AztecNode & AztecNodeDebug) {
102
115
  if (diff <= 1) {
103
116
  return;
104
117
  }
105
118
 
106
- const slot = await this.rollup.getSlotAt(BigInt(await this.cc.eth.timestamp()));
119
+ const slot = await this.rollup.getSlotAt(BigInt(await this.cc.eth.lastBlockTimestamp()));
107
120
  const targetSlot = SlotNumber(slot + diff);
108
121
  const ts = Number(await this.rollup.getTimestampForSlot(targetSlot));
109
- const timeDiff = ts - this.time;
110
- this.time = ts;
111
122
 
112
- // Mine ethereum blocks such that the next block will be in a new slot
113
- await this.cc.eth.warp(this.time - this.ethereumSlotDuration);
114
- if (dateProvider) {
115
- dateProvider.setTime(this.time * 1000);
123
+ // Queue-aware warp under AutomineSequencer: atomic warp + mineBlock that advances L2 time to the
124
+ // target slot. The cheat code routes through the AutomineSequencer queue when one is installed,
125
+ // and otherwise falls back to a manual warp + mineBlock loop.
126
+ if (node) {
127
+ await this.cc.warpL2TimeAtLeastTo(node, ts);
128
+ } else {
129
+ await this.cc.eth.warp(ts - this.ethereumSlotDuration);
116
130
  }
131
+
132
+ // Mark the latest checkpoint as proven so the rollup does not reorg pending checkpoints when
133
+ // time jumps far enough forward to cross an unproven epoch boundary.
117
134
  await this.cc.rollup.markAsProven(await this.rollup.getCheckpointNumber());
118
- this.accumulator = muldivDown(this.accumulator, computeMultiplier(this.rate, BigInt(timeDiff)), BASE);
119
135
  }
120
136
 
121
137
  depositPrivate(from: AztecAddress, onBehalfOf: Fr, amount: bigint) {
@@ -186,14 +202,16 @@ export class LendingSimulator {
186
202
 
187
203
  expect(this.borrowed).toEqual(this.stableCoin.totalSupply - this.mintedOutside);
188
204
 
189
- const asset = await this.lendingContract.methods.get_asset(0).simulate({ from: this.account.address });
205
+ const { result: asset } = await this.lendingContract.methods.get_asset(0).simulate({ from: this.account.address });
190
206
 
191
207
  const interestAccumulator = asset['interest_accumulator'];
192
208
  expect(interestAccumulator).toEqual(this.accumulator);
193
209
  expect(asset['last_updated_ts']).toEqual(BigInt(this.time));
194
210
 
195
211
  for (const key of [this.account.address, AztecAddress.fromField(await this.account.key())]) {
196
- const privatePos = await this.lendingContract.methods.get_position(key).simulate({ from: this.account.address });
212
+ const { result: privatePos } = await this.lendingContract.methods
213
+ .get_position(key)
214
+ .simulate({ from: this.account.address });
197
215
  expect(new Fr(privatePos['collateral'])).toEqual(this.collateral[key.toString()] ?? Fr.ZERO);
198
216
  expect(new Fr(privatePos['static_debt'])).toEqual(this.staticDebt[key.toString()] ?? Fr.ZERO);
199
217
  expect(privatePos['debt']).toEqual(
@@ -109,7 +109,9 @@ export class TokenSimulator {
109
109
  await Promise.all(
110
110
  chunk(calls, 5).map(batch => new BatchCall(this.defaultWallet, batch).simulate({ from: this.defaultAddress })),
111
111
  )
112
- ).flat();
112
+ )
113
+ .flatMap(r => r.result)
114
+ .map(r => r.result);
113
115
  expect(results[0]).toEqual(this.totalSupply);
114
116
 
115
117
  // Check that all our balances match
@@ -119,39 +121,13 @@ export class TokenSimulator {
119
121
  }
120
122
 
121
123
  async checkPrivate() {
122
- // Private calls
123
- const defaultLookups = [];
124
- const nonDefaultLookups = [];
125
-
126
124
  for (const address of this.accounts) {
127
- if (this.lookupProvider.has(address.toString())) {
128
- nonDefaultLookups.push(address);
129
- } else {
130
- defaultLookups.push(address);
131
- }
132
- }
133
-
134
- const defaultCalls = defaultLookups.map(address => this.token.methods.balance_of_private(address));
135
- const results = (
136
- await Promise.all(
137
- chunk(defaultCalls, 4).map(batch =>
138
- new BatchCall(this.defaultWallet, batch).simulate({ from: this.defaultAddress }),
139
- ),
140
- )
141
- ).flat();
142
- for (let i = 0; i < defaultLookups.length; i++) {
143
- expect(results[i]).toEqual(this.balanceOfPrivate(defaultLookups[i]));
144
- }
145
-
146
- // We are just running individual calls for the non-default lookups
147
- // @todo We should also batch these
148
- for (const address of nonDefaultLookups) {
149
125
  const wallet = this.lookupProvider.get(address.toString());
150
126
  const asset = wallet ? this.token.withWallet(wallet) : this.token;
151
127
 
152
- const actualPrivateBalance = await asset.methods
153
- .balance_of_private({ address })
154
- .simulate({ from: this.defaultAddress });
128
+ const { result: actualPrivateBalance } = await asset.methods
129
+ .balance_of_private(address)
130
+ .simulate({ from: address });
155
131
  expect(actualPrivateBalance).toEqual(this.balanceOfPrivate(address));
156
132
  }
157
133
  }
@@ -1,23 +1,28 @@
1
1
  import { generateSchnorrAccounts } from '@aztec/accounts/testing';
2
+ import { NO_FROM } from '@aztec/aztec.js/account';
2
3
  import { AztecAddress } from '@aztec/aztec.js/addresses';
3
4
  import { NO_WAIT } from '@aztec/aztec.js/contracts';
4
5
  import { L1FeeJuicePortalManager } from '@aztec/aztec.js/ethereum';
5
6
  import { FeeJuicePaymentMethodWithClaim } from '@aztec/aztec.js/fee';
6
7
  import { type FeePaymentMethod, SponsoredFeePaymentMethod } from '@aztec/aztec.js/fee';
7
8
  import { Fr } from '@aztec/aztec.js/fields';
9
+ import { waitForL1ToL2MessageReady } from '@aztec/aztec.js/messaging';
8
10
  import { type AztecNode, createAztecNodeClient, waitForTx } from '@aztec/aztec.js/node';
9
11
  import type { Wallet } from '@aztec/aztec.js/wallet';
10
12
  import { createEthereumChain } from '@aztec/ethereum/chain';
11
13
  import { createExtendedL1Client } from '@aztec/ethereum/client';
12
14
  import type { Logger } from '@aztec/foundation/log';
13
- import { retryUntil } from '@aztec/foundation/retry';
15
+ import { makeBackoff, retry, retryUntil } from '@aztec/foundation/retry';
14
16
  import { TokenContract } from '@aztec/noir-contracts.js/Token';
15
17
  import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
16
- import { TestWallet, proveInteraction, registerInitialLocalNetworkAccountsInWallet } from '@aztec/test-wallet/server';
18
+ import { registerInitialLocalNetworkAccountsInWallet } from '@aztec/wallets/testing';
17
19
 
18
20
  import { getACVMConfig } from '../fixtures/get_acvm_config.js';
19
21
  import { getBBConfig } from '../fixtures/get_bb_config.js';
20
22
  import { getSponsoredFPCAddress, registerSponsoredFPC } from '../fixtures/utils.js';
23
+ import { TestWallet } from '../test-wallet/test_wallet.js';
24
+ import { proveInteraction } from '../test-wallet/utils.js';
25
+ import { WorkerWallet } from '../test-wallet/worker_wallet.js';
21
26
 
22
27
  export interface TestAccounts {
23
28
  aztecNode: AztecNode;
@@ -85,11 +90,19 @@ export async function deploySponsoredTestAccountsWithTokens(
85
90
 
86
91
  const paymentMethod = new SponsoredFeePaymentMethod(await getSponsoredFPCAddress());
87
92
  const recipientDeployMethod = await recipientAccount.getDeployMethod();
88
- await recipientDeployMethod.send({ from: AztecAddress.ZERO, fee: { paymentMethod }, wait: { timeout: 2400 } });
93
+ await recipientDeployMethod.send({
94
+ from: NO_FROM,
95
+ fee: { paymentMethod },
96
+ wait: { timeout: 2400 },
97
+ });
89
98
  await Promise.all(
90
99
  fundedAccounts.map(async a => {
91
100
  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
101
+ await deployMethod.send({
102
+ from: NO_FROM,
103
+ fee: { paymentMethod },
104
+ wait: { timeout: 2400 },
105
+ }); // increase timeout on purpose in order to account for two empty epochs
93
106
  logger.info(`Account deployed at ${a.address}`);
94
107
  }),
95
108
  );
@@ -118,49 +131,91 @@ export async function deploySponsoredTestAccountsWithTokens(
118
131
  }
119
132
 
120
133
  async function deployAccountWithDiagnostics(
121
- account: { getDeployMethod: () => Promise<{ send: (opts: any) => any }>; address: any },
134
+ account: { getDeployMethod: () => Promise<{ simulate: (opts: any) => any; send: (opts: any) => any }>; address: any },
122
135
  paymentMethod: SponsoredFeePaymentMethod,
123
136
  aztecNode: AztecNode,
124
137
  logger: Logger,
125
138
  accountLabel: string,
139
+ estimateGas?: boolean,
126
140
  ): Promise<void> {
127
141
  const deployMethod = await account.getDeployMethod();
128
- let txHash;
129
- try {
130
- txHash = await deployMethod.send({ from: AztecAddress.ZERO, fee: { paymentMethod }, wait: NO_WAIT });
131
- await waitForTx(aztecNode, txHash, { timeout: 2400 });
132
- logger.info(`${accountLabel} deployed at ${account.address}`);
133
- } catch (error) {
134
- const blockNumber = await aztecNode.getBlockNumber();
135
- let receipt;
136
- try {
137
- receipt = await aztecNode.getTxReceipt(txHash);
138
- } catch {
139
- receipt = 'unavailable';
140
- }
141
- logger.error(`${accountLabel} deployment failed`, {
142
- txHash: txHash.toString(),
143
- receipt: JSON.stringify(receipt),
144
- currentBlockNumber: blockNumber,
145
- error: String(error),
146
- });
147
- throw error;
142
+ let gasSettings: any;
143
+ if (estimateGas) {
144
+ const sim = await deployMethod.simulate({ from: NO_FROM, fee: { paymentMethod } });
145
+ gasSettings = sim.estimatedGas;
146
+ logger.info(`${accountLabel} estimated gas: DA=${gasSettings.gasLimits.daGas} L2=${gasSettings.gasLimits.l2Gas}`);
148
147
  }
148
+
149
+ // Track the tx hash across retries so we don't re-send when the previous tx is still pending.
150
+ let sentTxHash: { txHash: any } | undefined;
151
+
152
+ await retry(
153
+ async () => {
154
+ // Check if already deployed (handles case where previous attempt succeeded but waitForTx timed out)
155
+ const existing = await aztecNode.getContract(account.address);
156
+ if (existing) {
157
+ logger.info(`${accountLabel} already deployed at ${account.address}, skipping`);
158
+ return;
159
+ }
160
+
161
+ // If we already sent a tx, check if it was dropped before deciding to re-send.
162
+ if (sentTxHash) {
163
+ const prevReceipt = await aztecNode.getTxReceipt(sentTxHash.txHash);
164
+ if (prevReceipt.isDropped()) {
165
+ logger.info(`${accountLabel} previous tx ${sentTxHash.txHash} was dropped, re-sending`);
166
+ sentTxHash = undefined;
167
+ } else {
168
+ logger.info(`${accountLabel} previous tx ${sentTxHash.txHash} still pending, waiting again...`);
169
+ }
170
+ }
171
+
172
+ if (!sentTxHash) {
173
+ const deployResult = await deployMethod.send({
174
+ from: NO_FROM,
175
+ fee: { paymentMethod, gasSettings },
176
+ wait: NO_WAIT,
177
+ });
178
+ sentTxHash = { txHash: deployResult.txHash };
179
+ logger.info(`${accountLabel} tx sent`, { txHash: sentTxHash.txHash.toString() });
180
+ }
181
+
182
+ const receipt = await waitForTx(aztecNode, sentTxHash.txHash, { timeout: 600 });
183
+ if (receipt.isDropped()) {
184
+ sentTxHash = undefined;
185
+ throw new Error(`${accountLabel} tx was dropped, retrying...`);
186
+ }
187
+ logger.info(`${accountLabel} deployed at ${account.address}`);
188
+ },
189
+ `deploy ${accountLabel}`,
190
+ makeBackoff([1, 2, 4, 8, 16]),
191
+ logger,
192
+ );
149
193
  }
150
194
 
151
195
  async function deployAccountsInBatches(
152
- accounts: { getDeployMethod: () => Promise<{ send: (opts: any) => any }>; address: any }[],
196
+ accounts: {
197
+ getDeployMethod: () => Promise<{ simulate: (opts: any) => any; send: (opts: any) => any }>;
198
+ address: any;
199
+ }[],
153
200
  paymentMethod: SponsoredFeePaymentMethod,
154
201
  aztecNode: AztecNode,
155
202
  logger: Logger,
156
203
  labelPrefix: string,
157
204
  batchSize = 2,
205
+ estimateGas?: boolean,
158
206
  ): Promise<void> {
159
207
  for (let i = 0; i < accounts.length; i += batchSize) {
160
208
  const batch = accounts.slice(i, i + batchSize);
161
209
  await Promise.all(
162
210
  batch.map((account, idx) =>
163
- deployAccountWithDiagnostics(account, paymentMethod, aztecNode, logger, `${labelPrefix}${i + idx + 1}`),
211
+ deployAccountWithDiagnostics(
212
+ account,
213
+ paymentMethod,
214
+ aztecNode,
215
+ logger,
216
+ `${labelPrefix}${i + idx + 1}`,
217
+ estimateGas,
218
+ ),
164
219
  ),
165
220
  );
166
221
  }
@@ -171,6 +226,7 @@ export async function deploySponsoredTestAccounts(
171
226
  aztecNode: AztecNode,
172
227
  logger: Logger,
173
228
  numberOfFundedWallets = 1,
229
+ opts?: { estimateGas?: boolean },
174
230
  ): Promise<TestAccountsWithoutTokens> {
175
231
  const [recipient, ...funded] = await generateSchnorrAccounts(numberOfFundedWallets + 1);
176
232
  const recipientAccount = await wallet.createSchnorrAccount(recipient.secret, recipient.salt);
@@ -180,8 +236,23 @@ export async function deploySponsoredTestAccounts(
180
236
 
181
237
  const paymentMethod = new SponsoredFeePaymentMethod(await getSponsoredFPCAddress());
182
238
 
183
- await deployAccountWithDiagnostics(recipientAccount, paymentMethod, aztecNode, logger, 'Recipient account');
184
- await deployAccountsInBatches(fundedAccounts, paymentMethod, aztecNode, logger, 'Funded account ', 2);
239
+ await deployAccountWithDiagnostics(
240
+ recipientAccount,
241
+ paymentMethod,
242
+ aztecNode,
243
+ logger,
244
+ 'Recipient account',
245
+ opts?.estimateGas,
246
+ );
247
+ await deployAccountsInBatches(
248
+ fundedAccounts,
249
+ paymentMethod,
250
+ aztecNode,
251
+ logger,
252
+ 'Funded account ',
253
+ 2,
254
+ opts?.estimateGas,
255
+ );
185
256
 
186
257
  return {
187
258
  aztecNode,
@@ -219,7 +290,7 @@ export async function deployTestAccountsWithTokens(
219
290
  fundedAccounts.map(async (a, i) => {
220
291
  const paymentMethod = new FeeJuicePaymentMethodWithClaim(a.address, claims[i]);
221
292
  const deployMethod = await a.getDeployMethod();
222
- await deployMethod.send({ from: AztecAddress.ZERO, fee: { paymentMethod } });
293
+ await deployMethod.send({ from: NO_FROM, fee: { paymentMethod } });
223
294
  logger.info(`Account deployed at ${a.address}`);
224
295
  }),
225
296
  );
@@ -262,9 +333,7 @@ async function bridgeL1FeeJuice(
262
333
  const portal = await L1FeeJuicePortalManager.new(aztecNode, l1Client, log);
263
334
  const claim = await portal.bridgeTokensPublic(recipient, amount, true /* mint */);
264
335
 
265
- const isSynced = async () =>
266
- (await aztecNode.getL1ToL2MessageBlock(Fr.fromHexString(claim.messageHash))) !== undefined;
267
- await retryUntil(isSynced, `message ${claim.messageHash} sync`, 24, 0.5);
336
+ await waitForL1ToL2MessageReady(aztecNode, Fr.fromHexString(claim.messageHash), { timeoutSeconds: 24 });
268
337
 
269
338
  log.info(`Created a claim for ${amount} L1 fee juice to ${recipient}.`, claim);
270
339
  return claim;
@@ -306,7 +375,7 @@ async function deployTokenAndMint(
306
375
  fee: {
307
376
  paymentMethod,
308
377
  },
309
- wait: { timeout: 600, returnReceipt: true },
378
+ wait: { timeout: 600 },
310
379
  });
311
380
 
312
381
  const tokenAddress = tokenContract.address;
@@ -395,3 +464,42 @@ export async function createWalletAndAztecNodeClient(
395
464
  },
396
465
  };
397
466
  }
467
+
468
+ export type WorkerWalletWrapper = {
469
+ wallet: WorkerWallet;
470
+ aztecNode: AztecNode;
471
+ cleanup: () => Promise<void>;
472
+ };
473
+
474
+ export async function createWorkerWalletClient(
475
+ nodeUrl: string,
476
+ proverEnabled: boolean,
477
+ logger: Logger,
478
+ ): Promise<WorkerWalletWrapper> {
479
+ const aztecNode = createAztecNodeClient(nodeUrl);
480
+ const [bbConfig, acvmConfig] = await Promise.all([getBBConfig(logger), getACVMConfig(logger)]);
481
+
482
+ // Strip cleanup functions — they can't be structured-cloned for worker transfer
483
+ const { cleanup: bbCleanup, ...bbPaths } = bbConfig ?? {};
484
+ const { cleanup: acvmCleanup, ...acvmPaths } = acvmConfig ?? {};
485
+
486
+ const pxeConfig = {
487
+ dataDirectory: undefined,
488
+ dataStoreMapSizeKb: 1024 * 1024,
489
+ ...bbPaths,
490
+ ...acvmPaths,
491
+ proverEnabled,
492
+ };
493
+
494
+ const wallet = await WorkerWallet.create(nodeUrl, pxeConfig);
495
+
496
+ return {
497
+ wallet,
498
+ aztecNode,
499
+ async cleanup() {
500
+ await wallet.stop();
501
+ await bbCleanup?.();
502
+ await acvmCleanup?.();
503
+ },
504
+ };
505
+ }
@@ -1,6 +1,6 @@
1
1
  import type { AztecNode } from '@aztec/aztec.js/node';
2
2
  import type { Logger } from '@aztec/foundation/log';
3
- import type { L2Block } from '@aztec/stdlib/block';
3
+ import type { BlockResponse } from '@aztec/stdlib/interfaces/client';
4
4
  import type { TopicType } from '@aztec/stdlib/p2p';
5
5
  import { Tx, type TxReceipt } from '@aztec/stdlib/tx';
6
6
 
@@ -134,9 +134,12 @@ export class ProvingMetrics {
134
134
 
135
135
  export type TxInclusionData = {
136
136
  txHash: string;
137
- sentAt: number;
138
- minedAt: number;
139
- attestedAt: number;
137
+ /** Wall-clock at client when the tx was submitted, in ms (Date.now()). */
138
+ sentAtMs: number;
139
+ /** Wall-clock at client when the block containing the tx first became visible, in ms (Date.now()). -1 if never observed. */
140
+ minedAtMs: number;
141
+ /** Reserved for future attestation-observed-at signal; -1 today. */
142
+ attestedAtMs: number;
140
143
  blocknumber: number;
141
144
  priorityFee: number;
142
145
  totalFee: number;
@@ -147,7 +150,7 @@ export type TxInclusionData = {
147
150
  export class TxInclusionMetrics {
148
151
  private data = new Map<string, TxInclusionData>();
149
152
  private groups = new Set<string>();
150
- private blocks = new Map<number, Promise<L2Block | undefined>>();
153
+ private blocks = new Map<number, Promise<BlockResponse<{ includeTransactions: true }> | undefined>>();
151
154
 
152
155
  private p2pGossipLatencyByTopic: Partial<Record<TopicType, { p50: number; p95: number }>> = {};
153
156
 
@@ -174,9 +177,9 @@ export class TxInclusionMetrics {
174
177
 
175
178
  this.data.set(txHash, {
176
179
  txHash,
177
- sentAt: Math.trunc(Date.now() / 1000),
178
- minedAt: -1,
179
- attestedAt: -1,
180
+ sentAtMs: Date.now(),
181
+ minedAtMs: -1,
182
+ attestedAtMs: -1,
180
183
  blocknumber: -1,
181
184
  priorityFee: Number(priorityFees.feePerDaGas + priorityFees.feePerL2Gas),
182
185
  totalFee: -1,
@@ -186,6 +189,28 @@ export class TxInclusionMetrics {
186
189
  this.groups.add(group);
187
190
  }
188
191
 
192
+ /**
193
+ * Stamp mined-at metadata for any tracked tx contained in this block, using
194
+ * `observedAtMs` (caller-supplied wall-clock at the moment they first saw the
195
+ * block). Idempotent: existing minedAtMs is preserved so the first observer
196
+ * wins (typically the block-watcher; recordMinedTx is a fallback).
197
+ */
198
+ observeBlockForMinedTxs(
199
+ blockNumber: number,
200
+ txHashes: ReadonlyArray<{ toString(): string }>,
201
+ observedAtMs: number,
202
+ ): void {
203
+ txHashes.forEach((txHash, position) => {
204
+ const data = this.data.get(txHash.toString());
205
+ if (!data || data.minedAtMs !== -1) {
206
+ return;
207
+ }
208
+ data.blocknumber = blockNumber;
209
+ data.minedAtMs = observedAtMs;
210
+ data.positionInBlock = position;
211
+ });
212
+ }
213
+
189
214
  async recordMinedTx(txReceipt: TxReceipt): Promise<void> {
190
215
  const { txHash, blockNumber } = txReceipt;
191
216
  if (!txReceipt.isMined() || !txReceipt.hasExecutionSucceeded() || !blockNumber) {
@@ -197,26 +222,43 @@ export class TxInclusionMetrics {
197
222
  return;
198
223
  }
199
224
 
200
- if (!this.blocks.has(blockNumber)) {
201
- this.blocks.set(blockNumber, this.aztecNode.getBlock(blockNumber));
202
- }
203
-
204
- const block = await this.blocks.get(blockNumber)!;
205
- if (!block) {
206
- this.logger?.warn('Failed to load block for mined tx receipt', { txHash: txHash.toString(), blockNumber });
207
- return;
208
- }
209
225
  const data = this.data.get(txHash.toString());
210
226
  if (!data) {
211
227
  const message = `Missing sent tx record for mined tx ${txHash.toString()}`;
212
228
  this.logger?.warn(message, { txHash: txHash.toString(), blockNumber });
213
229
  throw new Error(message);
214
230
  }
215
- data.blocknumber = blockNumber;
216
- data.minedAt = Number(block.header.globalVariables.timestamp);
217
- data.attestedAt = -1;
218
231
  data.totalFee = Number(txReceipt.transactionFee ?? 0n);
219
- data.positionInBlock = block.body.txEffects.findIndex(txEffect => txEffect.txHash.equals(txHash));
232
+
233
+ // Fallback path for txs the block-watcher missed (e.g. observed only after
234
+ // the watcher stopped). Stamp with the block's L2 slot timestamp; this is
235
+ // earlier than the true client-observed time by attestation+propagation
236
+ // lag, but it's the only deterministic timestamp available post-hoc.
237
+ if (data.minedAtMs === -1) {
238
+ if (!this.blocks.has(blockNumber)) {
239
+ this.blocks.set(blockNumber, this.aztecNode.getBlock(blockNumber, { includeTransactions: true }));
240
+ }
241
+ const block = await this.blocks.get(blockNumber)!;
242
+ if (!block) {
243
+ this.logger?.warn('Failed to load block for mined tx receipt', { txHash: txHash.toString(), blockNumber });
244
+ return;
245
+ }
246
+ data.blocknumber = blockNumber;
247
+ data.minedAtMs = Number(block.header.globalVariables.timestamp) * 1000;
248
+ data.positionInBlock = block.body.txEffects.findIndex(txEffect => txEffect.txHash.equals(txHash));
249
+ }
250
+ }
251
+
252
+ /** Per-tx inclusion records for a group. Used to serialise out for downstream tooling. */
253
+ getInclusionRecords(group?: string): TxInclusionData[] {
254
+ const out: TxInclusionData[] = [];
255
+ for (const tx of this.data.values()) {
256
+ if (group !== undefined && tx.group !== group) {
257
+ continue;
258
+ }
259
+ out.push({ ...tx });
260
+ }
261
+ return out;
220
262
  }
221
263
 
222
264
  public inclusionTimeInSeconds(group: string): {
@@ -229,12 +271,28 @@ export class TxInclusionMetrics {
229
271
  p99: number;
230
272
  } {
231
273
  const histogram = createHistogram({});
274
+ let nonPositive = 0;
232
275
  for (const tx of this.data.values()) {
233
- if (!tx.blocknumber || tx.group !== group || tx.minedAt === -1) {
276
+ if (!tx.blocknumber || tx.group !== group || tx.minedAtMs === -1) {
234
277
  continue;
235
278
  }
236
279
 
237
- histogram.record(tx.minedAt - tx.sentAt);
280
+ // Both timestamps are client wall-clock (ms). A negative delta should be
281
+ // impossible since the watcher stamps minedAtMs strictly after sentAtMs,
282
+ // but the fallback path (recordMinedTx via L2 slot timestamp) can stamp
283
+ // earlier than sentAtMs. perf_hooks.createHistogram rejects <=0; skip
284
+ // those instead of crashing.
285
+ const deltaMs = tx.minedAtMs - tx.sentAtMs;
286
+ if (deltaMs <= 0) {
287
+ nonPositive++;
288
+ continue;
289
+ }
290
+ // Histogram is recorded in seconds (rounded) to match the existing
291
+ // toGithubActionBenchmarkJSON output unit; per-tx records carry the raw ms.
292
+ histogram.record(Math.max(1, Math.round(deltaMs / 1000)));
293
+ }
294
+ if (nonPositive > 0) {
295
+ this.logger?.debug(`Dropped ${nonPositive} tx inclusion samples with non-positive delta`, { group });
238
296
  }
239
297
 
240
298
  if (histogram.count === 0) {
@@ -296,7 +354,7 @@ export class TxInclusionMetrics {
296
354
  value: stats.mean,
297
355
  },
298
356
  {
299
- name: `${group}/median_inclusion`,
357
+ name: `${group}/p50_inclusion`,
300
358
  unit: 's',
301
359
  value: stats.median,
302
360
  },
@@ -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 {
@@ -25,6 +25,7 @@ export {
25
25
  getRPCEndpoint,
26
26
  getEthereumEndpoint,
27
27
  createResilientPrometheusConnection,
28
+ scaleProverAgents,
28
29
  } from './k8s.js';
29
30
 
30
31
  // Chaos Mesh
@@ -40,6 +41,9 @@ export {
40
41
  applyNetworkShaping,
41
42
  } from './chaos.js';
42
43
 
44
+ // Helm
45
+ export { hasDeployedHelmRelease } from './helm.js';
46
+
43
47
  // Bot management
44
48
  export { restartBot, installTransferBot, uninstallTransferBot } from './bot.js';
45
49
 
@@ -62,3 +66,6 @@ export { getPublicViemClient, getL1DeploymentAddresses, getNodeClient } from './
62
66
 
63
67
  // Health checks
64
68
  export { ChainHealth, type ChainHealthSnapshot } from './health.js';
69
+
70
+ // Pod log extraction
71
+ export { type BlockBuiltLogEntry, fetchBlockBuiltLogs } from './pod_logs.js';