Skip to content

Commit 74906de

Browse files
denyeartyacovm
authored andcommitted
[FAB-6431] Pvt Transient Store to use received height
Transient store persists private data on authorized peers while transactions with private data are in-flight. One of the keys for transient store records was endorsementBlkHt, this work item will change it to blockHeight, as it will be better to store transient data based on 'received at' height rather than endorsement height, when a peer receives private data via gossip. The height will be the basis for block-to-live purging in subsequent changesets. Also, this change updates comments to indicate that TxPvtReadWriteSet includes write information but not read information (the read information is passed in the hashed rwset rather than in the private set). A subsequent changeset will rename TxPvtReadWriteSet to TxPvtWriteSet throughout the code. Change-Id: I52df4702ad47ca17f2a745faa4c278f78e350d2f Signed-off-by: David Enyeart <enyeart@us.ibm.com>
1 parent 7500e9b commit 74906de

File tree

9 files changed

+148
-144
lines changed

9 files changed

+148
-144
lines changed

core/transientstore/store.go

Lines changed: 53 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -44,42 +44,43 @@ type RWSetScanner interface {
4444
Close()
4545
}
4646

47-
// Store manages the storage of private read-write sets for a ledgerId.
47+
// Store manages the storage of private write sets for a ledgerId.
4848
// Ideally, a ledger can remove the data from this storage when it is committed to
4949
// the permanent storage or the pruning of some data items is enforced by the policy
5050
type Store interface {
51-
// Persist stores the private read-write set of a transaction in the transient store
52-
Persist(txid string, endorsementBlkHt uint64, privateSimulationResults *rwset.TxPvtReadWriteSet) error
51+
// Persist stores the private write set of a transaction in the transient store
52+
// based on txid and the block height the private data was received at
53+
Persist(txid string, blockHeight uint64, privateSimulationResults *rwset.TxPvtReadWriteSet) error
5354
// GetTxPvtRWSetByTxid returns an iterator due to the fact that the txid may have multiple private
54-
// RWSets persisted from different endorsers (via Gossip)
55+
// write sets persisted from different endorsers (via Gossip)
5556
GetTxPvtRWSetByTxid(txid string, filter ledger.PvtNsCollFilter) (RWSetScanner, error)
56-
// PurgeByTxids removes private read-write set of a given set of transactions from the
57+
// PurgeByTxids removes private write sets of a given set of transactions from the
5758
// transient store
5859
PurgeByTxids(txids []string) error
59-
// PurgeByHeight removes private read-writes set generated by endorsers at block height lesser than
60-
// a given maxBlockNumToRetain. In other words, Purge only retains private read-write sets
61-
// that were generated at block height of maxBlockNumToRetain or higher. Though the private
62-
// read-write sets stored in transient store is removed by coordinator using PurgebyTxids()
60+
// PurgeByHeight removes private write sets at block height lesser than
61+
// a given maxBlockNumToRetain. In other words, Purge only retains private write sets
62+
// that were persisted at block height of maxBlockNumToRetain or higher. Though the private
63+
// write sets stored in transient store is removed by coordinator using PurgebyTxids()
6364
// after successful block commit, PurgeByHeight() is still required to remove orphan entries (as
6465
// transaction that gets endorsed may not be submitted by the client for commit)
6566
PurgeByHeight(maxBlockNumToRetain uint64) error
66-
// GetMinEndorsementBlkHt returns the lowest retained endorsement block height
67-
GetMinEndorsementBlkHt() (uint64, error)
67+
// GetMinTransientBlkHt returns the lowest block height remaining in transient store
68+
GetMinTransientBlkHt() (uint64, error)
6869
Shutdown()
6970
}
7071

71-
// EndorserPvtSimulationResults captures the deatils of the simulation results specific to an endorser
72+
// EndorserPvtSimulationResults captures the details of the simulation results specific to an endorser
7273
type EndorserPvtSimulationResults struct {
73-
EndorsementBlockHeight uint64
74-
PvtSimulationResults *rwset.TxPvtReadWriteSet
74+
ReceivedAtBlockHeight uint64
75+
PvtSimulationResults *rwset.TxPvtReadWriteSet
7576
}
7677

7778
//////////////////////////////////////////////
7879
// Implementation
7980
/////////////////////////////////////////////
8081

8182
// storeProvider encapsulates a leveldb provider which is used to store
82-
// private read-write set of simulated transactions, and implements TransientStoreProvider
83+
// private write sets of simulated transactions, and implements TransientStoreProvider
8384
// interface.
8485
type storeProvider struct {
8586
dbProvider *leveldbhelper.Provider
@@ -114,16 +115,17 @@ func (provider *storeProvider) Close() {
114115
provider.dbProvider.Close()
115116
}
116117

117-
// Persist stores the private read-write set of a transaction in the transient store
118-
func (s *store) Persist(txid string, endorsementBlkHt uint64,
118+
// Persist stores the private write set of a transaction in the transient store
119+
// based on txid and the block height the private data was received at
120+
func (s *store) Persist(txid string, blockHeight uint64,
119121
privateSimulationResults *rwset.TxPvtReadWriteSet) error {
120122
dbBatch := leveldbhelper.NewUpdateBatch()
121123

122-
// Create compositeKey with appropriate prefix, txid, uuid and endorsementBlkHt
123-
// Due to the fact that the txid may have multiple private RWSets persisted from different
124+
// Create compositeKey with appropriate prefix, txid, uuid and blockHeight
125+
// Due to the fact that the txid may have multiple private write sets persisted from different
124126
// endorsers (via Gossip), we postfix an uuid with the txid to avoid collision.
125127
uuid := util.GenerateUUID()
126-
compositeKeyPvtRWSet := createCompositeKeyForPvtRWSet(txid, uuid, endorsementBlkHt)
128+
compositeKeyPvtRWSet := createCompositeKeyForPvtRWSet(txid, uuid, blockHeight)
127129
privateSimulationResultsBytes, err := proto.Marshal(privateSimulationResults)
128130
if err != nil {
129131
return err
@@ -132,16 +134,16 @@ func (s *store) Persist(txid string, endorsementBlkHt uint64,
132134

133135
// Create two index: (i) by txid, and (ii) by height
134136

135-
// Create compositeKey for purge index by height with appropriate prefix, endorsementBlkHt,
137+
// Create compositeKey for purge index by height with appropriate prefix, blockHeight,
136138
// txid, uuid and store the compositeKey (purge index) with a null byte as value. Note that
137139
// the purge index is used to remove orphan entries in the transient store (which are not removed
138140
// by PurgeTxids()) using BTL policy by PurgeByHeight(). Note that orphan entries are due to transaction
139141
// that gets endorsed but not submitted by the client for commit)
140-
compositeKeyPurgeIndexByHeight := createCompositeKeyForPurgeIndexByHeight(endorsementBlkHt, txid, uuid)
142+
compositeKeyPurgeIndexByHeight := createCompositeKeyForPurgeIndexByHeight(blockHeight, txid, uuid)
141143
dbBatch.Put(compositeKeyPurgeIndexByHeight, emptyValue)
142144

143145
// Create compositeKey for purge index by txid with appropriate prefix, txid, uuid,
144-
// endorsementBlkHt and store the compositeKey (purge index) with a null byte as value.
146+
// blockHeight and store the compositeKey (purge index) with a null byte as value.
145147
// Though compositeKeyPvtRWSet itself can be used to purge private write set by txid,
146148
// we create a separate composite key with a null byte as value. The reason is that
147149
// if we use compositeKeyPvtRWSet, we unnecessarily read (potentially large) private write
@@ -150,14 +152,14 @@ func (s *store) Persist(txid string, endorsementBlkHt uint64,
150152
// Note: We can create compositeKeyPurgeIndexByTxid by just replacing the prefix of compositeKeyPvtRWSet
151153
// with purgeIndexByTxidPrefix. For code readability and to be expressive, we use a
152154
// createCompositeKeyForPurgeIndexByTxid() instead.
153-
compositeKeyPurgeIndexByTxid := createCompositeKeyForPurgeIndexByTxid(txid, uuid, endorsementBlkHt)
155+
compositeKeyPurgeIndexByTxid := createCompositeKeyForPurgeIndexByTxid(txid, uuid, blockHeight)
154156
dbBatch.Put(compositeKeyPurgeIndexByTxid, emptyValue)
155157

156158
return s.db.WriteBatch(dbBatch, true)
157159
}
158160

159161
// GetTxPvtRWSetByTxid returns an iterator due to the fact that the txid may have multiple private
160-
// RWSets persisted from different endorsers.
162+
// write sets persisted from different endorsers.
161163
func (s *store) GetTxPvtRWSetByTxid(txid string, filter ledger.PvtNsCollFilter) (RWSetScanner, error) {
162164
// Construct startKey and endKey to do an range query
163165
startKey := createTxidRangeStartKey(txid)
@@ -167,7 +169,7 @@ func (s *store) GetTxPvtRWSetByTxid(txid string, filter ledger.PvtNsCollFilter)
167169
return &RwsetScanner{txid, iter, filter}, nil
168170
}
169171

170-
// PurgeByTxids removes private read-write set of a given set of transactions from the
172+
// PurgeByTxids removes private write sets of a given set of transactions from the
171173
// transient store. PurgeByTxids() is expected to be called by coordinator after
172174
// committing a block to ledger.
173175
func (s *store) PurgeByTxids(txids []string) error {
@@ -181,20 +183,20 @@ func (s *store) PurgeByTxids(txids []string) error {
181183
iter := s.db.GetIterator(startKey, endKey)
182184

183185
// Get all txid and uuid from above result and remove it from transient store (both
184-
// read/write set and the corresponding indexes.
186+
// write set and the corresponding indexes.
185187
for iter.Next() {
186188
// For each entry, remove the private read-write set and correponding indexes
187189

188-
// Remove private read-write set
190+
// Remove private write set
189191
compositeKeyPurgeIndexByTxid := iter.Key()
190192
// Note: We can create compositeKeyPvtRWSet by just replacing the prefix of compositeKeyPurgeIndexByTxid
191193
// with prwsetPrefix. For code readability and to be expressive, we split and create again.
192-
uuid, endorsementBlkHt := splitCompositeKeyOfPurgeIndexByTxid(compositeKeyPurgeIndexByTxid)
193-
compositeKeyPvtRWSet := createCompositeKeyForPvtRWSet(txid, uuid, endorsementBlkHt)
194+
uuid, blockHeight := splitCompositeKeyOfPurgeIndexByTxid(compositeKeyPurgeIndexByTxid)
195+
compositeKeyPvtRWSet := createCompositeKeyForPvtRWSet(txid, uuid, blockHeight)
194196
dbBatch.Delete(compositeKeyPvtRWSet)
195197

196198
// Remove purge index -- purgeIndexByHeight
197-
compositeKeyPurgeIndexByHeight := createCompositeKeyForPurgeIndexByHeight(endorsementBlkHt, txid, uuid)
199+
compositeKeyPurgeIndexByHeight := createCompositeKeyForPurgeIndexByHeight(blockHeight, txid, uuid)
198200
dbBatch.Delete(compositeKeyPurgeIndexByHeight)
199201

200202
// Remove purge index -- purgeIndexByTxid
@@ -207,10 +209,10 @@ func (s *store) PurgeByTxids(txids []string) error {
207209
return s.db.WriteBatch(dbBatch, true)
208210
}
209211

210-
// PurgeByHeight removes private read-writes set generated by endorsers at block height lesser than
211-
// a given maxBlockNumToRetain. In other words, PurgeByHeight only retains private read-write sets
212-
// that were generated at block height of maxBlockNumToRetain or higher. Though the private
213-
// read-write sets stored in transient store is removed by coordinator using PurgebyTxids()
212+
// PurgeByHeight removes private write sets at block height lesser than
213+
// a given maxBlockNumToRetain. In other words, Purge only retains private write sets
214+
// that were persisted at block height of maxBlockNumToRetain or higher. Though the private
215+
// write sets stored in transient store is removed by coordinator using PurgebyTxids()
214216
// after successful block commit, PurgeByHeight() is still required to remove orphan entries (as
215217
// transaction that gets endorsed may not be submitted by the client for commit)
216218
func (s *store) PurgeByHeight(maxBlockNumToRetain uint64) error {
@@ -222,18 +224,18 @@ func (s *store) PurgeByHeight(maxBlockNumToRetain uint64) error {
222224
dbBatch := leveldbhelper.NewUpdateBatch()
223225

224226
// Get all txid and uuid from above result and remove it from transient store (both
225-
// read/write set and the corresponding index.
227+
// write set and the corresponding index.
226228
for iter.Next() {
227229
// For each entry, remove the private read-write set and correponding indexes
228230

229-
// Remove private read-write set
231+
// Remove private write set
230232
compositeKeyPurgeIndexByHeight := iter.Key()
231-
txid, uuid, endorsementBlkHt := splitCompositeKeyOfPurgeIndexByHeight(compositeKeyPurgeIndexByHeight)
232-
compositeKeyPvtRWSet := createCompositeKeyForPvtRWSet(txid, uuid, endorsementBlkHt)
233+
txid, uuid, blockHeight := splitCompositeKeyOfPurgeIndexByHeight(compositeKeyPurgeIndexByHeight)
234+
compositeKeyPvtRWSet := createCompositeKeyForPvtRWSet(txid, uuid, blockHeight)
233235
dbBatch.Delete(compositeKeyPvtRWSet)
234236

235237
// Remove purge index -- purgeIndexByTxid
236-
compositeKeyPurgeIndexByTxid := createCompositeKeyForPurgeIndexByTxid(txid, uuid, endorsementBlkHt)
238+
compositeKeyPurgeIndexByTxid := createCompositeKeyForPurgeIndexByTxid(txid, uuid, blockHeight)
237239
dbBatch.Delete(compositeKeyPurgeIndexByTxid)
238240

239241
// Remove purge index -- purgeIndexByHeight
@@ -244,19 +246,19 @@ func (s *store) PurgeByHeight(maxBlockNumToRetain uint64) error {
244246
return s.db.WriteBatch(dbBatch, true)
245247
}
246248

247-
// GetMinEndorsementBlkHt returns the lowest retained endorsement block height
248-
func (s *store) GetMinEndorsementBlkHt() (uint64, error) {
249+
// GetMinTransientBlkHt returns the lowest block height remaining in transient store
250+
func (s *store) GetMinTransientBlkHt() (uint64, error) {
249251
// Current approach performs a range query on purgeIndex with startKey
250-
// as 0 (i.e., endorsementBlkHt) and returns the first key which denotes
251-
// the lowest retained endorsement block height. An alternative approach
252-
// is to explicitly store the minEndorsementBlkHt in the transientStore.
252+
// as 0 (i.e., blockHeight) and returns the first key which denotes
253+
// the lowest block height remaining in transient store. An alternative approach
254+
// is to explicitly store the minBlockHeight in the transientStore.
253255
startKey := createPurgeIndexByHeightRangeStartKey(0)
254256
iter := s.db.GetIterator(startKey, nil)
255-
// Fetch the minimum endorsement block height
257+
// Fetch the minimum transient block height
256258
if iter.Next() {
257259
dbKey := iter.Key()
258-
_, _, endorsementBlkHt := splitCompositeKeyOfPurgeIndexByHeight(dbKey)
259-
return endorsementBlkHt, nil
260+
_, _, blockHeight := splitCompositeKeyOfPurgeIndexByHeight(dbKey)
261+
return blockHeight, nil
260262
}
261263
iter.Release()
262264
// Returning an error may not be the right thing to do here. May be
@@ -277,7 +279,7 @@ func (scanner *RwsetScanner) Next() (*EndorserPvtSimulationResults, error) {
277279
}
278280
dbKey := scanner.dbItr.Key()
279281
dbVal := scanner.dbItr.Value()
280-
_, endorsementBlkHt := splitCompositeKeyOfPvtRWSet(dbKey)
282+
_, blockHeight := splitCompositeKeyOfPvtRWSet(dbKey)
281283

282284
txPvtRWSet := &rwset.TxPvtReadWriteSet{}
283285
if err := proto.Unmarshal(dbVal, txPvtRWSet); err != nil {
@@ -286,8 +288,8 @@ func (scanner *RwsetScanner) Next() (*EndorserPvtSimulationResults, error) {
286288
filteredTxPvtRWSet := pvtdatastorage.TrimPvtWSet(txPvtRWSet, scanner.filter)
287289

288290
return &EndorserPvtSimulationResults{
289-
EndorsementBlockHeight: endorsementBlkHt,
290-
PvtSimulationResults: filteredTxPvtRWSet,
291+
ReceivedAtBlockHeight: blockHeight,
292+
PvtSimulationResults: filteredTxPvtRWSet,
291293
}, nil
292294
}
293295

0 commit comments

Comments
 (0)