はじめに
こんにちは。晴れ時々Symbolの(時期的には雪時々Symbolか)だい(@ishidad2)です。
本記事は、nem / symbol Advent Calendar 2024 の16日目の記事となります。
普段は株式会社 OpeningLineでSymbolブロックチェーンを用いたWebアプリケーションの開発、ブロックチェーンノードの保守などを行っています。
個人でもスマホアプリの作成やIoT機器の個人開発などを行っています。
対象読者
この記事の対象読者としては、最低限以下の要件を満たす人を対象としています。
- サーバー(Linux)をいじったことのある人
- コマンドラインで作業できる人(ファイルの編集などはVSCodeでもOK)
- Symbolノードを自力で構築できる人(shoestringを使います)
本記事のゴール
本記事では、タイトルの通り「Symbolのデータベースをクラウドデータベースに置き換え」に挑戦します。
ブロックチェーンのデータベース(以下、DB)の肥大化はローカルサーバーにおいて大きな課題です。
そこで、DB本体をローカルからクラウドに切り替えられないかと思い調査しました。
結論から言うと、「Symbolのデータベースをクラウドデータベースに置き換え」は成功しました。
(置き換えは成功しましたが、証明書の問題やクラッシュした際の復帰方法、アクセス速度の問題など色々と課題はあります)
この記事では「Symbolのデータベースをクラウドデータベースに置き換え」ることを推奨しているわけではありません。
あくまでもクラウドサービスを使うことができるかどうかの検証結果を示すものとなります。
検証する際には自己責任でお願いします。
MongoDB Atlas
MongoDB Atlasは、MongoDB向けのクラウドデータベースソリューションです。
今回はこのMongoDB Atlasを使います。
今回はお試しなので無料枠を使います。
無料枠ではストレージが512MBまでしか使えないようです。
とりあえず、試すだけならなんとかなりそうなのでFreeプランを使います。
MongoDB Atlasのはじめ方や使い方はこの記事では説明しません。
Clusterを作成
無料プランでDBを作成します。
必ずM0(Free)を選択してください。
デプロイ先のプロバイダーはお好きな場所を選択してください。
私は使い慣れたAzureを選択してみました。
Clusterを作成する画面でデータベースへの接続パスワードが表示されるのでコピーして他者にバレないように保存してきます。
次に「Create Database User」をクリックしてユーザーを作成します。
作成したClusterの確認
デプロイが完了すると、「sample_mflix」というDBができていました。
正確な用途は不明ですが恐らくサンプルDBでしょう。(フリープランということもあり、容量がもったいないので消しておきましょう)
IPアドレス制限について
Atlasの初期の設定ではIP接続制限がかけられています。
接続するサーバーのIPアドレスを許可するか、一時的に0.0.0.0/0を許可するようにしておいてください。
DB接続文字列の取得
外部からDBに接続するための接続文字列を取得します。
「Get connection string」をクリックします。
(初回以降は左側メニューの「DATABASE」→「Clusters」から確認できます)
後ほどノード側で利用するのでDB接続文字列をコピーしておきます。
Mongo DB Atlas側の設定は以上です。
続いて、Symbolノードの構築を行います。
Symbolノード構築
環境
作業環境は以下のようになります。
$ cat /etc/os-release
PRETTY_NAME="Ubuntu 22.04 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04 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
$ docker -v
Docker version 27.4.0, build bde2b89
$ python --version
Python 3.9.20
ノードの構築にはshoestring
を使います。
ノード構築
ノード構築について
基本的にノード構築のノウハウは説明しませんので、その辺りはQiita内に記事がたくさんあるのでそちらを参考にしてください。
python3 -m shoestring.wizard
上記のコマンドを実行して、ノードの初期設定ファイル群を生成します。
今回は実験ですのでテストネットを指定して作成で問題ありません。
諸々の設定ファイルができたらいくつかファイルの書き換えを行っていきます。
接続文字列の修正
まず、ノードの初期設定ファイルのデータベース接続文字列を書き換えていきます。
対象となるファイルは以下の2つです。
- userconfig/resources/config-database.properties
- userconfig/rest.json
config-database.propertiesの書き換え
databaseUri
を以下のように書き換えます。
<username>
と<password>
を自身のものに書き換えてください。
また@cluster0.pkkzx
は環境によって違うものになる可能性があるので、DB接続文字列の取得でコピーした値に書き換えてください。
mongodb+srv://形式はTLS/SSLを使用します。接続時に証明書エラーが発生する可能性があったので、自己署名証明書を許可するためのオプション(tlsAllowInvalidCertificates
)を追加しています。
[database]
- databaseUri = mongodb://db:27017
+ databaseUri = mongodb+srv://<username>:<password>@cluster0.pkkzx.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0&tlsAllowInvalidCertificates=true
databaseName = catapult
maxWriterThreads = 8
maxDropBatchSize = 10
writeTimeout = 10m
[plugins]
catapult.mongo.plugins.accountlink = true
catapult.mongo.plugins.aggregate = true
catapult.mongo.plugins.lockhash = true
catapult.mongo.plugins.locksecret = true
catapult.mongo.plugins.metadata = true
catapult.mongo.plugins.mosaic = true
catapult.mongo.plugins.multisig = true
catapult.mongo.plugins.namespace = true
catapult.mongo.plugins.restrictionaccount = true
catapult.mongo.plugins.restrictionmosaic = true
catapult.mongo.plugins.transfer = true
rest.jsonの書き換え
url
とname
を以下のように書き換えます。
こちらも先ほど同じように<username>
と<password>
を自身のものに書き換えてください。
name
には?tlsAllowInvalidCertificates=true
を追加します。
...
"db": {
- "url":"mongodb://db:27017/",
+ "url": "mongodb+srv://<username>:<password>@cluster0.pkkzx.mongodb.net/",
- "name": "catapult",
+ "name": "catapult?tlsAllowInvalidCertificates=true",
"pageSizeMin": 10,
"pageSizeMax": 100,
"pageSizeDefault": 20,
"maxConnectionAttempts": 15,
"baseRetryDelay": 750,
"connectionPoolSize": 10,
"connectionTimeout": 500
},
...
各種スクリプトの修正
次に以下の各種スクリプトを修正します。
- startup/mongors.sh
- mongo/mongoDbPrepare.js
mongors.sh
このスクリプトはデータベースの起動をチェックしているものです。
今のままではローカルデータベースを参照してしまうので、クラウドデータベースを参照するように修正します。
こちらも先ほど同じように<username>
と<password>
を自身のものに書き換えてください。
#!/bin/bash
sleep 1
set -e
state_filename=$1
shift
pwd
while true;
do
- if mongosh --eval "db.runCommand( { serverStatus: 1 } )" db/local > /dev/null 2>&1; then
+ if mongosh "mongodb+srv://<username>:<password>@cluster0.pkkzx.mongodb.net/catapult" --eval "db.runCommand( { serverStatus: 1 } )" > /dev/null 2>&1; then
break;
fi
echo "waiting for mongod start..."
sleep 1
done
echo " [+] Preparing db5"
cd /mongo
-mongosh db/catapult < mongoDbPrepare.js
+mongosh "mongodb+srv://<username>:<password>@cluster0.pkkzx.mongodb.net/catapult" < mongoDbPrepare.js
echo " [.] (exit code: $?)"
cd -
echo " [+] db prepared, checking account indexes"
-mongosh --eval 'db.accounts.getIndexes()' db/catapult
+mongosh "mongodb+srv://<username>:<password>@cluster0.pkkzx.mongodb.net/catapult" --eval 'db.accounts.getIndexes()'
trap 'echo "exiting"; exit 0' SIGTERM
mkdir -p "$(dirname "${state_filename}")"
touch "${state_filename}"
sleep infinity & wait
mongoDbPrepare.jsの修正
Mongo DB Atlasでは2箇所ほどエラーが出るので、コメントアウトをして回避します。
(function prepareDbConfiguration() {
- db.setProfilingLevel(1, 100); // log slow queries
+ // db.setProfilingLevel(1, 100); // log slow queries
})();
(function prepareDbCollections() {
function makeSparse(propertyName) {
return { partialFilterExpression: { [propertyName]: { $exists: true } } };
}
function addCommonTransactionIndexes(collection) {
collection.createIndex({ 'transaction.signerPublicKey': 1, _id: -1 });
collection.createIndex({ 'transaction.recipientAddress': 1, _id: -1 });
collection.createIndex({ 'meta.hash': 1 }, Object.assign({ unique: true }, makeSparse('meta.hash')));
collection.createIndex({ 'meta.addresses': 1 }, makeSparse('meta.addresses'));
collection.createIndex({ 'meta.aggregateId': 1 }, makeSparse('meta.aggregateId'));
}
function addTransactionCollection(collectionName) {
db.createCollection(collectionName);
addCommonTransactionIndexes(db[collectionName]);
db[collectionName].createIndex({ 'meta.aggregateHash': 1 }, makeSparse('meta.aggregateHash'));
}
db.createCollection('blocks');
db.blocks.createIndex({ 'block.signerPublicKey': 1 });
db.blocks.createIndex({ 'block.timestamp': -1 }, { unique: true });
db.blocks.createIndex({ 'block.height': -1 }, { unique: true });
db.blocks.createIndex({ 'block.type': 1, 'block.height': -1 }, { unique: true });
db.blocks.createIndex({ 'block.signerPublicKey': 1, 'block.height': -1 }, { unique: true });
db.blocks.createIndex({ 'block.beneficiaryAddress': 1, 'block.height': -1 }, { unique: true });
db.createCollection('finalizedBlocks');
db.finalizedBlocks.createIndex({ 'block.finalizationEpoch': -1 });
db.finalizedBlocks.createIndex({ 'block.height': -1 });
db.finalizedBlocks.createIndex({ 'block.finalizationEpoch': -1, 'block.finalizationPoint': -1 }, { unique: true });
db.createCollection('transactions');
addCommonTransactionIndexes(db.transactions);
db.transactions.createIndex({ 'meta.height': -1 });
db.transactions.createIndex({ 'transaction.deadline': -1 });
db.transactions.createIndex({ 'transaction.cosignatures.signerPublicKey': 1 }, makeSparse('transaction.cosignatures.signerPublicKey'));
db.transactions.createIndex({ 'transaction.id': 1, 'transaction.type': 1 }, makeSparse('transaction.id'));
db.createCollection('transactionStatements');
db.transactionStatements.createIndex(
{ 'statement.height': 1, 'statement.source.primaryId': 1, 'statement.source.secondaryId': 1 },
{ unique: true });
['addressResolutionStatements', 'mosaicResolutionStatements'].forEach(collectionName => {
db.createCollection(collectionName);
db[collectionName].createIndex({ 'statement.height': 1, 'statement.unresolved': 1 }, { unique: true });
});
db.createCollection('accounts');
db.accounts.createIndex({ 'account.publicKey': 1 }); // cannot be unique because zeroed public keys are stored
db.accounts.createIndex({ 'account.address': 1 }, { unique: true });
['unconfirmedTransactions', 'partialTransactions'].forEach(addTransactionCollection);
db.createCollection('transactionStatuses', { capped: true, size: 53000000, max: 500000 });
db.transactionStatuses.createIndex({ 'status.hash': 1 }, { unique: true });
db.transactionStatuses.createIndex({ 'status.deadline': -1 });
- db.adminCommand( { setFeatureCompatibilityVersion: '6.0' } )
+ // db.adminCommand( { setFeatureCompatibilityVersion: '6.0' } )
})();
(function preparePluginDbCollections() {
const pluginNames = [
'LockHash', 'LockSecret', 'Metadata', 'Mosaic', 'Multisig', 'Namespace', 'RestrictionAccount', 'RestrictionMosaic'
];
pluginNames.forEach(pluginName => {
print(`Loading ${pluginName}`);
load(`mongo${pluginName}DbPrepare.js`);
});
})();
(function printCollectionIndexes() {
db.getCollectionNames().forEach(collectionName => {
print(`===== ${collectionName} INDEXES =====`);
db[collectionName].getIndexes().forEach(index => {
printjson(index.key);
});
});
})();
docker-compose.ymlの修正
最後にdocker-compose.yml
を修正します。
不要になったdbコンテナ部分をコメントアウトしておきます。
version: '2'
services:
# db:
# image: mongo:6.0.14
# user: '1000:1000'
# command: mongod --dbpath=/dbdata
# stop_signal: SIGINT
# ports:
# - 127.0.0.1:27017:27017
# volumes:
# - ./dbdata:/dbdata:rw
# - ./dbdata:/data:rw
initiate:
image: mongo:6.0.14
user: '1000:1000'
command: /bin/bash /startup/mongors.sh /real_data/startup/mongo-initialized
volumes:
- ./startup:/startup:ro
- ./mongo:/mongo:ro
- ./dbdata:/dbdata:rw
- ./dbdata:/data:rw
- ./data:/real_data
# depends_on:
# - db
client:
image: 'symbolplatform/symbol-server:gcc-1.0.3.7'
user: '1000:1000'
logging:
driver: json-file
options:
max-size: 25M
max-file: '10'
command: /bin/bash /startup/wait.sh /data/startup/mongo-initialized /startup/startServer.sh
environment:
- LD_LIBRARY_PATH=/usr/catapult/lib:/usr/catapult/deps
stop_signal: SIGINT
stop_grace_period: 300s
ports:
- 7900:7900
working_dir: /
volumes:
- ./startup:/startup:ro
- ./userconfig:/userconfig:ro
- ./seed:/seed:ro
- ./keys/cert:/certificates:ro
- ./data:/data
- ./logs:/logs
- ./keys/voting:/votingkeys
broker:
image: 'symbolplatform/symbol-server:gcc-1.0.3.7'
user: '1000:1000'
cap_add:
- SYS_PTRACE
command: /bin/bash /startup/wait.sh /data/startup/datadir-initialized /startup/startBroker.sh
environment:
- LD_LIBRARY_PATH=/usr/catapult/lib:/usr/catapult/deps
stop_signal: SIGINT
stop_grace_period: 60s
working_dir: /
volumes:
- ./startup:/startup:ro
- ./userconfig:/userconfig:ro
- ./keys/cert:/certificates:ro
- ./data:/data
- ./logs:/logs
rest-api:
image: 'symbolplatform/symbol-rest:2.4.4'
user: '1000:1000'
command: /bin/bash /startup/delayrestapi.sh
environment:
- HOME=/symbol-workdir
- NODE_ENV=production
working_dir: /symbol-workdir
ports:
- 3000:3000
volumes:
- ./startup:/startup:ro
- ./userconfig:/userconfig:ro
- ./keys/cert:/certificates:ro
- ./data:/data
- ./logs:/logs
- ./rest-cache:/symbol-workdir
networks:
default:
ipv4_address: 172.20.0.25
networks:
default:
name: catapult-node-network
ipam:
config:
- subnet: 172.20.0.0/24
変更したファイル一覧
- userconfig/resources/config-database.properties
- userconfig/rest.json
- startup/mongors.sh
- mongo/mongoDbPrepare.js
- docker-compose.yml
起動と確認
それでは、ノードを起動してクラウドデータベースにデータが保存されるか確認してみましょう。
Mongo DB AtlasのDATABASEにはまだ何もない状態です。
ノードの起動
以下のコマンドを実行してノードを起動します。
ログを確認したいのでデタッチオプション(-d)は付けずに起動します。
docker compose up
起動するとログが表示されます(長いので折りたたんであります)
ログ
Attaching to broker-1, client-1, initiate-1, rest-api-1
initiate-1 | /
initiate-1 | [+] Preparing db5
initiate-1 | Warning: Could not access file: EACCES: permission denied, mkdir '/data/db/.mongodb'
initiate-1 | Current Mongosh Log ID: 6758de35db87ca1ebbc934dc
initiate-1 | Connecting to: mongodb+srv://<credentials>@cluster0.pkkzx.mongodb.net/catapult?appName=mongosh+2.2.4
initiate-1 | Using MongoDB: 8.0.3
initiate-1 | Using Mongosh: 2.2.4
initiate-1 |
initiate-1 | For mongosh info see: https://docs.mongodb.com/mongodb-shell/
initiate-1 |
initiate-1 |
initiate-1 | To help improve our products, anonymous usage data is collected and sent to MongoDB periodically (https://www.mongodb.com/legal/privacy-policy).
initiate-1 | You can opt-out by running the disableTelemetry() command.
initiate-1 |
initiate-1 |
initiate-1 | Error: Could not open history file.
initiate-1 | REPL session history will not be persisted.
initiate-1 | [1G[0J [1GAtlas atlas-13wiab-shard-0 [primary] catapult> ... ...
initiate-1 | Atlas atlas-13wiab-shard-0 [primary] catapult>
initiate-1 | Atlas atlas-13wiab-shard-0 [primary] catapult> ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
initiate-1 | Atlas atlas-13wiab-shard-0 [primary] catapult>
initiate-1 | Atlas atlas-13wiab-shard-0 [primary] catapult> ... ... ... ... ... ... ... ... Loading LockHash
initiate-1 | Loading LockSecret
initiate-1 | Loading Metadata
initiate-1 | Loading Mosaic
initiate-1 | Loading Multisig
initiate-1 | Loading Namespace
initiate-1 | Loading RestrictionAccount
initiate-1 | Loading RestrictionMosaic
initiate-1 |
initiate-1 | Atlas atlas-13wiab-shard-0 [primary] catapult>
initiate-1 | Atlas atlas-13wiab-shard-0 [primary] catapult> ... ... ... ... ... ... ... ===== metadata INDEXES =====
initiate-1 | {
initiate-1 | _id: 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'metadataEntry.compositeHash': 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'metadataEntry.sourceAddress': 1,
initiate-1 | 'metadataEntry.metadataType': 1,
initiate-1 | 'metadataEntry.scopedMetadataKey': 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'metadataEntry.targetAddress': 1,
initiate-1 | 'metadataEntry.metadataType': 1,
initiate-1 | 'metadataEntry.scopedMetadataKey': 1
initiate-1 | }
initiate-1 | ===== hashLocks INDEXES =====
initiate-1 | {
initiate-1 | _id: 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'lock.hash': 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'lock.ownerAddress': 1
initiate-1 | }
initiate-1 | ===== partialTransactions INDEXES =====
initiate-1 | {
initiate-1 | _id: 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'transaction.signerPublicKey': 1,
initiate-1 | _id: -1
initiate-1 | }
initiate-1 | {
initiate-1 | 'transaction.recipientAddress': 1,
initiate-1 | _id: -1
initiate-1 | }
initiate-1 | {
initiate-1 | 'meta.hash': 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'meta.addresses': 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'meta.aggregateId': 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'meta.aggregateHash': 1
initiate-1 | }
initiate-1 | ===== addressResolutionStatements INDEXES =====
initiate-1 | {
initiate-1 | _id: 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'statement.height': 1,
initiate-1 | 'statement.unresolved': 1
initiate-1 | }
initiate-1 | ===== mosaicRestrictions INDEXES =====
initiate-1 | {
initiate-1 | _id: 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'mosaicRestrictionEntry.compositeHash': 1
initiate-1 | }
initiate-1 | ===== secretLocks INDEXES =====
initiate-1 | {
initiate-1 | _id: 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'lock.compositeHash': 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'lock.ownerAddress': 1
initiate-1 | }
initiate-1 | ===== mosaics INDEXES =====
initiate-1 | {
initiate-1 | _id: 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'mosaic.id': 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'mosaic.ownerAddress': 1
initiate-1 | }
initiate-1 | ===== unconfirmedTransactions INDEXES =====
initiate-1 | {
initiate-1 | _id: 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'transaction.signerPublicKey': 1,
initiate-1 | _id: -1
initiate-1 | }
initiate-1 | {
initiate-1 | 'transaction.recipientAddress': 1,
initiate-1 | _id: -1
initiate-1 | }
initiate-1 | {
initiate-1 | 'meta.hash': 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'meta.addresses': 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'meta.aggregateId': 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'meta.aggregateHash': 1
initiate-1 | }
initiate-1 | ===== transactionStatuses INDEXES =====
initiate-1 | {
initiate-1 | _id: 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'status.hash': 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'status.deadline': -1
initiate-1 | }
initiate-1 | ===== accountRestrictions INDEXES =====
initiate-1 | {
initiate-1 | _id: 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'accountRestrictions.address': 1
initiate-1 | }
initiate-1 | ===== transactionStatements INDEXES =====
initiate-1 | {
initiate-1 | _id: 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'statement.height': 1,
initiate-1 | 'statement.source.primaryId': 1,
initiate-1 | 'statement.source.secondaryId': 1
initiate-1 | }
initiate-1 | ===== namespaces INDEXES =====
initiate-1 | {
initiate-1 | _id: 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'namespace.level0': 1,
initiate-1 | 'meta.index': 1,
initiate-1 | 'namespace.depth': 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'meta.latest': -1,
initiate-1 | 'meta.index': 1,
initiate-1 | 'namespace.level0': 1,
initiate-1 | 'namespace.depth': 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'meta.latest': -1,
initiate-1 | 'namespace.level1': 1,
initiate-1 | 'namespace.depth': 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'meta.latest': -1,
initiate-1 | 'namespace.level2': 1,
initiate-1 | 'namespace.depth': 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'meta.latest': -1,
initiate-1 | 'namespace.ownerAddress': 1
initiate-1 | }
initiate-1 | ===== blocks INDEXES =====
initiate-1 | {
initiate-1 | _id: 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'block.signerPublicKey': 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'block.timestamp': -1
initiate-1 | }
initiate-1 | {
initiate-1 | 'block.height': -1
initiate-1 | }
initiate-1 | {
initiate-1 | 'block.type': 1,
initiate-1 | 'block.height': -1
initiate-1 | }
initiate-1 | {
initiate-1 | 'block.signerPublicKey': 1,
initiate-1 | 'block.height': -1
initiate-1 | }
initiate-1 | {
initiate-1 | 'block.beneficiaryAddress': 1,
initiate-1 | 'block.height': -1
initiate-1 | }
initiate-1 | ===== mosaicResolutionStatements INDEXES =====
initiate-1 | {
initiate-1 | _id: 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'statement.height': 1,
initiate-1 | 'statement.unresolved': 1
initiate-1 | }
initiate-1 | ===== transactions INDEXES =====
initiate-1 | {
initiate-1 | _id: 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'transaction.signerPublicKey': 1,
initiate-1 | _id: -1
initiate-1 | }
initiate-1 | {
initiate-1 | 'transaction.recipientAddress': 1,
initiate-1 | _id: -1
initiate-1 | }
initiate-1 | {
initiate-1 | 'meta.hash': 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'meta.addresses': 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'meta.aggregateId': 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'meta.height': -1
initiate-1 | }
initiate-1 | {
initiate-1 | 'transaction.deadline': -1
initiate-1 | }
initiate-1 | {
initiate-1 | 'transaction.cosignatures.signerPublicKey': 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'transaction.id': 1,
initiate-1 | 'transaction.type': 1
initiate-1 | }
initiate-1 | ===== finalizedBlocks INDEXES =====
initiate-1 | {
initiate-1 | _id: 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'block.finalizationEpoch': -1
initiate-1 | }
initiate-1 | {
initiate-1 | 'block.height': -1
initiate-1 | }
initiate-1 | {
initiate-1 | 'block.finalizationEpoch': -1,
initiate-1 | 'block.finalizationPoint': -1
initiate-1 | }
initiate-1 | ===== multisigs INDEXES =====
initiate-1 | {
initiate-1 | _id: 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'multisig.accountAddress': 1
initiate-1 | }
initiate-1 | ===== accounts INDEXES =====
initiate-1 | {
initiate-1 | _id: 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'account.publicKey': 1
initiate-1 | }
initiate-1 | {
initiate-1 | 'account.address': 1
initiate-1 | }
initiate-1 |
initiate-1 | Atlas atlas-13wiab-shard-0 [primary] catapult> [.] (exit code: 0)
initiate-1 | /
initiate-1 | [+] db prepared, checking account indexes
initiate-1 | Warning: Could not access file: EACCES: permission denied, mkdir '/data/db/.mongodb'
initiate-1 | [
initiate-1 | { v: 2, key: { _id: 1 }, name: '_id_' },
initiate-1 | {
initiate-1 | v: 2,
initiate-1 | key: { 'account.publicKey': 1 },
initiate-1 | name: 'account.publicKey_1'
initiate-1 | },
initiate-1 | {
initiate-1 | v: 2,
initiate-1 | key: { 'account.address': 1 },
initiate-1 | name: 'account.address_1',
initiate-1 | unique: true
initiate-1 | }
initiate-1 | ]
client-1 | uid=1000(ubuntu) gid=1000(ubuntu) groups=1000(ubuntu)
client-1 | total 20K
client-1 | drwx------ 3 ubuntu ubuntu 4.0K Dec 10 05:58 .
client-1 | drwxr-xr-x 1 root root 4.0K Dec 10 09:57 ..
client-1 | drwx------ 2 ubuntu ubuntu 4.0K Dec 10 05:58 00000
client-1 | -r-------- 1 ubuntu ubuntu 8 Dec 10 05:58 index.dat
client-1 | -r-------- 1 ubuntu ubuntu 48 Dec 10 05:58 proof.index.dat
client-1 | Copyright (c) Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp.
client-1 | catapult version: 1.0.3.7 (public)
client-1 | loading resources from "/userconfig/resources"
client-1 | loading configuration from "/userconfig/resources/config-inflation.properties"
client-1 | loading configuration from "/userconfig/resources/config-extensions-server.properties"
client-1 | loading configuration from "/userconfig/resources/config-user.properties"
client-1 | loading configuration from "/userconfig/resources/config-logging-server.properties"
client-1 | loading configuration from "/userconfig/resources/config-node.properties"
client-1 | loading configuration from "/userconfig/resources/config-network.properties"
client-1 | loading configuration from "/userconfig/resources/config-pt.properties"
client-1 | loading configuration from "/userconfig/resources/config-finalization.properties"
client-1 | loading configuration from "/userconfig/resources/config-task.properties"
client-1 | loading configuration from "/userconfig/resources/config-timesync.properties"
broker-1 | uid=1000(ubuntu) gid=1000(ubuntu) groups=1000(ubuntu)
broker-1 | total 36K
broker-1 | drwx------ 7 ubuntu ubuntu 4.0K Dec 11 00:35 .
broker-1 | drwxr-xr-x 1 root root 4.0K Dec 10 09:57 ..
broker-1 | drwx------ 2 ubuntu ubuntu 4.0K Dec 11 00:35 00000
broker-1 | drwx------ 3 ubuntu ubuntu 4.0K Dec 11 00:35 importance
broker-1 | -rw------- 1 ubuntu ubuntu 8 Dec 11 00:35 index.dat
broker-1 | -rw------- 1 ubuntu ubuntu 48 Dec 11 00:35 proof.index.dat
broker-1 | ---------- 1 ubuntu ubuntu 0 Dec 11 00:35 server.lock
broker-1 | drwx------ 9 ubuntu ubuntu 4.0K Dec 11 00:35 spool
broker-1 | drwxr-xr-x 2 ubuntu ubuntu 4.0K Dec 11 00:35 startup
broker-1 | drwx------ 5 ubuntu ubuntu 4.0K Dec 11 00:35 statedb
broker-1 | Copyright (c) Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp.
broker-1 | catapult version: 1.0.3.7 (public)
broker-1 | loading resources from "/userconfig/resources"
broker-1 | loading configuration from "/userconfig/resources/config-inflation.properties"
broker-1 | loading configuration from "/userconfig/resources/config-extensions-broker.properties"
broker-1 | loading configuration from "/userconfig/resources/config-user.properties"
broker-1 | loading configuration from "/userconfig/resources/config-logging-broker.properties"
broker-1 | loading configuration from "/userconfig/resources/config-node.properties"
broker-1 | loading configuration from "/userconfig/resources/config-network.properties"
broker-1 | loading configuration from "/userconfig/resources/config-database.properties"
rest-api-1 | [+] delaying rest API startup
broker-1 | loading configuration from "/userconfig/resources/config-messaging.properties"
rest-api-1 |
rest-api-1 | > symbol-api-rest@2.4.4 start
rest-api-1 | > node src/index.js /userconfig/rest.json
rest-api-1 |
解説
Attaching to broker-1, client-1, initiate-1, rest-api-1
...
initiate-1 | Connecting to: mongodb+srv://<credentials>@cluster0.pkkzx.mongodb.net/catapult?appName=mongosh+2.2.4
...
initiateコンテナが先ほど設定したMongo DB Atlasへ接続しに行っているのがわかります。
initiate-1 | Atlas atlas-13wiab-shard-0 [primary] catapult>
initiate-1 | Atlas atlas-13wiab-shard-0 [primary] catapult> ... ... ... ... ... ... ... ... Loading LockHash
...
initiate-1 |
initiate-1 | Atlas atlas-13wiab-shard-0 [primary] catapult>
initiate-1 | Atlas atlas-13wiab-shard-0 [primary] catapult> ... ... ... ... ... ... ... ===== metadata INDEXES =====
initiate-1 | {
initiate-1 | _id: 1
initiate-1 | }
...
initiate-1 | 'metadataEntry.scopedMetadataKey': 1
initiate-1 | }
initiate-1 | ===== hashLocks INDEXES =====
initiate-1 | {
initiate-1 | _id: 1
initiate-1 | }
...
initiate-1 | {
initiate-1 | 'multisig.accountAddress': 1
initiate-1 | }
initiate-1 | ===== accounts INDEXES =====
initiate-1 | {
...
initiate-1 | }
initiate-1 |
initiate-1 | Atlas atlas-13wiab-shard-0 [primary] catapult> [.] (exit code: 0)
initiate-1 | /
initiate-1 | [+] db prepared, checking account indexes
initiate-1 | Warning: Could not access file: EACCES: permission denied, mkdir '/data/db/.mongodb'
initiate-1 | [
initiate-1 | { v: 2, key: { _id: 1 }, name: '_id_' },
initiate-1 | {
initiate-1 | v: 2,
initiate-1 | key: { 'account.publicKey': 1 },
initiate-1 | name: 'account.publicKey_1'
initiate-1 | },
initiate-1 | {
initiate-1 | v: 2,
initiate-1 | key: { 'account.address': 1 },
initiate-1 | name: 'account.address_1',
initiate-1 | unique: true
initiate-1 | }
initiate-1 | ]
client-1 | uid=1000(ubuntu) gid=1000(ubuntu) groups=1000(ubuntu)
client-1 | total 20K
client-1 | drwx------ 3 ubuntu ubuntu 4.0K Dec 10 05:58 .
client-1 | drwxr-xr-x 1 root root 4.0K Dec 10 09:57 ..
client-1 | drwx------ 2 ubuntu ubuntu 4.0K Dec 10 05:58 00000
client-1 | -r-------- 1 ubuntu ubuntu 8 Dec 10 05:58 index.dat
client-1 | -r-------- 1 ubuntu ubuntu 48 Dec 10 05:58 proof.index.dat
client-1 | Copyright (c) Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp.
client-1 | catapult version: 1.0.3.7 (public)
client-1 | loading resources from "/userconfig/resources"
client-1 | loading configuration from "/userconfig/resources/config-inflation.properties"
...
broker-1 | uid=1000(ubuntu) gid=1000(ubuntu) groups=1000(ubuntu)
broker-1 | total 36K
broker-1 | drwx------ 7 ubuntu ubuntu 4.0K Dec 11 00:35 .
broker-1 | drwxr-xr-x 1 root root 4.0K Dec 10 09:57 ..
broker-1 | drwx------ 2 ubuntu ubuntu 4.0K Dec 11 00:35 00000
broker-1 | drwx------ 3 ubuntu ubuntu 4.0K Dec 11 00:35 importance
broker-1 | -rw------- 1 ubuntu ubuntu 8 Dec 11 00:35 index.dat
broker-1 | -rw------- 1 ubuntu ubuntu 48 Dec 11 00:35 proof.index.dat
broker-1 | ---------- 1 ubuntu ubuntu 0 Dec 11 00:35 server.lock
broker-1 | drwx------ 9 ubuntu ubuntu 4.0K Dec 11 00:35 spool
broker-1 | drwxr-xr-x 2 ubuntu ubuntu 4.0K Dec 11 00:35 startup
broker-1 | drwx------ 5 ubuntu ubuntu 4.0K Dec 11 00:35 statedb
broker-1 | Copyright (c) Jaguar0625, gimre, BloodyRookie, Tech Bureau, Corp.
broker-1 | catapult version: 1.0.3.7 (public)
broker-1 | loading resources from "/userconfig/resources"
broker-1 | loading configuration from "/userconfig/resources/config-inflation.properties"
broker-1 | loading configuration from "/userconfig/resources/config-extensions-broker.properties"
broker-1 | loading configuration from "/userconfig/resources/config-user.properties"
broker-1 | loading configuration from "/userconfig/resources/config-logging-broker.properties"
broker-1 | loading configuration from "/userconfig/resources/config-node.properties"
broker-1 | loading configuration from "/userconfig/resources/config-network.properties"
broker-1 | loading configuration from "/userconfig/resources/config-database.properties"
rest-api-1 | [+] delaying rest API startup
broker-1 | loading configuration from "/userconfig/resources/config-messaging.properties"
rest-api-1 |
rest-api-1 | > symbol-api-rest@2.4.4 start
rest-api-1 | > node src/index.js /userconfig/rest.json
rest-api-1 |
その後、いろいろなログが吐かれますがエラーなどがなければBrokerコンテナやRestAPIコンテナが立ち上がります。
また、Mongo DB AtlasのDATABASEを確認するとcatapult
データベースが作成されており、データが保存されていることがわかります。
無料枠を使っているのでノードの起動が確認できたらCtrl + C
でノードを停止しておいてください。
ノードを停止するとそのままでは再起動できない可能性があります。(起動時Brokerが落ちる)
その場合は、Mongo DB Atlas側のDBを削除した上で、python3 -m shoestring.wizardを使用してresetDataを実行してください。
全てのデータをクリアすれば起動できるはずです。
最後に
一応、当初の目的である「Symbolのデータベースをクラウドデータベースに置き換え」は成功しました。
とはいえ、これはあくまで検証です。
今回は無料枠で512MBしかデータベースにデータを保存できないので、フルでデータを保存した場合どのような挙動になるのかは正直不明です(通信速度とか検索性能とかセキュリティとか...etc)
あと、ノートの再起動がうまくできない場合もあります(理由は不明だかBrokerが落ちる...)
データの肥大化に伴うクラウド利用に関してはまだまだ問題点も多いですが、ローカルで物理サーバー運用している人などにはちょっとだけ嬉しい情報になるのではないでしょうか?(そうでもない?)
興味のある方はぜひ挑戦してみてください。