// 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 util.IsNil(value) { 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 }
// Next - see interface 'statemgmt.RangeScanIterator' for details func (itr *RangeScanIterator) Next() bool { if itr.done { return false } for ; itr.dbItr.Valid(); itr.dbItr.Next() { trieKeyBytes := itr.dbItr.Key().Data() trieNodeBytes := itr.dbItr.Value().Data() value := unmarshalTrieNodeValue(trieNodeBytes) if util.IsNil(value) { 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 }
// Next - see interface 'statemgmt.RangeScanIterator' for details func (itr *RangeScanIterator) Next() bool { if itr.done { return false } for itr.dbItr.Valid() { keyBytes := statemgmt.Copy(itr.dbItr.Key().Data()) valueBytes := 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 }
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.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 } }
// 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 }
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()) }