Interchain Query
概要
IBC(CosmosSDKのモジュール間プロトコル)の新機能
ICQ標準は、IBC対応チェーンが互いにオンチェーンデータを照会できるようにするために開発されたもの
相手チェーンの検証におけるオラクルの必要性を低減する。
専用の ICQ モジュールを実装することで、チェーンは問い合わせ要求を受け取ることができるようになる。
https://scrapbox.io/files/64c787f2c7b2f9001c3aed98.png
chainA上のノードは、まずIBCパケットを構築する。IBCパケットはrealayers経由で確立されたIBCチャネルを経由してchainBのノードに送られ、そのICQモジュールによって受信される。
ICQモジュールはパケットを開き、クエリーをチェックし、chainB上の適切なアプリケーション・モジュールにルーティングする
関連するデータを使って、chainBは構造化された応答を作成する。
最後に、ICQモジュールを経由して、応答がホームチェーンに送り返される。
ICQはオープンソースの標準であり、ネイティブのICQモジュールを利用するか、IBC対応のスマート・コントラクトに完全に依存するか、さまざまな方法で実装できる。
前提
IBC コア標準は、2 つの IBC チェーン間のアプリケーション・レベルのメッセージを可能にするインフラストラクチャの定義を提供する。IBC コアで規定されるコンポーネントには、コネクション、チャネル、ポート、パケットがある。チャネルはメッセージの注文と送信を行い、IBC チェーン間で開かれるコネクションに関連付けられます。ポートはモジュールをチャネルにバインドするために使用される。パケットはメッセージをカプセル化し、チャネルとポートのタプルで論理接続を指定するデータ構造です。
TAO : Transport, Authentication, and Orderingレイヤーは、接続の各側でステートマシンの追跡と検証に使用されるライトクライアントおよび実際にメッセージを伝送するリレイヤーと並んで、これらのコアデータ構造で構成される。
ICQ標準(本稿執筆時点ではICS-32として提案中)は、IBCプロトコルのリクエスト・レスポンス・ベースのメッセージ通信を拡張し、このTAO層上で動作する。
https://scrapbox.io/files/64c789c9162c13001b249d1f.png
genesis stateはICQモジュールの初期状態を定義する。
モジュールには、host portとmodule parametersという2つのgenesisフィールドがある。
Host port
固定文字列値で、ICQモジュール(ホストチェーン上)がポート名(portID)に所有権をバインドするために使用します。すべてのICQクエリメッセージはホストチェーンのこのポートに到着し、クライアントチェーンはホストポート名を相手ポートIDとして使用します。ホストポートは、動的に作成されるchannelIDと結合され、ホスト側のエンドポイントとして機能するchannel-portタプルを作成する。チャネル・ポート・タプルは、<portID, channelID>と表すことができる。
module parameters
2つのパラメータHostEnabledとAllowQueriesがある
HostEnabled
クエリされるチェーンがICQモジュールを介してクエリ要求を提供する機能を有効または無効にするために使用される。
AllowQueries
ホストチェーンが特定の種類のクエリをホワイトリストに登録することを可能にします
通常、ホストチェーンでは様々な gRPC クエリが利用可能であり、独自の種類のクエリを採用している場合があります
ホストチェーンが受け取りたい ICQ リクエストのタイプをフィルタするもの
このパラメータを空にすると、クエリは受け付けられない
デフォルトでは、AllowQueriesによって指定されたホワイトリストにそのタイプのクエリが明示的に含まれていない限り、ICQホストチェーン上でクエリを使用することはできません
詳細
チェーン間クエリは、Tendermint ABCIプロトコルのクエリメカニズムとメッセージタイプを使用して行われます。クライアントチェーン上のカスタムモジュールがこれらの ABCI クエリメカニズムを呼び出して ICQ クエリメッセージを開始します。ICQ クエリメッセージは Tendermint ABCI リクエストのリストで構成されます。メッセージはチャネルやIBC接続に送信される前にprotobufを使ってエンコードされます。
https://scrapbox.io/files/64c789c9162c13001b249d1f.pnghttps://scrapbox.io/files/64c78f1301f0eb001b3f4c95.png
ICQ応答メッセージはTendermint ABCI応答のリストで構成されます。これらはリクエストのリストが送信されたのと同じ順番で、クエリされた(ホスト)チェーンからクエリする(クライアント)チェーンに返されます。リストはプロトエンコードされ、InterchainQueryPacketAckのデータフィールドに生のバイトとして格納された後、問い合わせチェーンに応答として送信される。
各ICQメッセージは同じ構造を持っていることに注意してください - (クライアントからの)ABCIリクエストまたは(ホストからの)ABCIレスポンスのリストがエンコードされ、パケットにラップされています。ABCI応答のリストはABCIリクエストのリストと同じ順序に従うことを覚えておいてください。つまり、N番目のインデックスを持つリクエストは、返される確認応答パケットのN番目のインデックスを持つ応答に対応します。
https://scrapbox.io/files/64c789c9162c13001b249d1f.pnghttps://scrapbox.io/files/64c78f1301f0eb001b3f4c95.pnghttps://scrapbox.io/files/64c79128912716001c35941a.png
Channel Creation
ICQが2つのチェーン間で動作するためには、クライアント・チェーンはカスタム・モジュールを、ホスト・チェーンはICQモジュールを確立しなければならない。
これら2つのモジュールは、必要なポート名バインディングを準備しておく必要がある。クライアント・チェーンの問い合わせモジュールのポート名は、命名規則に制限がありません。
一方、ホストのICQモジュールのポートIDはデフォルトで "icqhost "に固定されている。
適切なポート名バインディングが設定され、両方のチェーンがライブであると仮定すると、リレイヤーオペレーターは、2つのチェーン間でチャネルを作成するようにリレイヤーを設定することができます。
ICQを実行するためのチャネル・ハンドシェイク・メッセージングはすべて、IBCプロトコルのコアスタンダードを使用してリレイヤーが行います。
Recap
ICQモジュールを持つホストチェーンは、複数の異なるクライアントチェーンからクエリ要求を受け取ることができます。ICQモジュールのGenesisステートフィールドには、ホストポートのportIDと、受信クエリの送信を有効/無効にするためのパラメータと、クエリタイプをフィルタリングするためのパラメータが含まれます。ICQメッセージは、TendermintのABCIクエリメッセージタイプを使用し、ABCIリクエストのリストをエンコードしたデータパケットでIBC経由でホストチェーンに送信することで構築されます。
応答は同じ形式のパケットとして返され、対応するリクエストと応答が同一のインデックス値を持つように、メッセージの順序が保持されます。ホスト側のICQモジュールは、適切にバインドされたポートを持つクライアント側の問い合わせモジュールとインターフェースする。それぞれの側のチャネルポートタプルは、2つのチェーン間の論理接続を表す。リレイヤは、バインドされたポートをリンクするチャネルを開くことで、パケットの転送を行う。
参考資料