Life of a Transaction
Libraトランザクションのライフサイクルをより深く理解するために、Libraバリデーターに送信されてからLibra Blockchainにコミットされるまでのトランザクションを追跡します。 次に、バリデータの各論理コンポーネントをズームインし、他のコンポーネントとの相互作用を調べます。
Client Submits a Transaction
Libra クライアントはRAWトランザクションを構築 し(T5rawと呼びます)、アリスのアカウントからボブのアカウントに10 LBRを転送します。 RAWトランザクションには、次のフィールドが含まれます。 各フィールドは、用語集の定義にリンクされています。
- アリスのアカウントアドレス
- アリスに代わって実行されるアクションを示すプログラム。
- Move bytecode(peer-to-peer transaction script.)
- スクリプトへの入力のリスト(この例では、Bobのアカウントアドレスと支払い額)。
- Gas price (in microlibra/gas units) — アリスがトランザクションを実行するためにガスの単位ごとに支払う金額。 ガスは、計算と保管に費用をかける方法です。 gas unitは、固有の実世界の価値を持たない計算の抽象的な測定値です。
- アリスがこのトランザクションに対して支払う意思のあるMaximum gas amount。
- トランザクションの有効期限。
-
Sequence number
- シーケンス番号5のトランザクションは、シーケンス番号5のアカウントにのみ適用できます。
クライアントは、アリスの秘密鍵でトランザクションT5rawに署名します。 署名されたトランザクションT5には次が含まれます。
- The raw transaction.
- アリスの public key.
- アリスの signature.
Assumptions
トランザクションT5のライフサイクルを説明するために、次のことを想定します。
- アリスとボブは、Libraブロックチェーンにアカウントを持っています。
- アリスのアカウントには110 LBRがあります。
- Aliceのアカウントの現在のシーケンス番号は5です(これは、5つのトランザクションがすでにAliceのアカウントから送信されたことを示しています)。
- ネットワークにはV1〜V100の合計100のバリデーターがあります。
- クライアントはトランザクションT5をバリデーターV1に送信します
- Validator V1は、現在のラウンドの提案者/リーダーです。
Lifecycle of the Transaction
このセクションでは、クライアントから送信されてからLibraブロックチェーンにコミットされるまでのトランザクションT5のライフサイクルについて説明します。
必要に応じて、ライフサイクルの番号付きの手順に従って、検証ノードの対応するコンポーネント間相互作用へのリンクを提供しました。 トランザクションのライフサイクルのすべてのステップに精通したら、各ステップの対応するコンポーネント間相互作用に関する情報を参照することができます。
注:このドキュメントのすべてのグラフィックの矢印は、対話/アクションを開始するコンポーネントから始まり、アクションが実行されているコンポーネントで終了します。 矢印は、読み取り、書き込み、または返されるデータを表していません。
FIGURE 1.1 LIFECYCLE OF A TRANSACTION
Accepting the Transaction
1 クライアントは、アドミッションコントロール(AC)コンポーネントがトランザクションを受信するバリデーターV1にトランザクションT5を送信します。 (クライアント→AC AC.1)
2 ACは仮想マシン(VM)コンポーネントを使用して、署名検証、Aliceのアカウントに十分な残高があることの確認、トランザクションT5がリプレイされていないことの確認などの検証チェックを実行します(AC→VM AC.2、VM.1 )
3 T5が検証チェックに合格すると、ACはT5をV1のMempoolに送信します。 (AC→Mempool AC.3、MP.1)
Sharing the Transaction With Other Validators
4 Mempoolは、メモリ内バッファにT5を保持します。 Mempoolには、アリスのアドレスから送信された複数のトランザクションが既に含まれている場合があります。
5 共有Mempoolプロトコルを使用して、V1はそのMempoolのトランザクション(T5を含む)を他のバリデーター(V2からV100)と共有し、他のバリデーターから受信したトランザクションを独自のMempoolに配置します。 (Mempool→その他の検証MP.2)
Proposing the Block
6 バリデーターV1は提案者/リーダーであるため、Mempoolからトランザクションのブロックをプルし、コンセンサスコンポーネントを介してこのブロックを他のバリデーターへの提案として複製します。 (Consensus→Mempool MP.3、CO.1)
7 V1のコンセンサスコンポーネントは、提案されたブロック内のトランザクションの順序に関するすべての検証者間の合意を調整する責任があります。 (コンセンサス→その他のバリデーターCO.2)。 提案されているコンセンサスプロトコルLibraBFTの詳細については、技術論文Libra BlockchainのState Machine Replicationを参照してください。
Executing the Block and Reaching Consensus
8 合意に達するために、トランザクションのブロック(T5を含む)がExecutionコンポーネントに渡されます。 (Consensus→ExecutionCO.3、EX.1)
9 Executionコンポーネントは、仮想マシン(VM)でのトランザクションの実行を管理します。 この実行は、ブロック内のトランザクションが合意される前に投機的に行われることに注意してください。 (Execution→VM EX.2、VM.3)
10 ブロック内のトランザクションを実行した後、実行コンポーネントはブロック内のトランザクション(T5を含む)を(履歴の)Merkle accumulatorに追加します。 これは、Merkleアキュムレーターのメモリー内/一時バージョンです。 これらのトランザクションを実行した結果(提案/推測)は、コンセンサスコンポーネントに返されます。 (Consensus→Execution CO.3、EX.1)。 「Consensus」から「Execution」への矢印は、トランザクションを実行する要求がコンセンサスコンポーネントによって行われたことを示します。 (このドキュメント全体で矢印を一貫して使用するために、データの流れを表すために矢印を使用していません)。
11 V1(コンセンサスリーダー)は、コンセンサスに参加している他の検証者とブロックの実行結果についてコンセンサスを得ようとします。 (コンセンサス→その他のバリデーターCO.3)
Committing the Block
12 ブロックの実行結果が投票のスーパーマジョリティを持つ一連のバリデーターによって合意され署名された場合、バリデーターV1のExecutionコンポーネントはブロック実行の結果を投機的実行キャッシュから読み取り、ブロック内のすべてのトランザクションを永続的にコミットします Storage。 (Consensus→Execution CO.4、EX.3)、(Execution→ Storage EX.4、ST.3)
13 アリスのアカウントは100 LBRになり、シーケンス番号は6になります。T5がボブによってリプレイされる場合、アリスのアカウントのシーケンス番号(6)はリプレイされたトランザクションのシーケンス番号(5)よりも大きいため拒否されます 。
Validator Component Interactions
前のセクションでは、ブロックチェーンの分散データベースへのサブミットからコミットまでのサンプルトランザクションの典型的なライフサイクルについて説明しました。 バリデーターがトランザクションを処理し、クエリに応答する際のバリデーターのコンポーネント間の相互作用をさらに詳しく見てみましょう。 この情報は、次の人に最も役立ちます。
- システムがどのように機能するかについての全体的なアイデアを得たい。
- Libra Coreソフトウェアに最終的に貢献することに興味がある。
説明のために、クライアントがバリデータVXにトランザクションTNを送信すると仮定します。 各バリデータコンポーネントについて、コンポーネント間の相互作用のそれぞれを、それぞれのコンポーネントのセクションの下のサブセクションで説明します。 コンポーネント間の相互作用を説明するサブセクションは、実行される順序で厳密にリストされていないことに注意してください。 インタラクションのほとんどはトランザクションの処理に関連しており、いくつかはクライアントによるクエリの読み取りに関連しています(ブロックチェーン上の既存の情報のクエリ)。
バリデータノードのコア論理コンポーネントを見てみましょう。
各セクションの最後に、Libra Coreの対応する"README"へのリンクを提供します。
Admission Control (AC)
アドミッションコントロールは、バリデーターの唯一の外部インターフェイスです。 クライアントからバリデーターへの要求は、最初にACに送信されます。
Client → AC (AC.1)
クライアントは、バリデータVXのアドミッションコントロールにトランザクションを送信します。 これは次の方法で行われます。VM::ValidateTransaction()
AC → VM (AC.2)
アドミッションコントロールは、バリデータの仮想マシン(VM)にアクセスして、不正なトランザクションを早期に拒否するためにトランザクションの予備チェックを実行します。 これは、VM::ValidateTransaction()
を介して行われます。
AC → Mempool (AC.3)
VM::ValidateTransaction()
がエラーなしで戻ると、ACはMempool:: AddTransactionWithValidation()
を介してバリデータVXのMempoolにトランザクションを転送します。 バリデーターVXのMempoolは、TNのシーケンス番号が送信者のアカウントの現在のシーケンス番号以上である場合にのみ、ACからのトランザクションTNを受け入れます(トランザクションは次になるまでコンセンサスに渡されないことに注意してください) シーケンス番号)。
AC → Storage (AC.4)
クライアントがLibra Blockchainで読み取りクエリを実行すると(たとえば、Aliceのアカウントの残高を取得するために)、ACはStorageコンポーネントと直接やり取りして、要求された情報を取得します。
Admission Control README
実装の詳細については、Admission Control READMEを参照してください。
Virtual Machine (VM)
Move仮想マシン(VM)は、Move bytecodeで記述されたトランザクションスクリプトを検証および実行します。
AC → VM (VM.1)
バリデーターVXのアドミッションコントロールは、クライアントからトランザクションを受信すると、VMでVM::ValidateTransaction()
を呼び出してトランザクションを検証します。
VM → Storage (VM.2)
ACまたはMempoolがVM::ValidateTransaction()
を介してトランザクションを検証するようにVMに要求すると、VMはトランザクション送信者のアカウントをStorageからロードし、次の検証を実行します。
- 署名されたトランザクションの入力署名が正しいことを確認します(誤って署名されたトランザクションを拒否するため)。
- 送信者のアカウント認証キーが公開キーのハッシュと同じであることを確認します(トランザクションの署名に使用される秘密キーに対応)。
- トランザクションのシーケンス番号が送信者のアカウントの現在のシーケンス番号より小さくないことを確認します。 このチェックを行うと、送信者のアカウントに対する同じトランザクションのリプレイが防止されます。
- 不正な形式のプログラムはVMで実行できないため、署名されたトランザクションのプログラムが不正な形式ではないことを確認します。
- トランザクションで指定された最大ガス量をサポートするために、送信者のアカウントに十分な残高があることを確認します。これにより、トランザクションは使用するリソースに対して支払いができます。
Execution → VM (VM.3)
ExecutionコンポーネントはVMを利用して、VM::ExecuteTransaction()
を介してトランザクションを実行します。
トランザクションの実行は、台帳の状態を更新し、結果をStorageに保持することとは異なることを理解することが重要です。 トランザクションTNは、コンセンサス中にブロックの合意に達する試みの一部として最初に実行されます。 トランザクションの順序とその実行結果について他の検証者と合意に達した場合、結果はStorageに保持され、元帳の状態が更新されます。
Mempool → VM (VM.4)
Mempoolが共有Mempoolを介して他のバリデータからトランザクションを受信すると、MempoolはVMでVM::ValidateTransaction()
を呼び出してトランザクションを検証します。
VM README
実装の詳細については、Virtual Machine READMEを参照してください。
Mempool
Mempoolは、実行待ちのトランザクションを保持する共有バッファです。 新しいトランザクションがMempoolに追加されると、Mempoolはこのトランザクションをシステム内の他のバリデーターと共有します。 「共有Mempool」のネットワーク消費を削減するために、各バリデーターは、独自のトランザクションを他のバリデーターに配信する責任があります。 バリデーターが別のバリデーターのMempoolからトランザクションを受信すると、そのトランザクションは受信者バリデーターのMempoolに追加されます。
AC → Mempool (MP.1)
- 初期検証チェックを実行した後、バリデーターのACはトランザクションをバリデーターのMempoolに送信します。
- バリデーターVXのMempoolは、TNのシーケンス番号が送信者のアカウントの現在のシーケンス番号以上である場合にのみ、送信者のアカウントのトランザクションTNを受け入れます。
Mempool → Other Validators (MP.2)
- バリデータVXのMempoolは、同じネットワーク上の他のバリデータとトランザクションTNを共有します。
- 他のバリデーターは、自分のMempoolのトランザクションをVXのMempoolと共有します。
Consensus → Mempool (MP.3)
- バリデーターVXがリーダーになると、そのコンセンサスはトランザクションのブロックをそのMempoolから引き出し、そのブロックを他のバリデーターに複製します。 これは、トランザクションの順序とブロック内のトランザクションの実行結果に関するコンセンサスに到達するために行われます。
- トランザクションTNがコンセンサスブロックに含まれていたからといって、TNが最終的にブロックチェーンの分散データベースに保持されることを保証しないことに注意してください。
Mempool → VM (MP.4)
Mempoolが他のバリデーターからトランザクションを受信すると、MempoolはVMでVM::ValidateTransaction()
を呼び出してトランザクションを検証します。
Mempool README
実装の詳細については、Mempool READMEを参照してください。
Consensus
コンセンサスコンポーネントは、トランザクションのブロックを順序付け、ネットワーク内の他のバリデーターとコンセンサスプロトコルに参加することにより実行結果に同意する責任があります。
Consensus → Mempool (CO.1)
バリデーターVXがリーダー/プロポーザーである場合、VXのコンセンサスはMempool:: GetBlock()
を介してMempoolからトランザクションのブロックを引き出し、提案を作成します。
Consensus → Other Validators (CO.2)
Xが提案者/リーダーである場合、そのコンセンサスは提案されたトランザクションのブロックを他の検証者に複製します。
Consensus → Execution, Consensus → Other Validators (CO.3)
- トランザクションのブロックを実行するために、コンセンサスはExecutionコンポーネントと対話します。 コンセンサスは、
Execution:ExecuteBlock()
を介してトランザクションのブロックを実行します(Consensus → Executionを参照) - ブロック内のトランザクションを実行した後、Executionはこれらのトランザクションの実行結果でコンセンサスに応答します。
- コンセンサスは実行結果に署名し、コンセンサスに参加している他の検証者とこの結果について合意に達しようとします。
Consensus → Execution (CO.4)
同じ実行結果に対して十分なバリデーターが投票すると、VXのコンセンサスコンポーネントは、Execution::CommitBlock()
を介して、このブロックがコミットされる準備ができていることをExecutionに通知します。
Consensus README
実装の詳細については、Consensus READMEを参照してください。
Execution
Executionの仕事は、トランザクションのブロックの実行を調整し、コンセンサスによって投票できる一時的な状態を維持することです。
Consensus → Execution (EX.1)
- コンセンサスは、
Execution::ExecuteBlock()
を介してトランザクションのブロックを実行する実行を要求します。 - Executionは、「スクラッチパッド」を維持します。これは、Merkle accumulatorsの関連部分のメモリ内コピーを保持します。 この情報は、ブロックチェーンの現在の状態のルートハッシュを計算するために使用されます。
- 現在の状態のルートハッシュは、ブロック内のトランザクションに関する情報と組み合わされて、アキュムレータの新しいルートハッシュが決定されます。 これは、データを永続化する前に行われ、検証者の定足数によって合意に達するまで状態またはトランザクションが保存されないようにします。
- Executionは投機的なルートハッシュを計算し、VXのコンセンサスがこのルートハッシュに署名し、他のバリデーターとこのルートハッシュについて合意に達することを試みます。
Execution → VM (EX.2)
コンセンサスがExecution::ExecuteBlock()
を介してトランザクションのブロックを実行するように実行を要求すると、ExecutionはVMを使用してトランザクションのブロックの実行結果を決定します。
Consensus → Execution (EX.3)
バリデーターの定足数がブロックの実行結果に同意する場合、各バリデーターのコンセンサスは、Execution::CommitBlock()
を介して、このブロックがコミットされる準備ができていることを実行コンポーネントに通知します。 実行コンポーネントへのこの呼び出しには、合意の証拠を提供する同意バリデーターの署名が含まれます。
Execution → Storage (EX.4)
Executionはその「スクラッチパッド」から値を取得し、Storage::SaveTransactions()
を介して永続化のためにStorageに送信します。 次に、Executionにより、不要になった「スクラッチパッド」から古い値が削除されます(たとえば、コミットできない並列ブロック)。
Execution README
実装の詳細については、Execution READMEを参照してください。
Storage
Storageコンポーネントは、トランザクションのブロックとその実行結果について合意されたままです。 トランザクションのブロック/セット(トランザクションTNを含む)は、次の場合にStorageを介して保存されます。
- 以下のすべてについてコンセンサスに参加している検証者の2f + 1以上の間で合意があります。
- ブロックに含めるトランザクション。
- トランザクションの順序。
- ブロックに含まれるトランザクションの実行結果。
ブロックチェーンを表すデータ構造にトランザクションを追加する方法については、Merkle accumulatorsを参照してください。
VM → Storage (ST.1)
ACまたはMempoolがVM::ValidateTransaction()
を呼び出してトランザクションを検証すると、VM::ValidateTransaction()
はStorageから送信者のアカウントをロードし、トランザクションで読み取り専用の有効性チェックを実行します。
Execution → Storage (ST.2)
コンセンサスがExecution::ExecuteBlock()
を呼び出すと、Executionは、メモリ内の「スクラッチパッド」データと組み合わされたStorageから現在の状態を読み取り、実行結果を判断します。
Execution → Storage (ST.3)
- トランザクションのブロックでコンセンサスに達すると、Executionは
Storage::SaveTransactions()
を介してStorageを呼び出し、トランザクションのブロックを保存して永続的に記録します。 これは、このトランザクションのブロックに同意した検証ノードからの署名も保存します。 - このブロックの「スクラッチパッド」のメモリ内データは、更新されたStorageに渡され、トランザクションを永続化します。
- Storageが更新されると、各トランザクションによって変更されたすべてのリソースのシーケンス番号がそれに応じて更新されます。
- 注:Libra Blockchainのアカウントのシーケンス番号は、そのアカウントから発信されたコミット済みのトランザクションごとに1ずつ増加します。
AC → Storage (ST.4)
ブロックチェーンから情報を読み取るクライアントクエリの場合、ACは要求された情報を読み取るためにStorageと直接対話します。
Storage README
実装の詳細については、Storage READMEを参照してください。