github.com/ewagmig/fabric@v2.1.1+incompatible/core/ledger/kvledger/txmgmt/txmgr/lockbasedtxmgr/txmgr_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package lockbasedtxmgr
     8  
     9  import (
    10  	"bytes"
    11  	"encoding/gob"
    12  	"encoding/json"
    13  	"fmt"
    14  	"strings"
    15  	"testing"
    16  
    17  	"github.com/hyperledger/fabric-protos-go/ledger/queryresult"
    18  	"github.com/hyperledger/fabric/common/ledger/testutil"
    19  	"github.com/hyperledger/fabric/core/ledger"
    20  	"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/privacyenabledstate"
    21  	"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/rwsetutil"
    22  	"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/txmgr"
    23  	"github.com/hyperledger/fabric/core/ledger/kvledger/txmgmt/version"
    24  	btltestutil "github.com/hyperledger/fabric/core/ledger/pvtdatapolicy/testutil"
    25  	"github.com/hyperledger/fabric/core/ledger/util"
    26  	"github.com/stretchr/testify/assert"
    27  )
    28  
    29  func TestTxSimulatorWithNoExistingData(t *testing.T) {
    30  	// run the tests for each environment configured in pkg_test.go
    31  	for _, testEnv := range testEnvs {
    32  		t.Logf("Running test for TestEnv = %s", testEnv.getName())
    33  		testLedgerID := "testtxsimulatorwithnoexistingdata"
    34  		testEnv.init(t, testLedgerID, nil)
    35  		testTxSimulatorWithNoExistingData(t, testEnv)
    36  		testEnv.cleanup()
    37  	}
    38  }
    39  
    40  func testTxSimulatorWithNoExistingData(t *testing.T, env testEnv) {
    41  	txMgr := env.getTxMgr()
    42  	s, _ := txMgr.NewTxSimulator("test_txid")
    43  	value, err := s.GetState("ns1", "key1")
    44  	assert.NoErrorf(t, err, "Error in GetState(): %s", err)
    45  	assert.Nil(t, value)
    46  
    47  	s.SetState("ns1", "key1", []byte("value1"))
    48  	s.SetState("ns1", "key2", []byte("value2"))
    49  	s.SetState("ns2", "key3", []byte("value3"))
    50  	s.SetState("ns2", "key4", []byte("value4"))
    51  
    52  	value, _ = s.GetState("ns2", "key3")
    53  	assert.Nil(t, value)
    54  
    55  	simulationResults, err := s.GetTxSimulationResults()
    56  	assert.NoError(t, err)
    57  	assert.Nil(t, simulationResults.PvtSimulationResults)
    58  }
    59  
    60  func TestTxSimulatorGetResults(t *testing.T) {
    61  	testEnv := testEnvsMap[levelDBtestEnvName]
    62  	testEnv.init(t, "testLedger", nil)
    63  	defer testEnv.cleanup()
    64  	txMgr := testEnv.getTxMgr()
    65  	populateCollConfigForTest(t, txMgr.(*LockBasedTxMgr),
    66  		[]collConfigkey{
    67  			{"ns1", "coll1"},
    68  			{"ns1", "coll3"},
    69  			{"ns2", "coll2"},
    70  			{"ns3", "coll3"},
    71  		},
    72  		version.NewHeight(1, 1),
    73  	)
    74  
    75  	var err error
    76  
    77  	// Create a simulator and get/set keys in one namespace "ns1"
    78  	simulator, _ := testEnv.getTxMgr().NewTxSimulator("test_txid1")
    79  	simulator.GetState("ns1", "key1")
    80  	_, err = simulator.GetPrivateData("ns1", "coll1", "key1")
    81  	assert.NoError(t, err)
    82  	simulator.SetState("ns1", "key1", []byte("value1"))
    83  	// get simulation results and verify that this contains rwset only for one namespace
    84  	simulationResults1, err := simulator.GetTxSimulationResults()
    85  	assert.NoError(t, err)
    86  	assert.Len(t, simulationResults1.PubSimulationResults.NsRwset, 1)
    87  	// clone freeze simulationResults1
    88  	buff1 := new(bytes.Buffer)
    89  	assert.NoError(t, gob.NewEncoder(buff1).Encode(simulationResults1))
    90  	frozenSimulationResults1 := &ledger.TxSimulationResults{}
    91  	assert.NoError(t, gob.NewDecoder(buff1).Decode(&frozenSimulationResults1))
    92  
    93  	// use the same simulator after obtaining the simulation results by get/set keys in one more namespace "ns2"
    94  	simulator.GetState("ns2", "key2")
    95  	simulator.GetPrivateData("ns2", "coll2", "key2")
    96  	simulator.SetState("ns2", "key2", []byte("value2"))
    97  	// get simulation results and verify that an error is raised when obtaining the simulation results more than once
    98  	_, err = simulator.GetTxSimulationResults()
    99  	assert.Error(t, err) // calling 'GetTxSimulationResults()' more than once should raise error
   100  	// Now, verify that the simulator operations did not have an effect on previously obtained results
   101  	assert.Equal(t, frozenSimulationResults1, simulationResults1)
   102  
   103  	// Call 'Done' and all the data get/set operations after calling 'Done' should fail.
   104  	simulator.Done()
   105  	_, err = simulator.GetState("ns3", "key3")
   106  	assert.Errorf(t, err, "An error is expected when using simulator to get/set data after calling `Done` function()")
   107  	err = simulator.SetState("ns3", "key3", []byte("value3"))
   108  	assert.Errorf(t, err, "An error is expected when using simulator to get/set data after calling `Done` function()")
   109  	_, err = simulator.GetPrivateData("ns3", "coll3", "key3")
   110  	assert.Errorf(t, err, "An error is expected when using simulator to get/set data after calling `Done` function()")
   111  	err = simulator.SetPrivateData("ns3", "coll3", "key3", []byte("value3"))
   112  	assert.Errorf(t, err, "An error is expected when using simulator to get/set data after calling `Done` function()")
   113  }
   114  
   115  func TestTxSimulatorWithExistingData(t *testing.T) {
   116  	for _, testEnv := range testEnvs {
   117  		t.Run(testEnv.getName(), func(t *testing.T) {
   118  			testLedgerID := "testtxsimulatorwithexistingdata"
   119  			testEnv.init(t, testLedgerID, nil)
   120  			testTxSimulatorWithExistingData(t, testEnv)
   121  			testEnv.cleanup()
   122  		})
   123  	}
   124  }
   125  
   126  func testTxSimulatorWithExistingData(t *testing.T, env testEnv) {
   127  	txMgr := env.getTxMgr()
   128  	txMgrHelper := newTxMgrTestHelper(t, txMgr)
   129  	// simulate tx1
   130  	s1, _ := txMgr.NewTxSimulator("test_tx1")
   131  	s1.SetState("ns1", "key1", []byte("value1"))
   132  	s1.SetState("ns1", "key2", []byte("value2"))
   133  	s1.SetState("ns2", "key3", []byte("value3"))
   134  	s1.SetState("ns2", "key4", []byte("value4"))
   135  	s1.Done()
   136  	// validate and commit RWset
   137  	txRWSet1, _ := s1.GetTxSimulationResults()
   138  	txMgrHelper.validateAndCommitRWSet(txRWSet1.PubSimulationResults)
   139  
   140  	// simulate tx2 that make changes to existing data
   141  	s2, _ := txMgr.NewTxSimulator("test_tx2")
   142  	value, _ := s2.GetState("ns1", "key1")
   143  	assert.Equal(t, []byte("value1"), value)
   144  	s2.SetState("ns1", "key1", []byte("value1_1"))
   145  	s2.DeleteState("ns2", "key3")
   146  	value, _ = s2.GetState("ns1", "key1")
   147  	assert.Equal(t, []byte("value1"), value)
   148  	s2.Done()
   149  	// validate and commit RWset for tx2
   150  	txRWSet2, _ := s2.GetTxSimulationResults()
   151  	txMgrHelper.validateAndCommitRWSet(txRWSet2.PubSimulationResults)
   152  
   153  	// simulate tx3
   154  	s3, _ := txMgr.NewTxSimulator("test_tx3")
   155  	value, _ = s3.GetState("ns1", "key1")
   156  	assert.Equal(t, []byte("value1_1"), value)
   157  	value, _ = s3.GetState("ns2", "key3")
   158  	assert.Nil(t, value)
   159  	s3.Done()
   160  
   161  	// verify the versions of keys in persistence
   162  	vv, _ := env.getVDB().GetState("ns1", "key1")
   163  	assert.Equal(t, version.NewHeight(2, 0), vv.Version)
   164  	vv, _ = env.getVDB().GetState("ns1", "key2")
   165  	assert.Equal(t, version.NewHeight(1, 0), vv.Version)
   166  }
   167  
   168  func TestTxValidation(t *testing.T) {
   169  	for _, testEnv := range testEnvs {
   170  		t.Logf("Running test for TestEnv = %s", testEnv.getName())
   171  		testLedgerID := "testtxvalidation"
   172  		testEnv.init(t, testLedgerID, nil)
   173  		testTxValidation(t, testEnv)
   174  		testEnv.cleanup()
   175  	}
   176  }
   177  
   178  func testTxValidation(t *testing.T, env testEnv) {
   179  	txMgr := env.getTxMgr()
   180  	txMgrHelper := newTxMgrTestHelper(t, txMgr)
   181  	// simulate tx1
   182  	s1, _ := txMgr.NewTxSimulator("test_tx1")
   183  	s1.SetState("ns1", "key1", []byte("value1"))
   184  	s1.SetState("ns1", "key2", []byte("value2"))
   185  	s1.SetState("ns2", "key3", []byte("value3"))
   186  	s1.SetState("ns2", "key4", []byte("value4"))
   187  	s1.Done()
   188  	// validate and commit RWset
   189  	txRWSet1, _ := s1.GetTxSimulationResults()
   190  	txMgrHelper.validateAndCommitRWSet(txRWSet1.PubSimulationResults)
   191  
   192  	// simulate tx2 that make changes to existing data.
   193  	// tx2: Read/Update ns1:key1, Delete ns2:key3.
   194  	s2, _ := txMgr.NewTxSimulator("test_tx2")
   195  	value, _ := s2.GetState("ns1", "key1")
   196  	assert.Equal(t, []byte("value1"), value)
   197  
   198  	s2.SetState("ns1", "key1", []byte("value1_2"))
   199  	s2.DeleteState("ns2", "key3")
   200  	s2.Done()
   201  
   202  	// simulate tx3 before committing tx2 changes. Reads and modifies the key changed by tx2.
   203  	// tx3: Read/Update ns1:key1
   204  	s3, _ := txMgr.NewTxSimulator("test_tx3")
   205  	s3.GetState("ns1", "key1")
   206  	s3.SetState("ns1", "key1", []byte("value1_3"))
   207  	s3.Done()
   208  
   209  	// simulate tx4 before committing tx2 changes. Reads and Deletes the key changed by tx2
   210  	// tx4: Read/Delete ns2:key3
   211  	s4, _ := txMgr.NewTxSimulator("test_tx4")
   212  	s4.GetState("ns2", "key3")
   213  	s4.DeleteState("ns2", "key3")
   214  	s4.Done()
   215  
   216  	// simulate tx5 before committing tx2 changes. Modifies and then Reads the key changed by tx2 and writes a new key
   217  	// tx5: Update/Read ns1:key1
   218  	s5, _ := txMgr.NewTxSimulator("test_tx5")
   219  	s5.SetState("ns1", "key1", []byte("new_value"))
   220  	s5.GetState("ns1", "key1")
   221  	s5.Done()
   222  
   223  	// simulate tx6 before committing tx2 changes. Only writes a new key, does not reads/writes a key changed by tx2
   224  	// tx6: Update ns1:new_key
   225  	s6, _ := txMgr.NewTxSimulator("test_tx6")
   226  	s6.SetState("ns1", "new_key", []byte("new_value"))
   227  	s6.Done()
   228  
   229  	// Summary of simulated transactions
   230  	// tx2: Read/Update ns1:key1, Delete ns2:key3.
   231  	// tx3: Read/Update ns1:key1
   232  	// tx4: Read/Delete ns2:key3
   233  	// tx5: Update/Read ns1:key1
   234  	// tx6: Update ns1:new_key
   235  
   236  	// validate and commit RWset for tx2
   237  	txRWSet2, _ := s2.GetTxSimulationResults()
   238  	txMgrHelper.validateAndCommitRWSet(txRWSet2.PubSimulationResults)
   239  
   240  	//RWSet for tx3 and tx4 and tx5 should be invalid now due to read conflicts
   241  	txRWSet3, _ := s3.GetTxSimulationResults()
   242  	txMgrHelper.checkRWsetInvalid(txRWSet3.PubSimulationResults)
   243  
   244  	txRWSet4, _ := s4.GetTxSimulationResults()
   245  	txMgrHelper.checkRWsetInvalid(txRWSet4.PubSimulationResults)
   246  
   247  	txRWSet5, _ := s5.GetTxSimulationResults()
   248  	txMgrHelper.checkRWsetInvalid(txRWSet5.PubSimulationResults)
   249  
   250  	// tx6 should still be valid as it only writes a new key
   251  	txRWSet6, _ := s6.GetTxSimulationResults()
   252  	txMgrHelper.validateAndCommitRWSet(txRWSet6.PubSimulationResults)
   253  }
   254  
   255  func TestTxPhantomValidation(t *testing.T) {
   256  	for _, testEnv := range testEnvs {
   257  		t.Logf("Running test for TestEnv = %s", testEnv.getName())
   258  		testLedgerID := "testtxphantomvalidation"
   259  		testEnv.init(t, testLedgerID, nil)
   260  		testTxPhantomValidation(t, testEnv)
   261  		testEnv.cleanup()
   262  	}
   263  }
   264  
   265  func testTxPhantomValidation(t *testing.T, env testEnv) {
   266  	txMgr := env.getTxMgr()
   267  	txMgrHelper := newTxMgrTestHelper(t, txMgr)
   268  	// simulate tx1
   269  	s1, _ := txMgr.NewTxSimulator("test_tx1")
   270  	s1.SetState("ns", "key1", []byte("value1"))
   271  	s1.SetState("ns", "key2", []byte("value2"))
   272  	s1.SetState("ns", "key3", []byte("value3"))
   273  	s1.SetState("ns", "key4", []byte("value4"))
   274  	s1.SetState("ns", "key5", []byte("value5"))
   275  	s1.SetState("ns", "key6", []byte("value6"))
   276  	// validate and commit RWset
   277  	txRWSet1, _ := s1.GetTxSimulationResults()
   278  	s1.Done() // explicitly calling done after obtaining the results to verify FAB-10788
   279  	txMgrHelper.validateAndCommitRWSet(txRWSet1.PubSimulationResults)
   280  
   281  	// simulate tx2
   282  	s2, _ := txMgr.NewTxSimulator("test_tx2")
   283  	itr2, _ := s2.GetStateRangeScanIterator("ns", "key2", "key5")
   284  	for {
   285  		if result, _ := itr2.Next(); result == nil {
   286  			break
   287  		}
   288  	}
   289  	s2.DeleteState("ns", "key3")
   290  	txRWSet2, _ := s2.GetTxSimulationResults()
   291  	s2.Done()
   292  
   293  	// simulate tx3
   294  	s3, _ := txMgr.NewTxSimulator("test_tx3")
   295  	itr3, _ := s3.GetStateRangeScanIterator("ns", "key2", "key5")
   296  	for {
   297  		if result, _ := itr3.Next(); result == nil {
   298  			break
   299  		}
   300  	}
   301  	s3.SetState("ns", "key3", []byte("value3_new"))
   302  	txRWSet3, _ := s3.GetTxSimulationResults()
   303  	s3.Done()
   304  	// simulate tx4
   305  	s4, _ := txMgr.NewTxSimulator("test_tx4")
   306  	itr4, _ := s4.GetStateRangeScanIterator("ns", "key4", "key6")
   307  	for {
   308  		if result, _ := itr4.Next(); result == nil {
   309  			break
   310  		}
   311  	}
   312  	s4.SetState("ns", "key3", []byte("value3_new"))
   313  	txRWSet4, _ := s4.GetTxSimulationResults()
   314  	s4.Done()
   315  
   316  	// txRWSet2 should be valid
   317  	txMgrHelper.validateAndCommitRWSet(txRWSet2.PubSimulationResults)
   318  	// txRWSet2 makes txRWSet3 invalid as it deletes a key in the range
   319  	txMgrHelper.checkRWsetInvalid(txRWSet3.PubSimulationResults)
   320  	// txRWSet4 should be valid as it iterates over a different range
   321  	txMgrHelper.validateAndCommitRWSet(txRWSet4.PubSimulationResults)
   322  }
   323  
   324  func TestIterator(t *testing.T) {
   325  	for _, testEnv := range testEnvs {
   326  		t.Logf("Running test for TestEnv = %s", testEnv.getName())
   327  
   328  		testLedgerID := "testiterator.1"
   329  		testEnv.init(t, testLedgerID, nil)
   330  		testIterator(t, testEnv, 10, 2, 7)
   331  		testEnv.cleanup()
   332  
   333  		testLedgerID = "testiterator.2"
   334  		testEnv.init(t, testLedgerID, nil)
   335  		testIterator(t, testEnv, 10, 1, 11)
   336  		testEnv.cleanup()
   337  
   338  		testLedgerID = "testiterator.3"
   339  		testEnv.init(t, testLedgerID, nil)
   340  		testIterator(t, testEnv, 10, 0, 0)
   341  		testEnv.cleanup()
   342  
   343  		testLedgerID = "testiterator.4"
   344  		testEnv.init(t, testLedgerID, nil)
   345  		testIterator(t, testEnv, 10, 5, 0)
   346  		testEnv.cleanup()
   347  
   348  		testLedgerID = "testiterator.5"
   349  		testEnv.init(t, testLedgerID, nil)
   350  		testIterator(t, testEnv, 10, 0, 5)
   351  		testEnv.cleanup()
   352  	}
   353  }
   354  
   355  func testIterator(t *testing.T, env testEnv, numKeys int, startKeyNum int, endKeyNum int) {
   356  	cID := "cid"
   357  	txMgr := env.getTxMgr()
   358  	txMgrHelper := newTxMgrTestHelper(t, txMgr)
   359  	s, _ := txMgr.NewTxSimulator("test_tx1")
   360  	for i := 1; i <= numKeys; i++ {
   361  		k := createTestKey(i)
   362  		v := createTestValue(i)
   363  		t.Logf("Adding k=[%s], v=[%s]", k, v)
   364  		s.SetState(cID, k, v)
   365  	}
   366  	s.Done()
   367  	// validate and commit RWset
   368  	txRWSet, _ := s.GetTxSimulationResults()
   369  	txMgrHelper.validateAndCommitRWSet(txRWSet.PubSimulationResults)
   370  
   371  	var startKey string
   372  	var endKey string
   373  	var begin int
   374  	var end int
   375  
   376  	if startKeyNum != 0 {
   377  		begin = startKeyNum
   378  		startKey = createTestKey(startKeyNum)
   379  	} else {
   380  		begin = 1 //first key in the db
   381  		startKey = ""
   382  	}
   383  
   384  	if endKeyNum != 0 {
   385  		endKey = createTestKey(endKeyNum)
   386  		end = endKeyNum
   387  	} else {
   388  		endKey = ""
   389  		end = numKeys + 1 //last key in the db
   390  	}
   391  
   392  	expectedCount := end - begin
   393  
   394  	queryExecuter, _ := txMgr.NewQueryExecutor("test_tx2")
   395  	itr, _ := queryExecuter.GetStateRangeScanIterator(cID, startKey, endKey)
   396  	count := 0
   397  	for {
   398  		kv, _ := itr.Next()
   399  		if kv == nil {
   400  			break
   401  		}
   402  		keyNum := begin + count
   403  		k := kv.(*queryresult.KV).Key
   404  		v := kv.(*queryresult.KV).Value
   405  		t.Logf("Retrieved k=%s, v=%s at count=%d start=%s end=%s", k, v, count, startKey, endKey)
   406  		assert.Equal(t, createTestKey(keyNum), k)
   407  		assert.Equal(t, createTestValue(keyNum), v)
   408  		count++
   409  	}
   410  	assert.Equal(t, expectedCount, count)
   411  }
   412  
   413  func TestIteratorPaging(t *testing.T) {
   414  	for _, testEnv := range testEnvs {
   415  		t.Logf("Running test for TestEnv = %s", testEnv.getName())
   416  
   417  		// test explicit paging
   418  		testLedgerID := "testiterator.1"
   419  		testEnv.init(t, testLedgerID, nil)
   420  		testIteratorPagingInit(t, testEnv, 10)
   421  		returnKeys := []string{"key_002", "key_003"}
   422  		nextStartKey := testIteratorPaging(t, testEnv, 10, "key_002", "key_007", int32(2), returnKeys)
   423  		returnKeys = []string{"key_004", "key_005"}
   424  		nextStartKey = testIteratorPaging(t, testEnv, 10, nextStartKey, "key_007", int32(2), returnKeys)
   425  		returnKeys = []string{"key_006"}
   426  		testIteratorPaging(t, testEnv, 10, nextStartKey, "key_007", int32(2), returnKeys)
   427  		testEnv.cleanup()
   428  	}
   429  }
   430  
   431  func testIteratorPagingInit(t *testing.T, env testEnv, numKeys int) {
   432  	cID := "cid"
   433  	txMgr := env.getTxMgr()
   434  	txMgrHelper := newTxMgrTestHelper(t, txMgr)
   435  	s, _ := txMgr.NewTxSimulator("test_tx1")
   436  	for i := 1; i <= numKeys; i++ {
   437  		k := createTestKey(i)
   438  		v := createTestValue(i)
   439  		t.Logf("Adding k=[%s], v=[%s]", k, v)
   440  		s.SetState(cID, k, v)
   441  	}
   442  	s.Done()
   443  	// validate and commit RWset
   444  	txRWSet, _ := s.GetTxSimulationResults()
   445  	txMgrHelper.validateAndCommitRWSet(txRWSet.PubSimulationResults)
   446  }
   447  
   448  func testIteratorPaging(t *testing.T, env testEnv, numKeys int, startKey, endKey string,
   449  	limit int32, expectedKeys []string) string {
   450  	cID := "cid"
   451  	txMgr := env.getTxMgr()
   452  
   453  	queryOptions := make(map[string]interface{})
   454  	if limit != 0 {
   455  		queryOptions["limit"] = limit
   456  	}
   457  
   458  	queryExecuter, _ := txMgr.NewQueryExecutor("test_tx2")
   459  	itr, _ := queryExecuter.GetStateRangeScanIteratorWithMetadata(cID, startKey, endKey, queryOptions)
   460  
   461  	// Verify the keys returned
   462  	testItrWithoutClose(t, itr, expectedKeys)
   463  
   464  	returnBookmark := ""
   465  	if limit > 0 {
   466  		returnBookmark = itr.GetBookmarkAndClose()
   467  	}
   468  
   469  	return returnBookmark
   470  }
   471  
   472  // testItrWithoutClose verifies an iterator contains expected keys
   473  func testItrWithoutClose(t *testing.T, itr ledger.QueryResultsIterator, expectedKeys []string) {
   474  	for _, expectedKey := range expectedKeys {
   475  		queryResult, err := itr.Next()
   476  		assert.NoError(t, err, "An unexpected error was thrown during iterator Next()")
   477  		vkv := queryResult.(*queryresult.KV)
   478  		key := vkv.Key
   479  		assert.Equal(t, expectedKey, key)
   480  	}
   481  	queryResult, err := itr.Next()
   482  	assert.NoError(t, err, "An unexpected error was thrown during iterator Next()")
   483  	assert.Nil(t, queryResult)
   484  }
   485  
   486  func TestIteratorWithDeletes(t *testing.T) {
   487  	for _, testEnv := range testEnvs {
   488  		t.Logf("Running test for TestEnv = %s", testEnv.getName())
   489  		testLedgerID := "testiteratorwithdeletes"
   490  		testEnv.init(t, testLedgerID, nil)
   491  		testIteratorWithDeletes(t, testEnv)
   492  		testEnv.cleanup()
   493  	}
   494  }
   495  
   496  func testIteratorWithDeletes(t *testing.T, env testEnv) {
   497  	cID := "cid"
   498  	txMgr := env.getTxMgr()
   499  	txMgrHelper := newTxMgrTestHelper(t, txMgr)
   500  	s, _ := txMgr.NewTxSimulator("test_tx1")
   501  	for i := 1; i <= 10; i++ {
   502  		k := createTestKey(i)
   503  		v := createTestValue(i)
   504  		t.Logf("Adding k=[%s], v=[%s]", k, v)
   505  		s.SetState(cID, k, v)
   506  	}
   507  	s.Done()
   508  	// validate and commit RWset
   509  	txRWSet1, _ := s.GetTxSimulationResults()
   510  	txMgrHelper.validateAndCommitRWSet(txRWSet1.PubSimulationResults)
   511  
   512  	s, _ = txMgr.NewTxSimulator("test_tx2")
   513  	s.DeleteState(cID, createTestKey(4))
   514  	s.Done()
   515  	// validate and commit RWset
   516  	txRWSet2, _ := s.GetTxSimulationResults()
   517  	txMgrHelper.validateAndCommitRWSet(txRWSet2.PubSimulationResults)
   518  
   519  	queryExecuter, _ := txMgr.NewQueryExecutor("test_tx3")
   520  	itr, _ := queryExecuter.GetStateRangeScanIterator(cID, createTestKey(3), createTestKey(6))
   521  	defer itr.Close()
   522  	kv, _ := itr.Next()
   523  	assert.Equal(t, createTestKey(3), kv.(*queryresult.KV).Key)
   524  	kv, _ = itr.Next()
   525  	assert.Equal(t, createTestKey(5), kv.(*queryresult.KV).Key)
   526  }
   527  
   528  func TestTxValidationWithItr(t *testing.T) {
   529  	for _, testEnv := range testEnvs {
   530  		t.Logf("Running test for TestEnv = %s", testEnv.getName())
   531  		testLedgerID := "testtxvalidationwithitr"
   532  		testEnv.init(t, testLedgerID, nil)
   533  		testTxValidationWithItr(t, testEnv)
   534  		testEnv.cleanup()
   535  	}
   536  }
   537  
   538  func testTxValidationWithItr(t *testing.T, env testEnv) {
   539  	cID := "cid"
   540  	txMgr := env.getTxMgr()
   541  	txMgrHelper := newTxMgrTestHelper(t, txMgr)
   542  
   543  	// simulate tx1
   544  	s1, _ := txMgr.NewTxSimulator("test_tx1")
   545  	for i := 1; i <= 10; i++ {
   546  		k := createTestKey(i)
   547  		v := createTestValue(i)
   548  		t.Logf("Adding k=[%s], v=[%s]", k, v)
   549  		s1.SetState(cID, k, v)
   550  	}
   551  	s1.Done()
   552  	// validate and commit RWset
   553  	txRWSet1, _ := s1.GetTxSimulationResults()
   554  	txMgrHelper.validateAndCommitRWSet(txRWSet1.PubSimulationResults)
   555  
   556  	// simulate tx2 that reads key_001 and key_002
   557  	s2, _ := txMgr.NewTxSimulator("test_tx2")
   558  	itr, _ := s2.GetStateRangeScanIterator(cID, createTestKey(1), createTestKey(5))
   559  	// read key_001 and key_002
   560  	itr.Next()
   561  	itr.Next()
   562  	itr.Close()
   563  	s2.Done()
   564  
   565  	// simulate tx3 that reads key_004 and key_005
   566  	s3, _ := txMgr.NewTxSimulator("test_tx3")
   567  	itr, _ = s3.GetStateRangeScanIterator(cID, createTestKey(4), createTestKey(6))
   568  	// read key_001 and key_002
   569  	itr.Next()
   570  	itr.Next()
   571  	itr.Close()
   572  	s3.Done()
   573  
   574  	// simulate tx4 before committing tx2 and tx3. Modifies a key read by tx3
   575  	s4, _ := txMgr.NewTxSimulator("test_tx4")
   576  	s4.DeleteState(cID, createTestKey(5))
   577  	s4.Done()
   578  
   579  	// validate and commit RWset for tx4
   580  	txRWSet4, _ := s4.GetTxSimulationResults()
   581  	txMgrHelper.validateAndCommitRWSet(txRWSet4.PubSimulationResults)
   582  
   583  	//RWSet tx3 should be invalid now
   584  	txRWSet3, _ := s3.GetTxSimulationResults()
   585  	txMgrHelper.checkRWsetInvalid(txRWSet3.PubSimulationResults)
   586  
   587  	// tx2 should still be valid
   588  	txRWSet2, _ := s2.GetTxSimulationResults()
   589  	txMgrHelper.validateAndCommitRWSet(txRWSet2.PubSimulationResults)
   590  
   591  }
   592  
   593  func TestGetSetMultipeKeys(t *testing.T) {
   594  	for _, testEnv := range testEnvs {
   595  		t.Logf("Running test for TestEnv = %s", testEnv.getName())
   596  		testLedgerID := "testgetsetmultipekeys"
   597  		testEnv.init(t, testLedgerID, nil)
   598  		testGetSetMultipeKeys(t, testEnv)
   599  		testEnv.cleanup()
   600  	}
   601  }
   602  
   603  func testGetSetMultipeKeys(t *testing.T, env testEnv) {
   604  	cID := "cid"
   605  	txMgr := env.getTxMgr()
   606  	txMgrHelper := newTxMgrTestHelper(t, txMgr)
   607  	// simulate tx1
   608  	s1, _ := txMgr.NewTxSimulator("test_tx1")
   609  	multipleKeyMap := make(map[string][]byte)
   610  	for i := 1; i <= 10; i++ {
   611  		k := createTestKey(i)
   612  		v := createTestValue(i)
   613  		multipleKeyMap[k] = v
   614  	}
   615  	s1.SetStateMultipleKeys(cID, multipleKeyMap)
   616  	s1.Done()
   617  	// validate and commit RWset
   618  	txRWSet, _ := s1.GetTxSimulationResults()
   619  	txMgrHelper.validateAndCommitRWSet(txRWSet.PubSimulationResults)
   620  	qe, _ := txMgr.NewQueryExecutor("test_tx2")
   621  	defer qe.Done()
   622  	multipleKeys := []string{}
   623  	for k := range multipleKeyMap {
   624  		multipleKeys = append(multipleKeys, k)
   625  	}
   626  	values, _ := qe.GetStateMultipleKeys(cID, multipleKeys)
   627  	assert.Len(t, values, 10)
   628  	for i, v := range values {
   629  		assert.Equal(t, multipleKeyMap[multipleKeys[i]], v)
   630  	}
   631  
   632  	s2, _ := txMgr.NewTxSimulator("test_tx3")
   633  	defer s2.Done()
   634  	values, _ = s2.GetStateMultipleKeys(cID, multipleKeys[5:7])
   635  	assert.Len(t, values, 2)
   636  	for i, v := range values {
   637  		assert.Equal(t, multipleKeyMap[multipleKeys[i+5]], v)
   638  	}
   639  }
   640  
   641  func createTestKey(i int) string {
   642  	if i == 0 {
   643  		return ""
   644  	}
   645  	return fmt.Sprintf("key_%03d", i)
   646  }
   647  
   648  func createTestValue(i int) []byte {
   649  	return []byte(fmt.Sprintf("value_%03d", i))
   650  }
   651  
   652  //TestExecuteQueryQuery is only tested on the CouchDB testEnv
   653  func TestExecuteQuery(t *testing.T) {
   654  	for _, testEnv := range testEnvs {
   655  		// Query is only supported and tested on the CouchDB testEnv
   656  		if testEnv.getName() == couchDBtestEnvName {
   657  			t.Logf("Running test for TestEnv = %s", testEnv.getName())
   658  			testLedgerID := "testexecutequery"
   659  			testEnv.init(t, testLedgerID, nil)
   660  			testExecuteQuery(t, testEnv)
   661  			testEnv.cleanup()
   662  		}
   663  	}
   664  }
   665  
   666  func testExecuteQuery(t *testing.T, env testEnv) {
   667  
   668  	type Asset struct {
   669  		ID        string `json:"_id"`
   670  		Rev       string `json:"_rev"`
   671  		AssetName string `json:"asset_name"`
   672  		Color     string `json:"color"`
   673  		Size      string `json:"size"`
   674  		Owner     string `json:"owner"`
   675  	}
   676  
   677  	txMgr := env.getTxMgr()
   678  	txMgrHelper := newTxMgrTestHelper(t, txMgr)
   679  
   680  	s1, _ := txMgr.NewTxSimulator("test_tx1")
   681  
   682  	s1.SetState("ns1", "key1", []byte("value1"))
   683  	s1.SetState("ns1", "key2", []byte("value2"))
   684  	s1.SetState("ns1", "key3", []byte("value3"))
   685  	s1.SetState("ns1", "key4", []byte("value4"))
   686  	s1.SetState("ns1", "key5", []byte("value5"))
   687  	s1.SetState("ns1", "key6", []byte("value6"))
   688  	s1.SetState("ns1", "key7", []byte("value7"))
   689  	s1.SetState("ns1", "key8", []byte("value8"))
   690  
   691  	s1.SetState("ns1", "key9", []byte(`{"asset_name":"marble1","color":"red","size":"25","owner":"jerry"}`))
   692  	s1.SetState("ns1", "key10", []byte(`{"asset_name":"marble2","color":"blue","size":"10","owner":"bob"}`))
   693  	s1.SetState("ns1", "key11", []byte(`{"asset_name":"marble3","color":"blue","size":"35","owner":"jerry"}`))
   694  	s1.SetState("ns1", "key12", []byte(`{"asset_name":"marble4","color":"green","size":"15","owner":"bob"}`))
   695  	s1.SetState("ns1", "key13", []byte(`{"asset_name":"marble5","color":"red","size":"35","owner":"jerry"}`))
   696  	s1.SetState("ns1", "key14", []byte(`{"asset_name":"marble6","color":"blue","size":"25","owner":"bob"}`))
   697  
   698  	s1.Done()
   699  
   700  	// validate and commit RWset
   701  	txRWSet, _ := s1.GetTxSimulationResults()
   702  	txMgrHelper.validateAndCommitRWSet(txRWSet.PubSimulationResults)
   703  
   704  	queryExecuter, _ := txMgr.NewQueryExecutor("test_tx2")
   705  	queryString := "{\"selector\":{\"owner\": {\"$eq\": \"bob\"}},\"limit\": 10,\"skip\": 0}"
   706  
   707  	itr, err := queryExecuter.ExecuteQuery("ns1", queryString)
   708  	assert.NoError(t, err, "Error upon ExecuteQuery()")
   709  	counter := 0
   710  	for {
   711  		queryRecord, _ := itr.Next()
   712  		if queryRecord == nil {
   713  			break
   714  		}
   715  		//Unmarshal the document to Asset structure
   716  		assetResp := &Asset{}
   717  		json.Unmarshal(queryRecord.(*queryresult.KV).Value, &assetResp)
   718  		//Verify the owner retrieved matches
   719  		assert.Equal(t, "bob", assetResp.Owner)
   720  		counter++
   721  	}
   722  	//Ensure the query returns 3 documents
   723  	assert.Equal(t, 3, counter)
   724  }
   725  
   726  // TestExecutePaginatedQuery is only tested on the CouchDB testEnv
   727  func TestExecutePaginatedQuery(t *testing.T) {
   728  	for _, testEnv := range testEnvs {
   729  		// Query is only supported and tested on the CouchDB testEnv
   730  		if testEnv.getName() == couchDBtestEnvName {
   731  			t.Logf("Running test for TestEnv = %s", testEnv.getName())
   732  			testLedgerID := "testexecutepaginatedquery"
   733  			testEnv.init(t, testLedgerID, nil)
   734  			testExecutePaginatedQuery(t, testEnv)
   735  			testEnv.cleanup()
   736  		}
   737  	}
   738  }
   739  
   740  func testExecutePaginatedQuery(t *testing.T, env testEnv) {
   741  
   742  	type Asset struct {
   743  		ID        string `json:"_id"`
   744  		Rev       string `json:"_rev"`
   745  		AssetName string `json:"asset_name"`
   746  		Color     string `json:"color"`
   747  		Size      string `json:"size"`
   748  		Owner     string `json:"owner"`
   749  	}
   750  
   751  	txMgr := env.getTxMgr()
   752  	txMgrHelper := newTxMgrTestHelper(t, txMgr)
   753  
   754  	s1, _ := txMgr.NewTxSimulator("test_tx1")
   755  
   756  	s1.SetState("ns1", "key1", []byte(`{"asset_name":"marble1","color":"red","size":"25","owner":"jerry"}`))
   757  	s1.SetState("ns1", "key2", []byte(`{"asset_name":"marble2","color":"blue","size":"10","owner":"bob"}`))
   758  	s1.SetState("ns1", "key3", []byte(`{"asset_name":"marble3","color":"blue","size":"35","owner":"jerry"}`))
   759  	s1.SetState("ns1", "key4", []byte(`{"asset_name":"marble4","color":"green","size":"15","owner":"bob"}`))
   760  	s1.SetState("ns1", "key5", []byte(`{"asset_name":"marble5","color":"red","size":"35","owner":"jerry"}`))
   761  	s1.SetState("ns1", "key6", []byte(`{"asset_name":"marble6","color":"blue","size":"25","owner":"bob"}`))
   762  
   763  	s1.Done()
   764  
   765  	// validate and commit RWset
   766  	txRWSet, _ := s1.GetTxSimulationResults()
   767  	txMgrHelper.validateAndCommitRWSet(txRWSet.PubSimulationResults)
   768  
   769  	queryExecuter, _ := txMgr.NewQueryExecutor("test_tx2")
   770  	queryString := `{"selector":{"owner":{"$eq":"bob"}}}`
   771  
   772  	queryOptions := map[string]interface{}{
   773  		"limit": int32(2),
   774  	}
   775  
   776  	itr, err := queryExecuter.ExecuteQueryWithMetadata("ns1", queryString, queryOptions)
   777  	assert.NoError(t, err, "Error upon ExecuteQueryWithMetadata()")
   778  	counter := 0
   779  	for {
   780  		queryRecord, _ := itr.Next()
   781  		if queryRecord == nil {
   782  			break
   783  		}
   784  		//Unmarshal the document to Asset structure
   785  		assetResp := &Asset{}
   786  		json.Unmarshal(queryRecord.(*queryresult.KV).Value, &assetResp)
   787  		//Verify the owner retrieved matches
   788  		assert.Equal(t, "bob", assetResp.Owner)
   789  		counter++
   790  	}
   791  	//Ensure the query returns 2 documents
   792  	assert.Equal(t, 2, counter)
   793  
   794  	bookmark := itr.GetBookmarkAndClose()
   795  
   796  	queryOptions = map[string]interface{}{
   797  		"limit": int32(2),
   798  	}
   799  	if bookmark != "" {
   800  		queryOptions["bookmark"] = bookmark
   801  	}
   802  
   803  	itr, err = queryExecuter.ExecuteQueryWithMetadata("ns1", queryString, queryOptions)
   804  	assert.NoError(t, err, "Error upon ExecuteQuery()")
   805  	counter = 0
   806  	for {
   807  		queryRecord, _ := itr.Next()
   808  		if queryRecord == nil {
   809  			break
   810  		}
   811  		//Unmarshal the document to Asset structure
   812  		assetResp := &Asset{}
   813  		json.Unmarshal(queryRecord.(*queryresult.KV).Value, &assetResp)
   814  		//Verify the owner retrieved matches
   815  		assert.Equal(t, "bob", assetResp.Owner)
   816  		counter++
   817  	}
   818  	//Ensure the query returns 1 documents
   819  	assert.Equal(t, 1, counter)
   820  }
   821  
   822  func TestValidateKey(t *testing.T) {
   823  	nonUTF8Key := string([]byte{0xff, 0xff})
   824  	dummyValue := []byte("dummyValue")
   825  	for _, testEnv := range testEnvs {
   826  		testLedgerID := "test.validate.key"
   827  		testEnv.init(t, testLedgerID, nil)
   828  		txSimulator, _ := testEnv.getTxMgr().NewTxSimulator("test_tx1")
   829  		err := txSimulator.SetState("ns1", nonUTF8Key, dummyValue)
   830  		if testEnv.getName() == levelDBtestEnvName {
   831  			assert.NoError(t, err)
   832  		}
   833  		if testEnv.getName() == couchDBtestEnvName {
   834  			assert.Error(t, err)
   835  		}
   836  		testEnv.cleanup()
   837  	}
   838  }
   839  
   840  // TestTxSimulatorUnsupportedTx verifies that a simulation must throw an error when an unsupported transaction
   841  // is perfromed - queries on private data are supported in a read-only tran
   842  func TestTxSimulatorUnsupportedTx(t *testing.T) {
   843  	testEnv := testEnvsMap[levelDBtestEnvName]
   844  	testEnv.init(t, "testtxsimulatorunsupportedtx", nil)
   845  	defer testEnv.cleanup()
   846  	txMgr := testEnv.getTxMgr()
   847  	populateCollConfigForTest(t, txMgr.(*LockBasedTxMgr),
   848  		[]collConfigkey{
   849  			{"ns1", "coll1"},
   850  			{"ns1", "coll2"},
   851  			{"ns1", "coll3"},
   852  			{"ns1", "coll4"},
   853  		},
   854  		version.NewHeight(1, 1))
   855  
   856  	simulator, _ := txMgr.NewTxSimulator("txid1")
   857  	err := simulator.SetState("ns", "key", []byte("value"))
   858  	assert.NoError(t, err)
   859  	_, err = simulator.GetPrivateDataRangeScanIterator("ns1", "coll1", "startKey", "endKey")
   860  	_, ok := err.(*txmgr.ErrUnsupportedTransaction)
   861  	assert.True(t, ok)
   862  
   863  	simulator, _ = txMgr.NewTxSimulator("txid2")
   864  	_, err = simulator.GetPrivateDataRangeScanIterator("ns1", "coll1", "startKey", "endKey")
   865  	assert.NoError(t, err)
   866  	err = simulator.SetState("ns", "key", []byte("value"))
   867  	_, ok = err.(*txmgr.ErrUnsupportedTransaction)
   868  	assert.True(t, ok)
   869  
   870  	queryOptions := map[string]interface{}{
   871  		"limit": int32(2),
   872  	}
   873  
   874  	simulator, _ = txMgr.NewTxSimulator("txid3")
   875  	err = simulator.SetState("ns", "key", []byte("value"))
   876  	assert.NoError(t, err)
   877  	_, err = simulator.GetStateRangeScanIteratorWithMetadata("ns1", "startKey", "endKey", queryOptions)
   878  	_, ok = err.(*txmgr.ErrUnsupportedTransaction)
   879  	assert.True(t, ok)
   880  
   881  	simulator, _ = txMgr.NewTxSimulator("txid4")
   882  	_, err = simulator.GetStateRangeScanIteratorWithMetadata("ns1", "startKey", "endKey", queryOptions)
   883  	assert.NoError(t, err)
   884  	err = simulator.SetState("ns", "key", []byte("value"))
   885  	_, ok = err.(*txmgr.ErrUnsupportedTransaction)
   886  	assert.True(t, ok)
   887  
   888  }
   889  
   890  // TestTxSimulatorQueryUnsupportedTx is only tested on the CouchDB testEnv
   891  func TestTxSimulatorQueryUnsupportedTx(t *testing.T) {
   892  	for _, testEnv := range testEnvs {
   893  		// Query is only supported and tested on the CouchDB testEnv
   894  		if testEnv.getName() == couchDBtestEnvName {
   895  			t.Logf("Running test for TestEnv = %s", testEnv.getName())
   896  			testLedgerID := "testtxsimulatorunsupportedtxqueries"
   897  			testEnv.init(t, testLedgerID, nil)
   898  			testTxSimulatorQueryUnsupportedTx(t, testEnv)
   899  			testEnv.cleanup()
   900  		}
   901  	}
   902  }
   903  
   904  func testTxSimulatorQueryUnsupportedTx(t *testing.T, env testEnv) {
   905  	txMgr := env.getTxMgr()
   906  	txMgrHelper := newTxMgrTestHelper(t, txMgr)
   907  
   908  	s1, _ := txMgr.NewTxSimulator("test_tx1")
   909  
   910  	s1.SetState("ns1", "key1", []byte(`{"asset_name":"marble1","color":"red","size":"25","owner":"jerry"}`))
   911  
   912  	s1.Done()
   913  
   914  	// validate and commit RWset
   915  	txRWSet, _ := s1.GetTxSimulationResults()
   916  	txMgrHelper.validateAndCommitRWSet(txRWSet.PubSimulationResults)
   917  
   918  	queryString := `{"selector":{"owner":{"$eq":"bob"}}}`
   919  	queryOptions := map[string]interface{}{
   920  		"limit": int32(2),
   921  	}
   922  
   923  	simulator, _ := txMgr.NewTxSimulator("txid1")
   924  	err := simulator.SetState("ns1", "key1", []byte(`{"asset_name":"marble1","color":"red","size":"25","owner":"jerry"}`))
   925  	assert.NoError(t, err)
   926  	_, err = simulator.ExecuteQueryWithMetadata("ns1", queryString, queryOptions)
   927  	_, ok := err.(*txmgr.ErrUnsupportedTransaction)
   928  	assert.True(t, ok)
   929  
   930  	simulator, _ = txMgr.NewTxSimulator("txid2")
   931  	_, err = simulator.ExecuteQueryWithMetadata("ns1", queryString, queryOptions)
   932  	assert.NoError(t, err)
   933  	err = simulator.SetState("ns1", "key1", []byte(`{"asset_name":"marble1","color":"red","size":"25","owner":"jerry"}`))
   934  	_, ok = err.(*txmgr.ErrUnsupportedTransaction)
   935  	assert.True(t, ok)
   936  
   937  }
   938  
   939  func TestConstructUniquePvtData(t *testing.T) {
   940  	v1 := []byte{1}
   941  	// ns1-coll1-key1 should be rejected as it is updated in the future by Blk2Tx1
   942  	pvtDataBlk1Tx1 := producePvtdata(t, 1, []string{"ns1:coll1"}, []string{"key1"}, [][]byte{v1})
   943  	// ns1-coll2-key3 should be accepted but ns1-coll1-key2 as it is updated in the future by Blk2Tx2
   944  	pvtDataBlk1Tx2 := producePvtdata(t, 2, []string{"ns1:coll1", "ns1:coll2"}, []string{"key2", "key3"}, [][]byte{v1, v1})
   945  	// ns1-coll2-key4 should be accepted
   946  	pvtDataBlk1Tx3 := producePvtdata(t, 3, []string{"ns1:coll2"}, []string{"key4"}, [][]byte{v1})
   947  
   948  	v2 := []byte{2}
   949  	// ns1-coll1-key1 should be rejected as it is updated in the future by Blk3Tx1
   950  	pvtDataBlk2Tx1 := producePvtdata(t, 1, []string{"ns1:coll1"}, []string{"key1"}, [][]byte{v2})
   951  	// ns1-coll1-key2 should be accepted
   952  	pvtDataBlk2Tx2 := producePvtdata(t, 2, []string{"ns1:coll1"}, []string{"key2"}, [][]byte{nil})
   953  
   954  	v3 := []byte{3}
   955  	// ns1-coll1-key1 should be accepted
   956  	pvtDataBlk3Tx1 := producePvtdata(t, 1, []string{"ns1:coll1"}, []string{"key1"}, [][]byte{v3})
   957  
   958  	blocksPvtData := map[uint64][]*ledger.TxPvtData{
   959  		1: {
   960  			pvtDataBlk1Tx1,
   961  			pvtDataBlk1Tx2,
   962  			pvtDataBlk1Tx3,
   963  		},
   964  		2: {
   965  			pvtDataBlk2Tx1,
   966  			pvtDataBlk2Tx2,
   967  		},
   968  		3: {
   969  			pvtDataBlk3Tx1,
   970  		},
   971  	}
   972  
   973  	hashedCompositeKeyNs1Coll2Key3 := privacyenabledstate.HashedCompositeKey{Namespace: "ns1", CollectionName: "coll2", KeyHash: string(util.ComputeStringHash("key3"))}
   974  	pvtKVWriteNs1Coll2Key3 := &privacyenabledstate.PvtKVWrite{Key: "key3", IsDelete: false, Value: v1, Version: version.NewHeight(1, 2)}
   975  
   976  	hashedCompositeKeyNs1Coll2Key4 := privacyenabledstate.HashedCompositeKey{Namespace: "ns1", CollectionName: "coll2", KeyHash: string(util.ComputeStringHash("key4"))}
   977  	pvtKVWriteNs1Coll2Key4 := &privacyenabledstate.PvtKVWrite{Key: "key4", IsDelete: false, Value: v1, Version: version.NewHeight(1, 3)}
   978  
   979  	hashedCompositeKeyNs1Coll1Key2 := privacyenabledstate.HashedCompositeKey{Namespace: "ns1", CollectionName: "coll1", KeyHash: string(util.ComputeStringHash("key2"))}
   980  	pvtKVWriteNs1Coll1Key2 := &privacyenabledstate.PvtKVWrite{Key: "key2", IsDelete: true, Value: nil, Version: version.NewHeight(2, 2)}
   981  
   982  	hashedCompositeKeyNs1Coll1Key1 := privacyenabledstate.HashedCompositeKey{Namespace: "ns1", CollectionName: "coll1", KeyHash: string(util.ComputeStringHash("key1"))}
   983  	pvtKVWriteNs1Coll1Key1 := &privacyenabledstate.PvtKVWrite{Key: "key1", IsDelete: false, Value: v3, Version: version.NewHeight(3, 1)}
   984  
   985  	expectedUniquePvtData := uniquePvtDataMap{
   986  		hashedCompositeKeyNs1Coll2Key3: pvtKVWriteNs1Coll2Key3,
   987  		hashedCompositeKeyNs1Coll2Key4: pvtKVWriteNs1Coll2Key4,
   988  		hashedCompositeKeyNs1Coll1Key2: pvtKVWriteNs1Coll1Key2,
   989  		hashedCompositeKeyNs1Coll1Key1: pvtKVWriteNs1Coll1Key1,
   990  	}
   991  
   992  	uniquePvtData, err := constructUniquePvtData(blocksPvtData)
   993  	assert.NoError(t, err)
   994  	assert.Equal(t, expectedUniquePvtData, uniquePvtData)
   995  }
   996  
   997  func TestFindAndRemoveStalePvtData(t *testing.T) {
   998  	ledgerid := "TestFindAndRemoveStalePvtData"
   999  	testEnv := testEnvsMap[levelDBtestEnvName]
  1000  	testEnv.init(t, ledgerid, nil)
  1001  	defer testEnv.cleanup()
  1002  	db := testEnv.getVDB()
  1003  
  1004  	batch := privacyenabledstate.NewUpdateBatch()
  1005  	batch.HashUpdates.Put("ns1", "coll1", util.ComputeStringHash("key1"), util.ComputeStringHash("value_1_1_1"), version.NewHeight(1, 1))
  1006  	batch.HashUpdates.Put("ns1", "coll2", util.ComputeStringHash("key2"), util.ComputeStringHash("value_1_2_2"), version.NewHeight(1, 2))
  1007  	batch.HashUpdates.Put("ns2", "coll1", util.ComputeStringHash("key2"), util.ComputeStringHash("value_2_1_2"), version.NewHeight(2, 1))
  1008  	batch.HashUpdates.Put("ns2", "coll2", util.ComputeStringHash("key3"), util.ComputeStringHash("value_2_2_3"), version.NewHeight(10, 10))
  1009  
  1010  	// all pvt data associated with the hash updates are missing
  1011  	db.ApplyPrivacyAwareUpdates(batch, version.NewHeight(11, 1))
  1012  
  1013  	// construct pvt data for some of the above missing data. note that no
  1014  	// duplicate entries are expected
  1015  
  1016  	// existent keyhash - a kvwrite with lower version (than the version of existent keyhash) should be considered stale
  1017  	hashedCompositeKeyNs1Coll1Key1 := privacyenabledstate.HashedCompositeKey{Namespace: "ns1", CollectionName: "coll1", KeyHash: string(util.ComputeStringHash("key1"))}
  1018  	pvtKVWriteNs1Coll1Key1 := &privacyenabledstate.PvtKVWrite{Key: "key1", IsDelete: false, Value: []byte("old_value_1_1_1"), Version: version.NewHeight(1, 0)}
  1019  
  1020  	// existent keyhash - a kvwrite with higher version (than the version of existent keyhash) should not be considered stale
  1021  	hashedCompositeKeyNs2Coll1Key2 := privacyenabledstate.HashedCompositeKey{Namespace: "ns2", CollectionName: "coll1", KeyHash: string(util.ComputeStringHash("key2"))}
  1022  	pvtKVWriteNs2Coll1Key2 := &privacyenabledstate.PvtKVWrite{Key: "key2", IsDelete: false, Value: []byte("value_2_1_2"), Version: version.NewHeight(2, 1)}
  1023  
  1024  	// non existent keyhash (because deleted earlier or expired) - a kvwrite for delete should not be considered stale
  1025  	hashedCompositeKeyNs1Coll3Key3 := privacyenabledstate.HashedCompositeKey{Namespace: "ns1", CollectionName: "coll3", KeyHash: string(util.ComputeStringHash("key3"))}
  1026  	pvtKVWriteNs1Coll3Key3 := &privacyenabledstate.PvtKVWrite{Key: "key3", IsDelete: true, Value: nil, Version: version.NewHeight(2, 3)}
  1027  
  1028  	// non existent keyhash (because deleted earlier or expired) - a kvwrite for value set should be considered stale
  1029  	hashedCompositeKeyNs1Coll4Key4 := privacyenabledstate.HashedCompositeKey{Namespace: "ns1", CollectionName: "coll4", KeyHash: string(util.ComputeStringHash("key4"))}
  1030  	pvtKVWriteNs1Coll4Key4 := &privacyenabledstate.PvtKVWrite{Key: "key4", Value: []byte("value_1_4_4"), Version: version.NewHeight(2, 3)}
  1031  
  1032  	// there would be a version mismatch but the hash value must be the same. hence,
  1033  	// this should be accepted too
  1034  	hashedCompositeKeyNs2Coll2Key3 := privacyenabledstate.HashedCompositeKey{Namespace: "ns2", CollectionName: "coll2", KeyHash: string(util.ComputeStringHash("key3"))}
  1035  	pvtKVWriteNs2Coll2Key3 := &privacyenabledstate.PvtKVWrite{Key: "key3", IsDelete: false, Value: []byte("value_2_2_3"), Version: version.NewHeight(9, 9)}
  1036  
  1037  	uniquePvtData := uniquePvtDataMap{
  1038  		hashedCompositeKeyNs1Coll1Key1: pvtKVWriteNs1Coll1Key1,
  1039  		hashedCompositeKeyNs2Coll1Key2: pvtKVWriteNs2Coll1Key2,
  1040  		hashedCompositeKeyNs1Coll3Key3: pvtKVWriteNs1Coll3Key3,
  1041  		hashedCompositeKeyNs2Coll2Key3: pvtKVWriteNs2Coll2Key3,
  1042  		hashedCompositeKeyNs1Coll4Key4: pvtKVWriteNs1Coll4Key4,
  1043  	}
  1044  
  1045  	// created the expected batch from ValidateAndPrepareBatchForPvtDataofOldBlocks
  1046  	expectedBatch := privacyenabledstate.NewUpdateBatch()
  1047  	expectedBatch.PvtUpdates.Put("ns2", "coll1", "key2", []byte("value_2_1_2"), version.NewHeight(2, 1))
  1048  	expectedBatch.PvtUpdates.Delete("ns1", "coll3", "key3", version.NewHeight(2, 3))
  1049  	expectedBatch.PvtUpdates.Put("ns2", "coll2", "key3", []byte("value_2_2_3"), version.NewHeight(10, 10))
  1050  
  1051  	err := uniquePvtData.findAndRemoveStalePvtData(db)
  1052  	assert.NoError(t, err, "uniquePvtData.findAndRemoveStatePvtData resulted in an error")
  1053  	batch = uniquePvtData.transformToUpdateBatch()
  1054  	assert.Equal(t, expectedBatch.PvtUpdates, batch.PvtUpdates)
  1055  }
  1056  
  1057  func producePvtdata(t *testing.T, txNum uint64, nsColls []string, keys []string, values [][]byte) *ledger.TxPvtData {
  1058  	builder := rwsetutil.NewRWSetBuilder()
  1059  	for index, nsColl := range nsColls {
  1060  		nsCollSplit := strings.Split(nsColl, ":")
  1061  		ns := nsCollSplit[0]
  1062  		coll := nsCollSplit[1]
  1063  		key := keys[index]
  1064  		value := values[index]
  1065  		builder.AddToPvtAndHashedWriteSet(ns, coll, key, value)
  1066  	}
  1067  	simRes, err := builder.GetTxSimulationResults()
  1068  	assert.NoError(t, err)
  1069  	return &ledger.TxPvtData{
  1070  		SeqInBlock: txNum,
  1071  		WriteSet:   simRes.PvtSimulationResults,
  1072  	}
  1073  }
  1074  
  1075  func TestRemoveStaleAndCommitPvtDataOfOldBlocks(t *testing.T) {
  1076  	for _, testEnv := range testEnvs {
  1077  		t.Logf("Running test for TestEnv = %s", testEnv.getName())
  1078  		testValidationAndCommitOfOldPvtData(t, testEnv)
  1079  	}
  1080  }
  1081  
  1082  func testValidationAndCommitOfOldPvtData(t *testing.T, env testEnv) {
  1083  	ledgerid := "testvalidationandcommitofoldpvtdata"
  1084  	btlPolicy := btltestutil.SampleBTLPolicy(
  1085  		map[[2]string]uint64{
  1086  			{"ns1", "coll1"}: 0,
  1087  			{"ns1", "coll2"}: 0,
  1088  		},
  1089  	)
  1090  	env.init(t, ledgerid, btlPolicy)
  1091  	defer env.cleanup()
  1092  	txMgr := env.getTxMgr()
  1093  	populateCollConfigForTest(t, txMgr.(*LockBasedTxMgr),
  1094  		[]collConfigkey{
  1095  			{"ns1", "coll1"},
  1096  			{"ns1", "coll2"},
  1097  		},
  1098  		version.NewHeight(1, 1),
  1099  	)
  1100  
  1101  	db := env.getVDB()
  1102  	updateBatch := privacyenabledstate.NewUpdateBatch()
  1103  	// all pvt data are missing
  1104  	updateBatch.HashUpdates.Put("ns1", "coll1", util.ComputeStringHash("key1"), util.ComputeStringHash("value1"), version.NewHeight(1, 1)) // E1
  1105  	updateBatch.HashUpdates.Put("ns1", "coll1", util.ComputeStringHash("key2"), util.ComputeStringHash("value2"), version.NewHeight(1, 2)) // E2
  1106  	updateBatch.HashUpdates.Put("ns1", "coll2", util.ComputeStringHash("key3"), util.ComputeStringHash("value3"), version.NewHeight(1, 2)) // E3
  1107  	updateBatch.HashUpdates.Put("ns1", "coll2", util.ComputeStringHash("key4"), util.ComputeStringHash("value4"), version.NewHeight(1, 3)) // E4
  1108  	db.ApplyPrivacyAwareUpdates(updateBatch, version.NewHeight(1, 2))
  1109  
  1110  	updateBatch = privacyenabledstate.NewUpdateBatch()
  1111  	updateBatch.HashUpdates.Put("ns1", "coll1", util.ComputeStringHash("key1"), util.ComputeStringHash("new-value1"), version.NewHeight(2, 1)) // E1 is updated
  1112  	updateBatch.HashUpdates.Delete("ns1", "coll1", util.ComputeStringHash("key2"), version.NewHeight(2, 2))                                    // E2 is being deleted
  1113  	db.ApplyPrivacyAwareUpdates(updateBatch, version.NewHeight(2, 2))
  1114  
  1115  	updateBatch = privacyenabledstate.NewUpdateBatch()
  1116  	updateBatch.HashUpdates.Put("ns1", "coll1", util.ComputeStringHash("key1"), util.ComputeStringHash("another-new-value1"), version.NewHeight(3, 1)) // E1 is again updated
  1117  	updateBatch.HashUpdates.Put("ns1", "coll2", util.ComputeStringHash("key3"), util.ComputeStringHash("value3"), version.NewHeight(3, 2))             // E3 gets only metadata update
  1118  	db.ApplyPrivacyAwareUpdates(updateBatch, version.NewHeight(3, 2))
  1119  
  1120  	v1 := []byte("value1")
  1121  	// ns1-coll1-key1 should be rejected as it is updated in the future by Blk2Tx1
  1122  	pvtDataBlk1Tx1 := producePvtdata(t, 1, []string{"ns1:coll1"}, []string{"key1"}, [][]byte{v1})
  1123  	// ns1-coll2-key3 should be accepted but ns1-coll1-key2
  1124  	// should be rejected as it is updated in the future by Blk2Tx2
  1125  	v2 := []byte("value2")
  1126  	v3 := []byte("value3")
  1127  	pvtDataBlk1Tx2 := producePvtdata(t, 2, []string{"ns1:coll1", "ns1:coll2"}, []string{"key2", "key3"}, [][]byte{v2, v3})
  1128  	// ns1-coll2-key4 should be accepted
  1129  	v4 := []byte("value4")
  1130  	pvtDataBlk1Tx3 := producePvtdata(t, 3, []string{"ns1:coll2"}, []string{"key4"}, [][]byte{v4})
  1131  
  1132  	nv1 := []byte("new-value1")
  1133  	// ns1-coll1-key1 should be rejected as it is updated in the future by Blk3Tx1
  1134  	pvtDataBlk2Tx1 := producePvtdata(t, 1, []string{"ns1:coll1"}, []string{"key1"}, [][]byte{nv1})
  1135  	// ns1-coll1-key2 should be accepted -- a delete operation
  1136  	pvtDataBlk2Tx2 := producePvtdata(t, 2, []string{"ns1:coll1"}, []string{"key2"}, [][]byte{nil})
  1137  
  1138  	anv1 := []byte("another-new-value1")
  1139  	// ns1-coll1-key1 should be accepted
  1140  	pvtDataBlk3Tx1 := producePvtdata(t, 1, []string{"ns1:coll1"}, []string{"key1"}, [][]byte{anv1})
  1141  	// ns1-coll2-key3 should be accepted -- assume that only metadata is being updated
  1142  	pvtDataBlk3Tx2 := producePvtdata(t, 2, []string{"ns1:coll2"}, []string{"key3"}, [][]byte{v3})
  1143  
  1144  	blocksPvtData := map[uint64][]*ledger.TxPvtData{
  1145  		1: {
  1146  			pvtDataBlk1Tx1,
  1147  			pvtDataBlk1Tx2,
  1148  			pvtDataBlk1Tx3,
  1149  		},
  1150  		2: {
  1151  			pvtDataBlk2Tx1,
  1152  			pvtDataBlk2Tx2,
  1153  		},
  1154  		3: {
  1155  			pvtDataBlk3Tx1,
  1156  			pvtDataBlk3Tx2,
  1157  		},
  1158  	}
  1159  
  1160  	err := txMgr.RemoveStaleAndCommitPvtDataOfOldBlocks(blocksPvtData)
  1161  	assert.NoError(t, err)
  1162  
  1163  	vv, err := db.GetPrivateData("ns1", "coll1", "key1")
  1164  	assert.NoError(t, err)
  1165  	assert.Equal(t, anv1, vv.Value) // last updated value
  1166  
  1167  	vv, err = db.GetPrivateData("ns1", "coll1", "key2")
  1168  	assert.NoError(t, err)
  1169  	assert.Equal(t, nil, nil) // deleted
  1170  
  1171  	vv, err = db.GetPrivateData("ns1", "coll2", "key3")
  1172  	assert.NoError(t, err)
  1173  	assert.Equal(t, v3, vv.Value)
  1174  	assert.Equal(t, version.NewHeight(3, 2), vv.Version) // though we passed with version {1,2}, we should get {3,2} due to metadata update
  1175  
  1176  	vv, err = db.GetPrivateData("ns1", "coll2", "key4")
  1177  	assert.NoError(t, err)
  1178  	assert.Equal(t, v4, vv.Value)
  1179  }
  1180  
  1181  func TestTxSimulatorMissingPvtdata(t *testing.T) {
  1182  	testEnv := testEnvsMap[levelDBtestEnvName]
  1183  	testEnv.init(t, "TestTxSimulatorUnsupportedTxQueries", nil)
  1184  	defer testEnv.cleanup()
  1185  
  1186  	txMgr := testEnv.getTxMgr()
  1187  	populateCollConfigForTest(t, txMgr.(*LockBasedTxMgr),
  1188  		[]collConfigkey{
  1189  			{"ns1", "coll1"},
  1190  			{"ns1", "coll2"},
  1191  			{"ns1", "coll3"},
  1192  			{"ns1", "coll4"},
  1193  		},
  1194  		version.NewHeight(1, 1),
  1195  	)
  1196  
  1197  	db := testEnv.getVDB()
  1198  	updateBatch := privacyenabledstate.NewUpdateBatch()
  1199  	updateBatch.HashUpdates.Put("ns1", "coll1", util.ComputeStringHash("key1"), util.ComputeStringHash("value1"), version.NewHeight(1, 1))
  1200  	updateBatch.PvtUpdates.Put("ns1", "coll1", "key1", []byte("value1"), version.NewHeight(1, 1))
  1201  	db.ApplyPrivacyAwareUpdates(updateBatch, version.NewHeight(1, 1))
  1202  
  1203  	assert.True(t, testPvtValueEqual(t, txMgr, "ns1", "coll1", "key1", []byte("value1")))
  1204  
  1205  	updateBatch = privacyenabledstate.NewUpdateBatch()
  1206  	updateBatch.HashUpdates.Put("ns1", "coll1", util.ComputeStringHash("key1"), util.ComputeStringHash("value1"), version.NewHeight(2, 1))
  1207  	updateBatch.HashUpdates.Put("ns1", "coll2", util.ComputeStringHash("key2"), util.ComputeStringHash("value2"), version.NewHeight(2, 1))
  1208  	updateBatch.HashUpdates.Put("ns1", "coll3", util.ComputeStringHash("key3"), util.ComputeStringHash("value3"), version.NewHeight(2, 1))
  1209  	updateBatch.PvtUpdates.Put("ns1", "coll3", "key3", []byte("value3"), version.NewHeight(2, 1))
  1210  	db.ApplyPrivacyAwareUpdates(updateBatch, version.NewHeight(2, 1))
  1211  
  1212  	assert.False(t, testPvtKeyExist(t, txMgr, "ns1", "coll1", "key1"))
  1213  
  1214  	assert.False(t, testPvtKeyExist(t, txMgr, "ns1", "coll2", "key2"))
  1215  
  1216  	assert.True(t, testPvtValueEqual(t, txMgr, "ns1", "coll3", "key3", []byte("value3")))
  1217  
  1218  	assert.True(t, testPvtValueEqual(t, txMgr, "ns1", "coll4", "key4", nil))
  1219  }
  1220  
  1221  func TestRemoveStaleAndCommitPvtDataOfOldBlocksWithExpiry(t *testing.T) {
  1222  	ledgerid := "TestTxSimulatorMissingPvtdataExpiry"
  1223  	btlPolicy := btltestutil.SampleBTLPolicy(
  1224  		map[[2]string]uint64{
  1225  			{"ns", "coll"}: 1,
  1226  		},
  1227  	)
  1228  	testEnv := testEnvsMap[levelDBtestEnvName]
  1229  	testEnv.init(t, ledgerid, btlPolicy)
  1230  	defer testEnv.cleanup()
  1231  
  1232  	txMgr := testEnv.getTxMgr()
  1233  	populateCollConfigForTest(t, txMgr.(*LockBasedTxMgr),
  1234  		[]collConfigkey{
  1235  			{"ns", "coll"},
  1236  		},
  1237  		version.NewHeight(1, 1),
  1238  	)
  1239  
  1240  	bg, _ := testutil.NewBlockGenerator(t, ledgerid, false)
  1241  
  1242  	// storing hashed data but the pvt key is missing
  1243  	// stored pvt key would get expired and purged while committing block 3
  1244  	blkAndPvtdata := prepareNextBlockForTest(t, txMgr, bg, "txid-1",
  1245  		map[string]string{"pubkey1": "pub-value1"}, map[string]string{"pvtkey1": "pvt-value1"}, true)
  1246  	_, _, err := txMgr.ValidateAndPrepare(blkAndPvtdata, true)
  1247  	assert.NoError(t, err)
  1248  	// committing block 1
  1249  	assert.NoError(t, txMgr.Commit())
  1250  
  1251  	// pvt data should not exist
  1252  	assert.False(t, testPvtKeyExist(t, txMgr, "ns", "coll", "pvtkey1"))
  1253  
  1254  	// committing pvt data of block 1
  1255  	v1 := []byte("pvt-value1")
  1256  	pvtDataBlk1Tx1 := producePvtdata(t, 1, []string{"ns:coll"}, []string{"pvtkey1"}, [][]byte{v1})
  1257  	blocksPvtData := map[uint64][]*ledger.TxPvtData{
  1258  		1: {
  1259  			pvtDataBlk1Tx1,
  1260  		},
  1261  	}
  1262  	err = txMgr.RemoveStaleAndCommitPvtDataOfOldBlocks(blocksPvtData)
  1263  	assert.NoError(t, err)
  1264  
  1265  	// pvt data should exist
  1266  	assert.True(t, testPvtValueEqual(t, txMgr, "ns", "coll", "pvtkey1", v1))
  1267  
  1268  	// storing hashed data but the pvt key is missing
  1269  	// stored pvt key would get expired and purged while committing block 4
  1270  	blkAndPvtdata = prepareNextBlockForTest(t, txMgr, bg, "txid-2",
  1271  		map[string]string{"pubkey2": "pub-value2"}, map[string]string{"pvtkey2": "pvt-value2"}, true)
  1272  	_, _, err = txMgr.ValidateAndPrepare(blkAndPvtdata, true)
  1273  	assert.NoError(t, err)
  1274  	// committing block 2
  1275  	assert.NoError(t, txMgr.Commit())
  1276  
  1277  	// pvt data should not exist
  1278  	assert.False(t, testPvtKeyExist(t, txMgr, "ns", "coll", "pvtkey2"))
  1279  
  1280  	blkAndPvtdata = prepareNextBlockForTest(t, txMgr, bg, "txid-3",
  1281  		map[string]string{"pubkey3": "pub-value3"}, nil, false)
  1282  	_, _, err = txMgr.ValidateAndPrepare(blkAndPvtdata, true)
  1283  	assert.NoError(t, err)
  1284  	// committing block 3
  1285  	assert.NoError(t, txMgr.Commit())
  1286  
  1287  	// prepareForExpiringKey must have selected the pvtkey2 as it would
  1288  	// get expired during next block commit
  1289  
  1290  	// committing pvt data of block 2
  1291  	v2 := []byte("pvt-value2")
  1292  	pvtDataBlk2Tx1 := producePvtdata(t, 1, []string{"ns:coll"}, []string{"pvtkey2"}, [][]byte{v2})
  1293  	blocksPvtData = map[uint64][]*ledger.TxPvtData{
  1294  		2: {
  1295  			pvtDataBlk2Tx1,
  1296  		},
  1297  	}
  1298  
  1299  	err = txMgr.RemoveStaleAndCommitPvtDataOfOldBlocks(blocksPvtData)
  1300  	assert.NoError(t, err)
  1301  
  1302  	// pvt data should exist
  1303  	assert.True(t, testPvtValueEqual(t, txMgr, "ns", "coll", "pvtkey2", v2))
  1304  
  1305  	blkAndPvtdata = prepareNextBlockForTest(t, txMgr, bg, "txid-4",
  1306  		map[string]string{"pubkey4": "pub-value4"}, nil, false)
  1307  	_, _, err = txMgr.ValidateAndPrepare(blkAndPvtdata, true)
  1308  	assert.NoError(t, err)
  1309  	// committing block 4 and should purge pvtkey2
  1310  	assert.NoError(t, txMgr.Commit())
  1311  
  1312  	assert.True(t, testPvtValueEqual(t, txMgr, "ns", "coll", "pvtkey2", nil))
  1313  }
  1314  
  1315  func testPvtKeyExist(t *testing.T, txMgr txmgr.TxMgr, ns, coll, key string) bool {
  1316  	simulator, _ := txMgr.NewTxSimulator("tx-tmp")
  1317  	defer simulator.Done()
  1318  	_, err := simulator.GetPrivateData(ns, coll, key)
  1319  	_, ok := err.(*txmgr.ErrPvtdataNotAvailable)
  1320  	return !ok
  1321  }
  1322  
  1323  func testPvtValueEqual(t *testing.T, txMgr txmgr.TxMgr, ns, coll, key string, value []byte) bool {
  1324  	simulator, _ := txMgr.NewTxSimulator("tx-tmp")
  1325  	defer simulator.Done()
  1326  	pvtValue, err := simulator.GetPrivateData(ns, coll, key)
  1327  	assert.NoError(t, err)
  1328  	if bytes.Equal(pvtValue, value) {
  1329  		return true
  1330  	}
  1331  	return false
  1332  }
  1333  
  1334  func TestDeleteOnCursor(t *testing.T) {
  1335  	cID := "cid"
  1336  	env := testEnvsMap[levelDBtestEnvName]
  1337  	env.init(t, "TestDeleteOnCursor", nil)
  1338  	defer env.cleanup()
  1339  
  1340  	txMgr := env.getTxMgr()
  1341  	txMgrHelper := newTxMgrTestHelper(t, txMgr)
  1342  
  1343  	// Simulate and commit tx1 to populate sample data (key_001 through key_010)
  1344  	s, _ := txMgr.NewTxSimulator("test_tx1")
  1345  	for i := 1; i <= 10; i++ {
  1346  		k := createTestKey(i)
  1347  		v := createTestValue(i)
  1348  		t.Logf("Adding k=[%s], v=[%s]", k, v)
  1349  		s.SetState(cID, k, v)
  1350  	}
  1351  	s.Done()
  1352  	txRWSet1, _ := s.GetTxSimulationResults()
  1353  	txMgrHelper.validateAndCommitRWSet(txRWSet1.PubSimulationResults)
  1354  
  1355  	// simulate and commit tx2 that reads keys key_001 through key_004 and deletes them one by one (in a loop - itr.Next() followed by Delete())
  1356  	s2, _ := txMgr.NewTxSimulator("test_tx2")
  1357  	itr2, _ := s2.GetStateRangeScanIterator(cID, createTestKey(1), createTestKey(5))
  1358  	for i := 1; i <= 4; i++ {
  1359  		kv, err := itr2.Next()
  1360  		assert.NoError(t, err)
  1361  		assert.NotNil(t, kv)
  1362  		key := kv.(*queryresult.KV).Key
  1363  		s2.DeleteState(cID, key)
  1364  	}
  1365  	itr2.Close()
  1366  	s2.Done()
  1367  	txRWSet2, _ := s2.GetTxSimulationResults()
  1368  	txMgrHelper.validateAndCommitRWSet(txRWSet2.PubSimulationResults)
  1369  
  1370  	// simulate tx3 to verify that the keys key_001 through key_004 got deleted
  1371  	s3, _ := txMgr.NewTxSimulator("test_tx3")
  1372  	itr3, _ := s3.GetStateRangeScanIterator(cID, createTestKey(1), createTestKey(10))
  1373  	kv, err := itr3.Next()
  1374  	assert.NoError(t, err)
  1375  	assert.NotNil(t, kv)
  1376  	key := kv.(*queryresult.KV).Key
  1377  	assert.Equal(t, "key_005", key)
  1378  	itr3.Close()
  1379  	s3.Done()
  1380  }
  1381  
  1382  func TestTxSimulatorMissingPvtdataExpiry(t *testing.T) {
  1383  	ledgerid := "TestTxSimulatorMissingPvtdataExpiry"
  1384  	testEnv := testEnvsMap[levelDBtestEnvName]
  1385  	btlPolicy := btltestutil.SampleBTLPolicy(
  1386  		map[[2]string]uint64{
  1387  			{"ns", "coll"}: 1,
  1388  		},
  1389  	)
  1390  	testEnv.init(t, ledgerid, btlPolicy)
  1391  	defer testEnv.cleanup()
  1392  
  1393  	txMgr := testEnv.getTxMgr()
  1394  	populateCollConfigForTest(t, txMgr.(*LockBasedTxMgr), []collConfigkey{{"ns", "coll"}}, version.NewHeight(1, 1))
  1395  
  1396  	bg, _ := testutil.NewBlockGenerator(t, ledgerid, false)
  1397  
  1398  	blkAndPvtdata := prepareNextBlockForTest(t, txMgr, bg, "txid-1",
  1399  		map[string]string{"pubkey1": "pub-value1"}, map[string]string{"pvtkey1": "pvt-value1"}, false)
  1400  	_, _, err := txMgr.ValidateAndPrepare(blkAndPvtdata, true)
  1401  	assert.NoError(t, err)
  1402  	assert.NoError(t, txMgr.Commit())
  1403  
  1404  	assert.True(t, testPvtValueEqual(t, txMgr, "ns", "coll", "pvtkey1", []byte("pvt-value1")))
  1405  
  1406  	blkAndPvtdata = prepareNextBlockForTest(t, txMgr, bg, "txid-2",
  1407  
  1408  		map[string]string{"pubkey1": "pub-value2"}, map[string]string{"pvtkey2": "pvt-value2"}, false)
  1409  	_, _, err = txMgr.ValidateAndPrepare(blkAndPvtdata, true)
  1410  	assert.NoError(t, err)
  1411  	assert.NoError(t, txMgr.Commit())
  1412  
  1413  	assert.True(t, testPvtValueEqual(t, txMgr, "ns", "coll", "pvtkey1", []byte("pvt-value1")))
  1414  
  1415  	blkAndPvtdata = prepareNextBlockForTest(t, txMgr, bg, "txid-2",
  1416  		map[string]string{"pubkey1": "pub-value3"}, map[string]string{"pvtkey3": "pvt-value3"}, false)
  1417  	_, _, err = txMgr.ValidateAndPrepare(blkAndPvtdata, true)
  1418  	assert.NoError(t, err)
  1419  	assert.NoError(t, txMgr.Commit())
  1420  
  1421  	assert.True(t, testPvtValueEqual(t, txMgr, "ns", "coll", "pvtkey1", nil))
  1422  }
  1423  
  1424  func TestTxWithPubMetadata(t *testing.T) {
  1425  	for _, testEnv := range testEnvs {
  1426  		t.Logf("Running test for TestEnv = %s", testEnv.getName())
  1427  		testLedgerID := "testtxwithpubmetadata"
  1428  		testEnv.init(t, testLedgerID, nil)
  1429  		testTxWithPubMetadata(t, testEnv)
  1430  		testEnv.cleanup()
  1431  	}
  1432  }
  1433  
  1434  func testTxWithPubMetadata(t *testing.T, env testEnv) {
  1435  	namespace := "testns"
  1436  	txMgr := env.getTxMgr()
  1437  	txMgrHelper := newTxMgrTestHelper(t, txMgr)
  1438  
  1439  	// Simulate and commit tx1 - set val and metadata for key1 and key2. Set only metadata for key3
  1440  	s1, _ := txMgr.NewTxSimulator("test_tx1")
  1441  	key1, value1, metadata1 := "key1", []byte("value1"), map[string][]byte{"entry1": []byte("meatadata1-entry1")}
  1442  	key2, value2, metadata2 := "key2", []byte("value2"), map[string][]byte{"entry1": []byte("meatadata2-entry1")}
  1443  	key3, metadata3 := "key3", map[string][]byte{"entry1": []byte("meatadata3-entry")}
  1444  
  1445  	s1.SetState(namespace, key1, value1)
  1446  	s1.SetStateMetadata(namespace, key1, metadata1)
  1447  	s1.SetState(namespace, key2, value2)
  1448  	s1.SetStateMetadata(namespace, key2, metadata2)
  1449  	s1.SetStateMetadata(namespace, key3, metadata3)
  1450  	s1.Done()
  1451  	txRWSet1, _ := s1.GetTxSimulationResults()
  1452  	txMgrHelper.validateAndCommitRWSet(txRWSet1.PubSimulationResults)
  1453  
  1454  	// Run query - key1 and key2 should return both value and metadata. Key3 should still be non-exsting in db
  1455  	qe, _ := txMgr.NewQueryExecutor("test_tx2")
  1456  	checkTestQueryResults(t, qe, namespace, key1, value1, metadata1)
  1457  	checkTestQueryResults(t, qe, namespace, key2, value2, metadata2)
  1458  	checkTestQueryResults(t, qe, namespace, key3, nil, nil)
  1459  	qe.Done()
  1460  
  1461  	// Simulate and commit tx3 - update metadata for key1 and delete metadata for key2
  1462  	updatedMetadata1 := map[string][]byte{"entry1": []byte("meatadata1-entry1"), "entry2": []byte("meatadata1-entry2")}
  1463  	s2, _ := txMgr.NewTxSimulator("test_tx3")
  1464  	s2.SetStateMetadata(namespace, key1, updatedMetadata1)
  1465  	s2.DeleteStateMetadata(namespace, key2)
  1466  	s2.Done()
  1467  	txRWSet2, _ := s2.GetTxSimulationResults()
  1468  	txMgrHelper.validateAndCommitRWSet(txRWSet2.PubSimulationResults)
  1469  
  1470  	// Run query - key1 should return updated metadata. Key2 should return 'nil' metadata
  1471  	qe, _ = txMgr.NewQueryExecutor("test_tx4")
  1472  	checkTestQueryResults(t, qe, namespace, key1, value1, updatedMetadata1)
  1473  	checkTestQueryResults(t, qe, namespace, key2, value2, nil)
  1474  	qe.Done()
  1475  }
  1476  
  1477  func TestTxWithPvtdataMetadata(t *testing.T) {
  1478  	ledgerid, ns, coll := "testtxwithpvtdatametadata", "ns", "coll"
  1479  	btlPolicy := btltestutil.SampleBTLPolicy(
  1480  		map[[2]string]uint64{
  1481  			{"ns", "coll"}: 1000,
  1482  		},
  1483  	)
  1484  	for _, testEnv := range testEnvs {
  1485  		t.Logf("Running test for TestEnv = %s", testEnv.getName())
  1486  		testEnv.init(t, ledgerid, btlPolicy)
  1487  		testTxWithPvtdataMetadata(t, testEnv, ns, coll)
  1488  		testEnv.cleanup()
  1489  	}
  1490  }
  1491  
  1492  func testTxWithPvtdataMetadata(t *testing.T, env testEnv, ns, coll string) {
  1493  	ledgerid := "testtxwithpvtdatametadata"
  1494  	txMgr := env.getTxMgr()
  1495  	bg, _ := testutil.NewBlockGenerator(t, ledgerid, false)
  1496  
  1497  	populateCollConfigForTest(t, txMgr.(*LockBasedTxMgr), []collConfigkey{{"ns", "coll"}}, version.NewHeight(1, 1))
  1498  
  1499  	// Simulate and commit tx1 - set val and metadata for key1 and key2. Set only metadata for key3
  1500  	s1, _ := txMgr.NewTxSimulator("test_tx1")
  1501  	key1, value1, metadata1 := "key1", []byte("value1"), map[string][]byte{"entry1": []byte("meatadata1-entry1")}
  1502  	key2, value2, metadata2 := "key2", []byte("value2"), map[string][]byte{"entry1": []byte("meatadata2-entry1")}
  1503  	key3, metadata3 := "key3", map[string][]byte{"entry1": []byte("meatadata3-entry")}
  1504  	s1.SetPrivateData(ns, coll, key1, value1)
  1505  	s1.SetPrivateDataMetadata(ns, coll, key1, metadata1)
  1506  	s1.SetPrivateData(ns, coll, key2, value2)
  1507  	s1.SetPrivateDataMetadata(ns, coll, key2, metadata2)
  1508  	s1.SetPrivateDataMetadata(ns, coll, key3, metadata3)
  1509  	s1.Done()
  1510  
  1511  	blkAndPvtdata1 := prepareNextBlockForTestFromSimulator(t, bg, s1)
  1512  	_, _, err := txMgr.ValidateAndPrepare(blkAndPvtdata1, true)
  1513  	assert.NoError(t, err)
  1514  	assert.NoError(t, txMgr.Commit())
  1515  
  1516  	// Run query - key1 and key2 should return both value and metadata. Key3 should still be non-exsting in db
  1517  	qe, _ := txMgr.NewQueryExecutor("test_tx2")
  1518  	checkPvtdataTestQueryResults(t, qe, ns, coll, key1, value1, metadata1)
  1519  	checkPvtdataTestQueryResults(t, qe, ns, coll, key2, value2, metadata2)
  1520  	checkPvtdataTestQueryResults(t, qe, ns, coll, key3, nil, nil)
  1521  	qe.Done()
  1522  
  1523  	// Simulate and commit tx3 - update metadata for key1 and delete metadata for key2
  1524  	updatedMetadata1 := map[string][]byte{"entry1": []byte("meatadata1-entry1"), "entry2": []byte("meatadata1-entry2")}
  1525  	s2, _ := txMgr.NewTxSimulator("test_tx3")
  1526  	s2.SetPrivateDataMetadata(ns, coll, key1, updatedMetadata1)
  1527  	s2.DeletePrivateDataMetadata(ns, coll, key2)
  1528  	s2.Done()
  1529  
  1530  	blkAndPvtdata2 := prepareNextBlockForTestFromSimulator(t, bg, s2)
  1531  	_, _, err = txMgr.ValidateAndPrepare(blkAndPvtdata2, true)
  1532  	assert.NoError(t, err)
  1533  	assert.NoError(t, txMgr.Commit())
  1534  
  1535  	// Run query - key1 should return updated metadata. Key2 should return 'nil' metadata
  1536  	qe, _ = txMgr.NewQueryExecutor("test_tx4")
  1537  	checkPvtdataTestQueryResults(t, qe, ns, coll, key1, value1, updatedMetadata1)
  1538  	checkPvtdataTestQueryResults(t, qe, ns, coll, key2, value2, nil)
  1539  	qe.Done()
  1540  }
  1541  
  1542  func prepareNextBlockForTest(t *testing.T, txMgr txmgr.TxMgr, bg *testutil.BlockGenerator,
  1543  	txid string, pubKVs map[string]string, pvtKVs map[string]string, isMissing bool) *ledger.BlockAndPvtData {
  1544  	simulator, _ := txMgr.NewTxSimulator(txid)
  1545  	//simulating transaction
  1546  	for k, v := range pubKVs {
  1547  		simulator.SetState("ns", k, []byte(v))
  1548  	}
  1549  	for k, v := range pvtKVs {
  1550  		simulator.SetPrivateData("ns", "coll", k, []byte(v))
  1551  	}
  1552  	simulator.Done()
  1553  	if isMissing {
  1554  		return prepareNextBlockForTestFromSimulatorWithMissingData(t, bg, simulator, txid, 1, "ns", "coll", true)
  1555  	}
  1556  	return prepareNextBlockForTestFromSimulator(t, bg, simulator)
  1557  }
  1558  
  1559  func prepareNextBlockForTestFromSimulator(t *testing.T, bg *testutil.BlockGenerator, simulator ledger.TxSimulator) *ledger.BlockAndPvtData {
  1560  	simRes, _ := simulator.GetTxSimulationResults()
  1561  	pubSimBytes, _ := simRes.GetPubSimulationBytes()
  1562  	block := bg.NextBlock([][]byte{pubSimBytes})
  1563  	return &ledger.BlockAndPvtData{Block: block,
  1564  		PvtData: ledger.TxPvtDataMap{0: {SeqInBlock: 0, WriteSet: simRes.PvtSimulationResults}},
  1565  	}
  1566  }
  1567  
  1568  func prepareNextBlockForTestFromSimulatorWithMissingData(t *testing.T, bg *testutil.BlockGenerator, simulator ledger.TxSimulator,
  1569  	txid string, txNum uint64, ns, coll string, isEligible bool) *ledger.BlockAndPvtData {
  1570  	simRes, _ := simulator.GetTxSimulationResults()
  1571  	pubSimBytes, _ := simRes.GetPubSimulationBytes()
  1572  	block := bg.NextBlock([][]byte{pubSimBytes})
  1573  	missingData := make(ledger.TxMissingPvtDataMap)
  1574  	missingData.Add(txNum, ns, coll, isEligible)
  1575  	return &ledger.BlockAndPvtData{Block: block, MissingPvtData: missingData}
  1576  }
  1577  
  1578  func checkTestQueryResults(t *testing.T, qe ledger.QueryExecutor, ns, key string,
  1579  	expectedVal []byte, expectedMetadata map[string][]byte) {
  1580  	committedVal, err := qe.GetState(ns, key)
  1581  	assert.NoError(t, err)
  1582  	assert.Equal(t, expectedVal, committedVal)
  1583  
  1584  	committedMetadata, err := qe.GetStateMetadata(ns, key)
  1585  	assert.NoError(t, err)
  1586  	assert.Equal(t, expectedMetadata, committedMetadata)
  1587  	t.Logf("key=%s, value=%s, metadata=%s", key, committedVal, committedMetadata)
  1588  }
  1589  
  1590  func checkPvtdataTestQueryResults(t *testing.T, qe ledger.QueryExecutor, ns, coll, key string,
  1591  	expectedVal []byte, expectedMetadata map[string][]byte) {
  1592  	committedVal, err := qe.GetPrivateData(ns, coll, key)
  1593  	assert.NoError(t, err)
  1594  	assert.Equal(t, expectedVal, committedVal)
  1595  
  1596  	committedMetadata, err := qe.GetPrivateDataMetadata(ns, coll, key)
  1597  	assert.NoError(t, err)
  1598  	assert.Equal(t, expectedMetadata, committedMetadata)
  1599  	t.Logf("key=%s, value=%s, metadata=%s", key, committedVal, committedMetadata)
  1600  }
  1601  
  1602  func TestName(t *testing.T) {
  1603  	testEnv := testEnvsMap[levelDBtestEnvName]
  1604  	testEnv.init(t, "testLedger", nil)
  1605  	defer testEnv.cleanup()
  1606  	txMgr := testEnv.getTxMgr()
  1607  	assert.Equal(t, "state", txMgr.Name())
  1608  }