Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 137 Lines • ▼ Show 20 Lines | bool ActivateBestChain( | ||||
const Config &config, CValidationState &state, | const Config &config, CValidationState &state, | ||||
std::shared_ptr<const CBlock> pblock = std::shared_ptr<const CBlock>()); | std::shared_ptr<const CBlock> pblock = std::shared_ptr<const CBlock>()); | ||||
bool AcceptBlockHeader(const Config &config, const CBlockHeader &block, | bool AcceptBlockHeader(const Config &config, const CBlockHeader &block, | ||||
CValidationState &state, CBlockIndex **ppindex); | CValidationState &state, CBlockIndex **ppindex); | ||||
bool AcceptBlock(const Config &config, | bool AcceptBlock(const Config &config, | ||||
const std::shared_ptr<const CBlock> &pblock, | const std::shared_ptr<const CBlock> &pblock, | ||||
CValidationState &state, bool fRequested, | CValidationState &state, bool fRequested, | ||||
const CDiskBlockPos *dbp, bool *fNewBlock); | const FlatFilePos *dbp, bool *fNewBlock); | ||||
// Block (dis)connection on a given view: | // Block (dis)connection on a given view: | ||||
DisconnectResult DisconnectBlock(const CBlock &block, | DisconnectResult DisconnectBlock(const CBlock &block, | ||||
const CBlockIndex *pindex, | const CBlockIndex *pindex, | ||||
CCoinsViewCache &view); | CCoinsViewCache &view); | ||||
bool ConnectBlock(const Config &config, const CBlock &block, | bool ConnectBlock(const Config &config, const CBlock &block, | ||||
CValidationState &state, CBlockIndex *pindex, | CValidationState &state, CBlockIndex *pindex, | ||||
CCoinsViewCache &view, bool fJustCheck = false); | CCoinsViewCache &view, bool fJustCheck = false); | ||||
Show All 39 Lines | private: | ||||
/** Create a new block index entry for a given block hash */ | /** Create a new block index entry for a given block hash */ | ||||
CBlockIndex *InsertBlockIndex(const uint256 &hash); | CBlockIndex *InsertBlockIndex(const uint256 &hash); | ||||
void CheckBlockIndex(const Consensus::Params &consensusParams); | void CheckBlockIndex(const Consensus::Params &consensusParams); | ||||
void InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state); | void InvalidBlockFound(CBlockIndex *pindex, const CValidationState &state); | ||||
CBlockIndex *FindMostWorkChain(); | CBlockIndex *FindMostWorkChain(); | ||||
bool ReceivedBlockTransactions(const CBlock &block, CValidationState &state, | bool ReceivedBlockTransactions(const CBlock &block, CValidationState &state, | ||||
CBlockIndex *pindexNew, | CBlockIndex *pindexNew, | ||||
const CDiskBlockPos &pos); | const FlatFilePos &pos); | ||||
bool RollforwardBlock(const CBlockIndex *pindex, CCoinsViewCache &inputs, | bool RollforwardBlock(const CBlockIndex *pindex, CCoinsViewCache &inputs, | ||||
const Config &config); | const Config &config); | ||||
} g_chainstate; | } g_chainstate; | ||||
/** | /** | ||||
* Global state | * Global state | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 95 Lines • ▼ Show 20 Lines | |||||
// See definition for documentation | // See definition for documentation | ||||
static bool FlushStateToDisk(const CChainParams &chainParams, | static bool FlushStateToDisk(const CChainParams &chainParams, | ||||
CValidationState &state, FlushStateMode mode, | CValidationState &state, FlushStateMode mode, | ||||
int nManualPruneHeight = 0); | int nManualPruneHeight = 0); | ||||
static void FindFilesToPruneManual(std::set<int> &setFilesToPrune, | static void FindFilesToPruneManual(std::set<int> &setFilesToPrune, | ||||
int nManualPruneHeight); | int nManualPruneHeight); | ||||
static void FindFilesToPrune(std::set<int> &setFilesToPrune, | static void FindFilesToPrune(std::set<int> &setFilesToPrune, | ||||
uint64_t nPruneAfterHeight); | uint64_t nPruneAfterHeight); | ||||
static FILE *OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly = false); | static FILE *OpenUndoFile(const FlatFilePos &pos, bool fReadOnly = false); | ||||
static FlatFileSeq BlockFileSeq(); | static FlatFileSeq BlockFileSeq(); | ||||
static FlatFileSeq UndoFileSeq(); | static FlatFileSeq UndoFileSeq(); | ||||
static uint32_t GetNextBlockScriptFlags(const Config &config, | static uint32_t GetNextBlockScriptFlags(const Config &config, | ||||
const CBlockIndex *pindex); | const CBlockIndex *pindex); | ||||
bool TestLockPointValidity(const LockPoints *lp) { | bool TestLockPointValidity(const LockPoints *lp) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
assert(lp); | assert(lp); | ||||
▲ Show 20 Lines • Show All 577 Lines • ▼ Show 20 Lines | bool GetTransaction(const Config &config, const TxId &txid, | ||||
return false; | return false; | ||||
} | } | ||||
////////////////////////////////////////////////////////////////////////////// | ////////////////////////////////////////////////////////////////////////////// | ||||
// | // | ||||
// CBlock and CBlockIndex | // CBlock and CBlockIndex | ||||
// | // | ||||
static bool WriteBlockToDisk(const CBlock &block, CDiskBlockPos &pos, | static bool WriteBlockToDisk(const CBlock &block, FlatFilePos &pos, | ||||
const CMessageHeader::MessageMagic &messageStart) { | const CMessageHeader::MessageMagic &messageStart) { | ||||
// Open history file to append | // Open history file to append | ||||
CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION); | CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION); | ||||
if (fileout.IsNull()) { | if (fileout.IsNull()) { | ||||
return error("WriteBlockToDisk: OpenBlockFile failed"); | return error("WriteBlockToDisk: OpenBlockFile failed"); | ||||
} | } | ||||
// Write index header | // Write index header | ||||
unsigned int nSize = GetSerializeSize(fileout, block); | unsigned int nSize = GetSerializeSize(fileout, block); | ||||
fileout << FLATDATA(messageStart) << nSize; | fileout << FLATDATA(messageStart) << nSize; | ||||
// Write block | // Write block | ||||
long fileOutPos = ftell(fileout.Get()); | long fileOutPos = ftell(fileout.Get()); | ||||
if (fileOutPos < 0) { | if (fileOutPos < 0) { | ||||
return error("WriteBlockToDisk: ftell failed"); | return error("WriteBlockToDisk: ftell failed"); | ||||
} | } | ||||
pos.nPos = (unsigned int)fileOutPos; | pos.nPos = (unsigned int)fileOutPos; | ||||
fileout << block; | fileout << block; | ||||
return true; | return true; | ||||
} | } | ||||
bool ReadBlockFromDisk(CBlock &block, const CDiskBlockPos &pos, | bool ReadBlockFromDisk(CBlock &block, const FlatFilePos &pos, | ||||
const Config &config) { | const Config &config) { | ||||
block.SetNull(); | block.SetNull(); | ||||
// Open history file to read | // Open history file to read | ||||
CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION); | CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION); | ||||
if (filein.IsNull()) { | if (filein.IsNull()) { | ||||
return error("ReadBlockFromDisk: OpenBlockFile failed for %s", | return error("ReadBlockFromDisk: OpenBlockFile failed for %s", | ||||
pos.ToString()); | pos.ToString()); | ||||
Show All 13 Lines | if (!CheckProofOfWork(block.GetHash(), block.nBits, config)) { | ||||
pos.ToString()); | pos.ToString()); | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
bool ReadBlockFromDisk(CBlock &block, const CBlockIndex *pindex, | bool ReadBlockFromDisk(CBlock &block, const CBlockIndex *pindex, | ||||
const Config &config) { | const Config &config) { | ||||
CDiskBlockPos blockPos; | FlatFilePos blockPos; | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
blockPos = pindex->GetBlockPos(); | blockPos = pindex->GetBlockPos(); | ||||
} | } | ||||
if (!ReadBlockFromDisk(block, blockPos, config)) { | if (!ReadBlockFromDisk(block, blockPos, config)) { | ||||
return false; | return false; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 338 Lines • ▼ Show 20 Lines | if (scriptCacheStore && !pvChecks) { | ||||
AddKeyInScriptCache(hashCacheEntry); | AddKeyInScriptCache(hashCacheEntry); | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
namespace { | namespace { | ||||
bool UndoWriteToDisk(const CBlockUndo &blockundo, CDiskBlockPos &pos, | bool UndoWriteToDisk(const CBlockUndo &blockundo, FlatFilePos &pos, | ||||
const uint256 &hashBlock, | const uint256 &hashBlock, | ||||
const CMessageHeader::MessageMagic &messageStart) { | const CMessageHeader::MessageMagic &messageStart) { | ||||
// Open history file to append | // Open history file to append | ||||
CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION); | CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION); | ||||
if (fileout.IsNull()) { | if (fileout.IsNull()) { | ||||
return error("%s: OpenUndoFile failed", __func__); | return error("%s: OpenUndoFile failed", __func__); | ||||
} | } | ||||
Show All 14 Lines | bool UndoWriteToDisk(const CBlockUndo &blockundo, FlatFilePos &pos, | ||||
hasher << hashBlock; | hasher << hashBlock; | ||||
hasher << blockundo; | hasher << blockundo; | ||||
fileout << hasher.GetHash(); | fileout << hasher.GetHash(); | ||||
return true; | return true; | ||||
} | } | ||||
static bool UndoReadFromDisk(CBlockUndo &blockundo, const CBlockIndex *pindex) { | static bool UndoReadFromDisk(CBlockUndo &blockundo, const CBlockIndex *pindex) { | ||||
CDiskBlockPos pos = pindex->GetUndoPos(); | FlatFilePos pos = pindex->GetUndoPos(); | ||||
if (pos.IsNull()) { | if (pos.IsNull()) { | ||||
return error("%s: no undo data available", __func__); | return error("%s: no undo data available", __func__); | ||||
} | } | ||||
// Open history file to read | // Open history file to read | ||||
CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION); | CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION); | ||||
if (filein.IsNull()) { | if (filein.IsNull()) { | ||||
return error("%s: OpenUndoFile failed", __func__); | return error("%s: OpenUndoFile failed", __func__); | ||||
▲ Show 20 Lines • Show All 153 Lines • ▼ Show 20 Lines | DisconnectResult ApplyBlockUndo(const CBlockUndo &blockUndo, | ||||
view.SetBestBlock(block.hashPrevBlock); | view.SetBestBlock(block.hashPrevBlock); | ||||
return fClean ? DISCONNECT_OK : DISCONNECT_UNCLEAN; | return fClean ? DISCONNECT_OK : DISCONNECT_UNCLEAN; | ||||
} | } | ||||
static void FlushBlockFile(bool fFinalize = false) { | static void FlushBlockFile(bool fFinalize = false) { | ||||
LOCK(cs_LastBlockFile); | LOCK(cs_LastBlockFile); | ||||
CDiskBlockPos block_pos_old(nLastBlockFile, | FlatFilePos block_pos_old(nLastBlockFile, | ||||
vinfoBlockFile[nLastBlockFile].nSize); | vinfoBlockFile[nLastBlockFile].nSize); | ||||
CDiskBlockPos undo_pos_old(nLastBlockFile, | FlatFilePos undo_pos_old(nLastBlockFile, | ||||
vinfoBlockFile[nLastBlockFile].nUndoSize); | vinfoBlockFile[nLastBlockFile].nUndoSize); | ||||
bool status = true; | bool status = true; | ||||
status &= BlockFileSeq().Flush(block_pos_old, fFinalize); | status &= BlockFileSeq().Flush(block_pos_old, fFinalize); | ||||
status &= UndoFileSeq().Flush(undo_pos_old, fFinalize); | status &= UndoFileSeq().Flush(undo_pos_old, fFinalize); | ||||
if (!status) { | if (!status) { | ||||
AbortNode("Flushing block file to disk failed. This is likely the " | AbortNode("Flushing block file to disk failed. This is likely the " | ||||
"result of an I/O error."); | "result of an I/O error."); | ||||
} | } | ||||
} | } | ||||
static bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, | static bool FindUndoPos(CValidationState &state, int nFile, FlatFilePos &pos, | ||||
unsigned int nAddSize); | unsigned int nAddSize); | ||||
static bool WriteUndoDataForBlock(const CBlockUndo &blockundo, | static bool WriteUndoDataForBlock(const CBlockUndo &blockundo, | ||||
CValidationState &state, CBlockIndex *pindex, | CValidationState &state, CBlockIndex *pindex, | ||||
const CChainParams &chainparams) { | const CChainParams &chainparams) { | ||||
// Write undo information to disk | // Write undo information to disk | ||||
if (pindex->GetUndoPos().IsNull()) { | if (pindex->GetUndoPos().IsNull()) { | ||||
CDiskBlockPos _pos; | FlatFilePos _pos; | ||||
if (!FindUndoPos( | if (!FindUndoPos( | ||||
state, pindex->nFile, _pos, | state, pindex->nFile, _pos, | ||||
::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40)) { | ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40)) { | ||||
return error("ConnectBlock(): FindUndoPos failed"); | return error("ConnectBlock(): FindUndoPos failed"); | ||||
} | } | ||||
if (!UndoWriteToDisk(blockundo, _pos, pindex->pprev->GetBlockHash(), | if (!UndoWriteToDisk(blockundo, _pos, pindex->pprev->GetBlockHash(), | ||||
chainparams.DiskMagic())) { | chainparams.DiskMagic())) { | ||||
return AbortNode(state, "Failed to write undo data"); | return AbortNode(state, "Failed to write undo data"); | ||||
▲ Show 20 Lines • Show All 1,720 Lines • ▼ Show 20 Lines | |||||
/** | /** | ||||
* Mark a block as having its data received and checked (up to | * Mark a block as having its data received and checked (up to | ||||
* BLOCK_VALID_TRANSACTIONS). | * BLOCK_VALID_TRANSACTIONS). | ||||
*/ | */ | ||||
bool CChainState::ReceivedBlockTransactions(const CBlock &block, | bool CChainState::ReceivedBlockTransactions(const CBlock &block, | ||||
CValidationState &state, | CValidationState &state, | ||||
CBlockIndex *pindexNew, | CBlockIndex *pindexNew, | ||||
const CDiskBlockPos &pos) { | const FlatFilePos &pos) { | ||||
pindexNew->nTx = block.vtx.size(); | pindexNew->nTx = block.vtx.size(); | ||||
pindexNew->nChainTx = 0; | pindexNew->nChainTx = 0; | ||||
pindexNew->nFile = pos.nFile; | pindexNew->nFile = pos.nFile; | ||||
pindexNew->nDataPos = pos.nPos; | pindexNew->nDataPos = pos.nPos; | ||||
pindexNew->nUndoPos = 0; | pindexNew->nUndoPos = 0; | ||||
pindexNew->nStatus = pindexNew->nStatus.withData(); | pindexNew->nStatus = pindexNew->nStatus.withData(); | ||||
pindexNew->RaiseValidity(BlockValidity::TRANSACTIONS); | pindexNew->RaiseValidity(BlockValidity::TRANSACTIONS); | ||||
setDirtyBlockIndex.insert(pindexNew); | setDirtyBlockIndex.insert(pindexNew); | ||||
Show All 40 Lines | bool CChainState::ReceivedBlockTransactions(const CBlock &block, | ||||
} else if (pindexNew->pprev && | } else if (pindexNew->pprev && | ||||
pindexNew->pprev->IsValid(BlockValidity::TREE)) { | pindexNew->pprev->IsValid(BlockValidity::TREE)) { | ||||
mapBlocksUnlinked.insert(std::make_pair(pindexNew->pprev, pindexNew)); | mapBlocksUnlinked.insert(std::make_pair(pindexNew->pprev, pindexNew)); | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
static bool FindBlockPos(CDiskBlockPos &pos, unsigned int nAddSize, | static bool FindBlockPos(FlatFilePos &pos, unsigned int nAddSize, | ||||
unsigned int nHeight, uint64_t nTime, | unsigned int nHeight, uint64_t nTime, | ||||
bool fKnown = false) { | bool fKnown = false) { | ||||
LOCK(cs_LastBlockFile); | LOCK(cs_LastBlockFile); | ||||
unsigned int nFile = fKnown ? pos.nFile : nLastBlockFile; | unsigned int nFile = fKnown ? pos.nFile : nLastBlockFile; | ||||
if (vinfoBlockFile.size() <= nFile) { | if (vinfoBlockFile.size() <= nFile) { | ||||
vinfoBlockFile.resize(nFile + 1); | vinfoBlockFile.resize(nFile + 1); | ||||
} | } | ||||
Show All 38 Lines | if (!fKnown) { | ||||
fCheckForPruning = true; | fCheckForPruning = true; | ||||
} | } | ||||
} | } | ||||
setDirtyFileInfo.insert(nFile); | setDirtyFileInfo.insert(nFile); | ||||
return true; | return true; | ||||
} | } | ||||
static bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, | static bool FindUndoPos(CValidationState &state, int nFile, FlatFilePos &pos, | ||||
unsigned int nAddSize) { | unsigned int nAddSize) { | ||||
pos.nFile = nFile; | pos.nFile = nFile; | ||||
LOCK(cs_LastBlockFile); | LOCK(cs_LastBlockFile); | ||||
pos.nPos = vinfoBlockFile[nFile].nUndoSize; | pos.nPos = vinfoBlockFile[nFile].nUndoSize; | ||||
vinfoBlockFile[nFile].nUndoSize += nAddSize; | vinfoBlockFile[nFile].nUndoSize += nAddSize; | ||||
setDirtyFileInfo.insert(nFile); | setDirtyFileInfo.insert(nFile); | ||||
▲ Show 20 Lines • Show All 461 Lines • ▼ Show 20 Lines | bool ProcessNewBlockHeaders(const Config &config, | ||||
NotifyHeaderTip(); | NotifyHeaderTip(); | ||||
return true; | return true; | ||||
} | } | ||||
/** | /** | ||||
* Store block on disk. If dbp is non-nullptr, the file is known to already | * Store block on disk. If dbp is non-nullptr, the file is known to already | ||||
* reside on disk. | * reside on disk. | ||||
*/ | */ | ||||
static CDiskBlockPos SaveBlockToDisk(const CBlock &block, int nHeight, | static FlatFilePos SaveBlockToDisk(const CBlock &block, int nHeight, | ||||
const CChainParams &chainparams, | const CChainParams &chainparams, | ||||
const CDiskBlockPos *dbp) { | const FlatFilePos *dbp) { | ||||
unsigned int nBlockSize = | unsigned int nBlockSize = | ||||
::GetSerializeSize(block, SER_DISK, CLIENT_VERSION); | ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION); | ||||
CDiskBlockPos blockPos; | FlatFilePos blockPos; | ||||
if (dbp != nullptr) { | if (dbp != nullptr) { | ||||
blockPos = *dbp; | blockPos = *dbp; | ||||
} | } | ||||
if (!FindBlockPos(blockPos, nBlockSize + 8, nHeight, block.GetBlockTime(), | if (!FindBlockPos(blockPos, nBlockSize + 8, nHeight, block.GetBlockTime(), | ||||
dbp != nullptr)) { | dbp != nullptr)) { | ||||
error("%s: FindBlockPos failed", __func__); | error("%s: FindBlockPos failed", __func__); | ||||
return CDiskBlockPos(); | return FlatFilePos(); | ||||
} | } | ||||
if (dbp == nullptr) { | if (dbp == nullptr) { | ||||
if (!WriteBlockToDisk(block, blockPos, chainparams.DiskMagic())) { | if (!WriteBlockToDisk(block, blockPos, chainparams.DiskMagic())) { | ||||
AbortNode("Failed to write block"); | AbortNode("Failed to write block"); | ||||
return CDiskBlockPos(); | return FlatFilePos(); | ||||
} | } | ||||
} | } | ||||
return blockPos; | return blockPos; | ||||
} | } | ||||
/** | /** | ||||
* Store a block on disk. | * Store a block on disk. | ||||
* | * | ||||
* @param[in] config The global config. | * @param[in] config The global config. | ||||
* @param[in-out] pblock The block we want to accept. | * @param[in-out] pblock The block we want to accept. | ||||
* @param[in] fRequested A boolean to indicate if this block was requested | * @param[in] fRequested A boolean to indicate if this block was requested | ||||
* from our peers. | * from our peers. | ||||
* @param[in] dbp If non-null, the disk position of the block. | * @param[in] dbp If non-null, the disk position of the block. | ||||
* @param[in-out] fNewBlock True if block was first received via this call. | * @param[in-out] fNewBlock True if block was first received via this call. | ||||
* @return True if the block is accepted as a valid block and written to disk. | * @return True if the block is accepted as a valid block and written to disk. | ||||
*/ | */ | ||||
bool CChainState::AcceptBlock(const Config &config, | bool CChainState::AcceptBlock(const Config &config, | ||||
const std::shared_ptr<const CBlock> &pblock, | const std::shared_ptr<const CBlock> &pblock, | ||||
CValidationState &state, bool fRequested, | CValidationState &state, bool fRequested, | ||||
const CDiskBlockPos *dbp, bool *fNewBlock) { | const FlatFilePos *dbp, bool *fNewBlock) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
const CBlock &block = *pblock; | const CBlock &block = *pblock; | ||||
if (fNewBlock) { | if (fNewBlock) { | ||||
*fNewBlock = false; | *fNewBlock = false; | ||||
} | } | ||||
CBlockIndex *pindex = nullptr; | CBlockIndex *pindex = nullptr; | ||||
▲ Show 20 Lines • Show All 111 Lines • ▼ Show 20 Lines | bool CChainState::AcceptBlock(const Config &config, | ||||
if (!IsInitialBlockDownload() && chainActive.Tip() == pindex->pprev) { | if (!IsInitialBlockDownload() && chainActive.Tip() == pindex->pprev) { | ||||
GetMainSignals().NewPoWValidBlock(pindex, pblock); | GetMainSignals().NewPoWValidBlock(pindex, pblock); | ||||
} | } | ||||
const CChainParams &chainparams = config.GetChainParams(); | const CChainParams &chainparams = config.GetChainParams(); | ||||
// Write block to history file | // Write block to history file | ||||
try { | try { | ||||
CDiskBlockPos blockPos = | FlatFilePos blockPos = | ||||
SaveBlockToDisk(block, pindex->nHeight, chainparams, dbp); | SaveBlockToDisk(block, pindex->nHeight, chainparams, dbp); | ||||
if (blockPos.IsNull()) { | if (blockPos.IsNull()) { | ||||
state.Error(strprintf( | state.Error(strprintf( | ||||
"%s: Failed to find position to write new block to disk", | "%s: Failed to find position to write new block to disk", | ||||
__func__)); | __func__)); | ||||
return false; | return false; | ||||
} | } | ||||
if (!ReceivedBlockTransactions(block, state, pindex, blockPos)) { | if (!ReceivedBlockTransactions(block, state, pindex, blockPos)) { | ||||
▲ Show 20 Lines • Show All 145 Lines • ▼ Show 20 Lines | void PruneOneBlockFile(const int fileNumber) { | ||||
} | } | ||||
vinfoBlockFile[fileNumber].SetNull(); | vinfoBlockFile[fileNumber].SetNull(); | ||||
setDirtyFileInfo.insert(fileNumber); | setDirtyFileInfo.insert(fileNumber); | ||||
} | } | ||||
void UnlinkPrunedFiles(const std::set<int> &setFilesToPrune) { | void UnlinkPrunedFiles(const std::set<int> &setFilesToPrune) { | ||||
for (const int i : setFilesToPrune) { | for (const int i : setFilesToPrune) { | ||||
CDiskBlockPos pos(i, 0); | FlatFilePos pos(i, 0); | ||||
fs::remove(BlockFileSeq().FileName(pos)); | fs::remove(BlockFileSeq().FileName(pos)); | ||||
fs::remove(UndoFileSeq().FileName(pos)); | fs::remove(UndoFileSeq().FileName(pos)); | ||||
LogPrintf("Prune: %s deleted blk/rev (%05u)\n", __func__, i); | LogPrintf("Prune: %s deleted blk/rev (%05u)\n", __func__, i); | ||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Calculate the block/rev files to delete based on height specified by user | * Calculate the block/rev files to delete based on height specified by user | ||||
▲ Show 20 Lines • Show All 115 Lines • ▼ Show 20 Lines | |||||
static FlatFileSeq BlockFileSeq() { | static FlatFileSeq BlockFileSeq() { | ||||
return FlatFileSeq(GetBlocksDir(), "blk", BLOCKFILE_CHUNK_SIZE); | return FlatFileSeq(GetBlocksDir(), "blk", BLOCKFILE_CHUNK_SIZE); | ||||
} | } | ||||
static FlatFileSeq UndoFileSeq() { | static FlatFileSeq UndoFileSeq() { | ||||
return FlatFileSeq(GetBlocksDir(), "rev", UNDOFILE_CHUNK_SIZE); | return FlatFileSeq(GetBlocksDir(), "rev", UNDOFILE_CHUNK_SIZE); | ||||
} | } | ||||
FILE *OpenBlockFile(const CDiskBlockPos &pos, bool fReadOnly) { | FILE *OpenBlockFile(const FlatFilePos &pos, bool fReadOnly) { | ||||
return BlockFileSeq().Open(pos, fReadOnly); | return BlockFileSeq().Open(pos, fReadOnly); | ||||
} | } | ||||
/** Open an undo file (rev?????.dat) */ | /** Open an undo file (rev?????.dat) */ | ||||
static FILE *OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly) { | static FILE *OpenUndoFile(const FlatFilePos &pos, bool fReadOnly) { | ||||
return UndoFileSeq().Open(pos, fReadOnly); | return UndoFileSeq().Open(pos, fReadOnly); | ||||
} | } | ||||
fs::path GetBlockPosFilename(const CDiskBlockPos &pos) { | fs::path GetBlockPosFilename(const FlatFilePos &pos) { | ||||
return BlockFileSeq().FileName(pos); | return BlockFileSeq().FileName(pos); | ||||
} | } | ||||
CBlockIndex *CChainState::InsertBlockIndex(const uint256 &hash) { | CBlockIndex *CChainState::InsertBlockIndex(const uint256 &hash) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
if (hash.IsNull()) { | if (hash.IsNull()) { | ||||
return nullptr; | return nullptr; | ||||
▲ Show 20 Lines • Show All 122 Lines • ▼ Show 20 Lines | bool static LoadBlockIndexDB(const Config &config) { | ||||
for (const std::pair<const uint256, CBlockIndex *> &item : mapBlockIndex) { | for (const std::pair<const uint256, CBlockIndex *> &item : mapBlockIndex) { | ||||
CBlockIndex *pindex = item.second; | CBlockIndex *pindex = item.second; | ||||
if (pindex->nStatus.hasData()) { | if (pindex->nStatus.hasData()) { | ||||
setBlkDataFiles.insert(pindex->nFile); | setBlkDataFiles.insert(pindex->nFile); | ||||
} | } | ||||
} | } | ||||
for (const int i : setBlkDataFiles) { | for (const int i : setBlkDataFiles) { | ||||
CDiskBlockPos pos(i, 0); | FlatFilePos pos(i, 0); | ||||
if (CAutoFile(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION) | if (CAutoFile(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION) | ||||
.IsNull()) { | .IsNull()) { | ||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
// Check whether we have ever pruned block & undo files | // Check whether we have ever pruned block & undo files | ||||
pblocktree->ReadFlag("prunedblockfiles", fHavePruned); | pblocktree->ReadFlag("prunedblockfiles", fHavePruned); | ||||
▲ Show 20 Lines • Show All 481 Lines • ▼ Show 20 Lines | bool CChainState::LoadGenesisBlock(const CChainParams &chainparams) { | ||||
// set based on the coins db, not the block index db, which is the only | // set based on the coins db, not the block index db, which is the only | ||||
// thing loaded at this point. | // thing loaded at this point. | ||||
if (mapBlockIndex.count(chainparams.GenesisBlock().GetHash())) { | if (mapBlockIndex.count(chainparams.GenesisBlock().GetHash())) { | ||||
return true; | return true; | ||||
} | } | ||||
try { | try { | ||||
CBlock &block = const_cast<CBlock &>(chainparams.GenesisBlock()); | CBlock &block = const_cast<CBlock &>(chainparams.GenesisBlock()); | ||||
CDiskBlockPos blockPos = | FlatFilePos blockPos = SaveBlockToDisk(block, 0, chainparams, nullptr); | ||||
SaveBlockToDisk(block, 0, chainparams, nullptr); | |||||
if (blockPos.IsNull()) { | if (blockPos.IsNull()) { | ||||
return error("%s: writing genesis block to disk failed", __func__); | return error("%s: writing genesis block to disk failed", __func__); | ||||
} | } | ||||
CBlockIndex *pindex = AddToBlockIndex(block); | CBlockIndex *pindex = AddToBlockIndex(block); | ||||
CValidationState state; | CValidationState state; | ||||
if (!ReceivedBlockTransactions(block, state, pindex, blockPos)) { | if (!ReceivedBlockTransactions(block, state, pindex, blockPos)) { | ||||
return error("%s: genesis block not accepted", __func__); | return error("%s: genesis block not accepted", __func__); | ||||
} | } | ||||
} catch (const std::runtime_error &e) { | } catch (const std::runtime_error &e) { | ||||
return error("%s: failed to write genesis block: %s", __func__, | return error("%s: failed to write genesis block: %s", __func__, | ||||
e.what()); | e.what()); | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
bool LoadGenesisBlock(const CChainParams &chainparams) { | bool LoadGenesisBlock(const CChainParams &chainparams) { | ||||
return g_chainstate.LoadGenesisBlock(chainparams); | return g_chainstate.LoadGenesisBlock(chainparams); | ||||
} | } | ||||
bool LoadExternalBlockFile(const Config &config, FILE *fileIn, | bool LoadExternalBlockFile(const Config &config, FILE *fileIn, | ||||
CDiskBlockPos *dbp) { | FlatFilePos *dbp) { | ||||
// Map of disk positions for blocks with unknown parent (only used for | // Map of disk positions for blocks with unknown parent (only used for | ||||
// reindex) | // reindex) | ||||
static std::multimap<uint256, CDiskBlockPos> mapBlocksUnknownParent; | static std::multimap<uint256, FlatFilePos> mapBlocksUnknownParent; | ||||
int64_t nStart = GetTimeMillis(); | int64_t nStart = GetTimeMillis(); | ||||
const CChainParams &chainparams = config.GetChainParams(); | const CChainParams &chainparams = config.GetChainParams(); | ||||
int nLoaded = 0; | int nLoaded = 0; | ||||
try { | try { | ||||
// This takes over fileIn and calls fclose() on it in the CBufferedFile | // This takes over fileIn and calls fclose() on it in the CBufferedFile | ||||
// destructor. Make sure we have at least 2*MAX_TX_SIZE space in there | // destructor. Make sure we have at least 2*MAX_TX_SIZE space in there | ||||
▲ Show 20 Lines • Show All 96 Lines • ▼ Show 20 Lines | try { | ||||
// Recursively process earlier encountered successors of this | // Recursively process earlier encountered successors of this | ||||
// block | // block | ||||
std::deque<uint256> queue; | std::deque<uint256> queue; | ||||
queue.push_back(hash); | queue.push_back(hash); | ||||
while (!queue.empty()) { | while (!queue.empty()) { | ||||
uint256 head = queue.front(); | uint256 head = queue.front(); | ||||
queue.pop_front(); | queue.pop_front(); | ||||
std::pair<std::multimap<uint256, CDiskBlockPos>::iterator, | std::pair<std::multimap<uint256, FlatFilePos>::iterator, | ||||
std::multimap<uint256, CDiskBlockPos>::iterator> | std::multimap<uint256, FlatFilePos>::iterator> | ||||
range = mapBlocksUnknownParent.equal_range(head); | range = mapBlocksUnknownParent.equal_range(head); | ||||
while (range.first != range.second) { | while (range.first != range.second) { | ||||
std::multimap<uint256, CDiskBlockPos>::iterator it = | std::multimap<uint256, FlatFilePos>::iterator it = | ||||
range.first; | range.first; | ||||
std::shared_ptr<CBlock> pblockrecursive = | std::shared_ptr<CBlock> pblockrecursive = | ||||
std::make_shared<CBlock>(); | std::make_shared<CBlock>(); | ||||
if (ReadBlockFromDisk(*pblockrecursive, it->second, | if (ReadBlockFromDisk(*pblockrecursive, it->second, | ||||
config)) { | config)) { | ||||
LogPrint( | LogPrint( | ||||
BCLog::REINDEX, | BCLog::REINDEX, | ||||
"%s: Processing out of order child %s of %s\n", | "%s: Processing out of order child %s of %s\n", | ||||
▲ Show 20 Lines • Show All 539 Lines • Show Last 20 Lines |