아발란체 로컬에서 노드 돌려보기

아발란체 로컬에서 노드 돌려보기

블록체인 또는 가상자산의 구동 원리를 알기 위해선 알려진 자료들에 비해 유의미한 정보들을 찾기가 어렵다. 블록체인의 개념이나 추상적인 개론 뿐이거나 가상자산의 투자 정보 같은 부수적인 내용들이 대부분이다. 10년 전 비트코인의 구동 원리를 직접 코드로 짜보면서 공부했던 것이 가장 효율적었고 이번 역시 유사한 방법으로 아발란체의 동작을 확인해보고자 한다. 아발란체는 P, C, X 체인으로 역할에 따라 분리한 것이 특징이고 snowman 합의 알고리즘으로 빠른 트랜잭션을 자랑하고 있다라고 한다. 솔직히 잘 이해가 안된다. 직접 눈으로 봐야겠다.

주의: 아발란체 메인넷에 노드 참여와는 관련이 없으며 아발란체 소스코드를 내려받아 직접 로컬에 구동해보는 내용입니다.

프로젝트 포크 후 클론

아발란체 공식 Repository

https://github.com/ava-labs/avalanchego

Project Fork

아발란체 프로젝트는 자신의 Git 저장소에 Fork해서 자유롭게 뜯어보길 권장한다.

필요한 기술 지식

  • Go
  • Docker & Docker Compose

필수 환경 구성

우선 아발란체는 Go로 개발되었다. 따라서 로컬에서 go를 설치해야한다. Mac 기준에서 brew를 통해 설치를 진행했다.

$ brew install go

로컬에서 구동할 노드 디렉토리 및 파일 구성

프로젝트를 내려받은 뒤 추가할 디렉토리와 파일은 아래와 같다.

  • docker-compose.yml: docker 이미지 파일을 이용해 2개의 노드 컨테이너를 올리기 위해 필요
  • node1/config.json: 첫 번째 노드의 설정 파일
  • node1/genesis.json: 첫 번째 노드의 제네시스 파일
  • node2/config.json: 두 번째 노드의 설정 파일
  • node2/genesis.json: 두 번째 노드의 제네시스 파일

제네시스 파일은 블록체인이 새롭게 시작될 때 최초 블록을 정의하기 위한 파일이 된다. 비트코인 역시 제네시스 블록이 최초에 정의되어 있으며 비트코인의 제네시스 블록에 대한 정보를 찾아보면 재미있는 내용을 확인 할 수 있다.

project/
├── docker-compose.yml
├── node1/
│   └── config.json
│   └── genesis.json
└── node2/
│   └── config.json
    └── genesis.json

Dockerfile 이미지 빌드

아발란체 노드로 실행될 Docker 이미지를 빌드한다. 이렇게 빌드된 Docker 이미지는 Docker Compose에서 아발란체 노드들을 구동하기 위해 필요하다.

$ docker build --build-arg GO_VERSION=1.21.11 -t avalanche .

2개의 노드를 상호 연결하기 위한 설정

각 노드의 network id는 동일하게 설정하되 상대 노드를 바라보도록 bootstrap-ips에 정의해줘야 한다. 로컬에서 구동되기 때문에 Loopback IP(127.0.0.1)을 사용하고 있다.

// node1/config.json
{
  "network-id": "local",
  "db-dir": "/config/db",
  "log-level": "debug",
  "http-host": "0.0.0.0",
  "bootstrap-ips": "127.0.0.1:9653",
  "bootstrap-ids": "NodeID-7Xhw2mDxuDS44j42TCB6U5579esbSt3Lg",
  "genesis": "/config/genesis.json"
}

// node2/config.json
{
  "network-id": "local",
  "db-dir": "/config/db",
  "log-level": "debug",
  "http-host": "0.0.0.0",
  "bootstrap-ips": "127.0.0.1:9651",
  "bootstrap-ids": "NodeID-7Xhw2mDxuDS44j42TCB6U5579esbSt3Lg",
  "genesis": "/config/genesis.json"
}

노드를 실행하기 위한 docker-compose 정의

docker-compose.yml에 구동할 노드들의 설정을 모두 정의할 수 있다. 아발란체 노드는 기본적으로 9650, 9651 포트를 사용하고 있으며 1번 노드는 기본 포트를 그대로 사용하고 2번 노드는 1번이 사용하는 포트와 겹치지 않도록 호스트 사용 포트를 9652, 9653으로 매핑시켜준다.

각 노드의 설정(config)은 컨테이너가 재시작 또는 재구성 되더라도 내용을 보존하기 위해 외부 volume으로 정의한다.

log-level은 debug로 설정되어있으나 정상 구동이 확인되면 info로 변경하여 불필요한 로그 출력을 방지하도록 하자.

version: '3.8'

services:
  avalanche-node1:
    image: avalanche:latest
    container_name: avalanche-node1
    ports:
      - "9650:9650"
      - "9651:9651"
    volumes:
      - ./node1:/config
    command: >
      /avalanchego/build/avalanchego
      --network-id=local
      --db-dir=/config/db
      --log-level=debug
      --http-host=0.0.0.0
      --config-file=/config/config.json
    networks:
      - avalanche-network

  avalanche-node2:
    image: avalanche:latest
    container_name: avalanche-node2
    ports:
      - "9652:9650"
      - "9653:9651"
    volumes:
      - ./node2:/config
    command: >
      /avalanchego/build/avalanchego
      --network-id=local
      --db-dir=/config/db
      --log-level=debug
      --http-host=0.0.0.0
      --config-file=/config/config.json
    networks:
      - avalanche-network

networks:
  avalanche-network:
    driver: bridge

docker-compose 로 노드 실행

위 과정들이 모두 정상적으로 세팅되었다면 docker compose로 노드를 구동시킬 수 있다.

$ docker-compose up --build

아발란체 노드 로그 확인

정상적으로 구동된 경우 docker log에서는 아래와 같이 1번 노드와 2번 노드가 수시로 동기화하는 메시지가 확인된다. 이는 log-level을 info로 변경하면 출력되지 않는다.

avalanche-node1  | [06-15|03:16:29.734] DEBUG <P Chain> handler/handler.go:938 forwarding chan message to consensus {"messageOp": "gossip_request"}
avalanche-node1  | [06-15|03:16:29.735] DEBUG <P Chain> handler/handler.go:960 finished handling chan message {"messageOp": "gossip_request"}
avalanche-node2  | [06-15|03:16:29.736] DEBUG <P Chain> handler/handler.go:938 forwarding chan message to consensus {"messageOp": "gossip_request"}
avalanche-node2  | [06-15|03:16:29.736] DEBUG <P Chain> handler/handler.go:960 finished handling chan message {"messageOp": "gossip_request"}
avalanche-node2  | [06-15|03:16:29.834] DEBUG <P Chain> handler/handler.go:938 forwarding chan message to consensus {"messageOp": "gossip_request"}
avalanche-node2  | [06-15|03:16:29.835] DEBUG <P Chain> handler/handler.go:960 finished handling chan message {"messageOp": "gossip_request"}
avalanche-node1  | [06-15|03:16:29.835] DEBUG <P Chain> handler/handler.go:938 forwarding chan message to consensus {"messageOp": "gossip_request"}
avalanche-node1  | [06-15|03:16:29.835] DEBUG <P Chain> handler/handler.go:960 finished handling chan message {"messageOp": "gossip_request"}

어렵지 않게 아발란체를 로컬로 포크떠서 띄울 수 있었다. 다음엔 이렇게 띄워진 네트워크 상에 기록을 시도해보도록 하겠다.

%d 블로거가 이것을 좋아합니다: