LoginSignup
0

More than 3 years have passed since last update.

Libraを複数サーバ・マルチノードで動かす

Posted at

初めに

Facebookが発表したLibraですが、チュートリアル用に用意されているものは1サーバ上に1ノードしか動かせません。
今回は2つのサーバ上にそれぞれノードを動かして、CLI clientを用いて一方のノードに対して実行したトランザクションが他方のノードからも参照できることを確認します。

Libraのビルド

以下のサーバを2台用意します。両方のサーバ上で以下の手順に沿ってLibraのビルドを行ってください。

ノード IPアドレス OS
ノード1 192.168.10.1 Ubuntu 18.04
ノード2 192.168.10.2 Ubuntu 18.04

ホームディレクトリにfacebookというディレクトリを作成し、リポジトリをcloneします。

$ mkdir facebook
$ cd facebook
$ git clone https://github.com/libra/libra.git
Cloning into 'libra'...
remote: Enumerating objects: 1, done.
remote: Counting objects: 100% (1/1), done.
remote: Total 11907 (delta 0), reused 0 (delta 0), pack-reused 11906
Receiving objects: 100% (11907/11907), 5.07 MiB | 1.50 MiB/s, done.
Resolving deltas: 100% (7513/7513), done.
Checking out files: 100% (1502/1502), done.

ビルドに必要なライブラリ等をダウンロードし、ビルドを行います。ビルドは少し時間がかかります。

$ cd libra
$ ./scripts/dev_setup.sh 
Welcome to Libra!

This script will download and install the necessary dependencies needed to
build Libra Core. This includes:
        * Rust (and the necessary components, e.g. rust-fmt, clippy)
        * CMake, protobuf, go (for building protobuf)

<中略>

$ source $HOME/.cargo/env
$ cargo build
<中略>
    Finished dev [unoptimized + debuginfo] target(s) in 26m 03s

~/facebook/libra/target/debugにバイナリが作成されているのでパスを通しておきます。

$ cd target/debug
$ export PATH=$PATH:`pwd`

ネットワーク設定作業

ここからはノード1のサーバで作業を行います。ノード1のサーバ上でノードを起動するために必要な各種ファイルの作成作業を行います。
facebookディレクトリ配下にnodeというディレクトリを作成します。今後はこのディレクトリの中で作業を行います。

$ mkdir ~/facebook/node
$ cd ~/facebook/node

まず、キーペアを作成します。oオプションでファイル名を指定します。

$ generate_keypair -o ./mint.key

設定ファイルを作成します。この際、設定ファイルのテンプレートとなるファイルをbオプションを用いて指定する必要があります。テンプレートファイルがリポジトリ内のconfig/data/configs/node.config.tomlに用意されているのでこれを利用します。また、mオプションで先ほど作成したキーペアを、nオプションでノードの数(今回は2)を指定します。

$ libra-config -b ../libra/config/data/configs/node.config.toml -m ./mint.key -n 2
$ ls
trusted_peers.config.toml
seed_peers.config.toml
validator_8deeeaed65f0cd7484a9e4e5ac51fbac548f2f71299a05e000156031ca78fb9f.node.config.toml
validator_8deeeaed65f0cd7484a9e4e5ac51fbac548f2f71299a05e000156031ca78fb9f.node.keys.toml
validator_1e5d5a74b0fd09f601ac0fca2fe7d213704e02e51943d18cf25a546b8416e9e1.node.config.toml
validator_1e5d5a74b0fd09f601ac0fca2fe7d213704e02e51943d18cf25a546b8416e9e1.node.keys.toml

8deeeaed65f0cd7484a9e4e5ac51fbac548f2f71299a05e000156031ca78fb9fという名前のノードと、1e5d5a74b0fd09f601ac0fca2fe7d213704e02e51943d18cf25a546b8416e9e1という名前のノードの設定ファイルとキーペア、genesis.blobが作成されました。
今回は、
8deeeaed65f0cd7484a9e4e5ac51fbac548f2f71299a05e000156031ca78fb9fをノード1
1e5d5a74b0fd09f601ac0fca2fe7d213704e02e51943d18cf25a546b8416e9e1をノード2
とします。

これらの設定ファイルはIP v6用の設定になっているので編集します。まず、seed_peers.config.tomlにIPアドレスを書くところがあるので以下のように編集します。

[seed_peers]
8deeeaed65f0cd7484a9e4e5ac51fbac548f2f71299a05e000156031ca78fb9f = ["/ip4/192.168.10.1/tcp/34573"]
1e5d5a74b0fd09f601ac0fca2fe7d213704e02e51943d18cf25a546b8416e9e1 = ["/ip4/192.168.10.2/tcp/33199"]

また、以下の2つの設定ファイルもIP v6用の設定になっているので編集します。
validator_8deeeaed65f0cd7484a9e4e5ac51fbac548f2f71299a05e000156031ca78fb9f.node.config.toml
validator_1e5d5a74b0fd09f601ac0fca2fe7d213704e02e51943d18cf25a546b8416e9e1.node.config.toml
それぞれ「/ip6/::1/tcp/」、「::1」となっている部分を「/ip4/0.0.0.0/tcp/」、「0.0.0.0」に変更します。

参考として、変更後のファイルは以下の通りです。

validator_8deeeaed65f0cd7484a9e4e5ac51fbac548f2f71299a05e000156031ca78fb9f.node.config.toml
[base]
peer_id = "1e5d5a74b0fd09f601ac0fca2fe7d213704e02e51943d18cf25a546b8416e9e1"
data_dir_path = "/home/myhome/facebook/node"
node_sync_retries = 7
node_sync_channel_buffer_size = 10
node_async_log_chan_size = 256

[metrics]
dir = "metrics"
collection_interval_ms = 1000
push_server_addr = ""

[execution]
address = "localhost"
port = 37875
testnet_genesis = false
genesis_file_location = "genesis.blob"

[admission_control]
address = "0.0.0.0"
admission_control_service_port = 42891
need_to_check_mempool_before_validation = false

[debug_interface]
admission_control_node_debug_port = 43337
secret_service_node_debug_port = 37533
storage_node_debug_port = 46841
metrics_server_port = 38115
address = "0.0.0.0"

[storage]
address = "localhost"
port = 33041
dir = "libradb/validator_1e5d5a74b0fd09f601ac0fca2fe7d213704e02e51943d18cf25a546b8416e9e1/db"
grpc_max_receive_len = 100000000

[network]
listen_address = "/ip4/0.0.0.0/tcp/33199"
advertised_address = "/ip4/0.0.0.0/tcp/33199"
discovery_interval_ms = 1000
connectivity_check_interval_ms = 5000
enable_encryption_and_authentication = true
role = "validator"
peer_keypairs_file = "validator_1e5d5a74b0fd09f601ac0fca2fe7d213704e02e51943d18cf25a546b8416e9e1.node.keys.toml"
trusted_peers_file = "trusted_peers.config.toml"
seed_peers_file = "seed_peers.config.toml"

[consensus]
max_block_size = 100
proposer_type = "rotating_proposer"
contiguous_rounds = 2

[mempool]
broadcast_transactions = true
shared_mempool_tick_interval_ms = 50
shared_mempool_batch_size = 100
shared_mempool_max_concurrent_inbound_syncs = 100
capacity = 10000000
capacity_per_user = 100
sequence_cache_capacity = 1000
system_transaction_timeout_secs = 86400
system_transaction_gc_interval_ms = 180000
mempool_service_port = 37901
address = "localhost"

[state_sync]
chunk_limit = 1000
tick_interval_ms = 10
long_poll_timeout_ms = 30000
max_chunk_limit = 1000
max_timeout_ms = 120000

[log_collector]
is_async = true
use_std_output = true
[vm_config.publishing_options]
type = "Open"

[secret_service]
address = "localhost"
secret_service_port = 33739

編集したら~/facebook/nodeのディレクトリごともう一方のサーバにコピーしておいてください。

最後にそれぞれのサーバでノードを起動します。
まず、ノード1のサーバでノードを起動します。fオプションで設定ファイルを、pオプションでノードのIDを指定します。

$ libra_node -f ./validator_1e5d5a74b0fd09f601ac0fca2fe7d213704e02e51943d18cf25a546b8416e9e1.node.config.toml -p 1e5d5a74b0fd09f601ac0fca2fe7d213704e02e51943d18cf25a546b8416e9e1

次に、ノード2のサーバでノードを起動します。

$ libra_node -f ./validator_8deeeaed65f0cd7484a9e4e5ac51fbac548f2f71299a05e000156031ca78fb9f.node.config.toml -p 8deeeaed65f0cd7484a9e4e5ac51fbac548f2f71299a05e000156031ca78fb9f

たくさんログが出ますが、

Successfully connected to peer

というログが表示されれば成功です。

トランザクション実行

https://developers.libra.org/docs/my-first-transaction
と同様のトランザクションを実行します。チュートリアルと同様にCLI clientを用いてトランザクションを実行します。

ノード1サーバのfacebookディレクトリ配下にclient1とclien2というディレクトリを作成します。今後はこのディレクトリの中で作業を行います。

$ mkdir ~/facebook/client1
$ mkdir ~/facebook/client2
$ cd ~/facebook/client1

まずノード1に接続するclientを起動します。この際、先ほど作成したmint.keyとtrusted_peers.config.tomlが必要になるので、nodeディレクトリからコピーしておきます。

$ cp ../node/mint.key .
$ cp ../node/trusted_peers.config.toml .

CLI clientを起動します。mオプションでキーペアを、aオプションでIPアドレスを、pオプションでノード1の設定ファイル(validator_1e5d5a74b0fd09f601ac0fca2fe7d213704e02e51943d18cf25a546b8416e9e1.node.config.toml)の中にあるadmission_control_service_portの番号を、sオプションでtrusted_peers.config.tomlを指定します。

$ client -m ./mint.key -a localhost -p 42891 -s ./trusted_peers.config.toml
Connected to validator at: localhost:42891
usage: <command> <args>

Use the following commands:

account | a 
        Account operations
query | q 
        Query operations
transfer | transferb | t | tb 
        <sender_account_address>|<sender_account_ref_id> <receiver_account_address>|<receiver_account_ref_id> <number_of_coins> [gas_unit_price_in_micro_libras (default=0)] [max_gas_amount_in_micro_libras (default 100000)] Suffix 'b' is for blocking. 
        Transfer coins (in libra) from account to another.
dev 
        Local move development
help | h 
        Prints this help
quit | q! 
        Exit this client


Please, input commands: 

libra% 

https://developers.libra.org/docs/my-first-transaction
に書かれているコマンドを実行していきます。

libra% account create
>> Creating/retrieving next account from wallet
Created/retrieved account #0 address bc9e6e3b8ddf96fbd57b6541d6286df319ecb4a23aad2039c7c75ae6a60471f1
libra% account create
>> Creating/retrieving next account from wallet
Created/retrieved account #1 address aac6755196d5108f4119ed5bca7faef7d90af00815ed156fc5844cb3b9cb23eb
libra% account mint 0 110
>> Minting coins
Mint request submitted
libra% account mint 1 52
>> Minting coins
Mint request submitted
libra% query balance 0
Balance is: 110.000000
libra% query balance 1
Balance is: 52.000000
libra% query sequence 0
>> Getting current sequence number
Sequence number is: 0
libra% query sequence 1
>> Getting current sequence number
Sequence number is: 0
libra% transfer 0 1 10
>> Transferring
Transaction submitted to validator
To query for transaction status, run: query txn_acc_seq 0 0 <fetch_events=true|false>
libra% query sequence 0
>> Getting current sequence number
Sequence number is: 1
libra% query sequence 1
>> Getting current sequence number
Sequence number is: 0
libra% query balance 0
Balance is: 100.000000
libra% query balance 1
Balance is: 62.000000

ノード2に接続するclientを起動します。ノード1と同じですが、mintトランザクションは実行しないため、mint.keyは必要ありません。

$ cd ~/facebook/client2
$ cp ../node/trusted_peers.config.toml .

CLI clientを起動します。aオプションでIPアドレスを、pオプションでノード2の設定ファイル(validator_8deeeaed65f0cd7484a9e4e5ac51fbac548f2f71299a05e000156031ca78fb9f.node.config.toml)の中にあるadmission_control_service_portの番号を、sオプションでtrusted_peers.config.tomlを指定します。

$ client -a 192.168.10.2 -p 40409 -s ./trusted_peers.config.toml
Connected to validator at: 192.168.10.2:40409
usage: <command> <args>

Use the following commands:

account | a 
        Account operations
query | q 
        Query operations
transfer | transferb | t | tb 
        <sender_account_address>|<sender_account_ref_id> <receiver_account_address>|<receiver_account_ref_id> <number_of_coins> [gas_unit_price_in_micro_libras (default=0)] [max_gas_amount_in_micro_libras (default 100000)] Suffix 'b' is for blocking. 
        Transfer coins (in libra) from account to another.
help | h 
        Prints this help
quit | q! 
        Exit this client


Please, input commands: 

libra% 

ノード1で実行したトランザクションとその結果がノード2からクエリできることを確認します。
その際、account createを実行した際に画面に表示されたaccountのaddressが必要になります。今回は以下の2つです。
bc9e6e3b8ddf96fbd57b6541d6286df319ecb4a23aad2039c7c75ae6a60471f1
aac6755196d5108f4119ed5bca7faef7d90af00815ed156fc5844cb3b9cb23eb

libra% query balance bc9e6e3b8ddf96fbd57b6541d6286df319ecb4a23aad2039c7c75ae6a60471f1
Balance is: 100.000000
libra% query balance aac6755196d5108f4119ed5bca7faef7d90af00815ed156fc5844cb3b9cb23eb
Balance is: 62.000000
libra% query sequence bc9e6e3b8ddf96fbd57b6541d6286df319ecb4a23aad2039c7c75ae6a60471f1
>> Getting current sequence number
Sequence number is: 1
libra% query sequence aac6755196d5108f4119ed5bca7faef7d90af00815ed156fc5844cb3b9cb23eb
>> Getting current sequence number
Sequence number is: 0

残高やシーケンスがノード1と一致していことがわかります。
また、query txn_range <start_version> <limit> <fetch_events=true|false>でトランザクションの内容をクエリできます。

libra% query txn_range 0 10 false
>> Getting committed transaction by range
Transaction at version 0: SignedTransaction { 
 raw_txn: RawTransaction { 
        sender: 000000000000000000000000000000000000000000000000000000000a550c18, 
        sequence_number: 0, 
        payload: {, 
                transaction: genesis, 
                args: [  
                ]
        }, 
        max_gas_amount: 0, 
        gas_unit_price: 0, 
        expiration_time: 18446744073709551615s, 
}, 
 public_key: Ed25519PublicKey(
    PublicKey(CompressedEdwardsY: [102, 79, 110, 143, 54, 234, 203, 23, 112, 250, 135, 157, 134, 194, 193, 208, 250, 254, 161, 69, 232, 79, 167, 214, 113, 171, 122, 1, 26, 84, 213, 9]), EdwardsPoint{
        X: FieldElement51([1852396171027154, 860490020578256, 813265495276734, 709853280255065, 1167621827020382]),
        Y: FieldElement51([1101944985636710, 232757151007481, 1838365913843466, 1610695743894562, 172989498791850]),
        Z: FieldElement51([1, 0, 0, 0, 0]),
        T: FieldElement51([416741632430606, 2066765412282255, 1539741622329517, 1822242378190878, 341152508952685])
    }),
), 
 signature: Ed25519Signature(
    Signature( R: CompressedEdwardsY: [237, 53, 137, 203, 231, 16, 247, 105, 95, 90, 93, 148, 44, 153, 95, 115, 197, 80, 157, 146, 26, 163, 230, 224, 250, 157, 132, 135, 3, 254, 126, 13], s: Scalar{
        bytes: [78, 48, 115, 67, 168, 40, 194, 198, 240, 218, 60, 222, 119, 88, 146, 116, 78, 52, 115, 47, 85, 205, 72, 198, 115, 132, 17, 166, 234, 152, 86, 5],
    } ),
), 
 }
Transaction at version 1: SignedTransaction { 
 raw_txn: RawTransaction { 
        sender: 000000000000000000000000000000000000000000000000000000000a550c18, 
        sequence_number: 0, 
        payload: {, 
                transaction: mint_transaction, 
                args: [ 
                        {ADDRESS: bc9e6e3b8ddf96fbd57b6541d6286df319ecb4a23aad2039c7c75ae6a60471f1},
                        {U64: 110000000}, 
                ]
        }, 
        max_gas_amount: 140000, 
        gas_unit_price: 0, 
        expiration_time: 1566832205s, 
}, 
 public_key: Ed25519PublicKey(
    PublicKey(CompressedEdwardsY: [102, 79, 110, 143, 54, 234, 203, 23, 112, 250, 135, 157, 134, 194, 193, 208, 250, 254, 161, 69, 232, 79, 167, 214, 113, 171, 122, 1, 26, 84, 213, 9]), EdwardsPoint{
        X: FieldElement51([1852396171027154, 860490020578256, 813265495276734, 709853280255065, 1167621827020382]),
        Y: FieldElement51([1101944985636710, 232757151007481, 1838365913843466, 1610695743894562, 172989498791850]),
        Z: FieldElement51([1, 0, 0, 0, 0]),
        T: FieldElement51([416741632430606, 2066765412282255, 1539741622329517, 1822242378190878, 341152508952685])
    }),
), 
 signature: Ed25519Signature(
    Signature( R: CompressedEdwardsY: [105, 84, 144, 28, 62, 83, 198, 96, 163, 63, 75, 144, 103, 157, 195, 238, 64, 73, 71, 81, 141, 202, 32, 109, 31, 227, 212, 99, 165, 202, 152, 67], s: Scalar{
        bytes: [98, 251, 140, 141, 128, 184, 104, 160, 34, 211, 71, 123, 125, 182, 170, 171, 252, 178, 108, 52, 140, 188, 52, 168, 111, 173, 125, 64, 100, 0, 151, 11],
    } ),
), 
 }
Transaction at version 2: SignedTransaction { 
 raw_txn: RawTransaction { 
        sender: 000000000000000000000000000000000000000000000000000000000a550c18, 
        sequence_number: 1, 
        payload: {, 
                transaction: mint_transaction, 
                args: [ 
                        {ADDRESS: aac6755196d5108f4119ed5bca7faef7d90af00815ed156fc5844cb3b9cb23eb},
                        {U64: 52000000}, 
                ]
        }, 
        max_gas_amount: 140000, 
        gas_unit_price: 0, 
        expiration_time: 1566832211s, 
}, 
 public_key: Ed25519PublicKey(
    PublicKey(CompressedEdwardsY: [102, 79, 110, 143, 54, 234, 203, 23, 112, 250, 135, 157, 134, 194, 193, 208, 250, 254, 161, 69, 232, 79, 167, 214, 113, 171, 122, 1, 26, 84, 213, 9]), EdwardsPoint{
        X: FieldElement51([1852396171027154, 860490020578256, 813265495276734, 709853280255065, 1167621827020382]),
        Y: FieldElement51([1101944985636710, 232757151007481, 1838365913843466, 1610695743894562, 172989498791850]),
        Z: FieldElement51([1, 0, 0, 0, 0]),
        T: FieldElement51([416741632430606, 2066765412282255, 1539741622329517, 1822242378190878, 341152508952685])
    }),
), 
 signature: Ed25519Signature(
    Signature( R: CompressedEdwardsY: [190, 204, 179, 21, 144, 117, 11, 137, 212, 180, 53, 10, 29, 199, 177, 28, 228, 33, 175, 62, 144, 210, 105, 1, 55, 49, 118, 199, 171, 130, 220, 173], s: Scalar{
        bytes: [9, 215, 147, 62, 131, 31, 62, 231, 111, 36, 27, 211, 136, 98, 162, 130, 133, 191, 164, 17, 46, 99, 134, 198, 79, 73, 141, 235, 74, 51, 199, 15],
    } ),
), 
 }
Transaction at version 3: SignedTransaction { 
 raw_txn: RawTransaction { 
        sender: bc9e6e3b8ddf96fbd57b6541d6286df319ecb4a23aad2039c7c75ae6a60471f1, 
        sequence_number: 0, 
        payload: {, 
                transaction: peer_to_peer_transaction, 
                args: [ 
                        {ADDRESS: aac6755196d5108f4119ed5bca7faef7d90af00815ed156fc5844cb3b9cb23eb},
                        {U64: 10000000}, 
                ]
        }, 
        max_gas_amount: 140000, 
        gas_unit_price: 0, 
        expiration_time: 1566832243s, 
}, 
 public_key: Ed25519PublicKey(
    PublicKey(CompressedEdwardsY: [58, 63, 85, 167, 117, 103, 100, 191, 235, 179, 53, 106, 137, 189, 118, 49, 49, 188, 198, 31, 116, 80, 162, 32, 7, 142, 235, 8, 189, 121, 112, 219]), EdwardsPoint{
        X: FieldElement51([1772812698879353, 304530301646940, 2169944738223635, 697707544457128, 1010507603644876]),
        Y: FieldElement51([1239654923059002, 331256709347308, 1999946232748790, 1974243208739343, 1608618190343864]),
        Z: FieldElement51([1, 0, 0, 0, 0]),
        T: FieldElement51([1387442142995314, 665264140131818, 629072752354239, 1547256085650866, 1618042475867041])
    }),
), 
 signature: Ed25519Signature(
    Signature( R: CompressedEdwardsY: [39, 182, 130, 122, 90, 0, 201, 1, 194, 27, 81, 52, 242, 45, 110, 98, 60, 12, 17, 236, 189, 81, 36, 30, 154, 102, 116, 6, 219, 164, 207, 94], s: Scalar{
        bytes: [246, 245, 235, 81, 114, 195, 190, 184, 156, 253, 124, 61, 188, 51, 9, 136, 42, 47, 172, 127, 191, 83, 158, 6, 244, 38, 174, 58, 140, 5, 77, 12],
    } ),
), 
 }

genesisトランザクションが1つとmintトランザクションが2つ、アカウント間で送金した際のpeer_to_peer_transactionがノード2からもクエリできることが確認できました。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0