ビットコイン・インスティテュート

ビットコインの​P2Pネットワーク設計 — ノード発見、​メッセージ中継、​ブロック伝播

淡く光るノードが線で結ばれた網目状のネットワーク図。起点ノードから同心円状の波が広がり、ノード間を破線の矢印とパケットのアイコンが行き来し、平文接続と暗号化接続を南京錠の開閉で対比させたパネルが添えられている

はじめに

本ページは設計文書シリーズのL1 #1 — P2Pネットワーク設計である。ネットワーク層を端から端まで解説する。ノードがどのように互いを発見し、メッセージをどのように交換し、トランザクションとブロックがピアツーピアのゴシップネットワークをどのように伝播するかを扱う。

ネットワーク層は合意形成層、トランザクション層、ブロック層の下に位置する。他のすべてが動作するためのトランスポートを提供する。信頼できるピアツーピア通信がなければ、合意形成設計、トランザクション設計、ブロック・チェーン設計の各ページに記述される決定論的検証規則は、処理すべきデータを持たないことになる。

サトシ時代の実装(v0.1、2009年1月。Forensicxsによる2024年のコードウォークスルーが行単位で調査済み)と現行のBitcoin Core(v27以降基準)で挙動が異なる場合は、両方を記す。

これらの概念がはじめての方は、取引はどうやって共有台帳になるのかがうわさ話ネットワークと、単一の相手を信用しない理由を事前知識ゼロで紹介している。本ページは同じ伝送層を設計文書として扱う。

1. ネットワークトポロジー

ビットコインは非構造的ゴシップネットワークを用いる。ノードはTCP接続のランダムなメッシュを形成し、データをピアに中継し、ピアはさらにそのピアに中継する。中央サーバー、ルーティングテーブル、分散ハッシュテーブル (DHT)、ノード間の階層構造は存在しない。すべてのフルノードは等しく権威を持つ。

ノード A

ノード B

ノード C

ノード D

ノード E

ノード F

ノード G

ノード H

特性設計上の選択
構造非構造的ランダムグラフ — DHTなし、スーパーノード階層なし
ノードあたりの接続数各ノードが少数のピアを維持(v27以降の既定: 出方向11、入方向最大114、合計125)
中継モデル蓄積転送型ゴシップ — 各ノードが中継前に独立して検証
冗長性メッセージは複数の経路を伝播する。単一のリンクが不可欠ということはない
分断耐性ランダムなピア選択が標的型ネットワーク分割を困難にする

ゴシップであり構造化ルーティングでない理由。DHTや階層的トポロジーはメッセージの冗長性を減らすが、単一障害点も生み出し、ネットワークの分断が容易になる。ビットコインのフラットなゴシップモデルは、攻撃者がノードの見る情報を制御するにはそのピアの大部分を侵害しなければならないことを保証する。これがエクリプス攻撃耐性の基盤である。

2. ノード発見

ネットワークに新規参加するノードはブートストラップ問題に直面する。最低1つの既存ピアを見つける必要があるが、ネットワークの構成員に関する事前知識を持たない。

発見メカニズム

メカニズム時代仕組み
IRCブートストラップv0.1 (2009年)ノードが特定のIRCチャネル(Freenodeの #bitcoin。2010年のv0.3でirc.lfnet.orgへ移った)に参加し、IPアドレスを告知した。他のノードはチャネルを読んでピアを発見した。v0.8.2 (2013年) で廃止。
ハードコードされたシードノードv0.1 → 現在バイナリにコンパイルされた信頼性の高い既知IPアドレスの一覧。DNSシードとキャッシュ済みピアが利用不能な場合の最終手段。
DNSシードv0.3.21以降 (2011年)ホスト名(例: seed.bitcoin.sipa.be)が現在アクティブなノードのIPアドレスに解決される。現行Bitcoin Coreの主要なブートストラップ手段。
addr / addrv2中継v0.1 → 現在接続済みピアが、既知の他のノードのIPアドレスを含むaddrメッセージを交換する。addrv2 (BIP 155、v0.21.0以降) はTor v3のアドレスに対応を広げ、I2Pはv22.0、CJDNSはv23.0で加わった。2026年10月には、接続できるアドレスの半分がTorの.onionだった(接続できるノードの半分がTorになった経緯)。
ローカルピアデータベースv0.1 → 現在ノードが既知のピアアドレスをpeers.datに永続化し、再起動時に再接続を試みる。正常に動作するノードは時間とともに数千のアドレスを蓄積する。

ブートストラップ手順(v27以降基準)

順を追うと、ノードはまずpeers.datを試すが、その結果得られる接続数が依然として少なすぎる場合は、集合を補うためにDNSシードにも問い合わせる。ハードコードされたシードは、他の2つの後にだけ試される段階ではなく、独立した最後の手段として同じ接続ステップに合流する。

サトシ時代とv27以降基準の比較。元のv0.1クライアントは主要な発見メカニズムとしてIRCに依存していた。これは単純だが、IRCサーバーのダウンタイムやチャネル追放に脆弱な中央集権的アプローチであった。現行のBitcoin Coreは独立したコミュニティメンバーが運営するDNSシードでIRCを置き換えている。DNSシード運営者はネットワークを継続的に探索するクローラーソフトウェアを動作させており、DNSレコードには現在到達可能で互換性のあるプロトコルバージョンを実行しているノードのみが反映される。

3. 接続管理

各ノードは2種類のTCP接続を維持する。ノードが開始する出方向接続と、他のノードがノードに対して開始する入方向接続である。

接続種別方向既定上限(v27以降)目的
全中継出方向出方向8トランザクションとブロックを中継するための主要ピア
ブロック中継専用出方向出方向2ブロックのみを中継(トランザクション/addr中継なし)。メモリープール情報を漏洩せずにブロック接続性を向上
フィーラー出方向(短命)同時に1候補アドレスが到達可能かを検査。ハンドシェイク成功後即座に切断
入方向入方向最大114(合計125から出方向の11枠を引いた数)他のノードからの接続。ノードは誰が接続するかを制御しない
アンカー出方向(永続)2(ブロック中継専用集合から)再起動をまたいで保存され、最低2つの信頼できる出方向ピアを維持。再起動時のエクリプス攻撃に抵抗

出方向と入方向: 設計による非対称性。ノードは自身の出方向接続を入方向接続よりも信頼する。出方向ピアは自分自身が選んだものだからである。ノードを孤立させたい攻撃者(エクリプス攻撃)が取れる道は二つしかない。すべての出方向ピアを制御するか、攻撃者制御の入方向接続でノードを溢れさせるかである。前者を果たすには、ノードのアドレス選択を予測または操作できなければならない。出方向数の少なさ(永続接続で合計10、内訳はフルリレー8 + ブロックリレー専用2。加えて、候補アドレスを試すためだけに使い捨てる一時的なフィーラー接続枠が1あり、瞬間ごとの出方向ソケット数としては11になる)と独立したアドレス選択アルゴリズムが、これを困難にしている。後者は入方向の退去ロジックによって維持コストがかさむ。

退去

ノードの入方向スロットが満杯の状態で新しい入方向接続が到着すると、ノードは既存ピアの1つを切断するかどうかを決定する退去アルゴリズムを実行する。このアルゴリズムは望ましい特性を持つピアを保護する:

  • 低レイテンシ(最近有用なデータを送信した)
  • 長い接続期間
  • ネットワークグループの多様性(異なる /16サブネット、異なる自律システム)
  • 最近有効なブロックまたはトランザクションを中継した

この多様性保持型退去は、攻撃者がノードの入方向スロットを独占するコストを高くする。攻撃者の接続は、保護されるすべての次元で正直なピアに同時に勝つことが難しいためである。

4. メッセージプロトコル

ピア間のすべての通信はバイナリメッセージプロトコルを使用する。すべてのメッセージは24バイトのヘッダー(4バイトのネットワークマジック + 12バイトのコマンド名 + 4バイトのペイロード長 + 4バイトのチェックサム)に続くペイロードで構成される。v0.1のヘッダーは20バイトで、チェックサムは2010年に加わった。

バージョンハンドシェイクとブロック中継

ノード B(応答側)ノード A(開始側)ノード B(応答側)ノード A(開始側)TCP 接続確立ハンドシェイク完了 — ピア稼働中後刻 — 新ブロック発見version(プロトコル版、サービス、最良ブロック高)version(プロトコル版、サービス、最良ブロック高)verackveracksendcmpct(コンパクトブロック対応を通知)sendcmpctcmpctblock(ヘッダー + 短縮 tx ID)メモリープールからブロックを再構築getblocktxn(不足トランザクションを要求)blocktxn(不足トランザクション)完全ブロックを検証

主要メッセージ型

メッセージペイロード役割
versionプロトコルバージョン、サービスビットマスク、最良ブロック高、ノードのタイムスタンプハンドシェイクを開始。ピア間で機能を交換
verack空versionメッセージを確認。ハンドシェイクを完了
invインベントリベクター(型 + ハッシュ)のリストデータ送信なしで既知のトランザクションまたはブロックを告知
getdataインベントリベクターのリスト告知された項目の完全データを要求
tx直列化されたトランザクションgetdataに応じてトランザクションを配信
block直列化された完全ブロック完全ブロックを配信(従来型中継モード)
headers最大2,000件のブロックヘッダーヘッダー先行同期用にブロックヘッダーを配信
getheadersロケーターハッシュ + 停止ハッシュブロックヘッダーの範囲を要求
cmpctblockヘッダー + 短縮トランザクションID (BIP 152)コンパクトブロック告知。受信側がメモリープールから再構築
getblocktxnブロックハッシュ + 不足トランザクションのインデックス受信側のメモリープールに存在しなかったトランザクションを要求
blocktxnブロックハッシュ + 不足トランザクションgetblocktxnで要求されたトランザクションを配信
addr / addrv2タイムスタンプ付きピアアドレスのリストネットワーク全体に既知のピアアドレスを伝播
ping / pongナンスレイテンシ測定と生存確認
feefilter最低手数料率(サトシ/kB)この手数料率を下回るトランザクションを中継しないようピアに通知
sendheaders空invではなくheadersメッセージで新規ブロックを告知するようピアに要求

サトシ時代とv27以降基準の比較。v0.1プロトコルは12種のメッセージ型を定義し、完全ブロックをすべてのピアに中継していた。現行のBitcoin Core(v27以降基準)は27種以上のメッセージ型に対応し、既定の中継方式としてコンパクトブロック (BIP 152) を使用する。メモリープールが重複する接続良好なノードでは、ブロック中継の帯域幅を約90% 削減する。

5. トランザクション中継

ノードがトランザクションをメモリープールに受理すると、ゴシップネットワークを通じてそのトランザクションをピアに告知する。

inv (txid)

inv (txid)

getdata

tx(完全

トランザクション)

検証 → メモリープール

inv (txid)

getdata

tx

ウォレットが

トランザクションを送信

ノード A:

検証 → メモリープールに受理

ノード B

ノード C

ノード D

中継プロセスは告知後要求パターンに従う:

  1. 告知。ノードがトランザクションのハッシュを含むinvメッセージを各ピアに送信する。
  2. 要求。このハッシュを見たことがないピアがgetdataで応答する。
  3. 配信。告知側のノードが完全なtxメッセージを送信する。
  4. 検証と伝播。受信側のピアがトランザクションを独立して検証する。有効であれば自身のメモリープールに受理し、そのピアに対して告知サイクルを繰り返す。

プライバシー保護型中継。ネットワーク観察者がトランザクションを発信元ノードまで追跡するのを防ぐため、Bitcoin Coreは各ピアへのトランザクション告知前にランダムな遅延を追加する(ポアソン分布タイマー)。各ピアはわずかに異なる時点で、場合によっては異なる先行中継者集合から告知を受け取るため、発信元の推定が困難になる。

手数料フィルター。feefilterメッセージ (BIP 133) により、ノードは自身の最低許容手数料率をピアに通知できる。ピアはその閾値を下回るトランザクションの告知を省略し、受信側ノードがどのみち拒否するトランザクションに帯域幅を浪費しなくなる。

孤児トランザクション。親トランザクションが不明な入力を参照するトランザクションは孤児と呼ばれる。ノードは孤児を限定的なキャッシュに保持する。親トランザクションが後から到着すれば、孤児は再評価される。キャッシュが満杯になると、無作為に選ばれた孤児が退去される。このメカニズムは順序外で到着するトランザクションに対応しつつ、無効な孤児の大量送信によるメモリー枯渇を防止する。

6. ブロック伝播

ブロック伝播はネットワーク内で最もレイテンシに敏感な操作である。伝播が遅いと失効ブロック率が上昇し、接続状態の良いマイナーに有利になり、マイニング競争の公平性を損なう。

伝播モード

コンパクトブロック (BIP 152, v0.13 以降)

あり

なし

マイナーが

ブロック発見

cmpctblock

(ヘッダー + 短縮 tx ID)

約 20 kB

ピアがメモリープール

からブロック再構築

全 tx

あり?

ブロックを検証

getblocktxn

(不足分を要求)

blocktxn

(不足 tx のみ)

ヘッダー先行同期 (v0.10 以降)

ノードが IBD 開始

getheaders

(ヘッダーチェーンを

要求)

headers

(最大 2,000 ヘッダー)

ヘッダーチェーン構築、

PoW を検証

getdata(

複数ピアから

並列ブロック要求)

チェーン順に

完全ブロック検証

従来: 完全ブロック中継 (v0.1)

マイナーが

ブロック発見

inv(

ブロックハッシュ)

を全ピアへ

ピア: getdata

block(完全直列化

ブロック)

大きさに かかわらず 全体

ピアが検証し

中継

モードブロックあたり帯域幅レイテンシ使用場面
従来の完全ブロック中継大きさにかかわらずブロック全体高い — 完全な直列化 + 転送サトシ時代 (v0.1)。フォールバックとして引き続き利用可能
ヘッダー先行同期ヘッダー: 各80バイト、ブロック: 完全サイズだが並列要求中程度 — 並列性が完全ブロックのサイズを補償初期ブロックダウンロード (IBD) — ジェネシスからチェーン先端までの同期
コンパクトブロック (BIP 152)標準的に約20 kB(ヘッダー + 短縮ID)。不足トランザクションはオンデマンド低い — 大半のトランザクションは既にメモリープール内同期済みノード間の定常的ブロック中継(v27以降の既定)

コンパクトブロックが約90% 節約を達成する仕組み。2つのピアのメモリープールが類似している場合(接続良好なノードでは一般的)、受信側はブロック内のトランザクションの大半を既に持っている。cmpctblockメッセージはブロックヘッダーと各トランザクションの6バイト短縮IDのみを送信する。受信側はこれらのIDをメモリープールと照合し、ローカルでブロックを再構築し、不足しているわずかなトランザクションのみを要求する。2,000件のトランザクションを含むブロックの場合、cmpctblockメッセージは1〜2 MBではなく約20 kBとなる。

高帯域幅モードと低帯域幅モード (BIP 152)。コンパクトブロックは2つのモードで動作する。高帯域幅モードでは、送信側ピアは検証完了と同時にcmpctblockをプッシュする。受信側がinv/getdataで要求するのを待たない。ノードは通常3つのピアを高帯域幅モードに指定し、新規ブロックの中継レイテンシを最小化する。低帯域幅モードでは、まずinvを送る標準的な告知後要求パターンを使用し、残りのピアとの間でレイテンシを帯域幅節約と引き換えにする。

7. トランスポート層: 平文と暗号化

サトシ時代の設計では、すべてのピアツーピア通信が平文で送信されていた。ISP、国家レベルの敵対者、ローカルネットワーク上の中間者など、あらゆるネットワーク観察者がすべてのメッセージを読み取り、ノードが中継しているトランザクションを特定し、ネットワークトポロジーをマッピングし、メッセージを選択的に遮断または遅延させることができた。

BIP 324 v2トランスポート(v26.0以降で対応、v27以降で既定有効)は、双方がこれに対応するピア間で日和見的な暗号化トランスポート層を導入する。これは暗号設計ページが示すビットコインの本来暗号化されない・認証専用の暗号モデルにおける唯一の例外であり、トランザクション層の基本要素ではなくネットワーク層の関心事であるため、そちらではなくここで扱う。

側面サトシ時代 (v0.1)v27以降基準 (BIP 324)
トランスポート平文TCP日和見的暗号化トランスポート(v2プロトコル)
機密性なし — すべてのメッセージが任意のネットワーク観察者に可読メッセージをChaCha20-Poly1305で暗号化。観察者には内容が不透明
認証なし任意のセッションID比較により手動ピア認証が可能。中間者攻撃に対抗
パケット構造平文のコマンド名を含む固定長ヘッダー。v0.1は20バイトで、2010年にチェックサムが加わり24バイト可変長暗号化パケット。コマンドIDは1バイト(外部から読み取り不能)
検出可能性ネットワークマジックバイトによりビットコイン通信として容易に識別可能ランダムバイトに見えるよう設計。トラフィック分析分類に抵抗
後方互換性該当なしノードは接続開始時にv2を交渉。ピアが非対応であればv1(平文)にフォールバック

暗号化トランスポートが重要な理由。平文通信は、ビットコインの設計が意図していない3つの能力をネットワーク層の敵対者に与える: (1) 監視。ISPがノードの中継するトランザクションを記録し、IPアドレスと関連付けられる。 (2) 標的型検閲。国家がプロトコルの特徴的なヘッダーをパターン照合してビットコイン通信を特定し遮断できる。 (3) 中間者操作。中間者がブロックやトランザクションを選択的に遅延させ、特定のマイナーを有利にしたり特定のノードを分断したりできる。暗号化トランスポートはこれらの脅威をすべて排除するわけではない(持続的な敵対者は依然として接続パターンを観察できる)が、そのコストを大幅に引き上げる。

8. 二時代比較

機能サトシ時代 (v0.1、2009年1月)現行Bitcoin Core、v27以降基準
ピア発見IRCチャネルブートストラップ + addrメッセージDNSシード + addr/addrv2中継 + peers.datキャッシュ
対応アドレス型IPv4のみIPv4、IPv6、Tor v3 (onion)、I2P、CJDNS (addrv2、BIP 155経由)
出方向接続入方向も含めた接続が15本になるまで、出方向の接続を開く。出方向8本の固定は2010年8月から8件の全中継 + 2件のブロック中継専用 + フィーラー + アンカー接続
入方向接続コード上の上限なし最大114(合計125)、多様性保持型退去アルゴリズム付き
メッセージ型12(version、addr、inv、getdata、getblocks、block、txを含む)27種以上
トランザクション中継invのあとgetdataに応えてtx、遅延なしポアソンタイマー遅延付き告知後要求、wtxid中継、feefilter
ブロック中継全ピアへの完全ブロック送信コンパクトブロック (BIP 152)。高帯域幅モードと低帯域幅モード
初期同期逐次: 1ブロックずつダウンロードして検証ヘッダー先行: 全ヘッダーをダウンロード後、ブロックを並列要求
トランスポート平文TCP日和見的暗号化トランスポート (BIP 324、ChaCha20-Poly1305)
エクリプス耐性最小限 — 少数のピア集合、退去の多様性なし出方向ピアの回転、多様性退去、アンカー接続、ブロック中継専用ピア
プロトコルバージョニングバージョン1ハンドシェイク時にインクリメンタルにバージョンを交渉。サービスビットで機能を告知

9. 本ページの範囲

本ページはネットワーク層を独立して扱う。以下のトピックは本ページの範囲外であり、設計文書シリーズ内のそれぞれのドメインページで扱う:

  • トランザクション検証とUTXOモデル: トランザクションがメモリープールに入る前に何がそれを有効にするか。トランザクション設計ページで扱う。
  • ブロック検証と合意規則: ネットワークから受信したすべてのブロックにノードが適用する決定論的検査。合意形成設計ページで扱う。
  • ブロック構造とマークルツリー: トランザクションがブロックヘッダー内でどのようにコミットされるか。ブロック・チェーン設計ページで扱う。
  • マイニングとプルーフ・オブ・ワーク: ブロックテンプレート構築、ハッシュパズル、プールプロトコル。
  • エクリプス攻撃とシビル攻撃の経済学: ネットワーク層攻撃の完全な脅威モデル。L2セキュリティモデル深掘りに委ねる。
  • メモリープールポリシーの詳細: パッケージ中継、手数料引上げによる置換の仕組み、手数料率バケット推定。
  • ストレージ: ブロックが検証を通過してローカルノードに到達した後に何が起きるか。ブロックファイル、UTXOデータベース、剪定。ストレージ設計ページで扱う。

参照元の外部ソース

https://bitcoin.org/bitcoin.pdf