Example #1
0
func TestStateImpl_DB_Changes(t *testing.T) {
	// number of buckets at each level 26,9,3,1
	testHasher, stateImplTestWrapper, stateDelta := createFreshDBAndInitTestStateImplWithCustomHasher(t, 26, 3)
	// populate hash fucntion such that
	// ["chaincodeID1", "key1"] is bucketized to bucket 1
	testHasher.populate("chaincodeID1", "key1", 0)
	testHasher.populate("chaincodeID1", "key2", 0)
	testHasher.populate("chaincodeID2", "key1", 1)
	testHasher.populate("chaincodeID2", "key3", 3)
	testHasher.populate("chaincodeID10", "key10", 24)

	// prepare stateDelta
	stateDelta.Set("chaincodeID1", "key1", []byte("value1"), nil)
	stateDelta.Set("chaincodeID1", "key2", []byte("value2"), nil)
	stateDelta.Set("chaincodeID2", "key1", []byte("value3"), nil)
	stateDelta.Set("chaincodeID2", "key3", []byte("value4"), nil)

	stateImplTestWrapper.prepareWorkingSetAndComputeCryptoHash(stateDelta)
	stateImplTestWrapper.persistChangesAndResetInMemoryChanges()

	// Read state from DB
	testutil.AssertEquals(t, stateImplTestWrapper.get("chaincodeID1", "key1"), []byte("value1"))
	testutil.AssertEquals(t, stateImplTestWrapper.get("chaincodeID2", "key1"), []byte("value3"))

	// fetch datanode from DB
	dataNodeFromDB, _ := fetchDataNodeFromDB(newDataKey("chaincodeID2", "key1"))
	testutil.AssertEquals(t, dataNodeFromDB, newDataNode(newDataKey("chaincodeID2", "key1"), []byte("value3")))

	//fetch non-existing data node from DB
	dataNodeFromDB, _ = fetchDataNodeFromDB(newDataKey("chaincodeID10", "key10"))
	t.Logf("isNIL...[%t]", dataNodeFromDB == nil)
	testutil.AssertNil(t, dataNodeFromDB)

	// fetch all data nodes from db that belong to bucket 1 at lowest level
	dataNodesFromDB, _ := fetchDataNodesFromDBFor(newBucketKeyAtLowestLevel(1))
	testutil.AssertContainsAll(t, dataNodesFromDB,
		dataNodes{newDataNode(newDataKey("chaincodeID1", "key1"), []byte("value1")),
			newDataNode(newDataKey("chaincodeID1", "key2"), []byte("value2"))})

	// fetch all data nodes from db that belong to bucket 2 at lowest level
	dataNodesFromDB, _ = fetchDataNodesFromDBFor(newBucketKeyAtLowestLevel(2))
	testutil.AssertContainsAll(t, dataNodesFromDB,
		dataNodes{newDataNode(newDataKey("chaincodeID2", "key1"), []byte("value3"))})

	// fetch first bucket at second level
	bucketNodeFromDB, _ := fetchBucketNodeFromDB(newBucketKey(2, 1))
	testutil.AssertEquals(t, bucketNodeFromDB.bucketKey, newBucketKey(2, 1))
	//check childrenCryptoHash entries in the bucket node from DB
	testutil.AssertEquals(t, bucketNodeFromDB.childrenCryptoHash[0],
		expectedBucketHashForTest([]string{"chaincodeID1", "key1", "value1", "key2", "value2"}))

	testutil.AssertEquals(t, bucketNodeFromDB.childrenCryptoHash[1],
		expectedBucketHashForTest([]string{"chaincodeID2", "key1", "value3"}))

	testutil.AssertNil(t, bucketNodeFromDB.childrenCryptoHash[2])

	// third bucket at second level should be nil
	bucketNodeFromDB, _ = fetchBucketNodeFromDB(newBucketKey(2, 3))
	testutil.AssertNil(t, bucketNodeFromDB)
}
func TestStateSnapshotIterator(t *testing.T) {
	testDBWrapper.CreateFreshDB(t)
	stateTrieTestWrapper := newStateTrieTestWrapper(t)
	stateTrie := stateTrieTestWrapper.stateTrie
	stateDelta := statemgmt.NewStateDelta()

	// insert keys
	stateDelta.Set("chaincodeID1", "key1", []byte("value1"), nil)
	stateDelta.Set("chaincodeID2", "key2", []byte("value2"), nil)
	stateDelta.Set("chaincodeID3", "key3", []byte("value3"), nil)
	stateDelta.Set("chaincodeID4", "key4", []byte("value4"), nil)
	stateDelta.Set("chaincodeID5", "key5", []byte("value5"), nil)
	stateDelta.Set("chaincodeID6", "key6", []byte("value6"), nil)
	stateTrie.PrepareWorkingSet(stateDelta)
	stateTrieTestWrapper.PersistChangesAndResetInMemoryChanges()
	//check that the key is persisted
	testutil.AssertEquals(t, stateTrieTestWrapper.Get("chaincodeID1", "key1"), []byte("value1"))
	testutil.AssertEquals(t, stateTrieTestWrapper.Get("chaincodeID2", "key2"), []byte("value2"))
	testutil.AssertEquals(t, stateTrieTestWrapper.Get("chaincodeID3", "key3"), []byte("value3"))
	testutil.AssertEquals(t, stateTrieTestWrapper.Get("chaincodeID4", "key4"), []byte("value4"))
	testutil.AssertEquals(t, stateTrieTestWrapper.Get("chaincodeID5", "key5"), []byte("value5"))
	testutil.AssertEquals(t, stateTrieTestWrapper.Get("chaincodeID6", "key6"), []byte("value6"))

	// take db snapeshot
	dbSnapshot := db.GetDBHandle().GetSnapshot()

	stateDelta1 := statemgmt.NewStateDelta()
	// delete a few keys
	stateDelta1.Delete("chaincodeID1", "key1", nil)
	stateDelta1.Delete("chaincodeID3", "key3", nil)
	stateDelta1.Delete("chaincodeID4", "key4", nil)
	stateDelta1.Delete("chaincodeID6", "key6", nil)

	// update remaining keys
	stateDelta1.Set("chaincodeID2", "key2", []byte("value2_new"), nil)
	stateDelta1.Set("chaincodeID5", "key5", []byte("value5_new"), nil)

	stateTrie.PrepareWorkingSet(stateDelta1)
	stateTrieTestWrapper.PersistChangesAndResetInMemoryChanges()
	//check that the keys are updated
	testutil.AssertNil(t, stateTrieTestWrapper.Get("chaincodeID1", "key1"))
	testutil.AssertNil(t, stateTrieTestWrapper.Get("chaincodeID3", "key3"))
	testutil.AssertNil(t, stateTrieTestWrapper.Get("chaincodeID4", "key4"))
	testutil.AssertNil(t, stateTrieTestWrapper.Get("chaincodeID6", "key6"))
	testutil.AssertEquals(t, stateTrieTestWrapper.Get("chaincodeID2", "key2"), []byte("value2_new"))
	testutil.AssertEquals(t, stateTrieTestWrapper.Get("chaincodeID5", "key5"), []byte("value5_new"))

	itr, err := newStateSnapshotIterator(dbSnapshot)
	testutil.AssertNoError(t, err, "Error while getting state snapeshot iterator")

	stateDeltaFromSnapshot := statemgmt.NewStateDelta()
	for itr.Next() {
		keyBytes, valueBytes := itr.GetRawKeyValue()
		t.Logf("key=[%s], value=[%s]", string(keyBytes), string(valueBytes))
		chaincodeID, key := statemgmt.DecodeCompositeKey(keyBytes)
		stateDeltaFromSnapshot.Set(chaincodeID, key, valueBytes, nil)
	}
	testutil.AssertEquals(t, stateDelta, stateDeltaFromSnapshot)
}
func TestBlockChain_SimpleChain(t *testing.T) {
	testDBWrapper.CreateFreshDB(t)
	blockchainTestWrapper := newTestBlockchainWrapper(t)
	blockchain := blockchainTestWrapper.blockchain
	allBlocks, allStateHashes := blockchainTestWrapper.populateBlockChainWithSampleData()
	testutil.AssertEquals(t, blockchain.getSize(), uint64(len(allBlocks)))
	testutil.AssertEquals(t, blockchainTestWrapper.fetchBlockchainSizeFromDB(), uint64(len(allBlocks)))

	for i := range allStateHashes {
		t.Logf("Checking state hash for block number = [%d]", i)
		testutil.AssertEquals(t, blockchainTestWrapper.getBlock(uint64(i)).GetStateHash(), allStateHashes[i])
	}

	for i := range allBlocks {
		t.Logf("Checking block hash for block number = [%d]", i)
		blockhash, _ := blockchainTestWrapper.getBlock(uint64(i)).GetHash()
		expectedBlockHash, _ := allBlocks[i].GetHash()
		testutil.AssertEquals(t, blockhash, expectedBlockHash)
	}

	testutil.AssertNil(t, blockchainTestWrapper.getBlock(uint64(0)).PreviousBlockHash)

	i := 1
	for i < len(allBlocks) {
		t.Logf("Checking previous block hash for block number = [%d]", i)
		expectedPreviousBlockHash, _ := allBlocks[i-1].GetHash()
		testutil.AssertEquals(t, blockchainTestWrapper.getBlock(uint64(i)).PreviousBlockHash, expectedPreviousBlockHash)
		i++
	}
}
Example #4
0
func TestLedgerRollbackWithHash(t *testing.T) {
	ledgerTestWrapper := createFreshDBAndTestLedgerWrapper(t)
	ledger := ledgerTestWrapper.ledger

	ledger.BeginTxBatch(0)
	ledger.TxBegin("txUuid")
	ledger.SetState("chaincode0", "key1", []byte("value1"))
	ledger.SetState("chaincode0", "key2", []byte("value2"))
	ledger.SetState("chaincode0", "key3", []byte("value3"))
	ledger.TxFinished("txUuid", true)
	ledger.RollbackTxBatch(0)

	hash0 := ledgerTestWrapper.GetTempStateHash()

	ledger.BeginTxBatch(1)
	ledger.TxBegin("txUuid")
	ledger.SetState("chaincode1", "key1", []byte("value1"))
	ledger.SetState("chaincode2", "key2", []byte("value2"))
	ledger.SetState("chaincode3", "key3", []byte("value3"))
	ledger.TxFinished("txUuid", true)

	hash1 := ledgerTestWrapper.GetTempStateHash()
	testutil.AssertNotEquals(t, hash1, hash0)

	ledger.RollbackTxBatch(1)
	hash1 = ledgerTestWrapper.GetTempStateHash()
	testutil.AssertEquals(t, hash1, hash0)
	testutil.AssertNil(t, ledgerTestWrapper.GetState("chaincode1", "key1", false))
}
Example #5
0
func TestDeleteAllStateKeysAndValues(t *testing.T) {
	ledgerTestWrapper := createFreshDBAndTestLedgerWrapper(t)
	ledger := ledgerTestWrapper.ledger
	ledger.BeginTxBatch(1)
	ledger.TxBegin("txUuid1")
	ledger.SetState("chaincode1", "key1", []byte("value1"))
	ledger.SetState("chaincode2", "key2", []byte("value2"))
	ledger.SetState("chaincode3", "key3", []byte("value3"))
	ledger.TxFinished("txUuid1", true)
	transaction, _ := buildTestTx(t)
	ledger.CommitTxBatch(1, []*protos.Transaction{transaction}, nil, []byte("proof"))

	// Confirm values are present in state
	testutil.AssertEquals(t, ledgerTestWrapper.GetState("chaincode1", "key1", true), []byte("value1"))
	testutil.AssertEquals(t, ledgerTestWrapper.GetState("chaincode2", "key2", true), []byte("value2"))
	testutil.AssertEquals(t, ledgerTestWrapper.GetState("chaincode3", "key3", true), []byte("value3"))

	// Delete all keys/values
	err := ledger.DeleteALLStateKeysAndValues()
	if err != nil {
		t.Fatalf("Error calling deleting all keys/values from state: %s", err)
	}

	// Confirm values are deleted
	testutil.AssertNil(t, ledgerTestWrapper.GetState("chaincode1", "key1", true))
	testutil.AssertNil(t, ledgerTestWrapper.GetState("chaincode2", "key2", true))
	testutil.AssertNil(t, ledgerTestWrapper.GetState("chaincode3", "key3", true))

	// Test that we can now store new stuff in the state
	ledger.BeginTxBatch(2)
	ledger.TxBegin("txUuid1")
	ledger.SetState("chaincode1", "key1", []byte("value1"))
	ledger.SetState("chaincode2", "key2", []byte("value2"))
	ledger.SetState("chaincode3", "key3", []byte("value3"))
	ledger.TxFinished("txUuid1", true)
	transaction, _ = buildTestTx(t)
	ledger.CommitTxBatch(2, []*protos.Transaction{transaction}, nil, []byte("proof"))

	// Confirm values are present in state
	testutil.AssertEquals(t, ledgerTestWrapper.GetState("chaincode1", "key1", true), []byte("value1"))
	testutil.AssertEquals(t, ledgerTestWrapper.GetState("chaincode2", "key2", true), []byte("value2"))
	testutil.AssertEquals(t, ledgerTestWrapper.GetState("chaincode3", "key3", true), []byte("value3"))
}
Example #6
0
func TestStateChanges(t *testing.T) {
	stateTestWrapper, state := createFreshDBAndConstructState(t)
	// add keys
	state.TxBegin("txUuid")
	state.Set("chaincode1", "key1", []byte("value1"))
	state.Set("chaincode1", "key2", []byte("value2"))
	state.TxFinish("txUuid", true)
	//chehck in-memory
	testutil.AssertEquals(t, stateTestWrapper.get("chaincode1", "key1", false), []byte("value1"))
	testutil.AssertNil(t, stateTestWrapper.get("chaincode1", "key1", true))

	delta := state.getStateDelta()
	// save to db
	stateTestWrapper.persistAndClearInMemoryChanges(0)
	testutil.AssertEquals(t, stateTestWrapper.get("chaincode1", "key1", true), []byte("value1"))
	testutil.AssertEquals(t, stateTestWrapper.fetchStateDeltaFromDB(0), delta)

	// make changes when data is already in db
	state.TxBegin("txUuid")
	state.Set("chaincode1", "key1", []byte("new_value1"))
	state.TxFinish("txUuid", true)
	testutil.AssertEquals(t, stateTestWrapper.get("chaincode1", "key1", false), []byte("new_value1"))

	state.TxBegin("txUuid")
	state.Delete("chaincode1", "key2")
	state.TxFinish("txUuid", true)
	testutil.AssertNil(t, stateTestWrapper.get("chaincode1", "key2", false))

	state.TxBegin("txUuid")
	state.Set("chaincode2", "key3", []byte("value3"))
	state.Set("chaincode2", "key4", []byte("value4"))
	state.TxFinish("txUuid", true)

	delta = state.getStateDelta()
	stateTestWrapper.persistAndClearInMemoryChanges(1)
	testutil.AssertEquals(t, stateTestWrapper.fetchStateDeltaFromDB(1), delta)

	testutil.AssertEquals(t, stateTestWrapper.get("chaincode1", "key1", true), []byte("new_value1"))
	testutil.AssertNil(t, stateTestWrapper.get("chaincode1", "key2", true))
	testutil.AssertEquals(t, stateTestWrapper.get("chaincode2", "key3", true), []byte("value3"))
}
Example #7
0
func TestLedgerRollback(t *testing.T) {
	ledgerTestWrapper := createFreshDBAndTestLedgerWrapper(t)
	ledger := ledgerTestWrapper.ledger
	ledger.BeginTxBatch(1)
	ledger.TxBegin("txUuid")
	ledger.SetState("chaincode1", "key1", []byte("value1"))
	ledger.SetState("chaincode2", "key2", []byte("value2"))
	ledger.SetState("chaincode3", "key3", []byte("value3"))
	ledger.TxFinished("txUuid", true)
	ledger.RollbackTxBatch(1)
	testutil.AssertNil(t, ledgerTestWrapper.GetState("chaincode1", "key1", false))
}
Example #8
0
func TestDeleteState(t *testing.T) {

	stateTestWrapper, state := createFreshDBAndConstructState(t)

	// Add keys
	state.TxBegin("txUuid")
	state.Set("chaincode1", "key1", []byte("value1"))
	state.Set("chaincode1", "key2", []byte("value2"))
	state.TxFinish("txUuid", true)
	state.getStateDelta()
	stateTestWrapper.persistAndClearInMemoryChanges(0)

	// confirm keys are present
	testutil.AssertEquals(t, stateTestWrapper.get("chaincode1", "key1", true), []byte("value1"))
	testutil.AssertEquals(t, stateTestWrapper.get("chaincode1", "key2", true), []byte("value2"))

	// Delete the State
	err := state.DeleteState()
	if err != nil {
		t.Fatalf("Error deleting the state: %s", err)
	}

	// confirm the values are empty
	testutil.AssertNil(t, stateTestWrapper.get("chaincode1", "key1", false))
	testutil.AssertNil(t, stateTestWrapper.get("chaincode1", "key2", false))
	testutil.AssertNil(t, stateTestWrapper.get("chaincode1", "key1", true))
	testutil.AssertNil(t, stateTestWrapper.get("chaincode1", "key2", true))

	// Confirm that we can now store new stuff in the state
	state.TxBegin("txUuid")
	state.Set("chaincode1", "key1", []byte("value1"))
	state.Set("chaincode1", "key2", []byte("value2"))
	state.TxFinish("txUuid", true)
	state.getStateDelta()
	stateTestWrapper.persistAndClearInMemoryChanges(1)

	// confirm keys are present
	testutil.AssertEquals(t, stateTestWrapper.get("chaincode1", "key1", true), []byte("value1"))
	testutil.AssertEquals(t, stateTestWrapper.get("chaincode1", "key2", true), []byte("value2"))
}
Example #9
0
func TestStateDeltaCryptoHash(t *testing.T) {
	stateDelta := NewStateDelta()

	testutil.AssertNil(t, stateDelta.ComputeCryptoHash())

	stateDelta.Set("chaincodeID1", "key2", []byte("value2"), nil)
	stateDelta.Set("chaincodeID1", "key1", []byte("value1"), nil)
	stateDelta.Set("chaincodeID2", "key2", []byte("value2"), nil)
	stateDelta.Set("chaincodeID2", "key1", []byte("value1"), nil)
	testutil.AssertEquals(t, stateDelta.ComputeCryptoHash(), testutil.ComputeCryptoHash([]byte("chaincodeID1key1value1key2value2chaincodeID2key1value1key2value2")))

	stateDelta.Delete("chaincodeID2", "key1", nil)
	testutil.AssertEquals(t, stateDelta.ComputeCryptoHash(), testutil.ComputeCryptoHash([]byte("chaincodeID1key1value1key2value2chaincodeID2key1key2value2")))
}
Example #10
0
func TestStateTxBehavior(t *testing.T) {
	stateTestWrapper, state := createFreshDBAndConstructState(t)
	if state.txInProgress() {
		t.Fatalf("No tx should be reported to be in progress")
	}

	// set state in a successful tx
	state.TxBegin("txUuid")
	state.Set("chaincode1", "key1", []byte("value1"))
	state.Set("chaincode2", "key2", []byte("value2"))
	testutil.AssertEquals(t, stateTestWrapper.get("chaincode1", "key1", false), []byte("value1"))
	state.TxFinish("txUuid", true)
	testutil.AssertEquals(t, stateTestWrapper.get("chaincode1", "key1", false), []byte("value1"))

	// set state in a failed tx
	state.TxBegin("txUuid1")
	state.Set("chaincode1", "key1", []byte("value1_new"))
	state.Set("chaincode2", "key2", []byte("value2_new"))
	testutil.AssertEquals(t, stateTestWrapper.get("chaincode1", "key1", false), []byte("value1_new"))
	state.TxFinish("txUuid1", false)
	//older state should be available
	testutil.AssertEquals(t, stateTestWrapper.get("chaincode1", "key1", false), []byte("value1"))

	// delete state in a successful tx
	state.TxBegin("txUuid2")
	state.Delete("chaincode1", "key1")
	testutil.AssertNil(t, stateTestWrapper.get("chaincode1", "key1", false))
	state.TxFinish("txUuid2", true)
	testutil.AssertNil(t, stateTestWrapper.get("chaincode1", "key1", false))

	// // delete state in a failed tx
	state.TxBegin("txUuid2")
	state.Delete("chaincode2", "key2")
	testutil.AssertNil(t, stateTestWrapper.get("chaincode2", "key2", false))
	state.TxFinish("txUuid2", false)
	testutil.AssertEquals(t, stateTestWrapper.get("chaincode2", "key2", false), []byte("value2"))
}
Example #11
0
func TestStateSnapshotIterator(t *testing.T) {
	testDBWrapper.CreateFreshDB(t)
	stateImplTestWrapper := newStateImplTestWrapper(t)
	stateDelta := statemgmt.NewStateDelta()

	// insert keys
	stateDelta.Set("chaincodeID1", "key1", []byte("value1"), nil)
	stateDelta.Set("chaincodeID2", "key2", []byte("value2"), nil)
	stateDelta.Set("chaincodeID3", "key3", []byte("value3"), nil)
	stateDelta.Set("chaincodeID4", "key4", []byte("value4"), nil)
	stateDelta.Set("chaincodeID5", "key5", []byte("value5"), nil)
	stateDelta.Set("chaincodeID6", "key6", []byte("value6"), nil)
	stateImplTestWrapper.prepareWorkingSet(stateDelta)
	stateImplTestWrapper.persistChangesAndResetInMemoryChanges()
	//check that the key is persisted
	testutil.AssertEquals(t, stateImplTestWrapper.get("chaincodeID5", "key5"), []byte("value5"))

	// take db snapeshot
	dbSnapshot := db.GetDBHandle().GetSnapshot()

	// delete keys
	stateDelta.Delete("chaincodeID1", "key1", nil)
	stateDelta.Delete("chaincodeID2", "key2", nil)
	stateDelta.Delete("chaincodeID3", "key3", nil)
	stateDelta.Delete("chaincodeID4", "key4", nil)
	stateDelta.Delete("chaincodeID5", "key5", nil)
	stateDelta.Delete("chaincodeID6", "key6", nil)
	stateImplTestWrapper.prepareWorkingSet(stateDelta)
	stateImplTestWrapper.persistChangesAndResetInMemoryChanges()
	//check that the key is deleted
	testutil.AssertNil(t, stateImplTestWrapper.get("chaincodeID5", "key5"))

	itr, err := newStateSnapshotIterator(dbSnapshot)
	testutil.AssertNoError(t, err, "Error while getting state snapeshot iterator")
	numKeys := 0
	for itr.Next() {
		key, value := itr.GetRawKeyValue()
		t.Logf("key=[%s], value=[%s]", string(key), string(value))
		numKeys++
	}
	testutil.AssertEquals(t, numKeys, 6)
}
Example #12
0
func TestStateSnapshot(t *testing.T) {
	stateTestWrapper, state := createFreshDBAndConstructState(t)
	// insert keys
	state.TxBegin("txUuid")
	state.Set("chaincodeID1", "key1", []byte("value1"))
	state.Set("chaincodeID2", "key2", []byte("value2"))
	state.Set("chaincodeID3", "key3", []byte("value3"))
	state.Set("chaincodeID4", "key4", []byte("value4"))
	state.Set("chaincodeID5", "key5", []byte("value5"))
	state.Set("chaincodeID6", "key6", []byte("value6"))
	state.TxFinish("txUuid", true)

	stateTestWrapper.persistAndClearInMemoryChanges(0)
	testutil.AssertEquals(t, stateTestWrapper.get("chaincodeID5", "key5", true), []byte("value5"))

	// take db snapeshot
	stateSnapshot := stateTestWrapper.getSnapshot()

	// delete keys
	state.TxBegin("txUuid")
	state.Delete("chaincodeID1", "key1")
	state.Delete("chaincodeID2", "key2")
	state.Delete("chaincodeID3", "key3")
	state.Delete("chaincodeID4", "key4")
	state.Delete("chaincodeID5", "key5")
	state.Delete("chaincodeID6", "key6")
	state.TxFinish("txUuid", true)
	stateTestWrapper.persistAndClearInMemoryChanges(0)
	//check that the key is deleted
	testutil.AssertNil(t, stateTestWrapper.get("chaincodeID5", "key5", true))

	numKeys := 0
	for stateSnapshot.Next() {
		key, value := stateSnapshot.GetRawKeyValue()
		t.Logf("key=[%s], value=[%s]", string(key), string(value))
		numKeys++
	}
	testutil.AssertEquals(t, numKeys, 6)
}
Example #13
0
func TestGetTransactionByUUID(t *testing.T) {
	ledgerTestWrapper := createFreshDBAndTestLedgerWrapper(t)
	ledger := ledgerTestWrapper.ledger

	// Block 0
	ledger.BeginTxBatch(0)
	ledger.TxBegin("txUuid1")
	ledger.SetState("chaincode1", "key1", []byte("value1A"))
	ledger.SetState("chaincode2", "key2", []byte("value2A"))
	ledger.SetState("chaincode3", "key3", []byte("value3A"))
	ledger.TxFinished("txUuid1", true)
	transaction, uuid := buildTestTx(t)
	ledger.CommitTxBatch(0, []*protos.Transaction{transaction}, nil, []byte("proof"))

	ledgerTransaction, err := ledger.GetTransactionByUUID(uuid)
	testutil.AssertNoError(t, err, "Error fetching transaction by UUID.")
	testutil.AssertEquals(t, transaction, ledgerTransaction)

	ledgerTransaction, err = ledger.GetTransactionByUUID("InvalidUUID")
	testutil.AssertEquals(t, err, ErrResourceNotFound)
	testutil.AssertNil(t, ledgerTransaction)
}
Example #14
0
func TestLedgerGetTempStateHashWithTxDeltaStateHashes(t *testing.T) {
	ledgerTestWrapper := createFreshDBAndTestLedgerWrapper(t)
	ledger := ledgerTestWrapper.ledger
	ledger.BeginTxBatch(1)
	ledger.TxBegin("txUuid1")
	ledger.SetState("chaincode1", "key1", []byte("value1"))
	ledger.TxFinished("txUuid1", true)

	ledger.TxBegin("txUuid2")
	ledger.SetState("chaincode2", "key2", []byte("value2"))
	ledger.TxFinished("txUuid2", true)

	ledger.TxBegin("txUuid3")
	ledger.TxFinished("txUuid3", true)

	ledger.TxBegin("txUuid4")
	ledger.SetState("chaincode4", "key4", []byte("value4"))
	ledger.TxFinished("txUuid4", false)

	_, txDeltaHashes, _ := ledger.GetTempStateHashWithTxDeltaStateHashes()
	testutil.AssertEquals(t, testutil.ComputeCryptoHash([]byte("chaincode1key1value1")), txDeltaHashes["txUuid1"])
	testutil.AssertEquals(t, testutil.ComputeCryptoHash([]byte("chaincode2key2value2")), txDeltaHashes["txUuid2"])
	testutil.AssertNil(t, txDeltaHashes["txUuid3"])
	_, ok := txDeltaHashes["txUuid4"]
	if ok {
		t.Fatalf("Entry for a failed Tx should not be present in txDeltaHashes map")
	}
	ledger.CommitTxBatch(1, []*protos.Transaction{}, nil, []byte("proof"))

	ledger.BeginTxBatch(2)
	ledger.TxBegin("txUuid1")
	ledger.SetState("chaincode1", "key1", []byte("value1"))
	ledger.TxFinished("txUuid1", true)
	_, txDeltaHashes, _ = ledger.GetTempStateHashWithTxDeltaStateHashes()
	if len(txDeltaHashes) != 1 {
		t.Fatalf("Entries in txDeltaHashes map should only be from current batch")
	}
}
Example #15
0
func TestStateImpl_ComputeHash_DB_3(t *testing.T) {
	// simple test... not using custom hasher
	conf = initConfig(DefaultNumBuckets, DefaultMaxGroupingAtEachLevel, fnvHash)
	testDBWrapper.CreateFreshDB(t)
	stateImplTestWrapper := newStateImplTestWrapper(t)
	stateImpl := stateImplTestWrapper.stateImpl
	stateDelta := statemgmt.NewStateDelta()
	stateDelta.Set("chaincode1", "key1", []byte("value1"), nil)
	stateDelta.Set("chaincode2", "key2", []byte("value2"), nil)
	stateDelta.Set("chaincode3", "key3", []byte("value3"), nil)
	stateImpl.PrepareWorkingSet(stateDelta)
	hash1 := stateImplTestWrapper.computeCryptoHash()
	stateImplTestWrapper.persistChangesAndResetInMemoryChanges()

	stateDelta = statemgmt.NewStateDelta()
	stateDelta.Delete("chaincode1", "key1", nil)
	stateDelta.Delete("chaincode2", "key2", nil)
	stateDelta.Delete("chaincode3", "key3", nil)
	stateImpl.PrepareWorkingSet(stateDelta)
	hash2 := stateImplTestWrapper.computeCryptoHash()
	stateImplTestWrapper.persistChangesAndResetInMemoryChanges()
	testutil.AssertNotEquals(t, hash1, hash2)
	testutil.AssertNil(t, hash2)
}
Example #16
0
func TestStateImpl_ComputeHash_DB_1(t *testing.T) {
	// number of buckets at each level 26,9,3,1
	testHasher, stateImplTestWrapper, stateDelta := createFreshDBAndInitTestStateImplWithCustomHasher(t, 26, 3)
	// populate hash fucntion such that
	// all keys belong to a single bucket so as to test overwrite/delete scenario
	testHasher.populate("chaincodeID1", "key1", 3)
	testHasher.populate("chaincodeID2", "key2", 3)
	testHasher.populate("chaincodeID3", "key3", 3)
	testHasher.populate("chaincodeID4", "key4", 3)
	testHasher.populate("chaincodeID5", "key5", 3)
	testHasher.populate("chaincodeID6", "key6", 3)
	testHasher.populate("chaincodeID7", "key7", 3)

	stateDelta.Set("chaincodeID2", "key2", []byte("value2"), nil)
	stateDelta.Set("chaincodeID3", "key3", []byte("value3"), nil)
	stateDelta.Set("chaincodeID5", "key5", []byte("value5"), nil)
	stateDelta.Set("chaincodeID6", "key6", []byte("value6"), nil)
	rootHash := stateImplTestWrapper.prepareWorkingSetAndComputeCryptoHash(stateDelta)
	stateImplTestWrapper.persistChangesAndResetInMemoryChanges()

	expectedHash1 := testutil.ComputeCryptoHash(statemgmt.ConstructCompositeKey("chaincodeID2", "key2"), []byte("value2"),
		statemgmt.ConstructCompositeKey("chaincodeID3", "key3"), []byte("value3"),
		statemgmt.ConstructCompositeKey("chaincodeID5", "key5"), []byte("value5"),
		statemgmt.ConstructCompositeKey("chaincodeID6", "key6"), []byte("value6"))
	testutil.AssertEquals(t, rootHash, expectedHash1)

	// modify boundary keys and a middle key
	stateDelta = statemgmt.NewStateDelta()
	stateDelta.Set("chaincodeID2", "key2", []byte("value2_new"), nil)
	stateDelta.Set("chaincodeID3", "key3", []byte("value3_new"), nil)
	stateDelta.Set("chaincodeID6", "key6", []byte("value6_new"), nil)
	rootHash = stateImplTestWrapper.prepareWorkingSetAndComputeCryptoHash(stateDelta)
	stateImplTestWrapper.persistChangesAndResetInMemoryChanges()
	expectedHash2 := testutil.ComputeCryptoHash(statemgmt.ConstructCompositeKey("chaincodeID2", "key2"), []byte("value2_new"),
		statemgmt.ConstructCompositeKey("chaincodeID3", "key3"), []byte("value3_new"),
		statemgmt.ConstructCompositeKey("chaincodeID5", "key5"), []byte("value5"),
		statemgmt.ConstructCompositeKey("chaincodeID6", "key6"), []byte("value6_new"))
	testutil.AssertEquals(t, rootHash, expectedHash2)
	testutil.AssertEquals(t, stateImplTestWrapper.get("chaincodeID2", "key2"), []byte("value2_new"))
	testutil.AssertEquals(t, stateImplTestWrapper.get("chaincodeID3", "key3"), []byte("value3_new"))
	testutil.AssertEquals(t, stateImplTestWrapper.get("chaincodeID6", "key6"), []byte("value6_new"))

	// insert keys at boundary and in the middle
	stateDelta = statemgmt.NewStateDelta()
	stateDelta.Set("chaincodeID1", "key1", []byte("value1"), nil)
	stateDelta.Set("chaincodeID4", "key4", []byte("value4"), nil)
	stateDelta.Set("chaincodeID7", "key7", []byte("value7"), nil)
	rootHash = stateImplTestWrapper.prepareWorkingSetAndComputeCryptoHash(stateDelta)
	stateImplTestWrapper.persistChangesAndResetInMemoryChanges()
	expectedHash3 := testutil.ComputeCryptoHash(statemgmt.ConstructCompositeKey("chaincodeID1", "key1"), []byte("value1"),
		statemgmt.ConstructCompositeKey("chaincodeID2", "key2"), []byte("value2_new"),
		statemgmt.ConstructCompositeKey("chaincodeID3", "key3"), []byte("value3_new"),
		statemgmt.ConstructCompositeKey("chaincodeID4", "key4"), []byte("value4"),
		statemgmt.ConstructCompositeKey("chaincodeID5", "key5"), []byte("value5"),
		statemgmt.ConstructCompositeKey("chaincodeID6", "key6"), []byte("value6_new"),
		statemgmt.ConstructCompositeKey("chaincodeID7", "key7"), []byte("value7"))
	testutil.AssertEquals(t, rootHash, expectedHash3)
	testutil.AssertEquals(t, stateImplTestWrapper.get("chaincodeID1", "key1"), []byte("value1"))
	testutil.AssertEquals(t, stateImplTestWrapper.get("chaincodeID4", "key4"), []byte("value4"))
	testutil.AssertEquals(t, stateImplTestWrapper.get("chaincodeID7", "key7"), []byte("value7"))

	// delete keys at a boundary and in the middle
	stateDelta = statemgmt.NewStateDelta()
	stateDelta.Delete("chaincodeID1", "key1", nil)
	stateDelta.Delete("chaincodeID4", "key4", nil)
	stateDelta.Delete("chaincodeID7", "key7", nil)
	rootHash = stateImplTestWrapper.prepareWorkingSetAndComputeCryptoHash(stateDelta)
	stateImplTestWrapper.persistChangesAndResetInMemoryChanges()
	testutil.AssertEquals(t, rootHash, expectedHash2)
	testutil.AssertNil(t, stateImplTestWrapper.get("chaincodeID1", "key1"))
	testutil.AssertNil(t, stateImplTestWrapper.get("chaincodeID4", "key4"))
	testutil.AssertNil(t, stateImplTestWrapper.get("chaincodeID7", "key7"))
}
Example #17
0
func TestStateTrie_ComputeHash_WithDB_Spread_Keys(t *testing.T) {
	testDBWrapper.CreateFreshDB(t)
	stateTrie := NewStateTrie()
	stateTrieTestWrapper := &stateTrieTestWrapper{stateTrie, t}

	// Add a few keys and write to DB
	stateDelta := statemgmt.NewStateDelta()
	stateDelta.Set("chaincodeID1", "key1", []byte("value1"), nil)
	stateDelta.Set("chaincodeID1", "key2", []byte("value2"), nil)
	stateDelta.Set("chaincodeID2", "key3", []byte("value3"), nil)
	stateDelta.Set("chaincodeID2", "key4", []byte("value4"), nil)
	stateTrie.PrepareWorkingSet(stateDelta)
	stateTrieTestWrapper.PersistChangesAndResetInMemoryChanges()

	/////////////////////////////////////////////////////////
	// Test1 - Add a non-existing key
	/////////////////////////////////////////////////////////
	stateDelta = statemgmt.NewStateDelta()
	stateDelta.Set("chaincodeID3", "key5", []byte("value5"), nil)
	rootHash1 := stateTrieTestWrapper.PrepareWorkingSetAndComputeCryptoHash(stateDelta)
	expected_hash1 := computeTestHash(newTrieKey("chaincodeID1", "key1").getEncodedBytes(), []byte("value1"))
	expected_hash2 := computeTestHash(newTrieKey("chaincodeID1", "key2").getEncodedBytes(), []byte("value2"))
	expected_hash3 := computeTestHash(newTrieKey("chaincodeID2", "key3").getEncodedBytes(), []byte("value3"))
	expected_hash4 := computeTestHash(newTrieKey("chaincodeID2", "key4").getEncodedBytes(), []byte("value4"))
	expected_hash1_hash2 := computeTestHash(expected_hash1, expected_hash2)
	expected_hash3_hash4 := computeTestHash(expected_hash3, expected_hash4)
	expected_hash5 := computeTestHash(newTrieKey("chaincodeID3", "key5").getEncodedBytes(), []byte("value5"))
	expectedRootHash1 := computeTestHash(expected_hash1_hash2, expected_hash3_hash4, expected_hash5)
	testutil.AssertEquals(t, rootHash1, expectedRootHash1)
	stateTrieTestWrapper.PersistChangesAndResetInMemoryChanges()

	/////////////////////////////////////////////////////////
	// Test2 - Change value of an existing key
	/////////////////////////////////////////////////////////
	stateDelta = statemgmt.NewStateDelta()
	stateDelta.Set("chaincodeID2", "key4", []byte("value4-new"), nil)
	rootHash2 := stateTrieTestWrapper.PrepareWorkingSetAndComputeCryptoHash(stateDelta)
	expected_hash4 = computeTestHash(newTrieKey("chaincodeID2", "key4").getEncodedBytes(), []byte("value4-new"))
	expected_hash3_hash4 = computeTestHash(expected_hash3, expected_hash4)
	expectedRootHash2 := computeTestHash(expected_hash1_hash2, expected_hash3_hash4, expected_hash5)
	testutil.AssertEquals(t, rootHash2, expectedRootHash2)
	stateTrieTestWrapper.PersistChangesAndResetInMemoryChanges()

	/////////////////////////////////////////////////////////
	// Test3 - Change value of another existing key
	/////////////////////////////////////////////////////////
	stateDelta = statemgmt.NewStateDelta()
	stateDelta.Set("chaincodeID1", "key1", []byte("value1-new"), nil)
	rootHash3 := stateTrieTestWrapper.PrepareWorkingSetAndComputeCryptoHash(stateDelta)
	expected_hash1 = computeTestHash(newTrieKey("chaincodeID1", "key1").getEncodedBytes(), []byte("value1-new"))
	expected_hash1_hash2 = computeTestHash(expected_hash1, expected_hash2)
	expectedRootHash3 := computeTestHash(expected_hash1_hash2, expected_hash3_hash4, expected_hash5)
	testutil.AssertEquals(t, rootHash3, expectedRootHash3)
	stateTrieTestWrapper.PersistChangesAndResetInMemoryChanges()

	/////////////////////////////////////////////////////////
	// Test4 - Delete an existing existing key
	/////////////////////////////////////////////////////////
	fmt.Println("\n -- Delete an existing key --- ")
	stateDelta = statemgmt.NewStateDelta()
	stateDelta.Delete("chaincodeID3", "key5", nil)
	rootHash4 := stateTrieTestWrapper.PrepareWorkingSetAndComputeCryptoHash(stateDelta)
	expectedRootHash4 := computeTestHash(expected_hash1_hash2, expected_hash3_hash4)
	testutil.AssertEquals(t, rootHash4, expectedRootHash4)
	stateTrieTestWrapper.PersistChangesAndResetInMemoryChanges()
	// Delete should remove the key from db because, this key has no value and no children
	testutil.AssertNil(t, testDBWrapper.GetFromStateCF(t, newTrieKey("chaincodeID3", "key5").getEncodedBytes()))

	/////////////////////////////////////////////////////////
	// Test5 - Delete another existing existing key
	/////////////////////////////////////////////////////////
	stateDelta = statemgmt.NewStateDelta()
	stateDelta.Delete("chaincodeID2", "key4", nil)
	rootHash5 := stateTrieTestWrapper.PrepareWorkingSetAndComputeCryptoHash(stateDelta)
	expectedRootHash5 := computeTestHash(expected_hash1_hash2, expected_hash3)
	testutil.AssertEquals(t, rootHash5, expectedRootHash5)
	stateTrieTestWrapper.PersistChangesAndResetInMemoryChanges()
	testutil.AssertNil(t, testDBWrapper.GetFromStateCF(t, newTrieKey("chaincodeID2", "key4").getEncodedBytes()))
}
Example #18
0
func constructDummyTx(tb testing.TB) *protos.Transaction {
	uuid := util.GenerateUUID()
	tx, err := protos.NewTransaction(protos.ChaincodeID{Path: "dummyChaincodeId"}, uuid, "dummyFunction", []string{"dummyParamValue1, dummyParamValue2"})
	testutil.AssertNil(tb, err)
	return tx
}
Example #19
0
func buildTestTx(t *testing.T) (*protos.Transaction, string) {
	uuid, _ := util.GenerateUUID()
	tx, err := protos.NewTransaction(protos.ChaincodeID{Path: "testUrl"}, uuid, "anyfunction", []string{"param1, param2"})
	testutil.AssertNil(t, err)
	return tx, uuid
}
Example #20
0
func TestStateImpl_ComputeHash_DB_2(t *testing.T) {
	// number of buckets at each level 26,13,7,4,2,1
	testHasher, stateImplTestWrapper, stateDelta := createFreshDBAndInitTestStateImplWithCustomHasher(t, 26, 2)
	testHasher.populate("chaincodeID1", "key1", 0)
	testHasher.populate("chaincodeID2", "key2", 1)
	testHasher.populate("chaincodeID3", "key3", 5)
	testHasher.populate("chaincodeID4", "key4", 9)
	testHasher.populate("chaincodeID5", "key5", 24)
	testHasher.populate("chaincodeID6", "key6", 25)

	stateDelta.Set("chaincodeID1", "key1", []byte("value1"), nil)
	stateDelta.Set("chaincodeID2", "key2", []byte("value2"), nil)
	stateDelta.Set("chaincodeID3", "key3", []byte("value3"), nil)
	stateDelta.Set("chaincodeID4", "key4", []byte("value4"), nil)
	stateDelta.Set("chaincodeID5", "key5", []byte("value5"), nil)
	stateDelta.Set("chaincodeID6", "key6", []byte("value6"), nil)
	stateImplTestWrapper.prepareWorkingSet(stateDelta)
	// Populate DB
	stateImplTestWrapper.persistChangesAndResetInMemoryChanges()

	//////////// Test - constrcuting a new state tree simulates starting state tree when db already has some data ////////
	stateImplTestWrapper.constructNewStateImpl()
	rootHash := stateImplTestWrapper.computeCryptoHash()

	/*************************** bucket-tree-structure ***************
	1		1		1	1	1	1
	2		1		1	1	1	1
	6		3		2	1	1	1
	10	5		3	2	1	1
	25	13	7	4	2	1
	26	13	7	4	2	1
	*******************************************************************/
	expectedHashBucket5_1 := testutil.ComputeCryptoHash(statemgmt.ConstructCompositeKey("chaincodeID1", "key1"), []byte("value1"))
	expectedHashBucket5_2 := testutil.ComputeCryptoHash(statemgmt.ConstructCompositeKey("chaincodeID2", "key2"), []byte("value2"))
	expectedHashBucket5_6 := testutil.ComputeCryptoHash(statemgmt.ConstructCompositeKey("chaincodeID3", "key3"), []byte("value3"))
	expectedHashBucket5_10 := testutil.ComputeCryptoHash(statemgmt.ConstructCompositeKey("chaincodeID4", "key4"), []byte("value4"))
	expectedHashBucket5_25 := testutil.ComputeCryptoHash(statemgmt.ConstructCompositeKey("chaincodeID5", "key5"), []byte("value5"))
	expectedHashBucket5_26 := testutil.ComputeCryptoHash(statemgmt.ConstructCompositeKey("chaincodeID6", "key6"), []byte("value6"))
	expectedHashBucket4_1 := testutil.ComputeCryptoHash(expectedHashBucket5_1, expectedHashBucket5_2)
	expectedHashBucket4_13 := testutil.ComputeCryptoHash(expectedHashBucket5_25, expectedHashBucket5_26)
	expectedHashBucket2_1 := testutil.ComputeCryptoHash(expectedHashBucket4_1, expectedHashBucket5_6)
	expectedHashBucket1_1 := testutil.ComputeCryptoHash(expectedHashBucket2_1, expectedHashBucket5_10)
	expectedHash := testutil.ComputeCryptoHash(expectedHashBucket1_1, expectedHashBucket4_13)
	testutil.AssertEquals(t, rootHash, expectedHash)

	//////////////	Test - Add a few more keys (include keys in the existing buckes and new buckets) /////////////////////
	stateDelta = statemgmt.NewStateDelta()
	testHasher.populate("chaincodeID7", "key7", 1)
	testHasher.populate("chaincodeID8", "key8", 7)
	testHasher.populate("chaincodeID9", "key9", 9)
	testHasher.populate("chaincodeID10", "key10", 20)

	stateDelta.Set("chaincodeID7", "key7", []byte("value7"), nil)
	stateDelta.Set("chaincodeID8", "key8", []byte("value8"), nil)
	stateDelta.Set("chaincodeID9", "key9", []byte("value9"), nil)
	stateDelta.Set("chaincodeID10", "key10", []byte("value10"), nil)

	/*************************** bucket-tree-structure after adding keys ***************
	1		1		1	1	1	1
	2		1		1	1	1	1
	6		3		2	1	1	1
	8		4		2	1	1	1
	10	5		3	2	1	1
	21	11	6	3	2	1
	25	13	7	4	2	1
	26	13	7	4	2	1
	***********************************************************************************/
	rootHash = stateImplTestWrapper.prepareWorkingSetAndComputeCryptoHash(stateDelta)
	expectedHashBucket5_2 = testutil.ComputeCryptoHash(statemgmt.ConstructCompositeKey("chaincodeID2", "key2"), []byte("value2"),
		statemgmt.ConstructCompositeKey("chaincodeID7", "key7"), []byte("value7"))
	expectedHashBucket5_8 := testutil.ComputeCryptoHash(statemgmt.ConstructCompositeKey("chaincodeID8", "key8"), []byte("value8"))
	expectedHashBucket5_10 = testutil.ComputeCryptoHash(statemgmt.ConstructCompositeKey("chaincodeID4", "key4"), []byte("value4"),
		statemgmt.ConstructCompositeKey("chaincodeID9", "key9"), []byte("value9"))
	expectedHashBucket5_21 := testutil.ComputeCryptoHash(statemgmt.ConstructCompositeKey("chaincodeID10", "key10"), []byte("value10"))
	expectedHashBucket4_1 = testutil.ComputeCryptoHash(expectedHashBucket5_1, expectedHashBucket5_2)
	expectedHashBucket3_2 := testutil.ComputeCryptoHash(expectedHashBucket5_6, expectedHashBucket5_8)
	expectedHashBucket2_1 = testutil.ComputeCryptoHash(expectedHashBucket4_1, expectedHashBucket3_2)

	expectedHashBucket1_1 = testutil.ComputeCryptoHash(expectedHashBucket2_1, expectedHashBucket5_10)
	expectedHashBucket1_2 := testutil.ComputeCryptoHash(expectedHashBucket5_21, expectedHashBucket4_13)
	expectedHash = testutil.ComputeCryptoHash(expectedHashBucket1_1, expectedHashBucket1_2)
	testutil.AssertEquals(t, rootHash, expectedHash)
	stateImplTestWrapper.persistChangesAndResetInMemoryChanges()

	//////////////	Test - overwrite an existing key /////////////////////
	stateDelta = statemgmt.NewStateDelta()
	stateDelta.Set("chaincodeID7", "key7", []byte("value7_new"), nil)
	rootHash = stateImplTestWrapper.prepareWorkingSetAndComputeCryptoHash(stateDelta)
	expectedHashBucket5_2 = testutil.ComputeCryptoHash(statemgmt.ConstructCompositeKey("chaincodeID2", "key2"), []byte("value2"),
		statemgmt.ConstructCompositeKey("chaincodeID7", "key7"), []byte("value7_new"))
	expectedHashBucket4_1 = testutil.ComputeCryptoHash(expectedHashBucket5_1, expectedHashBucket5_2)
	expectedHashBucket2_1 = testutil.ComputeCryptoHash(expectedHashBucket4_1, expectedHashBucket3_2)
	expectedHashBucket1_1 = testutil.ComputeCryptoHash(expectedHashBucket2_1, expectedHashBucket5_10)
	expectedHash = testutil.ComputeCryptoHash(expectedHashBucket1_1, expectedHashBucket1_2)
	testutil.AssertEquals(t, rootHash, expectedHash)
	stateImplTestWrapper.persistChangesAndResetInMemoryChanges()
	testutil.AssertEquals(t, stateImplTestWrapper.get("chaincodeID7", "key7"), []byte("value7_new"))

	//////////////	Test - delete an existing key /////////////////////
	stateDelta = statemgmt.NewStateDelta()
	stateDelta.Delete("chaincodeID2", "key2", nil)
	rootHash = stateImplTestWrapper.prepareWorkingSetAndComputeCryptoHash(stateDelta)
	expectedHashBucket5_2 = testutil.ComputeCryptoHash(statemgmt.ConstructCompositeKey("chaincodeID7", "key7"), []byte("value7_new"))
	expectedHashBucket4_1 = testutil.ComputeCryptoHash(expectedHashBucket5_1, expectedHashBucket5_2)
	expectedHashBucket2_1 = testutil.ComputeCryptoHash(expectedHashBucket4_1, expectedHashBucket3_2)
	expectedHashBucket1_1 = testutil.ComputeCryptoHash(expectedHashBucket2_1, expectedHashBucket5_10)
	expectedHash = testutil.ComputeCryptoHash(expectedHashBucket1_1, expectedHashBucket1_2)
	testutil.AssertEquals(t, rootHash, expectedHash)
	stateImplTestWrapper.persistChangesAndResetInMemoryChanges()
	testutil.AssertNil(t, stateImplTestWrapper.get("chaincodeID2", "key2"))
}