Fork Testing
Learn how to test contracts against real blockchain state by forking testnet or mainnet
Fork testing allows you to run tests against real blockchain state by loading accounts and libraries from TON's testnet or mainnet. This enables testing contract interactions with real deployed contracts without needing to set up a complex local environment.
What is Fork Testing?
Fork testing creates a local "fork" of the real blockchain state for your tests. When your test code accesses an account that exists on testnet or mainnet, the test runner automatically:
- Fetches the account's state from the network
- Caches it locally for the test run
- Uses that real state in your test execution
This is particularly useful for:
- Testing integrations with existing contracts
- Verifying behavior against real contract code
- Debugging issues with deployed contracts
- Testing edge cases with real on-chain data
Enabling Fork Testing
Basic Usage
To enable fork testing, use the --fork-net flag when running tests:
# Fork from testnet
acton test --fork-net testnet
# Fork from mainnet
acton test --fork-net mainnetConfiguring API Access
Access to TonCenter API requires an API key to avoid rate limiting. Set the env var that matches the forked network:
TONCENTER_TESTNET_API_KEY=YOUR_API_KEY acton test --fork-net testnet
TONCENTER_MAINNET_API_KEY=YOUR_API_KEY acton test --fork-net mainnetGetting an API Key
You can obtain a free TonCenter API key from toncenter.com.
How Fork Testing Works
When a test accesses an account while fork testing is enabled:
- Check Local Cache — The system first checks if the account was already loaded
- Fetch from Network — If not cached and
--fork-netis specified, it queries TonCenter API - Load State — Account state (balance, code, data, status) is downloaded and deserialized
- Cache for Reuse — The state is cached for subsequent accesses during the test run
- Execute Locally — Tests execute using this real state in the local emulator
This hybrid approach gives you real data with local execution speed.
Network Latency
The first access to each unique account will make a network request, which adds latency. Subsequent accesses use the cache. Consider this when writing tests that access many different accounts.
Cache Scope and Refresh Behavior
Forked account snapshots are cached only in memory for the current acton test
invocation.
- The cache key is the tuple of fork network, optional pinned block number, and account address.
- The cache is shared across tests in the same run, so the second test that touches the same account does not re-fetch it.
- The cache is not persisted to disk. A fresh
acton test --fork-net ...run starts with an empty remote snapshot cache. - Failed lookups are not cached. If a request errors, the next access can try the network again.
If you need to refetch network state, rerun the test command. Mutations made by the local emulator do not invalidate and re-download the remote snapshot.
Local State Priority
Accounts that were deployed or modified within your test will not be overwritten by network state. Fork testing only loads accounts that don't exist in the local test environment.
That precedence also applies after an account is fetched once. Once the account exists in the emulated world state, later reads and message execution use the local copy from that world state rather than querying the network again.
Library Lookup Precedence
Library lookup follows the same "local first" rule.
When code asks to resolve a library hash, Acton first checks libraries already
registered in the current emulated world state, for example via
testing.registerLibrary(...). Only if the library is still missing does it
fall back to the configured fork network.
This matters when you intentionally override a real network library during a forked test: the locally registered library wins for the rest of that run.
Last updated on