ethereum-lists / ethereum-lists/chains

20 listed RPC endpoints answer eth_chainId with a different chain ID, including two testnet entries served by mainnet endpoints

Open
#8,635 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Kotlin
Stars
9.8k
Forks
8.1k
Avg merge
1d 6h
Merged PRs (30d)
83

Description

## Summary

Twenty RPC endpoints, across eighteen chain entries, answer `eth_chainId` with a different chain ID than the entry that lists them.

Two of these are worth separating from the rest, because a wallet that adds the network from this registry and trusts the listed endpoint would be transacting on a different chain than the one it believes it is on:

- **chainId 159, Roburna Testnet** lists `https://preseed-testnet-1.roburna.com`, which answers **1**. That is Ethereum mainnet.
- **chainId 100010, VeChain Testnet** lists `https://rpc-testnet.vechain.energy`, which answers **100009**, the VeChain mainnet entry in this registry.

A testnet entry pointing at a mainnet endpoint is the one case here with a plausible route to real financial loss, so I have led with it rather than burying it in the table.

## Method, and what is deliberately excluded

I took every `rpc` entry in `chains.json` that is an `http(s)` URL and contains no placeholder token such as `${INFURA_API_KEY}`. That is 3,451 endpoints across 2,717 chains. Each was sent a plain `eth_chainId` call with an eight second timeout.

- 1,366 endpoints answered.
- 2,085 were unreachable, timed out, or returned a non-JSON-RPC response.
- Of the 1,366 that answered, **20 answered with the wrong chain ID**.

**Unreachable endpoints are not reported here and are not a defect.** A dead endpoint is ordinary decay and could be a transient network condition on my side. Only a live endpoint that positively asserts a different chain ID is a registry error, because in that case the registry and the endpoint disagree about a fact that the endpoint is authoritative on.

All twenty were re-checked twice on separate requests and returned the same value both times.

## The full list

| listed chainId | listed name | endpoint | answers | that ID is registered as |
|---|---|---|---|---|
| 159 | Roburna Testnet | `https://preseed-testnet-1.roburna.com` | **1** | Ethereum Mainnet |
| 160 | Armonia Eva Chain Mainnet | `https://evascan.io/api/eth-rpc/` | **2248** | not in this registry |
| 161 | Armonia Eva Chain Testnet | `https://testnet.evascan.io/api/eth-rpc/` | **12248** | not in this registry |
| 261 | Guru Network Testnet | `https://rpc-test.gurunetwork.ai` | **263** | not in this registry |
| 786 | MAAL Chain | `https://node1-mainnet.maalscan.io/` | **7862** | MaalChain V2 |
| 786 | MAAL Chain | `https://node2-mainnet.maalscan.io/` | **7862** | MaalChain V2 |
| 786 | MAAL Chain | `https://node3-mainnet.maalscan.io/` | **7862** | MaalChain V2 |
| 938 | Haust Mainnet | `https://haust-network-rpc.eu-north-2.gateway.fm` | **3864** | not in this registry |
| 1075 | IOTA EVM Testnet | `https://json-rpc.evm.testnet.iotaledger.net` | **1076** | not in this registry |
| 2340 | Atleta Olympia | `https://public-atleta.nownodes.io` | **2440** | Atleta Network |
| 3889 | KalyChain Testnet | `https://testnetrpc.kalychain.io/rpc` | **3890** | not in this registry |
| 42429 | Tempo Testnet Andantino (Deprecated) | `https://rpc.testnet.tempo.xyz` | **42431** | Tempo Testnet Moderato |
| 100010 | VeChain Testnet | `https://rpc-testnet.vechain.energy` | **100009** | VeChain |
| 224400 | CONET Mainnet | `https://mainnet-rpc.conet.network` | **224422** | CONET Sebolia Testnet |
| 224433 | CONET Cancun | `https://rpc.conet.network` | **224422** | CONET Sebolia Testnet |
| 1440002 | XRPL EVM Sidechain Devnet | `https://rpc.devnet.xrplevm.org` | **1449900** | not in this registry |
| 20230825 | Vcity Testnet | `http://testnet-rpc.vcity.app` | **20230826** | not in this registry |
| 1722641160 | Silicon zkEVM Sepolia Testnet | `https://silicon-testnet.nodeinfra.com` | **1414** | Silicon zkEVM Sepolia Testnet(Deprecated) |
| 2478899481 | Accumulate Kermit | `https://kermit.accumulatenetwork.io/eth` | **317849881** | not in this registry |
| 44474237230 | Deriw Devnet | `https://rpc.dev.deriw.com` | **18417507517** | not in this registry |

## Patterns in the list

Several of these look like a chain that migrated and left the old entry behind. All three `MAAL Chain` (786) endpoints answer 7862, which this registry already knows as `MaalChain V2`. `Silicon zkEVM Sepolia Testnet` (1722641160) answers 1414, which is its own deprecated entry. `Atleta Olympia` (2340) answers 2440, `Atleta Network`.

Two `CONET` entries, mainnet (224400) and Cancun (224433), both answer 224422, which is `CONET Sebolia Testnet`. A mainnet entry served by a testnet endpoint is the mirror of the Roburna and VeChain cases.

The remainder answer IDs that are not in this registry at all, which suggests the endpoint moved to a chain that was never filed.

## Reproduce

```bash
curl -s -X POST -H 'content-type: application/json' \
--data '{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}' \
https://preseed-testnet-1.roburna.com
# {"jsonrpc":"2.0","id":1,"result":"0x1"} <- Ethereum mainnet, listed under chainId 159

curl -s -X POST -H 'content-type: application/json' \
--data '{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}' \
https://rpc-testnet.vechain.energy
# 0x186a9 = 100009, listed under chainId 100010
```

## Suggestion

`validate_json.yml` checks structure, and as far as I can see nothing asks an endpoint what chain it thinks it is on. A check that calls `eth_chainId` on each listed RPC for any added or modified chain file, and fails only on a positive mismatch while tolerating unreachable endpoints, would catch this class at PR time without making CI flaky.

I am happy to open that PR rather than only filing this, if you would find it useful. I would also be glad to re-run the full sweep periodically and report deltas.

## Context

Found while building an open cross-chain contract control census, which uses this registry to resolve CAIP-2 identifiers: https://github.com/fabio-rovai/chain-control-ontology

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with validate_json.yml and the chains.json RPC entries, then reproduce the reported cases with the provided curl commands. Define the validation boundary around added or modified chain files and verify that positive eth_chainId mismatches fail while unreachable or non-JSON-RPC endpoints are tolerated. Done means the check catches the listed mismatch class without making CI flaky.

Written by the indexing model from the issue text.

Assessment

Tech stack
github-actions
Domain
backend-api-design, ci-cd
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
64/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.