@aztec/end-to-end 0.0.1-commit.993d240 → 0.0.1-commit.9a89641

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 (282) hide show
  1. package/README.md +215 -27
  2. package/dest/automine/automine_test_context.d.ts +85 -0
  3. package/dest/automine/automine_test_context.d.ts.map +1 -0
  4. package/dest/automine/automine_test_context.js +98 -0
  5. package/dest/automine/contracts/fixtures/storage_proof_fetcher.d.ts +2 -0
  6. package/dest/automine/contracts/fixtures/storage_proof_fetcher.d.ts.map +1 -0
  7. package/dest/{e2e_storage_proof → automine/contracts}/fixtures/storage_proof_fixture.d.ts +1 -1
  8. package/dest/automine/contracts/fixtures/storage_proof_fixture.d.ts.map +1 -0
  9. package/dest/automine/delivery/interactive_handshake_responder.d.ts +48 -0
  10. package/dest/automine/delivery/interactive_handshake_responder.d.ts.map +1 -0
  11. package/dest/automine/delivery/interactive_handshake_responder.js +76 -0
  12. package/dest/automine/delivery/onchain_delivery_harness.d.ts +19 -0
  13. package/dest/automine/delivery/onchain_delivery_harness.d.ts.map +1 -0
  14. package/dest/automine/delivery/onchain_delivery_harness.js +141 -0
  15. package/dest/automine/token/blacklist_token_contract_test.d.ts +49 -0
  16. package/dest/automine/token/blacklist_token_contract_test.d.ts.map +1 -0
  17. package/dest/{e2e_blacklist_token_contract → automine/token}/blacklist_token_contract_test.js +18 -40
  18. package/dest/automine/token/token_contract_test.d.ts +40 -0
  19. package/dest/automine/token/token_contract_test.d.ts.map +1 -0
  20. package/dest/{e2e_token_contract → automine/token}/token_contract_test.js +22 -39
  21. package/dest/automine/token/token_test_helpers.d.ts +73 -0
  22. package/dest/automine/token/token_test_helpers.d.ts.map +1 -0
  23. package/dest/automine/token/token_test_helpers.js +97 -0
  24. package/dest/bench/client_flows/benchmark.d.ts +1 -1
  25. package/dest/bench/client_flows/benchmark.d.ts.map +1 -1
  26. package/dest/bench/client_flows/benchmark.js +3 -1
  27. package/dest/bench/client_flows/client_flows_benchmark.d.ts +5 -5
  28. package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
  29. package/dest/bench/client_flows/client_flows_benchmark.js +34 -25
  30. package/dest/bench/client_flows/data_extractor.js +1 -0
  31. package/dest/bench/utils.d.ts +3 -3
  32. package/dest/bench/utils.d.ts.map +1 -1
  33. package/dest/bench/utils.js +95 -6
  34. package/dest/composed/ha/ha_full_setup.d.ts +77 -0
  35. package/dest/composed/ha/ha_full_setup.d.ts.map +1 -0
  36. package/dest/composed/ha/ha_full_setup.js +383 -0
  37. package/dest/composed/web3signer/multi_validator_keystore_utils.d.ts +12 -0
  38. package/dest/composed/web3signer/multi_validator_keystore_utils.d.ts.map +1 -0
  39. package/dest/fixtures/e2e_prover_test.d.ts +12 -9
  40. package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
  41. package/dest/fixtures/e2e_prover_test.js +48 -28
  42. package/dest/fixtures/fixtures.d.ts +20 -14
  43. package/dest/fixtures/fixtures.d.ts.map +1 -1
  44. package/dest/fixtures/fixtures.js +27 -15
  45. package/dest/fixtures/get_acvm_config.d.ts +1 -1
  46. package/dest/fixtures/get_acvm_config.d.ts.map +1 -1
  47. package/dest/fixtures/get_acvm_config.js +2 -2
  48. package/dest/fixtures/get_bb_config.d.ts +1 -1
  49. package/dest/fixtures/get_bb_config.d.ts.map +1 -1
  50. package/dest/fixtures/get_bb_config.js +2 -2
  51. package/dest/fixtures/ha_setup.d.ts +3 -3
  52. package/dest/fixtures/ha_setup.d.ts.map +1 -1
  53. package/dest/fixtures/ha_setup.js +4 -1
  54. package/dest/fixtures/index.d.ts +2 -1
  55. package/dest/fixtures/index.d.ts.map +1 -1
  56. package/dest/fixtures/index.js +1 -0
  57. package/dest/fixtures/setup.d.ts +52 -40
  58. package/dest/fixtures/setup.d.ts.map +1 -1
  59. package/dest/fixtures/setup.js +207 -221
  60. package/dest/fixtures/setup_p2p_test.d.ts +1 -1
  61. package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
  62. package/dest/fixtures/setup_p2p_test.js +3 -3
  63. package/dest/fixtures/standard_contracts_genesis.d.ts +16 -0
  64. package/dest/fixtures/standard_contracts_genesis.d.ts.map +1 -0
  65. package/dest/fixtures/standard_contracts_genesis.js +25 -0
  66. package/dest/fixtures/timing.d.ts +42 -0
  67. package/dest/fixtures/timing.d.ts.map +1 -0
  68. package/dest/fixtures/timing.js +72 -0
  69. package/dest/fixtures/token_utils.d.ts +22 -4
  70. package/dest/fixtures/token_utils.d.ts.map +1 -1
  71. package/dest/fixtures/token_utils.js +21 -1
  72. package/dest/fixtures/utils.d.ts +2 -2
  73. package/dest/fixtures/utils.d.ts.map +1 -1
  74. package/dest/fixtures/utils.js +1 -1
  75. package/dest/fixtures/wait_helpers.d.ts +135 -0
  76. package/dest/fixtures/wait_helpers.d.ts.map +1 -0
  77. package/dest/fixtures/wait_helpers.js +154 -0
  78. package/dest/forward-compatibility/wallet_service.js +3 -3
  79. package/dest/multi-node/block-production/setup.d.ts +97 -0
  80. package/dest/multi-node/block-production/setup.d.ts.map +1 -0
  81. package/dest/multi-node/block-production/setup.js +158 -0
  82. package/dest/multi-node/governance/setup.d.ts +67 -0
  83. package/dest/multi-node/governance/setup.d.ts.map +1 -0
  84. package/dest/multi-node/governance/setup.js +126 -0
  85. package/dest/multi-node/multi_node_test_context.d.ts +212 -0
  86. package/dest/multi-node/multi_node_test_context.d.ts.map +1 -0
  87. package/dest/multi-node/multi_node_test_context.js +347 -0
  88. package/dest/multi-node/slashing/inactivity_setup.d.ts +27 -0
  89. package/dest/multi-node/slashing/inactivity_setup.d.ts.map +1 -0
  90. package/dest/multi-node/slashing/inactivity_setup.js +111 -0
  91. package/dest/multi-node/slashing/setup.d.ts +167 -0
  92. package/dest/multi-node/slashing/setup.d.ts.map +1 -0
  93. package/dest/multi-node/slashing/setup.js +275 -0
  94. package/dest/{e2e_p2p → p2p}/p2p_network.d.ts +10 -2
  95. package/dest/p2p/p2p_network.d.ts.map +1 -0
  96. package/dest/{e2e_p2p → p2p}/p2p_network.js +41 -16
  97. package/dest/p2p/reqresp/utils.d.ts +19 -0
  98. package/dest/p2p/reqresp/utils.d.ts.map +1 -0
  99. package/dest/{e2e_p2p → p2p}/reqresp/utils.js +6 -19
  100. package/dest/p2p/shared.d.ts +72 -0
  101. package/dest/p2p/shared.d.ts.map +1 -0
  102. package/dest/p2p/shared.js +212 -0
  103. package/dest/shared/cross_chain_test_harness.d.ts +3 -3
  104. package/dest/shared/cross_chain_test_harness.d.ts.map +1 -1
  105. package/dest/shared/cross_chain_test_harness.js +24 -16
  106. package/dest/shared/gas_portal_test_harness.d.ts +2 -2
  107. package/dest/shared/gas_portal_test_harness.d.ts.map +1 -1
  108. package/dest/shared/gas_portal_test_harness.js +10 -8
  109. package/dest/shared/submit-transactions.d.ts +1 -1
  110. package/dest/shared/submit-transactions.d.ts.map +1 -1
  111. package/dest/shared/submit-transactions.js +12 -5
  112. package/dest/shared/timing_env.d.js +5 -0
  113. package/dest/shared/timing_env.js +365 -0
  114. package/dest/shared/uniswap_l1_l2.d.ts +1 -1
  115. package/dest/shared/uniswap_l1_l2.d.ts.map +1 -1
  116. package/dest/shared/uniswap_l1_l2.js +8 -19
  117. package/dest/shared/wait_for_l1_to_l2_message.js +1 -1
  118. package/dest/simulators/lending_simulator.js +1 -1
  119. package/dest/single-node/cross-chain/cross_chain_messaging_test.d.ts +75 -0
  120. package/dest/single-node/cross-chain/cross_chain_messaging_test.d.ts.map +1 -0
  121. package/dest/single-node/cross-chain/cross_chain_messaging_test.js +209 -0
  122. package/dest/single-node/cross-chain/message_test_helpers.d.ts +38 -0
  123. package/dest/single-node/cross-chain/message_test_helpers.d.ts.map +1 -0
  124. package/dest/single-node/cross-chain/message_test_helpers.js +70 -0
  125. package/dest/{e2e_fees → single-node/fees}/bridging_race.notest.d.ts +1 -1
  126. package/dest/single-node/fees/bridging_race.notest.d.ts.map +1 -0
  127. package/dest/{e2e_fees → single-node/fees}/bridging_race.notest.js +17 -4
  128. package/dest/single-node/fees/fees_test.d.ts +95 -0
  129. package/dest/single-node/fees/fees_test.d.ts.map +1 -0
  130. package/dest/{e2e_fees → single-node/fees}/fees_test.js +129 -66
  131. package/dest/single-node/l1-reorgs/setup.d.ts +42 -0
  132. package/dest/single-node/l1-reorgs/setup.d.ts.map +1 -0
  133. package/dest/single-node/l1-reorgs/setup.js +57 -0
  134. package/dest/single-node/partial-proofs/setup.d.ts +5 -0
  135. package/dest/single-node/partial-proofs/setup.d.ts.map +1 -0
  136. package/dest/single-node/partial-proofs/setup.js +5 -0
  137. package/dest/single-node/proving/setup.d.ts +5 -0
  138. package/dest/single-node/proving/setup.d.ts.map +1 -0
  139. package/dest/single-node/proving/setup.js +5 -0
  140. package/dest/single-node/recovery/setup.d.ts +5 -0
  141. package/dest/single-node/recovery/setup.d.ts.map +1 -0
  142. package/dest/single-node/recovery/setup.js +5 -0
  143. package/dest/single-node/setup.d.ts +49 -0
  144. package/dest/single-node/setup.d.ts.map +1 -0
  145. package/dest/single-node/setup.js +56 -0
  146. package/dest/single-node/single_node_test_context.d.ts +374 -0
  147. package/dest/single-node/single_node_test_context.d.ts.map +1 -0
  148. package/dest/single-node/single_node_test_context.js +847 -0
  149. package/dest/spartan/setup_test_wallets.d.ts +1 -1
  150. package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
  151. package/dest/spartan/setup_test_wallets.js +24 -10
  152. package/dest/spartan/tx_metrics.d.ts +10 -1
  153. package/dest/spartan/tx_metrics.d.ts.map +1 -1
  154. package/dest/spartan/tx_metrics.js +32 -0
  155. package/dest/test-wallet/test_wallet.d.ts +23 -3
  156. package/dest/test-wallet/test_wallet.d.ts.map +1 -1
  157. package/dest/test-wallet/test_wallet.js +56 -9
  158. package/dest/test-wallet/utils.d.ts +36 -1
  159. package/dest/test-wallet/utils.d.ts.map +1 -1
  160. package/dest/test-wallet/utils.js +64 -4
  161. package/dest/test-wallet/wallet_worker_script.js +10 -2
  162. package/dest/test-wallet/worker_wallet.d.ts +5 -5
  163. package/dest/test-wallet/worker_wallet.d.ts.map +1 -1
  164. package/dest/test-wallet/worker_wallet.js +6 -4
  165. package/dest/test-wallet/worker_wallet_schema.d.ts +3 -159
  166. package/dest/test-wallet/worker_wallet_schema.d.ts.map +1 -1
  167. package/dest/test-wallet/worker_wallet_schema.js +2 -1
  168. package/package.json +41 -41
  169. package/src/automine/README.md +60 -0
  170. package/src/automine/automine_test_context.ts +153 -0
  171. package/src/automine/delivery/interactive_handshake_responder.ts +125 -0
  172. package/src/automine/delivery/onchain_delivery_harness.ts +213 -0
  173. package/src/{e2e_blacklist_token_contract → automine/token}/blacklist_token_contract_test.ts +20 -57
  174. package/src/{e2e_token_contract → automine/token}/token_contract_test.ts +24 -57
  175. package/src/automine/token/token_test_helpers.ts +138 -0
  176. package/src/bench/client_flows/benchmark.ts +3 -1
  177. package/src/bench/client_flows/client_flows_benchmark.ts +48 -32
  178. package/src/bench/client_flows/data_extractor.ts +1 -0
  179. package/src/bench/utils.ts +109 -6
  180. package/src/composed/ha/ha_full_setup.ts +466 -0
  181. package/src/fixtures/e2e_prover_test.ts +60 -47
  182. package/src/fixtures/fixtures.ts +29 -15
  183. package/src/fixtures/get_acvm_config.ts +2 -8
  184. package/src/fixtures/get_bb_config.ts +1 -2
  185. package/src/fixtures/ha_setup.ts +7 -3
  186. package/src/fixtures/index.ts +1 -0
  187. package/src/fixtures/setup.ts +255 -281
  188. package/src/fixtures/setup_p2p_test.ts +3 -3
  189. package/src/fixtures/standard_contracts_genesis.ts +28 -0
  190. package/src/fixtures/timing.ts +97 -0
  191. package/src/fixtures/token_utils.ts +39 -4
  192. package/src/fixtures/utils.ts +0 -3
  193. package/src/fixtures/wait_helpers.ts +333 -0
  194. package/src/forward-compatibility/wallet_service.ts +6 -4
  195. package/src/guides/up_quick_start.sh +5 -0
  196. package/src/infra/README.md +12 -0
  197. package/src/multi-node/README.md +96 -0
  198. package/src/multi-node/block-production/setup.ts +272 -0
  199. package/src/multi-node/governance/setup.ts +172 -0
  200. package/src/multi-node/multi_node_test_context.ts +447 -0
  201. package/src/multi-node/slashing/inactivity_setup.ts +139 -0
  202. package/src/multi-node/slashing/setup.ts +433 -0
  203. package/src/p2p/README.md +78 -0
  204. package/src/{e2e_p2p → p2p}/p2p_network.ts +40 -13
  205. package/src/{e2e_p2p → p2p}/reqresp/utils.ts +7 -18
  206. package/src/p2p/shared.ts +329 -0
  207. package/src/shared/cross_chain_test_harness.ts +22 -13
  208. package/src/shared/gas_portal_test_harness.ts +15 -8
  209. package/src/shared/submit-transactions.ts +13 -5
  210. package/src/shared/timing_env.d.mts +39 -0
  211. package/src/shared/timing_env.mjs +363 -0
  212. package/src/shared/uniswap_l1_l2.ts +38 -21
  213. package/src/shared/wait_for_l1_to_l2_message.ts +1 -1
  214. package/src/simulators/lending_simulator.ts +1 -1
  215. package/src/single-node/README.md +66 -0
  216. package/src/single-node/cross-chain/cross_chain_messaging_test.ts +302 -0
  217. package/src/single-node/cross-chain/message_test_helpers.ts +125 -0
  218. package/src/{e2e_fees → single-node/fees}/bridging_race.notest.ts +19 -5
  219. package/src/{e2e_fees → single-node/fees}/fees_test.ts +146 -76
  220. package/src/single-node/l1-reorgs/setup.ts +93 -0
  221. package/src/single-node/partial-proofs/setup.ts +8 -0
  222. package/src/single-node/proving/setup.ts +15 -0
  223. package/src/single-node/recovery/setup.ts +8 -0
  224. package/src/single-node/setup.ts +63 -0
  225. package/src/single-node/single_node_test_context.ts +1058 -0
  226. package/src/spartan/setup_test_wallets.ts +28 -10
  227. package/src/spartan/tx_metrics.ts +26 -0
  228. package/src/test-wallet/test_wallet.ts +60 -10
  229. package/src/test-wallet/utils.ts +102 -5
  230. package/src/test-wallet/wallet_worker_script.ts +9 -3
  231. package/src/test-wallet/worker_wallet.ts +11 -13
  232. package/src/test-wallet/worker_wallet_schema.ts +3 -2
  233. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +0 -56
  234. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts.map +0 -1
  235. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts +0 -58
  236. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts.map +0 -1
  237. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.js +0 -161
  238. package/dest/e2e_deploy_contract/deploy_test.d.ts +0 -37
  239. package/dest/e2e_deploy_contract/deploy_test.d.ts.map +0 -1
  240. package/dest/e2e_deploy_contract/deploy_test.js +0 -51
  241. package/dest/e2e_epochs/epochs_test.d.ts +0 -125
  242. package/dest/e2e_epochs/epochs_test.d.ts.map +0 -1
  243. package/dest/e2e_epochs/epochs_test.js +0 -460
  244. package/dest/e2e_fees/bridging_race.notest.d.ts.map +0 -1
  245. package/dest/e2e_fees/fees_test.d.ts +0 -91
  246. package/dest/e2e_fees/fees_test.d.ts.map +0 -1
  247. package/dest/e2e_l1_publisher/write_json.d.ts +0 -11
  248. package/dest/e2e_l1_publisher/write_json.d.ts.map +0 -1
  249. package/dest/e2e_l1_publisher/write_json.js +0 -56
  250. package/dest/e2e_multi_validator/utils.d.ts +0 -12
  251. package/dest/e2e_multi_validator/utils.d.ts.map +0 -1
  252. package/dest/e2e_nested_contract/nested_contract_test.d.ts +0 -26
  253. package/dest/e2e_nested_contract/nested_contract_test.d.ts.map +0 -1
  254. package/dest/e2e_nested_contract/nested_contract_test.js +0 -55
  255. package/dest/e2e_p2p/inactivity_slash_test.d.ts +0 -31
  256. package/dest/e2e_p2p/inactivity_slash_test.d.ts.map +0 -1
  257. package/dest/e2e_p2p/inactivity_slash_test.js +0 -138
  258. package/dest/e2e_p2p/p2p_network.d.ts.map +0 -1
  259. package/dest/e2e_p2p/reqresp/utils.d.ts +0 -22
  260. package/dest/e2e_p2p/reqresp/utils.d.ts.map +0 -1
  261. package/dest/e2e_p2p/shared.d.ts +0 -64
  262. package/dest/e2e_p2p/shared.d.ts.map +0 -1
  263. package/dest/e2e_p2p/shared.js +0 -204
  264. package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.d.ts +0 -2
  265. package/dest/e2e_storage_proof/fixtures/storage_proof_fetcher.d.ts.map +0 -1
  266. package/dest/e2e_storage_proof/fixtures/storage_proof_fixture.d.ts.map +0 -1
  267. package/dest/e2e_token_contract/token_contract_test.d.ts +0 -44
  268. package/dest/e2e_token_contract/token_contract_test.d.ts.map +0 -1
  269. package/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +0 -231
  270. package/src/e2e_deploy_contract/deploy_test.ts +0 -86
  271. package/src/e2e_epochs/epochs_test.ts +0 -575
  272. package/src/e2e_l1_publisher/write_json.ts +0 -77
  273. package/src/e2e_nested_contract/nested_contract_test.ts +0 -77
  274. package/src/e2e_p2p/inactivity_slash_test.ts +0 -181
  275. package/src/e2e_p2p/shared.ts +0 -318
  276. /package/dest/{e2e_storage_proof → automine/contracts}/fixtures/storage_proof_fetcher.js +0 -0
  277. /package/dest/{e2e_storage_proof → automine/contracts}/fixtures/storage_proof_fixture.js +0 -0
  278. /package/dest/{e2e_multi_validator/utils.js → composed/web3signer/multi_validator_keystore_utils.js} +0 -0
  279. /package/src/{e2e_storage_proof → automine/contracts}/fixtures/storage_proof.json +0 -0
  280. /package/src/{e2e_storage_proof → automine/contracts}/fixtures/storage_proof_fetcher.ts +0 -0
  281. /package/src/{e2e_storage_proof → automine/contracts}/fixtures/storage_proof_fixture.ts +0 -0
  282. /package/src/{e2e_multi_validator/utils.ts → composed/web3signer/multi_validator_keystore_utils.ts} +0 -0
@@ -1,5 +1,5 @@
1
1
  import { AztecAddress } from '@aztec/aztec.js/addresses';
2
- import { type Logger, createLogger } from '@aztec/aztec.js/log';
2
+ import { createLogger } from '@aztec/aztec.js/log';
3
3
  import type { AztecNode } from '@aztec/aztec.js/node';
4
4
  import { TokenContract } from '@aztec/noir-contracts.js/Token';
5
5
  import { GenericProxyContract } from '@aztec/noir-test-contracts.js/GenericProxy';
@@ -7,27 +7,23 @@ import { InvalidAccountContract } from '@aztec/noir-test-contracts.js/InvalidAcc
7
7
 
8
8
  import { jest } from '@jest/globals';
9
9
 
10
- import {
11
- type EndToEndContext,
12
- type SetupOptions,
13
- deployAccounts,
14
- ensureAuthRegistryPublished,
15
- publicDeployAccounts,
16
- setup,
17
- teardown,
18
- } from '../fixtures/setup.js';
19
- import { mintTokensToPrivate } from '../fixtures/token_utils.js';
20
- import { TokenSimulator } from '../simulators/token_simulator.js';
21
- import type { TestWallet } from '../test-wallet/test_wallet.js';
10
+ import { ensureAuthRegistryPublished } from '../../fixtures/setup.js';
11
+ import { mintTokensToPrivate } from '../../fixtures/token_utils.js';
12
+ import { TokenSimulator } from '../../simulators/token_simulator.js';
13
+ import { AutomineTestContext, type AutomineTestOpts } from '../automine_test_context.js';
22
14
 
23
15
  const { METRICS_PORT: metricsPort } = process.env;
24
16
 
25
- export class TokenContractTest {
17
+ /**
18
+ * Token-domain harness over the automine topology: extends {@link AutomineTestContext} with a
19
+ * {@link TokenSimulator}, the USDC Token deploy plus a bad-account and authwit proxy, and an optional
20
+ * mint. Base setup is opt-in via {@link applyBaseSnapshots} (run during `setup()`); {@link applyMint}
21
+ * is called explicitly after `setup()`.
22
+ */
23
+ export class TokenContractTest extends AutomineTestContext {
26
24
  static TOKEN_NAME = 'USDC';
27
25
  static TOKEN_SYMBOL = 'USD';
28
26
  static TOKEN_DECIMALS = 18n;
29
- context!: EndToEndContext;
30
- logger: Logger;
31
27
  metricsPort?: number;
32
28
  asset!: TokenContract;
33
29
  tokenSim!: TokenSimulator;
@@ -35,16 +31,16 @@ export class TokenContractTest {
35
31
 
36
32
  badAccount!: InvalidAccountContract;
37
33
  authwitProxy!: GenericProxyContract;
38
- wallet!: TestWallet;
39
34
  adminAddress!: AztecAddress;
40
- account1Address!: AztecAddress;
35
+ otherAddress!: AztecAddress;
41
36
  account2Address!: AztecAddress;
42
37
 
43
38
  private shouldApplyBaseSetup = false;
44
- private shouldApplyMint = false;
39
+ private testName: string;
45
40
 
46
41
  constructor(testName: string) {
47
- this.logger = createLogger(`e2e:e2e_token_contract:${testName}`);
42
+ super();
43
+ this.testName = testName;
48
44
  this.metricsPort = metricsPort ? parseInt(metricsPort) : undefined;
49
45
  }
50
46
 
@@ -56,14 +52,6 @@ export class TokenContractTest {
56
52
  this.shouldApplyBaseSetup = true;
57
53
  }
58
54
 
59
- /**
60
- * Registers that mint should be applied during setup().
61
- * Call this before setup() to mint tokens to the admin account.
62
- */
63
- applyMintSnapshot() {
64
- this.shouldApplyMint = true;
65
- }
66
-
67
55
  /**
68
56
  * Applies base setup: deploys 3 accounts, publicly deploys accounts, token contract and a "bad account".
69
57
  */
@@ -71,23 +59,12 @@ export class TokenContractTest {
71
59
  // Adding a timeout of 2 minutes in here such that it is propagated to the underlying tests
72
60
  jest.setTimeout(120_000);
73
61
 
74
- this.logger.info('Applying base setup - deploying 3 accounts');
75
- const { deployedAccounts } = await deployAccounts(
76
- 3,
77
- this.logger,
78
- )({
79
- wallet: this.context.wallet,
80
- initialFundedAccounts: this.context.initialFundedAccounts,
81
- });
82
-
83
62
  this.node = this.context.aztecNodeService;
84
63
  this.wallet = this.context.wallet;
85
- [this.adminAddress, this.account1Address, this.account2Address] = deployedAccounts.map(acc => acc.address);
64
+ [this.adminAddress, this.otherAddress, this.account2Address] = this.context.accounts;
86
65
 
87
66
  this.logger.info('Applying base setup - deploying token contract');
88
67
  await ensureAuthRegistryPublished(this.wallet, this.adminAddress);
89
- this.logger.verbose(`Public deploy accounts...`);
90
- await publicDeployAccounts(this.wallet, [this.adminAddress, this.account1Address]);
91
68
 
92
69
  this.logger.verbose(`Deploying TokenContract...`);
93
70
  ({ contract: this.asset } = await TokenContract.deploy(
@@ -116,7 +93,7 @@ export class TokenContractTest {
116
93
 
117
94
  this.tokenSim = new TokenSimulator(this.asset, this.wallet, this.adminAddress, this.logger, [
118
95
  this.adminAddress,
119
- this.account1Address,
96
+ this.otherAddress,
120
97
  ]);
121
98
 
122
99
  expect((await this.asset.methods.get_admin().simulate({ from: this.adminAddress })).result).toBe(
@@ -124,28 +101,18 @@ export class TokenContractTest {
124
101
  );
125
102
  }
126
103
 
127
- async setup(opts: Partial<SetupOptions> = {}) {
128
- this.context = await setup(0, {
129
- ...opts,
130
- metricsPort: this.metricsPort,
131
- fundSponsoredFPC: true,
132
- skipAccountDeployment: true,
133
- });
104
+ override async setup(opts: AutomineTestOpts = {}) {
105
+ await super.setup({ numberOfAccounts: 3, metricsPort: this.metricsPort, ...opts });
106
+ // hydrateFromContext repoints `this.logger` at the context logger; restore the harness-named one.
107
+ this.logger = createLogger(`e2e:automine:token:${this.testName}`);
134
108
 
135
109
  if (this.shouldApplyBaseSetup) {
136
110
  await this.applyBaseSetup();
137
111
  }
138
-
139
- if (this.shouldApplyMint) {
140
- await this.applyMint();
141
- }
142
- }
143
-
144
- async teardown() {
145
- await teardown(this.context);
146
112
  }
147
113
 
148
- private async applyMint() {
114
+ /** Mints an initial public and private balance to the admin account. Call after {@link setup}. */
115
+ async applyMint() {
149
116
  this.logger.info('Applying mint setup');
150
117
  const { asset, adminAddress, tokenSim } = this;
151
118
  const amount = 10000n;
@@ -0,0 +1,138 @@
1
+ import type { AztecAddress } from '@aztec/aztec.js/addresses';
2
+ import type { ContractFunctionInteraction } from '@aztec/aztec.js/contracts';
3
+ import type { Logger } from '@aztec/aztec.js/log';
4
+ import type { Wallet } from '@aztec/aztec.js/wallet';
5
+ import { AMMContract } from '@aztec/noir-contracts.js/AMM';
6
+ import type { GenericProxyContract } from '@aztec/noir-test-contracts.js/GenericProxy';
7
+
8
+ import { sendThroughAuthwitProxy } from '../../fixtures/authwit_proxy.js';
9
+ import { DUPLICATE_NULLIFIER_ERROR } from '../../fixtures/fixtures.js';
10
+ import { type AnyTokenContract, mintTokensToPrivate } from '../../fixtures/token_utils.js';
11
+ import type { TestWallet } from '../../test-wallet/test_wallet.js';
12
+
13
+ /** Whether an amount / balance is read from the private or public balance of the token. */
14
+ export type BalanceKind = 'private' | 'public';
15
+
16
+ /** The invalid-authwit-nonce assertion the contract raises when `from == msg_sender` but nonce != 0. */
17
+ export const INVALID_AUTHWIT_NONCE_ERROR =
18
+ "Assertion failed: Invalid authwit nonce. When 'from' and 'msg_sender' are the same, 'authwit_nonce' must be zero";
19
+
20
+ /** Minimal token shape needed to read balances — satisfied structurally by Token/TestToken/TokenBlacklist. */
21
+ export interface BalanceReadable {
22
+ methods: {
23
+ balance_of_private(owner: AztecAddress): { simulate(opts: { from: AztecAddress }): Promise<{ result: bigint }> };
24
+ balance_of_public(owner: AztecAddress): { simulate(opts: { from: AztecAddress }): Promise<{ result: bigint }> };
25
+ };
26
+ }
27
+
28
+ /** Reads the private or public balance of an account, simulating from that account's own scope. */
29
+ export async function balanceOf(asset: BalanceReadable, kind: BalanceKind, account: AztecAddress): Promise<bigint> {
30
+ const interaction =
31
+ kind === 'private' ? asset.methods.balance_of_private(account) : asset.methods.balance_of_public(account);
32
+ return (await interaction.simulate({ from: account })).result;
33
+ }
34
+
35
+ /** Returns half of an account's balance, asserting it is non-zero so the operation under test is meaningful. */
36
+ export async function halfBalanceOf(asset: BalanceReadable, kind: BalanceKind, owner: AztecAddress): Promise<bigint> {
37
+ const amount = (await balanceOf(asset, kind, owner)) / 2n;
38
+ expect(amount).toBeGreaterThan(0n);
39
+ return amount;
40
+ }
41
+
42
+ /** Returns an amount just above an account's balance (balance + delta), asserting it is non-zero. */
43
+ export async function amountAboveBalance(
44
+ asset: BalanceReadable,
45
+ kind: BalanceKind,
46
+ owner: AztecAddress,
47
+ delta = 1n,
48
+ ): Promise<bigint> {
49
+ const amount = (await balanceOf(asset, kind, owner)) + delta;
50
+ expect(amount).toBeGreaterThan(0n);
51
+ return amount;
52
+ }
53
+
54
+ /**
55
+ * Grants a public authwit for `caller` to run `action` on behalf of `owner`, executes it from `caller`,
56
+ * then asserts a replay of the same call reverts as unauthorized (the authwit is single-use).
57
+ *
58
+ * `onExecuted` runs after the successful execution (before the replay attempt) so callers can update
59
+ * their {@link TokenSimulator} to match the state change the executed action produced.
60
+ */
61
+ export async function assertPublicAuthwitReplayRejected(
62
+ wallet: TestWallet,
63
+ owner: AztecAddress,
64
+ action: ContractFunctionInteraction,
65
+ caller: AztecAddress,
66
+ onExecuted?: () => void,
67
+ ): Promise<void> {
68
+ const grant = await wallet.setPublicAuthWit(owner, { caller, action }, true);
69
+ await grant.send();
70
+
71
+ await action.send({ from: caller });
72
+ onExecuted?.();
73
+
74
+ await expect(action.simulate({ from: caller })).rejects.toThrow(/unauthorized/);
75
+ }
76
+
77
+ /**
78
+ * Creates a private authwit for `owner`, executes `action` through the authwit proxy (so `msg_sender`
79
+ * differs from the note owner), then asserts a replay reverts with a duplicate-nullifier error.
80
+ *
81
+ * `onExecuted` runs after the successful execution (before the replay attempt) so callers can update
82
+ * their {@link TokenSimulator} to match the state change the executed action produced.
83
+ */
84
+ export async function assertAuthwitProxyReplayRejected(
85
+ proxy: GenericProxyContract,
86
+ wallet: TestWallet,
87
+ owner: AztecAddress,
88
+ action: ContractFunctionInteraction,
89
+ onExecuted?: () => void,
90
+ ): Promise<void> {
91
+ const witness = await wallet.createAuthWit(owner, { caller: proxy.address, action });
92
+
93
+ await sendThroughAuthwitProxy(proxy, action, { from: owner, authWitnesses: [witness] });
94
+ onExecuted?.();
95
+
96
+ await expect(sendThroughAuthwitProxy(proxy, action, { from: owner, authWitnesses: [witness] })).rejects.toThrow(
97
+ DUPLICATE_NULLIFIER_ERROR,
98
+ );
99
+ }
100
+
101
+ /**
102
+ * Deploys an {@link AMMContract} over three freshly deployed tokens (token0, token1, and the liquidity
103
+ * token), makes the AMM the liquidity token's minter, and mints `initialBalance` of token0 and token1 to
104
+ * each liquidity provider plus token0 to the swapper. `deploy` selects the token flavour (Token vs
105
+ * TestToken), so the concrete token type flows through to the caller.
106
+ */
107
+ export async function deployAmmWithTokens<T extends AnyTokenContract>(
108
+ wallet: Wallet,
109
+ admin: AztecAddress,
110
+ deploy: (wallet: Wallet, admin: AztecAddress, initialBalance: bigint, logger: Logger) => Promise<{ contract: T }>,
111
+ opts: { liquidityProviders: AztecAddress[]; swapper: AztecAddress; initialBalance: bigint; logger: Logger },
112
+ ): Promise<{ token0: T; token1: T; liquidityToken: T; amm: AMMContract }> {
113
+ const { liquidityProviders, swapper, initialBalance, logger } = opts;
114
+
115
+ const { contract: token0 } = await deploy(wallet, admin, 0n, logger);
116
+ const { contract: token1 } = await deploy(wallet, admin, 0n, logger);
117
+ const { contract: liquidityToken } = await deploy(wallet, admin, 0n, logger);
118
+
119
+ const { contract: amm } = await AMMContract.deploy(
120
+ wallet,
121
+ token0.address,
122
+ token1.address,
123
+ liquidityToken.address,
124
+ ).send({ from: admin });
125
+
126
+ // TODO(#9480): consider deploying the token by some factory when the AMM is deployed, and making the AMM be the
127
+ // minter there.
128
+ await liquidityToken.methods.set_minter(amm.address, true).send({ from: admin });
129
+
130
+ for (const lp of liquidityProviders) {
131
+ await mintTokensToPrivate(token0, admin, lp, initialBalance);
132
+ await mintTokensToPrivate(token1, admin, lp, initialBalance);
133
+ }
134
+ // Note that the swapper only holds token0, not token1.
135
+ await mintTokensToPrivate(token0, admin, swapper, initialBalance);
136
+
137
+ return { token0, token1, liquidityToken, amm };
138
+ }
@@ -336,7 +336,9 @@ export function convertProfileToGHBenchmark(benchmark: ClientFlowBenchmark): Git
336
336
  */
337
337
  export function expectedExecutionSteps(apps: number): number {
338
338
  const kernels = Math.ceil(apps / MAX_APPS_PER_KERNEL);
339
- return apps + kernels + 1 /* final reset */ + 1 /* tail */ + 1 /* hiding */;
339
+ // The final reset and tail are proved as a single circuit (reset_tail or reset_tail_to_public),
340
+ // so they share one execution step.
341
+ return apps + kernels + 1 /* reset+tail */ + 1 /* hiding */;
340
342
  }
341
343
 
342
344
  export async function captureProfile(
@@ -4,6 +4,7 @@ import { FeeJuicePaymentMethodWithClaim } from '@aztec/aztec.js/fee';
4
4
  import { type FeePaymentMethod, PrivateFeePaymentMethod, SponsoredFeePaymentMethod } from '@aztec/aztec.js/fee';
5
5
  import { type Logger, createLogger } from '@aztec/aztec.js/log';
6
6
  import type { AztecNode } from '@aztec/aztec.js/node';
7
+ import { FeeJuiceContract } from '@aztec/aztec.js/protocol';
7
8
  import type { Wallet } from '@aztec/aztec.js/wallet';
8
9
  import { CheatCodes, getTokenAllowedSetupFunctions } from '@aztec/aztec/testing';
9
10
  import { createExtendedL1Client } from '@aztec/ethereum/client';
@@ -13,23 +14,26 @@ import { deployL1Contract } from '@aztec/ethereum/deploy-l1-contract';
13
14
  import { ChainMonitor } from '@aztec/ethereum/test';
14
15
  import { randomBytes } from '@aztec/foundation/crypto/random';
15
16
  import { Fr } from '@aztec/foundation/curves/bn254';
17
+ import { GrumpkinScalar } from '@aztec/foundation/curves/grumpkin';
16
18
  import { EthAddress } from '@aztec/foundation/eth-address';
17
19
  import { TestERC20Abi } from '@aztec/l1-artifacts/TestERC20Abi';
18
20
  import { TestERC20Bytecode } from '@aztec/l1-artifacts/TestERC20Bytecode';
19
21
  import { AMMContract } from '@aztec/noir-contracts.js/AMM';
20
22
  import { FPCContract } from '@aztec/noir-contracts.js/FPC';
21
- import { FeeJuiceContract } from '@aztec/noir-contracts.js/FeeJuice';
22
23
  import { SponsoredFPCContract } from '@aztec/noir-contracts.js/SponsoredFPC';
23
- import { TokenContract as BananaCoin, TokenContract } from '@aztec/noir-contracts.js/Token';
24
- import { ProtocolContractAddress } from '@aztec/protocol-contracts';
25
- import { getCanonicalFeeJuice } from '@aztec/protocol-contracts/fee-juice';
24
+ import { TestTokenContract as BananaCoin, TestTokenContract } from '@aztec/noir-test-contracts.js/TestToken';
26
25
  import { type PXEConfig, getPXEConfig } from '@aztec/pxe/server';
27
26
  import type { ContractInstanceWithAddress } from '@aztec/stdlib/contract';
28
- import { GasSettings } from '@aztec/stdlib/gas';
29
- import { deriveSigningKey } from '@aztec/stdlib/keys';
27
+ import { Gas, GasSettings } from '@aztec/stdlib/gas';
28
+ import { AppTaggingSecretKind } from '@aztec/stdlib/logs';
30
29
 
31
- import { AUTOMINE_E2E_OPTS, MNEMONIC, getPaddedMaxFeesPerGas } from '../../fixtures/fixtures.js';
32
- import { type EndToEndContext, type SetupOptions, deployAccounts, setup, teardown } from '../../fixtures/setup.js';
30
+ import {
31
+ AUTOMINE_E2E_OPTS,
32
+ L1_DIRECT_WRITE_ACCOUNT_INDEX,
33
+ MNEMONIC,
34
+ getPaddedMaxFeesPerGas,
35
+ } from '../../fixtures/fixtures.js';
36
+ import { type EndToEndContext, type SetupOptions, setup, teardown } from '../../fixtures/setup.js';
33
37
  import { mintTokensToPrivate } from '../../fixtures/token_utils.js';
34
38
  import { setupSponsoredFPC } from '../../fixtures/utils.js';
35
39
  import { CrossChainTestHarness } from '../../shared/cross_chain_test_harness.js';
@@ -71,13 +75,13 @@ export class ClientFlowsBenchmark {
71
75
  public bananaFPC!: FPCContract;
72
76
  public bananaFPCInstance!: ContractInstanceWithAddress;
73
77
  // Random asset we want to trade
74
- public candyBarCoin!: TokenContract;
78
+ public candyBarCoin!: TestTokenContract;
75
79
  public candyBarCoinInstance!: ContractInstanceWithAddress;
76
80
  // AMM contract
77
81
  public amm!: AMMContract;
78
82
  public ammInstance!: ContractInstanceWithAddress;
79
83
  // Liquidity token for AMM
80
- public liquidityToken!: TokenContract;
84
+ public liquidityToken!: TestTokenContract;
81
85
  public liquidityTokenInstance!: ContractInstanceWithAddress;
82
86
  // Sponsored FPC contract
83
87
  public sponsoredFPC!: SponsoredFPCContract;
@@ -134,11 +138,11 @@ export class ClientFlowsBenchmark {
134
138
  async setup() {
135
139
  this.logger.info('Setting up subsystems from fresh');
136
140
  // Token allowlist entries are test-only: FPC-based fee payment with custom tokens won't work on mainnet alpha.
137
- const tokenAllowList = await getTokenAllowedSetupFunctions();
138
- this.context = await setup(0, {
141
+ // BananaCoin is the codegen'd TestToken here, so the allowlist must key on its class, not canonical Token's.
142
+ const tokenAllowList = await getTokenAllowedSetupFunctions(BananaCoin.artifact);
143
+ this.context = await setup(2, {
139
144
  ...this.setupOptions,
140
145
  fundSponsoredFPC: true,
141
- skipAccountDeployment: true,
142
146
  l1ContractsArgs: this.setupOptions,
143
147
  txPublicSetupAllowListExtend: [...(this.setupOptions.txPublicSetupAllowListExtend ?? []), ...tokenAllowList],
144
148
  });
@@ -186,7 +190,7 @@ export class ClientFlowsBenchmark {
186
190
 
187
191
  let benchysPrivateSigningKey;
188
192
  if (type === 'schnorr') {
189
- benchysPrivateSigningKey = deriveSigningKey(benchysSecret);
193
+ benchysPrivateSigningKey = GrumpkinScalar.random();
190
194
  return wallet.createSchnorrAccount(benchysSecret, salt, benchysPrivateSigningKey);
191
195
  } else if (type === 'ecdsar1') {
192
196
  benchysPrivateSigningKey = randomBytes(32);
@@ -203,15 +207,7 @@ export class ClientFlowsBenchmark {
203
207
 
204
208
  async applyInitialAccounts() {
205
209
  this.logger.info('Applying initial accounts setup');
206
- const { deployedAccounts } = await deployAccounts(
207
- 2,
208
- this.logger,
209
- )({
210
- wallet: this.context.wallet,
211
- initialFundedAccounts: this.context.initialFundedAccounts,
212
- });
213
-
214
- const [{ address: adminAddress }, { address: sequencerAddress }] = deployedAccounts;
210
+ const [adminAddress, sequencerAddress] = this.context.accounts;
215
211
 
216
212
  this.adminWallet = this.context.wallet;
217
213
  this.aztecNode = this.context.aztecNodeService;
@@ -220,8 +216,7 @@ export class ClientFlowsBenchmark {
220
216
  this.adminAddress = adminAddress;
221
217
  this.sequencerAddress = sequencerAddress;
222
218
 
223
- const canonicalFeeJuice = await getCanonicalFeeJuice();
224
- this.feeJuiceContract = FeeJuiceContract.at(canonicalFeeJuice.address, this.adminWallet);
219
+ this.feeJuiceContract = FeeJuiceContract.withWallet(this.adminWallet);
225
220
  this.coinbase = EthAddress.random();
226
221
 
227
222
  const userPXEConfig = getPXEConfig();
@@ -234,17 +229,38 @@ export class ClientFlowsBenchmark {
234
229
  loggers: {
235
230
  prover: this.proxyLogger.createLogger('pxe:bb:wasm:bundle:proxied'),
236
231
  },
232
+ // The benchmark measures steady-state app cost, not first-send discovery cost. Reproduce the pre-handshake-default
233
+ // behavior of unconstrained delivery: derive the tagging secret from the (sender, recipient) key pair via ECDH
234
+ // instead of taking the current default (a non-interactive handshake, which injects two extra private app
235
+ // executions and a nullifier per cold chain). Constrained delivery is unaffected: the Noir circuit rejects
236
+ // address-derived for constrained, so the hook falls through to a handshake there.
237
+ hooks: {
238
+ resolveTaggingSecretStrategy: ({ deliveryMode }) =>
239
+ Promise.resolve(
240
+ deliveryMode === AppTaggingSecretKind.UNCONSTRAINED
241
+ ? { type: 'address-derived' }
242
+ : { type: 'non-interactive-handshake' },
243
+ ),
244
+ },
237
245
  });
238
246
  }
239
247
 
240
248
  async applySetupFeeJuice() {
241
249
  this.logger.info('Applying fee juice setup');
242
- this.feeJuiceContract = FeeJuiceContract.at(ProtocolContractAddress.FeeJuice, this.adminWallet);
250
+ this.feeJuiceContract = FeeJuiceContract.withWallet(this.adminWallet);
243
251
 
244
252
  this.feeJuiceBridgeTestHarness = await FeeJuicePortalTestingHarnessFactory.create({
245
253
  aztecNode: this.context.aztecNodeService,
246
254
  aztecNodeAdmin: this.context.aztecNodeService,
247
- l1Client: this.context.deployL1ContractsValues.l1Client,
255
+ // Bridge from a dedicated L1 account so its direct writes don't race the sequencer publisher's
256
+ // txs on the deployer account (see L1_DIRECT_WRITE_ACCOUNT_INDEX).
257
+ l1Client: createExtendedL1Client(
258
+ this.context.config.l1RpcUrls,
259
+ MNEMONIC,
260
+ undefined,
261
+ undefined,
262
+ L1_DIRECT_WRITE_ACCOUNT_INDEX,
263
+ ),
248
264
  wallet: this.adminWallet,
249
265
  logger: this.logger,
250
266
  });
@@ -268,7 +284,7 @@ export class ClientFlowsBenchmark {
268
284
 
269
285
  async applyDeployCandyBarToken() {
270
286
  this.logger.info('Applying candy bar token deployment');
271
- const { contract: candyBarCoin, instance: candyBarCoinInstance } = await TokenContract.deploy(
287
+ const { contract: candyBarCoin, instance: candyBarCoinInstance } = await TestTokenContract.deploy(
272
288
  this.adminWallet,
273
289
  this.adminAddress,
274
290
  'CBC',
@@ -338,7 +354,6 @@ export class ClientFlowsBenchmark {
338
354
 
339
355
  public async createAndFundBenchmarkingAccountOnUserWallet(accountType: AccountType) {
340
356
  const benchysAccountManager = await this.createBenchmarkingAccountManager(this.adminWallet, accountType);
341
- const benchysAccount = await benchysAccountManager.getAccount();
342
357
  const benchysAddress = benchysAccountManager.address;
343
358
  const claim = await this.feeJuiceBridgeTestHarness.prepareTokensOnL1(benchysAddress);
344
359
  const behchysDeployMethod = await benchysAccountManager.getDeployMethod();
@@ -348,7 +363,7 @@ export class ClientFlowsBenchmark {
348
363
  });
349
364
  // Register benchy on the user's Wallet, where we're going to be interacting from
350
365
  const accountManager = await this.userWallet.createAccount({
351
- secret: benchysAccount.getSecretKey(),
366
+ secret: benchysAccountManager.getSecretKey(),
352
367
  salt: new Fr(benchysAccountManager.getInstance().salt),
353
368
  contract: benchysAccountManager.getAccountContract(),
354
369
  });
@@ -357,7 +372,7 @@ export class ClientFlowsBenchmark {
357
372
 
358
373
  public async applyDeployAmm() {
359
374
  this.logger.info('Applying AMM deployment');
360
- const { contract: liquidityToken, instance: liquidityTokenInstance } = await TokenContract.deploy(
375
+ const { contract: liquidityToken, instance: liquidityTokenInstance } = await TestTokenContract.deploy(
361
376
  this.adminWallet,
362
377
  this.adminAddress,
363
378
  'LPT',
@@ -389,7 +404,8 @@ export class ClientFlowsBenchmark {
389
404
  // The private fee paying method assembled on the app side requires knowledge of the maximum
390
405
  // fee the user is willing to pay
391
406
  const maxFeesPerGas = await getPaddedMaxFeesPerGas(this.aztecNode);
392
- const gasSettings = GasSettings.fallback({ maxFeesPerGas });
407
+ const gasLimits = Gas.from((await this.aztecNode.getNodeInfo()).txsLimits.gas);
408
+ const gasSettings = GasSettings.fallback({ gasLimits, maxFeesPerGas });
393
409
  return new PrivateFeePaymentMethod(this.bananaFPC.address, sender, wallet, gasSettings);
394
410
  }
395
411
 
@@ -51,6 +51,7 @@ async function main() {
51
51
  // TODO(AD) do we still want to take this from witness.json?
52
52
  witness: witnessStack[i],
53
53
  vk: stepsFromFile[i].vk,
54
+ kind: stepsFromFile[i].kind,
54
55
  timings: {
55
56
  witgen: step.timings.witgen,
56
57
  gateCount: step.timings.gateCount,
@@ -2,8 +2,10 @@ import type { AztecNodeService } from '@aztec/aztec-node';
2
2
  import { AztecAddress } from '@aztec/aztec.js/addresses';
3
3
  import { BatchCall, NO_WAIT, type WaitOpts } from '@aztec/aztec.js/contracts';
4
4
  import { waitForTx } from '@aztec/aztec.js/node';
5
+ import { SlotNumber } from '@aztec/foundation/branded-types';
5
6
  import { mean, stdDev, times } from '@aztec/foundation/collection';
6
7
  import { BenchmarkingContract } from '@aztec/noir-test-contracts.js/Benchmarking';
8
+ import { type Sequencer, type SequencerEvents, SequencerState } from '@aztec/sequencer-client';
7
9
  import type { TxHash } from '@aztec/stdlib/tx';
8
10
  import type { MetricDefinition } from '@aztec/telemetry-client';
9
11
  import type { BenchmarkDataPoint, BenchmarkMetricsType, BenchmarkTelemetryClient } from '@aztec/telemetry-client/bench';
@@ -14,8 +16,13 @@ import path from 'path';
14
16
  import { PIPELINING_SETUP_OPTS } from '../fixtures/fixtures.js';
15
17
  import { type EndToEndContext, type SetupOptions, setup } from '../fixtures/utils.js';
16
18
 
19
+ const MAX_BENCH_WAIT_BLOCKS = 6;
20
+ const BENCH_FINAL_WAIT_TIMEOUT_SECONDS = 10;
21
+ const SEQUENCER_IDLE_TIMEOUT_MS = 60_000;
22
+ const DEFAULT_L1_PUBLISHING_TIME_SECONDS = 12;
23
+
17
24
  /**
18
- * Setup for benchmarks. Initializes a remote node with a single account and deploys a benchmark contract.
25
+ * Setup for benchmarks. Initializes a remote node with a funded hardcoded account and deploys a benchmark contract.
19
26
  */
20
27
  export async function benchmarkSetup(
21
28
  opts: Partial<SetupOptions> & {
@@ -24,11 +31,19 @@ export async function benchmarkSetup(
24
31
  benchOutput?: string;
25
32
  },
26
33
  ) {
27
- const context = await setup(1, { ...PIPELINING_SETUP_OPTS, ...opts, telemetryConfig: { benchmark: true } });
28
- const defaultAccountAddress = context.accounts[0];
29
- const { contract } = await BenchmarkingContract.deploy(context.wallet).send({ from: defaultAccountAddress });
34
+ const context = await setup(1, {
35
+ ...PIPELINING_SETUP_OPTS,
36
+ ...opts,
37
+ telemetryConfig: { benchmark: true },
38
+ });
39
+ const [defaultAccountAddress] = context.accounts;
40
+ const sequencer = getSequencerClient(context);
41
+ await waitForSequencerIdle(sequencer.getSequencer());
42
+ const deployment = BenchmarkingContract.deploy(context.wallet);
43
+ const { txHash } = await deployment.send({ from: defaultAccountAddress, wait: NO_WAIT });
44
+ await waitTxs([txHash], context);
45
+ const contract = await deployment.register();
30
46
  context.logger.info(`Deployed benchmarking contract at ${contract.address}`);
31
- const sequencer = (context.aztecNode as AztecNodeService).getSequencer()!;
32
47
  const telemetry = context.telemetryClient as BenchmarkTelemetryClient;
33
48
  context.logger.warn(`Cleared benchmark data points from setup`);
34
49
  telemetry.clear();
@@ -49,6 +64,14 @@ export async function benchmarkSetup(
49
64
  return { telemetry, context, contract, sequencer };
50
65
  }
51
66
 
67
+ function getSequencerClient(context: EndToEndContext) {
68
+ const sequencer = (context.aztecNode as AztecNodeService).getSequencer();
69
+ if (!sequencer) {
70
+ throw new Error('Benchmark setup requires a local sequencer');
71
+ }
72
+ return sequencer;
73
+ }
74
+
52
75
  type MetricFilter = {
53
76
  source: MetricDefinition;
54
77
  transform: (value: number) => number;
@@ -160,10 +183,90 @@ export async function sendTxs(
160
183
 
161
184
  export async function waitTxs(txs: TxHash[], context: EndToEndContext, txWaitOpts?: WaitOpts) {
162
185
  context.logger.info(`Awaiting ${txs.length} txs to be mined`);
163
- await Promise.all(txs.map(txHash => waitForTx(context.aztecNode, txHash, txWaitOpts)));
186
+ await waitTxsWithBlockMining(txs, context, txWaitOpts);
164
187
  context.logger.info(`${txs.length} txs have been mined`);
165
188
  }
166
189
 
190
+ async function waitTxsWithBlockMining(txs: TxHash[], context: EndToEndContext, txWaitOpts?: WaitOpts) {
191
+ const sequencer = getSequencerClient(context).getSequencer();
192
+ for (let attempt = 0; attempt <= MAX_BENCH_WAIT_BLOCKS; attempt++) {
193
+ if (await haveAllTxsMined(txs, context, txWaitOpts)) {
194
+ await waitForSequencerIdle(sequencer);
195
+ return;
196
+ }
197
+ await waitForSequencerIdle(sequencer);
198
+ context.logger.info('Mining next benchmark block while waiting for txs', {
199
+ attempt,
200
+ txs: txs.length,
201
+ });
202
+ await mineNextBenchmarkBlock(context, sequencer);
203
+ }
204
+ await Promise.all(
205
+ txs.map(txHash =>
206
+ waitForTx(context.aztecNode, txHash, {
207
+ ...txWaitOpts,
208
+ timeout: txWaitOpts?.timeout ?? BENCH_FINAL_WAIT_TIMEOUT_SECONDS,
209
+ }),
210
+ ),
211
+ );
212
+ }
213
+
214
+ async function haveAllTxsMined(txs: TxHash[], context: EndToEndContext, txWaitOpts?: WaitOpts): Promise<boolean> {
215
+ const receipts = await Promise.all(txs.map(txHash => context.aztecNode.getTxReceipt(txHash)));
216
+ for (const receipt of receipts) {
217
+ if (receipt.isDropped()) {
218
+ throw new Error(`Transaction ${receipt.txHash.toString()} was dropped. Reason: ${receipt.error ?? 'unknown'}`);
219
+ }
220
+ if (!receipt.isMined()) {
221
+ return false;
222
+ }
223
+ if (!receipt.hasExecutionSucceeded() && !txWaitOpts?.dontThrowOnRevert) {
224
+ throw new Error(
225
+ `Transaction ${receipt.txHash.toString()} reverted: ${receipt.executionResult}. Reason: ${
226
+ receipt.error ?? 'unknown'
227
+ }`,
228
+ );
229
+ }
230
+ }
231
+ return true;
232
+ }
233
+
234
+ async function mineNextBenchmarkBlock(context: EndToEndContext, sequencer: Sequencer) {
235
+ const l1PublishingTime = BigInt(context.config.l1PublishingTime ?? DEFAULT_L1_PUBLISHING_TIME_SECONDS);
236
+ const currentTimestamp = BigInt(await context.cheatCodes.eth.lastBlockTimestamp());
237
+ let targetSlot = SlotNumber((await context.cheatCodes.rollup.getSlot()) + 1);
238
+ let targetTimestamp = await context.cheatCodes.rollup.getTimestampForSlot(targetSlot);
239
+ while (targetTimestamp - l1PublishingTime - 1n <= currentTimestamp) {
240
+ targetSlot = SlotNumber(targetSlot + 1);
241
+ targetTimestamp = await context.cheatCodes.rollup.getTimestampForSlot(targetSlot);
242
+ }
243
+
244
+ const triggerTimestamp = targetTimestamp - l1PublishingTime - 1n;
245
+ await context.cheatCodes.eth.warp(triggerTimestamp, { resetBlockInterval: true });
246
+ await context.aztecNode.mineBlock();
247
+ await waitForSequencerIdle(sequencer);
248
+ }
249
+
250
+ function waitForSequencerIdle(sequencer: Sequencer, timeout = SEQUENCER_IDLE_TIMEOUT_MS): Promise<void> {
251
+ if (sequencer.status().state === SequencerState.IDLE) {
252
+ return Promise.resolve();
253
+ }
254
+ return new Promise((resolve, reject) => {
255
+ const timer = setTimeout(() => {
256
+ sequencer.off('state-changed', handler);
257
+ reject(new Error('Timeout waiting for sequencer IDLE state'));
258
+ }, timeout);
259
+ const handler = (args: Parameters<SequencerEvents['state-changed']>[0]) => {
260
+ if (args.newState === SequencerState.IDLE) {
261
+ clearTimeout(timer);
262
+ sequencer.off('state-changed', handler);
263
+ resolve();
264
+ }
265
+ };
266
+ sequencer.on('state-changed', handler);
267
+ });
268
+ }
269
+
167
270
  function randomBytesAsBigInts(length: number): bigint[] {
168
271
  return [...Array(length)].map(_ => BigInt(Math.floor(Math.random() * 255)));
169
272
  }