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) }
// TestDeletes tests deteles func TestDeletes(t *testing.T, db statedb.VersionedDB) { db.Open() defer db.Close() batch := statedb.NewUpdateBatch() vv1 := statedb.VersionedValue{Value: []byte("value1"), Version: version.NewHeight(1, 1)} vv2 := statedb.VersionedValue{Value: []byte("value2"), Version: version.NewHeight(1, 2)} vv3 := statedb.VersionedValue{Value: []byte("value1"), Version: version.NewHeight(1, 3)} vv4 := statedb.VersionedValue{Value: []byte("value2"), Version: version.NewHeight(1, 4)} batch.Put("ns", "key1", vv1.Value, vv1.Version) batch.Put("ns", "key2", vv2.Value, vv2.Version) batch.Put("ns", "key3", vv2.Value, vv3.Version) batch.Put("ns", "key4", vv2.Value, vv4.Version) batch.Delete("ns", "key3", version.NewHeight(1, 5)) savePoint := version.NewHeight(1, 5) err := db.ApplyUpdates(batch, savePoint) testutil.AssertNoError(t, err, "") vv, _ := db.GetState("ns", "key2") testutil.AssertEquals(t, vv, &vv2) vv, err = db.GetState("ns", "key3") testutil.AssertNoError(t, err, "") testutil.AssertNil(t, vv) batch = statedb.NewUpdateBatch() batch.Delete("ns", "key2", version.NewHeight(1, 6)) err = db.ApplyUpdates(batch, savePoint) testutil.AssertNoError(t, err, "") vv, err = db.GetState("ns", "key2") testutil.AssertNoError(t, err, "") testutil.AssertNil(t, vv) }
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 testBlockStream(t *testing.T, numFiles int) { env := newTestEnv(t) defer env.Cleanup() w := newTestBlockfileWrapper(t, env) defer w.close() blockfileMgr := w.blockfileMgr numBlocksInEachFile := 10 bg := testutil.NewBlockGenerator(t) for i := 0; i < numFiles; i++ { blocks := bg.NextTestBlocks(numBlocksInEachFile) w.addBlocks(blocks) blockfileMgr.moveToNextFile() } s, err := newBlockStream(blockfileMgr.rootDir, 0, 0, numFiles-1) defer s.close() testutil.AssertNoError(t, err, "Error in constructing new block stream") blockCount := 0 for { blockBytes, err := s.nextBlockBytes() testutil.AssertNoError(t, err, "Error in getting next block") if blockBytes == nil { break } blockCount++ } // After the stream has been exhausted, both blockBytes and err should be nil blockBytes, err := s.nextBlockBytes() testutil.AssertNil(t, blockBytes) testutil.AssertNoError(t, err, "Error in getting next block after exhausting the file") testutil.AssertEquals(t, blockCount, numFiles*numBlocksInEachFile) }
func TestLedgerPutRawBlock(t *testing.T) { ledgerTestWrapper := createFreshDBAndTestLedgerWrapper(t) ledger := ledgerTestWrapper.ledger block := new(protos.Block) block.PreviousBlockHash = []byte("foo") block.StateHash = []byte("bar") ledger.PutRawBlock(block, 4) testutil.AssertEquals(t, ledgerTestWrapper.GetBlockByNumber(4), block) ledger.BeginTxBatch(1) ledger.TxBegin("txUuid") ledger.SetState("chaincode1", "key1", []byte("value1")) ledger.TxFinished("txUuid", true) transaction, _ := buildTestTx(t) ledger.CommitTxBatch(1, []*protos.Transaction{transaction}, nil, []byte("proof")) previousHash, _ := block.GetHash() newBlock := ledgerTestWrapper.GetBlockByNumber(5) if !bytes.Equal(newBlock.PreviousBlockHash, previousHash) { t.Fatalf("Expected new block to properly set its previous hash") } // Assert that a non-existent block is nil testutil.AssertNil(t, ledgerTestWrapper.GetBlockByNumber(2)) }
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)) }
// TestBasicRW tests basic read-write func TestBasicRW(t *testing.T, db statedb.VersionedDB) { db.Open() defer db.Close() val, err := db.GetState("ns", "key1") testutil.AssertNoError(t, err, "") testutil.AssertNil(t, val) batch := statedb.NewUpdateBatch() vv1 := statedb.VersionedValue{Value: []byte("value1"), Version: version.NewHeight(1, 1)} vv2 := statedb.VersionedValue{Value: []byte("value2"), Version: version.NewHeight(1, 2)} vv3 := statedb.VersionedValue{Value: []byte("value3"), Version: version.NewHeight(1, 3)} vv4 := statedb.VersionedValue{Value: []byte{}, Version: version.NewHeight(1, 4)} batch.Put("ns1", "key1", vv1.Value, vv1.Version) batch.Put("ns1", "key2", vv2.Value, vv2.Version) batch.Put("ns2", "key3", vv3.Value, vv3.Version) batch.Put("ns2", "key4", vv4.Value, vv4.Version) savePoint := version.NewHeight(2, 5) db.ApplyUpdates(batch, savePoint) vv, _ := db.GetState("ns1", "key1") testutil.AssertEquals(t, vv, &vv1) vv, _ = db.GetState("ns2", "key4") testutil.AssertEquals(t, vv, &vv4) sp, err := db.GetLatestSavePoint() testutil.AssertNoError(t, err, "") testutil.AssertEquals(t, sp, savePoint) }
func TestBlockChain_SimpleChain(t *testing.T) { testDBWrapper.CleanDB(t) blockchainTestWrapper := newTestBlockchainWrapper(t) blockchain := blockchainTestWrapper.blockchain allBlocks, allStateHashes, err := blockchainTestWrapper.populateBlockChainWithSampleData() if err != nil { t.Logf("Error populating block chain with sample data: %s", err) t.Fail() } 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++ } }
func testBlockfileStream(t *testing.T, numBlocks int) { env := newTestEnv(t) defer env.Cleanup() w := newTestBlockfileWrapper(t, env) blockfileMgr := w.blockfileMgr blocks := testutil.ConstructTestBlocks(t, numBlocks) w.addBlocks(blocks) w.close() s, err := newBlockfileStream(blockfileMgr.rootDir, 0, 0) defer s.close() testutil.AssertNoError(t, err, "Error in constructing blockfile stream") blockCount := 0 for { blockBytes, err := s.nextBlockBytes() testutil.AssertNoError(t, err, "Error in getting next block") if blockBytes == nil { break } blockCount++ } // After the stream has been exhausted, both blockBytes and err should be nil blockBytes, err := s.nextBlockBytes() testutil.AssertNil(t, blockBytes) testutil.AssertNoError(t, err, "Error in getting next block after exhausting the file") testutil.AssertEquals(t, blockCount, numBlocks) }
func testTxSimulatorWithNoExistingData(t *testing.T, env testEnv) { txMgr := env.getTxMgr() s, _ := txMgr.NewTxSimulator() value, err := s.GetState("ns1", "key1") testutil.AssertNoError(t, err, fmt.Sprintf("Error in GetState(): %s", err)) testutil.AssertNil(t, value) s.SetState("ns1", "key1", []byte("value1")) s.SetState("ns1", "key2", []byte("value2")) s.SetState("ns2", "key3", []byte("value3")) s.SetState("ns2", "key4", []byte("value4")) value, _ = s.GetState("ns2", "key3") testutil.AssertEquals(t, value, []byte("value3")) s.DeleteState("ns2", "key3") value, _ = s.GetState("ns2", "key3") testutil.AssertNil(t, value) }
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")) }
func testItr(t *testing.T, itr statedb.ResultsIterator, expectedKeys []string) { defer itr.Close() for _, expectedKey := range expectedKeys { vkv, _ := itr.Next() key := vkv.Key testutil.AssertEquals(t, key, expectedKey) } last, err := itr.Next() testutil.AssertNoError(t, err, "") testutil.AssertNil(t, last) }
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")) }
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)) }
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")) }
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"))) }
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")) }
func TestStateSnapshotIterator(t *testing.T) { testDBWrapper.CleanDB(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) }
func testBlockFileStreamUnexpectedEOF(t *testing.T, numBlocks int, partialBlockBytes []byte) { env := newTestEnv(t) defer env.Cleanup() w := newTestBlockfileWrapper(t, env) blockfileMgr := w.blockfileMgr blocks := testutil.ConstructTestBlocks(t, numBlocks) w.addBlocks(blocks) blockfileMgr.currentFileWriter.append(partialBlockBytes, true) w.close() s, err := newBlockfileStream(blockfileMgr.rootDir, 0, 0) defer s.close() testutil.AssertNoError(t, err, "Error in constructing blockfile stream") for i := 0; i < numBlocks; i++ { blockBytes, err := s.nextBlockBytes() testutil.AssertNotNil(t, blockBytes) testutil.AssertNoError(t, err, "Error in getting next block") } blockBytes, err := s.nextBlockBytes() testutil.AssertNil(t, blockBytes) testutil.AssertSame(t, err, ErrUnexpectedEndOfBlockfile) }
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) }
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) }
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") } }
func TestStateImpl_ComputeHash_DB_3(t *testing.T) { // simple test... not using custom hasher conf = newConfig(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) }
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 }
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 := expectedBucketHashForTest( []string{"chaincodeID2", "key2", "value2"}, []string{"chaincodeID3", "key3", "value3"}, []string{"chaincodeID5", "key5", "value5"}, []string{"chaincodeID6", "key6", "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 := expectedBucketHashForTest( []string{"chaincodeID2", "key2", "value2_new"}, []string{"chaincodeID3", "key3", "value3_new"}, []string{"chaincodeID5", "key5", "value5"}, []string{"chaincodeID6", "key6", "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 := expectedBucketHashForTest( []string{"chaincodeID1", "key1", "value1"}, []string{"chaincodeID2", "key2", "value2_new"}, []string{"chaincodeID3", "key3", "value3_new"}, []string{"chaincodeID4", "key4", "value4"}, []string{"chaincodeID5", "key5", "value5"}, []string{"chaincodeID6", "key6", "value6_new"}, []string{"chaincodeID7", "key7", "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")) }
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 := expectedBucketHashForTest([]string{"chaincodeID1", "key1", "value1"}) expectedHashBucket5_2 := expectedBucketHashForTest([]string{"chaincodeID2", "key2", "value2"}) expectedHashBucket5_6 := expectedBucketHashForTest([]string{"chaincodeID3", "key3", "value3"}) expectedHashBucket5_10 := expectedBucketHashForTest([]string{"chaincodeID4", "key4", "value4"}) expectedHashBucket5_25 := expectedBucketHashForTest([]string{"chaincodeID5", "key5", "value5"}) expectedHashBucket5_26 := expectedBucketHashForTest([]string{"chaincodeID6", "key6", "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 = expectedBucketHashForTest( []string{"chaincodeID2", "key2", "value2"}, []string{"chaincodeID7", "key7", "value7"}, ) expectedHashBucket5_8 := expectedBucketHashForTest([]string{"chaincodeID8", "key8", "value8"}) expectedHashBucket5_10 = expectedBucketHashForTest([]string{"chaincodeID4", "key4", "value4"}, []string{"chaincodeID9", "key9", "value9"}) expectedHashBucket5_21 := expectedBucketHashForTest([]string{"chaincodeID10", "key10", "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 = expectedBucketHashForTest( []string{"chaincodeID2", "key2", "value2"}, []string{"chaincodeID7", "key7", "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 = expectedBucketHashForTest([]string{"chaincodeID7", "key7", "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")) }
func TestStateTrie_ComputeHash_WithDB_Spread_Keys(t *testing.T) { testDBWrapper.CleanDB(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) expectedHash1 := expectedCryptoHashForTest(newTrieKey("chaincodeID1", "key1"), []byte("value1")) expectedHash2 := expectedCryptoHashForTest(newTrieKey("chaincodeID1", "key2"), []byte("value2")) expectedHash3 := expectedCryptoHashForTest(newTrieKey("chaincodeID2", "key3"), []byte("value3")) expectedHash4 := expectedCryptoHashForTest(newTrieKey("chaincodeID2", "key4"), []byte("value4")) expectedHash1Hash2 := expectedCryptoHashForTest(nil, nil, expectedHash1, expectedHash2) expectedHash3Hash4 := expectedCryptoHashForTest(nil, nil, expectedHash3, expectedHash4) expectedHash5 := expectedCryptoHashForTest(newTrieKey("chaincodeID3", "key5"), []byte("value5")) expectedRootHash1 := expectedCryptoHashForTest(nil, nil, expectedHash1Hash2, expectedHash3Hash4, expectedHash5) 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) expectedHash4 = expectedCryptoHashForTest(newTrieKey("chaincodeID2", "key4"), []byte("value4-new")) expectedHash3Hash4 = expectedCryptoHashForTest(nil, nil, expectedHash3, expectedHash4) expectedRootHash2 := expectedCryptoHashForTest(nil, nil, expectedHash1Hash2, expectedHash3Hash4, expectedHash5) 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) expectedHash1 = expectedCryptoHashForTest(newTrieKey("chaincodeID1", "key1"), []byte("value1-new")) expectedHash1Hash2 = expectedCryptoHashForTest(nil, nil, expectedHash1, expectedHash2) expectedRootHash3 := expectedCryptoHashForTest(nil, nil, expectedHash1Hash2, expectedHash3Hash4, expectedHash5) testutil.AssertEquals(t, rootHash3, expectedRootHash3) stateTrieTestWrapper.PersistChangesAndResetInMemoryChanges() ///////////////////////////////////////////////////////// // Test4 - Delete an existing existing key ///////////////////////////////////////////////////////// t.Logf("-- Delete an existing key ---") stateDelta = statemgmt.NewStateDelta() stateDelta.Delete("chaincodeID3", "key5", nil) rootHash4 := stateTrieTestWrapper.PrepareWorkingSetAndComputeCryptoHash(stateDelta) expectedRootHash4 := expectedCryptoHashForTest(nil, nil, expectedHash1Hash2, expectedHash3Hash4) 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 := expectedCryptoHashForTest(nil, nil, expectedHash1Hash2, expectedHash3) testutil.AssertEquals(t, rootHash5, expectedRootHash5) stateTrieTestWrapper.PersistChangesAndResetInMemoryChanges() testutil.AssertNil(t, testDBWrapper.GetFromStateCF(t, newTrieKey("chaincodeID2", "key4").getEncodedBytes())) }
func buildTestTx(tb testing.TB) (*protos.Transaction, string) { uuid := util.GenerateUUID() tx, err := protos.NewTransaction(protos.ChaincodeID{Path: "testUrl"}, uuid, "anyfunction", []string{"param1, param2"}) testutil.AssertNil(tb, err) return tx, uuid }