From ab7ed7a11f2e64b97be5e25f456e297ef2739ddd Mon Sep 17 00:00:00 2001 From: AztecBot Date: Wed, 20 May 2026 15:27:51 +0000 Subject: [PATCH 1/2] test: flake-group e2e_slashing + e2e_expiration_timestamp race --- .test_patterns.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.test_patterns.yml b/.test_patterns.yml index e3743de0d2d1..da53062cea47 100644 --- a/.test_patterns.yml +++ b/.test_patterns.yml @@ -291,6 +291,11 @@ tests: owners: - *palla + - regex: "src/e2e_slashing/.*\\.test\\.ts" + flake_group_id: e2e-p2p-epoch-flakes + owners: + - *palla + - regex: "p2p/src/client/test/.*\\.test\\.ts" flake_group_id: e2e-p2p-epoch-flakes owners: @@ -373,6 +378,15 @@ tests: owners: - *martin + # http://ci.aztec-labs.com/97be94f0ae50ea78 + # Under proposer pipelining, the previous "invalidates the transaction" test warps L1 past the + # pipelined block's slot, triggering an archiver reorg. The next test's `getBlockData('latest')` + # races the prune and briefly returns undefined, surfacing as this thrown error at line 147. + - regex: "src/e2e_expiration_timestamp.test.ts" + error_regex: "Block header not found in invalidates-the-transaction setup" + owners: + - *palla + - regex: "yarn-project/scripts/run_test.sh bb-prover/src/avm_proving_tests/avm_" error_regex: "timeout: sending signal" owners: From 1142f6cfa4077a204aa8ca0d3cd330e663d28428 Mon Sep 17 00:00:00 2001 From: AztecBot Date: Wed, 20 May 2026 15:33:55 +0000 Subject: [PATCH 2/2] test(e2e): cache header in e2e_expiration_timestamp to avoid prune race The 'invalidates the transaction' tests warp L1 past the proposer-pipelined block's slot, which makes the archiver prune that block asynchronously. The next test's beforeEach + body each call aztecNode.getBlockData('latest'); the second call races the prune and resolves a block number that has been deleted by the time the row is read, returning undefined. Cache the header timestamp from beforeEach and reuse it in runInvalidatesTest instead of refetching mid-cycle. Drop the matching error_regex flake pattern added in the previous commit on this branch. --- .test_patterns.yml | 9 --------- .../src/e2e_expiration_timestamp.test.ts | 15 +++++++++------ 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/.test_patterns.yml b/.test_patterns.yml index da53062cea47..a5e08576ad88 100644 --- a/.test_patterns.yml +++ b/.test_patterns.yml @@ -378,15 +378,6 @@ tests: owners: - *martin - # http://ci.aztec-labs.com/97be94f0ae50ea78 - # Under proposer pipelining, the previous "invalidates the transaction" test warps L1 past the - # pipelined block's slot, triggering an archiver reorg. The next test's `getBlockData('latest')` - # races the prune and briefly returns undefined, surfacing as this thrown error at line 147. - - regex: "src/e2e_expiration_timestamp.test.ts" - error_regex: "Block header not found in invalidates-the-transaction setup" - owners: - - *palla - - regex: "yarn-project/scripts/run_test.sh bb-prover/src/avm_proving_tests/avm_" error_regex: "timeout: sending signal" owners: diff --git a/yarn-project/end-to-end/src/e2e_expiration_timestamp.test.ts b/yarn-project/end-to-end/src/e2e_expiration_timestamp.test.ts index 5d7cbefd9494..3a03d75b8dfc 100644 --- a/yarn-project/end-to-end/src/e2e_expiration_timestamp.test.ts +++ b/yarn-project/end-to-end/src/e2e_expiration_timestamp.test.ts @@ -90,16 +90,23 @@ describe('e2e_expiration_timestamp', () => { describe('when requesting expiration timestamp lower than the next block', () => { let expirationTimestamp: bigint; + let latestBlockTimestamp: bigint; beforeEach(async () => { + // The prior test's `cheatCodes.eth.warp` can invalidate a pipelined block (the proposer + // builds N+1 during slot N, but L1 jumped past slot N+1's deadline). The archiver then + // prunes that block asynchronously, opening a race where `getBlockData('latest')` + // resolves a block number that's deleted by the time the row is read. We cache the + // timestamp here so `runInvalidatesTest` doesn't need a second read mid-cycle. const header = (await aztecNode.getBlockData('latest'))?.header; if (!header) { throw new Error('Block header not found in the setup of e2e_expiration_timestamp.test.ts'); } + latestBlockTimestamp = header.globalVariables.timestamp; // 1n lower than two slots ahead. Under proposer pipelining the anchor block may already // have advanced one slot past the latest mined header, so the next slot to be mined is // typically two slots ahead; this expiration sits just below that slot's start. - expirationTimestamp = header.globalVariables.timestamp + aztecSlotDuration * 2n - 1n; + expirationTimestamp = latestBlockTimestamp + aztecSlotDuration * 2n - 1n; }); describe('with no enqueued public calls', () => { @@ -142,11 +149,7 @@ describe('e2e_expiration_timestamp', () => { // L1 time past the expiration. Submitting the proven tx must then be rejected by the node because // the next slot's timestamp (derived from L1 time) is greater than the tx expiration. async function runInvalidatesTest(enqueuePublicCall: boolean) { - const header = (await aztecNode.getBlockData('latest'))?.header; - if (!header) { - throw new Error('Block header not found in invalidates-the-transaction setup'); - } - const requestedExpiration = header.globalVariables.timestamp + aztecSlotDuration * 5n; + const requestedExpiration = latestBlockTimestamp + aztecSlotDuration * 5n; const provenTx = await proveInteraction( wallet,