본 아티클을 통해 스택스 체인 메인넷 풀노드 구축 방법에 대해 알아보겠습니다.

실제 스택스 메인넷 풀노드를 구축하기 위해 필요한 준비 및 숙지 사항 그리고 직접 노드를 구성하면서 겪었던 주의 사항에 대해 기술하였습니다. 시작하기에 앞서 최근 릴리즈된 Stacks 2.05.0.2 업데이트 주요 사항에 대해 알아보겠습니다.

Stacks 2.05.0.2 업데이트 주요 사항

  • 디스크에 커밋이 될 때까지 새로운 루트 해시 계산을 지연시켜 불필요한 해시 계산을 피함으로써 블록 쓰기 속도를 약 10-200배 개선
  • 데이터베이스 인덱스 상태를 별도 파일에 저장함으로써 스키마 최적화를 통해 스택스 체인의 읽기 성능이 약 10-14배 향상
  • 불필요한 상황의 데이터베이스 읽지 않도록 개선하여 데이터 정렬 처리 성능이 약 10배 향상
  • 블록 처리 과정에서 노드 비정상 종료 시 이벤트 옵저버가 마지막 이벤트를 읽지 못하는 버그를 수정
  • /v2/info API 엔드포인트에 노드의 public 키과 hash를 표시함으로써 다른 노드의 이웃 리스트에서 노드 검색 가능
  • 전체적인 체인 성능 향상으로 마이너는 기존 3분에서 30초로 단축하여 블록을 빌드하도록 시도할 수 있으며 더 빨라진 체인 상태의 인덱스는 mempool 을 빠르게 스캔할 수 있도록 개선
  • 체인 및 mempool 검사를 위한 CLI 도구인 blockstack-core 바이너리를 stacks-inspect 이름으로 변경

* 자세한 업데이트 사항은 스택스 체인 GitHub에서 확인하실 수 있습니다.

스택스 풀노드 구축 준비 사항

본격적인 풀노드 구축에 앞서 먼저 구축 방법, 최소 필요조건 (권장 하드웨어 및 소프트웨어 요구 사항)에 대해 알아보도록 하겠습니다.

1. 노드 구축 방법

풀노드 구축 방법으론 아래와 같이 크게 두 가지 방법이 존재하며, 본 아티클에서는 스택스 재단과 히로 팀에서 권장하고 있는 Docker 이미지를 사용하여 노드를 가동하였습니다.

  1. 소스를 다운로드하여 컴파일 후 노드 가동
  2. 패키징 된 Docker 이미지를 사용하여 노드 가동

2. 최소 필요조건

풀노드 구동을 위해 특별히 요구되는 하드웨어 사양은 없지만, 스펙이 낮은 하드웨어에서 실행하는 경우 블록을 동기화하고, 트랜잭션을 처리하는 데 더 많은 시간이 소요될 수 있습니다. 때문에 아래와 같은 최소 스펙을 권장합니다.

최소 권장 하드웨어 (EC2 스펙 기준)

  • CPU : 2 core
  • Memory : 8 GB
  • Disk : 100 GB (SSD)
  • Network : Public 라우팅이 가능한 IP

*주의: 블록 동기화 과정 중 Stacks 2.0 체인에서 Stacks 1.0 데이터 마이그레이션을 하기 위해 OOM(Out Of Memory)이 발생할 소지가 있으므로 메모리는 최소 8 GB 이상의 하드웨어를 반드시 권장합니다.

3. 소프트웨어 요구 사항

스택스 풀노드를 가동 및 테스트하고 API 노드 서비스가 올바르게 작동하기 위해선 아래와 같은 소프트웨어를 설치 및 세팅해야 합니다.

필수 소프트웨어 준비

Inbound 방화벽 설정

  • 5432 (TCP, localhost) : Postgres
  • 20443 (TCP, 0.0.0.0/0) : Stacks Blockchain
  • 20444 (TCP, 0.0.0.0/0) : Stacks Blockchain
  • 3999 (TCP, 0.0.0.0/0) : Stacks Blockchain API

Outbound 방화벽 설정

  • 8332
  • 8333
  • 20443–2044

*주의: Outbound 포트는 스택스 체인 및 비트코인 헤더의 동기화를 위해 필요하며 열려있지 않은 경우 동기화에 실패하게 됩니다.

스택스 풀노드 구축 작업 순서

Docker 이미지를 사용하여 스택스 풀노드를 가동 시, 작업 순서에 유의해야 합니다. 각 Docker 컨테이너에서 구동되는 컴포넌트는 통신 시, Sequential 하게 동작하므로 작업 순서가 지켜지지 않는 경우 블록 동기화 과정에서 비정상적으로 동작하여 처음부터 블록을 다시 동기화해야 할 수 있습니다.

노드 시작 작업 순서

  1. Postgres 가동
  2. 스택스 블록체인 API 가동
  3. 스택스 블록체인 가동

노드 종료 작업 순서

  1. 스택스 블록체인 종료
  2. 스택스 블록체인 API 가동
  3. Postgres 종료

* 주의: 노드 종료 시에는 노드 시작 작업의 반대 순서로 진행해야 합니다. 그렇지 않을 시, 블록 데이터 동기화가 비정상적으로 동작할 수 있습니다.

스택스 풀노드 구축하기

STEP1. 환경 설정

스택스 풀노드를 가동하기 위해 Docker 이미지를 다운로드하고 서비스의 영구적인(Persistent) 데이터를 보관할 디렉토리 구조를 생성합니다.

mkdir -p ./stacks-node/{persistent-data/postgres,persistent-data/stacks-blockchain,bns,config}

docker pull blockstack/stacks-blockchain-api \

&& docker pull blockstack/stacks-blockchain \

&& docker pull postgres:alpine

docker network create stacks-blockchain > /dev/null 2>&1

cd ./stacks-node

STEP2. Postgres 시작하기

postgres:alpine 이미지에서는 Docker 컨테이너 실행 시 아래의 매개변수(Argument)를 참조하여 패스워드를 설정합니다. 본 아티클에서는 예시를 들기 위해서 기본 패스워드로 postgres를 설정합니다.

POSTGRES_PASSWORD=postgres

Postgres 시작

docker run -d --rm \
--name postgres \
--net=stacks-blockchain \
-e POSTGRES_PASSWORD=postgres \
-v $(pwd)/persistent-data/postgres:/var/lib/postgresql/data \
-p 5432:5432 \
postgres:alpine

Postgres 작동 확인

docker ps --filter name=postgres

Postgres 종료

docker stop postgres

STEP3. 스택스 블록체인 API 시작하기

스택스 블록체인 API가 정상적으로 실행되기 위해서는 몇 가지 환경 변수(.env)를 설정해야 합니다. 본 아티클에서는 예시를 위해 아래의 기본 설정을 사용합니다.

cd ./stacks-node
vim .env

STEP1에서 생성한 stacks-node 디렉토리 내에 아래의 env 파일을 생성합니다.

NODE_ENV=production
GIT_TAG=master
PG_HOST=postgres
PG_PORT=5432
PG_USER=postgres
PG_PASSWORD=postgres
PG_DATABASE=postgres
STACKS_CHAIN_ID=0x00000001
V2_POX_MIN_AMOUNT_USTX=90000000260
STACKS_CORE_EVENT_PORT=3700
STACKS_CORE_EVENT_HOST=0.0.0.0
STACKS_BLOCKCHAIN_API_PORT=3999
STACKS_BLOCKCHAIN_API_HOST=0.0.0.0
STACKS_BLOCKCHAIN_API_DB=pg
STACKS_CORE_RPC_HOST=stacks-blockchain
STACKS_CORE_RPC_PORT=20443
API_DOCS_URL=https://docs.hiro.so/api

스택스 블록체인 API 시작

docker run -d --rm \
--name stacks-blockchain-api \
--net=stacks-blockchain \
--env-file $(pwd)/.env \
-p 3700:3700 \
-p 3999:3999 \
blockstack/stacks-blockchain-api

스택스 블록체인 API 작동 확인

docker ps --filter name=stacks-blockchain-api

스택스 블록체인 인스턴스 stacks-blockchain-api는 3999, 3700 포트로 작동하므로 이를 확인합니다. 초기 동기화 시 3999 포트를 사용할 수 있게 되는 데에는 몇 분의 시간이 소요될 수 있습니다.

스택스 블록체인 API 종료

docker stop stacks-blockchain-api

STEP4. 스택스 블록체인 시작하기

스택스 블록체인은 스택스 블록체인 API와 블록체인 이벤트를 주고받으며 통신 함으로써 작동합니다. STEP2에서 이미 스택스 블록체인 API는 실행해두었으므로, 이제 스택스 블록체인을 실행하여 실제 메인넷 블록 데이터 동기화 작업을 실행할 수 있습니다.

스택스 블록체인을 실행하기에 앞서 스택스 블록체인 API와 블록체인 이벤트 통신에 관한 설정이 필요합니다.

/stacks-node 디렉토리에 config 디렉토리를 생성합니다.

mkdir -p ./stacks-node/config

config 디렉토리 내에 Config.toml 설정 파일을 아래와 같이 생성합니다.

vim ./stacks-node/config/Config.toml

Config.toml

[node]
working_dir = "/root/stacks-node/data"
rpc_bind = "0.0.0.0:20443"
p2p_bind = "0.0.0.0:20444"
bootstrap_node = "02da7a464ac770ae8337a343670778b93410f2f3fef6bea98dd1c3e9224459d36b@seed-0.mainnet.stacks.co:20444,02afeae522aab5f8c99a00ddf75fbcb4a641e052dd48836408d9cf437344b63516@seed-1.mainnet.stacks.co:20444,03652212ea76be0ed4cd83a25c06e57819993029a7b9999f7d63c36340b34a4e62@seed-2.mainnet.stacks.co:20444"
wait_time_for_microblocks = 10000

[[events_observer]]
endpoint = "stacks-blockchain-api:3700"
retry_count = 255
events_keys = ["*"]

[burnchain]
chain = "bitcoin"
mode = "mainnet"
peer_host = "bitcoin.blockstack.com"
username = "blockstack"
password = "blockstacksystem"
rpc_port = 8332
peer_port = 8333

[connection_options]
read_only_call_limit_write_length = 0
read_only_call_limit_read_length = 100000
read_only_call_limit_write_count = 0
read_only_call_limit_read_count = 30
read_only_call_limit_runtime = 1000000000

스택스 블록체인 시작

docker run -d --rm \
--name stacks-blockchain \
--net=stacks-blockchain \
-v $(pwd)/persistent-data/stacks-blockchain:/root/stacks-node/data \
-v $(pwd)/config:/src/stacks-node \
-p 20443:20443 \
-p 20444:20444 \
blockstack/stacks-blockchain \
/bin/stacks-node start --config /src/stacks-node/Config.toml

스택스 블록체인 작동 확인

docker ps --filter name=stacks-blockchain

스택스 블록체인은 20443–20444 포트에서 작동하므로 이를 확인합니다.

스택스 블록체인 종료

docker stop stacks-blockchain

Docker 인스턴스 종료 시에는 컨테이너만 삭제되며, 블록 데이터는 아래의 디렉토리에 보관되어 삭제되지 않습니다.

./stacks-node/persistent-data/stacks-blockchain/mainnet

STEP5. 인스턴스 작동 확인

Postgres 테스트

1. 데이터베이스에 연결합니다.

psql -h localhost -U postgres

위에서 환경 변수 POSTGRES_PASSWORD로 설정했던 비밀번호를 사용하여 접속합니다.

2. 현재 데이터베이스를 나열합니다.

\l

3.데이터베이스 연결을 해제합니다.

\q

스택스 블록체인 테스트

아래의 API를 통해서 스택스 블록 높이가 진행 중인지 체크합니다.

curl -sL localhost:20443/v2/info | jq{
"peer_version": 402653184,
"pox_consensus": "89d752034e73ed10d3b97e6bcf3cff53367b4166",
"burn_block_height": 666143,
"stable_pox_consensus": "707f26d9d0d1b4c62881a093c99f9232bc74e744",
"stable_burn_block_height": 666136,
"server_version": "stacks-node 2.0.11.1.0-rc1 (master:67dccdf, release build, linux [x86_64])",
"network_id": 1,
"parent_network_id": 3652501241,
"stacks_tip_height": 61,
"stacks_tip": "e08b2fe3dce36fd6d015c2a839c8eb0885cbe29119c1e2a581f75bc5814bce6f",
"stacks_tip_consensus_hash": "ad9f4cb6155a5b4f5dcb719d0f6bee043038bc63",
"genesis_chainstate_hash": "74237aa39aa50a83de11a4f53e9d3bb7d43461d1de9873f402e5453ae60bc59b",
"unanchored_tip": "74d172df8f8934b468c5b0af2efdefe938e9848772d69bcaeffcfe1d6c6ef041",
"unanchored_seq": 0,
"exit_at_block_height": null
}

스택스 블록체인 API 테스트

스택스 블록체인으로부터 데이터 통신을 잘 받고 있는지 위주로 체크합니다.

curl -sL localhost:3999/v2/info | jq{
"peer_version": 402653184,
"pox_consensus": "e472cadc17dcf3bc1afafc6aa595899e55f25b72",
"burn_block_height": 666144,
"stable_pox_consensus": "6a6fb0aa75a8acd4919f56c9c4c81ce5bc42cac1",
"stable_burn_block_height": 666137,
"server_version": "stacks-node 2.0.11.1.0-rc1 (master:67dccdf, release build, linux [x86_64])",
"network_id": 1,
"parent_network_id": 3652501241,
"stacks_tip_height": 61,
"stacks_tip": "e08b2fe3dce36fd6d015c2a839c8eb0885cbe29119c1e2a581f75bc5814bce6f",
"stacks_tip_consensus_hash": "ad9f4cb6155a5b4f5dcb719d0f6bee043038bc63",
"genesis_chainstate_hash": "74237aa39aa50a83de11a4f53e9d3bb7d43461d1de9873f402e5453ae60bc59b",
"unanchored_tip": "74d172df8f8934b468c5b0af2efdefe938e9848772d69bcaeffcfe1d6c6ef041",
"unanchored_seq": 0,
"exit_at_block_height": null
}

선택사항. 로컬 비트코인 노드 사용하기

위 ‘STEP4. 스택스 블록체인 시작하기’에서 스택스 블록체인의 노드 통신과 관련된 설정인 Config.toml 설정 파일을 셋업했습니다.

Config.toml

[node]
working_dir = "/root/stacks-node/data"
rpc_bind = "0.0.0.0:20443"
p2p_bind = "0.0.0.0:20444"
bootstrap_node = "02da7a464ac770ae8337a343670778b93410f2f3fef6bea98dd1c3e9224459d36b@seed-0.mainnet.stacks.co:20444,02afeae522aab5f8c99a00ddf75fbcb4a641e052dd48836408d9cf437344b63516@seed-1.mainnet.stacks.co:20444,03652212ea76be0ed4cd83a25c06e57819993029a7b9999f7d63c36340b34a4e62@seed-2.mainnet.stacks.co:20444"
wait_time_for_microblocks = 10000[[events_observer]]
endpoint = "stacks-blockchain-api:3700"
retry_count = 255
events_keys = ["*"][burnchain]
chain = "bitcoin"
mode = "mainnet"
peer_host = "bitcoin.blockstack.com"
username = "blockstack"
password = "blockstacksystem"
rpc_port = 8332
peer_port = 8333[connection_options]
read_only_call_limit_write_length = 0
read_only_call_limit_read_length = 100000
read_only_call_limit_write_count = 0
read_only_call_limit_read_count = 30
read_only_call_limit_runtime = 1000000000

위 설정 파일 중 burnchain 파트에서 스택스 블록체인 노드와 통신할 비트코인 노드를 설정할 수 있으며, 기본값으로 Hiro에서 제공하고 있는 피어(Peer) 호스트를 사용하였음을 알 수 있습니다.

Hiro에서 제공하는 비트코인 피어 호스트를 사용해도 스택스 블록체인 API 노드의 기능은 동일합니다. 하지만 Hiro에 요청되는 많은 트래픽으로 인한 노드 당 트래픽 제한과 미국과 한국 사이의 먼 거리로 인해 발생한 네트워크 지연으로, 초기 풀 노드 동기화 과정에서 비트코인 헤더와 블록 데이터를 동기화하는 데 오랜 시간이 걸릴 수 있습니다.

때문에 스택스 풀 노드를 가동 시 로컬 비트코인 노드와 통신을 위해 비트코인 노드를 구축하는 것을 권장드립니다.

로컬 비트코인 노드 구축은 스택스 노드 구축보다 수월하며, 관련 가이드는 아래 비트코인 재단의 공식 홈페이지를 통해 확인 가능합니다:

Introduction — Bitcoin
This site aims to provide the docs you need to understand Bitcoin and start building Bitcoin-based applications.

마지막으로, 로컬 비트코인 노드 구축이 완료되면 Config.toml의 설정 파일에서 burnchain 파트를 아래와 같이 수정해야 합니다.

[burnchain]
chain = "bitcoin"
mode = "mainnet"
peer_host = "{ 비트코인 노드 가동 URI }"
username = "{ Username }"
password = "{ 패스워드 }"
rpc_port = { RPC 포트(default:8332) }
peer_port = { Peer 포트(default:8333) }

username과 password는 비트코인 노드 구축 시 계정 인증을 할 수 있는 선택사항이지만, 불필요한 외부 트래픽 차단 및 보안을 위해 설정하는 것을 권장드립니다.

지금까지 스택스 메인넷 풀 노드를 구축하는 방법에 대해 알아보았습니다. 개인이 직접 스택스 풀 노드를 구축하기에는 많은 시간과 비용이 소요될 수 있기 때문에 일반 사용자는 Hiro에서 제공하는 스택스 API를 사용합니다.

하지만 많은 유저의 요청이 몰리거나 스택스 체인의 상태에 따라 API에 접근이 어려운 상황이 생길 수 있습니다. 따라서, Production 레벨의 스택스 디앱을 서비스하거나 안정적으로 컨트랙트와 통신하기 위해서는 스택스 풀 노드를 직접 구축하는 것을 권장합니다.

현재 디스프레드에서는 스택스 생태계 유저들이 자유롭게 사용할 수 있도록 북미와 한국을 거점으로 스택스 풀 노드를 가동 중이며, 아래의 API 주소를 통해서 접근 가능합니다.

스택스 관련 자료 & URL

▪ Hiro 공식 홈페이지: https://hiro.so
▪ Hiro Systems 트위터: https://twitter.com/hirosystems
▪ Stacks node : https://docs.stacks.co/nodes-and-miners/running-mainnet-node
▪ Stacks node API GitHub: https://github.com/hirosystems/stacks-blockchain-api
▪ Stacks 2.05.0.2 릴리즈 노트: https://github.com/hirosystems/stacks-blockchain-api