github.com/osdi23p228/fabric@v0.0.0-20221218062954-77808885f5db/core/ledger/kvledger/txmgmt/txmgr/txmgr_test.go (about)

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