diff options
author | MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz> | 2023-08-01 12:01:02 +0200 |
---|---|---|
committer | MarcoFalke <*~=`'#}+{/-|&$^_@721217.xyz> | 2023-08-01 15:27:33 +0200 |
commit | fa65111b99627289fd47dcfaa5197e0f09b8a50e (patch) | |
tree | aa759777b4149a547979da18d655d994d70c75e9 /src/node | |
parent | fa8685597e7302fc136f21b6dd3a4b187fa8e251 (diff) |
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
Diffstat (limited to 'src/node')
-rw-r--r-- | src/node/blockstorage.cpp | 102 | ||||
-rw-r--r-- | src/node/blockstorage.h | 29 |
2 files changed, 130 insertions, 1 deletions
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 <chain.h> #include <clientversion.h> #include <consensus/validation.h> +#include <dbwrapper.h> #include <flatfile.h> #include <hash.h> #include <kernel/chainparams.h> @@ -15,15 +16,116 @@ #include <reverse_iterator.h> #include <signet.h> #include <streams.h> +#include <sync.h> #include <undo.h> #include <util/batchpriority.h> #include <util/fs.h> #include <util/signalinterrupt.h> +#include <util/translation.h> #include <validation.h> #include <map> #include <unordered_map> +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<std::pair<int, const CBlockFileInfo*> >& fileInfo, int nLastFile, const std::vector<const CBlockIndex*>& blockinfo) { + CDBBatch batch(*this); + for (std::vector<std::pair<int, const CBlockFileInfo*> >::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 CBlockIndex*>::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<CBlockIndex*(const uint256&)> insertBlockIndex, const util::SignalInterrupt& interrupt) +{ + AssertLockHeld(::cs_main); + std::unique_ptr<CDBIterator> pcursor(NewIterator()); + pcursor->Seek(std::make_pair(DB_BLOCK_INDEX, uint256())); + + // Load m_block_index + while (pcursor->Valid()) { + if (interrupt) return false; + std::pair<uint8_t, uint256> 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 <attributes.h> #include <chain.h> +#include <dbwrapper.h> #include <kernel/blockmanager_opts.h> #include <kernel/chainparams.h> #include <kernel/cs_main.h> #include <protocol.h> #include <sync.h> -#include <txdb.h> #include <util/fs.h> +#include <util/hasher.h> #include <atomic> #include <cstdint> +#include <functional> +#include <limits> +#include <map> +#include <memory> +#include <set> +#include <string> #include <unordered_map> +#include <utility> #include <vector> 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<std::pair<int, const CBlockFileInfo*>>& fileInfo, int nLastFile, const std::vector<const CBlockIndex*>& 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<CBlockIndex*(const uint256&)> 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 |