本文会以一个提交到Libra validator的transaction为例,来说解Transaction和其余组件的交互,和具体的状态变化过程。缓存
这里咱们举个例子,仍是上篇文章的例子,A拥有110LBR,B拥有52LBR。接下来会构建一个原始交易Tn,将A拥有的10LBR转给B。网络
这个原始交易将包含以下字段:区块链
A的账户地址。cdn
一个要表明A执行的动做的程序。它包含:排序
一个Move字节码表示的peer-to-peer交易脚本。教程
一个该脚本的输入列表(例如,B的账户地址和付款金额)。接口
Gas价格 -A愿意为执行交易而为每单位Gas支付的金额。Gas是一种支付计算和存储费用的方式。Gas单位是对计算的抽象度量,没有固有的实际值。生命周期
A愿意为此交易支付的最大Gas金额。事务
交易的到期时间。内存
序列号
每一个帐号的交易都有一个惟一的序列号,用来标记这个帐号发出的交易。
有了这个原始交易以后,咱们会使用A的私钥对这个原始交易进行签名,签名后的交易包含以下内容:
咱们假设这个Libra区块链上面有100个validators, 咱们用V1到V100来表示。客户将这个Transaction提交到了V1。V1是这一轮共识的发起者。
咱们先用一张图来表示这个Transaction入链的过程:
Transaction的入链过程能够分为五大步:
客户端将transaction提交给V1,V1的admission Control(AC)模块将会接收这个transaction。
AC是验证器的惟一外部接口。 客户端对验证器的任何请求都将首先转到AC。
AC调用虚拟机(VM)的接口来验证该交易的正确性,包括:签名认证,判断帐户是否有足够的金额,Tn不是一个重放交易等等信息。用以防止恶意节点。
这里虚拟机是用来执行Move脚本,也是Libra业务逻辑运行的地方。
若是Tn经过了VM的验证,那么进入下一步,AC将会把Transaction送到MemPool中。
Mempool是一个共享缓冲区,用于保存“等待”执行的事务。 将新事务添加到内存池后,内存池将与系统中的其余验证程序共享此事务。 为了减小“共享内存池”中的网络消耗,每一个验证器负责将本身的事务传递给其余验证器。 当验证者从另外一个验证者的内存池接收到事务时,该事务将添加到接收者验证者的内存池中。
咱们假设V1是Proposing节点,那么它会将本身mempool的交易打包成一个Block,而后经过共识模块向其余验证节点提交一个Proposal。
共识模块负责经过与网络中的其余验证者一块儿参与共识协议来对交易块进行排序并就执行结果达成一致。
V1的共识模块负责协调全部验证者之间对拟议区块中交易顺序的协议。
为了达成共识,在第六步生成的Block会被传递到执行模块。执行的工做是协调一组事务的执行,并保持一个能够经过共识投票的临时状态。
执行模块管理虚拟机(VM)中事务的执行。 请注意,这里的执行是在区块中的交易达成一致以前进行的推测性执行。
将Block中的Transaction执行完成后,执行模块将Block中的Transaction追加到Libra区块链的Merkle累加器。 这是Merkle累加器的内存/临时版本。 执行这些事务的(提议/推测)结果将返回到共识组件。从“共识”到“执行”的箭头表示执行交易的请求是由共识组件发出的。
V1(共识领导者)试图与参与该共识的其余验证者就块的执行结果达成共识。
若是区块的执行结果由一组具备多数表决权的验证器达成一致并签名,则验证器V1的执行模块从推测执行缓存中读取区块执行的结果,并提交区块中的全部事务并永久存储。
A的账户如今将具备100LBR,其序列号将为n+1。若是Tn被B重放,则它将被拒绝,由于A的账户的序列号n+1大于重放的事务的序列号n。
更多教程请参考 flydean的博客