Skip to content

fix: resolve a per-chain RPC URL on a fork - #2977

Open
apexearth wants to merge 1 commit into
masterfrom
fix/per-chain-fork-rpc
Open

fix: resolve a per-chain RPC URL on a fork#2977
apexearth wants to merge 1 commit into
masterfrom
fix/per-chain-fork-rpc

Conversation

@apexearth

Copy link
Copy Markdown
Contributor

rpcUrlFor() returns LOCAL_PROVIDER_URL for every chain whenever FORK=true, so a fork stack can only ever serve one chain. anvil serves a single chain id, so a Sonic or Base action pointed at a mainnet fork fails in initNetwork() — the provider is built for the action's real chain id while the node reports the fork's:

[otokenOsRebase] Running on sonic (146)
[otokenOsRebase] Error: underlying network changed
  (network={"chainId":146,"name":"unknown"},
   detectedNetwork={"name":"homestead","chainId":1}, code=NETWORK_ERROR)
-  if (process.env.FORK === "true" && process.env.LOCAL_PROVIDER_URL) {
-    url = process.env.LOCAL_PROVIDER_URL;
+  const forkUrl =
+    process.env.FORK === "true"
+      ? process.env[`LOCAL_PROVIDER_URL_${chainId}`] || process.env.LOCAL_PROVIDER_URL
+      : undefined;
+  if (forkUrl) {
+    url = forkUrl;

A per-chain LOCAL_PROVIDER_URL_<chainId> wins when set, falling back to the shared LOCAL_PROVIDER_URL.

Scenario chain 1 chain 146 chain 8453
Multi-chain fork anvil:8545 anvil-sonic:8545 anvil-base:8545
Single fork (back-compat) anvil:8545 anvil:8545 anvil:8545
No fork MAINNET_PROVIDER_URL SONIC_PROVIDER_URL BASE_PROVIDER_URL

Single-chain forks behave exactly as before, and the non-fork path is untouched.

Why now

oplabs/talos#30 runs one anvil per chain (mainnet, Base, Sonic) so actions on all three can be exercised locally against an impersonated relayer. Companion PR in this repo: #2976 (nonce-queue recording on the impersonated branch).

Not verified

No typecheck — the worktree has no node_modules. Resolution logic was checked against all three scenarios above by simulation, not by running the code.

rpcUrlFor() returned LOCAL_PROVIDER_URL for every chain whenever FORK=true, so
a fork stack could only ever serve one chain. anvil serves a single chain id,
so a Sonic or Base action pointed at a mainnet fork fails in initNetwork():
the provider is constructed for the action's real chain id while the node
reports the fork's, and ethers throws

  underlying network changed (network={chainId:146}, detected={chainId:1})

Now a per-chain LOCAL_PROVIDER_URL_<chainId> wins when set, falling back to
the shared LOCAL_PROVIDER_URL. Single-chain forks are unchanged, and the
non-fork path is untouched.

Surfaced by talos running one anvil per chain so mainnet, Base and Sonic
actions can all be exercised locally.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant