diff --git a/yarn-project/end-to-end/src/multi-node/block-production/multi_validator_node.parallel.test.ts b/yarn-project/end-to-end/src/multi-node/block-production/multi_validator_node.parallel.test.ts index 7b2ce0b5150c..15084cbec107 100644 --- a/yarn-project/end-to-end/src/multi-node/block-production/multi_validator_node.parallel.test.ts +++ b/yarn-project/end-to-end/src/multi-node/block-production/multi_validator_node.parallel.test.ts @@ -17,6 +17,7 @@ import type { TestWallet } from '../../test-wallet/test_wallet.js'; import { MOCK_GOSSIP_MULTI_VALIDATOR_OPTS, MultiNodeTestContext, + NO_REORG_SUBMISSION_EPOCHS, buildMockGossipValidators, } from '../multi_node_test_context.js'; @@ -26,7 +27,7 @@ const COMMITTEE_SIZE = VALIDATOR_COUNT - 2; // Tests that a single AztecNodeService hosting multiple validator keys correctly signs attestations // and filters signing to only active committee members. One node, 5 validators staked, committee // size 3. Uses MultiNodeTestContext on the mock-gossip bus: all 5 validators on a single physical -// node, ethSlot=8s, aztecSlot=36s, epoch=2, proofSubEpochs=1024. Each it is an isolated CI job +// node, ethSlot=8s, aztecSlot=36s, epoch=2, proofSubEpochs=NO_REORG_SUBMISSION_EPOCHS. Each it is an isolated CI job // (parallel convention). describe('multi-node/block-production/multi_validator_node', () => { jest.setTimeout(15 * 60 * 1000); @@ -51,7 +52,7 @@ describe('multi-node/block-production/multi_validator_node', () => { aztecEpochDuration: 2, ethereumSlotDuration: 8, aztecSlotDuration: 36, - aztecProofSubmissionEpochs: 1024, + aztecProofSubmissionEpochs: NO_REORG_SUBMISSION_EPOCHS, anvilSlotsInAnEpoch: 4, blockDurationMs: 6000, minTxsPerBlock: 0, diff --git a/yarn-project/end-to-end/src/multi-node/multi_node_test_context.ts b/yarn-project/end-to-end/src/multi-node/multi_node_test_context.ts index 26839b029986..79679f9ec698 100644 --- a/yarn-project/end-to-end/src/multi-node/multi_node_test_context.ts +++ b/yarn-project/end-to-end/src/multi-node/multi_node_test_context.ts @@ -21,12 +21,14 @@ import { privateKeyToAccount } from 'viem/accounts'; import { testSpan } from '../fixtures/timing.js'; import { getPrivateKeyFromIndex } from '../fixtures/utils.js'; +import { NO_REORG_SUBMISSION_EPOCHS } from '../single-node/setup.js'; import { SingleNodeTestContext, type SingleNodeTestOpts, type TrackedSequencerEvent, } from '../single-node/single_node_test_context.js'; +export { NO_REORG_SUBMISSION_EPOCHS, PROVING_SLOT_TIMING } from '../single-node/setup.js'; export { WORLD_STATE_CHECKPOINT_HISTORY, WORLD_STATE_BLOCK_CHECK_INTERVAL, @@ -73,7 +75,7 @@ export const MOCK_GOSSIP_MULTI_VALIDATOR_OPTS = { mockGossipSubNetwork: true, skipInitialSequencer: true, startProverNode: false, - aztecProofSubmissionEpochs: 1024, + aztecProofSubmissionEpochs: NO_REORG_SUBMISSION_EPOCHS, numberOfAccounts: 0, } as const; diff --git a/yarn-project/end-to-end/src/single-node/block-building/debug_trace.test.ts b/yarn-project/end-to-end/src/single-node/block-building/debug_trace.test.ts index 77c5d3814af5..fcb86aab36b1 100644 --- a/yarn-project/end-to-end/src/single-node/block-building/debug_trace.test.ts +++ b/yarn-project/end-to-end/src/single-node/block-building/debug_trace.test.ts @@ -16,14 +16,14 @@ import { type Hex, decodeFunctionData, encodeFunctionData, multicall3Abi } from import { getPrivateKeyFromIndex } from '../../fixtures/utils.js'; import { waitForBlockNumber } from '../../fixtures/wait_helpers.js'; -import { setupBlockProducer } from '../setup.js'; +import { NO_REORG_SUBMISSION_EPOCHS, setupBlockProducer } from '../setup.js'; import type { SingleNodeTestContext } from '../single_node_test_context.js'; // Tests that the sequencer can successfully process blocks when L1 block proposals are forwarded // via a proxy contract (Forwarder). Also tests that a corrupted first propose call (failing with // allowFailure:true) followed by a valid second call still produces blocks. // Uses setupBlockProducer (no prover node) with numberOfAccounts:2, ethereumSlotDuration:4, -// aztecSlotDuration:12, aztecEpochDuration:32, aztecProofSubmissionEpochs:640, minTxsPerBlock:0 — +// aztecSlotDuration:12, aztecEpochDuration:32, aztecProofSubmissionEpochs:NO_REORG_SUBMISSION_EPOCHS, minTxsPerBlock:0 — // production sequencer, anvil interval mining. The L1 interaction is Forwarder/Multicall3/Rollup // contract interception for block-proposal routing, not cross-chain bridging. describe('single-node/block-building/debug_trace', () => { @@ -58,7 +58,7 @@ describe('single-node/block-building/debug_trace', () => { // boundary at slot 6; the proposer-corruption test intercepts every propose and runs long // enough to reach it, where the proposer selection changes and the propose silently reverts. aztecEpochDuration: 32, - aztecProofSubmissionEpochs: 640, + aztecProofSubmissionEpochs: NO_REORG_SUBMISSION_EPOCHS, inboxLag: 2, }); ({ aztecNode, logger, aztecNodeAdmin, config } = test.context); diff --git a/yarn-project/end-to-end/src/single-node/bot/bot.test.ts b/yarn-project/end-to-end/src/single-node/bot/bot.test.ts index d3ee2314eaf9..3a73306a5c8a 100644 --- a/yarn-project/end-to-end/src/single-node/bot/bot.test.ts +++ b/yarn-project/end-to-end/src/single-node/bot/bot.test.ts @@ -23,10 +23,11 @@ import { jest } from '@jest/globals'; import { PIPELINED_FEE_PADDING, PIPELINING_SETUP_OPTS } from '../../fixtures/fixtures.js'; import { getPrivateKeyFromIndex, setup } from '../../fixtures/utils.js'; +import { NO_REORG_SUBMISSION_EPOCHS } from '../setup.js'; // Tests the transaction bot implementations (transfer bot, AMM bot, cross-chain bot). -// Uses setup(0, PIPELINING_SETUP_OPTS + aztecProofSubmissionEpochs:640) with one node, production -// sequencer (ethereumSlotDuration=4s, aztecSlotDuration=12s, proofSubEpochs=640, minTxsPerBlock=0; +// Uses setup(0, PIPELINING_SETUP_OPTS + aztecProofSubmissionEpochs:NO_REORG_SUBMISSION_EPOCHS) with one node, production +// sequencer (ethereumSlotDuration=4s, aztecSlotDuration=12s, proofSubEpochs=NO_REORG_SUBMISSION_EPOCHS, minTxsPerBlock=0; // aztecEpochDuration is the setup() default). The bridge-resume, setup-via-bridging, and // cross-chain-bot subsuites actively drive L1 cross-chain bridging: fee-juice portal deposits, // advanceInboxInProgress, and L2→L1 messages via CrossChainBot. @@ -43,7 +44,7 @@ describe('single-node/bot/bot', () => { const [botAccount] = await getInitialTestAccountsData(); const setupResult = await setup(0, { ...PIPELINING_SETUP_OPTS, - aztecProofSubmissionEpochs: 640, + aztecProofSubmissionEpochs: NO_REORG_SUBMISSION_EPOCHS, additionallyFundedAccounts: [botAccount], }); ({ diff --git a/yarn-project/end-to-end/src/single-node/fees/failures.test.ts b/yarn-project/end-to-end/src/single-node/fees/failures.test.ts index ef9e336ca787..234b84c54f44 100644 --- a/yarn-project/end-to-end/src/single-node/fees/failures.test.ts +++ b/yarn-project/end-to-end/src/single-node/fees/failures.test.ts @@ -19,11 +19,12 @@ import { jest } from '@jest/globals'; import { PIPELINING_SETUP_OPTS, U128_UNDERFLOW_ERROR } from '../../fixtures/fixtures.js'; import { ensureAuthRegistryPublished } from '../../fixtures/setup.js'; import { expectMapping } from '../../fixtures/utils.js'; +import { NO_REORG_SUBMISSION_EPOCHS } from '../setup.js'; import { FeesTest } from './fees_test.js'; // Fee behaviour when transactions revert. Uses FeesTest (prod sequencer, pipelining preset: // ethSlot=4s, aztecSlot=12s, inboxLag=2, minTxsPerBlock=0, aztecEpochDuration=4, -// aztecProofSubmissionEpochs=640), fake in-proc prover node, and GasBridgingTestHarness for +// aztecProofSubmissionEpochs=NO_REORG_SUBMISSION_EPOCHS), fake in-proc prover node, and GasBridgingTestHarness for // L1↔L2 fee-juice bridging. Auto-proving is disabled after setup so tests control proving themselves. describe('single-node/fees/failures', () => { // FeesTest.setup + applyFPCSetup chains many dependent txs which run at the @@ -45,7 +46,11 @@ describe('single-node/fees/failures', () => { // Shorter epochs (default 32 → 4) speed the per-test `advanceToNextEpoch + waitForProven` // cycle: the prover-node submits a proof as soon as the epoch is complete, so ~8x shorter // epochs ≈ ~8x faster proof cadence per cycle. Setup itself stays slot-bound. - await t.setup({ ...PIPELINING_SETUP_OPTS, aztecProofSubmissionEpochs: 640, aztecEpochDuration: 4 }); + await t.setup({ + ...PIPELINING_SETUP_OPTS, + aztecProofSubmissionEpochs: NO_REORG_SUBMISSION_EPOCHS, + aztecEpochDuration: 4, + }); await t.applyFPCSetup(); ({ wallet, aliceAddress, sequencerAddress, bananaCoin, bananaFPC, gasSettings } = t); await ensureAuthRegistryPublished(wallet, aliceAddress); diff --git a/yarn-project/end-to-end/src/single-node/fees/fee_settings.test.ts b/yarn-project/end-to-end/src/single-node/fees/fee_settings.test.ts index 333efc4067f3..53b062cff8ce 100644 --- a/yarn-project/end-to-end/src/single-node/fees/fee_settings.test.ts +++ b/yarn-project/end-to-end/src/single-node/fees/fee_settings.test.ts @@ -16,6 +16,7 @@ import { DEFAULT_MIN_FEE_PADDING } from '../../fixtures/fixtures.js'; import { waitForBlockNumber, waitForNodeCheckpoint } from '../../fixtures/wait_helpers.js'; import type { TestWallet } from '../../test-wallet/test_wallet.js'; import { proveInteraction } from '../../test-wallet/utils.js'; +import { NO_REORG_SUBMISSION_EPOCHS } from '../setup.js'; import { FeesTest } from './fees_test.js'; /** @@ -55,7 +56,7 @@ async function spikeL1BaseFeeUntilMinFee( // Fee oracle and wallet fee-padding behaviour under L1 base-fee spikes and governance fee-config bumps. // Uses FeesTest with a custom timing preset (ethSlot=4s, aztecSlot=12s, inboxLag=2, minTxsPerBlock=0, -// aztecProofSubmissionEpochs=640, manaTarget=4M, walletMinFeePadding=30) and fake in-proc prover node. +// aztecProofSubmissionEpochs=NO_REORG_SUBMISSION_EPOCHS, manaTarget=4M, walletMinFeePadding=30) and fake in-proc prover node. // No token bridging involved — all L1 interaction is L1 base-fee cheat codes and Rollup oracle calls. // (Category: single-node despite using FeesTest, since no cross-chain token transfer or fee-juice // portal bridging occurs in any test body — L1 is active only for oracle updates.) @@ -79,7 +80,7 @@ describe('single-node/fees/fee_settings', () => { minTxsPerBlock: 0, aztecSlotDuration: AZTEC_SLOT_DURATION, ethereumSlotDuration: 4, - aztecProofSubmissionEpochs: 640, + aztecProofSubmissionEpochs: NO_REORG_SUBMISSION_EPOCHS, walletMinFeePadding: 30, manaTarget: 4_000_000n, }); diff --git a/yarn-project/end-to-end/src/single-node/misc/missed_l1_slot.test.ts b/yarn-project/end-to-end/src/single-node/misc/missed_l1_slot.test.ts index 7500c72cb3ea..c68ff5c5e185 100644 --- a/yarn-project/end-to-end/src/single-node/misc/missed_l1_slot.test.ts +++ b/yarn-project/end-to-end/src/single-node/misc/missed_l1_slot.test.ts @@ -9,7 +9,7 @@ import { getTimestampForSlot } from '@aztec/stdlib/epoch-helpers'; import { jest } from '@jest/globals'; import { proveAndSendTxs } from '../../test-wallet/utils.js'; -import { setupWithProver } from '../setup.js'; +import { NO_REORG_SUBMISSION_EPOCHS, setupWithProver } from '../setup.js'; import { SingleNodeTestContext } from '../single_node_test_context.js'; jest.setTimeout(1000 * 60 * 10); @@ -90,7 +90,7 @@ describe('single-node/misc/missed_l1_slot', () => { ethereumSlotDuration: 6, aztecSlotDurationInL1Slots: L1_SLOTS_PER_L2_SLOT, startProverNode: false, - aztecProofSubmissionEpochs: 1024, + aztecProofSubmissionEpochs: NO_REORG_SUBMISSION_EPOCHS, // Required for the proposer's own broadcasts to route through the local // proposal handler (the dummy p2p service drops them). Without this, the // archiver's #proposedCheckpoints map stays empty and the pipelining diff --git a/yarn-project/end-to-end/src/single-node/partial-proofs/multi_root.test.ts b/yarn-project/end-to-end/src/single-node/partial-proofs/multi_root.test.ts index 71c065886edf..8c8b2fead495 100644 --- a/yarn-project/end-to-end/src/single-node/partial-proofs/multi_root.test.ts +++ b/yarn-project/end-to-end/src/single-node/partial-proofs/multi_root.test.ts @@ -24,15 +24,15 @@ import { type TxReceipt, TxStatus } from '@aztec/stdlib/tx'; import { type Hex, decodeEventLog } from 'viem'; import { waitForL2ToL1Witness } from '../../fixtures/wait_helpers.js'; -import { SingleNodeTestContext, jest, setupWithProver } from './setup.js'; +import { NO_REORG_SUBMISSION_EPOCHS, SingleNodeTestContext, jest, setupWithProver } from './setup.js'; // Suite: verifies the AZIP-14 partial-proof multi-root Outbox design. Drives an EpochTestSettler // manually to stage progressively deeper partial-proof roots (K=1, 2, 3) for the same epoch, then // asserts: (a) the node picks the smallest covering root, (b) any covering root produces a valid // consume tx, (c) the shared bitmap blocks double-spend, and (d) K=4 can be staged later. // SingleNodeTestContext: single node, no prover, prod-seq, interval mining. Timing: ethSlot=default -// (8s/12s CI), aztecSlot=default, epoch=1000, proofSubmissionEpochs=1024 (v5: the disableAnvilTestWatcher -// override was removed and a perBlockAllocationMultiplier=1.3 was added so the first block of the +// (8s/12s CI), aztecSlot=default, epoch=32, proofSubmissionEpochs=NO_REORG_SUBMISSION_EPOCHS (v5: the +// disableAnvilTestWatcher override was removed and a perBlockAllocationMultiplier=1.3 was added so the first block of the // now-up-to-5-block checkpoint has enough DA budget for the TestContract deploy tx). The test actively // calls the Outbox L1 contract to consume L2-to-L1 messages → cross-chain. describe('single-node/partial-proofs/multi_root', () => { @@ -56,12 +56,11 @@ describe('single-node/partial-proofs/multi_root', () => { // fallback DA gas for the TestContract deploy is based on a 4-block checkpoint, so give the // first block enough of the checkpoint DA budget to include the deploy tx. perBlockAllocationMultiplier: 1.3, - // Long epoch so 4 well-spaced checkpoints comfortably fit before the boundary. - aztecEpochDuration: 1000, + // Epoch long enough that the 4 well-spaced checkpoints fit before the boundary. + aztecEpochDuration: 32, // Don't let the real prover land a partial proof under us. We drive Outbox state via the - // settler. `aztecProofSubmissionEpochs` >> test duration makes it impossible to enter the - // submission window. - aztecProofSubmissionEpochs: 1024, + // settler; a never-reorg window makes it impossible to enter the submission window. + aztecProofSubmissionEpochs: NO_REORG_SUBMISSION_EPOCHS, startProverNode: false, }); ({ logger } = test); diff --git a/yarn-project/end-to-end/src/single-node/partial-proofs/setup.ts b/yarn-project/end-to-end/src/single-node/partial-proofs/setup.ts index e2d5324a4d64..2fb92da27743 100644 --- a/yarn-project/end-to-end/src/single-node/partial-proofs/setup.ts +++ b/yarn-project/end-to-end/src/single-node/partial-proofs/setup.ts @@ -1,8 +1,8 @@ import { jest } from '@jest/globals'; -import { setupWithProver } from '../setup.js'; +import { NO_REORG_SUBMISSION_EPOCHS, PROVING_SLOT_TIMING, setupWithProver } from '../setup.js'; import { SingleNodeTestContext } from '../single_node_test_context.js'; jest.setTimeout(1000 * 60 * 10); -export { jest, setupWithProver, SingleNodeTestContext }; +export { jest, setupWithProver, SingleNodeTestContext, NO_REORG_SUBMISSION_EPOCHS, PROVING_SLOT_TIMING }; diff --git a/yarn-project/end-to-end/src/single-node/partial-proofs/single_root.test.ts b/yarn-project/end-to-end/src/single-node/partial-proofs/single_root.test.ts index 43e50f4ddb74..012effe3e02b 100644 --- a/yarn-project/end-to-end/src/single-node/partial-proofs/single_root.test.ts +++ b/yarn-project/end-to-end/src/single-node/partial-proofs/single_root.test.ts @@ -2,7 +2,7 @@ import type { Logger } from '@aztec/aztec.js/log'; import type { ChainMonitor } from '@aztec/ethereum/test'; import { CheckpointNumber, EpochNumber } from '@aztec/foundation/branded-types'; -import { SingleNodeTestContext, jest, setupWithProver } from './setup.js'; +import { PROVING_SLOT_TIMING, SingleNodeTestContext, jest, setupWithProver } from './setup.js'; // Co-located with the multi-root suite: both manually drive partial-epoch proving on a single node // with a very long epoch. This one is the only coverage of the prover-node `startProof` path (the @@ -15,10 +15,9 @@ describe('single-node/partial-proofs/single_root', () => { let test: SingleNodeTestContext; beforeEach(async () => { - // Run at the 4s/12s slot-cadence floor: the body waits in real wall-clock for the sequencer to publish - // empty checkpoints one per L2 slot, so a shorter slot shortens that wait. 12s is the floor for the - // 3s-block timing model. A clock warp here races the sequencer's building and trips EmptyEpochError. - test = await setupWithProver({ aztecEpochDuration: 1000, ethereumSlotDuration: 4, aztecSlotDurationInL1Slots: 3 }); + // A clock warp here races the sequencer's building and trips EmptyEpochError, so this runs at the + // real-time PROVING_SLOT_TIMING floor. Long epoch so the partial-proof checkpoints fit before the boundary. + test = await setupWithProver({ ...PROVING_SLOT_TIMING, aztecEpochDuration: 1000 }); ({ monitor, logger } = test); }); diff --git a/yarn-project/end-to-end/src/single-node/proving/long_proving_time.test.ts b/yarn-project/end-to-end/src/single-node/proving/long_proving_time.test.ts index 7a50e9a8f006..c8244d5a17a2 100644 --- a/yarn-project/end-to-end/src/single-node/proving/long_proving_time.test.ts +++ b/yarn-project/end-to-end/src/single-node/proving/long_proving_time.test.ts @@ -2,7 +2,13 @@ import type { Logger } from '@aztec/aztec.js/log'; import { ChainMonitor } from '@aztec/ethereum/test'; import { sleep } from '@aztec/foundation/sleep'; -import { SingleNodeTestContext, jest, setupWithProver } from './setup.js'; +import { + NO_REORG_SUBMISSION_EPOCHS, + PROVING_SLOT_TIMING, + SingleNodeTestContext, + jest, + setupWithProver, +} from './setup.js'; const MAX_JOB_COUNT = 20; @@ -25,18 +31,13 @@ describe('single-node/proving/long_proving_time', () => { // So we delay proving of each circuit such that each epoch takes 3 epochs to prove. const aztecEpochDuration = 2; // The body is bounded by the real-wall-clock prover delay (a `sleep`, not the date provider, so warping - // cannot shrink it): a single agent serially sleeps `proverTestDelayMs` per circuit. Both the - // block-build cadence and the proving delay scale with the slot duration, so a shorter L1 slot scales - // the whole timeline down while keeping the delay-to-slot ratio — and hence the "proving lags block - // production by ~3 epochs" assertion — intact. The L2 slot stays at 3 L1 slots (12s): the timing model - // needs S >= ~8.5s with the default 3s block duration to fit one block per checkpoint, so 12s is the - // floor — an 8s slot derives 0 blocks per checkpoint and trips the timing-config guard. - const ethereumSlotDuration = 4; - const aztecSlotDurationInL1Slots = 3; + // cannot shrink it): a single agent serially sleeps `proverTestDelayMs` per circuit. Both the block-build + // cadence and the proving delay scale with the slot duration, so the PROVING_SLOT_TIMING floor scales the + // whole timeline down while keeping the delay-to-slot ratio — and hence the "proving lags block production + // by ~3 epochs" assertion — intact. const { aztecSlotDuration } = SingleNodeTestContext.getSlotDurations({ aztecEpochDuration, - ethereumSlotDuration, - aztecSlotDurationInL1Slots, + ...PROVING_SLOT_TIMING, }); const epochDurationInSeconds = aztecSlotDuration * aztecEpochDuration; const proverTestDelayMs = (epochDurationInSeconds * 1000 * 3) / 4; @@ -44,9 +45,8 @@ describe('single-node/proving/long_proving_time', () => { // at least that many epochs to avoid rejecting jobs as stale. test = await setupWithProver({ aztecEpochDuration, - ethereumSlotDuration, - aztecSlotDurationInL1Slots, - aztecProofSubmissionEpochs: 1000, // Effectively don't re-org + ...PROVING_SLOT_TIMING, + aztecProofSubmissionEpochs: NO_REORG_SUBMISSION_EPOCHS, // Effectively don't re-org proverTestDelayMs, proverNodeMaxPendingJobs: MAX_JOB_COUNT, // Prove multiple epochs concurrently proverBrokerMaxEpochsToKeepResultsFor: 10, diff --git a/yarn-project/end-to-end/src/single-node/proving/multi_proof.test.ts b/yarn-project/end-to-end/src/single-node/proving/multi_proof.test.ts index 0e75122f6a9b..d2c9a17e0afa 100644 --- a/yarn-project/end-to-end/src/single-node/proving/multi_proof.test.ts +++ b/yarn-project/end-to-end/src/single-node/proving/multi_proof.test.ts @@ -7,7 +7,7 @@ import { getEpochAtSlot } from '@aztec/stdlib/epoch-helpers'; import { jest } from '@jest/globals'; import type { EndToEndContext } from '../../fixtures/utils.js'; -import { setupWithProver } from '../setup.js'; +import { PROVING_SLOT_TIMING, setupWithProver } from '../setup.js'; import { SingleNodeTestContext } from '../single_node_test_context.js'; jest.setTimeout(1000 * 60 * 10); @@ -27,17 +27,12 @@ describe('single-node/proving/multi_proof', () => { // Don't start prover node during setup - we'll create and manage all prover nodes in the test // This ensures we can apply delay patches before any prover starts proving. // - // Run at the 4s/12s slot-cadence floor: the body is bounded by the production sequencer building epoch - // 0 on the real wall-clock (one empty block per L2 slot) plus the per-prover stagger - // (`index * ethereumSlotDuration` ms). Both scale with the slot duration, so a shorter slot shortens the - // timeline while keeping the stagger >=1 L1 slot apart (so the three provers still land their proofs on - // distinct L1 blocks). 12s is the floor: the timing model needs an L2 slot >= ~8.5s with the default 3s - // block to fit one block per checkpoint, so an 8s slot derives 0 blocks per checkpoint. The 6-slot epoch - // is kept so epoch 0 still reliably lands >=1 block. + // The per-prover stagger (`index * ethereumSlotDuration` ms) scales with the slot duration, so the + // PROVING_SLOT_TIMING floor keeps the timeline short while holding the stagger >=1 L1 slot apart (the + // three provers still land their proofs on distinct L1 blocks). test = await setupWithProver({ startProverNode: false, - ethereumSlotDuration: 4, - aztecSlotDurationInL1Slots: 3, + ...PROVING_SLOT_TIMING, }); ({ context, logger } = test); }); diff --git a/yarn-project/end-to-end/src/single-node/proving/optimistic.parallel.test.ts b/yarn-project/end-to-end/src/single-node/proving/optimistic.parallel.test.ts index 98b9cffe1485..8a719cd3556c 100644 --- a/yarn-project/end-to-end/src/single-node/proving/optimistic.parallel.test.ts +++ b/yarn-project/end-to-end/src/single-node/proving/optimistic.parallel.test.ts @@ -13,7 +13,7 @@ import { expect, jest } from '@jest/globals'; import type { EndToEndContext } from '../../fixtures/utils.js'; import { waitForNodeCheckpoint } from '../../fixtures/wait_helpers.js'; import { proveInteraction } from '../../test-wallet/utils.js'; -import { setupWithProver } from '../setup.js'; +import { NO_REORG_SUBMISSION_EPOCHS, setupWithProver } from '../setup.js'; import { FAST_REORG_TIMING, SingleNodeTestContext } from '../single_node_test_context.js'; jest.setTimeout(1000 * 60 * 20); @@ -26,7 +26,7 @@ jest.setTimeout(1000 * 60 * 20); * six `describe` blocks builds a fresh context in its own `beforeEach` and tears it down in the shared `afterEach`. The * happy-path pair uses defaults (`numberOfAccounts: 1`; ethSlot=8s local/12s CI, aztecSlot=16s/24s, epoch=6, * proofSubEpochs=1); the five reorg describes use a faster cadence (ethSlot=4s, aztecSlot=36s, epoch=4 — or 8 for the - * with-replacement case so the replacement lands in-epoch — proofSubEpochs=1000, blockDurationMs=8s, minTxsPerBlock=0, + * with-replacement case so the replacement lands in-epoch — proofSubEpochs=NO_REORG_SUBMISSION_EPOCHS, blockDurationMs=8s, minTxsPerBlock=0, * anvilSlotsInAnEpoch=32, maxSpeedUpAttempts=0, cancelTxOnTimeout=false). The `prover-node starts mid-epoch` describe * sets `startProverNode: false` and spins up the prover via `test.createProverNode()` partway through the epoch. * @@ -275,7 +275,7 @@ describe('single-node/proving/optimistic', () => { // next epoch). aztecEpochDuration: 8, minTxsPerBlock: 0, - aztecProofSubmissionEpochs: 1000, + aztecProofSubmissionEpochs: NO_REORG_SUBMISSION_EPOCHS, }); ({ rollup, logger, context } = test); ({ L2_SLOT_DURATION_IN_S } = test); @@ -411,7 +411,7 @@ describe('single-node/proving/optimistic', () => { maxSpeedUpAttempts: 0, cancelTxOnTimeout: false, minTxsPerBlock: 0, - aztecProofSubmissionEpochs: 1000, + aztecProofSubmissionEpochs: NO_REORG_SUBMISSION_EPOCHS, }); ({ rollup, logger, context } = test); ({ L2_SLOT_DURATION_IN_S } = test); @@ -511,7 +511,7 @@ describe('single-node/proving/optimistic', () => { maxSpeedUpAttempts: 0, cancelTxOnTimeout: false, minTxsPerBlock: 0, - aztecProofSubmissionEpochs: 1000, + aztecProofSubmissionEpochs: NO_REORG_SUBMISSION_EPOCHS, }); ({ rollup, logger, context } = test); ({ L2_SLOT_DURATION_IN_S } = test); @@ -590,7 +590,7 @@ describe('single-node/proving/optimistic', () => { maxSpeedUpAttempts: 0, cancelTxOnTimeout: false, minTxsPerBlock: 0, - aztecProofSubmissionEpochs: 1000, + aztecProofSubmissionEpochs: NO_REORG_SUBMISSION_EPOCHS, // Apply a delay between "epoch complete on L1" and the prover-node hand-off so // the reorg below has time to be processed before finalization starts. proverNodeConfig: { proverNodeEpochProvingDelayMs: 10_000 }, @@ -675,7 +675,7 @@ describe('single-node/proving/optimistic', () => { maxSpeedUpAttempts: 0, cancelTxOnTimeout: false, minTxsPerBlock: 0, - aztecProofSubmissionEpochs: 1000, + aztecProofSubmissionEpochs: NO_REORG_SUBMISSION_EPOCHS, }); ({ rollup, logger, context } = test); ({ L2_SLOT_DURATION_IN_S } = test); @@ -812,7 +812,7 @@ describe('single-node/proving/optimistic', () => { maxSpeedUpAttempts: 0, cancelTxOnTimeout: false, minTxsPerBlock: 0, - aztecProofSubmissionEpochs: 1000, + aztecProofSubmissionEpochs: NO_REORG_SUBMISSION_EPOCHS, }); ({ rollup, logger, context } = test); ({ L2_SLOT_DURATION_IN_S } = test); diff --git a/yarn-project/end-to-end/src/single-node/proving/proof_fails.parallel.test.ts b/yarn-project/end-to-end/src/single-node/proving/proof_fails.parallel.test.ts index e1670002f7bf..1282d1771e89 100644 --- a/yarn-project/end-to-end/src/single-node/proving/proof_fails.parallel.test.ts +++ b/yarn-project/end-to-end/src/single-node/proving/proof_fails.parallel.test.ts @@ -17,14 +17,14 @@ import { RootRollupPublicInputs } from '@aztec/stdlib/rollup'; import { jest } from '@jest/globals'; import type { EndToEndContext } from '../../fixtures/utils.js'; -import { setupWithProver } from '../setup.js'; +import { PROVING_SLOT_TIMING, setupWithProver } from '../setup.js'; import { SingleNodeTestContext } from '../single_node_test_context.js'; jest.setTimeout(1000 * 60 * 10); // Suite: 2 parallel scenarios testing proof-submission failure paths. SingleNodeTestContext with single -// sequencer node, no initial prover (prover nodes created in test bodies). Timing: ethSlot=8s, -// aztecSlot=2×8=16s, epoch=8, proofSubmissionEpochs=1 (default), blockDurationMs=3s, +// sequencer node, no initial prover (prover nodes created in test bodies). Timing: PROVING_SLOT_TIMING +// (ethSlot=4s, aztecSlot=12s), epoch=8, proofSubmissionEpochs=1 (default), blockDurationMs=3s, // cancelTxOnTimeout=false, inboxLag=2 (v5 always enforces the timetable, so the former enforceTimeTable // override is gone). Prover Delayer steers proof tx timing. describe('single-node/proving/proof_fails', () => { @@ -42,11 +42,10 @@ describe('single-node/proving/proof_fails', () => { beforeEach(async () => { test = await setupWithProver({ + ...PROVING_SLOT_TIMING, maxSpeedUpAttempts: 0, // No speed ups startProverNode: false, // Avoid early proving - ethereumSlotDuration: 8, aztecEpochDuration: 8, // Bump epoch duration so we can land at least one block in epoch 0 - aztecSlotDurationInL1Slots: 2, blockDurationMs: 3000, // 3s blocks → 2 blocks per checkpoint under pipelining cancelTxOnTimeout: false, }); diff --git a/yarn-project/end-to-end/src/single-node/proving/setup.ts b/yarn-project/end-to-end/src/single-node/proving/setup.ts index 33b205e5613a..d0d6d7f7a5c1 100644 --- a/yarn-project/end-to-end/src/single-node/proving/setup.ts +++ b/yarn-project/end-to-end/src/single-node/proving/setup.ts @@ -1,8 +1,15 @@ import { jest } from '@jest/globals'; -import { setupWithProver } from '../setup.js'; +import { NO_REORG_SUBMISSION_EPOCHS, PROVING_SLOT_TIMING, setupWithProver } from '../setup.js'; import { SingleNodeTestContext, WORLD_STATE_CHECKPOINT_HISTORY } from '../single_node_test_context.js'; jest.setTimeout(1000 * 60 * 15); -export { jest, setupWithProver, SingleNodeTestContext, WORLD_STATE_CHECKPOINT_HISTORY }; +export { + jest, + setupWithProver, + SingleNodeTestContext, + WORLD_STATE_CHECKPOINT_HISTORY, + NO_REORG_SUBMISSION_EPOCHS, + PROVING_SLOT_TIMING, +}; diff --git a/yarn-project/end-to-end/src/single-node/proving/upload_failed_proof.test.ts b/yarn-project/end-to-end/src/single-node/proving/upload_failed_proof.test.ts index b19ef1ada0ff..f4832796d4f1 100644 --- a/yarn-project/end-to-end/src/single-node/proving/upload_failed_proof.test.ts +++ b/yarn-project/end-to-end/src/single-node/proving/upload_failed_proof.test.ts @@ -15,7 +15,7 @@ import { join } from 'path'; import { getACVMConfig } from '../../fixtures/get_acvm_config.js'; import { getBBConfig } from '../../fixtures/get_bb_config.js'; import type { EndToEndContext } from '../../fixtures/utils.js'; -import { setupWithProver } from '../setup.js'; +import { PROVING_SLOT_TIMING, setupWithProver } from '../setup.js'; import { SingleNodeTestContext } from '../single_node_test_context.js'; jest.setTimeout(1000 * 60 * 10); @@ -43,16 +43,11 @@ describe('single-node/proving/upload_failed_proof', () => { uploadPath = await mkdtemp(join(tmpdir(), 'failed-proofs-')); uploadUrl = `file://${uploadPath}`; - // Run at the 4s/12s slot-cadence floor: the body is bounded by the production sequencer building epoch - // 0 on the real wall-clock (one empty checkpoint per L2 slot) before the prover finalizes epoch 0 at the - // epoch-1 boundary and trips the failing top-tree-prove hook. The epoch wall-time scales with the slot - // duration, so a shorter slot shortens the timeline. 12s is the floor: the timing model needs an L2 slot - // >= ~8.5s with the default 3s block to fit one block per checkpoint. The 6-slot epoch is kept so epoch 0 - // still reliably lands its checkpoints. + // Runs at the PROVING_SLOT_TIMING floor: the body waits in real wall-clock for the sequencer to build + // epoch 0 before the prover finalizes it at the epoch-1 boundary and trips the failing top-tree-prove hook. test = await setupWithProver({ proverNodeConfig: { proverNodeFailedEpochStore: uploadUrl }, - ethereumSlotDuration: 4, - aztecSlotDurationInL1Slots: 3, + ...PROVING_SLOT_TIMING, }); ({ context, logger } = test); ({ config } = context); diff --git a/yarn-project/end-to-end/src/single-node/recovery/manual_rollback.test.ts b/yarn-project/end-to-end/src/single-node/recovery/manual_rollback.test.ts index e7f4d5bc2e0a..17e8d6eb2c1f 100644 --- a/yarn-project/end-to-end/src/single-node/recovery/manual_rollback.test.ts +++ b/yarn-project/end-to-end/src/single-node/recovery/manual_rollback.test.ts @@ -5,11 +5,17 @@ import { CheckpointNumber } from '@aztec/foundation/branded-types'; import type { EndToEndContext } from '../../fixtures/utils.js'; import { waitForBlockNumber } from '../../fixtures/wait_helpers.js'; -import { SingleNodeTestContext, jest, setupWithProver } from './setup.js'; +import { + NO_REORG_SUBMISSION_EPOCHS, + PROVING_SLOT_TIMING, + SingleNodeTestContext, + jest, + setupWithProver, +} from './setup.js'; -// Exercises the aztecNodeAdmin.rollbackTo() API. Default SingleNodeTestContext with a very long epoch -// (aztecEpochDuration=100) so there are no L2 reorgs, no finalized blocks, and the full pending chain -// is prunable. Actively drives L1 via cheatcodes (reorgTo to remove blocks). +// Exercises the aztecNodeAdmin.rollbackTo() API. Runs on the PROVING_SLOT_TIMING floor with a never-reorg +// proof window (NO_REORG_SUBMISSION_EPOCHS) so there are no L2 reorgs, no finalized blocks, and the full +// pending chain is prunable. Actively drives L1 via cheatcodes (reorgTo to remove blocks). describe('single-node/recovery/manual_rollback', () => { let context: EndToEndContext; let logger: Logger; @@ -19,10 +25,13 @@ describe('single-node/recovery/manual_rollback', () => { let test: SingleNodeTestContext; beforeEach(async () => { - // Run at the 4s/12s slot-cadence floor: the body waits in real wall-clock for the sequencer to publish - // empty checkpoints one per L2 slot, so a shorter slot shortens that wait. A clock warp here races the - // building and times out. No L2 reorgs, no finalized blocks. - test = await setupWithProver({ aztecEpochDuration: 100, ethereumSlotDuration: 4, aztecSlotDurationInL1Slots: 3 }); + // A clock warp here races the sequencer's building and times out, so this runs at the real-time + // PROVING_SLOT_TIMING floor. NO_REORG_SUBMISSION_EPOCHS keeps the pending chain unproven and prunable. + test = await setupWithProver({ + ...PROVING_SLOT_TIMING, + aztecEpochDuration: 32, + aztecProofSubmissionEpochs: NO_REORG_SUBMISSION_EPOCHS, + }); ({ context, logger, rollup } = test); ({ aztecNode: node } = context); }); diff --git a/yarn-project/end-to-end/src/single-node/recovery/prune_when_cannot_build.test.ts b/yarn-project/end-to-end/src/single-node/recovery/prune_when_cannot_build.test.ts index 5dbc2a23e21a..f4a7f136dc47 100644 --- a/yarn-project/end-to-end/src/single-node/recovery/prune_when_cannot_build.test.ts +++ b/yarn-project/end-to-end/src/single-node/recovery/prune_when_cannot_build.test.ts @@ -7,7 +7,7 @@ import { retryUntil } from '@aztec/foundation/retry'; import { jest } from '@jest/globals'; import type { EndToEndContext } from '../../fixtures/utils.js'; -import { setupWithProver } from '../setup.js'; +import { PROVING_SLOT_TIMING, setupWithProver } from '../setup.js'; import { SingleNodeTestContext } from '../single_node_test_context.js'; jest.setTimeout(1000 * 60 * 10); @@ -18,7 +18,7 @@ jest.setTimeout(1000 * 60 * 10); // its proof-submission window closes the chain becomes prunable and the proposer's fallback must call // `prune()` despite being unable to propose. // -// Timing: ethSlot=8s, aztecSlot=2×8=16s, epoch=8, proofSubmissionEpochs=1. +// Timing: PROVING_SLOT_TIMING (ethSlot=4s, aztecSlot=12s), epoch=8, proofSubmissionEpochs=1. describe('single-node/recovery/prune_when_cannot_build', () => { let context: EndToEndContext; let logger: Logger; @@ -31,10 +31,9 @@ describe('single-node/recovery/prune_when_cannot_build', () => { beforeEach(async () => { test = await setupWithProver({ + ...PROVING_SLOT_TIMING, startProverNode: false, // Nothing ever proves epoch 0, so its pending chain stays unproven and becomes prunable. - ethereumSlotDuration: 8, aztecEpochDuration: 8, // Long enough to land a few checkpoints in epoch 0. - aztecSlotDurationInL1Slots: 2, aztecProofSubmissionEpochs: 1, // Pending chain becomes prunable one proof window after epoch 0. minTxsPerBlock: 0, // Solo proposer advances the pending chain on empty checkpoints. }); diff --git a/yarn-project/end-to-end/src/single-node/recovery/setup.ts b/yarn-project/end-to-end/src/single-node/recovery/setup.ts index e2d5324a4d64..2fb92da27743 100644 --- a/yarn-project/end-to-end/src/single-node/recovery/setup.ts +++ b/yarn-project/end-to-end/src/single-node/recovery/setup.ts @@ -1,8 +1,8 @@ import { jest } from '@jest/globals'; -import { setupWithProver } from '../setup.js'; +import { NO_REORG_SUBMISSION_EPOCHS, PROVING_SLOT_TIMING, setupWithProver } from '../setup.js'; import { SingleNodeTestContext } from '../single_node_test_context.js'; jest.setTimeout(1000 * 60 * 10); -export { jest, setupWithProver, SingleNodeTestContext }; +export { jest, setupWithProver, SingleNodeTestContext, NO_REORG_SUBMISSION_EPOCHS, PROVING_SLOT_TIMING }; diff --git a/yarn-project/end-to-end/src/single-node/sequencer/gov_proposal.parallel.test.ts b/yarn-project/end-to-end/src/single-node/sequencer/gov_proposal.parallel.test.ts index 07c5306c4deb..a33e80929f1f 100644 --- a/yarn-project/end-to-end/src/single-node/sequencer/gov_proposal.parallel.test.ts +++ b/yarn-project/end-to-end/src/single-node/sequencer/gov_proposal.parallel.test.ts @@ -29,7 +29,7 @@ import { privateKeyToAccount } from 'viem/accounts'; import { PIPELINING_SETUP_OPTS } from '../../fixtures/fixtures.js'; import { getPrivateKeyFromIndex } from '../../fixtures/utils.js'; -import { setupBlockProducer } from '../setup.js'; +import { NO_REORG_SUBMISSION_EPOCHS, setupBlockProducer } from '../setup.js'; import type { SingleNodeTestContext } from '../single_node_test_context.js'; const ETHEREUM_SLOT_DURATION = 8; @@ -45,8 +45,8 @@ jest.setTimeout(1000 * 60 * 5); // Tests that a single sequencer node running a 16-validator committee can propose blocks while // simultaneously casting governance votes, and can cast votes even when block building is disabled. // Setup: setupBlockProducer (no prover node) with { ...PIPELINING_SETUP_OPTS, ethSlot=8s, -// aztecSlot=16s, committee=16, aztecProofSubmissionEpochs=128 } — the high proof-submission window -// pins blocks against pruning (v5 always enforces the timetable, so the former enforceTimeTable +// aztecSlot=16s, committee=16, aztecProofSubmissionEpochs=NO_REORG_SUBMISSION_EPOCHS } — the high +// proof-submission window pins blocks against pruning (v5 always enforces the timetable, so the former enforceTimeTable // override is gone). Uses cheatCodes.eth.warp + retryUntil for timing. describe('single-node/sequencer/gov_proposal', () => { let logger: Logger; @@ -83,7 +83,7 @@ describe('single-node/sequencer/gov_proposal', () => { governanceProposerQuorum: QUORUM_SIZE, ethereumSlotDuration: ETHEREUM_SLOT_DURATION, aztecSlotDuration: AZTEC_SLOT_DURATION, - aztecProofSubmissionEpochs: 128, // no pruning + aztecProofSubmissionEpochs: NO_REORG_SUBMISSION_EPOCHS, // no pruning minTxsPerBlock: TXS_PER_BLOCK, automineL1Setup: true, // speed up setup // Force the L1 sync to fetch blobs rather than promote the locally-proposed checkpoint. diff --git a/yarn-project/end-to-end/src/single-node/setup.ts b/yarn-project/end-to-end/src/single-node/setup.ts index 8687cf925af0..0bcd59af5e73 100644 --- a/yarn-project/end-to-end/src/single-node/setup.ts +++ b/yarn-project/end-to-end/src/single-node/setup.ts @@ -6,6 +6,26 @@ import { SingleNodeTestContext, type SingleNodeTestOpts } from './single_node_te * with it; tests pick the factory matching their topology and vary it through `opts`. */ +/** + * Proof-submission window (in epochs) so large the chain never prunes/reorgs in the test's lifetime. + * Tests that must keep unproven blocks alive for their whole run (no prover, or a hand-driven settler) + * set `aztecProofSubmissionEpochs` to this rather than picking an arbitrary large number. + */ +export const NO_REORG_SUBMISSION_EPOCHS = 1024; + +/** + * The "12s floor" slot cadence: a 4s L1 slot with 3 L1 slots per L2 slot, i.e. a 12s L2 slot. Shared by + * the proving / partial-proof suites whose bodies wait in real wall-clock for the sequencer to build + * empty checkpoints (one per L2 slot) and so cannot warp the clock forward. 12s is the shortest L2 slot + * that still fits one block per checkpoint under the default 3s block-duration timing model (which needs + * S >= ~8.5s); an 8s slot derives 0 blocks per checkpoint and trips the timing-config guard. Running at + * this floor keeps those real-time waits as short as possible. + */ +export const PROVING_SLOT_TIMING = { + ethereumSlotDuration: 4, + aztecSlotDurationInL1Slots: 3, +} as const; + /** * Single sequencer plus the context's fake in-process prover node (`realProofs: false`, * `aztecProofSubmissionEpochs: 1`, `syncChainTip: 'checkpointed'`). This is exactly today's @@ -18,8 +38,8 @@ export function setupWithProver(opts: SingleNodeTestOpts = {}): Promise { return SingleNodeTestContext.setup({ startProverNode: false, - aztecProofSubmissionEpochs: 1024, + aztecProofSubmissionEpochs: NO_REORG_SUBMISSION_EPOCHS, aztecEpochDuration: 32, ...opts, pxeOpts: { syncChainTip: 'proposed', ...opts.pxeOpts },