セキュアなスケーラビリティ: Internet Computer のピアツーピア層

tokuryoo
DfinityJP
Published in
19 min readJan 30, 2022

--

Medium の DFINITY 公式の記事 Secure Scalability: The Internet Computer’s Peer-to-Peer Layer (2021/10/21) の日本語訳です。

ピアツーピア層は、Internet Computer 上のサブネットのノード間において、セキュアで、信頼性のある、スケーラブルな通信を可能にします。

By Yotam Harchol, Research Scientist (Networking) | DFINITY

Internet Computer ブロックチェーンは、開発者が キャニスタースマートコントラクトを利用して消費者向けのDappsを完全にオンチェーンで構築することを可能にし、Webサービス、DeFiプラットフォーム、ソーシャルメディア、NFT、ゲーム などを見直すことを可能にします。そのために、Internet Comuter は、セキュアで、信頼性があり、スケーラブルになるよう設計されています。

スケーラビリティは非常に重要な要素であり、それは主にネットワークにおけるメッセージ配信の効率に依存します。ネットワークが大きくなればなるほど、より多くのメッセージを配信しなければなりません。そのため、Internet Computer のネットワークはサブネットに分割されています。各サブネットは、選ばれた複数のノードでキャニスターを実行する、より小さな Internet Computer ブロックチェーンと見なすことができます。ピアツーピア層は、同じサブネット内のノード間において、セキュアで、信頼性が高く、スケーラブルな通信を可能にする層です。

Internet Computer プロトコルは、大きく分けて4つの層で構成されています。

  • Execution は、ソフトウェアのメッセージを決定論的に実行するための安全な環境を管理します。
  • Message routing は、ユーザーとシステムが生成したメッセージをサブネット間でルーティングし、アプリケーションの入出力キューを管理し、メッセージを実行するためにスケジューリングします。
  • Consensus は、ユーザー および 異なるサブネット から受け取ったメッセージを選択し、順序付けして、メッセージルーティング層に配信される前に、公証及びファイナライズされる入力ブロックを作成します。
  • Peer-to-peer (“P2P”) は、ユーザーからのメッセージだけでなく、同じサブネットブロックチェーン内の他のノードからのメッセージも収集し、宣伝します。ピアツーピア層が受信したメッセージは、サブネット内の他のノードへ配信され、プラットフォームのセキュリティ、信頼性、および回復力を確保します。

Internet Computer のピアツーピア層の主な3つの挑戦は、セキュリティ、パフォーマンス、スケーラビリティです。Internet Computer は、悪意のあるノードに対してもセキュアであるように設計されており、ピアツーピア層とプロトコルは、そのような悪意のあるノード(サブネットの1/3まで)が存在しても動作を継続できるように設計されています。これは他の従来のピアツーピアの設計とは異なり、後述する複雑さと性能のトレードオフが加わっています。ピアツーピア層は、最小限のパフォーマンスオーバーヘッドでセキュリティ目標を達成すると同時に、サブネットの拡張を可能にします。

加えて、Internet Computer のピアツーピア層は、独自の優先順位付けのメカニズムをメッセージに提供します。これにより、重要なメッセージのより高速な配信が可能になり、不要なメッセージを送信しないことで帯域幅を節約できます。

上図翻訳 — Purpose: Make information available at one IC node reach enough other IC nodes in the same subnet efficiently 目的: ある1つのICノードから得られる情報を、同じサブネット内の十分な数のICノードへ、効率よく到達させる。

この記事では、Internet Computer のピアツーピア層について、下記の点に触れていきます。

  • 要件
  • 基本原則
  • アプリケーションコンポーネントとの連動
  • データ構造
  • ゴシッププロトコル
  • 帯域幅とメモリに関する考慮

ピアツーピア層は、上の層(例えば、コンセンサス)で作成されたアーティファクトを送信し、同じサブネット内の他のノードやユーザーから届くアーティファクトを受信、検証、処理、配信する役割を担っています。ピアツーピア層は、正直なノードがピアへアーティファクトを送信した場合、そのアーティファクトを必要とするサブネット内のすべての正直なノードが最終的に受信することを保証します。これは信頼性のあるブロードキャストの特殊なケースとみなすことができ、優先順位付けを伴う我々のコンセンサスアルゴリズムに合わせて調整されています。いくつかのネットワークの仮定のもとで、制限された時間での配信を提供します。

私たちは、以下の要件のもと、ピアツーピア層がその保証を提供することを望んでいます。

  • ビザンチン障害があるにもかかわらず、 制限された時間での配信/最終的な配信
  • 様々なアプリケーションの コンポーネント/ピア 用に予約されたリソース
  • 限られたリソース
  • 様々なアーティファクトに対する優先順位付け
  • 高い効率性
  • DOS/SPAM 耐性
  • 暗号化、真正性、完全性

ピアツーピアでは、サブネット内のメッセージの配信にゴシップメカニズムを使用しています。ゴシッププロトコルの原理は、噂の伝播に似たプロセスであり、受け取ったメッセージや作成したメッセージをサブネット内のピアに送信することです。ピアツーピアにおけるピアは、オーバーレイネットワークトポロジーによって決定されます。オーバーレイが無向で接続されていれば、すべてのものが O(直径) ホップで配送されることが保証され、すべてのノードがプロトコルに従い、メッセージがドロップすることはありません。

ピアツーピア層は、ビザンチンノードが存在してもフォールトトレラントがあるように設計されています。悪意を持って行動するノード(例:プロトコルに従わない、他のノードやユーザに危害を加えようとする)、または何らかの欠陥行動(例:応答しない、アーティファクトを配布しない、ひどいネットワーク遅延に悩まされる)を示すノードを「ビザンチン」と見なすことにしています。そのため、ピアツーピア層の設計では、サブネット内にそのようなノードが存在する可能性を考慮しており、サブネット内の最大3分の1のノードがビザンチンであっても、正しく効率的に動作することを保証しています。

ビザンチンノードを考える上で、いくつか避けたい問題があります。1つ目は、あるノードのすべてのピアがたまたま悪意を持っていたり、欠陥があったりする、いわゆる「エクリプス攻撃」です。悪意のあるノードが結託して、正直なノードが見るアーティファクトを選択し、そのノードをネットワークの残りの部分から切り離すことができます。メッセージの真正性を検証するため、悪意のあるノードがなりすましメッセージで正直なノードを騙すことはできませんが、接続性の問題は残ります。これを避けるには、十分な数のピアとの接続を保証するオーバーレイを使用して、すべての正直なノードが非常に高い確率で接続を形成するようにする必要があります。十分に小さなサブネットでは、ノードはサブネット内の他のすべてのノードに接続することができ、完全なグラフを形成するため、エクリプス攻撃に対する完璧な防御を提供することができます。Network Nervous System (NNS) のようなより大きなサブネットでは、よりスパースなオーバーレイを使用することになるでしょう。

アーティファクトがそれに依存するすべてのノードによって一定時間内に受信されることを保証したいので、ゴシッププロトコルは、欠陥のあるリンクやノードの問題が起こりうるにもかかわらず、これらのアーティファクトが配信されることを確認する必要があります。ゴシッププロトコルは多くの場合、冗長性と帯域幅の浪費をもたらす配信パターンに基づいています。したがって、これらのオーバーヘッドを削減する方法でそのようなプロトコルを設計することが重要です。

アーティファクトは大きい可能性があり、これが複数のピアから複数回送信されると、深刻な帯域幅の浪費を引き起こします。これは、複数の友人から同じ噂を何度も聞かされることに例えられます。この例えで言うと、単に噂をもう一度話すかわりに、友人があなたに最新のニュースを聞いたかどうかを尋ねることから始めることができます。私たちの文脈では、これは最初に送信される宣伝に相当します。宣伝は、アーティファクトのメタデータとそれを検証するいくつかの手段のみを含む小さなメッセージであり、その内容は含まれません。その後、各ノードは少なくとも1つのピアから必要とされているアーティファクトを要求します。我々の設計では、1つのピアに問い合わせることから始めますが、問題が発生した場合は、別のピアに同じアーティファクトを問い合わせ、欠陥のない誠実なピアが見つかるまでこれを繰り返すことができます。

宣伝には、ゴシッププロトコルとそのアプリケーションコンポーネントが整合性検証(例えば整合性ハッシュ)と意思決定(例えばコンポーネントがアーティファクトの優先順位を決めるのに役立つ属性)に利用するフィールドが含まれます。

ノードは複数の宣伝を受け取る可能性があるため、最初にリクエストするアーティファクトを選択しなければならない場合があります。各宣伝には、それを作成したクライアントコンポーネントによって提供されるいくつかの属性が含まれています。たとえば、コンセンサスアーティファクトには、対応するアーティファクトのブロックの高さを示すheight属性が含まれます。また、コンセンサスはゴシップに優先度関数を提供しており、その優先度関数は宣伝(その属性を含む)を受け取り、優先度値を返します。(最低は「drop」、つまりこのアーティファクトは不要であることを意味し、最高は「fetch now」、つまり最優先のアーティファクトであることを意味します)。たとえば、コンセンサスが現在高さ10である場合、アーティファクトのタイプや他の状態パラメータによっては、高さ11や12のアーティファクトよりも、高さ10のアーティファクトを優先するかもしれません(原則として、異なる高さよりも同じ高さを優先します)。ピアツーピアは、これらの優先度値を利用して、どのアーティファクトを最初に要求すべきかを決定します。

ピアツーピアは受信したアーティファクトをアーティファクトプールに格納します。そして、プールの変更について、コンセンサスと他のクライアントコンポーネントに通知した後、アプリケーションコンポーネントはプールの内容に関する次のアクションを決定します。アーティファクトプールには、各アプリケーションコンポーネントで利用できるすべてのアーティファクトが含まれています。

私たちは、アーティファクトを 「検証済み」と「未検証」に分類しています。後者の分類は、まだ検証されていないアーティファクト用です。検証とは、クライアントコンポーネントによるアーティファクトのチェック、例えば署名の検証、を意味します。クライアントのアーティファクトプールは、必要に応じて不揮発性ストレージに永続化できます。これはコンセンサスアーティファクトに対して行います。

(上図の翻訳)

Artifacts have been validated by application component, to be relayed.

(左上)アーティファクトはアプリケーションコンポーネントによって検証され、中継されます。

Artifacts received from peer2, not validated yet by application component.

(左下)ピア2から受信したアーティファクトは、アプリケーションコンポーネントによってまだ検証されていません。

Data structures maintained for each peer.

(PEER CONTEXT 1 の上)ピアごとに保持されるデータ構造。

Adverts received from peer1, queued to request artifacts according to priority.

(右上)ピア1から受信した宣伝は、優先順位に従ってアーティファクトを要求するためにキューに入れられます。

Advarts of artifacts currently requested from peer.

(右中)現在ピアから要求されているアーティファクトの広告。

Recently completed artifacts.

(右下)最近完成したアーティファクト。

上図では、ノードがゴシッププロトコルのためにどのようなデータ構造を保持しているのかがわかります。左側はアーティファクトプールで、検証済みセクションと未検証セクションに分かれています。未検証のセクションには、まだ検証されていないアーティファクトが格納されます。各未検証セクションのサイズは、悪質なピアによってアーティファクトプールがいっぱいになり、リソースリークやDoS攻撃を引き起こすことを防ぐために制限されていますが、通常の状況でプロトコルが正しく動作することを保証するのに十分なサイズとなっています。

さらに、各ピアにおいて、コンテキストを保持することで、どの宣伝を受け取ったか、どの宣伝を誰にリクエストしたか などを追跡できるようにしています。

  • 宣伝キューは、このピアから受信したすべての宣伝の優先順位のキューです。これらは、その優先順位によって並べられます。
  • 要求された集合には、対応するアーティファクトがこのピアからすでに要求された、すべての宣伝が含まれます。
  • 受信チェックキャッシュは、最近受信したアーティファクトに対する要求を防ぐために利用されます。

ゴシッププロトコルが処理する主なイベントは下記です。

  • プール内の新しいアーティファクト(クライアントコンポーネントによってローカルに追加された)。
  • ピアから受信した新規宣伝の処理
  • ピアから受信した新しいアーティファクトの処理
  • リカバリーと再接続の問題

(上図の翻訳)

* 失敗した試行を検討します

** タイムアウトが経過したら、<手紙アイコン>を REQUESTED[i] からADVERTS[i] に戻します(訳注 ADVERT = 宣伝, REQUEST = 要求)

1. 宣伝キューから最も優先度の高い* <手紙アイコン>を i のREQUESTED にキューし、download_next(i)を再度呼び出すためのタイムアウト <ストップウォッチアイコン> も一緒にキューします **

2. iに要求 <手紙アイコン>を送信します

プール内の新しいアーティファクト(クライアントコンポーネントによってローカルに追加された)

ノードはクライアントコンポーネントから新しいアーティファクトを受信すると、そのアーティファクトの宣伝を作成し、この宣伝をすべてのピアに送信します。

ピアから受信した新しい宣伝の処理

ノードがピアから宣伝を受信すると、まず、対応するアーティファクトがノード自身によってすでにダウンロードまたは作成されているかどうかをチェックします。そうではなく、この宣伝の優先順位が「drop」よりも高い場合、その宣伝を送信したピア の 宣伝キューに追加します。アーティファクトプールの未検証セクションにピアのための十分なスペースがある場合は、このピア i のために特別に download_next(i) という関数を呼び出します。この関数は、(優先度関数によって割り当てられた優先度に基づいて)最優先の宣伝をフェッチし、そのピアに対応するアーティファクトを要求します。したがって、今宣伝を受け取ったアーティファクトを要求する必要はなく、最も優先度の高いアーティファクトを要求するだけです。

アーティファクトを要求した後、対応する宣伝を、宣伝キューから アーティファクトを要求しているピアの要求集合 へ移動します。

複数のピアから同じ宣伝が送信されている可能性があるため、複数のピアの宣伝キューに同じ宣伝がある場合があります。宣伝は、実際のアーティファクトを受け取るまで、他のピアの宣伝キューに残っています。アーティファクトの要求には、応答しないピアまたは遅いピアから守るために、タイムアウトが設定されています。これは、限られた時間での配信を保証するのに役立ちます。すでにリクエストしたピアからのアーティファクトの要求は、誤動作の可能性があるので、避けます。この場合は、他のピアがこの同じアーティファクトを宣伝したかどうかを確認し、もしそうならば、応答のないピアを試す前に、そのピアからフェッチしてみます。

ピアから受信した新しいアーティファクトの処理

ピアからアーティファクトを受け取ると、まず、対応する宣伝がピアの要求集合にあることをチェックすることで、それが要求されたものであることを確認します。次に、対応する整合性ハッシュを使用してその整合性を検証します。これらのチェックのいずれかが失敗した場合は、このピアが不正を行っていることを意味します。最終的に、すべての宣伝キュー要求されたセットから宣伝を削除します。それを送信したピアの未検証プールにアーティファクトを追加します。クライアントコンポーネントがそれをチェックし検証するために、そこに残しておきます。また、ピアごとに維持されている received checkという小さなキャッシュにアーティファクトのハッシュを追加し、同じアーティファクトに対するさらなる宣伝を無視するようにします。これは、アーティファクトがプールの未検証部分から削除されても、同じ宣伝を再び要求しないように、アプリケーションコンポーネントが優先度関数を更新するための猶予期間を設けるために行われます。未検証のアーティファクトプールにこのピアのためのスペースがまだある場合、download_next(i) 関数を使用して、優先順位に従って、このピアから次のアーティファクトを要求します。

トランスポートとコネクションの管理

ゴシップコンポーネントの下には、ピア間の実際のネットワーク接続を維持するトランスポートコンポーネントがあります。トランスポートコンポーネントは、接続を安定させようとする役割を担っています。一過性の接続障害や通信が混雑した場合に備えて、独自のバッファを持っています。また、接続がハングアップしないように、また通常より長い遅延を検出するための内部メカニズムを備えています。これは、限られた時間での配信を提供するために重要です。トランスポートは、それ自身のレイヤー7ヘッダーを使ってゴシップメッセージを組み立てます。このヘッダーは、フローを維持し、エラーを報告するために、トランスポートコンポーネントによって使用されるいくつかのメタデータフィールドを含んでいます。現在、トランスポートはピア間で複数のTCPストリームを使用します。

トランスポートでは、このような分散型P2Pネットワークに適応した方法で TLS 1.3を使用しており、信頼の根源となる認証局の層はありません。その代わり、信頼の根源は、ノードがピアを認証できるようにノードに自己署名証明書を提供するレジストリです。

TCP接続が中断された場合、トランスポートは定期的に再接続を試みます(対応するピアがまだノードの割り当てられたオーバーレイ上にある限り)。接続が再確立されると、対応するトランスポートキューが排出されて、新しいメッセージの入力を開始できます。

すべてのデータ構造はサイズに制限があるため、これはトランスポートバッファにも適用されます。このようなバッファが満杯になった場合、あるいは再接続を待っていた場合、トランスポートは最終的に受信側のゴシップコンポーネントにメッセージのドロップの可能性を通知します。その後、受信者は 再送信要求 を送ることができます。再送信要求は、ゴシッププロトコルのメッセージであり、要求の送信者が見た最新のアーティファクトを受信者に伝えるためのフィルタを備えています。この要求が送信されるまでに、他のピアがすでに同じ宣伝の送信に成功しているかもしれないので、ノードが見逃したすべてのメッセージにおいて対応するピアに追いつく必要がないかもしれません。

再送信要求を受信すると、送信ノードは要求に含まれるフィルタに従って関連するすべての宣伝を送信します。トランスポートはこれらの宣伝をレシーバーに送信します。このプロセスの間にキューが再び満杯になると、残りの宣伝のために別の再送信要求が送信されます。

要約すると、ピアツーピア層は、限られた時間でサブネット内のアーティファクトの配信を保証します。また、宣伝要求アーティファクトパターンとオーバーレイトポロジーを使用して帯域幅のオーバーヘッドを削減し、クライアントコンポーネントに優先順位付け API を提供して、最も優先度の高いアーティファクトが最初に配信されることを保証します。このプロトコルはフォールトトレラントになるよう設計されており、DoS 攻撃とその他の脅威を考慮に入れています。
____

smartcontracts.org で構築を開始し、forum.dfinity.org で開発者コミュニティに参加しましょう。

--

--