Skip to content

Interop tx filter#7

Closed
opsuperchain wants to merge 17 commits intodevelopfrom
feature/interop-tx-filter
Closed

Interop tx filter#7
opsuperchain wants to merge 17 commits intodevelopfrom
feature/interop-tx-filter

Conversation

@opsuperchain
Copy link
Copy Markdown
Collaborator

No description provided.

opsuperchain and others added 7 commits November 25, 2025 04:51
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>
}

// NewChain creates a new Chain instance
func NewChain(ctx context.Context, logger log.Logger, m metrics.Metricer,
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be a chain ingester? I feel like it's weird calling this a chain

opsuperchain and others added 6 commits November 25, 2025 05:01
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)
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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/
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why change this?

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
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>
@opsuperchain
Copy link
Copy Markdown
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants