背景
区块链平台中的一个个交易都是由智能合约编写的,每一个交易想要成功上链,首先需要经过矿工(想要进行上链的节点,也就是新区块)进行挖矿,然后将挖好的区块交给验证者(区块链中已经挖矿成功的节点进行验证)进行验证,验证成功就会将区块上链;验证失败,则会拒绝将数据上链。那么如何来判断验证成功和验证失败呢?
首先矿工会在本地进行交易的执行,也就是从区块链平台的交易队列中取一部分交易进行执行,然后把执行的结果按照一定的规则(共识机制)发送给全网的验证节点进行验证汇总。如果验证节点汇总的结果满足绝大多数的结果,也就是执行后交易交易结果和矿工发来的执行后的结果相同,那么这个验证节点就持赞同的意见,结果不同,就持拒绝的意见。
但是在智能合约执行的过程中,所有的交易都是按照串行进行执行的,因为现有的智能合约的虚拟机并没有并发执行的功能,所以在当前的多核处理器的时代中,这无疑会导致区块链的吞吐量很低。这篇文章将并发性添加到智能合约执行中,我们可以实现更好的效率和更高的吞吐量。主要开发了一个高效的框架来使用软件事务内存系统(STM)来并发执行智能合约事务。
并行化过程
而要在区块链智能合约进行并行化处理,首先要解决的问题就是交易的依赖性。虽然我们从绝大多数智能合约交易的数据集可以知道的一点就是,存在交易依赖的交易只占总体交易的20%,虽然存在交易依赖的交易只占少数,但是为了保证交易执行后的结果仍保证正确性,我们还是需要去分析,在一组交易集中存在交易依赖的交易。也就是说,我们需要将所有存在交易依赖的交易建立交易依赖图,然后把交易集的所有交易都建立一个一个的交易依赖分区,然后把这些交易依赖分区分给不同的线程去执行,来克服只有一个线程去执行所有的交易依赖的低效率的做法。
这篇文章通过把数据库管理系统中几个并发执行协议引入到智能合约来实现智能合约并行化,并且也引入多版本数据库系统来进行组合寻找最优的并发控制模型。最终引入的比较模型有时间戳协议(Basic Time stamp Ordering ,BTO) 和多版本时间戳协议(Multi-Version Time stamp Ordering ,MVTO) 。由于多线程执行的效果,实现了比串行执行的3.6倍和3.7倍挖矿执行效率和40.8倍和47.1倍的验证者进行验证的效率。
一个交易依赖分区
但是具体到两个有冲突的交易的时候呢?就比如:
这个图中(a)说明两个并行执行的两个交易T1和T2会对同一个数据x进行写操作,这个x是属于区块链中的一个数据。图(b)(c)主要展示当有冲突的交易进行不同顺序的交易之后,所导致的结果不同。也就是说,当交易T1和交易T2对同一个数据有交易冲突的时候,在矿工并行执行时会发生T1先执行,而T2后执行所导致的x的值最后结果为20,而在验证者进行并行执行时,就会产生T2先执行,而T1后执行导致的x值最后结果为10。
这个在别的论文中针对上述问题采取的是,在有交易依赖的交易之间构建锁,来保证交易可以进行回滚,最终使交易的执行保证为串行执行。
而本文采取的就是利用软件事务内存里面的时间戳协议来保证最后结果的一致性。为什么采用软件事务内存里面的时间戳协议就可以实现上述问题呢?看看时间戳协议究竟完成了什么……
时间戳协议
单版本时间戳协议
基本定义
-
时间戳排序协议用于根据时间戳对交易进行排序。事务的顺序只不过是事务创建的升序。
-
旧事务的优先级更高,这就是它首先执行的原因。为了确定事务的时间戳,该协议使用系统时间或逻辑计数器。
-
基于锁的协议用于在执行时管理事务之间冲突对之间的顺序。但是一旦创建事务,基于时间戳的协议就会开始工作。
-
假设有两个事务 T1 和 T2。假设事务T1在007次进入系统,事务T2在009次进入系统。T1 具有较高的优先级,因此它首先进入系统,因此它首先执行。
-
时间戳排序协议还维护对数据的最后一次“读取”和“写入”操作的时间戳。
基本原理
基本时间戳排序协议的工作原理如下:
- 每当事务 Ti 发出Read (X)操作时,检查以下条件:
- 如果 W_TS(X) >TS(Ti) 则拒绝该操作。
- 如果 W_TS(X) <= TS(Ti) 则执行操作。
更新所有数据项的时间戳。
- 每当事务 Ti 发出Write(X)操作时,检查以下条件:
- 如果 TS(Ti) < R_TS(X) 则拒绝该操作。
- 如果 TS(Ti) < W_TS(X) 则拒绝操作并回滚 Ti,否则执行操作。
其中:
-
TS(TI)表示事务 Ti 的时间戳。
-
R_TS(X)表示数据项 X 的读取时间戳。
-
W_TS(X)表示数据项 X 的写入时间戳。
多版本时间戳协议
在多版本时间戳排序技术中,对于系统中的每个事务,在事务开始执行之前分配一个唯一的时间戳。事务 T 的时间戳记为 TS(T)。对于每个数据项 X,一系列版本 <X 1 , X 2 , X 3 ,……X K > 相关联。
对于数据项(X)的每个版本 X i,系统维护以下三个字段:
- 版本的值。
- Read_TS (Xi): X i的读取时间戳是任何成功读取版本 X i 的事务的最大时间戳。
- Write_TS(Xi): X i的写入时间戳是任何成功写入版本 X i 的事务的最大时间戳。
为确保可序列化,使用以下两条规则:
假设事务 T 对数据项 X 发出读取请求和写入请求。设 X i为 X 的所有版本中具有最大 Write_TS(X i ) 的版本,该版本也小于或等于 TS(T) .
- 规则一:假设事务 T 发出 Read(X) 请求,如果 Read_TS(X i )<TS(T) 则系统将 X i的值返回给事务 T 并更新 Read_TS(X i )的值到 TS(T)
- 规则二: 假设事务 T 发出 Write(X) 请求 TS(T) < Read_TS(X),则系统中止事务 T。另一方面,如果 TS(T) = Write_TS(X),则系统覆盖X的内容;如果 TS(T)>Write_TS(X) 它创建一个新版本的 X。
机制
使用邻接表的方法来构建区块依赖图。如下图:
其中ts为提交该交易的时间戳(具有唯一性),
A
U
i
d
AU_{id}
AUid为事务Ti执行的原子单元的id,为了维持vNode节点为递减,我们初始化inCnt为0,当存在依赖关系时,我们就可以将存在依赖关系的inCnt修改为相对应的值(位于依赖图中执行的顺序),而eNext和vNext就为依赖图中构建依赖图的边连接点。
如何构建的依赖图的算法主要利用一个无锁图库里面的5种算法:addVert(), addEdge(), searchLocal(), searchGlobal() and decInCount()。(具体算法仿照构建连接表算法类似)
并行挖矿的过程
- 从交易平台中获取交易
- 并行执行交易计算并且计算出各个变量的最终状态
- 生成冲突表(也可以说交易依赖图)
- 计算前一个区块的hash值
- 生成最终的区块内部的需要生成的值
- 推送给所有的验证节点进行验证
总结
主要进行单版本时间戳和多版本时间戳的协议在智能合约并行化执行后的结果进行比较,主要是偏向于事务内存系统(STM)在智能合约上的应用,所以本文的参考价值主要是在于如何进行时间戳的利用和公式的证明。
附录-算法
简单的拍卖合约
line2:进行拍卖交易的地址
line3:拍卖结束时间
line5:最高拍卖者的地址
line6:最高拍卖者的竞价
line7:把最高拍卖者的地址和竞价连接起来
函数功能:
- 当前时间超过拍卖时间,抛出异常
- 竞价人的竞价小于当前的价格,抛出异常
- 竞价高的人并且在合理时间内将竞价者和竞价记录
矿工的并行执行
文章来源:https://www.toymoban.com/news/detail-811881.html
验证者并行执行(根据区块依赖图,BG)
文章来源地址https://www.toymoban.com/news/detail-811881.html
到了这里,关于【论文研读】-An Efficient Framework for Optimistic Concurrent Execution of Smart Contracts的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!