@aztec/end-to-end 0.0.1-commit.24de95ac → 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 (299) hide show
  1. package/README.md +27 -0
  2. package/dest/bench/client_flows/benchmark.d.ts +17 -2
  3. package/dest/bench/client_flows/benchmark.d.ts.map +1 -1
  4. package/dest/bench/client_flows/benchmark.js +38 -1
  5. package/dest/bench/client_flows/client_flows_benchmark.d.ts +23 -17
  6. package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
  7. package/dest/bench/client_flows/client_flows_benchmark.js +143 -136
  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/client_flows/data_extractor.d.ts +1 -1
  12. package/dest/bench/client_flows/data_extractor.js +7 -27
  13. package/dest/bench/utils.d.ts +8 -7
  14. package/dest/bench/utils.d.ts.map +1 -1
  15. package/dest/bench/utils.js +33 -19
  16. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +12 -10
  17. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts.map +1 -1
  18. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.js +120 -117
  19. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts +33 -16
  20. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts.map +1 -1
  21. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.js +124 -70
  22. package/dest/e2e_deploy_contract/deploy_test.d.ts +7 -6
  23. package/dest/e2e_deploy_contract/deploy_test.d.ts.map +1 -1
  24. package/dest/e2e_deploy_contract/deploy_test.js +20 -14
  25. package/dest/e2e_epochs/epochs_test.d.ts +49 -16
  26. package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
  27. package/dest/e2e_epochs/epochs_test.js +188 -64
  28. package/dest/e2e_fees/bridging_race.notest.d.ts +1 -1
  29. package/dest/e2e_fees/bridging_race.notest.js +5 -7
  30. package/dest/e2e_fees/fees_test.d.ts +25 -18
  31. package/dest/e2e_fees/fees_test.d.ts.map +1 -1
  32. package/dest/e2e_fees/fees_test.js +162 -141
  33. package/dest/e2e_l1_publisher/write_json.d.ts +4 -3
  34. package/dest/e2e_l1_publisher/write_json.d.ts.map +1 -1
  35. package/dest/e2e_l1_publisher/write_json.js +18 -19
  36. package/dest/e2e_multi_validator/utils.d.ts +1 -1
  37. package/dest/e2e_multi_validator/utils.js +1 -1
  38. package/dest/e2e_nested_contract/nested_contract_test.d.ts +7 -10
  39. package/dest/e2e_nested_contract/nested_contract_test.d.ts.map +1 -1
  40. package/dest/e2e_nested_contract/nested_contract_test.js +32 -40
  41. package/dest/e2e_p2p/inactivity_slash_test.d.ts +3 -3
  42. package/dest/e2e_p2p/inactivity_slash_test.d.ts.map +1 -1
  43. package/dest/e2e_p2p/inactivity_slash_test.js +11 -9
  44. package/dest/e2e_p2p/p2p_network.d.ts +237 -28
  45. package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
  46. package/dest/e2e_p2p/p2p_network.js +176 -129
  47. package/dest/e2e_p2p/reqresp/utils.d.ts +22 -0
  48. package/dest/e2e_p2p/reqresp/utils.d.ts.map +1 -0
  49. package/dest/e2e_p2p/reqresp/utils.js +206 -0
  50. package/dest/e2e_p2p/shared.d.ts +44 -15
  51. package/dest/e2e_p2p/shared.d.ts.map +1 -1
  52. package/dest/e2e_p2p/shared.js +102 -68
  53. package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.d.ts +2 -0
  54. package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.d.ts.map +1 -0
  55. package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.js +184 -0
  56. package/dest/e2e_storage_proof/fixtures/storage_proof_fixture.d.ts +18 -0
  57. package/dest/e2e_storage_proof/fixtures/storage_proof_fixture.d.ts.map +1 -0
  58. package/dest/e2e_storage_proof/fixtures/storage_proof_fixture.js +120 -0
  59. package/dest/e2e_token_contract/token_contract_test.d.ts +20 -11
  60. package/dest/e2e_token_contract/token_contract_test.d.ts.map +1 -1
  61. package/dest/e2e_token_contract/token_contract_test.js +103 -93
  62. package/dest/fixtures/authwit_proxy.d.ts +15 -0
  63. package/dest/fixtures/authwit_proxy.d.ts.map +1 -0
  64. package/dest/fixtures/authwit_proxy.js +34 -0
  65. package/dest/fixtures/e2e_prover_test.d.ts +19 -24
  66. package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
  67. package/dest/fixtures/e2e_prover_test.js +126 -145
  68. package/dest/fixtures/elu_monitor.d.ts +21 -0
  69. package/dest/fixtures/elu_monitor.d.ts.map +1 -0
  70. package/dest/fixtures/elu_monitor.js +102 -0
  71. package/dest/fixtures/fixtures.d.ts +75 -3
  72. package/dest/fixtures/fixtures.d.ts.map +1 -1
  73. package/dest/fixtures/fixtures.js +73 -3
  74. package/dest/fixtures/get_acvm_config.d.ts +1 -1
  75. package/dest/fixtures/get_acvm_config.js +1 -1
  76. package/dest/fixtures/get_bb_config.d.ts +1 -1
  77. package/dest/fixtures/get_bb_config.d.ts.map +1 -1
  78. package/dest/fixtures/get_bb_config.js +5 -5
  79. package/dest/fixtures/ha_setup.d.ts +71 -0
  80. package/dest/fixtures/ha_setup.d.ts.map +1 -0
  81. package/dest/fixtures/ha_setup.js +116 -0
  82. package/dest/fixtures/index.d.ts +2 -1
  83. package/dest/fixtures/index.d.ts.map +1 -1
  84. package/dest/fixtures/index.js +1 -0
  85. package/dest/fixtures/l1_to_l2_messaging.d.ts +4 -3
  86. package/dest/fixtures/l1_to_l2_messaging.d.ts.map +1 -1
  87. package/dest/fixtures/l1_to_l2_messaging.js +2 -2
  88. package/dest/fixtures/logging.d.ts +1 -1
  89. package/dest/fixtures/schnorr_hardcoded_account_contract.d.ts +25 -0
  90. package/dest/fixtures/schnorr_hardcoded_account_contract.d.ts.map +1 -0
  91. package/dest/fixtures/schnorr_hardcoded_account_contract.js +37 -0
  92. package/dest/fixtures/setup.d.ts +272 -0
  93. package/dest/fixtures/setup.d.ts.map +1 -0
  94. package/dest/fixtures/setup.js +735 -0
  95. package/dest/fixtures/setup_p2p_test.d.ts +22 -11
  96. package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
  97. package/dest/fixtures/setup_p2p_test.js +57 -38
  98. package/dest/fixtures/token_utils.d.ts +6 -3
  99. package/dest/fixtures/token_utils.d.ts.map +1 -1
  100. package/dest/fixtures/token_utils.js +13 -9
  101. package/dest/fixtures/utils.d.ts +5 -192
  102. package/dest/fixtures/utils.d.ts.map +1 -1
  103. package/dest/fixtures/utils.js +4 -648
  104. package/dest/fixtures/web3signer.d.ts +1 -1
  105. package/dest/fixtures/web3signer.js +1 -1
  106. package/dest/fixtures/with_telemetry_utils.d.ts +2 -2
  107. package/dest/fixtures/with_telemetry_utils.d.ts.map +1 -1
  108. package/dest/fixtures/with_telemetry_utils.js +2 -2
  109. package/dest/forward-compatibility/wallet_rpc_client.d.ts +7 -0
  110. package/dest/forward-compatibility/wallet_rpc_client.d.ts.map +1 -0
  111. package/dest/forward-compatibility/wallet_rpc_client.js +15 -0
  112. package/dest/forward-compatibility/wallet_service.d.ts +3 -0
  113. package/dest/forward-compatibility/wallet_service.d.ts.map +1 -0
  114. package/dest/forward-compatibility/wallet_service.js +109 -0
  115. package/dest/index.d.ts +1 -1
  116. package/dest/install_legacy_contracts.d.cts +10 -0
  117. package/dest/install_legacy_contracts.d.cts.map +1 -0
  118. package/dest/legacy-jest-resolver.d.cts +3 -0
  119. package/dest/legacy-jest-resolver.d.cts.map +1 -0
  120. package/dest/quality_of_service/grafana_client.d.ts +41 -0
  121. package/dest/quality_of_service/grafana_client.d.ts.map +1 -0
  122. package/dest/quality_of_service/{alert_checker.js → grafana_client.js} +1 -1
  123. package/dest/quality_of_service/prometheus_client.d.ts +38 -0
  124. package/dest/quality_of_service/prometheus_client.d.ts.map +1 -0
  125. package/dest/quality_of_service/prometheus_client.js +67 -0
  126. package/dest/shared/cross_chain_test_harness.d.ts +9 -6
  127. package/dest/shared/cross_chain_test_harness.d.ts.map +1 -1
  128. package/dest/shared/cross_chain_test_harness.js +34 -30
  129. package/dest/shared/gas_portal_test_harness.d.ts +9 -6
  130. package/dest/shared/gas_portal_test_harness.d.ts.map +1 -1
  131. package/dest/shared/gas_portal_test_harness.js +21 -12
  132. package/dest/shared/index.d.ts +3 -2
  133. package/dest/shared/index.d.ts.map +1 -1
  134. package/dest/shared/index.js +1 -0
  135. package/dest/shared/jest_setup.d.ts +1 -1
  136. package/dest/shared/jest_setup.js +41 -1
  137. package/dest/shared/mock_state_view.d.ts +86 -0
  138. package/dest/shared/mock_state_view.d.ts.map +1 -0
  139. package/dest/shared/mock_state_view.js +186 -0
  140. package/dest/shared/submit-transactions.d.ts +4 -4
  141. package/dest/shared/submit-transactions.d.ts.map +1 -1
  142. package/dest/shared/submit-transactions.js +9 -11
  143. package/dest/shared/uniswap_l1_l2.d.ts +3 -27
  144. package/dest/shared/uniswap_l1_l2.d.ts.map +1 -1
  145. package/dest/shared/uniswap_l1_l2.js +87 -50
  146. package/dest/shared/wait_for_l1_to_l2_message.d.ts +13 -0
  147. package/dest/shared/wait_for_l1_to_l2_message.d.ts.map +1 -0
  148. package/dest/shared/wait_for_l1_to_l2_message.js +10 -0
  149. package/dest/simulators/index.d.ts +1 -1
  150. package/dest/simulators/lending_simulator.d.ts +11 -4
  151. package/dest/simulators/lending_simulator.d.ts.map +1 -1
  152. package/dest/simulators/lending_simulator.js +32 -18
  153. package/dest/simulators/token_simulator.d.ts +1 -1
  154. package/dest/simulators/token_simulator.d.ts.map +1 -1
  155. package/dest/simulators/token_simulator.js +3 -24
  156. package/dest/spartan/setup_test_wallets.d.ts +18 -6
  157. package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
  158. package/dest/spartan/setup_test_wallets.js +159 -30
  159. package/dest/spartan/tx_metrics.d.ts +102 -0
  160. package/dest/spartan/tx_metrics.d.ts.map +1 -0
  161. package/dest/spartan/tx_metrics.js +475 -0
  162. package/dest/spartan/utils/bot.d.ts +28 -0
  163. package/dest/spartan/utils/bot.d.ts.map +1 -0
  164. package/dest/spartan/utils/bot.js +142 -0
  165. package/dest/spartan/utils/chaos.d.ts +79 -0
  166. package/dest/spartan/utils/chaos.d.ts.map +1 -0
  167. package/dest/spartan/utils/chaos.js +142 -0
  168. package/dest/spartan/utils/clients.d.ts +39 -0
  169. package/dest/spartan/utils/clients.d.ts.map +1 -0
  170. package/dest/spartan/utils/clients.js +90 -0
  171. package/dest/spartan/utils/config.d.ts +19 -0
  172. package/dest/spartan/utils/config.d.ts.map +1 -0
  173. package/dest/spartan/utils/config.js +23 -0
  174. package/dest/spartan/utils/health.d.ts +63 -0
  175. package/dest/spartan/utils/health.d.ts.map +1 -0
  176. package/dest/spartan/utils/health.js +202 -0
  177. package/dest/spartan/utils/helm.d.ts +15 -0
  178. package/dest/spartan/utils/helm.d.ts.map +1 -0
  179. package/dest/spartan/utils/helm.js +47 -0
  180. package/dest/spartan/utils/index.d.ts +11 -0
  181. package/dest/spartan/utils/index.d.ts.map +1 -0
  182. package/dest/spartan/utils/index.js +22 -0
  183. package/dest/spartan/utils/k8s.d.ts +128 -0
  184. package/dest/spartan/utils/k8s.d.ts.map +1 -0
  185. package/dest/spartan/utils/k8s.js +381 -0
  186. package/dest/spartan/utils/nodes.d.ts +40 -0
  187. package/dest/spartan/utils/nodes.d.ts.map +1 -0
  188. package/dest/spartan/utils/nodes.js +461 -0
  189. package/dest/spartan/utils/pod_logs.d.ts +25 -0
  190. package/dest/spartan/utils/pod_logs.d.ts.map +1 -0
  191. package/dest/spartan/utils/pod_logs.js +74 -0
  192. package/dest/spartan/utils/scripts.d.ts +30 -0
  193. package/dest/spartan/utils/scripts.d.ts.map +1 -0
  194. package/dest/spartan/utils/scripts.js +81 -0
  195. package/dest/spartan/utils.d.ts +2 -218
  196. package/dest/spartan/utils.d.ts.map +1 -1
  197. package/dest/spartan/utils.js +1 -749
  198. package/dest/test-wallet/test_wallet.d.ts +85 -0
  199. package/dest/test-wallet/test_wallet.d.ts.map +1 -0
  200. package/dest/test-wallet/test_wallet.js +273 -0
  201. package/dest/test-wallet/utils.d.ts +41 -0
  202. package/dest/test-wallet/utils.d.ts.map +1 -0
  203. package/dest/test-wallet/utils.js +66 -0
  204. package/dest/test-wallet/wallet_worker_script.d.ts +2 -0
  205. package/dest/test-wallet/wallet_worker_script.d.ts.map +1 -0
  206. package/dest/test-wallet/wallet_worker_script.js +53 -0
  207. package/dest/test-wallet/worker_wallet.d.ts +53 -0
  208. package/dest/test-wallet/worker_wallet.d.ts.map +1 -0
  209. package/dest/test-wallet/worker_wallet.js +155 -0
  210. package/dest/test-wallet/worker_wallet_schema.d.ts +160 -0
  211. package/dest/test-wallet/worker_wallet_schema.d.ts.map +1 -0
  212. package/dest/test-wallet/worker_wallet_schema.js +22 -0
  213. package/package.json +56 -46
  214. package/src/bench/client_flows/benchmark.ts +43 -2
  215. package/src/bench/client_flows/client_flows_benchmark.ts +203 -206
  216. package/src/bench/client_flows/config.ts +9 -1
  217. package/src/bench/client_flows/data_extractor.ts +6 -28
  218. package/src/bench/utils.ts +38 -22
  219. package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +141 -152
  220. package/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +180 -127
  221. package/src/e2e_deploy_contract/deploy_test.ts +25 -17
  222. package/src/e2e_epochs/epochs_test.ts +254 -116
  223. package/src/e2e_fees/bridging_race.notest.ts +6 -12
  224. package/src/e2e_fees/fees_test.ts +215 -229
  225. package/src/e2e_l1_publisher/write_json.ts +20 -19
  226. package/src/e2e_multi_validator/utils.ts +1 -1
  227. package/src/e2e_nested_contract/nested_contract_test.ts +38 -56
  228. package/src/e2e_p2p/inactivity_slash_test.ts +12 -10
  229. package/src/e2e_p2p/p2p_network.ts +246 -201
  230. package/src/e2e_p2p/reqresp/utils.ts +274 -0
  231. package/src/e2e_p2p/shared.ts +132 -82
  232. package/src/e2e_storage_proof/fixtures/storage_proof.json +915 -0
  233. package/src/e2e_storage_proof/fixtures/storage_proof_fetcher.ts +190 -0
  234. package/src/e2e_storage_proof/fixtures/storage_proof_fixture.ts +173 -0
  235. package/src/e2e_token_contract/token_contract_test.ts +129 -117
  236. package/src/fixtures/authwit_proxy.ts +54 -0
  237. package/src/fixtures/dumps/epoch_proof_result.json +1 -1
  238. package/src/fixtures/e2e_prover_test.ts +154 -199
  239. package/src/fixtures/elu_monitor.ts +126 -0
  240. package/src/fixtures/fixtures.ts +95 -5
  241. package/src/fixtures/get_acvm_config.ts +1 -1
  242. package/src/fixtures/get_bb_config.ts +7 -6
  243. package/src/fixtures/ha_setup.ts +188 -0
  244. package/src/fixtures/index.ts +1 -0
  245. package/src/fixtures/l1_to_l2_messaging.ts +4 -2
  246. package/src/fixtures/schnorr_hardcoded_account_contract.ts +49 -0
  247. package/src/fixtures/setup.ts +1056 -0
  248. package/src/fixtures/setup_p2p_test.ts +70 -56
  249. package/src/fixtures/token_utils.ts +9 -8
  250. package/src/fixtures/utils.ts +29 -947
  251. package/src/fixtures/web3signer.ts +1 -1
  252. package/src/fixtures/with_telemetry_utils.ts +2 -2
  253. package/src/forward-compatibility/wallet_rpc_client.ts +14 -0
  254. package/src/forward-compatibility/wallet_service.ts +104 -0
  255. package/src/guides/up_quick_start.sh +4 -6
  256. package/src/install_legacy_contracts.cjs +75 -0
  257. package/src/legacy-jest-resolver.cjs +112 -0
  258. package/src/quality_of_service/{alert_checker.ts → grafana_client.ts} +1 -1
  259. package/src/quality_of_service/prometheus_client.ts +113 -0
  260. package/src/shared/cross_chain_test_harness.ts +37 -40
  261. package/src/shared/gas_portal_test_harness.ts +24 -14
  262. package/src/shared/index.ts +2 -1
  263. package/src/shared/jest_setup.ts +51 -1
  264. package/src/shared/mock_state_view.ts +188 -0
  265. package/src/shared/submit-transactions.ts +11 -16
  266. package/src/shared/uniswap_l1_l2.ts +142 -114
  267. package/src/shared/wait_for_l1_to_l2_message.ts +23 -0
  268. package/src/simulators/lending_simulator.ts +39 -19
  269. package/src/simulators/token_simulator.ts +6 -30
  270. package/src/spartan/DEVELOP.md +7 -0
  271. package/src/spartan/setup_test_wallets.ts +234 -32
  272. package/src/spartan/tx_metrics.ts +434 -0
  273. package/src/spartan/utils/bot.ts +188 -0
  274. package/src/spartan/utils/chaos.ts +253 -0
  275. package/src/spartan/utils/clients.ts +100 -0
  276. package/src/spartan/utils/config.ts +29 -0
  277. package/src/spartan/utils/health.ts +255 -0
  278. package/src/spartan/utils/helm.ts +84 -0
  279. package/src/spartan/utils/index.ts +71 -0
  280. package/src/spartan/utils/k8s.ts +535 -0
  281. package/src/spartan/utils/nodes.ts +543 -0
  282. package/src/spartan/utils/pod_logs.ts +99 -0
  283. package/src/spartan/utils/scripts.ts +99 -0
  284. package/src/spartan/utils.ts +1 -942
  285. package/src/test-wallet/test_wallet.ts +376 -0
  286. package/src/test-wallet/utils.ts +108 -0
  287. package/src/test-wallet/wallet_worker_script.ts +63 -0
  288. package/src/test-wallet/worker_wallet.ts +218 -0
  289. package/src/test-wallet/worker_wallet_schema.ts +13 -0
  290. package/dest/fixtures/setup_l1_contracts.d.ts +0 -6
  291. package/dest/fixtures/setup_l1_contracts.d.ts.map +0 -1
  292. package/dest/fixtures/setup_l1_contracts.js +0 -17
  293. package/dest/fixtures/snapshot_manager.d.ts +0 -95
  294. package/dest/fixtures/snapshot_manager.d.ts.map +0 -1
  295. package/dest/fixtures/snapshot_manager.js +0 -505
  296. package/dest/quality_of_service/alert_checker.d.ts +0 -41
  297. package/dest/quality_of_service/alert_checker.d.ts.map +0 -1
  298. package/src/fixtures/setup_l1_contracts.ts +0 -26
  299. package/src/fixtures/snapshot_manager.ts +0 -665
@@ -1,4 +1,7 @@
1
+ import type { InitialAccountData } from '@aztec/accounts/testing';
2
+ import type { Archiver } from '@aztec/archiver';
1
3
  import { type AztecNodeConfig, AztecNodeService } from '@aztec/aztec-node';
4
+ import { getAccountContractAddress } from '@aztec/aztec.js/account';
2
5
  import { getTimestampRangeForEpoch } from '@aztec/aztec.js/block';
3
6
  import { getContractInstanceFromInstantiationParams } from '@aztec/aztec.js/contracts';
4
7
  import { Fr } from '@aztec/aztec.js/fields';
@@ -6,33 +9,37 @@ import type { Logger } from '@aztec/aztec.js/log';
6
9
  import { MerkleTreeId } from '@aztec/aztec.js/trees';
7
10
  import type { Wallet } from '@aztec/aztec.js/wallet';
8
11
  import { EpochCache } from '@aztec/epoch-cache';
9
- import { DefaultL1ContractsConfig, type ExtendedViemWalletClient, createExtendedL1Client } from '@aztec/ethereum';
12
+ import { createExtendedL1Client } from '@aztec/ethereum/client';
13
+ import { DefaultL1ContractsConfig } from '@aztec/ethereum/config';
10
14
  import { RollupContract } from '@aztec/ethereum/contracts';
11
- import { ChainMonitor, DelayedTxUtils, type Delayer, waitUntilL1Timestamp, withDelayer } from '@aztec/ethereum/test';
15
+ import { Delayer, createDelayer, waitUntilL1Timestamp, wrapClientWithDelayer } from '@aztec/ethereum/l1-tx-utils';
16
+ import { ChainMonitor } from '@aztec/ethereum/test';
17
+ import type { ExtendedViemWalletClient } from '@aztec/ethereum/types';
18
+ import { BlockNumber, CheckpointNumber, EpochNumber } from '@aztec/foundation/branded-types';
12
19
  import { SecretValue } from '@aztec/foundation/config';
13
- import { randomBytes } from '@aztec/foundation/crypto';
14
- import { withLogNameSuffix } from '@aztec/foundation/log';
20
+ import { randomBytes } from '@aztec/foundation/crypto/random';
21
+ import { withLoggerBindings } from '@aztec/foundation/log/server';
15
22
  import { retryUntil } from '@aztec/foundation/retry';
16
23
  import { sleep } from '@aztec/foundation/sleep';
17
24
  import { SpamContract } from '@aztec/noir-test-contracts.js/Spam';
25
+ import { TestContract } from '@aztec/noir-test-contracts.js/Test';
18
26
  import { getMockPubSubP2PServiceFactory } from '@aztec/p2p/test-helpers';
19
- import { ProverNode, type ProverNodeConfig, ProverNodePublisher } from '@aztec/prover-node';
20
- import type { TestProverNode } from '@aztec/prover-node/test';
21
- import {
22
- type SequencerClient,
23
- type SequencerEvents,
24
- type SequencerPublisher,
25
- SequencerState,
26
- } from '@aztec/sequencer-client';
27
- import type { TestSequencerClient } from '@aztec/sequencer-client/test';
28
- import { EthAddress, type L2BlockNumber } from '@aztec/stdlib/block';
27
+ import type { ProverNodeConfig } from '@aztec/prover-node';
28
+ import type { PXEConfig } from '@aztec/pxe/config';
29
+ import { type SequencerClient, type SequencerEvents, SequencerState } from '@aztec/sequencer-client';
30
+ import { type BlockParameter, EthAddress } from '@aztec/stdlib/block';
29
31
  import { type L1RollupConstants, getProofSubmissionDeadlineTimestamp } from '@aztec/stdlib/epoch-helpers';
30
32
  import { tryStop } from '@aztec/stdlib/interfaces/server';
33
+ import type { SlashingProtectionDatabase } from '@aztec/validator-ha-signer/types';
31
34
 
32
35
  import { join } from 'path';
33
36
  import type { Hex } from 'viem';
34
37
  import { privateKeyToAccount } from 'viem/accounts';
35
38
 
39
+ import {
40
+ SCHNORR_HARDCODED_PRIVATE_KEY,
41
+ SchnorrHardcodedKeyAccountContract,
42
+ } from '../fixtures/schnorr_hardcoded_account_contract.js';
36
43
  import {
37
44
  type EndToEndContext,
38
45
  type SetupOptions,
@@ -40,13 +47,25 @@ import {
40
47
  getPrivateKeyFromIndex,
41
48
  setup,
42
49
  } from '../fixtures/utils.js';
50
+ import type { TestWallet } from '../test-wallet/test_wallet.js';
43
51
 
44
- export const WORLD_STATE_BLOCK_HISTORY = 2;
52
+ export const WORLD_STATE_CHECKPOINT_HISTORY = 2;
45
53
  export const WORLD_STATE_BLOCK_CHECK_INTERVAL = 50;
46
54
  export const ARCHIVER_POLL_INTERVAL = 50;
47
55
  export const DEFAULT_L1_BLOCK_TIME = process.env.CI ? 12 : 8;
48
56
 
49
- export type EpochsTestOpts = Partial<SetupOptions> & { numberOfAccounts?: number };
57
+ export type EpochsTestOpts = Partial<SetupOptions> & {
58
+ numberOfAccounts?: number;
59
+ pxeOpts?: Partial<PXEConfig>;
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;
68
+ };
50
69
 
51
70
  export type TrackedSequencerEvent = {
52
71
  [K in keyof SequencerEvents]: Parameters<SequencerEvents[K]>[0] & {
@@ -72,7 +91,7 @@ export class EpochsTestContext {
72
91
  public proverDelayer!: Delayer;
73
92
  public sequencerDelayer!: Delayer;
74
93
 
75
- public proverNodes: ProverNode[] = [];
94
+ public proverNodes: AztecNodeService[] = [];
76
95
  public nodes: AztecNodeService[] = [];
77
96
 
78
97
  public epochDuration!: number;
@@ -91,48 +110,78 @@ export class EpochsTestContext {
91
110
  ? parseInt(process.env.L1_BLOCK_TIME)
92
111
  : DEFAULT_L1_BLOCK_TIME;
93
112
  const ethereumSlotDuration = opts.ethereumSlotDuration ?? envEthereumSlotDuration;
94
- const aztecSlotDuration = opts.aztecSlotDuration ?? ethereumSlotDuration * 2;
113
+ const aztecSlotDuration = opts.aztecSlotDuration ?? (opts.aztecSlotDurationInL1Slots ?? 2) * ethereumSlotDuration;
95
114
  const aztecEpochDuration = opts.aztecEpochDuration ?? 6;
96
115
  const aztecProofSubmissionEpochs = opts.aztecProofSubmissionEpochs ?? 1;
97
- return { ethereumSlotDuration, aztecSlotDuration, aztecEpochDuration, aztecProofSubmissionEpochs };
116
+ const l1PublishingTime = opts.l1PublishingTime ?? 1;
117
+ return {
118
+ l1PublishingTime,
119
+ ethereumSlotDuration,
120
+ aztecSlotDuration,
121
+ aztecEpochDuration,
122
+ aztecProofSubmissionEpochs,
123
+ };
98
124
  }
99
125
 
100
126
  public async setup(opts: EpochsTestOpts = {}) {
101
- const { ethereumSlotDuration, aztecSlotDuration, aztecEpochDuration, aztecProofSubmissionEpochs } =
102
- EpochsTestContext.getSlotDurations(opts);
127
+ const {
128
+ ethereumSlotDuration,
129
+ aztecSlotDuration,
130
+ aztecEpochDuration,
131
+ aztecProofSubmissionEpochs,
132
+ l1PublishingTime,
133
+ } = EpochsTestContext.getSlotDurations(opts);
103
134
 
104
135
  this.L1_BLOCK_TIME_IN_S = ethereumSlotDuration;
105
136
  this.L2_SLOT_DURATION_IN_S = aztecSlotDuration;
106
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
+
107
148
  // Set up system without any account nor protocol contracts
108
149
  // and with faster block times and shorter epochs.
109
- const context = await setup(opts.numberOfAccounts ?? 0, {
110
- automineL1Setup: true,
111
- checkIntervalMs: 50,
112
- archiverPollingIntervalMS: ARCHIVER_POLL_INTERVAL,
113
- worldStateBlockCheckIntervalMS: WORLD_STATE_BLOCK_CHECK_INTERVAL,
114
- skipProtocolContracts: true,
115
- salt: 1,
116
- aztecEpochDuration,
117
- aztecSlotDuration,
118
- ethereumSlotDuration,
119
- aztecProofSubmissionEpochs,
120
- aztecTargetCommitteeSize: opts.initialValidators?.length ?? 0,
121
- minTxsPerBlock: 0,
122
- realProofs: false,
123
- startProverNode: true,
124
- proverTestDelayMs: opts.proverTestDelayMs ?? 0,
125
- // We use numeric incremental prover ids for simplicity, but we can switch to
126
- // using the prover's eth address if the proverId is used for something in the rollup contract
127
- // Use numeric EthAddress for deterministic prover id
128
- proverId: EthAddress.fromNumber(1),
129
- worldStateBlockHistory: WORLD_STATE_BLOCK_HISTORY,
130
- exitDelaySeconds: DefaultL1ContractsConfig.exitDelaySeconds,
131
- slasherFlavor: 'none',
132
- ...opts,
133
- });
150
+ const context = await setup(
151
+ useHardcodedAccount ? 0 : (opts.numberOfAccounts ?? 0),
152
+ {
153
+ automineL1Setup: true,
154
+ checkIntervalMs: 50,
155
+ archiverPollingIntervalMS: ARCHIVER_POLL_INTERVAL,
156
+ worldStateBlockCheckIntervalMS: WORLD_STATE_BLOCK_CHECK_INTERVAL,
157
+ aztecEpochDuration,
158
+ aztecSlotDuration,
159
+ ethereumSlotDuration,
160
+ aztecProofSubmissionEpochs,
161
+ aztecTargetCommitteeSize: opts.initialValidators?.length ?? 0,
162
+ minTxsPerBlock: 0,
163
+ realProofs: false,
164
+ startProverNode: true,
165
+ proverTestDelayMs: opts.proverTestDelayMs ?? 0,
166
+ proverId: EthAddress.fromNumber(1),
167
+ worldStateCheckpointHistory: WORLD_STATE_CHECKPOINT_HISTORY,
168
+ exitDelaySeconds: DefaultL1ContractsConfig.exitDelaySeconds,
169
+ slasherEnabled: false,
170
+ l1PublishingTime,
171
+ ...opts,
172
+ ...(hardcodedAccountData ? { initialFundedAccounts: [hardcodedAccountData], numberOfAccounts: 0 } : {}),
173
+ },
174
+ // Use checkpointed chain tip for PXE by default to avoid issues with blocks being dropped due to pruned anchor blocks.
175
+ // Can be overridden via opts.pxeOpts.
176
+ { syncChainTip: 'checkpointed', ...opts.pxeOpts },
177
+ );
134
178
 
135
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
+ }
136
185
  this.proverNodes = context.proverNode ? [context.proverNode] : [];
137
186
  this.nodes = context.aztecNode ? [context.aztecNode as AztecNodeService] : [];
138
187
  this.logger = context.logger;
@@ -143,17 +192,8 @@ export class EpochsTestContext {
143
192
  // Loop that tracks L1 and L2 block numbers and logs whenever there's a new one.
144
193
  this.monitor = new ChainMonitor(this.rollup, context.dateProvider, this.logger).start();
145
194
 
146
- // This is hideous.
147
- // We ought to have a definite reference to the l1TxUtils that we're using in both places, provided by the test context.
148
- this.proverDelayer = context.proverNode
149
- ? (((context.proverNode as TestProverNode).publisher as ProverNodePublisher).l1TxUtils as DelayedTxUtils).delayer!
150
- : undefined!;
151
- this.sequencerDelayer = context.sequencer
152
- ? (
153
- ((context.sequencer as TestSequencerClient).sequencer.publisher as SequencerPublisher)
154
- .l1TxUtils as DelayedTxUtils
155
- ).delayer!
156
- : undefined!;
195
+ this.proverDelayer = context.proverDelayer!;
196
+ this.sequencerDelayer = context.sequencerDelayer!;
157
197
 
158
198
  if ((context.proverNode && !this.proverDelayer) || (context.sequencer && !this.sequencerDelayer)) {
159
199
  throw new Error(`Could not find prover or sequencer delayer`);
@@ -168,6 +208,8 @@ export class EpochsTestContext {
168
208
  l1GenesisTime: await this.rollup.getL1GenesisTime(),
169
209
  ethereumSlotDuration,
170
210
  proofSubmissionEpochs: Number(await this.rollup.getProofSubmissionEpochs()),
211
+ targetCommitteeSize: await this.rollup.getTargetCommitteeSize(),
212
+ rollupManaLimit: Number(await this.rollup.getManaLimit()),
171
213
  };
172
214
 
173
215
  this.logger.info(
@@ -182,23 +224,64 @@ export class EpochsTestContext {
182
224
  await this.context.teardown();
183
225
  }
184
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
+
185
256
  public async createProverNode(opts: { dontStart?: boolean } & Partial<ProverNodeConfig> = {}) {
186
257
  this.logger.warn('Creating and syncing a simulated prover node...');
187
258
  const proverNodePrivateKey = this.getNextPrivateKey();
188
- const suffix = (this.proverNodes.length + 1).toString();
189
- const proverNode = await withLogNameSuffix(suffix, () =>
259
+ const proverIndex = this.proverNodes.length + 1;
260
+ const { mockGossipSubNetwork } = this.context;
261
+ const { proverNode } = await withLoggerBindings({ actor: `prover-${proverIndex}` }, () =>
190
262
  createAndSyncProverNode(
191
263
  proverNodePrivateKey,
192
- { ...this.context.config },
193
264
  {
194
- dataDirectory: join(this.context.config.dataDirectory!, randomBytes(8).toString('hex')),
195
- proverId: EthAddress.fromNumber(parseInt(suffix, 10)),
265
+ ...this.context.config,
266
+ p2pEnabled: this.context.config.p2pEnabled || mockGossipSubNetwork !== undefined,
267
+ proverId: EthAddress.fromNumber(proverIndex),
196
268
  dontStart: opts.dontStart,
197
269
  ...opts,
198
270
  },
199
- this.context.aztecNode,
200
- undefined,
201
- { dateProvider: this.context.dateProvider },
271
+ {
272
+ dataDirectory: join(this.context.config.dataDirectory!, randomBytes(8).toString('hex')),
273
+ },
274
+ {
275
+ dateProvider: this.context.dateProvider,
276
+ p2pClientDeps: {
277
+ p2pServiceFactory: mockGossipSubNetwork ? getMockPubSubP2PServiceFactory(mockGossipSubNetwork) : undefined,
278
+ rpcTxProviders: [this.context.aztecNode],
279
+ },
280
+ },
281
+ {
282
+ genesis: this.context.genesis,
283
+ dontStart: opts.dontStart,
284
+ },
202
285
  ),
203
286
  );
204
287
  this.proverNodes.push(proverNode);
@@ -212,26 +295,34 @@ export class EpochsTestContext {
212
295
 
213
296
  public createValidatorNode(
214
297
  privateKeys: `0x${string}`[],
215
- opts: Partial<AztecNodeConfig> & { txDelayerMaxInclusionTimeIntoSlot?: number; dontStartSequencer?: boolean } = {},
298
+ opts: Partial<AztecNodeConfig> & {
299
+ dontStartSequencer?: boolean;
300
+ slashingProtectionDb?: SlashingProtectionDatabase;
301
+ } = {},
216
302
  ) {
217
303
  this.logger.warn('Creating and syncing a validator node...');
218
304
  return this.createNode({ ...opts, disableValidator: false, validatorPrivateKeys: new SecretValue(privateKeys) });
219
305
  }
220
306
 
221
307
  private async createNode(
222
- opts: Partial<AztecNodeConfig> & { txDelayerMaxInclusionTimeIntoSlot?: number; dontStartSequencer?: boolean } = {},
308
+ opts: Partial<AztecNodeConfig> & {
309
+ dontStartSequencer?: boolean;
310
+ slashingProtectionDb?: SlashingProtectionDatabase;
311
+ } = {},
223
312
  ) {
224
- const suffix = (this.nodes.length + 1).toString();
313
+ const nodeIndex = this.nodes.length + 1;
314
+ const actorPrefix = opts.disableValidator ? 'node' : 'validator';
225
315
  const { mockGossipSubNetwork } = this.context;
226
316
  const resolvedConfig = { ...this.context.config, ...opts };
227
317
  const p2pEnabled = resolvedConfig.p2pEnabled || mockGossipSubNetwork !== undefined;
228
318
  const p2pIp = resolvedConfig.p2pIp ?? (p2pEnabled ? '127.0.0.1' : undefined);
229
- const node = await withLogNameSuffix(suffix, () =>
319
+ const node = await withLoggerBindings({ actor: `${actorPrefix}-${nodeIndex}` }, () =>
230
320
  AztecNodeService.createAndSync(
231
321
  {
232
322
  ...resolvedConfig,
233
323
  dataDirectory: join(this.context.config.dataDirectory!, randomBytes(8).toString('hex')),
234
324
  validatorPrivateKeys: opts.validatorPrivateKeys ?? new SecretValue([]),
325
+ nodeId: resolvedConfig.nodeId || `${actorPrefix}-${nodeIndex}`,
235
326
  p2pEnabled,
236
327
  p2pIp,
237
328
  },
@@ -240,34 +331,15 @@ export class EpochsTestContext {
240
331
  p2pClientDeps: {
241
332
  p2pServiceFactory: mockGossipSubNetwork ? getMockPubSubP2PServiceFactory(mockGossipSubNetwork) : undefined,
242
333
  },
334
+ slashingProtectionDb: opts.slashingProtectionDb,
243
335
  },
244
336
  {
245
- prefilledPublicData: this.context.prefilledPublicData,
337
+ genesis: this.context.genesis,
246
338
  ...opts,
247
339
  },
248
340
  ),
249
341
  );
250
342
 
251
- // REFACTOR: We're getting too much into the internals of the sequencer here.
252
- // We should have a single method for constructing an aztec node that returns a TestAztecNodeService
253
- // which directly exposes the delayer and sets any test config.
254
- if (opts.txDelayerMaxInclusionTimeIntoSlot !== undefined) {
255
- this.logger.info(
256
- `Setting tx delayer max inclusion time into slot to ${opts.txDelayerMaxInclusionTimeIntoSlot} seconds`,
257
- );
258
- // Here we reach into the sequencer and hook in a tx delayer. The problem is that the sequencer's l1 utils only uses a public client, not a wallet.
259
- // The delayer needs a wallet (a client that can sign), so we have to create one here.
260
- const l1Client = createExtendedL1Client(
261
- resolvedConfig.l1RpcUrls!,
262
- resolvedConfig.publisherPrivateKeys![0]!.getValue(),
263
- );
264
- const sequencer = node.getSequencer() as TestSequencerClient;
265
- const publisher = sequencer.sequencer.publisher;
266
- const delayed = DelayedTxUtils.fromL1TxUtils(publisher.l1TxUtils, this.L1_BLOCK_TIME_IN_S, l1Client);
267
- delayed.delayer!.setMaxInclusionTimeIntoSlot(opts.txDelayerMaxInclusionTimeIntoSlot);
268
- publisher.l1TxUtils = delayed;
269
- }
270
-
271
343
  this.nodes.push(node);
272
344
  return node;
273
345
  }
@@ -279,7 +351,7 @@ export class EpochsTestContext {
279
351
 
280
352
  /** Waits until the epoch begins (ie until the immediately previous L1 block is mined). */
281
353
  public async waitUntilEpochStarts(epoch: number) {
282
- const [start] = getTimestampRangeForEpoch(BigInt(epoch), this.constants);
354
+ const [start] = getTimestampRangeForEpoch(EpochNumber(epoch), this.constants);
283
355
  this.logger.info(`Waiting until L1 timestamp ${start} is reached as the start of epoch ${epoch}`);
284
356
  await waitUntilL1Timestamp(
285
357
  this.l1Client,
@@ -290,51 +362,54 @@ export class EpochsTestContext {
290
362
  return start;
291
363
  }
292
364
 
293
- /** Waits until the given L2 block number is mined. */
294
- public async waitUntilL2BlockNumber(target: number, timeout = 60) {
365
+ /** Waits until the given checkpoint number is mined. */
366
+ public async waitUntilCheckpointNumber(target: CheckpointNumber, timeout = 120) {
295
367
  await retryUntil(
296
- () => Promise.resolve(target <= this.monitor.l2BlockNumber),
297
- `Wait until L2 block ${target}`,
368
+ () => Promise.resolve(target <= this.monitor.checkpointNumber),
369
+ `Wait until checkpoint ${target}`,
298
370
  timeout,
299
371
  0.1,
300
372
  );
301
373
  }
302
374
 
303
- /** Waits until the given L2 block number is marked as proven. */
304
- public async waitUntilProvenL2BlockNumber(t: number, timeout = 60) {
375
+ /** Waits until the given checkpoint number is marked as proven. */
376
+ public async waitUntilProvenCheckpointNumber(target: CheckpointNumber, timeout = 120) {
305
377
  await retryUntil(
306
- () => Promise.resolve(t <= this.monitor.l2ProvenBlockNumber),
307
- `Wait proven L2 block ${t}`,
378
+ () => Promise.resolve(target <= this.monitor.provenCheckpointNumber),
379
+ `Wait proven checkpoint ${target}`,
308
380
  timeout,
309
381
  0.1,
310
382
  );
311
- return this.monitor.l2ProvenBlockNumber;
383
+ return this.monitor.provenCheckpointNumber;
312
384
  }
313
385
 
314
386
  /** Waits until the last slot of the proof submission window for a given epoch. */
315
387
  public async waitUntilLastSlotOfProofSubmissionWindow(epochNumber: number | bigint) {
316
- const deadline = getProofSubmissionDeadlineTimestamp(BigInt(epochNumber), this.constants);
388
+ const deadline = getProofSubmissionDeadlineTimestamp(EpochNumber.fromBigInt(BigInt(epochNumber)), this.constants);
317
389
  const oneSlotBefore = deadline - BigInt(this.constants.slotDuration);
318
390
  const date = new Date(Number(oneSlotBefore) * 1000);
319
391
  this.logger.info(`Waiting until last slot of submission window for epoch ${epochNumber} at ${date}`, {
320
392
  oneSlotBefore,
321
393
  });
322
- await waitUntilL1Timestamp(this.l1Client, oneSlotBefore);
394
+ // Use a timeout that accounts for the full proof submission window
395
+ const proofSubmissionWindowDuration =
396
+ this.constants.proofSubmissionEpochs * this.epochDuration * this.L2_SLOT_DURATION_IN_S;
397
+ await waitUntilL1Timestamp(this.l1Client, oneSlotBefore, undefined, proofSubmissionWindowDuration * 2);
323
398
  }
324
399
 
325
400
  /** Waits for the aztec node to sync to the target block number. */
326
- public async waitForNodeToSync(blockNumber: number, type: 'proven' | 'finalized' | 'historic') {
401
+ public async waitForNodeToSync(blockNumber: BlockNumber, type: 'proven' | 'finalized' | 'historic') {
327
402
  const waitTime = ARCHIVER_POLL_INTERVAL + WORLD_STATE_BLOCK_CHECK_INTERVAL;
328
403
  let synched = false;
329
404
  while (!synched) {
330
405
  await sleep(waitTime);
331
406
  const [syncState, tips] = await Promise.all([
332
407
  this.context.aztecNode.getWorldStateSyncStatus(),
333
- await this.context.aztecNode.getL2Tips(),
408
+ await this.context.aztecNode.getChainTips(),
334
409
  ]);
335
410
  this.logger.info(`Wait for node synch ${blockNumber} ${type}`, { blockNumber, type, syncState, tips });
336
411
  if (type === 'proven') {
337
- synched = tips.proven.number >= blockNumber && syncState.latestBlockNumber >= blockNumber;
412
+ synched = tips.proven.block.number >= blockNumber && syncState.latestBlockNumber >= blockNumber;
338
413
  } else if (type === 'finalized') {
339
414
  synched = syncState.finalizedBlockNumber >= blockNumber;
340
415
  } else {
@@ -356,23 +431,34 @@ export class EpochsTestContext {
356
431
  return SpamContract.at(instance.address, wallet);
357
432
  }
358
433
 
434
+ /** Registers the TestContract on the given wallet. */
435
+ public async registerTestContract(wallet: Wallet, salt = Fr.ZERO) {
436
+ const instance = await getContractInstanceFromInstantiationParams(TestContract.artifact, {
437
+ constructorArgs: [],
438
+ constructorArtifact: undefined,
439
+ salt,
440
+ publicKeys: undefined,
441
+ deployer: undefined,
442
+ });
443
+ await wallet.registerContract(instance, TestContract.artifact);
444
+ return TestContract.at(instance.address, wallet);
445
+ }
446
+
359
447
  /** Creates an L1 client using a fresh account with funds from anvil, with a tx delayer already set up. */
360
448
  public async createL1Client() {
361
- const { client, delayer } = withDelayer(
362
- createExtendedL1Client(
363
- [...this.l1Client.chain.rpcUrls.default.http],
364
- privateKeyToAccount(this.getNextPrivateKey()),
365
- this.l1Client.chain,
366
- ),
367
- this.context.dateProvider!,
368
- { ethereumSlotDuration: this.L1_BLOCK_TIME_IN_S },
449
+ const rawClient = createExtendedL1Client(
450
+ [...this.l1Client.chain.rpcUrls.default.http],
451
+ privateKeyToAccount(this.getNextPrivateKey()),
452
+ this.l1Client.chain,
369
453
  );
454
+ const delayer = createDelayer(this.context.dateProvider, { ethereumSlotDuration: this.L1_BLOCK_TIME_IN_S }, {});
455
+ const client = wrapClientWithDelayer(rawClient, delayer);
370
456
  expect(await client.getBalance({ address: client.account.address })).toBeGreaterThan(0n);
371
457
  return { client, delayer };
372
458
  }
373
459
 
374
460
  /** Verifies whether the given block number is found on the aztec node. */
375
- public async verifyHistoricBlock(blockNumber: L2BlockNumber, expectedSuccess: boolean) {
461
+ public async verifyHistoricBlock(blockNumber: BlockParameter, expectedSuccess: boolean) {
376
462
  // We use `findLeavesIndexes` here, but could use any function that queries the world-state
377
463
  // at a particular block, so we know whether that historic block is available or has been
378
464
  // pruned. Note that `getBlock` would not work here, since it only hits the archiver.
@@ -383,19 +469,57 @@ export class EpochsTestContext {
383
469
  expect(result).toBe(expectedSuccess);
384
470
  }
385
471
 
472
+ /** Verifies at least one checkpoint has the target number of blocks (for MBPS validation). */
473
+ public async assertMultipleBlocksPerSlot(targetBlockCount: number) {
474
+ const archiver = (this.context.aztecNode as AztecNodeService).getBlockSource() as Archiver;
475
+ const checkpoints = await archiver.getCheckpoints({ from: CheckpointNumber(1), limit: 50 });
476
+
477
+ this.logger.warn(`Retrieved ${checkpoints.length} checkpoints from archiver`, {
478
+ checkpoints: checkpoints.map(pc => pc.checkpoint.getStats()),
479
+ });
480
+
481
+ let expectedBlockNumber = checkpoints[0].checkpoint.blocks[0].number;
482
+ let targetFound = false;
483
+
484
+ for (const checkpoint of checkpoints) {
485
+ const blockCount = checkpoint.checkpoint.blocks.length;
486
+ targetFound = targetFound || blockCount >= targetBlockCount;
487
+
488
+ this.logger.verbose(`Checkpoint ${checkpoint.checkpoint.number} has ${blockCount} blocks`, {
489
+ checkpoint: checkpoint.checkpoint.getStats(),
490
+ });
491
+
492
+ for (let i = 0; i < blockCount; i++) {
493
+ const block = checkpoint.checkpoint.blocks[i];
494
+ expect(block.indexWithinCheckpoint).toBe(i);
495
+ expect(block.checkpointNumber).toBe(checkpoint.checkpoint.number);
496
+ expect(block.number).toBe(expectedBlockNumber);
497
+ expectedBlockNumber++;
498
+ }
499
+ }
500
+
501
+ expect(targetFound).toBe(true);
502
+ }
503
+
386
504
  public watchSequencerEvents(
387
505
  sequencers: SequencerClient[],
388
506
  getMetadata: (i: number) => Record<string, any> = () => ({}),
507
+ additionalFailEventKeys: (keyof SequencerEvents)[] = [],
389
508
  ) {
390
509
  const stateChanges: TrackedSequencerEvent[] = [];
391
510
  const failEvents: TrackedSequencerEvent[] = [];
392
511
 
393
- // Note we do not include the 'tx-count-check-failed' event here, since it is fine if we dont build
512
+ // Note we do not include the 'block-tx-count-check-failed' event here, since it is fine if we dont build
394
513
  // due to lack of txs available.
395
514
  const failEventsKeys: (keyof SequencerEvents)[] = [
396
515
  'block-build-failed',
397
- 'block-publish-failed',
516
+ 'checkpoint-publish-failed',
398
517
  'proposer-rollup-check-failed',
518
+ 'checkpoint-error',
519
+ 'checkpoint-publish-failed',
520
+ 'header-validation-failed',
521
+ 'pipelined-checkpoint-discarded',
522
+ ...additionalFailEventKeys,
399
523
  ];
400
524
 
401
525
  const makeEvent = (
@@ -425,6 +549,13 @@ export class EpochsTestContext {
425
549
  });
426
550
  failEventsKeys.forEach(eventName => {
427
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
+ }
428
559
  const evt = makeEvent(i, eventName, args);
429
560
  failEvents.push(evt);
430
561
  this.logger.error(`Failed event ${eventName} from sequencer ${sequencerIndex}`, undefined, evt);
@@ -434,4 +565,11 @@ export class EpochsTestContext {
434
565
 
435
566
  return { failEvents, stateChanges };
436
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
+ }
437
575
  }
@@ -1,14 +1,14 @@
1
1
  import { SchnorrAccountContract } from '@aztec/accounts/schnorr';
2
2
  import { Fr } from '@aztec/aztec.js/fields';
3
3
  import type { Logger } from '@aztec/aztec.js/log';
4
- import { Fq } from '@aztec/foundation/fields';
4
+ import { Fq } from '@aztec/foundation/curves/bn254';
5
5
  import { sleep } from '@aztec/foundation/sleep';
6
6
  import type { AztecAddress } from '@aztec/stdlib/aztec-address';
7
- import type { TestWallet } from '@aztec/test-wallet/server';
8
7
 
9
8
  import { jest } from '@jest/globals';
10
9
  import type { Hex } from 'viem';
11
10
 
11
+ import type { TestWallet } from '../test-wallet/test_wallet.js';
12
12
  import { FeesTest } from './fees_test.js';
13
13
 
14
14
  jest.setTimeout(300_000);
@@ -26,11 +26,8 @@ describe('e2e_fees bridging_race', () => {
26
26
  });
27
27
 
28
28
  beforeAll(async () => {
29
- await t.applyInitialAccountsSnapshot();
30
- await t.applyPublicDeployAccountsSnapshot();
31
- await t.applySetupFeeJuiceSnapshot();
32
-
33
- ({ wallet, logger } = await t.setup());
29
+ await t.setup();
30
+ ({ wallet, logger } = t);
34
31
  });
35
32
 
36
33
  afterAll(async () => {
@@ -60,7 +57,7 @@ describe('e2e_fees bridging_race', () => {
60
57
  const origApprove = l1TokenManager.approve.bind(l1TokenManager);
61
58
  l1TokenManager.approve = async (amount: bigint, address: Hex, addressName = '') => {
62
59
  await origApprove(amount, address, addressName);
63
- const sleepTime = (Number(t.chainMonitor.l2BlockTimestamp) + AZTEC_SLOT_DURATION) * 1000 - Date.now() - 500;
60
+ const sleepTime = (Number(t.chainMonitor.checkpointTimestamp) + AZTEC_SLOT_DURATION) * 1000 - Date.now() - 500;
64
61
  logger.info(`Sleeping for ${sleepTime}ms until near end of L2 slot before sending L1 fee juice to L2 inbox`);
65
62
  await sleep(sleepTime);
66
63
  };
@@ -70,10 +67,7 @@ describe('e2e_fees bridging_race', () => {
70
67
  // Yes, we need to REFACTOR it at some point
71
68
  const claim = await t.feeJuiceBridgeTestHarness.prepareTokensOnL1(bobsAddress);
72
69
  const { claimSecret: secret, messageLeafIndex: index } = claim;
73
- await t.feeJuiceContract.methods
74
- .claim(bobsAddress, claim.claimAmount, secret, index)
75
- .send({ from: bobsAddress })
76
- .wait();
70
+ await t.feeJuiceContract.methods.claim(bobsAddress, claim.claimAmount, secret, index).send({ from: bobsAddress });
77
71
  const [balance] = await t.getGasBalanceFn(bobsAddress);
78
72
  expect(balance).toEqual(claim.claimAmount);
79
73
  });