Read-Write set semantics(读写集

本文讨论了关于读写集当前实现的细节。

Transaction simulation and read-write set(事务模拟和读写集

客户端提交事务到peer,peer会执行背书验证并模拟该事务的请求结果,为该事务的请求准备一个读写集。读集包含了该事务在读取本地账本时的一列事务版本信息及该信息对应的的一列唯一键,写集包含了一个唯一键(可能也允许与读集中的键重复)列表和事务写入的最新值。如果事务的执行是删除操作,那么将为这一列唯一键设置一个delete标记(在新值的位置)。

此外,如果事务为键多次写入一个值,则只保留最后一个写入值。另外,即使在事务读取结果发出之前更新了键值,也会返回事务读取已提交状态的值。换句话说,必须保证读写一致性。

正如上面提到的,键的版本只在读取集中记录,而写集仅包含由事务设置的一列惟一键和它们的最新值。

可以有各种各样的执行版本的方案。版本控制方案的最低要求是为给定的键生成不重复的标识符。例如,使用单调递增的版本可以采用一个这样的方案。在当前的实现中,我们使用一个基于区块链顶点的版本控制方案,在这个方案中,提交事务的顶点被用作事务修改后的所有键的最新版本,事务的顶点由一个元组表示(txNumber是该块内事务的顶点)。该方案与增量编号方案相比有许多优点—主要是它支持其他组件,如statedb、事务模拟和验证,以实现有效的设计选择。

下面是模拟假想事务的一个示例读写集的例子。为了简单起见,我们使用增量数字表示版本。

<TxReadWriteSet>
<NsReadWriteSet name="chaincode1">
<read-set>
<read key="K1", version="1">
<read key="K2", version="1">
</read-set>
<write-set>
<write key="K1", value="V1">
<write key="K3", value="V2">
<write key="K4", isDelete="true">
</write-set>
</NsReadWriteSet>
<TxReadWriteSet>

此外,如果事务在模拟期间执行范围查询,那么范围查询及其结果将被添加到读写集作为查询信息。

Transaction validation and updating world state using read-write set(使用读-写集进行事务验证和更新世界状态)

提交者使用读-写集的读集部分来检查事务的有效性,并使用读写集的写集部分更新受影响的键的版本和值。

在验证阶段,如果在事务读集中每一个key的版本都能够与world state(假定之前所有的事务都是有效的,包括之前在同一区块中的已经被提交的事务)中的key版本一致,那么该条事务则被认为是有效的。如果读写集还包含一个或多个查询信息,则需要执行额外的验证。

这些额外的验证需要确保在本次事务查询信息返回结果的范围内的key没有被插入/删除/更新过,换句话说,如果我们在对提交状态的验证过程中重新执行任何一个范围查询(在模拟期间执行的事务),那么它应该会产生与在模拟时所观察到的结果相同的结果。此检查确保如果事务在提交期间观察到虚项,则该事务应被标记为无效。注意,这个虚项保护仅限于范围查询(例如:在chaincode中的GetStateByRange函数)并且还没有为其他查询(例如:在chaincode中的GetQueryResult函数)实现。其他查询有可能出现虚项,因此只能在没有提交到排序的只读事务中使用,除非应用程序能够保证模拟和验证/提交时间之间的结果集的稳定性。

如果一个事务通过了有效性检查,提交者将使用写集来更新世界状态。在更新阶段,对于写集中的每个键,相同键的值都设置为在写集中指定的值,进一步地,这个世界状态的键的版本会被改变,以反映最新的版本。

Example simulation and validation(模拟和验证案例)

本节通过一个示例场景帮助理解语义。对于本例的目的,在世界状态中,键k的存在是由元组(k、ver、val)表示的,其中,ver是键k的最新版本,它的值由val表示。

现在,考虑一组5个事务,T1、T2、T3、T4和T5,它们都在同一个快照上模拟世界状态。下面的代码片段显示了对事务进行模拟的世界状态的快照,以及由这些事务执行的读取和写入活动的顺序。

World state: (k1,1,v1), (k2,1,v2), (k3,1,v3), (k4,1,v4), (k5,1,v5)
T1 -> Write(k1, v1'), Write(k2, v2')
T2 -> Read(k1), Write(k3, v3')
T3 -> Write(k2, v2'')
T4 -> Write(k2, v2'''), read(k2)
T5 -> Write(k6, v6'), read(k5)

现在,假设这些事务是在T1的序列中排序的。T5(可以包含在一个区块或不同的区块中)

  1. T1通过验证,因为它不执行任何读取操作。此外,世界状态中的键k1和k2的元组被更新为(k1,2,v1')和(k2,2,v2')
  2. T2失败了,因为它读取了一个键k1,它被之前的事务修改为T1
  3. T3通过验证,因为它不执行读操作。进一步的,在这个世界状态下的键的元组被更新到(k2,3,v2'')
  4. T4失败了,因为它读取了一个键k2,它被之前的事务T1修改过
  5. T5通过验证,因为它读取了一个键k5,它没有被前面的任何事务修改过

注意:目前还不支持具有多个读写集的事务。

Hyperledger Fabric Read-Write set semantics——读写集的更多相关文章

  1. HyperLedger Fabric基于zookeeper和kafka集群配置解析

    简述 在搭建HyperLedger Fabric环境的过程中,我们会用到一个configtx.yaml文件(可参考Hyperledger Fabric 1.0 从零开始(八)--Fabric多节点集群 ...

  2. Hyperledger Fabric 1.0 从零开始(九)——Fabric多节点集群生产启动

    7:Fabric多节点集群生产启动 7.1.多节点服务器配置 在生产环境上,我们沿用4.1.配置说明中的服务器各节点配置方案. 我们申请了五台生产服务器,其中四台服务器运行peer节点,另外一台服务器 ...

  3. (转)Fabric 1.0 读写集

    本文译自Fabric 1.0 文档,这篇文档详述了当前读写集语义实现的细节.文档地址为: https://hyperledger-fabric.readthedocs.io/en/latest/rea ...

  4. Hyperledger Fabric 1.0 从零开始(八)——Fabric多节点集群生产部署

    6.1.平台特定使用的二进制文件配置 该方案与Hyperledger Fabric 1.0 从零开始(五)--运行测试e2e类似,根据企业需要,可以控制各节点的域名,及联盟链的统一域名.可以指定单独节 ...

  5. Hyperledger Fabric Ledger——账本总账

    Ledger Ledger(账本)即所有的state transitions(状态切换),是有序且不可篡改的.state transitions(状态切换)是由参与方提交的chaincode(智能合约 ...

  6. Hyperledger Fabric Model——超级账本组成模型

    超级账本组成模型 本文主要讲述Hyperledger Fabric的关键设计特性,并细述如何实现了一个全面的.可定制的企业级区块链解决方案: 资产定义--资产这里理解为任何具有货币价值的东西,它们都可 ...

  7. Hyperledger Fabric Transaction Flow——事务处理流程

    Transaction Flow 本文概述了在标准资产交换过程中发生的事务机制.这个场景包括两个客户,A和B,他们在购买和销售萝卜(产品).他们每个人在网络上都有一个peer,通过这个网络,他们发送自 ...

  8. 在HyperLedger Fabric中启用CouchDB作为State Database

    回顾一下我之前的一篇博客,在Fabric 1.0中,我们存在3种类型的数据存储,一种是基于文件系统的区块链数据,这个跟比特币很像,比特币也是文件形式存储的.Fabric1.0中的区块链存储了Trans ...

  9. 第6章 Hyperledger Fabric模型

    This section outlines the key design features woven into Hyperledger Fabric that fulfill its promise ...

随机推荐

  1. java 数据格式验证类

    作为一个前端,懂一点java,php之类的,甚好. 我所在的项目前端采用的就是java的spring mvc框架,所以我们也写java,掐指一算,也快一年了. 前端而言,验证是一个坎,绕不过去的,前面 ...

  2. C++ 脑筋急转弯

    最近重新温习一下C++的基础知识,这里给大家分享一下,独痛苦不如众痛苦. 先贴出一段示例代码如下: class CTest{ public: CTest(){ ); }; ~CTest(){ if ( ...

  3. 冒泡算法给0~9随机n位数字排序

    <?php //产生5位0~9的随机数      function getRand($begin=0,$end=9,$limit=5){                $rand_array=r ...

  4. 【深度学习系列】关于PaddlePaddle的一些避“坑”技巧

    最近除了工作以外,业余在参加Paddle的AI比赛,在用Paddle训练的过程中遇到了一些问题,并找到了解决方法,跟大家分享一下: PaddlePaddle的Anaconda的兼容问题 之前我是在服务 ...

  5. 【转载】SSD 下的 MySQL IO 优化

    一 目录 一 目录 二 背景 三 SSD 特性 四 基于 SSD 的数据库优化 五 A 项目 MySQL 主从关系图 六 程序切换之前调优 6.1 修改系统 IO 调度算法 6.2 修改 innodb ...

  6. HDU 1754 I Hate It(线段树之单点更新,区间最值)

    I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  7. hihoCoder #1094 : Lost in the City(枚举,微软苏州校招笔试 12月27日 )

    #1094 : Lost in the City 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 Little Hi gets lost in the city. He ...

  8. ubuntu11.0静态IP地址配置

    1. 静态IP地址配置 配置文件路径:/etc/network/interfaces auto lo iface lo inet loopback auto eth0 iface eth0 inet ...

  9. Java集合系列[4]----LinkedHashMap源码分析

    这篇文章我们开始分析LinkedHashMap的源码,LinkedHashMap继承了HashMap,也就是说LinkedHashMap是在HashMap的基础上扩展而来的,因此在看LinkedHas ...

  10. Vue中的$set的使用

    在我们使用vue进行开发的过程中,可能会遇到一种情况:当生成vue实例后,当再次给数据赋值时,有时候并不会自动更新到视图上去: 当我们去看vue文档的时候,会发现有这么一句话:如果在实例创建之后添加新 ...