Cardano stake pool 설치 - [1/2]

기본적인 linux 명령어에 대한 이해도가 높다면 더욱 쉽게 설치할 수 있습니다.

과정 전체는 약 1시간 정도가 소요되며, 설치나 POOL의 동기화를 기다리는 시간을 포함하면 8시간 정도가 소요될것으로 예상됩니다.

LINUX나 개발에 대해 잘 모르는 분들이어도 한번 따라해볼 수 있도록 가벼운 설명을 추가하여 작성했습니다.

궁금하신 부분이 있으면 댓글로 남겨주세요.

준비물

virtual box, ubuntu 20.04

cpu 2 core 이상,

ram 8G

100G의 하드디스크 여유공간

linux terminal

virtual box에 ubuntu 설치를 완료한 후 ctrl+alt+t를 누르면 terminal이 열리게 됩니다.

거기에 아래 명령어들을 입력합니다.

필요한 package 설치

sudo apt-get update -y
sudo apt-get upgrade -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

-y는 설치시 설치하시겠습니까라는 메시지를 받지 않기 위한 옵션입니다.

Libsodium 설치

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

$HOME directory에 git 폴더를 만들고 이동해서 libsodium을 clone 합니다.

66f017f1 commit에 check out 한 후에 해당 버전을 설치하게 됩니다.

cabal 설치

cd
wget https://downloads.haskell.org/~cabal/cabal-install-3.2.0.0/cabal-install-3.2.0.0-x86_64-unknown-linux.tar.xz
tar -xf cabal-install-3.2.0.0-x86_64-unknown-linux.tar.xz
rm cabal-install-3.2.0.0-x86_64-unknown-linux.tar.xz cabal.sig

sudo mv cabal /usr/local/bin/

cabal을 다운 받은 후 cabal을 /usr/local/bin에 등록 해줍니다.

GHC 설치

wget https://downloads.haskell.org/ghc/8.10.2/ghc-8.10.2-x86_64-deb9-linux.tar.xz
tar -xf ghc-8.10.2-x86_64-deb9-linux.tar.xz
rm ghc-8.10.2-x86_64-deb9-linux.tar.xz
cd ghc-8.10.2
./configure
sudo make install

GHC를 받은후 압축을 풀고 install 해줍니다.

위 패키지들을 설치시 warning message가 많이 나오는데 stable 버전이 아니거나 deprecate된 메소드를 사용하여 나는 메시지 이므로

설치에 성공했다면 신경쓰지 않으셔도 됩니다.

환경변수 setup

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

각종 변수들을 세팅하고 source .bashrc 통해 적용해줍니다.

확인

cabal update
cabal -V
ghc -V

정상적으로 설치된 경우 아래와 같은 message가 출력됨을 알 수 있습니다.

zoster@zoster-VirtualBox:~/$ cabal -V
cabal-install version 3.2.0.0
compiled using version 3.2.0.0 of the Cabal library
zoster@zoster-VirtualBox:~/$ ghc -V
The Glorious Glasgow Haskell Compilation System, version 8.10.2

cardano build

이제 Cardano의 source를 빌드하게 됩니다.

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 tags/1.26.1

마찬가지로 git clone 통해 cardano node를 가져오고 1.26.1 버전으로 checkout 합니다.

cabal configure -O0 -w ghc-8.10.2

cabal을 setting 해줍니다.(상당 시간이 소요됨)

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.2

sed를 통해 설정을 변경해줍니다.

sed는 file안의 내용을 replace 해주는 명령어 입니다.

cabal build cardano-cli cardano-node

cabal을 통해서 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

cabal을 /usr/local/bin에 등록했을때와 마찬가지로 cardano 명령어들도 등록해줍니다.

cardano-node version
cardano-cli version

설치를 확인해봅니다.

zoster@zoster-VirtualBox:~$ cardano-node version
cardano-node 1.26.1 - linux-x86_64 - ghc-8.10
git rev 9a7331cce5e8bc0ea9c6bfa1c28773f4c5a7000f

zoster@zoster-VirtualBox:~$ cardano-cli version
cardano-cli 1.26.1 - linux-x86_64 - ghc-8.10
git rev 9a7331cce5e8bc0ea9c6bfa1c28773f4c5a7000f

마찬가지로 정상 등록된 경우 위와 같은 message를 볼 수 있습니다.

node 설정

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}-config.json

$NODE_HOME으로 이동해 각종 설정 파일들은 다운 받습니다.

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

sed를 통해 replace 해줍니다.

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

환경변수를 setup하고 source .bashrc 통해 적용해줍니다.

virtual box 복제

cardano stake pool은 block producer와 relay로 구성되어 있습니다.

block producer는 core를 담당하고, relay는 외부와 연결되어있는 node 입니다.

block producer는 오직 relay와만 통신하게 됩니다.

virtual box에서는 현재 만들어진 vm을 복사하는 기능이 있습니다.

복제 → 연결된 복제를 통해 현재 setup된 내용들을 공유하는 vm을 추가할 수 있습니다.

block - relay - cold 세가지 vm을 만들어 줍니다.

block과 relay는 bridge 형태의 네트워크를 사용하고, cold는 네트워크 어댑터를 추가하지 않고 만들어줍니다.

block producer node 설정

block producer vm으로 돌아와

cat > $NODE_HOME/${NODE_CONFIG}-topology.json << EOF
{
   "Producers": [
    {
       "addr": "<RELAYNODE1'S PUBLIC IP ADDRESS>",
       "port": 6000,
       "valency": 1
    }
  ]
}
EOF

topology.json 파일의 addr에 relay node의 public ip를 setup해 줍니다. ifconfig를 통해 해당 vm의 ip를 알 수 있습니다.

relay node 설정

relay vm으로 들어가서 아래 명령어를 입력합니다.

cat > $NODE_HOME/${NODE_CONFIG}-topology.json << EOF
{
   "Producers": [
    {
       "addr": "<BLOCK PRODUCER NODE'S PUBLIC IP ADDRESS>",
       "port": 6000,
       "valency": 1
    },
    {
       "addr": "relays-new.cardano-mainnet.iohk.io",
       "port": 3001,
       "valency": 2
    }
  ]
}
EOF

이번에는 addr에 block producer의 ip를 입력해줍니다.

cold 설정

cold vm은 반드시 네트워크가 연결되지 않아야 합니다.

cold vm으로 돌아와 아래 명령어를 입력합니다.

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

아까 했던 환경 변수 설정을 해줍니다.

systemctl script 작성

systemctl이란 window의 시작프로그램과 비슷한 개념입니다.

거기에 추가적으로 해당 process가 죽었을경우 자동으로 재시작 해주는 기능이 있습니다.

block producer의 startup script 를 작성해줍니다.

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

relay의 startup script도 작성해줍니다.

cat > $NODE_HOME/startRelayNode1.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/startRelayNode1.sh

만들어진 startup script에 chmod +x 로 실행권한을 추가해줍니다.

startup script 작성이 끝났으면

systemctl script를 작성합니다.

block producer용

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

[Install]
WantedBy= multi-user.target
EOF

relay용

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}/startRelayNode1.sh'
KillSignal=SIGINT
RestartKillSignal=SIGINT
TimeoutStopSec=2
LimitNOFILE=32768
Restart=always
RestartSec=5

[Install]
WantedBy= multi-user.target
EOF

이제 양쪽 모두(block, relay) systemctl에 해당 script를 등록해줍니다.

sudo mv $NODE_HOME/cardano-node.service /etc/systemd/system/cardano-node.service
sudo chmod 644 /etc/systemd/system/cardano-node.service
sudo systemctl daemon-reload
sudo systemctl enable cardano-node
sudo systemctl reload-or-restart cardano-node
sudo systemctl status cardano-node

정상적으로 실행되었으면 아래 메시지를 볼 수 있습니다.

● cardano-node.service - Cardano node service
    Loaded: loaded (/etc/systemd/system/cardano-node.service; enabled; vendor preset: enabled)
    Active: active (running) since Sat 2021-03-13 12:27:21 UTC; 2h 53min ago

gListView 설치

이제 stake pool을 모니터링 할 수 있는 환경을 setup 해줍니다.

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

gLiveView, env파일을 받고 gLiveView에 실행권한도 주게 됩니다.

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"

설정을 sed로 변경해주고

./gLiveView.sh

실행해주면 아래 결과를 볼 수 있습니다.

  > Cardano Node - (Relay - Mainnet) : 1.26.1 [9a7331cc] <
┌────────────────────────┬────────────┬────────────────────────┐
│ Uptime: 02:56:02       │ Port: 6000 │ Guild LiveView v1.19.4 │
│------------------------└────────────┴────────────────────────┤
│ Epoch 253 [34.7%] (node)                                     │
│ 3d 06:21:28 until epoch boundary (chain)                     │
│ ▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▖▖▖▖▖▖▖▖▖▖▖▖▖▖▖▖▖▖▖▖▖▖▖▖▖▖▖▖▖▖▖▖▖▖▖▖▖▖▖ │
│                                                             │
│ Block   : 5456402               Tip (ref) : 24082712       │
│ Slot   : 149888               Tip (node) : 24082688       │
│ Density : 4.788                 Tip (diff) : 24 :)           │
│--------------------------------------------------------------│
│ Processed TX     : 0                   Out / In             │
│ Mempool TX/Bytes : 0 / 0       Peers :   1   0             │
└──────────────────────────────────────────────────────────────┘
TG Announcement/Support channel: t.me/guild_operators_official

[esc/q] Quit | [i] Info | [p] Peer Analysis

위는 동기화가 끝난 상황이며 실제로는 약간 다르게 표시됩니다. starting…과 같은 메시지가 찍혀있고

Epoch이 1부터 시작합니다. 몇시간이 지나면 현재 Epoch까지 따라오게 되고 이제 모든 동기화가 끝난 상태가 되게 됩니다.

릴레이와 블록 노드는 같은 퍼블릭 주소를 써도 되나요??

IP 별도로 구성해야 합니다.

ZSTP Retiring 하셨군요…

ㅎㅎ 네 리타이어입니다

가정용 PC로 구성할 경우 Node 1 는 public IP 6000, node 2는 public IP 6001 라고 구성할 때, 별도로 세팅해야 하는 게 있나요???

방화벽 유무, 있다면 Inbound 잘 열어 주셔야 하고…

집에서 서버를 셋팅하셨다면, Public IP가 제대로 들어가야겠죠

NAT를 타고 다른 IP로 바뀌게 된다면 Peer 검색 안될 겁니다.