Merged
Conversation
## Summary After a chain prune (reorg), `handlePrunedBlocks()` moves mined transactions back to pending, which can temporarily push the v2 pool over its configured size limit. The `EvictionManager` already dispatches a `CHAIN_PRUNED` event (via `evictAfterChainPrune()`), but `LowPriorityEvictionRule` only handled `TXS_ADDED` events — returning an empty result for `CHAIN_PRUNED` and leaving the pool over its limit until the next `addPendingTxs()` call. - Extended `LowPriorityEvictionRule.evict()` to also trigger on `CHAIN_PRUNED` events, so the pool size limit is enforced immediately after a reorg - Guarded `context.newTxHashes` access (only present on the `TXS_ADDED` variant of the discriminated union) with an event-type check, logging a distinct message for the chain-prune case - Added unit tests for `CHAIN_PRUNED` handling in `LowPriorityEvictionRule` (eviction when over limit, no-op when under limit, no-op when disabled, error handling) - Added integration tests in `tx_pool_v2.test.ts` exercising the full add → mine → set limit → prune → verify eviction flow ## Test plan - [x] Unit tests pass: `yarn workspace @aztec/p2p test src/mem_pools/tx_pool_v2/eviction/low_priority_eviction_rule.test.ts` (14 tests) - [x] Integration tests pass: `yarn workspace @aztec/p2p test src/mem_pools/tx_pool_v2/tx_pool_v2.test.ts -t 'handlePrunedBlocks'` (12 tests) - [x] Lint and format pass Fixes A-560
3 tasks
## Summary Wraps all `TxPoolV2Impl` handler methods in `this.#store.transactionAsync()` to ensure DB atomicity. Without this, a failure mid-way through a handler can leave LMDB in a partially updated state (e.g., some txs marked as mined but not others), breaking pool invariants on restart. `transactionAsync` accumulates writes in memory and flushes atomically at commit — it does not hold a real LMDB write lock during callback execution, so including eviction (with its world-state I/O) inside the transaction is safe. **Handlers wrapped:** - **`addPendingTxs`**: already had a transaction for the add loop; moved `evictAfterNewTxs` inside it - **`protectTxs`**: wraps the loop that reads from `#txsDB` and calls `#addTx` - **`handleMinedBlock`**: wraps markAsMined/clearIfMinedHigher loop and `evictAfterNewBlock` - **`handleFailedExecution`**: wraps the `#deleteTxsBatch` call - **`handleFinalizedBlock`**: wraps steps 2-5 (archive collection, batch delete, finalize soft-deletes, archive writes) - **`prepareForSlot`**: wraps entire body from `cleanupSlotDeleted` through `evictAfterNewTxs` - **`handlePrunedBlocks`**: wraps entire body from `markFromPrunedBlock` through `evictAfterChainPrune` No operation reordering, no API changes, no new types. ## Test plan - `yarn workspace @aztec/p2p test src/mem_pools/tx_pool_v2/tx_pool_v2.test.ts` passes - `yarn workspace @aztec/p2p test src/mem_pools/tx_pool_v2/eviction/` passes - `yarn workspace @aztec/p2p test src/mem_pools/tx_pool_v2/tx_pool_v2.compat.test.ts` passes - `yarn build` compiles Part of A-546
## Summary
- Replace the allowlist-based "strict" multicall3 validation with hash-only matching: the archiver now finds `propose` calls by rollup address + selector and verifies them against `attestationsHash` and `payloadDigest` from `CheckpointProposed` events
- Make expected hashes required throughout — drop backwards compatibility for older events without hashes
- Simplify `CalldataRetriever` constructor from a contract addresses object to just `rollupAddress`
- Remove the allowlist infrastructure: `ValidContractCall`, `computeValidContractCalls`, all non-propose selector constants, and unused ABI imports (`EmpireSlashingProposerAbi`, `GovernanceProposerAbi`, `SlashFactoryAbi`, `TallySlashingProposerAbi`)
- Update Spire Proposer to return all wrapped calls (not just exactly one), enabling hash matching across multi-call Spire transactions
- Fix the CLI debug tool (`retrieve-calldata.ts`) to extract hashes from `CheckpointProposed` event logs and pass them to the retriever
- Remove `l1Addresses` constructor parameter from `ArchiverL1Synchronizer` and `contractAddresses` from data retrieval functions
## Details
### Hash-only matching in `tryDecodeMulticall3`
Previously, the method first tried "strict" validation (all calls must be on an allowlist of known addresses and selectors), then fell back to "relaxed" hash matching. Now there's a single path: find all calls matching rollup address + `propose` selector, verify each candidate against expected hashes, return the uniquely verified one. If multiple candidates verify (identical data), the first is returned with a warning.
### Required expected hashes
`attestationsHash` and `payloadDigest` are now required (not optional) in:
- `CheckpointProposedArgs` type in `rollup.ts`
- All `CalldataRetriever` methods (`getCheckpointFromRollupTx`, `getCheckpointFromTx`, `tryDecodeMulticall3`, `tryDecodeDirectPropose`, `tryDecodeSpireProposer`, `tryDecodeAndVerifyPropose`)
Runtime guards in `getCheckpointProposedEvents` throw if either field is missing from the event log.
### Simplified constructor
`CalldataRetriever` now takes just `rollupAddress: EthAddress` instead of `{ rollupAddress, governanceProposerAddress, slashingProposerAddress, slashFactoryAddress? }`. This eliminates the need for `l1Addresses` in `ArchiverL1Synchronizer` and `contractAddresses` in data retrieval functions.
### Spire Proposer multi-call support
`getCallFromSpireProposer` renamed to `getCallsFromSpireProposer`, now returns all wrapped calls as an array. `tryDecodeSpireProposer` iterates each call and tries it through `tryDecodeMulticall3` or direct propose + hash verification, returning the first verified match.
### CLI debug tool
`retrieve-calldata.ts` now uses `decodeEventLog` from viem to extract `attestationsHash` and `payloadDigest` from the `CheckpointProposed` event log, passing real hashes instead of an empty object.
## Test plan
- All 55 calldata retriever unit tests pass (hash matching, multicall3, direct propose, Spire Proposer, trace fallback, integration)
- All 17 spire proposer unit tests pass (single/multi call, validation failures, array return type)
- Build, format, and lint pass cleanly
Fixes A-408
Stuff I don't want hanging over my head while I'm out. Potentially (read: recommended) portable to current devnet. * Comment about the protocol contracts `generate_data` script requested by @nchamo * Fix for Niall's issue with deployments that require authwitnesses: https://linear.app/aztec-labs/issue/F-302/authwits-are-not-being-forwarded-to-the-executionpayload-in * Update playground's devnet URL * Avoid reregistering accounts on every operation in `EmbeddedWallet`
This PR: - Splits AVM_MAX_PROCESSABLE_GAS (6M) from MAX_PROCESSABLE_GAS (6M+PUBLIC_TX_OVERHEAD) - Splits Public tx overhead and private tx overhead - Plugs in numbers from simulation metrics to tx overheads - Plugs in numbers from simulation metrics to side effects - TODO: Figure out contract class logs: we are having trouble measuring them.
## Summary - Trim attestations to the minimum required (2/3 + 1 of committee) before submitting to L1, saving calldata gas - The proposer's own attestation is always preserved (L1 reverts with `MissingProposerSignature` without it) - Attestations from the local node's validator keys are prioritized over external ones - No L1 contract changes needed — the existing packed format already handles positions without signatures by storing addresses instead (20 bytes vs 65 bytes per signature) ## Changes - `yarn-project/stdlib/src/p2p/attestation_utils.ts`: Added `trimAttestations()` utility that partitions attestations into proposer/local/external buckets and keeps only the minimum required, prioritizing proposer and local validators - `yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.ts`: Call `trimAttestations()` between `collectAttestations()` and `orderAttestations()` in `waitForAttestations()` - `yarn-project/stdlib/src/p2p/attestation_utils.test.ts`: New test file with 7 unit tests covering trimming behavior, priority ordering, edge cases - `yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.test.ts`: Added `getValidatorAddresses` mock - `yarn-project/sequencer-client/src/sequencer/checkpoint_proposal_job.timing.test.ts`: Added `getValidatorAddresses` mock ## Test plan - [x] `trimAttestations` unit tests (7/7 pass): no-op when under threshold, trims to required count, keeps proposer, prioritizes local, fills with external, no double-counting, handles bad signatures - [x] `checkpoint_proposal_job.test.ts` (26/26 pass) - [x] `checkpoint_proposal_job.timing.test.ts` (16/16 pass) - [x] `sequencer.test.ts` (22/22 pass) - [ ] E2E multi-validator tests (assertions use `>= quorum` so should be safe)
5 tasks
) ## Summary - Update `syncImmediate` calls in `FeePayerBalanceEvictionRule` and `InvalidTxsAfterReorgRule` to call without a block number during `CHAIN_PRUNED` events - `syncImmediate(blockNumber)` returns early when the world state is already at or past the target, skipping `blockStream.sync()` — calling without args ensures the prune event is always processed Note: despite the original issue description (A-545) suggesting that validations may produce incorrect results, the eviction rules were already correct. Both rules use `getSnapshot(blockNumber)` which serves historical data via the native content-addressed store's root hash, regardless of whether `unwindBlocks` has run. Additionally, `#revalidateMetadata` (step 5 in `handlePrunedBlocks`) already calls `syncImmediate()` without args through `createPoolTxValidator`, so the world state processes the prune before the eviction rules run. This change makes the eviction rules' intent explicit rather than relying on the earlier sync. Fixes A-545
…ec-packages into backport-to-v4-staging
Collaborator
Author
Flakey Tests🤖 says: This CI run detected 1 tests that failed, but were tolerated due to a .test_patterns.yml entry. |
aminsammara
approved these changes
Feb 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
BEGIN_COMMIT_OVERRIDE
feat: run low priority eviction rule on chain_pruned (#20687)
feat: adding mempool transactions (#20679)
feat: check calldata against emitted hashes (#20486)
fix: hodgepodge of small things (#20720)
feat: trim attestations to the minimum required length (#20591)
feat: call syncImmediate without block number during chain prune (#20717)
END_COMMIT_OVERRIDE