@aztec/end-to-end 0.0.0-test.1 → 0.0.1-commit.017a351

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 (316) hide show
  1. package/README.md +27 -0
  2. package/dest/bench/client_flows/benchmark.d.ts +76 -0
  3. package/dest/bench/client_flows/benchmark.d.ts.map +1 -0
  4. package/dest/bench/client_flows/benchmark.js +298 -0
  5. package/dest/bench/client_flows/client_flows_benchmark.d.ts +79 -0
  6. package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -0
  7. package/dest/bench/client_flows/client_flows_benchmark.js +318 -0
  8. package/dest/bench/client_flows/config.d.ts +14 -0
  9. package/dest/bench/client_flows/config.d.ts.map +1 -0
  10. package/dest/bench/client_flows/config.js +124 -0
  11. package/dest/bench/client_flows/data_extractor.d.ts +2 -0
  12. package/dest/bench/client_flows/data_extractor.d.ts.map +1 -0
  13. package/dest/bench/client_flows/data_extractor.js +79 -0
  14. package/dest/bench/utils.d.ts +16 -41
  15. package/dest/bench/utils.d.ts.map +1 -1
  16. package/dest/bench/utils.js +46 -72
  17. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +30 -20
  18. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts.map +1 -1
  19. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.js +137 -106
  20. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts +44 -33
  21. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts.map +1 -1
  22. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.js +136 -103
  23. package/dest/e2e_deploy_contract/deploy_test.d.ts +20 -11
  24. package/dest/e2e_deploy_contract/deploy_test.d.ts.map +1 -1
  25. package/dest/e2e_deploy_contract/deploy_test.js +28 -28
  26. package/dest/e2e_epochs/epochs_test.d.ts +98 -24
  27. package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
  28. package/dest/e2e_epochs/epochs_test.js +366 -61
  29. package/dest/e2e_fees/bridging_race.notest.d.ts +2 -0
  30. package/dest/e2e_fees/bridging_race.notest.d.ts.map +1 -0
  31. package/dest/e2e_fees/bridging_race.notest.js +61 -0
  32. package/dest/e2e_fees/fees_test.d.ts +42 -24
  33. package/dest/e2e_fees/fees_test.d.ts.map +1 -1
  34. package/dest/e2e_fees/fees_test.js +194 -182
  35. package/dest/e2e_l1_publisher/write_json.d.ts +11 -0
  36. package/dest/e2e_l1_publisher/write_json.d.ts.map +1 -0
  37. package/dest/e2e_l1_publisher/write_json.js +56 -0
  38. package/dest/e2e_multi_validator/utils.d.ts +12 -0
  39. package/dest/e2e_multi_validator/utils.d.ts.map +1 -0
  40. package/dest/e2e_multi_validator/utils.js +214 -0
  41. package/dest/e2e_nested_contract/nested_contract_test.d.ts +16 -16
  42. package/dest/e2e_nested_contract/nested_contract_test.d.ts.map +1 -1
  43. package/dest/e2e_nested_contract/nested_contract_test.js +38 -43
  44. package/dest/e2e_p2p/inactivity_slash_test.d.ts +31 -0
  45. package/dest/e2e_p2p/inactivity_slash_test.d.ts.map +1 -0
  46. package/dest/e2e_p2p/inactivity_slash_test.js +137 -0
  47. package/dest/e2e_p2p/p2p_network.d.ts +287 -31
  48. package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
  49. package/dest/e2e_p2p/p2p_network.js +281 -183
  50. package/dest/e2e_p2p/reqresp/utils.d.ts +22 -0
  51. package/dest/e2e_p2p/reqresp/utils.d.ts.map +1 -0
  52. package/dest/e2e_p2p/reqresp/utils.js +206 -0
  53. package/dest/e2e_p2p/shared.d.ts +73 -8
  54. package/dest/e2e_p2p/shared.d.ts.map +1 -1
  55. package/dest/e2e_p2p/shared.js +205 -27
  56. package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.d.ts +2 -0
  57. package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.d.ts.map +1 -0
  58. package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.js +184 -0
  59. package/dest/e2e_storage_proof/fixtures/storage_proof_fixture.d.ts +18 -0
  60. package/dest/e2e_storage_proof/fixtures/storage_proof_fixture.d.ts.map +1 -0
  61. package/dest/e2e_storage_proof/fixtures/storage_proof_fixture.js +120 -0
  62. package/dest/e2e_token_contract/token_contract_test.d.ts +30 -15
  63. package/dest/e2e_token_contract/token_contract_test.d.ts.map +1 -1
  64. package/dest/e2e_token_contract/token_contract_test.js +110 -76
  65. package/dest/fixtures/authwit_proxy.d.ts +15 -0
  66. package/dest/fixtures/authwit_proxy.d.ts.map +1 -0
  67. package/dest/fixtures/authwit_proxy.js +34 -0
  68. package/dest/fixtures/e2e_prover_test.d.ts +56 -0
  69. package/dest/fixtures/e2e_prover_test.d.ts.map +1 -0
  70. package/dest/fixtures/e2e_prover_test.js +267 -0
  71. package/dest/fixtures/elu_monitor.d.ts +21 -0
  72. package/dest/fixtures/elu_monitor.d.ts.map +1 -0
  73. package/dest/fixtures/elu_monitor.js +102 -0
  74. package/dest/fixtures/fixtures.d.ts +79 -8
  75. package/dest/fixtures/fixtures.d.ts.map +1 -1
  76. package/dest/fixtures/fixtures.js +76 -5
  77. package/dest/fixtures/get_acvm_config.d.ts +2 -2
  78. package/dest/fixtures/get_acvm_config.d.ts.map +1 -1
  79. package/dest/fixtures/get_acvm_config.js +3 -15
  80. package/dest/fixtures/get_bb_config.d.ts +2 -2
  81. package/dest/fixtures/get_bb_config.d.ts.map +1 -1
  82. package/dest/fixtures/get_bb_config.js +10 -17
  83. package/dest/fixtures/ha_setup.d.ts +71 -0
  84. package/dest/fixtures/ha_setup.d.ts.map +1 -0
  85. package/dest/fixtures/ha_setup.js +116 -0
  86. package/dest/fixtures/index.d.ts +2 -1
  87. package/dest/fixtures/index.d.ts.map +1 -1
  88. package/dest/fixtures/index.js +1 -0
  89. package/dest/fixtures/l1_to_l2_messaging.d.ts +11 -7
  90. package/dest/fixtures/l1_to_l2_messaging.d.ts.map +1 -1
  91. package/dest/fixtures/l1_to_l2_messaging.js +45 -19
  92. package/dest/fixtures/logging.d.ts +1 -1
  93. package/dest/fixtures/schnorr_hardcoded_account_contract.d.ts +25 -0
  94. package/dest/fixtures/schnorr_hardcoded_account_contract.d.ts.map +1 -0
  95. package/dest/fixtures/schnorr_hardcoded_account_contract.js +37 -0
  96. package/dest/fixtures/setup.d.ts +272 -0
  97. package/dest/fixtures/setup.d.ts.map +1 -0
  98. package/dest/fixtures/setup.js +735 -0
  99. package/dest/fixtures/setup_p2p_test.d.ts +28 -16
  100. package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
  101. package/dest/fixtures/setup_p2p_test.js +103 -32
  102. package/dest/fixtures/token_utils.d.ts +10 -4
  103. package/dest/fixtures/token_utils.d.ts.map +1 -1
  104. package/dest/fixtures/token_utils.js +30 -13
  105. package/dest/fixtures/utils.d.ts +5 -153
  106. package/dest/fixtures/utils.d.ts.map +1 -1
  107. package/dest/fixtures/utils.js +4 -552
  108. package/dest/fixtures/web3signer.d.ts +5 -0
  109. package/dest/fixtures/web3signer.d.ts.map +1 -0
  110. package/dest/fixtures/web3signer.js +53 -0
  111. package/dest/fixtures/with_telemetry_utils.d.ts +2 -2
  112. package/dest/fixtures/with_telemetry_utils.d.ts.map +1 -1
  113. package/dest/fixtures/with_telemetry_utils.js +2 -2
  114. package/dest/forward-compatibility/wallet_rpc_client.d.ts +7 -0
  115. package/dest/forward-compatibility/wallet_rpc_client.d.ts.map +1 -0
  116. package/dest/forward-compatibility/wallet_rpc_client.js +15 -0
  117. package/dest/forward-compatibility/wallet_service.d.ts +3 -0
  118. package/dest/forward-compatibility/wallet_service.d.ts.map +1 -0
  119. package/dest/forward-compatibility/wallet_service.js +109 -0
  120. package/dest/index.d.ts +1 -1
  121. package/dest/install_legacy_contracts.d.cts +10 -0
  122. package/dest/install_legacy_contracts.d.cts.map +1 -0
  123. package/dest/legacy-jest-resolver.d.cts +3 -0
  124. package/dest/legacy-jest-resolver.d.cts.map +1 -0
  125. package/dest/quality_of_service/grafana_client.d.ts +41 -0
  126. package/dest/quality_of_service/grafana_client.d.ts.map +1 -0
  127. package/dest/quality_of_service/{alert_checker.js → grafana_client.js} +1 -1
  128. package/dest/quality_of_service/prometheus_client.d.ts +38 -0
  129. package/dest/quality_of_service/prometheus_client.d.ts.map +1 -0
  130. package/dest/quality_of_service/prometheus_client.js +67 -0
  131. package/dest/shared/cross_chain_test_harness.d.ts +46 -27
  132. package/dest/shared/cross_chain_test_harness.d.ts.map +1 -1
  133. package/dest/shared/cross_chain_test_harness.js +113 -55
  134. package/dest/shared/gas_portal_test_harness.d.ts +39 -28
  135. package/dest/shared/gas_portal_test_harness.d.ts.map +1 -1
  136. package/dest/shared/gas_portal_test_harness.js +64 -34
  137. package/dest/shared/index.d.ts +3 -2
  138. package/dest/shared/index.d.ts.map +1 -1
  139. package/dest/shared/index.js +1 -0
  140. package/dest/shared/jest_setup.d.ts +1 -1
  141. package/dest/shared/jest_setup.js +42 -2
  142. package/dest/shared/mock_state_view.d.ts +86 -0
  143. package/dest/shared/mock_state_view.d.ts.map +1 -0
  144. package/dest/shared/mock_state_view.js +186 -0
  145. package/dest/shared/submit-transactions.d.ts +6 -4
  146. package/dest/shared/submit-transactions.d.ts.map +1 -1
  147. package/dest/shared/submit-transactions.js +15 -16
  148. package/dest/shared/uniswap_l1_l2.d.ts +3 -25
  149. package/dest/shared/uniswap_l1_l2.d.ts.map +1 -1
  150. package/dest/shared/uniswap_l1_l2.js +202 -135
  151. package/dest/shared/wait_for_l1_to_l2_message.d.ts +13 -0
  152. package/dest/shared/wait_for_l1_to_l2_message.d.ts.map +1 -0
  153. package/dest/shared/wait_for_l1_to_l2_message.js +10 -0
  154. package/dest/simulators/index.d.ts +1 -1
  155. package/dest/simulators/lending_simulator.d.ts +16 -9
  156. package/dest/simulators/lending_simulator.d.ts.map +1 -1
  157. package/dest/simulators/lending_simulator.js +38 -27
  158. package/dest/simulators/token_simulator.d.ts +6 -3
  159. package/dest/simulators/token_simulator.d.ts.map +1 -1
  160. package/dest/simulators/token_simulator.js +12 -30
  161. package/dest/spartan/setup_test_wallets.d.ts +36 -11
  162. package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
  163. package/dest/spartan/setup_test_wallets.js +301 -63
  164. package/dest/spartan/tx_metrics.d.ts +102 -0
  165. package/dest/spartan/tx_metrics.d.ts.map +1 -0
  166. package/dest/spartan/tx_metrics.js +475 -0
  167. package/dest/spartan/utils/bot.d.ts +28 -0
  168. package/dest/spartan/utils/bot.d.ts.map +1 -0
  169. package/dest/spartan/utils/bot.js +142 -0
  170. package/dest/spartan/utils/chaos.d.ts +79 -0
  171. package/dest/spartan/utils/chaos.d.ts.map +1 -0
  172. package/dest/spartan/utils/chaos.js +142 -0
  173. package/dest/spartan/utils/clients.d.ts +39 -0
  174. package/dest/spartan/utils/clients.d.ts.map +1 -0
  175. package/dest/spartan/utils/clients.js +90 -0
  176. package/dest/spartan/utils/config.d.ts +19 -0
  177. package/dest/spartan/utils/config.d.ts.map +1 -0
  178. package/dest/spartan/utils/config.js +23 -0
  179. package/dest/spartan/utils/health.d.ts +63 -0
  180. package/dest/spartan/utils/health.d.ts.map +1 -0
  181. package/dest/spartan/utils/health.js +202 -0
  182. package/dest/spartan/utils/helm.d.ts +15 -0
  183. package/dest/spartan/utils/helm.d.ts.map +1 -0
  184. package/dest/spartan/utils/helm.js +47 -0
  185. package/dest/spartan/utils/index.d.ts +11 -0
  186. package/dest/spartan/utils/index.d.ts.map +1 -0
  187. package/dest/spartan/utils/index.js +22 -0
  188. package/dest/spartan/utils/k8s.d.ts +128 -0
  189. package/dest/spartan/utils/k8s.d.ts.map +1 -0
  190. package/dest/spartan/utils/k8s.js +381 -0
  191. package/dest/spartan/utils/nodes.d.ts +40 -0
  192. package/dest/spartan/utils/nodes.d.ts.map +1 -0
  193. package/dest/spartan/utils/nodes.js +461 -0
  194. package/dest/spartan/utils/pod_logs.d.ts +25 -0
  195. package/dest/spartan/utils/pod_logs.d.ts.map +1 -0
  196. package/dest/spartan/utils/pod_logs.js +74 -0
  197. package/dest/spartan/utils/scripts.d.ts +30 -0
  198. package/dest/spartan/utils/scripts.d.ts.map +1 -0
  199. package/dest/spartan/utils/scripts.js +81 -0
  200. package/dest/spartan/utils.d.ts +2 -415
  201. package/dest/spartan/utils.d.ts.map +1 -1
  202. package/dest/spartan/utils.js +1 -445
  203. package/dest/test-wallet/test_wallet.d.ts +85 -0
  204. package/dest/test-wallet/test_wallet.d.ts.map +1 -0
  205. package/dest/test-wallet/test_wallet.js +273 -0
  206. package/dest/test-wallet/utils.d.ts +41 -0
  207. package/dest/test-wallet/utils.d.ts.map +1 -0
  208. package/dest/test-wallet/utils.js +66 -0
  209. package/dest/test-wallet/wallet_worker_script.d.ts +2 -0
  210. package/dest/test-wallet/wallet_worker_script.d.ts.map +1 -0
  211. package/dest/test-wallet/wallet_worker_script.js +53 -0
  212. package/dest/test-wallet/worker_wallet.d.ts +53 -0
  213. package/dest/test-wallet/worker_wallet.d.ts.map +1 -0
  214. package/dest/test-wallet/worker_wallet.js +155 -0
  215. package/dest/test-wallet/worker_wallet_schema.d.ts +160 -0
  216. package/dest/test-wallet/worker_wallet_schema.d.ts.map +1 -0
  217. package/dest/test-wallet/worker_wallet_schema.js +22 -0
  218. package/package.json +79 -64
  219. package/src/bench/client_flows/benchmark.ts +382 -0
  220. package/src/bench/client_flows/client_flows_benchmark.ts +399 -0
  221. package/src/bench/client_flows/config.ts +69 -0
  222. package/src/bench/client_flows/data_extractor.ts +89 -0
  223. package/src/bench/utils.ts +49 -87
  224. package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +164 -172
  225. package/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +194 -183
  226. package/src/e2e_deploy_contract/deploy_test.ts +42 -49
  227. package/src/e2e_epochs/epochs_test.ts +451 -93
  228. package/src/e2e_fees/bridging_race.notest.ts +74 -0
  229. package/src/e2e_fees/fees_test.ts +249 -262
  230. package/src/e2e_l1_publisher/write_json.ts +77 -0
  231. package/src/e2e_multi_validator/utils.ts +258 -0
  232. package/src/e2e_nested_contract/nested_contract_test.ts +51 -60
  233. package/src/e2e_p2p/inactivity_slash_test.ts +180 -0
  234. package/src/e2e_p2p/p2p_network.ts +391 -240
  235. package/src/e2e_p2p/reqresp/utils.ts +274 -0
  236. package/src/e2e_p2p/shared.ts +304 -39
  237. package/src/e2e_storage_proof/fixtures/storage_proof.json +915 -0
  238. package/src/e2e_storage_proof/fixtures/storage_proof_fetcher.ts +190 -0
  239. package/src/e2e_storage_proof/fixtures/storage_proof_fixture.ts +173 -0
  240. package/src/e2e_token_contract/token_contract_test.ts +140 -124
  241. package/src/fixtures/authwit_proxy.ts +54 -0
  242. package/src/fixtures/dumps/epoch_proof_result.json +1 -1
  243. package/src/fixtures/e2e_prover_test.ts +329 -0
  244. package/src/fixtures/elu_monitor.ts +126 -0
  245. package/src/fixtures/fixtures.ts +98 -7
  246. package/src/fixtures/get_acvm_config.ts +4 -12
  247. package/src/fixtures/get_bb_config.ts +19 -13
  248. package/src/fixtures/ha_setup.ts +188 -0
  249. package/src/fixtures/index.ts +1 -0
  250. package/src/fixtures/l1_to_l2_messaging.ts +56 -24
  251. package/src/fixtures/schnorr_hardcoded_account_contract.ts +49 -0
  252. package/src/fixtures/setup.ts +1056 -0
  253. package/src/fixtures/setup_p2p_test.ts +142 -54
  254. package/src/fixtures/token_utils.ts +34 -16
  255. package/src/fixtures/utils.ts +29 -820
  256. package/src/fixtures/web3signer.ts +63 -0
  257. package/src/fixtures/with_telemetry_utils.ts +2 -2
  258. package/src/forward-compatibility/wallet_rpc_client.ts +14 -0
  259. package/src/forward-compatibility/wallet_service.ts +104 -0
  260. package/src/guides/up_quick_start.sh +9 -19
  261. package/src/install_legacy_contracts.cjs +75 -0
  262. package/src/legacy-jest-resolver.cjs +112 -0
  263. package/src/quality_of_service/{alert_checker.ts → grafana_client.ts} +2 -2
  264. package/src/quality_of_service/prometheus_client.ts +113 -0
  265. package/src/shared/cross_chain_test_harness.ts +116 -90
  266. package/src/shared/gas_portal_test_harness.ts +75 -56
  267. package/src/shared/index.ts +2 -1
  268. package/src/shared/jest_setup.ts +52 -2
  269. package/src/shared/mock_state_view.ts +188 -0
  270. package/src/shared/submit-transactions.ts +19 -20
  271. package/src/shared/uniswap_l1_l2.ts +259 -234
  272. package/src/shared/wait_for_l1_to_l2_message.ts +23 -0
  273. package/src/simulators/lending_simulator.ts +43 -26
  274. package/src/simulators/token_simulator.ts +18 -34
  275. package/src/spartan/DEVELOP.md +128 -0
  276. package/src/spartan/setup_test_wallets.ts +420 -96
  277. package/src/spartan/tx_metrics.ts +434 -0
  278. package/src/spartan/utils/bot.ts +188 -0
  279. package/src/spartan/utils/chaos.ts +253 -0
  280. package/src/spartan/utils/clients.ts +100 -0
  281. package/src/spartan/utils/config.ts +29 -0
  282. package/src/spartan/utils/health.ts +255 -0
  283. package/src/spartan/utils/helm.ts +84 -0
  284. package/src/spartan/utils/index.ts +71 -0
  285. package/src/spartan/utils/k8s.ts +535 -0
  286. package/src/spartan/utils/nodes.ts +543 -0
  287. package/src/spartan/utils/pod_logs.ts +99 -0
  288. package/src/spartan/utils/scripts.ts +99 -0
  289. package/src/spartan/utils.ts +1 -582
  290. package/src/test-wallet/test_wallet.ts +376 -0
  291. package/src/test-wallet/utils.ts +108 -0
  292. package/src/test-wallet/wallet_worker_script.ts +63 -0
  293. package/src/test-wallet/worker_wallet.ts +218 -0
  294. package/src/test-wallet/worker_wallet_schema.ts +13 -0
  295. package/dest/e2e_prover/e2e_prover_test.d.ts +0 -56
  296. package/dest/e2e_prover/e2e_prover_test.d.ts.map +0 -1
  297. package/dest/e2e_prover/e2e_prover_test.js +0 -291
  298. package/dest/fixtures/setup_l1_contracts.d.ts +0 -6
  299. package/dest/fixtures/setup_l1_contracts.d.ts.map +0 -1
  300. package/dest/fixtures/setup_l1_contracts.js +0 -17
  301. package/dest/fixtures/snapshot_manager.d.ts +0 -87
  302. package/dest/fixtures/snapshot_manager.d.ts.map +0 -1
  303. package/dest/fixtures/snapshot_manager.js +0 -479
  304. package/dest/quality_of_service/alert_checker.d.ts +0 -41
  305. package/dest/quality_of_service/alert_checker.d.ts.map +0 -1
  306. package/dest/sample-dapp/connect.js +0 -12
  307. package/dest/sample-dapp/contracts.js +0 -10
  308. package/dest/sample-dapp/deploy.js +0 -35
  309. package/dest/sample-dapp/index.js +0 -98
  310. package/src/e2e_prover/e2e_prover_test.ts +0 -418
  311. package/src/fixtures/setup_l1_contracts.ts +0 -27
  312. package/src/fixtures/snapshot_manager.ts +0 -617
  313. package/src/sample-dapp/connect.mjs +0 -16
  314. package/src/sample-dapp/contracts.mjs +0 -14
  315. package/src/sample-dapp/deploy.mjs +0 -40
  316. package/src/sample-dapp/index.mjs +0 -128
@@ -1,21 +1,45 @@
1
- import { AztecNodeService } from '@aztec/aztec-node';
2
- import { Fr, type Logger, getTimestampRangeForEpoch, retryUntil, sleep } from '@aztec/aztec.js';
3
- import { ChainMonitor } from '@aztec/aztec.js/ethereum';
1
+ import type { InitialAccountData } from '@aztec/accounts/testing';
2
+ import type { Archiver } from '@aztec/archiver';
3
+ import { type AztecNodeConfig, AztecNodeService } from '@aztec/aztec-node';
4
+ import { getAccountContractAddress } from '@aztec/aztec.js/account';
5
+ import { getTimestampRangeForEpoch } from '@aztec/aztec.js/block';
6
+ import { getContractInstanceFromInstantiationParams } from '@aztec/aztec.js/contracts';
7
+ import { Fr } from '@aztec/aztec.js/fields';
8
+ import type { Logger } from '@aztec/aztec.js/log';
9
+ import { MerkleTreeId } from '@aztec/aztec.js/trees';
10
+ import type { Wallet } from '@aztec/aztec.js/wallet';
11
+ import { EpochCache } from '@aztec/epoch-cache';
12
+ import { createExtendedL1Client } from '@aztec/ethereum/client';
13
+ import { DefaultL1ContractsConfig } from '@aztec/ethereum/config';
4
14
  import { RollupContract } from '@aztec/ethereum/contracts';
5
- import { DelayedTxUtils, type Delayer, waitUntilL1Timestamp } from '@aztec/ethereum/test';
6
- import { randomBytes } from '@aztec/foundation/crypto';
7
- import { withLogNameSuffix } from '@aztec/foundation/log';
8
- import { ProverNode, ProverNodePublisher } from '@aztec/prover-node';
9
- import type { TestProverNode } from '@aztec/prover-node/test';
10
- import type { SequencerPublisher } from '@aztec/sequencer-client';
11
- import type { TestSequencerClient } from '@aztec/sequencer-client/test';
12
- import type { L2BlockNumber } from '@aztec/stdlib/block';
13
- import type { L1RollupConstants } from '@aztec/stdlib/epoch-helpers';
14
- import { MerkleTreeId } from '@aztec/stdlib/trees';
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';
19
+ import { SecretValue } from '@aztec/foundation/config';
20
+ import { randomBytes } from '@aztec/foundation/crypto/random';
21
+ import { withLoggerBindings } from '@aztec/foundation/log/server';
22
+ import { retryUntil } from '@aztec/foundation/retry';
23
+ import { sleep } from '@aztec/foundation/sleep';
24
+ import { SpamContract } from '@aztec/noir-test-contracts.js/Spam';
25
+ import { TestContract } from '@aztec/noir-test-contracts.js/Test';
26
+ import { getMockPubSubP2PServiceFactory } from '@aztec/p2p/test-helpers';
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';
31
+ import { type L1RollupConstants, getProofSubmissionDeadlineTimestamp } from '@aztec/stdlib/epoch-helpers';
32
+ import { tryStop } from '@aztec/stdlib/interfaces/server';
33
+ import type { SlashingProtectionDatabase } from '@aztec/validator-ha-signer/types';
15
34
 
16
35
  import { join } from 'path';
17
- import type { Hex, PublicClient } from 'viem';
36
+ import type { Hex } from 'viem';
37
+ import { privateKeyToAccount } from 'viem/accounts';
18
38
 
39
+ import {
40
+ SCHNORR_HARDCODED_PRIVATE_KEY,
41
+ SchnorrHardcodedKeyAccountContract,
42
+ } from '../fixtures/schnorr_hardcoded_account_contract.js';
19
43
  import {
20
44
  type EndToEndContext,
21
45
  type SetupOptions,
@@ -23,16 +47,33 @@ import {
23
47
  getPrivateKeyFromIndex,
24
48
  setup,
25
49
  } from '../fixtures/utils.js';
50
+ import type { TestWallet } from '../test-wallet/test_wallet.js';
26
51
 
27
- // This can be lowered to as much as 2s in non-CI
28
- export const L1_BLOCK_TIME_IN_S = process.env.L1_BLOCK_TIME ? parseInt(process.env.L1_BLOCK_TIME) : 8;
29
- export const EPOCH_DURATION_IN_L2_SLOTS = 4;
30
- export const L2_SLOT_DURATION_IN_L1_SLOTS = 2;
31
- export const WORLD_STATE_BLOCK_HISTORY = 2;
52
+ export const WORLD_STATE_CHECKPOINT_HISTORY = 2;
32
53
  export const WORLD_STATE_BLOCK_CHECK_INTERVAL = 50;
33
54
  export const ARCHIVER_POLL_INTERVAL = 50;
55
+ export const DEFAULT_L1_BLOCK_TIME = process.env.CI ? 12 : 8;
56
+
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
+ };
34
69
 
35
- export type EpochsTestOpts = Partial<Pick<SetupOptions, 'startProverNode'>>;
70
+ export type TrackedSequencerEvent = {
71
+ [K in keyof SequencerEvents]: Parameters<SequencerEvents[K]>[0] & {
72
+ type: K;
73
+ sequencerIndex: number;
74
+ validator: EthAddress;
75
+ };
76
+ }[keyof SequencerEvents];
36
77
 
37
78
  /**
38
79
  * Tests building of epochs using fast block times and short epochs.
@@ -41,79 +82,134 @@ export type EpochsTestOpts = Partial<Pick<SetupOptions, 'startProverNode'>>;
41
82
  */
42
83
  export class EpochsTestContext {
43
84
  public context!: EndToEndContext;
44
- public l1Client!: PublicClient;
85
+ public l1Client!: ExtendedViemWalletClient;
45
86
  public rollup!: RollupContract;
46
87
  public constants!: L1RollupConstants;
47
88
  public logger!: Logger;
48
89
  public monitor!: ChainMonitor;
90
+ public epochCache!: EpochCache;
49
91
  public proverDelayer!: Delayer;
50
92
  public sequencerDelayer!: Delayer;
51
93
 
52
- public proverNodes: ProverNode[] = [];
94
+ public proverNodes: AztecNodeService[] = [];
53
95
  public nodes: AztecNodeService[] = [];
54
96
 
97
+ public epochDuration!: number;
98
+
99
+ public L1_BLOCK_TIME_IN_S!: number;
100
+ public L2_SLOT_DURATION_IN_S!: number;
101
+
55
102
  public static async setup(opts: EpochsTestOpts = {}) {
56
103
  const test = new EpochsTestContext();
57
104
  await test.setup(opts);
58
105
  return test;
59
106
  }
60
107
 
108
+ public static getSlotDurations(opts: EpochsTestOpts = {}) {
109
+ const envEthereumSlotDuration = process.env.L1_BLOCK_TIME
110
+ ? parseInt(process.env.L1_BLOCK_TIME)
111
+ : DEFAULT_L1_BLOCK_TIME;
112
+ const ethereumSlotDuration = opts.ethereumSlotDuration ?? envEthereumSlotDuration;
113
+ const aztecSlotDuration = opts.aztecSlotDuration ?? (opts.aztecSlotDurationInL1Slots ?? 2) * ethereumSlotDuration;
114
+ const aztecEpochDuration = opts.aztecEpochDuration ?? 6;
115
+ const aztecProofSubmissionEpochs = opts.aztecProofSubmissionEpochs ?? 1;
116
+ const l1PublishingTime = opts.l1PublishingTime ?? 1;
117
+ return {
118
+ l1PublishingTime,
119
+ ethereumSlotDuration,
120
+ aztecSlotDuration,
121
+ aztecEpochDuration,
122
+ aztecProofSubmissionEpochs,
123
+ };
124
+ }
125
+
61
126
  public async setup(opts: EpochsTestOpts = {}) {
127
+ const {
128
+ ethereumSlotDuration,
129
+ aztecSlotDuration,
130
+ aztecEpochDuration,
131
+ aztecProofSubmissionEpochs,
132
+ l1PublishingTime,
133
+ } = EpochsTestContext.getSlotDurations(opts);
134
+
135
+ this.L1_BLOCK_TIME_IN_S = ethereumSlotDuration;
136
+ this.L2_SLOT_DURATION_IN_S = aztecSlotDuration;
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
+
62
148
  // Set up system without any account nor protocol contracts
63
149
  // and with faster block times and shorter epochs.
64
- const context = await setup(0, {
65
- checkIntervalMs: 50,
66
- archiverPollingIntervalMS: ARCHIVER_POLL_INTERVAL,
67
- worldStateBlockCheckIntervalMS: WORLD_STATE_BLOCK_CHECK_INTERVAL,
68
- skipProtocolContracts: true,
69
- salt: 1,
70
- aztecEpochDuration: EPOCH_DURATION_IN_L2_SLOTS,
71
- aztecSlotDuration: L1_BLOCK_TIME_IN_S * L2_SLOT_DURATION_IN_L1_SLOTS,
72
- ethereumSlotDuration: L1_BLOCK_TIME_IN_S,
73
- aztecProofSubmissionWindow: EPOCH_DURATION_IN_L2_SLOTS * 2 - 1,
74
- minTxsPerBlock: 0,
75
- realProofs: false,
76
- startProverNode: true,
77
- // We use numeric incremental prover ids for simplicity, but we can switch to
78
- // using the prover's eth address if the proverId is used for something in the rollup contract
79
- proverId: Fr.fromString('1'),
80
- // This must be enough so that the tx from the prover is delayed properly,
81
- // but not so much to hang the sequencer and timeout the teardown
82
- txPropagationMaxQueryAttempts: 12,
83
- worldStateBlockHistory: WORLD_STATE_BLOCK_HISTORY,
84
- ...opts,
85
- });
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
+ );
86
178
 
87
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
+ }
88
185
  this.proverNodes = context.proverNode ? [context.proverNode] : [];
89
186
  this.nodes = context.aztecNode ? [context.aztecNode as AztecNodeService] : [];
90
187
  this.logger = context.logger;
91
- this.l1Client = context.deployL1ContractsValues.publicClient;
188
+ this.l1Client = context.deployL1ContractsValues.l1Client;
92
189
  this.rollup = RollupContract.getFromConfig(context.config);
190
+ this.epochCache = await EpochCache.create(this.rollup, context.config, { dateProvider: context.dateProvider });
93
191
 
94
192
  // Loop that tracks L1 and L2 block numbers and logs whenever there's a new one.
95
- this.monitor = new ChainMonitor(this.rollup, this.logger).start();
96
-
97
- // This is hideous.
98
- // We ought to have a definite reference to the l1TxUtils that we're using in both places, provided by the test context.
99
- this.proverDelayer = context.proverNode
100
- ? (((context.proverNode as TestProverNode).publisher as ProverNodePublisher).l1TxUtils as DelayedTxUtils).delayer!
101
- : undefined!;
102
- this.sequencerDelayer = (
103
- ((context.sequencer as TestSequencerClient).sequencer.publisher as SequencerPublisher).l1TxUtils as DelayedTxUtils
104
- ).delayer!;
105
-
106
- if ((context.proverNode && !this.proverDelayer) || !this.sequencerDelayer) {
193
+ this.monitor = new ChainMonitor(this.rollup, context.dateProvider, this.logger).start();
194
+
195
+ this.proverDelayer = context.proverDelayer!;
196
+ this.sequencerDelayer = context.sequencerDelayer!;
197
+
198
+ if ((context.proverNode && !this.proverDelayer) || (context.sequencer && !this.sequencerDelayer)) {
107
199
  throw new Error(`Could not find prover or sequencer delayer`);
108
200
  }
109
201
 
110
202
  // Constants used for time calculation
203
+ this.epochDuration = aztecEpochDuration;
111
204
  this.constants = {
112
- epochDuration: EPOCH_DURATION_IN_L2_SLOTS,
113
- slotDuration: L1_BLOCK_TIME_IN_S * L2_SLOT_DURATION_IN_L1_SLOTS,
205
+ epochDuration: aztecEpochDuration,
206
+ slotDuration: aztecSlotDuration,
114
207
  l1StartBlock: await this.rollup.getL1StartBlock(),
115
208
  l1GenesisTime: await this.rollup.getL1GenesisTime(),
116
- ethereumSlotDuration: L1_BLOCK_TIME_IN_S,
209
+ ethereumSlotDuration,
210
+ proofSubmissionEpochs: Number(await this.rollup.getProofSubmissionEpochs()),
211
+ targetCommitteeSize: await this.rollup.getTargetCommitteeSize(),
212
+ rollupManaLimit: Number(await this.rollup.getManaLimit()),
117
213
  };
118
214
 
119
215
  this.logger.info(
@@ -122,38 +218,128 @@ export class EpochsTestContext {
122
218
  }
123
219
 
124
220
  public async teardown() {
125
- this.monitor.stop();
126
- await Promise.all(this.proverNodes.map(node => node.stop()));
127
- await Promise.all(this.nodes.map(node => node.stop()));
221
+ await this.monitor.stop();
222
+ await Promise.all(this.proverNodes.map(node => tryStop(node, this.logger)));
223
+ await Promise.all(this.nodes.map(node => tryStop(node, this.logger)));
128
224
  await this.context.teardown();
129
225
  }
130
226
 
131
- public async createProverNode() {
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
+
256
+ public async createProverNode(opts: { dontStart?: boolean } & Partial<ProverNodeConfig> = {}) {
132
257
  this.logger.warn('Creating and syncing a simulated prover node...');
133
258
  const proverNodePrivateKey = this.getNextPrivateKey();
134
- const suffix = (this.proverNodes.length + 1).toString();
135
- 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}` }, () =>
136
262
  createAndSyncProverNode(
137
263
  proverNodePrivateKey,
138
- { ...this.context.config, proverId: Fr.fromString(suffix) },
139
- this.context.aztecNode,
140
- join(this.context.config.dataDirectory!, randomBytes(8).toString('hex')),
264
+ {
265
+ ...this.context.config,
266
+ p2pEnabled: this.context.config.p2pEnabled || mockGossipSubNetwork !== undefined,
267
+ proverId: EthAddress.fromNumber(proverIndex),
268
+ dontStart: opts.dontStart,
269
+ ...opts,
270
+ },
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
+ },
141
285
  ),
142
286
  );
143
287
  this.proverNodes.push(proverNode);
144
288
  return proverNode;
145
289
  }
146
290
 
147
- public async createNonValidatorNode() {
291
+ public createNonValidatorNode(opts: Partial<AztecNodeConfig> = {}) {
148
292
  this.logger.warn('Creating and syncing a node without a validator...');
149
- const suffix = (this.nodes.length + 1).toString();
150
- const node = await withLogNameSuffix(suffix, () =>
151
- AztecNodeService.createAndSync({
152
- ...this.context.config,
153
- disableValidator: true,
154
- dataDirectory: join(this.context.config.dataDirectory!, randomBytes(8).toString('hex')),
155
- }),
293
+ return this.createNode({ ...opts, disableValidator: true });
294
+ }
295
+
296
+ public createValidatorNode(
297
+ privateKeys: `0x${string}`[],
298
+ opts: Partial<AztecNodeConfig> & {
299
+ dontStartSequencer?: boolean;
300
+ slashingProtectionDb?: SlashingProtectionDatabase;
301
+ } = {},
302
+ ) {
303
+ this.logger.warn('Creating and syncing a validator node...');
304
+ return this.createNode({ ...opts, disableValidator: false, validatorPrivateKeys: new SecretValue(privateKeys) });
305
+ }
306
+
307
+ private async createNode(
308
+ opts: Partial<AztecNodeConfig> & {
309
+ dontStartSequencer?: boolean;
310
+ slashingProtectionDb?: SlashingProtectionDatabase;
311
+ } = {},
312
+ ) {
313
+ const nodeIndex = this.nodes.length + 1;
314
+ const actorPrefix = opts.disableValidator ? 'node' : 'validator';
315
+ const { mockGossipSubNetwork } = this.context;
316
+ const resolvedConfig = { ...this.context.config, ...opts };
317
+ const p2pEnabled = resolvedConfig.p2pEnabled || mockGossipSubNetwork !== undefined;
318
+ const p2pIp = resolvedConfig.p2pIp ?? (p2pEnabled ? '127.0.0.1' : undefined);
319
+ const node = await withLoggerBindings({ actor: `${actorPrefix}-${nodeIndex}` }, () =>
320
+ AztecNodeService.createAndSync(
321
+ {
322
+ ...resolvedConfig,
323
+ dataDirectory: join(this.context.config.dataDirectory!, randomBytes(8).toString('hex')),
324
+ validatorPrivateKeys: opts.validatorPrivateKeys ?? new SecretValue([]),
325
+ nodeId: resolvedConfig.nodeId || `${actorPrefix}-${nodeIndex}`,
326
+ p2pEnabled,
327
+ p2pIp,
328
+ },
329
+ {
330
+ dateProvider: this.context.dateProvider,
331
+ p2pClientDeps: {
332
+ p2pServiceFactory: mockGossipSubNetwork ? getMockPubSubP2PServiceFactory(mockGossipSubNetwork) : undefined,
333
+ },
334
+ slashingProtectionDb: opts.slashingProtectionDb,
335
+ },
336
+ {
337
+ genesis: this.context.genesis,
338
+ ...opts,
339
+ },
340
+ ),
156
341
  );
342
+
157
343
  this.nodes.push(node);
158
344
  return node;
159
345
  }
@@ -165,53 +351,225 @@ export class EpochsTestContext {
165
351
 
166
352
  /** Waits until the epoch begins (ie until the immediately previous L1 block is mined). */
167
353
  public async waitUntilEpochStarts(epoch: number) {
168
- const [start] = getTimestampRangeForEpoch(BigInt(epoch), this.constants);
354
+ const [start] = getTimestampRangeForEpoch(EpochNumber(epoch), this.constants);
169
355
  this.logger.info(`Waiting until L1 timestamp ${start} is reached as the start of epoch ${epoch}`);
170
- await waitUntilL1Timestamp(this.l1Client, start - BigInt(L1_BLOCK_TIME_IN_S));
356
+ await waitUntilL1Timestamp(
357
+ this.l1Client,
358
+ start - BigInt(this.L1_BLOCK_TIME_IN_S),
359
+ undefined,
360
+ 30 * this.epochDuration,
361
+ );
171
362
  return start;
172
363
  }
173
364
 
174
- /** Waits until the given L2 block number is mined. */
175
- public async waitUntilL2BlockNumber(target: number, timeout = 60) {
365
+ /** Waits until the given checkpoint number is mined. */
366
+ public async waitUntilCheckpointNumber(target: CheckpointNumber, timeout = 120) {
176
367
  await retryUntil(
177
- () => Promise.resolve(target === this.monitor.l2BlockNumber),
178
- `Wait until L2 block ${target}`,
368
+ () => Promise.resolve(target <= this.monitor.checkpointNumber),
369
+ `Wait until checkpoint ${target}`,
179
370
  timeout,
180
371
  0.1,
181
372
  );
182
373
  }
183
374
 
184
- /** Waits until the given L2 block number is marked as proven. */
185
- 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) {
186
377
  await retryUntil(
187
- () => Promise.resolve(t === this.monitor.l2ProvenBlockNumber),
188
- `Wait proven L2 block ${t}`,
378
+ () => Promise.resolve(target <= this.monitor.provenCheckpointNumber),
379
+ `Wait proven checkpoint ${target}`,
189
380
  timeout,
190
381
  0.1,
191
382
  );
383
+ return this.monitor.provenCheckpointNumber;
384
+ }
385
+
386
+ /** Waits until the last slot of the proof submission window for a given epoch. */
387
+ public async waitUntilLastSlotOfProofSubmissionWindow(epochNumber: number | bigint) {
388
+ const deadline = getProofSubmissionDeadlineTimestamp(EpochNumber.fromBigInt(BigInt(epochNumber)), this.constants);
389
+ const oneSlotBefore = deadline - BigInt(this.constants.slotDuration);
390
+ const date = new Date(Number(oneSlotBefore) * 1000);
391
+ this.logger.info(`Waiting until last slot of submission window for epoch ${epochNumber} at ${date}`, {
392
+ oneSlotBefore,
393
+ });
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);
192
398
  }
193
399
 
194
400
  /** Waits for the aztec node to sync to the target block number. */
195
- public async waitForNodeToSync(blockNumber: number, type: 'finalised' | 'historic') {
401
+ public async waitForNodeToSync(blockNumber: BlockNumber, type: 'proven' | 'finalized' | 'historic') {
196
402
  const waitTime = ARCHIVER_POLL_INTERVAL + WORLD_STATE_BLOCK_CHECK_INTERVAL;
197
403
  let synched = false;
198
404
  while (!synched) {
199
405
  await sleep(waitTime);
200
- const syncState = await this.context.aztecNode.getWorldStateSyncStatus();
201
- if (type === 'finalised') {
202
- synched = syncState.finalisedBlockNumber >= blockNumber;
406
+ const [syncState, tips] = await Promise.all([
407
+ this.context.aztecNode.getWorldStateSyncStatus(),
408
+ await this.context.aztecNode.getChainTips(),
409
+ ]);
410
+ this.logger.info(`Wait for node synch ${blockNumber} ${type}`, { blockNumber, type, syncState, tips });
411
+ if (type === 'proven') {
412
+ synched = tips.proven.block.number >= blockNumber && syncState.latestBlockNumber >= blockNumber;
413
+ } else if (type === 'finalized') {
414
+ synched = syncState.finalizedBlockNumber >= blockNumber;
203
415
  } else {
204
416
  synched = syncState.oldestHistoricBlockNumber >= blockNumber;
205
417
  }
206
418
  }
207
419
  }
208
420
 
421
+ /** Registers the SpamContract on the given wallet. */
422
+ public async registerSpamContract(wallet: Wallet, salt = Fr.ZERO) {
423
+ const instance = await getContractInstanceFromInstantiationParams(SpamContract.artifact, {
424
+ constructorArgs: [],
425
+ constructorArtifact: undefined,
426
+ salt,
427
+ publicKeys: undefined,
428
+ deployer: undefined,
429
+ });
430
+ await wallet.registerContract(instance, SpamContract.artifact);
431
+ return SpamContract.at(instance.address, wallet);
432
+ }
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
+
447
+ /** Creates an L1 client using a fresh account with funds from anvil, with a tx delayer already set up. */
448
+ public async createL1Client() {
449
+ const rawClient = createExtendedL1Client(
450
+ [...this.l1Client.chain.rpcUrls.default.http],
451
+ privateKeyToAccount(this.getNextPrivateKey()),
452
+ this.l1Client.chain,
453
+ );
454
+ const delayer = createDelayer(this.context.dateProvider, { ethereumSlotDuration: this.L1_BLOCK_TIME_IN_S }, {});
455
+ const client = wrapClientWithDelayer(rawClient, delayer);
456
+ expect(await client.getBalance({ address: client.account.address })).toBeGreaterThan(0n);
457
+ return { client, delayer };
458
+ }
459
+
209
460
  /** Verifies whether the given block number is found on the aztec node. */
210
- public async verifyHistoricBlock(blockNumber: L2BlockNumber, expectedSuccess: boolean) {
461
+ public async verifyHistoricBlock(blockNumber: BlockParameter, expectedSuccess: boolean) {
462
+ // We use `findLeavesIndexes` here, but could use any function that queries the world-state
463
+ // at a particular block, so we know whether that historic block is available or has been
464
+ // pruned. Note that `getBlock` would not work here, since it only hits the archiver.
211
465
  const result = await this.context.aztecNode
212
- .findBlockNumbersForIndexes(blockNumber, MerkleTreeId.NULLIFIER_TREE, [0n])
466
+ .findLeavesIndexes(blockNumber, MerkleTreeId.NULLIFIER_TREE, [Fr.ZERO])
213
467
  .then(_ => true)
214
468
  .catch(_ => false);
215
469
  expect(result).toBe(expectedSuccess);
216
470
  }
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
+
504
+ public watchSequencerEvents(
505
+ sequencers: SequencerClient[],
506
+ getMetadata: (i: number) => Record<string, any> = () => ({}),
507
+ additionalFailEventKeys: (keyof SequencerEvents)[] = [],
508
+ ) {
509
+ const stateChanges: TrackedSequencerEvent[] = [];
510
+ const failEvents: TrackedSequencerEvent[] = [];
511
+
512
+ // Note we do not include the 'block-tx-count-check-failed' event here, since it is fine if we dont build
513
+ // due to lack of txs available.
514
+ const failEventsKeys: (keyof SequencerEvents)[] = [
515
+ 'block-build-failed',
516
+ 'checkpoint-publish-failed',
517
+ 'proposer-rollup-check-failed',
518
+ 'checkpoint-error',
519
+ 'checkpoint-publish-failed',
520
+ 'header-validation-failed',
521
+ 'pipelined-checkpoint-discarded',
522
+ ...additionalFailEventKeys,
523
+ ];
524
+
525
+ const makeEvent = (
526
+ i: number,
527
+ eventName: keyof SequencerEvents,
528
+ args: Parameters<SequencerEvents[keyof SequencerEvents]>[0],
529
+ ) =>
530
+ ({
531
+ ...args,
532
+ type: eventName,
533
+ sequencerIndex: i + 2,
534
+ ...getMetadata(i),
535
+ }) as TrackedSequencerEvent;
536
+
537
+ sequencers.forEach((sequencer, i) => {
538
+ const sequencerIndex = i + 2;
539
+ sequencer.getSequencer().on('state-changed', (args: Parameters<SequencerEvents['state-changed']>[0]) => {
540
+ const noisyStates = [SequencerState.IDLE, SequencerState.PROPOSER_CHECK, SequencerState.SYNCHRONIZING];
541
+ if (!noisyStates.includes(args.newState)) {
542
+ const evt = makeEvent(i, 'state-changed', args);
543
+ stateChanges.push(evt);
544
+ this.logger.verbose(
545
+ `Sequencer ${sequencerIndex} transitioned from state ${args.oldState} to state ${args.newState}`,
546
+ evt,
547
+ );
548
+ }
549
+ });
550
+ failEventsKeys.forEach(eventName => {
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
+ }
559
+ const evt = makeEvent(i, eventName, args);
560
+ failEvents.push(evt);
561
+ this.logger.error(`Failed event ${eventName} from sequencer ${sequencerIndex}`, undefined, evt);
562
+ });
563
+ });
564
+ });
565
+
566
+ return { failEvents, stateChanges };
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
+ }
217
575
  }