@aztec/end-to-end 0.0.1-commit.0c875d939 → 0.0.1-commit.0dc957cde

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 (165) hide show
  1. package/README.md +27 -0
  2. package/dest/bench/client_flows/client_flows_benchmark.d.ts +1 -1
  3. package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
  4. package/dest/bench/client_flows/client_flows_benchmark.js +21 -28
  5. package/dest/bench/utils.d.ts +1 -1
  6. package/dest/bench/utils.d.ts.map +1 -1
  7. package/dest/bench/utils.js +6 -3
  8. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +3 -2
  9. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts.map +1 -1
  10. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.js +15 -15
  11. package/dest/e2e_epochs/epochs_test.d.ts +26 -7
  12. package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
  13. package/dest/e2e_epochs/epochs_test.js +113 -43
  14. package/dest/e2e_fees/fees_test.d.ts +1 -1
  15. package/dest/e2e_fees/fees_test.d.ts.map +1 -1
  16. package/dest/e2e_fees/fees_test.js +16 -9
  17. package/dest/e2e_nested_contract/nested_contract_test.d.ts +1 -1
  18. package/dest/e2e_nested_contract/nested_contract_test.d.ts.map +1 -1
  19. package/dest/e2e_nested_contract/nested_contract_test.js +4 -6
  20. package/dest/e2e_p2p/inactivity_slash_test.js +3 -3
  21. package/dest/e2e_p2p/p2p_network.d.ts +13 -11
  22. package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
  23. package/dest/e2e_p2p/p2p_network.js +70 -34
  24. package/dest/e2e_p2p/reqresp/utils.d.ts +3 -3
  25. package/dest/e2e_p2p/reqresp/utils.d.ts.map +1 -1
  26. package/dest/e2e_p2p/reqresp/utils.js +46 -9
  27. package/dest/e2e_p2p/shared.d.ts +25 -7
  28. package/dest/e2e_p2p/shared.d.ts.map +1 -1
  29. package/dest/e2e_p2p/shared.js +69 -49
  30. package/dest/e2e_token_contract/token_contract_test.d.ts +1 -1
  31. package/dest/e2e_token_contract/token_contract_test.d.ts.map +1 -1
  32. package/dest/e2e_token_contract/token_contract_test.js +11 -11
  33. package/dest/fixtures/authwit_proxy.d.ts +3 -3
  34. package/dest/fixtures/authwit_proxy.d.ts.map +1 -1
  35. package/dest/fixtures/authwit_proxy.js +4 -0
  36. package/dest/fixtures/e2e_prover_test.d.ts +6 -5
  37. package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
  38. package/dest/fixtures/e2e_prover_test.js +37 -49
  39. package/dest/fixtures/elu_monitor.d.ts +21 -0
  40. package/dest/fixtures/elu_monitor.d.ts.map +1 -0
  41. package/dest/fixtures/elu_monitor.js +102 -0
  42. package/dest/fixtures/fixtures.d.ts +16 -1
  43. package/dest/fixtures/fixtures.d.ts.map +1 -1
  44. package/dest/fixtures/fixtures.js +16 -0
  45. package/dest/fixtures/get_bb_config.d.ts +1 -1
  46. package/dest/fixtures/get_bb_config.d.ts.map +1 -1
  47. package/dest/fixtures/get_bb_config.js +5 -5
  48. package/dest/fixtures/ha_setup.d.ts +2 -2
  49. package/dest/fixtures/ha_setup.d.ts.map +1 -1
  50. package/dest/fixtures/ha_setup.js +1 -1
  51. package/dest/fixtures/schnorr_hardcoded_account_contract.d.ts +25 -0
  52. package/dest/fixtures/schnorr_hardcoded_account_contract.d.ts.map +1 -0
  53. package/dest/fixtures/schnorr_hardcoded_account_contract.js +39 -0
  54. package/dest/fixtures/setup.d.ts +45 -17
  55. package/dest/fixtures/setup.d.ts.map +1 -1
  56. package/dest/fixtures/setup.js +88 -99
  57. package/dest/fixtures/setup_p2p_test.d.ts +10 -7
  58. package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
  59. package/dest/fixtures/setup_p2p_test.js +18 -15
  60. package/dest/fixtures/token_utils.d.ts +2 -2
  61. package/dest/fixtures/token_utils.d.ts.map +1 -1
  62. package/dest/fixtures/token_utils.js +5 -7
  63. package/dest/forward-compatibility/wallet_rpc_client.d.ts +7 -0
  64. package/dest/forward-compatibility/wallet_rpc_client.d.ts.map +1 -0
  65. package/dest/forward-compatibility/wallet_rpc_client.js +15 -0
  66. package/dest/forward-compatibility/wallet_service.d.ts +3 -0
  67. package/dest/forward-compatibility/wallet_service.d.ts.map +1 -0
  68. package/dest/forward-compatibility/wallet_service.js +109 -0
  69. package/dest/legacy-jest-resolver.d.cts +3 -0
  70. package/dest/legacy-jest-resolver.d.cts.map +1 -0
  71. package/dest/shared/cross_chain_test_harness.d.ts +1 -1
  72. package/dest/shared/cross_chain_test_harness.d.ts.map +1 -1
  73. package/dest/shared/cross_chain_test_harness.js +13 -13
  74. package/dest/shared/gas_portal_test_harness.js +3 -3
  75. package/dest/shared/jest_setup.js +41 -1
  76. package/dest/shared/submit-transactions.js +1 -1
  77. package/dest/shared/uniswap_l1_l2.d.ts +1 -1
  78. package/dest/shared/uniswap_l1_l2.d.ts.map +1 -1
  79. package/dest/shared/uniswap_l1_l2.js +14 -21
  80. package/dest/simulators/lending_simulator.d.ts +1 -1
  81. package/dest/simulators/lending_simulator.d.ts.map +1 -1
  82. package/dest/simulators/lending_simulator.js +4 -4
  83. package/dest/simulators/token_simulator.d.ts +1 -1
  84. package/dest/simulators/token_simulator.d.ts.map +1 -1
  85. package/dest/simulators/token_simulator.js +2 -2
  86. package/dest/spartan/setup_test_wallets.d.ts +11 -2
  87. package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
  88. package/dest/spartan/setup_test_wallets.js +97 -38
  89. package/dest/spartan/tx_metrics.js +1 -1
  90. package/dest/spartan/utils/bot.d.ts +3 -2
  91. package/dest/spartan/utils/bot.d.ts.map +1 -1
  92. package/dest/spartan/utils/bot.js +2 -1
  93. package/dest/spartan/utils/config.d.ts +7 -1
  94. package/dest/spartan/utils/config.d.ts.map +1 -1
  95. package/dest/spartan/utils/config.js +3 -1
  96. package/dest/spartan/utils/index.d.ts +4 -2
  97. package/dest/spartan/utils/index.d.ts.map +1 -1
  98. package/dest/spartan/utils/index.js +5 -1
  99. package/dest/spartan/utils/k8s.d.ts +3 -1
  100. package/dest/spartan/utils/k8s.d.ts.map +1 -1
  101. package/dest/spartan/utils/k8s.js +6 -0
  102. package/dest/spartan/utils/nodes.d.ts +4 -5
  103. package/dest/spartan/utils/nodes.d.ts.map +1 -1
  104. package/dest/spartan/utils/nodes.js +9 -9
  105. package/dest/spartan/utils/pod_logs.d.ts +25 -0
  106. package/dest/spartan/utils/pod_logs.d.ts.map +1 -0
  107. package/dest/spartan/utils/pod_logs.js +74 -0
  108. package/dest/test-wallet/test_wallet.d.ts +24 -23
  109. package/dest/test-wallet/test_wallet.d.ts.map +1 -1
  110. package/dest/test-wallet/test_wallet.js +119 -82
  111. package/dest/test-wallet/wallet_worker_script.d.ts +2 -0
  112. package/dest/test-wallet/wallet_worker_script.d.ts.map +1 -0
  113. package/dest/test-wallet/wallet_worker_script.js +48 -0
  114. package/dest/test-wallet/worker_wallet.d.ts +52 -0
  115. package/dest/test-wallet/worker_wallet.d.ts.map +1 -0
  116. package/dest/test-wallet/worker_wallet.js +151 -0
  117. package/dest/test-wallet/worker_wallet_schema.d.ts +279 -0
  118. package/dest/test-wallet/worker_wallet_schema.d.ts.map +1 -0
  119. package/dest/test-wallet/worker_wallet_schema.js +10 -0
  120. package/package.json +43 -44
  121. package/src/bench/client_flows/client_flows_benchmark.ts +29 -12
  122. package/src/bench/utils.ts +7 -2
  123. package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +21 -20
  124. package/src/e2e_epochs/epochs_test.ts +131 -70
  125. package/src/e2e_fees/fees_test.ts +17 -8
  126. package/src/e2e_nested_contract/nested_contract_test.ts +6 -4
  127. package/src/e2e_p2p/inactivity_slash_test.ts +3 -3
  128. package/src/e2e_p2p/p2p_network.ts +88 -44
  129. package/src/e2e_p2p/reqresp/utils.ts +58 -9
  130. package/src/e2e_p2p/shared.ts +88 -63
  131. package/src/e2e_token_contract/token_contract_test.ts +16 -8
  132. package/src/fixtures/authwit_proxy.ts +4 -0
  133. package/src/fixtures/dumps/epoch_proof_result.json +1 -1
  134. package/src/fixtures/e2e_prover_test.ts +43 -52
  135. package/src/fixtures/elu_monitor.ts +126 -0
  136. package/src/fixtures/fixtures.ts +32 -0
  137. package/src/fixtures/get_bb_config.ts +7 -6
  138. package/src/fixtures/ha_setup.ts +4 -2
  139. package/src/fixtures/schnorr_hardcoded_account_contract.ts +49 -0
  140. package/src/fixtures/setup.ts +125 -132
  141. package/src/fixtures/setup_p2p_test.ts +17 -25
  142. package/src/fixtures/token_utils.ts +3 -3
  143. package/src/forward-compatibility/wallet_rpc_client.ts +14 -0
  144. package/src/forward-compatibility/wallet_service.ts +104 -0
  145. package/src/guides/up_quick_start.sh +0 -2
  146. package/src/legacy-jest-resolver.cjs +135 -0
  147. package/src/shared/cross_chain_test_harness.ts +13 -9
  148. package/src/shared/gas_portal_test_harness.ts +1 -2
  149. package/src/shared/jest_setup.ts +51 -1
  150. package/src/shared/submit-transactions.ts +1 -1
  151. package/src/shared/uniswap_l1_l2.ts +35 -32
  152. package/src/simulators/lending_simulator.ts +8 -4
  153. package/src/simulators/token_simulator.ts +6 -2
  154. package/src/spartan/setup_test_wallets.ts +138 -31
  155. package/src/spartan/tx_metrics.ts +1 -1
  156. package/src/spartan/utils/bot.ts +3 -0
  157. package/src/spartan/utils/config.ts +2 -0
  158. package/src/spartan/utils/index.ts +7 -0
  159. package/src/spartan/utils/k8s.ts +8 -0
  160. package/src/spartan/utils/nodes.ts +15 -10
  161. package/src/spartan/utils/pod_logs.ts +99 -0
  162. package/src/test-wallet/test_wallet.ts +148 -101
  163. package/src/test-wallet/wallet_worker_script.ts +60 -0
  164. package/src/test-wallet/worker_wallet.ts +214 -0
  165. package/src/test-wallet/worker_wallet_schema.ts +13 -0
@@ -1,12 +1,14 @@
1
1
  import { SchnorrAccountContractArtifact } from '@aztec/accounts/schnorr';
2
2
  import { type InitialAccountData, generateSchnorrAccounts } from '@aztec/accounts/testing';
3
- import { type Archiver, createArchiver } from '@aztec/archiver';
4
3
  import { type AztecNodeConfig, AztecNodeService, getConfigEnvVars } from '@aztec/aztec-node';
4
+ import { NO_FROM } from '@aztec/aztec.js/account';
5
5
  import { AztecAddress, EthAddress } from '@aztec/aztec.js/addresses';
6
6
  import {
7
7
  BatchCall,
8
8
  type ContractFunctionInteraction,
9
9
  type ContractMethod,
10
+ type DeployInteractionWaitOptions,
11
+ type DeployOptions,
10
12
  getContractClassFromArtifact,
11
13
  waitForProven,
12
14
  } from '@aztec/aztec.js/contracts';
@@ -15,8 +17,7 @@ import { Fr } from '@aztec/aztec.js/fields';
15
17
  import { type Logger, createLogger } from '@aztec/aztec.js/log';
16
18
  import type { AztecNode } from '@aztec/aztec.js/node';
17
19
  import type { Wallet } from '@aztec/aztec.js/wallet';
18
- import { AnvilTestWatcher, CheatCodes } from '@aztec/aztec/testing';
19
- import { createBlobClientWithFileStores } from '@aztec/blob-client/client';
20
+ import { AnvilTestWatcher, type AnvilTestWatcherOpts, CheatCodes } from '@aztec/aztec/testing';
20
21
  import { SPONSORED_FPC_SALT } from '@aztec/constants';
21
22
  import { isAnvilTestChain } from '@aztec/ethereum/chain';
22
23
  import { createExtendedL1Client } from '@aztec/ethereum/client';
@@ -30,13 +31,9 @@ import {
30
31
  type ZKPassportArgs,
31
32
  deployAztecL1Contracts,
32
33
  } from '@aztec/ethereum/deploy-aztec-l1-contracts';
33
- import {
34
- DelayedTxUtils,
35
- EthCheatCodes,
36
- EthCheatCodesWithState,
37
- createDelayedL1TxUtilsFromViemWallet,
38
- startAnvil,
39
- } from '@aztec/ethereum/test';
34
+ import type { Delayer } from '@aztec/ethereum/l1-tx-utils';
35
+ import { EthCheatCodes, EthCheatCodesWithState, startAnvil } from '@aztec/ethereum/test';
36
+ import type { Anvil } from '@aztec/ethereum/test';
40
37
  import { BlockNumber, EpochNumber } from '@aztec/foundation/branded-types';
41
38
  import { SecretValue } from '@aztec/foundation/config';
42
39
  import { randomBytes } from '@aztec/foundation/crypto/random';
@@ -45,21 +42,19 @@ import { withLoggerBindings } from '@aztec/foundation/log/server';
45
42
  import { retryUntil } from '@aztec/foundation/retry';
46
43
  import { sleep } from '@aztec/foundation/sleep';
47
44
  import { DateProvider, TestDateProvider } from '@aztec/foundation/timer';
48
- import type { DataStoreConfig } from '@aztec/kv-store/config';
49
45
  import { SponsoredFPCContract } from '@aztec/noir-contracts.js/SponsoredFPC';
50
46
  import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
51
47
  import type { P2PClientDeps } from '@aztec/p2p';
52
48
  import { MockGossipSubNetwork, getMockPubSubP2PServiceFactory } from '@aztec/p2p/test-helpers';
53
49
  import { protocolContractsHash } from '@aztec/protocol-contracts';
54
- import { type ProverNode, type ProverNodeConfig, type ProverNodeDeps, createProverNode } from '@aztec/prover-node';
50
+ import type { ProverNodeConfig } from '@aztec/prover-node';
55
51
  import { type PXEConfig, getPXEConfig } from '@aztec/pxe/server';
56
52
  import type { SequencerClient } from '@aztec/sequencer-client';
57
- import type { TestSequencerClient } from '@aztec/sequencer-client/test';
58
53
  import { type ContractInstanceWithAddress, getContractInstanceFromInstantiationParams } from '@aztec/stdlib/contract';
59
- import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
54
+ import type { AztecNodeAdmin, AztecNodeDebug } from '@aztec/stdlib/interfaces/client';
60
55
  import { tryStop } from '@aztec/stdlib/interfaces/server';
61
- import type { P2PClientType } from '@aztec/stdlib/p2p';
62
56
  import type { PublicDataTreeLeaf } from '@aztec/stdlib/trees';
57
+ import type { GenesisData } from '@aztec/stdlib/world-state';
63
58
  import {
64
59
  type TelemetryClient,
65
60
  type TelemetryClientConfig,
@@ -70,7 +65,6 @@ import { BenchmarkTelemetryClient } from '@aztec/telemetry-client/bench';
70
65
  import { deployFundedSchnorrAccounts } from '@aztec/wallets/testing';
71
66
  import { getGenesisValues } from '@aztec/world-state/testing';
72
67
 
73
- import type { Anvil } from '@viem/anvil';
74
68
  import fs from 'fs/promises';
75
69
  import { tmpdir } from 'os';
76
70
  import path from 'path';
@@ -187,14 +181,22 @@ export type SetupOptions = {
187
181
  proverNodeConfig?: Partial<ProverNodeConfig>;
188
182
  /** Whether to use a mock gossip sub network for p2p clients. */
189
183
  mockGossipSubNetwork?: boolean;
184
+ /** Whether to add simulated latency to the mock gossipsub network (in ms) */
185
+ mockGossipSubNetworkLatency?: number;
190
186
  /** Whether to disable the anvil test watcher (can still be manually started) */
191
187
  disableAnvilTestWatcher?: boolean;
188
+ anvilTestWatcherOpts?: AnvilTestWatcherOpts;
192
189
  /** Whether to enable anvil automine during deployment of L1 contracts (consider defaulting this to true). */
193
190
  automineL1Setup?: boolean;
194
191
  /** How many accounts to seed and unlock in anvil. */
195
192
  anvilAccounts?: number;
196
193
  /** Port to start anvil (defaults to 8545) */
197
194
  anvilPort?: number;
195
+ /**
196
+ * Number of slots per epoch for Anvil's finality simulation.
197
+ * Anvil reports `finalized = latest - slotsInAnEpoch * 2`.
198
+ */
199
+ anvilSlotsInAnEpoch?: number;
198
200
  /** Key to use for publishing L1 contracts */
199
201
  l1PublisherKey?: SecretValue<`0x${string}`>;
200
202
  /** ZkPassport configuration (domain, scope, mock verifier) */
@@ -205,8 +207,11 @@ export type SetupOptions = {
205
207
  skipAccountDeployment?: boolean;
206
208
  /** L1 contracts deployment arguments. */
207
209
  l1ContractsArgs?: Partial<DeployAztecL1ContractsArgs>;
208
- /** Wallet minimum fee padding multiplier (defaults to 0.5, which is 50% padding). */
210
+ /** Wallet minimum fee padding multiplier */
209
211
  walletMinFeePadding?: number;
212
+ /** Whether the initial node should be a lightweight RPC-only node (no sequencer, no validator).
213
+ * Use for tests that create their own validator nodes and don't need the initial sequencer. */
214
+ skipInitialSequencer?: boolean;
210
215
  } & Partial<AztecNodeConfig>;
211
216
 
212
217
  /** Context for an end-to-end test as returned by the `setup` function */
@@ -214,13 +219,13 @@ export type EndToEndContext = {
214
219
  /** The Anvil instance (only set if anvil was started locally). */
215
220
  anvil: Anvil | undefined;
216
221
  /** The Aztec Node service or client a connected to it. */
217
- aztecNode: AztecNode;
222
+ aztecNode: AztecNode & AztecNodeDebug;
218
223
  /** The Aztec Node as a service. */
219
224
  aztecNodeService: AztecNodeService;
220
225
  /** Client to the Aztec Node admin interface. */
221
226
  aztecNodeAdmin: AztecNodeAdmin;
222
- /** The prover node service (only set if startProverNode is true) */
223
- proverNode: ProverNode | undefined;
227
+ /** The aztec node running the prover node subsystem (only set if startProverNode is true). */
228
+ proverNode: AztecNodeService | undefined;
224
229
  /** A client to the sequencer service. */
225
230
  sequencer: SequencerClient | undefined;
226
231
  /** Return values from deployAztecL1Contracts function. */
@@ -249,8 +254,12 @@ export type EndToEndContext = {
249
254
  telemetryClient: TelemetryClient;
250
255
  /** Mock gossip sub network used for gossipping messages (only if mockGossipSubNetwork was set to true in opts) */
251
256
  mockGossipSubNetwork: MockGossipSubNetwork | undefined;
252
- /** Prefilled public data used for setting up nodes. */
253
- prefilledPublicData: PublicDataTreeLeaf[] | undefined;
257
+ /** Delayer for sequencer L1 txs (only when enableDelayer is true). */
258
+ sequencerDelayer: Delayer | undefined;
259
+ /** Delayer for prover node L1 txs (only when enableDelayer and startProverNode are true). */
260
+ proverDelayer: Delayer | undefined;
261
+ /** Genesis data used for setting up nodes. */
262
+ genesis: GenesisData | undefined;
254
263
  /** ACVM config (only set if running locally). */
255
264
  acvmConfig: Awaited<ReturnType<typeof getACVMConfig>>;
256
265
  /** BB config (only set if running locally). */
@@ -276,7 +285,7 @@ export async function setup(
276
285
  let anvil: Anvil | undefined;
277
286
  try {
278
287
  opts.aztecTargetCommitteeSize ??= 0;
279
- opts.slasherFlavor ??= 'none';
288
+ opts.slasherEnabled ??= false;
280
289
 
281
290
  const config: AztecNodeConfig & SetupOptions = { ...getConfigEnvVars(), ...opts };
282
291
  // use initialValidators for the node config
@@ -288,6 +297,8 @@ export async function setup(
288
297
  config.realProofs = !!opts.realProofs;
289
298
  // Only enforce the time table if requested
290
299
  config.enforceTimeTable = !!opts.enforceTimeTable;
300
+ // Enable the tx delayer for tests (default config has it disabled, so we force-enable it here)
301
+ config.enableDelayer = true;
291
302
  config.listenAddress = '127.0.0.1';
292
303
 
293
304
  config.minTxPoolAgeMs = opts.minTxPoolAgeMs ?? 0;
@@ -301,6 +312,8 @@ export async function setup(
301
312
  config.dataDirectory = directoryToCleanup;
302
313
  }
303
314
 
315
+ const dateProvider = new TestDateProvider();
316
+
304
317
  if (!config.l1RpcUrls?.length) {
305
318
  if (!isAnvilTestChain(chain.id)) {
306
319
  throw new Error(`No ETHEREUM_HOSTS set but non anvil chain requested`);
@@ -309,6 +322,8 @@ export async function setup(
309
322
  l1BlockTime: opts.ethereumSlotDuration,
310
323
  accounts: opts.anvilAccounts,
311
324
  port: opts.anvilPort ?? (process.env.ANVIL_PORT ? parseInt(process.env.ANVIL_PORT) : undefined),
325
+ slotsInAnEpoch: opts.anvilSlotsInAnEpoch,
326
+ dateProvider,
312
327
  });
313
328
  anvil = res.anvil;
314
329
  config.l1RpcUrls = [res.rpcUrl];
@@ -320,8 +335,6 @@ export async function setup(
320
335
  logger.info(`Logging metrics to ${filename}`);
321
336
  setupMetricsLogger(filename);
322
337
  }
323
-
324
- const dateProvider = new TestDateProvider();
325
338
  const ethCheatCodes = new EthCheatCodesWithState(config.l1RpcUrls, dateProvider);
326
339
 
327
340
  if (opts.stateLoad) {
@@ -339,11 +352,11 @@ export async function setup(
339
352
  publisherPrivKeyHex = opts.l1PublisherKey.getValue();
340
353
  publisherHdAccount = privateKeyToAccount(publisherPrivKeyHex);
341
354
  } else if (
342
- config.publisherPrivateKeys &&
343
- config.publisherPrivateKeys.length > 0 &&
344
- config.publisherPrivateKeys[0].getValue() != NULL_KEY
355
+ config.sequencerPublisherPrivateKeys &&
356
+ config.sequencerPublisherPrivateKeys.length > 0 &&
357
+ config.sequencerPublisherPrivateKeys[0].getValue() != NULL_KEY
345
358
  ) {
346
- publisherPrivKeyHex = config.publisherPrivateKeys[0].getValue();
359
+ publisherPrivKeyHex = config.sequencerPublisherPrivateKeys[0].getValue();
347
360
  publisherHdAccount = privateKeyToAccount(publisherPrivKeyHex);
348
361
  } else if (!MNEMONIC) {
349
362
  throw new Error(`Mnemonic not provided and no publisher private key`);
@@ -352,7 +365,7 @@ export async function setup(
352
365
  const publisherPrivKeyRaw = publisherHdAccount.getHdKey().privateKey;
353
366
  const publisherPrivKey = publisherPrivKeyRaw === null ? null : Buffer.from(publisherPrivKeyRaw);
354
367
  publisherPrivKeyHex = `0x${publisherPrivKey!.toString('hex')}` as const;
355
- config.publisherPrivateKeys = [new SecretValue(publisherPrivKeyHex)];
368
+ config.sequencerPublisherPrivateKeys = [new SecretValue(publisherPrivKeyHex)];
356
369
  }
357
370
 
358
371
  if (config.coinbase === undefined) {
@@ -371,10 +384,12 @@ export async function setup(
371
384
  addressesToFund.push(sponsoredFPCAddress);
372
385
  }
373
386
 
374
- const { genesisArchiveRoot, prefilledPublicData, fundingNeeded } = await getGenesisValues(
387
+ const genesisTimestamp = BigInt(Math.floor(Date.now() / 1000));
388
+ const { genesisArchiveRoot, genesis, fundingNeeded } = await getGenesisValues(
375
389
  addressesToFund,
376
390
  opts.initialAccountFeeJuice,
377
391
  opts.genesisPublicData,
392
+ genesisTimestamp,
378
393
  );
379
394
 
380
395
  const wasAutomining = await ethCheatCodes.isAutoMining();
@@ -417,11 +432,12 @@ export async function setup(
417
432
  await ethCheatCodes.setIntervalMining(config.ethereumSlotDuration);
418
433
  }
419
434
 
420
- // Always sync dateProvider to L1 time after deploying L1 contracts, regardless of mining mode.
421
- // In compose mode, L1 time may have drifted ahead of system time due to the local-network watcher
422
- // warping time forward on each filled slot. Without this sync, the sequencer computes the wrong
423
- // slot from its dateProvider and cannot propose blocks.
424
- dateProvider.setTime((await ethCheatCodes.timestamp()) * 1000);
435
+ // In compose mode (no local anvil), sync dateProvider to L1 time since it may have drifted
436
+ // ahead of system time due to the local-network watcher warping time forward on each filled slot.
437
+ // When running with a local anvil, the dateProvider is kept in sync via the stdout listener.
438
+ if (!anvil) {
439
+ dateProvider.setTime((await ethCheatCodes.lastBlockTimestamp()) * 1000);
440
+ }
425
441
 
426
442
  if (opts.l2StartTime) {
427
443
  await ethCheatCodes.warp(opts.l2StartTime, { resetBlockInterval: true });
@@ -432,6 +448,7 @@ export async function setup(
432
448
  deployL1ContractsValues.l1ContractAddresses.rollupAddress,
433
449
  deployL1ContractsValues.l1Client,
434
450
  dateProvider,
451
+ opts.anvilTestWatcherOpts,
435
452
  );
436
453
  if (!opts.disableAnvilTestWatcher) {
437
454
  await watcher.start();
@@ -459,10 +476,10 @@ export async function setup(
459
476
  }
460
477
 
461
478
  let mockGossipSubNetwork: MockGossipSubNetwork | undefined;
462
- let p2pClientDeps: P2PClientDeps<P2PClientType.Full> | undefined = undefined;
479
+ let p2pClientDeps: P2PClientDeps | undefined = undefined;
463
480
 
464
481
  if (opts.mockGossipSubNetwork) {
465
- mockGossipSubNetwork = new MockGossipSubNetwork();
482
+ mockGossipSubNetwork = new MockGossipSubNetwork(opts.mockGossipSubNetworkLatency);
466
483
  p2pClientDeps = { p2pServiceFactory: getMockPubSubP2PServiceFactory(mockGossipSubNetwork) };
467
484
  }
468
485
 
@@ -490,45 +507,53 @@ export async function setup(
490
507
  }
491
508
  }
492
509
 
510
+ // When skipInitialSequencer is set, the initial node is a lightweight RPC-only node.
511
+ // We apply these overrides to a copy so they don't leak into the returned config.
512
+ // Keep P2P enabled if mockGossipSubNetwork is used (needed for tx propagation to validators).
513
+ const initialNodeConfig = opts.skipInitialSequencer
514
+ ? {
515
+ ...config,
516
+ disableValidator: true,
517
+ ...(opts.mockGossipSubNetwork ? {} : { p2pEnabled: false, bootstrapNodes: [] as string[] }),
518
+ }
519
+ : config;
520
+
493
521
  const aztecNodeService = await withLoggerBindings({ actor: 'node-0' }, () =>
494
522
  AztecNodeService.createAndSync(
495
- config,
523
+ initialNodeConfig,
496
524
  { dateProvider, telemetry: telemetryClient, p2pClientDeps },
497
- { prefilledPublicData },
525
+ { genesis, dontStartSequencer: opts.skipInitialSequencer },
498
526
  ),
499
527
  );
500
528
  const sequencerClient = aztecNodeService.getSequencer();
501
529
 
502
- if (sequencerClient) {
503
- const publisher = (sequencerClient as TestSequencerClient).sequencer.publisher;
504
- publisher.l1TxUtils = DelayedTxUtils.fromL1TxUtils(publisher.l1TxUtils, config.ethereumSlotDuration, l1Client);
505
- }
506
-
507
- let proverNode: ProverNode | undefined = undefined;
530
+ let proverNode: AztecNodeService | undefined = undefined;
508
531
  if (opts.startProverNode) {
509
532
  logger.verbose('Creating and syncing a simulated prover node...');
510
533
  const proverNodePrivateKey = getPrivateKeyFromIndex(2);
511
534
  const proverNodePrivateKeyHex: Hex = `0x${proverNodePrivateKey!.toString('hex')}`;
512
535
  const proverNodeDataDirectory = path.join(directoryToCleanup, randomBytes(8).toString('hex'));
513
- const proverNodeConfig = {
514
- ...config.proverNodeConfig,
515
- dataDirectory: proverNodeDataDirectory,
516
- p2pEnabled: !!mockGossipSubNetwork,
536
+
537
+ const p2pClientDeps: Partial<P2PClientDeps> = {
538
+ p2pServiceFactory: mockGossipSubNetwork && getMockPubSubP2PServiceFactory(mockGossipSubNetwork!),
539
+ rpcTxProviders: [aztecNodeService],
517
540
  };
518
- proverNode = await createAndSyncProverNode(
541
+
542
+ ({ proverNode } = await createAndSyncProverNode(
519
543
  proverNodePrivateKeyHex,
520
544
  config,
521
- proverNodeConfig,
522
- aztecNodeService,
523
- prefilledPublicData,
524
545
  {
525
- p2pClientDeps: mockGossipSubNetwork
526
- ? { p2pServiceFactory: getMockPubSubP2PServiceFactory(mockGossipSubNetwork) }
527
- : undefined,
546
+ ...config.proverNodeConfig,
547
+ dataDirectory: proverNodeDataDirectory,
528
548
  },
529
- );
549
+ { dateProvider, p2pClientDeps, telemetry: telemetryClient },
550
+ { genesis },
551
+ ));
530
552
  }
531
553
 
554
+ const sequencerDelayer = sequencerClient?.getDelayer();
555
+ const proverDelayer = proverNode?.getProverNode()?.getDelayer();
556
+
532
557
  logger.verbose('Creating a pxe...');
533
558
  const pxeConfig = { ...getPXEConfig(), ...pxeOpts };
534
559
  pxeConfig.dataDirectory = path.join(directoryToCleanup, randomBytes(8).toString('hex'));
@@ -558,7 +583,9 @@ export async function setup(
558
583
 
559
584
  let accounts: AztecAddress[] = [];
560
585
 
561
- if (shouldDeployAccounts) {
586
+ if (opts.skipInitialSequencer) {
587
+ logger.info('Sequencer not started on initial node, skipping block progression');
588
+ } else if (shouldDeployAccounts) {
562
589
  logger.info(
563
590
  `${numberOfAccounts} accounts are being deployed. Reliably progressing past genesis by setting minTxsPerBlock to 1 and waiting for the accounts to be deployed`,
564
591
  );
@@ -627,8 +654,10 @@ export async function setup(
627
654
  initialFundedAccounts,
628
655
  logger,
629
656
  mockGossipSubNetwork,
630
- prefilledPublicData,
657
+ genesis,
631
658
  proverNode,
659
+ sequencerDelayer,
660
+ proverDelayer,
632
661
  sequencer: sequencerClient,
633
662
  teardown,
634
663
  telemetryClient,
@@ -712,81 +741,42 @@ export async function waitForProvenChain(node: AztecNode, targetBlock?: BlockNum
712
741
  );
713
742
  }
714
743
 
744
+ /**
745
+ * Creates an AztecNodeService with the prover node enabled as a subsystem.
746
+ * Returns both the aztec node service (for lifecycle management) and the prover node (for test internals access).
747
+ */
715
748
  export function createAndSyncProverNode(
716
749
  proverNodePrivateKey: `0x${string}`,
717
- aztecNodeConfig: AztecNodeConfig,
718
- proverNodeConfig: Partial<ProverNodeConfig> & Pick<DataStoreConfig, 'dataDirectory'> & { dontStart?: boolean },
719
- aztecNode: AztecNode | undefined,
720
- prefilledPublicData: PublicDataTreeLeaf[] = [],
721
- proverNodeDeps: ProverNodeDeps = {},
722
- ) {
750
+ baseConfig: AztecNodeConfig,
751
+ configOverrides: Pick<AztecNodeConfig, 'dataDirectory'>,
752
+ deps: {
753
+ telemetry?: TelemetryClient;
754
+ dateProvider: DateProvider;
755
+ p2pClientDeps?: P2PClientDeps;
756
+ },
757
+ options: { genesis?: GenesisData; dontStart?: boolean },
758
+ ): Promise<{ proverNode: AztecNodeService }> {
723
759
  return withLoggerBindings({ actor: 'prover-0' }, async () => {
724
- const aztecNodeTxProvider = aztecNode && {
725
- getTxByHash: aztecNode.getTxByHash.bind(aztecNode),
726
- getTxsByHash: aztecNode.getTxsByHash.bind(aztecNode),
727
- stop: () => Promise.resolve(),
728
- };
729
-
730
- const blobClient = await createBlobClientWithFileStores(aztecNodeConfig, createLogger('blob-client:prover-node'));
731
-
732
- const archiverConfig = { ...aztecNodeConfig, dataDirectory: proverNodeConfig.dataDirectory };
733
- const archiver = await createArchiver(
734
- archiverConfig,
735
- { blobClient, dateProvider: proverNodeDeps.dateProvider },
736
- { blockUntilSync: true },
737
- );
738
-
739
- const proverConfig: ProverNodeConfig = {
740
- ...aztecNodeConfig,
741
- txCollectionNodeRpcUrls: [],
742
- realProofs: false,
743
- proverAgentCount: 2,
744
- publisherPrivateKeys: [new SecretValue(proverNodePrivateKey)],
745
- proverNodeMaxPendingJobs: 10,
746
- proverNodeMaxParallelBlocksPerEpoch: 32,
747
- proverNodePollingIntervalMs: 200,
748
- txGatheringIntervalMs: 1000,
749
- txGatheringBatchSize: 10,
750
- txGatheringMaxParallelRequestsPerNode: 10,
751
- txGatheringTimeoutMs: 24_000,
752
- proverNodeFailedEpochStore: undefined,
753
- proverId: EthAddress.fromNumber(1),
754
- proverNodeEpochProvingDelayMs: undefined,
755
- ...proverNodeConfig,
756
- };
757
-
758
- const l1TxUtils = createDelayedL1TxUtils(
759
- aztecNodeConfig,
760
- proverNodePrivateKey,
761
- 'prover-node',
762
- proverNodeDeps.dateProvider,
760
+ const proverNode = await AztecNodeService.createAndSync(
761
+ {
762
+ ...baseConfig,
763
+ ...configOverrides,
764
+ p2pPort: 0,
765
+ enableProverNode: true,
766
+ disableValidator: true,
767
+ proverPublisherPrivateKeys: [new SecretValue(proverNodePrivateKey)],
768
+ },
769
+ deps,
770
+ { genesis: options.genesis, dontStartProverNode: options.dontStart },
763
771
  );
764
772
 
765
- const proverNode = await createProverNode(
766
- proverConfig,
767
- { ...proverNodeDeps, aztecNodeTxProvider, archiver: archiver as Archiver, l1TxUtils },
768
- { prefilledPublicData },
769
- );
770
- getLogger().info(`Created and synced prover node`, { publisherAddress: l1TxUtils.client.account!.address });
771
- if (!proverNodeConfig.dontStart) {
772
- await proverNode.start();
773
+ if (!proverNode.getProverNode()) {
774
+ throw new Error('Prover node subsystem was not created despite enableProverNode being set');
773
775
  }
774
- return proverNode;
775
- });
776
- }
777
776
 
778
- function createDelayedL1TxUtils(
779
- aztecNodeConfig: AztecNodeConfig,
780
- privateKey: `0x${string}`,
781
- logName: string,
782
- dateProvider?: DateProvider,
783
- ) {
784
- const l1Client = createExtendedL1Client(aztecNodeConfig.l1RpcUrls, privateKey, foundry);
785
-
786
- const log = createLogger(logName);
787
- const l1TxUtils = createDelayedL1TxUtilsFromViemWallet(l1Client, log, dateProvider, aztecNodeConfig);
788
- l1TxUtils.enableDelayer(aztecNodeConfig.ethereumSlotDuration);
789
- return l1TxUtils;
777
+ getLogger().info(`Created and synced prover node`);
778
+ return { proverNode };
779
+ });
790
780
  }
791
781
 
792
782
  export type BalancesFn = ReturnType<typeof getBalancesFn>;
@@ -797,7 +787,9 @@ export function getBalancesFn(
797
787
  ): (...addresses: (AztecAddress | { address: AztecAddress })[]) => Promise<bigint[]> {
798
788
  const balances = async (...addressLikes: (AztecAddress | { address: AztecAddress })[]) => {
799
789
  const addresses = addressLikes.map(addressLike => ('address' in addressLike ? addressLike.address : addressLike));
800
- const b = await Promise.all(addresses.map(address => method(address).simulate({ from: address })));
790
+ const b = await Promise.all(
791
+ addresses.map(async address => (await method(address).simulate({ from: address })).result),
792
+ );
801
793
  const debugString = `${symbol} balances: ${addresses.map((address, i) => `${address}: ${b[i]}`).join(', ')}`;
802
794
  logger.verbose(debugString);
803
795
  return b;
@@ -866,7 +858,7 @@ export async function ensureAccountContractsPublished(wallet: Wallet, accountsTo
866
858
  * Returns deployed account data that can be used by tests.
867
859
  */
868
860
  export const deployAccounts =
869
- (numberOfAccounts: number, logger: Logger) =>
861
+ (numberOfAccounts: number, logger: Logger, deployOptions?: Partial<DeployOptions<DeployInteractionWaitOptions>>) =>
870
862
  async ({ wallet, initialFundedAccounts }: { wallet: TestWallet; initialFundedAccounts: InitialAccountData[] }) => {
871
863
  if (initialFundedAccounts.length < numberOfAccounts) {
872
864
  throw new Error(`Cannot deploy more than ${initialFundedAccounts.length} initial accounts.`);
@@ -883,8 +875,9 @@ export const deployAccounts =
883
875
  );
884
876
  const deployMethod = await accountManager.getDeployMethod();
885
877
  await deployMethod.send({
886
- from: AztecAddress.ZERO,
878
+ from: NO_FROM,
887
879
  skipClassPublication: i !== 0, // Publish the contract class at most once.
880
+ ...deployOptions,
888
881
  });
889
882
  }
890
883
 
@@ -915,7 +908,7 @@ export async function publicDeployAccounts(
915
908
 
916
909
  const batch = new BatchCall(wallet, calls);
917
910
 
918
- const txReceipt = await batch.send({ from: accountsToDeploy[0] });
911
+ const { receipt: txReceipt } = await batch.send({ from: accountsToDeploy[0] });
919
912
  if (waitUntilProven) {
920
913
  if (!node) {
921
914
  throw new Error('Need to provide an AztecNode to wait for proven.');
@@ -7,8 +7,7 @@ import { SecretValue } from '@aztec/foundation/config';
7
7
  import { withLoggerBindings } from '@aztec/foundation/log/server';
8
8
  import { bufferToHex } from '@aztec/foundation/string';
9
9
  import type { DateProvider } from '@aztec/foundation/timer';
10
- import type { ProverNodeConfig, ProverNodeDeps } from '@aztec/prover-node';
11
- import type { PublicDataTreeLeaf } from '@aztec/stdlib/trees';
10
+ import type { GenesisData } from '@aztec/stdlib/world-state';
12
11
 
13
12
  import getPort from 'get-port';
14
13
 
@@ -41,7 +40,7 @@ export async function createNodes(
41
40
  bootstrapNodeEnr: string,
42
41
  numNodes: number,
43
42
  bootNodePort: number,
44
- prefilledPublicData?: PublicDataTreeLeaf[],
43
+ genesis?: GenesisData,
45
44
  dataDirectory?: string,
46
45
  metricsPort?: number,
47
46
  indexOffset = 0,
@@ -66,7 +65,7 @@ export async function createNodes(
66
65
  port,
67
66
  bootstrapNodeEnr,
68
67
  validatorIndices,
69
- prefilledPublicData,
68
+ genesis,
70
69
  dataDir,
71
70
  metricsPort,
72
71
  );
@@ -98,7 +97,7 @@ export async function createNode(
98
97
  tcpPort: number,
99
98
  bootstrapNode: string | undefined,
100
99
  addressIndex: number | number[],
101
- prefilledPublicData?: PublicDataTreeLeaf[],
100
+ genesis?: GenesisData,
102
101
  dataDirectory?: string,
103
102
  metricsPort?: number,
104
103
  ) {
@@ -109,7 +108,7 @@ export async function createNode(
109
108
  return await AztecNodeService.createAndSync(
110
109
  validatorConfig,
111
110
  { telemetry, dateProvider },
112
- { prefilledPublicData, dontStartSequencer: config.dontStartSequencer },
111
+ { genesis, dontStartSequencer: config.dontStartSequencer },
113
112
  );
114
113
  });
115
114
  }
@@ -120,7 +119,7 @@ export async function createNonValidatorNode(
120
119
  dateProvider: DateProvider,
121
120
  tcpPort: number,
122
121
  bootstrapNode: string | undefined,
123
- prefilledPublicData?: PublicDataTreeLeaf[],
122
+ genesis?: GenesisData,
124
123
  dataDirectory?: string,
125
124
  metricsPort?: number,
126
125
  ) {
@@ -131,10 +130,10 @@ export async function createNonValidatorNode(
131
130
  ...p2pConfig,
132
131
  disableValidator: true,
133
132
  validatorPrivateKeys: undefined,
134
- publisherPrivateKeys: [],
133
+ sequencerPublisherPrivateKeys: [],
135
134
  };
136
135
  const telemetry = await getEndToEndTestTelemetryClient(metricsPort);
137
- return await AztecNodeService.createAndSync(config, { telemetry, dateProvider }, { prefilledPublicData });
136
+ return await AztecNodeService.createAndSync(config, { telemetry, dateProvider }, { genesis });
138
137
  });
139
138
  }
140
139
 
@@ -143,31 +142,24 @@ export async function createProverNode(
143
142
  tcpPort: number,
144
143
  bootstrapNode: string | undefined,
145
144
  addressIndex: number,
146
- proverNodeDeps: ProverNodeDeps & Required<Pick<ProverNodeDeps, 'dateProvider'>>,
147
- prefilledPublicData?: PublicDataTreeLeaf[],
145
+ deps: { dateProvider: DateProvider },
146
+ genesis?: GenesisData,
148
147
  dataDirectory?: string,
149
148
  metricsPort?: number,
150
- ) {
149
+ ): Promise<{ proverNode: AztecNodeService }> {
151
150
  const actorIndex = proverCounter++;
152
151
  return await withLoggerBindings({ actor: `prover-${actorIndex}` }, async () => {
153
152
  const proverNodePrivateKey = getPrivateKeyFromIndex(ATTESTER_PRIVATE_KEYS_START_INDEX + addressIndex)!;
154
153
  const telemetry = await getEndToEndTestTelemetryClient(metricsPort);
155
154
 
156
- const proverConfig: Partial<ProverNodeConfig> = await createP2PConfig(
157
- config,
158
- bootstrapNode,
159
- tcpPort,
160
- dataDirectory,
161
- );
155
+ const p2pConfig = await createP2PConfig(config, bootstrapNode, tcpPort, dataDirectory);
162
156
 
163
- const aztecNodeRpcTxProvider = undefined;
164
157
  return await createAndSyncProverNode(
165
158
  bufferToHex(proverNodePrivateKey),
166
- config,
167
- { ...proverConfig, dataDirectory },
168
- aztecNodeRpcTxProvider,
169
- prefilledPublicData,
170
- { ...proverNodeDeps, telemetry },
159
+ { ...config, ...p2pConfig },
160
+ { dataDirectory },
161
+ { ...deps, telemetry },
162
+ { genesis },
171
163
  );
172
164
  });
173
165
  }
@@ -215,7 +207,7 @@ export async function createValidatorConfig(
215
207
  ...config,
216
208
  ...p2pConfig,
217
209
  validatorPrivateKeys: new SecretValue(attesterPrivateKeys),
218
- publisherPrivateKeys: [new SecretValue(attesterPrivateKeys[0])],
210
+ sequencerPublisherPrivateKeys: [new SecretValue(attesterPrivateKeys[0])],
219
211
  };
220
212
 
221
213
  return nodeConfig;
@@ -8,7 +8,6 @@ export async function deployToken(wallet: Wallet, admin: AztecAddress, initialAd
8
8
  logger.info(`Deploying Token contract...`);
9
9
  const { contract, instance } = await TokenContract.deploy(wallet, admin, 'TokenName', 'TokenSymbol', 18).send({
10
10
  from: admin,
11
- wait: { returnReceipt: true },
12
11
  });
13
12
 
14
13
  if (initialAdminBalance > 0n) {
@@ -25,8 +24,9 @@ export async function mintTokensToPrivate(
25
24
  minter: AztecAddress,
26
25
  recipient: AztecAddress,
27
26
  amount: bigint,
27
+ additionalScopes?: AztecAddress[],
28
28
  ) {
29
- await token.methods.mint_to_private(recipient, amount).send({ from: minter });
29
+ await token.methods.mint_to_private(recipient, amount).send({ from: minter, additionalScopes });
30
30
  }
31
31
 
32
32
  export async function expectTokenBalance(
@@ -38,7 +38,7 @@ export async function expectTokenBalance(
38
38
  ) {
39
39
  // Then check the balance
40
40
  const contractWithWallet = TokenContract.at(token.address, wallet);
41
- const balance = await contractWithWallet.methods.balance_of_private(owner).simulate({ from: owner });
41
+ const { result: balance } = await contractWithWallet.methods.balance_of_private(owner).simulate({ from: owner });
42
42
  logger.info(`Account ${owner} balance: ${balance}`);
43
43
  expect(balance).toBe(expectedBalance);
44
44
  }
@@ -0,0 +1,14 @@
1
+ import type { Wallet } from '@aztec/aztec.js/wallet';
2
+ import { WalletSchema } from '@aztec/aztec.js/wallet';
3
+ import { createSafeJsonRpcClient, makeFetch } from '@aztec/foundation/json-rpc/client';
4
+
5
+ /**
6
+ * Creates a JSON-RPC client that connects to a remote wallet service.
7
+ * The returned object implements the {@link Wallet} interface, proxying all calls over HTTP to the specified URL.
8
+ */
9
+ export function createWalletClient(url: string): Wallet {
10
+ return createSafeJsonRpcClient<Wallet>(url, WalletSchema, {
11
+ namespaceMethods: 'wallet',
12
+ fetch: makeFetch([1, 2, 3], false),
13
+ });
14
+ }