@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,20 +1,36 @@
1
1
  import { AztecNodeService } from '@aztec/aztec-node';
2
- import { Fr, getTimestampRangeForEpoch, retryUntil, sleep } from '@aztec/aztec.js';
3
- import { ChainMonitor } from '@aztec/aztec.js/ethereum';
2
+ import { getAccountContractAddress } from '@aztec/aztec.js/account';
3
+ import { getTimestampRangeForEpoch } from '@aztec/aztec.js/block';
4
+ import { getContractInstanceFromInstantiationParams } from '@aztec/aztec.js/contracts';
5
+ import { Fr } from '@aztec/aztec.js/fields';
6
+ import { MerkleTreeId } from '@aztec/aztec.js/trees';
7
+ import { EpochCache } from '@aztec/epoch-cache';
8
+ import { createExtendedL1Client } from '@aztec/ethereum/client';
9
+ import { DefaultL1ContractsConfig } from '@aztec/ethereum/config';
4
10
  import { RollupContract } from '@aztec/ethereum/contracts';
5
- import { waitUntilL1Timestamp } from '@aztec/ethereum/test';
6
- import { randomBytes } from '@aztec/foundation/crypto';
7
- import { withLogNameSuffix } from '@aztec/foundation/log';
8
- import { MerkleTreeId } from '@aztec/stdlib/trees';
11
+ import { createDelayer, waitUntilL1Timestamp, wrapClientWithDelayer } from '@aztec/ethereum/l1-tx-utils';
12
+ import { ChainMonitor } from '@aztec/ethereum/test';
13
+ import { CheckpointNumber, EpochNumber } from '@aztec/foundation/branded-types';
14
+ import { SecretValue } from '@aztec/foundation/config';
15
+ import { randomBytes } from '@aztec/foundation/crypto/random';
16
+ import { withLoggerBindings } from '@aztec/foundation/log/server';
17
+ import { retryUntil } from '@aztec/foundation/retry';
18
+ import { sleep } from '@aztec/foundation/sleep';
19
+ import { SpamContract } from '@aztec/noir-test-contracts.js/Spam';
20
+ import { TestContract } from '@aztec/noir-test-contracts.js/Test';
21
+ import { getMockPubSubP2PServiceFactory } from '@aztec/p2p/test-helpers';
22
+ import { SequencerState } from '@aztec/sequencer-client';
23
+ import { EthAddress } from '@aztec/stdlib/block';
24
+ import { getProofSubmissionDeadlineTimestamp } from '@aztec/stdlib/epoch-helpers';
25
+ import { tryStop } from '@aztec/stdlib/interfaces/server';
9
26
  import { join } from 'path';
27
+ import { privateKeyToAccount } from 'viem/accounts';
28
+ import { SCHNORR_HARDCODED_PRIVATE_KEY, SchnorrHardcodedKeyAccountContract } from '../fixtures/schnorr_hardcoded_account_contract.js';
10
29
  import { createAndSyncProverNode, getPrivateKeyFromIndex, setup } from '../fixtures/utils.js';
11
- // This can be lowered to as much as 2s in non-CI
12
- export const L1_BLOCK_TIME_IN_S = process.env.L1_BLOCK_TIME ? parseInt(process.env.L1_BLOCK_TIME) : 8;
13
- export const EPOCH_DURATION_IN_L2_SLOTS = 4;
14
- export const L2_SLOT_DURATION_IN_L1_SLOTS = 2;
15
- export const WORLD_STATE_BLOCK_HISTORY = 2;
30
+ export const WORLD_STATE_CHECKPOINT_HISTORY = 2;
16
31
  export const WORLD_STATE_BLOCK_CHECK_INTERVAL = 50;
17
32
  export const ARCHIVER_POLL_INTERVAL = 50;
33
+ export const DEFAULT_L1_BLOCK_TIME = process.env.CI ? 12 : 8;
18
34
  /**
19
35
  * Tests building of epochs using fast block times and short epochs.
20
36
  * Spawns an aztec node and a prover node with fake proofs.
@@ -26,41 +42,86 @@ export const ARCHIVER_POLL_INTERVAL = 50;
26
42
  constants;
27
43
  logger;
28
44
  monitor;
45
+ epochCache;
29
46
  proverDelayer;
30
47
  sequencerDelayer;
31
48
  proverNodes = [];
32
49
  nodes = [];
50
+ epochDuration;
51
+ L1_BLOCK_TIME_IN_S;
52
+ L2_SLOT_DURATION_IN_S;
33
53
  static async setup(opts = {}) {
34
54
  const test = new EpochsTestContext();
35
55
  await test.setup(opts);
36
56
  return test;
37
57
  }
58
+ static getSlotDurations(opts = {}) {
59
+ const envEthereumSlotDuration = process.env.L1_BLOCK_TIME ? parseInt(process.env.L1_BLOCK_TIME) : DEFAULT_L1_BLOCK_TIME;
60
+ const ethereumSlotDuration = opts.ethereumSlotDuration ?? envEthereumSlotDuration;
61
+ const aztecSlotDuration = opts.aztecSlotDuration ?? (opts.aztecSlotDurationInL1Slots ?? 2) * ethereumSlotDuration;
62
+ const aztecEpochDuration = opts.aztecEpochDuration ?? 6;
63
+ const aztecProofSubmissionEpochs = opts.aztecProofSubmissionEpochs ?? 1;
64
+ const l1PublishingTime = opts.l1PublishingTime ?? 1;
65
+ return {
66
+ l1PublishingTime,
67
+ ethereumSlotDuration,
68
+ aztecSlotDuration,
69
+ aztecEpochDuration,
70
+ aztecProofSubmissionEpochs
71
+ };
72
+ }
38
73
  async setup(opts = {}) {
74
+ const { ethereumSlotDuration, aztecSlotDuration, aztecEpochDuration, aztecProofSubmissionEpochs, l1PublishingTime } = EpochsTestContext.getSlotDurations(opts);
75
+ this.L1_BLOCK_TIME_IN_S = ethereumSlotDuration;
76
+ this.L2_SLOT_DURATION_IN_S = aztecSlotDuration;
77
+ // Auto-create a hardcoded account funded via genesis when:
78
+ // - skipInitialSequencer is set (no sequencer to deploy on-chain), or
79
+ // - useHardcodedAccount is explicitly requested (e.g. tight per-block gas budgets that
80
+ // can't fit a full account-deploy tx).
81
+ const useHardcodedAccount = (opts.skipInitialSequencer || opts.useHardcodedAccount) && !opts.skipHardcodedAccount;
82
+ let hardcodedAccountData;
83
+ if (useHardcodedAccount) {
84
+ hardcodedAccountData = await EpochsTestContext.getHardcodedAccountData(Fr.random(), Fr.random());
85
+ }
39
86
  // Set up system without any account nor protocol contracts
40
87
  // and with faster block times and shorter epochs.
41
- const context = await setup(0, {
88
+ const context = await setup(useHardcodedAccount ? 0 : opts.numberOfAccounts ?? 0, {
89
+ automineL1Setup: true,
42
90
  checkIntervalMs: 50,
43
91
  archiverPollingIntervalMS: ARCHIVER_POLL_INTERVAL,
44
92
  worldStateBlockCheckIntervalMS: WORLD_STATE_BLOCK_CHECK_INTERVAL,
45
- skipProtocolContracts: true,
46
- salt: 1,
47
- aztecEpochDuration: EPOCH_DURATION_IN_L2_SLOTS,
48
- aztecSlotDuration: L1_BLOCK_TIME_IN_S * L2_SLOT_DURATION_IN_L1_SLOTS,
49
- ethereumSlotDuration: L1_BLOCK_TIME_IN_S,
50
- aztecProofSubmissionWindow: EPOCH_DURATION_IN_L2_SLOTS * 2 - 1,
93
+ aztecEpochDuration,
94
+ aztecSlotDuration,
95
+ ethereumSlotDuration,
96
+ aztecProofSubmissionEpochs,
97
+ aztecTargetCommitteeSize: opts.initialValidators?.length ?? 0,
51
98
  minTxsPerBlock: 0,
52
99
  realProofs: false,
53
100
  startProverNode: true,
54
- // We use numeric incremental prover ids for simplicity, but we can switch to
55
- // using the prover's eth address if the proverId is used for something in the rollup contract
56
- proverId: Fr.fromString('1'),
57
- // This must be enough so that the tx from the prover is delayed properly,
58
- // but not so much to hang the sequencer and timeout the teardown
59
- txPropagationMaxQueryAttempts: 12,
60
- worldStateBlockHistory: WORLD_STATE_BLOCK_HISTORY,
61
- ...opts
101
+ proverTestDelayMs: opts.proverTestDelayMs ?? 0,
102
+ proverId: EthAddress.fromNumber(1),
103
+ worldStateCheckpointHistory: WORLD_STATE_CHECKPOINT_HISTORY,
104
+ exitDelaySeconds: DefaultL1ContractsConfig.exitDelaySeconds,
105
+ slasherEnabled: false,
106
+ l1PublishingTime,
107
+ ...opts,
108
+ ...hardcodedAccountData ? {
109
+ initialFundedAccounts: [
110
+ hardcodedAccountData
111
+ ],
112
+ numberOfAccounts: 0
113
+ } : {}
114
+ }, // Use checkpointed chain tip for PXE by default to avoid issues with blocks being dropped due to pruned anchor blocks.
115
+ // Can be overridden via opts.pxeOpts.
116
+ {
117
+ syncChainTip: 'checkpointed',
118
+ ...opts.pxeOpts
62
119
  });
63
120
  this.context = context;
121
+ // Register the hardcoded account in PXE (local only, no on-chain deployment needed).
122
+ if (hardcodedAccountData) {
123
+ await this.registerHardcodedAccount(hardcodedAccountData);
124
+ }
64
125
  this.proverNodes = context.proverNode ? [
65
126
  context.proverNode
66
127
  ] : [];
@@ -68,51 +129,143 @@ export const ARCHIVER_POLL_INTERVAL = 50;
68
129
  context.aztecNode
69
130
  ] : [];
70
131
  this.logger = context.logger;
71
- this.l1Client = context.deployL1ContractsValues.publicClient;
132
+ this.l1Client = context.deployL1ContractsValues.l1Client;
72
133
  this.rollup = RollupContract.getFromConfig(context.config);
134
+ this.epochCache = await EpochCache.create(this.rollup, context.config, {
135
+ dateProvider: context.dateProvider
136
+ });
73
137
  // Loop that tracks L1 and L2 block numbers and logs whenever there's a new one.
74
- this.monitor = new ChainMonitor(this.rollup, this.logger).start();
75
- // This is hideous.
76
- // We ought to have a definite reference to the l1TxUtils that we're using in both places, provided by the test context.
77
- this.proverDelayer = context.proverNode ? context.proverNode.publisher.l1TxUtils.delayer : undefined;
78
- this.sequencerDelayer = context.sequencer.sequencer.publisher.l1TxUtils.delayer;
79
- if (context.proverNode && !this.proverDelayer || !this.sequencerDelayer) {
138
+ this.monitor = new ChainMonitor(this.rollup, context.dateProvider, this.logger).start();
139
+ this.proverDelayer = context.proverDelayer;
140
+ this.sequencerDelayer = context.sequencerDelayer;
141
+ if (context.proverNode && !this.proverDelayer || context.sequencer && !this.sequencerDelayer) {
80
142
  throw new Error(`Could not find prover or sequencer delayer`);
81
143
  }
82
144
  // Constants used for time calculation
145
+ this.epochDuration = aztecEpochDuration;
83
146
  this.constants = {
84
- epochDuration: EPOCH_DURATION_IN_L2_SLOTS,
85
- slotDuration: L1_BLOCK_TIME_IN_S * L2_SLOT_DURATION_IN_L1_SLOTS,
147
+ epochDuration: aztecEpochDuration,
148
+ slotDuration: aztecSlotDuration,
86
149
  l1StartBlock: await this.rollup.getL1StartBlock(),
87
150
  l1GenesisTime: await this.rollup.getL1GenesisTime(),
88
- ethereumSlotDuration: L1_BLOCK_TIME_IN_S
151
+ ethereumSlotDuration,
152
+ proofSubmissionEpochs: Number(await this.rollup.getProofSubmissionEpochs()),
153
+ targetCommitteeSize: await this.rollup.getTargetCommitteeSize(),
154
+ rollupManaLimit: Number(await this.rollup.getManaLimit())
89
155
  };
90
156
  this.logger.info(`L2 genesis at L1 block ${this.constants.l1StartBlock} (timestamp ${this.constants.l1GenesisTime})`);
91
157
  }
92
158
  async teardown() {
93
- this.monitor.stop();
94
- await Promise.all(this.proverNodes.map((node)=>node.stop()));
95
- await Promise.all(this.nodes.map((node)=>node.stop()));
159
+ await this.monitor.stop();
160
+ await Promise.all(this.proverNodes.map((node)=>tryStop(node, this.logger)));
161
+ await Promise.all(this.nodes.map((node)=>tryStop(node, this.logger)));
96
162
  await this.context.teardown();
97
163
  }
98
- async createProverNode() {
164
+ /**
165
+ * Computes InitialAccountData for a SchnorrHardcodedKeyAccountContract.
166
+ * This contract has a hardcoded signing key and no initializer, so it can be used without
167
+ * on-chain deployment. Pass the returned data in `initialFundedAccounts` so the address
168
+ * gets funded with fee juice in genesis.
169
+ */ static async getHardcodedAccountData(secret, salt) {
170
+ const contract = new SchnorrHardcodedKeyAccountContract();
171
+ const address = await getAccountContractAddress(contract, secret, salt);
172
+ const signingKey = SCHNORR_HARDCODED_PRIVATE_KEY;
173
+ return {
174
+ secret,
175
+ salt,
176
+ signingKey,
177
+ address
178
+ };
179
+ }
180
+ /**
181
+ * Registers a SchnorrHardcodedKeyAccountContract in PXE. The account must have been funded
182
+ * at genesis (via getHardcodedAccountData). No on-chain deployment or block mining needed.
183
+ */ async registerHardcodedAccount(accountData) {
184
+ const contract = new SchnorrHardcodedKeyAccountContract();
185
+ const wallet = this.context.wallet;
186
+ const accountManager = await wallet.createAccount({
187
+ secret: accountData.secret,
188
+ salt: accountData.salt,
189
+ contract
190
+ });
191
+ this.context.accounts = [
192
+ accountManager.address
193
+ ];
194
+ return accountManager.address;
195
+ }
196
+ async createProverNode(opts = {}) {
99
197
  this.logger.warn('Creating and syncing a simulated prover node...');
100
198
  const proverNodePrivateKey = this.getNextPrivateKey();
101
- const suffix = (this.proverNodes.length + 1).toString();
102
- const proverNode = await withLogNameSuffix(suffix, ()=>createAndSyncProverNode(proverNodePrivateKey, {
199
+ const proverIndex = this.proverNodes.length + 1;
200
+ const { mockGossipSubNetwork } = this.context;
201
+ const { proverNode } = await withLoggerBindings({
202
+ actor: `prover-${proverIndex}`
203
+ }, ()=>createAndSyncProverNode(proverNodePrivateKey, {
103
204
  ...this.context.config,
104
- proverId: Fr.fromString(suffix)
105
- }, this.context.aztecNode, join(this.context.config.dataDirectory, randomBytes(8).toString('hex'))));
205
+ p2pEnabled: this.context.config.p2pEnabled || mockGossipSubNetwork !== undefined,
206
+ proverId: EthAddress.fromNumber(proverIndex),
207
+ dontStart: opts.dontStart,
208
+ ...opts
209
+ }, {
210
+ dataDirectory: join(this.context.config.dataDirectory, randomBytes(8).toString('hex'))
211
+ }, {
212
+ dateProvider: this.context.dateProvider,
213
+ p2pClientDeps: {
214
+ p2pServiceFactory: mockGossipSubNetwork ? getMockPubSubP2PServiceFactory(mockGossipSubNetwork) : undefined,
215
+ rpcTxProviders: [
216
+ this.context.aztecNode
217
+ ]
218
+ }
219
+ }, {
220
+ genesis: this.context.genesis,
221
+ dontStart: opts.dontStart
222
+ }));
106
223
  this.proverNodes.push(proverNode);
107
224
  return proverNode;
108
225
  }
109
- async createNonValidatorNode() {
226
+ createNonValidatorNode(opts = {}) {
110
227
  this.logger.warn('Creating and syncing a node without a validator...');
111
- const suffix = (this.nodes.length + 1).toString();
112
- const node = await withLogNameSuffix(suffix, ()=>AztecNodeService.createAndSync({
113
- ...this.context.config,
114
- disableValidator: true,
115
- dataDirectory: join(this.context.config.dataDirectory, randomBytes(8).toString('hex'))
228
+ return this.createNode({
229
+ ...opts,
230
+ disableValidator: true
231
+ });
232
+ }
233
+ createValidatorNode(privateKeys, opts = {}) {
234
+ this.logger.warn('Creating and syncing a validator node...');
235
+ return this.createNode({
236
+ ...opts,
237
+ disableValidator: false,
238
+ validatorPrivateKeys: new SecretValue(privateKeys)
239
+ });
240
+ }
241
+ async createNode(opts = {}) {
242
+ const nodeIndex = this.nodes.length + 1;
243
+ const actorPrefix = opts.disableValidator ? 'node' : 'validator';
244
+ const { mockGossipSubNetwork } = this.context;
245
+ const resolvedConfig = {
246
+ ...this.context.config,
247
+ ...opts
248
+ };
249
+ const p2pEnabled = resolvedConfig.p2pEnabled || mockGossipSubNetwork !== undefined;
250
+ const p2pIp = resolvedConfig.p2pIp ?? (p2pEnabled ? '127.0.0.1' : undefined);
251
+ const node = await withLoggerBindings({
252
+ actor: `${actorPrefix}-${nodeIndex}`
253
+ }, ()=>AztecNodeService.createAndSync({
254
+ ...resolvedConfig,
255
+ dataDirectory: join(this.context.config.dataDirectory, randomBytes(8).toString('hex')),
256
+ validatorPrivateKeys: opts.validatorPrivateKeys ?? new SecretValue([]),
257
+ nodeId: resolvedConfig.nodeId || `${actorPrefix}-${nodeIndex}`,
258
+ p2pEnabled,
259
+ p2pIp
260
+ }, {
261
+ dateProvider: this.context.dateProvider,
262
+ p2pClientDeps: {
263
+ p2pServiceFactory: mockGossipSubNetwork ? getMockPubSubP2PServiceFactory(mockGossipSubNetwork) : undefined
264
+ },
265
+ slashingProtectionDb: opts.slashingProtectionDb
266
+ }, {
267
+ genesis: this.context.genesis,
268
+ ...opts
116
269
  }));
117
270
  this.nodes.push(node);
118
271
  return node;
@@ -122,34 +275,186 @@ export const ARCHIVER_POLL_INTERVAL = 50;
122
275
  return `0x${key.toString('hex')}`;
123
276
  }
124
277
  /** Waits until the epoch begins (ie until the immediately previous L1 block is mined). */ async waitUntilEpochStarts(epoch) {
125
- const [start] = getTimestampRangeForEpoch(BigInt(epoch), this.constants);
278
+ const [start] = getTimestampRangeForEpoch(EpochNumber(epoch), this.constants);
126
279
  this.logger.info(`Waiting until L1 timestamp ${start} is reached as the start of epoch ${epoch}`);
127
- await waitUntilL1Timestamp(this.l1Client, start - BigInt(L1_BLOCK_TIME_IN_S));
280
+ await waitUntilL1Timestamp(this.l1Client, start - BigInt(this.L1_BLOCK_TIME_IN_S), undefined, 30 * this.epochDuration);
128
281
  return start;
129
282
  }
130
- /** Waits until the given L2 block number is mined. */ async waitUntilL2BlockNumber(target, timeout = 60) {
131
- await retryUntil(()=>Promise.resolve(target === this.monitor.l2BlockNumber), `Wait until L2 block ${target}`, timeout, 0.1);
283
+ /** Waits until the given checkpoint number is mined. */ async waitUntilCheckpointNumber(target, timeout = 120) {
284
+ await retryUntil(()=>Promise.resolve(target <= this.monitor.checkpointNumber), `Wait until checkpoint ${target}`, timeout, 0.1);
285
+ }
286
+ /** Waits until the given checkpoint number is marked as proven. */ async waitUntilProvenCheckpointNumber(target, timeout = 120) {
287
+ await retryUntil(()=>Promise.resolve(target <= this.monitor.provenCheckpointNumber), `Wait proven checkpoint ${target}`, timeout, 0.1);
288
+ return this.monitor.provenCheckpointNumber;
132
289
  }
133
- /** Waits until the given L2 block number is marked as proven. */ async waitUntilProvenL2BlockNumber(t, timeout = 60) {
134
- await retryUntil(()=>Promise.resolve(t === this.monitor.l2ProvenBlockNumber), `Wait proven L2 block ${t}`, timeout, 0.1);
290
+ /** Waits until the last slot of the proof submission window for a given epoch. */ async waitUntilLastSlotOfProofSubmissionWindow(epochNumber) {
291
+ const deadline = getProofSubmissionDeadlineTimestamp(EpochNumber.fromBigInt(BigInt(epochNumber)), this.constants);
292
+ const oneSlotBefore = deadline - BigInt(this.constants.slotDuration);
293
+ const date = new Date(Number(oneSlotBefore) * 1000);
294
+ this.logger.info(`Waiting until last slot of submission window for epoch ${epochNumber} at ${date}`, {
295
+ oneSlotBefore
296
+ });
297
+ // Use a timeout that accounts for the full proof submission window
298
+ const proofSubmissionWindowDuration = this.constants.proofSubmissionEpochs * this.epochDuration * this.L2_SLOT_DURATION_IN_S;
299
+ await waitUntilL1Timestamp(this.l1Client, oneSlotBefore, undefined, proofSubmissionWindowDuration * 2);
135
300
  }
136
301
  /** Waits for the aztec node to sync to the target block number. */ async waitForNodeToSync(blockNumber, type) {
137
302
  const waitTime = ARCHIVER_POLL_INTERVAL + WORLD_STATE_BLOCK_CHECK_INTERVAL;
138
303
  let synched = false;
139
304
  while(!synched){
140
305
  await sleep(waitTime);
141
- const syncState = await this.context.aztecNode.getWorldStateSyncStatus();
142
- if (type === 'finalised') {
143
- synched = syncState.finalisedBlockNumber >= blockNumber;
306
+ const [syncState, tips] = await Promise.all([
307
+ this.context.aztecNode.getWorldStateSyncStatus(),
308
+ await this.context.aztecNode.getChainTips()
309
+ ]);
310
+ this.logger.info(`Wait for node synch ${blockNumber} ${type}`, {
311
+ blockNumber,
312
+ type,
313
+ syncState,
314
+ tips
315
+ });
316
+ if (type === 'proven') {
317
+ synched = tips.proven.block.number >= blockNumber && syncState.latestBlockNumber >= blockNumber;
318
+ } else if (type === 'finalized') {
319
+ synched = syncState.finalizedBlockNumber >= blockNumber;
144
320
  } else {
145
321
  synched = syncState.oldestHistoricBlockNumber >= blockNumber;
146
322
  }
147
323
  }
148
324
  }
325
+ /** Registers the SpamContract on the given wallet. */ async registerSpamContract(wallet, salt = Fr.ZERO) {
326
+ const instance = await getContractInstanceFromInstantiationParams(SpamContract.artifact, {
327
+ constructorArgs: [],
328
+ constructorArtifact: undefined,
329
+ salt,
330
+ publicKeys: undefined,
331
+ deployer: undefined
332
+ });
333
+ await wallet.registerContract(instance, SpamContract.artifact);
334
+ return SpamContract.at(instance.address, wallet);
335
+ }
336
+ /** Registers the TestContract on the given wallet. */ async registerTestContract(wallet, salt = Fr.ZERO) {
337
+ const instance = await getContractInstanceFromInstantiationParams(TestContract.artifact, {
338
+ constructorArgs: [],
339
+ constructorArtifact: undefined,
340
+ salt,
341
+ publicKeys: undefined,
342
+ deployer: undefined
343
+ });
344
+ await wallet.registerContract(instance, TestContract.artifact);
345
+ return TestContract.at(instance.address, wallet);
346
+ }
347
+ /** Creates an L1 client using a fresh account with funds from anvil, with a tx delayer already set up. */ async createL1Client() {
348
+ const rawClient = createExtendedL1Client([
349
+ ...this.l1Client.chain.rpcUrls.default.http
350
+ ], privateKeyToAccount(this.getNextPrivateKey()), this.l1Client.chain);
351
+ const delayer = createDelayer(this.context.dateProvider, {
352
+ ethereumSlotDuration: this.L1_BLOCK_TIME_IN_S
353
+ }, {});
354
+ const client = wrapClientWithDelayer(rawClient, delayer);
355
+ expect(await client.getBalance({
356
+ address: client.account.address
357
+ })).toBeGreaterThan(0n);
358
+ return {
359
+ client,
360
+ delayer
361
+ };
362
+ }
149
363
  /** Verifies whether the given block number is found on the aztec node. */ async verifyHistoricBlock(blockNumber, expectedSuccess) {
150
- const result = await this.context.aztecNode.findBlockNumbersForIndexes(blockNumber, MerkleTreeId.NULLIFIER_TREE, [
151
- 0n
364
+ // We use `findLeavesIndexes` here, but could use any function that queries the world-state
365
+ // at a particular block, so we know whether that historic block is available or has been
366
+ // pruned. Note that `getBlock` would not work here, since it only hits the archiver.
367
+ const result = await this.context.aztecNode.findLeavesIndexes(blockNumber, MerkleTreeId.NULLIFIER_TREE, [
368
+ Fr.ZERO
152
369
  ]).then((_)=>true).catch((_)=>false);
153
370
  expect(result).toBe(expectedSuccess);
154
371
  }
372
+ /** Verifies at least one checkpoint has the target number of blocks (for MBPS validation). */ async assertMultipleBlocksPerSlot(targetBlockCount) {
373
+ const archiver = this.context.aztecNode.getBlockSource();
374
+ const checkpoints = await archiver.getCheckpoints({
375
+ from: CheckpointNumber(1),
376
+ limit: 50
377
+ });
378
+ this.logger.warn(`Retrieved ${checkpoints.length} checkpoints from archiver`, {
379
+ checkpoints: checkpoints.map((pc)=>pc.checkpoint.getStats())
380
+ });
381
+ let expectedBlockNumber = checkpoints[0].checkpoint.blocks[0].number;
382
+ let targetFound = false;
383
+ for (const checkpoint of checkpoints){
384
+ const blockCount = checkpoint.checkpoint.blocks.length;
385
+ targetFound = targetFound || blockCount >= targetBlockCount;
386
+ this.logger.verbose(`Checkpoint ${checkpoint.checkpoint.number} has ${blockCount} blocks`, {
387
+ checkpoint: checkpoint.checkpoint.getStats()
388
+ });
389
+ for(let i = 0; i < blockCount; i++){
390
+ const block = checkpoint.checkpoint.blocks[i];
391
+ expect(block.indexWithinCheckpoint).toBe(i);
392
+ expect(block.checkpointNumber).toBe(checkpoint.checkpoint.number);
393
+ expect(block.number).toBe(expectedBlockNumber);
394
+ expectedBlockNumber++;
395
+ }
396
+ }
397
+ expect(targetFound).toBe(true);
398
+ }
399
+ watchSequencerEvents(sequencers, getMetadata = ()=>({}), additionalFailEventKeys = []) {
400
+ const stateChanges = [];
401
+ const failEvents = [];
402
+ // Note we do not include the 'block-tx-count-check-failed' event here, since it is fine if we dont build
403
+ // due to lack of txs available.
404
+ const failEventsKeys = [
405
+ 'block-build-failed',
406
+ 'checkpoint-publish-failed',
407
+ 'proposer-rollup-check-failed',
408
+ 'checkpoint-error',
409
+ 'checkpoint-publish-failed',
410
+ 'header-validation-failed',
411
+ 'pipelined-checkpoint-discarded',
412
+ ...additionalFailEventKeys
413
+ ];
414
+ const makeEvent = (i, eventName, args)=>({
415
+ ...args,
416
+ type: eventName,
417
+ sequencerIndex: i + 2,
418
+ ...getMetadata(i)
419
+ });
420
+ sequencers.forEach((sequencer, i)=>{
421
+ const sequencerIndex = i + 2;
422
+ sequencer.getSequencer().on('state-changed', (args)=>{
423
+ const noisyStates = [
424
+ SequencerState.IDLE,
425
+ SequencerState.PROPOSER_CHECK,
426
+ SequencerState.SYNCHRONIZING
427
+ ];
428
+ if (!noisyStates.includes(args.newState)) {
429
+ const evt = makeEvent(i, 'state-changed', args);
430
+ stateChanges.push(evt);
431
+ this.logger.verbose(`Sequencer ${sequencerIndex} transitioned from state ${args.oldState} to state ${args.newState}`, evt);
432
+ }
433
+ });
434
+ failEventsKeys.forEach((eventName)=>{
435
+ sequencer.getSequencer().on(eventName, (args)=>{
436
+ // Skip benign block-build-failed events where the builder rejected the block because it
437
+ // could not collect enough valid txs. This is the same "not enough txs" case as
438
+ // block-tx-count-check-failed (which is already excluded above), just detected after we
439
+ // started processing txs rather than before.
440
+ if (eventName === 'block-build-failed' && args.reason === 'Insufficient valid txs') {
441
+ return;
442
+ }
443
+ const evt = makeEvent(i, eventName, args);
444
+ failEvents.push(evt);
445
+ this.logger.error(`Failed event ${eventName} from sequencer ${sequencerIndex}`, undefined, evt);
446
+ });
447
+ });
448
+ });
449
+ return {
450
+ failEvents,
451
+ stateChanges
452
+ };
453
+ }
454
+ assertNoFailuresFromSequencers(failEvents) {
455
+ if (failEvents.length > 0) {
456
+ this.logger.error(`Failed events from sequencers`, failEvents);
457
+ }
458
+ expect(failEvents).toEqual([]);
459
+ }
155
460
  }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnJpZGdpbmdfcmFjZS5ub3Rlc3QuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9lMmVfZmVlcy9icmlkZ2luZ19yYWNlLm5vdGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIn0=
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridging_race.notest.d.ts","sourceRoot":"","sources":["../../src/e2e_fees/bridging_race.notest.ts"],"names":[],"mappings":""}
@@ -0,0 +1,61 @@
1
+ import { SchnorrAccountContract } from '@aztec/accounts/schnorr';
2
+ import { Fr } from '@aztec/aztec.js/fields';
3
+ import { Fq } from '@aztec/foundation/curves/bn254';
4
+ import { sleep } from '@aztec/foundation/sleep';
5
+ import { jest } from '@jest/globals';
6
+ import { FeesTest } from './fees_test.js';
7
+ jest.setTimeout(300_000);
8
+ // Regression for https://github.com/AztecProtocol/aztec-packages/issues/12366
9
+ // Similar to e2e_fees/account_init but with no automine
10
+ describe('e2e_fees bridging_race', ()=>{
11
+ const ETHEREUM_SLOT_DURATION = 4;
12
+ const AZTEC_SLOT_DURATION = ETHEREUM_SLOT_DURATION * 2;
13
+ const t = new FeesTest('bridging_race', 1, {
14
+ ethereumSlotDuration: ETHEREUM_SLOT_DURATION,
15
+ aztecSlotDuration: AZTEC_SLOT_DURATION,
16
+ minTxsPerBlock: 0
17
+ });
18
+ beforeAll(async ()=>{
19
+ await t.setup();
20
+ ({ wallet, logger } = t);
21
+ });
22
+ afterAll(async ()=>{
23
+ await t.teardown();
24
+ });
25
+ let logger;
26
+ let bobsAddress;
27
+ let wallet;
28
+ beforeEach(async ()=>{
29
+ const bobsSecretKey = Fr.random();
30
+ const bobsPrivateSigningKey = Fq.random();
31
+ const bobsSalt = Fr.random();
32
+ const bobsAccountManager = await wallet.createAccount({
33
+ secret: bobsSecretKey,
34
+ salt: bobsSalt,
35
+ contract: new SchnorrAccountContract(bobsPrivateSigningKey)
36
+ });
37
+ bobsAddress = bobsAccountManager.address;
38
+ });
39
+ it('Alice bridges funds to Bob', async ()=>{
40
+ // Tweak the token manager so the bridging happens immediately before the end of the current L2 slot
41
+ // This caused the message to be "not in state" when tried to be used
42
+ const l1TokenManager = t.feeJuiceBridgeTestHarness.l1TokenManager;
43
+ const origApprove = l1TokenManager.approve.bind(l1TokenManager);
44
+ l1TokenManager.approve = async (amount, address, addressName = '')=>{
45
+ await origApprove(amount, address, addressName);
46
+ const sleepTime = (Number(t.chainMonitor.checkpointTimestamp) + AZTEC_SLOT_DURATION) * 1000 - Date.now() - 500;
47
+ logger.info(`Sleeping for ${sleepTime}ms until near end of L2 slot before sending L1 fee juice to L2 inbox`);
48
+ await sleep(sleepTime);
49
+ };
50
+ // Waiting for the archiver to sync the message _before_ waiting for the mandatory 2 L2 blocks to pass fixed it
51
+ // This was added everywhere we wait for two blocks, which is spread across three different places in the codebase
52
+ // Yes, we need to REFACTOR it at some point
53
+ const claim = await t.feeJuiceBridgeTestHarness.prepareTokensOnL1(bobsAddress);
54
+ const { claimSecret: secret, messageLeafIndex: index } = claim;
55
+ await t.feeJuiceContract.methods.claim(bobsAddress, claim.claimAmount, secret, index).send({
56
+ from: bobsAddress
57
+ });
58
+ const [balance] = await t.getGasBalanceFn(bobsAddress);
59
+ expect(balance).toEqual(claim.claimAmount);
60
+ });
61
+ });