# The fork engine

The fork engine produces a deterministic snapshot of a program's on-chain state at a given slot. This chapter documents what the engine fetches, how it stores the result, and which guarantees the snapshot does and does not provide.

## Inputs

A fork operation is identified by three values: a program ID, a network identifier, and a slot. The CLI accepts the first two as positional arguments and the third as `--slot`. When `--slot` is absent, the engine resolves the chain tip at the moment of invocation by issuing `getSlot` against the configured RPC.

The resolved slot is recorded in the snapshot filename. This means a `solforge fork` command that omits `--slot` is reproducible: subsequent runs that pass the recorded slot value will produce a byte-identical snapshot.

## RPC sequence

For each fork, the engine issues two RPC calls.

The first is `getSlot`, used only when `--slot` was not supplied. The second is `getProgramAccounts` with `encoding=base64` and `commitment=confirmed`. Base64 is mandatory for two reasons: it is the only encoding that survives the `dataSize` filter on accounts larger than 128KB, and it produces a stable byte sequence that the snapshot's content addressing depends on.

The engine does not chunk `getProgramAccounts`; if the program has more accounts than the RPC will return in a single response, the call fails and the engine surfaces the error verbatim. Chunked retrieval is on the roadmap and will land before 1.0.

## Snapshot layout

A snapshot is written to:

```
.solforge/snapshots/<network>/<programId>/<slot>.json
```

The JSON structure is:

```json
{
  "schema_version": 1,
  "fetched_at": "2026-05-08T17:00:00Z",
  "network": "devnet",
  "program_id": "9xQ...",
  "slot": 240118022,
  "accounts": [
    {
      "pubkey": "Ec7...",
      "lamports": 1461600,
      "owner": "9xQ...",
      "executable": false,
      "rent_epoch": 1234,
      "data_b64": "AQI..."
    }
  ]
}
```

`schema_version` is bumped on any field-level change to the layout. The framework will refuse to read a snapshot whose schema is newer than the binary; a clear diagnostic recommends the appropriate upgrade.

## What the snapshot does not contain

A fork captures the program's owned accounts. It does **not** capture:

* accounts owned by other programs that the target program calls into via CPI;
* the validator's clock, slot history, or rent sysvars;
* the program's executable bytecode (the IDL is fetched separately by the IDL loader).

For the fuzz engine, the missing CPI targets are usually the limiting factor. A program that performs a CPI into Token-2022 will fuzz fine for instructions that do not call Token-2022, and will fail loudly on instructions that do. The diagnostic recommends the workaround: add the foreign program to the fork via the `--also-fork` flag, which is documented in the changelog.

## Re-running a fork

A `solforge fork` against an already-snapshotted `(network, programId, slot)` is a no-op. The engine writes nothing, the filesystem is not touched, and the command exits 0. This makes it safe to re-fork at the start of every test run; CI workflows in [Wiring solforge into GitHub Actions](/solanatestforge-docs/part-iii-recipes/github-actions.md) rely on this property.

To force a re-fetch, delete the existing snapshot. The framework does not provide a `--force` flag; the explicit `rm` is preferred because it makes the destruction visible.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://solanatestforge.gitbook.io/solanatestforge-docs/part-ii-reference/fork-engine.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
