初めまして。
CryptoGamesというブロックチェーンゲーム企業でエンジニアをしている cardene(かるでね) です!
ERCについてひたすらまとめたり、スマートコントラクトを書いたり、フロントエンド・バックエンド・インフラと幅広く触れています。
以下でも情報発信しているので、興味ある記事があればぜひ読んでみてください!
https://twitter.com/cardene777
https://chaldene.net/
https://qiita.com/cardene
https://zenn.dev/heku
https://mirror.xyz/0xcE77b9fCd390847627c84359fC1Bc02fC78f0e58
https://cardene.notion.site/ERC-EIP-2a03fa3ea33d43baa9ed82288f98d4a9?pvs=4
また、これからも情報を見逃したくないという方はぜひ以下の購読ボタンを教えてください。
更新があった時、登録しているメールアドレス宛に通知が飛ぶようになります。
今回はSolanaについての第2回の記事になります。
以下のドキュメントを参考にSolanaのRentについてまとめていきます。
https://solana.com/docs/intro
Rent
Solanaネットワークでは、トランザクションを処理するためにコストがかかります。
このコストは、トランザクションを提出する人が支払い、バリデータ(検証者)が収集します。
Solanaのアカウントには、アカウントの残高(Account::lamports
)とは別に、所有者が管理する状態(Account::data
)があります。
ネットワーク上のバリデータ(検証者)は、この状態の動作コピーをメモリ内に保持する必要があるため、このリソース消費に対して時間と容量に基づく料金を徴収します。
これが「レント」です。
Solanaではアカウントがデータ(例えば、スマートコントラクトのコードやアカウントの状態情報など)をブロックチェーン上に保存することができます。
しかし、このデータをブロックチェーン上に保存し続けるには、ネットワークのリソース(特にメモリ)を消費するため、その使用料として「レント」と呼ばれる料金が発生します。
この料金は、データを保存するために必要な空間(バイト数)と、そのデータがネットワーク上に存在する時間に基づいて計算されます。
つまり、アカウントがより多くのデータを長期間にわたって保存するほど、そのアカウントが支払うレントは高くなります。
このシステムの目的は、ネットワーク上でデータを無制限に保存することによるリソースの過剰使用を防ぎ、バリデータが効率的に機能し続けることを確保することにあります。
また、不必要なデータや利用されていないアカウントに対しては、ガーベージコレクションを通じて削除することで、ネットワークの健全性を維持します。
データが増えると、データの送信や検証にかかるコストも増えます。
この問題に対処するために、Solanaは「Storage Rent」というシステムを導入しています。
Rentとは
Solanaブロックチェーンでは、データを保存するために各アカウントから「レント(Rent)」と呼ばれる料金が徴収されます。
この料金は、時間と容量に基づいており、アカウントとそのデータをブロックチェーン上に保存させ続けるために必要です。
Solanaのクラスタ(ネットワークを構成する一群のコンピュータ)は、このデータを維持する必要があります。
クラスタについては以下の記事を参考にしてください。
Solanaのクラスタ(ネットワークを構成する一群のコンピュータ)がデータを維持する必要がある理由は以下になります。
分散化とセキュリティ
ブロックチェーンは分散型の台帳技術です。
これは、単一の中央サーバーではなく、ネットワーク上の多数のコンピュータ(ノード)がデータを共有して維持することを意味します。
この分散化により、データの透明性、安全性、および耐障害性が大幅に向上します。
Solanaのクラスタがデータを維持することで、ネットワーク全体のセキュリティと信頼性が確保されます。
一貫性と可用性
データをネットワーク全体で維持することで、どのノードからでもアクセスした場合にも同じ情報が得られるようになります。
これは、ブロックチェーンの一貫性と可用性を保証するために重要です。
ユーザーがトランザクションを実攻したり、スマートコントラクトを実行したりする時には、最新かつ正確なデータに基づいて処理される必要があります。
スケーラビリティ
Solanaは特に高いトランザクション処理速度とスケーラビリティを目指して設計されています。
データを効率的に維持し、最適化することで、高速なトランザクション確認とネットワークの拡張性を実現しています。
データを適切に維持することで、大量のトランザクションを迅速に処理し、より多くのユーザーとアプリケーションをサポートできます。
持続可能性
ストレージレントの導入は、ネットワークが不必要なデータで過負荷になることを防ぎ、持続可能性を確保します。
これにより、ノードは重要なデータのみを維持し、リソースを効率的に使用することができます。
Solanaクラスタがデータを維持する必要があるのは、ブロックチェーンネットワークがその基本的な利点(セキュリティ、一貫性、スケーラビリティ、持続可能性)を提供し続けるためです。
すべてのSolanaアカウント(そしてプログラムも)は、ブロックチェーン上に残り続けるために、レントを支払うために十分なラムポート(LAMPORT、Solanaの最小通貨単位)の残高を維持する必要があります。
アカウントがレントを支払うための十分なラムポートを持たなくなった場合、そのアカウントは「ガーベージコレクション」と呼ばれるプロセスを通じてネットワークから削除されます。
ガーベージコレクション
ガーベージコレクションは、使用されなくなったデータや不要な情報を自動的に削除し、システムのリソース(特にメモリ)を回収するプロセスです。
この概念は、プログラミング言語やオペレーティングシステムなど、コンピュータのさまざまな分野で用いられますが、ブロックチェーンの文脈ではやや異なる意味を持ちます。Solanaブロックチェーンにおけるガーベージコレクションは、レントを払うことができなくなったアカウントをネットワークから自動的に削除するプロセスを指します。
アカウントが保持すべき最低限のラムポート(LAMPORTS、Solanaの通貨単位)を下回った場合、そのアカウントとそれに関連するデータは、ネットワークのリソースを節約し、効率的に運用するために削除されます。このプロセスは以下のような理由があります。
リソースの効率的な使用
ブロックチェーンは、ネットワーク全体でデータを維持するために大量の計算リソースを使用します。
不要なデータを削除することで、これらのリソースを有効活用できます。ネットワークのパフォーマンス向上
不要なデータを定期的にクリアすることで、ネットワークの処理速度や応答性が向上します。
これにより、ユーザー体験が改善されます。持続可能性の確保
データの蓄積は、ストレージコストの増大やネットワークの運用コストの増加につながります。
ガーベージコレクションによって、ネットワークはより持続可能な運用が可能になります。Solanaにおけるガーベージコレクションは、ネットワークの健全性を維持し、長期的にスケーラブルで効率的なブロックチェーン環境を確保するために不可欠なメカニズムです。
レントはトランザクション手数料とは異なります。
レントはSolanaブロックチェーン上にデータを保存するために支払われる(あるいはアカウント内に保持される)ものです。
一方、トランザクション手数料は、ネットワーク上で指示を処理するために支払われます。
レントはあなたのデータがSolanaブロックチェーン上に保存され続けるための料金で、トランザクション手数料はそのデータを使って何かアクション(トランザクション)を起こすための料金です。
アカウントがレントを払い続ける能力を失うと、そのデータはブロックチェーンから削除されます。
Rent Rate
Solanaのレントレートは、ネットワーク全体で設定されており、主に1バイトあたり年間に必要なラムポート(LAMPORTS)の数に基づいています。
これは、Solanaブロックチェーン上でデータを保存するためのコストを示しており、データの量(バイト数)と保存期間(年)に応じて、必要なラムポートの量が決定されます。
現在、このレントレートは静的(変動しない)数値であり、「Rent sysvar」というシステム変数に保存されています。
これは、Solanaの開発者やユーザーがブロックチェーン上でデータを保存する時のコストを把握しやすくするための仕組みです。
レントの料金体系は、ネットワークがデータを継続的に保持するために必要な資源の使用量に対する費用を反映しています。
Solanaではデータをブロックチェーン上に保存するために一定の料金(レント)がかかり、その料金は保存するデータの量と期間に基づいて計算されます。
この料金はネットワーク全体で統一されたレートに基づき、そのレートは「Rent sysvar」というシステム変数によって管理されています。
Rent免除
Solanaブロックチェーンでは、ある特定残高を維持しているアカウントは「レント免除」(rent exempt)とみなされ、レント(保管料)を徴収されません。
具体的には、2年分のレント費用以上のラムポート残高をアカウントが持っている場合、そのアカウントはレントの徴収対象外となります。
この2年という期間は、ハードウェアのコストが2年ごとに約50%減少するという事実に基づいています。
この2年という期間は、ハードウェアの価格が約2年ごとに50%減少するという、「ムーアの法則」として知られている観察結果に基づいています。
ムーアの法則は、1965年にインテルの共同創設者ゴードン・ムーアによって初めて提唱されました。
彼は、集積回路(IC)上のトランジスタ数が約2年ごとに倍増し、これに伴い計算能力が向上する一方でコストは下がると予測しました。ムーアの法則は、半導体業界の成長と技術進歩を予測するための経験則として広く受け入れられてきました。
この法則により、コンピュータやその他の電子機器の性能は向上し続ける一方で、製造コストは下がり続けることが期待されています。Solanaの2年というレント免除期間は、このムーアの法則に基づいて設定されています。
つまり、ハードウェアのコストが2年ごとに50%減少することを考慮して、Solanaネットワーク上でのデータストレージのコストも時間とともに減少すると想定されています。
この考え方により、ネットワークは、技術の進歩に伴うハードウェアコストの減少を反映して、レントのコストを調整する可能性があります。この2年周期は、技術の進歩とハードウェアの価格低下を考慮に入れ、Solanaネットワーク上でのデータ保管コストを合理的に設定するための基準となっています。
これにより、ネットワークは効率的に運用され、ユーザーにとってもコスト負担が軽減されることが期待されます。
Solanaでは、エポック(一定期間)ごとにレントの支払いが行われます。Account::rent_epoch
は、アカウントから次にレントを徴収すべき時期を追跡します。
アカウントがレント免除状態にある場合、この値は更新されませんが、レント支払いが必要な場合、エポックごとにレントが差し引かれ、Account::rent_epoch
が更新されます。
新規に作成されるアカウントやプログラムは、レント免除を受けるために必要なラムポートを初期に持っている必要があります。
SolanaのRPC(リモートプロシージャコール)エンドポイントには、このレント免除に必要な推定残高を計算する機能があり、アカウント作成時にこの機能を利用することが推奨されます。
アカウントの残高が減少するたびに、そのアカウントがレント免除の条件を満たしているかどうかのチェックが行われます。
アカウントの残高がレント免除の最低閾値を下回るようなトランザクションは失敗します。
Solanaではアカウントが一定額以上のラムポートを保有していることで、そのアカウントのデータ保管料(レント)が免除されるシステムです。
これにより、アカウント所有者は一定期間データを安全に保管できると同時に、余分な費用を支払うことなくブロックチェーンの利用が可能になります。
このシステムは、ユーザーにとっても、ネットワークの持続可能性を確保するためにも重要です。
Solanaのレントシステムは、アカウントがブロックチェーン上でデータを保持するために必要な費用に関して、現在は固定されたコスト構造を採用しています。
これは、genesis(ネットワークの初期設定)時に定められたレートによって、レントのコストが決定されているということです。
つまり、今のところレントの価格は変動せず、あらかじめ定められた料金が適用されます。
しかし、将来的には、レントのコストが動的に変化するようになると予想されています。
これは、ハードウェアのストレージコストが時間とともに変動することを反映するためです。
具体的には、技術の進歩により、ストレージデバイスの製造コストが下がると、その節約分がレントの価格にも反映されることになります。
このようにして、レントの価格は下がる傾向にあります。
このアプローチの背景には、ムーアの法則やその他の技術進歩により、コンピュータハードウェアの性能が向上し、コストが減少するという長年の傾向があります。
Solanaがこの原理をレントシステムに取り入れることで、ユーザーは将来的により少ないコストでデータをブロックチェーン上に保持できるようになる可能性があります。
現在はレントの価格が固定されていますが、技術の進歩とハードウェアコストの減少に合わせて、将来的にはレントの価格も下がっていくことが期待されています。
これにより、Solanaユーザーは、より効率的かつ経済的にブロックチェーン上でデータを保持できるようになるわけです。
Storage Rent
ストレージレントには、以下の2つの支払い方法があります。
セットして忘れる (Set it and forget it)
この方法では、2年分のレントをあらかじめアカウントに預け入れることで、そのアカウントはネットワークからのレントの請求から免除されます。
この最低残高を維持することで、ネットワーク全体が流動性を減少させるメリットを享受し、アカウント所有者は自分のアカウントデータが継続的にアクセス可能であることを確信できます。
バイトごとに支払う (Pay per byte)
この方式では、アカウントが2年分のレントを前払いしていない場合、ネットワークは使用したデータの量に応じてエポック(Solanaのブロックチェーン上での一定期間)ごとにレントを請求します。
このレントは次のエポックのためのクレジットとして差し引かれ、そのレートは「genesis(初期設定)」にてラムポート(lamports、Solanaの通貨単位)で指定された「キロバイト年」あたりの値で計算されます。
具体例
あるアカウントが1KB(キロバイト)のデータを保持していて、genesisでのレートが1年あたり10ラムポートである場合を想定します。
このアカウントは、2年分のレントを保有していません。
エポックごとに、ネットワークはこのアカウントから10ラムポート(1年分のレント)を次のエポックのクレジットとして差し引きます。
もしアカウントが複数のエポックにわたってデータを保持し続ける場合、それぞれのエポックの終わりにレントが再度請求されます。
この方法では、アカウントが保持するデータ量に基づいて、より柔軟にレントを支払うことができます。
小さなデータを短期間だけ保持する場合、レントのコストを低く抑えることができます。
しかし、大量のデータを長期間保持する場合は、その分だけ多くのレントを支払う必要があります。
このシステムの目的は、アカウントがネットワーク上で使用するリソース(データの保存に必要なメモリや計算リソース)の量に応じて、公平にコストを負担させることにあります。
ある最低限のラムポート(Solanaの通貨単位)を保持している間はは、2年分のレント支払いに相当する金額です。
そのため、新しく作成されるアカウントは、このレント免除条件を満たすために十分なラムポートを持っている状態で初期化されることが一般的です。
アカウントの残高がレント免除の最低限以下(ただしゼロではない)になるようなトランザクションは失敗します。
これにより、基本的にすべてのアカウントがレント免除の状態を維持することになります。
この要件が設定される前に作成されたレントを支払うアカウントは、アカウントの残高がゼロになるか、またはレント免除状態を達成するためのトランザクションが行われるまで、引き続きレントを支払い続けます。
Solanaはアカウントがブロックチェーン上でデータを保持するためのコスト(レント)を支払うことから保護するために、レント免除制度を設けています。
この制度により、アカウントが一定のラムポートを保持している限り、追加のレントを支払う必要はありません。
そして、新しいアカウントは自動的にこのレント免除状態になるように初期化されますが、既存のアカウントは特定の条件下でレントを支払い続ける可能性があります。
つまり、このシステムは、データをネットワーク上に保持するコストを公平に分担し、またデータの保存によるネットワーク全体への負担を軽減するために設計されています。
Rent徴収タイミング
Solanaにおけるレント(保持費用)の徴収には主に2つのタイミングがあります。
トランザクションによって参照されたとき
これには、新しいアカウントを作成するトランザクション自体が含まれます。
このタイプのレント徴収は、通常のトランザクション処理の一環として実行されます。
つまり、あるトランザクションがアカウントにアクセスする時、そのタイミングでレントが徴収されるということです。
エポックごとに
これは、最近のエポックで全く参照されていない、いわゆる「古い」アカウントからレントを徴収するために存在します。
この方法では、全アカウントを参照する必要があり、レントの徴収による負荷の急増を避けるために、アカウントアドレスの接頭辞に基づいてエポック全体にわたって分散されます。
レントの徴収プロセスをエポックの全期間にわたって均等に、または計画的に分けて行います。
これにより、ある瞬間に全アカウントから同時にレントを徴収しようとした際のネットワークの負荷の急増を避けることができます。
Solanaの各アカウントは一意のアドレス(ID)を持っています。このアドレスは、一定のルールに従って生成され、特定の形式をしています。
アドレスの「接頭辞」とは、アドレスの先頭部分のことを指し、アドレスをある程度のカテゴリーに分類する役割を持ちます。
例えば、ある接頭辞を持つアドレス群は同じエポック内の特定の時点でレントの徴収対象となるかもしれません。
一方で、プロトコルレベルの処理に直接関与するアカウントには、レントの徴収が適用されません。
プロトコルレベルの処理としては以下があります。
トランザクションの検証と記録
ブロックチェーンネットワークでは、各トランザクションがプロトコルに従って有効であることが検証され、承認されたトランザクションはブロックチェーンに記録されます。
このプロセスは、ネットワーク全体で共有される公開台帳の整合性を維持するために重要です。レントの分配
Solanaのようなシステムでは、アカウントから徴収されたレントがプロトコルに定義されたルールに従って処理されます。
例えば、徴収されたレントの一部が破棄され、残りがバリデータに配分されることがあります。
これは、ネットワークの安全性を維持し、バリデータに報酬を提供するために行われます。ステーキング報酬と手数料の分配
プロトコルは、ステーキングに参加しているユーザーやバリデータに報酬を分配する方法も定めています。
この報酬は、ネットワークのセキュリティに貢献するインセンティブとして機能します。
同様に、トランザクション手数料もプロトコルに基づいてバリデータ間で分配されます。自動化されたガバナンス
一部のブロックチェーンシステムでは、プロトコル自体が投票や提案のプロセスを自動化し、システムのアップグレードや変更を管理します。
これにより、分散型の意思決定プロセスが実現されます。
これには以下のような処理が含まれます。
レント徴収の分配自体
これがレント徴収に適用されると、再帰的な処理が発生する可能性があるためです。
エポックの開始時にステーキング報酬を分配
新しいエポックの開始時に処理の急増をできるだけ減らすためです。
各スロットの終わりにトランザクション手数料を分配
これも、特定のタイミングでの処理負荷を軽減するためです。
これらのプロセスはレント徴収の範囲外ですが、操作された全てのアカウントは最終的に上記の2番目のメカニズムによって処理されます。
これにより、ネットワークは使用されていないアカウントからも公平にレントを徴収し、効率的にリソースを管理することが可能になります。
Rentの徴収処理
Solanaでのレント徴収の実際の処理についてステップごと確認していきます。
1. レントの期間
レントは、1エポック分の時間に対して発生します。
アカウントは、Account::rent_epoch
がcurrent_epoch
(現在のエポック)またはcurrent_epoch + 1
(次のエポック)を持つことになりますが、これはレントの制度によって異なります。
2. レント免除制度(Exempt Regime)
アカウントがレント免除の場合、Account::rent_epoch
は単にcurrent_epoch
に更新されます。
これは、アカウントがレントの支払いから免除されている状態を意味します。
3. レント非免除制度(Non-Exempt Regime)
アカウントがレント非免除の場合、Account::rent_epoch
と次のエポックとの差を使用して、そのアカウントが支払うべきレントの額が計算されます(Rent::due()
を通じて)。
計算で出たラムポートの小数部分は切り捨てられます。
計算されたレントはAccount::lamports
から差し引かれ、Account::rent_epoch
はcurrent_epoch + 1
(= 次のエポック)に更新されます。
レント額が1ラムポート未満の場合、アカウントに変更はありません。
4. レント支払い不能のアカウント
レントを満たすのに十分な残高がないアカウントは、単にロードに失敗します。
5. レントの分配
徴収されたレントの一部は破棄され、残りは各スロットの終わりに、トランザクション手数料と同様に、ステークウェイトに基づいてバリデータアカウントに分配されます。
6. レント徴収のプロトコルレベルでの処理
レントの徴収はプロトコルレベルのアカウント更新、例えばバリデータへのレント分配などに従って行われ、レント控除に対応するトランザクションはありません。
そのため、レントの徴収は目に見えない形で行われ、最近のトランザクションやアカウントアドレスの接頭辞に与えられた予定されたタイミングによってのみ間接的に観察可能です。
設計上の考慮点
Solanaのレントシステムに関する設計考慮事項は、ネットワークが直面するさまざまな課題に対処するためのものです。
現在の設計理念
既存の設計のもとでは、レントを支払わずに放置されるアカウントを持つことは不可能です。
すべてのアカウントは、レント免除、sysvar(システム変数)、実行可能アカウントを除き、各エポックに一度正確にレントを支払います。
これは意図的な設計選択です。
そうでなければ、誰でもNoop(無操作)命令を使って不正にレントを徴収し、レントから不当に利益を得ることができる可能性があります。
これは、特にレントのコストが変動することが予想されるため、レントを節約しようとする人にとっても不利です。
副作用
この設計選択の副作用として、定期的なレントの徴収はバリデータが古いアカウントをコールドストレージに保存し、ストレージコストを節約することを阻止します。
これはアカウントの所有者にとって不利であり、トランザクションの処理が他のものよりも長く停滞する原因となる可能性があります。
一方で、これは悪意のあるユーザーが大量のガーベージアカウントを作成し、バリデータに負担をかけることを防ぎます。
設計の全体的な結果
この設計の結果として、すべてのアカウントはバリデータの作業セットとして同じパフォーマンス特性を反映することになり、一律のレント価格構造を反映します。
アドホックな徴収
アカウントが読み込まれたりアクセスされたりした時に必要に応じてレントを徴収することが検討されましたが、この方法には問題があります。
例えば、トランザクションのために「クレジットオンリー」として読み込まれるアカウントにはレントが発生する可能性がありますが、そのようなトランザクション中に書き込み可能ではありません。
クレジットオンリー
トランザクション中にそのアカウントの残高は参照(読み取り)されるが、残高を変更する(書き込む)ことはできないという状態。
複数のトランザクションが同じアカウントの残高を同時に読み込むが、競合を避けるために同時に変更は許されない場合に使用されます。
このようにして読み込まれたアカウントにもレントが発生する可能性があるという点は問題です。
トランザクション処理の一環としてアカウントがアクセスされた場合、そのアカウントは活動していると見なされ、そのエポックのレントが適用されることがあります。
しかし、「クレジットオンリー」で読み込まれたアカウントは、トランザクション処理中に残高の更新(書き込み)ができないため、この時点でレントを直接徴収してアカウントの残高を更新することはできません。
この制約により、アカウントが頻繁にアクセスされるがレントの支払いが直接行われない場合、レントの徴収が適切に行われない状況が生じる可能性があります。
このようなアカウントは、理論的にはレントの支払いを避けることができるため、「必要に応じてレントを徴収する」というアプローチは、すべてのアカウントに公平にレントを適用するという目的に沿わない場合があります。
この問題を回避するために、Solanaは他のレント徴収メカニズムを採用しています。
システム命令によるレントの徴収
システム命令を介してレントを徴収することも検討されました。
これは自然にアクティブでステークウェイトされたノードにレントを分配し、段階的に行うことができました。
しかし、この方法はネットワークのスループットに悪影響を及ぼし、特別な処理が必要とされ、誰かがトランザクションを発行する必要があります。
このように、Solanaはレントシステムを通じて、ネットワークの公平性を保ちながら、効率的でスケーラブルな運用を目指しています。
データの永続保管方法
Solanaブロックチェーンのバリデータがどのようにしてアカウントのデータ(トランザクションによって処理された結果としての状態)を永続的に保管しているかについてまとめていきます。
永続的アカウントストレージ
アカウントのセット
これは、バリデータによって処理された全てのトランザクションの現在の計算済み状態を表します。
各バリデータは、このセット全体を維持する必要があります。
ブロックとアカウントセット
ネットワークによって提案される各ブロックは、このアカウントセットへの変更を表します。
各ブロックがロールバックポイントの可能性を持つため、これらの変更は逆転可能である必要があります。
ストレージの種類と最適化
永続的ストレージ
NVME(非揮発性メモリエクスプレス)のような永続的ストレージは、DDR(ダブルデータレートメモリ)よりも20〜40倍安価ですが、読み書きのパフォーマンスはDDRに比べてはるかに遅いです。
読み書きの最適化
読み書きのパフォーマンスの遅さを克服するために、データの読み書きは複数のストレージドライブ間で分割して並行アクセスが可能です。
この設計は、同時読み取りと書き込みを可能にするデータ構造を提案しています。
AppendVecデータ構造
書き込みはAppendVecデータ構造を使用して最適化されており、単一のライターがデータを追記しながら多くの同時リーダーへのアクセスを許可します。
アカウントインデックス
アカウントインデックスは、各フォークに追記されたアカウントの位置へのポインタを保持します。
これにより、状態の明示的なチェックポイント(固定化)が不要になります。
Solanaはデータの読み書きを最適化し、同時アクセスを可能にすることで、永続的ストレージのパフォーマンスの問題を克服しつつ、コスト効率の良い方法でアカウントのデータを保持するための工夫をしていることがわかります。
これにより、バリデータは大量のアカウントデータを効率的に管理し、ネットワークのパフォーマンスを維持できます。
AppendVec
AppendVecは、ランダム読み取りを単一のデータ追加専用ライターと同時に実行できるデータ構造です。
これは、特にデータの追加操作を高速に行いつつ、同時に多数の読み取り操作を許可する設計が特徴です。
AppendVecの容量を拡大またはリサイズする時には、排他的アクセスが必要になりますが、追記操作自体は原子的なオフセット(atomic offset)を利用して更新され、これにより同時実行管理が容易になります。
主な特徴と実装
ランダム読み取りと追記の同時実行
AppendVecは、データを追記する一方で、異なる部分のデータを同時にランダムに読み取ることができます。
これにより、データベースやファイルシステムなど、高速な読み書きが求められるアプリケーションに適しています。
メモリマップファイル
AppendVecの実体はメモリマップファイル(memory-mapped file)に基づいています。
メモリマップファイルは、ディスク上のファイルをメモリアドレス空間にマッピングし、ファイルへのアクセスをメモリ操作のように扱えるようにする技術です。
これにより、ランダムアクセスの速度が向上し、ページング(データを物理メモリとディスク間で移動すること)はOSによって管理されます。
原子的なオフセット更新
データの追記は、原子的な操作によってオフセットが更新されるため、追記が完了した時点でのみオフセットが変更されます。
これにより、追記中に他の読み取り操作が発生してもデータの整合性が保たれます。
利点
高速なデータアクセス
メモリマップファイルを利用することで、ディスク上のデータへのアクセス速度が大幅に向上します。
効率的な同時実行処理
追記と読み取りを同時に行うことができるため、多くの読み取り要求を処理するアプリケーションにおいても高いパフォーマンスを実現します。
OSによるページング管理
ページング処理をOSが担うことで、アプリケーションレベルでのページング管理の複雑さが軽減され、開発が容易になります。
AppendVecは、Solanaのような高性能を必要とする分散型システムや、大量のデータアクセスを効率的に扱いたい場合に特に有効なデータ構造です。
アカウントインデックス
アカウントインデックス(Account Index)は、Solanaネットワーク上でフォーク(分岐)された全てのアカウントを1つのインデックスで管理するために設計されたデータ構造です。
このインデックスを使って、特定のフォークにおけるアカウントのバージョンを効率的に取得できます。
基本構造
AppendVecI
アカウントデータが保存されているAppendVec(追記専用ベクタ)のID。
Fork
ブロックチェーンのフォーク(分岐点)を識別するための数値。
AccountMap
各フォークにおけるアカウントの位置(AppendVecIdとオフセット)を格納するハッシュマップ。
AccountIndex
アカウントの公開鍵(Pubkey)をキーとして、そのアカウントのAccountMapを格納するハッシュマップ。
アカウントの読み込み
特定のフォークでアカウントを読み込む時、AccountIndexはアカウントの公開鍵とフォーク番号を用いて、該当するアカウントデータの位置を特定します。
この読み込みは、メモリマップされたAppendVec内の特定の位置を指すことで実現され、データのコピーを作成せずに参照を返すことができます。
ルートフォークとスカッシュ(圧縮)
ルートフォーク
Tower BFTによって選出されたフォークがルートフォークとして確定されると、それ以前のフォークはロールバック(巻き戻し)されることはありません。
Tower BFT
Tower BFTは、Solanaブロックチェーンにおける合意形成アルゴリズムの一種で、Byzantine Fault Tolerance(ビザンチン障害耐性)を基盤としています
Tower BFTは、ネットワーク全体でトランザクションの順序を効率的に合意するために設計されており、特に高速なトランザクション処理とスケーラビリティを実現するためにSolanaに適用されています。主な特徴と仕組み
Proof of History
Tower BFTは、Solana独自のProof of Historyと組み合わせて使用されます。
PoHは、トランザクションが発生した正確な時刻を証明することで、トランザクションの順序付けと検証を簡素化し、高速化します。
これにより、各ノードがトランザクションの履歴を独立して検証でき、合意形成プロセスを迅速に進めることができます。ビザンチン障害耐性
Tower BFTは、ネットワーク内の不正行為や障害を持つノードが存在しても、正確で信頼性の高いトランザクション処理を保証するための設計がなされています。
これは、分散システムにおいて一貫性とセキュリティを確保する上で重要な要素です。フォークの選択と確定
Tower BFTでは、ネットワークにおける複数のフォーク(トランザクションの異なる履歴)から1つを選択し、それを正式なチェーンの一部として確定します。
このプロセスは、各バリデータが投票を行い、多数派の合意に基づいて行われます。
確定されたフォークは「ルートフォーク」と呼ばれ、その後のトランザクションはこのフォークに基づいて処理されます。高速なトランザクション処理
Tower BFTとPoHの組み合わせにより、Solanaは数百万TPS(トランザクション毎秒)に達する可能性があるとされています。
これにより、大規模な分散アプリケーション(dApps)や金融取引など、高い処理能力を要求される用途に適しています。Tower BFTは、Solanaが提案する革新的な合意形成アルゴリズムの一例であり、高速でスケーラブルなブロックチェーンシステムの実現を目指しています。
スカッシュ
ルートフォークが確定すると、そのフォーク以前の全てのアカウントは、インデックスを更新することで新しいフォークに統合されます。
バランスがゼロのアカウントは、インデックスから削除されます。
ガベージコレクション
フォークがスカッシュされることによって到達不可能になったアカウントは、ガベージコレクション(不要データの削除)の対象となります。
これにはいくつかの方法があり、ルートフォークのHashSetを維持したり、プルーン(枝刈り)されたフォークをインデックスから削除したり、古いルートを新しいものに移行することで、不要になったフォークを後で削除することが含まれます。
このアカウントインデックスシステムにより、Solanaはフォークされたブロックチェーンの複雑な状態を効率的に管理し、パフォーマンスを最適化しながらアカウントデータに迅速にアクセスすることが可能になります。
インデックスの回復
Solanaネットワークのバックエンドでのデータ整合性とインデックス管理の方法についてまとめていきます。
バンクスレッドとアカウントの排他的アクセス
各バンクスレッドは、アカウントデータへの追記(append)操作中にそのアカウントに対して排他的アクセス権を持ちます。
これは、データがコミットされるまでアカウントのロックを解放できないためです。
つまり、一度に一つのスレッドのみが特定のアカウントデータを変更できるということです。
バンクスレッド
Solanaブロックチェーンにおける「バンクスレッド」とは、トランザクションを処理し、アカウントの状態を更新するための仕組みです。
Solanaのアーキテクチャは非常に高速なトランザクション処理能力を目指して設計されており、その核心部分にバンクスレッドがあります。バンクスレッドの役割
トランザクション処理
バンクスレッドは、ユーザーから送信されるトランザクションを受け取り、それを検証して処理します。
これには、トランザクションの署名の検証、アカウントの残高のチェック、トランザクションによって要求される操作の実行などが含まれます。アカウントの状態更新
トランザクションが正常に処理されると、バンクスレッドはトランザクションに関連するアカウントの状態を更新します。
これには、残高の更新、スマートコントラクトの状態の変更などがあります。並列処理
Solanaはマルチスレッド処理を活用しており、複数のバンクスレッドが並列にトランザクションを処理することで高いスループットを実現しています。
この並列処理により、Solanaは他のブロックチェーンシステムと比較して非常に高速なトランザクション処理能力を持っています。トランザクションのコミット
トランザクションがバンクスレッドによって処理されると、その結果は一時的に保持され、確定(コミット)されるまでは永続的な状態にはなりません。
トランザクションが正常に終了し、すべての検証がパスした後に、その変更がブロックチェーンの永続的な記録にコミットされます。バンクスレッドは、Solanaの高速なトランザクション処理と、ブロックチェーン上での正確なアカウント管理を可能にする重要な機能です。
その効率的な並列処理と状態管理のメカニズムにより、Solanaは分散型アプリケーションや金融トランザクションなど、さまざまな用途に対応するための強力な基盤を提供します。
AppendVecファイルと書き込みの順序
AppendVecは、アカウントデータを保存するためのファイル形式です。
ただし、異なるAppendVecファイル間での書き込み操作には明示的な順序がありません。
これにより、どのデータが最新かを決定することが難しくなる可能性があります。
アトミックな書き込みバージョンカウンタ
この問題を解決するために、インデックスはアトミックな書き込みバージョンカウンタを維持します。
これは、各AppendVecへの追記ごとに一意のバージョン番号を割り当てることで、追記の順序を作成します。
アカウントがAppendVecに追記される時、その追記のインデックス書き込みバージョン番号がアカウントのエントリに記録されます。
アトミック(原子性)とは、コンピュータ科学において、一連の操作が「分割不可能」であることを意味します。
つまり、操作が完全に実行されるか、あるいは全く実行されないかのどちらかであり、途中で中断されることはありません。
アトミックな操作は、データの整合性を保つために非常に重要です。
特に、複数のプロセスやスレッドが同時に同じデータにアクセスし、変更を加える場合に、データの矛盾や不整合を避けるために使用されます。例えば、銀行口座からの送金操作では、送金元の口座から金額を引き、送金先の口座にその金額を加える必要があります。
この操作全体がアトミックである場合、送金は完全に成功するか、あるいは何らかの問題が発生した場合は全く行われないため、口座の残高が不正確になることはありません。アトミック操作は、データベースのトランザクション処理、マルチスレッドプログラミング、分散システム設計など、さまざまなコンピュータシステムの分野で広く利用されています。
アトミック性を保証することで、システムの信頼性と正確性を向上させることができます。
インデックスの回復
システムが再起動されたり、何らかの理由でインデックスが失われたりした場合、全てのAppendVecファイルは任意の順序で読み込むことができ、それぞれのフォークに対する最新の書き込みバージョンがインデックスに格納されます。
これにより、最新のアカウントデータの状態を正確に回復することができます。
この仕組みにより、Solanaは複数のバンクスレッドが同時に動作しても、アカウントデータの一貫性を保ちながら効率的にデータの更新と回復を行うことができます。
スナップショット
スナップショットについて説明します。
スナップショットは、ある時点でのシステムの状態を保存することで、後でその時点に戻ることができるようにする技術です。
これは、データのバックアップや復元、システムの安定性の確保などに役立ちます。
Solanaでは、スナップショットの取得プロセスには以下のステップが含まれます。
メモリマップファイルのフラッシュ
AppendVecの下にあるメモリマップファイル(データを格納しているファイル)をディスクにフラッシュ(書き出し)します。
メモリマップファイルとは、ファイルの内容をメモリにマッピングして、直接メモリアクセスによりファイル内容を読み書きできるようにする技術です。
フラッシュとは、メモリに一時的に保持されているデータを永続的なストレージ(例えばHDDやSSD)に書き出すことを意味します。
これにより、現在のデータの状態がディスク上に安全に保存されます。インデックスのディスクへの書き出し
アカウントのインデックス(どのアカウントがどのAppendVecファイルのどの位置にデータを持っているかを追跡する情報)もディスクに書き出されます。
これにより、スナップショット時点での全アカウントの状態に関する完全な情報が保存されます。
スナップショットにより、システムが何らかの理由で障害を起こした場合でも、最後にスナップショットが取得された時点の状態にデータを復元することが可能になります。
これは、データ損失を防ぐためや、システムの以前の状態に戻す必要がある場合に特に重要です。
Solanaのような分散型システムでは、スナップショットを定期的に取得することで、ネットワーク全体のデータの整合性と安定性を保つことができます。
パフォーマンス
Solanaブロックチェーンにおけるデータの書き込みと読み取りのパフォーマンスについてまとめていきます。
ここでのポイントは、高速なデータ処理を実現するための技術的な設計に焦点を当てています。
追記専用の書き込みが高速
SSDとNVMeの利用
Solanaでは、データの追記専用書き込みにSSDやNVMe(非揮発性メモリエクスプレス)を使用しています。
これらのストレージデバイスは、PCIまたはNVMeの帯域幅(最大約2,700 MB/s)をフルに活用して、高速なデータ追記を可能にします。
同時書き込みと読み取り
ReplayとBankingスレッド
Solanaの各リプレイ(再生)およびバンキング(取引処理)スレッドは、それぞれ独自のAppendVecに対して並行して書き込みを行います。
これにより、データの書き込みが効率的に行われます。
別々のNVMeによるホスティング
各AppendVecは、別々のNVMeデバイス上に配置される可能性があります。
これにより、データの保存とアクセスの並列性が向上します。
ブロッキングしない読み取りアクセス
各リプレイおよびバンキングスレッドは、全てのAppendVecに対する同時読み取りアクセスを持ち、書き込みをブロックすることなくデータを読み取ることができます。
インデックスのロックとパフォーマンス
インデックスの書き込みロック
インデックスの更新には排他的な書き込みロックが必要ですが、HashMapの更新における単一スレッドのパフォーマンスは秒間約1000万回の更新が可能です。
最適なスレッド数
バンキングおよびリプレイのステージでは、NVMeごとに32スレッドを使用することが推奨されます。
NVMeは32の並行読み書きアクセスに最適化されています。
Solanaは高速なデータ追記、効率的な同時読み取りと書き込み、およびスケーラブルなインデックス更新を実現するために、先進的なストレージ技術と並列処理の設計を採用していることがわかります。
これにより、ブロックチェーンネットワークとしての高いパフォーマンスとスケーラビリティを確保しています。
最後に
今回はSolanaのRentについてまとめました。
これからもSolanaについてまとめていきつつ、他のブロックチェーンやサービスについてもまとめていきます。
情報を見逃したくないという方はぜひ以下の購読ボタンを教えてください。
更新があった時、登録しているメールアドレス宛に通知が飛ぶようになります。
また、拡散もしてくれると嬉しいです🙇♂️
参考
https://docs.solanalabs.com/implemented-proposals/rent
https://docs.solanalabs.com/implemented-proposals/persistent-account-storage