本文共 5890 字,大约阅读时间需要 19 分钟。
对应官方文档:
为了更深入的了解Libra交易的生命周期,我们将跟踪一笔交易,从提交到Libra验证器,到使用Libra区块链处理确认交易的整个过程。然后,我们将“放大”来看验证器的每个逻辑组件及与其他组件之间的交互。
Libra客户端创建一个原始的交易(称为T~5~raw)将10个Libra Coin从Alice账户转移到Bob账户。原始交易包含以下字段,每个字段都和其词汇表定义相关联。
客户端使用Alice的私钥对事务T~5~raw进行签名。签名后的交易T5包括以下内容:
为了描述交易T5的生命周期,我们假设:
在本节中,我们将描述交易T5的生命周期,从客户端提交开始到交易在Libra区块链确认。
根据相关的情况,并在交易生命周期中的各个步骤编号,我们提供相关验证器节点及其相应组件之间的交互链接,熟悉了交易的生命周期中所有的步骤后,你可以参考每个步骤中相应组件之间的交互信息。
注意:本文档中所有图形中的箭头都表示组件之间的指向,终止于执行操作的组件上。 箭头不表示读取,写入或返回的数据。图1.1交易生命周期
1 — 客户端将交易T5提交给验证器V1,验证器V1的准入控制(AC)组件接收该交易。 (客户端→AC )
2 — AC将使用虚拟机(VM)组件执行验证检查,例如签名验证,检查Alice的帐户是否有足够的余额,检查交易T5是否未被重复广播等。(AC→VM ,)
3 — 当T5通过验证检查时,AC将T5发送到V1的内存池。 (AC→内存池 ,)
4 — 内存池将T5保存在内存缓冲区中。 内存池可能已包含从Alice的地址发送的多个交易。
5 — 使用shared-mempool协议,V1将在其内存池中与其他验证器(V2到V100)广播交易(包括T5),并将从其他验证器接收的交易放入其自己的内存池中。 (内存池→其他验证者)
6 — 由于验证器V1是提议者/领导者,它将从其内存池中提取一个交易块,并通过其共识组件将此块作为提议复制到其他验证器。(共识→内存池 ,)
7 — V1的共识部分负责根据提议的块中的交易顺序协调所有验证器之间的协议。 (共识→其他验证者)。 有关我们提出的共识协议LibraBFT的详细信息,请参阅我们的技术文章。
8 — 作为达成协议的一部分,交易块(包含T5)被传递给执行组件。 (共识→执行,)
9 — 执行组件管理虚拟机(VM)中的交易的执行。 请注意,在块中的交易已经达成一致之前,这种执行是以不确定的方式进行的。 (执行→VM ,)
10 — 在执行块中的交易之后,执行组件将块中的交易(包括T5)附加到Merkle累加器(分布式历史账本)。 这是的内存/临时版本。 执行了这些交易的(建议/推测)结果返回到共识组件。 (共识→执行,)。 从“共识”到“执行”的箭头表示执行交易的请求是由共识组件完成的。 (为了在本文档中一致使用箭头,我们不使用箭头来表示数据流)。
11 — V1(共识领导者)试图与参与共识的其他验证者就该块的执行结果达成共识。 (共识→其他验证者)
12 — 如果块的执行结果由一组具有超过多数票数的验证器达成一致后并签名了,则验证器V1的执行组件从高速缓存中读取块执行的结果并提交块中的所有交易至持久存储。 (共识→执行,),(执行→存储,)
13 — Alice的账号现在有100个Libra Coin,其序列号为6.如果T5由Bob重播,它将被拒绝,因为Alice的账号(6)的序列号大于重放的交易的序列号(5)。.
在, 我们描述了一个交易从提交到在区块链分布式数据库中确认的一个典型交易生命周期。现在让我们更深入的了解验证器组件之间的交互,验证器处理交易并响应查询。相信这些信息对以下人员最为有用:
对于我们的描述,我们假设客户端将交易TN提交给验证器VX。 对于每个验证器组件,我们将在相应组件下的子组件中描述其每个组件之间交互。 请注意,描述组件间交互的子部分未严格按其执行顺序列出。 大多数交互与交易的处理相关,少数与客户端读取查询相关(查询区块链上的当前信息)。
让我们看一下验证器节点的核心逻辑组件:
在每个部分的末尾,我们提供了Libra Core相应“README”的链接。
)
图1.2准入控制准入控制是验证器的唯一外部接口。 客户端向验证器发出的任何请求都会先转到AC。
客户端将事务提交给验证器VX的准入控制。 这可以通过以下方式完成:AC::SubmitTransaction()
.
准入控制访问验证器的虚拟机(VM)并对交易初步检查,以便尽早拒绝格式错误的交易。 这通过以下方式完成:.
一旦 VM::ValidateTransaction()
没有返回错误, AC通过Mempool::AddTransactionWithValidation().
将交易转发到验证器VX的内存池。 只有当TN的序列号大于或等于发送者帐户的当前序列号时,验证器VX的内存池才会接受来自AC的交易TN(请注意,除非交易序号是下一个序列号,否则交易无法达成共识)
当客户端对Libra区块链执行查询时(例如,为了获得Alice帐户的余额),AC直接与存储组件交互以获取所请求的信息。
有关实施细节,请参阅.
(VM)验证并执行Move字节码编写的交易脚本。
当验证器VX的准入控制从客户端接收到交易时,它会调用VM上的VM::ValidateTransaction()
来验证交易。
当AC或内存池通过VM::ValidateTransaction()
请求虚拟机验证交易时,虚拟机从存储加载交易到发送者的帐户并执行以下验证:
执行组件利用虚拟机通过VM::ExecuteTransaction()
执行交易。
这里重点要理解:执行交易不同于更新分布式账本的状态和将执行结果保存在存储中。 交易TN首先执行,但它作为在共识期间达成一致性共识的一部分来执行。 如果与其他验证节点就交易顺序及其执行结果达成了一致,那么结果就将保留在存储中,并更新分布式账本的状态。
当内存池通过共享的内存池从其他验证器接收交易时,内存池会在虚拟机上调用来验证交易。
有关实现的详细信息,请参阅。
内存池是一个共享缓冲区,用于保存“等待”执行的交易。 当新交易添加到内存池时,内存池与区块链系统中的其他验证器共享此交易。 为了减少“共享内存池”中的网络消耗,每个验证器负责将其自己的交易传递给其他验证器。 当一个验证器从另一个验证器的内存池接收到一个交易时,该交易将被添加到接收者验证器的内存池中。
当内存池从其他验证器接收到交易时,内存池会在虚拟机上调用来验证交易。
有关实现的详细信息,请参阅。
共识组件负责处理排序交易块,并通过与网络中的其他验证器一起参与来达成一致结果。
当验证器VX是领导者/提议者时,验证器VX的共识通过该方式Mempool::GetBlock()
从其内存池中提取一个交易块,并发出提议。
如果VX是提议者/领导者,则其共识将提取的交易块复制到其他验证器。
Execution:ExecuteBlock()
(参见)如果网络中有足够的验证器为同一执行结果来投票,则验证器VX的共识组件通过Execution::CommitBlock()
通知执行组件该交易块已准备好提交。
有关实施细节,请参阅.
执行组件的工作是协调交易块(区块),并维持一个通过共识协商投票的过渡状态。
Execution::ExecuteBlock()
.当共识请求执行组件使用:Execution::ExecuteBlock()
执行交易块时,执行组件使用虚拟机来确定执行交易块的结果。
如果足够(法定)数量的验证器同意该块的执行结果,那么每个验证器会一致性通过执行Execution::CommitBlock()
该执行包括了:通知其执行组件该块已准备好提交, 对执行组件的进行包括同意的签名,及为其协议提供证明。
执行组件从其“暂存器”获取值,并通过Storage::SaveTransactions()
将它们发送到存储器以实现持久存储。 执行筛选删除“暂存器”中的旧值(例如,无法提交的块)。
有关实现的详细信息,请参阅.
存储保存共识执行后的交易块及其执行结果。 在以下情况下,将通过存储一个/一组交易(包括交易TN):
有关如何将交易附加到区块链中数据结构的信息,请参阅[Merkle累加器]()。
当AC或内存池调用VM::ValidateTransaction()
来验证交易时,VM::ValidateTransaction()
从存储中加载发送人的帐户,并通过只读权限来检查交易的有效性。
当共识组件调用Execution::ExecuteBlock()
时,执行组件从存储中读取当前状态并结合内存中的“暂存器”数据来确定执行结果。
Storage::SaveTransactions()
来存储来保存交易块并永久记录它们。 同时还将存储网络中同意该交易块验证器节点的数字签名。客户端查询区块链中的信息,AC直接与存储交互以读取所请求的信息。
有关实现的详细信息,请参阅.
转载地址:http://uayai.baihongyu.com/