Skip to main content
メモリプールは、署名済みトランザクションとコミット済みブロックの間に立つものです。何を保持する価値があるか、ある送信者のトランザクションがどの順序で処理対象になるか、どのピアがそのトランザクションを知るか、需要が容量を超えたとき何を捨てるかを決めます。 取引ネットワークにとって、これは付随的な部品ではなく荷重を受ける構造材です。発注と取り消しのトラフィックはバースト的で、送信者が偏り、遅延への敏感さが非対称です。遅れて届く取り消しは、遅れて届く注文より悪い結果になります。以下の構造が存在するのは、単一のFIFOキューではそのどれもうまく扱えないからです。

受け入れの経路

署名済みトランザクション
検証署名 · 形式 · アカウント状態 · 送信者が支払えるか
理由を返して破棄黙って消えず、送信者に理由を返す
トランザクションストア
ピアへブロードキャスト
バッチ生成、そしてコンセンサス
検証は安価でローカルに完結するため、下流の高価なリソースは、実際に実行されうるトランザクションにだけ使われます。
拒否
受理
トランザクションは、保存される前に検証されます。検証は安価でローカルに完結します。署名、形式、アカウント状態、送信者が要求している内容の分を支払えるかどうかです。これがあるおかげで、下流の高価なリソースは、実際に実行されうるトランザクションにだけ使われます。ここでの拒否は、黙って消えるのではなく送信者に理由を返します。

トランザクションの保持方法

受理されたトランザクションは、ひとつの平坦なキューには置かれません。ストアは同じ集合に対して複数のビューを維持し、それぞれが別の問いに答えます。
受理済みトランザクションの集合五つのキューではなく、五つのビュー
アカウント別の順序この送信者の次のトランザクションはどれか
優先度インデックス全送信者の中で、コンセンサスに先に渡すべきものはどれか
有効期限インデックス期限を過ぎたものはどれか
タイムラインインデックスこのピアがまだ知らないものはどれか
パーキングロット妥当だがまだ処理対象でないものはどれか
パーキングロットは、連携バグが表面化する場所です。妥当でありながら送信者にとって次の順番ではないトランザクションは、拒否されずにここへ置かれ、前方の欠番が埋まった瞬間に処理対象になります。
パーキングロットが最も注意に値します。ある種の連携バグが表面化する場所だからです。トランザクションは、完全に妥当でありながら、その送信者にとって次の順番ではないことがあります。多くの場合、同じアカウントの先行トランザクションが到着していないか、まだコミットされていないためです。そうしたトランザクションは拒否されず、パーキングロットに置かれます。利用可能なまま保たれ、前方の欠番が埋まった瞬間に処理対象になります。したがって順序を外して送信したクライアントが経験するのは、失敗ではなく遅延です。ただし欠番を最後まで埋めないクライアントは、期限切れになるまで作業を置き去りにすることになります。 タイムラインインデックスは、ピアへの伝播を差分的にするものです。各ピアがタイムライン上のどこまで配信済みかを追跡するため、ブロードキャストはプール全体を再送するのではなく、そのピアに欠けているものだけを送ります。タイムラインは一本の列ではなくバケットに分かれており、これによって、重量級の送信者ひとりがブロードキャストの枠を独占することを防ぎます。

伝播と公平性

各ノードがそれぞれ独立にトランザクションを知るわけではありません。トランザクションを受理したノードはそれをピアへブロードキャストしますが、ピアは一律には扱われません。上流のピアが優先されるため、トランザクションはネットワーク全体へ均等に拡散するのではなく、それを処理できるバリデータのほうへ進みます。 公平性は、メッセージ単位で強制するのではなく直近の履歴に対して追跡されます。メモリプールは、どの送信者とどの種類のトラフィックが最近容量を消費したかをローリングで記録し、それをもとに次に何を処理するかを調整します。これが、あるアカウントの発注と取り消しの嵐がネットワークの残りを締め出さないようにする仕組みです。正当なマーケットメイクを不利にする、アカウント単位の厳格なレート制限を必要としません。

コンセンサスへの引き渡し

コンセンサスは、メモリプールからトランザクションを一件ずつ取り出すわけではありません。トランザクションはバッチにまとめられ、バッチはバックグラウンドでバリデータへ伝播され、各バッチは、ネットワークの十分な部分がそれを保持していると発信元が証明できるまで、受領確認を集め続けます。そこではじめて、ブロック提案がそれを参照できます。 その結果、ブロック提案はトランザクション本体ではなくバッチのダイジェストを運びます。スループットが上がっても、コンセンサスのメッセージサイズは一定のままです。コミット済みブロックも常にリプレイ可能です。その背後にあるデータは、参照される前に可用性が証明されているからです。その証明がどう作られ、どう使われるのかはIntentionBFTを参照してください。
これは、メモリプールに受け入れられることとブロックに含まれることが同じではない理由でもあります。受理され、保存され、ブロードキャストされたトランザクションは、列に入っただけです。順序づけられてはいません。トランザクションの行方は、それを含むブロックをコンセンサスがコミットするまで何も確定しません。

クライアント側で押さえること

  • 送信時の拒否は情報になります。それはトランザクションが保存される前に起きており、返される理由は、クライアント側で直せる何かを指しています。
  • 無音は拒否ではありません。トランザクションは、クライアント自身が作った欠番の後ろでパーキングロットに置かれているかもしれません。受領確認がないことを破棄と決めつけず、何を送信し、何がコミットされたかを追跡してください。
  • アカウント内の順序は意味を持ち、アカウント間の順序は意味を持ちません。同じ送信者の二つのトランザクションには、定められた順序があります。異なる送信者の二つのトランザクションは、どちらが先に送信したかではなくコンセンサスによって順序づけられます。
  • メモリプールの中で取り消しが優遇されることはありません。取り消しの優先はカーネル実行の性質であり、同じブロック内で取り消しがテイカー注文の発注より先に走るというものです。キューイングの性質ではありません。