Beyond Blockchain One (BBc-1) をRaspberry Pi 3で動作させる

# はじめに

「[Beyond Blockchain One (BBc-1) のインストールと簡単な使い方](https://qiita.com/jqtype/items/575e1328a3cd359a5f7c)」で、BBc-1のノード構築方法を紹介しました。これをそのまま利用し、宅内にRaspberry Pi 3 Model BでBBc-1ノードを構築しようとしたのですが、アーキテクチャがX86_64ではないというところでハマるところがありました。今回はその部分の解決方法を中心に、ラズパイでBBc-1のデプロイ方法を紹介します。

また、今回構築したラズパイBBc-1ノードは、テストノードとして公開しておきます。BBc-1の接続テストなどに利用してみてください。(※ただし、個人運用なのでいつ止まってもおかしくないことにご注意くださいませ。)

# 環境

基本的に、ハードウェアとOS等の導入設定、ネットワーク設定は終わっているものと仮定します。今回の環境は以下の通りです。

- Raspberry Pi 3 Model B
- Raspbian Stretch Lite
- Python 3.6.4
- 特定ポート(e.g., 56641)でポートフォワード設定済、InternetからRaspberry Piへ疎通可能

ここで、Raspbian Stretchに入っているのはPython3.5のため、Python3.6.4は公式サイトからダウンロード・コンパイルしています。

```
$ sudo apt-get install libsqlite3-dev libbz2-dev libncurses5-dev libgdbm-dev liblzma-dev libssl-dev tcl-dev tk-dev libreadline-dev ← Python3.6.4のコンパイル用
$ wget https://www.python.org/ftp/python/3.6.4/Python-3.6.4.tgz
$ tar xvf Python-3.6.4.tgz 
$ cd Python-3.6.4/
$ ./configure && make && sudo make install
```

# インストール手順

「[Beyond Blockchain One (BBc-1) のインストールと簡単な使い方](https://qiita.com/jqtype/items/575e1328a3cd359a5f7c)」の手順通りに作業を進めます。今回はソースからインストールします。

1. 必要なパッケージの導入


    ```
    $ sudo apt-get update
    $ sudo apt-get install -y git tzdata openssh-server python3 python3-dev python3-venv libffi-dev net-tools autoconf automake libtool libssl-dev make pkg-config
    ```

2. ソースのダウンロード、OpenSSLのコンパイル、virtualenvの設定

    ````
    $ git clone git@github.com:beyond-blockchain/bbc1.git
    $ cd bbc1
    $ git checkout develop
    $ bash prepare.sh
    $ python3 -m venv .bbc1_venv
    $ source .bbc1_venv/bin/activate
    (.bbc1_venv)$ pip install --upgrade pip
    ````

3. 必要なpipパッケージの導入

    ```
    $ pip install -r requirements.txt
    ......(中略)......
    Command "/home/pi/.bbc1_venv/bin/python3 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-xl_ajnl0/secp256k1/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-gzd08rx6-record/install-record.txt --single-version-externally-managed --compile --install-headers /home/pi/.bbc1_venv/include/site/python3.6/secp256k1" failed with error code 1 in /tmp/pip-build-xl_ajnl0/secp256k1/
    ```

    …コケました。pipインストール中に`secp256k1`のビルドができないようです。どうやら64bitでのビルドが前提になっており、32bit OSであるraspbianではビルド不可能なようです。さて、「Raspberry PiでBBc-1を動作させる」という観点から、2つの方法を取ることが出来ます。

    1. 64bitカーネルを入れる。
    2. `secp256k1`を利用しているBBc-1のサブシステム(Etherium)をオミットする。

    BBc-1のサブシステムとして、「トランザクションの一部を保存させEtheriumの信頼性に相乗りする」という目的のためにEtheriumが利用可能です。ですが、今回はBBc-1を動かすことが目的のため、Etherium自体は不要。従って、手間がかかりそうな1番ではなく2番を選択します。

    まずはrequirements.txtを更新します。

    ```diff:requirements.txt
    diff --git a/requirements.txt b/requirements.txt
    index 9accc8c..06dcda5 100644
    --- a/requirements.txt
    +++ b/requirements.txt
    @@ -4,4 +4,4 @@ requests>=2.12.4
     gevent>=1.2.1
     pytest<=3.2.*,>=3.0.5
     msgpack-python>=0.4.8
    -populus==2.1.0
    +#populus==2.1.0
    ```

    あらためて、pipパッケージのインストールを行います。

    ```
    (.bbc1_venv)$ pip install -r requirements.txt
    ```

4. `bbc_core.py`の起動

    subsystemを無視して起動させるために、`bbc_core.py`を以下のように編集します。色々無視してコメントアウトしているだけなことには目を瞑ってください。


    ```diff:bbc1/core/bbc_core.py
diff --git a/bbc1/core/bbc_core.py b/bbc1/core/bbc_core.py
index e985aa6..3732727 100644
--- a/bbc1/core/bbc_core.py
+++ b/bbc1/core/bbc_core.py
    @@ -40,7 +40,7 @@ from bbc1.common.bbclib import BBcTransaction, ServiceMessageType as MsgType, St
 from bbc1.core import bbc_network, bbc_storage, query_management, bbc_stats
 from bbc1.core.bbc_config import BBcConfig
 from bbc1.core.bbc_ledger import BBcLedger, ResourceType
-from bbc1.core import ledger_subsystem
+#from bbc1.core import ledger_subsystem
 from bbc1.core import command
 from bbc1.common.bbc_error import *
 
    @@ -134,7 +134,7 @@ class BBcCoreService:
         self.networking = bbc_network.BBcNetwork(self.config, core=self, p2p_port=p2p_port, use_global=use_global,
                                                  external_ip4addr=ip4addr, external_ip6addr=ip6addr,
                                                  loglevel=loglevel, logname=logname)
-        self.ledger_subsystem = ledger_subsystem.LedgerSubsystem(self.config, core=self, loglevel=loglevel, logname=logname)
+        #self.ledger_subsystem = ledger_subsystem.LedgerSubsystem(self.config, core=self, loglevel=loglevel, logname=logname)
 
         gevent.signal(signal.SIGINT, self.quit_program)
         if server_start:
    @@ -380,7 +380,7 @@ class BBcCoreService:
                 return False, None
             asset_group_id = dat[KeyType.asset_group_id]
             transaction_id = dat[KeyType.transaction_id]
-            self.ledger_subsystem.register_transaction(asset_group_id=asset_group_id, transaction_id=transaction_id)
+            #self.ledger_subsystem.register_transaction(asset_group_id=asset_group_id, transaction_id=transaction_id)
             retmsg = make_message_structure(MsgType.RESPONSE_REGISTER_HASH_IN_SUBSYS,
                                             dat[KeyType.asset_group_id], dat[KeyType.source_user_id], dat[KeyType.query_id])
             self.send_message(retmsg)
@@ -393,8 +393,8 @@ class BBcCoreService:
             transaction_id = dat[KeyType.transaction_id]
             retmsg = make_message_structure(MsgType.RESPONSE_VERIFY_HASH_IN_SUBSYS,
                                             dat[KeyType.asset_group_id], dat[KeyType.source_user_id], dat[KeyType.query_id])
-            result = self.ledger_subsystem.verify_transaction(asset_group_id=asset_group_id,
-                                                              transaction_id=transaction_id)
+            #result = self.ledger_subsystem.verify_transaction(asset_group_id=asset_group_id,
+            #                                                  transaction_id=transaction_id)
             retmsg[KeyType.merkle_tree] = result
             self.send_message(retmsg)
 
    @@ -504,11 +504,11 @@ class BBcCoreService:
         elif cmd == MsgType.REQUEST_MANIP_LEDGER_SUBSYS:
             retmsg = make_message_structure(MsgType.RESPONSE_MANIP_LEDGER_SUBSYS,
                                             None, dat[KeyType.source_user_id], dat[KeyType.query_id])
-            if dat[KeyType.ledger_subsys_manip]:
-                self.ledger_subsystem.enable()
-            else:
-                self.ledger_subsystem.disable()
-            self.ledger_subsystem.set_domain(dat[KeyType.domain_id])
+            #if dat[KeyType.ledger_subsys_manip]:
+            #    self.ledger_subsystem.enable()
+            #else:
+            #    self.ledger_subsystem.disable()
+            #self.ledger_subsystem.set_domain(dat[KeyType.domain_id])
             self.send_raw_message(socket, retmsg)
 
         elif cmd == MsgType.REQUEST_INSERT_NOTIFICATION:
    ```

    `bbc_core.py`を起動させます。ポート番号56641やログの場所は適宜読み替えてください。
    
    ````
    (.bbc1_venv)$ cd bbc1/core/
    (.bbc1_venv)$ python bbc_core.py --ip4addr 153.201.211.136 -d -pp 56641 -l /var/tmp/bbc1.log 
    ````

# 接続テスト

適当なドメイン設定を読み込ませて、他のノードへ`bbc_ping.py`を打ち込み、接続テストを行います。今回は、[前回](https://qiita.com/jqtype/items/575e1328a3cd359a5f7c)の記事の執筆時に構築したクラウド上の環境へ打ち込んでみます。

まずはドメイン設定を読み込みます。今回は、打ち込み先のノードですでに設定済みのドメインを書き込んだ以下のファイルを用意しています。

```json:domain_conf.json
{
    "b703536cd2aee7999d523b194c5d530b522d53178424b61ed44d650139ddbeda": {
        "module": "simple_cluster",
        "asset_group_ids": {
        },
	"static_nodes": {
        }
    }
}
```

これを読み込み、このドメインの上で`bbc_ping.py`を打ち込みます。

```shell
(.bbc1_venv)$ cd ../../utils
(.bbc1_venv)$ python bbc_system_conf.py domain_conf.json
(.bbc1_venv)$ python bbc_ping.py b703536cd2aee7999d523b194c5d530b522d53178424b61ed44d650139ddbeda <destination_addr> <destination_port>
Request domain_ping to 13.78.171.193, ::, 6641
*** wait 5 sec, checking peer_list in the core ***
====== peer list =====
*myself*    b'd03d1961', 153.201.211.136, ::, 56641
            b'bdae2640', <destination_addr>, ::, 6641
```

接続されました。

---
# テストノードへの接続情報
最後に、今回立ち上げたラズパイBBc-1ノードへの接続情報をまとめておきます。

- IPv4 Address: 153.201.211.136
- BBc-1 Port: 56641
- Domain: b703536cd2aee7999d523b194c5d530b522d53178424b61ed44d650139ddbeda

あくまでテスト利用のノードということをご認識の上、繋いでみてくださいませ。