Skip to content

Commit 28d0a9d

Browse files
committed
[FAB-10788] Fix range query info in simulation results
The range query info was being computed and added to simulation results when the on the 'Done' function call. However, now, in the endorser 'Done' call is made after obtaining the simulation results. This CR adds range query info during the invocation to 'GetTxSimulationResults'. Change-Id: I522336f22e5c695848afd93582bab43e28a10e62 Signed-off-by: manish <manish.sethi@gmail.com>
1 parent fef758e commit 28d0a9d

File tree

3 files changed

+23
-53
lines changed

3 files changed

+23
-53
lines changed

core/ledger/kvledger/txmgmt/txmgr/lockbasedtxmgr/helper.go

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,6 @@
11
/*
2-
Copyright IBM Corp. 2016 All Rights Reserved.
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.
2+
Copyright IBM Corp. All Rights Reserved.
3+
SPDX-License-Identifier: Apache-2.0
154
*/
165

176
package lockbasedtxmgr
@@ -201,7 +190,9 @@ func (h *queryHelper) done() {
201190
itr.Close()
202191
}
203192
}()
193+
}
204194

195+
func (h *queryHelper) addRangeQueryInfo() {
205196
for _, itr := range h.itrs {
206197
if h.rwsetBuilder != nil {
207198
results, hash, err := itr.rangeQueryResultsHelper.Done()

core/ledger/kvledger/txmgmt/txmgr/lockbasedtxmgr/lockbased_tx_simulator.go

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,6 @@
11
/*
2-
Copyright IBM Corp. 2016 All Rights Reserved.
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.
2+
Copyright IBM Corp. All Rights Reserved.
3+
SPDX-License-Identifier: Apache-2.0
154
*/
165

176
package lockbasedtxmgr
@@ -29,16 +18,17 @@ import (
2918
// LockBasedTxSimulator is a transaction simulator used in `LockBasedTxMgr`
3019
type lockBasedTxSimulator struct {
3120
lockBasedQueryExecutor
32-
rwsetBuilder *rwsetutil.RWSetBuilder
33-
writePerformed bool
34-
pvtdataQueriesPerformed bool
21+
rwsetBuilder *rwsetutil.RWSetBuilder
22+
writePerformed bool
23+
pvtdataQueriesPerformed bool
24+
simulationResultsComputed bool
3525
}
3626

3727
func newLockBasedTxSimulator(txmgr *LockBasedTxMgr, txid string) (*lockBasedTxSimulator, error) {
3828
rwsetBuilder := rwsetutil.NewRWSetBuilder()
3929
helper := newQueryHelper(txmgr, rwsetBuilder)
4030
logger.Debugf("constructing new tx simulator txid = [%s]", txid)
41-
return &lockBasedTxSimulator{lockBasedQueryExecutor{helper, txid}, rwsetBuilder, false, false}, nil
31+
return &lockBasedTxSimulator{lockBasedQueryExecutor{helper, txid}, rwsetBuilder, false, false, false}, nil
4232
}
4333

4434
// SetState implements method in interface `ledger.TxSimulator`
@@ -143,10 +133,15 @@ func (s *lockBasedTxSimulator) ExecuteQueryOnPrivateData(namespace, collection,
143133

144134
// GetTxSimulationResults implements method in interface `ledger.TxSimulator`
145135
func (s *lockBasedTxSimulator) GetTxSimulationResults() (*ledger.TxSimulationResults, error) {
136+
if s.simulationResultsComputed {
137+
return nil, errors.New("the function GetTxSimulationResults() should only be called once on a transaction simulator instance")
138+
}
139+
defer func() { s.simulationResultsComputed = true }()
146140
logger.Debugf("Simulation completed, getting simulation results")
147141
if s.helper.err != nil {
148142
return nil, s.helper.err
149143
}
144+
s.helper.addRangeQueryInfo()
150145
return s.rwsetBuilder.GetTxSimulationResults()
151146
}
152147

core/ledger/kvledger/txmgmt/txmgr/lockbasedtxmgr/txmgr_test.go

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -111,26 +111,11 @@ func TestTxSimulatorGetResults(t *testing.T) {
111111
simulator.GetState("ns2", "key2")
112112
simulator.GetPrivateData("ns2", "coll2", "key2")
113113
simulator.SetState("ns2", "key2", []byte("value2"))
114-
// get simulation results and verify that this contains rwset for both the namespaces "ns1" and "ns2"
115-
simulationResults2, err := simulator.GetTxSimulationResults()
116-
assert.Equal(t, 3, len(simulationResults2.PubSimulationResults.NsRwset))
117-
// clone freeze simulationResults2
118-
buff2 := new(bytes.Buffer)
119-
assert.NoError(t, gob.NewEncoder(buff2).Encode(simulationResults2))
120-
frozenSimulationResults2 := &ledger.TxSimulationResults{}
121-
assert.NoError(t, gob.NewDecoder(buff2).Decode(&frozenSimulationResults2))
122-
123-
// use the same simulator further to operate on different keys in the namespcace "ns1"
124-
simulator.GetState("ns1", "key3")
125-
simulator.GetPrivateData("ns1", "coll3", "key3")
126-
simulator.SetState("ns1", "key3", []byte("value3"))
127-
// get simulation results and verify that this contains rwset for both the namespaces "ns1" and "ns2"
128-
simulationResults3, err := simulator.GetTxSimulationResults()
129-
assert.Equal(t, 3, len(simulationResults3.PubSimulationResults.NsRwset))
130-
114+
// get simulation results and verify that an error is raised when obtaining the simulation results more than once
115+
_, err = simulator.GetTxSimulationResults()
116+
assert.Error(t, err) // calling 'GetTxSimulationResults()' more than once should raise error
131117
// Now, verify that the simulator operations did not have an effect on privously obtained results
132118
assert.Equal(t, frozenSimulationResults1, simulationResults1)
133-
assert.Equal(t, frozenSimulationResults2, simulationResults2)
134119

135120
// Call 'Done' and all the data get/set operations after calling 'Done' should fail.
136121
simulator.Done()
@@ -305,9 +290,9 @@ func testTxPhantomValidation(t *testing.T, env testEnv) {
305290
s1.SetState("ns", "key4", []byte("value4"))
306291
s1.SetState("ns", "key5", []byte("value5"))
307292
s1.SetState("ns", "key6", []byte("value6"))
308-
s1.Done()
309293
// validate and commit RWset
310294
txRWSet1, _ := s1.GetTxSimulationResults()
295+
s1.Done() // explicitly calling done after obtaining the results to verify FAB-10788
311296
txMgrHelper.validateAndCommitRWSet(txRWSet1.PubSimulationResults)
312297

313298
// simulate tx2
@@ -319,8 +304,8 @@ func testTxPhantomValidation(t *testing.T, env testEnv) {
319304
}
320305
}
321306
s2.DeleteState("ns", "key3")
322-
s2.Done()
323307
txRWSet2, _ := s2.GetTxSimulationResults()
308+
s2.Done()
324309

325310
// simulate tx3
326311
s3, _ := txMgr.NewTxSimulator("test_tx3")
@@ -331,9 +316,8 @@ func testTxPhantomValidation(t *testing.T, env testEnv) {
331316
}
332317
}
333318
s3.SetState("ns", "key3", []byte("value3_new"))
334-
s3.Done()
335319
txRWSet3, _ := s3.GetTxSimulationResults()
336-
320+
s3.Done()
337321
// simulate tx4
338322
s4, _ := txMgr.NewTxSimulator("test_tx4")
339323
itr4, _ := s4.GetStateRangeScanIterator("ns", "key4", "key6")
@@ -343,8 +327,8 @@ func testTxPhantomValidation(t *testing.T, env testEnv) {
343327
}
344328
}
345329
s4.SetState("ns", "key3", []byte("value3_new"))
346-
s4.Done()
347330
txRWSet4, _ := s4.GetTxSimulationResults()
331+
s4.Done()
348332

349333
// txRWSet2 should be valid
350334
txMgrHelper.validateAndCommitRWSet(txRWSet2.PubSimulationResults)

0 commit comments

Comments
 (0)