커널 업그레이드 워크플로 (Aeneid)
Aeneid 테스트넷 DKG 위원회 Validator의 story-kernel 바이너리를 업그레이드합니다.
DKG 온체인 업그레이드 메커니즘을 사용합니다: 새 MRENCLAVE 화이트리스트 등록, 업그레이드 스케줄링, 듀얼 커널 리셰어링, 그리고 컷오버.
사전 요구사항
- 현재 DKG 라운드가 Active 단계일 때 업그레이드를 시작하는 것을 권장합니다
- 모든 Validator 머신에 새 story-kernel 바이너리가 빌드되어 있어야 합니다(동일한 MRENCLAVE를 생성해야 함)
whitelistEnclaveType 및 scheduleUpgrade를 위한 DKG 컨트랙트에 대한 Timelock/owner 액세스
- 새 커널 클라이언트의 SGXValidationHook 프록시 주소를 알고 있어야 함
1단계: 새 커널 빌드
각 Validator 머신에서 새 story-kernel 바이너리를 빌드하세요(MRENCLAVE가 일치해야 하므로 절대 SCP로 바이너리를 전송하지 마세요).
cd ~/story-kernel
git pull origin release/0.1
make clean && make build-with-cpp && make all-gramine
NEW_MRENCLAVE=$(cat story-kernel.manifest.sgx.d/mrenclave.txt)
echo "New MRENCLAVE: $NEW_MRENCLAVE"
진행하기 전에 모든 Validator가 동일한 NEW_MRENCLAVE 값을 생성하는지 확인하세요.
2단계: 듀얼 커널 시작
새 커널은 별도의 포트에서 기존 커널과 함께 실행됩니다. DATA Foundation CL은 각 커널을 code_commitment(MRENCLAVE)로 식별합니다.
# 기존 커널: 이미 :50051에서 실행 중
# 새 커널: :50052에서 별도 home 디렉토리로 시작
# 두 커널 모두 리스닝 중인지 확인
sudo lsof -i :50051 | grep LISTEN # 기존
sudo lsof -i :50052 | grep LISTEN # 새
새 커널은 다음이 별도로 필요합니다:
- Home 디렉토리 (별도의 라이트 클라이언트 상태)
- 다른
listen_addr (:50052)을 가진 Gramine manifest
3단계: DATA Foundation Config 업데이트 + 재시작
새 커널 엔드포인트를 story.toml에 추가하세요:
kernel-endpoints = ["127.0.0.1:50051", "127.0.0.1:50052"]
story를 재시작하세요:
sudo systemctl restart story
두 커널이 모두 연결되었는지 확인하세요:
journalctl -u story --since '1 minute ago' | grep "Connected to kernel"
# 서로 다른 code_commitment 값을 가진 두 항목이 표시되어야 합니다
# 확인: connected_clients=2
4단계: 온체인 화이트리스트 + 업그레이드 스케줄링
현재 DKG 라운드가 Active 단계가 될 때까지 기다린 후:
DKG="0xCcCcCC0000000000000000000000000000000004"
ENCLAVE_TYPE="0x0000000000000000000000000000000000000000000000000000000000000001"
SGX_HOOK="<sgx_hook_proxy_addr>"
# 1. 새 MRENCLAVE 화이트리스트 등록
cast send $DKG 'whitelistEnclaveType(bytes32,(bytes32,address),bool)' \
$ENCLAVE_TYPE "(0x$NEW_MRENCLAVE,$SGX_HOOK)" true \
--rpc-url $RPC --private-key $KEY --legacy --gas-price 30000000000
# 2. 업그레이드 스케줄링 (activation = 현재 높이 + 버퍼)
CURRENT=$(cast block-number --rpc-url $RPC)
ACTIVATION=$((CURRENT + 50))
cast send $DKG 'scheduleUpgrade(uint256,string)' $ACTIVATION "v<version>" \
--rpc-url $RPC --private-key $KEY --legacy --gas-price 30000000000
Aeneid에서 DKG 컨트랙트 작업은 Timelock(minDelay=600s)을 거칩니다.
Timelock 트랜잭션을 스케줄링하고, 10분 대기 후 실행하세요.
5단계: 업그레이드 리셰어링 대기
# activation 모니터링
while true; do
HEIGHT=$(curl -s localhost:26657/status | python3 -c "import sys,json; print(json.load(sys.stdin)['result']['sync_info']['latest_block_height'])")
echo "Height: $HEIGHT / $ACTIVATION"
if [ "$HEIGHT" -ge "$ACTIVATION" ]; then break; fi
sleep 5
done
# 업그레이드 리셰어링 라운드 시작 확인
journalctl -u story --since '5 minutes ago' | grep 'is_upgrade.*true'
# 완료 대기
timeout 3600 bash -c "while ! journalctl -u story --since '1 hour ago' | grep -q 'DKG finalization phase complete'; do sleep 15; done"
6단계: 새 커널로 컷오버
업그레이드 리셰어링이 성공적으로 완료된 후:
# 1. 기존 커널 중지
sudo systemctl stop story-kernel # :50051의 기존
# 2. story.toml을 새 커널만 사용하도록 업데이트
sed -i 's|kernel-endpoints = \["127.0.0.1:50051", "127.0.0.1:50052"\]|kernel-endpoints = ["127.0.0.1:50052"]|' \
~/.story/story/config/story.toml
# 3. story 재시작
sudo systemctl restart story
# 4. 검증
journalctl -u story --since '1 minute ago' | grep "Connected to kernel"
# 새 code_commitment를 가진 1개 항목이 표시되어야 합니다
검증 체크리스트
문제 해결
| 증상 | 원인 | 해결 방법 |
|---|
재시작 후 connected_clients=1 | 새 커널이 실행되지 않거나 포트 불일치 | lsof -i :50052 확인, Gramine manifest 확인 |
| ”no new kernel client found for upgrade” | DATA Foundation이 새 커널에 연결되지 않음 | kernel-endpoints에 두 포트가 모두 있는지 확인, story 재시작 |
| activation 높이에서 업그레이드 라운드가 시작되지 않음 | 스케줄링 시 Active 단계가 아니었음 | 다음 Active 단계 동안 재스케줄링 |
| Finalization 실패 | 업그레이드된 위원회 멤버 부족 | 모든 Validator가 듀얼 커널을 실행 중인지 확인 |