Bitcoin Core 0.11 (ch 3): Initialization and Startup

提供: tezos-wiki
2018年4月14日 (土) 16:12時点におけるVq35de (トーク | 投稿記録)による版
移動先: 案内検索

このページでは、起動と初期化を管理するBitcoin Coreコードについて説明します。

プログラムエントリポイント

プログラムのエントリポイントは bitcoind.cpp </ u>にあります。

main()はコードの3行です:

  • SetupEnvironment()(これはプログラムのロケールを設定します)
  • 信号ハンドラを接続する
  • AppInit()(この関数はプログラムの寿命を延ばす)


AppInit:これは<u> bitcoind.cpp </ u>の近くにあります。

  • コマンドラインを解析する
  • データディレクトリを開きます。
  • 設定ファイルを読み込みます
  • プロセスをフォークします(デーモンとして実行している場合)
  • コントロールを<u> init.cpp </ u>にあるAppInit2()に渡します。


初期化ステップ(<u> init.cpp </ u>)

AppInit2()はビットコインシステムを初期化します。

これには約800行のコードが含まれており、12段階に分かれています。

各ステップが始まる場所は、コードに文書化されています。 <u> Init.cpp </ u>にはファイルの先頭にいくつかの関数がありますが、大部分はAppInit2()で構成されています。

次の表は、手順をまとめたものです。

初期化
ステップ
簡単な説明 詳細
1 OS固有のセットアップタスク これらの作業は特に興味深いものではありません。
詳細は、コードを参照してください。
2 パラメータの相互作用 特定のコマンドラインオプションでは、特定の方法で他のオプションを設定する必要があります。
たとえば、-zapwallettxesは-rescanを意味します。したがって、コードは-rescanフラグ= trueを設定します(まだ存在していない場合)。
3 内部フラグ /
パラメータ健全性チェック
特定のパラメータのグローバル変数を設定します。
財布については、取引料金レベルを正当性をチェックします(あなたの手数料がリレー[エラー]の資格を得るのに十分高いが、不当に高い[警告]ではないことを確認します)。
4 アプリケーション初期化。 / RPCサーバー

データディレクトリをロックします。 (できない場合は、エラーを出力して終了してください。)
スクリプトチェックエンジン用のXスレッドを生成する。 (デフォルト= 0、使用可能なすべてのプロセッサを使用することを意味し、boost :: thread :: hardware_concurrency)。
"ウォームアップ"モードでRPCサーバーを起動します。

5 ウォレット・データベースの整合性の確認 ウォレットが有効になっている場合は、開こうとします。

ウォレットが破損していることがわかっている場合(-salvagewallet)、パスワードの回復を試みます。

6 ネットワーク初期化

ノードは特定の信号を登録する。
ユーザーが特定のネットワーク(ip4、ip6、tor)のピアとのみ対話したいかどうかを確認します。
オニオンルーティング(tor)を使用するかどうかをチェックします。
ユーザーが特定のピアをホワイトリストに登録するかどうかを確認します。
ビットコインポートでリスンしようとします(失敗時に終了します)。
ユーザーが接続をシードする特定のピアを指定した場合は、接続を試みます。

7 ブロックチェーンをロードします。

ブロックチェーンをメモリにロードし、UTXOキャッシュを初期化します。

<u>キャッシュサイズを計算します。
3つの特定のキャッシュに分割された合計キャッシュサイズがあります。
デフォルトの合計キャッシュサイズ= 100MB(最大:4GB、最小:4MB)。
1)ブロックチェーンキャッシュ:合計キャッシュの1/8ですが、2MBを超えてはいけません。
2)UTXOデータベース・キャッシュ:残りのキャッシュ・スペースの25〜50%。 これはLevelDBキャッシュです。
これは、LevelDBデータの圧縮されていないブロックを格納し、LevelDBによって管理されます。the LevelDB documentation.
3)UTXOインメモリキャッシュ:残りのキャッシュスペースの半分。
このキャッシュサイズは、cacheCoinsオブジェクト(CoinsViewCacheの保護されたメンバー)のサイズを定義します。
TODO:このステートメントが正しいことを確認してください...

ブロックチェーンをmapBlockIndexにロードします。
「ブロックチェイン」とは、ブロックツリー全体(アクティブチェーン内のブロックだけでなく、すべての既知のブロック)を意味します。
メモリにロードされるのはブロックに関するメタデータを含むCBlockIndexオブジェクトです。
最後の288ブロック(VerifyDB)を検証します。
注意:プログラムはこの時点までに起動から1秒未満を要します。 このステップには約10〜20秒かかります。

UTXOセット。
UTXOセットはメモリにロードされません。 代わりに、コインがデータベースからアクセスされるときにキャッシュがいっぱいになります。
2015年5月現在、UTXOセット全体をメモリに格納するには約3.6 GBが必要です。
2016年1月現在、ディスク上の圧縮データは約1.2 GBです。

8 ウォレットをロードします。 プログラムが初めて実行された場合は、ウォレットが作成され、最初のキー(アドレス)が与えられます。
9 Datadirのメンテナンス ユーザーがブロックプルーニングを行っている場合は、NODE_NETWORKの設定を解除し、プルーニング機能を呼び出します。
10 インポートブロック 現在有効なチェーンとして接続されていないブロックチェーンデータベースのチェーンをスキャンします。
11 開始ノード /
RPCサーバー

net.cppでStartNodeを呼び出します。
これは、プログラムのメインスレッドであるThreadProcessMessageを含むネットワーキングスレッドグループを起動します(下記参照)。
RPCサーバーを "ウォームアップ"モードから通常モードに移行します。

12 終了


AppInit2が終了すると、 bitcoind.cpp </ u>のAppInit()に戻ります。

そこで、コードのトップレベルスレッドは、WaitForShutdown()という関数で無期限にループします。 2秒間スリープ状態になり、ユーザーがctrl-Cを押したかどうかを確認します。 その場合は、<u> init.cpp </ u>でShutdown()を呼び出します。

シャットダウン()は、RPCサーバーをシャットダウンし、ノードを停止し、シグナルハンドラの登録を解除し、プログラムが完了します。

キャッシュサイズ

ステップ7は、キャッシュサイズを初期化した。手順7で考えられる3つのキャッシュがあります.2つはLevelDBデータベースキャッシュであり、もう1つはコインキャッシュであり、そのサイズは<u> main.cpp </ u>のフラッシュコードによって管理されます。

ユーザーは、-dbcacheを使用して合計キャッシュ・サイズを割り当てることができます。ユーザーは、特定の各キャッシュに割り当てるスペースを選択して選択することはできません。デフォルトの合計キャッシュサイズ= 100MB(最大:4GB、最小:4MB)。

'1)ブロックインデックスキャッシュ'

このキャッシュには、/ block / index LevelDBデータの圧縮されていないチャンクが保存され、LevelDBのドキュメントに記載されているように、LevelDBによって管理されます。 br>

ユーザーが完全なトランザクションインデックス(-txindex = 1)を有効にした場合、合計キャッシュサイズの1/8までになります。 -txindexが有効でない場合は、2 MiBだけが必要です。


'2)UTXOデータベースキャッシュ'

これは、/ chainstateデータベースのLevelDBキャッシュです。

このキャッシュは、合計キャッシュ・サイズに応じて、残りのキャッシュ・スペースの25〜50%に割り振られます。


'3)UTXOインメモリキャッシュ'

これは<u> main.cpp </ u>コードで管理されるコインキャッシュです。 (FlushStateToDiskおよび関連する関数を参照)

変数(nCoinsCache)は、<u> main.h </ u>のexternとして宣言されています。 <u> main.cpp </ u>には、5000 * 300にハードコードされています(メモリ内コインは約300バイトなので5000コインを意味します)。しかし、ステップ7で再初期​​化する必要があります。

このキャッシュには残りのキャッシュ領域がすべて与えられます。

このキャッシュは、初期化中にロードされるのではなく、コインがアクセスされるときに満たされます。 (これは、cachedCoinsUsage = 0を設定するCCoinsViewCacheコンストラクタによって検証できます)。

スレッド起動

このコードでは、boost :: thread_groupsを使用してさまざまなスレッドを管理しています。

Bitcoin Coreはマルチスレッドプログラムですが、 "参照Satoshiクライアントは主にシングルスレッドです"ということに注意してください。 BIP 31(2012)のMike Hearnによるコメント

つまり、プログラムの活動の大部分がメッセージングスレッド(ThreadMessageHandler - 以下を参照)で行われるということです。

ほとんどすべてのスレッドは、プログラムの起動時にスタック上に作成される単一のマスタースレッドグループの一部です(<u> bitcoind.cpp </ u>を参照)。このスレッドグループはいくつかの子スレッドを生成する<u> init.cpp </ u>に渡されます(いくつかのスクリプト検査スレッドを含みますが、これらはすべて別個のグループではなくマスタースレッドグループの一部です)。

スレッドグループは<u> net.cpp </ u>に渡され、メッセージ処理スレッドを含むネットワーキングスレッドが作成されます。

2つの他のスレッドグループはタスク固有です。

  • rpcサーバースレッドグループ(<r> rpcserver.h / cpp </ u>を参照)
  • minerスレッドグループ

当然のことながら、ノードはRPCサーバーがアクティブになっている場合にのみRPCサーバースレッドグループを作成し、マイナースレッドグループがマイニングの場合にのみ作成します。両方が無効の場合、Bitcoin Coreは単一のスレッドグループしか持たない。

'子スレッド'

親スレッド(プログラムが動作を開始するスレッドを意味する)は、ほとんどすべてのプログラムの作業を子スレッドに委譲します。 <u> init.cpp </ u>と<u> net.cpp </ u>でスレッドを生成した後、親スレッドは単にシャットダウンコマンドを待ちます。スレッドグループを開き、シャットダウンを続行します。

子スレッドは、作成された順にリストされています。

Thread When / Where Created Description
Script-checking Step 4
init.cpp
This is a set of threads - 4 by default.
Script-checking (including signature checking) is expensive so is handled in separate threads.
Scheduler Step 4
init.cpp
Scheduler thread.
(TODO: describe)
RPC Threads Step 4
rpcserver.cpp
If RPC server enabled, start a group of threads to handle RPC calls.
Import Step 10
init.cpp
Imports blocks. Three scenarios:
1) Reindex (rescan all known blocks from blk???.dat files).
2) Bootstrap (use bootstrap.dat as an alternative to full IBD from the network.)
3) -loadblock (scan a specific blk???.dat file)
If none of those apply, this thread does nothing.
DNSAddressSeed Step 11
net.cpp
Attempts to build a vector of IP addresses based on the dns seeds, stores the vector and the thread exits.
In a test in June 2014, this took about 4 seconds and found 158 addresses.
Plug & Play Step 11
net.cpp
UPNP (Universal Plug & Play)
Deals with port mapping for UPNP.
SocketHandler Step 11
net.cpp
<u>This thread services the sockets:
Waits for I/O on all the relevant sockets with a 50ms timeout.
Processes new incoming connections on listening socket and creates a CNode for the new peer.
Receives and sends data streams.
Sets sockets that have not done anything to a disconnected state.
OpenAddedConnections Step 11
net.cpp
Initiates outbound connections specified by the user with the –addnode parameter.
If can't connect, sleeps for 2 minutes each cycle.
OpenConnections Step 11
net.cpp
Initiates other outbound connections from DNS seeds (if that fails, find nodes based on fixed seeds)
If can't connect, sleeps for 500 milliseconds each cycle.
MessageHandler Step 11
net.cpp
This is the program's main thread.
This thread runs a while(true) loop, receiving and sending messages. (See net.cpp:1049)
The code uses boost::signals2 to call the ProcessMessages and SendMessages functions in main.cpp.
(The code introducing signals is in PR 2154 - see the next-to-last commit in that pull.)
ProcessMessage and SendMessage run in this thread.
So, most of the code in main.cpp runs in this thread.
Wallet Flusher Step 12
init.cpp
If wallet is enabled, this thread flushes the wallet periodically.


関連項目

Core 0.11(Ch 1):概要
Bitcoin Core 0.11(Ch 2):データストレージ
Bitcoin Core 0.11(Ch 4):P2Pネットワーク
Bitcoin Core 0.11(Ch 5):初期ブロックダウンロード
Bitcoin Core 0.11(Ch 6):ブロックチェーン


Category:技術 Category:開発者