前回のEthereumエコシステムの全体像では、ユーザーからEVMに至るまでの縦のスタックを整理した。今回はその中の「ノード」にフォーカスし、ノード同士がどう通信してブロックを積み上げていくのかを追う。
全体の流れ
sequenceDiagram
actor User as ユーザー
participant RPC as RPCプロバイダ
participant Node as ノード
participant Mempool as メモリプール
participant Proposer as ブロック提案者
participant Committee as 検証委員会
participant Chain as ブロックチェーン
User->>RPC: 署名済みトランザクション
RPC->>Node: トランザクション転送
Node->>Mempool: トランザクションを保持
Node->>Node: P2Pでトランザクションを伝播
Note over Proposer, Chain: スロット開始(12秒ごと)
Proposer->>Mempool: トランザクションを選択
Proposer->>Proposer: ブロックを構築・実行
Proposer->>Committee: ブロックを提案
Committee->>Committee: ブロックを検証
Committee->>Proposer: アテステーション(投票)
Note over Proposer, Chain: 2/3以上の賛成で正当化
Proposer->>Chain: ブロック追加
Chain->>Chain: 2エポック後にファイナライズ
トランザクションの伝播
ユーザーが署名したトランザクションは、RPCプロバイダを経由してノードに届く。ノードはそれを**メモリプール(mempool)**に保持するとともに、P2P(ピアツーピア)ネットワークを通じて他のノードに伝播する。
graph TB
TX[新しいトランザクション]
N1[ノードA]
N2[ノードB]
N3[ノードC]
N4[ノードD]
N5[ノードE]
TX --> N1
N1 -->|gossip| N2
N1 -->|gossip| N3
N2 -->|gossip| N4
N3 -->|gossip| N5
N4 -->|gossip| N5
この伝播はゴシッププロトコルで行われる。各ノードが知り合いのノードに情報を流し、それがさらに広がっていく。中央のサーバーが配信するのではなく、噂話のように伝わっていく仕組み。
すべてのノードがすべてのトランザクションを即座に受け取るわけではない。ネットワーク遅延やノード数により、伝播には数百ミリ秒〜数秒かかる。
スロットとエポック
EthereumのProof of Stakeでは、時間が一定の単位で区切られている。
| 単位 | 長さ | 役割 |
|---|---|---|
| スロット | 12秒 | 1ブロックが提案される単位 |
| エポック | 32スロット(6.4分) | バリデータのシャッフルとファイナリティの単位 |
12秒ごとに1つのスロットが訪れ、そのスロットに割り当てられたバリデータがブロックを提案する。
バリデータの役割
Ethereumに32 ETHをステーキングすると、バリデータとしてネットワークに参加できる。バリデータには各スロットで2つの役割がランダムに割り当てられる。
ブロック提案者(Proposer)
スロットごとに1人だけ選ばれる。メモリプールからトランザクションを選んでブロックを構築し、ネットワークに提案する役割。
提案者の選出はランダムだが、ステーキング量に応じて選ばれる確率が上がる。どのバリデータが次の提案者になるかは事前に決まっているが、直前までは公開されない設計になっている(リーダー選出の秘匿化)。
検証委員会(Committee)
各スロットに割り当てられるバリデータのグループ。提案されたブロックを検証し、正しいと判断すれば**アテステーション(attestation)**と呼ばれる投票を送る。
委員会のメンバーはエポックごとにシャッフルされる。特定のバリデータが継続的に同じスロットを担当することはない。
ブロックの構築から確定まで
1. ブロック構築
提案者はメモリプールからトランザクションを選び、EVMで実行し、ブロックを構築する。どのトランザクションをどの順番で含めるかは提案者の裁量になる。
実際には、多くの提案者はMEV-Boostという仕組みを使い、ブロック構築を専門のビルダーに委託している。ビルダーがトランザクションの順序を最適化してブロックを構築し、提案者はその中から最も報酬の高いブロックを選んで提案する。この分離はProposer-Builder Separation(PBS)と呼ばれている。
2. ブロック提案
構築したブロックをP2Pネットワークに送信する。他のノードがこのブロックを受信し、検証を開始する。
3. アテステーション(検証投票)
検証委員会のメンバーが、提案されたブロックの内容を検証する。
- トランザクションの署名は正しいか
- ステート遷移は正しいか
- 前のブロックとの整合性はあるか
検証が通ればアテステーションを送信する。このアテステーションもP2Pで伝播される。
4. 正当化(Justification)
エポックの終わりに、そのエポック内のブロックに対するアテステーションが集計される。ステーキング総量の2/3以上がアテステーションを送っていれば、そのエポックのチェックポイントが「正当化(justified)」される。
5. ファイナライズ(Finality)
正当化されたチェックポイントの次のエポックも正当化されると、最初のチェックポイントがファイナライズされる。ファイナライズされたブロックは、事実上覆すことができない。
ファイナライズまでには通常2エポック(約12.8分)かかる。
graph LR
E1["エポック N<br/>正当化"]
E2["エポック N+1<br/>正当化"]
E3["エポック N+2"]
E1 -->|"2/3以上の投票"| E2
E2 -->|"2/3以上の投票"| E3
E2 -.->|"N がファイナライズ"| E1
不正への対処
スラッシング
バリデータが悪意のある行動を取った場合、ステーキングしたETHの一部が没収される。具体的には以下の行為が対象。
- 二重提案: 同じスロットで2つの異なるブロックを提案する
- 矛盾した投票: 互いに矛盾するアテステーションを送る
スラッシングされたバリデータはネットワークから強制的に退出させられる。これにより、不正行為に経済的なペナルティが課される。
インアクティビティリーク
バリデータが長期間オフラインになると、ステーキング報酬が徐々に減少する。ネットワーク全体でファイナリティが達成できないほどバリデータが離脱した場合、オフラインのバリデータのステーキングが加速度的に削られ、オンラインのバリデータが2/3を回復できるように調整される。
P2Pネットワークの構造
ノード間の通信にはdevp2pとlibp2pという2つのプロトコルスタックが使われている。
- devp2p: 実行クライアント(Geth等)間の通信。トランザクションの伝播やブロックの同期に使用
- libp2p: コンセンサスクライアント(Prysm等)間の通信。アテステーションやブロック提案の伝播に使用
各ノードは数十〜数百のピアと接続し、メッシュ状のネットワークを形成している。特定のノードがダウンしてもネットワーク全体は影響を受けない。
まとめ
ブロックが積まれるまでの流れを整理するとこうなる。
- トランザクションがゴシッププロトコルでネットワーク全体に伝播する
- 12秒ごとのスロットで、ランダムに選ばれた提案者がブロックを構築・提案する
- 検証委員会がブロックを検証し、アテステーションを送る
- ステーキング総量の2/3以上の賛成が集まるとチェックポイントが正当化される
- 連続する正当化によりファイナリティが確定する
すべてが経済的インセンティブで動いている。正しく振る舞えば報酬を得られ、不正を働けばステーキングを失う。中央の管理者ではなく、経済合理性によって正直な行動が促される設計になっている。