Skip to content

@subql/node-ethereum init fails on Polkadot Hub RPCs (earliest -> 0x0 -> null) #3012

@pasevin

Description

@pasevin

Summary

@subql/node-ethereum fails during init() on Polkadot Hub RPCs with:

Getting genesis block returned null from tag: earliest

This blocks indexer startup before indexing begins.

Why this happens

In subql-ethereum/packages/node/src/ethereum/api.ethereum.ts, init() calls getGenesisBlock(chainId).
For most chains, getGenesisBlock() uses this.client.getBlock('earliest').

With ethers v5, getBlock('earliest') is normalized to eth_getBlockByNumber('0x0', false).
On Polkadot Hub RPCs, 0x0 returns null, so SubQuery throws and exits.

Affected networks (verified)

  • Polkadot Hub mainnet (chainId: 420420419) — fails
  • Polkadot Hub testnet (chainId: 420420417) — fails

Not affected (verified)

  • Moonbeam (1284) — passes
  • Moonriver (1285) — passes
  • Moonbase Alpha (1287) — passes

Additional observed behavior on Polkadot Hub RPCs

  • eth_getBlockByNumber('earliest', false) returns non-null
  • eth_getBlockByNumber('0x0', false) returns null
  • ethers.getBlock('earliest') returns null (because it requests 0x0)

First existing substrate heights that return EVM block number 0x0:

  • Mainnet: 11405258
  • Testnet: 4367913

Minimal repro

import { providers } from 'ethers';

const p = new providers.JsonRpcProvider('https://services.polkadothub-rpc.com/mainnet');
await p.getNetwork();
const block = await p.getBlock('earliest');
console.log(block); // null

Equivalent SubQuery init check behavior:

const b = await provider.getBlock('earliest');
if (b === null) throw new Error('Getting genesis block returned null from tag: earliest');

Request

Could @subql/node-ethereum make genesis init robust for chains where 0x0 is not directly available via EVM RPC adapter (e.g. Polkadot Hub)?

Potential approaches:

  1. Avoid strict dependency on getBlock('earliest' -> 0x0) for startup validation.
  2. Add chain-specific non-zero genesis tag mapping (similar to existing BEVM Canary special-case).
  3. Fallback logic when 'earliest' resolves to null but the endpoint is otherwise healthy.

Thanks — happy to run additional tests if needed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions