初めてのsymbol-shoestring(コマンドライン編)

# 初めてのsymbol-shoestring(コマンドライン編)

`symbol-shoestring`を初めて使用する人（コマンドライン）向けの記事です。

:::note warn
Dockerのインストールやその他サーバー設定は終わっている前提
:::

## 環境

```bash
$ cat /etc/os-release 
PRETTY_NAME="Ubuntu 22.04.3 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.3 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy
```

## Python環境の構築(for Anaconda)

>Anacondaとは、Pythonでプログラムを作成する際によく用いられる
複数のライブラリを、1つのパッケージとして一括で管理・インストール
することができるディストリビューションのこと

参考

https://qiita.com/dusanjp/items/53d440fa38cb2fabab10


Anacondaを使用した環境構築方法はづ〜さんが書いてくれてますので、そちらを参考にどうぞ。

この記事では、pyenvをインストールして希望するPythonを実行できるようにします。

## pyenv環境の構築

ライブラリのインストール

```bash
$ sudo apt update
$ sudo apt install -y build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev curl libbz2-dev libsqlite3-dev liblzma-dev
```

ソースコードの取得

```bash
$ git clone https://github.com/pyenv/pyenv.git ~/.pyenv
```

### パスを設定

```bash
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
$ echo 'command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(pyenv init -)"' >> ~/.bashrc
```

### 設定を反映

```bash
$ source ~/.bashrc
```

### バージョン確認

```bash
$ pyenv --version
> pyenv 2.4.0
```


## pyenvでPythonをインストール

```bash
$ pyenv install -list
```

バージョンリストがでるのでインストールしたいバージョンを指定してインストール

```bash
$ pyenv install 3.9.13
```

グローバルで使用できるようにする

```bash
$ pyenv global 3.9.13
```

確認

```bash
$ python --version
> Python 3.9.13
```

# symbol-shoestringのインストール

https://pypi.org/project/symbol-shoestring/

```bash
$ pip install symbol-shoestring
```

# コマンドで実行する

shoestringはウィザードインターフェイスを備えています。

```bash
$ python -m shoestring.wizard
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/934471/d4e8d0ce-03af-4519-1aba-f6fc64978ff5.png)

とすれば、ウィザードが起動します。
この記事ではあえてウィザードを使わずコマンドラインのみでノードを起動したいと思います。

```bash
$ mkdir symbol-shoestring
$ cd symbol-shoestring
```
以降、作業は`symbol-shoestring`フォルダ内で行います。

# PEMファイル

OpenSSLを使用して新しいキーを生成

```bash
$ openssl genpkey -algorithm ed25519 -out ca.key.pem
```

# init

初期設定ファイルの生成

```bash
$ python -m shoestring init --package sai config
>     i     | copying FILE /tmp/tmpv3ng_flt/shoestring.ini into config
```

```bash
$ ls -la
total 16
drwxrwxr-x  2 dai dai 4096 Apr  8 23:00 .
drwxr-x--- 19 dai dai 4096 Apr  8 22:49 ..
-rw-------  1 dai dai  119 Apr  8 22:58 ca.key.pem
-rw-rw-r--  1 dai dai  665 Apr  8 23:00 config
```

# 設定ファイを修正

```bash
$ vi config 
```

```diff
[network]

name = testnet
identifier = 152
epochAdjustment = 1667250467
generationHashSeed = 49D6E1CE276A85B70EAFE52349AACCA389302E7A9754BCF1221E79494FC665A4

[images]

client = symbolplatform/symbol-server:gcc-1.0.3.7
rest = symbolplatform/symbol-rest:2.4.4

[services]

nodewatch = https://nodewatch.symbol.tools/testnet

[transaction]

- feeMultiplier = 200
+ feeMultiplier = 10
timeoutHours = 1
minCosignaturesCount = 0
hashLockDuration = 1440
currencyMosaicId = 0x72C0212E67A08BCE
lockedFundsPerAggregate = 10000000

[imports]

harvester =
voter =

[node]

-　features = API | HARVESTER | VOTER
+　features = PEER | API | HARVESTER
userId = 1000
groupId = 1000
caPassword =
apiHttps = true

caCommonName =
nodeCommonName =
```

# overrides.iniの作成

```bash
$vi overrides.ini
```

中身

```ini
[node.localnode]

host: hostname.com # Use your domain or IP address
friendlyName: Hello World # Choose a preferred name
```

:::note warn
ドメインはご自身の保有しているものを記載してください
:::

# setup

```bash
python -m shoestring setup --config $HOME/symbol-shoestring/config --ca-key-path $HOME/symbol-shoestring/ca.key.pem --directory $HOME/symbol-shoestring --package sai --overrides overrides.ini
```

結果

```bash
      i     | saved peers file /home/dai/symbol-shoestring/userconfig/resources/peers-p2p.json
      i     | saved peers file /home/dai/symbol-shoestring/userconfig/resources/peers-api.json
      i     | copying TREE /tmp/tmpgu2evru9/seed to /home/dai/symbol-shoestring/seed
      i     | copying FILE /tmp/tmpgu2evru9/resources/config-extensions-recovery.properties into /home/dai/symbol-shoestring/userconfig/resources/config-extensions-recovery.properties
      i     | copying FILE /tmp/tmpgu2evru9/resources/config-extensions-server.properties into /home/dai/symbol-shoestring/userconfig/resources/config-extensions-server.properties
      i     | copying FILE /tmp/tmpgu2evru9/resources/config-finalization.properties into /home/dai/symbol-shoestring/userconfig/resources/config-finalization.properties
      i     | copying FILE /tmp/tmpgu2evru9/resources/config-inflation.properties into /home/dai/symbol-shoestring/userconfig/resources/config-inflation.properties
      i     | copying FILE /tmp/tmpgu2evru9/resources/config-logging-recovery.properties into /home/dai/symbol-shoestring/userconfig/resources/config-logging-recovery.properties
      i     | copying FILE /tmp/tmpgu2evru9/resources/config-logging-server.properties into /home/dai/symbol-shoestring/userconfig/resources/config-logging-server.properties
      i     | copying FILE /tmp/tmpgu2evru9/resources/config-network.properties into /home/dai/symbol-shoestring/userconfig/resources/config-network.properties
      i     | copying FILE /tmp/tmpgu2evru9/resources/config-node.properties into /home/dai/symbol-shoestring/userconfig/resources/config-node.properties
      i     | copying FILE /tmp/tmpgu2evru9/resources/config-task.properties into /home/dai/symbol-shoestring/userconfig/resources/config-task.properties
      i     | copying FILE /tmp/tmpgu2evru9/resources/config-timesync.properties into /home/dai/symbol-shoestring/userconfig/resources/config-timesync.properties
      i     | copying FILE /tmp/tmpgu2evru9/resources/config-user.properties into /home/dai/symbol-shoestring/userconfig/resources/config-user.properties
      i     | copying FILE /tmp/tmpgu2evru9/resources/config-database.properties into /home/dai/symbol-shoestring/userconfig/resources/config-database.properties
      i     | copying FILE /tmp/tmpgu2evru9/resources/config-extensions-broker.properties into /home/dai/symbol-shoestring/userconfig/resources/config-extensions-broker.properties
      i     | copying FILE /tmp/tmpgu2evru9/resources/config-logging-broker.properties into /home/dai/symbol-shoestring/userconfig/resources/config-logging-broker.properties
      i     | copying FILE /tmp/tmpgu2evru9/resources/config-messaging.properties into /home/dai/symbol-shoestring/userconfig/resources/config-messaging.properties
      i     | copying FILE /tmp/tmpgu2evru9/resources/config-pt.properties into /home/dai/symbol-shoestring/userconfig/resources/config-pt.properties
      i     | copying FILE /tmp/tmpgu2evru9/resources/config-harvesting.properties into /home/dai/symbol-shoestring/userconfig/resources/config-harvesting.properties
      i     | copying TREE /tmp/tmpgu2evru9/mongo to /home/dai/symbol-shoestring/mongo
      i     | copying FILE /tmp/tmpgu2evru9/rest/rest.json into /home/dai/symbol-shoestring/userconfig
      i     | copying FILE /home/dai/.pyenv/versions/3.9.13/lib/python3.9/site-packages/shoestring/templates/nginx.conf.erb into /home/dai/symbol-shoestring/https-proxy
      i     | copying TREE /home/dai/.pyenv/versions/3.9.13/lib/python3.9/site-packages/shoestring/startup to /home/dai/symbol-shoestring/startup
      i     | detected last finalized height as 1331716
      i     | detected current finalization epoch as 1851
Using configuration from ca.cnf
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
commonName            :ASN.1 12:'custom-rest.daisan.dev'
Certificate is to be certified until Apr 18 15:30:31 2025 GMT (375 days)

Write out database with 1 new entries
Data Base Updated
      i     | connecting to http://xym-testnet.11ppm.com:3000
      i     | created aggregate transaction with hash 34E5A9177C585F983CAC0D97B4B4451AA06123C5D82CB94F9E19C6871E6668BE
      i     | transaction file written to /home/dai/symbol-shoestring/linking_transaction.dat
      i     | (signature: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000, signer_public_key: 8FA849280A1D42305FC71761E827D5E472A8E9E64F3272ED5D9760AABEFBB352, version: 0x2, network: NetworkType.TESTNET, type_: TransactionType.AGGREGATE_COMPLETE, fee: 0x00000000000157C0, deadline: 0x0000000A8EACDC98, transactions_hash: E1C812880A77FBFC5BCEE1C736180A919EB7FDFC6F5492F60AA5EEB21AB9390A, transactions: ['(signer_public_key: 8FA849280A1D42305FC71761E827D5E472A8E9E64F3272ED5D9760AABEFBB352, version: 0x1, network: NetworkType.TESTNET, type_: TransactionType.ACCOUNT_KEY_LINK, linked_public_key: D6CA40DF2979E4838BA1A0305C858F6DD552C0048936F840B4625090A474C586, link_action: LinkAction.LINK, )', '(signer_public_key: 8FA849280A1D42305FC71761E827D5E472A8E9E64F3272ED5D9760AABEFBB352, version: 0x1, network: NetworkType.TESTNET, type_: TransactionType.VRF_KEY_LINK, linked_public_key: CB720E183F93CC95B0C8403F1BDF0751E2835C6DB197FCC6DCCA47D9BD3D8257, link_action: LinkAction.LINK, )', '(signer_public_key: 8FA849280A1D42305FC71761E827D5E472A8E9E64F3272ED5D9760AABEFBB352, version: 0x1, network: NetworkType.TESTNET, type_: TransactionType.VOTING_KEY_LINK, linked_public_key: 238381096A187043B88DF748C3A72E4B3A14FEE41164CCDF13381FDDBE698E2E, start_epoch: 0x0000073D, end_epoch: 0x00000A0C, link_action: LinkAction.LINK, )'], cosignatures: [], )
```

```bash
$ ls -la
total 68
drwxrwxr-x 12 dai dai 4096 Apr  9 00:30 .
drwxr-x--- 19 dai dai 4096 Apr  9 00:07 ..
-rw-------  1 dai dai  119 Apr  8 23:27 ca.key.pem
-rw-rw-r--  1 dai dai  699 Apr  8 23:54 config
drwx------  2 dai dai 4096 Apr  9 00:30 data
drwx------  2 dai dai 4096 Apr  9 00:30 dbdata
-r--------  1 dai dai 2812 Apr  9 00:30 docker-compose.yaml
drwx------  2 dai dai 4096 Apr  9 00:30 https-proxy
drwx------  4 dai dai 4096 Apr  9 00:30 keys
-rw-------  1 dai dai  440 Apr  9 00:30 linking_transaction.dat
drwx------  2 dai dai 4096 Apr  9 00:30 logs
drwx------  2 dai dai 4096 Apr  9 00:30 mongo
-rw-rw-r--  1 dai dai   73 Apr  9 00:07 overrides.ini
drwx------  2 dai dai 4096 Apr  9 00:30 rest-cache
drwx------  3 dai dai 4096 Apr  9 00:30 seed
drwx------  2 dai dai 4096 Apr  9 00:30 startup
drwx------  3 dai dai 4096 Apr  9 00:30 userconfig
```

# 実行

```
docker compose up -d

[+] Running 6/7
 ⠹ Network catapult-node-network                       Created                                                            1.2s 
 ✔ Container symbol-shoestring-rest-api-1              Started                                                            0.8s 
 ✔ Container symbol-shoestring-db-1                    Started                                                            0.6s 
 ✔ Container symbol-shoestring-broker-1                Started                                                            0.8s 
 ✔ Container symbol-shoestring-client-1                Started                                                            0.6s 
 ✔ Container symbol-shoestring-rest-api-https-proxy-1  Started                                                            1.0s 
 ✔ Container symbol-shoestring-initiate-1              Started                                                            0.9s 

```

結果

```bash
$ docker ps
CONTAINER ID   IMAGE                                      COMMAND                  CREATED         STATUS                            PORTS                                                                                                               NAMES
13726fc4ea74   mongo:6.0.14                               "docker-entrypoint.s…"   5 seconds ago   Up 3 seconds                      27017/tcp                                                                                                           symbol-shoestring-initiate-1
28c508e89cee   steveltn/https-portal:1                    "/init"                  5 seconds ago   Up 3 seconds (health: starting)   0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:3000->80/tcp, :::3000->80/tcp, 0.0.0.0:3001->443/tcp, :::3001->443/tcp   symbol-shoestring-rest-api-https-proxy-1
b5e46ac3030f   symbolplatform/symbol-server:gcc-1.0.3.7   "/bin/bash /startup/…"   5 seconds ago   Up 4 seconds                      0.0.0.0:7900->7900/tcp, :::7900->7900/tcp                                                                           symbol-shoestring-client-1
ed0ea876a459   mongo:6.0.14                               "docker-entrypoint.s…"   5 seconds ago   Up 4 seconds                      127.0.0.1:27017->27017/tcp                                                                                          symbol-shoestring-db-1
16477c85522c   symbolplatform/symbol-rest:2.4.4           "/bin/bash /startup/…"   5 seconds ago   Up 3 seconds                      3000/tcp                                                                                                            symbol-shoestring-rest-api-1
3782b1429edd   symbolplatform/symbol-server:gcc-1.0.3.7   "/bin/bash /startup/…"   5 seconds ago   Up 3 seconds                                                                                                                                          symbol-shoestring-broker-1
```

# ヘルスチェック

```bash
$ python -m shoestring health --config config --directory $HOME/symbol-shoestring
     ...    | running health agent for peer certificate
      i     | ca certificate not near expiry (7299 day(s))
      i     | node certificate not near expiry (374 day(s))
/home/dai/symbol-shoestring/keys/cert/ca.crt.pem: OK
/home/dai/symbol-shoestring/keys/cert/node.crt.pem: OK
     ...    | running health agent for peer API
      i     | peer API accessible, height = 5401
     ...    | running health agent for voting keys
      i     | detected last finalized height as 1331716
      i     | detected current finalization epoch as 1851
      i     | future voting keys discovered for epochs 1853 to 2572
    [!!!]   | no voting keys are registered for the current epoch 1851
     ...    | running health agent for REST HTTPS certificate
Traceback (most recent call last):
  File "/home/dai/.pyenv/versions/3.9.13/lib/python3.9/runpy.py", line 197, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/home/dai/.pyenv/versions/3.9.13/lib/python3.9/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/home/dai/.pyenv/versions/3.9.13/lib/python3.9/site-packages/shoestring/__main__.py", line 53, in <module>
    asyncio.run(main(sys.argv[1:]))
  File "/home/dai/.pyenv/versions/3.9.13/lib/python3.9/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/home/dai/.pyenv/versions/3.9.13/lib/python3.9/asyncio/base_events.py", line 647, in run_until_complete
    return future.result()
  File "/home/dai/.pyenv/versions/3.9.13/lib/python3.9/site-packages/shoestring/__main__.py", line 49, in main
    await possible_task
  File "/home/dai/.pyenv/versions/3.9.13/lib/python3.9/site-packages/shoestring/commands/health.py", line 71, in run_main
    await module.validate(context)
  File "/home/dai/.pyenv/versions/3.9.13/lib/python3.9/site-packages/shoestring/healthagents/rest_https_certificate.py", line 90, in validate
    hostname = context.hostname
AttributeError: 'HealthAgentContext' object has no attribute 'hostname'
```

現段階ではバグがあり、エラーが表示されます。

https://discord.com/channels/856325968096133191/887352684066259024/1226875730550460468