aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPieter Wuille <pieter.wuille@gmail.com>2014-09-04 23:48:01 +0200
committerPieter Wuille <pieter.wuille@gmail.com>2014-09-04 23:49:35 +0200
commitaf9c3b0cffa4449f1254da3073aef77bafddf9cd (patch)
tree7f76c41b2a5556b9836bde8691ee4af9c3030dae
parentb4cd0975fbc93063473a4d9a09e2b2fe3c4ad489 (diff)
parent1e4f87f5a13e34a457b537e9d13a212e6c5b754f (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.cpp4
-rw-r--r--src/checkpoints.h2
-rw-r--r--src/init.cpp2
-rw-r--r--src/main.cpp38
-rw-r--r--src/main.h9
-rw-r--r--src/qt/transactionrecord.cpp2
-rw-r--r--src/rpcblockchain.cpp2
-rw-r--r--src/rpcrawtransaction.cpp2
-rw-r--r--src/rpcwallet.cpp2
-rw-r--r--src/uint256.h5
-rw-r--r--src/wallet.cpp6
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;