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++ } }
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)) }
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 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.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) }
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 = 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) }
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")) }
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())) }
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 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 }
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")) }