diff --git a/.changeset/eth-getlogs-block-range.md b/.changeset/eth-getlogs-block-range.md new file mode 100644 index 0000000000..11d275f74c --- /dev/null +++ b/.changeset/eth-getlogs-block-range.md @@ -0,0 +1,5 @@ +--- +"ensindexer": minor +--- + +ENSIndexer now supports tuning Ponder's `eth_getLogs` block range per chain. Set `ETH_GET_LOGS_BLOCK_RANGE` to apply a default cap across all chains, or `ETH_GET_LOGS_BLOCK_RANGE_` to override it for a specific chain (use `0` to opt a chain out and let Ponder auto-determine its range). This makes it easy to work with RPC providers that require a smaller `eth_getLogs` window. Like RPC connection settings, these are performance-only knobs: changing them does not affect indexed data and does not trigger a re-index. diff --git a/apps/ensindexer/.env.local.example b/apps/ensindexer/.env.local.example index ebd79f777f..ce95548c85 100644 --- a/apps/ensindexer/.env.local.example +++ b/apps/ensindexer/.env.local.example @@ -109,6 +109,30 @@ # provided HTTP/HTTPS RPC. More details at: https://ponder.sh/docs/config/chains#rpc-endpoints # +# eth_getLogs block range configuration +# Optional. Caps the maximum block range Ponder uses for eth_getLogs requests. +# +# Ponder auto-determines a safe eth_getLogs block range per chain. Set these only when an RPC provider +# rejects Ponder's default range (for example, when it requires a smaller window). Each value is a +# non-negative integer (0 included): a positive value is the number of blocks per eth_getLogs request, +# and 0 disables the override so Ponder auto-determines the range. +# +# - ETH_GET_LOGS_BLOCK_RANGE sets a default applied to every chain. +# - ETH_GET_LOGS_BLOCK_RANGE_${chainId} overrides that default for a specific chain. +# - ETH_GET_LOGS_BLOCK_RANGE_${chainId}=0 disables the cap for that chain (ignoring the default), so +# Ponder auto-determines its range. ETH_GET_LOGS_BLOCK_RANGE=0 is equivalent to leaving it unset. +# +# Chains without an effective value continue to use Ponder's auto-determined range. +# More details at: https://ponder.sh/docs/config/chains#eth_getlogs-block-range +# +# Changing these values does not trigger a re-index (they are not part of Ponder's build id), the +# same as changing RPC_URL_${chainId}. +# +# Example (default 1000 for all chains, 500 for Base, disabled for mainnet): +# ETH_GET_LOGS_BLOCK_RANGE=1000 +# ETH_GET_LOGS_BLOCK_RANGE_8453=500 +# ETH_GET_LOGS_BLOCK_RANGE_1=0 + # === ENS Namespace: Mainnet === # Ethereum Mainnet # - required if the configured namespace is mainnet diff --git a/apps/ensindexer/src/config/config.schema.ts b/apps/ensindexer/src/config/config.schema.ts index a72fc1b3a5..b300982bb9 100644 --- a/apps/ensindexer/src/config/config.schema.ts +++ b/apps/ensindexer/src/config/config.schema.ts @@ -17,6 +17,10 @@ import type { ENSIndexerEnvironment } from "@/config/environment"; import { applyDefaults, EnvironmentDefaults } from "@/config/environment-defaults"; import { derive_indexedChainIds } from "./derived-params"; +import { + buildEthGetLogsBlockRangesFromEnv, + EthGetLogsBlockRangesSchema, +} from "./eth-get-logs-block-ranges"; import type { EnsIndexerConfig } from "./types"; import { invariant_globalBlockrange, @@ -89,6 +93,7 @@ const IsSubgraphCompatibleSchema = const ENSIndexerConfigSchema = z .object({ rpcConfigs: RpcConfigsSchema, + ethGetLogsBlockRanges: EthGetLogsBlockRangesSchema, namespace: ENSNamespaceSchema, plugins: PluginsSchema, @@ -163,14 +168,16 @@ export function buildConfigFromEnvironment(_env: ENSIndexerEnvironment): EnsInde // apply the partial defaults to the provided env const env = applyDefaults(_env, environmentDefaults); - // and use that to generate rpcConfigs + // and use that to build the per-chain rpcConfigs and eth_getLogs block ranges const namespace = ENSNamespaceSchema.parse(env.NAMESPACE); const rpcConfigs = buildRpcConfigsFromEnv(env, namespace); + const ethGetLogsBlockRanges = buildEthGetLogsBlockRangesFromEnv(env, namespace); // parse/validate with ENSIndexerConfigSchema return ENSIndexerConfigSchema.parse({ namespace: env.NAMESPACE, rpcConfigs, + ethGetLogsBlockRanges, plugins: env.PLUGINS, isSubgraphCompatible: env.SUBGRAPH_COMPAT, diff --git a/apps/ensindexer/src/config/config.test.ts b/apps/ensindexer/src/config/config.test.ts index 7bd1e3aff1..9990bc6fd8 100644 --- a/apps/ensindexer/src/config/config.test.ts +++ b/apps/ensindexer/src/config/config.test.ts @@ -299,6 +299,44 @@ describe("config (with base env)", () => { }); }); + describe(".ethGetLogsBlockRanges", () => { + it("defaults to an empty Map when no ETH_GET_LOGS_BLOCK_RANGE var is set", async () => { + const config = await getConfig(); + expect(config.ethGetLogsBlockRanges).toStrictEqual(new Map()); + }); + + it("includes a chain's configured eth_getLogs block range", async () => { + vi.stubEnv("ETH_GET_LOGS_BLOCK_RANGE_1", "1000"); + const config = await getConfig(); + expect(config.ethGetLogsBlockRanges).toStrictEqual(new Map([[1, 1000]])); + }); + + it("applies the global ETH_GET_LOGS_BLOCK_RANGE default to indexed chains", async () => { + vi.stubEnv("ETH_GET_LOGS_BLOCK_RANGE", "1000"); + const config = await getConfig(); + expect(Object.fromEntries(config.ethGetLogsBlockRanges)).toMatchObject({ "1": 1000 }); + }); + + it("lets a chain-specific override take precedence over the global default", async () => { + vi.stubEnv("ETH_GET_LOGS_BLOCK_RANGE", "1000"); + vi.stubEnv("ETH_GET_LOGS_BLOCK_RANGE_1", "500"); + const config = await getConfig(); + expect(Object.fromEntries(config.ethGetLogsBlockRanges)).toMatchObject({ "1": 500 }); + }); + + it("omits a chain disabled with 0 even when a global default is set", async () => { + vi.stubEnv("ETH_GET_LOGS_BLOCK_RANGE", "1000"); + vi.stubEnv("ETH_GET_LOGS_BLOCK_RANGE_1", "0"); + const config = await getConfig(); + expect(Object.fromEntries(config.ethGetLogsBlockRanges)).not.toHaveProperty("1"); + }); + + it("throws if a configured eth_getLogs block range is not a non-negative integer", async () => { + vi.stubEnv("ETH_GET_LOGS_BLOCK_RANGE_1", "abc"); + await expect(getConfig()).rejects.toThrow(/non-negative integer/i); + }); + }); + describe(".chains", () => { it("returns the chains if it is a valid object (one HTTP protocol URL)", async () => { vi.stubEnv("RPC_URL_1", VALID_RPC_URL); diff --git a/apps/ensindexer/src/config/environment.ts b/apps/ensindexer/src/config/environment.ts index a764c271c5..e8a0d61419 100644 --- a/apps/ensindexer/src/config/environment.ts +++ b/apps/ensindexer/src/config/environment.ts @@ -1,5 +1,19 @@ import type { EnsDbEnvironment, RpcEnvironment } from "@ensnode/ensnode-sdk/internal"; +/** + * Environment variables for `eth_getLogs` block range overrides. + * + * `ETH_GET_LOGS_BLOCK_RANGE` sets a default applied to every chain, and each + * `ETH_GET_LOGS_BLOCK_RANGE_${chainId}` overrides that default for a specific chain (a value of `0` + * disables the override for that chain, so Ponder auto-determines its range). These cap Ponder's + * auto-determined maximum `eth_getLogs` block range. + * @see https://ponder.sh/docs/config/chains#eth_getlogs-block-range + */ +export interface EthGetLogsBlockRangeEnvironment { + ETH_GET_LOGS_BLOCK_RANGE?: string; + [x: `ETH_GET_LOGS_BLOCK_RANGE_${number}`]: string | undefined; +} + /** * Represents the raw, unvalidated environment variables for the ENSIndexer application. * @@ -8,7 +22,8 @@ import type { EnsDbEnvironment, RpcEnvironment } from "@ensnode/ensnode-sdk/inte * mapped/parsed into a structured configuration object like `ENSIndexerConfig`. */ export type ENSIndexerEnvironment = EnsDbEnvironment & - RpcEnvironment & { + RpcEnvironment & + EthGetLogsBlockRangeEnvironment & { NAMESPACE?: string; PLUGINS?: string; SUBGRAPH_COMPAT?: string; diff --git a/apps/ensindexer/src/config/eth-get-logs-block-ranges.test.ts b/apps/ensindexer/src/config/eth-get-logs-block-ranges.test.ts new file mode 100644 index 0000000000..5c7bea8ee0 --- /dev/null +++ b/apps/ensindexer/src/config/eth-get-logs-block-ranges.test.ts @@ -0,0 +1,73 @@ +import { describe, expect, it } from "vitest"; + +import { + buildEthGetLogsBlockRangesFromEnv, + EthGetLogsBlockRangesSchema, +} from "./eth-get-logs-block-ranges"; + +describe("buildEthGetLogsBlockRangesFromEnv", () => { + it("returns an empty record when no ETH_GET_LOGS_BLOCK_RANGE or ETH_GET_LOGS_BLOCK_RANGE_ vars are set", () => { + expect(buildEthGetLogsBlockRangesFromEnv({}, "mainnet")).toStrictEqual({}); + }); + + it("collects ETH_GET_LOGS_BLOCK_RANGE_ for chains in the namespace", () => { + expect( + buildEthGetLogsBlockRangesFromEnv({ ETH_GET_LOGS_BLOCK_RANGE_1: "1000" }, "mainnet"), + ).toStrictEqual({ "1": "1000" }); + }); + + it("applies the global ETH_GET_LOGS_BLOCK_RANGE default to every chain in the namespace", () => { + expect( + buildEthGetLogsBlockRangesFromEnv({ ETH_GET_LOGS_BLOCK_RANGE: "1000" }, "mainnet"), + ).toMatchObject({ "1": "1000", "8453": "1000" }); + }); + + it("lets a chain-specific value override the global default", () => { + expect( + buildEthGetLogsBlockRangesFromEnv( + { ETH_GET_LOGS_BLOCK_RANGE: "1000", ETH_GET_LOGS_BLOCK_RANGE_8453: "500" }, + "mainnet", + ), + ).toMatchObject({ "1": "1000", "8453": "500" }); + }); + + it("lets a chain-specific 0 take precedence over the global default", () => { + expect( + buildEthGetLogsBlockRangesFromEnv( + { ETH_GET_LOGS_BLOCK_RANGE: "1000", ETH_GET_LOGS_BLOCK_RANGE_1: "0" }, + "mainnet", + ), + ).toMatchObject({ "1": "0", "8453": "1000" }); + }); + + it("ignores ETH_GET_LOGS_BLOCK_RANGE_ for chains outside the namespace", () => { + expect( + buildEthGetLogsBlockRangesFromEnv({ ETH_GET_LOGS_BLOCK_RANGE_999999: "1000" }, "mainnet"), + ).toStrictEqual({}); + }); +}); + +describe("EthGetLogsBlockRangesSchema", () => { + it("parses an empty record to an empty Map", () => { + expect(EthGetLogsBlockRangesSchema.parse({})).toStrictEqual(new Map()); + }); + + it("parses chain-id strings to numeric block ranges", () => { + expect(EthGetLogsBlockRangesSchema.parse({ "1": "1000", "8453": "500" })).toStrictEqual( + new Map([ + [1, 1000], + [8453, 500], + ]), + ); + }); + + it("treats 0 as a disable sentinel and omits that chain", () => { + expect(EthGetLogsBlockRangesSchema.parse({ "1": "0", "8453": "1000" })).toStrictEqual( + new Map([[8453, 1000]]), + ); + }); + + it.each(["abc", "-5", "1.5"])("rejects invalid block range %j", (value) => { + expect(() => EthGetLogsBlockRangesSchema.parse({ "1": value })).toThrow(); + }); +}); diff --git a/apps/ensindexer/src/config/eth-get-logs-block-ranges.ts b/apps/ensindexer/src/config/eth-get-logs-block-ranges.ts new file mode 100644 index 0000000000..2673ea6521 --- /dev/null +++ b/apps/ensindexer/src/config/eth-get-logs-block-ranges.ts @@ -0,0 +1,70 @@ +import type { ChainId, ChainIdString } from "enssdk"; +import { z } from "zod/v4"; + +import { type Datasource, type ENSNamespaceId, getENSNamespace } from "@ensnode/datasources"; +import { deserializeChainId, serializeChainId } from "@ensnode/ensnode-sdk"; +import { makeChainIdStringSchema } from "@ensnode/ensnode-sdk/internal"; + +import type { EthGetLogsBlockRangeEnvironment } from "@/config/environment"; + +/** + * Builds the raw, per-chain `eth_getLogs` block range overrides from the environment, scoped to the + * chain IDs that appear in the specified `namespace`. + * + * For each chain in the namespace, a chain-specific `ETH_GET_LOGS_BLOCK_RANGE_${chainId}` takes + * precedence over the global `ETH_GET_LOGS_BLOCK_RANGE` default (a chain-specific `0` wins over the + * default and, once validated, disables the override for that chain). Variables for chains outside + * the namespace are ignored (same behavior as `RPC_URL_*`). + * + * NOTE: returns raw (unvalidated) string values; validation and the `0` disable semantics are + * applied in {@link EthGetLogsBlockRangesSchema}. + */ +export function buildEthGetLogsBlockRangesFromEnv( + env: EthGetLogsBlockRangeEnvironment, + namespace: ENSNamespaceId, +): Record { + const defaultValue = env.ETH_GET_LOGS_BLOCK_RANGE || undefined; + + const chainsInNamespace = Object.entries(getENSNamespace(namespace)).map( + ([, datasource]) => (datasource as Datasource).chain, + ); + + const ethGetLogsBlockRanges: Record = {}; + + for (const chain of chainsInNamespace) { + // a chain-specific value (including "0" to disable) takes precedence over the global default + const value = (env[`ETH_GET_LOGS_BLOCK_RANGE_${chain.id}`] || undefined) ?? defaultValue; + if (value !== undefined) { + ethGetLogsBlockRanges[serializeChainId(chain.id)] = value; + } + } + + return ethGetLogsBlockRanges; +} + +const EthGetLogsBlockRangeValueSchema = z.coerce + .number({ error: "ETH_GET_LOGS_BLOCK_RANGE must be a non-negative integer." }) + .int({ error: "ETH_GET_LOGS_BLOCK_RANGE must be a non-negative integer." }) + .min(0, { error: "ETH_GET_LOGS_BLOCK_RANGE must be a non-negative integer." }); + +/** + * Parses the raw per-chain `eth_getLogs` block range overrides into a `Map`, + * dropping any chain configured with `0` (the disable sentinel) so Ponder auto-determines its range. + */ +export const EthGetLogsBlockRangesSchema = z + .record(makeChainIdStringSchema("ETH_GET_LOGS_BLOCK_RANGE"), EthGetLogsBlockRangeValueSchema, { + error: + "ETH_GET_LOGS_BLOCK_RANGE configuration must be an object mapping valid chain IDs to non-negative integers.", + }) + .transform((records) => { + const ethGetLogsBlockRanges = new Map(); + + for (const [chainIdString, blockRange] of Object.entries(records)) { + // 0 disables the override for a chain, so it is omitted (Ponder auto-determines the range) + if (blockRange > 0) { + ethGetLogsBlockRanges.set(deserializeChainId(chainIdString), blockRange); + } + } + + return ethGetLogsBlockRanges; + }); diff --git a/apps/ensindexer/src/config/serialize.ts b/apps/ensindexer/src/config/serialize.ts index 563970289e..7d3ea24126 100644 --- a/apps/ensindexer/src/config/serialize.ts +++ b/apps/ensindexer/src/config/serialize.ts @@ -30,6 +30,21 @@ function serializeRpcConfigs( return serializedRpcConfigs; } +/** + * Serialize eth_getLogs block ranges {@link ENSIndexerConfig.ethGetLogsBlockRanges}. + */ +function serializeEthGetLogsBlockRanges( + ethGetLogsBlockRanges: ENSIndexerConfig["ethGetLogsBlockRanges"], +): SerializedENSIndexerConfig["ethGetLogsBlockRanges"] { + const serializedEthGetLogsBlockRanges: SerializedENSIndexerConfig["ethGetLogsBlockRanges"] = {}; + + for (const [chainId, blockRange] of ethGetLogsBlockRanges.entries()) { + serializedEthGetLogsBlockRanges[serializeChainId(chainId)] = blockRange; + } + + return serializedEthGetLogsBlockRanges; +} + /** * Serialize redacted {@link ENSIndexerConfig} object. * @@ -51,5 +66,6 @@ export function serializeRedactedENSIndexerConfig( namespace: redactedConfig.namespace, plugins: redactedConfig.plugins, rpcConfigs: serializeRpcConfigs(redactedConfig.rpcConfigs), + ethGetLogsBlockRanges: serializeEthGetLogsBlockRanges(redactedConfig.ethGetLogsBlockRanges), } satisfies SerializedENSIndexerConfig; } diff --git a/apps/ensindexer/src/config/serialized-types.ts b/apps/ensindexer/src/config/serialized-types.ts index 167b4d572e..4f5d29deb3 100644 --- a/apps/ensindexer/src/config/serialized-types.ts +++ b/apps/ensindexer/src/config/serialized-types.ts @@ -26,7 +26,10 @@ export interface SerializedRpcConfig extends Omit { + extends Omit< + ENSIndexerConfig, + "ensRainbowUrl" | "indexedChainIds" | "rpcConfigs" | "ethGetLogsBlockRanges" | "plugins" + > { /** * Serialized representation of {@link ENSIndexerConfig.ensRainbowUrl}. */ @@ -47,6 +50,11 @@ export interface SerializedENSIndexerConfig */ rpcConfigs: Record; + /** + * Serialized representation of {@link ENSIndexerConfig.ethGetLogsBlockRanges}. + */ + ethGetLogsBlockRanges: Record; + /** * Serialized representation of {@link ENSIndexerConfig.plugins}. * diff --git a/apps/ensindexer/src/config/types.ts b/apps/ensindexer/src/config/types.ts index c41b68b951..571afa4ec0 100644 --- a/apps/ensindexer/src/config/types.ts +++ b/apps/ensindexer/src/config/types.ts @@ -6,6 +6,14 @@ import type { BlockNumberRange, PluginName } from "@ensnode/ensnode-sdk"; import { RpcConfig, type RpcConfigs } from "@ensnode/ensnode-sdk/internal"; import type { EnsRainbowClientLabelSet } from "@ensnode/ensrainbow-sdk"; +/** + * Effective per-chain cap on Ponder's maximum `eth_getLogs` block range (after resolving the global + * default and per-chain overrides), keyed by chain id. + * + * @invariant Each value is a positive integer. + */ +export type EthGetLogsBlockRanges = Map; + /** * The complete runtime configuration for an ENSIndexer instance. */ @@ -104,6 +112,31 @@ export interface EnsIndexerConfig { */ rpcConfigs: RpcConfigs; + /** + * Effective per-chain cap on Ponder's maximum `eth_getLogs` block range, keyed by chain id, after + * resolving environment configuration. + * + * Configured via environment variables: + * - `ETH_GET_LOGS_BLOCK_RANGE` sets a default applied to every chain. + * - `ETH_GET_LOGS_BLOCK_RANGE_` overrides that default for a specific chain. + * - `ETH_GET_LOGS_BLOCK_RANGE_=0` disables the cap for that chain (ignoring the default), + * so Ponder auto-determines its range. `ETH_GET_LOGS_BLOCK_RANGE=0` is equivalent to unset. + * + * Ponder auto-determines a safe `eth_getLogs` block range per chain; these overrides let operators + * set a manual cap for RPC providers that reject Ponder's default range. + * @see https://ponder.sh/docs/config/chains#eth_getlogs-block-range + * + * Like {@link rpcConfigs}, this is a performance/connection tuning knob only: it does NOT affect + * indexed data and is intentionally excluded from the indexing-behavior Build ID. Changing it does + * not trigger a re-index. + * + * Invariants: + * - Keys are a subset of the chains in the configured {@link namespace}. A chain is absent when it + * has no effective cap (unset, or disabled with `0`), in which case Ponder auto-determines its + * range. + */ + ethGetLogsBlockRanges: EthGetLogsBlockRanges; + /** * Indexed Chain IDs * diff --git a/apps/ensindexer/src/lib/ponder-helpers.test.ts b/apps/ensindexer/src/lib/ponder-helpers.test.ts index 11dd145292..65089b783f 100644 --- a/apps/ensindexer/src/lib/ponder-helpers.test.ts +++ b/apps/ensindexer/src/lib/ponder-helpers.test.ts @@ -1,8 +1,10 @@ +import type { ChainId } from "enssdk"; import { describe, expect, it } from "vitest"; +import type { RpcConfig } from "@ensnode/ensnode-sdk/internal"; import { buildBlockNumberRange } from "@ensnode/ponder-sdk"; -import { constrainBlockrange } from "./ponder-helpers"; +import { chainsConnectionConfig, constrainBlockrange } from "./ponder-helpers"; const UNDEFINED_BLOCKRANGE = buildBlockNumberRange(undefined, undefined); const BLOCKRANGE_WITH_END = buildBlockNumberRange(undefined, 1234); @@ -90,4 +92,29 @@ describe("ponder helpers", () => { }); }); }); + + describe("chainsConnectionConfig", () => { + const CHAIN_ID = 1 as ChainId; + const rpcConfigs = new Map([ + [CHAIN_ID, { httpRPCs: [new URL("https://rpc.example/1")], websocketRPC: undefined }], + ]); + + it("omits ethGetLogsBlockRange when the chain has no configured override", () => { + const chains = chainsConnectionConfig( + { rpcConfigs, ethGetLogsBlockRanges: new Map() }, + CHAIN_ID, + ); + + expect(chains[CHAIN_ID.toString()]).not.toHaveProperty("ethGetLogsBlockRange"); + }); + + it("includes ethGetLogsBlockRange when the chain has a configured override", () => { + const chains = chainsConnectionConfig( + { rpcConfigs, ethGetLogsBlockRanges: new Map([[CHAIN_ID, 1000]]) }, + CHAIN_ID, + ); + + expect(chains[CHAIN_ID.toString()]).toMatchObject({ ethGetLogsBlockRange: 1000 }); + }); + }); }); diff --git a/apps/ensindexer/src/lib/ponder-helpers.ts b/apps/ensindexer/src/lib/ponder-helpers.ts index 732a187bd1..4b367c82de 100644 --- a/apps/ensindexer/src/lib/ponder-helpers.ts +++ b/apps/ensindexer/src/lib/ponder-helpers.ts @@ -89,31 +89,35 @@ export const constrainBlockrange = ( /** * Builds a ponder#Config["chains"] for a single, specific chain in the context of the ENSIndexerConfig. * - * @param rpcConfigs - The RPC configuration object from ENSIndexerConfig, keyed by chain ID. + * @param config - The ENSIndexerConfig slice providing per-chain RPC configs and eth_getLogs block ranges. * @param chainId - The numeric chain ID for which to build the chain config. * @returns a ponder#Config["chains"] */ export function chainsConnectionConfig( - rpcConfigs: ENSIndexerConfig["rpcConfigs"], + config: Pick, chainId: ChainId, ) { - const rpcConfig = rpcConfigs.get(chainId); + const rpcConfig = config.rpcConfigs.get(chainId); if (!rpcConfig) { throw new Error( - `chainsConnectionConfig called for chain id ${chainId} but no associated rpcConfig is available. rpcConfig specifies the following chain ids: [${Object.keys(rpcConfigs).join(", ")}].`, + `chainsConnectionConfig called for chain id ${chainId} but no associated rpcConfig is available. rpcConfig specifies the following chain ids: [${[...config.rpcConfigs.keys()].join(", ")}].`, ); } // NOTE: disable cache on ens-test-env const disableCache = chainId === ensTestEnvChain.id; + const ethGetLogsBlockRange = config.ethGetLogsBlockRanges.get(chainId); + return { [chainId.toString()]: { id: chainId, rpc: rpcConfig.httpRPCs.map((httpRPC) => httpRPC.toString()), ws: rpcConfig.websocketRPC?.toString(), disableCache, + // only set when explicitly configured; otherwise Ponder auto-determines the range + ...(ethGetLogsBlockRange !== undefined ? { ethGetLogsBlockRange } : {}), } satisfies ChainConfig, }; } @@ -221,18 +225,17 @@ export function mergedChainConfigForContracts( * TODO */ export function chainsConnectionConfigForDatasources( - namespace: ENSNamespaceId, - rpcConfigs: ENSIndexerConfig["rpcConfigs"], + config: Pick, datasourceNames: DatasourceName[], ) { return datasourceNames - .map((datasourceName) => maybeGetDatasource(namespace, datasourceName)) + .map((datasourceName) => maybeGetDatasource(config.namespace, datasourceName)) .filter((ds) => !!ds) .map((datasource) => datasource.chain) .reduce>( (memo, chain) => ({ ...memo, - ...chainsConnectionConfig(rpcConfigs, chain.id), + ...chainsConnectionConfig(config, chain.id), }), {}, ); diff --git a/apps/ensindexer/src/plugins/protocol-acceleration/plugin.ts b/apps/ensindexer/src/plugins/protocol-acceleration/plugin.ts index 67291ce4d9..b8806aced2 100644 --- a/apps/ensindexer/src/plugins/protocol-acceleration/plugin.ts +++ b/apps/ensindexer/src/plugins/protocol-acceleration/plugin.ts @@ -75,11 +75,7 @@ export default createPlugin({ } = maybeGetDatasources(config.namespace, ALL_DATASOURCE_NAMES); return createConfig({ - chains: chainsConnectionConfigForDatasources( - config.namespace, - config.rpcConfigs, - ALL_DATASOURCE_NAMES, - ), + chains: chainsConnectionConfigForDatasources(config, ALL_DATASOURCE_NAMES), contracts: { ////////////////////// // Resolver Contracts diff --git a/apps/ensindexer/src/plugins/registrars/plugin.ts b/apps/ensindexer/src/plugins/registrars/plugin.ts index dde5173d19..c807dae61f 100644 --- a/apps/ensindexer/src/plugins/registrars/plugin.ts +++ b/apps/ensindexer/src/plugins/registrars/plugin.ts @@ -41,11 +41,7 @@ export default createPlugin({ } = getRequiredDatasources(config.namespace, REQUIRED_DATASOURCE_NAMES); return createConfig({ - chains: chainsConnectionConfigForDatasources( - config.namespace, - config.rpcConfigs, - REQUIRED_DATASOURCE_NAMES, - ), + chains: chainsConnectionConfigForDatasources(config, REQUIRED_DATASOURCE_NAMES), contracts: { ////////////////////// // Ethnames Registrar diff --git a/apps/ensindexer/src/plugins/subgraph/plugins/basenames/plugin.ts b/apps/ensindexer/src/plugins/subgraph/plugins/basenames/plugin.ts index 8d90744d30..e192af89e5 100644 --- a/apps/ensindexer/src/plugins/subgraph/plugins/basenames/plugin.ts +++ b/apps/ensindexer/src/plugins/subgraph/plugins/basenames/plugin.ts @@ -28,11 +28,7 @@ export default createPlugin({ } = getRequiredDatasources(config.namespace, REQUIRED_DATASOURCE_NAMES); return ponder.createConfig({ - chains: chainsConnectionConfigForDatasources( - config.namespace, - config.rpcConfigs, - REQUIRED_DATASOURCE_NAMES, - ), + chains: chainsConnectionConfigForDatasources(config, REQUIRED_DATASOURCE_NAMES), contracts: { [namespaceContract(pluginName, "Registry")]: { chain: chainConfigForContract(config.globalBlockrange, chain.id, contracts.Registry), diff --git a/apps/ensindexer/src/plugins/subgraph/plugins/lineanames/plugin.ts b/apps/ensindexer/src/plugins/subgraph/plugins/lineanames/plugin.ts index 59f39f93d1..57e8556e59 100644 --- a/apps/ensindexer/src/plugins/subgraph/plugins/lineanames/plugin.ts +++ b/apps/ensindexer/src/plugins/subgraph/plugins/lineanames/plugin.ts @@ -29,11 +29,7 @@ export default createPlugin({ } = getRequiredDatasources(config.namespace, REQUIRED_DATASOURCE_NAMES); return ponder.createConfig({ - chains: chainsConnectionConfigForDatasources( - config.namespace, - config.rpcConfigs, - REQUIRED_DATASOURCE_NAMES, - ), + chains: chainsConnectionConfigForDatasources(config, REQUIRED_DATASOURCE_NAMES), contracts: { [namespaceContract(pluginName, "Registry")]: { chain: chainConfigForContract(config.globalBlockrange, chain.id, contracts.Registry), diff --git a/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/plugin.ts b/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/plugin.ts index e0cb6eb84b..ffda6c0d1e 100644 --- a/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/plugin.ts +++ b/apps/ensindexer/src/plugins/subgraph/plugins/subgraph/plugin.ts @@ -31,11 +31,7 @@ export default createPlugin({ } = getRequiredDatasources(config.namespace, REQUIRED_DATASOURCE_NAMES); return ponder.createConfig({ - chains: chainsConnectionConfigForDatasources( - config.namespace, - config.rpcConfigs, - REQUIRED_DATASOURCE_NAMES, - ), + chains: chainsConnectionConfigForDatasources(config, REQUIRED_DATASOURCE_NAMES), contracts: { [namespaceContract(pluginName, "ENSv1RegistryOld")]: { chain: chainConfigForContract( diff --git a/apps/ensindexer/src/plugins/subgraph/plugins/threedns/plugin.ts b/apps/ensindexer/src/plugins/subgraph/plugins/threedns/plugin.ts index 725b3f174a..a15fc3e4c5 100644 --- a/apps/ensindexer/src/plugins/subgraph/plugins/threedns/plugin.ts +++ b/apps/ensindexer/src/plugins/subgraph/plugins/threedns/plugin.ts @@ -29,11 +29,7 @@ export default createPlugin({ } = getRequiredDatasources(config.namespace, REQUIRED_DATASOURCE_NAMES); return ponder.createConfig({ - chains: chainsConnectionConfigForDatasources( - config.namespace, - config.rpcConfigs, - REQUIRED_DATASOURCE_NAMES, - ), + chains: chainsConnectionConfigForDatasources(config, REQUIRED_DATASOURCE_NAMES), contracts: { // multi-chain ThreeDNSToken indexing config [namespaceContract(pluginName, "ThreeDNSToken")]: { diff --git a/apps/ensindexer/src/plugins/tokenscope/plugin.ts b/apps/ensindexer/src/plugins/tokenscope/plugin.ts index e844ca10e7..ac28131acd 100644 --- a/apps/ensindexer/src/plugins/tokenscope/plugin.ts +++ b/apps/ensindexer/src/plugins/tokenscope/plugin.ts @@ -55,12 +55,12 @@ export default createPlugin({ return ponder.createConfig({ chains: { - ...chainsConnectionConfig(config.rpcConfigs, seaport.chain.id), - ...chainsConnectionConfig(config.rpcConfigs, ensroot.chain.id), - ...chainsConnectionConfig(config.rpcConfigs, basenames.chain.id), - ...chainsConnectionConfig(config.rpcConfigs, lineanames.chain.id), - ...chainsConnectionConfig(config.rpcConfigs, threednsOptimism.chain.id), - ...chainsConnectionConfig(config.rpcConfigs, threednsBase.chain.id), + ...chainsConnectionConfig(config, seaport.chain.id), + ...chainsConnectionConfig(config, ensroot.chain.id), + ...chainsConnectionConfig(config, basenames.chain.id), + ...chainsConnectionConfig(config, lineanames.chain.id), + ...chainsConnectionConfig(config, threednsOptimism.chain.id), + ...chainsConnectionConfig(config, threednsBase.chain.id), }, contracts: { [namespaceContract(pluginName, "Seaport")]: { diff --git a/apps/ensindexer/src/plugins/unigraph/plugin.ts b/apps/ensindexer/src/plugins/unigraph/plugin.ts index 2f66ac865b..a92aaf37fc 100644 --- a/apps/ensindexer/src/plugins/unigraph/plugin.ts +++ b/apps/ensindexer/src/plugins/unigraph/plugin.ts @@ -57,11 +57,7 @@ export default createPlugin({ const DATASOURCES_WITH_ENSV2_CONTRACTS = getDatasourcesWithENSv2Contracts(config.namespace); return createConfig({ - chains: chainsConnectionConfigForDatasources( - config.namespace, - config.rpcConfigs, - ALL_DATASOURCE_NAMES, - ), + chains: chainsConnectionConfigForDatasources(config, ALL_DATASOURCE_NAMES), contracts: { //////////////////////////// diff --git a/docker/envs/.env.docker.example b/docker/envs/.env.docker.example index 4ee7174e47..9cb7984461 100644 --- a/docker/envs/.env.docker.example +++ b/docker/envs/.env.docker.example @@ -25,3 +25,6 @@ DB_SCHEMA_VERSION=3 # RPC_URL_42161= # RPC_URL_59144= # RPC_URL_534352= +# ETH_GET_LOGS_BLOCK_RANGE= +# ETH_GET_LOGS_BLOCK_RANGE_1= +# ETH_GET_LOGS_BLOCK_RANGE_8453=