· 6분 읽기
Celestia 데이터 구조와 저장 전략: ODS, EDS, ODSQ4
Celestia에서 블록 데이터는 곧바로 EDS(Extended Data Square)가 되지 않습니다. 트랜잭션 배열은 먼저 ODS(Original Data Square)로 정리된 뒤, 2차원 Reed-Solomon 확장을 거쳐 EDS가 됩니다. 이 글은 ODS 생성 파이프라인, EDS의 Q1~Q4 구조, 실제 저장 용량 계산과 윈도우별 저장 전략, 그리고 이를 구현하는 store/file 패키지 구조까지 데이터 구조와 스토리지 관점에서 정리합니다. 검증(DAS·NMT) 관점은 자매 글 Celestia 데이터 가용성 검증: 해시의 한계에서 DAS와 NMT까지에서 다룹니다.
트랜잭션 배열을 ODS로 변환하는 파이프라인
변환은 다섯 단계로 이루어집니다.
- 트랜잭션 분류
- Share 분할
- 네임스페이스 정렬
- 패딩 적용
- 정사각형 배치(ODS 생성)
1) 트랜잭션 분류
일반 트랜잭션과 PFB(PayForBlob)를 분리해 처리합니다. blob 데이터는 별도 경로로 배치됩니다.
2) Share 분할
- Compact share: 일반 트랜잭션/PFB
- Sparse share: blob
데이터 타입별로 인코딩 단위를 분리해 배치 효율을 높입니다.
3) 네임스페이스 정렬
Celestia는 네임스페이스 기반 검증을 지원하므로, share를 배치하는 단계에서 정렬 규칙이 중요합니다. 이 정렬 규칙이 뒤에서 다룰 NMT 기반 증명의 전제가 됩니다.
4) 패딩과 square size
최종 ODS는 2의 거듭제곱 크기의 정사각형이 되어야 하며, 부족한 영역은 정해진 규칙에 따라 패딩합니다.
실무 포인트
- max square size를 네트워크·메모리 한계와 함께 관리합니다.
- 패딩 비율이 높으면 데이터 배치 정책을 재검토합니다.
- 네임스페이스 정렬 규칙 변경은 하위 호환 영향을 검토해야 합니다.
ODS 생성은 단순한 포맷 변환이 아니라, 이후 DAS 샘플링과 증명 효율을 결정하는 전처리 단계입니다.
EDS: 2D Reed-Solomon 확장과 Q1~Q4 구조
EDS는 Celestia 데이터 가용성 설계의 중심입니다. ODS를 2차원 Reed-Solomon으로 확장해, 일부가 누락되어도 복구할 수 있는 구조를 만듭니다.
EDS는 네 개의 사분면으로 구성됩니다.
- Q1: 원본 데이터(ODS)
- Q2: 행 패리티
- Q3: 열 패리티
- Q4: 행+열 패리티
이 구조 덕분에 샘플링과 복구가 동시에 가능해집니다.
왜 2D 인코딩인가
- 단순 복제보다 저장 효율이 높습니다.
- 누락 패턴이 생겨도 복구 성공 가능성이 커집니다.
- DAS와 결합할 때 탐지와 복구의 균형이 좋습니다.
저장 용량 계산과 윈도우별 저장 전략
전체 EDS 용량(이론값)
전체 EDS는 원본 데이터의 4배 크기를 차지합니다. Q1(원본, 100%), Q2(행 패리티, 100%), Q3(열 패리티, 100%), Q4(행+열 패리티, 100%)를 모두 저장한다면 원본 크기의 4배가 필요합니다.
실제 저장 전략
Celestia는 실제로 모든 사분면을 항상 저장하지 않고, 다음 두 가지 전략을 상황에 맞춰 사용합니다.
- ODS만 저장(원본 데이터만): 원본 데이터의 1배 용량을 사용합니다. 오래된 블록이나 아카이브 목적의 저장에 쓰이며, 필요하면 나머지 사분면(Q2, Q3, Q4)은 계산으로 복구할 수 있습니다.
- ODSQ4 저장(원본 + Q4 사분면): 원본 데이터의 2배 용량을 사용합니다. 가용성 윈도우 내의 최근 블록에 사용되며, 특정 접근 패턴에서 계산 효율성이 향상됩니다.
실제 코드에서는 가용성 윈도우 여부에 따라 저장 전략을 분기합니다.
// 가용성 윈도우 내의 블록은 ODS와 Q4 모두 저장 (원본의 2배)
if availability.IsWithinWindow(eh.Time(), availability.StorageWindow) {
err = store.PutODSQ4(ctx, eh.DAH, eh.Height(), eds)
} else {
// 그 외 블록은 ODS만 저장 (원본의 1배)
err = store.PutODS(ctx, eh.DAH, eh.Height(), eds)
}
저장 공간을 최적화하는 이유
- 디스크 공간 효율성: 모든 블록의 모든 사분면을 저장하는 것은 비효율적이며, 대부분의 경우 원본 데이터만으로도 충분합니다.
- 계산 비용과 저장 비용의 균형: Q2와 Q3는 Q1과 Q4로부터 계산할 수 있으므로 필요할 때만 계산하고, 가장 자주 접근하는 최근 블록에만 Q4를 함께 저장해 계산 비용을 절약합니다.
- 가용성과 검증의 균형: 데이터 가용성 검증은 최근 블록에 대해 더 중요하므로, 최근 블록은 더 많은 공간(ODS+Q4)을 쓰고 오래된 블록은 공간 효율성(ODS만)을 우선합니다.
결론적으로 Celestia는 원본 데이터의 약 1~2배 정도의 저장 공간을 사용하면서도, 데이터 가용성 검증과 복구 기능을 효율적으로 제공합니다. 이 윈도우 경계와 인코딩 실패를 어떻게 다루는지가 실제 운영에서 중요합니다.
체크리스트
- 가용성 윈도우 경계 정책을 명확히 정의합니다.
- EDS 생성 실패 원인을 인코딩/입력 데이터로 분리해 로깅합니다.
- 복구 경로 테스트를 정기적으로 실행합니다.
celestia-node의 store/file 패키지
store/file 패키지는 EDS 저장을 디스크 친화적으로 다루는 핵심 레이어입니다. 핵심 아이디어는 "모든 것을 항상 저장하지 않고, 필요한 형태만 저장한다"는 것입니다.
핵심 데이터 단위
- ODS: 원본 데이터 사각형(Q1)
- EDS: ODS를 확장한 데이터 사각형
- Q4: 복구/샘플링 최적화에 쓰이는 사분면
저장 전략
- ODS 저장: 저장량이 작습니다(대략 EDS 대비 1/4). 오래된 블록이나 아카이브에 유리합니다.
- ODSQ4 저장: ODS + Q4를 저장합니다(대략 EDS 대비 1/2). 최근 블록의 샘플링/복구에서 계산 부담을 줄입니다.
시간축에 따라 저장 정책을 다르게 가져가 디스크와 CPU를 균형화하는 방식입니다.
코드 구조의 주요 타입
ODS: 기본 접근자/스트리머 구현q4: Q4 전용 파일 접근ODSQ4: ODS + Q4 조합 접근자headerV0: 파일 포맷 메타데이터codecCache: Reed-Solomon 인코더 캐시
운영 포인트
- 가용성 윈도우 기준으로 ODS/ODSQ4 정책을 분리합니다.
- Q4는 lazy loading으로 시작 지연을 최소화합니다.
- 파일 크기/해시 검증 실패는 즉시 격리합니다.
- 인코더 캐시 hit율을 모니터링해 CPU 급등을 방지합니다.
이 패키지는 단순 파일 저장소가 아니라, DAS와 복구 비용을 운영 가능한 수준으로 맞추기 위한 스토리지 전략 계층입니다.
정리
트랜잭션 배열은 분류·share 분할·네임스페이스 정렬·패딩을 거쳐 ODS가 되고, ODS는 2D Reed-Solomon 확장을 통해 Q1~Q4 구조의 EDS가 됩니다. 이 구조가 4배의 이론적 저장 비용을 만들지만, Celestia는 가용성 윈도우를 기준으로 최근 블록은 ODSQ4(2배), 오래된 블록은 ODS(1배)만 저장해 실제 비용을 크게 낮춥니다. store/file 패키지는 이 전략을 lazy loading, 인코더 캐시, 즉시 격리 같은 구체적인 장치로 구현한 계층이며, 여기서 확보한 데이터 구조는 자매 글에서 다루는 DAS·NMT 기반 검증의 토대가 됩니다.