> ## 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 노드 및 검증자 인프라를 배포하고 운영하며 유지 관리하기 위한 운영 지침을 제공합니다. 네트워크 배포 절차, 검증자 운영 방법, 노드 유지 관리 전반을 다룹니다.

시스템 아키텍처 및 컴포넌트 설계에 대한 내용은 Core Architecture를 참고하세요. 합의 프로토콜의 세부 동작은 Anzeon WBFT Consensus Protocol을, 거버넌스 컨트랙트 사용 방법은 Governance System 문서를 참조하세요.

## 네트워크 배포

### 제네시스 파일 생성

StableNet 네트워크는 `genesis_generator` 도구로 생성된 제네시스 파일을 사용하여 초기화됩니다. 해당 도구는 Anzeon 합의 매개변수와 시스템 컨트랙트를 포함한 제네시스 블록을 생성합니다.

```text theme={null}
```

### 제네시스 구성 매개변수

StableNet의 제네시스 구성은 `anzeon` 섹션에서 합의 및 거버넌스와 관련된 전용 매개변수를 정의해야 합니다.

| Parameter                    | Location                            | Description                                 |
| ---------------------------- | ----------------------------------- | ------------------------------------------- |
| `wbft.epochLength`           | `anzeon.wbft.epochLength`           | Number of blocks per epoch (default: 10)    |
| `wbft.blockPeriodSeconds`    | `anzeon.wbft.blockPeriodSeconds`    | Target block time in seconds (default: 1)   |
| `wbft.requestTimeoutSeconds` | `anzeon.wbft.requestTimeoutSeconds` | Consensus timeout in seconds (default: 2)   |
| `wbft.proposerPolicy`        | `anzeon.wbft.proposerPolicy`        | Proposer selection policy (0 = round-robin) |
| `init.validators`            | `anzeon.init.validators`            | Initial validator addresses for first epoch |
| `init.blsPublicKeys`         | `anzeon.init.blsPublicKeys`         | BLS public keys for each validator          |
| `systemContracts`            | `anzeon.systemContracts`            | Configuration for system contracts          |

### 시스템 컨트랙트 초기화

각 시스템 컨트랙트는 제네시스 단계에서 초기화 매개변수를 통해 구성됩니다.
아래는 주요 시스템 컨트랙트별 초기화 매개변수 목록입니다.

**GovValidator** (주소: `0x0000000000000000000000000000000000001001`)

* `members`: 쉼표로 구분된 운영자 주소 목록
* `validators`: 쉼표로 구분된 검증자 주소 목록
* `blsPublicKeys`: 검증자 BLS 공개 키 목록 (validators 순서와 동일)
* `quorum`: 거버넌스 작업을 승인하기 위한 최소 투표 수
* `expiry`: 거버넌스 제안 만료 시간 (초 단위, 기본값: 604800 = 7일)
* `gasTip`: 일반 계정 트랜잭션에 적용되는 가스 팁 (wei 단위)

**NativeCoinAdapter** (주소: `0x0000000000000000000000000000000000001000`)

* `name`: 네이티브 토큰 이름 (예: `"WKRC"`)
* `symbol`: 네이티브 토큰 심볼 (예: `"WKRC"`)
* `decimals`: 토큰 소수점 자리 수 (일반적으로 `18`)
* `currency`: 토큰이 페그된 법정화폐 코드 (예: `"KRW"`)
* `masterMinter`: GovMasterMinter 컨트랙트 주소
* `minters`: 민팅 권한을 가진 컨트랙트 주소 목록 (쉼표 구분)

### 부트노드 구성

StableNet 네트워크는 피어 발견을 위해 부트노드를 사용합니다. 부트노드는 실행 시 `--bootnodes` 플래그를 통해 지정하거나, 구성 파일에 설정하여 사용할 수 있습니다.

**부트노드 사용 예시 (`--bootnodes` 플래그 사용)**

```
--bootnodes enode://722f1f35c6fe2ac829aa9e0d7ef55bbe782ef3cea1e2354eefbe1584057a01b7@127.0.0.1:8589,enode://aa46e4a40781022e480bb05d1fd578fff164dc2ad379dc00370456c5ce9c2479@127.0.0.1:8589
```

부트노드는 다음 우선순위에 따라 선택됩니다.

1. `--bootnodes` 플래그로 명시적으로 지정된 값
2. 구성 파일에 정의된 `BootstrapNodes`
3. 네트워크 사전 설정 플래그 (`--mainnet`, `--testnet`)
4. 기본 Mainnet 부트노드 설정

### 네트워크 플래그 및 구성

StableNet 네트워크를 배포하고 실행하기 위해 다음과 같은 주요 명령줄 플래그를 사용합니다.

| Flag           | Purpose                                      | Default          |
| -------------- | -------------------------------------------- | ---------------- |
| `--datadir`    | Data directory for databases and keystore    | `~/.stable`      |
| `--mainnet`    | StableNet mainnet                            | -                |
| `--testnet`    | StableNet test network                       | -                |
| `--networkid`  | Network ID (auto-detects from chain ID if 0) | 0                |
| `--port`       | P2P listening port                           | 30303            |
| `--bootnodes`  | Comma-separated enode URLs for bootstrap     | Network-specific |
| `--maxpeers`   | Maximum number of network peers              | 50               |
| `--nodiscover` | Disable peer discovery mechanism             | false            |
| `--nat`        | NAT port mapping mechanism                   | "any"            |

## 검증자 운영

### 검증자 키 구조

StableNet 검증자는 합의 및 거버넌스 시스템에 참여하기 위해 각각 다른 역할을 수행하는 세 가지 암호화 키를 사용합니다.

### 키 생성 및 관리

#### ECDSA 키

ECDSA 키는 표준 Ethereum 키스토어 형식을 사용하여 생성 및 관리합니다.

```bash theme={null}
# Generate operator key (for governance)
gstable account new --datadir /data/validator1

# Generate validator key (for block signing)
gstable account new --datadir /data/validator1 --keystore /data/validator1/validator-keystore

# Import existing private key
gstable account import private.key --datadir /data/validator1
```

공개키 주소는 노드의 etherbase(coinbase)로 설정되며, GovValidator.validators에 등록된 주소와 반드시 일치해야 합니다.

#### BLS 키 파생

BLS 키는 검증자의 ECDSA 개인 키로부터 결정적으로 파생됩니다. 이를 통해 동일한 ECDSA 개인 키에 대해 항상 동일한 BLS 키가 생성됩니다.

```go theme={null}
// Derive BLS key from ECDSA private key
blsKey, err := bls.DeriveFromECDSA(ecdsaPrivateKey)
if err != nil {
    log.Fatal("Failed to derive BLS key", "err", err)
}
blsPublicKey := blsKey.PublicKey()
```

파생된 BLS 공개 키는 검증자 주소와 동일한 인덱스에 위치하도록 GovValidator.blsPublicKeys에 등록되어야 합니다.

### 검증자 등록

검증자는 거버넌스 제안을 통해 `GovValidator` 컨트랙트에 등록됩니다. 등록이 완료된 검증자만 합의 및 블록 제안에 참여할 수 있습니다.

### 검증자 노드 시작

다음은 마이닝이 활성화된 검증자 노드를 시작하는 예시입니다.

```bash theme={null}
gstable \
    --datadir /data/validator1 \
    --networkid 8282 \
    --mine \
    --miner.etherbase 0xYOUR_VALIDATOR_ADDRESS
```

**주요 검증자 플래그:**

| Flag                | Purpose                      |
| ------------------- | ---------------------------- |
| `--mine`            | Enable block production      |
| `--miner.etherbase` | Validator address (coinbase) |

### 검증자 마이닝 프로세스

검증자 노드가 마이닝을 시작하면 다음과 같은 초기화 절차가 수행됩니다.

1. **검증자 상태 로드**
   * 제네시스 및 최신 블록 상태를 기준으로 `GovValidator` 컨트랙트에 등록된 검증자 목록을 로드합니다.
   * 현재 노드의 etherbase(coinbase)가 활성 검증자 집합에 포함되어 있는지 확인합니다.

2. **검증자 키 검증**
   * 합의 메시지 서명에 사용되는 키에서 파생된 주소가 etherbase 주소와 일치하는지 검증합니다.
   * 해당 검증자에 대응하는 BLS 공개 키가 `GovValidator.blsPublicKeys`에 올바르게 등록되어 있는지 확인합니다.

3. **WBFT 합의 엔진 초기화**
   * 제네시스에 정의된 Anzeon WBFT 매개변수(epoch length, block period, timeout 등)를 로드합니다.
   * 현재 블록 높이에 해당하는 WBFT 설정을 적용하여 합의 엔진을 초기화합니다.

4. **검증자 역할 결정**
   * 현재 라운드와 proposer 정책에 따라 본 노드가 proposer인지 여부를 판단합니다.
   * proposer로 선택된 경우 블록 제안을 준비합니다.

5. **합의 메시지 처리 시작**
   * 합의 메시지 수신을 위한 네트워크 핸들러를 활성화합니다.
   * 합의 단계별 서명 생성 및 검증 로직을 준비합니다 (BLS 서명 집계 포함).

6. **블록 생성 및 합의 참여**
   * proposer인 경우 WBFTExtra를 포함한 블록을 제안합니다.
   * proposer가 아닌 경우 제안된 블록을 검증하고, 합의 단계에 따라 서명된 메시지를 전파합니다.

### 가스 팁 정책

StableNet에서는 일반 계정의 가스 팁(우선순위 수수료)을 거버넌스 투표를 통해 관리하며, 해당 값은 `GovValidator` 컨트랙트에 저장됩니다.
가스 팁 정책은 계정 유형에 따라 다음과 같이 적용됩니다.

#### 인증 계정 (Authorized Account)

인증 계정은 기존 Ethereum과 동일한 방식으로 트랜잭션별 `maxPriorityFeePerGas` 값을 직접 지정하여 사용합니다.

* 트랜잭션마다 개별 가스 팁 설정 가능
* 설정된 `maxPriorityFeePerGas` 값이 실제 우선순위 수수료로 적용됨
* 네트워크 혼잡 시 경쟁적 우선순위 지정 가능
* 거버넌스에서 정의된 고정 가스 팁 정책의 적용을 받지 않음

#### 일반 계정 (Non-Authorized Account)

일반 계정 역시 트랜잭션마다 `maxPriorityFeePerGas` 값을 설정할 수 있으나, 해당 값은 **실제 가스 팁 결정에는 사용되지 않습니다.**

* 트랜잭션에 설정된 `maxPriorityFeePerGas` 값과 관계없이 거버넌스에서 정의된 **고정 가스 팁**이 실제 우선순위 수수료로 적용됨
* 트랜잭션에 설정된 가스 팁 값은 **트랜잭션 교체(replacement) 판단을 위한 용도로만 사용됨**
* 고정 가스 팁 미만의 트랜잭션은 트랜잭션 풀에서 필터링됨

#### 가스 팁 업데이트

* 검증자는 거버넌스 제안을 통해 새로운 고정 가스 팁 값을 제안할 수 있습니다.
* 제안은 정족수 승인을 거쳐야 하며, 승인 및 실행 시점부터 즉시 적용됩니다.

### 에포크 전환

StableNet은 에포크(epoch) 단위로 동작하며, 검증자 세트 변경은 에포크 블록에서만 적용됩니다.

**주요 사항:**

* 에포크 길이는 `anzeon.wbft.epochLength`로 구성되며, 기본값은 10블록입니다.
* 에포크 N 동안 제안 및 승인된 검증자 세트 변경 사항은 에포크 N+1 시작 시점부터 적용됩니다.
* 첫 번째 에포크의 검증자 세트는 제네시스에 정의된 `anzeon.init.validators`를 사용합니다.
* 이후 에포크의 검증자 세트는 `GovValidator.validators` 배열을 기준으로 로드됩니다.

### 거버넌스 참여

검증자는 운영 키(operator key)를 사용하여 거버넌스에 참여합니다.
거버넌스는 제안과 투표를 통해 네트워크 설정과 검증자 세트를 관리합니다.

#### 제안 타입

* `ADD_VALIDATOR`: 검증자 세트에 새로운 검증자를 추가
* `REMOVE_VALIDATOR`: 검증자 세트에서 기존 검증자를 제거
* `SET_GAS_TIP`: 필수 가스 팁 값 업데이트
* `CONFIGURE_SYSTEM`: 시스템 매개변수 및 설정 변경

#### 투표 프로세스

* 모든 거버넌스 구성원은 컨트랙트 호출을 통해 제안을 생성할 수 있습니다.
* 다른 구성원은 `vote(proposalId, approve)` 호출을 통해 제안에 대해 찬성 또는 반대 투표를 수행합니다.
* 제안이 정족수에 도달하면 자동으로 실행됩니다.
* 제안은 설정된 만료 기간(기본값: 7일)이 경과하면 만료됩니다.

## 노드 모니터링 및 유지 관리

### 로깅 구성

StableNet 노드는 여러 수준의 로그 상세도를 지원하는 구조화된 로깅 시스템을 사용합니다.
운영 환경에 따라 전역 로그 레벨, 모듈별 로그 레벨, 로그 출력 형식을 구성할 수 있습니다.

```bash theme={null}
# 전역 로그 레벨 설정
gstable --verbosity 3  # 0=silent, 1=error, 2=warn, 3=info, 4=debug, 5=trace

# 모듈별 로그 레벨 설정
gstable --vmodule "consensus/*=5,miner=4,eth/*=3"

# 파일 로그 출력 및 로테이션
gstable --log.file /var/log/gstable/node.log --log.rotate

# 로그 수집을 위한 JSON 포맷 출력
gstable --log.json
```

**모니터링할 주요 로그 모듈:**

| Module            | Purpose          | Important Events                                      |
| ----------------- | ---------------- | ----------------------------------------------------- |
| `consensus/wbft`  | WBFT consensus   | Round changes, validator proposals, commit messages   |
| `miner`           | Block production | Block sealing, transaction inclusion, gas tip updates |
| `eth/handler`     | Chain sync       | Peer connections, block propagation, sync progress    |
| `core/blockchain` | Chain processing | Block insertion, reorgs, state root mismatches        |
| `eth/downloader`  | Sync progress    | Sync mode, peer selection, download rates             |

### 메트릭 및 모니터링

StableNet 노드는 운영 가시성을 확보하기 위해
메트릭 수집 및 외부 모니터링 시스템 연동을 지원합니다.
메트릭 서버를 활성화하거나 InfluxDB와 같은 외부 저장소로
메트릭을 전송할 수 있습니다.

```bash theme={null}
# 메트릭 서버 활성화
gstable --metrics --metrics.addr 0.0.0.0 --metrics.port 6060

# InfluxDB 메트릭 전송 활성화
gstable \
    --metrics.influxdb \
    --metrics.influxdb.endpoint http://influxdb:8086 \
    --metrics.influxdb.database gstable \
    --metrics.influxdb.username monitor \
    --metrics.influxdb.password secret
```

### 디스크 공간 관리

StableNet 노드는 블록체인 데이터를 저장하기 위해 상당한 디스크 공간을 사용합니다.
안정적인 운영을 위해 디스크 사용량을 지속적으로 모니터링하고, 필요 시 자동 보호 동작을 구성할 수 있습니다.

#### 최소 여유 디스크 공간

디스크 공간 부족으로 인한 데이터 손상을 방지하기 위해,최소 여유 디스크 공간 기준을 설정할 수 있습니다.
설정된 임계값 미만으로 여유 공간이 감소할 경우노드는 자동으로 종료됩니다.

```bash theme={null}
# 최소 여유 디스크 공간 설정 (MB 단위)
gstable --datadir.minfreedisk 50000  # 여유 공간이 50GB 미만일 경우 종료
```

노드는 주기적으로 사용 가능한 디스크 공간을 확인하며, 설정된 임계값에 도달할 경우 데이터베이스 손상을 방지하기 위해 정상 종료를 수행합니다.

#### 데이터베이스 크기 모니터링

StableNet 노드는 동기화 모드 및 프루닝 구성에 따라 데이터베이스 사용량이 달라집니다.
아래 표는 일반적인 구성별 데이터베이스 크기와 월별 예상 증가량을 나타냅니다.

| Configuration       | Approximate Size | Growth Rate   |
| ------------------- | ---------------- | ------------- |
| Full node (archive) | 500+ GB          | \~30 GB/month |
| Full node (pruned)  | 150–200 GB       | \~10 GB/month |
| Snap sync           | 100–150 GB       | \~8 GB/month  |

운영 환경에서는 다음 디렉터리의 디스크 사용량을
지속적으로 모니터링해야 합니다.

* `chaindata/`: 메인 블록체인 상태 및 블록 데이터베이스
* `ancient/`: 오래된 블록 데이터를 저장하는 프리저 디렉터리 (별도 구성 시)
* `blobpool/`: Blob 트랜잭션 풀 관련 데이터
* `ethash/`: Ethash 합의 사용 시 DAG 파일 저장소

#### 프루닝 및 가비지 컬렉션

해시 스키마 상태 저장소를 사용하는 경우, 프루닝 및 가비지 컬렉션 동작을 구성하여 데이터베이스 크기와 디스크 사용량을 제어할 수 있습니다.

```bash theme={null}
# Archive 모드 (프루닝 비활성화)
gstable --gcmode archive --cache.gc 0

# Full 모드 (프루닝 활성화)
gstable --gcmode full --cache.gc 25  # 캐시의 25%를 GC에 사용
```

참고: 경로 스키마 데이터베이스는 자동 프루닝을 사용하며 수동 가비지 컬렉션 제어를 지원하지 않습니다.

### 데이터베이스 유지 관리

#### 상태 스키마 선택

StableNet은 두 가지 상태 저장소 스키마를 지원하며, 노드의 운영 목적에 따라 적절한 스키마를 선택할 수 있습니다.

```bash theme={null}
# Hash-based scheme (traditional)
gstable --state.scheme hash

# Path-based scheme (recommended for new nodes)
gstable --state.scheme path
```

**경로 스키마의 장점:**

* 상태 데이터가 자동으로 프루닝됨
* 디스크 사용량이 상대적으로 낮음
* 동기화 성능이 우수함

**해시 스키마 장점:**

* 구조가 성숙하고 충분히 검증됨
* 프루닝 및 가비지 컬렉션을 수동으로 제어 가능
* 오프라인 프루닝 도구 사용이 필요한 환경에 적합

#### 오프라인 프루닝 복구

해시 스키마를 사용하는 노드는 중단된 프루닝 작업이 감지될 경우 노드 시작 시 자동으로 복구 절차를 수행합니다.

```go theme={null}
// Automatic recovery at startup
if scheme == rawdb.HashScheme {
    if err := pruner.RecoverPruning(stack.ResolvePath(""), chainDb); err != nil {
        log.Error("Failed to recover state", "error", err)
    }
}
```

이 복구 과정은 노드 시작 중에 자동으로 실행되며, 프루닝이 비정상적으로 중단된 경우 데이터베이스를 일관된 상태로 복원합니다.

### 체인 복구 및 SetHead

블록체인 상태가 손상되었거나 특정 시점으로 되돌려야 하는 경우 `debug_setHead` RPC 메서드를 사용하여 체인 헤드를 재설정할 수 있습니다.

```bash theme={null}
# 특정 블록 번호로 되돌리기
gstable attach /data/gstable.ipc --exec 'debug.setHead("0x10000")'  # 블록 65536으로 이동

# 블록 수 기준으로 되돌리기
gstable attach /data/gstable.ipc --exec 'debug.setHead("0x-100")'  # 현재 위치에서 256블록 이전으로 이동
```

**사용 사례:**

* 손상된 블록 데이터로부터 복구
* 체인 이상 감지 후 이전 상태로 롤백
* 네트워크 분할 이후 올바른 포크로 체인 재구성

**주의:** `setHead`호출은 지정된 지점 이후의 블록과 상태 데이터를 삭제합니다. 실행 전에 반드시 백업이 존재하는지 확인하고, 동작의 영향을 충분히 이해한 상태에서 사용해야 합니다.

### 노드 업그레이드 절차

노드 업그레이드는 아래 절차에 따라 순차적으로 수행합니다.

1. **노드 중지**
   * 실행 중인 `gstable` 노드를 정상적으로 종료합니다.

2. **바이너리 교체**
   * 기존 바이너리를 백업한 후, 새 버전의 `gstable` 바이너리로 교체합니다.
   * 실행 권한 및 경로 설정이 올바른지 확인합니다.

3. **구성 파일 확인**
   * 새로운 버전에서 추가되거나 변경된 설정 항목이 있는지 확인합니다.
   * 기존 구성 파일과의 호환성을 검토하고 필요한 경우 값을 보완합니다.

4. **노드 재시작**
   * 기존과 동일한 옵션으로 노드를 재시작합니다.
   * 검증자 노드의 경우 `--mine` 옵션이 포함되었는지 확인합니다.

5. **초기 로그 확인**
   * 노드 시작 직후 로그를 확인하여 데이터베이스 마이그레이션, 합의 엔진 초기화, 네트워크 연결 과정에서 오류가 발생하지 않았는지 점검합니다.

**업그레이드 전 체크리스트:**

* 변경 사항에 대한 릴리스 노트 검토
* 데이터베이스 백업 (`chaindata/` 디렉터리)
* 중요하지 않은 노드에서 업그레이드 사전 테스트
* 검증자 노드의 경우 계획된 다운타임을 피어에 사전 공지

**업그레이드 후 검증:**

```bash theme={null}
# 노드 버전 확인
gstable version

# 데이터베이스 버전 확인
gstable --datadir /data version-check

# 동기화 상태 확인
gstable attach --exec 'eth.syncing'

# 피어 연결 상태 확인
gstable attach --exec 'admin.peers.length'

# 검증자 노드의 경우 마이닝 상태 확인
gstable attach --exec 'eth.mining'
```

### 비정상 종료 감지

StableNet 노드는 이전 실행에서의 비정상 종료 여부를 데이터베이스 상태를 기반으로 간접적으로 판단하여 노드 시작 시 데이터베이스 복구 메커니즘이 자동으로 수행됩니다.

#### 비정상 종료 처리 방식

* 노드 시작 시 LevelDB의 WAL(Write-Ahead Log)을 통해 이전 실행에서 미완료된 쓰기 작업을 자동으로 복구합니다.
* 상태 데이터베이스, 스냅샷, freezer(ancient) 데이터 간의 정합성을 검사하고, 필요 시 내부 복구 로직을 수행합니다.
* 데이터베이스가 일관된 상태로 복구되지 않을 경우 동기화 또는 상태 재구성이 트리거될 수 있습니다.

**비정상 종료 후 수동 복구:**

자동 복구 이후에도 데이터베이스 이상이 의심되는 경우, 다음 명령을 사용하여 수동 점검 및 복구 작업을 수행할 수 있습니다.

```bash theme={null}
# 데이터베이스 무결성 확인
gstable --datadir /data verify-db

# 필요한 경우 인덱스 재구성
gstable --datadir /data rebuild-indexes
```

### 부트노드 운영

StableNet 네트워크의 피어 발견을 위해 전용 부트노드를 실행할 수 있습니다.

```bash theme={null}
# 부트노드 키 생성
bootnode --genkey=boot.key

# 부트노드 실행
bootnode \
    --nodekey=boot.key \
    --addr=:30303 \
    --netrestrict=0.0.0.0/0 \
    --verbosity=3

# enode URL 출력
bootnode --nodekey=boot.key --writeaddress
```

부트노드는 전체 노드를 실행하지 않고 피어 발견을 위한 경량 서비스만 제공하며, 클라이언트는 다음과 같이 부트노드를 지정하여 사용하도록 구성할 수 있습니다.

```bash theme={null}
gstable --bootnodes enode://[nodekey-pubkey]@[ip]:30303
```

### 네트워크 모니터링 대시보드

검증자 노드의 안정적인 운영을 위해 다음과 같은 모니터링 지표를 대시보드에 구성하는 것을 권장합니다.

**검증자용 주요 성능 지표(KPI)**

| Metric                | Target           | Alert Threshold    |
| --------------------- | ---------------- | ------------------ |
| Block production rate | \~1 block/second | \< 0.9 blocks/sec  |
| Missed blocks         | 0%               | > 1%               |
| Peer count            | 10–50            | \< 5 peers         |
| Sync delay            | \< 2 blocks      | > 10 blocks behind |
| Disk free space       | > 100 GB         | \< 50 GB           |
| Memory usage          | \< 80%           | > 90%              |
| CPU usage             | \< 50%           | > 80% sustained    |
