Don't think! Just do it!

종합 IT 기술 정체성 카오스 블로그! 이... 이곳은 어디지?

Cardano/staking pool 구축

ADA Staking Pool 구축 #3

방피터 2022. 2. 28. 16:51

이전글

2022.02.28 - [Cardano/staking pool 구축] - ADA Staking Pool 구축 #2

 

ADA Staking Pool 구축 #2

이전글 2022.02.28 - [Cardano/staking pool 구축] - ADA Staking Pool 구축 #1 ADA Staking Pool 구축 #1 Cardano node를 운영해 보기로 마음을 먹었습니다. 이유야 뭐 ㅎㅎㅎ 돈 좀 벌어보려고 하는거죠. 결론부..

engschool.tistory.com

 

계속 이어 staking pool을 구축하도록 하겠습니다.

 

다시 한번 말씀드리지만 cardano.io에 있는 공식 developer 문서는 따라하지 마시기 바랍니다. (21년 9월 23일 기준)

업데이트가 느린 것 같고 testnet 기준입니다. 저는 아래 링크에 있는 사이트를 기준으로 작성했습니다.

https://www.coincashew.com/coins/overview-ada/guide-how-to-build-a-haskell-stakepool-node

 

Guide: How to build a Cardano Stake Pool

On Ubuntu/Debian, this guide will illustrate how to install and configure a Cardano stake pool from source code on a two node setup with 1 block producer node and 1 relay node.

www.coincashew.com

 

AWS EC2가 준비되었다면 터미널을 이용해 접속해 봅시다. AWS EC2 대시보드에서 연결을 클릭.

 

SSH 클라이언트 탭을 선택하면 아래와 같은 화면을 볼 수 있습니다.  먼저 키의 권한을 변경하고 ssh 접속 명령을 복사해 ec2 인스턴스로 접근합니다. (nodeKeyPair.pem 은 블로그 용으로 생성하도 등록한 키입니다. 자신의 키 이름을 사용해 주세요.)

 

 

ec2 SSH 접속


Cabal 및 GHC 설치

 

먼저 시스템 업데이트을 업데이트 합니다.

sudo apt-get update -y

 

설치에 필요한 소프트웨어 패키지들을 설치합니다. 시간이 조금 걸립니다.

sudo apt-get install git jq bc make automake rsync htop curl build-essential pkg-config libffi-dev libgmp-dev libssl-dev libtinfo-dev libsystemd-dev zlib1g-dev make g++ wget libncursesw5 libtool autoconf -y

 

Libsodium을 설치합니다. (자세한 설명 -> https://libsodium.gitbook.io/doc/) 시간이 조금 걸립니다.

mkdir $HOME/git
cd $HOME/git
git clone https://github.com/input-output-hk/libsodium
cd libsodium
git checkout 66f017f1
./autogen.sh
./configure
make
sudo make install

 

Cabal 의존성 소프트웨어들을 설치합니다. (자세한 설명 -> https://www.haskell.org/cabal/)

sudo apt-get -y install pkg-config libgmp-dev libssl-dev libtinfo-dev libsystemd-dev zlib1g-dev build-essential curl libgmp-dev libffi-dev libncurses-dev libtinfo5

Cabal을 설치합니다. 시간이 오래 걸립니다. 인내심!

curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh

 

ghcup을 업그레이드 합니다. ghcup은 Haskell을 위한 installer입니다.

cd $HOME
source .bashrc
ghcup upgrade
ghcup install cabal 3.4.0.0
ghcup set cabal 3.4.0.0

ghc 8.10.4를 설치 및 버전을 설정합니다. 역시 시간이 조금 걸립니다.

ghcup install ghc 8.10.4
ghcup set ghc 8.10.4

 

Cabal과 GHC 실행파일을 위한 PATH와 NODE_HOME, NODE_CONFIG 등 노드 수행에 필요한 경로를 업데이트 합니다.

echo PATH="$HOME/.local/bin:$PATH" >> $HOME/.bashrc
echo export LD_LIBRARY_PATH="/usr/local/lib:$LD_LIBRARY_PATH" >> $HOME/.bashrc
echo export NODE_HOME=$HOME/cardano-my-node >> $HOME/.bashrc
echo export NODE_CONFIG=mainnet>> $HOME/.bashrc
echo export NODE_BUILD_NUM=$(curl https://hydra.iohk.io/job/Cardano/iohk-nix/cardano-deployment/latest-finished/download/1/index.html | grep -e "build" | sed 's/.*build\/\([0-9]*\)\/download.*/\1/g') >> $HOME/.bashrc
source $HOME/.bashrc

 

Cabal을 업데이트 후 버전을 확인합니다.

cabal update
cabal --version
ghc --version

 

아래 화면과 같이 Cabal의 버전은 3.4.0 GHC의 버전은 9.10.4이어야 합니다.

Cabal과 GHC 버전


Cardano 노드 소스코드 다운로드 및 빌드

 

이제야 Cardano node 소스 코드를 다운받습니다.

cd $HOME/git
git clone https://github.com/input-output-hk/cardano-node.git
cd cardano-node
git fetch --all --recurse-submodules --tags
git checkout $(curl -s https://api.github.com/repos/input-output-hk/cardano-node/releases/latest | jq -r .tag_name)

 

빌드 옵션을 설정합니다. 시간이 5-10분 걸립니다. 기다려봅시다.

cabal configure -O0 -w ghc-8.10.4

 

 

Cabal과 프로젝트 설정을 업데이트 합니다. 빌드 폴더를 초기화 합니다.

echo -e "package cardano-crypto-praos\n flags: -external-libsodium-vrf" > cabal.project.local
sed -i $HOME/.cabal/config -e "s/overwrite-policy:/overwrite-policy: always/g"
rm -rf $HOME/git/cardano-node/dist-newstyle/build/x86_64-linux/ghc-8.10.4

 

cardano-cli와 cardano-node를 빌드합니다. 이 때 시간이 5만년 걸립니다. 오늘은 잊고 다음날 설치가 완료되었는지 확인해보세요.

cabal build cardano-cli cardano-node

 

빌드가 완료되면 cardano-cli와 cardano-node 파일을 바이너리 디렉토리로 복사합니다.

sudo cp $(find $HOME/git/cardano-node/dist-newstyle/build -type f -name "cardano-cli") /usr/local/bin/cardano-cli
sudo cp $(find $HOME/git/cardano-node/dist-newstyle/build -type f -name "cardano-node") /usr/local/bin/cardano-node

 

올바르게 설치가 되어 있는지 확인합니다.

cardano-node version
cardano-cli version

 

아래와 같이 버전 정보가 출력되어야 합니다.

 

 

 

 


Cardano 노드 설정

노드 설정을 위한 configuration file들을 다운로드 받습니다.

mkdir $NODE_HOME
cd $NODE_HOME
wget -N https://hydra.iohk.io/build/${NODE_BUILD_NUM}/download/1/${NODE_CONFIG}-byron-genesis.json
wget -N https://hydra.iohk.io/build/${NODE_BUILD_NUM}/download/1/${NODE_CONFIG}-topology.json
wget -N https://hydra.iohk.io/build/${NODE_BUILD_NUM}/download/1/${NODE_CONFIG}-shelley-genesis.json
wget -N https://hydra.iohk.io/build/${NODE_BUILD_NUM}/download/1/${NODE_CONFIG}-alonzo-genesis.json
wget -N https://hydra.iohk.io/build/${NODE_BUILD_NUM}/download/1/${NODE_CONFIG}-config.json

 

다음을 실행하여 mainnet-config.json의 TraceBlockFetchDecisions 항목을 true로 변경합니다.

sed -i ${NODE_CONFIG}-config.json \
    -e "s/TraceBlockFetchDecisions\": false/TraceBlockFetchDecisions\": true/g"

릴레이 노드의 메모리  및 CPU 사용량을 줄이기 위한 팁: mainnet-config.json파일의 TraceMemPool 항목을 false로 변경합니다. (라고 설명되어 있으나 큰 차이를 모르겠습니다.)

 

cardano 소켓 파일 위치 변수를 .bashrc에 업데이트 합니다.

echo export CARDANO_NODE_SOCKET_PATH="$NODE_HOME/db/socket" >> $HOME/.bashrc
source $HOME/.bashrc

 

 

 

 

위 설치 과정을 나머지 하나의 EC2에도 똑같이 수행하여 설치합니다.

자 이제 우리는 1개의 블록 생성 노드와 1개의 릴레이 노드를 구동시킬 준비가 되었습니다.


블록 생성 노드 설정

이전에 말씀드렸다시피 카르다노 스테이킹 풀을 돌리기 위해서는 1개의 블록 생성 노드와 1개 이상의 릴레이 노드, 즉 적어도 2개의 노드가 필요합니다. 블록 생성 노드는 자신의 릴레이 노드(들)와만 연결되며 릴레이 노드는 블록 생서 노드, 자신의 다른 릴레이 노드 그리고 기타 다른 노드와 연결됩니다.

블록 생성 노드와 릴레이 노드 구조

 

아래는 mainnet-topology.json을 설정하는 부분인데 addr과 port 번호를 설정합니다. 보통 포트번호는 3001번 혹은 6000번, 6001번 정도를 많이 사용합니다. 그런데 아래와 같이 수행하려면 메모장에 복붙하고 수정하고 다시 터미널에서 수행해야하는 번거로움이 있습니다.

cat > $NODE_HOME/${NODE_CONFIG}-topology.json << EOF 
 {
    "Producers": [
      {
        "addr": "<내 릴레이 노드 Public IP 주소>",
        "port": 내 릴레이 노드 포트번호,
        "valency": 1
      }
    ]
  }
EOF

 

위처럼 cat 명령을 사용하지 않고 nano나 vim 등 편한 툴로 직접 편집하시면 됩니다.

nano mainnet-topology.json

 


릴레이 노드 설정

릴레이는 여러 개를 구성하여 스테이크 풀 아키텍쳐를 확장할 수 있다고 설명하고 있지만 어떤 이익이 있는지는 아직 정확하게 모르겠습니다. ^^;; 아하하.. 저도 공부중이라 양해를..

릴레이 노드도 블록 생성 노드와 같이 mainnet-topology.json 파일을 수정합니다. 하지만 다른 점은 첫 번째 노드 정보에 내 블록 생성 노드의 정보를 넣어야 한다는 것입니다. 두번째의 relays-new.cardano-mainnet.iohk.io는 iohk의 기본 노드입니다.

cat > $NODE_HOME/${NODE_CONFIG}-topology.json << EOF 
 {
    "Producers": [
      {
        "addr": "내 블록 생성 노드의 Public IP 주소",
        "port": 내 블록 생성 노드 포트번호,
        "valency": 1
      },
      {
        "addr": "relays-new.cardano-mainnet.iohk.io",
        "port": 3001,
        "valency": 2
      }
    ]
  }
EOF

마찬가지로 복붙하기 귀찮으신 분들은 nano나 vim 등 편한 편집기로 직접 편집하시면 됩니다.

 

*참고: valency는 얼마나 많은 커넥션을 유지할 지에 대한 옵션이라고 합니다. DNS 주소에만 영향을 미치며 0이면 해당 주소는 무시됩니다. 운영에 얼마나 영향을 미치는 지는 정확하게 파악하지는 못했어요 ㅠㅠ


노드 방화벽 설정

카르다노 노드를 실행하려면 AWS EC2 방화벽에서 위에서 사용한 포트 사용을 허용해야 합니다. AWS EC2를 사용하지 않으시는 분들은 각자의 머신에 맞게 방화벽을 설정하여 해당 포트를 열어줍니다.

 

AWS EC2 대쉬보드에서 해당 인스턴스 정보에서 하단의 보안 탭 -> 그리고 보안 그룹 클릭하여 이동

 

Edit inbound rules 버튼 클릭하여 인바운드 룰 편집 화면으로 이동

 

규칙 추가 버튼 클릭하여 인바운드 규칙을 추가 합니다. 유형에 사용자 지정 TCP, 포트 범위에는 자신이 설정한 포트 번호, 그리고 마지막으로 소스는 자신의 IP 혹은 anywhere-ip4를 선택 후 규칙 저장을 눌러 보안 설정을 완료합니다.

 

기본적으로 모든 인바운드 포트는 막혀있으므로 릴레이 노드와 블록 생성 노드 둘 다 반드시 방화벽을 설정해 주어야 합니다.


air-gapped offline 머신 준비

air-gapped offile machine는 인터넷이 연결되어 있지 않은 독립적인 PC를 의미합니다. Cold environment라고도 합니다. 스테이크 풀 특성상 키나 인증서 등이 절대 노출되면 안되기 때문에 키 생성 등은 별도의 PC에서 작업하는 것을 권장합니다. 그리고 Hot과 Cold environment 사이에서 데이터 교환은 USB 디스크 등을 이용해 물리적으로 이동시켜야 합니다.

 

한마디로 쉽게 말씀드리자면 인터넷이 연결되어 있지 않은 리눅스 머신과 USB디스크를 준비하셔야 합니다.

 

그리고 air-gapped offline machine에 아래와 같이 환경변수를 입력해 줍니다.

echo export NODE_HOME=$HOME/cardano-my-node >> $HOME/.bashrc
source $HOME/.bashrc
mkdir -p $NODE_HOME

Start up script 준비

 

노드를 background에서 실행시키기 위한 script를 블록 생성 노드와 릴레이 노드 각각 작성해 줍니다. PORT 번호만 주의하도록 합니다. HOSTADDR=0.0.0.0이 맞습니다.

 

<블록 생성 노드 스크립트>

cat > $NODE_HOME/startBlockProducingNode.sh << EOF 
#!/bin/bash
DIRECTORY=$NODE_HOME
PORT=6000
HOSTADDR=0.0.0.0
TOPOLOGY=\${DIRECTORY}/${NODE_CONFIG}-topology.json
DB_PATH=\${DIRECTORY}/db
SOCKET_PATH=\${DIRECTORY}/db/socket
CONFIG=\${DIRECTORY}/${NODE_CONFIG}-config.json
/usr/local/bin/cardano-node run --topology \${TOPOLOGY} --database-path \${DB_PATH} --socket-path \${SOCKET_PATH} --host-addr \${HOSTADDR} --port \${PORT} --config \${CONFIG}
EOF

실행 권한 추가

chmod +x $NODE_HOME/startBlockProducingNode.sh

<릴레이 노드 스크립트>

cat > $NODE_HOME/startRelayNode.sh << EOF 
#!/bin/bash
DIRECTORY=$NODE_HOME
PORT=6000
HOSTADDR=0.0.0.0
TOPOLOGY=\${DIRECTORY}/${NODE_CONFIG}-topology.json
DB_PATH=\${DIRECTORY}/db
SOCKET_PATH=\${DIRECTORY}/db/socket
CONFIG=\${DIRECTORY}/${NODE_CONFIG}-config.json
/usr/local/bin/cardano-node run --topology \${TOPOLOGY} --database-path \${DB_PATH} --socket-path \${SOCKET_PATH} --host-addr \${HOSTADDR} --port \${PORT} --config \${CONFIG}
EOF

실행 권한 추가

chmod +x $NODE_HOME/startRelayNode.sh

 

이제 systemd로 만들어 시스템 서비스로 등록합니다.

 

<블록 생성 노드 systemd>

cat > $NODE_HOME/cardano-node.service << EOF 
# The Cardano node service (part of systemd)
# file: /etc/systemd/system/cardano-node.service 

[Unit]
Description     = Cardano node service
Wants           = network-online.target
After           = network-online.target 

[Service]
User            = ${USER}
Type            = simple
WorkingDirectory= ${NODE_HOME}
ExecStart       = /bin/bash -c '${NODE_HOME}/startBlockProducingNode.sh'
KillSignal=SIGINT
RestartKillSignal=SIGINT
TimeoutStopSec=2
LimitNOFILE=32768
Restart=always
RestartSec=5
SyslogIdentifier=cardano-node

[Install]
WantedBy	= multi-user.target
EOF

 

<릴레이 노드 systemd>

cat > $NODE_HOME/cardano-node.service << EOF 
# The Cardano node service (part of systemd)
# file: /etc/systemd/system/cardano-node.service 

[Unit]
Description     = Cardano node service
Wants           = network-online.target
After           = network-online.target 

[Service]
User            = ${USER}
Type            = simple
WorkingDirectory= ${NODE_HOME}
ExecStart       = /bin/bash -c '${NODE_HOME}/startRelayNode.sh'
KillSignal=SIGINT
RestartKillSignal=SIGINT
TimeoutStopSec=2
LimitNOFILE=32768
Restart=always
RestartSec=5
SyslogIdentifier=cardano-node

[Install]
WantedBy	= multi-user.target
EOF

 

생성된 파일을 /etc/systemd/system으로 옮기고 권한을 부여합니다.

sudo mv $NODE_HOME/cardano-node.service /etc/systemd/system/cardano-node.service
sudo chmod 644 /etc/systemd/system/cardano-node.service

 

OS 부트시 자동으로 실행되도록 서비스를 활성화합니다.

sudo systemctl daemon-reload
sudo systemctl enable cardano-node

기타 systemd 운용시 유용한 명령들

아래는 systemd와 관련한 유용한 명령들입니다. coincashew처럼 저도 똑같이 소개해드리겠습니다.

 

노드의 상태를 확인합니다.

sudo systemctl status cardano-node

노드를 재시작합니다.

sudo systemctl reload-or-restart cardano-node

노드를 중지합니다.

sudo systemctl stop cardano-node

 

시스템 로그를 확인합니다.

journalctl --unit=cardano-node --follow
journalctl --unit=cardano-node --since=yesterday
journalctl --unit=cardano-node --since=today
journalctl --unit=cardano-node --since='2020-07-29 00:00:00' --until='2020-07-29 12:00:00'

노드 시작

아래 명령을 수행해 노드를 시작합니다.

sudo systemctl start cardano-node

노드가 시작되면 블록을 다운받기 시작합니다. 컴퓨터 사양과 네트워크 속도에 따라 틀리지만 시간이 굉장히 많이 소요됩니다. 2-3일 정도 걸리는 것 같습니다. 그냥 잊고 지내시는게 맘 편합니다.

 

노드 상태를 로그만으로 파악하는 건 무리가 있기 때문에 터미널 위에서 중요한 노드 정보를 보여주는 gLiveView라는 로컬 모니터링 툴을 설치하여 상태를 확인합니다.

 

아래를 수행하여 gLiveView 다운로드

cd $NODE_HOME
sudo apt install bc tcptraceroute -y
curl -s -o gLiveView.sh https://raw.githubusercontent.com/cardano-community/guild-operators/master/scripts/cnode-helper-scripts/gLiveView.sh
curl -s -o env https://raw.githubusercontent.com/cardano-community/guild-operators/master/scripts/cnode-helper-scripts/env
chmod 755 gLiveView.sh

 

아래를 수행하여 env 파일에 설정 정보를 수정합니다.

sed -i env \
    -e "s/\#CONFIG=\"\${CNODE_HOME}\/files\/config.json\"/CONFIG=\"\${NODE_HOME}\/mainnet-config.json\"/g" \
    -e "s/\#SOCKET=\"\${CNODE_HOME}\/sockets\/node0.socket\"/SOCKET=\"\${NODE_HOME}\/db\/socket\"/g"

 

gLiveView를 실행하기전에 노드의 에포크가 208에 도달해야만 합니다. 다시 말씀드리지만 블록을 다운받는데에 시간이 매우 많이 소요됩니다. 아래 명령을 수행하여 블록 다운로드 상태를 확인하실 수 있습니다.

cardano-cli query tip --mainnet

 

에포크가 208에 도달하면 gLiveView.sh를 실행하여 로컬 모니터링을 시작합니다.

./gLiveView.sh

gLiveView 실행화면

 

재차 말씀드리지만 블록을 다운받는데 시간이 오래 걸려요. 진짜 2-3일 풀로 걸립니다. 여유를 가지고 해보시기 바랍니다.

 

이제 절반정도 온 것 같은데요. 이제 남은 부분은 스테이킹을 위한 각종 키 생성, 스테이킹 풀 등록, 보증금 납입 등과 릴레이 topology update, pool meta file server 만들기 정도인 것 같습니다. 너무 길어서 다음에 이어서 끝내기로 하지요

 

안녕~!

 

다음글

2022.02.28 - [Cardano/staking pool 구축] - ADA Staking Pool 구축 #4

 

ADA Staking Pool 구축 #4

이전글 2021.09.23 - [스테이킹] - ADA Staking Pool 구축 #3 이번 글을 마지막으로 어느 정도 스테이킹 풀 구축이 끝날 것 같습니다. 이제부터의 나머지 과정은 블록을 100% 다운로드 받은 후 수행하시기

engschool.tistory.com

 

반응형

'Cardano > staking pool 구축' 카테고리의 다른 글

ADA Staking Pool 운영에 대해...  (0) 2022.02.28
ADA Staking Pool 구축 #4  (0) 2022.02.28
ADA Staking Pool 구축 #2  (0) 2022.02.28
ADA Staking Pool 구축 #1  (0) 2022.02.28