catapult-service-bootstrapにpeer-nodeを追加する その２ サーバー編

# 概要

[catapult-service-bootstrapにpeer-nodeを追加する その１ サービス追加](https://qiita.com/planethouki/items/b80fe29157d80a63122c)

今回は、別々のサーバーでやってみようと思います。

既存のサーバーで、`catapult-service-bootstrap`が動いているとします。新規のサーバーに、`peer-node-2`を立ち上げ、既存サーバーの`peer-node-1`に接続します。

前回とは異なり、サーバー間接続となるため、ポート開放の設定が必要になってきます。

# 作業

## 既存サーバー

### ファイアウォール設定

7900番ポートをあけましょう。


### ファイル編集

#### docker-compose.yml

`peer-node-1`の7900番ポートをあけます。`ports`のところを追加します。

```yaml:docker-compose.yml
  peer-node-1:
    build: dockerfiles/catapult
    command: bash -c "/bin-mount/wait /state/peer-node-1-nemgen && /bin/bash /userconfig/startServer.sh"
    ports:
    - "7900:7900"
    stop_signal: SIGINT
    volumes:
    - ./build/catapult-config/peer-node-1/userconfig/resources/:/userconfig/resources/
    - ./data/peer-node-1:/data:rw
    - ./bin/bash:/bin-mount
    - ./build/state:/state
    depends_on:
    - generate-configs
    - peer-node-1-nemgen
```

#### peers-p2p.json

※この設定は行わなくてもいけます。

新規サーバーの`peer-node-2`の公開鍵とホスト名を設定します。

公開鍵は、build/generated-addresses/addresses.yamlを開き、peer_nodes以下にあるアカウントの3番目のものを使います。（1番目は`peer-node-0`が、2番目は`peer-node-1`が使用しています。）

これを`peer-node-1`の下に挿入します。カンマを忘れないで。

```peers-p2p.json
    {
      "publicKey": "<new server public key>",
      "endpoint": {
        "host": "<new server host name>",
        "port": 7900
      },
      "metadata": {
        "name": "peer-node-2",
        "roles": "Peer"
      }
    }
```

※この設定により、新規サーバーの`peer-node-2`がダウンした場合、既存サーバーの`peer-node-1`の挙動が変わります。この設定を行わなかった場合、何もしません。この設定を行った場合は、接続エラーが出力されます。

### コンテナ再作成

ポート設定を変更したので、コンテナを作り直す必要があります。

```bash
$ docker-compose stop peer-node-1
Stopping catapult-service-bootstrap_peer-node-1_1 ... done
$ docker-compose up -d peer-node-1
Starting catapult-service-bootstrap_generate-configs_1 ... done
Starting catapult-service-bootstrap_peer-node-1-nemgen_1 ... done
Recreating catapult-service-bootstrap_peer-node-1_1      ... done
```

### コンテナ確認

`0.0.0.0:7900->7900/tcp`となっていることを確認します。

```bash
$ docker-compose ps
                       Name                                      Command               State            Ports         
----------------------------------------------------------------------------------------------------------------------                          
catapult-service-bootstrap_peer-node-1-nemgen_1       bash -c /bin-mount/wait /s ...   Exit 0                         
catapult-service-bootstrap_peer-node-1_1              bash -c /bin-mount/wait /s ...   Up       0.0.0.0:7900->7900/tcp     
...
```

### データコピー

buildディレクトリをアーカイブするなりして、新規サーバーへ送ります。

```bash
tar cfzv /path/to/build.tar.gz build
scp /path/to/build.tar.gz user@new-host:/path/to/build.tar.gz
```

## 新規サーバー

### 時刻確認

`ntpq -p`や`date`で、時刻が正しいことを確認します。

### ファイアウォール設定

7900番ポートをあけましょう。

### catapult-service-bootstrap

```
git clone https://github.com/tech-bureau/catapult-service-bootstrap.git
cd catapult-service-bootstrap
```

### データコピー

`build.tar.gz`を展開し、設定ファイルを作ります。

```
mv /path/to/build.tar.gz .
tar xfzv build.tar.gz
cd build/catapult-config
cp -r peer-node-0 peer-node-2
cd peer-node-2/userconfig/resources
```

### ファイル編集

#### config-harvesting.properties

`build/generated-addresses/addresses.yaml`を開き、`nemesis_addresses_harvesting`以下にあるアカウントの2番目の秘密鍵を設定します。（1番目は`peer-node-0`が使用しています。）

```config-harvesting.properties
harvestKey = <nemesis_addresses_harvesting private key>
```

#### config-node.properties

`[localnode]`の箇所を変更します。ここで設定したホスト名が`peer-node-1`に伝わります。

```config-node.properties
[localnode]

host = <new server host name>
friendlyName = peer-node-2
version = 0
roles = Peer
```

#### config-user.properties

`build/generated-addresses/addresses.yaml`を開き、`peer_nodes`以下にあるアカウントの3番目の秘密鍵を設定します。（1番目は`peer-node-0`が、2番目は`peer-node-1`が使用しています。）

```config-user.properties
[account]
  
bootKey = <peer_nodes private key>
```

#### peers-p2p.json

`peers-p2p.json`を設定します。`peer-node-0`は接続できないので削除します。`peer-node-1`には、既存サーバーのホスト名を設定し、`peer-node-2`には、新規サーバーのホスト名を設定します。

```peers-p2p.json
{
  "_info": "this file contains a list of peer_node peers",
  "knownPeers": [
    {
      "publicKey": "<peer-node-1 public key>",
      "endpoint": {
        "host": "<existing server hostname>",
        "port": 7900
      },
      "metadata": {
        "name": "peer-node-1",
        "roles": "Peer"
      }
    },
    {
      "publicKey": "<peer_nodes public key>",
      "endpoint": {
        "host": "<new server hostname>",
        "port": 7900
      },
      "metadata": {
        "name": "peer-node-2",
        "roles": "Peer"
      }
    }
  ]
}
```

#### peers-api.json

`api-node-0`には接続できないので、削除します。

```peers-api.json
{
  "_info": "this file contains a list of api_node peers",
  "knownPeers": [
  ]
}
```

#### docker-compose.yml

`peer-node-2`に必要な`generate-config`と`peer-node-2-nemgen`だけ設定し、あとは削除します。

```docker-compose.yml
version: '2'
services:

  generate-configs:
    build: dockerfiles/ruby-alpine
    command: ash -c "/bin-mount/wait /addresses/addresses.yaml && /ruby/bin/generate-and-write-configurations.rb /addresses/addresses.yaml /config-build /nemesis && touch /state/configs-generated"
    volumes:
    - ./bin/ash:/bin-mount
    - ./ruby:/ruby
    - ./build/generated-addresses:/addresses
    - ./build/catapult-config:/config-build
    - ./build/nemesis:/nemesis:rw
    - ./build/state:/state:rw

  peer-node-2-nemgen:
    build: dockerfiles/nemgen
    command: bash -c "/bin-mount/wait /state/configs-generated && /bin/bash /userconfig/nemgen.sh && touch /state/peer-node-2-nemgen"
    stop_signal: SIGINT
    volumes:
    - ./build/nemesis/:/nemesis
    - ./data/peer-node-2:/data:rw
    - ./bin/bash:/bin-mount
    - ./build/state:/state:rw
    depends_on:
    - generate-configs

  peer-node-2:
    build: dockerfiles/catapult
    command: bash -c "/bin-mount/wait /state/peer-node-2-nemgen && /bin/bash /userconfig/startServer.sh"
    ports:
    - "7900:7900"
    stop_signal: SIGINT
    volumes:
    - ./build/catapult-config/peer-node-2/userconfig/resources/:/userconfig/resources/
    - ./data/peer-node-2:/data:rw
    - ./bin/bash:/bin-mount
    - ./build/state:/state
    depends_on:
    - generate-configs
    - peer-node-2-nemgen
```

### 起動

```bash
$ docker-compose up -d peer-node-2
Starting catapult-service-bootstrap_generate-configs_1 ... done
Creating catapult-service-bootstrap_peer-node-2-nemgen_1 ... done
Creating catapult-service-bootstrap_peer-node-2_1        ... done
```

ログを確認。

ブロック同期に時間がかかります。

```
$ docker-compose logs -f
<debug> (chain::ChainSynchronizer.cpp@290) pulling blocks from remote with common height 15121 (fork depth = 0) 
<info> (chain::ChainSynchronizer.cpp@203) peer returned 360 blocks (heights 15122 - 15481) 
<debug> (disruptor::Disruptor.cpp@42) disruptor queuing element 43 (360 blocks (heights 15122 - 15481) [1A000000] from Remote_Pull) 
<info> (chain::RemoteApiForwarder.h@65) completed 'synchronizer task' (peer-node-1 @ catapult48gh23s.xyz) with result Success 
<debug> (utils::StackLogger.h@37) pushing scope 'PosImportanceCalculator::recalculate' 
<debug> (observers::PosImportanceCalculator.cpp@65) recalculated importances (22 / 28 eligible) 
<debug> (utils::StackLogger.h@47) popping scope 'PosImportanceCalculator::recalculate' (0ms) 
<debug> (chain::UtUpdater.cpp@79) confirmed 5 transactions, reverted 0 transactions 
<info> (disruptor::ConsumerDispatcher.cpp@44) completing processing of element 43 (360 blocks (heights 15122 - 15481) [9CEE4428] from Remote_Pull), last consumer is 0 elements behind 
<debug> (chain::CompareChains.cpp@95) comparing chain scores: 158552475135475696 (local) vs 1197524055563978542 (remote) 
```

## 確認

### Block Explorer

ブロックエクスプローラーを見てみます。

ハーベストするピアノードを追加したことにより、Harvesterが二人になりました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/172833/2b6d982c-4fd4-fd1f-6927-21c175ab4cca.png)

### peer-node-2

なお、`peer-node-2`（新規サーバー）では、`peer-node-0`と`api-node-0`へ接続できないというエラーが出ます。想定通りとして、無視するのもアリだと思います。

`api-node-0`や`peer-node-0`も7900番ポートで動いているので、これらと接続するためには、7900番ポート以外で運用する必要があります。そうなると、既存サーバー側の接続設定もいくつか変更する箇所が出てきます。

```
<error> (ionet::PacketSocket.cpp@456) failed when resolving address 'peer-node-0': Host not found (authoritative) (cancelled? false) 
<error> (ionet::PacketSocket.cpp@456) failed when resolving address 'api-node-0': Host not found (authoritative) (cancelled? false) 
```

### peer-node-1

`peer-node-1`（既存サーバー）では、このような「接続に成功した」ログが表示されると思います。

```
<debug> (net::Challenge.cpp@55) verify signature result: true 
<debug> (net::Challenge.cpp@47) preparing challenge response 
<debug> (net::VerifyPeer.cpp@107) VerifyClient completed with Success (None) 
<debug> (net::PacketReaders.cpp@189) accepted connection from '<new server ip>' as <peer-node-2 public key>
<info> (extensions::NetworkUtils.h@49) accept result to local node port 7900: Accepted 
```

### peer-node-0

`peer-node-0`では、`peer-node-2`（新規サーバー）のホスト名が取得できていません。ホスト名情報は、直接接続するか、`peers-p2p.json`に書かなければならないということでしょうか。

```
<error> (ionet::PacketSocket.cpp@456) failed when resolving address 'peer-node-2': Host not found (authoritative) (cancelled? false) 
<debug> (net::PacketWriters.cpp@142) aborting connection to: peer-node-2 @ peer-node-2 
<warning> (extensions::PeersConnectionTasks.cpp@97) connection attempt to peer-node-2 @ peer-node-2 completed with Socket_Error 
```

# 所感

`catapult-service-bootstrap`に、別サーバーのピアノードを追加することができました。

`peer-node-2`と接続関係にない`peer-node-0`でも、`peer-node-2`の情報をもっていたので、ピアノード情報を交換しているということが実感できました。逆もしかり。

この作業をしているときに、新規サーバー側の時計が10分以上も早くなっていて、ブロック同期がうまくいきませんでした。時計大事。

ピアノード、APIノード、mongoDB、RESTゲートウェイ、Block Explorerを揃えたサーバーを複数地点で運用すると楽しそう。

複数人で集まって、nemesisブロック作って、ネットワーク作るのもおもしろいと思います。

# 関連記事

catapult-service-bootstrapにpeer-nodeを追加する その１ サービス追加
https://qiita.com/planethouki/items/b80fe29157d80a63122c

catapult-service-bootstrapにpeer-nodeを追加する その２ サーバー編
https://qiita.com/planethouki/items/4c73a6b924b92529bd32

catapult-service-bootstrap その３ ホスト名とポート変更
https://qiita.com/planethouki/items/d365f2344c0f7a6c3523

catapult-service-bootstrap その４ チェーンの手動削除
https://qiita.com/planethouki/items/7ec5404701adeb96bb8e

catapult-service-bootstrap その５ catapult.tools.health/network
https://qiita.com/planethouki/items/5ed19ae8ceb67ad6fee0