|
|
@ -106,7 +106,7 @@ namespace { |
|
|
|
multimap<CBlockIndex*, CBlockIndex*> mapBlocksUnlinked; |
|
|
|
multimap<CBlockIndex*, CBlockIndex*> mapBlocksUnlinked; |
|
|
|
|
|
|
|
|
|
|
|
CCriticalSection cs_LastBlockFile; |
|
|
|
CCriticalSection cs_LastBlockFile; |
|
|
|
CBlockFileInfo infoLastBlockFile; |
|
|
|
std::vector<CBlockFileInfo> vinfoBlockFile; |
|
|
|
int nLastBlockFile = 0; |
|
|
|
int nLastBlockFile = 0; |
|
|
|
|
|
|
|
|
|
|
|
// Every received block is assigned a unique and increasing identifier, so we
|
|
|
|
// Every received block is assigned a unique and increasing identifier, so we
|
|
|
@ -1547,7 +1547,7 @@ void static FlushBlockFile(bool fFinalize = false) |
|
|
|
FILE *fileOld = OpenBlockFile(posOld); |
|
|
|
FILE *fileOld = OpenBlockFile(posOld); |
|
|
|
if (fileOld) { |
|
|
|
if (fileOld) { |
|
|
|
if (fFinalize) |
|
|
|
if (fFinalize) |
|
|
|
TruncateFile(fileOld, infoLastBlockFile.nSize); |
|
|
|
TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nSize); |
|
|
|
FileCommit(fileOld); |
|
|
|
FileCommit(fileOld); |
|
|
|
fclose(fileOld); |
|
|
|
fclose(fileOld); |
|
|
|
} |
|
|
|
} |
|
|
@ -1555,7 +1555,7 @@ void static FlushBlockFile(bool fFinalize = false) |
|
|
|
fileOld = OpenUndoFile(posOld); |
|
|
|
fileOld = OpenUndoFile(posOld); |
|
|
|
if (fileOld) { |
|
|
|
if (fileOld) { |
|
|
|
if (fFinalize) |
|
|
|
if (fFinalize) |
|
|
|
TruncateFile(fileOld, infoLastBlockFile.nUndoSize); |
|
|
|
TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nUndoSize); |
|
|
|
FileCommit(fileOld); |
|
|
|
FileCommit(fileOld); |
|
|
|
fclose(fileOld); |
|
|
|
fclose(fileOld); |
|
|
|
} |
|
|
|
} |
|
|
@ -2163,32 +2163,32 @@ bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAdd |
|
|
|
|
|
|
|
|
|
|
|
LOCK(cs_LastBlockFile); |
|
|
|
LOCK(cs_LastBlockFile); |
|
|
|
|
|
|
|
|
|
|
|
if (fKnown) { |
|
|
|
unsigned int nFile = fKnown ? pos.nFile : nLastBlockFile; |
|
|
|
if (nLastBlockFile != pos.nFile) { |
|
|
|
if (vinfoBlockFile.size() <= nFile) { |
|
|
|
nLastBlockFile = pos.nFile; |
|
|
|
vinfoBlockFile.resize(nFile + 1); |
|
|
|
infoLastBlockFile.SetNull(); |
|
|
|
} |
|
|
|
pblocktree->ReadBlockFileInfo(nLastBlockFile, infoLastBlockFile); |
|
|
|
|
|
|
|
fUpdatedLast = true; |
|
|
|
if (!fKnown) { |
|
|
|
} |
|
|
|
while (vinfoBlockFile[nFile].nSize + nAddSize >= MAX_BLOCKFILE_SIZE) { |
|
|
|
} else { |
|
|
|
LogPrintf("Leaving block file %i: %s\n", nFile, vinfoBlockFile[nFile].ToString()); |
|
|
|
while (infoLastBlockFile.nSize + nAddSize >= MAX_BLOCKFILE_SIZE) { |
|
|
|
|
|
|
|
LogPrintf("Leaving block file %i: %s\n", nLastBlockFile, infoLastBlockFile.ToString()); |
|
|
|
|
|
|
|
FlushBlockFile(true); |
|
|
|
FlushBlockFile(true); |
|
|
|
nLastBlockFile++; |
|
|
|
nFile++; |
|
|
|
infoLastBlockFile.SetNull(); |
|
|
|
if (vinfoBlockFile.size() <= nFile) { |
|
|
|
pblocktree->ReadBlockFileInfo(nLastBlockFile, infoLastBlockFile); // check whether data for the new file somehow already exist; can fail just fine
|
|
|
|
vinfoBlockFile.resize(nFile + 1); |
|
|
|
|
|
|
|
} |
|
|
|
fUpdatedLast = true; |
|
|
|
fUpdatedLast = true; |
|
|
|
} |
|
|
|
} |
|
|
|
pos.nFile = nLastBlockFile; |
|
|
|
pos.nFile = nFile; |
|
|
|
pos.nPos = infoLastBlockFile.nSize; |
|
|
|
pos.nPos = vinfoBlockFile[nFile].nSize; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
infoLastBlockFile.nSize += nAddSize; |
|
|
|
nLastBlockFile = nFile; |
|
|
|
infoLastBlockFile.AddBlock(nHeight, nTime); |
|
|
|
vinfoBlockFile[nFile].nSize += nAddSize; |
|
|
|
|
|
|
|
vinfoBlockFile[nFile].AddBlock(nHeight, nTime); |
|
|
|
|
|
|
|
|
|
|
|
if (!fKnown) { |
|
|
|
if (!fKnown) { |
|
|
|
unsigned int nOldChunks = (pos.nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE; |
|
|
|
unsigned int nOldChunks = (pos.nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE; |
|
|
|
unsigned int nNewChunks = (infoLastBlockFile.nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE; |
|
|
|
unsigned int nNewChunks = (vinfoBlockFile[nFile].nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE; |
|
|
|
if (nNewChunks > nOldChunks) { |
|
|
|
if (nNewChunks > nOldChunks) { |
|
|
|
if (CheckDiskSpace(nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos)) { |
|
|
|
if (CheckDiskSpace(nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos)) { |
|
|
|
FILE *file = OpenBlockFile(pos); |
|
|
|
FILE *file = OpenBlockFile(pos); |
|
|
@ -2203,7 +2203,7 @@ bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAdd |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!pblocktree->WriteBlockFileInfo(nLastBlockFile, infoLastBlockFile)) |
|
|
|
if (!pblocktree->WriteBlockFileInfo(nLastBlockFile, vinfoBlockFile[nFile])) |
|
|
|
return state.Abort("Failed to write file info"); |
|
|
|
return state.Abort("Failed to write file info"); |
|
|
|
if (fUpdatedLast) |
|
|
|
if (fUpdatedLast) |
|
|
|
pblocktree->WriteLastBlockFile(nLastBlockFile); |
|
|
|
pblocktree->WriteLastBlockFile(nLastBlockFile); |
|
|
@ -2218,19 +2218,10 @@ bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigne |
|
|
|
LOCK(cs_LastBlockFile); |
|
|
|
LOCK(cs_LastBlockFile); |
|
|
|
|
|
|
|
|
|
|
|
unsigned int nNewSize; |
|
|
|
unsigned int nNewSize; |
|
|
|
if (nFile == nLastBlockFile) { |
|
|
|
pos.nPos = vinfoBlockFile[nFile].nUndoSize; |
|
|
|
pos.nPos = infoLastBlockFile.nUndoSize; |
|
|
|
nNewSize = vinfoBlockFile[nFile].nUndoSize += nAddSize; |
|
|
|
nNewSize = (infoLastBlockFile.nUndoSize += nAddSize); |
|
|
|
if (!pblocktree->WriteBlockFileInfo(nLastBlockFile, vinfoBlockFile[nLastBlockFile])) { |
|
|
|
if (!pblocktree->WriteBlockFileInfo(nLastBlockFile, infoLastBlockFile)) |
|
|
|
return state.Abort("Failed to write block info"); |
|
|
|
return state.Abort("Failed to write block info"); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
CBlockFileInfo info; |
|
|
|
|
|
|
|
if (!pblocktree->ReadBlockFileInfo(nFile, info)) |
|
|
|
|
|
|
|
return state.Abort("Failed to read block info"); |
|
|
|
|
|
|
|
pos.nPos = info.nUndoSize; |
|
|
|
|
|
|
|
nNewSize = (info.nUndoSize += nAddSize); |
|
|
|
|
|
|
|
if (!pblocktree->WriteBlockFileInfo(nFile, info)) |
|
|
|
|
|
|
|
return state.Abort("Failed to write block info"); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
unsigned int nOldChunks = (pos.nPos + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE; |
|
|
|
unsigned int nOldChunks = (pos.nPos + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE; |
|
|
@ -2826,9 +2817,20 @@ bool static LoadBlockIndexDB() |
|
|
|
|
|
|
|
|
|
|
|
// Load block file info
|
|
|
|
// Load block file info
|
|
|
|
pblocktree->ReadLastBlockFile(nLastBlockFile); |
|
|
|
pblocktree->ReadLastBlockFile(nLastBlockFile); |
|
|
|
LogPrintf("LoadBlockIndexDB(): last block file = %i\n", nLastBlockFile); |
|
|
|
vinfoBlockFile.resize(nLastBlockFile + 1); |
|
|
|
if (pblocktree->ReadBlockFileInfo(nLastBlockFile, infoLastBlockFile)) |
|
|
|
LogPrintf("%s: last block file = %i\n", __func__, nLastBlockFile); |
|
|
|
LogPrintf("LoadBlockIndexDB(): last block file info: %s\n", infoLastBlockFile.ToString()); |
|
|
|
for (int nFile = 0; nFile <= nLastBlockFile; nFile++) { |
|
|
|
|
|
|
|
pblocktree->ReadBlockFileInfo(nFile, vinfoBlockFile[nFile]); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
LogPrintf("%s: last block file info: %s\n", __func__, vinfoBlockFile[nLastBlockFile].ToString()); |
|
|
|
|
|
|
|
for (int nFile = nLastBlockFile + 1; true; nFile++) { |
|
|
|
|
|
|
|
CBlockFileInfo info; |
|
|
|
|
|
|
|
if (pblocktree->ReadBlockFileInfo(nFile, info)) { |
|
|
|
|
|
|
|
vinfoBlockFile.push_back(info); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Check presence of blk files
|
|
|
|
// Check presence of blk files
|
|
|
|
LogPrintf("Checking all blk files are present...\n"); |
|
|
|
LogPrintf("Checking all blk files are present...\n"); |
|
|
|