Beispiel #1
0
// NewState constructs a new State. This Initializes encapsulated state implementation
func NewState() *State {
	stateImplName := viper.GetString("ledger.state.dataStructure")
	if len(stateImplName) == 0 {
		stateImplName = detaultStateImpl
	}

	switch stateImplName {
	case "buckettree":
		stateImpl = buckettree.NewStateImpl()
	case "trie":
		stateImpl = trie.NewStateTrie()
	default:
		panic(fmt.Errorf("Error during initialization of state implementation. State data structure '%s' is not valid.", stateImplName))
	}

	err := stateImpl.Initialize()
	if err != nil {
		panic(fmt.Errorf("Error during initialization of state implementation: %s", err))
	}
	deltaHistorySize := viper.GetInt("ledger.state.deltaHistorySize")
	if deltaHistorySize < 0 {
		panic(fmt.Errorf("Delta history size must be greater than or equal to 0. Current value is %d.", deltaHistorySize))
	}
	return &State{stateImpl, statemgmt.NewStateDelta(), statemgmt.NewStateDelta(), "", make(map[string][]byte),
		false, uint64(deltaHistorySize)}
}
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 TestStateTrie_ComputeHash_AllInMemory_NoContents(t *testing.T) {
	testDBWrapper.CreateFreshDB(t)
	stateTrie := NewStateTrie()
	stateTrieTestWrapper := &stateTrieTestWrapper{stateTrie, t}
	hash := stateTrieTestWrapper.PrepareWorkingSetAndComputeCryptoHash(statemgmt.NewStateDelta())
	testutil.AssertEquals(t, hash, nil)
}
Beispiel #4
0
func createFreshDBAndInitTestStateImplWithCustomHasher(t *testing.T, numBuckets int, maxGroupingAtEachLevel int) (*testHasher, *stateImplTestWrapper, *statemgmt.StateDelta) {
	testDBWrapper.CreateFreshDB(t)
	testHasher := newTestHasher()
	stateImplTestWrapper := newStateImplTestWrapper(t)
	stateDelta := statemgmt.NewStateDelta()
	conf = initConfig(numBuckets, maxGroupingAtEachLevel, testHasher.getHashFunction())
	return testHasher, stateImplTestWrapper, stateDelta
}
Beispiel #5
0
// FetchStateDeltaFromDB fetches the StateDelta corrsponding to given blockNumber
func (state *State) FetchStateDeltaFromDB(blockNumber uint64) (*statemgmt.StateDelta, error) {
	stateDeltaBytes, err := db.GetDBHandle().GetFromStateDeltaCF(encodeStateDeltaKey(blockNumber))
	if err != nil {
		return nil, err
	}
	if stateDeltaBytes == nil {
		return nil, nil
	}
	stateDelta := statemgmt.NewStateDelta()
	stateDelta.Unmarshal(stateDeltaBytes)
	return stateDelta, nil
}
func TestStateTrie_GetSet_WithDB(t *testing.T) {
	testDBWrapper.CreateFreshDB(t)
	stateTrie := NewStateTrie()
	stateTrieTestWrapper := &stateTrieTestWrapper{stateTrie, t}
	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)
	stateTrieTestWrapper.PrepareWorkingSetAndComputeCryptoHash(stateDelta)
	stateTrieTestWrapper.PersistChangesAndResetInMemoryChanges()
	testutil.AssertEquals(t, stateTrieTestWrapper.Get("chaincodeID1", "key1"), []byte("value1"))
}
Beispiel #7
0
// sendBlocks sends the blocks based upon the supplied SyncBlockRange over the stream.
func (d *Handler) sendStateSnapshot(syncStateSnapshotRequest *pb.SyncStateSnapshotRequest) {
	peerLogger.Debug("Sending state snapshot with correlationId = %d", syncStateSnapshotRequest.CorrelationId)

	snapshot, err := d.Coordinator.GetStateSnapshot()
	if err != nil {
		peerLogger.Error(fmt.Sprintf("Error getting snapshot: %s", err))
		return
	}
	defer snapshot.Release()

	// Iterate over the state deltas and send to requestor
	delta := statemgmt.NewStateDelta()
	currBlockNumber := snapshot.GetBlockNumber()
	var sequence uint64
	// Loop through and send the Deltas
	for i := 0; snapshot.Next(); i++ {
		k, v := snapshot.GetRawKeyValue()
		cID, kID := statemgmt.DecodeCompositeKey(k)
		delta.Set(cID, kID, v, nil)

		deltaAsBytes := delta.Marshal()
		// Encode a SyncStateSnapsot into the payload
		sequence = uint64(i)
		syncStateSnapshot := &pb.SyncStateSnapshot{Delta: deltaAsBytes, Sequence: sequence, BlockNumber: currBlockNumber, Request: syncStateSnapshotRequest}

		syncStateSnapshotBytes, err := proto.Marshal(syncStateSnapshot)
		if err != nil {
			peerLogger.Error(fmt.Sprintf("Error marshalling syncStateSnapsot for BlockNum = %d: %s", currBlockNumber, err))
			break
		}
		if err := d.SendMessage(&pb.OpenchainMessage{Type: pb.OpenchainMessage_SYNC_STATE_SNAPSHOT, Payload: syncStateSnapshotBytes}); err != nil {
			peerLogger.Error(fmt.Sprintf("Error sending syncStateSnapsot for BlockNum = %d: %s", currBlockNumber, err))
			break
		}
	}

	// Now send the terminating message
	syncStateSnapshot := &pb.SyncStateSnapshot{Delta: []byte{}, Sequence: sequence + 1, BlockNumber: currBlockNumber, Request: syncStateSnapshotRequest}
	syncStateSnapshotBytes, err := proto.Marshal(syncStateSnapshot)
	if err != nil {
		peerLogger.Error(fmt.Sprintf("Error marshalling terminating syncStateSnapsot message for correlationId = %d, BlockNum = %d: %s", syncStateSnapshotRequest.CorrelationId, currBlockNumber, err))
		return
	}
	if err := d.SendMessage(&pb.OpenchainMessage{Type: pb.OpenchainMessage_SYNC_STATE_SNAPSHOT, Payload: syncStateSnapshotBytes}); err != nil {
		peerLogger.Error(fmt.Sprintf("Error sending terminating syncStateSnapsot for correlationId = %d, BlockNum = %d: %s", syncStateSnapshotRequest.CorrelationId, currBlockNumber, err))
		return
	}

}
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)
}
Beispiel #9
0
func createFreshDBAndInitTestStateImplWithCustomHasher(t *testing.T, numBuckets int, maxGroupingAtEachLevel int) (*testHasher, *stateImplTestWrapper, *statemgmt.StateDelta) {
	testHasher := newTestHasher()
	configMap := map[string]interface{}{
		ConfigNumBuckets:             numBuckets,
		ConfigMaxGroupingAtEachLevel: maxGroupingAtEachLevel,
		ConfigHashFunction:           testHasher.getHashFunction(),
	}

	testDBWrapper.CreateFreshDB(t)
	stateImpl := NewStateImpl()
	stateImpl.Initialize(configMap)
	stateImplTestWrapper := &stateImplTestWrapper{configMap, stateImpl, t}
	stateDelta := statemgmt.NewStateDelta()
	return testHasher, stateImplTestWrapper, stateDelta
}
func TestDataNodesDelta(t *testing.T) {
	conf = initConfig(26, 3, fnvHash)
	stateDelta := statemgmt.NewStateDelta()
	stateDelta.Set("chaincodeID1", "key1", []byte("value1_1"), nil)
	stateDelta.Set("chaincodeID1", "key2", []byte("value1_2"), nil)
	stateDelta.Set("chaincodeID2", "key1", []byte("value2_1"), nil)
	stateDelta.Set("chaincodeID2", "key2", []byte("value2_2"), nil)

	dataNodesDelta := newDataNodesDelta(stateDelta)
	affectedBuckets := dataNodesDelta.getAffectedBuckets()
	testutil.AssertContains(t, affectedBuckets, newDataKey("chaincodeID1", "key1").getBucketKey())
	testutil.AssertContains(t, affectedBuckets, newDataKey("chaincodeID1", "key2").getBucketKey())
	testutil.AssertContains(t, affectedBuckets, newDataKey("chaincodeID2", "key1").getBucketKey())
	testutil.AssertContains(t, affectedBuckets, newDataKey("chaincodeID2", "key2").getBucketKey())

}
Beispiel #11
0
// TxFinish marks the completion of on-going tx. If txUUID is not same as of the on-going tx, this call panics
func (state *State) TxFinish(txUUID string, txSuccessful bool) {
	logger.Debug("txFinish() for txUuid [%s], txSuccessful=[%t]", txUUID, txSuccessful)
	if state.currentTxUUID != txUUID {
		panic(fmt.Errorf("Different Uuid in tx-begin [%s] and tx-finish [%s]", state.currentTxUUID, txUUID))
	}
	if txSuccessful {
		if !state.currentTxStateDelta.IsEmpty() {
			logger.Debug("txFinish() for txUuid [%s] merging state changes", txUUID)
			state.stateDelta.ApplyChanges(state.currentTxStateDelta)
			state.txStateDeltaHash[txUUID] = state.currentTxStateDelta.ComputeCryptoHash()
			state.updateStateImpl = true
		} else {
			state.txStateDeltaHash[txUUID] = nil
		}
	}
	state.currentTxStateDelta = statemgmt.NewStateDelta()
	state.currentTxUUID = ""
}
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 TestStateTrie_ComputeHash_AllInMemory(t *testing.T) {
	testDBWrapper.CreateFreshDB(t)
	stateTrie := NewStateTrie()
	stateTrieTestWrapper := &stateTrieTestWrapper{stateTrie, t}
	stateDelta := statemgmt.NewStateDelta()

	// Test1 - Add a few keys
	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)
	rootHash1 := stateTrieTestWrapper.PrepareWorkingSetAndComputeCryptoHash(stateDelta)

	hash1 := computeTestHash(newTrieKey("chaincodeID1", "key1").getEncodedBytes(), []byte("value1"))
	hash2 := computeTestHash(newTrieKey("chaincodeID1", "key2").getEncodedBytes(), []byte("value2"))
	hash3 := computeTestHash(newTrieKey("chaincodeID2", "key3").getEncodedBytes(), []byte("value3"))
	hash4 := computeTestHash(newTrieKey("chaincodeID2", "key4").getEncodedBytes(), []byte("value4"))

	hash1_hash2 := computeTestHash(hash1, hash2)
	hash3_hash4 := computeTestHash(hash3, hash4)
	expectedRootHash1 := computeTestHash(hash1_hash2, hash3_hash4)
	testutil.AssertEquals(t, rootHash1, expectedRootHash1)
	stateTrie.ClearWorkingSet(true)

	// Test2 - Add one more key
	fmt.Println("\n-- Add one more key exiting key --- ")
	stateDelta.Set("chaincodeID3", "key5", []byte("value5"), nil)
	rootHash2 := stateTrieTestWrapper.PrepareWorkingSetAndComputeCryptoHash(stateDelta)
	hash5 := computeTestHash(newTrieKey("chaincodeID3", "key5").getEncodedBytes(), []byte("value5"))
	expectedRootHash2 := computeTestHash(hash1_hash2, hash3_hash4, hash5)
	testutil.AssertEquals(t, rootHash2, expectedRootHash2)
	stateTrie.ClearWorkingSet(true)

	// Test3 - Remove one of the existing keys
	fmt.Println("\n-- Remove an exiting key --- ")
	stateDelta.Delete("chaincodeID2", "key4", nil)
	rootHash3 := stateTrieTestWrapper.PrepareWorkingSetAndComputeCryptoHash(stateDelta)
	expectedRootHash3 := computeTestHash(hash1_hash2, hash3, hash5)
	testutil.AssertEquals(t, rootHash3, expectedRootHash3)
	stateTrie.ClearWorkingSet(true)
}
func TestStateTrie_ComputeHash_WithDB_Staggered_Keys(t *testing.T) {
	testDBWrapper.CreateFreshDB(t)
	stateTrie := NewStateTrie()
	stateTrieTestWrapper := &stateTrieTestWrapper{stateTrie, t}

	/////////////////////////////////////////////////////////
	// Test1 - Add a few staggered keys
	/////////////////////////////////////////////////////////
	stateDelta := statemgmt.NewStateDelta()
	stateDelta.Set("ID", "key1", []byte("value_key1"), nil)
	stateDelta.Set("ID", "key", []byte("value_key"), nil)
	stateDelta.Set("ID", "k", []byte("value_k"), nil)
	expectedHash_key1 := computeTestHash(newTrieKey("ID", "key1").getEncodedBytes(), []byte("value_key1"))
	expectedHash_key := computeTestHash(newTrieKey("ID", "key").getEncodedBytes(), []byte("value_key"), expectedHash_key1)
	expectedHash_k := computeTestHash(newTrieKey("ID", "k").getEncodedBytes(), []byte("value_k"), expectedHash_key)
	rootHash1 := stateTrieTestWrapper.PrepareWorkingSetAndComputeCryptoHash(stateDelta)
	testutil.AssertEquals(t, rootHash1, expectedHash_k)
	stateTrieTestWrapper.PersistChangesAndResetInMemoryChanges()

	/////////////////////////////////////////////////////////
	// Test2 - Add a new key in path of existing staggered keys
	/////////////////////////////////////////////////////////
	fmt.Println("- Add a new key in path of existing staggered keys -")
	stateDelta = statemgmt.NewStateDelta()
	stateDelta.Set("ID", "ke", []byte("value_ke"), nil)
	expectedHash_ke := computeTestHash(newTrieKey("ID", "ke").getEncodedBytes(), []byte("value_ke"), expectedHash_key)
	expectedHash_k = computeTestHash(newTrieKey("ID", "k").getEncodedBytes(), []byte("value_k"), expectedHash_ke)
	rootHash2 := stateTrieTestWrapper.PrepareWorkingSetAndComputeCryptoHash(stateDelta)
	testutil.AssertEquals(t, rootHash2, expectedHash_k)
	stateTrieTestWrapper.PersistChangesAndResetInMemoryChanges()

	/////////////////////////////////////////////////////////
	// Test3 - Change value of one of the existing keys
	/////////////////////////////////////////////////////////
	stateDelta = statemgmt.NewStateDelta()
	stateDelta.Set("ID", "ke", []byte("value_ke_new"), nil)
	expectedHash_ke = computeTestHash(newTrieKey("ID", "ke").getEncodedBytes(), []byte("value_ke_new"), expectedHash_key)
	expectedHash_k = computeTestHash(newTrieKey("ID", "k").getEncodedBytes(), []byte("value_k"), expectedHash_ke)
	rootHash3 := stateTrieTestWrapper.PrepareWorkingSetAndComputeCryptoHash(stateDelta)
	testutil.AssertEquals(t, rootHash3, expectedHash_k)
	stateTrieTestWrapper.PersistChangesAndResetInMemoryChanges()

	/////////////////////////////////////////////////////////
	// Test4 - delete one of the existing keys
	/////////////////////////////////////////////////////////
	stateDelta = statemgmt.NewStateDelta()
	stateDelta.Delete("ID", "ke", nil)
	expectedHash_k = computeTestHash(newTrieKey("ID", "k").getEncodedBytes(), []byte("value_k"), expectedHash_key)
	rootHash4 := stateTrieTestWrapper.PrepareWorkingSetAndComputeCryptoHash(stateDelta)
	testutil.AssertEquals(t, rootHash4, expectedHash_k)
	stateTrieTestWrapper.PersistChangesAndResetInMemoryChanges()
	// Delete should not remove the key from db because, this key has children
	testutil.AssertNotNil(t, testDBWrapper.GetFromStateCF(t, newTrieKey("ID", "ke").getEncodedBytes()))
	testutil.AssertEquals(t, rootHash1, rootHash4)

	//////////////////////////////////////////////////////////////
	// Test4 -  Add one more key as a sibling of an intermediate node
	//////////////////////////////////////////////////////////////
	stateDelta = statemgmt.NewStateDelta()
	stateDelta.Set("ID", "kez", []byte("value_kez"), nil)
	expectedHash_kez := computeTestHash(newTrieKey("ID", "kez").getEncodedBytes(), []byte("value_kez"))
	expectedHash_ke = computeTestHash(expectedHash_key, expectedHash_kez)
	expectedHash_k = computeTestHash(newTrieKey("ID", "k").getEncodedBytes(), []byte("value_k"), expectedHash_ke)
	rootHash5 := stateTrieTestWrapper.PrepareWorkingSetAndComputeCryptoHash(stateDelta)
	testutil.AssertEquals(t, rootHash5, expectedHash_k)
}
Beispiel #15
0
func TestLedgerSetRawState(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"))

	// Ensure values are in the DB
	val := ledgerTestWrapper.GetState("chaincode1", "key1", true)
	if bytes.Compare(val, []byte("value1")) != 0 {
		t.Fatalf("Expected initial chaincode1 key1 to be %s, but got %s", []byte("value1"), val)
	}
	val = ledgerTestWrapper.GetState("chaincode2", "key2", true)
	if bytes.Compare(val, []byte("value2")) != 0 {
		t.Fatalf("Expected initial chaincode1 key2 to be %s, but got %s", []byte("value2"), val)
	}
	val = ledgerTestWrapper.GetState("chaincode3", "key3", true)
	if bytes.Compare(val, []byte("value3")) != 0 {
		t.Fatalf("Expected initial chaincode1 key3 to be %s, but got %s", []byte("value3"), val)
	}

	hash1, hash1Err := ledger.GetTempStateHash()
	if hash1Err != nil {
		t.Fatalf("Error getting hash1 %s", hash1Err)
	}

	snapshot, snapshotError := ledger.GetStateSnapshot()
	if snapshotError != nil {
		t.Fatalf("Error fetching snapshot %s", snapshotError)
	}
	defer snapshot.Release()

	// Delete keys
	ledger.BeginTxBatch(2)
	ledger.TxBegin("txUuid2")
	ledger.DeleteState("chaincode1", "key1")
	ledger.DeleteState("chaincode2", "key2")
	ledger.DeleteState("chaincode3", "key3")
	ledger.TxFinished("txUuid2", true)
	transaction, _ = buildTestTx(t)
	ledger.CommitTxBatch(2, []*protos.Transaction{transaction}, nil, []byte("proof"))

	// ensure keys are deleted
	val = ledgerTestWrapper.GetState("chaincode1", "key1", true)
	if val != nil {
		t.Fatalf("Expected chaincode1 key1 to be nil, but got %s", val)
	}
	val = ledgerTestWrapper.GetState("chaincode2", "key2", true)
	if val != nil {
		t.Fatalf("Expected chaincode2 key2 to be nil, but got %s", val)
	}
	val = ledgerTestWrapper.GetState("chaincode3", "key3", true)
	if val != nil {
		t.Fatalf("Expected chaincode3 key3 to be nil, but got %s", val)
	}

	hash2, hash2Err := ledger.GetTempStateHash()
	if hash2Err != nil {
		t.Fatalf("Error getting hash2 %s", hash2Err)
	}

	if bytes.Compare(hash1, hash2) == 0 {
		t.Fatalf("Expected hashes to not match, but they both equal %s", hash1)
	}

	// put key/values from the snapshot back in the DB
	//var keys, values [][]byte
	delta := statemgmt.NewStateDelta()
	for i := 0; snapshot.Next(); i++ {
		k, v := snapshot.GetRawKeyValue()
		cID, keyID := statemgmt.DecodeCompositeKey(k)
		delta.Set(cID, keyID, v, nil)
	}

	ledgerTestWrapper.ApplyStateDelta(1, delta)
	ledgerTestWrapper.CommitStateDelta(1)

	// Ensure values are back in the DB
	val = ledgerTestWrapper.GetState("chaincode1", "key1", true)
	if bytes.Compare(val, []byte("value1")) != 0 {
		t.Fatalf("Expected chaincode1 key1 to be %s, but got %s", []byte("value1"), val)
	}
	val = ledgerTestWrapper.GetState("chaincode2", "key2", true)
	if bytes.Compare(val, []byte("value2")) != 0 {
		t.Fatalf("Expected chaincode1 key2 to be %s, but got %s", []byte("value2"), val)
	}
	val = ledgerTestWrapper.GetState("chaincode3", "key3", true)
	if bytes.Compare(val, []byte("value3")) != 0 {
		t.Fatalf("Expected chaincode1 key3 to be %s, but got %s", []byte("value3"), val)
	}

	hash3, hash3Err := ledger.GetTempStateHash()
	if hash3Err != nil {
		t.Fatalf("Error getting hash3 %s", hash3Err)
	}
	if bytes.Compare(hash1, hash3) != 0 {
		t.Fatalf("Expected hashes to be equal, but they are %s and %s", hash1, hash3)
	}
}
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"))
}
func TestStateImpl_ComputeHash_AllInMemory_NoContents(t *testing.T) {
	testDBWrapper.CreateFreshDB(t)
	stateImplTestWrapper := newStateImplTestWrapper(t)
	hash := stateImplTestWrapper.prepareWorkingSetAndComputeCryptoHash(statemgmt.NewStateDelta())
	testutil.AssertEquals(t, hash, nil)
}
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()))
}
Beispiel #19
0
// ClearInMemoryChanges remove from memory all the changes to state
func (state *State) ClearInMemoryChanges(changesPersisted bool) {
	state.stateDelta = statemgmt.NewStateDelta()
	state.txStateDeltaHash = make(map[string][]byte)
	state.stateImpl.ClearWorkingSet(changesPersisted)
}
func TestRangeScanIterator(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", "key1", []byte("value1"), nil)
	stateDelta.Set("chaincodeID2", "key2", []byte("value2"), nil)
	stateDelta.Set("chaincodeID2", "key3", []byte("value3"), nil)
	stateDelta.Set("chaincodeID2", "key4", []byte("value4"), nil)
	stateDelta.Set("chaincodeID2", "key5", []byte("value5"), nil)
	stateDelta.Set("chaincodeID2", "key6", []byte("value6"), nil)
	stateDelta.Set("chaincodeID2", "key7", []byte("value7"), nil)

	stateDelta.Set("chaincodeID3", "key1", []byte("value1"), nil)

	stateDelta.Set("chaincodeID4", "key1", []byte("value1"), nil)
	stateDelta.Set("chaincodeID4", "key2", []byte("value2"), nil)
	stateDelta.Set("chaincodeID4", "key3", []byte("value3"), nil)
	stateDelta.Set("chaincodeID4", "key4", []byte("value4"), nil)
	stateDelta.Set("chaincodeID4", "key5", []byte("value5"), nil)
	stateDelta.Set("chaincodeID4", "key6", []byte("value6"), nil)
	stateDelta.Set("chaincodeID4", "key7", []byte("value7"), nil)

	stateDelta.Set("chaincodeID5", "key1", []byte("value5"), nil)
	stateDelta.Set("chaincodeID6", "key1", []byte("value6"), nil)

	stateTrie.PrepareWorkingSet(stateDelta)
	stateTrieTestWrapper.PersistChangesAndResetInMemoryChanges()

	// test range scan for chaincodeID2
	rangeScanItr, _ := stateTrie.GetRangeScanIterator("chaincodeID2", "key2", "key5")

	var results = make(map[string][]byte)
	for rangeScanItr.Next() {
		key, value := rangeScanItr.GetKeyValue()
		results[key] = value
	}
	t.Logf("Results = %s", results)
	testutil.AssertEquals(t, len(results), 4)
	testutil.AssertEquals(t, results["key2"], []byte("value2"))
	testutil.AssertEquals(t, results["key3"], []byte("value3"))
	testutil.AssertEquals(t, results["key4"], []byte("value4"))
	testutil.AssertEquals(t, results["key5"], []byte("value5"))
	rangeScanItr.Close()

	// test range scan for chaincodeID4
	rangeScanItr, _ = stateTrie.GetRangeScanIterator("chaincodeID2", "key3", "key6")
	results = make(map[string][]byte)
	for rangeScanItr.Next() {
		key, value := rangeScanItr.GetKeyValue()
		results[key] = value
	}
	t.Logf("Results = %s", results)
	testutil.AssertEquals(t, len(results), 4)
	testutil.AssertEquals(t, results["key3"], []byte("value3"))
	testutil.AssertEquals(t, results["key4"], []byte("value4"))
	testutil.AssertEquals(t, results["key5"], []byte("value5"))
	testutil.AssertEquals(t, results["key6"], []byte("value6"))
	rangeScanItr.Close()

	// test range scan for chaincodeID2 starting from first key
	rangeScanItr, _ = stateTrie.GetRangeScanIterator("chaincodeID2", "", "key5")
	results = make(map[string][]byte)
	for rangeScanItr.Next() {
		key, value := rangeScanItr.GetKeyValue()
		results[key] = value
	}
	t.Logf("Results = %s", results)
	testutil.AssertEquals(t, len(results), 5)
	testutil.AssertEquals(t, results["key1"], []byte("value1"))
	testutil.AssertEquals(t, results["key2"], []byte("value2"))
	testutil.AssertEquals(t, results["key3"], []byte("value3"))
	testutil.AssertEquals(t, results["key4"], []byte("value4"))
	testutil.AssertEquals(t, results["key5"], []byte("value5"))
	rangeScanItr.Close()

	// test range scan for all the keys in chaincodeID2 starting from first key
	rangeScanItr, _ = stateTrie.GetRangeScanIterator("chaincodeID2", "", "")
	results = make(map[string][]byte)
	for rangeScanItr.Next() {
		key, value := rangeScanItr.GetKeyValue()
		results[key] = value
	}
	t.Logf("Results = %s", results)
	testutil.AssertEquals(t, len(results), 7)
	testutil.AssertEquals(t, results["key1"], []byte("value1"))
	testutil.AssertEquals(t, results["key2"], []byte("value2"))
	testutil.AssertEquals(t, results["key3"], []byte("value3"))
	testutil.AssertEquals(t, results["key4"], []byte("value4"))
	testutil.AssertEquals(t, results["key5"], []byte("value5"))
	testutil.AssertEquals(t, results["key6"], []byte("value6"))
	testutil.AssertEquals(t, results["key7"], []byte("value7"))
	rangeScanItr.Close()
}
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"))
}
Beispiel #22
0
func (testWrapper *stateTestWrapper) fetchStateDeltaFromDB(blockNumber uint64) *statemgmt.StateDelta {
	delta := statemgmt.NewStateDelta()
	delta.Unmarshal(testDBWrapper.GetFromStateDeltaCF(testWrapper.t, encodeStateDeltaKey(blockNumber)))
	return delta
}