> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stablenet.network/llms.txt
> Use this file to discover all available pages before exploring further.

# State Management

## Purpose and Scope

This document describes the state management system in StableNet that maintains and manages the global state, including all account balances, nonces, contract code, and contract storage.\
The state management layer provides a caching interface on top of a Merkle Patricia Trie structure, tracks state transitions that occur during transaction execution, and commits state changes at the block level.

Related documents:

* Transaction execution and state transitions: [Transaction Processing](/en/transaction-processing/index)
* Trie database schema: [Storage Architecture](/en/storage-architecture/index)
* State usage during block execution: [Blockchain Management](/en/core-architecture/3.2-blockchain-management)

## StateDB Architecture

`StateDB` is the core interface responsible for accessing and modifying state. It is defined in `core/state/statedb.go`, provides an in-memory caching layer on top of the account trie, and manages the full lifecycle of state objects representing individual accounts.

Key components:

* **trie**: the account trie that stores account state
* **snaps**: snapshot trees for fast state access (optional)
* **stateObjects**: in-memory cache of account objects (`map[common.Address]*stateObject`)
* **journal**: a journal that records state changes for rollback
* **originalRoot**: the state root at the start of the current block execution

StateDB is created at the beginning of block execution with a specific state root, accumulates state changes while executing transactions within the block, and computes and commits a new state root at the end of the block.

## State Objects

A `stateObject` is an internal structure that represents the state of a single account, including balance, nonce, code, and storage.\
It is cached in memory and clearly distinguishes between modified (dirty) state and committed state.

### StateAccount Structure

Each account’s persistent data is stored in the `StateAccount` structure defined in `core/types/state_account.go`:

| Field      | Type           | Description                                      |
| ---------- | -------------- | ------------------------------------------------ |
| `Nonce`    | `uint64`       | Transaction counter                              |
| `Balance`  | `*uint256.Int` | Account balance in Wei                           |
| `Root`     | `common.Hash`  | Storage trie root                                |
| `CodeHash` | `[]byte`       | Contract code hash                               |
| `Extra`    | `uint64`       | StableNet extension field (account policy flags) |

The `Extra` field is a StableNet extension used to represent account policy state defined by the governance layer.

### State Object Lifecycle

State objects are managed through the following stages:

1. **Create / Load**: `getStateObject()` retrieves the object from cache or loads it from the trie or snapshot if absent
2. **Modify**: balance, nonce, and storage values are updated in memory during transaction execution
3. **Finalize**: on `Finalise()`, dirty state is moved to the pending state
4. **Commit**: on `Commit()`, changes are written to the trie and persisted to the database

## Trie Structure

State is managed using a hierarchical Merkle Patricia Trie structure:

* **Account Trie**: a single trie storing the state of all accounts, keyed by address hash
* **Storage Trie**: one per contract account, storing contract variable values

Key operations include:

| Operation      | StateDB Method        | Description          |
| -------------- | --------------------- | -------------------- |
| Load account   | `getStateObject()`    | Load account state   |
| Update account | `updateStateObject()` | Update account state |
| Delete account | `deleteStateObject()` | Remove account       |
| Load storage   | `GetState()`          | Read storage slot    |
| Update storage | `SetState()`          | Update storage slot  |

## Caching Layers

To reduce the cost of state access, a multi-level caching architecture is used:

```
Request → StateDB cache → Snapshot layer → Trie node cache → Disk database
```

1. **StateDB Cache**\
   Keeps `stateObject` instances in memory. It manages `dirtyStorage` modified in the current transaction, `pendingStorage` finalized but not yet committed, and `originStorage` for change tracking.

2. **Snapshot Layer**\
   Provides account and storage data in a flat key–value structure, bypassing trie traversal. This significantly improves read performance and is generated and updated asynchronously.

3. **Trie Node Cache**\
   Managed by the trie database, separating recently accessed clean nodes and modified (dirty) nodes not yet written to disk.

4. **Disk Database**\
   The final persistent storage, holding encoded trie nodes and state data.

## Journaling and Snapshots

The journal system records all state changes sequentially, enabling transaction-level rollback.\
If an error occurs during execution, all state changes made by that transaction can be precisely reverted.

### Snapshots and Reverts

* **`Snapshot()`**: creates a rollback checkpoint for the current state and returns a journal index
* **`RevertToSnapshot()`**: restores all changes made after the specified snapshot in reverse order

The journal records the following types of changes:

* Balance, nonce, and code updates
* Storage slot updates
* `selfdestruct` flags
* Access list changes
* Log additions

A snapshot is created before each EVM call, and if execution fails, only the state changes within that call scope are rolled back.

## State Commit

State commits are performed at the block level and persist changes to permanent storage.

### Commit Flow

```
Finalise → IntermediateRoot → Commit
```

**1. Finalise**

* Move dirty storage to pending storage
* Clean up empty accounts (EIP-161)
* Called repeatedly after transaction execution

**2. IntermediateRoot**

* Compute roots of all storage tries
* Update the account trie
* Return the current state root, used to compute the receipt root

**3. Commit**

* Commit account and storage tries to disk
* Update the trie database
* Commit snapshots
* Return the final state root

### State Change Tracking

With the path-based state scheme (PBSS), the following tracking maps are maintained for efficient state management and pruning:

* **accounts / storages**: accounts and storage entries modified in the current block
* **accountsOrigin / storagesOrigin**: original values before modification
* **stateObjectsDestruct**: information about deleted accounts

This information is passed to the trie database during commit and used for state management optimizations.

## Database Integration

StateDB integrates with the trie database through the `Database` interface defined in `core/state/database.go`.\
Both hash-based and path-based (PBSS) state schemes are supported.

### Database Configuration

| Setting          | Default    | Description                              |
| ---------------- | ---------- | ---------------------------------------- |
| `StateScheme`    | HashScheme | State storage scheme                     |
| `TrieCleanLimit` | 256 MB     | Clean cache size                         |
| `TrieDirtyLimit` | 256 MB     | Dirty cache size                         |
| `SnapshotLimit`  | 256 MB     | Snapshot cache size                      |
| `Preimages`      | false      | Whether to store trie key preimages      |
| `StateHistory`   | 0          | Number of blocks to retain state history |

Key interface methods:

* `OpenTrie(root)`
* `OpenStorageTrie(stateRoot, addrHash, root, trie)`
* `ContractCode(addrHash, codeHash)`
* `TrieDB()`

## State Prefetching

State prefetching is an optimization technique that preloads required trie nodes during block execution.\
It is started with `StartPrefetcher()` and stopped with `StopPrefetcher()`.

The prefetcher predicts which accounts and storage slots transactions will access and loads them into cache in advance, reducing disk I/O wait time and improving block processing performance.

## Performance Metrics

StateDB collects the following metrics to monitor state management performance:

* Account and storage read/write/commit times
* Snapshot lookup and commit times
* Trie database commit times
* Number of modified accounts and storage slots

These metrics help node operators analyze state processing bottlenecks and tune performance.
