feat(contracts): index contract creations + /contracts/{recent,pioneers,stats}#61
Conversation
…rs,stats}
Phase 2 of explorer-indexer consolidation: indexer-rs now serves the contract
leaderboards the frontend expects, so it fully replaces the legacy indexer.
- Migration 0004: `contracts` table (address PK, first/last_seen_block,
code_hash NULL, tx_count, created_tx_hash) + indexes for recent/pioneers.
- Detection: a tx with `to_addr IS NULL` is a contract creation; the created
address is the CREATE address keccak(rlp(sender, nonce))[12:] (alloy), lower-
cased. Wired into both block-writer paths (single + batch).
- One-time history backfill on boot (no-op once populated) fills `contracts`
from existing creation txs — runs in the background so it never blocks sync.
- Routes `/contracts/recent` (newest), `/contracts/pioneers` (oldest),
`/contracts/stats` (sortable list, defaults newest). Shape
`{"contracts":[{rank,address,first_seen_block,last_seen_block,code_hash}]}`,
matching the frontend (`res?.contracts ?? []`, null code_hash → "—").
code_hash stays NULL for now (the UI already handles it); an eth_getCode pass
is a later enhancement.
Tests: CREATE-address known vector + bad-input; response shape; smoke fixture
contract + /contracts/{recent,pioneers,stats} asserts.
|
Caution Review failedPull request was closed or merged during review 📝 WalkthroughWalkthroughThis PR introduces contract leaderboards across the full stack. A new Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Why
Phase 2 of consolidating the testnet explorer onto a single indexer (indexer-rs). After #60 (stats/whale parity), the only remaining gap was the contract leaderboards — indexer-rs had no contract data at all. This adds it, so indexer-rs can fully replace the legacy indexer.
Changes
contractstable (address PK, first/last_seen_block, code_hash NULL, tx_count, created_tx_hash) + recent/pioneers indexes.to_addr IS NULLis a contract creation; the created address =keccak(rlp(sender, nonce))[12:](alloyAddress::create), lowercased. Wired into both block-writer paths (single + batch).contractsfrom existing creation txs (no-op once populated, so cheap on every restart)./contracts/recent(newest),/contracts/pioneers(oldest),/contracts/stats(sortable, defaults newest). Shape{"contracts":[{rank,address,first_seen_block,last_seen_block,code_hash}]}— matches the frontend (res?.contracts ?? []; nullcode_hashrenders "—").code_hashstays NULL for now (UI handles it); aneth_getCodepass is a later enhancement.Tests
block_writer).routes/contracts)./contracts/{recent,pioneers,stats}asserts (incl null code_hash).Note
cargo-deny red is pre-existing (RUSTSEC-2026-0173
proc-macro-error2, repo-wide, unrelated).Summary by CodeRabbit
/contracts/recent,/contracts/pioneers, and/contracts/statsfor contract ranking queries