diff options
author | Pieter Wuille <pieter.wuille@gmail.com> | 2014-09-04 23:48:01 +0200 |
---|---|---|
committer | Pieter Wuille <pieter.wuille@gmail.com> | 2014-09-04 23:49:35 +0200 |
commit | af9c3b0cffa4449f1254da3073aef77bafddf9cd (patch) | |
tree | 7f76c41b2a5556b9836bde8691ee4af9c3030dae | |
parent | b4cd0975fbc93063473a4d9a09e2b2fe3c4ad489 (diff) | |
parent | 1e4f87f5a13e34a457b537e9d13a212e6c5b754f (diff) |
Merge pull request #4838
1e4f87f Use memcmp for uint256 equality/inequality (Pieter Wuille)
8a41e1e Use boost::unordered_map for mapBlockIndex (Pieter Wuille)
145d5be Introduce BlockMap type for mapBlockIndex (Pieter Wuille)
a0dbe43 checkpoints.cpp depends on main, it can use mapBlockIndex directly (Pieter Wuille)
-rw-r--r-- | src/checkpoints.cpp | 4 | ||||
-rw-r--r-- | src/checkpoints.h | 2 | ||||
-rw-r--r-- | src/init.cpp | 2 | ||||
-rw-r--r-- | src/main.cpp | 38 | ||||
-rw-r--r-- | src/main.h | 9 | ||||
-rw-r--r-- | src/qt/transactionrecord.cpp | 2 | ||||
-rw-r--r-- | src/rpcblockchain.cpp | 2 | ||||
-rw-r--r-- | src/rpcrawtransaction.cpp | 2 | ||||
-rw-r--r-- | src/rpcwallet.cpp | 2 | ||||
-rw-r--r-- | src/uint256.h | 5 | ||||
-rw-r--r-- | src/wallet.cpp | 6 |
11 files changed, 41 insertions, 33 deletions
diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index 717f0b90fe..c41deea7ce 100644 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -146,7 +146,7 @@ namespace Checkpoints { return checkpoints.rbegin()->first; } - CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex) + CBlockIndex* GetLastCheckpoint() { if (!fEnabled) return NULL; @@ -156,7 +156,7 @@ namespace Checkpoints { BOOST_REVERSE_FOREACH(const MapCheckpoints::value_type& i, checkpoints) { const uint256& hash = i.second; - std::map<uint256, CBlockIndex*>::const_iterator t = mapBlockIndex.find(hash); + BlockMap::const_iterator t = mapBlockIndex.find(hash); if (t != mapBlockIndex.end()) return t->second; } diff --git a/src/checkpoints.h b/src/checkpoints.h index 52cdc35559..6d3f2d4935 100644 --- a/src/checkpoints.h +++ b/src/checkpoints.h @@ -22,7 +22,7 @@ namespace Checkpoints { int GetTotalBlocksEstimate(); // Returns last CBlockIndex* in mapBlockIndex that is a checkpoint - CBlockIndex* GetLastCheckpoint(const std::map<uint256, CBlockIndex*>& mapBlockIndex); + CBlockIndex* GetLastCheckpoint(); double GuessVerificationProgress(CBlockIndex *pindex, bool fSigchecks = true); diff --git a/src/init.cpp b/src/init.cpp index b8988f8b75..31f64878fb 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1031,7 +1031,7 @@ bool AppInit2(boost::thread_group& threadGroup) { string strMatch = mapArgs["-printblock"]; int nFound = 0; - for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi) + for (BlockMap::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi) { uint256 hash = (*mi).first; if (boost::algorithm::starts_with(hash.ToString(), strMatch)) diff --git a/src/main.cpp b/src/main.cpp index 4aebdadd3b..2479beabdd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -38,7 +38,7 @@ using namespace boost; CCriticalSection cs_main; -map<uint256, CBlockIndex*> mapBlockIndex; +BlockMap mapBlockIndex; CChain chainActive; int64_t nTimeBestReceived = 0; CWaitableCriticalSection csBestBlock; @@ -328,7 +328,7 @@ void ProcessBlockAvailability(NodeId nodeid) { assert(state != NULL); if (state->hashLastUnknownBlock != 0) { - map<uint256, CBlockIndex*>::iterator itOld = mapBlockIndex.find(state->hashLastUnknownBlock); + BlockMap::iterator itOld = mapBlockIndex.find(state->hashLastUnknownBlock); if (itOld != mapBlockIndex.end() && itOld->second->nChainWork > 0) { if (state->pindexBestKnownBlock == NULL || itOld->second->nChainWork >= state->pindexBestKnownBlock->nChainWork) state->pindexBestKnownBlock = itOld->second; @@ -344,7 +344,7 @@ void UpdateBlockAvailability(NodeId nodeid, const uint256 &hash) { ProcessBlockAvailability(nodeid); - map<uint256, CBlockIndex*>::iterator it = mapBlockIndex.find(hash); + BlockMap::iterator it = mapBlockIndex.find(hash); if (it != mapBlockIndex.end() && it->second->nChainWork > 0) { // An actually better block was announced. if (state->pindexBestKnownBlock == NULL || it->second->nChainWork >= state->pindexBestKnownBlock->nChainWork) @@ -434,7 +434,7 @@ CBlockLocator CChain::GetLocator(const CBlockIndex *pindex) const { CBlockIndex *CChain::FindFork(const CBlockLocator &locator) const { // Find the first block the caller has in the main chain BOOST_FOREACH(const uint256& hash, locator.vHave) { - std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash); + BlockMap::iterator mi = mapBlockIndex.find(hash); if (mi != mapBlockIndex.end()) { CBlockIndex* pindex = (*mi).second; @@ -2068,7 +2068,7 @@ CBlockIndex* AddToBlockIndex(CBlockHeader& block) { // Check for duplicate uint256 hash = block.GetHash(); - std::map<uint256, CBlockIndex*>::iterator it = mapBlockIndex.find(hash); + BlockMap::iterator it = mapBlockIndex.find(hash); if (it != mapBlockIndex.end()) return it->second; @@ -2079,9 +2079,9 @@ CBlockIndex* AddToBlockIndex(CBlockHeader& block) LOCK(cs_nBlockSequenceId); pindexNew->nSequenceId = nBlockSequenceId++; } - map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first; + BlockMap::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first; pindexNew->phashBlock = &((*mi).first); - map<uint256, CBlockIndex*>::iterator miPrev = mapBlockIndex.find(block.hashPrevBlock); + BlockMap::iterator miPrev = mapBlockIndex.find(block.hashPrevBlock); if (miPrev != mapBlockIndex.end()) { pindexNew->pprev = (*miPrev).second; @@ -2294,7 +2294,7 @@ bool AcceptBlockHeader(CBlockHeader& block, CValidationState& state, CBlockIndex AssertLockHeld(cs_main); // Check for duplicate uint256 hash = block.GetHash(); - std::map<uint256, CBlockIndex*>::iterator miSelf = mapBlockIndex.find(hash); + BlockMap::iterator miSelf = mapBlockIndex.find(hash); CBlockIndex *pindex = NULL; if (miSelf != mapBlockIndex.end()) { pindex = miSelf->second; @@ -2302,7 +2302,7 @@ bool AcceptBlockHeader(CBlockHeader& block, CValidationState& state, CBlockIndex return state.Invalid(error("AcceptBlock() : block is marked invalid"), 0, "duplicate"); } - CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(mapBlockIndex); + CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(); if (pcheckpoint && block.hashPrevBlock != (chainActive.Tip() ? chainActive.Tip()->GetBlockHash() : uint256(0))) { // Extra checks to prevent "fill up memory by spamming with bogus blocks" @@ -2323,7 +2323,7 @@ bool AcceptBlockHeader(CBlockHeader& block, CValidationState& state, CBlockIndex CBlockIndex* pindexPrev = NULL; int nHeight = 0; if (hash != Params().HashGenesisBlock()) { - map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(block.hashPrevBlock); + BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock); if (mi == mapBlockIndex.end()) return state.DoS(10, error("AcceptBlock() : prev block not found"), 0, "bad-prevblk"); pindexPrev = (*mi).second; @@ -2345,7 +2345,7 @@ bool AcceptBlockHeader(CBlockHeader& block, CValidationState& state, CBlockIndex REJECT_CHECKPOINT, "checkpoint mismatch"); // Don't accept any forks from the main chain prior to last checkpoint - CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(mapBlockIndex); + CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(); if (pcheckpoint && nHeight < pcheckpoint->nHeight) return state.DoS(100, error("AcceptBlock() : forked chain older than last checkpoint (height %d)", nHeight)); @@ -2517,7 +2517,7 @@ bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBl return error("ProcessBlock() : CheckBlock FAILED"); // If we don't already have its previous block (with full data), shunt it off to holding area until we get it - std::map<uint256, CBlockIndex*>::iterator it = mapBlockIndex.find(pblock->hashPrevBlock); + BlockMap::iterator it = mapBlockIndex.find(pblock->hashPrevBlock); if (pblock->hashPrevBlock != 0 && (it == mapBlockIndex.end() || !(it->second->nStatus & BLOCK_HAVE_DATA))) { LogPrintf("ProcessBlock: ORPHAN BLOCK %lu, prev=%s\n", (unsigned long)mapOrphanBlocks.size(), pblock->hashPrevBlock.ToString()); @@ -2799,7 +2799,7 @@ CBlockIndex * InsertBlockIndex(uint256 hash) return NULL; // Return existing - map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hash); + BlockMap::iterator mi = mapBlockIndex.find(hash); if (mi != mapBlockIndex.end()) return (*mi).second; @@ -2876,7 +2876,7 @@ bool static LoadBlockIndexDB() LogPrintf("LoadBlockIndexDB(): transaction index %s\n", fTxIndex ? "enabled" : "disabled"); // Load pointer to end of best chain - std::map<uint256, CBlockIndex*>::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock()); + BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock()); if (it == mapBlockIndex.end()) return true; chainActive.SetTip(it->second); @@ -3034,7 +3034,7 @@ void PrintBlockTree() AssertLockHeld(cs_main); // pre-compute tree structure map<CBlockIndex*, vector<CBlockIndex*> > mapNext; - for (map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi) + for (BlockMap::iterator mi = mapBlockIndex.begin(); mi != mapBlockIndex.end(); ++mi) { CBlockIndex* pindex = (*mi).second; mapNext[pindex->pprev].push_back(pindex); @@ -3280,13 +3280,13 @@ void static ProcessGetData(CNode* pfrom) if (inv.type == MSG_BLOCK || inv.type == MSG_FILTERED_BLOCK) { bool send = false; - map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(inv.hash); + BlockMap::iterator mi = mapBlockIndex.find(inv.hash); if (mi != mapBlockIndex.end()) { // If the requested block is at a height below our last // checkpoint, only serve it if it's in the checkpointed chain int nHeight = mi->second->nHeight; - CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(mapBlockIndex); + CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(); if (pcheckpoint && nHeight < pcheckpoint->nHeight) { if (!chainActive.Contains(mi->second)) { @@ -3711,7 +3711,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, if (locator.IsNull()) { // If locator is null, return the hashStop block - map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashStop); + BlockMap::iterator mi = mapBlockIndex.find(hashStop); if (mi == mapBlockIndex.end()) return true; pindex = (*mi).second; @@ -4513,7 +4513,7 @@ public: CMainCleanup() {} ~CMainCleanup() { // block headers - std::map<uint256, CBlockIndex*>::iterator it1 = mapBlockIndex.begin(); + BlockMap::iterator it1 = mapBlockIndex.begin(); for (; it1 != mapBlockIndex.end(); it1++) delete (*it1).second; mapBlockIndex.clear(); diff --git a/src/main.h b/src/main.h index d38d033d2c..8c0a743e24 100644 --- a/src/main.h +++ b/src/main.h @@ -29,6 +29,8 @@ #include <utility> #include <vector> +#include <boost/unordered_map.hpp> + class CBlockIndex; class CBloomFilter; class CInv; @@ -81,11 +83,16 @@ static const unsigned char REJECT_DUST = 0x41; static const unsigned char REJECT_INSUFFICIENTFEE = 0x42; static const unsigned char REJECT_CHECKPOINT = 0x43; +struct BlockHasher +{ + size_t operator()(const uint256& hash) const { return hash.GetLow64(); } +}; extern CScript COINBASE_FLAGS; extern CCriticalSection cs_main; extern CTxMemPool mempool; -extern std::map<uint256, CBlockIndex*> mapBlockIndex; +typedef boost::unordered_map<uint256, CBlockIndex*, BlockHasher> BlockMap; +extern BlockMap mapBlockIndex; extern uint64_t nLastBlockTx; extern uint64_t nLastBlockSize; extern const std::string strMessageMagic; diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index d7bd25e08b..20c1449c92 100644 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -170,7 +170,7 @@ void TransactionRecord::updateStatus(const CWalletTx &wtx) // Find the block the tx is in CBlockIndex* pindex = NULL; - std::map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(wtx.hashBlock); + BlockMap::iterator mi = mapBlockIndex.find(wtx.hashBlock); if (mi != mapBlockIndex.end()) pindex = (*mi).second; diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 83fe629351..4b3beae20c 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -392,7 +392,7 @@ Value gettxout(const Array& params, bool fHelp) if (n<0 || (unsigned int)n>=coins.vout.size() || coins.vout[n].IsNull()) return Value::null; - std::map<uint256, CBlockIndex*>::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock()); + BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock()); CBlockIndex *pindex = it->second; ret.push_back(Pair("bestblock", pindex->GetBlockHash().GetHex())); if ((unsigned int)coins.nHeight == MEMPOOL_HEIGHT) diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 7cd704193d..a73641834d 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -88,7 +88,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry) if (hashBlock != 0) { entry.push_back(Pair("blockhash", hashBlock.GetHex())); - map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock); + BlockMap::iterator mi = mapBlockIndex.find(hashBlock); if (mi != mapBlockIndex.end() && (*mi).second) { CBlockIndex* pindex = (*mi).second; if (chainActive.Contains(pindex)) { diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index 215da2ea12..100d6c2bd0 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -1447,7 +1447,7 @@ Value listsinceblock(const Array& params, bool fHelp) uint256 blockId = 0; blockId.SetHex(params[0].get_str()); - std::map<uint256, CBlockIndex*>::iterator it = mapBlockIndex.find(blockId); + BlockMap::iterator it = mapBlockIndex.find(blockId); if (it != mapBlockIndex.end()) pindex = it->second; } diff --git a/src/uint256.h b/src/uint256.h index d1a822af0d..6bb9a59400 100644 --- a/src/uint256.h +++ b/src/uint256.h @@ -10,6 +10,7 @@ #include <stdexcept> #include <stdint.h> #include <string> +#include <cstring> #include <vector> class uint_error : public std::runtime_error { @@ -215,8 +216,8 @@ public: friend inline const base_uint operator>>(const base_uint& a, int shift) { return base_uint(a) >>= shift; } friend inline const base_uint operator<<(const base_uint& a, int shift) { return base_uint(a) <<= shift; } friend inline const base_uint operator*(const base_uint& a, uint32_t b) { return base_uint(a) *= b; } - friend inline bool operator==(const base_uint& a, const base_uint& b) { return a.CompareTo(b) == 0; } - friend inline bool operator!=(const base_uint& a, const base_uint& b) { return a.CompareTo(b) != 0; } + friend inline bool operator==(const base_uint& a, const base_uint& b) { return memcmp(a.pn, b.pn, sizeof(a.pn)) == 0; } + friend inline bool operator!=(const base_uint& a, const base_uint& b) { return memcmp(a.pn, b.pn, sizeof(a.pn)) != 0; } friend inline bool operator>(const base_uint& a, const base_uint& b) { return a.CompareTo(b) > 0; } friend inline bool operator<(const base_uint& a, const base_uint& b) { return a.CompareTo(b) < 0; } friend inline bool operator>=(const base_uint& a, const base_uint& b) { return a.CompareTo(b) >= 0; } diff --git a/src/wallet.cpp b/src/wallet.cpp index 18a5b3971c..d3ad4869bb 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -2113,7 +2113,7 @@ void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t> &mapKeyBirth) const { for (std::map<uint256, CWalletTx>::const_iterator it = mapWallet.begin(); it != mapWallet.end(); it++) { // iterate over all wallet transactions... const CWalletTx &wtx = (*it).second; - std::map<uint256, CBlockIndex*>::const_iterator blit = mapBlockIndex.find(wtx.hashBlock); + BlockMap::const_iterator blit = mapBlockIndex.find(wtx.hashBlock); if (blit != mapBlockIndex.end() && chainActive.Contains(blit->second)) { // ... which are already in a block int nHeight = blit->second->nHeight; @@ -2233,7 +2233,7 @@ int CMerkleTx::SetMerkleBranch(const CBlock* pblock) } // Is the tx in a block that's in the main chain - map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock); + BlockMap::iterator mi = mapBlockIndex.find(hashBlock); if (mi == mapBlockIndex.end()) return 0; CBlockIndex* pindex = (*mi).second; @@ -2250,7 +2250,7 @@ int CMerkleTx::GetDepthInMainChainINTERNAL(CBlockIndex* &pindexRet) const AssertLockHeld(cs_main); // Find the block it claims to be in - map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.find(hashBlock); + BlockMap::iterator mi = mapBlockIndex.find(hashBlock); if (mi == mapBlockIndex.end()) return 0; CBlockIndex* pindex = (*mi).second; |