크라우니클라우드+블록체인 3노드 연동 테스트
개요
크라우니클라우드(9611, 라이브)에 실데이터 왕복 검증, 블록체인 테스트클러스터(3노드, P2P 최소구현 신규 작성) 구축·전파 검증, DEX(9402, 라이브·읽기전용) 이벤트를 체인에 기록해 3노드 전파까지 확인하는 격리 테스트. 라이브 서비스(dex:9402, chain:9729, cloud:9611) kill/재시작 없음, 원본 파일 무수정(전부 /tmp/chain-test/ 사본 작업).
무엇을 했는지
- 크라우니클라우드(9611) 왕복 검증:
/Users/ef/crowny-services/서비스서버.한선의/api/store확인(GET/POST, owner 스코핑 JSON 스냅샷, 512KB 제한).X-Crowny-Owner헤더 폴백 인증으로chaintest01오너에 DEX 백서/감사로그 텍스트 POST 후 GET 재조회 — 바이트 단위 일치. - 블록체인 3노드 테스트 클러스터:
/Users/ef/crowny-chain/서버/크라우니코인.한선(624줄) 구조 파악(블록해시/데이터/시각/채굴자 병렬 배열, WAL 파일 영속화,_WAL줄재생으로 재기동 복원). 이 파일을/tmp/chain-test/base.한선로 복사해 수정 → node1/2/3 각각에 배치:
../libs/체인인증.한선 임포트 제거(사본 상대경로 깨짐 방지, 테스트 목적상 /api/mine 인증 생략 — 원본 라이브는 그대로 인증 필요)
- 포트/_데이터디렉을 환경변수("PORT")/환경변수("DATA_DIR")로 주입해 노드별 독립
- P2P 최소 구현 신규 작성(원본엔 없음): 피어목록 배열 + GET/POST /api/peers(등록·조회) + 블록전파()(채굴 성공 시 등록 피어에 체계(curl -s -m2 ... &)로 새 블록 fire-and-forget gossip — VM에 TCP 클라이언트 내장함수 없어 셸 curl로 구현) + POST /api/receive_block(수신측 height 연속성 체크 후 로컬 체인에 반영, 포크해결 없음)
- 3노드 기동: PORT=9856(9853 충돌 회피)/9854/9855, DATA_DIR 각 노드 독립. 서로
/api/peers에 상호 등록. - DEX↔체인 브릿지:
/tmp/chain-test/dex_bridge.sh— DEX(9402)/api/markets에서 CRN 시세 조회(주문/체결 mempool 비어있어 시세 스냅샷을 이벤트로 사용) → 체인 노드1/api/tx에 기록 →/api/mine채굴로 블록 포함 → 3노드 전파 확인. - 정리: 테스트 노드 3개 프로세스 kill,
ps/lsof로 종료 재확인.
실측 수치
1) 클라우드 왕복 (9611)
- POST
/api/store(X-Crowny-Owner: chaintest01) →{"ok":true}[200] - GET
/api/store→{"test":"dex-audit-log","content":"DEX 백서 감사로그 테스트 1785485059","nodes":[9853,9854,9855]}[200] — POST 본문과 완전 일치
2) 3노드 P2P 전파 (1회차 — 순수 채굴)
- 채굴 전: 3노드 모두
height:1(제네시스만) - node1(9856)
/api/mine호출 →{"height":1,"hash":"e895bbff84a06f52d94dd69bfce581f05b55f29ffbe2328fb784e927b1929783",...}[201] - 3초 후 3노드 모두
height:2동일 확인 /api/block?height=13노드 응답 해시 완전 일치:e895bbff84a06f52d94dd69bfce581f05b55f29ffbe2328fb784e927b1929783
3) DEX→체인→3노드 전파 (2회차 — 브릿지)
- DEX
/api/markets→ CRN price_crd=25.5 확보 - 노드1
/api/txPOST →{"queued":1}[201], mempool 확인count:1 - 노드1
/api/mine(data=dex-event 페이로드) → 해시42d43d8459f65fa7e16ef7bf71bc8b1a8c88c76b7504564795a3fd5d581bc448[201], height 2→3 - 3노드 모두
height:3, totalSupply:81동일 /api/block?height=23노드 응답의 hash·data(dex-event|symbol=CRN|price_crd=25.5|src=dex.crowny.org:9402|ts=1785485829) 완전 일치
4) 프로세스 정리 확인
- kill 대상 PID: 69243(node1) / 54572(node2) / 54648(node3)
- kill 후
ps aux | grep 코인.toau→ 매치 없음 lsof -iTCP:9854,9855,9856 -sTCP:LISTEN→ 리스너 없음(전부 종료 확인)
관련 파일 경로
- 원본(무수정):
/Users/ef/crowny-chain/서버/크라우니코인.한선,/Users/ef/crowny-services/서비스서버.한선,/Users/ef/crowny-chain/libs/체인인증.한선 - 테스트 사본 소스:
/tmp/chain-test/base.한선 - 노드별 사본+컴파일산출물:
/tmp/chain-test/node1/크라우니코인.한선,/tmp/chain-test/node1/코인.toau(node2/node3 동일 패턴) - 노드별 데이터/WAL:
/tmp/chain-test/node{1,2,3}/data/coin-wal.log - 노드 실행 로그:
/tmp/chain-test/node{1,2,3}/run.log,compile.err - DEX 브릿지 스크립트:
/tmp/chain-test/dex_bridge.sh - 컴파일러:
/Users/ef/CrownyOS/crownyc/hanseonc_high,/Users/ef/CrownyOS/crownyc/crownyc
한계 / 잔여 이슈
- 포크 해결 없음:
/api/receive_block은 height 연속성만 체크(다르면 409 반환·폐기), 체인 재구성/최장체인 규칙 미구현. 동시 채굴(양쪽 노드가 거의 동시에 mine) 시 두 블록이 충돌하면 한쪽만 반영되고 재시도 로직 없음. - gossip이 fire-and-forget:
체계(curl ... &)로 비동기 발사만 하고 전달 성공 여부를 체인 레벨에서 재확인/재전송하지 않음(테스트에선sleep후 확인해 성공 관측). 피어 다운 시 유실. - VM에 TCP 클라이언트 내장함수 없음: 순수 한선씨로 아웃바운드 HTTP를 못 짜서
체계(curl)셸 경유로 우회 구현. 향후 정식 P2P는 크라우니VM에 TCP연결(op659 계열, 현재 미배선) 또는 소켓연결 내장함수 확장이 필요. - /api/mine 인증 생략은 사본 한정: 원본 라이브
크라우니코인.한선은체인인증.한선의요청검증(공유키 HMAC)을 그대로 유지 — 이번 변경은 프로덕션에 전혀 반영되지 않음. - 9853 포트 충돌: 배정받은 9853이 로컬 CrownyBro 프로세스가 이미 점유 중이라 node1은 9856으로 대체 배정(포트 레지스트리 미등록, 로컬 테스트 한정이므로 문제 없음).
- DEX 이벤트가 실제 체결/스왑이 아님: 테스트 시점 DEX
/api/orders·/api/trades가 비어있어/api/markets시세 스냅샷을 이벤트로 대체 사용. 실제 주문체결 이벤트 발생 시 동일 브릿지 패턴(dex_bridge.sh)으로 재현 가능. - 본 클러스터는 완전히 휘발성 테스트였음 — 재현하려면
/tmp/chain-test/를 재빌드해야 함(정리 과정에서 프로세스만 kill, 파일은 남겨둠).