Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
3fb8bed
fix(p2p): re-seed discovery from persisted peer ENRs after restart (#…
PhilWindle Jun 19, 2026
bc2c924
docs(e2e): annotate e2e tests with setup/category notes (#24191)
spalladino Jun 19, 2026
d3ff40b
fix(p2p): bound declared contract-class bytecode length before alloca…
PhilWindle Jun 20, 2026
9e4e990
fix(p2p): frame gossipsub msgId and restrict allowedTopics (A-1256)
PhilWindle Jun 20, 2026
09ccf6f
fix(p2p): guard ENR address parsing against malformed TCP fields (A-1…
PhilWindle Jun 20, 2026
efad5ed
fix(stdlib): guard bufferFromFields against an empty field array (A-1…
PhilWindle Jun 22, 2026
0440c0d
chore: merge v5-next into merge-train/spartan-v5 (raw, conflict marke…
AztecBot Jun 22, 2026
ed67bd1
fix(archiver): index zero-field logs under empty tag instead of throw…
PhilWindle Jun 22, 2026
a2a6297
fix(p2p): drop fastMsgIdFn so dedup rests on the cryptographic msgId …
PhilWindle Jun 22, 2026
7ae7aac
chore(p2p): drop unused xxhash-wasm dependency (A-1256)
PhilWindle Jun 22, 2026
eb7d64d
fix(prover-node): report awaiting-root and publishing-proof phases in…
PhilWindle Jun 22, 2026
4f132d9
chore: merge v5-next into merge-train/spartan-v5
AztecBot Jun 22, 2026
400b434
fix(p2p): bound declared contract-class bytecode length before alloca…
PhilWindle Jun 22, 2026
ac59fe0
fix(p2p): frame gossipsub msgId and restrict allowedTopics (A-1256) (…
PhilWindle Jun 22, 2026
a30385b
chore: merge v5-next into merge-train/spartan-v5 (#24226)
PhilWindle Jun 22, 2026
717b13d
fix(p2p): guard ENR address parsing against malformed TCP fields (A-1…
PhilWindle Jun 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions yarn-project/end-to-end/src/bench/bench_build_block.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ const ETHEREUM_SLOT_DURATION_SECONDS = 12;
const BLOCK_DURATION_MS = 200_000;
const L1_TX_TIMEOUT_MS = 30 * 60 * 1000;

// Block-building latency benchmark. Uses benchmarkSetup() (wraps setup() with telemetry override) and
// emits BENCH_OUTPUT JSON for the GitHub Benchmark Action. Measures sequencer block-build duration and
// mana throughput across 32-tx standard and 8-tx compute-heavy block configurations.
describe('benchmarks/build_block', () => {
let context: EndToEndContext;
let contract: BenchmarkingContract;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ import { type AccountType, type BenchmarkingFeePaymentMethod, ClientFlowsBenchma

jest.setTimeout(300_000);

// Account deployment round-trip benchmark. Uses ClientFlowsBenchmark (wraps setup()) with BENCHMARK_CONFIG
// env var; profiles the full deployment flow (simulate → prove → send → wait) for ECDSA-R1 and Schnorr
// account types with various fee-payment methods. Bench pipeline only.
describe('Deployment benchmark', () => {
const t = new ClientFlowsBenchmark('deployments');

Expand Down
2 changes: 2 additions & 0 deletions yarn-project/end-to-end/src/bench/client_flows/amm.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ interface RoundTripData {
roundTrips: RoundTripStats | undefined;
}

// AMM interaction round-trip benchmark. Uses ClientFlowsBenchmark with BENCHMARK_CONFIG; profiles
// add-liquidity and swap flows across account types and fee-payment methods; emits BENCH_OUTPUT JSON.
describe('AMM benchmark', () => {
const roundTripData: RoundTripData[] = [];
const t = new ClientFlowsBenchmark('amm');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { type AccountType, type BenchmarkingFeePaymentMethod, ClientFlowsBenchma

jest.setTimeout(300_000);

// L1↔L2 bridging round-trip benchmark. Uses ClientFlowsBenchmark (wraps CrossChainTestHarness) with
// BENCHMARK_CONFIG; profiles the full bridge-in flow for multiple account/fee-method combinations.
describe('Bridging benchmark', () => {
const t = new ClientFlowsBenchmark('bridging');
// The wallet used by the user to interact
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { type AccountType, type BenchmarkingFeePaymentMethod, ClientFlowsBenchma

jest.setTimeout(1_600_000);

// Contract deployment round-trip benchmark. Uses ClientFlowsBenchmark with BENCHMARK_CONFIG; profiles
// PrivateVoting contract deployment across account types and fee-payment methods; emits BENCH_OUTPUT JSON.
describe('Deployment benchmark', () => {
const t = new ClientFlowsBenchmark('deployments');
let node: AztecNode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import { type AccountType, type BenchmarkingFeePaymentMethod, ClientFlowsBenchma

jest.setTimeout(300_000);

// Storage proof round-trip benchmark. Uses ClientFlowsBenchmark with BENCHMARK_CONFIG; profiles the full
// buildStorageProofCapsules + contract-call flow for multiple account/fee-method combinations.
describe('Storage proof benchmark', () => {
const t = new ClientFlowsBenchmark('storage_proof');
let userWallet: TestWallet;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ const AMOUNT_PER_NOTE = 1_000_000;

const MINIMUM_NOTES_FOR_RECURSION_LEVEL = [0, 2, 10];

// Token transfer round-trip benchmark. Uses ClientFlowsBenchmark with BENCHMARK_CONFIG; profiles private
// token transfer flows at varying note-recursion depths for multiple account/fee-method combinations.
describe('Transfer benchmark', () => {
const t = new ClientFlowsBenchmark('transfers');
// The wallet used by the admin to interact
Expand Down
3 changes: 3 additions & 0 deletions yarn-project/end-to-end/src/bench/node_rpc_perf.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ async function benchmark<T>(
};
}

// Node RPC performance benchmark. Uses setup() with PIPELINING_SETUP_OPTS, builds BLOCKS_TO_BUILD blocks,
// then iterates all RPC endpoints measuring avg/min/max latency; emits BENCH_OUTPUT JSON for the bench
// pipeline. Not in test_cmds; runs via bench_cmds.
describe('e2e_node_rpc_perf', () => {
jest.setTimeout(10 * 60 * 1000); // 10 minutes

Expand Down
3 changes: 3 additions & 0 deletions yarn-project/end-to-end/src/bench/tx_stats_bench.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ import { proveInteraction } from '../test-wallet/utils.js';
const REAL_PROOFS = !parseBooleanEnv(process.env.FAKE_PROOFS);
const TIMEOUT = REAL_PROOFS ? 45 * 60 * 1000 : 15 * 60 * 1000;

// Transaction stats benchmark. Uses FullProverTest with real or fake proofs (FAKE_PROOFS env var).
// Measures proof generation time, tx wire size, and compression ratios (snappy/brotli/zstd) for public
// and private transactions; emits BENCH_OUTPUT JSON. Bench pipeline only.
describe('transaction benchmarks', () => {
const COINBASE_ADDRESS = EthAddress.random();
const t = new FullProverTest('full_prover', 1, COINBASE_ADDRESS, REAL_PROOFS);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const { AZTEC_NODE_URL = 'http://localhost:8080', ETHEREUM_HOSTS = 'http://local

// Unlike the non-composed e2e_cheat_codes.test.ts these tests are testing that the AztecNodeDebug endpoints get
// correctly exposed on the node.
// Runs against a pre-started docker-compose network (AZTEC_NODE_URL + ETHEREUM_HOSTS); no in-proc setup().
describe('e2e_cheat_codes', () => {
const logger = createLogger('e2e:cheat_codes');
let aztecNode: AztecNode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ const { AZTEC_NODE_URL = 'http://localhost:8080' } = process.env;
//
// 3. Run the tests:
// yarn test:e2e e2e_local_network_example.test.ts
// End-to-end example of connecting to the --local-network quickstart. Runs against a pre-started
// docker-compose stack (AZTEC_NODE_URL); demonstrates account loading, token deployment, and transfers
// using only the public aztec.js npm API.
describe('e2e_local_network_example', () => {
it('local network example works', async () => {
////////////// CREATE THE CLIENT INTERFACE AND CONTACT THE LOCAL NETWORK //////////////
Expand Down
3 changes: 3 additions & 0 deletions yarn-project/end-to-end/src/composed/e2e_persistence.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ import type { TestWallet } from '../test-wallet/test_wallet.js';

jest.setTimeout(15 * 60 * 1000);

// Node and PXE persistence tests. Uses setup() directly with PIPELINING_SETUP_OPTS; excluded from the
// compose glob for unknown reasons (migrate-later candidate). Spawns and tears down node/PXE with
// varying combinations of persisted vs empty data directories to cover five restart scenarios.
describe('Aztec persistence', () => {
/**
* These tests check that the Aztec Node and PXE can be shutdown and restarted without losing data.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ async function addMinter(l1TokenContract: EthAddress, l1TokenHandler: EthAddress
//
// 3. Run the tests:
// yarn test:e2e e2e_token_bridge_tutorial_test.test.ts
// Token bridge tutorial test. Runs against a pre-started local network (AZTEC_NODE_URL + ETHEREUM_HOSTS)
// using only published npm packages. Deploys an L1 ERC20/portal and L2 token bridge, then exercises the
// full L1↔L2 bridging flow. Intentional constraint: no in-proc setup().
describe('e2e_cross_chain_messaging token_bridge_tutorial_test', () => {
it('Deploys tokens & bridges to L1 & L2, mints & publicly bridges tokens', async () => {
const logger = createLogger('aztec:token-bridge-tutorial');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ async function waitForTriggerTx(node: AztecNode, txHash: TxHash): Promise<TxRece
return receipt;
}

// Requires the docker-compose HA suite (run_test.sh ha): live Postgres (DATABASE_URL) and Web3Signer
// sidecar. Uses setup() with PIPELINING_SETUP_OPTS; multiple in-proc AztecNodeService instances share the
// Postgres slashing-protection DB and Web3Signer keystore.
describe('HA Full Setup', () => {
jest.setTimeout(20 * 60 * 1000); // 20 minutes

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ import { getLogger, startAnvil } from '../fixtures/utils.js';
* Regenerate this test's fixture with
* AZTEC_GENERATE_TEST_DATA=1 yarn workspace @aztec/prover-client test bb_prover_full_rollup
*/
// Standalone Honk proof verifier integration test. Starts its own anvil, deploys a HonkVerifier contract,
// loads a serialised RootRollupPublicInputs fixture, and verifies the proof on-chain via BBCircuitVerifier.
// No Aztec node. Excluded from compose glob; requires a pre-generated proof fixture (AZTEC_GENERATE_TEST_DATA).
describe('proof_verification', () => {
let proof: Proof;
let publicInputs: RootRollupPublicInputs;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import { uniswapL1L2TestSuite } from '../shared/uniswap_l1_l2.js';

// This tests works on forked mainnet. There is a dump of the data in `dumpedState` such that we
// don't need to burn through RPC requests.
// Uses setup() with PIPELINING_SETUP_OPTS, stateLoad (anvil chain dump), and startProverNode. Delegates to
// uniswapL1L2TestSuite which drives L1 Uniswap interactions from L2. Migrate-later candidate — runs in-proc
// but stateLoad dump and prover node need verification before folding into the standard simple suite.
const dumpedState = 'src/fixtures/dumps/uniswap_state';
// When taking a dump use the block number of the fork to improve speed.
const EXPECTED_FORKED_BLOCK = 0; //17514288;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@ function verifyKeyStore(directory: string) {

jest.setTimeout(10 * 60 * 1000);

// Multi-validator key-store test using a Web3Signer sidecar (docker-compose web3signer suite). Runs
// setup() with PIPELINING_SETUP_OPTS and multiple keystores loaded through the NodeKeystoreAdapter and
// Web3Signer, then verifies that blocks are proposed and proven across VALIDATOR_COUNT validators.
describe('e2e_multi_validator_node', () => {
let initialValidatorPrivateKeys: `0x${string}`[];
let validatorAddresses: `0x${string}`[];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ import {

const { L1_CHAIN_ID = '31337' } = process.env;

// Integration test for RemoteSigner against a live Web3Signer instance (docker-compose web3signer suite).
// No Aztec node; exercises EIP-712 typed-data signing and raw transaction signing, comparing remote results
// against a local signer for the same key.
describe('RemoteSigner integration: Web3Signer (compose)', () => {
jest.setTimeout(180_000);

Expand Down
17 changes: 17 additions & 0 deletions yarn-project/end-to-end/src/e2e_2_pxes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ import { TestWallet } from './test-wallet/test_wallet.js';

const TIMEOUT = 300_000;

// Tests multi-PXE isolation: one node with two separate PXE instances attached, each holding different
// account keys. Exercises note decryption scoping, contract registration ordering, and deferred-note
// reprocessing when a contract is registered late. setup(1, AUTOMINE_E2E_OPTS) provides one node with
// automine sequencer; a second PXE is attached via setupPXEAndGetWallet.
describe('e2e_2_pxes', () => {
jest.setTimeout(TIMEOUT);

Expand Down Expand Up @@ -75,6 +79,8 @@ describe('e2e_2_pxes', () => {
await teardownA();
});

// Deploys a Token on PXE A, mints initial balance, transfers A→B via PXE A, then B→A via PXE B.
// Asserts balances visible on each PXE match expectations after each step.
it('transfers funds from user A to B via PXE A followed by transfer from B to A via PXE B', async () => {
const initialBalance = 987n;
const transferAmount1 = 654n;
Expand Down Expand Up @@ -125,6 +131,8 @@ describe('e2e_2_pxes', () => {
const getChildStoredValue = (child: { address: AztecAddress }, node: AztecNode) =>
node.getPublicStorageAt('latest', child.address, new Fr(1));

// Deploys a Child contract via PXE A, registers it on PXE B, then calls a public write from PXE B.
// Asserts the stored value is visible through the shared node regardless of which PXE was used.
it('user calls a public function on a contract deployed by a different user using a different PXE', async () => {
const childCompleteAddress = await deployChildContractViaServerA();

Expand All @@ -143,6 +151,8 @@ describe('e2e_2_pxes', () => {
expect(storedValueOnA).toEqual(newValueToSet);
});

// Mints private balances for two accounts, each on their own PXE. Verifies that querying
// the balance for account A from PXE B returns 0 (key not registered), and vice versa.
it('private state is "zero" when PXE does not have the account secret key', async () => {
const userABalance = 100n;
const userBBalance = 150n;
Expand All @@ -167,6 +177,8 @@ describe('e2e_2_pxes', () => {
await expectTokenBalance(walletA, token, accountBAddress, 0n, logger);
});

// Transfers tokens to PXE B's account before B has registered the contract. Then B registers
// the contract and asserts it can now see its balance from the deferred notes.
it('permits sending funds to a user before they have registered the contract', async () => {
const initialBalance = 987n;
const transferAmount1 = 654n;
Expand All @@ -187,6 +199,9 @@ describe('e2e_2_pxes', () => {
await expectTokenBalance(walletB, token, accountBAddress, transferAmount1, logger);
});

// A shared account is registered on both PXEs. Tokens are sent through the shared account before
// PXE B registers the contract. Verifies deferred-note reprocessing correctly applies nullifiers
// and reconciles balances after late contract registration.
it('permits sending funds to a user, and spending them, before they have registered the contract', async () => {
const initialBalance = 987n;
const transferAmount1 = 654n;
Expand Down Expand Up @@ -226,6 +241,8 @@ describe('e2e_2_pxes', () => {
await expectTokenBalance(walletB, token, sharedAccountAddress, transferAmount1 - transferAmount2, logger);
});

// Sets up a third PXE (C) that has no knowledge of sender A. Transfers tokens A→C, confirms C
// sees 0 balance. Then registers A as a sender on C and confirms the balance is immediately visible.
it('balance updates automatically after sender is registered', async () => {
const initialBalance = 500n;
const transferAmount = 200n;
Expand Down
14 changes: 12 additions & 2 deletions yarn-project/end-to-end/src/e2e_abi_types.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ const U64_MAX = 2n ** 64n - 1n;
const I64_MAX = 2n ** 63n - 1n;
const I64_MIN = -(2n ** 63n);

// Tests that different types are supported to be passed to contract functions and received as return values. This
// mirrors the Noir tests for the AbiTypes contract to make sure that these values can also be passed from TS.
// Tests that different ABI types are correctly encoded when passed to contract functions and decoded from
// return values in TypeScript. Mirrors Noir-side AbiTypes unit tests. Uses setup(1, AUTOMINE_E2E_OPTS)
// providing one node, automine sequencer, and one deployed account.
describe('AbiTypes', () => {
let abiTypesContract: AbiTypesContract;
jest.setTimeout(TIMEOUT);
Expand All @@ -37,6 +38,8 @@ describe('AbiTypes', () => {

afterAll(() => teardown());

// Simulates return_public_parameters with min and max values for bool, Field, u64, i64, and a nested
// struct. Asserts that round-tripped values match the TS originals at both extremes.
it('passes public parameters', async () => {
const { result: minResult } = await abiTypesContract.methods
.return_public_parameters(false, 0n, 0n, I64_MIN, { w: 0n, x: false, y: 0n, z: I64_MIN })
Expand All @@ -62,6 +65,7 @@ describe('AbiTypes', () => {
]);
});

// Same as public parameters but via a private function (return_private_parameters).
it('passes private parameters', async () => {
const { result: minResult } = await abiTypesContract.methods
.return_private_parameters(false, 0n, 0n, I64_MIN, { w: 0n, x: false, y: 0n, z: I64_MIN })
Expand All @@ -87,6 +91,8 @@ describe('AbiTypes', () => {
]);
});

// Passes an EthAddress to the contract and asserts the return value is decoded as an EthAddress instance
// with the same value.
it('decodes EthAddress return value', async () => {
const ethAddr = EthAddress.fromString('0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045');

Expand All @@ -98,6 +104,8 @@ describe('AbiTypes', () => {
expect(result).toEqual(ethAddr);
});

// Passes a FunctionSelector to the contract and asserts round-trip decoding produces an equal
// FunctionSelector instance.
it('decodes FunctionSelector return value', async () => {
const selector = FunctionSelector.fromField(new Fr(0xdeadbeefn));

Expand All @@ -109,6 +117,7 @@ describe('AbiTypes', () => {
expect(result).toEqual(selector);
});

// Passes a wrapped-field value and asserts the return is decoded as an Fr instance equal to Fr(42).
it('decodes wrapped field struct as Fr', async () => {
const value = new Fr(42n);

Expand All @@ -120,6 +129,7 @@ describe('AbiTypes', () => {
expect(result).toEqual(value);
});

// Same as public/private parameters but via a utility (unconstrained view) function.
it('passes utility parameters', async () => {
const { result: minResult } = await abiTypesContract.methods
.return_utility_parameters(false, 0n, 0n, I64_MIN, { w: 0n, x: false, y: 0n, z: I64_MIN })
Expand Down
12 changes: 12 additions & 0 deletions yarn-project/end-to-end/src/e2e_account_contracts.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ export class TestWalletInternals extends TestWallet {
const itShouldBehaveLikeAnAccountContract = (
getAccountContract: (encryptionKey: GrumpkinScalar) => AccountContract,
) => {
// Shared suite parametrized over account contract type. Creates one account from the supplied
// AccountContract implementation (deploying it only if it has an initializer — initializerless
// variants skip the deploy tx) and exercises private calls, public calls, and signature failure.
describe(`behaves like an account contract`, () => {
let aztecNode: AztecNode;
let logger: Logger;
Expand Down Expand Up @@ -80,18 +83,22 @@ const itShouldBehaveLikeAnAccountContract = (

afterAll(() => teardown());

// Sends a private function call on ChildContract and asserts it does not revert.
it('calls a private function', async () => {
logger.info('Calling private function...');
await child.methods.value(42).send({ from: completeAddress.address });
});

// Calls pub_inc_value on the deployed Child contract and reads the resulting stored value via the node.
it('calls a public function', async () => {
logger.info('Calling public function...');
await child.methods.pub_inc_value(42).send({ from: completeAddress.address });
const storedValue = await aztecNode.getPublicStorageAt('latest', child.address, new Fr(1));
expect(storedValue).toEqual(new Fr(42n));
});

// Swaps out the account's AuthWitnessProvider for one holding a random key, then simulates
// a private call and expects a "Cannot satisfy constraint" rejection.
it('fails to call a function using an invalid signature', async () => {
const randomContract = getAccountContract(GrumpkinScalar.random());
const authWitnessProvider = randomContract.getAuthWitnessProvider(completeAddress);
Expand All @@ -108,6 +115,11 @@ const itShouldBehaveLikeAnAccountContract = (
});
};

// Tests that multiple account contract implementations (Schnorr, Schnorr-initializerless, and ECDSA
// stored-key) satisfy the common account contract interface. Each variant gets its own
// setup(0, AUTOMINE_E2E_OPTS) with an additionallyFundedAccounts override, one node, automine sequencer,
// no extra nodes. (v5: added the initializerless variant and renamed initialFundedAccounts →
// additionallyFundedAccounts.)
describe('e2e_account_contracts', () => {
describe('schnorr account', () => {
itShouldBehaveLikeAnAccountContract(() => new SchnorrAccountContract(GrumpkinScalar.random()));
Expand Down
Loading
Loading