From cf7ba72f8df041fd9f212abb96b4abf8e8699770 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Wed, 6 May 2026 12:58:45 -0300 Subject: [PATCH] test(e2e): wait for archiver sync before asserting pipelining Alternative fix for flake in epochs_mbps.pipeline. See also https://gist.github.com/AztecBot/164f3e04bd74f48cafd6505433935421. --- .../epochs_mbps.pipeline.parallel.test.ts | 40 +++++++++++++++---- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/yarn-project/end-to-end/src/e2e_epochs/epochs_mbps.pipeline.parallel.test.ts b/yarn-project/end-to-end/src/e2e_epochs/epochs_mbps.pipeline.parallel.test.ts index 013324576541..35f3fb1acc40 100644 --- a/yarn-project/end-to-end/src/e2e_epochs/epochs_mbps.pipeline.parallel.test.ts +++ b/yarn-project/end-to-end/src/e2e_epochs/epochs_mbps.pipeline.parallel.test.ts @@ -12,6 +12,7 @@ import { asyncMap } from '@aztec/foundation/async-map'; import { BlockNumber, CheckpointNumber, SlotNumber } from '@aztec/foundation/branded-types'; import { times, timesAsync } from '@aztec/foundation/collection'; import { SecretValue } from '@aztec/foundation/config'; +import { retryUntil } from '@aztec/foundation/retry'; import { bufferToHex } from '@aztec/foundation/string'; import { executeTimeout } from '@aztec/foundation/timer'; import { TestContract } from '@aztec/noir-test-contracts.js/Test'; @@ -113,8 +114,25 @@ describe('e2e_epochs/epochs_mbps_pipeline', () => { logger.warn(`Test setup completed.`, { validators: validators.map(v => v.attester.toString()) }); } - /** Retrieves all checkpoints from the archiver, checks that one has the target block count, and returns its number. */ - async function assertMultipleBlocksPerSlot(targetBlockCount: number, logger: Logger): Promise { + /** + * Waits until the archiver's checkpointed chain tip has reached `targetBlockNumber`, then retrieves all checkpoints, + * checks that one has the target block count, and returns its number. + */ + async function assertMultipleBlocksPerSlot( + targetBlockCount: number, + targetBlockNumber: BlockNumber, + logger: Logger, + ): Promise { + await retryUntil( + async () => { + const checkpointed = await archiver.getBlockNumber({ tag: 'checkpointed' }); + return checkpointed !== undefined && checkpointed >= targetBlockNumber; + }, + `archiver checkpointed block ${targetBlockNumber}`, + 10, + 0.1, + ); + const checkpoints = await archiver.getCheckpoints({ from: CheckpointNumber(1), limit: 50 }); logger.warn(`Retrieved ${checkpoints.length} checkpoints from archiver`, { checkpoints: checkpoints.map(pc => pc.checkpoint.getStats()), @@ -253,14 +271,19 @@ describe('e2e_epochs/epochs_mbps_pipeline', () => { // Wait until all txs are mined const timeout = test.L2_SLOT_DURATION_IN_S * 5; - await executeTimeout( + const receipts = await executeTimeout( () => Promise.all(txHashes.map(txHash => waitForTx(context.aztecNode, txHash, { timeout }))), timeout * 1000, ); logger.warn(`All txs have been mined`); - // Verify MBPS works with pipelining - const multiBlockCheckpoint = await assertMultipleBlocksPerSlot(EXPECTED_BLOCKS_PER_CHECKPOINT, logger); + // Verify MBPS works with pipelining; target the highest block number across mined receipts + const maxMinedBlockNumber = BlockNumber(Math.max(...receipts.map(r => r.blockNumber ?? 0))); + const multiBlockCheckpoint = await assertMultipleBlocksPerSlot( + EXPECTED_BLOCKS_PER_CHECKPOINT, + maxMinedBlockNumber, + logger, + ); // Verify the pipelining offset: build slot N vs submission slot N+1 await assertProposerPipelining(blockProposedEvents, logger); @@ -348,14 +371,15 @@ describe('e2e_epochs/epochs_mbps_pipeline', () => { // Wait for a new checkpoint (recovery) - where all txs end up mined const timeout = test.L2_SLOT_DURATION_IN_S * 5; - await executeTimeout( + const receipts = await executeTimeout( () => Promise.all(txHashes.map(txHash => waitForTx(context.aztecNode, txHash, { timeout }))), timeout * 1000, ); logger.warn(`All txs have been mined`); - // Verify MBPS works with pipelining - await assertMultipleBlocksPerSlot(EXPECTED_BLOCKS_PER_CHECKPOINT, logger); + // Verify MBPS works with pipelining; target the highest block number across mined receipts + const maxMinedBlockNumber = BlockNumber(Math.max(...receipts.map(r => r.blockNumber ?? 0))); + await assertMultipleBlocksPerSlot(EXPECTED_BLOCKS_PER_CHECKPOINT, maxMinedBlockNumber, logger); // Verify the pipelining offset: build slot N vs submission slot N+1 await assertProposerPipelining(blockProposedEvents, logger);