Skip to content

chore(defaults): consensus-based audit, drop stale fallbacks (2026-05-02)#29

Merged
Sentinel-Bluebuilder merged 1 commit intomasterfrom
chore/audit-consensus-2026-05-02
May 2, 2026
Merged

chore(defaults): consensus-based audit, drop stale fallbacks (2026-05-02)#29
Sentinel-Bluebuilder merged 1 commit intomasterfrom
chore/audit-consensus-2026-05-02

Conversation

@Sentinel-Bluebuilder
Copy link
Copy Markdown
Owner

Why

Follow-up to #28 (merged earlier today). Re-running the audit immediately surfaced two issues:

  1. Hardcoded balance constant goes stale. The previous audit-rpc-endpoints.mjs asserted EXPECTED_UDVPN === '10000000000'. The audit wallet had a small outflow (98923 udvpn) between PR authoring and merge, so re-running flagged 0/22 healthy when in fact 12 endpoints all agreed on the new correct balance and only rpc.sentinel.co was actually broken. Health-check by hardcoded value is brittle by construction.

  2. rpc.sentinel.co / lcd.sentinel.co still in defaults.js as 'stale fallback'. Today's audit confirms both are still ~22k blocks behind tip and return 0 for funded addresses while reporting catching_up=false on /status. Keeping them in the array means a tryWithFallback() call could still hit them after every other endpoint fails and silently return wrong data — exactly the failure mode chore(defaults): refresh RPC/LCD endpoints (2026-05-02) #28 was supposed to fix.

What

  • tools/audit-rpc-endpoints.mjs — replace hardcoded EXPECTED_UDVPN with a consensus check: health = (height, balance) matches the modal answer across responding candidates, within 50 blocks of tip. Survives any future outflow from the audit address. The script also now audits LCD endpoints in the same run (the previous script was RPC-only).
  • defaults.js — drop rpc.sentinel.co and lcd.sentinel.co entirely. Re-sort RPC list by today's measured latency. Expand LCD list 6 -> 9 entries (Roomit, ChainTools, ChainVibes, Validatus all newly verified).

Audit results (2026-05-02, consensus mode)

RPC: 12/22 healthy -- 12/13 responding agree on balance, only rpc.sentinel.co disagrees.

LCD: 9/12 healthy -- 9/10 responding agree, only lcd.sentinel.co disagrees (balance=0); lcd.sentineldao.com and api.mathnodes.com are DNS-NXDOMAIN.

Removed

  • https://rpc.sentinel.co:443 -- catching_up=true, balance=0 (22k blocks behind tip)
  • https://lcd.sentinel.co -- same pattern, returned 0 for the funded address

Consumers that hardcode these can re-add them at runtime via addRpcEndpoint() / addLcdEndpoint().

Test plan

  • node tools/audit-rpc-endpoints.mjs -- exits 0, prints both RPC + LCD tier-1 lists
  • node -e "import('./defaults.js').then(d => console.log(d.DEFAULT_RPC, d.DEFAULT_LCD))" -- both resolve to Busurnode (fastest)
  • Consensus check confirmed by manual inspection: 12/13 RPC + 9/10 LCD agree on the modal balance
  • Reviewer sanity: re-run node tools/audit-rpc-endpoints.mjs on a fresh checkout

…-02)

The 2026-05-02 follow-up to PR #28 surfaced two issues with the audit:

1. The previous script hardcoded EXPECTED_UDVPN as a constant. The audited
   wallet had a small outflow between PR authoring and merge, so re-running
   the script declared 0/22 healthy when in fact 12 endpoints all agreed on
   the new (correct) balance and only rpc.sentinel.co was actually broken.

2. defaults.js still listed rpc.sentinel.co / lcd.sentinel.co as a "stale
   fallback" entry. Today's audit confirms both are still ~22k blocks behind
   tip and return 0 for funded addresses while reporting catching_up=false.
   Keeping them in the array meant a tryWithFallback() call could still hit
   them after every other endpoint failed and silently return wrong data.

Changes:

- tools/audit-rpc-endpoints.mjs — replace hardcoded EXPECTED_UDVPN with a
  consensus check (modal balance across responding candidates, within 50
  blocks of tip). Survives any future outflow from the audit address. Also
  audits LCD endpoints in the same run; the previous script only covered RPC.
- defaults.js — drop rpc.sentinel.co and lcd.sentinel.co. Re-sort RPC list
  by today's measured latency. Expand LCD list 6 -> 9 entries (Roomit,
  ChainTools, ChainVibes, Validatus all newly verified).

Audit results (2026-05-02, consensus mode):
- RPC: 12/22 healthy, 12/13 responding agree on balance
- LCD: 9/12 healthy, 9/10 responding agree on balance

Run: node tools/audit-rpc-endpoints.mjs

Test plan
- node -e "import('./defaults.js').then(d => console.log(d.DEFAULT_RPC, d.DEFAULT_LCD))" -> Busurnode for both
- Audit script exits 0 with both RPC and LCD tier-1 lists populated
@Sentinel-Bluebuilder Sentinel-Bluebuilder merged commit c6ada72 into master May 2, 2026
2 checks passed
@Sentinel-Bluebuilder Sentinel-Bluebuilder deleted the chore/audit-consensus-2026-05-02 branch May 2, 2026 20:37
@Sentinel-Bluebuilder Sentinel-Bluebuilder mentioned this pull request May 2, 2026
2 tasks
Sentinel-Bluebuilder added a commit that referenced this pull request May 2, 2026
Patch release shipping the consensus-audited RPC + LCD endpoint defaults
from #28 and #29 to npm consumers.

- package.json: 2.7.0 -> 2.7.1
- defaults.js: SDK_VERSION 2.4.0 -> 2.7.1 (was lagging package.json)

No API surface changes. Defaults-only update -- consumers calling
createRpcQueryClientWithFallback() / SentinelClient with no overrides will
now skip the stale rpc.sentinel.co / lcd.sentinel.co endpoints that were
returning balance=0 for funded addresses.

Co-authored-by: Sentinel-Autonomybuilder <[email protected]>
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