QuorumのConstellationを構築する


# 記事の内容
ConstellationはQuorumの追加機能で「自己管理型のピアツーピアシステム」です。
Tessera同様にConstellationもQuorumの追加機能なので、この記事では環境構築の手順をメモします。

※公式ドキュメントに「Migration from Constellation」という項があり、Tesseraを構築していればConstellationは不要なのかもしれません。

# 前提条件
Quorumの環境構築が出来ていること

[Quorum with Raft consensus](https://docs.goquorum.com/en/latest/Getting%20Started/Creating-A-Network-From-Scratch/#quorum-with-raft-consensus)

# Constellationとは？
[Constellation](https://docs.goquorum.com/en/latest/Privacy/Constellation/Constellation/)のドキュメントに書いている内容です。（google翻訳）


〇　多くのNaCl（Curve25519）公開/秘密鍵ペアをホストする
〇　1つの他のホストと同期した後、ネットワーク上の他のノードを自動的に検出する
〇　受信者ホストにマップされた公開鍵のディレクトリをネットワーク上の他のノードと同期する
〇　他のノードが暗号化されたバイト文字列をノードに送信し、同期して、ノードが知っているノードに関する情報を取得できるようにするパブリックAPIを公開
〇　次のプライベートAPIを公開する
バイト文字列を1つ以上の公開鍵に送信して、内容アドレス指定可能な識別子を返すことができます。このバイト文字列は、透過的かつ効率的に（対称暗号化速度で）暗号化されてから、正しい受信者ノード（およびそれらのノードのみ）にネットワーク経由で送信されます。　識別子は、すべての受信者ノードが受信する暗号化されたペイロードのハッシュダイジェストです。
　各受信者ノードは、暗号化されたペイロードのマスターキーを含む公開鍵用に暗号化された小さなblobも受信します。
〇　LevelDB、BerkeleyDB、SQLite、および任意のFUSEアダプターでの使用に適したDirectory / Maildirスタイルのファイルストレージを含む、いくつかのストレージバックエンドをサポートします。 
〇　相互認証されたTLSを最新の設定で使用し、ハイブリッドCA / tofu（デフォルト）、tofu（OpenSSHと考える）、ホワイトリスト（公開鍵の一部のセットのみが接続できます）などのさまざまな信頼モデルを使用します。
〇IPホワイトリストのようなアクセス制御をサポートする

# 環境構築
## 準備
### stackのインストール
ConstellationがHaskellで書かれているため、コンパイラであるstackをインストールしておく必要があります。
https://haskell.e-bigmoon.com/stack/intro/stack-install.html

### dnfのインストール
公式ドキュメントに載っているconstellationのインストールコマンドがyumではなくdnfであるため、dnfをインストールしておきます。

~~~
yum -y install dnf
~~~

## インストール
~~~
dnf install libdb-devel leveldb-devel libsodium-devel zlib-devel ncurses-devel
~~~

完了すると以下のディレクトリにインストールされました。
パスを通しておきます。

~~~
$ ls /root/.local/bin/
constellation-node
$ export PATH=$PATH:/root/.local/bin
~~~

## キー生成
Key Generateの処理を動かします。
ConstellationはP2P管理のシステムなのでnode間通信が発生します。
この記事ではnode1とnode2を作成します。
ディレクトリ

~~~ /home/quorum
$ mkdir node1c
$ cd node1c
$ constellation-node --generatekeys=node1
$ cd ..
$ mkdir node2c
$ cd node2c
$ constellation-node --generatekeys=node2
~~~
constellation-nodeコマンドを実行するとパスワードの入力を求められますので、パスワードを設定します。

## Constellationノードの起動
ノードを起動します。
公式ドキュメントには以下のコマンドが記載されています。

~~~
$ constellation-node --url=https://127.0.0.1:9001/ --port=9001 --workdir=. --socket=tm.ipc --publickeys=new-node-1.pub --privatekeys=new-node-1.key --othernodes=https://127.0.0.1:9001/ >> constellation.log 2>&1 &
~~~
このコマンドだとバックグラウンドで起動されていますが、コマンドを実行するとパスワードを求められるのでパスワードを入力出来ず、処理が止まってしまいました。

ノード１とノード２のそれぞれ起動します。
### node1起動

~~~
constellation-node --url=https://127.0.0.1:9010/ \
--port=9010 \
--workdir=./node1c \
--socket=node1-constellation.ipc \
--othernodes=https://127.0.0.1:9011/ \
--publickeys=node1.pub \
--privatekeys=node1.key \ 
--verbosity=2 \
--password=password
~~~

--verbosity
ログレベルのオプションで以下の出力レベルになる
   - 0: Only fatal errors
   - 1: Warnings
   - 2: Informational messages
   - 3: Debug messages

--password=password
passwordにはキー生成時に設定したパスワードを入力しておく。
このファイル名を--passwordオプションにファイル名を設定する

### node2起動

~~~
constellation-node --url=https://127.0.0.1:9011/ \
--port=9011 \
--workdir=./constellation \
--socket=node1-constellation.ipc \
--othernodes=https://127.0.0.1:9010/ \
--publickeys=node.pub \
--privatekeys=node.key \
--verbosity=2 \
--password=password
~~~
ノード１とノード２ではothernodesに互いのノードを指定する必要があります。
その為、起動コマンドのポートが異なりますので注意が必要です。

コンソールに以下のログが出力され始めたら構築が通信出来ているみたいです。

~~~
07:13:14 [INFO] Starting synchronization with https://127.0.0.1:9010/
07:13:15 [INFO] Finished synchronization with https://127.0.0.1:9010/
~~~