- Surfpool is a local Solana network with real mainnet state on demand — a copy-on-read fork means any account you touch is lazy-fetched from mainnet, no snapshot dumps required.
- Anchor v1.0.0 (2026-04-02) makes Surfpool the default validator for
anchor testandanchor localnet. If you rananchor inittoday, yourAnchor.tomlalready has a[surfpool]section — but you still need to install thesurfpoolbinary separately (see install below). - It exposes a full Solana JSON-RPC server and adds 26
surfnet_*cheatcode methods — set any account, mint any token, time-travel, pause the clock, profile any transaction. - Internally it wraps LiteSVM for execution, so it boots in sub-second time and runs on a Raspberry Pi. Self-description: “Surfpool is to Solana what Anvil is to Ethereum.”
- All commands and cheatcode signatures in this guide are verified against txtx/surfpool v1.1.2 as of April 2026.
Where Surfpool fits
Solana’s modern testing pyramid trades fidelity for speed. Surfpool owns the integration tier — the layer above pure unit testing, the layer below a real testnet.| Tier | Tool | What you get | What you give up |
|---|---|---|---|
| Unit (single instruction) | Mollusk | CU-accurate benchmarking, no bank state | No sysvars, no CPI across programs |
| Unit (multi-instruction) | LiteSVM | Full bank, sysvars, CPI, fastest iteration | No RPC, no network effects, no mainnet state |
| Integration | Surfpool | Full RPC, mainnet fork, cheatcodes | No MEV/contention simulation, single validator only |
| End-to-end | Devnet / mainnet | Real network | Slow, flaky, real money |
What Surfpool replaces
| Incumbent | How Surfpool compares |
|---|---|
solana-test-validator | Drop-in replacement. Full RPC compatibility, but boots in sub-second time and can fork any mainnet account on demand. Works on a Raspberry Pi. |
Manual --clone of mainnet accounts | No pre-dumping. Call any RPC method that touches a mainnet address — Surfpool fetches the account the first time you ask for it and caches it locally. |
Install
The installer script is the recommended path:First run
- Starts a JSON-RPC server on
127.0.0.1:8899(same assolana-test-validator) - Starts a WebSocket server on
127.0.0.1:8900 - Opens Surfpool Studio (a local dashboard) on a browser port
- Enters an interactive TUI showing block production, transaction throughput, and account activity
--no-tui to stream logs instead of the dashboard, or --no-studio if you don’t want the browser UI.
Point any Solana tool at the local endpoint — it speaks standard Solana RPC:
Fork mainnet with Chainstack
The killer feature is copy-on-read mainnet fork. Any account you read is fetched from the datasource the first time you touch it, cached locally, and treated as local state from then on.The
SURFPOOL_DATASOURCE_RPC_URL environment variable is equivalent to --rpc-url. Set it once in your shell profile to avoid retyping the endpoint.Cheatcodes: 26 surfnet_* RPC methods
Surfpool’s JSON-RPC server accepts all standard Solana methods (getAccountInfo, sendTransaction, etc.) plus 26 surfnet_* extensions that let you mutate local state in ways the real network won’t allow. Complete list, verified from source:
Accounts: setAccount, setTokenAccount, cloneProgramAccount, resetAccount, offlineAccount, setSupply, setProgramAuthority, writeProgram
Transaction profiling: profileTransaction, getTransactionProfile, getProfileResultsByTag
IDL: registerIdl, getActiveIdl
Clock: timeTravel, pauseClock, resumeClock
Network: resetNetwork, exportSnapshot, getSurfnetInfo, getLocalSignatures
Account streaming: streamAccount, streamAccounts, getStreamedAccounts
Cheatcode control: enableCheatcode, disableCheatcode
Scenarios: registerScenario
Four worked examples below cover the ones you will reach for on day one.
Set any account
Overwrite any on-chain account with arbitrary lamports, data, and owner. TheAccountUpdate struct is all-optional — send only the fields you want to change.
data field, if provided, takes a hex-encoded byte string — despite what some documentation suggests, the v1.1.2 implementation only accepts hex. Sending base64 or base58 returns Invalid hex data provided. Omit the field to leave data untouched, or pass "data": "" to clear it.
Mint tokens to any wallet (no authority required)
The cheatcode that saves the most time in DeFi tests. Give any wallet any token balance without caring about mint authority.Include
"state": "initialized" or the newly-created token account is usable as an address but reports a zero balance. This is a quiet footgun — the cheatcode succeeds either way.Time travel
Advance the clock to any slot, epoch, or unix timestamp. Useful for vesting, auctions, staking warmup/cooldown.{ "absoluteSlot": <n> } or { "absoluteEpoch": <n> }. Slot and epoch are absolute values — they must be strictly greater than the current ones. Pair with surfnet_pauseClock / surfnet_resumeClock to freeze block production.
Profile a transaction
surfnet_profileTransaction executes the transaction against a temporary state snapshot — the execution is real, but state changes are not committed to the local network. It captures pre/post account snapshots and per-instruction CU metrics for analysis.
instructionProfiles, and a unique key UUID. The second positional parameter is an optional tag string — not a config object. Call surfnet_getProfileResultsByTag later to compare runs that share a tag.
Anchor integration
Anchor v1.0.0 made Surfpool the default test validator (PR #4106). A freshanchor init scaffolds a [surfpool] section in Anchor.toml:
solana-test-validator:
Migrating from [test.validator.clone]
Legacy Anchor projects pre-dump mainnet accounts via the [test.validator.clone] section. Surfpool makes that unnecessary — lazy fetch replaces pre-cloning. The old pattern:
surfnet_setAccount from a test-setup step after fetching the bytes from mainnet RPC yourself. surfnet_cloneProgramAccount is not a general warmer — its signature is (source_program_id, destination_program_id) and it only copies executable program accounts.
Pitfalls
Offline mode is the default
As above —online = false in Anchor.toml means no mainnet fetch, no matter what datasource_rpc_url you set. This trips up everyone migrating from a manual solana-test-validator --clone workflow.
No transaction contention or MEV simulation
Every transaction Surfpool sees succeeds in priority order as submitted. There is no priority-fee reordering, no sandwich attack simulation, no write-lock contention (issue #529, open). For MEV-sensitive logic, test on a real cluster or use dedicated MEV simulation tooling.Single validator only
No multi-node support (issue #448, open). Tests that need cross-validator behavior (e.g., leader rotation, gossip-dependent protocols) need a real cluster.CI version pinning
The installer script always installs the latest version. Anchor’sSURFPOOL_CLI_VERSION env var only busts caches — it doesn’t pin (issue #4160, closed as resolved in Anchor v1.0, though version pinning for the installer itself is still manual). For reproducible CI, pin to a specific cargo install surfpool-cli --version or a pinned Docker tag.
Snap package is stale
sudo snap install surfpool fetches v0.9.5 (2025-07-21) — roughly 6 months behind GitHub. Use the installer script or cargo.
anchor deploy cluster-node timeout
Running anchor deploy against a running Surfpool sometimes fails with Failed to find any cluster node info for upcoming leaders, timeout: 20s (Solana SE #23339). The validator is up but has not emitted leader-schedule info yet. Wait a few slots after surfpool start before invoking anchor deploy, or prefer anchor test (which waits for Surfpool to be ready before deploying).
No MCP-less non-interactive mode
surfpool start always boots with the TUI unless you pass --no-tui. For CI, always combine --no-tui --no-studio.
When not to use Surfpool
- You need MEV or priority-fee contention simulation. Use a real cluster.
- You need multi-validator / leader-rotation tests. Use a real cluster.
- You need reproducible CI with a locked version before installer pinning ships. Use a Docker tag or pinned
cargo install. - You are doing pure unit testing and don’t need a real RPC. LiteSVM is 10× faster per test.
- You want CU-accurate single-instruction benchmarking. Mollusk is purpose-built.
See also
- Solana: Fast unit testing with LiteSVM — the unit tier below Surfpool; Surfpool wraps LiteSVM internally.
- Solana: Anchor development — the framework Surfpool is now the default test backend for.
- Surfpool docs — authoritative CLI, RPC, cheatcode reference.
- Surfpool cheatcodes reference — full JSON-RPC signature for every
surfnet_*method. - Anchor v1.0.0 release notes — the PR that made Surfpool default.
- Helius: Introducing Surfpool — conceptual intro and lazy-fork explanation.
- Blueshift: Surfpool 101 — interactive course.