Phase4 P2 — 연합체인 Merkle root 누적 공시 + 포함증명
개요
연합 게이트웨이의 노드 등록 체인(nodes.ndjson)을 RFC 6962 근사 Merkle 트리로
묶어 root 만 서명·공시한다. 노드는 전체 체인 다운로드 없이 자기 등록 블록의
포함을 O(log n) 포함증명(inclusion proof)으로 검증할 수 있다.
라이브 게이트웨이(:8080/:8443/gateway.yaml) 무접촉. 연합 API(:9160)와
연합체인 파일(data/federation-chain/)만 사용.
무엇을 했는지
1. 신규 라이브러리 (ADDITIVE, 자동실행 없음)
/Users/ef/crowny-gateway/한선게이트웨이/크라우니게이트웨이연합머클.한선
연합머클루트()— nodes.ndjson 각 블록hash를 리프로 Merkle 트리 구성 → root 반환연합블록수()— 체인 블록 수연합루트서명(root,count,ts)— HMAC_SHA256(fed-shared.key,root|count|ts)연합루트공시()— root+count+ts+sig 를federation-root.txt에 JSON 한 줄로 기록연합루트공시읽기()— 공시 JSON 읽기(없으면 즉석 공시)포함증명(타깃해시)— 형제 경로 직렬 반환"형제,방향;형제,방향;..."(R=오른쪽 L=왼쪽)증명검증(타깃해시, 증명, root)— 경로 재계산 후 root 일치 시 1, 아니면 0- (헬퍼)
M블록해시목록 M리프목록 M레벨업 M리프해시 M내부해시 M값 M공백정리 M다음세미
2. Merkle 트리 구성 방식 (RFC 6962 근사)
- 리프 해시 =
SHA256("L:" + 블록해시)(RFC6962SHA256(0x00‖data)근사) - 내부 노드 =
SHA256("N:" + 왼 + 오른)(RFC6962SHA256(0x01‖L‖R)근사) - 홀수 레벨 = 마지막 노드 그대로 승격(promote) — 복제 아님 (RFC6962 권장)
- 빈 체인 root =
SHA256("L:EMPTY"), 1블록이면 그 리프 = root - 리프 순서 = 체인 append 순서 (= nodes.ndjson 줄 순서)
- 한선씨 배열 append-only(
추가())만 사용, 맵객체 의존 안 함
3. 포함증명 형식
직렬 문자열:형제해시,방향;형제해시,방향;...
- 방향
R= 형제가 오른쪽 →내부해시(현재, 형제) - 방향
L= 형제가 왼쪽 →내부해시(형제, 현재) - 홀수 promote 레벨에서 형제 없는 노드는 그 레벨 항목 생략
- 검증: 타깃 블록해시 →
리프해시시작 → 경로 따라 재계산 → root 비교
4. 연합 API(:9160) 신규 엔드포인트
/Users/ef/crowny-gateway/한선게이트웨이/크라우니게이트웨이연합API.한선
GET /root — 현재 root 재계산·공시 후 {root,count,ts,sig} 반환GET /proof?hash=<블록해시> — {ok,hash,root,proof,verified,format} 반환경로기본() / 쿼리값() 추가, 처리() 시그니처를 전체경로 기준으로 변경/ 자기설명·기동 로그에 신규 엔드포인트 반영5. 단위검증 진입점 (비파괴)
/Users/ef/crowny-gateway/한선게이트웨이/크라우니게이트웨이연합머클검증.한선
- 임시 체인(
/tmp/_fedm_*) 5블록 등록 → root 계산/공시/포함증명 5/5 PASS - 위조해시 증명 거부 PASS, 교차증명(block0 해시 + block3 증명) 거부 PASS
검증 결과
기동.sh fed-api 재기동 후 실제 4블록 체인 curl:/root → {root:bc19347b..,count:4,ts,sig:83220689..}/proof?hash=eab011..(block0) → proof ..,R;..,R; verified=true/proof?hash=c3e537..(block3) → proof ..,L;..,L; verified=true (같은 root){ok:false,error:"hash not found in chain"}/verify blocks=4 corrupted=false, /health ok관련 파일
/Users/ef/crowny-gateway/한선게이트웨이/크라우니게이트웨이연합머클.한선(신규)/Users/ef/crowny-gateway/한선게이트웨이/크라우니게이트웨이연합머클검증.한선(신규)/Users/ef/crowny-gateway/한선게이트웨이/크라우니게이트웨이연합API.한선(수정: 머클 import + /root + /proof + 쿼리파서)- 데이터:
/Users/ef/crowny-gateway/data/federation-chain/federation-root.txt(신규 공시),nodes.ndjson,fed-shared.key
잔여 이슈 / 인수인계 (메인세션)
- 한선씨 함정 발견:
/proof미발견 404 본문에루트P(함수 반환 해시문자열)를
-2147483647(문자열핸들 오류) 반환.
→ 미발견 응답은 정적 JSON 으로 고정해 회피함. 성공 경로(pj 2문장 분할)는 정상.
근본 원인은 crownyc 문자열핸들 관련으로 추정(누적 아님, 결정적). 추후 VM 측 조사 권장.
- 현재 root 서명키 =
fed-shared.key(부트스트랩 루트키 재사용). 운영 시 별도
/root는 매 호출마다 전체 재계산+공시. 블록 수 증가 시 캐시(헤드해시 기준 무효화) 고려.- 노드 클라이언트 측
포함증명 자체검증헬퍼(원격에서 root 받아 검증)는 동일
증명검증() 으로 가능 — 노드 CLI 통합은 후속.