// 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 }
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) }
// 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 } }
// 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 }
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()
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 (dataNode *dataNode) getKeyElements() (string, string) { return statemgmt.DecodeCompositeKey(dataNode.getCompositeKey()) }