> ## 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.

# 상태 관리

## 목적 및 범위

이 문서는 StableNet에서 모든 계정 잔액, nonce, 컨트랙트 코드, 컨트랙트 저장소를 포함하는 전역 상태를 유지·관리하는 상태 관리 시스템을 설명합니다.\
상태 관리 레이어는 Merkle Patricia Trie 구조 위에 캐싱 인터페이스를 제공하며, 트랜잭션 실행 중 발생하는 상태 전환을 추적하고, 블록 단위로 상태를 커밋하는 역할을 수행합니다.

관련 문서:

* 트랜잭션 실행 및 상태 전이: [트랜잭션 처리](/ko/transaction-processing/index)
* Trie 데이터베이스 스키마: [저장소 아키텍처](/ko/storage-architecture/index)
* 블록 실행 중 상태 사용: [블록체인 관리](/ko/core-architecture/3.2-blockchain-management)

## StateDB 아키텍처

`StateDB`는 상태 접근과 수정을 담당하는 핵심 인터페이스입니다. `core/state/statedb.go`에 정의되어 있으며, 계정 trie 위에 메모리 캐싱 레이어를 제공하고 개별 계정을 나타내는 상태 객체의 전체 라이프사이클을 관리합니다.

핵심 구성 요소:

* **trie**: 계정 상태를 저장하는 계정 trie
* **snaps**: 빠른 상태 조회를 위한 스냅샷 트리 (선택적)
* **stateObjects**: 메모리 내 계정 객체 캐시 (`map[common.Address]*stateObject`)
* **journal**: 상태 변경을 기록하는 저널, 롤백에 사용
* **originalRoot**: 현재 블록 처리 시작 시점의 상태 루트

StateDB는 블록 실행 시작 시 특정 상태 루트를 기준으로 생성되며, 블록 내 트랜잭션 실행 동안 상태 변경을 누적한 뒤, 블록 종료 시 새로운 상태 루트를 계산하고 커밋합니다.

## 상태 객체

`stateObject`는 단일 계정의 상태를 표현하는 내부 구조체로, 잔액, nonce, 코드, 저장소를 포함합니다. 메모리에 캐시되며, 변경 중인 상태와 커밋된 상태를 명확히 구분하여 관리합니다.

### StateAccount 구조

각 계정의 영구 데이터는 `core/types/state_account.go`에 정의된 `StateAccount` 구조체에 저장됩니다:

| 필드         | 타입             | 설명                          |
| ---------- | -------------- | --------------------------- |
| `Nonce`    | `uint64`       | 트랜잭션 카운터                    |
| `Balance`  | `*uint256.Int` | Wei 단위 계정 잔액                |
| `Root`     | `common.Hash`  | 저장소 trie 루트                 |
| `CodeHash` | `[]byte`       | 컨트랙트 코드 해시                  |
| `Extra`    | `uint64`       | StableNet 확장 필드 (계정 정책 플래그) |

`Extra` 필드는 StableNet 확장으로, 거버넌스 레이어에서 정의한 계정 정책 상태를 표현하는 데 사용됩니다.

### 상태 객체 라이프사이클

상태 객체는 다음 단계를 거쳐 관리됩니다:

1. **생성/로드**: `getStateObject()`가 캐시에서 조회하거나, 없을 경우 trie 또는 스냅샷에서 로드
2. **수정**: 트랜잭션 실행 중 잔액, nonce, 저장소 값 변경이 메모리에 기록
3. **최종화**: `Finalise()` 호출 시 dirty 상태가 pending 상태로 전환
4. **커밋**: `Commit()` 호출 시 변경 사항이 trie에 반영되고 데이터베이스에 저장

## Trie 구조

상태는 계층적인 Merkle Patricia Trie 구조로 관리됩니다:

* **계정 trie (Account Trie)**: 모든 계정의 상태를 저장하는 단일 trie, 키는 주소 해시
* **저장소 trie (Storage Trie)**: 각 컨트랙트 계정마다 존재하며, 컨트랙트 변수 값을 저장

주요 연산은 다음과 같습니다:

| 작업     | StateDB 메서드           | 설명        |
| ------ | --------------------- | --------- |
| 계정 조회  | `getStateObject()`    | 계정 상태 로드  |
| 계정 기록  | `updateStateObject()` | 계정 상태 갱신  |
| 계정 삭제  | `deleteStateObject()` | 계정 제거     |
| 저장소 조회 | `GetState()`          | 저장소 슬롯 조회 |
| 저장소 기록 | `SetState()`          | 저장소 슬롯 갱신 |

## 캐싱 레이어

상태 접근 비용을 줄이기 위해 다단계 캐싱 구조를 사용합니다:

```
요청 → StateDB 캐시 → 스냅샷 레이어 → Trie 노드 캐시 → 디스크 데이터베이스
```

1. **StateDB 캐시**\
   `stateObject` 인스턴스를 메모리에 유지합니다. 현재 트랜잭션에서 변경된 `dirtyStorage`, 최종화되었으나 커밋되지 않은 `pendingStorage`, 변경 추적을 위한 `originStorage`를 관리합니다.

2. **스냅샷 레이어**\
   계정과 저장소를 평면 키-값 구조로 제공하여 trie 순회를 우회합니다. 일반 상태 조회 성능을 크게 개선하며, 비동기적으로 생성·갱신됩니다.

3. **Trie 노드 캐시**\
   trie 데이터베이스가 관리하며, 최근 접근 노드(clean)와 아직 디스크에 기록되지 않은 수정 노드(dirty)를 분리해 보관합니다.

4. **디스크 데이터베이스**\
   최종 영구 저장소로, 인코딩된 trie 노드와 상태 데이터를 저장합니다.

## 저널링 및 스냅샷

저널 시스템은 모든 상태 변경을 순서대로 기록하여, 트랜잭션 단위의 롤백을 가능하게 합니다. 실행 중 오류가 발생하면 해당 트랜잭션에서 발생한 모든 상태 변경을 정확히 되돌릴 수 있습니다.

### 스냅샷 및 되돌리기

* **`Snapshot()`**: 현재 상태의 되돌리기 기준점을 생성하며, 저널 인덱스를 반환합니다
* **`RevertToSnapshot()`**: 지정된 스냅샷 이후의 모든 변경을 역순으로 복구합니다

저널에는 다음과 같은 변경 유형이 기록됩니다:

* 잔액, nonce, 코드 변경
* 저장소 슬롯 변경
* selfdestruct 플래그
* 접근 목록(access list) 변경
* 로그 추가

각 EVM 호출 전 스냅샷이 생성되며, 실행이 실패하면 해당 호출 범위의 상태 변경만 롤백됩니다.

## 상태 커밋

상태 커밋은 블록 단위로 수행되며, 변경 사항을 영구 저장소에 반영하는 과정입니다.

### 커밋 흐름

```
Finalise → IntermediateRoot → Commit
```

**1. Finalise**

* dirty 저장소를 pending 저장소로 전환
* 빈 계정 정리(EIP-161)
* 트랜잭션 실행 후 반복 호출

**2. IntermediateRoot**

* 각 저장소 trie의 루트 계산
* 계정 trie 갱신
* 현재 상태 루트 반환, 영수증 루트 계산에 사용

**3. Commit**

* 계정 trie와 저장소 trie를 디스크에 커밋
* trie 데이터베이스 갱신
* 스냅샷 커밋
* 최종 상태 루트 반환

### 상태 변경 추적

경로 기반 상태 스키마(PBSS)에서는 효율적인 상태 관리와 프루닝을 위해 다음 추적 맵을 유지합니다:

* **accounts / storages**: 현재 블록에서 변경된 계정 및 저장소
* **accountsOrigin / storagesOrigin**: 변경 전 원본 값
* **stateObjectsDestruct**: 삭제된 계정 정보

이 정보는 커밋 시 trie 데이터베이스로 전달되어 상태 관리 최적화에 사용됩니다.

## 데이터베이스 통합

StateDB는 `core/state/database.go`의 `Database` 인터페이스를 통해 trie 데이터베이스와 통합됩니다. 해시 기반 스키마와 경로 기반(PBSS) 스키마를 모두 지원합니다.

### 데이터베이스 구성

| 설정               | 기본값        | 설명                 |
| ---------------- | ---------- | ------------------ |
| `StateScheme`    | HashScheme | 상태 저장 스키마          |
| `TrieCleanLimit` | 256 MB     | Clean 캐시 크기        |
| `TrieDirtyLimit` | 256 MB     | Dirty 캐시 크기        |
| `SnapshotLimit`  | 256 MB     | 스냅샷 캐시 크기          |
| `Preimages`      | false      | Trie 키 프리이미지 저장 여부 |
| `StateHistory`   | 0          | 상태 히스토리 보관 블록 수    |

주요 인터페이스 메서드:

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

## 상태 프리페칭

상태 프리페칭은 블록 실행 중 필요한 trie 노드를 사전에 로드하는 최적화 기법입니다.\
`StartPrefetcher()`로 시작되고 `StopPrefetcher()`로 종료됩니다.

프리페처는 트랜잭션이 접근할 계정과 저장소 슬롯을 예측하여 캐시에 적재함으로써, 디스크 I/O 대기를 줄이고 블록 처리 성능을 향상시킵니다.

## 성능 메트릭

StateDB는 상태 관리 성능을 모니터링하기 위해 다음 메트릭을 수집합니다:

* 계정 및 저장소 읽기/쓰기/커밋 시간
* 스냅샷 조회 및 커밋 시간
* Trie 데이터베이스 커밋 시간
* 변경된 계정 및 저장소 슬롯 수

이 메트릭은 노드 운영자가 상태 처리 병목을 분석하고 성능을 튜닝하는 데 활용됩니다.
