X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fmain.cpp;h=b345ef3247bb75da910ccef8aedbbe45c8db7d1b;hb=60cf27d9500deb3bc80ffa8ce5dc3e8284a4c658;hp=bdc7e8d6d3e55029aba4a490d78b86ca25986a39;hpb=d5c96395c728154d40d426cdac4b9221416b64e8;p=novacoin.git diff --git a/src/main.cpp b/src/main.cpp index bdc7e8d..b345ef3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -6,17 +6,18 @@ #include "alert.h" #include "checkpoints.h" #include "db.h" -#include "txdb.h" +#include "txdb-leveldb.h" #include "init.h" -#include "ui_interface.h" +#include "interface.h" #include "checkqueue.h" #include "kernel.h" -#include #include #include #include "main.h" +#include + using namespace std; using namespace boost; @@ -80,7 +81,6 @@ int64_t nMinimumInputValue = MIN_TXOUT_AMOUNT; // Ping and address broadcast intervals int64_t nPingInterval = 30 * 60; -int64_t nBroadcastInterval = nOneDay; extern enum Checkpoints::CPMode CheckpointsMode; @@ -111,25 +111,16 @@ void UnregisterWallet(CWallet* pwalletIn) // check whether the passed transaction is from us bool static IsFromMe(CTransaction& tx) { - BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) + for (CWallet* pwallet : setpwalletRegistered) if (pwallet->IsFromMe(tx)) return true; return false; } -// get the wallet transaction with the given hash (if it exists) -bool static GetTransaction(const uint256& hashTx, CWalletTx& wtx) -{ - BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) - if (pwallet->GetTransaction(hashTx,wtx)) - return true; - return false; -} - // erases transaction with the given hash from all wallets void static EraseFromWallets(uint256 hash) { - BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) + for (CWallet* pwallet : setpwalletRegistered) pwallet->EraseFromWallet(hash); } @@ -141,49 +132,49 @@ void SyncWithWallets(const CTransaction& tx, const CBlock* pblock, bool fUpdate, // wallets need to refund inputs when disconnecting coinstake if (tx.IsCoinStake()) { - BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) + for (CWallet* pwallet : setpwalletRegistered) if (pwallet->IsFromMe(tx)) pwallet->DisableTransaction(tx); } return; } - BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) + for (CWallet* pwallet : setpwalletRegistered) pwallet->AddToWalletIfInvolvingMe(tx, pblock, fUpdate); } // notify wallets about a new best chain void static SetBestChain(const CBlockLocator& loc) { - BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) + for (CWallet* pwallet : setpwalletRegistered) pwallet->SetBestChain(loc); } // notify wallets about an updated transaction void static UpdatedTransaction(const uint256& hashTx) { - BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) + for (CWallet* pwallet : setpwalletRegistered) pwallet->UpdatedTransaction(hashTx); } // dump all wallets void static PrintWallets(const CBlock& block) { - BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) + for (CWallet* pwallet : setpwalletRegistered) pwallet->PrintWallet(block); } // notify wallets about an incoming inventory (for request counts) void static Inventory(const uint256& hash) { - BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) + for (CWallet* pwallet : setpwalletRegistered) pwallet->Inventory(hash); } // ask wallets to resend their transactions void ResendWalletTransactions(bool fForceResend) { - BOOST_FOREACH(CWallet* pwallet, setpwalletRegistered) + for (CWallet* pwallet : setpwalletRegistered) pwallet->ResendWalletTransactions(fForceResend); } @@ -221,7 +212,7 @@ bool AddOrphanTx(const CTransaction& tx) } mapOrphanTransactions[hash] = tx; - BOOST_FOREACH(const CTxIn& txin, tx.vin) + for (const CTxIn& txin : tx.vin) mapOrphanTransactionsByPrev[txin.prevout.hash].insert(hash); printf("stored orphan tx %s (mapsz %" PRIszu ")\n", hash.ToString().substr(0,10).c_str(), @@ -234,7 +225,7 @@ void static EraseOrphanTx(uint256 hash) if (!mapOrphanTransactions.count(hash)) return; const CTransaction& tx = mapOrphanTransactions[hash]; - BOOST_FOREACH(const CTxIn& txin, tx.vin) + for (const CTxIn& txin : tx.vin) { mapOrphanTransactionsByPrev[txin.prevout.hash].erase(hash); if (mapOrphanTransactionsByPrev[txin.prevout.hash].empty()) @@ -308,7 +299,7 @@ bool CTransaction::IsStandard(string& strReason) const unsigned int nDataOut = 0; txnouttype whichType; - BOOST_FOREACH(const CTxIn& txin, vin) + for (const CTxIn& txin : vin) { // Biggest 'standard' txin is a 15-of-15 P2SH multisig with compressed // keys. (remember the 520 byte limit on redeemScript size) That works @@ -332,7 +323,7 @@ bool CTransaction::IsStandard(string& strReason) const return false; } } - BOOST_FOREACH(const CTxOut& txout, vout) { + for (const CTxOut& txout : vout) { if (!::IsStandard(txout.scriptPubKey, whichType)) { strReason = "scriptpubkey"; return false; @@ -433,19 +424,18 @@ CTransaction::GetLegacySigOpCount() const { // Coinbase scriptsigs are never executed, so there is // no sense in calculation of sigops. - BOOST_FOREACH(const CTxIn& txin, vin) + for (const CTxIn& txin : vin) { nSigOps += txin.scriptSig.GetSigOpCount(false); } } - BOOST_FOREACH(const CTxOut& txout, vout) + for (const CTxOut& txout : vout) { nSigOps += txout.scriptPubKey.GetSigOpCount(false); } return nSigOps; } - int CMerkleTx::SetMerkleBranch(const CBlock* pblock) { if (fClient) @@ -456,6 +446,7 @@ int CMerkleTx::SetMerkleBranch(const CBlock* pblock) else { CBlock blockTmp; + if (pblock == NULL) { // Load the block this tx is in @@ -490,19 +481,13 @@ int CMerkleTx::SetMerkleBranch(const CBlock* pblock) map::iterator mi = mapBlockIndex.find(hashBlock); if (mi == mapBlockIndex.end()) return 0; - CBlockIndex* pindex = (*mi).second; + const CBlockIndex* pindex = (*mi).second; if (!pindex || !pindex->IsInMainChain()) return 0; return pindexBest->nHeight - pindex->nHeight + 1; } - - - - - - bool CTransaction::CheckTransaction() const { // Basic checks that don't depend on any context @@ -533,7 +518,7 @@ bool CTransaction::CheckTransaction() const // Check for duplicate inputs set vInOutPoints; - BOOST_FOREACH(const CTxIn& txin, vin) + for (const CTxIn& txin : vin) { if (vInOutPoints.count(txin.prevout)) return false; @@ -547,7 +532,7 @@ bool CTransaction::CheckTransaction() const } else { - BOOST_FOREACH(const CTxIn& txin, vin) + for (const CTxIn& txin : vin) if (txin.prevout.IsNull()) return DoS(10, error("CTransaction::CheckTransaction() : prevout is null")); } @@ -593,7 +578,7 @@ int64_t CTransaction::GetMinFee(unsigned int nBlockSize, bool fAllowFree, enum G // // It's safe to ignore empty outputs here, because these inputs are allowed // only for coinbase and coinstake transactions. - BOOST_FOREACH(const CTxOut& txout, vout) + for (const CTxOut& txout : vout) if (txout.nValue < CENT && !txout.IsEmpty()) nMinFee += nBaseFee; @@ -795,7 +780,7 @@ bool CTxMemPool::remove(CTransaction &tx) uint256 hash = tx.GetHash(); if (mapTx.count(hash)) { - BOOST_FOREACH(const CTxIn& txin, tx.vin) + for (const CTxIn& txin : tx.vin) mapNextTx.erase(txin.prevout); mapTx.erase(hash); nTransactionsUpdated++; @@ -887,7 +872,7 @@ bool CWalletTx::AcceptWalletTransaction(CTxDB& txdb, bool fCheckInputs) { LOCK(mempool.cs); // Add previous supporting transactions first - BOOST_FOREACH(CMerkleTx& tx, vtxPrev) + for (CMerkleTx& tx : vtxPrev) { if (!(tx.IsCoinBase() || tx.IsCoinStake())) { @@ -1300,7 +1285,7 @@ bool CTransaction::DisconnectInputs(CTxDB& txdb) // Relinquish previous transactions' spent pointers if (!IsCoinBase()) { - BOOST_FOREACH(const CTxIn& txin, vin) + for (const CTxIn& txin : vin) { COutPoint prevout = txin.prevout; @@ -1658,7 +1643,7 @@ bool CBlock::DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex) } // ppcoin: clean up wallet after disconnecting coinstake - BOOST_FOREACH(CTransaction& tx, vtx) + for (CTransaction& tx : vtx) SyncWithWallets(tx, this, false, false); return true; @@ -1714,14 +1699,14 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) int64_t nValueIn = 0; int64_t nValueOut = 0; unsigned int nSigOps = 0; - BOOST_FOREACH(CTransaction& tx, vtx) + for (CTransaction& tx : vtx) { uint256 hashTx = tx.GetHash(); if (fEnforceBIP30) { CTxIndex txindexOld; if (txdb.ReadTxIndex(hashTx, txindexOld)) { - BOOST_FOREACH(CDiskTxPos &pos, txindexOld.vSpent) + for (CDiskTxPos &pos : txindexOld.vSpent) if (pos.IsNull()) return false; } @@ -1762,8 +1747,10 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) if (tx.nTime >= CHECKLOCKTIMEVERIFY_SWITCH_TIME) { nFlags |= SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY; - // OP_CHECKSEQUENCEVERIFY is senseless without BIP68, so we're going disable it for now. - // nFlags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY; + } + + if (tx.nTime >= CHECKSEQUENCEVERIFY_SWITCH_TIME) { + nFlags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY; } std::vector vChecks; @@ -1821,7 +1808,7 @@ bool CBlock::ConnectBlock(CTxDB& txdb, CBlockIndex* pindex, bool fJustCheck) } // Watch for transactions paying to me - BOOST_FOREACH(CTransaction& tx, vtx) + for (CTransaction& tx : vtx) SyncWithWallets(tx, this, true); @@ -1838,11 +1825,11 @@ bool static Reorganize(CTxDB& txdb, CBlockIndex* pindexNew) while (pfork != plonger) { while (plonger->nHeight > pfork->nHeight) - if (!(plonger = plonger->pprev)) + if ((plonger = plonger->pprev) == NULL) return error("Reorganize() : plonger->pprev is null"); if (pfork == plonger) break; - if (!(pfork = pfork->pprev)) + if ((pfork = pfork->pprev) == NULL) return error("Reorganize() : pfork->pprev is null"); } @@ -1862,7 +1849,7 @@ bool static Reorganize(CTxDB& txdb, CBlockIndex* pindexNew) // Disconnect shorter branch vector vResurrect; - BOOST_FOREACH(CBlockIndex* pindex, vDisconnect) + for (CBlockIndex* pindex : vDisconnect) { CBlock block; if (!block.ReadFromDisk(pindex)) @@ -1871,7 +1858,7 @@ bool static Reorganize(CTxDB& txdb, CBlockIndex* pindexNew) return error("Reorganize() : DisconnectBlock %s failed", pindex->GetBlockHash().ToString().substr(0,20).c_str()); // Queue memory transactions to resurrect - BOOST_FOREACH(const CTransaction& tx, block.vtx) + for (const CTransaction& tx : block.vtx) if (!(tx.IsCoinBase() || tx.IsCoinStake())) vResurrect.push_back(tx); } @@ -1891,7 +1878,7 @@ bool static Reorganize(CTxDB& txdb, CBlockIndex* pindexNew) } // Queue memory transactions to delete - BOOST_FOREACH(const CTransaction& tx, block.vtx) + for (const CTransaction& tx : block.vtx) vDelete.push_back(tx); } if (!txdb.WriteHashBestChain(pindexNew->GetBlockHash())) @@ -1902,21 +1889,21 @@ bool static Reorganize(CTxDB& txdb, CBlockIndex* pindexNew) return error("Reorganize() : TxnCommit failed"); // Disconnect shorter branch - BOOST_FOREACH(CBlockIndex* pindex, vDisconnect) + for (CBlockIndex* pindex : vDisconnect) if (pindex->pprev) pindex->pprev->pnext = NULL; // Connect longer branch - BOOST_FOREACH(CBlockIndex* pindex, vConnect) + for (CBlockIndex* pindex : vConnect) if (pindex->pprev) pindex->pprev->pnext = pindex; // Resurrect memory transactions that were in the disconnected branch - BOOST_FOREACH(CTransaction& tx, vResurrect) + for (CTransaction& tx : vResurrect) tx.AcceptToMemoryPool(txdb, false); // Delete redundant memory transactions that are in the connected branch - BOOST_FOREACH(CTransaction& tx, vDelete) + for (CTransaction& tx : vDelete) mempool.remove(tx); printf("REORGANIZE: done\n"); @@ -1944,7 +1931,7 @@ bool CBlock::SetBestChainInner(CTxDB& txdb, CBlockIndex *pindexNew) pindexNew->pprev->pnext = pindexNew; // Delete redundant memory transactions - BOOST_FOREACH(CTransaction& tx, vtx) + for (CTransaction& tx : vtx) mempool.remove(tx); return true; @@ -1997,10 +1984,10 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) } // Connect further blocks - BOOST_REVERSE_FOREACH(CBlockIndex *pindex, vpindexSecondary) + for (std::vector::reverse_iterator rit = vpindexSecondary.rbegin(); rit != vpindexSecondary.rend(); ++rit) { CBlock block; - if (!block.ReadFromDisk(pindex)) + if (!block.ReadFromDisk(*rit)) { printf("SetBestChain() : ReadFromDisk failed\n"); break; @@ -2010,7 +1997,7 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) break; } // errors now are not fatal, we still did a reorganisation to a new chain in a valid way - if (!block.SetBestChainInner(txdb, pindex)) + if (!block.SetBestChainInner(txdb, *rit)) break; } } @@ -2061,10 +2048,8 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew) std::string strCmd = GetArg("-blocknotify", ""); if (!fIsInitialDownload && !strCmd.empty()) - { - boost::replace_all(strCmd, "%s", hashBestChain.GetHex()); - boost::thread t(runCommand, strCmd); // thread runs free - } + // thread runs free + boost::thread t(runCommand, regex_replace(strCmd, static_cast("%s"), hashBestChain.GetHex())); return true; } @@ -2084,7 +2069,7 @@ bool CTransaction::GetCoinAge(CTxDB& txdb, uint64_t& nCoinAge) const if (IsCoinBase()) return true; - BOOST_FOREACH(const CTxIn& txin, vin) + for (const CTxIn& txin : vin) { // First try finding the previous transaction in database CTransaction txPrev; @@ -2121,7 +2106,7 @@ bool CBlock::GetCoinAge(uint64_t& nCoinAge) const nCoinAge = 0; CTxDB txdb("r"); - BOOST_FOREACH(const CTransaction& tx, vtx) + for (const CTransaction& tx : vtx) { uint64_t nTxCoinAge; if (tx.GetCoinAge(txdb, nTxCoinAge)) @@ -2360,7 +2345,7 @@ bool CBlock::AcceptBlock() return error("AcceptBlock() : block's timestamp is too far in the future"); // Check that all transactions are finalized - BOOST_FOREACH(const CTransaction& tx, vtx) + for (const CTransaction& tx : vtx) if (!tx.IsFinal(nHeight, GetBlockTime())) return DoS(10, error("AcceptBlock() : contains a non-final transaction")); @@ -2398,7 +2383,7 @@ bool CBlock::AcceptBlock() if (hashBestChain == hash) { LOCK(cs_vNodes); - BOOST_FOREACH(CNode* pnode, vNodes) + for (CNode* pnode : vNodes) if (nBestHeight > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate)) pnode->PushInventory(CInv(MSG_BLOCK, hash)); } @@ -2508,7 +2493,7 @@ bool static ReserealizeBlockSignature(CBlock* pblock) return true; } - return CKey::ReserealizeSignature(pblock->vchBlockSig); + return CPubKey::ReserealizeSignature(pblock->vchBlockSig); } bool static IsCanonicalBlockSignature(CBlock* pblock) @@ -2528,6 +2513,13 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) if (mapOrphanBlocks.count(hash)) return error("ProcessBlock() : already have block (orphan) %s", hash.ToString().substr(0,20).c_str()); + // Check that block isn't listed as unconditionally banned. + if (!Checkpoints::CheckBanned(hash)) { + if (pfrom) + pfrom->Misbehaving(100); + return error("ProcessBlock() : block %s is rejected by hard-coded banlist", hash.GetHex().substr(0,20).c_str()); + } + // Check proof-of-stake // Limited duplicity on stake: prevents block flood attack // Duplicate stake allowed only when there is orphan child block @@ -2544,19 +2536,6 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) if (!pblock->CheckBlock(true, true, (pblock->nTime > Checkpoints::GetLastCheckpointTime()))) return error("ProcessBlock() : CheckBlock FAILED"); - // ppcoin: verify hash target and signature of coinstake tx - if (pblock->IsProofOfStake()) - { - uint256 hashProofOfStake = 0, targetProofOfStake = 0; - if (!CheckProofOfStake(pblock->vtx[1], pblock->nBits, hashProofOfStake, targetProofOfStake)) - { - printf("WARNING: ProcessBlock(): check proof-of-stake failed for block %s\n", hash.ToString().c_str()); - return false; // do not error here as we expect this during initial block download - } - if (!mapProofOfStake.count(hash)) // add to mapProofOfStake - mapProofOfStake.insert(make_pair(hash, hashProofOfStake)); - } - CBlockIndex* pcheckpoint = Checkpoints::GetLastSyncCheckpoint(); if (pcheckpoint && pblock->hashPrevBlock != hashBestChain && !Checkpoints::WantedByPendingSyncCheckpoint(hash)) { @@ -2579,6 +2558,7 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) } } + // ppcoin: ask for pending sync-checkpoint if any if (!IsInitialBlockDownload()) Checkpoints::AskForPendingSyncCheckpoint(pfrom); @@ -2613,11 +2593,31 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) return true; } + // ppcoin: verify hash target and signature of coinstake tx + if (pblock->IsProofOfStake()) + { + uint256 hashProofOfStake = 0, targetProofOfStake = 0; + if (!CheckProofOfStake(pblock->vtx[1], pblock->nBits, hashProofOfStake, targetProofOfStake)) + { + // Having prev block in index should be enough for validation + if (mapBlockIndex.count(pblock->hashPrevBlock)) + return error("ProcessBlock(): check proof-of-stake (%s, %d) failed for block %s\n", pblock->GetProofOfStake().first.ToString().c_str(), pblock->GetProofOfStake().second, hash.ToString().c_str()); + + // Orphan blocks should be validated later once all parents successfully added to local chain + printf("ProcessBlock(): delaying proof-of-stake validation for orphan block %s\n", hash.ToString().c_str()); + return false; // do not error here as we expect this to happen here + } + + // Needed for AcceptBlock() + if (!mapProofOfStake.count(hash)) + mapProofOfStake.insert(make_pair(hash, hashProofOfStake)); + } + // Store to disk if (!pblock->AcceptBlock()) return error("ProcessBlock() : AcceptBlock FAILED"); - // Recursively process any orphan blocks that depended on this one + // Process any orphan blocks that depended on this one vector vWorkQueue; vWorkQueue.push_back(hash); for (unsigned int i = 0; i < vWorkQueue.size(); i++) @@ -2628,12 +2628,36 @@ bool ProcessBlock(CNode* pfrom, CBlock* pblock) ++mi) { CBlock* pblockOrphan = (*mi).second; - if (pblockOrphan->AcceptBlock()) - vWorkQueue.push_back(pblockOrphan->GetHash()); - mapOrphanBlocks.erase(pblockOrphan->GetHash()); - setStakeSeenOrphan.erase(pblockOrphan->GetProofOfStake()); + uint256 hashOrphanBlock = pblockOrphan->GetHash(); + + if (pblockOrphan->IsProofOfStake()) { + // Check proof-of-stake and do other contextual + // preparations before running AcceptBlock() + uint256 hashOrphanProofOfStake = 0; + uint256 targetOrphanProofOfStake = 0; + + if (CheckProofOfStake(pblockOrphan->vtx[1], pblockOrphan->nBits, hashOrphanProofOfStake, targetOrphanProofOfStake)) + { + // Needed for AcceptBlock() + if (!mapProofOfStake.count(hashOrphanBlock)) + mapProofOfStake.insert(make_pair(hashOrphanBlock, hashOrphanProofOfStake)); + + // Finally, we're ready to run AcceptBlock() + if (pblockOrphan->AcceptBlock()) + vWorkQueue.push_back(hashOrphanBlock); + setStakeSeenOrphan.erase(pblockOrphan->GetProofOfStake()); + } + } else { + // proof-of-work verification + // is notoriously simpler + if (pblockOrphan->AcceptBlock()) + vWorkQueue.push_back(hashOrphanBlock); + } + + mapOrphanBlocks.erase(hashOrphanBlock); delete pblockOrphan; } + mapOrphanBlocksByPrev.erase(hashPrev); } @@ -2660,8 +2684,8 @@ bool CBlock::CheckBlockSignature() const if (whichType == TX_PUBKEY) { valtype& vchPubKey = vSolutions[0]; - CKey key; - if (!key.SetPubKey(vchPubKey)) + CPubKey key(vchPubKey); + if (!key.IsValid()) return false; return key.Verify(GetHash(), vchBlockSig); } @@ -2671,7 +2695,7 @@ bool CBlock::CheckBlockSignature() const bool CheckDiskSpace(uint64_t nAdditionalBytes) { - uint64_t nFreeBytesAvailable = filesystem::space(GetDataDir()).available; + uint64_t nFreeBytesAvailable = boost::filesystem::space(GetDataDir()).available; // Check for nMinDiskSpace bytes (currently 50MB) if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes) @@ -2687,7 +2711,7 @@ bool CheckDiskSpace(uint64_t nAdditionalBytes) return true; } -static filesystem::path BlockFilePath(unsigned int nFile) +static boost::filesystem::path BlockFilePath(unsigned int nFile) { string strBlockFn = strprintf("blk%04u.dat", nFile); return GetDataDir() / strBlockFn; @@ -2716,7 +2740,7 @@ static unsigned int nCurrentBlockFile = 1; FILE* AppendBlockFile(unsigned int& nFileRet) { nFileRet = 0; - while (true) + for ( ; ; ) { FILE* file = OpenBlockFile(nCurrentBlockFile, 0, "ab"); if (!file) @@ -2795,12 +2819,12 @@ bool LoadBlockIndex(bool fAllowNew) // CTxOut(empty) // vMerkleTree: 4cb33b3b6a - const char* pszTimestamp = "https://bitcointalk.org/index.php?topic=134179.msg1502196#msg1502196"; + const string strTimestamp = "https://bitcointalk.org/index.php?topic=134179.msg1502196#msg1502196"; CTransaction txNew; txNew.nTime = 1360105017; txNew.vin.resize(1); txNew.vout.resize(1); - txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(9999) << vector((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); + txNew.vin[0].scriptSig = CScript() << 486604799 << CBigNum(9999) << vector(strTimestamp.begin(), strTimestamp.end()); txNew.vout[0].SetEmpty(); CBlock block; block.vtx.push_back(txNew); @@ -2867,10 +2891,6 @@ bool LoadBlockIndex(bool fAllowNew) if (!txdb.WriteModifierUpgradeTime(nModifierUpgradeTime)) return error("LoadBlockIndex() : failed to write upgrade info"); } - -#ifndef USE_LEVELDB - txdb.Close(); -#endif } return true; @@ -2967,7 +2987,7 @@ bool LoadExternalBlockFile(FILE* fileIn) unsigned char pchData[65536]; do { fseek(blkdat, nPos, SEEK_SET); - int nRead = fread(pchData, 1, sizeof(pchData), blkdat); + size_t nRead = fread(pchData, 1, sizeof(pchData), blkdat); if (nRead <= 8) { nPos = std::numeric_limits::max(); @@ -3030,7 +3050,7 @@ string GetWarnings(string strFor) strRPC = "test"; // Misc warnings like out of disk space and clock is wrong - if (strMiscWarning != "") + if (!strMiscWarning.empty()) { nPriority = 1000; strStatusBar = strMiscWarning; @@ -3054,7 +3074,7 @@ string GetWarnings(string strFor) // Alerts { LOCK(cs_mapAlerts); - BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts) + for (auto& item : mapAlerts) { const CAlert& alert = item.second; if (alert.AppliesToMe() && alert.nPriority > nPriority) @@ -3241,7 +3261,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) // Relay alerts { LOCK(cs_mapAlerts); - BOOST_FOREACH(PAIRTYPE(const uint256, CAlert)& item, mapAlerts) + for (auto& item : mapAlerts) item.second.RelayTo(pfrom); } @@ -3296,7 +3316,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) vector vAddrOk; int64_t nNow = GetAdjustedTime(); int64_t nSince = nNow - 10 * 60; - BOOST_FOREACH(CAddress& addr, vAddr) + for (CAddress& addr : vAddr) { if (fShutdown) return true; @@ -3318,7 +3338,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) uint256 hashRand = hashSalt ^ (hashAddr<<32) ^ ((GetTime()+hashAddr)/nOneDay); hashRand = Hash(BEGIN(hashRand), END(hashRand)); multimap mapMix; - BOOST_FOREACH(CNode* pnode, vNodes) + for (CNode* pnode : vNodes) { if (pnode->nVersion < CADDR_TIME_VERSION) continue; @@ -3355,15 +3375,15 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) } // find last block in inv vector - unsigned int nLastBlock = std::numeric_limits::max(); - for (unsigned int nInv = 0; nInv < vInv.size(); nInv++) { + size_t nLastBlock = std::numeric_limits::max(); + for (size_t nInv = 0; nInv < vInv.size(); nInv++) { if (vInv[vInv.size() - 1 - nInv].type == MSG_BLOCK) { nLastBlock = vInv.size() - 1 - nInv; break; } } CTxDB txdb("r"); - for (unsigned int nInv = 0; nInv < vInv.size(); nInv++) + for (size_t nInv = 0; nInv < vInv.size(); nInv++) { const CInv &inv = vInv[nInv]; @@ -3407,7 +3427,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) if (fDebugNet || (vInv.size() != 1)) printf("received getdata (%" PRIszu " invsz)\n", vInv.size()); - BOOST_FOREACH(const CInv& inv, vInv) + for (const CInv& inv : vInv) { if (fShutdown) return true; @@ -3513,7 +3533,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) // Relay pfrom->hashCheckpointKnown = checkpoint.hashCheckpoint; LOCK(cs_vNodes); - BOOST_FOREACH(CNode* pnode, vNodes) + for (CNode* pnode : vNodes) checkpoint.RelayTo(pnode); } } @@ -3605,7 +3625,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) } } - BOOST_FOREACH(uint256 hash, vEraseQueue) + for (uint256 hash : vEraseQueue) EraseOrphanTx(hash); } else if (fMissingInputs) @@ -3650,7 +3670,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) int64_t nCutOff = GetTime() - (nNodeLifespan * nOneDay); pfrom->vAddrToSend.clear(); vector vAddr = addrman.GetAddr(); - BOOST_FOREACH(const CAddress &addr, vAddr) + for (const CAddress &addr : vAddr) if(addr.nTime > nCutOff) pfrom->PushAddress(addr); } @@ -3752,7 +3772,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) pfrom->setKnown.insert(alertHash); { LOCK(cs_vNodes); - BOOST_FOREACH(CNode* pnode, vNodes) + for (CNode* pnode : vNodes) alert.RelayTo(pnode); } } @@ -3801,7 +3821,7 @@ bool ProcessMessages(CNode* pfrom) // (x) data // - while (true) + for ( ; ; ) { // Don't bother if send buffer is too full to respond anyway if (pfrom->vSend.size() >= SendBufferSize()) @@ -3830,7 +3850,7 @@ bool ProcessMessages(CNode* pfrom) if (!hdr.IsValid()) { printf("\n\nPROCESSMESSAGE: ERRORS IN HEADER %s\n\n\n", hdr.GetCommand().c_str()); - continue; + return false; } string strCommand = hdr.GetCommand(); @@ -3856,7 +3876,7 @@ bool ProcessMessages(CNode* pfrom) { printf("ProcessMessages(%s, %u bytes) : CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n", strCommand.c_str(), nMessageSize, nChecksum, hdr.nChecksum); - continue; + return false; } // Copy message to its own buffer @@ -3897,8 +3917,10 @@ bool ProcessMessages(CNode* pfrom) PrintExceptionContinue(NULL, "ProcessMessages()"); } - if (!fRet) + if (!fRet) { printf("ProcessMessage(%s, %u bytes) FAILED\n", strCommand.c_str(), nMessageSize); + return false; + } } vRecv.Compact(); @@ -3906,10 +3928,13 @@ bool ProcessMessages(CNode* pfrom) } -bool SendMessages(CNode* pto, bool fSendTrickle) +bool SendMessages(CNode* pto) { TRY_LOCK(cs_main, lockMain); if (lockMain) { + // Current time in microseconds + int64_t nNow = GetTimeMicros(); + // Don't send anything until we get their version message if (pto->nVersion == 0) return true; @@ -3931,39 +3956,20 @@ bool SendMessages(CNode* pto, bool fSendTrickle) ResendWalletTransactions(); // Address refresh broadcast - static int64_t nLastRebroadcast; - if (!IsInitialBlockDownload() && (GetTime() - nLastRebroadcast > nBroadcastInterval)) - { - { - LOCK(cs_vNodes); - BOOST_FOREACH(CNode* pnode, vNodes) - { - // Periodically clear setAddrKnown to allow refresh broadcasts - if (nLastRebroadcast) - pnode->setAddrKnown.clear(); - - // Rebroadcast our address - if (!fNoListen) - { - CAddress addr = GetLocalAddress(&pnode->addr); - if (addr.IsRoutable()) - pnode->PushAddress(addr); - } - } - } - nLastRebroadcast = GetTime(); + if (!IsInitialBlockDownload() && pto->nNextLocalAddrSend < nNow) { + AdvertiseLocal(pto); + pto->nNextLocalAddrSend = PoissonNextSend(nNow, nOneDay); } // // Message: addr // - if (fSendTrickle) - { + if (pto->nNextAddrSend < nNow) { + pto->nNextAddrSend = PoissonNextSend(nNow, 30); vector vAddr; vAddr.reserve(pto->vAddrToSend.size()); - BOOST_FOREACH(const CAddress& addr, pto->vAddrToSend) + for (const CAddress& addr : pto->vAddrToSend) { - // returns true if wasn't already contained in the set if (pto->setAddrKnown.insert(addr).second) { vAddr.push_back(addr); @@ -3980,17 +3986,21 @@ bool SendMessages(CNode* pto, bool fSendTrickle) pto->PushMessage("addr", vAddr); } - // // Message: inventory // vector vInv; vector vInvWait; { + bool fSendTrickle = false; + if (pto->nNextInvSend < nNow) { + fSendTrickle = true; + pto->nNextInvSend = PoissonNextSend(nNow, 5); + } LOCK(pto->cs_inventory); vInv.reserve(pto->vInventoryToSend.size()); vInvWait.reserve(pto->vInventoryToSend.size()); - BOOST_FOREACH(const CInv& inv, pto->vInventoryToSend) + for (const CInv& inv : pto->vInventoryToSend) { if (pto->setInventoryKnown.count(inv)) continue; @@ -4006,15 +4016,6 @@ bool SendMessages(CNode* pto, bool fSendTrickle) hashRand = Hash(BEGIN(hashRand), END(hashRand)); bool fTrickleWait = ((hashRand & 3) != 0); - // always trickle our own transactions - if (!fTrickleWait) - { - CWalletTx wtx; - if (GetTransaction(inv.hash, wtx)) - if (wtx.fFromMe) - fTrickleWait = true; - } - if (fTrickleWait) { vInvWait.push_back(inv); @@ -4043,7 +4044,6 @@ bool SendMessages(CNode* pto, bool fSendTrickle) // Message: getdata // vector vGetData; - int64_t nNow = GetTime() * 1000000; CTxDB txdb("r"); while (!pto->mapAskFor.empty() && (*pto->mapAskFor.begin()).first <= nNow) {