You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardexpand all lines: core/ledger/ReadWriteSet.md
+27-15
Original file line number
Diff line number
Diff line change
@@ -3,13 +3,23 @@
3
3
This documents discusses the details of the current implementation about the semantics of read-write sets.
4
4
5
5
##### Transaction simulation and read-write set
6
-
During simulation of a transaction at an `endorser`, a read-write set is prepared for the transaction. The `read set` contains a list of unique keys and their their committed versions that the transaction reads during simulation. The `write set` contains a list of unique keys (though there can be overlap with the keys present in the read set) and their new values that the transaction writes. A delete marker is set (in the place of new value) for the key if the update performed by the transaction is to delete the key.
6
+
During simulation of a transaction at an `endorser`, a read-write set is prepared for the transaction. The `read set` contains a list of unique keys and their committed versions that the transaction reads during simulation. The `write set` contains a list of unique keys (though there can be overlap with the keys present in the read set) and their new values that the transaction writes. A delete marker is set (in the place of new value) for the key if the update performed by the transaction is to delete the key.
7
7
8
-
Further, if the transaction writes a value multiple times for a key, only the last written value is retained. Also, if a transaction reads a value for a key that the transaction itself has written before, the last written value is returned instead of the value present in the committed snapshot; one implication of this is that if a transaction writes a value for a key before reading it from the committed snapshot, the key does not appear in the read set of the transaction.
8
+
Further, if the transaction writes a value multiple times for a key, only the last written value is retained.
9
+
Also, if a transaction reads a value for a key, the value in the committed state is returned even if
10
+
the transaction has updated the value for the key before issuing the read.
11
+
In another words, Read-your-writes semantics are not supported.
9
12
10
13
As noted earlier, the versions of the keys are recorded only in the read set; the write set just contains the list of unique keys and their latest values set by the transaction.
11
14
15
+
There could be various schemes for implementing versions. The minimal requirement for a versioning scheme is to produce non-repeating identifiers for a given key.
16
+
For instance, using monotonically incresing numbers for versions can be one such scheme.
17
+
In the current implementation, we use a blockchain height based versioning scheme in which the height of the commiting transaction is used as the latest version for all the keys modified by the transaction.
18
+
In this scheme, the height of a transaction is represented by a tuple <blockNumer, txNumber> (txNumber is the height of the transaction within the block).
19
+
This scheme has many advantages over the incremental number scheme - primarily, it enables other components such as statedb, transaction simulation and validation for making efficient design choices.
20
+
12
21
Following is an illustration of an example read-write set prepared by simulation of an hypothetical transaction.
22
+
For the sake of simplicity, in the illustrations, we use the incremental numbers for representing the versions.
13
23
14
24
```
15
25
<TxReadWriteSet>
@@ -27,26 +37,34 @@ Following is an illustration of an example read-write set prepared by simulation
27
37
<TxReadWriteSet>
28
38
```
29
39
40
+
Additionally, if the transaction performs a range query during simulation, the range query as well as its results will be added to the read-write set as `query-info`.
41
+
30
42
##### Transaction validation and updating world state using read-write set
31
43
A `committer` uses the read set portion of the read-write set for checking the validity of a transaction and the write set portion of the read-write set for updating the versions and the values of the affected keys.
32
44
33
-
In the validation phase, a transaction is considered `valid` iff the version of each key present in the read-set of the transaction matches the version for the same key in the world state - assuming all the preceding `valid` transactions (including the preceding transactions in the same block) are committed.
45
+
In the validation phase, a transaction is considered `valid` if the version of each key present in the read set of the transaction matches the version for the same key in the world state - assuming all the preceding `valid` transactions (including the preceding transactions in the same block) are committed (*committed-state*). An additional validation is performed if the read-write set also contains one or more query-info.
46
+
This additional validation should ensure that no key has been inserted/deleted/updated in the super range (i.e., union of the ranges) of the results captured in the query-info(s). In other words,
47
+
if we re-execute any of the range queries (that the transaction performed during simulation) during validation on the committed-state, it should yield the same results that were observed by the transaction at the time of simulation.
48
+
This check ensures that if a transaction observes phantom items during commit, the transaction should be marked as invalid.
49
+
Note that the this phantom protection is limited to range queries (i.e., `GetStateByRange` function in the chaincode) and not yet implemented for other
50
+
queries (i.e., `GetQueryResult` function in the chaincode). Other queries are at risk of phantoms, and should therefore only be used in read-only transactions that are not submitted to ordering,
51
+
unless the application can guarantee the stability of the result set between simulation and validation/commit time.
34
52
35
-
If a transaction passes the validity check, the committer uses the write set for updating the world state. In the update phase, for each key present in the write set, the value in the world state for the same key is set to the value as specified in the write set. Further, the version of the key in the world state is incremented by one.
53
+
If a transaction passes the validity check, the committer uses the write set for updating the world state. In the update phase, for each key present in the write set, the value in the world state for the same key is set to the value as specified in the write set. Further, the version of the key in the world state is changed to reflect the latest version.
36
54
37
55
##### Example simulation and validation
38
56
This section helps understanding the semantics with the help of an example scenario.
39
57
For the purpose of this example, the presence of a key `k` in the world state is represented by a tuple `(k,ver,val)` where `ver` is the latest version of the key `k` having `val` as its value.
40
58
41
-
Now, consider a set of file transactions `T1, T2, T3, T4, and T5`, all simulated on the same snapshot of the world state. Following snippet shows the snapshot of the world state against witch the transactions are simulated and the sequence of read and write activities performed by each of these transactions.
59
+
Now, consider a set of five transactions `T1, T2, T3, T4, and T5`, all simulated on the same snapshot of the world state. Following snippet shows the snapshot of the world state against witch the transactions are simulated and the sequence of read and write activities performed by each of these transactions.
42
60
43
61
```
44
62
World state: (k1,1,v1), (k2,1,v2), (k3,1,v3), (k4,1,v4), (k5,1,v5)
45
63
T1 -> Write(k1, v1'), Write(k2, v2')
46
64
T2 -> Read(k1), Write(k3, v3')
47
65
T3 -> Write(k2, v2'')
48
66
T4 -> Write(k2, v2'''), read(k2)
49
-
T5 -> Write(k6, v6'), read(k1)
67
+
T5 -> Write(k6, v6'), read(k5)
50
68
```
51
69
Now, assume that these transactions are ordered in the sequence of T1,..,T5 (could be contained in a single block or different blocks)
52
70
@@ -56,15 +74,9 @@ Now, assume that these transactions are ordered in the sequence of T1,..,T5 (cou
56
74
57
75
3.`T3` passes the validation because it does not perform a read. Further the tuple of the key `k2` in the world state are updated to `(k2,3,v2'')`
58
76
59
-
4.`T4`passes the validation because it performs a read the key `k2`after writing the new value (though the key was modified by a preceding transaction `T1`). Further the tuple of the key `k2` in the world state are updated to `(k2,4,v2''')`
77
+
4.`T4`fails the validation because it reads a key `k2`which is modified by a preceding transaction `T1`
60
78
61
-
5.`T5`fails the validation because it performs a read for key `k1` which is modified by a preceding transaction `T1`
79
+
5.`T5`passes the validation because it reads a key `k5` which is not modified by any of the preceding transactions
62
80
63
81
#### Transactions with multiple read-write sets
64
-
If a transaction contains multiple read-write sets as a result of including different simulations results in a single transaction, the validation also checks for read conflicts between the read-write sets in addition to the read conflicts check with preceding transactions.
65
-
66
-
#### Questions
67
-
1. In the final block, is there a benefit of persisting read-set portion of the read-write set? The advantage of not storing clearly reduces the storage space requirement. If we chose not to store the read-set, the endorsers should sign only the write set portion of the read-write set which means that the
68
-
`actionBytes` field in the `EndorsedAction` would contain only write set and a separate field would be required for the read set.
69
-
70
-
2. Is there a benefit of deciding the version for a key in the write-set at simulation time instead of commit time? If we fix the version at the simulation time, then we would have to discard the transactions that have only write conflicts (i.e., some other transaction has written the version).
82
+
Not yet supported (https://jira.hyperledger.org/browse/FAB-445)
0 commit comments