レッスン2 — Ethereum の PoS(Casper FFG + LMD-GHOST)
問い
Ethereum は 1 つの コンセンサスプロトコルを走らせているわけではない。2 つを重ねて 走らせている。なぜ 2 つなのか? 100 万バリデータでネットワークを溶かさずに BFT 系の即時 finality を得るのは不可能 — かといって「何も最終に確定しない」chain も出荷できない。ハイブリッドはその妥協点。両者の境界はどこか?
原理(最小モデル)
- 2 プロトコルの役割分担。 LMD-GHOST = fork choice(毎 slot、確率的 head)、Casper FFG = finality gadget(毎 epoch、確定 checkpoint)。
- LMD-GHOST = Latest Message Driven, Greedy Heaviest Observed Sub-Tree. 各バリデータの 最新の attestation だけを stake 加重で数え、最大重量の subtree を選ぶ。直系の子ではなく subtree 全体を数える(GHOST 部分)。
- Casper FFG = 2 epoch 連続 justify で finalize. 32 slot ごとに checkpoint。stake の 2/3+ が justify、次の checkpoint も justified になった時点で finalize。最短 2 epoch = 12.8 分。
- Slashing = 暗号的に検出可能. Double vote / surround vote の 2 違反。署名 2 つあれば誰でも proof を提出できる。最低 1 ETH、相関 slashing で最大 full stake(32 ETH)。
- Engine API が EL と CL を繋ぐ.
engine_forkchoiceUpdated/engine_getPayload/engine_newPayloadの 3 メソッド。
具体例
CL ↔ EL のハンドシェイク:
sequenceDiagram
participant CL as Consensus Client (Lighthouse)
participant EL as Execution Client (Reth)
Note over CL: Slot N — 自分が proposer
CL->>EL: engine_forkchoiceUpdated(head, finalized, safe)
CL->>EL: engine_getPayloadV4(payloadId)
EL-->>CL: ExecutionPayload (構築済ブロック)
Note over CL: ブロックに署名 + ブロードキャスト
CL->>EL: engine_newPayloadV4(payload)
EL-->>CL: PayloadStatus { VALID }
Fork choice の例:
Block A (slot N で提案)
├── Block B (slot N+1) ← subtree で attestation 60%
│ └── Block D (slot N+2)
└── Block C (slot N+1、対立 fork) ← attestation 40%
LMD-GHOST は B を canonical として選ぶ。C は orphan。
失敗例(誤解)
「LMD-GHOST は要するに longest-chain」— 間違い。LMD-GHOST は stake 加重の heaviest-subtree。heaviest-subtree が防ぐ攻撃: selfish mining。longest-chain では 30% のハッシュパワーを持つマイナーが秘密裏に chain を作って後から公開し、他者を orphan にできる。heaviest-subtree は stake 加重の attestation を強制し、これをずっと困難にする。
「Ethereum は BFT」— 半分正しく、半分間違い。Ethereum は finalized ブロックには BFT だが unfinalized ブロックには Nakamoto 風。この区別は consensus-critical。
🛑 予測。 Ethereum の slot time 12 秒、epoch 32 slot。finality は最短 ~2 epoch。実時間を計算する。なぜ毎 slot finalize しないのか?(答え: 12s × 32 × 2 = 12.8 分。毎 slot finalize すると 100 万バリデータが毎 12 秒に全員投票することになり、ネットワーク帯域とコンセンサスメッセージ量が爆発する。epoch 単位に集約することでスケールと finality を両立。)
ステップで組み立てる
Step 1: 2 プロトコルの周期と出力を覚える
| プロトコル | 役割 | 周期 | 出力 |
|---|---|---|---|
| LMD-GHOST | Fork choice | 毎 slot(12s) | 確率的 head |
| Casper FFG | Finality gadget | 毎 epoch(~6.4 分) | 確定 checkpoint |
Step 2: Slashing 2 違反を 1 文で
- Double voting: 同じ epoch で異なる checkpoint に 2 票署名
- Surround voting: 票 A の後に A を surround する票 B を署名
どちらも暗号的に証明可能 = oracle 不要 = パーミッションレス検出。
Step 3: Engine API の 3 メソッドを役割で覚える
engine_forkchoiceUpdated→ 「chain head は X、X の上にブロックを準備せよ」engine_getPayload→ 「準備したブロックを渡せ」engine_newPayload→ 「他の proposer から受け取ったブロックを検証せよ」
Step 4: 自分の L1 への含意
- おそらく Ethereum の CL は走らせない(独自 validator set、異なる slot time)
- おそらく Reth 互換の Engine API は使う(別の CL を差し替えられる)
- 絶対に slashing の意味論は必要(validator set サイズに合わせてカスタマイズ)
答え合わせ
- Double vote のスラッシング額: 最低 1 ETH(単独)、最大 full 32 ETH(相関、攻撃時)。「相関 slashing」が同時 slash されたバリデータ数に比例して罰則を上げる。
- finality 13 分のトレードオフ: スケールでのバリデータ分散化(100 万バリデータ規模)を 1 秒 BFT finality と引き換えに得ている。
- Solana の別系統との対比: Tower BFT + PoH は検証可能クロックにアンカーされた投票で ~400ms finality を達成、代わりにバリデータハードウェア要求が高い + 単一リーダー(スロットごとの委員会なし)。Gasper はスケールのために、Tower BFT はサブ秒 finality のためにそれぞれ別の犠牲を払う。
合格基準
- LMD-GHOST と Casper FFG の周期・出力を即答できる。
- Engine API 3 メソッドを役割で言える。
- 「Ethereum の finality 13 分はバグではなく分散化トレードオフ」を 2 文で説明できる。
- slashing 2 違反を絵で書ける。
まとめ(3行)
- Ethereum = LMD-GHOST(毎 slot fork choice)+ Casper FFG(毎 epoch finality)の 2 層構造。
- Slashing 2 違反(double vote / surround vote)は暗号的に検出可能、相関罰則で協調攻撃を経済的に潰す。
- Engine API(forkchoiceUpdated / getPayload / newPayload)が EL ↔ CL の唯一の接続点 — Reth は EL 側を実装する。