新着:HeliusがLight Protocolを買収
SolanaのPreconfirmationsとは?
ブログ/開発

SolanaのPreconfirmations(Preconfs)とは?

Developer Experience EngineerXの0xIchigoLinkedInの0xIchigoGitHubの0xIchigo
読了時間:15分

Preconfirmations(preconfs)は、トランザクションがSolanaに取り込まれようとしていることを示す、最も早く利用可能なシグナルです。preconfirmationは、ブロックリーダーがトランザクションを実行し、その結果がローカルで判明した瞬間に発行されます。これは、結果がエントリに記録され、shredに分割され、ネットワーク全体に伝播される前です。Preconfirmationsを利用すると、開発者はshredストリームより1段階早く、あらゆるRPCコミットメントレベルより数段階早くトランザクションを観測できます。

一般的なアプリケーションがトランザクションのステータスを把握する流れを考えてみましょう。ほとんどの場合、processedコミットメントに達して初めて把握します。つまり、トランザクションが実行され、shredにまとめられ、Turbineを通じてブロードキャストされた後です。

レイテンシに敏感なシステムでは、shredを直接取得し、バリデータ間で交換される生データからトランザクションを再構築することで、このプロセスを高速化してきました。

Preconfirmationsは、観測地点をさらに1段階上流へ移します。トランザクションの実行結果がすでに判明し、各preconfirmationにトランザクションステータスが含まれている一方で、ブロックデータはまだリーダーのマシンから出ていない時点です。これより前には観測可能なものは存在しません。実行前のトランザクションは、キューで待機する何千もの候補の1つにすぎないためです。

このシグナルが具体的にどこから生まれ、パイプラインのそれ以前の段階ではなぜストリーミングできないのかを理解するには、スロット中にリーダー内部で何が起きるかを順に見ていく必要があります。

リーダー内部におけるトランザクションのライフサイクル

以下では、Preconfirmationsと可観測性に関係する範囲に絞り、リーダー内部のトランザクションライフサイクルを説明します。Solanaにおけるトランザクションのライフサイクル全体については、Solana Virtual Machine(SVM)の技術概要をご覧ください。

リーダーに届く前

Solanaでは、署名済みトランザクションはブロック生成者(リーダー)と次のリーダー候補へ直接送信されます。トランザクションはQUIC経由で到着します。接続容量はステーク加重で割り当てられるため、ステーク接続を介して中継されたトランザクションは、高負荷時にも受け入れられる可能性が大幅に高くなります。

この時点でトランザクションを確認できるのは、送信者と、現在および今後のリーダーへ中継しているRPCノードまたはトランザクション到達サービスだけです。

この段階では、トランザクションが最終的にどうなるかは何も分かりません。

ステージ1:取り込みとSigVerify

リーダーのTransaction Processing Unit(TPU)は、受信トランザクションをパケットとして受け取り、デシリアライズし、署名を検証して、重複を破棄します。高負荷時には、不正なパケットやスパムトランザクションが、それ以上のリソースを消費する前に破棄されます。

取り込まれてSigVerifyステージの署名検証を通過したトランザクションも、まだ単なる候補です。各スロットには何千もの候補トランザクションが到着し、その多くはブロックに入りません。

この段階のトランザクションをストリーミングしてもノイズを流すだけなので、意味のある可観測性はありません。

ステージ2:スケジューラ

ブロック生成はBanking Stageで行われます。Agave 1.18以降、その中核となっているのが中央スケジューラです。保留中の全トランザクションを把握する単一のスケジューリングスレッドが、実行ワーカーのプールへ処理を割り当てます。全体のコンテキストを持つ単一スレッドを使うことで、共有キューを奪い合うn個のスレッドよりもロック競合を大幅に減らしながらブロックを構築できます。

スケジューラは、基本的にトランザクションを次の3つの主要ステップで処理します。

1. バッファリングと優先順位付け

受信トランザクションは、スケジューラの受信およびバッファコンポーネントに入ります。そこで各トランザクションの優先順位とコストが計算され、優先順位順のコンテナに挿入されます。

この時点でも、トランザクションは何千もの「候補」の1つにすぎません。より優先順位の高い処理でバッファが埋まれば、排除される可能性があります。

2. スケジューリング

スケジューラのコントローラ内の制御ループは、コンテナから最も優先順位の高いトランザクションを繰り返し取り出し、アカウントロックの競合を確認して、実行用のバッチにまとめます。

Agave 2.3以降、採用されているスケジューリングアルゴリズムはgreedy schedulerです。テストでgreedy方式のほうが少ないオーバーヘッドでブロックを構築できることが示されたため、以前のprio-graph設計に代わって導入されました。

3. ディスパッチ

スケジュールされたバッチは、チャネル経由で実行ワーカーへ送られます。この時点でリーダーは、ワーカースレッド、アカウントロック、構築中のブロック内の枠といった実リソースを、その特定のトランザクションに割り当てています。

この時点でも、トランザクションは保留中です。リーダーは実行する予定ですが、まだ何も実行されていないため、報告できる結果はありません。Preconfirmationsはその次のステップで生成されます。

FiredancerのスケジューラアーキテクチャはAgaveとどう違いますか?

Firedancerも、わずかに異なるアーキテクチャを通じて同じ時点に到達します。Firedancerでは、メモリを共有するスレッドの代わりに、共有メモリキューで接続された分離型タイルが動作し、スケジューリングロジックはpack tileに置かれています。

pack tileは保留中の全トランザクションを保持し、各bank tileが現在保持しているアカウントを追跡します。そして競合がなく、手数料を最大化するトランザクションを選択してマイクロブロックにまとめ、実行のためにbank tileへ渡します。

ここでも同じ引き渡しが行われます。選択されたトランザクションはパッキングロジックから実行ユニットへ送られ、そこで結果が決まります。

ステージ3:実行

Agaveのワーカー、またはFiredancerのbank tileは、スケジュールされたトランザクションバッチを現在のbankに対して実行し、アカウントを読み込み、プログラムを実行して、その結果をコミットします。

スケジュールされたトランザクションがさまざまな理由で失敗する可能性があるのも、この段階です。残高不足、プログラムエラー、リバートを引き起こすスリッページチェック、その他のランタイム条件などが含まれます。いずれの場合も、この時点で結果はリーダーのマシン内にのみ存在します。

この瞬間にpreconfirmationが発行されます。リーダーは各トランザクションが実行された瞬間に、そのステータスとともにストリーミングします。これは結果がエントリに記録される前であり、ブロックデータがマシンを離れるよりはるかに前です。

トランザクションのライフサイクル全体で、その結果が存在し、かつ報告可能になる最初の瞬間です。実行より上流には、ストリーミングできる結果を持たない保留中の候補プールしかありません。下流では、その情報はすでにブロックへ格納され、ネットワーク全体へ向かっています。

したがって、この種の早期シグナルが存在できるのは実行時点だけです。すべてのpreconfirmationが予測ではなく、トランザクションの実際の結果を伝えるのはこのためです。

ただし、preconfirmationからは、そのトランザクションを含むブロックが正規チェーンに採用されるかどうかまでは分かりません。そのブロックはまだshredに分割されておらず、伝播も投票もされていません。

そのため、Preconfirmationsは保証ではなくシグナルです。

ステージ4:Proof of Historyとエントリ

実行済みバッチはProof of Historyストリームに記録され、エントリが生成されます。エントリは、リーダーの検証可能なクロックに組み込まれた、ハッシュ化済みトランザクションのまとまりです。エントリは台帳のネイティブ形式ですが、この時点ではまだリーダーのマシン内にしか存在しません。

リーダー以外から見た可観測性は、実質的にゼロです。

なお、RotorとVotorによってSolanaの分散型クロックが不要になるため、AlpenglowアップデートでProof of Historyは廃止されます。Preconfirmationsのモデルには影響しません。リーダーは引き続きトランザクションを配信前に実行するため、最も早く観測できるシグナルは、リーダーのローカルな実行結果のままです。

ステージ5:shred化とブロードキャスト

エントリは、損失耐性のために消失訂正符号化されたMTUサイズの断片であるshredに分割されます。これらのshredは署名され、Turbineのステーク加重ツリーを通じてブロードキャストされます。

ここで可観測性が一気に開かれます。shredは特定のブロックについてリーダーのマシンを離れる最初の生成物です。そのため、shredストリームを含むSolana上の他のあらゆる早期データプロダクトはここから始まります。shredからトランザクションを再構築する方法は、RPCコミットメントレベルと比べれば高速です。しかし、shredが存在する前にリーダーはトランザクションを実行しているため、preconfirmationと比べれば遅くなります。

この後は、バリデータによるブロックのリプレイと投票が続き、トランザクションはprocessed、confirmed、finalizedの各コミットメントレベルを進んでいきます。

Preconfirmationsはレイテンシの階層のどこに位置しますか?

Preconfirmationsは、rawおよびデコード済みshred、LaserStream、その他のデータストリーミング方式を含む、Solana上のあらゆるシグナルの中で最速です。

ただし、preconfsはレイテンシの階層の1段として捉えるのが適切です。各段階では、より早い観測と引き換えに、完全性や確実性の一部が失われます。

早いものから遅いものへ並べると、次のようになります。

シグナル観測されるステージ提供内容トレードオフ
Preconfirmationsリーダー内部の実行済みトランザクションブロックデータがマシンを離れる前、結果が存在した瞬間にストリーミングされるリーダーの実行結果完全な実行メタデータはなく、ステータスのみ。ブロックは未確認。カバレッジは転送するバリデータに依存
Shred Delivery(raw)リーダーから送出されるshredネットワークの大部分に届く前のブロックのraw断片shredの再構築ロジックが必要。実行メタデータなし
Preprocessed Transactions再構築およびデコードされたshredprocessedトランザクションより約8ms早い署名済みトランザクションをWebSocket経由で提供実行メタデータなし
LaserStreamprocessed、confirmed、finalized実行結果を含む完全なトランザクションデータ。リプレイ可能ブロックはすでに伝播済み
WebSocketsprocessed、confirmed、finalizedシンプルなインターフェースによるフィルタリング済みトランザクションストリームトランザクション情報の受信は最も遅い部類。レイテンシより利便性を重視した設計
RPCポーリングconfirmed、finalized確実性情報を得る最も遅い方法

この表から、2つのことが分かります。

まず、これらのシグナルは互いを直接置き換えるものではなく、すべて補完関係にあります。

たとえば、Preconfirmationsはネットワークが把握する前にリーダーが実行した内容を報告します。一方、LaserStreamからのメッセージは、何が起きたかを完全なメタデータとともに示します。

本番システムでは通常、両方を利用する必要があります。Preconfirmationsに基づいて動作し、下流のシグナルを検証に使用します。

次に、各段階の差は均一ではありません。

processedストリームからshredへ移ることで短縮できるのは1桁ミリ秒です。一方、shredからPreconfirmationsへ移ると、観測地点がブロックで最初に公開される生成物からリーダー内部にしか存在しない結果へ変わるため、ブロック生成パイプラインの残り、つまりエントリ記録、shred化、伝播を省略できます。

その結果、Preconfirmationsはshredより約5〜50ミリ秒高速です。

Preconfirmationsの信頼モデル:保証ではなくシグナル

preconfirmationが約束する内容は、1つの文にまとめられます。「リーダーがこのトランザクションをこの結果で実行した」ということです。preconfが約束しない内容も、同じ文から導かれます。

実行済みトランザクションは、まだ取り込み済みのトランザクションではありません。つまり、それを含むブロックはまだshred化、伝播、投票されていません。このブロックは、ネットワークに確認される前にスキップされたり、フォークから外れたりする可能性があります。preconfirmation済みトランザクションのほぼすべては、オンチェーンに正常に取り込まれます。ただし、Preconfirmationsに基づいて動作するシステムは、結果を最終的なものとして扱う前に、他の可観測性チェックで確認する必要があります。

カバレッジも設計上、部分的です。Preconfirmationsが存在するのは、そのスロットのリーダーがスケジュール済みトランザクションのストリームをHeliusへ転送する場合に限られます。そのため、カバレッジは参加するネットワークステークの割合に応じて拡大し、ストリームが常に連続するとは限りません。

サービスが継続的なカバレッジを絶対条件として必要とする場合は、ギャップの発生時にLaserStreamまたはShred Deliveryへフォールバックすることを検討してください。

Preconfirmationsは実行後に発行されるため、サブスクライバーが確認するのは、すでに結果が決まったトランザクションです。悪用を待つ保留中のオーダーフローではありません。つまり、そのトランザクションにブロック内で先回りする余地は、すでになくなっています。これは、早期の可視性を提供することと、スケジュール前のオーダーフローを漏洩することの決定的な違いです。前者ではサブスクライバーがネットワークの他の参加者より早く反応できますが、後者ではストリーミングされているトランザクションそのものに対して不利な行動を取れてしまいます。Preconfirmationsは厳密に前者です。

このシグナルは、その性質を正確に示しています。preconfirmationを裏付ける経済的コミットメントはなく、そのような保証も主張していません。リーダーはローカルな結果を報告しますが、その後の履行に何かをステークするわけではありません。Preconfirmationsが対象とする戦略にとって、これは適切なトレードオフです。

たとえば清算ボットに必要なのは、トランザクションが取り込まれることを絶対的かつスラッシュ可能な形で保証する約束ではありません。競合より数ミリ秒早く、そのトランザクションの結果を知ることです。

Helius Preconfirmationsの仕組み

Helius Preconfirmationsは、単一のWebSocketサブスクリプションで配信されます。クライアントはGatekeeperエンドポイント(wss://beta.helius-rpc.com)に接続し、preconfSubscribeリクエストを送信できます。

preconfSubscribe Request
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "preconfSubscribe",
  "params": [
    {
      "failed": false,
      "regionInclude": ["ewr", "fra"],
      "accountInclude": ["TARGET_WALLET_ADDRESS"],
      "accountExclude": [],
      "accountRequired": []
    }
  ]
}

フィルターはサーバー側でアカウント(include、exclude、required)、リージョン、ステータスに対して適用され、ルックアップテーブル(LUT)にも対応しています。そのため、サブスクライバーが受信して料金を支払うのは、自身の戦略に関連するスケジュール済みトランザクションだけです。

Preconfirmationsは実行後に発行されるため、ステータスフィルターは実際の結果に対して機能します。failed: falseとなり、失敗したトランザクションはストリーミングも課金もされません。

料金はクレジットベースで、他のHelius WebSocketサブスクリプションと同じく1メッセージあたり10クレジットです。ストリーミングされるトランザクションごとに1メッセージが送られ、Professional以上のプランで利用できます。

その後、フィルターに一致する各スケジュール済みトランザクションが、コンパクトなバイナリフレームとして届きます。具体的には、トランザクションのバージョン、スケジュールされたスロット、スロット内のトランザクションインデックス、ステータスを含む固定18バイトのヘッダーに、完全なトランザクションバイト列が続きます。

この形式が意図的に簡素なのは、固定ヘッダーならホットパスでJSONを解析することなく、ナノ秒単位でデコードできるためです。このやり取りで必要なJSONは、利便性のためのサブスクリプション確認応答だけです。

なお、preconfirmationは取引の片側にすぎません。トランザクションを最初に確認できても、レスポンスが最初に到達しなければ意味がありません。そこで、Helius Senderで最高性能のティアとなるSender Maxも提供しています。

Sender Maxは、送信内容(単一のトランザクション、または最大4つのトランザクションからなるアトミックバンドル)を、利用可能なすべての高速経路へルーティングします。さらに、チップが高いものを優先するpriority tip bufferに投入します。最小チップは0.001 SOLです。

preconfSubscribeでシグナルを取得し、Sender Maxでトランザクションを到達させます。

Preconfirmationsで何を構築できますか?

トランザクションの結果が決まってから観測されるまで、1ミリ秒経過するごとに利益が減少する戦略は、すべてpreconfsの恩恵を受けます。これには、以下のユースケースが含まれますが、これらに限定されません。

スナイピング

新しいプールの作成やトークンのローンチは、デプロイトランザクションがリーダー内部で実行された瞬間に確認できます。Preconfirmationsを利用するスナイパーは、shredを監視する参加者がブロックの最初の断片を待っている間に反応できます。

コピートレード

対象ウォレットの動きは、リーダーが実行した瞬間にpreconfirmationストリームへ現れます。accountIncludeを使って対象アドレスでフィルタリングすると、ストリームを専用のミラーフィードとして利用でき、他のコピートレーダーより早く動きを把握できます。

清算

ポジションを債務超過にするオラクル更新は、実行された瞬間に把握できます。その時点で検知する清算ボットは、shredやprocessedコミットメントを監視するボットよりもパイプライン全体を先行して開始できます。そのため、Preconfirmationsは清算処理で極めて重要です。

マーケットメイキングとpropAMMs

実行時点で着信フローを確認できるため、propAMMsやその他のクオートシステムは、そのフローが公開される前に価格を更新したり、古いクオートを取り下げたりできます。

いずれの場合も、Preconfirmationsは戦略の反応時点を「ネットワークが把握した後」から「リーダーが実行した瞬間」へ移します。

Preconfirmationsの転送で収益を得る

Preconfirmationのカバレッジは、供給側にバリデータが存在するネットワーク効果です。どのバリデータも自身のストリームをHeliusへ転送し、その対価として収益を得られます。これにより、ブロック生成の副産物を、バリデータが自身のポジションを他の方法で収益化しているかどうかにかかわらず存在する収益源へ変えられます。

参加するステークが増えるほど、カバレッジも広がります。参加を希望するバリデータは、お問い合わせのうえ、バリデータ向けPreconfirmationsドキュメントをご覧ください。

EthereumのpreconfsとSolanaのpreconfsの違いは?

EthereumのPreconfirmationsは、トランザクションが将来のブロックに取り込まれることを保証する提案者のコミットメントです。一方、SolanaのPreconfirmationsは、現在のブロックについてリーダーがローカルで実行したばかりのトランザクションを伝える、リアルタイムのオンチェーントランザクションシグナルです。前者の目的は早く確定を知ることであり、後者の目的は早く観測することです。

EthereumのPreconfirmations

EthereumのPreconfirmationsは、研究文献ではbased preconfsと記されることが多く、2023年にJustin Drakeが初めて明確に提唱した設計です。これは、取り込みに関するコミットメントです。提案者は自身のスロットより前に、トランザクションを将来のブロックへ取り込むことを約束し、その約束はスラッシングなどの経済的メカニズムで裏付けられます。

すでに稼働している実装が複数あります。

  • PrimevのMEV-Commit:ウォレット、サーチャー、インテントプロトコルが、コミットメントを得るために実行プロバイダー(ブロックビルダーやシーケンサー)へ入札するマーケットプレイス
  • ETHGas:経済的な裏付けを持つpreconfirmationネットワーク
  • ChainboundのBolt:パーミッションレスでMEV-Boost互換の提案者コミットメントを提供

特に重要なのは、EthereumのPreconfirmationsが次の性質を持つことです。

  • 自分自身のトランザクションが対象
  • 実行前に発行
  • 確実性を重視

EthereumのPreconfirmationsは、実際に取り込まれる前に、トランザクションが取り込まれることを保証します。

Ethereumでこの仕組みが必要なのは、ブロックの構築方法に理由があります。ほとんどの提案者は、MEV-Boostを通じてブロック構築を直前にオークションへ出します。そのため、オークションが決着するまで、ブロックについて信頼できる約束はできません。一方、Solanaにはこの空白がありませんでした。リーダースケジュールは事前に判明しており、mempoolは存在せず、単一のリーダーがスロット内で継続的にブロックを受信、順序付け、実行、ストリーミングします。Ethereumが経済的な仕組みを構築して生み出す必要がある早期シグナルは、Solanaのブロック生成パイプラインに元から存在していました。必要だったのは、それを外部へ公開することだけです。

SolanaのPreconfirmations

SolanaのPreconfirmationsは、将来の約束ではなくリアルタイムのオンチェーンシグナルです。リーダーは、トランザクションがネットワークの他の部分へ伝播する前に、すでに実行したトランザクションを報告します。

特に重要なのは、SolanaのPreconfirmationsが次の性質を持つことです。

  • すべての人のトランザクションが対象
  • 実行後に発行
  • レイテンシを重視

SolanaのPreconfirmationsを使うと、実行済みトランザクションを、shredや標準的なコミットメントレベルのRPCリクエストを通じてネットワーク全体から観測できるようになる数ミリ秒前に確認できます。

Ethereumのブロックスペース予約型preconfirmationに最も近いSolana上の仕組みは、Raikuが提供するAhead-of-Time(AOT)Transactions向けのコンピュートユニットマーケットプレイスです。アプリは将来のブロックへの確実な取り込みを予約できます。

まとめ

Solana上のすべてのトランザクションには、その行方が不明から確定へ変わる瞬間が1度だけあります。リーダーが実行する瞬間です。Preconfirmationsは、その瞬間をネットワークの他の参加者が確認できるようになる前にストリーミングします。Preconfirmationsがレイテンシの階層でshredより上に位置するのは、ブロックの公開生成物ではなく、リーダーの実行結果を観測するためです。ブロックはネットワークによって確認されるまで正規と見なされないため、Preconfirmationsは保証ではなくシグナルです。

スナイパー、コピートレーダー、清算者、マーケットメーカー、サーチャーなど、レイテンシに敏感なシステムでは、preconfSubscribeでサブスクライブし、重要なアカウントをフィルタリングし、Sender Maxでシグナルに応答して、標準的なコミットメントチェックで検証してください。

サブスクリプションの完全なリファレンス、メッセージ形式、統合例は、すべてPreconfirmationsドキュメントで確認できます。

Heliusを購読

Solana開発の最新情報や新しい記事の公開通知を受け取れます