Skip to content

Show Ethereum's in-use beacons alongside Base's - #118

Merged
thedavidmeister merged 3 commits into
masterfrom
ethereum-in-use-beacons
Jul 22, 2026
Merged

Show Ethereum's in-use beacons alongside Base's#118
thedavidmeister merged 3 commits into
masterfrom
ethereum-in-use-beacons

Conversation

@thedavidmeister

Copy link
Copy Markdown
Contributor

The deployments dashboard showed Base's beacons and nothing else. Ethereum carries its own production deployment — different addresses, different Safe, a different beacon generation — and none of it was visible.

This mirrors what S01-Issuer/st0x.deploy#266 establishes on the contract side: the beacons that matter are the ones a chain's production tokens actually RUN ON, and that set is per-chain.

The chain travels with the session

roh-scan was Base-only end to end — curl_json iterated a hardcoded BASE_RPCS, and every eth_call inherited it. A second chain cannot be bolted onto that safely, because an address that exists on one chain and not the other, asked of the wrong endpoint set, answers "no code here". That is a silent downgrade to not deployed, not an error — precisely the failure a second chain invites, and it would look identical to a real outage.

So rpc_session() now takes a Chain and returns a Session { chain, cursor }. Every read carries its chain with it; there is no way to reach an endpoint the caller did not choose. Call sites are unchanged beyond the session construction.

Ethereum's in-use set

Ethereum bootstrapped at 0.1.1, so that generation IS its production set (Base kept its V1-generation beacon addresses through every implementation upgrade). Only the wrapped-token-vault beacon has a generated address pin — the receipt and receipt-vault beacons are created inside the 0.1.1 beacon-set deployer's constructor and exist nowhere as a constant, so they are resolved live from iReceiptBeacon() / iOffchainAssetReceiptVaultBeacon(). Expected owner is STOX_TOKEN_OWNER_SAFE_ETHEREUM, which I confirmed live: all three Ethereum beacons are held by 0x3840aeDa….

There is no previous generation to fall back to on Ethereum, so an implementation that is not the 0.1.1 target is reported as unrecognised rather than as "behind".

Shape

deploymentBeacons becomes one block per chain. A merged table would put rows from two chains side by side with nothing distinguishing them; a chain whose read failed is dropped rather than emitted as null, so the dashboard never renders an empty section that reads as "this chain has no beacons".

renderBeacons accepts either an array or a single block, so it keeps working against a health.json written before this change.

Verification

cargo build clean, 177 rust tests pass, cargo fmt --check + clippy -D clippy::all clean.

The scanner was Base-only end to end: one hardcoded endpoint set, one beacon
block. Ethereum carries its own production deployment at different addresses,
owned by a different Safe, so none of it was visible on the dashboard.

The chain now travels with the RPC session rather than being implied by the
caller. An address that exists on one chain and not the other, answered by
the wrong endpoint set, reads as "not deployed" — a silent downgrade rather
than an error, which is exactly the failure a second chain invites.

Ethereum's in-use beacons are the 0.1.1 generation. Only the wrapped-token
vault beacon has a generated address pin; the other two are created inside
the 0.1.1 beacon-set deployer's constructor and exist nowhere as a constant,
so they are resolved live from its getters.

deploymentBeacons becomes one block per chain, and a chain whose read failed
is dropped rather than emitted as null.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@thedavidmeister thedavidmeister self-assigned this Jul 22, 2026
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@thedavidmeister, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 42 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 76e77b94-dd16-45ad-8796-92e13d10d858

📥 Commits

Reviewing files that changed from the base of the PR and between b100fcb and 48850b5.

📒 Files selected for processing (5)
  • plugins/rain-org-health-check/roh-scan/src/deployhealth.rs
  • plugins/rain-org-health-check/roh-scan/src/main.rs
  • plugins/rain-org-health-check/roh-scan/src/rpc.rs
  • site/deployments.html
  • test/dashboard.test.js
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ethereum-in-use-beacons

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

A chain whose beacon read failed was filtered out of the list, which renders
as no section at all — indistinguishable from "this chain has no production
beacons". That is the same silent vanish that hid the token registry, so the
chain now keeps its identity and the dashboard states the reason.

The Ethereum endpoint set is cut to the four verified live against the 0.1.1
beacon-set deployer: each answers the getters with the addresses the Solidity
lib resolves. The two dropped endpoints answered 521 and 429, and an endpoint
that cannot answer fails the whole chain's read.

The getter selectors are pinned against their signatures. A wrong selector
reverts on-chain, which the scan reports as an unreadable beacon rather than
as a bad selector, so nothing else would catch it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@thedavidmeister

Copy link
Copy Markdown
Contributor Author

Renders

Before — today's prod. BEACONS — BASE runs straight into TOKENS — BASE; Ethereum appears nowhere.

before

After — both chains. Ethereum's three beacons, all SAFE / 0.1.1 / HEALTHY, owner 0x3840aeDaEc82f79d8F6a8F6ADCa271E13E0329.

after

Ethereum unreadable. The failure mode that matters: the chain keeps its heading and states the reason instead of the section disappearing. A dropped chain reads as "Ethereum has no production beacons" — the same silent vanish #117 just fixed for tokens, which my first version of this PR reintroduced.

unavailable

Full pages: before · after · unavailable

How these were produced

The Base half and everything outside the beacon sections is a real scan (site/health.json at scanned 2026-07-22 19:03 UTC). The Ethereum block was assembled from live on-chain reads rather than a full scan run, because a whole-org scan takes long enough that it would have delayed this well past useful. Every value in it is a read, not an invention:

field source
beacon addresses iReceiptBeacon() / iOffchainAssetReceiptVaultBeacon() on 0xd64246e6…, plus the generated wrapped-beacon pin
owners owner() on each — all three return 0x3840aeDa…
implementations implementation() on each — 0x2df5cfe6…, 0x2bcced62…, 0x0d99e017…

All four endpoints in ETHEREUM_RPCS return identical answers for the getters, and those answers match what LibProdBeaconsEthereum.beacons() resolves in Solidity. A post-merge scan will confirm the same block end to end.

Unrelated but visible now that #117 is live: wtASML is a MISMATCH — on-chain "Wrapped ASML Holding N.V. ST0x" vs registry "Wrapped ASML Holding N.V. New York Registry Shares ST0x", part of "17 of 21 tokens fully wired". Real registry drift that was invisible while the section was missing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@thedavidmeister

Copy link
Copy Markdown
Contributor Author

Reviewed 48850b5: approve

Adds Ethereum's in-use beacons to the deployments dashboard, mirroring what S01-Issuer/st0x.deploy#266 establishes on the contract side: the beacons that matter are the ones a chain's production tokens actually run on, and that set is per-chain.

The chain now travels with the RPC session rather than being implied by the caller — a Base address asked of an Ethereum endpoint answers "no code here", a silent downgrade to not deployed that would look identical to a real outage. All four ETHEREUM_RPCS were verified live: each returns the same beacon addresses the Solidity lib resolves, and the two endpoints that failed (521, 429) were dropped rather than left in to fail a chain's read.

An unreadable chain reports itself instead of being filtered out. My first version dropped it, which renders as no section at all — the same silent vanish #117 had just fixed for tokens.

Verified: rust 179, deno 75, pre-commit run --all-files clean, and I read all three renders (posted above) rather than only gating on them.

Merging over one still-running macos rs-test; its ubuntu twin and the other macos job are green. No failing check.

@thedavidmeister
thedavidmeister merged commit 3a97e2c into master Jul 22, 2026
7 of 8 checks passed
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