Conversation
## 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
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## 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)
) ## 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
fix scenario test
Collaborator
Author
|
🤖 Auto-merge enabled after 4 hours of inactivity. This PR will be merged automatically once all checks pass. |
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: check calldata against emitted hashes (#20486)
feat: trim attestations to the minimum required length (#20591)
feat: call syncImmediate without block number during chain prune (#20717)
chore(metrics): add L1 inclusion timing metrics to archiver (#20722)
fix: pxe native prover log level (#20724)
chore: fix worker wallet in jest (#20725)
fix: rpc deployment name used to restart gke pods (#20736)
END_COMMIT_OVERRIDE