feat(ensindexer): per-chain end blocks via END_BLOCK_<chainId>#2176
feat(ensindexer): per-chain end blocks via END_BLOCK_<chainId>#2176shrugs wants to merge 1 commit into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
🦋 Changeset detectedLatest commit: 7aa4410 The changes in this PR will be included in the next version bump. This PR includes changesets to release 22 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (24)
✨ Finishing Touches🧪 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 |
There was a problem hiding this comment.
Pull request overview
Adds support to ENSIndexer for per-chain indexing end blocks via END_BLOCK_<chainId> environment variables, enabling deterministic multi-chain checkpointing by constraining each chain independently (layered on top of the existing global START_BLOCK/END_BLOCK behavior).
Changes:
- Introduces
config.chainEndBlocks: Map<ChainId, number>parsed fromEND_BLOCK_<chainId>env vars, validated via a newinvariant_chainEndBlocks. - Adds
blockrangeForChain()and threadschainEndBlocksthroughchainConfigForContract()/mergedChainConfigForContracts()so plugin contract configs respect per-chain end blocks. - Updates plugins and tests to use the per-chain effective blockrange where needed (including Resolver configs built via
constrainBlockrange(...)).
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| apps/ensindexer/src/plugins/unigraph/plugin.ts | Passes chainEndBlocks into chain config helpers and applies per-chain blockrange when constraining Resolver ranges. |
| apps/ensindexer/src/plugins/tokenscope/plugin.ts | Passes chainEndBlocks into chainConfigForContract for all configured contracts/chains. |
| apps/ensindexer/src/plugins/subgraph/plugins/threedns/plugin.ts | Threads chainEndBlocks into chain config helper calls for 3DNS contracts on multiple chains. |
| apps/ensindexer/src/plugins/subgraph/plugins/subgraph/plugin.ts | Updates subgraph plugin contract configs to respect per-chain end blocks. |
| apps/ensindexer/src/plugins/subgraph/plugins/lineanames/plugin.ts | Updates lineanames subgraph plugin configs to include per-chain end blocks. |
| apps/ensindexer/src/plugins/subgraph/plugins/basenames/plugin.ts | Updates basenames subgraph plugin configs to include per-chain end blocks. |
| apps/ensindexer/src/plugins/registrars/plugin.ts | Threads chainEndBlocks into registrar-related contract config helpers, including merged registrar controller config. |
| apps/ensindexer/src/plugins/protocol-acceleration/plugin.ts | Passes chainEndBlocks into chain config helpers and applies per-chain blockrange to Resolver constraints. |
| apps/ensindexer/src/lib/ponder-helpers.ts | Adds blockrangeForChain() and layers per-chain end blocks into chainConfigForContract and mergedChainConfigForContracts. |
| apps/ensindexer/src/lib/ponder-helpers.test.ts | Adds focused unit tests for blockrangeForChain(). |
| apps/ensindexer/src/config/validations.ts | Adds invariant_chainEndBlocks to ensure each END_BLOCK_<chainId> corresponds to an indexed chain. |
| apps/ensindexer/src/config/types.ts | Extends EnsIndexerConfig with chainEndBlocks and documents its semantics/invariants. |
| apps/ensindexer/src/config/serialized-types.ts | Excludes chainEndBlocks from the serialized config type (since it’s a Map). |
| apps/ensindexer/src/config/environment.ts | Extends the environment type to allow END_BLOCK_<number> keys. |
| apps/ensindexer/src/config/config.test.ts | Adds config parsing/validation tests for END_BLOCK_<chainId> (multi-chain allowed, non-indexed chain rejected, negative/non-numeric rejected). |
| apps/ensindexer/src/config/config.schema.ts | Implements buildChainEndBlocksFromEnv, adds schema support for chainEndBlocks, and wires in the new invariant. |
| .changeset/ensindexer-per-chain-end-blocks.md | Changeset describing the new per-chain end block feature and semantics. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const endBlock = Number(value); | ||
| if (!Number.isInteger(endBlock) || endBlock < 0) { | ||
| throw new Error(`${key} must be a non-negative integer.`); | ||
| } | ||
|
|
||
| chainEndBlocks.set(Number(match[1]), endBlock); |
Greptile SummaryThis PR replaces the single-global
Confidence Score: 5/5Safe to merge — per-chain end-block logic is consistently applied across all plugins and the new invariant correctly guards against misconfigured chain IDs. The replacement of globalBlockrange with chainEndBlocks is mechanically consistent across all plugins. Core validation, parsing, range resolution, and Ponder build-ID serialization are all correct. Tests cover the main paths. The two suggestions are usability polish, not correctness issues. apps/ensindexer/src/config/serialized-types.ts omits chainEndBlocks with no replacement, leaving per-chain end-block state invisible in the serialized config output. Important Files Changed
Reviews (2): Last reviewed commit: "feat(ensindexer): per-chain end blocks v..." | Re-trigger Greptile |
| export interface SerializedENSIndexerConfig | ||
| extends Omit<ENSIndexerConfig, "ensRainbowUrl" | "indexedChainIds" | "rpcConfigs" | "plugins"> { | ||
| extends Omit< | ||
| ENSIndexerConfig, | ||
| "ensRainbowUrl" | "indexedChainIds" | "rpcConfigs" | "plugins" | "chainEndBlocks" | ||
| > { |
There was a problem hiding this comment.
chainEndBlocks is omitted from SerializedENSIndexerConfig with no replacement property. Every other Map-typed field that's omitted gets a serialized counterpart (indexedChainIds → ChainId[], rpcConfigs → Record<ChainIdString, SerializedRpcConfig>). Without a replacement, the active per-chain end-block configuration becomes invisible in whatever endpoint or log surfaces the serialized config, making it hard to confirm or debug which END_BLOCK_<chainId> values are in effect.
Replace the global START_BLOCK/END_BLOCK indexing-range config with per-chain end blocks via END_BLOCK_<chainId> env vars (mirroring RPC_URL_<chainId>), parsed into config.chainEndBlocks. Each constrains its chain's indexing end block independently and may be set across any number of indexed chains. blockrangeForChain() resolves the per-chain range; buildIndexedBlockranges (@ensnode/ensnode-sdk) now takes a per-chain end-block map so indexing-status reaches omnichain-completed for bounded multichain runs. Enables deterministic, reproducible multichain checkpoints. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
6966b41 to
7aa4410
Compare
Add
END_BLOCK_<chainId>env vars (mirroringRPC_URL_<chainId>) parsed intoconfig.chainEndBlocks: Map<ChainId, number>. Each constrains its chain's indexing end block independently, layered on top of the global blockrange (lower end wins), resolved per chain viablockrangeForChain()in ponder-helpers.Unlike the global START_BLOCK/END_BLOCK — still restricted to single-chain indexing by
invariant_globalBlockrange— per-chain end blocks MAY be set across multiple indexed chains (newinvariant_chainEndBlocksonly checks each chain is indexed). This enables deterministic, reproducible multichain checkpoints where every chain stops at a block corresponding to a shared timestamp.