SuperNodeを目指してノード環境を準備する


## やりたいこと

Symbolのローンチが近づき、ノード運用をしたいと考えるとステーキング(報酬)が用意されているので、より高額な報酬を受けるために、残高さえあれば最終的にスーパーノードを目指したい。
でも、サーバを自前で構築・運用する必要があるので、環境構築や運用費用、セキュリティを意識して(自分の中で)実運用でも問題ない設計を考える

## 報酬(ステーキング)について簡単に

Symbolでは報酬パターンが複数あり、まだ全ての報酬が完全に決まってなさそう。(もう年末には全て決まってると思ってた)
今回、どの程度の報酬とかやると長くなるので(あんまりそこまで分かってない)、パターンだけ書くと

* ブロック報酬
    * ローカルハーベスティング
    * デリゲーテッドハーベスティング
* ノードサービス報酬
* スーパーノードプログラム
* Early Node Incentives
* Nem Eco Systemボーナス
* ファイナライズのVoting(投票権)報酬(ブロック報酬だけど、報酬はsinkからとかまだ未決定ぽいので、一旦別項目で・・・)

現時点で(12/21)では、フォーラムで議論が止まってるので、ローンチまでには何かしらきっと決まると思います。

https://forum.nem.io/t/symbol-tokenomics-update/26516
https://forum.nem.io/t/catapult-migration-and-tokenomics-proposal-for-nem-community-poi-vote/24033


## SuperNodeとは

公式サイトにまだスーパーノードプログラムの記載がないので、ほぼ[NIS1のSuperNode条件](https://nemplatform.com/supernode-program/)とほぼ同じとなるはず
SuperNodeは以下のような項目を合格した高スペックなノードを用意して、長期運用することで報酬をもらう
ただし、報酬は現時点では6年間程度しかない。

Symbolのスーパーノードプログラムの条件として確実なのは最低残高が3階層の報酬システムに変更されたことぐらいしか情報がないので、NIS1の条件を元に考える。

|項目|しきい値|
|---|---|
|ネットワーク帯域|5Mbps以上|
|ブロック高|参照ノードから4ブロック内|
|チェーンパーツ|50ブロックの範囲で正確にアップロードされている|
|計算能力| 2000 Iterations/s 以上|
|最低残高|3階層報酬システムに 1,000,000 XYM, 2,000,000 XYM, 3,000,000 XYM|
|バージョン|常に最新であること|
|ping|200ms以下の応答速度|
|レスポンシブ|10個の連続した要求に応える|


## サーバ周りの環境検討

今回は[AWS](https://aws.amazon.com/)でノード構築を検討する。
テストネットでしばらく運用してみて思ったが、初期同期時と高負荷時は、スペックがそこそこでは継続的なノード運用が難しい。

### 固定IPアドレスはいるか？

ずっとノードを運用する以上、IPアドレスは固定化しないとIPアドレスが変わってしまうので固定化サービスのElastic IPで取得する
(AWSでは紐付けたインスタンスが起動していれば、固定IPアドレスが無料)

### サーバ(インスタンス)はどの程度のスペック？

通常のノード要件を確認すると、`4コア、8GB以上` とある
https://docs.symbolplatform.com/guides/network/using-symbol-bootstrap.html

でも、実際テストネットで同じくらいのスペックでやると初期同期100,000ブロック付近で、dockerコンテナがCPU不足やメモリ不足で落ちるときがあって安定しなかった。
AWSのインスタンスはSwap領域がないのでSwapファイルを作って逃げる方法もあるが、メモリ不足が発生してSwapに退避すると遅くなるので十分なスペックを確保する。


AWSのEC2インスタンスでどの程度必要かを考えると種類がいっぱいあるので迷うが、 現時点では一旦ネットワーク帯域が高い `c5nファミリー` の `2xlarge以上` あたりを選択する
(インスタンスタイプの変更は、後からでも簡単にできるし、あくまでここはSuperNodeを目指しているので)

https://aws.amazon.com/jp/ec2/instance-types/

|モデル|	vCPU|	メモリ (GiB)|	インスタンスストレージ (GiB)|	ネットワーク帯域幅 (Gbps)|EBS 帯域幅 (Mbps)|
|---|---|---|---|---|---|---|
|c5n.2xlarge|	8	|21	|EBS のみ	|最大 25|	最大 4,750|

### ディスクはどの程度の速さで容量は結構いる？

ディスクはAWS EBSで外付けマウントし、そこにsymbolのデータを丸々置く。
ディスクサイズやIOPSは後からでも簡単に増やせるが、ちょうどre:Inventでボリュームタイプに[gp3](https://aws.amazon.com/jp/about-aws/whats-new/2020/12/introducing-new-amazon-ebs-general-purpose-volumes-gp3/)が発表されて、今までのgp2より安くて早いディスクにできた。

| 種類 | ボリュームタイプ | ボリュームサイズ | IOPS| 
|:-:|:-:|:-:|:-:|
| root | gp3 | 8GB | 3000 |
| data  | gp3  | 300GB  | 3000 |

### サーバ費用感はどれくらいだろう？

`c5n.2xlarge` でいくならネットワーク料金も含むと大体45,000円/月ぐらい
3年前払いなしリザーブドインスタンスを購入すれば20,000円/月ぐらいに抑えることができる
高額だが、VPSやベアメタルだと可用性を確保できないので・・・

https://calculator.aws/#/estimate?id=dd9d832a4ed6e7c4d88b9e0877a5b3506e805ef6

### セキュリティどうしよう？

3000ポートと7900ポートと監視ポート？だけインターネットに空いてればOKな、セキュリティグループ(ファイアウォール的な)を作成する
不要にSSHポートを外に開けてると攻撃受けるので、SSH経由ではなくAWS System Managerのセッションマネージャー経由でリモート接続する。
そうすることで、AWSアカウント権限がない限りはログインできないセキュアな環境になる。
(とはいえ、AWSアカウントの2FA化してない、AWSアクセスキーの漏洩とかは気をつける)
送受信のネットワークトラフィックはAWS側のセキュリティグループ設定で事足りるので、OSレベルではファイアウォール設定はしない。

## ということでSymbolノードを構築する

今回企業ではよく使うAWS上で構築するので、以下のような構成図のネットワーク構成上にsymbolノードを立ち上げるオーケストレーション(Cloudformation)テンプレートを書いてみた。
Symbolのノード構築方法はいっぱい文献あり参考にさせて頂いたが、Symbolカスタマイズは一旦はやめて、「AWS上で環境を作り、Symbolノードを構築する」ことを重点に置いた。

AWS上の構築方法は以下のgithubのREADMEに記載。
mijinのように[Marketplace](https://aws.amazon.com/marketplace/pp/B08HDPWV4L?qid=1608600136319&sr=0-1&ref_=srh_res_product_title)で提供はしていないので、AWSの知識が多少は必要で、もちろん構築は自己責任で・・・。
(急いで作ったのでバグあるかも・・・)

https://github.com/keiyow/symbol-aws-cloudformation


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135107/9f3c7771-19d3-bcca-393a-94edbfada171.png)

### 構築内容

git上のスタックボタンを押して、項目選択しCreateStackを押すと、10分ぐらいで以下のものが作られる

* VPC
    * public subnet
    * RouteTable
    * InternetGateway
* セキュリティグループ
    * インバウンドに対して3000ポートと7900の許可、監視ポートは後回し
    * アウトバウンドは全許可
* Elastic IP(固定IPアドレス)
    * EC2インスタンスに紐付け
* EC2インスタンス
    * Ubuntu20(全リージョン対応しているはず)
* EBS(外付けディスク)
    * /mnt/symbolにxfsでフォーマットしてマウント
* dockerとかnodeなどミドルウェアのインストール
    * とりあえず最新でなく、Repositoryにあった最新で・・・
* symbol-bootstrapの実行
    * とりあえずまだtestnetしかないので、testnet限定で
    * /mnt/symbol/data以下にbootstrapを実行
    * votiningのファイルは作るが、keylinkするには残高いるので後回し

スーパーノードの監視プログラム？現時点で何も情報もないので、とりあえず今回は無視で頭にだけ入れておく

## Symbolアカウントのセキュリティ

ノードを構築した後は、アカウント周りをちゃんと考えたい。
1,000,000XYM以上を保持することを考えると、サーバセキュリティだけでなく、アカウントの管理も含めてセキュリティをしっかり考える必要がある。
サーバセキュリティだけだともし盗まれた時、ある程度権限があるインフラの人間が真っ先に内部犯行を疑われてしまうからだ。
そこでsymbolの機能を活用してみる。

**1. ノードの秘密鍵が盗まれた、見られた場合でも送金できないようにする**
**2. 連署者が裏切ったとしてもトランザクション監視の仕組みさえ用意しておけば、転送失敗かアカウント制限解除がでるので、クッションがある**

というようなアカウントにするには、以下のようにする

* アカウントはマルチシグ化する
    * 9人ぐらいで2/3以上の承認/削除とかにする
* アカウント操作制限をする
    * 転送トランザクションを禁止してしまう
* アカウントのトランザクションを監視する
    * アカウント制限が解除されていないか、トランザクションが送信されていないかなど

アグリゲートボンデッドトランザクション使って、作れば大丈夫
監視はサーバーレスで十分だしLambdaでと思ったが常時起動できないし、CloudwatchEventで定期実行してもやられた時に即時通知ができないので、常時監視したいからFargateあたりを使う

ここで頑張って実行スクリプト書こうかと思ったが今年は力尽きた・・・。