Skip to content

fix(#2204): restrict getProgramAccounts to Percolator programs, not just to filtered queries - #2530

Merged
dcccrypto merged 1 commit into
playgroundfrom
fix/2204-gpa-bounds
Sep 2, 2026
Merged

fix(#2204): restrict getProgramAccounts to Percolator programs, not just to filtered queries#2530
dcccrypto merged 1 commit into
playgroundfrom
fix/2204-gpa-bounds

Conversation

@dcccrypto

Copy link
Copy Markdown
Owner

Closes #2204.

A filter requirement (dataSize / memcmp) was already in place. It is necessary but not sufficient, and the issue's own example is the proof:

full account state dumps of the SPL Token Program

That query supplies dataSize: 165 — the SPL token-account size — quite happily. The filter check passes, and the upstream node still returns every token account on the cluster.

A filter bounds the result shape. It does not bound the program. On a program with millions of matching accounts, that is no bound at all. Both halves of the report were real; only one had been closed.

The program is now pinned too

Built from config, not a hardcoded list:

target source used by
wrapper + every slab tier getAllProgramIds() userAccountScan
matcher matcherProgramId matcherCaps
NFT program nftProgramId userAccountScan
stake / vault vaultProgramId stake reads

Anything else is refused with -32602 rather than forwarded to a paid endpoint. Adding a slab tier extends the allowlist with no change here — the same property getAllProgramIds() already gives assertKnownProgram.

A non-string params[0] is rejected rather than coerced, so a missing target cannot fall through.

One test worth calling out

It pins that the allowlist is non-empty. An allowlist that degrades to empty still "works" — it rejects everything — but the inverse shape, where an empty set is treated as permissive, is the dangerous one. This makes a config regression visible either way.

Launch suite: 3128 passed / 16 skipped / 0 failed.

🤖 Generated with Claude Code

https://claude.ai/code/session_01NgoNgagkvw7i5SSRC3FJ8D

…ust to filtered queries

The filter requirement already in place (`dataSize` or `memcmp`) is necessary but
NOT sufficient, and the issue's own example is the proof: dumping the SPL Token
Program supplies `dataSize: 165` — the token-account size — quite happily. The
filter check passes and the upstream node still returns every token account on
the cluster.

A filter bounds the result SHAPE. It does not bound the PROGRAM, and on a program
with millions of matching accounts that is no bound at all. Both halves of the
report were real; only one had been closed.

So the program is pinned too. This proxy exists to serve THIS app, and the app
only ever queries programs it owns:

  wrapper + every slab tier   getAllProgramIds()   (userAccountScan)
  matcher                     matcherProgramId     (matcherCaps)
  NFT program                 nftProgramId         (userAccountScan)
  stake/vault                 vaultProgramId

Anything else is not a query we need to serve, so it is refused with -32602
rather than forwarded to a paid endpoint.

Built from config rather than a hardcoded list, so adding a slab tier extends the
allowlist with no change here — the same property getAllProgramIds() already
gives assertKnownProgram.

A non-string `params[0]` is rejected rather than coerced, so a missing target
cannot fall through to the upstream node.

One test pins that the allowlist is NON-EMPTY. An allowlist that silently
degrades to empty still "works" — it rejects everything — but the inverse shape,
where an empty set is treated as permissive, is the dangerous one, and this makes
a config regression visible either way.

Launch suite: 3128 passed / 16 skipped / 0 failed.

Refs: #2204

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NgoNgagkvw7i5SSRC3FJ8D
@vercel

vercel Bot commented Sep 2, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
percolator-launch Ready Ready Preview Sep 2, 2026 6:33pm UTC
percolator-mainnet Ready Ready Preview Sep 2, 2026 6:33pm UTC
percolator-playground Ready Ready Preview Sep 2, 2026 6:33pm UTC

Request Review

@coderabbitai

coderabbitai Bot commented Sep 2, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 45 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Team

Run ID: 63896ed6-e487-49fc-a8aa-004ca7465bf7

📥 Commits

Reviewing files that changed from the base of the PR and between 57d97ff and c5b01bf.

📒 Files selected for processing (2)
  • app/__tests__/api/rpc-gpa-program-allowlist.test.ts
  • app/app/api/rpc/route.ts

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.

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