Closed
Conversation
Add a new service that validates interop executing messages for op-geth transaction filtering. Uses LogsDB for storage with automatic reorg detection via parent hash validation. Key features: - Ingests blocks from configured L2 chains into LogsDB - Backfills configurable history on startup (default 24h) - Serves supervisor_checkAccessList RPC for op-geth validation - Automatic failsafe on reorg detection - Prometheus metrics for monitoring 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Change --backfill-hours to --backfill-duration to accept Go duration strings like "24h", "30m", "1h30m" for more flexible configuration. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Allow using chain names like "op-mainnet", "op-sepolia", "base-mainnet" instead of chain IDs. Names are resolved via the superchain registry. Examples: --l2-rpcs=op-mainnet:http://localhost:8545 --l2-rpcs=op-sepolia:http://localhost:8545,base-sepolia:http://base:8545 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Add required cache sizes to EthClientConfig (TransactionsCacheSize, PayloadsCacheSize, BlockRefsCacheSize, MaxConcurrentRequests) - Fix LogsDB initialization to use SealBlock for empty DB - Clear temp directory on startup to avoid stale data conflicts - Fix subscribeNewBlocks to start from backfilled head, not block 0 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Add a standalone CLI tool to validate the interop filter service by:
- Querying random logs from L2 chains
- Constructing valid checkAccessList queries (expects success)
- Constructing invalid queries with corrupted checksums (expects rejection)
- Exiting with error if any unexpected response
Usage:
./bin/filter-spammer \
--l2-rpc=<URL> \
--filter-rpc=http://localhost:8560 \
--chain-id=<ID> \
--num-queries=100 # 0 = run forever
--query-interval=500ms
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add Prometheus metrics to filter-spammer - queries_total (by type and result) - query_latency_seconds histogram - errors_total - up gauge - Add terminal dashboard (filter-dashboard) - Real-time ASCII dashboard polling Prometheus endpoints - Shows filter status, chain status, spammer stats - Correctness progress bar - Add run-overnight.sh script - Starts filter service with metrics - Starts spammer with metrics - Instructions for running dashboard Usage: ./op-interop-filter/scripts/run-overnight.sh # In another terminal: ./bin/filter-dashboard 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Add LogsDB-specific metrics to track database state: - logsdb_entries: total entries in LogsDB - logsdb_first_block: first block number in LogsDB - logsdb_blocks_sealed_total: counter for blocks sealed - logsdb_logs_added_total: counter for logs added Update dashboard to display LogsDB stats per chain. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
opsuperchain
commented
Nov 25, 2025
op-interop-filter/filter/chain.go
Outdated
| } | ||
|
|
||
| // NewChain creates a new Chain instance | ||
| func NewChain(ctx context.Context, logger log.Logger, m metrics.Metricer, |
Collaborator
Author
There was a problem hiding this comment.
This should probably be a chain ingester? I feel like it's weird calling this a chain
Add /recent endpoint to spammer that returns last 10 queries as JSON. Dashboard now displays the 5 most recent queries with: - Block number - Transaction hash (truncated for display) - Log index - Contract address - Query type (valid/invalid) - Result (accepted/rejected) This allows looking up queried logs via cast or block explorer. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Dashboard: display recent queries grouped by chain with Blockscout links - Dashboard: support multiple spammer endpoints (comma-separated) - Spammer: wait for filter backfill to complete before starting queries - Spammer: use eth.ChainID type properly for JSON serialization - Filter: improve backfill progress logging (every 10% or 10 seconds) - run-overnight.sh: remove hardcoded RPC URLs, use env vars from .env.dev - run-overnight.sh: reduce defaults to 5m backfill, 100 block range 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Address PR feedback: the struct manages block ingestion and LogsDB, so ChainIngester is a more accurate name than Chain. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Use types.ErrFailsafeEnabled instead of local error definition - Use types.ErrUninitialized for not-ready state (proper error code) - Reject unsupported safety levels (only "unsafe" is supported) - Propagate actual LogsDB errors instead of collapsing to ErrConflict - Fix test file to use ChainIngester type 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Add comprehensive README matching monorepo service style with: - Quickstart and usage instructions - Architecture diagram - Configuration flags - RPC interface documentation - Design decisions (why no op-conductor integration) - Failure modes documentation - Future improvements section (leader proxy, consensus proxy, etc.) Remove CLAUDE.md (internal development notes). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Match filename to struct name. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
| Pull requests: [monorepo](https://github.com/ethereum-optimism/optimism/pulls?q=is%3Aopen+is%3Apr+label%3AA-op-interop-filter) | ||
|
|
||
| Specs: | ||
| - [interop specs](https://github.com/ethereum-optimism/specs/tree/main/specs/interop) |
Owner
There was a problem hiding this comment.
we don't have specs, pls remove
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
| Specs: | ||
| - [interop specs](https://github.com/ethereum-optimism/specs/tree/main/specs/interop) | ||
|
|
||
| `op-interop-filter` is a lightweight service that validates interop executing messages for op-geth transaction filtering. It maintains a local LogsDB of recent blocks and serves `supervisor_checkAccessList` requests. |
Owner
There was a problem hiding this comment.
Just say op-geth and (soon) op-reth
|
|
||
| `op-interop-filter` is a lightweight service that validates interop executing messages for op-geth transaction filtering. It maintains a local LogsDB of recent blocks and serves `supervisor_checkAccessList` requests. | ||
|
|
||
| This is a simplified alternative to [op-supervisor] for deployments that only need transaction filtering without full cross-chain safety tracking. |
Owner
There was a problem hiding this comment.
Delete - I don't think we need to include this detail
Docker image support not yet available. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
|
|
||
| # ignore local asdf config | ||
| .tool-versions No newline at end of file | ||
| .tool-versionsbin/ |
Add docker-bake target and Dockerfile stages for op-interop-filter, following the same pattern as op-supernode and other services. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
|
|
||
| **Note:** Only `"unsafe"` safety level is currently supported. | ||
|
|
||
| ## Design Decisions |
Owner
There was a problem hiding this comment.
we can remove this section i think
Add missing build infrastructure: - justfile for building op-interop-filter binary - Makefile shim that calls just targets - Add op-interop-filter to root Makefile - Add op-interop-filter to Dockerfile.dockerignore allowlist 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Collaborator
Author
|
Closing: base branch targets upstream develop |
karlfloersch
pushed a commit
that referenced
this pull request
Mar 4, 2026
…16 (ethereum-optimism#19271) Add missing @param blueprint NatSpec to OpcmContractRef struct (#2). Add comments about pause blocking interop upgrades (#3). Document migrate() scope limitations and re-migration risks (#7, #15). Update PERMIT_ALL_CONTRACTS_INSTRUCTION comment (#12). Document intentional use of chainSystemConfigs[0] for shared contracts (#16). Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
karlfloersch
pushed a commit
that referenced
this pull request
Mar 17, 2026
* docs(staking): document pause bypass behavior in setAllowedStaker * fix(staking): only reset lastUpdate on full unstake in _decreasePeData Cantina audit finding #7: _decreasePeData unconditionally reset lastUpdate on every decrease, penalizing partial unstakers by resetting their staking weight. Now lastUpdate is only reset when effectiveStake reaches zero. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(staking): implement two-step ownership transfer Cantina audit finding #8: transferOwnership now nominates a pending owner who must call acceptOwnership() to finalize the transfer, preventing irrevocable ownership loss from incorrect addresses. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs(staking): document lastUpdate reset trust assumption in setAllowedStaker Cantina audit finding #10: when a beneficiary removes a staker from their allowlist, the staker's lastUpdate is reset via _increasePeData, losing accumulated staking weight. Document this as an inherent trust assumption of the delegation model. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: undo version change * chore: upgrade natspec * chore: update event emission order * fix: wrong event args * chore: add interface comments * fix: pre-pr * refactor: make ownable private functions public * fix: pre-pr * feat(ownable): reset pending owner on zeroaddress ownership transfer * refactor: inherit OZ's ownable and use helper contract for mapping storage slot * fix: ci --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
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.
No description provided.