|
|
@ -76,6 +76,7 @@ using namespace std; |
|
|
|
* Global state |
|
|
|
*/ |
|
|
|
|
|
|
|
#define TMPFILE_START 100000000 |
|
|
|
CCriticalSection cs_main; |
|
|
|
extern uint8_t NOTARY_PUBKEY33[33]; |
|
|
|
extern int32_t KOMODO_LOADINGBLOCKS,KOMODO_LONGESTCHAIN,KOMODO_INSYNC,KOMODO_CONNECTING,KOMODO_EXTRASATOSHI; |
|
|
@ -182,8 +183,9 @@ namespace { |
|
|
|
multimap<CBlockIndex*, CBlockIndex*> mapBlocksUnlinked; |
|
|
|
|
|
|
|
CCriticalSection cs_LastBlockFile; |
|
|
|
std::vector<CBlockFileInfo> vinfoBlockFile; |
|
|
|
std::vector<CBlockFileInfo> vinfoBlockFile,tmpBlockFiles; |
|
|
|
int nLastBlockFile = 0; |
|
|
|
int nLastTmpFile = 0; |
|
|
|
/** Global flag to indicate we should check to see if there are
|
|
|
|
* block/undo files that should be deleted. Set on startup |
|
|
|
* or if we allocate more file space when we're in prune mode |
|
|
@ -3256,6 +3258,17 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin |
|
|
|
return false; |
|
|
|
fprintf(stderr,"grandfathered exception, until jan 15th 2019\n"); |
|
|
|
} |
|
|
|
if ( (pindex->nStatus & BLOCK_IN_TMPFILE) != 0 ) |
|
|
|
{ |
|
|
|
unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION); |
|
|
|
CDiskBlockPos blockPos; |
|
|
|
if (!FindBlockPos(1,state, blockPos, nBlockSize+8, pindex->GetHeight(), block.GetBlockTime(),false)) |
|
|
|
return error("ConnectBlock(): FindBlockPos failed"); |
|
|
|
if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart())) |
|
|
|
return error("ConnectBlock(): FindBlockPos failed"); |
|
|
|
pindex->nStatus &= (~BLOCK_IN_TMPFILE); |
|
|
|
fprintf(stderr,"added ht.%d copy of tmpfile\n",pindex->GetHeight()); |
|
|
|
} |
|
|
|
// verify that the view's current state corresponds to the previous block
|
|
|
|
uint256 hashPrevBlock = pindex->pprev == NULL ? uint256() : pindex->pprev->GetBlockHash(); |
|
|
|
if ( hashPrevBlock != view.GetBestBlock() ) |
|
|
@ -4550,43 +4563,57 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAddSize, unsigned int nHeight, uint64_t nTime, bool fKnown = false) |
|
|
|
bool FindBlockPos(int32_t tmpflag,CValidationState &state, CDiskBlockPos &pos, unsigned int nAddSize, unsigned int nHeight, uint64_t nTime, bool fKnown = false) |
|
|
|
{ |
|
|
|
std::vector<CBlockFileInfo> *ptr; int *lastfilep; |
|
|
|
LOCK(cs_LastBlockFile); |
|
|
|
|
|
|
|
unsigned int nFile = fKnown ? pos.nFile : nLastBlockFile; |
|
|
|
if (vinfoBlockFile.size() <= nFile) { |
|
|
|
vinfoBlockFile.resize(nFile + 1); |
|
|
|
unsigned int nFile; |
|
|
|
if ( tmpflag != 0 ) |
|
|
|
{ |
|
|
|
ptr = &tmpBlockFiles; |
|
|
|
nFile = nLastTmpFile; |
|
|
|
lastfilep = &nLastTmpFile; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
ptr = &vinfoBlockFile; |
|
|
|
lastfilep = &nLastBlockFile; |
|
|
|
nFile = fKnown ? pos.nFile : nLastBlockFile; |
|
|
|
if (vinfoBlockFile.size() <= nFile) { |
|
|
|
vinfoBlockFile.resize(nFile + 1); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (!fKnown) { |
|
|
|
while (vinfoBlockFile[nFile].nSize + nAddSize >= MAX_BLOCKFILE_SIZE) { |
|
|
|
while ((*ptr)[nFile].nSize + nAddSize >= MAX_BLOCKFILE_SIZE) { |
|
|
|
nFile++; |
|
|
|
if (vinfoBlockFile.size() <= nFile) { |
|
|
|
vinfoBlockFile.resize(nFile + 1); |
|
|
|
if ((*ptr).size() <= nFile) { |
|
|
|
(*ptr).resize(nFile + 1); |
|
|
|
} |
|
|
|
} |
|
|
|
pos.nFile = nFile; |
|
|
|
pos.nPos = vinfoBlockFile[nFile].nSize; |
|
|
|
pos.nFile = nFile + tmpflag*TMPFILE_START; |
|
|
|
pos.nPos = (*ptr)[nFile].nSize; |
|
|
|
if ( tmpflag != 0 ) |
|
|
|
fprintf(stderr,"pos.nFile %d nPos %u\n",pos.nFile,pos.nPos); |
|
|
|
} |
|
|
|
|
|
|
|
if (nFile != nLastBlockFile) { |
|
|
|
if (nFile != *lastfilep) { |
|
|
|
if (!fKnown) { |
|
|
|
LogPrintf("Leaving block file %i: %s\n", nFile, vinfoBlockFile[nFile].ToString()); |
|
|
|
LogPrintf("Leaving block file %i: %s\n", nFile, (*ptr)[nFile].ToString()); |
|
|
|
} |
|
|
|
FlushBlockFile(!fKnown); |
|
|
|
nLastBlockFile = nFile; |
|
|
|
*lastfilep = nFile; |
|
|
|
} |
|
|
|
|
|
|
|
vinfoBlockFile[nFile].AddBlock(nHeight, nTime); |
|
|
|
(*ptr)[nFile].AddBlock(nHeight, nTime); |
|
|
|
if (fKnown) |
|
|
|
vinfoBlockFile[nFile].nSize = std::max(pos.nPos + nAddSize, vinfoBlockFile[nFile].nSize); |
|
|
|
(*ptr)[nFile].nSize = std::max(pos.nPos + nAddSize, (*ptr)[nFile].nSize); |
|
|
|
else |
|
|
|
vinfoBlockFile[nFile].nSize += nAddSize; |
|
|
|
(*ptr)[nFile].nSize += nAddSize; |
|
|
|
|
|
|
|
if (!fKnown) { |
|
|
|
unsigned int nOldChunks = (pos.nPos + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE; |
|
|
|
unsigned int nNewChunks = (vinfoBlockFile[nFile].nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE; |
|
|
|
unsigned int nNewChunks = ((*ptr)[nFile].nSize + BLOCKFILE_CHUNK_SIZE - 1) / BLOCKFILE_CHUNK_SIZE; |
|
|
|
if (nNewChunks > nOldChunks) { |
|
|
|
if (fPruneMode) |
|
|
|
fCheckForPruning = true; |
|
|
@ -4603,12 +4630,17 @@ bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAdd |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
setDirtyFileInfo.insert(nFile); |
|
|
|
setDirtyFileInfo.insert(nFile + tmpflag*TMPFILE_START); |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigned int nAddSize) |
|
|
|
{ |
|
|
|
if ( nFile >= TMPFILE_START ) |
|
|
|
{ |
|
|
|
fprintf(stderr,"FindUndoPos unexpected tmpfile %d\n",nFile); |
|
|
|
return(false); |
|
|
|
} |
|
|
|
pos.nFile = nFile; |
|
|
|
|
|
|
|
LOCK(cs_LastBlockFile); |
|
|
@ -5171,13 +5203,14 @@ bool AcceptBlock(int32_t *futureblockp,CBlock& block, CValidationState& state, C |
|
|
|
CDiskBlockPos blockPos; |
|
|
|
if (dbp != NULL) |
|
|
|
blockPos = *dbp; |
|
|
|
if (!FindBlockPos(state, blockPos, nBlockSize+8, nHeight, block.GetBlockTime(), dbp != NULL)) |
|
|
|
if (!FindBlockPos(1,state, blockPos, nBlockSize+8, nHeight, block.GetBlockTime(), dbp != NULL)) |
|
|
|
return error("AcceptBlock(): FindBlockPos failed"); |
|
|
|
if (dbp == NULL) |
|
|
|
if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart())) |
|
|
|
AbortNode(state, "Failed to write block"); |
|
|
|
if (!ReceivedBlockTransactions(block, state, pindex, blockPos)) |
|
|
|
return error("AcceptBlock(): ReceivedBlockTransactions failed"); |
|
|
|
pindex->nStatus |= BLOCK_IN_TMPFILE; |
|
|
|
} catch (const std::runtime_error& e) { |
|
|
|
return AbortNode(state, std::string("System error: ") + e.what()); |
|
|
|
} |
|
|
@ -5495,7 +5528,7 @@ bool CheckDiskSpace(uint64_t nAdditionalBytes) |
|
|
|
|
|
|
|
FILE* OpenDiskFile(const CDiskBlockPos &pos, const char *prefix, bool fReadOnly) |
|
|
|
{ |
|
|
|
static int32_t didinit[64]; |
|
|
|
static int32_t didinit[256]; |
|
|
|
if (pos.IsNull()) |
|
|
|
return NULL; |
|
|
|
boost::filesystem::path path = GetBlockPosFilename(pos, prefix); |
|
|
@ -6002,6 +6035,7 @@ void UnloadBlockIndex() |
|
|
|
nSyncStarted = 0; |
|
|
|
mapBlocksUnlinked.clear(); |
|
|
|
vinfoBlockFile.clear(); |
|
|
|
tmpBlockFiles.clear(); |
|
|
|
nLastBlockFile = 0; |
|
|
|
nBlockSequenceId = 1; |
|
|
|
mapBlockSource.clear(); |
|
|
@ -6037,6 +6071,7 @@ bool LoadBlockIndex() |
|
|
|
bool InitBlockIndex() { |
|
|
|
const CChainParams& chainparams = Params(); |
|
|
|
LOCK(cs_main); |
|
|
|
tmpBlockFiles.clear(); |
|
|
|
|
|
|
|
// Initialize global variables that cannot be constructed at startup.
|
|
|
|
recentRejects.reset(new CRollingBloomFilter(120000, 0.000001)); |
|
|
@ -6069,7 +6104,7 @@ bool InitBlockIndex() { |
|
|
|
unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION); |
|
|
|
CDiskBlockPos blockPos; |
|
|
|
CValidationState state; |
|
|
|
if (!FindBlockPos(state, blockPos, nBlockSize+8, 0, block.GetBlockTime())) |
|
|
|
if (!FindBlockPos(0,state, blockPos, nBlockSize+8, 0, block.GetBlockTime())) |
|
|
|
return error("LoadBlockIndex(): FindBlockPos failed"); |
|
|
|
if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart())) |
|
|
|
return error("LoadBlockIndex(): writing genesis block to disk failed"); |
|
|
|