@aztec/end-to-end 0.0.0-test.0 → 0.0.1-commit.001888fc

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