Skip to content

Commit

Permalink
[FAB-10788] Fix range query info in simulation results
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
manish-sethi authored and denyeart committed Jun 25, 2018
1 parent 61a1290 commit 82a6056
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 53 deletions.
17 changes: 4 additions & 13 deletions core/ledger/kvledger/txmgmt/txmgr/lockbasedtxmgr/helper.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,6 @@
/*
Copyright IBM Corp. 2016 All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package lockbasedtxmgr
Expand Down Expand Up @@ -201,7 +190,9 @@ func (h *queryHelper) done() {
itr.Close()
}
}()
}

func (h *queryHelper) addRangeQueryInfo() {
for _, itr := range h.itrs {
if h.rwsetBuilder != nil {
results, hash, err := itr.rangeQueryResultsHelper.Done()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,6 @@
/*
Copyright IBM Corp. 2016 All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/

package lockbasedtxmgr
Expand All @@ -29,16 +18,17 @@ import (
// LockBasedTxSimulator is a transaction simulator used in `LockBasedTxMgr`
type lockBasedTxSimulator struct {
lockBasedQueryExecutor
rwsetBuilder *rwsetutil.RWSetBuilder
writePerformed bool
pvtdataQueriesPerformed bool
rwsetBuilder *rwsetutil.RWSetBuilder
writePerformed bool
pvtdataQueriesPerformed bool
simulationResultsComputed bool
}

func newLockBasedTxSimulator(txmgr *LockBasedTxMgr, txid string) (*lockBasedTxSimulator, error) {
rwsetBuilder := rwsetutil.NewRWSetBuilder()
helper := newQueryHelper(txmgr, rwsetBuilder)
logger.Debugf("constructing new tx simulator txid = [%s]", txid)
return &lockBasedTxSimulator{lockBasedQueryExecutor{helper, txid}, rwsetBuilder, false, false}, nil
return &lockBasedTxSimulator{lockBasedQueryExecutor{helper, txid}, rwsetBuilder, false, false, false}, nil
}

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

// GetTxSimulationResults implements method in interface `ledger.TxSimulator`
func (s *lockBasedTxSimulator) GetTxSimulationResults() (*ledger.TxSimulationResults, error) {
if s.simulationResultsComputed {
return nil, errors.New("the function GetTxSimulationResults() should only be called once on a transaction simulator instance")
}
defer func() { s.simulationResultsComputed = true }()
logger.Debugf("Simulation completed, getting simulation results")
if s.helper.err != nil {
return nil, s.helper.err
}
s.helper.addRangeQueryInfo()
return s.rwsetBuilder.GetTxSimulationResults()
}

Expand Down
30 changes: 7 additions & 23 deletions core/ledger/kvledger/txmgmt/txmgr/lockbasedtxmgr/txmgr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,26 +111,11 @@ func TestTxSimulatorGetResults(t *testing.T) {
simulator.GetState("ns2", "key2")
simulator.GetPrivateData("ns2", "coll2", "key2")
simulator.SetState("ns2", "key2", []byte("value2"))
// get simulation results and verify that this contains rwset for both the namespaces "ns1" and "ns2"
simulationResults2, err := simulator.GetTxSimulationResults()
assert.Equal(t, 3, len(simulationResults2.PubSimulationResults.NsRwset))
// clone freeze simulationResults2
buff2 := new(bytes.Buffer)
assert.NoError(t, gob.NewEncoder(buff2).Encode(simulationResults2))
frozenSimulationResults2 := &ledger.TxSimulationResults{}
assert.NoError(t, gob.NewDecoder(buff2).Decode(&frozenSimulationResults2))

// use the same simulator further to operate on different keys in the namespcace "ns1"
simulator.GetState("ns1", "key3")
simulator.GetPrivateData("ns1", "coll3", "key3")
simulator.SetState("ns1", "key3", []byte("value3"))
// get simulation results and verify that this contains rwset for both the namespaces "ns1" and "ns2"
simulationResults3, err := simulator.GetTxSimulationResults()
assert.Equal(t, 3, len(simulationResults3.PubSimulationResults.NsRwset))

// get simulation results and verify that an error is raised when obtaining the simulation results more than once
_, err = simulator.GetTxSimulationResults()
assert.Error(t, err) // calling 'GetTxSimulationResults()' more than once should raise error
// Now, verify that the simulator operations did not have an effect on privously obtained results
assert.Equal(t, frozenSimulationResults1, simulationResults1)
assert.Equal(t, frozenSimulationResults2, simulationResults2)

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

// simulate tx2
Expand All @@ -319,8 +304,8 @@ func testTxPhantomValidation(t *testing.T, env testEnv) {
}
}
s2.DeleteState("ns", "key3")
s2.Done()
txRWSet2, _ := s2.GetTxSimulationResults()
s2.Done()

// simulate tx3
s3, _ := txMgr.NewTxSimulator("test_tx3")
Expand All @@ -331,9 +316,8 @@ func testTxPhantomValidation(t *testing.T, env testEnv) {
}
}
s3.SetState("ns", "key3", []byte("value3_new"))
s3.Done()
txRWSet3, _ := s3.GetTxSimulationResults()

s3.Done()
// simulate tx4
s4, _ := txMgr.NewTxSimulator("test_tx4")
itr4, _ := s4.GetStateRangeScanIterator("ns", "key4", "key6")
Expand All @@ -343,8 +327,8 @@ func testTxPhantomValidation(t *testing.T, env testEnv) {
}
}
s4.SetState("ns", "key3", []byte("value3_new"))
s4.Done()
txRWSet4, _ := s4.GetTxSimulationResults()
s4.Done()

// txRWSet2 should be valid
txMgrHelper.validateAndCommitRWSet(txRWSet2.PubSimulationResults)
Expand Down

0 comments on commit 82a6056

Please sign in to comment.