@aztec/end-to-end 0.0.0-test.1 → 0.0.1-fake-ceab37513c

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 (156) hide show
  1. package/dest/bench/client_flows/benchmark.d.ts +60 -0
  2. package/dest/bench/client_flows/benchmark.d.ts.map +1 -0
  3. package/dest/bench/client_flows/benchmark.js +261 -0
  4. package/dest/bench/client_flows/client_flows_benchmark.d.ts +69 -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 +315 -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 +106 -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 +99 -0
  13. package/dest/bench/utils.d.ts +10 -27
  14. package/dest/bench/utils.d.ts.map +1 -1
  15. package/dest/bench/utils.js +27 -43
  16. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +15 -7
  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 +66 -38
  19. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts +10 -18
  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 +34 -53
  22. package/dest/e2e_deploy_contract/deploy_test.d.ts +4 -2
  23. package/dest/e2e_deploy_contract/deploy_test.d.ts.map +1 -1
  24. package/dest/e2e_deploy_contract/deploy_test.js +9 -6
  25. package/dest/e2e_epochs/epochs_test.d.ts +56 -17
  26. package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
  27. package/dest/e2e_epochs/epochs_test.js +222 -42
  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 +60 -0
  31. package/dest/e2e_fees/fees_test.d.ts +16 -5
  32. package/dest/e2e_fees/fees_test.d.ts.map +1 -1
  33. package/dest/e2e_fees/fees_test.js +87 -88
  34. package/dest/e2e_l1_publisher/write_json.d.ts +8 -0
  35. package/dest/e2e_l1_publisher/write_json.d.ts.map +1 -0
  36. package/dest/e2e_l1_publisher/write_json.js +57 -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 +5 -5
  41. package/dest/e2e_nested_contract/nested_contract_test.d.ts.map +1 -1
  42. package/dest/e2e_nested_contract/nested_contract_test.js +19 -14
  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 +132 -0
  46. package/dest/e2e_p2p/p2p_network.d.ts +56 -21
  47. package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
  48. package/dest/e2e_p2p/p2p_network.js +154 -125
  49. package/dest/e2e_p2p/shared.d.ts +41 -3
  50. package/dest/e2e_p2p/shared.d.ts.map +1 -1
  51. package/dest/e2e_p2p/shared.js +146 -6
  52. package/dest/e2e_token_contract/token_contract_test.d.ts +10 -5
  53. package/dest/e2e_token_contract/token_contract_test.d.ts.map +1 -1
  54. package/dest/e2e_token_contract/token_contract_test.js +51 -24
  55. package/dest/{e2e_prover → fixtures}/e2e_prover_test.d.ts +7 -4
  56. package/dest/fixtures/e2e_prover_test.d.ts.map +1 -0
  57. package/dest/{e2e_prover → fixtures}/e2e_prover_test.js +67 -62
  58. package/dest/fixtures/fixtures.d.ts +5 -6
  59. package/dest/fixtures/fixtures.d.ts.map +1 -1
  60. package/dest/fixtures/fixtures.js +4 -3
  61. package/dest/fixtures/get_acvm_config.d.ts.map +1 -1
  62. package/dest/fixtures/get_acvm_config.js +2 -14
  63. package/dest/fixtures/get_bb_config.d.ts.map +1 -1
  64. package/dest/fixtures/get_bb_config.js +8 -15
  65. package/dest/fixtures/l1_to_l2_messaging.d.ts +8 -5
  66. package/dest/fixtures/l1_to_l2_messaging.d.ts.map +1 -1
  67. package/dest/fixtures/l1_to_l2_messaging.js +44 -18
  68. package/dest/fixtures/setup_l1_contracts.d.ts +3 -3
  69. package/dest/fixtures/setup_l1_contracts.d.ts.map +1 -1
  70. package/dest/fixtures/setup_l1_contracts.js +3 -3
  71. package/dest/fixtures/setup_p2p_test.d.ts +14 -6
  72. package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
  73. package/dest/fixtures/setup_p2p_test.js +73 -21
  74. package/dest/fixtures/snapshot_manager.d.ts +8 -3
  75. package/dest/fixtures/snapshot_manager.d.ts.map +1 -1
  76. package/dest/fixtures/snapshot_manager.js +120 -104
  77. package/dest/fixtures/token_utils.d.ts +4 -3
  78. package/dest/fixtures/token_utils.d.ts.map +1 -1
  79. package/dest/fixtures/token_utils.js +24 -7
  80. package/dest/fixtures/utils.d.ts +65 -22
  81. package/dest/fixtures/utils.d.ts.map +1 -1
  82. package/dest/fixtures/utils.js +439 -318
  83. package/dest/fixtures/web3signer.d.ts +5 -0
  84. package/dest/fixtures/web3signer.d.ts.map +1 -0
  85. package/dest/fixtures/web3signer.js +42 -0
  86. package/dest/shared/cross_chain_test_harness.d.ts +28 -18
  87. package/dest/shared/cross_chain_test_harness.d.ts.map +1 -1
  88. package/dest/shared/cross_chain_test_harness.js +97 -41
  89. package/dest/shared/gas_portal_test_harness.d.ts +23 -18
  90. package/dest/shared/gas_portal_test_harness.d.ts.map +1 -1
  91. package/dest/shared/gas_portal_test_harness.js +43 -25
  92. package/dest/shared/submit-transactions.d.ts.map +1 -1
  93. package/dest/shared/uniswap_l1_l2.d.ts +5 -6
  94. package/dest/shared/uniswap_l1_l2.d.ts.map +1 -1
  95. package/dest/shared/uniswap_l1_l2.js +136 -90
  96. package/dest/simulators/lending_simulator.d.ts +5 -6
  97. package/dest/simulators/lending_simulator.d.ts.map +1 -1
  98. package/dest/simulators/lending_simulator.js +11 -15
  99. package/dest/simulators/token_simulator.d.ts +2 -1
  100. package/dest/simulators/token_simulator.d.ts.map +1 -1
  101. package/dest/simulators/token_simulator.js +16 -13
  102. package/dest/spartan/setup_test_wallets.d.ts +8 -1
  103. package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
  104. package/dest/spartan/setup_test_wallets.js +108 -22
  105. package/dest/spartan/utils.d.ts +60 -307
  106. package/dest/spartan/utils.d.ts.map +1 -1
  107. package/dest/spartan/utils.js +200 -115
  108. package/package.json +60 -56
  109. package/src/bench/client_flows/benchmark.ts +341 -0
  110. package/src/bench/client_flows/client_flows_benchmark.ts +422 -0
  111. package/src/bench/client_flows/config.ts +61 -0
  112. package/src/bench/client_flows/data_extractor.ts +111 -0
  113. package/src/bench/utils.ts +26 -52
  114. package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +60 -40
  115. package/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +47 -75
  116. package/src/e2e_deploy_contract/deploy_test.ts +11 -8
  117. package/src/e2e_epochs/epochs_test.ts +276 -54
  118. package/src/e2e_fees/bridging_race.notest.ts +75 -0
  119. package/src/e2e_fees/fees_test.ts +121 -108
  120. package/src/e2e_l1_publisher/write_json.ts +74 -0
  121. package/src/e2e_multi_validator/utils.ts +258 -0
  122. package/src/e2e_nested_contract/nested_contract_test.ts +22 -14
  123. package/src/e2e_p2p/inactivity_slash_test.ts +174 -0
  124. package/src/e2e_p2p/p2p_network.ts +212 -144
  125. package/src/e2e_p2p/shared.ts +234 -14
  126. package/src/e2e_token_contract/token_contract_test.ts +42 -38
  127. package/src/fixtures/dumps/epoch_proof_result.json +1 -1
  128. package/src/{e2e_prover → fixtures}/e2e_prover_test.ts +62 -69
  129. package/src/fixtures/fixtures.ts +4 -3
  130. package/src/fixtures/get_acvm_config.ts +2 -10
  131. package/src/fixtures/get_bb_config.ts +15 -11
  132. package/src/fixtures/l1_to_l2_messaging.ts +53 -23
  133. package/src/fixtures/setup_l1_contracts.ts +5 -6
  134. package/src/fixtures/setup_p2p_test.ts +112 -30
  135. package/src/fixtures/snapshot_manager.ts +150 -102
  136. package/src/fixtures/token_utils.ts +33 -8
  137. package/src/fixtures/utils.ts +530 -352
  138. package/src/fixtures/web3signer.ts +46 -0
  139. package/src/guides/up_quick_start.sh +4 -4
  140. package/src/shared/cross_chain_test_harness.ts +92 -52
  141. package/src/shared/gas_portal_test_harness.ts +47 -31
  142. package/src/shared/uniswap_l1_l2.ts +127 -124
  143. package/src/simulators/lending_simulator.ts +11 -15
  144. package/src/simulators/token_simulator.ts +17 -12
  145. package/src/spartan/DEVELOP.md +116 -0
  146. package/src/spartan/setup_test_wallets.ts +144 -29
  147. package/src/spartan/utils.ts +194 -116
  148. package/dest/e2e_prover/e2e_prover_test.d.ts.map +0 -1
  149. package/dest/sample-dapp/connect.js +0 -12
  150. package/dest/sample-dapp/contracts.js +0 -10
  151. package/dest/sample-dapp/deploy.js +0 -35
  152. package/dest/sample-dapp/index.js +0 -98
  153. package/src/sample-dapp/connect.mjs +0 -16
  154. package/src/sample-dapp/contracts.mjs +0 -14
  155. package/src/sample-dapp/deploy.mjs +0 -40
  156. package/src/sample-dapp/index.mjs +0 -128
@@ -2,25 +2,32 @@ import { SchnorrAccountContractArtifact } from '@aztec/accounts/schnorr';
2
2
  import { deployFundedSchnorrAccounts, generateSchnorrAccounts, getDeployedTestAccounts, getDeployedTestAccountsWallets } from '@aztec/accounts/testing';
3
3
  import { createArchiver } from '@aztec/archiver';
4
4
  import { AztecNodeService, getConfigEnvVars } from '@aztec/aztec-node';
5
- import { AnvilTestWatcher, BatchCall, CheatCodes, FeeJuicePaymentMethod, SignerlessWallet, createAztecNodeClient, createLogger, createPXEClient, deployL1Contracts, makeFetch, waitForPXE } from '@aztec/aztec.js';
6
- import { deployInstance, registerContractClass } from '@aztec/aztec.js/deployment';
5
+ import { BatchCall, createAztecNodeClient, createLogger, createPXEClient, makeFetch, sleep, waitForPXE } from '@aztec/aztec.js';
6
+ import { publishContractClass, publishInstance } from '@aztec/aztec.js/deployment';
7
+ import { AnvilTestWatcher, CheatCodes } from '@aztec/aztec/testing';
7
8
  import { createBlobSinkClient } from '@aztec/blob-sink/client';
8
9
  import { createBlobSinkServer } from '@aztec/blob-sink/server';
9
- import { FEE_JUICE_INITIAL_MINT, GENESIS_ARCHIVE_ROOT, GENESIS_BLOCK_HASH } from '@aztec/constants';
10
- import { ForwarderContract, NULL_KEY, createL1Clients, getL1ContractsConfigEnvVars, isAnvilTestChain, l1Artifacts } from '@aztec/ethereum';
11
- import { DelayedTxUtils, EthCheatCodesWithState, startAnvil } from '@aztec/ethereum/test';
10
+ import { GENESIS_ARCHIVE_ROOT, SPONSORED_FPC_SALT } from '@aztec/constants';
11
+ import { FeeAssetArtifact, NULL_KEY, RollupContract, createExtendedL1Client, deployL1Contracts, deployMulticall3, getL1ContractsConfigEnvVars, isAnvilTestChain } from '@aztec/ethereum';
12
+ import { DelayedTxUtils, EthCheatCodes, EthCheatCodesWithState, createDelayedL1TxUtilsFromViemWallet, startAnvil } from '@aztec/ethereum/test';
13
+ import { SecretValue } from '@aztec/foundation/config';
12
14
  import { randomBytes } from '@aztec/foundation/crypto';
13
15
  import { EthAddress } from '@aztec/foundation/eth-address';
14
16
  import { Fr } from '@aztec/foundation/fields';
17
+ import { tryRmDir } from '@aztec/foundation/fs';
18
+ import { withLogNameSuffix } from '@aztec/foundation/log';
15
19
  import { retryUntil } from '@aztec/foundation/retry';
16
20
  import { TestDateProvider } from '@aztec/foundation/timer';
17
- import { FeeJuiceContract } from '@aztec/noir-contracts.js/FeeJuice';
21
+ import { SponsoredFPCContract } from '@aztec/noir-contracts.js/SponsoredFPC';
18
22
  import { getVKTreeRoot } from '@aztec/noir-protocol-circuits-types/vk-tree';
19
- import { ProtocolContractAddress, protocolContractTreeRoot } from '@aztec/protocol-contracts';
23
+ import { MockGossipSubNetwork, getMockPubSubP2PServiceFactory } from '@aztec/p2p/test-helpers';
24
+ import { protocolContractTreeRoot } from '@aztec/protocol-contracts';
20
25
  import { createProverNode } from '@aztec/prover-node';
21
- import { createPXEService, getPXEServiceConfig } from '@aztec/pxe/server';
22
- import { getContractClassFromArtifact } from '@aztec/stdlib/contract';
23
- import { Gas } from '@aztec/stdlib/gas';
26
+ import { createPXEServiceWithSimulator, getPXEServiceConfig } from '@aztec/pxe/server';
27
+ import { MemoryCircuitRecorder, SimulatorRecorderWrapper, WASMSimulator } from '@aztec/simulator/client';
28
+ import { FileCircuitRecorder } from '@aztec/simulator/testing';
29
+ import { getContractClassFromArtifact, getContractInstanceFromInstantiationParams } from '@aztec/stdlib/contract';
30
+ import { tryStop } from '@aztec/stdlib/interfaces/server';
24
31
  import { getConfigEnvVars as getTelemetryConfig, initTelemetryClient } from '@aztec/telemetry-client';
25
32
  import { BenchmarkTelemetryClient } from '@aztec/telemetry-client/bench';
26
33
  import { getGenesisValues } from '@aztec/world-state/testing';
@@ -28,9 +35,8 @@ import fs from 'fs/promises';
28
35
  import getPort from 'get-port';
29
36
  import { tmpdir } from 'os';
30
37
  import * as path from 'path';
31
- import { inspect } from 'util';
32
38
  import { getContract } from 'viem';
33
- import { mnemonicToAccount, privateKeyToAccount } from 'viem/accounts';
39
+ import { generatePrivateKey, mnemonicToAccount, privateKeyToAccount } from 'viem/accounts';
34
40
  import { foundry } from 'viem/chains';
35
41
  import { MNEMONIC, TEST_PEER_CHECK_INTERVAL_MS } from './fixtures.js';
36
42
  import { getACVMConfig } from './get_acvm_config.js';
@@ -65,14 +71,13 @@ export const getPrivateKeyFromIndex = (index)=>{
65
71
  };
66
72
  export const setupL1Contracts = async (l1RpcUrls, account, logger, args = {}, chain = foundry)=>{
67
73
  const l1Data = await deployL1Contracts(l1RpcUrls, account, chain, logger, {
68
- l2FeeJuiceAddress: ProtocolContractAddress.FeeJuice.toField(),
69
74
  vkTreeRoot: getVKTreeRoot(),
70
75
  protocolContractTreeRoot,
71
76
  genesisArchiveRoot: args.genesisArchiveRoot ?? new Fr(GENESIS_ARCHIVE_ROOT),
72
- genesisBlockHash: args.genesisBlockHash ?? new Fr(GENESIS_BLOCK_HASH),
73
77
  salt: args.salt,
74
78
  initialValidators: args.initialValidators,
75
79
  ...getL1ContractsConfigEnvVars(),
80
+ realVerifier: false,
76
81
  ...args
77
82
  });
78
83
  return l1Data;
@@ -81,35 +86,28 @@ export const setupL1Contracts = async (l1RpcUrls, account, logger, args = {}, ch
81
86
  * Sets up Private eXecution Environment (PXE).
82
87
  * @param aztecNode - An instance of Aztec Node.
83
88
  * @param opts - Partial configuration for the PXE service.
84
- * @param firstPrivKey - The private key of the first account to be created.
85
89
  * @param logger - The logger to be used.
86
90
  * @param useLogSuffix - Whether to add a randomly generated suffix to the PXE debug logs.
87
- * @param proofCreator - An optional proof creator to use
88
- * @returns Private eXecution Environment (PXE), accounts, wallets and logger.
89
- */ export async function setupPXEService(aztecNode, opts = {}, logger = getLogger(), useLogSuffix = false, proofCreator) {
91
+ * @returns Private eXecution Environment (PXE), logger and teardown function.
92
+ */ export async function setupPXEService(aztecNode, opts = {}, logger = getLogger(), useLogSuffix = false) {
90
93
  const pxeServiceConfig = {
91
94
  ...getPXEServiceConfig(),
92
95
  ...opts
93
96
  };
97
+ // For tests we only want proving enabled if specifically requested
98
+ pxeServiceConfig.proverEnabled = !!opts.proverEnabled;
94
99
  // If no data directory provided, create a temp directory and clean up afterwards
95
100
  const configuredDataDirectory = pxeServiceConfig.dataDirectory;
96
101
  if (!configuredDataDirectory) {
97
102
  pxeServiceConfig.dataDirectory = path.join(tmpdir(), randomBytes(8).toString('hex'));
98
103
  }
99
- const pxe = await createPXEService(aztecNode, pxeServiceConfig, useLogSuffix, proofCreator);
100
- const teardown = async ()=>{
101
- if (!configuredDataDirectory) {
102
- try {
103
- await fs.rm(pxeServiceConfig.dataDirectory, {
104
- recursive: true,
105
- force: true,
106
- maxRetries: 3
107
- });
108
- } catch (err) {
109
- logger.warn(`Failed to delete tmp PXE data directory ${pxeServiceConfig.dataDirectory}: ${err}`);
110
- }
111
- }
112
- };
104
+ const simulator = new WASMSimulator();
105
+ const recorder = process.env.CIRCUIT_RECORD_DIR ? new FileCircuitRecorder(process.env.CIRCUIT_RECORD_DIR) : new MemoryCircuitRecorder();
106
+ const simulatorWithRecorder = new SimulatorRecorderWrapper(simulator, recorder);
107
+ const pxe = await createPXEServiceWithSimulator(aztecNode, simulatorWithRecorder, pxeServiceConfig, {
108
+ useLogSuffix
109
+ });
110
+ const teardown = configuredDataDirectory ? ()=>Promise.resolve() : ()=>tryRmDir(pxeServiceConfig.dataDirectory);
113
111
  return {
114
112
  pxe,
115
113
  logger,
@@ -138,16 +136,16 @@ export const setupL1Contracts = async (l1RpcUrls, account, logger, args = {}, ch
138
136
  await waitForPXE(pxeClient, logger);
139
137
  logger.verbose('JSON RPC client connected to PXE');
140
138
  logger.verbose(`Retrieving contract addresses from ${PXE_URL}`);
141
- const l1Contracts = (await pxeClient.getNodeInfo()).l1ContractAddresses;
142
- const { walletClient, publicClient } = createL1Clients(config.l1RpcUrls, account, foundry);
139
+ const { l1ContractAddresses, rollupVersion } = await pxeClient.getNodeInfo();
140
+ const l1Client = createExtendedL1Client(config.l1RpcUrls, account, foundry);
143
141
  const deployL1ContractsValues = {
144
- l1ContractAddresses: l1Contracts,
145
- walletClient,
146
- publicClient
142
+ l1ContractAddresses,
143
+ l1Client,
144
+ rollupVersion
147
145
  };
146
+ const ethCheatCodes = new EthCheatCodes(config.l1RpcUrls);
148
147
  const cheatCodes = await CheatCodes.create(config.l1RpcUrls, pxeClient);
149
148
  const teardown = ()=>Promise.resolve();
150
- await setupCanonicalFeeJuice(pxeClient);
151
149
  logger.verbose('Constructing available wallets from already registered accounts...');
152
150
  const initialFundedAccounts = await getDeployedTestAccounts(pxeClient);
153
151
  const wallets = await getDeployedTestAccountsWallets(pxeClient);
@@ -157,17 +155,21 @@ export const setupL1Contracts = async (l1RpcUrls, account, logger, args = {}, ch
157
155
  }
158
156
  return {
159
157
  aztecNode,
158
+ aztecNodeAdmin: undefined,
160
159
  sequencer: undefined,
161
160
  proverNode: undefined,
162
161
  pxe: pxeClient,
163
162
  deployL1ContractsValues,
164
- accounts: await pxeClient.getRegisteredAccounts(),
165
163
  config,
166
164
  initialFundedAccounts,
165
+ wallets,
167
166
  wallet: wallets[0],
168
- wallets: wallets.slice(0, numberOfAccounts),
167
+ accounts: wallets.slice(0, numberOfAccounts).map((w)=>w.getAddress()),
169
168
  logger,
170
169
  cheatCodes,
170
+ ethCheatCodes,
171
+ prefilledPublicData: undefined,
172
+ mockGossipSubNetwork: undefined,
171
173
  watcher: undefined,
172
174
  dateProvider: undefined,
173
175
  blobSink: undefined,
@@ -180,215 +182,305 @@ export const setupL1Contracts = async (l1RpcUrls, account, logger, args = {}, ch
180
182
  * @param numberOfAccounts - The number of new accounts to be created once the PXE is initiated.
181
183
  * @param opts - Options to pass to the node initialization and to the setup script.
182
184
  * @param pxeOpts - Options to pass to the PXE initialization.
183
- */ export async function setup(numberOfAccounts = 1, opts = {
184
- customForwarderContractAddress: EthAddress.ZERO
185
- }, pxeOpts = {}, chain = foundry) {
186
- const config = {
187
- ...getConfigEnvVars(),
188
- ...opts
189
- };
190
- config.peerCheckIntervalMS = TEST_PEER_CHECK_INTERVAL_MS;
191
- const logger = getLogger();
192
- // Create a temp directory for any services that need it and cleanup later
193
- const directoryToCleanup = path.join(tmpdir(), randomBytes(8).toString('hex'));
194
- await fs.mkdir(directoryToCleanup, {
195
- recursive: true
196
- });
197
- if (!config.dataDirectory) {
198
- config.dataDirectory = directoryToCleanup;
199
- }
185
+ */ export async function setup(numberOfAccounts = 1, opts = {}, pxeOpts = {}, chain = foundry) {
200
186
  let anvil;
201
- if (!config.l1RpcUrls?.length) {
202
- if (!isAnvilTestChain(chain.id)) {
203
- throw new Error(`No ETHEREUM_HOSTS set but non anvil chain requested`);
187
+ try {
188
+ opts.aztecTargetCommitteeSize ??= 0;
189
+ opts.slasherFlavor ??= 'none';
190
+ const config = {
191
+ ...getConfigEnvVars(),
192
+ ...opts
193
+ };
194
+ // use initialValidators for the node config
195
+ config.validatorPrivateKeys = new SecretValue(opts.initialValidators?.map((v)=>v.privateKey) ?? []);
196
+ config.peerCheckIntervalMS = TEST_PEER_CHECK_INTERVAL_MS;
197
+ // For tests we only want proving enabled if specifically requested
198
+ config.realProofs = !!opts.realProofs;
199
+ // Only enforce the time table if requested
200
+ config.enforceTimeTable = !!opts.enforceTimeTable;
201
+ const logger = getLogger();
202
+ // Create a temp directory for any services that need it and cleanup later
203
+ const directoryToCleanup = path.join(tmpdir(), randomBytes(8).toString('hex'));
204
+ await fs.mkdir(directoryToCleanup, {
205
+ recursive: true
206
+ });
207
+ if (!config.dataDirectory) {
208
+ config.dataDirectory = directoryToCleanup;
209
+ }
210
+ if (!config.l1RpcUrls?.length) {
211
+ if (!isAnvilTestChain(chain.id)) {
212
+ throw new Error(`No ETHEREUM_HOSTS set but non anvil chain requested`);
213
+ }
214
+ if (PXE_URL) {
215
+ throw new Error(`PXE_URL provided but no ETHEREUM_HOSTS set. Refusing to run, please set both variables so tests can deploy L1 contracts to the same Anvil instance`);
216
+ }
217
+ const res = await startAnvil({
218
+ l1BlockTime: opts.ethereumSlotDuration,
219
+ accounts: opts.anvilAccounts,
220
+ port: opts.anvilPort
221
+ });
222
+ anvil = res.anvil;
223
+ config.l1RpcUrls = [
224
+ res.rpcUrl
225
+ ];
226
+ }
227
+ // Enable logging metrics to a local file named after the test suite
228
+ if (isMetricsLoggingRequested()) {
229
+ const filename = path.join('log', getJobName() + '.jsonl');
230
+ logger.info(`Logging metrics to ${filename}`);
231
+ setupMetricsLogger(filename);
232
+ }
233
+ const ethCheatCodes = new EthCheatCodesWithState(config.l1RpcUrls);
234
+ if (opts.stateLoad) {
235
+ await ethCheatCodes.loadChainState(opts.stateLoad);
204
236
  }
237
+ if (opts.l1StartTime) {
238
+ await ethCheatCodes.warp(opts.l1StartTime, {
239
+ resetBlockInterval: true
240
+ });
241
+ }
242
+ let publisherPrivKey = undefined;
243
+ let publisherHdAccount = undefined;
244
+ if (opts.l1PublisherKey && opts.l1PublisherKey.getValue() && opts.l1PublisherKey.getValue() != NULL_KEY) {
245
+ publisherHdAccount = privateKeyToAccount(opts.l1PublisherKey.getValue());
246
+ } else if (config.publisherPrivateKeys && config.publisherPrivateKeys.length > 0 && config.publisherPrivateKeys[0].getValue() != NULL_KEY) {
247
+ publisherHdAccount = privateKeyToAccount(config.publisherPrivateKeys[0].getValue());
248
+ } else if (!MNEMONIC) {
249
+ throw new Error(`Mnemonic not provided and no publisher private key`);
250
+ } else {
251
+ publisherHdAccount = mnemonicToAccount(MNEMONIC, {
252
+ addressIndex: 0
253
+ });
254
+ const publisherPrivKeyRaw = publisherHdAccount.getHdKey().privateKey;
255
+ publisherPrivKey = publisherPrivKeyRaw === null ? null : Buffer.from(publisherPrivKeyRaw);
256
+ config.publisherPrivateKeys = [
257
+ new SecretValue(`0x${publisherPrivKey.toString('hex')}`)
258
+ ];
259
+ }
260
+ config.coinbase = EthAddress.fromString(publisherHdAccount.address);
205
261
  if (PXE_URL) {
206
- throw new Error(`PXE_URL provided but no ETHEREUM_HOSTS set. Refusing to run, please set both variables so tests can deploy L1 contracts to the same Anvil instance`);
262
+ // we are setting up against a remote environment, l1 contracts are assumed to already be deployed
263
+ return await setupWithRemoteEnvironment(publisherHdAccount, config, logger, numberOfAccounts);
207
264
  }
208
- const res = await startAnvil({
209
- l1BlockTime: opts.ethereumSlotDuration
210
- });
211
- anvil = res.anvil;
212
- config.l1RpcUrls = [
213
- res.rpcUrl
214
- ];
215
- }
216
- // Enable logging metrics to a local file named after the test suite
217
- if (isMetricsLoggingRequested()) {
218
- const filename = path.join('log', getJobName() + '.jsonl');
219
- logger.info(`Logging metrics to ${filename}`);
220
- setupMetricsLogger(filename);
221
- }
222
- const ethCheatCodes = new EthCheatCodesWithState(config.l1RpcUrls);
223
- if (opts.stateLoad) {
224
- await ethCheatCodes.loadChainState(opts.stateLoad);
225
- }
226
- if (opts.l1StartTime) {
227
- await ethCheatCodes.warp(opts.l1StartTime);
228
- }
229
- let publisherPrivKey = undefined;
230
- let publisherHdAccount = undefined;
231
- if (config.publisherPrivateKey && config.publisherPrivateKey != NULL_KEY) {
232
- publisherHdAccount = privateKeyToAccount(config.publisherPrivateKey);
233
- } else if (!MNEMONIC) {
234
- throw new Error(`Mnemonic not provided and no publisher private key`);
235
- } else {
236
- publisherHdAccount = mnemonicToAccount(MNEMONIC, {
237
- addressIndex: 0
238
- });
239
- const publisherPrivKeyRaw = publisherHdAccount.getHdKey().privateKey;
240
- publisherPrivKey = publisherPrivKeyRaw === null ? null : Buffer.from(publisherPrivKeyRaw);
241
- config.publisherPrivateKey = `0x${publisherPrivKey.toString('hex')}`;
242
- }
243
- // Made as separate values such that keys can change, but for test they will be the same.
244
- config.validatorPrivateKey = config.publisherPrivateKey;
245
- if (PXE_URL) {
246
- // we are setting up against a remote environment, l1 contracts are assumed to already be deployed
247
- return await setupWithRemoteEnvironment(publisherHdAccount, config, logger, numberOfAccounts);
248
- }
249
- // Blob sink service - blobs get posted here and served from here
250
- const blobSinkPort = await getPort();
251
- const blobSink = await createBlobSinkServer({
252
- port: blobSinkPort
253
- });
254
- await blobSink.start();
255
- config.blobSinkUrl = `http://localhost:${blobSinkPort}`;
256
- const initialFundedAccounts = opts.initialFundedAccounts ?? await generateSchnorrAccounts(opts.numberOfInitialFundedAccounts ?? numberOfAccounts);
257
- const { genesisBlockHash, genesisArchiveRoot, prefilledPublicData } = await getGenesisValues(initialFundedAccounts.map((a)=>a.address), opts.initialAccountFeeJuice, opts.genesisPublicData);
258
- const deployL1ContractsValues = opts.deployL1ContractsValues ?? await setupL1Contracts(config.l1RpcUrls, publisherHdAccount, logger, {
259
- ...opts,
260
- genesisArchiveRoot,
261
- genesisBlockHash
262
- }, chain);
263
- config.l1Contracts = deployL1ContractsValues.l1ContractAddresses;
264
- if (opts.fundRewardDistributor) {
265
- // Mints block rewards for 10000 blocks to the rewardDistributor contract
266
- const rewardDistributor = getContract({
267
- address: deployL1ContractsValues.l1ContractAddresses.rewardDistributorAddress.toString(),
268
- abi: l1Artifacts.rewardDistributor.contractAbi,
269
- client: deployL1ContractsValues.publicClient
270
- });
271
- const blockReward = await rewardDistributor.read.BLOCK_REWARD();
272
- const mintAmount = 10_000n * blockReward;
273
- const feeJuice = getContract({
274
- address: deployL1ContractsValues.l1ContractAddresses.feeJuiceAddress.toString(),
275
- abi: l1Artifacts.feeAsset.contractAbi,
276
- client: deployL1ContractsValues.walletClient
265
+ const initialFundedAccounts = opts.initialFundedAccounts ?? await generateSchnorrAccounts(opts.numberOfInitialFundedAccounts ?? numberOfAccounts);
266
+ const { genesisArchiveRoot, prefilledPublicData, fundingNeeded } = await getGenesisValues(initialFundedAccounts.map((a)=>a.address), opts.initialAccountFeeJuice, opts.genesisPublicData);
267
+ const wasAutomining = await ethCheatCodes.isAutoMining();
268
+ const enableAutomine = opts.automineL1Setup && !wasAutomining && isAnvilTestChain(chain.id);
269
+ if (enableAutomine) {
270
+ await ethCheatCodes.setAutomine(true);
271
+ }
272
+ const l1Client = createExtendedL1Client(config.l1RpcUrls, publisherHdAccount, chain);
273
+ await deployMulticall3(l1Client, logger);
274
+ const deployL1ContractsValues = opts.deployL1ContractsValues ?? await setupL1Contracts(config.l1RpcUrls, publisherHdAccount, logger, {
275
+ ...opts,
276
+ genesisArchiveRoot,
277
+ feeJuicePortalInitialBalance: fundingNeeded,
278
+ initialValidators: opts.initialValidators
279
+ }, chain);
280
+ config.l1Contracts = deployL1ContractsValues.l1ContractAddresses;
281
+ config.rollupVersion = deployL1ContractsValues.rollupVersion;
282
+ if (opts.fundRewardDistributor) {
283
+ // Mints block rewards for 10000 blocks to the rewardDistributor contract
284
+ const rollup = new RollupContract(deployL1ContractsValues.l1Client, deployL1ContractsValues.l1ContractAddresses.rollupAddress);
285
+ const blockReward = await rollup.getBlockReward();
286
+ const mintAmount = 10_000n * blockReward;
287
+ const feeJuice = getContract({
288
+ address: deployL1ContractsValues.l1ContractAddresses.feeJuiceAddress.toString(),
289
+ abi: FeeAssetArtifact.contractAbi,
290
+ client: deployL1ContractsValues.l1Client
291
+ });
292
+ const rewardDistributorMintTxHash = await feeJuice.write.mint([
293
+ deployL1ContractsValues.l1ContractAddresses.rewardDistributorAddress.toString(),
294
+ mintAmount
295
+ ], {});
296
+ await deployL1ContractsValues.l1Client.waitForTransactionReceipt({
297
+ hash: rewardDistributorMintTxHash
298
+ });
299
+ logger.info(`Funding rewardDistributor in ${rewardDistributorMintTxHash}`);
300
+ }
301
+ if (enableAutomine) {
302
+ await ethCheatCodes.setAutomine(false);
303
+ await ethCheatCodes.setIntervalMining(config.ethereumSlotDuration);
304
+ }
305
+ if (opts.l2StartTime) {
306
+ // This should only be used in synching test or when you need to have a stable
307
+ // timestamp for the first l2 block.
308
+ await ethCheatCodes.warp(opts.l2StartTime, {
309
+ resetBlockInterval: true
310
+ });
311
+ }
312
+ const dateProvider = new TestDateProvider();
313
+ dateProvider.setTime(await ethCheatCodes.timestamp() * 1000);
314
+ const watcher = new AnvilTestWatcher(new EthCheatCodesWithState(config.l1RpcUrls), deployL1ContractsValues.l1ContractAddresses.rollupAddress, deployL1ContractsValues.l1Client, dateProvider);
315
+ if (!opts.disableAnvilTestWatcher) {
316
+ await watcher.start();
317
+ }
318
+ const telemetry = getTelemetryClient(opts.telemetryConfig);
319
+ // Blob sink service - blobs get posted here and served from here
320
+ const blobSinkPort = await getPort();
321
+ const blobSink = await createBlobSinkServer({
322
+ l1ChainId: config.l1ChainId,
323
+ l1RpcUrls: config.l1RpcUrls,
324
+ l1Contracts: config.l1Contracts,
325
+ port: blobSinkPort,
326
+ dataDirectory: config.dataDirectory,
327
+ dataStoreMapSizeKb: config.dataStoreMapSizeKb
328
+ }, telemetry);
329
+ await blobSink.start();
330
+ config.blobSinkUrl = `http://localhost:${blobSinkPort}`;
331
+ logger.verbose('Creating and synching an aztec node', config);
332
+ const acvmConfig = await getACVMConfig(logger);
333
+ if (acvmConfig) {
334
+ config.acvmWorkingDirectory = acvmConfig.acvmWorkingDirectory;
335
+ config.acvmBinaryPath = acvmConfig.acvmBinaryPath;
336
+ }
337
+ const bbConfig = await getBBConfig(logger);
338
+ if (bbConfig) {
339
+ config.bbBinaryPath = bbConfig.bbBinaryPath;
340
+ config.bbWorkingDirectory = bbConfig.bbWorkingDirectory;
341
+ }
342
+ const blobSinkClient = createBlobSinkClient(config, {
343
+ logger: createLogger('node:blob-sink:client')
277
344
  });
278
- const rewardDistributorMintTxHash = await feeJuice.write.mint([
279
- rewardDistributor.address,
280
- mintAmount
281
- ], {});
282
- await deployL1ContractsValues.publicClient.waitForTransactionReceipt({
283
- hash: rewardDistributorMintTxHash
345
+ let mockGossipSubNetwork;
346
+ let p2pClientDeps = undefined;
347
+ if (opts.mockGossipSubNetwork) {
348
+ mockGossipSubNetwork = new MockGossipSubNetwork();
349
+ p2pClientDeps = {
350
+ p2pServiceFactory: getMockPubSubP2PServiceFactory(mockGossipSubNetwork)
351
+ };
352
+ }
353
+ // Transactions built against the genesis state must be included in block 1, otherwise they are dropped.
354
+ // To avoid test failures from dropped transactions, we ensure progression beyond genesis before proceeding.
355
+ // For account deployments, we set minTxsPerBlock=1 and deploy accounts sequentially for guaranteed success.
356
+ // If no accounts need deployment, we await an empty block to confirm network progression. After either path
357
+ // completes, we restore the original minTxsPerBlock setting. The deployment and waiting for empty block is
358
+ // handled by the if-else branches on line 632.
359
+ // For more details on why the tx would be dropped see `validate_include_by_timestamp` function in
360
+ // `noir-projects/noir-protocol-circuits/crates/rollup-lib/src/base/components/validation_requests.nr`.
361
+ //
362
+ // Note: If the following seems too convoluted or if it starts making problems, we could drop the "progressing
363
+ // past genesis via an account contract deployment" optimization and just call flush() on the sequencer and wait
364
+ // for an empty block to be mined. This would simplify it all quite a bit but the setup would be slower for tests
365
+ // deploying accounts.
366
+ const originalMinTxsPerBlock = config.minTxsPerBlock;
367
+ if (originalMinTxsPerBlock === undefined) {
368
+ throw new Error('minTxsPerBlock is undefined in e2e test setup');
369
+ }
370
+ config.minTxsPerBlock = numberOfAccounts === 0 ? 0 : 1;
371
+ config.p2pEnabled = opts.mockGossipSubNetwork || config.p2pEnabled;
372
+ config.p2pIp = opts.p2pIp ?? config.p2pIp ?? '127.0.0.1';
373
+ if (!config.disableValidator) {
374
+ if ((config.validatorPrivateKeys?.getValue().length ?? 0) === 0) {
375
+ config.validatorPrivateKeys = new SecretValue([
376
+ generatePrivateKey()
377
+ ]);
378
+ }
379
+ }
380
+ const aztecNode = await AztecNodeService.createAndSync(config, {
381
+ dateProvider,
382
+ blobSinkClient,
383
+ telemetry,
384
+ p2pClientDeps,
385
+ logger: createLogger('node:MAIN-aztec-node')
386
+ }, {
387
+ prefilledPublicData
284
388
  });
285
- logger.info(`Funding rewardDistributor in ${rewardDistributorMintTxHash}`);
286
- }
287
- if (opts.l2StartTime) {
288
- // This should only be used in synching test or when you need to have a stable
289
- // timestamp for the first l2 block.
290
- await ethCheatCodes.warp(opts.l2StartTime);
291
- }
292
- const dateProvider = new TestDateProvider();
293
- const watcher = new AnvilTestWatcher(new EthCheatCodesWithState(config.l1RpcUrls), deployL1ContractsValues.l1ContractAddresses.rollupAddress, deployL1ContractsValues.publicClient, dateProvider);
294
- await watcher.start();
295
- logger.verbose('Creating and synching an aztec node...');
296
- const acvmConfig = await getACVMConfig(logger);
297
- if (acvmConfig) {
298
- config.acvmWorkingDirectory = acvmConfig.acvmWorkingDirectory;
299
- config.acvmBinaryPath = acvmConfig.acvmBinaryPath;
300
- }
301
- const bbConfig = await getBBConfig(logger);
302
- if (bbConfig) {
303
- config.bbBinaryPath = bbConfig.bbBinaryPath;
304
- config.bbWorkingDirectory = bbConfig.bbWorkingDirectory;
305
- }
306
- config.l1PublishRetryIntervalMS = 100;
307
- const telemetry = getTelemetryClient(opts.telemetryConfig);
308
- const blobSinkClient = createBlobSinkClient(config);
309
- const aztecNode = await AztecNodeService.createAndSync(config, {
310
- dateProvider,
311
- blobSinkClient
312
- }, {
313
- prefilledPublicData
314
- });
315
- const sequencer = aztecNode.getSequencer();
316
- if (sequencer) {
317
- const publisher = sequencer.sequencer.publisher;
318
- publisher.l1TxUtils = DelayedTxUtils.fromL1TxUtils(publisher.l1TxUtils, config.ethereumSlotDuration);
319
- }
320
- let proverNode = undefined;
321
- if (opts.startProverNode) {
322
- logger.verbose('Creating and syncing a simulated prover node...');
323
- const proverNodePrivateKey = getPrivateKeyFromIndex(2);
324
- const proverNodePrivateKeyHex = `0x${proverNodePrivateKey.toString('hex')}`;
325
- proverNode = await createAndSyncProverNode(proverNodePrivateKeyHex, config, aztecNode, path.join(directoryToCleanup, randomBytes(8).toString('hex')));
326
- }
327
- logger.verbose('Creating a pxe...');
328
- const { pxe, teardown: pxeTeardown } = await setupPXEService(aztecNode, pxeOpts, logger);
329
- if (!config.skipProtocolContracts) {
330
- logger.verbose('Setting up Fee Juice...');
331
- await setupCanonicalFeeJuice(pxe);
332
- }
333
- const accountManagers = await deployFundedSchnorrAccounts(pxe, initialFundedAccounts.slice(0, numberOfAccounts));
334
- const wallets = await Promise.all(accountManagers.map((account)=>account.getWallet()));
335
- if (initialFundedAccounts.length < numberOfAccounts) {
336
- // TODO: Create (numberOfAccounts - initialFundedAccounts.length) wallets without funds.
337
- throw new Error(`Unable to deploy ${numberOfAccounts} accounts. Only ${initialFundedAccounts.length} accounts were funded.`);
338
- }
339
- const cheatCodes = await CheatCodes.create(config.l1RpcUrls, pxe);
340
- const teardown = async ()=>{
341
- await pxeTeardown();
342
- if (aztecNode instanceof AztecNodeService) {
343
- await aztecNode?.stop();
389
+ const sequencerClient = aztecNode.getSequencer();
390
+ if (sequencerClient) {
391
+ const publisher = sequencerClient.sequencer.publisher;
392
+ publisher.l1TxUtils = DelayedTxUtils.fromL1TxUtils(publisher.l1TxUtils, config.ethereumSlotDuration, l1Client);
344
393
  }
345
- if (proverNode) {
346
- await proverNode.stop();
394
+ let proverNode = undefined;
395
+ if (opts.startProverNode) {
396
+ logger.verbose('Creating and syncing a simulated prover node...');
397
+ const proverNodePrivateKey = getPrivateKeyFromIndex(2);
398
+ const proverNodePrivateKeyHex = `0x${proverNodePrivateKey.toString('hex')}`;
399
+ const proverNodeDataDirectory = path.join(directoryToCleanup, randomBytes(8).toString('hex'));
400
+ const proverNodeConfig = {
401
+ ...config.proverNodeConfig,
402
+ dataDirectory: proverNodeDataDirectory
403
+ };
404
+ proverNode = await createAndSyncProverNode(proverNodePrivateKeyHex, config, proverNodeConfig, aztecNode, prefilledPublicData);
347
405
  }
348
- if (acvmConfig?.cleanup) {
349
- // remove the temp directory created for the acvm
350
- logger.verbose(`Cleaning up ACVM state`);
351
- await acvmConfig.cleanup();
406
+ logger.verbose('Creating a pxe...');
407
+ const { pxe, teardown: pxeTeardown } = await setupPXEService(aztecNode, pxeOpts, logger);
408
+ const cheatCodes = await CheatCodes.create(config.l1RpcUrls, pxe);
409
+ if (opts.aztecTargetCommitteeSize && opts.aztecTargetCommitteeSize > 0 || opts.initialValidators && opts.initialValidators.length > 0) {
410
+ // We need to advance such that the committee is set up.
411
+ await cheatCodes.rollup.advanceToEpoch(await cheatCodes.rollup.getEpoch() + BigInt(config.lagInEpochs + 1), {
412
+ updateDateProvider: dateProvider
413
+ });
414
+ await cheatCodes.rollup.setupEpoch();
415
+ await cheatCodes.rollup.debugRollup();
352
416
  }
353
- if (bbConfig?.cleanup) {
354
- // remove the temp directory created for the acvm
355
- logger.verbose(`Cleaning up BB state`);
356
- await bbConfig.cleanup();
417
+ // Below we continue with what we described in the long comment on line 571.
418
+ let accountManagers = [];
419
+ if (numberOfAccounts === 0) {
420
+ logger.info('No accounts are being deployed, waiting for an empty block 1 to be mined');
421
+ while(await pxe.getBlockNumber() === 0){
422
+ await sleep(2000);
423
+ }
424
+ } else {
425
+ logger.info(`${numberOfAccounts} accounts are being deployed. Reliably progressing past genesis by setting minTxsPerBlock to 1 and waiting for the accounts to be deployed`);
426
+ accountManagers = await deployFundedSchnorrAccounts(pxe, initialFundedAccounts.slice(0, numberOfAccounts));
427
+ }
428
+ // Now we restore the original minTxsPerBlock setting.
429
+ sequencerClient.getSequencer().updateConfig({
430
+ minTxsPerBlock: originalMinTxsPerBlock
431
+ });
432
+ const wallets = await Promise.all(accountManagers.map((account)=>account.getWallet()));
433
+ if (initialFundedAccounts.length < numberOfAccounts) {
434
+ // TODO: Create (numberOfAccounts - initialFundedAccounts.length) wallets without funds.
435
+ throw new Error(`Unable to deploy ${numberOfAccounts} accounts. Only ${initialFundedAccounts.length} accounts were funded.`);
357
436
  }
358
- await anvil?.stop().catch((err)=>getLogger().error(err));
359
- await watcher.stop();
360
- await blobSink?.stop();
361
- if (directoryToCleanup) {
437
+ const teardown = async ()=>{
362
438
  try {
363
- logger.verbose(`Cleaning up data directory at ${directoryToCleanup}`);
364
- await fs.rm(directoryToCleanup, {
365
- recursive: true,
366
- force: true,
367
- maxRetries: 3
368
- });
439
+ await pxeTeardown();
440
+ await tryStop(aztecNode, logger);
441
+ await tryStop(proverNode, logger);
442
+ if (acvmConfig?.cleanup) {
443
+ await acvmConfig.cleanup();
444
+ }
445
+ if (bbConfig?.cleanup) {
446
+ await bbConfig.cleanup();
447
+ }
448
+ await tryStop(watcher, logger);
449
+ await tryStop(anvil, logger);
450
+ await tryStop(blobSink, logger);
451
+ await tryRmDir(directoryToCleanup, logger);
369
452
  } catch (err) {
370
- logger.warn(`Failed to delete data directory at ${directoryToCleanup}: ${err}`);
453
+ logger.error(`Error during e2e test teardown`, err);
371
454
  }
372
- }
373
- };
374
- return {
375
- aztecNode,
376
- blobSink,
377
- cheatCodes,
378
- config,
379
- dateProvider,
380
- deployL1ContractsValues,
381
- initialFundedAccounts,
382
- logger,
383
- proverNode,
384
- pxe,
385
- sequencer,
386
- teardown,
387
- telemetryClient: telemetry,
388
- wallet: wallets[0],
389
- wallets,
390
- watcher
391
- };
455
+ };
456
+ return {
457
+ aztecNode,
458
+ aztecNodeAdmin: aztecNode,
459
+ blobSink,
460
+ cheatCodes,
461
+ ethCheatCodes,
462
+ config,
463
+ dateProvider,
464
+ deployL1ContractsValues,
465
+ initialFundedAccounts,
466
+ logger,
467
+ mockGossipSubNetwork,
468
+ prefilledPublicData,
469
+ proverNode,
470
+ pxe,
471
+ sequencer: sequencerClient,
472
+ teardown,
473
+ telemetryClient: telemetry,
474
+ wallets,
475
+ wallet: wallets[0],
476
+ accounts: wallets.map((w)=>w.getAddress()),
477
+ watcher
478
+ };
479
+ } catch (err) {
480
+ // TODO: Just hoisted anvil for now to ensure cleanup. Prob need to hoist the rest.
481
+ await anvil?.stop();
482
+ throw err;
483
+ }
392
484
  }
393
485
  /**
394
486
  * Registers the contract class used for test accounts and publicly deploys the instances requested.
@@ -396,26 +488,28 @@ export const setupL1Contracts = async (l1RpcUrls, account, logger, args = {}, ch
396
488
  * @param sender - Wallet to send the deployment tx.
397
489
  * @param accountsToDeploy - Which accounts to publicly deploy.
398
490
  */ // docs:start:public_deploy_accounts
399
- export async function ensureAccountsPubliclyDeployed(sender, accountsToDeploy) {
491
+ export async function ensureAccountContractsPublished(sender, accountsToDeploy) {
400
492
  // We have to check whether the accounts are already deployed. This can happen if the test runs against
401
493
  // the sandbox and the test accounts exist
402
494
  const accountsAndAddresses = await Promise.all(accountsToDeploy.map(async (account)=>{
403
495
  const address = account.getAddress();
404
496
  return {
405
497
  address,
406
- deployed: (await sender.getContractMetadata(address)).isContractPubliclyDeployed
498
+ deployed: (await sender.getContractMetadata(address)).isContractPublished
407
499
  };
408
500
  }));
409
501
  const instances = (await Promise.all(accountsAndAddresses.filter(({ deployed })=>!deployed).map(({ address })=>sender.getContractMetadata(address)))).map((contractMetadata)=>contractMetadata.contractInstance);
410
502
  const contractClass = await getContractClassFromArtifact(SchnorrAccountContractArtifact);
411
503
  if (!(await sender.getContractClassMetadata(contractClass.id, true)).isContractClassPubliclyRegistered) {
412
- await (await registerContractClass(sender, SchnorrAccountContractArtifact)).send().wait();
504
+ await (await publishContractClass(sender, SchnorrAccountContractArtifact)).send({
505
+ from: accountsToDeploy[0].getAddress()
506
+ }).wait();
413
507
  }
414
- const requests = await Promise.all(instances.map(async (instance)=>(await deployInstance(sender, instance)).request()));
415
- const batch = new BatchCall(sender, [
416
- ...requests
417
- ]);
418
- await batch.send().wait();
508
+ const requests = await Promise.all(instances.map(async (instance)=>await publishInstance(sender, instance)));
509
+ const batch = new BatchCall(sender, requests);
510
+ await batch.send({
511
+ from: accountsToDeploy[0].getAddress()
512
+ }).wait();
419
513
  }
420
514
  // docs:end:public_deploy_accounts
421
515
  /**
@@ -446,10 +540,12 @@ export async function ensureAccountsPubliclyDeployed(sender, accountsToDeploy) {
446
540
  }
447
541
  return createLogger('e2e:' + describeBlockName);
448
542
  }
449
- export function getBalancesFn(symbol, method, logger) {
543
+ export function getBalancesFn(symbol, method, from, logger) {
450
544
  const balances = async (...addressLikes)=>{
451
545
  const addresses = addressLikes.map((addressLike)=>'address' in addressLike ? addressLike.address : addressLike);
452
- const b = await Promise.all(addresses.map((address)=>method(address).simulate()));
546
+ const b = await Promise.all(addresses.map((address)=>method(address).simulate({
547
+ from
548
+ })));
453
549
  const debugString = `${symbol} balances: ${addresses.map((address, i)=>`${address}: ${b[i]}`).join(', ')}`;
454
550
  logger.verbose(debugString);
455
551
  return b;
@@ -468,86 +564,111 @@ export async function expectMappingDelta(initialValues, fn, inputs, expectedDiff
468
564
  expect(diffs).toEqual(expectedDiffs);
469
565
  }
470
566
  /**
471
- * Deploy the protocol contracts to a running instance.
472
- */ export async function setupCanonicalFeeJuice(pxe) {
473
- // "deploy" the Fee Juice as it contains public functions
474
- const feeJuicePortalAddress = (await pxe.getNodeInfo()).l1ContractAddresses.feeJuicePortalAddress;
475
- const wallet = new SignerlessWallet(pxe);
476
- const feeJuice = await FeeJuiceContract.at(ProtocolContractAddress.FeeJuice, wallet);
477
- try {
478
- const paymentMethod = new FeeJuicePaymentMethod(ProtocolContractAddress.FeeJuice);
479
- await feeJuice.methods.initialize(feeJuicePortalAddress, FEE_JUICE_INITIAL_MINT).send({
480
- fee: {
481
- paymentMethod,
482
- gasSettings: {
483
- teardownGasLimits: Gas.empty()
484
- }
485
- }
486
- }).wait();
487
- getLogger().info(`Fee Juice successfully setup. Portal address: ${feeJuicePortalAddress}`);
488
- } catch (error) {
489
- getLogger().warn(`Fee Juice might have already been setup. Got error: ${inspect(error)}.`);
490
- }
567
+ * Computes the address of the "canonical" SponosoredFPCContract. This is not a protocol contract
568
+ * but by conventions its address is computed with a salt of 0.
569
+ * @returns The address of the sponsored FPC contract
570
+ */ export function getSponsoredFPCInstance() {
571
+ return Promise.resolve(getContractInstanceFromInstantiationParams(SponsoredFPCContract.artifact, {
572
+ salt: new Fr(SPONSORED_FPC_SALT)
573
+ }));
574
+ }
575
+ /**
576
+ * Computes the address of the "canonical" SponosoredFPCContract. This is not a protocol contract
577
+ * but by conventions its address is computed with a salt of 0.
578
+ * @returns The address of the sponsored FPC contract
579
+ */ export async function getSponsoredFPCAddress() {
580
+ const sponsoredFPCInstance = await getSponsoredFPCInstance();
581
+ return sponsoredFPCInstance.address;
582
+ }
583
+ /**
584
+ * Deploy a sponsored FPC contract to a running instance.
585
+ */ export async function setupSponsoredFPC(pxe) {
586
+ const instance = await getContractInstanceFromInstantiationParams(SponsoredFPCContract.artifact, {
587
+ salt: new Fr(SPONSORED_FPC_SALT)
588
+ });
589
+ await pxe.registerContract({
590
+ instance,
591
+ artifact: SponsoredFPCContract.artifact
592
+ });
593
+ getLogger().info(`SponsoredFPC: ${instance.address}`);
594
+ return instance;
595
+ }
596
+ /**
597
+ * Registers the SponsoredFPC in this PXE instance
598
+ * @param pxe - The pxe client
599
+ */ export async function registerSponsoredFPC(pxe) {
600
+ await pxe.registerContract({
601
+ instance: await getSponsoredFPCInstance(),
602
+ artifact: SponsoredFPCContract.artifact
603
+ });
491
604
  }
492
605
  export async function waitForProvenChain(node, targetBlock, timeoutSec = 60, intervalSec = 1) {
493
606
  targetBlock ??= await node.getBlockNumber();
494
607
  await retryUntil(async ()=>await node.getProvenBlockNumber() >= targetBlock, 'proven chain status', timeoutSec, intervalSec);
495
608
  }
496
- export async function createAndSyncProverNode(proverNodePrivateKey, aztecNodeConfig, aztecNode, dataDirectory, prefilledPublicData = []) {
497
- // Disable stopping the aztec node as the prover coordination test will kill it otherwise
498
- // This is only required when stopping the prover node for testing
499
- const aztecNodeWithoutStop = {
500
- getTxByHash: aztecNode.getTxByHash.bind(aztecNode),
501
- getTxsByHash: aztecNode.getTxsByHash.bind(aztecNode),
502
- stop: ()=>Promise.resolve()
503
- };
504
- const blobSinkClient = createBlobSinkClient(aztecNodeConfig);
505
- // Creating temp store and archiver for simulated prover node
506
- const archiverConfig = {
507
- ...aztecNodeConfig,
508
- dataDirectory
509
- };
510
- const archiver = await createArchiver(archiverConfig, blobSinkClient, {
511
- blockUntilSync: true
512
- });
513
- // Prover node config is for simulated proofs
514
- const proverConfig = {
515
- ...aztecNodeConfig,
516
- proverCoordinationNodeUrl: undefined,
517
- dataDirectory: undefined,
518
- realProofs: false,
519
- proverAgentCount: 2,
520
- publisherPrivateKey: proverNodePrivateKey,
521
- proverNodeMaxPendingJobs: 10,
522
- proverNodeMaxParallelBlocksPerEpoch: 32,
523
- proverNodePollingIntervalMs: 200,
524
- txGatheringTimeoutMs: 60000,
525
- txGatheringIntervalMs: 1000,
526
- txGatheringMaxParallelRequests: 100
527
- };
528
- const l1TxUtils = createDelayedL1TxUtils(aztecNodeConfig, proverNodePrivateKey, 'prover-node');
529
- const proverNode = await createProverNode(proverConfig, {
530
- aztecNodeTxProvider: aztecNodeWithoutStop,
531
- archiver: archiver,
532
- l1TxUtils
533
- }, {
534
- prefilledPublicData
535
- });
536
- getLogger().info(`Created and synced prover node`, {
537
- publisherAddress: l1TxUtils.walletClient.account.address
609
+ export function createAndSyncProverNode(proverNodePrivateKey, aztecNodeConfig, proverNodeConfig, aztecNode, prefilledPublicData = [], proverNodeDeps = {}) {
610
+ return withLogNameSuffix('prover-node', async ()=>{
611
+ // Disable stopping the aztec node as the prover coordination test will kill it otherwise
612
+ // This is only required when stopping the prover node for testing
613
+ const aztecNodeTxProvider = aztecNode && {
614
+ getTxByHash: aztecNode.getTxByHash.bind(aztecNode),
615
+ getTxsByHash: aztecNode.getTxsByHash.bind(aztecNode),
616
+ stop: ()=>Promise.resolve()
617
+ };
618
+ const blobSinkClient = createBlobSinkClient(aztecNodeConfig);
619
+ // Creating temp store and archiver for simulated prover node
620
+ const archiverConfig = {
621
+ ...aztecNodeConfig,
622
+ dataDirectory: proverNodeConfig.dataDirectory
623
+ };
624
+ const archiver = await createArchiver(archiverConfig, {
625
+ blobSinkClient
626
+ }, {
627
+ blockUntilSync: true
628
+ });
629
+ // Prover node config is for simulated proofs
630
+ const proverConfig = {
631
+ ...aztecNodeConfig,
632
+ txCollectionNodeRpcUrls: [],
633
+ realProofs: false,
634
+ proverAgentCount: 2,
635
+ publisherPrivateKeys: [
636
+ new SecretValue(proverNodePrivateKey)
637
+ ],
638
+ proverNodeMaxPendingJobs: 10,
639
+ proverNodeMaxParallelBlocksPerEpoch: 32,
640
+ proverNodePollingIntervalMs: 200,
641
+ txGatheringIntervalMs: 1000,
642
+ txGatheringBatchSize: 10,
643
+ txGatheringMaxParallelRequestsPerNode: 10,
644
+ txGatheringTimeoutMs: 24_000,
645
+ proverNodeFailedEpochStore: undefined,
646
+ proverId: EthAddress.fromNumber(1),
647
+ proverNodeEpochProvingDelayMs: undefined,
648
+ ...proverNodeConfig
649
+ };
650
+ const l1TxUtils = createDelayedL1TxUtils(aztecNodeConfig, proverNodePrivateKey, 'prover-node', proverNodeDeps.dateProvider);
651
+ const proverNode = await createProverNode(proverConfig, {
652
+ ...proverNodeDeps,
653
+ aztecNodeTxProvider,
654
+ archiver: archiver,
655
+ l1TxUtils
656
+ }, {
657
+ prefilledPublicData
658
+ });
659
+ getLogger().info(`Created and synced prover node`, {
660
+ publisherAddress: l1TxUtils.client.account.address
661
+ });
662
+ if (!proverNodeConfig.dontStart) {
663
+ await proverNode.start();
664
+ }
665
+ return proverNode;
538
666
  });
539
- proverNode.start();
540
- return proverNode;
541
667
  }
542
- function createDelayedL1TxUtils(aztecNodeConfig, privateKey, logName) {
543
- const { publicClient, walletClient } = createL1Clients(aztecNodeConfig.l1RpcUrls, privateKey, foundry);
668
+ function createDelayedL1TxUtils(aztecNodeConfig, privateKey, logName, dateProvider) {
669
+ const l1Client = createExtendedL1Client(aztecNodeConfig.l1RpcUrls, privateKey, foundry);
544
670
  const log = createLogger(logName);
545
- const l1TxUtils = new DelayedTxUtils(publicClient, walletClient, log, aztecNodeConfig);
671
+ const l1TxUtils = createDelayedL1TxUtilsFromViemWallet(l1Client, log, dateProvider, aztecNodeConfig);
546
672
  l1TxUtils.enableDelayer(aztecNodeConfig.ethereumSlotDuration);
547
673
  return l1TxUtils;
548
674
  }
549
- export async function createForwarderContract(aztecNodeConfig, privateKey, rollupAddress) {
550
- const { walletClient, publicClient } = createL1Clients(aztecNodeConfig.l1RpcUrls, privateKey, foundry);
551
- const forwarderContract = await ForwarderContract.create(walletClient.account.address, walletClient, publicClient, createLogger('forwarder'), rollupAddress);
552
- return forwarderContract;
553
- }