Internet Computer の新しい P2P 層がステート同期に QUIC を導入(日本語訳)

tokuryoo
DfinityJP
Published in
13 min readSep 26, 2023

DFINITY 公式の記事 New P2P layer of the Internet Computer introduces QUIC for State Sync (2023/9/7) の日本語訳です。

これまで、Internet Computer 上のステートの同期は、TCP 上で動作するレガシー P2P 層を使用していました。新しい P2P 層はステートの同期用に調整され、QUIC トランスポートプロトコルを使用することで、よりシンプルでパフォーマンスとセキュリティがより高くなり、将来の進化に対応できるようになっています。

著者:Yotam Harchol

はじめに

Internet Computer のブロックチェーンは、各サブネットのノード間でメッセージを配布するピアツーピア(P2P)プロトコルに依存しています。これらのメッセージは Internet Computer プロトコルのクライアントによって生成されます。これらのクライアントはそれぞれ、Internet Computer Cコンセンサスプロトコル や ステート同期プロトコルなどの上位レイヤーのプロトコルを実装しています。詳しくは後述します。

基本的に、各クライアントの要件と動作は大きく異なります。これまでは、単一の P2P コンポーネントが、すべてのプロトコルクライアントによって、すべてのサブネット内通信に使用されていました。このアプローチは、複雑なコードと最適とは言えないパフォーマンスをもたらし、実装に変更を加えることを難しくしていました。

ステートの同期のための新しい P2P 層は、様々なクライアントの P2P 通信を切り離し、コードを簡素化し、Internet Computer のための新機能と改良されたネットワーキングを導入することを可能にします。この一部は、現在使用されている TCP に代わる QUIC トランスポートプロトコルを採用することで実現されています。QUIC は、Internet Computer のセッティングにおいて、TCP よりも多くの利点があります。何よりもまず、複数のストリームを多重化できることです。

このブログ投稿の時点で、NNS(Internet Computer を管理するDAO)は、コミュニティが提案した8個のサブネット用のレプリカバージョン cabe2ae3 の採用に対応するため、ステート同期のための新しい P2P 層の展開をすでに開始しています。これは、新しい QUIC トランスポートが Internet Computer のすべてのサブネットでアクティブになったことを意味します。しかし、ステートの同期は新しい P2P 層を、今のところ、より小さなサブネットのセットでのみ使用しています。しかしながら、新しい P2P 層を用いたステート同期は、現段階ではサブネットの一部でのみ使用されています。

この記事では、技術的な変更について詳しく説明し、Internet Computer のための新しく改善されたP2Pレイヤーを作成するために、どのように QUIC の新機能が活用されているかを説明します。

Internet Computer のピアツーピアプロトコル

Internet Computer のピアツーピア(P2P)層は、ノードのサブネット内でのメッセージ配信を担当します。各サブネットは個別のピアツーピアネットワークを運用しており、各サブネット内のノードはこのネットワークを使用してメッセージを互いに送信します。

この層の上には、P2P 層を使用してピア間でメッセージを交換する複数のコンポーネントがあり、最も有名なものは Internet Computer Consensus プロトコルです。ステート同期プロトコルを含む他のコンポーネントも、同じサブネット上のピアとメッセージを交換するために P2P 層を使用します。

Internet Computer のステート同期プロトコル

図1:Internet Computer のステート同期プロトコル。

非常に高いレベルでは、Internet Computer のステート同期プロトコルは、例えば遅れをとった複数のノードが、それぞれのサブネットのブロックチェーンのすべてのブロックを(再)実行することなく、サブネットの複製されたステートを同期することを可能にします。代わりに、このステート同期プロトコルを使って、必要なステートを即座にダウンロードし、サブネットのチェーンキーと照らし合わせてその真正性を検証できるのです。

ステート同期プロトコルは下記のように動作します: 最新のノードは、数百ラウンド(通常は500ラウンド)ごとにいわゆるチェックポイントを作成します。これには、複製されたステートをディスクに書き込み、このステートのハッシュを計算し、いわゆるキャッチアップパッケージ(CUP)にハッシュを含めることでこのステートに合意しようとするコンセンサスが含まれます。ハッシュは、同じハッシュを持つ2つの異なるステートを作成することが不可能な方法で計算されます。つまり、特定の高さについて合意された CUP が存在するということは、(1)ノードの大多数が特定の高さのステートに合意し、(2)ノードの大多数がステート同期の一部としてこのステートを実際に提供できることを意味します。

下記のプロセスを図1に示します。ノードは定期的に、同じサブネット上のピアに対して、ローカルで利用可能なすべてのステートのバージョンを宣伝(原文 advertise)します(宣伝 と呼ばれます)。このバージョンは基本的に、ステートが対応するブロックの高さと、このステートのハッシュです。ノードが自分のローカルのステートよりも新しい CUP を見た場合、そのノードは遅れを取ったと結論付けることができ、次にこのステートのアドバタイズを見たときに、この CUP に対応するステートをピアに要求できます。また、このプロトコルは、ノードが利用可能なステートの未変更部分が再ダウンロードされることなく、ノードが直接使用できることを保証します。ステートはファイルツリーとして見ることができ、各ファイルは順にチャンクに分割されます。再開するノードは多くのチャンクをすでに持っている可能性がありますが、すべてのチャンクを持っているわけではありません。ノードは、BitTorrent と同様に、複数のピアからチャンクを同時にリクエストできます。

再開ノードは、ステートの同期のきっかけとなった広告を送信したピアから、マニフェストと呼ばれる特別なチャンクを要求することから始めます。このマニフェストには、このステートに対応するすべてのファイルとチャンクのリストが含まれています。各ファイルと各チャンクには、ハッシュといくつかのメタデータも含まれています。Torrent ファイルと同様に、マニフェストにはピア情報は含まれず、そのコンテンツは特定のピアに依存しません。マニフェストのハッシュは、CUP に含まれているハッシュです。マニフェストのハッシュが CUP に含まれているハッシュに対して検証されると、マニフェスト内のファイルおよびチャンクのハッシュは本物であると結論付けることができ、ファイルおよびチャンクのハッシュをマニフェストに含まれるハッシュと比較することで、ファイルおよびチャンクの検証に使用できます。このメカニズムにより、ノードがお互いを騙して偽のステートチャンクをダウンロードして使用できないようにします。

マニフェストのダウンロード後、再開ノードはどのチャンクが欠けているかを正確に把握します。そして、他のピア(同じステートを宣伝したすべてのピア)に対して複数の同時ダウンロード要求をきっかけとして、欠落しているチャンクをできるだけ早くフェッチできます。

QUICを使用してステート同期の P2P を簡素化

図2:ステート同期のための新しいP2Pレイヤーの設計

これまでのところ、ステート同期プロトコルは、Internet Computer の既存の P2P 層を使用してきました。前述のように、この P2P 層は複数のクライアントからのメッセージを多重化し、同じサブネット上のピア間で拡散します。しかし、この P2P 層は比較的小さなメッセージの配信を想定して設計されており、多くのクライアントが必要としているメッセージの配信には適しているが、ステート同期プロトコルには適していません。そのため、これまでは、すべてのクライアントの問題を解決しようとする単一のモノリシックな P2P プロトコルを用いていました。しかし、これではコードが必要以上に複雑になり、改良も難しくなります。

このような理由から、P2P 層を2つに分けることは非常に理にかなっています。1つはステート同期用で、もう1つは残りの(既存の)クライアント用です。他のクライアントのために P2P 層を簡素化し、強化する我々の継続的な努力と合わせて、これはよりシンプルで、より高性能で、よりセキュアな新しい P2P レイヤーを形成するでしょう。

図2に示すステート同期用の新しい P2P 層は、ステート同期プロトコルは変更せず、その下のネットワーキングレイヤーのみを変更し、新しいトランスポートコンポーネントを使用します。トランスポートコンポーネントとは、P2P がピア間の接続を作成・維持するために使用されるコンポーネントです。ステート同期のための新しい P2P 層のために、2つの非同期 API 関数をサポートする新しいトランスポートコンポーネントを作成しました:

  • push(message, peer_id)
  • rpc(message, peer_id) -> response

トランスポートは単一のストリームで TCP を使用していたため、トランスポートでステートを保持し、リクエストとレスポンスを追跡しなければ、リクエストとレスポンスを関連付けることは不可能でした。新しいトランスポートコンポーネントは QUIC [IETFドラフトへのリンク] トランスポートプロトコルを使います。QUIC はユーザー空間の UDP の上に実装された最新のトランスポートプロトコルです。TCP に比べて多くの利点がありますが、我々のケースで最も重要なのは、1つの接続で複数のストリームを多重化できることです。他のいくつかのブロックチェーンはすでに QUIC を使用しています。

この新しいトランスポートコンポーネント上で、2つの新しい P2P コンポーネントが実行されます。1つはステート同期用で、もう1つは他のクライアント用です(下記参照)。ステート同期用の新しい P2P コンポーネントは、以下のように新しいトランスポート層を使用します。定期的に、現在のステートで push() を呼び出し、すべてのピアに宣伝します。このような宣伝を受信したとき、ノードは遅れていることに気づくと、rpc() コールを使ってピアに特定のチャンクを要求します。

図3:QUIC 接続での多重化

QUIC に切り替えるメリット

QUIC ストリーム多重化により、P2P 層のコードを完全に非同期に変えることができ、利用可能な CPU と帯域幅リソースをより有効に活用できます。また、リクエスト処理におけるヘッドオブラインのブロッキングを回避し、コードの信頼性を改善できます。

QUIC を使用するもう一つの利点は、コネクションのマルチストリーム構造により、アプリケーション層でステートを維持しなくても、すべてのレスポンスが対応するリクエストに結び付けられることです。

新しいトランスポートを他のクライアントに使用する

上述したように、我々は他のクライアントが使用する P2P 層の刷新にも取り組んでいます。私たちの計画では、新しいトランスポートコンポーネントを使用し、最終的にはすべてのクライアントからのメッセージを同じ QUIC コネクションで多重化し、TCP トランスポートを廃止する予定です。QUIC を使うことで、様々なクライアントのトラフィックを動的に優先させることができます。たとえば、ステート同期は帯域幅を大量に消費するため、他のクライアントよりも優先して、できるだけ早く終了させたい場合があります。しかし、同じサブネット上の多くのノードがステート同期を行っている場合、ステート同期よりもコンセンサスプロトコルが優先されるようにすることもできます。そうしないと、十分な速さで進まないかもしれません。

現在実装中のコンセンサス用 P2P 層の刷新により、P2P 層とコンセンサス層のスケーラビリティ、パフォーマンス、信頼性など、いくつかの面で既存の P2P 層が大幅に改善されます。このトピックについては、近日中に詳細をお伝えする予定です。

ステート同期プロトコルを改善する方法

この P2P 層の変更により、ステート同期プロトコルの新機能に対応するための拡張が容易になります。そのような機能の1つは、ノードがステート全体を持っていないピアからチャンクをダウンロードする機能です。これにより、特に同じサブネット内の複数のノードがステートを同期する必要がある場合に、プロトコルのパフォーマンスが大幅に向上します。

PODC 2022 の Internet Computer Consensus プロトコルに関する論文を読んでください。

Internet Computer についてもっと知る:internetcomputer.org
ツイッターで技術をフォローする:
@DFINITYDev

Internet Computer で開発を始める:

--

--