Bitcoin Core 0.11 (ch 1): Overview
目次
ページの構成とメンテナンス[編集]
この一連のWikiページの目的は、Bitcoin Core C ++のソースコードを文書化して、プログラムの設計方法とコードの内容を学びたいプログラマーにとって有益な方法です。
理想的には、これらのページの情報の正確さは、Bitcoin Coreコードベースの速度を上げている開発者によってチェックされます。さらに、新しいバージョンのBitcoin Core(0.12、0.13など)には、そのバージョンと一致するように変更された新しい一連のページが含まれる可能性があります。
ページは、2011年に書かれたバージョン0.3に基づいて作成された "Satoshi Client:xxx"(このWiki上)というページセットに基づいています。
このWikiページのセットは次のとおりです。
- Ch 1:イントロと概要(このページ)
- Ch 2:データストレージ
- Ch 3:初期化とスタートアップ
- Ch 4:P2Pネットワーク
- Ch 5:初期ブロックダウンロード(IBD)
- Ch 6:ブロックチェーン
- Ch 7:トランザクションとメモリプール
- Ch 8:RPCサーバー
これらのページには、Bitcoin Coreの「リレーノード」の側面が記載されています。これは、ブロックとトランザクションを検証し、それらを他のノードに中継するノードを意味します。ノードはブロックチェインを完全に検証しましたが、必ずしもディスク上に完全コピーを保持しているとは限りません。
これらのページには含まれていません:
- ウォレット
- GUI(Qt)
- 採掘
定義[編集]
最初はいくつかの定義があります:
コンセンサスコード[編集]
ブロックとトランザクションを検証するコード。
コンセンサスコードは、バージョンと実装の間でバグに対する互換性を持っていなければなりません(つまり、バグがあっても0.12は0.11と同じコンセンサスビヘイビアを持つ必要があり、そうでない場合はネットワークフォークが発生する可能性があります)。
ポリシーコード[編集]
特定のノードのポリシーを実装するコード(コンセンサスとは対照的に)。トランザクションプールに格納するトランザクションのノードアルゴリズム。ポリシーの例です。たとえば、ノードが200KBを超えるトランザクションを中継または格納することを拒否する可能性があります。重要なのは、そのようなトランザクションが新たに採掘されたブロックの一部としてノードに送信される場合、ノードはそのブロックを拒否しないことです。
P2Pコード[編集]
P2Pネットワーク上の他のノード(ピア)との通信に関連するコード。通信には、他のノードの検出と接続が含まれます。様々なP2Pメッセージ(例えば、ブロックおよびトランザクションを含むメッセージ)を交換する。時には、誤動作している同輩を禁止する。ビットコインネットワークは、P2Pメッセージのカスタムセットを使用します。ほとんどのP2Pコードは net.h / net.cpp にあります。
Mempool( "メモリプール"または "トランザクションプール")[編集]
ノードが知っていて、メモリに格納して他のノードにリレーすることを選択し、ブロックにまだ含まれていないトランザクションのセット。多くの場合、これは、ノードが受信して検証したトランザクションの完全なセットである可能性があります。しかし、ノードがそのポリシーに違反するトランザクションを受け取った場合、mempoolはサブセットになります。いずれにしても、ノードがブロックを受信して検証すると、ブロック内のトランザクションはすべてそのメンプールから削除されます。
フルノード[編集]
完全なノードは、ブロックとトランザクションを検証し、それらを他のノードに中継するノードです。完全なノードはゼロからブロックチェーンを検証しましたが(ブロックファイルプルーニングではチェーンの古い部分を破棄してディスク領域をクリアしている可能性があります)。完全なノードの重要な特徴はブロックチェーンを検証し、受信ブロックとトランザクションを検証してリレーします。完全なノードは、別のノード(または一連のノード)を信頼して検証するSPVノードと区別できます。
基本完全ノード[編集]
「基本完全ノード」は、これらのページに記載されているものです。 「基本完全ノード」とは、ブロックとトランザクションを検証してリレーするノードですが、新しいブロックをマイニングすることも、その他のオプションのタスク(RPCサーバー、ウォレット)を実行することもありません。これらのページを拡張して、ノードのこれらのオプションの側面のドキュメントを含めることは、将来のプロジェクトです。
Bitcoinノードのアーキテクチャ[編集]
ある開発者は、基本的な完全ノードのアーキテクチャを次のように説明しました。
:--------------------
ビットコインノードの基本アーキテクチャは以下の通りです。
:コアには、シリアライゼーション/デシリアライズに必要なコードとともに、基本的なビットコインメッセージ構造があります。これらの構造体は、依存関係を最小限に抑えて独自のソースファイルに属しているため、フィルタリングや通知エージェントなどの検証やリレーを実行する必要がないアプリケーションに再利用できます。残念ながら、これらのコア構造は現在、main.h / main.cppのほとんどの部分にあります。
:これらのコア構造の上には、ソケットを管理し、ピア発見を行い、メッセージのキューイングとディスパッチを処理するネットワークコンポーネントがあります。このコンポーネントは、明らかにコアメッセージ構造に依存しますが、ブロックとトランザクションを検証するために使用される特定のロジックや、不正なピアを特定したり、トランザクションに署名したり、ブロックチェーンデータベースを維持したりすることはありません。
次に、スクリプトエンジン、署名検証コンポーネント、署名コンポーネントがあります。履歴データベースアプリケーションは、署名検証/署名機能をまったく必要としません。メッセージのフィルタリングとアラートの送信は、一般にスクリプトエンジンを必要とせず、基本的なパターンマッチングでうまくいきます。
:聡明なクライアントなどの検証/中継ノードによって必要とされる最も重要な高レベル操作は、トランザクション検証である。ブロックチェーンとメモリプール管理;不正なピアの検出/管理。これらは現在主にmain.h / main.cppに実装されています。これらは実際には偽クライアントの主な操作ですが、コアの低レベル構造はこのロジックには全く依存すべきではありません。
:---------------------
こちらをご覧ください:PR 2154
(粗)画像の形で:
トランザクションの検証。ブロックチェーン、mempool、および同僚の管理。
|
スクリプトエンジン/シグネチャ
|
ネットワーク層
|
P2Pメッセージ
そして、上の定義で補われた同じ図がここにあります:
トランザクションの検証。ブロックチェーン、mempool、同僚の管理(コンセンサスとポリシーコード)
|
スクリプトエンジン/署名(コンセンサスコード)
|
ネットワーク層(P2Pコード)
|
P2Pメッセージ
コードモジュール化/組織[編集]
0.11から、Bitcoin Coreコードのモジュール化はいくらか制限されています。
理想的には、Bitcoin Coreはモジュール化され、コンセンサスコードが分離され、他の実装に配布されるライブラリになります。このようにして、誤ってネットワークをフォークする恐れが軽減されます。 2016年現在、これは進行中の作業です(GitHubのさまざまな「libconsensus」プルリクエストなどを参照してください)。
2013年12月に、コードベースのモジュール化の提案が行われました。[Bitcoin Coreのポスト0.9モジュール化] [1]
オプションモジュールの例は次のとおりです。
- 鉱夫
- ウォレット
- 通知
0.11から、モジュール化に向けたステップは、主に、特定のクラスを以下に説明するサブディレクトリに分割していました
ソースコードファイル[編集]
C ++コードは、リポジトリのsrc /ディレクトリにあります。
ほとんどのコードはトップレベルのディレクトリにありますが、サブディレクトリ(ウォレット、コンセンサス、プリミティブなど)を使用してコードベースをモジュール化する努力もありますが、特定のコンポーネント(QT、LevelDBなど)もサブディレクトリにあります。
src /ディレクトリのキーファイルには次のものが含まれます:(file。*はヘッダーファイル[file.h]とソースファイル[file.cpp]を意味します)
ファイル | 説明/目的 |
---|---|
ネット。* | ネットワーク(ピア接続など)を管理します。 ThreadMessageHandlerのwhile(true)ループは、処理が必要なときに main.cpp を通知するプログラムのフローを制御します。 主な依存関係:なし。 |
init.cpp | 必要に応じて main.cpp の関数を呼び出す、ノードを初期化します。 主な依存関係:main.h |
メイン。* | main.hはいくつかの主要なグローバル変数(mapBlockIndex、chainActive、mempoolなど)、定数、および関数を宣言します。 main.cppは、プログラムの最長のソースファイル(5,237行)です。 main.cppは、接続、切断、検証、保存などのブロックチェーンを管理するための主要な機能をほとんど持っていますブロック;特定のブロックを最長チェーンの先端として特定するステップと、 ほとんどのコードの「エントリポイント」はProcessMessages(メッセージ処理スレッドからのシグナルをリッスンする)です。 コードの中には、初期化中に実行されるものがあります。 .cpp。 主な依存関係:net.h |
チェーン。* | ヘッダーファイル(chain.h)は、ブロック(CBlockIndex)と最長ブロックチェーン(CChain)に関するメタデータの型定義を宣言しているので、2つのうち最も顕著なものです。 chain.cppには、ブロックチェーンを管理するための便利な機能がいくつかあります(たとえば、ブロックの検索や2つのチェーン間のフォークポイントの検索など)。 |
コイン。* | ヘッダファイルには概念的には "ビットコイン"であるCCoinが宣言されています。 ソースファイルには、コイン(取得、支出など)を操作するためのメソッドが含まれています。 |
鉱夫。* | ブロックの作成や新しいビットコインの生成を含むマイニングコードが含まれています。 |
'サブディレクトリ:'
サブディレクトリは3つのカテゴリに分類されます。
- 明確に定義されたコンポーネント(場合によっては第三者)
- コードのモジュール化
- その他(単体テスト、ビルドファイルなど)
サブディレクトリ - コンポーネント:
ディレクトリ | 説明/目的 |
---|---|
leveldb | LevelDBビルド用のC ++ソースコード、ドキュメントなど。 |
qt | GUIコード(QT)。 QTは、1995年に初めてリリースされたGUIコード用のC ++オープンソースプロジェクトです。 |
secp256k1 | ECDSA暗号を実装するライブラリ 目的:この独自のCライブラリは、署名検査のためのSSLへの依存を排除します。 新しくリリースされたバージョンではバグのためのバグの互換性が保証されていないため、SSLはコンセンサスバグの導入を受けやすいため、これは重要です。 このライブラリは2015年初頭に書かれ、リリースされました。 |
zmq | ZMQ wikiから: ZMQ(またはZeroMQまたは0MQ)は、高性能な非同期メッセージングライブラリです。 メッセージキューを提供しますが、メッセージ指向のミドルウェアとは異なり、ZMQシステムは専用のメッセージブローカー。 ライブラリは使い慣れたソケットスタイルのAPIを持つように設計されています。 |
サブディレクトリ - モジュール化:
ディレクトリ | キーファイル | 説明/目的 |
---|---|---|
コンセンサス | 合意。* merkle。* params。* 検証。* |
目的:このコードをサブディレクトリに移動することは、コンセンサスコードのモジュール化に向けた一歩です。 アイデアは、将来のバージョンでは(つまり、コンセンサスコードはライブラリとしてパッケージ化する必要があるため、プロトコルの別の実装ではこのライブラリを単純に組み込み、検証の互換性を保証することができます。 "...彼の目標は、コンセンサスのルールを再実装するのではなく、Bitcoin Coreからそれらを抽出して、誰も再実装する必要がないようにすることです。Bitcoin Coreから公開するだけでなく、Bitcoin Core Bitcoin Core特有のものを変更したり、考慮したりすることなく、変更することができます。 - Jorge Timon、2015年8月20日、Bitcoin-Developmentメーリングリストで公開されました。 [gps / gitub.com/bitcin/issues/6714 PR6714] |
暗号 | ripemd。* sha256。* |
暗号化ハッシュ関数 RIPEMDとSHA-256はビットコインアドレスをBase-58エンコーディングに変換する際に使用されます。 |
ポリシー | ポリシー。*手数料。* | (コンセンサスとは対照的に)「政策」の問題である検証コードを別のディレクトリに移動する。 |
プリミティブ | ブロック。* トランザクション。* |
特定の基本データ型(ブロック、トランザクションなど)の定義 |
スクリプト | 通訳。*スクリプト。*標準。* | スクリプトエンジン op_codes(script.h)を定義します。 検証スクリプトを解析して評価します。 (interpreter.cpp:EvalScript()) "標準"トランザクション(standard.h)を定義します。 目的:スクリプトエンジンは基本トランザクションを検証しますが、契約も可能にします。大部分、Ethereumのようなプラットフォームは、より堅牢なスクリプトエンジン(スクリプトを表現するための言語)を提供していると言えるかもしれません。つまり、ある意味では、このサブディレクトリ何かより強力な。 |
財布 | 財布。* | ウォレットコード。 |
サブディレクトリ - その他:
ディレクトリ | 説明/目的 |
---|---|
compat | 互換性の詳細を扱う少数のマイナーな低レベルのファイル。 |
設定 obj obj-test |
これらのディレクトリは、ビルドプロセスに関連しています。 |
テスト | ユニットテスト Boostユニットテストフレームワークを使用します。 Boostユーザテストフレームワークの紹介は、ここにあります:- と - ブーストテスト/ |
一義性 | README: 「JSONエンコーディング(出力)とデコード(入力)を持つ普遍的な価値オブジェクト 単一の動的RAII C ++オブジェクトクラスとして構築され、テンプレートはありません。 |
デザインパターン[編集]
'オブジェクト指向設計'
当然のことながら、C ++プログラムであるこのコードでは、オブジェクト指向設計が採用されています。
しかし、コードのオブジェクト指向設計の使用は普遍的ではありません。 0.11では、主にmain.cppがブロックチェーンとUTXOセット(ビットコイン)を管理するために使用するデータ構造を定義するためにオブジェクトが使用されます。 Main.hは多くの関数とグローバル変数を宣言しますが、ほとんどのクラスは宣言しません。 main.cpp は5000行以上ありますが、クラスメソッドは含まれていません。
コードは比較的フラットなクラス構造を持ち、ほとんどのクラスは「スタンドアロン」です。
継承が使用される場合、それはしばしば線形階層(すなわち、A < - B < - C < - D)であり、
例えば: CBlockHeader < - CBlock CTransaction < - CMerkleTx < - CWalletTx
2つ以上の子孫クラスを持つ基本クラスの例はわずかで、複数の継承はコード内で1回のみ使用されます(CWalletは2つのクラスから継承されます)。
エレガントなクラス階層のプログラムの最良の例は、コインキャッシュに関するものです。カプセル化と多型を示すいくつかのサブクラスによって継承される抽象クラスを使用します。第3章では、クラス図と、そのクラスがどのようにインスタンス化され、互いに関連しているかの図と説明を示しています。
'マルチスレッド'
このコードでは、Boostスレッドグループを使用してマルチスレッドを実装しています。アクションの大部分は、メッセージ処理スレッドで行われますが、ソケットスレッドでは発生しません。
'オブザーバー(信号とスロット)'
「オブザーバ」パターンは、2つ以上のコード領域をデカップリングするために「信号とスロット」を使用します。 Bitcoin Core 0.11では、オブザーバパターンが限定的に使用されています。つまり、 main.cpp コードからメッセージ収集ループを切り離すために信号を使用します。 0.10以前では、通常の関数呼び出しが使用されていました。
関連項目[編集]
Bitcoin Core 0.11(Ch 2):データストレージ
Core 0.11(Ch 3):初期化とスタートアップ
Bitcoin Core 0.11(Ch 4):P2Pネットワーク
Bitcoin Core 0.11(Ch 5):初期ブロックダウンロード
Bitcoin Core 0.11(Ch 6):ブロックチェーン