aboutsummaryrefslogtreecommitdiff
path: root/src/node
diff options
context:
space:
mode:
authorMarcoFalke <falke.marco@gmail.com>2021-04-02 20:42:05 +0200
committerMarcoFalke <falke.marco@gmail.com>2021-04-05 20:26:14 +0200
commitfa0c7d9ad24d3c9515d3f9c136af4071cbd79055 (patch)
treeab4694ab21d018246826d8ff4a87bccdf7b8d690 /src/node
parentfa91b2b2b3447a3645e7958c7dc4e1946a69cb9c (diff)
move-only: Move *Disk functions to blockstorage
Can be reviewed with the git options --color-moved=dimmed-zebra --color-moved-ws=ignore-all-space
Diffstat (limited to 'src/node')
-rw-r--r--src/node/blockstorage.cpp142
-rw-r--r--src/node/blockstorage.h21
-rw-r--r--src/node/interfaces.cpp4
3 files changed, 165 insertions, 2 deletions
diff --git a/src/node/blockstorage.cpp b/src/node/blockstorage.cpp
index 235dbb1693..de54bf1f42 100644
--- a/src/node/blockstorage.cpp
+++ b/src/node/blockstorage.cpp
@@ -2,14 +2,154 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include <blockstorage.h>
+#include <node/blockstorage.h>
+#include <chain.h>
#include <chainparams.h>
+#include <flatfile.h>
#include <fs.h>
+#include <pow.h>
#include <shutdown.h>
+#include <signet.h>
+#include <streams.h>
#include <util/system.h>
#include <validation.h>
+// From validation. TODO move here
+bool FindBlockPos(FlatFilePos& pos, unsigned int nAddSize, unsigned int nHeight, CChain& active_chain, uint64_t nTime, bool fKnown = false);
+
+static bool WriteBlockToDisk(const CBlock& block, FlatFilePos& pos, const CMessageHeader::MessageStartChars& messageStart)
+{
+ // Open history file to append
+ CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION);
+ if (fileout.IsNull())
+ return error("WriteBlockToDisk: OpenBlockFile failed");
+
+ // Write index header
+ unsigned int nSize = GetSerializeSize(block, fileout.GetVersion());
+ fileout << messageStart << nSize;
+
+ // Write block
+ long fileOutPos = ftell(fileout.Get());
+ if (fileOutPos < 0)
+ return error("WriteBlockToDisk: ftell failed");
+ pos.nPos = (unsigned int)fileOutPos;
+ fileout << block;
+
+ return true;
+}
+
+bool ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos, const Consensus::Params& consensusParams)
+{
+ block.SetNull();
+
+ // Open history file to read
+ CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION);
+ if (filein.IsNull())
+ return error("ReadBlockFromDisk: OpenBlockFile failed for %s", pos.ToString());
+
+ // Read block
+ try {
+ filein >> block;
+ }
+ catch (const std::exception& e) {
+ return error("%s: Deserialize or I/O error - %s at %s", __func__, e.what(), pos.ToString());
+ }
+
+ // Check the header
+ if (!CheckProofOfWork(block.GetHash(), block.nBits, consensusParams))
+ return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString());
+
+ // Signet only: check block solution
+ if (consensusParams.signet_blocks && !CheckSignetBlockSolution(block, consensusParams)) {
+ return error("ReadBlockFromDisk: Errors in block solution at %s", pos.ToString());
+ }
+
+ return true;
+}
+
+bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams)
+{
+ FlatFilePos blockPos;
+ {
+ LOCK(cs_main);
+ blockPos = pindex->GetBlockPos();
+ }
+
+ if (!ReadBlockFromDisk(block, blockPos, consensusParams))
+ return false;
+ if (block.GetHash() != pindex->GetBlockHash())
+ return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s",
+ pindex->ToString(), pindex->GetBlockPos().ToString());
+ return true;
+}
+
+bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatFilePos& pos, const CMessageHeader::MessageStartChars& message_start)
+{
+ FlatFilePos hpos = pos;
+ hpos.nPos -= 8; // Seek back 8 bytes for meta header
+ CAutoFile filein(OpenBlockFile(hpos, true), SER_DISK, CLIENT_VERSION);
+ if (filein.IsNull()) {
+ return error("%s: OpenBlockFile failed for %s", __func__, pos.ToString());
+ }
+
+ try {
+ CMessageHeader::MessageStartChars blk_start;
+ unsigned int blk_size;
+
+ filein >> blk_start >> blk_size;
+
+ if (memcmp(blk_start, message_start, CMessageHeader::MESSAGE_START_SIZE)) {
+ return error("%s: Block magic mismatch for %s: %s versus expected %s", __func__, pos.ToString(),
+ HexStr(blk_start),
+ HexStr(message_start));
+ }
+
+ if (blk_size > MAX_SIZE) {
+ return error("%s: Block data is larger than maximum deserialization size for %s: %s versus %s", __func__, pos.ToString(),
+ blk_size, MAX_SIZE);
+ }
+
+ block.resize(blk_size); // Zeroing of memory is intentional here
+ filein.read((char*)block.data(), blk_size);
+ } catch (const std::exception& e) {
+ return error("%s: Read from block file failed: %s for %s", __func__, e.what(), pos.ToString());
+ }
+
+ return true;
+}
+
+bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const CBlockIndex* pindex, const CMessageHeader::MessageStartChars& message_start)
+{
+ FlatFilePos block_pos;
+ {
+ LOCK(cs_main);
+ block_pos = pindex->GetBlockPos();
+ }
+
+ return ReadRawBlockFromDisk(block, block_pos, message_start);
+}
+
+/** Store block on disk. If dbp is non-nullptr, the file is known to already reside on disk */
+FlatFilePos SaveBlockToDisk(const CBlock& block, int nHeight, CChain& active_chain, const CChainParams& chainparams, const FlatFilePos* dbp)
+{
+ unsigned int nBlockSize = ::GetSerializeSize(block, CLIENT_VERSION);
+ FlatFilePos blockPos;
+ if (dbp != nullptr)
+ blockPos = *dbp;
+ if (!FindBlockPos(blockPos, nBlockSize + 8, nHeight, active_chain, block.GetBlockTime(), dbp != nullptr)) {
+ error("%s: FindBlockPos failed", __func__);
+ return FlatFilePos();
+ }
+ if (dbp == nullptr) {
+ if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart())) {
+ AbortNode("Failed to write block");
+ return FlatFilePos();
+ }
+ }
+ return blockPos;
+}
+
struct CImportingNow {
CImportingNow()
{
diff --git a/src/node/blockstorage.h b/src/node/blockstorage.h
index d81b39f9f9..3b546f0719 100644
--- a/src/node/blockstorage.h
+++ b/src/node/blockstorage.h
@@ -5,15 +5,36 @@
#ifndef BITCOIN_NODE_BLOCKSTORAGE_H
#define BITCOIN_NODE_BLOCKSTORAGE_H
+#include <cstdint>
#include <vector>
#include <fs.h>
+#include <protocol.h> // For CMessageHeader::MessageStartChars
class ArgsManager;
+class CBlock;
+class CBlockIndex;
+class CBlockUndo;
+class CChain;
+class CChainParams;
class ChainstateManager;
+struct FlatFilePos;
+namespace Consensus {
+struct Params;
+}
static constexpr bool DEFAULT_STOPAFTERBLOCKIMPORT{false};
+/** Functions for disk access for blocks */
+bool ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos, const Consensus::Params& consensusParams);
+bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams);
+bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatFilePos& pos, const CMessageHeader::MessageStartChars& message_start);
+bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const CBlockIndex* pindex, const CMessageHeader::MessageStartChars& message_start);
+
+bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex* pindex);
+
+FlatFilePos SaveBlockToDisk(const CBlock& block, int nHeight, CChain& active_chain, const CChainParams& chainparams, const FlatFilePos* dbp);
+
void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFiles, const ArgsManager& args);
#endif // BITCOIN_NODE_BLOCKSTORAGE_H
diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp
index 7ad02f81dc..264bec58f9 100644
--- a/src/node/interfaces.cpp
+++ b/src/node/interfaces.cpp
@@ -4,7 +4,6 @@
#include <addrdb.h>
#include <banman.h>
-#include <boost/signals2/signal.hpp>
#include <chain.h>
#include <chainparams.h>
#include <init.h>
@@ -17,6 +16,7 @@
#include <net_processing.h>
#include <netaddress.h>
#include <netbase.h>
+#include <node/blockstorage.h>
#include <node/coin.h>
#include <node/context.h>
#include <node/transaction.h>
@@ -53,6 +53,8 @@
#include <optional>
#include <utility>
+#include <boost/signals2/signal.hpp>
+
using interfaces::BlockTip;
using interfaces::Chain;
using interfaces::FoundBlock;