diff options
Diffstat (limited to 'src/main.cpp')
-rw-r--r-- | src/main.cpp | 126 |
1 files changed, 71 insertions, 55 deletions
diff --git a/src/main.cpp b/src/main.cpp index ce1211cca5..82d52913a0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -106,7 +106,7 @@ namespace { multimap<CBlockIndex*, CBlockIndex*> mapBlocksUnlinked; CCriticalSection cs_LastBlockFile; - CBlockFileInfo infoLastBlockFile; + std::vector<CBlockFileInfo> vinfoBlockFile; int nLastBlockFile = 0; // Every received block is assigned a unique and increasing identifier, so we @@ -128,6 +128,8 @@ namespace { }; map<uint256, pair<NodeId, list<QueuedBlock>::iterator> > mapBlocksInFlight; + // Number of preferrable block download peers. + int nPreferredDownload = 0; } // anon namespace ////////////////////////////////////////////////////////////////////////////// @@ -230,6 +232,8 @@ struct CNodeState { int64_t nStallingSince; list<QueuedBlock> vBlocksInFlight; int nBlocksInFlight; + // Whether we consider this a preferred download peer. + bool fPreferredDownload; CNodeState() { nMisbehavior = 0; @@ -240,6 +244,7 @@ struct CNodeState { fSyncStarted = false; nStallingSince = 0; nBlocksInFlight = 0; + fPreferredDownload = false; } }; @@ -260,6 +265,16 @@ int GetHeight() return chainActive.Height(); } +void UpdatePreferredDownload(CNode* node, CNodeState* state) +{ + nPreferredDownload -= state->fPreferredDownload; + + // Whether this node should be marked as a preferred download node. + state->fPreferredDownload = (!node->fInbound || node->fWhitelisted) && !node->fOneShot && !node->fClient; + + nPreferredDownload += state->fPreferredDownload; +} + void InitializeNode(NodeId nodeid, const CNode *pnode) { LOCK(cs_main); CNodeState &state = mapNodeState.insert(std::make_pair(nodeid, CNodeState())).first->second; @@ -276,6 +291,7 @@ void FinalizeNode(NodeId nodeid) { BOOST_FOREACH(const QueuedBlock& entry, state->vBlocksInFlight) mapBlocksInFlight.erase(entry.hash); EraseOrphansFor(nodeid); + nPreferredDownload -= state->fPreferredDownload; mapNodeState.erase(nodeid); } @@ -638,10 +654,6 @@ bool IsStandardTx(const CTransaction& tx, string& reason) reason = "scriptsig-not-pushonly"; return false; } - if (!txin.scriptSig.HasCanonicalPushes()) { - reason = "scriptsig-non-canonical-push"; - return false; - } } unsigned int nDataOut = 0; @@ -1056,7 +1068,7 @@ bool GetTransaction(const uint256 &hash, CTransaction &txOut, uint256 &hashBlock CBlockHeader header; try { file >> header; - fseek(file, postx.nTxOffset, SEEK_CUR); + fseek(file.Get(), postx.nTxOffset, SEEK_CUR); file >> txOut; } catch (std::exception &e) { return error("%s : Deserialize or I/O error - %s", __func__, e.what()); @@ -1111,7 +1123,7 @@ bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos) { // Open history file to append CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION); - if (!fileout) + if (fileout.IsNull()) return error("WriteBlockToDisk : OpenBlockFile failed"); // Write index header @@ -1119,16 +1131,16 @@ bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos) fileout << FLATDATA(Params().MessageStart()) << nSize; // Write block - long fileOutPos = ftell(fileout); + long fileOutPos = ftell(fileout.Get()); if (fileOutPos < 0) return error("WriteBlockToDisk : ftell failed"); pos.nPos = (unsigned int)fileOutPos; fileout << block; // Flush stdio buffers and commit to disk before returning - fflush(fileout); + fflush(fileout.Get()); if (!IsInitialBlockDownload()) - FileCommit(fileout); + FileCommit(fileout.Get()); return true; } @@ -1139,7 +1151,7 @@ bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos) // Open history file to read CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION); - if (!filein) + if (filein.IsNull()) return error("ReadBlockFromDisk : OpenBlockFile failed"); // Read block @@ -1552,7 +1564,7 @@ void static FlushBlockFile(bool fFinalize = false) FILE *fileOld = OpenBlockFile(posOld); if (fileOld) { if (fFinalize) - TruncateFile(fileOld, infoLastBlockFile.nSize); + TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nSize); FileCommit(fileOld); fclose(fileOld); } @@ -1560,7 +1572,7 @@ void static FlushBlockFile(bool fFinalize = false) fileOld = OpenUndoFile(posOld); if (fileOld) { if (fFinalize) - TruncateFile(fileOld, infoLastBlockFile.nUndoSize); + TruncateFile(fileOld, vinfoBlockFile[nLastBlockFile].nUndoSize); FileCommit(fileOld); fclose(fileOld); } @@ -2170,32 +2182,32 @@ bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAdd LOCK(cs_LastBlockFile); - if (fKnown) { - if (nLastBlockFile != pos.nFile) { - nLastBlockFile = pos.nFile; - infoLastBlockFile.SetNull(); - pblocktree->ReadBlockFileInfo(nLastBlockFile, infoLastBlockFile); - fUpdatedLast = true; - } - } else { - while (infoLastBlockFile.nSize + nAddSize >= MAX_BLOCKFILE_SIZE) { - LogPrintf("Leaving block file %i: %s\n", nLastBlockFile, infoLastBlockFile.ToString()); + unsigned int nFile = fKnown ? pos.nFile : nLastBlockFile; + if (vinfoBlockFile.size() <= nFile) { + vinfoBlockFile.resize(nFile + 1); + } + + if (!fKnown) { + while (vinfoBlockFile[nFile].nSize + nAddSize >= MAX_BLOCKFILE_SIZE) { + LogPrintf("Leaving block file %i: %s\n", nFile, vinfoBlockFile[nFile].ToString()); FlushBlockFile(true); - nLastBlockFile++; - infoLastBlockFile.SetNull(); - pblocktree->ReadBlockFileInfo(nLastBlockFile, infoLastBlockFile); // check whether data for the new file somehow already exist; can fail just fine + nFile++; + if (vinfoBlockFile.size() <= nFile) { + vinfoBlockFile.resize(nFile + 1); + } fUpdatedLast = true; } - pos.nFile = nLastBlockFile; - pos.nPos = infoLastBlockFile.nSize; + pos.nFile = nFile; + pos.nPos = vinfoBlockFile[nFile].nSize; } - infoLastBlockFile.nSize += nAddSize; - infoLastBlockFile.AddBlock(nHeight, nTime); + nLastBlockFile = nFile; + vinfoBlockFile[nFile].nSize += nAddSize; + vinfoBlockFile[nFile].AddBlock(nHeight, nTime); if (!fKnown) { 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 (CheckDiskSpace(nNewChunks * BLOCKFILE_CHUNK_SIZE - pos.nPos)) { FILE *file = OpenBlockFile(pos); @@ -2210,7 +2222,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"); if (fUpdatedLast) pblocktree->WriteLastBlockFile(nLastBlockFile); @@ -2225,19 +2237,10 @@ bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigne LOCK(cs_LastBlockFile); unsigned int nNewSize; - if (nFile == nLastBlockFile) { - pos.nPos = infoLastBlockFile.nUndoSize; - nNewSize = (infoLastBlockFile.nUndoSize += nAddSize); - if (!pblocktree->WriteBlockFileInfo(nLastBlockFile, infoLastBlockFile)) - 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"); + pos.nPos = vinfoBlockFile[nFile].nUndoSize; + nNewSize = vinfoBlockFile[nFile].nUndoSize += nAddSize; + if (!pblocktree->WriteBlockFileInfo(nLastBlockFile, vinfoBlockFile[nLastBlockFile])) { + return state.Abort("Failed to write block info"); } unsigned int nOldChunks = (pos.nPos + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE; @@ -2833,9 +2836,20 @@ bool static LoadBlockIndexDB() // Load block file info pblocktree->ReadLastBlockFile(nLastBlockFile); - LogPrintf("LoadBlockIndexDB(): last block file = %i\n", nLastBlockFile); - if (pblocktree->ReadBlockFileInfo(nLastBlockFile, infoLastBlockFile)) - LogPrintf("LoadBlockIndexDB(): last block file info: %s\n", infoLastBlockFile.ToString()); + vinfoBlockFile.resize(nLastBlockFile + 1); + LogPrintf("%s: last block file = %i\n", __func__, nLastBlockFile); + 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 LogPrintf("Checking all blk files are present...\n"); @@ -2850,7 +2864,7 @@ bool static LoadBlockIndexDB() for (std::set<int>::iterator it = setBlkDataFiles.begin(); it != setBlkDataFiles.end(); it++) { CDiskBlockPos pos(*it, 0); - if (!CAutoFile(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION)) { + if (CAutoFile(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION).IsNull()) { return false; } } @@ -3480,6 +3494,8 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, pfrom->fClient = !(pfrom->nServices & NODE_NETWORK); + // Potentially mark this peer as a preferred download peer. + UpdatePreferredDownload(pfrom, State(pfrom->GetId())); // Change version pfrom->PushMessage("verack"); @@ -4424,7 +4440,7 @@ bool SendMessages(CNode* pto, bool fSendTrickle) // Start block sync if (pindexBestHeader == NULL) pindexBestHeader = chainActive.Tip(); - bool fFetch = !pto->fInbound || (pindexBestHeader && (state.pindexLastCommonBlock ? state.pindexLastCommonBlock->nHeight : 0) + 144 > pindexBestHeader->nHeight); + bool fFetch = state.fPreferredDownload || (nPreferredDownload == 0 && !pto->fClient && !pto->fOneShot); // Download if this is a nice peer, or we have no nice peers and this one might do. if (!state.fSyncStarted && !pto->fClient && fFetch && !fImporting && !fReindex) { // Only actively request headers from a single peer, unless we're close to today. if (nSyncStarted == 0 || pindexBestHeader->GetBlockTime() > GetAdjustedTime() - 24 * 60 * 60) { @@ -4555,7 +4571,7 @@ bool CBlockUndo::WriteToDisk(CDiskBlockPos &pos, const uint256 &hashBlock) { // Open history file to append CAutoFile fileout(OpenUndoFile(pos), SER_DISK, CLIENT_VERSION); - if (!fileout) + if (fileout.IsNull()) return error("CBlockUndo::WriteToDisk : OpenUndoFile failed"); // Write index header @@ -4563,7 +4579,7 @@ bool CBlockUndo::WriteToDisk(CDiskBlockPos &pos, const uint256 &hashBlock) fileout << FLATDATA(Params().MessageStart()) << nSize; // Write undo data - long fileOutPos = ftell(fileout); + long fileOutPos = ftell(fileout.Get()); if (fileOutPos < 0) return error("CBlockUndo::WriteToDisk : ftell failed"); pos.nPos = (unsigned int)fileOutPos; @@ -4576,9 +4592,9 @@ bool CBlockUndo::WriteToDisk(CDiskBlockPos &pos, const uint256 &hashBlock) fileout << hasher.GetHash(); // Flush stdio buffers and commit to disk before returning - fflush(fileout); + fflush(fileout.Get()); if (!IsInitialBlockDownload()) - FileCommit(fileout); + FileCommit(fileout.Get()); return true; } @@ -4587,7 +4603,7 @@ bool CBlockUndo::ReadFromDisk(const CDiskBlockPos &pos, const uint256 &hashBlock { // Open history file to read CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION); - if (!filein) + if (filein.IsNull()) return error("CBlockUndo::ReadFromDisk : OpenBlockFile failed"); // Read block |