github.com/kaituanwang/hyperledger@v2.0.1+incompatible/docs/source/readwrite.rst (about) 1 Read-Write set semantics 2 ~~~~~~~~~~~~~~~~~~~~~~~~ 3 4 This document discusses the details of the current implementation about 5 the semantics of read-write sets. 6 7 Transaction simulation and read-write set 8 ''''''''''''''''''''''''''''''''''''''''' 9 10 During simulation of a transaction at an ``endorser``, a read-write set 11 is prepared for the transaction. The ``read set`` contains a list of 12 unique keys and their committed version numbers (but not values) that 13 the transaction reads during simulation. The ``write set`` contains a list 14 of unique keys (though there can be overlap with the keys present in the read set) 15 and their new values that the transaction writes. A delete marker is set (in 16 the place of new value) for the key if the update performed by the 17 transaction is to delete the key. 18 19 Further, if the transaction writes a value multiple times for a key, 20 only the last written value is retained. Also, if a transaction reads a 21 value for a key, the value in the committed state is returned even if 22 the transaction has updated the value for the key before issuing the 23 read. In another words, Read-your-writes semantics are not supported. 24 25 As noted earlier, the versions of the keys are recorded only in the read 26 set; the write set just contains the list of unique keys and their 27 latest values set by the transaction. 28 29 There could be various schemes for implementing versions. The minimal 30 requirement for a versioning scheme is to produce non-repeating 31 identifiers for a given key. For instance, using monotonically 32 increasing numbers for versions can be one such scheme. In the current 33 implementation, we use a blockchain height based versioning scheme in 34 which the height of the committing transaction is used as the latest 35 version for all the keys modified by the transaction. In this scheme, 36 the height of a transaction is represented by a tuple (txNumber is the 37 height of the transaction within the block). This scheme has many 38 advantages over the incremental number scheme - primarily, it enables 39 other components such as statedb, transaction simulation and validation 40 for making efficient design choices. 41 42 Following is an illustration of an example read-write set prepared by 43 simulation of a hypothetical transaction. For the sake of simplicity, in 44 the illustrations, we use the incremental numbers for representing the 45 versions. 46 47 :: 48 49 <TxReadWriteSet> 50 <NsReadWriteSet name="chaincode1"> 51 <read-set> 52 <read key="K1", version="1"> 53 <read key="K2", version="1"> 54 </read-set> 55 <write-set> 56 <write key="K1", value="V1" 57 <write key="K3", value="V2" 58 <write key="K4", isDelete="true" 59 </write-set> 60 </NsReadWriteSet> 61 <TxReadWriteSet> 62 63 Additionally, if the transaction performs a range query during 64 simulation, the range query as well as its results will be added to the 65 read-write set as ``query-info``. 66 67 Transaction validation and updating world state using read-write set 68 '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 69 70 A ``committer`` uses the read set portion of the read-write set for 71 checking the validity of a transaction and the write set portion of the 72 read-write set for updating the versions and the values of the affected 73 keys. 74 75 In the validation phase, a transaction is considered ``valid`` if the 76 version of each key present in the read set of the transaction matches 77 the version for the same key in the world state - assuming all the 78 preceding ``valid`` transactions (including the preceding transactions 79 in the same block) are committed (*committed-state*). An additional 80 validation is performed if the read-write set also contains one or more 81 query-info. 82 83 This additional validation should ensure that no key has been 84 inserted/deleted/updated in the super range (i.e., union of the ranges) 85 of the results captured in the query-info(s). In other words, if we 86 re-execute any of the range queries (that the transaction performed 87 during simulation) during validation on the committed-state, it should 88 yield the same results that were observed by the transaction at the time 89 of simulation. This check ensures that if a transaction observes phantom 90 items during commit, the transaction should be marked as invalid. Note 91 that the this phantom protection is limited to range queries (i.e., 92 ``GetStateByRange`` function in the chaincode) and not yet implemented 93 for other queries (i.e., ``GetQueryResult`` function in the chaincode). 94 Other queries are at risk of phantoms, and should therefore only be used 95 in read-only transactions that are not submitted to ordering, unless the 96 application can guarantee the stability of the result set between 97 simulation and validation/commit time. 98 99 If a transaction passes the validity check, the committer uses the write 100 set for updating the world state. In the update phase, for each key 101 present in the write set, the value in the world state for the same key 102 is set to the value as specified in the write set. Further, the version 103 of the key in the world state is changed to reflect the latest version. 104 105 Example simulation and validation 106 ''''''''''''''''''''''''''''''''' 107 108 This section helps with understanding the semantics through an example 109 scenario. For the purpose of this example, the presence of a key, ``k``, 110 in the world state is represented by a tuple ``(k,ver,val)`` where 111 ``ver`` is the latest version of the key ``k`` having ``val`` as its 112 value. 113 114 Now, consider a set of five transactions ``T1, T2, T3, T4, and T5``, all 115 simulated on the same snapshot of the world state. The following snippet 116 shows the snapshot of the world state against which the transactions are 117 simulated and the sequence of read and write activities performed by 118 each of these transactions. 119 120 :: 121 122 World state: (k1,1,v1), (k2,1,v2), (k3,1,v3), (k4,1,v4), (k5,1,v5) 123 T1 -> Write(k1, v1'), Write(k2, v2') 124 T2 -> Read(k1), Write(k3, v3') 125 T3 -> Write(k2, v2'') 126 T4 -> Write(k2, v2'''), read(k2) 127 T5 -> Write(k6, v6'), read(k5) 128 129 Now, assume that these transactions are ordered in the sequence of 130 T1,..,T5 (could be contained in a single block or different blocks) 131 132 1. ``T1`` passes validation because it does not perform any read. 133 Further, the tuple of keys ``k1`` and ``k2`` in the world state are 134 updated to ``(k1,2,v1'), (k2,2,v2')`` 135 136 2. ``T2`` fails validation because it reads a key, ``k1``, which was 137 modified by a preceding transaction - ``T1`` 138 139 3. ``T3`` passes the validation because it does not perform a read. 140 Further the tuple of the key, ``k2``, in the world state is updated 141 to ``(k2,3,v2'')`` 142 143 4. ``T4`` fails the validation because it reads a key, ``k2``, which was 144 modified by a preceding transaction ``T1`` 145 146 5. ``T5`` passes validation because it reads a key, ``k5,`` which was 147 not modified by any of the preceding transactions 148 149 **Note**: Transactions with multiple read-write sets are not yet supported. 150 151 .. Licensed under Creative Commons Attribution 4.0 International License 152 https://creativecommons.org/licenses/by/4.0/