// AddChangesForPersistence commits current changes to the database func (stateTrie *StateTrie) AddChangesForPersistence(writeBatch *gorocksdb.WriteBatch) error { if stateTrie.recomputeCryptoHash { _, err := stateTrie.ComputeCryptoHash() if err != nil { return err } } if stateTrie.trieDelta == nil { stateTrieLogger.Info("trieDelta is nil. Not writing anything to DB") return nil } openchainDB := db.GetDBHandle() lowestLevel := stateTrie.trieDelta.getLowestLevel() for level := lowestLevel; level >= 0; level-- { changedNodes := stateTrie.trieDelta.deltaMap[level] for _, changedNode := range changedNodes { if changedNode.markedForDeletion { writeBatch.DeleteCF(openchainDB.StateCF, changedNode.trieKey.getEncodedBytes()) continue } serializedContent, err := changedNode.marshal() if err != nil { return err } writeBatch.PutCF(openchainDB.StateCF, changedNode.trieKey.getEncodedBytes(), serializedContent) } } stateTrieLogger.Debug("Added changes to DB") return nil }
func (blockchain *blockchain) addPersistenceChangesForNewBlock(ctx context.Context, block *protos.Block, stateHash []byte, writeBatch *gorocksdb.WriteBatch) (uint64, error) { block = blockchain.buildBlock(block, stateHash) if block.NonHashData == nil { block.NonHashData = &protos.NonHashData{LocalLedgerCommitTimestamp: util.CreateUtcTimestamp()} } else { block.NonHashData.LocalLedgerCommitTimestamp = util.CreateUtcTimestamp() } blockNumber := blockchain.size blockHash, err := block.GetHash() if err != nil { return 0, err } blockBytes, blockBytesErr := block.Bytes() if blockBytesErr != nil { return 0, blockBytesErr } writeBatch.PutCF(db.GetDBHandle().BlockchainCF, encodeBlockNumberDBKey(blockNumber), blockBytes) writeBatch.PutCF(db.GetDBHandle().BlockchainCF, blockCountKey, encodeUint64(blockNumber+1)) if blockchain.indexer.isSynchronous() { blockchain.indexer.createIndexesSync(block, blockNumber, blockHash, writeBatch) } blockchain.lastProcessedBlock = &lastProcessedBlock{block, blockNumber, blockHash} return blockNumber, nil }
func (stateImpl *StateImpl) addBucketNodeChangesForPersistence(writeBatch *gorocksdb.WriteBatch) { openchainDB := db.GetDBHandle() secondLastLevel := conf.getLowestLevel() - 1 for level := secondLastLevel; level >= 0; level-- { bucketNodes := stateImpl.bucketTreeDelta.getBucketNodesAt(level) for _, bucketNode := range bucketNodes { if bucketNode.markedForDeletion { writeBatch.DeleteCF(openchainDB.StateCF, bucketNode.bucketKey.getEncodedBytes()) } else { writeBatch.PutCF(openchainDB.StateCF, bucketNode.bucketKey.getEncodedBytes(), bucketNode.marshal()) } } } }
func (stateImpl *StateImpl) addDataNodeChangesForPersistence(writeBatch *gorocksdb.WriteBatch) { openchainDB := db.GetDBHandle() affectedBuckets := stateImpl.dataNodesDelta.getAffectedBuckets() for _, affectedBucket := range affectedBuckets { dataNodes := stateImpl.dataNodesDelta.getSortedDataNodesFor(affectedBucket) for _, dataNode := range dataNodes { if dataNode.isDelete() { writeBatch.DeleteCF(openchainDB.StateCF, dataNode.dataKey.getEncodedBytes()) } else { writeBatch.PutCF(openchainDB.StateCF, dataNode.dataKey.getEncodedBytes(), dataNode.value) } } } }
// AddChangesForPersistence - method implementation for interface 'statemgmt.HashableState' func (impl *StateImpl) AddChangesForPersistence(writeBatch *gorocksdb.WriteBatch) error { delta := impl.stateDelta if delta == nil { return nil } openchainDB := db.GetDBHandle() updatedChaincodeIds := delta.GetUpdatedChaincodeIds(false) for _, updatedChaincodeID := range updatedChaincodeIds { updates := delta.GetUpdates(updatedChaincodeID) for updatedKey, value := range updates { compositeKey := statemgmt.ConstructCompositeKey(updatedChaincodeID, updatedKey) if value.IsDeleted() { writeBatch.DeleteCF(openchainDB.StateCF, compositeKey) } else { writeBatch.PutCF(openchainDB.StateCF, compositeKey, value.GetValue()) } } } return nil }
// Functions for persisting and retrieving index data func addIndexDataForPersistence(block *protos.Block, blockNumber uint64, blockHash []byte, writeBatch *gorocksdb.WriteBatch) error { openchainDB := db.GetDBHandle() cf := openchainDB.IndexesCF // add blockhash -> blockNumber indexLogger.Debug("Indexing block number [%d] by hash = [%x]", blockNumber, blockHash) writeBatch.PutCF(cf, encodeBlockHashKey(blockHash), encodeBlockNumber(blockNumber)) addressToTxIndexesMap := make(map[string][]uint64) addressToChaincodeIDsMap := make(map[string][]*protos.ChaincodeID) transactions := block.GetTransactions() for txIndex, tx := range transactions { // add TxUUID -> (blockNumber,indexWithinBlock) writeBatch.PutCF(cf, encodeTxUUIDKey(tx.Uuid), encodeBlockNumTxIndex(blockNumber, uint64(txIndex))) txExecutingAddress := getTxExecutingAddress(tx) addressToTxIndexesMap[txExecutingAddress] = append(addressToTxIndexesMap[txExecutingAddress], uint64(txIndex)) switch tx.Type { case protos.Transaction_CHAINCODE_NEW, protos.Transaction_CHAINCODE_UPDATE: authroizedAddresses, chaincodeID := getAuthorisedAddresses(tx) for _, authroizedAddress := range authroizedAddresses { addressToChaincodeIDsMap[authroizedAddress] = append(addressToChaincodeIDsMap[authroizedAddress], chaincodeID) } } } for address, txsIndexes := range addressToTxIndexesMap { writeBatch.PutCF(cf, encodeAddressBlockNumCompositeKey(address, blockNumber), encodeListTxIndexes(txsIndexes)) } return nil }
// AddChangesForPersistence adds key-value pairs to writeBatch func (state *State) AddChangesForPersistence(blockNumber uint64, writeBatch *gorocksdb.WriteBatch) { logger.Debug("state.addChangesForPersistence()...start") if state.updateStateImpl { state.stateImpl.PrepareWorkingSet(state.stateDelta) state.updateStateImpl = false } state.stateImpl.AddChangesForPersistence(writeBatch) serializedStateDelta := state.stateDelta.Marshal() cf := db.GetDBHandle().StateDeltaCF logger.Debug("Adding state-delta corresponding to block number[%d]", blockNumber) writeBatch.PutCF(cf, encodeStateDeltaKey(blockNumber), serializedStateDelta) if blockNumber >= state.historyStateDeltaSize { blockNumberToDelete := blockNumber - state.historyStateDeltaSize logger.Debug("Deleting state-delta corresponding to block number[%d]", blockNumberToDelete) writeBatch.DeleteCF(cf, encodeStateDeltaKey(blockNumberToDelete)) } else { logger.Debug("Not deleting previous state-delta. Block number [%d] is smaller than historyStateDeltaSize [%d]", blockNumber, state.historyStateDeltaSize) } logger.Debug("state.addChangesForPersistence()...finished") }