分散合意(コンセンサス):管理者なしで「同じ事実」に合意する
P2Pネットワークが単なるデータ配布を超えて「台帳」や「状態」を共有しようとすると、全員が同じ内容に合意する仕組み、つまり分散合意アルゴリズムが必要になります。PoW、PoS、PBFT、HotStuffという代表的な4方式を解説します。
なぜ分散合意は難しいのか
中央サーバーがあれば「正しいデータ」はサーバーが決めれば済みます。しかし対等なピアの集まりでは、通信の遅延や欠落、ノードの故障、さらには嘘をつくノードの存在まで想定しなければなりません。この難しさは、いくつかの有名な理論で定式化されています。
- ビザンチン将軍問題: 離れた場所に陣取る将軍たちは、伝令だけで「一斉攻撃か撤退か」を揃えなければなりません。しかし伝令は失われるかもしれず、裏切り者の将軍は各所に矛盾した内容を伝えるかもしれません。これは、故障だけでなく「悪意ある参加者」がいる環境での合意の難しさを示す思考実験です。矛盾した振る舞いをする故障をビザンチン障害と呼びます。
- CAP定理: 分散システムは、一貫性(Consistency)・可用性(Availability)・分断耐性(Partition tolerance)の3つを同時には満たせない、という原理。ネットワーク分断は避けられないため、実際の設計は「分断時に一貫性と可用性のどちらを優先するか」の選択になります。
- FLP不可能性: 非同期ネットワーク(メッセージ到着時間に保証がない環境)では、たった1台の故障の可能性があるだけで、決定論的に必ず合意へ到達するアルゴリズムは存在しない、という1985年の定理。実用システムはタイムアウトや乱択、経済的インセンティブを導入してこの壁を回避しています。
つまり分散合意アルゴリズムとは、これらの理論的制約の中で「現実的な仮定を置いて、実用上十分な合意を実現する」工夫の体系です。大きく分けて、参加自由(パーミッションレス)な環境向けのナカモト型(PoW/PoS)と、参加者が既知(パーミッションド)な環境向けのBFT型(PBFT/HotStuff)の2系統があります。
障害モデルで整理する:クラッシュ耐性系とビザンチン耐性系
合意アルゴリズムを理解する最短ルートは、「どんな故障を想定するか(障害モデル)」で分類することです。クラッシュ障害は「ノードが黙って止まる」だけの故障で、嘘はつきません。データセンター内のデータベースのように、参加者が自組織の管理下にある環境ではこの想定で十分であり、PaxosやRaftが活躍します。一方ビザンチン障害は「止まるどころか嘘をつく・矛盾したことを言う」任意の故障で、参加者を信頼できない環境ではこちらを想定する必要があり、PBFTやHotStuff、さらに参加自由な環境ではPoW/PoSが対応します。
必要なノード数にも本質的な差があります。クラッシュ耐性ならf台の故障に2f+1台(過半数クォーラム)で足りますが、ビザンチン耐性は嘘つきを票決で炙り出すために3f+1台が必要です。以下、Proof系 → クラッシュ耐性系 → ビザンチン耐性系の順に見ていきます。
参加モデルで整理する:信頼できるノードの合意と、信頼できないノードの合意
ここまでの整理は「障害モデル」(クラッシュ障害だけを想定するか、嘘をつくビザンチン障害まで想定するか)が軸でしたが、実はもう一つ独立した軸、参加モデル(メンバーの顔ぶれが既知で固定されているか、誰でも自由に出入りできるか)を掛け合わせて初めて、なぜ6つの方式がそれぞれの形になったのかが見えてきます。
信頼できるノードの合意(既知メンバー×クラッシュ耐性のみ): 自社のデータセンターやKubernetesクラスタのように、ノードは自分たちが構築・監視しており、ハードウェア故障やネットワーク分断で黙って止まることはあっても、意図的に嘘のメッセージを送ってくることはないと仮定してよい環境です。この「信頼できるが完璧ではない」ノード像にはPaxosやRaftが最適で、必要な冗長性もf台の故障に2f+1台で足り、暗号署名なしの軽い通信で済みます。
信頼できないが身元は分かっているノードの合意(既知メンバー×ビザンチン耐性): コンソーシアムチェーンや金融機関間の決済網のように、参加者の組織や身元は登録・審査によって既知でも、運用者が買収されたりシステムが侵害されたりする可能性までは排除できない環境です。ここでは「身元は分かっているが挙動までは信頼できない」ノードを想定し、PBFTやHotStuff、さらにステーク量で参加者の顔ぶれを決めるTendermintのような合意が使われます。ビザンチン耐性には3f+1台が必要になり、署名や複数ラウンドの投票という重い仕組みが要求される代わりに、参加者を限定できるからこそ実用的な速度を出せます。
身元さえ分からないノードの合意(自由参加×ビザンチン耐性): 公開ブロックチェーンのように、誰が何台のノードで参加しているかを誰も把握できない環境です。身元で信頼を担保できない以上、正直な参加者が多数派であることを、計算資源(PoW)や経済的資産(PoS)という「不正に使うと自分が損をする」外部コストで裏付けます。参加自由度と引き換えに、確率的ファイナリティやスラッシングといった、既知メンバー環境にはない仕組みが必要になります。
残る「自由参加×クラッシュ耐性のみ」という組み合わせは、実用上ほとんど存在しません。誰でも自由に参加できるのに、参加者全員が嘘をつかないと仮定するのは無防備すぎるからです。身元確認のコストを払わないなら振る舞いの正直さも保証できません。これが、公開ネットワークの合意が例外なくビザンチン耐性を要求する理由です。
| 参加モデル | 想定する障害 | 該当方式 | 典型的な環境 |
|---|---|---|---|
| 既知・固定(パーミッションド) | クラッシュのみ | Paxos、Raft | 自社データセンター、単一組織のクラスタ |
| 既知・固定(パーミッションド) | ビザンチン | PBFT、HotStuff、Tendermint | コンソーシアムチェーン、金融機関間の決済網 |
| 自由参加(パーミッションレス) | ビザンチン | PoW、PoS | パブリックブロックチェーン |
| 自由参加(パーミッションレス) | クラッシュのみ | (実用例なし) | 身元確認なしに正直さは仮定できない |
この整理から、PoSの立ち位置がより明確になります。PoSが担っているのは「身元の代わりにステークで参加資格を発行する」という自由参加層の工夫にすぎません。いったんステークによってバリデータ集合が確定すれば、その集合内部の合意はしばしば「既知メンバーによるビザンチン耐性合意」、つまりPBFTやHotStuffの領域に戻ってきます。次節で具体例を見ていきましょう。
Proof系:参加自由なネットワークの合意(PoW / PoS)
PoW(Proof of Work):計算量で「正しさ」を裏付ける
Bitcoinが採用するProof of Work(作業証明)は、「次のブロックを追加する権利」を計算競争で決めます。マイナー(採掘者)は、ブロックのハッシュ値が特定の条件(先頭に一定数のゼロが並ぶなど)を満たすような使い捨ての数値(ノンス)を、ひたすら総当たりで探します。条件を満たすハッシュを最初に見つけたマイナーがブロックを提案し、報酬を受け取ります。
重要なのは、答えを見つけるのは大変でも検証は一瞬であることです。他のノードはハッシュを1回計算するだけで、そのブロックに膨大な計算が投入されたことを確認できます。チェーンが分岐した場合は「最も多くの累積計算量が投入されたチェーンを正とする」というものです。この単純なルールがナカモトコンセンサスであり、参加者が誰でも・何人でもよいオープンな環境で初めて実用的な合意を成立させました。
- 51%攻撃: 全体の過半数の計算力を握った攻撃者は、取引の取り消し(二重支払い)や特定取引の排除が可能になります。逆に言えば、過半数の計算力を集めるコストが安全性の根拠です。小規模チェーンでは実際に51%攻撃の被害が発生しています。
- 確率的ファイナリティ: ブロックは「後ろに積まれるほど覆りにくくなる」だけで、数学的に確定する瞬間はありません。Bitcoinで「6承認を待つ」慣習はこのためです。
- 電力問題: 安全性が計算量に比例する構造上、大量の電力消費が避けられません。この環境負荷への批判が、次に述べるPoSへの移行を後押ししました。
PoS(Proof of Stake):資産の預け入れで「正しさ」を裏付ける
Proof of Stake(出資証明)は、計算競争の代わりに「通貨の預け入れ(ステーク)」で参加資格を担保します。バリデータ(検証者)は一定量の通貨をロックして登録し、プロトコルがステーク量などに応じてブロック提案者を選出します。他のバリデータは提案ブロックに投票(アテステーション)し、規定の賛成が集まればブロックが確定していきます。
不正の抑止力はスラッシングです。二重に矛盾するブロックへ署名するなどの違反が検出されると、預けたステークの一部または全部が没収されます。PoWの「攻撃には電気代がかかる」に対し、PoSは「攻撃すると自分の資産が焼かれる」という経済的ペナルティで安全性を作ります。
- Nothing at Stake問題: 初期のPoS設計への古典的批判。チェーンが分岐したとき、投票にコストがかからないなら「全部の分岐に賭けておく」のが合理的になり、合意が収束しない恐れがあります。スラッシングはまさにこの対策で、矛盾した投票そのものを罰します。
- Ethereumの移行(The Merge): 2022年9月、EthereumはPoWからPoSへ稼働したまま移行し、消費電力を99.9%以上削減しました。現在は32 ETHをステークしたバリデータ群がブロックを提案・承認し、一定条件で「確定(ファイナライズ)」する明示的なファイナリティも導入されています。
- 課題: 大口保有者への権力集中、ステーキングプールによる事実上の中央集権化、長期レンジ攻撃への対策(弱い主観性)など、PoS固有の論点も活発に研究されています。
クラッシュ耐性系:味方だけの世界の合意(Paxos / Raft)
Paxos:クラッシュ耐性合意の古典
レスリー・ランポートが提案したPaxosは、クラッシュ障害モデルにおける合意の理論的基礎です。核心のアイデアは多数決クォーラム、すなわち「どの2つの多数派も必ず1台は共有する」という性質であり、これにより過去に決まった値が後から覆らないことを保証します。役割は3つ:値を提案するProposer、投票して値を受理するAcceptor、決定を学ぶLearner(実装では1ノードが兼任するのが普通です)。
合意は2フェーズで進みます。まずPrepare/Promise:Proposerが単調増加する提案番号nを添えてPrepareを送り、Acceptorの過半数から「n未満の提案はもう受理しない」という約束(Promise)と、受理済みの値があればその情報を集めます。次にAccept/Accepted:Proposerは「Promiseの中に受理済みの値があればその値、なければ自分の値」をAcceptとして送り、過半数が受理(Accepted)した時点で値が確定します。受理済みの値を引き継ぐこのルールこそが、「一度決まった値は二度と変わらない」安全性の源です。
- 難しさの正体: アルゴリズム自体は短いのに、複数Proposerの衝突(ライブロック)、故障からの回復、状態の永続化など「現実に動かすための周辺」が論文に書かれておらず、実装者ごとに解釈が分かれたことが「Paxosは難しい」と言われる主因です。
- Multi-Paxos: 値を1つ決める基本Paxosを連続適用し、安定したリーダーを立ててPrepareフェーズを省略することで、実用的なログ複製システムになります。
- 採用例: GoogleのロックサービスChubby、そしてSpanner系の分散データベースがPaxosを基盤にしています。
Raft:「理解しやすさ」を設計目標にした合意
Raft(Ongaro & Ousterhout、2014年)は、「Paxosと同等の性能・安全性を、理解しやすい形で」を掲げて設計されました。問題をリーダー選出・ログ複製・安全性の3つに分解し、常に強いリーダーを1人置くことで思考を単純化します(原論文は参考文献のongaro2014search)。
- リーダー選出: 時間はterm(任期)という単調増加の番号で区切られます。フォロワーはリーダーからの心拍(ハートビート)がランダム化されたタイムアウト(例: 150〜300ms)内に届かないと候補者に転じ、termを進めて投票を募ります。過半数の票を得たノードが新リーダーになります。タイムアウトのランダム化により票割れが自然に解消されるのが巧妙な点です。
- ログ複製: クライアントの命令はリーダーのログに追記され、AppendEntries RPCで全フォロワーへ複製されます。過半数への複製が確認できたエントリをコミットとし、各ノードのステートマシンへ適用します。
- 安全性(Leader Completeness): 投票時に「自分よりログが古い候補者には投票しない」というルールにより、コミット済みエントリを持たないノードはリーダーになれません。これにより「コミットした命令が失われない」ことが保証されます。
理解しやすさは普及に直結しました。Kubernetesの心臓部であるetcd、NewSQLデータベースのTiDBやCockroachDB(参考文献のhuang2020tidb / taft2020cockroachdb)など、現代のインフラの至る所でRaftが動いています。
Raftのログ複製。リーダーがログを配り、過半数に届いた時点でコミットが確定する。
ビザンチン耐性系:裏切り者がいても壊れない合意(PBFT / HotStuff)
PBFT:許可型ネットワークの古典的BFT合意
PBFT(Practical Byzantine Fault Tolerance、1999年)は、参加者が既知の環境(コンソーシアムチェーンや金融システムなど)で使われるビザンチン耐性合意の古典です。n台のうち最大f台が任意の(悪意的な)故障をしても、n ≥ 3f+1であれば正しく合意できます。つまり4台なら1台、7台なら2台の裏切りに耐えられます。
合意は3つのフェーズで進みます。
- pre-prepare: リーダー(プライマリ)がクライアントの要求に順序番号を付け、全レプリカへ提案を配布します。
- prepare: 各レプリカは提案を検証し、「私はこの提案を受け入れる」というprepareメッセージを全ノードへ相互に送信します。2f+1件集まれば、十分な数の正直なノードが同じ提案を見ていることが確認できます。
- commit: さらに「確定してよい」というcommitメッセージを相互に交換し、2f+1件集まった時点で要求を実行し、クライアントへ応答します。クライアントはf+1件の一致した応答で結果を信頼できます。
ブロックが覆る可能性のあるナカモト型と違い、PBFTはコミットした瞬間に結果が確定する即時ファイナリティを持ちます。一方で、prepare/commitフェーズで全ノードが全ノードへメッセージを送るため通信量がO(n²)となり、数十〜百ノード程度が実用上の上限とされます。また、リーダーが故障した場合は「ビュー変更」という重いプロトコルで新リーダーを選び直す必要があります。
PBFTのメッセージフロー。prepare/commitでは全ノードが相互にメッセージを交換するため、通信量はO(n²)に膨らむ。
HotStuff:通信量O(n)を実現したモダンBFT
HotStuff(2019年)は、PBFTの通信量問題を解決したリーダーベースのBFT合意アルゴリズムです。最大の工夫は、レプリカ同士が相互にメッセージを送り合う代わりに、すべての投票をリーダーに集約すること。リーダーは2f+1票を集めると、それらを1つの「証明書(QC: Quorum Certificate)」にまとめて次のラウンドで全員に配ります。しきい値署名を使えば証明書は1つの署名に圧縮でき、1ラウンドあたりの通信量はO(n)で済みます。
もう一つの特徴が3チェーンルールです。ブロックはprepare→precommit→commitに相当する3世代のQCが連続して積み重なった時点で確定します。この設計により「合意の1フェーズ」と「リーダー交代」が同じ形の処理に統一され、リーダーをラウンドごとに交代させ続ける(ローテーション)ことが低コストで可能になりました。PBFTでは重い例外処理だったビュー変更が、HotStuffでは通常運転の一部になっています。
- Facebook(現Meta)のLibra/DiemプロジェクトがLibraBFTとして採用したことで広く知られるようになりました。
- 現在もAptosなどの高性能ブロックチェーンで、HotStuff系の合意(改良版含む)が中核に使われています。
- 「リーダー集約+しきい値署名+チェーン化」という設計は、その後のBFT研究(2ラウンド化、DAGベース合意など)の共通言語になりました。
PoSとBFT合意の接点:バリデータを選ぶ層と、票を合意に変える層
主要なPoSチェーンの内部を見ると、「誰が投票権を持つか」を決めるPoSの層と、「集まった票をどう最終合意に変えるか」を決めるBFT合意の層が、明確に分離して積み重なっていることが分かります。Tendermint、Diem/Aptos、Ethereumという3つの実例で、この積層構造を具体的に見ていきましょう。
Tendermint(Cosmos):PBFT系の3フェーズをステーク加重で回す
Tendermintは、propose → prevote → precommitという、PBFTのpre-prepare → prepare → commitとほぼ同型の3フェーズ構造を持つBFT合意です(参考文献のbuchman2018tendermint)。違いは、参加者が固定された既知メンバーではなくステーク量に応じてラウンドごとに回転するプロポーザである点、そして「2f+1ノード」ではなく「2/3以上のステーク」がクォーラムの基準になる点です。PoSはここで「誰が提案者か」「1票の重みはいくつか」を決める入力に徹し、実際の合意ロジックはPBFTに極めて近い設計を使っています。O(n²)通信という弱点も引き継いでおり、Cosmosエコシステムではバリデータ数をおおむね100〜150程度に抑えることで実用性を保っています。
Diem(Libra)/Aptos:HotStuffそのものをPoSバリデータ集合の上で走らせる
LibraBFT(現Diem)やAptosの合意層は、HotStuff論文(参考文献のyin2018hotstuff)をほぼそのまま実装に落とし込んだものです。バリデータ集合の構成員と投票権重はPoSのステーク量で決まり、その集合の中でHotStuffのリーダー集約・QC・3チェーンルールが動きます。PBFT系のTendermintがO(n²)通信のまま大規模化に苦労するのに対し、HotStuff系はO(n)通信のおかげでより大きなバリデータ集合でもスループットを保ちやすく、Aptosはこれを土台にDiemBFTv4(Jolteon)などさらに高速化した派生版を採用しています。
Ethereum:Casper FFGという「PBFT型ファイナリティ×ナカモト型フォーク選択」の二層構造
Ethereumは単純な「Tendermint型」でも「HotStuff型」でもなく、二層のハイブリッドです。直近ブロックの提案とチェーン先端の決定はLMD-GHOSTというナカモト型(最も重みのついた枝を選ぶ)フォーク選択ルールが担い、これだけなら確率的ファイナリティのままです。その上にCasper FFG(Finality Gadget)が被さり、エポック境界のチェックポイントに対してバリデータのステークの2/3超が2ラウンドの投票(justify → finalize)で賛成すると、そのチェックポイントは覆せない形で確定します。この2ラウンド・2/3スーパーマジョリティという構造はPBFTのprepare/commitと同じ発想であり、原論文(参考文献のbuterin2017casper)もビザンチン耐性合意の系譜を明示的に参照しています。
| チェーン | PoSが決めること | BFT合意の系統 | ファイナリティの粒度 |
|---|---|---|---|
| Tendermint / Cosmos | プロポーザ選出と投票権重 | PBFT系(3フェーズ・O(n²)) | ブロックごとに即時確定 |
| Diem・Aptos | バリデータ集合と投票権重 | HotStuff系(QC集約・O(n)) | ブロックごとに即時確定(3チェーン) |
| Ethereum | バリデータ集合と投票権重 | Casper FFG(PBFT型2/3投票)+LMD-GHOST | エポック単位で確定、直近ブロックは確率的 |
PoS = 誰が投票するか(Sybil耐性・投票権重)、PBFT/HotStuff = 集まった票をどう合意に変えるか(安全性・ファイナリティ)。現代の主要チェーンの多くは、この2つのレイヤーの組み合わせとして実装されています。冒頭の表で「Proof系」と「ビザンチン耐性系」が別グループに見えるのは障害モデル・参加モデルという分類軸のためであり、実装レベルでは両者が積み重なって共存していることを覚えておいてください。
6方式の比較
それぞれの方式は「誰が参加できるか」「どんな故障を想定するか」「何を担保にするか」が根本的に異なります。用途に応じた使い分けが重要です。
| 方式 | ファイナリティ | 耐障害モデル | スケーラビリティ | 代表例 |
|---|---|---|---|---|
| PoW | 確率的(覆る可能性が漸減) | ビザンチン耐性(計算力の過半数が正直) | 参加ノード数は無制限/処理性能は低い | Bitcoin、初期Ethereum |
| PoS | 確率的+明示的ファイナリティ併用 | ビザンチン耐性(ステークの2/3以上が正直) | 参加は広く開放/PoWより高速 | Ethereum(Merge後)、Cardano |
| Paxos | 即時(過半数受理で確定) | クラッシュ障害のみ(n≥2f+1) | 数ノード〜十数ノードのクラスタ向け | Google Chubby、Spanner系 |
| Raft | 即時(過半数複製でコミット) | クラッシュ障害のみ(n≥2f+1) | 数ノード〜十数ノードのクラスタ向け | etcd(Kubernetes)、TiDB、CockroachDB |
| PBFT | 即時(コミットで確定) | ビザンチン耐性(n≥3f+1) | O(n²)通信のため数十ノード規模 | Hyperledger Fabric(初期)、Tendermint系の源流 |
| HotStuff | 即時(3チェーンで確定) | ビザンチン耐性(n≥3f+1) | O(n)通信で百ノード規模も可能 | Diem(LibraBFT)、Aptos |
関連する学術文献は参考文献ページにまとめています。