feat(contracts): detect contracts via addresses registry + eth_getCode#63
Conversation
Replaces the to_addr-NULL creation heuristic (wrong for Sentrix, which records to_addr = the created contract address, so zero rows ever matched) with an addresses table classified by a lazy eth_getCode detector, mirroring the legacy indexer. /contracts/* now serves addresses WHERE is_contract = true ORDER BY first_seen_block.
- chain: ChainProvider::get_code (eth_getCode)
- db: migration 0005_addresses + addresses module (upsert_batch/unclassified_batch/classify/list_contracts/backfill)
- sync: block writer registers from/to addresses; contract_detect worker classifies unclassified rows rate-limited
- indexer: spawn detector + one-time address-history backfill; INDEXER_CONTRACT_DETECT_{INTERVAL_SECS,BATCH}
- api: /contracts/* reads the addresses table; removes the dead contracts module (0004 table left in place, append-only)
|
Caution Review failedPull request was closed or merged during review 📝 WalkthroughWalkthroughThis PR introduces a lazy contract detection architecture to replace eager contract identification via transaction analysis. A new Sequence DiagramsequenceDiagram
participant Sync as Block Sync
participant BW as Block Writer
participant DB as Addresses Registry
participant Detector as Contract Detector
participant Provider as ChainProvider
Sync->>BW: write_block(transactions)
BW->>BW: Extract from/to addresses
BW->>DB: upsert_batch(addresses, block)
loop On detector interval
Detector->>DB: unclassified_batch(limit)
DB-->>Detector: [address1, address2, ...]
loop For each unclassified address
Detector->>Provider: get_code(address)
Provider-->>Detector: code_bytes
Detector->>Detector: Compute keccak256 hash
Detector->>DB: classify(address, is_contract, code_hash)
end
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 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 |
What
Replaces the
to_addr IS NULLcontract-creation heuristic with anaddressesregistry classified by a lazyeth_getCodedetector — mirroring the legacy indexer./contracts/*now servesaddresses WHERE is_contract = true ORDER BY first_seen_block.Why
The shipped to_addr-NULL detection populated nothing on this chain: contract-creation txs are recorded with
to_addr = the created contract address, not NULL (SELECT count(*) FROM transactions WHERE to_addr IS NULL= 0). The correct model is an address registry with anis_contractflag set by probingeth_getCode.Changes
ChainProvider::get_code(eth_getCode)0005_addresses+addressesmodule (upsert_batch / unclassified_batch / classify / list_contracts / backfill_from_transactions)contract_detectworker classifies unclassified rows, rate-limited (INDEXER_CONTRACT_DETECT_INTERVAL_SECS=4,INDEXER_CONTRACT_DETECT_BATCH=10)/contracts/*readsaddresses; removes the now-deadcontractsdb module (migration 0004 table left in place — migrations are append-only)/contracts/*returns only the contract (is_contract filter)Notes
/contracts/*fills over time after deploy — bump the rate envs for a faster initial catch-up.Summary by CodeRabbit
New Features
Refactor