1
1
/*
2
- Copyright IBM Corp. 2017 All Rights Reserved.
2
+ Copyright IBM Corp. All Rights Reserved.
3
3
4
- Licensed under the Apache License, Version 2.0 (the "License");
5
- you may not use this file except in compliance with the License.
6
- You may obtain a copy of the License at
7
-
8
- http://www.apache.org/licenses/LICENSE-2.0
9
-
10
- Unless required by applicable law or agreed to in writing, software
11
- distributed under the License is distributed on an "AS IS" BASIS,
12
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- See the License for the specific language governing permissions and
14
- limitations under the License.
4
+ SPDX-License-Identifier: Apache-2.0
15
5
*/
16
6
17
7
package transientstore
18
8
19
9
import (
20
10
"errors"
21
11
22
- commonledger "github.com/hyperledger/fabric/common/ledger"
12
+ "github.com/golang/protobuf/proto"
13
+ "github.com/hyperledger/fabric/protos/ledger/rwset"
14
+
23
15
"github.com/hyperledger/fabric/common/ledger/util/leveldbhelper"
16
+ "github.com/hyperledger/fabric/core/ledger"
17
+ "github.com/hyperledger/fabric/core/ledger/pvtdatastorage"
24
18
"github.com/syndtr/goleveldb/leveldb/iterator"
25
19
)
26
20
@@ -44,10 +38,10 @@ type StoreProvider interface {
44
38
// the permanent storage or the pruning of some data items is enforced by the policy
45
39
type Store interface {
46
40
// Persist stores the private read-write set of a transaction in the transient store
47
- Persist (txid string , endorserid string , endorsementBlkHt uint64 , privateSimulationResults [] byte ) error
41
+ Persist (txid string , endorserid string , endorsementBlkHt uint64 , privateSimulationResults * rwset. TxPvtReadWriteSet ) error
48
42
// GetTxPvtRWSetByTxid returns an iterator due to the fact that the txid may have multiple private
49
43
// RWSets persisted from different endorsers (via Gossip)
50
- GetTxPvtRWSetByTxid (txid string ) (commonledger. ResultsIterator , error )
44
+ GetTxPvtRWSetByTxid (txid string , filter ledger. PvtNsCollFilter ) (* rwsetScanner , error )
51
45
// GetSelfSimulatedTxPvtRWSetByTxid returns the private read-write set generated from the simulation
52
46
// performed by the peer itself
53
47
GetSelfSimulatedTxPvtRWSetByTxid (txid string ) (* EndorserPvtSimulationResults , error )
@@ -64,7 +58,7 @@ type Store interface {
64
58
type EndorserPvtSimulationResults struct {
65
59
EndorserID string
66
60
EndorsementBlockHeight uint64
67
- PvtSimulationResults [] byte
61
+ PvtSimulationResults * rwset. TxPvtReadWriteSet
68
62
}
69
63
70
64
//////////////////////////////////////////////
@@ -85,8 +79,9 @@ type store struct {
85
79
}
86
80
87
81
type rwsetScanner struct {
88
- txid string
89
- dbItr iterator.Iterator
82
+ txid string
83
+ dbItr iterator.Iterator
84
+ filter ledger.PvtNsCollFilter
90
85
}
91
86
92
87
// NewStoreProvider instantiates TransientStoreProvider
@@ -95,16 +90,6 @@ func NewStoreProvider() StoreProvider {
95
90
return & storeProvider {dbProvider : dbProvider }
96
91
}
97
92
98
- // NewCustomPathStoreProvider constructs a StoreProvider at the given path
99
- // This function is used by ledger to construct a dedicated store till the time the store is managed
100
- // by the transient coordinator. A separate store location by the ledger is desired so that
101
- // the coordinator can be developed independently to handle the management of the transient store at default location.
102
- // Once the coordinator is developed, the ledger can stop using the transient store and this function can be removed.
103
- func NewCustomPathStoreProvider (path string ) StoreProvider {
104
- dbProvider := leveldbhelper .NewProvider (& leveldbhelper.Conf {DBPath : path })
105
- return & storeProvider {dbProvider : dbProvider }
106
- }
107
-
108
93
// OpenStore returns a handle to a ledgerId in Store
109
94
func (provider * storeProvider ) OpenStore (ledgerID string ) (Store , error ) {
110
95
dbHandle := provider .dbProvider .GetDBHandle (ledgerID )
@@ -118,12 +103,16 @@ func (provider *storeProvider) Close() {
118
103
119
104
// Persist stores the private read-write set of a transaction in the transient store
120
105
func (s * store ) Persist (txid string , endorserid string ,
121
- endorsementBlkHt uint64 , privateSimulationResults [] byte ) error {
106
+ endorsementBlkHt uint64 , privateSimulationResults * rwset. TxPvtReadWriteSet ) error {
122
107
dbBatch := leveldbhelper .NewUpdateBatch ()
123
108
124
109
// Create compositeKey with appropriate prefix, txid, endorserid and endorsementBlkHt
125
110
compositeKey := createCompositeKeyForPvtRWSet (txid , endorserid , endorsementBlkHt )
126
- dbBatch .Put (compositeKey , privateSimulationResults )
111
+ privateSimulationResultsBytes , err := proto .Marshal (privateSimulationResults )
112
+ if err != nil {
113
+ return err
114
+ }
115
+ dbBatch .Put (compositeKey , privateSimulationResultsBytes )
127
116
128
117
// Create compositeKey with appropriate prefix, endorsementBlkHt, txid, endorserid & Store
129
118
// the compositeKey (purge index) a null byte as value.
@@ -136,34 +125,29 @@ func (s *store) Persist(txid string, endorserid string,
136
125
// GetTxPvtRWSetByTxid returns an iterator due to the fact that the txid may have multiple private
137
126
// RWSets persisted from different endorserids. Eventually, we may pass a set of collections name
138
127
// (filters) along with txid.
139
- func (s * store ) GetTxPvtRWSetByTxid (txid string ) (commonledger. ResultsIterator , error ) {
128
+ func (s * store ) GetTxPvtRWSetByTxid (txid string , filter ledger. PvtNsCollFilter ) (* rwsetScanner , error ) {
140
129
// Construct startKey and endKey to do an range query
141
130
startKey := createTxidRangeStartKey (txid )
142
131
endKey := createTxidRangeEndKey (txid )
143
132
144
133
iter := s .db .GetIterator (startKey , endKey )
145
- return & rwsetScanner {txid , iter }, nil
134
+ return & rwsetScanner {txid , iter , filter }, nil
146
135
}
147
136
148
137
// GetSelfSimulatedTxPvtRWSetByTxid returns the private write set generated from the simulation performed
149
138
// by the peer itself. Eventually, we may pass a set of collections name (filters) along with txid.
150
139
func (s * store ) GetSelfSimulatedTxPvtRWSetByTxid (txid string ) (* EndorserPvtSimulationResults , error ) {
151
140
var err error
152
- var itr commonledger. ResultsIterator
153
- if itr , err = s .GetTxPvtRWSetByTxid (txid ); err != nil {
141
+ var itr * rwsetScanner
142
+ if itr , err = s .GetTxPvtRWSetByTxid (txid , nil ); err != nil {
154
143
return nil , err
155
144
}
156
145
defer itr .Close ()
157
- var temp commonledger.QueryResult
158
146
var res * EndorserPvtSimulationResults
159
147
for {
160
- if temp , err = itr .Next (); err != nil {
148
+ if res , err = itr .Next (); res == nil || err != nil {
161
149
return nil , err
162
150
}
163
- if temp == nil {
164
- return nil , nil
165
- }
166
- res = temp .(* EndorserPvtSimulationResults )
167
151
if selfSimulated (res ) {
168
152
return res , nil
169
153
}
@@ -219,17 +203,24 @@ func (s *store) Shutdown() {
219
203
220
204
// Next moves the iterator to the next key/value pair.
221
205
// It returns whether the iterator is exhausted.
222
- func (scanner * rwsetScanner ) Next () (commonledger. QueryResult , error ) {
206
+ func (scanner * rwsetScanner ) Next () (* EndorserPvtSimulationResults , error ) {
223
207
if ! scanner .dbItr .Next () {
224
208
return nil , nil
225
209
}
226
210
dbKey := scanner .dbItr .Key ()
227
211
dbVal := scanner .dbItr .Value ()
228
212
endorserid , endorsementBlkHt := splitCompositeKeyOfPvtRWSet (dbKey )
213
+
214
+ txPvtRWSet := & rwset.TxPvtReadWriteSet {}
215
+ if err := proto .Unmarshal (dbVal , txPvtRWSet ); err != nil {
216
+ return nil , err
217
+ }
218
+ filteredTxPvtRWSet := pvtdatastorage .TrimPvtWSet (txPvtRWSet , scanner .filter )
219
+
229
220
return & EndorserPvtSimulationResults {
230
221
EndorserID : endorserid ,
231
222
EndorsementBlockHeight : endorsementBlkHt ,
232
- PvtSimulationResults : dbVal ,
223
+ PvtSimulationResults : filteredTxPvtRWSet ,
233
224
}, nil
234
225
}
235
226
0 commit comments