@aztec/end-to-end 0.0.1-commit.ffe5b04ea → 0.0.1-commit.fff30aa

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 (89) 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 +3 -4
  5. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +3 -2
  6. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts.map +1 -1
  7. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.js +1 -1
  8. package/dest/e2e_epochs/epochs_test.d.ts +3 -1
  9. package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
  10. package/dest/e2e_epochs/epochs_test.js +5 -2
  11. package/dest/e2e_fees/fees_test.js +1 -1
  12. package/dest/e2e_p2p/inactivity_slash_test.d.ts +1 -1
  13. package/dest/e2e_p2p/inactivity_slash_test.d.ts.map +1 -1
  14. package/dest/e2e_p2p/inactivity_slash_test.js +1 -0
  15. package/dest/e2e_p2p/p2p_network.d.ts +1 -1
  16. package/dest/e2e_p2p/p2p_network.js +1 -1
  17. package/dest/e2e_p2p/shared.d.ts +19 -1
  18. package/dest/e2e_p2p/shared.d.ts.map +1 -1
  19. package/dest/e2e_p2p/shared.js +31 -0
  20. package/dest/fixtures/authwit_proxy.d.ts +1 -1
  21. package/dest/fixtures/authwit_proxy.d.ts.map +1 -1
  22. package/dest/fixtures/authwit_proxy.js +4 -0
  23. package/dest/fixtures/setup.d.ts +9 -5
  24. package/dest/fixtures/setup.d.ts.map +1 -1
  25. package/dest/fixtures/setup.js +13 -9
  26. package/dest/forward-compatibility/wallet_rpc_client.d.ts +7 -0
  27. package/dest/forward-compatibility/wallet_rpc_client.d.ts.map +1 -0
  28. package/dest/forward-compatibility/wallet_rpc_client.js +15 -0
  29. package/dest/forward-compatibility/wallet_service.d.ts +3 -0
  30. package/dest/forward-compatibility/wallet_service.d.ts.map +1 -0
  31. package/dest/forward-compatibility/wallet_service.js +109 -0
  32. package/dest/install_legacy_contracts.d.cts +10 -0
  33. package/dest/install_legacy_contracts.d.cts.map +1 -0
  34. package/dest/legacy-jest-resolver.d.cts +3 -0
  35. package/dest/legacy-jest-resolver.d.cts.map +1 -0
  36. package/dest/shared/jest_setup.js +1 -41
  37. package/dest/shared/submit-transactions.d.ts +1 -1
  38. package/dest/shared/submit-transactions.d.ts.map +1 -1
  39. package/dest/shared/uniswap_l1_l2.d.ts +1 -1
  40. package/dest/shared/uniswap_l1_l2.d.ts.map +1 -1
  41. package/dest/shared/uniswap_l1_l2.js +9 -12
  42. package/dest/simulators/lending_simulator.d.ts +1 -1
  43. package/dest/simulators/lending_simulator.d.ts.map +1 -1
  44. package/dest/simulators/lending_simulator.js +2 -2
  45. package/dest/spartan/setup_test_wallets.d.ts +4 -2
  46. package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
  47. package/dest/spartan/setup_test_wallets.js +24 -12
  48. package/dest/spartan/tx_metrics.js +1 -1
  49. package/dest/spartan/utils/config.d.ts +1 -4
  50. package/dest/spartan/utils/config.d.ts.map +1 -1
  51. package/dest/spartan/utils/config.js +1 -2
  52. package/dest/spartan/utils/nodes.d.ts +5 -4
  53. package/dest/spartan/utils/nodes.d.ts.map +1 -1
  54. package/dest/spartan/utils/nodes.js +9 -9
  55. package/dest/test-wallet/test_wallet.d.ts +24 -23
  56. package/dest/test-wallet/test_wallet.d.ts.map +1 -1
  57. package/dest/test-wallet/test_wallet.js +115 -80
  58. package/dest/test-wallet/worker_wallet.d.ts +4 -4
  59. package/dest/test-wallet/worker_wallet.d.ts.map +1 -1
  60. package/dest/test-wallet/worker_wallet_schema.d.ts +3 -3
  61. package/package.json +45 -43
  62. package/src/bench/client_flows/client_flows_benchmark.ts +3 -3
  63. package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +3 -6
  64. package/src/e2e_epochs/epochs_test.ts +14 -2
  65. package/src/e2e_fees/fees_test.ts +1 -1
  66. package/src/e2e_p2p/inactivity_slash_test.ts +1 -0
  67. package/src/e2e_p2p/p2p_network.ts +1 -1
  68. package/src/e2e_p2p/shared.ts +52 -0
  69. package/src/fixtures/authwit_proxy.ts +4 -0
  70. package/src/fixtures/dumps/epoch_proof_result.json +1 -1
  71. package/src/fixtures/setup.ts +20 -12
  72. package/src/forward-compatibility/wallet_rpc_client.ts +14 -0
  73. package/src/forward-compatibility/wallet_service.ts +104 -0
  74. package/src/install_legacy_contracts.cjs +75 -0
  75. package/src/legacy-jest-resolver.cjs +101 -0
  76. package/src/shared/jest_setup.ts +1 -51
  77. package/src/shared/submit-transactions.ts +4 -1
  78. package/src/shared/uniswap_l1_l2.ts +29 -24
  79. package/src/simulators/lending_simulator.ts +4 -2
  80. package/src/spartan/setup_test_wallets.ts +48 -9
  81. package/src/spartan/tx_metrics.ts +1 -1
  82. package/src/spartan/utils/config.ts +0 -1
  83. package/src/spartan/utils/nodes.ts +10 -15
  84. package/src/test-wallet/test_wallet.ts +144 -99
  85. package/src/test-wallet/worker_wallet.ts +3 -2
  86. package/dest/fixtures/elu_monitor.d.ts +0 -21
  87. package/dest/fixtures/elu_monitor.d.ts.map +0 -1
  88. package/dest/fixtures/elu_monitor.js +0 -102
  89. package/src/fixtures/elu_monitor.ts +0 -126
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env -S node --no-warnings
2
+ /**
3
+ * Standalone entrypoint that spins up a local Aztec network (L1 + node) and exposes a {@link NodeEmbeddedWallet} over
4
+ * JSON-RPC.
5
+ *
6
+ * Intended for forward-compatibility testing: an **old** release image runs this script so that **new** tests can send
7
+ * new artifacts to old runtime code (loadContractArtifact, ACIR simulator, class-ID computation, entrypoint encoding,
8
+ * etc.).
9
+ */
10
+ import { getSchnorrAccountContractAddress } from '@aztec/accounts/schnorr';
11
+ import { getInitialTestAccountsData } from '@aztec/accounts/testing';
12
+ import { createLocalNetwork } from '@aztec/aztec';
13
+ import { Fr } from '@aztec/aztec.js/fields';
14
+ import { WalletSchema } from '@aztec/aztec.js/wallet';
15
+ import { GrumpkinScalar } from '@aztec/foundation/curves/grumpkin';
16
+ import { createNamespacedSafeJsonRpcServer, startHttpRpcServer } from '@aztec/foundation/json-rpc/server';
17
+ import { createLogger } from '@aztec/foundation/log';
18
+ import { AztecNodeApiSchema } from '@aztec/stdlib/interfaces/client';
19
+ import { EmbeddedWallet } from '@aztec/wallets/embedded';
20
+
21
+ const logger = createLogger('wallet-service');
22
+
23
+ const { ETHEREUM_HOSTS = 'http://localhost:8545', NODE_PORT = '8080', WALLET_PORT = '8081' } = process.env;
24
+
25
+ async function main() {
26
+ const l1RpcUrls = ETHEREUM_HOSTS.split(',').map(url => url.trim());
27
+
28
+ // Some tests (e.g. AMM) need 4 accounts but only 3 are funded via genesis. Generate deterministic keys for a 4th
29
+ // account so we can compute its address before network startup and include it in genesis funding. We cannot do this
30
+ // in the test because Wallet interface does not expose account creation functionality (only TestWallet exposes that
31
+ // but that's not used in forward compatibility testing).
32
+ const extraAccountSecret = Fr.fromHexString('0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef');
33
+ const extraAccountSalt = Fr.ZERO;
34
+ const extraAccountSigningKey = GrumpkinScalar.random();
35
+ const extraAccountAddress = await getSchnorrAccountContractAddress(
36
+ extraAccountSecret,
37
+ extraAccountSalt,
38
+ extraAccountSigningKey,
39
+ );
40
+
41
+ logger.info('Starting wallet service...', { l1RpcUrls });
42
+
43
+ // createLocalNetwork deploys L1 contracts, starts the node, and optionally deploys funded test accounts (when
44
+ // TEST_ACCOUNTS=true via env). We are not proving anything just like is done when local network is started by
45
+ // the `aztecStart` function. The extra account address is passed via prefundAddresses so it gets fee juice at genesis.
46
+ const { node, stop: stopNetwork } = await createLocalNetwork(
47
+ { l1RpcUrls, realProofs: false, prefundAddresses: [extraAccountAddress.toString()] },
48
+ logger.info,
49
+ );
50
+
51
+ // Create an ephemeral embedded wallet backed by the local node.
52
+ const wallet = await EmbeddedWallet.create(node, { ephemeral: true });
53
+
54
+ // Re-register the initial test accounts so they are available via wallet.getAccounts(). createLocalNetwork deploys
55
+ // them onchain but uses a temporary wallet that is then stopped.
56
+ //
57
+ // We use the non-lazy import path (@aztec/accounts/testing, not /lazy) to avoid the dynamic JSON import that is
58
+ // incompatible with Node.js import attribute enforcement.
59
+ const testAccountsData = await getInitialTestAccountsData();
60
+ const accounts = await Promise.all(
61
+ testAccountsData.map(({ secret, salt, signingKey }) => wallet.createSchnorrAccount(secret, salt, signingKey)),
62
+ );
63
+
64
+ // Register and deploy the 4th account.
65
+ const extraAccount = await wallet.createSchnorrAccount(extraAccountSecret, extraAccountSalt, extraAccountSigningKey);
66
+ const deployMethod = await extraAccount.getDeployMethod();
67
+ await deployMethod.send({ from: accounts[0].address });
68
+
69
+ logger.info('Embedded wallet created', {
70
+ accounts: [...accounts, extraAccount].map(a => a.address.toString()),
71
+ });
72
+
73
+ // Contract artifacts are large, so allow generous body sizes for RPC requests.
74
+ const rpcOptions = { maxBodySizeBytes: '50mb' };
75
+
76
+ // Serve node RPC
77
+ const nodeRpcServer = createNamespacedSafeJsonRpcServer({ node: [node, AztecNodeApiSchema] }, rpcOptions);
78
+ const nodeHttpServer = await startHttpRpcServer(nodeRpcServer, { port: NODE_PORT });
79
+ logger.info(`Node JSON-RPC server listening on port ${nodeHttpServer.port}`);
80
+
81
+ // Serve wallet RPC
82
+ const walletRpcServer = createNamespacedSafeJsonRpcServer({ wallet: [wallet, WalletSchema] }, rpcOptions);
83
+ const walletHttpServer = await startHttpRpcServer(walletRpcServer, { port: WALLET_PORT });
84
+ logger.info(`Wallet JSON-RPC server listening on port ${walletHttpServer.port}`);
85
+
86
+ const shutdown = async () => {
87
+ logger.info('Shutting down...');
88
+ nodeHttpServer.close();
89
+ walletHttpServer.close();
90
+ await wallet.stop();
91
+ await stopNetwork();
92
+ process.exit(0);
93
+ };
94
+
95
+ // eslint-disable-next-line @typescript-eslint/no-misused-promises
96
+ process.once('SIGINT', shutdown);
97
+ // eslint-disable-next-line @typescript-eslint/no-misused-promises
98
+ process.once('SIGTERM', shutdown);
99
+ }
100
+
101
+ main().catch(err => {
102
+ logger.error('Wallet service failed to start', err);
103
+ process.exit(1);
104
+ });
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env node
2
+ // Installs pinned legacy @aztec/* contract-artifact packages into .legacy-contracts/<version>/.
3
+ //
4
+ // Called from two places:
5
+ // - bootstrap.sh ci-compat-e2e: pre-populates the cache on the host before hermetic test
6
+ // containers launch. The containers run with --net=none (see ci3/docker_isolate), so on-demand
7
+ // installs from inside them fail with EAI_AGAIN.
8
+ // - legacy-jest-resolver.cjs: on-demand install for local dev, where jest runs with network.
9
+ //
10
+ // Idempotent: no-op when all packages are already present.
11
+ /* eslint-disable @typescript-eslint/no-require-imports */
12
+
13
+ const path = require('path');
14
+ const fs = require('fs');
15
+ const { execFileSync } = require('child_process');
16
+
17
+ const REDIRECTED = ['@aztec/noir-contracts.js', '@aztec/noir-test-contracts.js', '@aztec/accounts'];
18
+
19
+ const e2eRoot = path.resolve(__dirname, '..');
20
+
21
+ function cacheRoot(version) {
22
+ return path.join(e2eRoot, '.legacy-contracts', version);
23
+ }
24
+
25
+ function pkgJsonPath(version, pkg) {
26
+ return path.join(cacheRoot(version), 'node_modules', pkg, 'package.json');
27
+ }
28
+
29
+ function installLegacyContracts(version) {
30
+ if (!version) {
31
+ throw new Error('installLegacyContracts: version is required');
32
+ }
33
+ if (REDIRECTED.every(pkg => fs.existsSync(pkgJsonPath(version, pkg)))) {
34
+ return;
35
+ }
36
+
37
+ const cacheDir = cacheRoot(version);
38
+ fs.mkdirSync(cacheDir, { recursive: true });
39
+
40
+ // Seed a standalone package.json so `npm install --prefix` treats cacheRoot as its own project. Without this, npm
41
+ // walks up and finds the yarn-project workspace root, which breaks on `workspace:` protocol deps and risks
42
+ // clobbering the monorepo's node_modules.
43
+ const seed = path.join(cacheDir, 'package.json');
44
+ if (!fs.existsSync(seed)) {
45
+ fs.writeFileSync(seed, JSON.stringify({ name: 'legacy-contracts-cache', private: true }));
46
+ }
47
+
48
+ const specs = REDIRECTED.map(pkg => `${pkg}@${version}`);
49
+ process.stderr.write(`[legacy-contracts] installing ${specs.join(' ')} into ${cacheDir}\n`);
50
+ // --prefix: install into cacheRoot instead of cwd, so the cache is isolated from the monorepo.
51
+ // --no-save: don't write the installed packages back to the seeded package.json.
52
+ // --ignore-scripts: skip lifecycle scripts (preinstall/postinstall) of the legacy packages and their transitive
53
+ // deps; we only want the files on disk, not to run any build steps.
54
+ // --legacy-peer-deps: tolerate peer-dependency mismatches between the pinned legacy @aztec/* graph and whatever
55
+ // current versions npm would otherwise try to reconcile.
56
+ execFileSync(
57
+ 'npm',
58
+ ['install', '--prefix', cacheDir, '--no-save', '--ignore-scripts', '--legacy-peer-deps', ...specs],
59
+ { stdio: 'inherit' },
60
+ );
61
+
62
+ // Verify versions on disk match the requested version.
63
+ for (const pkg of REDIRECTED) {
64
+ const onDisk = JSON.parse(fs.readFileSync(pkgJsonPath(version, pkg), 'utf8')).version;
65
+ if (onDisk !== version) {
66
+ throw new Error(`[legacy-contracts] ${pkg} on disk is ${onDisk}, expected ${version}`);
67
+ }
68
+ }
69
+ }
70
+
71
+ module.exports = { installLegacyContracts, REDIRECTED, cacheRoot };
72
+
73
+ if (require.main === module) {
74
+ installLegacyContracts(process.argv[2]);
75
+ }
@@ -0,0 +1,101 @@
1
+ // Custom Jest resolver. When CONTRACT_ARTIFACTS_VERSION is set, redirects *only* JSON artifact files under
2
+ // @aztec/noir-contracts.js/artifacts/, @aztec/noir-test-contracts.js/artifacts/, and @aztec/accounts/artifacts/ to a local cache of the pinned
3
+ // legacy versions. TypeScript wrapper classes (e.g. Token.ts) continue to load from the current workspace and use the
4
+ // current @aztec/aztec.js — only the artifact JSON (the deployed-contract ABI / bytecode / notes surface) is swapped.
5
+ //
6
+ // Why JSON-only: the JSON artifact is the actual interchange surface a "deployed contract" exposes. The TS wrapper is
7
+ // generated client-side ergonomics that's tightly coupled to the current @aztec/aztec.js API. Redirecting the wrapper
8
+ // would couple this test to a moving aztec.js surface and break at import time on unrelated breaking changes; we want
9
+ // to fail only on actual artifact-compat regressions.
10
+ //
11
+ // Cache population lives in install_legacy_contracts.cjs — invoked lazily here for local dev, and eagerly
12
+ // by bootstrap.sh ci-compat-e2e before hermetic test containers (which run with --net=none) launch.
13
+ //
14
+ // Activated by env var; passthrough otherwise.
15
+ /* eslint-disable @typescript-eslint/no-require-imports */
16
+
17
+ const path = require('path');
18
+ const fs = require('fs');
19
+ const { installLegacyContracts, REDIRECTED, cacheRoot } = require('./install_legacy_contracts.cjs');
20
+
21
+ const version = process.env.CONTRACT_ARTIFACTS_VERSION;
22
+ const cacheDir = version ? cacheRoot(version) : null;
23
+
24
+ function pkgJsonPath(name) {
25
+ return path.join(cacheDir, 'node_modules', name, 'package.json');
26
+ }
27
+
28
+ // Kept in a separate module (not inlined) because bootstrap.sh ci-compat-e2e also calls it directly
29
+ // via `node .../install_legacy_contracts.cjs <version>` to pre-populate the cache on the host before
30
+ // hermetic --net=none test containers launch. Inlining here would force us to duplicate the logic
31
+ // in bash or re-run jest just to trigger the install.
32
+ if (version) {
33
+ installLegacyContracts(version);
34
+ }
35
+
36
+ let bannerPrinted = false;
37
+ const seen = new Set();
38
+
39
+ function printBannerOnce() {
40
+ if (bannerPrinted || !version) {
41
+ return;
42
+ }
43
+ bannerPrinted = true;
44
+ const lines = ['='.repeat(60), `[legacy-contracts][jest] CONTRACT_ARTIFACTS_VERSION=${version}`];
45
+ for (const p of REDIRECTED) {
46
+ const v = JSON.parse(fs.readFileSync(pkgJsonPath(p), 'utf8')).version;
47
+ if (v !== version) {
48
+ throw new Error(`[legacy-contracts] ${p} on disk is ${v}, expected ${version}`);
49
+ }
50
+ lines.push(`[legacy-contracts][jest] redirecting ${p}/artifacts/*.json -> .legacy-contracts/${version}/...`);
51
+ }
52
+ lines.push('='.repeat(60));
53
+ process.stderr.write(lines.join('\n') + '\n');
54
+ }
55
+
56
+ // Match a resolved absolute path against the workspace artifacts dirs and return the legacy cache equivalent, or null
57
+ // if it's not an artifact path we should redirect.
58
+ function legacyArtifactPath(resolved) {
59
+ if (!resolved.endsWith('.json')) {
60
+ return null;
61
+ }
62
+ for (const pkg of REDIRECTED) {
63
+ // pkg = '@aztec/noir-contracts.js' -> match '/noir-contracts.js/artifacts/'
64
+ const dirName = pkg.split('/')[1];
65
+ const marker = `/${dirName}/artifacts/`;
66
+ const idx = resolved.indexOf(marker);
67
+ if (idx === -1) {
68
+ continue;
69
+ }
70
+ const basename = resolved.slice(idx + marker.length);
71
+ return path.join(cacheDir, 'node_modules', pkg, 'artifacts', basename);
72
+ }
73
+ return null;
74
+ }
75
+
76
+ module.exports = function legacyResolver(request, options) {
77
+ // Always run the default resolver first. We only inspect (and possibly rewrite) the *result*; this catches both
78
+ // bare-specifier imports of `@aztec/noir-contracts.js/artifacts/foo.json` and the relative `../artifacts/foo.json`
79
+ // imports inside the workspace TS wrapper classes — both resolve to the same workspace artifact path that we then
80
+ // redirect.
81
+ const resolved = options.defaultResolver(request, options);
82
+ if (!version) {
83
+ return resolved;
84
+ }
85
+ printBannerOnce();
86
+ const legacy = legacyArtifactPath(resolved);
87
+ if (!legacy) {
88
+ return resolved;
89
+ }
90
+ if (!fs.existsSync(legacy)) {
91
+ throw new Error(
92
+ `[legacy-contracts] artifact ${path.basename(legacy)} not present in legacy cache @${version}; ` +
93
+ `the contract may have been added after that release. Pin a newer CONTRACT_ARTIFACTS_VERSION or skip this test.`,
94
+ );
95
+ }
96
+ if (!seen.has(resolved)) {
97
+ seen.add(resolved);
98
+ process.stderr.write(`[legacy-contracts][jest] redirected ${path.basename(legacy)} -> ${legacy}\n`);
99
+ }
100
+ return legacy;
101
+ };
@@ -1,19 +1,8 @@
1
1
  import { createLogger } from '@aztec/aztec.js/log';
2
2
 
3
- import { afterAll, afterEach, beforeEach, expect } from '@jest/globals';
4
- import { readlinkSync } from 'fs';
3
+ import { beforeEach, expect } from '@jest/globals';
5
4
  import { basename } from 'path';
6
5
 
7
- import { EluMonitor } from '../fixtures/elu_monitor.js';
8
-
9
- const eluMonitor = process.env.ELU_MONITOR_FILE
10
- ? new EluMonitor(process.env.ELU_MONITOR_FILE, Number(process.env.ELU_MONITOR_INTERVAL_MS) || undefined)
11
- : undefined;
12
-
13
- if (eluMonitor) {
14
- process.on('exit', () => eluMonitor.stop());
15
- }
16
-
17
6
  beforeEach(() => {
18
7
  const { testPath, currentTestName } = expect.getState();
19
8
  if (!testPath || !currentTestName) {
@@ -21,43 +10,4 @@ beforeEach(() => {
21
10
  }
22
11
  const logger = createLogger(`e2e:${basename(testPath).replace('.test.ts', '')}`);
23
12
  logger.info(`Running test: ${currentTestName}`);
24
- eluMonitor?.startTest(currentTestName);
25
- });
26
-
27
- afterEach(() => {
28
- eluMonitor?.stopTest();
29
- });
30
-
31
- // Log leaked handles after all tests complete. This runs after test-level afterAll hooks,
32
- // so any handles still alive at this point were not properly cleaned up during teardown.
33
- // This diagnostic helps identify the source of exit hangs without masking them.
34
- afterAll(() => {
35
- const handles = (process as any)._getActiveHandles();
36
- if (handles.length > 0) {
37
- const details = handles.map((h: any) => {
38
- const type = h?.constructor?.name ?? typeof h;
39
- const fd = h?.fd ?? h?._handle?.fd ?? '?';
40
- const destroyed = h?.destroyed ?? '?';
41
- const hasRef = typeof h?.hasRef === 'function' ? h.hasRef() : '?';
42
- const localAddr = h?.localAddress ?? '';
43
- const remoteAddr = h?.remoteAddress ?? '';
44
- const localPort = h?.localPort ?? '';
45
- const remotePort = h?.remotePort ?? '';
46
- const proto = Object.getPrototypeOf(h)?.constructor?.name ?? '?';
47
- const keys = Object.keys(h).slice(0, 10).join(',');
48
- let fdTarget = '';
49
- if (typeof fd === 'number') {
50
- try {
51
- fdTarget = ` -> ${readlinkSync(`/proc/self/fd/${fd}`)}`;
52
- } catch {
53
- // ignore
54
- }
55
- }
56
- return ` ${type}(fd=${fd}, destroyed=${destroyed}, hasRef=${hasRef}${fdTarget}) proto=${proto} addr=${localAddr}:${localPort}->${remoteAddr}:${remotePort} keys=[${keys}]`;
57
- });
58
- process.stderr.write(
59
- `\n[jest_setup] WARNING: ${handles.length} handle(s) still active after teardown:\n${details.join('\n')}\n` +
60
- `These may prevent Jest from exiting. Investigate and fix the leak.\n\n`,
61
- );
62
- }
63
13
  });
@@ -19,7 +19,10 @@ export const submitTxsTo = async (
19
19
  times(numTxs, async () => {
20
20
  const accountManager = await wallet.createSchnorrAccount(Fr.random(), Fr.random(), GrumpkinScalar.random());
21
21
  const deployMethod = await accountManager.getDeployMethod();
22
- const { txHash } = await deployMethod.send({ from: submitter, wait: NO_WAIT });
22
+ const { txHash } = await deployMethod.send({
23
+ from: submitter,
24
+ wait: NO_WAIT,
25
+ });
23
26
 
24
27
  logger.info(`Tx sent with hash ${txHash}`);
25
28
  const receipt: TxReceipt = await wallet.getTxReceipt(txHash);
@@ -252,8 +252,12 @@ export const uniswapL1L2TestSuite = (
252
252
  await wethCrossChainHarness.expectPublicBalanceOnL2(uniswapL2Contract.address, 0n);
253
253
 
254
254
  // Since the outbox is only consumable when the epoch is proven, we need to advance to the next epoch.
255
- const block = await aztecNode.getBlock(l2UniswapInteractionReceipt.blockNumber!);
256
- const epoch = await rollup.getEpochNumberForCheckpoint(block!.checkpointNumber);
255
+ const swapResult = (await computeL2ToL1MembershipWitness(
256
+ aztecNode,
257
+ swapPrivateLeaf,
258
+ l2UniswapInteractionReceipt.txHash,
259
+ ))!;
260
+ const { epochNumber: epoch } = swapResult;
257
261
  await cheatCodes.rollup.advanceToEpoch(EpochNumber(epoch + 1));
258
262
  await waitForProven(aztecNode, l2UniswapInteractionReceipt, { provenTimeout: 300 });
259
263
 
@@ -262,14 +266,17 @@ export const uniswapL1L2TestSuite = (
262
266
  const daiL1BalanceOfPortalBeforeSwap = await daiCrossChainHarness.getL1BalanceOf(
263
267
  daiCrossChainHarness.tokenPortalAddress,
264
268
  );
265
- const swapResult = await computeL2ToL1MembershipWitness(aztecNode, epoch, swapPrivateLeaf);
266
- const withdrawResult = await computeL2ToL1MembershipWitness(aztecNode, epoch, withdrawLeaf);
269
+ const withdrawResult = (await computeL2ToL1MembershipWitness(
270
+ aztecNode,
271
+ withdrawLeaf,
272
+ l2UniswapInteractionReceipt.txHash,
273
+ ))!;
267
274
 
268
- const swapPrivateL2MessageIndex = swapResult!.leafIndex;
269
- const swapPrivateSiblingPath = swapResult!.siblingPath;
275
+ const swapPrivateL2MessageIndex = swapResult.leafIndex;
276
+ const swapPrivateSiblingPath = swapResult.siblingPath;
270
277
 
271
- const withdrawL2MessageIndex = withdrawResult!.leafIndex;
272
- const withdrawSiblingPath = withdrawResult!.siblingPath;
278
+ const withdrawL2MessageIndex = withdrawResult.leafIndex;
279
+ const withdrawSiblingPath = withdrawResult.siblingPath;
273
280
 
274
281
  const withdrawMessageMetadata = {
275
282
  _epoch: BigInt(epoch),
@@ -840,16 +847,15 @@ export const uniswapL1L2TestSuite = (
840
847
  chainId: new Fr(l1Client.chain.id),
841
848
  });
842
849
 
843
- const block = await aztecNode.getBlock(withdrawReceipt.blockNumber!);
844
- const epoch = await rollup.getEpochNumberForCheckpoint(block!.checkpointNumber);
845
- const swapResult = await computeL2ToL1MembershipWitness(aztecNode, epoch, swapPrivateLeaf);
846
- const withdrawResult = await computeL2ToL1MembershipWitness(aztecNode, epoch, withdrawLeaf);
850
+ const swapResult = (await computeL2ToL1MembershipWitness(aztecNode, swapPrivateLeaf, withdrawReceipt.txHash))!;
851
+ const { epochNumber: epoch } = swapResult;
852
+ const withdrawResult = (await computeL2ToL1MembershipWitness(aztecNode, withdrawLeaf, withdrawReceipt.txHash))!;
847
853
 
848
- const swapPrivateL2MessageIndex = swapResult!.leafIndex;
849
- const swapPrivateSiblingPath = swapResult!.siblingPath;
854
+ const swapPrivateL2MessageIndex = swapResult.leafIndex;
855
+ const swapPrivateSiblingPath = swapResult.siblingPath;
850
856
 
851
- const withdrawL2MessageIndex = withdrawResult!.leafIndex;
852
- const withdrawSiblingPath = withdrawResult!.siblingPath;
857
+ const withdrawL2MessageIndex = withdrawResult.leafIndex;
858
+ const withdrawSiblingPath = withdrawResult.siblingPath;
853
859
 
854
860
  const withdrawMessageMetadata = {
855
861
  _epoch: BigInt(epoch),
@@ -973,16 +979,15 @@ export const uniswapL1L2TestSuite = (
973
979
  chainId: new Fr(l1Client.chain.id),
974
980
  });
975
981
 
976
- const block = await aztecNode.getBlock(withdrawReceipt.blockNumber!);
977
- const epoch = await rollup.getEpochNumberForCheckpoint(block!.checkpointNumber);
978
- const swapResult = await computeL2ToL1MembershipWitness(aztecNode, epoch, swapPublicLeaf);
979
- const withdrawResult = await computeL2ToL1MembershipWitness(aztecNode, epoch, withdrawLeaf);
982
+ const swapResult = (await computeL2ToL1MembershipWitness(aztecNode, swapPublicLeaf, withdrawReceipt.txHash))!;
983
+ const { epochNumber: epoch } = swapResult;
984
+ const withdrawResult = (await computeL2ToL1MembershipWitness(aztecNode, withdrawLeaf, withdrawReceipt.txHash))!;
980
985
 
981
- const swapPublicL2MessageIndex = swapResult!.leafIndex;
982
- const swapPublicSiblingPath = swapResult!.siblingPath;
986
+ const swapPublicL2MessageIndex = swapResult.leafIndex;
987
+ const swapPublicSiblingPath = swapResult.siblingPath;
983
988
 
984
- const withdrawL2MessageIndex = withdrawResult!.leafIndex;
985
- const withdrawSiblingPath = withdrawResult!.siblingPath;
989
+ const withdrawL2MessageIndex = withdrawResult.leafIndex;
990
+ const withdrawSiblingPath = withdrawResult.siblingPath;
986
991
 
987
992
  const withdrawMessageMetadata = {
988
993
  _epoch: BigInt(epoch),
@@ -94,7 +94,9 @@ export class LendingSimulator {
94
94
 
95
95
  async prepare() {
96
96
  this.accumulator = BASE;
97
- const slot = await this.rollup.getSlotAt(BigInt(await this.cc.eth.timestamp()) + BigInt(this.ethereumSlotDuration));
97
+ const slot = await this.rollup.getSlotAt(
98
+ BigInt(await this.cc.eth.lastBlockTimestamp()) + BigInt(this.ethereumSlotDuration),
99
+ );
98
100
  this.time = Number(await this.rollup.getTimestampForSlot(slot));
99
101
  }
100
102
 
@@ -103,7 +105,7 @@ export class LendingSimulator {
103
105
  return;
104
106
  }
105
107
 
106
- const slot = await this.rollup.getSlotAt(BigInt(await this.cc.eth.timestamp()));
108
+ const slot = await this.rollup.getSlotAt(BigInt(await this.cc.eth.lastBlockTimestamp()));
107
109
  const targetSlot = SlotNumber(slot + diff);
108
110
  const ts = Number(await this.rollup.getTimestampForSlot(targetSlot));
109
111
  const timeDiff = ts - this.time;
@@ -1,4 +1,5 @@
1
1
  import { generateSchnorrAccounts } from '@aztec/accounts/testing';
2
+ import { NO_FROM } from '@aztec/aztec.js/account';
2
3
  import { AztecAddress } from '@aztec/aztec.js/addresses';
3
4
  import { NO_WAIT } from '@aztec/aztec.js/contracts';
4
5
  import { L1FeeJuicePortalManager } from '@aztec/aztec.js/ethereum';
@@ -89,7 +90,7 @@ export async function deploySponsoredTestAccountsWithTokens(
89
90
  const paymentMethod = new SponsoredFeePaymentMethod(await getSponsoredFPCAddress());
90
91
  const recipientDeployMethod = await recipientAccount.getDeployMethod();
91
92
  await recipientDeployMethod.send({
92
- from: AztecAddress.ZERO,
93
+ from: NO_FROM,
93
94
  fee: { paymentMethod },
94
95
  wait: { timeout: 2400 },
95
96
  });
@@ -97,7 +98,7 @@ export async function deploySponsoredTestAccountsWithTokens(
97
98
  fundedAccounts.map(async a => {
98
99
  const deployMethod = await a.getDeployMethod();
99
100
  await deployMethod.send({
100
- from: AztecAddress.ZERO,
101
+ from: NO_FROM,
101
102
  fee: { paymentMethod },
102
103
  wait: { timeout: 2400 },
103
104
  }); // increase timeout on purpose in order to account for two empty epochs
@@ -129,16 +130,27 @@ export async function deploySponsoredTestAccountsWithTokens(
129
130
  }
130
131
 
131
132
  async function deployAccountWithDiagnostics(
132
- account: { getDeployMethod: () => Promise<{ send: (opts: any) => any }>; address: any },
133
+ account: { getDeployMethod: () => Promise<{ simulate: (opts: any) => any; send: (opts: any) => any }>; address: any },
133
134
  paymentMethod: SponsoredFeePaymentMethod,
134
135
  aztecNode: AztecNode,
135
136
  logger: Logger,
136
137
  accountLabel: string,
138
+ estimateGas?: boolean,
137
139
  ): Promise<void> {
138
140
  const deployMethod = await account.getDeployMethod();
139
141
  let txHash;
140
142
  try {
141
- const deployResult = await deployMethod.send({ from: AztecAddress.ZERO, fee: { paymentMethod }, wait: NO_WAIT });
143
+ let gasSettings;
144
+ if (estimateGas) {
145
+ const sim = await deployMethod.simulate({ from: NO_FROM, fee: { paymentMethod } });
146
+ gasSettings = sim.estimatedGas;
147
+ logger.info(`${accountLabel} estimated gas: DA=${gasSettings.gasLimits.daGas} L2=${gasSettings.gasLimits.l2Gas}`);
148
+ }
149
+ const deployResult = await deployMethod.send({
150
+ from: NO_FROM,
151
+ fee: { paymentMethod, gasSettings },
152
+ wait: NO_WAIT,
153
+ });
142
154
  txHash = deployResult.txHash;
143
155
  await waitForTx(aztecNode, txHash, { timeout: 2400 });
144
156
  logger.info(`${accountLabel} deployed at ${account.address}`);
@@ -161,18 +173,29 @@ async function deployAccountWithDiagnostics(
161
173
  }
162
174
 
163
175
  async function deployAccountsInBatches(
164
- accounts: { getDeployMethod: () => Promise<{ send: (opts: any) => any }>; address: any }[],
176
+ accounts: {
177
+ getDeployMethod: () => Promise<{ simulate: (opts: any) => any; send: (opts: any) => any }>;
178
+ address: any;
179
+ }[],
165
180
  paymentMethod: SponsoredFeePaymentMethod,
166
181
  aztecNode: AztecNode,
167
182
  logger: Logger,
168
183
  labelPrefix: string,
169
184
  batchSize = 2,
185
+ estimateGas?: boolean,
170
186
  ): Promise<void> {
171
187
  for (let i = 0; i < accounts.length; i += batchSize) {
172
188
  const batch = accounts.slice(i, i + batchSize);
173
189
  await Promise.all(
174
190
  batch.map((account, idx) =>
175
- deployAccountWithDiagnostics(account, paymentMethod, aztecNode, logger, `${labelPrefix}${i + idx + 1}`),
191
+ deployAccountWithDiagnostics(
192
+ account,
193
+ paymentMethod,
194
+ aztecNode,
195
+ logger,
196
+ `${labelPrefix}${i + idx + 1}`,
197
+ estimateGas,
198
+ ),
176
199
  ),
177
200
  );
178
201
  }
@@ -183,6 +206,7 @@ export async function deploySponsoredTestAccounts(
183
206
  aztecNode: AztecNode,
184
207
  logger: Logger,
185
208
  numberOfFundedWallets = 1,
209
+ opts?: { estimateGas?: boolean },
186
210
  ): Promise<TestAccountsWithoutTokens> {
187
211
  const [recipient, ...funded] = await generateSchnorrAccounts(numberOfFundedWallets + 1);
188
212
  const recipientAccount = await wallet.createSchnorrAccount(recipient.secret, recipient.salt);
@@ -192,8 +216,23 @@ export async function deploySponsoredTestAccounts(
192
216
 
193
217
  const paymentMethod = new SponsoredFeePaymentMethod(await getSponsoredFPCAddress());
194
218
 
195
- await deployAccountWithDiagnostics(recipientAccount, paymentMethod, aztecNode, logger, 'Recipient account');
196
- await deployAccountsInBatches(fundedAccounts, paymentMethod, aztecNode, logger, 'Funded account ', 2);
219
+ await deployAccountWithDiagnostics(
220
+ recipientAccount,
221
+ paymentMethod,
222
+ aztecNode,
223
+ logger,
224
+ 'Recipient account',
225
+ opts?.estimateGas,
226
+ );
227
+ await deployAccountsInBatches(
228
+ fundedAccounts,
229
+ paymentMethod,
230
+ aztecNode,
231
+ logger,
232
+ 'Funded account ',
233
+ 2,
234
+ opts?.estimateGas,
235
+ );
197
236
 
198
237
  return {
199
238
  aztecNode,
@@ -231,7 +270,7 @@ export async function deployTestAccountsWithTokens(
231
270
  fundedAccounts.map(async (a, i) => {
232
271
  const paymentMethod = new FeeJuicePaymentMethodWithClaim(a.address, claims[i]);
233
272
  const deployMethod = await a.getDeployMethod();
234
- await deployMethod.send({ from: AztecAddress.ZERO, fee: { paymentMethod } });
273
+ await deployMethod.send({ from: NO_FROM, fee: { paymentMethod } });
235
274
  logger.info(`Account deployed at ${a.address}`);
236
275
  }),
237
276
  );
@@ -296,7 +296,7 @@ export class TxInclusionMetrics {
296
296
  value: stats.mean,
297
297
  },
298
298
  {
299
- name: `${group}/p50_inclusion`,
299
+ name: `${group}/median_inclusion`,
300
300
  unit: 's',
301
301
  value: stats.median,
302
302
  },
@@ -16,7 +16,6 @@ const testConfigSchema = z.object({
16
16
  AZTEC_PROOF_SUBMISSION_WINDOW: z.coerce.number().optional().default(5),
17
17
  AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET: z.coerce.number().optional().default(2),
18
18
  FUNDING_PRIVATE_KEY: z.string().optional(),
19
- AZTEC_ADMIN_API_KEY: z.string().optional(),
20
19
  });
21
20
 
22
21
  export type TestConfig = z.infer<typeof testConfigSchema>;