技術概要 - Canister HTTPS アウトコール の仕組み
このページでは、Canister HTTP アウトコール(Canister HTTPS リクエスト)の仕組みと、API を利用する際の注意点について詳しく説明します。また、通常の(Web2.0)コンピューター・プログラムが HTTP コールを行う場合と比較して、いくつかの制限や違いがあること、この機能をうまく使うためにプログラマーが考慮すべき点についても言及したいと思います。この機能を使おうとするエンジニアは、このページを読んでいただき、この機能を素早く理解することをお勧めします。すぐにでもコーディングに取り組みたいというせっかちな読者は、コンセプトの部分を読み飛ばして、今すぐコーディングセクションにジャンプして、コーディングを始めることができます。
テクノロジー
HTTPS アウトコール機能により、Canister は従来の Web2.0 HTTP サーバーに対して HTTP のアウトコールを行うことができます。リクエストのレスポンスは、サブネットのレプリカ間でステートが不一致する危険性がなく、安全に Canister の演算に利用することができます。
HTTPS アウトコールが IC で処理される仕組み
Canister の HTTP アウトコール機能は、Internet Computer レプリカの一部として実装され、マネージメント Canister の API として公開されます。次に、Canister によるリクエストがどのように処理されるのか、簡略化して概要を説明します。HTTP リクエスト機能はサブネット単位で実現されており,各サブネットは自分の Canister の HTTP リクエストを他のサブネットから独立して処理し,HTTP リクエストが他のサブネットにルーティングされて実行されることはありません。
- Canister は、
http_request
メソッドを使用してマネージメント Canister API を呼び出すことにより、HTTP リクエストを発信します。 - このリクエストはサブネットで複製されたステートに一時的に保存されます。
- 定期的に(ラウンドごとに)、各レプリカのネットワーキング層にあるアダプターは、複製されたステートから保留中の HTTP アウトコールを取得します(実際には、レプリカプロセスの内部にあるアダプター層(‘shim’)がこれを行います。アダプター自体は、セキュリティ上の理由から、別の OS レベルのプロセスにサンドボックス化されています)。
- 各レプリカ上のアダプターは、HTTP リクエストをターゲット・サーバーに送信して実行します。
- サーバーからの HTTP レスポンスは、サブネットの各レプリカ上のアダプターが受信し、レプリカプロセスのコンポーネントに提供されます。アダプターは、ネットワークレスポンスサイズを
max_response_bytes
に制限しており、デフォルトでは MB に設定されていますが、より小さい値を設定することもできます。この値はリクエストの価格に影響するので、期待するレスポンスに対してできる限り低く設定することが重要です。価格はmax_response_bytes
のサイズとともに増加し、実際のレスポンスサイズは考慮されず、最大値のみが考慮されます。 - 各レプリカのレスポンスに対して、Canister の一部として実装されたオプションの変換関数が呼び出され,レスポンスが変換されます。これはレプリカプロセス内のコンポーネントによって行われます。
- 変換されたレスポンスは、各レプリカのコンセンサスに引き渡されます。
- ここで、少なくとも (正確には 、 はプロトコルが許容する欠陥レプリカ数です)のレプリカが、入力としてのリクエストに対して同じレスポンスを持つ場合、IC コンセンサスはレスポンスに同意します。この場合、コンセンサスはこのレスポンスをマネージメント Canister API に返します。コンセンサスが得られない場合やその他の問題がある場合は、エラーを返します。
- マネージメント Canister API は、呼び出しをした Canister にレスポンスまたはエラーを返します。
上の図は、Canister がどのように機能と相互作用し、サブネットレプリカが外部サーバーと通信するパターンを概観しています。
要約すると、HTTP リクエストを実行するために、各レプリカは、外部の Web サーバーから受け取った HTTP レスポンスの(変換関数を指定した場合には変換された)インスタンスを Internet Computer のコンセンサス層を介してプッシュします。サブネットのレプリカは、レプリカが受け取ったすべてのサーバーレスポンスに基づいて、Canister に提供するレスポンスに合意できるようにします。変換関数の指定により、サーバーから各レプリカで受信したレスポンスが部分的に異なる場合、それらの違いは排除され、同じ変換されたレスポンスがすべての(正直な)レプリカのコンセンサスに提供されることが保証されます。これにより、すべてのレプリカにおいて全く同じレスポンスが Canister の実行に使用される(または何も使用されない)ことが保証され、それによってこの機能を使用するときに不一致が起こらず、サブネットの複製ステートマシンの性質が維持されることが保証されます。
この機能には、変換関数と IC コンセンサスが重要な役割を果たすことがおわかりいただけると思います。変換関数は、レプリカが受信したレスポンスの差異を確実に取り除き、異なるレプリカ上の変換されたレスポンスが全く同じになるようにすることで、コンセンサスが呼び出し側の Canister に合意されたレスポンスを提供することを可能にします。レプリカが受信したレスポンスをコンセンサスで実行することで、どのレプリカもスマートコントラクト Wasm の実行環境に対して同じレスポンスを提供することを保証しています。
トラストモデルとプログラミングモデル
Canister HTTP アウトコールのトラストモデルは,呼び出された HTTP サーバーと IC のトラストモデルに基づいています:
- HTTP サービスは正直であると仮定します。そうでなければ、(HTTP サービスは)サブネットのどの呼び出し側レプリカに対しても、任意のレスポンスをできることになります。これは、Web 2.0 サービスやオラクルからサービスを呼び出す場合と同様で、ブロックチェーンからサービスを呼び出す場合もこれと同じシュチュエーションです。
- IC のトラストモデルは、少なくとも のレプリカが正直であると仮定しています。この場合、正直なレプリカは(オプショナルである変換後に)同じレスポンスを取得し、そのレスポンスを呼び出し元の Canister に提供し返せるように、コンセンサスを得ることができます。 不誠実なサーバー(レプリカ)は、簡単にリクエストを失敗させたり、間違ったデータを提供することができます。また、 以上の不誠実なサブネットのレプリカはリクエスト自体を失敗させることができます。間違ったデータを提供するためには、 以上のレプリカの共謀が必要です。
この機能のプログラミングモデルでは、HTTP アウトコールを行う Canister が HTTP クライアントとして動作します。つまり、一般的なケースにおいては、様々なヘッダーを解釈し、それに応じて動作する必要があります。API リクエストのような使用例では、これはかなり簡単で、標準的なケースでは多くの特別な考慮は必要ありません。IC プロトコルスタックは、概念的には、Canister と従来の HTTP サーバーの間の通信パイプとみなすことができ、HTTP レスポンスが合意を経て、すべての正直なレプリカが実行時にまったく同じレスポンスを受け取るようにします。つまり、呼び出し側の Canister が合意されたレスポンスを受け取るようにするものです。
HTTPS アウトコールと オラクルの比較
ブロックチェーンオラクル、または単にオラクルは、他のユーザーと同様に、クエリを作成したり、イングレスメッセージを送信することによってブロックチェーンと対話する外部パーティです。これまでのところ、ブロックチェーンの世界では、スマートコントラクトを従来の Web2.0 サーバーと通信させるための主要な手段となっています。
基本的なアーキテクチャは、チェーン上にオラクルスマートコントラクトが配置されていることです。ユーザーはこのオラクルスマートコントラクトにリクエストを行い、オラクルスマートコントラクトはそのリクエストを一時的に保存します。オラクル、つまり Web 2.0 サーバーは、クエリやアップデートコールを使ってオラクルスマートコントラクトと通常のやり取りをすることで、保存されたリクエストを取得します。次に、オラクルは通常の HTTP コールによって Web 2.0 の世界でリクエストを実行し、ブロックチェーンとの通常の対話パラダイム(アップデートコール)を使用して、オラクルスマートコントラクトにレスポンスを返します。その後、オラクルスマートコントラクトは、標準的なオンチェーン相互作用を使用して、呼び出したスマートコントラクトにレスポンスを提供し返します。
オラクルアーキテクチャでは、単一のオラクルがオリジナルのリクエストを実行するかもしれないし、オラクルの分散ネットワークがそれぞれリクエストを発行し、合意したレスポンス(証拠を含む)をオラクルコントラクト、最終的には呼び出し側の Canister に提供するかもしれません。このように、オラクルの世界でアウトコールと同じ結果を効果的に達成することができますが、そのサービスの対価を求めるひとつ以上の外部パーティを必要とし、より複雑なアーキテクチャになります。したがって、HTTP アウトコールは多くの関連するユースケースでオラクルに取って代わり、より強力なトラストモデルで、より低い手数料とより低いリクエスト実行レイテンシーで同様のことができると考えることができます。
オラクルサービスは、追加の機能またはサービスを提供することができます。ひとつの顕著な例は、与えられた情報項目(例えば、アセット価格)に対して複数のデータソースを使用し、その結果として正規化されたレスポンス(例えば、中央値価格)を提供することです。別の例としては、スマートコントラクトがオラクルとの対話なしに、直接アクセスできるように取得された価格履歴のセレクションをチェーン上で利用可能にしておくことです。これらの機能はいずれも、Canister の HTTP アウトコール機能で構築でき、オラクルは必要ありません。
全体として、Canister HTTP アウトコール機能は、オラクルやオラクルネットワークが行ってきたことを、さらなる障害点や手数料を獲得を目的にした付加的なパーティを必要とせずに、より強力なモデルで実現することができます。Canister HTTP アウトコール機能により、Web2.0 サーバーとのインタラクションは、よりシンプルなアーキテクチャにより、手数料の削減と低レイテンシーの恩恵を受けることができます。
開発者の便益
開発者にとって、Canister HTTP リクエスト機能は、いずれにせよ信頼が必要となる IC に加えて、どの当事者(オラクル)を信頼するかを決定する必要がないという利点があります。トラストの前提を減らしより良い分散化を得るために、単一のオラクルを使用するか、複数のオラクルを使用するかを決定する必要がなく、HTTP アウトコールでこれらを得ることができるのです。HTTP アウトコールのコストは、確立されたオラクル・プロバイダーにそのサービスと関連するイングレス・コストを支払うよりもはるかに低いと思われます。したがって、HTTP コールを使用することには明らかな経済的利点があります。分かりにくい信頼性の判断から解放された開発者は、ビジネスロジックに集中し、必要な HTTP コールを行う(そして対応する変換関数を書く)だけでよく、より自然な形で開発することができます。
エンドユーザーの便益
エンドユーザーは HTTP アウトコールから、様々な方法で利益を得ることができます。
- より強力なトラストモデル: エンドユーザーは、さらなる障害点になるかもしれない付加的なパーティーに依存しないことで、より強力なセキュリティを得ることができ、それによってより良い分散化の恩恵を受けることができます。オラクルサービスのようなサードパーティが関与しないので、サブネットのレプリカと呼び出される外部サービスだけを使った我々の HTTP アウトコールは分散化の最たるものです。
- 低料金: オラクルのミドルパーティがカットされるため、ユーザーは通常より安いサービスを得ることができます。
- 低レイテンシー: HTTP を直接呼び出す場合のレイテンシーは、オラクルコントラクトに(Xnet)リクエストを出し、外部のオラクルサービスによってポーリングののちにサービスされる場合に比べて低く、Canister と対話する際のユーザーエクスペリエンスが向上します。IC のサブネットアーキテクチャの原則といくらか矛盾する、オラクルプロバイダが関連するすべてのサブネットにオラクルスマートコントラクトをセットアップするということをしない限り、(複数の)Xnet リクエストが必要になり、レイテンシーがさらに顕著になります。
既知の制限事項
現在の MVP にはいくつかの制限があり、エンジニアがこの機能に何を期待できるのか、また、あるユースケースに対してこの機能を適用できるのかを知るために、明示することが必要です。これらの制限のいくつかは、将来の機能拡張で対処されるかもしれません。
レスポンスは“同様”でなければならない
サブネットのレプリカが受け取るレスポンスは、各レスポンスが同じ変換関数を受けることができ、変換の結果がどのレプリカでも等しいという意味で、“同様”でなければなりません。したがって、この文脈で同様とは、我々が関心を持ついくつかの核となる情報がすべてのレスポンスで等しく、他の部分は異なっていても、レスポンスには関係ないことを意味します。HTTP API の世界でよくある設定は、レスポンスは構造的に等しいが、レスポンスに含まれるタイムスタンプや識別子などのために、あるフィールドが異なるというものです。
POST リクエストはべき等でなければならない
この(HTTP アウトコールの)機能の実装方法が意味するところは、すべての HTTP リクエストをサブネットのすべてのレプリカが行う必要があるということです。これは GET
だけでなく POST
リクエストにも当てはまり、後者では GET
リクエストにはない課題が生じます。基本的な HTTP の原則に従って適切に実装されるならば、その課題はべき等です。べき等とは、リクエストが複数回行われた場合、同じ結果をもたらし、サーバーの状態を変化させないということです。べき等は POST
リクエストには適用されません。つまり、さらなる予防措置がなければ、Canister から行われた POST
は、サブネットのレプリカの数を として、 回、呼ばれたサーバーの更新につながるリクエストになる可能性があるということです。この動作は明らかに意図したものではありませんし、ほとんどのシナリオで受け入れられるものでもありません。
このようなシナリオで実際に使われる標準的な解決策は、リクエストに べき等鍵 を使用することです。この鍵は、異なるレプリカが生成したすべてのリクエストと一緒に送られるヘッダーにある、一意のランダムな文字列です。サーバーはひとつ以外のすべてのリクエストを重複と見なし、それらはサーバーの状態を変更するために考慮されず、ひとつのみが考慮されます。この結果、POST
の意図した動作が、サーバーによって一度だけ適用されることになります。しかし、サーバーによって処理されるこのひとつのリクエストは、実際には不正なレプリカによって行われたリクエストである可能性があり、また意図されていないリクエストであるかもしれないことに注意してください。また、不正なレプリカが、べき等鍵を変更することで、そのリクエストと実際の意図したリクエストがサーバーによって処理されてしまうかもしれません。
べき等鍵は一部のサーバーでサポートされていますが、すべてのサーバーでサポートされているわけではありません。べき等鍵の適用可能性はケースバイケースで評価される必要があります。べき等であるという課題は、将来的にこの機能を拡張し、定足数を減らすことで部分的に軽減することができます。つまり、Canister はクォーラムサイズを 1 と定義し、ひとつのレプリカに POST
リクエストを実行させることができます。不正なレプリカの問題は明らかにまだ残っていますが、べき等性の問題はこの拡張機能で解決されます。
リクエストが適切に実行されたかどうかをチェックするために、GET
を介して安全な 読み直し 操作を行うことは、課題のいくつかを軽減するのに役立ちます。しかし、不正なレプリカが状態の全く異なる部分を更新することは、この方法では信頼性をもって検出できません。
不正なレプリカ
すでに述べたように、不正なレプリカはより一般的な問題です。そのようなレプリカは、正直なレプリカによって実装された Canister が気づいていない任意の POST
リクエストを、いつでもサービスに対して行うことができます。つまり、外部サーバーを認証するために API キーやパスワードを保存している場合、不正なレプリカが保存されている平文の認証情報を使ってサーバーを認証してしまうという問題に直面するのです。
しかし、この問題はオラクルでも簡単に解決できないことに注意してください。不正なオラクルは不正なレプリカと全く同じことをすることになります。複数のオラクルがあっても、POST
の問題は解決されません。これを解決するには、閾値 TLS のような高度な(暗号)機構を使用するか、サーバー側で何らかのサポートが必要です。例えば、サーバーは与えられた API キーに対して行われたすべてのステート変更のログを保持し、Canister はこのログを安全に読み返し、少なくとも不正なレプリカによる呼び出しを検出することができます。リクエスト元の IP アドレスを追跡することで、不正なレプリカを特定し、それに対して法的措置やその他の措置を取ることができるかもしれません。
Internet Computer と Web2.0 サーバー間の書き込み統合を安全にするための一例として、Chain Key 暗号を用いたサブネット署名で POST
リクエストに署名し、サーバーにその署名をチェックさせるという方法があります。このようなアプローチはサーバーの適応を必要とするが、不正なレプリカが任意のリクエストを行うという、残りのセキュリティ問題を解決することができます。
これまで見てきたように、不正なレプリカが POST
コールに与える影響を完全に取り除くには、HTTP2.0 サービスによるサポートが必要かもしれません。そのようなサポートがあれば、Web3.0 と Web2.0 の間のシームレスで安全な相互運用性を実現することができます。
IPv6 のみサポート
現在、IC 自体が IPv6 ベースのシステムであるため、Canister の HTTP アウトコール機能は IPv6 のみの機能となっています。今後、コミュニティからの要望に応じて IPv4 対応を行う可能性があります。現在 IPv4 をサポートしていない主な理由は、IC の各レプリカが独自の IPv4 アドレスを取得できるほどの IPv4 アドレスがないため、バウンダリーノード上でトラフィックをルーティングするか、他のメカニズムを使用して IPv4 通信を可能にする必要があるためです。これらのアプローチはいずれも分散化を抑制し、Web2.0 サーバーと直接通信するレプリカと比較してトラストモデルを弱めることに繋がります。
サーバーによるレート制限
一般消費者向けにサービスを提供しているほとんどの Web サーバーは、ある種の速度制限を実装しています。レート制限とは、ある時間間隔で IPv4 アドレスまたは IPv6 プレフィックスから行えるリクエストの数を制限することです。あるアドレスやプレフィックスの割り当てを使い切ると、この IP やプレフィックスからのリクエストは処理されず、代わりに相応のエラー応答が処理されることになります。
問題は、サブネット上のすべての Canister が、このサブネットのレプリカの IPv6 プレフィックスを共有し、したがって、レート制限を実装する各サーバーのクォータを共有することです。一般(未認証)ユーザー向けの HTTP サービスの典型的なクォータは、1秒あたり 10$ リクエストのオーダーです。どのレプリカも同じリクエストをするので、 の増幅率があります。 はサブネット内のレプリカの数です。このため、クォータはすぐに消費され、レート制限によりスロットリングやレプリカが(一時的に)ブロックされる可能性があります。
登録ユーザーを使い、API キーでリクエストを承認することで、同じサーバー上のユーザーを切り離し、それぞれに割り当てを与えることができ、公開 API での問題を解決することができます。ただし、API キーは各レプリカに保存され、レプリカが侵害された場合に公開される可能性があることに注意してください。これはスマートコントラクトのセキュリティモデルで考慮する必要があり、特に POST
操作に関連します。詳細については、discussion on compromised replicas を参照してください。
登録ユーザーを利用することで、公開 API のレート制限や、すべての Canister がサービスの割り当てを共有することの問題のほとんど、あるいはすべてを解決できると考えているため、現在 IC プロトコルスタックにレート制限を実装していません。
今後の拡張性
すでにさらに上で述べたように、コミュニティの需要に基づいて、将来的に実装することを検討している複数の可能な拡張機能があります。現在の MVP は、機能セットを減らすことで、より早く市場に投入することができるため、それらを含んでいません。
- IPv4 サポート: IPv4 サポートは、Canister が IPv6 では利用できず、IPv4 のみで利用できるサーバーにリーチするのに役立つでしょう。
- 縮小クォーラム: Canister は、縮小クォーラムがリクエストに使用されるべきと定義できます。例えば、すべての レプリカの代わりに、リクエストを行うサブネットの レプリカのみが使用されます。これは
POST
リクエストのべき等問題を解決するのに非常に有効です。また、信頼度は重要ではなく、サーバーのクォータによってリクエストの増幅を抑えたい場合にも有効です。
HTTPS アウトコールのコーディング
次に、Canister スマートコントラクトで Canister HTTP リクエストを使用したいエンジニアのために、重要な情報を提供します。Canister HTTP リクエストを使用することは、一般的なケースにおいて、通常のエンタープライズ・アプリケーションで HTTP リクエストを行うよりもやや困難です。また、The Internet Computer Interface Specification の機能の API 定義も読者に紹介します。
Canister HTTP コールのコーディングのレシピ
次の “レシピ” は、新しい Canister HTTP アウトコールタイプの実装に取り組むための最良の方法のブループリントになります。
- “手動” で、例えば、
curl
ツールを使って、サブネットのレプリカによって行われることをエミュレートするために、短い時間枠(1-2秒)内に関心のある同じ HTTP リクエストを2回、単により小さい で行います。 - 2つのレスポンスの差分を取って、2つのリクエストで異なる項目をすべて見つけます。ここでは、ボディとヘッダーの両方を考慮することが重要です。あるいは、関心のあるコア情報と、それがどのようにレスポンスとして抽出されるかを特定します。
- 観測されたレスポンスの差分や意図したレスポンスに基づいて、各レプリカで等しくなるようにレスポンスを変換する変換関数を実装します。
- このタイプのリクエストに対するサーバーのレスポンスの最大サイズを決定して、
max_response_bytes
パラメータにそれを入力します。これは API コールでよく機能し、Cycle に関してリクエスト側の Canister を過負荷しないようにすることが重要です。レスポンスサイズがかなり動的に変化する場合は、HEAD
リクエストタイプを使用して、これを行うことができます。 - リクエストを実装して、ローカル SDK 環境で試してみてください。ただし、ローカル環境にはレプリカがひとつしかなく、IC のサブネットには 、たとえば のレプリカがあるので、ローカル環境の動作が IC の動作に反映されないことに注意してください。
ヘッダーには、タイムスタンプなどの可変項目が含まれていることがあり、レスポンスがコンセンサスを通過するのを妨げる可能性があるため、レスポンスの可変部分を特定する際には、レスポンスヘッダーを考慮することを忘れないでください。
変換関数
変換関数の目的は、レプリカ が受信した各レスポンス を変換することであり、異なるレプリカが受信した は異なる場合があります。この変換関数は、IC コンセンサスの一部としてレスポンスに合意できるように、誠実なレプリカのすべての が等しくなることを意図して、レスポンス を変換されたレスポンス に変換するものです。変換関数は Canister のプログラマーによって提供されなければならず、Canister によってクエリとして公開されます。Canister は任意の数の変換関数を定義することができます。マネージメント Canister に http_request
を呼び出す際に、オプションで変換関数を入力として提供することができます。HTTP リクエストの目的に応じて、変換関数の書き方はさまざまです。
- 興味のある情報項目のみを抽出する。これは、例えば、 Canister に転送される日付と資産価格からなるペアのリスト、または単一の資産価格とすることができます。この方法は、Canister で HTTP レスポンス全体を必要とせず、特定の情報項目のみを必要とする場合に有効です。
- リクエストの可変部分をすべて個別に削除し、残りの部分をすべて保持する。その後、Canister は関連情報を抽出します。これは、Canister が HTTP リクエストの構造とヘッダをまだ必要とする場合に便利です。
私たちは、複数の利点があるため、可能な限り最初のアプローチを行うことをお勧めします。価格設定や他の多くの API への呼び出しは、ほとんど最初のアプローチで動作するはずです。
- 結果として得られるレスポンスはより小さいサイズになります。
- 変換関数はより速く計算されるかもしれません、つまり、関数(クエリ)はより少ない CPU Cycle で実行されます。IC のクエリは現在無料ですが、将来的には有料になる可能性があることに注意してください。
- 変換関数は、例えば、レスポンス・ボディに対する単純な、あるいはいくつかの単純な Json 操作によって、容易に実装することができます。
エラーとデバッグ
この機能を使用する際に起こりうるエラーケースは数多くあります。最も重要なものを次に挙げます。
- SysFatal - Url needs to specify https scheme: この機能は現在、HTTPS 接続のみを許可しており、プレーン HTTP を使用するとエラーになります。
- SysFatal - Timeout expired: リクエストは、タイムアウト期間内に実行されない場合、タイムアウトします。これが起こる重要な例のひとつは、コンセンサスを得るために十分な数の等しいレスポンスがないときです。これは、例えば、変換関数が応答のすべての可変部分を考慮に入れて正確に書かれていないときに起きます。
- SysTransient - Failed to connect: error trying to connect: tcp connect error: Connection refused (os error 111): このエラーは、相手サーバーとの TCP 接続が確立できなかったことを示します。
- CanisterReject - http_request request sent with 0 cycles, but ... cycles are required: 少なくとも必要な量の Cycle が、サブネットで満たされるために要求と共に送信される必要があります。
- CanisterReject - max_response_bytes expected to be in the range [0..2097152], got …: このエラーは、サーバーから受信したネットワークレスポンスが大きすぎることを示します。これは、応答サイズが過小評価され、
max_response_bytes
の値が低く設定された場合に発生します。 - SysFatal - Transformed http response exceeds limit: 2045952: このエラーは、変換されたレスポンスサイズの制限に達したことを示します。これは現在、HTTPS アウトコール機能のハードレスポンスサイズ制限です。レスポンスサイズは、レスポンスボディとヘッダーに基づいて計算されることに注意してください。
この機能を初めて使う開発者は、最初のうちはある種の問題にぶつかる可能性が高く、それは以下のエラーのいずれかとして具体化されます。この機能を使い始める際に、最も顕著であると思われる問題を列挙します。
- IC では通常のアプリケーションのサブネットで 個のレプリカが動作するのに対し、ローカル環境では 個のレプリカが動作するため、ある特定のタイプの Canister HTTP リクエストがローカルの dfx 環境では動作しても、IC では動作しない可能性があります。このような問題は、このような呼び出しを開発する際、特に開発者がその機能を扱うのに必要な経験をまだ積んでいない場合に予想されます。ここで予想される主な問題は、変換関数の不足または問題です。なお、dfx 環境と IC へのデプロイの違いは、dfx 環境の動作に起因するものであり、すぐに変わるものではありません。dfx 環境は、ローカルにひとつのレプリカを実行し、エンジニアリングプロセスにおけるすべての長所と短所を伴います。
- タイムアウトを受信する:HTTP サーバーから返されたリクエストが、機能で要求されるように “同様” でない場合、これは変換関数のエラーが原因である可能性が高いです。つまり、変換されたレスポンスは、合意を得るために十分に多くの正直なレプリカでまだ等しくないため、IC ブロックにレスポンスが追加されることはありません。最終的には、タイムアウトにより、この HTTP アウトコールに関連するすべてのアーティファクトが削除されます。この問題は、サービスに対して行われた複数のリクエストを差分し、変換関数が変換結果の変数部分を保持しないようにすることで、最も効果的にデバッグできます。
- リクエストがあまりにも多くの Cycle を消費する:Canister HTTPS アウトコールは Cycle が課金されます。しかし、かなり小さなレスポンスのリクエストが頻繁に非常に大きな Cycle を消費する場合、おそらく原因は
max_response_size
パラメータがリクエストに設定されていないことです。この場合、システムは最大応答サイズである MB を想定し課金します。このパラメータには常に、実際に期待される最大応答サイズにできるだけ近い値を設定し、少なくとも同程度の大きさで、それより小さい値でないことを確認してください。max_response_size
パラメータはボディとヘッダの両方で構成され、Canister への最終的なレスポンスではなく、サーバーからのネットワークレスポンスを参照します。
価格
IC の他の機能と同様に、Canister HTTP アウトコール機能は、使用時に課金されます。現在の価格設定は、HTTP リクエストに対して M Cycle の基本料金に加え、リクエスト 1バイトと max_response_bytes
バイトごとに K Cycle を課金するよう定義されています。リクエストごとの固定コストと、ヘッダーなどによる HTTP リクエストのオーバーヘッドのため、アプリケーションの観点から実行可能であれば、より小さなリクエストを多数回行うのと同じ情報を取得するために、より大きなレスポンスを持つより少ないリクエストを行うことがコストの観点から有利です。呼び出しで提供される Cycle は、リクエストのコストをカバーするのに十分でなければならず、過剰な Cycle は呼び出し元に返されます。
現在の価格設定はかなり保守的(高価)であると定義されており、価格は今後、価格モデルの更新が導入されることで変更される可能性があります。しかし、ファイナンス API への問い合わせに使用されるような小さなレスポンスを伴う HTTP アウトコールは、USD セントの端数しかかからず、ほとんどのブロックチェーンでオラクルがコールする際に課される手数料よりも大幅に安いということは述べておきましょう。
コミュニティへの貢献
ドキュメントにまだ記載されていない問題が発生した場合、またはエンジニアがより効果的にこの機能を使用できるようなドキュメントの改善案がある場合は、forum topic でお知らせください。