목적 및 범위
이 문서는 정식 체인 유지, 블록 삽입, 체인 재구성 처리를 담당하는 블록체인 관리 하위 시스템을 설명합니다.BlockChain과 HeaderChain이 블록 헤더, 본문, 영수증 및 체인 선택에 필요한 메타데이터를 추적하여 체인 상태를 관리하는 방식을 다룹니다.
관련 문서:
- 상태 관리 및 StateDB 아키텍처: 상태 관리
- 트랜잭션 풀 관리: 트랜잭션 풀
- 합의별 블록 봉인: 합의 및 블록 생성
핵심 구조
BlockChain
BlockChain 타입은 정식 블록체인을 관리하는 중앙 컴포넌트입니다. 블록 삽입, 검증, 상태 실행, 체인 재구성을 조정하며, 합의 엔진(consensus.Engine), 포크 선택 로직(ForkChoice), 상태 처리기(Processor), 블록 검증기(Validator)와 협력합니다.
주요 상태로 현재 정식 헤드(currentBlock), 스냅 동기화 기준 블록(currentSnapBlock), 최종화된 블록(currentFinalBlock), 안전 블록(currentSafeBlock)을 추적합니다. 이러한 헤드 포인터는 합의 규칙과 포크 선택 결과에 따라 갱신됩니다.
HeaderChain
HeaderChain은 블록 헤더 저장소와 번호–해시 매핑을 관리하는 경량 체인 구조입니다. 헤더 단위 검증과 체인 탐색을 담당하며, 헤더 체인 재구성과 정식 헤더 매핑 갱신을 조정합니다. 전체 블록 삽입은 BlockChain이 담당하며, HeaderChain은 그 하위 구성 요소로 사용됩니다.
정식 체인 관리
정식 체인은 노드가 따르는 공식 체인 경로를 의미합니다. 블록체인은 다음 두 가지 핵심 매핑을 유지합니다:- 번호 → 해시: 특정 블록 번호에 대응하는 정식 블록 해시
- 해시 → 번호: 특정 블록 해시에 대응하는 블록 번호
초기화 시 상태 로딩
초기화 중loadLastState() 메서드는 디스크에서 체인 상태를 복원합니다:
- 데이터베이스에서 마지막 헤드 블록 해시 읽기
- 해시를 통해 헤드 블록 로드
- 현재 블록(
currentBlock) 설정 - 헤더 체인 헤드 로드
- 스냅 기준 블록 및 최종화 블록 로드
블록 삽입 파이프라인
블록 삽입은 검증, 실행, 정식 체인 업데이트를 포함하는 다단계 프로세스입니다.삽입 흐름 요약
InsertChain() 메서드는 블록 배치를 삽입하는 주요 진입점이며, 내부적으로 다음 단계를 거칩니다:
각 단계 설명
1. 사전 검증- 미래 블록 캐시(
futureBlocks) 확인 - 블록 중복 삽입 여부 확인
- 부모 블록 존재 여부 확인
- 합의 엔진의
VerifyHeader()호출 - WBFT의 경우 제안자, 서명, 검증자 세트 정합성 검증
- 블록 번호, 타임스탬프, 가스 한도 규칙 확인
ValidateBody()호출- 트랜잭션 루트 해시와 헤더 일치 여부 확인
- WBFT 환경에서는 엉클 블록이 존재하지 않음을 검증
- 부모 블록 상태를 기반으로 StateDB 생성
- 각 트랜잭션에 대해
ApplyTransaction()호출하여 EVM 실행 - 영수증 및 사용 가스 누적
ValidateState()호출- 가스 사용량, 영수증 블룸, 상태 루트 검증
- 블록과 영수증을 데이터베이스에 기록
- 상태 trie 커밋 및 스냅샷 갱신
- 합의 엔진과 포크 선택 규칙에 따라 새 블록의 우선순위 평가
- 필요 시 체인 재구성 수행
ChainEvent,ChainHeadEvent발생- 로그 및 트랜잭션 풀에 새 헤드 알림 전파
체인 재구성
체인 재구성(reorg)은 포크 선택 규칙에 따라 기존 정식 체인보다 우선하는 체인이 등장할 경우 발생합니다. StableNet의 WBFT 환경에서는 총 난이도 대신 합의 규칙과 에포크 기반 검증자 합의 결과가 체인 선택의 기준이 됩니다.재구성 프로세스
- 포크 선택 결정:
ForkChoice로직이 새 블록의 정식 체인 채택 여부 판단 - 공통 조상 탐색: 기존 체인과 새 체인의 분기점 탐색
- 정식 매핑 갱신:
HeaderChain.Reorg()를 통해 번호–해시 매핑 갱신 - 헤드 포인터 갱신:
currentBlock,currentFinalBlock,currentSafeBlock업데이트
HeaderChain.Reorg()의 주요 동작은 다음과 같습니다:
- 부모가 현재 헤드인 경우 단순 확장
- 기존 정식 매핑 중 교체 대상 제거
- 공통 조상까지 역추적하며 매핑 재작성
- 새 체인의 헤더를 정식 체인으로 기록
- 헤드 헤더 해시를 데이터베이스에 저장
캐싱
블록체인은 LRU 캐시를 사용하여 디스크 접근을 최소화합니다:| 캐시 | 크기 | 용도 |
|---|---|---|
bodyCache | 256 | 블록 본문 캐시 |
blockCache | 256 | 완전한 블록 캐시 |
receiptsCache | 32 | 트랜잭션 영수증 캐시 |
txLookupCache | 1024 | 트랜잭션 위치 조회 |
futureBlocks | 256 | 미래 시점 블록 임시 보관 |
체인 복구
SetHead
SetHead() 메서드는 체인을 특정 블록 번호까지 되돌립니다. 주요 사용 사례는 다음과 같습니다:
- 손상된 블록 이후 상태 복구
- 알려진 문제 블록 우회
- 체인 규칙 변경 후 재동기화
Reset
Reset()은 전체 체인 데이터를 제거하고 제네시스 블록 상태로 복원합니다.
SnapSyncCommitHead
스냅 동기화 완료 시 호출되어 동기화된 블록을 정식 헤드로 설정합니다:- 블록 존재 여부 확인
- 상태 저장소 활성화
- 상태 trie 접근 가능성 검증
- 현재 블록 포인터 갱신
- 스냅샷 구조 재구성
데이터베이스 스키마
블록 저장소 키
| 키 패턴 | 값 타입 | 용도 |
|---|---|---|
h{num}n | common.Hash | 블록 번호의 정식 해시 |
h{hash}n | uint64 | 해시의 블록 번호 |
H{hash}{num} | *types.Header | 블록 헤더 |
b{hash}{num} | *types.Body | 블록 본문 |
r{hash}{num} | []*types.Receipt | 트랜잭션 영수증 |
체인 상태 키
| 키 | 용도 |
|---|---|
LastBlock | 정식 블록 헤드 해시 |
LastHeader | 정식 헤더 헤드 해시 |
LastFast | 스냅 기준 블록 해시 |
LastFinalized | 최종화 블록 해시 |
SnapshotRoot | 스냅샷 루트 |
오류 처리
| 오류 | 조건 | 처리 방식 |
|---|---|---|
ErrKnownBlock | 이미 처리된 블록 | 무시 |
ErrNoGenesis | 제네시스 누락 | 초기화 필요 |
ErrBannedHash | 차단된 블록 해시 | 체인 되돌리기 |
ErrUnknownAncestor | 부모 블록 없음 | 피어에서 요청 |
ErrPrunedAncestor | 부모 상태 프루닝됨 | 스냅 동기화 필요 |
errInsertionInterrupted | 삽입 중단 | 현재 삽입 중지 |

