11
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ビットコインとか忘年会

こちらのイベントで「フルノード職人の朝は早い」というタイトルでフルノードの建て方をLTしました。

この記事ではEVM系のチェーンであるEthereum(メインネット)およびArbitrum、Optimism、Binance Smart Chain、Avalancheと、LTでは触れられなかったPolygonのフルノードの建て方を紹介します。

マシン構成

クラウド課金地獄

クラウドを使ってもいいのですが、普通にこれらすべてのチェーンを動かそうとするとメモリが最低でも64GB、SSDが15TBとか必要になりますので、月額何千ドルもかかってしまいます。

実際、DigitalOceanという格安VPSで作っていたのですが、月1,200ドル(当時のレートで約20万円)を請求されて泣きそうになりました。

そこで僕は自宅にワークステーション(という名の自作PC)を作り、自宅サーバとして運用しています。

ちなみにOSはUbuntu 22.04 LTSです。

マシン構成

CPUは8コア以上、メモリ64GB以上、SSDが15TB以上あれば十分かと思います。

僕の場合には以下のような構成で組みました。

種類 モデル 参考価格
マザーボード ASRock B550M Phantom Gaming 4 11,680円
CPU AMD Ryzen 9 3950X 16コア 廃盤(現世代では7950X=80,000円相当)
メモリ A-DATA 32GB DDR4 3,200MT/s x 4 = 128GB 1枚15,000円 x 4 = 60,000円
SSD (OS) NVMe 2TB x 2 (RAID 1) 1枚10,000円 x 2 = 20,000円
SSD (データ) SATA 8TB x 4 (RAID 5 + LVM) 1枚56,800円 x 4 = 227,200円
その他 電源、ケース、GPUなど 40,000円くらい
合計 438,880円

初期投資としてはかなり高額かと思います。

特にSSD代で半分以上を占めており、ストレージに一番お金がかかっています。

ちなみに安いHDDで組むと、IOが足らずに同期が終わらなくなりますのでSSDへの課金は必須です。

CPUについては16コアのものを使いましたが、8コアぐらいでも大丈夫かと思います(試していないので分かりませんが)。

メモリについては最低でも64GBくらいないとgethがキャッシュとしてメモリを大量に食いますのでスワップしまくって大変になります。

メモリは正直載せれば載せるほどディスクキャッシュに回りますので、多ければ多いほどよいです。

ただ、コンシュマー向けのCPUだとAMDのThredripperを除いて128GBまでしか載りませんので、上限を載せています。

まぁメモリはそんな高くないですしね。

なおブロックチェーンは永遠に成長してどんどんディスクを食っていきますので、必ずいずれ足りなくなります。

将来的に拡張できるようにSATAポートが多いマザボを買うか、最初から多めに積んでおくことをおすすめします。

今回のケースでは8TBが4台のRAID5構成なので、8TB×3台=24TBの容量が使えます。

SSDの設定

まずはSSDを使えるように設定していきます。

フォーマット

GPTパーティションをgdiskを使って作っていきます。

$ sudo gdisk /dev/sd[a-d]

RAID構築

$ sudo mdadm --create --raid-devices=4 --level=raid5 /dev/md1 /dev/sda1 /dev/sdb1 /dev/sdc1 /dev/sdd1

これで/dev/md1に三台分の容量のブロックデバイスが出来上がります。

状態確認は

$ cat /proc/mdstat

でできます。

RAIDの構築におおむね半日〜一日程度くらいかかります。

RAIDの構築中にこれ以降の作業をしてもいいのですが、IOが発生しているとRAIDの同期がどんどん遅くなっていってしまいますので、素直に待ったほうがいいと思います。

LVM構築

先程作ったRAIDデバイスをそのままフォーマットして使ってもいいのですが、今後の拡張性のためにLVMを利用しました。

$ sudo pvcreate /dev/md1
$ sudo vgcreate ssd01 /dev/md1
$ sudo lvcreate --name dat01 --size 15T ssd01

ボリュームグループ名はssd01、論理ボリューム名はssd01としています。

FS作成

最後にファイルシステムを作っていきマウントします。

$ sudo mkfs -t ext4 /dev/mapper/ssd01-dat01
$ sudo mkdir /mnt/dat01
$ sudo mount /dev/mapper/ssd01-dat01 /mnt/dat01
$ sudo vi /etc/fstab
/dev/mapper/ssd01-dat01 /mnt/dat01	ext4		defaults,nofail	0	0

これでブロックチェーンデータ用の大容量SSDの作成は終わりです。

容量が足りなくなったらlvextendで拡張しましょう。

Ethereum (geth)

インストール

公式のPPAリポジトリがありますのでこちらからインストールします。

$ sudo add-apt-repository -y ppa:ethereum/ethereum
$ sudo apt-get update
$ sudo apt-get install ethereum

起動

gethはデフォルトで$HOME/.ethereumを使いますので、大容量SSDへのシンボリックリンクを張ります。

$ ln -s /mnt/dat01/ethereum $HOME/.ethereum

あとは普通に起動します。

$ geth

デフォルトでスナップショット同期が行われますが、同期が完全に終わるまでだいたい2〜3日くらい(もちろんCPUはネットワーク帯域にも依存しますが)かかります。

状態確認は

$ geth attach
> eth.syncing
> eth.blockNumber

でできます。

自動起動

さて、マシンを再起動するたびに手動で起動するのは非常に面倒です。

そこでsystemdデーモン化しましょう。

$ sudo vi /etc/systemd/system/geth.service
[Unit]
Description=Go Ethereum
After=syslog.target network.target

[Service]
User=visvirial
Group=visvirial
Type=simple
ExecStart=/usr/bin/geth --http --http.api debug,eth,net,rpc,txpool,web3 --http.addr 0.0.0.0 --http.vhosts '*' --http.corsdomain '*'
KillMode=process
KillSignal=SIGINT
TimeoutStopSec=600    // ⇦ 止めるときに10分くらいまで待たないとDBがぶっ壊れるので注意!
estart=on-failure
RestartSec=10s

[Install]
WantedBy=multi-user.target

一つ注意なのがTimeoutStopSecに十分大きな値(10分とか)を指定することです。

デフォルトでは90秒だったと思いますが、この時間ではgethがオンメモリキャッシュをディスクにフラッシュするのが終わらず、強制終了になってしまい、最悪データベースが壊れて同期を一からやり直しになります。

実際、僕もこれもDBをぶっ壊して泣きながら同期し直しましたので気をつけてください。

Arbitrum

スナップショット

チェーンのジェネシスブロック(?)的なデータが必要なのでこれをダウンロードします。

執筆時点で350GiBくらいありました。

非常に巨大なので計画的にダウンロードしましょう。

ちなみにwgetやcurlなどを使うと、途中でネットワークが不安定になった場合にダウンロードがエラーとなってやり直しになってしまい非常に辛いです。

ですのでaria2cなどのダウンロードツールを使うことを強く推奨します。

Docker

公式でDockerイメージを配布しており、こちらを使うのが最も簡単です。

$ docker run --name arbitrum -itd --restart unless-stopped -v /mnt/dat01/arbitrum:/home/user/.arbitrum -p 0.0.0.0:8547:8547 -p 0.0.0.0:8548:8548 offchainlabs/nitro-node:v2.1.3-e815395 --parent-chain.connection.url http://172.17.0.1:8545 --chain.id=42161 --http.api=net,web3,eth,debug --http.corsdomain=* --http.addr=0.0.0.0 --http.vhosts=*

--restart unless-stoppedを指定するとマシンを再起動しても自動的に起動してくれますので便利です。

Optimism

インストール

op-gethop-nodeの二つのプロセスが必要です。

ビルドの仕方は以下のサイトに詳しく載っていますので、こちらに従ってビルドしてください。

スナップショット

Arbitrumと同様、ジェネシスブロックのデータ的なもの (Bedrock) がありますので、こちらをダウンロードします。

300GBくらいありますので計画的にダウンロードしましょう。

共通鍵作成

op-gethop-nodeをつなげるのにJWTファイルを作る必要があります。

$ cd op-geth
$ openssl rand -hex 32 > jwt.txt
$ cp jwt.txt ../optimism

起動

op-geth

#!/bin/bash

SEQUENCER_URL=https://mainnet-sequencer.optimism.io/

./build/bin/geth \
  --datadir=./datadir \
  --http \
  --http.port=8549 \
  --http.addr=0.0.0.0 \
  --http.corsdomain '*' \
  --authrpc.addr=localhost \
  --authrpc.port=8552 \
  --authrpc.jwtsecret=./jwt.txt \
  --verbosity=3 \
  --rollup.sequencerhttp=$SEQUENCER_URL \
  --nodiscover \
  --syncmode=full \
  --maxpeers=0 \
  --port=30304

こんな感じのスクリプトファイルを作って起動しましょう。

op-node

#!/bin/bash

L1URL=http://localhost:8545
L1KIND=debug_geth
NET=mainnet

./op-node/bin/op-node \
    --l1=$L1URL  \
    --l1.rpckind=$L1KIND \
    --l2=ws://localhost:8552 \
    --l2.jwt-secret=./jwt.txt \
    --network=$NET \
    --rpc.addr=0.0.0.0 \
    --rpc.port=8550

こちらも同様でこんな感じのスクリプトを作ります。

公式との違いは、L1KINDdebug_gethを指定することです。

デフォルトのbasicだと非常に遅く、同期が何週間もかかります。

debug_gethを指定すれば一週間くらいで同期できます。

Binance Smart Chain

インストール

$ wget $(curl -s https://api.github.com/repos/bnb-chain/bsc/releases/latest |grep browser_ |grep geth_linux |cut -d\" -f4)
$ mv geth_linux geth
$ chmod -v u+x geth

genesis.json/config.tomlのダウンロード

$ wget $(curl -s https://api.github.com/repos/bnb-chain/bsc/releases/latest |grep browser_ |grep mainnet |cut -d\" -f4)
$ unzip mainnet.zip

スナップショットのダウンロード

公式のスナップショットもあるのですが、BNB48Clubという人たちが提供してくれているもののほうがpruningされているため、データ量が少ないです。

約400GBあります。

起動

$ ./geth --config ./config.toml --datadir ./node --cache 8000 --rpc.allow-unprotected-txs --txlookuplimit 0 --tries-verify-mode none --snapshot=false --syncmode full --http.port 8546

Avalanche

インストール

$ wget -nd -m https://raw.githubusercontent.com/ava-labs/avalanche-docs/master/scripts/avalanchego-installer.sh
$ chmod 755 avalanchego-installer.sh
$ ./avalanchego-installer.sh

これを実行すると$HOME/avalanche-node/avalanchegoという実行ファイルがダウンロードされます。

起動

$ $HOME/avalanche-node/avalanchego --config-file=/home/visvirial/.avalanchego/configs/node.json

Polygon

インストール

Heimdallborの二つが必要です。

Heimdall

$ curl -L https://raw.githubusercontent.com/maticnetwork/install/main/heimdall.sh | bash -s -- v1.0.3 mainnet heimdall
$ sed -i 's|^seeds =.*|seeds = "seed_details"|g' /var/lib/heimdall/config/config.toml

Bor

$ curl -L https://raw.githubusercontent.com/maticnetwork/install/main/heimdall.sh | bash -s -- v1.0.3 mainnet bor
sed -i 's|.*bootnodes =.*|bootnodes = "mainnet_bootnodes"|g' /var/lib/bor/config.toml

スナップショット

Heimdall

curl -L https://snapshot-download.polygon.technology/snapdown.sh | bash -s -- --network mainnet --client heimdall --validate-checksum true

だいたい400GBくらいあります。

aria2cを使って分割されたファイルをダウンロードしたあとに合体し、チェックサムの検証とアーカイブの展開までやってくれます。

Bor

curl -L https://snapshot-download.polygon.technology/snapdown.sh | bash -s -- --network mainnet --client bor --validate-checksum true

だいたい3TBくらい(!)あるので計画的にダウンロードしましょう。

100Mbpsの回線だと3日かかりますので、大変です。

起動

インストールスクリプトが/lib/systemd/system/(heimdalld|bor).serviceを作ってくれますので、普通にsystemctlコマンドで起動できます。

まずはHeimdallを起動して同期を完了させましょう。

Heimdallが同期できるまでBorの同期は開始できないようなので注意してください。

$ sudo systemctl start heimdalld

状態は

curl localhost:26657/status

で確認できます。

.result.sync_info.catching_upfalseになれば同期完了です。

同期できたらBorを起動しましょう。

$ sudo systemctl start bor

同期に二週間くらいかかります。

まとめ

フルノードはTB級のデータを高速に捌かないといけないため、非常に運用が大変です。

スナップショットのダウンロードに時間がかかりますし、スナップショット時点から最新のブロックまで同期するまでも大量のIOが発生するため、SSDでも非常に時間がかかります。

さらっとやり方を書きましたが、全部やり終えるまで二ヶ月くらいかかりました。

それでもなんでフルノードを自前でも使って?

Don't trust, verify.

ですよ!!!

まぁ実務的にはRPCのホスティングサービスがどれも不安定で(ちゃんと課金しているにもかかわらず)よく通信に失敗するので、自前のサーバにつないでよしなにやるために必要で仕方なく運用しているというのが実情です。

おまけ

同期ダッシュボード

サーバにいちいちログインして一つ一つ同期状態を確認するのはなかなか大変です。

そのため同期状態が一発で分かるダッシュボードを作りました。

オープンソースなので、よろしければ改造して使ってください。

(※RPCは全世界に公開していますが、基本的に自分用なので勝手に繋がないでください)

NATを越えろ!

自宅サーバで運用しているため、外部からアクセスできるようにするためにはNAT超えをする必要があります。

僕の場合にはWireGuardでVPNとしてつないで、nginxでリバースプロキシしています。

ローカルでしか使わないのであれば必要ないと思います。

最後に

フルノード建てるの楽しいよ!みんなもやってみてね!!!

11
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?