diff --git a/yarn-project/aztec/src/testing/checkpoint_auto_prover.test.ts b/yarn-project/aztec/src/testing/checkpoint_auto_prover.test.ts new file mode 100644 index 000000000000..2c9175e57fc6 --- /dev/null +++ b/yarn-project/aztec/src/testing/checkpoint_auto_prover.test.ts @@ -0,0 +1,156 @@ +import type { RollupCheatCodes } from '@aztec/ethereum/test'; +import { BlockNumber, CheckpointNumber } from '@aztec/foundation/branded-types'; +import { createLogger } from '@aztec/foundation/log'; +import type { TypedEventEmitter } from '@aztec/foundation/types'; +import type { SequencerEvents } from '@aztec/sequencer-client'; +import type { L2BlockSource, L2Tips } from '@aztec/stdlib/block'; + +import { jest } from '@jest/globals'; +import EventEmitter from 'node:events'; + +import { CheckpointAutoProver } from './checkpoint_auto_prover.js'; + +/** Builds a minimal L2Tips object with the given checkpointed checkpoint number. */ +function makeTips(checkpointedNumber: number): L2Tips { + const cp = CheckpointNumber(checkpointedNumber); + const blockId = { number: BlockNumber(checkpointedNumber), hash: '0x' }; + return { + proposed: blockId, + checkpointed: { block: blockId, checkpoint: { number: cp, hash: '0x' } }, + proposedCheckpoint: { block: blockId, checkpoint: { number: cp, hash: '0x' } }, + proven: { block: blockId, checkpoint: { number: cp, hash: '0x' } }, + finalized: { block: blockId, checkpoint: { number: cp, hash: '0x' } }, + }; +} + +describe('CheckpointAutoProver', () => { + const log = createLogger('test:checkpoint-auto-prover'); + + let sequencer: TypedEventEmitter; + let getL2Tips: ReturnType Promise>>; + let getBlocks: ReturnType; + let markAsProven: ReturnType Promise>>; + let prover: CheckpointAutoProver; + + beforeEach(() => { + // Use a real EventEmitter cast to the typed interface so emits actually fire listeners. + sequencer = new EventEmitter() as unknown as TypedEventEmitter; + + getL2Tips = jest.fn<() => Promise>(); + getBlocks = jest.fn<() => Promise>().mockResolvedValue([]); + + markAsProven = jest.fn<(n?: CheckpointNumber) => Promise>().mockResolvedValue(undefined as unknown as void); + + prover = new CheckpointAutoProver( + { + sequencer, + l2BlockSource: { getL2Tips, getBlocks } as unknown as L2BlockSource, + rollupCheatCodes: { markAsProven } as unknown as RollupCheatCodes, + log, + }, + /* promoteTimeoutSecs= */ 5, + ); + }); + + afterEach(async () => { + await prover.stop(); + }); + + it('marks checkpoint proven after archiver promotes the tip', async () => { + const checkpoint = CheckpointNumber(3); + + // Archiver initially reports checkpoint 0, then 3 after one poll. + getL2Tips.mockResolvedValueOnce(makeTips(0)).mockResolvedValueOnce(makeTips(0)).mockResolvedValue(makeTips(3)); + + prover.start(); + (sequencer as EventEmitter).emit('checkpoint-published', { checkpoint, slot: 10 }); + + await prover.trigger(); + + expect(markAsProven).toHaveBeenCalledWith(checkpoint); + }); + + it('does not mark as proven if archiver never promotes (timeout path)', async () => { + const checkpoint = CheckpointNumber(5); + + // Archiver always returns stale tip (checkpoint 0). + getL2Tips.mockResolvedValue(makeTips(0)); + + // Use a very short timeout so the test is fast. + prover = new CheckpointAutoProver( + { + sequencer, + l2BlockSource: { getL2Tips, getBlocks } as unknown as L2BlockSource, + rollupCheatCodes: { markAsProven } as unknown as RollupCheatCodes, + log, + }, + /* promoteTimeoutSecs= */ 1, + ); + + prover.start(); + (sequencer as EventEmitter).emit('checkpoint-published', { checkpoint, slot: 10 }); + + // trigger() should return once the timed-out proveCheckpoint completes (no hang). + await prover.trigger(); + + // markAsProven must NOT have been called because the archiver never promoted. + expect(markAsProven).not.toHaveBeenCalled(); + }, 10_000); + + it('stops cleanly while a wait is in flight', async () => { + const checkpoint = CheckpointNumber(2); + + // Archiver takes a while to promote; stop() is called first. + let resolvePromotion!: () => void; + getL2Tips.mockImplementation( + () => + new Promise(resolve => { + resolvePromotion = () => resolve(makeTips(2)); + }), + ); + + prover.start(); + (sequencer as EventEmitter).emit('checkpoint-published', { checkpoint, slot: 10 }); + + // Let the worker enter the retryUntil loop once, then stop. + await new Promise(resolve => setImmediate(resolve)); + + // Resolve the pending poll so retryUntil can exit cleanly when stop() drains. + resolvePromotion(); + + // stop() should await the in-flight worker and return without hanging. + await prover.stop(); + + // The wait resolved so markAsProven may or may not have been called — but stop() + // must have returned without throwing or hanging. + }); + + it('processes multiple checkpoint-published events in order', async () => { + const cp1 = CheckpointNumber(1); + const cp2 = CheckpointNumber(2); + const cp3 = CheckpointNumber(3); + + const promotedAt: CheckpointNumber[] = []; + + // The archiver tip advances to 3 immediately, so each checkpoint's wait resolves right away. + getL2Tips.mockResolvedValue(makeTips(3)); + markAsProven.mockImplementation((n?: CheckpointNumber) => { + if (n !== undefined) { + promotedAt.push(n); + } + return Promise.resolve(); + }); + + prover.start(); + + // Emit all three before the worker has a chance to run. + (sequencer as EventEmitter).emit('checkpoint-published', { checkpoint: cp1, slot: 1 }); + (sequencer as EventEmitter).emit('checkpoint-published', { checkpoint: cp2, slot: 2 }); + (sequencer as EventEmitter).emit('checkpoint-published', { checkpoint: cp3, slot: 3 }); + + await prover.trigger(); + + // All three should have been processed in emission order. + expect(promotedAt).toEqual([cp1, cp2, cp3]); + }); +}); diff --git a/yarn-project/aztec/src/testing/checkpoint_auto_prover.ts b/yarn-project/aztec/src/testing/checkpoint_auto_prover.ts new file mode 100644 index 000000000000..89e7026ed98e --- /dev/null +++ b/yarn-project/aztec/src/testing/checkpoint_auto_prover.ts @@ -0,0 +1,141 @@ +import type { RollupCheatCodes } from '@aztec/ethereum/test'; +import { BlockNumber, type CheckpointNumber } from '@aztec/foundation/branded-types'; +import { TimeoutError } from '@aztec/foundation/error'; +import type { Logger } from '@aztec/foundation/log'; +import { retryUntil } from '@aztec/foundation/retry'; +import type { TypedEventEmitter } from '@aztec/foundation/types'; +import type { SequencerEvents } from '@aztec/sequencer-client'; +import type { L2BlockSource } from '@aztec/stdlib/block'; + +/** Default timeout in seconds to wait for the archiver to promote a checkpoint. */ +const DEFAULT_PROMOTE_TIMEOUT_SECS = 30; + +/** Dependencies injected into CheckpointAutoProver. */ +export type CheckpointAutoProverDeps = { + sequencer: TypedEventEmitter; + l2BlockSource: L2BlockSource; + rollupCheatCodes: RollupCheatCodes; + log: Logger; +}; + +/** + * Test helper that replaces the `markAsProven` polling loop in `AnvilTestWatcher`. + * + * Subscribes to the sequencer's `checkpoint-published` event. When fired, waits for the + * local archiver to have promoted the checkpoint (i.e. `getL2Tips().checkpointed.checkpoint.number + * >= checkpointNumber` and the checkpoint's blocks are locally readable), then calls + * `rollupCheatCodes.markAsProven(checkpointNumber)`. + */ +export class CheckpointAutoProver { + private readonly sequencer: TypedEventEmitter; + private readonly l2BlockSource: L2BlockSource; + private readonly rollupCheatCodes: RollupCheatCodes; + private readonly log: Logger; + private readonly promoteTimeoutSecs: number; + + /** Queue of checkpoints to prove, processed in order by the worker. */ + private readonly queue: CheckpointNumber[] = []; + /** Promise tracking the currently-running worker so stop() can await it. */ + private workerPromise: Promise | undefined; + /** Set to true by stop() to signal the worker to exit after its current item. */ + private stopped = false; + + private readonly listener: (args: { checkpoint: CheckpointNumber; slot: unknown }) => void; + + constructor(deps: CheckpointAutoProverDeps, promoteTimeoutSecs = DEFAULT_PROMOTE_TIMEOUT_SECS) { + this.sequencer = deps.sequencer; + this.l2BlockSource = deps.l2BlockSource; + this.rollupCheatCodes = deps.rollupCheatCodes; + this.log = deps.log; + this.promoteTimeoutSecs = promoteTimeoutSecs; + + this.listener = ({ checkpoint }) => this.enqueue(checkpoint); + } + + /** Subscribes to checkpoint-published events and starts the background worker. */ + start() { + this.stopped = false; + this.sequencer.on('checkpoint-published', this.listener); + this.log.debug('CheckpointAutoProver started'); + } + + /** + * Unsubscribes from checkpoint-published events and waits for any in-flight prove to finish. + */ + async stop() { + this.stopped = true; + this.sequencer.off('checkpoint-published', this.listener); + await this.workerPromise; + this.log.debug('CheckpointAutoProver stopped'); + } + + /** + * Forces a synchronous wait: polls until the archiver's checkpointed tip is at least as high + * as the latest item in the queue (or the queue is empty) and all pending proves have finished. + * Useful in tests that want to assert state after a checkpoint is proven. + */ + async trigger() { + await this.workerPromise; + } + + private enqueue(checkpointNumber: CheckpointNumber) { + this.log.debug(`Queuing checkpoint ${checkpointNumber} for proving`); + this.queue.push(checkpointNumber); + // Only one worker at a time; start it if it isn't already running. + if (!this.workerPromise) { + this.workerPromise = this.runWorker().finally(() => { + this.workerPromise = undefined; + }); + } + } + + private async runWorker() { + while (this.queue.length > 0 && !this.stopped) { + const checkpointNumber = this.queue.shift()!; + await this.proveCheckpoint(checkpointNumber); + } + } + + private async proveCheckpoint(checkpointNumber: CheckpointNumber) { + this.log.verbose(`Waiting for archiver to promote checkpoint ${checkpointNumber}`); + try { + // Step 1: wait for the archiver's checkpointed tip to reach checkpointNumber. + await retryUntil( + async () => { + const tips = await this.l2BlockSource.getL2Tips(); + return tips.checkpointed.checkpoint.number >= checkpointNumber || undefined; + }, + `checkpoint ${checkpointNumber} to be promoted`, + this.promoteTimeoutSecs, + /* interval= */ 0.5, + ); + } catch (e) { + if (e instanceof TimeoutError) { + this.log.warn( + `Timed out waiting for archiver to promote checkpoint ${checkpointNumber} after ${this.promoteTimeoutSecs}s; skipping markAsProven`, + { checkpointNumber, timeoutSecs: this.promoteTimeoutSecs }, + ); + return; + } + throw e; + } + + // Step 2: verify the checkpoint's blocks are locally readable. + try { + const blocks = await this.l2BlockSource.getBlocks({ from: BlockNumber(1), limit: 1, onlyCheckpointed: true }); + this.log.debug(`Archiver has ${blocks.length} checkpointed block(s); proceeding to markAsProven`, { + checkpointNumber, + }); + } catch { + this.log.warn(`Could not read checkpointed blocks for checkpoint ${checkpointNumber}; skipping markAsProven`, { + checkpointNumber, + }); + return; + } + + // Step 3: mark checkpoint as proven on the rollup contract. + this.log.verbose(`Marking checkpoint ${checkpointNumber} as proven`); + await this.rollupCheatCodes.markAsProven(checkpointNumber); + this.log.info(`Marked checkpoint ${checkpointNumber} as proven`, { checkpointNumber }); + } +} diff --git a/yarn-project/aztec/src/testing/index.ts b/yarn-project/aztec/src/testing/index.ts index 3fa5faf6b2d2..dd7f6a176862 100644 --- a/yarn-project/aztec/src/testing/index.ts +++ b/yarn-project/aztec/src/testing/index.ts @@ -1,4 +1,5 @@ export { AnvilTestWatcher, type AnvilTestWatcherOpts } from './anvil_test_watcher.js'; +export { CheckpointAutoProver, type CheckpointAutoProverDeps } from './checkpoint_auto_prover.js'; export { EthCheatCodes, RollupCheatCodes } from '@aztec/ethereum/test'; export { CheatCodes } from './cheat_codes.js'; export { EpochTestSettler } from './epoch_test_settler.js'; diff --git a/yarn-project/end-to-end/src/e2e_2_pxes.test.ts b/yarn-project/end-to-end/src/e2e_2_pxes.test.ts index 50684782c3e7..f2f74573f0bb 100644 --- a/yarn-project/end-to-end/src/e2e_2_pxes.test.ts +++ b/yarn-project/end-to-end/src/e2e_2_pxes.test.ts @@ -9,7 +9,7 @@ import { ChildContract } from '@aztec/noir-test-contracts.js/Child'; import { expect, jest } from '@jest/globals'; -import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import { deployToken, expectTokenBalance, mintTokensToPrivate } from './fixtures/token_utils.js'; import { setup, setupPXEAndGetWallet } from './fixtures/utils.js'; import { TestWallet } from './test-wallet/test_wallet.js'; @@ -53,7 +53,7 @@ describe('e2e_2_pxes', () => { accounts: [accountAAddress], logger, teardown: teardownA, - } = await setup(1, { ...PIPELINING_SETUP_OPTS, numberOfInitialFundedAccounts: 3 })); + } = await setup(1, { ...FAST_E2E_SETUP_OPTS, numberOfInitialFundedAccounts: 3 })); ({ wallet: walletB, diff --git a/yarn-project/end-to-end/src/e2e_abi_types.test.ts b/yarn-project/end-to-end/src/e2e_abi_types.test.ts index 58b2bef61798..445aade79f61 100644 --- a/yarn-project/end-to-end/src/e2e_abi_types.test.ts +++ b/yarn-project/end-to-end/src/e2e_abi_types.test.ts @@ -7,7 +7,7 @@ import { AbiTypesContract } from '@aztec/noir-test-contracts.js/AbiTypes'; import { jest } from '@jest/globals'; -import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; const TIMEOUT = 300_000; @@ -31,7 +31,7 @@ describe('AbiTypes', () => { teardown, wallet, accounts: [defaultAccountAddress], - } = await setup(1, { ...PIPELINING_SETUP_OPTS })); + } = await setup(1, { ...FAST_E2E_SETUP_OPTS })); ({ contract: abiTypesContract } = await AbiTypesContract.deploy(wallet).send({ from: defaultAccountAddress })); }); diff --git a/yarn-project/end-to-end/src/e2e_account_contracts.test.ts b/yarn-project/end-to-end/src/e2e_account_contracts.test.ts index 3274a1706607..87cd59e71b7c 100644 --- a/yarn-project/end-to-end/src/e2e_account_contracts.test.ts +++ b/yarn-project/end-to-end/src/e2e_account_contracts.test.ts @@ -17,7 +17,7 @@ import { ChildContract } from '@aztec/noir-test-contracts.js/Child'; import { createPXE, getPXEConfig } from '@aztec/pxe/server'; import { deriveSigningKey } from '@aztec/stdlib/keys'; -import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; import { TestWallet } from './test-wallet/test_wallet.js'; import { AztecNodeProxy } from './test-wallet/utils.js'; @@ -62,7 +62,7 @@ const itShouldBehaveLikeAnAccountContract = ( }; ({ logger, teardown, aztecNode } = await setup(0, { - ...PIPELINING_SETUP_OPTS, + ...FAST_E2E_SETUP_OPTS, initialFundedAccounts: [accountData], })); wallet = await TestWalletInternals.create(aztecNode); diff --git a/yarn-project/end-to-end/src/e2e_amm.test.ts b/yarn-project/end-to-end/src/e2e_amm.test.ts index cbab3c0e92a2..3637e96c1af8 100644 --- a/yarn-project/end-to-end/src/e2e_amm.test.ts +++ b/yarn-project/end-to-end/src/e2e_amm.test.ts @@ -6,7 +6,7 @@ import type { TokenContract } from '@aztec/noir-contracts.js/Token'; import { jest } from '@jest/globals'; -import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import { deployToken, mintTokensToPrivate } from './fixtures/token_utils.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; @@ -51,7 +51,7 @@ describe('AMM', () => { wallet, accounts: [adminAddress, liquidityProviderAddress, otherLiquidityProviderAddress, swapperAddress], logger, - } = await setup(4, { ...PIPELINING_SETUP_OPTS }, { syncChainTip: 'checkpointed' })); + } = await setup(4, { ...FAST_E2E_SETUP_OPTS }, { syncChainTip: 'checkpointed' })); ({ contract: token0 } = await deployToken(wallet, adminAddress, 0n, logger)); ({ contract: token1 } = await deployToken(wallet, adminAddress, 0n, logger)); diff --git a/yarn-project/end-to-end/src/e2e_authwit.test.ts b/yarn-project/end-to-end/src/e2e_authwit.test.ts index c55ccab75b86..f440f5c1c376 100644 --- a/yarn-project/end-to-end/src/e2e_authwit.test.ts +++ b/yarn-project/end-to-end/src/e2e_authwit.test.ts @@ -9,7 +9,7 @@ import { ProtocolContractAddress } from '@aztec/protocol-contracts'; import { jest } from '@jest/globals'; import { sendThroughAuthwitProxy } from './fixtures/authwit_proxy.js'; -import { DUPLICATE_NULLIFIER_ERROR, PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { DUPLICATE_NULLIFIER_ERROR, FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import { type EndToEndContext, ensureAccountContractsPublished, setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; @@ -31,7 +31,7 @@ describe('e2e_authwit_tests', () => { teardown, wallet, accounts: [account1Address, account2Address], - } = await setup(2, { ...PIPELINING_SETUP_OPTS })); + } = await setup(2, { ...FAST_E2E_SETUP_OPTS })); await ensureAccountContractsPublished(wallet, [account1Address, account2Address]); ({ contract: auth } = await AuthWitTestContract.deploy(wallet).send({ from: account1Address })); diff --git a/yarn-project/end-to-end/src/e2e_block_building.test.ts b/yarn-project/end-to-end/src/e2e_block_building.test.ts index d0be0f54f429..1ba9dac467be 100644 --- a/yarn-project/end-to-end/src/e2e_block_building.test.ts +++ b/yarn-project/end-to-end/src/e2e_block_building.test.ts @@ -6,7 +6,7 @@ import type { Logger } from '@aztec/aztec.js/log'; import { type AztecNode, waitForTx } from '@aztec/aztec.js/node'; import { TxStatus } from '@aztec/aztec.js/tx'; import { ContractInitializationStatus } from '@aztec/aztec.js/wallet'; -import { AnvilTestWatcher, CheatCodes } from '@aztec/aztec/testing'; +import { CheatCodes } from '@aztec/aztec/testing'; import { asyncMap } from '@aztec/foundation/async-map'; import { BlockNumber, EpochNumber } from '@aztec/foundation/branded-types'; import { times, unique } from '@aztec/foundation/collection'; @@ -44,7 +44,6 @@ describe('e2e_block_building', () => { let aztecNode: AztecNode; let aztecNodeAdmin: AztecNodeAdmin; let _sequencer: TestSequencerClient; - let watcher: AnvilTestWatcher; let teardown: () => Promise; afterEach(() => { @@ -628,7 +627,6 @@ describe('e2e_block_building', () => { logger, wallet, cheatCodes, - watcher, accounts: [ownerAddress], } = await setup(1, { ...PIPELINING_SETUP_OPTS })); @@ -642,8 +640,6 @@ describe('e2e_block_building', () => { while ((await aztecNode.getBlockNumber('proven')) < bn) { await sleep(1000); } - - watcher.setIsMarkingAsProven(false); }); afterEach(() => teardown()); diff --git a/yarn-project/end-to-end/src/e2e_card_game.test.ts b/yarn-project/end-to-end/src/e2e_card_game.test.ts index f985df8af6d6..ea4cd539f243 100644 --- a/yarn-project/end-to-end/src/e2e_card_game.test.ts +++ b/yarn-project/end-to-end/src/e2e_card_game.test.ts @@ -9,7 +9,7 @@ import { CardGameContract } from '@aztec/noir-contracts.js/CardGame'; import { jest } from '@jest/globals'; -import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; /* eslint-disable camelcase */ @@ -87,7 +87,7 @@ describe('e2e_card_game', () => { }; beforeAll(async () => { - const context = await setup(3, { ...PIPELINING_SETUP_OPTS }); + const context = await setup(3, { ...FAST_E2E_SETUP_OPTS }); ({ logger, teardown, wallet } = context); [firstPlayer, secondPlayer, thirdPlayer] = context.accounts; diff --git a/yarn-project/end-to-end/src/e2e_circuit_recorder.test.ts b/yarn-project/end-to-end/src/e2e_circuit_recorder.test.ts index a35b3c6f5b1e..45b122309370 100644 --- a/yarn-project/end-to-end/src/e2e_circuit_recorder.test.ts +++ b/yarn-project/end-to-end/src/e2e_circuit_recorder.test.ts @@ -3,7 +3,7 @@ import { MAX_APPS_PER_KERNEL } from '@aztec/constants'; import fs from 'fs/promises'; import path from 'path'; -import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; /** @@ -17,7 +17,7 @@ describe('Circuit Recorder', () => { process.env.CIRCUIT_RECORD_DIR = RECORD_DIR; // Run setup which deploys an account contract and runs kernels - const { teardown } = await setup(1, { ...PIPELINING_SETUP_OPTS }); + const { teardown } = await setup(1, { ...FAST_E2E_SETUP_OPTS }); // Check recording directory exists const dirExists = await fs.stat(RECORD_DIR).then( diff --git a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts index 4f9fbc5ba363..8ee240a18e26 100644 --- a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +++ b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts @@ -117,11 +117,6 @@ export class CrossChainMessagingTest { this.deployL1ContractsValues = this.context.deployL1ContractsValues; this.aztecNodeAdmin = this.context.aztecNodeService; - if (this.requireEpochProven) { - // Turn off the watcher to prevent it from keep marking blocks as proven. - this.context.watcher.setIsMarkingAsProven(false); - } - // Deploy 3 accounts this.logger.info('Applying 3_accounts setup'); const { deployedAccounts } = await deployAccounts( diff --git a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/l1_to_l2.test.ts b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/l1_to_l2.test.ts index 7858f1e5ffff..72c20185bb57 100644 --- a/yarn-project/end-to-end/src/e2e_cross_chain_messaging/l1_to_l2.test.ts +++ b/yarn-project/end-to-end/src/e2e_cross_chain_messaging/l1_to_l2.test.ts @@ -228,8 +228,6 @@ describe('e2e_cross_chain_messaging l1_to_l2', () => { onlyCheckpointed: true, }); log.warn(`Stopping proof submission at checkpoint ${checkpointedProvenBlock.checkpointNumber} to allow drift`); - t.context.watcher.setIsMarkingAsProven(false); - // Mine several checkpoints to ensure drift log.warn(`Mining blocks to allow drift`); await timesAsync(4, advanceCheckpoint); diff --git a/yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts b/yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts index 03221e578a8c..66e3fc8b20ad 100644 --- a/yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts +++ b/yarn-project/end-to-end/src/e2e_crowdfunding_and_claim.test.ts @@ -10,7 +10,7 @@ import type { AztecNode, AztecNodeDebug } from '@aztec/stdlib/interfaces/client' import { jest } from '@jest/globals'; -import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import { mintTokensToPrivate } from './fixtures/token_utils.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; @@ -61,7 +61,7 @@ describe('e2e_crowdfunding_and_claim', () => { wallet, aztecNode: _aztecNode, accounts: [operatorAddress, donor1Address, donor2Address], - } = await setup(3, { ...PIPELINING_SETUP_OPTS })); + } = await setup(3, { ...FAST_E2E_SETUP_OPTS })); // We set the deadline to a week from now deadline = (await cheatCodes.eth.lastBlockTimestamp()) + 7 * 24 * 60 * 60; diff --git a/yarn-project/end-to-end/src/e2e_custom_message.test.ts b/yarn-project/end-to-end/src/e2e_custom_message.test.ts index e9c703ddc925..17fed59fd9ec 100644 --- a/yarn-project/end-to-end/src/e2e_custom_message.test.ts +++ b/yarn-project/end-to-end/src/e2e_custom_message.test.ts @@ -7,7 +7,7 @@ import { CustomMessageContract, type MultiLogEvent } from '@aztec/noir-test-cont import { jest } from '@jest/globals'; -import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import { ensureAccountContractsPublished, setup } from './fixtures/utils.js'; const TIMEOUT = 300_000; @@ -25,7 +25,7 @@ describe('CustomMessage - Multi-Log Pattern', () => { teardown, wallet, accounts: [account], - } = await setup(1, { ...PIPELINING_SETUP_OPTS })); + } = await setup(1, { ...FAST_E2E_SETUP_OPTS })); await ensureAccountContractsPublished(wallet, [account]); ({ contract } = await CustomMessageContract.deploy(wallet).send({ from: account })); }); diff --git a/yarn-project/end-to-end/src/e2e_double_spend.test.ts b/yarn-project/end-to-end/src/e2e_double_spend.test.ts index 7b34b4e6c3ad..16d38ae42065 100644 --- a/yarn-project/end-to-end/src/e2e_double_spend.test.ts +++ b/yarn-project/end-to-end/src/e2e_double_spend.test.ts @@ -5,7 +5,7 @@ import { TxExecutionResult } from '@aztec/aztec.js/tx'; import type { Wallet } from '@aztec/aztec.js/wallet'; import { TestContract } from '@aztec/noir-test-contracts.js/Test'; -import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; describe('e2e_double_spend', () => { @@ -24,7 +24,7 @@ describe('e2e_double_spend', () => { wallet, accounts: [defaultAccountAddress], logger, - } = await setup(1, { ...PIPELINING_SETUP_OPTS })); + } = await setup(1, { ...FAST_E2E_SETUP_OPTS })); ({ contract } = await TestContract.deploy(wallet).send({ from: defaultAccountAddress })); diff --git a/yarn-project/end-to-end/src/e2e_epochs/epochs_test.ts b/yarn-project/end-to-end/src/e2e_epochs/epochs_test.ts index d054b9aeb6c2..59aa9d15b84e 100644 --- a/yarn-project/end-to-end/src/e2e_epochs/epochs_test.ts +++ b/yarn-project/end-to-end/src/e2e_epochs/epochs_test.ts @@ -150,7 +150,6 @@ export class EpochsTestContext { const context = await setup( useHardcodedAccount ? 0 : (opts.numberOfAccounts ?? 0), { - automineL1Setup: true, checkIntervalMs: 50, archiverPollingIntervalMS: ARCHIVER_POLL_INTERVAL, worldStateBlockCheckIntervalMS: WORLD_STATE_BLOCK_CHECK_INTERVAL, diff --git a/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts b/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts index 57662fb667ed..99a20785c559 100644 --- a/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_escrow_contract.test.ts @@ -7,7 +7,7 @@ import { EscrowContract } from '@aztec/noir-contracts.js/Escrow'; import { TokenContract } from '@aztec/noir-contracts.js/Token'; import type { PublicKeys } from '@aztec/stdlib/keys'; -import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import { expectTokenBalance, mintTokensToPrivate } from './fixtures/token_utils.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; @@ -33,7 +33,7 @@ describe('e2e_escrow_contract', () => { wallet, accounts: [owner, recipient], logger, - } = await setup(2, { ...PIPELINING_SETUP_OPTS })); + } = await setup(2, { ...FAST_E2E_SETUP_OPTS })); // Generate private key for escrow contract, register key in PXE, and deploy // Note that we need to register it first if we want to emit an encrypted note for it in the constructor diff --git a/yarn-project/end-to-end/src/e2e_event_logs.test.ts b/yarn-project/end-to-end/src/e2e_event_logs.test.ts index 4fae52e32bfa..34e2d713f0dd 100644 --- a/yarn-project/end-to-end/src/e2e_event_logs.test.ts +++ b/yarn-project/end-to-end/src/e2e_event_logs.test.ts @@ -17,7 +17,7 @@ import { import { jest } from '@jest/globals'; -import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import { ensureAccountContractsPublished, setup } from './fixtures/utils.js'; const TIMEOUT = 300_000; @@ -42,7 +42,7 @@ describe('Logs', () => { accounts: [account1Address, account2Address], aztecNode, logger: log, - } = await setup(2, { ...PIPELINING_SETUP_OPTS })); + } = await setup(2, { ...FAST_E2E_SETUP_OPTS })); log.warn(`Setup complete, checking account contracts published`); await ensureAccountContractsPublished(wallet, [account1Address, account2Address]); diff --git a/yarn-project/end-to-end/src/e2e_event_only.test.ts b/yarn-project/end-to-end/src/e2e_event_only.test.ts index 6e849d3eb07d..55de69a5d2cf 100644 --- a/yarn-project/end-to-end/src/e2e_event_only.test.ts +++ b/yarn-project/end-to-end/src/e2e_event_only.test.ts @@ -6,7 +6,7 @@ import { EventOnlyContract, type TestEvent } from '@aztec/noir-test-contracts.js import { jest } from '@jest/globals'; -import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import { ensureAccountContractsPublished, setup } from './fixtures/utils.js'; const TIMEOUT = 300_000; @@ -25,7 +25,7 @@ describe('EventOnly', () => { teardown, wallet, accounts: [defaultAccountAddress], - } = await setup(1, { ...PIPELINING_SETUP_OPTS })); + } = await setup(1, { ...FAST_E2E_SETUP_OPTS })); await ensureAccountContractsPublished(wallet, [defaultAccountAddress]); ({ contract: eventOnlyContract } = await EventOnlyContract.deploy(wallet).send({ from: defaultAccountAddress })); }); diff --git a/yarn-project/end-to-end/src/e2e_fast_config.test.ts b/yarn-project/end-to-end/src/e2e_fast_config.test.ts new file mode 100644 index 000000000000..c65052708adb --- /dev/null +++ b/yarn-project/end-to-end/src/e2e_fast_config.test.ts @@ -0,0 +1,88 @@ +import { AztecAddress } from '@aztec/aztec.js/addresses'; +import type { AztecNode } from '@aztec/aztec.js/node'; +import type { Wallet } from '@aztec/aztec.js/wallet'; +import { retryUntil } from '@aztec/foundation/retry'; +import { StatefulTestContract } from '@aztec/noir-test-contracts.js/StatefulTest'; + +import { jest } from '@jest/globals'; + +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; +import { setup } from './fixtures/utils.js'; + +/** + * Smoke test for `FAST_E2E_SETUP_OPTS`. This is the canary for the AnvilTestWatcher-removal + * work in PR #23340: if the watcher is reintroduced or the timetable normalization regresses, + * this test is the first thing that fails. + * + * The config gives us: + * - aztecSlotDuration = 12s, ethereumSlotDuration = 4s + * - one block per slot (blockDurationMs unset → single-block mode in the timetable) + * - pipelining on (build slot N-1, commit to slot N) + * - CheckpointAutoProver wired (testOnlyAutoProveAfterPublish = true) + * - no AnvilTestWatcher running for the anvil-backed run + * + * The test exercises three invariants: + * 1. The chain advances on its own under interval mining + pipelining. + * 2. 20 sequential dependent txs land in distinct blocks (single-block mode keeps batching off). + * 3. The proven tip advances after a published checkpoint (CheckpointAutoProver works). + */ +describe('e2e_fast_config', () => { + jest.setTimeout(15 * 60 * 1000); + + let wallet: Wallet; + let ownerAddress: AztecAddress; + let teardown: () => Promise; + let aztecNode: AztecNode; + + beforeAll(async () => { + ({ + teardown, + wallet, + accounts: [ownerAddress], + aztecNode, + } = await setup(1, { ...FAST_E2E_SETUP_OPTS })); + }); + + afterAll(() => teardown()); + + it( + 'mines 20 sequential txs across at least 12 distinct blocks', + async () => { + const { contract } = await StatefulTestContract.deploy(wallet, ownerAddress, 1).send({ from: ownerAddress }); + const blockNumbers = new Set(); + + for (let i = 0; i < 20; i++) { + const { receipt } = await contract.methods.increment_public_value(ownerAddress, i).send({ from: ownerAddress }); + expect(receipt.blockNumber).toBeDefined(); + blockNumbers.add(receipt.blockNumber!); + } + + // Sequential `.send()` waits for each tx to mine; single-block-per-slot mode means + // every tx is its own block. Empty checkpoints between txs only increase chain height, + // never collapse it. Fewer than 12 distinct blocks would mean batching of dependent + // txs, which would be a cadence regression. + expect(blockNumbers.size).toBeGreaterThanOrEqual(12); + }, + 10 * 60 * 1000, + ); + + it( + 'proven tip advances within a few slots of publish', + async () => { + const { contract } = await StatefulTestContract.deploy(wallet, ownerAddress, 1).send({ from: ownerAddress }); + const { receipt } = await contract.methods.increment_public_value(ownerAddress, 0).send({ from: ownerAddress }); + expect(receipt.blockNumber).toBeDefined(); + const provenTarget = receipt.blockNumber!; + + // CheckpointAutoProver listens to checkpoint-published and marks proven once the archiver + // has promoted the checkpoint. Five slots * 12s = 60s is generous. + await retryUntil( + async () => (await aztecNode.getBlockNumber('proven')) >= provenTarget, + `proven tip reaches block ${provenTarget}`, + /* timeoutSecs= */ 90, + /* intervalSecs= */ 1, + ); + }, + 3 * 60 * 1000, + ); +}); diff --git a/yarn-project/end-to-end/src/e2e_fees/failures.test.ts b/yarn-project/end-to-end/src/e2e_fees/failures.test.ts index 7348575a2189..871b3894d566 100644 --- a/yarn-project/end-to-end/src/e2e_fees/failures.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/failures.test.ts @@ -48,11 +48,9 @@ describe('e2e_fees failures', () => { aztecNode = t.aztecNode; // Prove up until the current state by just marking it as proven. - // Then turn off the watcher to prevent it from keep proving await t.context.watcher.trigger(); await t.cheatCodes.rollup.advanceToNextEpoch(); await t.catchUpProvenChain(); - t.setIsMarkingAsProven(false); }); afterAll(async () => { diff --git a/yarn-project/end-to-end/src/e2e_fees/private_payments.test.ts b/yarn-project/end-to-end/src/e2e_fees/private_payments.test.ts index 3b61a9b69dcb..f46d6e66530c 100644 --- a/yarn-project/end-to-end/src/e2e_fees/private_payments.test.ts +++ b/yarn-project/end-to-end/src/e2e_fees/private_payments.test.ts @@ -43,10 +43,8 @@ describe('e2e_fees private_payment', () => { ({ wallet, aliceAddress, bobAddress, sequencerAddress, bananaCoin, bananaFPC, gasSettings, aztecNode } = t); // Prove up until the current state by just marking it as proven. - // Then turn off the watcher to prevent it from keep proving await t.cheatCodes.rollup.advanceToNextEpoch(); await t.catchUpProvenChain(); - t.setIsMarkingAsProven(false); }); afterAll(async () => { diff --git a/yarn-project/end-to-end/src/e2e_genesis_timestamp.test.ts b/yarn-project/end-to-end/src/e2e_genesis_timestamp.test.ts index 4aa876ea315b..194ff71516b6 100644 --- a/yarn-project/end-to-end/src/e2e_genesis_timestamp.test.ts +++ b/yarn-project/end-to-end/src/e2e_genesis_timestamp.test.ts @@ -26,8 +26,6 @@ describe('e2e_genesis_timestamp', () => { }, { syncChainTip: 'proven' }, ); - - context.watcher.setIsMarkingAsProven(false); }); afterEach(() => context.teardown()); diff --git a/yarn-project/end-to-end/src/e2e_kernelless_simulation.test.ts b/yarn-project/end-to-end/src/e2e_kernelless_simulation.test.ts index 3b140fd59960..f3657f9c6fed 100644 --- a/yarn-project/end-to-end/src/e2e_kernelless_simulation.test.ts +++ b/yarn-project/end-to-end/src/e2e_kernelless_simulation.test.ts @@ -20,7 +20,7 @@ import { MerkleTreeId } from '@aztec/stdlib/trees'; import { jest } from '@jest/globals'; import { simulateThroughAuthwitProxy } from './fixtures/authwit_proxy.js'; -import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import { deployToken, mintTokensToPrivate } from './fixtures/token_utils.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; @@ -57,7 +57,7 @@ describe('Kernelless simulation', () => { wallet, accounts: [adminAddress, liquidityProviderAddress, swapperAddress], logger, - } = await setup(3, { ...PIPELINING_SETUP_OPTS })); + } = await setup(3, { ...FAST_E2E_SETUP_OPTS })); ({ contract: token0 } = await deployToken(wallet, adminAddress, 0n, logger)); ({ contract: token1 } = await deployToken(wallet, adminAddress, 0n, logger)); diff --git a/yarn-project/end-to-end/src/e2e_keys.test.ts b/yarn-project/end-to-end/src/e2e_keys.test.ts index d7c49827417d..85e87381c0bd 100644 --- a/yarn-project/end-to-end/src/e2e_keys.test.ts +++ b/yarn-project/end-to-end/src/e2e_keys.test.ts @@ -18,7 +18,7 @@ import { import { jest } from '@jest/globals'; -import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; const TIMEOUT = 300_000; @@ -43,7 +43,7 @@ describe('Keys', () => { wallet, accounts: [defaultAccountAddress], initialFundedAccounts, - } = await setup(1, { ...PIPELINING_SETUP_OPTS })); + } = await setup(1, { ...FAST_E2E_SETUP_OPTS })); ({ contract: testContract } = await TestContract.deploy(wallet).send({ from: defaultAccountAddress })); diff --git a/yarn-project/end-to-end/src/e2e_large_public_event.test.ts b/yarn-project/end-to-end/src/e2e_large_public_event.test.ts index 4262949adbbc..baad93a6be34 100644 --- a/yarn-project/end-to-end/src/e2e_large_public_event.test.ts +++ b/yarn-project/end-to-end/src/e2e_large_public_event.test.ts @@ -8,7 +8,7 @@ import type { AztecAddress } from '@aztec/stdlib/aztec-address'; import { jest } from '@jest/globals'; -import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; const TIMEOUT = 300_000; @@ -29,7 +29,7 @@ describe('LargePublicEvent', () => { wallet, aztecNode, accounts: [accountAddress], - } = await setup(1, { ...PIPELINING_SETUP_OPTS })); + } = await setup(1, { ...FAST_E2E_SETUP_OPTS })); ({ contract } = await LargePublicEventContract.deploy(wallet).send({ from: accountAddress })); }); diff --git a/yarn-project/end-to-end/src/e2e_lending_contract.test.ts b/yarn-project/end-to-end/src/e2e_lending_contract.test.ts index 58a603970711..51a03c9a7f9c 100644 --- a/yarn-project/end-to-end/src/e2e_lending_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_lending_contract.test.ts @@ -12,7 +12,7 @@ import { TokenContract } from '@aztec/noir-contracts.js/Token'; import { afterAll, jest } from '@jest/globals'; -import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import type { EndToEndContext } from './fixtures/setup.js'; import { mintTokensToPrivate } from './fixtures/token_utils.js'; import { ensureAccountContractsPublished, setup } from './fixtures/utils.js'; @@ -81,7 +81,7 @@ describe('e2e_lending_contract', () => { }; beforeAll(async () => { - const ctx = await setup(1, { ...PIPELINING_SETUP_OPTS }); + const ctx = await setup(1, { ...FAST_E2E_SETUP_OPTS }); ({ teardown, logger, diff --git a/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts b/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts index 0dfd87664d6b..0634af271766 100644 --- a/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts +++ b/yarn-project/end-to-end/src/e2e_multiple_accounts_1_enc_key.test.ts @@ -5,7 +5,7 @@ import type { Logger } from '@aztec/aztec.js/log'; import type { Wallet } from '@aztec/aztec.js/wallet'; import { TokenContract } from '@aztec/noir-contracts.js/Token'; -import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import { deployToken, expectTokenBalance } from './fixtures/token_utils.js'; import { setup } from './fixtures/utils.js'; @@ -40,7 +40,7 @@ describe('e2e_multiple_accounts_1_enc_key', () => { ); ({ teardown, logger, wallet, accounts } = await setup(numAccounts, { - ...PIPELINING_SETUP_OPTS, + ...FAST_E2E_SETUP_OPTS, initialFundedAccounts, })); logger.info('Account contracts deployed'); diff --git a/yarn-project/end-to-end/src/e2e_nested_contract/importer.test.ts b/yarn-project/end-to-end/src/e2e_nested_contract/importer.test.ts index aab6d6fb59c4..89ed9d178812 100644 --- a/yarn-project/end-to-end/src/e2e_nested_contract/importer.test.ts +++ b/yarn-project/end-to-end/src/e2e_nested_contract/importer.test.ts @@ -1,6 +1,7 @@ import { ImportTestContract } from '@aztec/noir-test-contracts.js/ImportTest'; import { TestContract } from '@aztec/noir-test-contracts.js/Test'; +import { FAST_E2E_SETUP_OPTS } from '../fixtures/fixtures.js'; import { NestedContractTest } from './nested_contract_test.js'; describe('e2e_nested_contract manual', () => { @@ -10,7 +11,7 @@ describe('e2e_nested_contract manual', () => { let { wallet, logger, defaultAccountAddress } = t; beforeAll(async () => { - await t.setup(); + await t.setup({ ...FAST_E2E_SETUP_OPTS }); ({ wallet, logger, defaultAccountAddress } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_nested_contract/manual_private_call.test.ts b/yarn-project/end-to-end/src/e2e_nested_contract/manual_private_call.test.ts index d702434c7f10..01c0ebc940a3 100644 --- a/yarn-project/end-to-end/src/e2e_nested_contract/manual_private_call.test.ts +++ b/yarn-project/end-to-end/src/e2e_nested_contract/manual_private_call.test.ts @@ -1,3 +1,4 @@ +import { FAST_E2E_SETUP_OPTS } from '../fixtures/fixtures.js'; import { NestedContractTest } from './nested_contract_test.js'; describe('e2e_nested_contract manual', () => { @@ -5,7 +6,7 @@ describe('e2e_nested_contract manual', () => { let { parentContract, childContract, defaultAccountAddress } = t; beforeAll(async () => { - await t.setup(); + await t.setup({ ...FAST_E2E_SETUP_OPTS }); await t.applyManual(); ({ parentContract, childContract, defaultAccountAddress } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_nested_contract/manual_private_enqueue.test.ts b/yarn-project/end-to-end/src/e2e_nested_contract/manual_private_enqueue.test.ts index 0e19664a5662..c92e0c2c9d2b 100644 --- a/yarn-project/end-to-end/src/e2e_nested_contract/manual_private_enqueue.test.ts +++ b/yarn-project/end-to-end/src/e2e_nested_contract/manual_private_enqueue.test.ts @@ -3,6 +3,7 @@ import { Fr } from '@aztec/aztec.js/fields'; import { ChildContract } from '@aztec/noir-test-contracts.js/Child'; import { ParentContract } from '@aztec/noir-test-contracts.js/Parent'; +import { FAST_E2E_SETUP_OPTS } from '../fixtures/fixtures.js'; import { NestedContractTest } from './nested_contract_test.js'; describe('e2e_nested_contract manual_enqueue', () => { @@ -14,7 +15,7 @@ describe('e2e_nested_contract manual_enqueue', () => { beforeAll(async () => { // We don't deploy contracts in beforeAll because every test requires a fresh setup - await t.setup(); + await t.setup({ ...FAST_E2E_SETUP_OPTS }); ({ wallet, defaultAccountAddress, aztecNode } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_nested_contract/manual_public.test.ts b/yarn-project/end-to-end/src/e2e_nested_contract/manual_public.test.ts index a699ea8f1764..e654bc39df8a 100644 --- a/yarn-project/end-to-end/src/e2e_nested_contract/manual_public.test.ts +++ b/yarn-project/end-to-end/src/e2e_nested_contract/manual_public.test.ts @@ -4,6 +4,7 @@ import { Fr } from '@aztec/aztec.js/fields'; import { toBigIntBE } from '@aztec/foundation/bigint-buffer'; import { serializeToBuffer } from '@aztec/foundation/serialize'; +import { FAST_E2E_SETUP_OPTS } from '../fixtures/fixtures.js'; import { NestedContractTest } from './nested_contract_test.js'; describe('e2e_nested_contract manual', () => { @@ -14,7 +15,7 @@ describe('e2e_nested_contract manual', () => { aztecNode.getPublicStorageAt('latest', child.address, new Fr(1)); beforeAll(async () => { - await t.setup(); + await t.setup({ ...FAST_E2E_SETUP_OPTS }); await t.applyManual(); ({ wallet, parentContract, childContract, defaultAccountAddress, aztecNode } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_nested_contract/nested_contract_test.ts b/yarn-project/end-to-end/src/e2e_nested_contract/nested_contract_test.ts index 769db81c1ba0..d68dcc808b16 100644 --- a/yarn-project/end-to-end/src/e2e_nested_contract/nested_contract_test.ts +++ b/yarn-project/end-to-end/src/e2e_nested_contract/nested_contract_test.ts @@ -7,6 +7,7 @@ import { ParentContract } from '@aztec/noir-test-contracts.js/Parent'; import { type EndToEndContext, + type SetupOptions, deployAccounts, publicDeployAccounts, setup, @@ -50,9 +51,10 @@ export class NestedContractTest { await publicDeployAccounts(this.wallet, [this.defaultAccountAddress]); } - async setup() { + async setup(opts: Partial = {}) { this.logger.info('Setting up fresh subsystems'); this.context = await setup(0, { + ...opts, fundSponsoredFPC: true, skipAccountDeployment: true, }); diff --git a/yarn-project/end-to-end/src/e2e_nested_utility_calls.test.ts b/yarn-project/end-to-end/src/e2e_nested_utility_calls.test.ts index 613cb84f41aa..e6482f1c5903 100644 --- a/yarn-project/end-to-end/src/e2e_nested_utility_calls.test.ts +++ b/yarn-project/end-to-end/src/e2e_nested_utility_calls.test.ts @@ -5,7 +5,7 @@ import type { UtilityCallAuthorizationRequest } from '@aztec/pxe/server'; import { jest } from '@jest/globals'; -import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; const TIMEOUT = 300_000; @@ -26,7 +26,7 @@ describe('Nested utility calls', () => { teardown, wallet, accounts: [defaultAccountAddress], - } = await setup(1, { ...PIPELINING_SETUP_OPTS })); + } = await setup(1, { ...FAST_E2E_SETUP_OPTS })); ({ contract: contractA } = await NestedUtilityContract.deploy(wallet).send({ from: defaultAccountAddress })); ({ contract: contractB } = await NestedUtilityContract.deploy(wallet).send({ from: defaultAccountAddress })); }); @@ -78,7 +78,7 @@ describe('authorizeUtilityCall hook', () => { wallet, accounts: [defaultAccountAddress], } = await setup(1, { - ...PIPELINING_SETUP_OPTS, + ...FAST_E2E_SETUP_OPTS, pxeCreationOptions: { hooks: { authorizeUtilityCall: (req: UtilityCallAuthorizationRequest) => { diff --git a/yarn-project/end-to-end/src/e2e_nft.test.ts b/yarn-project/end-to-end/src/e2e_nft.test.ts index c98da00e2c9e..ff05d01bf511 100644 --- a/yarn-project/end-to-end/src/e2e_nft.test.ts +++ b/yarn-project/end-to-end/src/e2e_nft.test.ts @@ -5,7 +5,7 @@ import { NFTContract } from '@aztec/noir-contracts.js/NFT'; import { jest } from '@jest/globals'; -import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; const TIMEOUT = 300_000; @@ -31,7 +31,7 @@ describe('NFT', () => { beforeAll(async () => { let accounts: AztecAddress[]; - ({ teardown, wallet, accounts } = await setup(4, { ...PIPELINING_SETUP_OPTS })); + ({ teardown, wallet, accounts } = await setup(4, { ...FAST_E2E_SETUP_OPTS })); [adminAddress, minterAddress, user1Address, user2Address] = accounts; ({ contract: nftContract } = await NFTContract.deploy(wallet, adminAddress, 'FROG', 'FRG').send({ diff --git a/yarn-project/end-to-end/src/e2e_note_getter.test.ts b/yarn-project/end-to-end/src/e2e_note_getter.test.ts index 3a793fe86d05..d04d50d0a257 100644 --- a/yarn-project/end-to-end/src/e2e_note_getter.test.ts +++ b/yarn-project/end-to-end/src/e2e_note_getter.test.ts @@ -4,7 +4,7 @@ import type { Wallet } from '@aztec/aztec.js/wallet'; import { NoteGetterContract } from '@aztec/noir-test-contracts.js/NoteGetter'; import { TestContract } from '@aztec/noir-test-contracts.js/Test'; -import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; interface NoirBoundedVec { @@ -26,7 +26,7 @@ describe('e2e_note_getter', () => { teardown, wallet, accounts: [defaultAddress], - } = await setup(1, { ...PIPELINING_SETUP_OPTS })); + } = await setup(1, { ...FAST_E2E_SETUP_OPTS })); }); afterAll(() => teardown()); diff --git a/yarn-project/end-to-end/src/e2e_offchain_effect.test.ts b/yarn-project/end-to-end/src/e2e_offchain_effect.test.ts index cbca2c8e6638..0ad168e498f2 100644 --- a/yarn-project/end-to-end/src/e2e_offchain_effect.test.ts +++ b/yarn-project/end-to-end/src/e2e_offchain_effect.test.ts @@ -5,7 +5,7 @@ import { OffchainEffectContract, type TestEvent } from '@aztec/noir-test-contrac import { jest } from '@jest/globals'; -import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; import { proveInteraction } from './test-wallet/utils.js'; @@ -26,7 +26,7 @@ describe('e2e_offchain_effect', () => { teardown, wallet, accounts: [defaultAccountAddress], - } = await setup(1, { ...PIPELINING_SETUP_OPTS })); + } = await setup(1, { ...FAST_E2E_SETUP_OPTS })); ({ contract: contract1 } = await OffchainEffectContract.deploy(wallet).send({ from: defaultAccountAddress })); ({ contract: contract2 } = await OffchainEffectContract.deploy(wallet).send({ from: defaultAccountAddress })); }); diff --git a/yarn-project/end-to-end/src/e2e_offchain_payment.test.ts b/yarn-project/end-to-end/src/e2e_offchain_payment.test.ts index af1c89fa971c..38352fbbb218 100644 --- a/yarn-project/end-to-end/src/e2e_offchain_payment.test.ts +++ b/yarn-project/end-to-end/src/e2e_offchain_payment.test.ts @@ -10,7 +10,7 @@ import type { AztecNodeAdmin } from '@aztec/stdlib/interfaces/client'; import { jest } from '@jest/globals'; -import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import { getLogger, setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; import { proveInteraction } from './test-wallet/utils.js'; @@ -31,7 +31,7 @@ describe('e2e_offchain_payment', () => { beforeAll(async () => { ({ teardown, wallet, accounts, aztecNode, aztecNodeAdmin, cheatCodes } = await setup(2, { - ...PIPELINING_SETUP_OPTS, + ...FAST_E2E_SETUP_OPTS, anvilSlotsInAnEpoch: 32, })); }); diff --git a/yarn-project/end-to-end/src/e2e_option_params.test.ts b/yarn-project/end-to-end/src/e2e_option_params.test.ts index 58b0d17d40c0..362d6d52b016 100644 --- a/yarn-project/end-to-end/src/e2e_option_params.test.ts +++ b/yarn-project/end-to-end/src/e2e_option_params.test.ts @@ -5,7 +5,7 @@ import { OptionParamContract } from '@aztec/noir-test-contracts.js/OptionParam'; import { jest } from '@jest/globals'; -import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; const TIMEOUT = 300_000; @@ -33,7 +33,7 @@ describe('Option params', () => { teardown, wallet, accounts: [defaultAccountAddress], - } = await setup(1, { ...PIPELINING_SETUP_OPTS })); + } = await setup(1, { ...FAST_E2E_SETUP_OPTS })); contract = (await OptionParamContract.deploy(wallet).send({ from: defaultAccountAddress })).contract; }); diff --git a/yarn-project/end-to-end/src/e2e_orderbook.test.ts b/yarn-project/end-to-end/src/e2e_orderbook.test.ts index 86ec0225ffd5..65a3304d511b 100644 --- a/yarn-project/end-to-end/src/e2e_orderbook.test.ts +++ b/yarn-project/end-to-end/src/e2e_orderbook.test.ts @@ -9,7 +9,7 @@ import type { TokenContract } from '@aztec/noir-contracts.js/Token'; import { jest } from '@jest/globals'; -import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import { deployToken, mintTokensToPrivate } from './fixtures/token_utils.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; @@ -48,7 +48,7 @@ describe('Orderbook', () => { accounts: [adminAddress, makerAddress, takerAddress], aztecNode, logger, - } = await setup(3, { ...PIPELINING_SETUP_OPTS })); + } = await setup(3, { ...FAST_E2E_SETUP_OPTS })); ({ contract: token0 } = await deployToken(wallet, adminAddress, 0n, logger)); ({ contract: token1 } = await deployToken(wallet, adminAddress, 0n, logger)); diff --git a/yarn-project/end-to-end/src/e2e_ordering.test.ts b/yarn-project/end-to-end/src/e2e_ordering.test.ts index a460beefff7e..8a545ae780d9 100644 --- a/yarn-project/end-to-end/src/e2e_ordering.test.ts +++ b/yarn-project/end-to-end/src/e2e_ordering.test.ts @@ -11,7 +11,7 @@ import { computeCalldataHash } from '@aztec/stdlib/hash'; import { jest } from '@jest/globals'; -import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; import { proveInteraction } from './test-wallet/utils.js'; @@ -45,7 +45,7 @@ describe('e2e_ordering', () => { wallet, aztecNode, accounts: [defaultAccountAddress], - } = await setup(1, { ...PIPELINING_SETUP_OPTS })); + } = await setup(1, { ...FAST_E2E_SETUP_OPTS })); }, TIMEOUT); afterEach(() => teardown()); diff --git a/yarn-project/end-to-end/src/e2e_p2p/add_rollup.test.ts b/yarn-project/end-to-end/src/e2e_p2p/add_rollup.test.ts index 5c4c468fbcdf..2554134239c3 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/add_rollup.test.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/add_rollup.test.ts @@ -98,8 +98,6 @@ describe('e2e_p2p_add_rollup', () => { await t.removeInitialNode(); l1TxUtils = createL1TxUtils(t.ctx.deployL1ContractsValues.l1Client); - - t.ctx.watcher.setIsMarkingAsProven(false); }); afterAll(async () => { diff --git a/yarn-project/end-to-end/src/e2e_p2p/gossip_network_no_cheat.test.ts b/yarn-project/end-to-end/src/e2e_p2p/gossip_network_no_cheat.test.ts index 9fa76164243d..b98dcbb869e2 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/gossip_network_no_cheat.test.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/gossip_network_no_cheat.test.ts @@ -160,9 +160,7 @@ describe('e2e_p2p_network', () => { } // Wait for the validators to be added to the rollup - const timestamp = await t.ctx.cheatCodes.rollup.advanceToEpoch( - EpochNumber(t.ctx.aztecNodeConfig.lagInEpochsForValidatorSet + 1), - ); + await t.ctx.cheatCodes.rollup.advanceToEpoch(EpochNumber(t.ctx.aztecNodeConfig.lagInEpochsForValidatorSet + 1)); // Changes have now taken effect const attesters = await rollupWrapper.getAttesters(); @@ -178,10 +176,6 @@ describe('e2e_p2p_network', () => { }), }); - // Set the system time in the node, only after we have warped the time and waited for a block - // Time is only set in the NEXT block - t.ctx.dateProvider.setTime(Number(timestamp) * 1000); - // create our network of nodes and submit txs into each of them // the number of txs per node and the number of txs per rollup // should be set so that the only way for rollups to be built diff --git a/yarn-project/end-to-end/src/e2e_p2p/reex.test.ts b/yarn-project/end-to-end/src/e2e_p2p/reex.test.ts index aa1369606450..61ab3c640af7 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/reex.test.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/reex.test.ts @@ -235,8 +235,7 @@ describe('e2e_p2p_reex', () => { } // Start a fresh slot and resume proposals - const [ts] = await t.ctx.cheatCodes.rollup.advanceToNextSlot(); - t.ctx.dateProvider.setTime(Number(ts) * 1000); + await t.ctx.cheatCodes.rollup.advanceToNextSlot(); await resumeProposals(); diff --git a/yarn-project/end-to-end/src/e2e_p2p/reqresp/utils.ts b/yarn-project/end-to-end/src/e2e_p2p/reqresp/utils.ts index 71f440695add..3233b3693575 100644 --- a/yarn-project/end-to-end/src/e2e_p2p/reqresp/utils.ts +++ b/yarn-project/end-to-end/src/e2e_p2p/reqresp/utils.ts @@ -122,7 +122,6 @@ export async function runReqrespTxTest(params: { t.logger.info('Starting fresh slot'); const [timestamp] = await t.ctx.cheatCodes.rollup.advanceToNextSlot(); - t.ctx.dateProvider.setTime(Number(timestamp) * 1000); const startSlotTimestamp = BigInt(timestamp); const { proposerIndexes, nodesToTurnOffTxGossip } = await getProposerIndexes(t, startSlotTimestamp); diff --git a/yarn-project/end-to-end/src/e2e_partial_notes.test.ts b/yarn-project/end-to-end/src/e2e_partial_notes.test.ts index c1f92e312c70..e0ac01e3e33e 100644 --- a/yarn-project/end-to-end/src/e2e_partial_notes.test.ts +++ b/yarn-project/end-to-end/src/e2e_partial_notes.test.ts @@ -5,7 +5,7 @@ import type { TokenContract } from '@aztec/noir-contracts.js/Token'; import { jest } from '@jest/globals'; -import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import { deployToken, mintTokensToPrivate } from './fixtures/token_utils.js'; import { setup } from './fixtures/utils.js'; @@ -33,7 +33,7 @@ describe('partial notes', () => { wallet, accounts: [adminAddress, liquidityProviderAddress], logger, - } = await setup(2, { ...PIPELINING_SETUP_OPTS })); + } = await setup(2, { ...FAST_E2E_SETUP_OPTS })); const { contract } = await deployToken(wallet, adminAddress, 0n, logger); token0 = contract; diff --git a/yarn-project/end-to-end/src/e2e_pending_note_hashes_contract.test.ts b/yarn-project/end-to-end/src/e2e_pending_note_hashes_contract.test.ts index 2d063995c164..adc2ca4a177a 100644 --- a/yarn-project/end-to-end/src/e2e_pending_note_hashes_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_pending_note_hashes_contract.test.ts @@ -10,7 +10,7 @@ import { } from '@aztec/constants'; import { PendingNoteHashesContract } from '@aztec/noir-test-contracts.js/PendingNoteHashes'; -import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; @@ -29,7 +29,7 @@ describe('e2e_pending_note_hashes_contract', () => { wallet, logger, accounts: [owner], - } = await setup(1, { ...PIPELINING_SETUP_OPTS })); + } = await setup(1, { ...FAST_E2E_SETUP_OPTS })); }); afterAll(() => teardown()); diff --git a/yarn-project/end-to-end/src/e2e_phase_check.test.ts b/yarn-project/end-to-end/src/e2e_phase_check.test.ts index 7d447632b424..c975952854e9 100644 --- a/yarn-project/end-to-end/src/e2e_phase_check.test.ts +++ b/yarn-project/end-to-end/src/e2e_phase_check.test.ts @@ -9,7 +9,7 @@ import { getContractInstanceFromInstantiationParams } from '@aztec/stdlib/contra import { PublicDataTreeLeaf } from '@aztec/stdlib/trees'; import { defaultInitialAccountFeeJuice } from '@aztec/world-state/testing'; -import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; @@ -34,7 +34,7 @@ describe('Phase check', () => { teardown, wallet, accounts: [defaultAccountAddress], - } = await setup(1, { ...PIPELINING_SETUP_OPTS, genesisPublicData: [genesisBalanceEntry] })); + } = await setup(1, { ...FAST_E2E_SETUP_OPTS, genesisPublicData: [genesisBalanceEntry] })); ({ contract } = await TestContract.deploy(wallet).send({ from: defaultAccountAddress })); sponsoredFPC = await SponsoredFPCNoEndSetupContract.deploy(wallet, { diff --git a/yarn-project/end-to-end/src/e2e_private_voting_contract.test.ts b/yarn-project/end-to-end/src/e2e_private_voting_contract.test.ts index 077a5e55400a..600276720959 100644 --- a/yarn-project/end-to-end/src/e2e_private_voting_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_private_voting_contract.test.ts @@ -5,7 +5,7 @@ import type { Wallet } from '@aztec/aztec.js/wallet'; import { PrivateVotingContract } from '@aztec/noir-contracts.js/PrivateVoting'; import { TX_ERROR_EXISTING_NULLIFIER } from '@aztec/stdlib/tx'; -import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; describe('e2e_voting_contract', () => { @@ -24,7 +24,7 @@ describe('e2e_voting_contract', () => { wallet, logger, accounts: [owner], - } = await setup(1, { ...PIPELINING_SETUP_OPTS })); + } = await setup(1, { ...FAST_E2E_SETUP_OPTS })); ({ contract: votingContract } = await PrivateVotingContract.deploy(wallet, owner).send({ from: owner })); diff --git a/yarn-project/end-to-end/src/e2e_pxe.test.ts b/yarn-project/end-to-end/src/e2e_pxe.test.ts index 8240208ca70c..f4851b6a6635 100644 --- a/yarn-project/end-to-end/src/e2e_pxe.test.ts +++ b/yarn-project/end-to-end/src/e2e_pxe.test.ts @@ -3,7 +3,7 @@ import { Fr } from '@aztec/aztec.js/fields'; import { TestContract } from '@aztec/noir-test-contracts.js/Test'; import { TX_ERROR_EXISTING_NULLIFIER } from '@aztec/stdlib/tx'; -import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; @@ -21,7 +21,7 @@ describe('e2e_pxe', () => { teardown, wallet, accounts: [defaultAccountAddress], - } = await setup(1, { ...PIPELINING_SETUP_OPTS })); + } = await setup(1, { ...FAST_E2E_SETUP_OPTS })); ({ contract } = await TestContract.deploy(wallet).send({ from: defaultAccountAddress })); }); diff --git a/yarn-project/end-to-end/src/e2e_scope_isolation.test.ts b/yarn-project/end-to-end/src/e2e_scope_isolation.test.ts index cebea5cdd26e..a11ec67aabde 100644 --- a/yarn-project/end-to-end/src/e2e_scope_isolation.test.ts +++ b/yarn-project/end-to-end/src/e2e_scope_isolation.test.ts @@ -2,7 +2,7 @@ import type { AztecAddress } from '@aztec/aztec.js/addresses'; import type { Wallet } from '@aztec/aztec.js/wallet'; import { ScopeTestContract } from '@aztec/noir-test-contracts.js/ScopeTest'; -import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; describe('e2e scope isolation', () => { @@ -19,7 +19,7 @@ describe('e2e scope isolation', () => { const BOB_NOTE_VALUE = 100n; beforeAll(async () => { - ({ teardown, wallet, accounts } = await setup(3, { ...PIPELINING_SETUP_OPTS })); + ({ teardown, wallet, accounts } = await setup(3, { ...FAST_E2E_SETUP_OPTS })); [alice, bob, charlie] = accounts; ({ contract } = await ScopeTestContract.deploy(wallet).send({ from: alice })); diff --git a/yarn-project/end-to-end/src/e2e_sequencer/escape_hatch_vote_only.test.ts b/yarn-project/end-to-end/src/e2e_sequencer/escape_hatch_vote_only.test.ts index 216b0abef73e..307308a3fef1 100644 --- a/yarn-project/end-to-end/src/e2e_sequencer/escape_hatch_vote_only.test.ts +++ b/yarn-project/end-to-end/src/e2e_sequencer/escape_hatch_vote_only.test.ts @@ -76,7 +76,6 @@ describe('e2e_escape_hatch_vote_only', () => { // Keep pruning far away for this test. aztecProofSubmissionEpochs: 15, // needed so ACTIVE_DURATION=2 is a valid EscapeHatch config enforceTimeTable: true, - automineL1Setup: true, // Pipelining opts — exercise the §6 B5 fix (tryVoteWhenEscapeHatchOpen signing/submitting for targetSlot). // inboxLag: 2 so the sequencer sources L1->L2 messages from a sealed checkpoint when building for slot+1. enableProposerPipelining: true, diff --git a/yarn-project/end-to-end/src/e2e_sequencer/gov_proposal.parallel.test.ts b/yarn-project/end-to-end/src/e2e_sequencer/gov_proposal.parallel.test.ts index ec03b1615960..9724c9a70604 100644 --- a/yarn-project/end-to-end/src/e2e_sequencer/gov_proposal.parallel.test.ts +++ b/yarn-project/end-to-end/src/e2e_sequencer/gov_proposal.parallel.test.ts @@ -79,7 +79,6 @@ describe('e2e_gov_proposal', () => { aztecProofSubmissionEpochs: 128, // no pruning minTxsPerBlock: TXS_PER_BLOCK, enforceTimeTable: true, - automineL1Setup: true, // speed up setup // Force the L1 sync to fetch blobs rather than promote the locally-proposed checkpoint. // The "should vote even when unable to build blocks" test relies on the blob client being the // only source of truth for block sync: disabling the blob client should make the tx un-syncable. diff --git a/yarn-project/end-to-end/src/e2e_state_vars.test.ts b/yarn-project/end-to-end/src/e2e_state_vars.test.ts index 37b59691a5b7..75697d37ddee 100644 --- a/yarn-project/end-to-end/src/e2e_state_vars.test.ts +++ b/yarn-project/end-to-end/src/e2e_state_vars.test.ts @@ -7,7 +7,7 @@ import { StateVarsContract } from '@aztec/noir-test-contracts.js/StateVars'; import { jest } from '@jest/globals'; -import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; import type { TestWallet } from './test-wallet/test_wallet.js'; import { proveInteraction } from './test-wallet/utils.js'; @@ -33,7 +33,7 @@ describe('e2e_state_vars', () => { aztecNode, wallet, accounts: [defaultAccountAddress], - } = await setup(1, { ...PIPELINING_SETUP_OPTS })); + } = await setup(1, { ...FAST_E2E_SETUP_OPTS })); ({ contract } = await StateVarsContract.deploy(wallet).send({ from: defaultAccountAddress })); }); diff --git a/yarn-project/end-to-end/src/e2e_static_calls.test.ts b/yarn-project/end-to-end/src/e2e_static_calls.test.ts index 422bb9a2b09d..65bc1cdbdc61 100644 --- a/yarn-project/end-to-end/src/e2e_static_calls.test.ts +++ b/yarn-project/end-to-end/src/e2e_static_calls.test.ts @@ -4,7 +4,7 @@ import { StaticChildContract } from '@aztec/noir-test-contracts.js/StaticChild'; import { StaticParentContract } from '@aztec/noir-test-contracts.js/StaticParent'; import { - PIPELINING_SETUP_OPTS, + FAST_E2E_SETUP_OPTS, STATIC_CALL_STATE_MODIFICATION_ERROR, STATIC_CONTEXT_ASSERTION_ERROR, } from './fixtures/fixtures.js'; @@ -23,7 +23,7 @@ describe('e2e_static_calls', () => { teardown, wallet, accounts: [owner], - } = await setup(1, { ...PIPELINING_SETUP_OPTS })); + } = await setup(1, { ...FAST_E2E_SETUP_OPTS })); sender = owner; ({ contract: parentContract } = await StaticParentContract.deploy(wallet).send({ from: owner })); ({ contract: childContract } = await StaticChildContract.deploy(wallet).send({ from: owner })); diff --git a/yarn-project/end-to-end/src/e2e_token_contract/access_control.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/access_control.test.ts index 50ac4a7f36be..0bcfb1e451df 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/access_control.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/access_control.test.ts @@ -1,3 +1,4 @@ +import { FAST_E2E_SETUP_OPTS } from '../fixtures/fixtures.js'; import { TokenContractTest } from './token_contract_test.js'; describe('e2e_token_contract access control', () => { @@ -5,7 +6,7 @@ describe('e2e_token_contract access control', () => { beforeAll(async () => { t.applyBaseSnapshots(); - await t.setup(); + await t.setup({ ...FAST_E2E_SETUP_OPTS }); }); afterAll(async () => { diff --git a/yarn-project/end-to-end/src/e2e_token_contract/burn.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/burn.test.ts index b9760a983627..8b7fbd0fc1fc 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/burn.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/burn.test.ts @@ -2,7 +2,7 @@ import { computeAuthWitMessageHash } from '@aztec/aztec.js/authorization'; import { Fr } from '@aztec/aztec.js/fields'; import { sendThroughAuthwitProxy, simulateThroughAuthwitProxy } from '../fixtures/authwit_proxy.js'; -import { DUPLICATE_NULLIFIER_ERROR, U128_UNDERFLOW_ERROR } from '../fixtures/index.js'; +import { DUPLICATE_NULLIFIER_ERROR, FAST_E2E_SETUP_OPTS, U128_UNDERFLOW_ERROR } from '../fixtures/index.js'; import { TokenContractTest } from './token_contract_test.js'; describe('e2e_token_contract burn', () => { @@ -12,7 +12,7 @@ describe('e2e_token_contract burn', () => { beforeAll(async () => { t.applyBaseSnapshots(); t.applyMintSnapshot(); - await t.setup(); + await t.setup({ ...FAST_E2E_SETUP_OPTS }); // Have to destructure again to ensure we have latest refs. ({ asset, wallet, adminAddress, tokenSim, adminAddress, account1Address } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_token_contract/minting.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/minting.test.ts index 46908a688eab..2d93c6c8e129 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/minting.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/minting.test.ts @@ -1,4 +1,4 @@ -import { U128_OVERFLOW_ERROR } from '../fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS, U128_OVERFLOW_ERROR } from '../fixtures/fixtures.js'; import { TokenContractTest } from './token_contract_test.js'; describe('e2e_token_contract minting', () => { @@ -7,7 +7,7 @@ describe('e2e_token_contract minting', () => { beforeAll(async () => { t.applyBaseSnapshots(); - await t.setup(); + await t.setup({ ...FAST_E2E_SETUP_OPTS }); ({ asset, tokenSim, adminAddress, account1Address } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_token_contract/private_transfer_recursion.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/private_transfer_recursion.test.ts index ffa5688df3b5..64c890a6c384 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/private_transfer_recursion.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/private_transfer_recursion.test.ts @@ -1,6 +1,7 @@ import { BlockNumber } from '@aztec/foundation/branded-types'; import { TokenContract, type Transfer } from '@aztec/noir-contracts.js/Token'; +import { FAST_E2E_SETUP_OPTS } from '../fixtures/fixtures.js'; import { mintNotes } from '../fixtures/token_utils.js'; import { TokenContractTest } from './token_contract_test.js'; @@ -10,7 +11,7 @@ describe('e2e_token_contract private transfer recursion', () => { beforeAll(async () => { t.applyBaseSnapshots(); - await t.setup(); + await t.setup({ ...FAST_E2E_SETUP_OPTS }); ({ asset, wallet, adminAddress, account1Address, node } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_token_contract/reading_constants.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/reading_constants.test.ts index 185ac4231e8e..e6d08748f921 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/reading_constants.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/reading_constants.test.ts @@ -1,5 +1,6 @@ import { readFieldCompressedString } from '@aztec/aztec.js/utils'; +import { FAST_E2E_SETUP_OPTS } from '../fixtures/fixtures.js'; import { TokenContractTest } from './token_contract_test.js'; describe('e2e_token_contract reading constants', () => { @@ -8,7 +9,7 @@ describe('e2e_token_contract reading constants', () => { beforeAll(async () => { t.applyBaseSnapshots(); - await t.setup(); + await t.setup({ ...FAST_E2E_SETUP_OPTS }); }); afterAll(async () => { diff --git a/yarn-project/end-to-end/src/e2e_token_contract/token_contract_test.ts b/yarn-project/end-to-end/src/e2e_token_contract/token_contract_test.ts index bbc7f024fd19..74b8e590bf54 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/token_contract_test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/token_contract_test.ts @@ -7,7 +7,14 @@ import { InvalidAccountContract } from '@aztec/noir-test-contracts.js/InvalidAcc import { jest } from '@jest/globals'; -import { type EndToEndContext, deployAccounts, publicDeployAccounts, setup, teardown } from '../fixtures/setup.js'; +import { + type EndToEndContext, + type SetupOptions, + deployAccounts, + publicDeployAccounts, + setup, + teardown, +} from '../fixtures/setup.js'; import { mintTokensToPrivate } from '../fixtures/token_utils.js'; import { TokenSimulator } from '../simulators/token_simulator.js'; import type { TestWallet } from '../test-wallet/test_wallet.js'; @@ -115,8 +122,9 @@ export class TokenContractTest { ); } - async setup() { + async setup(opts: Partial = {}) { this.context = await setup(0, { + ...opts, metricsPort: this.metricsPort, fundSponsoredFPC: true, skipAccountDeployment: true, diff --git a/yarn-project/end-to-end/src/e2e_token_contract/transfer.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/transfer.test.ts index 564707a74c77..f27a48b95c05 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/transfer.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/transfer.test.ts @@ -2,6 +2,7 @@ import { AztecAddress, CompleteAddress } from '@aztec/aztec.js/addresses'; import { BlockNumber } from '@aztec/foundation/branded-types'; import { TokenContract, type Transfer } from '@aztec/noir-contracts.js/Token'; +import { FAST_E2E_SETUP_OPTS } from '../fixtures/fixtures.js'; import { TokenContractTest } from './token_contract_test.js'; describe('e2e_token_contract transfer private', () => { @@ -11,7 +12,7 @@ describe('e2e_token_contract transfer private', () => { beforeAll(async () => { t.applyBaseSnapshots(); t.applyMintSnapshot(); - await t.setup(); + await t.setup({ ...FAST_E2E_SETUP_OPTS }); ({ asset, adminAddress, wallet, account1Address, tokenSim } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_private.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_private.test.ts index 385c912cec06..5cbd80c4bafe 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_private.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_private.test.ts @@ -2,7 +2,7 @@ import { computeAuthWitMessageHash, computeInnerAuthWitHashFromAction } from '@a import { Fr } from '@aztec/aztec.js/fields'; import { sendThroughAuthwitProxy, simulateThroughAuthwitProxy } from '../fixtures/authwit_proxy.js'; -import { DUPLICATE_NULLIFIER_ERROR } from '../fixtures/fixtures.js'; +import { DUPLICATE_NULLIFIER_ERROR, FAST_E2E_SETUP_OPTS } from '../fixtures/fixtures.js'; import { TokenContractTest } from './token_contract_test.js'; describe('e2e_token_contract transfer private', () => { @@ -12,7 +12,7 @@ describe('e2e_token_contract transfer private', () => { beforeAll(async () => { t.applyBaseSnapshots(); t.applyMintSnapshot(); - await t.setup(); + await t.setup({ ...FAST_E2E_SETUP_OPTS }); ({ asset, tokenSim, wallet, adminAddress, account1Address, badAccount } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_public.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_public.test.ts index f50c89d80b5a..d4fb86caf953 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_public.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/transfer_in_public.test.ts @@ -1,6 +1,6 @@ import { Fr } from '@aztec/aztec.js/fields'; -import { U128_UNDERFLOW_ERROR } from '../fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS, U128_UNDERFLOW_ERROR } from '../fixtures/fixtures.js'; import { type AlertConfig, GrafanaClient } from '../quality_of_service/grafana_client.js'; import { TokenContractTest } from './token_contract_test.js'; @@ -25,7 +25,7 @@ describe('e2e_token_contract transfer public', () => { beforeAll(async () => { t.applyBaseSnapshots(); t.applyMintSnapshot(); - await t.setup(); + await t.setup({ ...FAST_E2E_SETUP_OPTS }); // Have to destructure again to ensure we have latest refs. ({ asset, tokenSim, wallet, adminAddress, account1Address, badAccount } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_token_contract/transfer_to_private.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/transfer_to_private.test.ts index 2688fea57172..fb5f8850962f 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/transfer_to_private.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/transfer_to_private.test.ts @@ -1,4 +1,4 @@ -import { U128_UNDERFLOW_ERROR } from '../fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS, U128_UNDERFLOW_ERROR } from '../fixtures/fixtures.js'; import { TokenContractTest } from './token_contract_test.js'; describe('e2e_token_contract transfer_to_private', () => { @@ -8,7 +8,7 @@ describe('e2e_token_contract transfer_to_private', () => { beforeAll(async () => { t.applyBaseSnapshots(); t.applyMintSnapshot(); - await t.setup(); + await t.setup({ ...FAST_E2E_SETUP_OPTS }); // Have to destructure again to ensure we have latest refs. ({ asset, adminAddress, account1Address, tokenSim } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_token_contract/transfer_to_public.test.ts b/yarn-project/end-to-end/src/e2e_token_contract/transfer_to_public.test.ts index 1ff6f31ef53b..6dec5b858834 100644 --- a/yarn-project/end-to-end/src/e2e_token_contract/transfer_to_public.test.ts +++ b/yarn-project/end-to-end/src/e2e_token_contract/transfer_to_public.test.ts @@ -2,7 +2,7 @@ import { computeAuthWitMessageHash } from '@aztec/aztec.js/authorization'; import { Fr } from '@aztec/aztec.js/fields'; import { sendThroughAuthwitProxy, simulateThroughAuthwitProxy } from '../fixtures/authwit_proxy.js'; -import { DUPLICATE_NULLIFIER_ERROR } from '../fixtures/fixtures.js'; +import { DUPLICATE_NULLIFIER_ERROR, FAST_E2E_SETUP_OPTS } from '../fixtures/fixtures.js'; import { TokenContractTest } from './token_contract_test.js'; describe('e2e_token_contract transfer_to_public', () => { @@ -12,7 +12,7 @@ describe('e2e_token_contract transfer_to_public', () => { beforeAll(async () => { t.applyBaseSnapshots(); t.applyMintSnapshot(); - await t.setup(); + await t.setup({ ...FAST_E2E_SETUP_OPTS }); // Have to destructure again to ensure we have latest refs. ({ asset, wallet, adminAddress, account1Address, tokenSim } = t); }); diff --git a/yarn-project/end-to-end/src/e2e_tx_effect_oracle.test.ts b/yarn-project/end-to-end/src/e2e_tx_effect_oracle.test.ts index 584501383c88..c6133dcec73e 100644 --- a/yarn-project/end-to-end/src/e2e_tx_effect_oracle.test.ts +++ b/yarn-project/end-to-end/src/e2e_tx_effect_oracle.test.ts @@ -19,7 +19,7 @@ import type { TxEffect, TxHash } from '@aztec/stdlib/tx'; import { jest } from '@jest/globals'; -import { PIPELINING_SETUP_OPTS } from './fixtures/fixtures.js'; +import { FAST_E2E_SETUP_OPTS } from './fixtures/fixtures.js'; import { setup } from './fixtures/utils.js'; const TIMEOUT = 120_000; @@ -49,7 +49,7 @@ describe('e2e tx effect oracle', () => { wallet, aztecNode, accounts: [defaultAccountAddress], - } = await setup(1, { ...PIPELINING_SETUP_OPTS })); + } = await setup(1, { ...FAST_E2E_SETUP_OPTS })); const { contract: deployed, receipt } = await TxEffectOracleTestContract.deploy(wallet).send({ from: defaultAccountAddress, }); diff --git a/yarn-project/end-to-end/src/fixtures/fixtures.ts b/yarn-project/end-to-end/src/fixtures/fixtures.ts index ebae4156c0ea..3236868b27de 100644 --- a/yarn-project/end-to-end/src/fixtures/fixtures.ts +++ b/yarn-project/end-to-end/src/fixtures/fixtures.ts @@ -45,6 +45,37 @@ export const PIPELINING_SETUP_OPTS = { walletMinFeePadding: PIPELINED_FEE_PADDING, } as const; +/** + * Fast e2e setup preset that opts a test into proposer pipelining with the smallest possible + * timing constants. Use this for single-sequencer, non-block-building tests. + * + * await setup(N, { ...FAST_E2E_SETUP_OPTS }); + * + * Extends PIPELINING_SETUP_OPTS with: + * - `l1PublishingTime: 4`: L1 tx is expected to land inside one Ethereum slot. + * - `testOnlyAutoProveAfterPublish: true`: opts in to the test fixture's CheckpointAutoProver + * (wired in step 4 of the plan; safe to set in step 1 because it just sets a config value), + * removing the need for AnvilTestWatcher's markAsProven loop. + * + * Auto-tuning applied by `normalizeCheckpointTimingConfig` (stdlib/src/timetable/index.ts): + * because ethereumSlotDuration < 8, p2pPropagationTime = 0, checkpointAssembleTime = 0.5, + * checkpointInitializationTime = 0.5, minExecutionTime = 1. `blockDurationMs` remains unset, + * so the sequencer runs in single-block-per-slot mode: + * + * minimumBuildSlotWork = init + 2*minExec = 0.5 + 2 = 2.5s + * initializeDeadline = aztecSlotDuration - minimumBuildSlotWork = 9.5s + * checkpointFinalizationTime = assemble + 2*p2p + publish = 0.5 + 0 + 4 = 4.5s + * maxAllowed (single block) = aztecSlotDuration - checkpointFinalizationTime = 7.5s + * available at slot start = (7.5 - 0) / 2 = 3.75s (split: exec vs re-exec) + * + * The pipelined publish deadline is `2 * aztecSlotDuration - l1PublishingTime` = 20s into build slot. + */ +export const FAST_E2E_SETUP_OPTS = { + ...PIPELINING_SETUP_OPTS, + l1PublishingTime: 4, + testOnlyAutoProveAfterPublish: true, +} as const; + /** Returns worst-case predicted min fees with padding applied, mirroring the BaseWallet pattern. */ export async function getPaddedMaxFeesPerGas(node: AztecNode, padding = DEFAULT_MIN_FEE_PADDING): Promise { const predicted = await node.getPredictedMinFees(); diff --git a/yarn-project/end-to-end/src/fixtures/setup.ts b/yarn-project/end-to-end/src/fixtures/setup.ts index 1367d9498f07..11d364869689 100644 --- a/yarn-project/end-to-end/src/fixtures/setup.ts +++ b/yarn-project/end-to-end/src/fixtures/setup.ts @@ -17,7 +17,7 @@ import { Fr } from '@aztec/aztec.js/fields'; import { type Logger, createLogger } from '@aztec/aztec.js/log'; import type { AztecNode } from '@aztec/aztec.js/node'; import type { Wallet } from '@aztec/aztec.js/wallet'; -import { AnvilTestWatcher, type AnvilTestWatcherOpts, CheatCodes } from '@aztec/aztec/testing'; +import { AnvilTestWatcher, type AnvilTestWatcherOpts, CheatCodes, CheckpointAutoProver } from '@aztec/aztec/testing'; import { SPONSORED_FPC_SALT } from '@aztec/constants'; import { isAnvilTestChain } from '@aztec/ethereum/chain'; import { createExtendedL1Client } from '@aztec/ethereum/client'; @@ -187,8 +187,6 @@ export type SetupOptions = { /** Whether to disable the anvil test watcher (can still be manually started) */ disableAnvilTestWatcher?: boolean; anvilTestWatcherOpts?: AnvilTestWatcherOpts; - /** Whether to enable anvil automine during deployment of L1 contracts (consider defaulting this to true). */ - automineL1Setup?: boolean; /** How many accounts to seed and unlock in anvil. */ anvilAccounts?: number; /** Port to start anvil (defaults to 8545) */ @@ -215,6 +213,13 @@ export type SetupOptions = { skipInitialSequencer?: boolean; /** Options forwarded to PXE creation (e.g. execution hooks). */ pxeCreationOptions?: PXECreationOptions; + /** + * When true, the fixture constructs a CheckpointAutoProver that calls + * `RollupCheatCodes.markAsProven` after each published checkpoint, replacing + * AnvilTestWatcher's markAsProven loop. Wired in step 4 of the plan; safe to + * set in step 1 because it just stores a config value until the helper is hooked up. + */ + testOnlyAutoProveAfterPublish?: boolean; } & Partial; /** Context for an end-to-end test as returned by the `setup` function */ @@ -251,6 +256,8 @@ export type EndToEndContext = { ethCheatCodes: EthCheatCodes; /** The anvil test watcher. */ watcher: AnvilTestWatcher; + /** Auto-prover that calls markAsProven after each checkpoint when testOnlyAutoProveAfterPublish is true. */ + checkpointAutoProver: CheckpointAutoProver | undefined; /** Allows tweaking current system time, used by the epoch cache only. */ dateProvider: TestDateProvider; /** Telemetry client */ @@ -422,9 +429,8 @@ export async function setup( genesisTimestamp, ); - const wasAutomining = await ethCheatCodes.isAutoMining(); - const enableAutomine = opts.automineL1Setup && !wasAutomining && isAnvilTestChain(chain.id); - if (enableAutomine) { + const isAnvilChain = isAnvilTestChain(chain.id); + if (isAnvilChain) { await ethCheatCodes.setAutomine(true); } @@ -457,7 +463,7 @@ export async function setup( Object.assign(config, deployL1ContractsValues.l1ContractAddresses); config.rollupVersion = deployL1ContractsValues.rollupVersion; - if (enableAutomine) { + if (isAnvilChain) { await ethCheatCodes.setAutomine(false); await ethCheatCodes.setIntervalMining(config.ethereumSlotDuration); } @@ -480,7 +486,10 @@ export async function setup( dateProvider, opts.anvilTestWatcherOpts, ); - if (!opts.disableAnvilTestWatcher) { + // Watcher is only needed on the sandbox path. Anvil e2e tests use interval mining + cheat-code + // atomic dateProvider sync + CheckpointAutoProver instead. + const disableWatcher = opts.disableAnvilTestWatcher ?? isAnvilChain; + if (!disableWatcher) { await watcher.start(); } @@ -604,6 +613,17 @@ export async function setup( const cheatCodes = await CheatCodes.create(config.l1RpcUrls, aztecNodeService, dateProvider); + let checkpointAutoProver: CheckpointAutoProver | undefined = undefined; + if (opts.testOnlyAutoProveAfterPublish && isAnvilChain && !opts.startProverNode && sequencerClient) { + checkpointAutoProver = new CheckpointAutoProver({ + sequencer: sequencerClient.getSequencer(), + l2BlockSource: aztecNodeService.getBlockSource(), + rollupCheatCodes: cheatCodes.rollup, + log: logger, + }); + checkpointAutoProver.start(); + } + if ( (opts.aztecTargetCommitteeSize && opts.aztecTargetCommitteeSize > 0) || (opts.initialValidators && opts.initialValidators.length > 0) @@ -650,6 +670,7 @@ export async function setup( const teardown = async () => { try { + await checkpointAutoProver?.stop(); await tryStop(wallet, logger); await tryStop(aztecNodeService, logger); await tryStop(proverNode, logger); @@ -701,6 +722,7 @@ export async function setup( wallet, accounts, watcher, + checkpointAutoProver, acvmConfig, bbConfig, directoryToCleanup, diff --git a/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts b/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts index 1950d9925e4a..e9e2e7a9a142 100644 --- a/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts +++ b/yarn-project/end-to-end/src/shared/uniswap_l1_l2.ts @@ -84,8 +84,6 @@ export const uniswapL1L2TestSuite = ( l1Client = deployL1ContractsValues.l1Client; - t.watcher.setIsMarkingAsProven(false); - if (Number(await l1Client.getBlockNumber()) < expectedForkBlockNumber) { throw new Error('This test must be run on a fork of mainnet with the expected fork block'); } diff --git a/yarn-project/ethereum/src/test/eth_cheat_codes.test.ts b/yarn-project/ethereum/src/test/eth_cheat_codes.test.ts index 9a489e18375a..094449bf1076 100644 --- a/yarn-project/ethereum/src/test/eth_cheat_codes.test.ts +++ b/yarn-project/ethereum/src/test/eth_cheat_codes.test.ts @@ -2,7 +2,7 @@ import { Blob } from '@aztec/blob-lib'; import { times, timesAsync } from '@aztec/foundation/collection'; import { type Logger, createLogger } from '@aztec/foundation/log'; import { sleep } from '@aztec/foundation/sleep'; -import { DateProvider } from '@aztec/foundation/timer'; +import { DateProvider, TestDateProvider } from '@aztec/foundation/timer'; import { TestERC20Abi, TestERC20Bytecode } from '@aztec/l1-artifacts'; import { type Hex, encodeFunctionData, getContract } from 'viem'; @@ -212,6 +212,51 @@ describe('EthCheatCodes', () => { }); }); + describe('dateProvider sync', () => { + let testDateProvider: TestDateProvider; + let cheatCodesWithTestDateProvider: EthCheatCodes; + + beforeEach(() => { + testDateProvider = new TestDateProvider(); + cheatCodesWithTestDateProvider = new EthCheatCodes([rpcUrl], testDateProvider); + }); + + it('mine() syncs dateProvider to latest block timestamp', async () => { + const before = await cheatCodesWithTestDateProvider.lastBlockTimestamp(); + await cheatCodesWithTestDateProvider.mine(3); + const after = await cheatCodesWithTestDateProvider.lastBlockTimestamp(); + expect(after).toBeGreaterThanOrEqual(before); + expect(testDateProvider.now()).toBeGreaterThanOrEqual(after * 1000); + expect(testDateProvider.now()).toBeLessThan((after + 5) * 1000); + }); + + it('evmMine() syncs dateProvider to latest block timestamp', async () => { + const before = await cheatCodesWithTestDateProvider.lastBlockTimestamp(); + await cheatCodesWithTestDateProvider.evmMine(); + const after = await cheatCodesWithTestDateProvider.lastBlockTimestamp(); + expect(after).toBeGreaterThanOrEqual(before); + expect(testDateProvider.now()).toBeGreaterThanOrEqual(after * 1000); + expect(testDateProvider.now()).toBeLessThan((after + 5) * 1000); + }); + + it('warp() syncs dateProvider to the warped timestamp', async () => { + const current = await cheatCodesWithTestDateProvider.lastBlockTimestamp(); + const target = current + 1000; + await cheatCodesWithTestDateProvider.warp(target); + expect(testDateProvider.now()).toBeGreaterThanOrEqual(target * 1000); + expect(testDateProvider.now()).toBeLessThan((target + 5) * 1000); + }); + + it('mineEmptyBlock() syncs dateProvider to latest block timestamp', async () => { + const before = await cheatCodesWithTestDateProvider.lastBlockTimestamp(); + await cheatCodesWithTestDateProvider.mineEmptyBlock(); + const after = await cheatCodesWithTestDateProvider.lastBlockTimestamp(); + expect(after).toBeGreaterThanOrEqual(before); + expect(testDateProvider.now()).toBeGreaterThanOrEqual(after * 1000); + expect(testDateProvider.now()).toBeLessThan((after + 5) * 1000); + }); + }); + describe('mineEmptyBlock', () => { it('mines an empty block while preserving pending transactions', async () => { // Deploy a token first (with automine enabled) diff --git a/yarn-project/ethereum/src/test/eth_cheat_codes.ts b/yarn-project/ethereum/src/test/eth_cheat_codes.ts index b1cbdd199d6f..bcc9c140cde2 100644 --- a/yarn-project/ethereum/src/test/eth_cheat_codes.ts +++ b/yarn-project/ethereum/src/test/eth_cheat_codes.ts @@ -101,6 +101,7 @@ export class EthCheatCodes { */ public async mine(numberOfBlocks: number | bigint = 1): Promise { await this.doMine(Number(numberOfBlocks)); + await this.syncDateProvider(); this.logger.warn(`Mined ${numberOfBlocks} L1 blocks`); } @@ -118,6 +119,7 @@ export class EthCheatCodes { public async evmMine(): Promise { try { await this.doRpcCall('evm_mine', []); + await this.syncDateProvider(); this.logger.warn(`Mined 1 L1 block with evm_mine`); } catch (err) { throw new Error(`Error mining: ${err}`); @@ -517,6 +519,7 @@ export class EthCheatCodes { } }); + await this.syncDateProvider(); this.logger.warn(`Mined ${blockCount} empty L1 ${pluralize('block', blockCount)}`); } diff --git a/yarn-project/stdlib/src/timetable/index.test.ts b/yarn-project/stdlib/src/timetable/index.test.ts index f0a2ede5d718..5077fcdcfac0 100644 --- a/yarn-project/stdlib/src/timetable/index.test.ts +++ b/yarn-project/stdlib/src/timetable/index.test.ts @@ -104,4 +104,29 @@ describe('timetable validation', () => { expect(timing.calculateMaxBlocksPerSlot()).toBe(1); }); + + it('derives single-block fast-config timing matching FAST_E2E_SETUP_OPTS', () => { + // Replicates FAST_E2E_SETUP_OPTS values (defined in end-to-end; not imported to avoid a cycle). + const timing = createCheckpointTimingModel({ + aztecSlotDuration: 12, + ethereumSlotDuration: 4, + l1PublishingTime: 4, + pipelining: true, + // blockDuration intentionally unset — single-block-per-slot mode + }); + + // ethereumSlotDuration < 8 triggers normalizeCheckpointTimingConfig auto-tuning + expect(timing.p2pPropagationTime).toBe(0); + expect(timing.checkpointAssembleTime).toBe(0.5); + expect(timing.checkpointInitializationTime).toBe(0.5); + expect(timing.minExecutionTime).toBe(1); + // checkpointFinalizationTime = assemble + 2*p2p + publish = 0.5 + 0 + 4 = 4.5 + expect(timing.checkpointFinalizationTime).toBeCloseTo(4.5); + // initializeDeadline = aztecSlotDuration - minimumBuildSlotWork = 12 - 2.5 = 9.5 + expect(timing.initializeDeadline).toBeCloseTo(9.5); + // checkpointPublishingDeadline = 2 * aztecSlotDuration - l1PublishingTime = 20 + expect(timing.checkpointPublishingDeadline).toBeCloseTo(20); + // blockDuration unset → single-block mode + expect(timing.calculateMaxBlocksPerSlot()).toBe(1); + }); });