…efficient.
This is also an incremental step in making an index pruner for #4481
…efficient.
This is also an incremental step in making an index pruner for #4481
What if the first encountered block with file N doesn’t have undo data, but the second one does? You’d skip checking it.
EDIT: fixed
2983@@ -2984,19 +2984,30 @@ bool static LoadBlockIndexDB()
2984
2985 // Check presence of blk files
2986 LogPrintf("Checking all blk files are present...\n");
2987- set<int> setBlkDataFiles;
2988+ map<int, bool> mapBlkDataFileReadable,mapBlkUndoFileReadable;
3006@@ -3025,6 +3007,50 @@ bool static LoadBlockIndexDB()
3007 DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()),
3008 Checkpoints::GuessVerificationProgress(chainActive.Tip()));
3009
3010+ // Check presence of essential data
3011+ LogPrintf("Checking essential data is accesible...\n");
CheckForBlockFiles()
) and calling that separately. After all, this is not part of loading the block index DB.
2984+}
2985
2986+bool CheckBlockFiles()
2987+{
2988+ // Check presence of essential data
2989+ LogPrintf("Checking essential data is accesible...\n");
Checking required block data is available...
?
3021+ else
3022+ {
3023+ // Block 0 doesn't have undo data.
3024+ if (pindex->nHeight)
3025+ {
3026+ LogPrintf("Missing undo for block: %i\n", pindex->nHeight);
Error:
and also log which file exactly is missing (also a suggestion for normal block files).
3021+ else
3022+ {
3023+ // Block 0 doesn't have undo data.
3024+ if (pindex->nHeight)
3025+ {
3026+ LogPrintf("Error: Missing undo for block: %i\n", pindex->nHeight);
undo data
also fits better in here, but no need to add, if this is going to be merged soon.
2897+ // Check presence of blk files
2898+ LogPrintf("Checking all blk files are present...\n");
2899+ set<int> setRequiredDataFilesAreOpenable;
2900+ for (CBlockIndex* pindex = chainActive.Tip(); pindex && pindex->pprev; pindex = pindex->pprev) {
2901+ if (pindex->nStatus & BLOCK_HAVE_DATA && pindex->nStatus & BLOCK_HAVE_UNDO) {
2902+ if (!setRequiredDataFilesAreOpenable.count(pindex->nFile)) {
It’s not clear to me why you switched from the two-pass solution to a single loop, but from a readability viewpoint I’d prefer something like:
0std::map<int,uint32_t> mapBlkDataFiles;
1BOOST_FOREACH(const PAIRTYPE(uint256, CBlockIndex*)& item, mapBlockIndex)
2{
3 CBlockIndex* pindex = item.second;
4 mapBlkDataFiles[pindex->nFile] |= pindex->nStatus;
5}
6for (std::map<int,uint32_t>::iterator it = mapBlkDataFiles.begin(); it != mapBlkDataFiles.end(); it++)
7{
8 if ((it->second & BLOCK_HAVE_DATA) && !BlockFileIsOpenable(it->first)) {
9 LogPrintf("Error: Required block file %i can't be opened.\n", it->first);
10 return false;
11 }
12 if ((it->second & BLOCK_HAVE_UNDO) && !UndoFileIsOpenable(it->first)) {
13 LogPrintf("Error: Required undo file %i can't be opened.\n", it->first);
14 return false;
15 }
16}
2872@@ -2891,6 +2873,48 @@ bool static LoadBlockIndexDB()
2873 return true;
2874 }
2875
2876+bool BlockFileIsOpenable(int nFile)
172@@ -173,6 +173,8 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp = NULL);
173 bool InitBlockIndex();
174 /** Load the block tree and coins database from disk */
175 bool LoadBlockIndex();
176+/** Check all required block files are present */
0/** Check all required block and undo files are present */