Life of a Transaction交易的生命周期

https://developers.libra.org/docs/life-of-a-transaction

为了更深入地了解Libra交易的生命周期,我们将跟踪一个交易从提交给Libra验证器到提交给Libra区块链的过程。然后,我们将“放大”验证器的每个逻辑组件,并查看它与其他组件的交互。

Client Submits a Transaction用户提交一个交易

Libra用户构建了一个原始交易(我们称之为Traw),将10个Libra从Alice的帐户转移到Bob的帐户。原始交易包括以下字段。每个字段都链接到其术语表定义:

  • Alice的帐户地址(account address)。
  • 一个程序,指示Alice要执行的操作。它包含:
  1. 一个Move字节码点对点的交易脚本(peer-to-peer transaction script)。
  2. 脚本的输入列表(例如,Bob的帐户地址和付款金额)。
  • Gas价格(Gas price,以microlibra/gas单位表示)——即Alice愿意为执行交易而支付的每单位gas的价格。gas是区块链中支付计算和储存费用的一种方式。gas单位是计算的抽象度量,没有固有的实际价值。
  • 最大gas数量(Maximum gas amount)—— Alice愿意为这笔交易支付的最高天然气金额。
  • 过期时间(Expiration time)——交易的过期时间。
  • 序号(Sequence number)-这里设置为 5
  1. 序列号为5的交易只能应用于序列号为5的帐户。

客户端使用Alice的私钥签署交易Traw。已签署的交易T包括:

  • 原始交易。
  • Alice的公钥。
  • Alice的签名。

Assumptions假设

为了描述交易T的生命周期,我们假设:

  • Alice和Bob在Libra的区块链上都有账户( accounts)。
  • Alice的账户上有110个Libra。
  • Alice账户的当前序列号( sequence number)为5(表示已经从Alice账户发送了5个交易)。
  • 总共有100个验证器——网络上从V到V。
  • 客户端将交易T提交给validator V
  • Validator V是当前轮的提议者/领导者。

Lifecycle of the Transaction交易的生命周期

在本节中,我们将描述交易T的生命周期,即从客户端提交到提交到Libra区块链的过程。

在相关的遵循了生命周期中编号的步骤地方,我们提供了到验证器节点的相应组件间交互的链接,如下图所示。在你熟悉了交易生命周期中的所有步骤之后,你可能想要参考每个步骤对应的组件间交互的信息。

注意⚠️: 本文档中所有图形中的箭头都起源于发起交互/操作的组件,并终止于正在执行操作的组件。箭头不表示读取、写入或返回的数据。

Facebook libra开发者文档- 3 -Life of a Transaction交易生命周期-LMLPHP

Accepting the Transaction接受一个交易

1 -客户端向validator V提交交易T, validator V的许可控制(AC)组件接收交易。(client→AC,AC.1)

2 - AC将使用虚拟机(VM)组件执行验证检查,如签名验证、检查Alice的帐户是否有足够的余额、检查交易T是否正在重播等(AC→VM, AC.2VM.1)

3 -当T通过验证检查时,AC将T发送到V的内存池mempool。(AC→Mempool ,AC.3MP.1)

Sharing the Transaction With Other Validators与其他验证器共享该交易

4 -内存池将在内存缓冲区中保存T。Mempool可能已经包含从Alice的地址发送的多个交易。

5 -使用共享内存池mempool协议,V将与其他验证器(V到V)共享其mempool中的交易(包括T),并将从其他验证器接收到的交易放入自己的mempool中。(Mempool→Other Validators ,MP.2)

Proposing the Block 提议执行的区块

6 -由于validator V是一个提议者/领导者,它将从它的mempool中提取一个交易块(包含n笔交易),并通过它的consensus组件将这个交易块作为提议proposal复制到其他验证器。(Consensus→Mempool MP.3CO.1)

7 - V的consensus部分负责协调所有验证器之间关于proposed区块中的交易的顺序。(Consensus→Other ValidatorsCO.2)。有关我们提议的共识协议LibraBFT的详细信息,请参阅我们在Libra区块链中的技术论文状态机复制(State Machine Replication in the Libra Blockchain)。

Executing the Block and Reaching Consensus执行区块并达成共识

8 -作为达成协议的一部分,交易块(包含T)被传递给执行组件Execution。(Consensus→Execution CO.3EX.1)

9 -执行组件Execution管理虚拟机(VM)中交易的执行。请注意,这种执行是在块中的交易达成一致意见之前推测进行的。(Execution→VM ex2, VM.3)

10 -在执行块中的交易之后,执行组件Execution将块中的交易(包括T)附加到Merkle累加器(Merkle accumulator,账本历史记录)。这是Merkle累加器的内存/临时版本。执行这些交易的(提交的/推测的)结果返回给共识组件consensus。(Consensus→ExecutionCO.3, ex1)。

从“consensus”到“execution”的箭头表示执行交易的请求是由consensus组件发出的。(为了在整个文档中一致地使用箭头,我们没有使用箭头来表示数据流)。

11 - V(共识领导者)试图与其他参与共识的验证者就block的执行结果达成共识。(Consensus→Other Validators CO.3)

Committing the Block 提交区块到区块链

12 -如果块的执行结果是被一系列验证器的绝对多数选票同意并签名了的,验证器V的执行组件Execution从推测执行缓存(speculative execution cache)中读取区块的执行结果,并提交区块中的所有交易到持久性存储(persistent storage)中。(Consensus→Execution CO.4EX.3),(执行→存储ex4, ST.3)

13 -Alice的账户现在有100个天秤座,它的序号将是6,即下一个要执行的交易的序列号。如果Bob重播T,将被拒绝,因为Alice账户(6)的序列号大于重播交易(5)的序号。

Validator Component Interactions验证器组件交互

在上一节中,我们描述了一个示例交易的典型生命周期,从提交到提交到区块链的分布式数据库。现在让我们更深入地研究验证器在处理交易和响应查询时的组件间的交互。这些资料对下列人士最有用:

  • 想要了解系统在幕后是如何工作的。
  • 有兴趣最终为Libra的核心软件做出贡献。

在我们的叙述中,我们将假设客户端向验证器V提交一个交易T。对于每个验证器组件,我们将在各自组件部分的子部分中描述其组件间的每个交互。注意,描述组件间交互的子部分并没有严格按照执行它们的顺序列出。大多数交互与交易处理相关,少数与客户机读取查询相关(查询区块链上的现有信息)。

让我们看看验证器节点的核心逻辑组件:

在每个部分的最后,我们提供了Libra核心(Libra Core)相应的“自述”链接。

Admission Control (AC)许可控制

Facebook libra开发者文档- 3 -Life of a Transaction交易生命周期-LMLPHP

许可控制是验证器唯一的外部接口。客户端向验证器发出的任何请求都将首先到达AC。

Client → AC (AC.1)

客户端向验证器V的许可控制提交交易。这是通过: AC::SubmitTransaction()完成的。

AC → VM (AC.2)

许可控制访问验证器的虚拟机(VM),对交易执行初步检查,以便尽早拒绝格式不正确的交易。这是通过: VM::ValidateTransaction()完成的。

AC → Mempool (AC.3)

一旦 VM::ValidateTransaction()返回没有错误,AC就通过 mempool::AddTransactionWithValidation() 将交易转发给验证器V的mempool。只有在T的序列号是大于或等于当前序列号发送方的账户中的序列号时,验证器V的mempool才会接受来自AC的交易T(注意,交易将不会通过共识,直到下一个序列号)。

AC → Storage (AC.4)

当客户端对Libra区块链执行读查询(例如,获取Alice帐户的余额)时,AC直接与存储组件交互,以获得请求的信息。

Admission Control README许可控制的自述

有关实现细节,请参阅Admission Control README

Virtual Machine (VM)虚拟机

Facebook libra开发者文档- 3 -Life of a Transaction交易生命周期-LMLPHP

Move虚拟机(Move virtual machine,VM)验证并执行用Move字节码编写的交易脚本。

AC → VM (VM.1)

当validator V的许可控制从客户机接收交易时,它调用VM上的VM::ValidateTransaction()来验证交易。

VM → Storage (VM.2)

当AC或mempool通过VM::ValidateTransaction()请求VM去验证交易时,VM从存储(storage)中加载交易发送方的帐户,并执行以下验证:

  • 检查已签名交易上的输入签名是否正确(拒绝不正确签名的交易)。
  • 检查发送方的帐户身份验证密钥是否与公钥的散列相同(对应于用于签署交易的私钥)。
  • 验证交易的序列号不小于发送方帐户的当前序列号。执行此检查可防止对发送方的帐户重播相同的交易。
  • 验证已签名交易中的程序program是否格式错误,因为格式错误的程序不能由VM执行。
  • 验证发送方帐户中是否有足够的余额来支持交易中指定的最大gas量,从而确保交易可以为其使用的资源支付费用。

Execution → VM (VM.3)

执行组件Execution通过调用函数VM::ExecuteTransaction()去使用VM来执行交易。

重要的是要理解,执行交易不同于更新账本的状态和将结果保存在存储中。首先执行一个在达成共识期间,作为区块达成协议尝试的一部分的交易T。如果与其他验证器就交易的顺序及其执行结果达成一致,则这些结果将保存在存储器storage中,并更新账本的状态。

Mempool → VM (VM.4)

当mempool通过共享mempool从其他验证器中接收交易时,mempool调用VM上的VM::ValidateTransaction()来验证交易。

VM README

有关实现细节,请参考Virtual Machine README

Mempool内存池

Facebook libra开发者文档- 3 -Life of a Transaction交易生命周期-LMLPHP

Mempool是一个共享缓冲区,它保存“等待”执行的交易。当向mempool添加新交易时,mempool与系统中的其他验证器共享该交易。为了减少“共享mempool”中的网络消耗,每个验证器负责将自己的交易交付给其他验证器。当验证器从另一个验证器的mempool接收交易时,该交易将添加到接收验证器的mempool中。

AC → Mempool (MP.1)

  • 执行初始验证检查后,验证器的AC将交易发送到验证器的mempool。
  • 验证器V的mempool仅在T的序列号大于或等于发送方帐户的当前序列号时才接受发送方帐户的交易T。

Mempool → Other Validators (MP.2)

  • 验证器V的mempool与同一网络上的其他验证器共享交易T。
  • 其他验证器与V的mempool共享其mempool中的交易。

Consensus → Mempool (MP.3)

  • 当validator V成为领导者时,它的共识组件consensus将从它的mempool中提取一个交易块,并将这个交易块复制到其他验证器。它这样做是为了就交易的顺序和块中交易的执行结果达成共识。

注意,仅仅因为一个交易T包含在一个协商一致块中,它并不保证T最终会被持久化到区块链的分布式数据库中,因为块中有些出错的交易会被丢弃。

Mempool → VM (MP.4)

当mempool从其他验证器接收交易时,mempool调用VM上的VM::ValidateTransaction()来验证交易。

Mempool README

有关实现细节,请参考Mempool README

Consensus共识

Facebook libra开发者文档- 3 -Life of a Transaction交易生命周期-LMLPHP

共识组件负责排序交易块,并通过与网络中的其他验证器参与共识(consensus protocol
)协议,就执行结果达成一致。

Consensus → Mempool (CO.1)

当验证器V是领导者/提议者时,V的共识通过: mempool::GetBlock()从它的mempool中提取一个交易块,并形成一个提议proposal。

Consensus → Other Validators (CO.2)

如果V是一个提议者/领导者,它的共识组件会将提议的交易块复制到其他验证器。

Consensus → Execution, Consensus → Other Validators (CO.3)

  • 要执行一个交易块,consensus与执行组件Execution进行交互。共识组件通过Execution:ExecuteBlock()来执行一个交易块(引用Consensus → Execution)
  • 在执行块中的交易之后,执行组件将执行这些交易的结果响应到共识组件。
  • 共识组件对执行结果进行签名,并试图与参与共识的其他验证器就该结果达成一致协议。

Consensus → Execution (CO.4)

如果有足够多的验证器投票支持相同的执行结果,V的consensus组件将通过execution::CommitBlock()通知执行组件Execution,这个块已经准备好提交到区块链中。

Consensus README

有关实现细节,请参阅 Consensus README

Execution执行组件

Facebook libra开发者文档- 3 -Life of a Transaction交易生命周期-LMLPHP

执行组件的工作是协调一个交易块的执行,并维护一个可以通过共识组件进行表决的临时状态。

Consensus → Execution (EX.1)

  • Consensus组件通过调用函数execution::ExecuteBlock()请求执行组件Execution执行一个交易块。
  • 执行组件维护一个“暂存板scratchpad”,它在内存中保存Merkle累加器(Merkle accumulators)相关部分的副本。此信息用于计算区块链当前状态的根哈希。
  • 当前状态的根哈希值与块中交易的信息相结合,以确定累加器的新根哈希值。这是在持久化任何数据之前完成的,并确保在验证器仲裁达成一致协议之前不会存储任何状态或交易。
  • 执行组件计算推测的根哈希值,然后V一致对这个根哈希值进行签名,并尝试与其他验证器就这个根哈希值达成一致协议,即确定该新状态是正确的。

Execution → VM (EX.2)

当consensus组件通过调用函数execution::ExecuteBlock()请求执行组件Execution执行交易块时,执行组件使用VM来确定执行交易块的结果。

Consensus → Execution (EX.3)

如果验证器仲裁同意块执行结果,每个验证器的共识组件将通过调用execution::CommitBlock()通知其执行组件Execution该块已准备提交。这个对执行组件Execution的调用将包括同意验证器的签名,以提供其一致协议的证明。

Execution → Storage (EX.4)

执行组件从它的“暂存板scratchpad”中获取值,并通过调用storage::SaveTransactions()将它们发送到存储区storage以进行持久性存储。然后执行组件从“暂存板”中删除不再需要的旧值(例如,不能提交的并行块)。

Execution README

有关实现细节,请参阅Execution README

Storage存储

Facebook libra开发者文档- 3 -Life of a Transaction交易生命周期-LMLPHP

存储组件保存商定的交易块及其执行结果。当下列情况发生时,一块/组的交易(包括交易T)会被存储到storage中:

  • 数量超过2f+1的验证器就下列各项达成协议:
  1. 要包含在块中的交易。
  2. 交易的顺序。
  3. 要包含在块中的交易的执行结果。

有关如何将交易附加到表示区块链的数据结构的信息,请参阅Merkle accumulators

VM → Storage (ST.1)

当AC或mempool调用VM::ValidateTransaction()来验证交易时,VM::ValidateTransaction()从存储组件storage中加载发送方的帐户,并对交易执行只读有效性检查。

Execution → Storage (ST.2)

当共识组件调用Execution::ExecuteBlock()时,执行将从存储组件和内存中的“暂存板”数据中读取当前状态,以确定执行结果。

Execution → Storage (ST.3)

  • 一旦对交易块达成共识,执行组件就通过storage::SaveTransactions()调用storage组件来保存交易块并永久记录它们。这还将存储来自同意此交易块的验证器节点的签名。
  • 该区块的“暂存板”中的内存数据被传递到更新的存储组件中并保存交易。
  • 更新存储组件时,每个交易修改的所有资源的序列号将相应地更新。
  • 注意:Libra区块链上的帐户序列号对来自该帐户的每个提交交易递增1。

AC → Storage (ST.4)

对于从区块链中读取信息的客户机查询,AC直接与存储组件交互来读取请求的信息。

Storage README

有关实现细节,请参阅Storage README

05-11 22:02