예제 #1
0
// Next - see interface 'statemgmt.RangeScanIterator' for details
func (itr *RangeScanIterator) Next() bool {
	if itr.done {
		return false
	}
	for ; itr.dbItr.Valid(); itr.dbItr.Next() {

		// making a copy of key-value bytes because, underlying key bytes are reused by itr.
		// no need to free slices as iterator frees memory when closed.
		trieKeyBytes := statemgmt.Copy(itr.dbItr.Key().Data())
		trieNodeBytes := statemgmt.Copy(itr.dbItr.Value().Data())
		value := unmarshalTrieNodeValue(trieNodeBytes)
		if value == nil {
			continue
		}

		// found an actual key
		currentCompositeKey := trieKeyEncoderImpl.decodeTrieKeyBytes(statemgmt.Copy(trieKeyBytes))
		currentChaincodeID, currentKey := statemgmt.DecodeCompositeKey(currentCompositeKey)
		if currentChaincodeID == itr.chaincodeID && (itr.endKey == "" || currentKey <= itr.endKey) {
			itr.currentKey = currentKey
			itr.currentValue = value
			itr.dbItr.Next()
			return true
		}

		// retrieved all the keys in the given range
		break
	}
	itr.done = true
	return false
}
예제 #2
0
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)
}
예제 #3
0
// sendBlocks sends the blocks based upon the supplied SyncBlockRange over the stream.
func (d *Handler) sendStateSnapshot(syncStateSnapshotRequest *pb.SyncStateSnapshotRequest) {
	peerLogger.Debugf("Sending state snapshot with correlationId = %d", syncStateSnapshotRequest.CorrelationId)

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

	// Iterate over the state deltas and send to requestor
	currBlockNumber := snapshot.GetBlockNumber()
	var sequence uint64
	// Loop through and send the Deltas
	for i := 0; snapshot.Next(); i++ {
		delta := statemgmt.NewStateDelta()
		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.Errorf("Error marshalling syncStateSnapsot for BlockNum = %d: %s", currBlockNumber, err)
			break
		}
		if err := d.SendMessage(&pb.Message{Type: pb.Message_SYNC_STATE_SNAPSHOT, Payload: syncStateSnapshotBytes}); err != nil {
			peerLogger.Errorf("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.Errorf("Error marshalling terminating syncStateSnapsot message for correlationId = %d, BlockNum = %d: %s", syncStateSnapshotRequest.CorrelationId, currBlockNumber, err)
		return
	}
	if err := d.SendMessage(&pb.Message{Type: pb.Message_SYNC_STATE_SNAPSHOT, Payload: syncStateSnapshotBytes}); err != nil {
		peerLogger.Errorf("Error sending terminating syncStateSnapsot for correlationId = %d, BlockNum = %d: %s", syncStateSnapshotRequest.CorrelationId, currBlockNumber, err)
		return
	}

}
예제 #4
0
// Next - see interface 'statemgmt.RangeScanIterator' for details
func (itr *RangeScanIterator) Next() bool {
	if itr.done {
		return false
	}

	for itr.dbItr.Valid() {

		// making a copy of key-value bytes because, underlying key bytes are reused by itr.
		// no need to free slices as iterator frees memory when closed.
		keyBytes := statemgmt.Copy(itr.dbItr.Key().Data())
		valueBytes := statemgmt.Copy(itr.dbItr.Value().Data())

		dataNode := unmarshalDataNodeFromBytes(keyBytes, valueBytes)
		dataKey := dataNode.dataKey
		chaincodeID, key := statemgmt.DecodeCompositeKey(dataNode.getCompositeKey())
		value := dataNode.value
		logger.Debug("Evaluating data-key = %s", dataKey)

		bucketNumber := dataKey.bucketKey.bucketNumber
		if bucketNumber > itr.currentBucketNumber {
			itr.seekForStartKeyWithinBucket(bucketNumber)
			continue
		}

		if chaincodeID == itr.chaincodeID && (itr.endKey == "" || key <= itr.endKey) {
			logger.Debug("including data-key = %s", dataKey)
			itr.currentKey = key
			itr.currentValue = value
			itr.dbItr.Next()
			return true
		}

		itr.seekForStartKeyWithinBucket(bucketNumber + 1)
		continue
	}
	itr.done = true
	return false
}
예제 #5
0
			state, _ := ledgerPtr.GetState("chaincode1", "key1", true)
			Expect(state).To(BeNil())
			state, _ = ledgerPtr.GetState("chaincode2", "key2", true)
			Expect(state).To(BeNil())
			state, _ = ledgerPtr.GetState("chaincode3", "key3", true)
			Expect(state).To(BeNil())
			hash2, err = ledgerPtr.GetTempStateHash()
			Expect(err).To(BeNil())
			Expect(bytes.Compare(hash1, hash2)).ToNot(Equal(0))
			// 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)
			}
			ledgerPtr.ApplyStateDelta(1, delta)
			ledgerPtr.CommitStateDelta(1)
		})
		It("should return restored state", func() {
			state, _ := ledgerPtr.GetState("chaincode1", "key1", true)
			Expect(state).To(Equal([]byte("value1")))
			state, _ = ledgerPtr.GetState("chaincode2", "key2", true)
			Expect(state).To(Equal([]byte("value2")))
			state, _ = ledgerPtr.GetState("chaincode3", "key3", true)
			Expect(state).To(Equal([]byte("value3")))
		})
		It("should get state hash without error", func() {
			hash3, err = ledgerPtr.GetTempStateHash()
예제 #6
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)
	}
}
예제 #7
0
func (dataNode *dataNode) getKeyElements() (string, string) {
	return statemgmt.DecodeCompositeKey(dataNode.getCompositeKey())
}