@aztec/end-to-end 0.0.1-commit.5914bae → 0.0.1-commit.59a0419c6
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.
- package/dest/bench/client_flows/client_flows_benchmark.d.ts +1 -1
- package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
- package/dest/bench/client_flows/client_flows_benchmark.js +13 -27
- package/dest/e2e_epochs/epochs_test.d.ts +16 -1
- package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
- package/dest/e2e_epochs/epochs_test.js +56 -8
- package/dest/e2e_fees/fees_test.d.ts +1 -1
- package/dest/e2e_fees/fees_test.d.ts.map +1 -1
- package/dest/e2e_fees/fees_test.js +2 -2
- package/dest/e2e_p2p/inactivity_slash_test.d.ts +1 -1
- package/dest/e2e_p2p/inactivity_slash_test.d.ts.map +1 -1
- package/dest/e2e_p2p/inactivity_slash_test.js +2 -3
- package/dest/e2e_p2p/p2p_network.d.ts +11 -10
- package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
- package/dest/e2e_p2p/p2p_network.js +47 -28
- package/dest/e2e_p2p/reqresp/utils.d.ts +1 -1
- package/dest/e2e_p2p/reqresp/utils.d.ts.map +1 -1
- package/dest/e2e_p2p/reqresp/utils.js +16 -3
- package/dest/e2e_p2p/shared.d.ts +5 -19
- package/dest/e2e_p2p/shared.d.ts.map +1 -1
- package/dest/e2e_p2p/shared.js +36 -70
- package/dest/fixtures/e2e_prover_test.d.ts +4 -3
- package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
- package/dest/fixtures/e2e_prover_test.js +7 -12
- package/dest/fixtures/elu_monitor.d.ts +21 -0
- package/dest/fixtures/elu_monitor.d.ts.map +1 -0
- package/dest/fixtures/elu_monitor.js +102 -0
- package/dest/fixtures/fixtures.d.ts +12 -1
- package/dest/fixtures/fixtures.d.ts.map +1 -1
- package/dest/fixtures/fixtures.js +10 -0
- package/dest/fixtures/get_bb_config.d.ts +1 -1
- package/dest/fixtures/get_bb_config.d.ts.map +1 -1
- package/dest/fixtures/get_bb_config.js +5 -5
- package/dest/fixtures/ha_setup.d.ts +2 -2
- package/dest/fixtures/ha_setup.d.ts.map +1 -1
- package/dest/fixtures/ha_setup.js +1 -1
- package/dest/fixtures/schnorr_hardcoded_account_contract.d.ts +25 -0
- package/dest/fixtures/schnorr_hardcoded_account_contract.d.ts.map +1 -0
- package/dest/fixtures/schnorr_hardcoded_account_contract.js +39 -0
- package/dest/fixtures/setup.d.ts +17 -9
- package/dest/fixtures/setup.d.ts.map +1 -1
- package/dest/fixtures/setup.js +28 -12
- package/dest/fixtures/setup_p2p_test.d.ts +6 -6
- package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
- package/dest/fixtures/setup_p2p_test.js +8 -8
- package/dest/fixtures/token_utils.d.ts +1 -1
- package/dest/fixtures/token_utils.d.ts.map +1 -1
- package/dest/fixtures/token_utils.js +2 -5
- package/dest/shared/gas_portal_test_harness.js +1 -1
- package/dest/shared/jest_setup.js +41 -1
- package/dest/shared/submit-transactions.d.ts +1 -1
- package/dest/shared/submit-transactions.d.ts.map +1 -1
- package/dest/shared/uniswap_l1_l2.d.ts +1 -1
- package/dest/shared/uniswap_l1_l2.d.ts.map +1 -1
- package/dest/shared/uniswap_l1_l2.js +0 -4
- package/dest/simulators/token_simulator.js +1 -1
- package/dest/spartan/setup_test_wallets.d.ts +1 -1
- package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
- package/dest/spartan/setup_test_wallets.js +58 -40
- package/dest/spartan/tx_metrics.d.ts +1 -1
- package/dest/spartan/tx_metrics.d.ts.map +1 -1
- package/dest/spartan/tx_metrics.js +16 -2
- package/dest/spartan/utils/config.d.ts +7 -1
- package/dest/spartan/utils/config.d.ts.map +1 -1
- package/dest/spartan/utils/config.js +3 -1
- package/dest/spartan/utils/index.d.ts +2 -1
- package/dest/spartan/utils/index.d.ts.map +1 -1
- package/dest/spartan/utils/index.js +2 -0
- package/dest/spartan/utils/nodes.d.ts +4 -5
- package/dest/spartan/utils/nodes.d.ts.map +1 -1
- package/dest/spartan/utils/nodes.js +9 -9
- package/dest/spartan/utils/pod_logs.d.ts +25 -0
- package/dest/spartan/utils/pod_logs.d.ts.map +1 -0
- package/dest/spartan/utils/pod_logs.js +74 -0
- package/dest/test-wallet/test_wallet.d.ts +1 -1
- package/dest/test-wallet/test_wallet.d.ts.map +1 -1
- package/dest/test-wallet/test_wallet.js +10 -4
- package/dest/test-wallet/worker_wallet_schema.d.ts +6 -1
- package/dest/test-wallet/worker_wallet_schema.d.ts.map +1 -1
- package/package.json +42 -44
- package/src/bench/client_flows/client_flows_benchmark.ts +31 -22
- package/src/e2e_epochs/epochs_test.ts +56 -7
- package/src/e2e_fees/fees_test.ts +4 -2
- package/src/e2e_p2p/inactivity_slash_test.ts +2 -3
- package/src/e2e_p2p/p2p_network.ts +58 -40
- package/src/e2e_p2p/reqresp/utils.ts +24 -3
- package/src/e2e_p2p/shared.ts +33 -103
- package/src/fixtures/dumps/epoch_proof_result.json +1 -1
- package/src/fixtures/e2e_prover_test.ts +12 -17
- package/src/fixtures/elu_monitor.ts +126 -0
- package/src/fixtures/fixtures.ts +22 -0
- package/src/fixtures/get_bb_config.ts +7 -6
- package/src/fixtures/ha_setup.ts +4 -2
- package/src/fixtures/schnorr_hardcoded_account_contract.ts +49 -0
- package/src/fixtures/setup.ts +43 -16
- package/src/fixtures/setup_p2p_test.ts +9 -9
- package/src/fixtures/token_utils.ts +1 -4
- package/src/guides/up_quick_start.sh +0 -2
- package/src/shared/gas_portal_test_harness.ts +0 -1
- package/src/shared/jest_setup.ts +51 -1
- package/src/shared/submit-transactions.ts +1 -4
- package/src/shared/uniswap_l1_l2.ts +0 -4
- package/src/simulators/token_simulator.ts +1 -1
- package/src/spartan/setup_test_wallets.ts +59 -36
- package/src/spartan/tx_metrics.ts +14 -2
- package/src/spartan/utils/config.ts +2 -0
- package/src/spartan/utils/index.ts +3 -0
- package/src/spartan/utils/nodes.ts +15 -10
- package/src/spartan/utils/pod_logs.ts +99 -0
- package/src/test-wallet/test_wallet.ts +9 -3
package/src/fixtures/setup.ts
CHANGED
|
@@ -7,6 +7,8 @@ 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,7 +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';
|
|
20
|
+
import { AnvilTestWatcher, type AnvilTestWatcherOpts, CheatCodes } from '@aztec/aztec/testing';
|
|
19
21
|
import { SPONSORED_FPC_SALT } from '@aztec/constants';
|
|
20
22
|
import { isAnvilTestChain } from '@aztec/ethereum/chain';
|
|
21
23
|
import { createExtendedL1Client } from '@aztec/ethereum/client';
|
|
@@ -30,7 +32,8 @@ import {
|
|
|
30
32
|
deployAztecL1Contracts,
|
|
31
33
|
} from '@aztec/ethereum/deploy-aztec-l1-contracts';
|
|
32
34
|
import type { Delayer } from '@aztec/ethereum/l1-tx-utils';
|
|
33
|
-
import {
|
|
35
|
+
import { EthCheatCodes, EthCheatCodesWithState, startAnvil } from '@aztec/ethereum/test';
|
|
36
|
+
import type { Anvil } from '@aztec/ethereum/test';
|
|
34
37
|
import { BlockNumber, EpochNumber } from '@aztec/foundation/branded-types';
|
|
35
38
|
import { SecretValue } from '@aztec/foundation/config';
|
|
36
39
|
import { randomBytes } from '@aztec/foundation/crypto/random';
|
|
@@ -51,6 +54,7 @@ import { type ContractInstanceWithAddress, getContractInstanceFromInstantiationP
|
|
|
51
54
|
import type { AztecNodeAdmin, AztecNodeDebug } from '@aztec/stdlib/interfaces/client';
|
|
52
55
|
import { tryStop } from '@aztec/stdlib/interfaces/server';
|
|
53
56
|
import type { PublicDataTreeLeaf } from '@aztec/stdlib/trees';
|
|
57
|
+
import type { GenesisData } from '@aztec/stdlib/world-state';
|
|
54
58
|
import {
|
|
55
59
|
type TelemetryClient,
|
|
56
60
|
type TelemetryClientConfig,
|
|
@@ -177,8 +181,11 @@ export type SetupOptions = {
|
|
|
177
181
|
proverNodeConfig?: Partial<ProverNodeConfig>;
|
|
178
182
|
/** Whether to use a mock gossip sub network for p2p clients. */
|
|
179
183
|
mockGossipSubNetwork?: boolean;
|
|
184
|
+
/** Whether to add simulated latency to the mock gossipsub network (in ms) */
|
|
185
|
+
mockGossipSubNetworkLatency?: number;
|
|
180
186
|
/** Whether to disable the anvil test watcher (can still be manually started) */
|
|
181
187
|
disableAnvilTestWatcher?: boolean;
|
|
188
|
+
anvilTestWatcherOpts?: AnvilTestWatcherOpts;
|
|
182
189
|
/** Whether to enable anvil automine during deployment of L1 contracts (consider defaulting this to true). */
|
|
183
190
|
automineL1Setup?: boolean;
|
|
184
191
|
/** How many accounts to seed and unlock in anvil. */
|
|
@@ -200,8 +207,11 @@ export type SetupOptions = {
|
|
|
200
207
|
skipAccountDeployment?: boolean;
|
|
201
208
|
/** L1 contracts deployment arguments. */
|
|
202
209
|
l1ContractsArgs?: Partial<DeployAztecL1ContractsArgs>;
|
|
203
|
-
/** Wallet minimum fee padding multiplier
|
|
210
|
+
/** Wallet minimum fee padding multiplier */
|
|
204
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;
|
|
205
215
|
} & Partial<AztecNodeConfig>;
|
|
206
216
|
|
|
207
217
|
/** Context for an end-to-end test as returned by the `setup` function */
|
|
@@ -248,8 +258,8 @@ export type EndToEndContext = {
|
|
|
248
258
|
sequencerDelayer: Delayer | undefined;
|
|
249
259
|
/** Delayer for prover node L1 txs (only when enableDelayer and startProverNode are true). */
|
|
250
260
|
proverDelayer: Delayer | undefined;
|
|
251
|
-
/**
|
|
252
|
-
|
|
261
|
+
/** Genesis data used for setting up nodes. */
|
|
262
|
+
genesis: GenesisData | undefined;
|
|
253
263
|
/** ACVM config (only set if running locally). */
|
|
254
264
|
acvmConfig: Awaited<ReturnType<typeof getACVMConfig>>;
|
|
255
265
|
/** BB config (only set if running locally). */
|
|
@@ -275,7 +285,7 @@ export async function setup(
|
|
|
275
285
|
let anvil: Anvil | undefined;
|
|
276
286
|
try {
|
|
277
287
|
opts.aztecTargetCommitteeSize ??= 0;
|
|
278
|
-
opts.
|
|
288
|
+
opts.slasherEnabled ??= false;
|
|
279
289
|
|
|
280
290
|
const config: AztecNodeConfig & SetupOptions = { ...getConfigEnvVars(), ...opts };
|
|
281
291
|
// use initialValidators for the node config
|
|
@@ -374,10 +384,12 @@ export async function setup(
|
|
|
374
384
|
addressesToFund.push(sponsoredFPCAddress);
|
|
375
385
|
}
|
|
376
386
|
|
|
377
|
-
const
|
|
387
|
+
const genesisTimestamp = BigInt(Math.floor(Date.now() / 1000));
|
|
388
|
+
const { genesisArchiveRoot, genesis, fundingNeeded } = await getGenesisValues(
|
|
378
389
|
addressesToFund,
|
|
379
390
|
opts.initialAccountFeeJuice,
|
|
380
391
|
opts.genesisPublicData,
|
|
392
|
+
genesisTimestamp,
|
|
381
393
|
);
|
|
382
394
|
|
|
383
395
|
const wasAutomining = await ethCheatCodes.isAutoMining();
|
|
@@ -436,6 +448,7 @@ export async function setup(
|
|
|
436
448
|
deployL1ContractsValues.l1ContractAddresses.rollupAddress,
|
|
437
449
|
deployL1ContractsValues.l1Client,
|
|
438
450
|
dateProvider,
|
|
451
|
+
opts.anvilTestWatcherOpts,
|
|
439
452
|
);
|
|
440
453
|
if (!opts.disableAnvilTestWatcher) {
|
|
441
454
|
await watcher.start();
|
|
@@ -466,7 +479,7 @@ export async function setup(
|
|
|
466
479
|
let p2pClientDeps: P2PClientDeps | undefined = undefined;
|
|
467
480
|
|
|
468
481
|
if (opts.mockGossipSubNetwork) {
|
|
469
|
-
mockGossipSubNetwork = new MockGossipSubNetwork();
|
|
482
|
+
mockGossipSubNetwork = new MockGossipSubNetwork(opts.mockGossipSubNetworkLatency);
|
|
470
483
|
p2pClientDeps = { p2pServiceFactory: getMockPubSubP2PServiceFactory(mockGossipSubNetwork) };
|
|
471
484
|
}
|
|
472
485
|
|
|
@@ -494,11 +507,22 @@ export async function setup(
|
|
|
494
507
|
}
|
|
495
508
|
}
|
|
496
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
|
+
|
|
497
521
|
const aztecNodeService = await withLoggerBindings({ actor: 'node-0' }, () =>
|
|
498
522
|
AztecNodeService.createAndSync(
|
|
499
|
-
|
|
523
|
+
initialNodeConfig,
|
|
500
524
|
{ dateProvider, telemetry: telemetryClient, p2pClientDeps },
|
|
501
|
-
{
|
|
525
|
+
{ genesis, dontStartSequencer: opts.skipInitialSequencer },
|
|
502
526
|
),
|
|
503
527
|
);
|
|
504
528
|
const sequencerClient = aztecNodeService.getSequencer();
|
|
@@ -523,7 +547,7 @@ export async function setup(
|
|
|
523
547
|
dataDirectory: proverNodeDataDirectory,
|
|
524
548
|
},
|
|
525
549
|
{ dateProvider, p2pClientDeps, telemetry: telemetryClient },
|
|
526
|
-
{
|
|
550
|
+
{ genesis },
|
|
527
551
|
));
|
|
528
552
|
}
|
|
529
553
|
|
|
@@ -559,7 +583,9 @@ export async function setup(
|
|
|
559
583
|
|
|
560
584
|
let accounts: AztecAddress[] = [];
|
|
561
585
|
|
|
562
|
-
if (
|
|
586
|
+
if (opts.skipInitialSequencer) {
|
|
587
|
+
logger.info('Sequencer not started on initial node, skipping block progression');
|
|
588
|
+
} else if (shouldDeployAccounts) {
|
|
563
589
|
logger.info(
|
|
564
590
|
`${numberOfAccounts} accounts are being deployed. Reliably progressing past genesis by setting minTxsPerBlock to 1 and waiting for the accounts to be deployed`,
|
|
565
591
|
);
|
|
@@ -628,7 +654,7 @@ export async function setup(
|
|
|
628
654
|
initialFundedAccounts,
|
|
629
655
|
logger,
|
|
630
656
|
mockGossipSubNetwork,
|
|
631
|
-
|
|
657
|
+
genesis,
|
|
632
658
|
proverNode,
|
|
633
659
|
sequencerDelayer,
|
|
634
660
|
proverDelayer,
|
|
@@ -728,7 +754,7 @@ export function createAndSyncProverNode(
|
|
|
728
754
|
dateProvider: DateProvider;
|
|
729
755
|
p2pClientDeps?: P2PClientDeps;
|
|
730
756
|
},
|
|
731
|
-
options: {
|
|
757
|
+
options: { genesis?: GenesisData; dontStart?: boolean },
|
|
732
758
|
): Promise<{ proverNode: AztecNodeService }> {
|
|
733
759
|
return withLoggerBindings({ actor: 'prover-0' }, async () => {
|
|
734
760
|
const proverNode = await AztecNodeService.createAndSync(
|
|
@@ -741,7 +767,7 @@ export function createAndSyncProverNode(
|
|
|
741
767
|
proverPublisherPrivateKeys: [new SecretValue(proverNodePrivateKey)],
|
|
742
768
|
},
|
|
743
769
|
deps,
|
|
744
|
-
{
|
|
770
|
+
{ genesis: options.genesis, dontStartProverNode: options.dontStart },
|
|
745
771
|
);
|
|
746
772
|
|
|
747
773
|
if (!proverNode.getProverNode()) {
|
|
@@ -832,7 +858,7 @@ export async function ensureAccountContractsPublished(wallet: Wallet, accountsTo
|
|
|
832
858
|
* Returns deployed account data that can be used by tests.
|
|
833
859
|
*/
|
|
834
860
|
export const deployAccounts =
|
|
835
|
-
(numberOfAccounts: number, logger: Logger) =>
|
|
861
|
+
(numberOfAccounts: number, logger: Logger, deployOptions?: Partial<DeployOptions<DeployInteractionWaitOptions>>) =>
|
|
836
862
|
async ({ wallet, initialFundedAccounts }: { wallet: TestWallet; initialFundedAccounts: InitialAccountData[] }) => {
|
|
837
863
|
if (initialFundedAccounts.length < numberOfAccounts) {
|
|
838
864
|
throw new Error(`Cannot deploy more than ${initialFundedAccounts.length} initial accounts.`);
|
|
@@ -851,6 +877,7 @@ export const deployAccounts =
|
|
|
851
877
|
await deployMethod.send({
|
|
852
878
|
from: NO_FROM,
|
|
853
879
|
skipClassPublication: i !== 0, // Publish the contract class at most once.
|
|
880
|
+
...deployOptions,
|
|
854
881
|
});
|
|
855
882
|
}
|
|
856
883
|
|
|
@@ -7,7 +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 {
|
|
10
|
+
import type { GenesisData } from '@aztec/stdlib/world-state';
|
|
11
11
|
|
|
12
12
|
import getPort from 'get-port';
|
|
13
13
|
|
|
@@ -40,7 +40,7 @@ export async function createNodes(
|
|
|
40
40
|
bootstrapNodeEnr: string,
|
|
41
41
|
numNodes: number,
|
|
42
42
|
bootNodePort: number,
|
|
43
|
-
|
|
43
|
+
genesis?: GenesisData,
|
|
44
44
|
dataDirectory?: string,
|
|
45
45
|
metricsPort?: number,
|
|
46
46
|
indexOffset = 0,
|
|
@@ -65,7 +65,7 @@ export async function createNodes(
|
|
|
65
65
|
port,
|
|
66
66
|
bootstrapNodeEnr,
|
|
67
67
|
validatorIndices,
|
|
68
|
-
|
|
68
|
+
genesis,
|
|
69
69
|
dataDir,
|
|
70
70
|
metricsPort,
|
|
71
71
|
);
|
|
@@ -97,7 +97,7 @@ export async function createNode(
|
|
|
97
97
|
tcpPort: number,
|
|
98
98
|
bootstrapNode: string | undefined,
|
|
99
99
|
addressIndex: number | number[],
|
|
100
|
-
|
|
100
|
+
genesis?: GenesisData,
|
|
101
101
|
dataDirectory?: string,
|
|
102
102
|
metricsPort?: number,
|
|
103
103
|
) {
|
|
@@ -108,7 +108,7 @@ export async function createNode(
|
|
|
108
108
|
return await AztecNodeService.createAndSync(
|
|
109
109
|
validatorConfig,
|
|
110
110
|
{ telemetry, dateProvider },
|
|
111
|
-
{
|
|
111
|
+
{ genesis, dontStartSequencer: config.dontStartSequencer },
|
|
112
112
|
);
|
|
113
113
|
});
|
|
114
114
|
}
|
|
@@ -119,7 +119,7 @@ export async function createNonValidatorNode(
|
|
|
119
119
|
dateProvider: DateProvider,
|
|
120
120
|
tcpPort: number,
|
|
121
121
|
bootstrapNode: string | undefined,
|
|
122
|
-
|
|
122
|
+
genesis?: GenesisData,
|
|
123
123
|
dataDirectory?: string,
|
|
124
124
|
metricsPort?: number,
|
|
125
125
|
) {
|
|
@@ -133,7 +133,7 @@ export async function createNonValidatorNode(
|
|
|
133
133
|
sequencerPublisherPrivateKeys: [],
|
|
134
134
|
};
|
|
135
135
|
const telemetry = await getEndToEndTestTelemetryClient(metricsPort);
|
|
136
|
-
return await AztecNodeService.createAndSync(config, { telemetry, dateProvider }, {
|
|
136
|
+
return await AztecNodeService.createAndSync(config, { telemetry, dateProvider }, { genesis });
|
|
137
137
|
});
|
|
138
138
|
}
|
|
139
139
|
|
|
@@ -143,7 +143,7 @@ export async function createProverNode(
|
|
|
143
143
|
bootstrapNode: string | undefined,
|
|
144
144
|
addressIndex: number,
|
|
145
145
|
deps: { dateProvider: DateProvider },
|
|
146
|
-
|
|
146
|
+
genesis?: GenesisData,
|
|
147
147
|
dataDirectory?: string,
|
|
148
148
|
metricsPort?: number,
|
|
149
149
|
): Promise<{ proverNode: AztecNodeService }> {
|
|
@@ -159,7 +159,7 @@ export async function createProverNode(
|
|
|
159
159
|
{ ...config, ...p2pConfig },
|
|
160
160
|
{ dataDirectory },
|
|
161
161
|
{ ...deps, telemetry },
|
|
162
|
-
{
|
|
162
|
+
{ genesis },
|
|
163
163
|
);
|
|
164
164
|
});
|
|
165
165
|
}
|
|
@@ -6,11 +6,8 @@ import { TokenContract } from '@aztec/noir-contracts.js/Token';
|
|
|
6
6
|
|
|
7
7
|
export async function deployToken(wallet: Wallet, admin: AztecAddress, initialAdminBalance: bigint, logger: Logger) {
|
|
8
8
|
logger.info(`Deploying Token contract...`);
|
|
9
|
-
const {
|
|
10
|
-
receipt: { contract, instance },
|
|
11
|
-
} = await TokenContract.deploy(wallet, admin, 'TokenName', 'TokenSymbol', 18).send({
|
|
9
|
+
const { contract, instance } = await TokenContract.deploy(wallet, admin, 'TokenName', 'TokenSymbol', 18).send({
|
|
12
10
|
from: admin,
|
|
13
|
-
wait: { returnReceipt: true },
|
|
14
11
|
});
|
|
15
12
|
|
|
16
13
|
if (initialAdminBalance > 0n) {
|
|
@@ -18,10 +18,8 @@ aztec-wallet() {
|
|
|
18
18
|
|
|
19
19
|
aztec-wallet import-test-accounts
|
|
20
20
|
|
|
21
|
-
# docs:start:declare-accounts
|
|
22
21
|
aztec-wallet create-account -a alice -f test0
|
|
23
22
|
aztec-wallet create-account -a bob -f test0
|
|
24
|
-
# docs:end:declare-accounts
|
|
25
23
|
|
|
26
24
|
aztec-wallet bridge-fee-juice 1000000000000000000000 accounts:alice --mint --no-wait
|
|
27
25
|
|
package/src/shared/jest_setup.ts
CHANGED
|
@@ -1,8 +1,19 @@
|
|
|
1
1
|
import { createLogger } from '@aztec/aztec.js/log';
|
|
2
2
|
|
|
3
|
-
import { beforeEach, expect } from '@jest/globals';
|
|
3
|
+
import { afterAll, afterEach, beforeEach, expect } from '@jest/globals';
|
|
4
|
+
import { readlinkSync } from 'fs';
|
|
4
5
|
import { basename } from 'path';
|
|
5
6
|
|
|
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
|
+
|
|
6
17
|
beforeEach(() => {
|
|
7
18
|
const { testPath, currentTestName } = expect.getState();
|
|
8
19
|
if (!testPath || !currentTestName) {
|
|
@@ -10,4 +21,43 @@ beforeEach(() => {
|
|
|
10
21
|
}
|
|
11
22
|
const logger = createLogger(`e2e:${basename(testPath).replace('.test.ts', '')}`);
|
|
12
23
|
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
|
+
}
|
|
13
63
|
});
|
|
@@ -19,10 +19,7 @@ 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({
|
|
23
|
-
from: submitter,
|
|
24
|
-
wait: NO_WAIT,
|
|
25
|
-
});
|
|
22
|
+
const { txHash } = await deployMethod.send({ from: submitter, wait: NO_WAIT });
|
|
26
23
|
|
|
27
24
|
logger.info(`Tx sent with hash ${txHash}`);
|
|
28
25
|
const receipt: TxReceipt = await wallet.getTxReceipt(txHash);
|
|
@@ -154,7 +154,6 @@ export const uniswapL1L2TestSuite = (
|
|
|
154
154
|
await cleanup();
|
|
155
155
|
});
|
|
156
156
|
|
|
157
|
-
// docs:start:uniswap_private
|
|
158
157
|
it('should uniswap trade on L1 from L2 funds privately (swaps WETH -> DAI)', async () => {
|
|
159
158
|
const wethL1BeforeBalance = await wethCrossChainHarness.getL1BalanceOf(ownerEthAddress);
|
|
160
159
|
|
|
@@ -345,10 +344,8 @@ export const uniswapL1L2TestSuite = (
|
|
|
345
344
|
logger.info('WETH balance after swap : ', wethL2BalanceAfterSwap.toString());
|
|
346
345
|
logger.info('DAI balance after swap : ', daiL2BalanceAfterSwap.toString());
|
|
347
346
|
});
|
|
348
|
-
// docs:end:uniswap_private
|
|
349
347
|
|
|
350
348
|
// TODO(#7463): reenable look into this failure https://github.com/AztecProtocol/aztec-packages/actions/runs/9912612912/job/27388320150?pr=7462
|
|
351
|
-
// // docs:start:uniswap_public
|
|
352
349
|
// it('should uniswap trade on L1 from L2 funds publicly (swaps WETH -> DAI)', async () => {
|
|
353
350
|
// const wethL1BeforeBalance = await wethCrossChainHarness.getL1BalanceOf(ownerEthAddress);
|
|
354
351
|
|
|
@@ -581,7 +578,6 @@ export const uniswapL1L2TestSuite = (
|
|
|
581
578
|
// logger.info('WETH balance after swap : ', wethL2BalanceAfterSwap.toString());
|
|
582
579
|
// logger.info('DAI balance after swap : ', daiL2BalanceAfterSwap.toString());
|
|
583
580
|
// });
|
|
584
|
-
// // docs:end:uniswap_public
|
|
585
581
|
|
|
586
582
|
// Edge cases for the private flow:
|
|
587
583
|
// note - tests for uniswapPortal.sol and minting asset on L2 are covered in other tests.
|
|
@@ -110,7 +110,7 @@ export class TokenSimulator {
|
|
|
110
110
|
chunk(calls, 5).map(batch => new BatchCall(this.defaultWallet, batch).simulate({ from: this.defaultAddress })),
|
|
111
111
|
)
|
|
112
112
|
)
|
|
113
|
-
.
|
|
113
|
+
.flatMap(r => r.result)
|
|
114
114
|
.map(r => r.result);
|
|
115
115
|
expect(results[0]).toEqual(this.totalSupply);
|
|
116
116
|
|
|
@@ -11,7 +11,7 @@ import type { Wallet } from '@aztec/aztec.js/wallet';
|
|
|
11
11
|
import { createEthereumChain } from '@aztec/ethereum/chain';
|
|
12
12
|
import { createExtendedL1Client } from '@aztec/ethereum/client';
|
|
13
13
|
import type { Logger } from '@aztec/foundation/log';
|
|
14
|
-
import { retryUntil } from '@aztec/foundation/retry';
|
|
14
|
+
import { makeBackoff, retry, retryUntil } from '@aztec/foundation/retry';
|
|
15
15
|
import { TokenContract } from '@aztec/noir-contracts.js/Token';
|
|
16
16
|
import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client';
|
|
17
17
|
import { registerInitialLocalNetworkAccountsInWallet } from '@aztec/wallets/testing';
|
|
@@ -138,38 +138,57 @@ async function deployAccountWithDiagnostics(
|
|
|
138
138
|
estimateGas?: boolean,
|
|
139
139
|
): Promise<void> {
|
|
140
140
|
const deployMethod = await account.getDeployMethod();
|
|
141
|
-
let
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
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
|
-
});
|
|
154
|
-
txHash = deployResult.txHash;
|
|
155
|
-
await waitForTx(aztecNode, txHash, { timeout: 2400 });
|
|
156
|
-
logger.info(`${accountLabel} deployed at ${account.address}`);
|
|
157
|
-
} catch (error) {
|
|
158
|
-
const blockNumber = await aztecNode.getBlockNumber();
|
|
159
|
-
let receipt;
|
|
160
|
-
try {
|
|
161
|
-
receipt = await aztecNode.getTxReceipt(txHash);
|
|
162
|
-
} catch {
|
|
163
|
-
receipt = 'unavailable';
|
|
164
|
-
}
|
|
165
|
-
logger.error(`${accountLabel} deployment failed`, {
|
|
166
|
-
txHash: txHash.toString(),
|
|
167
|
-
receipt: JSON.stringify(receipt),
|
|
168
|
-
currentBlockNumber: blockNumber,
|
|
169
|
-
error: String(error),
|
|
170
|
-
});
|
|
171
|
-
throw error;
|
|
141
|
+
let gasSettings: any;
|
|
142
|
+
if (estimateGas) {
|
|
143
|
+
const sim = await deployMethod.simulate({ from: NO_FROM, fee: { paymentMethod } });
|
|
144
|
+
gasSettings = sim.estimatedGas;
|
|
145
|
+
logger.info(`${accountLabel} estimated gas: DA=${gasSettings.gasLimits.daGas} L2=${gasSettings.gasLimits.l2Gas}`);
|
|
172
146
|
}
|
|
147
|
+
|
|
148
|
+
// Track the tx hash across retries so we don't re-send when the previous tx is still pending.
|
|
149
|
+
let sentTxHash: { txHash: any } | undefined;
|
|
150
|
+
|
|
151
|
+
await retry(
|
|
152
|
+
async () => {
|
|
153
|
+
// Check if already deployed (handles case where previous attempt succeeded but waitForTx timed out)
|
|
154
|
+
const existing = await aztecNode.getContract(account.address);
|
|
155
|
+
if (existing) {
|
|
156
|
+
logger.info(`${accountLabel} already deployed at ${account.address}, skipping`);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// If we already sent a tx, check if it was dropped before deciding to re-send.
|
|
161
|
+
if (sentTxHash) {
|
|
162
|
+
const prevReceipt = await aztecNode.getTxReceipt(sentTxHash.txHash);
|
|
163
|
+
if (prevReceipt.isDropped()) {
|
|
164
|
+
logger.info(`${accountLabel} previous tx ${sentTxHash.txHash} was dropped, re-sending`);
|
|
165
|
+
sentTxHash = undefined;
|
|
166
|
+
} else {
|
|
167
|
+
logger.info(`${accountLabel} previous tx ${sentTxHash.txHash} still pending, waiting again...`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (!sentTxHash) {
|
|
172
|
+
const deployResult = await deployMethod.send({
|
|
173
|
+
from: NO_FROM,
|
|
174
|
+
fee: { paymentMethod, gasSettings },
|
|
175
|
+
wait: NO_WAIT,
|
|
176
|
+
});
|
|
177
|
+
sentTxHash = { txHash: deployResult.txHash };
|
|
178
|
+
logger.info(`${accountLabel} tx sent`, { txHash: sentTxHash.txHash.toString() });
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
const receipt = await waitForTx(aztecNode, sentTxHash.txHash, { timeout: 600 });
|
|
182
|
+
if (receipt.isDropped()) {
|
|
183
|
+
sentTxHash = undefined;
|
|
184
|
+
throw new Error(`${accountLabel} tx was dropped, retrying...`);
|
|
185
|
+
}
|
|
186
|
+
logger.info(`${accountLabel} deployed at ${account.address}`);
|
|
187
|
+
},
|
|
188
|
+
`deploy ${accountLabel}`,
|
|
189
|
+
makeBackoff([1, 2, 4, 8, 16]),
|
|
190
|
+
logger,
|
|
191
|
+
);
|
|
173
192
|
}
|
|
174
193
|
|
|
175
194
|
async function deployAccountsInBatches(
|
|
@@ -346,14 +365,18 @@ async function deployTokenAndMint(
|
|
|
346
365
|
logger: Logger,
|
|
347
366
|
) {
|
|
348
367
|
logger.verbose(`Deploying TokenContract...`);
|
|
349
|
-
const {
|
|
350
|
-
|
|
351
|
-
|
|
368
|
+
const { contract: tokenContract } = await TokenContract.deploy(
|
|
369
|
+
wallet,
|
|
370
|
+
admin,
|
|
371
|
+
TOKEN_NAME,
|
|
372
|
+
TOKEN_SYMBOL,
|
|
373
|
+
TOKEN_DECIMALS,
|
|
374
|
+
).send({
|
|
352
375
|
from: admin,
|
|
353
376
|
fee: {
|
|
354
377
|
paymentMethod,
|
|
355
378
|
},
|
|
356
|
-
wait: { timeout: 600
|
|
379
|
+
wait: { timeout: 600 },
|
|
357
380
|
});
|
|
358
381
|
|
|
359
382
|
const tokenAddress = tokenContract.address;
|
|
@@ -229,12 +229,24 @@ export class TxInclusionMetrics {
|
|
|
229
229
|
p99: number;
|
|
230
230
|
} {
|
|
231
231
|
const histogram = createHistogram({});
|
|
232
|
+
let nonPositive = 0;
|
|
232
233
|
for (const tx of this.data.values()) {
|
|
233
234
|
if (!tx.blocknumber || tx.group !== group || tx.minedAt === -1) {
|
|
234
235
|
continue;
|
|
235
236
|
}
|
|
236
237
|
|
|
237
|
-
|
|
238
|
+
// `minedAt` is the block's L2 slot timestamp (seconds) while `sentAt` is the wall-clock
|
|
239
|
+
// send time. Because the slot timestamp can precede or equal the send time, the delta
|
|
240
|
+
// can be <= 0, which perf_hooks.createHistogram rejects. Skip those instead of crashing.
|
|
241
|
+
const delta = tx.minedAt - tx.sentAt;
|
|
242
|
+
if (delta <= 0) {
|
|
243
|
+
nonPositive++;
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
histogram.record(delta);
|
|
247
|
+
}
|
|
248
|
+
if (nonPositive > 0) {
|
|
249
|
+
this.logger?.debug(`Dropped ${nonPositive} tx inclusion samples with non-positive delta`, { group });
|
|
238
250
|
}
|
|
239
251
|
|
|
240
252
|
if (histogram.count === 0) {
|
|
@@ -296,7 +308,7 @@ export class TxInclusionMetrics {
|
|
|
296
308
|
value: stats.mean,
|
|
297
309
|
},
|
|
298
310
|
{
|
|
299
|
-
name: `${group}/
|
|
311
|
+
name: `${group}/p50_inclusion`,
|
|
300
312
|
unit: 's',
|
|
301
313
|
value: stats.median,
|
|
302
314
|
},
|
|
@@ -8,6 +8,7 @@ const logger = createLogger('e2e:k8s-utils');
|
|
|
8
8
|
const testConfigSchema = z.object({
|
|
9
9
|
NAMESPACE: z.string().default('scenario'),
|
|
10
10
|
REAL_VERIFIER: schemas.Boolean.optional().default(true),
|
|
11
|
+
DEBUG_FORCE_TX_PROOF_VERIFICATION: schemas.Boolean.optional().default(true),
|
|
11
12
|
CREATE_ETH_DEVNET: schemas.Boolean.optional().default(false),
|
|
12
13
|
L1_RPC_URLS_JSON: z.string().optional(),
|
|
13
14
|
L1_ACCOUNT_MNEMONIC: z.string().optional(),
|
|
@@ -16,6 +17,7 @@ const testConfigSchema = z.object({
|
|
|
16
17
|
AZTEC_PROOF_SUBMISSION_WINDOW: z.coerce.number().optional().default(5),
|
|
17
18
|
AZTEC_LAG_IN_EPOCHS_FOR_VALIDATOR_SET: z.coerce.number().optional().default(2),
|
|
18
19
|
FUNDING_PRIVATE_KEY: z.string().optional(),
|
|
20
|
+
AZTEC_ADMIN_API_KEY: z.string().optional(),
|
|
19
21
|
});
|
|
20
22
|
|
|
21
23
|
export type TestConfig = z.infer<typeof testConfigSchema>;
|
|
@@ -66,3 +66,6 @@ export { getPublicViemClient, getL1DeploymentAddresses, getNodeClient } from './
|
|
|
66
66
|
|
|
67
67
|
// Health checks
|
|
68
68
|
export { ChainHealth, type ChainHealthSnapshot } from './health.js';
|
|
69
|
+
|
|
70
|
+
// Pod log extraction
|
|
71
|
+
export { type BlockBuiltLogEntry, fetchBlockBuiltLogs } from './pod_logs.js';
|