From fa65111b99627289fd47dcfaa5197e0f09b8a50e Mon Sep 17 00:00:00 2001 From: MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz> Date: Tue, 1 Aug 2023 12:01:02 +0200 Subject: move-only: Move CBlockTreeDB to node/blockstorage The block index (CBlockTreeDB) is required to write and read blocks, so move it to blockstorage. This allows to drop the txdb.h include from `node/blockstorage.h`. Can be reviewed with: --color-moved=dimmed-zebra --color-moved-ws=ignore-all-space --- src/node/blockstorage.cpp | 102 ++++++++++++++++++++++++++++++++++++++++++++++ src/node/blockstorage.h | 29 ++++++++++++- 2 files changed, 130 insertions(+), 1 deletion(-) (limited to 'src/node') diff --git a/src/node/blockstorage.cpp b/src/node/blockstorage.cpp index 0d25c798ce..6767e6fc51 100644 --- a/src/node/blockstorage.cpp +++ b/src/node/blockstorage.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -15,15 +16,116 @@ #include #include #include +#include #include #include #include #include +#include #include #include #include +namespace kernel { +static constexpr uint8_t DB_BLOCK_FILES{'f'}; +static constexpr uint8_t DB_BLOCK_INDEX{'b'}; +static constexpr uint8_t DB_FLAG{'F'}; +static constexpr uint8_t DB_REINDEX_FLAG{'R'}; +static constexpr uint8_t DB_LAST_BLOCK{'l'}; +// Keys used in previous version that might still be found in the DB: +// CBlockTreeDB::DB_TXINDEX_BLOCK{'T'}; +// CBlockTreeDB::DB_TXINDEX{'t'} +// CBlockTreeDB::ReadFlag("txindex") + +bool CBlockTreeDB::ReadBlockFileInfo(int nFile, CBlockFileInfo &info) { + return Read(std::make_pair(DB_BLOCK_FILES, nFile), info); +} + +bool CBlockTreeDB::WriteReindexing(bool fReindexing) { + if (fReindexing) + return Write(DB_REINDEX_FLAG, uint8_t{'1'}); + else + return Erase(DB_REINDEX_FLAG); +} + +void CBlockTreeDB::ReadReindexing(bool &fReindexing) { + fReindexing = Exists(DB_REINDEX_FLAG); +} + +bool CBlockTreeDB::ReadLastBlockFile(int &nFile) { + return Read(DB_LAST_BLOCK, nFile); +} + +bool CBlockTreeDB::WriteBatchSync(const std::vector >& fileInfo, int nLastFile, const std::vector& blockinfo) { + CDBBatch batch(*this); + for (std::vector >::const_iterator it=fileInfo.begin(); it != fileInfo.end(); it++) { + batch.Write(std::make_pair(DB_BLOCK_FILES, it->first), *it->second); + } + batch.Write(DB_LAST_BLOCK, nLastFile); + for (std::vector::const_iterator it=blockinfo.begin(); it != blockinfo.end(); it++) { + batch.Write(std::make_pair(DB_BLOCK_INDEX, (*it)->GetBlockHash()), CDiskBlockIndex(*it)); + } + return WriteBatch(batch, true); +} + +bool CBlockTreeDB::WriteFlag(const std::string &name, bool fValue) { + return Write(std::make_pair(DB_FLAG, name), fValue ? uint8_t{'1'} : uint8_t{'0'}); +} + +bool CBlockTreeDB::ReadFlag(const std::string &name, bool &fValue) { + uint8_t ch; + if (!Read(std::make_pair(DB_FLAG, name), ch)) + return false; + fValue = ch == uint8_t{'1'}; + return true; +} + +bool CBlockTreeDB::LoadBlockIndexGuts(const Consensus::Params& consensusParams, std::function insertBlockIndex, const util::SignalInterrupt& interrupt) +{ + AssertLockHeld(::cs_main); + std::unique_ptr pcursor(NewIterator()); + pcursor->Seek(std::make_pair(DB_BLOCK_INDEX, uint256())); + + // Load m_block_index + while (pcursor->Valid()) { + if (interrupt) return false; + std::pair key; + if (pcursor->GetKey(key) && key.first == DB_BLOCK_INDEX) { + CDiskBlockIndex diskindex; + if (pcursor->GetValue(diskindex)) { + // Construct block index object + CBlockIndex* pindexNew = insertBlockIndex(diskindex.ConstructBlockHash()); + pindexNew->pprev = insertBlockIndex(diskindex.hashPrev); + pindexNew->nHeight = diskindex.nHeight; + pindexNew->nFile = diskindex.nFile; + pindexNew->nDataPos = diskindex.nDataPos; + pindexNew->nUndoPos = diskindex.nUndoPos; + pindexNew->nVersion = diskindex.nVersion; + pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot; + pindexNew->nTime = diskindex.nTime; + pindexNew->nBits = diskindex.nBits; + pindexNew->nNonce = diskindex.nNonce; + pindexNew->nStatus = diskindex.nStatus; + pindexNew->nTx = diskindex.nTx; + + if (!CheckProofOfWork(pindexNew->GetBlockHash(), pindexNew->nBits, consensusParams)) { + return error("%s: CheckProofOfWork failed: %s", __func__, pindexNew->ToString()); + } + + pcursor->Next(); + } else { + return error("%s: failed to read value", __func__); + } + } else { + break; + } + } + + return true; +} +} // namespace kernel + namespace node { std::atomic_bool fReindex(false); diff --git a/src/node/blockstorage.h b/src/node/blockstorage.h index eb40d45aba..58608fe015 100644 --- a/src/node/blockstorage.h +++ b/src/node/blockstorage.h @@ -7,17 +7,25 @@ #include #include +#include #include #include #include #include #include -#include #include +#include #include #include +#include +#include +#include +#include +#include +#include #include +#include #include class BlockValidationState; @@ -36,7 +44,26 @@ namespace util { class SignalInterrupt; } // namespace util +namespace kernel { +/** Access to the block database (blocks/index/) */ +class CBlockTreeDB : public CDBWrapper +{ +public: + using CDBWrapper::CDBWrapper; + bool WriteBatchSync(const std::vector>& fileInfo, int nLastFile, const std::vector& blockinfo); + bool ReadBlockFileInfo(int nFile, CBlockFileInfo& info); + bool ReadLastBlockFile(int& nFile); + bool WriteReindexing(bool fReindexing); + void ReadReindexing(bool& fReindexing); + bool WriteFlag(const std::string& name, bool fValue); + bool ReadFlag(const std::string& name, bool& fValue); + bool LoadBlockIndexGuts(const Consensus::Params& consensusParams, std::function insertBlockIndex, const util::SignalInterrupt& interrupt) + EXCLUSIVE_LOCKS_REQUIRED(::cs_main); +}; +} // namespace kernel + namespace node { +using kernel::CBlockTreeDB; /** The pre-allocation chunk size for blk?????.dat files (since 0.8) */ static const unsigned int BLOCKFILE_CHUNK_SIZE = 0x1000000; // 16 MiB -- cgit v1.2.3