Skip to content

event-gate erc20 balance reads#335

Open
mrq1911 wants to merge 1 commit into
galacticcouncil:masterfrom
mrq1911:perf/erc20-event-gated-balances
Open

event-gate erc20 balance reads#335
mrq1911 wants to merge 1 commit into
galacticcouncil:masterfrom
mrq1911:perf/erc20-event-gated-balances

Conversation

@mrq1911

@mrq1911 mrq1911 commented Jun 28, 2026

Copy link
Copy Markdown
Member

Problem

BalanceClient.watchErc20Balance is the #1 per-block RPC cost of an active sdk-next context. Today it does:

this.watcher.bestBlock$.pipe(switchMap(() => fetchBalance(ids)))

→ re-reads every ERC20 id via CurrenciesApi.account (a chainHead_v1_call) on every block, unconditionally. The distinctUntilChanged only suppresses emissions, not the RPC ops. Measured on a mainnet chainHead node (Treasury account, 64 pools / 43 ERC20 slots): ~84 chainHead_v1_call/block, all CurrenciesApi_account.

Fix (event-gated)

  • Seed once with a full read (unchanged first-block behaviour).
  • Subscribe to EVM.Log.watch(), decode ERC20 Transfer(from,to,value) logs, map the emitting contract → asset id via the existing ERC20.toAssetId (structural 0x..01<id> precompile prefix — no RPC; same mapping AavePoolClient uses in reverse).
  • Re-read only the (address, id) pairs where the watched account is from/to (account compared via H160.fromAny).
  • Safety net: full re-read every N=20 blocks so a missed/unmapped log (e.g. a non-EVM mutation of an ERC20-typed asset) can't permanently stale a balance.
  • A running snapshot map keeps every emission the complete ERC20 balance set, preserving the previous output shape.

Public watchErc20Balance / watchBalance signatures are unchanged (internal only).

Benchmark (mainnet chainHead, same harness, only the lib changes)

CurrenciesApi_account calls per block, Treasury account, 64 pools / 43 ERC20 slots:

CurrenciesApi_account/block total chainHead_v1_call/block storage ops/block
master 84 84 ~162
this PR 0 (idle) 0.43 ~166

Idle blocks drop to 0 CurrenciesApi_account calls; the residual 0.43 is the unrelated router Aave-executor call from the spot-price loop. Storage ops unchanged → the change targets exactly the ERC20 call fan-out and nothing else.

Regression

  • Existing suite green: 16 suites / 67 tests pass (baseline 15/57; +1 suite / +10 from the new Erc20Log.spec.ts).
  • Functional equivalence (verified): read every ERC20 balance for the account at the same pinned block on master vs this branch → byte-identical for all 23 ids, 0 mismatches. (The read path getBalanceData → CurrenciesApi.account is untouched; only the scheduling changed.)
  • Balance still updates on activity (verified by decode test + reasoned): the Erc20Log decoder + the from/to gate are unit-tested against synthetic Transfer logs (sender match, receiver match, wrong-asset drop, unrelated-account drop, non-asset-contract → null). A real Transfer touching the account triggers a targeted re-read; the safety re-read backstops any missed log.

Notes

  • New focused unit test: packages/sdk-next/src/client/Erc20Log.spec.ts (10 cases) covering the pure decoder + the event-gate predicate.
  • Changeset added (sdk-next patch).

@changeset-bot

changeset-bot Bot commented Jun 28, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: e0bca73

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@galacticcouncil/sdk-next Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@netlify

netlify Bot commented Jun 28, 2026

Copy link
Copy Markdown

Deploy Preview for galactic-apps ready!

Name Link
🔨 Latest commit e0bca73
🔍 Latest deploy log https://app.netlify.com/projects/galactic-apps/deploys/6a4106f787e0b90008585062
😎 Deploy Preview https://deploy-preview-335--galactic-apps.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@mrq1911
mrq1911 marked this pull request as ready for review June 28, 2026 11:49
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